From 6ce80460295cb17c51c2ad9b6f3ac62b8cf7de7d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 9 Jan 2025 17:31:02 -0800 Subject: [PATCH 001/755] part 1: new cfg data structure & caches to replace rd_entity, rd_window, rd_panel, rd_view, etc. --- src/os/gfx/linux/os_gfx_linux.c | 6 + src/os/gfx/os_gfx.h | 1 + src/os/gfx/stub/os_gfx_stub.c | 6 + src/os/gfx/win32/os_gfx_win32.c | 18 + src/raddbg/generated/raddbg.meta.c | 7 +- src/raddbg/generated/raddbg.meta.h | 17 +- src/raddbg/raddbg.mdesk | 5 +- src/raddbg/raddbg_core.c | 2513 ++++++++++++---------------- src/raddbg/raddbg_core.h | 364 ++-- 9 files changed, 1273 insertions(+), 1664 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 11da04b8..b2b08312 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -283,6 +283,12 @@ os_dim_from_monitor(OS_Handle monitor) return v2f32(0, 0); } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + return 96.f; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index f2a860d7..c0ddb4ea 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -168,6 +168,7 @@ internal OS_Handle os_primary_monitor(void); internal OS_Handle os_monitor_from_window(OS_Handle window); internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor); internal Vec2F32 os_dim_from_monitor(OS_Handle monitor); +internal F32 os_dpi_from_monitor(OS_Handle monitor); //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/stub/os_gfx_stub.c b/src/os/gfx/stub/os_gfx_stub.c index 34fd08c9..fc481446 100644 --- a/src/os/gfx/stub/os_gfx_stub.c +++ b/src/os/gfx/stub/os_gfx_stub.c @@ -181,6 +181,12 @@ os_dim_from_monitor(OS_Handle monitor) return v; } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + return 96.f; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 33ee2a9f..99d73deb 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -8,9 +8,11 @@ typedef BOOL w32_SetProcessDpiAwarenessContext_Type(void* value); typedef UINT w32_GetDpiForWindow_Type(HWND hwnd); +typedef HRESULT w32_GetDpiForMonitor_Type(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY); typedef int w32_GetSystemMetricsForDpi_Type(int nIndex, UINT dpi); #define w32_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((void*)-4) global w32_GetDpiForWindow_Type *w32_GetDpiForWindow_func = 0; +global w32_GetDpiForMonitor_Type *w32_GetDpiForMonitor_func = 0; global w32_GetSystemMetricsForDpi_Type *w32_GetSystemMetricsForDpi_func = 0; //////////////////////////////// @@ -811,6 +813,7 @@ os_gfx_init(void) (w32_SetProcessDpiAwarenessContext_Type*)GetProcAddress(module, "SetProcessDpiAwarenessContext"); w32_GetDpiForWindow_func = (w32_GetDpiForWindow_Type*)GetProcAddress(module, "GetDpiForWindow"); + w32_GetDpiForMonitor_func = (w32_GetDpiForMonitor_Type *)GetProcAddress(module, "GetDpiForMonitor"); w32_GetSystemMetricsForDpi_func = (w32_GetSystemMetricsForDpi_Type *)GetProcAddress(module, "GetSystemMetricsForDpi"); FreeLibrary(module); } @@ -1385,6 +1388,21 @@ os_dim_from_monitor(OS_Handle monitor) return result; } +internal F32 +os_dpi_from_monitor(OS_Handle monitor) +{ + F32 result = 96.f; + HMONITOR monitor_handle = (HMONITOR)monitor.u64[0]; + if(w32_GetDpiForMonitor_func != 0) + { + UINT dpi_x = 0; + UINT dpi_y = 0; + HRESULT hr = w32_GetDpiForMonitor_func(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); + result = (F32)dpi_x; + } + return result; +} + //////////////////////////////// //~ rjf: @os_hooks Events (Implemented Per-OS) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7594e916..7e6e1fb1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -191,7 +191,7 @@ RD_EntityKindFlags rd_entity_kind_flags_table[27] = (0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), }; -Rng1U64 rd_reg_slot_range_table[34] = +Rng1U64 rd_reg_slot_range_table[35] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -201,11 +201,12 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, ctrl_entity), OffsetOf(RD_Regs, ctrl_entity) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, tab), OffsetOf(RD_Regs, tab) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, prev_tab), OffsetOf(RD_Regs, prev_tab) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, entity), OffsetOf(RD_Regs, entity) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, entity_list), OffsetOf(RD_Regs, entity_list) + sizeof(RD_HandleList)}, +{OffsetOf(RD_Regs, ev_key), OffsetOf(RD_Regs, ev_key) + sizeof(EV_Key)}, {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, {OffsetOf(RD_Regs, inline_depth), OffsetOf(RD_Regs, inline_depth) + sizeof(U64)}, {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e466ec24..bdce8ed9 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -57,11 +57,12 @@ RD_RegSlot_Thread, RD_RegSlot_CtrlEntity, RD_RegSlot_Window, RD_RegSlot_Panel, -RD_RegSlot_View, -RD_RegSlot_PrevView, +RD_RegSlot_Tab, +RD_RegSlot_PrevTab, RD_RegSlot_DstPanel, RD_RegSlot_Entity, RD_RegSlot_EntityList, +RD_RegSlot_EVKey, RD_RegSlot_UnwindCount, RD_RegSlot_InlineDepth, RD_RegSlot_FilePath, @@ -547,11 +548,12 @@ CTRL_Handle thread; CTRL_Handle ctrl_entity; RD_Handle window; RD_Handle panel; -RD_Handle view; -RD_Handle prev_view; +RD_Handle tab; +RD_Handle prev_tab; RD_Handle dst_panel; RD_Handle entity; RD_HandleList entity_list; +EV_Key ev_key; U64 unwind_count; U64 inline_depth; String8 file_path; @@ -618,11 +620,12 @@ RD_ViewRuleUIFunctionType *ui; .ctrl_entity = rd_regs()->ctrl_entity,\ .window = rd_regs()->window,\ .panel = rd_regs()->panel,\ -.view = rd_regs()->view,\ -.prev_view = rd_regs()->prev_view,\ +.tab = rd_regs()->tab,\ +.prev_tab = rd_regs()->prev_tab,\ .dst_panel = rd_regs()->dst_panel,\ .entity = rd_regs()->entity,\ .entity_list = rd_regs()->entity_list,\ +.ev_key = rd_regs()->ev_key,\ .unwind_count = rd_regs()->unwind_count,\ .inline_depth = rd_regs()->inline_depth,\ .file_path = rd_regs()->file_path,\ @@ -764,7 +767,7 @@ extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[34]; +extern Rng1U64 rd_reg_slot_range_table[35]; extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index de4675fc..920e717a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -158,11 +158,12 @@ RD_RegTable: {CTRL_Handle ctrl_entity CtrlEntity } {RD_Handle window Window } {RD_Handle panel Panel } - {RD_Handle view View } - {RD_Handle prev_view PrevView } + {RD_Handle tab Tab } + {RD_Handle prev_tab PrevTab } {RD_Handle dst_panel DstPanel } {RD_Handle entity Entity } {RD_HandleList entity_list EntityList } + {EV_Key ev_key EVKey } // rjf: frame selection {U64 unwind_count UnwindCount } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 31fdd38e..c604c785 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -325,61 +325,6 @@ rd_parent_ev_key_from_entity(RD_Entity *entity) //////////////////////////////// //~ rjf: View Type Functions -internal B32 -rd_view_is_nil(RD_View *view) -{ - return (view == 0 || view == &rd_nil_view); -} - -internal B32 -rd_view_is_project_filtered(RD_View *view) -{ - B32 result = 0; - String8 view_project = view->project_path; - if(view_project.size != 0) - { - RD_ViewRuleKind kind = rd_view_rule_kind_from_string(view->spec->string); - // TODO(rjf): @hack hack hack - this should be completely determined if the view - // is parameterized by an expression, but that is currently the same string as the - // query, and so we can't rely on that. when query expressions are separated from - // filter strings, we can rely on that here. - if((kind == RD_ViewRuleKind_Text || - kind == RD_ViewRuleKind_Disasm || - kind == RD_ViewRuleKind_Memory || - kind == RD_ViewRuleKind_Bitmap || - kind == RD_ViewRuleKind_Geo3D) && - view->query_string_size != 0) - { - String8 current_project = rd_cfg_path_from_src(RD_CfgSrc_Project); - result = !path_match_normalized(view_project, current_project); - } - } - return result; -} - -internal RD_Handle -rd_handle_from_view(RD_View *view) -{ - RD_Handle handle = rd_handle_zero(); - if(!rd_view_is_nil(view)) - { - handle.u64[0] = (U64)view; - handle.u64[1] = view->generation; - } - return handle; -} - -internal RD_View * -rd_view_from_handle(RD_Handle handle) -{ - RD_View *result = (RD_View *)handle.u64[0]; - if(rd_view_is_nil(result) || result->generation != handle.u64[1]) - { - result = &rd_nil_view; - } - return result; -} - //////////////////////////////// //~ rjf: View Spec Type Functions @@ -418,444 +363,6 @@ rd_view_rule_info_from_string(String8 string) return result; } -//////////////////////////////// -//~ rjf: Panel Type Functions - -//- rjf: basic type functions - -internal B32 -rd_panel_is_nil(RD_Panel *panel) -{ - return panel == 0 || panel == &rd_nil_panel; -} - -internal RD_Handle -rd_handle_from_panel(RD_Panel *panel) -{ - RD_Handle h = {0}; - h.u64[0] = (U64)panel; - h.u64[1] = panel->generation; - return h; -} - -internal RD_Panel * -rd_panel_from_handle(RD_Handle handle) -{ - RD_Panel *panel = (RD_Panel *)handle.u64[0]; - if(panel == 0 || panel->generation != handle.u64[1]) - { - panel = &rd_nil_panel; - } - return panel; -} - -internal UI_Key -rd_ui_key_from_panel(RD_Panel *panel) -{ - UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_window_%p", panel); - return panel_key; -} - -//- rjf: tree construction - -internal void -rd_panel_insert(RD_Panel *parent, RD_Panel *prev_child, RD_Panel *new_child) -{ - DLLInsert_NPZ(&rd_nil_panel, parent->first, parent->last, prev_child, new_child, next, prev); - parent->child_count += 1; - new_child->parent = parent; -} - -internal void -rd_panel_remove(RD_Panel *parent, RD_Panel *child) -{ - DLLRemove_NPZ(&rd_nil_panel, parent->first, parent->last, child, next, prev); - child->next = child->prev = child->parent = &rd_nil_panel; - parent->child_count -= 1; -} - -//- rjf: tree walk - -internal RD_PanelRec -rd_panel_rec_depth_first(RD_Panel *panel, U64 sib_off, U64 child_off) -{ - RD_PanelRec rec = {0}; - if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, panel, child_off))) - { - rec.next = *MemberFromOffset(RD_Panel **, panel, child_off); - rec.push_count = 1; - } - else if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, panel, sib_off))) - { - rec.next = *MemberFromOffset(RD_Panel **, panel, sib_off); - } - else - { - RD_Panel *uncle = &rd_nil_panel; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) - { - rec.pop_count += 1; - if(!rd_panel_is_nil(*MemberFromOffset(RD_Panel **, p, sib_off))) - { - uncle = *MemberFromOffset(RD_Panel **, p, sib_off); - break; - } - } - rec.next = uncle; - } - return rec; -} - -//- rjf: panel -> rect calculations - -internal Rng2F32 -rd_target_rect_from_panel_child(Rng2F32 parent_rect, RD_Panel *parent, RD_Panel *panel) -{ - Rng2F32 rect = parent_rect; - if(!rd_panel_is_nil(parent)) - { - Vec2F32 parent_rect_size = dim_2f32(parent_rect); - Axis2 axis = parent->split_axis; - rect.p1.v[axis] = rect.p0.v[axis]; - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) - { - rect.p1.v[axis] += parent_rect_size.v[axis] * child->pct_of_parent; - if(child == panel) - { - break; - } - rect.p0.v[axis] = rect.p1.v[axis]; - } - //rect.p0.v[axis] += parent_rect_size.v[axis] * panel->off_pct_of_parent.v[axis]; - //rect.p0.v[axis2_flip(axis)] += parent_rect_size.v[axis2_flip(axis)] * panel->off_pct_of_parent.v[axis2_flip(axis)]; - } - rect.x0 = round_f32(rect.x0); - rect.x1 = round_f32(rect.x1); - rect.y0 = round_f32(rect.y0); - rect.y1 = round_f32(rect.y1); - return rect; -} - -internal Rng2F32 -rd_target_rect_from_panel(Rng2F32 root_rect, RD_Panel *root, RD_Panel *panel) -{ - Temp scratch = scratch_begin(0, 0); - - // rjf: count ancestors - U64 ancestor_count = 0; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) - { - ancestor_count += 1; - } - - // rjf: gather ancestors - RD_Panel **ancestors = push_array(scratch.arena, RD_Panel *, ancestor_count); - { - U64 ancestor_idx = 0; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) - { - ancestors[ancestor_idx] = p; - ancestor_idx += 1; - } - } - - // rjf: go from highest ancestor => panel and calculate rect - Rng2F32 parent_rect = root_rect; - for(S64 ancestor_idx = (S64)ancestor_count-1; - 0 <= ancestor_idx && ancestor_idx < ancestor_count; - ancestor_idx -= 1) - { - RD_Panel *ancestor = ancestors[ancestor_idx]; - RD_Panel *parent = ancestor->parent; - if(!rd_panel_is_nil(parent)) - { - parent_rect = rd_target_rect_from_panel_child(parent_rect, parent, ancestor); - } - } - - // rjf: calculate final rect - Rng2F32 rect = rd_target_rect_from_panel_child(parent_rect, panel->parent, panel); - - scratch_end(scratch); - return rect; -} - -//- rjf: view ownership insertion/removal - -internal void -rd_panel_insert_tab_view(RD_Panel *panel, RD_View *prev_view, RD_View *view) -{ - DLLInsert_NPZ(&rd_nil_view, panel->first_tab_view, panel->last_tab_view, prev_view, view, order_next, order_prev); - panel->tab_view_count += 1; - if(!rd_view_is_project_filtered(view)) - { - panel->selected_tab_view = rd_handle_from_view(view); - } -} - -internal void -rd_panel_remove_tab_view(RD_Panel *panel, RD_View *view) -{ - if(rd_view_from_handle(panel->selected_tab_view) == view) - { - panel->selected_tab_view = rd_handle_zero(); - if(rd_handle_match(rd_handle_zero(), panel->selected_tab_view)) - { - for(RD_View *v = view->order_next; !rd_view_is_nil(v); v = v->order_next) - { - if(!rd_view_is_project_filtered(v)) - { - panel->selected_tab_view = rd_handle_from_view(v); - break; - } - } - } - if(rd_handle_match(rd_handle_zero(), panel->selected_tab_view)) - { - for(RD_View *v = view->order_prev; !rd_view_is_nil(v); v = v->order_prev) - { - if(!rd_view_is_project_filtered(v)) - { - panel->selected_tab_view = rd_handle_from_view(v); - break; - } - } - } - } - DLLRemove_NPZ(&rd_nil_view, panel->first_tab_view, panel->last_tab_view, view, order_next, order_prev); - panel->tab_view_count -= 1; -} - -internal RD_View * -rd_selected_tab_from_panel(RD_Panel *panel) -{ - RD_View *view = rd_view_from_handle(panel->selected_tab_view); - if(rd_view_is_project_filtered(view)) - { - view = &rd_nil_view; - } - return view; -} - -//- rjf: icons & display strings - -internal RD_IconKind -rd_icon_kind_from_view(RD_View *view) -{ - RD_IconKind result = view->spec->icon_kind; - return result; -} - -internal DR_FancyStringList -rd_title_fstrs_from_view(Arena *arena, RD_View *view, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size) -{ - DR_FancyStringList result = {0}; - Temp scratch = scratch_begin(&arena, 1); - String8 query = str8(view->query_buffer, view->query_string_size); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, query); - - //- rjf: query is file path - do specific file name strings - if(file_path.size != 0) - { - // rjf: compute disambiguated file name - String8List qualifiers = {0}; - String8 file_name = str8_skip_last_slash(file_path); - if(rd_state->ambiguous_path_slots_count != 0) - { - U64 hash = d_hash_from_string__case_insensitive(file_name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - { - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) - { - if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) - { - node = n; - break; - } - } - } - if(node != 0 && node->paths.node_count > 1) - { - // rjf: get all colliding paths - String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); - - // rjf: get all reversed path parts for each collision - String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); - for EachIndex(idx, collisions.count) - { - String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); - } - } - - // rjf: get the search path & its reversed parts - String8List parts = str8_split_path(scratch.arena, file_path); - String8List parts_reversed = {0}; - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &parts_reversed, n->string); - } - - // rjf: iterate all collision part reversed lists, in lock-step with - // search path; disqualify until we only have one path remaining; gather - // qualifiers - { - U64 num_collisions_left = collisions.count; - String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); - for EachIndex(idx, collisions.count) - { - collision_nodes[idx] = collision_parts_reversed[idx].first; - } - for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) - { - B32 part_is_qualifier = 0; - for EachIndex(idx, collisions.count) - { - if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) - { - collision_nodes[idx] = 0; - num_collisions_left -= 1; - part_is_qualifier = 1; - } - else if(collision_nodes[idx] != 0) - { - collision_nodes[idx] = collision_nodes[idx]->next; - } - } - if(part_is_qualifier) - { - str8_list_push_front(scratch.arena, &qualifiers, n->string); - } - } - } - } - } - - // rjf: push qualifiers - for(String8Node *n = qualifiers.first; n != 0; n = n->next) - { - String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, string); - } - - // rjf: push file name - DR_FancyString fstr = - { - rd_font_from_slot(RD_FontSlot_Main), - push_str8_copy(arena, file_name), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr); - } - - //- rjf: query is not file path - do general case, for view rule & expression - else - { - DR_FancyString fstr1 = - { - rd_font_from_slot(RD_FontSlot_Main), - view->spec->display_name, - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr1); - if(query.size != 0) - { - DR_FancyString fstr2 = - { - rd_font_from_slot(RD_FontSlot_Code), - str8_lit(" "), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr2); - DR_FancyString fstr3 = - { - rd_font_from_slot(RD_FontSlot_Code), - push_str8_copy(arena, query), - secondary_color, - size*0.8f, - }; - dr_fancy_string_list_push(arena, &result, &fstr3); - } - } - scratch_end(scratch); - return result; -} - -//////////////////////////////// -//~ rjf: Window Type Functions - -internal RD_Handle -rd_handle_from_window(RD_Window *window) -{ - RD_Handle handle = {0}; - if(window != 0) - { - handle.u64[0] = (U64)window; - handle.u64[1] = window->gen; - } - return handle; -} - -internal RD_Window * -rd_window_from_handle(RD_Handle handle) -{ - RD_Window *window = (RD_Window *)handle.u64[0]; - if(window != 0 && window->gen != handle.u64[1]) - { - window = 0; - } - return window; -} - -//////////////////////////////// -//~ rjf: Command Parameters From Context - -internal B32 -rd_prefer_dasm_from_window(RD_Window *window) -{ - RD_Panel *panel = window->focused_panel; - RD_View *view = rd_selected_tab_from_panel(panel); - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 result = 0; - if(view_kind == RD_ViewRuleKind_Disasm) - { - result = 1; - } - else if(view_kind == RD_ViewRuleKind_Text) - { - result = 0; - } - else - { - B32 has_src = 0; - B32 has_dasm = 0; - for(RD_Panel *p = window->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) - { - RD_View *p_view = rd_selected_tab_from_panel(p); - RD_ViewRuleKind p_view_kind = rd_view_rule_kind_from_string(p_view->spec->string); - if(p_view_kind == RD_ViewRuleKind_Text) - { - has_src = 1; - } - if(p_view_kind == RD_ViewRuleKind_Disasm) - { - has_dasm = 1; - } - } - if(has_src && !has_dasm) {result = 0;} - if(has_dasm && !has_src) {result = 1;} - } - return result; -} - //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions @@ -912,13 +419,14 @@ rd_get_hover_regs(void) internal void rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws != 0) { ui_ctx_menu_open(rd_state->ctx_menu_key, anchor_box_key, anchor_box_off); - arena_clear(window->ctx_menu_arena); - window->ctx_menu_regs = rd_regs_copy(window->ctx_menu_arena, rd_regs()); - window->ctx_menu_regs_slot = slot; + arena_clear(ws->ctx_menu_arena); + ws->ctx_menu_regs = rd_regs_copy(ws->ctx_menu_arena, rd_regs()); + ws->ctx_menu_regs_slot = slot; } } @@ -1073,6 +581,29 @@ rd_cfg_release(RD_Cfg *cfg) scratch_end(scratch); } +internal RD_Handle +rd_handle_from_cfg(RD_Cfg *cfg) +{ + RD_Handle handle = {0}; + if(cfg != &rd_nil_cfg) + { + handle.u64[0] = (U64)cfg; + handle.u64[1] = cfg->gen; + } + return handle; +} + +internal RD_Cfg * +rd_cfg_from_handle(RD_Handle handle) +{ + RD_Cfg *cfg = (RD_Cfg *)handle.u64[0]; + if(handle.u64[1] != cfg->gen) + { + cfg = &rd_nil_cfg; + } + return cfg; +} + internal RD_Cfg * rd_cfg_new(RD_Cfg *parent, String8 string) { @@ -1095,6 +626,32 @@ rd_cfg_newf(RD_Cfg *parent, char *fmt, ...) return result; } +internal RD_Cfg * +rd_cfg_deep_copy(RD_Cfg *src_root) +{ + RD_CfgRec rec = {0}; + RD_Cfg *dst_root = &rd_nil_cfg; + RD_Cfg *dst_parent = &rd_nil_cfg; + for(RD_Cfg *src = src_root; src != &rd_nil_cfg; src = rec.next) + { + RD_Cfg *dst = rd_cfg_new(dst_parent, src->string); + rec = rd_cfg_rec__depth_first(src_root, src); + if(rec.push_count > 0) + { + dst_parent = dst; + if(dst_root == &rd_nil_cfg) + { + dst_root = dst; + } + } + else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) + { + dst_parent = dst_parent->parent; + } + } + return dst_root; +} + internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string) { @@ -1105,6 +662,18 @@ rd_cfg_equip_string(RD_Cfg *cfg, String8 string) cfg->string = rd_name_alloc(string); } +internal void +rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + rd_cfg_equip_string(cfg, string); + va_end(args); + scratch_end(scratch); +} + internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child) { @@ -1352,6 +921,196 @@ rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) list->count += 1; } +internal RD_PanelTree +rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + Temp scratch = scratch_begin(&arena, 1); + RD_Cfg *wcfg = rd_window_from_cfg(cfg); + RD_Cfg *src_root = rd_cfg_child_from_string(wcfg, str8_lit("panels")); + RD_PanelNode *dst_root = &rd_nil_panel_node; + RD_PanelNode *dst_focused = &rd_nil_panel_node; + { + Axis2 active_split_axis = rd_cfg_child_from_string(wcfg, str8_lit("split_x")) != &rd_nil_cfg ? Axis2_X : Axis2_Y; + RD_CfgRec rec = {0}; + RD_PanelNode *dst_active_parent = &rd_nil_panel_node; + for(RD_Cfg *src = src_root; src != &rd_nil_cfg; src = rec.next) + { + // rjf: build a panel node + RD_PanelNode *dst = push_array(arena, RD_PanelNode, 1); + MemoryCopyStruct(dst, &rd_nil_panel_node); + dst->parent = dst_active_parent; + if(dst_active_parent != &rd_nil_panel_node) + { + DLLPushBack_NPZ(&rd_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev); + dst_active_parent->child_count += 1; + } + + // rjf: extract cfg info + dst->cfg = src; + dst->pct_of_parent = (F32)f64_from_str8(src->string); + dst->tab_side = (rd_cfg_child_from_string(src, str8_lit("tabs_on_bottom")) != &rd_nil_cfg ? Side_Max : Side_Min); + dst->split_axis = active_split_axis; + for(RD_Cfg *src_child = src->first; src_child != &rd_nil_cfg; src_child = src_child->next) + { + MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src->string); + if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) + { + // NOTE(rjf): skip - this is a panel. + } + else if(str8_match(src_child->string, str8_lit("selected"), 0)) + { + dst_focused = dst; + } + else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier) + { + rd_cfg_list_push(arena, &dst->tabs, src_child); + if(rd_cfg_child_from_string(src_child, str8_lit("selected"))) + { + dst->selected_tab = src_child; + } + } + } + + // rjf: recurse + rec = rd_cfg_rec__depth_first(src_root, src); + if(rec.push_count > 0) + { + dst_active_parent = dst; + if(dst_root == &rd_nil_panel_node) + { + dst_root = dst; + } + active_split_axis = axis2_flip(active_split_axis); + } + else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) + { + dst_active_parent = dst_active_parent->parent; + active_split_axis = axis2_flip(active_split_axis); + } + } + } + scratch_end(scratch); + RD_PanelTree tree = {dst_root, dst_focused}; + return tree; +} + +internal RD_PanelNodeRec +rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_off, U64 child_off) +{ + RD_PanelNodeRec rec = {&rd_nil_panel_node}; + if(*MemberFromOffset(RD_PanelNode **, panel, child_off) != &rd_nil_panel_node) + { + rec.next = *MemberFromOffset(RD_PanelNode **, panel, child_off); + rec.push_count += 1; + } + else for(RD_PanelNode *p = panel; p != &rd_nil_panel_node && p != root; p = p->parent, rec.pop_count += 1) + { + if(*MemberFromOffset(RD_PanelNode **, panel, sib_off) != &rd_nil_panel_node) + { + rec.next = *MemberFromOffset(RD_PanelNode **, panel, sib_off); + break; + } + } + return rec; +} + +internal RD_PanelNode * +rd_panel_node_from_tree_cfg(RD_PanelNode *root, RD_Cfg *cfg) +{ + RD_PanelNode *result = &rd_nil_panel_node; + for(RD_PanelNode *p = root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(root, p).next) + { + if(p->cfg == cfg) + { + result = p; + break; + } + } + return result; +} + +internal Rng2F32 +rd_target_rect_from_panel_node_child(Rng2F32 parent_rect, RD_PanelNode *parent, RD_PanelNode *panel) +{ + Rng2F32 rect = parent_rect; + if(parent != &rd_nil_panel_node) + { + Vec2F32 parent_rect_size = dim_2f32(parent_rect); + Axis2 axis = parent->split_axis; + rect.p1.v[axis] = rect.p0.v[axis]; + for(RD_PanelNode *child = parent->first; child != &rd_nil_panel_node; child = child->next) + { + rect.p1.v[axis] += parent_rect_size.v[axis] * child->pct_of_parent; + if(child == panel) + { + break; + } + rect.p0.v[axis] = rect.p1.v[axis]; + } + //rect.p0.v[axis] += parent_rect_size.v[axis] * panel->off_pct_of_parent.v[axis]; + //rect.p0.v[axis2_flip(axis)] += parent_rect_size.v[axis2_flip(axis)] * panel->off_pct_of_parent.v[axis2_flip(axis)]; + } + rect.x0 = round_f32(rect.x0); + rect.x1 = round_f32(rect.x1); + rect.y0 = round_f32(rect.y0); + rect.y1 = round_f32(rect.y1); + return rect; +} + +internal Rng2F32 +rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode *root, RD_PanelNode *panel) +{ + Temp scratch = scratch_begin(0, 0); + + // rjf: count ancestors + U64 ancestor_count = 0; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) + { + ancestor_count += 1; + } + + // rjf: gather ancestors + RD_PanelNode **ancestors = push_array(scratch.arena, RD_PanelNode *, ancestor_count); + { + U64 ancestor_idx = 0; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) + { + ancestors[ancestor_idx] = p; + ancestor_idx += 1; + } + } + + // rjf: go from highest ancestor => panel and calculate rect + Rng2F32 parent_rect = root_rect; + for(S64 ancestor_idx = (S64)ancestor_count-1; + 0 <= ancestor_idx && ancestor_idx < ancestor_count; + ancestor_idx -= 1) + { + RD_PanelNode *ancestor = ancestors[ancestor_idx]; + RD_PanelNode *parent = ancestor->parent; + if(parent != &rd_nil_panel_node) + { + parent_rect = rd_target_rect_from_panel_node_child(parent_rect, parent, ancestor); + } + } + + // rjf: calculate final rect + Rng2F32 rect = rd_target_rect_from_panel_node_child(parent_rect, panel->parent, panel); + + scratch_end(scratch); + return rect; +} + +internal B32 +rd_cfg_is_project_filtered(RD_Cfg *cfg) +{ + RD_Cfg *project = rd_cfg_child_from_string(cfg, str8_lit("project")); + B32 result = path_match_normalized(rd_state->cfg_paths[RD_CfgSrc_Project], project->first->string); + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -2886,212 +2645,195 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) } //////////////////////////////// -//~ rjf: View State Functions +//~ rjf: View Functions -//- rjf: allocation/releasing - -internal RD_View * -rd_view_alloc(void) +internal RD_ViewState * +rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key) { - // rjf: allocate - RD_View *view = rd_state->free_view; + RD_Handle cfg_handle = rd_handle_from_cfg(cfg); + U64 hash = d_hash_from_string(str8_struct(&cfg_handle)); + U64 slot_idx = hash%rd_state->view_state_slots_count; + RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; + RD_ViewState *view_state = &rd_nil_view_state; + for(RD_ViewState *v = slot->first; v != &rd_nil_view_state; v = v->hash_next) { - if(!rd_view_is_nil(view)) + if(rd_handle_match(v->cfg_handle, cfg_handle) && ev_key_match(v->ev_key, ev_key)) { - rd_state->free_view_count -= 1; - SLLStackPop_N(rd_state->free_view, alloc_next); - U64 generation = view->generation; - MemoryZeroStruct(view); - view->generation = generation; + view_state = v; + break; + } + } + if(view_state == &rd_nil_view_state) + { + view_state = rd_state->free_view_state; + if(view_state != &rd_nil_view_state) + { + SLLStackPop_N(rd_state->free_view_state, hash_next); } else { - view = push_array(rd_state->arena, RD_View, 1); + view_state = push_array(rd_state->arena, RD_ViewState, 1); } - view->generation += 1; + MemoryCopyStruct(view_state, &rd_nil_view_state); + DLLPushBack_NPZ(&rd_nil_view_state, slot->first, slot->last, view_state, hash_next, hash_prev); + view_state->cfg_handle = cfg_handle; + view_state->ev_key = ev_key; + view_state->arena = arena_alloc(); } - - // rjf: initialize - view->arena = arena_alloc(); - view->spec = &rd_nil_view_rule_info; - view->project_path_arena = arena_alloc(); - view->project_path = str8_zero(); - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) + if(view_state != &rd_nil_view_state) { - view->params_arenas[idx] = arena_alloc(); - view->params_roots[idx] = &md_nil_node; + view_state->last_frame_index_touched = rd_state->frame_index; } - view->query_cursor = view->query_mark = txt_pt(1, 1); - view->query_string_size = 0; - rd_state->allocated_view_count += 1; - DLLPushBack_NPZ(&rd_nil_view, rd_state->first_view, rd_state->last_view, view, alloc_next, alloc_prev); - return view; + return view_state; } -internal void -rd_view_release(RD_View *view) +internal RD_ViewState * +rd_view_state_from_cfg(RD_Cfg *cfg) { - DLLRemove_NPZ(&rd_nil_view, rd_state->first_view, rd_state->last_view, view, alloc_next, alloc_prev); - SLLStackPush_N(rd_state->free_view, view, alloc_next); - for(RD_View *tchild = view->first_transient, *next = 0; !rd_view_is_nil(tchild); tchild = next) - { - next = tchild->order_next; - rd_view_release(tchild); - } - view->first_transient = view->last_transient = &rd_nil_view; - view->transient_view_slots_count = 0; - view->transient_view_slots = 0; - for(RD_ArenaExt *ext = view->first_arena_ext; ext != 0; ext = ext->next) - { - arena_release(ext->arena); - } - view->first_arena_ext = view->last_arena_ext = 0; - arena_release(view->project_path_arena); - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) - { - arena_release(view->params_arenas[idx]); - } - arena_release(view->arena); - view->generation += 1; - rd_state->allocated_view_count -= 1; - rd_state->free_view_count += 1; + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(cfg, ev_key_zero()); + return view_state; } -//- rjf: equipment - -internal void -rd_view_equip_spec(RD_View *view, RD_ViewRuleInfo *spec, String8 query, MD_Node *params) +internal DR_FancyStringList +rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size) { - // rjf: fill params tree - for(U64 idx = 0; idx < ArrayCount(view->params_arenas); idx += 1) - { - arena_clear(view->params_arenas[idx]); - } - view->params_roots[0] = md_tree_copy(view->params_arenas[0], params); - view->params_write_gen = view->params_read_gen = 0; + DR_FancyStringList result = {0}; + Temp scratch = scratch_begin(&arena, 1); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, query); - // rjf: fill query buffer - rd_view_equip_query(view, query); - - // rjf: initialize state for new view spec + //- rjf: query is file path - do specific file name strings + if(file_path.size != 0) { - for(RD_ArenaExt *ext = view->first_arena_ext; ext != 0; ext = ext->next) + // rjf: compute disambiguated file name + String8List qualifiers = {0}; + String8 file_name = str8_skip_last_slash(file_path); + if(rd_state->ambiguous_path_slots_count != 0) { - arena_release(ext->arena); + U64 hash = d_hash_from_string__case_insensitive(file_name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + { + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) + { + if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } + } + } + if(node != 0 && node->paths.node_count > 1) + { + // rjf: get all colliding paths + String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); + + // rjf: get all reversed path parts for each collision + String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); + for EachIndex(idx, collisions.count) + { + String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); + } + } + + // rjf: get the search path & its reversed parts + String8List parts = str8_split_path(scratch.arena, file_path); + String8List parts_reversed = {0}; + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &parts_reversed, n->string); + } + + // rjf: iterate all collision part reversed lists, in lock-step with + // search path; disqualify until we only have one path remaining; gather + // qualifiers + { + U64 num_collisions_left = collisions.count; + String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); + for EachIndex(idx, collisions.count) + { + collision_nodes[idx] = collision_parts_reversed[idx].first; + } + for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) + { + B32 part_is_qualifier = 0; + for EachIndex(idx, collisions.count) + { + if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) + { + collision_nodes[idx] = 0; + num_collisions_left -= 1; + part_is_qualifier = 1; + } + else if(collision_nodes[idx] != 0) + { + collision_nodes[idx] = collision_nodes[idx]->next; + } + } + if(part_is_qualifier) + { + str8_list_push_front(scratch.arena, &qualifiers, n->string); + } + } + } + } } - for(RD_View *tchild = view->first_transient, *next = 0; !rd_view_is_nil(tchild); tchild = next) + + // rjf: push qualifiers + for(String8Node *n = qualifiers.first; n != 0; n = n->next) { - next = tchild->order_next; - rd_view_release(tchild); + String8 string = push_str8f(arena, "<%S> ", n->string); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, string); } - view->first_transient = view->last_transient = &rd_nil_view; - view->first_arena_ext = view->last_arena_ext = 0; - view->transient_view_slots_count = 0; - view->transient_view_slots = 0; - arena_clear(view->arena); - view->user_data = 0; + + // rjf: push file name + DR_FancyString fstr = + { + rd_font_from_slot(RD_FontSlot_Main), + push_str8_copy(arena, file_name), + primary_color, + size, + }; + dr_fancy_string_list_push(arena, &result, &fstr); } - MemoryZeroStruct(&view->scroll_pos); - view->spec = spec; - arena_clear(view->project_path_arena); - view->project_path = push_str8_copy(view->project_path_arena, rd_cfg_path_from_src(RD_CfgSrc_Project)); - view->is_filtering = 0; - view->is_filtering_t = 0; -} - -internal void -rd_view_equip_query(RD_View *view, String8 query) -{ - view->query_string_size = Min(sizeof(view->query_buffer), query.size); - MemoryCopy(view->query_buffer, query.str, view->query_string_size); - view->query_cursor = view->query_mark = txt_pt(1, query.size+1); -} - -internal void -rd_view_equip_loading_info(RD_View *view, B32 is_loading, U64 progress_v, U64 progress_target) -{ - view->loading_t_target = (F32)!!is_loading; - view->loading_progress_v = progress_v; - view->loading_progress_v_target = progress_target; - if(is_loading) + + //- rjf: query is not file path - do general case, for view rule & expression + else { - view->loading_t = view->loading_t_target; + DR_FancyString fstr1 = + { + rd_font_from_slot(RD_FontSlot_Main), + viewer_name_string, + primary_color, + size, + }; + dr_fancy_string_list_push(arena, &result, &fstr1); + if(query.size != 0) + { + DR_FancyString fstr2 = + { + rd_font_from_slot(RD_FontSlot_Code), + str8_lit(" "), + primary_color, + size, + }; + dr_fancy_string_list_push(arena, &result, &fstr2); + DR_FancyString fstr3 = + { + rd_font_from_slot(RD_FontSlot_Code), + push_str8_copy(arena, query), + secondary_color, + size*0.8f, + }; + dr_fancy_string_list_push(arena, &result, &fstr3); + } } -} - -//- rjf: user state extensions - -internal void * -rd_view_get_or_push_user_state(RD_View *view, U64 size) -{ - void *result = view->user_data; - if(result == 0) - { - view->user_data = result = push_array(view->arena, U8, size); - } - return result; -} - -internal Arena * -rd_view_push_arena_ext(RD_View *view) -{ - RD_ArenaExt *ext = push_array(view->arena, RD_ArenaExt, 1); - ext->arena = arena_alloc(); - SLLQueuePush(view->first_arena_ext, view->last_arena_ext, ext); - return ext->arena; -} - -//- rjf: param saving - -internal void -rd_view_store_param(RD_View *view, String8 key, String8 value) -{ - B32 new_copy = 0; - if(view->params_write_gen == view->params_read_gen) - { - view->params_write_gen += 1; - new_copy = 1; - } - Arena *new_params_arena = view->params_arenas[view->params_write_gen%ArrayCount(view->params_arenas)]; - if(new_copy) - { - arena_clear(new_params_arena); - view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)] = md_tree_copy(new_params_arena, view->params_roots[view->params_read_gen%ArrayCount(view->params_arenas)]); - } - MD_Node *new_params_root = view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)]; - if(md_node_is_nil(new_params_root)) - { - new_params_root = view->params_roots[view->params_write_gen%ArrayCount(view->params_arenas)] = md_push_node(new_params_arena, MD_NodeKind_Main, 0, str8_zero(), str8_zero(), 0); - } - MD_Node *key_node = md_child_from_string(new_params_root, key, 0); - if(md_node_is_nil(key_node)) - { - String8 key_copy = push_str8_copy(new_params_arena, key); - key_node = md_push_node(new_params_arena, MD_NodeKind_Main, MD_NodeFlag_Identifier, key_copy, key_copy, 0); - md_node_push_child(new_params_root, key_node); - } - key_node->first = key_node->last = &md_nil_node; - String8 value_copy = push_str8_copy(new_params_arena, value); - MD_TokenizeResult value_tokenize = md_tokenize_from_text(new_params_arena, value_copy); - MD_ParseResult value_parse = md_parse_from_text_tokens(new_params_arena, str8_zero(), value_copy, value_tokenize.tokens); - for MD_EachNode(child, value_parse.root->first) - { - child->parent = key_node; - } - key_node->first = value_parse.root->first; - key_node->last = value_parse.root->last; -} - -internal void -rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...) -{ - Temp scratch = scratch_begin(0, 0); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - rd_view_store_param(view, key, string); - va_end(args); scratch_end(scratch); + return result; } //////////////////////////////// @@ -3102,33 +2844,35 @@ rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...) internal Arena * rd_view_arena(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - return view->arena; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + return view_state->arena; } internal UI_ScrollPt2 rd_view_scroll_pos(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - return view->scroll_pos; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + return view_state->scroll_pos; } internal String8 rd_view_expr_string(void) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - String8 expr_string = str8(view->query_buffer, view->query_string_size); + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + String8 expr_string = str8(view_state->expression_buffer, view_state->expression_string_size); return expr_string; } internal String8 rd_view_filter(void) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - String8 filter = str8(view->query_buffer, view->query_string_size); - return filter; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + String8 filter_string = str8(view_state->filter_buffer, view_state->filter_string_size); + return filter_string; } //- rjf: pushing/attaching view resources @@ -3136,17 +2880,24 @@ rd_view_filter(void) internal void * rd_view_state_by_size(U64 size) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - void *result = rd_view_get_or_push_user_state(view, size); - return result; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + if(view_state->user_data == 0) + { + view_state->user_data = push_array(view_state->arena, U8, size); + } + return view_state->user_data; } internal Arena * rd_push_view_arena(void) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - Arena *result = rd_view_push_arena_ext(view); - return result; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_ArenaExt *ext = push_array(view_state->arena, RD_ArenaExt, 1); + ext->arena = arena_alloc(); + SLLQueuePush(view_state->first_arena_ext, view_state->last_arena_ext, ext); + return ext->arena; } //- rjf: storing view-attached state @@ -3154,31 +2905,37 @@ rd_push_view_arena(void) internal void rd_store_view_expr_string(String8 string) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_query(view, string); + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + view_state->expression_string_size = Min(string.size, sizeof(view_state->expression_buffer)); + MemoryCopy(view_state->expression_buffer, string.str, view_state->expression_string_size); } internal void rd_store_view_filter(String8 string) { - // TODO(rjf): @entity_simplification filter and expr string need to be different - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_query(view, string); + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + view_state->filter_string_size = Min(string.size, sizeof(view_state->filter_buffer)); + MemoryCopy(view_state->filter_buffer, string.str, view_state->filter_string_size); } internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_loading_info(view, is_loading, progress_u64, progress_u64_target); + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + view_state->loading_t_target = (F32)!!is_loading; + view_state->loading_progress_v = progress_u64; + view_state->loading_progress_v_target = progress_u64_target; } internal void rd_store_view_scroll_pos(UI_ScrollPt2 pos) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - view->scroll_pos = pos; + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); + RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + view_state->scroll_pos = pos; } internal void @@ -3201,223 +2958,220 @@ rd_store_view_paramf(String8 key, char *fmt, ...) } //////////////////////////////// -//~ rjf: Expand-Keyed Transient View Functions +//~ rjf: Window Functions -internal RD_TransientViewNode * -rd_transient_view_node_from_ev_key(RD_View *owner_view, EV_Key key) +internal RD_Cfg * +rd_window_from_cfg(RD_Cfg *cfg) { - if(owner_view->transient_view_slots_count == 0) + RD_Cfg *result = &rd_nil_cfg; + for(RD_Cfg *c = cfg; c != &rd_nil_cfg; c = c->parent) { - owner_view->transient_view_slots_count = 256; - owner_view->transient_view_slots = push_array(owner_view->arena, RD_TransientViewSlot, owner_view->transient_view_slots_count); - } - U64 hash = ev_hash_from_key(key); - U64 slot_idx = hash%owner_view->transient_view_slots_count; - RD_TransientViewSlot *slot = &owner_view->transient_view_slots[slot_idx]; - RD_TransientViewNode *node = 0; - for(RD_TransientViewNode *n = slot->first; n != 0; n = n->next) - { - if(ev_key_match(n->key, key)) + if(c->parent->parent == rd_state->root_cfg && str8_match(c->string, str8_lit("window"), 0)) { - node = n; - n->last_frame_index_touched = rd_state->frame_index; - break; - } - } - if(node == 0) - { - if(!owner_view->free_transient_view_node) - { - owner_view->free_transient_view_node = push_array(rd_state->arena, RD_TransientViewNode, 1); - } - node = owner_view->free_transient_view_node; - SLLStackPop(owner_view->free_transient_view_node); - DLLPushBack(slot->first, slot->last, node); - node->key = key; - node->view = rd_view_alloc(); - node->initial_params_arena = arena_alloc(); - node->first_frame_index_touched = node->last_frame_index_touched = rd_state->frame_index; - DLLPushBack_NPZ(&rd_nil_view, owner_view->first_transient, owner_view->last_transient, node->view, order_next, order_prev); - } - return node; -} - -//////////////////////////////// -//~ rjf: Panel State Functions - -internal RD_Panel * -rd_panel_alloc(RD_Window *ws) -{ - RD_Panel *panel = ws->free_panel; - if(!rd_panel_is_nil(panel)) - { - SLLStackPop(ws->free_panel); - U64 generation = panel->generation; - MemoryZeroStruct(panel); - panel->generation = generation; - } - else - { - panel = push_array(ws->arena, RD_Panel, 1); - } - panel->first = panel->last = panel->next = panel->prev = panel->parent = &rd_nil_panel; - panel->first_tab_view = panel->last_tab_view = &rd_nil_view; - panel->generation += 1; - MemoryZeroStruct(&panel->animated_rect_pct); - return panel; -} - -internal void -rd_panel_release(RD_Window *ws, RD_Panel *panel) -{ - rd_panel_release_all_views(panel); - SLLStackPush(ws->free_panel, panel); - panel->generation += 1; -} - -internal void -rd_panel_release_all_views(RD_Panel *panel) -{ - for(RD_View *view = panel->first_tab_view, *next = 0; !rd_view_is_nil(view); view = next) - { - next = view->order_next; - rd_view_release(view); - } - panel->first_tab_view = panel->last_tab_view = &rd_nil_view; - panel->selected_tab_view = rd_handle_zero(); - panel->tab_view_count = 0; -} - -//////////////////////////////// -//~ rjf: Window State Functions - -internal RD_Window * -rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src) -{ - RD_Window *window = rd_state->free_window; - if(window != 0) - { - SLLStackPop(rd_state->free_window); - U64 gen = window->gen; - MemoryZeroStruct(window); - window->gen = gen; - } - else - { - window = push_array(rd_state->arena, RD_Window, 1); - } - window->gen += 1; - window->frames_alive = 0; - window->cfg_src = cfg_src; - window->arena = arena_alloc(); - { - String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); - window->os = os_window_open(size, OS_WindowFlag_CustomBorder, title); - } - window->r = r_window_equip(window->os); - window->ui = ui_state_alloc(); - window->ctx_menu_arena = arena_alloc(); - window->ctx_menu_regs = push_array(window->ctx_menu_arena, RD_Regs, 1); - window->ctx_menu_input_buffer_size = KB(4); - window->ctx_menu_input_buffer = push_array(window->arena, U8, window->ctx_menu_input_buffer_size); - window->drop_completion_arena = arena_alloc(); - window->hover_eval_arena = arena_alloc(); - window->autocomp_lister_params_arena = arena_alloc(); - window->free_panel = &rd_nil_panel; - window->root_panel = rd_panel_alloc(window); - window->focused_panel = window->root_panel; - window->query_cmd_arena = arena_alloc(); - window->query_view_stack_top = &rd_nil_view; - window->last_dpi = os_dpi_from_window(window->os); - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - window->setting_vals[code] = rd_setting_code_default_val_table[code]; - } - } - window->setting_vals[RD_SettingCode_MainFontSize].s32 = window->setting_vals[RD_SettingCode_MainFontSize].s32 * (window->last_dpi / 96.f); - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = window->setting_vals[RD_SettingCode_CodeFontSize].s32 * (window->last_dpi / 96.f); - window->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(window->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = ClampBot(window->setting_vals[RD_SettingCode_CodeFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_CodeFontSize].s32); - OS_Handle zero_monitor = {0}; - if(!os_handle_match(zero_monitor, preferred_monitor)) - { - os_window_set_monitor(window->os, preferred_monitor); - } - if(rd_state->first_window == 0) RD_RegsScope(.window = rd_handle_from_window(window)) - { - RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; - RD_FontSlot icon_font_slot = RD_FontSlot_Icons; - for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) - { - Temp scratch = scratch_begin(0, 0); - RD_FontSlot slot = english_font_slots[idx]; - String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Code), - 0, 0, 0, - sample_text); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Main), - 0, 0, 0, - sample_text); - scratch_end(scratch); - } - for(RD_IconKind icon_kind = RD_IconKind_Null; icon_kind < RD_IconKind_COUNT; icon_kind = (RD_IconKind)(icon_kind+1)) - { - Temp scratch = scratch_begin(0, 0); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(icon_font_slot), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Main), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Code), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - scratch_end(scratch); - } - } - DLLPushBack(rd_state->first_window, rd_state->last_window, window); - return window; -} - -internal RD_Window * -rd_window_from_os_handle(OS_Handle os) -{ - RD_Window *result = 0; - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) - { - if(os_handle_match(w->os, os)) - { - result = w; + result = c; break; } } return result; } +internal RD_WindowState * +rd_window_state_from_cfg(RD_Cfg *cfg) +{ + //- rjf: unpack + RD_Cfg *window_cfg = rd_window_from_cfg(cfg); + RD_Handle handle = rd_handle_from_cfg(window_cfg); + U64 hash = d_hash_from_string(str8_struct(&handle)); + U64 slot_idx = hash%rd_state->window_state_slots_count; + RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; + + //- rjf: scan for existing window + RD_WindowState *ws = &rd_nil_window_state; + for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) + { + if(rd_handle_match(w->cfg_handle, handle)) + { + ws = w; + break; + } + } + + //- rjf: allocate/open new window if one was not found + if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state) + { + Temp scratch = scratch_begin(0, 0); + + // rjf: unpack configuration options + Vec2F32 size = {0}; + OS_Handle preferred_monitor = {0}; + { + RD_Cfg *size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("size")); + RD_Cfg *monitor_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("monitor")); + size.x = (F32)f64_from_str8(size_cfg->first->string); + size.y = (F32)f64_from_str8(size_cfg->first->next->string); + OS_HandleArray monitors = os_push_monitors_array(scratch.arena); + for EachIndex(idx, monitors.count) + { + String8 monitor_name = os_name_from_monitor(scratch.arena, monitors.v[idx]); + if(str8_match(monitor_name, monitor_cfg->first->string, StringMatchFlag_CaseInsensitive)) + { + preferred_monitor = monitors.v[idx]; + break; + } + } + } + + // rjf: allocate window + ws = rd_state->free_window_state; + if(ws != 0) + { + SLLStackPop_N(rd_state->free_window_state, order_next); + } + else + { + ws = push_array_no_zero(rd_state->arena, RD_WindowState, 1); + } + MemoryZeroStruct(ws); + + // rjf: fill out window + ws->arena = arena_alloc(); + { + String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); + ws->os = os_window_open(size, OS_WindowFlag_CustomBorder, title); + } + ws->r = r_window_equip(ws->os); + ws->ui = ui_state_alloc(); + ws->ctx_menu_arena = arena_alloc(); + ws->ctx_menu_regs = push_array(ws->ctx_menu_arena, RD_Regs, 1); + ws->ctx_menu_input_buffer_size = KB(4); + ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); + ws->drop_completion_arena = arena_alloc(); + ws->hover_eval_arena = arena_alloc(); + ws->autocomp_lister_params_arena = arena_alloc(); + ws->query_cmd_arena = arena_alloc(); + ws->query_view_stack_top = &rd_nil_view; + ws->last_dpi = os_dpi_from_window(ws->os); + for EachEnumVal(RD_SettingCode, code) + { + if(rd_setting_code_default_is_per_window_table[code]) + { + ws->setting_vals[code] = rd_setting_code_default_val_table[code]; + } + } + ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ws->setting_vals[RD_SettingCode_MainFontSize].s32 * (ws->last_dpi / 96.f); + ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ws->setting_vals[RD_SettingCode_CodeFontSize].s32 * (ws->last_dpi / 96.f); + ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); + ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_CodeFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_CodeFontSize].s32); + OS_Handle zero_monitor = {0}; + if(!os_handle_match(zero_monitor, preferred_monitor)) + { + os_window_set_monitor(ws->os, preferred_monitor); + } + if(rd_cfg_child_from_string(window_cfg, str8_lit("fullscreen")) != &rd_nil_cfg) + { + os_window_set_fullscreen(ws->os, 1); + } + if(rd_cfg_child_from_string(window_cfg, str8_lit("maximized")) != &rd_nil_cfg) + { + os_window_set_maximized(ws->os, 1); + } + + // rjf: pre-emptively rasterize common glyphs + if(rd_state->first_window_state == 0) RD_RegsScope(.window = handle) + { + RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; + RD_FontSlot icon_font_slot = RD_FontSlot_Icons; + for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) + { + Temp scratch = scratch_begin(0, 0); + RD_FontSlot slot = english_font_slots[idx]; + String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(slot), + rd_font_size_from_slot(RD_FontSlot_Code), + 0, 0, 0, + sample_text); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(slot), + rd_font_size_from_slot(RD_FontSlot_Main), + 0, 0, 0, + sample_text); + scratch_end(scratch); + } + for(RD_IconKind icon_kind = RD_IconKind_Null; icon_kind < RD_IconKind_COUNT; icon_kind = (RD_IconKind)(icon_kind+1)) + { + Temp scratch = scratch_begin(0, 0); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(icon_font_slot), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(RD_FontSlot_Main), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(RD_FontSlot_Code), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + scratch_end(scratch); + } + } + + // rjf: hook up window links + DLLPushBack_NP(rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); + + scratch_end(scratch); + } + + //- rjf: touch window for this frame + if(ws != &rd_nil_window_state) + { + ws->last_frame_index_touched = rd_state->frame_index; + } + + return ws; +} + +internal RD_WindowState * +rd_window_state_from_os_handle(OS_Handle os) +{ + RD_WindowState *ws = 0; + for EachIndex(slot_idx, rd_state->window_state_slots_count) + { + for(RD_WindowState *w = rd_state->window_state_slots[slot_idx].first; + w != 0; + w = w->order_next) + { + if(os_handle_match(w->os, os)) + { + ws = w; + break; + } + } + } + return ws; +} + #if COMPILER_MSVC && !BUILD_DEBUG #pragma optimize("", off) #endif internal void -rd_window_frame(RD_Window *ws) +rd_window_frame(void) { + Temp scratch = scratch_begin(0, 0); ProfBeginFunction(); ////////////////////////////// //- rjf: unpack context // + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window)); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc; B32 popup_open = rd_state->popup_active; B32 query_is_open = !rd_view_is_nil(ws->query_view_stack_top); @@ -3432,53 +3186,11 @@ rd_window_frame(RD_Window *ws) ws->window_temporarily_focused_ipc = 0; ui_select_state(ws->ui); - ////////////////////////////// - //- rjf: panels with no selected tabs? -> select. - // panels with selected tabs? -> ensure they have active tabs. - // - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(!rd_panel_is_nil(panel->first)) - { - continue; - } - RD_View *view = rd_selected_tab_from_panel(panel); - if(rd_view_is_nil(view)) - { - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) - { - if(!rd_view_is_project_filtered(tab)) - { - panel->selected_tab_view = rd_handle_from_view(tab); - break; - } - } - } - if(!rd_view_is_nil(view)) - { - B32 found = 0; - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) - { - if(rd_view_is_project_filtered(tab)) {continue;} - if(tab == view) - { - found = 1; - } - } - if(!found) - { - panel->selected_tab_view = rd_handle_zero(); - } - } - } - ////////////////////////////// //- rjf: fill panel/view interaction registers // - rd_regs()->panel = rd_handle_from_panel(ws->focused_panel); - rd_regs()->view = ws->focused_panel->selected_tab_view; + rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); + rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); ////////////////////////////// //- rjf: compute ui palettes from theme @@ -3819,9 +3531,9 @@ rd_window_frame(RD_Window *ws) .view = rd_state->drag_drop_regs->view) { Temp scratch = scratch_begin(0, 0); - RD_Panel *panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); { //- rjf: tab dragging if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view)) @@ -3843,7 +3555,7 @@ rd_window_frame(RD_Window *ws) { UI_Row { - RD_IconKind icon_kind = rd_icon_kind_from_view(view); + RD_IconKind icon_kind = view_rule_info->icon_kind; DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); RD_Font(RD_FontSlot_Icons) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) @@ -3862,7 +3574,7 @@ rd_window_frame(RD_Window *ws) UI_Box *view_preview_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_preview_container"); UI_Parent(view_preview_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill { - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; + RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], view_preview_container->rect); } } @@ -3948,17 +3660,17 @@ rd_window_frame(RD_Window *ws) ui_divider(ui_em(1.f, 1.f)); //- rjf: draw per-window stats - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) + for(RD_WindowState *w = rd_state->first_window_state; w != 0; w = w->order_next) { // rjf: calc ui hash chain length F64 avg_ui_hash_chain_length = 0; { F64 chain_count = 0; F64 chain_length_sum = 0; - for(U64 idx = 0; idx < ws->ui->box_table_size; idx += 1) + for(U64 idx = 0; idx < w->ui->box_table_size; idx += 1) { F64 chain_length = 0; - for(UI_Box *b = ws->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) + for(UI_Box *b = w->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) { chain_length += 1; } @@ -3973,13 +3685,13 @@ rd_window_frame(RD_Window *ws) ui_labelf("Target Hz: %.2f", 1.f/rd_state->frame_dt); ui_labelf("Ctrl Run Index: %I64u", ctrl_run_gen()); ui_labelf("Ctrl Mem Gen Index: %I64u", ctrl_mem_gen()); - ui_labelf("Window %p", window); + ui_labelf("Window %p", w); ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_pref_height(ui_children_sum(1)); UI_Row { ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Box Count: %I64u", window->ui->last_build_box_count); + ui_labelf("Box Count: %I64u", w->ui->last_build_box_count); } ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_pref_height(ui_children_sum(1)); @@ -6051,6 +5763,20 @@ rd_window_frame(RD_Window *ws) ui_spacer(ui_em(0.75f, 0)); } + // rjf: close dropdown + UI_Key close_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###close_ctx_menu"); + UI_CtxMenu(close_ctx_menu_key) + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Window, 0, "Close Window"))) + { + rd_cmd(RD_CmdKind_CloseWindow); + } + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Exit"))) + { + rd_cmd(RD_CmdKind_Exit); + } + } + // rjf: min/max/close buttons { UI_Signal min_sig = {0}; @@ -6078,7 +5804,7 @@ rd_window_frame(RD_Window *ws) } if(ui_clicked(cls_sig)) { - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(ws)); + ui_ctx_menu_open(close_ctx_menu_key, cls_sig.box->key, v2f32(0, dim_2f32(cls_sig.box->rect).y)); } os_window_push_custom_title_bar_client_area(ws->os, min_sig.box->rect); os_window_push_custom_title_bar_client_area(ws->os, max_sig.box->rect); @@ -6471,6 +6197,7 @@ rd_window_frame(RD_Window *ws) // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) { +#if 0 // TODO(rjf): @cfg for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) @@ -6487,6 +6214,7 @@ rd_window_frame(RD_Window *ws) ws->hover_eval_first_frame_idx = rd_state->frame_index; } } +#endif } // rjf: reset open animation @@ -6811,14 +6539,14 @@ rd_window_frame(RD_Window *ws) // B32 is_changing_panel_boundaries = 0; ProfScope("non-leaf panel UI") - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { ////////////////////////// //- rjf: continue on leaf panels // - if(rd_panel_is_nil(panel->first)) + if(panel->first == &rd_nil_panel_node) { continue; } @@ -6827,7 +6555,7 @@ rd_window_frame(RD_Window *ws) //- rjf: grab info // Axis2 split_axis = panel->split_axis; - Rng2F32 panel_rect = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); ////////////////////////// //- rjf: boundary tab-drag/drop sites @@ -6846,10 +6574,10 @@ rd_window_frame(RD_Window *ws) // // (this does not naturally follow from the below algorithm, since the // root level panel only splits on X) - if(panel == ws->root_panel) UI_CornerRadius(corner_radius) + if(panel == panel_tree.root) UI_CornerRadius(corner_radius) { Vec2F32 panel_rect_center = center_2f32(panel_rect); - Axis2 axis = axis2_flip(ws->root_panel->split_axis); + Axis2 axis = axis2_flip(panel_tree.root->split_axis); for EachEnumVal(Side, side) { UI_Key key = ui_key_from_stringf(ui_key_zero(), "root_extra_split_%i", side); @@ -6917,9 +6645,9 @@ rd_window_frame(RD_Window *ws) Dir2_Invalid); if(dir != Dir2_Invalid) { - RD_Panel *split_panel = panel; + RD_PanelNode *split_panel = panel; rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(split_panel), + .dst_panel = rd_handle_from_cfg(split_panel->cfg), .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -6930,10 +6658,10 @@ rd_window_frame(RD_Window *ws) //- rjf: iterate all children, build boundary drop sites Axis2 split_axis = panel->split_axis; - UI_CornerRadius(corner_radius) for(RD_Panel *child = panel->first;; child = child->next) + UI_CornerRadius(corner_radius) for(RD_PanelNode *child = panel->first;; child = child->next) { // rjf: form rect - Rng2F32 child_rect = rd_target_rect_from_panel_child(panel_rect, panel, child); + Rng2F32 child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, child); Vec2F32 child_rect_center = center_2f32(child_rect); UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel, child); Rng2F32 site_rect = r2f32(child_rect_center, child_rect_center); @@ -6996,21 +6724,21 @@ rd_window_frame(RD_Window *ws) if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) { Dir2 dir = (panel->split_axis == Axis2_X ? Dir2_Left : Dir2_Up); - RD_Panel *split_panel = child; - if(rd_panel_is_nil(split_panel)) + RD_PanelNode *split_panel = child; + if(split_panel == &rd_nil_panel_node) { split_panel = panel->last; dir = (panel->split_axis == Axis2_X ? Dir2_Right : Dir2_Down); } rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(split_panel), + .dst_panel = rd_handle_from_cfg(split_panel->cfg), .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); } // rjf: exit on opl child - if(rd_panel_is_nil(child)) + if(child == &rd_nil_panel_node) { break; } @@ -7021,12 +6749,14 @@ rd_window_frame(RD_Window *ws) ////////////////////////// //- rjf: do UI for drag boundaries between all children // - for(RD_Panel *child = panel->first; !rd_panel_is_nil(child) && !rd_panel_is_nil(child->next); child = child->next) + for(RD_PanelNode *child = panel->first; + child != &rd_nil_panel_node && child->next != &rd_nil_panel_node; + child = child->next) { - RD_Panel *min_child = child; - RD_Panel *max_child = min_child->next; - Rng2F32 min_child_rect = rd_target_rect_from_panel_child(panel_rect, panel, min_child); - Rng2F32 max_child_rect = rd_target_rect_from_panel_child(panel_rect, panel, max_child); + RD_PanelNode *min_child = child; + RD_PanelNode *max_child = min_child->next; + Rng2F32 min_child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, min_child); + Rng2F32 max_child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, max_child); Rng2F32 boundary_rect = {0}; { boundary_rect.p0.v[split_axis] = min_child_rect.p1.v[split_axis] - ui_top_font_size()/3; @@ -7087,14 +6817,17 @@ rd_window_frame(RD_Window *ws) //////////////////////////// //- rjf: animate panels // +#if 0 { F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-50.f * rd_state->frame_dt)) : 1.f; Vec2F32 content_rect_dim = dim_2f32(content_rect); if(content_rect_dim.x > 0 && content_rect_dim.y > 0) { - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel).next) { - Rng2F32 target_rect_px = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); + Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0/content_rect_dim.x, target_rect_px.y0/content_rect_dim.y, target_rect_px.x1/content_rect_dim.x, @@ -7117,29 +6850,36 @@ rd_window_frame(RD_Window *ws) } } } +#endif //////////////////////////// //- rjf: panel leaf UI // ProfScope("leaf panel UI") - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) {continue;} + if(panel->first != &rd_nil_panel_node) {continue;} B32 panel_is_focused = (window_is_focused && !ws->menu_bar_focused && (!query_is_open || !ws->query_view_selected) && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused && - ws->focused_panel == panel); + panel_tree.focused == panel); UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { ////////////////////////// //- rjf: calculate UI rectangles // Vec2F32 content_rect_dim = dim_2f32(content_rect); - Rng2F32 panel_rect_pct = panel->animated_rect_pct; + Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0 / content_rect_dim.x, + target_rect_px.y0 / content_rect_dim.y, + target_rect_px.x1 / content_rect_dim.x, + target_rect_px.y1 / content_rect_dim.y); + // TODO(rjf): @cfg animate `target_rect_pct` + Rng2F32 panel_rect_pct = target_rect_pct; Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, panel_rect_pct.y0*content_rect_dim.y, panel_rect_pct.x1*content_rect_dim.x, @@ -7299,7 +7039,7 @@ rd_window_frame(RD_Window *ws) if(dir != Dir2_Invalid) { rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_panel(panel), + .dst_panel = rd_handle_from_cfg(panel->cfg), .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -7307,7 +7047,7 @@ rd_window_frame(RD_Window *ws) else { rd_cmd(RD_CmdKind_MoveTab, - .dst_panel = rd_handle_from_panel(panel), + .dst_panel = rd_handle_from_cfg(panel->cfg), .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .prev_view = rd_handle_from_view(panel->last_tab_view)); @@ -8595,6 +8335,7 @@ rd_window_frame(RD_Window *ws) ws->frames_alive += 1; ProfEnd(); + scratch_end(scratch); } #if COMPILER_MSVC && !BUILD_DEBUG @@ -9761,25 +9502,26 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window->hover_eval_last_frame_idx+1 < rd_state->frame_index && + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws->hover_eval_last_frame_idx+1 < rd_state->frame_index && ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero())) { - B32 is_new_string = !str8_match(window->hover_eval_string, string, 0); + B32 is_new_string = !str8_match(ws->hover_eval_string, string, 0); if(is_new_string) { - window->hover_eval_first_frame_idx = window->hover_eval_last_frame_idx = rd_state->frame_index; - arena_clear(window->hover_eval_arena); - window->hover_eval_string = push_str8_copy(window->hover_eval_arena, string); - window->hover_eval_file_path = push_str8_copy(window->hover_eval_arena, file_path); - window->hover_eval_file_pt = pt; - window->hover_eval_vaddr = vaddr; - window->hover_eval_focused = 0; + ws->hover_eval_first_frame_idx = ws->hover_eval_last_frame_idx = rd_state->frame_index; + arena_clear(ws->hover_eval_arena); + ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); + ws->hover_eval_file_path = push_str8_copy(ws->hover_eval_arena, file_path); + ws->hover_eval_file_pt = pt; + ws->hover_eval_vaddr = vaddr; + ws->hover_eval_focused = 0; } - window->hover_eval_spawn_pos = pos; - window->hover_eval_last_frame_idx = rd_state->frame_index; + ws->hover_eval_spawn_pos = pos; + ws->hover_eval_last_frame_idx = rd_state->frame_index; } } @@ -10053,29 +9795,30 @@ rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri internal void rd_set_autocomp_lister_query(UI_Key root_key, RD_AutoCompListerParams *params, String8 input, U64 cursor_off) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(cursor_off != window->autocomp_cursor_off) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(cursor_off != ws->autocomp_cursor_off) { - window->autocomp_input_dirty = 1; - window->autocomp_cursor_off = cursor_off; + ws->autocomp_input_dirty = 1; + ws->autocomp_cursor_off = cursor_off; } - if(!ui_key_match(window->autocomp_root_key, root_key)) + if(!ui_key_match(ws->autocomp_root_key, root_key)) { - window->autocomp_num_visible_rows_t = 0; - window->autocomp_open_t = 0; + ws->autocomp_num_visible_rows_t = 0; + ws->autocomp_open_t = 0; } - if(window->autocomp_last_frame_idx+1 < rd_state->frame_index) + if(ws->autocomp_last_frame_idx+1 < rd_state->frame_index) { - window->autocomp_num_visible_rows_t = 0; - window->autocomp_open_t = 0; + ws->autocomp_num_visible_rows_t = 0; + ws->autocomp_open_t = 0; } - window->autocomp_root_key = root_key; - arena_clear(window->autocomp_lister_params_arena); - MemoryCopyStruct(&window->autocomp_lister_params, params); - window->autocomp_lister_params.strings = str8_list_copy(window->autocomp_lister_params_arena, &window->autocomp_lister_params.strings); - window->autocomp_lister_input_size = Min(input.size, sizeof(window->autocomp_lister_input_buffer)); - MemoryCopy(window->autocomp_lister_input_buffer, input.str, window->autocomp_lister_input_size); - window->autocomp_last_frame_idx = rd_state->frame_index; + ws->autocomp_root_key = root_key; + arena_clear(ws->autocomp_lister_params_arena); + MemoryCopyStruct(&ws->autocomp_lister_params, params); + ws->autocomp_lister_params.strings = str8_list_copy(ws->autocomp_lister_params_arena, &ws->autocomp_lister_params.strings); + ws->autocomp_lister_input_size = Min(input.size, sizeof(ws->autocomp_lister_input_buffer)); + MemoryCopy(ws->autocomp_lister_input_buffer, input.str, ws->autocomp_lister_input_size); + ws->autocomp_last_frame_idx = rd_state->frame_index; } //////////////////////////////// @@ -10347,8 +10090,9 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str internal UI_Palette * rd_palette_from_code(RD_PaletteCode code) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - UI_Palette *result = &window->cfg_palettes[code]; + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); + UI_Palette *result = &ws->cfg_palettes[code]; return result; } @@ -10365,7 +10109,8 @@ internal F32 rd_font_size_from_slot(RD_FontSlot slot) { F32 result = 0; - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); F32 dpi = os_dpi_from_window(ws->os); if(dpi != ws->last_dpi) { @@ -10419,11 +10164,12 @@ rd_raster_flags_from_slot(RD_FontSlot slot) internal RD_SettingVal rd_setting_val_from_code(RD_SettingCode code) { - RD_Window *window = rd_window_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); RD_SettingVal result = {0}; - if(window != 0) + if(ws != 0) { - result = window->setting_vals[code]; + result = ws->setting_vals[code]; } if(result.set == 0) { @@ -10626,14 +10372,11 @@ rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) } //- rjf: serialize windows + if(source == RD_CfgSrc_User) { B32 first = 1; - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) + for(RD_WindowState *window = rd_state->first_window_state; window != 0; window = window->order_next) { - if(window->cfg_src != source) - { - continue; - } if(first) { first = 0; @@ -11694,6 +11437,57 @@ rd_frame(void) rd_state->ctrl_entity_meval_cache_slots_count = 1024; rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count); + ////////////////////////////// + //- rjf: garbage collect untouched window states + // + if(depth == 0) DeferLoop(depth += 1, depth -= 1) + { + for EachIndex(slot_idx, rd_state->window_state_slots_count) + { + for(RD_WindowState *ws = rd_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) + { + next = ws->hash_next; + if(ws->last_frame_index_touched+1 < rd_state->frame_index) + { + ui_state_release(ws->ui); + r_window_unequip(ws->os, ws->r); + os_window_close(ws->os); + arena_release(ws->query_cmd_arena); + arena_release(ws->ctx_menu_arena); + arena_release(ws->drop_completion_arena); + arena_release(ws->hover_eval_arena); + arena_release(ws->autocomp_lister_params_arena); + arena_release(ws->arena); + DLLRemove_NP(rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); + SLLStackPush_N(rd_state->free_window_state, ws, order_next); + } + } + } + } + + ////////////////////////////// + //- rjf: garbage collect untouched view states + // + if(depth == 0) + { + for EachIndex(slot_idx, rd_state->view_state_slots_count) + { + for(RD_ViewState *vs = rd_state->view_state_slots[slot_idx].first, *next; vs != 0; vs = next) + { + next = vs->hash_next; + if(vs->last_frame_index_touched+1 < rd_state->frame_index) + { + for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) + { + arena_release(ext->arena); + } + arena_release(vs->arena); + } + } + } + } + ////////////////////////////// //- rjf: get events from the OS // @@ -11811,12 +11605,12 @@ rd_frame(void) RD_RegsScope() { next = event->next; - RD_Window *window = rd_window_from_os_handle(event->window); - if(window != 0 && window != rd_window_from_handle(rd_regs()->window)) + RD_WindowState *ws = rd_window_state_from_os_handle(event->window); + if(ws != 0 && ws != rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window))) { - rd_regs()->window = rd_handle_from_window(window); - rd_regs()->panel = rd_handle_from_panel(window->focused_panel); - rd_regs()->view = window->focused_panel->selected_tab_view; + rd_regs()->window = ws->cfg_handle; + rd_regs()->panel = rd_handle_from_panel(ws->focused_panel); + rd_regs()->view = ws->focused_panel->selected_tab_view; } B32 take = 0; @@ -11827,10 +11621,10 @@ rd_frame(void) } //- rjf: try window close - if(!take && event->kind == OS_EventKind_WindowClose && window != 0) + if(!take && event->kind == OS_EventKind_WindowClose && ws != 0) { take = 1; - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(window)); + rd_cmd(RD_CmdKind_CloseWindow, .window = ws->cfg_handle); } //- rjf: try menu bar operations @@ -11839,34 +11633,34 @@ rd_frame(void) { take = 1; rd_request_frame(); - window->menu_bar_focused_on_press = window->menu_bar_focused; - window->menu_bar_key_held = 1; - window->menu_bar_focus_press_started = 1; + ws->menu_bar_focused_on_press = ws->menu_bar_focused; + ws->menu_bar_key_held = 1; + ws->menu_bar_focus_press_started = 1; } if(!take && event->kind == OS_EventKind_Release && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_key_held = 0; + ws->menu_bar_key_held = 0; } - if(window->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) + if(ws->menu_bar_focused && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_focused = 0; + ws->menu_bar_focused = 0; } - else if(window->menu_bar_focus_press_started && !window->menu_bar_focused && event->kind == OS_EventKind_Release && event->modifiers == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) + else if(ws->menu_bar_focus_press_started && !ws->menu_bar_focused && event->kind == OS_EventKind_Release && event->modifiers == 0 && event->key == OS_Key_Alt && event->is_repeat == 0) { take = 1; rd_request_frame(); - window->menu_bar_focused = !window->menu_bar_focused_on_press; - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focused = !ws->menu_bar_focused_on_press; + ws->menu_bar_focus_press_started = 0; } - else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && window->menu_bar_focused && !ui_any_ctx_menu_is_open()) + else if(event->kind == OS_EventKind_Press && event->key == OS_Key_Esc && ws->menu_bar_focused && !ui_any_ctx_menu_is_open()) { take = 1; rd_request_frame(); - window->menu_bar_focused = 0; + ws->menu_bar_focused = 0; } } @@ -11889,13 +11683,13 @@ rd_frame(void) take = 1; if(event->modifiers & OS_Modifier_Alt) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } } } else if(OS_Key_F1 <= event->key && event->key <= OS_Key_F19) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } rd_request_frame(); } @@ -11910,7 +11704,7 @@ rd_frame(void) take = 1; if(event->modifiers & OS_Modifier_Alt) { - window->menu_bar_focus_press_started = 0; + ws->menu_bar_focus_press_started = 0; } } @@ -12250,6 +12044,19 @@ rd_frame(void) } } + //////////////////////////// + //- rjf: sanitize the window/panel/tab tree structure + // + { + // TODO(rjf): @cfg in the past, we had a spot in the rd_window_frame, + // which ensured to select tabs, if a panel had tabs but had none + // selected, and if a panel had a selected tab but it was project-filtered. + // this is effectively just fixing up unexpected malformations of the + // panel tree - because we are adopting some number of new possibilities + // of this via the cfg change, we can just actually do a single fixup + // point here. + } + //////////////////////////// //- rjf: process top-level graphical commands // @@ -12267,7 +12074,7 @@ rd_frame(void) // rjf: process command Dir2 split_dir = Dir2_Invalid; - RD_Panel *split_panel = &rd_nil_panel; + RD_Cfg *split_panel = &rd_nil_cfg; U64 panel_sib_off = 0; U64 panel_child_off = 0; Vec2S32 panel_change_dir = {0}; @@ -12339,14 +12146,15 @@ rd_frame(void) // rjf: command has required query -> prep query else { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); + if(ws != 0) { - arena_clear(window->query_cmd_arena); - window->query_cmd_name = push_str8_copy(window->query_cmd_arena, cmd->regs->cmd_name); - window->query_cmd_regs = rd_regs_copy(window->query_cmd_arena, rd_regs()); - MemoryZeroArray(window->query_cmd_regs_mask); - window->query_view_selected = 1; + arena_clear(ws->query_cmd_arena); + ws->query_cmd_name = push_str8_copy(ws->query_cmd_arena, cmd->regs->cmd_name); + ws->query_cmd_regs = rd_regs_copy(ws->query_cmd_arena, rd_regs()); + MemoryZeroArray(ws->query_cmd_regs_mask); + ws->query_view_selected = 1; } } }break; @@ -12385,73 +12193,51 @@ rd_frame(void) //- rjf: windows case RD_CmdKind_OpenWindow: { - RD_Window *originating_window = rd_window_from_handle(rd_regs()->window); - if(originating_window == 0) + RD_Cfg *old_window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *bucket = old_window->parent; + if(bucket == &rd_nil_cfg) { - originating_window = rd_state->first_window; + bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); } - OS_Handle preferred_monitor = {0}; - RD_Window *new_ws = rd_window_open(v2f32(1280, 720), preferred_monitor, RD_CfgSrc_User); - if(originating_window) + RD_Cfg *new_window = rd_cfg_new(bucket, str8_lit("window")); + RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); + rd_cfg_newf(size, "1280"); + rd_cfg_newf(size, "720"); + for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { - MemoryCopy(new_ws->setting_vals, originating_window->setting_vals, sizeof(RD_SettingVal)*RD_SettingCode_COUNT); + if(!str8_match(old_child->string, str8_lit("panels"), 0)) + { + RD_Cfg *new_child = rd_cfg_deep_copy(old_child); + rd_cfg_insert_child(new_window, new_window->last, new_child); + } } }break; case RD_CmdKind_CloseWindow: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - if(ws != 0) - { - // rjf: is this the last window? -> exit - if(rd_state->first_window == rd_state->last_window && rd_state->first_window == ws) - { - rd_cmd(RD_CmdKind_Exit); - } - - // rjf: not the last window? -> just release this window - else - { - // NOTE(rjf): we need to explicitly release all panel views, because views - // are a global concept and otherwise would leak. - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - rd_panel_release_all_views(panel); - } - - ui_state_release(ws->ui); - DLLRemove(rd_state->first_window, rd_state->last_window, ws); - r_window_unequip(ws->os, ws->r); - os_window_close(ws->os); - arena_release(ws->query_cmd_arena); - arena_release(ws->ctx_menu_arena); - arena_release(ws->drop_completion_arena); - arena_release(ws->hover_eval_arena); - arena_release(ws->autocomp_lister_params_arena); - arena_release(ws->arena); - SLLStackPush(rd_state->free_window, ws); - ws->gen += 1; - } - } + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + rd_cfg_release(wcfg); }break; case RD_CmdKind_ToggleFullscreen: { - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); + if(ws != &rd_nil_window_state) { - os_window_set_fullscreen(window->os, !os_window_is_fullscreen(window->os)); + os_window_set_fullscreen(ws->os, !os_window_is_fullscreen(ws->os)); } }break; case RD_CmdKind_BringToFront: { - RD_Window *last_focused_window = rd_window_from_handle(rd_state->last_focused_window); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + RD_Cfg *last_focused_wcfg = rd_cfg_from_handle(rd_state->last_focused_window); + RD_WindowState *last_focused_ws = rd_window_state_from_cfg(last_focused_wcfg); + if(last_focused_ws == &rd_nil_window_state) { - os_window_set_minimized(w->os, 0); - os_window_focus(last_focused_window->os); + last_focused_ws = rd_state->first_window_state; } - if(last_focused_window != 0) + if(last_focused_ws != &rd_nil_window_state) { - os_window_focus(last_focused_window->os); + os_window_set_minimized(last_focused_ws->os, 0); + os_window_focus(last_focused_ws->os); } }break; @@ -12507,6 +12293,36 @@ rd_frame(void) { rd_cfg_insert_child(file_root, file_root->last, n->v); } + + //- rjf: if config did not open any windows for the user, then we need to open a sensible default + { + if(str8_match(file_root_key, str8_lit("user"), 0)) + { + RD_CfgList all_user_windows = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("window")); + if(all_user_windows.count == 0) + { + OS_Handle monitor = os_primary_monitor(); + String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); + Vec2F32 monitor_dim = os_dim_from_monitor(monitor); + F32 monitor_dpi = os_dpi_from_monitor(monitor); + Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); + RD_Cfg *new_window = rd_cfg_new(file_root, str8_lit("window")); + RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); + rd_cfg_newf(size, "%f", window_dim.x); + rd_cfg_newf(size, "%f", window_dim.y); + F32 line_height_guess = 11.f * (monitor_dpi / 96.f); + F32 num_lines_in_monitor_height = monitor_dim.y / line_height_guess; + if(num_lines_in_monitor_height < 100) + { + rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_cfg(new_window)); + } + else + { + rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_cfg(new_window)); + } + } + } + } } // TODO(rjf): dear lord this is so overcomplicated, this needs to be collapsed down & simplified ASAP @@ -12941,16 +12757,6 @@ rd_frame(void) } } - //- rjf: eliminate all windows - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) - { - if(window->cfg_src != src) - { - continue; - } - rd_cmd(RD_CmdKind_CloseWindow, .window = rd_handle_from_window(window)); - } - //- rjf: apply fonts { FNT_Tag defaults[RD_FontSlot_COUNT] = @@ -13090,198 +12896,6 @@ rd_frame(void) } } } - - // rjf: open window - RD_Window *ws = rd_window_open(size, preferred_monitor, window_tree->source); - if(dpi != 0.f) { ws->last_dpi = dpi; } - for EachEnumVal(RD_SettingCode, code) - { - if(setting_vals[code].set == 0 && rd_setting_code_default_is_per_window_table[code]) - { - setting_vals[code] = rd_setting_code_default_val_table[code]; - } - } - MemoryCopy(ws->setting_vals, setting_vals, sizeof(setting_vals[0])*ArrayCount(setting_vals)); - - // rjf: build panel tree - MD_Node *panel_tree = md_child_from_string(window_tree->root, str8_lit("panels"), 0); - RD_Panel *panel_parent = ws->root_panel; - panel_parent->split_axis = top_level_split_axis; - MD_NodeRec rec = {0}; - for(MD_Node *n = panel_tree, *next = &md_nil_node; - !md_node_is_nil(n); - n = next) - { - // rjf: assume we're just moving to the next one initially... - next = n->next; - - // rjf: grab root panel - RD_Panel *panel = &rd_nil_panel; - if(n == panel_tree) - { - panel = ws->root_panel; - panel->pct_of_parent = 1.f; - } - - // rjf: allocate & insert non-root panels - these will have a numeric string, determining - // pct of parent - if(n->flags & MD_NodeFlag_Numeric) - { - panel = rd_panel_alloc(ws); - rd_panel_insert(panel_parent, panel_parent->last, panel); - panel->split_axis = axis2_flip(panel_parent->split_axis); - panel->pct_of_parent = (F32)f64_from_str8(n->string); - } - - // rjf: do general per-panel work - if(!rd_panel_is_nil(panel)) - { - // rjf: determine if this panel has panel children - B32 has_panel_children = 0; - for MD_EachNode(child, n->first) - { - if(child->flags & MD_NodeFlag_Numeric) - { - has_panel_children = 1; - break; - } - } - - // rjf: apply panel options - for MD_EachNode(op, n->first) - { - if(md_node_is_nil(op->first) && str8_match(op->string, str8_lit("tabs_on_bottom"), 0)) - { - panel->tab_side = Side_Max; - } - } - - // rjf: apply panel views/tabs/commands - RD_View *selected_view = &rd_nil_view; - for MD_EachNode(op, n->first) - { - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(op->string); - if(view_rule_info == &rd_nil_view_rule_info || has_panel_children != 0) - { - continue; - } - - // rjf: allocate view & apply view-specific parameterizations - RD_View *view = &rd_nil_view; - B32 view_is_selected = 0; - RD_ViewRuleInfoFlags view_rule_info_flags = view_rule_info->flags; - { - // rjf: allocate view - view = rd_view_alloc(); - - // rjf: check if this view is selected - view_is_selected = !md_node_is_nil(md_child_from_string(op, str8_lit("selected"), 0)); - - // rjf: read project path - String8 project_path = str8_lit(""); - { - MD_Node *project_node = md_child_from_string(op, str8_lit("project"), 0); - if(!md_node_is_nil(project_node)) - { - project_path = path_absolute_dst_from_relative_dst_src(scratch.arena, project_node->first->string, cfg_folder); - } - } - - // rjf: read view query string - String8 view_query = str8_lit(""); - { - String8 escaped_query = md_child_from_string(op, str8_lit("query"), 0)->first->string; - view_query = raw_from_escaped_str8(scratch.arena, escaped_query); - } - - // rjf: convert file queries from relative to absolute - { - String8 query_file_path = rd_file_path_from_eval_string(scratch.arena, view_query); - if(query_file_path.size != 0) - { - query_file_path = path_absolute_dst_from_relative_dst_src(scratch.arena, query_file_path, cfg_folder); - view_query = push_str8f(scratch.arena, "file:\"%S\"", query_file_path); - } - } - - // rjf: set up view - rd_view_equip_spec(view, view_rule_info, view_query, op); - if(project_path.size != 0) - { - arena_clear(view->project_path_arena); - view->project_path = push_str8_copy(view->project_path_arena, project_path); - } - } - - // rjf: insert - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(panel, panel->last_tab_view, view); - if(view_is_selected) - { - selected_view = view; - } - } - } - - // rjf: select selected view - if(!rd_view_is_nil(selected_view)) - { - panel->selected_tab_view = rd_handle_from_view(selected_view); - } - - // rjf: recurse from this panel - if(has_panel_children) - { - next = n->first; - panel_parent = panel; - } - else for(MD_Node *p = n; - p != &md_nil_node && p != panel_tree; - p = p->parent, panel_parent = panel_parent->parent) - { - if(p->next != &md_nil_node) - { - next = p->next; - break; - } - } - } - } - - // rjf: initiate fullscreen - if(is_fullscreen) - { - os_window_set_fullscreen(ws->os, 1); - } - - // rjf: initiate maximize - if(is_maximized) - { - os_window_set_maximized(ws->os, 1); - } - - // rjf: focus the biggest panel - { - RD_Panel *best_leaf_panel = &rd_nil_panel; - F32 best_leaf_panel_area = 0; - Rng2F32 root_rect = r2f32p(0, 0, 1000, 1000); // NOTE(rjf): we can assume any size - just need proportions. - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(rd_panel_is_nil(panel->first)) - { - Rng2F32 rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); - Vec2F32 dim = dim_2f32(rect); - F32 area = dim.x*dim.y; - if(best_leaf_panel_area == 0 || area > best_leaf_panel_area) - { - best_leaf_panel_area = area; - best_leaf_panel = panel; - } - } - } - ws->focused_panel = best_leaf_panel; - } } //- rjf: apply keybindings @@ -13508,6 +13122,7 @@ rd_frame(void) } //- rjf: if config opened 0 windows, we need to do some sensible default +#if 0 // TODO(rjf): @cfg if(src == RD_CfgSrc_User && windows->first == &d_nil_cfg_tree) { OS_Handle preferred_monitor = os_primary_monitor(); @@ -13525,6 +13140,7 @@ rd_frame(void) rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_window(ws)); } } +#endif //- rjf: if config bound 0 keys, we need to do some sensible default if(src == RD_CfgSrc_User && rd_state->key_map_total_count == 0) @@ -13607,46 +13223,66 @@ rd_frame(void) case RD_CmdKind_IncUIFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *main_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("main_font_size")); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(main_font_size_cfg == &rd_nil_cfg) { - window->setting_vals[RD_SettingCode_MainFontSize].set = 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 += 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_MainFontSize], window->setting_vals[RD_SettingCode_MainFontSize].s32); + main_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("main_font_size")); + rd_cfg_newf(main_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); } + F32 size = (F32)f64_from_str8(main_font_size_cfg->first->string); + size += 1; + size = Clamp(6, size, 72); + rd_cfg_equip_stringf(main_font_size_cfg->first, "%f", size); }break; case RD_CmdKind_DecUIFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *main_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("main_font_size")); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(main_font_size_cfg == &rd_nil_cfg) { - window->setting_vals[RD_SettingCode_MainFontSize].set = 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 -= 1; - window->setting_vals[RD_SettingCode_MainFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_MainFontSize], window->setting_vals[RD_SettingCode_MainFontSize].s32); + main_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("main_font_size")); + rd_cfg_newf(main_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); } + F32 size = (F32)f64_from_str8(main_font_size_cfg->first->string); + size -= 1; + size = Clamp(6, size, 72); + rd_cfg_equip_stringf(main_font_size_cfg->first, "%f", size); }break; case RD_CmdKind_IncCodeFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *code_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("code_font_size")); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(code_font_size_cfg == &rd_nil_cfg) { - window->setting_vals[RD_SettingCode_CodeFontSize].set = 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 += 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_CodeFontSize], window->setting_vals[RD_SettingCode_CodeFontSize].s32); + code_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("code_font_size")); + rd_cfg_newf(code_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); } + F32 size = (F32)f64_from_str8(code_font_size_cfg->first->string); + size += 1; + size = Clamp(6, size, 72); + rd_cfg_equip_stringf(code_font_size_cfg->first, "%f", size); }break; case RD_CmdKind_DecCodeFontScale: { fnt_reset(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - if(window != 0) + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *code_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("code_font_size")); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(code_font_size_cfg == &rd_nil_cfg) { - window->setting_vals[RD_SettingCode_CodeFontSize].set = 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 -= 1; - window->setting_vals[RD_SettingCode_CodeFontSize].s32 = clamp_1s32(rd_setting_code_s32_range_table[RD_SettingCode_CodeFontSize], window->setting_vals[RD_SettingCode_CodeFontSize].s32); + code_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("code_font_size")); + rd_cfg_newf(code_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); } + F32 size = (F32)f64_from_str8(code_font_size_cfg->first->string); + size -= 1; + size = Clamp(6, size, 72); + rd_cfg_equip_stringf(code_font_size_cfg->first, "%f", size); }break; //- rjf: panel creation @@ -13657,65 +13293,70 @@ rd_frame(void) case RD_CmdKind_SplitPanel: { split_dir = rd_regs()->dir2; - split_panel = rd_panel_from_handle(rd_regs()->dst_panel); + split_panel = rd_cfg_from_handle(rd_regs()->dst_panel); }goto split; split:; if(split_dir != Dir2_Invalid) { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - if(rd_panel_is_nil(split_panel)) - { - split_panel = ws->focused_panel; - } - RD_Panel *new_panel = &rd_nil_panel; + // rjf: unpack Axis2 split_axis = axis2_from_dir2(split_dir); Side split_side = side_from_dir2(split_dir); - RD_Panel *panel = split_panel; - RD_Panel *parent = panel->parent; - if(!rd_panel_is_nil(parent) && parent->split_axis == split_axis) + RD_Cfg *new_panel_cfg = &rd_nil_cfg; + RD_PanelNode *panel_root = rd_panel_tree_from_cfg(scratch.arena, split_panel); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_root, split_panel); + RD_PanelNode *parent = panel->parent; + + // rjf: splitting on same axis as parent -> insert new sibling on same axis, adjust sizes + if(parent != &rd_nil_panel_node && parent->split_axis == split_axis) { - RD_Panel *next = rd_panel_alloc(ws); - rd_panel_insert(parent, split_side == Side_Max ? panel : panel->prev, next); - next->pct_of_parent = 1.f/parent->child_count; - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) + RD_Cfg *parent_cfg = parent->cfg; + RD_Cfg *panel_cfg = panel->cfg; + RD_Cfg *new_cfg = rd_cfg_alloc(); + rd_cfg_insert_child(parent_cfg, split_side == Side_Max ? panel_cfg : panel_cfg->prev, new_cfg); + rd_cfg_equip_stringf(new_cfg, "%f", 1.f/parent->child_count); + for(RD_PanelNode *child = parent->first; child != &rd_nil_panel_node; child = child->next) { - if(child != next) - { - child->pct_of_parent *= (F32)(parent->child_count-1) / (parent->child_count); - } + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct * ((F32)(parent->child_count) / (parent->child_count+1)); + rd_cfg_equip_stringf(child->cfg, "%f", new_pct); } - ws->focused_panel = next; - new_panel = next; + new_panel_cfg = new_cfg; } + + // rjf: splitting on opposite axis as parent - need to create new replacement node, + new sibling else { - RD_Panel *pre_prev = panel->prev; - RD_Panel *pre_parent = parent; - RD_Panel *new_parent = rd_panel_alloc(ws); - new_parent->pct_of_parent = panel->pct_of_parent; - if(!rd_panel_is_nil(pre_parent)) + RD_Cfg *split_panel_prev = panel->prev->cfg; + RD_Cfg *new_parent = rd_cfg_alloc(); + RD_Cfg *new_sibling = rd_cfg_alloc(); + rd_cfg_equip_string(new_parent, split_panel->string); + rd_cfg_equip_string(split_panel, str8_lit("0.5")); + rd_cfg_equip_string(new_sibling, str8_lit("0.5")); + if(parent->cfg != &rd_nil_cfg) { - rd_panel_remove(pre_parent, panel); - rd_panel_insert(pre_parent, pre_prev, new_parent); + rd_cfg_unhook(parent->cfg, split_panel); + rd_cfg_insert_child(parent->cfg, split_panel_prev, new_parent); } else { - ws->root_panel = new_parent; + rd_cfg_equip_string(new_parent, str8_lit("panels")); + RD_Cfg *window_cfg = rd_window_from_cfg(split_panel); + rd_cfg_insert_child(window_cfg, window_cfg->last, new_parent); } - RD_Panel *left = panel; - RD_Panel *right = rd_panel_alloc(ws); - new_panel = right; + RD_Cfg *min = split_panel; + RD_Cfg *max = new_sibling; if(split_side == Side_Min) { - Swap(RD_Panel *, left, right); + Swap(RD_Cfg *, min, max); } - rd_panel_insert(new_parent, &rd_nil_panel, left); - rd_panel_insert(new_parent, left, right); - new_parent->split_axis = split_axis; - left->pct_of_parent = 0.5f; - right->pct_of_parent = 0.5f; - ws->focused_panel = new_panel; + rd_cfg_insert_child(new_parent, new_parent->last, min); + rd_cfg_insert_child(new_parent, new_parent->last, max); + new_panel_cfg = new_sibling; } + + // rjf: pre-emptively set up the animation rectangle, depending on where + // the new panel was inserted (?) +#if 0 // TODO(rjf): @cfg if(!rd_panel_is_nil(new_panel->prev)) { Rng2F32 prev_rect_pct = new_panel->prev->animated_rect_pct; @@ -13728,38 +13369,40 @@ rd_frame(void) new_panel->animated_rect_pct = next_rect_pct; new_panel->animated_rect_pct.p1.v[split_axis] = new_panel->animated_rect_pct.p0.v[split_axis]; } - RD_Panel *move_tab_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *move_tab = rd_view_from_handle(rd_regs()->view); - if(!rd_panel_is_nil(new_panel) && !rd_view_is_nil(move_tab) && !rd_panel_is_nil(move_tab_panel) && - kind == RD_CmdKind_SplitPanel) +#endif + + // rjf: if this split was caused by drag/dropping a tab, and the originating panel + // has no further tabs, then close the originating panel + RD_Cfg *dragdrop_origin_panel_cfg = rd_cfg_from_handle(rd_regs()->panel); + RD_Cfg *dragdrop_tab = rd_cfg_from_handle(rd_regs()->view); + if(kind == RD_CmdKind_SplitPanel && + new_panel_cfg != &rd_nil_cfg && dragdrop_tab != &rd_nil_cfg && dragdrop_origin_panel_cfg != &rd_nil_cfg) { - rd_panel_remove_tab_view(move_tab_panel, move_tab); - rd_panel_insert_tab_view(new_panel, new_panel->last_tab_view, move_tab); - new_panel->selected_tab_view = rd_handle_from_view(move_tab); - B32 move_tab_panel_is_empty = 1; - for(RD_View *v = move_tab_panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + rd_cfg_unhook(dragdrop_origin_panel_cfg, dragdrop_tab); + rd_cfg_insert_child(new_panel_cfg, new_panel_cfg->last, dragdrop_tab); + RD_PanelNode *origin_panel_tree = rd_panel_tree_from_cfg(scratch.arena, dragdrop_origin_panel_cfg); + RD_PanelNode *origin_panel = rd_panel_node_from_tree_cfg(origin_panel_tree, dragdrop_origin_panel_cfg); + if(origin_panel->tabs.count == 0) { - if(!rd_view_is_project_filtered(v)) - { - move_tab_panel_is_empty = 0; - break; - } - } - if(move_tab_panel_is_empty && move_tab_panel != ws->root_panel && - move_tab_panel != new_panel->prev && move_tab_panel != new_panel->next) - { - rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(move_tab_panel)); + rd_cmd(RD_CmdKind_ClosePanel); } } + + // rjf: focus new panel + if(new_panel_cfg != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(new_panel_cfg)); + } }break; //- rjf: panel rotation case RD_CmdKind_RotatePanelColumns: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = ws->focused_panel; - RD_Panel *parent = &rd_nil_panel; - for(RD_Panel *p = panel->parent; !rd_panel_is_nil(p); p = p->parent) + RD_Cfg *panel_cfg = rd_cfg_from_handle(rd_regs()->panel); + RD_PanelNode *panel_root = rd_panel_tree_from_cfg(scratch.arena, panel_cfg); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_root, panel_cfg); + RD_PanelNode *parent = &rd_nil_panel_node; + for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) { if(p->split_axis == Axis2_X) { @@ -13767,47 +13410,65 @@ rd_frame(void) break; } } - if(!rd_panel_is_nil(parent) && parent->child_count > 1) + if(parent != &rd_nil_panel_node && parent->child_count > 1) { - RD_Panel *old_first = parent->first; - RD_Panel *new_first = parent->first->next; - old_first->next = &rd_nil_panel; - old_first->prev = parent->last; - parent->last->next = old_first; - new_first->prev = &rd_nil_panel; - parent->first = new_first; - parent->last = old_first; + RD_Cfg *rotated = parent->first->cfg; + rd_cfg_unhook(parent->cfg, parent->first->cfg); + rd_cfg_insert_child(parent->cfg, parent->last->cfg, rotated); } }break; //- rjf: panel focusing - case RD_CmdKind_NextPanel: panel_sib_off = OffsetOf(RD_Panel, next); panel_child_off = OffsetOf(RD_Panel, first); goto cycle; - case RD_CmdKind_PrevPanel: panel_sib_off = OffsetOf(RD_Panel, prev); panel_child_off = OffsetOf(RD_Panel, last); goto cycle; + case RD_CmdKind_NextPanel: panel_sib_off = OffsetOf(RD_PanelNode, next); panel_child_off = OffsetOf(RD_PanelNode, first); goto cycle; + case RD_CmdKind_PrevPanel: panel_sib_off = OffsetOf(RD_PanelNode, prev); panel_child_off = OffsetOf(RD_PanelNode, last); goto cycle; cycle:; { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - for(RD_Panel *panel = ws->focused_panel; !rd_panel_is_nil(panel);) + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(rd_regs()->window)); + RD_PanelNode *next_focused = &rd_nil_panel_node; + for(RD_PanelNode *p = panel_tree.focused; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) { - RD_PanelRec rec = rd_panel_rec_depth_first(panel, panel_sib_off, panel_child_off); - panel = rec.next; - if(rd_panel_is_nil(panel)) + if(p->first == &rd_nil_panel_node) { - panel = ws->root_panel; - } - if(rd_panel_is_nil(panel->first)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); + next_focused = p; break; } } + if(next_focused == &rd_nil_panel_node) + { + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) + { + if(p->first == &rd_nil_panel_node) + { + next_focused = p; + } + } + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(next_focused->cfg)); }break; case RD_CmdKind_FocusPanel: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - if(!rd_panel_is_nil(panel)) + RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - ws->focused_panel = panel; + RD_Cfg *p_cfg = p->cfg; + RD_Cfg *p_selection = rd_cfg_child_from_string(p_cfg, str8_lit("selected")); + if(p_selection != &rd_nil_cfg) + { + rd_cfg_release(p_selection); + } + } + if(panel != &rd_nil_cfg) + { + rd_cfg_new(panel, str8_lit("selected")); + RD_Cfg *window = rd_window_from_cfg(panel); + RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; ws->query_view_selected = 0; } @@ -14168,7 +13829,6 @@ rd_frame(void) //- rjf: files case RD_CmdKind_Open: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); String8 path = rd_regs()->file_path; FileProperties props = os_properties_from_file_path(path); if(props.created != 0) @@ -16871,21 +16531,26 @@ rd_frame(void) // { dr_begin_frame(); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for EachIndex(slot_idx, rd_state->window_state_slots_count) { - B32 window_is_focused = os_window_is_focused(w->os); - if(window_is_focused) + for(RD_WindowState *w = rd_state->window_state_slots[slot_idx]; + w != 0; + w = w->next) { - rd_state->last_focused_window = rd_handle_from_window(w); - } - rd_push_regs(); - rd_regs()->window = rd_handle_from_window(w); - rd_window_frame(w); - MemoryZeroStruct(&w->ui_events); - RD_Regs *window_regs = rd_pop_regs(); - if(rd_window_from_handle(rd_state->last_focused_window) == w) - { - MemoryCopyStruct(rd_regs(), window_regs); + B32 window_is_focused = os_window_is_focused(w->os); + if(window_is_focused) + { + rd_state->last_focused_window = rd_handle_from_window(w); + } + rd_push_regs(); + rd_regs()->window = w->cfg_handle; + rd_window_frame(w); + MemoryZeroStruct(&w->ui_events); + RD_Regs *window_regs = rd_pop_regs(); + if(rd_window_from_handle(rd_state->last_focused_window) == w) + { + MemoryCopyStruct(rd_regs(), window_regs); + } } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 196a6328..5a46b69c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -169,8 +169,6 @@ typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); //////////////////////////////// //~ rjf: View Types -typedef struct RD_View RD_View; - typedef struct RD_ArenaExt RD_ArenaExt; struct RD_ArenaExt { @@ -178,126 +176,49 @@ struct RD_ArenaExt Arena *arena; }; -typedef struct RD_TransientViewNode RD_TransientViewNode; -struct RD_TransientViewNode +typedef struct RD_ViewState RD_ViewState; +struct RD_ViewState { - RD_TransientViewNode *next; - RD_TransientViewNode *prev; - EV_Key key; - RD_View *view; - Arena *initial_params_arena; - MD_Node *initial_params; - U64 first_frame_index_touched; + // rjf: hash links & key + RD_ViewState *hash_next; + RD_ViewState *hash_prev; + RD_Handle cfg_handle; + EV_Key ev_key; + + // rjf: touch info U64 last_frame_index_touched; -}; - -typedef struct RD_TransientViewSlot RD_TransientViewSlot; -struct RD_TransientViewSlot -{ - RD_TransientViewNode *first; - RD_TransientViewNode *last; -}; - -typedef struct RD_View RD_View; -struct RD_View -{ - // rjf: allocation links (for iterating all views) - RD_View *alloc_next; - RD_View *alloc_prev; - // rjf: ownership links ('owners' can have lists of views) - RD_View *order_next; - RD_View *order_prev; - - // rjf: transient view children - RD_View *first_transient; - RD_View *last_transient; - - // rjf: view specification info - struct RD_ViewRuleInfo *spec; - - // rjf: allocation info - U64 generation; - - // rjf: loading animation state - F32 loading_t; + // rjf: loading indicator info F32 loading_t_target; U64 loading_progress_v; U64 loading_progress_v_target; - // rjf: view project (for project-specific/filtered views) - Arena *project_path_arena; - String8 project_path; - - // rjf: view state + // rjf: scroll position UI_ScrollPt2 scroll_pos; // rjf: view-lifetime allocation & user data extensions Arena *arena; RD_ArenaExt *first_arena_ext; RD_ArenaExt *last_arena_ext; - U64 transient_view_slots_count; - RD_TransientViewSlot *transient_view_slots; - RD_TransientViewNode *free_transient_view_node; void *user_data; - // rjf: filter mode + // rjf: expression string + U8 expression_buffer[KB(1)]; + U64 expression_string_size; + + // rjf: filter editing controls B32 is_filtering; - F32 is_filtering_t; - - // rjf: params tree state - Arena *params_arenas[2]; - MD_Node *params_roots[2]; - U64 params_write_gen; - U64 params_read_gen; - - // rjf: text query state - TxtPt query_cursor; - TxtPt query_mark; - U64 query_string_size; - U8 query_buffer[KB(4)]; + TxtPt filter_cursor; + TxtPt filter_mark; + U8 filter_buffer[KB(1)]; + U64 filter_string_size; }; -//////////////////////////////// -//~ rjf: Panel Types - -typedef struct RD_Panel RD_Panel; -struct RD_Panel +typedef struct RD_ViewStateSlot RD_ViewStateSlot; +struct RD_ViewStateSlot { - // rjf: tree links/data - RD_Panel *first; - RD_Panel *last; - RD_Panel *next; - RD_Panel *prev; - RD_Panel *parent; - U64 child_count; - - // rjf: allocation data - U64 generation; - - // rjf: split data - Axis2 split_axis; - F32 pct_of_parent; - - // rjf: animated rectangle data - Rng2F32 animated_rect_pct; - - // rjf: tab params - Side tab_side; - - // rjf: stable views (tabs) - RD_View *first_tab_view; - RD_View *last_tab_view; - U64 tab_view_count; - RD_Handle selected_tab_view; -}; - -typedef struct RD_PanelRec RD_PanelRec; -struct RD_PanelRec -{ - RD_Panel *next; - int push_count; - int pop_count; + RD_ViewState *first; + RD_ViewState *last; }; //////////////////////////////// @@ -414,6 +335,48 @@ struct RD_CfgRec S32 pop_count; }; +//////////////////////////////// +//~ rjf: New Panel Types (Queried From Config) + +typedef struct RD_PanelNode RD_PanelNode; +struct RD_PanelNode +{ + // rjf: links data + RD_PanelNode *first; + RD_PanelNode *last; + RD_PanelNode *next; + RD_PanelNode *prev; + RD_PanelNode *parent; + U64 child_count; + RD_Cfg *cfg; + + // rjf: split data + Axis2 split_axis; + F32 pct_of_parent; + + // rjf: tab params + Side tab_side; + + // rjf: which tabs are attached + RD_CfgList tabs; + RD_Cfg *selected_tab; +}; + +typedef struct RD_PanelTree RD_PanelTree; +struct RD_PanelTree +{ + RD_PanelNode *root; + RD_PanelNode *focused; +}; + +typedef struct RD_PanelNodeRec RD_PanelNodeRec; +struct RD_PanelNodeRec +{ + RD_PanelNode *next; + S32 push_count; + S32 pop_count; +}; + //////////////////////////////// //~ rjf: Entity Types @@ -618,15 +581,17 @@ struct RD_AutoCompListerParams //////////////////////////////// //~ rjf: Per-Window State -typedef struct RD_Window RD_Window; -struct RD_Window +typedef struct RD_WindowState RD_WindowState; +struct RD_WindowState { // rjf: links & metadata - RD_Window *next; - RD_Window *prev; - U64 gen; + RD_WindowState *order_next; + RD_WindowState *order_prev; + RD_WindowState *hash_next; + RD_WindowState *hash_prev; + RD_Handle cfg_handle; U64 frames_alive; - RD_CfgSrc cfg_src; + U64 last_frame_index_touched; // rjf: top-level info & handles Arena *arena; @@ -681,7 +646,6 @@ struct RD_Window String8 query_cmd_name; RD_Regs *query_cmd_regs; U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; - RD_View *query_view_stack_top; B32 query_view_selected; F32 query_view_selected_t; F32 query_view_t; @@ -708,11 +672,6 @@ struct RD_Window U64 error_string_size; F32 error_t; - // rjf: panel state - RD_Panel *root_panel; - RD_Panel *free_panel; - RD_Panel *focused_panel; - // rjf: per-frame ui events state UI_EventList ui_events; @@ -720,6 +679,13 @@ struct RD_Window DR_Bucket *draw_bucket; }; +typedef struct RD_WindowStateSlot RD_WindowStateSlot; +struct RD_WindowStateSlot +{ + RD_WindowState *first; + RD_WindowState *last; +}; + //////////////////////////////// //~ rjf: Eval Visualization View Cache Types @@ -879,6 +845,19 @@ struct RD_State RD_Cfg *free_cfg; RD_Cfg *root_cfg; + // rjf: window state cache + U64 window_state_slots_count; + RD_WindowStateSlot *window_state_slots; + RD_WindowState *free_window_state; + RD_Handle last_focused_window; + RD_WindowState *first_window_state; + RD_WindowState *last_window_state; + + // rjf: view state cache + U64 view_state_slots_count; + RD_ViewStateSlot *view_state_slots; + RD_ViewState *free_view_state; + //- // TODO(rjf): TO BE ELIMINATED OR REPLACED VVVVVVVVVVVVVVVV //- @@ -910,21 +889,6 @@ struct RD_State String8 bind_change_cmd_name; RD_Binding bind_change_binding; - // rjf: windows - RD_Window *first_window; - RD_Window *last_window; - RD_Window *free_window; - U64 window_count; - B32 last_window_queued_save; - RD_Handle last_focused_window; - - // rjf: view state - RD_View *first_view; - RD_View *last_view; - RD_View *free_view; - U64 free_view_count; - U64 allocated_view_count; - // rjf: config reading state Arena *cfg_path_arenas[RD_CfgSrc_COUNT]; String8 cfg_paths[RD_CfgSrc_COUNT]; @@ -965,6 +929,17 @@ read_only global RD_Cfg rd_nil_cfg = &rd_nil_cfg, }; +read_only global RD_PanelNode rd_nil_panel_node = +{ + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + &rd_nil_panel_node, + 0, + &rd_nil_cfg, +}; + read_only global RD_Entity rd_nil_entity = { &rd_nil_entity, @@ -988,24 +963,18 @@ read_only global RD_ViewRuleInfo rd_nil_view_rule_info = RD_VIEW_RULE_UI_FUNCTION_NAME(null) }; -read_only global RD_View rd_nil_view = +read_only global RD_ViewState rd_nil_view_state = { - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view, - &rd_nil_view_rule_info, + &rd_nil_view_state, + &rd_nil_view_state, }; -read_only global RD_Panel rd_nil_panel = +read_only global RD_WindowState rd_nil_window_state = { - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, - &rd_nil_panel, + &rd_nil_window_state, + &rd_nil_window_state, + &rd_nil_window_state, + &rd_nil_window_state, }; global RD_State *rd_state = 0; @@ -1071,14 +1040,6 @@ internal Vec4F32 rd_rgba_from_entity(RD_Entity *entity); internal EV_Key rd_ev_key_from_entity(RD_Entity *entity); internal EV_Key rd_parent_ev_key_from_entity(RD_Entity *entity); -//////////////////////////////// -//~ rjf: View Type Functions - -internal B32 rd_view_is_nil(RD_View *view); -internal B32 rd_view_is_project_filtered(RD_View *view); -internal RD_Handle rd_handle_from_view(RD_View *view); -internal RD_View *rd_view_from_handle(RD_Handle handle); - //////////////////////////////// //~ rjf: View Spec Type Functions @@ -1089,44 +1050,7 @@ internal RD_ViewRuleInfo *rd_view_rule_info_from_string(String8 string); //////////////////////////////// //~ rjf: Panel Type Functions -//- rjf: basic type functions -internal B32 rd_panel_is_nil(RD_Panel *panel); -internal RD_Handle rd_handle_from_panel(RD_Panel *panel); -internal RD_Panel *rd_panel_from_handle(RD_Handle handle); -internal UI_Key rd_ui_key_from_panel(RD_Panel *panel); -//- rjf: tree construction -internal void rd_panel_insert(RD_Panel *parent, RD_Panel *prev_child, RD_Panel *new_child); -internal void rd_panel_remove(RD_Panel *parent, RD_Panel *child); - -//- rjf: tree walk -internal RD_PanelRec rd_panel_rec_depth_first(RD_Panel *panel, U64 sib_off, U64 child_off); -#define rd_panel_rec_depth_first_pre(panel) rd_panel_rec_depth_first(panel, OffsetOf(RD_Panel, next), OffsetOf(RD_Panel, first)) -#define rd_panel_rec_depth_first_pre_rev(panel) rd_panel_rec_depth_first(panel, OffsetOf(RD_Panel, prev), OffsetOf(RD_Panel, last)) - -//- rjf: panel -> rect calculations -internal Rng2F32 rd_target_rect_from_panel_child(Rng2F32 parent_rect, RD_Panel *parent, RD_Panel *panel); -internal Rng2F32 rd_target_rect_from_panel(Rng2F32 root_rect, RD_Panel *root, RD_Panel *panel); - -//- rjf: view ownership insertion/removal -internal void rd_panel_insert_tab_view(RD_Panel *panel, RD_View *prev_view, RD_View *view); -internal void rd_panel_remove_tab_view(RD_Panel *panel, RD_View *view); -internal RD_View *rd_selected_tab_from_panel(RD_Panel *panel); - -//- rjf: icons & display strings -internal RD_IconKind rd_icon_kind_from_view(RD_View *view); -internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, RD_View *view, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); - -//////////////////////////////// -//~ rjf: Window Type Functions - -internal RD_Handle rd_handle_from_window(RD_Window *window); -internal RD_Window *rd_window_from_handle(RD_Handle handle); - -//////////////////////////////// -//~ rjf: Command Parameters From Context - -internal B32 rd_prefer_dasm_from_window(RD_Window *window); //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions @@ -1153,9 +1077,13 @@ internal void rd_name_release(String8 string); internal RD_Cfg *rd_cfg_alloc(void); internal void rd_cfg_release(RD_Cfg *cfg); +internal RD_Handle rd_handle_from_cfg(RD_Cfg *cfg); +internal RD_Cfg *rd_cfg_from_handle(RD_Handle handle); internal RD_Cfg *rd_cfg_new(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_newf(RD_Cfg *parent, char *fmt, ...); +internal RD_Cfg *rd_cfg_deep_copy(RD_Cfg *src_root); internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string); +internal void rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...); internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child); internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child); internal RD_Cfg *rd_cfg_child_from_string(RD_Cfg *parent, String8 string); @@ -1166,6 +1094,16 @@ internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); internal void rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); +internal RD_PanelTree rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg); +internal RD_PanelNodeRec rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_off, U64 child_off); +#define rd_panel_node_rec__depth_first_pre(root, p) rd_panel_node_rec__depth_first((root), (p), OffsetOf(RD_PanelNode, next), OffsetOf(RD_PanelNode, first)) +#define rd_panel_node_rec__depth_first_pre_rev(root, p) rd_panel_node_rec__depth_first((root), (p), OffsetOf(RD_PanelNode, prev), OffsetOf(RD_PanelNode, last)) +internal RD_PanelNode *rd_panel_node_from_tree_cfg(RD_PanelNode *root, RD_Cfg *cfg); +internal Rng2F32 rd_target_rect_from_panel_node_child(Rng2F32 parent_rect, RD_PanelNode *parent, RD_PanelNode *panel); +internal Rng2F32 rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode *root, RD_PanelNode *panel); + +internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg); + //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1259,28 +1197,11 @@ internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); //////////////////////////////// -//~ rjf: View State Functions +//~ rjf: View Functions -//- rjf: allocation/releasing -internal RD_View *rd_view_alloc(void); -internal void rd_view_release(RD_View *view); - -//- rjf: equipment -internal void rd_view_equip_spec(RD_View *view, RD_ViewRuleInfo *spec, String8 query, MD_Node *params); -internal void rd_view_equip_query(RD_View *view, String8 query); -internal void rd_view_equip_loading_info(RD_View *view, B32 is_loading, U64 progress_v, U64 progress_target); - -//- rjf: user state extensions -internal void *rd_view_get_or_push_user_state(RD_View *view, U64 size); -internal Arena *rd_view_push_arena_ext(RD_View *view); -#define rd_view_user_state(view, type) (type *)rd_view_get_or_push_user_state((view), sizeof(type)) - -//- rjf: param saving -internal void rd_view_store_param(RD_View *view, String8 key, String8 value); -internal void rd_view_store_paramf(RD_View *view, String8 key, char *fmt, ...); -#define rd_view_store_param_f32(view, key, f32) rd_view_store_paramf((view), (key), "%ff", (f32)) -#define rd_view_store_param_s64(view, key, s64) rd_view_store_paramf((view), (key), "%I64d", (s64)) -#define rd_view_store_param_u64(view, key, u64) rd_view_store_paramf((view), (key), "0x%I64x", (u64)) +internal RD_ViewState *rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key); +internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); +internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); //////////////////////////////// //~ rjf: View Building API @@ -1308,25 +1229,12 @@ internal void rd_store_view_paramf(String8 key, char *fmt, ...); #define rd_store_view_param_u64(key, u64) rd_store_view_paramf((key), "0x%I64x", (u64)) //////////////////////////////// -//~ rjf: Expand-Keyed Transient View Functions +//~ rjf: Window Functions -internal RD_TransientViewNode *rd_transient_view_node_from_ev_key(RD_View *owner_view, EV_Key key); - -//////////////////////////////// -//~ rjf: Panel State Functions - -internal RD_Panel *rd_panel_alloc(RD_Window *ws); -internal void rd_panel_release(RD_Window *ws, RD_Panel *panel); -internal void rd_panel_release_all_views(RD_Panel *panel); - -//////////////////////////////// -//~ rjf: Window State Functions - -internal RD_Window *rd_window_open(Vec2F32 size, OS_Handle preferred_monitor, RD_CfgSrc cfg_src); - -internal RD_Window *rd_window_from_os_handle(OS_Handle os); - -internal void rd_window_frame(RD_Window *ws); +internal RD_Cfg *rd_window_from_cfg(RD_Cfg *cfg); +internal RD_WindowState *rd_window_state_from_cfg(RD_Cfg *cfg); +internal RD_WindowState *rd_window_state_from_os_handle(OS_Handle os); +internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization From d9ca51b36feaaabfb64c841fb972c7817e2ba239 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 10 Jan 2025 12:56:45 -0800 Subject: [PATCH 002/755] part 2: furthered progress on cfg switch --- project.4coder | 2 +- src/eval/eval_types.c | 1 + src/raddbg/generated/raddbg.meta.c | 10 +- src/raddbg/generated/raddbg.meta.h | 18 +- src/raddbg/raddbg.mdesk | 6 +- src/raddbg/raddbg_core.c | 1329 +++++++++++++++------------- src/raddbg/raddbg_core.h | 15 +- src/raddbg/raddbg_views.c | 18 +- src/raddbg/raddbg_widgets.c | 5 +- 9 files changed, 760 insertions(+), 644 deletions(-) diff --git a/project.4coder b/project.4coder index 0be9237b..dc18d243 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "build raddbg telemetry clang", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 57706489..13ba76f5 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -626,6 +626,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->byte_size = node->byte_size; switch(type->kind) { + default:{}break; case E_TypeKind_Struct: case E_TypeKind_Union: case E_TypeKind_Class: diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7e6e1fb1..f2a83f62 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -191,7 +191,7 @@ RD_EntityKindFlags rd_entity_kind_flags_table[27] = (0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), }; -Rng1U64 rd_reg_slot_range_table[35] = +Rng1U64 rd_reg_slot_range_table[34] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -201,12 +201,11 @@ Rng1U64 rd_reg_slot_range_table[35] = {OffsetOf(RD_Regs, ctrl_entity), OffsetOf(RD_Regs, ctrl_entity) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, tab), OffsetOf(RD_Regs, tab) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, prev_tab), OffsetOf(RD_Regs, prev_tab) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, entity), OffsetOf(RD_Regs, entity) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, entity_list), OffsetOf(RD_Regs, entity_list) + sizeof(RD_HandleList)}, -{OffsetOf(RD_Regs, ev_key), OffsetOf(RD_Regs, ev_key) + sizeof(EV_Key)}, {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, {OffsetOf(RD_Regs, inline_depth), OffsetOf(RD_Regs, inline_depth) + sizeof(U64)}, {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, @@ -230,7 +229,7 @@ Rng1U64 rd_reg_slot_range_table[35] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[214] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, @@ -303,6 +302,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index bdce8ed9..e2d24b71 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -57,12 +57,11 @@ RD_RegSlot_Thread, RD_RegSlot_CtrlEntity, RD_RegSlot_Window, RD_RegSlot_Panel, -RD_RegSlot_Tab, -RD_RegSlot_PrevTab, +RD_RegSlot_View, +RD_RegSlot_PrevView, RD_RegSlot_DstPanel, RD_RegSlot_Entity, RD_RegSlot_EntityList, -RD_RegSlot_EVKey, RD_RegSlot_UnwindCount, RD_RegSlot_InlineDepth, RD_RegSlot_FilePath, @@ -160,6 +159,7 @@ RD_CmdKind_Redo, RD_CmdKind_GoBack, RD_CmdKind_GoForward, RD_CmdKind_ClosePanel, +RD_CmdKind_FocusTab, RD_CmdKind_NextTab, RD_CmdKind_PrevTab, RD_CmdKind_MoveTabRight, @@ -548,12 +548,11 @@ CTRL_Handle thread; CTRL_Handle ctrl_entity; RD_Handle window; RD_Handle panel; -RD_Handle tab; -RD_Handle prev_tab; +RD_Handle view; +RD_Handle prev_view; RD_Handle dst_panel; RD_Handle entity; RD_HandleList entity_list; -EV_Key ev_key; U64 unwind_count; U64 inline_depth; String8 file_path; @@ -620,12 +619,11 @@ RD_ViewRuleUIFunctionType *ui; .ctrl_entity = rd_regs()->ctrl_entity,\ .window = rd_regs()->window,\ .panel = rd_regs()->panel,\ -.tab = rd_regs()->tab,\ -.prev_tab = rd_regs()->prev_tab,\ +.view = rd_regs()->view,\ +.prev_view = rd_regs()->prev_view,\ .dst_panel = rd_regs()->dst_panel,\ .entity = rd_regs()->entity,\ .entity_list = rd_regs()->entity_list,\ -.ev_key = rd_regs()->ev_key,\ .unwind_count = rd_regs()->unwind_count,\ .inline_depth = rd_regs()->inline_depth,\ .file_path = rd_regs()->file_path,\ @@ -767,7 +765,7 @@ extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[35]; +extern Rng1U64 rd_reg_slot_range_table[34]; extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 920e717a..7f6c02dc 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -158,12 +158,11 @@ RD_RegTable: {CTRL_Handle ctrl_entity CtrlEntity } {RD_Handle window Window } {RD_Handle panel Panel } - {RD_Handle tab Tab } - {RD_Handle prev_tab PrevTab } + {RD_Handle view View } + {RD_Handle prev_view PrevView } {RD_Handle dst_panel DstPanel } {RD_Handle entity Entity } {RD_HandleList entity_list EntityList } - {EV_Key ev_key EVKey } // rjf: frame selection {U64 unwind_count UnwindCount } @@ -290,6 +289,7 @@ RD_CmdTable: // | | | | {ClosePanel 1 1 Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" } //- rjf: panel tab + {FocusTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" } {NextTab 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" } {PrevTab 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" } {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c604c785..ae583352 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -684,7 +684,7 @@ rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child) internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child) { - if(parent == child->parent && parent != &rd_nil_cfg) + if(child != &rd_nil_cfg && parent == child->parent && parent != &rd_nil_cfg) { DLLRemove_NPZ(&rd_nil_cfg, parent->first, parent->last, child, next, prev); child->parent = &rd_nil_cfg; @@ -706,6 +706,17 @@ rd_cfg_child_from_string(RD_Cfg *parent, String8 string) return child; } +internal RD_Cfg * +rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string) +{ + RD_Cfg *child = rd_cfg_child_from_string(parent, string); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(parent, string); + } + return child; +} + internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string) { @@ -751,7 +762,9 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 string) for(MD_Node *src_n = tln; !md_node_is_nil(src_n); src_n = rec.next) { RD_Cfg *dst_n = rd_cfg_alloc(); - rd_cfg_equip_string(dst_n, src_n->string); + String8 src_n_string = src_n->string; + String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); + rd_cfg_equip_string(dst_n, src_n_string__raw); if(dst_active_parent_n != &rd_nil_cfg) { rd_cfg_insert_child(dst_active_parent_n, dst_active_parent_n->last, dst_n); @@ -2648,7 +2661,7 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) //~ rjf: View Functions internal RD_ViewState * -rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key) +rd_view_state_from_cfg(RD_Cfg *cfg) { RD_Handle cfg_handle = rd_handle_from_cfg(cfg); U64 hash = d_hash_from_string(str8_struct(&cfg_handle)); @@ -2657,7 +2670,7 @@ rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key) RD_ViewState *view_state = &rd_nil_view_state; for(RD_ViewState *v = slot->first; v != &rd_nil_view_state; v = v->hash_next) { - if(rd_handle_match(v->cfg_handle, cfg_handle) && ev_key_match(v->ev_key, ev_key)) + if(rd_handle_match(v->cfg_handle, cfg_handle)) { view_state = v; break; @@ -2677,7 +2690,6 @@ rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key) MemoryCopyStruct(view_state, &rd_nil_view_state); DLLPushBack_NPZ(&rd_nil_view_state, slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_handle = cfg_handle; - view_state->ev_key = ev_key; view_state->arena = arena_alloc(); } if(view_state != &rd_nil_view_state) @@ -2687,13 +2699,6 @@ rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key) return view_state; } -internal RD_ViewState * -rd_view_state_from_cfg(RD_Cfg *cfg) -{ - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(cfg, ev_key_zero()); - return view_state; -} - internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size) { @@ -2844,34 +2849,34 @@ rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query internal Arena * rd_view_arena(void) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); return view_state->arena; } internal UI_ScrollPt2 rd_view_scroll_pos(void) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); return view_state->scroll_pos; } internal String8 rd_view_expr_string(void) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); - String8 expr_string = str8(view_state->expression_buffer, view_state->expression_string_size); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *expr = rd_cfg_child_from_string(view, str8_lit("query")); + String8 expr_string = expr->first->string; return expr_string; } internal String8 rd_view_filter(void) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); - String8 filter_string = str8(view_state->filter_buffer, view_state->filter_string_size); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *filter = rd_cfg_child_from_string(view, str8_lit("filter")); + String8 filter_string = filter->first->string; return filter_string; } @@ -2880,8 +2885,8 @@ rd_view_filter(void) internal void * rd_view_state_by_size(U64 size) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); if(view_state->user_data == 0) { view_state->user_data = push_array(view_state->arena, U8, size); @@ -2892,8 +2897,8 @@ rd_view_state_by_size(U64 size) internal Arena * rd_push_view_arena(void) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); RD_ArenaExt *ext = push_array(view_state->arena, RD_ArenaExt, 1); ext->arena = arena_alloc(); SLLQueuePush(view_state->first_arena_ext, view_state->last_arena_ext, ext); @@ -2905,26 +2910,34 @@ rd_push_view_arena(void) internal void rd_store_view_expr_string(String8 string) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); - view_state->expression_string_size = Min(string.size, sizeof(view_state->expression_buffer)); - MemoryCopy(view_state->expression_buffer, string.str, view_state->expression_string_size); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + for(RD_Cfg *child = expr->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } + rd_cfg_new(expr, string); } internal void rd_store_view_filter(String8 string) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); - view_state->filter_string_size = Min(string.size, sizeof(view_state->filter_buffer)); - MemoryCopy(view_state->filter_buffer, string.str, view_state->filter_string_size); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); + for(RD_Cfg *child = filter->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } + rd_cfg_new(filter, string); } internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); view_state->loading_t_target = (F32)!!is_loading; view_state->loading_progress_v = progress_u64; view_state->loading_progress_v_target = progress_u64_target; @@ -2933,16 +2946,21 @@ rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_ta internal void rd_store_view_scroll_pos(UI_ScrollPt2 pos) { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->tab); - RD_ViewState *view_state = rd_view_state_from_cfg_ev_key(tab, rd_regs()->ev_key); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); view_state->scroll_pos = pos; } internal void rd_store_view_param(String8 key, String8 value) { - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_store_param(view, key, value); + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *child = rd_cfg_child_from_string(view, key); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(view, key); + } + rd_cfg_new(child, value); } internal void @@ -2987,7 +3005,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) //- rjf: scan for existing window RD_WindowState *ws = &rd_nil_window_state; - for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) + for(RD_WindowState *w = slot->first; w != &rd_nil_window_state; w = w->hash_next) { if(rd_handle_match(w->cfg_handle, handle)) { @@ -3049,7 +3067,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->hover_eval_arena = arena_alloc(); ws->autocomp_lister_params_arena = arena_alloc(); ws->query_cmd_arena = arena_alloc(); - ws->query_view_stack_top = &rd_nil_view; + ws->query_view_stack_top = &rd_nil_cfg; ws->last_dpi = os_dpi_from_window(ws->os); for EachEnumVal(RD_SettingCode, code) { @@ -3077,7 +3095,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) } // rjf: pre-emptively rasterize common glyphs - if(rd_state->first_window_state == 0) RD_RegsScope(.window = handle) + if(rd_state->first_window_state == &rd_nil_window_state) RD_RegsScope(.window = handle) { RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; RD_FontSlot icon_font_slot = RD_FontSlot_Icons; @@ -3121,8 +3139,8 @@ rd_window_state_from_cfg(RD_Cfg *cfg) } // rjf: hook up window links - DLLPushBack_NP(rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); - DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); + DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLPushBack_NPZ(&rd_nil_window_state, slot->first, slot->last, ws, hash_next, hash_prev); scratch_end(scratch); } @@ -3139,11 +3157,11 @@ rd_window_state_from_cfg(RD_Cfg *cfg) internal RD_WindowState * rd_window_state_from_os_handle(OS_Handle os) { - RD_WindowState *ws = 0; + RD_WindowState *ws = &rd_nil_window_state; for EachIndex(slot_idx, rd_state->window_state_slots_count) { for(RD_WindowState *w = rd_state->window_state_slots[slot_idx].first; - w != 0; + w != &rd_nil_window_state; w = w->order_next) { if(os_handle_match(w->os, os)) @@ -3174,7 +3192,7 @@ rd_window_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc; B32 popup_open = rd_state->popup_active; - B32 query_is_open = !rd_view_is_nil(ws->query_view_stack_top); + B32 query_is_open = (ws->query_view_stack_top != &rd_nil_cfg); B32 hover_eval_is_open = (!popup_open && ws->hover_eval_string.size != 0 && ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && @@ -3533,10 +3551,11 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); { //- rjf: tab dragging - if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view)) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg) { UI_Size main_width = ui_top_pref_width(); UI_Size main_height = ui_top_pref_height(); @@ -3556,7 +3575,7 @@ rd_window_frame(void) UI_Row { RD_IconKind icon_kind = view_rule_info->icon_kind; - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, query->first->string, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); RD_Font(RD_FontSlot_Icons) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) UI_PrefWidth(ui_em(2.5f, 1.f)) @@ -3575,7 +3594,8 @@ rd_window_frame(void) UI_Parent(view_preview_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill { RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], view_preview_container->rect); + String8 expr = rd_view_expr_string(); + view_ui(expr, view_preview_container->rect); } } } @@ -3867,121 +3887,127 @@ rd_window_frame(void) // case RD_RegSlot_View: { - RD_Panel *panel = rd_panel_from_handle(regs->panel); - RD_View *view = rd_view_from_handle(regs->view); - RD_IconKind view_icon = rd_icon_kind_from_view(view); - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - - // rjf: title - UI_Row + RD_Cfg *tab = rd_cfg_from_handle(regs->view); + RD_RegsScope(.view = regs->view) { - ui_spacer(ui_em(1.f, 1.f)); - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(2.f, 1.f)) - UI_PrefHeight(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[view_icon]); - UI_PrefWidth(ui_text_dim(10, 1)) + String8 expr = rd_view_expr_string(); + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(tab->string); + RD_IconKind view_icon = view_rule_info->icon_kind; + DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr); + + // rjf: title + UI_Row { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); - } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - // rjf: copy name - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) - { - os_set_clipboard_text(dr_string_from_fancy_string_list(scratch.arena, &fstrs)); - ui_ctx_menu_close(); - } - - // rjf: copy full path - if(file_path.size != 0) - { - UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"); - String8 full_path = path_normalized_from_string(scratch.arena, file_path); - if(ui_clicked(copy_full_path_sig)) - { - os_set_clipboard_text(full_path); - ui_ctx_menu_close(); - } - if(ui_hovering(copy_full_path_sig)) UI_Tooltip - { - ui_label(full_path); - } - } - - // rjf: show in explorer - if(file_path.size != 0) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer"); - if(ui_clicked(sig)) - { - String8 full_path = path_normalized_from_string(scratch.arena, file_path); - os_show_in_filesystem_ui(full_path); - ui_ctx_menu_close(); - } - } - - // rjf: filter controls - if(view->spec->flags & RD_ViewRuleInfoFlag_CanFilter) - { - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].string))) - { - rd_cmd(RD_CmdKind_Filter, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].string))) - { - rd_cmd(RD_CmdKind_ClearFilter, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - } - - // rjf: close tab - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab"))) - { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - ui_ctx_menu_close(); - } - - // rjf: param tree editing - UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code) - { - Temp scratch = scratch_begin(0, 0); - String8 schema_string = view->spec->params_schema; - MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string); - MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens); - MD_Node *schema_root = schema_parse.root->first; - if(!md_node_is_nil(schema_root)) - { - if(!md_node_is_nil(schema_root->first)) + ui_spacer(ui_em(1.f, 1.f)); + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) + UI_PrefWidth(ui_em(2.f, 1.f)) + UI_PrefHeight(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + ui_label(rd_icon_kind_text_table[view_icon]); + UI_PrefWidth(ui_text_dim(10, 1)) { - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(name_box, &fstrs); } - for MD_EachNode(key, schema_root->first) + } + + RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + + // rjf: copy name + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) + { + os_set_clipboard_text(dr_string_from_fancy_string_list(scratch.arena, &fstrs)); + ui_ctx_menu_close(); + } + + // rjf: copy full path + if(file_path.size != 0) + { + UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"); + String8 full_path = path_normalized_from_string(scratch.arena, file_path); + if(ui_clicked(copy_full_path_sig)) { - UI_Row + os_set_clipboard_text(full_path); + ui_ctx_menu_close(); + } + if(ui_hovering(copy_full_path_sig)) UI_Tooltip + { + ui_label(full_path); + } + } + + // rjf: show in explorer + if(file_path.size != 0) + { + UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer"); + if(ui_clicked(sig)) + { + String8 full_path = path_normalized_from_string(scratch.arena, file_path); + os_show_in_filesystem_ui(full_path); + ui_ctx_menu_close(); + } + } + + // rjf: filter controls + if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter) + { + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].string))) + { + rd_cmd(RD_CmdKind_Filter); + ui_ctx_menu_close(); + } + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].string))) + { + rd_cmd(RD_CmdKind_ClearFilter); + ui_ctx_menu_close(); + } + } + + // rjf: close tab + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab"))) + { + rd_cmd(RD_CmdKind_CloseTab); + ui_ctx_menu_close(); + } + + // rjf: param tree editing +#if 0 + UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code) + { + Temp scratch = scratch_begin(0, 0); + String8 schema_string = view->spec->params_schema; + MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string); + MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens); + MD_Node *schema_root = schema_parse.root->first; + if(!md_node_is_nil(schema_root)) + { + if(!md_node_is_nil(schema_root->first)) { - MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)]; - MD_Node *param_tree = md_child_from_string(params, key->string, 0); - String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); - UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); - if(ui_committed(sig)) + RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + } + for MD_EachNode(key, schema_root->first) + { + UI_Row { - String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); - rd_view_store_param(view, key->string, new_string); + MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)]; + MD_Node *param_tree = md_child_from_string(params, key->string, 0); + String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); + UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); + UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); + if(ui_committed(sig)) + { + String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); + rd_view_store_param(view, key->string, new_string); + } } } } + scratch_end(scratch); } - scratch_end(scratch); +#endif } }break; @@ -5951,19 +5977,13 @@ rd_window_frame(void) } } RD_ViewRuleInfo *view_spec = rd_view_rule_info_from_string(query_view_name); - if(ws->query_view_stack_top->spec != view_spec || - rd_view_is_nil(ws->query_view_stack_top)) + if(!str8_match(ws->query_view_stack_top->string, view_spec->string, 0) || + ws->query_view_stack_top == &rd_nil_cfg) { Temp scratch = scratch_begin(0, 0); // rjf: clear existing query stack - for(RD_View *query_view = ws->query_view_stack_top, *next = 0; - !rd_view_is_nil(query_view); - query_view = next) - { - next = query_view->order_next; - rd_view_release(query_view); - } + rd_cfg_release(ws->query_view_stack_top); // rjf: determine default query String8 default_query = {0}; @@ -5982,83 +6002,52 @@ rd_window_frame(void) } // rjf: construct & push new view - RD_View *view = rd_view_alloc(); - rd_view_equip_spec(view, view_spec, default_query, &md_nil_node); + RD_Cfg *bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *view = rd_cfg_new(bucket, view_spec->string); + RD_Cfg *filter = rd_cfg_new(view, str8_lit("filter")); + rd_cfg_new(filter, default_query); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + view_state->filter_cursor = txt_pt(1, default_query.size+1); if(cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) { - view->query_mark = txt_pt(1, 1); + view_state->filter_mark = txt_pt(1, 1); } ws->query_view_stack_top = view; ws->query_view_selected = 1; - view->order_next = &rd_nil_view; scratch_end(scratch); } } - //////////////////////////// - //- rjf: animate query info - // - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - - // rjf: animate query view selection transition - { - F32 target = (F32)!!ws->query_view_selected; - F32 diff = abs_f32(target - ws->query_view_selected_t); - if(diff > 0.005f) - { - rd_request_frame(); - if(diff < 0.005f) - { - ws->query_view_selected_t = target; - } - ws->query_view_selected_t += (target - ws->query_view_selected_t) * rate; - } - } - - // rjf: animate query view open/close transition - { - F32 query_view_t_target = !rd_view_is_nil(ws->query_view_stack_top); - F32 diff = abs_f32(query_view_t_target - ws->query_view_t); - if(diff > 0.005f) - { - rd_request_frame(); - } - if(diff < 0.005f) - { - ws->query_view_t = query_view_t_target; - } - ws->query_view_t += (query_view_t_target - ws->query_view_t) * rate; - } - } - //////////////////////////// //- rjf: build query // - if(!rd_view_is_nil(ws->query_view_stack_top)) + if(ws->query_view_stack_top != &rd_nil_cfg) UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_view_selected) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Palette(RD_PaletteCode_Floating) { - RD_View *view = ws->query_view_stack_top; + RD_Cfg *view = ws->query_view_stack_top; + RD_ViewState *view_state = rd_view_state_from_cfg(view); + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); String8 query_cmd_name = ws->query_cmd_name; RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); RD_Query *query = &query_cmd_info->query; + F32 query_view_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###%p_query_view_t", ws), 1.f); //- rjf: calculate rectangles Vec2F32 window_center = center_2f32(window_rect); F32 query_container_width = dim_2f32(window_rect).x*0.5f; F32 query_container_margin = ui_top_font_size()*8.f; F32 query_line_edit_height = ui_top_font_size()*3.f; - Rng2F32 query_container_rect = r2f32p(window_center.x - query_container_width/2 + (1-ws->query_view_t)*query_container_width/4, + Rng2F32 query_container_rect = r2f32p(window_center.x - query_container_width/2 + (1-query_view_t)*query_container_width/4, window_rect.y0 + query_container_margin, - window_center.x + query_container_width/2 - (1-ws->query_view_t)*query_container_width/4, + window_center.x + query_container_width/2 - (1-query_view_t)*query_container_width/4, window_rect.y1 - query_container_margin); - if(ws->query_view_stack_top->spec == &rd_nil_view_rule_info) + if(view_rule_info == &rd_nil_view_rule_info) { query_container_rect.y1 = query_container_rect.y0 + query_line_edit_height; } - query_container_rect.y1 = mix_1f32(query_container_rect.y0, query_container_rect.y1, ws->query_view_t); + query_container_rect.y1 = mix_1f32(query_container_rect.y0, query_container_rect.y1, query_view_t); Rng2F32 query_container_content_rect = r2f32p(query_container_rect.x0, query_container_rect.y0+query_line_edit_height, query_container_rect.x1, @@ -6069,8 +6058,8 @@ rd_window_frame(void) UI_Rect(query_container_rect) UI_CornerRadius(ui_top_font_size()*0.2f) UI_ChildLayoutAxis(Axis2_Y) - UI_Squish(0.25f-ws->query_view_t*0.25f) - UI_Transparency(1-ws->query_view_t) + UI_Squish(0.25f - query_view_t*0.25f) + UI_Transparency(1-query_view_t) { query_container_box = ui_build_box_from_stringf(UI_BoxFlag_Floating| UI_BoxFlag_AllowOverflow| @@ -6110,13 +6099,13 @@ rd_window_frame(void) (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), 0, 0, - &view->query_cursor, - &view->query_mark, - view->query_buffer, - sizeof(view->query_buffer), - &view->query_string_size, + &view_state->filter_cursor, + &view_state->filter_mark, + view_state->filter_buffer, + sizeof(view_state->filter_buffer), + &view_state->filter_string_size, 0, - str8(view->query_buffer, view->query_string_size), + str8(view_state->filter_buffer, view_state->filter_string_size), str8_lit("###query_text_input")); if(ui_pressed(sig)) { @@ -6142,10 +6131,11 @@ rd_window_frame(void) //- rjf: build query view UI_Parent(query_container_box) UI_WidthFill UI_Focus(UI_FocusKind_Null) - RD_RegsScope(.view = rd_handle_from_view(view)) + RD_RegsScope(.view = rd_handle_from_cfg(view)) { - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], query_container_content_rect); + RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; + String8 filter = str8(view_state->filter_buffer, view_state->filter_string_size); + view_ui(filter, query_container_content_rect); } //- rjf: query submission @@ -6157,10 +6147,9 @@ rd_window_frame(void) if((ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) || query_completed) { Temp scratch = scratch_begin(0, 0); - RD_View *view = ws->query_view_stack_top; RD_RegsScope() { - rd_regs_fill_slot_from_string(query->slot, str8(view->query_buffer, view->query_string_size)); + rd_regs_fill_slot_from_string(query->slot, str8(view_state->filter_buffer, view_state->filter_string_size)); rd_cmd(RD_CmdKind_CompleteQuery); } scratch_end(scratch); @@ -6176,7 +6165,8 @@ rd_window_frame(void) } //- rjf: build darkening overlay for rest of screen - UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-ws->query_view_selected_t))) + F32 query_view_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_view_selected", ws), (F32)!!ws->query_view_selected); + UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_view_selected_t))) UI_Rect(window_rect) { ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); @@ -6561,8 +6551,8 @@ rd_window_frame(void) //- rjf: boundary tab-drag/drop sites // { - RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(drag_view)) + RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && drag_view != &rd_nil_cfg) { //- rjf: params F32 drop_site_major_dim_px = ceil_f32(ui_top_font_size()*7.f); @@ -6817,7 +6807,7 @@ rd_window_frame(void) //////////////////////////// //- rjf: animate panels // -#if 0 +#if 0 // TODO(rjf): @cfg { F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-50.f * rd_state->frame_dt)) : 1.f; Vec2F32 content_rect_dim = dim_2f32(content_rect); @@ -6867,7 +6857,12 @@ rd_window_frame(void) !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused && panel_tree.focused == panel); + RD_Cfg *selected_tab = panel->selected_tab; + RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); + F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + RD_RegsScope(.panel = rd_handle_from_cfg(panel->cfg), + .view = rd_handle_from_cfg(selected_tab)) { ////////////////////////// //- rjf: calculate UI rectangles @@ -6900,24 +6895,21 @@ rd_window_frame(void) content_rect.y0 = panel_rect.y0; content_rect.y1 = panel_rect.y1 - tab_bar_vheight; } + if(selected_tab_is_filtering_t > 0.01f) { - RD_View *tab = rd_selected_tab_from_panel(panel); - if(tab->is_filtering_t > 0.01f) - { - filter_rect.x0 = content_rect.x0; - filter_rect.y0 = content_rect.y0; - filter_rect.x1 = content_rect.x1; - content_rect.y0 += filter_bar_height*tab->is_filtering_t; - filter_rect.y1 = content_rect.y0; - } + filter_rect.x0 = content_rect.x0; + filter_rect.y0 = content_rect.y0; + filter_rect.x1 = content_rect.x1; + content_rect.y0 += filter_bar_height*selected_tab_is_filtering_t; + filter_rect.y1 = content_rect.y0; } ////////////////////////// //- rjf: build combined split+movetab drag/drop sites // { - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view) && contains_2f32(panel_rect, ui_mouse())) + RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse())) { F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); @@ -7050,7 +7042,7 @@ rd_window_frame(void) .dst_panel = rd_handle_from_cfg(panel->cfg), .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, - .prev_view = rd_handle_from_view(panel->last_tab_view)); + .prev_view = rd_handle_from_cfg(rd_cfg_list_last(&panel->tabs))); } } } @@ -7095,14 +7087,16 @@ rd_window_frame(void) //- rjf: build filtering box // { - RD_View *view = rd_selected_tab_from_panel(panel); - UI_Focus(UI_FocusKind_On) + RD_Cfg *view = selected_tab; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = rd_handle_from_cfg(view)) { - if(view->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + if(view_state->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { - rd_cmd(RD_CmdKind_ApplyFilter, .view = rd_handle_from_view(view)); + rd_cmd(RD_CmdKind_ApplyFilter); } - if(view->is_filtering || view->is_filtering_t > 0.01f) + if(view_state->is_filtering || selected_tab_is_filtering_t > 0.01f) { UI_Box *filter_box = &ui_nil_box; UI_Rect(filter_rect) @@ -7122,24 +7116,24 @@ rd_window_frame(void) ui_label(str8_lit("Filter")); } ui_spacer(ui_em(0.5f, 1.f)); - RD_Font(view->spec->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_Focus(view->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) + UI_Focus(view_state->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) UI_TextPadding(ui_top_font_size()*0.5f) { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view->spec->flags & RD_ViewRuleInfoFlag_FilterIsCode), + UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode), 0, 0, - &view->query_cursor, - &view->query_mark, - view->query_buffer, - sizeof(view->query_buffer), - &view->query_string_size, + &view_state->filter_cursor, + &view_state->filter_mark, + view_state->filter_buffer, + sizeof(view_state->filter_buffer), + &view_state->filter_string_size, 0, - str8(view->query_buffer, view->query_string_size), + str8(view_state->filter_buffer, view_state->filter_string_size), str8_lit("###filter_text_input")); if(ui_pressed(sig)) { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); + rd_cmd(RD_CmdKind_FocusPanel); } } } @@ -7150,7 +7144,7 @@ rd_window_frame(void) ////////////////////////// //- rjf: panel not selected? -> darken // - if(panel != ws->focused_panel) + if(panel != panel_tree.focused) { UI_Palette(ui_build_palette(0, .background = rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay))) UI_Rect(content_rect) @@ -7165,12 +7159,12 @@ rd_window_frame(void) UI_Box *panel_box = &ui_nil_box; UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) { - UI_Key panel_key = rd_ui_key_from_panel(panel); + UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_box_%p", panel->cfg); panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| UI_BoxFlag_Clip| UI_BoxFlag_DrawBorder| UI_BoxFlag_DisableFocusOverlay| - ((ws->focused_panel != panel)*UI_BoxFlag_DisableFocusBorder), + ((panel_tree.focused != panel)*UI_BoxFlag_DisableFocusBorder), panel_key); } @@ -7193,10 +7187,8 @@ rd_window_frame(void) //- rjf: push interaction registers, fill with per-view states rd_push_regs(); { - RD_View *view = rd_selected_tab_from_panel(panel); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(view->query_buffer, view->query_string_size)); - rd_regs()->panel = rd_handle_from_panel(panel); - rd_regs()->view = rd_handle_from_view(view); + String8 view_expr = rd_view_expr_string(); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); if(view_file_path.size != 0) { rd_regs()->file_path = view_file_path; @@ -7213,22 +7205,23 @@ rd_window_frame(void) } //- rjf: build empty view - UI_Parent(view_container_box) if(rd_view_is_nil(rd_selected_tab_from_panel(panel))) + UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) { - RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), &md_nil_node, content_rect); + RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), content_rect); } //- rjf: build tab view - UI_Parent(view_container_box) if(!rd_view_is_nil(rd_selected_tab_from_panel(panel))) + UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) { - RD_View *view = rd_selected_tab_from_panel(panel); - RD_ViewRuleUIFunctionType *view_ui = view->spec->ui; - view_ui(str8(view->query_buffer, view->query_string_size), view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)], content_rect); + String8 view_expr = rd_view_expr_string(); + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(selected_tab->string); + RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; + view_ui(view_expr, content_rect); } //- rjf: pop interaction registers; commit if this is the selected view RD_Regs *view_regs = rd_pop_regs(); - if(ws->focused_panel == panel) + if(panel_tree.focused == panel) { MemoryCopyStruct(rd_regs(), view_regs); } @@ -7238,10 +7231,10 @@ rd_window_frame(void) //- rjf: loading? -> fill loading overlay container // { - RD_View *view = rd_selected_tab_from_panel(panel); - if(view->loading_t > 0.01f) UI_Parent(loading_overlay_container) + F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target); + if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) { - rd_loading_overlay(panel_rect, view->loading_t, view->loading_progress_v, view->loading_progress_v_target); + rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); } } @@ -7250,8 +7243,10 @@ rd_window_frame(void) // UI_Focus(UI_FocusKind_On) { - RD_View *view = rd_selected_tab_from_panel(panel); - if(ui_is_focus_active() && view->spec->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view->is_filtering) + RD_Cfg *view = selected_tab; + RD_ViewState *view_state = selected_tab_view_state; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); + if(ui_is_focus_active() && view_rule_info->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view_state->is_filtering) { for(UI_Event *evt = 0; ui_next_event(&evt);) { @@ -7269,9 +7264,9 @@ rd_window_frame(void) } } } - if(view->spec->flags & RD_ViewRuleInfoFlag_CanFilter && (view->query_string_size != 0 || view->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter && (view_state->filter_string_size != 0 || view_state->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { - rd_cmd(RD_CmdKind_ClearFilter, .view = rd_handle_from_view(view)); + rd_cmd(RD_CmdKind_ClearFilter); } } @@ -7281,7 +7276,7 @@ rd_window_frame(void) UI_Signal panel_sig = ui_signal_from_box(panel_box); if(ui_pressed(panel_sig)) { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); + rd_cmd(RD_CmdKind_FocusPanel); } ////////////////////////// @@ -7296,13 +7291,13 @@ rd_window_frame(void) struct DropSite { F32 p; - RD_View *prev_view; + RD_Cfg *prev_view; }; // rjf: prep output data - RD_View *next_selected_tab_view = rd_selected_tab_from_panel(panel); + RD_Cfg *next_selected_tab = selected_tab; UI_Box *tab_bar_box = &ui_nil_box; - U64 drop_site_count = panel->tab_view_count+1; + U64 drop_site_count = panel->tabs.count+1; DropSite *drop_sites = push_array(scratch.arena, DropSite, drop_site_count); F32 drop_site_max_p = 0; U64 view_idx = 0; @@ -7327,20 +7322,26 @@ rd_window_frame(void) ui_spacer(ui_px(1.f, 1.f)); // rjf: build tabs + RD_Cfg *tab = &rd_nil_cfg; + RD_Cfg *prev_tab = &rd_nil_cfg; UI_PrefWidth(ui_em(18.f, 0.5f)) UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) - for(RD_View *view = panel->first_tab_view;; view = view->order_next, view_idx += 1) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next, view_idx += 1) { + prev_tab = tab; + tab = tab_n->v; + RD_ViewRuleInfo *tab_view_rule_info = rd_view_rule_info_from_string(tab->string); temp_end(scratch); - if(rd_view_is_project_filtered(view)) { continue; } + if(rd_cfg_is_project_filtered(tab)) { continue; } // rjf: if before this tab is the prev-view of the current tab drag, // draw empty space if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && catchall_drop_site_hovered) { +#if 0 // TODO(rjf): @cfg RD_Panel *dst_panel = rd_panel_from_handle(rd_last_drag_drop_panel); RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); RD_View *dst_prev_view = rd_view_from_handle(rd_last_drag_drop_prev_tab); @@ -7359,25 +7360,124 @@ rd_window_frame(void) } } } +#endif } // rjf: end on nil view - if(rd_view_is_nil(view)) + if(tab == &rd_nil_cfg) { break; } - // rjf: gather info for this tab - B32 view_is_selected = (view == rd_selected_tab_from_panel(panel)); - RD_IconKind icon_kind = rd_icon_kind_from_view(view); - DR_FancyStringList title_fstrs = rd_title_fstrs_from_view(scratch.arena, view, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + // rjf: build per-tab info + RD_RegsScope(.panel = rd_handle_from_cfg(panel->cfg), .view = rd_handle_from_cfg(tab)) + { + // rjf: gather info for this tab + B32 view_is_selected = (tab == panel->selected_tab); + RD_IconKind icon_kind = tab_view_rule_info->icon_kind; + String8 view_expr = rd_view_expr_string(); + DR_FancyStringList title_fstrs = rd_title_fstrs_from_view(scratch.arena, tab_view_rule_info->display_name, view_expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + + // rjf: begin vertical region for this tab + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: build tab container box + UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) RD_Palette(view_is_selected ? RD_PaletteCode_Tab : RD_PaletteCode_TabInactive) + { + if(panel->tab_side == Side_Max) + { + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + (UI_BoxFlag_DrawDropShadow*view_is_selected)| + UI_BoxFlag_Clickable, + "tab_%p", tab); + + // rjf: build tab contents + UI_Parent(tab_box) + { + UI_WidthFill UI_Row + { + ui_spacer(ui_em(0.5f, 1.f)); + if(icon_kind != RD_IconKind_Null) + { + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(1.75f, 1.f)) + ui_label(rd_icon_kind_text_table[icon_kind]); + } + UI_PrefWidth(ui_text_dim(10, 0)) + { + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(name_box, &title_fstrs); + } + } + UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) + UI_Flags(UI_BoxFlag_DrawTextWeak) + UI_CornerRadius00(0) + UI_CornerRadius01(0) + { + UI_Palette *palette = ui_build_palette(ui_top_palette()); + palette->background = v4f32(0, 0, 0, 0); + ui_set_next_palette(palette); + UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + if(ui_clicked(sig) || ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); + } + } + } + + // rjf: consume events for tab clicking + { + UI_Signal sig = ui_signal_from_box(tab_box); + if(ui_pressed(sig)) + { + next_selected_tab = tab; + rd_cmd(RD_CmdKind_FocusPanel); + } + else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) + { + rd_drag_begin(RD_RegSlot_View); + } + else if(ui_right_clicked(sig)) + { + rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); + } + else if(ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); + } + } + } + + // rjf: space for next tab + { + ui_spacer(ui_em(0.3f, 1.f)); + } + + // rjf: store off drop-site + drop_sites[view_idx].p = tab_column_box->rect.x0 - tab_spacing/2; + drop_sites[view_idx].prev_view = prev_tab; + drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p); + } - // rjf: begin vertical region for this tab - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", view); - - // rjf: build tab container box - UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) RD_Palette(view_is_selected ? RD_PaletteCode_Tab : RD_PaletteCode_TabInactive) + // rjf: build add-new-tab button + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) + UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + UI_Column { if(panel->tab_side == Side_Max) { @@ -7387,210 +7487,109 @@ rd_window_frame(void) { ui_spacer(ui_px(1.f, 1.f)); } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - (UI_BoxFlag_DrawDropShadow*view_is_selected)| - UI_BoxFlag_Clickable, - "tab_%p", view); - - // rjf: build tab contents - UI_Parent(tab_box) + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Palette(RD_PaletteCode_ImplicitButton) { - UI_WidthFill UI_Row + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel); + UI_Signal sig = ui_signal_from_box(add_new_box); + if(ui_clicked(sig)) { - ui_spacer(ui_em(0.5f, 1.f)); - if(icon_kind != RD_IconKind_Null) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(1.75f, 1.f)) - ui_label(rd_icon_kind_text_table[icon_kind]); - } - UI_PrefWidth(ui_text_dim(10, 0)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &title_fstrs); - } + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); } - UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_Flags(UI_BoxFlag_DrawTextWeak) - UI_CornerRadius00(0) - UI_CornerRadius01(0) + } + } + + scratch_end(scratch); + } + + // rjf: interact with tab bar + ui_signal_from_box(tab_bar_box); + + // rjf: fill out last drop site + { + drop_sites[drop_site_count-1].p = drop_site_max_p; + drop_sites[drop_site_count-1].prev_view = rd_cfg_list_last(&panel->tabs); + } + + // rjf: more precise drop-sites on tab bar + { + Vec2F32 mouse = ui_mouse(); + RD_Cfg *drag_tab = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg) + { + // rjf: mouse => hovered drop site + F32 min_distance = 0; + DropSite *active_drop_site = 0; + if(catchall_drop_site_hovered) + { + for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) { - UI_Palette *palette = ui_build_palette(ui_top_palette()); - palette->background = v4f32(0, 0, 0, 0); - ui_set_next_palette(palette); - UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], view); - if(ui_clicked(sig) || ui_middle_clicked(sig)) + F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); + if(drop_site_idx == 0 || distance < min_distance) { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); + active_drop_site = &drop_sites[drop_site_idx]; + min_distance = distance; } } } - // rjf: consume events for tab clicking + // rjf: store closest prev-view + if(active_drop_site != 0) { - UI_Signal sig = ui_signal_from_box(tab_box); - if(ui_pressed(sig)) - { - next_selected_tab_view = view; - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - } - else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) - { - RD_RegsScope(.panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)) - { - rd_drag_begin(RD_RegSlot_View); - } - } - else if(ui_right_clicked(sig)) - { - RD_RegsScope(.panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)) - { - rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); - } - } - else if(ui_middle_clicked(sig)) - { - rd_cmd(RD_CmdKind_CloseTab, .panel = rd_handle_from_panel(panel), .view = rd_handle_from_view(view)); - } + rd_last_drag_drop_prev_tab = rd_handle_from_cfg(active_drop_site->prev_view); } - } - - // rjf: space for next tab - { - ui_spacer(ui_em(0.3f, 1.f)); - } - - // rjf: store off drop-site - drop_sites[view_idx].p = tab_column_box->rect.x0 - tab_spacing/2; - drop_sites[view_idx].prev_view = view->order_prev; - drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p); - } - - // rjf: build add-new-tab button - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) - UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column - { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HoverCursor(OS_Cursor_HandPoint) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) + else { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(panel)); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + rd_last_drag_drop_prev_tab = rd_handle_zero(); } - } - } - - scratch_end(scratch); - } - - // rjf: interact with tab bar - ui_signal_from_box(tab_bar_box); - - // rjf: fill out last drop site - { - drop_sites[drop_site_count-1].p = drop_site_max_p; - drop_sites[drop_site_count-1].prev_view = panel->last_tab_view; - } - - // rjf: more precise drop-sites on tab bar - { - Vec2F32 mouse = ui_mouse(); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && !rd_view_is_nil(view)) - { - // rjf: mouse => hovered drop site - F32 min_distance = 0; - DropSite *active_drop_site = 0; - if(catchall_drop_site_hovered) - { - for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) + + // rjf: vis + if(drag_tab != &rd_nil_cfg && active_drop_site != 0) { - F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); - if(drop_site_idx == 0 || distance < min_distance) + RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + + // rjf: drop + if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) + { + RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *src_panel = rd_cfg_from_handle(rd_state->drag_drop_regs->panel); + RD_Cfg *dst_panel = panel->cfg; + if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg) { - active_drop_site = &drop_sites[drop_site_idx]; - min_distance = distance; + rd_cmd(RD_CmdKind_MoveTab, + .panel = rd_handle_from_cfg(src_panel), + .dst_panel = rd_handle_from_cfg(dst_panel), + .view = rd_handle_from_cfg(drag_view), + .prev_view = rd_handle_from_cfg(active_drop_site->prev_view)); } } } - - // rjf: store closest prev-view - if(active_drop_site != 0) - { - rd_last_drag_drop_prev_tab = rd_handle_from_view(active_drop_site->prev_view); - } - else - { - rd_last_drag_drop_prev_tab = rd_handle_zero(); - } - - // rjf: vis - RD_Panel *drag_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - if(!rd_view_is_nil(view) && active_drop_site != 0) - { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) - { - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - RD_Panel *src_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - if(!rd_panel_is_nil(panel) && !rd_view_is_nil(view)) - { - rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_panel(src_panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view), - .prev_view = rd_handle_from_view(active_drop_site->prev_view)); - } - } } } // rjf: apply tab change { - panel->selected_tab_view = rd_handle_from_view(next_selected_tab_view); + rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); } scratch_end(scratch); @@ -7601,6 +7600,7 @@ rd_window_frame(void) // if(catchall_drop_site_hovered) { +#if 0 // TODO(rjf): @cfg rd_last_drag_drop_panel = rd_handle_from_panel(panel); RD_View *dragged_view = rd_view_from_handle(rd_state->drag_drop_regs->view); @@ -7640,6 +7640,7 @@ rd_window_frame(void) } } } +#endif } ////////////////////////// @@ -7683,6 +7684,7 @@ rd_window_frame(void) //- rjf: animate views // { +#if 0 // TODO(rjf): @cfg Temp scratch = scratch_begin(0, 0); typedef struct Task Task; struct Task @@ -7758,6 +7760,7 @@ rd_window_frame(void) } } scratch_end(scratch); +#endif } //////////////////////////// @@ -7779,11 +7782,11 @@ rd_window_frame(void) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncUIFontScale, .window = rd_handle_from_window(ws)); + rd_cmd(RD_CmdKind_IncUIFontScale); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecUIFontScale, .window = rd_handle_from_window(ws)); + rd_cmd(RD_CmdKind_DecUIFontScale); } } } @@ -10196,10 +10199,11 @@ rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingP internal String8List rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) { + String8List strs = {0}; +#if 0 // TODO(rjf): @cfg ProfBeginFunction(); local_persist char *spaces = " "; local_persist char *slashes= "////////////////////////////////////////////////////////////////////////////////"; - String8List strs = {0}; //- rjf: write all entities { @@ -10726,6 +10730,7 @@ rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) } ProfEnd(); +#endif return strs; } @@ -11608,9 +11613,12 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_os_handle(event->window); if(ws != 0 && ws != rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window))) { + Temp scratch = scratch_begin(0, 0); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(ws->cfg_handle)); rd_regs()->window = ws->cfg_handle; - rd_regs()->panel = rd_handle_from_panel(ws->focused_panel); - rd_regs()->view = ws->focused_panel->selected_tab_view; + rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); + rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); + scratch_end(scratch); } B32 take = 0; @@ -13182,6 +13190,7 @@ rd_frame(void) case RD_CmdKind_WriteUserData: case RD_CmdKind_WriteProjectData: { +#if 0 // TODO(rjf): @cfg RD_CfgSrc src = RD_CfgSrc_User; for(RD_CfgSrc s = (RD_CfgSrc)0; s < RD_CfgSrc_COUNT; s = (RD_CfgSrc)(s+1)) { @@ -13200,6 +13209,7 @@ rd_frame(void) String8 data = str8_list_join(scratch.arena, &strs, 0); String8 data_indented = indented_from_string(scratch.arena, data); os_write_data_to_file_path(path, data_indented); +#endif }break; //- rjf: code navigation @@ -13302,7 +13312,8 @@ rd_frame(void) Axis2 split_axis = axis2_from_dir2(split_dir); Side split_side = side_from_dir2(split_dir); RD_Cfg *new_panel_cfg = &rd_nil_cfg; - RD_PanelNode *panel_root = rd_panel_tree_from_cfg(scratch.arena, split_panel); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, split_panel); + RD_PanelNode *panel_root = panel_tree.root; RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_root, split_panel); RD_PanelNode *parent = panel->parent; @@ -13380,8 +13391,8 @@ rd_frame(void) { rd_cfg_unhook(dragdrop_origin_panel_cfg, dragdrop_tab); rd_cfg_insert_child(new_panel_cfg, new_panel_cfg->last, dragdrop_tab); - RD_PanelNode *origin_panel_tree = rd_panel_tree_from_cfg(scratch.arena, dragdrop_origin_panel_cfg); - RD_PanelNode *origin_panel = rd_panel_node_from_tree_cfg(origin_panel_tree, dragdrop_origin_panel_cfg); + RD_PanelTree origin_panel_tree = rd_panel_tree_from_cfg(scratch.arena, dragdrop_origin_panel_cfg); + RD_PanelNode *origin_panel = rd_panel_node_from_tree_cfg(origin_panel_tree.root, dragdrop_origin_panel_cfg); if(origin_panel->tabs.count == 0) { rd_cmd(RD_CmdKind_ClosePanel); @@ -13399,8 +13410,8 @@ rd_frame(void) case RD_CmdKind_RotatePanelColumns: { RD_Cfg *panel_cfg = rd_cfg_from_handle(rd_regs()->panel); - RD_PanelNode *panel_root = rd_panel_tree_from_cfg(scratch.arena, panel_cfg); - RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_root, panel_cfg); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel_cfg); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, panel_cfg); RD_PanelNode *parent = &rd_nil_panel_node; for(RD_PanelNode *p = panel->parent; p != &rd_nil_panel_node; p = p->parent) { @@ -13481,6 +13492,7 @@ rd_frame(void) case RD_CmdKind_FocusPanelDown: panel_change_dir = v2s32(+0, +1); goto focus_panel_dir; focus_panel_dir:; { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *src_panel = ws->focused_panel; Rng2F32 src_panel_rect = rd_target_rect_from_panel(r2f32(v2f32(0, 0), v2f32(1000, 1000)), ws->root_panel, src_panel); @@ -13515,6 +13527,7 @@ rd_frame(void) } rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(dst_panel)); } +#endif }break; //- rjf: undo/redo @@ -13616,6 +13629,7 @@ rd_frame(void) //- rjf: panel removal case RD_CmdKind_ClosePanel: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_Panel *parent = panel->parent; @@ -13708,11 +13722,17 @@ rd_frame(void) } } } +#endif }break; //- rjf: panel tab controls + case RD_CmdKind_FocusTab: + { + // TODO(rjf): @cfg + }break; case RD_CmdKind_NextTab: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *start_view = rd_selected_tab_from_panel(panel); RD_View *next_view = start_view; @@ -13730,9 +13750,11 @@ rd_frame(void) } } panel->selected_tab_view = rd_handle_from_view(next_view); +#endif }break; case RD_CmdKind_PrevTab: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *start_view = rd_selected_tab_from_panel(panel); RD_View *next_view = start_view; @@ -13750,10 +13772,12 @@ rd_frame(void) } } panel->selected_tab_view = rd_handle_from_view(next_view); +#endif }break; case RD_CmdKind_MoveTabRight: case RD_CmdKind_MoveTabLeft: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *panel = ws->focused_panel; RD_View *view = rd_selected_tab_from_panel(panel); @@ -13766,18 +13790,22 @@ rd_frame(void) .view = rd_handle_from_view(view), .prev_view = rd_handle_from_view(prev_view)); } +#endif }break; case RD_CmdKind_OpenTab: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_alloc(); String8 query = rd_regs()->string; RD_ViewRuleInfo *spec = rd_view_rule_info_from_string(rd_regs()->params_tree->string); rd_view_equip_spec(view, spec, query, rd_regs()->params_tree); rd_panel_insert_tab_view(panel, panel->last_tab_view, view); +#endif }break; case RD_CmdKind_CloseTab: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_from_handle(rd_regs()->view); if(!rd_view_is_nil(view)) @@ -13785,9 +13813,11 @@ rd_frame(void) rd_panel_remove_tab_view(panel, view); rd_view_release(view); } +#endif }break; case RD_CmdKind_MoveTab: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_from_handle(rd_regs()->view); @@ -13814,16 +13844,21 @@ rd_frame(void) rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(src_panel)); } } +#endif }break; case RD_CmdKind_TabBarTop: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); panel->tab_side = Side_Min; +#endif }break; case RD_CmdKind_TabBarBottom: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); panel->tab_side = Side_Max; +#endif }break; //- rjf: files @@ -13845,6 +13880,7 @@ rd_frame(void) }break; case RD_CmdKind_Switch: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); RD_View *src_view = rd_view_from_handle(rd_regs()->view); @@ -13887,9 +13923,11 @@ rd_frame(void) existing_panel->selected_tab_view = rd_handle_from_view(existing_view); } } +#endif }break; case RD_CmdKind_SwitchToPartnerFile: { +#if 0 // TODO(rjf): @cfg RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_selected_tab_from_panel(panel); { @@ -13932,6 +13970,7 @@ rd_frame(void) } } } +#endif }break; case RD_CmdKind_RecordFileInProject: if(rd_regs()->file_path.size != 0) @@ -14026,6 +14065,7 @@ rd_frame(void) case RD_CmdKind_ResetToCompactPanels: { panel_reset_done = 1; +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); typedef enum Layout @@ -14385,11 +14425,12 @@ rd_frame(void) RD_CmdKind write_cmd = rd_cfg_src_write_cmd_kind_table[src]; rd_cmd(write_cmd, .file_path = rd_cfg_path_from_src(src)); } +#endif }break; //- rjf: thread finding case RD_CmdKind_FindThread: - for(RD_Window *ws = rd_state->first_window; ws != 0; ws = ws->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != 0; ws = ws->order_next) { DI_Scope *scope = di_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -14461,7 +14502,7 @@ rd_frame(void) di_scope_close(scope); }break; case RD_CmdKind_FindSelectedThread: - for(RD_Window *ws = rd_state->first_window; ws != 0; ws = ws->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != 0; ws = ws->order_next) { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); rd_cmd(RD_CmdKind_FindThread, @@ -14513,8 +14554,9 @@ rd_frame(void) String8List search_parts = str8_split_path(scratch.arena, file_part_of_name); // rjf: get source path - RD_View *src_view = rd_view_from_handle(rd_regs()->view); - String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, str8(src_view->query_buffer, src_view->query_string_size)); + RD_Cfg *src_view = rd_cfg_from_handle(rd_regs()->view); + String8 src_view_expr = rd_view_expr_string(); + String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, src_view_expr); String8List src_file_parts = str8_split_path(scratch.arena, src_file_path); // rjf: search for actual file @@ -14627,7 +14669,8 @@ rd_frame(void) // the biggest empty panel. // 4. If there is no empty panel, then we will pick the biggest // panel. - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); // rjf: grab things to find. path * point, process * address, etc. String8 file_path = {0}; @@ -14663,17 +14706,21 @@ rd_frame(void) } // rjf: first, try to find panel/view pair that already has the src file open - RD_Panel *panel_w_this_src_code = &rd_nil_panel; - RD_View *view_w_this_src_code = &rd_nil_view; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + RD_Cfg *panel_w_this_src_code = &rd_nil_cfg; + RD_Cfg *view_w_this_src_code = &rd_nil_cfg; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } +#if 0 // TODO(rjf): @cfg String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); if((view_kind == RD_ViewRuleKind_Text || view_kind == RD_ViewRuleKind_PendingFile) && @@ -14686,15 +14733,17 @@ rd_frame(void) break; } } +#endif } } // rjf: find a panel that already has *any* code open (prioritize largest) - RD_Panel *panel_w_any_src_code = &rd_nil_panel; + RD_PanelNode *panel_w_any_src_code = &rd_nil_panel_node; +#if 0 // TODO(rjf): @cfg { Rng2F32 root_rect = os_client_rect_from_window(ws->os); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) { if(!rd_panel_is_nil(panel->first)) { @@ -14716,8 +14765,10 @@ rd_frame(void) } } } +#endif // rjf: try to find panel/view pair that has disassembly open (prioritize largest) +#if 0 // TODO(rjf): @cfg RD_Panel *panel_w_disasm = &rd_nil_panel; RD_View *view_w_disasm = &rd_nil_view; { @@ -14751,8 +14802,10 @@ rd_frame(void) } } } +#endif // rjf: find the biggest panel +#if 0 // TODO(rjf): @cfg RD_Panel *biggest_panel = &rd_nil_panel; { Rng2F32 root_rect = os_client_rect_from_window(ws->os); @@ -14773,8 +14826,10 @@ rd_frame(void) } } } +#endif // rjf: find the biggest empty panel +#if 0 // TODO(rjf): @cfg RD_Panel *biggest_empty_panel = &rd_nil_panel; { Rng2F32 root_rect = os_client_rect_from_window(ws->os); @@ -14804,8 +14859,10 @@ rd_frame(void) } } } +#endif // rjf: choose panel for source code +#if 0 // TODO(rjf): @cfg RD_Panel *src_code_dst_panel = &rd_nil_panel; { if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = panel_w_this_src_code; } @@ -14813,18 +14870,22 @@ rd_frame(void) if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_empty_panel; } if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_panel; } } +#endif // rjf: choose panel for disassembly +#if 0 // TODO(rjf): @cfg RD_Panel *disasm_dst_panel = &rd_nil_panel; { if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = panel_w_disasm; } if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_empty_panel; } if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_panel; } } +#endif // rjf: if disasm and source code match: // if disasm preferred, cancel source // if source preferred, cancel disasm +#if 0 // TODO(rjf): @cfg if(disasm_dst_panel == src_code_dst_panel) { if(rd_regs()->prefer_disasm) @@ -14836,16 +14897,20 @@ rd_frame(void) disasm_dst_panel = &rd_nil_panel; } } +#endif // rjf: if disasm is not preferred, and we have no disassembly view // open at all, cancel disasm, so that it doesn't open if the user // doesn't want it. +#if 0 // TODO(rjf): @cfg if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel) { disasm_dst_panel = &rd_nil_panel; } +#endif // rjf: given the above, find source code location. +#if 0 // TODO(rjf): @cfg if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel) { RD_Panel *dst_panel = src_code_dst_panel; @@ -14884,8 +14949,10 @@ rd_frame(void) // rjf: record rd_cmd(RD_CmdKind_RecordFileInProject, .file_path = file_path); } +#endif // rjf: given the above, find disassembly location. +#if 0 // TODO(rjf): @cfg if(process != &ctrl_entity_nil && vaddr != 0 && disasm_dst_panel != &rd_nil_panel) { RD_Panel *dst_panel = disasm_dst_panel; @@ -14918,11 +14985,13 @@ rd_frame(void) rd_cmd(cursor_snap_kind); } } +#endif }break; //- rjf: filtering case RD_CmdKind_Filter: { +#if 0 // TODO(rjf): @cfg RD_View *view = rd_view_from_handle(rd_regs()->view); RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); B32 view_is_tab = 0; @@ -14941,9 +15010,11 @@ rd_frame(void) view->query_cursor = txt_pt(1, 1+(S64)view->query_string_size); view->query_mark = txt_pt(1, 1); } +#endif }break; case RD_CmdKind_ClearFilter: { +#if 0 // TODO(rjf): @cfg RD_View *view = rd_view_from_handle(rd_regs()->view); if(!rd_view_is_nil(view)) { @@ -14951,19 +15022,23 @@ rd_frame(void) view->is_filtering = 0; view->query_cursor = view->query_mark = txt_pt(1, 1); } +#endif }break; case RD_CmdKind_ApplyFilter: { +#if 0 // TODO(rjf): @cfg RD_View *view = rd_view_from_handle(rd_regs()->view); if(!rd_view_is_nil(view)) { view->is_filtering = 0; } +#endif }break; //- rjf: query completion case RD_CmdKind_CompleteQuery: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); String8 query_cmd_name = ws->query_cmd_name; RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(query_cmd_name); @@ -15005,9 +15080,11 @@ rd_frame(void) { rd_push_cmd(ws->query_cmd_name, ws->query_cmd_regs); } +#endif }break; case RD_CmdKind_CancelQuery: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); arena_clear(ws->query_cmd_arena); MemoryZeroStruct(&ws->query_cmd_name); @@ -15019,13 +15096,16 @@ rd_frame(void) rd_view_release(v); } ws->query_view_stack_top = &rd_nil_view; +#endif }break; //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: { +#if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); ws->dev_menu_is_open ^= 1; +#endif }break; //- rjf: general entity operations @@ -15501,8 +15581,8 @@ rd_frame(void) case RD_CmdKind_OSEvent: { OS_Event *os_event = rd_regs()->os_event; - RD_Window *ws = rd_window_from_os_handle(os_event->window); - if(os_event != 0 && ws != 0) + RD_WindowState *ws = rd_window_state_from_os_handle(os_event->window); + if(os_event != 0 && ws != &rd_nil_window_state) { UI_Event ui_event = zero_struct; UI_EventKind kind = UI_EventKind_Null; @@ -15621,7 +15701,8 @@ rd_frame(void) //- rjf: meta controls case RD_CmdKind_Edit: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Edit; @@ -15629,7 +15710,8 @@ rd_frame(void) }break; case RD_CmdKind_Accept: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Accept; @@ -15637,7 +15719,8 @@ rd_frame(void) }break; case RD_CmdKind_Cancel: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; evt.slot = UI_EventActionSlot_Cancel; @@ -15652,7 +15735,8 @@ rd_frame(void) // case RD_CmdKind_MoveLeft: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; @@ -15662,7 +15746,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRight: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_PickSelectSide|UI_EventFlag_ZeroDeltaOnSelect|UI_EventFlag_ExplicitDirectional; @@ -15672,7 +15757,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUp: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15682,7 +15768,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDown: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15692,7 +15779,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15702,7 +15790,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15712,7 +15801,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15722,7 +15812,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15732,7 +15823,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15742,7 +15834,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15752,7 +15845,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15762,7 +15856,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_ExplicitDirectional; @@ -15772,7 +15867,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpPage: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -15781,7 +15877,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownPage: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Page; @@ -15790,7 +15887,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpWhole: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -15799,7 +15897,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownWhole: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Whole; @@ -15808,7 +15907,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveLeftChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15818,7 +15918,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveRightChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15828,7 +15929,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15838,7 +15940,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownChunkSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; @@ -15848,7 +15951,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpPageSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15858,7 +15962,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownPageSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15868,7 +15973,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpWholeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15878,7 +15984,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownWholeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15888,7 +15995,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveUpReorder: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_Reorder; @@ -15898,7 +16006,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveDownReorder: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_Reorder; @@ -15908,7 +16017,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveHome: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -15917,7 +16027,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveEnd: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.delta_unit = UI_EventDeltaUnit_Line; @@ -15926,7 +16037,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveHomeSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15936,7 +16048,8 @@ rd_frame(void) }break; case RD_CmdKind_MoveEndSelect: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; evt.flags = UI_EventFlag_KeepMark; @@ -15946,7 +16059,8 @@ rd_frame(void) }break; case RD_CmdKind_SelectAll: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt1 = zero_struct; evt1.kind = UI_EventKind_Navigate; evt1.delta_unit = UI_EventDeltaUnit_Whole; @@ -15961,7 +16075,8 @@ rd_frame(void) }break; case RD_CmdKind_DeleteSingle: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -15971,7 +16086,8 @@ rd_frame(void) }break; case RD_CmdKind_DeleteChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -15981,7 +16097,8 @@ rd_frame(void) }break; case RD_CmdKind_BackspaceSingle: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; @@ -15991,7 +16108,8 @@ rd_frame(void) }break; case RD_CmdKind_BackspaceChunk: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Delete; @@ -16001,7 +16119,8 @@ rd_frame(void) }break; case RD_CmdKind_Copy: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_KeepMark; @@ -16009,7 +16128,8 @@ rd_frame(void) }break; case RD_CmdKind_Cut: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; evt.flags = UI_EventFlag_Copy|UI_EventFlag_Delete; @@ -16017,7 +16137,8 @@ rd_frame(void) }break; case RD_CmdKind_Paste: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = os_get_clipboard_text(scratch.arena); @@ -16025,7 +16146,8 @@ rd_frame(void) }break; case RD_CmdKind_InsertText: { - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; evt.string = rd_regs()->string; @@ -16316,9 +16438,9 @@ rd_frame(void) if(need_refocus && (selected_thread != &ctrl_entity_nil || thread != &ctrl_entity_nil)) { B32 any_window_is_focused = 0; - for(RD_Window *window = rd_state->first_window; window != 0; window = window->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - if(os_window_is_focused(window->os)) + if(os_window_is_focused(ws->os)) { any_window_is_focused = 1; break; @@ -16326,16 +16448,17 @@ rd_frame(void) } if(!any_window_is_focused) { - RD_Window *window = rd_window_from_handle(rd_state->last_focused_window); - if(window == 0) + RD_Cfg *last_focused_window = rd_cfg_from_handle(rd_state->last_focused_window); + RD_WindowState *ws = rd_window_state_from_cfg(last_focused_window); + if(ws == &rd_nil_window_state) { - window = rd_state->first_window; + ws = rd_state->first_window_state; } - if(window != 0) + if(ws != &rd_nil_window_state) { - os_window_set_minimized(window->os, 0); - os_window_bring_to_front(window->os); - os_window_focus(window->os); + os_window_set_minimized(ws->os, 0); + os_window_bring_to_front(ws->os); + os_window_focus(ws->os); } } } @@ -16398,27 +16521,6 @@ rd_frame(void) } } - ////////////////////////////// - //- rjf: capture is active? -> keep rendering - // - if(ProfIsCapturing()) - { - // rd_request_frame(); - } - - ////////////////////////////// - //- rjf: commit params changes for all views - // - { - for(RD_View *v = rd_state->first_view; !rd_view_is_nil(v); v = v->alloc_next) - { - if(v->params_write_gen == v->params_read_gen+1) - { - v->params_read_gen += 1; - } - } - } - //////////////////////////// //- rjf: rotate command slots, bump command gen counter // @@ -16475,41 +16577,47 @@ rd_frame(void) Temp scratch = scratch_begin(0, 0); rd_state->ambiguous_path_slots_count = 512; rd_state->ambiguous_path_slots = push_array(rd_frame_arena(), RD_AmbiguousPathNode *, rd_state->ambiguous_path_slots_count); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - for(RD_Panel *p = w->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_Cfg *window = rd_cfg_from_handle(ws->cfg_handle); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - for(RD_View *v = p->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + for(RD_CfgNode *tab_n = p->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(v)) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } - String8 eval_string = str8(v->query_buffer, v->query_string_size); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); - if(file_path.size != 0) + RD_RegsScope(.view = rd_handle_from_cfg(tab)) { - String8 name = str8_skip_last_slash(file_path); - U64 hash = d_hash_from_string__case_insensitive(name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) + String8 eval_string = rd_view_expr_string(); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); + if(file_path.size != 0) { - if(str8_match(n->name, name, StringMatchFlag_CaseInsensitive)) + String8 name = str8_skip_last_slash(file_path); + U64 hash = d_hash_from_string__case_insensitive(name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) { - node = n; - break; + if(str8_match(n->name, name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } } + if(node == 0) + { + node = push_array(rd_frame_arena(), RD_AmbiguousPathNode, 1); + SLLStackPush(rd_state->ambiguous_path_slots[slot_idx], node); + node->name = push_str8_copy(rd_frame_arena(), name); + } + str8_list_push(rd_frame_arena(), &node->paths, push_str8_copy(rd_frame_arena(), file_path)); } - if(node == 0) - { - node = push_array(rd_frame_arena(), RD_AmbiguousPathNode, 1); - SLLStackPush(rd_state->ambiguous_path_slots[slot_idx], node); - node->name = push_str8_copy(rd_frame_arena(), name); - } - str8_list_push(rd_frame_arena(), &node->paths, push_str8_copy(rd_frame_arena(), file_path)); } } } @@ -16533,21 +16641,21 @@ rd_frame(void) dr_begin_frame(); for EachIndex(slot_idx, rd_state->window_state_slots_count) { - for(RD_WindowState *w = rd_state->window_state_slots[slot_idx]; - w != 0; - w = w->next) + for(RD_WindowState *w = rd_state->first_window_state; + w != &rd_nil_window_state; + w = w->order_next) { B32 window_is_focused = os_window_is_focused(w->os); if(window_is_focused) { - rd_state->last_focused_window = rd_handle_from_window(w); + rd_state->last_focused_window = w->cfg_handle; } rd_push_regs(); rd_regs()->window = w->cfg_handle; - rd_window_frame(w); + rd_window_frame(); MemoryZeroStruct(&w->ui_events); RD_Regs *window_regs = rd_pop_regs(); - if(rd_window_from_handle(rd_state->last_focused_window) == w) + if(rd_handle_match(rd_state->last_focused_window, w->cfg_handle)) { MemoryCopyStruct(rd_regs(), window_regs); } @@ -16593,7 +16701,7 @@ rd_frame(void) ProfScope("submit rendering to all windows") { r_begin_frame(); - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { r_window_begin_frame(w->os, w->r); dr_submit_bucket(w->os, w->r, w->draw_bucket); @@ -16608,17 +16716,18 @@ rd_frame(void) if(depth == 0) { RD_HandleList windows_to_show = {0}; - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { if(w->frames_alive == 1) { - rd_handle_list_push(scratch.arena, &windows_to_show, rd_handle_from_window(w)); + rd_handle_list_push(scratch.arena, &windows_to_show, w->cfg_handle); } } for(RD_HandleNode *n = windows_to_show.first; n != 0; n = n->next) { - RD_Window *window = rd_window_from_handle(n->handle); - DeferLoop(depth += 1, depth -= 1) os_window_first_paint(window->os); + RD_Cfg *window = rd_cfg_from_handle(n->handle); + RD_WindowState *ws = rd_window_state_from_cfg(window); + DeferLoop(depth += 1, depth -= 1) os_window_first_paint(ws->os); } } @@ -16680,11 +16789,11 @@ rd_frame(void) os_append_data_to_file_path(rd_state->log_path, log.strings[LogMsgKind_Info]); if(log.strings[LogMsgKind_UserError].size != 0) { - for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - w->error_string_size = Min(sizeof(w->error_buffer), log.strings[LogMsgKind_UserError].size); - MemoryCopy(w->error_buffer, log.strings[LogMsgKind_UserError].str, w->error_string_size); - w->error_t = 1.f; + ws->error_string_size = Min(sizeof(ws->error_buffer), log.strings[LogMsgKind_UserError].size); + MemoryCopy(ws->error_buffer, log.strings[LogMsgKind_UserError].str, ws->error_string_size); + ws->error_t = 1.f; } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5a46b69c..e5b1b96e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -161,7 +161,7 @@ enum RD_ViewRuleInfoFlag_ProjectFiltered = (1<<7), }; -#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, MD_Node *params, Rng2F32 rect) +#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, Rng2F32 rect) #define RD_VIEW_RULE_UI_FUNCTION_NAME(name) rd_view_rule_ui_##name #define RD_VIEW_RULE_UI_FUNCTION_DEF(name) internal RD_VIEW_RULE_UI_FUNCTION_SIG(RD_VIEW_RULE_UI_FUNCTION_NAME(name)) typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); @@ -183,7 +183,6 @@ struct RD_ViewState RD_ViewState *hash_next; RD_ViewState *hash_prev; RD_Handle cfg_handle; - EV_Key ev_key; // rjf: touch info U64 last_frame_index_touched; @@ -202,10 +201,6 @@ struct RD_ViewState RD_ArenaExt *last_arena_ext; void *user_data; - // rjf: expression string - U8 expression_buffer[KB(1)]; - U64 expression_string_size; - // rjf: filter editing controls B32 is_filtering; TxtPt filter_cursor; @@ -646,9 +641,8 @@ struct RD_WindowState String8 query_cmd_name; RD_Regs *query_cmd_regs; U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; + RD_Cfg *query_view_stack_top; B32 query_view_selected; - F32 query_view_selected_t; - F32 query_view_t; // rjf: hover eval state B32 hover_eval_focused; @@ -850,6 +844,7 @@ struct RD_State RD_WindowStateSlot *window_state_slots; RD_WindowState *free_window_state; RD_Handle last_focused_window; + // TODO(rjf): @cfg must be nil-initialized RD_WindowState *first_window_state; RD_WindowState *last_window_state; @@ -1087,12 +1082,15 @@ internal void rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...); internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child); internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child); internal RD_Cfg *rd_cfg_child_from_string(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_top_level_list_from_string(Arena *arena, String8 string); internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string); internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); internal void rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); +#define rd_cfg_list_first(list) ((list)->count ? (list)->first->v : &rd_nil_cfg) +#define rd_cfg_list_last(list) ((list)->count ? (list)->last->v : &rd_nil_cfg) internal RD_PanelTree rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg); internal RD_PanelNodeRec rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_off, U64 child_off); @@ -1199,7 +1197,6 @@ internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); //////////////////////////////// //~ rjf: View Functions -internal RD_ViewState *rd_view_state_from_cfg_ev_key(RD_Cfg *cfg, EV_Key ev_key); internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 77373bc9..0f5d5cd6 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -148,6 +148,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla Side search_query_side = Side_Invalid; B32 search_query_is_active = 0; { +#if 0 // TODO(rjf): @cfg RD_Window *window = rd_window_from_handle(rd_regs()->window); RD_CmdKind query_cmd_kind = rd_cmd_kind_from_string(window->query_cmd_name); if(query_cmd_kind == RD_CmdKind_FindTextForward || @@ -157,6 +158,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla search_query_is_active = 1; search_query_side = (query_cmd_kind == RD_CmdKind_FindTextForward) ? Side_Max : Side_Min; } +#endif } ////////////////////////////// @@ -1304,6 +1306,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: root-level view rule which has a ui hook? call into that to build the UI // B32 is_top_level_hook = 0; +#if 0 // TODO(rjf): @cfg { RD_ViewRuleInfo *hook_rule_info = 0; MD_Node *hook_rule_root = &md_nil_node; @@ -1323,6 +1326,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo is_top_level_hook = 1; } } +#endif ////////////////////////////// //- rjf: determine autocompletion string @@ -2445,6 +2449,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewRowKind_Canvas: ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) { +#if 0 // TODO(rjf): @cfg //- rjf: unpack RD_WatchViewPoint pt = {0, row->block->key, row->key}; RD_View *view = rd_view_from_handle(rd_regs()->view); @@ -2537,6 +2542,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: pop interaction registers rd_pop_regs(); } +#endif }break; //////////////////// @@ -3116,7 +3122,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo UI_Parent(box) { String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); + cell_ui_hook(row_expr, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); } sig = ui_signal_from_box(box); } @@ -4066,10 +4072,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) RD_PathQuery path_query = rd_path_query_from_string(query_normalized_with_opt_slash); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); +#if 0 // TODO(rjf): @cfg RD_Window *window = rd_window_from_handle(rd_regs()->window); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - B32 file_selection = !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFiles); - B32 dir_selection = !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFolders); +#endif + B32 file_selection = 1;// !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFiles); + B32 dir_selection = 1;// !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFolders); //- rjf: get extra state for this view UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); @@ -4892,9 +4900,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); +#if 0 // TODO(rjf): @cfg RD_Window *window = rd_window_from_handle(rd_regs()->window); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - RD_EntityKind entity_kind = cmd_kind_info->query.entity_kind; +#endif + RD_EntityKind entity_kind = RD_EntityKind_Nil; // cmd_kind_info->query.entity_kind; F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0e2c3355..c81bdd68 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -343,8 +343,9 @@ rd_cmd_list_menu_buttons(U64 count, String8 *cmd_names, U32 *fastpath_codepoints { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_names[idx]); ui_ctx_menu_close(); - RD_Window *window = rd_window_from_handle(rd_regs()->window); - window->menu_bar_focused = 0; + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + ws->menu_bar_focused = 0; } } scratch_end(scratch); From 6ff26938238576e75bf5b45d74d732ee521873b3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 10 Jan 2025 15:53:40 -0800 Subject: [PATCH 003/755] part 3: more progress on entity -> cfg frontend pass --- project.4coder | 2 +- src/raddbg/raddbg_core.c | 622 +++++++++++++++++++++++++++----------- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_main.c | 23 +- src/raddbg/raddbg_views.c | 59 ++-- 5 files changed, 493 insertions(+), 214 deletions(-) diff --git a/project.4coder b/project.4coder index dc18d243..0be9237b 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "build raddbg telemetry clang", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ae583352..d1b30a00 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -597,7 +597,7 @@ internal RD_Cfg * rd_cfg_from_handle(RD_Handle handle) { RD_Cfg *cfg = (RD_Cfg *)handle.u64[0]; - if(handle.u64[1] != cfg->gen) + if(cfg == 0 || handle.u64[1] != cfg->gen) { cfg = &rd_nil_cfg; } @@ -959,13 +959,14 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) } // rjf: extract cfg info + B32 panel_has_tabs = 0; dst->cfg = src; dst->pct_of_parent = (F32)f64_from_str8(src->string); dst->tab_side = (rd_cfg_child_from_string(src, str8_lit("tabs_on_bottom")) != &rd_nil_cfg ? Side_Max : Side_Min); dst->split_axis = active_split_axis; for(RD_Cfg *src_child = src->first; src_child != &rd_nil_cfg; src_child = src_child->next) { - MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src->string); + MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string); if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) { // NOTE(rjf): skip - this is a panel. @@ -976,8 +977,9 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) } else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier) { + panel_has_tabs = 1; rd_cfg_list_push(arena, &dst->tabs, src_child); - if(rd_cfg_child_from_string(src_child, str8_lit("selected"))) + if(rd_cfg_child_from_string(src_child, str8_lit("selected")) != &rd_nil_cfg) { dst->selected_tab = src_child; } @@ -986,6 +988,19 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) // rjf: recurse rec = rd_cfg_rec__depth_first(src_root, src); + if(panel_has_tabs) + { + MemoryZeroStruct(&rec); + rec.next = &rd_nil_cfg; + for(RD_Cfg *p = src; p != src_root && p != &rd_nil_cfg; p = p->parent, rec.pop_count += 1) + { + if(p->next != &rd_nil_cfg) + { + rec.next = p->next; + break; + } + } + } if(rec.push_count > 0) { dst_active_parent = dst; @@ -1018,9 +1033,9 @@ rd_panel_node_rec__depth_first(RD_PanelNode *root, RD_PanelNode *panel, U64 sib_ } else for(RD_PanelNode *p = panel; p != &rd_nil_panel_node && p != root; p = p->parent, rec.pop_count += 1) { - if(*MemberFromOffset(RD_PanelNode **, panel, sib_off) != &rd_nil_panel_node) + if(*MemberFromOffset(RD_PanelNode **, p, sib_off) != &rd_nil_panel_node) { - rec.next = *MemberFromOffset(RD_PanelNode **, panel, sib_off); + rec.next = *MemberFromOffset(RD_PanelNode **, p, sib_off); break; } } @@ -2668,7 +2683,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) U64 slot_idx = hash%rd_state->view_state_slots_count; RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; RD_ViewState *view_state = &rd_nil_view_state; - for(RD_ViewState *v = slot->first; v != &rd_nil_view_state; v = v->hash_next) + for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) { if(rd_handle_match(v->cfg_handle, cfg_handle)) { @@ -2679,7 +2694,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) if(view_state == &rd_nil_view_state) { view_state = rd_state->free_view_state; - if(view_state != &rd_nil_view_state) + if(view_state) { SLLStackPop_N(rd_state->free_view_state, hash_next); } @@ -2688,7 +2703,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) view_state = push_array(rd_state->arena, RD_ViewState, 1); } MemoryCopyStruct(view_state, &rd_nil_view_state); - DLLPushBack_NPZ(&rd_nil_view_state, slot->first, slot->last, view_state, hash_next, hash_prev); + DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_handle = cfg_handle; view_state->arena = arena_alloc(); } @@ -3005,7 +3020,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) //- rjf: scan for existing window RD_WindowState *ws = &rd_nil_window_state; - for(RD_WindowState *w = slot->first; w != &rd_nil_window_state; w = w->hash_next) + for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) { if(rd_handle_match(w->cfg_handle, handle)) { @@ -3052,6 +3067,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) MemoryZeroStruct(ws); // rjf: fill out window + ws->cfg_handle = handle; ws->arena = arena_alloc(); { String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); @@ -3094,53 +3110,9 @@ rd_window_state_from_cfg(RD_Cfg *cfg) os_window_set_maximized(ws->os, 1); } - // rjf: pre-emptively rasterize common glyphs - if(rd_state->first_window_state == &rd_nil_window_state) RD_RegsScope(.window = handle) - { - RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; - RD_FontSlot icon_font_slot = RD_FontSlot_Icons; - for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) - { - Temp scratch = scratch_begin(0, 0); - RD_FontSlot slot = english_font_slots[idx]; - String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Code), - 0, 0, 0, - sample_text); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Main), - 0, 0, 0, - sample_text); - scratch_end(scratch); - } - for(RD_IconKind icon_kind = RD_IconKind_Null; icon_kind < RD_IconKind_COUNT; icon_kind = (RD_IconKind)(icon_kind+1)) - { - Temp scratch = scratch_begin(0, 0); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(icon_font_slot), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Main), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Code), - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - scratch_end(scratch); - } - } - // rjf: hook up window links DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); - DLLPushBack_NPZ(&rd_nil_window_state, slot->first, slot->last, ws, hash_next, hash_prev); + DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); scratch_end(scratch); } @@ -3158,9 +3130,8 @@ internal RD_WindowState * rd_window_state_from_os_handle(OS_Handle os) { RD_WindowState *ws = &rd_nil_window_state; - for EachIndex(slot_idx, rd_state->window_state_slots_count) { - for(RD_WindowState *w = rd_state->window_state_slots[slot_idx].first; + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { @@ -3204,6 +3175,52 @@ rd_window_frame(void) ws->window_temporarily_focused_ipc = 0; ui_select_state(ws->ui); + ////////////////////////////// + //- rjf: pre-emptively rasterize common glyphs on the first frame + // + if(rd_state->first_window_state == ws && rd_state->last_window_state == ws && ws->frames_alive == 0) + { + RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; + RD_FontSlot icon_font_slot = RD_FontSlot_Icons; + for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) + { + Temp scratch = scratch_begin(0, 0); + RD_FontSlot slot = english_font_slots[idx]; + String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(slot), + rd_font_size_from_slot(RD_FontSlot_Code), + 0, 0, 0, + sample_text); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(slot), + rd_font_size_from_slot(RD_FontSlot_Main), + 0, 0, 0, + sample_text); + scratch_end(scratch); + } + for(RD_IconKind icon_kind = RD_IconKind_Null; icon_kind < RD_IconKind_COUNT; icon_kind = (RD_IconKind)(icon_kind+1)) + { + Temp scratch = scratch_begin(0, 0); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(icon_font_slot), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(RD_FontSlot_Main), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_push_run_from_string(scratch.arena, + rd_font_from_slot(icon_font_slot), + rd_font_size_from_slot(RD_FontSlot_Code), + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + scratch_end(scratch); + } + } + ////////////////////////////// //- rjf: fill panel/view interaction registers // @@ -5791,7 +5808,7 @@ rd_window_frame(void) // rjf: close dropdown UI_Key close_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###close_ctx_menu"); - UI_CtxMenu(close_ctx_menu_key) + UI_CtxMenu(close_ctx_menu_key) RD_Palette(RD_PaletteCode_ImplicitButton) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Window, 0, "Close Window"))) { @@ -7472,116 +7489,116 @@ rd_window_frame(void) drop_sites[view_idx].prev_view = prev_tab; drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p); } - - // rjf: build add-new-tab button - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) - UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column + } + + // rjf: build add-new-tab button + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) + UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + UI_Column + { + if(panel->tab_side == Side_Max) { - if(panel->tab_side == Side_Max) + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Palette(RD_PaletteCode_ImplicitButton) + { + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel); + UI_Signal sig = ui_signal_from_box(add_new_box); + if(ui_clicked(sig)) { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); } - else + } + } + + scratch_end(scratch); + } + + // rjf: interact with tab bar + ui_signal_from_box(tab_bar_box); + + // rjf: fill out last drop site + { + drop_sites[drop_site_count-1].p = drop_site_max_p; + drop_sites[drop_site_count-1].prev_view = rd_cfg_list_last(&panel->tabs); + } + + // rjf: more precise drop-sites on tab bar + { + Vec2F32 mouse = ui_mouse(); + RD_Cfg *drag_tab = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg) + { + // rjf: mouse => hovered drop site + F32 min_distance = 0; + DropSite *active_drop_site = 0; + if(catchall_drop_site_hovered) + { + for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HoverCursor(OS_Cursor_HandPoint) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) + F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); + if(drop_site_idx == 0 || distance < min_distance) { - rd_cmd(RD_CmdKind_FocusPanel); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + active_drop_site = &drop_sites[drop_site_idx]; + min_distance = distance; } } } - scratch_end(scratch); - } - - // rjf: interact with tab bar - ui_signal_from_box(tab_bar_box); - - // rjf: fill out last drop site - { - drop_sites[drop_site_count-1].p = drop_site_max_p; - drop_sites[drop_site_count-1].prev_view = rd_cfg_list_last(&panel->tabs); - } - - // rjf: more precise drop-sites on tab bar - { - Vec2F32 mouse = ui_mouse(); - RD_Cfg *drag_tab = rd_cfg_from_handle(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg) + // rjf: store closest prev-view + if(active_drop_site != 0) { - // rjf: mouse => hovered drop site - F32 min_distance = 0; - DropSite *active_drop_site = 0; - if(catchall_drop_site_hovered) + rd_last_drag_drop_prev_tab = rd_handle_from_cfg(active_drop_site->prev_view); + } + else + { + rd_last_drag_drop_prev_tab = rd_handle_zero(); + } + + // rjf: vis + if(drag_tab != &rd_nil_cfg && active_drop_site != 0) + { + RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + + // rjf: drop + if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) + { + RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *src_panel = rd_cfg_from_handle(rd_state->drag_drop_regs->panel); + RD_Cfg *dst_panel = panel->cfg; + if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg) { - for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) - { - F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); - if(drop_site_idx == 0 || distance < min_distance) - { - active_drop_site = &drop_sites[drop_site_idx]; - min_distance = distance; - } - } - } - - // rjf: store closest prev-view - if(active_drop_site != 0) - { - rd_last_drag_drop_prev_tab = rd_handle_from_cfg(active_drop_site->prev_view); - } - else - { - rd_last_drag_drop_prev_tab = rd_handle_zero(); - } - - // rjf: vis - if(drag_tab != &rd_nil_cfg && active_drop_site != 0) - { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) - { - RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); - RD_Cfg *src_panel = rd_cfg_from_handle(rd_state->drag_drop_regs->panel); - RD_Cfg *dst_panel = panel->cfg; - if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg) - { - rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_cfg(src_panel), - .dst_panel = rd_handle_from_cfg(dst_panel), - .view = rd_handle_from_cfg(drag_view), - .prev_view = rd_handle_from_cfg(active_drop_site->prev_view)); - } + rd_cmd(RD_CmdKind_MoveTab, + .panel = rd_handle_from_cfg(src_panel), + .dst_panel = rd_handle_from_cfg(dst_panel), + .view = rd_handle_from_cfg(drag_view), + .prev_view = rd_handle_from_cfg(active_drop_site->prev_view)); } } } @@ -10111,6 +10128,48 @@ rd_font_from_slot(RD_FontSlot slot) internal F32 rd_font_size_from_slot(RD_FontSlot slot) { + B32 explicit_config_found = 0; + F32 result = 11.f; + + // rjf: determine config key based on slot + String8 key = {0}; + switch(slot) + { + default:{}break; + case RD_FontSlot_Icons: + case RD_FontSlot_Main:{key = str8_lit("main_font_size");}break; + case RD_FontSlot_Code:{key = str8_lit("code_font_size");}break; + } + + // rjf: find most-granular config scope to begin looking for the setting + RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + + // rjf: scan upwards the config tree until we find the setting + for(RD_Cfg *parent = start_cfg; parent != &rd_nil_cfg; parent = parent->parent) + { + RD_Cfg *child = rd_cfg_child_from_string(parent, key); + if(child != &rd_nil_cfg) + { + result = (F32)f64_from_str8(child->first->string); + explicit_config_found = 1; + break; + } + } + + // rjf: if we haven't found any explicit config, then use the window's monitor's DPI + // based on some default size. + if(explicit_config_found == 0) + { + RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + F32 dpi = os_dpi_from_window(ws->os); + result *= (dpi / 96.f); + } + return result; + +#if 0 // TODO(rjf): @cfg F32 result = 0; RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(wcfg); @@ -10146,6 +10205,7 @@ rd_font_size_from_slot(RD_FontSlot slot) }break; } return result; +#endif } internal FNT_RasterFlags @@ -11247,6 +11307,19 @@ rd_init(CmdLine *cmdln) RD_Cfg *transient = rd_cfg_new(rd_state->root_cfg, str8_lit("transient")); } + // rjf: set up window cache + { + rd_state->window_state_slots_count = 64; + rd_state->window_state_slots = push_array(arena, RD_WindowStateSlot, rd_state->window_state_slots_count); + rd_state->first_window_state = rd_state->last_window_state = &rd_nil_window_state; + } + + // rjf: set up view cache + { + rd_state->view_state_slots_count = 4096; + rd_state->view_state_slots = push_array(arena, RD_ViewStateSlot, rd_state->view_state_slots_count); + } + // rjf: set up user / project paths { Temp scratch = scratch_begin(0, 0); @@ -11452,7 +11525,7 @@ rd_frame(void) for(RD_WindowState *ws = rd_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) { next = ws->hash_next; - if(ws->last_frame_index_touched+1 < rd_state->frame_index) + if(ws->last_frame_index_touched+2 < rd_state->frame_index) { ui_state_release(ws->ui); r_window_unequip(ws->os, ws->r); @@ -11463,7 +11536,7 @@ rd_frame(void) arena_release(ws->hover_eval_arena); arena_release(ws->autocomp_lister_params_arena); arena_release(ws->arena); - DLLRemove_NP(rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); SLLStackPush_N(rd_state->free_window_state, ws, order_next); } @@ -11481,13 +11554,14 @@ rd_frame(void) for(RD_ViewState *vs = rd_state->view_state_slots[slot_idx].first, *next; vs != 0; vs = next) { next = vs->hash_next; - if(vs->last_frame_index_touched+1 < rd_state->frame_index) + if(vs->last_frame_index_touched+2 < rd_state->frame_index) { for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) { arena_release(ext->arena); } arena_release(vs->arena); + SLLStackPush_N(rd_state->free_view_state, vs, hash_next); } } } @@ -12068,7 +12142,6 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // - B32 panel_reset_done = 0; if(depth == 0) { for(;rd_next_cmd(&cmd);) RD_RegsScope() @@ -14064,7 +14137,200 @@ rd_frame(void) case RD_CmdKind_ResetToDefaultPanels: case RD_CmdKind_ResetToCompactPanels: { - panel_reset_done = 1; + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *panels = rd_cfg_child_from_string(window, str8_lit("panels")); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + + //- rjf: define all of the "fixed" tabs we care about +#define FixedTab_XList \ +X(watch)\ +X(locals)\ +X(regs)\ +X(globals)\ +X(tlocals)\ +X(types)\ +X(procs)\ +X(call_stack)\ +X(breakpoints)\ +X(watch_pins)\ +X(output)\ +X(targets)\ +X(scheduler)\ +X(modules)\ +X(disasm)\ +X(memory)\ +X(getting_started) +#define X(name) RD_Cfg *name = &rd_nil_cfg; + FixedTab_XList +#undef X + + //- rjf: find all the fixed tabs, and all text viewers + RD_CfgList texts = {0}; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + B32 need_unhook = 1; + if(0){} +#define X(name) else if(str8_match(tab->string, str8_lit(#name), 0)) {name = tab;} + FixedTab_XList +#undef X + else if(str8_match(tab->string, str8_lit("text"), 0)) {rd_cfg_list_push(scratch.arena, &texts, tab);} + else + { + need_unhook = 0; + } + if(need_unhook) + { + rd_cfg_unhook(panel->cfg, tab); + } + } + } + + //- rjf: release the old panel tree + rd_cfg_release(panels); + + //- rjf: allocate any missing tabs +#define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} + FixedTab_XList +#undef X + + //- rjf: eliminate all tab selections +#define X(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} + FixedTab_XList +#undef X + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_release(rd_cfg_child_from_string(n->v, str8_lit("selected"))); + } + + //- rjf: create the panel root + panels = rd_cfg_new(window, str8_lit("panels")); + + //- rjf: rebuild the new panel tree + switch(kind) + { + default:{}break; + + //- rjf: (default layout) + case RD_CmdKind_ResetToDefaultPanels: + { + // rjf: root split + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.85")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.15")); + + // rjf: root_0 split + RD_Cfg *root_0_0 = rd_cfg_new(root_0, str8_lit("0.80")); + RD_Cfg *root_0_1 = rd_cfg_new(root_0, str8_lit("0.20")); + + // rjf: root_1 split + RD_Cfg *root_1_0 = rd_cfg_new(root_1, str8_lit("0.50")); + RD_Cfg *root_1_1 = rd_cfg_new(root_1, str8_lit("0.50")); + rd_cfg_insert_child(root_1_0, root_1_0->last, targets); + rd_cfg_insert_child(root_1_1, root_1_1->last, scheduler); + rd_cfg_new(targets, str8_lit("selected")); + rd_cfg_new(scheduler, str8_lit("selected")); + + // rjf: root 0_0 split + RD_Cfg *root_0_0_0 = rd_cfg_new(root_0_0, str8_lit("0.25")); + RD_Cfg *root_0_0_1 = rd_cfg_new(root_0_0, str8_lit("0.75")); + + // rjf: root_0_0_0 split + RD_Cfg *root_0_0_0_0 = rd_cfg_new(root_0_0_0, str8_lit("0.50")); + RD_Cfg *root_0_0_0_1 = rd_cfg_new(root_0_0_0, str8_lit("0.50")); + rd_cfg_insert_child(root_0_0_0_0, root_0_0_0_0->last, disasm); + rd_cfg_new(disasm, str8_lit("selected")); + + // rjf: root_0_1 split + RD_Cfg *root_0_1_0 = rd_cfg_new(root_0_1, str8_lit("0.60")); + RD_Cfg *root_0_1_1 = rd_cfg_new(root_0_1, str8_lit("0.40")); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, watch); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, locals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, regs); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, globals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, tlocals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, types); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, procs); + rd_cfg_new(watch, str8_lit("selected")); + rd_cfg_new(root_0_1_0, str8_lit("tabs_on_bottom")); + rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, call_stack); + rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, modules); + rd_cfg_new(call_stack, str8_lit("selected")); + rd_cfg_new(root_0_1_1, str8_lit("tabs_on_bottom")); + + // rjf: fill main panel with getting started, OR all collected code views + RD_Cfg *main_panel = root_0_0_1; + if(getting_started != &rd_nil_cfg) + { + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); + } + else if(texts.first) + { + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); + } + + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); + }break; + + //- rjf: (compact layout) + case RD_CmdKind_ResetToCompactPanels: + { + // rjf: root split + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.25")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.75")); + + // rjf: root_0 split + RD_Cfg *root_0_0 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_1 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_2 = rd_cfg_new(root_0, str8_lit("0.25")); + RD_Cfg *root_0_3 = rd_cfg_new(root_0, str8_lit("0.25")); + rd_cfg_insert_child(root_0_0, root_0_0->last, watch); + rd_cfg_insert_child(root_0_0, root_0_0->last, types); + rd_cfg_new(watch, str8_lit("selected")); + rd_cfg_insert_child(root_0_1, root_0_1->last, scheduler); + rd_cfg_insert_child(root_0_1, root_0_1->last, targets); + rd_cfg_insert_child(root_0_1, root_0_1->last, breakpoints); + rd_cfg_insert_child(root_0_1, root_0_1->last, watch_pins); + rd_cfg_new(scheduler, str8_lit("selected")); + rd_cfg_insert_child(root_0_2, root_0_2->last, disasm); + rd_cfg_insert_child(root_0_2, root_0_2->last, output); + rd_cfg_new(disasm, str8_lit("selected")); + rd_cfg_insert_child(root_0_3, root_0_3->last, call_stack); + rd_cfg_insert_child(root_0_3, root_0_3->last, modules); + rd_cfg_new(call_stack, str8_lit("selected")); + + // rjf: fill main panel with getting started, OR all collected code views + RD_Cfg *main_panel = root_1; + if(getting_started != &rd_nil_cfg) + { + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); + } + else if(texts.first) + { + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); + } + + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); + }break; + } + #if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); @@ -16639,26 +16905,24 @@ rd_frame(void) // { dr_begin_frame(); - for EachIndex(slot_idx, rd_state->window_state_slots_count) + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { - for(RD_WindowState *w = rd_state->first_window_state; - w != &rd_nil_window_state; - w = w->order_next) + RD_Cfg *window = n->v; + RD_WindowState *w = rd_window_state_from_cfg(window); + B32 window_is_focused = os_window_is_focused(w->os); + if(window_is_focused) { - B32 window_is_focused = os_window_is_focused(w->os); - if(window_is_focused) - { - rd_state->last_focused_window = w->cfg_handle; - } - rd_push_regs(); - rd_regs()->window = w->cfg_handle; - rd_window_frame(); - MemoryZeroStruct(&w->ui_events); - RD_Regs *window_regs = rd_pop_regs(); - if(rd_handle_match(rd_state->last_focused_window, w->cfg_handle)) - { - MemoryCopyStruct(rd_regs(), window_regs); - } + rd_state->last_focused_window = w->cfg_handle; + } + rd_push_regs(); + rd_regs()->window = w->cfg_handle; + rd_window_frame(); + MemoryZeroStruct(&w->ui_events); + RD_Regs *window_regs = rd_pop_regs(); + if(rd_handle_match(rd_state->last_focused_window, w->cfg_handle)) + { + MemoryCopyStruct(rd_regs(), window_regs); } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index e5b1b96e..8817e572 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -933,6 +933,7 @@ read_only global RD_PanelNode rd_nil_panel_node = &rd_nil_panel_node, 0, &rd_nil_cfg, + .selected_tab = &rd_nil_cfg, }; read_only global RD_Entity rd_nil_entity = diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index f0f97e8a..52e6df14 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -750,29 +750,32 @@ entry_point(CmdLine *cmd_line) if(msg.size != 0) { log_infof("ipc_msg: \"%S\"", msg); - RD_Window *dst_window = rd_state->first_window; - for(RD_Window *window = dst_window; window != 0; window = window->next) + RD_WindowState *dst_ws = rd_state->first_window_state; + for(RD_WindowState *ws = dst_ws; ws != &rd_nil_window_state; ws = ws->order_next) { - if(os_window_is_focused(window->os)) + if(os_window_is_focused(ws->os)) { - dst_window = window; + dst_ws = ws; break; } } - if(dst_window != 0) + if(dst_ws != &rd_nil_window_state) { - dst_window->window_temporarily_focused_ipc = 1; + dst_ws->window_temporarily_focused_ipc = 1; U64 first_space_pos = str8_find_needle(msg, 0, str8_lit(" "), 0); String8 cmd_kind_name_string = str8_prefix(msg, first_space_pos); String8 cmd_args_string = str8_skip_chop_whitespace(str8_skip(msg, first_space_pos)); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_kind_name_string); if(cmd_kind_info != &rd_nil_cmd_kind_info) RD_RegsScope() { - if(dst_window != rd_window_from_handle(rd_regs()->window)) + if(!rd_handle_match(dst_ws->cfg_handle, rd_regs()->window)) { - rd_regs()->window = rd_handle_from_window(dst_window); - rd_regs()->panel = rd_handle_from_panel(dst_window->focused_panel); - rd_regs()->view = dst_window->focused_panel->selected_tab_view; + Temp scratch = scratch_begin(0, 0); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(dst_ws->cfg_handle)); + rd_regs()->window = dst_ws->cfg_handle; + rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); + rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); + scratch_end(scratch); } rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, cmd_args_string); rd_push_cmd(cmd_kind_name_string, rd_regs()); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0f5d5cd6..d73009e8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -5106,9 +5106,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); +#if 0 // TODO(rjf): @cfg RD_Window *window = rd_window_from_handle(rd_regs()->window); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); - CTRL_EntityKind entity_kind = cmd_kind_info->query.ctrl_entity_kind; +#endif + CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; // cmd_kind_info->query.ctrl_entity_kind; F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); @@ -5779,6 +5781,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) } //- rjf: if file is ready, move params tree to scratch for new command +#if 0 // TODO(rjf): @cfg MD_Node *params_copy = &md_nil_node; if(file_is_ready) { @@ -5793,6 +5796,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) RD_View *view = rd_view_from_handle(rd_regs()->view); rd_view_equip_spec(view, view_rule_info, query, params_copy); } +#endif //- rjf: if entity is ready, but we have no viewer for it, then just close this tab if(file_is_ready && viewer_kind == RD_ViewRuleKind_Null) @@ -5870,18 +5874,20 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) rd_regs()->file_path = path; rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; +#if 0 // TODO(rjf): @cfg rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; +#endif if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 range = rd_range_from_eval_params(eval, params); + Rng1U64 range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval_params(eval, params); + rd_regs()->lang_kind = TXT_LangKind_Null; // TODO(rjf): @cfg rd_lang_kind_from_eval_params(eval, params); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); @@ -6151,8 +6157,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = rd_range_from_eval_params(eval, params); - Arch arch = rd_arch_from_eval_params(eval, params); + Rng1U64 range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); + Arch arch = Arch_Null; // TODO(rjf): @cfg rd_arch_from_eval_params(eval, params); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; DI_Key dbgi_key = {0}; @@ -6301,10 +6307,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(output) // rd_regs()->file_path = str8_zero(); rd_regs()->vaddr = 0; +#if 0 // TODO(rjf): @cfg rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; +#endif ////////////////////////////// //- rjf: unpack text info @@ -6400,7 +6408,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) //- rjf: unpack parameterization info // E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 space_range = rd_range_from_eval_params(eval, params); + Rng1U64 space_range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -6410,10 +6418,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) space_range = r1u64(0, 0x7FFFFFFFFFFFull); } } - U64 cursor = rd_value_from_params_key(params, str8_lit("cursor_vaddr")).u64; - U64 mark = rd_value_from_params_key(params, str8_lit("mark_vaddr")).u64; - U64 bytes_per_cell = rd_value_from_params_key(params, str8_lit("bytes_per_cell")).u64; - U64 num_columns = rd_value_from_params_key(params, str8_lit("num_columns")).u64; + U64 cursor = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("cursor_vaddr")).u64; + U64 mark = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("mark_vaddr")).u64; + U64 bytes_per_cell = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("bytes_per_cell")).u64; + U64 num_columns = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("num_columns")).u64; if(num_columns == 0) { num_columns = 16; @@ -7326,8 +7334,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) //- rjf: evaluate expression // E_Eval eval = e_eval_from_string(scratch.arena, string); - Vec2S32 dim = rd_dim2s32_from_eval_params(eval, params); - R_Tex2DFormat fmt = rd_tex2dformat_from_eval_params(eval, params); + Vec2S32 dim = {0}; // TODO(rjf): @cfg rd_dim2s32_from_eval_params(eval, params); + R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; // TODO(rjf): @cfg rd_tex2dformat_from_eval_params(eval, params); U64 base_offset = rd_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -7335,11 +7343,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: unpack params // - F32 zoom = rd_value_from_params_key(params, str8_lit("zoom")).f32; + F32 zoom = 1.f; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("zoom")).f32; Vec2F32 view_center_pos = { - rd_value_from_params_key(params, str8_lit("x")).f32, - rd_value_from_params_key(params, str8_lit("y")).f32, + 0.f, // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("x")).f32, + 0.f, // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("y")).f32, }; if(zoom == 0) { @@ -7570,7 +7578,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) Vec2F32 dim = dim_2f32(rect); F32 padding = ui_top_font_size()*3.f; E_Eval eval = e_eval_from_string(scratch.arena, string); - Vec4F32 rgba = rd_rgba_from_eval_params(eval, params); + Vec4F32 rgba = {0}; // TODO(rjf): @cfg rd_rgba_from_eval_params(eval, params); Vec4F32 hsva = hsva_from_rgba(rgba); //- rjf: too small -> just show components @@ -7734,12 +7742,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_value_from_params_key(params, str8_lit("count")).u64; - U64 vtx_base_off = rd_value_from_params_key(params, str8_lit("vtx")).u64; - U64 vtx_size = rd_value_from_params_key(params, str8_lit("vtx_size")).u64; - F32 yaw_target = rd_value_from_params_key(params, str8_lit("yaw")).f32; - F32 pitch_target = rd_value_from_params_key(params, str8_lit("pitch")).f32; - F32 zoom_target = rd_value_from_params_key(params, str8_lit("zoom")).f32; + U64 count = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("count")).u64; + U64 vtx_base_off = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("vtx")).u64; + U64 vtx_size = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("vtx_size")).u64; + F32 yaw_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("yaw")).f32; + F32 pitch_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("pitch")).f32; + F32 zoom_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("zoom")).f32; ////////////////////////////// //- rjf: evaluate & unpack expression @@ -8056,7 +8064,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) Temp scratch = scratch_begin(0, 0); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); String8 query = string; - RD_Window *window = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); ////////////////////////////// @@ -8520,7 +8528,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { rgba = rd_rgba_from_theme_color(item->color); }break; - case RD_SettingsItemKind_WindowSetting: {val_table = &window->setting_vals[0];}goto setting; + case RD_SettingsItemKind_WindowSetting: + { + // TODO(rjf): @cfg val_table = &window->setting_vals[0]; + }goto setting; case RD_SettingsItemKind_GlobalSetting:{}goto setting; setting:; { From 8bb3e6c1911db4fcc973806b6a953ad5355b5f49 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 Jan 2025 10:06:47 -0800 Subject: [PATCH 004/755] rdi_from_pdb: fix line emitting rules in inline site symbol parsing; also fix non-application of code lengths to code offsets in inline lines --- src/rdi_from_pdb/rdi_from_pdb.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 268e50ab..d1e19ae1 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -794,11 +794,9 @@ ASYNC_WORK_DEF(p2r_units_convert_work) CV_InlineRangeKind range_kind = 0; U32 code_length = 0; U32 code_offset = 0; - U32 last_code_offset = code_offset; String8 file_name = inlinee_lines_parsed->file_name; - String8 last_file_name = file_name; + String8 last_file_name = {0}; S32 line = (S32)inlinee_lines_parsed->first_source_ln; - S32 last_line = line; S32 column = 1; S32 last_column = column; @@ -821,6 +819,9 @@ ASYNC_WORK_DEF(p2r_units_convert_work) CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; // rjf: decode loop + B32 line_num_emitted = 0; + B32 code_off_emitted = 0; + B32 code_len_emitted = 0; U64 read_off = 0; U64 read_off_opl = binary_annots.size; for(B32 good = 1; read_off < read_off_opl && good;) @@ -840,6 +841,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) case CV_InlineBinaryAnnotation_CodeOffset: { read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_offset); + code_off_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: { @@ -857,11 +859,13 @@ ASYNC_WORK_DEF(p2r_units_convert_work) U32 delta = 0; read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &delta); code_offset += delta; + code_off_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeCodeLength: { code_length = 0; read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length); + code_len_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeFile: { @@ -881,6 +885,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) S32 delta = 0; read_off += cv_decode_inline_annot_s32(binary_annots, read_off, &delta); line += delta; + line_num_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeLineEndDelta: { @@ -923,6 +928,8 @@ ASYNC_WORK_DEF(p2r_units_convert_work) S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4); code_offset += code_delta; line += line_delta; + code_off_emitted = 1; + line_num_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: { @@ -930,6 +937,8 @@ ASYNC_WORK_DEF(p2r_units_convert_work) read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length); read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &offset_delta); code_offset += offset_delta; + code_len_emitted = 1; + code_off_emitted = 1; }break; case CV_InlineBinaryAnnotation_ChangeColumnEnd: { @@ -941,7 +950,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } // rjf: gather new lines - if(!good || line != last_line || code_offset != last_code_offset) + if(!good || (line_num_emitted && code_off_emitted && code_len_emitted)) { LineChunk *chunk = last_line_chunk; if(chunk == 0 || chunk->count+1 >= chunk->cap) @@ -957,6 +966,15 @@ ASYNC_WORK_DEF(p2r_units_convert_work) chunk->line_nums[chunk->count] = (U32)line; chunk->count += 1; total_line_chunk_line_count += 1; + line_num_emitted = 0; + code_off_emitted = 0; + code_len_emitted = 0; + } + + // rjf: advance code offset by the code length + { + code_offset += code_length; + code_length = 0; } // rjf: push line sequence to line table & source file @@ -1029,12 +1047,6 @@ ASYNC_WORK_DEF(p2r_units_convert_work) first_line_chunk = last_line_chunk = 0; total_line_chunk_line_count = 0; } - - // rjf: update prev/current states - last_file_name = file_name; - last_line = line; - last_column = column; - last_code_offset = code_offset; } } }break; From e9a10bbbd267fe51c57815bfaccca3194067dfa9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 Jan 2025 11:12:59 -0800 Subject: [PATCH 005/755] part 4: fix panel/tab ui key stability for new cfg-based panels/tabs; eliminate query views & begin pluggin in autocompletion lister to query input --- src/raddbg/raddbg_core.c | 176 ++++++++++++++++++++------------------- src/raddbg/raddbg_core.h | 9 +- 2 files changed, 99 insertions(+), 86 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d1b30a00..989aff3f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -971,6 +971,10 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) { // NOTE(rjf): skip - this is a panel. } + else if(str8_match(src_child->string, str8_lit("tabs_on_bottom"), 0)) + { + // NOTE(rjf): skip - this is a panel option. + } else if(str8_match(src_child->string, str8_lit("selected"), 0)) { dst_focused = dst; @@ -3083,7 +3087,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->hover_eval_arena = arena_alloc(); ws->autocomp_lister_params_arena = arena_alloc(); ws->query_cmd_arena = arena_alloc(); - ws->query_view_stack_top = &rd_nil_cfg; ws->last_dpi = os_dpi_from_window(ws->os); for EachEnumVal(RD_SettingCode, code) { @@ -3163,7 +3166,7 @@ rd_window_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc; B32 popup_open = rd_state->popup_active; - B32 query_is_open = (ws->query_view_stack_top != &rd_nil_cfg); + B32 query_is_open = (ws->query_cmd_name.size != 0); B32 hover_eval_is_open = (!popup_open && ws->hover_eval_string.size != 0 && ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && @@ -5970,12 +5973,24 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: prepare query view stack for the in-progress command + //- rjf: prepare query state for the in-progress query command // if(ws->query_cmd_name.size != 0) { RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(ws->query_cmd_name); RD_RegSlot missing_slot = cmd_kind_info->query.slot; + + //- rjf: if our input is stale, w.r.t. the current query command, initialize input state + if(ws->query_input_gen < ws->query_cmd_gen) + { + ws->query_input_gen = ws->query_cmd_gen; + String8 default_query_input = {0}; + ws->query_input_string_size = Min(sizeof(ws->query_input_buffer), default_query_input.size); + MemoryCopy(ws->query_input_buffer, default_query_input.str, ws->query_input_string_size); + ws->query_input_cursor = ws->query_input_mark = txt_pt(1, ws->query_input_string_size+1); + } + +#if 0 // TODO(rjf): @cfg (query state prep) String8 query_view_name = cmd_kind_info->query.view_name; if(query_view_name.size == 0) { @@ -6034,18 +6049,16 @@ rd_window_frame(void) scratch_end(scratch); } +#endif } //////////////////////////// //- rjf: build query // - if(ws->query_view_stack_top != &rd_nil_cfg) - UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_view_selected) ? UI_FocusKind_On : UI_FocusKind_Off) + if(query_is_open) + UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_input_selected) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Palette(RD_PaletteCode_Floating) { - RD_Cfg *view = ws->query_view_stack_top; - RD_ViewState *view_state = rd_view_state_from_cfg(view); - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); String8 query_cmd_name = ws->query_cmd_name; RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); RD_Query *query = &query_cmd_info->query; @@ -6053,26 +6066,16 @@ rd_window_frame(void) //- rjf: calculate rectangles Vec2F32 window_center = center_2f32(window_rect); - F32 query_container_width = dim_2f32(window_rect).x*0.5f; - F32 query_container_margin = ui_top_font_size()*8.f; - F32 query_line_edit_height = ui_top_font_size()*3.f; - Rng2F32 query_container_rect = r2f32p(window_center.x - query_container_width/2 + (1-query_view_t)*query_container_width/4, - window_rect.y0 + query_container_margin, - window_center.x + query_container_width/2 - (1-query_view_t)*query_container_width/4, - window_rect.y1 - query_container_margin); - if(view_rule_info == &rd_nil_view_rule_info) - { - query_container_rect.y1 = query_container_rect.y0 + query_line_edit_height; - } - query_container_rect.y1 = mix_1f32(query_container_rect.y0, query_container_rect.y1, query_view_t); - Rng2F32 query_container_content_rect = r2f32p(query_container_rect.x0, - query_container_rect.y0+query_line_edit_height, - query_container_rect.x1, - query_container_rect.y1); + Vec2F32 query_input_dim = v2f32(dim_2f32(window_rect).x*0.5f, ui_top_font_size()*3.f); + F32 query_input_margin = ui_top_font_size()*8.f; + Rng2F32 query_input_rect = r2f32p(window_center.x - query_input_dim.x/2 + (1-query_view_t)*query_input_dim.x/4, + window_rect.y0 + query_input_margin, + window_center.x + query_input_dim.x/2 - (1-query_view_t)*query_input_dim.x/4, + window_rect.y0 + query_input_margin + query_input_dim.y); - //- rjf: build floating query view container + //- rjf: build floating query container UI_Box *query_container_box = &ui_nil_box; - UI_Rect(query_container_rect) + UI_Rect(query_input_rect) UI_CornerRadius(ui_top_font_size()*0.2f) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.25f - query_view_t*0.25f) @@ -6087,14 +6090,21 @@ rd_window_frame(void) UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBackgroundBlur| UI_BoxFlag_DrawDropShadow, - "panel_query_container"); + "query_container"); } + //- rjf: set up autocompletion lister info + RD_AutoCompListerParams params = {0}; + { + params.flags = 0xffffffff; + } + rd_set_autocomp_lister_query(query_container_box->key, ¶ms, str8(ws->query_input_buffer, ws->query_input_string_size), ws->query_input_cursor.column-1); + //- rjf: build query text input B32 query_completed = 0; B32 query_cancelled = 0; UI_Parent(query_container_box) - UI_WidthFill UI_PrefHeight(ui_px(query_line_edit_height, 1.f)) + UI_WidthFill UI_HeightFill UI_Focus(UI_FocusKind_On) { ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); @@ -6116,17 +6126,17 @@ rd_window_frame(void) (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), 0, 0, - &view_state->filter_cursor, - &view_state->filter_mark, - view_state->filter_buffer, - sizeof(view_state->filter_buffer), - &view_state->filter_string_size, + &ws->query_input_cursor, + &ws->query_input_mark, + ws->query_input_buffer, + sizeof(ws->query_input_buffer), + &ws->query_input_string_size, 0, - str8(view_state->filter_buffer, view_state->filter_string_size), + str8(ws->query_input_buffer, ws->query_input_string_size), str8_lit("###query_text_input")); if(ui_pressed(sig)) { - ws->query_view_selected = 1; + ws->query_input_selected = 1; } } UI_PrefWidth(ui_em(5.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PositivePopButton) @@ -6146,17 +6156,8 @@ rd_window_frame(void) } } - //- rjf: build query view - UI_Parent(query_container_box) UI_WidthFill UI_Focus(UI_FocusKind_Null) - RD_RegsScope(.view = rd_handle_from_cfg(view)) - { - RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - String8 filter = str8(view_state->filter_buffer, view_state->filter_string_size); - view_ui(filter, query_container_content_rect); - } - //- rjf: query submission - if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_view_selected)) && + if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_input_selected)) && ui_slot_press(UI_EventActionSlot_Cancel)) || query_cancelled) { rd_cmd(RD_CmdKind_CancelQuery); @@ -6166,7 +6167,7 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); RD_RegsScope() { - rd_regs_fill_slot_from_string(query->slot, str8(view_state->filter_buffer, view_state->filter_string_size)); + rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); rd_cmd(RD_CmdKind_CompleteQuery); } scratch_end(scratch); @@ -6177,13 +6178,13 @@ rd_window_frame(void) UI_Signal sig = ui_signal_from_box(query_container_box); if(ui_pressed(sig)) { - ws->query_view_selected = 1; + ws->query_input_selected = 1; } } //- rjf: build darkening overlay for rest of screen - F32 query_view_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_view_selected", ws), (F32)!!ws->query_view_selected); - UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_view_selected_t))) + F32 query_input_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_input_selected", ws), (F32)!!ws->query_input_selected); + UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_input_selected_t))) UI_Rect(window_rect) { ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); @@ -6191,7 +6192,7 @@ rd_window_frame(void) } else { - ws->query_view_selected = 0; + ws->query_input_selected = 0; } //////////////////////////// @@ -6259,7 +6260,7 @@ rd_window_frame(void) //- rjf: build if good if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && (!query_is_open || !ws->query_view_selected)) ? UI_FocusKind_Null : UI_FocusKind_Off) + UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && (!query_is_open || !ws->query_input_selected)) ? UI_FocusKind_Null : UI_FocusKind_Off) { //- rjf: eval -> viz artifacts F32 row_height = floor_f32(ui_top_font_size()*2.8f); @@ -6775,7 +6776,7 @@ rd_window_frame(void) UI_Rect(boundary_rect) { ui_set_next_hover_cursor(split_axis == Axis2_X ? OS_Cursor_LeftRight : OS_Cursor_UpDown); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child, max_child); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%p_%p", min_child->cfg, max_child->cfg); UI_Signal sig = ui_signal_from_box(box); if(ui_double_clicked(sig)) { @@ -6783,6 +6784,8 @@ rd_window_frame(void) F32 sum_pct = min_child->pct_of_parent + max_child->pct_of_parent; min_child->pct_of_parent = 0.5f * sum_pct; max_child->pct_of_parent = 0.5f * sum_pct; + rd_cfg_equip_stringf(min_child->cfg, "%f", min_child->pct_of_parent); + rd_cfg_equip_stringf(max_child->cfg, "%f", max_child->pct_of_parent); } else if(ui_pressed(sig)) { @@ -6815,6 +6818,8 @@ rd_window_frame(void) } min_child->pct_of_parent = min_pct__after; max_child->pct_of_parent = max_pct__after; + rd_cfg_equip_stringf(min_child->cfg, "%f", min_pct__after); + rd_cfg_equip_stringf(max_child->cfg, "%f", max_pct__after); is_changing_panel_boundaries = 1; } } @@ -6870,7 +6875,7 @@ rd_window_frame(void) if(panel->first != &rd_nil_panel_node) {continue;} B32 panel_is_focused = (window_is_focused && !ws->menu_bar_focused && - (!query_is_open || !ws->query_view_selected) && + (!query_is_open || !ws->query_input_selected) && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused && panel_tree.focused == panel); @@ -6942,13 +6947,13 @@ rd_window_frame(void) sites[] = { { - ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel), + ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel->cfg), Dir2_Invalid, r2f32(sub_2f32(panel_center, drop_site_half_dim), add_2f32(panel_center, drop_site_half_dim)) }, { - ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel), + ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel->cfg), Dir2_Up, r2f32p(panel_center.x-drop_site_half_dim.x, panel_center.y-drop_site_half_dim.y - drop_site_half_dim.y*2, @@ -6956,7 +6961,7 @@ rd_window_frame(void) panel_center.y+drop_site_half_dim.y - drop_site_half_dim.y*2), }, { - ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel), + ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel->cfg), Dir2_Down, r2f32p(panel_center.x-drop_site_half_dim.x, panel_center.y-drop_site_half_dim.y + drop_site_half_dim.y*2, @@ -6964,7 +6969,7 @@ rd_window_frame(void) panel_center.y+drop_site_half_dim.y + drop_site_half_dim.y*2), }, { - ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel), + ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel->cfg), Dir2_Left, r2f32p(panel_center.x-drop_site_half_dim.x - drop_site_half_dim.x*2, panel_center.y-drop_site_half_dim.y, @@ -6972,7 +6977,7 @@ rd_window_frame(void) panel_center.y+drop_site_half_dim.y), }, { - ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel), + ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel->cfg), Dir2_Right, r2f32p(panel_center.x-drop_site_half_dim.x + drop_site_half_dim.x*2, panel_center.y-drop_site_half_dim.y, @@ -7093,7 +7098,7 @@ rd_window_frame(void) { UI_Rect(panel_rect) { - UI_Key key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel); + UI_Key key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, key); ui_signal_from_box(catchall_drop_site); catchall_drop_site_hovered = ui_key_match(key, ui_drop_hot_key()); @@ -7322,7 +7327,7 @@ rd_window_frame(void) // rjf: build UI_CornerRadius(0) { - UI_Rect(tab_bar_rect) tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClampX|UI_BoxFlag_ViewScrollX|UI_BoxFlag_Clickable, "tab_bar_%p", panel); + UI_Rect(tab_bar_rect) tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClampX|UI_BoxFlag_ViewScrollX|UI_BoxFlag_Clickable, "tab_bar_%p", panel->cfg); if(panel->tab_side == Side_Max) { tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); @@ -7524,7 +7529,7 @@ rd_window_frame(void) UI_BoxFlag_DisableTextTrunc, "%S##add_new_tab_button_%p", rd_icon_kind_text_table[RD_IconKind_Add], - panel); + panel->cfg); UI_Signal sig = ui_signal_from_box(add_new_box); if(ui_clicked(sig)) { @@ -8861,7 +8866,7 @@ rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view } scratch_end(scratch); EV_ExpandInfo info = {accel, accel->entities.count}; - // TODO(rjf): hack + // TODO(rjf): @hack if(kind == CTRL_EntityKind_Machine) { info.rows_default_expanded = 1; @@ -11561,6 +11566,7 @@ rd_frame(void) arena_release(ext->arena); } arena_release(vs->arena); + DLLRemove_NP(rd_state->view_state_slots[slot_idx].first, rd_state->view_state_slots[slot_idx].last, vs, hash_next, hash_prev); SLLStackPush_N(rd_state->free_view_state, vs, hash_next); } } @@ -11706,7 +11712,7 @@ rd_frame(void) if(!take && event->kind == OS_EventKind_WindowClose && ws != 0) { take = 1; - rd_cmd(RD_CmdKind_CloseWindow, .window = ws->cfg_handle); + rd_cmd(RD_CmdKind_Exit); } //- rjf: try menu bar operations @@ -12231,11 +12237,12 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(wcfg); if(ws != 0) { + ws->query_cmd_gen += 1; arena_clear(ws->query_cmd_arena); ws->query_cmd_name = push_str8_copy(ws->query_cmd_arena, cmd->regs->cmd_name); ws->query_cmd_regs = rd_regs_copy(ws->query_cmd_arena, rd_regs()); MemoryZeroArray(ws->query_cmd_regs_mask); - ws->query_view_selected = 1; + ws->query_input_selected = 1; } } }break; @@ -13554,7 +13561,7 @@ rd_frame(void) RD_Cfg *window = rd_window_from_cfg(panel); RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; - ws->query_view_selected = 0; + ws->query_input_selected = 0; } }break; @@ -14145,11 +14152,11 @@ rd_frame(void) #define FixedTab_XList \ X(watch)\ X(locals)\ -X(regs)\ +X(registers)\ X(globals)\ -X(tlocals)\ +X(thread_locals)\ X(types)\ -X(procs)\ +X(procedures)\ X(call_stack)\ X(breakpoints)\ X(watch_pins)\ @@ -14244,17 +14251,22 @@ X(getting_started) RD_Cfg *root_0_0_0_1 = rd_cfg_new(root_0_0_0, str8_lit("0.50")); rd_cfg_insert_child(root_0_0_0_0, root_0_0_0_0->last, disasm); rd_cfg_new(disasm, str8_lit("selected")); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, breakpoints); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, watch_pins); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, output); + rd_cfg_insert_child(root_0_0_0_1, root_0_0_0_1->last, memory); + rd_cfg_new(output, str8_lit("selected")); // rjf: root_0_1 split RD_Cfg *root_0_1_0 = rd_cfg_new(root_0_1, str8_lit("0.60")); RD_Cfg *root_0_1_1 = rd_cfg_new(root_0_1, str8_lit("0.40")); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, watch); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, locals); - rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, regs); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, registers); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, globals); - rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, tlocals); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, thread_locals); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, types); - rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, procs); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, procedures); rd_cfg_new(watch, str8_lit("selected")); rd_cfg_new(root_0_1_0, str8_lit("tabs_on_bottom")); rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, call_stack); @@ -14331,6 +14343,11 @@ X(getting_started) }break; } + //- rjf: release any unused views from the previous layout +#define X(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} + FixedTab_XList +#undef X + #if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); @@ -15350,28 +15367,19 @@ X(getting_started) }break; case RD_CmdKind_CancelQuery: { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); arena_clear(ws->query_cmd_arena); MemoryZeroStruct(&ws->query_cmd_name); ws->query_cmd_regs = 0; - MemoryZeroArray(ws->query_cmd_regs_mask); - for(RD_View *v = ws->query_view_stack_top, *next = 0; !rd_view_is_nil(v); v = next) - { - next = v->order_next; - rd_view_release(v); - } - ws->query_view_stack_top = &rd_nil_view; -#endif }break; //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); ws->dev_menu_is_open ^= 1; -#endif }break; //- rjf: general entity operations diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 8817e572..8f16907f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -637,12 +637,17 @@ struct RD_WindowState S64 autocomp_cursor_num; // rjf: query view stack + U64 query_cmd_gen; Arena *query_cmd_arena; String8 query_cmd_name; RD_Regs *query_cmd_regs; U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; - RD_Cfg *query_view_stack_top; - B32 query_view_selected; + U64 query_input_gen; + B32 query_input_selected; + U8 query_input_buffer[1024]; + U64 query_input_string_size; + TxtPt query_input_cursor; + TxtPt query_input_mark; // rjf: hover eval state B32 hover_eval_focused; From 1b52100361d75d3f93cd29df36c8722cce77b93e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 13 Jan 2025 14:18:34 -0800 Subject: [PATCH 006/755] part 5: begin shifting autocompletion lister box to being unified lister/ctx-menu replacement --- src/raddbg/raddbg_core.c | 1734 ++++++++++++++++++----------------- src/raddbg/raddbg_core.h | 109 +-- src/raddbg/raddbg_views.c | 38 +- src/raddbg/raddbg_widgets.c | 4 +- 4 files changed, 964 insertions(+), 921 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 989aff3f..b2fa13d4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3085,7 +3085,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); - ws->autocomp_lister_params_arena = arena_alloc(); + ws->lister_params_arena = arena_alloc(); ws->query_cmd_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); for EachEnumVal(RD_SettingCode, code) @@ -3306,7 +3306,7 @@ rd_window_frame(void) ////////////////////////////// //- rjf: build UI // - UI_Box *autocomp_box = &ui_nil_box; + UI_Box *lister_box = &ui_nil_box; UI_Box *hover_eval_box = &ui_nil_box; ProfScope("build UI") { @@ -3774,6 +3774,806 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: prepare query state for the in-progress query command + // + if(ws->query_cmd_name.size != 0) + { + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(ws->query_cmd_name); + RD_RegSlot missing_slot = cmd_kind_info->query.slot; + + //- rjf: if our input is stale, w.r.t. the current query command, initialize input state + if(ws->query_input_gen < ws->query_cmd_gen) + { + ws->query_input_gen = ws->query_cmd_gen; + String8 default_query_input = {0}; + ws->query_input_string_size = Min(sizeof(ws->query_input_buffer), default_query_input.size); + MemoryCopy(ws->query_input_buffer, default_query_input.str, ws->query_input_string_size); + ws->query_input_cursor = ws->query_input_mark = txt_pt(1, ws->query_input_string_size+1); + } + +#if 0 // TODO(rjf): @cfg (query state prep) + String8 query_view_name = cmd_kind_info->query.view_name; + if(query_view_name.size == 0) + { + switch(missing_slot) + { + default:{}break; + case RD_RegSlot_Thread: + case RD_RegSlot_Module: + case RD_RegSlot_Process: + case RD_RegSlot_Machine: + case RD_RegSlot_CtrlEntity:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_CtrlEntityLister].string;}break; + case RD_RegSlot_Entity: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; + case RD_RegSlot_EntityList:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; + case RD_RegSlot_FilePath: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_FileSystem].string;}break; + case RD_RegSlot_PID: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_SystemProcesses].string;}break; + } + } + RD_ViewRuleInfo *view_spec = rd_view_rule_info_from_string(query_view_name); + if(!str8_match(ws->query_view_stack_top->string, view_spec->string, 0) || + ws->query_view_stack_top == &rd_nil_cfg) + { + Temp scratch = scratch_begin(0, 0); + + // rjf: clear existing query stack + rd_cfg_release(ws->query_view_stack_top); + + // rjf: determine default query + String8 default_query = {0}; + switch(missing_slot) + { + default: + if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + { + default_query = rd_push_search_string(scratch.arena); + }break; + case RD_RegSlot_FilePath: + { + default_query = path_normalized_from_string(scratch.arena, rd_state->current_path); + default_query = push_str8f(scratch.arena, "%S/", default_query); + }break; + } + + // rjf: construct & push new view + RD_Cfg *bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *view = rd_cfg_new(bucket, view_spec->string); + RD_Cfg *filter = rd_cfg_new(view, str8_lit("filter")); + rd_cfg_new(filter, default_query); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + view_state->filter_cursor = txt_pt(1, default_query.size+1); + if(cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + view_state->filter_mark = txt_pt(1, 1); + } + ws->query_view_stack_top = view; + ws->query_view_selected = 1; + + scratch_end(scratch); + } +#endif + } + + //////////////////////////// + //- rjf: build query + // + if(query_is_open) + UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_input_selected) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Palette(RD_PaletteCode_Floating) + { + String8 query_cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); + RD_Query *query = &query_cmd_info->query; + F32 query_view_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###%p_query_view_t", ws), 1.f); + F32 query_squish = 0.25f - query_view_t*0.25f; + F32 query_transparency = 1.f - query_view_t; + + //- rjf: calculate rectangles + Vec2F32 window_center = center_2f32(window_rect); + Vec2F32 query_input_dim = v2f32(dim_2f32(window_rect).x*0.5f, ui_top_font_size()*3.f); + F32 query_input_margin = ui_top_font_size()*8.f; + Rng2F32 query_input_rect = r2f32p(window_center.x - query_input_dim.x/2, + window_rect.y0 + query_input_margin, + window_center.x + query_input_dim.x/2, + window_rect.y0 + query_input_margin + query_input_dim.y); + + //- rjf: build floating query container + UI_Box *query_container_box = &ui_nil_box; + UI_Rect(query_input_rect) + UI_CornerRadius00(ui_top_font_size()*0.2f) + UI_CornerRadius10(ui_top_font_size()*0.2f) + UI_ChildLayoutAxis(Axis2_Y) + UI_Squish(query_squish) + UI_Transparency(query_transparency) + { + query_container_box = ui_build_box_from_stringf(UI_BoxFlag_Floating| + UI_BoxFlag_AllowOverflow| + UI_BoxFlag_Clickable| + UI_BoxFlag_Clip| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow, + "query_container"); + } + + //- rjf: set up autocompletion lister info + if(ui_is_focus_active()) + { + rd_set_lister_query(.anchor_key = query_container_box->key, + .anchor_off = v2f32(0, dim_2f32(query_container_box->rect).y - dim_2f32(query_container_box->rect).y*(1-query_view_t)*0.25f - 2.f), + .flags = 0xffffffff, + .input = str8(ws->query_input_buffer, ws->query_input_string_size), + .cursor_off = ws->query_input_cursor.column-1, + .squish = query_squish, + .transparency= query_transparency); + } + + //- rjf: build query text input + B32 query_completed = 0; + B32 query_cancelled = 0; + UI_Parent(query_container_box) + UI_WidthFill UI_HeightFill + UI_Focus(UI_FocusKind_On) + { + ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); + UI_Row + { + UI_PrefWidth(ui_text_dim(0.f, 1.f)) UI_Padding(ui_em(1.f, 1.f)) + { + RD_IconKind icon_kind = query_cmd_info->icon_kind; + if(icon_kind != RD_IconKind_Null) + { + RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[icon_kind]); + } + ui_labelf("%S", query_cmd_info->display_name); + } + RD_Font((query->flags & RD_QueryFlag_CodeInput) ? RD_FontSlot_Code : RD_FontSlot_Main) + UI_TextPadding(ui_top_font_size()*0.5f) + { + UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border| + (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), + 0, + 0, + &ws->query_input_cursor, + &ws->query_input_mark, + ws->query_input_buffer, + sizeof(ws->query_input_buffer), + &ws->query_input_string_size, + 0, + str8(ws->query_input_buffer, ws->query_input_string_size), + str8_lit("###query_text_input")); + if(ui_pressed(sig)) + { + ws->query_input_selected = 1; + } + } + UI_PrefWidth(ui_em(5.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PositivePopButton) + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "##complete_query"))) + { + query_completed = 1; + } + } + UI_PrefWidth(ui_em(3.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PlainButton) + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "##cancel_query"))) + { + query_cancelled = 1; + } + } + } + } + + //- rjf: query submission + if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_input_selected)) && + ui_slot_press(UI_EventActionSlot_Cancel)) || query_cancelled) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + if((ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) || query_completed) + { + Temp scratch = scratch_begin(0, 0); + RD_RegsScope() + { + rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); + rd_cmd(RD_CmdKind_CompleteQuery); + } + scratch_end(scratch); + } + + //- rjf: take fallthrough interaction in query view + { + UI_Signal sig = ui_signal_from_box(query_container_box); + if(ui_pressed(sig)) + { + ws->query_input_selected = 1; + } + } + } + else + { + ws->query_input_selected = 0; + } + + //////////////////////////// + //- rjf: build lister + // + ProfScope("build lister") + if(!ui_key_match(ws->lister_params.anchor_key, ui_key_zero()) && ws->lister_last_frame_idx+1 >= rd_state->frame_index) + { + String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); + String8 query_word = rd_lister_query_word_from_input_string_off(input, ws->lister_params.cursor_off); + String8 query_path = rd_lister_query_path_from_input_string_off(input, ws->lister_params.cursor_off); + UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); + if(!ui_box_is_nil(lister_root_box)) + { + Temp scratch = scratch_begin(0, 0); + DI_Scope *di_scope = di_scope_open(); + 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); + + //- rjf: grab rdis + 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) + { + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); + RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); + rdis[idx] = rdi; + } + } + + //- rjf: unpack lister params + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + + //- rjf: gather lister items + RD_ListerItemChunkList item_list = {0}; + { + //- rjf: gather locals + if(ws->lister_params.flags & RD_ListerFlag_Locals) + { + E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + { + RD_ListerItem item = {0}; + { + item.string = n->string; + item.kind_string = str8_lit("Local"); + item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) + { + RD_ListerItem item = {0}; + { + item.string = n->string; + item.kind_string = str8_lit("Local (Member)"); + item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather registers + if(ws->lister_params.flags & RD_ListerFlag_Registers) + { + Arch arch = thread->arch; + U64 reg_names_count = regs_reg_code_count_from_arch(arch); + U64 alias_names_count = regs_alias_code_count_from_arch(arch); + String8 *reg_names = regs_reg_code_string_table_from_arch(arch); + String8 *alias_names = regs_alias_code_string_table_from_arch(arch); + for(U64 idx = 0; idx < reg_names_count; idx += 1) + { + if(reg_names[idx].size != 0) + { + RD_ListerItem item = {0}; + { + item.string = reg_names[idx]; + item.kind_string = str8_lit("Register"); + item.matches = fuzzy_match_find(scratch.arena, query_word, reg_names[idx]); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + for(U64 idx = 0; idx < alias_names_count; idx += 1) + { + if(alias_names[idx].size != 0) + { + RD_ListerItem item = {0}; + { + item.string = alias_names[idx]; + item.kind_string = str8_lit("Reg. Alias"); + item.matches = fuzzy_match_find(scratch.arena, query_word, alias_names[idx]); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + } + + //- rjf: gather view rules + if(ws->lister_params.flags & RD_ListerFlag_ViewRules) + { + for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) + { + for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) + { + RD_ListerItem item = {0}; + { + item.string = spec->info.string; + item.kind_string = str8_lit("View Rule"); + item.matches = fuzzy_match_find(scratch.arena, query_word, spec->info.string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + } + + //- rjf: gather members + if(ws->lister_params.flags & RD_ListerFlag_Members) + { + // TODO(rjf) + } + + //- rjf: gather globals + if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_GlobalVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + + // rjf: push item + RD_ListerItem item = {0}; + { + item.string = name; + item.kind_string = str8_lit("Global"); + item.matches = items.v[idx].match_ranges; + item.group = 1; + } + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + + //- rjf: gather thread locals + if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_ThreadVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + + // rjf: push item + RD_ListerItem item = {0}; + { + item.string = name; + item.kind_string = str8_lit("Thread Local"); + item.matches = items.v[idx].match_ranges; + item.group = 1; + } + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + + //- rjf: gather procedures + if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_Procedures, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + + // rjf: push item + RD_ListerItem item = {0}; + { + item.string = name; + item.kind_string = str8_lit("Procedure"); + item.matches = items.v[idx].match_ranges; + item.group = 1; + } + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + + //- rjf: gather types + if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_UDTs, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + + // rjf: push item + RD_ListerItem item = {0}; + { + item.string = name; + item.kind_string = str8_lit("Type"); + item.matches = items.v[idx].match_ranges; + item.group = 1; + } + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + + //- rjf: gather languages + if(ws->lister_params.flags & RD_ListerFlag_Languages) + { + for EachNonZeroEnumVal(TXT_LangKind, lang) + { + RD_ListerItem item = {0}; + { + item.string = txt_extension_from_lang_kind(lang); + item.kind_string = str8_lit("Language"); + item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); + } + if(item.string.size != 0 && (query_word.size == 0 || item.matches.count != 0)) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather architectures + if(ws->lister_params.flags & RD_ListerFlag_Architectures) + { + for EachNonZeroEnumVal(Arch, arch) + { + RD_ListerItem item = {0}; + { + item.string = string_from_arch(arch); + item.kind_string = str8_lit("Arch"); + item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather tex2dformats + if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) + { + for EachEnumVal(R_Tex2DFormat, fmt) + { + RD_ListerItem item = {0}; + { + item.string = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + item.kind_string = str8_lit("Format"); + item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather view rule params + if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) + { + for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) + { + String8 string = n->string; + RD_ListerItem item = {0}; + { + item.string = string; + item.kind_string = str8_lit("Parameter"); + item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); + } + if(query_word.size == 0 || item.matches.count != 0) + { + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + } + + //- rjf: gather files + if(ws->lister_params.flags & RD_ListerFlag_Files) + { + // rjf: find containing directory in query_path + String8 dir_str_in_input = {0}; + for(U64 i = 0; i < query_path.size; i += 1) + { + String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); + String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); + String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); + if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); + } + else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + if(dir_str_in_input.size != 0) + { + break; + } + } + + // rjf: use query_path string to form various parts of search space + String8 prefix = {0}; + String8 path = {0}; + String8 search = {0}; + if(dir_str_in_input.size != 0) + { + String8 dir = dir_str_in_input; + U64 one_past_last_slash = dir.size; + for(U64 i = 0; i < dir_str_in_input.size; i += 1) + { + if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') + { + one_past_last_slash = i+1; + } + } + dir.size = one_past_last_slash; + path = dir; + search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); + prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); + } + + // rjf: get current files, filtered + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); + B32 fits_search = (search.size == 0 || match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + RD_ListerItem item = {0}; + { + item.string = info.props.flags & FilePropertyFlag_IsFolder ? push_str8f(scratch.arena, "%S/", info.name) : info.name; + item.kind_string = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"); + item.matches = match_ranges; + item.is_non_code = 1; + } + rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); + } + } + os_file_iter_end(it); + } + } + + //- rjf: lister item list -> sorted array + RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); + rd_lister_item_array_sort__in_place(&item_array); + + //- rjf: animate + { + // rjf: animate target # of rows + { + F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + F32 target = Min((F32)item_array.count, 16.f); + if(abs_f32(target - ws->lister_num_visible_rows_t) > 0.01f) + { + rd_request_frame(); + } + ws->lister_num_visible_rows_t += (target - ws->lister_num_visible_rows_t) * rate; + if(abs_f32(target - ws->lister_num_visible_rows_t) <= 0.02f) + { + ws->lister_num_visible_rows_t = target; + } + } + + // rjf: animate open + { + F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; + F32 diff = 1.f-ws->lister_open_t; + ws->lister_open_t += diff*rate; + if(abs_f32(diff) < 0.05f) + { + ws->lister_open_t = 1.f; + } + else + { + rd_request_frame(); + } + } + } + + //- rjf: build + if(item_array.count != 0) + { + F32 squish = ws->lister_params.squish; + F32 transparency = ws->lister_params.transparency; + if(squish == 0.f) + { + squish = 0.25f - 0.25f*ws->lister_open_t; + } + if(transparency == 0.f) + { + transparency = 1.f-ws->lister_open_t; + } + F32 width_px = ui_box_is_nil(lister_root_box) ? (ui_top_font_size()*30.f) : dim_2f32(lister_root_box->rect).x; + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + ui_set_next_fixed_x(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x); + ui_set_next_fixed_y(lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); + ui_set_next_pref_width(ui_px(width_px, 1.f)); + ui_set_next_pref_height(ui_px(row_height_px*ws->lister_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); + ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); + UI_Focus(UI_FocusKind_On) + UI_Squish(squish) + UI_Transparency(transparency) + RD_Palette(RD_PaletteCode_Floating) + { + lister_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| + UI_BoxFlag_Clickable| + UI_BoxFlag_Clip| + UI_BoxFlag_RoundChildrenByParent| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackground, + "lister_box"); + if(ws->lister_input_dirty) + { + ws->lister_input_dirty = 0; + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); + } + } + UI_Parent(lister_box) + UI_WidthFill + UI_PrefHeight(ui_px(row_height_px, 1.f)) + RD_Font(RD_FontSlot_Code) + UI_HoverCursor(OS_Cursor_HandPoint) + UI_Focus(UI_FocusKind_Null) + RD_Palette(RD_PaletteCode_ImplicitButton) + UI_Padding(ui_em(1.f, 1.f)) + { + for(U64 idx = 0; idx < item_array.count; idx += 1) + { + RD_ListerItem *item = &item_array.v[idx]; + UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); + UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) + { + UI_WidthFill RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + UI_Box *box = item->is_non_code ? ui_label(item->string).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->string); + ui_box_equip_fuzzy_match_ranges(box, &item->matches); + } + RD_Font(RD_FontSlot_Main) + UI_PrefWidth(ui_text_dim(10, 1)) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + ui_label(item->kind_string); + } + UI_Signal item_sig = ui_signal_from_box(item_box); + if(ui_clicked(item_sig)) + { + UI_Event move_back_evt = zero_struct; + move_back_evt.kind = UI_EventKind_Navigate; + move_back_evt.flags = UI_EventFlag_KeepMark; + move_back_evt.delta_2s32.x = -(S32)query_word.size; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); + UI_Event paste_evt = zero_struct; + paste_evt.kind = UI_EventKind_Text; + paste_evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); + } + else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); + } + } + } + } + + di_scope_close(di_scope); + scratch_end(scratch); + } + } + + //////////////////////////// + //- rjf: darken lower layer ui when query is selected + // + F32 query_input_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_input_selected", ws), (F32)!!ws->query_input_selected); + UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_input_selected_t))) + UI_Rect(window_rect) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + //////////////////////////// //- rjf: top-level registers context menu // @@ -4528,563 +5328,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: build auto-complete lister - // - ProfScope("build autocomplete lister") - if(!ui_key_match(ws->autocomp_root_key, ui_key_zero()) && ws->autocomp_last_frame_idx+1 >= rd_state->frame_index) - { - String8 input = str8(ws->autocomp_lister_input_buffer, ws->autocomp_lister_input_size); - String8 query_word = rd_autocomp_query_word_from_input_string_off(input, ws->autocomp_cursor_off); - String8 query_path = rd_autocomp_query_path_from_input_string_off(input, ws->autocomp_cursor_off); - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) - { - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - 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); - - //- rjf: grab rdis - 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) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: unpack lister params - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - - //- rjf: gather lister items - RD_AutoCompListerItemChunkList item_list = {0}; - { - //- rjf: gather locals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Locals) - { - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) - { - RD_AutoCompListerItem item = {0}; - { - item.string = n->string; - item.kind_string = str8_lit("Local"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - RD_AutoCompListerItem item = {0}; - { - item.string = n->string; - item.kind_string = str8_lit("Local (Member)"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather registers - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Registers) - { - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - RD_AutoCompListerItem item = {0}; - { - item.string = reg_names[idx]; - item.kind_string = str8_lit("Register"); - item.matches = fuzzy_match_find(scratch.arena, query_word, reg_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - RD_AutoCompListerItem item = {0}; - { - item.string = alias_names[idx]; - item.kind_string = str8_lit("Reg. Alias"); - item.matches = fuzzy_match_find(scratch.arena, query_word, alias_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather view rules - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - RD_AutoCompListerItem item = {0}; - { - item.string = spec->info.string; - item.kind_string = str8_lit("View Rule"); - item.matches = fuzzy_match_find(scratch.arena, query_word, spec->info.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather members - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Members) - { - // TODO(rjf) - } - - //- rjf: gather globals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Globals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Global"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather thread locals - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ThreadLocals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Thread Local"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather procedures - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Procedures && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Procedure"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather types - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Types && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_AutoCompListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Type"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather languages - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - RD_AutoCompListerItem item = {0}; - { - item.string = txt_extension_from_lang_kind(lang); - item.kind_string = str8_lit("Language"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(item.string.size != 0 && (query_word.size == 0 || item.matches.count != 0)) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather architectures - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - RD_AutoCompListerItem item = {0}; - { - item.string = string_from_arch(arch); - item.kind_string = str8_lit("Arch"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather tex2dformats - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Tex2DFormats) - { - for EachEnumVal(R_Tex2DFormat, fmt) - { - RD_AutoCompListerItem item = {0}; - { - item.string = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); - item.kind_string = str8_lit("Format"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather view rule params - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ViewRuleParams) - { - for(String8Node *n = ws->autocomp_lister_params.strings.first; n != 0; n = n->next) - { - String8 string = n->string; - RD_AutoCompListerItem item = {0}; - { - item.string = string; - item.kind_string = str8_lit("Parameter"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather files - if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Files) - { - // rjf: find containing directory in query_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < query_path.size; i += 1) - { - String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - // rjf: use query_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); - } - - // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); - B32 fits_search = (search.size == 0 || match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) - { - RD_AutoCompListerItem item = {0}; - { - item.string = info.props.flags & FilePropertyFlag_IsFolder ? push_str8f(scratch.arena, "%S/", info.name) : info.name; - item.kind_string = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"); - item.matches = match_ranges; - item.is_non_code = 1; - } - rd_autocomp_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - os_file_iter_end(it); - } - } - - //- rjf: lister item list -> sorted array - RD_AutoCompListerItemArray item_array = rd_autocomp_lister_item_array_from_chunk_list(scratch.arena, &item_list); - rd_autocomp_lister_item_array_sort__in_place(&item_array); - - //- rjf: animate - { - // rjf: animate target # of rows - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - F32 target = Min((F32)item_array.count, 16.f); - if(abs_f32(target - ws->autocomp_num_visible_rows_t) > 0.01f) - { - rd_request_frame(); - } - ws->autocomp_num_visible_rows_t += (target - ws->autocomp_num_visible_rows_t) * rate; - if(abs_f32(target - ws->autocomp_num_visible_rows_t) <= 0.02f) - { - ws->autocomp_num_visible_rows_t = target; - } - } - - // rjf: animate open - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - F32 diff = 1.f-ws->autocomp_open_t; - ws->autocomp_open_t += diff*rate; - if(abs_f32(diff) < 0.05f) - { - ws->autocomp_open_t = 1.f; - } - else - { - rd_request_frame(); - } - } - } - - //- rjf: build - if(item_array.count != 0) - { - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - ui_set_next_fixed_x(autocomp_root_box->rect.x0); - ui_set_next_fixed_y(autocomp_root_box->rect.y1); - ui_set_next_pref_width(ui_em(30.f, 1.f)); - ui_set_next_pref_height(ui_px(row_height_px*ws->autocomp_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_10(ui_top_font_size()*0.25f); - UI_Focus(UI_FocusKind_On) - UI_Squish(0.25f-0.25f*ws->autocomp_open_t) - UI_Transparency(1.f-ws->autocomp_open_t) - RD_Palette(RD_PaletteCode_Floating) - { - autocomp_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - "autocomp_box"); - if(ws->autocomp_input_dirty) - { - ws->autocomp_input_dirty = 0; - autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); - } - } - UI_Parent(autocomp_box) - UI_WidthFill - UI_PrefHeight(ui_px(row_height_px, 1.f)) - RD_Font(RD_FontSlot_Code) - UI_HoverCursor(OS_Cursor_HandPoint) - UI_Focus(UI_FocusKind_Null) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_Padding(ui_em(1.f, 1.f)) - { - for(U64 idx = 0; idx < item_array.count; idx += 1) - { - RD_AutoCompListerItem *item = &item_array.v[idx]; - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) - { - UI_WidthFill RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - UI_Box *box = item->is_non_code ? ui_label(item->string).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->string); - ui_box_equip_fuzzy_match_ranges(box, &item->matches); - } - RD_Font(RD_FontSlot_Main) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(item->kind_string); - } - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - autocomp_box->default_nav_focus_hot_key = autocomp_box->default_nav_focus_active_key = autocomp_box->default_nav_focus_next_hot_key = autocomp_box->default_nav_focus_next_active_key = ui_key_zero(); - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } - } - } - } - - di_scope_close(di_scope); - scratch_end(scratch); - } - } - //////////////////////////// //- rjf: top bar // @@ -5850,7 +6093,15 @@ rd_window_frame(void) } if(ui_clicked(cls_sig)) { - ui_ctx_menu_open(close_ctx_menu_key, cls_sig.box->key, v2f32(0, dim_2f32(cls_sig.box->rect).y)); + if(ws->order_next != &rd_nil_window_state || + ws->order_prev != &rd_nil_window_state) + { + ui_ctx_menu_open(close_ctx_menu_key, cls_sig.box->key, v2f32(0, dim_2f32(cls_sig.box->rect).y)); + } + else + { + rd_cmd(RD_CmdKind_Exit); + } } os_window_push_custom_title_bar_client_area(ws->os, min_sig.box->rect); os_window_push_custom_title_bar_client_area(ws->os, max_sig.box->rect); @@ -5972,229 +6223,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: prepare query state for the in-progress query command - // - if(ws->query_cmd_name.size != 0) - { - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(ws->query_cmd_name); - RD_RegSlot missing_slot = cmd_kind_info->query.slot; - - //- rjf: if our input is stale, w.r.t. the current query command, initialize input state - if(ws->query_input_gen < ws->query_cmd_gen) - { - ws->query_input_gen = ws->query_cmd_gen; - String8 default_query_input = {0}; - ws->query_input_string_size = Min(sizeof(ws->query_input_buffer), default_query_input.size); - MemoryCopy(ws->query_input_buffer, default_query_input.str, ws->query_input_string_size); - ws->query_input_cursor = ws->query_input_mark = txt_pt(1, ws->query_input_string_size+1); - } - -#if 0 // TODO(rjf): @cfg (query state prep) - String8 query_view_name = cmd_kind_info->query.view_name; - if(query_view_name.size == 0) - { - switch(missing_slot) - { - default:{}break; - case RD_RegSlot_Thread: - case RD_RegSlot_Module: - case RD_RegSlot_Process: - case RD_RegSlot_Machine: - case RD_RegSlot_CtrlEntity:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_CtrlEntityLister].string;}break; - case RD_RegSlot_Entity: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_EntityList:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_FilePath: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_FileSystem].string;}break; - case RD_RegSlot_PID: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_SystemProcesses].string;}break; - } - } - RD_ViewRuleInfo *view_spec = rd_view_rule_info_from_string(query_view_name); - if(!str8_match(ws->query_view_stack_top->string, view_spec->string, 0) || - ws->query_view_stack_top == &rd_nil_cfg) - { - Temp scratch = scratch_begin(0, 0); - - // rjf: clear existing query stack - rd_cfg_release(ws->query_view_stack_top); - - // rjf: determine default query - String8 default_query = {0}; - switch(missing_slot) - { - default: - if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) - { - default_query = rd_push_search_string(scratch.arena); - }break; - case RD_RegSlot_FilePath: - { - default_query = path_normalized_from_string(scratch.arena, rd_state->current_path); - default_query = push_str8f(scratch.arena, "%S/", default_query); - }break; - } - - // rjf: construct & push new view - RD_Cfg *bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); - RD_Cfg *view = rd_cfg_new(bucket, view_spec->string); - RD_Cfg *filter = rd_cfg_new(view, str8_lit("filter")); - rd_cfg_new(filter, default_query); - RD_ViewState *view_state = rd_view_state_from_cfg(view); - view_state->filter_cursor = txt_pt(1, default_query.size+1); - if(cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) - { - view_state->filter_mark = txt_pt(1, 1); - } - ws->query_view_stack_top = view; - ws->query_view_selected = 1; - - scratch_end(scratch); - } -#endif - } - - //////////////////////////// - //- rjf: build query - // - if(query_is_open) - UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_input_selected) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Palette(RD_PaletteCode_Floating) - { - String8 query_cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); - RD_Query *query = &query_cmd_info->query; - F32 query_view_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###%p_query_view_t", ws), 1.f); - - //- rjf: calculate rectangles - Vec2F32 window_center = center_2f32(window_rect); - Vec2F32 query_input_dim = v2f32(dim_2f32(window_rect).x*0.5f, ui_top_font_size()*3.f); - F32 query_input_margin = ui_top_font_size()*8.f; - Rng2F32 query_input_rect = r2f32p(window_center.x - query_input_dim.x/2 + (1-query_view_t)*query_input_dim.x/4, - window_rect.y0 + query_input_margin, - window_center.x + query_input_dim.x/2 - (1-query_view_t)*query_input_dim.x/4, - window_rect.y0 + query_input_margin + query_input_dim.y); - - //- rjf: build floating query container - UI_Box *query_container_box = &ui_nil_box; - UI_Rect(query_input_rect) - UI_CornerRadius(ui_top_font_size()*0.2f) - UI_ChildLayoutAxis(Axis2_Y) - UI_Squish(0.25f - query_view_t*0.25f) - UI_Transparency(1-query_view_t) - { - query_container_box = ui_build_box_from_stringf(UI_BoxFlag_Floating| - UI_BoxFlag_AllowOverflow| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow, - "query_container"); - } - - //- rjf: set up autocompletion lister info - RD_AutoCompListerParams params = {0}; - { - params.flags = 0xffffffff; - } - rd_set_autocomp_lister_query(query_container_box->key, ¶ms, str8(ws->query_input_buffer, ws->query_input_string_size), ws->query_input_cursor.column-1); - - //- rjf: build query text input - B32 query_completed = 0; - B32 query_cancelled = 0; - UI_Parent(query_container_box) - UI_WidthFill UI_HeightFill - UI_Focus(UI_FocusKind_On) - { - ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); - UI_Row - { - UI_PrefWidth(ui_text_dim(0.f, 1.f)) UI_Padding(ui_em(1.f, 1.f)) - { - RD_IconKind icon_kind = query_cmd_info->icon_kind; - if(icon_kind != RD_IconKind_Null) - { - RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[icon_kind]); - } - ui_labelf("%S", query_cmd_info->display_name); - } - RD_Font((query->flags & RD_QueryFlag_CodeInput) ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border| - (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), - 0, - 0, - &ws->query_input_cursor, - &ws->query_input_mark, - ws->query_input_buffer, - sizeof(ws->query_input_buffer), - &ws->query_input_string_size, - 0, - str8(ws->query_input_buffer, ws->query_input_string_size), - str8_lit("###query_text_input")); - if(ui_pressed(sig)) - { - ws->query_input_selected = 1; - } - } - UI_PrefWidth(ui_em(5.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PositivePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "##complete_query"))) - { - query_completed = 1; - } - } - UI_PrefWidth(ui_em(3.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PlainButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "##cancel_query"))) - { - query_cancelled = 1; - } - } - } - } - - //- rjf: query submission - if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_input_selected)) && - ui_slot_press(UI_EventActionSlot_Cancel)) || query_cancelled) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - if((ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) || query_completed) - { - Temp scratch = scratch_begin(0, 0); - RD_RegsScope() - { - rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); - } - scratch_end(scratch); - } - - //- rjf: take fallthrough interaction in query view - { - UI_Signal sig = ui_signal_from_box(query_container_box); - if(ui_pressed(sig)) - { - ws->query_input_selected = 1; - } - } - - //- rjf: build darkening overlay for rest of screen - F32 query_input_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_input_selected", ws), (F32)!!ws->query_input_selected); - UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_input_selected_t))) - UI_Rect(window_rect) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - else - { - ws->query_input_selected = 0; - } - //////////////////////////// //- rjf: build hover eval // @@ -7844,35 +7872,36 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: attach autocomp box to root, or hide if it has not been renewed + //- rjf: attach lister box to root, or hide if it has not been renewed // - if(!ui_box_is_nil(autocomp_box) && ws->autocomp_last_frame_idx+1 >= rd_state->frame_index+1) + if(!ui_box_is_nil(lister_box) && ws->lister_last_frame_idx+1 >= rd_state->frame_index+1) { - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) + UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); + if(!ui_box_is_nil(lister_root_box)) { - Vec2F32 size = autocomp_box->fixed_size; - autocomp_box->fixed_position = v2f32(autocomp_root_box->rect.x0, autocomp_root_box->rect.y1); - autocomp_box->rect = r2f32(autocomp_box->fixed_position, add_2f32(autocomp_box->fixed_position, size)); + Vec2F32 size = lister_box->fixed_size; + lister_box->fixed_position = v2f32(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x, + lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); + lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) { - ui_calc_sizes_standalone__in_place_rec(autocomp_box, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(autocomp_box, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(autocomp_box, axis); - ui_layout_enforce_constraints__in_place_rec(autocomp_box, axis); - ui_layout_position__in_place_rec(autocomp_box, axis); + ui_calc_sizes_standalone__in_place_rec(lister_box, axis); + ui_calc_sizes_upwards_dependent__in_place_rec(lister_box, axis); + ui_calc_sizes_downwards_dependent__in_place_rec(lister_box, axis); + ui_layout_enforce_constraints__in_place_rec(lister_box, axis); + ui_layout_position__in_place_rec(lister_box, axis); } } } - else if(!ui_box_is_nil(autocomp_box) && ws->autocomp_last_frame_idx+1 < rd_state->frame_index+1) + else if(!ui_box_is_nil(lister_box) && ws->lister_last_frame_idx+1 < rd_state->frame_index+1) { - UI_Box *autocomp_root_box = ui_box_from_key(ws->autocomp_root_key); - if(!ui_box_is_nil(autocomp_root_box)) + UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); + if(!ui_box_is_nil(lister_root_box)) { - Vec2F32 size = autocomp_box->fixed_size; + Vec2F32 size = lister_box->fixed_size; Rng2F32 window_rect = os_client_rect_from_window(ws->os); - autocomp_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); - autocomp_box->rect = r2f32(autocomp_box->fixed_position, add_2f32(autocomp_box->fixed_position, size)); + lister_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); + lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); } } @@ -7960,9 +7989,9 @@ rd_window_frame(void) if(box->squish != 0) { Vec2F32 box_dim = dim_2f32(box->rect); - Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/8, -box->rect.y0)); + Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/2, -box->rect.y0)); Mat3x3F32 scale_xform = make_scale_3x3f32(v2f32(1-box->squish, 1-box->squish)); - Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/8, box->rect.y0)); + Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/2, box->rect.y0)); Mat3x3F32 xform = mul_3x3f32(origin2box_xform, mul_3x3f32(scale_xform, box2origin_xform)); dr_push_xform2d(xform); dr_push_tex2d_sample_kind(R_Tex2DSampleKind_Linear); @@ -8200,7 +8229,8 @@ rd_window_frame(void) // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1.f), b->palette->colors[UI_ColorCode_Border], 0, 1.f, 1.f); + Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, b->palette->colors[UI_ColorCode_Border], 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); // rjf: hover effect @@ -8208,7 +8238,7 @@ rd_window_frame(void) { Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); color.w *= b->hot_t; - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1), color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } } @@ -8216,7 +8246,7 @@ rd_window_frame(void) // rjf: debug border rendering if(0) { - R_Rect2DInst *inst = dr_rect(pad_2f32(b->rect, 1), v4f32(1, 0, 1, 0.25f), 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1, 0, 1, 0.25f), 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -9554,15 +9584,15 @@ rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 s //~ rjf: Auto-Complete Lister internal void -rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunkList *list, U64 cap, RD_AutoCompListerItem *item) +rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item) { - RD_AutoCompListerItemChunkNode *n = list->last; + RD_ListerItemChunkNode *n = list->last; if(n == 0 || n->count >= n->cap) { - n = push_array(arena, RD_AutoCompListerItemChunkNode, 1); + n = push_array(arena, RD_ListerItemChunkNode, 1); SLLQueuePush(list->first, list->last, n); n->cap = cap; - n->v = push_array_no_zero(arena, RD_AutoCompListerItem, n->cap); + n->v = push_array_no_zero(arena, RD_ListerItem, n->cap); list->chunk_count += 1; } MemoryCopyStruct(&n->v[n->count], item); @@ -9570,23 +9600,23 @@ rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunk list->total_count += 1; } -internal RD_AutoCompListerItemArray -rd_autocomp_lister_item_array_from_chunk_list(Arena *arena, RD_AutoCompListerItemChunkList *list) +internal RD_ListerItemArray +rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list) { - RD_AutoCompListerItemArray array = {0}; + RD_ListerItemArray array = {0}; array.count = list->total_count; - array.v = push_array_no_zero(arena, RD_AutoCompListerItem, array.count); + array.v = push_array_no_zero(arena, RD_ListerItem, array.count); U64 idx = 0; - for(RD_AutoCompListerItemChunkNode *n = list->first; n != 0; n = n->next) + for(RD_ListerItemChunkNode *n = list->first; n != 0; n = n->next) { - MemoryCopy(array.v+idx, n->v, sizeof(RD_AutoCompListerItem)*n->count); + MemoryCopy(array.v+idx, n->v, sizeof(RD_ListerItem)*n->count); idx += n->count; } return array; } internal int -rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListerItem *b) +rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b) { int result = 0; if(a->group < b->group) @@ -9621,13 +9651,13 @@ rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListe } internal void -rd_autocomp_lister_item_array_sort__in_place(RD_AutoCompListerItemArray *array) +rd_lister_item_array_sort__in_place(RD_ListerItemArray *array) { - quick_sort(array->v, array->count, sizeof(array->v[0]), rd_autocomp_lister_item_qsort_compare); + quick_sort(array->v, array->count, sizeof(array->v[0]), rd_lister_item_qsort_compare); } internal String8 -rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) +rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) { U64 word_start_off = 0; for(U64 off = 0; off < input.size && off < cursor_off; off += 1) @@ -9642,7 +9672,7 @@ rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) } internal String8 -rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off) +rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) { // rjf: find start of path U64 path_start_off = 0; @@ -9675,10 +9705,10 @@ rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } -internal RD_AutoCompListerParams -rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) +internal RD_ListerParams +rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) { - RD_AutoCompListerParams params = {0}; + RD_ListerParams params = {0}; { Temp scratch = scratch_begin(&arena, 1); @@ -9786,15 +9816,15 @@ rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri for MD_EachNode(child, schema_node->first) { if(0){} - else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Locals;} - else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Members;} - else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Languages;} - else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Architectures;} - else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_AutoCompListerFlag_Tex2DFormats;} + else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Locals;} + else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Members;} + else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Languages;} + else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Architectures;} + else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Tex2DFormats;} else if(child->flags & (MD_NodeFlag_StringSingleQuote|MD_NodeFlag_StringDoubleQuote|MD_NodeFlag_StringTick)) { str8_list_push(arena, ¶ms.strings, child->string); - params.flags |= RD_AutoCompListerFlag_ViewRuleParams; + params.flags |= RD_ListerFlag_ViewRuleParams; } } break; @@ -9818,32 +9848,30 @@ rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 stri } internal void -rd_set_autocomp_lister_query(UI_Key root_key, RD_AutoCompListerParams *params, String8 input, U64 cursor_off) +rd_set_lister_query_(RD_ListerParams *params) { RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(cursor_off != ws->autocomp_cursor_off) + if(params->cursor_off != ws->lister_params.cursor_off) { - ws->autocomp_input_dirty = 1; - ws->autocomp_cursor_off = cursor_off; + ws->lister_input_dirty = 1; } - if(!ui_key_match(ws->autocomp_root_key, root_key)) + if(!ui_key_match(ws->lister_params.anchor_key, params->anchor_key)) { - ws->autocomp_num_visible_rows_t = 0; - ws->autocomp_open_t = 0; + ws->lister_num_visible_rows_t = 0; + ws->lister_open_t = 0; } - if(ws->autocomp_last_frame_idx+1 < rd_state->frame_index) + if(ws->lister_last_frame_idx+1 < rd_state->frame_index) { - ws->autocomp_num_visible_rows_t = 0; - ws->autocomp_open_t = 0; + ws->lister_num_visible_rows_t = 0; + ws->lister_open_t = 0; } - ws->autocomp_root_key = root_key; - arena_clear(ws->autocomp_lister_params_arena); - MemoryCopyStruct(&ws->autocomp_lister_params, params); - ws->autocomp_lister_params.strings = str8_list_copy(ws->autocomp_lister_params_arena, &ws->autocomp_lister_params.strings); - ws->autocomp_lister_input_size = Min(input.size, sizeof(ws->autocomp_lister_input_buffer)); - MemoryCopy(ws->autocomp_lister_input_buffer, input.str, ws->autocomp_lister_input_size); - ws->autocomp_last_frame_idx = rd_state->frame_index; + arena_clear(ws->lister_params_arena); + MemoryCopyStruct(&ws->lister_params, params); + ws->lister_params.strings = str8_list_copy(ws->lister_params_arena, &ws->lister_params.strings); + ws->lister_input_size = Min(params->input.size, sizeof(ws->lister_input_buffer)); + MemoryCopy(ws->lister_input_buffer, params->input.str, ws->lister_input_size); + ws->lister_last_frame_idx = rd_state->frame_index; } //////////////////////////////// @@ -11539,7 +11567,7 @@ rd_frame(void) arena_release(ws->ctx_menu_arena); arena_release(ws->drop_completion_arena); arena_release(ws->hover_eval_arena); - arena_release(ws->autocomp_lister_params_arena); + arena_release(ws->lister_params_arena); arena_release(ws->arena); DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); @@ -13808,7 +13836,15 @@ rd_frame(void) //- rjf: panel tab controls case RD_CmdKind_FocusTab: { - // TODO(rjf): @cfg + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *panel = tab->parent; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); + RD_PanelNode *panel_node = rd_panel_node_from_tree_cfg(panel_tree.root, panel); + for(RD_CfgNode *n = panel_node->tabs.first; n != 0; n = n->next) + { + rd_cfg_release(rd_cfg_child_from_string(n->v, str8_lit("selected"))); + } + rd_cfg_new(tab, str8_lit("selected")); }break; case RD_CmdKind_NextTab: { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 8f16907f..da3d2392 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -511,28 +511,28 @@ typedef enum RD_PaletteCode RD_PaletteCode; //////////////////////////////// -//~ rjf: Auto-Complete Lister Types +//~ rjf: Lister Types -typedef U32 RD_AutoCompListerFlags; +typedef U32 RD_ListerFlags; enum { - RD_AutoCompListerFlag_Locals = (1<<0), - RD_AutoCompListerFlag_Registers = (1<<1), - RD_AutoCompListerFlag_ViewRules = (1<<2), - RD_AutoCompListerFlag_ViewRuleParams= (1<<3), - RD_AutoCompListerFlag_Members = (1<<4), - RD_AutoCompListerFlag_Globals = (1<<5), - RD_AutoCompListerFlag_ThreadLocals = (1<<6), - RD_AutoCompListerFlag_Procedures = (1<<7), - RD_AutoCompListerFlag_Types = (1<<8), - RD_AutoCompListerFlag_Languages = (1<<9), - RD_AutoCompListerFlag_Architectures = (1<<10), - RD_AutoCompListerFlag_Tex2DFormats = (1<<11), - RD_AutoCompListerFlag_Files = (1<<12), + RD_ListerFlag_Locals = (1<<0), + RD_ListerFlag_Registers = (1<<1), + RD_ListerFlag_ViewRules = (1<<2), + RD_ListerFlag_ViewRuleParams= (1<<3), + RD_ListerFlag_Members = (1<<4), + RD_ListerFlag_Globals = (1<<5), + RD_ListerFlag_ThreadLocals = (1<<6), + RD_ListerFlag_Procedures = (1<<7), + RD_ListerFlag_Types = (1<<8), + RD_ListerFlag_Languages = (1<<9), + RD_ListerFlag_Architectures = (1<<10), + RD_ListerFlag_Tex2DFormats = (1<<11), + RD_ListerFlag_Files = (1<<12), }; -typedef struct RD_AutoCompListerItem RD_AutoCompListerItem; -struct RD_AutoCompListerItem +typedef struct RD_ListerItem RD_ListerItem; +struct RD_ListerItem { String8 string; String8 kind_string; @@ -541,36 +541,42 @@ struct RD_AutoCompListerItem B32 is_non_code; }; -typedef struct RD_AutoCompListerItemChunkNode RD_AutoCompListerItemChunkNode; -struct RD_AutoCompListerItemChunkNode +typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode; +struct RD_ListerItemChunkNode { - RD_AutoCompListerItemChunkNode *next; - RD_AutoCompListerItem *v; + RD_ListerItemChunkNode *next; + RD_ListerItem *v; U64 count; U64 cap; }; -typedef struct RD_AutoCompListerItemChunkList RD_AutoCompListerItemChunkList; -struct RD_AutoCompListerItemChunkList +typedef struct RD_ListerItemChunkList RD_ListerItemChunkList; +struct RD_ListerItemChunkList { - RD_AutoCompListerItemChunkNode *first; - RD_AutoCompListerItemChunkNode *last; + RD_ListerItemChunkNode *first; + RD_ListerItemChunkNode *last; U64 chunk_count; U64 total_count; }; -typedef struct RD_AutoCompListerItemArray RD_AutoCompListerItemArray; -struct RD_AutoCompListerItemArray +typedef struct RD_ListerItemArray RD_ListerItemArray; +struct RD_ListerItemArray { - RD_AutoCompListerItem *v; + RD_ListerItem *v; U64 count; }; -typedef struct RD_AutoCompListerParams RD_AutoCompListerParams; -struct RD_AutoCompListerParams +typedef struct RD_ListerParams RD_ListerParams; +struct RD_ListerParams { - RD_AutoCompListerFlags flags; + UI_Key anchor_key; + Vec2F32 anchor_off; + RD_ListerFlags flags; String8List strings; + String8 input; + U64 cursor_off; + F32 squish; + F32 transparency; }; //////////////////////////////// @@ -623,18 +629,15 @@ struct RD_WindowState Arena *drop_completion_arena; String8List drop_completion_paths; - // rjf: autocomplete lister state - U64 autocomp_last_frame_idx; - B32 autocomp_input_dirty; - UI_Key autocomp_root_key; - Arena *autocomp_lister_params_arena; - RD_AutoCompListerParams autocomp_lister_params; - U64 autocomp_cursor_off; - U8 autocomp_lister_input_buffer[1024]; - U64 autocomp_lister_input_size; - F32 autocomp_open_t; - F32 autocomp_num_visible_rows_t; - S64 autocomp_cursor_num; + // rjf: lister state + U64 lister_last_frame_idx; + B32 lister_input_dirty; + Arena *lister_params_arena; + RD_ListerParams lister_params; + U8 lister_input_buffer[1024]; + U64 lister_input_size; + F32 lister_open_t; + F32 lister_num_visible_rows_t; // rjf: query view stack U64 query_cmd_gen; @@ -849,7 +852,6 @@ struct RD_State RD_WindowStateSlot *window_state_slots; RD_WindowState *free_window_state; RD_Handle last_focused_window; - // TODO(rjf): @cfg must be nil-initialized RD_WindowState *first_window_state; RD_WindowState *last_window_state; @@ -1267,17 +1269,18 @@ internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string); //////////////////////////////// -//~ rjf: Auto-Complete Lister +//~ rjf: Lister -internal void rd_autocomp_lister_item_chunk_list_push(Arena *arena, RD_AutoCompListerItemChunkList *list, U64 cap, RD_AutoCompListerItem *item); -internal RD_AutoCompListerItemArray rd_autocomp_lister_item_array_from_chunk_list(Arena *arena, RD_AutoCompListerItemChunkList *list); -internal int rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListerItem *b); -internal void rd_autocomp_lister_item_array_sort__in_place(RD_AutoCompListerItemArray *array); +internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item); +internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); +internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); +internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); -internal String8 rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); -internal String8 rd_autocomp_query_path_from_input_string_off(String8 input, U64 cursor_off); -internal RD_AutoCompListerParams rd_view_rule_autocomp_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); -internal void rd_set_autocomp_lister_query(UI_Key root_key, RD_AutoCompListerParams *params, String8 input, U64 cursor_off); +internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); +internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); +internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); +internal void rd_set_lister_query_(RD_ListerParams *params); +#define rd_set_lister_query(...) rd_set_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) //////////////////////////////// //~ rjf: Search Strings diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d73009e8..9270ef7b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1704,7 +1704,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo if(autocomplete_hint_string.size != 0) { take_autocomplete = 1; - String8 word_query = rd_autocomp_query_word_from_input_string_off(string, edit_state->cursor.column-1); + String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); U64 word_off = (U64)(word_query.str - string.str); String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); @@ -2892,7 +2892,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo String8 cell_inheritance_string = {0}; String8 cell_error_string = {0}; String8 cell_error_tooltip_string = {0}; - RD_AutoCompListerFlags cell_autocomp_flags = 0; + RD_ListerFlags cell_autocomp_flags = 0; RD_ViewRuleUIFunctionType *cell_ui_hook = 0; MD_Node *cell_ui_params = &md_nil_node; Vec4F32 cell_base_color = ui_top_palette()->text; @@ -2908,11 +2908,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); } - cell_autocomp_flags = (RD_AutoCompListerFlag_Locals| - RD_AutoCompListerFlag_Procedures| - RD_AutoCompListerFlag_Globals| - RD_AutoCompListerFlag_ThreadLocals| - RD_AutoCompListerFlag_Types); + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); if(row->member != 0 && row->member->inheritance_key_chain.first != 0) { String8List inheritance_chain_type_names = {0}; @@ -2964,14 +2964,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { cell_error_tooltip_string = str8_lit("Could not read memory successfully."); } - cell_autocomp_flags = (RD_AutoCompListerFlag_Locals| - RD_AutoCompListerFlag_Procedures| - RD_AutoCompListerFlag_Globals| - RD_AutoCompListerFlag_ThreadLocals| - RD_AutoCompListerFlag_Types); + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); if(cell_type->flags & E_TypeFlag_IsPathText) { - cell_autocomp_flags = RD_AutoCompListerFlag_Files; + cell_autocomp_flags = RD_ListerFlag_Files; } if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) { @@ -2997,7 +2997,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewColumnKind_ViewRule: { cell_can_edit = 1; - cell_autocomp_flags = RD_AutoCompListerFlag_ViewRules; + cell_autocomp_flags = RD_ListerFlag_ViewRules; if(cell_pre_edit_string.size == 0) { EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); @@ -3158,16 +3158,20 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - RD_AutoCompListerParams params = {cell_autocomp_flags}; + RD_ListerParams params = {cell_autocomp_flags}; if(col->kind == RD_WatchViewColumnKind_ViewRule) { - params = rd_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, cell_edit_state->cursor.column-1); + params = rd_view_rule_lister_params_from_input_cursor(scratch.arena, input, cell_edit_state->cursor.column-1); if(params.flags == 0) { params.flags = cell_autocomp_flags; } } - rd_set_autocomp_lister_query(sig.box->key, ¶ms, input, cell_edit_state->cursor.column-1); + params.anchor_key = sig.box->key; + params.anchor_off = v2f32(0, dim_2f32(sig.box->rect).y); + params.input = input; + params.cursor_off = cell_edit_state->cursor.column-1; + rd_set_lister_query_(¶ms); } } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c81bdd68..99cb299b 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2575,7 +2575,7 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op if(autocomplete_hint_string.size != 0) { - String8 word_query = rd_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 word_query = rd_lister_query_word_from_input_string_off(edit_string, cursor->column-1); U64 word_off = (U64)(word_query.str - edit_string.str); String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); new_string.size = Min(edit_buffer_size, new_string.size); @@ -2678,7 +2678,7 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx DR_FancyStringList code_fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); if(autocomplete_hint_string.size != 0) { - String8 query_word = rd_autocomp_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, cursor->column-1); String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); U64 off = 0; U64 cursor_off = cursor->column-1; From ace7db492bd6fd5ae445c240942a5df09bf1a7a0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 Jan 2025 13:06:26 -0800 Subject: [PATCH 007/755] fix nil-cases of cfg insertion; fix incorrect root setting in cfg deep copy --- src/raddbg/raddbg_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b2fa13d4..ab694bef 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -635,14 +635,14 @@ rd_cfg_deep_copy(RD_Cfg *src_root) for(RD_Cfg *src = src_root; src != &rd_nil_cfg; src = rec.next) { RD_Cfg *dst = rd_cfg_new(dst_parent, src->string); + if(dst_root == &rd_nil_cfg) + { + dst_root = dst; + } rec = rd_cfg_rec__depth_first(src_root, src); if(rec.push_count > 0) { dst_parent = dst; - if(dst_root == &rd_nil_cfg) - { - dst_root = dst; - } } else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) { @@ -677,8 +677,11 @@ rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...) internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child) { - DLLInsert_NPZ(&rd_nil_cfg, parent->first, parent->last, prev_child, new_child, next, prev); - new_child->parent = parent; + if(parent != &rd_nil_cfg) + { + DLLInsert_NPZ(&rd_nil_cfg, parent->first, parent->last, prev_child, new_child, next, prev); + new_child->parent = parent; + } } internal void From b98ebc8da4748aa760e7e089be29f5c9f125b308 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 Jan 2025 15:16:55 -0800 Subject: [PATCH 008/755] lister applicability work - applies to commands, icons, descriptions, etc. --- src/raddbg/raddbg_core.c | 1244 ++++++++++++++++++++------------------ src/raddbg/raddbg_core.h | 42 +- 2 files changed, 699 insertions(+), 587 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ab694bef..535a1db4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -322,9 +322,6 @@ rd_parent_ev_key_from_entity(RD_Entity *entity) return parent_key; } -//////////////////////////////// -//~ rjf: View Type Functions - //////////////////////////////// //~ rjf: View Spec Type Functions @@ -3777,6 +3774,660 @@ rd_window_frame(void) } } + + //////////////////////////// + //- rjf: build lister + // + ProfScope("build lister") + if(!ui_key_match(ws->lister_params.anchor_key, ui_key_zero()) && ws->lister_last_frame_idx+1 >= rd_state->frame_index) + { + String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); + String8 query_word = rd_lister_query_word_from_input_string_off(input, ws->lister_params.cursor_off); + String8 query_path = rd_lister_query_path_from_input_string_off(input, ws->lister_params.cursor_off); + UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); + if(!ui_box_is_nil(lister_root_box)) + { + Temp scratch = scratch_begin(0, 0); + DI_Scope *di_scope = di_scope_open(); + 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); + + //- rjf: grab rdis + 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) + { + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); + RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); + rdis[idx] = rdi; + } + } + + //- rjf: unpack lister params + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + + //- rjf: gather lister items + RD_ListerItemChunkList item_list = {0}; + { + //- rjf: gather locals + if(ws->lister_params.flags & RD_ListerFlag_Locals) + { + E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local (Member)"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather registers + if(ws->lister_params.flags & RD_ListerFlag_Registers) + { + Arch arch = thread->arch; + U64 reg_names_count = regs_reg_code_count_from_arch(arch); + U64 alias_names_count = regs_alias_code_count_from_arch(arch); + String8 *reg_names = regs_reg_code_string_table_from_arch(arch); + String8 *alias_names = regs_alias_code_string_table_from_arch(arch); + for(U64 idx = 0; idx < reg_names_count; idx += 1) + { + if(reg_names[idx].size != 0) + { + String8 display_name = reg_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Register"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + for(U64 idx = 0; idx < alias_names_count; idx += 1) + { + if(alias_names[idx].size != 0) + { + String8 display_name = alias_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Reg. Alias"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather view rules + if(ws->lister_params.flags & RD_ListerFlag_ViewRules) + { + for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) + { + for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) + { + String8 display_name = spec->info.string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + String8 description = spec->info.description; + FuzzyMatchRangeList description__matches = fuzzy_match_find(scratch.arena, query_word, description); + if(display_name__matches.count == display_name__matches.needle_part_count || + description__matches.count == description__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .description = description, + .description__matches = description__matches); + } + } + } + } + + //- rjf: gather members + if(ws->lister_params.flags & RD_ListerFlag_Members) + { + // TODO(rjf) + } + + //- rjf: gather globals + if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_GlobalVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Global"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather thread locals + if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_ThreadVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Thread Local"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather procedures + if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_Procedures, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Procedure"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather types + if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_UDTs, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Type"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather languages + if(ws->lister_params.flags & RD_ListerFlag_Languages) + { + for EachNonZeroEnumVal(TXT_LangKind, lang) + { + String8 display_name = txt_extension_from_lang_kind(lang); + if(display_name.size != 0) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Language"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather architectures + if(ws->lister_params.flags & RD_ListerFlag_Architectures) + { + for EachNonZeroEnumVal(Arch, arch) + { + String8 display_name = string_from_arch(arch); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Architecture"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather tex2dformats + if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) + { + for EachEnumVal(R_Tex2DFormat, fmt) + { + String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("2D Texture Format"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather view rule params + if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) + { + for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) + { + String8 display_name = n->string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule Parameter"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather files + if(ws->lister_params.flags & RD_ListerFlag_Files) + { + // rjf: find containing directory in query_path + String8 dir_str_in_input = {0}; + for(U64 i = 0; i < query_path.size; i += 1) + { + String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); + String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); + String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); + if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); + } + else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + if(dir_str_in_input.size != 0) + { + break; + } + } + + // rjf: use query_path string to form various parts of search space + String8 prefix = {0}; + String8 path = {0}; + String8 search = {0}; + if(dir_str_in_input.size != 0) + { + String8 dir = dir_str_in_input; + U64 one_past_last_slash = dir.size; + for(U64 i = 0; i < dir_str_in_input.size; i += 1) + { + if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') + { + one_past_last_slash = i+1; + } + } + dir.size = one_past_last_slash; + path = dir; + search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); + prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); + } + + // rjf: get current files, filtered + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); + B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = info.name, + .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), + .display_name = info.name, + .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, + .display_name__matches = match_ranges, + .is_non_code = 1); + } + } + os_file_iter_end(it); + } + + //- rjf: gather commands + if(ws->lister_params.flags & RD_ListerFlag_Commands) + { + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 cmd_display_name = info->display_name; + String8 cmd_desc = info->description; + String8 cmd_tags = info->search_tags; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, query_word, cmd_display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, query_word, cmd_desc); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, query_word, cmd_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == name_matches.needle_part_count || + tags_matches.count > 0 || + name_matches.needle_part_count == 0) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = info->icon_kind, + .string = info->string, + .kind_name = str8_lit("Command"), + .display_name = cmd_display_name, + .display_name__matches = name_matches, + .description = cmd_desc, + .description__matches = desc_matches, + .is_non_code = 1); + } + } + } + } + + //- rjf: lister item list -> sorted array + RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); + rd_lister_item_array_sort__in_place(&item_array); + + //- rjf: animate + { + // rjf: animate target # of rows + { + F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + F32 target = Min((F32)item_array.count, 16.f); + if(abs_f32(target - ws->lister_num_visible_rows_t) > 0.01f) + { + rd_request_frame(); + } + ws->lister_num_visible_rows_t += (target - ws->lister_num_visible_rows_t) * rate; + if(abs_f32(target - ws->lister_num_visible_rows_t) <= 0.02f) + { + ws->lister_num_visible_rows_t = target; + } + } + + // rjf: animate open + { + F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; + F32 diff = 1.f-ws->lister_open_t; + ws->lister_open_t += diff*rate; + if(abs_f32(diff) < 0.05f) + { + ws->lister_open_t = 1.f; + } + else + { + rd_request_frame(); + } + } + } + + //- rjf: build + if(item_array.count != 0) + { + F32 squish = ws->lister_params.squish; + F32 transparency = ws->lister_params.transparency; + if(squish == 0.f) + { + squish = 0.25f - 0.25f*ws->lister_open_t; + } + if(transparency == 0.f) + { + transparency = 1.f-ws->lister_open_t; + } + F32 width_px = ui_box_is_nil(lister_root_box) ? (ui_top_font_size()*30.f) : dim_2f32(lister_root_box->rect).x; + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + { + row_height_px += floor_f32(ui_top_font_size()*3.5f); + } + ui_set_next_fixed_x(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x); + ui_set_next_fixed_y(lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); + ui_set_next_pref_width(ui_px(width_px, 1.f)); + ui_set_next_pref_height(ui_px(row_height_px*ws->lister_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); + ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); + UI_Focus(UI_FocusKind_On) + UI_Squish(squish) + UI_Transparency(transparency) + RD_Palette(RD_PaletteCode_Floating) + { + lister_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| + UI_BoxFlag_Clickable| + UI_BoxFlag_Clip| + UI_BoxFlag_RoundChildrenByParent| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackground, + "lister_box"); + if(ws->lister_input_dirty) + { + ws->lister_input_dirty = 0; + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); + } + } + UI_Parent(lister_box) + UI_WidthFill + UI_PrefHeight(ui_px(row_height_px, 1.f)) + UI_HoverCursor(OS_Cursor_HandPoint) + UI_Focus(UI_FocusKind_Null) + RD_Palette(RD_PaletteCode_ImplicitButton) + UI_Padding(ui_em(1.f, 1.f)) + { + for(U64 idx = 0; idx < item_array.count; idx += 1) + { + RD_ListerItem *item = &item_array.v[idx]; + + //- rjf: build the top-level box for the item + UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); + + //- rjf: build item contents + UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) + { + // rjf: icon + if(item->icon_kind != RD_IconKind_Null) + UI_PrefWidth(ui_em(3.f, 1.f)) + UI_Column + UI_Padding(ui_pct(1, 0)) + RD_Font(RD_FontSlot_Icons) + { + ui_label(rd_icon_kind_text_table[item->icon_kind]); + } + + // rjf: name / description + UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) + { + // rjf: name + UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) + { + // rjf: display name + RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + UI_Box *box = item->is_non_code ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); + ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); + } + + // rjf: kind name + if(item->kind_name.size != 0) + { + ui_spacer(ui_em(1.f, 1.f)); + RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) + { + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_flags(UI_BoxFlag_DrawBorder); + UI_Row UI_Padding(ui_em(0.5f, 1.f)) + { + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); + ui_box_equip_display_string(box, item->kind_name); + } + } + } + } + + // rjf: description + if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + { + if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) + { + UI_Box *box = ui_label(item->description).box; + ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); + } + } + } + + // rjf: bindings + if(0) UI_Column + { + + } + } + + //- rjf: do interaction with top-level item + UI_Signal item_sig = ui_signal_from_box(item_box); + if(ui_clicked(item_sig)) + { + UI_Event move_back_evt = zero_struct; + move_back_evt.kind = UI_EventKind_Navigate; + move_back_evt.flags = UI_EventFlag_KeepMark; + move_back_evt.delta_2s32.x = -(S32)query_word.size; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); + UI_Event paste_evt = zero_struct; + paste_evt.kind = UI_EventKind_Text; + paste_evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); + } + else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); + } + } + } + } + + di_scope_close(di_scope); + scratch_end(scratch); + } + } + //////////////////////////// //- rjf: prepare query state for the in-progress query command // @@ -4000,573 +4651,6 @@ rd_window_frame(void) ws->query_input_selected = 0; } - //////////////////////////// - //- rjf: build lister - // - ProfScope("build lister") - if(!ui_key_match(ws->lister_params.anchor_key, ui_key_zero()) && ws->lister_last_frame_idx+1 >= rd_state->frame_index) - { - String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); - String8 query_word = rd_lister_query_word_from_input_string_off(input, ws->lister_params.cursor_off); - String8 query_path = rd_lister_query_path_from_input_string_off(input, ws->lister_params.cursor_off); - UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); - if(!ui_box_is_nil(lister_root_box)) - { - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - 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); - - //- rjf: grab rdis - 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) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: unpack lister params - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - - //- rjf: gather lister items - RD_ListerItemChunkList item_list = {0}; - { - //- rjf: gather locals - if(ws->lister_params.flags & RD_ListerFlag_Locals) - { - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) - { - RD_ListerItem item = {0}; - { - item.string = n->string; - item.kind_string = str8_lit("Local"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - RD_ListerItem item = {0}; - { - item.string = n->string; - item.kind_string = str8_lit("Local (Member)"); - item.matches = fuzzy_match_find(scratch.arena, query_word, n->string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather registers - if(ws->lister_params.flags & RD_ListerFlag_Registers) - { - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - RD_ListerItem item = {0}; - { - item.string = reg_names[idx]; - item.kind_string = str8_lit("Register"); - item.matches = fuzzy_match_find(scratch.arena, query_word, reg_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - RD_ListerItem item = {0}; - { - item.string = alias_names[idx]; - item.kind_string = str8_lit("Reg. Alias"); - item.matches = fuzzy_match_find(scratch.arena, query_word, alias_names[idx]); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather view rules - if(ws->lister_params.flags & RD_ListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - RD_ListerItem item = {0}; - { - item.string = spec->info.string; - item.kind_string = str8_lit("View Rule"); - item.matches = fuzzy_match_find(scratch.arena, query_word, spec->info.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - } - - //- rjf: gather members - if(ws->lister_params.flags & RD_ListerFlag_Members) - { - // TODO(rjf) - } - - //- rjf: gather globals - if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_ListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Global"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather thread locals - if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_ListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Thread Local"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather procedures - if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_ListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Procedure"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather types - if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - - // rjf: push item - RD_ListerItem item = {0}; - { - item.string = name; - item.kind_string = str8_lit("Type"); - item.matches = items.v[idx].match_ranges; - item.group = 1; - } - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - - //- rjf: gather languages - if(ws->lister_params.flags & RD_ListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - RD_ListerItem item = {0}; - { - item.string = txt_extension_from_lang_kind(lang); - item.kind_string = str8_lit("Language"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(item.string.size != 0 && (query_word.size == 0 || item.matches.count != 0)) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather architectures - if(ws->lister_params.flags & RD_ListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - RD_ListerItem item = {0}; - { - item.string = string_from_arch(arch); - item.kind_string = str8_lit("Arch"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather tex2dformats - if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) - { - for EachEnumVal(R_Tex2DFormat, fmt) - { - RD_ListerItem item = {0}; - { - item.string = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); - item.kind_string = str8_lit("Format"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather view rule params - if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) - { - for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) - { - String8 string = n->string; - RD_ListerItem item = {0}; - { - item.string = string; - item.kind_string = str8_lit("Parameter"); - item.matches = fuzzy_match_find(scratch.arena, query_word, item.string); - } - if(query_word.size == 0 || item.matches.count != 0) - { - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - } - - //- rjf: gather files - if(ws->lister_params.flags & RD_ListerFlag_Files) - { - // rjf: find containing directory in query_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < query_path.size; i += 1) - { - String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - // rjf: use query_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); - } - - // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); - B32 fits_search = (search.size == 0 || match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) - { - RD_ListerItem item = {0}; - { - item.string = info.props.flags & FilePropertyFlag_IsFolder ? push_str8f(scratch.arena, "%S/", info.name) : info.name; - item.kind_string = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"); - item.matches = match_ranges; - item.is_non_code = 1; - } - rd_lister_item_chunk_list_push(scratch.arena, &item_list, 256, &item); - } - } - os_file_iter_end(it); - } - } - - //- rjf: lister item list -> sorted array - RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); - rd_lister_item_array_sort__in_place(&item_array); - - //- rjf: animate - { - // rjf: animate target # of rows - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - F32 target = Min((F32)item_array.count, 16.f); - if(abs_f32(target - ws->lister_num_visible_rows_t) > 0.01f) - { - rd_request_frame(); - } - ws->lister_num_visible_rows_t += (target - ws->lister_num_visible_rows_t) * rate; - if(abs_f32(target - ws->lister_num_visible_rows_t) <= 0.02f) - { - ws->lister_num_visible_rows_t = target; - } - } - - // rjf: animate open - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - F32 diff = 1.f-ws->lister_open_t; - ws->lister_open_t += diff*rate; - if(abs_f32(diff) < 0.05f) - { - ws->lister_open_t = 1.f; - } - else - { - rd_request_frame(); - } - } - } - - //- rjf: build - if(item_array.count != 0) - { - F32 squish = ws->lister_params.squish; - F32 transparency = ws->lister_params.transparency; - if(squish == 0.f) - { - squish = 0.25f - 0.25f*ws->lister_open_t; - } - if(transparency == 0.f) - { - transparency = 1.f-ws->lister_open_t; - } - F32 width_px = ui_box_is_nil(lister_root_box) ? (ui_top_font_size()*30.f) : dim_2f32(lister_root_box->rect).x; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - ui_set_next_fixed_x(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x); - ui_set_next_fixed_y(lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); - ui_set_next_pref_width(ui_px(width_px, 1.f)); - ui_set_next_pref_height(ui_px(row_height_px*ws->lister_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); - UI_Focus(UI_FocusKind_On) - UI_Squish(squish) - UI_Transparency(transparency) - RD_Palette(RD_PaletteCode_Floating) - { - lister_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - "lister_box"); - if(ws->lister_input_dirty) - { - ws->lister_input_dirty = 0; - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); - } - } - UI_Parent(lister_box) - UI_WidthFill - UI_PrefHeight(ui_px(row_height_px, 1.f)) - RD_Font(RD_FontSlot_Code) - UI_HoverCursor(OS_Cursor_HandPoint) - UI_Focus(UI_FocusKind_Null) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_Padding(ui_em(1.f, 1.f)) - { - for(U64 idx = 0; idx < item_array.count; idx += 1) - { - RD_ListerItem *item = &item_array.v[idx]; - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) - { - UI_WidthFill RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - UI_Box *box = item->is_non_code ? ui_label(item->string).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->string); - ui_box_equip_fuzzy_match_ranges(box, &item->matches); - } - RD_Font(RD_FontSlot_Main) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(item->kind_string); - } - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } - } - } - } - - di_scope_close(di_scope); - scratch_end(scratch); - } - } - //////////////////////////// //- rjf: darken lower layer ui when query is selected // @@ -9630,11 +9714,27 @@ rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b) { result = +1; } - else if(a->matches.count > b->matches.count) + else if(a->display_name__matches.count > b->display_name__matches.count) { result = -1; } - else if(a->matches.count < b->matches.count) + else if(a->display_name__matches.count < b->display_name__matches.count) + { + result = +1; + } + else if(a->description__matches.count > b->description__matches.count) + { + result = -1; + } + else if(a->description__matches.count < b->description__matches.count) + { + result = +1; + } + else if(a->kind_name__matches.count > b->kind_name__matches.count) + { + result = -1; + } + else if(a->kind_name__matches.count < b->kind_name__matches.count) { result = +1; } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index da3d2392..3e77d6cf 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -516,27 +516,38 @@ RD_PaletteCode; typedef U32 RD_ListerFlags; enum { - RD_ListerFlag_Locals = (1<<0), - RD_ListerFlag_Registers = (1<<1), - RD_ListerFlag_ViewRules = (1<<2), - RD_ListerFlag_ViewRuleParams= (1<<3), - RD_ListerFlag_Members = (1<<4), - RD_ListerFlag_Globals = (1<<5), - RD_ListerFlag_ThreadLocals = (1<<6), - RD_ListerFlag_Procedures = (1<<7), - RD_ListerFlag_Types = (1<<8), - RD_ListerFlag_Languages = (1<<9), - RD_ListerFlag_Architectures = (1<<10), - RD_ListerFlag_Tex2DFormats = (1<<11), - RD_ListerFlag_Files = (1<<12), + //- rjf: lister visual settings + RD_ListerFlag_Descriptions = (1<<0), + + //- rjf: lister item sources + RD_ListerFlag_Locals = (1<<1), + RD_ListerFlag_Registers = (1<<2), + RD_ListerFlag_ViewRules = (1<<3), + RD_ListerFlag_ViewRuleParams= (1<<4), + RD_ListerFlag_Members = (1<<5), + RD_ListerFlag_Globals = (1<<6), + RD_ListerFlag_ThreadLocals = (1<<7), + RD_ListerFlag_Procedures = (1<<8), + RD_ListerFlag_Types = (1<<9), + RD_ListerFlag_Languages = (1<<10), + RD_ListerFlag_Architectures = (1<<11), + RD_ListerFlag_Tex2DFormats = (1<<12), + RD_ListerFlag_Files = (1<<13), + RD_ListerFlag_Commands = (1<<14), }; typedef struct RD_ListerItem RD_ListerItem; struct RD_ListerItem { String8 string; - String8 kind_string; - FuzzyMatchRangeList matches; + String8 kind_name; + String8 display_name; + String8 description; + String8 search_tags; + RD_IconKind icon_kind; + FuzzyMatchRangeList kind_name__matches; + FuzzyMatchRangeList display_name__matches; + FuzzyMatchRangeList description__matches; U64 group; B32 is_non_code; }; @@ -1272,6 +1283,7 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 va //~ rjf: Lister internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item); +#define rd_lister_item_chunk_list_push_new(arena, list, cap, ...) rd_lister_item_chunk_list_push((arena), (list), (cap), &(RD_ListerItem){.string = {0}, __VA_ARGS__}) internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); From 6fe9a14778189c62217a537e2f49e946951e509f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 14 Jan 2025 17:30:07 -0800 Subject: [PATCH 009/755] eliminate stateful keybindings data structure - move to on-the-fly cfg tree usage --- src/raddbg/raddbg_core.c | 309 +++++++++++++++++++++--------------- src/raddbg/raddbg_core.h | 146 ++++++++++------- src/raddbg/raddbg_main.c | 2 + src/raddbg/raddbg_widgets.c | 26 +-- 4 files changed, 281 insertions(+), 202 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 535a1db4..d6d331af 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1143,6 +1143,48 @@ rd_cfg_is_project_filtered(RD_Cfg *cfg) return result; } +internal RD_KeyMapNodePtrList +rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string) +{ + RD_KeyMapNodePtrList list = {0}; + { + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%rd_state->key_map->name_slots_count; + for(RD_KeyMapNode *n = rd_state->key_map->name_slots[slot_idx].first; n != 0; n = n->name_hash_next) + { + if(str8_match(n->name, string, 0)) + { + RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1); + ptr->v = n; + SLLQueuePush(list.first, list.last, ptr); + list.count += 1; + } + } + } + return list; +} + +internal RD_KeyMapNodePtrList +rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding) +{ + RD_KeyMapNodePtrList list = {0}; + { + U64 hash = d_hash_from_string(str8_struct(&binding)); + U64 slot_idx = hash%rd_state->key_map->binding_slots_count; + for(RD_KeyMapNode *n = rd_state->key_map->binding_slots[slot_idx].first; n != 0; n = n->binding_hash_next) + { + if(MemoryMatchStruct(&binding, &n->binding)) + { + RD_KeyMapNodePtr *ptr = push_array(arena, RD_KeyMapNodePtr, 1); + ptr->v = n; + SLLQueuePush(list.first, list.last, ptr); + list.count += 1; + } + } + } + return list; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -4231,7 +4273,8 @@ rd_window_frame(void) .display_name__matches = name_matches, .description = cmd_desc, .description__matches = desc_matches, - .is_non_code = 1); + .is_non_code = 1, + .can_have_bindings = 1); } } } @@ -4391,9 +4434,17 @@ rd_window_frame(void) } // rjf: bindings - if(0) UI_Column + if(item->can_have_bindings) { - + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) + { + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) + { + rd_cmd_binding_buttons(item->string); + } + } } } @@ -9997,123 +10048,6 @@ rd_push_search_string(Arena *arena) //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: keybindings - -internal OS_Key -rd_os_key_from_cfg_string(String8 string) -{ - OS_Key result = OS_Key_Null; - { - for(OS_Key key = OS_Key_Null; key < OS_Key_COUNT; key = (OS_Key)(key+1)) - { - if(str8_match(string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive)) - { - result = key; - break; - } - } - } - return result; -} - -internal void -rd_clear_bindings(void) -{ - arena_clear(rd_state->key_map_arena); - rd_state->key_map_table_size = 1024; - rd_state->key_map_table = push_array(rd_state->key_map_arena, RD_KeyMapSlot, rd_state->key_map_table_size); - rd_state->key_map_total_count = 0; -} - -internal RD_BindingList -rd_bindings_from_name(Arena *arena, String8 name) -{ - RD_BindingList result = {0}; - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next) - { - if(str8_match(n->name, name, 0)) - { - RD_BindingNode *node = push_array(arena, RD_BindingNode, 1); - node->binding = n->binding; - SLLQueuePush(result.first, result.last, node); - result.count += 1; - } - } - return result; -} - -internal void -rd_bind_name(String8 name, RD_Binding binding) -{ - if(binding.key != OS_Key_Null) - { - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - RD_KeyMapNode *existing_node = 0; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first; n != 0; n = n->hash_next) - { - if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - existing_node = n; - break; - } - } - if(existing_node == 0) - { - RD_KeyMapNode *n = rd_state->free_key_map_node; - if(n == 0) - { - n = push_array(rd_state->arena, RD_KeyMapNode, 1); - } - else - { - rd_state->free_key_map_node = rd_state->free_key_map_node->hash_next; - } - n->name = push_str8_copy(rd_state->arena, name); - n->binding = binding; - DLLPushBack_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev); - rd_state->key_map_total_count += 1; - } - } -} - -internal void -rd_unbind_name(String8 name, RD_Binding binding) -{ - U64 hash = d_hash_from_string(name); - U64 slot = hash%rd_state->key_map_table_size; - for(RD_KeyMapNode *n = rd_state->key_map_table[slot].first, *next = 0; n != 0; n = next) - { - next = n->hash_next; - if(str8_match(n->name, name, 0) && n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - DLLRemove_NP(rd_state->key_map_table[slot].first, rd_state->key_map_table[slot].last, n, hash_next, hash_prev); - n->hash_next = rd_state->free_key_map_node; - rd_state->free_key_map_node = n; - rd_state->key_map_total_count -= 1; - } - } -} - -internal String8List -rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding) -{ - String8List result = {0}; - for(U64 idx = 0; idx < rd_state->key_map_table_size; idx += 1) - { - for(RD_KeyMapNode *n = rd_state->key_map_table[idx].first; n != 0; n = n->hash_next) - { - if(n->binding.key == binding.key && n->binding.modifiers == binding.modifiers) - { - str8_list_push(arena, &result, n->name); - } - } - } - return result; -} - //- rjf: colors internal Vec4F32 @@ -11335,7 +11269,7 @@ rd_cmd_kind_info_from_string(String8 string) { RD_CmdKindInfo *info = &rd_nil_cmd_kind_info; { - // TODO(rjf): extend this by looking up into dynamically-registered commands by views + // TODO(rjf): @dynamic_cmds extend this by looking up into dynamically-registered commands by views RD_CmdKind kind = rd_cmd_kind_from_string(string); if(kind != RD_CmdKind_Null) { @@ -11419,7 +11353,6 @@ rd_init(CmdLine *cmdln) rd_state->entities_base = push_array(rd_state->entities_arena, RD_Entity, 0); rd_state->entities_count = 0; rd_state->entities_root = rd_entity_alloc(&rd_nil_entity, RD_EntityKind_Root); - rd_state->key_map_arena = arena_alloc(); rd_state->popup_arena = arena_alloc(); rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); @@ -11432,7 +11365,6 @@ rd_init(CmdLine *cmdln) rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); rd_state->top_regs = &rd_state->base_regs; - rd_clear_bindings(); // rjf: set up top-level config entity trees { @@ -11704,6 +11636,109 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: build key map from config + // + { + //- rjf: set up table + rd_state->key_map = push_array(rd_frame_arena(), RD_KeyMap, 1); + RD_KeyMap *key_map = rd_state->key_map; + key_map->name_slots_count = 4096; + key_map->name_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->name_slots_count); + key_map->binding_slots_count = 4096; + key_map->binding_slots = push_array(rd_frame_arena(), RD_KeyMapSlot, key_map->binding_slots_count); + + //- rjf: gather & parse all explicitly stored keybinding sets + RD_CfgList keybindings_cfg_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("keybindings")); + for(RD_CfgNode *n = keybindings_cfg_list.first; n != 0; n = n->next) + { + RD_Cfg *keybindings_root = n->v; + for(RD_Cfg *keybinding = keybindings_root->first; keybinding != &rd_nil_cfg; keybinding = keybinding->next) + { + String8 name = {0}; + RD_Binding binding = {0}; + for(RD_Cfg *child = keybinding->first; child != &rd_nil_cfg; child = child->next) + { + if(0){} + else if(str8_match(child->string, str8_lit("ctrl"), 0)) { binding.modifiers |= OS_Modifier_Ctrl; } + else if(str8_match(child->string, str8_lit("alt"), 0)) { binding.modifiers |= OS_Modifier_Alt; } + else if(str8_match(child->string, str8_lit("shift"), 0)) { binding.modifiers |= OS_Modifier_Shift; } + else + { + OS_Key key = OS_Key_Null; + for EachEnumVal(OS_Key, k) + { + if(str8_match(child->string, os_g_key_cfg_string_table[k], StringMatchFlag_CaseInsensitive)) + { + key = k; + break; + } + } + if(key != OS_Key_Null) + { + binding.key = key; + } + else + { + name = child->string; + for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1) + { + if(str8_match(rd_binding_version_remap_old_name_table[idx], name, StringMatchFlag_CaseInsensitive)) + { + name = rd_binding_version_remap_new_name_table[idx]; + } + } + } + } + } + if(name.size != 0) + { + U64 name_hash = d_hash_from_string(name); + U64 binding_hash = d_hash_from_string(str8_struct(&binding)); + U64 name_slot_idx = name_hash%key_map->name_slots_count; + U64 binding_slot_idx = binding_hash%key_map->binding_slots_count; + RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1); + n->cfg = keybinding; + n->name = push_str8_copy(rd_frame_arena(), name); + n->binding = binding; + SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next); + SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next); + } + } + } + + //- rjf: iterate all commands - if they are not found in the map, then use + // the default binding. + // TODO(rjf): @dynamic_cmds + for EachElement(idx, rd_default_binding_table) + { + String8 name = rd_default_binding_table[idx].string; + B32 name_was_mapped = 0; + U64 name_hash = d_hash_from_string(name); + U64 name_slot_idx = name_hash%key_map->name_slots_count; + for(RD_KeyMapNode *n = key_map->name_slots[name_slot_idx].first; n != 0; n = n->name_hash_next) + { + if(str8_match(n->name, name, 0)) + { + name_was_mapped = 1; + break; + } + } + if(!name_was_mapped) + { + RD_Binding binding = rd_default_binding_table[idx].binding; + U64 binding_hash = d_hash_from_string(str8_struct(&binding)); + U64 binding_slot_idx = binding_hash%key_map->binding_slots_count; + RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1); + n->cfg = &rd_nil_cfg; + n->name = push_str8_copy(rd_frame_arena(), name); + n->binding = binding; + SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next); + SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next); + } + } + } + ////////////////////////////// //- rjf: get events from the OS // @@ -11774,7 +11809,7 @@ rd_frame(void) if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete)) { rd_request_frame(); - rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + // TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); rd_state->bind_change_active = 0; rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); } @@ -11798,8 +11833,8 @@ rd_frame(void) binding.key = event->key; binding.modifiers = event->modifiers; } - rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); - rd_bind_name(rd_state->bind_change_cmd_name, binding); + // TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + // TODO(rjf): @cfg rd_bind_name(rd_state->bind_change_cmd_name, binding); U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); os_text(&events, event->window, codepoint); os_eat_event(&events, event); @@ -11887,13 +11922,13 @@ rd_frame(void) if(!take && event->kind == OS_EventKind_Press) { RD_Binding binding = {event->key, event->modifiers}; - String8List spec_candidates = rd_cmd_name_list_from_binding(scratch.arena, binding); - if(spec_candidates.first != 0) + RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding); + if(key_map_nodes.first != 0) { U32 hit_char = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); if(hit_char == 0 || allow_text_hotkeys) { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = spec_candidates.first->string); + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = key_map_nodes.first->v->name); if(allow_text_hotkeys) { os_text(&events, event->window, hit_char); @@ -13118,6 +13153,7 @@ rd_frame(void) } //- rjf: apply keybindings +#if 0 // TODO(rjf): @cfg if(src == RD_CfgSrc_User) { rd_clear_bindings(); @@ -13150,7 +13186,15 @@ rd_frame(void) } else { - OS_Key k = rd_os_key_from_cfg_string(child->string); + OS_Key k = OS_Key_Null; + for EachEnumVal(OS_Key, key) + { + if(str8_match(child->string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive)) + { + k = key; + break; + } + } if(k != OS_Key_Null) { key = k; @@ -13180,6 +13224,7 @@ rd_frame(void) } } } +#endif //- rjf: reset theme to default MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); @@ -13362,6 +13407,7 @@ rd_frame(void) #endif //- rjf: if config bound 0 keys, we need to do some sensible default +#if 0 // TODO(rjf): @cfg if(src == RD_CfgSrc_User && rd_state->key_map_total_count == 0) { for(U64 idx = 0; idx < ArrayCount(rd_default_binding_table); idx += 1) @@ -13370,8 +13416,10 @@ rd_frame(void) rd_bind_name(pair->string, pair->binding); } } +#endif //- rjf: always ensure that the meta controls have bindings +#if 0 // TODO(rjf): @cfg if(src == RD_CfgSrc_User) { struct @@ -13395,6 +13443,7 @@ rd_frame(void) } } } +#endif }break; //- rjf: writing config changes diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 3e77d6cf..09bcb823 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -29,6 +29,38 @@ struct RD_HandleList U64 count; }; +//////////////////////////////// +//~ rjf: Binding Types + +typedef struct RD_Binding RD_Binding; +struct RD_Binding +{ + OS_Key key; + OS_Modifiers modifiers; +}; + +typedef struct RD_BindingNode RD_BindingNode; +struct RD_BindingNode +{ + RD_BindingNode *next; + RD_Binding binding; +}; + +typedef struct RD_BindingList RD_BindingList; +struct RD_BindingList +{ + RD_BindingNode *first; + RD_BindingNode *last; + U64 count; +}; + +typedef struct RD_StringBindingPair RD_StringBindingPair; +struct RD_StringBindingPair +{ + String8 string; + RD_Binding binding; +}; + //////////////////////////////// //~ rjf: Evaluation Spaces @@ -84,57 +116,6 @@ enum RD_EntityFlag_MarkedForDeletion = (1<<31), }; -//////////////////////////////// -//~ rjf: Binding Types - -typedef struct RD_Binding RD_Binding; -struct RD_Binding -{ - OS_Key key; - OS_Modifiers modifiers; -}; - -typedef struct RD_BindingNode RD_BindingNode; -struct RD_BindingNode -{ - RD_BindingNode *next; - RD_Binding binding; -}; - -typedef struct RD_BindingList RD_BindingList; -struct RD_BindingList -{ - RD_BindingNode *first; - RD_BindingNode *last; - U64 count; -}; - -typedef struct RD_StringBindingPair RD_StringBindingPair; -struct RD_StringBindingPair -{ - String8 string; - RD_Binding binding; -}; - -//////////////////////////////// -//~ rjf: Key Map Types - -typedef struct RD_KeyMapNode RD_KeyMapNode; -struct RD_KeyMapNode -{ - RD_KeyMapNode *hash_next; - RD_KeyMapNode *hash_prev; - String8 name; - RD_Binding binding; -}; - -typedef struct RD_KeyMapSlot RD_KeyMapSlot; -struct RD_KeyMapSlot -{ - RD_KeyMapNode *first; - RD_KeyMapNode *last; -}; - //////////////////////////////// //~ rjf: Setting Types @@ -330,6 +311,50 @@ struct RD_CfgRec S32 pop_count; }; +//////////////////////////////// +//~ rjf: Key Map Types + +typedef struct RD_KeyMapNode RD_KeyMapNode; +struct RD_KeyMapNode +{ + RD_KeyMapNode *name_hash_next; + RD_KeyMapNode *binding_hash_next; + RD_Cfg *cfg; + String8 name; + RD_Binding binding; +}; + +typedef struct RD_KeyMapNodePtr RD_KeyMapNodePtr; +struct RD_KeyMapNodePtr +{ + RD_KeyMapNodePtr *next; + RD_KeyMapNode *v; +}; + +typedef struct RD_KeyMapNodePtrList RD_KeyMapNodePtrList; +struct RD_KeyMapNodePtrList +{ + RD_KeyMapNodePtr *first; + RD_KeyMapNodePtr *last; + U64 count; +}; + +typedef struct RD_KeyMapSlot RD_KeyMapSlot; +struct RD_KeyMapSlot +{ + RD_KeyMapNode *first; + RD_KeyMapNode *last; +}; + +typedef struct RD_KeyMap RD_KeyMap; +struct RD_KeyMap +{ + U64 name_slots_count; + RD_KeyMapSlot *name_slots; + U64 binding_slots_count; + RD_KeyMapSlot *binding_slots; +}; + //////////////////////////////// //~ rjf: New Panel Types (Queried From Config) @@ -550,6 +575,7 @@ struct RD_ListerItem FuzzyMatchRangeList description__matches; U64 group; B32 is_non_code; + B32 can_have_bindings; }; typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode; @@ -789,10 +815,13 @@ struct RD_State // rjf: dbgi match store DI_MatchStore *match_store; - // rjf: ambiguous path table + // rjf: ambiguous path table (constructed from-scratch each frame) U64 ambiguous_path_slots_count; RD_AmbiguousPathNode **ambiguous_path_slots; + // rjf: key map (constructed from-scratch each frame) + RD_KeyMap *key_map; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -890,11 +919,13 @@ struct RD_State RD_EntityListCache kind_caches[RD_EntityKind_COUNT]; // rjf: key map table +#if 0 // TODO(rjf): @cfg Arena *key_map_arena; U64 key_map_table_size; RD_KeyMapSlot *key_map_table; RD_KeyMapNode *free_key_map_node; U64 key_map_total_count; +#endif // rjf: bind change Arena *bind_change_arena; @@ -1121,6 +1152,9 @@ internal Rng2F32 rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg); +internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string); +internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding); + //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1303,14 +1337,6 @@ internal String8 rd_push_search_string(Arena *arena); //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: keybindings -internal OS_Key rd_os_key_from_cfg_string(String8 string); -internal void rd_clear_bindings(void); -internal RD_BindingList rd_bindings_from_name(Arena *arena, String8 name); -internal void rd_bind_name(String8 name, RD_Binding binding); -internal void rd_unbind_name(String8 name, RD_Binding binding); -internal String8List rd_cmd_name_list_from_binding(Arena *arena, RD_Binding binding); - //- rjf: colors internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 52e6df14..29e4915f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -25,6 +25,8 @@ // etc., all need to be merged, and optionally contextualized/filtered. // right-clicking a tab should be equivalent to spawning a command lister, // but only with commands that are directly +// +// [ ] r8 bitmap view rule seems incorrect? //////////////////////////////// //~ rjf: post-0.9.12 TODO notes diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 99cb299b..209bf857 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -95,26 +95,28 @@ internal void rd_cmd_binding_buttons(String8 name) { Temp scratch = scratch_begin(0, 0); - RD_BindingList bindings = rd_bindings_from_name(scratch.arena, name); + RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name); //- rjf: build buttons for each binding - for(RD_BindingNode *n = bindings.first; n != 0; n = n->next) + for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next) { - RD_Binding binding = n->binding; + RD_Binding binding = n->v->binding; B32 rebinding_active_for_this_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && rd_state->bind_change_binding.key == binding.key && rd_state->bind_change_binding.modifiers == binding.modifiers); //- rjf: grab all conflicts - String8List specs_with_binding = rd_cmd_name_list_from_binding(scratch.arena, binding); B32 has_conflicts = 0; - for(String8Node *n = specs_with_binding.first; n != 0; n = n->next) + RD_KeyMapNodePtrList nodes_with_this_binding = rd_key_map_node_ptr_list_from_binding(scratch.arena, binding); { - if(!str8_match(n->string, name, 0)) + for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next) { - has_conflicts = 1; - break; + if(!str8_match(n->v->name, n2->v->name, 0)) + { + has_conflicts = 1; + break; + } } } @@ -196,11 +198,11 @@ rd_cmd_binding_buttons(String8 name) if(ui_hovering(sig) && has_conflicts) UI_Tooltip { UI_PrefWidth(ui_children_sum(1)) rd_error_label(str8_lit("This binding conflicts with those for:")); - for(String8Node *n = specs_with_binding.first; n != 0; n = n->next) + for(RD_KeyMapNodePtr *n2 = nodes_with_this_binding.first; n2 != 0; n2 = n2->next) { - if(!str8_match(n->string, name, 0)) + if(!str8_match(n2->v->name, n->v->name, 0)) { - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n->string); + RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n2->v->name); ui_labelf("%S", info->display_name); } } @@ -219,7 +221,7 @@ rd_cmd_binding_buttons(String8 name) UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding")); if(ui_clicked(sig)) { - rd_unbind_name(name, binding); + // TODO(rjf): @cfg rd_unbind_name(name, binding); rd_state->bind_change_active = 0; } } From 62894c098a86e063fe99b72d64a26ed4044cd558 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 Jan 2025 15:25:49 -0800 Subject: [PATCH 010/755] further progress on unified lister interface --- src/raddbg/raddbg_core.c | 1333 ++++++++++++++++++++------------------ src/raddbg/raddbg_core.h | 64 +- 2 files changed, 741 insertions(+), 656 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d6d331af..024fcf8b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3127,7 +3127,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); - ws->lister_params_arena = arena_alloc(); + ws->lister_arena = arena_alloc(); ws->query_cmd_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); for EachEnumVal(RD_SettingCode, code) @@ -3137,6 +3137,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->setting_vals[code] = rd_setting_code_default_val_table[code]; } } + ws->lister_input_cursor = ws->lister_input_mark = txt_pt(1, 1); ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ws->setting_vals[RD_SettingCode_MainFontSize].s32 * (ws->last_dpi / 96.f); ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ws->setting_vals[RD_SettingCode_CodeFontSize].s32 * (ws->last_dpi / 96.f); ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); @@ -3203,17 +3204,17 @@ rd_window_frame(void) ////////////////////////////// //- rjf: unpack context // - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window)); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window)); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); - B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc; - B32 popup_open = rd_state->popup_active; - B32 query_is_open = (ws->query_cmd_name.size != 0); - B32 hover_eval_is_open = (!popup_open && - ws->hover_eval_string.size != 0 && - ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && - rd_state->frame_index-ws->hover_eval_last_frame_idx < 20); - if(!window_is_focused || popup_open) + B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); + B32 popup_is_open = (rd_state->popup_active); + B32 lister_is_open = (ws->lister_last_frame_idx+1 >= rd_state->frame_index); + B32 hover_eval_is_open = (!popup_is_open && + ws->hover_eval_string.size != 0 && + ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && + rd_state->frame_index-ws->hover_eval_last_frame_idx < 20); + if(!window_is_focused || popup_is_open) { ws->menu_bar_key_held = 0; } @@ -3816,669 +3817,763 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: prepare for active query + // + if(ws->query_cmd_name.size != 0) + { + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + if(ui_slot_press(UI_EventActionSlot_Accept)) + { + Temp scratch = scratch_begin(0, 0); + RD_RegsScope() + { + //rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); + rd_cmd(RD_CmdKind_CompleteQuery); + } + scratch_end(scratch); + } + rd_set_lister_query(.flags = 0xffffffff); + } //////////////////////////// //- rjf: build lister // ProfScope("build lister") - if(!ui_key_match(ws->lister_params.anchor_key, ui_key_zero()) && ws->lister_last_frame_idx+1 >= rd_state->frame_index) + if(ws->lister_last_frame_idx+1 >= rd_state->frame_index) { - String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); - String8 query_word = rd_lister_query_word_from_input_string_off(input, ws->lister_params.cursor_off); - String8 query_path = rd_lister_query_path_from_input_string_off(input, ws->lister_params.cursor_off); - UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); - if(!ui_box_is_nil(lister_root_box)) + Temp scratch = scratch_begin(0, 0); + DI_Scope *di_scope = di_scope_open(); + + ////////////////////////// + //- rjf: unpack + // + U64 input_cursor_off = ws->lister_params.cursor_off; + if(ws->lister_params.flags & RD_ListerFlag_LineEdit) { - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - 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); - - //- rjf: grab rdis - U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + input_cursor_off = ws->lister_input_cursor.column-1; + } + String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); + String8 query_word = rd_lister_query_word_from_input_string_off(input, input_cursor_off); + String8 query_path = rd_lister_query_path_from_input_string_off(input, input_cursor_off); + UI_Box *lister_anchor_box = ui_box_from_key(ws->lister_params.anchor_key); + 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); + + ////////////////////////// + //- rjf: grab rdis + // + 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) { - for(U64 idx = 0; idx < rdis_count; idx += 1) + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); + RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); + rdis[idx] = rdi; + } + } + + ////////////////////////// + //- rjf: unpack lister params + // + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + + ////////////////////////// + //- rjf: gather lister items + // + RD_ListerItemChunkList item_list = {0}; + { + //////////////////////// + //- rjf: gather locals + // + if(ws->lister_params.flags & RD_ListerFlag_Locals) + { + E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local (Member)"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } } } - //- rjf: unpack lister params - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - - //- rjf: gather lister items - RD_ListerItemChunkList item_list = {0}; + //////////////////////// + //- rjf: gather registers + // + if(ws->lister_params.flags & RD_ListerFlag_Registers) { - //- rjf: gather locals - if(ws->lister_params.flags & RD_ListerFlag_Locals) + Arch arch = thread->arch; + U64 reg_names_count = regs_reg_code_count_from_arch(arch); + U64 alias_names_count = regs_alias_code_count_from_arch(arch); + String8 *reg_names = regs_reg_code_string_table_from_arch(arch); + String8 *alias_names = regs_alias_code_string_table_from_arch(arch); + for(U64 idx = 0; idx < reg_names_count; idx += 1) { - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + if(reg_names[idx].size != 0) { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local (Member)"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - } - - //- rjf: gather registers - if(ws->lister_params.flags & RD_ListerFlag_Registers) - { - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - String8 display_name = reg_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Register"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - String8 display_name = alias_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Reg. Alias"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //- rjf: gather view rules - if(ws->lister_params.flags & RD_ListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - String8 display_name = spec->info.string; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - String8 description = spec->info.description; - FuzzyMatchRangeList description__matches = fuzzy_match_find(scratch.arena, query_word, description); - if(display_name__matches.count == display_name__matches.needle_part_count || - description__matches.count == description__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("View Rule"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .description = description, - .description__matches = description__matches); - } - } - } - } - - //- rjf: gather members - if(ws->lister_params.flags & RD_ListerFlag_Members) - { - // TODO(rjf) - } - - //- rjf: gather globals - if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Global"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather thread locals - if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Thread Local"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather procedures - if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Procedure"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather types - if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Type"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather languages - if(ws->lister_params.flags & RD_ListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - String8 display_name = txt_extension_from_lang_kind(lang); - if(display_name.size != 0) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Language"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //- rjf: gather architectures - if(ws->lister_params.flags & RD_ListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - String8 display_name = string_from_arch(arch); + String8 display_name = reg_names[idx]; FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); if(display_name__matches.count == display_name__matches.needle_part_count) { rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, .string = display_name, - .kind_name = str8_lit("Architecture"), + .kind_name = str8_lit("Register"), .display_name = display_name, .display_name__matches = display_name__matches); } } } - - //- rjf: gather tex2dformats - if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) + for(U64 idx = 0; idx < alias_names_count; idx += 1) { - for EachEnumVal(R_Tex2DFormat, fmt) + if(alias_names[idx].size != 0) { - String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + String8 display_name = alias_names[idx]; FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); if(display_name__matches.count == display_name__matches.needle_part_count) { rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, .string = display_name, - .kind_name = str8_lit("2D Texture Format"), + .kind_name = str8_lit("Reg. Alias"), .display_name = display_name, .display_name__matches = display_name__matches); } } } - - //- rjf: gather view rule params - if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) + } + + //////////////////////// + //- rjf: gather view rules + // + if(ws->lister_params.flags & RD_ListerFlag_ViewRules) + { + for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) { - for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) + for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) { - String8 display_name = n->string; + String8 display_name = spec->info.string; FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) + String8 description = spec->info.description; + FuzzyMatchRangeList description__matches = fuzzy_match_find(scratch.arena, query_word, description); + if(display_name__matches.count == display_name__matches.needle_part_count || + description__matches.count == description__matches.needle_part_count) { rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, .string = display_name, - .kind_name = str8_lit("View Rule Parameter"), + .kind_name = str8_lit("View Rule"), .display_name = display_name, - .display_name__matches = display_name__matches); + .display_name__matches = display_name__matches, + .description = description, + .description__matches = description__matches); } } } - - //- rjf: gather files - if(ws->lister_params.flags & RD_ListerFlag_Files) + } + + //////////////////////// + //- rjf: gather members + // + if(ws->lister_params.flags & RD_ListerFlag_Members) + { + // TODO(rjf) + } + + //////////////////////// + //- rjf: gather globals + // + if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = { - // rjf: find containing directory in query_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < query_path.size; i += 1) + RDI_SectionKind_GlobalVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) { - String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } + continue; } - // rjf: use query_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Global"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //////////////////////// + //- rjf: gather thread locals + // + if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_ThreadVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Thread Local"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //////////////////////// + //- rjf: gather procedures + // + if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_Procedures, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Procedure"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //////////////////////// + //- rjf: gather types + // + if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_UDTs, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Type"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //////////////////////// + //- rjf: gather languages + // + if(ws->lister_params.flags & RD_ListerFlag_Languages) + { + for EachNonZeroEnumVal(TXT_LangKind, lang) + { + String8 display_name = txt_extension_from_lang_kind(lang); + if(display_name.size != 0) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Language"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //////////////////////// + //- rjf: gather architectures + // + if(ws->lister_params.flags & RD_ListerFlag_Architectures) + { + for EachNonZeroEnumVal(Arch, arch) + { + String8 display_name = string_from_arch(arch); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Architecture"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //////////////////////// + //- rjf: gather tex2dformats + // + if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) + { + for EachEnumVal(R_Tex2DFormat, fmt) + { + String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("2D Texture Format"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //////////////////////// + //- rjf: gather view rule params + // + if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) + { + for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) + { + String8 display_name = n->string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule Parameter"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //////////////////////// + //- rjf: gather files + // + if(ws->lister_params.flags & RD_ListerFlag_Files) + { + // rjf: find containing directory in query_path + String8 dir_str_in_input = {0}; + for(U64 i = 0; i < query_path.size; i += 1) + { + String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); + String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); + String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); + if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); + } + else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } + else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); + } if(dir_str_in_input.size != 0) { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) + break; + } + } + + // rjf: use query_path string to form various parts of search space + String8 prefix = {0}; + String8 path = {0}; + String8 search = {0}; + if(dir_str_in_input.size != 0) + { + String8 dir = dir_str_in_input; + U64 one_past_last_slash = dir.size; + for(U64 i = 0; i < dir_str_in_input.size; i += 1) + { + if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } + one_past_last_slash = i+1; } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); + } + dir.size = one_past_last_slash; + path = dir; + search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); + prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); + } + + // rjf: get current files, filtered + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); + B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = info.name, + .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), + .display_name = info.name, + .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, + .display_name__matches = match_ranges, + .is_non_code = 1); + } + } + os_file_iter_end(it); + } + + //////////////////////// + //- rjf: gather commands + // + if(ws->lister_params.flags & RD_ListerFlag_Commands) + { + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 cmd_display_name = info->display_name; + String8 cmd_desc = info->description; + String8 cmd_tags = info->search_tags; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, query_word, cmd_display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, query_word, cmd_desc); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, query_word, cmd_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == name_matches.needle_part_count || + tags_matches.count > 0 || + name_matches.needle_part_count == 0) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = info->icon_kind, + .string = info->string, + .kind_name = str8_lit("Command"), + .display_name = cmd_display_name, + .display_name__matches = name_matches, + .description = cmd_desc, + .description__matches = desc_matches, + .is_non_code = 1, + .can_have_bindings = 1); + } + } + } + } + + ////////////////////////// + //- rjf: lister item list -> sorted array + // + RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); + rd_lister_item_array_sort__in_place(&item_array); + + ////////////////////////// + //- rjf: animate values + // + F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); + F32 lister_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_open"), 1.f); + F32 lister_num_of_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_num_of_rows"), (F32)item_array.count); + ws->lister_scroll_pt.off -= ws->lister_scroll_pt.off*fast_rate; + + ////////////////////////// + //- rjf: unpack build parameters + // + F32 squish = ((ws->lister_params.squish != 0.f) ? ws->lister_params.squish : (0.25f - 0.25f*lister_open_t)); + F32 transparency = ((ws->lister_params.transparency != 0.f) ? ws->lister_params.transparency : 1.f-lister_open_t); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + { + row_height_px += floor_f32(ui_top_font_size()*3.5f); + } + Vec2F32 content_rect_dim = dim_2f32(content_rect); + Vec2F32 content_rect_center = center_2f32(content_rect); + F32 line_edit_height_px = 0; + if(ws->lister_params.flags & RD_ListerFlag_LineEdit) + { + line_edit_height_px = floor_f32(ui_top_font_size()*3.f); + } + F32 lister_height_max = content_rect_dim.y*0.9f; + Vec2F32 lister_dim_px = + { + content_rect_dim.x*0.5f, + line_edit_height_px + lister_num_of_rows_t*row_height_px, + }; + if(!ui_box_is_nil(lister_anchor_box)) + { + lister_dim_px.x = dim_2f32(lister_anchor_box->rect).x; + } + lister_dim_px.x = Max(lister_dim_px.x, ui_top_font_size()*30.f); + lister_dim_px.y = Min(lister_dim_px.y, lister_height_max); + Vec2F32 lister_pos_px = + { + content_rect_center.x - lister_dim_px.x/2, + content_rect_center.y - content_rect_dim.y*0.9f/2, + }; + if(!ui_box_is_nil(lister_anchor_box)) + { + lister_pos_px = v2f32(lister_anchor_box->rect.x0 + ws->lister_params.anchor_off.x, + lister_anchor_box->rect.y0 + ws->lister_params.anchor_off.y); + } + + ////////////////////////// + //- rjf: build top-level lister box + // + ui_set_next_fixed_x(lister_pos_px.x); + ui_set_next_fixed_y(lister_pos_px.y); + ui_set_next_pref_width(ui_px(lister_dim_px.x, 1.f)); + ui_set_next_pref_height(ui_px(lister_dim_px.y, 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); + ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); + UI_Focus(UI_FocusKind_On) + UI_Squish(squish) + UI_Transparency(transparency) + RD_Palette(RD_PaletteCode_Floating) + { + lister_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Clip| + UI_BoxFlag_RoundChildrenByParent| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackground, + "lister_box"); + } + + ////////////////////////// + //- rjf: build lister line edit + // + if(ws->lister_params.flags & RD_ListerFlag_LineEdit) + UI_WidthFill + UI_Parent(lister_box) + UI_Focus(UI_FocusKind_On) + { + UI_PrefHeight(ui_px(line_edit_height_px, 1.f)) + { + UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border, + 0, + 0, + &ws->lister_input_cursor, + &ws->lister_input_mark, + ws->lister_input_buffer, + sizeof(ws->lister_input_buffer), + &ws->lister_input_size, + 0, + str8(ws->lister_input_buffer, ws->lister_input_size), + str8_lit("###lister_text_input")); + } + } + + ////////////////////////// + //- rjf: build lister contents + // + UI_ScrollListParams params = + { + .flags = UI_ScrollListFlag_All, + .dim_px = v2f32(lister_dim_px.x, lister_dim_px.y - line_edit_height_px), + .row_height_px = row_height_px, + .cursor_range = r2s64(v2s64(0, 0), v2s64(0, item_array.count)), + .item_range = r1s64(0, item_array.count), + .cursor_min_is_empty_selection[Axis2_Y] = 1, + }; + Vec2S64 cursor = {0}; + Rng1S64 visible_row_range = {0}; + UI_ScrollListSignal scroll_list_signal = {0}; + UI_WidthFill UI_HeightFill + UI_Parent(lister_box) + UI_ScrollList(¶ms, &ws->lister_scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) + RD_Palette(RD_PaletteCode_ImplicitButton) + { + UI_HoverCursor(OS_Cursor_HandPoint) + for(S64 idx = visible_row_range.min; 0 <= idx && idx < visible_row_range.max && idx < item_array.count; idx += 1) + { + RD_ListerItem *item = &item_array.v[idx]; + + //- rjf: build the top-level box for the item + UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); + + //- rjf: build item contents + UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) + { + // rjf: icon + if(item->icon_kind != RD_IconKind_Null) + UI_PrefWidth(ui_em(2.f, 1.f)) + UI_Column + UI_Padding(ui_pct(1, 0)) + RD_Font(RD_FontSlot_Icons) + { + ui_label(rd_icon_kind_text_table[item->icon_kind]); } - // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + // rjf: name / description + UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); - B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) + // rjf: name + UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = info.name, - .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), - .display_name = info.name, - .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, - .display_name__matches = match_ranges, - .is_non_code = 1); + // rjf: display name + RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + UI_Box *box = item->is_non_code ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); + ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); + } + + // rjf: kind name + if(item->kind_name.size != 0) + { + ui_spacer(ui_em(1.f, 1.f)); + RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) + { + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_flags(UI_BoxFlag_DrawBorder); + UI_Row UI_Padding(ui_em(0.5f, 1.f)) + { + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); + ui_box_equip_display_string(box, item->kind_name); + } + } + } + } + + // rjf: description + if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + { + if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) + { + UI_Box *box = ui_label(item->description).box; + ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); + } } } - os_file_iter_end(it); - } - - //- rjf: gather commands - if(ws->lister_params.flags & RD_ListerFlag_Commands) - { - for EachNonZeroEnumVal(RD_CmdKind, k) + + // rjf: bindings + if(item->can_have_bindings) RD_Palette(RD_PaletteCode_Base) { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - String8 cmd_tags = info->search_tags; - FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, query_word, cmd_display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, query_word, cmd_desc); - FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, query_word, cmd_tags); - if(name_matches.count == name_matches.needle_part_count || - desc_matches.count == name_matches.needle_part_count || - tags_matches.count > 0 || - name_matches.needle_part_count == 0) + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .icon_kind = info->icon_kind, - .string = info->string, - .kind_name = str8_lit("Command"), - .display_name = cmd_display_name, - .display_name__matches = name_matches, - .description = cmd_desc, - .description__matches = desc_matches, - .is_non_code = 1, - .can_have_bindings = 1); + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) + { + rd_cmd_binding_buttons(item->string); + } } } } - } - - //- rjf: lister item list -> sorted array - RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); - rd_lister_item_array_sort__in_place(&item_array); - - //- rjf: animate - { - // rjf: animate target # of rows - { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - F32 target = Min((F32)item_array.count, 16.f); - if(abs_f32(target - ws->lister_num_visible_rows_t) > 0.01f) - { - rd_request_frame(); - } - ws->lister_num_visible_rows_t += (target - ws->lister_num_visible_rows_t) * rate; - if(abs_f32(target - ws->lister_num_visible_rows_t) <= 0.02f) - { - ws->lister_num_visible_rows_t = target; - } - } - // rjf: animate open + //- rjf: do interaction with top-level item + UI_Signal item_sig = ui_signal_from_box(item_box); + if(ui_clicked(item_sig)) { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - F32 diff = 1.f-ws->lister_open_t; - ws->lister_open_t += diff*rate; - if(abs_f32(diff) < 0.05f) - { - ws->lister_open_t = 1.f; - } - else - { - rd_request_frame(); - } + UI_Event move_back_evt = zero_struct; + move_back_evt.kind = UI_EventKind_Navigate; + move_back_evt.flags = UI_EventFlag_KeepMark; + move_back_evt.delta_2s32.x = -(S32)query_word.size; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); + UI_Event paste_evt = zero_struct; + paste_evt.kind = UI_EventKind_Text; + paste_evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); + } + else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); } } - - //- rjf: build - if(item_array.count != 0) - { - F32 squish = ws->lister_params.squish; - F32 transparency = ws->lister_params.transparency; - if(squish == 0.f) - { - squish = 0.25f - 0.25f*ws->lister_open_t; - } - if(transparency == 0.f) - { - transparency = 1.f-ws->lister_open_t; - } - F32 width_px = ui_box_is_nil(lister_root_box) ? (ui_top_font_size()*30.f) : dim_2f32(lister_root_box->rect).x; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - if(ws->lister_params.flags & RD_ListerFlag_Descriptions) - { - row_height_px += floor_f32(ui_top_font_size()*3.5f); - } - ui_set_next_fixed_x(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x); - ui_set_next_fixed_y(lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); - ui_set_next_pref_width(ui_px(width_px, 1.f)); - ui_set_next_pref_height(ui_px(row_height_px*ws->lister_num_visible_rows_t + ui_top_font_size()*2.f, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); - UI_Focus(UI_FocusKind_On) - UI_Squish(squish) - UI_Transparency(transparency) - RD_Palette(RD_PaletteCode_Floating) - { - lister_box = ui_build_box_from_stringf(UI_BoxFlag_DefaultFocusNavY| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - "lister_box"); - if(ws->lister_input_dirty) - { - ws->lister_input_dirty = 0; - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); - } - } - UI_Parent(lister_box) - UI_WidthFill - UI_PrefHeight(ui_px(row_height_px, 1.f)) - UI_HoverCursor(OS_Cursor_HandPoint) - UI_Focus(UI_FocusKind_Null) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_Padding(ui_em(1.f, 1.f)) - { - for(U64 idx = 0; idx < item_array.count; idx += 1) - { - RD_ListerItem *item = &item_array.v[idx]; - - //- rjf: build the top-level box for the item - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - - //- rjf: build item contents - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) - { - // rjf: icon - if(item->icon_kind != RD_IconKind_Null) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_Column - UI_Padding(ui_pct(1, 0)) - RD_Font(RD_FontSlot_Icons) - { - ui_label(rd_icon_kind_text_table[item->icon_kind]); - } - - // rjf: name / description - UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) - { - // rjf: name - UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) - { - // rjf: display name - RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - UI_Box *box = item->is_non_code ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); - ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); - } - - // rjf: kind name - if(item->kind_name.size != 0) - { - ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) - { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_flags(UI_BoxFlag_DrawBorder); - UI_Row UI_Padding(ui_em(0.5f, 1.f)) - { - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); - ui_box_equip_display_string(box, item->kind_name); - } - } - } - } - - // rjf: description - if(ws->lister_params.flags & RD_ListerFlag_Descriptions) - { - if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) - { - UI_Box *box = ui_label(item->description).box; - ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); - } - } - } - - // rjf: bindings - if(item->can_have_bindings) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) - { - rd_cmd_binding_buttons(item->string); - } - } - } - } - - //- rjf: do interaction with top-level item - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } - } - } - } - - di_scope_close(di_scope); - scratch_end(scratch); } + + di_scope_close(di_scope); + scratch_end(scratch); } +#if 0 // TODO(rjf): @cfg //////////////////////////// //- rjf: prepare query state for the in-progress query command // @@ -4711,6 +4806,7 @@ rd_window_frame(void) { ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); } +#endif //////////////////////////// //- rjf: top-level registers context menu @@ -6426,7 +6522,7 @@ rd_window_frame(void) //- rjf: build if good if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && (!query_is_open || !ws->query_input_selected)) ? UI_FocusKind_Null : UI_FocusKind_Off) + UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && !lister_is_open) ? UI_FocusKind_Null : UI_FocusKind_Off) { //- rjf: eval -> viz artifacts F32 row_height = floor_f32(ui_top_font_size()*2.8f); @@ -7041,7 +7137,7 @@ rd_window_frame(void) if(panel->first != &rd_nil_panel_node) {continue;} B32 panel_is_focused = (window_is_focused && !ws->menu_bar_focused && - (!query_is_open || !ws->query_input_selected) && + !lister_is_open && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused && panel_tree.focused == panel); @@ -10006,25 +10102,15 @@ rd_set_lister_query_(RD_ListerParams *params) { RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(params->cursor_off != ws->lister_params.cursor_off) - { - ws->lister_input_dirty = 1; - } - if(!ui_key_match(ws->lister_params.anchor_key, params->anchor_key)) - { - ws->lister_num_visible_rows_t = 0; - ws->lister_open_t = 0; - } - if(ws->lister_last_frame_idx+1 < rd_state->frame_index) - { - ws->lister_num_visible_rows_t = 0; - ws->lister_open_t = 0; - } - arena_clear(ws->lister_params_arena); + arena_clear(ws->lister_arena); + ws->lister_regs = rd_regs_copy(ws->lister_arena, rd_regs()); MemoryCopyStruct(&ws->lister_params, params); - ws->lister_params.strings = str8_list_copy(ws->lister_params_arena, &ws->lister_params.strings); - ws->lister_input_size = Min(params->input.size, sizeof(ws->lister_input_buffer)); - MemoryCopy(ws->lister_input_buffer, params->input.str, ws->lister_input_size); + ws->lister_params.strings = str8_list_copy(ws->lister_arena, &ws->lister_params.strings); + if(!(params->flags & RD_ListerFlag_LineEdit)) + { + ws->lister_input_size = Min(params->input.size, sizeof(ws->lister_input_buffer)); + MemoryCopy(ws->lister_input_buffer, params->input.str, ws->lister_input_size); + } ws->lister_last_frame_idx = rd_state->frame_index; } @@ -11602,7 +11688,7 @@ rd_frame(void) arena_release(ws->ctx_menu_arena); arena_release(ws->drop_completion_arena); arena_release(ws->hover_eval_arena); - arena_release(ws->lister_params_arena); + arena_release(ws->lister_arena); arena_release(ws->arena); DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); @@ -12403,12 +12489,10 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(wcfg); if(ws != 0) { - ws->query_cmd_gen += 1; arena_clear(ws->query_cmd_arena); ws->query_cmd_name = push_str8_copy(ws->query_cmd_arena, cmd->regs->cmd_name); ws->query_cmd_regs = rd_regs_copy(ws->query_cmd_arena, rd_regs()); MemoryZeroArray(ws->query_cmd_regs_mask); - ws->query_input_selected = 1; } } }break; @@ -13741,7 +13825,6 @@ rd_frame(void) RD_Cfg *window = rd_window_from_cfg(panel); RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; - ws->query_input_selected = 0; } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 09bcb823..1c5837dd 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -542,23 +542,24 @@ typedef U32 RD_ListerFlags; enum { //- rjf: lister visual settings - RD_ListerFlag_Descriptions = (1<<0), + RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user + RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) //- rjf: lister item sources - RD_ListerFlag_Locals = (1<<1), - RD_ListerFlag_Registers = (1<<2), - RD_ListerFlag_ViewRules = (1<<3), - RD_ListerFlag_ViewRuleParams= (1<<4), - RD_ListerFlag_Members = (1<<5), - RD_ListerFlag_Globals = (1<<6), - RD_ListerFlag_ThreadLocals = (1<<7), - RD_ListerFlag_Procedures = (1<<8), - RD_ListerFlag_Types = (1<<9), - RD_ListerFlag_Languages = (1<<10), - RD_ListerFlag_Architectures = (1<<11), - RD_ListerFlag_Tex2DFormats = (1<<12), - RD_ListerFlag_Files = (1<<13), - RD_ListerFlag_Commands = (1<<14), + RD_ListerFlag_Locals = (1<<2), + RD_ListerFlag_Registers = (1<<3), + RD_ListerFlag_ViewRules = (1<<4), + RD_ListerFlag_ViewRuleParams= (1<<5), + RD_ListerFlag_Members = (1<<6), + RD_ListerFlag_Globals = (1<<7), + RD_ListerFlag_ThreadLocals = (1<<8), + RD_ListerFlag_Procedures = (1<<9), + RD_ListerFlag_Types = (1<<10), + RD_ListerFlag_Languages = (1<<11), + RD_ListerFlag_Architectures = (1<<12), + RD_ListerFlag_Tex2DFormats = (1<<13), + RD_ListerFlag_Files = (1<<14), + RD_ListerFlag_Commands = (1<<15), }; typedef struct RD_ListerItem RD_ListerItem; @@ -619,6 +620,15 @@ struct RD_ListerParams //////////////////////////////// //~ rjf: Per-Window State +typedef struct RD_QueryMenu RD_QueryMenu; +struct RD_QueryMenu +{ + RD_QueryMenu *next; + Arena *arena; + RD_Regs *regs; + RD_RegSlot slot; +}; + typedef struct RD_WindowState RD_WindowState; struct RD_WindowState { @@ -668,26 +678,23 @@ struct RD_WindowState // rjf: lister state U64 lister_last_frame_idx; - B32 lister_input_dirty; - Arena *lister_params_arena; + Arena *lister_arena; + RD_Regs *lister_regs; RD_ListerParams lister_params; + UI_ScrollPt lister_scroll_pt; U8 lister_input_buffer[1024]; U64 lister_input_size; - F32 lister_open_t; - F32 lister_num_visible_rows_t; + TxtPt lister_input_cursor; + TxtPt lister_input_mark; + + // rjf: query menu stack + RD_QueryMenu *top_query_menu; // rjf: query view stack - U64 query_cmd_gen; Arena *query_cmd_arena; String8 query_cmd_name; RD_Regs *query_cmd_regs; U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; - U64 query_input_gen; - B32 query_input_selected; - U8 query_input_buffer[1024]; - U64 query_input_string_size; - TxtPt query_input_cursor; - TxtPt query_input_mark; // rjf: hover eval state B32 hover_eval_focused; @@ -1092,11 +1099,6 @@ internal RD_ViewRuleKind rd_view_rule_kind_from_string(String8 string); internal RD_ViewRuleInfo *rd_view_rule_info_from_kind(RD_ViewRuleKind kind); internal RD_ViewRuleInfo *rd_view_rule_info_from_string(String8 string); -//////////////////////////////// -//~ rjf: Panel Type Functions - - - //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions From 4ae032efffc9174c5c3d6bae640367ef7ed777bb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 15 Jan 2025 17:18:58 -0800 Subject: [PATCH 011/755] begin sketching out stuff for stateful listers being collapsed with immediate-mode autocomplete lister --- src/raddbg/generated/raddbg.meta.c | 7 ++-- src/raddbg/generated/raddbg.meta.h | 5 ++- src/raddbg/raddbg.mdesk | 7 ++-- src/raddbg/raddbg_core.c | 43 +++++++++++++------- src/raddbg/raddbg_core.h | 64 +++++++++++++++++------------- src/raddbg/raddbg_views.c | 34 ++++++++-------- 6 files changed, 92 insertions(+), 68 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f2a83f62..52f51110 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -229,7 +229,7 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[214] = +RD_CmdKindInfo rd_cmd_kind_info_table[215] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, @@ -441,8 +441,9 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_query"), str8_lit_comp("Completes a query."), str8_lit_comp(""), str8_lit_comp("Complete Query"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_query"), str8_lit_comp("Cancels a query."), str8_lit_comp(""), str8_lit_comp("Cancel Query"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e2d24b71..17dc9a13 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -298,8 +298,9 @@ RD_CmdKind_Settings, RD_CmdKind_PickFile, RD_CmdKind_PickFolder, RD_CmdKind_PickFileOrFolder, -RD_CmdKind_CompleteQuery, -RD_CmdKind_CancelQuery, +RD_CmdKind_PushLister, +RD_CmdKind_CompleteLister, +RD_CmdKind_CancelLister, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, RD_CmdKind_COUNT, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 7f6c02dc..ab8cbee8 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -477,9 +477,10 @@ RD_CmdTable: // | | | | {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" } {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" } - //- rjf: query completion - {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_query" "Complete Query" "Completes a query." "" } - {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_query" "Cancel Query" "Cancels a query." "" } + //- rjf: lister stack + {PushLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" } + {CompleteLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" } + {CancelLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" } //- rjf: developer commands {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 024fcf8b..5030148c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3824,7 +3824,7 @@ rd_window_frame(void) { if(ui_slot_press(UI_EventActionSlot_Cancel)) { - rd_cmd(RD_CmdKind_CancelQuery); + rd_cmd(RD_CmdKind_CancelLister); } if(ui_slot_press(UI_EventActionSlot_Accept)) { @@ -3832,11 +3832,11 @@ rd_window_frame(void) RD_RegsScope() { //rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); + rd_cmd(RD_CmdKind_CompleteLister); } scratch_end(scratch); } - rd_set_lister_query(.flags = 0xffffffff); + rd_set_autocomp_lister_query(.flags = 0xffffffff); } //////////////////////////// @@ -4701,13 +4701,13 @@ rd_window_frame(void) //- rjf: set up autocompletion lister info if(ui_is_focus_active()) { - rd_set_lister_query(.anchor_key = query_container_box->key, - .anchor_off = v2f32(0, dim_2f32(query_container_box->rect).y - dim_2f32(query_container_box->rect).y*(1-query_view_t)*0.25f - 2.f), - .flags = 0xffffffff, - .input = str8(ws->query_input_buffer, ws->query_input_string_size), - .cursor_off = ws->query_input_cursor.column-1, - .squish = query_squish, - .transparency= query_transparency); + rd_set_autocomp_lister_query(.anchor_key = query_container_box->key, + .anchor_off = v2f32(0, dim_2f32(query_container_box->rect).y - dim_2f32(query_container_box->rect).y*(1-query_view_t)*0.25f - 2.f), + .flags = 0xffffffff, + .input = str8(ws->query_input_buffer, ws->query_input_string_size), + .cursor_off = ws->query_input_cursor.column-1, + .squish = query_squish, + .transparency= query_transparency); } //- rjf: build query text input @@ -4778,7 +4778,7 @@ rd_window_frame(void) RD_RegsScope() { rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); + rd_cmd(RD_CmdKind_CompleteLister); } scratch_end(scratch); } @@ -10098,7 +10098,7 @@ rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 c } internal void -rd_set_lister_query_(RD_ListerParams *params) +rd_set_autocomp_lister_query_(RD_ListerParams *params) { RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); @@ -15589,8 +15589,21 @@ X(getting_started) #endif }break; - //- rjf: query completion - case RD_CmdKind_CompleteQuery: + //- rjf: lister stack + case RD_CmdKind_PushLister: + { + RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(cfg); + if(ws != &rd_nil_window_state) + { + Arena *arena = arena_alloc(); + RD_Lister *lister = push_array(arena, RD_Lister, 1); + SLLStackPush(ws->top_lister.next, lister); + lister->arena = arena; + lister->regs = rd_regs_copy(lister->arena, rd_regs()); + } + }break; + case RD_CmdKind_CompleteLister: { #if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); @@ -15636,7 +15649,7 @@ X(getting_started) } #endif }break; - case RD_CmdKind_CancelQuery: + case RD_CmdKind_CancelLister: { RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 1c5837dd..97f65a5f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -542,24 +542,26 @@ typedef U32 RD_ListerFlags; enum { //- rjf: lister visual settings - RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user - RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) + RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user + RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) //- rjf: lister item sources - RD_ListerFlag_Locals = (1<<2), - RD_ListerFlag_Registers = (1<<3), - RD_ListerFlag_ViewRules = (1<<4), - RD_ListerFlag_ViewRuleParams= (1<<5), - RD_ListerFlag_Members = (1<<6), - RD_ListerFlag_Globals = (1<<7), - RD_ListerFlag_ThreadLocals = (1<<8), - RD_ListerFlag_Procedures = (1<<9), - RD_ListerFlag_Types = (1<<10), - RD_ListerFlag_Languages = (1<<11), - RD_ListerFlag_Architectures = (1<<12), - RD_ListerFlag_Tex2DFormats = (1<<13), - RD_ListerFlag_Files = (1<<14), - RD_ListerFlag_Commands = (1<<15), + RD_ListerFlag_Locals = (1<<2), + RD_ListerFlag_Registers = (1<<3), + RD_ListerFlag_ViewRules = (1<<4), + RD_ListerFlag_ViewRuleParams = (1<<5), + RD_ListerFlag_Members = (1<<6), + RD_ListerFlag_Globals = (1<<7), + RD_ListerFlag_ThreadLocals = (1<<8), + RD_ListerFlag_Procedures = (1<<9), + RD_ListerFlag_Types = (1<<10), + RD_ListerFlag_Languages = (1<<11), + RD_ListerFlag_Architectures = (1<<12), + RD_ListerFlag_Tex2DFormats = (1<<13), + RD_ListerFlag_Files = (1<<14), + RD_ListerFlag_Commands = (1<<15), + RD_ListerFlag_Settings = (1<<16), + RD_ListerFlag_SystemProcesses= (1<<17), }; typedef struct RD_ListerItem RD_ListerItem; @@ -617,18 +619,23 @@ struct RD_ListerParams F32 transparency; }; -//////////////////////////////// -//~ rjf: Per-Window State - -typedef struct RD_QueryMenu RD_QueryMenu; -struct RD_QueryMenu +typedef struct RD_Lister RD_Lister; +struct RD_Lister { - RD_QueryMenu *next; + RD_Lister *next; Arena *arena; RD_Regs *regs; - RD_RegSlot slot; + RD_ListerParams params; + UI_ScrollPt scroll_pt; + U8 input_buffer[1024]; + U64 input_string_size; + TxtPt input_cursor; + TxtPt input_mark; }; +//////////////////////////////// +//~ rjf: Per-Window State + typedef struct RD_WindowState RD_WindowState; struct RD_WindowState { @@ -662,6 +669,10 @@ struct RD_WindowState B32 menu_bar_key_held; B32 menu_bar_focus_press_started; + // rjf: lister stack state + RD_Lister top_lister; // points to chain of stateful listers + U64 autocomp_lister_last_frame_idx; + // rjf: context menu state Arena *ctx_menu_arena; RD_Regs *ctx_menu_regs; @@ -687,9 +698,6 @@ struct RD_WindowState TxtPt lister_input_cursor; TxtPt lister_input_mark; - // rjf: query menu stack - RD_QueryMenu *top_query_menu; - // rjf: query view stack Arena *query_cmd_arena; String8 query_cmd_name; @@ -1327,8 +1335,8 @@ internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); -internal void rd_set_lister_query_(RD_ListerParams *params); -#define rd_set_lister_query(...) rd_set_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) +internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); +#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) //////////////////////////////// //~ rjf: Search Strings diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9270ef7b..625d7be6 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3171,7 +3171,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo params.anchor_off = v2f32(0, dim_2f32(sig.box->rect).y); params.input = input; params.cursor_off = cell_edit_state->cursor.column-1; - rd_set_lister_query_(¶ms); + rd_set_autocomp_lister_query_(¶ms); } } } @@ -3762,7 +3762,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(commands) //- rjf: submit best match when hitting enter w/ no selection if(cv->selected_cmd_hash == 0 && ui_slot_press(UI_EventActionSlot_Accept)) { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); + rd_cmd(RD_CmdKind_CompleteLister, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); } //- rjf: selected kind -> cursor @@ -3875,7 +3875,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(commands) UI_Signal sig = ui_signal_from_box(box); if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = item->cmd_name); + rd_cmd(RD_CmdKind_CompleteLister, .cmd_name = item->cmd_name); } } } @@ -4227,7 +4227,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) // rjf: command search part is empty, but directory matches some file: if(path_query_path_props.created != 0 && path_query.search.size == 0) { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = query_normalized_with_opt_slash); } // rjf: command argument exactly matches some file: @@ -4243,14 +4243,14 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) // rjf: is a file -> complete view else { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = query_normalized_with_opt_slash); } } // rjf: command argument is empty, picking folders -> use current folder else if(path_query.search.size == 0 && dir_selection) { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = path_query.path); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = path_query.path); } // rjf: command argument does not exactly match any file, but lister results are in: @@ -4266,14 +4266,14 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) else { String8 file_path = push_str8f(scratch.arena, "%S%S", path_query.path, filename); - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file_path); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = file_path); } } // rjf: command argument does not match any file, and lister is empty (new file) else { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = query); } } @@ -4472,7 +4472,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) } else { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = new_path); + rd_cmd(RD_CmdKind_CompleteLister, .file_path = new_path); } } } @@ -4693,7 +4693,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_slot_press(UI_EventActionSlot_Accept)) { RD_ProcessInfo *info = &process_info_array.v[0]; - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); + rd_cmd(RD_CmdKind_CompleteLister, .pid = info->info.pid); } //- rjf: selected PID -> cursor @@ -4781,7 +4781,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) // rjf: click => activate this specific process if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); + rd_cmd(RD_CmdKind_CompleteLister, .pid = info->info.pid); } } } @@ -4932,7 +4932,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) if(rd_entity_is_nil(rd_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) { RD_Entity *ent = ent_arr.v[0].entity; - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); + rd_cmd(RD_CmdKind_CompleteLister, .entity = rd_handle_from_entity(ent)); } //- rjf: selected entity -> cursor @@ -4997,7 +4997,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) } if(ui_clicked(ui_signal_from_box(box))) { - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); + rd_cmd(RD_CmdKind_CompleteLister, .entity = rd_handle_from_entity(ent)); } } } @@ -5148,7 +5148,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); + rd_cmd(RD_CmdKind_CompleteLister, .ctrl_entity = ent->handle); } } @@ -5224,7 +5224,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); + rd_cmd(RD_CmdKind_CompleteLister, .ctrl_entity = ent->handle); } } } @@ -5301,7 +5301,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) String8 name = str8(name_base, name_size); if(name.size != 0) { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); + rd_cmd(RD_CmdKind_CompleteLister, .string = name); } } } @@ -5373,7 +5373,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) UI_Signal sig = ui_signal_from_box(box); if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); + rd_cmd(RD_CmdKind_CompleteLister, .string = name); } if(ui_hovering(sig)) UI_Tooltip { From e6d0afb026a16c098763abfb3af73bc3b1894a92 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 17 Jan 2025 08:11:01 -0800 Subject: [PATCH 012/755] stateful query lister stack & immediate-mode autocompletion lister, via same codepath; begin hooking up views --- src/raddbg/generated/raddbg.meta.c | 13 +- src/raddbg/generated/raddbg.meta.h | 21 +- src/raddbg/raddbg.mdesk | 22 +- src/raddbg/raddbg_core.c | 1518 +++++++++++++++------------- src/raddbg/raddbg_core.h | 97 +- src/raddbg/raddbg_views.c | 69 +- 6 files changed, 921 insertions(+), 819 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 52f51110..7e56a987 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -191,7 +191,7 @@ RD_EntityKindFlags rd_entity_kind_flags_table[27] = (0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), }; -Rng1U64 rd_reg_slot_range_table[34] = +Rng1U64 rd_reg_slot_range_table[38] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -219,6 +219,10 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, voff), OffsetOf(RD_Regs, voff) + sizeof(U64)}, {OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)}, {OffsetOf(RD_Regs, voff_range), OffsetOf(RD_Regs, voff_range) + sizeof(Rng1U64)}, +{OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)}, +{OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)}, +{OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)}, +{OffsetOf(RD_Regs, reg_slot), OffsetOf(RD_Regs, reg_slot) + sizeof(RD_RegSlot)}, {OffsetOf(RD_Regs, pid), OffsetOf(RD_Regs, pid) + sizeof(U32)}, {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, @@ -229,7 +233,7 @@ Rng1U64 rd_reg_slot_range_table[34] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[215] = +RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, @@ -266,6 +270,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[215] = { str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, @@ -308,7 +313,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[215] = { str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, @@ -558,7 +563,7 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, {str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("run_command"), {OS_Key_F1, 0 }}, +{str8_lit_comp("open_lister"), {OS_Key_F1, 0 }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 17dc9a13..199f4738 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -75,6 +75,10 @@ RD_RegSlot_Vaddr, RD_RegSlot_Voff, RD_RegSlot_VaddrRange, RD_RegSlot_VoffRange, +RD_RegSlot_UIKey, +RD_RegSlot_OffPx, +RD_RegSlot_ListerFlags, +RD_RegSlot_RegSlot, RD_RegSlot_PID, RD_RegSlot_ForceConfirm, RD_RegSlot_PreferDisasm, @@ -123,6 +127,7 @@ RD_CmdKind_SetEntityColor, RD_CmdKind_SetEntityName, RD_CmdKind_Attach, RD_CmdKind_Exit, +RD_CmdKind_OpenLister, RD_CmdKind_RunCommand, RD_CmdKind_OSEvent, RD_CmdKind_SelectThread, @@ -298,9 +303,9 @@ RD_CmdKind_Settings, RD_CmdKind_PickFile, RD_CmdKind_PickFolder, RD_CmdKind_PickFileOrFolder, -RD_CmdKind_PushLister, -RD_CmdKind_CompleteLister, -RD_CmdKind_CancelLister, +RD_CmdKind_PushQuery, +RD_CmdKind_CompleteQuery, +RD_CmdKind_CancelQuery, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, RD_CmdKind_COUNT, @@ -567,6 +572,10 @@ U64 vaddr; U64 voff; Rng1U64 vaddr_range; Rng1U64 voff_range; +UI_Key ui_key; +Vec2F32 off_px; +RD_ListerFlags lister_flags; +RD_RegSlot reg_slot; U32 pid; B32 force_confirm; B32 prefer_disasm; @@ -638,6 +647,10 @@ RD_ViewRuleUIFunctionType *ui; .voff = rd_regs()->voff,\ .vaddr_range = rd_regs()->vaddr_range,\ .voff_range = rd_regs()->voff_range,\ +.ui_key = rd_regs()->ui_key,\ +.off_px = rd_regs()->off_px,\ +.lister_flags = rd_regs()->lister_flags,\ +.reg_slot = rd_regs()->reg_slot,\ .pid = rd_regs()->pid,\ .force_confirm = rd_regs()->force_confirm,\ .prefer_disasm = rd_regs()->prefer_disasm,\ @@ -766,7 +779,7 @@ extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[34]; +extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index ab8cbee8..33aa7c04 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -181,6 +181,12 @@ RD_RegTable: {Rng1U64 vaddr_range VaddrRange } {Rng1U64 voff_range VoffRange } + // rjf: ui context + {UI_Key ui_key UIKey } + {Vec2F32 off_px OffPx } + {RD_ListerFlags lister_flags ListerFlags } + {RD_RegSlot reg_slot RegSlot } + // rjf: general parameters {U32 pid PID } {B32 force_confirm ForceConfirm } @@ -228,6 +234,9 @@ RD_CmdTable: // | | | | //- rjf: exiting {Exit 1 1 Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" } + //- rjf: top-level lister + {OpenLister 1 1 Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" } + //- rjf: command runner {RunCommand 1 1 CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" } @@ -295,7 +304,7 @@ RD_CmdTable: // | | | | {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" } {MoveTabLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" } {OpenTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" } - {CloseTab 1 1 Null null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" } + {CloseTab 1 1 View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" } {MoveTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" } {TabBarTop 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" } {TabBarBottom 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" } @@ -477,10 +486,10 @@ RD_CmdTable: // | | | | {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" } {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" } - //- rjf: lister stack - {PushLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" } - {CompleteLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" } - {CancelLister 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" } + //- rjf: query stack + {PushQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" } + {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" } + {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" } //- rjf: developer commands {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" } @@ -685,7 +694,8 @@ RD_DefaultBindingTable: { "filter" Slash ctrl 0 0 } //- rjf: command lister - { "run_command" F1 0 0 0 } + // { "run_command" F1 0 0 0 } + { "open_lister" F1 0 0 0 } //- rjf: developer commands { "log_marker" M ctrl shift alt } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5030148c..17e67d8d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3127,8 +3127,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); - ws->lister_arena = arena_alloc(); - ws->query_cmd_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); for EachEnumVal(RD_SettingCode, code) { @@ -3137,7 +3135,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->setting_vals[code] = rd_setting_code_default_val_table[code]; } } - ws->lister_input_cursor = ws->lister_input_mark = txt_pt(1, 1); ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ws->setting_vals[RD_SettingCode_MainFontSize].s32 * (ws->last_dpi / 96.f); ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ws->setting_vals[RD_SettingCode_CodeFontSize].s32 * (ws->last_dpi / 96.f); ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); @@ -3209,7 +3206,7 @@ rd_window_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); B32 popup_is_open = (rd_state->popup_active); - B32 lister_is_open = (ws->lister_last_frame_idx+1 >= rd_state->frame_index); + B32 query_is_open = (ws->top_query_lister != 0); B32 hover_eval_is_open = (!popup_is_open && ws->hover_eval_string.size != 0 && ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && @@ -3346,6 +3343,36 @@ rd_window_frame(void) } } + ////////////////////////////// + //- rjf: gather listers + // + typedef struct ListerTask ListerTask; + struct ListerTask + { + ListerTask *next; + RD_Lister *lister; + UI_Key root_key; + }; + ListerTask *first_lister_task = 0; + ListerTask *last_lister_task = 0; + ProfScope("build all listers") + { + if(ws->autocomp_lister != 0 && ws->autocomp_lister_last_frame_idx+1 >= rd_state->frame_index) + { + ListerTask *task = push_array(scratch.arena, ListerTask, 1); + SLLQueuePush(first_lister_task, last_lister_task, task); + task->lister = ws->autocomp_lister; + task->root_key = ui_key_from_stringf(ui_key_zero(), "###lister_%p", task->lister); + } + if(ws->top_query_lister != 0) + { + ListerTask *task = push_array(scratch.arena, ListerTask, 1); + SLLQueuePush(first_lister_task, last_lister_task, task); + task->lister = ws->top_query_lister; + task->root_key = ui_key_from_stringf(ui_key_zero(), "###lister_%p", task->lister); + } + } + ////////////////////////////// //- rjf: build UI // @@ -3658,7 +3685,9 @@ rd_window_frame(void) { RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; String8 expr = rd_view_expr_string(); - view_ui(expr, view_preview_container->rect); + String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); + MD_Node *params = md_tree_from_string(scratch.arena, params_string); + view_ui(expr, params, view_preview_container->rect); } } } @@ -3743,7 +3772,7 @@ rd_window_frame(void) ui_divider(ui_em(1.f, 1.f)); //- rjf: draw per-window stats - for(RD_WindowState *w = rd_state->first_window_state; w != 0; w = w->order_next) + for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { // rjf: calc ui hash chain length F64 avg_ui_hash_chain_length = 0; @@ -3818,13 +3847,13 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: prepare for active query + //- rjf: do query lister stack controls // - if(ws->query_cmd_name.size != 0) + if(ws->top_query_lister != 0) { if(ui_slot_press(UI_EventActionSlot_Cancel)) { - rd_cmd(RD_CmdKind_CancelLister); + rd_cmd(RD_CmdKind_CancelQuery); } if(ui_slot_press(UI_EventActionSlot_Accept)) { @@ -3832,522 +3861,33 @@ rd_window_frame(void) RD_RegsScope() { //rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteLister); + rd_cmd(RD_CmdKind_CompleteQuery); } scratch_end(scratch); } - rd_set_autocomp_lister_query(.flags = 0xffffffff); } //////////////////////////// - //- rjf: build lister + //- rjf: build listers // - ProfScope("build lister") - if(ws->lister_last_frame_idx+1 >= rd_state->frame_index) + for(ListerTask *task = first_lister_task; task != 0; task = task->next) { - Temp scratch = scratch_begin(0, 0); DI_Scope *di_scope = di_scope_open(); ////////////////////////// //- rjf: unpack // - U64 input_cursor_off = ws->lister_params.cursor_off; - if(ws->lister_params.flags & RD_ListerFlag_LineEdit) - { - input_cursor_off = ws->lister_input_cursor.column-1; - } - String8 input = str8(ws->lister_input_buffer, ws->lister_input_size); - String8 query_word = rd_lister_query_word_from_input_string_off(input, input_cursor_off); - String8 query_path = rd_lister_query_path_from_input_string_off(input, input_cursor_off); - UI_Box *lister_anchor_box = ui_box_from_key(ws->lister_params.anchor_key); - 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); + RD_Lister *lister = task->lister; + RD_ListerFlags flags = lister->regs->lister_flags; + lister->regs->string = str8(lister->input_buffer, lister->input_string_size); + lister->regs->cursor = lister->input_cursor; + lister->regs->mark = lister->input_mark; + UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); ////////////////////////// - //- rjf: grab rdis + //- rjf: parameters -> lister items // - 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) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - ////////////////////////// - //- rjf: unpack lister params - // - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_base_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - - ////////////////////////// - //- rjf: gather lister items - // - RD_ListerItemChunkList item_list = {0}; - { - //////////////////////// - //- rjf: gather locals - // - if(ws->lister_params.flags & RD_ListerFlag_Locals) - { - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local (Member)"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - } - - //////////////////////// - //- rjf: gather registers - // - if(ws->lister_params.flags & RD_ListerFlag_Registers) - { - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - String8 display_name = reg_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Register"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - String8 display_name = alias_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Reg. Alias"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //////////////////////// - //- rjf: gather view rules - // - if(ws->lister_params.flags & RD_ListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - String8 display_name = spec->info.string; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - String8 description = spec->info.description; - FuzzyMatchRangeList description__matches = fuzzy_match_find(scratch.arena, query_word, description); - if(display_name__matches.count == display_name__matches.needle_part_count || - description__matches.count == description__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("View Rule"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .description = description, - .description__matches = description__matches); - } - } - } - } - - //////////////////////// - //- rjf: gather members - // - if(ws->lister_params.flags & RD_ListerFlag_Members) - { - // TODO(rjf) - } - - //////////////////////// - //- rjf: gather globals - // - if(ws->lister_params.flags & RD_ListerFlag_Globals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Global"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //////////////////////// - //- rjf: gather thread locals - // - if(ws->lister_params.flags & RD_ListerFlag_ThreadLocals && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Thread Local"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //////////////////////// - //- rjf: gather procedures - // - if(ws->lister_params.flags & RD_ListerFlag_Procedures && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Procedure"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //////////////////////// - //- rjf: gather types - // - if(ws->lister_params.flags & RD_ListerFlag_Types && query_word.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Type"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //////////////////////// - //- rjf: gather languages - // - if(ws->lister_params.flags & RD_ListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - String8 display_name = txt_extension_from_lang_kind(lang); - if(display_name.size != 0) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Language"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //////////////////////// - //- rjf: gather architectures - // - if(ws->lister_params.flags & RD_ListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - String8 display_name = string_from_arch(arch); - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Architecture"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - - //////////////////////// - //- rjf: gather tex2dformats - // - if(ws->lister_params.flags & RD_ListerFlag_Tex2DFormats) - { - for EachEnumVal(R_Tex2DFormat, fmt) - { - String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("2D Texture Format"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - - //////////////////////// - //- rjf: gather view rule params - // - if(ws->lister_params.flags & RD_ListerFlag_ViewRuleParams) - { - for(String8Node *n = ws->lister_params.strings.first; n != 0; n = n->next) - { - String8 display_name = n->string; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(scratch.arena, query_word, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("View Rule Parameter"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - - //////////////////////// - //- rjf: gather files - // - if(ws->lister_params.flags & RD_ListerFlag_Files) - { - // rjf: find containing directory in query_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < query_path.size; i += 1) - { - String8 substr1 = str8_substr(query_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(query_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(query_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i-1, query_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(query_path, r1u64(i, query_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - // rjf: use query_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(query_path, r1u64(0, path.str - query_path.str)); - } - - // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(scratch.arena, search, info.name); - B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = info.name, - .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), - .display_name = info.name, - .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, - .display_name__matches = match_ranges, - .is_non_code = 1); - } - } - os_file_iter_end(it); - } - - //////////////////////// - //- rjf: gather commands - // - if(ws->lister_params.flags & RD_ListerFlag_Commands) - { - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - String8 cmd_tags = info->search_tags; - FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, query_word, cmd_display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, query_word, cmd_desc); - FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, query_word, cmd_tags); - if(name_matches.count == name_matches.needle_part_count || - desc_matches.count == name_matches.needle_part_count || - tags_matches.count > 0 || - name_matches.needle_part_count == 0) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .icon_kind = info->icon_kind, - .string = info->string, - .kind_name = str8_lit("Command"), - .display_name = cmd_display_name, - .display_name__matches = name_matches, - .description = cmd_desc, - .description__matches = desc_matches, - .is_non_code = 1, - .can_have_bindings = 1); - } - } - } - } - - ////////////////////////// - //- rjf: lister item list -> sorted array - // - RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(scratch.arena, &item_list); - rd_lister_item_array_sort__in_place(&item_array); + RD_ListerItemArray item_array = rd_lister_item_array_from_regs(scratch.arena, lister->regs); ////////////////////////// //- rjf: animate values @@ -4355,22 +3895,22 @@ rd_window_frame(void) F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); F32 lister_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_open"), 1.f); F32 lister_num_of_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_num_of_rows"), (F32)item_array.count); - ws->lister_scroll_pt.off -= ws->lister_scroll_pt.off*fast_rate; + lister->scroll_pt.off -= lister->scroll_pt.off*fast_rate; ////////////////////////// //- rjf: unpack build parameters // - F32 squish = ((ws->lister_params.squish != 0.f) ? ws->lister_params.squish : (0.25f - 0.25f*lister_open_t)); - F32 transparency = ((ws->lister_params.transparency != 0.f) ? ws->lister_params.transparency : 1.f-lister_open_t); + F32 squish = (0.25f - 0.25f*lister_open_t); + F32 transparency = (1.f - lister_open_t); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + if(lister->regs->lister_flags & RD_ListerFlag_Descriptions) { row_height_px += floor_f32(ui_top_font_size()*3.5f); } Vec2F32 content_rect_dim = dim_2f32(content_rect); Vec2F32 content_rect_center = center_2f32(content_rect); F32 line_edit_height_px = 0; - if(ws->lister_params.flags & RD_ListerFlag_LineEdit) + if(lister->regs->lister_flags & RD_ListerFlag_LineEdit) { line_edit_height_px = floor_f32(ui_top_font_size()*3.f); } @@ -4380,9 +3920,9 @@ rd_window_frame(void) content_rect_dim.x*0.5f, line_edit_height_px + lister_num_of_rows_t*row_height_px, }; - if(!ui_box_is_nil(lister_anchor_box)) + if(!ui_box_is_nil(anchor_box)) { - lister_dim_px.x = dim_2f32(lister_anchor_box->rect).x; + lister_dim_px.x = dim_2f32(anchor_box->rect).x; } lister_dim_px.x = Max(lister_dim_px.x, ui_top_font_size()*30.f); lister_dim_px.y = Min(lister_dim_px.y, lister_height_max); @@ -4391,10 +3931,10 @@ rd_window_frame(void) content_rect_center.x - lister_dim_px.x/2, content_rect_center.y - content_rect_dim.y*0.9f/2, }; - if(!ui_box_is_nil(lister_anchor_box)) + if(!ui_box_is_nil(anchor_box)) { - lister_pos_px = v2f32(lister_anchor_box->rect.x0 + ws->lister_params.anchor_off.x, - lister_anchor_box->rect.y0 + ws->lister_params.anchor_off.y); + lister_pos_px = v2f32(anchor_box->rect.x0 + lister->regs->off_px.x, + anchor_box->rect.y0 + lister->regs->off_px.y); } ////////////////////////// @@ -4412,21 +3952,21 @@ rd_window_frame(void) UI_Transparency(transparency) RD_Palette(RD_PaletteCode_Floating) { - lister_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - "lister_box"); + lister_box = ui_build_box_from_key(UI_BoxFlag_Clickable| + UI_BoxFlag_Clip| + UI_BoxFlag_RoundChildrenByParent| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackground, + task->root_key); } ////////////////////////// //- rjf: build lister line edit // - if(ws->lister_params.flags & RD_ListerFlag_LineEdit) + if(flags & RD_ListerFlag_LineEdit) UI_WidthFill UI_Parent(lister_box) UI_Focus(UI_FocusKind_On) @@ -4436,13 +3976,13 @@ rd_window_frame(void) UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border, 0, 0, - &ws->lister_input_cursor, - &ws->lister_input_mark, - ws->lister_input_buffer, - sizeof(ws->lister_input_buffer), - &ws->lister_input_size, + &lister->input_cursor, + &lister->input_mark, + lister->input_buffer, + sizeof(lister->input_buffer), + &lister->input_string_size, 0, - str8(ws->lister_input_buffer, ws->lister_input_size), + str8(lister->input_buffer, lister->input_string_size), str8_lit("###lister_text_input")); } } @@ -4464,7 +4004,7 @@ rd_window_frame(void) UI_ScrollListSignal scroll_list_signal = {0}; UI_WidthFill UI_HeightFill UI_Parent(lister_box) - UI_ScrollList(¶ms, &ws->lister_scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) + UI_ScrollList(¶ms, &lister->scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) RD_Palette(RD_PaletteCode_ImplicitButton) { UI_HoverCursor(OS_Cursor_HandPoint) @@ -4519,7 +4059,7 @@ rd_window_frame(void) } // rjf: description - if(ws->lister_params.flags & RD_ListerFlag_Descriptions) + if(flags & RD_ListerFlag_Descriptions) { if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) { @@ -4548,6 +4088,7 @@ rd_window_frame(void) UI_Signal item_sig = ui_signal_from_box(item_box); if(ui_clicked(item_sig)) { +#if 0 // TODO(rjf): @cfg UI_Event move_back_evt = zero_struct; move_back_evt.kind = UI_EventKind_Navigate; move_back_evt.flags = UI_EventFlag_KeepMark; @@ -4558,6 +4099,7 @@ rd_window_frame(void) paste_evt.string = item->string; ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); +#endif } else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) { @@ -4570,7 +4112,6 @@ rd_window_frame(void) } di_scope_close(di_scope); - scratch_end(scratch); } #if 0 // TODO(rjf): @cfg @@ -4778,7 +4319,7 @@ rd_window_frame(void) RD_RegsScope() { rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteLister); + rd_cmd(RD_CmdKind_CompleteQuery); } scratch_end(scratch); } @@ -6522,7 +6063,7 @@ rd_window_frame(void) //- rjf: build if good if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && !lister_is_open) ? UI_FocusKind_Null : UI_FocusKind_Off) + UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && !query_is_open) ? UI_FocusKind_Null : UI_FocusKind_Off) { //- rjf: eval -> viz artifacts F32 row_height = floor_f32(ui_top_font_size()*2.8f); @@ -7137,14 +6678,15 @@ rd_window_frame(void) if(panel->first != &rd_nil_panel_node) {continue;} B32 panel_is_focused = (window_is_focused && !ws->menu_bar_focused && - !lister_is_open && + !query_is_open && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused && panel_tree.focused == panel); RD_Cfg *selected_tab = panel->selected_tab; RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); - UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) + UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) RD_RegsScope(.panel = rd_handle_from_cfg(panel->cfg), .view = rd_handle_from_cfg(selected_tab)) { @@ -7491,16 +7033,18 @@ rd_window_frame(void) //- rjf: build empty view UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) { - RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), content_rect); + RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), &md_nil_node, content_rect); } //- rjf: build tab view - UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) + UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") { String8 view_expr = rd_view_expr_string(); + String8 params_string = rd_string_from_cfg_tree(scratch.arena, selected_tab); + MD_Node *params = md_tree_from_string(scratch.arena, params_string); RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(selected_tab->string); RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - view_ui(view_expr, content_rect); + view_ui(view_expr, params, content_rect); } //- rjf: pop interaction registers; commit if this is the selected view @@ -7737,7 +7281,12 @@ rd_window_frame(void) } else if(ui_right_clicked(sig)) { - rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); + // rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands, + .reg_slot = RD_RegSlot_View); } else if(ui_middle_clicked(sig)) { @@ -8106,36 +7655,42 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: attach lister box to root, or hide if it has not been renewed + //- rjf: attach lister boxes to root, or hide if it has not been renewed // - if(!ui_box_is_nil(lister_box) && ws->lister_last_frame_idx+1 >= rd_state->frame_index+1) + for(ListerTask *task = first_lister_task; task != 0; task = task->next) { - UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); - if(!ui_box_is_nil(lister_root_box)) + RD_Lister *lister = task->lister; + RD_Regs *regs = lister->regs; + UI_Box *lister_box = ui_box_from_key(task->root_key); + if(!ui_box_is_nil(lister_box) && (lister != ws->autocomp_lister || ws->autocomp_lister_last_frame_idx+1 >= rd_state->frame_index+1)) { - Vec2F32 size = lister_box->fixed_size; - lister_box->fixed_position = v2f32(lister_root_box->rect.x0 + ws->lister_params.anchor_off.x, - lister_root_box->rect.y0 + ws->lister_params.anchor_off.y); - lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) + UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); + if(!ui_box_is_nil(anchor_box)) { - ui_calc_sizes_standalone__in_place_rec(lister_box, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(lister_box, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(lister_box, axis); - ui_layout_enforce_constraints__in_place_rec(lister_box, axis); - ui_layout_position__in_place_rec(lister_box, axis); + Vec2F32 size = lister_box->fixed_size; + lister_box->fixed_position = v2f32(anchor_box->rect.x0 + lister->regs->off_px.x, + anchor_box->rect.y0 + lister->regs->off_px.y); + lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); + for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) + { + ui_calc_sizes_standalone__in_place_rec(lister_box, axis); + ui_calc_sizes_upwards_dependent__in_place_rec(lister_box, axis); + ui_calc_sizes_downwards_dependent__in_place_rec(lister_box, axis); + ui_layout_enforce_constraints__in_place_rec(lister_box, axis); + ui_layout_position__in_place_rec(lister_box, axis); + } } } - } - else if(!ui_box_is_nil(lister_box) && ws->lister_last_frame_idx+1 < rd_state->frame_index+1) - { - UI_Box *lister_root_box = ui_box_from_key(ws->lister_params.anchor_key); - if(!ui_box_is_nil(lister_root_box)) + else if(!ui_box_is_nil(lister_box) && lister == ws->autocomp_lister && ws->autocomp_lister_last_frame_idx+1 < rd_state->frame_index+1) { - Vec2F32 size = lister_box->fixed_size; - Rng2F32 window_rect = os_client_rect_from_window(ws->os); - lister_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); - lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); + UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); + if(!ui_box_is_nil(anchor_box)) + { + Vec2F32 size = lister_box->fixed_size; + Rng2F32 window_rect = os_client_rect_from_window(ws->os); + lister_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); + lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); + } } } @@ -9815,7 +9370,7 @@ rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 s } //////////////////////////////// -//~ rjf: Auto-Complete Lister +//~ rjf: Lister Functions internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item) @@ -9906,6 +9461,477 @@ rd_lister_item_array_sort__in_place(RD_ListerItemArray *array) quick_sort(array->v, array->count, sizeof(array->v[0]), rd_lister_item_qsort_compare); } +internal RD_ListerItemArray +rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) +{ + Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); + RD_ListerFlags flags = regs->lister_flags; + String8 needle = regs->string; + U64 cursor_off = regs->cursor.column-1; + cursor_off = Clamp(0, cursor_off, needle.size); + String8 needle_path = rd_lister_query_path_from_input_string_off(needle, cursor_off); + RD_ListerItemChunkList item_list = {0}; + 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); + + ////////////////////////// + //- rjf: grab rdis + // + 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) + { + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); + RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); + rdis[idx] = rdi; + } + } + + //- rjf: gather locals + if(flags & RD_ListerFlag_Locals) + { + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); + for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = n->string, + .kind_name = str8_lit("Local (Member)"), + .display_name = n->string, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather registers + if(flags & RD_ListerFlag_Registers) + { + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + Arch arch = thread->arch; + U64 reg_names_count = regs_reg_code_count_from_arch(arch); + U64 alias_names_count = regs_alias_code_count_from_arch(arch); + String8 *reg_names = regs_reg_code_string_table_from_arch(arch); + String8 *alias_names = regs_alias_code_string_table_from_arch(arch); + for(U64 idx = 0; idx < reg_names_count; idx += 1) + { + if(reg_names[idx].size != 0) + { + String8 display_name = reg_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Register"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + for(U64 idx = 0; idx < alias_names_count; idx += 1) + { + if(alias_names[idx].size != 0) + { + String8 display_name = alias_names[idx]; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Reg. Alias"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather view rules + if(flags & RD_ListerFlag_ViewRules) + { + for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) + { + for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) + { + String8 display_name = spec->info.string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + String8 description = spec->info.description; + FuzzyMatchRangeList description__matches = fuzzy_match_find(arena, needle, description); + if(display_name__matches.count == display_name__matches.needle_part_count || + description__matches.count == description__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .description = description, + .description__matches = description__matches); + } + } + } + } + + //- rjf: gather members + if(flags & RD_ListerFlag_Members) + { + // TODO(rjf) + } + + //- rjf: gather globals + if(flags & RD_ListerFlag_Globals && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_GlobalVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Global"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather thread locals + if(flags & RD_ListerFlag_ThreadLocals && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_ThreadVariables, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Thread Local"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather procedures + if(flags & RD_ListerFlag_Procedures && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_Procedures, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Procedure"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather types + if(flags & RD_ListerFlag_Types && needle.size != 0) + { + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = + { + RDI_SectionKind_UDTs, + dbgi_keys, + }; + B32 is_stale = 0; + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); + for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) + { + // rjf: skip bad elements + if(items.v[idx].dbgi_idx >= rdis_count) + { + continue; + } + + // rjf: unpack info + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); + FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; + + // rjf: push item + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Type"), + .display_name = display_name, + .display_name__matches = display_name__matches, + .group = 1); + } + } + + //- rjf: gather languages + if(flags & RD_ListerFlag_Languages) + { + for EachNonZeroEnumVal(TXT_LangKind, lang) + { + String8 display_name = txt_extension_from_lang_kind(lang); + if(display_name.size != 0) + { + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Language"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + } + + //- rjf: gather architectures + if(flags & RD_ListerFlag_Architectures) + { + for EachNonZeroEnumVal(Arch, arch) + { + String8 display_name = string_from_arch(arch); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("Architecture"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather tex2dformats + if(flags & RD_ListerFlag_Tex2DFormats) + { + for EachEnumVal(R_Tex2DFormat, fmt) + { + String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("2D Texture Format"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } + + //- rjf: gather view rule params +#if 0 // TODO(rjf): @cfg + if(flags & RD_ListerFlag_ViewRuleParams) + { + for(String8Node *n = strings.first; n != 0; n = n->next) + { + String8 display_name = n->string; + FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); + if(display_name__matches.count == display_name__matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = display_name, + .kind_name = str8_lit("View Rule Parameter"), + .display_name = display_name, + .display_name__matches = display_name__matches); + } + } + } +#endif + + //- rjf: gather files + if(flags & RD_ListerFlag_Files) + { + // rjf: find containing directory in needle_path + String8 dir_str_in_input = {0}; + for(U64 i = 0; i < needle_path.size; i += 1) + { + String8 substr1 = str8_substr(needle_path, r1u64(i, i+1)); + String8 substr2 = str8_substr(needle_path, r1u64(i, i+2)); + String8 substr3 = str8_substr(needle_path, r1u64(i, i+3)); + if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i-1, needle_path.size)); + } + else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) + { + dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); + } + if(dir_str_in_input.size != 0) + { + break; + } + } + + // rjf: use needle_path string to form various parts of search space + String8 prefix = {0}; + String8 path = {0}; + String8 search = {0}; + if(dir_str_in_input.size != 0) + { + String8 dir = dir_str_in_input; + U64 one_past_last_slash = dir.size; + for(U64 i = 0; i < dir_str_in_input.size; i += 1) + { + if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') + { + one_past_last_slash = i+1; + } + } + dir.size = one_past_last_slash; + path = dir; + search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); + prefix = str8_substr(needle_path, r1u64(0, path.str - needle_path.str)); + } + + // rjf: get current files, filtered + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + FuzzyMatchRangeList match_ranges = fuzzy_match_find(arena, search, info.name); + B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = info.name, + .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), + .display_name = info.name, + .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, + .display_name__matches = match_ranges, + .is_non_code = 1); + } + } + os_file_iter_end(it); + } + + //- rjf: gather commands + if(flags & RD_ListerFlag_Commands) + { + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + if(info->query.slot == regs->reg_slot || regs->reg_slot == RD_RegSlot_Null) + { + String8 cmd_display_name = info->display_name; + String8 cmd_desc = info->description; + String8 cmd_tags = info->search_tags; + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, cmd_display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(arena, needle, cmd_desc); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(arena, needle, cmd_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == name_matches.needle_part_count || + tags_matches.count > 0 || + name_matches.needle_part_count == 0) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = info->icon_kind, + .string = info->string, + .kind_name = str8_lit("Command"), + .display_name = cmd_display_name, + .display_name__matches = name_matches, + .description = cmd_desc, + .description__matches = desc_matches, + .is_non_code = 1, + .can_have_bindings = 1); + } + } + } + } + + //- rjf: lister item list -> sorted array + RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(arena, &item_list); + rd_lister_item_array_sort__in_place(&item_array); + + di_scope_close(di_scope); + scratch_end(scratch); + return item_array; +} + internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) { @@ -9955,6 +9981,8 @@ rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } +#if 0 // TODO(rjf): @cfg + internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) { @@ -10114,6 +10142,31 @@ rd_set_autocomp_lister_query_(RD_ListerParams *params) ws->lister_last_frame_idx = rd_state->frame_index; } +#endif + +internal void +rd_set_autocomp_lister_query_(RD_Regs *regs) +{ + RD_Cfg *window_cfg = rd_cfg_from_handle(regs->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws->autocomp_lister == 0) + { + Arena *arena = arena_alloc(); + ws->autocomp_lister = push_array(arena, RD_Lister, 1); + ws->autocomp_lister->arena = arena; + } + Arena *arena = ws->autocomp_lister->arena; + arena_clear(arena); + ws->autocomp_lister = push_array(arena, RD_Lister, 1); + ws->autocomp_lister->arena = arena; + ws->autocomp_lister->regs = rd_regs_copy(arena, regs); + ws->autocomp_lister->input_string_size = Min(regs->string.size, sizeof(ws->autocomp_lister->input_buffer)); + MemoryCopy(ws->autocomp_lister->input_buffer, regs->string.str, ws->autocomp_lister->input_string_size); + ws->autocomp_lister->input_cursor = regs->cursor; + ws->autocomp_lister->input_mark = regs->mark; + ws->autocomp_lister_last_frame_idx = rd_state->frame_index; +} + //////////////////////////////// //~ rjf: Search Strings @@ -10595,7 +10648,7 @@ rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) if(source == RD_CfgSrc_User) { B32 first = 1; - for(RD_WindowState *window = rd_state->first_window_state; window != 0; window = window->order_next) + for(RD_WindowState *window = rd_state->first_window_state; window != &rd_nil_window_state; window = window->order_next) { if(first) { @@ -11684,11 +11737,17 @@ rd_frame(void) ui_state_release(ws->ui); r_window_unequip(ws->os, ws->r); os_window_close(ws->os); - arena_release(ws->query_cmd_arena); + if(ws->autocomp_lister != 0) + { + arena_release(ws->autocomp_lister->arena); + } + for(RD_Lister *lister = ws->top_query_lister; lister != 0; lister = lister->next) + { + arena_release(lister->arena); + } arena_release(ws->ctx_menu_arena); arena_release(ws->drop_completion_arena); arena_release(ws->hover_eval_arena); - arena_release(ws->lister_arena); arena_release(ws->arena); DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); @@ -11722,6 +11781,48 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: animate all views + // + if(depth == 0) + { + F32 slow_rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); + F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); + for EachIndex(slot_idx, rd_state->view_state_slots_count) + { + for(RD_ViewState *vs = rd_state->view_state_slots[slot_idx].first; + vs != 0; + vs = vs->hash_next) + { + F32 scroll_x_diff = (-vs->scroll_pos.x.off); + F32 scroll_y_diff = (-vs->scroll_pos.y.off); + F32 loading_t_diff = (vs->loading_t_target - vs->loading_t); + vs->scroll_pos.x.off += scroll_x_diff*fast_rate; + vs->scroll_pos.y.off += scroll_y_diff*fast_rate; + vs->loading_t += loading_t_diff * slow_rate; + if(abs_f32(loading_t_diff) > 0.01f || + abs_f32(scroll_x_diff) > 0.01f || + abs_f32(scroll_y_diff) > 0.01f) + { + rd_request_frame(); + } + if(abs_f32(scroll_x_diff) <= 0.01f) + { + vs->scroll_pos.x.off = 0; + } + if(abs_f32(scroll_y_diff) <= 0.01f) + { + vs->scroll_pos.y.off = 0; + } + RD_Cfg *vcfg = rd_cfg_from_handle(vs->cfg_handle); + if(rd_cfg_child_from_string(vcfg, str8_lit("selected")) != &rd_nil_cfg) + { + vs->loading_t_target = 0; + } + } + } + } + ////////////////////////////// //- rjf: build key map from config // @@ -12471,6 +12572,12 @@ rd_frame(void) } }break; + //- rjf: top-level lister + case RD_CmdKind_OpenLister: + { + rd_cmd(RD_CmdKind_PushQuery, .lister_flags = 0xffffffff); + }break; + //- rjf: command fast path case RD_CmdKind_RunCommand: { @@ -12485,15 +12592,7 @@ rd_frame(void) // rjf: command has required query -> prep query else { - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - if(ws != 0) - { - arena_clear(ws->query_cmd_arena); - ws->query_cmd_name = push_str8_copy(ws->query_cmd_arena, cmd->regs->cmd_name); - ws->query_cmd_regs = rd_regs_copy(ws->query_cmd_arena, rd_regs()); - MemoryZeroArray(ws->query_cmd_regs_mask); - } + rd_cmd(RD_CmdKind_PushQuery, .lister_flags = rd_regs()->lister_flags|RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Descriptions); } }break; @@ -14984,7 +15083,7 @@ X(getting_started) //- rjf: thread finding case RD_CmdKind_FindThread: - for(RD_WindowState *ws = rd_state->first_window_state; ws != 0; ws = ws->order_next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { DI_Scope *scope = di_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -15056,7 +15155,7 @@ X(getting_started) di_scope_close(scope); }break; case RD_CmdKind_FindSelectedThread: - for(RD_WindowState *ws = rd_state->first_window_state; ws != 0; ws = ws->order_next) + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); rd_cmd(RD_CmdKind_FindThread, @@ -15260,7 +15359,7 @@ X(getting_started) } // rjf: first, try to find panel/view pair that already has the src file open - RD_Cfg *panel_w_this_src_code = &rd_nil_cfg; + RD_PanelNode *panel_w_this_src_code = &rd_nil_panel_node; RD_Cfg *view_w_this_src_code = &rd_nil_cfg; for(RD_PanelNode *panel = panel_tree.root; panel != &rd_nil_panel_node; @@ -15274,42 +15373,46 @@ X(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } -#if 0 // TODO(rjf): @cfg - String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - if((view_kind == RD_ViewRuleKind_Text || view_kind == RD_ViewRuleKind_PendingFile) && - path_match_normalized(view_file_path, file_path)) + RD_RegsScope(.view = rd_handle_from_cfg(tab)) { - panel_w_this_src_code = panel; - view_w_this_src_code = view; - if(view == rd_selected_tab_from_panel(panel)) + String8 tab_expr = rd_view_expr_string(); + String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); + RD_ViewRuleKind tab_view_kind = rd_view_rule_kind_from_string(tab->string); + if((tab_view_kind == RD_ViewRuleKind_Text || tab_view_kind == RD_ViewRuleKind_PendingFile) && + path_match_normalized(tab_file_path, file_path)) { - break; + panel_w_this_src_code = panel; + view_w_this_src_code = tab; + if(tab == panel->selected_tab) + { + break; + } } } -#endif } } // rjf: find a panel that already has *any* code open (prioritize largest) RD_PanelNode *panel_w_any_src_code = &rd_nil_panel_node; -#if 0 // TODO(rjf): @cfg { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_PanelNode *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); if(view_kind == RD_ViewRuleKind_Text && panel_area > best_panel_area) { panel_w_any_src_code = panel; @@ -15319,227 +15422,208 @@ X(getting_started) } } } -#endif // rjf: try to find panel/view pair that has disassembly open (prioritize largest) -#if 0 // TODO(rjf): @cfg - RD_Panel *panel_w_disasm = &rd_nil_panel; - RD_View *view_w_disasm = &rd_nil_view; + RD_PanelNode *panel_w_disasm = &rd_nil_panel_node; + RD_Cfg *view_w_disasm = &rd_nil_cfg; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; - RD_View *panel_selected_tab = rd_selected_tab_from_panel(panel); - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) { - if(rd_view_is_project_filtered(view)) { continue; } - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 view_is_selected = (view == panel_selected_tab); - if(view_kind == RD_ViewRuleKind_Disasm && view->query_string_size == 0 && panel_area > best_panel_area) + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + RD_RegsScope(.view = rd_handle_from_cfg(tab)) { - panel_w_disasm = panel; - view_w_disasm = view; - best_panel_area = panel_area; - if(view_is_selected) + B32 tab_is_selected = (tab == panel->selected_tab); + RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); + String8 expr_string = rd_view_expr_string(); + if(view_kind == RD_ViewRuleKind_Disasm && expr_string.size == 0 && panel_area > best_panel_area) { - break; + panel_w_disasm = panel; + view_w_disasm = tab; + best_panel_area = panel_area; + if(tab_is_selected) + { + break; + } } } } } } -#endif // rjf: find the biggest panel -#if 0 // TODO(rjf): @cfg - RD_Panel *biggest_panel = &rd_nil_panel; + RD_PanelNode *biggest_panel = &rd_nil_panel_node; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); - F32 area = panel_rect_dim.x * panel_rect_dim.y; - if((best_panel_area == 0 || area > best_panel_area)) + F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; + if((best_panel_area == 0 || panel_area > best_panel_area)) { - best_panel_area = area; + best_panel_area = panel_area; biggest_panel = panel; } } } -#endif // rjf: find the biggest empty panel -#if 0 // TODO(rjf): @cfg - RD_Panel *biggest_empty_panel = &rd_nil_panel; + RD_PanelNode *biggest_empty_panel = &rd_nil_panel_node; { - Rng2F32 root_rect = os_client_rect_from_window(ws->os); + Rng2F32 root_rect = r2f32(v2f32(0, 0), v2f32(1000, 1000)); F32 best_panel_area = 0; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) + if(panel->first != &rd_nil_panel_node) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(root_rect, ws->root_panel, panel); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(root_rect, panel_tree.root, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); - F32 area = panel_rect_dim.x * panel_rect_dim.y; + F32 panel_area = panel_rect_dim.x*panel_rect_dim.y; B32 panel_is_empty = 1; - for(RD_View *v = panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - if(!rd_view_is_project_filtered(v)) + RD_Cfg *tab = n->v; + if(!rd_cfg_is_project_filtered(tab)) { panel_is_empty = 0; break; } } - if(panel_is_empty && (best_panel_area == 0 || area > best_panel_area)) + if(panel_is_empty && (best_panel_area == 0 || panel_area > best_panel_area)) { - best_panel_area = area; + best_panel_area = panel_area; biggest_empty_panel = panel; } } } -#endif // rjf: choose panel for source code -#if 0 // TODO(rjf): @cfg - RD_Panel *src_code_dst_panel = &rd_nil_panel; + RD_PanelNode *src_code_dst_panel = &rd_nil_panel_node; { - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = panel_w_this_src_code; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = panel_w_any_src_code; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_empty_panel; } - if(rd_panel_is_nil(src_code_dst_panel)) { src_code_dst_panel = biggest_panel; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_this_src_code; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_any_src_code; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_empty_panel; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_panel; } } -#endif // rjf: choose panel for disassembly -#if 0 // TODO(rjf): @cfg - RD_Panel *disasm_dst_panel = &rd_nil_panel; + RD_PanelNode *disasm_dst_panel = &rd_nil_panel_node; { - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = panel_w_disasm; } - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_empty_panel; } - if(rd_panel_is_nil(disasm_dst_panel)) { disasm_dst_panel = biggest_panel; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = panel_w_disasm; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = biggest_empty_panel; } + if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = biggest_panel; } } -#endif // rjf: if disasm and source code match: // if disasm preferred, cancel source // if source preferred, cancel disasm -#if 0 // TODO(rjf): @cfg if(disasm_dst_panel == src_code_dst_panel) { if(rd_regs()->prefer_disasm) { - src_code_dst_panel = &rd_nil_panel; + src_code_dst_panel = &rd_nil_panel_node; } else { - disasm_dst_panel = &rd_nil_panel; + disasm_dst_panel = &rd_nil_panel_node; } } -#endif // rjf: if disasm is not preferred, and we have no disassembly view // open at all, cancel disasm, so that it doesn't open if the user // doesn't want it. -#if 0 // TODO(rjf): @cfg - if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel) + if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel_node) { - disasm_dst_panel = &rd_nil_panel; + disasm_dst_panel = &rd_nil_panel_node; } -#endif // rjf: given the above, find source code location. -#if 0 // TODO(rjf): @cfg - if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel) + if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel_node) { - RD_Panel *dst_panel = src_code_dst_panel; + RD_PanelNode *dst_panel = src_code_dst_panel; // rjf: construct new view if needed - RD_View *dst_view = view_w_this_src_code; - if(!rd_panel_is_nil(dst_panel) && rd_view_is_nil(view_w_this_src_code)) + RD_Cfg *dst_tab = view_w_this_src_code; + if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) { - RD_View *view = rd_view_alloc(); - String8 file_path_query = rd_eval_string_from_file_path(scratch.arena, file_path); - rd_view_equip_spec(view, rd_view_rule_info_from_kind(RD_ViewRuleKind_Text), file_path_query, &md_nil_node); - rd_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); - dst_view = view; + dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("text")); + RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("query")); + rd_cfg_new(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); } // rjf: determine if we need a contain or center RD_CmdKind cursor_snap_kind = RD_CmdKind_CenterCursor; - if(!rd_panel_is_nil(dst_panel) && dst_view == view_w_this_src_code && rd_selected_tab_from_panel(dst_panel) == dst_view) + if(dst_panel != &rd_nil_panel_node && dst_tab == view_w_this_src_code && dst_panel->selected_tab == dst_tab) { cursor_snap_kind = RD_CmdKind_ContainCursor; } // rjf: move cursor & snap-to-cursor - if(!rd_panel_is_nil(dst_panel)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = rd_handle_from_cfg(dst_panel->cfg), + .view = rd_handle_from_cfg(dst_tab)) { - dst_panel->selected_tab_view = rd_handle_from_view(dst_view); - rd_cmd(RD_CmdKind_GoToLine, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view), - .cursor = point); - rd_cmd(cursor_snap_kind, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view)); + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_GoToLine, .cursor = point); + rd_cmd(cursor_snap_kind); } // rjf: record rd_cmd(RD_CmdKind_RecordFileInProject, .file_path = file_path); } -#endif // rjf: given the above, find disassembly location. -#if 0 // TODO(rjf): @cfg - if(process != &ctrl_entity_nil && vaddr != 0 && disasm_dst_panel != &rd_nil_panel) + if(process != &ctrl_entity_nil && vaddr != 0 && disasm_dst_panel != &rd_nil_panel_node) { - RD_Panel *dst_panel = disasm_dst_panel; + RD_PanelNode *dst_panel = disasm_dst_panel; - // rjf: construct new view if needed - RD_View *dst_view = view_w_disasm; - if(!rd_panel_is_nil(dst_panel) && rd_view_is_nil(view_w_disasm)) + // rjf: construct new tab if needed + RD_Cfg *dst_tab = view_w_disasm; + if(dst_panel != &rd_nil_panel_node && view_w_disasm == &rd_nil_cfg) { - RD_View *view = rd_view_alloc(); - rd_view_equip_spec(view, rd_view_rule_info_from_kind(RD_ViewRuleKind_Disasm), str8_zero(), &md_nil_node); - rd_panel_insert_tab_view(dst_panel, dst_panel->last_tab_view, view); - dst_view = view; + dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("disasm")); } // rjf: determine if we need a contain or center RD_CmdKind cursor_snap_kind = RD_CmdKind_CenterCursor; - if(dst_view == view_w_disasm && rd_selected_tab_from_panel(dst_panel) == dst_view) + if(dst_tab == view_w_disasm && dst_panel->selected_tab == dst_tab) { cursor_snap_kind = RD_CmdKind_ContainCursor; } // rjf: move cursor & snap-to-cursor - if(!rd_panel_is_nil(dst_panel)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = rd_handle_from_cfg(dst_panel->cfg), + .view = rd_handle_from_cfg(dst_tab)) { - dst_panel->selected_tab_view = rd_handle_from_view(dst_view); - rd_cmd(RD_CmdKind_GoToAddress, - .process = process->handle, .vaddr = vaddr, - .panel = rd_handle_from_panel(dst_panel), - .view = rd_handle_from_view(dst_view)); + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_GoToAddress, .process = process->handle, .vaddr = vaddr); rd_cmd(cursor_snap_kind); } } -#endif }break; //- rjf: filtering @@ -15589,21 +15673,24 @@ X(getting_started) #endif }break; - //- rjf: lister stack - case RD_CmdKind_PushLister: + //- rjf: query stack + case RD_CmdKind_PushQuery: { RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(cfg); + RD_WindowState *ws = rd_window_state_from_cfg(wcfg); if(ws != &rd_nil_window_state) { Arena *arena = arena_alloc(); RD_Lister *lister = push_array(arena, RD_Lister, 1); - SLLStackPush(ws->top_lister.next, lister); lister->arena = arena; lister->regs = rd_regs_copy(lister->arena, rd_regs()); + lister->input_string_size = Min(rd_regs()->string.size, sizeof(lister->input_buffer)); + lister->input_cursor = lister->input_mark = txt_pt(1, lister->input_string_size+1); + MemoryCopy(lister->input_buffer, rd_regs()->string.str, lister->input_string_size); + SLLStackPush(ws->top_query_lister, lister); } }break; - case RD_CmdKind_CompleteLister: + case RD_CmdKind_CompleteQuery: { #if 0 // TODO(rjf): @cfg RD_Window *ws = rd_window_from_handle(rd_regs()->window); @@ -15649,13 +15736,16 @@ X(getting_started) } #endif }break; - case RD_CmdKind_CancelLister: + case RD_CmdKind_CancelQuery: { RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); - arena_clear(ws->query_cmd_arena); - MemoryZeroStruct(&ws->query_cmd_name); - ws->query_cmd_regs = 0; + RD_Lister *top_lister = ws->top_query_lister; + if(top_lister != 0) + { + SLLStackPop(ws->top_query_lister); + arena_release(top_lister->arena); + } }break; //- rjf: developer commands diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 97f65a5f..5670d3c3 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -142,7 +142,7 @@ enum RD_ViewRuleInfoFlag_ProjectFiltered = (1<<7), }; -#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, Rng2F32 rect) +#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, MD_Node *params, Rng2F32 rect) #define RD_VIEW_RULE_UI_FUNCTION_NAME(name) rd_view_rule_ui_##name #define RD_VIEW_RULE_UI_FUNCTION_DEF(name) internal RD_VIEW_RULE_UI_FUNCTION_SIG(RD_VIEW_RULE_UI_FUNCTION_NAME(name)) typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); @@ -169,6 +169,7 @@ struct RD_ViewState U64 last_frame_index_touched; // rjf: loading indicator info + F32 loading_t; F32 loading_t_target; U64 loading_progress_v; U64 loading_progress_v_target; @@ -230,6 +231,35 @@ enum RD_CmdKindFlag_ListInIPCDocs = (1<<1), }; +//////////////////////////////// +//~ rjf: Lister Flags + +typedef U32 RD_ListerFlags; +enum +{ + //- rjf: lister visual settings + RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user + RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) + + //- rjf: lister item sources + RD_ListerFlag_Locals = (1<<2), + RD_ListerFlag_Registers = (1<<3), + RD_ListerFlag_ViewRules = (1<<4), + RD_ListerFlag_ViewRuleParams = (1<<5), + RD_ListerFlag_Members = (1<<6), + RD_ListerFlag_Globals = (1<<7), + RD_ListerFlag_ThreadLocals = (1<<8), + RD_ListerFlag_Procedures = (1<<9), + RD_ListerFlag_Types = (1<<10), + RD_ListerFlag_Languages = (1<<11), + RD_ListerFlag_Architectures = (1<<12), + RD_ListerFlag_Tex2DFormats = (1<<13), + RD_ListerFlag_Files = (1<<14), + RD_ListerFlag_Commands = (1<<15), + RD_ListerFlag_Settings = (1<<16), + RD_ListerFlag_SystemProcesses= (1<<17), +}; + //////////////////////////////// //~ rjf: Generated Code @@ -538,32 +568,6 @@ RD_PaletteCode; //////////////////////////////// //~ rjf: Lister Types -typedef U32 RD_ListerFlags; -enum -{ - //- rjf: lister visual settings - RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user - RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) - - //- rjf: lister item sources - RD_ListerFlag_Locals = (1<<2), - RD_ListerFlag_Registers = (1<<3), - RD_ListerFlag_ViewRules = (1<<4), - RD_ListerFlag_ViewRuleParams = (1<<5), - RD_ListerFlag_Members = (1<<6), - RD_ListerFlag_Globals = (1<<7), - RD_ListerFlag_ThreadLocals = (1<<8), - RD_ListerFlag_Procedures = (1<<9), - RD_ListerFlag_Types = (1<<10), - RD_ListerFlag_Languages = (1<<11), - RD_ListerFlag_Architectures = (1<<12), - RD_ListerFlag_Tex2DFormats = (1<<13), - RD_ListerFlag_Files = (1<<14), - RD_ListerFlag_Commands = (1<<15), - RD_ListerFlag_Settings = (1<<16), - RD_ListerFlag_SystemProcesses= (1<<17), -}; - typedef struct RD_ListerItem RD_ListerItem; struct RD_ListerItem { @@ -606,26 +610,12 @@ struct RD_ListerItemArray U64 count; }; -typedef struct RD_ListerParams RD_ListerParams; -struct RD_ListerParams -{ - UI_Key anchor_key; - Vec2F32 anchor_off; - RD_ListerFlags flags; - String8List strings; - String8 input; - U64 cursor_off; - F32 squish; - F32 transparency; -}; - typedef struct RD_Lister RD_Lister; struct RD_Lister { RD_Lister *next; Arena *arena; RD_Regs *regs; - RD_ListerParams params; UI_ScrollPt scroll_pt; U8 input_buffer[1024]; U64 input_string_size; @@ -669,8 +659,9 @@ struct RD_WindowState B32 menu_bar_key_held; B32 menu_bar_focus_press_started; - // rjf: lister stack state - RD_Lister top_lister; // points to chain of stateful listers + // rjf: lister state + RD_Lister *top_query_lister; + RD_Lister *autocomp_lister; U64 autocomp_lister_last_frame_idx; // rjf: context menu state @@ -687,22 +678,13 @@ struct RD_WindowState Arena *drop_completion_arena; String8List drop_completion_paths; - // rjf: lister state - U64 lister_last_frame_idx; - Arena *lister_arena; - RD_Regs *lister_regs; - RD_ListerParams lister_params; - UI_ScrollPt lister_scroll_pt; - U8 lister_input_buffer[1024]; - U64 lister_input_size; - TxtPt lister_input_cursor; - TxtPt lister_input_mark; - // rjf: query view stack +#if 0 Arena *query_cmd_arena; String8 query_cmd_name; RD_Regs *query_cmd_regs; U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; +#endif // rjf: hover eval state B32 hover_eval_focused; @@ -1324,19 +1306,24 @@ internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string); //////////////////////////////// -//~ rjf: Lister +//~ rjf: Lister Functions internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item); #define rd_lister_item_chunk_list_push_new(arena, list, cap, ...) rd_lister_item_chunk_list_push((arena), (list), (cap), &(RD_ListerItem){.string = {0}, __VA_ARGS__}) internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); +internal RD_ListerItemArray rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs); internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); +#if 0 // TODO(rjf): @cfg internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); #define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) +#endif +internal void rd_set_autocomp_lister_query_(RD_Regs *regs); +#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) //////////////////////////////// //~ rjf: Search Strings diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 625d7be6..eaa496e1 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -7,6 +7,7 @@ internal void rd_code_view_init(RD_CodeViewState *cv) { + ProfBeginFunction(); if(cv->initialized == 0) { cv->initialized = 1; @@ -15,6 +16,7 @@ rd_code_view_init(RD_CodeViewState *cv) cv->center_cursor = 1; rd_store_view_loading_info(1, 0, 0); } + ProfEnd(); } internal RD_CodeViewBuildResult @@ -3122,7 +3124,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo UI_Parent(box) { String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); + cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); } sig = ui_signal_from_box(box); } @@ -3158,20 +3160,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - RD_ListerParams params = {cell_autocomp_flags}; - if(col->kind == RD_WatchViewColumnKind_ViewRule) - { - params = rd_view_rule_lister_params_from_input_cursor(scratch.arena, input, cell_edit_state->cursor.column-1); - if(params.flags == 0) - { - params.flags = cell_autocomp_flags; - } - } - params.anchor_key = sig.box->key; - params.anchor_off = v2f32(0, dim_2f32(sig.box->rect).y); - params.input = input; - params.cursor_off = cell_edit_state->cursor.column-1; - rd_set_autocomp_lister_query_(¶ms); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); } } } @@ -3762,7 +3755,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(commands) //- rjf: submit best match when hitting enter w/ no selection if(cv->selected_cmd_hash == 0 && ui_slot_press(UI_EventActionSlot_Accept)) { - rd_cmd(RD_CmdKind_CompleteLister, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); + rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); } //- rjf: selected kind -> cursor @@ -3875,7 +3868,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(commands) UI_Signal sig = ui_signal_from_box(box); if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteLister, .cmd_name = item->cmd_name); + rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = item->cmd_name); } } } @@ -4227,7 +4220,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) // rjf: command search part is empty, but directory matches some file: if(path_query_path_props.created != 0 && path_query.search.size == 0) { - rd_cmd(RD_CmdKind_CompleteLister, .file_path = query_normalized_with_opt_slash); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); } // rjf: command argument exactly matches some file: @@ -4243,14 +4236,14 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) // rjf: is a file -> complete view else { - rd_cmd(RD_CmdKind_CompleteLister, .file_path = query_normalized_with_opt_slash); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); } } // rjf: command argument is empty, picking folders -> use current folder else if(path_query.search.size == 0 && dir_selection) { - rd_cmd(RD_CmdKind_CompleteLister, .file_path = path_query.path); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = path_query.path); } // rjf: command argument does not exactly match any file, but lister results are in: @@ -4266,14 +4259,14 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) else { String8 file_path = push_str8f(scratch.arena, "%S%S", path_query.path, filename); - rd_cmd(RD_CmdKind_CompleteLister, .file_path = file_path); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file_path); } } // rjf: command argument does not match any file, and lister is empty (new file) else { - rd_cmd(RD_CmdKind_CompleteLister, .file_path = query); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query); } } @@ -4472,7 +4465,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) } else { - rd_cmd(RD_CmdKind_CompleteLister, .file_path = new_path); + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = new_path); } } } @@ -4693,7 +4686,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_slot_press(UI_EventActionSlot_Accept)) { RD_ProcessInfo *info = &process_info_array.v[0]; - rd_cmd(RD_CmdKind_CompleteLister, .pid = info->info.pid); + rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); } //- rjf: selected PID -> cursor @@ -4781,7 +4774,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) // rjf: click => activate this specific process if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteLister, .pid = info->info.pid); + rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); } } } @@ -4932,7 +4925,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) if(rd_entity_is_nil(rd_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) { RD_Entity *ent = ent_arr.v[0].entity; - rd_cmd(RD_CmdKind_CompleteLister, .entity = rd_handle_from_entity(ent)); + rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); } //- rjf: selected entity -> cursor @@ -4997,7 +4990,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) } if(ui_clicked(ui_signal_from_box(box))) { - rd_cmd(RD_CmdKind_CompleteLister, .entity = rd_handle_from_entity(ent)); + rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); } } } @@ -5148,7 +5141,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; } - rd_cmd(RD_CmdKind_CompleteLister, .ctrl_entity = ent->handle); + rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); } } @@ -5224,7 +5217,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; } - rd_cmd(RD_CmdKind_CompleteLister, .ctrl_entity = ent->handle); + rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); } } } @@ -5301,7 +5294,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) String8 name = str8(name_base, name_size); if(name.size != 0) { - rd_cmd(RD_CmdKind_CompleteLister, .string = name); + rd_cmd(RD_CmdKind_CompleteQuery, .string = name); } } } @@ -5373,7 +5366,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) UI_Signal sig = ui_signal_from_box(box); if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_CompleteLister, .string = name); + rd_cmd(RD_CmdKind_CompleteQuery, .string = name); } if(ui_hovering(sig)) UI_Tooltip { @@ -5840,7 +5833,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: process code-file commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + ProfScope("process code-file commands") for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) @@ -5874,29 +5867,33 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: unpack parameterization info // + ProfBegin("unpack parameterization info"); String8 path = rd_file_path_from_eval_string(rd_frame_arena(), string); rd_regs()->file_path = path; rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; -#if 0 // TODO(rjf): @cfg rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; -#endif if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); + Rng1U64 range = rd_range_from_eval_params(eval, params); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = TXT_LangKind_Null; // TODO(rjf): @cfg rd_lang_kind_from_eval_params(eval, params); + rd_regs()->lang_kind = rd_lang_kind_from_eval_params(eval, params); + if(rd_regs()->lang_kind == TXT_LangKind_Null && path.size != 0) + { + rd_regs()->lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(path)); + } U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); B32 file_is_missing = (path.size != 0 && os_properties_from_file_path(path).modified == 0); B32 key_has_data = !u128_match(hash, u128_zero()) && info.lines_count; + ProfEnd(); ////////////////////////////// //- rjf: build missing file interface From 069084c108110e526e1f13a2e0160387b3fb5606 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 17 Jan 2025 10:35:04 -0800 Subject: [PATCH 013/755] fix view parameter storage hook to not repeatedly duplicate key values --- src/raddbg/raddbg_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 17e67d8d..c851cae2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3016,10 +3016,13 @@ internal void rd_store_view_param(String8 key, String8 value) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); - RD_Cfg *child = rd_cfg_child_from_string(view, key); - if(child == &rd_nil_cfg) + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(view, key); + for(RD_Cfg *val_child = child->first, *next = &rd_nil_cfg; + val_child != &rd_nil_cfg; + val_child = next) { - child = rd_cfg_new(view, key); + next = val_child->next; + rd_cfg_release(val_child); } rd_cfg_new(child, value); } From 4371d727fb54a10ea1e9c08d6bb19d87e45dded5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 17 Jan 2025 13:34:18 -0800 Subject: [PATCH 014/755] line expressions in eval lang; begin getting off of entities for breakpoints/watch-pins/etc., move -> cfg --- src/eval/eval.mdesk | 2 + src/eval/eval_ir.c | 45 +++ src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/generated/raddbg.meta.h | 8 +- src/raddbg/raddbg.mdesk | 2 + src/raddbg/raddbg_core.c | 442 +++++++++++++---------------- src/raddbg/raddbg_core.h | 19 ++ src/raddbg/raddbg_views.c | 68 ++--- src/raddbg/raddbg_widgets.c | 83 +++--- src/raddbg/raddbg_widgets.h | 4 +- 12 files changed, 366 insertions(+), 322 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index f6de6560..0c7aba70 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -132,6 +132,8 @@ E_ExprKindTable: { Array Null 0 "array" "" "" "" } { Func Null 0 "function" "" "" "" } + { Line Binary 1 ":" "" ":" "" } + { Define Binary 13 "=" "" "=" "" } } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9c08b133..49fdda40 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1337,6 +1337,51 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Type expression not expected."); }break; + //- rjf: textual line slicing + case E_ExprKind_Line: + { + E_Expr *lhs = expr->first; + E_Expr *rhs = expr->last; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_Space space = lhs_irtree.space; + U64 line_num = rhs->value.u64; + B32 space_is_good = 1; + if(lhs_irtree.root->op != E_IRExtKind_SetSpace) + { + space_is_good = 0; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, lhs->location, "Cannot take a line from a non-file."); + } + B32 line_num_is_good = 1; + if(rhs->kind != E_ExprKind_LeafU64) + { + line_num_is_good = 0; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, rhs->location, "Line number must be specified as a constant number."); + } + if(space_is_good && line_num_is_good) + { + TXT_Scope *txt_scope = txt_scope_open(); + U128 key = space.u128; + U128 hash = {0}; + TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, TXT_LangKind_Null, &hash); + if(1 <= line_num && line_num <= text_info.lines_count) + { + Rng1U64 line_range = text_info.lines_ranges[line_num-1]; + U64 line_size = dim_1u64(line_range); + E_IRNode *line_offset = e_irtree_const_u(arena, line_range.min); + E_IRNode *set_space = e_irtree_set_space(arena, space, line_offset); + result.root = set_space; + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size); + result.mode = E_Mode_Offset; + result.space = space; + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, rhs->location, "Line %I64u is out of bounds.", line_num); + } + txt_scope_close(txt_scope); + } + }break; + //- rjf: definitions case E_ExprKind_Define: { diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 35b65640..dd52f65a 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[48] = +String8 e_expr_kind_strings[49] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -63,6 +63,7 @@ str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), +str8_lit_comp("Line"), str8_lit_comp("Define"), }; @@ -81,7 +82,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[48] = +E_OpInfo e_expr_kind_op_info_table[49] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -130,6 +131,7 @@ E_OpInfo e_expr_kind_op_info_table[48] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 1, str8_lit_comp(""), str8_lit_comp(":"), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 2a6200ba..c4dc0adc 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -138,6 +138,7 @@ E_ExprKind_TypeIdent, E_ExprKind_Ptr, E_ExprKind_Array, E_ExprKind_Func, +E_ExprKind_Line, E_ExprKind_Define, E_ExprKind_COUNT, } E_ExprKindEnum; @@ -160,9 +161,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[48]; +extern String8 e_expr_kind_strings[49]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[48]; +extern E_OpInfo e_expr_kind_op_info_table[49]; extern U8 e_kind_basic_byte_size_table[56]; extern String8 e_kind_basic_string_table[56]; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7e56a987..d63c1116 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -191,7 +191,7 @@ RD_EntityKindFlags rd_entity_kind_flags_table[27] = (0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), }; -Rng1U64 rd_reg_slot_range_table[38] = +Rng1U64 rd_reg_slot_range_table[40] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -204,6 +204,8 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, cfg), OffsetOf(RD_Regs, cfg) + sizeof(RD_Handle)}, +{OffsetOf(RD_Regs, cfg_list), OffsetOf(RD_Regs, cfg_list) + sizeof(RD_HandleList)}, {OffsetOf(RD_Regs, entity), OffsetOf(RD_Regs, entity) + sizeof(RD_Handle)}, {OffsetOf(RD_Regs, entity_list), OffsetOf(RD_Regs, entity_list) + sizeof(RD_HandleList)}, {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 199f4738..eeb77547 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -60,6 +60,8 @@ RD_RegSlot_Panel, RD_RegSlot_View, RD_RegSlot_PrevView, RD_RegSlot_DstPanel, +RD_RegSlot_Cfg, +RD_RegSlot_CfgList, RD_RegSlot_Entity, RD_RegSlot_EntityList, RD_RegSlot_UnwindCount, @@ -557,6 +559,8 @@ RD_Handle panel; RD_Handle view; RD_Handle prev_view; RD_Handle dst_panel; +RD_Handle cfg; +RD_HandleList cfg_list; RD_Handle entity; RD_HandleList entity_list; U64 unwind_count; @@ -632,6 +636,8 @@ RD_ViewRuleUIFunctionType *ui; .view = rd_regs()->view,\ .prev_view = rd_regs()->prev_view,\ .dst_panel = rd_regs()->dst_panel,\ +.cfg = rd_regs()->cfg,\ +.cfg_list = rd_regs()->cfg_list,\ .entity = rd_regs()->entity,\ .entity_list = rd_regs()->entity_list,\ .unwind_count = rd_regs()->unwind_count,\ @@ -779,7 +785,7 @@ extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[38]; +extern Rng1U64 rd_reg_slot_range_table[40]; extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 33aa7c04..c8812019 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -161,6 +161,8 @@ RD_RegTable: {RD_Handle view View } {RD_Handle prev_view PrevView } {RD_Handle dst_panel DstPanel } + {RD_Handle cfg Cfg } + {RD_HandleList cfg_list CfgList } {RD_Handle entity Entity } {RD_HandleList entity_list EntityList } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c851cae2..16c828dd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -131,6 +131,7 @@ rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src) { MemoryCopyStruct(dst, src); dst->entity_list = rd_handle_list_copy(arena, src->entity_list); + dst->cfg_list = rd_handle_list_copy(arena, src->cfg_list); dst->file_path = push_str8_copy(arena, src->file_path); dst->lines = d_line_list_copy(arena, &src->lines); dst->dbgi_key = di_key_copy(arena, &src->dbgi_key); @@ -1185,6 +1186,78 @@ rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding) return list; } +internal Vec4F32 +rd_hsva_from_cfg(RD_Cfg *cfg) +{ + Vec4F32 hsva = {0}; + RD_Cfg *hsva_root = rd_cfg_child_from_string(cfg, str8_lit("hsva")); + RD_Cfg *h = hsva_root->first; + RD_Cfg *s = h->next; + RD_Cfg *v = s->next; + RD_Cfg *a = v->next; + hsva.x = (F32)f64_from_str8(h->string); + hsva.y = (F32)f64_from_str8(s->string); + hsva.z = (F32)f64_from_str8(v->string); + hsva.w = (F32)f64_from_str8(a->string); + return hsva; +} + +internal Vec4F32 +rd_rgba_from_cfg(RD_Cfg *cfg) +{ + Vec4F32 hsva = rd_hsva_from_cfg(cfg); + Vec4F32 rgba = rgba_from_hsva(hsva); + return rgba; +} + +internal B32 +rd_disabled_from_cfg(RD_Cfg *cfg) +{ + B32 is_disabled = (rd_cfg_child_from_string(cfg, str8_lit("disabled")) != &rd_nil_cfg); + return is_disabled; +} + +internal RD_Location +rd_location_from_cfg(RD_Cfg *cfg) +{ + RD_Location dst_loc = {0}; + { + RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("location")); + if(src_loc->first != &rd_nil_cfg && src_loc->first->first != &rd_nil_cfg) + { + dst_loc.file_path = src_loc->first->string; + try_s64_from_str8_c_rules(src_loc->first->first->string, &dst_loc.pt.line); + if(!try_s64_from_str8_c_rules(src_loc->first->first->first->string, &dst_loc.pt.column)) + { + dst_loc.pt.column = 1; + } + } + else + { + Temp scratch = scratch_begin(0, 0); + MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_loc->first->string); + if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) + { + dst_loc.name = src_loc->first->string; + } + else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) + { + try_u64_from_str8_c_rules(src_loc->first->string, &dst_loc.vaddr); + } + scratch_end(scratch); + } + } + return dst_loc; +} + +internal String8 +rd_expr_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *expr_root = rd_cfg_child_from_string(cfg, str8_lit("expression")); + String8 result = expr_root->first->string; + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -3689,7 +3762,7 @@ rd_window_frame(void) RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; String8 expr = rd_view_expr_string(); String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); - MD_Node *params = md_tree_from_string(scratch.arena, params_string); + MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; view_ui(expr, params, view_preview_container->rect); } } @@ -4091,7 +4164,7 @@ rd_window_frame(void) UI_Signal item_sig = ui_signal_from_box(item_box); if(ui_clicked(item_sig)) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_lister UI_Event move_back_evt = zero_struct; move_back_evt.kind = UI_EventKind_Navigate; move_back_evt.flags = UI_EventFlag_KeepMark; @@ -4117,7 +4190,7 @@ rd_window_frame(void) di_scope_close(di_scope); } -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_lister //////////////////////////// //- rjf: prepare query state for the in-progress query command // @@ -4136,7 +4209,7 @@ rd_window_frame(void) ws->query_input_cursor = ws->query_input_mark = txt_pt(1, ws->query_input_string_size+1); } -#if 0 // TODO(rjf): @cfg (query state prep) +#if 0 // TODO(rjf): @cfg_lister (query state prep) String8 query_view_name = cmd_kind_info->query.view_name; if(query_view_name.size == 0) { @@ -6011,7 +6084,7 @@ rd_window_frame(void) // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_panels for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) @@ -6635,7 +6708,7 @@ rd_window_frame(void) //////////////////////////// //- rjf: animate panels // -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_panels { F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-50.f * rd_state->frame_dt)) : 1.f; Vec2F32 content_rect_dim = dim_2f32(content_rect); @@ -6690,8 +6763,6 @@ rd_window_frame(void) F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - RD_RegsScope(.panel = rd_handle_from_cfg(panel->cfg), - .view = rd_handle_from_cfg(selected_tab)) { ////////////////////////// //- rjf: calculate UI rectangles @@ -6702,7 +6773,7 @@ rd_window_frame(void) target_rect_px.y0 / content_rect_dim.y, target_rect_px.x1 / content_rect_dim.x, target_rect_px.y1 / content_rect_dim.y); - // TODO(rjf): @cfg animate `target_rect_pct` + // TODO(rjf): @cfg_panels animate `target_rect_pct` Rng2F32 panel_rect_pct = target_rect_pct; Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, panel_rect_pct.y0*content_rect_dim.y, @@ -7020,6 +7091,8 @@ rd_window_frame(void) String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); if(view_file_path.size != 0) { + rd_regs()->panel = rd_handle_from_cfg(panel->cfg); + rd_regs()->view = rd_handle_from_cfg(selected_tab); rd_regs()->file_path = view_file_path; } } @@ -7044,7 +7117,7 @@ rd_window_frame(void) { String8 view_expr = rd_view_expr_string(); String8 params_string = rd_string_from_cfg_tree(scratch.arena, selected_tab); - MD_Node *params = md_tree_from_string(scratch.arena, params_string); + MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(selected_tab->string); RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; view_ui(view_expr, params, content_rect); @@ -7172,7 +7245,7 @@ rd_window_frame(void) // draw empty space if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && catchall_drop_site_hovered) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_dragdrop RD_Panel *dst_panel = rd_panel_from_handle(rd_last_drag_drop_panel); RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); RD_View *dst_prev_view = rd_view_from_handle(rd_last_drag_drop_prev_tab); @@ -7436,7 +7509,7 @@ rd_window_frame(void) // if(catchall_drop_site_hovered) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_dragdrop rd_last_drag_drop_panel = rd_handle_from_panel(panel); RD_View *dragged_view = rd_view_from_handle(rd_state->drag_drop_regs->view); @@ -7516,89 +7589,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: animate views - // - { -#if 0 // TODO(rjf): @cfg - Temp scratch = scratch_begin(0, 0); - typedef struct Task Task; - struct Task - { - Task *next; - RD_Panel *panel; - RD_View *list_first; - RD_View *transient_owner; - }; - Task start_task = {0, &rd_nil_panel, ws->query_view_stack_top}; - Task *first_task = &start_task; - Task *last_task = first_task; - F32 rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); - F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) - { - Task *t = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, t); - t->panel = panel; - t->list_first = panel->first_tab_view; - } - for(Task *t = first_task; t != 0; t = t->next) - { - RD_View *list_first = t->list_first; - for(RD_View *view = list_first; !rd_view_is_nil(view); view = view->order_next) - { - if(!rd_view_is_nil(view->first_transient)) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->panel = t->panel; - task->list_first = view->first_transient; - task->transient_owner = view; - } - if(window_is_focused) - { - if(abs_f32(view->loading_t_target - view->loading_t) > 0.01f || - abs_f32(view->scroll_pos.x.off) > 0.01f || - abs_f32(view->scroll_pos.y.off) > 0.01f || - abs_f32(view->is_filtering_t - (F32)!!view->is_filtering)) - { - rd_request_frame(); - } - if(view->loading_t_target != 0 && (view == rd_selected_tab_from_panel(t->panel) || - t->transient_owner == rd_selected_tab_from_panel(t->panel))) - { - rd_request_frame(); - } - } - view->loading_t += (view->loading_t_target - view->loading_t) * rate; - view->is_filtering_t += ((F32)!!view->is_filtering - view->is_filtering_t) * fast_rate; - view->scroll_pos.x.off -= view->scroll_pos.x.off * (rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32 ? fast_rate : 1.f); - view->scroll_pos.y.off -= view->scroll_pos.y.off * (rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32 ? fast_rate : 1.f); - if(abs_f32(view->scroll_pos.x.off) < 0.01f) - { - view->scroll_pos.x.off = 0; - } - if(abs_f32(view->scroll_pos.y.off) < 0.01f) - { - view->scroll_pos.y.off = 0; - } - if(abs_f32(view->is_filtering_t - (F32)!!view->is_filtering) < 0.01f) - { - view->is_filtering_t = (F32)!!view->is_filtering; - } - if(view == rd_selected_tab_from_panel(t->panel) || - t->transient_owner == rd_selected_tab_from_panel(t->panel)) - { - view->loading_t_target = 0; - } - } - } - scratch_end(scratch); -#endif - } - //////////////////////////// //- rjf: drag/drop cancelling // @@ -9984,7 +9974,7 @@ rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg_lister internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) @@ -10380,44 +10370,6 @@ rd_font_size_from_slot(RD_FontSlot slot) result *= (dpi / 96.f); } return result; - -#if 0 // TODO(rjf): @cfg - F32 result = 0; - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - F32 dpi = os_dpi_from_window(ws->os); - if(dpi != ws->last_dpi) - { - F32 old_dpi = ws->last_dpi; - F32 new_dpi = dpi; - ws->last_dpi = dpi; - S32 *pt_sizes[] = - { - &ws->setting_vals[RD_SettingCode_MainFontSize].s32, - &ws->setting_vals[RD_SettingCode_CodeFontSize].s32, - }; - for(U64 idx = 0; idx < ArrayCount(pt_sizes); idx += 1) - { - F32 ratio = pt_sizes[idx][0] / old_dpi; - F32 new_pt_size = ratio*new_dpi; - pt_sizes[idx][0] = (S32)new_pt_size; - } - } - switch(slot) - { - case RD_FontSlot_Code: - { - result = (F32)ws->setting_vals[RD_SettingCode_CodeFontSize].s32; - }break; - default: - case RD_FontSlot_Main: - case RD_FontSlot_Icons: - { - result = (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32; - }break; - } - return result; -#endif } internal FNT_RasterFlags @@ -11826,6 +11778,112 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: get events from the OS + // + OS_EventList events = {0}; + if(depth == 0) DeferLoop(depth += 1, depth -= 1) + { + events = os_get_events(scratch.arena, rd_state->num_frames_requested == 0); + } + + ////////////////////////////// + //- rjf: pick target hz + // + // TODO(rjf): maximize target, given all windows and their monitors + F32 target_hz = os_get_gfx_info()->default_refresh_rate; + if(rd_state->frame_index > 32) + { + // rjf: calculate average frame time out of the last N + U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); + U64 frame_time_history_sum_us = 0; + for(U64 idx = 0; idx < num_frames_in_history; idx += 1) + { + frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; + } + U64 frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; + + // rjf: pick among a number of sensible targets to snap to, given how well + // we've been performing + F32 possible_alternate_hz_targets[] = {target_hz, 60.f, 120.f, 144.f, 240.f}; + F32 best_target_hz = target_hz; + S64 best_target_hz_frame_time_us_diff = max_S64; + for(U64 idx = 0; idx < ArrayCount(possible_alternate_hz_targets); idx += 1) + { + F32 candidate = possible_alternate_hz_targets[idx]; + if(candidate <= target_hz) + { + U64 candidate_frame_time_us = 1000000/(U64)candidate; + S64 frame_time_us_diff = (S64)frame_time_history_avg_us - (S64)candidate_frame_time_us; + if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff) + { + best_target_hz = candidate; + best_target_hz_frame_time_us_diff = frame_time_us_diff; + } + } + } + target_hz = best_target_hz; + } + + ////////////////////////////// + //- rjf: target Hz -> delta time + // + rd_state->frame_dt = 1.f/target_hz; + + ////////////////////////////// + //- rjf: begin measuring actual per-frame work + // + U64 begin_time_us = os_now_microseconds(); + + ////////////////////////////// + //- rjf: bind change + // + if(!rd_state->popup_active && rd_state->bind_change_active) + { + if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Esc)) + { + rd_request_frame(); + rd_state->bind_change_active = 0; + } + if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete)) + { + rd_request_frame(); + // TODO(rjf): @cfg_bindchange rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + rd_state->bind_change_active = 0; + rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); + } + for(OS_Event *event = events.first, *next = 0; event != 0; event = next) + { + if(event->kind == OS_EventKind_Press && + event->key != OS_Key_Esc && + event->key != OS_Key_Return && + event->key != OS_Key_Backspace && + event->key != OS_Key_Delete && + event->key != OS_Key_LeftMouseButton && + event->key != OS_Key_RightMouseButton && + event->key != OS_Key_MiddleMouseButton && + event->key != OS_Key_Ctrl && + event->key != OS_Key_Alt && + event->key != OS_Key_Shift) + { + rd_state->bind_change_active = 0; + RD_Binding binding = zero_struct; + { + binding.key = event->key; + binding.modifiers = event->modifiers; + } + // TODO(rjf): @cfg_bindchange rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + // TODO(rjf): @cfg_bindchange rd_bind_name(rd_state->bind_change_cmd_name, binding); + U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); + os_text(&events, event->window, codepoint); + os_eat_event(&events, event); + rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); + rd_request_frame(); + break; + } + } + } + ////////////////////////////// //- rjf: build key map from config // @@ -11929,112 +11987,6 @@ rd_frame(void) } } - ////////////////////////////// - //- rjf: get events from the OS - // - OS_EventList events = {0}; - if(depth == 0) DeferLoop(depth += 1, depth -= 1) - { - events = os_get_events(scratch.arena, rd_state->num_frames_requested == 0); - } - - ////////////////////////////// - //- rjf: pick target hz - // - // TODO(rjf): maximize target, given all windows and their monitors - F32 target_hz = os_get_gfx_info()->default_refresh_rate; - if(rd_state->frame_index > 32) - { - // rjf: calculate average frame time out of the last N - U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); - U64 frame_time_history_sum_us = 0; - for(U64 idx = 0; idx < num_frames_in_history; idx += 1) - { - frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; - } - U64 frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; - - // rjf: pick among a number of sensible targets to snap to, given how well - // we've been performing - F32 possible_alternate_hz_targets[] = {target_hz, 60.f, 120.f, 144.f, 240.f}; - F32 best_target_hz = target_hz; - S64 best_target_hz_frame_time_us_diff = max_S64; - for(U64 idx = 0; idx < ArrayCount(possible_alternate_hz_targets); idx += 1) - { - F32 candidate = possible_alternate_hz_targets[idx]; - if(candidate <= target_hz) - { - U64 candidate_frame_time_us = 1000000/(U64)candidate; - S64 frame_time_us_diff = (S64)frame_time_history_avg_us - (S64)candidate_frame_time_us; - if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff) - { - best_target_hz = candidate; - best_target_hz_frame_time_us_diff = frame_time_us_diff; - } - } - } - target_hz = best_target_hz; - } - - ////////////////////////////// - //- rjf: target Hz -> delta time - // - rd_state->frame_dt = 1.f/target_hz; - - ////////////////////////////// - //- rjf: begin measuring actual per-frame work - // - U64 begin_time_us = os_now_microseconds(); - - ////////////////////////////// - //- rjf: bind change - // - if(!rd_state->popup_active && rd_state->bind_change_active) - { - if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Esc)) - { - rd_request_frame(); - rd_state->bind_change_active = 0; - } - if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete)) - { - rd_request_frame(); - // TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); - rd_state->bind_change_active = 0; - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); - } - for(OS_Event *event = events.first, *next = 0; event != 0; event = next) - { - if(event->kind == OS_EventKind_Press && - event->key != OS_Key_Esc && - event->key != OS_Key_Return && - event->key != OS_Key_Backspace && - event->key != OS_Key_Delete && - event->key != OS_Key_LeftMouseButton && - event->key != OS_Key_RightMouseButton && - event->key != OS_Key_MiddleMouseButton && - event->key != OS_Key_Ctrl && - event->key != OS_Key_Alt && - event->key != OS_Key_Shift) - { - rd_state->bind_change_active = 0; - RD_Binding binding = zero_struct; - { - binding.key = event->key; - binding.modifiers = event->modifiers; - } - // TODO(rjf): @cfg rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); - // TODO(rjf): @cfg rd_bind_name(rd_state->bind_change_cmd_name, binding); - U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); - os_text(&events, event->window, codepoint); - os_eat_event(&events, event); - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); - rd_request_frame(); - break; - } - } - } - ////////////////////////////// //- rjf: consume events // @@ -12492,7 +12444,7 @@ rd_frame(void) //- rjf: sanitize the window/panel/tab tree structure // { - // TODO(rjf): @cfg in the past, we had a spot in the rd_window_frame, + // TODO(rjf): @cfg_panels in the past, we had a spot in the rd_window_frame, // which ensured to select tabs, if a panel had tabs but had none // selected, and if a panel had a selected tab but it was project-filtered. // this is effectively just fixing up unexpected malformations of the @@ -15999,13 +15951,13 @@ X(getting_started) for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { RD_Cfg *wp = n->v; - RD_Cfg *name = rd_cfg_child_from_string(wp, str8_lit("name")); + RD_Cfg *expr = rd_cfg_child_from_string(wp, str8_lit("expression")); RD_Cfg *loc = rd_cfg_child_from_string(wp, str8_lit("location")); S64 loc_line = 0; U64 loc_vaddr = 0; B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - B32 loc_matches_expr = (string.size != 0 && str8_match(name->first->string, string, 0)); + B32 loc_matches_expr = (string.size != 0 && str8_match(expr->first->string, string, 0)); if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) { rd_cfg_release(wp); @@ -16018,9 +15970,9 @@ X(getting_started) { RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); - RD_Cfg *name = rd_cfg_new(wp, str8_lit("name")); + RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); - rd_cfg_new(name, string); + rd_cfg_new(expr, string); if(vaddr != 0) { rd_cfg_newf(loc, "0x%I64x", vaddr); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5670d3c3..5f897bc7 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -341,6 +341,18 @@ struct RD_CfgRec S32 pop_count; }; +//////////////////////////////// +//~ rjf: Structured Locations, Parsed From Config + +typedef struct RD_Location RD_Location; +struct RD_Location +{ + String8 file_path; + TxtPt pt; + U64 vaddr; + String8 name; +}; + //////////////////////////////// //~ rjf: Key Map Types @@ -1147,6 +1159,13 @@ internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg); internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string); internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding); +internal Vec4F32 rd_hsva_from_cfg(RD_Cfg *cfg); +internal Vec4F32 rd_rgba_from_cfg(RD_Cfg *cfg); + +internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); +internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); +internal String8 rd_expr_from_cfg(RD_Cfg *cfg); + //////////////////////////////// //~ rjf: Entity Stateful Functions diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index eaa496e1..22ecf4f0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -178,9 +178,9 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count); code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count); code_slice_params.line_tokens = push_array(scratch.arena, TXT_TokenArray, visible_line_count); - code_slice_params.line_bps = push_array(scratch.arena, RD_EntityList, visible_line_count); + code_slice_params.line_bps = push_array(scratch.arena, RD_CfgList, visible_line_count); code_slice_params.line_ips = push_array(scratch.arena, CTRL_EntityList, visible_line_count); - code_slice_params.line_pins = push_array(scratch.arena, RD_EntityList, visible_line_count); + code_slice_params.line_pins = push_array(scratch.arena, RD_CfgList, visible_line_count); code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count); code_slice_params.line_infos = push_array(scratch.arena, D_LineList, visible_line_count); code_slice_params.font = code_font; @@ -211,21 +211,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find visible breakpoints for source code if(!dasm_lines) ProfScope("find visible breakpoints for source code") { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if(visible_line_num_range.min <= loc->text_point.line && loc->text_point.line <= visible_line_num_range.max) + RD_Cfg *bp = n->v; + RD_Location loc = rd_location_from_cfg(bp); + if(visible_line_num_range.min <= loc.pt.line && loc.pt.line <= visible_line_num_range.max) { for(String8Node *override_n = file_path_possible_overrides.first; override_n != 0; override_n = override_n->next) { - if(path_match_normalized(loc->string, override_n->string)) + if(path_match_normalized(loc.file_path, override_n->string)) { - U64 slice_line_idx = (loc->text_point.line-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); + U64 slice_line_idx = (U64)(loc.pt.line-visible_line_num_range.min); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); break; } } @@ -273,21 +273,21 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find visible watch pins for source code if(!dasm_lines) ProfScope("find visible watch pins for source code") { - RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *wp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(wp, RD_EntityKind_Location); - if(visible_line_num_range.min <= loc->text_point.line && loc->text_point.line <= visible_line_num_range.max) + RD_Cfg *wp = n->v; + RD_Location loc = rd_location_from_cfg(wp); + if(visible_line_num_range.min <= loc.pt.line && loc.pt.line <= visible_line_num_range.max) { for(String8Node *override_n = file_path_possible_overrides.first; override_n != 0; override_n = override_n->next) { - if(path_match_normalized(loc->string, override_n->string)) + if(path_match_normalized(loc.file_path, override_n->string)) { - U64 slice_line_idx = (loc->text_point.line-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); + U64 slice_line_idx = (loc.pt.line-visible_line_num_range.min); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); break; } } @@ -335,20 +335,20 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find breakpoints mapping to this disasm if(dasm_lines) ProfScope("find breakpoints mapping to this disassembly") { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if(loc->flags & RD_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, loc->vaddr)) + RD_Cfg *bp = n->v; + RD_Location loc = rd_location_from_cfg(bp); + if(contains_1u64(dasm_vaddr_range, loc.vaddr)) { - U64 off = loc->vaddr-dasm_vaddr_range.min; + U64 off = loc.vaddr - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); - S64 line_num = (S64)(idx+1); + S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) { U64 slice_line_idx = (line_num-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp); } } } @@ -357,20 +357,20 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find watch pins mapping to this disasm if(dasm_lines) ProfScope("find watch pins mapping to this disassembly") { - RD_EntityList pins = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = pins.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(pin, RD_EntityKind_Location); - if(loc->flags & RD_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, loc->vaddr)) + RD_Cfg *wp = n->v; + RD_Location loc = rd_location_from_cfg(wp); + if(contains_1u64(dasm_vaddr_range, loc.vaddr)) { - U64 off = loc->vaddr-dasm_vaddr_range.min; + U64 off = loc.vaddr - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); - S64 line_num = (S64)(idx+1); + S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) { U64 slice_line_idx = (line_num-visible_line_num_range.min); - rd_entity_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], pin); + rd_cfg_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp); } } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 209bf857..80027037 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -829,8 +829,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { CTRL_EntityList line_ips = params->line_ips[line_idx]; - RD_EntityList line_bps = params->line_bps[line_idx]; - RD_EntityList line_pins = params->line_pins[line_idx]; + RD_CfgList line_bps = params->line_bps[line_idx]; + RD_CfgList line_pins = params->line_pins[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) @@ -952,25 +952,26 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } //- rjf: build margin breakpoint ui - for(RD_EntityNode *n = line_bps.first; n != 0; n = n->next) + for(RD_CfgNode *n = line_bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - Vec4F32 bp_color = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); - if(bp->flags & RD_EntityFlag_HasColor) + RD_Cfg *bp = n->v; + Vec4F32 bp_rgba = rd_rgba_from_cfg(bp); + B32 bp_is_disabled = rd_disabled_from_cfg(bp); + if(bp_rgba.w == 0) { - bp_color = rd_rgba_from_entity(bp); + bp_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); } - if(bp->disabled) + if(bp_is_disabled) { - bp_color = v4f32(bp_color.x * 0.6f, bp_color.y * 0.6f, bp_color.z * 0.6f, bp_color.w * 0.6f); + bp_rgba = v4f32(bp_rgba.x * 0.6f, bp_rgba.y * 0.6f, bp_rgba.z * 0.6f, bp_rgba.w * 0.6f); } // rjf: prep custom rendering data RD_BreakpointBoxDrawExtData *bp_draw = push_array(ui_build_arena(), RD_BreakpointBoxDrawExtData, 1); { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (rd_entity_from_handle(hover_regs->entity) == bp && rd_state->hover_regs_slot == RD_RegSlot_Entity); - bp_draw->color = bp_color; + B32 is_hovering = (rd_cfg_from_handle(hover_regs->cfg) == bp && rd_state->hover_regs_slot == RD_RegSlot_Cfg); + bp_draw->color = bp_rgba; bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); bp_draw->do_lines = rd_setting_val_from_code(RD_SettingCode_BreakpointLines).s32; @@ -995,7 +996,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = bp_color)); + ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = bp_rgba)); ui_set_next_text_alignment(UI_TextAlign_Center); UI_Box *bp_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| @@ -1009,42 +1010,46 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.entity = rd_handle_from_cfg(bp)) rd_set_hover_regs(RD_RegSlot_Entity); } // rjf: shift+click => enable breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags & OS_Modifier_Shift) { - rd_cmd(bp->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(bp)); + rd_cmd(bp_is_disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .cfg = rd_handle_from_cfg(bp)); } // rjf: click => remove breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags == 0) { - rd_cmd(RD_CmdKind_RemoveEntity, .entity = rd_handle_from_entity(bp)); + rd_cmd(RD_CmdKind_RemoveEntity, .cfg = rd_handle_from_cfg(bp)); } // rjf: drag start if(ui_dragging(bp_sig) && !contains_2f32(bp_box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_drag_begin(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(bp)) rd_drag_begin(RD_RegSlot_Cfg); } // rjf: bp right-click menu if(ui_right_clicked(bp_sig)) { - RD_RegsScope(.entity = rd_handle_from_entity(bp)) rd_open_ctx_menu(bp_box->key, v2f32(0, bp_box->rect.y1-bp_box->rect.y0), RD_RegSlot_Entity); + rd_cmd(RD_CmdKind_PushQuery, + .cfg = rd_handle_from_cfg(bp), + .reg_slot= RD_RegSlot_Cfg, + .ui_key = bp_box->key, + .off_px = v2f32(0, bp_box->rect.y1-bp_box->rect.y0)); } } //- rjf: build margin watch pin ui - for(RD_EntityNode *n = line_pins.first; n != 0; n = n->next) + for(RD_CfgNode *n = line_pins.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Text); - if(pin->flags & RD_EntityFlag_HasColor) + RD_Cfg *pin = n->v; + Vec4F32 color = rd_rgba_from_cfg(pin); + if(color.w == 0) { - color = rd_rgba_from_entity(pin); + color = rd_rgba_from_theme_color(RD_ThemeColor_Text); } // rjf: build box for watch @@ -1065,25 +1070,29 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_set_hover_regs(RD_RegSlot_Entity); } // rjf: click => remove pin if(ui_clicked(pin_sig)) { - rd_cmd(RD_CmdKind_RemoveEntity, .entity = rd_handle_from_entity(pin)); + rd_cmd(RD_CmdKind_RemoveEntity, .cfg = rd_handle_from_cfg(pin)); } // rjf: drag start if(ui_dragging(pin_sig) && !contains_2f32(pin_box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_drag_begin(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_drag_begin(RD_RegSlot_Cfg); } // rjf: watch right-click menu if(ui_right_clicked(pin_sig)) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(pin_box->key, v2f32(0, pin_box->rect.y1-pin_box->rect.y0), RD_RegSlot_Entity); + rd_cmd(RD_CmdKind_PushQuery, + .cfg = rd_handle_from_cfg(pin), + .reg_slot= RD_RegSlot_Cfg, + .ui_key = pin_box->key, + .off_px = v2f32(0, pin_box->rect.y1-pin_box->rect.y0)); } } } @@ -1257,16 +1266,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num < params->line_num_range.max; line_num += 1, line_idx += 1) { - RD_EntityList pins = params->line_pins[line_idx]; + RD_CfgList pins = params->line_pins[line_idx]; if(pins.count != 0) UI_Parent(line_extras_boxes[line_idx]) RD_Font(RD_FontSlot_Code) UI_FontSize(params->font_size) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { - for(RD_EntityNode *n = pins.first; n != 0; n = n->next) + for(RD_CfgNode *n = pins.first; n != 0; n = n->next) { - RD_Entity *pin = n->entity; - String8 pin_expr = pin->string; + RD_Cfg *pin = n->v; + String8 pin_expr = rd_expr_from_cfg(pin); E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.type_key)) @@ -1283,10 +1292,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_BoxFlag_DrawBorder, pin_box_key); UI_Parent(pin_box) UI_PrefWidth(ui_text_dim(10, 1)) { - Vec4F32 pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); - if(pin->flags & RD_EntityFlag_HasColor) + Vec4F32 pin_color = rd_rgba_from_cfg(pin); + if(pin_color.w == 0) { - pin_color = rd_rgba_from_entity(pin); + pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } UI_PrefWidth(ui_em(1.5f, 1.f)) RD_Font(RD_FontSlot_Icons) @@ -1297,11 +1306,15 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal sig = ui_buttonf("%S###pin_nub", rd_icon_kind_text_table[RD_IconKind_Pin]); if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_drag_begin(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_drag_begin(RD_RegSlot_Cfg); } if(ui_right_clicked(sig)) { - RD_RegsScope(.entity = rd_handle_from_entity(pin)) rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0), RD_RegSlot_Entity); + rd_cmd(RD_CmdKind_PushQuery, + .cfg = rd_handle_from_cfg(pin), + .reg_slot= RD_RegSlot_Cfg, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); } } rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 9048161e..3774f7fe 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -43,9 +43,9 @@ struct RD_CodeSliceParams String8 *line_text; Rng1U64 *line_ranges; TXT_TokenArray *line_tokens; - RD_EntityList *line_bps; + RD_CfgList *line_bps; CTRL_EntityList *line_ips; - RD_EntityList *line_pins; + RD_CfgList *line_pins; U64 *line_vaddrs; D_LineList *line_infos; DI_KeyList relevant_dbgi_keys; From 5cbef8f10d5ec6ec2ef8913bf6b8cd55b1df14ed Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 17 Jan 2025 15:16:23 -0800 Subject: [PATCH 015/755] more entity -> cfg work --- src/raddbg/raddbg_core.c | 304 ++++++++++++++++++++++++++++++++++----- src/raddbg/raddbg_core.h | 2 + 2 files changed, 274 insertions(+), 32 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 16c828dd..5364e3c4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1258,6 +1258,248 @@ rd_expr_from_cfg(RD_Cfg *cfg) return result; } +internal D_Target +rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + D_Target target = {0}; + target.exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + target.args = rd_cfg_child_from_string(cfg, str8_lit("arguments"))->first->string; + target.working_directory = rd_cfg_child_from_string(cfg, str8_lit("working_directory"))->first->string; + target.custom_entry_point_name = rd_cfg_child_from_string(cfg, str8_lit("entry_point"))->first->string; + target.stdout_path = rd_cfg_child_from_string(cfg, str8_lit("stdout_path"))->first->string; + target.stderr_path = rd_cfg_child_from_string(cfg, str8_lit("stderr_path"))->first->string; + target.stdin_path = rd_cfg_child_from_string(cfg, str8_lit("stdin_path"))->first->string; + target.debug_subprocesses = (rd_cfg_child_from_string(cfg, str8_lit("debug_subprocesses")) != &rd_nil_cfg); + RD_Cfg *env_root = rd_cfg_child_from_string(cfg, str8_lit("environment")); + for(RD_Cfg *env_child = env_root->first; env_child != &rd_nil_cfg; env_child = env_child->next) + { + str8_list_push(arena, &target.env, env_child->string); + } + return target; +} + +internal DR_FancyStringList +rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size) +{ + DR_FancyStringList result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: unpack config + B32 is_disabled = rd_disabled_from_cfg(cfg); + RD_Location loc = rd_location_from_cfg(cfg); + D_Target target = rd_target_from_cfg(scratch.arena, cfg); + Vec4F32 rgba = rd_rgba_from_cfg(cfg); + if(rgba.w == 0) + { + rgba = ui_top_palette()->text; + } + + //- rjf: name -> icon table + local_persist struct + { + String8 name; + RD_IconKind icon_kind; + } + name2icon_map[] = + { + {str8_lit_comp("target"), RD_IconKind_Target}, + {str8_lit_comp("breakpoint"), RD_IconKind_CircleFilled}, + {str8_lit_comp("auto_view_rule"), RD_IconKind_Binoculars}, + {str8_lit_comp("file_path_map"), RD_IconKind_FileOutline}, + {str8_lit_comp("watch_pin"), RD_IconKind_Pin}, + {str8_lit_comp("watch"), RD_IconKind_Binoculars}, + {str8_lit_comp("window"), RD_IconKind_Window}, + {str8_lit_comp("recent_project"), RD_IconKind_Briefcase}, + {str8_lit_comp("recent_file"), RD_IconKind_FileOutline}, + }; + + //- rjf: map cfg -> icon + RD_IconKind icon_kind = RD_IconKind_Null; + for EachElement(idx, name2icon_map) + { + if(str8_match(cfg->string, name2icon_map[idx].name, 0)) + { + icon_kind = name2icon_map[idx].icon_kind; + break; + } + } + + //- rjf: map icon -> is-from-command-line + B32 is_from_command_line = 0; + { + RD_Cfg *cmd_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(p == cmd_line_root) + { + is_from_command_line = 1; + break; + } + } + } + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + Vec4F32 secondary_rgba = secondary_color; + F32 secondary_size = size*0.8f; + B32 running_is_secondary = 0; + Vec4F32 running_rgba = rgba; + F32 running_size = size; +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; running_rgba = secondary_rgba; running_size = secondary_size;} + + //- rjf: push icon + if(icon_kind != RD_IconKind_Null) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + } + + //- rjf: push warning icon for command-line entities + if(is_from_command_line) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), rd_icon_kind_text_table[RD_IconKind_Info]); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + } + + //- rjf: push label + { + String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; + if(label.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, label); + start_secondary(); + } + } + + //- rjf: push expression + { + String8 expr = rd_cfg_child_from_string(cfg, str8_lit("expression"))->first->string; + if(expr.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, expr); + start_secondary(); + } + } + + //- rjf: push text location + if(loc.file_path.size != 0) + { + String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", loc.file_path, loc.pt.line, loc.pt.column); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, location_string); + start_secondary(); + } + + //- rjf: push target executable name + if(target.exe.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, target.exe); + start_secondary(); + } + + //- rjf: push target arguments + if(target.args.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, target.args); + } + + //- rjf: push conditions + { + String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; + if(condition.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, condition); + } + } + + //- rjf: push disabled marker + if(is_disabled) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, str8_lit("(Disabled)")); + } + + //- rjf: push hit count + { + String8 hit_count_value_string = rd_cfg_child_from_string(cfg, str8_lit("hit_count"))->first->string; + U64 hit_count = 0; + if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count)) + { + String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, hit_count_text); + } + } + + //- rjf: special case: auto view rule + if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + DR_FancyStringList src_fstrs = {0}; + DR_FancyStringList dst_fstrs = {0}; + if(src_string.size == 0) + { + src_string = str8_lit("(type)"); + src_color = secondary_color; + dr_fancy_string_list_push_new(arena, &src_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); + } + else RD_Font(RD_FontSlot_Code) + { + src_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, src_color, src_string); + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(view rule)"); + dst_color = secondary_color; + dr_fancy_string_list_push_new(arena, &dst_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); + } + else RD_Font(RD_FontSlot_Code) + { + dst_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, dst_color, dst_string); + } + dr_fancy_string_list_concat_in_place(&result, &src_fstrs); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); + dr_fancy_string_list_concat_in_place(&result, &dst_fstrs); + } + + //- rjf: special case: file path maps + if(str8_match(cfg->string, str8_lit("file_path_map"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + if(src_string.size == 0) + { + src_string = str8_lit("(source path)"); + src_color = secondary_color; + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(destination path)"); + dst_color = secondary_color; + } + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); + } + +#undef start_secondary + scratch_end(scratch); + } + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -1519,13 +1761,13 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) { String8 file_path__normalized = path_normalized_from_string(scratch.arena, file_path); String8List file_path_parts = str8_split_path(scratch.arena, file_path__normalized); - RD_EntityList maps = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); + RD_CfgList maps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); String8 best_map_dst = {0}; U64 best_map_match_length = max_U64; String8Node *best_map_remaining_suffix_first = 0; - for(RD_EntityNode *n = maps.first; n != 0; n = n->next) + for(RD_CfgNode *n = maps.first; n != 0; n = n->next) { - String8 map_src = rd_entity_child_from_kind(n->entity, RD_EntityKind_Source)->string; + String8 map_src = rd_cfg_child_from_string(n->v, str8_lit("source"))->first->string; String8 map_src__normalized = path_normalized_from_string(scratch.arena, map_src); String8List map_src_parts = str8_split_path(scratch.arena, map_src__normalized); B32 matches = 1; @@ -1545,7 +1787,7 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) if(matches && match_length < best_map_match_length) { best_map_match_length = match_length; - best_map_dst = rd_entity_child_from_kind(n->entity, RD_EntityKind_Dest)->string; + best_map_dst = rd_cfg_child_from_string(n->v, str8_lit("dest"))->first->string; best_map_remaining_suffix_first = file_path_part_n; } } @@ -1590,17 +1832,17 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) PathStyle pth_style = PathStyle_Relative; String8List pth_parts = path_normalized_list_from_string(scratch.arena, file_path, &pth_style); { - RD_EntityList links = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); - for(RD_EntityNode *n = links.first; n != 0; n = n->next) + RD_CfgList links = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); + for(RD_CfgNode *n = links.first; n != 0; n = n->next) { //- rjf: unpack link - RD_Entity *link = n->entity; - RD_Entity *src = rd_entity_child_from_kind(link, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(link, RD_EntityKind_Dest); + RD_Cfg *link = n->v; + RD_Cfg *src = rd_cfg_child_from_string(link, str8_lit("source")); + RD_Cfg *dst = rd_cfg_child_from_string(link, str8_lit("dest")); PathStyle src_style = PathStyle_Relative; PathStyle dst_style = PathStyle_Relative; - String8List src_parts = path_normalized_list_from_string(scratch.arena, src->string, &src_style); - String8List dst_parts = path_normalized_list_from_string(scratch.arena, dst->string, &dst_style); + String8List src_parts = path_normalized_list_from_string(scratch.arena, src->first->string, &src_style); + String8List dst_parts = path_normalized_list_from_string(scratch.arena, dst->first->string, &dst_style); //- rjf: determine if this link can possibly redirect to the target file path B32 dst_redirects_to_pth = 0; @@ -1638,6 +1880,7 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) } } } + scratch_end(scratch); return result; } @@ -5610,9 +5853,9 @@ rd_window_frame(void) UI_FontSize(ui_top_font_size()*0.85f) { Temp scratch = scratch_begin(0, 0); - RD_EntityList targets = rd_push_active_target_list(scratch.arena); + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - B32 have_targets = targets.count != 0; + B32 have_targets = (targets.count != 0); B32 can_send_signal = !d_ctrl_targets_running(); B32 can_play = (have_targets && (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())); B32 can_pause = (!can_send_signal); @@ -5647,9 +5890,10 @@ rd_window_frame(void) else { ui_labelf("Launch all active targets:"); - for(RD_EntityNode *n = targets.first; n != 0; n = n->next) + for(RD_CfgNode *n = targets.first; n != 0; n = n->next) { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(ui_build_arena(), n->entity, ui_top_palette()->text_weak, ui_top_font_size()); + RD_Cfg *target = n->v; + DR_FancyStringList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target, ui_top_palette()->text_weak, ui_top_font_size()); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fancy_strings(box, &title_fstrs); } @@ -7085,14 +7329,13 @@ rd_window_frame(void) UI_WidthFill { //- rjf: push interaction registers, fill with per-view states - rd_push_regs(); + rd_push_regs(.panel = rd_handle_from_cfg(panel->cfg), + .view = rd_handle_from_cfg(selected_tab)); { String8 view_expr = rd_view_expr_string(); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); if(view_file_path.size != 0) { - rd_regs()->panel = rd_handle_from_cfg(panel->cfg); - rd_regs()->view = rd_handle_from_cfg(selected_tab); rd_regs()->file_path = view_file_path; } } @@ -7180,7 +7423,7 @@ rd_window_frame(void) UI_Signal panel_sig = ui_signal_from_box(panel_box); if(ui_pressed(panel_sig)) { - rd_cmd(RD_CmdKind_FocusPanel); + rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(panel->cfg)); } ////////////////////////// @@ -12498,7 +12741,6 @@ rd_frame(void) // rjf: try to run engine command if(D_CmdKind_Null < (D_CmdKind)kind && (D_CmdKind)kind < D_CmdKind_COUNT) { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); D_CmdParams params = {0}; params.machine = rd_regs()->machine; params.process = rd_regs()->process; @@ -12510,12 +12752,9 @@ rd_frame(void) params.vaddr = rd_regs()->vaddr; params.prefer_disasm = rd_regs()->prefer_disasm; params.pid = rd_regs()->pid; - if(entity->kind == RD_EntityKind_Target) - { - params.targets.count = 1; - params.targets.v = push_array(scratch.arena, D_Target, params.targets.count); - params.targets.v[0] = rd_d_target_from_entity(entity); - } + params.targets.count = 1; + params.targets.v = push_array(scratch.arena, D_Target, params.targets.count); + params.targets.v[0] = rd_target_from_cfg(scratch.arena, rd_cfg_from_handle(rd_regs()->cfg)); d_push_cmd((D_CmdKind)kind, ¶ms); } @@ -16766,19 +17005,20 @@ X(getting_started) D_TargetArray targets = {0}; ProfScope("gather targets") { - RD_EntityList target_entities = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); - targets.count = target_entities.count; + RD_CfgList target_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + targets.count = target_cfgs.count; targets.v = push_array(scratch.arena, D_Target, targets.count); U64 idx = 0; - for(RD_EntityNode *n = target_entities.first; n != 0; n = n->next) + for(RD_CfgNode *n = target_cfgs.first; n != 0; n = n->next) { - RD_Entity *src_target = n->entity; - if(src_target->disabled) + RD_Cfg *src = n->v; + B32 src_is_disabled = rd_disabled_from_cfg(src); + if(src_is_disabled) { targets.count -= 1; continue; } - targets.v[idx] = rd_d_target_from_entity(src_target); + targets.v[idx] = rd_target_from_cfg(scratch.arena, src); idx += 1; } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5f897bc7..fbaac83c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1165,6 +1165,8 @@ internal Vec4F32 rd_rgba_from_cfg(RD_Cfg *cfg); internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); +internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); +internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); //////////////////////////////// //~ rjf: Entity Stateful Functions From 84fd1e9d3fde8f1fbd0a348658ab920a60920548 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 21 Jan 2025 16:41:59 -0800 Subject: [PATCH 016/755] big batch of work in moving from entity -> cfg; work on new universal lister system for cfg right-click menus, system processes, file system, autocompletion, procedures, etc. --- project.4coder | 3 +- src/dbg_engine/dbg_engine.mdesk | 74 ++-- src/dbg_engine/dbg_engine_core.c | 29 -- src/raddbg/generated/raddbg.meta.c | 477 +++++++++++---------- src/raddbg/generated/raddbg.meta.h | 14 +- src/raddbg/raddbg.mdesk | 514 +++++++++++++---------- src/raddbg/raddbg_core.c | 641 ++++++++++++++++++----------- src/raddbg/raddbg_core.h | 63 ++- src/raddbg/raddbg_main.c | 136 ++---- src/raddbg/raddbg_views.c | 2 - src/raddbg/raddbg_widgets.c | 47 ++- 11 files changed, 1125 insertions(+), 875 deletions(-) diff --git a/project.4coder b/project.4coder index 0be9237b..0d7a82c4 100644 --- a/project.4coder +++ b/project.4coder @@ -48,7 +48,8 @@ commands = //- rjf: fkey command slots (change locally but do not commit) .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "pushd build && textperf.exe --capture && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 8dc7469c..dd4ff355 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -4,53 +4,53 @@ //////////////////////////////// //~ rjf: Built-In Command Tables -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ) -// / | | | \___ _________________________________/ | | | | | -// / | | | \ / | | | | | -D_CmdTable: // | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | \___ _________________________________/ | | | | | | +// / | | | \ / | | | | | | +D_CmdTable: // | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 Entity null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" } - {LaunchAndInit 1 1 Entity null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" } - {Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" } - {KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" } - {Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" } - {Continue 1 1 Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" } - {StepIntoInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" } - {StepOverInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" } - {StepIntoLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" } - {StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" } - {StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" } - {Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" } - {SoftHaltRefresh 1 1 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" } - {SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" } + {LaunchAndRun 1 1 Entity null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndInit 1 1 Entity null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } + {KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } + {Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } + {Continue 1 1 Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } + {StepIntoInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } + {StepOverInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } + {StepIntoLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } + {StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } + {StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } + {Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } + {SoftHaltRefresh 1 1 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" } - {RunToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" } - {Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" } - {Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" } - {StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" } - {StepOver 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" } + {RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {RunToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" "" } + {Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } + {Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } + {StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } + {StepOver 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } //- rjf: debug control context management operations - {FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" } - {ThawThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" } - {FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" } - {ThawProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" } - {FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" } - {ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" } - {FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" } - {ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" } - {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "freeze_entity" "Freeze Entity" "Freezes an entity." "" } - {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "thaw_entity" "Thaw Entity" "Thaws an entity." "" } + {FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } + {ThawThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } + {FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } + {ThawProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } + {FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } + {ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } + {FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } + {ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } + {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration - {SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" } - {SetEntityName 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" } + {SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } + {SetEntityName 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } //- rjf: attaching - {Attach 1 1 PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" } + {Attach 1 1 PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } } @enum D_CmdKind: diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index ff307b28..6c65f5e4 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1872,35 +1872,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } } - ////////////////////////////// - //- rjf: sync with di parsers - // - ProfScope("sync with di parsers") - { - DI_EventList events = di_p2u_pop_events(scratch.arena, 0); - for(DI_EventNode *n = events.first; n != 0; n = n->next) - { - DI_Event *event = &n->v; - switch(event->kind) - { - default:{}break; - case DI_EventKind_ConversionStarted: - { - RD_Entity *task = rd_entity_alloc(rd_entity_root(), RD_EntityKind_ConversionTask); - rd_entity_equip_name(task, event->string); - }break; - case DI_EventKind_ConversionEnded: - { - RD_Entity *task = rd_entity_from_name_and_kind(event->string, RD_EntityKind_ConversionTask); - if(!rd_entity_is_nil(task)) - { - rd_entity_mark_for_deletion(task); - } - }break; - } - } - } - ////////////////////////////// //- rjf: process top-level commands // diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d63c1116..c232a9a1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -36,6 +36,49 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; +RD_VocabularyInfo rd_vocabulary_info_table[39] = +{ +{str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, +{str8_lit_comp("watch_pin"), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pin"), str8_lit_comp("Watch Pins"), RD_IconKind_Pin}, +{str8_lit_comp("watch"), str8_lit_comp("watches"), str8_lit_comp("Watch"), str8_lit_comp("Watches"), RD_IconKind_Binoculars}, +{str8_lit_comp("view_rule"), str8_lit_comp("view_rules"), str8_lit_comp("View Rule"), str8_lit_comp("View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("breakpoint"), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoint"), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled}, +{str8_lit_comp("condition"), str8_lit_comp("conditions"), str8_lit_comp("Condition"), str8_lit_comp("Conditions"), RD_IconKind_Null}, +{str8_lit_comp("location"), str8_lit_comp("locations"), str8_lit_comp("Location"), str8_lit_comp("Locations"), RD_IconKind_Null}, +{str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, +{str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, +{str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, +{str8_lit_comp("working_directory"), str8_lit_comp("working_directories"), str8_lit_comp("Working Directory"), str8_lit_comp("Working Directories"), RD_IconKind_FolderClosedFilled}, +{str8_lit_comp("entry_point"), str8_lit_comp("entry_points"), str8_lit_comp("Entry Point"), str8_lit_comp("Entry Points"), RD_IconKind_Null}, +{str8_lit_comp("stdout_path"), str8_lit_comp("stdout_paths"), str8_lit_comp("Standard Output Path"), str8_lit_comp("Standard Output Paths"), RD_IconKind_Null}, +{str8_lit_comp("stderr_path"), str8_lit_comp("stderr_paths"), str8_lit_comp("Standard Error Path"), str8_lit_comp("Standard Error Paths"), RD_IconKind_Null}, +{str8_lit_comp("stdin_path"), str8_lit_comp("stdin_paths"), str8_lit_comp("Standard Input Path"), str8_lit_comp("Standard Input Paths"), RD_IconKind_Null}, +{str8_lit_comp("window"), str8_lit_comp("windows"), str8_lit_comp("Window"), str8_lit_comp("Windows"), RD_IconKind_Null}, +{str8_lit_comp("panel"), str8_lit_comp("panels"), str8_lit_comp("Panel"), str8_lit_comp("Panels"), RD_IconKind_Null}, +{str8_lit_comp("view"), str8_lit_comp("views"), str8_lit_comp("View"), str8_lit_comp("Views"), RD_IconKind_Null}, +{str8_lit_comp("tab"), str8_lit_comp("tabs"), str8_lit_comp("Tab"), str8_lit_comp("Tabs"), RD_IconKind_Null}, +{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Null}, +{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_Null}, +{str8_lit_comp("src"), str8_lit_comp("srcs"), str8_lit_comp("Source"), str8_lit_comp("Sources"), RD_IconKind_Null}, +{str8_lit_comp("dst"), str8_lit_comp("dsts"), str8_lit_comp("Destination"), str8_lit_comp("Destinations"), RD_IconKind_Null}, +{str8_lit_comp("conversion_task"), str8_lit_comp("conversion_tasks"), str8_lit_comp("Conversion Task"), str8_lit_comp("Conversion Tasks"), RD_IconKind_Null}, +{str8_lit_comp("conversion_fail"), str8_lit_comp("conversion_fails"), str8_lit_comp("Conversion Fail"), str8_lit_comp("Conversion Fails"), RD_IconKind_Null}, +{str8_lit_comp("lang"), str8_lit_comp("langs"), str8_lit_comp("Language"), str8_lit_comp("Languages"), RD_IconKind_Null}, +{str8_lit_comp("arch"), str8_lit_comp("archs"), str8_lit_comp("Architecture"), str8_lit_comp("Architectures"), RD_IconKind_Null}, +{str8_lit_comp("expr"), str8_lit_comp("exprs"), str8_lit_comp("Expression"), str8_lit_comp("Expressions"), RD_IconKind_Null}, +{str8_lit_comp("size"), str8_lit_comp("sizes"), str8_lit_comp("Size"), str8_lit_comp("Sizes"), RD_IconKind_Null}, +{str8_lit_comp("count"), str8_lit_comp("counts"), str8_lit_comp("Count"), str8_lit_comp("Counts"), RD_IconKind_Null}, +{str8_lit_comp("bool"), str8_lit_comp("bools"), str8_lit_comp("Boolean"), str8_lit_comp("Booleans"), RD_IconKind_Null}, +{str8_lit_comp("w"), str8_lit_comp("ws"), str8_lit_comp("Width"), str8_lit_comp("Widths"), RD_IconKind_Null}, +{str8_lit_comp("h"), str8_lit_comp("hs"), str8_lit_comp("Height"), str8_lit_comp("Heights"), RD_IconKind_Null}, +{str8_lit_comp("fmt"), str8_lit_comp("fmts"), str8_lit_comp("Format"), str8_lit_comp("Formats"), RD_IconKind_Null}, +{str8_lit_comp("addresses"), str8_lit_comp("addresses"), str8_lit_comp("Addresses"), str8_lit_comp("Addresses"), RD_IconKind_Null}, +{str8_lit_comp("code_bytes"), str8_lit_comp("code_bytes"), str8_lit_comp("Code Bytes"), str8_lit_comp("Code Bytes"), RD_IconKind_Null}, +{str8_lit_comp("vtx"), str8_lit_comp("vtxs"), str8_lit_comp("Vertex Buffer"), str8_lit_comp("Vertex Buffers"), RD_IconKind_Null}, +{str8_lit_comp("vtx_size"), str8_lit_comp("vtx_sizes"), str8_lit_comp("Vertex Buffer Size"), str8_lit_comp("Vertex Buffer Sizes"), RD_IconKind_Null}, +}; + String8 d_entity_kind_display_string_table[27] = { str8_lit_comp("Nil"), @@ -238,221 +281,221 @@ Rng1U64 rd_reg_slot_range_table[40] = RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp("Apply User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_entity"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp("Enable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_entity"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp("Disable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_entity"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp("Select Entity"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_entity"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp("Remove Entity"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp("Name Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_entity"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp("Condition Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_entity"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp("Relocate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_cursor"), str8_lit_comp("Runs the selected thread to the current cursor."), str8_lit_comp("line"), str8_lit_comp("Run To Cursor"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exception_filters"), str8_lit_comp("Opens the exception filters view."), str8_lit_comp("exceptions,filters"), str8_lit_comp("Exception Filters"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), str8_lit_comp("Show File In Explorer"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, +{ str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Apply User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_entity"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_entity"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_entity"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Entity"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_entity"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Entity"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_entity"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_entity"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("exception_filters"), str8_lit_comp("Opens the exception filters view."), str8_lit_comp("exceptions,filters"), str8_lit_comp(""), str8_lit_comp("Exception Filters"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, }; RD_StringBindingPair rd_default_binding_table[110] = @@ -468,7 +511,7 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("step_into"), {OS_Key_F11, 0 }}, {str8_lit_comp("step_over"), {OS_Key_F10, 0 }}, -{str8_lit_comp("run_to_cursor"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("run_to_line"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, {str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, @@ -850,7 +893,7 @@ RD_ViewRuleInfo rd_view_rule_kind_info_table[35] = {str8_lit_comp("call_stack"), str8_lit_comp("Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top."), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(call_stack)}, {str8_lit_comp("modules"), str8_lit_comp("Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module."), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(modules)}, {str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, -{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, +{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, {str8_lit_comp("output"), str8_lit_comp("Displays debug strings, output from attached processes."), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(output)}, {str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, {str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index eeb77547..a2b0eb95 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -181,6 +181,7 @@ RD_CmdKind_Open, RD_CmdKind_Switch, RD_CmdKind_SwitchToPartnerFile, RD_CmdKind_RecordFileInProject, +RD_CmdKind_ShowFileInExplorer, RD_CmdKind_GoToDisassembly, RD_CmdKind_GoToSource, RD_CmdKind_SetFileReplacementPath, @@ -267,7 +268,6 @@ RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, -RD_CmdKind_RunToCursor, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -546,6 +546,16 @@ RD_SettingCode_HintCodeText, RD_SettingCode_COUNT, } RD_SettingCode; +typedef struct RD_VocabularyInfo RD_VocabularyInfo; +struct RD_VocabularyInfo +{ +String8 code_name; +String8 code_name_plural; +String8 display_name; +String8 display_name_plural; +RD_IconKind icon_kind; +}; + typedef struct RD_Regs RD_Regs; struct RD_Regs { @@ -606,6 +616,7 @@ struct RD_CmdKindInfo String8 string; String8 description; String8 search_tags; +String8 ctx_filter; String8 display_name; RD_IconKind icon_kind; RD_CmdKindFlags flags; @@ -780,6 +791,7 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_apply_cmd_kind_table[4]; +extern RD_VocabularyInfo rd_vocabulary_info_table[39]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index c8812019..0c40c45d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -48,6 +48,69 @@ RD_CfgSrcTable: @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.apply_cmd)`; } +//////////////////////////////// +//~ rjf: Vocabulary Maps + +@table(code_name code_name_plural display_name display_name_plural icon_kind) +RD_VocabularyMap: +// NOTE(rjf): the _ character is used as a fastpath for default rules. when +// pluralizing, you just append an `s`, and so on. +{ + {auto_view_rule _ "Auto View Rule" _ Binoculars } + {file_path_map _ "File Path Map" _ FileOutline } + {watch_pin _ "Watch Pin" _ Pin } + {watch watches "Watch" "Watches" Binoculars } + {view_rule _ "View Rule" _ Binoculars } + {breakpoint _ "Breakpoint" _ CircleFilled } + {condition _ "Condition" _ Null } + {location _ "Location" _ Null } + {target _ "Target" _ Target } + {executable _ "Executable" _ Module } + {arguments arguments "Arguments" "Arguments" Null } + {working_directory working_directories "Working Directory" "Working Directories" FolderClosedFilled } + {entry_point _ "Entry Point" _ Null } + {stdout_path _ "Standard Output Path" _ Null } + {stderr_path _ "Standard Error Path" _ Null } + {stdin_path _ "Standard Input Path" _ Null } + {window _ "Window" _ Null } + {panel _ "Panel" _ Null } + {view _ "View" _ Null } + {tab _ "Tab" _ Null } + {recent_project _ "Recent Project" _ Null } + {recent_file _ "Recent File" _ Null } + {src _ "Source" _ Null } + {dst _ "Destination" _ Null } + {conversion_task _ "Conversion Task" _ Null } + {conversion_fail _ "Conversion Fail" _ Null } + {lang _ "Language" _ Null } + {arch _ "Architecture" _ Null } + {expr _ "Expression" _ Null } + {size _ "Size" _ Null } + {count _ "Count" _ Null } + {bool _ "Boolean" _ Null } + {w _ "Width" _ Null } + {h _ "Height" _ Null } + {fmt _ "Format" _ Null } + {addresses addresses "Addresses" "Addresses" Null } + {code_bytes code_bytes "Code Bytes" "Code Bytes" Null } + {vtx _ "Vertex Buffer" _ Null } + {vtx_size _ "Vertex Buffer Size" _ Null } +} + +@struct RD_VocabularyInfo: +{ + `String8 code_name`; + `String8 code_name_plural`; + `String8 display_name`; + `String8 display_name_plural`; + `RD_IconKind icon_kind`; +} + +@data(RD_VocabularyInfo) rd_vocabulary_info_table: +{ + @expand(RD_VocabularyMap a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; +} + //////////////////////////////// //~ rjf: Entity Kind Tables @@ -228,274 +291,274 @@ RD_RegTable: //////////////////////////////// //~ rjf: Command Table -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ) -// / | | | \___ _____________________________________________________/ | | | | | -// / | | | \ / | | | | | -RD_CmdTable: // | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | \___ _____________________________________________________/ | | | | | | +// / | | | \ / | | | | | | +RD_CmdTable: // | | | | | | | | | | | { //- rjf: exiting - {Exit 1 1 Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" } + {Exit 1 1 Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } //- rjf: top-level lister - {OpenLister 1 1 Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" } + {OpenLister 1 1 Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } //- rjf: command runner - {RunCommand 1 1 CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" } + {RunCommand 1 1 CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } //- rjf: os event passthrough - {OSEvent 0 0 Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" } + {OSEvent 0 0 Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" } - {SelectUnwind 0 1 Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" } - {UpOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" } - {DownOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" } + {SelectThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 0 1 Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {UpOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } + {DownOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } //- rjf: font sizes - {IncUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" } - {DecUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" } - {IncCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" } - {DecCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" } + {IncUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } + {DecUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } + {IncCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } + {DecCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } //- rjf: windows - {OpenWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" } - {CloseWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" } - {ToggleFullscreen 1 1 Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" } - {BringToFront 0 1 Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" } + {OpenWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {CloseWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } + {ToggleFullscreen 1 1 Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } + {BringToFront 0 1 Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } //- rjf: popups - {PopupAccept 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" } - {PopupCancel 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" } + {PopupAccept 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } + {PopupCancel 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } //- rjf: panel splitting - {ResetToDefaultPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" } - {ResetToCompactPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" } - {NewPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" } - {NewPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" } - {NewPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" } - {NewPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" } - {SplitPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" } + {ResetToDefaultPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } + {ResetToCompactPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {NewPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } + {NewPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } + {NewPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } + {NewPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } + {SplitPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } //- rjf: panel rotation - {RotatePanelColumns 1 1 Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" } + {RotatePanelColumns 1 1 Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } //- rjf: focused panel changing - {NextPanel 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" } - {PrevPanel 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" } - {FocusPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" } - {FocusPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" } - {FocusPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" } - {FocusPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" } - {FocusPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" } + {NextPanel 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } + {PrevPanel 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } + {FocusPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } + {FocusPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } + {FocusPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } + {FocusPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } + {FocusPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } //- rjf: undo/redo - {Undo 0 0 Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" } - {Redo 0 0 Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" } + {Undo 0 0 Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } + {Redo 0 0 Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } //- rjf: focus history - {GoBack 0 0 Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" } - {GoForward 0 0 Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" } + {GoBack 0 0 Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } + {GoForward 0 0 Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } //- rjf: panel removal - {ClosePanel 1 1 Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" } + {ClosePanel 1 1 Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } //- rjf: panel tab - {FocusTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" } - {NextTab 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" } - {PrevTab 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" } - {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" } - {MoveTabLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" } - {OpenTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" } - {CloseTab 1 1 View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" } - {MoveTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" } - {TabBarTop 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" } - {TabBarBottom 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" } + {FocusTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } + {NextTab 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } + {PrevTab 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } + {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } + {MoveTabLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } + {OpenTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {CloseTab 1 1 View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {TabBarTop 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } + {TabBarBottom 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } //- rjf: files - {SetCurrentPath 0 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" } - {Open 1 1 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" } - {Switch 1 1 Entity null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" } - {SwitchToPartnerFile 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" } - {RecordFileInProject 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" } + {SetCurrentPath 0 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } + {Open 1 1 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Switch 1 1 Entity null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {SwitchToPartnerFile 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } + {RecordFileInProject 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } + {ShowFileInExplorer 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm - {GoToDisassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" } - {GoToSource 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" } + {GoToDisassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } + {GoToSource 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } //- rjf: override file links - {SetFileReplacementPath 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" } + {SetFileReplacementPath 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" } - {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" } - {OpenRecentProject 1 1 Entity null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" } + {OpenUser 1 1 FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenRecentProject 1 1 Entity null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: loading/applying stateful config changes - {ApplyUserData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" } - {ApplyProjectData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_project_data" "Apply Project Data" "Applies project data from the active project file." "" } + {ApplyUserData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" "" } + {ApplyProjectData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_project_data" "Apply Project Data" "Applies project data from the active project file." "" "" } //- rjf: writing config changes - {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" } - {WriteProjectData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" } + {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } + {WriteProjectData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } //- rjf: meta controls - {Edit 1 1 Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" } - {Accept 1 1 Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" } - {Cancel 1 1 Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" } + {Edit 1 1 Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } + {Accept 1 1 Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } + {Cancel 1 1 Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } //- rjf: directional movement & text controls - {MoveLeft 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" } - {MoveRight 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" } - {MoveUp 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" } - {MoveDown 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" } - {MoveLeftSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" } - {MoveRightSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" } - {MoveUpSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" } - {MoveDownSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" } - {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Select" "Moves the cursor or selection left one chunk." "" } - {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Select" "Moves the cursor or selection right one chunk." "" } - {MoveUpChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" } - {MoveDownChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" } - {MoveUpPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" } - {MoveDownPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" } - {MoveUpWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" } - {MoveDownWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" } - {MoveLeftChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" } - {MoveRightChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" } - {MoveUpChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" } - {MoveDownChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" } - {MoveUpPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" } - {MoveDownPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" } - {MoveUpWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" } - {MoveDownWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" } - {MoveUpReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" } - {MoveDownReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" } - {MoveHome 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" } - {MoveEnd 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" } - {MoveHomeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" } - {MoveEndSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" } - {SelectAll 1 1 Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" } - {DeleteSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" } - {DeleteChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" } - {BackspaceSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" } - {BackspaceChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" } - {Copy 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" } - {Cut 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" } - {Paste 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" } - {InsertText 0 1 Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" } + {MoveLeft 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } + {MoveRight 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } + {MoveUp 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } + {MoveDown 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } + {MoveLeftSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } + {MoveRightSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } + {MoveUpSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } + {MoveDownSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } + {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } + {MoveDownPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } + {MoveUpWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } + {MoveDownWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } + {MoveLeftChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } + {MoveDownPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } + {MoveUpWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } + {MoveDownWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } + {MoveUpReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } + {MoveDownReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } + {MoveHome 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } + {MoveEnd 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } + {MoveHomeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } + {MoveEndSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } + {SelectAll 1 1 Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } + {DeleteSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } + {DeleteChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } + {BackspaceSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } + {BackspaceChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } + {Copy 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } + {Cut 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } + {Paste 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } + {InsertText 0 1 Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } //- rjf: code navigation - {GoToLine 1 1 Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" } - {GoToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" } - {CenterCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" } - {ContainCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" } - {FindTextForward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" } - {FindTextBackward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" } - {FindNext 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" } - {FindPrev 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" } + {GoToLine 1 1 Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } + {CenterCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } + {ContainCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } + {FindTextForward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } + {FindTextBackward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } + {FindNext 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } + {FindPrev 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } //- rjf: thread finding - {FindThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" } - {FindSelectedThread 1 1 Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" } + {FindThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } + {FindSelectedThread 1 1 Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } //- rjf: name finding - {GoToName 1 1 String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" } - {GoToNameAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" } + {GoToName 1 1 String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } + {GoToNameAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } //- rjf: watch expressions - {ToggleWatchExpression 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" } - {ToggleWatchExpressionAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" } - {ToggleWatchExpressionAtMouse 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" } + {ToggleWatchExpression 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } + {ToggleWatchExpressionAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } + {ToggleWatchExpressionAtMouse 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: memory view parameterization - {SetColumns 1 1 Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" } + {SetColumns 1 1 Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } //- rjf: disassembly view parameterization - {ToggleAddressVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" } - {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" } + {ToggleAddressVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } + {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general entity operations - {EnableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" } - {DisableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" } - {SelectEntity 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" } - {RemoveEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" } - {NameEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" } - {ConditionEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" } - {DuplicateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" } - {RelocateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" } + {EnableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" "" } + {DisableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" "" } + {SelectEntity 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" "" } + {RemoveEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" "" } + {NameEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" "" } + {ConditionEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" "" } + {DuplicateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" "" } + {RelocateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" } - {AddAddressBreakpoint 1 0 Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" } - {AddFunctionBreakpoint 1 0 String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" } - {ToggleBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" } - {EnableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" } - {DisableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" } + {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddAddressBreakpoint 1 0 Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {AddFunctionBreakpoint 1 0 String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } + {ToggleBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {EnableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" } - {ToggleWatchPin 1 0 String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" } + {AddWatchPin 1 1 String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } - //- rjf: cursor operations - {RunToCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_cursor" "Run To Cursor" "Runs the selected thread to the current cursor." "line" } - {SetNextStatement 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" } + //- rjf: line operations + {SetNextStatement 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" } - {SelectTarget 1 1 Entity null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" } - {EnableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" } - {DisableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" } + {AddTarget 1 1 FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {SelectTarget 1 1 Entity null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching - {RegisterAsJITDebugger 1 1 Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" } + {RegisterAsJITDebugger 1 1 Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } //- rjf: snap-to-code-location - {FindCodeLocation 0 1 FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" } + {FindCodeLocation 0 1 FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } //- rjf: general-purpose view filtering - {Filter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "filter" "Filter" "Begins filtering the active view." "sort,search,filter,find" } - {ApplyFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "apply_filter" "Apply Filter" "Applies the typed filter to the active view." "sort,search,filter,find,apply" } - {ClearFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "clear_filter" "Clear Filter" "Clears the filter applied to the active view." "sort,search,filter,find,clear" } + {Filter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "filter" "Filter" "Begins filtering the active view." "sort,search,filter,find" "" } + {ApplyFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "apply_filter" "Apply Filter" "Applies the typed filter to the active view." "sort,search,filter,find,apply" "" } + {ClearFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "clear_filter" "Clear Filter" "Clears the filter applied to the active view." "sort,search,filter,find,clear" "" } //- rjf: view drivers - {GettingStarted 1 1 Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" } - {Commands 0 0 Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" } - {Target 0 0 Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" } - {Targets 1 1 Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" } - {FilePathMap 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" } - {AutoViewRules 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" } - {Breakpoints 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" } - {WatchPins 1 1 Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" } - {Scheduler 1 1 Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" } - {CallStack 1 1 Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" } - {Modules 1 1 Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" } - {Watch 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" } - {Locals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" } - {Registers 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" } - {Globals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" } - {ThreadLocals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" } - {Types 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" } - {Procedures 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" } - {PendingFile 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" } - {Disassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" } - {Output 1 1 Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" } - {Memory 1 1 Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" } - {ExceptionFilters 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "exception_filters" "Exception Filters" "Opens the exception filters view." "exceptions,filters" } - {Settings 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" } + {GettingStarted 1 1 Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } + {Commands 0 0 Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } + {Target 0 0 Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } + {Targets 1 1 Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } + {FilePathMap 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } + {AutoViewRules 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } + {Breakpoints 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } + {WatchPins 1 1 Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } + {Scheduler 1 1 Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } + {CallStack 1 1 Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } + {Modules 1 1 Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } + {Watch 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } + {Locals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } + {Registers 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } + {Globals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } + {ThreadLocals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } + {Types 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } + {Procedures 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } + {PendingFile 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } + {Disassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } + {Output 1 1 Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } + {Memory 1 1 Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } + {ExceptionFilters 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "exception_filters" "Exception Filters" "Opens the exception filters view." "exceptions,filters" "" } + {Settings 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" } - {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" } - {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" } + {PickFile 0 0 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack - {PushQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" } - {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" } - {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" } + {PushQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } + {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } + {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } //- rjf: developer commands - {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" } - {LogMarker 1 1 Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" } + {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } + {LogMarker 1 1 Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } } @enum RD_CmdKind: @@ -520,6 +583,7 @@ RD_CmdTable: // | | | | `String8 string`; `String8 description`; `String8 search_tags`; + `String8 ctx_filter`; `String8 display_name`; `RD_IconKind icon_kind`; `RD_CmdKindFlags flags`; @@ -530,9 +594,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -555,7 +619,7 @@ RD_DefaultBindingTable: { "restart" F5 ctrl shift 0 } { "step_into" F11 0 0 0 } { "step_over" F10 0 0 0 } - { "run_to_cursor" F10 ctrl 0 0 } + { "run_to_line" F10 ctrl 0 0 } { "set_next_statement" F10 ctrl shift 0 } //- rjf: font sizes @@ -902,58 +966,58 @@ RD_CollectionTable: //////////////////////////////// //~ rjf: View Rules -@table(name name_lower display_name params_schema icon can_filter filter_is_code typing_automatically_filters can_use_in_watch_table can_fill_value_cell can_expand show_in_docs description) +@table(name name_lower display_name params_schema icon can_filter filter_is_code typing_automatically_filters can_use_in_watch_table can_fill_value_cell can_expand show_in_docs description) RD_ViewRuleTable: { //- rjf: basics - { Empty empty "" "" Null 0 0 0 0 0 0 0 "" } - { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } + { Empty empty "" "" Null 0 0 0 0 0 0 0 "" } + { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } //- rjf: meta (settings) - { ExceptionFilters exception_filters "Exception Filters" "" Gear 0 0 0 0 0 0 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } - { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } + { ExceptionFilters exception_filters "Exception Filters" "" Gear 0 0 0 0 0 0 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } + { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } //- rjf: temporary view for loading files - must analyze file before picking viewer - { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } + { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } //- rjf: query listers - { Commands commands "Commands" "" List 0 0 0 0 0 0 0 "" } - { FileSystem file_system "File System" "" FileOutline 0 0 0 0 0 0 0 "" } - { SystemProcesses system_processes "System Processes" "" Null 0 0 0 0 0 0 0 "" } - { EntityLister entity_lister "Entities" "" Null 0 0 0 0 0 0 0 "" } - { CtrlEntityLister ctrl_entity_lister "Control Entities" "" Null 0 0 0 0 0 0 0 "" } - { SymbolLister symbol_lister "Symbols" "" Null 0 0 0 0 0 0 0 "" } + { Commands commands "Commands" "" List 0 0 0 0 0 0 0 "" } + { FileSystem file_system "File System" "" FileOutline 0 0 0 0 0 0 0 "" } + { SystemProcesses system_processes "System Processes" "" Null 0 0 0 0 0 0 0 "" } + { EntityLister entity_lister "Entities" "" Null 0 0 0 0 0 0 0 "" } + { CtrlEntityLister ctrl_entity_lister "Control Entities" "" Null 0 0 0 0 0 0 0 "" } + { SymbolLister symbol_lister "Symbols" "" Null 0 0 0 0 0 0 0 "" } //- rjf: watch or watch-style tables - { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } - { Locals locals "Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Registers registers "Registers" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Globals globals "Globals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { ThreadLocals thread_locals "Thread Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Types types "Types" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Procedures procedures "Procedures" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } + { Locals locals "Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Registers registers "Registers" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Globals globals "Globals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { ThreadLocals thread_locals "Thread Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Types types "Types" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Procedures procedures "Procedures" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } //- rjf: configuration watch tables - { Targets targets "Targets" "" Target 1 1 1 0 0 0 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } - { FilePathMap file_path_map "File Path Map" "" FileOutline 1 1 1 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } - { AutoViewRules auto_view_rules "Auto View Rules" "" Binoculars 1 1 1 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } - { Breakpoints breakpoints "Breakpoints" "" CircleFilled 1 1 1 0 0 0 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } - { WatchPins watch_pins "Watch Pins" "" Pin 1 1 1 0 0 0 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } + { Targets targets "Targets" "" Target 1 1 1 0 0 0 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } + { FilePathMap file_path_map "File Path Map" "" FileOutline 1 1 1 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } + { AutoViewRules auto_view_rules "Auto View Rules" "" Binoculars 1 1 1 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } + { Breakpoints breakpoints "Breakpoints" "" CircleFilled 1 1 1 0 0 0 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } + { WatchPins watch_pins "Watch Pins" "" Pin 1 1 1 0 0 0 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } //- rjf: debug entity info watch tables - { Scheduler scheduler "Scheduler" "" Scheduler 1 1 1 0 0 0 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } - { CallStack call_stack "Call Stack" "" Thread 1 1 1 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } - { Modules modules "Modules" "" Module 1 1 1 0 0 0 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } + { Scheduler scheduler "Scheduler" "" Scheduler 1 1 1 0 0 0 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } + { CallStack call_stack "Call Stack" "" Thread 1 1 1 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } + { Modules modules "Modules" "" Module 1 1 1 0 0 0 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } //- rjf: data visualizers - { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } - { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } - { Output output "Output" "" List 0 0 0 0 0 0 1 "Displays debug strings, output from attached processes." } - { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } - { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } - { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } - { ColorRGBA color_rgba "Color (RGBA)" "" Palette 0 0 0 1 1 1 1 "Visualizes memory as an RGBA color." } - { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } + { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } + { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } + { Output output "Output" "" List 0 0 0 0 0 0 1 "Displays debug strings, output from attached processes." } + { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } + { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } + { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } + { ColorRGBA color_rgba "Color (RGBA)" "" Palette 0 0 0 1 1 1 1 "Visualizes memory as an RGBA color." } + { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } } @enum RD_ViewRuleKind: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5364e3c4..41c55c85 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3068,6 +3068,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_handle = cfg_handle; view_state->arena = arena_alloc(); + view_state->loading_t = 1.f; } if(view_state != &rd_nil_view_state) { @@ -3243,7 +3244,7 @@ internal String8 rd_view_expr_string(void) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); - RD_Cfg *expr = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *expr = rd_cfg_child_from_string(view, str8_lit("expression")); String8 expr_string = expr->first->string; return expr_string; } @@ -3288,7 +3289,7 @@ internal void rd_store_view_expr_string(String8 string) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); for(RD_Cfg *child = expr->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { next = child->next; @@ -3797,14 +3798,14 @@ rd_window_frame(void) default:{}break; //////////////////////// - //- rjf: frontend entity tooltips + //- rjf: cfg tooltips // - case RD_RegSlot_Entity: + case RD_RegSlot_Cfg: UI_Tooltip { // rjf: unpack - RD_Entity *entity = rd_entity_from_handle(regs->entity); - DR_FancyStringList fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); + RD_Cfg *cfg = rd_cfg_from_handle(regs->cfg); + DR_FancyStringList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) @@ -3812,12 +3813,6 @@ rd_window_frame(void) UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fancy_strings(box, &fstrs); } - - // rjf: temporary target -> display - if(entity->kind == RD_EntityKind_Target && entity->cfg_src == RD_CfgSrc_CommandLine) - { - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_label(str8_lit("Specified on the command line; will not be saved.")); - } }break; //////////////////////// @@ -3958,9 +3953,8 @@ rd_window_frame(void) .view = rd_state->drag_drop_regs->view) { Temp scratch = scratch_begin(0, 0); - RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("expression")); RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); { //- rjf: tab dragging @@ -4134,34 +4128,6 @@ rd_window_frame(void) } ui_divider(ui_em(1.f, 1.f)); - - //- rjf: draw entity tree -#if 0 - RD_EntityRec rec = {0}; - S32 indent = 0; - UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("Entity Tree:"); - for(RD_Entity *e = rd_entity_root(); !rd_entity_is_nil(e); e = rec.next) - { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_pref_height(ui_children_sum(1)); - UI_Row - { - ui_spacer(ui_em(2.f*indent, 1.f)); - RD_Entity *dst = rd_entity_from_handle(e->entity_handle); - if(!rd_entity_is_nil(dst)) - { - ui_labelf("[link] %S -> %S", e->string, dst->string); - } - else - { - ui_labelf("%S: %S", d_entity_kind_display_string_table[e->kind], e->string); - } - } - rec = rd_entity_rec_depth_first_pre(e, rd_entity_root()); - indent += rec.push_count; - indent -= rec.pop_count; - } -#endif } } @@ -4198,22 +4164,49 @@ rd_window_frame(void) // RD_Lister *lister = task->lister; RD_ListerFlags flags = lister->regs->lister_flags; - lister->regs->string = str8(lister->input_buffer, lister->input_string_size); - lister->regs->cursor = lister->input_cursor; - lister->regs->mark = lister->input_mark; UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); ////////////////////////// //- rjf: parameters -> lister items // - RD_ListerItemArray item_array = rd_lister_item_array_from_regs(scratch.arena, lister->regs); + RD_ListerItemArray item_array = rd_lister_item_array_from_regs_needle_cursor_off(scratch.arena, lister->regs, str8(lister->input_buffer, lister->input_string_size), lister->input_cursor.column-1); + + ////////////////////////// + //- rjf: selected item hash -> cursor + // + Vec2S64 cursor = {0}; + for EachIndex(idx, item_array.count) + { + RD_ListerItem *item = &item_array.v[idx]; + U64 hash = rd_hash_from_lister_item(item); + if(hash == lister->selected_item_hash) + { + cursor.y = (S64)(idx+1); + break; + } + } + + ////////////////////////// + //- rjf: push autocompletion hint + // + if(1 <= cursor.y && cursor.y <= item_array.count) + { + RD_ListerItem *item = &item_array.v[cursor.y-1]; + if(item->flags & RD_ListerItemFlag_Autocompletion) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); + } + } ////////////////////////// //- rjf: animate values // F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); - F32 lister_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_open"), 1.f); - F32 lister_num_of_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_num_of_rows"), (F32)item_array.count); + F32 lister_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_open_%p", lister), 1.f); + F32 lister_num_of_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_num_of_rows_%p", lister), (F32)item_array.count); lister->scroll_pt.off -= lister->scroll_pt.off*fast_rate; ////////////////////////// @@ -4221,10 +4214,10 @@ rd_window_frame(void) // F32 squish = (0.25f - 0.25f*lister_open_t); F32 transparency = (1.f - lister_open_t); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + F32 row_height_px = floor_f32(ui_top_font_size()*3.f); if(lister->regs->lister_flags & RD_ListerFlag_Descriptions) { - row_height_px += floor_f32(ui_top_font_size()*3.5f); + row_height_px += floor_f32(ui_top_font_size()*3.f); } Vec2F32 content_rect_dim = dim_2f32(content_rect); Vec2F32 content_rect_center = center_2f32(content_rect); @@ -4233,17 +4226,22 @@ rd_window_frame(void) { line_edit_height_px = floor_f32(ui_top_font_size()*3.f); } + line_edit_height_px = Min(line_edit_height_px, row_height_px); F32 lister_height_max = content_rect_dim.y*0.9f; Vec2F32 lister_dim_px = { content_rect_dim.x*0.5f, line_edit_height_px + lister_num_of_rows_t*row_height_px, }; - if(!ui_box_is_nil(anchor_box)) + if(!ui_box_is_nil(anchor_box) && flags & RD_ListerFlag_SizeByAnchor) { lister_dim_px.x = dim_2f32(anchor_box->rect).x; } - lister_dim_px.x = Max(lister_dim_px.x, ui_top_font_size()*30.f); + else if(!ui_box_is_nil(anchor_box)) + { + lister_dim_px.x = ui_top_font_size()*50.f; + } + lister_dim_px.x = Max(lister_dim_px.x, ui_top_font_size()*50.f); lister_dim_px.y = Min(lister_dim_px.y, lister_height_max); Vec2F32 lister_pos_px = { @@ -4289,10 +4287,11 @@ rd_window_frame(void) UI_WidthFill UI_Parent(lister_box) UI_Focus(UI_FocusKind_On) + RD_Font(RD_FontSlot_Code) { UI_PrefHeight(ui_px(line_edit_height_px, 1.f)) { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border, + UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &lister->input_cursor, @@ -4318,118 +4317,136 @@ rd_window_frame(void) .item_range = r1s64(0, item_array.count), .cursor_min_is_empty_selection[Axis2_Y] = 1, }; - Vec2S64 cursor = {0}; Rng1S64 visible_row_range = {0}; UI_ScrollListSignal scroll_list_signal = {0}; UI_WidthFill UI_HeightFill UI_Parent(lister_box) + UI_Focus(UI_FocusKind_On) UI_ScrollList(¶ms, &lister->scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) + UI_Focus(UI_FocusKind_Null) RD_Palette(RD_PaletteCode_ImplicitButton) { UI_HoverCursor(OS_Cursor_HandPoint) for(S64 idx = visible_row_range.min; 0 <= idx && idx < visible_row_range.max && idx < item_array.count; idx += 1) { RD_ListerItem *item = &item_array.v[idx]; - - //- rjf: build the top-level box for the item - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - - //- rjf: build item contents - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) + B32 item_is_selected = (idx == cursor.y-1); + UI_FocusHot(item_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) { - // rjf: icon - if(item->icon_kind != RD_IconKind_Null) - UI_PrefWidth(ui_em(2.f, 1.f)) - UI_Column - UI_Padding(ui_pct(1, 0)) - RD_Font(RD_FontSlot_Icons) - { - ui_label(rd_icon_kind_text_table[item->icon_kind]); - } + //- rjf: build the top-level box for the item + UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - // rjf: name / description - UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) + //- rjf: build item contents + UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) { - // rjf: name - UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) + // rjf: icon + if(item->icon_kind != RD_IconKind_Null) + UI_PrefWidth(ui_em(2.f, 1.f)) + UI_Column + UI_Padding(ui_pct(1, 0)) + RD_Font(RD_FontSlot_Icons) { - // rjf: display name - RD_Font(item->is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + ui_label(rd_icon_kind_text_table[item->icon_kind]); + } + + // rjf: name / description + UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) + { + // rjf: name + UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) { - UI_Box *box = item->is_non_code ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); - ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); + // rjf: display name + RD_Font(item->flags & RD_ListerItemFlag_IsNonCode ? RD_FontSlot_Main : RD_FontSlot_Code) + { + UI_Box *box = item->flags & RD_ListerItemFlag_IsNonCode ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); + ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); + } + + // rjf: kind name + if(flags & RD_ListerFlag_KindLabel && item->kind_name.size != 0) + { + ui_spacer(ui_em(1.f, 1.f)); + RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) + { + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_flags(UI_BoxFlag_DrawBorder); + UI_Row UI_Padding(ui_em(0.5f, 1.f)) + { + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); + ui_box_equip_display_string(box, item->kind_name); + } + } + } } - // rjf: kind name - if(item->kind_name.size != 0) + // rjf: description + if(flags & RD_ListerFlag_Descriptions) { - ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) + if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_flags(UI_BoxFlag_DrawBorder); - UI_Row UI_Padding(ui_em(0.5f, 1.f)) - { - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); - ui_box_equip_display_string(box, item->kind_name); - } + UI_Box *box = ui_label(item->description).box; + ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); } } } - // rjf: description - if(flags & RD_ListerFlag_Descriptions) + // rjf: bindings + if(item->flags & RD_ListerItemFlag_Bindings) RD_Palette(RD_PaletteCode_Floating) UI_Focus(UI_FocusKind_Off) { - if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_px(row_height_px/4.f, 0.f)) { - UI_Box *box = ui_label(item->description).box; - ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); + ui_set_next_flags(UI_BoxFlag_Clickable); + UI_NamedRow(str8_lit("binding_row")) + { + rd_cmd_binding_buttons(item->string); + } } } } - // rjf: bindings - if(item->can_have_bindings) RD_Palette(RD_PaletteCode_Base) + //- rjf: do interaction with top-level item + UI_Signal item_sig = ui_signal_from_box(item_box); + if(ui_clicked(item_sig)) { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) - { - rd_cmd_binding_buttons(item->string); - } - } +#if 0 // TODO(rjf): @cfg_lister + UI_Event move_back_evt = zero_struct; + move_back_evt.kind = UI_EventKind_Navigate; + move_back_evt.flags = UI_EventFlag_KeepMark; + move_back_evt.delta_2s32.x = -(S32)query_word.size; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); + UI_Event paste_evt = zero_struct; + paste_evt.kind = UI_EventKind_Text; + paste_evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); + lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); +#endif + } + else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) + { + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = item->string; + ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); } } - - //- rjf: do interaction with top-level item - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { -#if 0 // TODO(rjf): @cfg_lister - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); -#endif - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } } } + ////////////////////////// + //- rjf: cursor -> selected item hash + // + if(1 <= cursor.y && cursor.y <= item_array.count) + { + RD_ListerItem *item = &item_array.v[cursor.y-1]; + U64 hash = rd_hash_from_lister_item(item); + lister->selected_item_hash = hash; + } + else + { + lister->selected_item_hash = 0; + } + di_scope_close(di_scope); } @@ -7358,7 +7375,7 @@ rd_window_frame(void) //- rjf: build tab view UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") { - String8 view_expr = rd_view_expr_string(); + String8 view_expr = rd_expr_from_cfg(selected_tab); String8 params_string = rd_string_from_cfg_tree(scratch.arena, selected_tab); MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(selected_tab->string); @@ -7425,6 +7442,16 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(panel->cfg)); } + if(ui_right_clicked(panel_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .view = rd_handle_from_cfg(panel->selected_tab), + .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), + .ui_key = panel_box->key, + .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), + .reg_slot = RD_RegSlot_View, + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + } ////////////////////////// //- rjf: build tab bar @@ -7600,12 +7627,11 @@ rd_window_frame(void) } else if(ui_right_clicked(sig)) { - // rd_open_ctx_menu(sig.box->key, v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), RD_RegSlot_View); rd_cmd(RD_CmdKind_PushQuery, + .reg_slot = RD_RegSlot_View, .ui_key = sig.box->key, .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands, - .reg_slot = RD_RegSlot_View); + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); } else if(ui_middle_clicked(sig)) { @@ -9698,19 +9724,59 @@ rd_lister_item_array_sort__in_place(RD_ListerItemArray *array) } internal RD_ListerItemArray -rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) +rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off) { Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = di_scope_open(); RD_ListerFlags flags = regs->lister_flags; - String8 needle = regs->string; - U64 cursor_off = regs->cursor.column-1; - cursor_off = Clamp(0, cursor_off, needle.size); String8 needle_path = rd_lister_query_path_from_input_string_off(needle, cursor_off); RD_ListerItemChunkList item_list = {0}; 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); + ////////////////////////// + //- rjf: determine all ctx filters + // + String8List ctx_filter_strings = {0}; + { + switch(regs->reg_slot) + { + default:{}break; + case RD_RegSlot_Cursor: + { + if(!txt_pt_match(regs->cursor, regs->mark)) + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_rng,"); + } + else + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_pt,"); + } + }break; + case RD_RegSlot_Cfg: + { + RD_Cfg *cfg = rd_cfg_from_handle(regs->cfg); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", cfg->string); + }break; + case RD_RegSlot_View: + { + RD_Cfg *view = rd_cfg_from_handle(regs->view); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$tab,"); + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", view->string); + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); + if(view_file_path.size != 0) + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$file,"); + } + } // fallthrough; + case RD_RegSlot_Panel: + { + str8_list_pushf(scratch.arena, &ctx_filter_strings, "$panel,"); + }break; + } + } + ////////////////////////// //- rjf: grab rdis // @@ -10104,25 +10170,28 @@ rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) } // rjf: get current files, filtered - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + if(dir_str_in_input.size != 0) { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(arena, search, info.name); - B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) + B32 allow_dirs = 1; + OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = info.name, - .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), - .display_name = info.name, - .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, - .display_name__matches = match_ranges, - .is_non_code = 1); + FuzzyMatchRangeList match_ranges = fuzzy_match_find(arena, search, info.name); + B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); + B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); + if(fits_search && fits_dir_only) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .string = info.name, + .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), + .display_name = info.name, + .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, + .display_name__matches = match_ranges, + .flags = RD_ListerItemFlag_IsNonCode); + } } + os_file_iter_end(it); } - os_file_iter_end(it); } //- rjf: gather commands @@ -10131,7 +10200,17 @@ rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) for EachNonZeroEnumVal(RD_CmdKind, k) { RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - if(info->query.slot == regs->reg_slot || regs->reg_slot == RD_RegSlot_Null) + B32 included_by_filter_string = 0; + for(String8Node *n = ctx_filter_strings.first; n != 0; n = n->next) + { + B32 n_match = (str8_find_needle(info->ctx_filter, 0, n->string, 0) < info->ctx_filter.size); + if(n_match) + { + included_by_filter_string = 1; + break; + } + } + if(ctx_filter_strings.node_count == 0 || included_by_filter_string) { String8 cmd_display_name = info->display_name; String8 cmd_desc = info->description; @@ -10152,13 +10231,77 @@ rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) .display_name__matches = name_matches, .description = cmd_desc, .description__matches = desc_matches, - .is_non_code = 1, - .can_have_bindings = 1); + .flags = RD_ListerItemFlag_IsNonCode|RD_ListerItemFlag_Bindings); } } } } + //- rjf: gather settings + if(flags & RD_ListerFlag_Settings) + { + String8List schema_strings = {0}; + + // rjf: push schema for view + { + RD_Cfg *view = rd_cfg_from_handle(regs->view); + String8 view_name = view->string; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view_name); + str8_list_push(scratch.arena, &schema_strings, view_rule_info->params_schema); + } + + // rjf: for each schema, gather parameters + for(String8Node *n = schema_strings.first; n != 0; n = n->next) + { + MD_Node *schema = md_tree_from_string(scratch.arena, n->string)->first; + for MD_EachNode(param, schema->first) + { + RD_VocabularyInfo *param_vocab_info = rd_vocabulary_info_from_code_name(param->string); + String8 name = param_vocab_info->display_name; + RD_IconKind icon_kind = param_vocab_info->icon_kind; + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); + if(name_matches.count == name_matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = icon_kind, + .string = param->string, + .kind_name = str8_lit("Setting"), + .display_name = name, + .display_name__matches = name_matches, + .flags = RD_ListerItemFlag_IsNonCode); + } + } + } + } + + //- rjf: gather system processes + if(flags & RD_ListerFlag_SystemProcesses) + { + U32 this_process_pid = os_get_process_info()->pid; + DMN_ProcessIter iter = {0}; + dmn_process_iter_begin(&iter); + for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) + { + if(info.pid == this_process_pid) + { + continue; + } + String8 name = push_str8f(scratch.arena, "%S (PID: %i)", info.name, info.pid); + FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); + if(name_matches.count == name_matches.needle_part_count) + { + rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, + .icon_kind = RD_IconKind_Threads, + .string = name, + .kind_name = str8_lit("System Process"), + .display_name = name, + .display_name__matches = name_matches, + .flags = RD_ListerItemFlag_IsNonCode); + } + } + dmn_process_iter_end(&iter); + } + //- rjf: lister item list -> sorted array RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(arena, &item_list); rd_lister_item_array_sort__in_place(&item_array); @@ -10168,6 +10311,16 @@ rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs) return item_array; } +internal U64 +rd_hash_from_lister_item(RD_ListerItem *item) +{ + U64 item_hash = 5381; + item_hash = d_hash_from_seed_string(item_hash, item->string); + item_hash = d_hash_from_seed_string(item_hash, item->kind_name); + item_hash = d_hash_from_seed_string(item_hash, str8_struct(&item->group)); + return item_hash; +} + internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) { @@ -10574,7 +10727,7 @@ internal F32 rd_font_size_from_slot(RD_FontSlot slot) { B32 explicit_config_found = 0; - F32 result = 11.f; + F32 result = 9.f; // rjf: determine config key based on slot String8 key = {0}; @@ -11362,6 +11515,24 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) return fstrs; } +//////////////////////////////// +//~ rjf: Vocabulary Info Lookups + +internal RD_VocabularyInfo * +rd_vocabulary_info_from_code_name(String8 code_name) +{ + RD_VocabularyInfo *info = &rd_nil_vocabulary_info; + for EachElement(idx, rd_vocabulary_info_table) + { + if(str8_match(rd_vocabulary_info_table[idx].code_name, code_name, 0)) + { + info = &rd_vocabulary_info_table[idx]; + break; + } + } + return info; +} + //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -11431,23 +11602,6 @@ rd_push_active_target_list(Arena *arena) return active_targets; } -internal RD_Entity * -rd_entity_from_ev_key_and_kind(EV_Key key, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - RD_EntityList list = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = list.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(ev_key_match(rd_ev_key_from_entity(entity), key)) - { - result = entity; - break; - } - } - return result; -} - //- rjf: config state internal RD_CfgTable * @@ -11979,6 +12133,40 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: sync with di parsers + // + ProfScope("sync with di parsers") + { + DI_EventList events = di_p2u_pop_events(scratch.arena, 0); + for(DI_EventNode *n = events.first; n != 0; n = n->next) + { + DI_Event *event = &n->v; + switch(event->kind) + { + default:{}break; + case DI_EventKind_ConversionStarted: + { + RD_Cfg *root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *task = rd_cfg_new(root, str8_lit("conversion_task")); + rd_cfg_new(task, event->string); + }break; + case DI_EventKind_ConversionEnded: + { + RD_Cfg *root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + for(RD_Cfg *tln = root->first; tln != &rd_nil_cfg; tln = tln->next) + { + if(str8_match(tln->string, str8_lit("conversion_task"), 0) && str8_match(tln->first->string, event->string, 0)) + { + rd_cfg_release(tln); + break; + } + } + }break; + } + } + } + ////////////////////////////// //- rjf: animate all views // @@ -12769,7 +12957,15 @@ rd_frame(void) //- rjf: top-level lister case RD_CmdKind_OpenLister: { - rd_cmd(RD_CmdKind_PushQuery, .lister_flags = 0xffffffff); + RD_ListerFlags lister_flags = (RD_ListerFlag_LineEdit| + RD_ListerFlag_Descriptions| + RD_ListerFlag_KindLabel| + RD_ListerFlag_Procedures| + RD_ListerFlag_Files| + RD_ListerFlag_Commands| + RD_ListerFlag_Settings| + RD_ListerFlag_SystemProcesses); + rd_cmd(RD_CmdKind_PushQuery, .lister_flags = lister_flags); }break; //- rjf: command fast path @@ -12891,10 +13087,10 @@ rd_frame(void) //- rjf: config path saving/loading/applying case RD_CmdKind_OpenRecentProject: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - if(entity->kind == RD_EntityKind_RecentProject) + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + if(str8_match(cfg->string, str8_lit("recent_project"), 0)) { - rd_cmd(RD_CmdKind_OpenProject, .file_path = entity->string); + rd_cmd(RD_CmdKind_OpenProject, .file_path = cfg->first->string); } }break; case RD_CmdKind_OpenUser: @@ -13870,66 +14066,58 @@ rd_frame(void) case RD_CmdKind_IncUIFontScale: { fnt_reset(); - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); - RD_Cfg *main_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("main_font_size")); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(main_font_size_cfg == &rd_nil_cfg) + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + for(RD_Cfg *child = main_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { - main_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("main_font_size")); - rd_cfg_newf(main_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); + next = child->next; + rd_cfg_release(child); } - F32 size = (F32)f64_from_str8(main_font_size_cfg->first->string); - size += 1; - size = Clamp(6, size, 72); - rd_cfg_equip_stringf(main_font_size_cfg->first, "%f", size); + rd_cfg_newf(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecUIFontScale: { fnt_reset(); - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); - RD_Cfg *main_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("main_font_size")); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(main_font_size_cfg == &rd_nil_cfg) + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + for(RD_Cfg *child = main_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { - main_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("main_font_size")); - rd_cfg_newf(main_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); + next = child->next; + rd_cfg_release(child); } - F32 size = (F32)f64_from_str8(main_font_size_cfg->first->string); - size -= 1; - size = Clamp(6, size, 72); - rd_cfg_equip_stringf(main_font_size_cfg->first, "%f", size); + rd_cfg_newf(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_IncCodeFontScale: { fnt_reset(); - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); - RD_Cfg *code_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("code_font_size")); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(code_font_size_cfg == &rd_nil_cfg) + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); + for(RD_Cfg *child = code_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { - code_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("code_font_size")); - rd_cfg_newf(code_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); + next = child->next; + rd_cfg_release(child); } - F32 size = (F32)f64_from_str8(code_font_size_cfg->first->string); - size += 1; - size = Clamp(6, size, 72); - rd_cfg_equip_stringf(code_font_size_cfg->first, "%f", size); + rd_cfg_newf(code_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecCodeFontScale: { fnt_reset(); - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); - RD_Cfg *code_font_size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("code_font_size")); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(code_font_size_cfg == &rd_nil_cfg) + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); + for(RD_Cfg *child = code_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { - code_font_size_cfg = rd_cfg_new(window_cfg, str8_lit("code_font_size")); - rd_cfg_newf(code_font_size_cfg, "%f", (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32); + next = child->next; + rd_cfg_release(child); } - F32 size = (F32)f64_from_str8(code_font_size_cfg->first->string); - size -= 1; - size = Clamp(6, size, 72); - rd_cfg_equip_stringf(code_font_size_cfg->first, "%f", size); + rd_cfg_newf(code_font_size, "%f", new_font_size); }break; //- rjf: panel creation @@ -14673,6 +14861,12 @@ rd_frame(void) rd_entity_change_parent(existing_recent_file, rd_entity_root(), rd_entity_root(), rd_entity_root()->last); } }break; + case RD_CmdKind_ShowFileInExplorer: + if(rd_regs()->file_path.size != 0) + { + String8 full_path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); + os_show_in_filesystem_ui(full_path); + }break; //- rjf: source <-> disasm case RD_CmdKind_GoToDisassembly: @@ -15766,7 +15960,7 @@ X(getting_started) if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) { dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("text")); - RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("query")); + RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("expression")); rd_cfg_new(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); } @@ -16307,17 +16501,6 @@ X(getting_started) txt_scope_close(txt_scope); hs_scope_close(hs_scope); }break; - case RD_CmdKind_RunToCursor: - { - if(rd_regs()->file_path.size != 0) - { - rd_cmd(RD_CmdKind_RunToLine); - } - else - { - rd_cmd(RD_CmdKind_RunToAddress); - } - }break; case RD_CmdKind_SetNextStatement: { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index fbaac83c..a2421f7d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -240,24 +240,26 @@ enum //- rjf: lister visual settings RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) + RD_ListerFlag_KindLabel = (1<<2), // determines whether or not the lister items have labels for each item's kind + RD_ListerFlag_SizeByAnchor = (1<<3), // determines whether or not the lister is sized by the anchor box //- rjf: lister item sources - RD_ListerFlag_Locals = (1<<2), - RD_ListerFlag_Registers = (1<<3), - RD_ListerFlag_ViewRules = (1<<4), - RD_ListerFlag_ViewRuleParams = (1<<5), - RD_ListerFlag_Members = (1<<6), - RD_ListerFlag_Globals = (1<<7), - RD_ListerFlag_ThreadLocals = (1<<8), - RD_ListerFlag_Procedures = (1<<9), - RD_ListerFlag_Types = (1<<10), - RD_ListerFlag_Languages = (1<<11), - RD_ListerFlag_Architectures = (1<<12), - RD_ListerFlag_Tex2DFormats = (1<<13), - RD_ListerFlag_Files = (1<<14), - RD_ListerFlag_Commands = (1<<15), - RD_ListerFlag_Settings = (1<<16), - RD_ListerFlag_SystemProcesses= (1<<17), + RD_ListerFlag_Locals = (1<<4), + RD_ListerFlag_Registers = (1<<5), + RD_ListerFlag_ViewRules = (1<<6), + RD_ListerFlag_ViewRuleParams = (1<<7), + RD_ListerFlag_Members = (1<<8), + RD_ListerFlag_Globals = (1<<9), + RD_ListerFlag_ThreadLocals = (1<<10), + RD_ListerFlag_Procedures = (1<<11), + RD_ListerFlag_Types = (1<<12), + RD_ListerFlag_Languages = (1<<13), + RD_ListerFlag_Architectures = (1<<14), + RD_ListerFlag_Tex2DFormats = (1<<15), + RD_ListerFlag_Files = (1<<16), + RD_ListerFlag_Commands = (1<<17), + RD_ListerFlag_Settings = (1<<18), + RD_ListerFlag_SystemProcesses= (1<<19), }; //////////////////////////////// @@ -580,21 +582,28 @@ RD_PaletteCode; //////////////////////////////// //~ rjf: Lister Types +typedef U32 RD_ListerItemFlags; +enum +{ + RD_ListerItemFlag_IsNonCode = (1<<0), + RD_ListerItemFlag_Bindings = (1<<1), + RD_ListerItemFlag_Autocompletion = (1<<2), +}; + typedef struct RD_ListerItem RD_ListerItem; struct RD_ListerItem { + RD_ListerItemFlags flags; + RD_IconKind icon_kind; String8 string; String8 kind_name; String8 display_name; String8 description; String8 search_tags; - RD_IconKind icon_kind; FuzzyMatchRangeList kind_name__matches; FuzzyMatchRangeList display_name__matches; FuzzyMatchRangeList description__matches; U64 group; - B32 is_non_code; - B32 can_have_bindings; }; typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode; @@ -629,6 +638,7 @@ struct RD_Lister Arena *arena; RD_Regs *regs; UI_ScrollPt scroll_pt; + U64 selected_item_hash; U8 input_buffer[1024]; U64 input_string_size; TxtPt input_cursor; @@ -970,6 +980,8 @@ struct RD_State //////////////////////////////// //~ rjf: Globals +read_only global RD_VocabularyInfo rd_nil_vocabulary_info = {0}; + read_only global RD_CfgTree d_nil_cfg_tree = {&d_nil_cfg_tree, RD_CfgSrc_User, &md_nil_node}; read_only global RD_CfgVal d_nil_cfg_val = {&d_nil_cfg_val, &d_nil_cfg_val, &d_nil_cfg_tree, &d_nil_cfg_tree}; @@ -1334,7 +1346,8 @@ internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkLis internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); -internal RD_ListerItemArray rd_lister_item_array_from_regs(Arena *arena, RD_Regs *regs); +internal RD_ListerItemArray rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off); +internal U64 rd_hash_from_lister_item(RD_ListerItem *item); internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); @@ -1381,6 +1394,15 @@ internal String8List rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD internal String8 rd_string_from_exception_code(U32 code); internal DR_FancyStringList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event); +//////////////////////////////// +//~ rjf: Vocabulary Info Lookups + +internal RD_VocabularyInfo *rd_vocabulary_info_from_code_name(String8 code_name); +#define rd_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->code_name_plural) +#define rd_display_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name) +#define rd_display_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name_plural) +#define rd_icon_kind_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->icon_kind) + //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -1398,7 +1420,6 @@ internal String8 rd_cfg_path_from_src(RD_CfgSrc src); //- rjf: entity cache queries internal RD_EntityList rd_query_cached_entity_list_with_kind(RD_EntityKind kind); internal RD_EntityList rd_push_active_target_list(Arena *arena); -internal RD_Entity *rd_entity_from_ev_key_and_kind(EV_Key key, RD_EntityKind kind); //- rjf: config state internal RD_CfgTable *rd_cfg_table(void); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 29e4915f..35bf5d39 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -601,106 +601,58 @@ entry_point(CmdLine *cmd_line) String8List args = cmd_line->inputs; if(args.node_count > 0 && args.first->string.size != 0) { - //- TODO(rjf): @cfg setup initial target from command line arguments - { - Temp scratch = scratch_begin(0, 0); - - //- rjf: unpack command line inputs - String8 executable_name_string = {0}; - String8 arguments_string = {0}; - String8 working_directory_string = {0}; - { - // rjf: unpack full executable path - if(args.first->string.size != 0) - { - String8 current_path = os_get_current_path(scratch.arena); - String8 exe_name = args.first->string; - PathStyle style = path_style_from_str8(exe_name); - if(style == PathStyle_Relative) - { - exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); - exe_name = path_normalized_from_string(scratch.arena, exe_name); - } - executable_name_string = exe_name; - } - - // rjf: unpack working directory - if(args.first->string.size != 0) - { - String8 path_part_of_arg = str8_chop_last_slash(args.first->string); - if(path_part_of_arg.size != 0) - { - String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); - working_directory_string = path; - } - } - - // rjf: unpack arguments - String8List passthrough_args_list = {0}; - for(String8Node *n = args.first->next; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &passthrough_args_list, n->string); - } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - arguments_string = str8_list_join(scratch.arena, &passthrough_args_list, &join); - } - - //- rjf: build config tree - RD_Cfg *command_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); - RD_Cfg *target = rd_cfg_new(command_line_root, str8_lit("target")); - RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); - RD_Cfg *args = rd_cfg_new(target, str8_lit("arguments")); - RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); - rd_cfg_new(exe, executable_name_string); - rd_cfg_new(args, arguments_string); - rd_cfg_new(wdir, working_directory_string); - - scratch_end(scratch); - } - Temp scratch = scratch_begin(0, 0); - RD_Entity *target = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Target); - rd_entity_equip_cfg_src(target, RD_CfgSrc_CommandLine); - String8List passthrough_args_list = {0}; - for(String8Node *n = args.first->next; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &passthrough_args_list, n->string); - } - // rjf: get current path - String8 current_path = os_get_current_path(scratch.arena); - - // rjf: equip exe - if(args.first->string.size != 0) + //- rjf: unpack command line inputs + String8 executable_name_string = {0}; + String8 arguments_string = {0}; + String8 working_directory_string = {0}; { - String8 exe_name = args.first->string; - RD_Entity *exe = rd_entity_alloc(target, RD_EntityKind_Executable); - PathStyle style = path_style_from_str8(exe_name); - if(style == PathStyle_Relative) + // rjf: unpack full executable path + if(args.first->string.size != 0) { - exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); - exe_name = path_normalized_from_string(scratch.arena, exe_name); + String8 current_path = os_get_current_path(scratch.arena); + String8 exe_name = args.first->string; + PathStyle style = path_style_from_str8(exe_name); + if(style == PathStyle_Relative) + { + exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); + exe_name = path_normalized_from_string(scratch.arena, exe_name); + } + executable_name_string = exe_name; } - rd_entity_equip_name(exe, exe_name); + + // rjf: unpack working directory + if(args.first->string.size != 0) + { + String8 path_part_of_arg = str8_chop_last_slash(args.first->string); + if(path_part_of_arg.size != 0) + { + String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); + working_directory_string = path; + } + } + + // rjf: unpack arguments + String8List passthrough_args_list = {0}; + for(String8Node *n = args.first->next; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &passthrough_args_list, n->string); + } + StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; + arguments_string = str8_list_join(scratch.arena, &passthrough_args_list, &join); } - // rjf: equip working directory - String8 path_part_of_arg = str8_chop_last_slash(args.first->string); - if(path_part_of_arg.size != 0) - { - String8 path = push_str8f(scratch.arena, "%S/", path_part_of_arg); - RD_Entity *wdir = rd_entity_alloc(target, RD_EntityKind_WorkingDirectory); - rd_entity_equip_name(wdir, path); - } + //- rjf: build config tree + RD_Cfg *command_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + RD_Cfg *target = rd_cfg_new(command_line_root, str8_lit("target")); + RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); + RD_Cfg *args = rd_cfg_new(target, str8_lit("arguments")); + RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); + rd_cfg_new(exe, executable_name_string); + rd_cfg_new(args, arguments_string); + rd_cfg_new(wdir, working_directory_string); - // rjf: equip args - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - String8 args_str = str8_list_join(scratch.arena, &passthrough_args_list, &join); - if(args_str.size != 0) - { - RD_Entity *args_entity = rd_entity_alloc(target, RD_EntityKind_Arguments); - rd_entity_equip_name(args_entity, args_str); - } scratch_end(scratch); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 22ecf4f0..1430e47d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -6308,12 +6308,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(output) // rd_regs()->file_path = str8_zero(); rd_regs()->vaddr = 0; -#if 0 // TODO(rjf): @cfg rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; -#endif ////////////////////////////// //- rjf: unpack text info diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 80027037..2d11258e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1010,7 +1010,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - RD_RegsScope(.entity = rd_handle_from_cfg(bp)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(bp)) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: shift+click => enable breakpoint @@ -1035,10 +1035,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(ui_right_clicked(bp_sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(bp), - .reg_slot= RD_RegSlot_Cfg, - .ui_key = bp_box->key, - .off_px = v2f32(0, bp_box->rect.y1-bp_box->rect.y0)); + .cfg = rd_handle_from_cfg(bp), + .reg_slot = RD_RegSlot_Cfg, + .ui_key = bp_box->key, + .off_px = v2f32(0, bp_box->rect.y1-bp_box->rect.y0), + .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); } } @@ -1070,7 +1071,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_set_hover_regs(RD_RegSlot_Entity); + RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: click => remove pin @@ -1089,10 +1090,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(ui_right_clicked(pin_sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(pin), - .reg_slot= RD_RegSlot_Cfg, - .ui_key = pin_box->key, - .off_px = v2f32(0, pin_box->rect.y1-pin_box->rect.y0)); + .cfg = rd_handle_from_cfg(pin), + .reg_slot = RD_RegSlot_Cfg, + .ui_key = pin_box->key, + .off_px = v2f32(0, pin_box->rect.y1-pin_box->rect.y0), + .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); } } } @@ -1311,10 +1313,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(ui_right_clicked(sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(pin), - .reg_slot= RD_RegSlot_Cfg, - .ui_key = sig.box->key, - .off_px = v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + .cfg = rd_handle_from_cfg(pin), + .reg_slot = RD_RegSlot_Cfg, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1-sig.box->rect.y0), + .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); } } rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); @@ -1460,13 +1463,15 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min]; lines = params->line_infos[cursor->line - params->line_num_range.min]; } - RD_RegsScope(.cursor = *cursor, - .mark = *mark, - .vaddr = vaddr, - .lines = lines) - { - rd_open_ctx_menu(ui_key_zero(), sub_2f32(ui_mouse(), v2f32(2, 2)), RD_RegSlot_Cursor); - } + rd_cmd(RD_CmdKind_PushQuery, + .reg_slot = RD_RegSlot_Cursor, + .ui_key = ui_get_selected_state()->root->key, + .off_px = sub_2f32(ui_mouse(), v2f32(2, 2)), + .cursor = *cursor, + .mark = *mark, + .vaddr = vaddr, + .lines = lines, + .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); } //- rjf: dragging threads, breakpoints, or watch pins over this slice -> From 16a717d6843f80110b91ed745cef16c9af10e6bb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 22 Jan 2025 09:22:06 -0800 Subject: [PATCH 017/755] further elimination of entity-based code; more simplification/moving to cfg; begin sketching out expanded eval-viz block tree, such that each block can have its own table topology (will be useful to collapse/simplify/expand the capabilities of watch views) --- .../eval_visualization_core.c | 28 +- .../eval_visualization_core.h | 33 +- src/os/gfx/win32/os_gfx_win32.c | 5 +- src/raddbg/generated/raddbg.meta.c | 14 +- src/raddbg/generated/raddbg.meta.h | 30 +- src/raddbg/raddbg.mdesk | 32 +- src/raddbg/raddbg_core.c | 766 ++----- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 1816 +---------------- src/raddbg/raddbg_widgets.c | 33 +- 10 files changed, 327 insertions(+), 2432 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index dfaf7e46..a36cd7c4 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -667,11 +667,31 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) return expr; } +//////////////////////////////// +//~ rjf: Column List Building + +internal EV_Col * +ev_col_list_push(Arena *arena, EV_ColList *list) +{ + EV_Col *col = push_array(arena, EV_Col, 1); + SLLQueuePush(list->first, list->last, col); + list->count += 1; + return col; +} + +internal EV_Col * +ev_col_list_push_new(Arena *arena, EV_ColList *list, String8 key) +{ + EV_Col *col = ev_col_list_push(arena, list); + col->key = push_str8_copy(arena, key); + return col; +} + //////////////////////////////// //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules) +ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, EV_ColList *cols) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -691,6 +711,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = ev_key_root(); + tree.root->cols = *cols; tree.root->string = string; tree.root->expr = ev_resolved_from_expr(arena, expr, top_level_view_rules); tree.root->view_rules = top_level_view_rules; @@ -758,6 +779,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str expansion_block->parent = t->parent_block; expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; + expansion_block->cols = *cols; expansion_block->expr = t->expr; expansion_block->view_rules = t->view_rules; expansion_block->expand_view_rule_info = expand_view_rule_info; @@ -885,7 +907,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules) +ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules, EV_ColList *cols) { ProfBeginFunction(); EV_BlockTree tree = {0}; @@ -896,7 +918,7 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, string); EV_ViewRuleList *all_view_rules = ev_view_rule_list_copy(arena, view_rules); ev_view_rule_list_concat_in_place(all_view_rules, &fastpath_view_rules); - tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules); + tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules, cols); } scratch_end(scratch); ProfEnd(); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 41b9d403..164ca077 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -187,6 +187,24 @@ struct EV_ViewRuleInfoTable U64 slots_count; }; +//////////////////////////////// +//~ rjf: Columns + +typedef struct EV_Col EV_Col; +struct EV_Col +{ + EV_Col *next; + String8 key; +}; + +typedef struct EV_ColList EV_ColList; +struct EV_ColList +{ + EV_Col *first; + EV_Col *last; + U64 count; +}; + //////////////////////////////// //~ rjf: Blocks @@ -206,6 +224,9 @@ struct EV_Block // rjf: split index, relative to parent's space U64 split_relative_idx; + // rjf: columns + EV_ColList cols; + // rjf: expression / visualization info String8 string; E_Expr *expr; @@ -351,7 +372,7 @@ global read_only EV_ViewRuleInfo ev_nil_view_rule_info = thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; global read_only EV_ViewRuleList ev_nil_view_rule_list = {0}; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; //////////////////////////////// //~ rjf: Key Functions @@ -415,11 +436,17 @@ internal void ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRul internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules); +//////////////////////////////// +//~ rjf: Column List Building + +internal EV_Col *ev_col_list_push(Arena *arena, EV_ColList *list); +internal EV_Col *ev_col_list_push_new(Arena *arena, EV_ColList *list, String8 key); + //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules); -internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules); +internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, EV_ColList *cols); +internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules, EV_ColList *cols); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 99d73deb..fdcac746 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -715,9 +715,10 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // of the top hit area so manually checking that. F32 dpi = w32_GetDpiForWindow_func ? (F32)w32_GetDpiForWindow_func(hwnd) : 96.f; S32 frame_y = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME); - S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER); + // NOTE(rjf): it seems incorrect to apply this padding here... + // S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER); - B32 is_over_top_resize = pos_client.y >= 0 && pos_client.y < frame_y + padding; + B32 is_over_top_resize = pos_client.y >= 0 && pos_client.y < frame_y; // + padding; B32 is_over_title_bar = pos_client.y >= 0 && pos_client.y < window->custom_border_title_thickness; //- rjf: check against title bar client areas diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c232a9a1..75dea353 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -54,12 +54,12 @@ RD_VocabularyInfo rd_vocabulary_info_table[39] = {str8_lit_comp("stdout_path"), str8_lit_comp("stdout_paths"), str8_lit_comp("Standard Output Path"), str8_lit_comp("Standard Output Paths"), RD_IconKind_Null}, {str8_lit_comp("stderr_path"), str8_lit_comp("stderr_paths"), str8_lit_comp("Standard Error Path"), str8_lit_comp("Standard Error Paths"), RD_IconKind_Null}, {str8_lit_comp("stdin_path"), str8_lit_comp("stdin_paths"), str8_lit_comp("Standard Input Path"), str8_lit_comp("Standard Input Paths"), RD_IconKind_Null}, -{str8_lit_comp("window"), str8_lit_comp("windows"), str8_lit_comp("Window"), str8_lit_comp("Windows"), RD_IconKind_Null}, +{str8_lit_comp("window"), str8_lit_comp("windows"), str8_lit_comp("Window"), str8_lit_comp("Windows"), RD_IconKind_Window}, {str8_lit_comp("panel"), str8_lit_comp("panels"), str8_lit_comp("Panel"), str8_lit_comp("Panels"), RD_IconKind_Null}, {str8_lit_comp("view"), str8_lit_comp("views"), str8_lit_comp("View"), str8_lit_comp("Views"), RD_IconKind_Null}, {str8_lit_comp("tab"), str8_lit_comp("tabs"), str8_lit_comp("Tab"), str8_lit_comp("Tabs"), RD_IconKind_Null}, -{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Null}, -{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_Null}, +{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, {str8_lit_comp("src"), str8_lit_comp("srcs"), str8_lit_comp("Source"), str8_lit_comp("Sources"), RD_IconKind_Null}, {str8_lit_comp("dst"), str8_lit_comp("dsts"), str8_lit_comp("Destination"), str8_lit_comp("Destinations"), RD_IconKind_Null}, {str8_lit_comp("conversion_task"), str8_lit_comp("conversion_tasks"), str8_lit_comp("Conversion Task"), str8_lit_comp("Conversion Tasks"), RD_IconKind_Null}, @@ -863,7 +863,7 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(procedures), }; -RD_ViewRuleInfo rd_view_rule_kind_info_table[35] = +RD_ViewRuleInfo rd_view_rule_kind_info_table[29] = { {{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, {str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, @@ -871,12 +871,6 @@ RD_ViewRuleInfo rd_view_rule_kind_info_table[35] = {str8_lit_comp("exception_filters"), str8_lit_comp("An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time."), str8_lit_comp("Exception Filters"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(exception_filters)}, {str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, {str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, -{str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(commands)}, -{str8_lit_comp("file_system"), str8_lit_comp(""), str8_lit_comp("File System"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(file_system)}, -{str8_lit_comp("system_processes"), str8_lit_comp(""), str8_lit_comp("System Processes"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(system_processes)}, -{str8_lit_comp("entity_lister"), str8_lit_comp(""), str8_lit_comp("Entities"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(entity_lister)}, -{str8_lit_comp("ctrl_entity_lister"), str8_lit_comp(""), str8_lit_comp("Control Entities"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(ctrl_entity_lister)}, -{str8_lit_comp("symbol_lister"), str8_lit_comp(""), str8_lit_comp("Symbols"), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(symbol_lister)}, {str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, {str8_lit_comp("locals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(locals)}, {str8_lit_comp("registers"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(registers)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index a2b0eb95..b1e7a936 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -252,14 +252,14 @@ RD_CmdKind_ToggleWatchExpressionAtMouse, RD_CmdKind_SetColumns, RD_CmdKind_ToggleAddressVisibility, RD_CmdKind_ToggleCodeBytesVisibility, -RD_CmdKind_EnableEntity, -RD_CmdKind_DisableEntity, -RD_CmdKind_SelectEntity, -RD_CmdKind_RemoveEntity, -RD_CmdKind_NameEntity, -RD_CmdKind_ConditionEntity, -RD_CmdKind_DuplicateEntity, -RD_CmdKind_RelocateEntity, +RD_CmdKind_EnableCfg, +RD_CmdKind_DisableCfg, +RD_CmdKind_SelectCfg, +RD_CmdKind_RemoveCfg, +RD_CmdKind_NameCfg, +RD_CmdKind_ConditionCfg, +RD_CmdKind_DuplicateCfg, +RD_CmdKind_RelocateCfg, RD_CmdKind_AddBreakpoint, RD_CmdKind_AddAddressBreakpoint, RD_CmdKind_AddFunctionBreakpoint, @@ -395,12 +395,6 @@ RD_ViewRuleKind_GettingStarted, RD_ViewRuleKind_ExceptionFilters, RD_ViewRuleKind_Settings, RD_ViewRuleKind_PendingFile, -RD_ViewRuleKind_Commands, -RD_ViewRuleKind_FileSystem, -RD_ViewRuleKind_SystemProcesses, -RD_ViewRuleKind_EntityLister, -RD_ViewRuleKind_CtrlEntityLister, -RD_ViewRuleKind_SymbolLister, RD_ViewRuleKind_Watch, RD_ViewRuleKind_Locals, RD_ViewRuleKind_Registers, @@ -757,12 +751,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); RD_VIEW_RULE_UI_FUNCTION_DEF(exception_filters); RD_VIEW_RULE_UI_FUNCTION_DEF(settings); RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file); -RD_VIEW_RULE_UI_FUNCTION_DEF(commands); -RD_VIEW_RULE_UI_FUNCTION_DEF(file_system); -RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes); -RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister); -RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister); -RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister); RD_VIEW_RULE_UI_FUNCTION_DEF(watch); RD_VIEW_RULE_UI_FUNCTION_DEF(locals); RD_VIEW_RULE_UI_FUNCTION_DEF(registers); @@ -809,7 +797,7 @@ extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_inf extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18]; extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18]; extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18]; -extern RD_ViewRuleInfo rd_view_rule_kind_info_table[35]; +extern RD_ViewRuleInfo rd_view_rule_kind_info_table[29]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 0c40c45d..a41ca1a1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -72,12 +72,12 @@ RD_VocabularyMap: {stdout_path _ "Standard Output Path" _ Null } {stderr_path _ "Standard Error Path" _ Null } {stdin_path _ "Standard Input Path" _ Null } - {window _ "Window" _ Null } + {window _ "Window" _ Window } {panel _ "Panel" _ Null } {view _ "View" _ Null } {tab _ "Tab" _ Null } - {recent_project _ "Recent Project" _ Null } - {recent_file _ "Recent File" _ Null } + {recent_project _ "Recent Project" _ Briefcase } + {recent_file _ "Recent File" _ FileOutline } {src _ "Source" _ Null } {dst _ "Destination" _ Null } {conversion_task _ "Conversion Task" _ Null } @@ -478,15 +478,15 @@ RD_CmdTable: // | | | | {ToggleAddressVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } - //- rjf: general entity operations - {EnableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" "" } - {DisableEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" "" } - {SelectEntity 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" "" } - {RemoveEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" "" } - {NameEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" "" } - {ConditionEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" "" } - {DuplicateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" "" } - {RelocateEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" "" } + //- rjf: general config operations + {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" "" } + {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" "" } + {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" "" } + {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" "" } + {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" "" } + {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" "" } + {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" "" } + {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } @@ -980,14 +980,6 @@ RD_ViewRuleTable: //- rjf: temporary view for loading files - must analyze file before picking viewer { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } - //- rjf: query listers - { Commands commands "Commands" "" List 0 0 0 0 0 0 0 "" } - { FileSystem file_system "File System" "" FileOutline 0 0 0 0 0 0 0 "" } - { SystemProcesses system_processes "System Processes" "" Null 0 0 0 0 0 0 0 "" } - { EntityLister entity_lister "Entities" "" Null 0 0 0 0 0 0 0 "" } - { CtrlEntityLister ctrl_entity_lister "Control Entities" "" Null 0 0 0 0 0 0 0 "" } - { SymbolLister symbol_lister "Symbols" "" Null 0 0 0 0 0 0 0 "" } - //- rjf: watch or watch-style tables { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } { Locals locals "Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 41c55c85..5e8ef63e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -579,6 +579,16 @@ rd_cfg_release(RD_Cfg *cfg) scratch_end(scratch); } +internal void +rd_cfg_release_all_children(RD_Cfg *cfg) +{ + for(RD_Cfg *child = cfg->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } +} + internal RD_Handle rd_handle_from_cfg(RD_Cfg *cfg) { @@ -1294,38 +1304,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 { rgba = ui_top_palette()->text; } - - //- rjf: name -> icon table - local_persist struct - { - String8 name; - RD_IconKind icon_kind; - } - name2icon_map[] = - { - {str8_lit_comp("target"), RD_IconKind_Target}, - {str8_lit_comp("breakpoint"), RD_IconKind_CircleFilled}, - {str8_lit_comp("auto_view_rule"), RD_IconKind_Binoculars}, - {str8_lit_comp("file_path_map"), RD_IconKind_FileOutline}, - {str8_lit_comp("watch_pin"), RD_IconKind_Pin}, - {str8_lit_comp("watch"), RD_IconKind_Binoculars}, - {str8_lit_comp("window"), RD_IconKind_Window}, - {str8_lit_comp("recent_project"), RD_IconKind_Briefcase}, - {str8_lit_comp("recent_file"), RD_IconKind_FileOutline}, - }; - - //- rjf: map cfg -> icon - RD_IconKind icon_kind = RD_IconKind_Null; - for EachElement(idx, name2icon_map) - { - if(str8_match(cfg->string, name2icon_map[idx].name, 0)) - { - icon_kind = name2icon_map[idx].icon_kind; - break; - } - } - - //- rjf: map icon -> is-from-command-line + RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); B32 is_from_command_line = 0; { RD_Cfg *cmd_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); @@ -1947,28 +1926,6 @@ rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind) //////////////////////////////// //~ rjf: Frontend Entity Info Extraction -internal D_Target -rd_d_target_from_entity(RD_Entity *entity) -{ - RD_Entity *src_target_exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *src_target_args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *src_target_wdir = rd_entity_child_from_kind(entity, RD_EntityKind_WorkingDirectory); - RD_Entity *src_target_stdo = rd_entity_child_from_kind(entity, RD_EntityKind_StdoutPath); - RD_Entity *src_target_stde = rd_entity_child_from_kind(entity, RD_EntityKind_StderrPath); - RD_Entity *src_target_stdi = rd_entity_child_from_kind(entity, RD_EntityKind_StdinPath); - RD_Entity *src_target_entry = rd_entity_child_from_kind(entity, RD_EntityKind_EntryPoint); - D_Target target = {0}; - target.exe = src_target_exe->string; - target.args = src_target_args->string; - target.working_directory = src_target_wdir->string; - target.custom_entry_point_name = src_target_entry->string; - target.stdout_path = src_target_stdo->string; - target.stderr_path = src_target_stde->string; - target.stdin_path = src_target_stdi->string; - target.debug_subprocesses = entity->debug_subprocesses; - return target; -} - internal DR_FancyStringList rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size) { @@ -3290,11 +3247,7 @@ rd_store_view_expr_string(String8 string) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - for(RD_Cfg *child = expr->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(expr); rd_cfg_new(expr, string); } @@ -3303,11 +3256,7 @@ rd_store_view_filter(String8 string) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); - for(RD_Cfg *child = filter->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(filter); rd_cfg_new(filter, string); } @@ -3334,13 +3283,7 @@ rd_store_view_param(String8 key, String8 value) { RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); RD_Cfg *child = rd_cfg_child_from_string_or_alloc(view, key); - for(RD_Cfg *val_child = child->first, *next = &rd_nil_cfg; - val_child != &rd_nil_cfg; - val_child = next) - { - next = val_child->next; - rd_cfg_release(val_child); - } + rd_cfg_release_all_children(child); rd_cfg_new(child, value); } @@ -5236,71 +5179,6 @@ rd_window_frame(void) } #endif }break; - - ////////////////////// - //- rjf: frontend entities - // - case RD_RegSlot_Entity: - { - RD_Entity *entity = rd_entity_from_handle(regs->entity); - RD_EntityKindFlags kind_flags = rd_entity_kind_flags_table[entity->kind]; - - //- rjf: title - UI_Row - UI_PrefWidth(ui_text_dim(5, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_TextPadding(ui_top_font_size()*1.5f) - { - DR_FancyStringList fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - ui_spacer(ui_em(0.5f, 1.f)); - UI_FontSize(ui_top_font_size() - 1.f) - UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(string_from_arch(ctrl_entity->arch)); - ui_spacer(ui_em(0.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("TID: %i", (U32)ctrl_entity->id); - } - } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - //- rjf: name editor - if(kind_flags & RD_EntityKindFlag_CanRename) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, entity->string, "Name###entity_string_edit_%p", ctrl_entity); - if(ui_committed(sig)) - { - rd_cmd(RD_CmdKind_NameEntity, .entity = regs->entity, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } - } - - //- rjf: condition editor - if(kind_flags & RD_EntityKindFlag_CanCondition) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, rd_entity_child_from_kind(entity, RD_EntityKind_Condition)->string, "Condition###entity_condition_edit_%p", entity); - if(ui_committed(sig)) - { - rd_cmd(RD_CmdKind_ConditionEntity, .entity = regs->entity, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } - } - - //- rjf: name editor - if(entity->cfg_src == RD_CfgSrc_CommandLine) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Save, 0, "Save To Project"))) - { - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - } - } - }break; - } } @@ -5839,13 +5717,14 @@ rd_window_frame(void) RD_Palette(RD_PaletteCode_NeutralPopButton) { Temp scratch = scratch_begin(0, 0); - RD_EntityList tasks = rd_query_cached_entity_list_with_kind(RD_EntityKind_ConversionTask); - for(RD_EntityNode *n = tasks.first; n != 0; n = n->next) + RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); + for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) { - RD_Entity *task = n->entity; - if(task->alloc_time_us + 500000 < os_now_microseconds()) + RD_Cfg *task = n->v; + F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%p_%I64u", task, task->gen), 1.f); + if(task_t > 0.5f) { - String8 rdi_path = task->string; + String8 rdi_path = task->first->string; String8 rdi_name = str8_skip_last_slash(rdi_path); String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); @@ -6397,6 +6276,7 @@ rd_window_frame(void) String8 expr = ws->hover_eval_string; E_Eval eval = e_eval_from_string(scratch.arena, expr); EV_ViewRuleList top_level_view_rules = {0}; + EV_ColList top_level_cols = {0}; //- rjf: build if good if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) @@ -6410,7 +6290,7 @@ rd_window_frame(void) 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_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules); + EV_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules, &top_level_cols); EV_BlockRangeList block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); // 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); @@ -12839,14 +12719,12 @@ rd_frame(void) { ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_keys[idx], rd_collection_name_table[idx], 1); } - RD_EntityList auto_view_rules = rd_query_cached_entity_list_with_kind(RD_EntityKind_AutoViewRule); - for(RD_EntityNode *n = auto_view_rules.first; n != 0; n = n->next) + RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); + for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) { - RD_Entity *rule = n->entity; - RD_Entity *src = rd_entity_child_from_kind(rule, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(rule, RD_EntityKind_Dest); - String8 type_string = src->string; - String8 view_rule_string = dst->string; + RD_Cfg *rule = n->v; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("source"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("dest"))->first->string; E_TokenArray tokens = e_token_array_from_text(scratch.arena, type_string); E_Parse type_parse = e_parse_type_from_text_tokens(scratch.arena, type_string, &tokens); E_TypeKey type_key = e_type_from_expr(type_parse.expr); @@ -12917,10 +12795,12 @@ rd_frame(void) CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count == 0 || kind == RD_CmdKind_Restart) { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - n->entity->u64 = 0; + RD_Cfg *hit_count = rd_cfg_child_from_string_or_alloc(n->v, str8_lit("hit_count")); + rd_cfg_release_all_children(hit_count); + rd_cfg_new(hit_count, str8_lit("0")); } } } // fallthrough @@ -13325,66 +13205,28 @@ rd_frame(void) //- rjf: keep track of recent projects if(src == RD_CfgSrc_Project) { - //- TODO(rjf): @cfg keep track of recent projects + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_CfgList recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); + RD_Cfg *recent_project = &rd_nil_cfg; + for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_CfgList recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); - RD_Cfg *recent_project = &rd_nil_cfg; - for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) + if(path_match_normalized(n->v->string, cfg_path)) { - if(path_match_normalized(n->v->string, cfg_path)) - { - recent_project = n->v; - break; - } - } - if(recent_project == &rd_nil_cfg) - { - recent_project = rd_cfg_new(user, str8_lit("recent_project")); - rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); - } - rd_cfg_unhook(user, recent_project); - rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); - recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); - if(recent_projects.count > 32) - { - rd_cfg_release(recent_projects.last->v); - } - } - RD_EntityList recent_projects = rd_query_cached_entity_list_with_kind(RD_EntityKind_RecentProject); - RD_Entity *recent_project = &rd_nil_entity; - for(RD_EntityNode *n = recent_projects.first; n != 0; n = n->next) - { - if(path_match_normalized(cfg_path, n->entity->string)) - { - recent_project = n->entity; + recent_project = n->v; break; } } - if(rd_entity_is_nil(recent_project)) + if(recent_project == &rd_nil_cfg) { - recent_project = rd_entity_alloc(rd_entity_root(), RD_EntityKind_RecentProject); - rd_entity_equip_name(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); - rd_entity_equip_cfg_src(recent_project, RD_CfgSrc_User); + recent_project = rd_cfg_new(user, str8_lit("recent_project")); + rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); } - } - - //- rjf: eliminate all existing entities which are derived from config - { - for EachEnumVal(RD_EntityKind, k) + rd_cfg_unhook(user, recent_project); + rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); + recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); + if(recent_projects.count > 32) { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(k_flags & RD_EntityKindFlag_IsSerializedToConfig) - { - RD_EntityList entities = rd_query_cached_entity_list_with_kind(k); - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - if(n->entity->cfg_src == src) - { - rd_entity_mark_for_deletion(n->entity); - } - } - } + rd_cfg_release(recent_projects.last->v); } } @@ -14070,11 +13912,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); - for(RD_Cfg *child = main_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(main_font_size); rd_cfg_newf(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecUIFontScale: @@ -14084,11 +13922,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); - for(RD_Cfg *child = main_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(main_font_size); rd_cfg_newf(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_IncCodeFontScale: @@ -14098,11 +13932,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - for(RD_Cfg *child = code_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(code_font_size); rd_cfg_newf(code_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecCodeFontScale: @@ -14112,11 +13942,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - for(RD_Cfg *child = code_font_size->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) - { - next = child->next; - rd_cfg_release(child); - } + rd_cfg_release_all_children(code_font_size); rd_cfg_newf(code_font_size, "%f", new_font_size); }break; @@ -14433,21 +14259,13 @@ rd_frame(void) String8 map_src = str8_list_join(scratch.arena, &map_src_parts, &map_join); String8 map_dst = str8_list_join(scratch.arena, &map_dst_parts, &map_join); - //- rjf: store as file path map entity - //- TODO(rjf): @cfg store as file path map entity - { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *map = rd_cfg_new(user, str8_lit("file_path_map")); - RD_Cfg *src = rd_cfg_new(map, str8_lit("source")); - RD_Cfg *dst = rd_cfg_new(map, str8_lit("dest")); - rd_cfg_new(src, map_src); - rd_cfg_new(dst, map_dst); - } - RD_Entity *map = rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); - RD_Entity *src = rd_entity_alloc(map, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_alloc(map, RD_EntityKind_Dest); - rd_entity_equip_name(src, map_src); - rd_entity_equip_name(dst, map_dst); + //- rjf: store as file path map cfg + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *map = rd_cfg_new(user, str8_lit("file_path_map")); + RD_Cfg *src = rd_cfg_new(map, str8_lit("source")); + RD_Cfg *dst = rd_cfg_new(map, str8_lit("dest")); + rd_cfg_new(src, map_src); + rd_cfg_new(dst, map_dst); }break; //- rjf: panel removal @@ -14680,17 +14498,13 @@ rd_frame(void) }break; case RD_CmdKind_TabBarTop: { -#if 0 // TODO(rjf): @cfg - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - panel->tab_side = Side_Min; -#endif + RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + rd_cfg_release(rd_cfg_child_from_string(panel, str8_lit("tabs_on_bottom"))); }break; case RD_CmdKind_TabBarBottom: { -#if 0 // TODO(rjf): @cfg - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - panel->tab_side = Side_Max; -#endif + RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + rd_cfg_child_from_string_or_alloc(panel, str8_lit("tabs_on_bottom")); }break; //- rjf: files @@ -14808,57 +14622,28 @@ rd_frame(void) if(rd_regs()->file_path.size != 0) { String8 path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); - - //- TODO(rjf): @cfg record file in project + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); + RD_Cfg *recent_file = &rd_nil_cfg; + for(RD_CfgNode *n = recent_files.first; n != 0; n = n->next) { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); - RD_Cfg *recent_file = &rd_nil_cfg; - for(RD_CfgNode *n = recent_files.first; n != 0; n = n->next) + if(path_match_normalized(n->v->string, path)) { - if(path_match_normalized(n->v->string, path)) - { - recent_file = n->v; - break; - } - } - if(recent_file == &rd_nil_cfg) - { - recent_file = rd_cfg_new(project, str8_lit("recent_file")); - rd_cfg_new(recent_file, path); - } - rd_cfg_unhook(project, recent_file); - rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); - recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); - if(recent_files.count > 256) - { - rd_cfg_release(recent_files.last->v); - } - } - - RD_EntityList recent_files = rd_query_cached_entity_list_with_kind(RD_EntityKind_RecentFile); - if(recent_files.count >= 256) - { - rd_entity_mark_for_deletion(recent_files.first->entity); - } - RD_Entity *existing_recent_file = &rd_nil_entity; - for(RD_EntityNode *n = recent_files.first; n != 0; n = n->next) - { - if(str8_match(n->entity->string, path, StringMatchFlag_CaseInsensitive)) - { - existing_recent_file = n->entity; + recent_file = n->v; break; } } - if(rd_entity_is_nil(existing_recent_file)) + if(recent_file == &rd_nil_cfg) { - RD_Entity *recent_file = rd_entity_alloc(rd_entity_root(), RD_EntityKind_RecentFile); - rd_entity_equip_name(recent_file, path); - rd_entity_equip_cfg_src(recent_file, RD_CfgSrc_Project); + recent_file = rd_cfg_new(project, str8_lit("recent_file")); + rd_cfg_new(recent_file, path); } - else + rd_cfg_unhook(project, recent_file); + rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); + recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); + if(recent_files.count > 256) { - rd_entity_change_parent(existing_recent_file, rd_entity_root(), rd_entity_root(), rd_entity_root()->last); + rd_cfg_release(recent_files.last->v); } }break; case RD_CmdKind_ShowFileInExplorer: @@ -16145,124 +15930,95 @@ X(getting_started) }break; //- rjf: general entity operations - case RD_CmdKind_SelectEntity: + case RD_CmdKind_SelectCfg: case RD_CmdKind_SelectTarget: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_EntityList all_of_the_same_kind = rd_query_cached_entity_list_with_kind(entity->kind); - B32 is_selected = !entity->disabled; - for(RD_EntityNode *n = all_of_the_same_kind.first; n != 0; n = n->next) + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_CfgList all_of_the_same_kind = rd_cfg_top_level_list_from_string(scratch.arena, cfg->string); + B32 is_selected = rd_disabled_from_cfg(cfg); + for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) { - RD_Entity *e = n->entity; - rd_entity_equip_disabled(e, 1); + RD_Cfg *c = n->v; + rd_cfg_child_from_string_or_alloc(c, str8_lit("disabled")); } if(!is_selected) { - rd_entity_equip_disabled(entity, 0); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("disabled"))); } }break; - case RD_CmdKind_EnableEntity: + case RD_CmdKind_EnableCfg: case RD_CmdKind_EnableBreakpoint: case RD_CmdKind_EnableTarget: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - rd_entity_equip_disabled(entity, 0); + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("disabled"))); }break; - case RD_CmdKind_DisableEntity: + case RD_CmdKind_DisableCfg: case RD_CmdKind_DisableBreakpoint: case RD_CmdKind_DisableTarget: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - rd_entity_equip_disabled(entity, 1); + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); }break; - case RD_CmdKind_RemoveEntity: + case RD_CmdKind_RemoveCfg: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_EntityKindFlags kind_flags = rd_entity_kind_flags_table[entity->kind]; - if(kind_flags & RD_EntityKindFlag_CanDelete) + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + rd_cfg_release(cfg); + }break; + case RD_CmdKind_NameCfg: + { + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + if(rd_regs()->string.size != 0) { - rd_entity_mark_for_deletion(entity); - } - }break; - case RD_CmdKind_NameEntity: - { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - String8 string = rd_regs()->string; - rd_entity_equip_name(entity, string); - }break; - case RD_CmdKind_ConditionEntity: - { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - String8 string = rd_regs()->string; - if(string.size != 0) - { - RD_Entity *child = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Condition); - rd_entity_equip_name(child, string); + RD_Cfg *label = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("label")); + rd_cfg_new(label, rd_regs()->string); } else { - RD_Entity *child = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - rd_entity_mark_for_deletion(child); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("label"))); } }break; - case RD_CmdKind_DuplicateEntity: + case RD_CmdKind_ConditionCfg: { - RD_Entity *src = rd_entity_from_handle(rd_regs()->entity); - if(!rd_entity_is_nil(src)) + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + if(rd_regs()->string.size != 0) { - typedef struct Task Task; - struct Task - { - Task *next; - RD_Entity *src_n; - RD_Entity *dst_parent; - }; - Task starter_task = {0, src, src->parent}; - Task *first_task = &starter_task; - Task *last_task = &starter_task; - for(Task *task = first_task; task != 0; task = task->next) - { - RD_Entity *src_n = task->src_n; - RD_Entity *dst_n = rd_entity_alloc(task->dst_parent, task->src_n->kind); - if(src_n->flags & RD_EntityFlag_HasTextPoint) {rd_entity_equip_txt_pt(dst_n, src_n->text_point);} - if(src_n->flags & RD_EntityFlag_HasU64) {rd_entity_equip_u64(dst_n, src_n->u64);} - if(src_n->flags & RD_EntityFlag_HasColor) {rd_entity_equip_color_hsva(dst_n, rd_hsva_from_entity(src_n));} - if(src_n->flags & RD_EntityFlag_HasVAddr) {rd_entity_equip_vaddr(dst_n, src_n->vaddr);} - if(src_n->disabled) {rd_entity_equip_disabled(dst_n, 1);} - if(src_n->string.size != 0) {rd_entity_equip_name(dst_n, src_n->string);} - dst_n->cfg_src = src_n->cfg_src; - for(RD_Entity *src_child = task->src_n->first; !rd_entity_is_nil(src_child); src_child = src_child->next) - { - Task *child_task = push_array(scratch.arena, Task, 1); - child_task->src_n = src_child; - child_task->dst_parent = dst_n; - SLLQueuePush(first_task, last_task, child_task); - } - } + RD_Cfg *cnd = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("condition")); + rd_cfg_new(cnd, rd_regs()->string); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("condition"))); } }break; - case RD_CmdKind_RelocateEntity: + case RD_CmdKind_DuplicateCfg: { - RD_Entity *entity = rd_entity_from_handle(rd_regs()->entity); - RD_Entity *location = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - if(rd_entity_is_nil(location)) + RD_Cfg *src = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *dst = rd_cfg_deep_copy(src); + rd_cfg_insert_child(src->parent, src, dst); + }break; + case RD_CmdKind_RelocateCfg: + { + RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *loc = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("location")); + for(RD_Cfg *child = loc->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { - location = rd_entity_alloc(entity, RD_EntityKind_Location); + next = child->next; + rd_cfg_release(child); } - location->flags &= ~RD_EntityFlag_HasTextPoint; - location->flags &= ~RD_EntityFlag_HasVAddr; if(rd_regs()->cursor.line != 0) { - rd_entity_equip_txt_pt(location, rd_regs()->cursor); + RD_Cfg *file = rd_cfg_new(loc, rd_regs()->file_path); + RD_Cfg *line = rd_cfg_newf(file, "%I64d", rd_regs()->cursor.line); + rd_cfg_newf(line, "%I64d", rd_regs()->cursor.column); } - if(rd_regs()->vaddr != 0) + else if(rd_regs()->vaddr != 0) { - rd_entity_equip_vaddr(location, rd_regs()->vaddr); - rd_entity_equip_name(location, str8_zero()); + rd_cfg_newf(loc, "0x%I64x", rd_regs()->vaddr); } - if(rd_regs()->file_path.size != 0) + else if(rd_regs()->string.size != 0) { - rd_entity_equip_name(location, rd_regs()->file_path); + rd_cfg_new(loc, rd_regs()->string); } }break; @@ -16276,62 +16032,22 @@ X(getting_started) U64 vaddr = rd_regs()->vaddr; if(file_path.size != 0 || string.size != 0 || vaddr != 0) { - //- TODO(rjf): @cfg add/toggle breakpoint - { - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleBreakpoint) - { - RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); - for(RD_CfgNode *n = bps.first; n != 0; n = n->next) - { - RD_Cfg *bp = n->v; - RD_Cfg *loc = rd_cfg_child_from_string(bp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_string = (string.size != 0 && str8_match(loc->first->string, string, 0)); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - if(loc_matches_file_pt || loc_matches_string || loc_matches_vaddr) - { - rd_cfg_release(bp); - removed_already_existing = 1; - break; - } - } - } - if(!removed_already_existing) - { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); - RD_Cfg *loc = rd_cfg_new(bp, str8_lit("location")); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(string.size != 0) - { - rd_cfg_new(loc, string); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); - } - } - } B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleBreakpoint) { - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - if((loc->flags & RD_EntityFlag_HasTextPoint && path_match_normalized(loc->string, file_path) && loc->text_point.line == pt.line) || - (loc->flags & RD_EntityFlag_HasVAddr && loc->vaddr == vaddr) || - (!(loc->flags & RD_EntityFlag_HasTextPoint) && str8_match(loc->string, string, 0))) + RD_Cfg *bp = n->v; + RD_Cfg *loc = rd_cfg_child_from_string(bp, str8_lit("location")); + S64 loc_line = 0; + U64 loc_vaddr = 0; + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); + B32 loc_matches_string = (string.size != 0 && str8_match(loc->first->string, string, 0)); + B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); + if(loc_matches_file_pt || loc_matches_string || loc_matches_vaddr) { - rd_entity_mark_for_deletion(bp); + rd_cfg_release(bp); removed_already_existing = 1; break; } @@ -16339,21 +16055,21 @@ X(getting_started) } if(!removed_already_existing) { - RD_Entity *bp = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Breakpoint); - rd_entity_equip_cfg_src(bp, RD_CfgSrc_Project); - RD_Entity *loc = rd_entity_alloc(bp, RD_EntityKind_Location); + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); + RD_Cfg *loc = rd_cfg_new(bp, str8_lit("location")); if(vaddr != 0) { - rd_entity_equip_vaddr(loc, vaddr); + rd_cfg_newf(loc, "0x%I64x", vaddr); } else if(string.size != 0) { - rd_entity_equip_name(loc, string); + rd_cfg_new(loc, string); } - else if(file_path.size != 0 && pt.line != 0) + else if(file_path.size != 0) { - rd_entity_equip_name(loc, file_path); - rd_entity_equip_txt_pt(loc, pt); + RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); + rd_cfg_newf(file_path_cfg, "%I64d", pt.line); } } } @@ -16375,61 +16091,23 @@ X(getting_started) TxtPt pt = rd_regs()->cursor; String8 string = rd_regs()->string; U64 vaddr = rd_regs()->vaddr; - //- TODO(rjf): @cfg add/toggle watch pin - { - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleWatchPin) - { - RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); - for(RD_CfgNode *n = wps.first; n != 0; n = n->next) - { - RD_Cfg *wp = n->v; - RD_Cfg *expr = rd_cfg_child_from_string(wp, str8_lit("expression")); - RD_Cfg *loc = rd_cfg_child_from_string(wp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - B32 loc_matches_expr = (string.size != 0 && str8_match(expr->first->string, string, 0)); - if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) - { - rd_cfg_release(wp); - removed_already_existing = 1; - break; - } - } - } - if(!removed_already_existing) - { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); - RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); - RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); - rd_cfg_new(expr, string); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); - } - } - } B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleWatchPin) { - RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + RD_CfgList wps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch_pin")); + for(RD_CfgNode *n = wps.first; n != 0; n = n->next) { - RD_Entity *wp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(wp, RD_EntityKind_Location); - if(str8_match(wp->string, string, 0) && - ((loc->flags & RD_EntityFlag_HasTextPoint && path_match_normalized(loc->string, file_path) && loc->text_point.line == pt.line) || - (loc->flags & RD_EntityFlag_HasVAddr && loc->vaddr == vaddr))) + RD_Cfg *wp = n->v; + RD_Cfg *expr = rd_cfg_child_from_string(wp, str8_lit("expression")); + RD_Cfg *loc = rd_cfg_child_from_string(wp, str8_lit("location")); + S64 loc_line = 0; + U64 loc_vaddr = 0; + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); + B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); + B32 loc_matches_expr = (string.size != 0 && str8_match(expr->first->string, string, 0)); + if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) { - rd_entity_mark_for_deletion(wp); + rd_cfg_release(wp); removed_already_existing = 1; break; } @@ -16437,18 +16115,19 @@ X(getting_started) } if(!removed_already_existing) { - RD_Entity *wp = rd_entity_alloc(rd_entity_root(), RD_EntityKind_WatchPin); - rd_entity_equip_name(wp, string); - rd_entity_equip_cfg_src(wp, RD_CfgSrc_Project); - RD_Entity *loc = rd_entity_alloc(wp, RD_EntityKind_Location); - if(file_path.size != 0 && pt.line != 0) + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); + RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); + RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); + rd_cfg_new(expr, string); + if(vaddr != 0) { - rd_entity_equip_name(loc, file_path); - rd_entity_equip_txt_pt(loc, pt); + rd_cfg_newf(loc, "0x%I64x", vaddr); } - else if(vaddr != 0) + else if(file_path.size != 0) { - rd_entity_equip_vaddr(loc, vaddr); + RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); + rd_cfg_newf(file_path_cfg, "%I64d", pt.line); } } }break; @@ -16526,37 +16205,18 @@ X(getting_started) //- rjf: targets case RD_CmdKind_AddTarget: { - //- TODO(rjf): @cfg add new target + String8 file_path = rd_regs()->file_path; + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); + RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); + rd_cfg_new(exe, file_path); + String8 working_directory = str8_chop_last_slash(file_path); + if(working_directory.size != 0) { - String8 file_path = rd_regs()->file_path; - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); - RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); - rd_cfg_new(exe, file_path); - String8 working_directory = str8_chop_last_slash(file_path); - if(working_directory.size != 0) - { - RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); - rd_cfg_newf(wdir, "%S/", working_directory); - } - // TODO(rjf): (select target here) + RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); + rd_cfg_newf(wdir, "%S/", working_directory); } - - // rjf: build target - RD_Entity *entity = &rd_nil_entity; - entity = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Target); - rd_entity_equip_disabled(entity, 1); - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - RD_Entity *exe = rd_entity_alloc(entity, RD_EntityKind_Executable); - rd_entity_equip_name(exe, rd_regs()->file_path); - String8 working_dir = str8_chop_last_slash(rd_regs()->file_path); - if(working_dir.size != 0) - { - String8 working_dir_path = push_str8f(scratch.arena, "%S/", working_dir); - RD_Entity *execution_path = rd_entity_alloc(entity, RD_EntityKind_WorkingDirectory); - rd_entity_equip_name(execution_path, working_dir_path); - } - rd_cmd(RD_CmdKind_SelectTarget, .entity = rd_handle_from_entity(entity)); + rd_cmd(RD_CmdKind_SelectCfg, .cfg = rd_handle_from_cfg(target)); }break; //- rjf: jit-debugger registration @@ -17222,20 +16882,21 @@ X(getting_started) U64 meval_count = 0; MetaEvalNode *first_meval = 0; MetaEvalNode *last_meval = 0; - RD_EntityList bp_entities = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - breakpoints.count = bp_entities.count; + RD_CfgList bp_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + breakpoints.count = bp_cfgs.count; breakpoints.v = push_array(scratch.arena, D_Breakpoint, breakpoints.count); U64 idx = 0; - for(RD_EntityNode *n = bp_entities.first; n != 0; n = n->next) + for(RD_CfgNode *n = bp_cfgs.first; n != 0; n = n->next) { - RD_Entity *src_bp = n->entity; - if(src_bp->disabled) + RD_Cfg *src_bp = n->v; + B32 src_bp_is_disabled = rd_disabled_from_cfg(src_bp); + if(src_bp_is_disabled) { breakpoints.count -= 1; continue; } - RD_Entity *src_bp_loc = rd_entity_child_from_kind(src_bp, RD_EntityKind_Location); - RD_Entity *src_bp_cnd = rd_entity_child_from_kind(src_bp, RD_EntityKind_Condition); + RD_Location src_bp_loc = rd_location_from_cfg(src_bp); + String8 src_bp_cnd = rd_cfg_child_from_string(src_bp, str8_lit("condition"))->first->string; //- rjf: walk conditional breakpoint expression tree - for each leaf identifier, // determine if it resolves to a meta-evaluation. if it does, compute the meta @@ -17248,7 +16909,7 @@ X(getting_started) // or not it is 'static', w.r.t. the control thread. // B32 is_static_for_ctrl_thread = 0; - if(src_bp_cnd->string.size != 0) + if(src_bp_cnd.size != 0) { typedef struct ExprWalkTask ExprWalkTask; struct ExprWalkTask @@ -17256,7 +16917,7 @@ X(getting_started) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd->string); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd); ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) @@ -17302,7 +16963,7 @@ X(getting_started) B32 is_statically_disqualified = 0; if(is_static_for_ctrl_thread) { - E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd->string); + E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd); E_Eval value_eval = e_value_eval_from_eval(eval); if(value_eval.value.u64 == 0) { @@ -17319,11 +16980,11 @@ X(getting_started) //- rjf: fill breakpoint D_Breakpoint *dst_bp = &breakpoints.v[idx]; - dst_bp->file_path = src_bp_loc->string; - dst_bp->pt = src_bp_loc->text_point; - dst_bp->symbol_name = src_bp_loc->string; - dst_bp->vaddr = src_bp_loc->vaddr; - dst_bp->condition = src_bp_cnd->string; + dst_bp->file_path = src_bp_loc.file_path; + dst_bp->pt = src_bp_loc.pt; + dst_bp->symbol_name = src_bp_loc.name; + dst_bp->vaddr = src_bp_loc.vaddr; + dst_bp->condition = src_bp_cnd; idx += 1; } @@ -17345,15 +17006,15 @@ X(getting_started) // D_PathMapArray path_maps = {0}; { - RD_EntityList maps = rd_query_cached_entity_list_with_kind(RD_EntityKind_FilePathMap); + RD_CfgList maps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); path_maps.count = maps.count; path_maps.v = push_array(scratch.arena, D_PathMap, path_maps.count); U64 idx = 0; - for(RD_EntityNode *n = maps.first; n != 0; n = n->next, idx += 1) + for(RD_CfgNode *n = maps.first; n != 0; n = n->next, idx += 1) { - RD_Entity *map = n->entity; - path_maps.v[idx].src = rd_entity_child_from_kind(map, RD_EntityKind_Source)->string; - path_maps.v[idx].dst = rd_entity_child_from_kind(map, RD_EntityKind_Dest)->string; + RD_Cfg *map = n->v; + path_maps.v[idx].src = rd_cfg_child_from_string(map, str8_lit("source"))->first->string; + path_maps.v[idx].dst = rd_cfg_child_from_string(map, str8_lit("dest"))->first->string; } } @@ -17428,35 +17089,40 @@ X(getting_started) // rjf: increment breakpoint hit counts if(evt->cause == D_EventCause_UserBreakpoint) { - RD_EntityList user_bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - for(RD_EntityNode *n = user_bps.first; n != 0; n = n->next) + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_Entity *bp = n->entity; - RD_Entity *loc = rd_entity_child_from_kind(bp, RD_EntityKind_Location); - D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc->string, loc->text_point.line); + RD_Cfg *bp = n->v; + RD_Cfg *hit_count_root = rd_cfg_child_from_string_or_alloc(bp, str8_lit("hit_count")); + U64 hit_count = 0; + try_u64_from_str8_c_rules(hit_count_root->first->string, &hit_count); + RD_Location loc = rd_location_from_cfg(bp); + D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc.file_path, loc.pt.line); if(loc_lines.first != 0) { for(D_LineNode *n = loc_lines.first; n != 0; n = n->next) { if(contains_1u64(n->v.voff_range, voff)) { - bp->u64 += 1; + hit_count += 1; break; } } } - else if(loc->flags & RD_EntityFlag_HasVAddr && vaddr == loc->vaddr) + else if(loc.vaddr != 0 && vaddr == loc.vaddr) { - bp->u64 += 1; + hit_count += 1; } - else if(loc->string.size != 0) + else if(loc.name.size != 0) { - U64 symb_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, loc->string); + U64 symb_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, loc.name); if(symb_voff == voff) { - bp->u64 += 1; + hit_count += 1; } } + rd_cfg_release_all_children(hit_count_root); + rd_cfg_newf(hit_count_root, "%I64u", hit_count); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index a2421f7d..fc8e2169 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1138,6 +1138,7 @@ internal void rd_name_release(String8 string); internal RD_Cfg *rd_cfg_alloc(void); internal void rd_cfg_release(RD_Cfg *cfg); +internal void rd_cfg_release_all_children(RD_Cfg *cfg); internal RD_Handle rd_handle_from_cfg(RD_Cfg *cfg); internal RD_Cfg *rd_cfg_from_handle(RD_Handle handle); internal RD_Cfg *rd_cfg_new(RD_Cfg *parent, String8 string); @@ -1218,7 +1219,6 @@ internal RD_Entity *rd_entity_from_name_and_kind(String8 string, RD_EntityKind k //////////////////////////////// //~ rjf: Frontend Entity Info Extraction -internal D_Target rd_d_target_from_entity(RD_Entity *entity); internal DR_FancyStringList rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size); //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 1430e47d..2ab0280b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1274,6 +1274,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: unpack arguments // EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_from_string(scratch.arena, root_view_rule); + EV_ColList top_level_cols = {0}; String8 eval_view_key_string = push_str8f(scratch.arena, "eval_view_watch_%p", ewv); EV_View *eval_view = rd_ev_view_from_key(d_hash_from_string(eval_view_key_string)); String8 filter = rd_view_filter(); @@ -1285,6 +1286,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { string_flags |= EV_StringFlag_PrettyNames; } +#if 0 // TODO(rjf): @cfg RD_WatchViewRowCtrl row_ctrls_[] = { {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_LaunchAndRun }, @@ -1303,6 +1305,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo }; RD_WatchViewRowCtrl *row_ctrls = row_ctrls_; U64 row_ctrls_count = ArrayCount(row_ctrls_); +#endif ////////////////////////////// //- rjf: root-level view rule which has a ui hook? call into that to build the UI @@ -1371,7 +1374,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules); + block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules, &top_level_cols); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); } @@ -1467,6 +1470,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo if(row_kind == RD_WatchViewRowKind_PrettyEntityControls) { U64 row_ctrl_count = 0; +#if 0 // TODO(rjf): @cfg for EachIndex(idx, row_ctrls_count) { if(row_ctrls[idx].entity_kind == row_info.collection_entity->kind && @@ -1475,6 +1479,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo row_ctrl_count += 1; } } +#endif cursor_x_range = r1s64(1, 1+row_ctrl_count); } } @@ -2725,6 +2730,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } if(ui_double_clicked(sig)) { +#if 0 // TODO(rjf): @cfg if(entity->kind == RD_EntityKind_Target) { rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : @@ -2744,6 +2750,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo .cursor = loc->text_point, .vaddr = loc->vaddr); } +#endif } } } @@ -2751,6 +2758,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: build extra entity controls UI_PrefWidth(ui_em(3.f, 1.f)) { +#if 0 // TODO(rjf): @cfg U64 ctrl_idx = 1; for EachIndex(idx, row_ctrls_count) { @@ -2818,6 +2826,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ctrl_idx += 1; } } +#endif } } }break; @@ -3592,1811 +3601,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) ProfEnd(); } -//////////////////////////////// -//~ rjf: commands @view_hook_impl - -typedef struct RD_CmdListerItem RD_CmdListerItem; -struct RD_CmdListerItem -{ - String8 cmd_name; - U64 registrar_idx; - U64 ordering_idx; - FuzzyMatchRangeList name_match_ranges; - FuzzyMatchRangeList desc_match_ranges; - FuzzyMatchRangeList tags_match_ranges; -}; - -typedef struct RD_CmdListerItemNode RD_CmdListerItemNode; -struct RD_CmdListerItemNode -{ - RD_CmdListerItemNode *next; - RD_CmdListerItem item; -}; - -typedef struct RD_CmdListerItemList RD_CmdListerItemList; -struct RD_CmdListerItemList -{ - RD_CmdListerItemNode *first; - RD_CmdListerItemNode *last; - U64 count; -}; - -typedef struct RD_CmdListerItemArray RD_CmdListerItemArray; -struct RD_CmdListerItemArray -{ - RD_CmdListerItem *v; - U64 count; -}; - -internal RD_CmdListerItemList -rd_cmd_lister_item_list_from_needle(Arena *arena, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_CmdListerItemList result = {0}; - // TODO(rjf): extend this with dynamically-registered command info - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - if(info->flags & RD_CmdKindFlag_ListInUI) - { - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - String8 cmd_tags = info->search_tags; - FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, cmd_display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(arena, needle, cmd_desc); - FuzzyMatchRangeList tags_matches = fuzzy_match_find(arena, needle, cmd_tags); - if(name_matches.count == name_matches.needle_part_count || - desc_matches.count == name_matches.needle_part_count || - tags_matches.count > 0 || - name_matches.needle_part_count == 0) - { - RD_CmdListerItemNode *node = push_array(arena, RD_CmdListerItemNode, 1); - node->item.cmd_name = info->string; - node->item.registrar_idx = (U64)k; - node->item.ordering_idx = (U64)k; - node->item.name_match_ranges = name_matches; - node->item.desc_match_ranges = desc_matches; - node->item.tags_match_ranges = tags_matches; - SLLQueuePush(result.first, result.last, node); - result.count += 1; - } - } - } - scratch_end(scratch); - return result; -} - -internal RD_CmdListerItemArray -rd_cmd_lister_item_array_from_list(Arena *arena, RD_CmdListerItemList list) -{ - RD_CmdListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_CmdListerItem, result.count); - U64 idx = 0; - for(RD_CmdListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - return result; -} - -internal int -rd_qsort_compare_cmd_lister__strength(RD_CmdListerItem *a, RD_CmdListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - else if(a->desc_match_ranges.count > b->desc_match_ranges.count) - { - result = -1; - } - else if(a->desc_match_ranges.count < b->desc_match_ranges.count) - { - result = +1; - } - else if(a->tags_match_ranges.count > b->tags_match_ranges.count) - { - result = -1; - } - else if(a->tags_match_ranges.count < b->tags_match_ranges.count) - { - result = +1; - } - else if(a->registrar_idx < b->registrar_idx) - { - result = -1; - } - else if(a->registrar_idx > b->registrar_idx) - { - result = +1; - } - else if(a->ordering_idx < b->ordering_idx) - { - result = -1; - } - else if(a->ordering_idx > b->ordering_idx) - { - result = +1; - } - return result; -} - -internal void -rd_cmd_lister_item_array_sort_by_strength__in_place(RD_CmdListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_CmdListerItem), rd_qsort_compare_cmd_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(commands) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - - //- rjf: grab state - typedef struct RD_CmdsViewState RD_CmdsViewState; - struct RD_CmdsViewState - { - U64 selected_cmd_hash; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_CmdsViewState *cv = rd_view_state(RD_CmdsViewState); - - //- rjf: build filtered array of commands - RD_CmdListerItemList cmd_list = rd_cmd_lister_item_list_from_needle(scratch.arena, string); - RD_CmdListerItemArray cmd_array = rd_cmd_lister_item_array_from_list(scratch.arena, cmd_list); - rd_cmd_lister_item_array_sort_by_strength__in_place(cmd_array); - - //- rjf: submit best match when hitting enter w/ no selection - if(cv->selected_cmd_hash == 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = (cmd_array.count > 0 ? cmd_array.v[0].cmd_name : str8_zero())); - } - - //- rjf: selected kind -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < cmd_array.count; idx += 1) - { - if(d_hash_from_string(cmd_array.v[idx].cmd_name) == cv->selected_cmd_hash) - { - cursor.y = (S64)idx+1; - break; - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*6.5f); - scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, cmd_array.count)); - scroll_list_params.item_range = r1s64(0, cmd_array.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - //- rjf: build buttons - for(S64 row_idx = visible_row_range.min; - row_idx <= visible_row_range.max && row_idx < cmd_array.count; - row_idx += 1) - { - RD_CmdListerItem *item = &cmd_array.v[row_idx]; - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(item->cmd_name); - - //- rjf: build row contents - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_Focus(cursor.y == row_idx+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###cmd_button_%S", item->cmd_name); - } - UI_Parent(box) UI_PrefHeight(ui_em(1.65f, 1.f)) - { - //- rjf: icon - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_HeightFill - UI_Column - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HeightFill - UI_TextAlignment(UI_TextAlign_Center) - { - RD_IconKind icon = info->icon_kind; - if(icon != RD_IconKind_Null) - { - ui_label(rd_icon_kind_text_table[icon]); - } - } - - //- rjf: name + description - ui_set_next_pref_height(ui_pct(1, 0)); - UI_Column UI_Padding(ui_pct(1, 0)) - { - FNT_Tag font = ui_top_font(); - F32 font_size = ui_top_font_size(); - FNT_Metrics font_metrics = fnt_metrics_from_tag_size(font, font_size); - F32 font_line_height = fnt_line_height_from_metrics(&font_metrics); - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - UI_Box *name_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##name_%S", cmd_display_name, info->string); - UI_Box *desc_box = &ui_nil_box; - UI_PrefHeight(ui_em(1.8f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - desc_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##desc_%S", cmd_desc, info->string); - } - ui_box_equip_fuzzy_match_ranges(name_box, &item->name_match_ranges); - ui_box_equip_fuzzy_match_ranges(desc_box, &item->desc_match_ranges); - } - - //- rjf: bindings - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_NamedRow(str8_lit("binding_row")) UI_Padding(ui_em(1.f, 1.f)) - { - rd_cmd_binding_buttons(item->cmd_name); - } - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = item->cmd_name); - } - } - } - - //- rjf: map selected num -> selected kind - if(1 <= cursor.y && cursor.y <= cmd_array.count) - { - cv->selected_cmd_hash = d_hash_from_string(cmd_array.v[cursor.y-1].cmd_name); - } - else - { - cv->selected_cmd_hash = 0; - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: file_system @view_hook_impl - -typedef enum RD_FileSortKind -{ - RD_FileSortKind_Null, - RD_FileSortKind_Filename, - RD_FileSortKind_LastModified, - RD_FileSortKind_Size, - RD_FileSortKind_COUNT -} -RD_FileSortKind; - -typedef struct RD_FileInfo RD_FileInfo; -struct RD_FileInfo -{ - String8 filename; - FileProperties props; - FuzzyMatchRangeList match_ranges; -}; - -typedef struct RD_FileInfoNode RD_FileInfoNode; -struct RD_FileInfoNode -{ - RD_FileInfoNode *next; - RD_FileInfo file_info; -}; - -typedef struct RD_FileSystemViewPathState RD_FileSystemViewPathState; -struct RD_FileSystemViewPathState -{ - RD_FileSystemViewPathState *hash_next; - String8 normalized_path; - Vec2S64 cursor; -}; - -typedef struct RD_FileSystemViewState RD_FileSystemViewState; -struct RD_FileSystemViewState -{ - B32 initialized; - U64 path_state_table_size; - RD_FileSystemViewPathState **path_state_table; - RD_FileSortKind sort_kind; - Side sort_side; - Arena *cached_files_arena; - String8 cached_files_path; - RD_FileSortKind cached_files_sort_kind; - Side cached_files_sort_side; - U64 cached_file_count; - RD_FileInfo *cached_files; - F32 col_pcts[3]; -}; - -typedef struct RD_PathQuery RD_PathQuery; -struct RD_PathQuery -{ - String8 prefix; - String8 path; - String8 search; -}; - -internal RD_PathQuery -rd_path_query_from_string(String8 string) -{ - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < string.size; i += 1) - { - String8 substr1 = str8_substr(string, r1u64(i, i+1)); - String8 substr2 = str8_substr(string, r1u64(i, i+2)); - String8 substr3 = str8_substr(string, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i-1, string.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(string, r1u64(i, string.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - RD_PathQuery path_query = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - String8 search = {0}; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - path_query.path = dir; - path_query.search = search; - path_query.prefix = str8_substr(string, r1u64(0, path_query.path.str - string.str)); - } - return path_query; -} - -internal int -rd_qsort_compare_file_info__filename(RD_FileInfo *a, RD_FileInfo *b) -{ - return strncmp((char *)a->filename.str, (char *)b->filename.str, Min(a->filename.size, b->filename.size)); -} - -internal int -rd_qsort_compare_file_info__default(RD_FileInfo *a, RD_FileInfo *b) -{ - int result = 0; - if(a->props.flags & FilePropertyFlag_IsFolder && !(b->props.flags & FilePropertyFlag_IsFolder)) - { - result = -1; - } - else if(b->props.flags & FilePropertyFlag_IsFolder && !(a->props.flags & FilePropertyFlag_IsFolder)) - { - result = +1; - } - else - { - result = rd_qsort_compare_file_info__filename(a, b); - } - return result; -} - -internal int -rd_qsort_compare_file_info__default_filtered(RD_FileInfo *a, RD_FileInfo *b) -{ - int result = 0; - if(a->filename.size < b->filename.size) - { - result = -1; - } - else if(a->filename.size > b->filename.size) - { - result = +1; - } - return result; -} - -internal int -rd_qsort_compare_file_info__last_modified(RD_FileInfo *a, RD_FileInfo *b) -{ - return ((a->props.modified < b->props.modified) ? -1 : - (a->props.modified > b->props.modified) ? +1 : - 0); -} - -internal int -rd_qsort_compare_file_info__size(RD_FileInfo *a, RD_FileInfo *b) -{ - return ((a->props.size < b->props.size) ? -1 : - (a->props.size > b->props.size) ? +1 : - 0); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(file_system) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - String8 query = string; - String8 query_normalized = path_normalized_from_string(scratch.arena, query); - B32 query_has_slash = (query.size != 0 && char_to_correct_slash(query.str[query.size-1]) == '/'); - String8 query_normalized_with_opt_slash = push_str8f(scratch.arena, "%S%s", query_normalized, query_has_slash ? "/" : ""); - RD_PathQuery path_query = rd_path_query_from_string(query_normalized_with_opt_slash); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); -#if 0 // TODO(rjf): @cfg - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); -#endif - B32 file_selection = 1;// !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFiles); - B32 dir_selection = 1;// !!(cmd_kind_info->query.flags & RD_QueryFlag_AllowFolders); - - //- rjf: get extra state for this view - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_FileSystemViewState *fs = rd_view_state(RD_FileSystemViewState); - if(fs->initialized == 0) - { - fs->initialized = 1; - fs->path_state_table_size = 256; - fs->path_state_table = push_array(rd_view_arena(), RD_FileSystemViewPathState *, fs->path_state_table_size); - fs->cached_files_arena = rd_push_view_arena(); - fs->col_pcts[0] = 0.60f; - fs->col_pcts[1] = 0.20f; - fs->col_pcts[2] = 0.20f; - } - - //- rjf: grab state for the current path - RD_FileSystemViewPathState *ps = 0; - { - String8 key = query_normalized; - U64 hash = d_hash_from_string(key); - U64 slot = hash % fs->path_state_table_size; - for(RD_FileSystemViewPathState *p = fs->path_state_table[slot]; p != 0; p = p->hash_next) - { - if(str8_match(p->normalized_path, key, 0)) - { - ps = p; - break; - } - } - if(ps == 0) - { - ps = push_array(rd_view_arena(), RD_FileSystemViewPathState, 1); - ps->hash_next = fs->path_state_table[slot]; - fs->path_state_table[slot] = ps; - ps->normalized_path = push_str8_copy(rd_view_arena(), key); - } - } - - //- rjf: get file array from the current path - U64 file_count = fs->cached_file_count; - RD_FileInfo *files = fs->cached_files; - if(!str8_match(fs->cached_files_path, query_normalized_with_opt_slash, 0) || - fs->cached_files_sort_kind != fs->sort_kind || - fs->cached_files_sort_side != fs->sort_side) - { - arena_clear(fs->cached_files_arena); - - //- rjf: store off path that we're gathering from - fs->cached_files_path = push_str8_copy(fs->cached_files_arena, query_normalized_with_opt_slash); - fs->cached_files_sort_kind = fs->sort_kind; - fs->cached_files_sort_side = fs->sort_side; - - //- rjf: use stored path as the new browse path for the whole frontend - // (multiple file system views may conflict here. that's okay. we'll just always - // choose the most recent change to a file browser path, and live with the - // consequences). - { - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_query.path); - } - - //- rjf: get files, filtered - U64 new_file_count = 0; - RD_FileInfoNode *first_file = 0; - RD_FileInfoNode *last_file = 0; - { - OS_FileIter *it = os_file_iter_begin(scratch.arena, path_query.path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(fs->cached_files_arena, path_query.search, info.name); - B32 fits_search = (path_query.search.size == 0 || match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = !!(info.props.flags & FilePropertyFlag_IsFolder) || !dir_selection; - if(fits_search && fits_dir_only) - { - RD_FileInfoNode *node = push_array(scratch.arena, RD_FileInfoNode, 1); - node->file_info.filename = push_str8_copy(fs->cached_files_arena, info.name); - node->file_info.props = info.props; - node->file_info.match_ranges = match_ranges; - SLLQueuePush(first_file, last_file, node); - new_file_count += 1; - } - } - os_file_iter_end(it); - } - - //- rjf: convert list to array - RD_FileInfo *new_files = push_array(fs->cached_files_arena, RD_FileInfo, new_file_count); - { - U64 idx = 0; - for(RD_FileInfoNode *n = first_file; n != 0; n = n->next, idx += 1) - { - new_files[idx] = n->file_info; - } - } - - //- rjf: apply sort - switch(fs->sort_kind) - { - default: - { - if(path_query.search.size != 0) - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__default_filtered); - } - else - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__default); - } - }break; - case RD_FileSortKind_Filename: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__filename); - }break; - case RD_FileSortKind_LastModified: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__last_modified); - }break; - case RD_FileSortKind_Size: - { - quick_sort(new_files, new_file_count, sizeof(RD_FileInfo), rd_qsort_compare_file_info__size); - }break; - } - - //- rjf: apply reverse - if(fs->sort_kind != RD_FileSortKind_Null && fs->sort_side == Side_Max) - { - for(U64 idx = 0; idx < new_file_count/2; idx += 1) - { - U64 rev_idx = new_file_count - idx - 1; - Swap(RD_FileInfo, new_files[idx], new_files[rev_idx]); - } - } - - fs->cached_file_count = file_count = new_file_count; - fs->cached_files = files = new_files; - } - - //- rjf: submit best match when hitting enter w/ no selection - if(ps->cursor.y == 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - FileProperties query_normalized_with_opt_slash_props = os_properties_from_file_path(query_normalized_with_opt_slash); - FileProperties path_query_path_props = os_properties_from_file_path(path_query.path); - - // rjf: command search part is empty, but directory matches some file: - if(path_query_path_props.created != 0 && path_query.search.size == 0) - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); - } - - // rjf: command argument exactly matches some file: - else if(query_normalized_with_opt_slash_props.created != 0 && path_query.search.size != 0) - { - // rjf: is a folder -> autocomplete to slash - if(query_normalized_with_opt_slash_props.flags & FilePropertyFlag_IsFolder) - { - String8 new_path = push_str8f(scratch.arena, "%S%S/", path_query.path, path_query.search); - rd_store_view_filter(new_path); - } - - // rjf: is a file -> complete view - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query_normalized_with_opt_slash); - } - } - - // rjf: command argument is empty, picking folders -> use current folder - else if(path_query.search.size == 0 && dir_selection) - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = path_query.path); - } - - // rjf: command argument does not exactly match any file, but lister results are in: - else if(file_count != 0) - { - String8 filename = files[0].filename; - if(files[0].props.flags & FilePropertyFlag_IsFolder) - { - String8 existing_path = str8_chop_last_slash(path_query.path); - String8 new_path = push_str8f(scratch.arena, "%S/%S/", existing_path, files[0].filename); - rd_store_view_filter(new_path); - } - else - { - String8 file_path = push_str8f(scratch.arena, "%S%S", path_query.path, filename); - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file_path); - } - } - - // rjf: command argument does not match any file, and lister is empty (new file) - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = query); - } - } - - //- rjf: build non-scrolled table header - U64 row_num = 1; - F32 **col_pcts = push_array(scratch.arena, F32 *, ArrayCount(fs->col_pcts)); - for(U64 idx = 0; idx < ArrayCount(fs->col_pcts); idx += 1) - { - col_pcts[idx] = &fs->col_pcts[idx]; - } - UI_PrefHeight(ui_px(row_height_px, 1)) UI_Focus(UI_FocusKind_Off) UI_TableF(ArrayCount(fs->col_pcts), col_pcts, "###fs_tbl") - { - UI_TableVector - { - struct - { - RD_FileSortKind kind; - String8 string; - } - kinds[] = - { - { RD_FileSortKind_Filename, str8_lit_comp("Filename") }, - { RD_FileSortKind_LastModified, str8_lit_comp("Last Modified") }, - { RD_FileSortKind_Size, str8_lit_comp("Size") }, - }; - for(U64 idx = 0; idx < ArrayCount(kinds); idx += 1) - { - B32 sorting = (fs->sort_kind == kinds[idx].kind); - UI_TableCell UI_FlagsAdd(sorting ? 0 : UI_BoxFlag_DrawTextWeak) - { - UI_Signal sig = ui_sort_header(sorting, - fs->cached_files_sort_side == Side_Min, - kinds[idx].string); - if(ui_clicked(sig)) - { - if(fs->sort_kind != kinds[idx].kind) - { - fs->sort_kind = kinds[idx].kind; - fs->sort_side = Side_Max; - } - else if(fs->sort_kind == kinds[idx].kind && fs->sort_side == Side_Max) - { - fs->sort_side = Side_Min; - } - else if(fs->sort_kind == kinds[idx].kind && fs->sort_side == Side_Min) - { - fs->sort_kind = RD_FileSortKind_Null; - } - } - } - } - } - } - - //- rjf: build file list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y-row_height_px); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, file_count+1)); - scroll_list_params.item_range = r1s64(0, file_count+1); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &ps->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - // rjf: up-one-directory button (at idx 0) - if(visible_row_range.min == 0) - { - // rjf: build - UI_Signal sig = {0}; - UI_FocusHot(ps->cursor.y == row_num ? UI_FocusKind_On : UI_FocusKind_Off) - { - sig = ui_buttonf("###up_one"); - } - - // rjf: make content - UI_Parent(sig.box) - { - // rjf: icons - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[RD_IconKind_LeftArrow]); - } - - // rjf: text - { - ui_label(str8_lit("Up One Directory")); - } - - row_num += 1; - } - - // rjf: click => up one directory - if(ui_clicked(sig)) - { - String8 new_path = str8_chop_last_slash(str8_chop_last_slash(path_query.path)); - new_path = path_normalized_from_string(scratch.arena, new_path); - String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); - rd_store_view_filter(new_cmd); - } - } - - // rjf: file buttons - for(U64 row_idx = Max(visible_row_range.min, 1); - row_idx <= visible_row_range.max && row_idx <= file_count; - row_idx += 1, row_num += 1) - { - U64 file_idx = row_idx-1; - RD_FileInfo *file = &files[file_idx]; - B32 file_kb_focus = (ps->cursor.y == (row_idx+1)); - - // rjf: make button - UI_Signal file_sig = {0}; - UI_FocusHot(file_kb_focus ? UI_FocusKind_On : UI_FocusKind_Off) - { - file_sig = ui_buttonf("##%S", file->filename); - } - - // rjf: make content - UI_Parent(file_sig.box) - { - UI_PrefWidth(ui_pct(fs->col_pcts[0], 1)) UI_Row - { - // rjf: icon to signify directory - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - if(file->props.flags & FilePropertyFlag_IsFolder) - { - ui_label((ui_key_match(ui_hot_key(), file_sig.box->key) || file_kb_focus) - ? rd_icon_kind_text_table[RD_IconKind_FolderOpenFilled] - : rd_icon_kind_text_table[RD_IconKind_FolderClosedFilled]); - } - else - { - ui_label(rd_icon_kind_text_table[RD_IconKind_FileOutline]); - } - } - - // rjf: filename - UI_PrefWidth(ui_pct(1, 0)) - { - UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, file->filename); - ui_box_equip_fuzzy_match_ranges(box, &file->match_ranges); - } - } - - // rjf: last-modified time - UI_PrefWidth(ui_pct(fs->col_pcts[1], 1)) UI_Row - UI_PrefWidth(ui_pct(1, 0)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - DateTime time = date_time_from_dense_time(file->props.modified); - DateTime time_local = os_local_time_from_universal(&time); - String8 string = push_date_time_string(scratch.arena, &time_local); - ui_label(string); - } - - // rjf: file size - UI_PrefWidth(ui_pct(fs->col_pcts[2], 1)) UI_Row - UI_PrefWidth(ui_pct(1, 0)) - { - if(file->props.size != 0) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_from_memory_size(scratch.arena, file->props.size)); - } - } - } - - // rjf: click => activate this file - if(ui_clicked(file_sig)) - { - String8 existing_path = str8_chop_last_slash(path_query.path); - String8 new_path = push_str8f(scratch.arena, "%S%s%S/", existing_path, existing_path.size != 0 ? "/" : "", file->filename); - new_path = path_normalized_from_string(scratch.arena, new_path); - if(file->props.flags & FilePropertyFlag_IsFolder) - { - String8 new_cmd = push_str8f(scratch.arena, "%S%s", new_path, new_path.size != 0 ? "/" : ""); - rd_store_view_filter(new_cmd); - } - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = new_path); - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: system_processes @view_hook_impl - -typedef struct RD_ProcessInfo RD_ProcessInfo; -struct RD_ProcessInfo -{ - DMN_ProcessInfo info; - B32 is_attached; - FuzzyMatchRangeList attached_match_ranges; - FuzzyMatchRangeList name_match_ranges; - FuzzyMatchRangeList pid_match_ranges; -}; - -typedef struct RD_ProcessInfoNode RD_ProcessInfoNode; -struct RD_ProcessInfoNode -{ - RD_ProcessInfoNode *next; - RD_ProcessInfo info; -}; - -typedef struct RD_ProcessInfoList RD_ProcessInfoList; -struct RD_ProcessInfoList -{ - RD_ProcessInfoNode *first; - RD_ProcessInfoNode *last; - U64 count; -}; - -typedef struct RD_ProcessInfoArray RD_ProcessInfoArray; -struct RD_ProcessInfoArray -{ - RD_ProcessInfo *v; - U64 count; -}; - -internal RD_ProcessInfoList -rd_process_info_list_from_query(Arena *arena, String8 query) -{ - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: gather PIDs that we're currently attached to - U64 attached_process_count = 0; - U32 *attached_process_pids = 0; - { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - attached_process_count = processes.count; - attached_process_pids = push_array(scratch.arena, U32, attached_process_count); - U64 idx = 0; - for(CTRL_EntityNode *n = processes.first; n != 0; n = n->next, idx += 1) - { - CTRL_Entity *process = n->v; - attached_process_pids[idx] = process->id; - } - } - - //- rjf: build list - RD_ProcessInfoList list = {0}; - { - DMN_ProcessIter iter = {0}; - dmn_process_iter_begin(&iter); - for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) - { - // rjf: skip root-level or otherwise 0-pid processes - if(info.pid == 0) - { - continue; - } - - // rjf: determine if this process is attached - B32 is_attached = 0; - for(U64 attached_idx = 0; attached_idx < attached_process_count; attached_idx += 1) - { - if(attached_process_pids[attached_idx] == info.pid) - { - is_attached = 1; - break; - } - } - - // rjf: gather fuzzy matches - FuzzyMatchRangeList attached_match_ranges = {0}; - FuzzyMatchRangeList name_match_ranges = fuzzy_match_find(arena, query, info.name); - FuzzyMatchRangeList pid_match_ranges = fuzzy_match_find(arena, query, push_str8f(scratch.arena, "%i", info.pid)); - if(is_attached) - { - attached_match_ranges = fuzzy_match_find(arena, query, str8_lit("[attached]")); - } - - // rjf: determine if this item is filtered out - B32 matches_query = (query.size == 0 || - (attached_match_ranges.needle_part_count != 0 && attached_match_ranges.count >= attached_match_ranges.needle_part_count) || - (name_match_ranges.count != 0 && name_match_ranges.count >= name_match_ranges.needle_part_count) || - (pid_match_ranges.count != 0 && pid_match_ranges.count >= pid_match_ranges.needle_part_count)); - - // rjf: push if unfiltered - if(matches_query) - { - RD_ProcessInfoNode *n = push_array(arena, RD_ProcessInfoNode, 1); - n->info.info = info; - n->info.info.name = push_str8_copy(arena, info.name); - n->info.is_attached = is_attached; - n->info.attached_match_ranges = attached_match_ranges; - n->info.name_match_ranges = name_match_ranges; - n->info.pid_match_ranges = pid_match_ranges; - SLLQueuePush(list.first, list.last, n); - list.count += 1; - } - } - dmn_process_iter_end(&iter); - } - - scratch_end(scratch); - return list; -} - -internal RD_ProcessInfoArray -rd_process_info_array_from_list(Arena *arena, RD_ProcessInfoList list) -{ - RD_ProcessInfoArray array = {0}; - array.count = list.count; - array.v = push_array(arena, RD_ProcessInfo, array.count); - U64 idx = 0; - for(RD_ProcessInfoNode *n = list.first; n != 0; n = n->next, idx += 1) - { - array.v[idx] = n->info; - } - return array; -} - -internal int -rd_qsort_compare_process_info(RD_ProcessInfo *a, RD_ProcessInfo *b) -{ - int result = 0; - if(a->pid_match_ranges.count > b->pid_match_ranges.count) - { - result = -1; - } - else if(a->pid_match_ranges.count < b->pid_match_ranges.count) - { - result = +1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = +1; - } - else if(a->attached_match_ranges.count < b->attached_match_ranges.count) - { - result = -1; - } - else if(a->attached_match_ranges.count > b->attached_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_process_info_array_sort_by_strength__in_place(RD_ProcessInfoArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_ProcessInfo), rd_qsort_compare_process_info); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(system_processes) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - - //- rjf: grab state - typedef struct RD_SystemProcessesViewState RD_SystemProcessesViewState; - struct RD_SystemProcessesViewState - { - B32 initialized; - B32 need_initial_gather; - U32 selected_pid; - Arena *cached_process_arena; - String8 cached_process_arg; - RD_ProcessInfoArray cached_process_array; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_SystemProcessesViewState *sp = rd_view_state(RD_SystemProcessesViewState); - if(sp->initialized == 0) - { - sp->initialized = 1; - sp->need_initial_gather = 1; - sp->cached_process_arena = rd_push_view_arena(); - } - - //- rjf: gather list of filtered process infos - String8 query = string; - RD_ProcessInfoArray process_info_array = sp->cached_process_array; - if(sp->need_initial_gather || !str8_match(sp->cached_process_arg, query, 0)) - { - arena_clear(sp->cached_process_arena); - sp->need_initial_gather = 0; - sp->cached_process_arg = push_str8_copy(sp->cached_process_arena, query); - RD_ProcessInfoList list = rd_process_info_list_from_query(sp->cached_process_arena, query); - sp->cached_process_array = rd_process_info_array_from_list(sp->cached_process_arena, list); - process_info_array = sp->cached_process_array; - rd_process_info_array_sort_by_strength__in_place(process_info_array); - } - - //- rjf: submit best match when hitting enter w/ no selection - if(sp->selected_pid == 0 && process_info_array.count > 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - RD_ProcessInfo *info = &process_info_array.v[0]; - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); - } - - //- rjf: selected PID -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < process_info_array.count; idx += 1) - { - if(process_info_array.v[idx].info.pid == sp->selected_pid) - { - cursor.y = idx+1; - break; - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, process_info_array.count)); - scroll_list_params.item_range = r1s64(0, process_info_array.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - //- rjf: build rows - for(U64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < process_info_array.count; - idx += 1) - { - RD_ProcessInfo *info = &process_info_array.v[idx]; - B32 is_attached = info->is_attached; - UI_Signal sig = {0}; - UI_FocusHot(cursor.y == idx+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - sig = ui_buttonf("###proc_%i", info->info.pid); - } - UI_Parent(sig.box) - { - // rjf: icon - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[RD_IconKind_Threads]); - } - - // rjf: attached indicator - if(is_attached) UI_PrefWidth(ui_text_dim(10, 1)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - UI_Box *attached_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "[attached]##attached_label_%i", (int)info->info.pid); - ui_box_equip_fuzzy_match_ranges(attached_label, &info->attached_match_ranges); - } - - // rjf: process name - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *name_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##name_label_%i", info->info.name, (int)info->info.pid); - ui_box_equip_fuzzy_match_ranges(name_label, &info->name_match_ranges); - } - - // rjf: process number - UI_PrefWidth(ui_text_dim(1, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_TextPadding(0) - { - ui_labelf("[PID: "); - UI_Box *pid_label = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%i##pid_label", info->info.pid); - ui_box_equip_fuzzy_match_ranges(pid_label, &info->pid_match_ranges); - ui_labelf("]"); - } - } - - // rjf: click => activate this specific process - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .pid = info->info.pid); - } - } - } - - //- rjf: selected num -> selected PID - { - if(1 <= cursor.y && cursor.y <= process_info_array.count) - { - sp->selected_pid = process_info_array.v[cursor.y-1].info.pid; - } - else - { - sp->selected_pid = 0; - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: entity_lister @view_hook_impl - -typedef struct RD_EntityListerItem RD_EntityListerItem; -struct RD_EntityListerItem -{ - RD_Entity *entity; - FuzzyMatchRangeList name_match_ranges; -}; - -typedef struct RD_EntityListerItemNode RD_EntityListerItemNode; -struct RD_EntityListerItemNode -{ - RD_EntityListerItemNode *next; - RD_EntityListerItem item; -}; - -typedef struct RD_EntityListerItemList RD_EntityListerItemList; -struct RD_EntityListerItemList -{ - RD_EntityListerItemNode *first; - RD_EntityListerItemNode *last; - U64 count; -}; - -typedef struct RD_EntityListerItemArray RD_EntityListerItemArray; -struct RD_EntityListerItemArray -{ - RD_EntityListerItem *v; - U64 count; -}; - -internal RD_EntityListerItemList -rd_entity_lister_item_list_from_needle(Arena *arena, RD_EntityKind kind, RD_EntityFlags omit_flags, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_EntityListerItemList result = {0}; - RD_EntityList ent_list = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = ent_list.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(!(entity->flags & omit_flags)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, v4f32(0, 0, 0, 0), 0); - String8 title_string = dr_string_from_fancy_string_list(scratch.arena, &title_fstrs); - FuzzyMatchRangeList match_rngs = fuzzy_match_find(arena, needle, title_string); - if(match_rngs.count != 0 || needle.size == 0) - { - RD_EntityListerItemNode *item_n = push_array(arena, RD_EntityListerItemNode, 1); - item_n->item.entity = entity; - item_n->item.name_match_ranges = match_rngs; - SLLQueuePush(result.first, result.last, item_n); - result.count += 1; - } - } - } - scratch_end(scratch); - return result; -} - -internal RD_EntityListerItemArray -rd_entity_lister_item_array_from_list(Arena *arena, RD_EntityListerItemList list) -{ - RD_EntityListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_EntityListerItem, result.count); - { - U64 idx = 0; - for(RD_EntityListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - } - return result; -} - -internal int -rd_qsort_compare_entity_lister__strength(RD_EntityListerItem *a, RD_EntityListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_entity_lister_item_array_sort_by_strength__in_place(RD_EntityListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_EntityListerItem), rd_qsort_compare_entity_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(entity_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); -#if 0 // TODO(rjf): @cfg - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); -#endif - RD_EntityKind entity_kind = RD_EntityKind_Nil; // cmd_kind_info->query.entity_kind; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - - //- rjf: grab state - typedef struct RD_EntityListerViewState RD_EntityListerViewState; - struct RD_EntityListerViewState - { - RD_Handle selected_entity_handle; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_EntityListerViewState *fev = rd_view_state(RD_EntityListerViewState); - RD_Handle selected_entity_handle = fev->selected_entity_handle; - RD_Entity *selected_entity = rd_entity_from_handle(selected_entity_handle); - - //- rjf: build filtered array of entities - RD_EntityListerItemList ent_list = rd_entity_lister_item_list_from_needle(scratch.arena, entity_kind, 0, string); - RD_EntityListerItemArray ent_arr = rd_entity_lister_item_array_from_list(scratch.arena, ent_list); - rd_entity_lister_item_array_sort_by_strength__in_place(ent_arr); - - //- rjf: submit best match when hitting enter w/ no selection - if(rd_entity_is_nil(rd_entity_from_handle(fev->selected_entity_handle)) && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - RD_Entity *ent = ent_arr.v[0].entity; - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); - } - - //- rjf: selected entity -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < ent_arr.count; idx += 1) - { - if(ent_arr.v[idx].entity == selected_entity) - { - cursor.y = (S64)(idx+1); - break; - } - } - } - - //- rjf: build list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, ent_arr.count)); - scroll_list_params.item_range = r1s64(0, ent_arr.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < ent_arr.count; - idx += 1) - { - RD_EntityListerItem item = ent_arr.v[idx]; - RD_Entity *ent = item.entity; - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_FocusHot(idx+1 == cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###ent_btn_%p", ent); - } - UI_Parent(box) UI_WidthFill UI_Padding(ui_em(1.f, 1.f)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_entity(scratch.arena, ent, ui_top_palette()->text_weak, ui_top_font_size()); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &title_fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &item.name_match_ranges); - } - if(ui_clicked(ui_signal_from_box(box))) - { - rd_cmd(RD_CmdKind_CompleteQuery, .entity = rd_handle_from_entity(ent)); - } - } - } - - //- rjf: selected entity num -> handle - { - fev->selected_entity_handle = (1 <= cursor.y && cursor.y <= ent_arr.count) ? rd_handle_from_entity(ent_arr.v[cursor.y-1].entity) : rd_handle_zero(); - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: ctrl_entity_lister @view_hook_impl - -typedef struct RD_CtrlEntityListerItem RD_CtrlEntityListerItem; -struct RD_CtrlEntityListerItem -{ - CTRL_Entity *entity; - FuzzyMatchRangeList name_match_ranges; -}; - -typedef struct RD_CtrlEntityListerItemNode RD_CtrlEntityListerItemNode; -struct RD_CtrlEntityListerItemNode -{ - RD_CtrlEntityListerItemNode *next; - RD_CtrlEntityListerItem item; -}; - -typedef struct RD_CtrlEntityListerItemList RD_CtrlEntityListerItemList; -struct RD_CtrlEntityListerItemList -{ - RD_CtrlEntityListerItemNode *first; - RD_CtrlEntityListerItemNode *last; - U64 count; -}; - -typedef struct RD_CtrlEntityListerItemArray RD_CtrlEntityListerItemArray; -struct RD_CtrlEntityListerItemArray -{ - RD_CtrlEntityListerItem *v; - U64 count; -}; - -internal RD_CtrlEntityListerItemList -rd_ctrl_entity_lister_item_list_from_needle(Arena *arena, CTRL_EntityKind kind, String8 needle) -{ - Temp scratch = scratch_begin(&arena, 1); - RD_CtrlEntityListerItemList result = {0}; - CTRL_EntityList ent_list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - for(CTRL_EntityNode *n = ent_list.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - DR_FancyStringList title_fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, v4f32(0, 0, 0, 0), 0, 0); - String8 title_fstrs_text = dr_string_from_fancy_string_list(scratch.arena, &title_fstrs); - FuzzyMatchRangeList match_rngs = fuzzy_match_find(arena, needle, title_fstrs_text); - if(match_rngs.count == match_rngs.needle_part_count || needle.size == 0) - { - RD_CtrlEntityListerItemNode *item_n = push_array(arena, RD_CtrlEntityListerItemNode, 1); - item_n->item.entity = entity; - item_n->item.name_match_ranges = match_rngs; - SLLQueuePush(result.first, result.last, item_n); - result.count += 1; - } - } - scratch_end(scratch); - return result; -} - -internal RD_CtrlEntityListerItemArray -rd_ctrl_entity_lister_item_array_from_list(Arena *arena, RD_CtrlEntityListerItemList list) -{ - RD_CtrlEntityListerItemArray result = {0}; - result.count = list.count; - result.v = push_array(arena, RD_CtrlEntityListerItem, result.count); - { - U64 idx = 0; - for(RD_CtrlEntityListerItemNode *n = list.first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->item; - } - } - return result; -} - -internal int -rd_qsort_compare_ctrl_entity_lister__strength(RD_CtrlEntityListerItem *a, RD_CtrlEntityListerItem *b) -{ - int result = 0; - if(a->name_match_ranges.count > b->name_match_ranges.count) - { - result = -1; - } - else if(a->name_match_ranges.count < b->name_match_ranges.count) - { - result = +1; - } - return result; -} - -internal void -rd_ctrl_entity_lister_item_array_sort_by_strength__in_place(RD_CtrlEntityListerItemArray array) -{ - quick_sort(array.v, array.count, sizeof(RD_CtrlEntityListerItem), rd_qsort_compare_ctrl_entity_lister__strength); -} - -RD_VIEW_RULE_UI_FUNCTION_DEF(ctrl_entity_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); -#if 0 // TODO(rjf): @cfg - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(window->query_cmd_name); -#endif - CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; // cmd_kind_info->query.ctrl_entity_kind; - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - - //- rjf: grab state - typedef struct RD_CtrlEntityListerViewState RD_CtrlEntityListerViewState; - struct RD_CtrlEntityListerViewState - { - CTRL_Handle selected_entity_handle; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_CtrlEntityListerViewState *fev = rd_view_state(RD_CtrlEntityListerViewState); - CTRL_Handle selected_entity_handle = fev->selected_entity_handle; - CTRL_Entity *selected_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, selected_entity_handle); - - //- rjf: build filtered array of entities - RD_CtrlEntityListerItemList ent_list = rd_ctrl_entity_lister_item_list_from_needle(scratch.arena, entity_kind, string); - RD_CtrlEntityListerItemArray ent_arr = rd_ctrl_entity_lister_item_array_from_list(scratch.arena, ent_list); - rd_ctrl_entity_lister_item_array_sort_by_strength__in_place(ent_arr); - - //- rjf: submit best match when hitting enter w/ no selection - if(ctrl_entity_from_handle(d_state->ctrl_entity_store, fev->selected_entity_handle) == &ctrl_entity_nil && ent_arr.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - CTRL_Entity *ent = ent_arr.v[0].entity; - RD_RegsScope() - { - switch(ent->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{rd_regs()->machine = ent->handle;}break; - case CTRL_EntityKind_Process:{rd_regs()->process = ent->handle;}break; - case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; - case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; - } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); - } - } - - //- rjf: selected entity -> cursor - Vec2S64 cursor = {0}; - { - for(U64 idx = 0; idx < ent_arr.count; idx += 1) - { - if(ent_arr.v[idx].entity == selected_entity) - { - cursor.y = (S64)(idx+1); - break; - } - } - } - - //- rjf: build list - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, ent_arr.count)); - scroll_list_params.item_range = r1s64(0, ent_arr.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < ent_arr.count; - idx += 1) - { - RD_CtrlEntityListerItem item = ent_arr.v[idx]; - CTRL_Entity *ent = item.entity; - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *box = &ui_nil_box; - UI_FocusHot(idx+1 == cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) - { - box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###ent_btn_%p", ent); - } - UI_Parent(box) UI_WidthFill UI_Padding(ui_em(1.f, 1.f)) - { - DR_FancyStringList title_fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ent, ui_top_palette()->text_weak, ui_top_font_size(), 1); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &title_fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &item.name_match_ranges); - } - if(ui_clicked(ui_signal_from_box(box))) - { - RD_RegsScope() - { - switch(ent->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{rd_regs()->machine = ent->handle;}break; - case CTRL_EntityKind_Process:{rd_regs()->process = ent->handle;}break; - case CTRL_EntityKind_Thread: {rd_regs()->thread = ent->handle;}break; - case CTRL_EntityKind_Module: {rd_regs()->module = ent->handle;}break; - } - rd_cmd(RD_CmdKind_CompleteQuery, .ctrl_entity = ent->handle); - } - } - } - } - - //- rjf: selected entity num -> handle - { - fev->selected_entity_handle = (1 <= cursor.y && cursor.y <= ent_arr.count) ? (ent_arr.v[cursor.y-1].entity->handle) : ctrl_handle_zero(); - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: symbol_lister @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - 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); - DI_SearchParams search_params = {RDI_SectionKind_Procedures, dbgi_keys}; - U64 endt_us = os_now_microseconds()+200; - - //- rjf: grab rdis - 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) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], endt_us); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: grab state - typedef struct RD_SymbolListerViewState RD_SymbolListerViewState; - struct RD_SymbolListerViewState - { - Vec2S64 cursor; - }; - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - RD_SymbolListerViewState *slv = rd_view_state(RD_SymbolListerViewState); - - //- rjf: query -> raddbg, filtered items - U128 search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]}; - B32 items_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, string, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - - //- rjf: submit best match when hitting enter w/ no selection - if(slv->cursor.y == 0 && items.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) - { - DI_SearchItem *item = &items.v[0]; - if(item->dbgi_idx < rdis_count) - { - RDI_Parsed *rdi = rdis[item->dbgi_idx]; - U64 rdi_procedures_count = 0; - rdi_section_raw_table_from_kind(rdi, RDI_SectionKind_Procedures, &rdi_procedures_count); - if(item->idx < rdi_procedures_count) - { - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); - U64 name_size = 0; - U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 name = str8(name_base, name_size); - if(name.size != 0) - { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); - } - } - } - } - - //- rjf: build contents - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 content_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, items.count)); - scroll_list_params.item_range = r1s64(0, items.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &slv->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Code)) - { - //- rjf: build rows - for(U64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < items.count; - idx += 1) - UI_Focus((slv->cursor.y == idx+1) ? UI_FocusKind_On : UI_FocusKind_Off) - { - DI_SearchItem *item = &items.v[idx]; - if(item->dbgi_idx >= rdis_count) {continue;} - DI_Key dbgi_key = dbgi_keys.v[item->dbgi_idx]; - RDI_Parsed *rdi = rdis[item->dbgi_idx]; - - //- rjf: unpack this item's info - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); - U64 name_size = 0; - U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 name = str8(name_base, name_size); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - - //- rjf: build item button - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###procedure_%I64x", item->idx); - UI_Parent(box) UI_PrefWidth(ui_text_dim(10, 1)) RD_Font(RD_FontSlot_Code) - { - UI_Box *box = rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - ui_box_equip_fuzzy_match_ranges(box, &item->match_ranges); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - String8 type_string = e_type_string_from_key(scratch.arena, type_key); - rd_code_label(0.5f, 0, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), type_string); - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_CompleteQuery, .string = name); - } - if(ui_hovering(sig)) UI_Tooltip - { - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_labelf("Procedure #%I64u", idx); - U64 binary_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, name); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, binary_voff); - if(lines.first != 0 && lines.first->v.file_path.size != 0 && lines.first->v.pt.line != 0) - { - String8 file_path = lines.first->v.file_path; - S64 line_num = lines.first->v.pt.line; - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_labelf("%S:%I64d", file_path, line_num); - } - else - { - RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(str8_lit("(No source code location found)")); - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - di_scope_close(di_scope); - scratch_end(scratch); - ProfEnd(); -} - //////////////////////////////// //~ rjf: targets @view_hook_impl diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2d11258e..ce58c58e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1016,13 +1016,13 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: shift+click => enable breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags & OS_Modifier_Shift) { - rd_cmd(bp_is_disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .cfg = rd_handle_from_cfg(bp)); + rd_cmd(bp_is_disabled ? RD_CmdKind_EnableCfg : RD_CmdKind_DisableCfg, .cfg = rd_handle_from_cfg(bp)); } // rjf: click => remove breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags == 0) { - rd_cmd(RD_CmdKind_RemoveEntity, .cfg = rd_handle_from_cfg(bp)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = rd_handle_from_cfg(bp)); } // rjf: drag start @@ -1077,7 +1077,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: click => remove pin if(ui_clicked(pin_sig)) { - rd_cmd(RD_CmdKind_RemoveEntity, .cfg = rd_handle_from_cfg(pin)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = rd_handle_from_cfg(pin)); } // rjf: drag start @@ -1403,7 +1403,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); B32 line_drag_drop = 0; - RD_Entity *line_drag_entity = &rd_nil_entity; + RD_Cfg *line_drag_cfg = &rd_nil_cfg; CTRL_Entity *line_drag_ctrl_entity = &ctrl_entity_nil; Vec4F32 line_drag_drop_color = rd_rgba_from_theme_color(RD_ThemeColor_DropSiteOverlay); { @@ -1479,17 +1479,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(rd_drag_is_active() && contains_2f32(clipped_top_container_rect, ui_mouse())) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); - RD_Entity *entity = rd_entity_from_handle(rd_state->drag_drop_regs->entity); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Entity && - (entity->kind == RD_EntityKind_WatchPin || - entity->kind == RD_EntityKind_Breakpoint)) + RD_Cfg *cfg = rd_cfg_from_handle(rd_state->drag_drop_regs->cfg); + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && + (str8_match(cfg->string, str8_lit("breakpoint"), 0) || + str8_match(cfg->string, str8_lit("watch_pin"), 0))) { line_drag_drop = 1; - line_drag_entity = entity; - if(entity->flags & RD_EntityFlag_HasColor) + line_drag_cfg = cfg; + line_drag_drop_color = rd_rgba_from_cfg(cfg); + line_drag_drop_color.w *= 0.5f; + if(line_drag_drop_color.w == 0) { - line_drag_drop_color = rd_rgba_from_entity(entity); - line_drag_drop_color.w *= 0.5f; + line_drag_drop_color = rd_rgba_from_theme_color(RD_ThemeColor_DropSiteOverlay); } } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) @@ -1503,14 +1504,14 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: drop target is dropped -> process { - if(!rd_entity_is_nil(line_drag_entity) && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) + if(line_drag_cfg != &rd_nil_cfg && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) { - RD_Entity *dropped_entity = line_drag_entity; + RD_Cfg *dropped_cfg = line_drag_cfg; S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; U64 line_vaddr = params->line_vaddrs[line_idx]; - rd_cmd(RD_CmdKind_RelocateEntity, - .entity = rd_handle_from_entity(dropped_entity), + rd_cmd(RD_CmdKind_RelocateCfg, + .cfg = rd_handle_from_cfg(dropped_cfg), .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); From 7443f330698b3e7b79f7f8d0e986ea15dd7e63f6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 22 Jan 2025 09:40:57 -0800 Subject: [PATCH 018/755] sketch out schemas for configuration trees --- src/raddbg/generated/raddbg.meta.c | 13 ++++++++++++- src/raddbg/generated/raddbg.meta.h | 10 +++++++++- src/raddbg/raddbg.mdesk | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 75dea353..b9eabc32 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -36,7 +36,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[39] = +RD_VocabularyInfo rd_vocabulary_info_table[41] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -67,6 +67,7 @@ RD_VocabularyInfo rd_vocabulary_info_table[39] = {str8_lit_comp("lang"), str8_lit_comp("langs"), str8_lit_comp("Language"), str8_lit_comp("Languages"), RD_IconKind_Null}, {str8_lit_comp("arch"), str8_lit_comp("archs"), str8_lit_comp("Architecture"), str8_lit_comp("Architectures"), RD_IconKind_Null}, {str8_lit_comp("expr"), str8_lit_comp("exprs"), str8_lit_comp("Expression"), str8_lit_comp("Expressions"), RD_IconKind_Null}, +{str8_lit_comp("expression"), str8_lit_comp("expressions"), str8_lit_comp("Expression"), str8_lit_comp("Expressions"), RD_IconKind_Null}, {str8_lit_comp("size"), str8_lit_comp("sizes"), str8_lit_comp("Size"), str8_lit_comp("Sizes"), RD_IconKind_Null}, {str8_lit_comp("count"), str8_lit_comp("counts"), str8_lit_comp("Count"), str8_lit_comp("Counts"), RD_IconKind_Null}, {str8_lit_comp("bool"), str8_lit_comp("bools"), str8_lit_comp("Boolean"), str8_lit_comp("Booleans"), RD_IconKind_Null}, @@ -77,6 +78,16 @@ RD_VocabularyInfo rd_vocabulary_info_table[39] = {str8_lit_comp("code_bytes"), str8_lit_comp("code_bytes"), str8_lit_comp("Code Bytes"), str8_lit_comp("Code Bytes"), RD_IconKind_Null}, {str8_lit_comp("vtx"), str8_lit_comp("vtxs"), str8_lit_comp("Vertex Buffer"), str8_lit_comp("Vertex Buffers"), RD_IconKind_Null}, {str8_lit_comp("vtx_size"), str8_lit_comp("vtx_sizes"), str8_lit_comp("Vertex Buffer Size"), str8_lit_comp("Vertex Buffer Sizes"), RD_IconKind_Null}, +{str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, +}; + +RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5] = +{ +{str8_lit_comp("target"), str8_lit_comp("x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("x:{'expression':code_string, 'view_rule':code_string, 'location':location}")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}")}, }; String8 d_entity_kind_display_string_table[27] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b1e7a936..b9cc15ed 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -550,6 +550,13 @@ String8 display_name_plural; RD_IconKind icon_kind; }; +typedef struct RD_CfgNameSchemaPair RD_CfgNameSchemaPair; +struct RD_CfgNameSchemaPair +{ +String8 name; +String8 schema; +}; + typedef struct RD_Regs RD_Regs; struct RD_Regs { @@ -779,7 +786,8 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_apply_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[39]; +extern RD_VocabularyInfo rd_vocabulary_info_table[41]; +extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a41ca1a1..bf18be82 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -85,6 +85,7 @@ RD_VocabularyMap: {lang _ "Language" _ Null } {arch _ "Architecture" _ Null } {expr _ "Expression" _ Null } + {expression _ "Expression" _ Null } {size _ "Size" _ Null } {count _ "Count" _ Null } {bool _ "Boolean" _ Null } @@ -95,6 +96,7 @@ RD_VocabularyMap: {code_bytes code_bytes "Code Bytes" "Code Bytes" Null } {vtx _ "Vertex Buffer" _ Null } {vtx_size _ "Vertex Buffer Size" _ Null } + {label _ "Label" _ Null } } @struct RD_VocabularyInfo: @@ -111,6 +113,29 @@ RD_VocabularyMap: @expand(RD_VocabularyMap a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; } +//////////////////////////////// +//~ rjf: Configuration Tree Schemas + +@table(name schema) RD_CfgSchemaTable: +{ + {target "x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}"} + {breakpoint "x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}"} + {watch_pin "x:{'expression':code_string, 'view_rule':code_string, 'location':location}"} + {file_path_map "x:{'source':path, 'dest':path}"} + {auto_view_rule "x:{'source':code_string, 'dest':code_string}"} +} + +@struct RD_CfgNameSchemaPair: +{ + `String8 name`; + `String8 schema`; +} + +@data(RD_CfgNameSchemaPair) rd_cfg_name_schema_pair_table: +{ + @expand(RD_CfgSchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)")}` +} + //////////////////////////////// //~ rjf: Entity Kind Tables From 443fee10ec30dfb8eddfcec14e95650955dc7edf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 22 Jan 2025 09:57:40 -0800 Subject: [PATCH 019/755] more entity code deletion --- src/raddbg/raddbg_core.c | 15 --------------- src/raddbg/raddbg_core.h | 1 - src/raddbg/raddbg_views.c | 15 ++++++++------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5e8ef63e..1523a494 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11467,21 +11467,6 @@ rd_query_cached_entity_list_with_kind(RD_EntityKind kind) return result; } -internal RD_EntityList -rd_push_active_target_list(Arena *arena) -{ - RD_EntityList active_targets = {0}; - RD_EntityList all_targets = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); - for(RD_EntityNode *n = all_targets.first; n != 0; n = n->next) - { - if(!n->entity->disabled) - { - rd_entity_list_push(arena, &active_targets, n->entity); - } - } - return active_targets; -} - //- rjf: config state internal RD_CfgTable * diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index fc8e2169..460e58d3 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1419,7 +1419,6 @@ internal String8 rd_cfg_path_from_src(RD_CfgSrc src); //- rjf: entity cache queries internal RD_EntityList rd_query_cached_entity_list_with_kind(RD_EntityKind kind); -internal RD_EntityList rd_push_active_target_list(Arena *arena); //- rjf: config state internal RD_CfgTable *rd_cfg_table(void); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2ab0280b..dd7a4025 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3485,7 +3485,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) { - RD_EntityList targets = rd_push_active_target_list(scratch.arena); + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); //- rjf: icon & info @@ -3543,8 +3543,9 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) //- rjf: user has 1 target. build helper for launching it case 1: { - RD_Entity *target = rd_first_entity_from_list(&targets); - String8 target_full_path = target->string; + RD_Cfg *target_cfg = rd_cfg_list_first(&targets); + D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); + String8 target_full_path = target.exe; String8 target_name = str8_skip_last_slash(target_full_path); UI_PrefHeight(ui_em(3.75f, 1.f)) UI_Row @@ -3556,12 +3557,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) { - rd_cmd(RD_CmdKind_LaunchAndRun, .entity = rd_handle_from_entity(target)); + rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = rd_handle_from_cfg(target_cfg)); } ui_spacer(ui_em(1.5f, 1)); if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) { - rd_cmd(RD_CmdKind_LaunchAndInit, .entity = rd_handle_from_entity(target)); + rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = rd_handle_from_cfg(target_cfg)); } } }break; @@ -3593,8 +3594,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) RD_Palette(RD_PaletteCode_Floating) { ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_RunCommand].string); - ui_labelf("to open command menu"); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + ui_labelf("to open the lister for commands and options"); } } scratch_end(scratch); From 9a54ae50c1703330c90dfd61231323f5615da495 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 22 Jan 2025 14:23:39 -0800 Subject: [PATCH 020/755] old config code elimination --- src/raddbg/generated/raddbg.meta.c | 16 +- src/raddbg/generated/raddbg.meta.h | 8 +- src/raddbg/raddbg.mdesk | 11 - src/raddbg/raddbg_core.c | 1281 ++++++++-------------------- src/raddbg/raddbg_core.h | 149 ++-- src/raddbg/raddbg_views.c | 140 +-- 6 files changed, 413 insertions(+), 1192 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b9eabc32..c628a0ff 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,14 +28,6 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_CmdKind rd_cfg_src_apply_cmd_kind_table[4] = -{ -RD_CmdKind_ApplyUserData, -RD_CmdKind_ApplyProjectData, -RD_CmdKind_Null, -RD_CmdKind_Null, -}; - RD_VocabularyInfo rd_vocabulary_info_table[41] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, @@ -289,7 +281,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[216] = +RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, @@ -385,8 +377,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[216] = { str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Apply User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, @@ -497,7 +487,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[216] = { str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exception_filters"), str8_lit_comp("Opens the exception filters view."), str8_lit_comp("exceptions,filters"), str8_lit_comp(""), str8_lit_comp("Exception Filters"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, @@ -874,12 +863,11 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(procedures), }; -RD_ViewRuleInfo rd_view_rule_kind_info_table[29] = +RD_ViewRuleInfo rd_view_rule_kind_info_table[28] = { {{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, {str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, {str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(getting_started)}, -{str8_lit_comp("exception_filters"), str8_lit_comp("An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time."), str8_lit_comp("Exception Filters"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(exception_filters)}, {str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, {str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, {str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b9cc15ed..ca29430a 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -188,8 +188,6 @@ RD_CmdKind_SetFileReplacementPath, RD_CmdKind_OpenUser, RD_CmdKind_OpenProject, RD_CmdKind_OpenRecentProject, -RD_CmdKind_ApplyUserData, -RD_CmdKind_ApplyProjectData, RD_CmdKind_WriteUserData, RD_CmdKind_WriteProjectData, RD_CmdKind_Edit, @@ -300,7 +298,6 @@ RD_CmdKind_PendingFile, RD_CmdKind_Disassembly, RD_CmdKind_Output, RD_CmdKind_Memory, -RD_CmdKind_ExceptionFilters, RD_CmdKind_Settings, RD_CmdKind_PickFile, RD_CmdKind_PickFolder, @@ -392,7 +389,6 @@ typedef enum RD_ViewRuleKind RD_ViewRuleKind_Null, RD_ViewRuleKind_Empty, RD_ViewRuleKind_GettingStarted, -RD_ViewRuleKind_ExceptionFilters, RD_ViewRuleKind_Settings, RD_ViewRuleKind_PendingFile, RD_ViewRuleKind_Watch, @@ -755,7 +751,6 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d); RD_VIEW_RULE_UI_FUNCTION_DEF(empty); RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); -RD_VIEW_RULE_UI_FUNCTION_DEF(exception_filters); RD_VIEW_RULE_UI_FUNCTION_DEF(settings); RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file); RD_VIEW_RULE_UI_FUNCTION_DEF(watch); @@ -785,7 +780,6 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_CmdKind rd_cfg_src_apply_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[41]; extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5]; extern String8 d_entity_kind_display_string_table[27]; @@ -805,7 +799,7 @@ extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_inf extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18]; extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18]; extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18]; -extern RD_ViewRuleInfo rd_view_rule_kind_info_table[29]; +extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index bf18be82..747cb0e7 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -43,11 +43,6 @@ RD_CfgSrcTable: @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.write_cmd)`, } -@data(RD_CmdKind) rd_cfg_src_apply_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.apply_cmd)`; -} - //////////////////////////////// //~ rjf: Vocabulary Maps @@ -419,10 +414,6 @@ RD_CmdTable: // | | | | {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } {OpenRecentProject 1 1 Entity null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } - //- rjf: loading/applying stateful config changes - {ApplyUserData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" "" } - {ApplyProjectData 0 0 Null null Nil Null 0 0 0 0 0 0 Null "apply_project_data" "Apply Project Data" "Applies project data from the active project file." "" "" } - //- rjf: writing config changes {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } {WriteProjectData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } @@ -568,7 +559,6 @@ RD_CmdTable: // | | | | {Disassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } {Output 1 1 Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } {Memory 1 1 Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } - {ExceptionFilters 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "exception_filters" "Exception Filters" "Opens the exception filters view." "exceptions,filters" "" } {Settings 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries @@ -999,7 +989,6 @@ RD_ViewRuleTable: { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } //- rjf: meta (settings) - { ExceptionFilters exception_filters "Exception Filters" "" Gear 0 0 0 0 0 0 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } //- rjf: temporary view for loading files - must analyze file before picking viewer diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1523a494..ac7f2240 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1150,7 +1150,7 @@ internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg) { RD_Cfg *project = rd_cfg_child_from_string(cfg, str8_lit("project")); - B32 result = path_match_normalized(rd_state->cfg_paths[RD_CfgSrc_Project], project->first->string); + B32 result = path_match_normalized(rd_state->project_path, project->first->string); return result; } @@ -2262,6 +2262,30 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon //////////////////////////////// //~ rjf: Evaluation Spaces +//- rjf: cfg <-> eval space + +internal RD_Cfg * +rd_cfg_from_eval_space(E_Space space) +{ + RD_Cfg *cfg = &rd_nil_cfg; + if(space.kind == RD_EvalSpaceKind_MetaCfg) + { + RD_Handle handle = {space.u64s[0], space.u64s[1]}; + cfg = rd_cfg_from_handle(handle); + } + return cfg; +} + +internal E_Space +rd_eval_space_from_cfg(RD_Cfg *cfg) +{ + E_Space space = e_space_make(RD_EvalSpaceKind_MetaCfg); + RD_Handle handle = rd_handle_from_cfg(cfg); + space.u64s[0] = handle.u64[0]; + space.u64s[1] = handle.u64[1]; + return space; +} + //- rjf: entity <-> eval space internal RD_Entity * @@ -3537,7 +3561,7 @@ rd_window_frame(void) //- rjf: compute ui palettes from theme // { - RD_Theme *current = &rd_state->cfg_theme; + RD_Theme *current = rd_state->theme; for EachEnumVal(RD_PaletteCode, code) { ws->cfg_palettes[code].null = v4f32(1, 0, 1, 1); @@ -5482,7 +5506,6 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, rd_cmd_kind_info_table[RD_CmdKind_Settings].string, - rd_cmd_kind_info_table[RD_CmdKind_ExceptionFilters].string, rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, }; U32 codepoints[] = @@ -5505,7 +5528,6 @@ rd_window_frame(void) 'h', 'p', 'v', - 'e', 'g', 0, }; @@ -5991,7 +6013,7 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, user_box->rect); UI_Parent(user_box) UI_PrefWidth(ui_text_dim(10, 0)) UI_TextAlignment(UI_TextAlign_Center) { - String8 user_path = rd_cfg_path_from_src(RD_CfgSrc_User); + String8 user_path = rd_state->user_path; user_path = str8_chop_last_dot(user_path); RD_Font(RD_FontSlot_Icons) UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Icons)) @@ -6025,7 +6047,7 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, prof_box->rect); UI_Parent(prof_box) UI_PrefWidth(ui_text_dim(10, 0)) UI_TextAlignment(UI_TextAlign_Center) { - String8 prof_path = rd_cfg_path_from_src(RD_CfgSrc_Project); + String8 prof_path = rd_state->project_path; prof_path = str8_chop_last_dot(prof_path); RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_Briefcase]); @@ -10461,7 +10483,7 @@ rd_push_search_string(Arena *arena) internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color) { - return rd_state->cfg_theme.colors[color]; + return rd_state->theme->colors[color]; } internal RD_ThemeColor @@ -10599,7 +10621,51 @@ rd_palette_from_code(RD_PaletteCode code) internal FNT_Tag rd_font_from_slot(RD_FontSlot slot) { - FNT_Tag result = rd_state->cfg_font_tags[slot]; + // rjf: determine key name for this font slot + String8 key = {0}; + switch(slot) + { + default:{}break; + case RD_FontSlot_Main:{key = str8_lit("main_font");}break; + case RD_FontSlot_Code:{key = str8_lit("code_font");}break; + } + + // rjf: determine font name + String8 font_name = {0}; + if(key.size != 0) + { + RD_Cfg *seed_cfg = &rd_nil_cfg; + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->view); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->panel); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->window); } + for(RD_Cfg *cfg = seed_cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) + { + RD_Cfg *font_root = rd_cfg_child_from_string(cfg, key); + if(font_root != &rd_nil_cfg) + { + font_name = font_root->first->string; + break; + } + } + } + + // rjf: map name -> tag + FNT_Tag result = {0}; + if(font_name.size == 0) + { + switch(slot) + { + default: + case RD_FontSlot_Main: {result = fnt_tag_from_static_data_string(&rd_default_main_font_bytes);}break; + case RD_FontSlot_Code: {result = fnt_tag_from_static_data_string(&rd_default_code_font_bytes);}break; + case RD_FontSlot_Icons:{result = fnt_tag_from_static_data_string(&rd_icon_font_bytes);}break; + } + } + else + { + // TODO(rjf): need to handle "system font names" here. + result = fnt_tag_from_path(font_name); + } return result; } @@ -11433,14 +11499,6 @@ rd_frame_arena(void) return rd_state->frame_arenas[rd_state->frame_index%ArrayCount(rd_state->frame_arenas)]; } -//- rjf: config paths - -internal String8 -rd_cfg_path_from_src(RD_CfgSrc src) -{ - return rd_state->cfg_paths[src]; -} - //- rjf: entity cache queries internal RD_EntityList @@ -11467,14 +11525,6 @@ rd_query_cached_entity_list_with_kind(RD_EntityKind kind) return result; } -//- rjf: config state - -internal RD_CfgTable * -rd_cfg_table(void) -{ - return &rd_state->cfg_table; -} - //////////////////////////////// //~ rjf: Registers @@ -11682,6 +11732,8 @@ rd_init(CmdLine *cmdln) rd_state->arena = arena; rd_state->quit_after_success = (cmd_line_has_flag(cmdln, str8_lit("quit_after_success")) || cmd_line_has_flag(cmdln, str8_lit("q"))); + rd_state->user_path_arena = arena_alloc(); + rd_state->project_path_arena = arena_alloc(); for(U64 idx = 0; idx < ArrayCount(rd_state->frame_arenas); idx += 1) { rd_state->frame_arenas[idx] = arena_alloc(); @@ -11715,8 +11767,6 @@ rd_init(CmdLine *cmdln) rd_state->string_search_arena = arena_alloc(); rd_state->eval_viz_view_cache_slots_count = 1024; rd_state->eval_viz_view_cache_slots = push_array(arena, RD_EvalVizViewCacheSlot, rd_state->eval_viz_view_cache_slots_count); - rd_state->cfg_main_font_path_arena = arena_alloc(); - rd_state->cfg_code_font_path_arena = arena_alloc(); rd_state->bind_change_arena = arena_alloc(); rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); @@ -11749,48 +11799,29 @@ rd_init(CmdLine *cmdln) Temp scratch = scratch_begin(0, 0); // rjf: unpack command line arguments - String8 user_cfg_path = cmd_line_string(cmdln, str8_lit("user")); - String8 project_cfg_path = cmd_line_string(cmdln, str8_lit("project")); - if(project_cfg_path.size == 0) - { - project_cfg_path = cmd_line_string(cmdln, str8_lit("profile")); - } + String8 user_path = cmd_line_string(cmdln, str8_lit("user")); + String8 project_path = cmd_line_string(cmdln, str8_lit("project")); { String8 user_program_data_path = os_get_process_info()->user_program_data_path; String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); os_make_directory(user_data_folder); - if(user_cfg_path.size == 0) + if(user_path.size == 0) { - user_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); + user_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } - if(project_cfg_path.size == 0) + if(project_path.size == 0) { - project_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); + project_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); } } - // rjf: set up config path state - String8 cfg_src_paths[RD_CfgSrc_COUNT] = {user_cfg_path, project_cfg_path}; - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - rd_state->cfg_path_arenas[src] = arena_alloc(); - rd_cmd(rd_cfg_src_load_cmd_kind_table[src], .file_path = path_normalized_from_string(scratch.arena, cfg_src_paths[src])); - } + // rjf: do initial load + rd_cmd(RD_CmdKind_OpenUser, .file_path = user_path); + rd_cmd(RD_CmdKind_OpenProject, .file_path = project_path); - // rjf: set up config table arena - rd_state->cfg_arena = arena_alloc(); scratch_end(scratch); } - // rjf: set up initial exception filtering rules - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) - { - if(ctrl_exception_code_kind_default_enable_table[k]) - { - rd_state->ctrl_exception_code_filters[k/64] |= 1ull<<(k%64); - } - } - // rjf: unpack icon image data { Temp scratch = scratch_begin(0, 0); @@ -12146,7 +12177,6 @@ rd_frame(void) rd_request_frame(); // TODO(rjf): @cfg_bindchange rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); rd_state->bind_change_active = 0; - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); } for(OS_Event *event = events.first, *next = 0; event != 0; event = next) { @@ -12173,7 +12203,6 @@ rd_frame(void) U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); os_text(&events, event->window, codepoint); os_eat_event(&events, event); - rd_cmd(rd_cfg_src_write_cmd_kind_table[RD_CfgSrc_User]); rd_request_frame(); break; } @@ -12183,6 +12212,7 @@ rd_frame(void) ////////////////////////////// //- rjf: build key map from config // + ProfScope("build key map from config") { //- rjf: set up table rd_state->key_map = push_array(rd_frame_arena(), RD_KeyMap, 1); @@ -12251,9 +12281,11 @@ rd_frame(void) } } - //- rjf: iterate all commands - if they are not found in the map, then use - // the default binding. + //- rjf: iterate default bindings - if their commands are not found in the + // map, then use the default binding. + // // TODO(rjf): @dynamic_cmds + // for EachElement(idx, rd_default_binding_table) { String8 name = rd_default_binding_table[idx].string; @@ -12283,6 +12315,110 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: build theme from config + // + ProfScope("build theme from config") + { + rd_state->theme_target = push_array(rd_frame_arena(), RD_Theme, 1); + RD_Theme *theme = rd_state->theme_target; + + //- rjf: gather globally-applying config options + RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("color_preset")); + RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("colors")); + + //- rjf: assume default-dark + MemoryCopy(theme->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); + + //- rjf: apply explicitly-specified presets + for(RD_CfgNode *n = preset_roots.first; n != 0; n = n->next) + { + RD_Cfg *preset = n->v; + String8 preset_name = preset->first->string; + RD_ThemePreset preset_kind = (RD_ThemePreset)0; + B32 found_preset_kind = 0; + for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) + { + if(str8_match(preset_name, rd_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) + { + found_preset_kind = 1; + preset_kind = p; + break; + } + } + if(found_preset_kind) + { + MemoryCopy(theme->colors, rd_theme_preset_colors_table[preset_kind], sizeof(rd_theme_preset_colors__default_dark)); + } + } + + //- rjf: apply explicitly-specified color codes + for(RD_CfgNode *n = colors_roots.first; n != 0; n = n->next) + { + RD_Cfg *colors = n->v; + for(RD_Cfg *color = colors->first; color != &rd_nil_cfg; color = color->next) + { + String8 name = color->string; + RD_ThemeColor color_code = RD_ThemeColor_Null; + for(RD_ThemeColor c = RD_ThemeColor_Null; c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) + { + if(str8_match(rd_theme_color_cfg_string_table[c], name, StringMatchFlag_CaseInsensitive)) + { + color_code = c; + break; + } + } + if(color_code != RD_ThemeColor_Null) + { + U64 color_val = 0; + if(try_u64_from_str8_c_rules(color->first->string, &color_val)) + { + Vec4F32 color_rgba = rgba_from_u32((U32)color_val); + theme->colors[color_code] = color_rgba; + } + } + } + } + } + + ////////////////////////////// + //- rjf: animate theme + // + { + RD_Theme *last = rd_state->theme; + rd_state->theme = push_array(rd_frame_arena(), RD_Theme, 1); + RD_Theme *current = rd_state->theme; + RD_Theme *target = rd_state->theme_target; + if(last) + { + MemoryCopyStruct(current, last); + } + if(rd_state->frame_index <= 2) + { + MemoryCopyStruct(current, target); + } + else + { + F32 rate = 1 - pow_f32(2, (-50.f * rd_state->frame_dt)); + for(RD_ThemeColor color = RD_ThemeColor_Null; + color < RD_ThemeColor_COUNT; + color = (RD_ThemeColor)(color+1)) + { + if(abs_f32(target->colors[color].x - current->colors[color].x) > 0.01f || + abs_f32(target->colors[color].y - current->colors[color].y) > 0.01f || + abs_f32(target->colors[color].z - current->colors[color].z) > 0.01f || + abs_f32(target->colors[color].w - current->colors[color].w) > 0.01f) + { + rd_request_frame(); + } + current->colors[color].x += (target->colors[color].x - current->colors[color].x) * rate; + current->colors[color].y += (target->colors[color].y - current->colors[color].y) * rate; + current->colors[color].z += (target->colors[color].z - current->colors[color].z) * rate; + current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; + } + } + } + ////////////////////////////// //- rjf: consume events // @@ -12528,7 +12664,39 @@ rd_frame(void) } } + //- rjf: add macros for evallable config trees + { + String8 evallable_names[] = + { + str8_lit("breakpoint"), + str8_lit("watch_pin"), + str8_lit("target"), + str8_lit("file_path_map"), + str8_lit("auto_view_rule"), + }; + for EachElement(idx, evallable_names) + { + // rjf: determine schema string for this name + String8 schema_string = {0}; + for EachElement(schema_idx, rd_cfg_name_schema_pair_table) + { + if(str8_match(evallable_names[idx], rd_cfg_name_schema_pair_table[idx].name, 0)) + { + schema_string = rd_cfg_name_schema_pair_table[idx].schema; + break; + } + } + + // rjf: parse schema + MD_Node *schema = md_tree_from_string(scratch.arena, schema_string)->first; + + // rjf: form evaluation type from schema + + } + } + //- rjf: add macros for all evallable debugger frontend entities +#if 0 // TODO(rjf): @cfg { RD_EntityKind evallable_kinds[] = { @@ -12565,6 +12733,7 @@ rd_frame(void) } } } +#endif //- rjf: add macros for all evallable control entities { @@ -12961,241 +13130,105 @@ rd_frame(void) case RD_CmdKind_OpenUser: case RD_CmdKind_OpenProject: { - //- TODO(rjf): @cfg load & apply user/project data to the cfg data structure + String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : str8_lit("project")); + RD_Cfg *file_root = rd_cfg_child_from_string(rd_state->root_cfg, file_root_key); + + //- rjf: load the new file's data + String8 file_path = rd_regs()->file_path; + String8 file_data = os_data_from_file_path(scratch.arena, file_path); + + //- rjf: determine if the file is good + B32 file_is_okay = 0; { - String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : str8_lit("project")); - RD_Cfg *file_root = rd_cfg_child_from_string(rd_state->root_cfg, file_root_key); - - //- rjf: eliminate all old state under this file tree - for(RD_Cfg *tln = file_root->first, *next = &rd_nil_cfg; - tln != &rd_nil_cfg; - tln = next) - { - next = tln->next; - rd_cfg_release(tln); - } - - //- rjf: load & parse the new file, generate cfg entities for it - String8 file_path = rd_regs()->file_path; - String8 file_data = os_data_from_file_path(scratch.arena, file_path); - RD_CfgList file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_data); - - //- rjf: insert the new cfg entities into this file tree - for(RD_CfgNode *n = file_cfg_list.first; n != 0; n = n->next) - { - rd_cfg_insert_child(file_root, file_root->last, n->v); - } - - //- rjf: if config did not open any windows for the user, then we need to open a sensible default - { - if(str8_match(file_root_key, str8_lit("user"), 0)) - { - RD_CfgList all_user_windows = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("window")); - if(all_user_windows.count == 0) - { - OS_Handle monitor = os_primary_monitor(); - String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); - Vec2F32 monitor_dim = os_dim_from_monitor(monitor); - F32 monitor_dpi = os_dpi_from_monitor(monitor); - Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); - RD_Cfg *new_window = rd_cfg_new(file_root, str8_lit("window")); - RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); - rd_cfg_newf(size, "%f", window_dim.x); - rd_cfg_newf(size, "%f", window_dim.y); - F32 line_height_guess = 11.f * (monitor_dpi / 96.f); - F32 num_lines_in_monitor_height = monitor_dim.y / line_height_guess; - if(num_lines_in_monitor_height < 100) - { - rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_cfg(new_window)); - } - else - { - rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_cfg(new_window)); - } - } - } - } - } - - // TODO(rjf): dear lord this is so overcomplicated, this needs to be collapsed down & simplified ASAP - - B32 load_cfg[RD_CfgSrc_COUNT] = {0}; - RD_CfgSrc cfg_src = (RD_CfgSrc)0; - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - load_cfg[src] = (kind == rd_cfg_src_load_cmd_kind_table[src]); - if(load_cfg[src]) - { - cfg_src = src; - } - } - - //- rjf: normalize path - String8 new_path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); - - //- rjf: path -> data - FileProperties props = {0}; - String8 data = {0}; - { - OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, new_path); - props = os_properties_from_file(file); - data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size)); - os_file_close(file); - } - - //- rjf: investigate file path/data - B32 file_is_okay = 1; - if(props.modified != 0 && data.size != 0 && !str8_match(str8_prefix(data, 9), str8_lit("// raddbg"), 0) && rd_state->cfg_cached_timestamp[cfg_src] != 0) - { - file_is_okay = 0; - } - - //- rjf: set new config paths - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(load_cfg[src]) - { - arena_clear(rd_state->cfg_path_arenas[src]); - rd_state->cfg_paths[src] = push_str8_copy(rd_state->cfg_path_arenas[src], new_path); - } - } - } - - //- rjf: get config file properties - FileProperties cfg_props[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - String8 path = rd_cfg_path_from_src(src); - cfg_props[src] = os_properties_from_file_path(path); - } - } - - //- rjf: load files - String8 cfg_data[RD_CfgSrc_COUNT] = {0}; - U64 cfg_timestamps[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - String8 path = rd_cfg_path_from_src(src); - OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, path); - FileProperties props = os_properties_from_file(file); - String8 data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size)); - if(props.modified != 0) - { - cfg_data[src] = data; - cfg_timestamps[src] = props.modified; - } - os_file_close(file); - } - } - - //- rjf: determine if we need to save config - B32 cfg_save[RD_CfgSrc_COUNT] = {0}; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - cfg_save[src] = (load_cfg[src] && cfg_props[src].created == 0); - } - } - - //- rjf: determine if we need to reload config - B32 cfg_load[RD_CfgSrc_COUNT] = {0}; - B32 cfg_load_any = 0; - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - cfg_load[src] = (load_cfg[src] && ((cfg_save[src] == 0 && rd_state->cfg_cached_timestamp[src] != cfg_timestamps[src]) || cfg_props[src].created == 0)); - cfg_load_any = cfg_load_any || cfg_load[src]; - } - } - - //- rjf: load => build new config table - if(cfg_load_any) - { - arena_clear(rd_state->cfg_arena); - MemoryZeroStruct(&rd_state->cfg_table); - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - rd_cfg_table_push_unparsed_string(rd_state->cfg_arena, &rd_state->cfg_table, cfg_data[src], src); - } - } - - //- rjf: load => dispatch apply - // - // NOTE(rjf): must happen before `save`. we need to create a default before saving, which - // occurs in the 'apply' path. - // - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(cfg_load[src]) - { - RD_CmdKind cmd_kind = rd_cfg_src_apply_cmd_kind_table[src]; - rd_cmd(cmd_kind); - rd_state->cfg_cached_timestamp[src] = cfg_timestamps[src]; - } - } - } - - //- rjf: save => dispatch write - if(file_is_okay) - { - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - if(cfg_save[src]) - { - RD_CmdKind cmd_kind = rd_cfg_src_write_cmd_kind_table[src]; - rd_cmd(cmd_kind); - } - } + FileProperties file_props = os_properties_from_file_path(file_path); + file_is_okay = ((file_props.size == 0 && file_props.created == 0) || + str8_match(str8_prefix(file_data, 9), str8_lit("// raddbg"), 0)); } //- rjf: bad file -> alert user if(!file_is_okay) { - log_user_errorf("\"%S\" appears to refer to an existing file which is not a RADDBG config file. This would overwrite the file.", new_path); + log_user_errorf("\"%S\" appears to refer to an existing file which is not a RADDBG config file. This would overwrite the file.", file_path); } - }break; - - //- rjf: loading/applying stateful config changes - case RD_CmdKind_ApplyUserData: - case RD_CmdKind_ApplyProjectData: - { - RD_CfgTable *table = rd_cfg_table(); - OS_HandleArray monitors = os_push_monitors_array(scratch.arena); - //- rjf: get config source - RD_CfgSrc src = RD_CfgSrc_User; - for(RD_CfgSrc s = (RD_CfgSrc)0; s < RD_CfgSrc_COUNT; s = (RD_CfgSrc)(s+1)) + //- rjf: eliminate all old state under this file tree + if(file_is_okay) { - if(kind == rd_cfg_src_apply_cmd_kind_table[s]) + rd_cfg_release_all_children(file_root); + } + + //- rjf: parse the new file, generate cfg entities for it + RD_CfgList file_cfg_list = {0}; + if(file_is_okay) + { + file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_data); + } + + //- rjf: store path + if(file_is_okay) + { + switch(kind) { - src = s; - break; + default:{}break; + case RD_CmdKind_OpenUser: + { + arena_clear(rd_state->user_path_arena); + rd_state->user_path = push_str8_copy(rd_state->user_path_arena, file_path); + }break; + case RD_CmdKind_OpenProject: + { + arena_clear(rd_state->project_path_arena); + rd_state->project_path = push_str8_copy(rd_state->project_path_arena, file_path); + }break; } } - //- rjf: get paths - String8 cfg_path = rd_cfg_path_from_src(src); - String8 cfg_folder = str8_chop_last_slash(cfg_path); + //- rjf: insert the new cfg entities into this file tree + if(file_is_okay) + { + for(RD_CfgNode *n = file_cfg_list.first; n != 0; n = n->next) + { + rd_cfg_insert_child(file_root, file_root->last, n->v); + } + } - //- rjf: keep track of recent projects - if(src == RD_CfgSrc_Project) + //- rjf: if config did not open any windows for the user, then we need to open a sensible default + if(file_is_okay && kind == RD_CmdKind_OpenUser) + { + RD_CfgList all_user_windows = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("window")); + if(all_user_windows.count == 0) + { + OS_Handle monitor = os_primary_monitor(); + String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); + Vec2F32 monitor_dim = os_dim_from_monitor(monitor); + F32 monitor_dpi = os_dpi_from_monitor(monitor); + Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); + RD_Cfg *new_window = rd_cfg_new(file_root, str8_lit("window")); + RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); + rd_cfg_newf(size, "%f", window_dim.x); + rd_cfg_newf(size, "%f", window_dim.y); + F32 line_height_guess = 11.f * (monitor_dpi / 96.f); + F32 num_lines_in_monitor_height = monitor_dim.y / line_height_guess; + if(num_lines_in_monitor_height < 100) + { + rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_cfg(new_window)); + } + else + { + rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_cfg(new_window)); + } + } + } + + //- rjf: record recently-opened projects in the user + if(file_is_okay && kind == RD_CmdKind_OpenProject) { RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); RD_CfgList recent_projects = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("recent_project")); RD_Cfg *recent_project = &rd_nil_cfg; for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) { - if(path_match_normalized(n->v->string, cfg_path)) + if(path_match_normalized(n->v->string, file_path)) { recent_project = n->v; break; @@ -13204,7 +13237,7 @@ rd_frame(void) if(recent_project == &rd_nil_cfg) { recent_project = rd_cfg_new(user, str8_lit("recent_project")); - rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, cfg_path)); + rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, file_path)); } rd_cfg_unhook(user, recent_project); rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); @@ -13214,636 +13247,6 @@ rd_frame(void) rd_cfg_release(recent_projects.last->v); } } - - //- rjf: apply all entities - { - for EachEnumVal(RD_EntityKind, k) - { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(k_flags & RD_EntityKindFlag_IsSerializedToConfig) - { - RD_CfgVal *k_val = rd_cfg_val_from_string(table, d_entity_kind_name_lower_table[k]); - for(RD_CfgTree *k_tree = k_val->first; - k_tree != &d_nil_cfg_tree; - k_tree = k_tree->next) - { - if(k_tree->source != src) - { - continue; - } - RD_Entity *entity = rd_entity_alloc(rd_entity_root(), k); - rd_entity_equip_cfg_src(entity, k_tree->source); - - // rjf: iterate config tree - typedef struct Task Task; - struct Task - { - Task *next; - RD_Entity *entity; - MD_Node *n; - }; - Task start_task = {0, entity, k_tree->root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - MD_Node *node = t->n; - for MD_EachNode(child, node->first) - { - // rjf: standalone string literals under an entity -> name - if(child->flags & MD_NodeFlag_StringLiteral && child->first == &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->string); - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath && - t->entity->kind != RD_EntityKind_Location) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - } - - // rjf: standalone string literals under an entity, with a numeric child -> name & text location - if(child->flags & MD_NodeFlag_StringLiteral && child->first->flags & MD_NodeFlag_Numeric && child->first->first == &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->string); - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - S64 line = 0; - try_s64_from_str8_c_rules(child->first->string, &line); - TxtPt pt = txt_pt(line, 1); - rd_entity_equip_txt_pt(t->entity, pt); - } - - // rjf: standalone hex literals under an entity -> vaddr - if(child->flags & MD_NodeFlag_Numeric && child->first == &md_nil_node && str8_match(str8_substr(child->string, r1u64(0, 2)), str8_lit("0x"), 0)) - { - U64 vaddr = 0; - try_u64_from_str8_c_rules(child->string, &vaddr); - rd_entity_equip_vaddr(t->entity, vaddr); - } - - // rjf: specifically named entity equipment - if((str8_match(child->string, str8_lit("name"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("label"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - String8 string = raw_from_escaped_str8(scratch.arena, child->first->string); - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[t->entity->kind] & RD_EntityKindFlag_NameIsPath && - (t->entity->kind != RD_EntityKind_Location || !md_node_is_nil(md_child_from_string(node, str8_lit("line"), 0)))) - { - string = path_absolute_dst_from_relative_dst_src(scratch.arena, string, cfg_folder); - } - rd_entity_equip_name(t->entity, string); - } - if((str8_match(child->string, str8_lit("active"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("enabled"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - rd_entity_equip_disabled(t->entity, !str8_match(child->first->string, str8_lit("1"), 0)); - } - if(str8_match(child->string, str8_lit("disabled"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - rd_entity_equip_disabled(t->entity, str8_match(child->first->string, str8_lit("1"), 0)); - } - if(str8_match(child->string, str8_lit("debug_subprocesses"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - t->entity->debug_subprocesses = str8_match(child->first->string, str8_lit("1"), 0); - } - if(str8_match(child->string, str8_lit("hsva"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - Vec4F32 hsva = {0}; - hsva.x = (F32)f64_from_str8(child->first->string); - hsva.y = (F32)f64_from_str8(child->first->next->string); - hsva.z = (F32)f64_from_str8(child->first->next->next->string); - hsva.w = (F32)f64_from_str8(child->first->next->next->next->string); - rd_entity_equip_color_hsva(t->entity, hsva); - } - if(str8_match(child->string, str8_lit("color"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - Vec4F32 rgba = rgba_from_hex_string_4f32(child->first->string); - Vec4F32 hsva = hsva_from_rgba(rgba); - rd_entity_equip_color_hsva(t->entity, hsva); - } - if(str8_match(child->string, str8_lit("line"), StringMatchFlag_CaseInsensitive) && child->first != &md_nil_node) - { - S64 line = 0; - try_s64_from_str8_c_rules(child->first->string, &line); - TxtPt pt = txt_pt(line, 1); - rd_entity_equip_txt_pt(t->entity, pt); - } - if((str8_match(child->string, str8_lit("vaddr"), StringMatchFlag_CaseInsensitive) || - str8_match(child->string, str8_lit("addr"), StringMatchFlag_CaseInsensitive)) && - child->first != &md_nil_node) - { - U64 vaddr = 0; - try_u64_from_str8_c_rules(child->first->string, &vaddr); - rd_entity_equip_vaddr(t->entity, vaddr); - } - - // rjf: sub-entity -> create new task - RD_EntityKind sub_entity_kind = RD_EntityKind_Nil; - for EachEnumVal(RD_EntityKind, k2) - { - if(child->flags & MD_NodeFlag_Identifier && child->first != &md_nil_node && - (str8_match(child->string, d_entity_kind_name_lower_table[k2], StringMatchFlag_CaseInsensitive) || - (k2 == RD_EntityKind_Executable && str8_match(child->string, str8_lit("exe"), StringMatchFlag_CaseInsensitive)))) - { - Task *task = push_array(scratch.arena, Task, 1); - task->next = t->next; - task->entity = rd_entity_alloc(t->entity, k2); - task->n = child; - t->next = task; - break; - } - } - } - } - } - } - } - } - - //- rjf: apply exception code filters - RD_CfgVal *filter_tables = rd_cfg_val_from_string(table, str8_lit("exception_code_filters")); - for(RD_CfgTree *table = filter_tables->first; - table != &d_nil_cfg_tree; - table = table->next) - { - for MD_EachNode(rule, table->root->first) - { - String8 name = rule->string; - String8 val_string = rule->first->string; - U64 val = 0; - if(try_u64_from_str8_c_rules(val_string, &val)) - { - CTRL_ExceptionCodeKind kind = CTRL_ExceptionCodeKind_Null; - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - if(str8_match(name, ctrl_exception_code_kind_lowercase_code_string_table[k], 0)) - { - kind = k; - break; - } - } - if(kind != CTRL_ExceptionCodeKind_Null) - { - if(val) - { - rd_state->ctrl_exception_code_filters[kind/64] |= (1ull<<(kind%64)); - } - else - { - rd_state->ctrl_exception_code_filters[kind/64] &= ~(1ull<<(kind%64)); - } - } - } - } - } - - //- rjf: apply fonts - { - FNT_Tag defaults[RD_FontSlot_COUNT] = - { - fnt_tag_from_static_data_string(&rd_default_main_font_bytes), - fnt_tag_from_static_data_string(&rd_default_code_font_bytes), - fnt_tag_from_static_data_string(&rd_icon_font_bytes), - }; - MemoryZeroArray(rd_state->cfg_font_tags); - { - RD_CfgVal *code_font_val = rd_cfg_val_from_string(table, str8_lit("code_font")); - RD_CfgVal *main_font_val = rd_cfg_val_from_string(table, str8_lit("main_font")); - MD_Node *code_font_node = code_font_val->last->root; - MD_Node *main_font_node = main_font_val->last->root; - String8 code_font_relative_path = code_font_node->first->string; - String8 main_font_relative_path = main_font_node->first->string; - if(!md_node_is_nil(code_font_node)) - { - arena_clear(rd_state->cfg_code_font_path_arena); - rd_state->cfg_code_font_path = raw_from_escaped_str8(rd_state->cfg_code_font_path_arena, code_font_relative_path); - } - if(!md_node_is_nil(main_font_node)) - { - arena_clear(rd_state->cfg_main_font_path_arena); - rd_state->cfg_main_font_path = raw_from_escaped_str8(rd_state->cfg_main_font_path_arena, main_font_relative_path); - } - String8 code_font_path = path_absolute_dst_from_relative_dst_src(scratch.arena, code_font_relative_path, cfg_folder); - String8 main_font_path = path_absolute_dst_from_relative_dst_src(scratch.arena, main_font_relative_path, cfg_folder); - if(os_file_path_exists(code_font_path) && !md_node_is_nil(code_font_node) && code_font_relative_path.size != 0) - { - rd_state->cfg_font_tags[RD_FontSlot_Code] = fnt_tag_from_path(code_font_path); - } - if(os_file_path_exists(main_font_path) && !md_node_is_nil(main_font_node) && main_font_relative_path.size != 0) - { - rd_state->cfg_font_tags[RD_FontSlot_Main] = fnt_tag_from_path(main_font_path); - } - } - for(RD_FontSlot slot = (RD_FontSlot)0; slot < RD_FontSlot_COUNT; slot = (RD_FontSlot)(slot+1)) - { - if(fnt_tag_match(fnt_tag_zero(), rd_state->cfg_font_tags[slot])) - { - rd_state->cfg_font_tags[slot] = defaults[slot]; - } - } - } - - //- rjf: build windows & panel layouts - RD_CfgVal *windows = rd_cfg_val_from_string(table, str8_lit("window")); - for(RD_CfgTree *window_tree = windows->first; - window_tree != &d_nil_cfg_tree; - window_tree = window_tree->next) - { - // rjf: skip wrong source - if(window_tree->source != src) - { - continue; - } - - // rjf: grab metadata - B32 is_fullscreen = 0; - B32 is_maximized = 0; - Axis2 top_level_split_axis = Axis2_X; - OS_Handle preferred_monitor = os_primary_monitor(); - Vec2F32 size = {0}; - F32 dpi = 0.f; - RD_SettingVal setting_vals[RD_SettingCode_COUNT] = {0}; - { - for MD_EachNode(n, window_tree->root->first) - { - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("split_x"), StringMatchFlag_CaseInsensitive)) - { - top_level_split_axis = Axis2_X; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("split_y"), StringMatchFlag_CaseInsensitive)) - { - top_level_split_axis = Axis2_Y; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("fullscreen"), StringMatchFlag_CaseInsensitive)) - { - is_fullscreen = 1; - } - if(n->flags & MD_NodeFlag_Identifier && - md_node_is_nil(n->first) && - str8_match(n->string, str8_lit("maximized"), StringMatchFlag_CaseInsensitive)) - { - is_maximized = 1; - } - } - MD_Node *monitor_node = md_child_from_string(window_tree->root, str8_lit("monitor"), 0); - String8 preferred_monitor_name = monitor_node->first->string; - for(U64 idx = 0; idx < monitors.count; idx += 1) - { - String8 monitor_name = os_name_from_monitor(scratch.arena, monitors.v[idx]); - if(str8_match(monitor_name, preferred_monitor_name, StringMatchFlag_CaseInsensitive)) - { - preferred_monitor = monitors.v[idx]; - break; - } - } - Vec2F32 preferred_monitor_size = os_dim_from_monitor(preferred_monitor); - MD_Node *size_node = md_child_from_string(window_tree->root, str8_lit("size"), 0); - { - String8 x_string = size_node->first->string; - String8 y_string = size_node->first->next->string; - U64 x_u64 = 0; - U64 y_u64 = 0; - if(!try_u64_from_str8_c_rules(x_string, &x_u64)) - { - x_u64 = (U64)(preferred_monitor_size.x*2/3); - } - if(!try_u64_from_str8_c_rules(y_string, &y_u64)) - { - y_u64 = (U64)(preferred_monitor_size.y*2/3); - } - size.x = (F32)x_u64; - size.y = (F32)y_u64; - } - MD_Node *dpi_node = md_child_from_string(window_tree->root, str8_lit("dpi"), 0); - String8 dpi_string = md_string_from_children(scratch.arena, dpi_node); - dpi = f64_from_str8(dpi_string); - for EachEnumVal(RD_SettingCode, code) - { - MD_Node *code_node = md_child_from_string(window_tree->root, rd_setting_code_lower_string_table[code], 0); - if(!md_node_is_nil(code_node)) - { - S64 val_s64 = 0; - try_s64_from_str8_c_rules(code_node->first->string, &val_s64); - setting_vals[code].set = 1; - setting_vals[code].s32 = (S32)val_s64; - setting_vals[code].s32 = clamp_1s32(rd_setting_code_s32_range_table[code], setting_vals[code].s32); - } - } - } - } - - //- rjf: apply keybindings -#if 0 // TODO(rjf): @cfg - if(src == RD_CfgSrc_User) - { - rd_clear_bindings(); - } - RD_CfgVal *keybindings = rd_cfg_val_from_string(table, str8_lit("keybindings")); - for(RD_CfgTree *keybinding_set = keybindings->first; - keybinding_set != &d_nil_cfg_tree; - keybinding_set = keybinding_set->next) - { - for MD_EachNode(keybind, keybinding_set->root->first) - { - String8 cmd_name = {0}; - OS_Key key = OS_Key_Null; - MD_Node *ctrl_node = &md_nil_node; - MD_Node *shift_node = &md_nil_node; - MD_Node *alt_node = &md_nil_node; - for MD_EachNode(child, keybind->first) - { - if(str8_match(child->string, str8_lit("ctrl"), 0)) - { - ctrl_node = child; - } - else if(str8_match(child->string, str8_lit("shift"), 0)) - { - shift_node = child; - } - else if(str8_match(child->string, str8_lit("alt"), 0)) - { - alt_node = child; - } - else - { - OS_Key k = OS_Key_Null; - for EachEnumVal(OS_Key, key) - { - if(str8_match(child->string, os_g_key_cfg_string_table[key], StringMatchFlag_CaseInsensitive)) - { - k = key; - break; - } - } - if(k != OS_Key_Null) - { - key = k; - } - else - { - cmd_name = child->string; - for(U64 idx = 0; idx < ArrayCount(rd_binding_version_remap_old_name_table); idx += 1) - { - if(str8_match(rd_binding_version_remap_old_name_table[idx], child->string, StringMatchFlag_CaseInsensitive)) - { - String8 new_name = rd_binding_version_remap_new_name_table[idx]; - cmd_name = new_name; - } - } - } - } - } - if(cmd_name.size != 0 && key != OS_Key_Null) - { - OS_Modifiers flags = 0; - if(!md_node_is_nil(ctrl_node)) { flags |= OS_Modifier_Ctrl; } - if(!md_node_is_nil(shift_node)) { flags |= OS_Modifier_Shift; } - if(!md_node_is_nil(alt_node)) { flags |= OS_Modifier_Alt; } - RD_Binding binding = {key, flags}; - rd_bind_name(cmd_name, binding); - } - } - } -#endif - - //- rjf: reset theme to default - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - - //- rjf: apply theme presets - RD_CfgVal *color_preset = rd_cfg_val_from_string(table, str8_lit("color_preset")); - B32 preset_applied = 0; - if(color_preset != &d_nil_cfg_val) - { - String8 color_preset_name = color_preset->last->root->first->string; - RD_ThemePreset preset = (RD_ThemePreset)0; - B32 found_preset = 0; - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - if(str8_match(color_preset_name, rd_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) - { - found_preset = 1; - preset = p; - break; - } - } - if(found_preset) - { - preset_applied = 1; - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors_table[preset], sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors_table[preset], sizeof(rd_theme_preset_colors__default_dark)); - } - } - - //- rjf: apply individual theme colors - B8 theme_color_hit[RD_ThemeColor_COUNT] = {0}; - RD_CfgVal *colors = rd_cfg_val_from_string(table, str8_lit("colors")); - for(RD_CfgTree *colors_set = colors->first; - colors_set != &d_nil_cfg_tree; - colors_set = colors_set->next) - { - for MD_EachNode(color, colors_set->root->first) - { - String8 saved_color_name = color->string; - String8List candidate_color_names = {0}; - str8_list_push(scratch.arena, &candidate_color_names, saved_color_name); - for(U64 idx = 0; idx < ArrayCount(rd_theme_color_version_remap_old_name_table); idx += 1) - { - if(str8_match(rd_theme_color_version_remap_old_name_table[idx], saved_color_name, StringMatchFlag_CaseInsensitive)) - { - str8_list_push(scratch.arena, &candidate_color_names, rd_theme_color_version_remap_new_name_table[idx]); - } - } - for(String8Node *name_n = candidate_color_names.first; name_n != 0; name_n = name_n->next) - { - String8 name = name_n->string; - RD_ThemeColor color_code = RD_ThemeColor_Null; - for(RD_ThemeColor c = RD_ThemeColor_Null; c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(str8_match(rd_theme_color_cfg_string_table[c], name, StringMatchFlag_CaseInsensitive)) - { - color_code = c; - break; - } - } - if(color_code != RD_ThemeColor_Null) - { - theme_color_hit[color_code] = 1; - MD_Node *hex_cfg = color->first; - String8 hex_string = hex_cfg->string; - U64 hex_val = 0; - try_u64_from_str8_c_rules(hex_string, &hex_val); - Vec4F32 color_rgba = rgba_from_u32((U32)hex_val); - rd_state->cfg_theme_target.colors[color_code] = color_rgba; - if(rd_state->frame_index <= 2) - { - rd_state->cfg_theme.colors[color_code] = color_rgba; - } - } - } - } - } - - //- rjf: no preset -> autofill all missing colors from the preset with the most similar background - if(!preset_applied) - { - RD_ThemePreset closest_preset = RD_ThemePreset_DefaultDark; - F32 closest_preset_bg_distance = 100000000; - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - Vec4F32 cfg_bg = rd_state->cfg_theme_target.colors[RD_ThemeColor_BaseBackground]; - Vec4F32 pre_bg = rd_theme_preset_colors_table[p][RD_ThemeColor_BaseBackground]; - Vec4F32 diff = sub_4f32(cfg_bg, pre_bg); - Vec3F32 diff3 = diff.xyz; - F32 distance = length_3f32(diff3); - if(distance < closest_preset_bg_distance) - { - closest_preset = p; - closest_preset_bg_distance = distance; - } - } - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); - c < RD_ThemeColor_COUNT; - c = (RD_ThemeColor)(c+1)) - { - if(!theme_color_hit[c]) - { - rd_state->cfg_theme_target.colors[c] = rd_state->cfg_theme.colors[c] = rd_theme_preset_colors_table[closest_preset][c]; - } - } - } - - //- rjf: if theme colors are all zeroes, then set to default - config appears busted - { - B32 all_colors_are_zero = 1; - Vec4F32 zero_color = {0}; - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(!MemoryMatchStruct(&rd_state->cfg_theme_target.colors[c], &zero_color)) - { - all_colors_are_zero = 0; - break; - } - } - if(all_colors_are_zero) - { - MemoryCopy(rd_state->cfg_theme_target.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - MemoryCopy(rd_state->cfg_theme.colors, rd_theme_preset_colors__default_dark, sizeof(rd_theme_preset_colors__default_dark)); - } - } - - //- rjf: apply settings - B8 setting_codes_hit[RD_SettingCode_COUNT] = {0}; - MemoryZero(&rd_state->cfg_setting_vals[src][0], sizeof(RD_SettingVal)*RD_SettingCode_COUNT); - for EachEnumVal(RD_SettingCode, code) - { - String8 name = rd_setting_code_lower_string_table[code]; - RD_CfgVal *code_cfg_val = rd_cfg_val_from_string(table, name); - RD_CfgTree *code_tree = code_cfg_val->last; - if(code_tree->source == src) - { - MD_Node *val_node = code_tree->root->first; - S64 val = 0; - if(try_s64_from_str8_c_rules(val_node->string, &val)) - { - rd_state->cfg_setting_vals[src][code].set = 1; - rd_state->cfg_setting_vals[src][code].s32 = (S32)val; - } - setting_codes_hit[code] = !md_node_is_nil(val_node); - } - } - - //- rjf: if config applied 0 settings, we need to do some sensible default - if(src == RD_CfgSrc_User) - { - for EachEnumVal(RD_SettingCode, code) - { - if(!setting_codes_hit[code]) - { - rd_state->cfg_setting_vals[src][code] = rd_setting_code_default_val_table[code]; - } - } - } - - //- rjf: if config opened 0 windows, we need to do some sensible default -#if 0 // TODO(rjf): @cfg - if(src == RD_CfgSrc_User && windows->first == &d_nil_cfg_tree) - { - OS_Handle preferred_monitor = os_primary_monitor(); - Vec2F32 monitor_dim = os_dim_from_monitor(preferred_monitor); - Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); - RD_Window *ws = rd_window_open(window_dim, preferred_monitor, RD_CfgSrc_User); - F32 font_size = (F32)ws->setting_vals[RD_SettingCode_MainFontSize].s32; - F32 num_lines_in_monitor_height = monitor_dim.y / font_size; - if(num_lines_in_monitor_height < 100) - { - rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_window(ws)); - } - else - { - rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_window(ws)); - } - } -#endif - - //- rjf: if config bound 0 keys, we need to do some sensible default -#if 0 // TODO(rjf): @cfg - if(src == RD_CfgSrc_User && rd_state->key_map_total_count == 0) - { - for(U64 idx = 0; idx < ArrayCount(rd_default_binding_table); idx += 1) - { - RD_StringBindingPair *pair = &rd_default_binding_table[idx]; - rd_bind_name(pair->string, pair->binding); - } - } -#endif - - //- rjf: always ensure that the meta controls have bindings -#if 0 // TODO(rjf): @cfg - if(src == RD_CfgSrc_User) - { - struct - { - String8 name; - OS_Key fallback_key; - } - meta_ctrls[] = - { - { rd_cmd_kind_info_table[RD_CmdKind_Edit].string, OS_Key_F2 }, - { rd_cmd_kind_info_table[RD_CmdKind_Accept].string, OS_Key_Return }, - { rd_cmd_kind_info_table[RD_CmdKind_Cancel].string, OS_Key_Esc }, - }; - for(U64 idx = 0; idx < ArrayCount(meta_ctrls); idx += 1) - { - RD_BindingList bindings = rd_bindings_from_name(scratch.arena, meta_ctrls[idx].name); - if(bindings.count == 0) - { - RD_Binding binding = {meta_ctrls[idx].fallback_key, 0}; - rd_bind_name(meta_ctrls[idx].name, binding); - } - } - } -#endif }break; //- rjf: writing config changes @@ -17008,7 +16411,50 @@ X(getting_started) // U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64] = {0}; { - MemoryCopyArray(exception_code_filters, rd_state->ctrl_exception_code_filters); + Temp scratch = scratch_begin(0, 0); + for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) + { + if(ctrl_exception_code_kind_default_enable_table[k]) + { + exception_code_filters[k/64] |= 1ull<<(k%64); + } + } + RD_CfgList exception_code_filters_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("exception_code_filters")); + for(RD_CfgNode *n = exception_code_filters_roots.first; n != 0; n = n->next) + { + for(RD_Cfg *rule = n->v->first; rule != &rd_nil_cfg; rule = rule->next) + { + String8 name = rule->string; + String8 val_string = rule->first->string; + U64 val = 0; + if(try_u64_from_str8_c_rules(val_string, &val)) + { + CTRL_ExceptionCodeKind kind = CTRL_ExceptionCodeKind_Null; + for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); + k < CTRL_ExceptionCodeKind_COUNT; + k = (CTRL_ExceptionCodeKind)(k+1)) + { + if(str8_match(name, ctrl_exception_code_kind_lowercase_code_string_table[k], 0)) + { + kind = k; + break; + } + } + if(kind != CTRL_ExceptionCodeKind_Null) + { + if(val) + { + exception_code_filters[kind/64] |= (1ull<<(kind%64)); + } + else + { + exception_code_filters[kind/64] &= ~(1ull<<(kind%64)); + } + } + } + } + } + scratch_end(scratch); } //////////////////////////// @@ -17173,31 +16619,6 @@ X(getting_started) } } - ////////////////////////////// - //- rjf: animate theme - // - { - RD_Theme *current = &rd_state->cfg_theme; - RD_Theme *target = &rd_state->cfg_theme_target; - F32 rate = 1 - pow_f32(2, (-50.f * rd_state->frame_dt)); - for(RD_ThemeColor color = RD_ThemeColor_Null; - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - if(abs_f32(target->colors[color].x - current->colors[color].x) > 0.01f || - abs_f32(target->colors[color].y - current->colors[color].y) > 0.01f || - abs_f32(target->colors[color].z - current->colors[color].z) > 0.01f || - abs_f32(target->colors[color].w - current->colors[color].w) > 0.01f) - { - rd_request_frame(); - } - current->colors[color].x += (target->colors[color].x - current->colors[color].x) * rate; - current->colors[color].y += (target->colors[color].y - current->colors[color].y) * rate; - current->colors[color].z += (target->colors[color].z - current->colors[color].z) * rate; - current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; - } - } - //////////////////////////// //- rjf: rotate command slots, bump command gen counter // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 460e58d3..f1da382d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -39,21 +39,6 @@ struct RD_Binding OS_Modifiers modifiers; }; -typedef struct RD_BindingNode RD_BindingNode; -struct RD_BindingNode -{ - RD_BindingNode *next; - RD_Binding binding; -}; - -typedef struct RD_BindingList RD_BindingList; -struct RD_BindingList -{ - RD_BindingNode *first; - RD_BindingNode *last; - U64 count; -}; - typedef struct RD_StringBindingPair RD_StringBindingPair; struct RD_StringBindingPair { @@ -61,6 +46,47 @@ struct RD_StringBindingPair RD_Binding binding; }; +typedef struct RD_KeyMapNode RD_KeyMapNode; +struct RD_KeyMapNode +{ + RD_KeyMapNode *name_hash_next; + RD_KeyMapNode *binding_hash_next; + struct RD_Cfg *cfg; + String8 name; + RD_Binding binding; +}; + +typedef struct RD_KeyMapNodePtr RD_KeyMapNodePtr; +struct RD_KeyMapNodePtr +{ + RD_KeyMapNodePtr *next; + RD_KeyMapNode *v; +}; + +typedef struct RD_KeyMapNodePtrList RD_KeyMapNodePtrList; +struct RD_KeyMapNodePtrList +{ + RD_KeyMapNodePtr *first; + RD_KeyMapNodePtr *last; + U64 count; +}; + +typedef struct RD_KeyMapSlot RD_KeyMapSlot; +struct RD_KeyMapSlot +{ + RD_KeyMapNode *first; + RD_KeyMapNode *last; +}; + +typedef struct RD_KeyMap RD_KeyMap; +struct RD_KeyMap +{ + U64 name_slots_count; + RD_KeyMapSlot *name_slots; + U64 binding_slots_count; + RD_KeyMapSlot *binding_slots; +}; + //////////////////////////////// //~ rjf: Evaluation Spaces @@ -68,6 +94,7 @@ typedef U64 RD_EvalSpaceKind; enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, + RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaEntity, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaCollection, @@ -148,7 +175,7 @@ enum typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); //////////////////////////////// -//~ rjf: View Types +//~ rjf: View State Types typedef struct RD_ArenaExt RD_ArenaExt; struct RD_ArenaExt @@ -355,50 +382,6 @@ struct RD_Location String8 name; }; -//////////////////////////////// -//~ rjf: Key Map Types - -typedef struct RD_KeyMapNode RD_KeyMapNode; -struct RD_KeyMapNode -{ - RD_KeyMapNode *name_hash_next; - RD_KeyMapNode *binding_hash_next; - RD_Cfg *cfg; - String8 name; - RD_Binding binding; -}; - -typedef struct RD_KeyMapNodePtr RD_KeyMapNodePtr; -struct RD_KeyMapNodePtr -{ - RD_KeyMapNodePtr *next; - RD_KeyMapNode *v; -}; - -typedef struct RD_KeyMapNodePtrList RD_KeyMapNodePtrList; -struct RD_KeyMapNodePtrList -{ - RD_KeyMapNodePtr *first; - RD_KeyMapNodePtr *last; - U64 count; -}; - -typedef struct RD_KeyMapSlot RD_KeyMapSlot; -struct RD_KeyMapSlot -{ - RD_KeyMapNode *first; - RD_KeyMapNode *last; -}; - -typedef struct RD_KeyMap RD_KeyMap; -struct RD_KeyMap -{ - U64 name_slots_count; - RD_KeyMapSlot *name_slots; - U64 binding_slots_count; - RD_KeyMapSlot *binding_slots; -}; - //////////////////////////////// //~ rjf: New Panel Types (Queried From Config) @@ -816,6 +799,12 @@ struct RD_State B32 quit; B32 quit_after_success; + // rjf: config bucket paths + Arena *user_path_arena; + String8 user_path; + Arena *project_path_arena; + String8 project_path; + // rjf: log Log *log; String8 log_path; @@ -841,6 +830,10 @@ struct RD_State // rjf: key map (constructed from-scratch each frame) RD_KeyMap *key_map; + // rjf: theme target (constructed from-scratch each frame) + RD_Theme *theme; + RD_Theme *theme_target; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -937,38 +930,12 @@ struct RD_State U64 kind_alloc_gens[RD_EntityKind_COUNT]; RD_EntityListCache kind_caches[RD_EntityKind_COUNT]; - // rjf: key map table -#if 0 // TODO(rjf): @cfg - Arena *key_map_arena; - U64 key_map_table_size; - RD_KeyMapSlot *key_map_table; - RD_KeyMapNode *free_key_map_node; - U64 key_map_total_count; -#endif - // rjf: bind change Arena *bind_change_arena; B32 bind_change_active; String8 bind_change_cmd_name; RD_Binding bind_change_binding; - // rjf: config reading state - Arena *cfg_path_arenas[RD_CfgSrc_COUNT]; - String8 cfg_paths[RD_CfgSrc_COUNT]; - U64 cfg_cached_timestamp[RD_CfgSrc_COUNT]; - Arena *cfg_arena; - RD_CfgTable cfg_table; - U64 ctrl_exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; - - // rjf: running theme state - RD_Theme cfg_theme_target; - RD_Theme cfg_theme; - Arena *cfg_main_font_path_arena; - Arena *cfg_code_font_path_arena; - String8 cfg_main_font_path; - String8 cfg_code_font_path; - FNT_Tag cfg_font_tags[RD_FontSlot_COUNT]; // derivative from font paths - // rjf: global settings RD_SettingVal cfg_setting_vals[RD_CfgSrc_COUNT][RD_SettingCode_COUNT]; @@ -1231,6 +1198,10 @@ internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_E //////////////////////////////// //~ rjf: Evaluation Spaces +//- rjf: cfg <-> eval space +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); @@ -1414,15 +1385,9 @@ internal void rd_request_frame(void); //- rjf: per-frame arena internal Arena *rd_frame_arena(void); -//- rjf: config paths -internal String8 rd_cfg_path_from_src(RD_CfgSrc src); - //- rjf: entity cache queries internal RD_EntityList rd_query_cached_entity_list_with_kind(RD_EntityKind kind); -//- rjf: config state -internal RD_CfgTable *rd_cfg_table(void); - //////////////////////////////// //~ rjf: Registers diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index dd7a4025..a190700b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -6050,144 +6050,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) scratch_end(scratch); } -//////////////////////////////// -//~ rjf: exception_filters @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(exception_filters) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - String8 query = string; - - //- rjf: get state - typedef struct RD_ExceptionFiltersViewState RD_ExceptionFiltersViewState; - struct RD_ExceptionFiltersViewState - { - Vec2S64 cursor; - }; - RD_ExceptionFiltersViewState *sv = rd_view_state(RD_ExceptionFiltersViewState); - - //- rjf: get list of options - typedef struct RD_ExceptionFiltersOption RD_ExceptionFiltersOption; - struct RD_ExceptionFiltersOption - { - String8 name; - FuzzyMatchRangeList matches; - B32 is_enabled; - CTRL_ExceptionCodeKind exception_code_kind; - }; - typedef struct RD_ExceptionFiltersOptionChunkNode RD_ExceptionFiltersOptionChunkNode; - struct RD_ExceptionFiltersOptionChunkNode - { - RD_ExceptionFiltersOptionChunkNode *next; - RD_ExceptionFiltersOption *v; - U64 cap; - U64 count; - }; - typedef struct RD_ExceptionFiltersOptionChunkList RD_ExceptionFiltersOptionChunkList; - struct RD_ExceptionFiltersOptionChunkList - { - RD_ExceptionFiltersOptionChunkNode *first; - RD_ExceptionFiltersOptionChunkNode *last; - U64 option_count; - U64 node_count; - }; - typedef struct RD_ExceptionFiltersOptionArray RD_ExceptionFiltersOptionArray; - struct RD_ExceptionFiltersOptionArray - { - RD_ExceptionFiltersOption *v; - U64 count; - }; - RD_ExceptionFiltersOptionChunkList opts_list = {0}; - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - RD_ExceptionFiltersOptionChunkNode *node = opts_list.last; - String8 name = push_str8f(scratch.arena, "0x%x %S", ctrl_exception_code_kind_code_table[k], ctrl_exception_code_kind_display_string_table[k]); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, query, name); - if(matches.count >= matches.needle_part_count) - { - if(node == 0 || node->count >= node->cap) - { - node = push_array(scratch.arena, RD_ExceptionFiltersOptionChunkNode, 1); - node->cap = 256; - node->v = push_array_no_zero(scratch.arena, RD_ExceptionFiltersOption, node->cap); - SLLQueuePush(opts_list.first, opts_list.last, node); - opts_list.node_count += 1; - } - node->v[node->count].name = name; - node->v[node->count].matches = matches; - node->v[node->count].is_enabled = !!(rd_state->ctrl_exception_code_filters[k/64] & (1ull<<(k%64))); - node->v[node->count].exception_code_kind = k; - node->count += 1; - opts_list.option_count += 1; - } - } - RD_ExceptionFiltersOptionArray opts = {0}; - { - opts.count = opts_list.option_count; - opts.v = push_array_no_zero(scratch.arena, RD_ExceptionFiltersOption, opts.count); - U64 idx = 0; - for(RD_ExceptionFiltersOptionChunkNode *n = opts_list.first; n != 0; n = n->next) - { - MemoryCopy(opts.v+idx, n->v, n->count*sizeof(RD_ExceptionFiltersOption)); - idx += n->count; - } - } - - //- rjf: build option table - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 rect_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = rect_dim; - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, opts.count)); - scroll_list_params.item_range = r1s64(0, opts.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, - &scroll_pos.y, - &sv->cursor, - 0, - &visible_row_range, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 row = visible_row_range.min; row <= visible_row_range.max && row < opts.count; row += 1) - UI_FocusHot(sv->cursor.y == row+1 ? UI_FocusKind_On : UI_FocusKind_Off) - { - RD_ExceptionFiltersOption *opt = &opts.v[row]; - UI_Signal sig = rd_icon_buttonf(opt->is_enabled ? RD_IconKind_CheckFilled : RD_IconKind_CheckHollow, &opt->matches, "%S", opt->name); - if(ui_clicked(sig)) - { - if(opt->exception_code_kind != CTRL_ExceptionCodeKind_Null) - { - CTRL_ExceptionCodeKind k = opt->exception_code_kind; - if(opt->is_enabled) - { - rd_state->ctrl_exception_code_filters[k/64] &= ~(1ull<<(k%64)); - } - else - { - rd_state->ctrl_exception_code_filters[k/64] |= (1ull<<(k%64)); - } - } - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - //////////////////////////////// //~ rjf: settings @view_hook_impl @@ -6264,6 +6126,7 @@ rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { +#if 0 ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); @@ -6888,4 +6751,5 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) rd_store_view_scroll_pos(scroll_pos); scratch_end(scratch); ProfEnd(); +#endif } From 45f02b7a4140efce21d48f7cc142e21e1bedef04 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 22 Jan 2025 15:42:21 -0800 Subject: [PATCH 021/755] sketch out top-level schema for cfg tree --- src/raddbg/raddbg.mdesk | 29 +++++++++++++++++++++++++++++ src/raddbg/raddbg_views.c | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 747cb0e7..e27f2929 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -111,6 +111,35 @@ RD_VocabularyMap: //////////////////////////////// //~ rjf: Configuration Tree Schemas +/* + { + top_level, + ```x: + { + 'hover_animations': bool, + 'press_animations': bool, + 'focus_animations': bool, + 'tooltip_animations': bool, + 'menu_animations': bool, + 'scrolling_animations': bool, + 'background_blur': bool, + 'thread_lines': bool, + 'breakpoint_lines': bool, + 'thread_glow': bool, + 'breakpoint_glow': bool, + 'opaque_backgrounds': bool, + 'smooth_main_text': bool, + 'smooth_code_text': bool, + 'hint_main_text': bool, + 'hint_code_text': bool, + 'tab_width': @range[1, 32] u64, + 'main_font_size': @range[6, 72] u64, + 'code_font_size': @range[1, 32] u64, + } + ``` + } +*/ + @table(name schema) RD_CfgSchemaTable: { {target "x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}"} diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a190700b..d614ef07 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -6126,7 +6126,7 @@ rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { -#if 0 +#if 0 // TODO(rjf): @cfg ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); From 50000c0d6bbd627febf41da628217dd8389738a6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 23 Jan 2025 11:39:55 -0800 Subject: [PATCH 022/755] adjust metagen to support correctly-escaped multiline string generations; sketch out setting schemas; eliminate old settings hack, move to using cfg tree & settings schema --- src/lib_rdi_format/rdi_format.h | 2 +- src/metagen/metagen.c | 26 +- src/metagen/metagen_base/metagen_base_arena.c | 77 +- src/metagen/metagen_base/metagen_base_arena.h | 19 +- .../metagen_base/metagen_base_command_line.c | 24 +- .../metagen_base/metagen_base_command_line.h | 2 + .../metagen_base_context_cracking.h | 6 +- src/metagen/metagen_base/metagen_base_core.c | 114 ++- src/metagen/metagen_base/metagen_base_core.h | 160 ++++- .../metagen_base/metagen_base_entry_point.c | 78 ++- .../metagen_base/metagen_base_entry_point.h | 4 +- src/metagen/metagen_base/metagen_base_inc.c | 5 +- src/metagen/metagen_base/metagen_base_inc.h | 1 + src/metagen/metagen_base/metagen_base_log.c | 2 +- src/metagen/metagen_base/metagen_base_math.c | 61 +- src/metagen/metagen_base/metagen_base_math.h | 26 + src/metagen/metagen_base/metagen_base_meta.c | 422 +++++++++++ src/metagen/metagen_base/metagen_base_meta.h | 298 ++++++++ .../metagen_base/metagen_base_profile.h | 50 +- .../metagen_base/metagen_base_strings.c | 661 +++++++++++++++--- .../metagen_base/metagen_base_strings.h | 39 +- .../metagen_base_thread_context.h | 2 +- src/metagen/metagen_main.c | 18 +- .../core/win32/metagen_os_core_win32.c | 2 +- src/raddbg/generated/raddbg.meta.c | 124 +--- src/raddbg/generated/raddbg.meta.h | 31 +- src/raddbg/raddbg.mdesk | 167 +++-- src/raddbg/raddbg_core.c | 152 ++-- src/raddbg/raddbg_core.h | 11 +- src/raddbg/raddbg_views.c | 6 +- src/raddbg/raddbg_widgets.c | 14 +- src/rdi_format/rdi_format.mdesk | 2 +- 32 files changed, 2014 insertions(+), 592 deletions(-) create mode 100644 src/metagen/metagen_base/metagen_base_meta.c create mode 100644 src/metagen/metagen_base/metagen_base_meta.h diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index f440f03c..65f75c1e 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -50,7 +50,7 @@ typedef int64_t RDI_S64; //////////////////////////////////////////////////////////////// //~ Format Constants -// \"raddbg\0\0\" +// "raddbg\0\0" #define RDI_MAGIC_CONSTANT 0x0000676264646172 #define RDI_ENCODING_VERSION 10 diff --git a/src/metagen/metagen.c b/src/metagen/metagen.c index 4d68bf5a..33c4daa7 100644 --- a/src/metagen/metagen.c +++ b/src/metagen/metagen.c @@ -686,8 +686,8 @@ mg_string_from_row_desc_idx(MD_Node *row_parent, MG_ColumnDescArray descs, U64 i cell_idx -= 1; } } - MD_Node *node = md_child_from_index(row_parent, cell_idx); - result = node->string; + MD_Node *node = md_child_from_index(row_parent, cell_idx); + result = node->string; }break; case MG_ColumnKind_CheckForTag: @@ -828,8 +828,8 @@ mg_eval_table_expand_expr__string(Arena *arena, MG_StrExpr *expr, MG_TableExpand }break; case MG_StrExprOp_Null: - { - str8_list_push(arena, out, expr->node->string); + { + str8_list_push(arena, out, expr->node->string); }break; case MG_StrExprOp_Dot: @@ -900,7 +900,14 @@ mg_eval_table_expand_expr__string(Arena *arena, MG_StrExpr *expr, MG_TableExpand } // rjf: push lookup string - { + { + B32 is_multiline = (str8_find_needle(lookup_string, 0, str8_lit("\n"), 0) < lookup_string.size); + if(is_multiline) + { + lookup_string = indented_from_string(mg_arena, lookup_string); + lookup_string = escaped_from_raw_str8(mg_arena, lookup_string); + lookup_string = escaped_from_raw_str8(mg_arena, lookup_string); + } str8_list_push(arena, out, lookup_string); } }break; @@ -1010,9 +1017,10 @@ mg_loop_table_column_expansion(Arena *arena, String8 strexpr, MG_TableExpandInfo char_idx += 1; } } - String8 expansion_str = str8_list_join(arena, &expansion_strs, 0); + String8 expansion_str = str8_list_join(arena, &expansion_strs, 0); if(expansion_str.size != 0) - { + { + expansion_str = raw_from_escaped_str8(mg_arena, expansion_str); str8_list_push(arena, out, expansion_str); } } @@ -1028,7 +1036,7 @@ mg_string_list_from_table_gen(Arena *arena, MG_Map grid_name_map, MG_Map grid_co Temp scratch = scratch_begin(&arena, 1); if(md_node_is_nil(gen->first) && gen->string.size != 0) { - str8_list_push(arena, &result, gen->string); + str8_list_push(arena, &result, raw_from_escaped_str8(arena, gen->string)); str8_list_push(arena, &result, str8_lit("\n")); } else for MD_EachNode(strexpr_node, gen->first) @@ -1080,7 +1088,7 @@ mg_string_list_from_table_gen(Arena *arena, MG_Map grid_name_map, MG_Map grid_co } else { - str8_list_push(arena, &result, strexpr_node->string); + str8_list_push(arena, &result, raw_from_escaped_str8(arena, strexpr_node->string)); } } } diff --git a/src/metagen/metagen_base/metagen_base_arena.c b/src/metagen/metagen_base/metagen_base_arena.c index 28eb6e83..68ad2544 100644 --- a/src/metagen/metagen_base/metagen_base_arena.c +++ b/src/metagen/metagen_base/metagen_base_arena.c @@ -52,12 +52,16 @@ arena_alloc_(ArenaParams *params) Arena *arena = (Arena *)base; arena->current = arena; arena->flags = params->flags; - arena->cmt_size = (U32)params->commit_size; + arena->cmt_size = params->commit_size; arena->res_size = params->reserve_size; arena->base_pos = 0; arena->pos = ARENA_HEADER_SIZE; arena->cmt = commit_size; arena->res = reserve_size; +#if ARENA_FREE_LIST + arena->free_size = 0; + arena->free_last = 0; +#endif AsanPoisonMemoryRegion(base, commit_size); AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE); return arena; @@ -85,30 +89,67 @@ arena_push(Arena *arena, U64 size, U64 align) // rjf: chain, if needed if(current->res < pos_pst && !(arena->flags & ArenaFlag_NoChain)) { - U64 res_size = current->res_size; - U64 cmt_size = current->cmt_size; - if(size + ARENA_HEADER_SIZE > res_size) + Arena *new_block = 0; + +#if ARENA_FREE_LIST + Arena *prev_block; + for(new_block = arena->free_last, prev_block = 0; new_block != 0; prev_block = new_block, new_block = new_block->prev) { - res_size = size + ARENA_HEADER_SIZE; - cmt_size = size + ARENA_HEADER_SIZE; + if(new_block->res >= AlignPow2(size, align)) + { + if(prev_block) + { + prev_block->prev = new_block->prev; + } + else + { + arena->free_last = new_block->prev; + } + arena->free_size -= new_block->res_size; + AsanUnpoisonMemoryRegion((U8*)new_block + ARENA_HEADER_SIZE, new_block->res_size - ARENA_HEADER_SIZE); + break; + } } - Arena *new_block = arena_alloc(.reserve_size = res_size, - .commit_size = cmt_size, - .flags = current->flags); +#endif + + if(new_block == 0) + { + U64 res_size = current->res_size; + U64 cmt_size = current->cmt_size; + if(size + ARENA_HEADER_SIZE > res_size) + { + res_size = AlignPow2(size + ARENA_HEADER_SIZE, align); + cmt_size = AlignPow2(size + ARENA_HEADER_SIZE, align); + } + new_block = arena_alloc(.reserve_size = res_size, + .commit_size = cmt_size, + .flags = current->flags); + } + new_block->base_pos = current->base_pos + current->res; SLLStackPush_N(arena->current, new_block, prev); + current = new_block; pos_pre = AlignPow2(current->pos, align); pos_pst = pos_pre + size; } // rjf: commit new pages, if needed - if(current->cmt < pos_pst && !(current->flags & ArenaFlag_LargePages)) + if(current->cmt < pos_pst) { - U64 cmt_pst_aligned = AlignPow2(pos_pst, current->cmt_size); + U64 cmt_pst_aligned = pos_pst + current->cmt_size-1; + cmt_pst_aligned -= cmt_pst_aligned%current->cmt_size; U64 cmt_pst_clamped = ClampTop(cmt_pst_aligned, current->res); U64 cmt_size = cmt_pst_clamped - current->cmt; - os_commit((U8 *)current + current->cmt, cmt_size); + U8 *cmt_ptr = (U8 *)current + current->cmt; + if(current->flags & ArenaFlag_LargePages) + { + os_commit_large(cmt_ptr, cmt_size); + } + else + { + os_commit(cmt_ptr, cmt_size); + } current->cmt = cmt_pst_clamped; } @@ -146,11 +187,23 @@ arena_pop_to(Arena *arena, U64 pos) { U64 big_pos = ClampBot(ARENA_HEADER_SIZE, pos); Arena *current = arena->current; + +#if ARENA_FREE_LIST + for(Arena *prev = 0; current->base_pos >= big_pos; current = prev) + { + prev = current->prev; + current->pos = ARENA_HEADER_SIZE; + arena->free_size += current->res_size; + SLLStackPush_N(arena->free_last, current, prev); + AsanPoisonMemoryRegion((U8*)current + ARENA_HEADER_SIZE, current->res_size - ARENA_HEADER_SIZE); + } +#else for(Arena *prev = 0; current->base_pos >= big_pos; current = prev) { prev = current->prev; os_release(current, current->res); } +#endif arena->current = current; U64 new_pos = big_pos - current->base_pos; AssertAlways(new_pos <= current->pos); diff --git a/src/metagen/metagen_base/metagen_base_arena.h b/src/metagen/metagen_base/metagen_base_arena.h index f941bcd7..8696f49f 100644 --- a/src/metagen/metagen_base/metagen_base_arena.h +++ b/src/metagen/metagen_base/metagen_base_arena.h @@ -7,12 +7,12 @@ //////////////////////////////// //~ rjf: Constants -#define ARENA_HEADER_SIZE 64 +#define ARENA_HEADER_SIZE 128 //////////////////////////////// //~ rjf: Types -typedef U32 ArenaFlags; +typedef U64 ArenaFlags; enum { ArenaFlag_NoChain = (1<<0), @@ -34,12 +34,16 @@ struct Arena Arena *prev; // previous arena in chain Arena *current; // current arena in chain ArenaFlags flags; - U32 cmt_size; + U64 cmt_size; U64 res_size; U64 base_pos; U64 pos; U64 cmt; U64 res; +#if ARENA_FREE_LIST + U64 free_size; + Arena *free_last; +#endif }; StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check); @@ -50,12 +54,19 @@ struct Temp U64 pos; }; +//////////////////////////////// +//~ rjf: Global Defaults + +global U64 arena_default_reserve_size = MB(64); +global U64 arena_default_commit_size = KB(64); +global ArenaFlags arena_default_flags = 0; + //////////////////////////////// //~ rjf: Arena Functions //- rjf: arena creation/destruction internal Arena *arena_alloc_(ArenaParams *params); -#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__}) +#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, __VA_ARGS__}) internal void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions diff --git a/src/metagen/metagen_base/metagen_base_command_line.c b/src/metagen/metagen_base/metagen_base_command_line.c index ecf23745..ec726752 100644 --- a/src/metagen/metagen_base/metagen_base_command_line.c +++ b/src/metagen/metagen_base/metagen_base_command_line.c @@ -98,9 +98,10 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) next = node->next; String8 option_name = node->string; - // NOTE(rjf): Look at -- or - at the start of an argument to determine if it's - // a flag option. All arguments after a single "--" (with no trailing string - // on the command line will be considered as input files. + // NOTE(rjf): Look at --, -, or / (only on Windows) at the start of an + // argument to determine if it's a flag option. All arguments after a + // single "--" (with no trailing string on the command line will be + // considered as input files. B32 is_option = 1; if(after_passthrough_option == 0) { @@ -117,6 +118,11 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) { option_name = str8_skip(option_name, 1); } + else if(operating_system_from_context() == OperatingSystem_Windows && + str8_match(str8_prefix(node->string, 1), str8_lit("/"), 0)) + { + option_name = str8_skip(option_name, 1); + } else { is_option = 0; @@ -184,6 +190,18 @@ cmd_line_from_string_list(Arena *arena, String8List command_line) } } + // rjf: fill argc/argv + parsed.argc = command_line.node_count; + parsed.argv = push_array(arena, char *, parsed.argc); + { + U64 idx = 0; + for(String8Node *n = command_line.first; n != 0; n = n->next) + { + parsed.argv[idx] = (char *)push_str8_copy(arena, n->string).str; + idx += 1; + } + } + return parsed; } diff --git a/src/metagen/metagen_base/metagen_base_command_line.h b/src/metagen/metagen_base/metagen_base_command_line.h index c37f91dc..acd7f17b 100644 --- a/src/metagen/metagen_base/metagen_base_command_line.h +++ b/src/metagen/metagen_base/metagen_base_command_line.h @@ -34,6 +34,8 @@ struct CmdLine String8List inputs; U64 option_table_size; CmdLineOpt **option_table; + U64 argc; + char **argv; }; //////////////////////////////// diff --git a/src/metagen/metagen_base/metagen_base_context_cracking.h b/src/metagen/metagen_base/metagen_base_context_cracking.h index 040c0004..bac701dd 100644 --- a/src/metagen/metagen_base/metagen_base_context_cracking.h +++ b/src/metagen/metagen_base/metagen_base_context_cracking.h @@ -155,11 +155,11 @@ #endif #if !defined(BUILD_VERSION_MINOR) -# define BUILD_VERSION_MINOR 0 +# define BUILD_VERSION_MINOR 9 #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 0 +# define BUILD_VERSION_PATCH 14 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) @@ -183,7 +183,7 @@ #endif #if !defined(BUILD_ISSUES_LINK_STRING_LITERAL) -# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGames/raddebugger/issues" +# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGamesExt/raddebugger/issues" #endif #define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND diff --git a/src/metagen/metagen_base/metagen_base_core.c b/src/metagen/metagen_base/metagen_base_core.c index 877dcb4e..b392e4a0 100644 --- a/src/metagen/metagen_base/metagen_base_core.c +++ b/src/metagen/metagen_base/metagen_base_core.c @@ -143,12 +143,6 @@ bswap_u64(U64 x) #if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) -internal U64 -count_bits_set16(U16 val) -{ - return __popcnt16(val); -} - internal U64 count_bits_set32(U32 val) { @@ -195,46 +189,40 @@ clz64(U64 mask) #elif COMPILER_CLANG || COMPILER_GCC -internal U64 -count_bits_set16(U16 val) -{ - NotImplemented; - return 0; -} - internal U64 count_bits_set32(U32 val) { - NotImplemented; - return 0; + return __builtin_popcount(val); } internal U64 count_bits_set64(U64 val) { - NotImplemented; - return 0; + return __builtin_popcountll(val); } internal U64 ctz32(U32 val) { - NotImplemented; - return 0; + return __builtin_ctz(val); } internal U64 clz32(U32 val) { - NotImplemented; - return 0; + return __builtin_clz(val); +} + +internal U64 +ctz64(U64 val) +{ + return __builtin_ctzll(val); } internal U64 clz64(U64 val) { - NotImplemented; - return 0; + return __builtin_clzll(val); } #else @@ -399,23 +387,23 @@ txt_rng_contains(TxtRng r, TxtPt pt) //~ rjf: Toolchain/Environment Enum Functions internal U64 -bit_size_from_arch(Architecture arch) +bit_size_from_arch(Arch arch) { // TODO(rjf): metacode U64 arch_bitsize = 0; switch(arch) { - case Architecture_x64: arch_bitsize = 64; break; - case Architecture_x86: arch_bitsize = 32; break; - case Architecture_arm64: arch_bitsize = 64; break; - case Architecture_arm32: arch_bitsize = 32; break; + case Arch_x64: arch_bitsize = 64; break; + case Arch_x86: arch_bitsize = 32; break; + case Arch_arm64: arch_bitsize = 64; break; + case Arch_arm32: arch_bitsize = 32; break; default: break; } return arch_bitsize; } internal U64 -max_instruction_size_from_arch(Architecture arch) +max_instruction_size_from_arch(Arch arch) { // TODO(rjf): make this real return 64; @@ -434,17 +422,17 @@ operating_system_from_context(void){ return os; } -internal Architecture -architecture_from_context(void){ - Architecture arch = Architecture_Null; +internal Arch +arch_from_context(void){ + Arch arch = Arch_Null; #if ARCH_X64 - arch = Architecture_x64; + arch = Arch_x64; #elif ARCH_X86 - arch = Architecture_x86; + arch = Arch_x86; #elif ARCH_ARM64 - arch = Architecture_arm64; + arch = Arch_arm64; #elif ARCH_ARM32 - arch = Architecture_arm32; + arch = Arch_arm32; #endif return arch; } @@ -526,6 +514,60 @@ date_time_from_micro_seconds(U64 time){ return(result); } +internal DateTime +date_time_from_unix_time(U64 unix_time) +{ + DateTime date = {0}; + date.year = 1970; + date.day = 1 + (unix_time / 86400); + date.sec = (U32)unix_time % 60; + date.min = (U32)(unix_time / 60) % 60; + date.hour = (U32)(unix_time / 3600) % 24; + + for(;;) + { + for(date.month = 0; date.month < 12; ++date.month) + { + U64 c = 0; + switch(date.month) + { + case Month_Jan: c = 31; break; + case Month_Feb: + { + if((date.year % 4 == 0) && ((date.year % 100) != 0 || (date.year % 400) == 0)) + { + c = 29; + } + else + { + c = 28; + } + } break; + case Month_Mar: c = 31; break; + case Month_Apr: c = 30; break; + case Month_May: c = 31; break; + case Month_Jun: c = 30; break; + case Month_Jul: c = 31; break; + case Month_Aug: c = 31; break; + case Month_Sep: c = 30; break; + case Month_Oct: c = 31; break; + case Month_Nov: c = 30; break; + case Month_Dec: c = 31; break; + default: InvalidPath; + } + if(date.day <= c) + { + goto exit; + } + date.day -= c; + } + ++date.year; + } + exit:; + + return date; +} + //////////////////////////////// //~ rjf: Non-Fancy Ring Buffer Reads/Writes diff --git a/src/metagen/metagen_base/metagen_base_core.h b/src/metagen/metagen_base/metagen_base_core.h index b2483870..191e1e7f 100644 --- a/src/metagen/metagen_base/metagen_base_core.h +++ b/src/metagen/metagen_base/metagen_base_core.h @@ -40,6 +40,12 @@ # define thread_static __thread #endif +#if COMPILER_MSVC +# define force_inline __forceinline +#elif COMPILER_CLANG || COMPILER_GCC +# define force_inline __attribute__((always_inline)) +#endif + //////////////////////////////// //~ rjf: Linkage Keyword Macros @@ -118,8 +124,10 @@ #define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) #define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end)) -#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1) -#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1) +#define EachIndex(it, count) (U64 it = 0; it < (count); it += 1) +#define EachElement(it, array) (U64 it = 0; it < ArrayCount(array); it += 1) +#define EachEnumVal(type, it) (type it = (type)0; it < type##_COUNT; it = (type)(it+1)) +#define EachNonZeroEnumVal(type, it) (type it = (type)1; it < type##_COUNT; it = (type)(it+1)) //////////////////////////////// //~ rjf: Memory Operation Macros @@ -170,33 +178,49 @@ //////////////////////////////// //~ rjf: Atomic Operations -#if OS_WINDOWS -# include -# include -# include +#if COMPILER_MSVC # include # if ARCH_X64 -# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0) -# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) -# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) +# define ins_atomic_u64_eval(x) *((volatile U64 *)(x)) +# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) +# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) # define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x),(k),(c)) -# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) -# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) +# define ins_atomic_u32_eval(x) *((volatile U32 *)(x)) +# define ins_atomic_u32_inc_eval(x) InterlockedIncrement((volatile LONG *)x) +# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) # define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c)) -# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c)) +# define ins_atomic_u32_add_eval(x,c) InterlockedAdd((volatile LONG *)(x), c) # else -# error Atomic intrinsics not defined for this operating system / architecture combination. -# endif -#elif OS_LINUX -# if ARCH_X64 -# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) -# else -# error Atomic intrinsics not defined for this operating system / architecture combination. +# error Atomic intrinsics not defined for this compiler / architecture combination. # endif +#elif COMPILER_CLANG || COMPILER_GCC +# define ins_atomic_u64_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_inc_eval(x) (__atomic_fetch_add((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u64_dec_eval(x) (__atomic_fetch_sub((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) - 1) +# define ins_atomic_u64_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_add_eval(x,c) (__atomic_fetch_add((volatile U64 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u64_eval_cond_assign(x,k,c) ({ U64 _new = (c); __atomic_compare_exchange_n((volatile U64 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) +# define ins_atomic_u32_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_inc_eval(x) (__atomic_fetch_add((volatile U32 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u32_add_eval(x,c) (__atomic_fetch_add((volatile U32 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u32_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_eval_cond_assign(x,k,c) ({ U32 _new = (c); __atomic_compare_exchange_n((volatile U32 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) #else -# error Atomic intrinsics not defined for this operating system. +# error Atomic intrinsics not defined for this compiler / architecture. +#endif + +#if ARCH_64BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u64_eval_cond_assign((volatile U64 *)(x), (U64)(k), (U64)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile U64 *)(x), (U64)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u64_eval((volatile U64 *)x) +#elif ARCH_32BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u32_eval_cond_assign((volatile U32 *)(x), (U32)(k), (U32)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u32_eval_assign((volatile U32 *)(x), (U32)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u32_eval((volatile U32 *)x) +#else +# error Atomic intrinsics for pointers not defined for this architecture. #endif //////////////////////////////// @@ -430,16 +454,25 @@ typedef enum OperatingSystem } OperatingSystem; -typedef enum Architecture +typedef enum ImageType { - Architecture_Null, - Architecture_x64, - Architecture_x86, - Architecture_arm64, - Architecture_arm32, - Architecture_COUNT, + Image_Null, + Image_CoffPe, + Image_Elf32, + Image_Elf64, + Image_Macho +} ImageType; + +typedef enum Arch +{ + Arch_Null, + Arch_x64, + Arch_x86, + Arch_arm64, + Arch_arm32, + Arch_COUNT, } -Architecture; +Arch; typedef enum Compiler { @@ -468,6 +501,51 @@ struct TxtRng TxtPt max; }; +//////////////////////////////// +//~ Globally Unique Ids + +typedef union Guid Guid; +union Guid +{ + struct + { + U32 data1; + U16 data2; + U16 data3; + U8 data4[8]; + }; + U8 v[16]; +}; +StaticAssert(sizeof(Guid) == 16, g_guid_size_check); + +//////////////////////////////// +//~ Arrays + +typedef struct U16Array U16Array; +struct U16Array +{ + U64 count; + U16 *v; +}; +typedef struct U32Array U32Array; +struct U32Array +{ + U64 count; + U32 *v; +}; +typedef struct U64Array U64Array; +struct U64Array +{ + U64 count; + U64 *v; +}; +typedef struct U128Array U128Array; +struct U128Array +{ + U64 count; + U128 *v; +}; + //////////////////////////////// //~ NOTE(allen): Constants @@ -734,7 +812,16 @@ internal U16 bswap_u16(U16 x); internal U32 bswap_u32(U32 x); internal U64 bswap_u64(U64 x); -internal U64 count_bits_set16(U16 val); +#if ARCH_LITTLE_ENDIAN +# define from_be_u16(x) bswap_u16(x) +# define from_be_u32(x) bswap_u32(x) +# define from_be_u64(x) bswap_u64(x) +#else +# define from_be_u16(x) (x) +# define from_be_u32(x) (x) +# define from_be_u64(x) (x) +#endif + internal U64 count_bits_set32(U32 val); internal U64 count_bits_set64(U64 val); @@ -770,19 +857,20 @@ internal B32 txt_rng_contains(TxtRng r, TxtPt pt); //////////////////////////////// //~ rjf: Toolchain/Environment Enum Functions -internal U64 bit_size_from_arch(Architecture arch); -internal U64 max_instruction_size_from_arch(Architecture arch); +internal U64 bit_size_from_arch(Arch arch); +internal U64 max_instruction_size_from_arch(Arch arch); internal OperatingSystem operating_system_from_context(void); -internal Architecture architecture_from_context(void); +internal Arch arch_from_context(void); internal Compiler compiler_from_context(void); //////////////////////////////// //~ rjf: Time Functions internal DenseTime dense_time_from_date_time(DateTime date_time); -internal DateTime date_time_from_dense_time(DenseTime time); -internal DateTime date_time_from_micro_seconds(U64 time); +internal DateTime date_time_from_dense_time(DenseTime time); +internal DateTime date_time_from_micro_seconds(U64 time); +internal DateTime date_time_from_unix_time(U64 unix_time); //////////////////////////////// //~ rjf: Non-Fancy Ring Buffer Reads/Writes diff --git a/src/metagen/metagen_base/metagen_base_entry_point.c b/src/metagen/metagen_base/metagen_base_entry_point.c index 498ec0b5..21bbc363 100644 --- a/src/metagen/metagen_base/metagen_base_entry_point.c +++ b/src/metagen/metagen_base/metagen_base_entry_point.c @@ -1,26 +1,43 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +global U64 global_update_tick_idx = 0; + internal void -main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count) +main_thread_base_entry_point(int arguments_count, char **arguments) { + Temp scratch = scratch_begin(0, 0); + ThreadNameF("[main thread]"); + + //- rjf: set up telemetry #if PROFILE_TELEMETRY - local_persist U8 tm_data[MB(64)]; + local_persist char tm_data[MB(64)]; tmLoadLibrary(TM_RELEASE); tmSetMaxThreadCount(256); - tmInitialize(sizeof(tm_data), (char *)tm_data); + tmInitialize(sizeof(tm_data), tm_data); #endif - ThreadNameF("[main thread]"); - Temp scratch = scratch_begin(0, 0); - String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments); + + //- rjf: parse command line + String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, arguments_count, arguments); CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings); + + //- rjf: begin captures B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture")); if(capture) { ProfBeginCapture(arguments[0]); } -#if defined(TASK_SYSTEM_H) && !defined(TS_INIT_MANUAL) - ts_init(); + +#if PROFILE_TELEMETRY + tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE); +#endif + + //- rjf: initialize all included layers +#if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL) + async_init(&cmdline); +#endif +#if defined(RDI_FROM_PDB_H) && !defined(P2R_INIT_MANUAL) + p2r_init(); #endif #if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL) hs_init(); @@ -37,19 +54,16 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum #if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL) dasm_init(); #endif -#if defined(DI_H) && !defined(DI_INIT_MANUAL) +#if defined(DBGI_H) && !defined(DI_INIT_MANUAL) di_init(); #endif -#if defined(FUZZY_SEARCH_H) && !defined(FZY_INIT_MANUAL) - fzy_init(); -#endif #if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL) dmn_init(); #endif #if defined(CTRL_CORE_H) && !defined(CTRL_INIT_MANUAL) ctrl_init(); #endif -#if defined(OS_GRAPHICAL_H) && !defined(OS_GFX_INIT_MANUAL) +#if defined(OS_GFX_H) && !defined(OS_GFX_INIT_MANUAL) os_gfx_init(); #endif #if defined(FONT_PROVIDER_H) && !defined(FP_INIT_MANUAL) @@ -64,21 +78,25 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum #if defined(GEO_CACHE_H) && !defined(GEO_INIT_MANUAL) geo_init(); #endif -#if defined(FONT_CACHE_H) && !defined(F_INIT_MANUAL) - f_init(); +#if defined(FONT_CACHE_H) && !defined(FNT_INIT_MANUAL) + fnt_init(); #endif -#if defined(DF_CORE_H) && !defined(DF_INIT_MANUAL) - DF_StateDeltaHistory *hist = df_state_delta_history_alloc(); - df_core_init(&cmdline, hist); +#if defined(DBG_ENGINE_CORE_H) && !defined(D_INIT_MANUAL) + d_init(); #endif -#if defined(DF_GFX_H) && !defined(DF_GFX_INIT_MANUAL) - df_gfx_init(update_and_render, df_state_delta_history()); +#if defined(RADDBG_CORE_H) && !defined(RD_INIT_MANUAL) + rd_init(&cmdline); #endif + + //- rjf: call into entry point entry_point(&cmdline); + + //- rjf: end captures if(capture) { ProfEndCapture(); } + scratch_end(scratch); } @@ -90,3 +108,23 @@ supplement_thread_base_entry_point(void (*entry_point)(void *params), void *para entry_point(params); tctx_release(); } + +internal U64 +update_tick_idx(void) +{ + U64 result = ins_atomic_u64_eval(&global_update_tick_idx); + return result; +} + +internal B32 +update(void) +{ + ProfTick(0); + ins_atomic_u64_inc_eval(&global_update_tick_idx); +#if OS_FEATURE_GRAPHICAL + B32 result = frame(); +#else + B32 result = 0; +#endif + return result; +} diff --git a/src/metagen/metagen_base/metagen_base_entry_point.h b/src/metagen/metagen_base/metagen_base_entry_point.h index 560bdcc7..318f8d9f 100644 --- a/src/metagen/metagen_base/metagen_base_entry_point.h +++ b/src/metagen/metagen_base/metagen_base_entry_point.h @@ -4,7 +4,9 @@ #ifndef BASE_ENTRY_POINT_H #define BASE_ENTRY_POINT_H -internal void main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count); +internal void main_thread_base_entry_point(int argc, char **argv); internal void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params); +internal U64 update_tick_idx(void); +internal B32 update(void); #endif // BASE_ENTRY_POINT_H diff --git a/src/metagen/metagen_base/metagen_base_inc.c b/src/metagen/metagen_base/metagen_base_inc.c index 74dcfe02..57aa2113 100644 --- a/src/metagen/metagen_base/metagen_base_inc.c +++ b/src/metagen/metagen_base/metagen_base_inc.c @@ -4,8 +4,8 @@ //////////////////////////////// //~ rjf: Base Includes -#undef RADDBG_LAYER_COLOR -#define RADDBG_LAYER_COLOR 0.20f, 0.60f, 0.80f +#undef MARKUP_LAYER_COLOR +#define MARKUP_LAYER_COLOR 0.20f, 0.60f, 0.80f #include "metagen_base_core.c" #include "metagen_base_profile.c" @@ -15,5 +15,6 @@ #include "metagen_base_thread_context.c" #include "metagen_base_command_line.c" #include "metagen_base_markup.c" +#include "metagen_base_meta.c" #include "metagen_base_log.c" #include "metagen_base_entry_point.c" diff --git a/src/metagen/metagen_base/metagen_base_inc.h b/src/metagen/metagen_base/metagen_base_inc.h index 88aa65f7..55e2ebe7 100644 --- a/src/metagen/metagen_base/metagen_base_inc.h +++ b/src/metagen/metagen_base/metagen_base_inc.h @@ -17,6 +17,7 @@ #include "metagen_base_thread_context.h" #include "metagen_base_command_line.h" #include "metagen_base_markup.h" +#include "metagen_base_meta.h" #include "metagen_base_log.h" #include "metagen_base_entry_point.h" diff --git a/src/metagen/metagen_base/metagen_base_log.c b/src/metagen/metagen_base/metagen_base_log.c index 418b29ff..1c2a05f8 100644 --- a/src/metagen/metagen_base/metagen_base_log.c +++ b/src/metagen/metagen_base/metagen_base_log.c @@ -88,7 +88,7 @@ log_scope_end(Arena *arena) SLLStackPop(log_active->top_scope); if(arena != 0) { - for(EachEnumVal(LogMsgKind, kind)) + for EachEnumVal(LogMsgKind, kind) { Temp scratch = scratch_begin(&arena, 1); String8 result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0); diff --git a/src/metagen/metagen_base/metagen_base_math.c b/src/metagen/metagen_base/metagen_base_math.c index 465d342d..2c6201f3 100644 --- a/src/metagen/metagen_base/metagen_base_math.c +++ b/src/metagen/metagen_base/metagen_base_math.c @@ -394,7 +394,7 @@ internal Rng1U32 shift_1u32(Rng1U32 r, U32 x) {r.min += x; r.m internal Rng1U32 pad_1u32(Rng1U32 r, U32 x) {r.min -= x; r.max += x; return r;} internal U32 center_1u32(Rng1U32 r) {U32 c = (r.min+r.max)/2; return c;} internal B32 contains_1u32(Rng1U32 r, U32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal U32 dim_1u32(Rng1U32 r) {U32 c = r.max-r.min; return c;} +internal U32 dim_1u32(Rng1U32 r) {U32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1U32 union_1u32(Rng1U32 a, Rng1U32 b) {Rng1U32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1U32 intersect_1u32(Rng1U32 a, Rng1U32 b) {Rng1U32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal U32 clamp_1u32(Rng1U32 r, U32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -404,7 +404,7 @@ internal Rng1S32 shift_1s32(Rng1S32 r, S32 x) {r.min += x; r.m internal Rng1S32 pad_1s32(Rng1S32 r, S32 x) {r.min -= x; r.max += x; return r;} internal S32 center_1s32(Rng1S32 r) {S32 c = (r.min+r.max)/2; return c;} internal B32 contains_1s32(Rng1S32 r, S32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal S32 dim_1s32(Rng1S32 r) {S32 c = r.max-r.min; return c;} +internal S32 dim_1s32(Rng1S32 r) {S32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1S32 union_1s32(Rng1S32 a, Rng1S32 b) {Rng1S32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1S32 intersect_1s32(Rng1S32 a, Rng1S32 b) {Rng1S32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal S32 clamp_1s32(Rng1S32 r, S32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -414,7 +414,7 @@ internal Rng1U64 shift_1u64(Rng1U64 r, U64 x) {r.min += x; r.m internal Rng1U64 pad_1u64(Rng1U64 r, U64 x) {r.min -= x; r.max += x; return r;} internal U64 center_1u64(Rng1U64 r) {U64 c = (r.min+r.max)/2; return c;} internal B32 contains_1u64(Rng1U64 r, U64 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal U64 dim_1u64(Rng1U64 r) {U64 c = r.max-r.min; return c;} +internal U64 dim_1u64(Rng1U64 r) {U64 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1U64 union_1u64(Rng1U64 a, Rng1U64 b) {Rng1U64 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1U64 intersect_1u64(Rng1U64 a, Rng1U64 b) {Rng1U64 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal U64 clamp_1u64(Rng1U64 r, U64 v) {v = Clamp(r.min, v, r.max); return v;} @@ -424,7 +424,7 @@ internal Rng1S64 shift_1s64(Rng1S64 r, S64 x) {r.min += x; r.m internal Rng1S64 pad_1s64(Rng1S64 r, S64 x) {r.min -= x; r.max += x; return r;} internal S64 center_1s64(Rng1S64 r) {S64 c = (r.min+r.max)/2; return c;} internal B32 contains_1s64(Rng1S64 r, S64 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal S64 dim_1s64(Rng1S64 r) {S64 c = r.max-r.min; return c;} +internal S64 dim_1s64(Rng1S64 r) {S64 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1S64 union_1s64(Rng1S64 a, Rng1S64 b) {Rng1S64 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1S64 intersect_1s64(Rng1S64 a, Rng1S64 b) {Rng1S64 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal S64 clamp_1s64(Rng1S64 r, S64 v) {v = Clamp(r.min, v, r.max); return v;} @@ -434,7 +434,7 @@ internal Rng1F32 shift_1f32(Rng1F32 r, F32 x) {r.min += x; r.m internal Rng1F32 pad_1f32(Rng1F32 r, F32 x) {r.min -= x; r.max += x; return r;} internal F32 center_1f32(Rng1F32 r) {F32 c = (r.min+r.max)/2; return c;} internal B32 contains_1f32(Rng1F32 r, F32 x) {B32 c = (r.min <= x && x < r.max); return c;} -internal F32 dim_1f32(Rng1F32 r) {F32 c = r.max-r.min; return c;} +internal F32 dim_1f32(Rng1F32 r) {F32 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;} internal Rng1F32 union_1f32(Rng1F32 a, Rng1F32 b) {Rng1F32 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;} internal Rng1F32 intersect_1f32(Rng1F32 a, Rng1F32 b) {Rng1F32 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;} internal F32 clamp_1f32(Rng1F32 r, F32 v) {v = Clamp(r.min, v, r.max); return v;} @@ -444,7 +444,7 @@ internal Rng2S16 shift_2s16(Rng2S16 r, Vec2S16 x) {r.min = add_2s1 internal Rng2S16 pad_2s16(Rng2S16 r, S16 x) {Vec2S16 xv = {x, x}; r.min = sub_2s16(r.min, xv); r.max = add_2s16(r.max, xv); return r;} internal Vec2S16 center_2s16(Rng2S16 r) {Vec2S16 c = {(S16)((r.min.x+r.max.x)/2), (S16)((r.min.y+r.max.y)/2)}; return c;} internal B32 contains_2s16(Rng2S16 r, Vec2S16 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S16 dim_2s16(Rng2S16 r) {Vec2S16 dim = {(S16)(r.max.x-r.min.x), (S16)(r.max.y-r.min.y)}; return dim;} +internal Vec2S16 dim_2s16(Rng2S16 r) {Vec2S16 dim = {(S16)(((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0)), (S16)(((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0))}; return dim;} internal Rng2S16 union_2s16(Rng2S16 a, Rng2S16 b) {Rng2S16 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S16 intersect_2s16(Rng2S16 a, Rng2S16 b) {Rng2S16 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S16 clamp_2s16(Rng2S16 r, Vec2S16 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -454,7 +454,7 @@ internal Rng2S32 shift_2s32(Rng2S32 r, Vec2S32 x) {r.min = add_2s3 internal Rng2S32 pad_2s32(Rng2S32 r, S32 x) {Vec2S32 xv = {x, x}; r.min = sub_2s32(r.min, xv); r.max = add_2s32(r.max, xv); return r;} internal Vec2S32 center_2s32(Rng2S32 r) {Vec2S32 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2s32(Rng2S32 r, Vec2S32 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S32 dim_2s32(Rng2S32 r) {Vec2S32 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2S32 dim_2s32(Rng2S32 r) {Vec2S32 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2S32 union_2s32(Rng2S32 a, Rng2S32 b) {Rng2S32 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S32 intersect_2s32(Rng2S32 a, Rng2S32 b) {Rng2S32 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S32 clamp_2s32(Rng2S32 r, Vec2S32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -464,7 +464,7 @@ internal Rng2S64 shift_2s64(Rng2S64 r, Vec2S64 x) {r.min = add_2s6 internal Rng2S64 pad_2s64(Rng2S64 r, S64 x) {Vec2S64 xv = {x, x}; r.min = sub_2s64(r.min, xv); r.max = add_2s64(r.max, xv); return r;} internal Vec2S64 center_2s64(Rng2S64 r) {Vec2S64 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2s64(Rng2S64 r, Vec2S64 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2S64 dim_2s64(Rng2S64 r) {Vec2S64 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2S64 dim_2s64(Rng2S64 r) {Vec2S64 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2S64 union_2s64(Rng2S64 a, Rng2S64 b) {Rng2S64 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2S64 intersect_2s64(Rng2S64 a, Rng2S64 b) {Rng2S64 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2S64 clamp_2s64(Rng2S64 r, Vec2S64 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -474,7 +474,7 @@ internal Rng2F32 shift_2f32(Rng2F32 r, Vec2F32 x) {r.min = add_2f3 internal Rng2F32 pad_2f32(Rng2F32 r, F32 x) {Vec2F32 xv = {x, x}; r.min = sub_2f32(r.min, xv); r.max = add_2f32(r.max, xv); return r;} internal Vec2F32 center_2f32(Rng2F32 r) {Vec2F32 c = {(r.min.x+r.max.x)/2, (r.min.y+r.max.y)/2}; return c;} internal B32 contains_2f32(Rng2F32 r, Vec2F32 x) {B32 c = (r.min.x <= x.x && x.x < r.max.x && r.min.y <= x.y && x.y < r.max.y); return c;} -internal Vec2F32 dim_2f32(Rng2F32 r) {Vec2F32 dim = {r.max.x-r.min.x, r.max.y-r.min.y}; return dim;} +internal Vec2F32 dim_2f32(Rng2F32 r) {Vec2F32 dim = {((r.max.x > r.min.x) ? (r.max.x - r.min.x) : 0), ((r.max.y > r.min.y) ? (r.max.y - r.min.y) : 0)}; return dim;} internal Rng2F32 union_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0.x = Min(a.min.x, b.min.x); c.p0.y = Min(a.min.y, b.min.y); c.p1.x = Max(a.max.x, b.max.x); c.p1.y = Max(a.max.y, b.max.y); return c;} internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0.x = Max(a.min.x, b.min.x); c.p0.y = Max(a.min.y, b.min.y); c.p1.x = Min(a.max.x, b.max.x); c.p1.y = Min(a.max.y, b.max.y); return c;} internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} @@ -591,6 +591,49 @@ u32_from_rgba(Vec4F32 rgba) //////////////////////////////// //~ rjf: List Type Functions +internal void +rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng) +{ + Rng1U64Node *n = push_array(arena, Rng1U64Node, 1); + MemoryCopyStruct(&n->v, &rng); + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal void +rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat) +{ + if(to_concat->first) + { + if(list->first) + { + list->last->next = to_concat->first; + list->last = to_concat->last; + } + else + { + list->first = to_concat->first; + list->last = to_concat->last; + } + MemoryZeroStruct(to_concat); + } +} + +internal Rng1U64Array +rng1u64_array_from_list(Arena *arena, Rng1U64List *list) +{ + Rng1U64Array arr = {0}; + arr.count = list->count; + arr.v = push_array_no_zero(arena, Rng1U64, arr.count); + U64 idx = 0; + for(Rng1U64Node *n = list->first; n != 0; n = n->next) + { + arr.v[idx] = n->v; + idx += 1; + } + return arr; +} + internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng) { diff --git a/src/metagen/metagen_base/metagen_base_math.h b/src/metagen/metagen_base/metagen_base_math.h index 645a6d31..b6063ad5 100644 --- a/src/metagen/metagen_base/metagen_base_math.h +++ b/src/metagen/metagen_base/metagen_base_math.h @@ -329,6 +329,28 @@ union Rng2S64 //////////////////////////////// //~ rjf: List Types +typedef struct Rng1U64Node Rng1U64Node; +struct Rng1U64Node +{ + Rng1U64Node *next; + Rng1U64 v; +}; + +typedef struct Rng1U64List Rng1U64List; +struct Rng1U64List +{ + U64 count; + Rng1U64Node *first; + Rng1U64Node *last; +}; + +typedef struct Rng1U64Array Rng1U64Array; +struct Rng1U64Array +{ + Rng1U64 *v; + U64 count; +}; + typedef struct Rng1S64Node Rng1S64Node; struct Rng1S64Node { @@ -643,6 +665,10 @@ internal U32 u32_from_rgba(Vec4F32 rgba); //////////////////////////////// //~ rjf: List Type Functions +internal void rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng); +internal void rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat); +internal Rng1U64Array rng1u64_array_from_list(Arena *arena, Rng1U64List *list); + internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng); internal Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list); diff --git a/src/metagen/metagen_base/metagen_base_meta.c b/src/metagen/metagen_base/metagen_base_meta.c new file mode 100644 index 00000000..c60dc237 --- /dev/null +++ b/src/metagen/metagen_base/metagen_base_meta.c @@ -0,0 +1,422 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Type Info Lookups + +internal Member * +member_from_name(Type *type, String8 name) +{ + Member *member = &member_nil; + if(type->members != 0 && name.size != 0) + { + for(U64 idx = 0; idx < type->count; idx += 1) + { + if(str8_match(type->members[idx].name, name, 0)) + { + member = &type->members[idx]; + break; + } + } + } + return member; +} + +//////////////////////////////// +//~ rjf: Type Info * Instance Operations + +internal void +typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr) +{ + Temp scratch = scratch_begin(0, 0); + typedef struct RebaseTypeTask RebaseTypeTask; + struct RebaseTypeTask + { + RebaseTypeTask *next; + Type *type; + U8 *ptr; + }; + RebaseTypeTask start_task = {0, type, data.str}; + RebaseTypeTask *first_task = &start_task; + RebaseTypeTask *last_task = first_task; + for(RebaseTypeTask *t = first_task; t != 0; t = t->next) + { + switch(t->type->kind) + { + default:{}break; + case TypeKind_Ptr: + if(!(t->type->flags & TypeFlag_IsExternal)) + { + *(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr)); + }break; + case TypeKind_Array: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = t->type->direct; + task->ptr = t->ptr + t->type->direct->size * idx; + SLLQueuePush(first_task, last_task, task); + } + }break; + case TypeKind_Struct: + { + for(U64 idx = 0; idx < t->type->count; idx += 1) + { + Member *member = &t->type->members[idx]; + RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1); + task->type = member->type; + task->ptr = t->ptr + member->value; + SLLQueuePush(first_task, last_task, task); + } + }break; + } + } + scratch_end(scratch); +} + +internal String8 +serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; + str8_serial_begin(scratch.arena, &strings); + { + typedef struct SerializeTypeTask SerializeTypeTask; + struct SerializeTypeTask + { + SerializeTypeTask *next; + Type *type; + U64 count; + U8 *src; + Type *containing_type; + U8 *containing_ptr; + B32 is_post_header; + }; + SerializeTypeTask start_task = {0, type, 1, data.str}; + SerializeTypeTask *first_task = &start_task; + SerializeTypeTask *last_task = first_task; + for(SerializeTypeTask *t = first_task; t != 0; t = t->next) + { + switch(t->type->kind) + { + //- rjf: leaf -> just copy the data directly + default: + if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf) + { + str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); + }break; + + //- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise just write as plain data + case TypeKind_Ptr: + { + // rjf: unpack info about this pointer + TypeSerializePtrRefInfo *ptr_ref_info = 0; + for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1) + { + if(params->ptr_ref_infos[idx].type == t->type->direct) + { + ptr_ref_info = ¶ms->ptr_ref_infos[idx]; + break; + } + } + + // rjf: indexification -> subtract base, divide direct size, write index + if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t->src, sizeof(ptr_value)); + U64 ptr_write_value = ((U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->indexify_base)/t->type->direct->size); + str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value); + } + + // rjf: offsetification -> subtract base, write offsets + else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t->src, sizeof(ptr_value)); + U64 ptr_write_value = (U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->offsetify_base); + str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value); + } + + // rjf: size-by-member (pre-header): still potentially dependent on other members which + // delimit our size, so push a new post-header task for pointer. + else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type; + task->count = t->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + task->is_post_header = 1; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: size-by-member (post-header): all flat parts of containing struct have been + // iterated, so now we can read the size, & descend to new task to read pointer + // destination contents + else if(t->type->count_delimiter_name.size != 0 && t->is_post_header) + { + // rjf: determine count of this pointer + U64 count = 0; + { + Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name); + MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size); + } + + // rjf: push task + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = count; + task->src = *(void **)t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: catch-all: write pointer value + else + { + str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); + } + }break; + + //- rjf: arrays -> descend to underlying type, + count + case TypeKind_Array: + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->type->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + + //- rjf: struct -> descend to members + case TypeKind_Struct: + { + U64 off = 0; + for(U64 idx = 0; idx < t->count; idx += 1) + { + for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1) + { + if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize) + { + continue; + } + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->members[member_idx].type; + task->count = 1; + task->src = t->src + idx*t->type->size + t->type->members[member_idx].value; + task->containing_type = t->type; + task->containing_ptr = t->src; + SLLQueuePush(first_task, last_task, task); + } + } + }break; + + //- rjf: enum -> descend to basic type interpretation + case TypeKind_Enum: + { + SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->count; + task->src = t->src; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + } + } + } + String8 result = str8_serial_end(arena, &strings); + scratch_end(scratch); + return result; +} + +internal String8 +deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + String8 result = {0}; + result.size = type->size; + result.str = push_array(arena, U8, result.size); + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct DeserializeTypeTask DeserializeTypeTask; + struct DeserializeTypeTask + { + DeserializeTypeTask *next; + Type *type; + U64 count; + U8 *dst; + Type *containing_type; + U8 *containing_ptr; + B32 is_post_header; + }; + U64 read_off = 0; + DeserializeTypeTask start_task = {0, type, 1, result.str}; + DeserializeTypeTask *first_task = &start_task; + DeserializeTypeTask *last_task = first_task; + for(DeserializeTypeTask *t = first_task; t != 0; t = t->next) + { + U8 *t_src = data.str + read_off; + switch(t->type->kind) + { + //- rjf: leaf -> copy the data directly + default: + if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf) + { + MemoryCopy(t->dst, t_src, t->type->size*t->count); + read_off += t->type->size*t->count; + }break; + + //- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise skip + case TypeKind_Ptr: + { + // rjf: unpack info about this pointer + TypeSerializePtrRefInfo *ptr_ref_info = 0; + for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1) + { + if(params->ptr_ref_infos[idx].type == t->type->direct) + { + ptr_ref_info = ¶ms->ptr_ref_infos[idx]; + break; + } + } + + // rjf: indexification -> add base, multiply direct size + if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t_src, sizeof(ptr_value)); + U64 ptr_write_value = (ptr_value + (U64)ptr_ref_info->indexify_base) * t->type->direct->size; + MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value)); + read_off += sizeof(ptr_value); + } + + // rjf: offsetification -> subtract base, write offsets + else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0) + { + U64 ptr_value = 0; + MemoryCopy(&ptr_value, t_src, sizeof(ptr_value)); + U64 ptr_write_value = ptr_value + (U64)ptr_ref_info->offsetify_base; + MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value)); + read_off += sizeof(ptr_value); + } + + // rjf: size-by-member (pre-header): still potentially dependent on other members which + // delimit our size, so push a new post-header task for pointer. + else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header) + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type; + task->count = t->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + task->is_post_header = 1; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: size-by-member (post-header): all flat parts of containing struct have been + // iterated, so now we can read the size, & descend to new task to read pointer + // destination contents + else if(t->type->count_delimiter_name.size != 0 && t->is_post_header) + { + // rjf: determine count of this pointer + U64 count = 0; + { + Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name); + MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size); + } + + // rjf: allocate buffer for pointer destination; write address into pointer value slot + U64 ptr_dest_buffer_size = (count+1)*t->type->direct->size; + U8 *ptr_dest_buffer = push_array(arena, U8, ptr_dest_buffer_size); + MemoryCopy(t->dst, &ptr_dest_buffer, sizeof(ptr_dest_buffer)); + + // rjf: push task + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = count; + task->dst = ptr_dest_buffer; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + } + + // rjf: catch-all: read pointer value + else + { + MemoryCopy(t->dst, t_src, t->type->size*t->count); + read_off += t->type->size*t->count; + } + }break; + + //- rjf: arrays -> descend to underlying type, + count + case TypeKind_Array: + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->type->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + + //- rjf: struct -> descend to members + case TypeKind_Struct: + { + for(U64 idx = 0; idx < t->count; idx += 1) + { + for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1) + { + if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize) + { + continue; + } + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->members[member_idx].type; + task->count = 1; + task->dst = t->dst + idx*t->type->size + t->type->members[member_idx].value; + task->containing_type = t->type; + task->containing_ptr = t->dst; + SLLQueuePush(first_task, last_task, task); + } + } + }break; + + //- rjf: enum -> descend to basic type interpretation + case TypeKind_Enum: + { + DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1); + task->type = t->type->direct; + task->count = t->count; + task->dst = t->dst; + task->containing_type = t->containing_type; + task->containing_ptr = t->containing_ptr; + SLLQueuePush(first_task, last_task, task); + }break; + } + } + if(params->advance_out != 0) + { + params->advance_out[0] = read_off; + } + scratch_end(scratch); + } + return result; +} + +internal String8 +deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 data_srlz = serialized_from_typed_data(scratch.arena, type, data, params); + String8 data_copy = deserialized_from_typed_data(arena, type, data_srlz, params); + scratch_end(scratch); + return data_copy; +} diff --git a/src/metagen/metagen_base/metagen_base_meta.h b/src/metagen/metagen_base/metagen_base_meta.h new file mode 100644 index 00000000..45d01e72 --- /dev/null +++ b/src/metagen/metagen_base/metagen_base_meta.h @@ -0,0 +1,298 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef BASE_META_H +#define BASE_META_H + +//////////////////////////////// +//~ rjf: Meta Markup Features + +#define EmbedFile(name, path) +#define TweakB32(name, default) (TWEAK_##name) +#define TweakF32(name, default, min, max) (TWEAK_##name) + +//////////////////////////////// +//~ rjf: Tweak Info Tables + +typedef struct TweakB32Info TweakB32Info; +struct TweakB32Info +{ + String8 name; + B32 default_value; + B32 *value_ptr; +}; + +typedef struct TweakF32Info TweakF32Info; +struct TweakF32Info +{ + String8 name; + F32 default_value; + Rng1F32 value_range; + F32 *value_ptr; +}; + +typedef struct TweakB32InfoTable TweakB32InfoTable; +struct TweakB32InfoTable +{ + TweakB32Info *v; + U64 count; +}; + +typedef struct TweakF32InfoTable TweakF32InfoTable; +struct TweakF32InfoTable +{ + TweakF32Info *v; + U64 count; +}; + +typedef struct EmbedInfo EmbedInfo; +struct EmbedInfo +{ + String8 name; + String8 *data; + U128 *hash; +}; + +typedef struct EmbedInfoTable EmbedInfoTable; +struct EmbedInfoTable +{ + EmbedInfo *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Type Info Types + +typedef enum TypeKind +{ + TypeKind_Null, + + // rjf: leaves + TypeKind_Void, TypeKind_FirstLeaf = TypeKind_Void, + TypeKind_U8, + TypeKind_U16, + TypeKind_U32, + TypeKind_U64, + TypeKind_S8, + TypeKind_S16, + TypeKind_S32, + TypeKind_S64, + TypeKind_B8, + TypeKind_B16, + TypeKind_B32, + TypeKind_B64, + TypeKind_F32, + TypeKind_F64, TypeKind_LastLeaf = TypeKind_F64, + + // rjf: operators + TypeKind_Ptr, + TypeKind_Array, + + // rjf: user-defined-types + TypeKind_Struct, + TypeKind_Union, + TypeKind_Enum, + + TypeKind_COUNT +} +TypeKind; + +typedef U32 TypeFlags; +enum +{ + TypeFlag_IsExternal = (1<<0), + TypeFlag_IsPlainText = (1<<1), + TypeFlag_IsCodeText = (1<<2), + TypeFlag_IsPathText = (1<<3), +}; + +typedef U32 MemberFlags; +enum +{ + MemberFlag_DoNotSerialize = (1<<0), +}; + +typedef struct Type Type; +typedef struct Member Member; +struct Member +{ + String8 name; + String8 pretty_name; + Type *type; + U64 value; + MemberFlags flags; +}; + +typedef struct Type Type; +struct Type +{ + TypeKind kind; + TypeFlags flags; + U64 size; + Type *direct; + String8 name; + String8 count_delimiter_name; // gathered from surrounding members, turns *->[1] into *->[N] + U64 count; + Member *members; +}; + +//////////////////////////////// +//~ rjf: Type Serialization Parameters + +typedef struct TypeSerializePtrRefInfo TypeSerializePtrRefInfo; +struct TypeSerializePtrRefInfo +{ + Type *type; // pointers to this + void *indexify_base; // can be indexified using this + void *offsetify_base; // can be offsetified using this + void *nil_ptr; // is terminal if matching 0 or this +}; + +typedef struct TypeSerializeParams TypeSerializeParams; +struct TypeSerializeParams +{ + U64 *advance_out; + TypeSerializePtrRefInfo *ptr_ref_infos; + U64 ptr_ref_infos_count; +}; + +//////////////////////////////// +//~ rjf: Type Name -> Type Info + +#define type(T) (&T##__type) + +//////////////////////////////// +//~ rjf: Type Info Table Initializer Helpers + +#define member_lit_comp(S, ti, m, ...) {str8_lit_comp(#m), {0}, (ti), OffsetOf(S, m), __VA_ARGS__} +#define struct_members(S) read_only global Member S##__members[] = +#define struct_type(S, ...) read_only global Type S##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#S), {0}, ArrayCount(S##__members), S##__members, __VA_ARGS__} +#define named_struct_type(name, S, ...) read_only global Type name##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#name), {0}, ArrayCount(name##__members), name##__members, __VA_ARGS__} +#define ptr_type(name, ti, ...) read_only global Type name = {TypeKind_Ptr, 0, sizeof(void *), (ti), __VA_ARGS__} + +//////////////////////////////// +//~ rjf: Globals + +read_only global Type type_nil = {TypeKind_Null, 0, 0, &type_nil}; +read_only global Member member_nil = {{0}, {0}, &type_nil}; + +//////////////////////////////// +//~ rjf: Built-In Types + +//- rjf: leaves +read_only global Type void__type = {TypeKind_Void, 0, 0, &type_nil, str8_lit_comp("void")}; +read_only global Type U8__type = {TypeKind_U8, 0, sizeof(U8), &type_nil, str8_lit_comp("U8")}; +read_only global Type U16__type = {TypeKind_U16, 0, sizeof(U16), &type_nil, str8_lit_comp("U16")}; +read_only global Type U32__type = {TypeKind_U32, 0, sizeof(U32), &type_nil, str8_lit_comp("U32")}; +read_only global Type U64__type = {TypeKind_U64, 0, sizeof(U64), &type_nil, str8_lit_comp("U64")}; +read_only global Type S8__type = {TypeKind_S8, 0, sizeof(S8), &type_nil, str8_lit_comp("S8")}; +read_only global Type S16__type = {TypeKind_S16, 0, sizeof(S16), &type_nil, str8_lit_comp("S16")}; +read_only global Type S32__type = {TypeKind_S32, 0, sizeof(S32), &type_nil, str8_lit_comp("S32")}; +read_only global Type S64__type = {TypeKind_S64, 0, sizeof(S64), &type_nil, str8_lit_comp("S64")}; +read_only global Type B8__type = {TypeKind_B8, 0, sizeof(B8), &type_nil, str8_lit_comp("B8")}; +read_only global Type B16__type = {TypeKind_B16, 0, sizeof(B16), &type_nil, str8_lit_comp("B16")}; +read_only global Type B32__type = {TypeKind_B32, 0, sizeof(B32), &type_nil, str8_lit_comp("B32")}; +read_only global Type B64__type = {TypeKind_B64, 0, sizeof(B64), &type_nil, str8_lit_comp("B64")}; +read_only global Type F32__type = {TypeKind_F32, 0, sizeof(F32), &type_nil, str8_lit_comp("F32")}; +read_only global Type F64__type = {TypeKind_F64, 0, sizeof(F64), &type_nil, str8_lit_comp("F64")}; +read_only global Type *type_kind_type_table[] = +{ + &type_nil, + type(void), + type(U8), + type(U16), + type(U32), + type(U64), + type(S8), + type(S16), + type(S32), + type(S64), + type(B8), + type(B16), + type(B32), + type(B64), + type(F32), + type(F64), + &type_nil, + &type_nil, + &type_nil, + &type_nil, + &type_nil, +}; + +//- rjf: Rng1U64 +struct_members(Rng1U64) +{ + member_lit_comp(Rng1U64, type(U64), min), + member_lit_comp(Rng1U64, type(U64), max), +}; +struct_type(Rng1U64); + +//- rjf: String8 +ptr_type(String8__str_ptr_type, type(U8), str8_lit_comp("size")); +struct_members(String8) +{ + member_lit_comp(String8, &String8__str_ptr_type, str), + member_lit_comp(String8, type(U64), size), +}; +struct_type(String8); + +//- rjf: String8Node +extern Type String8Node__type; +Type String8Node__ptr_type = {TypeKind_Ptr, 0, sizeof(void *), &String8Node__type}; +Member String8Node__members[] = +{ + {str8_lit_comp("next"), {0}, &String8Node__ptr_type, OffsetOf(String8Node, next)}, + {str8_lit_comp("string"), {0}, type(String8), OffsetOf(String8Node, string)}, +}; +Type String8Node__type = +{ + TypeKind_Struct, + 0, + sizeof(String8Node), + &type_nil, + str8_lit_comp("String8Node"), + {0}, + ArrayCount(String8Node__members), + String8Node__members, +}; + +//- rjf: String8List +Member String8List__members[] = +{ + {str8_lit_comp("first"), {0}, &String8Node__ptr_type, OffsetOf(String8List, first)}, + {str8_lit_comp("last"), {0}, &String8Node__ptr_type, OffsetOf(String8List, last), MemberFlag_DoNotSerialize}, + {str8_lit_comp("node_count"), {0}, type(U64), OffsetOf(String8List, node_count)}, + {str8_lit_comp("total_size"), {0}, type(U64), OffsetOf(String8List, total_size)}, +}; +Type String8List__type = +{ + TypeKind_Struct, + 0, + sizeof(String8List), + &type_nil, + str8_lit_comp("String8List"), + {0}, + ArrayCount(String8List__members), + String8List__members, +}; + +//////////////////////////////// +//~ rjf: Type Info Lookups + +internal Member *member_from_name(Type *type, String8 name); +#define EachMember(T, it) (Member *it = (type(T))->members; it != 0 && it < (type(T))->members + (type(T))->count; it += 1) + +//////////////////////////////// +//~ rjf: Type Info * Instance Operations + +internal void typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr); +internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +internal String8 deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +internal String8 deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params); +#define struct_rebase_ptrs(T, ptr, base) typed_data_rebase_ptrs(type(T), str8_struct(ptr), (base)) +#define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}) +#define struct_from_serialized(arena, T, string, ...) (T *)deserialized_from_typed_data((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str +#define deep_copy_from_struct(arena, T, ptr, ...) (T *)deep_copy_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str + +#endif // BASE_META_H diff --git a/src/metagen/metagen_base/metagen_base_profile.h b/src/metagen/metagen_base/metagen_base_profile.h index fa67b823..098270f4 100644 --- a/src/metagen/metagen_base/metagen_base_profile.h +++ b/src/metagen/metagen_base/metagen_base_profile.h @@ -43,26 +43,48 @@ # define ProfLockTake(...) tmAcquiredLock(0, 0, __VA_ARGS__) # define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__) # define ProfColor(color) tmZoneColorSticky(color) +# define ProfBeginV(...) \ + if (TM_API_PTR) { \ + static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ + Temp scratch = scratch_begin(0,0); \ + String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ + tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ + hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ + TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \ + scratch_end(scratch); \ + } +# define ProfNoteV(...) \ + if (TM_API_PTR) { \ + static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ + Temp scratch = scratch_begin(0,0); \ + String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ + tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ + hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ + TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \ + scratch_end(scratch); \ + } #endif //////////////////////////////// //~ rjf: Zeroify Undefined Defines #if !defined(ProfBegin) -# define ProfBegin(...) (0) -# define ProfBeginDynamic(...) (0) -# define ProfEnd(...) (0) -# define ProfTick(...) (0) -# define ProfIsCapturing(...) (0) -# define ProfBeginCapture(...) (0) -# define ProfEndCapture(...) (0) -# define ProfThreadName(...) (0) -# define ProfMsg(...) (0) -# define ProfBeginLockWait(...) (0) -# define ProfEndLockWait(...) (0) -# define ProfLockTake(...) (0) -# define ProfLockDrop(...) (0) -# define ProfColor(...) (0) +# define ProfBegin(...) (0) +# define ProfBeginDynamic(...) (0) +# define ProfEnd(...) (0) +# define ProfTick(...) (0) +# define ProfIsCapturing(...) (0) +# define ProfBeginCapture(...) (0) +# define ProfEndCapture(...) (0) +# define ProfThreadName(...) (0) +# define ProfMsg(...) (0) +# define ProfBeginLockWait(...) (0) +# define ProfEndLockWait(...) (0) +# define ProfLockTake(...) (0) +# define ProfLockDrop(...) (0) +# define ProfColor(...) (0) +# define ProfBeginV(...) (0) +# define ProfNoteV(...) (0) #endif //////////////////////////////// diff --git a/src/metagen/metagen_base/metagen_base_strings.c b/src/metagen/metagen_base/metagen_base_strings.c index 91a47562..9e42e0cd 100644 --- a/src/metagen/metagen_base/metagen_base_strings.c +++ b/src/metagen/metagen_base/metagen_base_strings.c @@ -215,12 +215,42 @@ str32_cstring(U32 *c){ internal String8 str8_cstring_capped(void *cstr, void *cap) { - char *ptr = (char*)cstr; - char *opl = (char*)cap; + char *ptr = (char *)cstr; + char *opl = (char *)cap; for (;ptr < opl && *ptr != 0; ptr += 1); U64 size = (U64)(ptr - (char *)cstr); - String8 result = {(U8*)cstr, size}; - return(result); + String8 result = str8((U8*)cstr, size); + return result; +} + +internal String16 +str16_cstring_capped(void *cstr, void *cap) +{ + U16 *ptr = (U16 *)cstr; + U16 *opl = (U16 *)cap; + for (;ptr < opl && *ptr != 0; ptr += 1); + U64 size = (U64)(ptr - (U16 *)cstr); + String16 result = str16(cstr, size); + return result; +} + +internal String8 +str8_cstring_capped_reverse(void *raw_start, void *raw_cap) +{ + U8 *start = raw_start; + U8 *ptr = raw_cap; + for(; ptr > start; ) + { + ptr -= 1; + + if (*ptr == '\0') + { + break; + } + } + U64 size = (U64)(ptr - start); + String8 result = str8(start, size); + return result; } //////////////////////////////// @@ -263,31 +293,41 @@ backslashed_from_str8(Arena *arena, String8 string) //~ rjf: String Matching internal B32 -str8_match(String8 a, String8 b, StringMatchFlags flags){ +str8_match(String8 a, String8 b, StringMatchFlags flags) +{ B32 result = 0; - if (a.size == b.size || (flags & StringMatchFlag_RightSideSloppy)){ - B32 case_insensitive = (flags & StringMatchFlag_CaseInsensitive); + if(a.size == b.size && flags == 0) + { + result = MemoryMatch(a.str, b.str, b.size); + } + else if(a.size == b.size || (flags & StringMatchFlag_RightSideSloppy)) + { + B32 case_insensitive = (flags & StringMatchFlag_CaseInsensitive); B32 slash_insensitive = (flags & StringMatchFlag_SlashInsensitive); - U64 size = Min(a.size, b.size); + U64 size = Min(a.size, b.size); result = 1; - for (U64 i = 0; i < size; i += 1){ + for(U64 i = 0; i < size; i += 1) + { U8 at = a.str[i]; U8 bt = b.str[i]; - if (case_insensitive){ + if(case_insensitive) + { at = char_to_upper(at); bt = char_to_upper(bt); } - if (slash_insensitive){ + if(slash_insensitive) + { at = char_to_correct_slash(at); bt = char_to_correct_slash(bt); } - if (at != bt){ + if(at != bt) + { result = 0; break; } } } - return(result); + return result; } internal U64 @@ -322,6 +362,22 @@ str8_find_needle(String8 string, U64 start_pos, String8 needle, StringMatchFlags return(result); } +internal U64 +str8_find_needle_reverse(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags) +{ + U64 result = 0; + for(S64 i = string.size - start_pos - needle.size; i >= 0; --i) + { + String8 haystack = str8_substr(string, rng_1u64(i, i + needle.size)); + if(str8_match(haystack, needle, flags)) + { + result = (U64)i + needle.size; + break; + } + } + return result; +} + internal B32 str8_ends_with(String8 string, String8 end, StringMatchFlags flags){ String8 postfix = str8_postfix(string, end.size); @@ -500,6 +556,22 @@ s64_from_str8(String8 string, U32 radix){ return(x); } +internal U32 +u32_from_str8(String8 string, U32 radix) +{ + U64 x64 = u64_from_str8(string, radix); + U32 x32 = safe_cast_u32(x64); + return x32; +} + +internal S32 +s32_from_str8(String8 string, U32 radix) +{ + S64 x64 = s64_from_str8(string, radix); + S32 x32 = safe_cast_s32(x64); + return x32; +} + internal B32 try_u64_from_str8_c_rules(String8 string, U64 *x){ B32 is_integer = 0; @@ -544,21 +616,121 @@ try_s64_from_str8_c_rules(String8 string, S64 *x){ //- rjf: integer -> string internal String8 -str8_from_memory_size(Arena *arena, U64 z){ - String8 result = {0}; - if (z < KB(1)){ - result = push_str8f(arena, "%llu b", z); +str8_from_memory_size(Arena *arena, U64 size) +{ + String8 result; + + if(size < KB(1)) + { + result = push_str8f(arena, "%llu Bytes", size); } - else if (z < MB(1)){ - result = push_str8f(arena, "%llu.%02llu Kb", z/KB(1), ((100*z)/KB(1))%100); + else if(size < MB(1)) + { + result = push_str8f(arena, "%llu.%02llu KiB", size / KB(1), ((size * 100) / KB(1)) % 100); } - else if (z < GB(1)){ - result = push_str8f(arena, "%llu.%02llu Mb", z/MB(1), ((100*z)/MB(1))%100); + else if(size < GB(1)) + { + result = push_str8f(arena, "%llu.%02llu MiB", size / MB(1), ((size * 100) / MB(1)) % 100); } - else{ - result = push_str8f(arena, "%llu.%02llu Gb", z/GB(1), ((100*z)/GB(1))%100); + else if(size < TB(1)) + { + result = push_str8f(arena, "%llu.%02llu GiB", size / GB(1), ((size * 100) / GB(1)) % 100); } - return(result); + else + { + result = push_str8f(arena, "%llu.%02llu TiB", size / TB(1), ((size * 100) / TB(1)) % 100); + } + + return result; +} + +internal String8 +str8_from_count(Arena *arena, U64 count) +{ + String8 result; + + if(count < 1 * 1000) + { + result = push_str8f(arena, "%llu", count); + } + else if(count < 1000000) + { + U64 frac = ((count * 100) / 1000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluK", count / 1000, frac); + } + else + { + result = push_str8f(arena, "%lluK", count / 1000); + } + } + else if(count < 1000000000) + { + U64 frac = ((count * 100) / 1000000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluM", count / 1000000, frac); + } + else + { + result = push_str8f(arena, "%lluM", count / 1000000); + } + } + else + { + U64 frac = ((count * 100) * 1000000000) % 100; + if(frac > 0) + { + result = push_str8f(arena, "%llu.%02lluB", count / 1000000000, frac); + } + else + { + result = push_str8f(arena, "%lluB", count / 1000000000, frac); + } + } + + return result; +} + +internal String8 +str8_from_bits_u32(Arena *arena, U32 x) +{ + U8 c0 = 'a' + ((x >> 28) & 0xf); + U8 c1 = 'a' + ((x >> 24) & 0xf); + U8 c2 = 'a' + ((x >> 20) & 0xf); + U8 c3 = 'a' + ((x >> 16) & 0xf); + U8 c4 = 'a' + ((x >> 12) & 0xf); + U8 c5 = 'a' + ((x >> 8) & 0xf); + U8 c6 = 'a' + ((x >> 4) & 0xf); + U8 c7 = 'a' + ((x >> 0) & 0xf); + String8 result = push_str8f(arena, "%c%c%c%c%c%c%c%c", c0, c1, c2, c3, c4, c5, c6, c7); + return result; +} + +internal String8 +str8_from_bits_u64(Arena *arena, U64 x) +{ + U8 c0 = 'a' + ((x >> 60) & 0xf); + U8 c1 = 'a' + ((x >> 56) & 0xf); + U8 c2 = 'a' + ((x >> 52) & 0xf); + U8 c3 = 'a' + ((x >> 48) & 0xf); + U8 c4 = 'a' + ((x >> 44) & 0xf); + U8 c5 = 'a' + ((x >> 40) & 0xf); + U8 c6 = 'a' + ((x >> 36) & 0xf); + U8 c7 = 'a' + ((x >> 32) & 0xf); + U8 c8 = 'a' + ((x >> 28) & 0xf); + U8 c9 = 'a' + ((x >> 24) & 0xf); + U8 ca = 'a' + ((x >> 20) & 0xf); + U8 cb = 'a' + ((x >> 16) & 0xf); + U8 cc = 'a' + ((x >> 12) & 0xf); + U8 cd = 'a' + ((x >> 8) & 0xf); + U8 ce = 'a' + ((x >> 4) & 0xf); + U8 cf = 'a' + ((x >> 0) & 0xf); + String8 result = push_str8f(arena, + "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf); + return result; } internal String8 @@ -685,27 +857,28 @@ f64_from_str8(String8 string) { // rjf: find starting pos of numeric string, as well as sign F64 sign = +1.0; - //U64 first_numeric = 0; if(string.str[0] == '-') { - //first_numeric = 1; sign = -1.0; } else if(string.str[0] == '+') { - //first_numeric = 1; sign = 1.0; } // rjf: gather numerics U64 num_valid_chars = 0; char buffer[64]; + B32 exp = 0; for(U64 idx = 0; idx < string.size && num_valid_chars < sizeof(buffer)-1; idx += 1) { - if(char_is_digit(string.str[idx], 10) || string.str[idx] == '.') + if(char_is_digit(string.str[idx], 10) || string.str[idx] == '.' || string.str[idx] == 'e' || + (exp && (string.str[idx] == '+' || string.str[idx] == '-'))) { buffer[num_valid_chars] = string.str[idx]; num_valid_chars += 1; + exp = 0; + exp = (string.str[idx] == 'e'); } } @@ -1138,7 +1311,9 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ internal String8 str8_path_list_join_by_style(Arena *arena, String8List *path, PathStyle style){ StringJoin params = {0}; - switch (style){ + switch(style) + { + case PathStyle_Null:{}break; case PathStyle_Relative: case PathStyle_WindowsAbsolute: { @@ -1151,9 +1326,8 @@ str8_path_list_join_by_style(Arena *arena, String8List *path, PathStyle style){ params.sep = str8_lit("/"); }break; } - String8 result = str8_list_join(arena, path, ¶ms); - return(result); + return result; } internal String8TxtPtPair @@ -1346,70 +1520,127 @@ utf8_from_utf32_single(U8 *buffer, U32 character){ //~ rjf: Unicode String Conversions internal String8 -str8_from_16(Arena *arena, String16 in){ - U64 cap = in.size*3; - U8 *str = push_array_no_zero(arena, U8, cap + 1); - U16 *ptr = in.str; - U16 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf16_decode(ptr, opl - ptr); - size += utf8_encode(str + size, consume.codepoint); +str8_from_16(Arena *arena, String16 in) +{ + String8 result = str8_zero(); + if(in.size) + { + U64 cap = in.size*3; + U8 *str = push_array_no_zero(arena, U8, cap + 1); + U16 *ptr = in.str; + U16 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf16_decode(ptr, opl - ptr); + size += utf8_encode(str + size, consume.codepoint); + } + str[size] = 0; + arena_pop(arena, (cap - size)); + result = str8(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)); - return(str8(str, size)); + return result; } internal String16 -str16_from_8(Arena *arena, String8 in){ - U64 cap = in.size*2; - U16 *str = push_array_no_zero(arena, U16, cap + 1); - U8 *ptr = in.str; - U8 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf8_decode(ptr, opl - ptr); - size += utf16_encode(str + size, consume.codepoint); +str16_from_8(Arena *arena, String8 in) +{ + String16 result = str16_zero(); + if(in.size) + { + U64 cap = in.size*2; + U16 *str = push_array_no_zero(arena, U16, cap + 1); + U8 *ptr = in.str; + U8 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf8_decode(ptr, opl - ptr); + size += utf16_encode(str + size, consume.codepoint); + } + str[size] = 0; + arena_pop(arena, (cap - size)*2); + result = str16(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)*2); - return(str16(str, size)); + return result; } internal String8 -str8_from_32(Arena *arena, String32 in){ - U64 cap = in.size*4; - U8 *str = push_array_no_zero(arena, U8, cap + 1); - U32 *ptr = in.str; - U32 *opl = ptr + in.size; - U64 size = 0; - for (;ptr < opl; ptr += 1){ - size += utf8_encode(str + size, *ptr); +str8_from_32(Arena *arena, String32 in) +{ + String8 result = str8_zero(); + if(in.size) + { + U64 cap = in.size*4; + U8 *str = push_array_no_zero(arena, U8, cap + 1); + U32 *ptr = in.str; + U32 *opl = ptr + in.size; + U64 size = 0; + for(;ptr < opl; ptr += 1) + { + size += utf8_encode(str + size, *ptr); + } + str[size] = 0; + arena_pop(arena, (cap - size)); + result = str8(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)); - return(str8(str, size)); + return result; } internal String32 -str32_from_8(Arena *arena, String8 in){ - U64 cap = in.size; - U32 *str = push_array_no_zero(arena, U32, cap + 1); - U8 *ptr = in.str; - U8 *opl = ptr + in.size; - U64 size = 0; - UnicodeDecode consume; - for (;ptr < opl; ptr += consume.inc){ - consume = utf8_decode(ptr, opl - ptr); - str[size] = consume.codepoint; - size += 1; +str32_from_8(Arena *arena, String8 in) +{ + String32 result = str32_zero(); + if(in.size) + { + U64 cap = in.size; + U32 *str = push_array_no_zero(arena, U32, cap + 1); + U8 *ptr = in.str; + U8 *opl = ptr + in.size; + U64 size = 0; + UnicodeDecode consume; + for(;ptr < opl; ptr += consume.inc) + { + consume = utf8_decode(ptr, opl - ptr); + str[size] = consume.codepoint; + size += 1; + } + str[size] = 0; + arena_pop(arena, (cap - size)*4); + result = str32(str, size); } - str[size] = 0; - arena_pop(arena, (cap - size)*4); - return(str32(str, size)); + return result; +} + +//////////////////////////////// +//~ String -> Enum Conversions + +read_only global struct +{ + String8 string; + OperatingSystem os; +} g_os_enum_map[] = +{ + { str8_lit_comp(""), OperatingSystem_Null }, + { str8_lit_comp("Windows"), OperatingSystem_Windows, }, + { str8_lit_comp("Linux"), OperatingSystem_Linux, }, + { str8_lit_comp("Mac"), OperatingSystem_Mac, }, +}; +StaticAssert(ArrayCount(g_os_enum_map) == OperatingSystem_COUNT, g_os_enum_map_count_check); + +internal OperatingSystem +operating_system_from_string(String8 string) +{ + for(U64 i = 0; i < ArrayCount(g_os_enum_map); ++i) + { + if(str8_match(g_os_enum_map[i].string, string, StringMatchFlag_CaseInsensitive)) + { + return g_os_enum_map[i].os; + } + } + return OperatingSystem_Null; } //////////////////////////////// @@ -1444,22 +1675,18 @@ string_from_side(Side side){ } internal String8 -string_from_operating_system(OperatingSystem os){ - local_persist String8 strings[] = { - str8_lit_comp("Null"), - str8_lit_comp("Windows"), - str8_lit_comp("Linux"), - str8_lit_comp("Mac"), - }; - String8 result = str8_lit("error"); - if (os < OperatingSystem_COUNT){ - result = strings[os]; +string_from_operating_system(OperatingSystem os) +{ + String8 result = g_os_enum_map[OperatingSystem_Null].string; + if(os < ArrayCount(g_os_enum_map)) + { + result = g_os_enum_map[os].string; } - return(result); + return result; } internal String8 -string_from_architecture(Architecture arch){ +string_from_arch(Arch arch){ local_persist String8 strings[] = { str8_lit_comp("Null"), str8_lit_comp("x64"), @@ -1468,7 +1695,7 @@ string_from_architecture(Architecture arch){ str8_lit_comp("arm32"), }; String8 result = str8_lit("error"); - if (arch < Architecture_COUNT){ + if (arch < Arch_COUNT){ result = strings[arch]; } return(result); @@ -1565,6 +1792,78 @@ string_from_elapsed_time(Arena *arena, DateTime dt){ return(result); } +//////////////////////////////// +//~ Globally UNique Ids + +internal String8 +string_from_guid(Arena *arena, Guid guid) +{ + String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + guid.data1, + guid.data2, + guid.data3, + guid.data4[0], + guid.data4[1], + guid.data4[2], + guid.data4[3], + guid.data4[4], + guid.data4[5], + guid.data4[6], + guid.data4[7]); + return result; +} + +internal B32 +try_guid_from_string(String8 string, Guid *guid_out) +{ + Temp scratch = scratch_begin(0,0); + B32 is_parsed = 0; + String8List list = str8_split_by_string_chars(scratch.arena, string, str8_lit("-"), StringSplitFlag_KeepEmpties); + if(list.node_count == 5) + { + String8 data1_str = list.first->string; + String8 data2_str = list.first->next->string; + String8 data3_str = list.first->next->next->string; + String8 data4_hi_str = list.first->next->next->next->string; + String8 data4_lo_str = list.first->next->next->next->next->string; + if(str8_is_integer(data1_str, 16) && + str8_is_integer(data2_str, 16) && + str8_is_integer(data3_str, 16) && + str8_is_integer(data4_hi_str, 16) && + str8_is_integer(data4_lo_str, 16)) + { + U64 data1 = u64_from_str8(data1_str, 16); + U64 data2 = u64_from_str8(data2_str, 16); + U64 data3 = u64_from_str8(data3_str, 16); + U64 data4_hi = u64_from_str8(data4_hi_str, 16); + U64 data4_lo = u64_from_str8(data4_lo_str, 16); + if(data1 <= max_U32 && + data2 <= max_U16 && + data3 <= max_U16 && + data4_hi <= max_U16 && + data4_lo <= 0xffffffffffff) + { + guid_out->data1 = (U32)data1; + guid_out->data2 = (U16)data2; + guid_out->data3 = (U16)data3; + U64 data4 = (data4_hi << 48) | data4_lo; + MemoryCopy(&guid_out->data4[0], &data4, sizeof(data4)); + is_parsed = 1; + } + } + } + scratch_end(scratch); + return is_parsed; +} + +internal Guid +guid_from_string(String8 string) +{ + Guid guid = {0}; + try_guid_from_string(string, &guid); + return guid; +} + //////////////////////////////// //~ rjf: Basic Text Indentation @@ -1593,6 +1892,10 @@ indented_from_string(Arena *arena, String8 string) { str8_list_pushf(scratch.arena, &indented_strings, "%.*s%S\n", (int)depth*2, indentation_bytes, line); } + if(line.size == 0 && indented_strings.node_count != 0 && off < string.size) + { + str8_list_pushf(scratch.arena, &indented_strings, "\n"); + } line_begin_off = off+1; depth = next_depth; }break; @@ -1603,6 +1906,100 @@ indented_from_string(Arena *arena, String8 string) return result; } +//////////////////////////////// +//~ rjf: Text Escaping + +internal String8 +escaped_from_raw_str8(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List parts = {0}; + U64 start_split_idx = 0; + for(U64 idx = 0; idx <= string.size; idx += 1) + { + U8 byte = (idx < string.size) ? string.str[idx] : 0; + B32 split = 1; + String8 separator_replace = {0}; + switch(byte) + { + default:{split = 0;}break; + case 0: {}break; + case '\a': {separator_replace = str8_lit("\\a");}break; + case '\b': {separator_replace = str8_lit("\\b");}break; + case '\f': {separator_replace = str8_lit("\\f");}break; + case '\n': {separator_replace = str8_lit("\\n");}break; + case '\r': {separator_replace = str8_lit("\\r");}break; + case '\t': {separator_replace = str8_lit("\\t");}break; + case '\v': {separator_replace = str8_lit("\\v");}break; + case '\\': {separator_replace = str8_lit("\\\\");}break; + case '"': {separator_replace = str8_lit("\\\"");}break; + case '?': {separator_replace = str8_lit("\\?");}break; + } + if(split) + { + String8 substr = str8_substr(string, r1u64(start_split_idx, idx)); + start_split_idx = idx+1; + str8_list_push(scratch.arena, &parts, substr); + if(separator_replace.size != 0) + { + str8_list_push(scratch.arena, &parts, separator_replace); + } + } + } + StringJoin join = {0}; + String8 result = str8_list_join(arena, &parts, &join); + scratch_end(scratch); + return result; +} + +internal String8 +raw_from_escaped_str8(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strs = {0}; + U64 start = 0; + for(U64 idx = 0; idx <= string.size; idx += 1) + { + if(idx == string.size || string.str[idx] == '\\' || string.str[idx] == '\r') + { + String8 str = str8_substr(string, r1u64(start, idx)); + if(str.size != 0) + { + str8_list_push(scratch.arena, &strs, str); + } + start = idx+1; + } + if(idx < string.size && string.str[idx] == '\\') + { + U8 next_char = string.str[idx+1]; + U8 replace_byte = 0; + switch(next_char) + { + default:{}break; + case 'a': replace_byte = 0x07; break; + case 'b': replace_byte = 0x08; break; + case 'e': replace_byte = 0x1b; break; + case 'f': replace_byte = 0x0c; break; + case 'n': replace_byte = 0x0a; break; + case 'r': replace_byte = 0x0d; break; + case 't': replace_byte = 0x09; break; + case 'v': replace_byte = 0x0b; break; + case '\\':replace_byte = '\\'; break; + case '\'':replace_byte = '\''; break; + case '"': replace_byte = '"'; break; + case '?': replace_byte = '?'; break; + } + String8 replace_string = push_str8_copy(scratch.arena, str8(&replace_byte, 1)); + str8_list_push(scratch.arena, &strs, replace_string); + idx += 1; + start += 1; + } + } + String8 result = str8_list_join(arena, &strs, 0); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Text Wrapping @@ -1973,3 +2370,77 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out) *block_out = str8_substr(string, range); return block_out->size; } + +internal U64 +str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte = 0; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) + { + value |= -(S64)(1ull << shift); + } + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + diff --git a/src/metagen/metagen_base/metagen_base_strings.h b/src/metagen/metagen_base/metagen_base_strings.h index c68bdff6..fc946dd8 100644 --- a/src/metagen/metagen_base/metagen_base_strings.h +++ b/src/metagen/metagen_base/metagen_base_strings.h @@ -86,6 +86,7 @@ enum typedef enum PathStyle { + PathStyle_Null, PathStyle_Relative, PathStyle_WindowsAbsolute, PathStyle_UnixAbsolute, @@ -192,6 +193,8 @@ internal String8 str8_cstring(char *c); internal String16 str16_cstring(U16 *c); internal String32 str32_cstring(U32 *c); internal String8 str8_cstring_capped(void *cstr, void *cap); +internal String16 str16_cstring_capped(void *cstr, void *cap); +internal String8 str8_cstring_capped_reverse(void *raw_start, void *raw_cap); //////////////////////////////// //~ rjf: String Stylization @@ -205,6 +208,7 @@ internal String8 backslashed_from_str8(Arena *arena, String8 string); internal B32 str8_match(String8 a, String8 b, StringMatchFlags flags); internal U64 str8_find_needle(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags); +internal U64 str8_find_needle_reverse(String8 string, U64 start_pos, String8 needle, StringMatchFlags flags); internal B32 str8_ends_with(String8 string, String8 end, StringMatchFlags flags); //////////////////////////////// @@ -231,13 +235,19 @@ internal String8 push_str8f(Arena *arena, char *fmt, ...); //- rjf: string -> integer internal S64 sign_from_str8(String8 string, String8 *string_tail); internal B32 str8_is_integer(String8 string, U32 radix); + internal U64 u64_from_str8(String8 string, U32 radix); internal S64 s64_from_str8(String8 string, U32 radix); +internal U32 u32_from_str8(String8 string, U32 radix); +internal S32 s32_from_str8(String8 string, U32 radix); internal B32 try_u64_from_str8_c_rules(String8 string, U64 *x); internal B32 try_s64_from_str8_c_rules(String8 string, S64 *x); //- rjf: integer -> string -internal String8 str8_from_memory_size(Arena *arena, U64 z); +internal String8 str8_from_memory_size(Arena *arena, U64 size); +internal String8 str8_from_count(Arena *arena, U64 count); +internal String8 str8_from_bits_u32(Arena *arena, U32 x); +internal String8 str8_from_bits_u64(Arena *arena, U64 x); internal String8 str8_from_u64(Arena *arena, U64 u64, U32 radix, U8 min_digits, U8 digit_group_separator); internal String8 str8_from_s64(Arena *arena, S64 s64, U32 radix, U8 min_digits, U8 digit_group_separator); @@ -309,13 +319,18 @@ internal String16 str16_from_8(Arena *arena, String8 in); internal String8 str8_from_32(Arena *arena, String32 in); internal String32 str32_from_8(Arena *arena, String8 in); +//////////////////////////////// +//~ String -> Enum Conversions + +internal OperatingSystem operating_system_from_string(String8 string); + //////////////////////////////// //~ rjf: Basic Types & Space Enum -> String Conversions internal String8 string_from_dimension(Dimension dimension); internal String8 string_from_side(Side side); internal String8 string_from_operating_system(OperatingSystem os); -internal String8 string_from_architecture(Architecture arch); +internal String8 string_from_arch(Arch arch); //////////////////////////////// //~ rjf: Time Types -> String @@ -326,11 +341,24 @@ internal String8 push_date_time_string(Arena *arena, DateTime *date_time); internal String8 push_file_name_date_time_string(Arena *arena, DateTime *date_time); internal String8 string_from_elapsed_time(Arena *arena, DateTime dt); +//////////////////////////////// +//~ Globally Unique Ids + +internal String8 string_from_guid(Arena *arena, Guid guid); +internal B32 try_guid_from_string(String8 string, Guid *guid_out); +internal Guid guid_from_string(String8 string); + //////////////////////////////// //~ rjf: Basic Text Indentation internal String8 indented_from_string(Arena *arena, String8 string); +//////////////////////////////// +//~ rjf: Text Escaping + +internal String8 escaped_from_raw_str8(Arena *arena, String8 string); +internal String8 raw_from_escaped_str8(Arena *arena, String8 string); + //////////////////////////////// //~ rjf: Text Wrapping @@ -372,10 +400,13 @@ internal void str8_serial_push_string(Arena *arena, String8List *srl, String8 internal U64 str8_deserial_read(String8 string, U64 off, void *read_dst, U64 read_size, U64 granularity); internal U64 str8_deserial_find_first_match(String8 string, U64 off, U16 scan_val); -internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size);internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); +internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size); +internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16 *str_out); internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out); +internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); +internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) -#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)), sizeof(*(ptr))) +#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1) #endif // BASE_STRINGS_H diff --git a/src/metagen/metagen_base/metagen_base_thread_context.h b/src/metagen/metagen_base/metagen_base_thread_context.h index 90a396fe..b2515c93 100644 --- a/src/metagen/metagen_base/metagen_base_thread_context.h +++ b/src/metagen/metagen_base/metagen_base_thread_context.h @@ -26,7 +26,7 @@ internal void tctx_init_and_equip(TCTX *tctx); internal void tctx_release(void); internal TCTX* tctx_get_equipped(void); -internal Arena* tctx_get_scratch(Arena **conflicts, U64 count); +internal Arena* tctx_get_scratch(Arena **conflicts, U64 countt); internal void tctx_set_thread_name(String8 name); internal String8 tctx_get_thread_name(void); diff --git a/src/metagen/metagen_main.c b/src/metagen/metagen_main.c index 2323a6d9..24c645b1 100644 --- a/src/metagen/metagen_main.c +++ b/src/metagen/metagen_main.c @@ -246,8 +246,7 @@ entry_point(CmdLine *cmdline) } for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->enums, "%S_%S,\n", enum_member_prefix, escaped); + str8_list_pushf(mg_arena, &layer->enums, "%S_%S,\n", enum_member_prefix, n->string); } if(enum_base_type_name.size == 0) { @@ -278,8 +277,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->enums, "#define %S \\\n", node->string); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->enums, "X(%S)\\\n", escaped); + str8_list_pushf(mg_arena, &layer->enums, "X(%S)\\\n", n->string); } str8_list_push(mg_arena, &layer->enums, str8_lit("\n")); } @@ -303,8 +301,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->structs, "struct %S\n{\n", node->string); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->structs, "%S;\n", escaped); + str8_list_pushf(mg_arena, &layer->structs, "%S;\n", n->string); } str8_list_pushf(mg_arena, &layer->structs, "};\n\n"); } @@ -333,8 +330,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->c_tables, "%S %S[%I64u] =\n{\n", element_type, node->string, gen_strings.node_count); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->c_tables, "%S,\n", escaped); + str8_list_pushf(mg_arena, &layer->c_tables, "%S,\n", n->string); } str8_list_push(mg_arena, &layer->c_tables, str8_lit("};\n\n")); } @@ -364,8 +360,7 @@ entry_point(CmdLine *cmdline) str8_list_pushf(mg_arena, &layer->c_functions, "default:{}break;\n"); for(String8Node *n = gen_strings.first; n != 0; n = n->next) { - String8 escaped = mg_escaped_from_str8(mg_arena, n->string); - str8_list_pushf(mg_arena, &layer->c_functions, "%S;\n", escaped); + str8_list_pushf(mg_arena, &layer->c_functions, "%S;\n", n->string); } str8_list_pushf(mg_arena, &layer->c_functions, "}\n"); str8_list_pushf(mg_arena, &layer->c_functions, "return result;\n"); @@ -398,8 +393,7 @@ entry_point(CmdLine *cmdline) for(String8Node *n = gen_strings.first; n != 0; n = n->next) { String8 trimmed = str8_skip_chop_whitespace(n->string); - String8 escaped = mg_escaped_from_str8(mg_arena, trimmed); - str8_list_push(mg_arena, out, escaped); + str8_list_push(mg_arena, out, trimmed); str8_list_push(mg_arena, out, str8_lit("\n")); } } diff --git a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c index 37e02710..876f0d91 100644 --- a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c +++ b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c @@ -1628,7 +1628,7 @@ w32_entry_point_caller(int argc, WCHAR **wargv) } //- rjf: call into "real" entry point - main_thread_base_entry_point(entry_point, argv, (U64)argc); + main_thread_base_entry_point(argc, argv); } #if BUILD_CONSOLE_INTERFACE diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c628a0ff..e9c96ee3 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -73,11 +73,12 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, }; -RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5] = +RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = { -{str8_lit_comp("target"), str8_lit_comp("x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("x:{'expression':code_string, 'view_rule':code_string, 'location':location}")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'exe': path,\n 'args': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression':code_string,\n 'view_rule':code_string,\n 'location':location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}")}, }; @@ -1897,120 +1898,5 @@ str8_lit_comp("breakpoint"), str8_lit_comp("cache_line_boundary"), }; -String8 rd_setting_code_display_string_table[19] = -{ -str8_lit_comp("Hover Animations"), -str8_lit_comp("Press Animations"), -str8_lit_comp("Focus Animations"), -str8_lit_comp("Tooltip Animations"), -str8_lit_comp("Menu Animations"), -str8_lit_comp("Scrolling Animations"), -str8_lit_comp("Background Blur"), -str8_lit_comp("Thread Lines"), -str8_lit_comp("Breakpoint Lines"), -str8_lit_comp("Thread Glow"), -str8_lit_comp("Breakpoint Glow"), -str8_lit_comp("Opaque Backgrounds"), -str8_lit_comp("Tab Width"), -str8_lit_comp("Main Font Size"), -str8_lit_comp("Code Font Size"), -str8_lit_comp("Smooth UI Text"), -str8_lit_comp("Smooth Code Text"), -str8_lit_comp("Hint UI Text"), -str8_lit_comp("Hint Code Text"), -}; - -String8 rd_setting_code_lower_string_table[19] = -{ -str8_lit_comp("hover_animations"), -str8_lit_comp("press_animations"), -str8_lit_comp("focus_animations"), -str8_lit_comp("tooltip_animations"), -str8_lit_comp("menu_animations"), -str8_lit_comp("scrolling_animations"), -str8_lit_comp("background_blur"), -str8_lit_comp("thread_lines"), -str8_lit_comp("breakpoint_lines"), -str8_lit_comp("thread_glow"), -str8_lit_comp("breakpoint_glow"), -str8_lit_comp("opaque_backgrounds"), -str8_lit_comp("tab_width"), -str8_lit_comp("main_font_size"), -str8_lit_comp("code_font_size"), -str8_lit_comp("smooth_ui_text"), -str8_lit_comp("smooth_code_text"), -str8_lit_comp("hint_ui_text"), -str8_lit_comp("hint_code_text"), -}; - -B8 rd_setting_code_default_is_per_window_table[19] = -{ -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -1, -1, -1, -1, -1, -}; - -RD_SettingVal rd_setting_code_default_val_table[19] = -{ -{1, 1}, -{1, 1}, -{1, 0}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 1}, -{1, 0}, -{1, 4}, -{1, 11}, -{1, 11}, -{1, 1}, -{1, 0}, -{1, 1}, -{1, 1}, -}; - -Rng1S32 rd_setting_code_s32_range_table[19] = -{ -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -{1, 32}, -{6, 72}, -{6, 72}, -{0, 1}, -{0, 1}, -{0, 1}, -{0, 1}, -}; - C_LINKAGE_END diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index ca29430a..897039d7 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -512,30 +512,6 @@ RD_ThemePreset_FarManager, RD_ThemePreset_COUNT, } RD_ThemePreset; -typedef enum RD_SettingCode -{ -RD_SettingCode_HoverAnimations, -RD_SettingCode_PressAnimations, -RD_SettingCode_FocusAnimations, -RD_SettingCode_TooltipAnimations, -RD_SettingCode_MenuAnimations, -RD_SettingCode_ScrollingAnimations, -RD_SettingCode_BackgroundBlur, -RD_SettingCode_ThreadLines, -RD_SettingCode_BreakpointLines, -RD_SettingCode_ThreadGlow, -RD_SettingCode_BreakpointGlow, -RD_SettingCode_OpaqueBackgrounds, -RD_SettingCode_TabWidth, -RD_SettingCode_MainFontSize, -RD_SettingCode_CodeFontSize, -RD_SettingCode_SmoothUIText, -RD_SettingCode_SmoothCodeText, -RD_SettingCode_HintUIText, -RD_SettingCode_HintCodeText, -RD_SettingCode_COUNT, -} RD_SettingCode; - typedef struct RD_VocabularyInfo RD_VocabularyInfo; struct RD_VocabularyInfo { @@ -781,7 +757,7 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[41]; -extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[5]; +extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; @@ -817,11 +793,6 @@ extern Vec4F32 rd_theme_preset_colors__far_manager[76]; extern Vec4F32* rd_theme_preset_colors_table[9]; extern String8 rd_theme_color_display_string_table[76]; extern String8 rd_theme_color_cfg_string_table[76]; -extern String8 rd_setting_code_display_string_table[19]; -extern String8 rd_setting_code_lower_string_table[19]; -extern B8 rd_setting_code_default_is_per_window_table[19]; -extern RD_SettingVal rd_setting_code_default_val_table[19]; -extern Rng1S32 rd_setting_code_s32_range_table[19]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e27f2929..3b6bac8d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -111,42 +111,91 @@ RD_VocabularyMap: //////////////////////////////// //~ rjf: Configuration Tree Schemas -/* +@table(name schema) RD_CfgSchemaTable: +{ + //- rjf: settings { - top_level, + settings, ```x: { - 'hover_animations': bool, - 'press_animations': bool, - 'focus_animations': bool, - 'tooltip_animations': bool, - 'menu_animations': bool, - 'scrolling_animations': bool, - 'background_blur': bool, - 'thread_lines': bool, - 'breakpoint_lines': bool, - 'thread_glow': bool, - 'breakpoint_glow': bool, - 'opaque_backgrounds': bool, - 'smooth_main_text': bool, - 'smooth_code_text': bool, - 'hint_main_text': bool, - 'hint_code_text': bool, - 'tab_width': @range[1, 32] u64, - 'main_font_size': @range[6, 72] u64, - 'code_font_size': @range[1, 32] u64, + @default(1) 'hover_animations': bool, + @default(1) 'press_animations': bool, + @default(0) 'focus_animations': bool, + @default(1) 'tooltip_animations': bool, + @default(1) 'menu_animations': bool, + @default(1) 'scrolling_animations': bool, + @default(1) 'background_blur': bool, + @default(1) 'thread_lines': bool, + @default(1) 'breakpoint_lines': bool, + @default(1) 'thread_glow': bool, + @default(1) 'breakpoint_glow': bool, + @default(0) 'opaque_backgrounds': bool, + @default(1) 'smooth_main_text': bool, + @default(0) 'smooth_code_text': bool, + @default(1) 'hint_main_text': bool, + @default(1) 'hint_code_text': bool, + @default(2) 'tab_width': @range[1, 32] u64, + @can_be_per_window 'main_font_size': @range[6, 72] u64, + @can_be_per_window 'code_font_size': @range[1, 32] u64, } ``` } -*/ - -@table(name schema) RD_CfgSchemaTable: -{ - {target "x:{'label':code_string, 'exe':path, 'args':string, 'working_directory':path, 'entry_point':code_string, 'stdout_path':path, 'stderr_path':path, 'stdin_path':path, 'debug_subprocesses':bool}"} - {breakpoint "x:{'label':code_string, 'condition':code_string, 'location':location, 'hit_count':u64, 'enabled':bool}"} - {watch_pin "x:{'expression':code_string, 'view_rule':code_string, 'location':location}"} - {file_path_map "x:{'source':path, 'dest':path}"} - {auto_view_rule "x:{'source':code_string, 'dest':code_string}"} + + //- rjf: targets + { + target, + ```x: + { + 'label': code_string, + 'exe': path, + 'args': string, + 'working_directory': path, + 'entry_point': code_string, + 'stdout_path': path, + 'stderr_path': path, + 'stdin_path': path, + 'debug_subprocesses': bool, + } + ``` + } + + //- rjf: breakpoints + { + breakpoint, + ```x: + { + 'label': code_string, + 'condition': code_string, + 'location': location, + 'hit_count': u64, + 'disabled': bool, + } + ``` + } + + //- rjf: watch pins + { + watch_pin, + ```x: + { + 'expression':code_string, + 'view_rule':code_string, + 'location':location, + } + ``` + } + + //- rjf: file path maps + { + file_path_map, + ```x:{'source':path, 'dest':path}``` + } + + //- rjf: auto view rules + { + auto_view_rule, + ```x:{'source':code_string, 'dest':code_string}``` + } } @struct RD_CfgNameSchemaPair: @@ -1290,64 +1339,6 @@ RD_ThemeColorVersionRemapTable: @expand(RD_ThemeColorTable a) `str8_lit_comp("$(a.name_lower)")` } -//////////////////////////////// -//~ rjf: Settings - -@table(name name_lower display_string default_per_window default_s32 s32_min s32_max) -RD_SettingTable: -{ - {HoverAnimations hover_animations "Hover Animations" 0 1 0 1 } - {PressAnimations press_animations "Press Animations" 0 1 0 1 } - {FocusAnimations focus_animations "Focus Animations" 0 0 0 1 } - {TooltipAnimations tooltip_animations "Tooltip Animations" 0 1 0 1 } - {MenuAnimations menu_animations "Menu Animations" 0 1 0 1 } - {ScrollingAnimations scrolling_animations "Scrolling Animations" 0 1 0 1 } - {BackgroundBlur background_blur "Background Blur" 0 1 0 1 } - {ThreadLines thread_lines "Thread Lines" 0 1 0 1 } - {BreakpointLines breakpoint_lines "Breakpoint Lines" 0 1 0 1 } - {ThreadGlow thread_glow "Thread Glow" 0 1 0 1 } - {BreakpointGlow breakpoint_glow "Breakpoint Glow" 0 1 0 1 } - {OpaqueBackgrounds opaque_backgrounds "Opaque Backgrounds" 0 0 0 1 } - {TabWidth tab_width "Tab Width" 0 4 1 32 } - {MainFontSize main_font_size "Main Font Size" 1 11 6 72 } - {CodeFontSize code_font_size "Code Font Size" 1 11 6 72 } - {SmoothUIText smooth_ui_text "Smooth UI Text" 1 1 0 1 } - {SmoothCodeText smooth_code_text "Smooth Code Text" 1 0 0 1 } - {HintUIText hint_ui_text "Hint UI Text" 1 1 0 1 } - {HintCodeText hint_code_text "Hint Code Text" 1 1 0 1 } -} - -@enum RD_SettingCode: -{ - @expand(RD_SettingTable a) `$(a.name)`, - COUNT -} - -@data(String8) rd_setting_code_display_string_table: -{ - @expand(RD_SettingTable a) `str8_lit_comp("$(a.display_string)")` -} - -@data(String8) rd_setting_code_lower_string_table: -{ - @expand(RD_SettingTable a) `str8_lit_comp("$(a.name_lower)")` -} - -@data(B8) rd_setting_code_default_is_per_window_table: -{ - @expand(RD_SettingTable a) `$(a.default_per_window)` -} - -@data(RD_SettingVal) rd_setting_code_default_val_table: -{ - @expand(RD_SettingTable a) `{1, $(a.default_s32)}` -} - -@data(Rng1S32) rd_setting_code_s32_range_table: -{ - @expand(RD_SettingTable a) `{$(a.s32_min), $(a.s32_max)}` -} - //////////////////////////////// //~ rjf: Help/Docs/README diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ac7f2240..ac0168b3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1479,6 +1479,49 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 return result; } +internal String8 +rd_setting_from_key(String8 key) +{ + String8 result = {0}; + { + // rjf: find most-granular config scope to begin looking for the setting + RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + + // rjf: scan upwards the config tree until we find the setting + RD_Cfg *setting = &rd_nil_cfg; + for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) + { + setting = rd_cfg_child_from_string(cfg, key); + } + + // rjf: return resultant child string stored under this key + result = setting->first->string; + + // rjf: no result -> look for default in settings schema + if(result.size == 0) ProfScope("default setting schema lookup") + { + Temp scratch = scratch_begin(0, 0); + String8 schema_string = {0}; + for EachElement(idx, rd_cfg_name_schema_pair_table) + { + if(str8_match(rd_cfg_name_schema_pair_table[idx].name, str8_lit("settings"), 0)) + { + schema_string = rd_cfg_name_schema_pair_table[idx].schema; + break; + } + } + MD_Node *schema = md_tree_from_string(scratch.arena, schema_string)->first; + MD_Node *setting = md_child_from_string(schema, key, 0); + MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + result = default_tag->first->string; + scratch_end(scratch); + } + } + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -3415,17 +3458,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - ws->setting_vals[code] = rd_setting_code_default_val_table[code]; - } - } - ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ws->setting_vals[RD_SettingCode_MainFontSize].s32 * (ws->last_dpi / 96.f); - ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ws->setting_vals[RD_SettingCode_CodeFontSize].s32 * (ws->last_dpi / 96.f); - ws->setting_vals[RD_SettingCode_MainFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_MainFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_MainFontSize].s32); - ws->setting_vals[RD_SettingCode_CodeFontSize].s32 = ClampBot(ws->setting_vals[RD_SettingCode_CodeFontSize].s32, rd_setting_code_default_val_table[RD_SettingCode_CodeFontSize].s32); OS_Handle zero_monitor = {0}; if(!os_handle_match(zero_monitor, preferred_monitor)) { @@ -3616,7 +3648,7 @@ rd_window_frame(void) ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_DropSiteOverlay]; - if(rd_setting_val_from_code(RD_SettingCode_OpaqueBackgrounds).s32) + if(rd_setting_b32_from_key(str8_lit("opaque_backgrounds"))) { for EachEnumVal(RD_PaletteCode, code) { @@ -3703,12 +3735,12 @@ rd_window_frame(void) // rjf: build animation info UI_AnimationInfo animation_info = {0}; { - if(rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_PressAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_FocusAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_TooltipAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} - if(rd_setting_val_from_code(RD_SettingCode_ScrollingAnimations).s32) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} + if(rd_setting_b32_from_key(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} + if(rd_setting_b32_from_key(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} + if(rd_setting_b32_from_key(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} + if(rd_setting_b32_from_key(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} + if(rd_setting_b32_from_key(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} + if(rd_setting_b32_from_key(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} } // rjf: begin & push initial stack values @@ -3721,8 +3753,8 @@ rd_window_frame(void) ui_push_palette(rd_palette_from_code(RD_PaletteCode_Base)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; - if(rd_setting_val_from_code(RD_SettingCode_SmoothUIText).s32) {text_raster_flags |= FNT_RasterFlag_Smooth;} - if(rd_setting_val_from_code(RD_SettingCode_HintUIText).s32) {text_raster_flags |= FNT_RasterFlag_Hinted;} + if(rd_setting_b32_from_key(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} + if(rd_setting_b32_from_key(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} ui_push_text_raster_flags(text_raster_flags); } @@ -6322,11 +6354,13 @@ rd_window_frame(void) //- rjf: animate { + B32 do_menu_animations = rd_setting_b32_from_key(str8_lit("menu_animations")); + F32 rate = do_menu_animations ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; + // rjf: animate height { - F32 fish_rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; F32 hover_eval_container_height_target = row_height * Min(30, block_tree.total_row_count); - ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * fish_rate; + ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * rate; if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) { rd_request_frame(); @@ -6339,9 +6373,8 @@ rd_window_frame(void) // rjf: animate open { - F32 fish_rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; F32 diff = 1.f - ws->hover_eval_open_t; - ws->hover_eval_open_t += diff*fish_rate; + ws->hover_eval_open_t += diff*rate; if(abs_f32(diff) < 0.01f) { ws->hover_eval_open_t = 1.f; @@ -7885,6 +7918,9 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); + //- rjf: unpack settings + B32 do_background_blur = rd_setting_b32_from_key(str8_lit("background_blur")); + //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; U64 *heatmap_buckets = 0; @@ -7959,7 +7995,7 @@ rd_window_frame(void) } // rjf: blur background - if(box->flags & UI_BoxFlag_DrawBackgroundBlur && rd_setting_val_from_code(RD_SettingCode_BackgroundBlur).s32) + if(box->flags & UI_BoxFlag_DrawBackgroundBlur && do_background_blur) { R_PassParams_Blur *params = dr_blur(pad_2f32(box->rect, 1.f), box->blur_size*(1-box->transparency), 0); MemoryCopyArray(params->corner_radii, box->corner_radii); @@ -10672,7 +10708,6 @@ rd_font_from_slot(RD_FontSlot slot) internal F32 rd_font_size_from_slot(RD_FontSlot slot) { - B32 explicit_config_found = 0; F32 result = 9.f; // rjf: determine config key based on slot @@ -10685,32 +10720,23 @@ rd_font_size_from_slot(RD_FontSlot slot) case RD_FontSlot_Code:{key = str8_lit("code_font_size");}break; } - // rjf: find most-granular config scope to begin looking for the setting - RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + // rjf: given key, find setting string + String8 setting_string = rd_setting_from_key(key); - // rjf: scan upwards the config tree until we find the setting - for(RD_Cfg *parent = start_cfg; parent != &rd_nil_cfg; parent = parent->parent) - { - RD_Cfg *child = rd_cfg_child_from_string(parent, key); - if(child != &rd_nil_cfg) - { - result = (F32)f64_from_str8(child->first->string); - explicit_config_found = 1; - break; - } - } - - // rjf: if we haven't found any explicit config, then use the window's monitor's DPI + // rjf: if found, map setting string -> f64; otherwise use the window's monitor's DPI // based on some default size. - if(explicit_config_found == 0) + if(setting_string.size) + { + result = (F32)f64_from_str8(setting_string); + } + else { RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); F32 dpi = os_dpi_from_window(ws->os); - result *= (dpi / 96.f); + result = 9.f * (dpi / 96.f); } + return result; } @@ -10722,38 +10748,12 @@ rd_raster_flags_from_slot(RD_FontSlot slot) { default:{}break; case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break; - case RD_FontSlot_Main: {flags = (!!rd_setting_val_from_code(RD_SettingCode_SmoothUIText).s32*FNT_RasterFlag_Smooth)|(!!rd_setting_val_from_code(RD_SettingCode_HintUIText).s32*FNT_RasterFlag_Hinted);}break; - case RD_FontSlot_Code: {flags = (!!rd_setting_val_from_code(RD_SettingCode_SmoothCodeText).s32*FNT_RasterFlag_Smooth)|(!!rd_setting_val_from_code(RD_SettingCode_HintCodeText).s32*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Main: {flags = (rd_setting_b32_from_key(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Code: {flags = (rd_setting_b32_from_key(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; } return flags; } -//- rjf: settings - -internal RD_SettingVal -rd_setting_val_from_code(RD_SettingCode code) -{ - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - RD_SettingVal result = {0}; - if(ws != 0) - { - result = ws->setting_vals[code]; - } - if(result.set == 0) - { - for EachEnumVal(RD_CfgSrc, src) - { - if(rd_state->cfg_setting_vals[src][code].set) - { - result = rd_state->cfg_setting_vals[src][code]; - break; - } - } - } - return result; -} - //- rjf: config serialization internal int @@ -13316,7 +13316,7 @@ rd_frame(void) case RD_CmdKind_IncCodeFontScale: { fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); @@ -13326,7 +13326,7 @@ rd_frame(void) case RD_CmdKind_DecCodeFontScale: { fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); + F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); @@ -16610,7 +16610,7 @@ X(getting_started) //- rjf: animate confirmation // { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; + F32 rate = rd_setting_b32_from_key(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; B32 popup_open = rd_state->popup_active; rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index f1da382d..2398512a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -652,7 +652,6 @@ struct RD_WindowState B32 window_temporarily_focused_ipc; // rjf: config/settings - RD_SettingVal setting_vals[RD_SettingCode_COUNT]; UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme // rjf: dev interface state @@ -936,9 +935,6 @@ struct RD_State String8 bind_change_cmd_name; RD_Binding bind_change_binding; - // rjf: global settings - RD_SettingVal cfg_setting_vals[RD_CfgSrc_COUNT][RD_SettingCode_COUNT]; - //- // TODO(rjf): TO BE ELIMINATED OR REPLACED ^^^^^^^^^^^^^^^^^^ //- @@ -1148,6 +1144,10 @@ internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); +internal String8 rd_setting_from_key(String8 key); +#define rd_setting_b32_from_key(key) (str8_match(rd_setting_from_key(key), str8_lit("1"), 0)) +#define rd_setting_u64_from_key(key) (u64_from_str8(rd_setting_from_key(key), 10)) + //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1352,9 +1352,6 @@ internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); internal F32 rd_font_size_from_slot(RD_FontSlot slot); internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); -//- rjf: settings -internal RD_SettingVal rd_setting_val_from_code(RD_SettingCode code); - //- rjf: config serialization internal int rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingPair *b); internal String8List rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d614ef07..8fd17d62 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -35,7 +35,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // FNT_Tag code_font = rd_font_from_slot(RD_FontSlot_Code); F32 code_font_size = rd_font_size_from_slot(RD_FontSlot_Code); - F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_val_from_code(RD_SettingCode_TabWidth).s32; + F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_key(str8_lit("tab_width")); FNT_Metrics code_font_metrics = fnt_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(fnt_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -1268,7 +1268,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo DI_Scope *di_scope = di_scope_open(); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32 ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; ////////////////////////////// //- rjf: unpack arguments @@ -6053,6 +6053,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) //////////////////////////////// //~ rjf: settings @view_hook_impl +#if 0 // TODO(rjf): @cfg typedef enum RD_SettingsItemKind { RD_SettingsItemKind_CategoryHeader, @@ -6123,6 +6124,7 @@ rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) } return result; } +#endif RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ce58c58e..3ae666d8 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -614,7 +614,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); - F32 entity_hover_t_rate = rd_setting_val_from_code(RD_SettingCode_HoverAnimations).s32 ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + B32 do_thread_lines = rd_setting_b32_from_key(str8_lit("thread_lines")); + B32 do_thread_glow = rd_setting_b32_from_key(str8_lit("thread_glow")); + B32 do_bp_lines = rd_setting_b32_from_key(str8_lit("breakpoint_lines")); + B32 do_bp_glow = rd_setting_b32_from_key(str8_lit("breakpoint_glow")); ////////////////////////////// //- rjf: build top-level container @@ -755,8 +759,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; - u->do_lines = rd_setting_val_from_code(RD_SettingCode_ThreadLines).s32; - u->do_glow = rd_setting_val_from_code(RD_SettingCode_ThreadGlow).s32; + u->do_lines = do_thread_lines; + u->do_glow = do_thread_glow; ui_box_equip_custom_draw(thread_box, rd_thread_box_draw_extensions, u); // rjf: fill out progress t (progress into range of current line's @@ -974,8 +978,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe bp_draw->color = bp_rgba; bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); - bp_draw->do_lines = rd_setting_val_from_code(RD_SettingCode_BreakpointLines).s32; - bp_draw->do_glow = rd_setting_val_from_code(RD_SettingCode_BreakpointGlow).s32; + bp_draw->do_lines = do_bp_lines; + bp_draw->do_glow = do_bp_glow; if(params->line_vaddrs[line_idx] == 0) { D_LineList *lines = ¶ms->line_infos[line_idx]; diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 2a515898..c0534cdf 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -60,7 +60,7 @@ "////////////////////////////////////////////////////////////////"; "//~ Format Constants"; ""; - "// \"raddbg\0\0\""; + "// \"raddbg\\0\\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; "#define RDI_ENCODING_VERSION 10"; ""; From 04e6eae49dc0c73b035d3d0c460d661f1d3d2bf9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 Jan 2025 12:28:52 -0800 Subject: [PATCH 023/755] progress on meta-evaluation of cfg trees & plugging into watch/eval system --- project.4coder | 2 +- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 10 +- src/raddbg/raddbg_core.c | 370 +++++++++++++++++++++-------- src/raddbg/raddbg_core.h | 65 ++++- src/raddbg/raddbg_views.c | 4 +- src/raddbg/raddbg_widgets.c | 10 +- 7 files changed, 347 insertions(+), 118 deletions(-) diff --git a/project.4coder b/project.4coder index 0d7a82c4..6e727228 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e9c96ee3..e218d564 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -76,9 +76,9 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'exe': path,\n 'args': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression':code_string,\n 'view_rule':code_string,\n 'location':location,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}")}, }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 3b6bac8d..f456797c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -147,8 +147,8 @@ RD_VocabularyMap: ```x: { 'label': code_string, - 'exe': path, - 'args': string, + 'executable': path, + 'arguments': string, 'working_directory': path, 'entry_point': code_string, 'stdout_path': path, @@ -178,9 +178,9 @@ RD_VocabularyMap: watch_pin, ```x: { - 'expression':code_string, - 'view_rule':code_string, - 'location':location, + 'expression': code_string, + 'view_rule': code_string, + 'location': location, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ac0168b3..578c3c77 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1479,8 +1479,24 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 return result; } +internal MD_Node * +rd_schema_from_name(Arena *arena, String8 name) +{ + String8 schema_string = {0}; + for EachElement(idx, rd_cfg_name_schema_pair_table) + { + if(str8_match(name, rd_cfg_name_schema_pair_table[idx].name, 0)) + { + schema_string = rd_cfg_name_schema_pair_table[idx].schema; + break; + } + } + MD_Node *schema = md_tree_from_string(arena, schema_string)->first; + return schema; +} + internal String8 -rd_setting_from_key(String8 key) +rd_setting_from_name(String8 name) { String8 result = {0}; { @@ -1493,7 +1509,7 @@ rd_setting_from_key(String8 key) RD_Cfg *setting = &rd_nil_cfg; for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) { - setting = rd_cfg_child_from_string(cfg, key); + setting = rd_cfg_child_from_string(cfg, name); } // rjf: return resultant child string stored under this key @@ -1503,17 +1519,8 @@ rd_setting_from_key(String8 key) if(result.size == 0) ProfScope("default setting schema lookup") { Temp scratch = scratch_begin(0, 0); - String8 schema_string = {0}; - for EachElement(idx, rd_cfg_name_schema_pair_table) - { - if(str8_match(rd_cfg_name_schema_pair_table[idx].name, str8_lit("settings"), 0)) - { - schema_string = rd_cfg_name_schema_pair_table[idx].schema; - break; - } - } - MD_Node *schema = md_tree_from_string(scratch.arena, schema_string)->first; - MD_Node *setting = md_child_from_string(schema, key, 0); + MD_Node *schema = rd_schema_from_name(scratch.arena, str8_lit("settings")); + MD_Node *setting = md_child_from_string(schema, name, 0); MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); result = default_tag->first->string; scratch_end(scratch); @@ -2329,6 +2336,107 @@ rd_eval_space_from_cfg(RD_Cfg *cfg) return space; } +internal String8 +rd_eval_blob_from_cfg(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) + { + if(rd_handle_match(handle, n->handle)) + { + node = n; + break; + } + } + + // rjf: no node? -> try to build one + if(node == 0) + { + // rjf: cfg name -> type + String8 name = cfg->string; + E_TypeKey type_key = zero_struct; + { + U64 name_hash = d_hash_from_string(name); + U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; + for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->string, name, 0)) + { + type_key = n->key; + break; + } + } + } + + // rjf: if this config has an eval type, build eval blob & cache + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + Temp scratch = scratch_begin(0, 0); + 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) + { + E_Member *member = &type->members[member_idx]; + String8 child_name = member->name; + MD_Node *member_schema = md_child_from_string(schema, child_name, 0); + String8 member_type_name = member_schema->first->string; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); + if(str8_match(member_type_name, str8_lit("code_string"), 0) || + str8_match(member_type_name, str8_lit("path"), 0) || + str8_match(member_type_name, str8_lit("string"), 0)) + { + 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, child->first->string); + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } + else if(str8_match(member_type_name, str8_lit("u64"), 0)) + { + U64 val = 0; + try_u64_from_str8_c_rules(child->first->string, &val); + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&val))); + } + else if(str8_match(member_type_name, str8_lit("bool"), 0)) + { + B32 val = str8_match(child->first->string, str8_lit("1"), 0); + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8((U8 *)&val, e_type_byte_size_from_key(member->type_key)))); + } + } + } + String8List all_parts = {0}; + str8_list_concat_in_place(&all_parts, &fixed_width_parts); + str8_list_concat_in_place(&all_parts, &variable_width_parts); + 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 = str8_list_join(rd_frame_arena(), &all_parts, 0); + scratch_end(scratch); + } + } + + // rjf: grab string from cached node + if(node != 0) + { + result = node->blob; + } + } + return result; +} + //- rjf: entity <-> eval space internal RD_Entity * @@ -2531,7 +2639,6 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) default:{}break; case CTRL_EntityKind_Process: { - Temp scratch = scratch_begin(0, 0); CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, d_state->frame_eval_memread_endt_us); String8 data = slice.data; if(data.size == dim_1u64(range)) @@ -2539,11 +2646,9 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) result = 1; MemoryCopy(out, data.str, data.size); } - scratch_end(scratch); }break; case CTRL_EntityKind_Thread: { - Temp scratch = scratch_begin(0, 0); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); U64 frame_idx = e_interpret_ctx->reg_unwind_count; if(frame_idx < unwind.frames.count) @@ -2556,12 +2661,25 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size); result = (read_size == dim_1u64(range)); } - scratch_end(scratch); }break; } }break; - //- rjf: meta reads (metadata about either control entities or debugger state) + //- rjf: meta-config reads + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(space); + String8 cfg_eval_blob = rd_eval_blob_from_cfg(cfg); + Rng1U64 legal_range = r1u64(0, cfg_eval_blob.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) + { + result = 1; + MemoryCopy(out, cfg_eval_blob.str + read_range.min, dim_1u64(read_range)); + } + }break; + + //- rjf: meta-control-enttiy reads (computed data about control entities) case RD_EvalSpaceKind_MetaCtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); @@ -3648,7 +3766,7 @@ rd_window_frame(void) ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_DropSiteOverlay]; - if(rd_setting_b32_from_key(str8_lit("opaque_backgrounds"))) + if(rd_setting_b32_from_name(str8_lit("opaque_backgrounds"))) { for EachEnumVal(RD_PaletteCode, code) { @@ -3735,12 +3853,12 @@ rd_window_frame(void) // rjf: build animation info UI_AnimationInfo animation_info = {0}; { - if(rd_setting_b32_from_key(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} - if(rd_setting_b32_from_key(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} - if(rd_setting_b32_from_key(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} - if(rd_setting_b32_from_key(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} - if(rd_setting_b32_from_key(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} - if(rd_setting_b32_from_key(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} + if(rd_setting_b32_from_name(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} + if(rd_setting_b32_from_name(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} + if(rd_setting_b32_from_name(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} + if(rd_setting_b32_from_name(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} + if(rd_setting_b32_from_name(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} + if(rd_setting_b32_from_name(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} } // rjf: begin & push initial stack values @@ -3753,8 +3871,8 @@ rd_window_frame(void) ui_push_palette(rd_palette_from_code(RD_PaletteCode_Base)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; - if(rd_setting_b32_from_key(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} - if(rd_setting_b32_from_key(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} + if(rd_setting_b32_from_name(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} + if(rd_setting_b32_from_name(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} ui_push_text_raster_flags(text_raster_flags); } @@ -6354,7 +6472,7 @@ rd_window_frame(void) //- rjf: animate { - B32 do_menu_animations = rd_setting_b32_from_key(str8_lit("menu_animations")); + B32 do_menu_animations = rd_setting_b32_from_name(str8_lit("menu_animations")); F32 rate = do_menu_animations ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; // rjf: animate height @@ -7919,7 +8037,7 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); //- rjf: unpack settings - B32 do_background_blur = rd_setting_b32_from_key(str8_lit("background_blur")); + B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; @@ -10708,7 +10826,7 @@ rd_font_from_slot(RD_FontSlot slot) internal F32 rd_font_size_from_slot(RD_FontSlot slot) { - F32 result = 9.f; + F32 result = 11.f; // rjf: determine config key based on slot String8 key = {0}; @@ -10721,7 +10839,7 @@ rd_font_size_from_slot(RD_FontSlot slot) } // rjf: given key, find setting string - String8 setting_string = rd_setting_from_key(key); + String8 setting_string = rd_setting_from_name(key); // rjf: if found, map setting string -> f64; otherwise use the window's monitor's DPI // based on some default size. @@ -10734,7 +10852,7 @@ rd_font_size_from_slot(RD_FontSlot slot) RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); F32 dpi = os_dpi_from_window(ws->os); - result = 9.f * (dpi / 96.f); + result = 11.f * (dpi / 96.f); } return result; @@ -10748,8 +10866,8 @@ rd_raster_flags_from_slot(RD_FontSlot slot) { default:{}break; case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break; - case RD_FontSlot_Main: {flags = (rd_setting_b32_from_key(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; - case RD_FontSlot_Code: {flags = (rd_setting_b32_from_key(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_key(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Main: {flags = (rd_setting_b32_from_name(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Code: {flags = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; } return flags; } @@ -11969,6 +12087,9 @@ rd_frame(void) rd_state->text_edit_mode = 0; rd_state->ctrl_entity_meval_cache_slots_count = 1024; rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count); + 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); ////////////////////////////// //- rjf: garbage collect untouched window states @@ -12666,7 +12787,8 @@ rd_frame(void) //- rjf: add macros for evallable config trees { - String8 evallable_names[] = + //- rjf: choose set of evallable config names + String8 evallable_cfg_names[] = { str8_lit("breakpoint"), str8_lit("watch_pin"), @@ -12674,66 +12796,115 @@ rd_frame(void) str8_lit("file_path_map"), str8_lit("auto_view_rule"), }; - for EachElement(idx, evallable_names) + + //- rjf: build special member types for evallable config types + E_TypeKey bool_type_key = {0}; + E_TypeKey u64_type_key = {0}; + E_TypeKey code_string_type_key = {0}; + E_TypeKey path_type_key = {0}; + E_TypeKey string_type_key = {0}; + E_TypeKey location_type_key = {0}; { - // rjf: determine schema string for this name - String8 schema_string = {0}; - for EachElement(schema_idx, rd_cfg_name_schema_pair_table) - { - if(str8_match(evallable_names[idx], rd_cfg_name_schema_pair_table[idx].name, 0)) - { - schema_string = rd_cfg_name_schema_pair_table[idx].schema; - break; - } - } - - // rjf: parse schema - MD_Node *schema = md_tree_from_string(scratch.arena, schema_string)->first; - - // rjf: form evaluation type from schema - + bool_type_key = e_type_key_basic(E_TypeKind_Bool); + u64_type_key = e_type_key_basic(E_TypeKind_U64); + code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsCodeText); + path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPathText); + string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText); + location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); } - } - - //- rjf: add macros for all evallable debugger frontend entities -#if 0 // TODO(rjf): @cfg - { - RD_EntityKind evallable_kinds[] = + + //- rjf: build types for each evallable config tree + struct { - RD_EntityKind_Breakpoint, - RD_EntityKind_WatchPin, - RD_EntityKind_Target, - RD_EntityKind_FilePathMap, - RD_EntityKind_AutoViewRule, + String8 schema_type_name; + E_TypeKey type_key; + } + schema_type_name_key_map[] = + { + { str8_lit("bool"), bool_type_key }, + { str8_lit("u64"), u64_type_key }, + { str8_lit("code_string"), code_string_type_key }, + { str8_lit("path"), path_type_key }, + { str8_lit("string"), string_type_key }, + { str8_lit("location"), location_type_key }, }; - E_TypeKey evallable_kind_types[] = + E_TypeKey evallable_cfg_types[ArrayCount(evallable_cfg_names)] = {0}; + for EachElement(idx, evallable_cfg_names) { - e_type_key_cons_base(type(CTRL_BreakpointMetaEval)), - e_type_key_cons_base(type(CTRL_PinMetaEval)), - e_type_key_cons_base(type(CTRL_TargetMetaEval)), - e_type_key_cons_base(type(CTRL_FilePathMapMetaEval)), - e_type_key_cons_base(type(CTRL_AutoViewRuleMetaEval)), - }; - for EachElement(idx, evallable_kinds) - { - RD_EntityList list = rd_query_cached_entity_list_with_kind(evallable_kinds[idx]); - for(RD_EntityNode *n = list.first; n != 0; n = n->next) + String8 name = evallable_cfg_names[idx]; + MD_Node *schema = rd_schema_from_name(scratch.arena, name); + E_MemberList members_list = {0}; + U64 off = 0; + for MD_EachNode(child, schema->first) { - RD_Entity *entity = n->entity; - E_Space space = rd_eval_space_from_entity(entity); + String8 member_name = child->string; + String8 member_pretty_name = rd_display_from_code_name(member_name); + E_TypeKey member_type_key = zero_struct; + for EachElement(schema_type_name_idx, schema_type_name_key_map) + { + if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) + { + member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; + break; + } + } + e_member_list_push_new(scratch.arena, &members_list, + .type_key = member_type_key, + .name = member_name, + .pretty_name = member_pretty_name, + .off = off); + off += e_type_byte_size_from_key(member_type_key); + } + E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); + evallable_cfg_types[idx] = e_type_key_cons(.name = name, + .kind = E_TypeKind_Struct, + .members = members.v, + .count = members.count); + } + + //- rjf: cache cfg name -> type key correllation + rd_state->cfg_string2typekey_map = push_array(rd_frame_arena(), RD_String2TypeKeyMap, 1); + rd_state->cfg_string2typekey_map->slots_count = 256; + rd_state->cfg_string2typekey_map->slots = push_array(rd_frame_arena(), RD_String2TypeKeySlot, rd_state->cfg_string2typekey_map->slots_count); + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + E_TypeKey type_key = evallable_cfg_types[idx]; + U64 hash = d_hash_from_string(name); + U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; + RD_String2TypeKeyNode *node = push_array(rd_frame_arena(), RD_String2TypeKeyNode, 1); + node->string = push_str8_copy(rd_frame_arena(), name); + node->key = type_key; + SLLQueuePush(rd_state->cfg_string2typekey_map->slots[slot_idx].first, rd_state->cfg_string2typekey_map->slots[slot_idx].last, node); + } + + //- rjf: add macros for each evallable config tree + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + RD_Cfg *cfg = n->v; + String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; + String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + E_Space space = rd_eval_space_from_cfg(cfg); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = space; expr->mode = E_Mode_Offset; - expr->type_key = evallable_kind_types[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64u", entity->id), expr); - if(entity->string.size != 0 && entity->kind != RD_EntityKind_WatchPin) + expr->type_key = evallable_cfg_types[idx]; + if(exe.size != 0) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); } + if(label.size != 0) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); + } + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x%I64x", (U64)cfg, cfg->gen), expr); } } } -#endif //- rjf: add macros for all evallable control entities { @@ -12785,11 +12956,11 @@ rd_frame(void) } //- rjf: add macros for all watches which define identifiers - RD_EntityList watches = rd_query_cached_entity_list_with_kind(RD_EntityKind_Watch); - for(RD_EntityNode *n = watches.first; n != 0; n = n->next) + RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + for(RD_CfgNode *n = watches.first; n != 0; n = n->next) { - RD_Entity *watch = n->entity; - String8 expr = watch->string; + RD_Cfg *watch = n->v; + String8 expr = rd_expr_from_cfg(watch); E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr, &tokens); if(parse.msgs.max_kind == E_MsgKind_Null) @@ -13530,42 +13701,41 @@ rd_frame(void) case RD_CmdKind_FocusPanelDown: panel_change_dir = v2s32(+0, +1); goto focus_panel_dir; focus_panel_dir:; { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = ws->focused_panel; - Rng2F32 src_panel_rect = rd_target_rect_from_panel(r2f32(v2f32(0, 0), v2f32(1000, 1000)), ws->root_panel, src_panel); + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *src_panel = panel_tree.focused; + Rng2F32 src_panel_rect = rd_target_rect_from_panel_node(r2f32(v2f32(0, 0), v2f32(1000, 1000)), panel_tree.root, src_panel); Vec2F32 src_panel_center = center_2f32(src_panel_rect); Vec2F32 src_panel_half_dim = scale_2f32(dim_2f32(src_panel_rect), 0.5f); Vec2F32 travel_dim = add_2f32(src_panel_half_dim, v2f32(10.f, 10.f)); Vec2F32 travel_dst = add_2f32(src_panel_center, mul_2f32(travel_dim, v2f32((F32)panel_change_dir.x, (F32)panel_change_dir.y))); - RD_Panel *dst_root = &rd_nil_panel; - for(RD_Panel *p = ws->root_panel; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_PanelNode *dst_root = &rd_nil_panel_node; + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { - if(p == src_panel || !rd_panel_is_nil(p->first)) + if(p == src_panel || p->first != &rd_nil_panel_node) { continue; } - Rng2F32 p_rect = rd_target_rect_from_panel(r2f32(v2f32(0, 0), v2f32(1000, 1000)), ws->root_panel, p); + Rng2F32 p_rect = rd_target_rect_from_panel_node(r2f32(v2f32(0, 0), v2f32(1000, 1000)), panel_tree.root, p); if(contains_2f32(p_rect, travel_dst)) { dst_root = p; break; } } - if(!rd_panel_is_nil(dst_root)) + if(dst_root != &rd_nil_panel_node) { - RD_Panel *dst_panel = &rd_nil_panel; - for(RD_Panel *p = dst_root; !rd_panel_is_nil(p); p = rd_panel_rec_depth_first_pre(p).next) + RD_PanelNode *dst_panel = &rd_nil_panel_node; + for(RD_PanelNode *p = dst_root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(dst_root, p).next) { - if(rd_panel_is_nil(p->first) && p != src_panel) + if(p->first == &rd_nil_panel_node && p != src_panel) { dst_panel = p; break; } } - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(dst_panel)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(dst_panel->cfg)); } -#endif }break; //- rjf: undo/redo @@ -16610,7 +16780,7 @@ X(getting_started) //- rjf: animate confirmation // { - F32 rate = rd_setting_b32_from_key(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; + F32 rate = rd_setting_b32_from_name(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; B32 popup_open = rd_state->popup_active; rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 2398512a..06e65945 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -764,6 +764,56 @@ struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheNode *last; }; +//////////////////////////////// +//~ rjf: String -> Type Key Map Helper Data Structure + +typedef struct RD_String2TypeKeyNode RD_String2TypeKeyNode; +struct RD_String2TypeKeyNode +{ + RD_String2TypeKeyNode *next; + String8 string; + E_TypeKey key; +}; + +typedef struct RD_String2TypeKeySlot RD_String2TypeKeySlot; +struct RD_String2TypeKeySlot +{ + RD_String2TypeKeyNode *first; + RD_String2TypeKeyNode *last; +}; + +typedef struct RD_String2TypeKeyMap RD_String2TypeKeyMap; +struct RD_String2TypeKeyMap +{ + U64 slots_count; + RD_String2TypeKeySlot *slots; +}; + +//////////////////////////////// +//~ rjf: Config -> Eval Blob Cache Types + +typedef struct RD_Cfg2EvalBlobNode RD_Cfg2EvalBlobNode; +struct RD_Cfg2EvalBlobNode +{ + RD_Cfg2EvalBlobNode *next; + RD_Handle handle; + String8 blob; +}; + +typedef struct RD_Cfg2EvalBlobSlot RD_Cfg2EvalBlobSlot; +struct RD_Cfg2EvalBlobSlot +{ + RD_Cfg2EvalBlobNode *first; + RD_Cfg2EvalBlobNode *last; +}; + +typedef struct RD_Cfg2EvalBlobMap RD_Cfg2EvalBlobMap; +struct RD_Cfg2EvalBlobMap +{ + U64 slots_count; + RD_Cfg2EvalBlobSlot *slots; +}; + //////////////////////////////// //~ rjf: Main Per-Process Graphical State @@ -833,6 +883,12 @@ struct RD_State RD_Theme *theme; RD_Theme *theme_target; + // rjf: config name -> eval type key map (constructed from-scratch each frame) + RD_String2TypeKeyMap *cfg_string2typekey_map; + + // rjf: config -> eval blob map (lazily constructed from-scratch each frame) + RD_Cfg2EvalBlobMap *cfg2evalblob_map; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -1144,9 +1200,11 @@ internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); -internal String8 rd_setting_from_key(String8 key); -#define rd_setting_b32_from_key(key) (str8_match(rd_setting_from_key(key), str8_lit("1"), 0)) -#define rd_setting_u64_from_key(key) (u64_from_str8(rd_setting_from_key(key), 10)) +internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); + +internal String8 rd_setting_from_name(String8 name); +#define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) +#define rd_setting_u64_from_name(name) (u64_from_str8(rd_setting_from_name(name), 10)) //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1201,6 +1259,7 @@ internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_E //- rjf: cfg <-> eval space internal RD_Cfg *rd_cfg_from_eval_space(E_Space space); internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); +internal String8 rd_eval_blob_from_cfg(RD_Cfg *cfg); //- rjf: entity <-> eval space internal RD_Entity *rd_entity_from_eval_space(E_Space space); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8fd17d62..9797b8c5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -35,7 +35,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // FNT_Tag code_font = rd_font_from_slot(RD_FontSlot_Code); F32 code_font_size = rd_font_size_from_slot(RD_FontSlot_Code); - F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_key(str8_lit("tab_width")); + F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_name(str8_lit("tab_width")); FNT_Metrics code_font_metrics = fnt_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(fnt_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -1268,7 +1268,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo DI_Scope *di_scope = di_scope_open(); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; ////////////////////////////// //- rjf: unpack arguments diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 3ae666d8..d33e32bd 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -614,11 +614,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); - F32 entity_hover_t_rate = rd_setting_b32_from_key(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; - B32 do_thread_lines = rd_setting_b32_from_key(str8_lit("thread_lines")); - B32 do_thread_glow = rd_setting_b32_from_key(str8_lit("thread_glow")); - B32 do_bp_lines = rd_setting_b32_from_key(str8_lit("breakpoint_lines")); - B32 do_bp_glow = rd_setting_b32_from_key(str8_lit("breakpoint_glow")); + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + B32 do_thread_lines = rd_setting_b32_from_name(str8_lit("thread_lines")); + B32 do_thread_glow = rd_setting_b32_from_name(str8_lit("thread_glow")); + B32 do_bp_lines = rd_setting_b32_from_name(str8_lit("breakpoint_lines")); + B32 do_bp_glow = rd_setting_b32_from_name(str8_lit("breakpoint_glow")); ////////////////////////////// //- rjf: build top-level container From aa03955a4577d4719da4c2053a0e1c38f9069602 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 Jan 2025 13:22:14 -0800 Subject: [PATCH 024/755] first pass at meta-cfg-space writes, for cfg editing --- src/raddbg/raddbg_core.c | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 578c3c77..8d049db0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2785,6 +2785,99 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } }break; + //- rjf: meta-config writes + case RD_EvalSpaceKind_MetaCfg: + { + Temp scratch = scratch_begin(0, 0); + + // rjf: unpack + RD_Cfg *cfg = rd_cfg_from_eval_space(space); + String8 eval_blob = rd_eval_blob_from_cfg(cfg); + MD_Node *schema = rd_schema_from_name(scratch.arena, cfg->string); + + // rjf: cfg name -> type key + String8 name = cfg->string; + E_TypeKey type_key = zero_struct; + { + U64 name_hash = d_hash_from_string(name); + U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; + for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->string, name, 0)) + { + type_key = n->key; + break; + } + } + } + + // rjf: key -> type + E_Type *type = e_type_from_key(scratch.arena, type_key); + + // rjf: find member to which this write applies, reflect back in the cfg tree + if(type->members != 0) for EachIndex(member_idx, type->count) + { + E_Member *member = &type->members[member_idx]; + Rng1U64 member_range = r1u64(member->off, member->off + e_type_byte_size_from_key(member->type_key)); + String8 child_name = member->name; + MD_Node *member_schema = md_child_from_string(schema, child_name, 0); + String8 member_type_name = member_schema->first->string; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); + if((str8_match(member_type_name, str8_lit("code_string"), 0) || + str8_match(member_type_name, str8_lit("path"), 0) || + str8_match(member_type_name, str8_lit("string"), 0)) && + member->off+sizeof(U64) <= eval_blob.size) + { + U64 string_off = *(U64 *)(eval_blob.str + member->off); + U64 string_opl = string_off + child->first->string.size + 1; + Rng1U64 string_range = r1u64(string_off, string_opl); + if(contains_1u64(string_range, range.min)) + { + String8 pre_edit_string = push_str8_copy(scratch.arena, str8(eval_blob.str + member->off, child->first->string.size)); + String8 post_edit_string = ui_push_string_replace_range(scratch.arena, pre_edit_string, r1s64(range.min-string_range.min+1, range.max-string_range.min+1), str8((U8 *)in, dim_1u64(range))); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_new(child, post_edit_string); + result = 1; + break; + } + } + else if(str8_match(member_type_name, str8_lit("u64"), 0) && dim_1u64(range) >= 1 && contains_1u64(member_range, range.min)) + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_newf(child, "%I64u", value); + result = 1; + break; + } + else if(str8_match(member_type_name, str8_lit("bool"), 0) && dim_1u64(range) >= 1 && contains_1u64(member_range, range.min)) + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_newf(child, "%I64u", value); + result = 1; + break; + } + } + + scratch_end(scratch); + }break; + //- rjf: meta-entity writes case RD_EvalSpaceKind_MetaEntity: { From 730e8a47208eba9d1fc751cf200924638b7f1a3e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 Jan 2025 15:55:08 -0800 Subject: [PATCH 025/755] commit cfg changes to eval blob cache immediately --- src/raddbg/raddbg_core.c | 264 ++++++++++++++++++++++++--------------- src/raddbg/raddbg_core.h | 5 +- 2 files changed, 165 insertions(+), 104 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8d049db0..216c506f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2336,107 +2336,6 @@ rd_eval_space_from_cfg(RD_Cfg *cfg) return space; } -internal String8 -rd_eval_blob_from_cfg(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) - { - if(rd_handle_match(handle, n->handle)) - { - node = n; - break; - } - } - - // rjf: no node? -> try to build one - if(node == 0) - { - // rjf: cfg name -> type - String8 name = cfg->string; - E_TypeKey type_key = zero_struct; - { - U64 name_hash = d_hash_from_string(name); - U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; - for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->string, name, 0)) - { - type_key = n->key; - break; - } - } - } - - // rjf: if this config has an eval type, build eval blob & cache - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - Temp scratch = scratch_begin(0, 0); - 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) - { - E_Member *member = &type->members[member_idx]; - String8 child_name = member->name; - MD_Node *member_schema = md_child_from_string(schema, child_name, 0); - String8 member_type_name = member_schema->first->string; - RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); - if(str8_match(member_type_name, str8_lit("code_string"), 0) || - str8_match(member_type_name, str8_lit("path"), 0) || - str8_match(member_type_name, str8_lit("string"), 0)) - { - 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, child->first->string); - str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); - } - else if(str8_match(member_type_name, str8_lit("u64"), 0)) - { - U64 val = 0; - try_u64_from_str8_c_rules(child->first->string, &val); - str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&val))); - } - else if(str8_match(member_type_name, str8_lit("bool"), 0)) - { - B32 val = str8_match(child->first->string, str8_lit("1"), 0); - str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8((U8 *)&val, e_type_byte_size_from_key(member->type_key)))); - } - } - } - String8List all_parts = {0}; - str8_list_concat_in_place(&all_parts, &fixed_width_parts); - str8_list_concat_in_place(&all_parts, &variable_width_parts); - 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 = str8_list_join(rd_frame_arena(), &all_parts, 0); - scratch_end(scratch); - } - } - - // rjf: grab string from cached node - if(node != 0) - { - result = node->blob; - } - } - return result; -} - //- rjf: entity <-> eval space internal RD_Entity * @@ -2487,6 +2386,140 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) return space; } +//- rjf: cfg -> eval blob + +internal String8 +rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + String8 result = {0}; + + // rjf: cfg name -> type + String8 name = cfg->string; + E_TypeKey type_key = zero_struct; + { + U64 name_hash = d_hash_from_string(name); + U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; + for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->string, name, 0)) + { + type_key = n->key; + break; + } + } + } + + // rjf: if this config has an eval type, build eval blob & cache + 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) + { + E_Member *member = &type->members[member_idx]; + String8 child_name = member->name; + MD_Node *member_schema = md_child_from_string(schema, child_name, 0); + String8 member_type_name = member_schema->first->string; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); + if(str8_match(member_type_name, str8_lit("code_string"), 0) || + str8_match(member_type_name, str8_lit("path"), 0) || + str8_match(member_type_name, str8_lit("string"), 0)) + { + 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, child->first->string); + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } + else if(str8_match(member_type_name, str8_lit("u64"), 0)) + { + U64 val = 0; + try_u64_from_str8_c_rules(child->first->string, &val); + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&val))); + } + else if(str8_match(member_type_name, str8_lit("bool"), 0)) + { + B32 val = str8_match(child->first->string, str8_lit("1"), 0); + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8((U8 *)&val, e_type_byte_size_from_key(member->type_key)))); + } + } + } + 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_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) + { + if(rd_handle_match(handle, n->handle)) + { + node = n; + break; + } + } + + // rjf: no node? -> try to build one + if(node == 0) + { + // rjf: cfg name -> type + String8 name = cfg->string; + E_TypeKey type_key = zero_struct; + { + U64 name_hash = d_hash_from_string(name); + U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; + for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->string, name, 0)) + { + type_key = n->key; + break; + } + } + } + + // rjf: if this config has an eval type, build eval blob & cache + 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); + } + } + + // rjf: grab string from cached node + if(node != 0) + { + result = node->blob; + } + } + return result; +} + //- rjf: entity -> meta eval internal CTRL_MetaEval * @@ -2669,7 +2702,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case RD_EvalSpaceKind_MetaCfg: { RD_Cfg *cfg = rd_cfg_from_eval_space(space); - String8 cfg_eval_blob = rd_eval_blob_from_cfg(cfg); + String8 cfg_eval_blob = rd_eval_blob_from_cfg__cached(cfg); Rng1U64 legal_range = r1u64(0, cfg_eval_blob.size); Rng1U64 read_range = intersect_1u64(range, legal_range); if(read_range.min < read_range.max) @@ -2792,7 +2825,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) // rjf: unpack RD_Cfg *cfg = rd_cfg_from_eval_space(space); - String8 eval_blob = rd_eval_blob_from_cfg(cfg); + String8 eval_blob = rd_eval_blob_from_cfg__cached(cfg); MD_Node *schema = rd_schema_from_name(scratch.arena, cfg->string); // rjf: cfg name -> type key @@ -2875,6 +2908,31 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } } + // rjf: commit to the eval blob cache + { + 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) + { + if(rd_handle_match(handle, n->handle)) + { + node = n; + break; + } + } + + // rjf: if node -> commit + if(node) + { + node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); + } + } + scratch_end(scratch); }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 06e65945..83087c58 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1259,7 +1259,6 @@ internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_E //- rjf: cfg <-> eval space internal RD_Cfg *rd_cfg_from_eval_space(E_Space space); internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); -internal String8 rd_eval_blob_from_cfg(RD_Cfg *cfg); //- rjf: entity <-> eval space internal RD_Entity *rd_entity_from_eval_space(E_Space space); @@ -1269,6 +1268,10 @@ internal E_Space rd_eval_space_from_entity(RD_Entity *entity); 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); +//- rjf: cfg -> eval blob +internal String8 rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg); +internal String8 rd_eval_blob_from_cfg__cached(RD_Cfg *cfg); + //- 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); From c0f23c38078482ebbdb35382c6138f27dd2e7fe9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 27 Jan 2025 09:22:34 -0800 Subject: [PATCH 026/755] further tweaks to support meta cfg eval --- src/raddbg/raddbg_core.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 216c506f..a292cddd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2869,7 +2869,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) if(contains_1u64(string_range, range.min)) { String8 pre_edit_string = push_str8_copy(scratch.arena, str8(eval_blob.str + member->off, child->first->string.size)); - String8 post_edit_string = ui_push_string_replace_range(scratch.arena, pre_edit_string, r1s64(range.min-string_range.min+1, range.max-string_range.min+1), str8((U8 *)in, dim_1u64(range))); + String8 post_edit_string = ui_push_string_replace_range(scratch.arena, pre_edit_string, r1s64(range.min-string_range.min+1, range.max-string_range.min+1), str8_cstring_capped(in, (U8 *)in + dim_1u64(range))); if(child == &rd_nil_cfg) { child = rd_cfg_new(cfg, child_name); @@ -9450,7 +9450,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } } if(eval.space.kind == RD_EvalSpaceKind_MetaEntity || - eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + eval.space.kind == RD_EvalSpaceKind_MetaCfg) { E_TypeKind kind = e_type_kind_from_key(eval.type_key); if(kind != E_TypeKind_Ptr) @@ -9548,9 +9549,15 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul String8 string_escaped = ev_escaped_from_raw_string(arena, string); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - str8_list_push(arena, out, str8_lit("\"")); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } str8_list_push(arena, out, string_escaped); - str8_list_push(arena, out, str8_lit("\"")); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } } // rjf: special case: push strings for symbols @@ -9674,9 +9681,15 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul String8 string_escaped = ev_escaped_from_raw_string(arena, string); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - str8_list_push(arena, out, str8_lit("\"")); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } str8_list_push(arena, out, string_escaped); - str8_list_push(arena, out, str8_lit("\"")); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } } // rjf: descend in all other cases From b085acbc32c681d88a763a4bf00a99292b108087 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 27 Jan 2025 11:02:49 -0800 Subject: [PATCH 027/755] strip out collection type - instead we will implement collections via arrays of exprs which map to meta evals --- src/eval/eval.mdesk | 1 - src/eval/generated/eval.meta.c | 6 ++---- src/eval/generated/eval.meta.h | 5 ++--- src/raddbg/raddbg_core.c | 15 +++------------ 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 0c7aba70..135213cb 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,7 +71,6 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } - {Collection "collection" 0 } } @table(name op_kind precedence string op_pre op_sep op_pos) diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index dd52f65a..228ef2fd 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -135,7 +135,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, }; -U8 e_kind_basic_byte_size_table[56] = +U8 e_kind_basic_byte_size_table[55] = { 0, 0, @@ -192,10 +192,9 @@ U8 e_kind_basic_byte_size_table[56] = 0, 0, 0, -0, }; -String8 e_kind_basic_string_table[56] = +String8 e_kind_basic_string_table[55] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -252,7 +251,6 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), -str8_lit_comp("collection"), }; C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index c4dc0adc..2dc6342f 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,7 +74,6 @@ 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, @@ -164,8 +163,8 @@ extern String8 e_token_kind_strings[6]; extern String8 e_expr_kind_strings[49]; extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[49]; -extern U8 e_kind_basic_byte_size_table[56]; -extern String8 e_kind_basic_string_table[56]; +extern U8 e_kind_basic_byte_size_table[55]; +extern String8 e_kind_basic_string_table[55]; C_LINKAGE_END diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a292cddd..857fb023 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2868,14 +2868,13 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) Rng1U64 string_range = r1u64(string_off, string_opl); if(contains_1u64(string_range, range.min)) { - String8 pre_edit_string = push_str8_copy(scratch.arena, str8(eval_blob.str + member->off, child->first->string.size)); - String8 post_edit_string = ui_push_string_replace_range(scratch.arena, pre_edit_string, r1s64(range.min-string_range.min+1, range.max-string_range.min+1), str8_cstring_capped(in, (U8 *)in + dim_1u64(range))); + String8 new_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); if(child == &rd_nil_cfg) { child = rd_cfg_new(cfg, child_name); } rd_cfg_release_all_children(child); - rd_cfg_new(child, post_edit_string); + rd_cfg_new(child, new_string); result = 1; break; } @@ -9796,14 +9795,6 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } }break; - - //- rjf: collections - case E_TypeKind_Collection: - { - String8 placeholder = str8_lit("{...}"); - str8_list_push(arena, out, placeholder); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, placeholder).x; - }break; } scratch_end(scratch); @@ -12924,7 +12915,7 @@ rd_frame(void) E_TypeKey collection_type_keys[ArrayCount(rd_collection_name_table)] = {0}; for EachElement(idx, rd_collection_name_table) { - collection_type_keys[idx] = e_type_key_cons(.kind = E_TypeKind_Collection, .name = rd_collection_name_table[idx]); + collection_type_keys[idx] = e_type_key_cons(.kind = E_TypeKind_Array, .name = rd_collection_name_table[idx]); } //////////////////////////// From 4cc5f636fe8ec63bec4bf844c26cf5c3c44268c6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 27 Jan 2025 15:33:35 -0800 Subject: [PATCH 028/755] cfg tree collection evaluation --- src/eval/eval.mdesk | 1 + src/eval/eval_bundles.c | 4 +- src/eval/eval_interpret.c | 25 +- src/eval/eval_interpret.h | 1 + src/eval/eval_ir.c | 200 +++---- src/eval/eval_ir.h | 9 +- src/eval/eval_types.c | 17 + src/eval/eval_types.h | 1 + src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- src/raddbg/generated/raddbg.meta.c | 49 +- src/raddbg/generated/raddbg.meta.h | 34 +- src/raddbg/raddbg.mdesk | 10 +- src/raddbg/raddbg_core.c | 843 +++++++++++------------------ src/raddbg/raddbg_core.h | 23 +- 15 files changed, 505 insertions(+), 723 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 135213cb..5fc62ece 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,6 +71,7 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } + {SpacePtr "space_ptr" 0 } } @table(name op_kind precedence string op_pre op_sep op_pos) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 5cdf357c..15cf1087 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -11,13 +11,11 @@ e_eval_from_expr(Arena *arena, E_Expr *expr) E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); E_Interpretation interp = e_interpret(bytecode); - E_Space zero_space = {0}; - E_Space space = (MemoryMatchStruct(&zero_space, &irtree.space) ? e_interpret_ctx->primary_space : irtree.space); E_Eval eval = { .value = interp.value, .mode = irtree.mode, - .space = space, + .space = interp.space, .expr = expr, .type_key = irtree.type_key, .code = interp.code, diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index c7c824a4..e507c46b 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -74,7 +74,8 @@ e_interpret(String8 bytecode) } else switch(op) { - case E_IRExtKind_SetSpace:{ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break; + case E_IRExtKind_SetSpace: {ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break; + case E_IRExtKind_DerefSpacePtr:{ctrlbits = RDI_EVAL_CTRLBITS(0, 1, 1);}break; default: { result.code = E_InterpretationCode_BadOp; @@ -124,6 +125,27 @@ e_interpret(String8 bytecode) MemoryCopy(&selected_space, &imm, sizeof(selected_space)); }break; + case E_IRExtKind_DerefSpacePtr: + { + U64 addr = svals[0].u64; + U64 size = sizeof(E_Space) + sizeof(U64); + typedef struct SpacePtrRead SpacePtrRead; + struct SpacePtrRead + { + E_Space space; + U64 off; + }; + SpacePtrRead space_ptr_read = {0}; + B32 good_read = e_space_read(selected_space, &space_ptr_read, r1u64(addr, addr+size)); + if(!good_read) + { + result.code = E_InterpretationCode_BadMemRead; + goto done; + } + MemoryCopyStruct(&selected_space, &space_ptr_read.space); + nval.u64 = space_ptr_read.off; + }break; + case RDI_EvalOp_Stop: { goto done; @@ -812,6 +834,7 @@ e_interpret(String8 bytecode) { result.value = stack[0]; } + result.space = selected_space; scratch_end(scratch); return result; } diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 3a9d0b51..68c6b029 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -11,6 +11,7 @@ typedef struct E_Interpretation E_Interpretation; struct E_Interpretation { E_Value value; + E_Space space; E_InterpretationCode code; }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 49fdda40..4b9957b8 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -145,6 +145,16 @@ e_oplist_push_set_space(Arena *arena, E_OpList *list, E_Space space) list->encoded_size += 1 + sizeof(space); } +internal void +e_oplist_push_deref_space_ptr(Arena *arena, E_OpList *list) +{ + E_Op *node = push_array_no_zero(arena, E_Op, 1); + node->opcode = E_IRExtKind_DerefSpacePtr; + SLLQueuePush(list->first, list->last, node); + list->op_count += 1; + list->encoded_size += 1; +} + internal void e_oplist_push_string_literal(Arena *arena, E_OpList *list, String8 string) { @@ -274,7 +284,15 @@ e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c) } internal E_IRNode * -e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_key) +e_irtree_deref_space_ptr(Arena *arena, E_IRNode *c) +{ + E_IRNode *root = e_push_irnode(arena, E_IRExtKind_DerefSpacePtr); + e_irnode_push_child(root, c); + return root; +} + +internal E_IRNode * +e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key) { E_IRNode *result = &e_irnode_nil; U64 byte_size = e_type_byte_size_from_key(type_key); @@ -296,11 +314,8 @@ e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_ e_irnode_push_child(with_trunc, read_node); } - // rjf: set space for this mem read - E_IRNode *set_space_node = e_irtree_set_space(arena, space, with_trunc); - // rjf: fill - result = set_space_node; + result = with_trunc; return result; } @@ -358,12 +373,12 @@ e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in) } internal E_IRNode * -e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key) +e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key) { E_IRNode *result = tree; if(from_mode == E_Mode_Offset) { - result = e_irtree_mem_read_type(arena, from_space, tree, type_key); + result = e_irtree_mem_read_type(arena, tree, type_key); } return result; } @@ -371,7 +386,7 @@ e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_ //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) +e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr) { E_IRTreeAndType result = {&e_irnode_nil}; E_ExprKind kind = expr->kind; @@ -382,7 +397,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) //- rjf: references -> just descend to sub-expr case E_ExprKind_Ref: { - result = e_irtree_and_type_from_expr(arena, expr->ref); + result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref); }break; //- rjf: array indices @@ -391,8 +406,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: unpack left/right expressions E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); - E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); + E_IRTreeAndType r = e_irtree_and_type_from_expr__space(arena, current_space, exprr); E_TypeKey l_restype = e_type_unwrap(l.type_key); E_TypeKey r_restype = e_type_unwrap(r.type_key); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); @@ -446,7 +461,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) case E_Mode_Offset: { // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.space, r.mode, r.root, r_restype); + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); if(direct_type_size > 1) { E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); @@ -457,7 +472,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *base_tree = l.root; if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) { - base_tree = e_irtree_resolve_to_value(arena, l.space, l.mode, base_tree, l_restype); + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); } // rjf: ops to compute the final address @@ -468,7 +483,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) case E_Mode_Value: { // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.space, r.mode, r.root, r_restype); + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); if(direct_type_size > 1) { E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); @@ -488,7 +503,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = direct_type; result.mode = l.mode; - result.space = l.space; }break; //- rjf: member accesses @@ -497,7 +511,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: unpack left/right expressions E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); E_TypeKey l_restype = e_type_unwrap(l.type_key); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); E_TypeKey check_type_key = l_restype; @@ -589,7 +603,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) l_restype_kind == E_TypeKind_LRef || l_restype_kind == E_TypeKind_RRef) { - new_tree = e_irtree_resolve_to_value(arena, l.space, l.mode, new_tree, l_restype); + new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); mode = E_Mode_Offset; } if(r_value != 0 && !r_is_constant_value) @@ -607,7 +621,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = r_type; result.mode = mode; - result.space = l.space; } }break; @@ -616,7 +629,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_direct_from_key(r_type); @@ -658,12 +671,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) r_type_kind == E_TypeKind_LRef || r_type_kind == E_TypeKind_RRef)) { - new_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + new_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); } result.root = new_tree; result.type_key = r_type_direct; result.mode = E_Mode_Offset; - result.space = r_tree.space; } }break; @@ -672,7 +684,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_unwrap(r_type); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); @@ -692,7 +704,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = r_tree.root; result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 0); result.mode = E_Mode_Value; - result.space = r_tree.space; }break; //- rjf: cast @@ -704,7 +715,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_TypeKey cast_type = e_type_from_expr(cast_type_expr); E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); + E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr__space(arena, current_space, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -736,7 +747,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.space, casted_tree.mode, casted_tree.root, casted_type); + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); E_IRNode *new_tree = in_tree; if(conversion_rule == RDI_EvalConversionKind_Legal) { @@ -749,7 +760,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = cast_type; result.mode = E_Mode_Value; - result.space = casted_tree.space; } }break; @@ -771,10 +781,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) }break; default: { - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; - space = r_tree.space; }break; } @@ -794,7 +803,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = e_irtree_const_u(arena, r_type_byte_size); result.type_key = e_type_key_basic(E_TypeKind_U64); result.mode = E_Mode_Value; - result.space = space; } }break; @@ -803,14 +811,13 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output result.root = e_irtree_const_u(arena, 0); result.type_key = r_tree.type_key; result.mode = E_Mode_Null; - result.space = r_tree.space; }break; //- rjf: byteswap @@ -818,12 +825,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); U64 r_type_size = e_type_byte_size_from_key(r_type); - E_Space space = r_tree.space; // rjf: bad conditions? -> error if applicable, exit if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) @@ -835,12 +841,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { E_IRNode *node = e_push_irnode(arena, RDI_EvalOp_ByteSwap); - E_IRNode *rhs = e_irtree_resolve_to_value(arena, space, r_tree.mode, r_tree.root, r_type); + E_IRNode *rhs = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); e_irnode_push_child(node, rhs); node->value.u64 = r_type_size; result.root = node; result.mode = E_Mode_Value; - result.space = space; result.type_key = r_type; } }break; @@ -848,7 +853,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) //- rjf: unary operations case E_ExprKind_Pos: { - result = e_irtree_and_type_from_expr(arena, expr->first); + result = e_irtree_and_type_from_expr__space(arena, current_space, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_LogNot: @@ -856,7 +861,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -877,13 +882,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); result.root = new_tree; result.type_key = r_type_promoted; result.mode = E_Mode_Value; - result.space = r_tree.space; } }break; @@ -912,8 +916,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key)); @@ -1011,20 +1015,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { E_TypeKey final_type_key = is_comparison ? e_type_key_basic(E_TypeKind_Bool) : l_type; - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); l_value_tree = e_irtree_convert_hi(arena, l_value_tree, l_type, l_type); r_value_tree = e_irtree_convert_hi(arena, r_value_tree, l_type, r_type); E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, l_value_tree, r_value_tree); result.root = new_tree; result.type_key = final_type_key; result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } } }break; @@ -1051,10 +1049,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *ptr_root = ptr_tree->root; if(!ptr_is_decay) { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->space, ptr_tree->mode, ptr_root, ptr_tree->type_key); + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_root, ptr_tree->type_key); } E_IRNode *int_root = int_tree->root; - int_root = e_irtree_resolve_to_value(arena, int_tree->space, int_tree->mode, int_root, int_tree->type_key); + int_root = e_irtree_resolve_to_value(arena, int_tree->mode, int_root, int_tree->type_key); if(direct_type_size > 1) { E_IRNode *const_root = e_irtree_const_u(arena, direct_type_size); @@ -1069,12 +1067,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_root; result.type_key = ptr_type; result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } } }break; @@ -1090,11 +1082,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *r_root = r_tree.root; if(!l_is_decay) { - l_root = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_root, l_type); + l_root = e_irtree_resolve_to_value(arena, l_tree.mode, l_root, l_type); } if(!r_is_decay) { - r_root = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_root, r_type); + r_root = e_irtree_resolve_to_value(arena, r_tree.mode, r_root, r_type); } E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_root, r_root); E_IRNode *new_tree = op_tree; @@ -1106,12 +1098,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = e_type_key_basic(E_TypeKind_U64); result.mode = E_Mode_Value; - result.space = l_tree.space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_tree.space; - } }break; //- rjf: pointer array comparison @@ -1133,22 +1119,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRNode *arr_root = arr_tree->root; if(!ptr_is_decay) { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->space, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); } // rjf: read from pointer into value, to compare with array - E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_tree->space, ptr_root, arr_tree->type_key); + E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_root, arr_tree->type_key); // rjf: generate result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, mem_root, arr_root); result.type_key = e_type_key_basic(E_TypeKind_Bool); result.mode = E_Mode_Value; - result.space = ptr_tree->space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = arr_tree->space; - } }break; } }break; @@ -1160,9 +1140,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr); - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType c_tree = e_irtree_and_type_from_expr__space(arena, current_space, c_expr); + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1190,21 +1170,15 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: generate { - E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.space, c_tree.mode, c_tree.root, c_type); - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.space, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.space, r_tree.mode, r_tree.root, r_type); + E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); l_value_tree = e_irtree_convert_hi(arena, l_value_tree, result_type, l_type); r_value_tree = e_irtree_convert_hi(arena, r_value_tree, result_type, r_type); E_IRNode *new_tree = e_irtree_conditional(arena, c_value_tree, l_value_tree, r_value_tree); result.root = new_tree; result.type_key = result_type; result.mode = E_Mode_Value; - result.space = l_expr->space; - E_Space zero_space = {0}; - if(MemoryMatchStruct(&result.space, &zero_space)) - { - result.space = r_expr->space; - } } }break; @@ -1216,7 +1190,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = final_type_key; result.mode = expr->mode; - result.space = expr->space; }break; //- rjf: (unexpected) leaf member @@ -1290,7 +1263,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) else { e_string2expr_map_inc_poison(e_ir_ctx->macro_map, expr->string); - result = e_irtree_and_type_from_expr(arena, macro_expr); + result = e_irtree_and_type_from_expr__space(arena, current_space, macro_expr); e_string2expr_map_dec_poison(e_ir_ctx->macro_map, expr->string); } }break; @@ -1303,7 +1276,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = new_tree; result.type_key = expr->type_key; result.mode = E_Mode_Offset; - result.space = expr->space; }break; //- rjf: leaf file paths @@ -1317,7 +1289,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = set_space; result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); result.mode = E_Mode_Offset; - result.space = space; }break; //- rjf: types @@ -1326,7 +1297,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = e_irtree_const_u(arena, 0); result.type_key = expr->type_key; result.mode = E_Mode_Null; - result.space = expr->space; }break; //- rjf: (unexpected) type expressions @@ -1342,15 +1312,19 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { E_Expr *lhs = expr->first; E_Expr *rhs = expr->last; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - E_Space space = lhs_irtree.space; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr__space(arena, current_space, lhs); U64 line_num = rhs->value.u64; B32 space_is_good = 1; + E_Space space = {0}; if(lhs_irtree.root->op != E_IRExtKind_SetSpace) { space_is_good = 0; e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, lhs->location, "Cannot take a line from a non-file."); } + else + { + MemoryCopy(&space, &lhs_irtree.root->value, sizeof(space)); + } B32 line_num_is_good = 1; if(rhs->kind != E_ExprKind_LeafU64) { @@ -1372,7 +1346,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) result.root = set_space; result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size); result.mode = E_Mode_Offset; - result.space = space; } else { @@ -1387,15 +1360,40 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_irtree_and_type_from_expr(arena, rhs); + result = e_irtree_and_type_from_expr__space(arena, current_space, rhs); if(lhs->kind != E_ExprKind_LeafIdent) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); } }break; - } + //- rjf: evaluating a space pointer -> generate a dynamic set-space & resolve to the offset + if(e_type_kind_from_key(result.type_key) == E_TypeKind_SpacePtr) + { + result.root = e_irtree_deref_space_ptr(arena, result.root); + result.type_key = e_type_direct_from_key(result.type_key); + result.mode = E_Mode_Offset; + } + + //- rjf: if the expression's space does not match the current, then push a set-space node + // before returning + E_Space zero_space = zero_struct; + if(!MemoryMatchStruct(current_space, &expr->space) && + !MemoryMatchStruct(&zero_space, &expr->space)) + { + result.root = e_irtree_set_space(arena, expr->space, result.root); + *current_space = expr->space; + } + + return result; +} + +internal E_IRTreeAndType +e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) +{ + E_Space space = e_interpret_ctx->primary_space; + E_IRTreeAndType result = e_irtree_and_type_from_expr__space(arena, &space, expr); return result; } @@ -1429,7 +1427,17 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) { e_append_oplist_from_irtree(arena, child, out); } - + }break; + + case E_IRExtKind_DerefSpacePtr: + { + for(E_IRNode *child = root->first; + child != &e_irnode_nil; + child = child->next) + { + e_append_oplist_from_irtree(arena, child, out); + } + e_oplist_push_deref_space_ptr(arena, out); }break; case RDI_EvalOp_Cond: diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d5485c1f..ed54188b 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -11,6 +11,7 @@ enum { E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, E_IRExtKind_SetSpace, + E_IRExtKind_DerefSpacePtr, E_IRExtKind_COUNT }; @@ -52,7 +53,6 @@ struct E_IRTreeAndType E_IRNode *root; E_TypeKey type_key; E_Mode mode; - E_Space space; E_MsgList msgs; }; @@ -92,6 +92,7 @@ internal void e_oplist_push_uconst(Arena *arena, E_OpList *list, U64 x); internal void e_oplist_push_sconst(Arena *arena, E_OpList *list, S64 x); internal void e_oplist_push_bytecode(Arena *arena, E_OpList *list, String8 bytecode); internal void e_oplist_push_set_space(Arena *arena, E_OpList *list, E_Space space); +internal void e_oplist_push_deref_space_ptr(Arena *arena, E_OpList *list); internal void e_oplist_push_string_literal(Arena *arena, E_OpList *list, String8 string); internal void e_oplist_concat_in_place(E_OpList *dst, E_OpList *to_push); @@ -108,13 +109,15 @@ internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l, internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string); internal E_IRNode *e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c); -internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_key); +internal E_IRNode *e_irtree_deref_space_ptr(Arena *arena, E_IRNode *c); +internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_convert_lo(Arena *arena, E_IRNode *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in); internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in); -internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); +internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); //- rjf: top-level irtree/type extraction +internal E_IRTreeAndType e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr); internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); //- rjf: irtree -> linear ops/bytecode diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 13ba76f5..ec47d860 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -427,6 +427,10 @@ e_type_key_cons_(E_ConsTypeParams *params) { node->byte_size = bit_size_from_arch(node->params.arch)/8; }break; + case E_TypeKind_SpacePtr: + { + node->byte_size = sizeof(U64) + sizeof(E_Space); + }break; case E_TypeKind_Array: { U64 ptee_size = e_type_byte_size_from_key(node->params.direct_key); @@ -458,6 +462,13 @@ e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags) return key; } +internal E_TypeKey +e_type_key_cons_space_ptr(E_TypeKey direct_type_key) +{ + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_SpacePtr, .direct_key = direct_type_key); + return key; +} + internal E_TypeKey e_type_key_cons_base(Type *type) { @@ -1699,6 +1710,12 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("*")); }break; + case E_TypeKind_SpacePtr: + { + E_TypeKey direct = e_type_direct_from_key(key); + e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); + }break; + case E_TypeKind_LRef: { E_TypeKey direct = e_type_direct_from_key(key); diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index ee4da7ba..9009c04c 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -294,6 +294,7 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); //- rjf: constructed type construction helpers internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags); +internal E_TypeKey e_type_key_cons_space_ptr(E_TypeKey direct_type_key); internal E_TypeKey e_type_key_cons_base(Type *type); //- rjf: basic type key functions diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 228ef2fd..1d5e9291 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -135,7 +135,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, }; -U8 e_kind_basic_byte_size_table[55] = +U8 e_kind_basic_byte_size_table[56] = { 0, 0, @@ -192,9 +192,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"), @@ -251,6 +252,7 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), +str8_lit_comp("space_ptr"), }; C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 2dc6342f..225aa598 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,6 +74,7 @@ E_TypeKind_IncompleteClass, E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, +E_TypeKind_SpacePtr, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -163,8 +164,8 @@ extern String8 e_token_kind_strings[6]; extern String8 e_expr_kind_strings[49]; extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[49]; -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 diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e218d564..586781d7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -710,14 +710,9 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -String8 rd_collection_name_table[18] = +String8 rd_collection_name_table[13] = { str8_lit_comp("watches"), -str8_lit_comp("targets"), -str8_lit_comp("breakpoints"), -str8_lit_comp("watch_pins"), -str8_lit_comp("file_path_maps"), -str8_lit_comp("auto_view_rules"), str8_lit_comp("machines"), str8_lit_comp("processes"), str8_lit_comp("threads"), @@ -732,14 +727,9 @@ str8_lit_comp("types"), str8_lit_comp("procedures"), }; -RD_EntityKind rd_collection_entity_kind_table[18] = +RD_EntityKind rd_collection_entity_kind_table[13] = { RD_EntityKind_Watch, -RD_EntityKind_Target, -RD_EntityKind_Breakpoint, -RD_EntityKind_WatchPin, -RD_EntityKind_FilePathMap, -RD_EntityKind_AutoViewRule, RD_EntityKind_Nil, RD_EntityKind_Nil, RD_EntityKind_Nil, @@ -754,14 +744,9 @@ RD_EntityKind_Nil, RD_EntityKind_Nil, }; -CTRL_EntityKind rd_collection_ctrl_entity_kind_table[18] = +CTRL_EntityKind rd_collection_ctrl_entity_kind_table[13] = { CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, CTRL_EntityKind_Machine, CTRL_EntityKind_Process, CTRL_EntityKind_Thread, @@ -776,14 +761,9 @@ CTRL_EntityKind_Null, CTRL_EntityKind_Null, }; -EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[18] = +EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[13] = { EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(auto_view_rules), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(threads), @@ -798,14 +778,9 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18] = +EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[13] = { EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(auto_view_rules), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(threads), @@ -820,14 +795,9 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[13] = { EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(auto_view_rules), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(threads), @@ -842,14 +812,9 @@ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[13] = { EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(targets), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(breakpoints), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watch_pins), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(file_path_maps), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(auto_view_rules), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(threads), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 897039d7..4e96eefb 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -651,11 +651,6 @@ RD_ViewRuleUIFunctionType *ui; .os_event = rd_regs()->os_event,\ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(auto_view_rules); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads); @@ -669,11 +664,6 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(auto_view_rules); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads); @@ -687,11 +677,6 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(auto_view_rules); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads); @@ -703,11 +688,6 @@ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(targets); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watch_pins); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(file_path_maps); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(auto_view_rules); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads); @@ -768,13 +748,13 @@ extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern String8 rd_collection_name_table[18]; -extern RD_EntityKind rd_collection_entity_kind_table[18]; -extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[18]; -extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[18]; -extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[18]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[18]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[18]; +extern String8 rd_collection_name_table[13]; +extern RD_EntityKind rd_collection_entity_kind_table[13]; +extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[13]; +extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[13]; +extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[13]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[13]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[13]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f456797c..e1ee91a5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -988,11 +988,11 @@ RD_CollectionTable: { //- rjf: frontend entity groups {watches Watch Null x} - {targets Target Null x} - {breakpoints Breakpoint Null x} - {watch_pins WatchPin Null x} - {file_path_maps FilePathMap Null x} - {auto_view_rules AutoViewRule Null x} + //{targets Target Null x} + //{breakpoints Breakpoint Null x} + //{watch_pins WatchPin Null x} + //{file_path_maps FilePathMap Null x} + //{auto_view_rules AutoViewRule Null x} //- rjf: control entity groups {machines Nil Machine x} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 857fb023..9aadb180 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -759,6 +759,20 @@ rd_cfg_top_level_list_from_string(Arena *arena, String8 string) return result; } +internal RD_CfgArray +rd_cfg_array_from_list(Arena *arena, RD_CfgList *list) +{ + RD_CfgArray array = {0}; + array.count = list->count; + array.v = push_array_no_zero(arena, RD_Cfg *, array.count); + U64 idx = 0; + for(RD_CfgNode *n = list->first; n != 0; n = n->next, idx += 1) + { + array.v[idx] = n->v; + } + return array; +} + internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string) { @@ -941,7 +955,7 @@ rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) { RD_CfgNode *n = push_array(arena, RD_CfgNode, 1); n->v = cfg; - SLLQueuePush(list->first, list->last, n); + DLLPushBack(list->first, list->last, n); list->count += 1; } @@ -2427,9 +2441,23 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) MD_Node *member_schema = md_child_from_string(schema, child_name, 0); String8 member_type_name = member_schema->first->string; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); - if(str8_match(member_type_name, str8_lit("code_string"), 0) || - str8_match(member_type_name, str8_lit("path"), 0) || - str8_match(member_type_name, str8_lit("string"), 0)) + if(str8_match(member_type_name, str8_lit("location"), 0)) + { + 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))); + for(RD_Cfg *loc_child = child->first; loc_child != &rd_nil_cfg; loc_child = loc_child->first) + { + if(loc_child != child->first) + { + str8_list_push(scratch.arena, &variable_width_parts, str8_lit(":")); + } + str8_list_push(scratch.arena, &variable_width_parts, loc_child->string); + } + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } + else if(str8_match(member_type_name, str8_lit("code_string"), 0) || + str8_match(member_type_name, str8_lit("path"), 0) || + str8_match(member_type_name, str8_lit("string"), 0)) { 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))); @@ -2778,6 +2806,38 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } } }break; + + //- rjf: meta collections + case RD_EvalSpaceKind_MetaCollection: + { + typedef struct SpacePtr SpacePtr; + struct SpacePtr + { + E_Space space; + U64 off; + }; + RD_CfgArray cfgs_array = {0}; + if(space.u64s[0] < rd_state->eval_collection_cfg_names->count) + { + cfgs_array = rd_state->eval_collection_cfgs[space.u64s[0]]; + } + U64 space_ptr_size = sizeof(SpacePtr); + Rng1U64 idx_range = r1u64(range.min/space_ptr_size, range.max/space_ptr_size); + U64 out_off = 0; + U64 out_opl = dim_1u64(range); + for(U64 src_idx = idx_range.min; src_idx < idx_range.max && out_off+space_ptr_size <= out_opl; src_idx += 1) + { + RD_Cfg *cfg = &rd_nil_cfg; + if(src_idx < cfgs_array.count) + { + cfg = cfgs_array.v[src_idx]; + } + SpacePtr space_ptr = {rd_eval_space_from_cfg(cfg), 0}; + MemoryCopy((U8 *)out + out_off, &space_ptr, space_ptr_size); + out_off += sizeof(space_ptr); + } + result = 1; + }break; } scratch_end(scratch); return result; @@ -2869,12 +2929,19 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) if(contains_1u64(string_range, range.min)) { String8 new_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); - if(child == &rd_nil_cfg) + if(new_string.size == 0) { - child = rd_cfg_new(cfg, child_name); + rd_cfg_release(child); + } + else + { + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_new(child, new_string); } - rd_cfg_release_all_children(child); - rd_cfg_new(child, new_string); result = 1; break; } @@ -2883,12 +2950,19 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { U64 value = 0; MemoryCopy(&value, in, dim_1u64(range)); - if(child == &rd_nil_cfg) + if(value == 0) { - child = rd_cfg_new(cfg, child_name); + rd_cfg_release(child); + } + else + { + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_newf(child, "%I64u", value); } - rd_cfg_release_all_children(child); - rd_cfg_newf(child, "%I64u", value); result = 1; break; } @@ -2896,12 +2970,19 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { U64 value = 0; MemoryCopy(&value, in, dim_1u64(range)); - if(child == &rd_nil_cfg) + if(value == 0) { - child = rd_cfg_new(cfg, child_name); + rd_cfg_release(child); + } + else + { + if(child == &rd_nil_cfg) + { + child = rd_cfg_new(cfg, child_name); + } + rd_cfg_release_all_children(child); + rd_cfg_newf(child, "%I64u", value); } - rd_cfg_release_all_children(child); - rd_cfg_newf(child, "%I64u", value); result = 1; break; } @@ -12940,127 +13021,135 @@ rd_frame(void) } } - //- rjf: add macros for evallable config trees + //- rjf: choose set of evallable config names + String8 evallable_cfg_names[] = { - //- rjf: choose set of evallable config names - String8 evallable_cfg_names[] = - { - str8_lit("breakpoint"), - str8_lit("watch_pin"), - str8_lit("target"), - str8_lit("file_path_map"), - str8_lit("auto_view_rule"), - }; - - //- rjf: build special member types for evallable config types - E_TypeKey bool_type_key = {0}; - E_TypeKey u64_type_key = {0}; - E_TypeKey code_string_type_key = {0}; - E_TypeKey path_type_key = {0}; - E_TypeKey string_type_key = {0}; - E_TypeKey location_type_key = {0}; - { - bool_type_key = e_type_key_basic(E_TypeKind_Bool); - u64_type_key = e_type_key_basic(E_TypeKind_U64); - code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsCodeText); - path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPathText); - string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText); - location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); - } - - //- rjf: build types for each evallable config tree - struct - { - String8 schema_type_name; - E_TypeKey type_key; - } - schema_type_name_key_map[] = - { - { str8_lit("bool"), bool_type_key }, - { str8_lit("u64"), u64_type_key }, - { str8_lit("code_string"), code_string_type_key }, - { str8_lit("path"), path_type_key }, - { str8_lit("string"), string_type_key }, - { str8_lit("location"), location_type_key }, - }; - E_TypeKey evallable_cfg_types[ArrayCount(evallable_cfg_names)] = {0}; - for EachElement(idx, evallable_cfg_names) - { - String8 name = evallable_cfg_names[idx]; - MD_Node *schema = rd_schema_from_name(scratch.arena, name); - E_MemberList members_list = {0}; - U64 off = 0; - for MD_EachNode(child, schema->first) - { - String8 member_name = child->string; - String8 member_pretty_name = rd_display_from_code_name(member_name); - E_TypeKey member_type_key = zero_struct; - for EachElement(schema_type_name_idx, schema_type_name_key_map) - { - if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) - { - member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; - break; - } - } - e_member_list_push_new(scratch.arena, &members_list, - .type_key = member_type_key, - .name = member_name, - .pretty_name = member_pretty_name, - .off = off); - off += e_type_byte_size_from_key(member_type_key); - } - E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); - evallable_cfg_types[idx] = e_type_key_cons(.name = name, - .kind = E_TypeKind_Struct, - .members = members.v, - .count = members.count); - } - - //- rjf: cache cfg name -> type key correllation - rd_state->cfg_string2typekey_map = push_array(rd_frame_arena(), RD_String2TypeKeyMap, 1); - rd_state->cfg_string2typekey_map->slots_count = 256; - rd_state->cfg_string2typekey_map->slots = push_array(rd_frame_arena(), RD_String2TypeKeySlot, rd_state->cfg_string2typekey_map->slots_count); - for EachElement(idx, evallable_cfg_names) - { - String8 name = evallable_cfg_names[idx]; - E_TypeKey type_key = evallable_cfg_types[idx]; - U64 hash = d_hash_from_string(name); - U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; - RD_String2TypeKeyNode *node = push_array(rd_frame_arena(), RD_String2TypeKeyNode, 1); - node->string = push_str8_copy(rd_frame_arena(), name); - node->key = type_key; - SLLQueuePush(rd_state->cfg_string2typekey_map->slots[slot_idx].first, rd_state->cfg_string2typekey_map->slots[slot_idx].last, node); - } - - //- rjf: add macros for each evallable config tree - for EachElement(idx, evallable_cfg_names) - { - String8 name = evallable_cfg_names[idx]; - RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) - { - RD_Cfg *cfg = n->v; - String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; - String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; - E_Space space = rd_eval_space_from_cfg(cfg); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = evallable_cfg_types[idx]; - if(exe.size != 0) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); - } - if(label.size != 0) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); - } - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x%I64x", (U64)cfg, cfg->gen), expr); - } - } + str8_lit("breakpoint"), + str8_lit("watch_pin"), + str8_lit("target"), + str8_lit("file_path_map"), + str8_lit("auto_view_rule"), + }; + + //- rjf: store off eval collections for this frame + rd_state->eval_collection_cfg_names = push_array(rd_frame_arena(), String8Array, 1); + rd_state->eval_collection_cfg_names->count = ArrayCount(evallable_cfg_names); + rd_state->eval_collection_cfg_names->v = push_array(rd_frame_arena(), String8, rd_state->eval_collection_cfg_names->count); + MemoryCopy(rd_state->eval_collection_cfg_names->v, evallable_cfg_names, sizeof(evallable_cfg_names)); + rd_state->eval_collection_cfgs = push_array(rd_frame_arena(), RD_CfgArray, rd_state->eval_collection_cfg_names->count); + for EachElement(idx, evallable_cfg_names) + { + RD_CfgList list = rd_cfg_top_level_list_from_string(scratch.arena, evallable_cfg_names[idx]); + rd_state->eval_collection_cfgs[idx] = rd_cfg_array_from_list(rd_frame_arena(), &list); } + //- rjf: build special member types for evallable config types + E_TypeKey bool_type_key = {0}; + E_TypeKey u64_type_key = {0}; + E_TypeKey code_string_type_key = {0}; + E_TypeKey path_type_key = {0}; + E_TypeKey string_type_key = {0}; + E_TypeKey location_type_key = {0}; + { + bool_type_key = e_type_key_basic(E_TypeKind_Bool); + u64_type_key = e_type_key_basic(E_TypeKind_U64); + code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsCodeText); + path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPathText); + string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText); + location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); + } + + //- rjf: build types for each evallable config tree + struct + { + String8 schema_type_name; + E_TypeKey type_key; + } + schema_type_name_key_map[] = + { + { str8_lit("bool"), bool_type_key }, + { str8_lit("u64"), u64_type_key }, + { str8_lit("code_string"), code_string_type_key }, + { str8_lit("path"), path_type_key }, + { str8_lit("string"), string_type_key }, + { str8_lit("location"), location_type_key }, + }; + E_TypeKey evallable_cfg_types[ArrayCount(evallable_cfg_names)] = {0}; + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + MD_Node *schema = rd_schema_from_name(scratch.arena, name); + E_MemberList members_list = {0}; + U64 off = 0; + for MD_EachNode(child, schema->first) + { + String8 member_name = child->string; + String8 member_pretty_name = rd_display_from_code_name(member_name); + E_TypeKey member_type_key = zero_struct; + for EachElement(schema_type_name_idx, schema_type_name_key_map) + { + if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) + { + member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; + break; + } + } + e_member_list_push_new(scratch.arena, &members_list, + .type_key = member_type_key, + .name = member_name, + .pretty_name = member_pretty_name, + .off = off); + off += e_type_byte_size_from_key(member_type_key); + } + E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); + evallable_cfg_types[idx] = e_type_key_cons(.name = name, + .kind = E_TypeKind_Struct, + .members = members.v, + .count = members.count); + } + + //- rjf: cache cfg name -> type key correllation + rd_state->cfg_string2typekey_map = push_array(rd_frame_arena(), RD_String2TypeKeyMap, 1); + rd_state->cfg_string2typekey_map->slots_count = 256; + rd_state->cfg_string2typekey_map->slots = push_array(rd_frame_arena(), RD_String2TypeKeySlot, rd_state->cfg_string2typekey_map->slots_count); + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + E_TypeKey type_key = evallable_cfg_types[idx]; + U64 hash = d_hash_from_string(name); + U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; + RD_String2TypeKeyNode *node = push_array(rd_frame_arena(), RD_String2TypeKeyNode, 1); + node->string = push_str8_copy(rd_frame_arena(), name); + node->key = type_key; + SLLQueuePush(rd_state->cfg_string2typekey_map->slots[slot_idx].first, rd_state->cfg_string2typekey_map->slots[slot_idx].last, node); + } + + //- rjf: add macros for each evallable config tree + for EachElement(idx, evallable_cfg_names) + { + String8 name = evallable_cfg_names[idx]; + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + RD_Cfg *cfg = n->v; + String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; + String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + E_Space space = rd_eval_space_from_cfg(cfg); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = evallable_cfg_types[idx]; + if(exe.size != 0) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); + } + if(label.size != 0) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); + } + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x%I64x", (U64)cfg, cfg->gen), expr); + } + } //- rjf: add macros for all evallable control entities { CTRL_EntityKind evallable_kinds[] = @@ -13110,6 +13199,26 @@ rd_frame(void) } } + //- rjf: add macros for collections (new @cfg) + for EachElement(cfg_name_idx, evallable_cfg_names) + { + String8 cfg_name = evallable_cfg_names[cfg_name_idx]; + String8 collection_name = rd_plural_from_code_name(cfg_name); + E_TypeKey collection_type_key = {0}; + { + E_TypeKey element_type_key = evallable_cfg_types[cfg_name_idx]; + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); + collection_type_key = e_type_key_cons_array(e_type_key_cons_space_ptr(element_type_key), cfgs.count); + } + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Space space = e_space_make(RD_EvalSpaceKind_MetaCollection); + space.u64s[0] = cfg_name_idx; + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = collection_type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + } + //- rjf: add macros for all watches which define identifiers RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); for(RD_CfgNode *n = watches.first; n != 0; n = n->next) @@ -14095,47 +14204,65 @@ rd_frame(void) }break; case RD_CmdKind_NextTab: { -#if 0 // TODO(rjf): @cfg - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *start_view = rd_selected_tab_from_panel(panel); - RD_View *next_view = start_view; - U64 idx = 0; - for(RD_View *v = start_view; !rd_view_is_nil(v); v = (rd_view_is_nil(v->order_next) ? panel->first_tab_view : v->order_next), idx += 1) + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *focused = panel_tree.focused; + RD_CfgNode *selected_tab_n = 0; + for(RD_CfgNode *n = focused->tabs.first; n != 0; n = n->next) { - if(v == start_view && idx != 0) + if(n->v == focused->selected_tab) { - break; - } - if(!rd_view_is_project_filtered(v) && v != start_view) - { - next_view = v; + selected_tab_n = n; break; } } - panel->selected_tab_view = rd_handle_from_view(next_view); -#endif + RD_Cfg *next_selected_tab = &rd_nil_cfg; + U64 idx = 0; + for(RD_CfgNode *tab_n = selected_tab_n; + tab_n != 0 && (tab_n != selected_tab_n || idx == 0); + ((tab_n->next == 0) ? (tab_n = focused->tabs.first) : (tab_n = tab_n->next)), idx += 1) + { + if(!rd_cfg_is_project_filtered(tab_n->v) && tab_n != selected_tab_n) + { + next_selected_tab = tab_n->v; + break; + } + } + if(next_selected_tab != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + } }break; case RD_CmdKind_PrevTab: { -#if 0 // TODO(rjf): @cfg - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *start_view = rd_selected_tab_from_panel(panel); - RD_View *next_view = start_view; - U64 idx = 0; - for(RD_View *v = start_view; !rd_view_is_nil(v); v = (rd_view_is_nil(v->order_prev) ? panel->last_tab_view : v->order_prev), idx += 1) + RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *focused = panel_tree.focused; + RD_CfgNode *selected_tab_n = 0; + for(RD_CfgNode *n = focused->tabs.last; n != 0; n = n->prev) { - if(v == start_view && idx != 0) + if(n->v == focused->selected_tab) { - break; - } - if(!rd_view_is_project_filtered(v) && v != start_view) - { - next_view = v; + selected_tab_n = n; break; } } - panel->selected_tab_view = rd_handle_from_view(next_view); -#endif + RD_Cfg *next_selected_tab = &rd_nil_cfg; + U64 idx = 0; + for(RD_CfgNode *tab_n = selected_tab_n; + tab_n != 0 && (tab_n != selected_tab_n || idx == 0); + ((tab_n->prev == 0) ? (tab_n = focused->tabs.last) : (tab_n = tab_n->prev)), idx += 1) + { + if(!rd_cfg_is_project_filtered(tab_n->v) && tab_n != selected_tab_n) + { + next_selected_tab = tab_n->v; + break; + } + } + if(next_selected_tab != &rd_nil_cfg) + { + rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + } }break; case RD_CmdKind_MoveTabRight: case RD_CmdKind_MoveTabLeft: @@ -14168,15 +14295,28 @@ rd_frame(void) }break; case RD_CmdKind_CloseTab: { -#if 0 // TODO(rjf): @cfg - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) + RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->view); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, tab); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); + B32 found_selected = 0; + RD_Cfg *next_selected_tab = &rd_nil_cfg; + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - rd_panel_remove_tab_view(panel, view); - rd_view_release(view); + if(n->v == panel->selected_tab) + { + found_selected = 1; + } + else if(!rd_cfg_is_project_filtered(n->v)) + { + next_selected_tab = n->v; + if(found_selected) + { + break; + } + } } -#endif + rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + rd_cfg_release(tab); }break; case RD_CmdKind_MoveTab: { @@ -14603,368 +14743,6 @@ X(getting_started) #define X(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} FixedTab_XList #undef X - -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - - typedef enum Layout - { - Layout_Default, - Layout_Compact, - } - Layout; - Layout layout = Layout_Default; - switch(kind) - { - default:{}break; - case RD_CmdKind_ResetToDefaultPanels:{layout = Layout_Default;}break; - case RD_CmdKind_ResetToCompactPanels:{layout = Layout_Compact;}break; - } - - //- rjf: gather all panels in the panel tree - remove & gather views - // we'd like to keep in the next layout - RD_HandleList panels_to_close = {0}; - RD_HandleList views_to_close = {0}; - RD_View *watch = &rd_nil_view; - RD_View *locals = &rd_nil_view; - RD_View *regs = &rd_nil_view; - RD_View *globals = &rd_nil_view; - RD_View *tlocals = &rd_nil_view; - RD_View *types = &rd_nil_view; - RD_View *procs = &rd_nil_view; - RD_View *callstack = &rd_nil_view; - RD_View *breakpoints = &rd_nil_view; - RD_View *watch_pins = &rd_nil_view; - RD_View *output = &rd_nil_view; - RD_View *targets = &rd_nil_view; - RD_View *scheduler = &rd_nil_view; - RD_View *modules = &rd_nil_view; - RD_View *disasm = &rd_nil_view; - RD_View *memory = &rd_nil_view; - RD_View *getting_started = &rd_nil_view; - RD_HandleList code_views = {0}; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - RD_Handle handle = rd_handle_from_panel(panel); - rd_handle_list_push(scratch.arena, &panels_to_close, handle); - for(RD_View *view = panel->first_tab_view, *next = 0; !rd_view_is_nil(view); view = next) - { - next = view->order_next; - RD_ViewRuleKind view_rule_kind = rd_view_rule_kind_from_string(view->spec->string); - B32 needs_delete = 1; - switch(view_rule_kind) - { - default:{}break; - case RD_ViewRuleKind_Watch: {if(rd_view_is_nil(watch)) { needs_delete = 0; watch = view;} }break; - case RD_ViewRuleKind_Locals: {if(rd_view_is_nil(locals)) { needs_delete = 0; locals = view;} }break; - case RD_ViewRuleKind_Registers: {if(rd_view_is_nil(regs)) { needs_delete = 0; regs = view;} }break; - case RD_ViewRuleKind_Globals: {if(rd_view_is_nil(globals)) { needs_delete = 0; globals = view;} }break; - case RD_ViewRuleKind_ThreadLocals: {if(rd_view_is_nil(tlocals)) { needs_delete = 0; tlocals = view;} }break; - case RD_ViewRuleKind_Types: {if(rd_view_is_nil(types)) { needs_delete = 0; types = view;} }break; - case RD_ViewRuleKind_Procedures: {if(rd_view_is_nil(procs)) { needs_delete = 0; procs = view;} }break; - case RD_ViewRuleKind_CallStack: {if(rd_view_is_nil(callstack)) { needs_delete = 0; callstack = view;} }break; - case RD_ViewRuleKind_Breakpoints: {if(rd_view_is_nil(breakpoints)) { needs_delete = 0; breakpoints = view;} }break; - case RD_ViewRuleKind_WatchPins: {if(rd_view_is_nil(watch_pins)) { needs_delete = 0; watch_pins = view;} }break; - case RD_ViewRuleKind_Output: {if(rd_view_is_nil(output)) { needs_delete = 0; output = view;} }break; - case RD_ViewRuleKind_Targets: {if(rd_view_is_nil(targets)) { needs_delete = 0; targets = view;} }break; - case RD_ViewRuleKind_Scheduler: {if(rd_view_is_nil(scheduler)) { needs_delete = 0; scheduler = view;} }break; - case RD_ViewRuleKind_Modules: {if(rd_view_is_nil(modules)) { needs_delete = 0; modules = view;} }break; - case RD_ViewRuleKind_Disasm: {if(rd_view_is_nil(disasm)) { needs_delete = 0; disasm = view;} }break; - case RD_ViewRuleKind_Memory: {if(rd_view_is_nil(memory)) { needs_delete = 0; memory = view;} }break; - case RD_ViewRuleKind_GettingStarted:{if(rd_view_is_nil(getting_started)) { needs_delete = 0; getting_started = view;} }break; - case RD_ViewRuleKind_Text: - { - needs_delete = 0; - rd_handle_list_push(scratch.arena, &code_views, rd_handle_from_view(view)); - }break; - } - if(!needs_delete) - { - rd_panel_remove_tab_view(panel, view); - } - } - } - - //- rjf: close all panels/views - for(RD_HandleNode *n = panels_to_close.first; n != 0; n = n->next) - { - RD_Panel *panel = rd_panel_from_handle(n->handle); - if(panel != ws->root_panel) - { - rd_panel_release(ws, panel); - } - else - { - rd_panel_release_all_views(panel); - panel->first = panel->last = &rd_nil_panel; - } - } - - //- rjf: allocate any missing views - if(rd_view_is_nil(watch)) - { - watch = rd_view_alloc(); - rd_view_equip_spec(watch, rd_view_rule_info_from_kind(RD_ViewRuleKind_Watch), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(locals)) - { - locals = rd_view_alloc(); - rd_view_equip_spec(locals, rd_view_rule_info_from_kind(RD_ViewRuleKind_Locals), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(regs)) - { - regs = rd_view_alloc(); - rd_view_equip_spec(regs, rd_view_rule_info_from_kind(RD_ViewRuleKind_Registers), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(globals)) - { - globals = rd_view_alloc(); - rd_view_equip_spec(globals, rd_view_rule_info_from_kind(RD_ViewRuleKind_Globals), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(tlocals)) - { - tlocals = rd_view_alloc(); - rd_view_equip_spec(tlocals, rd_view_rule_info_from_kind(RD_ViewRuleKind_ThreadLocals), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(types)) - { - types = rd_view_alloc(); - rd_view_equip_spec(types, rd_view_rule_info_from_kind(RD_ViewRuleKind_Types), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(procs)) - { - procs = rd_view_alloc(); - rd_view_equip_spec(procs, rd_view_rule_info_from_kind(RD_ViewRuleKind_Procedures), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(callstack)) - { - callstack = rd_view_alloc(); - rd_view_equip_spec(callstack, rd_view_rule_info_from_kind(RD_ViewRuleKind_CallStack), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(breakpoints)) - { - breakpoints = rd_view_alloc(); - rd_view_equip_spec(breakpoints, rd_view_rule_info_from_kind(RD_ViewRuleKind_Breakpoints), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(watch_pins)) - { - watch_pins = rd_view_alloc(); - rd_view_equip_spec(watch_pins, rd_view_rule_info_from_kind(RD_ViewRuleKind_WatchPins), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(output)) - { - output = rd_view_alloc(); - rd_view_equip_spec(output, rd_view_rule_info_from_kind(RD_ViewRuleKind_Output), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(targets)) - { - targets = rd_view_alloc(); - rd_view_equip_spec(targets, rd_view_rule_info_from_kind(RD_ViewRuleKind_Targets), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(scheduler)) - { - scheduler = rd_view_alloc(); - rd_view_equip_spec(scheduler, rd_view_rule_info_from_kind(RD_ViewRuleKind_Scheduler), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(modules)) - { - modules = rd_view_alloc(); - rd_view_equip_spec(modules, rd_view_rule_info_from_kind(RD_ViewRuleKind_Modules), str8_zero(), &md_nil_node); - } - if(rd_view_is_nil(disasm)) - { - disasm = rd_view_alloc(); - rd_view_equip_spec(disasm, rd_view_rule_info_from_kind(RD_ViewRuleKind_Disasm), str8_zero(), &md_nil_node); - } - if(layout == Layout_Default && rd_view_is_nil(memory)) - { - memory = rd_view_alloc(); - rd_view_equip_spec(memory, rd_view_rule_info_from_kind(RD_ViewRuleKind_Memory), str8_zero(), &md_nil_node); - } - if(code_views.count == 0 && rd_view_is_nil(getting_started)) - { - getting_started = rd_view_alloc(); - rd_view_equip_spec(getting_started, rd_view_rule_info_from_kind(RD_ViewRuleKind_GettingStarted), str8_zero(), &md_nil_node); - } - - //- rjf: apply layout - switch(layout) - { - //- rjf: default layout - case Layout_Default: - { - // rjf: root split - ws->root_panel->split_axis = Axis2_X; - RD_Panel *root_0 = rd_panel_alloc(ws); - RD_Panel *root_1 = rd_panel_alloc(ws); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_0); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_1); - root_0->pct_of_parent = 0.85f; - root_1->pct_of_parent = 0.15f; - - // rjf: root_0 split - root_0->split_axis = Axis2_Y; - RD_Panel *root_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0, root_0->last, root_0_0); - rd_panel_insert(root_0, root_0->last, root_0_1); - root_0_0->pct_of_parent = 0.80f; - root_0_1->pct_of_parent = 0.20f; - - // rjf: root_1 split - root_1->split_axis = Axis2_Y; - RD_Panel *root_1_0 = rd_panel_alloc(ws); - RD_Panel *root_1_1 = rd_panel_alloc(ws); - rd_panel_insert(root_1, root_1->last, root_1_0); - rd_panel_insert(root_1, root_1->last, root_1_1); - root_1_0->pct_of_parent = 0.50f; - root_1_1->pct_of_parent = 0.50f; - rd_panel_insert_tab_view(root_1_0, root_1_0->last_tab_view, targets); - rd_panel_insert_tab_view(root_1_1, root_1_1->last_tab_view, scheduler); - root_1_0->selected_tab_view = rd_handle_from_view(targets); - root_1_1->selected_tab_view = rd_handle_from_view(scheduler); - root_1_1->tab_side = Side_Max; - - // rjf: root_0_0 split - root_0_0->split_axis = Axis2_X; - RD_Panel *root_0_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_0, root_0_0->last, root_0_0_0); - rd_panel_insert(root_0_0, root_0_0->last, root_0_0_1); - root_0_0_0->pct_of_parent = 0.25f; - root_0_0_1->pct_of_parent = 0.75f; - - // rjf: root_0_0_0 split - root_0_0_0->split_axis = Axis2_Y; - RD_Panel *root_0_0_0_0 = rd_panel_alloc(ws); - RD_Panel *root_0_0_0_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_0_0, root_0_0_0->last, root_0_0_0_0); - rd_panel_insert(root_0_0_0, root_0_0_0->last, root_0_0_0_1); - root_0_0_0_0->pct_of_parent = 0.5f; - root_0_0_0_1->pct_of_parent = 0.5f; - rd_panel_insert_tab_view(root_0_0_0_0, root_0_0_0_0->last_tab_view, disasm); - root_0_0_0_0->selected_tab_view = rd_handle_from_view(disasm); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, breakpoints); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, watch_pins); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, output); - rd_panel_insert_tab_view(root_0_0_0_1, root_0_0_0_1->last_tab_view, memory); - root_0_0_0_1->selected_tab_view = rd_handle_from_view(output); - - // rjf: root_0_1 split - root_0_1->split_axis = Axis2_X; - RD_Panel *root_0_1_0 = rd_panel_alloc(ws); - RD_Panel *root_0_1_1 = rd_panel_alloc(ws); - rd_panel_insert(root_0_1, root_0_1->last, root_0_1_0); - rd_panel_insert(root_0_1, root_0_1->last, root_0_1_1); - root_0_1_0->pct_of_parent = 0.60f; - root_0_1_1->pct_of_parent = 0.40f; - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, watch); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, locals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, regs); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, globals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, tlocals); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, types); - rd_panel_insert_tab_view(root_0_1_0, root_0_1_0->last_tab_view, procs); - root_0_1_0->selected_tab_view = rd_handle_from_view(watch); - root_0_1_0->tab_side = Side_Max; - rd_panel_insert_tab_view(root_0_1_1, root_0_1_1->last_tab_view, callstack); - rd_panel_insert_tab_view(root_0_1_1, root_0_1_1->last_tab_view, modules); - root_0_1_1->selected_tab_view = rd_handle_from_view(callstack); - root_0_1_1->tab_side = Side_Max; - - // rjf: fill main panel with getting started, OR all collected code views - if(!rd_view_is_nil(getting_started)) - { - rd_panel_insert_tab_view(root_0_0_1, root_0_0_1->last_tab_view, getting_started); - } - for(RD_HandleNode *n = code_views.first; n != 0; n = n->next) - { - RD_View *view = rd_view_from_handle(n->handle); - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(root_0_0_1, root_0_0_1->last_tab_view, view); - } - } - - // rjf: choose initial focused panel - ws->focused_panel = root_0_0_1; - }break; - - //- rjf: compact layout: - case Layout_Compact: - { - // rjf: root split - ws->root_panel->split_axis = Axis2_X; - RD_Panel *root_0 = rd_panel_alloc(ws); - RD_Panel *root_1 = rd_panel_alloc(ws); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_0); - rd_panel_insert(ws->root_panel, ws->root_panel->last, root_1); - root_0->pct_of_parent = 0.25f; - root_1->pct_of_parent = 0.75f; - - // rjf: root_0 split - root_0->split_axis = Axis2_Y; - RD_Panel *root_0_0 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(watch)) { rd_panel_insert_tab_view(root_0_0, root_0_0->last_tab_view, watch); } - if(!rd_view_is_nil(types)) { rd_panel_insert_tab_view(root_0_0, root_0_0->last_tab_view, types); } - root_0_0->selected_tab_view = rd_handle_from_view(watch); - } - RD_Panel *root_0_1 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(scheduler)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, scheduler); } - if(!rd_view_is_nil(targets)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, targets); } - if(!rd_view_is_nil(breakpoints)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, breakpoints); } - if(!rd_view_is_nil(watch_pins)) { rd_panel_insert_tab_view(root_0_1, root_0_1->last_tab_view, watch_pins); } - root_0_1->selected_tab_view = rd_handle_from_view(scheduler); - } - RD_Panel *root_0_2 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(disasm)) { rd_panel_insert_tab_view(root_0_2, root_0_2->last_tab_view, disasm); } - if(!rd_view_is_nil(output)) { rd_panel_insert_tab_view(root_0_2, root_0_2->last_tab_view, output); } - root_0_2->selected_tab_view = rd_handle_from_view(disasm); - } - RD_Panel *root_0_3 = rd_panel_alloc(ws); - { - if(!rd_view_is_nil(callstack)) { rd_panel_insert_tab_view(root_0_3, root_0_3->last_tab_view, callstack); } - if(!rd_view_is_nil(modules)) { rd_panel_insert_tab_view(root_0_3, root_0_3->last_tab_view, modules); } - root_0_3->selected_tab_view = rd_handle_from_view(callstack); - } - rd_panel_insert(root_0, root_0->last, root_0_0); - rd_panel_insert(root_0, root_0->last, root_0_1); - rd_panel_insert(root_0, root_0->last, root_0_2); - rd_panel_insert(root_0, root_0->last, root_0_3); - root_0_0->pct_of_parent = 0.25f; - root_0_1->pct_of_parent = 0.25f; - root_0_2->pct_of_parent = 0.25f; - root_0_3->pct_of_parent = 0.25f; - - // rjf: fill main panel with getting started, OR all collected code views - if(!rd_view_is_nil(getting_started)) - { - rd_panel_insert_tab_view(root_1, root_1->last_tab_view, getting_started); - } - for(RD_HandleNode *n = code_views.first; n != 0; n = n->next) - { - RD_View *view = rd_view_from_handle(n->handle); - if(!rd_view_is_nil(view)) - { - rd_panel_insert_tab_view(root_1, root_1->last_tab_view, view); - } - } - - // rjf: choose initial focused panel - ws->focused_panel = root_1; - }break; - } - - // rjf: dispatch cfg saves - for(RD_CfgSrc src = (RD_CfgSrc)0; src < RD_CfgSrc_COUNT; src = (RD_CfgSrc)(src+1)) - { - RD_CmdKind write_cmd = rd_cfg_src_write_cmd_kind_table[src]; - rd_cmd(write_cmd, .file_path = rd_cfg_path_from_src(src)); - } -#endif }break; //- rjf: thread finding @@ -15671,7 +15449,8 @@ X(getting_started) case RD_CmdKind_DisableTarget: { RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); - rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); + RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); + rd_cfg_new(disabled, str8_lit("1")); }break; case RD_CmdKind_RemoveCfg: { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 83087c58..82482f27 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -143,16 +143,6 @@ enum RD_EntityFlag_MarkedForDeletion = (1<<31), }; -//////////////////////////////// -//~ rjf: Setting Types - -typedef struct RD_SettingVal RD_SettingVal; -struct RD_SettingVal -{ - B32 set; - S32 s32; -}; - //////////////////////////////// //~ rjf: View Rule Info Types @@ -351,6 +341,7 @@ typedef struct RD_CfgNode RD_CfgNode; struct RD_CfgNode { RD_CfgNode *next; + RD_CfgNode *prev; RD_Cfg *v; }; @@ -362,6 +353,13 @@ struct RD_CfgList U64 count; }; +typedef struct RD_CfgArray RD_CfgArray; +struct RD_CfgArray +{ + RD_Cfg **v; + U64 count; +}; + typedef struct RD_CfgRec RD_CfgRec; struct RD_CfgRec { @@ -889,6 +887,10 @@ struct RD_State // rjf: config -> eval blob map (lazily constructed from-scratch each frame) RD_Cfg2EvalBlobMap *cfg2evalblob_map; + // rjf: eval collections (constructed from scratch every frame) + String8Array *eval_collection_cfg_names; + RD_CfgArray *eval_collection_cfgs; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -1171,6 +1173,7 @@ internal RD_Cfg *rd_cfg_child_from_string(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_top_level_list_from_string(Arena *arena, String8 string); +internal RD_CfgArray rd_cfg_array_from_list(Arena *arena, RD_CfgList *list); internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string); internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); From 2a1ab9b3be7a363395d1fb17830fba6b8deb3c54 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 Jan 2025 10:42:41 -0800 Subject: [PATCH 029/755] fix incorrect bytecode writing for deref-space-ptr --- src/eval/eval_ir.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4b9957b8..203798f2 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1581,6 +1581,12 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) // rjf: advance ptr = next_ptr; }break; + + case E_IRExtKind_DerefSpacePtr: + { + ptr[0] = opcode; + ptr += 1; + }break; } } From 84d55c8939e7e64fe232830c2153875ace7ebe47 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 Jan 2025 18:31:34 -0800 Subject: [PATCH 030/755] make some progress on watch window refinement for various row topologies --- .../eval_visualization_core.c | 28 +- .../eval_visualization_core.h | 33 +- src/raddbg/generated/raddbg.meta.c | 28 +- src/raddbg/generated/raddbg.meta.h | 1 + src/raddbg/raddbg.mdesk | 36 +- src/raddbg/raddbg_core.c | 150 +++- src/raddbg/raddbg_core.h | 32 +- src/raddbg/raddbg_views.c | 693 ++++++++++++++++-- src/raddbg/raddbg_views.h | 45 +- 9 files changed, 846 insertions(+), 200 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index a36cd7c4..dfaf7e46 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -667,31 +667,11 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) return expr; } -//////////////////////////////// -//~ rjf: Column List Building - -internal EV_Col * -ev_col_list_push(Arena *arena, EV_ColList *list) -{ - EV_Col *col = push_array(arena, EV_Col, 1); - SLLQueuePush(list->first, list->last, col); - list->count += 1; - return col; -} - -internal EV_Col * -ev_col_list_push_new(Arena *arena, EV_ColList *list, String8 key) -{ - EV_Col *col = ev_col_list_push(arena, list); - col->key = push_str8_copy(arena, key); - return col; -} - //////////////////////////////// //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, EV_ColList *cols) +ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -711,7 +691,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = ev_key_root(); - tree.root->cols = *cols; tree.root->string = string; tree.root->expr = ev_resolved_from_expr(arena, expr, top_level_view_rules); tree.root->view_rules = top_level_view_rules; @@ -779,7 +758,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str expansion_block->parent = t->parent_block; expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; - expansion_block->cols = *cols; expansion_block->expr = t->expr; expansion_block->view_rules = t->view_rules; expansion_block->expand_view_rule_info = expand_view_rule_info; @@ -907,7 +885,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules, EV_ColList *cols) +ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules) { ProfBeginFunction(); EV_BlockTree tree = {0}; @@ -918,7 +896,7 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, string); EV_ViewRuleList *all_view_rules = ev_view_rule_list_copy(arena, view_rules); ev_view_rule_list_concat_in_place(all_view_rules, &fastpath_view_rules); - tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules, cols); + tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules); } scratch_end(scratch); ProfEnd(); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 164ca077..41b9d403 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -187,24 +187,6 @@ struct EV_ViewRuleInfoTable U64 slots_count; }; -//////////////////////////////// -//~ rjf: Columns - -typedef struct EV_Col EV_Col; -struct EV_Col -{ - EV_Col *next; - String8 key; -}; - -typedef struct EV_ColList EV_ColList; -struct EV_ColList -{ - EV_Col *first; - EV_Col *last; - U64 count; -}; - //////////////////////////////// //~ rjf: Blocks @@ -224,9 +206,6 @@ struct EV_Block // rjf: split index, relative to parent's space U64 split_relative_idx; - // rjf: columns - EV_ColList cols; - // rjf: expression / visualization info String8 string; E_Expr *expr; @@ -372,7 +351,7 @@ global read_only EV_ViewRuleInfo ev_nil_view_rule_info = thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; global read_only EV_ViewRuleList ev_nil_view_rule_list = {0}; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; //////////////////////////////// //~ rjf: Key Functions @@ -436,17 +415,11 @@ internal void ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRul internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules); -//////////////////////////////// -//~ rjf: Column List Building - -internal EV_Col *ev_col_list_push(Arena *arena, EV_ColList *list); -internal EV_Col *ev_col_list_push_new(Arena *arena, EV_ColList *list, String8 key); - //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, EV_ColList *cols); -internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules, EV_ColList *cols); +internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules); +internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 586781d7..a449799a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -75,12 +75,12 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n"), str8_lit_comp("")}, +{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n"), str8_lit_comp("launch_and_run,launch_and_init,select_cfg,remove_cfg")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n"), str8_lit_comp("enable_cfg,remove_cfg")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n"), str8_lit_comp("remove_cfg")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}"), str8_lit_comp("remove_cfg")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, }; String8 d_entity_kind_display_string_table[27] = @@ -440,14 +440,14 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_entity"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_entity"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_entity"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Entity"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_entity"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Entity"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_entity"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_entity"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 4e96eefb..6d677a10 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -527,6 +527,7 @@ struct RD_CfgNameSchemaPair { String8 name; String8 schema; +String8 cmd_names; }; typedef struct RD_Regs RD_Regs; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e1ee91a5..381212bd 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -111,7 +111,7 @@ RD_VocabularyMap: //////////////////////////////// //~ rjf: Configuration Tree Schemas -@table(name schema) RD_CfgSchemaTable: +@table(name schema cmd_names) RD_CfgSchemaTable: { //- rjf: settings { @@ -156,7 +156,8 @@ RD_VocabularyMap: 'stdin_path': path, 'debug_subprocesses': bool, } - ``` + ```, + `launch_and_run,launch_and_init,select_cfg,remove_cfg`, } //- rjf: breakpoints @@ -170,7 +171,8 @@ RD_VocabularyMap: 'hit_count': u64, 'disabled': bool, } - ``` + ```, + `enable_cfg,remove_cfg`, } //- rjf: watch pins @@ -182,19 +184,22 @@ RD_VocabularyMap: 'view_rule': code_string, 'location': location, } - ``` + ```, + `remove_cfg`, } //- rjf: file path maps { file_path_map, - ```x:{'source':path, 'dest':path}``` + ```x:{'source':path, 'dest':path}```, + `remove_cfg`, } //- rjf: auto view rules { auto_view_rule, - ```x:{'source':code_string, 'dest':code_string}``` + ```x:{'source':code_string, 'dest':code_string}```, + `remove_cfg`, } } @@ -202,11 +207,12 @@ RD_VocabularyMap: { `String8 name`; `String8 schema`; + `String8 cmd_names`; } @data(RD_CfgNameSchemaPair) rd_cfg_name_schema_pair_table: { - @expand(RD_CfgSchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)")}` + @expand(RD_CfgSchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.cmd_names)")}` } //////////////////////////////// @@ -573,14 +579,14 @@ RD_CmdTable: // | | | | {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general config operations - {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_entity" "Enable Entity" "Enables an entity." "" "" } - {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_entity" "Disable Entity" "Disables an entity." "" "" } - {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_entity" "Select Entity" "Selects an entity, disabling all others of the same kind." "" "" } - {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_entity" "Remove Entity" "Removes an entity." "" "" } - {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_entity" "Name Entity" "Equips an entity with a name." "" "" } - {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_entity" "Condition Entity" "Equips an entity with a condition string." "" "" } - {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" "" } - {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_entity" "Relocate Entity" "Relocates an entity." "" "" } + {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_cfg" "Enable Config Tree" "Enables an entity." "" "" } + {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_cfg" "Disable Config Tree" "Disables an entity." "" "" } + {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_cfg" "Select Config Tree" "Selects an entity, disabling all others of the same kind." "" "" } + {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes an entity." "" "" } + {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips an entity with a name." "" "" } + {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips an entity with a condition string." "" "" } + {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates an entity." "" "" } + {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates an entity." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9aadb180..f718f1be 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1543,6 +1543,46 @@ rd_setting_from_name(String8 name) return result; } +internal RD_Cfg * +rd_immediate_cfg_from_key(String8 string) +{ + RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + RD_Cfg *immediate = &rd_nil_cfg; + RD_Cfg *cfg = &rd_nil_cfg; + for(RD_Cfg *child = transient->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("immediate"), 0)) + { + cfg = rd_cfg_child_from_string(child, string); + if(cfg != &rd_nil_cfg) + { + immediate = child; + break; + } + } + } + if(cfg == &rd_nil_cfg) + { + immediate = rd_cfg_new(transient, str8_lit("immediate")); + cfg = rd_cfg_new(immediate, string); + } + rd_cfg_new(immediate, str8_lit("hot")); + return cfg; +} + +internal RD_Cfg * +rd_immediate_cfg_from_keyf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 key = push_str8fv(scratch.arena, fmt, args); + RD_Cfg *result = rd_immediate_cfg_from_key(key); + va_end(args); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Entity State Functions @@ -3441,6 +3481,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_handle = cfg_handle; view_state->arena = arena_alloc(); + view_state->ev_view = ev_view_alloc(); view_state->loading_t = 1.f; } if(view_state != &rd_nil_view_state) @@ -3613,6 +3654,14 @@ rd_view_scroll_pos(void) return view_state->scroll_pos; } +internal EV_View * +rd_view_eval_view(void) +{ + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + return view_state->ev_view; +} + internal String8 rd_view_expr_string(void) { @@ -6674,12 +6723,47 @@ rd_window_frame(void) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) RD_Palette(RD_PaletteCode_Floating) { + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + RD_RegsScope(.panel = rd_handle_zero(), .view = rd_handle_from_cfg(view)) + { + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); + rd_cfg_release_all_children(expr); + rd_cfg_new(expr, ws->hover_eval_string); + { + ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); + ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); + ui_set_next_pref_width(ui_em(60.f, 1.f)); + ui_set_next_pref_height(ui_em(40.f, 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + UI_Parent(container) + { + UI_Row + { + } + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill + { + RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; + String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); + MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; + view_ui(expr->first->string, params, view_contents_container->rect); + } + } + } + } + +#if 0 // TODO(rjf): @cfg Temp scratch = scratch_begin(0, 0); DI_Scope *scope = di_scope_open(); String8 expr = ws->hover_eval_string; E_Eval eval = e_eval_from_string(scratch.arena, expr); EV_ViewRuleList top_level_view_rules = {0}; - EV_ColList top_level_cols = {0}; //- rjf: build if good if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) @@ -6693,7 +6777,7 @@ rd_window_frame(void) 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_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules, &top_level_cols); + EV_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules); EV_BlockRangeList block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); // 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); @@ -6963,6 +7047,7 @@ rd_window_frame(void) di_scope_close(scope); scratch_end(scratch); +#endif } } @@ -9466,38 +9551,6 @@ rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI return num; } -internal EV_View * -rd_ev_view_from_key(U64 key) -{ - U64 slot_idx = key % rd_state->eval_viz_view_cache_slots_count; - RD_EvalVizViewCacheNode *node = 0; - RD_EvalVizViewCacheSlot *slot = &rd_state->eval_viz_view_cache_slots[slot_idx]; - for(RD_EvalVizViewCacheNode *n = slot->first; n != 0; n = n->next) - { - if(n->key == key) - { - node = n; - break; - } - } - if(node == 0) - { - node = rd_state->eval_viz_view_cache_node_free; - if(node) - { - SLLStackPop(rd_state->eval_viz_view_cache_node_free); - } - else - { - node = push_array(rd_state->arena, RD_EvalVizViewCacheNode, 1); - } - DLLPushBack(slot->first, slot->last, node); - node->key = key; - node->v = ev_view_alloc(); - } - return node->v; -} - 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) { @@ -12119,8 +12172,6 @@ rd_init(CmdLine *cmdln) rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); rd_state->string_search_arena = arena_alloc(); - rd_state->eval_viz_view_cache_slots_count = 1024; - rd_state->eval_viz_view_cache_slots = push_array(arena, RD_EvalVizViewCacheSlot, rd_state->eval_viz_view_cache_slots_count); rd_state->bind_change_arena = arena_alloc(); rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); @@ -12327,6 +12378,32 @@ rd_frame(void) 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); + ////////////////////////////// + //- rjf: garbage collect untouched immediate cfg trees + // + if(depth == 0) + { + RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); + for(RD_Cfg *tln = transient->first, *next = &rd_nil_cfg; tln != &rd_nil_cfg; tln = next) + { + next = tln->next; + if(str8_match(tln->string, str8_lit("immediate"), 0)) + { + if(rd_cfg_child_from_string(tln, str8_lit("hot")) == &rd_nil_cfg) + { + rd_cfg_release(tln); + } + } + } + for(RD_Cfg *tln = transient->first; tln != &rd_nil_cfg; tln = tln->next) + { + if(str8_match(tln->string, str8_lit("immediate"), 0)) + { + rd_cfg_release(rd_cfg_child_from_string(tln, str8_lit("hot"))); + } + } + } + ////////////////////////////// //- rjf: garbage collect untouched window states // @@ -12374,6 +12451,7 @@ rd_frame(void) next = vs->hash_next; if(vs->last_frame_index_touched+2 < rd_state->frame_index) { + ev_view_release(vs->ev_view); for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) { arena_release(ext->arena); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 82482f27..765220c3 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -194,6 +194,9 @@ struct RD_ViewState // rjf: scroll position UI_ScrollPt2 scroll_pos; + // rjf: eval visualization view state + EV_View *ev_view; + // rjf: view-lifetime allocation & user data extensions Arena *arena; RD_ArenaExt *first_arena_ext; @@ -724,25 +727,6 @@ struct RD_WindowStateSlot RD_WindowState *last; }; -//////////////////////////////// -//~ rjf: Eval Visualization View Cache Types - -typedef struct RD_EvalVizViewCacheNode RD_EvalVizViewCacheNode; -struct RD_EvalVizViewCacheNode -{ - RD_EvalVizViewCacheNode *next; - RD_EvalVizViewCacheNode *prev; - U64 key; - EV_View *v; -}; - -typedef struct RD_EvalVizViewCacheSlot RD_EvalVizViewCacheSlot; -struct RD_EvalVizViewCacheSlot -{ - RD_EvalVizViewCacheNode *first; - RD_EvalVizViewCacheNode *last; -}; - //////////////////////////////// //~ rjf: Meta Evaluation Cache Types @@ -919,11 +903,6 @@ struct RD_State Arena *string_search_arena; String8 string_search_string; - // rjf: eval visualization view cache - U64 eval_viz_view_cache_slots_count; - RD_EvalVizViewCacheSlot *eval_viz_view_cache_slots; - RD_EvalVizViewCacheNode *eval_viz_view_cache_node_free; - // rjf: ctrl entity meta eval cache U64 ctrl_entity_meval_cache_slots_count; RD_CtrlEntityMetaEvalCacheSlot *ctrl_entity_meval_cache_slots; @@ -1209,6 +1188,9 @@ internal String8 rd_setting_from_name(String8 name); #define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) #define rd_setting_u64_from_name(name) (u64_from_str8(rd_setting_from_name(name), 10)) +internal RD_Cfg *rd_immediate_cfg_from_key(String8 string); +internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); + //////////////////////////////// //~ rjf: Entity Stateful Functions @@ -1320,6 +1302,7 @@ internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewe //- rjf: view info extraction internal Arena *rd_view_arena(void); internal UI_ScrollPt2 rd_view_scroll_pos(void); +internal EV_View *rd_view_eval_view(void); internal String8 rd_view_expr_string(void); internal String8 rd_view_filter(void); @@ -1365,7 +1348,6 @@ internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__debug_info_t 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 id, void *user_data, RDI_SectionKind section); -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); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9797b8c5..16886323 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -794,6 +794,26 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //////////////////////////////// //~ rjf: Watch Views +//- rjf: cell list building + +internal RD_WatchCell * +rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list) +{ + RD_WatchCell *cell = push_array(arena, RD_WatchCell, 1); + SLLQueuePush(list->first, list->last, cell); + list->count += 1; + return cell; +} + +internal RD_WatchCell * +rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params) +{ + RD_WatchCell *cell = rd_watch_cell_list_push(arena, list); + MemoryCopyStruct(cell, params); + cell->next = 0; + return cell; +} + //- rjf: index -> column internal RD_WatchViewColumn * @@ -817,16 +837,16 @@ rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index) internal B32 rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b) { - return (a.x == b.x && - ev_key_match(a.parent_key, b.parent_key) && - ev_key_match(a.key, b.key)); + return (ev_key_match(a.parent_key, b.parent_key) && + ev_key_match(a.key, b.key) && + a.cell_id == b.cell_id); } internal RD_WatchViewPoint rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) { RD_WatchViewPoint pt = zero_struct; - pt.x = tbl.x; + pt.cell_id = (U64)tbl.x; pt.key = ev_key_from_num(block_ranges, (U64)tbl.y); pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key; return pt; @@ -836,7 +856,7 @@ internal Vec2S64 rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt) { Vec2S64 tbl = {0}; - tbl.x = pt.x; + tbl.x = (S64)pt.cell_id; tbl.y = (S64)ev_num_from_key(block_ranges, pt.key); return tbl; } @@ -996,10 +1016,23 @@ rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, return row_kind; } +//- rjf: row info -> cell list + +internal RD_WatchCellList +rd_watch_cell_list_from_row_info(Arena *arena, EV_Row *row, RD_WatchViewRowInfo *info) +{ + RD_WatchCellList cell_list = {0}; + rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Value, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Type, .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_ViewRule, .pct = 0.30f); + return cell_list; +} + //- rjf: row/column -> strings internal E_Expr * -rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, RD_WatchViewColumn *col) +rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col) { E_Expr *expr = row->expr; switch(col->kind) @@ -1026,11 +1059,11 @@ rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, } internal String8 -rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px) +rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px) { ProfBeginFunction(); String8 result = {0}; - E_Expr *row_col_expr = rd_expr_from_watch_view_row_column(arena, ev, row, col); + E_Expr *row_col_expr = rd_expr_from_watch_view_row_column(arena, row, col); switch(col->kind) { default:{}break; @@ -1063,6 +1096,9 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_Wa case RD_WatchViewColumnKind_ViewRule: ProfScope("view rule cell string") { + RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + EV_View *ev = vs->ev_view; result = ev_view_rule_from_key(ev, row->key); }break; case RD_WatchViewColumnKind_Module: @@ -1265,7 +1301,6 @@ internal void rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect) { ProfBeginFunction(); - DI_Scope *di_scope = di_scope_open(); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; @@ -1274,9 +1309,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: unpack arguments // EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_from_string(scratch.arena, root_view_rule); - EV_ColList top_level_cols = {0}; - String8 eval_view_key_string = push_str8f(scratch.arena, "eval_view_watch_%p", ewv); - EV_View *eval_view = rd_ev_view_from_key(d_hash_from_string(eval_view_key_string)); + EV_View *eval_view = rd_view_eval_view(); String8 filter = rd_view_filter(); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); @@ -1307,37 +1340,10 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo U64 row_ctrls_count = ArrayCount(row_ctrls_); #endif - ////////////////////////////// - //- rjf: root-level view rule which has a ui hook? call into that to build the UI - // - B32 is_top_level_hook = 0; -#if 0 // TODO(rjf): @cfg - { - RD_ViewRuleInfo *hook_rule_info = 0; - MD_Node *hook_rule_root = &md_nil_node; - for(EV_ViewRuleNode *n = top_level_view_rules->first; n != 0; n = n->next) - { - RD_ViewRuleInfo *rule_info = rd_view_rule_info_from_string(n->v.root->string); - if(rule_info != &rd_nil_view_rule_info && rule_info->ui != 0) - { - hook_rule_info = rule_info; - hook_rule_root = n->v.root; - break; - } - } - if(hook_rule_info) - { - hook_rule_info->ui(root_expr, hook_rule_root, rect); - is_top_level_hook = 1; - } - } -#endif - ////////////////////////////// //- rjf: determine autocompletion string // String8 autocomplete_hint_string = {0}; - if(!is_top_level_hook) { for(UI_Event *evt = 0; ui_next_event(&evt);) { @@ -1358,7 +1364,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo Vec2S64 cursor_tbl = {0}; Vec2S64 mark_tbl = {0}; Rng2S64 selection_tbl = {0}; - if(!is_top_level_hook) ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) + ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) { B32 state_dirty = 1; B32 snap_to_cursor = 0; @@ -1374,7 +1380,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules, &top_level_cols); + block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); } @@ -1591,9 +1597,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchViewPoint pt = {x, row->block->key, row->key}; + RD_WatchViewPoint pt = {row->block->key, row->key, x}; U64 hash = ev_hash_from_key(pt.key); U64 slot_idx = hash%ewv->text_edit_state_slots_count; RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); @@ -1779,7 +1785,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo if(rows.first != 0) { B32 should_commit_asap = editing_complete; - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); + E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, row, col); E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); if(dst_eval.space.kind == RD_EvalSpaceKind_MetaEntity) { @@ -1852,7 +1858,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 cell_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 cell_string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); cell_string = str8_skip_chop_whitespace(cell_string); U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) @@ -1920,7 +1926,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo key = row->block->key; parent_key = row->block->parent->key; } - RD_WatchViewPoint new_pt = {0, parent_key, key}; + RD_WatchViewPoint new_pt = {parent_key, key, 0}; next_cursor_pt = new_pt; next_cursor_set = 1; } @@ -1938,7 +1944,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } else if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Value || col->kind == RD_WatchViewColumnKind_Member) && row_kind == RD_WatchViewRowKind_Normal) { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); + E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, row, col); E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); rd_commit_eval_value_string(dst_eval, str8_zero(), 0); } @@ -2187,7 +2193,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: build ui // B32 pressed = 0; - if(!is_top_level_hook) ProfScope("build ui") + ProfScope("build ui") { F32 **col_pcts = push_array(scratch.arena, F32*, ewv->column_count); { @@ -2293,7 +2299,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ui_view_rule_params_root = &md_nil_node; } RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); + RD_WatchCellList row_cells = rd_watch_cell_list_from_row_info(scratch.arena, row, &row_info); ProfEnd(); //////////////////////// @@ -2346,6 +2352,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); row_flags |= UI_BoxFlag_DrawBackground; } +#if 0 // TODO(rjf): @cfg switch(row_kind) { default:{}break; @@ -2354,6 +2361,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewRowKind_Canvas:{row_flags |= UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder;}break; case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; } +#endif } ProfEnd(); @@ -2372,6 +2380,587 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ////////////////////// //- rjf: build row contents // + RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) + { + //////////////////// + //- rjf: draw start of cache lines in expansions + // + if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + { + U64 row_offset = row_eval.value.u64; + if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + + //////////////////// + //- rjf: draw mid-row cache line boundaries in expansions + // + if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + { + if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + row_eval.value.u64%64 != 0 && + row_depth > 0 && + !row_expanded) + { + U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); + if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_height(ui_top_font_size()*1.f); + Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); + boundary_color.w *= 0.5f; + ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + + //////////////////// + //- rjf: build all cells + // + for(RD_WatchCell *cell = row_cells.first; cell != 0; cell = cell->next) + { +#if 0 // TODO(rjf): @cfg + //- rjf: unpack cell info + RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); + String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + + //- rjf: unpack column-kind-specific info + ProfBegin("unpack column-kind-specific info"); + E_Eval cell_eval = row_eval; + E_Type *cell_type = row_type; + B32 cell_can_edit = 0; + FuzzyMatchRangeList cell_matches = {0}; + String8 cell_inheritance_string = {0}; + String8 cell_error_string = {0}; + String8 cell_error_tooltip_string = {0}; + RD_ListerFlags cell_autocomp_flags = 0; + RD_ViewRuleUIFunctionType *cell_ui_hook = 0; + MD_Node *cell_ui_params = &md_nil_node; + Vec4F32 cell_base_color = ui_top_palette()->text; + RD_IconKind cell_icon = RD_IconKind_Null; + String8 cell_ghost_text = {0}; + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: + { + cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); + if(filter.size != 0) + { + cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); + } + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); + if(row->member != 0 && row->member->inheritance_key_chain.first != 0) + { + String8List inheritance_chain_type_names = {0}; + for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) + { + String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); + inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); + str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); + } + if(inheritance_chain_type_names.node_count != 0) + { + StringJoin join = {0}; + join.sep = str8_lit("::"); + String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); + cell_inheritance_string = inheritance_type; + } + } + }break; + case RD_WatchViewColumnKind_Value: + { + }goto value_cell; + case RD_WatchViewColumnKind_Member: + { + E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); + cell_eval = e_eval_from_expr(scratch.arena, expr); + cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); + }goto value_cell; + value_cell:; + { + E_MsgList msgs = cell_eval.msgs; + if(row_depth == 0 && row->string.size != 0) + { + E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); + e_msg_list_concat_in_place(&parse.msgs, &msgs); + msgs = parse.msgs; + } + if(msgs.max_kind > E_MsgKind_Null) + { + String8List strings = {0}; + for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) + { + str8_list_push(scratch.arena, &strings, msg->text); + } + StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; + cell_error_string = str8_list_join(scratch.arena, &strings, &join); + } + if(row_is_bad) + { + cell_error_tooltip_string = str8_lit("Could not read memory successfully."); + } + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); + if(cell_type->flags & E_TypeFlag_IsPathText) + { + cell_autocomp_flags = RD_ListerFlag_Files; + } + if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) + { + cell_ui_hook = ui_view_rule_info->ui; + cell_ui_params = ui_view_rule_params_root; + } + for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) + { + EV_ViewRule *vr = &n->v; + RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); + if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) + { + cell_ui_hook = info->ui; + cell_ui_params = vr->root; + } + } + cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); + }break; + case RD_WatchViewColumnKind_Type: + { + cell_can_edit = 0; + }break; + case RD_WatchViewColumnKind_ViewRule: + { + cell_can_edit = 1; + cell_autocomp_flags = RD_ListerFlag_ViewRules; + if(cell_pre_edit_string.size == 0) + { + EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); + String8List strings = {0}; + for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &strings, n->v.root->string); + } + cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); + } + }break; + case RD_WatchViewColumnKind_CallStackFrameSelection: + { + if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && + row_info.callstack_unwind_index == rd_regs()->unwind_count && + row_info.callstack_inline_depth == rd_regs()->inline_depth) + { + cell_icon = RD_IconKind_RightArrow; + cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); + } + }break; + } + ProfEnd(); + + //- rjf: apply column-specified view rules + ProfBegin("apply column-specified view rules"); + if(col->view_rule_size != 0) + { + String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); + EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); + for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) + { + EV_ViewRule *vr = &n->v; + RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); + if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) + { + cell_ui_hook = info->ui; + cell_ui_params = vr->root; + } + } + } + ProfEnd(); + + //- rjf: determine cell's palette + ProfBegin("determine cell's palette"); + UI_BoxFlags cell_flags = 0; + UI_Palette *palette = ui_top_palette(); + { + if(cell_error_tooltip_string.size != 0 || + cell_error_string.size != 0) + { + palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); + cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(cell_inheritance_string.size != 0) + { + palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); + cell_flags |= UI_BoxFlag_DrawBackground; + } + else + { + palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); + } + } + ProfEnd(); + + //- rjf: determine if cell needs code styling + B32 cell_is_code = !col->is_non_code; + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: + { + cell_is_code = 1; + if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) + { + cell_is_code = 0; + } + }break; + case RD_WatchViewColumnKind_Value: + case RD_WatchViewColumnKind_Member: + { + if(cell_type->flags & E_TypeFlag_IsCodeText) + { + cell_is_code = 1; + } + else if(cell_type->flags & E_TypeFlag_IsPathText || + cell_type->flags & E_TypeFlag_IsPlainText) + { + cell_is_code = 0; + } + }break; + } + + //- rjf: build cell + UI_Signal sig = {0}; + ProfScope("build cell") + UI_Palette(palette) + UI_TableCell + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) + UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) + { + ui_set_next_flags(ui_top_flags() | cell_flags); + + // rjf: cell has errors? -> build error box + if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); + sig = ui_signal_from_box(box); + UI_Parent(box) UI_Flags(0) + { + rd_error_label(cell_error_string); + } + } + + // rjf: cell has hook? -> build ui by calling hook + else if(cell_ui_hook != 0) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); + UI_Parent(box) + { + String8 row_expr = e_string_from_expr(scratch.arena, row->expr); + cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); + } + sig = ui_signal_from_box(box); + } + + // rjf: cell has icon? build icon + else if(cell_icon != RD_IconKind_Null) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); + UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) + { + ui_label(rd_icon_kind_text_table[cell_icon]); + } + sig = ui_signal_from_box(box); + } + + // rjf: build cell line edit + else + { + sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| + RD_LineEditFlag_NoBackground| + RD_LineEditFlag_KeyboardClickable| + RD_LineEditFlag_DisableEdit*(!cell_can_edit)| + RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && cell == row_cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && cell == row_cells.first)| + RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && cell == row_cells.first)), + x == 0 ? row_depth : 0, + &cell_matches, + &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, + cell_pre_edit_string, + "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + { + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } + } + } + + //- rjf: handle interactions + { + // rjf: single-click -> move selection here + if(ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: double-click actions + if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) + { + ui_kill_action(); + + // rjf: has callstack info? -> select unwind + if(row_info.callstack_thread != &ctrl_entity_nil) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info.callstack_unwind_index, + .inline_depth = row_info.callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(cell_can_edit) + { + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: cannot edit, has addr info? -> go to address + else if(row_kind == RD_WatchViewRowKind_Normal && + (col->kind == RD_WatchViewColumnKind_Value || + col->kind == RD_WatchViewColumnKind_Member) && + cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) + { + U64 vaddr = cell_eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) + { + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; + } + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); + } + } + } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); + } + } + + //- rjf: bump x pixel coordinate + x_px += col->pct*dim_2f32(rect).x; + + //- 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_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); + } + + //- rjf: [DEV] hovering -> eval system tooltips + if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) + { + local_persist char *spaces = " "; + String8 string = ev_expr_string_from_row(scratch.arena, row, 0); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); + ui_label(string); + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); + for(U64 idx = 0; idx < tokens.count; idx += 1) + { + ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_Expr *expr; + S64 depth; + }; + Task start_task = {0, 0, parse.expr}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 ext = {0}; + switch(t->expr->kind) + { + default: + { + if(t->expr->string.size != 0) + { + ext = push_str8f(scratch.arena, "'%S'", t->expr->string); + } + else if(t->expr->value.u32 != 0) + { + ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); + } + else if(t->expr->value.f32 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); + } + else if(t->expr->value.f64 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); + } + else if(t->expr->value.u64 != 0) + { + ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); + } + }break; + } + ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->expr = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_IRNode *node; + S64 depth; + }; + Task start_task = {0, 0, irtree.root}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 op_string = {0}; + switch(t->node->op) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); + for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->node = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); + { + for(E_Op *op = oplist.first; op != 0; op = op->next) + { + String8 op_string = {0}; + switch(op->opcode) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + switch(op->opcode) + { + case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; + default: + { + ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); + }break; + } + ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); + { + for(U64 idx = 0; idx < bytecode.size; idx += 1) + { + ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); + } + } + } +#endif + } + } + + ////////////////////// + //- rjf: build row contents + // +#if 0 // TODO(rjf): @cfg RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) switch(row_kind) { //////////////////// @@ -3416,6 +4005,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } }break; } +#endif ////////////////////// //- rjf: commit expansion state changes @@ -3432,14 +4022,13 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ////////////////////////////// //- rjf: general table-wide press logic // - if(!is_top_level_hook) if(pressed) + if(pressed) { rd_cmd(RD_CmdKind_FocusPanel); } - if(!is_top_level_hook) { rd_store_view_scroll_pos(scroll_pos); } + rd_store_view_scroll_pos(scroll_pos); scratch_end(scratch); - di_scope_close(di_scope); ProfEnd(); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 0b3122fc..4c75d4e2 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -50,6 +50,37 @@ enum RD_WatchViewFlag_DisableCacheLines = (1<<3), }; +typedef enum RD_WatchCellKind +{ + RD_WatchCellKind_Expr, + RD_WatchCellKind_Value, + RD_WatchCellKind_Type, + RD_WatchCellKind_ViewRule, + RD_WatchCellKind_Member, + RD_WatchCellKind_CallStackFrame, + RD_WatchCellKind_CallStackFrameSelection, + RD_WatchCellKind_Module, +} +RD_WatchCellKind; + +typedef struct RD_WatchCell RD_WatchCell; +struct RD_WatchCell +{ + RD_WatchCell *next; + RD_WatchCellKind kind; + F32 pct; + String8 member; + String8 view_rule; +}; + +typedef struct RD_WatchCellList RD_WatchCellList; +struct RD_WatchCellList +{ + RD_WatchCell *first; + RD_WatchCell *last; + U64 count; +}; + typedef enum RD_WatchViewColumnKind { RD_WatchViewColumnKind_Expr, @@ -113,9 +144,9 @@ RD_WatchViewRowKind; typedef struct RD_WatchViewPoint RD_WatchViewPoint; struct RD_WatchViewPoint { - S64 x; EV_Key parent_key; EV_Key key; + U64 cell_id; }; typedef struct RD_WatchViewRowInfo RD_WatchViewRowInfo; @@ -178,6 +209,11 @@ internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewStat //////////////////////////////// //~ rjf: Watch View Functions +//- rjf: cell list building +internal RD_WatchCell *rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list); +internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params); +#define rd_watch_cell_list_push_new(arena, list, kind_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), __VA_ARGS__}) + //- rjf: index -> column internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index); @@ -192,9 +228,12 @@ internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); //- rjf: watch view flags & row & row info -> row kind internal RD_WatchViewRowKind rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, RD_WatchViewRowInfo *info); +//- rjf: row info -> cell list +internal RD_WatchCellList rd_watch_cell_list_from_row_info(Arena *arena, EV_Row *row, RD_WatchViewRowInfo *info); + //- rjf: row/column -> exprs / strings -internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, RD_WatchViewColumn *col); -internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); +internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col); +internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt); From 136a6a6d80d3911d52d71eff675768d4fed117ff Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 Jan 2025 10:38:04 -0800 Subject: [PATCH 031/755] eval visualization: vidx <-> num mappings; helpers to move from logical nums -> rows, feed through windowed row production path --- src/eval/eval_core.h | 2 +- src/eval/eval_ir.c | 2 +- .../eval_visualization_core.c | 101 +++++++++++++++--- .../eval_visualization_core.h | 26 +++-- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 22 +++- src/raddbg/raddbg_views.c | 55 +++++----- 8 files changed, 153 insertions(+), 63 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 29579d20..c27e2e57 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -93,7 +93,7 @@ typedef U64 E_SpaceKind; enum { E_SpaceKind_Null, - E_SpaceKind_FileSystem, + E_SpaceKind_HashStoreKey, E_SpaceKind_FirstUserDefined, }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 203798f2..8a4ce94b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1282,7 +1282,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr case E_ExprKind_LeafFilePath: { U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); - E_Space space = {E_SpaceKind_FileSystem, .u128 = key}; + E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; U64 size = fs_size_from_path(expr->string); E_IRNode *base_offset = e_irtree_const_u(arena, 0); E_IRNode *set_space = e_irtree_set_space(arena, space, base_offset); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index dfaf7e46..5797a435 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1049,6 +1049,52 @@ ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) return result; } +internal U64 +ev_vidx_from_num(EV_BlockRangeList *block_ranges, U64 num) +{ + U64 vidx = 0; + { + U64 base_vidx = 0; + U64 base_num = 1; + for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) + { + U64 next_base_num = base_num + (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + if(base_num <= num && num < next_base_num) + { + U64 relative_vidx = (n->v.block->single_item ? 0 : (num - base_num)); + vidx = base_vidx + relative_vidx; + break; + } + base_num = next_base_num; + base_vidx += dim_1u64(n->v.range); + } + } + return vidx; +} + +internal U64 +ev_num_from_vidx(EV_BlockRangeList *block_ranges, U64 vidx) +{ + U64 num = 0; + { + U64 base_vidx = 0; + U64 base_num = 1; + for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) + { + U64 next_base_vidx = base_vidx + dim_1u64(n->v.range); + if(base_vidx <= vidx && vidx < next_base_vidx) + { + U64 relative_num = (n->v.block->single_item ? 0 : (vidx - base_vidx)); + num = base_num + relative_num; + break; + } + base_vidx = next_base_vidx; + base_num += (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + } + } + return num; +} + //////////////////////////////// //~ rjf: Row Building @@ -1126,18 +1172,19 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } scratch_end(scratch); } - EV_Row *row = push_array(arena, EV_Row, 1); - SLLQueuePush(rows.first, rows.last, row); + EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); + SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; - row->block = n->v.block; - row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); - row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; - row->visual_size_skipped = num_skipped; - row->visual_size_chopped = num_chopped; - row->string = n->v.block->string; - row->expr = n->v.block->expr; - row->member = member; - row->view_rules = n->v.block->view_rules; + row_node->visual_size_skipped = num_skipped; + row_node->visual_size_chopped = num_chopped; + EV_Row *row = &row_node->row; + row->block = n->v.block; + row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); + row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; + row->string = n->v.block->string; + row->expr = n->v.block->expr; + row->member = member; + row->view_rules = n->v.block->view_rules; } // rjf: expansion operator applied -> call, and add rows for all expressions in the viewable range @@ -1165,14 +1212,13 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 scratch_end(scratch); } E_Expr *row_expr__resolved = ev_resolved_from_expr(arena, row_expr, row_view_rules); - EV_Row *row = push_array(arena, EV_Row, 1); - SLLQueuePush(rows.first, rows.last, row); + EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); + SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; + EV_Row *row = &row_node->row; row->block = n->v.block; row->key = row_key; row->visual_size = 1; - row->visual_size_skipped = 0; - row->visual_size_chopped = 0; row->string = expand_range_info.row_strings[idx]; row->expr = row_expr__resolved; row->member = expand_range_info.row_members[idx]; @@ -1205,6 +1251,31 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 return rows; } +internal EV_Row * +ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num) +{ + U64 vidx = ev_vidx_from_num(block_ranges, num); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, r1u64(vidx, vidx+1)); + EV_Row *result = 0; + if(rows.first != 0) + { + result = &rows.first->row; + } + else + { + result = push_array(arena, EV_Row, 1); + } + return result; +} + +internal EV_WindowedRowList +ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range) +{ + Rng1U64 vidx_range = r1u64(ev_vidx_from_num(block_ranges, num_range.min), ev_vidx_from_num(block_ranges, num_range.max)+1); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vidx_range); + return rows; +} + internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags) { diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 41b9d403..61fbed78 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -256,29 +256,29 @@ struct EV_BlockRangeList typedef struct EV_Row EV_Row; struct EV_Row { - EV_Row *next; - - // rjf: block hierarchy info EV_Block *block; EV_Key key; - - // rjf: row size/scroll info U64 visual_size; - U64 visual_size_skipped; - U64 visual_size_chopped; - - // rjf: expression / visualization info String8 string; E_Expr *expr; E_Member *member; EV_ViewRuleList *view_rules; }; +typedef struct EV_WindowedRowNode EV_WindowedRowNode; +struct EV_WindowedRowNode +{ + EV_WindowedRowNode *next; + U64 visual_size_skipped; + U64 visual_size_chopped; + EV_Row row; +}; + typedef struct EV_WindowedRowList EV_WindowedRowList; struct EV_WindowedRowList { - EV_Row *first; - EV_Row *last; + EV_WindowedRowNode *first; + EV_WindowedRowNode *last; U64 count; U64 count_before_visual; U64 count_before_semantic; @@ -429,11 +429,15 @@ internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockT internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num); internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key); +internal U64 ev_vidx_from_num(EV_BlockRangeList *block_ranges, U64 num); +internal U64 ev_num_from_vidx(EV_BlockRangeList *block_ranges, U64 vidx); //////////////////////////////// //~ rjf: Row Building internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range); +internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); +internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags); internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a449799a..5a97c7f0 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -391,8 +391,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 381212bd..05128c8d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -516,8 +516,8 @@ RD_CmdTable: // | | | | {MoveRightSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } {MoveUpSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } {MoveDownSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } - {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Select" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } {MoveUpChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } {MoveDownChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } {MoveUpPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f718f1be..d3b97378 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2713,7 +2713,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) switch(space.kind) { //- rjf: filesystem reads - case E_SpaceKind_FileSystem: + case E_SpaceKind_HashStoreKey: { U128 key = space.u128; U128 hash = hs_hash_from_key(key, 0); @@ -3164,7 +3164,7 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) U128 result = {0}; switch(space.kind) { - case E_SpaceKind_FileSystem: + case E_SpaceKind_HashStoreKey: { result = space.u128; }break; @@ -3188,7 +3188,7 @@ rd_whole_range_from_eval_space(E_Space space) Rng1U64 result = {0}; switch(space.kind) { - case E_SpaceKind_FileSystem: + case E_SpaceKind_HashStoreKey: { HS_Scope *scope = hs_scope_open(); U128 hash = {0}; @@ -13297,6 +13297,22 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); } + //- rjf: add macro for output log + { + HS_Scope *hs_scope = hs_scope_open(); + U128 key = d_state->output_log_key; + U128 hash = hs_hash_from_key(key, 0); + String8 data = hs_data_from_hash(hs_scope, hash); + E_Space space = e_space_make(E_SpaceKind_HashStoreKey); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + space.u128 = key; + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output_log"), expr); + hs_scope_close(hs_scope); + } + //- rjf: add macros for all watches which define identifiers RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); for(RD_CfgNode *n = watches.first; n != 0; n = n->next) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 16886323..4e00fe52 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1464,15 +1464,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo mark_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->mark); // rjf: compute row at initial selection point (or just cursor point) - mark_rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, mark_tbl.y), - ui_scroll_list_row_from_item(&row_blocks, mark_tbl.y)+1)); + mark_rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(mark_tbl.y, mark_tbl.y+1)); // rjf: compute legal coordinate range, given selection-defining row Rng1S64 cursor_x_range = r1s64(0, ewv->column_count-1); if(mark_rows.first != 0) { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(mark_rows.first); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, mark_rows.first, &row_info); + RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(&mark_rows.first->row); + RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, &mark_rows.first->row, &row_info); if(row_kind == RD_WatchViewRowKind_PrettyEntityControls) { U64 row_ctrl_count = 0; @@ -1584,11 +1583,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { + EV_Row *row = &row_node->row; RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); if(row_kind == RD_WatchViewRowKind_Normal) @@ -1623,12 +1622,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept) { taken = 1; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { // rjf: unpack row info + EV_Row *row = &row_node->row; RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); @@ -1693,11 +1692,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo evt->delta_2s32.y == 0)) { taken = 1; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { + EV_Row *row = &row_node->row; RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) @@ -1780,8 +1779,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewColumnKind_Member: case RD_WatchViewColumnKind_Value: { - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, y), - ui_scroll_list_row_from_item(&row_blocks, y)+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(y, y+1)); if(rows.first != 0) { B32 should_commit_asap = editing_complete; @@ -1850,11 +1848,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { taken = 1; String8List strs = {0}; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next) + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { + EV_Row *row = &row_node->row; for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); @@ -1894,11 +1892,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_EntityList entities_to_remove = {0}; RD_WatchViewPoint next_cursor_pt = {0}; B32 next_cursor_set = 0; - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y), - ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y)+1)); - EV_Row *row = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next) + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { + EV_Row *row = &row_node->row; RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) @@ -2245,7 +2243,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ProfScope("build table") { U64 global_row_idx = rows.count_before_semantic; - for(EV_Row *row = rows.first; row != 0; row = row->next, global_row_idx += 1) + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) { //////////////////////// //- rjf: skip header @@ -2259,6 +2257,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: unpack row info // ProfBegin("unpack row info"); + EV_Row *row = &row_node->row; U64 row_hash = ev_hash_from_key(row->key); U64 row_depth = ev_depth_from_block(row->block); if(row_depth > 0) @@ -2373,7 +2372,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_px(scroll_list_params.row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row_node->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); ui_ts_vector_idx += 1; ui_ts_cell_idx = 0; From baa19f3de451ca65170592dfe2b806ff36c057b6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 Jan 2025 16:41:14 -0800 Subject: [PATCH 032/755] begin introducing 'lookup' hook path in eval ir-tree generation, to collapse/universalize all 'access' operations, such that ., ->, and [] operations can be overridden via view rules, for cfg evaluations, and so on --- src/eval/eval.mdesk | 1 + src/eval/eval_ir.c | 532 +++++++++++++++++++-------------- src/eval/eval_ir.h | 64 ++++ src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- src/raddbg/raddbg_core.c | 4 +- src/raddbg/raddbg_views.c | 82 +++-- src/raddbg/raddbg_views.h | 38 ++- 8 files changed, 471 insertions(+), 261 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 5fc62ece..05737d53 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -72,6 +72,7 @@ E_TypeKindTable: {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } {SpacePtr "space_ptr" 0 } + {Set "set" 0 } } @table(name op_kind precedence string op_pre op_sep op_pos) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 8a4ce94b..67abc754 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -70,6 +70,310 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_ctx = ctx; } +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRule * +e_lookup_rule_from_string(String8 string) +{ + local_persist read_only E_LookupRule e_lookup_rule__default = + { + str8_lit_comp("default"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_FUNCTION_NAME(default), + }; + E_LookupRule *result = &e_lookup_rule__default; + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%e_ir_ctx->lookup_rule_map->slots_count; + for(E_LookupRuleNode *n = e_ir_ctx->lookup_rule_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->v.name, string, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + +E_LOOKUP_INFO_FUNCTION_DEF(default) +{ + E_LookupInfo lookup_info = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + lookup_info.idxed_expr_count = 1; + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Array) + { + E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); + lookup_info.idxed_expr_count = direct_type->count; + } + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); + lookup_info.named_expr_count = direct_type->count; + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Enum) + { + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + lookup_info.named_expr_count = lhs_type->count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_FUNCTION_DEF(default) +{ + E_Lookup lookup = {0}; + switch(kind) + { + default:{}break; + + //- rjf: member accessing + case E_ExprKind_MemberAccess: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKey check_type_key = l_restype; + E_TypeKind check_type_kind = l_restype_kind; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); + check_type_kind = e_type_kind_from_key(check_type_key); + } + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); + + // rjf: look up member + B32 r_found = 0; + E_TypeKey r_type = zero_struct; + U64 r_value = 0; + B32 r_is_constant_value = 0; + { + Temp scratch = scratch_begin(&arena, 1); + E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); + if(match.kind != E_MemberKind_Null) + { + r_found = 1; + r_type = match.type_key; + r_value = match.off; + } + if(match.kind == E_MemberKind_Null) + { + E_Type *type = e_type_from_key(scratch.arena, check_type_key); + if(type->enum_vals != 0) + { + String8 lookup_string = exprr->string; + String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); + String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); + E_EnumVal *enum_val_match = 0; + for EachIndex(idx, type->count) + { + if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) + { + enum_val_match = &type->enum_vals[idx]; + break; + } + } + if(enum_val_match != 0) + { + r_found = 1; + r_type = check_type_key; + r_value = enum_val_match->val; + r_is_constant_value = 1; + } + } + } + scratch_end(scratch); + } + + // rjf: bad conditions? -> error if applicable, exit + if(e_type_key_match(e_type_key_zero(), check_type_key)) + { + break; + } + else if(exprr->kind != E_ExprKind_LeafMember) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + break; + } + else if(!r_found) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + break; + } + else if(check_type_kind != E_TypeKind_Struct && + check_type_kind != E_TypeKind_Class && + check_type_kind != E_TypeKind_Union && + check_type_kind != E_TypeKind_Enum) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + break; + } + + // rjf: generate + { + // rjf: build tree + E_IRNode *new_tree = l.root; + E_Mode mode = l.mode; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); + mode = E_Mode_Offset; + } + if(r_value != 0 && !r_is_constant_value) + { + E_IRNode *const_tree = e_irtree_const_u(arena, r_value); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); + } + else if(r_is_constant_value) + { + new_tree = e_irtree_const_u(arena, r_value); + mode = E_Mode_Value; + } + + // rjf: fill + lookup.irtree_and_type.root = new_tree; + lookup.irtree_and_type.type_key = r_type; + lookup.irtree_and_type.mode = mode; + } + }break; + + //- rjf: array indexing + case E_ExprKind_ArrayIndex: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKey r_restype = e_type_unwrap(r.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); + if(e_type_kind_is_basic_or_enum(r_restype_kind)) + { + r_restype = e_type_unwrap_enum(r_restype); + r_restype_kind = e_type_kind_from_key(r_restype); + } + E_TypeKey direct_type = e_type_unwrap(l_restype); + direct_type = e_type_direct_from_key(direct_type); + direct_type = e_type_unwrap(direct_type); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &r.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r.root->op == 0) + { + break; + } + else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + break; + } + else if(!e_type_kind_is_integer(r_restype_kind)) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + break; + } + else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + break; + } + else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + break; + } + + // rjf: generate + E_IRNode *new_tree = &e_irnode_nil; + { + switch(l.mode) + { + // rjf: offsets -> read from base offset + default: + case E_Mode_Null: + case E_Mode_Offset: + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) + E_IRNode *base_tree = l.root; + if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) + { + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); + } + + // rjf: ops to compute the final address + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + }break; + + // rjf: values -> read from stack value + case E_Mode_Value: + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to push stack value, push offset, + read from stack value + new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); + new_tree->value.u64 = direct_type_size; + e_irnode_push_child(new_tree, offset_tree); + e_irnode_push_child(new_tree, l.root); + }break; + } + } + + // rjf: fill + lookup.irtree_and_type.root = new_tree; + lookup.irtree_and_type.type_key = direct_type; + lookup.irtree_and_type.mode = l.mode; + }break; + } + return lookup; +} + //////////////////////////////// //~ rjf: IR-ization Functions @@ -400,228 +704,16 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref); }break; - //- rjf: array indices + //- rjf: accesses + case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); - E_IRTreeAndType r = e_irtree_and_type_from_expr__space(arena, current_space, exprr); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKey r_restype = e_type_unwrap(r.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); - if(e_type_kind_is_basic_or_enum(r_restype_kind)) - { - r_restype = e_type_unwrap_enum(r_restype); - r_restype_kind = e_type_kind_from_key(r_restype); - } - E_TypeKey direct_type = e_type_unwrap(l_restype); - direct_type = e_type_direct_from_key(direct_type); - direct_type = e_type_unwrap(direct_type); - U64 direct_type_size = e_type_byte_size_from_key(direct_type); - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - e_msg_list_concat_in_place(&result.msgs, &r.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r.root->op == 0) - { - break; - } - else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); - break; - } - else if(!e_type_kind_is_integer(r_restype_kind)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); - break; - } - else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); - break; - } - else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); - break; - } - - // rjf: generate - E_IRNode *new_tree = &e_irnode_nil; - { - switch(l.mode) - { - // rjf: offsets -> read from base offset - default: - case E_Mode_Null: - case E_Mode_Offset: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) - E_IRNode *base_tree = l.root; - if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) - { - base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); - } - - // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - }break; - - // rjf: values -> read from stack value - case E_Mode_Value: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to push stack value, push offset, + read from stack value - new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); - new_tree->value.u64 = direct_type_size; - e_irnode_push_child(new_tree, offset_tree); - e_irnode_push_child(new_tree, l.root); - }break; - } - } - - // rjf: fill - result.root = new_tree; - result.type_key = direct_type; - result.mode = l.mode; - }break; - - //- rjf: member accesses - case E_ExprKind_MemberAccess: - { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKey check_type_key = l_restype; - E_TypeKind check_type_kind = l_restype_kind; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); - check_type_kind = e_type_kind_from_key(check_type_key); - } - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - - // rjf: look up member - B32 r_found = 0; - E_TypeKey r_type = zero_struct; - U64 r_value = 0; - B32 r_is_constant_value = 0; - { - Temp scratch = scratch_begin(&arena, 1); - E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); - if(match.kind != E_MemberKind_Null) - { - r_found = 1; - r_type = match.type_key; - r_value = match.off; - } - if(match.kind == E_MemberKind_Null) - { - E_Type *type = e_type_from_key(scratch.arena, check_type_key); - if(type->enum_vals != 0) - { - String8 lookup_string = exprr->string; - String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); - String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); - E_EnumVal *enum_val_match = 0; - for EachIndex(idx, type->count) - { - if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) - { - enum_val_match = &type->enum_vals[idx]; - break; - } - } - if(enum_val_match != 0) - { - r_found = 1; - r_type = check_type_key; - r_value = enum_val_match->val; - r_is_constant_value = 1; - } - } - } - scratch_end(scratch); - } - - // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(e_type_key_zero(), check_type_key)) - { - break; - } - else if(exprr->kind != E_ExprKind_LeafMember) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); - break; - } - else if(!r_found) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); - break; - } - else if(check_type_kind != E_TypeKind_Struct && - check_type_kind != E_TypeKind_Class && - check_type_kind != E_TypeKind_Union && - check_type_kind != E_TypeKind_Enum) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); - break; - } - - // rjf: generate - { - // rjf: build tree - E_IRNode *new_tree = l.root; - E_Mode mode = l.mode; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); - mode = E_Mode_Offset; - } - if(r_value != 0 && !r_is_constant_value) - { - E_IRNode *const_tree = e_irtree_const_u(arena, r_value); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); - } - else if(r_is_constant_value) - { - new_tree = e_irtree_const_u(arena, r_value); - mode = E_Mode_Value; - } - - // rjf: fill - result.root = new_tree; - result.type_key = r_type; - result.mode = mode; - } + E_Expr *lhs = expr->first; + E_Expr *rhs = lhs->next; + E_LookupRule *lookup_rule = e_lookup_rule_from_string(expr->string); + E_LookupInfo lookup_info = lookup_rule->lookup_info(arena, lhs); + E_Lookup lookup = lookup_rule->lookup(arena, expr->kind, lhs, rhs, lookup_info.user_data); + result = lookup.irtree_and_type; }break; //- rjf: dereference diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index ed54188b..0053ff76 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -56,6 +56,62 @@ struct E_IRTreeAndType E_MsgList msgs; }; +//////////////////////////////// +//~ rjf: Member/Index Lookup Hooks + +typedef struct E_LookupInfo E_LookupInfo; +struct E_LookupInfo +{ + void *user_data; + U64 named_expr_count; + U64 idxed_expr_count; +}; + +typedef struct E_Lookup E_Lookup; +struct E_Lookup +{ + E_IRTreeAndType irtree_and_type; +}; + +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs) +#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name +#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) +typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); + +#define E_LOOKUP_FUNCTION_SIG(name) E_Lookup name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) +#define E_LOOKUP_FUNCTION_NAME(name) e_lookup_##name +#define E_LOOKUP_FUNCTION_DEF(name) internal E_LOOKUP_FUNCTION_SIG(E_LOOKUP_FUNCTION_NAME(name)) +typedef E_LOOKUP_FUNCTION_SIG(E_LookupFunctionType); + +typedef struct E_LookupRule E_LookupRule; +struct E_LookupRule +{ + String8 name; + E_LookupInfoFunctionType *lookup_info; + E_LookupFunctionType *lookup; +}; + +typedef struct E_LookupRuleNode E_LookupRuleNode; +struct E_LookupRuleNode +{ + E_LookupRuleNode *next; + E_LookupRule v; +}; + +typedef struct E_LookupRuleSlot E_LookupRuleSlot; +struct E_LookupRuleSlot +{ + E_LookupRuleNode *first; + E_LookupRuleNode *last; +}; + +typedef struct E_LookupRuleMap E_LookupRuleMap; +struct E_LookupRuleMap +{ + E_LookupRuleSlot *slots; + U64 slots_count; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -63,6 +119,7 @@ typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { E_String2ExprMap *macro_map; + E_LookupRuleMap *lookup_rule_map; }; //////////////////////////////// @@ -83,6 +140,13 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); internal E_IRCtx *e_selected_ir_ctx(void); internal void e_select_ir_ctx(E_IRCtx *ctx); +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRule *e_lookup_rule_from_string(String8 string); +E_LOOKUP_INFO_FUNCTION_DEF(default); +E_LOOKUP_FUNCTION_DEF(default); + //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 1d5e9291..eec6b7bc 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -135,7 +135,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, }; -U8 e_kind_basic_byte_size_table[56] = +U8 e_kind_basic_byte_size_table[57] = { 0, 0, @@ -193,9 +193,10 @@ U8 e_kind_basic_byte_size_table[56] = 0, 0, 0, +0, }; -String8 e_kind_basic_string_table[56] = +String8 e_kind_basic_string_table[57] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -253,6 +254,7 @@ str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), str8_lit_comp("space_ptr"), +str8_lit_comp("set"), }; C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 225aa598..125d8245 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -75,6 +75,7 @@ E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, E_TypeKind_SpacePtr, +E_TypeKind_Set, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -164,8 +165,8 @@ extern String8 e_token_kind_strings[6]; extern String8 e_expr_kind_strings[49]; extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[49]; -extern U8 e_kind_basic_byte_size_table[56]; -extern String8 e_kind_basic_string_table[56]; +extern U8 e_kind_basic_byte_size_table[57]; +extern String8 e_kind_basic_string_table[57]; C_LINKAGE_END diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d3b97378..45669943 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13084,8 +13084,8 @@ rd_frame(void) E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); { 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); + 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 { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4e00fe52..fc6f4d80 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -835,17 +835,17 @@ rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index) //- rjf: watch view points <-> table coordinates internal B32 -rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b) +rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b) { return (ev_key_match(a.parent_key, b.parent_key) && ev_key_match(a.key, b.key) && a.cell_id == b.cell_id); } -internal RD_WatchViewPoint -rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) +internal RD_WatchPt +rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) { - RD_WatchViewPoint pt = zero_struct; + RD_WatchPt pt = zero_struct; pt.cell_id = (U64)tbl.x; pt.key = ev_key_from_num(block_ranges, (U64)tbl.y); pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key; @@ -853,7 +853,7 @@ rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) } internal Vec2S64 -rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt) +rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Vec2S64 tbl = {0}; tbl.x = (S64)pt.cell_id; @@ -861,6 +861,40 @@ rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint return tbl; } +//- rjf: row -> info + +internal RD_WatchRowInfo +rd_watch_row_info_from_row(Arena *arena, EV_Row *row) +{ + RD_WatchRowInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); + + // rjf: unpack key & block + EV_Block *block = row->block; + EV_Key key = row->key; + E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); + E_Type *parent_type = e_type_from_key(arena, parent_irtree.type_key); + + // rjf: fill row's eval + info.eval = e_eval_from_expr(arena, row->expr); + + // rjf: determine cfg group + + + // rjf: fill row's cells + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Value, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Type, .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewRule, .pct = 0.30f); + + di_scope_close(di_scope); + scratch_end(scratch); + } + return info; +} + //- rjf: row -> context info internal RD_WatchViewRowInfo @@ -1229,7 +1263,7 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState * -rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt) +rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt) { RD_WatchViewTextEditState *result = &wv->dummy_text_edit_state; if(wv->text_edit_state_slots_count != 0 && wv->text_editing != 0) @@ -1238,7 +1272,7 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint p U64 slot_idx = hash%wv->text_edit_state_slots_count; for(RD_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next) { - if(rd_watch_view_point_match(pt, s->pt)) + if(rd_watch_pt_match(pt, s->pt)) { result = s; break; @@ -1416,7 +1450,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo cursor_dirty__tbl = 0; struct { - RD_WatchViewPoint *pt_state; + RD_WatchPt *pt_state; Vec2S64 pt_tbl; } points[] = @@ -1428,7 +1462,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { EV_Key last_key = points[point_idx].pt_state->key; EV_Key last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state[0] = rd_watch_view_point_from_tbl(&block_ranges, points[point_idx].pt_tbl); + points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key)) { points[point_idx].pt_state->key = last_parent_key; @@ -1460,8 +1494,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo Rng2S64 cursor_tbl_range = {0}; { // rjf: compute 2d table coordinates - cursor_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->cursor); - mark_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->mark); + cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); + mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); // rjf: compute row at initial selection point (or just cursor point) mark_rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(mark_tbl.y, mark_tbl.y+1)); @@ -1544,7 +1578,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: apply cursor/mark rugpull change // B32 cursor_rugpull = 0; - if(!rd_watch_view_point_match(ewv->cursor, ewv->next_cursor)) + if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) { cursor_rugpull = 1; ewv->cursor = ewv->next_cursor; @@ -1598,7 +1632,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); String8 string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchViewPoint pt = {row->block->key, row->key, x}; + RD_WatchPt pt = {row->block->key, row->key, x}; U64 hash = ev_hash_from_key(pt.key); U64 slot_idx = hash%ewv->text_edit_state_slots_count; RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); @@ -1701,7 +1735,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, v2s64(x, y)); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, v2s64(x, y)); RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); String8 string = str8(edit_state->input_buffer, edit_state->input_size); UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); @@ -1808,7 +1842,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewColumnKind_ViewRule: if(editing_complete) { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); ev_key_set_view_rule(eval_view, pt.key, new_string); if(row_info.collection_entity_kind != RD_EntityKind_Nil) { @@ -1890,7 +1924,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo state_dirty = 1; snap_to_cursor = 1; RD_EntityList entities_to_remove = {0}; - RD_WatchViewPoint next_cursor_pt = {0}; + RD_WatchPt next_cursor_pt = {0}; B32 next_cursor_set = 0; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; @@ -1902,7 +1936,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { Vec2S64 tbl = v2s64(x, y); - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && row_info.collection_entity_kind != RD_EntityKind_Nil) @@ -1924,7 +1958,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo key = row->block->key; parent_key = row->block->parent->key; } - RD_WatchViewPoint new_pt = {parent_key, key, 0}; + RD_WatchPt new_pt = {parent_key, key, 0}; next_cursor_pt = new_pt; next_cursor_set = 1; } @@ -2298,7 +2332,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ui_view_rule_params_root = &md_nil_node; } RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchCellList row_cells = rd_watch_cell_list_from_row_info(scratch.arena, row, &row_info); + RD_WatchRowInfo row_info_NEW = rd_watch_row_info_from_row(scratch.arena, row); ProfEnd(); //////////////////////// @@ -2425,11 +2459,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////// //- rjf: build all cells // - for(RD_WatchCell *cell = row_cells.first; cell != 0; cell = cell->next) + for(RD_WatchCell *cell = row_info_NEW.cells.first; cell != 0; cell = cell->next) { #if 0 // TODO(rjf): @cfg //- rjf: unpack cell info - RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; + RD_WatchPt cell_pt = {x, row->block->key, row->key}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); @@ -3046,7 +3080,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { #if 0 // TODO(rjf): @cfg //- rjf: unpack - RD_WatchViewPoint pt = {0, row->block->key, row->key}; + RD_WatchPt pt = {0, row->block->key, row->key}; RD_View *view = rd_view_from_handle(rd_regs()->view); RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); RD_View *canvas_view = canvas_view_node->view; @@ -3312,7 +3346,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } if(ui_pressed(sig)) { - RD_WatchViewPoint cell_pt = {1, row->block->key, row->key}; + RD_WatchPt cell_pt = {1, row->block->key, row->key}; ewv->next_cursor = ewv->next_mark = cell_pt; pressed = 1; } @@ -3477,7 +3511,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) { //- rjf: unpack cell info - RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; + RD_WatchPt cell_pt = {x, row->block->key, row->key}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 4c75d4e2..4d0aa592 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -81,6 +81,19 @@ struct RD_WatchCellList U64 count; }; +typedef struct RD_WatchRowInfo RD_WatchRowInfo; +struct RD_WatchRowInfo +{ + E_Eval eval; + String8 group_key; + RD_Cfg *group_cfg; + CTRL_Entity *group_entity; + CTRL_Entity *callstack_thread; + U64 callstack_unwind_index; + U64 callstack_inline_depth; + RD_WatchCellList cells; +}; + typedef enum RD_WatchViewColumnKind { RD_WatchViewColumnKind_Expr, @@ -141,8 +154,8 @@ typedef enum RD_WatchViewRowKind } RD_WatchViewRowKind; -typedef struct RD_WatchViewPoint RD_WatchViewPoint; -struct RD_WatchViewPoint +typedef struct RD_WatchPt RD_WatchPt; +struct RD_WatchPt { EV_Key parent_key; EV_Key key; @@ -165,7 +178,7 @@ typedef struct RD_WatchViewTextEditState RD_WatchViewTextEditState; struct RD_WatchViewTextEditState { RD_WatchViewTextEditState *pt_hash_next; - RD_WatchViewPoint pt; + RD_WatchPt pt; TxtPt cursor; TxtPt mark; U8 input_buffer[1024]; @@ -187,10 +200,10 @@ struct RD_WatchViewState U64 column_count; // rjf; table cursor state - RD_WatchViewPoint cursor; - RD_WatchViewPoint mark; - RD_WatchViewPoint next_cursor; - RD_WatchViewPoint next_mark; + RD_WatchPt cursor; + RD_WatchPt mark; + RD_WatchPt next_cursor; + RD_WatchPt next_mark; // rjf: text input state Arena *text_edit_arena; @@ -218,9 +231,12 @@ internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellLi internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index); //- rjf: watch view points <-> table coordinates -internal B32 rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b); -internal RD_WatchViewPoint rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); -internal Vec2S64 rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt); +internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b); +internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); +internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt); + +//- rjf: row -> info +internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); //- rjf: row -> context info internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); @@ -236,7 +252,7 @@ internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, R internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: table coordinates -> text edit state -internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt); +internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); //- rjf: watch view column state mutation internal RD_WatchViewColumn *rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params); From 394d35287a2b1a51e75a4bea8e20d7020df98208 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 Jan 2025 17:00:50 -0800 Subject: [PATCH 033/755] fix default lookup rule --- src/eval/eval_ir.c | 9 ++------- src/eval/eval_ir.h | 9 +++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 67abc754..53211550 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -76,13 +76,8 @@ e_select_ir_ctx(E_IRCtx *ctx) internal E_LookupRule * e_lookup_rule_from_string(String8 string) { - local_persist read_only E_LookupRule e_lookup_rule__default = - { - str8_lit_comp("default"), - E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_FUNCTION_NAME(default), - }; E_LookupRule *result = &e_lookup_rule__default; + if(e_ir_ctx->lookup_rule_map != 0 && e_ir_ctx->lookup_rule_map->slots_count != 0) { U64 hash = e_hash_from_string(5381, string); U64 slot_idx = hash%e_ir_ctx->lookup_rule_map->slots_count; @@ -142,7 +137,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) E_LOOKUP_FUNCTION_DEF(default) { - E_Lookup lookup = {0}; + E_Lookup lookup = {{&e_irnode_nil}}; switch(kind) { default:{}break; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 0053ff76..7c747e5c 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -83,6 +83,9 @@ typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); #define E_LOOKUP_FUNCTION_DEF(name) internal E_LOOKUP_FUNCTION_SIG(E_LOOKUP_FUNCTION_NAME(name)) typedef E_LOOKUP_FUNCTION_SIG(E_LookupFunctionType); +E_LOOKUP_INFO_FUNCTION_DEF(default); +E_LOOKUP_FUNCTION_DEF(default); + typedef struct E_LookupRule E_LookupRule; struct E_LookupRule { @@ -125,6 +128,12 @@ struct E_IRCtx //////////////////////////////// //~ rjf: Globals +local_persist read_only E_LookupRule e_lookup_rule__default = +{ + str8_lit_comp("default"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_FUNCTION_NAME(default), +}; global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRCtx *e_ir_ctx = 0; From 92e68701d0dcc3b2088ca7d413b7547aa87d7645 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 Jan 2025 10:57:29 -0800 Subject: [PATCH 034/755] eval: lookup rule map building; eval: use general 'set' type-kind to specify custom lookup rule; watch: new table <-> stable-point mappings --- src/eval/eval_core.c | 12 +++++---- src/eval/eval_ir.c | 31 +++++++++++++++++++++- src/eval/eval_ir.h | 4 +++ src/raddbg/raddbg_core.c | 11 ++++---- src/raddbg/raddbg_views.c | 54 +++++++++++++++++++++++++++++++++++---- src/raddbg/raddbg_views.h | 1 + 6 files changed, 96 insertions(+), 17 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 0acb895e..ada7177d 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -9,14 +9,16 @@ //////////////////////////////// //~ rjf: Basic Helper Functions +#if !defined(XXH_IMPLEMENTATION) +# define XXH_IMPLEMENTATION +# define XXH_STATIC_LINKING_ONLY +# include "third_party/xxHash/xxhash.h" +#endif + internal U64 e_hash_from_string(U64 seed, String8 string) { - U64 result = seed; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } + U64 result = XXH3_64bits_withSeed(string.str, string.size, seed); return result; } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 53211550..4432f44c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -73,6 +73,26 @@ e_select_ir_ctx(E_IRCtx *ctx) //////////////////////////////// //~ rjf: Lookups +internal E_LookupRuleMap +e_lookup_rule_map_make(Arena *arena, U64 slots_count) +{ + E_LookupRuleMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); + return map; +} + +internal void +e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) +{ + U64 hash = e_hash_from_string(5381, rule->name); + U64 slot_idx = hash%map->slots_count; + E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + MemoryCopyStruct(&n->v, rule); + n->v.name = push_str8_copy(arena, n->v.name); +} + internal E_LookupRule * e_lookup_rule_from_string(String8 string) { @@ -703,12 +723,21 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { + Temp scratch = scratch_begin(&arena, 1); E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_irtree.type_key); + String8 lookup_rule_name = expr->string; + if(lhs_type->kind == E_TypeKind_Set) + { + lookup_rule_name = lhs_type->name; + } E_Expr *rhs = lhs->next; - E_LookupRule *lookup_rule = e_lookup_rule_from_string(expr->string); + E_LookupRule *lookup_rule = e_lookup_rule_from_string(lookup_rule_name); E_LookupInfo lookup_info = lookup_rule->lookup_info(arena, lhs); E_Lookup lookup = lookup_rule->lookup(arena, expr->kind, lhs, rhs, lookup_info.user_data); result = lookup.irtree_and_type; + scratch_end(scratch); }break; //- rjf: dereference diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 7c747e5c..67af8a91 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -152,6 +152,10 @@ internal void e_select_ir_ctx(E_IRCtx *ctx); //////////////////////////////// //~ rjf: Lookups +internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); +internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); +#define e_lookup_rule_map_insert_new(arena, map, name_, lookup_info_, lookup_) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), .lookup_info = (lookup_info_), .lookup = (lookup_)}) + internal E_LookupRule *e_lookup_rule_from_string(String8 string); E_LOOKUP_INFO_FUNCTION_DEF(default); E_LOOKUP_FUNCTION_DEF(default); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 45669943..b9c0df76 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13086,6 +13086,8 @@ rd_frame(void) 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); + ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); + ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); //- rjf: add macros for collections { @@ -13228,6 +13230,7 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x%I64x", (U64)cfg, cfg->gen), expr); } } + //- rjf: add macros for all evallable control entities { CTRL_EntityKind evallable_kinds[] = @@ -13282,12 +13285,7 @@ rd_frame(void) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = {0}; - { - E_TypeKey element_type_key = evallable_cfg_types[cfg_name_idx]; - RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); - collection_type_key = e_type_key_cons_array(e_type_key_cons_space_ptr(element_type_key), cfgs.count); - } + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); E_Space space = e_space_make(RD_EvalSpaceKind_MetaCollection); space.u64s[0] = cfg_name_idx; @@ -13295,6 +13293,7 @@ rd_frame(void) expr->mode = E_Mode_Offset; expr->type_key = collection_type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + // TODO(rjf): e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, ); } //- rjf: add macro for output log diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index fc6f4d80..f5c3669e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -796,6 +796,15 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: cell list building +internal U64 +rd_id_from_watch_cell(RD_WatchCell *cell) +{ + U64 result = 5381; + result = e_hash_from_string(result, str8_struct(&cell->kind)); + result = e_hash_from_string(result, cell->member); + return result; +} + internal RD_WatchCell * rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list) { @@ -846,9 +855,25 @@ internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) { RD_WatchPt pt = zero_struct; - pt.cell_id = (U64)tbl.x; - pt.key = ev_key_from_num(block_ranges, (U64)tbl.y); - pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key; + { + Temp scratch = scratch_begin(0, 0); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_filter(), block_ranges, (U64)tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + { + S64 x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, x += 1) + { + if(x == tbl.x) + { + pt.cell_id = rd_id_from_watch_cell(cell); + break; + } + } + } + pt.key = row->key; + pt.parent_key = row->block->key; + scratch_end(scratch); + } return pt; } @@ -856,8 +881,27 @@ internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Vec2S64 tbl = {0}; - tbl.x = (S64)pt.cell_id; - tbl.y = (S64)ev_num_from_key(block_ranges, pt.key); + { + Temp scratch = scratch_begin(0, 0); + U64 num = ev_num_from_key(block_ranges, pt.key); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_filter(), block_ranges, num); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + tbl.x = 0; + { + S64 x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, x += 1) + { + U64 cell_id = rd_id_from_watch_cell(cell); + if(cell_id == pt.cell_id) + { + tbl.x = x; + break; + } + } + } + tbl.y = (S64)num; + scratch_end(scratch); + } return tbl; } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 4d0aa592..04488d9b 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -223,6 +223,7 @@ internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewStat //~ rjf: Watch View Functions //- rjf: cell list building +internal U64 rd_id_from_watch_cell(RD_WatchCell *cell); internal RD_WatchCell *rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list); internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params); #define rd_watch_cell_list_push_new(arena, list, kind_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), __VA_ARGS__}) From 12784d9ae9f9b81840ffaf5870f92ed47c3c74f2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 Jan 2025 14:11:01 -0800 Subject: [PATCH 035/755] partial transition to new flexible watch table structure; more work on 'set' types; checkpoint before replacement of old view-rule-hacks with proper-eval-system support for sets/collections/etc. --- .../eval_visualization_builtin_view_rules.c | 10 + .../eval_visualization_core.c | 1 + src/raddbg/generated/raddbg.meta.c | 24 +- src/raddbg/generated/raddbg.meta.h | 20 +- src/raddbg/raddbg.mdesk | 15 +- src/raddbg/raddbg_core.c | 68 ++- src/raddbg/raddbg_core.h | 3 + src/raddbg/raddbg_main.c | 8 + src/raddbg/raddbg_views.c | 566 +++++------------- src/raddbg/raddbg_views.h | 46 +- 10 files changed, 290 insertions(+), 471 deletions(-) diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index ab4628dd..15505e4d 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -104,6 +104,7 @@ struct EV_DefaultExpandAccel { E_MemberArray members; E_EnumValArray enum_vals; + void *lookup_accel; U64 array_count; B32 array_need_extra_deref; B32 is_ptr2ptr; @@ -174,6 +175,15 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default) accel->is_ptr2ptr = 1; } + //////////////////////////// + //- rjf: sets -> expansions generate rows for all possible lookups + // + else if(type_kind == E_TypeKind_Set) + { + E_Type *type = e_type_from_key(scratch.arena, type_key); + //E_LookupRule *rule = e_lookup_rule_from_string(type->name); + } + //////////////////////////// //- rjf: package result // diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5797a435..7e63d063 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -115,6 +115,7 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) kind == E_TypeKind_Union || kind == E_TypeKind_Class || kind == E_TypeKind_Array || + kind == E_TypeKind_Set || (kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 5a97c7f0..5151fb98 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -73,7 +73,7 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, }; -RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = +RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[7] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n"), str8_lit_comp("")}, {str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n"), str8_lit_comp("launch_and_run,launch_and_init,select_cfg,remove_cfg")}, @@ -81,6 +81,7 @@ RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = {str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, +{str8_lit_comp("watch"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n}\n"), str8_lit_comp("remove_cfg")}, }; String8 d_entity_kind_display_string_table[27] = @@ -710,9 +711,8 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -String8 rd_collection_name_table[13] = +String8 rd_collection_name_table[12] = { -str8_lit_comp("watches"), str8_lit_comp("machines"), str8_lit_comp("processes"), str8_lit_comp("threads"), @@ -727,9 +727,8 @@ str8_lit_comp("types"), str8_lit_comp("procedures"), }; -RD_EntityKind rd_collection_entity_kind_table[13] = +RD_EntityKind rd_collection_entity_kind_table[12] = { -RD_EntityKind_Watch, RD_EntityKind_Nil, RD_EntityKind_Nil, RD_EntityKind_Nil, @@ -744,9 +743,8 @@ RD_EntityKind_Nil, RD_EntityKind_Nil, }; -CTRL_EntityKind rd_collection_ctrl_entity_kind_table[13] = +CTRL_EntityKind rd_collection_ctrl_entity_kind_table[12] = { -CTRL_EntityKind_Null, CTRL_EntityKind_Machine, CTRL_EntityKind_Process, CTRL_EntityKind_Thread, @@ -761,9 +759,8 @@ CTRL_EntityKind_Null, CTRL_EntityKind_Null, }; -EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[13] = +EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[12] = { -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(watches), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(threads), @@ -778,9 +775,8 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[13] = +EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[12] = { -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(watches), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(threads), @@ -795,9 +791,8 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[13] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[12] = { -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(threads), @@ -812,9 +807,8 @@ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(types), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[13] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[12] = { -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(machines), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(processes), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(threads), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6d677a10..a2815f31 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -651,7 +651,6 @@ RD_ViewRuleUIFunctionType *ui; .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watches); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads); @@ -664,7 +663,6 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(globals); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watches); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads); @@ -677,7 +675,6 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(globals); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads); @@ -688,7 +685,6 @@ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(globals); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads); @@ -738,7 +734,7 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[41]; -extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6]; +extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[7]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; @@ -749,13 +745,13 @@ extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern String8 rd_collection_name_table[13]; -extern RD_EntityKind rd_collection_entity_kind_table[13]; -extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[13]; -extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[13]; -extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[13]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[13]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[13]; +extern String8 rd_collection_name_table[12]; +extern RD_EntityKind rd_collection_entity_kind_table[12]; +extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[12]; +extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[12]; +extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[12]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[12]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[12]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 05128c8d..5ae3e266 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -201,6 +201,19 @@ RD_VocabularyMap: ```x:{'source':code_string, 'dest':code_string}```, `remove_cfg`, } + + //- rjf: watches + { + watch, + ```x: + { + 'expression': code_string, + 'view_rule': code_string, + } + ```, + `remove_cfg`, + } + } @struct RD_CfgNameSchemaPair: @@ -993,7 +1006,7 @@ RD_IconTable: RD_CollectionTable: { //- rjf: frontend entity groups - {watches Watch Null x} + //{watches Watch Null x} //{targets Target Null x} //{breakpoints Breakpoint Null x} //{watch_pins WatchPin Null x} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b9c0df76..47019822 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9161,6 +9161,65 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures) {return rd_ev_ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_Procedures); } EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_Procedures); } +E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, lhs_type->name); + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list); + result.user_data = cfgs; + result.idxed_expr_count = cfgs_list.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_FUNCTION_DEF(top_level_cfg) +{ + E_Lookup result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + E_Space cfg_space = rd_eval_space_from_cfg(cfg); + String8 cfg_name = cfg->string; + E_TypeKey cfg_type_key = {0}; + { + U64 hash = d_hash_from_string(cfg_name); + U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; + for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->string, cfg_name, 0)) + { + cfg_type_key = n->key; + break; + } + } + } + result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = cfg_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind) { @@ -13104,6 +13163,7 @@ rd_frame(void) //- rjf: choose set of evallable config names String8 evallable_cfg_names[] = { + str8_lit("watch"), str8_lit("breakpoint"), str8_lit("watch_pin"), str8_lit("target"), @@ -13208,10 +13268,10 @@ rd_frame(void) for EachElement(idx, evallable_cfg_names) { String8 name = evallable_cfg_names[idx]; - RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + RD_CfgArray cfgs = rd_state->eval_collection_cfgs[idx]; + for EachIndex(cfg_idx, cfgs.count) { - RD_Cfg *cfg = n->v; + RD_Cfg *cfg = cfgs.v[cfg_idx]; String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; E_Space space = rd_eval_space_from_cfg(cfg); @@ -13293,7 +13353,7 @@ rd_frame(void) expr->mode = E_Mode_Offset; expr->type_key = collection_type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - // TODO(rjf): e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, ); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), E_LOOKUP_FUNCTION_NAME(top_level_cfg)); } //- rjf: add macro for output log diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 765220c3..c9e1ceb6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1333,6 +1333,9 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization +E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg); +E_LOOKUP_FUNCTION_DEF(top_level_cfg); + internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind); internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top); internal U64 rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 35bf5d39..bc13537f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -596,6 +596,14 @@ entry_point(CmdLine *cmd_line) rd_init(cmd_line); } + //- TODO(rjf): @cfg set up debugging config state + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, str8_lit("basics")); + } + //- rjf: setup initial target from command line args { String8List args = cmd_line->inputs; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f5c3669e..4c24e936 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -801,7 +801,7 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); - result = e_hash_from_string(result, cell->member); + result = e_hash_from_string(result, cell->string); return result; } @@ -910,7 +910,13 @@ rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { - RD_WatchRowInfo info = {0}; + RD_WatchRowInfo info = + { + .module = &ctrl_entity_nil, + .group_cfg = &rd_nil_cfg, + .group_entity = &ctrl_entity_nil, + .callstack_thread = &ctrl_entity_nil, + }; { Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = di_scope_open(); @@ -924,14 +930,36 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); + // rjf: determine row's module + CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + if(info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + switch(row_ctrl_entity->kind) + { + default: + case CTRL_EntityKind_Process: + if(info.eval.mode == E_Mode_Offset) + { + info.module = ctrl_module_from_process_vaddr(row_ctrl_entity, info.eval.value.u64); + }break; + case CTRL_EntityKind_Thread: + if(info.eval.mode == E_Mode_Value) + { + CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); + info.module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); + }break; + } + } + // rjf: determine cfg group // rjf: fill row's cells - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Value, .pct = 0.30f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Type, .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewRule, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("expression"), .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("view_rule"), .pct = 0.30f); di_scope_close(di_scope); scratch_end(scratch); @@ -1058,53 +1086,14 @@ rd_watch_view_row_info_from_row(EV_Row *row) return info; } -//- rjf: watch view flags & row info -> row kind +//- rjf: row * cell -> string -internal RD_WatchViewRowKind -rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, RD_WatchViewRowInfo *info) +internal RD_WatchRowCellInfo +rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { - Temp scratch = scratch_begin(0, 0); - 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 || !(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; - } - RD_WatchViewRowKind row_kind = RD_WatchViewRowKind_Normal; - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - E_TypeKey row_type_key = row_eval.type_key; - E_TypeKind row_type_kind = e_type_kind_from_key(row_type_key); - if(ev_key_match(row->block->key, ev_key_root())) - { - row_kind = RD_WatchViewRowKind_Header; - } - else if(ui_view_rule_info != &rd_nil_view_rule_info && ui_view_rule_info->ui != 0) - { - row_kind = RD_WatchViewRowKind_Canvas; - } - else if(flags & RD_WatchViewFlag_PrettyEntityRows && - ((row_eval.value.u64 == 0 && row_type_kind == E_TypeKind_Struct) || - info->collection_entity_kind != RD_EntityKind_Nil || - info->collection_ctrl_entity_kind != CTRL_EntityKind_Null)) - { - row_kind = RD_WatchViewRowKind_PrettyEntityControls; - } - scratch_end(scratch); - return row_kind; -} - -//- rjf: row info -> cell list - -internal RD_WatchCellList -rd_watch_cell_list_from_row_info(Arena *arena, EV_Row *row, RD_WatchViewRowInfo *info) -{ - RD_WatchCellList cell_list = {0}; - rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Expr, .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Value, .pct = 0.30f); - rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_Type, .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &cell_list, RD_WatchCellKind_ViewRule, .pct = 0.30f); - return cell_list; + RD_WatchRowCellInfo result = {0}; + result.string = row->string; + return result; } //- rjf: row/column -> strings @@ -1376,7 +1365,7 @@ rd_watch_view_init(RD_WatchViewState *ewv) } internal void -rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect) +rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -1393,10 +1382,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = 0; - if(flags & RD_WatchViewFlag_PrettyNameMembers) - { - string_flags |= EV_StringFlag_PrettyNames; - } #if 0 // TODO(rjf): @cfg RD_WatchViewRowCtrl row_ctrls_[] = { @@ -1541,30 +1526,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); - // rjf: compute row at initial selection point (or just cursor point) - mark_rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(mark_tbl.y, mark_tbl.y+1)); - // rjf: compute legal coordinate range, given selection-defining row - Rng1S64 cursor_x_range = r1s64(0, ewv->column_count-1); - if(mark_rows.first != 0) + Rng1S64 cursor_x_range = {0}; { - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(&mark_rows.first->row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, &mark_rows.first->row, &row_info); - if(row_kind == RD_WatchViewRowKind_PrettyEntityControls) - { - U64 row_ctrl_count = 0; -#if 0 // TODO(rjf): @cfg - for EachIndex(idx, row_ctrls_count) - { - if(row_ctrls[idx].entity_kind == row_info.collection_entity->kind && - row_ctrls[idx].ctrl_entity_kind == row_info.collection_ctrl_entity->kind) - { - row_ctrl_count += 1; - } - } -#endif - cursor_x_range = r1s64(1, 1+row_ctrl_count); - } + EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + cursor_x_range = r1s64(0, (S64)row_info.cells.count); } cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count-1)); @@ -1663,34 +1630,39 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; + B32 any_edits_started = 0; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - if(row_kind == RD_WatchViewRowKind_Normal) + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { - ewv->text_editing = 1; - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.can_edit) + { + any_edits_started = 1; + String8 string = cell_info.string; string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchPt pt = {row->block->key, row->key, x}; + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; U64 hash = ev_hash_from_key(pt.key); U64 slot_idx = hash%ewv->text_edit_state_slots_count; RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); - SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); - edit_state->pt = pt; - edit_state->cursor = txt_pt(1, string.size+1); - edit_state->mark = txt_pt(1, 1); - edit_state->input_size = string.size; + edit_state->pt = pt; + edit_state->cursor = txt_pt(1, string.size+1); + edit_state->mark = txt_pt(1, 1); + edit_state->input_size = string.size; MemoryCopy(edit_state->input_buffer, string.str, string.size); edit_state->initial_size = string.size; MemoryCopy(edit_state->initial_buffer, string.str, string.size); } } } + ewv->text_editing = any_edits_started; } ////////////////////////// @@ -1706,12 +1678,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { // rjf: unpack row info EV_Row *row = &row_node->row; - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); // rjf: loop through X selections and perform operations for each for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { +#if 0 // TODO(rjf): @cfg //- rjf: determine operation for this cell typedef enum OpKind { @@ -1750,6 +1722,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); }break; } +#endif } } } @@ -1775,11 +1748,15 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { - RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, v2s64(x, y)); + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); String8 string = str8(edit_state->input_buffer, edit_state->input_size); UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); @@ -1826,6 +1803,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo edit_state->mark = op.mark; // rjf: commit edited cell string +#if 0 // TODO(rjf): @cfg Vec2S64 tbl = v2s64(x, y); RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); { @@ -1910,6 +1888,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo }break; } } +#endif } } } @@ -1975,13 +1954,16 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { - Vec2S64 tbl = v2s64(x, y); - RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; +#if 0 // TODO(rjf): @cfg if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && row_info.collection_entity_kind != RD_EntityKind_Nil) { @@ -2024,6 +2006,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); rd_commit_eval_value_string(dst_eval, str8_zero(), 0); } +#endif } } for(RD_EntityNode *n = entities_to_remove.first; n != 0; n = n->next) @@ -2286,7 +2269,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); scroll_list_params.dim_px = dim_2f32(rect); scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(ewv->column_count-1, block_tree.total_item_count)); - scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!(flags & RD_WatchViewFlag_NoHeader)); + scroll_list_params.item_range = r1s64(0, block_tree.total_row_count); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 0; scroll_list_params.row_blocks = row_blocks; } @@ -2312,7 +2295,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo // EV_WindowedRowList rows = {0}; { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min + !!(flags & RD_WatchViewFlag_NoHeader), visible_row_rng.max + 1 + !!(flags & RD_WatchViewFlag_NoHeader))); + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min, visible_row_rng.max + 1)); } //////////////////////////// @@ -2323,14 +2306,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo U64 global_row_idx = rows.count_before_semantic; for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) { - //////////////////////// - //- rjf: skip header - // - if(global_row_idx == 0 && flags & RD_WatchViewFlag_NoHeader) - { - continue; - } - //////////////////////// //- rjf: unpack row info // @@ -2338,45 +2313,15 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo EV_Row *row = &row_node->row; U64 row_hash = ev_hash_from_key(row->key); U64 row_depth = ev_depth_from_block(row->block); + B32 row_selected = (selection_tbl.min.y <= global_row_idx && global_row_idx <= selection_tbl.max.y); + B32 row_expanded = ev_expansion_from_key(eval_view, row->key); + B32 next_row_expanded = row_expanded; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + B32 row_is_expandable = ev_row_is_expandable(row); if(row_depth > 0) { row_depth -= 1; } - B32 row_selected = (selection_tbl.min.y <= global_row_idx && global_row_idx <= selection_tbl.max.y); - B32 row_expanded = ev_expansion_from_key(eval_view, row->key); - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); - if(row_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - switch(row_ctrl_entity->kind) - { - default: - case CTRL_EntityKind_Process: - if(row_eval.mode == E_Mode_Offset) - { - row_module = ctrl_module_from_process_vaddr(row_ctrl_entity, row_eval.value.u64); - }break; - case CTRL_EntityKind_Thread: - if(row_eval.mode == E_Mode_Value) - { - CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); - row_module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); - }break; - } - } - E_Type *row_type = e_type_from_key(scratch.arena, row_eval.type_key); - B32 row_is_expandable = ev_row_is_expandable(row); - 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 || !(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; - } - RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchRowInfo row_info_NEW = rd_watch_row_info_from_row(scratch.arena, row); ProfEnd(); //////////////////////// @@ -2385,17 +2330,17 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ProfBegin("determine if row's data is fresh and/or bad"); B32 row_is_fresh = 0; B32 row_is_bad = 0; - switch(row_eval.mode) + switch(row_info.eval.mode) { default:{}break; case E_Mode_Offset: { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - if(row_eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info.eval.space); + if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) { - U64 size = e_type_byte_size_from_key(row_eval.type_key); + U64 size = e_type_byte_size_from_key(row_info.eval.type_key); size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_eval.value.u64, row_eval.value.u64+size); + Rng1U64 vaddr_rng = r1u64(row_info.eval.value.u64, row_info.eval.value.u64+size); CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { @@ -2457,15 +2402,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ////////////////////// //- rjf: build row contents // - RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) + RD_RegsScope(.module = row_info.module->handle) UI_Parent(row_box) { //////////////////// //- rjf: draw start of cache lines in expansions // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) { - U64 row_offset = row_eval.value.u64; - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + U64 row_offset = row_info.eval.value.u64; + if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && row_offset%64 == 0 && row_depth > 0) { ui_set_next_fixed_x(0); @@ -2479,15 +2423,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////// //- rjf: draw mid-row cache line boundaries in expansions // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) { - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_eval.value.u64%64 != 0 && + if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && + row_info.eval.value.u64%64 != 0 && row_depth > 0 && !row_expanded) { - U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); - if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) + U64 next_off = (row_info.eval.value.u64 + e_type_byte_size_from_key(row_info.eval.type_key)); + if(next_off%64 != 0 && row_info.eval.value.u64/64 < next_off/64) { ui_set_next_fixed_x(0); ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); @@ -2503,224 +2446,35 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////// //- rjf: build all cells // - for(RD_WatchCell *cell = row_info_NEW.cells.first; cell != 0; cell = cell->next) + S64 cell_x = 0; + F32 cell_x_px = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { -#if 0 // TODO(rjf): @cfg //- rjf: unpack cell info - RD_WatchPt cell_pt = {x, row->block->key, row->key}; + U64 cell_id = rd_id_from_watch_cell(cell); + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); - String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - - //- rjf: unpack column-kind-specific info - ProfBegin("unpack column-kind-specific info"); - E_Eval cell_eval = row_eval; - E_Type *cell_type = row_type; - B32 cell_can_edit = 0; - FuzzyMatchRangeList cell_matches = {0}; - String8 cell_inheritance_string = {0}; - String8 cell_error_string = {0}; - String8 cell_error_tooltip_string = {0}; - RD_ListerFlags cell_autocomp_flags = 0; - RD_ViewRuleUIFunctionType *cell_ui_hook = 0; - MD_Node *cell_ui_params = &md_nil_node; - Vec4F32 cell_base_color = ui_top_palette()->text; - RD_IconKind cell_icon = RD_IconKind_Null; - String8 cell_ghost_text = {0}; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); - if(filter.size != 0) - { - cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); - } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(row->member != 0 && row->member->inheritance_key_chain.first != 0) - { - String8List inheritance_chain_type_names = {0}; - for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) - { - String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); - inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); - str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); - } - if(inheritance_chain_type_names.node_count != 0) - { - StringJoin join = {0}; - join.sep = str8_lit("::"); - String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); - cell_inheritance_string = inheritance_type; - } - } - }break; - case RD_WatchViewColumnKind_Value: - { - }goto value_cell; - case RD_WatchViewColumnKind_Member: - { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - cell_eval = e_eval_from_expr(scratch.arena, expr); - cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); - }goto value_cell; - value_cell:; - { - E_MsgList msgs = cell_eval.msgs; - if(row_depth == 0 && row->string.size != 0) - { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); - e_msg_list_concat_in_place(&parse.msgs, &msgs); - msgs = parse.msgs; - } - if(msgs.max_kind > E_MsgKind_Null) - { - String8List strings = {0}; - for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) - { - str8_list_push(scratch.arena, &strings, msg->text); - } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - cell_error_string = str8_list_join(scratch.arena, &strings, &join); - } - if(row_is_bad) - { - cell_error_tooltip_string = str8_lit("Could not read memory successfully."); - } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(cell_type->flags & E_TypeFlag_IsPathText) - { - cell_autocomp_flags = RD_ListerFlag_Files; - } - if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) - { - cell_ui_hook = ui_view_rule_info->ui; - cell_ui_params = ui_view_rule_params_root; - } - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); - }break; - case RD_WatchViewColumnKind_Type: - { - cell_can_edit = 0; - }break; - case RD_WatchViewColumnKind_ViewRule: - { - cell_can_edit = 1; - cell_autocomp_flags = RD_ListerFlag_ViewRules; - if(cell_pre_edit_string.size == 0) - { - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); - String8List strings = {0}; - for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &strings, n->v.root->string); - } - cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); - } - }break; - case RD_WatchViewColumnKind_CallStackFrameSelection: - { - if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && - row_info.callstack_unwind_index == rd_regs()->unwind_count && - row_info.callstack_inline_depth == rd_regs()->inline_depth) - { - cell_icon = RD_IconKind_RightArrow; - cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); - } - }break; - } - ProfEnd(); - - //- rjf: apply column-specified view rules - ProfBegin("apply column-specified view rules"); - if(col->view_rule_size != 0) - { - String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - } - ProfEnd(); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); //- rjf: determine cell's palette ProfBegin("determine cell's palette"); UI_BoxFlags cell_flags = 0; UI_Palette *palette = ui_top_palette(); { - if(cell_error_tooltip_string.size != 0 || - cell_error_string.size != 0) + if(cell_info.is_errored) { palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); cell_flags |= UI_BoxFlag_DrawBackground; } - else if(cell_inheritance_string.size != 0) + else if(cell_info.inheritance_tooltip.size != 0) { palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); cell_flags |= UI_BoxFlag_DrawBackground; } - else - { - palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); - } } ProfEnd(); - //- rjf: determine if cell needs code styling - B32 cell_is_code = !col->is_non_code; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_is_code = 1; - if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) - { - cell_is_code = 0; - } - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - { - if(cell_type->flags & E_TypeFlag_IsCodeText) - { - cell_is_code = 1; - } - else if(cell_type->flags & E_TypeFlag_IsPathText || - cell_type->flags & E_TypeFlag_IsPlainText) - { - cell_is_code = 0; - } - }break; - } - //- rjf: build cell UI_Signal sig = {0}; ProfScope("build cell") @@ -2728,41 +2482,30 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo UI_TableCell UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) + RD_Font(RD_FontSlot_Code) UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) { ui_set_next_flags(ui_top_flags() | cell_flags); // rjf: cell has errors? -> build error box - if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) + if(cell_info.is_errored) RD_Font(RD_FontSlot_Main) { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); sig = ui_signal_from_box(box); UI_Parent(box) UI_Flags(0) { - rd_error_label(cell_error_string); + rd_error_label(cell_info.string); } } // rjf: cell has hook? -> build ui by calling hook - else if(cell_ui_hook != 0) + else if(cell_info.ui != 0) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); UI_Parent(box) { String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); - } - sig = ui_signal_from_box(box); - } - - // rjf: cell has icon? build icon - else if(cell_icon != RD_IconKind_Null) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); - UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[cell_icon]); + cell_info.ui(row_expr, cell_info.ui_params, r2f32p(cell_x_px, 0, cell_x_px + cell->pct*dim_2f32(rect).x, row_height_px)); } sig = ui_signal_from_box(box); } @@ -2770,18 +2513,18 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo // rjf: build cell line edit else { - sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| + sig = rd_line_editf((RD_LineEditFlag_CodeContents| RD_LineEditFlag_NoBackground| RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_DisableEdit*(!cell_can_edit)| - RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && cell == row_cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && cell == row_cells.first)| - RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && cell == row_cells.first)), - x == 0 ? row_depth : 0, - &cell_matches, + RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)), + cell_x == 0 ? row_depth : 0, + 0, &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_pre_edit_string, - "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); + cell_info.string, + "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); +#if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) @@ -2793,6 +2536,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo .cursor = cell_edit_state->cursor, .lister_flags = cell_autocomp_flags); } +#endif } } @@ -2819,6 +2563,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo .inline_depth = row_info.callstack_inline_depth); } +#if 0 // TODO(rjf): @cfg // rjf: can edit? -> begin editing else if(cell_can_edit) { @@ -2854,27 +2599,28 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo .cursor = pt); } } +#endif } // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip + if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip { UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) { ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_info.inheritance_tooltip); } } // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip + if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); } } //- rjf: bump x pixel coordinate - x_px += col->pct*dim_2f32(rect).x; + cell_x_px += cell->pct*dim_2f32(rect).x; //- rjf: [DEV] hovering -> watch key tooltips if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) @@ -3030,7 +2776,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } } } -#endif } } @@ -4281,8 +4026,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(targets) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:targets"), str8_lit("only: label exe args working_directory entry_point stdout_path stderr_path stdin_path debug_subprocesses b32 str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:targets"), str8_lit("only: label exe args working_directory entry_point stdout_path stderr_path stdin_path debug_subprocesses b32 str"), 1, 10, rect); ProfEnd(); } @@ -4299,8 +4043,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:file_path_maps"), str8_lit("only: source_path destination_path str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:file_path_maps"), str8_lit("only: source_path destination_path str"), 1, 10, rect); ProfEnd(); } @@ -4317,8 +4060,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:auto_view_rules"), str8_lit("only: type view_rule str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:auto_view_rules"), str8_lit("only: type view_rule str"), 1, 10, rect); ProfEnd(); } @@ -4335,8 +4077,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:breakpoints"), str8_lit("only: label condition str hit_count source_location address_location function_location"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:breakpoints"), str8_lit("only: label condition str hit_count source_location address_location function_location"), 0, 10, rect); ProfEnd(); } @@ -4353,8 +4094,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:watch_pins"), str8_lit("only: label source_location address_location str"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:watch_pins"), str8_lit("only: label source_location address_location str"), 0, 10, rect); ProfEnd(); } @@ -4371,8 +4111,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(scheduler) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:machines"), str8_lit("only: label str id callstack v count vaddr inline_depth"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:machines"), str8_lit("only: label str id callstack v count vaddr inline_depth"), 0, 10, rect); ProfEnd(); } @@ -4391,7 +4130,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.20f, .string = str8_lit("vaddr"), .display_string = str8_lit("Address"), .view_rule = str8_lit("cast:U64")); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .string = str8_lit("module.str"), .display_string = str8_lit("Module"), .dequote_string = 1, .is_non_code = 1); } - rd_watch_view_build(wv, 0, str8_lit("thread:current_thread.callstack.v"), str8_lit("array:'thread:current_thread.callstack.count', hex"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("thread:current_thread.callstack.v"), str8_lit("array:'thread:current_thread.callstack.count', hex"), 0, 10, rect); ProfEnd(); } @@ -4408,8 +4147,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(modules) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_PrettyNameMembers|RD_WatchViewFlag_PrettyEntityRows|RD_WatchViewFlag_DisableCacheLines, - str8_lit("collection:modules"), str8_lit("only: exe dbg str vaddr_range min max"), 0, 16, rect); + rd_watch_view_build(wv, str8_lit("collection:modules"), str8_lit("only: exe dbg str vaddr_range min max"), 0, 16, rect); ProfEnd(); } @@ -4428,7 +4166,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:watches"), str8_lit(""), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:watches"), str8_lit(""), 1, 10, rect); ProfEnd(); } @@ -4447,7 +4185,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(locals) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:locals"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:locals"), str8_lit(""), 0, 10, rect); ProfEnd(); } @@ -4466,7 +4204,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(registers) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:registers"), str8_lit("hex"), 0, 16, rect); + rd_watch_view_build(wv, str8_lit("collection:registers"), str8_lit("hex"), 0, 16, rect); ProfEnd(); } @@ -4485,7 +4223,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(globals) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:globals"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:globals"), str8_lit(""), 0, 10, rect); ProfEnd(); } @@ -4504,7 +4242,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(thread_locals) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:thread_locals"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:thread_locals"), str8_lit(""), 0, 10, rect); ProfEnd(); } @@ -4523,7 +4261,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(types) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, 0, str8_lit("collection:types"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:types"), str8_lit(""), 0, 10, rect); ProfEnd(); } @@ -4541,7 +4279,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(procedures) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.6f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.2f); } - rd_watch_view_build(wv, 0, str8_lit("collection:procedures"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:procedures"), str8_lit(""), 0, 10, rect); ProfEnd(); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 04488d9b..42d21123 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -41,25 +41,11 @@ struct RD_CodeViewBuildResult //////////////////////////////// //~ rjf: Watch View Types -typedef U32 RD_WatchViewFlags; -enum -{ - RD_WatchViewFlag_NoHeader = (1<<0), - RD_WatchViewFlag_PrettyNameMembers = (1<<1), - RD_WatchViewFlag_PrettyEntityRows = (1<<2), - RD_WatchViewFlag_DisableCacheLines = (1<<3), -}; - typedef enum RD_WatchCellKind { - RD_WatchCellKind_Expr, - RD_WatchCellKind_Value, - RD_WatchCellKind_Type, - RD_WatchCellKind_ViewRule, - RD_WatchCellKind_Member, - RD_WatchCellKind_CallStackFrame, - RD_WatchCellKind_CallStackFrameSelection, - RD_WatchCellKind_Module, + RD_WatchCellKind_String, // plain text + RD_WatchCellKind_Expr, // strings for forming expression, under some key; `expression` for expression, `view_rule` for view rule + RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)~ } RD_WatchCellKind; @@ -68,9 +54,8 @@ struct RD_WatchCell { RD_WatchCell *next; RD_WatchCellKind kind; + String8 string; F32 pct; - String8 member; - String8 view_rule; }; typedef struct RD_WatchCellList RD_WatchCellList; @@ -85,6 +70,7 @@ typedef struct RD_WatchRowInfo RD_WatchRowInfo; struct RD_WatchRowInfo { E_Eval eval; + CTRL_Entity *module; String8 group_key; RD_Cfg *group_cfg; CTRL_Entity *group_entity; @@ -94,6 +80,19 @@ struct RD_WatchRowInfo RD_WatchCellList cells; }; +typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; +struct RD_WatchRowCellInfo +{ + E_Eval eval; + String8 string; + B32 can_edit; + B32 is_errored; + String8 error_tooltip; + String8 inheritance_tooltip; + RD_ViewRuleUIFunctionType *ui; + MD_Node *ui_params; +}; + typedef enum RD_WatchViewColumnKind { RD_WatchViewColumnKind_Expr, @@ -242,11 +241,8 @@ internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); //- rjf: row -> context info internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); -//- rjf: watch view flags & row & row info -> row kind -internal RD_WatchViewRowKind rd_watch_view_row_kind_from_flags_row_info(RD_WatchViewFlags flags, EV_Row *row, RD_WatchViewRowInfo *info); - -//- rjf: row info -> cell list -internal RD_WatchCellList rd_watch_cell_list_from_row_info(Arena *arena, EV_Row *row, RD_WatchViewRowInfo *info); +//- rjf: row * cell -> info +internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: row/column -> exprs / strings internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col); @@ -262,6 +258,6 @@ internal void rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewCo //- rjf: watch view main hooks internal void rd_watch_view_init(RD_WatchViewState *ewv); -internal void rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect); +internal void rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect); #endif // RADDBG_VIEWS_H From 68966ba55fd5fd39f9c5538724c856e23f515e6e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 Jan 2025 15:43:41 -0800 Subject: [PATCH 036/755] eval: more progress on 'sets', plug primary watch group into it; rd: more progress on watch ui based on new sets/lookups --- .../eval_visualization_builtin_view_rules.c | 26 ++++- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 14 +-- src/raddbg/raddbg_core.c | 96 +++++++++++++--- src/raddbg/raddbg_core.h | 2 + src/raddbg/raddbg_main.c | 8 -- src/raddbg/raddbg_views.c | 107 +++++++++++++++++- 8 files changed, 214 insertions(+), 49 deletions(-) diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index 15505e4d..250ecd81 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -104,7 +104,8 @@ struct EV_DefaultExpandAccel { E_MemberArray members; E_EnumValArray enum_vals; - void *lookup_accel; + E_LookupRule *lookup_rule; + void *lookup_user_data; U64 array_count; B32 array_need_extra_deref; B32 is_ptr2ptr; @@ -181,7 +182,11 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default) else if(type_kind == E_TypeKind_Set) { E_Type *type = e_type_from_key(scratch.arena, type_key); - //E_LookupRule *rule = e_lookup_rule_from_string(type->name); + E_LookupRule *rule = e_lookup_rule_from_string(type->name); + E_LookupInfo lookup_info = rule->lookup_info(arena, expr); + total_row_count = Max(lookup_info.named_expr_count, lookup_info.idxed_expr_count); + accel->lookup_rule = rule; + accel->lookup_user_data = lookup_info.user_data; } //////////////////////////// @@ -273,6 +278,23 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) result.row_members[0] = &e_member_nil; } + //////////////////////////// + //- rjf: fill with lookups + // + else if(accel->lookup_rule != 0) + { + result.row_exprs_count = needed_row_count; + result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); + result.row_strings = push_array(arena, String8, result.row_exprs_count); + result.row_view_rules = push_array(arena, String8, result.row_exprs_count); + result.row_members = push_array(arena, E_Member *, result.row_exprs_count); + for EachIndex(row_expr_idx, result.row_exprs_count) + { + result.row_exprs[row_expr_idx] = e_expr_ref_array_index(arena, expr, idx_range.min + row_expr_idx); + result.row_members[row_expr_idx] = &e_member_nil; + } + } + return result; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 5151fb98..04e89d6d 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -73,7 +73,7 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, }; -RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[7] = +RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n"), str8_lit_comp("")}, {str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n"), str8_lit_comp("launch_and_run,launch_and_init,select_cfg,remove_cfg")}, @@ -81,7 +81,6 @@ RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[7] = {str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, -{str8_lit_comp("watch"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n}\n"), str8_lit_comp("remove_cfg")}, }; String8 d_entity_kind_display_string_table[27] = @@ -500,7 +499,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, }; -RD_StringBindingPair rd_default_binding_table[110] = +RD_StringBindingPair rd_default_binding_table[111] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -612,6 +611,7 @@ RD_StringBindingPair rd_default_binding_table[110] = {str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("open_lister"), {OS_Key_F1, 0 }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("toggle_dev_menu"), {OS_Key_D, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, }; String8 rd_binding_version_remap_old_name_table[8] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index a2815f31..71b1ae02 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -734,14 +734,14 @@ extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[41]; -extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[7]; +extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; extern Rng1U64 rd_reg_slot_range_table[40]; -extern RD_StringBindingPair rd_default_binding_table[110]; +extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5ae3e266..2d5b5c90 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -201,19 +201,6 @@ RD_VocabularyMap: ```x:{'source':code_string, 'dest':code_string}```, `remove_cfg`, } - - //- rjf: watches - { - watch, - ```x: - { - 'expression': code_string, - 'view_rule': code_string, - } - ```, - `remove_cfg`, - } - } @struct RD_CfgNameSchemaPair: @@ -877,6 +864,7 @@ RD_DefaultBindingTable: //- rjf: developer commands { "log_marker" M ctrl shift alt } + { "toggle_dev_menu" D ctrl shift alt } } @data(RD_StringBindingPair) rd_default_binding_table: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 47019822..b6392876 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9161,6 +9161,45 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures) {return rd_ev_ EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_Procedures); } EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_Procedures); } +E_LOOKUP_INFO_FUNCTION_DEF(watch_group) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list); + result.user_data = cfgs; + result.idxed_expr_count = cfgs_list.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_FUNCTION_DEF(watch_group) +{ + E_Lookup result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *watch = cfgs->v[rhs_value.u64]; + String8 expr_string = rd_cfg_child_from_string(watch, str8_lit("expression"))->first->string; + E_Expr *expr = e_parse_expr_from_text(arena, expr_string); + result.irtree_and_type = e_irtree_and_type_from_expr(arena, expr); + } + scratch_end(scratch); + } + return result; +} + E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) { E_LookupInfo result = {0}; @@ -9169,7 +9208,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, lhs_type->name); + String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list); result.user_data = cfgs; @@ -9660,22 +9700,11 @@ 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 != &e_member_nil) + //- rjf: type evaluations -> display type string + if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key)) { - 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); - String8 size_string = str8_from_u64(arena, member_byte_size, radix, 0, 0); - str8_list_pushf(arena, out, "member (%S offset, %S byte%s)", offset_string, size_string, member_byte_size == 1 ? "" : "s"); - } - - //- rjf: type evaluations -> display type basic information - else if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && eval.expr->kind != E_ExprKind_MemberAccess) - { - String8 basic_type_kind_string = e_kind_basic_string_table[e_type_kind_from_key(eval.type_key)]; - U64 byte_size = e_type_byte_size_from_key(eval.type_key); - String8 size_string = str8_from_u64(arena, byte_size, radix, 0, 0); - str8_list_pushf(arena, out, "%S (%S byte%s)", basic_type_kind_string, size_string, byte_size == 1 ? "" : "s"); + String8 string = e_type_string_from_key(arena, eval.type_key); + str8_list_push(arena, out, string); } //- rjf: value/offset evaluations @@ -11945,6 +11974,21 @@ rd_vocabulary_info_from_code_name(String8 code_name) return info; } +internal RD_VocabularyInfo * +rd_vocabulary_info_from_code_name_plural(String8 code_name_plural) +{ + RD_VocabularyInfo *info = &rd_nil_vocabulary_info; + for EachElement(idx, rd_vocabulary_info_table) + { + if(str8_match(rd_vocabulary_info_table[idx].code_name_plural, code_name_plural, 0)) + { + info = &rd_vocabulary_info_table[idx]; + break; + } + } + return info; +} + //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -13163,7 +13207,6 @@ rd_frame(void) //- rjf: choose set of evallable config names String8 evallable_cfg_names[] = { - str8_lit("watch"), str8_lit("breakpoint"), str8_lit("watch_pin"), str8_lit("target"), @@ -13340,6 +13383,16 @@ rd_frame(void) } } + //- rjf: add macros for watch groups + { + String8 collection_name = str8_lit("watches"); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(watch_group), E_LOOKUP_FUNCTION_NAME(watch_group)); + } + //- rjf: add macros for collections (new @cfg) for EachElement(cfg_name_idx, evallable_cfg_names) { @@ -13835,6 +13888,15 @@ rd_frame(void) rd_cfg_release(recent_projects.last->v); } } + + //- TODO(rjf): @cfg set up debugging config state + if(kind == RD_CmdKind_OpenUser) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, str8_lit("basics")); + } }break; //- rjf: writing config changes diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index c9e1ceb6..dabf65be 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1416,10 +1416,12 @@ internal DR_FancyStringList rd_stop_explanation_fstrs_from_ctrl_event(Arena *are //~ rjf: Vocabulary Info Lookups internal RD_VocabularyInfo *rd_vocabulary_info_from_code_name(String8 code_name); +internal RD_VocabularyInfo *rd_vocabulary_info_from_code_name_plural(String8 code_name_plural); #define rd_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->code_name_plural) #define rd_display_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name) #define rd_display_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name_plural) #define rd_icon_kind_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->icon_kind) +#define rd_singular_from_code_name_plural(code_name_plural) (rd_vocabulary_info_from_code_name_plural(code_name_plural)->code_name) //////////////////////////////// //~ rjf: Continuous Frame Requests diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index bc13537f..35bf5d39 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -596,14 +596,6 @@ entry_point(CmdLine *cmd_line) rd_init(cmd_line); } - //- TODO(rjf): @cfg set up debugging config state - { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("basics")); - } - //- rjf: setup initial target from command line args { String8List args = cmd_line->inputs; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4c24e936..5155e92a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -957,9 +957,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's cells rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("expression"), .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.20f); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("view_rule"), .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("sizeof($expr)"), .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("view_rule"), .pct = 0.25f); di_scope_close(di_scope); scratch_end(scratch); @@ -1092,7 +1093,105 @@ internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { RD_WatchRowCellInfo result = {0}; - result.string = row->string; + switch(cell->kind) + { + //- rjf: expression cells -> if no string attached to row itself, form one from the + // expression tree. + case RD_WatchCellKind_Expr: + { + result.string = row->string; + if(result.string.size == 0) + { + E_Expr *notable_expr = row->expr; + for(B32 good = 0; !good;) + { + switch(notable_expr->kind) + { + default:{good = 1;}break; + case E_ExprKind_Address: + case E_ExprKind_Deref: + case E_ExprKind_Cast: + { + notable_expr = notable_expr->last; + }break; + case E_ExprKind_Ref: + { + notable_expr = notable_expr->ref; + }break; + } + } + switch(notable_expr->kind) + { + default: + { + result.string = e_string_from_expr(arena, notable_expr); + }break; + case E_ExprKind_ArrayIndex: + { + result.string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); + }break; + case E_ExprKind_MemberAccess: + { + result.string = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); + }break; + } + } + }break; + + //- rjf: evaluation cells -> wrap expression if needed, evaluate, & stringize + case RD_WatchCellKind_Eval: + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: use cell's wrap string to wrap row's expression + String8 wrap_string = cell->string; + E_Expr *root_expr = row->expr; + if(wrap_string.size != 0) + { + E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string); + root_expr = wrap_expr; + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *parent; + E_Expr *expr; + }; + Task start_task = {0, &e_expr_nil, wrap_expr}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + { + E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->expr); + if(t->parent != &e_expr_nil) + { + e_expr_insert_child(t->parent, t->expr, original_expr_ref); + e_expr_remove_child(t->parent, t->expr); + } + else + { + root_expr = original_expr_ref; + } + } + else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = t->expr; + task->expr = child; + } + } + } + + //- rjf: evaluate wrapped expression + result.eval = e_eval_from_expr(scratch.arena, root_expr); + result.string = rd_value_string_from_eval(arena, 0, 10, font, font_size, max_size_px, result.eval, &e_member_nil, row->view_rules); + + scratch_end(scratch); + }break; + } return result; } @@ -4026,7 +4125,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(targets) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, str8_lit("collection:targets"), str8_lit("only: label exe args working_directory entry_point stdout_path stderr_path stdin_path debug_subprocesses b32 str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:targets"), str8_zero(), 1, 10, rect); ProfEnd(); } From 5b82fc2339074e198bf6358c12d599a782a65a0f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 Jan 2025 15:52:26 -0800 Subject: [PATCH 037/755] eliminate member-filtering hack for cfg views; eliminate deref-space-ptr hack --- src/eval/eval_interpret.c | 22 -------------------- src/eval/eval_ir.c | 43 --------------------------------------- src/eval/eval_ir.h | 3 --- src/raddbg/raddbg_core.c | 39 +---------------------------------- src/raddbg/raddbg_core.h | 1 - src/raddbg/raddbg_views.c | 8 ++++---- 6 files changed, 5 insertions(+), 111 deletions(-) diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index e507c46b..630bd720 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -75,7 +75,6 @@ e_interpret(String8 bytecode) else switch(op) { case E_IRExtKind_SetSpace: {ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break; - case E_IRExtKind_DerefSpacePtr:{ctrlbits = RDI_EVAL_CTRLBITS(0, 1, 1);}break; default: { result.code = E_InterpretationCode_BadOp; @@ -125,27 +124,6 @@ e_interpret(String8 bytecode) MemoryCopy(&selected_space, &imm, sizeof(selected_space)); }break; - case E_IRExtKind_DerefSpacePtr: - { - U64 addr = svals[0].u64; - U64 size = sizeof(E_Space) + sizeof(U64); - typedef struct SpacePtrRead SpacePtrRead; - struct SpacePtrRead - { - E_Space space; - U64 off; - }; - SpacePtrRead space_ptr_read = {0}; - B32 good_read = e_space_read(selected_space, &space_ptr_read, r1u64(addr, addr+size)); - if(!good_read) - { - result.code = E_InterpretationCode_BadMemRead; - goto done; - } - MemoryCopyStruct(&selected_space, &space_ptr_read.space); - nval.u64 = space_ptr_read.off; - }break; - case RDI_EvalOp_Stop: { goto done; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4432f44c..1e481db7 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -464,16 +464,6 @@ e_oplist_push_set_space(Arena *arena, E_OpList *list, E_Space space) list->encoded_size += 1 + sizeof(space); } -internal void -e_oplist_push_deref_space_ptr(Arena *arena, E_OpList *list) -{ - E_Op *node = push_array_no_zero(arena, E_Op, 1); - node->opcode = E_IRExtKind_DerefSpacePtr; - SLLQueuePush(list->first, list->last, node); - list->op_count += 1; - list->encoded_size += 1; -} - internal void e_oplist_push_string_literal(Arena *arena, E_OpList *list, String8 string) { @@ -602,14 +592,6 @@ e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c) return root; } -internal E_IRNode * -e_irtree_deref_space_ptr(Arena *arena, E_IRNode *c) -{ - E_IRNode *root = e_push_irnode(arena, E_IRExtKind_DerefSpacePtr); - e_irnode_push_child(root, c); - return root; -} - internal E_IRNode * e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key) { @@ -1484,14 +1466,6 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr }break; } - //- rjf: evaluating a space pointer -> generate a dynamic set-space & resolve to the offset - if(e_type_kind_from_key(result.type_key) == E_TypeKind_SpacePtr) - { - result.root = e_irtree_deref_space_ptr(arena, result.root); - result.type_key = e_type_direct_from_key(result.type_key); - result.mode = E_Mode_Offset; - } - //- rjf: if the expression's space does not match the current, then push a set-space node // before returning E_Space zero_space = zero_struct; @@ -1545,17 +1519,6 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) } }break; - case E_IRExtKind_DerefSpacePtr: - { - for(E_IRNode *child = root->first; - child != &e_irnode_nil; - child = child->next) - { - e_append_oplist_from_irtree(arena, child, out); - } - e_oplist_push_deref_space_ptr(arena, out); - }break; - case RDI_EvalOp_Cond: { // rjf: generate oplists for each child @@ -1697,12 +1660,6 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) // rjf: advance ptr = next_ptr; }break; - - case E_IRExtKind_DerefSpacePtr: - { - ptr[0] = opcode; - ptr += 1; - }break; } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 67af8a91..dca8931c 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -11,7 +11,6 @@ enum { E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, E_IRExtKind_SetSpace, - E_IRExtKind_DerefSpacePtr, E_IRExtKind_COUNT }; @@ -169,7 +168,6 @@ internal void e_oplist_push_uconst(Arena *arena, E_OpList *list, U64 x); internal void e_oplist_push_sconst(Arena *arena, E_OpList *list, S64 x); internal void e_oplist_push_bytecode(Arena *arena, E_OpList *list, String8 bytecode); internal void e_oplist_push_set_space(Arena *arena, E_OpList *list, E_Space space); -internal void e_oplist_push_deref_space_ptr(Arena *arena, E_OpList *list); internal void e_oplist_push_string_literal(Arena *arena, E_OpList *list, String8 string); internal void e_oplist_concat_in_place(E_OpList *dst, E_OpList *to_push); @@ -186,7 +184,6 @@ internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l, internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string); internal E_IRNode *e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c); -internal E_IRNode *e_irtree_deref_space_ptr(Arena *arena, E_IRNode *c); internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_convert_lo(Arena *arena, E_IRNode *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in); internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b6392876..431154f9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2846,38 +2846,6 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } } }break; - - //- rjf: meta collections - case RD_EvalSpaceKind_MetaCollection: - { - typedef struct SpacePtr SpacePtr; - struct SpacePtr - { - E_Space space; - U64 off; - }; - RD_CfgArray cfgs_array = {0}; - if(space.u64s[0] < rd_state->eval_collection_cfg_names->count) - { - cfgs_array = rd_state->eval_collection_cfgs[space.u64s[0]]; - } - U64 space_ptr_size = sizeof(SpacePtr); - Rng1U64 idx_range = r1u64(range.min/space_ptr_size, range.max/space_ptr_size); - U64 out_off = 0; - U64 out_opl = dim_1u64(range); - for(U64 src_idx = idx_range.min; src_idx < idx_range.max && out_off+space_ptr_size <= out_opl; src_idx += 1) - { - RD_Cfg *cfg = &rd_nil_cfg; - if(src_idx < cfgs_array.count) - { - cfg = cfgs_array.v[src_idx]; - } - SpacePtr space_ptr = {rd_eval_space_from_cfg(cfg), 0}; - MemoryCopy((U8 *)out + out_off, &space_ptr, space_ptr_size); - out_off += sizeof(space_ptr); - } - result = 1; - }break; } scratch_end(scratch); return result; @@ -13197,7 +13165,6 @@ rd_frame(void) for EachElement(idx, rd_collection_name_table) { 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_keys[idx]; e_string2expr_map_insert(scratch.arena, ctx->macro_map, rd_collection_name_table[idx], expr); @@ -13393,17 +13360,13 @@ rd_frame(void) e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(watch_group), E_LOOKUP_FUNCTION_NAME(watch_group)); } - //- rjf: add macros for collections (new @cfg) + //- rjf: add macros for all cfg collections (new @cfg) for EachElement(cfg_name_idx, evallable_cfg_names) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - E_Space space = e_space_make(RD_EvalSpaceKind_MetaCollection); - space.u64s[0] = cfg_name_idx; - expr->space = space; - expr->mode = E_Mode_Offset; expr->type_key = collection_type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), E_LOOKUP_FUNCTION_NAME(top_level_cfg)); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index dabf65be..e4068719 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -97,7 +97,6 @@ enum RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaEntity, RD_EvalSpaceKind_MetaCtrlEntity, - RD_EvalSpaceKind_MetaCollection, }; //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5155e92a..0fc63153 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -4142,7 +4142,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, str8_lit("collection:file_path_maps"), str8_lit("only: source_path destination_path str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:file_path_maps"), str8_zero(), 1, 10, rect); ProfEnd(); } @@ -4159,7 +4159,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); } - rd_watch_view_build(wv, str8_lit("collection:auto_view_rules"), str8_lit("only: type view_rule str"), 1, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:auto_view_rules"), str8_zero(), 1, 10, rect); ProfEnd(); } @@ -4176,7 +4176,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, str8_lit("collection:breakpoints"), str8_lit("only: label condition str hit_count source_location address_location function_location"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:breakpoints"), str8_zero(), 0, 10, rect); ProfEnd(); } @@ -4193,7 +4193,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); } - rd_watch_view_build(wv, str8_lit("collection:watch_pins"), str8_lit("only: label source_location address_location str"), 0, 10, rect); + rd_watch_view_build(wv, str8_lit("collection:watch_pins"), str8_zero(), 0, 10, rect); ProfEnd(); } From b1829af8c60815df6d79b036a290e096008a8990 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 Jan 2025 16:52:15 -0800 Subject: [PATCH 038/755] eliminate old per-frame cfg group cache --- .../eval_visualization_core.h | 4 ++-- src/raddbg/raddbg_core.c | 20 ++++--------------- src/raddbg/raddbg_core.h | 4 ---- src/raddbg/raddbg_views.c | 19 +++++++++++++++++- src/raddbg/raddbg_views.h | 2 +- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 61fbed78..45405d9a 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -150,8 +150,8 @@ typedef EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_ViewRuleExprExpandN typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info enum { - EV_ViewRuleInfoFlag_Inherited = (1<<0), - EV_ViewRuleInfoFlag_Expandable = (1<<1), + EV_ViewRuleInfoFlag_Inherited = (1<<0), + EV_ViewRuleInfoFlag_Expandable = (1<<1), }; typedef struct EV_ViewRuleInfo EV_ViewRuleInfo; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 431154f9..02c80c50 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13181,18 +13181,6 @@ rd_frame(void) str8_lit("auto_view_rule"), }; - //- rjf: store off eval collections for this frame - rd_state->eval_collection_cfg_names = push_array(rd_frame_arena(), String8Array, 1); - rd_state->eval_collection_cfg_names->count = ArrayCount(evallable_cfg_names); - rd_state->eval_collection_cfg_names->v = push_array(rd_frame_arena(), String8, rd_state->eval_collection_cfg_names->count); - MemoryCopy(rd_state->eval_collection_cfg_names->v, evallable_cfg_names, sizeof(evallable_cfg_names)); - rd_state->eval_collection_cfgs = push_array(rd_frame_arena(), RD_CfgArray, rd_state->eval_collection_cfg_names->count); - for EachElement(idx, evallable_cfg_names) - { - RD_CfgList list = rd_cfg_top_level_list_from_string(scratch.arena, evallable_cfg_names[idx]); - rd_state->eval_collection_cfgs[idx] = rd_cfg_array_from_list(rd_frame_arena(), &list); - } - //- rjf: build special member types for evallable config types E_TypeKey bool_type_key = {0}; E_TypeKey u64_type_key = {0}; @@ -13278,10 +13266,10 @@ rd_frame(void) for EachElement(idx, evallable_cfg_names) { String8 name = evallable_cfg_names[idx]; - RD_CfgArray cfgs = rd_state->eval_collection_cfgs[idx]; - for EachIndex(cfg_idx, cfgs.count) + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { - RD_Cfg *cfg = cfgs.v[cfg_idx]; + RD_Cfg *cfg = n->v; String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; E_Space space = rd_eval_space_from_cfg(cfg); @@ -13858,7 +13846,7 @@ rd_frame(void) RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("basics")); + rd_cfg_new(expr, str8_lit("targets[0]")); } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index e4068719..cc99431e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -870,10 +870,6 @@ struct RD_State // rjf: config -> eval blob map (lazily constructed from-scratch each frame) RD_Cfg2EvalBlobMap *cfg2evalblob_map; - // rjf: eval collections (constructed from scratch every frame) - String8Array *eval_collection_cfg_names; - RD_CfgArray *eval_collection_cfgs; - // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0fc63153..252fcb25 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -952,8 +952,25 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine cfg group + // rjf: determine cfg group name + { + E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, row->block->expr); + E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + if(block_type_kind == E_TypeKind_Set) + { + E_Type *block_type = e_type_from_key(scratch.arena, block_type_key); + info.group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + } + } + // rjf: determine row's cfg + if(info.group_cfg_name.size != 0) + { + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, info.group_cfg_name); + // TODO(rjf): this is not correct - assumes row's evaluation is in the block's space... + // info.group_cfg = rd_cfg_from_eval_space(info.eval.space); + } // rjf: fill row's cells rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("expression"), .pct = 0.25f); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 42d21123..90ce0dc6 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -71,7 +71,7 @@ struct RD_WatchRowInfo { E_Eval eval; CTRL_Entity *module; - String8 group_key; + String8 group_cfg_name; RD_Cfg *group_cfg; CTRL_Entity *group_entity; CTRL_Entity *callstack_thread; From aac93b59526b10b8bec4f52884fc5b426ed42ce0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 1 Feb 2025 17:37:24 -0800 Subject: [PATCH 039/755] move over all expansion view rules to new eval-system lookup hooks; eliminate most of old hooks --- src/ctrl/ctrl.mdesk | 24 +- src/ctrl/ctrl_core.c | 15 + src/ctrl/ctrl_core.h | 1 + src/ctrl/generated/ctrl.meta.c | 13 + src/ctrl/generated/ctrl.meta.h | 1 + src/eval/eval_ir.c | 110 +- src/eval/eval_ir.h | 58 +- src/eval/eval_types.c | 37 + src/eval/eval_types.h | 28 + .../eval_visualization_builtin_view_rules.c | 14 +- src/raddbg/generated/raddbg.meta.c | 96 +- src/raddbg/generated/raddbg.meta.h | 58 +- src/raddbg/raddbg.mdesk | 58 +- src/raddbg/raddbg_core.c | 1011 ++++++++--------- src/raddbg/raddbg_core.h | 37 +- src/raddbg/raddbg_main.c | 1 + 16 files changed, 810 insertions(+), 752 deletions(-) diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index abc3401d..98a97412 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -4,17 +4,17 @@ //////////////////////////////// //~ rjf: Entity Kinds -@table(name display_string) +@table(name code_name display_string) CTRL_EntityKindTable: { - {Root "Root" } - {Machine "Machine" } - {Process "Process" } - {Thread "Thread" } - {Module "Module" } - {EntryPoint "Entry Point" } - {DebugInfoPath "Debug Info Path" } - {PendingThreadName "Pending Thread Name" } + {Root root "Root" } + {Machine machine "Machine" } + {Process process "Process" } + {Thread thread "Thread" } + {Module module "Module" } + {EntryPoint entry_point "Entry Point" } + {DebugInfoPath debug_info_path "Debug Info Path" } + {PendingThreadName pending_thread_name "Pending Thread Name" } } @enum CTRL_EntityKind: @@ -24,6 +24,12 @@ CTRL_EntityKindTable: COUNT, } +@data(String8) ctrl_entity_kind_code_name_table: +{ + `{0}`, + @expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.code_name)")` +} + @data(String8) ctrl_entity_kind_display_string_table: { `{0}`, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 41012033..4d285810 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -91,6 +91,21 @@ ctrl_string_from_msg_kind(CTRL_MsgKind kind) return result; } +internal CTRL_EntityKind +ctrl_entity_kind_from_string(String8 string) +{ + CTRL_EntityKind result = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(ctrl_entity_kind_code_name_table[k], string, 0)) + { + result = k; + break; + } + } + return result; +} + //////////////////////////////// //~ rjf: Machine/Handle Pair Type Functions diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 3540e87f..73e0d3eb 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -951,6 +951,7 @@ internal U64 ctrl_hash_from_handle(CTRL_Handle handle); internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind); internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); +internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); //////////////////////////////// //~ rjf: Handle Type Functions diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 019fde09..4b45ed27 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,6 +4,19 @@ //- GENERATED CODE C_LINKAGE_BEGIN +String8 ctrl_entity_kind_code_name_table[9] = +{ +{0}, +str8_lit_comp("root"), +str8_lit_comp("machine"), +str8_lit_comp("process"), +str8_lit_comp("thread"), +str8_lit_comp("module"), +str8_lit_comp("entry_point"), +str8_lit_comp("debug_info_path"), +str8_lit_comp("pending_thread_name"), +}; + String8 ctrl_entity_kind_display_string_table[9] = { {0}, diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 9192b4de..8c5e9a3a 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -64,6 +64,7 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN +extern String8 ctrl_entity_kind_code_name_table[9]; extern String8 ctrl_entity_kind_display_string_table[9]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 1e481db7..55610b1a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -90,6 +90,11 @@ e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); MemoryCopyStruct(&n->v, rule); + if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } + if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } + if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } + if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } + if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } n->v.name = push_str8_copy(arena, n->v.name); } @@ -155,9 +160,18 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) return lookup_info; } -E_LOOKUP_FUNCTION_DEF(default) +E_LOOKUP_ACCESS_FUNCTION_DEF(default) { - E_Lookup lookup = {{&e_irnode_nil}}; + // + // TODO(rjf): need to define what it means to access a set expression + // whose type *does not* define its IR generation rules, BUT it does + // define specific child expressions. so e.g. `watches`, does not + // define `watches[0]`, because it has defined that `watches[0]` + // maps to another expression, which is whatever the first watch + // expression is (e.g. `basics`). so, in that case, we can just use + // the lookup-range rule, grab the Nth expression, and IR-ify *that*. + // + E_LookupAccess result = {{&e_irnode_nil}}; switch(kind) { default:{}break; @@ -180,7 +194,7 @@ E_LOOKUP_FUNCTION_DEF(default) check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); check_type_kind = e_type_kind_from_key(check_type_key); } - e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); // rjf: look up member B32 r_found = 0; @@ -234,12 +248,12 @@ E_LOOKUP_FUNCTION_DEF(default) } else if(exprr->kind != E_ExprKind_LeafMember) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); break; } else if(!r_found) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); break; } else if(check_type_kind != E_TypeKind_Struct && @@ -247,7 +261,7 @@ E_LOOKUP_FUNCTION_DEF(default) check_type_kind != E_TypeKind_Union && check_type_kind != E_TypeKind_Enum) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); break; } @@ -275,9 +289,9 @@ E_LOOKUP_FUNCTION_DEF(default) } // rjf: fill - lookup.irtree_and_type.root = new_tree; - lookup.irtree_and_type.type_key = r_type; - lookup.irtree_and_type.mode = mode; + result.irtree_and_type.root = new_tree; + result.irtree_and_type.type_key = r_type; + result.irtree_and_type.mode = mode; } }break; @@ -302,8 +316,8 @@ E_LOOKUP_FUNCTION_DEF(default) direct_type = e_type_direct_from_key(direct_type); direct_type = e_type_unwrap(direct_type); U64 direct_type_size = e_type_byte_size_from_key(direct_type); - e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); - e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &r.msgs); + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); + e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &r.msgs); // rjf: bad conditions? -> error if applicable, exit if(r.root->op == 0) @@ -312,22 +326,22 @@ E_LOOKUP_FUNCTION_DEF(default) } else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); break; } else if(!e_type_kind_is_integer(r_restype_kind)) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); break; } else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); break; } else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) { - e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); break; } @@ -381,12 +395,64 @@ E_LOOKUP_FUNCTION_DEF(default) } // rjf: fill - lookup.irtree_and_type.root = new_tree; - lookup.irtree_and_type.type_key = direct_type; - lookup.irtree_and_type.mode = l.mode; + result.irtree_and_type.root = new_tree; + result.irtree_and_type.type_key = direct_type; + result.irtree_and_type.mode = l.mode; }break; } - return lookup; + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(default) +{ + E_LookupRange result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Enum) + { + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + Rng1U64 legal_idx_range = r1u64(0, lhs_type->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + result.exprs_count = read_range_count; + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + for(U64 idx = 0; idx < result.exprs_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = (lhs_type->members ? lhs_type->members[member_idx].name : + lhs_type->enum_vals ? lhs_type->enum_vals[member_idx].name : str8_lit("")); + result.exprs[idx] = e_expr_ref_member_access(arena, lhs, member_name); + } + } + else if(lhs_type_kind == E_TypeKind_Set) + { + result.exprs_count = dim_1u64(idx_range); + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + result.exprs_strings = push_array(arena, String8, result.exprs_count); + for(U64 idx = 0; idx < result.exprs_count; idx += 1) + { + result.exprs[idx] = e_expr_ref_array_index(arena, lhs, idx_range.min + idx); + } + } + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default) +{ + return num; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) +{ + return id; } //////////////////////////////// @@ -716,9 +782,9 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr } E_Expr *rhs = lhs->next; E_LookupRule *lookup_rule = e_lookup_rule_from_string(lookup_rule_name); - E_LookupInfo lookup_info = lookup_rule->lookup_info(arena, lhs); - E_Lookup lookup = lookup_rule->lookup(arena, expr->kind, lhs, rhs, lookup_info.user_data); - result = lookup.irtree_and_type; + E_LookupInfo lookup_info = lookup_rule->info(arena, lhs, str8_zero()); + E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); + result = lookup_access.irtree_and_type; scratch_end(scratch); }break; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index dca8931c..eef75238 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -66,31 +66,60 @@ struct E_LookupInfo U64 idxed_expr_count; }; -typedef struct E_Lookup E_Lookup; -struct E_Lookup +typedef struct E_LookupAccess E_LookupAccess; +struct E_LookupAccess { E_IRTreeAndType irtree_and_type; }; -#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs) +typedef struct E_LookupRange E_LookupRange; +struct E_LookupRange +{ + U64 exprs_count; + E_Expr **exprs; + String8 *exprs_strings; +}; + +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs, String8 filter) #define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name #define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); -#define E_LOOKUP_FUNCTION_SIG(name) E_Lookup name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) -#define E_LOOKUP_FUNCTION_NAME(name) e_lookup_##name -#define E_LOOKUP_FUNCTION_DEF(name) internal E_LOOKUP_FUNCTION_SIG(E_LOOKUP_FUNCTION_NAME(name)) -typedef E_LOOKUP_FUNCTION_SIG(E_LookupFunctionType); +#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) +#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name +#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) +typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); + +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) E_LookupRange name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name +#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) +typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); + +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) +typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); + +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) +typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); E_LOOKUP_INFO_FUNCTION_DEF(default); -E_LOOKUP_FUNCTION_DEF(default); +E_LOOKUP_ACCESS_FUNCTION_DEF(default); +E_LOOKUP_RANGE_FUNCTION_DEF(default); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); typedef struct E_LookupRule E_LookupRule; struct E_LookupRule { String8 name; - E_LookupInfoFunctionType *lookup_info; - E_LookupFunctionType *lookup; + E_LookupInfoFunctionType *info; + E_LookupAccessFunctionType *access; + E_LookupRangeFunctionType *range; + E_LookupIDFromNumFunctionType *id_from_num; + E_LookupNumFromIDFunctionType *num_from_id; }; typedef struct E_LookupRuleNode E_LookupRuleNode; @@ -131,7 +160,10 @@ local_persist read_only E_LookupRule e_lookup_rule__default = { str8_lit_comp("default"), E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_FUNCTION_NAME(default), + E_LOOKUP_ACCESS_FUNCTION_NAME(default), + E_LOOKUP_RANGE_FUNCTION_NAME(default), + E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), }; global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRCtx *e_ir_ctx = 0; @@ -153,11 +185,9 @@ internal void e_select_ir_ctx(E_IRCtx *ctx); internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); -#define e_lookup_rule_map_insert_new(arena, map, name_, lookup_info_, lookup_) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), .lookup_info = (lookup_info_), .lookup = (lookup_)}) +#define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__}) internal E_LookupRule *e_lookup_rule_from_string(String8 string); -E_LOOKUP_INFO_FUNCTION_DEF(default); -E_LOOKUP_FUNCTION_DEF(default); //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ec47d860..981581ee 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1864,6 +1864,43 @@ e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) return dst; } +internal E_String2TypeKeyMap +e_string2typekey_map_make(Arena *arena, U64 slots_count) +{ + E_String2TypeKeyMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_String2TypeKeySlot, map.slots_count); + return map; +} + +internal void +e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key) +{ + E_String2TypeKeyNode *n = push_array(arena, E_String2TypeKeyNode, 1); + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + n->string = push_str8_copy(arena, string); + n->key = key; +} + +internal E_TypeKey +e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) +{ + E_TypeKey key = zero_struct; + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_String2TypeKeyNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->string, string, 0)) + { + key = n->key; + break; + } + } + return key; +} + //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 9009c04c..a8cbd1b1 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -137,6 +137,31 @@ struct E_Type E_EnumVal *enum_vals; }; +//////////////////////////////// +//~ rjf: String -> Type Key Map Data Structure + +typedef struct E_String2TypeKeyNode E_String2TypeKeyNode; +struct E_String2TypeKeyNode +{ + E_String2TypeKeyNode *next; + String8 string; + E_TypeKey key; +}; + +typedef struct E_String2TypeKeySlot E_String2TypeKeySlot; +struct E_String2TypeKeySlot +{ + E_String2TypeKeyNode *first; + E_String2TypeKeyNode *last; +}; + +typedef struct E_String2TypeKeyMap E_String2TypeKeyMap; +struct E_String2TypeKeyMap +{ + U64 slots_count; + E_String2TypeKeySlot *slots; +}; + //////////////////////////////// //~ rjf: Evaluation Context @@ -323,6 +348,9 @@ internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); //- rjf: type key data structures internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); +internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); +internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); +internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string); //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index 250ecd81..d05dea15 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -183,7 +183,7 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default) { E_Type *type = e_type_from_key(scratch.arena, type_key); E_LookupRule *rule = e_lookup_rule_from_string(type->name); - E_LookupInfo lookup_info = rule->lookup_info(arena, expr); + E_LookupInfo lookup_info = rule->info(arena, expr, filter); total_row_count = Max(lookup_info.named_expr_count, lookup_info.idxed_expr_count); accel->lookup_rule = rule; accel->lookup_user_data = lookup_info.user_data; @@ -282,15 +282,15 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) //- rjf: fill with lookups // else if(accel->lookup_rule != 0) - { - result.row_exprs_count = needed_row_count; - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); + { + E_LookupRange lookup_range = accel->lookup_rule->range(arena, expr, idx_range, accel->lookup_user_data); + result.row_exprs_count = lookup_range.exprs_count; + result.row_exprs = lookup_range.exprs; + result.row_strings = lookup_range.exprs_strings; result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); + result.row_members = push_array(arena, E_Member *, result.row_exprs_count); for EachIndex(row_expr_idx, result.row_exprs_count) { - result.row_exprs[row_expr_idx] = e_expr_ref_array_index(arena, expr, idx_range.min + row_expr_idx); result.row_members[row_expr_idx] = &e_member_nil; } } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 04e89d6d..9b0ad608 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,7 +28,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[41] = +RD_VocabularyInfo rd_vocabulary_info_table[45] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -71,9 +71,13 @@ RD_VocabularyInfo rd_vocabulary_info_table[41] = {str8_lit_comp("vtx"), str8_lit_comp("vtxs"), str8_lit_comp("Vertex Buffer"), str8_lit_comp("Vertex Buffers"), RD_IconKind_Null}, {str8_lit_comp("vtx_size"), str8_lit_comp("vtx_sizes"), str8_lit_comp("Vertex Buffer Size"), str8_lit_comp("Vertex Buffer Sizes"), RD_IconKind_Null}, {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, +{str8_lit_comp("thread"), str8_lit_comp("threads"), str8_lit_comp("Thread"), str8_lit_comp("Threads"), RD_IconKind_Thread}, +{str8_lit_comp("process"), str8_lit_comp("processes"), str8_lit_comp("Process"), str8_lit_comp("Processes"), RD_IconKind_Threads}, +{str8_lit_comp("machine"), str8_lit_comp("machines"), str8_lit_comp("Machine"), str8_lit_comp("Machines"), RD_IconKind_Machine}, +{str8_lit_comp("module"), str8_lit_comp("modules"), str8_lit_comp("Module"), str8_lit_comp("Modules"), RD_IconKind_Module}, }; -RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = +RD_NameSchemaInfo rd_name_schema_info_table[10] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n"), str8_lit_comp("")}, {str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n"), str8_lit_comp("launch_and_run,launch_and_init,select_cfg,remove_cfg")}, @@ -81,6 +85,10 @@ RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6] = {str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'frozen':bool, 'label':code_string}"), str8_lit_comp("")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, +{str8_lit_comp("module"), str8_lit_comp("x:{'label':code_string, 'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}"), str8_lit_comp("")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, }; String8 d_entity_kind_display_string_table[27] = @@ -711,116 +719,46 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -String8 rd_collection_name_table[12] = +String8 rd_collection_name_table[2] = { -str8_lit_comp("machines"), -str8_lit_comp("processes"), -str8_lit_comp("threads"), -str8_lit_comp("modules"), str8_lit_comp("scheduler_machine"), str8_lit_comp("scheduler_process"), -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"), }; -RD_EntityKind rd_collection_entity_kind_table[12] = +RD_EntityKind rd_collection_entity_kind_table[2] = { RD_EntityKind_Nil, RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, -RD_EntityKind_Nil, }; -CTRL_EntityKind rd_collection_ctrl_entity_kind_table[12] = +CTRL_EntityKind rd_collection_ctrl_entity_kind_table[2] = { -CTRL_EntityKind_Machine, -CTRL_EntityKind_Process, -CTRL_EntityKind_Thread, -CTRL_EntityKind_Module, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, CTRL_EntityKind_Null, CTRL_EntityKind_Null, }; -EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[12] = +EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[2] = { -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(modules), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_machine), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(locals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(registers), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[12] = +EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[2] = { -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(modules), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_machine), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(locals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(registers), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[12] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[2] = { -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(modules), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_machine), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(procedures), }; -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[12] = +EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[2] = { -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(machines), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(processes), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(threads), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(modules), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_machine), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_process), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(globals), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(thread_locals), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(types), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(procedures), }; RD_ViewRuleInfo rd_view_rule_kind_info_table[28] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 71b1ae02..9e88a8d8 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -522,8 +522,8 @@ String8 display_name_plural; RD_IconKind icon_kind; }; -typedef struct RD_CfgNameSchemaPair RD_CfgNameSchemaPair; -struct RD_CfgNameSchemaPair +typedef struct RD_NameSchemaInfo RD_NameSchemaInfo; +struct RD_NameSchemaInfo { String8 name; String8 schema; @@ -651,50 +651,14 @@ RD_ViewRuleUIFunctionType *ui; .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(modules); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(locals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(registers); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(modules); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(locals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(registers); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(modules); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(modules); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine); EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(globals); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(thread_locals); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(types); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures); RD_VIEW_RULE_UI_FUNCTION_DEF(null); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm); @@ -733,8 +697,8 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[41]; -extern RD_CfgNameSchemaPair rd_cfg_name_schema_pair_table[6]; +extern RD_VocabularyInfo rd_vocabulary_info_table[45]; +extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern String8 d_entity_kind_display_string_table[27]; extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; @@ -745,13 +709,13 @@ extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern String8 rd_collection_name_table[12]; -extern RD_EntityKind rd_collection_entity_kind_table[12]; -extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[12]; -extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[12]; -extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[12]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[12]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[12]; +extern String8 rd_collection_name_table[2]; +extern RD_EntityKind rd_collection_entity_kind_table[2]; +extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[2]; +extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[2]; +extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[2]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[2]; +extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[2]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 2d5b5c90..16859833 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -92,6 +92,10 @@ RD_VocabularyMap: {vtx _ "Vertex Buffer" _ Null } {vtx_size _ "Vertex Buffer Size" _ Null } {label _ "Label" _ Null } + {thread _ "Thread" _ Thread } + {process processes "Process" "Processes" Threads } + {machine _ "Machine" _ Machine } + {module _ "Module" _ Module } } @struct RD_VocabularyInfo: @@ -109,9 +113,9 @@ RD_VocabularyMap: } //////////////////////////////// -//~ rjf: Configuration Tree Schemas +//~ rjf: Schemas -@table(name schema cmd_names) RD_CfgSchemaTable: +@table(name schema cmd_names) RD_SchemaTable: { //- rjf: settings { @@ -201,18 +205,42 @@ RD_VocabularyMap: ```x:{'source':code_string, 'dest':code_string}```, `remove_cfg`, } + + //- rjf: machines + { + machine, + ```x:{'frozen':bool, 'label':code_string}```, + } + + //- rjf: processes + { + process, + ```x:{'frozen':bool, 'label':code_string, 'id':u64}```, + } + + //- rjf: modules + { + module, + ```x:{'label':code_string, 'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}```, + } + + //- rjf: threads + { + thread, + ```x:{'frozen':bool, 'label':code_string, 'id':u64}```, + } } -@struct RD_CfgNameSchemaPair: +@struct RD_NameSchemaInfo: { `String8 name`; `String8 schema`; `String8 cmd_names`; } -@data(RD_CfgNameSchemaPair) rd_cfg_name_schema_pair_table: +@data(RD_NameSchemaInfo) rd_name_schema_info_table: { - @expand(RD_CfgSchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.cmd_names)")}` + @expand(RD_SchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.cmd_names)")}` } //////////////////////////////// @@ -1002,22 +1030,22 @@ RD_CollectionTable: //{auto_view_rules AutoViewRule Null x} //- rjf: control entity groups - {machines Nil Machine x} - {processes Nil Process x} - {threads Nil Thread x} - {modules Nil Module x} + //{machines Nil Machine x} + //{processes Nil Process x} + //{threads Nil Thread x} + //{modules Nil Module x} //- rjf: scheduling control entity hierarchies {scheduler_machine Nil Null x} {scheduler_process Nil Null x} //- rjf: debug info / architecture watch tables - {locals Nil Null -} - {registers Nil Null -} - {globals Nil Null x} - {thread_locals Nil Null x} - {types Nil Null x} - {procedures Nil Null x} + // {locals Nil Null -} + // {registers Nil Null -} + // {globals Nil Null x} + // {thread_locals Nil Null x} + // {types Nil Null x} + // {procedures Nil Null x} } @gen diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 02c80c50..b92cc98f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1497,11 +1497,11 @@ internal MD_Node * rd_schema_from_name(Arena *arena, String8 name) { String8 schema_string = {0}; - for EachElement(idx, rd_cfg_name_schema_pair_table) + for EachElement(idx, rd_name_schema_info_table) { - if(str8_match(name, rd_cfg_name_schema_pair_table[idx].name, 0)) + if(str8_match(name, rd_name_schema_info_table[idx].name, 0)) { - schema_string = rd_cfg_name_schema_pair_table[idx].schema; + schema_string = rd_name_schema_info_table[idx].schema; break; } } @@ -2446,26 +2446,8 @@ internal String8 rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) { String8 result = {0}; - - // rjf: cfg name -> type String8 name = cfg->string; - E_TypeKey type_key = zero_struct; - { - U64 name_hash = d_hash_from_string(name); - U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; - for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->string, name, 0)) - { - type_key = n->key; - break; - } - } - } - - // rjf: if this config has an eval type, build eval blob & cache + 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); @@ -2522,7 +2504,6 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) str8_list_concat_in_place(&all_parts, &variable_width_parts); result = str8_list_join(arena, &all_parts, 0); } - return result; } @@ -2551,25 +2532,7 @@ rd_eval_blob_from_cfg__cached(RD_Cfg *cfg) // rjf: no node? -> try to build one if(node == 0) { - // rjf: cfg name -> type - String8 name = cfg->string; - E_TypeKey type_key = zero_struct; - { - U64 name_hash = d_hash_from_string(name); - U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; - for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->string, name, 0)) - { - type_key = n->key; - break; - } - } - } - - // rjf: if this config has an eval type, build eval blob & cache + 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); @@ -2895,26 +2858,8 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) RD_Cfg *cfg = rd_cfg_from_eval_space(space); String8 eval_blob = rd_eval_blob_from_cfg__cached(cfg); MD_Node *schema = rd_schema_from_name(scratch.arena, cfg->string); - - // rjf: cfg name -> type key String8 name = cfg->string; - E_TypeKey type_key = zero_struct; - { - U64 name_hash = d_hash_from_string(name); - U64 name_slot_idx = name_hash%rd_state->cfg_string2typekey_map->slots_count; - for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[name_slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->string, name, 0)) - { - type_key = n->key; - break; - } - } - } - - // rjf: key -> type + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); E_Type *type = e_type_from_key(scratch.arena, type_key); // rjf: find member to which this write applies, reflect back in the cfg tree @@ -8803,52 +8748,6 @@ struct RD_CtrlEntityExpandAccel CTRL_EntityArray entities; }; -//- rjf: meta entities - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Watch); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Watch, 0); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Target); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(targets) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Target, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_Breakpoint); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(breakpoints) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_Breakpoint, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_WatchPin); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watch_pins) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_WatchPin, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_FilePathMap); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(file_path_maps) { return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_FilePathMap, 1); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(auto_view_rules) { return rd_ev_view_rule_expr_expand_info__meta_entities(arena, view, filter, expr, params, RD_EntityKind_AutoViewRule); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(auto_view_rules) { return rd_ev_view_rule_expr_expand_range_info__meta_entities(arena, view, filter, expr, params, idx_range, user_data, RD_EntityKind_AutoViewRule, 1); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(auto_view_rules){ return rd_ev_view_rule_expr_id_from_num__meta_entities(num, user_data, RD_EntityKind_AutoViewRule, 1); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(auto_view_rules){ return rd_ev_view_rule_expr_num_from_id__meta_entities(id, user_data, RD_EntityKind_AutoViewRule, 1); } - -//- rjf: control entity groups - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, str8_zero(), expr, params, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, str8_zero(), expr, params, idx_range, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(machines) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Machine); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(processes) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Process); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(threads) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Thread); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(arena, view, filter, expr, params, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(arena, view, filter, expr, params, idx_range, user_data, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(num, user_data, CTRL_EntityKind_Module); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(modules) { return rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(id, user_data, CTRL_EntityKind_Module); } - //- rjf: control entity hierarchies EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine) @@ -9010,53 +8909,107 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) return id; } -//- rjf: locals +//- rjf: debug info tables -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(locals) +E_LOOKUP_INFO_FUNCTION_DEF(watches) { + E_LookupInfo result = {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); - String8List exprs_filtered = {0}; - for EachIndex(idx, nodes.count) { - String8 local_expr_string = nodes.v[idx]->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); - if(matches.count == matches.needle_part_count) + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) { - str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + String8 expr = rd_expr_from_cfg(n->v); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); + if(matches.count == matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } } + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + result.user_data = cfgs; + result.idxed_expr_count = cfgs->count; } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_filtered); - EV_ExpandInfo info = {accel, accel->count}; scratch_end(scratch); - return info; + return result; } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(locals) +E_LOOKUP_RANGE_FUNCTION_DEF(watches) { - String8Array *accel = (String8Array *)user_data; - EV_ExpandRangeInfo result = {0}; + E_LookupRange result = {0}; { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + result.exprs_count = read_range_count; + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + result.exprs_strings = push_array(arena, String8, result.exprs_count); + for(U64 idx = 0; idx < result.exprs_count; idx += 1) { - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, accel->v[idx_range.min + row_expr_idx]); - result.row_members[row_expr_idx] = &e_member_nil; + U64 cfg_idx = read_range.min + idx; + String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; + result.exprs[idx] = e_parse_expr_from_text(arena, expr_string); + result.exprs_strings[idx] = push_str8_copy(arena, expr_string); } } return result; } -//- rjf: registers +E_LOOKUP_INFO_FUNCTION_DEF(locals) +{ + E_LookupInfo result = {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); + String8List exprs_filtered = {0}; + for EachIndex(idx, nodes.count) + { + String8 local_expr_string = nodes.v[idx]->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_filtered); + result.user_data = accel; + result.idxed_expr_count = accel->count; + } + scratch_end(scratch); + return result; +} -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(registers) +E_LOOKUP_RANGE_FUNCTION_DEF(locals) +{ + E_LookupRange result = {0}; + { + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + result.exprs_count = read_range_count; + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + result.exprs_strings = push_array(arena, String8, result.exprs_count); + for(U64 idx = 0; idx < result.exprs_count; idx += 1) + { + String8 expr_string = accel->v[read_range.min + idx]; + result.exprs[idx] = e_parse_expr_from_text(arena, expr_string); + result.exprs_strings[idx] = push_str8_copy(arena, expr_string); + } + } + return result; +} + +E_LOOKUP_INFO_FUNCTION_DEF(registers) { Temp scratch = scratch_begin(&arena, 1); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -9084,90 +9037,32 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(registers) } String8Array *accel = push_array(arena, String8Array, 1); *accel = str8_array_from_list(arena, &exprs_list); - EV_ExpandInfo info = {accel, accel->count}; + E_LookupInfo info = {accel, 0, accel->count}; scratch_end(scratch); return info; } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(registers) +E_LOOKUP_RANGE_FUNCTION_DEF(registers) { String8Array *accel = (String8Array *)user_data; - EV_ExpandRangeInfo result = {0}; + E_LookupRange result = {0}; { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + result.exprs_count = dim_1u64(read_range); + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + result.exprs_strings = push_array(arena, String8, result.exprs_count); + for(U64 idx = 0; idx < result.exprs_count; idx += 1) { - String8 string = push_str8f(arena, "reg:%S", accel->v[idx_range.min + row_expr_idx]); - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, string); - result.row_members[row_expr_idx] = &e_member_nil; + String8 register_name = accel->v[read_range.min + idx]; + String8 register_expr = push_str8f(arena, "reg:%S", register_name); + result.exprs_strings[idx] = register_name; + result.exprs[idx] = e_parse_expr_from_text(arena, register_expr); } } return result; } -//- rjf: debug info tables - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_GlobalVariables);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_GlobalVariables);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_GlobalVariables); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(globals) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_GlobalVariables); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_ThreadVariables);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_ThreadVariables);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_ThreadVariables); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(thread_locals) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_ThreadVariables); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_UDTs);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_UDTs);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_UDTs); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(types) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_UDTs); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_expand_info__debug_info_tables(arena, view, filter, expr, params, RDI_SectionKind_Procedures);} -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_expand_range_info__debug_info_tables(arena, view, filter, expr, params, idx_range, user_data, RDI_SectionKind_Procedures);} -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_id_from_num__debug_info_tables(num, user_data, RDI_SectionKind_Procedures); } -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(procedures) {return rd_ev_view_rule_expr_num_from_id__debug_info_tables(id, user_data, RDI_SectionKind_Procedures); } - -E_LOOKUP_INFO_FUNCTION_DEF(watch_group) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); - cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list); - result.user_data = cfgs; - result.idxed_expr_count = cfgs_list.count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_FUNCTION_DEF(watch_group) -{ - E_Lookup result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) - { - RD_Cfg *watch = cfgs->v[rhs_value.u64]; - String8 expr_string = rd_cfg_child_from_string(watch, str8_lit("expression"))->first->string; - E_Expr *expr = e_parse_expr_from_text(arena, expr_string); - result.irtree_and_type = e_irtree_and_type_from_expr(arena, expr); - } - scratch_end(scratch); - } - return result; -} - E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) { E_LookupInfo result = {0}; @@ -9187,9 +9082,9 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) return result; } -E_LOOKUP_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) { - E_Lookup result = {{&e_irnode_nil}}; + E_LookupAccess result = {{&e_irnode_nil}}; if(kind == E_ExprKind_ArrayIndex) { Temp scratch = scratch_begin(&arena, 1); @@ -9204,21 +9099,7 @@ E_LOOKUP_FUNCTION_DEF(top_level_cfg) RD_Cfg *cfg = cfgs->v[rhs_value.u64]; E_Space cfg_space = rd_eval_space_from_cfg(cfg); String8 cfg_name = cfg->string; - E_TypeKey cfg_type_key = {0}; - { - U64 hash = d_hash_from_string(cfg_name); - U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; - for(RD_String2TypeKeyNode *n = rd_state->cfg_string2typekey_map->slots[slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->string, cfg_name, 0)) - { - cfg_type_key = n->key; - break; - } - } - } + E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); result.irtree_and_type.type_key = cfg_type_key; result.irtree_and_type.mode = E_Mode_Offset; @@ -9228,6 +9109,253 @@ E_LOOKUP_FUNCTION_DEF(top_level_cfg) return result; } +E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + String8 name = rd_singular_from_code_name_plural(lhs_type->name); + CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) + { + entity_kind = k; + break; + } + } + CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + CTRL_EntityList list__filtered = list; + if(filter.size != 0) + { + MemoryZeroStruct(&list__filtered); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); + if(matches.count == matches.needle_part_count) + { + ctrl_entity_list_push(scratch.arena, &list__filtered, entity); + } + } + } + CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); + *array = ctrl_entity_array_from_list(arena, &list__filtered); + result.user_data = array; + result.idxed_expr_count = list.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < entities->count) + { + CTRL_Entity *entity = entities->v[rhs_value.u64]; + E_Space entity_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 entity_name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey entity_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, entity_name); + result.irtree_and_type.root = e_irtree_set_space(arena, entity_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = entity_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; +struct RD_DebugInfoTableLookupAccel +{ + RDI_SectionKind section; + U64 rdis_count; + RDI_Parsed **rdis; + DI_SearchItemArray items; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) +{ + Temp scratch = scratch_begin(&arena, 1); + + // rjf: determine which debug info section we're dealing with + RDI_SectionKind section = RDI_SectionKind_NULL; + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + if(0){} + else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} + else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} + else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} + else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} + } + + // rjf: gather debug info table items + RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); + if(section != RDI_SectionKind_NULL) + { + U64 endt_us = d_state->frame_eval_memread_endt_us; + + //- 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(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: query all filtered items from dbgi searching system + U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; + B32 items_stale = 0; + DI_SearchParams params = {section, dbgi_keys}; + accel->section = section; + accel->rdis_count = rdis_count; + accel->rdis = rdis; + accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + if(items_stale) + { + rd_request_frame(); + } + } + E_LookupInfo info = {accel, 0, accel->items.count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + E_LookupRange result = {0}; + { + U64 needed_row_count = dim_1u64(idx_range); + result.exprs_count = Min(needed_row_count, accel->items.count); + result.exprs = push_array(arena, E_Expr *, result.exprs_count); + result.exprs_strings = push_array(arena, String8, result.exprs_count); + for EachIndex(idx, result.exprs_count) + { + // rjf: unpack row + DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; + + // rjf: skip bad elements + if(item->dbgi_idx >= accel->rdis_count) + { + continue; + } + + // rjf: unpack row info + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; + + // rjf: build expr + E_Expr *item_expr = &e_expr_nil; + { + U64 element_idx = item->idx; + switch(accel->section) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); + RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Value; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_GlobalVariables: + { + RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); + U64 voff = gvar->voff; + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = gvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_ThreadVariables: + { + RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = tvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_UDTs: + { + RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + item_expr->type_key = type_key; + }break; + } + } + + // rjf: fill + result.exprs[idx] = item_expr; + } + } + return result; +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 id = 0; + if(0 < num && num <= accel->items.count) + { + id = accel->items.v[num-1].idx+1; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); + return num; +} + internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind) { @@ -9394,230 +9522,6 @@ rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view return info; } -internal EV_ExpandRangeInfo -rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->entities.count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - CTRL_Entity *entity = accel->entities.v[idx_range.min + row_expr_idx]; - String8 entity_expr_string = push_str8f(arena, "ctrl_entity:$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, entity_expr_string); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(U64 num, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - U64 id = 0; - if(1 <= num && num <= accel->entities.count) - { - id = d_hash_from_string(str8_struct(&accel->entities.v[num-1]->handle)); - } - return id; -} - -internal U64 -rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = (RD_CtrlEntityExpandAccel *)user_data; - U64 num = 0; - if(id != 0) - { - for EachIndex(idx, accel->entities.count) - { - U64 idx_id = d_hash_from_string(str8_struct(&accel->entities.v[idx]->handle)); - if(idx_id == id) - { - num = idx+1; - break; - } - } - } - return num; -} - -typedef struct RD_DebugInfoTableExpandAccel RD_DebugInfoTableExpandAccel; -struct RD_DebugInfoTableExpandAccel -{ - U64 rdis_count; - RDI_Parsed **rdis; - DI_SearchItemArray items; -}; - -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) -{ - RD_DebugInfoTableExpandAccel *accel = push_array(arena, RD_DebugInfoTableExpandAccel, 1); - if(section != RDI_SectionKind_NULL) - { - Temp scratch = scratch_begin(&arena, 1); - 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(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: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {(U64)view, (U64)section}; - B32 items_stale = 0; - DI_SearchParams params = {section, dbgi_keys}; - accel->rdis_count = rdis_count; - accel->rdis = rdis; - accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - - scratch_end(scratch); - } - EV_ExpandInfo info = {accel, accel->items.count}; - return info; -} - -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) -{ - RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->items.count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - // rjf: unpack row - DI_SearchItem *item = &accel->items.v[idx_range.min + row_expr_idx]; - - // rjf: skip bad elements - if(item->dbgi_idx >= accel->rdis_count) - { - continue; - } - - // rjf: unpack row info - RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; - - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; - { - U64 element_idx = item->idx; - switch(section) - { - default:{}break; - case RDI_SectionKind_Procedures: - { - RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); - RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_GlobalVariables: - { - RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_ThreadVariables: - { - RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_UDTs: - { - RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; - }break; - } - } - - // rjf: fill - result.row_exprs[row_expr_idx] = item_expr; - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section) -{ - 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 id, void *user_data, RDI_SectionKind section) -{ - RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); - return num; -} - 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) { @@ -13161,6 +13065,7 @@ rd_frame(void) ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); //- rjf: add macros for collections +#if 0 // TODO(rjf): @cfg { for EachElement(idx, rd_collection_name_table) { @@ -13170,34 +13075,45 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, rd_collection_name_table[idx], expr); } } +#endif - //- rjf: choose set of evallable config names - String8 evallable_cfg_names[] = + //- rjf: choose set of evallable meta names + String8 evallable_meta_names[] = { str8_lit("breakpoint"), str8_lit("watch_pin"), str8_lit("target"), str8_lit("file_path_map"), str8_lit("auto_view_rule"), + str8_lit("machine"), + str8_lit("process"), + str8_lit("thread"), + str8_lit("module"), }; - //- rjf: build special member types for evallable config types + //- rjf: build special member types for evallable meta types E_TypeKey bool_type_key = {0}; E_TypeKey u64_type_key = {0}; + E_TypeKey vaddr_range_type_key = {0}; E_TypeKey code_string_type_key = {0}; E_TypeKey path_type_key = {0}; E_TypeKey string_type_key = {0}; E_TypeKey location_type_key = {0}; { + E_MemberList vaddr_range_members_list = {0}; + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min")); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max")); + E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); bool_type_key = e_type_key_basic(E_TypeKind_Bool); u64_type_key = e_type_key_basic(E_TypeKind_U64); + vaddr_range_type_key = e_type_key_cons(E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsCodeText); path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPathText); string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText); location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); } - //- rjf: build types for each evallable config tree + //- rjf: build types for each evallable meta name struct { String8 schema_type_name; @@ -13207,15 +13123,16 @@ rd_frame(void) { { str8_lit("bool"), bool_type_key }, { str8_lit("u64"), u64_type_key }, + { str8_lit("vaddr_range"), vaddr_range_type_key }, { str8_lit("code_string"), code_string_type_key }, { str8_lit("path"), path_type_key }, { str8_lit("string"), string_type_key }, { str8_lit("location"), location_type_key }, }; - E_TypeKey evallable_cfg_types[ArrayCount(evallable_cfg_names)] = {0}; - for EachElement(idx, evallable_cfg_names) + E_TypeKey evallable_meta_types[ArrayCount(evallable_meta_names)] = {0}; + for EachElement(idx, evallable_meta_names) { - String8 name = evallable_cfg_names[idx]; + String8 name = evallable_meta_names[idx]; MD_Node *schema = rd_schema_from_name(scratch.arena, name); E_MemberList members_list = {0}; U64 off = 0; @@ -13240,29 +13157,31 @@ rd_frame(void) off += e_type_byte_size_from_key(member_type_key); } E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); - evallable_cfg_types[idx] = e_type_key_cons(.name = name, - .kind = E_TypeKind_Struct, - .members = members.v, - .count = members.count); + evallable_meta_types[idx] = e_type_key_cons(.name = name, + .kind = E_TypeKind_Struct, + .members = members.v, + .count = members.count); } - //- rjf: cache cfg name -> type key correllation - rd_state->cfg_string2typekey_map = push_array(rd_frame_arena(), RD_String2TypeKeyMap, 1); - rd_state->cfg_string2typekey_map->slots_count = 256; - rd_state->cfg_string2typekey_map->slots = push_array(rd_frame_arena(), RD_String2TypeKeySlot, rd_state->cfg_string2typekey_map->slots_count); - for EachElement(idx, evallable_cfg_names) + //- rjf: cache meta name -> type key correllation + rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); + rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); + for EachElement(idx, evallable_meta_names) { - String8 name = evallable_cfg_names[idx]; - E_TypeKey type_key = evallable_cfg_types[idx]; - U64 hash = d_hash_from_string(name); - U64 slot_idx = hash%rd_state->cfg_string2typekey_map->slots_count; - RD_String2TypeKeyNode *node = push_array(rd_frame_arena(), RD_String2TypeKeyNode, 1); - node->string = push_str8_copy(rd_frame_arena(), name); - node->key = type_key; - SLLQueuePush(rd_state->cfg_string2typekey_map->slots[slot_idx].first, rd_state->cfg_string2typekey_map->slots[slot_idx].last, node); + String8 name = evallable_meta_names[idx]; + E_TypeKey type_key = evallable_meta_types[idx]; + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); } - //- rjf: add macros for each evallable config tree + //- rjf: add macros for evallable config trees + String8 evallable_cfg_names[] = + { + str8_lit("breakpoint"), + str8_lit("watch_pin"), + str8_lit("target"), + str8_lit("file_path_map"), + str8_lit("auto_view_rule"), + }; for EachElement(idx, evallable_cfg_names) { String8 name = evallable_cfg_names[idx]; @@ -13276,7 +13195,7 @@ rd_frame(void) E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = space; expr->mode = E_Mode_Offset; - expr->type_key = evallable_cfg_types[idx]; + expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); if(exe.size != 0) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); @@ -13285,70 +13204,98 @@ rd_frame(void) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); } - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x%I64x", (U64)cfg, cfg->gen), expr); } } - //- rjf: add macros for all evallable control entities + //- rjf: add macros for evallable control entities + String8 evallable_ctrl_names[] = { - CTRL_EntityKind evallable_kinds[] = + str8_lit("machine"), + str8_lit("process"), + str8_lit("thread"), + str8_lit("module"), + }; + for EachElement(idx, evallable_ctrl_names) + { + String8 name = evallable_ctrl_names[idx]; + CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); + CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) { - CTRL_EntityKind_Machine, - CTRL_EntityKind_Process, - CTRL_EntityKind_Thread, - CTRL_EntityKind_Module, - }; - E_TypeKey evallable_kind_types[] = - { - e_type_key_cons_base(type(CTRL_MachineMetaEval)), - e_type_key_cons_base(type(CTRL_ProcessMetaEval)), - e_type_key_cons_base(type(CTRL_ThreadMetaEval)), - e_type_key_cons_base(type(CTRL_ModuleMetaEval)), - }; - for EachElement(idx, evallable_kinds) - { - CTRL_EntityKind kind = evallable_kinds[idx]; - CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + CTRL_Entity *entity = n->v; + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + if(entity->string.size != 0) { - CTRL_Entity *entity = n->v; - E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = evallable_kind_types[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]), expr); - if(entity->string.size != 0) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); - } - if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); - } - if(kind == CTRL_EntityKind_Process && ctrl_handle_match(rd_base_regs()->process, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_process"), expr); - } - if(kind == CTRL_EntityKind_Module && ctrl_handle_match(rd_base_regs()->module, entity->handle)) - { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); - } + e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); + } + if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); + } + if(kind == CTRL_EntityKind_Process && ctrl_handle_match(rd_base_regs()->process, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_process"), expr); + } + if(kind == CTRL_EntityKind_Module && ctrl_handle_match(rd_base_regs()->module, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); } } } - //- rjf: add macros for watch groups + //- rjf: add macro for collections with specific lookup rules + struct { - String8 collection_name = str8_lit("watches"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + String8 name; + E_LookupInfoFunctionType *lookup_info; + E_LookupRangeFunctionType *lookup_range; + } + collection_infos[] = + { +#define Collection(name) {str8_lit_comp(#name), E_LOOKUP_INFO_FUNCTION_NAME(name), E_LOOKUP_RANGE_FUNCTION_NAME(name)} + Collection(watches), + Collection(locals), + Collection(registers), +#undef Collection + }; + for EachElement(idx, collection_infos) + { + String8 collection_name = collection_infos[idx].name; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = collection_type_key; + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(watch_group), E_LOOKUP_FUNCTION_NAME(watch_group)); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = collection_infos[idx].lookup_info, + .range = collection_infos[idx].lookup_range); } - //- rjf: add macros for all cfg collections (new @cfg) + //- rjf: add macros for debug info table collections + String8 debug_info_table_collection_names[] = + { + str8_lit_comp("procedures"), + str8_lit_comp("thread_locals"), + str8_lit_comp("globals"), + str8_lit_comp("types"), + }; + for EachElement(idx, debug_info_table_collection_names) + { + String8 name = debug_info_table_collection_names[idx]; + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(debug_info_table), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(debug_info_table), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(debug_info_table)); + } + + //- rjf: add macros for all config collections for EachElement(cfg_name_idx, evallable_cfg_names) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; @@ -13357,7 +13304,23 @@ rd_frame(void) E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), E_LOOKUP_FUNCTION_NAME(top_level_cfg)); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(top_level_cfg)); + } + + //- rjf: add macros for all ctrl entity collections + for EachElement(ctrl_name_idx, evallable_ctrl_names) + { + String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; + String8 collection_name = rd_plural_from_code_name(kind_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities)); } //- rjf: add macro for output log @@ -13846,7 +13809,7 @@ rd_frame(void) RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("targets[0]")); + rd_cfg_new(expr, str8_lit("current_thread")); } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index cc99431e..1d2e38f4 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -745,31 +745,6 @@ struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheNode *last; }; -//////////////////////////////// -//~ rjf: String -> Type Key Map Helper Data Structure - -typedef struct RD_String2TypeKeyNode RD_String2TypeKeyNode; -struct RD_String2TypeKeyNode -{ - RD_String2TypeKeyNode *next; - String8 string; - E_TypeKey key; -}; - -typedef struct RD_String2TypeKeySlot RD_String2TypeKeySlot; -struct RD_String2TypeKeySlot -{ - RD_String2TypeKeyNode *first; - RD_String2TypeKeyNode *last; -}; - -typedef struct RD_String2TypeKeyMap RD_String2TypeKeyMap; -struct RD_String2TypeKeyMap -{ - U64 slots_count; - RD_String2TypeKeySlot *slots; -}; - //////////////////////////////// //~ rjf: Config -> Eval Blob Cache Types @@ -864,8 +839,8 @@ struct RD_State RD_Theme *theme; RD_Theme *theme_target; - // rjf: config name -> eval type key map (constructed from-scratch each frame) - RD_String2TypeKeyMap *cfg_string2typekey_map; + // 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) RD_Cfg2EvalBlobMap *cfg2evalblob_map; @@ -1328,9 +1303,6 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg); -E_LOOKUP_FUNCTION_DEF(top_level_cfg); - internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind); internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top); internal U64 rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top); @@ -1341,11 +1313,6 @@ internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_ctrl_en internal U64 rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(U64 num, void *user_data, CTRL_EntityKind kind); internal U64 rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CTRL_EntityKind kind); -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 id, void *user_data, RDI_SectionKind section); - 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); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 35bf5d39..e13a55f7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -27,6 +27,7 @@ // but only with commands that are directly // // [ ] r8 bitmap view rule seems incorrect? +// [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) //////////////////////////////// //~ rjf: post-0.9.12 TODO notes From 07c9268941c346eac76a9a41f9ef31ee6e45022f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 1 Feb 2025 20:50:31 -0800 Subject: [PATCH 040/755] eval: specify formal way in which tags (view rules) can fit into expression language, both in parsing & in structure; introduce ir-generation hook step in eval pipeline, transfer most of the default non-vbisualization view rule features to that layer --- src/eval/eval.mdesk | 4 + src/eval/eval_ir.c | 318 ++++++++++++++++++++++++++++----- src/eval/eval_ir.h | 91 +++++++++- src/eval/eval_parse.c | 159 ++++++++++++++++- src/eval/eval_parse.h | 4 + src/eval/generated/eval.meta.c | 8 +- src/eval/generated/eval.meta.h | 6 +- 7 files changed, 536 insertions(+), 54 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 05737d53..ffb12495 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -117,6 +117,8 @@ E_ExprKindTable: { Ternary Null 0 "? " "" "?" ":"} + { Call Null 0 "()" "(" "," ")"} + { LeafBytecode Null 0 "bytecode" "" "" "" } { LeafMember Null 0 "member" "" "" "" } { LeafStringLiteral Null 0 "string_literal" "" "" "" } @@ -136,6 +138,8 @@ E_ExprKindTable: { Line Binary 1 ":" "" ":" "" } { Define Binary 13 "=" "" "=" "" } + + { Tag Null 0 "=>" "=>" "," "" } } @table(name display_string) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 55610b1a..766675e7 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -455,6 +455,196 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) return id; } +//////////////////////////////// +//~ rjf: IR Gen Rules + +E_IRGEN_FUNCTION_DEF(cast) +{ + E_Expr *type_expr = tag->first->next; + E_TypeKey type_key = e_type_from_expr(type_expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRTreeAndType result = {irtree.root, type_key, irtree.mode, irtree.msgs}; + return result; +} + +E_IRGEN_FUNCTION_DEF(bswap) +{ + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); + e_irnode_push_child(root, irtree.root); + E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs}; + return result; +} + +E_IRGEN_FUNCTION_DEF(array) +{ + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_TypeKey type_key = irtree.type_key; + E_TypeKind type_kind = e_type_kind_from_key(type_key); + if(e_type_kind_is_pointer_or_ref(type_kind)) + { + Temp scratch = scratch_begin(&arena, 1); + E_Eval count_eval = e_eval_from_expr(scratch.arena, tag->first->next); + E_TypeKey element_type_key = e_type_ptee_from_key(type_key); + E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count_eval.value.u64); + E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); + irtree.type_key = ptr_type_key; + scratch_end(scratch); + } + return irtree; +} + +E_IRGEN_FUNCTION_DEF(slice) +{ + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key); + if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) + { + // rjf: unpack members + E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key); + + // rjf: choose base pointer & count members + E_Member *base_ptr_member = 0; + E_Member *count_member = 0; + for(U64 idx = 0; idx < members.count; idx += 1) + { + E_Member *member = &members.v[idx]; + E_TypeKey member_type = e_type_unwrap(member->type_key); + E_TypeKind member_type_kind = e_type_kind_from_key(member_type); + if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) + { + count_member = member; + } + if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + base_ptr_member = &members.v[idx]; + } + if(count_member != 0 && base_ptr_member != 0) + { + break; + } + } + + // rjf: evaluate count member, determine count + U64 count = 0; + if(count_member != 0) + { + E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name); + E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr); + E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval); + count = count_member_value_eval.value.u64; + } + + // rjf: generate new struct slice type + E_TypeKey slice_type_key = zero_struct; + if(base_ptr_member != 0 && count_member != 0) + { + String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key); + E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key); + E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count); + E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); + E_MemberList slice_type_members = {0}; + e_member_list_push(scratch.arena, &slice_type_members, count_member); + e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off}); + E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members); + slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch, + .kind = E_TypeKind_Struct, + .name = struct_name, + .members = slice_type_members_array.v, + .count = slice_type_members_array.count); + } + + // rjf: overwrite type + irtree.type_key = slice_type_key; + } + scratch_end(scratch); + return irtree; +} + +E_IRGEN_FUNCTION_DEF(wrap) +{ + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr_to_irify = expr; + E_Expr *wrap_expr_src = tag->first->next; + if(wrap_expr_src != &e_expr_nil) + { + expr_to_irify = e_expr_copy(scratch.arena, wrap_expr_src); + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *parent; + E_Expr *expr; + }; + Task start_task = {0, &e_expr_nil, expr_to_irify}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + { + E_Expr *original_expr_ref = e_expr_ref(arena, expr); + if(t->parent != &e_expr_nil) + { + e_expr_insert_child(t->parent, t->expr, original_expr_ref); + e_expr_remove_child(t->parent, t->expr); + } + } + else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = t->expr; + task->expr = child; + } + } + } + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr_to_irify); + scratch_end(scratch); + return irtree; +} + +internal E_IRGenRuleMap +e_irgen_rule_map_make(Arena *arena, U64 slots_count) +{ + E_IRGenRuleMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); + return map; +} + +internal void +e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule) +{ + U64 hash = e_hash_from_string(5381, rule->name); + U64 slot_idx = hash%map->slots_count; + E_IRGenRuleNode *n = push_array(arena, E_IRGenRuleNode, 1); + MemoryCopyStruct(&n->v, rule); + n->v.name = push_str8_copy(arena, n->v.name); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); +} + +internal E_IRGenRule * +e_irgen_rule_from_string(String8 string) +{ + E_IRGenRule *rule = &e_irgen_rule__default; + { + E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map; + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(string, n->v.name, 0)) + { + rule = &n->v; + break; + } + } + } + return rule; +} + //////////////////////////////// //~ rjf: IR-ization Functions @@ -752,8 +942,7 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type //- rjf: top-level irtree/type extraction -internal E_IRTreeAndType -e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr) +E_IRGEN_FUNCTION_DEF(default) { E_IRTreeAndType result = {&e_irnode_nil}; E_ExprKind kind = expr->kind; @@ -764,7 +953,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr //- rjf: references -> just descend to sub-expr case E_ExprKind_Ref: { - result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref); + result = e_irtree_and_type_from_expr(arena, expr->ref); }break; //- rjf: accesses @@ -793,7 +982,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_direct_from_key(r_type); @@ -848,7 +1037,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_unwrap(r_type); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); @@ -879,7 +1068,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr E_TypeKey cast_type = e_type_from_expr(cast_type_expr); E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr__space(arena, current_space, casted_expr); + E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -945,7 +1134,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr }break; default: { - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; }break; @@ -975,7 +1164,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -989,7 +1178,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1017,7 +1206,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr //- rjf: unary operations case E_ExprKind_Pos: { - result = e_irtree_and_type_from_expr__space(arena, current_space, expr->first); + result = e_irtree_and_type_from_expr(arena, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_LogNot: @@ -1025,7 +1214,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1080,8 +1269,8 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key)); @@ -1304,9 +1493,9 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_irtree_and_type_from_expr__space(arena, current_space, c_expr); - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr); + E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr); + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1350,6 +1539,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr case E_ExprKind_LeafBytecode: { E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode); + new_tree->space = expr->space; E_TypeKey final_type_key = expr->type_key; result.root = new_tree; result.type_key = final_type_key; @@ -1427,7 +1617,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr else { e_string2expr_map_inc_poison(e_ir_ctx->macro_map, expr->string); - result = e_irtree_and_type_from_expr__space(arena, current_space, macro_expr); + result = e_irtree_and_type_from_expr(arena, macro_expr); e_string2expr_map_dec_poison(e_ir_ctx->macro_map, expr->string); } }break; @@ -1437,6 +1627,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); new_tree->value.u64 = expr->value.u64; + new_tree->space = expr->space; result.root = new_tree; result.type_key = expr->type_key; result.mode = E_Mode_Offset; @@ -1449,8 +1640,8 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; U64 size = fs_size_from_path(expr->string); E_IRNode *base_offset = e_irtree_const_u(arena, 0); - E_IRNode *set_space = e_irtree_set_space(arena, space, base_offset); - result.root = set_space; + base_offset->space = space; + result.root = base_offset; result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); result.mode = E_Mode_Offset; }break; @@ -1459,6 +1650,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr case E_ExprKind_TypeIdent: { result.root = e_irtree_const_u(arena, 0); + result.root->space = expr->space; result.type_key = expr->type_key; result.mode = E_Mode_Null; }break; @@ -1476,7 +1668,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { E_Expr *lhs = expr->first; E_Expr *rhs = expr->last; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr__space(arena, current_space, lhs); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); U64 line_num = rhs->value.u64; B32 space_is_good = 1; E_Space space = {0}; @@ -1506,10 +1698,10 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr Rng1U64 line_range = text_info.lines_ranges[line_num-1]; U64 line_size = dim_1u64(line_range); E_IRNode *line_offset = e_irtree_const_u(arena, line_range.min); - E_IRNode *set_space = e_irtree_set_space(arena, space, line_offset); - result.root = set_space; - result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size); - result.mode = E_Mode_Offset; + result.root = line_offset; + result.root->space = space; + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size); + result.mode = E_Mode_Offset; } else { @@ -1524,41 +1716,82 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_irtree_and_type_from_expr__space(arena, current_space, rhs); + result = e_irtree_and_type_from_expr(arena, rhs); if(lhs->kind != E_ExprKind_LeafIdent) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); } }break; } - - //- rjf: if the expression's space does not match the current, then push a set-space node - // before returning - E_Space zero_space = zero_struct; - if(!MemoryMatchStruct(current_space, &expr->space) && - !MemoryMatchStruct(&zero_space, &expr->space)) - { - result.root = e_irtree_set_space(arena, expr->space, result.root); - *current_space = expr->space; - } - return result; } internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { - E_Space space = e_interpret_ctx->primary_space; - E_IRTreeAndType result = e_irtree_and_type_from_expr__space(arena, &space, expr); + E_IRTreeAndType result = {&e_irnode_nil}; + E_IRGenRule *irgen_rule = &e_irgen_rule__default; + E_Expr *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; + E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); + if(irgen_rule_candidate != &e_irgen_rule__default) + { + B32 tag_is_poisoned = 0; + U64 hash = e_hash_from_string(5381, str8_struct(&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 == tag) + { + tag_is_poisoned = 1; + break; + } + } + 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; + break; + } + } + } + result = irgen_rule->irgen(arena, expr, irgen_rule_tag); + if(irgen_rule_tag != &e_expr_nil) + { + 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) + { + if(n->tag == irgen_rule_tag) + { + DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n); + break; + } + } + } return result; } //- rjf: irtree -> linear ops/bytecode internal void -e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) +e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out) { U32 op = root->op; + { + E_Space zero_space = zero_struct; + if(!MemoryMatchStruct(&root->space, &zero_space) && + !MemoryMatchStruct(&root->space, current_space)) + { + *current_space = root->space; + e_oplist_push_set_space(arena, out, root->space); + } + } switch(op) { case RDI_EvalOp_Stop: @@ -1581,7 +1814,7 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) child != &e_irnode_nil; child = child->next) { - e_append_oplist_from_irtree(arena, child, out); + e_append_oplist_from_irtree(arena, child, current_space, out); } }break; @@ -1632,7 +1865,7 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out) child != &e_irnode_nil && idx < child_count; child = child->next, idx += 1) { - e_append_oplist_from_irtree(arena, child, out); + e_append_oplist_from_irtree(arena, child, current_space, out); } // rjf: emit op to compute this node @@ -1646,7 +1879,8 @@ internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root) { E_OpList ops = {0}; - e_append_oplist_from_irtree(arena, root, &ops); + E_Space space = e_interpret_ctx->primary_space; + e_append_oplist_from_irtree(arena, root, &space, &ops); return ops; } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index eef75238..3bbb6f63 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -42,6 +42,7 @@ struct E_IRNode E_IRNode *last; E_IRNode *next; RDI_EvalOp op; + E_Space space; String8 string; E_Value value; }; @@ -84,31 +85,30 @@ struct E_LookupRange #define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name #define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); +E_LOOKUP_INFO_FUNCTION_DEF(default); #define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) #define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name #define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); +E_LOOKUP_ACCESS_FUNCTION_DEF(default); #define E_LOOKUP_RANGE_FUNCTION_SIG(name) E_LookupRange name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, void *user_data) #define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name #define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); +E_LOOKUP_RANGE_FUNCTION_DEF(default); #define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) #define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name #define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); #define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) #define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name #define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); - -E_LOOKUP_INFO_FUNCTION_DEF(default); -E_LOOKUP_ACCESS_FUNCTION_DEF(default); -E_LOOKUP_RANGE_FUNCTION_DEF(default); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); typedef struct E_LookupRule E_LookupRule; @@ -143,6 +143,68 @@ struct E_LookupRuleMap U64 slots_count; }; +//////////////////////////////// +//~ rjf: IR Generation Hooks + +#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag) +#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name +#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) +typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); +E_IRGEN_FUNCTION_DEF(default); + +typedef struct E_IRGenRule E_IRGenRule; +struct E_IRGenRule +{ + String8 name; + E_IRGenFunctionType *irgen; +}; + +typedef struct E_IRGenRuleNode E_IRGenRuleNode; +struct E_IRGenRuleNode +{ + E_IRGenRuleNode *next; + E_IRGenRule v; +}; + +typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; +struct E_IRGenRuleSlot +{ + E_IRGenRuleNode *first; + E_IRGenRuleNode *last; +}; + +typedef struct E_IRGenRuleMap E_IRGenRuleMap; +struct E_IRGenRuleMap +{ + U64 slots_count; + E_IRGenRuleSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Used Tag Map Data Structure + +typedef struct E_UsedTagNode E_UsedTagNode; +struct E_UsedTagNode +{ + E_UsedTagNode *next; + E_UsedTagNode *prev; + E_Expr *tag; +}; + +typedef struct E_UsedTagSlot E_UsedTagSlot; +struct E_UsedTagSlot +{ + E_UsedTagNode *first; + E_UsedTagNode *last; +}; + +typedef struct E_UsedTagMap E_UsedTagMap; +struct E_UsedTagMap +{ + U64 slots_count; + E_UsedTagSlot *slots; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -151,6 +213,8 @@ struct E_IRCtx { E_String2ExprMap *macro_map; E_LookupRuleMap *lookup_rule_map; + E_IRGenRuleMap *irgen_rule_map; + E_UsedTagMap *used_tag_map; }; //////////////////////////////// @@ -165,6 +229,11 @@ local_persist read_only E_LookupRule e_lookup_rule__default = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), }; +local_persist read_only E_IRGenRule e_irgen_rule__default = +{ + str8_lit_comp("default"), + E_IRGEN_FUNCTION_NAME(default), +}; global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRCtx *e_ir_ctx = 0; @@ -189,6 +258,15 @@ internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_Loo internal E_LookupRule *e_lookup_rule_from_string(String8 string); +//////////////////////////////// +//~ rjf: IR Gen Rules + +internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count); +internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule); +#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__}) + +internal E_IRGenRule *e_irgen_rule_from_string(String8 string); + //////////////////////////////// //~ rjf: IR-ization Functions @@ -221,11 +299,10 @@ internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); //- rjf: top-level irtree/type extraction -internal E_IRTreeAndType e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr); internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); //- rjf: irtree -> linear ops/bytecode -internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out); +internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root); internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 60f31be4..12e4ea03 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -15,6 +15,7 @@ global read_only String8 e_multichar_symbol_strings[] = str8_lit_comp("!="), str8_lit_comp("&&"), str8_lit_comp("||"), + str8_lit_comp("=>"), }; global read_only S64 e_max_precedence = 15; @@ -649,7 +650,7 @@ internal E_Expr * e_push_expr(Arena *arena, E_ExprKind kind, void *location) { E_Expr *e = push_array(arena, E_Expr, 1); - e->first = e->last = e->next = e->ref = &e_expr_nil; + e->first = e->last = e->next = e->ref = e->first_tag = e->last_tag = &e_expr_nil; e->location = location; e->kind = kind; return e; @@ -673,6 +674,12 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child) DLLRemove_NPZ(&e_expr_nil, parent->first, parent->last, child, next, prev); } +internal void +e_expr_push_tag(E_Expr *parent, E_Expr *child) +{ + DLLPushBack_NPZ(&e_expr_nil, parent->first_tag, parent->last_tag, child, next, prev); +} + internal E_Expr * e_expr_ref(Arena *arena, E_Expr *ref) { @@ -744,6 +751,78 @@ e_expr_ref_bswap(Arena *arena, E_Expr *rhs) return root; } +internal E_Expr * +e_expr_copy(Arena *arena, E_Expr *src) +{ + E_Expr *result = &e_expr_nil; + Temp scratch = scratch_begin(&arena, 1); + { + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *dst_parent; + E_Expr *src; + B32 is_ref; + B32 is_tag; + }; + Task start_task = {0, &e_expr_nil, src}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->location); + dst->mode = t->src->mode; + dst->space = t->src->space; + dst->type_key = t->src->type_key; + dst->value = t->src->value; + dst->string = push_str8_copy(arena, t->src->string); + dst->bytecode = push_str8_copy(arena, t->src->bytecode); + if(t->dst_parent == &e_expr_nil) + { + result = dst; + } + else if(t->is_ref) + { + t->dst_parent->ref = dst; + } + else if(t->is_tag) + { + e_expr_push_tag(t->dst_parent, dst); + } + else + { + e_expr_push_child(t->dst_parent, dst); + } + if(t->src->ref != &e_expr_nil) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = t->src->ref; + task->is_ref = 1; + SLLQueuePush(first_task, last_task, task); + } + for(E_Expr *src_child = t->src->first; src_child != &e_expr_nil; src_child = src_child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = src_child; + SLLQueuePush(first_task, last_task, task); + } + for(E_Expr *src_child = t->src->first_tag; src_child != &e_expr_nil; src_child = src_child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = src_child; + task->is_tag = 1; + SLLQueuePush(first_task, last_task, task); + } + } + } + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Expression Tree -> String Conversions @@ -1943,6 +2022,44 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + // rjf: calls + if(token.kind == E_TokenKind_Symbol && + str8_match(token_string, str8_lit("("), 0)) + { + it += 1; + E_Expr *callee_expr = atom; + E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); + e_expr_push_child(call_expr, callee_expr); + for(B32 done = 0; !done && it < it_opl;) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0)) + { + done = 1; + it += 1; + } + else + { + E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence); + e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs); + if(arg_parse.expr != &e_expr_nil) + { + e_expr_push_child(call_expr, arg_parse.expr); + } + it = arg_parse.last_token; + E_Token maybe_comma = e_token_at_it(it, tokens); + String8 maybe_comma_string = str8_substr(text, token.range); + if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) + { + it += 1; + } + } + } + atom = call_expr; + } + // rjf: quit if this doesn't look like any patterns of postfix unary we know if(!is_postfix_unary) { @@ -2100,6 +2217,46 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //- rjf: parse tags + { + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) + { + for(B32 done = 0; !done && it < it_opl;) + { + E_Token maybe_identifier = e_token_at_it(it, tokens); + E_Token maybe_open_paren = e_token_at_it(it+1, tokens); + String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range); + if(maybe_identifier.kind == E_TokenKind_Identifier && + maybe_open_paren.kind == E_TokenKind_Symbol && + str8_match(maybe_open_paren_string, str8_lit("("), 0)) + { + E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens); + e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs); + it = tag_parse.last_token; + if(tag_parse.expr != &e_expr_nil) + { + e_expr_push_tag(atom, tag_parse.expr); + } + else + { + done = 1; + } + E_Token maybe_comma = e_token_at_it(it, tokens); + String8 maybe_comma_string = str8_substr(text, token.range); + if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) + { + it += 1; + } + } + else + { + done = 1; + } + } + } + } + // rjf: if we parsed nothing successfully, we're done if(it == start_it) { diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 9f46e6f7..f4ee3afe 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -52,6 +52,8 @@ struct E_Expr { E_Expr *first; E_Expr *last; + E_Expr *first_tag; + E_Expr *last_tag; E_Expr *next; E_Expr *prev; E_Expr *ref; @@ -218,6 +220,7 @@ internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location); internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); +internal void e_expr_push_tag(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); internal E_Expr *e_expr_ref_addr(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name); @@ -225,6 +228,7 @@ internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index); 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); //////////////////////////////// //~ rjf: Expression Tree -> String Conversions diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index eec6b7bc..673119c9 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[49] = +String8 e_expr_kind_strings[51] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -49,6 +49,7 @@ str8_lit_comp("BitOr"), str8_lit_comp("LogAnd"), str8_lit_comp("LogOr"), str8_lit_comp("Ternary"), +str8_lit_comp("Call"), str8_lit_comp("LeafBytecode"), str8_lit_comp("LeafMember"), str8_lit_comp("LeafStringLiteral"), @@ -65,6 +66,7 @@ str8_lit_comp("Array"), str8_lit_comp("Func"), str8_lit_comp("Line"), str8_lit_comp("Define"), +str8_lit_comp("Tag"), }; String8 e_interpretation_code_display_strings[11] = @@ -82,7 +84,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[49] = +E_OpInfo e_expr_kind_op_info_table[51] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -117,6 +119,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") }, { E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") }, +{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -133,6 +136,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 1, str8_lit_comp(""), str8_lit_comp(":"), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; U8 e_kind_basic_byte_size_table[57] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 125d8245..f227b316 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -125,6 +125,7 @@ E_ExprKind_BitOr, E_ExprKind_LogAnd, E_ExprKind_LogOr, E_ExprKind_Ternary, +E_ExprKind_Call, E_ExprKind_LeafBytecode, E_ExprKind_LeafMember, E_ExprKind_LeafStringLiteral, @@ -141,6 +142,7 @@ E_ExprKind_Array, E_ExprKind_Func, E_ExprKind_Line, E_ExprKind_Define, +E_ExprKind_Tag, E_ExprKind_COUNT, } E_ExprKindEnum; @@ -162,9 +164,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[49]; +extern String8 e_expr_kind_strings[51]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[49]; +extern E_OpInfo e_expr_kind_op_info_table[51]; extern U8 e_kind_basic_byte_size_table[57]; extern String8 e_kind_basic_string_table[57]; From 5bbd9f1c7ee347ce8d5e104063d7ef35b3595f5e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 2 Feb 2025 12:46:59 -0800 Subject: [PATCH 041/755] eliminate expr resolution hook in eval visualization layer; now succeeded by irgen hook --- .../eval_visualization.mdesk | 3 +- .../eval_visualization_builtin_view_rules.c | 287 +----------------- .../eval_visualization_core.c | 13 - .../eval_visualization_core.h | 8 - .../generated/eval_visualization.meta.c | 28 +- .../generated/eval_visualization.meta.h | 7 - src/raddbg/raddbg_core.c | 2 - 7 files changed, 21 insertions(+), 327 deletions(-) diff --git a/src/eval_visualization/eval_visualization.mdesk b/src/eval_visualization/eval_visualization.mdesk index 3fa5a06a..6a202e77 100644 --- a/src/eval_visualization/eval_visualization.mdesk +++ b/src/eval_visualization/eval_visualization.mdesk @@ -115,7 +115,6 @@ EV_ViewRuleTable: @gen { - @expand(EV_ViewRuleTable a) `$(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`; @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; } @@ -123,5 +122,5 @@ EV_ViewRuleTable: @data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table: { @expand(EV_ViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.xr != "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```; + ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```; } diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index d05dea15..44c535d0 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -282,13 +282,13 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) //- rjf: fill with lookups // else if(accel->lookup_rule != 0) - { - E_LookupRange lookup_range = accel->lookup_rule->range(arena, expr, idx_range, accel->lookup_user_data); - result.row_exprs_count = lookup_range.exprs_count; - result.row_exprs = lookup_range.exprs; - result.row_strings = lookup_range.exprs_strings; + { + E_LookupRange lookup_range = accel->lookup_rule->range(arena, expr, idx_range, accel->lookup_user_data); + result.row_exprs_count = lookup_range.exprs_count; + result.row_exprs = lookup_range.exprs; + result.row_strings = lookup_range.exprs_strings; result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); + result.row_members = push_array(arena, E_Member *, result.row_exprs_count); for EachIndex(row_expr_idx, result.row_exprs_count) { result.row_members[row_expr_idx] = &e_member_nil; @@ -298,27 +298,6 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) return result; } -//////////////////////////////// -//~ rjf: "array" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind)) - { - E_Value count = ev_value_from_params(params); - E_TypeKey element_type_key = e_type_ptee_from_key(type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count.u64); - E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); - expr = e_expr_ref_cast(arena, ptr_type_key, expr); - } - scratch_end(scratch); - return expr; -} - //////////////////////////////// //~ rjf: "list" @@ -333,257 +312,3 @@ EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list) EV_ExpandRangeInfo info = {0}; return info; } - -//////////////////////////////// -//~ rjf: "slice" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key); - if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) - { - // rjf: unpack members - E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key); - - // rjf: choose base pointer & count members - E_Member *base_ptr_member = 0; - E_Member *count_member = 0; - for(U64 idx = 0; idx < members.count; idx += 1) - { - E_Member *member = &members.v[idx]; - E_TypeKey member_type = e_type_unwrap(member->type_key); - E_TypeKind member_type_kind = e_type_kind_from_key(member_type); - if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) - { - count_member = member; - } - if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) - { - base_ptr_member = &members.v[idx]; - } - if(count_member != 0 && base_ptr_member != 0) - { - break; - } - } - - // rjf: evaluate count member, determine count - U64 count = 0; - if(count_member != 0) - { - E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name); - E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr); - E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval); - count = count_member_value_eval.value.u64; - } - - // rjf: generate new struct slice type - E_TypeKey slice_type_key = zero_struct; - if(base_ptr_member != 0 && count_member != 0) - { - String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key); - E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count); - E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); - E_MemberList slice_type_members = {0}; - e_member_list_push(scratch.arena, &slice_type_members, count_member); - e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off}); - E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members); - slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch, - .kind = E_TypeKind_Struct, - .name = struct_name, - .members = slice_type_members_array.v, - .count = slice_type_members_array.count); - } - - // rjf: generate new expression tree - addr of struct, cast-to-ptr, deref - if(base_ptr_member != 0 && count_member != 0) - { - expr = e_expr_ref_addr(arena, expr); - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, slice_type_key, 0), expr); - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} - -//////////////////////////////// -//~ rjf: "bswap" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap) -{ - expr = e_expr_ref_bswap(arena, expr); - return expr; -} - -//////////////////////////////// -//~ rjf: "cast" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast) -{ - E_TypeKey type_key = ev_type_key_from_params(params); - expr = e_expr_ref_cast(arena, type_key, expr); - return expr; -} - -//////////////////////////////// -//~ rjf: "wrap" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap) -{ - String8 wrap_string = md_string_from_children(arena, params); - E_Expr *wrap_expr = e_parse_expr_from_text(arena, wrap_string); - E_Expr *new_root_expr = wrap_expr; - if(wrap_expr != &e_expr_nil) - { - Temp scratch = scratch_begin(&arena, 1); - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *parent; - E_Expr *expr; - }; - Task start_task = {0, &e_expr_nil, wrap_expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) - { - E_Expr *original_expr_ref = e_expr_ref(arena, expr); - if(t->parent != &e_expr_nil) - { - e_expr_insert_child(t->parent, t->expr, original_expr_ref); - e_expr_remove_child(t->parent, t->expr); - } - else - { - new_root_expr = original_expr_ref; - } - } - else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = t->expr; - task->expr = child; - } - } - scratch_end(scratch); - } - return new_root_expr; -} - -//////////////////////////////// -//~ rjf: "only" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_direct_from_key(type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind); - E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key; - E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind; - if(struct_type_kind == E_TypeKind_Struct || - struct_type_kind == E_TypeKind_Union || - struct_type_kind == E_TypeKind_Class) - { - E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList new_members = {0}; - for MD_EachNode(node, params->first) - { - for EachIndex(idx, current_members.count) - { - if(str8_match(node->string, current_members.v[idx].name, 0)) - { - e_member_list_push(scratch.arena, &new_members, ¤t_members.v[idx]); - break; - } - } - } - E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members); - E_TypeKey new_type = {0}; - if(new_members_array.count == 1 && new_members_array.v[0].off == 0) - { - new_type = new_members_array.v[0].type_key; - } - else - { - String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key); - new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count); - } - if(!is_ptr) - { - expr = e_expr_ref_addr(arena, expr); - } - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr); - if(!is_ptr) - { - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} - -//////////////////////////////// -//~ rjf: "omit" - -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_direct_from_key(type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind); - E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key; - E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind; - if(struct_type_kind == E_TypeKind_Struct || - struct_type_kind == E_TypeKind_Union || - struct_type_kind == E_TypeKind_Class) - { - E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList new_members = {0}; - for EachIndex(idx, current_members.count) - { - B32 include = 1; - for MD_EachNode(node, params->first) - { - if(str8_match(node->string, current_members.v[idx].name, 0)) - { - include = 0; - break; - } - } - if(include) - { - e_member_list_push(scratch.arena, &new_members, ¤t_members.v[idx]); - } - } - E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members); - E_TypeKey new_type = {0}; - String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key); - new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count); - if(!is_ptr) - { - expr = e_expr_ref_addr(arena, expr); - } - expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr); - if(!is_ptr) - { - expr = e_expr_ref_deref(arena, expr); - } - } - scratch_end(scratch); - return expr; -} diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 7e63d063..71925429 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -9,11 +9,6 @@ //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity) -{ - return expr; -} - EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil) { EV_ExpandInfo info = {0}; @@ -656,14 +651,6 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) } scratch_end(scratch); } - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->expr_resolution != 0) - { - expr = info->expr_resolution(arena, expr, n->v.root); - } - } ProfEnd(); return expr; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 45405d9a..2a1da35f 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -121,10 +121,6 @@ struct EV_ExpandRangeInfo E_Member **row_members; }; -#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(name) E_Expr *name(Arena *arena, E_Expr *expr, MD_Node *params) -#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_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params) #define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name #define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name)) @@ -141,7 +137,6 @@ struct EV_ExpandRangeInfo #define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) ev_view_rule_expr_expand_num_from_id_##name #define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name)) -typedef EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_ViewRuleExprResolutionHookFunctionType); typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType); typedef EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandRangeInfoHookFunctionType); typedef EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_ViewRuleExprExpandIDFromNumHookFunctionType); @@ -159,7 +154,6 @@ struct EV_ViewRuleInfo { String8 string; EV_ViewRuleInfoFlags flags; - EV_ViewRuleExprResolutionHookFunctionType *expr_resolution; EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; EV_ViewRuleExprExpandRangeInfoHookFunctionType *expr_expand_range_info; EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_id_from_num; @@ -329,7 +323,6 @@ enum //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil); EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); @@ -342,7 +335,6 @@ global read_only EV_ViewRuleInfo ev_nil_view_rule_info = { {0}, 0, - EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), diff --git a/src/eval_visualization/generated/eval_visualization.meta.c b/src/eval_visualization/generated/eval_visualization.meta.c index ad7776d0..d40c4a80 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.c +++ b/src/eval_visualization/generated/eval_visualization.meta.c @@ -6,20 +6,20 @@ C_LINKAGE_BEGIN EV_ViewRuleInfo ev_builtin_view_rule_info_table[14] = { -{str8_lit_comp("default"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(array) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(slice) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(bswap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(cast) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(wrap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(only) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(omit) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("default"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, }; C_LINKAGE_END diff --git a/src/eval_visualization/generated/eval_visualization.meta.h b/src/eval_visualization/generated/eval_visualization.meta.h index da13d9b4..b3283350 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.h +++ b/src/eval_visualization/generated/eval_visualization.meta.h @@ -25,13 +25,6 @@ EV_ViewRuleKind_NoAddress, EV_ViewRuleKind_COUNT, } EV_ViewRuleKind; -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only); -EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list); EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b92cc98f..21c67123 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13387,7 +13387,6 @@ rd_frame(void) EV_ViewRuleInfo info = {0}; info.string = rd_collection_name_table[idx]; info.flags = EV_ViewRuleInfoFlag_Expandable; - info.expr_resolution = EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity); info.expr_expand_info = rd_collection_expr_expand_info_hook_function_table[idx]; info.expr_expand_range_info = rd_collection_expr_expand_range_info_hook_function_table[idx]; info.expr_expand_id_from_num = rd_collection_expr_expand_id_from_num_hook_function_table[idx]; @@ -13404,7 +13403,6 @@ rd_frame(void) EV_ViewRuleInfo dst_info = {0}; dst_info.string = src_info->string; dst_info.flags = src_info->flags & RD_ViewRuleInfoFlag_CanExpand ? EV_ViewRuleInfoFlag_Expandable : 0; - dst_info.expr_resolution = EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity); dst_info.expr_expand_info = src_info->expr_expand_info; dst_info.expr_expand_range_info = EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil); dst_info.expr_expand_id_from_num = EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity); From eab5c7c9714b4fd263de4e39dd7a9fb498d6ff22 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 2 Feb 2025 14:39:43 -0800 Subject: [PATCH 042/755] eval_visualization: eliminate expansion-range hook; move expansions & block tree building completely to new eval hooks for lookups --- src/eval/eval_bundles.c | 4 +- src/eval/eval_ir.c | 94 ++- src/eval/eval_ir.h | 10 +- src/eval/eval_parse.c | 4 +- src/eval/eval_types.c | 12 +- src/eval/eval_types.h | 3 +- .../eval_visualization.mdesk | 6 +- .../eval_visualization_builtin_view_rules.c | 208 ------- .../eval_visualization_core.c | 466 ++++----------- .../eval_visualization_core.h | 100 +--- .../generated/eval_visualization.meta.c | 28 +- .../generated/eval_visualization.meta.h | 5 +- src/raddbg/generated/raddbg.meta.c | 42 -- src/raddbg/generated/raddbg.meta.h | 15 - src/raddbg/raddbg.mdesk | 76 --- src/raddbg/raddbg_core.c | 541 +++++------------- src/raddbg/raddbg_core.h | 14 +- src/raddbg/raddbg_views.c | 27 +- src/raddbg/raddbg_views.h | 4 + src/raddbg/raddbg_widgets.c | 3 +- 20 files changed, 384 insertions(+), 1278 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 15cf1087..2d112567 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -61,7 +61,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) if(string_idx == 0) { string_idx = gvar->name_string_idx; } if(string_idx != 0) { - eval.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 0); + eval.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); } } return eval; @@ -127,7 +127,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 0); + E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); eval.type_key = ptr_to_derived_type_key; } } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 766675e7..ffb4f0a0 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -130,14 +130,10 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) { - lookup_info.idxed_expr_count = 1; + E_Type *type = e_type_from_key(scratch.arena, lhs_type_key); + lookup_info.idxed_expr_count = type->count; E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key)); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Array) - { - E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); - lookup_info.idxed_expr_count = direct_type->count; - } if(direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Class || direct_type_kind == E_TypeKind_Union || @@ -155,6 +151,11 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); lookup_info.named_expr_count = lhs_type->count; } + else if(lhs_type_kind == E_TypeKind_Array) + { + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + lookup_info.idxed_expr_count = lhs_type->count; + } } scratch_end(scratch); return lookup_info; @@ -405,44 +406,83 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) E_LOOKUP_RANGE_FUNCTION_DEF(default) { - E_LookupRange result = {0}; Temp scratch = scratch_begin(&arena, 1); { + //- rjf: unpack type of expression E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Enum) + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + + //- rjf: pull out specific kinds of types + B32 do_struct_range = 0; + B32 do_index_range = 0; + E_TypeKey struct_type_key = zero_struct; + E_TypeKind struct_type_kind = E_TypeKind_Null; + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + if(lhs_type->count == 1 && + (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Enum)) + { + struct_type_key = direct_type_key; + struct_type_kind = direct_type_kind; + do_struct_range = 1; + } + else + { + do_index_range = 1; + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Enum) + { + struct_type_key = lhs_type_key; + struct_type_kind = lhs_type_kind; + do_struct_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Set) + { + do_index_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Array) + { + do_index_range = 1; + } + + //- rjf: struct case -> the lookup-range will return a range of members + if(do_struct_range) { E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); Rng1U64 legal_idx_range = r1u64(0, lhs_type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); - result.exprs_count = read_range_count; - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - for(U64 idx = 0; idx < result.exprs_count; idx += 1) + for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 member_idx = idx + read_range.min; String8 member_name = (lhs_type->members ? lhs_type->members[member_idx].name : lhs_type->enum_vals ? lhs_type->enum_vals[member_idx].name : str8_lit("")); - result.exprs[idx] = e_expr_ref_member_access(arena, lhs, member_name); + exprs[idx] = e_expr_ref_member_access(arena, lhs, member_name); } } - else if(lhs_type_kind == E_TypeKind_Set) + + //- rjf: ptr case -> the lookup-range will return a range of dereferences + else if(do_index_range) { - result.exprs_count = dim_1u64(idx_range); - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - result.exprs_strings = push_array(arena, String8, result.exprs_count); - for(U64 idx = 0; idx < result.exprs_count; idx += 1) + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) { - result.exprs[idx] = e_expr_ref_array_index(arena, lhs, idx_range.min + idx); + exprs[idx] = e_expr_ref_array_index(arena, lhs, idx_range.min + idx); } } } scratch_end(scratch); - return result; } E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default) @@ -486,8 +526,7 @@ E_IRGEN_FUNCTION_DEF(array) Temp scratch = scratch_begin(&arena, 1); E_Eval count_eval = e_eval_from_expr(scratch.arena, tag->first->next); E_TypeKey element_type_key = e_type_ptee_from_key(type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count_eval.value.u64); - E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); + E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_eval.value.u64, 0); irtree.type_key = ptr_type_key; scratch_end(scratch); } @@ -542,8 +581,7 @@ E_IRGEN_FUNCTION_DEF(slice) { String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key); E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key); - E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count); - E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0); + E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count, 0); E_MemberList slice_type_members = {0}; e_member_list_push(scratch.arena, &slice_type_members, count_member); e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off}); @@ -1055,7 +1093,7 @@ E_IRGEN_FUNCTION_DEF(default) // rjf: generate result.root = r_tree.root; - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 0); + result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 1, 0); result.mode = E_Mode_Value; }break; @@ -1414,7 +1452,7 @@ E_IRGEN_FUNCTION_DEF(default) E_TypeKey ptr_type = ptr_tree->type_key; if(ptr_is_decay) { - ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 0); + ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 1, 0); } E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); result.root = new_root; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 3bbb6f63..b788412f 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -73,14 +73,6 @@ struct E_LookupAccess E_IRTreeAndType irtree_and_type; }; -typedef struct E_LookupRange E_LookupRange; -struct E_LookupRange -{ - U64 exprs_count; - E_Expr **exprs; - String8 *exprs_strings; -}; - #define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs, String8 filter) #define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name #define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) @@ -93,7 +85,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(default); typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); E_LOOKUP_ACCESS_FUNCTION_DEF(default); -#define E_LOOKUP_RANGE_FUNCTION_SIG(name) E_LookupRange name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) #define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name #define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 12e4ea03..e2265042 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1041,7 +1041,7 @@ e_type_from_expr(E_Expr *expr) case E_ExprKind_Ptr: { E_TypeKey direct_type_key = e_type_from_expr(expr->first); - result = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, direct_type_key, 0); + result = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, direct_type_key, 1, 0); }break; case E_ExprKind_Array: { @@ -1356,7 +1356,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to else { E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - type->type_key = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 0); + type->type_key = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); E_Expr *casted = atom; E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); e_expr_push_child(cast, type); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 981581ee..7c91ce63 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -456,19 +456,12 @@ e_type_key_cons_array(E_TypeKey element_type_key, U64 count) } internal E_TypeKey -e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags) +e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags) { E_TypeKey key = e_type_key_cons(.arch = arch, .kind = E_TypeKind_Ptr, .flags = flags, .direct_key = element_type_key); return key; } -internal E_TypeKey -e_type_key_cons_space_ptr(E_TypeKey direct_type_key) -{ - E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_SpacePtr, .direct_key = direct_type_key); - return key; -} - internal E_TypeKey e_type_key_cons_base(Type *type) { @@ -489,7 +482,7 @@ e_type_key_cons_base(Type *type) if(type->flags & TypeFlag_IsPlainText){ flags |= E_TypeFlag_IsPlainText; } if(type->flags & TypeFlag_IsCodeText) { flags |= E_TypeFlag_IsCodeText; } if(type->flags & TypeFlag_IsPathText) { flags |= E_TypeFlag_IsPathText; } - result = e_type_key_cons_ptr(arch_from_context(), direct_type, flags); + result = e_type_key_cons_ptr(arch_from_context(), direct_type, 1, flags); }break; case TypeKind_Array: { @@ -804,6 +797,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->kind = kind; type->direct_type_key = direct_type_key; type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->count = 1; }break; case RDI_TypeKind_Array: diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index a8cbd1b1..89fb27b2 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -318,8 +318,7 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); //- rjf: constructed type construction helpers internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); -internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags); -internal E_TypeKey e_type_key_cons_space_ptr(E_TypeKey direct_type_key); +internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_base(Type *type); //- rjf: basic type key functions diff --git a/src/eval_visualization/eval_visualization.mdesk b/src/eval_visualization/eval_visualization.mdesk index 6a202e77..416018f1 100644 --- a/src/eval_visualization/eval_visualization.mdesk +++ b/src/eval_visualization/eval_visualization.mdesk @@ -91,7 +91,6 @@ @table(coverage_check name name_lower string ih ex xr xe display_name docs schema description) EV_ViewRuleTable: { - {x Default default "default" - - - x "Default" - "" "" } {x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } {x List list "list" - - - x "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } {x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." } @@ -109,6 +108,7 @@ EV_ViewRuleTable: @enum EV_ViewRuleKind: { + EV_ViewRuleKind_Null, @expand(EV_ViewRuleTable a) `$(a.name)`, COUNT, } @@ -116,11 +116,11 @@ EV_ViewRuleTable: @gen { @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; - @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; } @data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table: { + `{0}`, @expand(EV_ViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```; + ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") }```; } diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index 44c535d0..4618f35f 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -96,208 +96,6 @@ ev_arch_from_eval_params(E_Eval eval, MD_Node *params) return arch; } -//////////////////////////////// -//~ rjf: default - -typedef struct EV_DefaultExpandAccel EV_DefaultExpandAccel; -struct EV_DefaultExpandAccel -{ - E_MemberArray members; - E_EnumValArray enum_vals; - E_LookupRule *lookup_rule; - void *lookup_user_data; - U64 array_count; - B32 array_need_extra_deref; - B32 is_ptr2ptr; -}; - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default) -{ - Temp scratch = scratch_begin(&arena, 1); - U64 total_row_count = 0; - EV_DefaultExpandAccel *accel = push_array(arena, EV_DefaultExpandAccel, 1); - - //////////////////////////// - //- rjf: unpack expression type info - // - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_TypeKey type_key = e_type_unwrap(irtree.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - //////////////////////////// - //- rjf: structs/unions/classes -> expansions generate rows for all members - // - if((type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class) || - (e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class))) - { - E_TypeKey struct_type_key = e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key; - accel->members = e_type_data_members_from_key__cached(struct_type_key); - total_row_count = accel->members.count; - } - - //////////////////////////// - //- rjf: enums -> expansions generate rows for all members - // - else if(type_kind == E_TypeKind_Enum || - (e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Enum)) - { - E_Type *type = e_type_from_key(arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key); - accel->enum_vals.v = type->enum_vals; - accel->enum_vals.count = type->count; - total_row_count = accel->enum_vals.count; - } - - //////////////////////////// - //- rjf: arrays -> expansions generate rows for all elements - // - else if(type_kind == E_TypeKind_Array || - (e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Array)) - { - B32 need_extra_deref = e_type_kind_is_pointer_or_ref(type_kind); - E_Expr *array_expr = need_extra_deref ? e_expr_ref_deref(arena, expr) : expr; - E_Type *type = e_type_from_key(arena, need_extra_deref ? direct_type_key : type_key); - total_row_count = type->count; - accel->array_count = type->count; - accel->array_need_extra_deref = need_extra_deref; - } - - //////////////////////////// - //- rjf: pointer-to-pointer -> expansions generate dereference - // - else if(e_type_kind_is_pointer_or_ref(type_kind) && e_type_kind_is_pointer_or_ref(direct_type_kind)) - { - total_row_count = 1; - accel->is_ptr2ptr = 1; - } - - //////////////////////////// - //- rjf: sets -> expansions generate rows for all possible lookups - // - else if(type_kind == E_TypeKind_Set) - { - E_Type *type = e_type_from_key(scratch.arena, type_key); - E_LookupRule *rule = e_lookup_rule_from_string(type->name); - E_LookupInfo lookup_info = rule->info(arena, expr, filter); - total_row_count = Max(lookup_info.named_expr_count, lookup_info.idxed_expr_count); - accel->lookup_rule = rule; - accel->lookup_user_data = lookup_info.user_data; - } - - //////////////////////////// - //- rjf: package result - // - EV_ExpandInfo result = {0}; - { - result.user_data = accel; - result.row_count = total_row_count; - } - - scratch_end(scratch); - return result; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default) -{ - EV_DefaultExpandAccel *accel = (EV_DefaultExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - U64 needed_row_count = dim_1u64(idx_range); - - //////////////////////////// - //- rjf: fill with members - // - if(accel->members.count != 0) - { - E_MemberArray *members = &accel->members; - result.row_exprs_count = Min(needed_row_count, members->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - E_Member *member = &members->v[idx_range.min + row_expr_idx]; - result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, member->name); - result.row_members[row_expr_idx] = member; - } - } - - //////////////////////////// - //- rjf: fill with enum vals - // - else if(accel->enum_vals.count != 0) - { - E_EnumValArray *enumvals = &accel->enum_vals; - result.row_exprs_count = Min(needed_row_count, enumvals->count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - E_EnumVal *enumval = &enumvals->v[idx_range.min + row_expr_idx]; - result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, enumval->name); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - - //////////////////////////// - //- rjf: fill with array indices - // - else if(accel->array_count != 0) - { - E_Expr *array_expr = accel->array_need_extra_deref ? e_expr_ref_deref(arena, expr) : expr; - result.row_exprs_count = Min(needed_row_count, accel->array_count); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - result.row_exprs[row_expr_idx] = e_expr_ref_array_index(arena, array_expr, idx_range.min + row_expr_idx); - result.row_members[row_expr_idx] = &e_member_nil; - } - } - - //////////////////////////// - //- rjf: fill with ptr-to-ptr deref - // - else if(accel->is_ptr2ptr) - { - result.row_exprs_count = 1; - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - result.row_exprs[0] = e_expr_ref_deref(arena, expr); - result.row_members[0] = &e_member_nil; - } - - //////////////////////////// - //- rjf: fill with lookups - // - else if(accel->lookup_rule != 0) - { - E_LookupRange lookup_range = accel->lookup_rule->range(arena, expr, idx_range, accel->lookup_user_data); - result.row_exprs_count = lookup_range.exprs_count; - result.row_exprs = lookup_range.exprs; - result.row_strings = lookup_range.exprs_strings; - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - result.row_members[row_expr_idx] = &e_member_nil; - } - } - - return result; -} - //////////////////////////////// //~ rjf: "list" @@ -306,9 +104,3 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list) EV_ExpandInfo info = {0}; return info; } - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list) -{ - EV_ExpandRangeInfo info = {0}; - return info; -} diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 71925429..3b547ff0 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -15,22 +15,6 @@ EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil) return info; } -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil) -{ - EV_ExpandRangeInfo info = {0}; - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) -{ - return id; -} - //////////////////////////////// //~ rjf: Key Functions @@ -352,7 +336,7 @@ ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewR internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table) { - for EachEnumVal(EV_ViewRuleKind, kind) + for EachNonZeroEnumVal(EV_ViewRuleKind, kind) { ev_view_rule_info_table_push(arena, table, &ev_builtin_view_rule_info_table[kind]); } @@ -387,206 +371,11 @@ ev_view_rule_info_from_string(String8 string) return info; } -//////////////////////////////// -//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups - -internal void -ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule, B32 is_required) -{ - if(table->slots_count == 0) - { - table->slots_count = 4096; - table->slots = push_array(arena, EV_AutoViewRuleSlot, table->slots_count); - } - U64 hash = e_hash_from_type_key(type_key); - U64 slot_idx = hash%table->slots_count; - EV_AutoViewRuleSlot *slot = &table->slots[slot_idx]; - EV_AutoViewRuleNode *node = 0; - for(EV_AutoViewRuleNode *n = slot->first; n != 0; n = n->next) - { - if(e_type_match(n->key, type_key)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(arena, EV_AutoViewRuleNode, 1); - node->key = type_key; - node->view_rule = push_str8_copy(arena, view_rule); - node->is_required = is_required; - SLLQueuePush(slot->first, slot->last, node); - } -} - -internal void -ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table) -{ - ev_auto_view_rule_table = table; -} - -internal EV_ViewRuleList * -ev_auto_view_rules_from_type_key(Arena *arena, E_TypeKey type_key, B32 gather_required, B32 gather_optional) -{ - EV_ViewRuleList *result = &ev_nil_view_rule_list; - if(ev_auto_view_rule_table != 0 && ev_auto_view_rule_table->slots_count != 0) - { - U64 hash = e_hash_from_type_key(type_key); - U64 slot_idx = hash%ev_auto_view_rule_table->slots_count; - EV_AutoViewRuleSlot *slot = &ev_auto_view_rule_table->slots[slot_idx]; - EV_AutoViewRuleNode *node = 0; - for(EV_AutoViewRuleNode *n = slot->first; n != 0; n = n->next) - { - if(e_type_match(n->key, type_key) && ((n->is_required && gather_required) || (!n->is_required && gather_optional))) - { - if(result == &ev_nil_view_rule_list) - { - result = push_array(arena, EV_ViewRuleList, 1); - } - ev_view_rule_list_push_string(arena, result, n->view_rule); - } - } - } - return result; -} - -//////////////////////////////// -//~ rjf: View Rule Instance List Building - -internal void -ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root) -{ - EV_ViewRuleNode *n = push_array(arena, EV_ViewRuleNode, 1); - n->v.root = root; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal void -ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string) -{ - if(string.size != 0) - { - MD_Node *root = md_tree_from_string(arena, string); - for MD_EachNode(tln, root->first) - { - ev_view_rule_list_push_tree(arena, list, tln); - } - } -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_string(Arena *arena, String8 string) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - ev_view_rule_list_push_string(arena, dst, string); - return dst; -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_expr_fastpaths(Arena *arena, String8 string) -{ - Temp scratch = scratch_begin(&arena, 1); - - // rjf: parse expression - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - - // rjf: extract view rules, encoded via fastpaths in expression string - String8List fastpath_view_rules = {0}; - { - U64 parse_opl = (parse.last_token >= tokens.v + tokens.count ? string.size : parse.last_token->range.min); - U64 comma_pos = str8_find_needle(string, parse_opl, str8_lit(","), 0); - U64 passthrough_pos = str8_find_needle(string, 0, str8_lit("--"), 0); - if(comma_pos < string.size && comma_pos < passthrough_pos) - { - String8 comma_extension = str8_skip_chop_whitespace(str8_substr(string, r1u64(comma_pos+1, passthrough_pos))); - if(str8_match(comma_extension, str8_lit("x"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "hex"); - } - else if(str8_match(comma_extension, str8_lit("b"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "bin"); - } - else if(str8_match(comma_extension, str8_lit("o"), StringMatchFlag_CaseInsensitive)) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "oct"); - } - else if(comma_extension.size != 0) - { - str8_list_pushf(scratch.arena, &fastpath_view_rules, "array:{%S}", comma_extension); - } - } - if(passthrough_pos < string.size) - { - String8 passthrough_view_rule = str8_skip_chop_whitespace(str8_skip(string, passthrough_pos+2)); - if(passthrough_view_rule.size != 0) - { - str8_list_push(scratch.arena, &fastpath_view_rules, passthrough_view_rule); - } - } - } - - // rjf: convert strings to parsed view rules - EV_ViewRuleList *view_rule_list = push_array(arena, EV_ViewRuleList, 1); - for(String8Node *n = fastpath_view_rules.first; n != 0; n = n->next) - { - ev_view_rule_list_push_string(arena, view_rule_list, push_str8_copy(arena, n->string)); - } - - scratch_end(scratch); - return view_rule_list; -} - -internal EV_ViewRuleList * -ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - for(EV_ViewRuleNode *n = src->first; n != 0; n = n->next) - { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->flags & EV_ViewRuleInfoFlag_Inherited) - { - ev_view_rule_list_push_tree(arena, dst, n->v.root); - } - } - return dst; -} - -internal EV_ViewRuleList * -ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src) -{ - EV_ViewRuleList *dst = push_array(arena, EV_ViewRuleList, 1); - for(EV_ViewRuleNode *n = src->first; n != 0; n = n->next) - { - ev_view_rule_list_push_tree(arena, dst, n->v.root); - } - return dst; -} - -internal void -ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRuleList **src) -{ - if(dst->first && src[0] != &ev_nil_view_rule_list && src[0]->first) - { - dst->last->next = src[0]->first; - dst->last = src[0]->last; - dst->count += src[0]->count; - } - else if(!dst->first) - { - MemoryCopyStruct(dst, *src); - } - *src = &ev_nil_view_rule_list; -} - //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) internal E_Expr * -ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) +ev_resolved_from_expr(Arena *arena, E_Expr *expr) { ProfBeginFunction(); { @@ -642,7 +431,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 0); + E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); expr = e_expr_ref_cast(arena, ptr_to_derived_type_key, expr); } } @@ -659,7 +448,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules) //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules) +ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -667,21 +456,12 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str Temp scratch = scratch_begin(&arena, 1); EV_ViewRuleInfo *default_expand_view_rule_info = ev_view_rule_info_from_string(str8_lit("default")); - //- rjf: form complete set of view rules - EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_copy(arena, view_rules); - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(arena, irtree.type_key, 1, 1); - ev_view_rule_list_concat_in_place(top_level_view_rules, &auto_view_rules); - } - //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = ev_key_root(); tree.root->string = string; - tree.root->expr = ev_resolved_from_expr(arena, expr, top_level_view_rules); - tree.root->view_rules = top_level_view_rules; + tree.root->expr = ev_resolved_from_expr(arena, expr); tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -694,11 +474,10 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str EV_Block *parent_block; E_Expr *expr; U64 child_id; - EV_ViewRuleList *view_rules; U64 split_relative_idx; B32 default_expanded; }; - Task start_task = {0, tree.root, tree.root->expr, 1, top_level_view_rules, 0}; + Task start_task = {0, tree.root, tree.root->expr, 1, 0}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -721,24 +500,66 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } // rjf: get expansion view rule info - EV_ViewRuleInfo *expand_view_rule_info = default_expand_view_rule_info; - MD_Node *expand_params = &md_nil_node; - for(EV_ViewRuleNode *n = t->view_rules->first; n != 0; n = n->next) + E_LookupRule *lookup_rule = &e_lookup_rule__default; + EV_ViewRuleInfo *expand_rule = default_expand_view_rule_info; + E_Expr *lookup_rule_tag = &e_expr_nil; + E_Expr *expand_rule_tag = &e_expr_nil; + for(E_Expr *tag = t->expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); - if(info->expr_expand_info != 0 && info->expr_expand_info != EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)) + E_LookupRule *lookup_rule_candidate = e_lookup_rule_from_string(tag->first->string); + EV_ViewRuleInfo *expand_rule_candidate = ev_view_rule_info_from_string(tag->first->string); + if(lookup_rule_candidate != &e_lookup_rule__default) { - expand_view_rule_info = info; - expand_params = n->v.root; + lookup_rule = lookup_rule_candidate; + lookup_rule_tag = tag; + } + if(expand_rule_candidate != &ev_nil_view_rule_info) + { + expand_rule = expand_rule_candidate; + expand_rule_tag = tag; } } - // rjf: get expansion info - EV_ExpandInfo expand_info = expand_view_rule_info->expr_expand_info(arena, view, filter, t->expr, expand_params); + // rjf: for set types, try to use the set's name to lookup rules, if we don't + // have any + if(lookup_rule == &e_lookup_rule__default || + expand_rule == default_expand_view_rule_info) + { + E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); + E_TypeKey expr_type_key = expr_irtree.type_key; + E_TypeKind expr_type_kind = e_type_kind_from_key(expr_type_key); + if(expr_type_kind == E_TypeKind_Set) + { + E_Type *expr_type = e_type_from_key(scratch.arena, expr_type_key); + if(lookup_rule == &e_lookup_rule__default) + { + lookup_rule = e_lookup_rule_from_string(expr_type->name); + } + if(expand_rule == default_expand_view_rule_info) + { + expand_rule = ev_view_rule_info_from_string(expr_type->name); + if(expand_rule == &ev_nil_view_rule_info) + { + expand_rule = default_expand_view_rule_info; + } + } + } + } + + // rjf: get top-level lookup/expansion info + E_LookupInfo lookup_info = lookup_rule->info(arena, t->expr, filter); + EV_ExpandInfo expand_info = expand_rule->expr_expand_info(arena, view, filter, t->expr, expand_rule_tag); + + // rjf: determine expansion info + U64 expansion_row_count = lookup_info.named_expr_count ? lookup_info.named_expr_count : lookup_info.idxed_expr_count; + if(expand_rule != &ev_nil_view_rule_info) + { + expansion_row_count = expand_info.row_count; + } // rjf: generate block for expansion EV_Block *expansion_block = &ev_nil_block; - if(expand_info.row_count != 0) + if(expansion_row_count != 0) { expansion_block = push_array(arena, EV_Block, 1); MemoryCopyStruct(expansion_block, &ev_nil_block); @@ -747,22 +568,24 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; expansion_block->expr = t->expr; - expansion_block->view_rules = t->view_rules; - expansion_block->expand_view_rule_info = expand_view_rule_info; - expansion_block->expand_view_rule_params = expand_params; - expansion_block->expand_view_rule_info_user_data = expand_info.user_data; - expansion_block->row_count = expand_info.row_count; + expansion_block->lookup_tag = lookup_rule_tag; + expansion_block->expand_tag = expand_rule_tag; + expansion_block->lookup_rule = lookup_rule; + expansion_block->expand_rule = expand_rule; + expansion_block->lookup_rule_user_data = lookup_info.user_data; + expansion_block->expand_rule_user_data = expand_info.user_data; + expansion_block->row_count = expansion_row_count; expansion_block->single_item = expand_info.single_item; expansion_block->rows_default_expanded = expand_info.rows_default_expanded; - tree.total_row_count += expand_info.row_count; - tree.total_item_count += expand_info.single_item ? 1 : expand_info.row_count; + tree.total_row_count += expansion_row_count; + tree.total_item_count += expand_info.single_item ? 1 : expansion_row_count; } // rjf: gather children expansions from expansion state U64 child_count = 0; EV_Key *child_keys = 0; U64 *child_nums = 0; - if(!child_count && !expand_info.rows_default_expanded && expand_node != 0 && expand_info.row_count != 0 && expand_view_rule_info->expr_expand_range_info) + if(!child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) { // rjf: count children for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} @@ -776,7 +599,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str 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); + child_nums[idx] = lookup_rule->num_from_id(child->key.child_id, lookup_info.user_data); if(child_nums[idx] != child_keys[idx].child_id) { needs_sort = 1; @@ -816,7 +639,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str child_nums = push_array(scratch.arena, U64, child_count); for(U64 idx = 0; idx < child_count; idx += 1) { - U64 child_id = expand_view_rule_info->expr_expand_id_from_num(idx+1, expand_info.user_data); + U64 child_id = lookup_rule->id_from_num(idx+1, lookup_info.user_data); child_keys[idx] = ev_key_make(ev_hash_from_key(key), child_id); child_nums[idx] = idx+1; } @@ -827,39 +650,24 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str { U64 split_num = child_nums[idx]; U64 split_relative_idx = split_num - 1; - if(split_relative_idx >= expand_info.row_count) + if(split_relative_idx >= expansion_row_count) { continue; } if(expand_info.rows_default_expanded || ev_expansion_from_key(view, child_keys[idx])) { - 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) + Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); + E_Expr *child_expr = &e_expr_nil; + String8 child_string = {0}; + lookup_rule->range(arena, t->expr, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); + if(child_expr != &e_expr_nil) { 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); - ev_view_rule_list_push_string(arena, child_view_rules, child_view_rule_string); - if(child_expand.row_strings[0].size != 0) - { - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, child_expand.row_strings[0]); - ev_view_rule_list_concat_in_place(child_view_rules, &fastpath_view_rules); - } - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType child_irtree = e_irtree_and_type_from_expr(scratch.arena, child_expr); - EV_ViewRuleList *child_auto_view_rules = ev_auto_view_rules_from_type_key(arena, child_irtree.type_key, 1, child_view_rule_string.size == 0); - ev_view_rule_list_concat_in_place(child_view_rules, &child_auto_view_rules); - scratch_end(scratch); - } - E_Expr *child_expr__resolved = ev_resolved_from_expr(arena, child_expr, child_view_rules); Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; - task->expr = child_expr__resolved; + task->expr = child_expr; task->child_id = child_key.child_id; - task->view_rules = child_view_rules; task->split_relative_idx = split_relative_idx; task->default_expanded = expand_info.rows_default_expanded; } @@ -873,7 +681,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules) +ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string) { ProfBeginFunction(); EV_BlockTree tree = {0}; @@ -881,10 +689,7 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s { E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, string); - EV_ViewRuleList *all_view_rules = ev_view_rule_list_copy(arena, view_rules); - ev_view_rule_list_concat_in_place(all_view_rules, &fastpath_view_rules); - tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr, all_view_rules); + tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr); } scratch_end(scratch); ProfEnd(); @@ -1004,7 +809,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) if(contains_1u64(global_range, num)) { U64 relative_num = (num - base_num) + n->v.range.min + 1; - U64 child_id = n->v.block->expand_view_rule_info->expr_expand_id_from_num(relative_num, n->v.block->expand_view_rule_info_user_data); + U64 child_id = n->v.block->lookup_rule->id_from_num(relative_num, n->v.block->lookup_rule_user_data); EV_Key block_key = n->v.block->key; key = ev_key_make(ev_hash_from_key(block_key), child_id); break; @@ -1024,7 +829,7 @@ ev_num_from_key(EV_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_id, n->v.block->expand_view_rule_info_user_data); + U64 relative_num = n->v.block->lookup_rule->num_from_id(key.child_id, n->v.block->lookup_rule_user_data); Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->single_item ? (n->v.range.min+1) : n->v.range.max); if(contains_1u64(num_range, relative_num-1)) { @@ -1141,25 +946,18 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 if(block_relative_range__windowed.max > block_relative_range__windowed.min) { // rjf: get info about expansion range - EV_ExpandRangeInfo expand_range_info = n->v.block->expand_view_rule_info->expr_expand_range_info(arena, view, filter, n->v.block->expr, n->v.block->expand_view_rule_params, block_relative_range__windowed, n->v.block->expand_view_rule_info_user_data); + U64 range_exprs_count = dim_1u64(block_relative_range__windowed); + E_Expr **range_exprs = push_array(arena, E_Expr *, range_exprs_count); + String8 *range_exprs_strings = push_array(arena, String8 ,range_exprs_count); + for EachIndex(idx, range_exprs_count) + { + range_exprs[idx] = &e_expr_nil; + } + n->v.block->lookup_rule->range(arena, n->v.block->expr, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); // rjf: no expansion operator applied -> push row for block expression; pass through block info - if(expand_range_info.row_exprs_count == 0) + if(range_exprs_count == 0) { - E_Member *member = &e_member_nil; - if(n->v.block->expr->kind == E_ExprKind_MemberAccess) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, n->v.block->expr->first); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Member expr_member = e_type_member_from_key_name__cached(lhs_type_key, n->v.block->expr->last->string); - if(expr_member.kind != E_MemberKind_Null) - { - member = push_array(arena, E_Member, 1); - MemoryCopyStruct(member, &expr_member); - } - scratch_end(scratch); - } EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1171,67 +969,24 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; row->string = n->v.block->string; row->expr = n->v.block->expr; - row->member = member; - row->view_rules = n->v.block->view_rules; } // rjf: expansion operator applied -> call, and add rows for all expressions in the viewable range - else + else for EachIndex(idx, range_exprs_count) { - for EachIndex(idx, expand_range_info.row_exprs_count) - { - 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); - ev_view_rule_list_push_string(arena, row_view_rules, row_view_rule_string); - if(expand_range_info.row_strings[idx].size != 0) - { - EV_ViewRuleList *fastpath_view_rules = ev_view_rule_list_from_expr_fastpaths(arena, expand_range_info.row_strings[idx]); - ev_view_rule_list_concat_in_place(row_view_rules, &fastpath_view_rules); - } - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType row_irtree = e_irtree_and_type_from_expr(scratch.arena, row_expr); - EV_ViewRuleList *row_auto_view_rules = ev_auto_view_rules_from_type_key(arena, row_irtree.type_key, 1, row_view_rule_string.size == 0); - ev_view_rule_list_concat_in_place(row_view_rules, &row_auto_view_rules); - scratch_end(scratch); - } - E_Expr *row_expr__resolved = ev_resolved_from_expr(arena, row_expr, row_view_rules); - EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); - SLLQueuePush(rows.first, rows.last, row_node); - rows.count += 1; - EV_Row *row = &row_node->row; - row->block = n->v.block; - row->key = row_key; - row->visual_size = 1; - row->string = expand_range_info.row_strings[idx]; - row->expr = row_expr__resolved; - row->member = expand_range_info.row_members[idx]; - row->view_rules = row_view_rules; - if(row->member == &e_member_nil || row->member == 0) - { - if(row->expr->kind == E_ExprKind_MemberAccess) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr->first); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Member expr_member = e_type_member_from_key_name__cached(lhs_type_key, row->expr->last->string); - if(expr_member.kind != E_MemberKind_Null) - { - row->member = push_array(arena, E_Member, 1); - MemoryCopyStruct(row->member, &expr_member); - } - scratch_end(scratch); - } - } - if(expand_range_info.row_view_rules[idx].size != 0) - { - ev_key_set_view_rule(view, row->key, expand_range_info.row_view_rules[idx]); - } - } + U64 child_num = block_relative_range.min + num_skipped + idx + 1; + U64 child_id = n->v.block->lookup_rule->id_from_num(child_num, n->v.block->lookup_rule_user_data); + EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); + E_Expr *row_expr = range_exprs[idx]; + EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); + SLLQueuePush(rows.first, rows.last, row_node); + rows.count += 1; + EV_Row *row = &row_node->row; + row->block = n->v.block; + row->key = row_key; + row->visual_size = 1; + row->string = range_exprs_strings[idx]; + row->expr = row_expr; } } } @@ -1298,14 +1053,7 @@ ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags) }break; case E_ExprKind_MemberAccess: { - if(flags & EV_StringFlag_PrettyNames && row->member->pretty_name.size != 0) - { - result = push_str8_copy(arena, row->member->pretty_name); - } - else - { - result = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); - } + result = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); }break; } return result; @@ -1319,9 +1067,9 @@ ev_row_is_expandable(EV_Row *row) // rjf: determine if view rules force expandability if(!result) { - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) + for(E_Expr *tag = row->expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(n->v.root->string); + EV_ViewRuleInfo *info = ev_view_rule_info_from_string(tag->first->string); if(info->flags & EV_ViewRuleInfoFlag_Expandable) { result = 1; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 2a1da35f..696adcc4 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -74,30 +74,6 @@ struct EV_View EV_KeyViewRuleNode *free_key_view_rule_node; }; -//////////////////////////////// -//~ rjf: View Rule Instance Types - -typedef struct EV_ViewRule EV_ViewRule; -struct EV_ViewRule -{ - MD_Node *root; -}; - -typedef struct EV_ViewRuleNode EV_ViewRuleNode; -struct EV_ViewRuleNode -{ - EV_ViewRuleNode *next; - EV_ViewRule v; -}; - -typedef struct EV_ViewRuleList EV_ViewRuleList; -struct EV_ViewRuleList -{ - EV_ViewRuleNode *first; - EV_ViewRuleNode *last; - U64 count; -}; - //////////////////////////////// //~ rjf: View Rule Info Types @@ -111,36 +87,10 @@ struct EV_ExpandInfo B32 rows_default_expanded; }; -typedef struct EV_ExpandRangeInfo EV_ExpandRangeInfo; -struct EV_ExpandRangeInfo -{ - U64 row_exprs_count; - String8 *row_strings; - String8 *row_view_rules; - E_Expr **row_exprs; - E_Member **row_members; -}; - -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params) +#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) #define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name #define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(name) EV_ExpandRangeInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_range_info__##name -#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name) ev_view_rule_expr_expand_id_from_num_##name -#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name)) - -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) ev_view_rule_expr_expand_num_from_id_##name -#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name)) - typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandRangeInfoHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_ViewRuleExprExpandIDFromNumHookFunctionType); -typedef EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_ViewRuleExprExpandNumFromIDHookFunctionType); typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info enum @@ -155,9 +105,6 @@ struct EV_ViewRuleInfo String8 string; EV_ViewRuleInfoFlags flags; EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; - EV_ViewRuleExprExpandRangeInfoHookFunctionType *expr_expand_range_info; - EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_id_from_num; - EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_num_from_id; }; typedef struct EV_ViewRuleInfoNode EV_ViewRuleInfoNode; @@ -203,10 +150,12 @@ struct EV_Block // rjf: expression / visualization info String8 string; E_Expr *expr; - EV_ViewRuleList *view_rules; - EV_ViewRuleInfo *expand_view_rule_info; - MD_Node *expand_view_rule_params; - void *expand_view_rule_info_user_data; + E_Expr *lookup_tag; + E_Expr *expand_tag; + E_LookupRule *lookup_rule; + EV_ViewRuleInfo *expand_rule; + void *lookup_rule_user_data; + void *expand_rule_user_data; // rjf: expansion info U64 row_count; @@ -255,8 +204,6 @@ struct EV_Row U64 visual_size; String8 string; E_Expr *expr; - E_Member *member; - EV_ViewRuleList *view_rules; }; typedef struct EV_WindowedRowNode EV_WindowedRowNode; @@ -324,9 +271,6 @@ enum //~ rjf: Nil/Identity View Rule Hooks EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); //////////////////////////////// //~ rjf: Globals @@ -336,14 +280,10 @@ global read_only EV_ViewRuleInfo ev_nil_view_rule_info = {0}, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), - EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), - EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), - EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), }; thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; -global read_only EV_ViewRuleList ev_nil_view_rule_list = {0}; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__default, &ev_nil_view_rule_info}; //////////////////////////////// //~ rjf: Key Functions @@ -384,34 +324,16 @@ internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInf internal void ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table); internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); -//////////////////////////////// -//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups - -internal void ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule, B32 is_required); -internal void ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table); -internal EV_ViewRuleList *ev_auto_view_rules_from_type_key(Arena *arena, E_TypeKey type_key, B32 gather_required, B32 gather_optional); - -//////////////////////////////// -//~ rjf: View Rule Instance List Building - -internal void ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root); -internal void ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_string(Arena *arena, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_expr_fastpaths(Arena *arena, String8 string); -internal EV_ViewRuleList *ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src); -internal EV_ViewRuleList *ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src); -internal void ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRuleList **src); - //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) -internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules); +internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules); -internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules); +internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr); +internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/eval_visualization/generated/eval_visualization.meta.c b/src/eval_visualization/generated/eval_visualization.meta.c index d40c4a80..30964f74 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.c +++ b/src/eval_visualization/generated/eval_visualization.meta.c @@ -6,20 +6,20 @@ C_LINKAGE_BEGIN EV_ViewRuleInfo ev_builtin_view_rule_info_table[14] = { -{str8_lit_comp("default"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, -{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }, +{0}, +{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) }, +{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, +{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, }; C_LINKAGE_END diff --git a/src/eval_visualization/generated/eval_visualization.meta.h b/src/eval_visualization/generated/eval_visualization.meta.h index b3283350..5625eefd 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.h +++ b/src/eval_visualization/generated/eval_visualization.meta.h @@ -8,7 +8,7 @@ typedef enum EV_ViewRuleKind { -EV_ViewRuleKind_Default, +EV_ViewRuleKind_EV_ViewRuleKind_Null, EV_ViewRuleKind_Array, EV_ViewRuleKind_List, EV_ViewRuleKind_Slice, @@ -25,8 +25,5 @@ EV_ViewRuleKind_NoAddress, EV_ViewRuleKind_COUNT, } EV_ViewRuleKind; -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list); #endif // EVAL_VISUALIZATION_META_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 9b0ad608..49c88b7f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -719,48 +719,6 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -String8 rd_collection_name_table[2] = -{ -str8_lit_comp("scheduler_machine"), -str8_lit_comp("scheduler_process"), -}; - -RD_EntityKind rd_collection_entity_kind_table[2] = -{ -RD_EntityKind_Nil, -RD_EntityKind_Nil, -}; - -CTRL_EntityKind rd_collection_ctrl_entity_kind_table[2] = -{ -CTRL_EntityKind_Null, -CTRL_EntityKind_Null, -}; - -EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[2] = -{ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(scheduler_process), -}; - -EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[2] = -{ -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(scheduler_process), -}; - -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[2] = -{ -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(scheduler_process), -}; - -EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[2] = -{ -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_machine), -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(scheduler_process), -}; - RD_ViewRuleInfo rd_view_rule_kind_info_table[28] = { {{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 9e88a8d8..b8f1cc6b 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -651,14 +651,6 @@ RD_ViewRuleUIFunctionType *ui; .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine); -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process); RD_VIEW_RULE_UI_FUNCTION_DEF(null); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text); EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm); @@ -709,13 +701,6 @@ extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern String8 rd_collection_name_table[2]; -extern RD_EntityKind rd_collection_entity_kind_table[2]; -extern CTRL_EntityKind rd_collection_ctrl_entity_kind_table[2]; -extern EV_ViewRuleExprExpandInfoHookFunctionType * rd_collection_expr_expand_info_hook_function_table[2]; -extern EV_ViewRuleExprExpandRangeInfoHookFunctionType * rd_collection_expr_expand_range_info_hook_function_table[2]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_id_from_num_hook_function_table[2]; -extern EV_ViewRuleExprExpandIDFromNumHookFunctionType * rd_collection_expr_expand_num_from_id_hook_function_table[2]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 16859833..789ed7bd 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1015,82 +1015,6 @@ RD_IconTable: @expand(RD_IconTable a) `str8_lit_comp("$(a.text)")`; } -//////////////////////////////// -//~ rjf: Collections - -@table(name entity_kind ctrl_entity_kind id_space) -RD_CollectionTable: -{ - //- rjf: frontend entity groups - //{watches Watch Null x} - //{targets Target Null x} - //{breakpoints Breakpoint Null x} - //{watch_pins WatchPin Null x} - //{file_path_maps FilePathMap Null x} - //{auto_view_rules AutoViewRule Null x} - - //- rjf: control entity groups - //{machines Nil Machine x} - //{processes Nil Process x} - //{threads Nil Thread x} - //{modules Nil Module x} - - //- rjf: scheduling control entity hierarchies - {scheduler_machine Nil Null x} - {scheduler_process Nil Null x} - - //- rjf: debug info / architecture watch tables - // {locals Nil Null -} - // {registers Nil Null -} - // {globals Nil Null x} - // {thread_locals Nil Null x} - // {types Nil Null x} - // {procedures Nil Null x} -} - -@gen -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF($(a.name));`; - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF($(a.name));`; - @expand(RD_CollectionTable a) `$(a.id_space == x -> "EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF("..a.name..");")`; - @expand(RD_CollectionTable a) `$(a.id_space == x -> "EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF("..a.name..");")`; -} - -@data(String8) rd_collection_name_table: -{ - @expand(RD_CollectionTable a) `str8_lit_comp("$(a.name)")` -} - -@data(RD_EntityKind) rd_collection_entity_kind_table: -{ - @expand(RD_CollectionTable a) `RD_EntityKind_$(a.entity_kind)`, -} - -@data(CTRL_EntityKind) rd_collection_ctrl_entity_kind_table: -{ - @expand(RD_CollectionTable a) `CTRL_EntityKind_$(a.ctrl_entity_kind)`, -} - -@data(`EV_ViewRuleExprExpandInfoHookFunctionType *`) rd_collection_expr_expand_info_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME($(a.name))` -} - -@data(`EV_ViewRuleExprExpandRangeInfoHookFunctionType *`) rd_collection_expr_expand_range_info_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME($(a.name))` -} - -@data(`EV_ViewRuleExprExpandIDFromNumHookFunctionType *`) rd_collection_expr_expand_id_from_num_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME($(a.id_space == x -> a.name)$(a.id_space != x -> identity))` -} - -@data(`EV_ViewRuleExprExpandIDFromNumHookFunctionType *`) rd_collection_expr_expand_num_from_id_hook_function_table: -{ - @expand(RD_CollectionTable a) `EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME($(a.id_space == x -> a.name)$(a.id_space != x -> identity))` -} - //////////////////////////////// //~ rjf: View Rules diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 21c67123..f8cb8411 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8736,18 +8736,19 @@ rd_window_frame(void) //////////////////////////////// //~ rjf: Eval Visualization -typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; -struct RD_EntityExpandAccel -{ - RD_EntityArray entities; -}; - typedef struct RD_CtrlEntityExpandAccel RD_CtrlEntityExpandAccel; struct RD_CtrlEntityExpandAccel { CTRL_EntityArray entities; }; +#if 0 // TODO(rjf): @cfg +typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; +struct RD_EntityExpandAccel +{ + RD_EntityArray entities; +}; + //- rjf: control entity hierarchies EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine) @@ -8908,6 +8909,7 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) { return id; } +#endif //- rjf: debug info tables @@ -8942,24 +8944,17 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) E_LOOKUP_RANGE_FUNCTION_DEF(watches) { - E_LookupRange result = {0}; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) { - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - result.exprs_count = read_range_count; - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - result.exprs_strings = push_array(arena, String8, result.exprs_count); - for(U64 idx = 0; idx < result.exprs_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; - result.exprs[idx] = e_parse_expr_from_text(arena, expr_string); - result.exprs_strings[idx] = push_str8_copy(arena, expr_string); - } + U64 cfg_idx = read_range.min + idx; + String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; + exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs_strings[idx] = push_str8_copy(arena, expr_string); } - return result; } E_LOOKUP_INFO_FUNCTION_DEF(locals) @@ -8990,23 +8985,16 @@ E_LOOKUP_INFO_FUNCTION_DEF(locals) E_LOOKUP_RANGE_FUNCTION_DEF(locals) { - E_LookupRange result = {0}; + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) { - String8Array *accel = (String8Array *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - result.exprs_count = read_range_count; - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - result.exprs_strings = push_array(arena, String8, result.exprs_count); - for(U64 idx = 0; idx < result.exprs_count; idx += 1) - { - String8 expr_string = accel->v[read_range.min + idx]; - result.exprs[idx] = e_parse_expr_from_text(arena, expr_string); - result.exprs_strings[idx] = push_str8_copy(arena, expr_string); - } + String8 expr_string = accel->v[read_range.min + idx]; + exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs_strings[idx] = push_str8_copy(arena, expr_string); } - return result; } E_LOOKUP_INFO_FUNCTION_DEF(registers) @@ -9045,22 +9033,16 @@ E_LOOKUP_INFO_FUNCTION_DEF(registers) E_LOOKUP_RANGE_FUNCTION_DEF(registers) { String8Array *accel = (String8Array *)user_data; - E_LookupRange result = {0}; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) { - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - result.exprs_count = dim_1u64(read_range); - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - result.exprs_strings = push_array(arena, String8, result.exprs_count); - for(U64 idx = 0; idx < result.exprs_count; idx += 1) - { - String8 register_name = accel->v[read_range.min + idx]; - String8 register_expr = push_str8f(arena, "reg:%S", register_name); - result.exprs_strings[idx] = register_name; - result.exprs[idx] = e_parse_expr_from_text(arena, register_expr); - } + String8 register_name = accel->v[read_range.min + idx]; + String8 register_expr = push_str8f(arena, "reg:%S", register_name); + exprs_strings[idx] = register_name; + exprs[idx] = e_parse_expr_from_text(arena, register_expr); } - return result; } E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) @@ -9241,101 +9223,94 @@ E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) { RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - E_LookupRange result = {0}; + U64 needed_row_count = dim_1u64(idx_range); + for EachIndex(idx, needed_row_count) { - U64 needed_row_count = dim_1u64(idx_range); - result.exprs_count = Min(needed_row_count, accel->items.count); - result.exprs = push_array(arena, E_Expr *, result.exprs_count); - result.exprs_strings = push_array(arena, String8, result.exprs_count); - for EachIndex(idx, result.exprs_count) + // rjf: unpack row + DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; + + // rjf: skip bad elements + if(item->dbgi_idx >= accel->rdis_count) { - // rjf: unpack row - DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; - - // rjf: skip bad elements - if(item->dbgi_idx >= accel->rdis_count) - { - continue; - } - - // rjf: unpack row info - RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; - - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; - { - U64 element_idx = item->idx; - switch(accel->section) - { - default:{}break; - case RDI_SectionKind_Procedures: - { - RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); - RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_GlobalVariables: - { - RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_ThreadVariables: - { - RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_UDTs: - { - RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; - }break; - } - } - - // rjf: fill - result.exprs[idx] = item_expr; + continue; } + + // rjf: unpack row info + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; + + // rjf: build expr + E_Expr *item_expr = &e_expr_nil; + { + U64 element_idx = item->idx; + switch(accel->section) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); + RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Value; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_GlobalVariables: + { + RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); + U64 voff = gvar->voff; + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = gvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_ThreadVariables: + { + RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = tvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_UDTs: + { + RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + item_expr->type_key = type_key; + }break; + } + } + + // rjf: fill + exprs[idx] = item_expr; } - return result; } E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) @@ -9356,174 +9331,8 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) return num; } -internal EV_ExpandInfo -rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind) -{ - RD_EntityExpandAccel *accel = push_array(arena, RD_EntityExpandAccel, 1); - Temp scratch = scratch_begin(&arena, 1); - { - RD_EntityList entities = rd_query_cached_entity_list_with_kind(kind); - RD_EntityList entities_filtered = {0}; - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - String8 entity_expr_string = entity->string; - B32 is_collection = 0; - for EachElement(idx, rd_collection_name_table) - { - if(str8_match(entity_expr_string, rd_collection_name_table[idx], 0)) - { - is_collection = 1; - break; - } - } - B32 is_in_filter = 1; - if(!is_collection && filter.size != 0) - { - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - FuzzyMatchRangeList expr_matches = fuzzy_match_find(scratch.arena, filter, entity_expr_string); - FuzzyMatchRangeList loc_matches = fuzzy_match_find(scratch.arena, filter, loc->string); - FuzzyMatchRangeList exe_matches = fuzzy_match_find(scratch.arena, filter, exe->string); - FuzzyMatchRangeList args_matches = fuzzy_match_find(scratch.arena, filter, args->string); - is_in_filter = (expr_matches.count == expr_matches.needle_part_count || - loc_matches.count == loc_matches.needle_part_count || - exe_matches.count == exe_matches.needle_part_count || - args_matches.count == args_matches.needle_part_count); - } - if(is_collection || is_in_filter) - { - rd_entity_list_push(scratch.arena, &entities_filtered, entity); - } - } - accel->entities = rd_entity_array_from_list(arena, &entities_filtered); - } - scratch_end(scratch); - EV_ExpandInfo info = {accel, accel->entities.count + 1}; - info.add_new_row = 1; - return info; -} - -internal EV_ExpandRangeInfo -rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - EV_ExpandRangeInfo result = {0}; - { - U64 entities_base_idx = (U64)!!add_new_at_top; - U64 needed_row_count = dim_1u64(idx_range); - result.row_exprs_count = Min(needed_row_count, accel->entities.count+1); - result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count); - result.row_strings = push_array(arena, String8, result.row_exprs_count); - result.row_view_rules = push_array(arena, String8, result.row_exprs_count); - result.row_members = push_array(arena, E_Member *, result.row_exprs_count); - for EachIndex(row_expr_idx, result.row_exprs_count) - { - U64 child_idx = idx_range.min + row_expr_idx; - RD_Entity *entity = &rd_nil_entity; - if(entities_base_idx <= child_idx && child_idx < entities_base_idx+accel->entities.count) - { - entity = accel->entities.v[child_idx-entities_base_idx]; - } - if(!rd_entity_is_nil(entity)) - { - String8 entity_expr_string = (kind == RD_EntityKind_Watch ? entity->string : push_str8f(arena, "entity:$%I64u", entity->id)); - if(kind == RD_EntityKind_Watch) - { - result.row_strings[row_expr_idx] = entity_expr_string; - } - result.row_exprs[row_expr_idx] = e_parse_expr_from_text(arena, entity_expr_string); - result.row_view_rules[row_expr_idx] = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule)->string; - } - else - { - result.row_exprs[row_expr_idx] = &e_expr_nil; - } - result.row_members[row_expr_idx] = &e_member_nil; - } - } - return result; -} - -internal U64 -rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - U64 id = 0; - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - U64 entities_base_idx = (U64)!!add_new_at_top; - if(entities_base_idx+1 <= num && num < entities_base_idx+accel->entities.count+1) - { - id = accel->entities.v[num-(entities_base_idx+1)]->id; - } - else - { - id = max_U64; - } - return id; -} - -internal U64 -rd_ev_view_rule_expr_num_from_id__meta_entities(U64 id, void *user_data, RD_EntityKind kind, B32 add_new_at_top) -{ - RD_EntityExpandAccel *accel = (RD_EntityExpandAccel *)user_data; - U64 num = 0; - U64 entities_base_idx = (U64)!!add_new_at_top; - if(id == max_U64) - { - num = add_new_at_top ? 1 : (entities_base_idx + accel->entities.count + 1); - } - else for(U64 idx = 0; idx < accel->entities.count; idx += 1) - { - if(accel->entities.v[idx]->id == id) - { - num = entities_base_idx+idx+1; - break; - } - } - return num; -} - -internal EV_ExpandInfo -rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, CTRL_EntityKind kind) -{ - RD_CtrlEntityExpandAccel *accel = push_array(arena, RD_CtrlEntityExpandAccel, 1); - Temp scratch = scratch_begin(&arena, 1); - { - CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); - CTRL_EntityList entities_filtered = {0}; - for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - B32 is_in_filter = 1; - if(filter.size != 0) - { - is_in_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - } - } - if(is_in_filter) - { - ctrl_entity_list_push(scratch.arena, &entities_filtered, entity); - } - } - accel->entities = ctrl_entity_array_from_list(arena, &entities_filtered); - } - scratch_end(scratch); - EV_ExpandInfo info = {accel, accel->entities.count}; - // TODO(rjf): @hack - if(kind == CTRL_EntityKind_Machine) - { - info.rows_default_expanded = 1; - } - return info; -} - 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) +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, String8List *out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -9535,22 +9344,22 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul B32 no_addr = 0; B32 no_string = 0; B32 has_array = 0; - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) + for(E_Expr *tag = eval.expr->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} - else if(str8_match(n->v.root->string, str8_lit("dec"), 0)) {radix = 10;} - else if(str8_match(n->v.root->string, str8_lit("hex"), 0)) {radix = 16;} - else if(str8_match(n->v.root->string, str8_lit("bin"), 0)) {radix = 2; } - else if(str8_match(n->v.root->string, str8_lit("oct"), 0)) {radix = 8; } - else if(str8_match(n->v.root->string, str8_lit("no_addr"), 0)) {no_addr = 1;} - else if(str8_match(n->v.root->string, str8_lit("no_string"), 0)) {no_string = 1;} - else if(str8_match(n->v.root->string, str8_lit("array"), 0)) {has_array = 1;} - else if(str8_match(n->v.root->string, str8_lit("digits"), 0)) + else if(str8_match(tag->string, str8_lit("dec"), 0)) {radix = 10;} + else if(str8_match(tag->string, str8_lit("hex"), 0)) {radix = 16;} + else if(str8_match(tag->string, str8_lit("bin"), 0)) {radix = 2; } + else if(str8_match(tag->string, str8_lit("oct"), 0)) {radix = 8; } + else if(str8_match(tag->string, str8_lit("no_addr"), 0)) {no_addr = 1;} + else if(str8_match(tag->string, str8_lit("no_string"), 0)) {no_string = 1;} + else if(str8_match(tag->first->string, str8_lit("array"), 0)) {has_array = 1;} + else if(str8_match(tag->first->string, str8_lit("digits"), 0)) { - String8 expr = md_string_from_children(scratch.arena, n->v.root); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - min_digits = (U32)value_eval.value.u64; + E_Expr *num_expr = tag->first->next; + E_Eval num_eval = e_eval_from_expr(scratch.arena, num_expr); + E_Eval num_value_eval = e_value_eval_from_eval(num_eval); + min_digits = (U32)num_value_eval.value.u64; } } if(eval.space.kind == RD_EvalSpaceKind_MetaEntity || @@ -9718,7 +9527,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, 0, view_rules, out); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, out); } else { @@ -9745,7 +9554,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul // rjf: special case: push strings for textual string content B32 did_content = 0; - if(!did_content && array_is_string && !no_string && (member == 0 || member->kind != E_MemberKind_Padding)) + if(!did_content && array_is_string && !no_string) { U64 element_size = e_type_byte_size_from_key(direct_type_key); did_content = 1; @@ -9804,7 +9613,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *element_expr = e_expr_ref_array_index(scratch.arena, eval.expr, idx); E_Eval element_eval = e_eval_from_expr(scratch.arena, element_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, element_eval, 0, view_rules, out); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, element_eval, out); if(idx+1 < array_count) { String8 comma = str8_lit(", "); @@ -9858,9 +9667,9 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Member *mem = &data_members.v[member_idx]; E_Expr *dot_expr = e_expr_ref_member_access(scratch.arena, eval.expr, mem->name); - E_Expr *dot_expr_resolved = ev_resolved_from_expr(scratch.arena, dot_expr, view_rules); + E_Expr *dot_expr_resolved = ev_resolved_from_expr(scratch.arena, dot_expr); E_Eval dot_eval = e_eval_from_expr(scratch.arena, dot_expr_resolved); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, 0, view_rules, out); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, out); if(member_idx+1 < data_members.count) { String8 comma = str8_lit(", "); @@ -9897,11 +9706,11 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } 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) +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) { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval, member, view_rules, &strs); + rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; @@ -13043,15 +12852,6 @@ rd_frame(void) } e_select_parse_ctx(parse_ctx); - //////////////////////////// - //- rjf: create names/type-info for debugger collections - // - E_TypeKey collection_type_keys[ArrayCount(rd_collection_name_table)] = {0}; - for EachElement(idx, rd_collection_name_table) - { - collection_type_keys[idx] = e_type_key_cons(.kind = E_TypeKind_Array, .name = rd_collection_name_table[idx]); - } - //////////////////////////// //- rjf: build eval IR context // @@ -13064,19 +12864,6 @@ rd_frame(void) ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); - //- rjf: add macros for collections -#if 0 // TODO(rjf): @cfg - { - for EachElement(idx, rd_collection_name_table) - { - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->mode = E_Mode_Null; - expr->type_key = collection_type_keys[idx]; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, rd_collection_name_table[idx], expr); - } - } -#endif - //- rjf: choose set of evallable meta names String8 evallable_meta_names[] = { @@ -13107,10 +12894,10 @@ rd_frame(void) bool_type_key = e_type_key_basic(E_TypeKind_Bool); u64_type_key = e_type_key_basic(E_TypeKind_U64); vaddr_range_type_key = e_type_key_cons(E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); - code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsCodeText); - path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPathText); - string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText); - location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); + code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); + string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText); + location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); } //- rjf: build types for each evallable meta name @@ -13380,52 +13167,16 @@ 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 rules - for EachElement(idx, rd_collection_name_table) - { - EV_ViewRuleInfo info = {0}; - info.string = rd_collection_name_table[idx]; - info.flags = EV_ViewRuleInfoFlag_Expandable; - info.expr_expand_info = rd_collection_expr_expand_info_hook_function_table[idx]; - info.expr_expand_range_info = rd_collection_expr_expand_range_info_hook_function_table[idx]; - info.expr_expand_id_from_num = rd_collection_expr_expand_id_from_num_hook_function_table[idx]; - info.expr_expand_num_from_id = rd_collection_expr_expand_num_from_id_hook_function_table[idx]; - ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &info); - } - - // rjf: visualizer view rules - for EachEnumVal(RD_ViewRuleKind, k) - { - RD_ViewRuleInfo *src_info = &rd_view_rule_kind_info_table[k]; - if(src_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable) - { - EV_ViewRuleInfo dst_info = {0}; - dst_info.string = src_info->string; - dst_info.flags = src_info->flags & RD_ViewRuleInfoFlag_CanExpand ? EV_ViewRuleInfoFlag_Expandable : 0; - dst_info.expr_expand_info = src_info->expr_expand_info; - dst_info.expr_expand_range_info = EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil); - dst_info.expr_expand_id_from_num = EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity); - dst_info.expr_expand_num_from_id = EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity); - ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &dst_info); - } - } } ev_select_view_rule_info_table(view_rule_info_table); //////////////////////////// //- rjf: build eval visualization auto-view-rule table // + // TODO(rjf): @cfg + // 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_CheckB32)), str8_lit("checkbox"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray)), str8_lit("slice"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MachineMetaEval)), str8_lit("scheduler_machine"), 1); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_ProcessMetaEval)), str8_lit("scheduler_process"), 1); - for EachElement(idx, rd_collection_name_table) - { - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_keys[idx], rd_collection_name_table[idx], 1); - } RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) { @@ -13437,11 +13188,11 @@ rd_frame(void) E_TypeKey type_key = e_type_from_expr(type_parse.expr); if(!e_type_key_match(e_type_key_zero(), type_key)) { - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, type_key, view_rule_string, 0); + // ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, type_key, view_rule_string, 0); } } } - ev_select_auto_view_rule_table(auto_view_rule_table); + // ev_select_auto_view_rule_table(auto_view_rule_table); //////////////////////////// //- rjf: autosave if needed diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 1d2e38f4..7dbc97af 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1303,18 +1303,8 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RD_EntityKind kind); -internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RD_EntityKind kind, B32 add_new_at_top); -internal U64 rd_ev_view_rule_expr_id_from_num__meta_entities(U64 num, void *user_data, RD_EntityKind kind, B32 add_new_at_top); -internal U64 rd_ev_view_rule_expr_num_from_id__meta_entities(U64 id, void *user_data, RD_EntityKind kind, B32 add_new_at_top); - -internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, CTRL_EntityKind kind); -internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_ctrl_entities(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, CTRL_EntityKind kind); -internal U64 rd_ev_view_rule_expr_id_from_num__meta_ctrl_entities(U64 num, void *user_data, CTRL_EntityKind kind); -internal U64 rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CTRL_EntityKind kind); - -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); +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, 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); //////////////////////////////// //~ rjf: Hover Eval diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 252fcb25..0f785c4f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -987,6 +987,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //- rjf: row -> context info +#if 0 // TODO(rjf): @cfg internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row) { @@ -1103,6 +1104,7 @@ rd_watch_view_row_info_from_row(EV_Row *row) } return info; } +#endif //- rjf: row * cell -> string @@ -1204,7 +1206,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info //- rjf: evaluate wrapped expression result.eval = e_eval_from_expr(scratch.arena, root_expr); - result.string = rd_value_string_from_eval(arena, 0, 10, font, font_size, max_size_px, result.eval, &e_member_nil, row->view_rules); + result.string = rd_value_string_from_eval(arena, 0, 10, font, font_size, max_size_px, result.eval); scratch_end(scratch); }break; @@ -1214,6 +1216,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info //- rjf: row/column -> strings +#if 0 // TODO(rjf): @cfg + internal E_Expr * rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col) { @@ -1409,6 +1413,8 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn return result; } +#endif + //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState * @@ -1491,7 +1497,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view ////////////////////////////// //- rjf: unpack arguments // - EV_ViewRuleList *top_level_view_rules = ev_view_rule_list_from_string(scratch.arena, root_view_rule); EV_View *eval_view = rd_view_eval_view(); String8 filter = rd_view_filter(); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); @@ -1559,7 +1564,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr, top_level_view_rules); + block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); } @@ -2026,10 +2031,16 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - String8 cell_string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 cell_string = cell_info.string; cell_string = str8_skip_chop_whitespace(cell_string); U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) @@ -2038,7 +2049,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view comma_pos < cell_string.size ? "\"" : "", cell_string, comma_pos < cell_string.size ? "\"" : "", - x+1 <= selection_tbl.max.x ? "," : ""); + cell_x+1 <= selection_tbl.max.x ? "," : ""); } else { @@ -2288,6 +2299,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); E_Type *type = e_type_from_key(scratch.arena, irtree.type_key); +#if 0 // TODO(rjf): @cfg for EachElement(idx, rd_collection_name_table) { if(str8_match(type->name, rd_collection_name_table[idx], 0)) @@ -2296,6 +2308,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view break; } } +#endif // rjf: map selection endpoints to entities RD_Entity *first_entity = &rd_nil_entity; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 90ce0dc6..841045e1 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -239,14 +239,18 @@ internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchP internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); //- rjf: row -> context info +#if 0 // TODO(rjf): @cfg internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); +#endif //- rjf: row * cell -> info internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: row/column -> exprs / strings +#if 0 // TODO(rjf): @cfg internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col); internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); +#endif //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index d33e32bd..eceda5a1 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1286,8 +1286,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.type_key)) { - EV_ViewRuleList view_rules = {0}; - eval_string = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval, &e_member_nil, &view_rules); + eval_string = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); } ui_spacer(ui_em(1.5f, 1.f)); ui_set_next_pref_width(ui_children_sum(1)); From 6f4533d8f52c5a84e89877da76234ff4476f988b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 2 Feb 2025 17:08:14 -0800 Subject: [PATCH 043/755] 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); From 59fe6c79cb5b5a515f07204f62ae7d97e737ba48 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 3 Feb 2025 10:07:20 -0800 Subject: [PATCH 044/755] distinguish root block from non-root blocks; in root case, we do not want to do a lookup-range to generate the block's expression (but in all other cases we do) --- src/eval/eval_ir.c | 2 +- src/eval/eval_ir.h | 9 +++++++++ src/eval_visualization/eval_visualization_core.c | 14 +++++++++++--- src/eval_visualization/eval_visualization_core.h | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index f83ea8a4..0c270083 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -101,7 +101,7 @@ e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) internal E_LookupRule * e_lookup_rule_from_string(String8 string) { - E_LookupRule *result = &e_lookup_rule__default; + E_LookupRule *result = &e_lookup_rule__nil; if(e_ir_ctx->lookup_rule_map != 0 && e_ir_ctx->lookup_rule_map->slots_count != 0) { U64 hash = e_hash_from_string(5381, string); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 0e0a0710..dace3b8b 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -242,6 +242,15 @@ struct E_IRCtx //////////////////////////////// //~ rjf: Globals +local_persist read_only E_LookupRule e_lookup_rule__nil = +{ + str8_lit_comp("nil"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_ACCESS_FUNCTION_NAME(default), + E_LOOKUP_RANGE_FUNCTION_NAME(default), + E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), +}; local_persist read_only E_LookupRule e_lookup_rule__default = { str8_lit_comp("default"), diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 3b547ff0..d2deaba4 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -508,7 +508,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str { E_LookupRule *lookup_rule_candidate = e_lookup_rule_from_string(tag->first->string); EV_ViewRuleInfo *expand_rule_candidate = ev_view_rule_info_from_string(tag->first->string); - if(lookup_rule_candidate != &e_lookup_rule__default) + if(lookup_rule_candidate != &e_lookup_rule__nil) { lookup_rule = lookup_rule_candidate; lookup_rule_tag = tag; @@ -946,6 +946,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 if(block_relative_range__windowed.max > block_relative_range__windowed.min) { // rjf: get info about expansion range + B32 is_root = 0; U64 range_exprs_count = dim_1u64(block_relative_range__windowed); E_Expr **range_exprs = push_array(arena, E_Expr *, range_exprs_count); String8 *range_exprs_strings = push_array(arena, String8 ,range_exprs_count); @@ -953,10 +954,17 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - n->v.block->lookup_rule->range(arena, n->v.block->expr, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + if(n->v.block->lookup_rule == &e_lookup_rule__nil) + { + is_root = 1; + } + else + { + n->v.block->lookup_rule->range(arena, n->v.block->expr, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + } // rjf: no expansion operator applied -> push row for block expression; pass through block info - if(range_exprs_count == 0) + if(is_root) { EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 696adcc4..5f537113 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -283,7 +283,7 @@ global read_only EV_ViewRuleInfo ev_nil_view_rule_info = }; thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__default, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_view_rule_info}; //////////////////////////////// //~ rjf: Key Functions From 9a405bee205b30b2d1ae2e0ba6fdbd7ac6fa3e2e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 3 Feb 2025 13:21:08 -0800 Subject: [PATCH 045/755] eval: lookup info hook -> just pass irtree, do not recompute; cache for type-key -> auto hook tag exprs; use tags/auto-tags in lookup rule for . operator; fix tag poisoning in ir generation pass; cache for type-key -> unpacked type info; replace all unpacked type info paths with cache usage --- src/dbg_engine/dbg_engine_core.c | 12 +- src/eval/eval_bundles.c | 6 +- src/eval/eval_ir.c | 175 +++++++++++++----- src/eval/eval_ir.h | 29 ++- src/eval/eval_parse.c | 4 + src/eval/eval_types.c | 99 +++++----- src/eval/eval_types.h | 24 ++- .../eval_visualization_core.c | 22 ++- .../eval_visualization_core.h | 2 + src/raddbg/raddbg_core.c | 71 ++++--- src/raddbg/raddbg_views.c | 6 +- 11 files changed, 308 insertions(+), 142 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 6c65f5e4..6e35ae7d 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -12,14 +12,16 @@ //////////////////////////////// //~ rjf: Basic Helpers +#if !defined(XXH_IMPLEMENTATION) +# define XXH_IMPLEMENTATION +# define XXH_STATIC_LINKING_ONLY +# include "third_party/xxHash/xxhash.h" +#endif + internal U64 d_hash_from_seed_string(U64 seed, String8 string) { - U64 result = seed; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } + U64 result = XXH3_64bits_withSeed(string.str, string.size, seed); return result; } diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 2d112567..f484a6e1 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -7,6 +7,7 @@ internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) { + ProfBeginFunction(); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); @@ -25,6 +26,7 @@ e_eval_from_expr(Arena *arena, E_Expr *expr) { e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]); } + ProfEnd(); return eval; } @@ -83,7 +85,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { - E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key); + E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); B32 has_vtable = 0; for(U64 idx = 0; idx < ptee_type->count; idx += 1) { @@ -166,7 +168,7 @@ e_value_eval_from_eval(E_Eval eval) if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64)) { Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); U64 valid_bits_mask = 0; for(U64 idx = 0; idx < type->count; idx += 1) { diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0c270083..95e471a3 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -123,23 +123,21 @@ e_lookup_rule_from_string(String8 string) E_LOOKUP_INFO_FUNCTION_DEF(default) { E_LookupInfo lookup_info = {0}; - Temp scratch = scratch_begin(&arena, 1); { - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key); + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) { - E_Type *type = e_type_from_key(scratch.arena, lhs_type_key); + E_Type *type = e_type_from_key__cached(lhs_type_key); lookup_info.idxed_expr_count = type->count; - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key)); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); if(direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Class || direct_type_kind == E_TypeKind_Union || direct_type_kind == E_TypeKind_Enum) { - E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); + E_Type *direct_type = e_type_from_key__cached(direct_type_key); lookup_info.named_expr_count = direct_type->count; } } @@ -148,16 +146,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) lhs_type_kind == E_TypeKind_Union || lhs_type_kind == E_TypeKind_Enum) { - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); lookup_info.named_expr_count = lhs_type->count; } else if(lhs_type_kind == E_TypeKind_Array) { - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); lookup_info.idxed_expr_count = lhs_type->count; } } - scratch_end(scratch); return lookup_info; } @@ -213,7 +210,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) } if(match.kind == E_MemberKind_Null) { - E_Type *type = e_type_from_key(scratch.arena, check_type_key); + E_Type *type = e_type_from_key__cached(check_type_key); if(type->enum_vals != 0) { String8 lookup_string = exprr->string; @@ -422,7 +419,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) E_TypeKind struct_type_kind = E_TypeKind_Null; if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) { - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); if(lhs_type->count == 1 && (direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Union || @@ -459,7 +456,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) //- rjf: struct case -> the lookup-range will return a range of members if(do_struct_range) { - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); Rng1U64 legal_idx_range = r1u64(0, lhs_type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -667,6 +664,7 @@ internal E_IRGenRule * e_irgen_rule_from_string(String8 string) { E_IRGenRule *rule = &e_irgen_rule__default; + if(e_ir_ctx != 0 && e_ir_ctx->irgen_rule_map != 0 && e_ir_ctx->irgen_rule_map->slots_count != 0) { E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map; U64 hash = e_hash_from_string(5381, string); @@ -710,7 +708,7 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St 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 hash = e_hash_from_string(5381, str8_struct(&type_key)); U64 slot_idx = map->slots_count; SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); } @@ -724,14 +722,17 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St internal E_ExprList e_auto_hook_tag_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; //- rjf: gather exact-type-key-matches from the map + if(map != 0 && map->slots_count != 0) { - U64 hash = e_hash_from_type_key(type_key); + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); U64 slot_idx = hash%map->slots_count; for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next) { @@ -743,7 +744,7 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } //- rjf: gather fuzzy matches from all patterns in the map - if(map->first_pattern != 0) + if(map != 0 && 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) @@ -773,6 +774,38 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) scratch_end(scratch); } + ProfEnd(); + return exprs; +} + +internal E_ExprList +e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) +{ + E_ExprList exprs = {0}; + if(e_ir_ctx != 0 && e_ir_ctx->type_auto_hook_cache_map != 0 && e_ir_ctx->type_auto_hook_cache_map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); + U64 slot_idx = hash%e_ir_ctx->type_auto_hook_cache_map->slots_count; + E_TypeAutoHookCacheNode *node = 0; + for(E_TypeAutoHookCacheNode *n = e_ir_ctx->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) + { + // TODO(rjf): @cfg hack!!! should not be using this arena... + node = push_array(e_type_state->arena, E_TypeAutoHookCacheNode, 1); + SLLQueuePush(e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].last, node); + node->key = type_key; + node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key); + } + exprs = node->exprs; + } return exprs; } @@ -1081,30 +1114,64 @@ E_IRGEN_FUNCTION_DEF(default) { default:{}break; - //- rjf: references -> just descend to sub-expr - case E_ExprKind_Ref: - { - result = e_irtree_and_type_from_expr(arena, expr->ref); - }break; - //- rjf: accesses case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { Temp scratch = scratch_begin(&arena, 1); E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_irtree.type_key); - String8 lookup_rule_name = expr->string; - if(lhs_type->kind == E_TypeKind_Set) - { - lookup_rule_name = lhs_type->name; - } E_Expr *rhs = lhs->next; - E_LookupRule *lookup_rule = e_lookup_rule_from_string(lookup_rule_name); - E_LookupInfo lookup_info = lookup_rule->info(arena, lhs, str8_zero()); - E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); - result = lookup_access.irtree_and_type; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + + // rjf: determine lookup rule - first check explicitly-specified tags + E_LookupRule *lookup_rule = &e_lookup_rule__default; + for(E_Expr *tag = lhs->first_tag; tag != &e_expr_nil; tag = tag->next) + { + E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); + if(candidate != &e_lookup_rule__nil) + { + lookup_rule = candidate; + break; + } + } + + // rjf: if the lookup rule is the default, try to (a) apply set-name hooks, or (b) apply auto-hooks + if(lookup_rule == &e_lookup_rule__default) + { + // rjf: try set name + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + if(lhs_type->kind == E_TypeKind_Set) + { + E_LookupRule *candidate = e_lookup_rule_from_string(lhs_type->name); + if(candidate != &e_lookup_rule__nil) + { + lookup_rule = candidate; + } + } + + // rjf: try auto tags + if(lookup_rule == &e_lookup_rule__default) + { + E_ExprList auto_tags = e_auto_hook_tag_exprs_from_type_key__cached(lhs_irtree.type_key); + for(E_ExprNode *n = auto_tags.first; n != 0; n = n->next) + { + E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); + if(candidate != &e_lookup_rule__nil) + { + lookup_rule = candidate; + break; + } + } + } + } + + // rjf: use lookup rule to actually do the access + ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name)) + { + E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, str8_zero()); + E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); + result = lookup_access.irtree_and_type; + } scratch_end(scratch); }break; @@ -1860,15 +1927,20 @@ E_IRGEN_FUNCTION_DEF(default) internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { + ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_Ref) + { + expr = expr->ref; + } //- 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; + String8 name = tag->string; E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); if(irgen_rule_candidate != &e_irgen_rule__default) { @@ -1916,24 +1988,40 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } // rjf: do this rule's generation - result = t->rule->irgen(arena, expr, t->tag); + ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) + { + 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); + E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) { 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) + B32 tag_is_poisoned = 0; + U64 hash = e_hash_from_string(5381, str8_struct(&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 *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->rule = rule; - task->tag = tag; - break; + if(n->tag == tag) + { + tag_is_poisoned = 1; + break; + } + } + if(!tag_is_poisoned) + { + E_IRGenRule *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; + } } } } @@ -1959,6 +2047,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } scratch_end(scratch); + ProfEnd(); return result; } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index dace3b8b..ce872a96 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -73,7 +73,7 @@ struct E_LookupAccess E_IRTreeAndType irtree_and_type; }; -#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs, String8 filter) +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, String8 filter) #define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name #define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); @@ -226,6 +226,31 @@ struct E_UsedTagMap E_UsedTagSlot *slots; }; +//////////////////////////////// +//~ rjf: Type Key -> Auto Hook Expr List Cache + +typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; +struct E_TypeAutoHookCacheNode +{ + E_TypeAutoHookCacheNode *next; + E_TypeKey key; + E_ExprList exprs; +}; + +typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; +struct E_TypeAutoHookCacheSlot +{ + E_TypeAutoHookCacheNode *first; + E_TypeAutoHookCacheNode *last; +}; + +typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; +struct E_TypeAutoHookCacheMap +{ + U64 slots_count; + E_TypeAutoHookCacheSlot *slots; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -237,6 +262,7 @@ struct E_IRCtx E_IRGenRuleMap *irgen_rule_map; E_AutoHookMap *auto_hook_map; E_UsedTagMap *used_tag_map; + E_TypeAutoHookCacheMap *type_auto_hook_cache_map; }; //////////////////////////////// @@ -304,6 +330,7 @@ internal E_IRGenRule *e_irgen_rule_from_string(String8 string); 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); +internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key); //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 9185c159..474163ef 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -2038,6 +2038,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; E_Expr *callee_expr = atom; E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); + if(callee_expr->kind == E_ExprKind_LeafIdent) + { + call_expr->string = callee_expr->string; + } e_expr_push_child(call_expr, callee_expr); for(B32 done = 0; !done && it < it_opl;) { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 7c91ce63..60c30953 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -250,6 +250,8 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->cons_key_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_key_slots_count); e_type_state->member_cache_slots_count = 256; e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count); + e_type_state->type_cache_slots_count = 1024; + e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); } //////////////////////////////// @@ -522,13 +524,12 @@ e_type_key_match(E_TypeKey l, E_TypeKey r) //- rjf: key -> info extraction internal U64 -e_hash_from_type_key(E_TypeKey key) +e_hash_from_type(E_Type *type) { U64 hash = 0; - if(!e_type_key_match(e_type_key_zero(), key)) + if(type != &e_type_nil) { Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); String8List strings = {0}; str8_serial_begin(scratch.arena, &strings); str8_serial_push_struct(scratch.arena, &strings, &type->kind); @@ -1133,6 +1134,34 @@ e_type_from_key(Arena *arena, E_TypeKey key) return type; } +internal E_Type * +e_type_from_key__cached(E_TypeKey key) +{ + E_Type *type = &e_type_nil; + { + U64 hash = e_hash_from_string(5381, str8_struct(&key)); + U64 slot_idx = hash%e_type_state->type_cache_slots_count; + E_TypeCacheNode *node = 0; + for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(e_type_key_match(key, n->key)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_type_state->arena, E_TypeCacheNode, 1); + node->key = key; + node->type = e_type_from_key(e_type_state->arena, key); + SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); + } + type = node->type; + } + return type; +} + internal U64 e_type_byte_size_from_key(E_TypeKey key) { @@ -1185,10 +1214,8 @@ e_type_direct_from_key(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); result = type->direct_type_key; - scratch_end(scratch); }break; } return result; @@ -1204,10 +1231,8 @@ e_type_owner_from_key(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); result = type->owner_type_key; - scratch_end(scratch); }break; } return result; @@ -1346,21 +1371,18 @@ e_type_match(E_TypeKey l, E_TypeKey r) case E_TypeKind_Array: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { result = 1; } - scratch_end(scratch); }break; case E_TypeKind_Function: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { B32 params_match = 1; @@ -1377,14 +1399,12 @@ e_type_match(E_TypeKey l, E_TypeKey r) } result = params_match; } - scratch_end(scratch); }break; case E_TypeKind_Method: { - Temp scratch = scratch_begin(0, 0); - E_Type *lt = e_type_from_key(scratch.arena, l); - E_Type *rt = e_type_from_key(scratch.arena, r); + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key) && e_type_match(lt->owner_type_key, rt->owner_type_key)) @@ -1403,7 +1423,6 @@ e_type_match(E_TypeKey l, E_TypeKey r) } result = params_match; } - scratch_end(scratch); }break; } } @@ -1448,7 +1467,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_MemberList members_list = {0}; B32 members_need_offset_sort = 0; { - E_Type *root_type = e_type_from_key(scratch.arena, key); + E_Type *root_type = e_type_from_key__cached(key); typedef struct Task Task; struct Task { @@ -1487,7 +1506,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) t->inheritance_chain = e_type_key_list_copy(scratch.arena, &task->inheritance_chain); e_type_key_list_push(scratch.arena, &t->inheritance_chain, type->members[member_idx].type_key); t->type_key = type->members[member_idx].type_key; - t->type = e_type_from_key(scratch.arena, type->members[member_idx].type_key); + t->type = e_type_from_key__cached(type->members[member_idx].type_key); SLLQueuePush(first_task, last_task, t); members_need_offset_sort = 1; } @@ -1608,26 +1627,21 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { default: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_Bitfield: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); e_type_lhs_string_from_key(arena, type->direct_type_key, out, prec, skip_return); str8_list_pushf(arena, out, ": %I64u", type->count); - scratch_end(scratch); }break; case E_TypeKind_Modifier: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); if(type->flags & E_TypeFlag_Const) @@ -1638,7 +1652,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { str8_list_push(arena, out, str8_lit("volatile ")); } - scratch_end(scratch); }break; case E_TypeKind_Variadic: @@ -1652,11 +1665,9 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Class: case E_TypeKind_Alias: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; @@ -1665,13 +1676,11 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_IncompleteClass: keyword = str8_lit("class"); goto fwd_udt; fwd_udt:; { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); str8_list_push(arena, out, push_str8_copy(arena, type->name)); str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); }break; case E_TypeKind_Array: @@ -1726,11 +1735,10 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_MemberPtr: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - E_Type *container = e_type_from_key(scratch.arena, type->owner_type_key); + E_Type *container = e_type_from_key__cached(type->owner_type_key); if(container->kind != E_TypeKind_Null) { str8_list_push(arena, out, push_str8_copy(arena, container->name)); @@ -1740,7 +1748,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("")); } str8_list_push(arena, out, str8_lit("::*")); - scratch_end(scratch); }break; } } @@ -1771,8 +1778,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Array: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1783,13 +1789,11 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("]")); E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); - scratch_end(scratch); }break; case E_TypeKind_Function: { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, key); + E_Type *type = e_type_from_key__cached(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1818,7 +1822,6 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); - scratch_end(scratch); }break; } } diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 89fb27b2..2802e75a 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -197,6 +197,23 @@ struct E_ConsTypeSlot E_ConsTypeNode *last; }; +//- rjf: unpacked type cache + +typedef struct E_TypeCacheNode E_TypeCacheNode; +struct E_TypeCacheNode +{ + E_TypeCacheNode *next; + E_TypeKey key; + E_Type *type; +}; + +typedef struct E_TypeCacheSlot E_TypeCacheSlot; +struct E_TypeCacheSlot +{ + E_TypeCacheNode *first; + E_TypeCacheNode *last; +}; + //- rjf: member lookup cache types typedef struct E_MemberHashNode E_MemberHashNode; @@ -266,6 +283,10 @@ struct E_TypeState // rjf: member cache table U64 member_cache_slots_count; E_MemberCacheSlot *member_cache_slots; + + // rjf: unpacked type cache + U64 type_cache_slots_count; + E_TypeCacheSlot *type_cache_slots; }; //////////////////////////////// @@ -325,10 +346,11 @@ internal E_TypeKey e_type_key_cons_base(Type *type); internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); //- rjf: key -> info extraction -internal U64 e_hash_from_type_key(E_TypeKey key); +internal U64 e_hash_from_type(E_Type *type); internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key); internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); +internal E_Type *e_type_from_key__cached(E_TypeKey key); internal E_TypeKey e_type_direct_from_key(E_TypeKey key); internal E_TypeKey e_type_owner_from_key(E_TypeKey key); internal E_TypeKey e_type_ptee_from_key(E_TypeKey key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index d2deaba4..3fd88419 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -374,6 +374,7 @@ ev_view_rule_info_from_string(String8 string) //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) +#if 0 // TODO(rjf): @cfg internal E_Expr * ev_resolved_from_expr(Arena *arena, E_Expr *expr) { @@ -387,7 +388,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { - E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key); + E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); B32 has_vtable = 0; for(U64 idx = 0; idx < ptee_type->count; idx += 1) { @@ -443,6 +444,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) ProfEnd(); return expr; } +#endif //////////////////////////////// //~ rjf: Block Building @@ -461,7 +463,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = ev_key_root(); tree.root->string = string; - tree.root->expr = ev_resolved_from_expr(arena, expr); + tree.root->expr = expr; tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -499,6 +501,9 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str continue; } + // rjf: unpack expr + E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); + // rjf: get expansion view rule info E_LookupRule *lookup_rule = &e_lookup_rule__default; EV_ViewRuleInfo *expand_rule = default_expand_view_rule_info; @@ -506,8 +511,8 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str E_Expr *expand_rule_tag = &e_expr_nil; for(E_Expr *tag = t->expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - E_LookupRule *lookup_rule_candidate = e_lookup_rule_from_string(tag->first->string); - EV_ViewRuleInfo *expand_rule_candidate = ev_view_rule_info_from_string(tag->first->string); + E_LookupRule *lookup_rule_candidate = e_lookup_rule_from_string(tag->string); + EV_ViewRuleInfo *expand_rule_candidate = ev_view_rule_info_from_string(tag->string); if(lookup_rule_candidate != &e_lookup_rule__nil) { lookup_rule = lookup_rule_candidate; @@ -525,12 +530,11 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str if(lookup_rule == &e_lookup_rule__default || expand_rule == default_expand_view_rule_info) { - E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); E_TypeKey expr_type_key = expr_irtree.type_key; E_TypeKind expr_type_kind = e_type_kind_from_key(expr_type_key); if(expr_type_kind == E_TypeKind_Set) { - E_Type *expr_type = e_type_from_key(scratch.arena, expr_type_key); + E_Type *expr_type = e_type_from_key__cached(expr_type_key); if(lookup_rule == &e_lookup_rule__default) { lookup_rule = e_lookup_rule_from_string(expr_type->name); @@ -547,7 +551,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str } // rjf: get top-level lookup/expansion info - E_LookupInfo lookup_info = lookup_rule->info(arena, t->expr, filter); + E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, filter); EV_ExpandInfo expand_info = expand_rule->expr_expand_info(arena, view, filter, t->expr, expand_rule_tag); // rjf: determine expansion info @@ -1077,7 +1081,7 @@ ev_row_is_expandable(EV_Row *row) { for(E_Expr *tag = row->expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(tag->first->string); + EV_ViewRuleInfo *info = ev_view_rule_info_from_string(tag->string); if(info->flags & EV_ViewRuleInfoFlag_Expandable) { result = 1; @@ -1429,7 +1433,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_Enum: { Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); String8 constant_name = {0}; for(U64 val_idx = 0; val_idx < type->count; val_idx += 1) { diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 5f537113..e931cbcf 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -327,7 +327,9 @@ internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) +#if 0 // TODO(rjf): @cfg internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); +#endif //////////////////////////////// //~ rjf: Block Building diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6797e546..7ef7e9cc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2431,7 +2431,7 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) String8List fixed_width_parts = {0}; String8List variable_width_parts = {0}; { - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); if(type->members != 0) for EachIndex(member_idx, type->count) { E_Member *member = &type->members[member_idx]; @@ -2528,7 +2528,7 @@ rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity) String8List fixed_width_parts = {0}; String8List variable_width_parts = {0}; { - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); if(type->members != 0) for EachIndex(member_idx, type->count) { E_Member *member = &type->members[member_idx]; @@ -2870,7 +2870,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) MD_Node *schema = rd_schema_from_name(scratch.arena, cfg->string); String8 name = cfg->string; E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_type_from_key__cached(type_key); // rjf: find member to which this write applies, reflect back in the cfg tree if(type->members != 0) for EachIndex(member_idx, type->count) @@ -8993,9 +8993,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); @@ -9039,9 +9038,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 name = rd_singular_from_code_name_plural(lhs_type->name); CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; for EachNonZeroEnumVal(CTRL_EntityKind, k) @@ -9119,9 +9117,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) // rjf: determine which debug info section we're dealing with RDI_SectionKind section = RDI_SectionKind_NULL; { - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); if(0){} else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} @@ -9296,8 +9293,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul else if(str8_match(tag->string, str8_lit("oct"), 0)) {radix = 8; } else if(str8_match(tag->string, str8_lit("no_addr"), 0)) {no_addr = 1;} else if(str8_match(tag->string, str8_lit("no_string"), 0)) {no_string = 1;} - else if(str8_match(tag->first->string, str8_lit("array"), 0)) {has_array = 1;} - else if(str8_match(tag->first->string, str8_lit("digits"), 0)) + else if(str8_match(tag->string, str8_lit("array"), 0)) {has_array = 1;} + else if(str8_match(tag->string, str8_lit("digits"), 0)) { E_Expr *num_expr = tag->first->next; E_Eval num_eval = e_eval_from_expr(scratch.arena, num_expr); @@ -9315,7 +9312,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } else { - E_Type *type = e_type_from_key(scratch.arena, eval.type_key); + E_Type *type = e_type_from_key__cached(eval.type_key); if(!(type->flags & E_TypeFlag_External)) { no_addr = 1; @@ -9484,7 +9481,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul case E_TypeKind_Array: { // rjf: unpack type info - E_Type *eval_type = e_type_from_key(scratch.arena, e_type_unwrap(eval.type_key)); + E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.type_key)); E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); U64 array_count = eval_type->count; @@ -9594,6 +9591,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul case E_TypeKind_IncompleteUnion: case E_TypeKind_IncompleteClass: { + ProfBegin("struct"); + // rjf: open brace { String8 brace = str8_lit("{"); @@ -9608,21 +9607,23 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul for(U64 member_idx = 0; member_idx < data_members.count && max_size > space_taken; member_idx += 1) { E_Member *mem = &data_members.v[member_idx]; - E_Expr *dot_expr = e_expr_ref_member_access(scratch.arena, eval.expr, mem->name); - E_Expr *dot_expr_resolved = ev_resolved_from_expr(scratch.arena, dot_expr); - E_Eval dot_eval = e_eval_from_expr(scratch.arena, dot_expr_resolved); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, out); - if(member_idx+1 < data_members.count) + ProfScope("member %.*s", str8_varg(mem->name)) { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - if(space_taken > max_size && member_idx+1 < data_members.count) - { - String8 ellipses = str8_lit("..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); + E_Expr *dot_expr = e_expr_ref_member_access(scratch.arena, eval.expr, mem->name); + E_Eval dot_eval = e_eval_from_expr(scratch.arena, dot_expr); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, out); + if(member_idx+1 < data_members.count) + { + String8 comma = str8_lit(", "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; + str8_list_push(arena, out, comma); + } + if(space_taken > max_size && member_idx+1 < data_members.count) + { + String8 ellipses = str8_lit("..."); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + str8_list_push(arena, out, ellipses); + } } } } @@ -9639,6 +9640,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul str8_list_push(arena, out, brace); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } + + ProfEnd(); }break; } @@ -12802,6 +12805,7 @@ rd_frame(void) // E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); + e_ir_ctx = 0; { E_IRCtx *ctx = ir_ctx; ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); @@ -12810,6 +12814,12 @@ rd_frame(void) 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); + ctx->used_tag_map = push_array(scratch.arena, E_UsedTagMap, 1); + ctx->used_tag_map->slots_count = 64; + ctx->used_tag_map->slots = push_array(scratch.arena, E_UsedTagSlot, ctx->used_tag_map->slots_count); + ctx->type_auto_hook_cache_map = push_array(scratch.arena, E_TypeAutoHookCacheMap, 1); + ctx->type_auto_hook_cache_map->slots_count = 256; + ctx->type_auto_hook_cache_map->slots = push_array(scratch.arena, E_TypeAutoHookCacheSlot, ctx->type_auto_hook_cache_map->slots_count); //- rjf: choose set of evallable meta names String8 evallable_meta_names[] = @@ -12980,6 +12990,7 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); } } + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, name, name); } //- rjf: add macro for collections with specific lookup rules diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0f785c4f..20b1703e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -925,7 +925,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) EV_Block *block = row->block; EV_Key key = row->key; E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); - E_Type *parent_type = e_type_from_key(arena, parent_irtree.type_key); + E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); @@ -959,7 +959,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); if(block_type_kind == E_TypeKind_Set) { - E_Type *block_type = e_type_from_key(scratch.arena, block_type_key); + E_Type *block_type = e_type_from_key__cached(block_type_key); info.group_cfg_name = rd_singular_from_code_name_plural(block_type->name); } } @@ -2298,7 +2298,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view // rjf: determine collection info for the block RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); - E_Type *type = e_type_from_key(scratch.arena, irtree.type_key); + E_Type *type = e_type_from_key__cached(irtree.type_key); #if 0 // TODO(rjf): @cfg for EachElement(idx, rd_collection_name_table) { From 657b78c4efb1bf6f4362aa05d5153a8bd1a2c106 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 09:57:13 -0800 Subject: [PATCH 046/755] eval: separate ir_ctx -> ir_state & ir_ctx; ir_state for implicit thread-local caching mechanisms for eval, ir_ctx for explicitly supplied user info --- src/eval/eval_ir.c | 66 ++++++++++++++++++++++++---------------- src/eval/eval_ir.h | 19 ++++++++++-- src/raddbg/raddbg_core.c | 10 ++---- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 95e471a3..bf136f9d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -61,13 +61,26 @@ e_expr_kind_is_comparison(E_ExprKind kind) internal E_IRCtx * e_selected_ir_ctx(void) { - return e_ir_ctx; + return e_ir_state->ctx; } internal void e_select_ir_ctx(E_IRCtx *ctx) { - e_ir_ctx = ctx; + if(e_ir_state == 0) + { + Arena *arena = arena_alloc(); + e_ir_state = push_array(arena, E_IRState, 1); + e_ir_state->arena = arena; + e_ir_state->arena_eval_start_pos = arena_pos(arena); + } + e_ir_state->ctx = ctx; + e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); + e_ir_state->used_tag_map->slots_count = 64; + e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); + e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); + e_ir_state->type_auto_hook_cache_map->slots_count = 256; + e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); } //////////////////////////////// @@ -102,11 +115,11 @@ internal E_LookupRule * e_lookup_rule_from_string(String8 string) { E_LookupRule *result = &e_lookup_rule__nil; - if(e_ir_ctx->lookup_rule_map != 0 && e_ir_ctx->lookup_rule_map->slots_count != 0) + if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) { U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_ir_ctx->lookup_rule_map->slots_count; - for(E_LookupRuleNode *n = e_ir_ctx->lookup_rule_map->slots[slot_idx].first; + U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; + for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; n != 0; n = n->next) { @@ -664,9 +677,9 @@ internal E_IRGenRule * e_irgen_rule_from_string(String8 string) { E_IRGenRule *rule = &e_irgen_rule__default; - if(e_ir_ctx != 0 && e_ir_ctx->irgen_rule_map != 0 && e_ir_ctx->irgen_rule_map->slots_count != 0) + if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->ctx->irgen_rule_map != 0 && e_ir_state->ctx->irgen_rule_map->slots_count != 0) { - E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map; + E_IRGenRuleMap *map = e_ir_state->ctx->irgen_rule_map; U64 hash = e_hash_from_string(5381, string); U64 slot_idx = hash%map->slots_count; for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) @@ -724,10 +737,10 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { ProfBeginFunction(); E_ExprList exprs = {0}; - if(e_ir_ctx != 0) + if(e_ir_state != 0 && e_ir_state->ctx != 0) { Temp scratch = scratch_begin(&arena, 1); - E_AutoHookMap *map = e_ir_ctx->auto_hook_map; + E_AutoHookMap *map = e_ir_state->ctx->auto_hook_map; //- rjf: gather exact-type-key-matches from the map if(map != 0 && map->slots_count != 0) @@ -782,12 +795,12 @@ internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) { E_ExprList exprs = {0}; - if(e_ir_ctx != 0 && e_ir_ctx->type_auto_hook_cache_map != 0 && e_ir_ctx->type_auto_hook_cache_map->slots_count != 0) + if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->type_auto_hook_cache_map != 0 && e_ir_state->type_auto_hook_cache_map->slots_count != 0) { U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); - U64 slot_idx = hash%e_ir_ctx->type_auto_hook_cache_map->slots_count; + U64 slot_idx = hash%e_ir_state->type_auto_hook_cache_map->slots_count; E_TypeAutoHookCacheNode *node = 0; - for(E_TypeAutoHookCacheNode *n = e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first; + for(E_TypeAutoHookCacheNode *n = e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first; n != 0; n = n->next) { @@ -798,9 +811,8 @@ e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) } if(node == 0) { - // TODO(rjf): @cfg hack!!! should not be using this arena... - node = push_array(e_type_state->arena, E_TypeAutoHookCacheNode, 1); - SLLQueuePush(e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].last, node); + node = push_array(e_ir_state->arena, E_TypeAutoHookCacheNode, 1); + SLLQueuePush(e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_state->type_auto_hook_cache_map->slots[slot_idx].last, node); node->key = type_key; node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key); } @@ -1807,16 +1819,16 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf identifiers case E_ExprKind_LeafIdent: { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_ctx->macro_map, expr->string); + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); if(macro_expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", expr->string); } else { - e_string2expr_map_inc_poison(e_ir_ctx->macro_map, expr->string); + e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, expr->string); result = e_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_ctx->macro_map, expr->string); + e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, expr->string); } }break; @@ -1946,8 +1958,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { B32 tag_is_poisoned = 0; U64 hash = e_hash_from_string(5381, str8_struct(&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) + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->tag == tag) { @@ -1981,10 +1993,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) 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; + U64 slot_idx = hash%e_ir_state->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); + DLLPushBack(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); } // rjf: do this rule's generation @@ -2002,8 +2014,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { B32 tag_is_poisoned = 0; U64 hash = e_hash_from_string(5381, str8_struct(&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) + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->tag == tag) { @@ -2034,12 +2046,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) 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) + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->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); + DLLRemove(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); break; } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index ce872a96..304c46ae 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -252,7 +252,7 @@ struct E_TypeAutoHookCacheMap }; //////////////////////////////// -//~ rjf: Parse Context +//~ rjf: IR Context typedef struct E_IRCtx E_IRCtx; struct E_IRCtx @@ -261,6 +261,21 @@ struct E_IRCtx E_LookupRuleMap *lookup_rule_map; E_IRGenRuleMap *irgen_rule_map; E_AutoHookMap *auto_hook_map; +}; + +//////////////////////////////// +//~ rjf: IR State + +typedef struct E_IRState E_IRState; +struct E_IRState +{ + Arena *arena; + U64 arena_eval_start_pos; + + // rjf: ir context + E_IRCtx *ctx; + + // rjf: caches E_UsedTagMap *used_tag_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; }; @@ -292,7 +307,7 @@ local_persist read_only E_IRGenRule e_irgen_rule__default = E_IRGEN_FUNCTION_NAME(default), }; global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -thread_static E_IRCtx *e_ir_ctx = 0; +thread_static E_IRState *e_ir_state = 0; //////////////////////////////// //~ rjf: Expr Kind Enum Functions diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7ef7e9cc..459c6b0e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12805,7 +12805,7 @@ rd_frame(void) // E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); - e_ir_ctx = 0; + if(e_ir_state != 0) { e_ir_state->ctx = 0; } { E_IRCtx *ctx = ir_ctx; ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); @@ -12814,12 +12814,6 @@ rd_frame(void) 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); - ctx->used_tag_map = push_array(scratch.arena, E_UsedTagMap, 1); - ctx->used_tag_map->slots_count = 64; - ctx->used_tag_map->slots = push_array(scratch.arena, E_UsedTagSlot, ctx->used_tag_map->slots_count); - ctx->type_auto_hook_cache_map = push_array(scratch.arena, E_TypeAutoHookCacheMap, 1); - ctx->type_auto_hook_cache_map->slots_count = 256; - ctx->type_auto_hook_cache_map->slots = push_array(scratch.arena, E_TypeAutoHookCacheSlot, ctx->type_auto_hook_cache_map->slots_count); //- rjf: choose set of evallable meta names String8 evallable_meta_names[] = @@ -16252,7 +16246,7 @@ X(getting_started) { if(t->expr->kind == E_ExprKind_LeafIdent) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_ctx->macro_map, t->expr->string); + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, t->expr->string); if(macro_expr != &e_expr_nil) { E_Eval eval = e_eval_from_expr(scratch.arena, macro_expr); From b9756d222aea0d210c14d591715790373ddb0f9b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 10:29:52 -0800 Subject: [PATCH 047/755] eval: sketch out parse/ir cache --- src/eval/eval_bundles.c | 6 +- src/eval/eval_ir.c | 35 ++++++ src/eval/eval_ir.h | 22 ++++ src/eval/eval_parse.c | 107 ++++++++++++------ src/eval/eval_parse.h | 45 ++++++-- src/eval/eval_types.c | 56 ++++----- src/eval/eval_types.h | 2 +- .../eval_visualization_core.c | 3 +- src/raddbg/raddbg_core.c | 23 ++-- src/raddbg/raddbg_views.c | 2 +- 10 files changed, 214 insertions(+), 87 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index f484a6e1..db040024 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -43,9 +43,9 @@ e_eval_from_string(Arena *arena, String8 string) internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval) { - if(e_parse_ctx && + if(e_parse_state && e_interpret_ctx && - e_parse_ctx->modules_count > 0 && + e_parse_state->ctx->modules_count > 0 && e_interpret_ctx->module_base != 0 && (e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S64)) || e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U64)) || @@ -54,7 +54,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) { U64 vaddr = eval.value.u64; U64 voff = vaddr - e_interpret_ctx->module_base[0]; - RDI_Parsed *rdi = e_parse_ctx->primary_module->rdi; + RDI_Parsed *rdi = e_parse_state->ctx->primary_module->rdi; RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index bf136f9d..5828596f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -81,6 +81,8 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); e_ir_state->type_auto_hook_cache_map->slots_count = 256; e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); + e_ir_state->irtree_and_type_cache_slots_count = 1024; + e_ir_state->irtree_and_type_cache_slots = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheSlot, e_ir_state->irtree_and_type_cache_slots_count); } //////////////////////////////// @@ -2255,3 +2257,36 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) result.str = str; return result; } + +//////////////////////////////// +//~ rjf: IRified Expression Cache + +internal E_IRTreeAndType +e_irtree_and_type_from_expr__cached(E_Expr *expr) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + { + U64 hash = e_hash_from_string(5381, str8_struct(&expr)); + U64 slot_idx = hash%e_ir_state->irtree_and_type_cache_slots_count; + E_IRTreeAndTypeCacheNode *node = 0; + for(E_IRTreeAndTypeCacheNode *n = e_ir_state->irtree_and_type_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(n->expr == expr) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheNode, 1); + SLLQueuePush(e_ir_state->irtree_and_type_cache_slots[slot_idx].first, e_ir_state->irtree_and_type_cache_slots[slot_idx].last, node); + node->irtree_and_type = e_irtree_and_type_from_expr(e_ir_state->arena, expr); + } + if(node != 0) + { + result = node->irtree_and_type; + } + } + return result; +} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 304c46ae..dbd901b9 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -266,6 +266,21 @@ struct E_IRCtx //////////////////////////////// //~ rjf: IR State +typedef struct E_IRTreeAndTypeCacheNode E_IRTreeAndTypeCacheNode; +struct E_IRTreeAndTypeCacheNode +{ + E_IRTreeAndTypeCacheNode *next; + E_Expr *expr; + E_IRTreeAndType irtree_and_type; +}; + +typedef struct E_IRTreeAndTypeCacheSlot E_IRTreeAndTypeCacheSlot; +struct E_IRTreeAndTypeCacheSlot +{ + E_IRTreeAndTypeCacheNode *first; + E_IRTreeAndTypeCacheNode *last; +}; + typedef struct E_IRState E_IRState; struct E_IRState { @@ -278,6 +293,8 @@ struct E_IRState // rjf: caches E_UsedTagMap *used_tag_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; + U64 irtree_and_type_cache_slots_count; + E_IRTreeAndTypeCacheSlot *irtree_and_type_cache_slots; }; //////////////////////////////// @@ -386,4 +403,9 @@ internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root); internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); +//////////////////////////////// +//~ rjf: IRified Expression Cache + +internal E_IRTreeAndType e_irtree_and_type_from_expr__cached(E_Expr *expr); + #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 474163ef..0b2a2dcd 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -619,22 +619,31 @@ e_token_array_make_first_opl(E_Token *first, E_Token *opl) internal E_ParseCtx * e_selected_parse_ctx(void) { - return e_parse_ctx; + return e_parse_state->ctx; } internal void e_select_parse_ctx(E_ParseCtx *ctx) { - e_parse_ctx = ctx; + if(e_parse_state == 0) + { + Arena *arena = arena_alloc(); + e_parse_state = push_array(arena, E_ParseState, 1); + e_parse_state->arena = arena; + e_parse_state->arena_eval_start_pos = arena_pos(arena); + } + e_parse_state->ctx = ctx; + e_parse_state->parse_cache_slots_count = 1024; + e_parse_state->parse_cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->parse_cache_slots_count); } internal U32 e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi) { U32 result = 0; - for(U64 idx = 0; idx < e_parse_ctx->modules_count; idx += 1) + for(U64 idx = 0; idx < e_parse_state->ctx->modules_count; idx += 1) { - if(e_parse_ctx->modules[idx].rdi == rdi) + if(e_parse_state->ctx->modules[idx].rdi == rdi) { result = (U32)idx; break; @@ -933,9 +942,9 @@ e_leaf_type_from_name(String8 name) { E_TypeKey key = zero_struct; B32 found = 0; - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) { - RDI_Parsed *rdi = e_parse_ctx->modules[module_idx].rdi; + RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); RDI_ParsedNameMap parsed_name_map = {0}; rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); @@ -1050,7 +1059,7 @@ e_type_from_expr(E_Expr *expr) case E_ExprKind_Ptr: { E_TypeKey direct_type_key = e_type_from_expr(expr->first); - result = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, direct_type_key, 1, 0); + result = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, direct_type_key, 1, 0); }break; case E_ExprKind_Array: { @@ -1365,7 +1374,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to else { E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - type->type_key = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); + type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); E_Expr *casted = atom; E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); e_expr_push_child(cast, type); @@ -1425,9 +1434,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: form namespaceified fallback versions of this lookup string String8List namespaceified_token_strings = {0}; { - E_Module *module = e_parse_ctx->primary_module; + E_Module *module = e_parse_state->ctx->primary_module; RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_ctx->ip_voff); + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); U64 proc_idx = scope->proc_idx; RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); @@ -1454,7 +1463,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: try members if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") { - U64 data_member_num = e_num_from_string(e_parse_ctx->member_map, token_string); + U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); if(data_member_num != 0) { atom_implicit_member_name = token_string; @@ -1465,15 +1474,15 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: try locals if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") { - E_Module *module = e_parse_ctx->primary_module; + E_Module *module = e_parse_state->ctx->primary_module; RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_ctx->locals_map, local_lookup_string); + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); if(local_num != 0) { identifier_type_is_possibly_dynamically_overridden = 1; RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_ctx->modules)); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); // rjf: grab location info for(U32 loc_block_idx = local_var->location_first; @@ -1481,7 +1490,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to loc_block_idx += 1) { RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_ctx->ip_voff && e_parse_ctx->ip_voff < block->scope_off_opl) + if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) { mapped_identifier = 1; space = module->space; @@ -1534,37 +1543,37 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: try registers if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") { - U64 reg_num = e_num_from_string(e_parse_ctx->regs_map, token_string); + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); if(reg_num != 0) { reg_code = reg_num; - type_key = e_type_key_reg(e_parse_ctx->primary_module->arch, reg_code); + type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); mapped_identifier = 1; - space = e_parse_ctx->ip_thread_space; - arch = e_parse_ctx->primary_module->arch; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; } } //- rjf: try register aliases if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") { - U64 alias_num = e_num_from_string(e_parse_ctx->reg_alias_map, token_string); + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); if(alias_num != 0) { alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_ctx->primary_module->arch, alias_code); + type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); mapped_identifier = 1; - space = e_parse_ctx->ip_thread_space; - arch = e_parse_ctx->primary_module->arch; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; } } //- rjf: try global variables if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) { - E_Module *module = &e_parse_ctx->modules[module_idx]; + E_Module *module = &e_parse_state->ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); RDI_ParsedNameMap parsed_name_map = {0}; @@ -1606,9 +1615,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: try thread variables if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) { - E_Module *module = &e_parse_ctx->modules[module_idx]; + E_Module *module = &e_parse_state->ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); RDI_ParsedNameMap parsed_name_map = {0}; @@ -1646,9 +1655,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: try procedures if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) { - E_Module *module = &e_parse_ctx->modules[module_idx]; + E_Module *module = &e_parse_state->ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); RDI_ParsedNameMap parsed_name_map = {0}; @@ -1694,7 +1703,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to mapped_identifier = 1; identifier_looks_like_type_expr = 1; MemoryZeroStruct(&space); - arch = e_parse_ctx->primary_module->arch; + arch = e_parse_state->ctx->primary_module->arch; } } @@ -1741,7 +1750,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } else if(reg_code != 0) { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[reg_code]; + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; E_OpList oplist = {0}; e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); @@ -1753,8 +1762,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } else if(alias_code != 0) { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[alias_slice.code]; + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; E_OpList oplist = {0}; e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); @@ -2303,3 +2312,35 @@ e_parse_expr_from_text(Arena *arena, String8 text) scratch_end(scratch); return parse.expr; } + +internal E_Parse +e_parse_expr_from_text__cached(String8 text) +{ + E_Parse parse = {0, &e_expr_nil}; + U64 hash = e_hash_from_string(5381, str8_struct(&text)); + U64 slot_idx = hash%e_parse_state->parse_cache_slots_count; + E_ParseCacheNode *node = 0; + for(E_ParseCacheNode *n = e_parse_state->parse_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->string, text, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + Temp scratch = scratch_begin(0, 0); + node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); + SLLQueuePush(e_parse_state->parse_cache_slots[slot_idx].first, e_parse_state->parse_cache_slots[slot_idx].last, node); + node->string = push_str8_copy(e_parse_state->arena, text); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); + node->parse = e_parse_expr_from_text_tokens(e_parse_state->arena, node->string, &tokens); + scratch_end(scratch); + } + if(node != 0) + { + parse = node->parse; + } + return parse; +} diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 6104a1c4..90b85c49 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -145,6 +145,17 @@ struct E_String2ExprMap E_String2ExprMapSlot *slots; }; +//////////////////////////////// +//~ rjf: Parse Results + +typedef struct E_Parse E_Parse; +struct E_Parse +{ + E_Token *last_token; + E_Expr *expr; + E_MsgList msgs; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -169,14 +180,33 @@ struct E_ParseCtx }; //////////////////////////////// -//~ rjf: Parse Results +//~ rjf: Parse State (Stateful thread-local caching mechanisms, not provided by user) -typedef struct E_Parse E_Parse; -struct E_Parse +typedef struct E_ParseCacheNode E_ParseCacheNode; +struct E_ParseCacheNode { - E_Token *last_token; - E_Expr *expr; - E_MsgList msgs; + E_ParseCacheNode *next; + String8 string; + E_Parse parse; +}; + +typedef struct E_ParseCacheSlot E_ParseCacheSlot; +struct E_ParseCacheSlot +{ + E_ParseCacheNode *first; + E_ParseCacheNode *last; +}; + +typedef struct E_ParseState E_ParseState; +struct E_ParseState +{ + Arena *arena; + U64 arena_eval_start_pos; + E_ParseCtx *ctx; + + // rjf: string -> parse cache + E_ParseCacheSlot *parse_cache_slots; + U64 parse_cache_slots_count; }; //////////////////////////////// @@ -185,7 +215,7 @@ struct E_Parse global read_only E_String2NumMap e_string2num_map_nil = {0}; global read_only E_String2ExprMap e_string2expr_map_nil = {0}; global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil}; -thread_static E_ParseCtx *e_parse_ctx = 0; +thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// //~ rjf: Basic Map Functions @@ -262,5 +292,6 @@ internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_Tok internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); internal E_Expr *e_parse_expr_from_text(Arena *arena, String8 text); +internal E_Parse e_parse_expr_from_text__cached(String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 60c30953..fa5fd05d 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1134,34 +1134,6 @@ e_type_from_key(Arena *arena, E_TypeKey key) return type; } -internal E_Type * -e_type_from_key__cached(E_TypeKey key) -{ - E_Type *type = &e_type_nil; - { - U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_type_state->type_cache_slots_count; - E_TypeCacheNode *node = 0; - for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) - { - if(e_type_key_match(key, n->key)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_type_state->arena, E_TypeCacheNode, 1); - node->key = key; - node->type = e_type_from_key(e_type_state->arena, key); - SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); - } - type = node->type; - } - return type; -} - internal U64 e_type_byte_size_from_key(E_TypeKey key) { @@ -1901,6 +1873,34 @@ e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) //////////////////////////////// //~ rjf: Cache Lookups +internal E_Type * +e_type_from_key__cached(E_TypeKey key) +{ + E_Type *type = &e_type_nil; + { + U64 hash = e_hash_from_string(5381, str8_struct(&key)); + U64 slot_idx = hash%e_type_state->type_cache_slots_count; + E_TypeCacheNode *node = 0; + for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) + { + if(e_type_key_match(key, n->key)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_type_state->arena, E_TypeCacheNode, 1); + node->key = key; + node->type = e_type_from_key(e_type_state->arena, key); + SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); + } + type = node->type; + } + return type; +} + internal E_MemberCacheNode * e_member_cache_node_from_type_key(E_TypeKey key) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 2802e75a..d17a4297 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -350,7 +350,6 @@ internal U64 e_hash_from_type(E_Type *type); internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key); internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); -internal E_Type *e_type_from_key__cached(E_TypeKey key); internal E_TypeKey e_type_direct_from_key(E_TypeKey key); internal E_TypeKey e_type_owner_from_key(E_TypeKey key); internal E_TypeKey e_type_ptee_from_key(E_TypeKey key); @@ -376,6 +375,7 @@ internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 //////////////////////////////// //~ rjf: Cache Lookups +internal E_Type *e_type_from_key__cached(E_TypeKey key); internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 3fd88419..ed606b9c 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -691,8 +691,7 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s EV_BlockTree tree = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); + E_Parse parse = e_parse_expr_from_text__cached(string); tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr); } scratch_end(scratch); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 459c6b0e..c1fe8830 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8905,7 +8905,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(locals) E_LookupInfo result = {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_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); e_string2num_map_node_array_sort__in_place(&nodes); String8List exprs_filtered = {0}; for EachIndex(idx, nodes.count) @@ -9177,7 +9177,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) // rjf: unpack row info RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; + E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; // rjf: build expr E_Expr *item_expr = &e_expr_nil; @@ -9196,7 +9196,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = procedure->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Value; item_expr->space = module->space; @@ -9213,7 +9213,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = gvar->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Offset; item_expr->space = module->space; @@ -9229,7 +9229,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = tvar->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Offset; item_expr->space = module->space; @@ -9241,7 +9241,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) { RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); item_expr->type_key = type_key; }break; @@ -10673,7 +10673,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_parse_ctx->locals_map, string); + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -10684,7 +10684,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_parse_ctx->member_map, string); + U64 member_num = e_num_from_string(e_parse_state->ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -10695,7 +10695,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_parse_ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -10706,7 +10706,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_parse_ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -13084,8 +13084,7 @@ rd_frame(void) { RD_Cfg *watch = n->v; String8 expr = rd_expr_from_cfg(watch); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr, &tokens); + E_Parse parse = e_parse_expr_from_text__cached(expr); if(parse.msgs.max_kind == E_MsgKind_Null) { e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, parse.expr); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 20b1703e..79412bca 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -5488,7 +5488,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) rd_rgba_from_theme_color(RD_ThemeColor_Thread7), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_parse_ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_parse_state->ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); From afd113adcc19769c59bfdde79ab2e9232053de4c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 12:16:28 -0800 Subject: [PATCH 048/755] rd: derive schema tree parse on startup rather than recomputing every time --- src/eval/eval_ir.c | 1 + src/eval/eval_parse.c | 1 + src/eval/eval_parse.h | 2 +- src/raddbg/raddbg_core.c | 15 ++++++++++++--- src/raddbg/raddbg_core.h | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5828596f..099ea486 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -74,6 +74,7 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena = arena; e_ir_state->arena_eval_start_pos = arena_pos(arena); } + arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); e_ir_state->ctx = ctx; e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); e_ir_state->used_tag_map->slots_count = 64; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 0b2a2dcd..87f57ade 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -632,6 +632,7 @@ e_select_parse_ctx(E_ParseCtx *ctx) e_parse_state->arena = arena; e_parse_state->arena_eval_start_pos = arena_pos(arena); } + arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); e_parse_state->ctx = ctx; e_parse_state->parse_cache_slots_count = 1024; e_parse_state->parse_cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->parse_cache_slots_count); diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 90b85c49..d91a2c76 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -180,7 +180,7 @@ struct E_ParseCtx }; //////////////////////////////// -//~ rjf: Parse State (Stateful thread-local caching mechanisms, not provided by user) +//~ rjf: Parse State (stateful thread-local caching mechanisms, not provided by user) typedef struct E_ParseCacheNode E_ParseCacheNode; struct E_ParseCacheNode diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c1fe8830..e5774a0a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1496,16 +1496,15 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 internal MD_Node * rd_schema_from_name(Arena *arena, String8 name) { - String8 schema_string = {0}; + MD_Node *schema = &md_nil_node; for EachElement(idx, rd_name_schema_info_table) { if(str8_match(name, rd_name_schema_info_table[idx].name, 0)) { - schema_string = rd_name_schema_info_table[idx].schema; + schema = rd_state->schemas[idx]; break; } } - MD_Node *schema = md_tree_from_string(arena, schema_string)->first; return schema; } @@ -11906,6 +11905,16 @@ rd_init(CmdLine *cmdln) rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); rd_state->top_regs = &rd_state->base_regs; + // rjf: set up schemas + { + U64 schemas_count = ArrayCount(rd_name_schema_info_table); + rd_state->schemas = push_array(rd_state->arena, MD_Node *, schemas_count); + for EachIndex(idx, schemas_count) + { + rd_state->schemas[idx] = md_tree_from_string(rd_state->arena, rd_name_schema_info_table[idx].schema)->first; + } + } + // rjf: set up top-level config entity trees { rd_state->root_cfg = rd_cfg_alloc(); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index b0ac9cba..b179840c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -834,6 +834,9 @@ struct RD_State Arena *project_path_arena; String8 project_path; + // rjf: schema table + MD_Node **schemas; + // rjf: log Log *log; String8 log_path; From 90c86dc812341a79225a80c54bcaf74bf5c7e4ff Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 13:20:25 -0800 Subject: [PATCH 049/755] eval/eval-viz: pull out rules for mapping exprs/irtrees -> lookup/expansion rules; use this path in the single-line value string generator; eliminate old non-view-rulified string generation paths --- src/eval/eval_ir.c | 78 ++- src/eval/eval_ir.h | 23 +- .../eval_visualization_core.c | 111 ++-- .../eval_visualization_core.h | 15 + src/raddbg/raddbg_core.c | 553 +++++++++--------- src/raddbg/raddbg_views.c | 17 +- src/raddbg/raddbg_views.h | 6 +- 7 files changed, 455 insertions(+), 348 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 099ea486..cfa03ed4 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -710,22 +710,26 @@ 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) +e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) { 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_TypeKey type_key = params->type_key; + if(params->type_pattern.size != 0) + { + E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); + E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + 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)); + node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, 0); + node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)); if(!e_type_key_match(e_type_key_zero(), type_key)) { U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); - U64 slot_idx = map->slots_count; + U64 slot_idx = hash%map->slots_count; SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); } else @@ -2291,3 +2295,61 @@ e_irtree_and_type_from_expr__cached(E_Expr *expr) } return result; } + +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Lookup Rule + +internal E_LookupRuleTagPair +e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) +{ + E_LookupRuleTagPair result = {&e_lookup_rule__default, &e_expr_nil}; + { + // rjf: first try explicitly-stored tags + if(result.rule == &e_lookup_rule__default) + { + for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) + { + E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + result.tag = tag; + break; + } + } + } + + // rjf: next try implicit set name -> rule mapping + if(result.rule == &e_lookup_rule__default) + { + E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); + if(type_kind == E_TypeKind_Set) + { + E_Type *type = e_type_from_key__cached(irtree->type_key); + String8 name = type->name; + E_LookupRule *candidate = e_lookup_rule_from_string(name); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + } + } + } + + // rjf: next try auto hook map + if(result.rule == &e_lookup_rule__default) + { + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + result.tag = n->v; + break; + } + } + } + } + return result; +} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index dbd901b9..0e26ed6e 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -135,6 +135,13 @@ struct E_LookupRuleMap U64 slots_count; }; +typedef struct E_LookupRuleTagPair E_LookupRuleTagPair; +struct E_LookupRuleTagPair +{ + E_LookupRule *rule; + E_Expr *tag; +}; + //////////////////////////////// //~ rjf: IR Generation Hooks @@ -201,6 +208,14 @@ struct E_AutoHookMap E_AutoHookNode *last_pattern; }; +typedef struct E_AutoHookParams E_AutoHookParams; +struct E_AutoHookParams +{ + E_TypeKey type_key; + String8 type_pattern; + String8 tag_expr_string; +}; + //////////////////////////////// //~ rjf: Used Tag Map Data Structure @@ -360,7 +375,8 @@ 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 void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params); +#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key); internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key); @@ -408,4 +424,9 @@ internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); internal E_IRTreeAndType e_irtree_and_type_from_expr__cached(E_Expr *expr); +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Lookup Rule + +internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); + #endif // EVAL_IR_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ed606b9c..15e80648 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -504,51 +504,15 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str // rjf: unpack expr E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); - // rjf: get expansion view rule info - E_LookupRule *lookup_rule = &e_lookup_rule__default; - EV_ViewRuleInfo *expand_rule = default_expand_view_rule_info; - E_Expr *lookup_rule_tag = &e_expr_nil; - E_Expr *expand_rule_tag = &e_expr_nil; - for(E_Expr *tag = t->expr->first_tag; tag != &e_expr_nil; tag = tag->next) - { - E_LookupRule *lookup_rule_candidate = e_lookup_rule_from_string(tag->string); - EV_ViewRuleInfo *expand_rule_candidate = ev_view_rule_info_from_string(tag->string); - if(lookup_rule_candidate != &e_lookup_rule__nil) - { - lookup_rule = lookup_rule_candidate; - lookup_rule_tag = tag; - } - if(expand_rule_candidate != &ev_nil_view_rule_info) - { - expand_rule = expand_rule_candidate; - expand_rule_tag = tag; - } - } + // rjf: get expr's lookup rule + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - // rjf: for set types, try to use the set's name to lookup rules, if we don't - // have any - if(lookup_rule == &e_lookup_rule__default || - expand_rule == default_expand_view_rule_info) - { - E_TypeKey expr_type_key = expr_irtree.type_key; - E_TypeKind expr_type_kind = e_type_kind_from_key(expr_type_key); - if(expr_type_kind == E_TypeKind_Set) - { - E_Type *expr_type = e_type_from_key__cached(expr_type_key); - if(lookup_rule == &e_lookup_rule__default) - { - lookup_rule = e_lookup_rule_from_string(expr_type->name); - } - if(expand_rule == default_expand_view_rule_info) - { - expand_rule = ev_view_rule_info_from_string(expr_type->name); - if(expand_rule == &ev_nil_view_rule_info) - { - expand_rule = default_expand_view_rule_info; - } - } - } - } + // rjf: get expr's expansion rule + EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + EV_ViewRuleInfo *expand_rule = expand_rule_and_tag.rule; + E_Expr *expand_rule_tag = expand_rule_and_tag.tag; // rjf: get top-level lookup/expansion info E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, filter); @@ -1510,3 +1474,62 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) scratch_end(scratch); return result; } + +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Expand Rule + +internal EV_ExpandRuleTagPair +ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) +{ + EV_ViewRuleInfo *default_expand_view_rule = ev_view_rule_info_from_string(str8_lit("default")); + EV_ExpandRuleTagPair result = {default_expand_view_rule, &e_expr_nil}; + { + // rjf: first try explicitly-stored tags + if(result.rule == default_expand_view_rule) + { + for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) + { + EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(tag->string); + if(candidate != &ev_nil_view_rule_info) + { + result.rule = candidate; + result.tag = tag; + break; + } + } + } + + // rjf: next try implicit set name -> rule mapping + if(result.rule == default_expand_view_rule) + { + E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); + if(type_kind == E_TypeKind_Set) + { + E_Type *type = e_type_from_key__cached(irtree->type_key); + String8 name = type->name; + EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(name); + if(candidate != &ev_nil_view_rule_info) + { + result.rule = candidate; + } + } + } + + // rjf: next try auto hook map + if(result.rule == default_expand_view_rule) + { + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(n->v->string); + if(candidate != &ev_nil_view_rule_info) + { + result.rule = candidate; + result.tag = n->v; + break; + } + } + } + } + return result; +} diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index e931cbcf..044dd6a1 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -128,6 +128,16 @@ struct EV_ViewRuleInfoTable U64 slots_count; }; +//////////////////////////////// +//~ rjf: Expansion Rule Types + +typedef struct EV_ExpandRuleTagPair EV_ExpandRuleTagPair; +struct EV_ExpandRuleTagPair +{ + EV_ViewRuleInfo *rule; + E_Expr *tag; +}; + //////////////////////////////// //~ rjf: Blocks @@ -368,4 +378,9 @@ internal String8 ev_string_from_hresult_code(U32 code); internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval); internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); +//////////////////////////////// +//~ rjf: Expression & IR-Tree => Expand Rule + +internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); + #endif // EVAL_VISUALIZATION_CORE_H diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e5774a0a..82d1c93d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9327,242 +9327,283 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } //- rjf: value/offset evaluations - else if(max_size > 0) switch(e_type_kind_from_key(e_type_unwrap(eval.type_key))) + else if(max_size > 0) { - //- rjf: default - leaf cases - default: + E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKind kind = e_type_kind_from_key(type_key); + switch(kind) { - E_Eval value_eval = e_value_eval_from_eval(eval); - String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - str8_list_push(arena, out, string); - }break; - - //- rjf: pointers - case E_TypeKind_Function: - case E_TypeKind_Ptr: - case E_TypeKind_LRef: - case E_TypeKind_RRef: - { - // rjf: unpack type info - E_TypeKind type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(e_type_unwrap(eval.type_key))); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - // rjf: unpack info about pointer destination - E_Eval value_eval = e_value_eval_from_eval(eval); - B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void); - B32 ptee_has_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - B32 did_string = 0; - if(!did_content && ptee_has_string && !no_string) + //- rjf: default - leaf cases + default: { - did_content = 1; - did_string = 1; - U64 string_memory_addr = value_eval.value.u64; - U64 element_size = e_type_byte_size_from_key(direct_type_key); - U64 string_buffer_size = 256; - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) - { - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); - if(read_good) - { - break; - } - } - string_buffer[string_buffer_size-1] = 0; - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring((char *)string_buffer);}break; - case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - str8_list_push(arena, out, string_escaped); - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - } - - // rjf: special case: push strings for symbols - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size != 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Void) || - (type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function))) - { - did_content = 1; - str8_list_push(arena, out, symbol_name); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; - } - - // rjf: special case: need symbol name, don't have one - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size == 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function)) && - (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - did_content = 1; - String8 string = str8_lit("???"); - str8_list_push(arena, out, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - } - - // rjf: push pointer value - B32 did_ptr_value = 0; - if(!no_addr || value_eval.value.u64 == 0) - { - did_ptr_value = 1; - if(did_content) - { - String8 left_paren = str8_lit(" ("); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; - str8_list_push(arena, out, left_paren); - } + E_Eval value_eval = e_value_eval_from_eval(eval); String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, out, string); - if(did_content) - { - String8 right_paren = str8_lit(")"); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, right_paren).x; - str8_list_push(arena, out, right_paren); - } - } + }break; - // rjf: descend for all other cases - B32 did_arrow = 0; - if(value_eval.value.u64 != 0 && !did_content && ptee_has_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) + //- rjf: pointers + case E_TypeKind_Function: + case E_TypeKind_Ptr: + case E_TypeKind_LRef: + case E_TypeKind_RRef: { - if(did_ptr_value && !did_arrow) - { - did_arrow = 1; - String8 arrow = str8_lit(" -> "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; - str8_list_push(arena, out, arrow); - } - did_content = 1; - if(depth < 4) - { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); - E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, out); - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - } - }break; - - //- rjf: arrays - case E_TypeKind_Array: - { - // rjf: unpack type info - E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - U64 array_count = eval_type->count; - - // rjf: get pointed-at type - B32 array_is_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - if(!did_content && array_is_string && !no_string) - { - U64 element_size = e_type_byte_size_from_key(direct_type_key); - did_content = 1; - U64 string_buffer_size = Clamp(1, array_count, 1024); - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - switch(eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - U64 string_memory_addr = eval.value.u64; - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+string_buffer_size)); - }break; - case E_Mode_Value: - { - MemoryCopy(string_buffer, &eval.value.u512[0], Min(string_buffer_size, sizeof(eval.value))); - }break; - } - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring_capped(string_buffer, string_buffer + string_buffer_size);}break; - case 2: {string = str8_from_16(arena, str16_cstring_capped(string_buffer, string_buffer + string_buffer_size));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - str8_list_push(arena, out, string_escaped); - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - } - - // rjf: descend in all other cases - if(!did_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - did_content = 1; + // rjf: unpack type info + E_TypeKind type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); + E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(e_type_unwrap(eval.type_key))); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - // rjf: [ + // rjf: unpack info about pointer destination + E_Eval value_eval = e_value_eval_from_eval(eval); + B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void); + B32 ptee_has_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || + direct_type_kind == E_TypeKind_S8 || + direct_type_kind == E_TypeKind_U8); + E_Space space = value_eval.space; + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process == &ctrl_entity_nil) { - String8 bracket = str8_lit("["); - str8_list_push(arena, out, bracket); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, bracket).x; + process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + } + String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1); + + // rjf: special case: push strings for textual string content + B32 did_content = 0; + B32 did_string = 0; + if(!did_content && ptee_has_string && !no_string) + { + did_content = 1; + did_string = 1; + U64 string_memory_addr = value_eval.value.u64; + U64 element_size = e_type_byte_size_from_key(direct_type_key); + U64 string_buffer_size = 1024; + U8 *string_buffer = push_array(arena, U8, string_buffer_size); + for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) + { + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); + if(read_good) + { + break; + } + } + string_buffer[string_buffer_size-1] = 0; + String8 string = {0}; + switch(element_size) + { + default:{string = str8_cstring((char *)string_buffer);}break; + case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; + case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; + } + String8 string_escaped = ev_escaped_from_raw_string(arena, string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; + space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + str8_list_push(arena, out, string_escaped); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + } + + // rjf: special case: push strings for symbols + if(value_eval.value.u64 != 0 && + !did_content && symbol_name.size != 0 && + flags & EV_StringFlag_ReadOnlyDisplayRules && + ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Void) || + (type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || + (type_kind == E_TypeKind_Function))) + { + did_content = 1; + str8_list_push(arena, out, symbol_name); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; + } + + // rjf: special case: need symbol name, don't have one + if(value_eval.value.u64 != 0 && + !did_content && symbol_name.size == 0 && + flags & EV_StringFlag_ReadOnlyDisplayRules && + ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || + (type_kind == E_TypeKind_Function)) && + (flags & EV_StringFlag_ReadOnlyDisplayRules)) + { + did_content = 1; + String8 string = str8_lit("???"); + str8_list_push(arena, out, string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + } + + // rjf: push pointer value + B32 did_ptr_value = 0; + if(!no_addr || value_eval.value.u64 == 0) + { + did_ptr_value = 1; + if(did_content) + { + String8 left_paren = str8_lit(" ("); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; + str8_list_push(arena, out, left_paren); + } + String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + str8_list_push(arena, out, string); + if(did_content) + { + String8 right_paren = str8_lit(")"); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, right_paren).x; + str8_list_push(arena, out, right_paren); + } + } + + // rjf: descend for all other cases + B32 did_arrow = 0; + if(value_eval.value.u64 != 0 && !did_content && ptee_has_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) + { + if(did_ptr_value && !did_arrow) + { + did_arrow = 1; + String8 arrow = str8_lit(" -> "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; + str8_list_push(arena, out, arrow); + } + did_content = 1; + if(depth < 4) + { + E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); + E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, out); + } + else + { + String8 ellipses = str8_lit("..."); + str8_list_push(arena, out, ellipses); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + } + } + }break; + + //- rjf: arrays + case E_TypeKind_Array: + { + // rjf: unpack type info + E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.type_key)); + E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + U64 array_count = eval_type->count; + + // rjf: get pointed-at type + B32 array_is_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || + direct_type_kind == E_TypeKind_S8 || + direct_type_kind == E_TypeKind_U8); + + // rjf: special case: push strings for textual string content + B32 did_content = 0; + if(!did_content && array_is_string && !no_string) + { + U64 element_size = e_type_byte_size_from_key(direct_type_key); + did_content = 1; + U64 string_buffer_size = Clamp(1, array_count, 1024); + U8 *string_buffer = push_array(arena, U8, string_buffer_size); + switch(eval.mode) + { + default:{}break; + case E_Mode_Offset: + { + U64 string_memory_addr = eval.value.u64; + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+string_buffer_size)); + }break; + case E_Mode_Value: + { + MemoryCopy(string_buffer, &eval.value.u512[0], Min(string_buffer_size, sizeof(eval.value))); + }break; + } + String8 string = {0}; + switch(element_size) + { + default:{string = str8_cstring_capped(string_buffer, string_buffer + string_buffer_size);}break; + case 2: {string = str8_from_16(arena, str16_cstring_capped(string_buffer, string_buffer + string_buffer_size));}break; + case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; + } + String8 string_escaped = ev_escaped_from_raw_string(arena, string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; + space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + str8_list_push(arena, out, string_escaped); + if(!no_addr || depth > 0) + { + str8_list_push(arena, out, str8_lit("\"")); + } + } + + // rjf: if we did not do any special content, then go to the regular arrays/structs/sets case + if(!did_content) + { + goto arrays_and_sets_and_structs; + } + }break; + + //- rjf: non-string-arrays/structs/sets + case E_TypeKind_Struct: + case E_TypeKind_Union: + case E_TypeKind_Class: + case E_TypeKind_IncompleteStruct: + case E_TypeKind_IncompleteUnion: + case E_TypeKind_IncompleteClass: + case E_TypeKind_Set: + arrays_and_sets_and_structs: + { + String8 opener_string = str8_lit("{"); + String8 closer_string = str8_lit("}"); + if(kind == E_TypeKind_Array) + { + opener_string = str8_lit("["); + closer_string = str8_lit("]"); + } + + // rjf: opener ({, [) + { + str8_list_push(arena, out, opener_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; } // rjf: build contents if(depth < 4) { - for(U64 idx = 0; idx < array_count && max_size > space_taken; idx += 1) + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.expr, &irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); + B32 is_first = 1; + for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) { - E_Expr *element_expr = e_expr_ref_array_index(scratch.arena, eval.expr, idx); - E_Eval element_eval = e_eval_from_expr(scratch.arena, element_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, element_eval, out); - if(idx+1 < array_count) + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + lookup_rule->range(scratch.arena, eval.expr, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + if(expr != &e_expr_nil) { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - if(space_taken > max_size && idx+1 < array_count) - { - String8 ellipses = str8_lit("..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); + if(!is_first) + { + String8 comma = str8_lit(", "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; + str8_list_push(arena, out, comma); + } + is_first = 0; + E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, child_eval, out); + if(space_taken > max_size && idx+1 < total_possible_child_count) + { + String8 ellipses = str8_lit(", ..."); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + str8_list_push(arena, out, ellipses); + } } } } @@ -9573,75 +9614,13 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; } - // rjf: ] + // rjf: closer (}, ]) { - String8 bracket = str8_lit("]"); - str8_list_push(arena, out, bracket); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, bracket).x; + str8_list_push(arena, out, closer_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; } - } - }break; - - //- rjf: structs - case E_TypeKind_Struct: - case E_TypeKind_Union: - case E_TypeKind_Class: - case E_TypeKind_IncompleteStruct: - case E_TypeKind_IncompleteUnion: - case E_TypeKind_IncompleteClass: - { - ProfBegin("struct"); - - // rjf: open brace - { - String8 brace = str8_lit("{"); - str8_list_push(arena, out, brace); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; - } - - // rjf: content - if(depth < 4) - { - E_MemberArray data_members = e_type_data_members_from_key__cached(e_type_unwrap(eval.type_key)); - for(U64 member_idx = 0; member_idx < data_members.count && max_size > space_taken; member_idx += 1) - { - E_Member *mem = &data_members.v[member_idx]; - ProfScope("member %.*s", str8_varg(mem->name)) - { - E_Expr *dot_expr = e_expr_ref_member_access(scratch.arena, eval.expr, mem->name); - E_Eval dot_eval = e_eval_from_expr(scratch.arena, dot_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, dot_eval, out); - if(member_idx+1 < data_members.count) - { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - if(space_taken > max_size && member_idx+1 < data_members.count) - { - String8 ellipses = str8_lit("..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); - } - } - } - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - - // rjf: close brace - { - String8 brace = str8_lit("}"); - str8_list_push(arena, out, brace); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; - } - - ProfEnd(); - }break; + }break; + } } scratch_end(scratch); @@ -12993,7 +12972,7 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); } } - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, name, name); + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); } //- rjf: add macro for collections with specific lookup rules diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 79412bca..ec82da74 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -973,11 +973,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: fill row's cells - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("expression"), .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.20f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("sizeof($expr)"), .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .string = str8_lit("view_rule"), .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.35f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .pct = 0.25f); + // rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("sizeof($expr)"), .pct = 0.15f); di_scope_close(di_scope); scratch_end(scratch); @@ -1210,6 +1210,13 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info scratch_end(scratch); }break; + + //- rjf: tag cells -> look up attached tag + case RD_WatchCellKind_Tag: + { + EV_View *ev_view = rd_view_eval_view(); + result.string = ev_view_rule_from_key(ev_view, row->key); + }break; } return result; } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 841045e1..f334c5ac 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -43,9 +43,9 @@ struct RD_CodeViewBuildResult typedef enum RD_WatchCellKind { - RD_WatchCellKind_String, // plain text - RD_WatchCellKind_Expr, // strings for forming expression, under some key; `expression` for expression, `view_rule` for view rule - RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)~ + RD_WatchCellKind_Expr, // strings to represent expression itself + RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity + RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` } RD_WatchCellKind; From de16c9cdefa176b202ec7b506b960fdd22b09afd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 14:13:01 -0800 Subject: [PATCH 050/755] keep active tab view states hot, even if their ui is not built on any given frame (because they are not selected) --- src/raddbg/raddbg_core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 82d1c93d..ec5f9836 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12098,6 +12098,33 @@ rd_frame(void) 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: iterate all tabs, touch their view-states + // + if(depth == 0) + { + Temp scratch = scratch_begin(0, 0); + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) + { + RD_Cfg *window = n->v; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) + { + for(RD_CfgNode *n = p->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + if(rd_cfg_is_project_filtered(tab)) + { + continue; + } + rd_view_state_from_cfg(tab); + } + } + } + scratch_end(scratch); + } + ////////////////////////////// //- rjf: garbage collect untouched immediate cfg trees // From a003a114250beb0149b69341810a36e33466c082 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 16:44:04 -0800 Subject: [PATCH 051/755] progress on mixing control (command, insertion) rows in cfg-list evaluation, for watch windows; e.g. empty row in watch window, add-new buttons in targets/breakpoints/watchpins/etc. --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 69 +++++++++++++++++++++++------- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 2 +- src/raddbg/raddbg_views.h | 17 -------- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 49c88b7f..55b49d50 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -87,7 +87,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[10] = {str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'frozen':bool, 'label':code_string}"), str8_lit_comp("")}, {str8_lit_comp("process"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, -{str8_lit_comp("module"), str8_lit_comp("x:{'label':code_string, 'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}"), str8_lit_comp("")}, +{str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}"), str8_lit_comp("")}, {str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 789ed7bd..1e48eb46 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -221,7 +221,7 @@ RD_VocabularyMap: //- rjf: modules { module, - ```x:{'label':code_string, 'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}```, + ```x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}```, } //- rjf: threads diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ec5f9836..e55c17e1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8878,7 +8878,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); result.user_data = cfgs; - result.idxed_expr_count = cfgs->count; + result.idxed_expr_count = cfgs->count + 1; } scratch_end(scratch); return result; @@ -8893,9 +8893,12 @@ E_LOOKUP_RANGE_FUNCTION_DEF(watches) for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 cfg_idx = read_range.min + idx; - String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; - exprs[idx] = e_parse_expr_from_text(arena, expr_string); - exprs_strings[idx] = push_str8_copy(arena, expr_string); + if(cfg_idx < cfgs->count) + { + String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; + exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs_strings[idx] = push_str8_copy(arena, expr_string); + } } } @@ -8987,6 +8990,13 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) } } +typedef struct RD_TopLevelCfgLookupAccel RD_TopLevelCfgLookupAccel; +struct RD_TopLevelCfgLookupAccel +{ + String8Array cmds; + RD_CfgArray cfgs; +}; + E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) { E_LookupInfo result = {0}; @@ -8995,11 +9005,28 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) E_TypeKey lhs_type_key = lhs->type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); - RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); - cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list); - result.user_data = cfgs; - result.idxed_expr_count = cfgs_list.count; + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name);\ + String8List cmds_list = {0}; + // TODO(rjf): @cfg hack - probably want to table-drive this + if(str8_match(cfg_name, str8_lit("target"), 0)) + { + str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + } + else if(str8_match(cfg_name, str8_lit("breakpoint"), 0)) + { + str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddBreakpoint].string); + str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); + str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); + } + else if(str8_match(cfg_name, str8_lit("watch_pin"), 0)) + { + str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); + } + RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); + accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); + accel->cmds = str8_array_from_list(arena, &cmds_list); + result.user_data = accel; + result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; } scratch_end(scratch); return result; @@ -9011,15 +9038,27 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) if(kind == E_ExprKind_ArrayIndex) { Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + Rng1U64 cmds_idx_range = r1u64(0, accel->cmds.count); + Rng1U64 cfgs_idx_range = r1u64(accel->cmds.count, accel->cmds.count + accel->cfgs.count); E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + if(contains_1u64(cmds_idx_range, rhs_value.u64)) { - RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + String8 cmd_name = accel->cmds.v[rhs_value.u64 - cmds_idx_range.min]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + E_TypeKey type_key = e_type_key_basic(E_TypeKind_U64); + E_Space cmd_space = e_space_make(RD_EvalSpaceKind_MetaCmd); + result.irtree_and_type.root = e_irtree_set_space(arena, cmd_space, e_irtree_const_u(arena, cmd_kind)); + result.irtree_and_type.type_key = type_key; + result.irtree_and_type.mode = E_Mode_Value; + } + else if(contains_1u64(cfgs_idx_range, rhs_value.u64)) + { + RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64 - cfgs_idx_range.min]; E_Space cfg_space = rd_eval_space_from_cfg(cfg); String8 cfg_name = cfg->string; E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); @@ -12854,12 +12893,12 @@ rd_frame(void) E_TypeKey location_type_key = {0}; { E_MemberList vaddr_range_members_list = {0}; - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min")); - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max")); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); bool_type_key = e_type_key_basic(E_TypeKind_Bool); u64_type_key = e_type_key_basic(E_TypeKind_U64); - vaddr_range_type_key = e_type_key_cons(E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); + vaddr_range_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index b179840c..dc630036 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -96,6 +96,7 @@ enum RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaCtrlEntity, + RD_EvalSpaceKind_MetaCmd, }; //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index ec82da74..c48ef08b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2497,7 +2497,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view //- rjf: determine row's flags & color palette // ProfBegin("determine row's flags & color palette"); - UI_BoxFlags row_flags = 0; + UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; UI_Palette *palette = ui_top_palette(); { if(row_is_fresh) diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index f334c5ac..cec9acf9 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -136,23 +136,6 @@ struct RD_WatchViewColumn B32 rangify_braces; }; -typedef struct RD_WatchViewRowCtrl RD_WatchViewRowCtrl; -struct RD_WatchViewRowCtrl -{ - RD_EntityKind entity_kind; - CTRL_EntityKind ctrl_entity_kind; - RD_CmdKind kind; -}; - -typedef enum RD_WatchViewRowKind -{ - RD_WatchViewRowKind_Normal, - RD_WatchViewRowKind_Header, - RD_WatchViewRowKind_Canvas, - RD_WatchViewRowKind_PrettyEntityControls, -} -RD_WatchViewRowKind; - typedef struct RD_WatchPt RD_WatchPt; struct RD_WatchPt { From 50f8732e63deed5b81e3d41d942e42681f0e1308 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Feb 2025 19:38:57 -0800 Subject: [PATCH 052/755] fix num/idx/vidx/vnum coordinates to correctly apply to root row in watch windows --- .../eval_visualization_core.c | 52 +++++++------- .../eval_visualization_core.h | 6 +- src/raddbg/raddbg_views.c | 70 ++++++------------- 3 files changed, 52 insertions(+), 76 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 15e80648..8a311a1b 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -768,7 +768,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) { key = ev_key_make(ev_hash_from_key(ev_key_root()), 1); } - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); @@ -790,7 +790,7 @@ internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) { U64 result = 0; - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 hash = ev_hash_from_key(n->v.block->key); @@ -810,45 +810,45 @@ ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) } internal U64 -ev_vidx_from_num(EV_BlockRangeList *block_ranges, U64 num) +ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num) { - U64 vidx = 0; + U64 vnum = 0; { - U64 base_vidx = 0; + U64 base_vnum = 1; U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 next_base_num = base_num + (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); if(base_num <= num && num < next_base_num) { - U64 relative_vidx = (n->v.block->single_item ? 0 : (num - base_num)); - vidx = base_vidx + relative_vidx; + U64 relative_vnum = (n->v.block->single_item ? 0 : (num - base_num)); + vnum = base_vnum + relative_vnum; break; } base_num = next_base_num; - base_vidx += dim_1u64(n->v.range); + base_vnum += dim_1u64(n->v.range); } } - return vidx; + return vnum; } internal U64 -ev_num_from_vidx(EV_BlockRangeList *block_ranges, U64 vidx) +ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vnum) { U64 num = 0; { - U64 base_vidx = 0; + U64 base_vnum = 1; U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 next_base_vidx = base_vidx + dim_1u64(n->v.range); - if(base_vidx <= vidx && vidx < next_base_vidx) + U64 next_base_vnum = base_vnum + dim_1u64(n->v.range); + if(base_vnum <= vnum && vnum < next_base_vnum) { - U64 relative_num = (n->v.block->single_item ? 0 : (vidx - base_vidx)); + U64 relative_num = (n->v.block->single_item ? 0 : (vnum - base_vnum)); num = base_num + relative_num; break; } - base_vidx = next_base_vidx; + base_vnum = next_base_vnum; base_num += (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); } } @@ -859,30 +859,30 @@ ev_num_from_vidx(EV_BlockRangeList *block_ranges, U64 vidx) //~ rjf: Row Building internal EV_WindowedRowList -ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range) +ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range) { EV_WindowedRowList rows = {0}; { - U64 visual_idx_off = 0; + U64 base_vnum = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { // rjf: unpack this block/range pair Rng1U64 block_relative_range = n->v.range; U64 block_num_visual_rows = dim_1u64(block_relative_range); - Rng1U64 block_global_range = r1u64(visual_idx_off, visual_idx_off + block_num_visual_rows); + Rng1U64 block_global_range = r1u64(base_vnum, base_vnum + block_num_visual_rows); // rjf: get skip/chop of global range U64 num_skipped = 0; U64 num_chopped = 0; { - if(visible_range.min > block_global_range.min) + if(vnum_range.min > block_global_range.min) { - num_skipped = (visible_range.min - block_global_range.min); + num_skipped = (vnum_range.min - block_global_range.min); num_skipped = Min(num_skipped, block_num_visual_rows); } - if(visible_range.max < block_global_range.max) + if(vnum_range.max < block_global_range.max) { - num_chopped = (block_global_range.max - visible_range.max); + num_chopped = (block_global_range.max - vnum_range.max); num_chopped = Min(num_chopped, block_num_visual_rows); } } @@ -892,7 +892,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 block_relative_range.max - num_chopped); // rjf: sum & advance - visual_idx_off += block_num_visual_rows; + base_vnum += block_num_visual_rows; rows.count_before_visual += num_skipped; if(block_num_visual_rows != 0 && num_skipped != 0) { @@ -972,7 +972,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 internal EV_Row * ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num) { - U64 vidx = ev_vidx_from_num(block_ranges, num); + U64 vidx = ev_vnum_from_num(block_ranges, num); EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, r1u64(vidx, vidx+1)); EV_Row *result = 0; if(rows.first != 0) @@ -982,6 +982,8 @@ ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList * else { result = push_array(arena, EV_Row, 1); + result->block = &ev_nil_block; + result->expr = &e_expr_nil; } return result; } @@ -989,7 +991,7 @@ ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList * internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range) { - Rng1U64 vidx_range = r1u64(ev_vidx_from_num(block_ranges, num_range.min), ev_vidx_from_num(block_ranges, num_range.max)+1); + Rng1U64 vidx_range = r1u64(ev_vnum_from_num(block_ranges, num_range.min), ev_vnum_from_num(block_ranges, num_range.max)+1); EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vidx_range); return rows; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 044dd6a1..0747f963 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -355,13 +355,13 @@ internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockT internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num); internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key); -internal U64 ev_vidx_from_num(EV_BlockRangeList *block_ranges, U64 num); -internal U64 ev_num_from_vidx(EV_BlockRangeList *block_ranges, U64 vidx); +internal U64 ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num); +internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx); //////////////////////////////// //~ rjf: Row Building -internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range); +internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index c48ef08b..55471e30 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1510,26 +1510,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = 0; -#if 0 // TODO(rjf): @cfg - RD_WatchViewRowCtrl row_ctrls_[] = - { - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_LaunchAndRun }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_LaunchAndInit }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_SelectEntity }, - {RD_EntityKind_Target, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_Breakpoint, CTRL_EntityKind_Null, RD_CmdKind_EnableEntity }, - {RD_EntityKind_Breakpoint, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_FilePathMap, CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_AutoViewRule,CTRL_EntityKind_Null, RD_CmdKind_RemoveEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Machine, RD_CmdKind_FreezeEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Process, RD_CmdKind_Kill }, - {RD_EntityKind_Nil, CTRL_EntityKind_Process, RD_CmdKind_FreezeEntity }, - {RD_EntityKind_Nil, CTRL_EntityKind_Thread, RD_CmdKind_SelectThread }, - {RD_EntityKind_Nil, CTRL_EntityKind_Thread, RD_CmdKind_FreezeEntity }, - }; - RD_WatchViewRowCtrl *row_ctrls = row_ctrls_; - U64 row_ctrls_count = ArrayCount(row_ctrls_); -#endif ////////////////////////////// //- rjf: determine autocompletion string @@ -1620,7 +1600,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view EV_Key last_key = points[point_idx].pt_state->key; EV_Key last_parent_key = points[point_idx].pt_state->parent_key; points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); - if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key)) + if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) { points[point_idx].pt_state->key = last_parent_key; EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); @@ -1659,9 +1639,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view { EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - cursor_x_range = r1s64(0, (S64)row_info.cells.count); + cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); } - cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count-1)); + cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count)); // rjf: clamp x positions of cursor/mark tbl for EachEnumVal(Axis2, axis) @@ -1680,36 +1660,30 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view // if(snap_to_cursor) { - Rng1S64 item_range = r1s64(0, block_tree.total_item_count); - Rng1S64 row_range = r1s64(0, block_tree.total_row_count); - Rng1S64 scroll_row_idx_range = r1s64(row_range.min, ClampBot(row_range.min, row_range.max-1)); - S64 cursor_item_idx = cursor_tbl.y; - if(item_range.min <= cursor_item_idx && cursor_item_idx <= item_range.max) + Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); + if(contains_1s64(global_vnum_range, cursor_tbl.y)) { UI_ScrollPt *scroll_pt = &scroll_pos.y; //- rjf: compute visible row range - Rng1S64 visible_row_range = r1s64(scroll_pt->idx + 0 - !!(scroll_pt->off < 0), - scroll_pt->idx + 0 + num_possible_visible_rows); + Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), + scroll_pt->idx + 1 + num_possible_visible_rows); //- rjf: compute cursor row range from cursor item - Rng1S64 cursor_visibility_row_range = {0}; - if(row_blocks.count == 0) - { - cursor_visibility_row_range = r1s64(cursor_item_idx-2, cursor_item_idx+3); - } - else - { - cursor_visibility_row_range.min = (S64)ui_scroll_list_row_from_item(&row_blocks, (U64)cursor_item_idx) - 1; - cursor_visibility_row_range.max = cursor_visibility_row_range.min + 3; - } + Rng1S64 cursor_visibility_row_num_range = {0}; + cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; + cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; //- rjf: compute deltas & apply - S64 min_delta = Min(0, cursor_visibility_row_range.min-visible_row_range.min); - S64 max_delta = Max(0, cursor_visibility_row_range.max-visible_row_range.max); - S64 new_idx = scroll_pt->idx+min_delta+max_delta; - new_idx = clamp_1s64(scroll_row_idx_range, new_idx); - ui_scroll_pt_target_idx(scroll_pt, new_idx); + S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); + S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); + S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; + new_num = clamp_1s64(global_vnum_range, new_num); + if(new_num > 0) + { + U64 new_idx = (U64)(new_num - 1); + ui_scroll_pt_target_idx(scroll_pt, new_idx); + } } } @@ -2406,7 +2380,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view scroll_list_params.dim_px = dim_2f32(rect); scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(ewv->column_count-1, block_tree.total_item_count)); scroll_list_params.item_range = r1s64(0, block_tree.total_row_count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 0; + scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; scroll_list_params.row_blocks = row_blocks; } UI_BoxFlags disabled_flags = ui_top_flags(); @@ -2431,7 +2405,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view // EV_WindowedRowList rows = {0}; { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min, visible_row_rng.max + 1)); + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); } //////////////////////////// @@ -2449,7 +2423,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view EV_Row *row = &row_node->row; U64 row_hash = ev_hash_from_key(row->key); U64 row_depth = ev_depth_from_block(row->block); - B32 row_selected = (selection_tbl.min.y <= global_row_idx && global_row_idx <= selection_tbl.max.y); + B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); B32 row_expanded = ev_expansion_from_key(eval_view, row->key); B32 next_row_expanded = row_expanded; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); From 8a8f1e4fc2fcc3db553bbbf1cc51ea2bcf4aa204 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 10:34:47 -0800 Subject: [PATCH 053/755] work on new hover eval ui, built using the new cfg data structure, immediate-mode view states, etc.; all watch window features -> hover eval --- src/raddbg/raddbg_core.c | 46 ++++++++++++++++++++++++++++++++++----- src/raddbg/raddbg_views.c | 7 +++++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e55c17e1..d31fe8d7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6578,6 +6578,7 @@ rd_window_frame(void) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) RD_Palette(RD_PaletteCode_Floating) { + F32 hover_eval_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_open_t"), 1.f); RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); @@ -6586,23 +6587,42 @@ rd_window_frame(void) RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); rd_cfg_release_all_children(expr); rd_cfg_new(expr, ws->hover_eval_string); + UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) { ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); ui_set_next_pref_width(ui_em(60.f, 1.f)); ui_set_next_pref_height(ui_em(40.f, 1.f)); ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); - UI_Parent(container) + ui_set_next_squish(0.25f-0.25f*hover_eval_t); + ui_set_next_transparency(1.f-hover_eval_t); + UI_Box *container = ui_build_box_from_string(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow, + str8_lit("hover_eval_container")); + if(!ws->hover_eval_focused) { - UI_Row + for(UI_Event *evt = 0; ui_next_event(&evt);) { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + contains_2f32(container->rect, evt->pos)) + { + ws->hover_eval_focused = 1; + break; + } } + } + UI_Parent(container) UI_Focus(ws->hover_eval_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + { ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); ui_set_next_child_layout_axis(Axis2_Y); UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill + UI_Parent(view_contents_container) UI_WidthFill { RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); @@ -6610,6 +6630,19 @@ rd_window_frame(void) view_ui(expr->first->string, params, view_contents_container->rect); } } + UI_Signal sig = ui_signal_from_box(container); + if(ui_pressed(sig)) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig)) + { + ws->hover_eval_last_frame_idx = rd_state->frame_index; + } + else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) + { + rd_request_frame(); + } } } @@ -8206,6 +8239,7 @@ rd_window_frame(void) ProfScope("draw UI") { Temp scratch = scratch_begin(0, 0); + F32 box_squish_epsilon = 0.01f; //- rjf: unpack settings B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); @@ -8264,7 +8298,7 @@ rd_window_frame(void) } // rjf: push squish - if(box->squish != 0) + if(box->squish > box_squish_epsilon) { Vec2F32 box_dim = dim_2f32(box->rect); Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/2, -box->rect.y0)); @@ -8579,7 +8613,7 @@ rd_window_frame(void) } // rjf: pop squish - if(b->squish != 0) + if(b->squish > box_squish_epsilon) { dr_pop_xform2d(); dr_pop_tex2d_sample_kind(); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 55471e30..ed41cd99 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -4276,7 +4276,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - rd_watch_view_build(wv, str8_lit("collection:watches"), str8_lit(""), 1, 10, rect); + String8 expr = rd_view_expr_string(); + if(expr.size == 0) + { + expr = str8_lit("collection:watches"); + } + rd_watch_view_build(wv, expr, str8_lit(""), 1, 10, rect); ProfEnd(); } From ad4e6cbce571b83c8878a4499ed12f07c2612239 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 11:38:55 -0800 Subject: [PATCH 054/755] size hover eval watch window by predicted block tree --- src/raddbg/raddbg_core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d31fe8d7..c4f82a75 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6587,12 +6587,18 @@ rd_window_frame(void) RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); rd_cfg_release_all_children(expr); rd_cfg_new(expr, ws->hover_eval_string); + EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*40.f / row_height_px); + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PrefHeight(ui_px(row_height_px, 1.f)) { ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); ui_set_next_pref_width(ui_em(60.f, 1.f)); - ui_set_next_pref_height(ui_em(40.f, 1.f)); + ui_set_next_pref_height(ui_px(num_rows_t*row_height_px, 1.f)); ui_set_next_child_layout_axis(Axis2_Y); ui_set_next_squish(0.25f-0.25f*hover_eval_t); ui_set_next_transparency(1.f-hover_eval_t); @@ -8240,6 +8246,7 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); F32 box_squish_epsilon = 0.01f; + Rng2F32 window_rect = os_client_rect_from_window(ws->os); //- rjf: unpack settings B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); @@ -8597,9 +8604,15 @@ rd_window_frame(void) // rjf: draw focus border if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusBorder) && b->focus_active_t > 0.01f) { + Rng2F32 rect = b->rect; + if(b->flags & UI_BoxFlag_Floating) + { + rect = pad_2f32(rect, 2.f); + rect = intersect_2f32(window_rect, rect); + } Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); color.w *= b->focus_active_t; - R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } From a80bd6664d175c6bd842a21fccbbcb198e4e9f02 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 12:44:33 -0800 Subject: [PATCH 055/755] collapse all watch-table watch window view rules into specializations of singular watch view path --- src/raddbg/generated/raddbg.meta.c | 17 +- src/raddbg/generated/raddbg.meta.h | 32 +-- src/raddbg/raddbg.mdesk | 21 +- src/raddbg/raddbg_core.c | 48 +++- src/raddbg/raddbg_views.c | 400 +++-------------------------- src/raddbg/raddbg_views.h | 2 +- 6 files changed, 75 insertions(+), 445 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 55b49d50..e90162a2 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -719,7 +719,7 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -RD_ViewRuleInfo rd_view_rule_kind_info_table[28] = +RD_ViewRuleInfo rd_view_rule_kind_info_table[13] = { {{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, {str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, @@ -727,23 +727,8 @@ RD_ViewRuleInfo rd_view_rule_kind_info_table[28] = {str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, {str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, {str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, -{str8_lit_comp("locals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(locals)}, -{str8_lit_comp("registers"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(registers)}, -{str8_lit_comp("globals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(globals)}, -{str8_lit_comp("thread_locals"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(thread_locals)}, -{str8_lit_comp("types"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(types)}, -{str8_lit_comp("procedures"), str8_lit_comp("Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table."), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(procedures)}, -{str8_lit_comp("targets"), str8_lit_comp("Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section."), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(targets)}, -{str8_lit_comp("file_path_map"), str8_lit_comp("Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths."), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(file_path_map)}, -{str8_lit_comp("auto_view_rules"), str8_lit_comp("Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible."), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(auto_view_rules)}, -{str8_lit_comp("breakpoints"), str8_lit_comp("Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section."), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(breakpoints)}, -{str8_lit_comp("watch_pins"), str8_lit_comp("Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin."), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch_pins)}, -{str8_lit_comp("scheduler"), str8_lit_comp("Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads."), str8_lit_comp("Scheduler"), str8_lit_comp(""), RD_IconKind_Scheduler, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(scheduler)}, -{str8_lit_comp("call_stack"), str8_lit_comp("Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top."), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(call_stack)}, -{str8_lit_comp("modules"), str8_lit_comp("Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module."), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(modules)}, {str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, {str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, -{str8_lit_comp("output"), str8_lit_comp("Displays debug strings, output from attached processes."), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(output)}, {str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, {str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, {str8_lit_comp("checkbox"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Checkbox"), str8_lit_comp(""), RD_IconKind_CheckFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(checkbox)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b8f1cc6b..b75cbd58 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -392,23 +392,8 @@ RD_ViewRuleKind_GettingStarted, RD_ViewRuleKind_Settings, RD_ViewRuleKind_PendingFile, RD_ViewRuleKind_Watch, -RD_ViewRuleKind_Locals, -RD_ViewRuleKind_Registers, -RD_ViewRuleKind_Globals, -RD_ViewRuleKind_ThreadLocals, -RD_ViewRuleKind_Types, -RD_ViewRuleKind_Procedures, -RD_ViewRuleKind_Targets, -RD_ViewRuleKind_FilePathMap, -RD_ViewRuleKind_AutoViewRules, -RD_ViewRuleKind_Breakpoints, -RD_ViewRuleKind_WatchPins, -RD_ViewRuleKind_Scheduler, -RD_ViewRuleKind_CallStack, -RD_ViewRuleKind_Modules, RD_ViewRuleKind_Text, RD_ViewRuleKind_Disasm, -RD_ViewRuleKind_Output, RD_ViewRuleKind_Memory, RD_ViewRuleKind_Bitmap, RD_ViewRuleKind_Checkbox, @@ -663,23 +648,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); RD_VIEW_RULE_UI_FUNCTION_DEF(settings); RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file); RD_VIEW_RULE_UI_FUNCTION_DEF(watch); -RD_VIEW_RULE_UI_FUNCTION_DEF(locals); -RD_VIEW_RULE_UI_FUNCTION_DEF(registers); -RD_VIEW_RULE_UI_FUNCTION_DEF(globals); -RD_VIEW_RULE_UI_FUNCTION_DEF(thread_locals); -RD_VIEW_RULE_UI_FUNCTION_DEF(types); -RD_VIEW_RULE_UI_FUNCTION_DEF(procedures); -RD_VIEW_RULE_UI_FUNCTION_DEF(targets); -RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map); -RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules); -RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints); -RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins); -RD_VIEW_RULE_UI_FUNCTION_DEF(scheduler); -RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack); -RD_VIEW_RULE_UI_FUNCTION_DEF(modules); RD_VIEW_RULE_UI_FUNCTION_DEF(text); RD_VIEW_RULE_UI_FUNCTION_DEF(disasm); -RD_VIEW_RULE_UI_FUNCTION_DEF(output); RD_VIEW_RULE_UI_FUNCTION_DEF(memory); RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap); RD_VIEW_RULE_UI_FUNCTION_DEF(checkbox); @@ -701,7 +671,7 @@ extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern RD_ViewRuleInfo rd_view_rule_kind_info_table[28]; +extern RD_ViewRuleInfo rd_view_rule_kind_info_table[13]; extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1e48eb46..60a08afe 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1031,31 +1031,12 @@ RD_ViewRuleTable: //- rjf: temporary view for loading files - must analyze file before picking viewer { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } - //- rjf: watch or watch-style tables + //- rjf: watch view { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } - { Locals locals "Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Registers registers "Registers" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Globals globals "Globals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { ThreadLocals thread_locals "Thread Locals" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Types types "Types" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Procedures procedures "Procedures" "" Binoculars 1 1 1 0 0 0 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - - //- rjf: configuration watch tables - { Targets targets "Targets" "" Target 1 1 1 0 0 0 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } - { FilePathMap file_path_map "File Path Map" "" FileOutline 1 1 1 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } - { AutoViewRules auto_view_rules "Auto View Rules" "" Binoculars 1 1 1 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } - { Breakpoints breakpoints "Breakpoints" "" CircleFilled 1 1 1 0 0 0 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } - { WatchPins watch_pins "Watch Pins" "" Pin 1 1 1 0 0 0 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } - - //- rjf: debug entity info watch tables - { Scheduler scheduler "Scheduler" "" Scheduler 1 1 1 0 0 0 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } - { CallStack call_stack "Call Stack" "" Thread 1 1 1 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } - { Modules modules "Modules" "" Module 1 1 1 0 0 0 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } //- rjf: data visualizers { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } - { Output output "Output" "" List 0 0 0 0 0 0 1 "Displays debug strings, output from attached processes." } { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c4f82a75..62ab2812 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8607,7 +8607,7 @@ rd_window_frame(void) Rng2F32 rect = b->rect; if(b->flags & UI_BoxFlag_Floating) { - rect = pad_2f32(rect, 2.f); + rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); @@ -14476,7 +14476,7 @@ rd_frame(void) //- rjf: define all of the "fixed" tabs we care about #define FixedTab_XList \ -X(watch)\ +X(watches)\ X(locals)\ X(registers)\ X(globals)\ @@ -14486,16 +14486,20 @@ X(procedures)\ X(call_stack)\ X(breakpoints)\ X(watch_pins)\ -X(output)\ X(targets)\ X(scheduler)\ X(modules)\ -X(disasm)\ -X(memory)\ -X(getting_started) +Y(output, text, "query:output_log")\ +Y(disasm, disasm, "")\ +Y(memory, memory, "")\ +Z(getting_started) #define X(name) RD_Cfg *name = &rd_nil_cfg; +#define Y(name, rule, expr) RD_Cfg *name = &rd_nil_cfg; +#define Z(name) RD_Cfg *name = &rd_nil_cfg; FixedTab_XList #undef X +#undef Y +#undef Z //- rjf: find all the fixed tabs, and all text viewers RD_CfgList texts = {0}; @@ -14508,9 +14512,13 @@ X(getting_started) RD_Cfg *tab = n->v; B32 need_unhook = 1; if(0){} -#define X(name) else if(str8_match(tab->string, str8_lit(#name), 0)) {name = tab;} +#define X(name) else if(str8_match(tab->string, str8_lit("watch"), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit("query:" #name), 0)) {name = tab;} +#define Y(name, rule, expr) else if(str8_match(tab->string, str8_lit(#rule), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit(expr), 0)) {name = tab;} +#define Z(name) else if(str8_match(tab->string, str8_lit(#name), 0)) {name = tab;} FixedTab_XList #undef X +#undef Y +#undef Z else if(str8_match(tab->string, str8_lit("text"), 0)) {rd_cfg_list_push(scratch.arena, &texts, tab);} else { @@ -14527,14 +14535,22 @@ X(getting_started) rd_cfg_release(panels); //- rjf: allocate any missing tabs -#define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} +#define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit("watch")); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit("query:" #name));} +#define Y(name, rule, expr) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#rule)); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit(expr));} +#define Z(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} FixedTab_XList #undef X +#undef Y +#undef Z //- rjf: eliminate all tab selections #define X(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} +#define Y(name, rule, expr) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} +#define Z(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} FixedTab_XList #undef X +#undef Y +#undef Z for(RD_CfgNode *n = texts.first; n != 0; n = n->next) { rd_cfg_release(rd_cfg_child_from_string(n->v, str8_lit("selected"))); @@ -14586,14 +14602,14 @@ X(getting_started) // rjf: root_0_1 split RD_Cfg *root_0_1_0 = rd_cfg_new(root_0_1, str8_lit("0.60")); RD_Cfg *root_0_1_1 = rd_cfg_new(root_0_1, str8_lit("0.40")); - rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, watch); + rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, watches); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, locals); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, registers); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, globals); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, thread_locals); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, types); rd_cfg_insert_child(root_0_1_0, root_0_1_0->last, procedures); - rd_cfg_new(watch, str8_lit("selected")); + rd_cfg_new(watches, str8_lit("selected")); rd_cfg_new(root_0_1_0, str8_lit("tabs_on_bottom")); rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, call_stack); rd_cfg_insert_child(root_0_1_1, root_0_1_1->last, modules); @@ -14633,9 +14649,9 @@ X(getting_started) RD_Cfg *root_0_1 = rd_cfg_new(root_0, str8_lit("0.25")); RD_Cfg *root_0_2 = rd_cfg_new(root_0, str8_lit("0.25")); RD_Cfg *root_0_3 = rd_cfg_new(root_0, str8_lit("0.25")); - rd_cfg_insert_child(root_0_0, root_0_0->last, watch); + rd_cfg_insert_child(root_0_0, root_0_0->last, watches); rd_cfg_insert_child(root_0_0, root_0_0->last, types); - rd_cfg_new(watch, str8_lit("selected")); + rd_cfg_new(watches, str8_lit("selected")); rd_cfg_insert_child(root_0_1, root_0_1->last, scheduler); rd_cfg_insert_child(root_0_1, root_0_1->last, targets); rd_cfg_insert_child(root_0_1, root_0_1->last, breakpoints); @@ -14671,8 +14687,12 @@ X(getting_started) //- rjf: release any unused views from the previous layout #define X(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} +#define Y(name, rule, expr) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} +#define Z(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} FixedTab_XList #undef X +#undef Y +#undef Z }break; //- rjf: thread finding @@ -15007,7 +15027,9 @@ X(getting_started) RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); - if(view_kind == RD_ViewRuleKind_Text && panel_area > best_panel_area) + String8 view_expr = rd_expr_from_cfg(tab); + String8 file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); + if(view_kind == RD_ViewRuleKind_Text && file_path.size != 0 && panel_area > best_panel_area) { panel_w_any_src_code = panel; best_panel_area = panel_area; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index ed41cd99..fd8e2236 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1494,7 +1494,7 @@ rd_watch_view_init(RD_WatchViewState *ewv) } internal void -rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect) +rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -1505,11 +1505,34 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view //- rjf: unpack arguments // EV_View *eval_view = rd_view_eval_view(); - String8 filter = rd_view_filter(); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = 0; + String8 filter = rd_view_filter(); + String8 expr = rd_view_expr_string(); + if(expr.size == 0) + { + expr = str8_lit("query:watches"); + } + + ////////////////////////////// + //- rjf: decide if root should be implicit + // + // "implicit" means -> root is automatically expanded, row depth is 1 less than the + // block tree structure would suggest. this would be used if the root is, for instance, + // the "collection of all watches", to build a watch window. but this behavior is not + // as desirable if we are just using some other expression as the root. + // + B32 implicit_root = 0; + { + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_TypeKind kind = e_type_kind_from_key(eval.type_key); + if(kind == E_TypeKind_Set) + { + implicit_root = 1; + } + } ////////////////////////////// //- rjf: determine autocompletion string @@ -1550,8 +1573,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view { MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, root_expr); + if(implicit_root) + { + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + } + block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, expr); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); } @@ -2428,7 +2454,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view B32 next_row_expanded = row_expanded; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); B32 row_is_expandable = ev_row_is_expandable(row); - if(row_depth > 0) + if(implicit_root && row_depth > 0) { row_depth -= 1; } @@ -3944,7 +3970,10 @@ rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view // if(next_row_expanded != row_expanded) { - ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + if(!ev_key_match(ev_key_root(), row->key) || !implicit_root) + { + ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + } } } } @@ -4123,144 +4152,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) ProfEnd(); } -//////////////////////////////// -//~ rjf: targets @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(targets) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, str8_lit("collection:targets"), str8_zero(), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: file_path_map @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(file_path_map) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, str8_lit("collection:file_path_maps"), str8_zero(), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: auto_view_rules @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(auto_view_rules) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1, .is_non_code = 0); - } - rd_watch_view_build(wv, str8_lit("collection:auto_view_rules"), str8_zero(), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: breakpoints @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(breakpoints) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, str8_lit("collection:breakpoints"), str8_zero(), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: watch_pins @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(watch_pins) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, str8_lit("collection:watch_pins"), str8_zero(), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: scheduler @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(scheduler) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, str8_lit("collection:machines"), str8_lit("only: label str id callstack v count vaddr inline_depth"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: call_stack @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrameSelection, 0.05f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrame, 0.50f, .display_string = str8_lit("Symbol"), .dequote_string = 1); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.20f, .string = str8_lit("vaddr"), .display_string = str8_lit("Address"), .view_rule = str8_lit("cast:U64")); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .string = str8_lit("module.str"), .display_string = str8_lit("Module"), .dequote_string = 1, .is_non_code = 1); - } - rd_watch_view_build(wv, str8_lit("thread:current_thread.callstack.v"), str8_lit("array:'thread:current_thread.callstack.count', hex"), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: modules @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(modules) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.75f, .dequote_string = 1); - } - rd_watch_view_build(wv, str8_lit("collection:modules"), str8_lit("only: exe dbg str vaddr_range min max"), 0, 16, rect); - ProfEnd(); -} - //////////////////////////////// //~ rjf: watch @view_hook_impl @@ -4276,125 +4167,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); } - String8 expr = rd_view_expr_string(); - if(expr.size == 0) - { - expr = str8_lit("collection:watches"); - } - rd_watch_view_build(wv, expr, str8_lit(""), 1, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: locals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(locals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, str8_lit("collection:locals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: registers @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(registers) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, str8_lit("collection:registers"), str8_lit("hex"), 0, 16, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: globals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(globals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, str8_lit("collection:globals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: thread_locals @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(thread_locals) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, str8_lit("collection:thread_locals"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: types @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(types) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, str8_lit("collection:types"), str8_lit(""), 0, 10, rect); - ProfEnd(); -} - -//////////////////////////////// -//~ rjf: procedures @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(procedures) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.2f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.6f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.2f); - } - rd_watch_view_build(wv, str8_lit("collection:procedures"), str8_lit(""), 0, 10, rect); + rd_watch_view_build(wv, rect); ProfEnd(); } @@ -5001,107 +4774,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) scratch_end(scratch); } -//////////////////////////////// -//~ rjf: output @view_hook_impl - -typedef struct RD_OutputViewState RD_OutputViewState; -struct RD_OutputViewState -{ - U128 last_hash; - RD_CodeViewState cv; -}; - -RD_VIEW_RULE_UI_FUNCTION_DEF(output) -{ - RD_OutputViewState *ov = rd_view_state(RD_OutputViewState); - RD_CodeViewState *cv = &ov->cv; - rd_code_view_init(cv); - Temp scratch = scratch_begin(0, 0); - HS_Scope *hs_scope = hs_scope_open(); - TXT_Scope *txt_scope = txt_scope_open(); - - ////////////////////////////// - //- rjf: set up invariants - // - F32 bottom_bar_height = ui_top_font_size()*2.f; - Rng2F32 code_area_rect = r2f32p(rect.x0, rect.y0, rect.x1, rect.y1 - bottom_bar_height); - Rng2F32 bottom_bar_rect = r2f32p(rect.x0, rect.y1 - bottom_bar_height, rect.x1, rect.y1); - - ////////////////////////////// - //- rjf: unpack parameterization info - // - rd_regs()->file_path = str8_zero(); - rd_regs()->vaddr = 0; - rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; - - ////////////////////////////// - //- rjf: unpack text info - // - U128 key = d_state->output_log_key; - TXT_LangKind lang_kind = TXT_LangKind_Null; - U128 hash = {0}; - TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash); - String8 data = hs_data_from_hash(hs_scope, hash); - Rng1U64 empty_range = {0}; - if(info.lines_count == 0) - { - info.lines_count = 1; - info.lines_ranges = &empty_range; - } - - ////////////////////////////// - //- rjf: scroll-to-bottom - // - if(!u128_match(hash, ov->last_hash)) - { - ov->last_hash = hash; - cv->goto_line_num = info.lines_count; - cv->contain_cursor= 1; - } - - ////////////////////////////// - //- rjf: build code contents - // - { - rd_code_view_build(scratch.arena, cv, 0, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); - } - - ////////////////////////////// - //- rjf: build bottom bar - // - { - ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); - ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_Row - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Code) - { - ui_labelf("(Debug String Output)"); - ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Line: %I64d, Column: %I64d", rd_regs()->cursor.line, rd_regs()->cursor.column); - ui_spacer(ui_pct(1, 0)); - ui_labelf("(read only)"); - } - } - - ////////////////////////////// - //- rjf: store params - // - rd_store_view_param_s64(str8_lit("cursor_line"), rd_regs()->cursor.line); - rd_store_view_param_s64(str8_lit("cursor_column"), rd_regs()->cursor.column); - rd_store_view_param_s64(str8_lit("mark_line"), rd_regs()->mark.line); - rd_store_view_param_s64(str8_lit("mark_column"), rd_regs()->mark.column); - - txt_scope_close(txt_scope); - hs_scope_close(hs_scope); - scratch_end(scratch); -} - //////////////////////////////// //~ rjf: memory @view_hook_impl diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index cec9acf9..1e7108c2 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -245,6 +245,6 @@ internal void rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewCo //- rjf: watch view main hooks internal void rd_watch_view_init(RD_WatchViewState *ewv); -internal void rd_watch_view_build(RD_WatchViewState *ewv, String8 root_expr, String8 root_view_rule, B32 modifiable, U32 default_radix, Rng2F32 rect); +internal void rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect); #endif // RADDBG_VIEWS_H From 92d4f3ebb1062cf4d35f881d10ccae03ea460d8f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 13:02:12 -0800 Subject: [PATCH 056/755] eliminate old config code --- src/raddbg/raddbg_core.c | 72 --------------------------------------- src/raddbg/raddbg_core.h | 51 ++------------------------- src/raddbg/raddbg_views.h | 12 ------- 3 files changed, 2 insertions(+), 133 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 62ab2812..d3bdf05b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -51,78 +51,6 @@ rd_handle_list_copy(Arena *arena, RD_HandleList list) return result; } -//////////////////////////////// -//~ rjf: Config Type Functions - -internal void -rd_cfg_table_push_unparsed_string(Arena *arena, RD_CfgTable *table, String8 string, RD_CfgSrc source) -{ - if(table->slot_count == 0) - { - table->slot_count = 64; - table->slots = push_array(arena, RD_CfgSlot, table->slot_count); - } - MD_TokenizeResult tokenize = md_tokenize_from_text(arena, string); - MD_ParseResult parse = md_parse_from_text_tokens(arena, str8_lit(""), string, tokenize.tokens); - for MD_EachNode(tln, parse.root->first) if(tln->string.size != 0) - { - // rjf: map string -> hash*slot - String8 string = str8(tln->string.str, tln->string.size); - U64 hash = d_hash_from_string__case_insensitive(string); - U64 slot_idx = hash % table->slot_count; - RD_CfgSlot *slot = &table->slots[slot_idx]; - - // rjf: find existing value for this string - RD_CfgVal *val = 0; - for(RD_CfgVal *v = slot->first; v != 0; v = v->hash_next) - { - if(str8_match(v->string, string, StringMatchFlag_CaseInsensitive)) - { - val = v; - break; - } - } - - // rjf: create new value if needed - if(val == 0) - { - val = push_array(arena, RD_CfgVal, 1); - val->string = push_str8_copy(arena, string); - val->insertion_stamp = table->insertion_stamp_counter; - SLLStackPush_N(slot->first, val, hash_next); - SLLQueuePush_N(table->first_val, table->last_val, val, linear_next); - table->insertion_stamp_counter += 1; - } - - // rjf: create new node within this value - RD_CfgTree *tree = push_array(arena, RD_CfgTree, 1); - SLLQueuePush_NZ(&d_nil_cfg_tree, val->first, val->last, tree, next); - tree->source = source; - tree->root = md_tree_copy(arena, tln); - } -} - -internal RD_CfgVal * -rd_cfg_val_from_string(RD_CfgTable *table, String8 string) -{ - RD_CfgVal *result = &d_nil_cfg_val; - if(table->slot_count != 0) - { - U64 hash = d_hash_from_string__case_insensitive(string); - U64 slot_idx = hash % table->slot_count; - RD_CfgSlot *slot = &table->slots[slot_idx]; - for(RD_CfgVal *val = slot->first; val != 0; val = val->hash_next) - { - if(str8_match(val->string, string, StringMatchFlag_CaseInsensitive)) - { - result = val; - break; - } - } - } - return result; -} - //////////////////////////////// //~ rjf: Registers Type Functions diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index dc630036..21d17818 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -30,7 +30,7 @@ struct RD_HandleList }; //////////////////////////////// -//~ rjf: Binding Types +//~ rjf: Key Binding Types typedef struct RD_Binding RD_Binding; struct RD_Binding @@ -287,45 +287,7 @@ enum #include "generated/raddbg.meta.h" //////////////////////////////// -//~ rjf: Config Types - -typedef struct RD_CfgTree RD_CfgTree; -struct RD_CfgTree -{ - RD_CfgTree *next; - RD_CfgSrc source; - MD_Node *root; -}; - -typedef struct RD_CfgVal RD_CfgVal; -struct RD_CfgVal -{ - RD_CfgVal *hash_next; - RD_CfgVal *linear_next; - RD_CfgTree *first; - RD_CfgTree *last; - U64 insertion_stamp; - String8 string; -}; - -typedef struct RD_CfgSlot RD_CfgSlot; -struct RD_CfgSlot -{ - RD_CfgVal *first; -}; - -typedef struct RD_CfgTable RD_CfgTable; -struct RD_CfgTable -{ - U64 slot_count; - RD_CfgSlot *slots; - U64 insertion_stamp_counter; - RD_CfgVal *first_val; - RD_CfgVal *last_val; -}; - -//////////////////////////////// -//~ rjf: New Config/Entity Data Structure +//~ rjf: Config Tree typedef struct RD_Cfg RD_Cfg; struct RD_Cfg @@ -981,9 +943,6 @@ struct RD_State read_only global RD_VocabularyInfo rd_nil_vocabulary_info = {0}; -read_only global RD_CfgTree d_nil_cfg_tree = {&d_nil_cfg_tree, RD_CfgSrc_User, &md_nil_node}; -read_only global RD_CfgVal d_nil_cfg_val = {&d_nil_cfg_val, &d_nil_cfg_val, &d_nil_cfg_tree, &d_nil_cfg_tree}; - read_only global RD_Cfg rd_nil_cfg = { &rd_nil_cfg, @@ -1055,12 +1014,6 @@ internal void rd_handle_list_push_node(RD_HandleList *list, RD_HandleNode *node) internal void rd_handle_list_push(Arena *arena, RD_HandleList *list, RD_Handle handle); internal RD_HandleList rd_handle_list_copy(Arena *arena, RD_HandleList list); -//////////////////////////////// -//~ rjf: Config Type Pure Functions - -internal void rd_cfg_table_push_unparsed_string(Arena *arena, RD_CfgTable *table, String8 string, RD_CfgSrc source); -internal RD_CfgVal *rd_cfg_val_from_string(RD_CfgTable *table, String8 string); - //////////////////////////////// //~ rjf: Registers Type Functions diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 1e7108c2..dd563f32 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -144,18 +144,6 @@ struct RD_WatchPt U64 cell_id; }; -typedef struct RD_WatchViewRowInfo RD_WatchViewRowInfo; -struct RD_WatchViewRowInfo -{ - RD_EntityKind collection_entity_kind; - RD_Entity *collection_entity; - CTRL_EntityKind collection_ctrl_entity_kind; - CTRL_Entity *collection_ctrl_entity; - CTRL_Entity *callstack_thread; - U64 callstack_unwind_index; - U64 callstack_inline_depth; -}; - typedef struct RD_WatchViewTextEditState RD_WatchViewTextEditState; struct RD_WatchViewTextEditState { From edbce2713f570269cdbafd2dec71ec9c6e2e2b20 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 13:11:06 -0800 Subject: [PATCH 057/755] eliminate RD_Entity code entirely --- src/raddbg/raddbg_core.c | 806 +------------------------------------- src/raddbg/raddbg_core.h | 171 -------- src/raddbg/raddbg_views.c | 9 +- 3 files changed, 24 insertions(+), 962 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d3bdf05b..fd00af6f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -93,164 +93,6 @@ rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs cmds->count += 1; } -//////////////////////////////// -//~ rjf: Entity Functions - -//- rjf: nil - -internal B32 -rd_entity_is_nil(RD_Entity *entity) -{ - return (entity == 0 || entity == &rd_nil_entity); -} - -//- rjf: handle <-> entity conversions - -internal U64 -rd_index_from_entity(RD_Entity *entity) -{ - return (U64)(entity - rd_state->entities_base); -} - -internal RD_Handle -rd_handle_from_entity(RD_Entity *entity) -{ - RD_Handle handle = rd_handle_zero(); - if(!rd_entity_is_nil(entity)) - { - handle.u64[0] = rd_index_from_entity(entity); - handle.u64[1] = entity->gen; - } - return handle; -} - -internal RD_Entity * -rd_entity_from_handle(RD_Handle handle) -{ - RD_Entity *result = rd_state->entities_base + handle.u64[0]; - if(handle.u64[0] >= rd_state->entities_count || result->gen != handle.u64[1]) - { - result = &rd_nil_entity; - } - return result; -} - -//- rjf: entity recursion iterators - -internal RD_EntityRec -rd_entity_rec_depth_first(RD_Entity *entity, RD_Entity *subtree_root, U64 sib_off, U64 child_off) -{ - RD_EntityRec result = {0}; - if(!rd_entity_is_nil(*MemberFromOffset(RD_Entity **, entity, child_off))) - { - result.next = *MemberFromOffset(RD_Entity **, entity, child_off); - result.push_count = 1; - } - else for(RD_Entity *parent = entity; parent != subtree_root && !rd_entity_is_nil(parent); parent = parent->parent) - { - if(parent != subtree_root && !rd_entity_is_nil(*MemberFromOffset(RD_Entity **, parent, sib_off))) - { - result.next = *MemberFromOffset(RD_Entity **, parent, sib_off); - break; - } - result.pop_count += 1; - } - return result; -} - -//- rjf: ancestor/child introspection - -internal RD_Entity * -rd_entity_child_from_kind(RD_Entity *entity, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - for(RD_Entity *child = entity->first; !rd_entity_is_nil(child); child = child->next) - { - if(!(child->flags & RD_EntityFlag_MarkedForDeletion) && child->kind == kind) - { - result = child; - break; - } - } - return result; -} - -//- rjf: entity list building - -internal void -rd_entity_list_push(Arena *arena, RD_EntityList *list, RD_Entity *entity) -{ - RD_EntityNode *n = push_array(arena, RD_EntityNode, 1); - n->entity = entity; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal RD_EntityArray -rd_entity_array_from_list(Arena *arena, RD_EntityList *list) -{ - RD_EntityArray result = {0}; - result.count = list->count; - result.v = push_array(arena, RD_Entity *, result.count); - U64 idx = 0; - for(RD_EntityNode *n = list->first; n != 0; n = n->next, idx += 1) - { - result.v[idx] = n->entity; - } - return result; -} - -//- rjf: entity -> color operations - -internal Vec4F32 -rd_hsva_from_entity(RD_Entity *entity) -{ - Vec4F32 result = {0}; - if(entity->flags & RD_EntityFlag_HasColor) - { - result = entity->color_hsva; - } - return result; -} - -internal Vec4F32 -rd_rgba_from_entity(RD_Entity *entity) -{ - Vec4F32 result = {0}; - if(entity->flags & RD_EntityFlag_HasColor) - { - Vec3F32 hsv = v3f32(entity->color_hsva.x, entity->color_hsva.y, entity->color_hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - result = v4f32(rgb.x, rgb.y, rgb.z, entity->color_hsva.w); - } - else switch(entity->kind) - { - default:{}break; - case RD_EntityKind_Breakpoint: - { - result = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); - }break; - } - return result; -} - -//- rjf: entity -> expansion tree keys - -internal EV_Key -rd_ev_key_from_entity(RD_Entity *entity) -{ - EV_Key parent_key = rd_parent_ev_key_from_entity(entity); - EV_Key key = ev_key_make(ev_hash_from_key(parent_key), (U64)entity); - return key; -} - -internal EV_Key -rd_parent_ev_key_from_entity(RD_Entity *entity) -{ - EV_Key parent_key = ev_key_make(5381, (U64)entity); - return parent_key; -} - //////////////////////////////// //~ rjf: View Spec Type Functions @@ -1510,258 +1352,6 @@ rd_immediate_cfg_from_keyf(char *fmt, ...) return result; } -//////////////////////////////// -//~ rjf: Entity State Functions - -//- rjf: entity allocation + tree forming - -internal RD_Entity * -rd_entity_alloc(RD_Entity *parent, RD_EntityKind kind) -{ - B32 user_defined_lifetime = !!(rd_entity_kind_flags_table[kind] & RD_EntityKindFlag_UserDefinedLifetime); - U64 free_list_idx = !!user_defined_lifetime; - if(rd_entity_is_nil(parent)) { parent = rd_state->entities_root; } - - // rjf: empty free list -> push new - if(!rd_state->entities_free[free_list_idx]) - { - RD_Entity *entity = push_array(rd_state->entities_arena, RD_Entity, 1); - rd_state->entities_count += 1; - rd_state->entities_free_count += 1; - SLLStackPush(rd_state->entities_free[free_list_idx], entity); - } - - // rjf: pop new entity off free-list - RD_Entity *entity = rd_state->entities_free[free_list_idx]; - SLLStackPop(rd_state->entities_free[free_list_idx]); - rd_state->entities_free_count -= 1; - rd_state->entities_active_count += 1; - - // rjf: zero entity - { - U64 gen = entity->gen; - MemoryZeroStruct(entity); - entity->gen = gen; - } - - // rjf: set up alloc'd entity links - entity->first = entity->last = entity->next = entity->prev = entity->parent = &rd_nil_entity; - entity->parent = parent; - - // rjf: stitch up parent links - if(rd_entity_is_nil(parent)) - { - rd_state->entities_root = entity; - } - else - { - DLLPushBack_NPZ(&rd_nil_entity, parent->first, parent->last, entity, next, prev); - } - - // rjf: fill out metadata - entity->kind = kind; - rd_state->entities_id_gen += 1; - entity->id = rd_state->entities_id_gen; - entity->gen += 1; - entity->alloc_time_us = os_now_microseconds(); - - // rjf: initialize to deleted, record history, then "undelete" if this allocation can be undone - if(user_defined_lifetime) - { - // TODO(rjf) - } - - // rjf: dirtify caches - rd_state->kind_alloc_gens[kind] += 1; - - // rjf: log - LogInfoNamedBlockF("new_entity") - { - log_infof("kind: \"%S\"\n", d_entity_kind_display_string_table[kind]); - log_infof("id: $0x%I64x\n", entity->id); - } - - return entity; -} - -internal void -rd_entity_mark_for_deletion(RD_Entity *entity) -{ - if(!rd_entity_is_nil(entity)) - { - entity->flags |= RD_EntityFlag_MarkedForDeletion; - rd_state->kind_alloc_gens[entity->kind] += 1; - } -} - -internal void -rd_entity_release(RD_Entity *entity) -{ - Temp scratch = scratch_begin(0, 0); - - // rjf: unpack - U64 free_list_idx = !!(rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_UserDefinedLifetime); - - // rjf: release whole tree - typedef struct Task Task; - struct Task - { - Task *next; - RD_Entity *e; - }; - Task start_task = {0, entity}; - Task *first_task = &start_task; - Task *last_task = &start_task; - for(Task *task = first_task; task != 0; task = task->next) - { - for(RD_Entity *child = task->e->first; !rd_entity_is_nil(child); child = child->next) - { - Task *t = push_array(scratch.arena, Task, 1); - t->e = child; - SLLQueuePush(first_task, last_task, t); - } - LogInfoNamedBlockF("end_entity") - { - log_infof("kind: \"%S\"\n", d_entity_kind_display_string_table[task->e->kind]); - log_infof("id: $0x%I64x\n", task->e->id); - } - SLLStackPush(rd_state->entities_free[free_list_idx], task->e); - rd_state->entities_free_count += 1; - rd_state->entities_active_count -= 1; - task->e->gen += 1; - if(task->e->string.size != 0) - { - rd_name_release(task->e->string); - } - rd_state->kind_alloc_gens[task->e->kind] += 1; - } - - scratch_end(scratch); -} - -internal void -rd_entity_change_parent(RD_Entity *entity, RD_Entity *old_parent, RD_Entity *new_parent, RD_Entity *prev_child) -{ - Assert(entity->parent == old_parent); - Assert(prev_child->parent == old_parent || rd_entity_is_nil(prev_child)); - if(prev_child != entity) - { - // rjf: fix up links - if(!rd_entity_is_nil(old_parent)) - { - DLLRemove_NPZ(&rd_nil_entity, old_parent->first, old_parent->last, entity, next, prev); - } - if(!rd_entity_is_nil(new_parent)) - { - DLLInsert_NPZ(&rd_nil_entity, new_parent->first, new_parent->last, prev_child, entity, next, prev); - } - entity->parent = new_parent; - - // rjf: notify - rd_state->kind_alloc_gens[entity->kind] += 1; - } -} - -internal RD_Entity * -rd_entity_child_from_kind_or_alloc(RD_Entity *entity, RD_EntityKind kind) -{ - RD_Entity *child = rd_entity_child_from_kind(entity, kind); - if(rd_entity_is_nil(child)) - { - child = rd_entity_alloc(entity, kind); - } - return child; -} - -//- rjf: entity simple equipment - -internal void -rd_entity_equip_txt_pt(RD_Entity *entity, TxtPt point) -{ - rd_require_entity_nonnil(entity, return); - entity->text_point = point; - entity->flags |= RD_EntityFlag_HasTextPoint; -} - -internal void -rd_entity_equip_disabled(RD_Entity *entity, B32 value) -{ - rd_require_entity_nonnil(entity, return); - entity->disabled = value; -} - -internal void -rd_entity_equip_u64(RD_Entity *entity, U64 u64) -{ - rd_require_entity_nonnil(entity, return); - entity->u64 = u64; - entity->flags |= RD_EntityFlag_HasU64; -} - -internal void -rd_entity_equip_color_rgba(RD_Entity *entity, Vec4F32 rgba) -{ - rd_require_entity_nonnil(entity, return); - Vec3F32 rgb = v3f32(rgba.x, rgba.y, rgba.z); - Vec3F32 hsv = hsv_from_rgb(rgb); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - rd_entity_equip_color_hsva(entity, hsva); -} - -internal void -rd_entity_equip_color_hsva(RD_Entity *entity, Vec4F32 hsva) -{ - rd_require_entity_nonnil(entity, return); - entity->color_hsva = hsva; - entity->flags |= RD_EntityFlag_HasColor; -} - -internal void -rd_entity_equip_cfg_src(RD_Entity *entity, RD_CfgSrc cfg_src) -{ - rd_require_entity_nonnil(entity, return); - entity->cfg_src = cfg_src; -} - -internal void -rd_entity_equip_timestamp(RD_Entity *entity, U64 timestamp) -{ - rd_require_entity_nonnil(entity, return); - entity->timestamp = timestamp; -} - -//- rjf: control layer correllation equipment - -internal void -rd_entity_equip_vaddr(RD_Entity *entity, U64 vaddr) -{ - rd_require_entity_nonnil(entity, return); - entity->vaddr = vaddr; - entity->flags |= RD_EntityFlag_HasVAddr; -} - -//- rjf: name equipment - -internal void -rd_entity_equip_name(RD_Entity *entity, String8 name) -{ - rd_require_entity_nonnil(entity, return); - if(entity->string.size != 0) - { - rd_name_release(entity->string); - } - if(name.size != 0) - { - entity->string = rd_name_alloc(name); - } - else - { - entity->string = str8_zero(); - } -} - -//- rjf: file path map override lookups - internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path) { @@ -1895,251 +1485,6 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) return result; } -//- rjf: top-level state queries - -internal RD_Entity * -rd_entity_root(void) -{ - return rd_state->entities_root; -} - -internal RD_EntityList -rd_push_entity_list_with_kind(Arena *arena, RD_EntityKind kind) -{ - ProfBeginFunction(); - RD_EntityList result = {0}; - for(RD_Entity *entity = rd_state->entities_root; - !rd_entity_is_nil(entity); - entity = rd_entity_rec_depth_first_pre(entity, &rd_nil_entity).next) - { - if(entity->kind == kind && !(entity->flags & RD_EntityFlag_MarkedForDeletion)) - { - rd_entity_list_push(arena, &result, entity); - } - } - ProfEnd(); - return result; -} - -internal RD_Entity * -rd_entity_from_id(RD_EntityID id) -{ - RD_Entity *result = &rd_nil_entity; - for(RD_Entity *e = rd_entity_root(); - !rd_entity_is_nil(e); - e = rd_entity_rec_depth_first_pre(e, &rd_nil_entity).next) - { - if(e->id == id) - { - result = e; - break; - } - } - return result; -} - -internal RD_Entity * -rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind) -{ - RD_Entity *result = &rd_nil_entity; - RD_EntityList all_of_this_kind = rd_query_cached_entity_list_with_kind(kind); - for(RD_EntityNode *n = all_of_this_kind.first; n != 0; n = n->next) - { - if(str8_match(n->entity->string, string, 0)) - { - result = n->entity; - break; - } - } - return result; -} - -//////////////////////////////// -//~ rjf: Frontend Entity Info Extraction - -internal DR_FancyStringList -rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size) -{ - DR_FancyStringList result = {0}; - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args = rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *cnd = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - RD_Entity *src = rd_entity_child_from_kind(entity, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(entity, RD_EntityKind_Dest); - RD_IconKind icon_kind = rd_entity_kind_icon_kind_table[entity->kind]; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Text); - if(icon_kind != RD_IconKind_Null) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - if(entity->kind == RD_EntityKind_Target && entity->cfg_src == RD_CfgSrc_CommandLine) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), rd_icon_kind_text_table[RD_IconKind_Info]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - } - String8 name = entity->string; - B32 name_is_code = 1; - if(rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_NameIsPath) - { - name_is_code = 0; - } - String8 location = {0}; - B32 location_is_code = 0; - String8 exe_name = str8_skip_last_slash(exe->string); - String8 args_string = args->string; - String8 cnd_string = cnd->string; - if(!rd_entity_is_nil(loc)) - { - if(loc->string.size != 0 && loc->flags & RD_EntityFlag_HasTextPoint) - { - location = push_str8f(arena, "%S:%I64d:%I64d", loc->string, loc->text_point.line, loc->text_point.column); - location_is_code = 0; - } - else if(loc->string.size != 0) - { - location = loc->string; - location_is_code = 1; - } - else if(loc->flags & RD_EntityFlag_HasVAddr) - { - location = push_str8f(arena, "0x%I64x", loc->vaddr); - location_is_code = 1; - } - } - B32 extra = 0; - F32 size_extrafied = size; - Vec4F32 color_extrafied = color; - if(name.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), size, color, name); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(location.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - if(location_is_code) - { - DR_FancyStringList loc_fstrs = {0}; - RD_Font(RD_FontSlot_Code) - loc_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, color_extrafied, location); - dr_fancy_string_list_concat_in_place(&result, &loc_fstrs); - } - else - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, location); - } - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(exe_name.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, exe_name); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(args_string.size != 0) - { - if(extra) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, color_extrafied, args_string); - extra = 1; - size_extrafied = size*0.95f; - color_extrafied = secondary_color; - } - if(cnd_string.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, color_extrafied, str8_lit(" if ")); - RD_Font(RD_FontSlot_Code) UI_FontSize(size_extrafied) - { - DR_FancyStringList cnd_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0.f, color_extrafied, cnd_string); - dr_fancy_string_list_concat_in_place(&result, &cnd_fstrs); - } - } - if(entity->kind == RD_EntityKind_FilePathMap) - { - String8 src_string = src->string; - Vec4F32 src_color = color; - String8 dst_string = dst->string; - Vec4F32 dst_color = color; - if(src_string.size == 0) - { - src_string = str8_lit("(source path)"); - src_color = secondary_color; - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(destination path)"); - dst_color = secondary_color; - } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); - } - if(entity->kind == RD_EntityKind_AutoViewRule) - { - String8 src_string = src->string; - Vec4F32 src_color = color; - String8 dst_string = dst->string; - Vec4F32 dst_color = color; - DR_FancyStringList src_fstrs = {0}; - DR_FancyStringList dst_fstrs = {0}; - if(src_string.size == 0) - { - src_string = str8_lit("(type)"); - src_color = secondary_color; - dr_fancy_string_list_push_new(arena, &src_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); - } - else RD_Font(RD_FontSlot_Code) - { - src_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, src_color, src_string); - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(view rule)"); - dst_color = secondary_color; - dr_fancy_string_list_push_new(arena, &dst_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); - } - else RD_Font(RD_FontSlot_Code) - { - dst_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, dst_color, dst_string); - } - dr_fancy_string_list_concat_in_place(&result, &src_fstrs); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&result, &dst_fstrs); - } - if((entity->kind == RD_EntityKind_Target || entity->kind == RD_EntityKind_Breakpoint) && entity->disabled) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, str8_lit("(Disabled)")); - } - if(entity->kind == RD_EntityKind_Breakpoint) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - String8 string = push_str8f(arena, "(%I64u hit%s)", entity->u64, entity->u64 == 1 ? "" : "s"); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size_extrafied, secondary_color, string); - } - return result; -} - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -2543,73 +1888,6 @@ 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) -{ - ProfBeginFunction(); - CTRL_MetaEval *meval = push_array(arena, CTRL_MetaEval, 1); - RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); - RD_Entity *args= rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); - RD_Entity *wdir= rd_entity_child_from_kind(entity, RD_EntityKind_WorkingDirectory); - RD_Entity *entr= rd_entity_child_from_kind(entity, RD_EntityKind_EntryPoint); - RD_Entity *stdo= rd_entity_child_from_kind(entity, RD_EntityKind_StdoutPath); - RD_Entity *stde= rd_entity_child_from_kind(entity, RD_EntityKind_StderrPath); - RD_Entity *stdi= rd_entity_child_from_kind(entity, RD_EntityKind_StdinPath); - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - RD_Entity *cnd = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); - RD_Entity *src = rd_entity_child_from_kind(entity, RD_EntityKind_Source); - RD_Entity *dst = rd_entity_child_from_kind(entity, RD_EntityKind_Dest); - String8 label_string = push_str8_copy(arena, entity->string); - String8 src_loc_string = {0}; - String8 vaddr_loc_string = {0}; - String8 function_loc_string = {0}; - if(loc->flags & RD_EntityFlag_HasTextPoint) - { - src_loc_string = push_str8f(arena, "%S:%I64u:%I64u", loc->string, loc->text_point.line, loc->text_point.column); - } - else if(loc->flags & RD_EntityFlag_HasVAddr) - { - vaddr_loc_string = push_str8f(arena, "0x%I64x", loc->vaddr); - } - else if(loc->string.size != 0) - { - function_loc_string = push_str8_copy(arena, loc->string); - } - String8 cnd_string = push_str8_copy(arena, cnd->string); - meval->enabled = !entity->disabled; - meval->hit_count = entity->u64; - meval->color = u32_from_rgba(rd_rgba_from_entity(entity)); - meval->label = label_string; - meval->exe = exe->string; - meval->args = args->string; - meval->working_directory = wdir->string; - meval->entry_point = entr->string; - meval->stdout_path = stdo->string; - meval->stderr_path = stde->string; - meval->stdin_path = stdi->string; - meval->source_location = src_loc_string; - meval->address_location = vaddr_loc_string; - meval->function_location = function_loc_string; - meval->condition = cnd_string; - meval->debug_subprocesses.b32 = entity->debug_subprocesses; - switch(entity->kind) - { - default:{}break; - case RD_EntityKind_FilePathMap: - { - meval->source_path = src->string; - meval->destination_path = dst->string; - }break; - case RD_EntityKind_AutoViewRule: - { - meval->type = src->string; - meval->view_rule = dst->string; - }break; - } - ProfEnd(); - return meval; -} - internal CTRL_MetaEval * rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) { @@ -11627,32 +10905,6 @@ rd_frame_arena(void) return rd_state->frame_arenas[rd_state->frame_index%ArrayCount(rd_state->frame_arenas)]; } -//- rjf: entity cache queries - -internal RD_EntityList -rd_query_cached_entity_list_with_kind(RD_EntityKind kind) -{ - ProfBeginFunction(); - RD_EntityListCache *cache = &rd_state->kind_caches[kind]; - - // rjf: build cached list if we're out-of-date - if(cache->alloc_gen != rd_state->kind_alloc_gens[kind]) - { - cache->alloc_gen = rd_state->kind_alloc_gens[kind]; - if(cache->arena == 0) - { - cache->arena = arena_alloc(); - } - arena_clear(cache->arena); - cache->list = rd_push_entity_list_with_kind(cache->arena, kind); - } - - // rjf: grab & return cached list - RD_EntityList result = cache->list; - ProfEnd(); - return result; -} - //////////////////////////////// //~ rjf: Registers @@ -11884,11 +11136,6 @@ rd_init(CmdLine *cmdln) { rd_state->cmds_arenas[idx] = arena_alloc(); } - rd_state->entities_arena = arena_alloc(.reserve_size = GB(64), .commit_size = KB(64)); - rd_state->entities_root = &rd_nil_entity; - rd_state->entities_base = push_array(rd_state->entities_arena, RD_Entity, 0); - rd_state->entities_count = 0; - rd_state->entities_root = rd_entity_alloc(&rd_nil_entity, RD_EntityKind_Root); rd_state->popup_arena = arena_alloc(); rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); @@ -15508,17 +14755,28 @@ Z(getting_started) case RD_CmdKind_ToggleWatchExpression: if(rd_regs()->string.size != 0) { - RD_Entity *existing_watch = rd_entity_from_name_and_kind(rd_regs()->string, RD_EntityKind_Watch); - if(rd_entity_is_nil(existing_watch)) + RD_CfgList all_existing_watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_Cfg *existing_watch = &rd_nil_cfg; + for(RD_CfgNode *n = all_existing_watches.first; n != 0; n = n->next) { - RD_Entity *watch = &rd_nil_entity; - watch = rd_entity_alloc(rd_entity_root(), RD_EntityKind_Watch); - rd_entity_equip_cfg_src(watch, RD_CfgSrc_Project); - rd_entity_equip_name(watch, rd_regs()->string); + RD_Cfg *watch = n->v; + String8 expr = rd_expr_from_cfg(watch); + if(str8_match(expr, rd_regs()->string, 0)) + { + existing_watch = watch; + break; + } + } + if(existing_watch == &rd_nil_cfg) + { + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + RD_Cfg *watch = rd_cfg_new(project, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, rd_regs()->string); } else { - rd_entity_mark_for_deletion(existing_watch); + rd_cfg_release(existing_watch); } }break; @@ -16803,34 +16061,6 @@ Z(getting_started) } } - ////////////////////////////// - //- rjf: eliminate entities that are marked for deletion - // - ProfScope("eliminate deleted entities") - { - for(RD_Entity *entity = rd_entity_root(), *next = 0; !rd_entity_is_nil(entity); entity = next) - { - next = rd_entity_rec_depth_first_pre(entity, &rd_nil_entity).next; - if(entity->flags & RD_EntityFlag_MarkedForDeletion) - { - B32 undoable = (rd_entity_kind_flags_table[entity->kind] & RD_EntityKindFlag_UserDefinedLifetime); - - // rjf: fixup next entity to iterate to - next = rd_entity_rec_depth_first(entity, &rd_nil_entity, OffsetOf(RD_Entity, next), OffsetOf(RD_Entity, next)).next; - - // rjf: eliminate root entity if we're freeing it - if(entity == rd_state->entities_root) - { - rd_state->entities_root = &rd_nil_entity; - } - - // rjf: unhook & release this entity tree - rd_entity_change_parent(entity, entity->parent, &rd_nil_entity, &rd_nil_entity); - rd_entity_release(entity); - } - } - } - ////////////////////////////// //- rjf: determine frame time, record into history // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 21d17818..b7a6c1f7 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -386,72 +386,6 @@ struct RD_PanelNodeRec S32 pop_count; }; -//////////////////////////////// -//~ rjf: Entity Types - -typedef U64 RD_EntityID; - -typedef struct RD_Entity RD_Entity; -struct RD_Entity -{ - // rjf: tree links - RD_Entity *first; - RD_Entity *last; - RD_Entity *next; - RD_Entity *prev; - RD_Entity *parent; - - // rjf: metadata - RD_EntityKind kind; - RD_EntityFlags flags; - RD_EntityID id; - U64 gen; - U64 alloc_time_us; - - // rjf: basic equipment - TxtPt text_point; - B32 disabled; - B32 debug_subprocesses; - U64 u64; - U64 vaddr; - Vec4F32 color_hsva; - RD_CfgSrc cfg_src; - U64 timestamp; - - // rjf: string equipment - String8 string; -}; - -typedef struct RD_EntityNode RD_EntityNode; -struct RD_EntityNode -{ - RD_EntityNode *next; - RD_Entity *entity; -}; - -typedef struct RD_EntityList RD_EntityList; -struct RD_EntityList -{ - RD_EntityNode *first; - RD_EntityNode *last; - U64 count; -}; - -typedef struct RD_EntityArray RD_EntityArray; -struct RD_EntityArray -{ - RD_Entity **v; - U64 count; -}; - -typedef struct RD_EntityRec RD_EntityRec; -struct RD_EntityRec -{ - RD_Entity *next; - S32 push_count; - S32 pop_count; -}; - //////////////////////////////// //~ rjf: Command Types @@ -767,14 +701,6 @@ struct RD_NameChunkNode U64 size; }; -typedef struct RD_EntityListCache RD_EntityListCache; -struct RD_EntityListCache -{ - Arena *arena; - U64 alloc_gen; - RD_EntityList list; -}; - typedef struct RD_AmbiguousPathNode RD_AmbiguousPathNode; struct RD_AmbiguousPathNode { @@ -913,20 +839,6 @@ struct RD_State // TODO(rjf): TO BE ELIMINATED OR REPLACED VVVVVVVVVVVVVVVV //- - // rjf: entity state - Arena *entities_arena; - RD_Entity *entities_base; - U64 entities_count; - U64 entities_id_gen; - RD_Entity *entities_root; - RD_Entity *entities_free[2]; // [0] -> normal lifetime, not user defined; [1] -> user defined lifetime (& thus undoable) - U64 entities_free_count; - U64 entities_active_count; - - // rjf: entity query caches - U64 kind_alloc_gens[RD_EntityKind_COUNT]; - RD_EntityListCache kind_caches[RD_EntityKind_COUNT]; - // rjf: bind change Arena *bind_change_arena; B32 bind_change_active; @@ -964,15 +876,6 @@ read_only global RD_PanelNode rd_nil_panel_node = .selected_tab = &rd_nil_cfg, }; -read_only global RD_Entity rd_nil_entity = -{ - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, - &rd_nil_entity, -}; - read_only global RD_CmdKindInfo rd_nil_cmd_kind_info = {0}; read_only global RD_ViewRuleInfo rd_nil_view_rule_info = @@ -1025,39 +928,6 @@ internal RD_Regs *rd_regs_copy(Arena *arena, RD_Regs *src); internal void rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs); -//////////////////////////////// -//~ rjf: Entity Type Pure Functions - -//- rjf: nil -internal B32 rd_entity_is_nil(RD_Entity *entity); -#define rd_require_entity_nonnil(entity, if_nil_stmts) do{if(rd_entity_is_nil(entity)){if_nil_stmts;}}while(0) - -//- rjf: handle <-> entity conversions -internal U64 rd_index_from_entity(RD_Entity *entity); -internal RD_Handle rd_handle_from_entity(RD_Entity *entity); -internal RD_Entity *rd_entity_from_handle(RD_Handle handle); - -//- rjf: entity recursion iterators -internal RD_EntityRec rd_entity_rec_depth_first(RD_Entity *entity, RD_Entity *subtree_root, U64 sib_off, U64 child_off); -#define rd_entity_rec_depth_first_pre(entity, subtree_root) rd_entity_rec_depth_first((entity), (subtree_root), OffsetOf(RD_Entity, next), OffsetOf(RD_Entity, first)) -#define rd_entity_rec_depth_first_post(entity, subtree_root) rd_entity_rec_depth_first((entity), (subtree_root), OffsetOf(RD_Entity, prev), OffsetOf(RD_Entity, last)) - -//- rjf: ancestor/child introspection -internal RD_Entity *rd_entity_child_from_kind(RD_Entity *entity, RD_EntityKind kind); - -//- rjf: entity list building -internal void rd_entity_list_push(Arena *arena, RD_EntityList *list, RD_Entity *entity); -internal RD_EntityArray rd_entity_array_from_list(Arena *arena, RD_EntityList *list); -#define rd_first_entity_from_list(list) ((list)->first != 0 ? (list)->first->entity : &rd_nil_entity) - -//- rjf: entity -> color operations -internal Vec4F32 rd_hsva_from_entity(RD_Entity *entity); -internal Vec4F32 rd_rgba_from_entity(RD_Entity *entity); - -//- rjf: entity -> expansion tree keys -internal EV_Key rd_ev_key_from_entity(RD_Entity *entity); -internal EV_Key rd_parent_ev_key_from_entity(RD_Entity *entity); - //////////////////////////////// //~ rjf: View Spec Type Functions @@ -1143,46 +1013,9 @@ internal String8 rd_setting_from_name(String8 name); internal RD_Cfg *rd_immediate_cfg_from_key(String8 string); internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); -//////////////////////////////// -//~ rjf: Entity Stateful Functions - -//- rjf: entity allocation + tree forming -internal RD_Entity *rd_entity_alloc(RD_Entity *parent, RD_EntityKind kind); -internal void rd_entity_mark_for_deletion(RD_Entity *entity); -internal void rd_entity_release(RD_Entity *entity); -internal void rd_entity_change_parent(RD_Entity *entity, RD_Entity *old_parent, RD_Entity *new_parent, RD_Entity *prev_child); -internal RD_Entity *rd_entity_child_from_kind_or_alloc(RD_Entity *entity, RD_EntityKind kind); - -//- rjf: entity simple equipment -internal void rd_entity_equip_txt_pt(RD_Entity *entity, TxtPt point); -internal void rd_entity_equip_disabled(RD_Entity *entity, B32 b32); -internal void rd_entity_equip_u64(RD_Entity *entity, U64 u64); -internal void rd_entity_equip_color_rgba(RD_Entity *entity, Vec4F32 rgba); -internal void rd_entity_equip_color_hsva(RD_Entity *entity, Vec4F32 hsva); -internal void rd_entity_equip_cfg_src(RD_Entity *entity, RD_CfgSrc cfg_src); -internal void rd_entity_equip_timestamp(RD_Entity *entity, U64 timestamp); - -//- rjf: control layer correllation equipment -internal void rd_entity_equip_vaddr(RD_Entity *entity, U64 vaddr); - -//- rjf: name equipment -internal void rd_entity_equip_name(RD_Entity *entity, String8 name); - -//- rjf: file path map override lookups internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path); internal String8List rd_possible_overrides_from_file_path(Arena *arena, String8 file_path); -//- rjf: top-level state queries -internal RD_Entity *rd_entity_root(void); -internal RD_EntityList rd_push_entity_list_with_kind(Arena *arena, RD_EntityKind kind); -internal RD_Entity *rd_entity_from_id(RD_EntityID id); -internal RD_Entity *rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind); - -//////////////////////////////// -//~ rjf: Frontend Entity Info Extraction - -internal DR_FancyStringList rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size); - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -1210,7 +1043,6 @@ 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); //- rjf: eval space reads/writes @@ -1368,9 +1200,6 @@ internal void rd_request_frame(void); //- rjf: per-frame arena internal Arena *rd_frame_arena(void); -//- rjf: entity cache queries -internal RD_EntityList rd_query_cached_entity_list_with_kind(RD_EntityKind kind); - //////////////////////////////// //~ rjf: Registers diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index fd8e2236..be895e31 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -968,6 +968,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(info.group_cfg_name.size != 0) { RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, info.group_cfg_name); + // TODO(rjf): this is not correct - assumes row's evaluation is in the block's space... // info.group_cfg = rd_cfg_from_eval_space(info.eval.space); } @@ -2080,7 +2081,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) taken = 1; state_dirty = 1; snap_to_cursor = 1; - RD_EntityList entities_to_remove = {0}; + RD_CfgList cfgs_to_remove = {0}; RD_WatchPt next_cursor_pt = {0}; B32 next_cursor_set = 0; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); @@ -2143,9 +2144,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) #endif } } - for(RD_EntityNode *n = entities_to_remove.first; n != 0; n = n->next) + for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) { - rd_entity_mark_for_deletion(n->entity); + rd_cfg_release(n->v); } if(next_cursor_set) { @@ -2318,6 +2319,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) #endif // rjf: map selection endpoints to entities +#if 0 // TODO(rjf): @cfg RD_Entity *first_entity = &rd_nil_entity; RD_Entity *last_entity = &rd_nil_entity; if(collection_entity_kind != RD_EntityKind_Nil) @@ -2360,6 +2362,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) rd_entity_change_parent(last_entity_next, last_entity_next->parent, last_entity_next->parent, first_entity_prev); } } +#endif } } From 836b6714913547aa66286fce62cb2b5f81ec9dee Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 13:37:58 -0800 Subject: [PATCH 058/755] move from ptr*gen handles -> id; eliminate all handle code in frontend and convert to using 64-bit ids --- src/dbg_engine/dbg_engine.mdesk | 4 +- src/raddbg/generated/raddbg.meta.c | 36 +- src/raddbg/generated/raddbg.meta.h | 22 +- src/raddbg/raddbg.mdesk | 30 +- src/raddbg/raddbg_core.c | 524 +++++++++++++++-------------- src/raddbg/raddbg_core.h | 72 ++-- src/raddbg/raddbg_main.c | 10 +- src/raddbg/raddbg_views.c | 18 +- src/raddbg/raddbg_widgets.c | 30 +- 9 files changed, 376 insertions(+), 370 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index dd4ff355..d4f40b62 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -10,8 +10,8 @@ D_CmdTable: // | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 Entity null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } - {LaunchAndInit 1 1 Entity null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {LaunchAndRun 1 1 Cfg null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndInit 1 1 Cfg null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } {Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } {KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } {Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e90162a2..f3cb056f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -246,7 +246,7 @@ RD_EntityKindFlags rd_entity_kind_flags_table[27] = (0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), }; -Rng1U64 rd_reg_slot_range_table[40] = +Rng1U64 rd_reg_slot_range_table[38] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -254,15 +254,13 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, process), OffsetOf(RD_Regs, process) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, thread), OffsetOf(RD_Regs, thread) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, ctrl_entity), OffsetOf(RD_Regs, ctrl_entity) + sizeof(CTRL_Handle)}, -{OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, cfg), OffsetOf(RD_Regs, cfg) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, cfg_list), OffsetOf(RD_Regs, cfg_list) + sizeof(RD_HandleList)}, -{OffsetOf(RD_Regs, entity), OffsetOf(RD_Regs, entity) + sizeof(RD_Handle)}, -{OffsetOf(RD_Regs, entity_list), OffsetOf(RD_Regs, entity_list) + sizeof(RD_HandleList)}, +{OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, cfg), OffsetOf(RD_Regs, cfg) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, cfg_list), OffsetOf(RD_Regs, cfg_list) + sizeof(RD_CfgIDList)}, {OffsetOf(RD_Regs, unwind_count), OffsetOf(RD_Regs, unwind_count) + sizeof(U64)}, {OffsetOf(RD_Regs, inline_depth), OffsetOf(RD_Regs, inline_depth) + sizeof(U64)}, {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, @@ -293,8 +291,8 @@ Rng1U64 rd_reg_slot_range_table[40] = RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, { str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, { str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, @@ -376,7 +374,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, { str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), str8_lit_comp("Show File In Explorer"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, @@ -385,7 +383,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, @@ -460,15 +458,15 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Entity, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, { str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, { str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b75cbd58..2beda79f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -62,8 +62,6 @@ RD_RegSlot_PrevView, RD_RegSlot_DstPanel, RD_RegSlot_Cfg, RD_RegSlot_CfgList, -RD_RegSlot_Entity, -RD_RegSlot_EntityList, RD_RegSlot_UnwindCount, RD_RegSlot_InlineDepth, RD_RegSlot_FilePath, @@ -523,15 +521,13 @@ CTRL_Handle module; CTRL_Handle process; CTRL_Handle thread; CTRL_Handle ctrl_entity; -RD_Handle window; -RD_Handle panel; -RD_Handle view; -RD_Handle prev_view; -RD_Handle dst_panel; -RD_Handle cfg; -RD_HandleList cfg_list; -RD_Handle entity; -RD_HandleList entity_list; +RD_CfgID window; +RD_CfgID panel; +RD_CfgID view; +RD_CfgID prev_view; +RD_CfgID dst_panel; +RD_CfgID cfg; +RD_CfgIDList cfg_list; U64 unwind_count; U64 inline_depth; String8 file_path; @@ -608,8 +604,6 @@ RD_ViewRuleUIFunctionType *ui; .dst_panel = rd_regs()->dst_panel,\ .cfg = rd_regs()->cfg,\ .cfg_list = rd_regs()->cfg_list,\ -.entity = rd_regs()->entity,\ -.entity_list = rd_regs()->entity_list,\ .unwind_count = rd_regs()->unwind_count,\ .inline_depth = rd_regs()->inline_depth,\ .file_path = rd_regs()->file_path,\ @@ -666,7 +660,7 @@ extern String8 d_entity_kind_name_lower_table[27]; extern String8 d_entity_kind_name_lower_plural_table[27]; extern String8 d_entity_kind_name_label_table[27]; extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; -extern Rng1U64 rd_reg_slot_range_table[40]; +extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 60a08afe..2c8359dd 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -351,15 +351,13 @@ RD_RegTable: {CTRL_Handle process Process } {CTRL_Handle thread Thread } {CTRL_Handle ctrl_entity CtrlEntity } - {RD_Handle window Window } - {RD_Handle panel Panel } - {RD_Handle view View } - {RD_Handle prev_view PrevView } - {RD_Handle dst_panel DstPanel } - {RD_Handle cfg Cfg } - {RD_HandleList cfg_list CfgList } - {RD_Handle entity Entity } - {RD_HandleList entity_list EntityList } + {RD_CfgID window Window } + {RD_CfgID panel Panel } + {RD_CfgID view View } + {RD_CfgID prev_view PrevView } + {RD_CfgID dst_panel DstPanel } + {RD_CfgID cfg Cfg } + {RD_CfgIDList cfg_list CfgList } // rjf: frame selection {U64 unwind_count UnwindCount } @@ -509,7 +507,7 @@ RD_CmdTable: // | | | | //- rjf: files {SetCurrentPath 0 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } {Open 1 1 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } - {Switch 1 1 Entity null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {Switch 1 1 Cfg null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } {ShowFileInExplorer 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } @@ -524,7 +522,7 @@ RD_CmdTable: // | | | | //- rjf: setting config paths {OpenUser 1 1 FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } - {OpenRecentProject 1 1 Entity null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } + {OpenRecentProject 1 1 Cfg null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } @@ -621,8 +619,8 @@ RD_CmdTable: // | | | | {AddAddressBreakpoint 1 0 Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } {AddFunctionBreakpoint 1 0 String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } {ToggleBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } - {EnableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } - {DisableBreakpoint 1 1 Entity null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {EnableBreakpoint 1 1 Cfg null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 Cfg null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins {AddWatchPin 1 1 String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } @@ -633,9 +631,9 @@ RD_CmdTable: // | | | | //- rjf: targets {AddTarget 1 1 FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } - {SelectTarget 1 1 Entity null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } - {EnableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } - {DisableTarget 1 1 Entity null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } + {SelectTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching {RegisterAsJITDebugger 1 1 Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fd00af6f..d57d7162 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10,43 +10,24 @@ #include "generated/raddbg.meta.c" //////////////////////////////// -//~ rjf: Handles - -internal RD_Handle -rd_handle_zero(void) -{ - RD_Handle result = {0}; - return result; -} - -internal B32 -rd_handle_match(RD_Handle a, RD_Handle b) -{ - return (a.u64[0] == b.u64[0] && a.u64[1] == b.u64[1]); -} +//~ rjf: Config ID Type Functions internal void -rd_handle_list_push_node(RD_HandleList *list, RD_HandleNode *node) +rd_cfg_id_list_push(Arena *arena, RD_CfgIDList *list, RD_CfgID id) { - DLLPushBack(list->first, list->last, node); + RD_CfgIDNode *n = push_array(arena, RD_CfgIDNode, 1); + n->v = id; + SLLQueuePush(list->first, list->last, n); list->count += 1; } -internal void -rd_handle_list_push(Arena *arena, RD_HandleList *list, RD_Handle handle) +internal RD_CfgIDList +rd_cfg_id_list_copy(Arena *arena, RD_CfgIDList *src) { - RD_HandleNode *n = push_array(arena, RD_HandleNode, 1); - n->handle = handle; - rd_handle_list_push_node(list, n); -} - -internal RD_HandleList -rd_handle_list_copy(Arena *arena, RD_HandleList list) -{ - RD_HandleList result = {0}; - for(RD_HandleNode *n = list.first; n != 0; n = n->next) + RD_CfgIDList result = {0}; + for(RD_CfgIDNode *n = src->first; n != 0; n = n->next) { - rd_handle_list_push(arena, &result, n->handle); + rd_cfg_id_list_push(arena, &result, n->v); } return result; } @@ -58,17 +39,16 @@ internal void rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src) { MemoryCopyStruct(dst, src); - dst->entity_list = rd_handle_list_copy(arena, src->entity_list); - dst->cfg_list = rd_handle_list_copy(arena, src->cfg_list); + dst->cfg_list = rd_cfg_id_list_copy(arena, &src->cfg_list); dst->file_path = push_str8_copy(arena, src->file_path); dst->lines = d_line_list_copy(arena, &src->lines); dst->dbgi_key = di_key_copy(arena, &src->dbgi_key); dst->string = push_str8_copy(arena, src->string); dst->cmd_name = push_str8_copy(arena, src->cmd_name); dst->params_tree = md_tree_copy(arena, src->params_tree); - if(dst->entity_list.count == 0 && !rd_handle_match(rd_handle_zero(), dst->entity)) + if(dst->cfg_list.count == 0 && dst->cfg != 0) { - rd_handle_list_push(arena, &dst->entity_list, dst->entity); + rd_cfg_id_list_push(arena, &dst->cfg_list, dst->cfg); } } @@ -187,7 +167,7 @@ rd_get_hover_regs(void) internal void rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot) { - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); if(ws != 0) { @@ -308,24 +288,47 @@ rd_name_release(String8 string) } //////////////////////////////// -//~ rjf: New Config/Entity Data Structure Functions +//~ rjf: Config Tree Functions internal RD_Cfg * rd_cfg_alloc(void) { + // rjf: allocate RD_Cfg *result = rd_state->free_cfg; - if(result) { - SLLStackPop(rd_state->free_cfg); + if(result) + { + SLLStackPop(rd_state->free_cfg); + } + else + { + result = push_array_no_zero(rd_state->arena, RD_Cfg, 1); + } } - else - { - result = push_array_no_zero(rd_state->arena, RD_Cfg, 1); - } - U64 old_gen = result->gen; + + // rjf: generate ID & fill + rd_state->cfg_id_gen += 1; MemoryZeroStruct(result); result->first = result->last = result->next = result->prev = result->parent = &rd_nil_cfg; - result->gen = old_gen + 1; + result->id = rd_state->cfg_id_gen; + + // rjf: store to ID -> cfg map + { + RD_CfgNode *cfg_id_node = rd_state->free_cfg_id_node; + if(cfg_id_node != 0) + { + SLLStackPop(rd_state->free_cfg_id_node); + } + else + { + cfg_id_node = push_array(rd_state->arena, RD_CfgNode, 1); + } + U64 hash = d_hash_from_string(str8_struct(&result->id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + DLLPushBack(rd_state->cfg_id_slots[slot_idx].first, rd_state->cfg_id_slots[slot_idx].last, cfg_id_node); + cfg_id_node->v = result; + } + return result; } @@ -333,19 +336,36 @@ internal void rd_cfg_release(RD_Cfg *cfg) { Temp scratch = scratch_begin(0, 0); + + // rjf: unhook from context rd_cfg_unhook(cfg->parent, cfg); + + // rjf: gather root & all descendants RD_CfgList nodes = {0}; for(RD_Cfg *c = cfg; c != &rd_nil_cfg; c = rd_cfg_rec__depth_first(cfg, c).next) { rd_cfg_list_push(scratch.arena, &nodes, c); } + + // rjf: release all nodes for(RD_CfgNode *n = nodes.first; n != 0; n = n->next) { RD_Cfg *c = n->v; - c->gen += 1; rd_name_release(c->string); SLLStackPush(rd_state->free_cfg, c); + U64 hash = d_hash_from_string(str8_struct(&c->id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) + { + if(n->v == c) + { + DLLRemove(rd_state->cfg_id_slots[slot_idx].first, rd_state->cfg_id_slots[slot_idx].last, n); + SLLStackPush(rd_state->free_cfg_id_node, n); + break; + } + } } + scratch_end(scratch); } @@ -359,27 +379,21 @@ rd_cfg_release_all_children(RD_Cfg *cfg) } } -internal RD_Handle -rd_handle_from_cfg(RD_Cfg *cfg) -{ - RD_Handle handle = {0}; - if(cfg != &rd_nil_cfg) - { - handle.u64[0] = (U64)cfg; - handle.u64[1] = cfg->gen; - } - return handle; -} - internal RD_Cfg * -rd_cfg_from_handle(RD_Handle handle) +rd_cfg_from_id(RD_CfgID id) { - RD_Cfg *cfg = (RD_Cfg *)handle.u64[0]; - if(cfg == 0 || handle.u64[1] != cfg->gen) + RD_Cfg *result = &rd_nil_cfg; + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) { - cfg = &rd_nil_cfg; + if(n->v->id == id) + { + result = n->v; + break; + } } - return cfg; + return result; } internal RD_Cfg * @@ -1284,9 +1298,9 @@ rd_setting_from_name(String8 name) String8 result = {0}; { // rjf: find most-granular config scope to begin looking for the setting - RD_Cfg *start_cfg = rd_cfg_from_handle(rd_regs()->view); - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->panel); } - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_handle(rd_regs()->window); } + RD_Cfg *start_cfg = rd_cfg_from_id(rd_regs()->view); + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->panel); } + if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } // rjf: scan upwards the config tree until we find the setting RD_Cfg *setting = &rd_nil_cfg; @@ -1646,8 +1660,8 @@ rd_cfg_from_eval_space(E_Space space) RD_Cfg *cfg = &rd_nil_cfg; if(space.kind == RD_EvalSpaceKind_MetaCfg) { - RD_Handle handle = {space.u64s[0], space.u64s[1]}; - cfg = rd_cfg_from_handle(handle); + RD_CfgID id = space.u64s[0]; + cfg = rd_cfg_from_id(id); } return cfg; } @@ -1656,9 +1670,7 @@ internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg) { E_Space space = e_space_make(RD_EvalSpaceKind_MetaCfg); - RD_Handle handle = rd_handle_from_cfg(cfg); - space.u64s[0] = handle.u64[0]; - space.u64s[1] = handle.u64[1]; + space.u64s[0] = cfg->id; return space; } @@ -1761,13 +1773,13 @@ rd_eval_blob_from_cfg__cached(RD_Cfg *cfg) String8 result = {0}; { RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; - RD_Handle handle = rd_handle_from_cfg(cfg); - U64 hash = d_hash_from_string(str8_struct(&handle)); + RD_CfgID id = cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); U64 slot_idx = hash%map->slots_count; RD_Cfg2EvalBlobNode *node = 0; for(RD_Cfg2EvalBlobNode *n = map->slots[slot_idx].first; n != 0; n = n->next) { - if(rd_handle_match(handle, n->handle)) + if(n->id == id) { node = n; break; @@ -1777,7 +1789,7 @@ rd_eval_blob_from_cfg__cached(RD_Cfg *cfg) { 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->id = id; node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); } result = node->blob; @@ -2159,15 +2171,15 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) // rjf: commit to the eval blob cache { RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; - RD_Handle handle = rd_handle_from_cfg(cfg); - U64 hash = d_hash_from_string(str8_struct(&handle)); + RD_CfgID id = cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); 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) { - if(rd_handle_match(handle, n->handle)) + if(n->id == id) { node = n; break; @@ -2514,14 +2526,14 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) internal RD_ViewState * rd_view_state_from_cfg(RD_Cfg *cfg) { - RD_Handle cfg_handle = rd_handle_from_cfg(cfg); - U64 hash = d_hash_from_string(str8_struct(&cfg_handle)); + RD_CfgID id = cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); U64 slot_idx = hash%rd_state->view_state_slots_count; RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; RD_ViewState *view_state = &rd_nil_view_state; for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) { - if(rd_handle_match(v->cfg_handle, cfg_handle)) + if(v->cfg_id == id) { view_state = v; break; @@ -2540,7 +2552,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) } MemoryCopyStruct(view_state, &rd_nil_view_state); DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); - view_state->cfg_handle = cfg_handle; + view_state->cfg_id = id; view_state->arena = arena_alloc(); view_state->ev_view = ev_view_alloc(); view_state->loading_t = 1.f; @@ -2702,7 +2714,7 @@ rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query internal Arena * rd_view_arena(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); return view_state->arena; } @@ -2710,7 +2722,7 @@ rd_view_arena(void) internal UI_ScrollPt2 rd_view_scroll_pos(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); return view_state->scroll_pos; } @@ -2718,7 +2730,7 @@ rd_view_scroll_pos(void) internal EV_View * rd_view_eval_view(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); return view_state->ev_view; } @@ -2726,7 +2738,7 @@ rd_view_eval_view(void) internal String8 rd_view_expr_string(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *expr = rd_cfg_child_from_string(view, str8_lit("expression")); String8 expr_string = expr->first->string; return expr_string; @@ -2735,7 +2747,7 @@ rd_view_expr_string(void) internal String8 rd_view_filter(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *filter = rd_cfg_child_from_string(view, str8_lit("filter")); String8 filter_string = filter->first->string; return filter_string; @@ -2746,7 +2758,7 @@ rd_view_filter(void) internal void * rd_view_state_by_size(U64 size) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); if(view_state->user_data == 0) { @@ -2758,7 +2770,7 @@ rd_view_state_by_size(U64 size) internal Arena * rd_push_view_arena(void) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); RD_ArenaExt *ext = push_array(view_state->arena, RD_ArenaExt, 1); ext->arena = arena_alloc(); @@ -2771,7 +2783,7 @@ rd_push_view_arena(void) internal void rd_store_view_expr_string(String8 string) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); rd_cfg_release_all_children(expr); rd_cfg_new(expr, string); @@ -2780,7 +2792,7 @@ rd_store_view_expr_string(String8 string) internal void rd_store_view_filter(String8 string) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); rd_cfg_release_all_children(filter); rd_cfg_new(filter, string); @@ -2789,7 +2801,7 @@ rd_store_view_filter(String8 string) internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); view_state->loading_t_target = (F32)!!is_loading; view_state->loading_progress_v = progress_u64; @@ -2799,7 +2811,7 @@ rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_ta internal void rd_store_view_scroll_pos(UI_ScrollPt2 pos) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *view_state = rd_view_state_from_cfg(view); view_state->scroll_pos = pos; } @@ -2807,7 +2819,7 @@ rd_store_view_scroll_pos(UI_ScrollPt2 pos) internal void rd_store_view_param(String8 key, String8 value) { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *child = rd_cfg_child_from_string_or_alloc(view, key); rd_cfg_release_all_children(child); rd_cfg_new(child, value); @@ -2848,8 +2860,8 @@ rd_window_state_from_cfg(RD_Cfg *cfg) { //- rjf: unpack RD_Cfg *window_cfg = rd_window_from_cfg(cfg); - RD_Handle handle = rd_handle_from_cfg(window_cfg); - U64 hash = d_hash_from_string(str8_struct(&handle)); + RD_CfgID id = window_cfg->id; + U64 hash = d_hash_from_string(str8_struct(&id)); U64 slot_idx = hash%rd_state->window_state_slots_count; RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; @@ -2857,7 +2869,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) RD_WindowState *ws = &rd_nil_window_state; for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) { - if(rd_handle_match(w->cfg_handle, handle)) + if(w->cfg_id == id) { ws = w; break; @@ -2902,7 +2914,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) MemoryZeroStruct(ws); // rjf: fill out window - ws->cfg_handle = handle; + ws->cfg_id = id; ws->arena = arena_alloc(); { String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); @@ -2979,8 +2991,8 @@ rd_window_frame(void) ////////////////////////////// //- rjf: unpack context // - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window)); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window)); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); B32 popup_is_open = (rd_state->popup_active); @@ -3045,8 +3057,8 @@ rd_window_frame(void) ////////////////////////////// //- rjf: fill panel/view interaction registers // - rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); - rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; ////////////////////////////// //- rjf: compute ui palettes from theme @@ -3262,7 +3274,7 @@ rd_window_frame(void) UI_Tooltip { // rjf: unpack - RD_Cfg *cfg = rd_cfg_from_handle(regs->cfg); + RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); DR_FancyStringList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); // rjf: title @@ -3411,7 +3423,7 @@ rd_window_frame(void) .view = rd_state->drag_drop_regs->view) { Temp scratch = scratch_begin(0, 0); - RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("expression")); RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); { @@ -3518,11 +3530,11 @@ rd_window_frame(void) ui_divider(ui_em(1.f, 1.f)); ui_label(regs_info[idx].name); RD_Regs *regs = regs_info[idx].regs; -#define Handle(name) ui_labelf("%s: [0x%I64x, 0x%I64x]", #name, (regs->name).u64[0], (regs->name).u64[1]) - Handle(window); - Handle(panel); - Handle(view); -#undef Handle +#define ID(name) ui_labelf("%s: $0x%I64x", #name, (regs->name)) + ID(window); + ID(panel); + ID(view); +#undef ID #define Handle(name) ui_labelf("%s: [0x%I64x, 0x%I64x]", #name, (regs->name).machine_id, (regs->name).dmn_handle.u64[0]) Handle(machine); Handle(process); @@ -4276,7 +4288,7 @@ rd_window_frame(void) // case RD_RegSlot_View: { - RD_Cfg *tab = rd_cfg_from_handle(regs->view); + RD_Cfg *tab = rd_cfg_from_id(regs->view); RD_RegsScope(.view = regs->view) { String8 expr = rd_view_expr_string(); @@ -5234,7 +5246,7 @@ rd_window_frame(void) for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) { RD_Cfg *task = n->v; - F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%p_%I64u", task, task->gen), 1.f); + F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f); if(task_t > 0.5f) { String8 rdi_path = task->first->string; @@ -5788,7 +5800,7 @@ rd_window_frame(void) RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - RD_RegsScope(.panel = rd_handle_zero(), .view = rd_handle_from_cfg(view)) + RD_RegsScope(.panel = 0, .view = view->id) { RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); rd_cfg_release_all_children(expr); @@ -6178,7 +6190,7 @@ rd_window_frame(void) //- rjf: boundary tab-drag/drop sites // { - RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *drag_view = rd_cfg_from_id(rd_state->drag_drop_regs->view); if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && drag_view != &rd_nil_cfg) { //- rjf: params @@ -6264,7 +6276,7 @@ rd_window_frame(void) { RD_PanelNode *split_panel = panel; rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_cfg(split_panel->cfg), + .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -6348,7 +6360,7 @@ rd_window_frame(void) dir = (panel->split_axis == Axis2_X ? Dir2_Right : Dir2_Down); } rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_cfg(split_panel->cfg), + .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -6538,7 +6550,7 @@ rd_window_frame(void) //- rjf: build combined split+movetab drag/drop sites // { - RD_Cfg *view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse())) { F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); @@ -6661,7 +6673,7 @@ rd_window_frame(void) if(dir != Dir2_Invalid) { rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = rd_handle_from_cfg(panel->cfg), + .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, .dir2 = dir); @@ -6669,10 +6681,10 @@ rd_window_frame(void) else { rd_cmd(RD_CmdKind_MoveTab, - .dst_panel = rd_handle_from_cfg(panel->cfg), + .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, - .prev_view = rd_handle_from_cfg(rd_cfg_list_last(&panel->tabs))); + .prev_view = rd_cfg_list_last(&panel->tabs)->id); } } } @@ -6720,7 +6732,7 @@ rd_window_frame(void) RD_Cfg *view = selected_tab; RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); RD_ViewState *view_state = rd_view_state_from_cfg(view); - UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = rd_handle_from_cfg(view)) + UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = view->id) { if(view_state->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { @@ -6815,8 +6827,8 @@ rd_window_frame(void) UI_WidthFill { //- rjf: push interaction registers, fill with per-view states - rd_push_regs(.panel = rd_handle_from_cfg(panel->cfg), - .view = rd_handle_from_cfg(selected_tab)); + rd_push_regs(.panel = panel->cfg->id, + .view = selected_tab->id); { String8 view_expr = rd_view_expr_string(); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); @@ -6909,12 +6921,12 @@ rd_window_frame(void) UI_Signal panel_sig = ui_signal_from_box(panel_box); if(ui_pressed(panel_sig)) { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(panel->cfg)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); } if(ui_right_clicked(panel_sig)) { rd_cmd(RD_CmdKind_PushQuery, - .view = rd_handle_from_cfg(panel->selected_tab), + .view = panel->selected_tab->id, .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), .ui_key = panel_box->key, .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), @@ -7013,7 +7025,7 @@ rd_window_frame(void) } // rjf: build per-tab info - RD_RegsScope(.panel = rd_handle_from_cfg(panel->cfg), .view = rd_handle_from_cfg(tab)) + RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) { // rjf: gather info for this tab B32 view_is_selected = (tab == panel->selected_tab); @@ -7180,7 +7192,7 @@ rd_window_frame(void) // rjf: more precise drop-sites on tab bar { Vec2F32 mouse = ui_mouse(); - RD_Cfg *drag_tab = rd_cfg_from_handle(rd_state->drag_drop_regs->view); + RD_Cfg *drag_tab = rd_cfg_from_id(rd_state->drag_drop_regs->view); if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg) { // rjf: mouse => hovered drop site @@ -7202,11 +7214,11 @@ rd_window_frame(void) // rjf: store closest prev-view if(active_drop_site != 0) { - rd_last_drag_drop_prev_tab = rd_handle_from_cfg(active_drop_site->prev_view); + rd_last_drag_drop_prev_tab = active_drop_site->prev_view->id; } else { - rd_last_drag_drop_prev_tab = rd_handle_zero(); + rd_last_drag_drop_prev_tab = 0; } // rjf: vis @@ -7219,16 +7231,16 @@ rd_window_frame(void) // rjf: drop if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) { - RD_Cfg *drag_view = rd_cfg_from_handle(rd_state->drag_drop_regs->view); - RD_Cfg *src_panel = rd_cfg_from_handle(rd_state->drag_drop_regs->panel); + RD_Cfg *drag_view = rd_cfg_from_id(rd_state->drag_drop_regs->view); + RD_Cfg *src_panel = rd_cfg_from_id(rd_state->drag_drop_regs->panel); RD_Cfg *dst_panel = panel->cfg; if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg) { rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_cfg(src_panel), - .dst_panel = rd_handle_from_cfg(dst_panel), - .view = rd_handle_from_cfg(drag_view), - .prev_view = rd_handle_from_cfg(active_drop_site->prev_view)); + .panel = src_panel->id, + .dst_panel = dst_panel->id, + .view = drag_view->id, + .prev_view = active_drop_site->prev_view->id); } } } @@ -7236,7 +7248,7 @@ rd_window_frame(void) // rjf: apply tab change { - rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); } scratch_end(scratch); @@ -8937,7 +8949,7 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string) { - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); if(ws->hover_eval_last_frame_idx+1 < rd_state->frame_index && ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && @@ -9084,12 +9096,12 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St }break; case RD_RegSlot_Cfg: { - RD_Cfg *cfg = rd_cfg_from_handle(regs->cfg); + RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", cfg->string); }break; case RD_RegSlot_View: { - RD_Cfg *view = rd_cfg_from_handle(regs->view); + RD_Cfg *view = rd_cfg_from_id(regs->view); str8_list_pushf(scratch.arena, &ctx_filter_strings, "$tab,"); str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", view->string); String8 view_expr = rd_expr_from_cfg(view); @@ -9573,7 +9585,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St // rjf: push schema for view { - RD_Cfg *view = rd_cfg_from_handle(regs->view); + RD_Cfg *view = rd_cfg_from_id(regs->view); String8 view_name = view->string; RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view_name); str8_list_push(scratch.arena, &schema_strings, view_rule_info->params_schema); @@ -9846,7 +9858,7 @@ rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 c internal void rd_set_autocomp_lister_query_(RD_ListerParams *params) { - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); arena_clear(ws->lister_arena); ws->lister_regs = rd_regs_copy(ws->lister_arena, rd_regs()); @@ -9865,7 +9877,7 @@ rd_set_autocomp_lister_query_(RD_ListerParams *params) internal void rd_set_autocomp_lister_query_(RD_Regs *regs) { - RD_Cfg *window_cfg = rd_cfg_from_handle(regs->window); + RD_Cfg *window_cfg = rd_cfg_from_id(regs->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); if(ws->autocomp_lister == 0) { @@ -10037,7 +10049,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str internal UI_Palette * rd_palette_from_code(RD_PaletteCode code) { - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(wcfg); UI_Palette *result = &ws->cfg_palettes[code]; return result; @@ -10062,9 +10074,9 @@ rd_font_from_slot(RD_FontSlot slot) if(key.size != 0) { RD_Cfg *seed_cfg = &rd_nil_cfg; - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->view); } - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->panel); } - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_handle(rd_regs()->window); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->view); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->panel); } + if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->window); } for(RD_Cfg *cfg = seed_cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) { RD_Cfg *font_root = rd_cfg_child_from_string(cfg, key); @@ -10122,7 +10134,7 @@ rd_font_size_from_slot(RD_FontSlot slot) } else { - RD_Cfg *window_cfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); F32 dpi = os_dpi_from_window(ws->os); result = 11.f * (dpi / 96.f); @@ -11155,8 +11167,10 @@ rd_init(CmdLine *cmdln) } } - // rjf: set up top-level config entity trees + // rjf: set up top-level config entity trees & tables { + rd_state->cfg_id_slots_count = 1024; + rd_state->cfg_id_slots = push_array(arena, RD_CfgSlot, rd_state->cfg_id_slots_count); rd_state->root_cfg = rd_cfg_alloc(); RD_Cfg *user_tree = rd_cfg_new(rd_state->root_cfg, str8_lit("user")); RD_Cfg *project_tree = rd_cfg_new(rd_state->root_cfg, str8_lit("project")); @@ -11539,7 +11553,7 @@ rd_frame(void) { vs->scroll_pos.y.off = 0; } - RD_Cfg *vcfg = rd_cfg_from_handle(vs->cfg_handle); + RD_Cfg *vcfg = rd_cfg_from_id(vs->cfg_id); if(rd_cfg_child_from_string(vcfg, str8_lit("selected")) != &rd_nil_cfg) { vs->loading_t_target = 0; @@ -11874,13 +11888,13 @@ rd_frame(void) { next = event->next; RD_WindowState *ws = rd_window_state_from_os_handle(event->window); - if(ws != 0 && ws != rd_window_state_from_cfg(rd_cfg_from_handle(rd_regs()->window))) + if(ws != 0 && ws != rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window))) { Temp scratch = scratch_begin(0, 0); - RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(ws->cfg_handle)); - rd_regs()->window = ws->cfg_handle; - rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); - rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(ws->cfg_id)); + rd_regs()->window = ws->cfg_id; + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; scratch_end(scratch); } B32 take = 0; @@ -12507,7 +12521,7 @@ rd_frame(void) params.pid = rd_regs()->pid; params.targets.count = 1; params.targets.v = push_array(scratch.arena, D_Target, params.targets.count); - params.targets.v[0] = rd_target_from_cfg(scratch.arena, rd_cfg_from_handle(rd_regs()->cfg)); + params.targets.v[0] = rd_target_from_cfg(scratch.arena, rd_cfg_from_id(rd_regs()->cfg)); d_push_cmd((D_CmdKind)kind, ¶ms); } @@ -12585,7 +12599,7 @@ rd_frame(void) //- rjf: windows case RD_CmdKind_OpenWindow: { - RD_Cfg *old_window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *old_window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *bucket = old_window->parent; if(bucket == &rd_nil_cfg) { @@ -12606,12 +12620,12 @@ rd_frame(void) }break; case RD_CmdKind_CloseWindow: { - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); rd_cfg_release(wcfg); }break; case RD_CmdKind_ToggleFullscreen: { - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(wcfg); if(ws != &rd_nil_window_state) { @@ -12620,7 +12634,7 @@ rd_frame(void) }break; case RD_CmdKind_BringToFront: { - RD_Cfg *last_focused_wcfg = rd_cfg_from_handle(rd_state->last_focused_window); + RD_Cfg *last_focused_wcfg = rd_cfg_from_id(rd_state->last_focused_window); RD_WindowState *last_focused_ws = rd_window_state_from_cfg(last_focused_wcfg); if(last_focused_ws == &rd_nil_window_state) { @@ -12652,7 +12666,7 @@ rd_frame(void) //- rjf: config path saving/loading/applying case RD_CmdKind_OpenRecentProject: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); if(str8_match(cfg->string, str8_lit("recent_project"), 0)) { rd_cmd(RD_CmdKind_OpenProject, .file_path = cfg->first->string); @@ -12742,11 +12756,11 @@ rd_frame(void) F32 num_lines_in_monitor_height = monitor_dim.y / line_height_guess; if(num_lines_in_monitor_height < 100) { - rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = rd_handle_from_cfg(new_window)); + rd_cmd(RD_CmdKind_ResetToCompactPanels, .window = new_window->id); } else { - rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = rd_handle_from_cfg(new_window)); + rd_cmd(RD_CmdKind_ResetToDefaultPanels, .window = new_window->id); } } } @@ -12838,7 +12852,7 @@ rd_frame(void) fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); rd_cfg_release_all_children(main_font_size); rd_cfg_newf(main_font_size, "%f", new_font_size); @@ -12848,7 +12862,7 @@ rd_frame(void) fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); rd_cfg_release_all_children(main_font_size); rd_cfg_newf(main_font_size, "%f", new_font_size); @@ -12858,7 +12872,7 @@ rd_frame(void) fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); rd_cfg_release_all_children(code_font_size); rd_cfg_newf(code_font_size, "%f", new_font_size); @@ -12868,7 +12882,7 @@ rd_frame(void) fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); rd_cfg_release_all_children(code_font_size); rd_cfg_newf(code_font_size, "%f", new_font_size); @@ -12882,7 +12896,7 @@ rd_frame(void) case RD_CmdKind_SplitPanel: { split_dir = rd_regs()->dir2; - split_panel = rd_cfg_from_handle(rd_regs()->dst_panel); + split_panel = rd_cfg_from_id(rd_regs()->dst_panel); }goto split; split:; if(split_dir != Dir2_Invalid) @@ -12963,8 +12977,8 @@ rd_frame(void) // rjf: if this split was caused by drag/dropping a tab, and the originating panel // has no further tabs, then close the originating panel - RD_Cfg *dragdrop_origin_panel_cfg = rd_cfg_from_handle(rd_regs()->panel); - RD_Cfg *dragdrop_tab = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *dragdrop_origin_panel_cfg = rd_cfg_from_id(rd_regs()->panel); + RD_Cfg *dragdrop_tab = rd_cfg_from_id(rd_regs()->view); if(kind == RD_CmdKind_SplitPanel && new_panel_cfg != &rd_nil_cfg && dragdrop_tab != &rd_nil_cfg && dragdrop_origin_panel_cfg != &rd_nil_cfg) { @@ -12981,14 +12995,14 @@ rd_frame(void) // rjf: focus new panel if(new_panel_cfg != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(new_panel_cfg)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_panel_cfg->id); } }break; //- rjf: panel rotation case RD_CmdKind_RotatePanelColumns: { - RD_Cfg *panel_cfg = rd_cfg_from_handle(rd_regs()->panel); + RD_Cfg *panel_cfg = rd_cfg_from_id(rd_regs()->panel); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel_cfg); RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, panel_cfg); RD_PanelNode *parent = &rd_nil_panel_node; @@ -13013,7 +13027,7 @@ rd_frame(void) case RD_CmdKind_PrevPanel: panel_sib_off = OffsetOf(RD_PanelNode, prev); panel_child_off = OffsetOf(RD_PanelNode, last); goto cycle; cycle:; { - RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(rd_regs()->window)); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(rd_regs()->window)); RD_PanelNode *next_focused = &rd_nil_panel_node; for(RD_PanelNode *p = panel_tree.focused; p != &rd_nil_panel_node; @@ -13037,11 +13051,11 @@ rd_frame(void) } } } - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(next_focused->cfg)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = next_focused->cfg->id); }break; case RD_CmdKind_FocusPanel: { - RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; @@ -13070,7 +13084,7 @@ rd_frame(void) case RD_CmdKind_FocusPanelDown: panel_change_dir = v2s32(+0, +1); goto focus_panel_dir; focus_panel_dir:; { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); RD_PanelNode *src_panel = panel_tree.focused; Rng2F32 src_panel_rect = rd_target_rect_from_panel_node(r2f32(v2f32(0, 0), v2f32(1000, 1000)), panel_tree.root, src_panel); @@ -13103,7 +13117,7 @@ rd_frame(void) break; } } - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_cfg(dst_panel->cfg)); + rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->cfg->id); } }break; @@ -13297,7 +13311,7 @@ rd_frame(void) //- rjf: panel tab controls case RD_CmdKind_FocusTab: { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); RD_Cfg *panel = tab->parent; RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); RD_PanelNode *panel_node = rd_panel_node_from_tree_cfg(panel_tree.root, panel); @@ -13309,7 +13323,7 @@ rd_frame(void) }break; case RD_CmdKind_NextTab: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); RD_PanelNode *focused = panel_tree.focused; RD_CfgNode *selected_tab_n = 0; @@ -13335,12 +13349,12 @@ rd_frame(void) } if(next_selected_tab != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); } }break; case RD_CmdKind_PrevTab: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); RD_PanelNode *focused = panel_tree.focused; RD_CfgNode *selected_tab_n = 0; @@ -13366,7 +13380,7 @@ rd_frame(void) } if(next_selected_tab != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); } }break; case RD_CmdKind_MoveTabRight: @@ -13400,7 +13414,7 @@ rd_frame(void) }break; case RD_CmdKind_CloseTab: { - RD_Cfg *tab = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, tab); RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); B32 found_selected = 0; @@ -13420,7 +13434,7 @@ rd_frame(void) } } } - rd_cmd(RD_CmdKind_FocusTab, .view = rd_handle_from_cfg(next_selected_tab)); + rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); rd_cfg_release(tab); }break; case RD_CmdKind_MoveTab: @@ -13456,12 +13470,12 @@ rd_frame(void) }break; case RD_CmdKind_TabBarTop: { - RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); rd_cfg_release(rd_cfg_child_from_string(panel, str8_lit("tabs_on_bottom"))); }break; case RD_CmdKind_TabBarBottom: { - RD_Cfg *panel = rd_cfg_from_handle(rd_regs()->panel); + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); rd_cfg_child_from_string_or_alloc(panel, str8_lit("tabs_on_bottom")); }break; @@ -13645,7 +13659,7 @@ rd_frame(void) case RD_CmdKind_ResetToDefaultPanels: case RD_CmdKind_ResetToCompactPanels: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *panels = rd_cfg_child_from_string(window, str8_lit("panels")); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); @@ -13996,7 +14010,7 @@ Z(getting_started) String8List search_parts = str8_split_path(scratch.arena, file_part_of_name); // rjf: get source path - RD_Cfg *src_view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *src_view = rd_cfg_from_id(rd_regs()->view); String8 src_view_expr = rd_view_expr_string(); String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, src_view_expr); String8List src_file_parts = str8_split_path(scratch.arena, src_file_path); @@ -14111,7 +14125,7 @@ Z(getting_started) // the biggest empty panel. // 4. If there is no empty panel, then we will pick the biggest // panel. - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); // rjf: grab things to find. path * point, process * address, etc. @@ -14162,7 +14176,7 @@ Z(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_RegsScope(.view = rd_handle_from_cfg(tab)) + RD_RegsScope(.view = tab->id) { String8 tab_expr = rd_view_expr_string(); String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); @@ -14235,7 +14249,7 @@ Z(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_RegsScope(.view = rd_handle_from_cfg(tab)) + RD_RegsScope(.view = tab->id) { B32 tab_is_selected = (tab == panel->selected_tab); RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); @@ -14375,8 +14389,8 @@ Z(getting_started) } // rjf: move cursor & snap-to-cursor - if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = rd_handle_from_cfg(dst_panel->cfg), - .view = rd_handle_from_cfg(dst_tab)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, + .view = dst_tab->id) { rd_cmd(RD_CmdKind_FocusTab); rd_cmd(RD_CmdKind_GoToLine, .cursor = point); @@ -14407,8 +14421,8 @@ Z(getting_started) } // rjf: move cursor & snap-to-cursor - if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = rd_handle_from_cfg(dst_panel->cfg), - .view = rd_handle_from_cfg(dst_tab)) + if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, + .view = dst_tab->id) { rd_cmd(RD_CmdKind_FocusTab); rd_cmd(RD_CmdKind_GoToAddress, .process = process->handle, .vaddr = vaddr); @@ -14467,7 +14481,7 @@ Z(getting_started) //- rjf: query stack case RD_CmdKind_PushQuery: { - RD_Cfg *wcfg = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(wcfg); if(ws != &rd_nil_window_state) { @@ -14529,7 +14543,7 @@ Z(getting_started) }break; case RD_CmdKind_CancelQuery: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); RD_Lister *top_lister = ws->top_query_lister; if(top_lister != 0) @@ -14542,7 +14556,7 @@ Z(getting_started) //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); ws->dev_menu_is_open ^= 1; }break; @@ -14551,7 +14565,7 @@ Z(getting_started) case RD_CmdKind_SelectCfg: case RD_CmdKind_SelectTarget: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_CfgList all_of_the_same_kind = rd_cfg_top_level_list_from_string(scratch.arena, cfg->string); B32 is_selected = rd_disabled_from_cfg(cfg); for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) @@ -14568,25 +14582,25 @@ Z(getting_started) case RD_CmdKind_EnableBreakpoint: case RD_CmdKind_EnableTarget: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("disabled"))); }break; case RD_CmdKind_DisableCfg: case RD_CmdKind_DisableBreakpoint: case RD_CmdKind_DisableTarget: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); rd_cfg_new(disabled, str8_lit("1")); }break; case RD_CmdKind_RemoveCfg: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); rd_cfg_release(cfg); }break; case RD_CmdKind_NameCfg: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); if(rd_regs()->string.size != 0) { RD_Cfg *label = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("label")); @@ -14599,7 +14613,7 @@ Z(getting_started) }break; case RD_CmdKind_ConditionCfg: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); if(rd_regs()->string.size != 0) { RD_Cfg *cnd = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("condition")); @@ -14612,13 +14626,13 @@ Z(getting_started) }break; case RD_CmdKind_DuplicateCfg: { - RD_Cfg *src = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *src = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *dst = rd_cfg_deep_copy(src); rd_cfg_insert_child(src->parent, src, dst); }break; case RD_CmdKind_RelocateCfg: { - RD_Cfg *cfg = rd_cfg_from_handle(rd_regs()->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *loc = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("location")); for(RD_Cfg *child = loc->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { @@ -14846,7 +14860,7 @@ Z(getting_started) RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); rd_cfg_newf(wdir, "%S/", working_directory); } - rd_cmd(RD_CmdKind_SelectCfg, .cfg = rd_handle_from_cfg(target)); + rd_cmd(RD_CmdKind_SelectCfg, .cfg = target->id); }break; //- rjf: jit-debugger registration @@ -15016,7 +15030,7 @@ Z(getting_started) //- rjf: meta controls case RD_CmdKind_Edit: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; @@ -15025,7 +15039,7 @@ Z(getting_started) }break; case RD_CmdKind_Accept: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; @@ -15034,7 +15048,7 @@ Z(getting_started) }break; case RD_CmdKind_Cancel: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Press; @@ -15050,7 +15064,7 @@ Z(getting_started) // case RD_CmdKind_MoveLeft: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15061,7 +15075,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveRight: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15072,7 +15086,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUp: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15083,7 +15097,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDown: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15094,7 +15108,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveLeftSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15105,7 +15119,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveRightSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15116,7 +15130,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15127,7 +15141,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15138,7 +15152,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveLeftChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15149,7 +15163,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveRightChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15160,7 +15174,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15171,7 +15185,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15182,7 +15196,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpPage: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15192,7 +15206,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownPage: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15202,7 +15216,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpWhole: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15212,7 +15226,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownWhole: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15222,7 +15236,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveLeftChunkSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15233,7 +15247,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveRightChunkSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15244,7 +15258,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpChunkSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15255,7 +15269,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownChunkSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15266,7 +15280,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpPageSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15277,7 +15291,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownPageSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15288,7 +15302,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpWholeSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15299,7 +15313,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownWholeSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15310,7 +15324,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveUpReorder: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15321,7 +15335,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveDownReorder: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15332,7 +15346,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveHome: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15342,7 +15356,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveEnd: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15352,7 +15366,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveHomeSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15363,7 +15377,7 @@ Z(getting_started) }break; case RD_CmdKind_MoveEndSelect: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; @@ -15374,7 +15388,7 @@ Z(getting_started) }break; case RD_CmdKind_SelectAll: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt1 = zero_struct; evt1.kind = UI_EventKind_Navigate; @@ -15390,7 +15404,7 @@ Z(getting_started) }break; case RD_CmdKind_DeleteSingle: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15401,7 +15415,7 @@ Z(getting_started) }break; case RD_CmdKind_DeleteChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15412,7 +15426,7 @@ Z(getting_started) }break; case RD_CmdKind_BackspaceSingle: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15423,7 +15437,7 @@ Z(getting_started) }break; case RD_CmdKind_BackspaceChunk: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15434,7 +15448,7 @@ Z(getting_started) }break; case RD_CmdKind_Copy: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15443,7 +15457,7 @@ Z(getting_started) }break; case RD_CmdKind_Cut: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; @@ -15452,7 +15466,7 @@ Z(getting_started) }break; case RD_CmdKind_Paste: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; @@ -15461,7 +15475,7 @@ Z(getting_started) }break; case RD_CmdKind_InsertText: { - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Text; @@ -15805,7 +15819,7 @@ Z(getting_started) } if(!any_window_is_focused) { - RD_Cfg *last_focused_window = rd_cfg_from_handle(rd_state->last_focused_window); + RD_Cfg *last_focused_window = rd_cfg_from_id(rd_state->last_focused_window); RD_WindowState *ws = rd_window_state_from_cfg(last_focused_window); if(ws == &rd_nil_window_state) { @@ -15911,7 +15925,7 @@ Z(getting_started) rd_state->ambiguous_path_slots = push_array(rd_frame_arena(), RD_AmbiguousPathNode *, rd_state->ambiguous_path_slots_count); for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) { - RD_Cfg *window = rd_cfg_from_handle(ws->cfg_handle); + RD_Cfg *window = rd_cfg_from_id(ws->cfg_id); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { @@ -15922,7 +15936,7 @@ Z(getting_started) { continue; } - RD_RegsScope(.view = rd_handle_from_cfg(tab)) + RD_RegsScope(.view = tab->id) { String8 eval_string = rd_view_expr_string(); String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); @@ -15979,14 +15993,14 @@ Z(getting_started) B32 window_is_focused = os_window_is_focused(w->os); if(window_is_focused) { - rd_state->last_focused_window = w->cfg_handle; + rd_state->last_focused_window = w->cfg_id; } rd_push_regs(); - rd_regs()->window = w->cfg_handle; + rd_regs()->window = w->cfg_id; rd_window_frame(); MemoryZeroStruct(&w->ui_events); RD_Regs *window_regs = rd_pop_regs(); - if(rd_handle_match(rd_state->last_focused_window, w->cfg_handle)) + if(rd_state->last_focused_window == w->cfg_id) { MemoryCopyStruct(rd_regs(), window_regs); } @@ -16045,17 +16059,17 @@ Z(getting_started) // if(depth == 0) { - RD_HandleList windows_to_show = {0}; + RD_CfgIDList windows_to_show = {0}; for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) { if(w->frames_alive == 1) { - rd_handle_list_push(scratch.arena, &windows_to_show, w->cfg_handle); + rd_cfg_id_list_push(scratch.arena, &windows_to_show, w->cfg_id); } } - for(RD_HandleNode *n = windows_to_show.first; n != 0; n = n->next) + for(RD_CfgIDNode *n = windows_to_show.first; n != 0; n = n->next) { - RD_Cfg *window = rd_cfg_from_handle(n->handle); + RD_Cfg *window = rd_cfg_from_id(n->v); RD_WindowState *ws = rd_window_state_from_cfg(window); DeferLoop(depth += 1, depth -= 1) os_window_first_paint(ws->os); } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index b7a6c1f7..d9fc5fe6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -5,27 +5,22 @@ #define RADDBG_CORE_H //////////////////////////////// -//~ rjf: Handles +//~ rjf: Config IDs -typedef struct RD_Handle RD_Handle; -struct RD_Handle +typedef U64 RD_CfgID; + +typedef struct RD_CfgIDNode RD_CfgIDNode; +struct RD_CfgIDNode { - U64 u64[2]; + RD_CfgIDNode *next; + RD_CfgID v; }; -typedef struct RD_HandleNode RD_HandleNode; -struct RD_HandleNode +typedef struct RD_CfgIDList RD_CfgIDList; +struct RD_CfgIDList { - RD_HandleNode *next; - RD_HandleNode *prev; - RD_Handle handle; -}; - -typedef struct RD_HandleList RD_HandleList; -struct RD_HandleList -{ - RD_HandleNode *first; - RD_HandleNode *last; + RD_CfgIDNode *first; + RD_CfgIDNode *last; U64 count; }; @@ -179,7 +174,7 @@ struct RD_ViewState // rjf: hash links & key RD_ViewState *hash_next; RD_ViewState *hash_prev; - RD_Handle cfg_handle; + RD_CfgID cfg_id; // rjf: touch info U64 last_frame_index_touched; @@ -297,7 +292,7 @@ struct RD_Cfg RD_Cfg *next; RD_Cfg *prev; RD_Cfg *parent; - U64 gen; + RD_CfgID id; String8 string; }; @@ -309,6 +304,13 @@ struct RD_CfgNode RD_Cfg *v; }; +typedef struct RD_CfgSlot RD_CfgSlot; +struct RD_CfgSlot +{ + RD_CfgNode *first; + RD_CfgNode *last; +}; + typedef struct RD_CfgList RD_CfgList; struct RD_CfgList { @@ -333,7 +335,7 @@ struct RD_CfgRec }; //////////////////////////////// -//~ rjf: Structured Locations, Parsed From Config +//~ rjf: Structured Locations, Parsed From Config Trees typedef struct RD_Location RD_Location; struct RD_Location @@ -345,7 +347,7 @@ struct RD_Location }; //////////////////////////////// -//~ rjf: New Panel Types (Queried From Config) +//~ rjf: Structured Panel Trees, Parsed From Config Trees typedef struct RD_PanelNode RD_PanelNode; struct RD_PanelNode @@ -423,7 +425,7 @@ struct RD_RegsNode }; //////////////////////////////// -//~ rjf: Theme Types +//~ rjf: Structured Theme Types, Parsed From Config typedef struct RD_Theme RD_Theme; struct RD_Theme @@ -535,7 +537,7 @@ struct RD_WindowState RD_WindowState *order_prev; RD_WindowState *hash_next; RD_WindowState *hash_prev; - RD_Handle cfg_handle; + RD_CfgID cfg_id; U64 frames_alive; U64 last_frame_index_touched; @@ -648,7 +650,7 @@ typedef struct RD_Cfg2EvalBlobNode RD_Cfg2EvalBlobNode; struct RD_Cfg2EvalBlobNode { RD_Cfg2EvalBlobNode *next; - RD_Handle handle; + RD_CfgID id; String8 blob; }; @@ -821,12 +823,16 @@ struct RD_State RD_NameChunkNode *free_name_chunks[8]; RD_Cfg *free_cfg; RD_Cfg *root_cfg; + U64 cfg_id_slots_count; + RD_CfgSlot *cfg_id_slots; + RD_CfgNode *free_cfg_id_node; + U64 cfg_id_gen; // rjf: window state cache U64 window_state_slots_count; RD_WindowStateSlot *window_state_slots; RD_WindowState *free_window_state; - RD_Handle last_focused_window; + RD_CfgID last_focused_window; RD_WindowState *first_window_state; RD_WindowState *last_window_state; @@ -905,17 +911,14 @@ read_only global RD_WindowState rd_nil_window_state = }; global RD_State *rd_state = 0; -global RD_Handle rd_last_drag_drop_panel = {0}; -global RD_Handle rd_last_drag_drop_prev_tab = {0}; +global RD_CfgID rd_last_drag_drop_panel = 0; +global RD_CfgID rd_last_drag_drop_prev_tab = 0; //////////////////////////////// -//~ rjf: Handle Type Pure Functions +//~ rjf: Config ID Type Functions -internal RD_Handle rd_handle_zero(void); -internal B32 rd_handle_match(RD_Handle a, RD_Handle b); -internal void rd_handle_list_push_node(RD_HandleList *list, RD_HandleNode *node); -internal void rd_handle_list_push(Arena *arena, RD_HandleList *list, RD_Handle handle); -internal RD_HandleList rd_handle_list_copy(Arena *arena, RD_HandleList list); +internal void rd_cfg_id_list_push(Arena *arena, RD_CfgIDList *list, RD_CfgID id); +internal RD_CfgIDList rd_cfg_id_list_copy(Arena *arena, RD_CfgIDList *src); //////////////////////////////// //~ rjf: Registers Type Functions @@ -956,13 +959,12 @@ internal String8 rd_name_alloc(String8 string); internal void rd_name_release(String8 string); //////////////////////////////// -//~ rjf: New Config/Entity Data Structure Functions +//~ rjf: Config Tree Functions internal RD_Cfg *rd_cfg_alloc(void); internal void rd_cfg_release(RD_Cfg *cfg); internal void rd_cfg_release_all_children(RD_Cfg *cfg); -internal RD_Handle rd_handle_from_cfg(RD_Cfg *cfg); -internal RD_Cfg *rd_cfg_from_handle(RD_Handle handle); +internal RD_Cfg *rd_cfg_from_id(RD_CfgID id); internal RD_Cfg *rd_cfg_new(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_newf(RD_Cfg *parent, char *fmt, ...); internal RD_Cfg *rd_cfg_deep_copy(RD_Cfg *src_root); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index e13a55f7..7f340862 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -723,13 +723,13 @@ entry_point(CmdLine *cmd_line) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_kind_name_string); if(cmd_kind_info != &rd_nil_cmd_kind_info) RD_RegsScope() { - if(!rd_handle_match(dst_ws->cfg_handle, rd_regs()->window)) + if(dst_ws->cfg_id != rd_regs()->window) { Temp scratch = scratch_begin(0, 0); - RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_handle(dst_ws->cfg_handle)); - rd_regs()->window = dst_ws->cfg_handle; - rd_regs()->panel = rd_handle_from_cfg(panel_tree.focused->cfg); - rd_regs()->view = rd_handle_from_cfg(panel_tree.focused->selected_tab); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(dst_ws->cfg_id)); + rd_regs()->window = dst_ws->cfg_id; + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; scratch_end(scratch); } rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, cmd_args_string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index be895e31..4c8a51ed 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -58,7 +58,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) + if(rd_regs()->view != cmd->regs->view) { continue; } @@ -1291,7 +1291,7 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn case RD_WatchViewColumnKind_ViewRule: ProfScope("view rule cell string") { - RD_Cfg *view = rd_cfg_from_handle(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *vs = rd_view_state_from_cfg(view); EV_View *ev = vs->ev_view; result = ev_view_rule_from_key(ev, row->key); @@ -4110,12 +4110,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) { - rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = rd_handle_from_cfg(target_cfg)); + rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); } ui_spacer(ui_em(1.5f, 1)); if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) { - rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = rd_handle_from_cfg(target_cfg)); + rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); } } }break; @@ -4200,7 +4200,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) + if(rd_regs()->view != cmd->regs->view) { continue; } @@ -4336,7 +4336,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ProfScope("process code-file commands") for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) + if(rd_regs()->view != cmd->regs->view) { continue; } @@ -4627,7 +4627,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) + if(rd_regs()->view != cmd->regs->view) { continue; } @@ -4834,7 +4834,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) { // rjf: mismatched window/panel => skip - if(!rd_handle_match(rd_regs()->view, cmd->regs->view)) + if(rd_regs()->view != cmd->regs->view) { continue; } @@ -6327,7 +6327,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) Temp scratch = scratch_begin(0, 0); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); String8 query = string; - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index eceda5a1..c8e90106 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -345,7 +345,7 @@ rd_cmd_list_menu_buttons(U64 count, String8 *cmd_names, U32 *fastpath_codepoints { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_names[idx]); ui_ctx_menu_close(); - RD_Cfg *window = rd_cfg_from_handle(rd_regs()->window); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; } @@ -974,7 +974,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_BreakpointBoxDrawExtData *bp_draw = push_array(ui_build_arena(), RD_BreakpointBoxDrawExtData, 1); { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (rd_cfg_from_handle(hover_regs->cfg) == bp && rd_state->hover_regs_slot == RD_RegSlot_Cfg); + B32 is_hovering = (rd_cfg_from_id(hover_regs->cfg) == bp && rd_state->hover_regs_slot == RD_RegSlot_Cfg); bp_draw->color = bp_rgba; bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); @@ -1014,32 +1014,32 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - RD_RegsScope(.cfg = rd_handle_from_cfg(bp)) rd_set_hover_regs(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: shift+click => enable breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags & OS_Modifier_Shift) { - rd_cmd(bp_is_disabled ? RD_CmdKind_EnableCfg : RD_CmdKind_DisableCfg, .cfg = rd_handle_from_cfg(bp)); + rd_cmd(bp_is_disabled ? RD_CmdKind_EnableCfg : RD_CmdKind_DisableCfg, .cfg = bp->id); } // rjf: click => remove breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags == 0) { - rd_cmd(RD_CmdKind_RemoveCfg, .cfg = rd_handle_from_cfg(bp)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = bp->id); } // rjf: drag start if(ui_dragging(bp_sig) && !contains_2f32(bp_box->rect, ui_mouse())) { - RD_RegsScope(.cfg = rd_handle_from_cfg(bp)) rd_drag_begin(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = bp->id) rd_drag_begin(RD_RegSlot_Cfg); } // rjf: bp right-click menu if(ui_right_clicked(bp_sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(bp), + .cfg = bp->id, .reg_slot = RD_RegSlot_Cfg, .ui_key = bp_box->key, .off_px = v2f32(0, bp_box->rect.y1-bp_box->rect.y0), @@ -1075,26 +1075,26 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_set_hover_regs(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: click => remove pin if(ui_clicked(pin_sig)) { - rd_cmd(RD_CmdKind_RemoveCfg, .cfg = rd_handle_from_cfg(pin)); + rd_cmd(RD_CmdKind_RemoveCfg, .cfg = pin->id); } // rjf: drag start if(ui_dragging(pin_sig) && !contains_2f32(pin_box->rect, ui_mouse())) { - RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_drag_begin(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } // rjf: watch right-click menu if(ui_right_clicked(pin_sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(pin), + .cfg = pin->id, .reg_slot = RD_RegSlot_Cfg, .ui_key = pin_box->key, .off_px = v2f32(0, pin_box->rect.y1-pin_box->rect.y0), @@ -1311,12 +1311,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal sig = ui_buttonf("%S###pin_nub", rd_icon_kind_text_table[RD_IconKind_Pin]); if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) { - RD_RegsScope(.cfg = rd_handle_from_cfg(pin)) rd_drag_begin(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } if(ui_right_clicked(sig)) { rd_cmd(RD_CmdKind_PushQuery, - .cfg = rd_handle_from_cfg(pin), + .cfg = pin->id, .reg_slot = RD_RegSlot_Cfg, .ui_key = sig.box->key, .off_px = v2f32(0, sig.box->rect.y1-sig.box->rect.y0), @@ -1482,7 +1482,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(rd_drag_is_active() && contains_2f32(clipped_top_container_rect, ui_mouse())) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); - RD_Cfg *cfg = rd_cfg_from_handle(rd_state->drag_drop_regs->cfg); + RD_Cfg *cfg = rd_cfg_from_id(rd_state->drag_drop_regs->cfg); if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && (str8_match(cfg->string, str8_lit("breakpoint"), 0) || str8_match(cfg->string, str8_lit("watch_pin"), 0))) @@ -1514,7 +1514,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_idx = line_num - params->line_num_range.min; U64 line_vaddr = params->line_vaddrs[line_idx]; rd_cmd(RD_CmdKind_RelocateCfg, - .cfg = rd_handle_from_cfg(dropped_cfg), + .cfg = dropped_cfg->id, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); From ffe8a0169908478b0210c557c6006d54683d3eb3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 14:15:50 -0800 Subject: [PATCH 059/755] uid <-> num mapping for top-level cfg collection expansions; fix incorrect expansion for watches --- src/raddbg/raddbg_core.c | 97 ++++++++++++++++++++++++++++++++++----- src/raddbg/raddbg_views.c | 6 +-- 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d57d7162..6764ab86 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8160,7 +8160,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(watches) U64 cfg_idx = read_range.min + idx; if(cfg_idx < cfgs->count) { - String8 expr_string = rd_cfg_child_from_string(cfgs->v[idx], str8_lit("expression"))->first->string; + String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; exprs[idx] = e_parse_expr_from_text(arena, expr_string); exprs_strings[idx] = push_str8_copy(arena, expr_string); } @@ -8260,6 +8260,8 @@ struct RD_TopLevelCfgLookupAccel { String8Array cmds; RD_CfgArray cfgs; + Rng1U64 cmds_idx_range; + Rng1U64 cfgs_idx_range; }; E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) @@ -8290,6 +8292,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); accel->cmds = str8_array_from_list(arena, &cmds_list); + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs_idx_range = r1u64(accel->cmds.count, accel->cmds.count + accel->cfgs.count); result.user_data = accel; result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; } @@ -8304,16 +8308,14 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) { Temp scratch = scratch_begin(&arena, 1); RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - Rng1U64 cmds_idx_range = r1u64(0, accel->cmds.count); - Rng1U64 cfgs_idx_range = r1u64(accel->cmds.count, accel->cmds.count + accel->cfgs.count); E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; - if(contains_1u64(cmds_idx_range, rhs_value.u64)) + if(contains_1u64(accel->cmds_idx_range, rhs_value.u64)) { - String8 cmd_name = accel->cmds.v[rhs_value.u64 - cmds_idx_range.min]; + String8 cmd_name = accel->cmds.v[rhs_value.u64 - accel->cmds_idx_range.min]; RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); E_TypeKey type_key = e_type_key_basic(E_TypeKind_U64); E_Space cmd_space = e_space_make(RD_EvalSpaceKind_MetaCmd); @@ -8321,9 +8323,9 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) result.irtree_and_type.type_key = type_key; result.irtree_and_type.mode = E_Mode_Value; } - else if(contains_1u64(cfgs_idx_range, rhs_value.u64)) + else if(contains_1u64(accel->cfgs_idx_range, rhs_value.u64)) { - RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64 - cfgs_idx_range.min]; + RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64 - accel->cfgs_idx_range.min]; E_Space cfg_space = rd_eval_space_from_cfg(cfg); String8 cfg_name = cfg->string; E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); @@ -8336,6 +8338,63 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) return result; } +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) +{ + U64 id = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(num != 0) + { + U64 idx = (num-1); + if(contains_1u64(accel->cfgs_idx_range, idx)) + { + id = accel->cfgs.v[idx - accel->cfgs_idx_range.min]->id; + } + else if(contains_1u64(accel->cmds_idx_range, idx)) + { + String8 cmd_name = accel->cmds.v[idx - accel->cmds_idx_range.min]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + id = (U64)cmd_kind; + id |= (1ull<<63); + } + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) +{ + U64 num = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(id != 0) + { + if(id & (1ull<<63)) + { + for EachIndex(idx, accel->cmds.count) + { + String8 cmd_name = accel->cmds.v[idx - accel->cmds_idx_range.min]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + U64 cmd_id = (U64)cmd_kind; + cmd_id |= (1ull<<63); + if(cmd_id == id) + { + num = idx+1+accel->cmds_idx_range.min; + } + } + } + else + { + for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx+1+accel->cfgs_idx_range.min; + break; + } + } + } + } + return num; +} + E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) { E_LookupInfo result = {0}; @@ -12334,8 +12393,10 @@ rd_frame(void) expr->type_key = collection_type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(top_level_cfg)); + .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(top_level_cfg), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(top_level_cfg), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(top_level_cfg)); } //- rjf: add macros for all ctrl entity collections @@ -12797,9 +12858,21 @@ rd_frame(void) if(kind == RD_CmdKind_OpenUser) { RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("current_thread")); + { + RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, str8_lit("current_thread")); + } + { + RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, str8_lit("targets[1]")); + } + { + RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); + rd_cfg_new(expr, str8_lit("basics")); + } } }break; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4c8a51ed..a7cfdaf3 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -967,10 +967,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: determine row's cfg if(info.group_cfg_name.size != 0) { - RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, info.group_cfg_name); - - // TODO(rjf): this is not correct - assumes row's evaluation is in the block's space... - // info.group_cfg = rd_cfg_from_eval_space(info.eval.space); + RD_CfgID id = row->key.child_id; + info.group_cfg = rd_cfg_from_id(id); } // rjf: fill row's cells From f2a958e5b696c0107d4d6d4ffcf1510c0e8069f8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 16:09:20 -0800 Subject: [PATCH 060/755] rd: progress on reintroducing watch window editability --- .../eval_visualization_core.c | 8 +- src/raddbg/raddbg_core.c | 341 +++++++++++------- src/raddbg/raddbg_views.c | 88 ++--- src/raddbg/raddbg_views.h | 2 +- 4 files changed, 260 insertions(+), 179 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 8a311a1b..122d14d1 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -828,6 +828,10 @@ ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num) base_num = next_base_num; base_vnum += dim_1u64(n->v.range); } + if(vnum == 0) + { + vnum = base_vnum; + } } return vnum; } @@ -991,8 +995,8 @@ ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList * internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range) { - Rng1U64 vidx_range = r1u64(ev_vnum_from_num(block_ranges, num_range.min), ev_vnum_from_num(block_ranges, num_range.max)+1); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vidx_range); + Rng1U64 vnum_range = r1u64(ev_vnum_from_num(block_ranges, num_range.min), ev_vnum_from_num(block_ranges, num_range.max)+1); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vnum_range); return rows; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6764ab86..dcc76c74 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5627,118 +5627,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: bottom bar - // - ProfScope("build bottom bar") - { - B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); - CTRL_Event stop_event = d_ctrl_last_stop_event(); - UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_PositivePopButton); - UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_NeutralPopButton); - UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_NegativePopButton); - UI_Palette *palette = running_scheme; - if(!is_running) - { - switch(stop_event.cause) - { - default: - case CTRL_EventCause_Finished: - { - palette = positive_scheme; - }break; - case CTRL_EventCause_UserBreakpoint: - case CTRL_EventCause_InterruptedByException: - case CTRL_EventCause_InterruptedByTrap: - case CTRL_EventCause_InterruptedByHalt: - { - palette = negative_scheme; - }break; - } - } - if(ws->error_t > 0.01f) - { - UI_Palette *blended_scheme = push_array(ui_build_arena(), UI_Palette, 1); - MemoryCopyStruct(blended_scheme, palette); - for EachEnumVal(UI_ColorCode, code) - { - for(U64 idx = 0; idx < 4; idx += 1) - { - blended_scheme->colors[code].v[idx] += (negative_scheme->colors[code].v[idx] - blended_scheme->colors[code].v[idx]) * ws->error_t; - } - } - palette = blended_scheme; - } - UI_Flags(UI_BoxFlag_DrawBackground) UI_CornerRadius(0) - UI_Palette(palette) - UI_Pane(bottom_bar_rect, str8_lit("###bottom_bar")) UI_WidthFill UI_Row - UI_Flags(0) - { - // rjf: developer frame-time indicator - if(DEV_updating_indicator) - { - F32 animation_t = pow_f32(sin_f32(rd_state->time_in_seconds/2.f), 2.f); - ui_spacer(ui_em(0.3f, 1.f)); - ui_spacer(ui_em(1.5f*animation_t, 1.f)); - UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("*"); - ui_spacer(ui_em(1.5f*(1-animation_t), 1.f)); - } - - // rjf: status - { - ui_spacer(ui_em(1.f, 1.f)); - if(is_running) - { - ui_label(str8_lit("Running")); - } - else - { - Temp scratch = scratch_begin(0, 0); - DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &explanation_fstrs); - scratch_end(scratch); - } - } - - ui_spacer(ui_pct(1, 0)); - - // rjf: bind change visualization - if(rd_state->bind_change_active) - { - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); - UI_PrefWidth(ui_text_dim(10, 1)) - UI_Flags(UI_BoxFlag_DrawBackground) - UI_TextAlignment(UI_TextAlign_Center) - UI_CornerRadius(4) - RD_Palette(RD_PaletteCode_NeutralPopButton) - ui_labelf("Currently rebinding \"%S\" hotkey", info->display_name); - } - - // rjf: error visualization - else if(ws->error_t >= 0.01f) - { - ws->error_t -= rd_state->frame_dt/8.f; - rd_request_frame(); - String8 error_string = str8(ws->error_buffer, ws->error_string_size); - if(error_string.size != 0) - { - ui_set_next_pref_width(ui_children_sum(1)); - UI_CornerRadius(4) - UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - { - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); - rd_label(error_string); - } - } - } - } - } - //////////////////////////// //- rjf: build hover eval // @@ -5807,7 +5695,11 @@ rd_window_frame(void) rd_cfg_new(expr, ws->hover_eval_string); EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*40.f / row_height_px); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) @@ -5859,7 +5751,7 @@ rd_window_frame(void) { ws->hover_eval_focused = 1; } - if(ui_mouse_over(sig)) + if(ui_mouse_over(sig) || ws->hover_eval_focused) { ws->hover_eval_last_frame_idx = rd_state->frame_index; } @@ -5867,6 +5759,22 @@ rd_window_frame(void) { rd_request_frame(); } + if(ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + !contains_2f32(container->rect, evt->pos)) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + break; + } + } + } } } @@ -6163,6 +6071,118 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: bottom bar + // + ProfScope("build bottom bar") + { + B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); + CTRL_Event stop_event = d_ctrl_last_stop_event(); + UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_PositivePopButton); + UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_NeutralPopButton); + UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_NegativePopButton); + UI_Palette *palette = running_scheme; + if(!is_running) + { + switch(stop_event.cause) + { + default: + case CTRL_EventCause_Finished: + { + palette = positive_scheme; + }break; + case CTRL_EventCause_UserBreakpoint: + case CTRL_EventCause_InterruptedByException: + case CTRL_EventCause_InterruptedByTrap: + case CTRL_EventCause_InterruptedByHalt: + { + palette = negative_scheme; + }break; + } + } + if(ws->error_t > 0.01f) + { + UI_Palette *blended_scheme = push_array(ui_build_arena(), UI_Palette, 1); + MemoryCopyStruct(blended_scheme, palette); + for EachEnumVal(UI_ColorCode, code) + { + for(U64 idx = 0; idx < 4; idx += 1) + { + blended_scheme->colors[code].v[idx] += (negative_scheme->colors[code].v[idx] - blended_scheme->colors[code].v[idx]) * ws->error_t; + } + } + palette = blended_scheme; + } + UI_Flags(UI_BoxFlag_DrawBackground) UI_CornerRadius(0) + UI_Palette(palette) + UI_Pane(bottom_bar_rect, str8_lit("###bottom_bar")) UI_WidthFill UI_Row + UI_Flags(0) + { + // rjf: developer frame-time indicator + if(DEV_updating_indicator) + { + F32 animation_t = pow_f32(sin_f32(rd_state->time_in_seconds/2.f), 2.f); + ui_spacer(ui_em(0.3f, 1.f)); + ui_spacer(ui_em(1.5f*animation_t, 1.f)); + UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("*"); + ui_spacer(ui_em(1.5f*(1-animation_t), 1.f)); + } + + // rjf: status + { + ui_spacer(ui_em(1.f, 1.f)); + if(is_running) + { + ui_label(str8_lit("Running")); + } + else + { + Temp scratch = scratch_begin(0, 0); + DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(box, &explanation_fstrs); + scratch_end(scratch); + } + } + + ui_spacer(ui_pct(1, 0)); + + // rjf: bind change visualization + if(rd_state->bind_change_active) + { + RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); + UI_PrefWidth(ui_text_dim(10, 1)) + UI_Flags(UI_BoxFlag_DrawBackground) + UI_TextAlignment(UI_TextAlign_Center) + UI_CornerRadius(4) + RD_Palette(RD_PaletteCode_NeutralPopButton) + ui_labelf("Currently rebinding \"%S\" hotkey", info->display_name); + } + + // rjf: error visualization + else if(ws->error_t >= 0.01f) + { + ws->error_t -= rd_state->frame_dt/8.f; + rd_request_frame(); + String8 error_string = str8(ws->error_buffer, ws->error_string_size); + if(error_string.size != 0) + { + ui_set_next_pref_width(ui_children_sum(1)); + UI_CornerRadius(4) + UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + { + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) + ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); + rd_label(error_string); + } + } + } + } + } + //////////////////////////// //- rjf: panel non-leaf UI (drag boundaries, drag/drop sites) // @@ -8167,6 +8187,44 @@ E_LOOKUP_RANGE_FUNCTION_DEF(watches) } } +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(watches) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + E_LOOKUP_INFO_FUNCTION_DEF(locals) { E_LookupInfo result = {0}; @@ -8727,7 +8785,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul CTRL_Entity *process = ctrl_process_from_entity(entity); if(process == &ctrl_entity_nil) { - process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + process = ctrl_process_from_entity(thread); } String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1); @@ -12336,30 +12395,44 @@ rd_frame(void) e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); } - //- rjf: add macro for collections with specific lookup rules - struct + //- rjf: add macro for watches group { - String8 name; - E_LookupInfoFunctionType *lookup_info; - E_LookupRangeFunctionType *lookup_range; - } - collection_infos[] = - { -#define Collection(name) {str8_lit_comp(#name), E_LOOKUP_INFO_FUNCTION_NAME(name), E_LOOKUP_RANGE_FUNCTION_NAME(name)} - Collection(watches), - Collection(locals), - Collection(registers), -#undef Collection - }; - for EachElement(idx, collection_infos) - { - String8 collection_name = collection_infos[idx].name; + String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = collection_infos[idx].lookup_info, - .range = collection_infos[idx].lookup_range); + .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(watches), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(watches), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(watches)); + } + + //- rjf: add macro for collections with specific lookup rules (but no unique id rules) + { + struct + { + String8 name; + E_LookupInfoFunctionType *lookup_info; + E_LookupRangeFunctionType *lookup_range; + } + collection_infos[] = + { +#define Collection(name) {str8_lit_comp(#name), E_LOOKUP_INFO_FUNCTION_NAME(name), E_LOOKUP_RANGE_FUNCTION_NAME(name)} + Collection(locals), + Collection(registers), +#undef Collection + }; + for EachElement(idx, collection_infos) + { + String8 collection_name = collection_infos[idx].name; + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, + .info = collection_infos[idx].lookup_info, + .range = collection_infos[idx].lookup_range); + } } //- rjf: add macros for debug info table collections diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a7cfdaf3..55d902ac 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1108,7 +1108,7 @@ rd_watch_view_row_info_from_row(EV_Row *row) //- rjf: row * cell -> string internal RD_WatchRowCellInfo -rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) +rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { RD_WatchRowCellInfo result = {0}; switch(cell->kind) @@ -1117,6 +1117,10 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info // expression tree. case RD_WatchCellKind_Expr: { + if(row->string.size != 0 || row->expr == &e_expr_nil) + { + result.can_edit = 1; + } result.string = row->string; if(result.string.size == 0) { @@ -1204,8 +1208,9 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info } //- rjf: evaluate wrapped expression - result.eval = e_eval_from_expr(scratch.arena, root_expr); - result.string = rd_value_string_from_eval(arena, 0, 10, font, font_size, max_size_px, result.eval); + result.eval = e_eval_from_expr(scratch.arena, root_expr); + result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); + result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); scratch_end(scratch); }break; @@ -1215,6 +1220,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info { EV_View *ev_view = rd_view_eval_view(); result.string = ev_view_rule_from_key(ev_view, row->key); + result.can_edit = 1; }break; } return result; @@ -1507,7 +1513,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; - EV_StringFlags string_flags = 0; + EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; String8 filter = rd_view_filter(); String8 expr = rd_view_expr_string(); if(expr.size == 0) @@ -1572,10 +1578,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) { MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); - if(implicit_root) - { - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - } + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, expr); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); } @@ -1769,7 +1772,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) { continue; } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); if(cell_info.can_edit) { any_edits_started = 1; @@ -1779,6 +1782,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) U64 hash = ev_hash_from_key(pt.key); U64 slot_idx = hash%ewv->text_edit_state_slots_count; RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); + SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); edit_state->pt = pt; edit_state->cursor = txt_pt(1, string.size+1); edit_state->mark = txt_pt(1, 1); @@ -2045,7 +2049,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) { continue; } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); String8 cell_string = cell_info.string; cell_string = str8_skip_chop_whitespace(cell_string); U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); @@ -2302,65 +2306,65 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) } // rjf: determine collection info for the block - RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); - E_Type *type = e_type_from_key__cached(irtree.type_key); -#if 0 // TODO(rjf): @cfg - for EachElement(idx, rd_collection_name_table) + String8 group_cfg_name = {0}; { - if(str8_match(type->name, rd_collection_name_table[idx], 0)) + E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); + E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + if(block_type_kind == E_TypeKind_Set) { - collection_entity_kind = rd_collection_entity_kind_table[idx]; - break; + E_Type *block_type = e_type_from_key__cached(block_type_key); + group_cfg_name = rd_singular_from_code_name_plural(block_type->name); } } -#endif - // rjf: map selection endpoints to entities -#if 0 // TODO(rjf): @cfg - RD_Entity *first_entity = &rd_nil_entity; - RD_Entity *last_entity = &rd_nil_entity; - if(collection_entity_kind != RD_EntityKind_Nil) + // rjf: map selection endpoints to cfgs + RD_Cfg *first_cfg = &rd_nil_cfg; + RD_Cfg *last_cfg = &rd_nil_cfg; + if(group_cfg_name.size != 0) { - first_entity = rd_entity_from_id(selection_keys_in_block[0].child_id); - last_entity = rd_entity_from_id(selection_keys_in_block[1].child_id); + first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); + last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); } // rjf: reorder - if(!rd_entity_is_nil(first_entity) && !rd_entity_is_nil(last_entity)) + if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) { - RD_Entity *first_entity_prev = &rd_nil_entity; - RD_Entity *last_entity_next = &rd_nil_entity; - for(RD_Entity *prev = first_entity->prev; !rd_entity_is_nil(prev); prev = prev->prev) + RD_Cfg *first_cfg_prev = &rd_nil_cfg; + RD_Cfg *last_cfg_next = &rd_nil_cfg; + for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) { - if(prev->kind == collection_entity_kind) + if(str8_match(prev->string, first_cfg->string, 0)) { - first_entity_prev = prev; + first_cfg_prev = prev; break; } } - for(RD_Entity *next = last_entity->next; !rd_entity_is_nil(next); next = next->next) + for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) { - if(next->kind == collection_entity_kind) + if(str8_match(next->string, last_cfg->string, 0)) { - last_entity_next = next; + last_cfg_next = next; break; } } - if(evt->delta_2s32.y < 0 && !rd_entity_is_nil(first_entity) && !rd_entity_is_nil(first_entity_prev)) + if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) { state_dirty = 1; snap_to_cursor = 1; - rd_entity_change_parent(first_entity_prev, first_entity_prev->parent, first_entity_prev->parent, last_entity); + RD_Cfg *parent = first_cfg_prev->parent; + rd_cfg_unhook(parent, first_cfg_prev); + rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); } - if(evt->delta_2s32.y > 0 && !rd_entity_is_nil(last_entity) && !rd_entity_is_nil(last_entity_next)) + if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) { state_dirty = 1; snap_to_cursor = 1; - rd_entity_change_parent(last_entity_next, last_entity_next->parent, last_entity_next->parent, first_entity_prev); + RD_Cfg *parent = last_cfg_next->parent; + rd_cfg_unhook(parent, last_cfg_next); + rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); } } -#endif } } @@ -2592,7 +2596,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); //- rjf: determine cell's palette ProfBegin("determine cell's palette"); @@ -3971,7 +3975,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) // if(next_row_expanded != row_expanded) { - if(!ev_key_match(ev_key_root(), row->key) || !implicit_root) + if(!ev_key_match(ev_key_root(), row->key)) { ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index dd563f32..36744ed0 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -215,7 +215,7 @@ internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); #endif //- rjf: row * cell -> info -internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); +internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: row/column -> exprs / strings #if 0 // TODO(rjf): @cfg From 66ab9c0ba3cf9d5800028d123d1d261586e96ef6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 5 Feb 2025 16:21:51 -0800 Subject: [PATCH 061/755] rd: watch cell string edit commits --- src/raddbg/raddbg_views.c | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 55d902ac..af967269 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1934,6 +1934,58 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) edit_state->mark = op.mark; // rjf: commit edited cell string + switch(cell->kind) + { + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg; + if(cfg == &rd_nil_cfg && editing_complete) + { + RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); + RD_Cfg *new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); + } + if(cfg != &rd_nil_cfg) + { + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("expression")); + rd_cfg_release_all_children(expr); + if(new_string.size != 0) + { + rd_cfg_new(expr, new_string); + } + } + }break; + case RD_WatchCellKind_Tag: + if(editing_complete) + { + ev_key_set_view_rule(eval_view, pt.key, new_string); + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.eval.mode == E_Mode_Offset) + { + B32 should_commit_asap = editing_complete; + if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + should_commit_asap = 1; + } + else if(evt->slot != UI_EventActionSlot_Cancel) + { + should_commit_asap = editing_complete; + } + if(should_commit_asap) + { + B32 success = 0; + success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); + if(!success) + { + log_user_error(str8_lit("Could not commit value successfully.")); + } + } + } + }break; + } #if 0 // TODO(rjf): @cfg Vec2S64 tbl = v2s64(x, y); RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); From be039496c7251202e5194931c4799988664e3511 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 09:15:13 -0800 Subject: [PATCH 062/755] rd: watch window editability progress, implicit root vis rules; eval: fix call args parser --- src/eval/eval_parse.c | 2 +- .../eval_visualization_core.c | 14 +++ src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_views.c | 107 +++++++++++------- src/raddbg/raddbg_widgets.c | 3 +- 5 files changed, 83 insertions(+), 44 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 87f57ade..3b32b756 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -2065,7 +2065,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to else { E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence); + E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs); if(arg_parse.expr != &e_expr_nil) { diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 122d14d1..fd4598a1 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -504,6 +504,12 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str // rjf: unpack expr E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); + // rjf: skip if type info disallows expansion + if(!ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) + { + continue; + } + // rjf: get expr's lookup rule E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; @@ -631,6 +637,14 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; + String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, child_key)); + E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + for(E_Expr *expr = tag_expr_parse.expr, *next = &e_expr_nil; expr != &e_expr_nil; expr = next) + { + next = expr->next; + e_expr_push_tag(child_expr, expr); + } Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index dcc76c74..a2a1ed04 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12342,6 +12342,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64u", cfg->id), expr); if(exe.size != 0) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index af967269..08b06b69 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1581,6 +1581,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, expr); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); + if(implicit_root && block_ranges.first != 0) + { + block_ranges.count -= 1; + block_ranges.first = block_ranges.first->next; + } } ////////////////////////// @@ -1669,7 +1674,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); } - cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count)); + cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); // rjf: clamp x positions of cursor/mark tbl for EachEnumVal(Axis2, axis) @@ -1761,7 +1766,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; B32 any_edits_started = 0; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); @@ -1773,7 +1778,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) continue; } RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.can_edit) + if(!ev_key_match(ev_key_root(), row->block->key) && cell_info.can_edit) { any_edits_started = 1; String8 string = cell_info.string; @@ -1876,7 +1881,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) taken = 1; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); @@ -1939,11 +1944,17 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) case RD_WatchCellKind_Expr: { RD_Cfg *cfg = row_info.group_cfg; - if(cfg == &rd_nil_cfg && editing_complete) + if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) { RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); RD_Cfg *new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + if(new_cfg_parent == &rd_nil_cfg) + { + new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + } cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); + state_dirty = 1; + snap_to_cursor = 1; } if(cfg != &rd_nil_cfg) { @@ -1959,6 +1970,16 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) if(editing_complete) { ev_key_set_view_rule(eval_view, pt.key, new_string); + RD_Cfg *cfg = row_info.group_cfg; + if(cfg != &rd_nil_cfg && new_string.size != 0) + { + RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); + rd_cfg_new(view_rule, new_string); + } + else if(cfg != &rd_nil_cfg && new_string.size == 0) + { + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("view_rule"))); + } }break; case RD_WatchCellKind_Eval: { @@ -2140,7 +2161,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) B32 next_cursor_set = 0; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { EV_Row *row = &row_node->row; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); @@ -2152,50 +2173,52 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) continue; } RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; -#if 0 // TODO(rjf): @cfg - if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && - row_info.collection_entity_kind != RD_EntityKind_Nil) + switch(cell->kind) { - RD_Entity *entity = row_info.collection_entity; - if(!rd_entity_is_nil(entity)) + default:{}break; + case RD_WatchCellKind_Expr: { - rd_entity_list_push(scratch.arena, &entities_to_remove, entity); - U64 deleted_id = row->key.child_id; - U64 deleted_num = row->block->expand_view_rule_info->expr_expand_num_from_id(deleted_id, row->block->expand_view_rule_info_user_data); - if(deleted_num != 0) + RD_Cfg *cfg = row_info.group_cfg; + if(cfg != &rd_nil_cfg) { - U64 fallback_id_next = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num+1, row->block->expand_view_rule_info_user_data); - U64 fallback_id_prev = row->block->expand_view_rule_info->expr_expand_id_from_num(deleted_num-1, row->block->expand_view_rule_info_user_data); - EV_Key parent_key = row->block->key; - EV_Key key = ev_key_make(row->key.parent_hash, fallback_id_next ? fallback_id_next : fallback_id_prev); - if(key.child_id == 0) + rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); + U64 deleted_num = ev_num_from_key(&block_ranges, row->key); + if(deleted_num != 0) { - key = row->block->key; - parent_key = row->block->parent->key; + EV_Key parent_key = row->block->parent->key; + EV_Key key = row->block->key; + EV_Key fallback_key_prev = ev_key_from_num(&block_ranges, deleted_num-1); + EV_Key fallback_key_next = ev_key_from_num(&block_ranges, deleted_num+1); + if(fallback_key_next.child_id != 0) + { + parent_key = row->block->key; + key = fallback_key_next; + } + else if(fallback_key_prev.child_id != 0) + { + parent_key = row->block->key; + key = fallback_key_prev; + } + RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; + next_cursor_pt = new_pt; + next_cursor_set = 1; } - RD_WatchPt new_pt = {parent_key, key, 0}; - next_cursor_pt = new_pt; - next_cursor_set = 1; } - } - } - else if(tbl.y != 0 && col->kind == RD_WatchViewColumnKind_ViewRule && row_kind == RD_WatchViewRowKind_Normal) - { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) + }break; + case RD_WatchCellKind_Tag: { - RD_Entity *entity = row_info.collection_entity; - RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); - rd_entity_mark_for_deletion(view_rule); - } - ev_key_set_view_rule(eval_view, row->key, str8_zero()); + if(row_info.group_cfg != &rd_nil_cfg) + { + rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg, str8_lit("view_rule"))); + } + ev_key_set_view_rule(eval_view, row->key, str8_zero()); + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); + }break; } - else if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Value || col->kind == RD_WatchViewColumnKind_Member) && row_kind == RD_WatchViewRowKind_Normal) - { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, row, col); - E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); - rd_commit_eval_value_string(dst_eval, str8_zero(), 0); - } -#endif } } for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c8e90106..8240b5d6 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1014,7 +1014,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); + rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", bp->id)); + // RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: shift+click => enable breakpoint From 43222e85112791a5c761c894341e2b14402c6022 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 09:35:19 -0800 Subject: [PATCH 063/755] tweak cfg tree mutations a bit to recycle old nodes/identities where possible --- src/raddbg/raddbg_core.c | 106 +++++++++++++++++++++++++++----------- src/raddbg/raddbg_core.h | 2 + src/raddbg/raddbg_views.c | 6 +-- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a2a1ed04..8c0b7a66 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -418,6 +418,36 @@ rd_cfg_newf(RD_Cfg *parent, char *fmt, ...) return result; } +internal RD_Cfg * +rd_cfg_new_replace(RD_Cfg *parent, String8 string) +{ + for(RD_Cfg *child = parent->first->next, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + rd_cfg_release(child); + } + if(parent->first == &rd_nil_cfg) + { + rd_cfg_new(parent, str8_zero()); + } + RD_Cfg *child = parent->first; + rd_cfg_equip_string(child, string); + return child; +} + +internal RD_Cfg * +rd_cfg_new_replacef(RD_Cfg *parent, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + RD_Cfg *result = rd_cfg_new_replace(parent, string); + va_end(args); + scratch_end(scratch); + return result; +} + internal RD_Cfg * rd_cfg_deep_copy(RD_Cfg *src_root) { @@ -471,6 +501,10 @@ rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *new_child) { if(parent != &rd_nil_cfg) { + if(new_child->parent != &rd_nil_cfg) + { + rd_cfg_unhook(new_child->parent, new_child); + } DLLInsert_NPZ(&rd_nil_cfg, parent->first, parent->last, prev_child, new_child, next, prev); new_child->parent = parent; } @@ -2119,8 +2153,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { child = rd_cfg_new(cfg, child_name); } - rd_cfg_release_all_children(child); - rd_cfg_new(child, new_string); + rd_cfg_new_replace(child, new_string); } result = 1; break; @@ -2140,8 +2173,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { child = rd_cfg_new(cfg, child_name); } - rd_cfg_release_all_children(child); - rd_cfg_newf(child, "%I64u", value); + rd_cfg_new_replacef(child, "%I64u", value); } result = 1; break; @@ -2160,8 +2192,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { child = rd_cfg_new(cfg, child_name); } - rd_cfg_release_all_children(child); - rd_cfg_newf(child, "%I64u", value); + rd_cfg_new_replacef(child, "%I64u", value); } result = 1; break; @@ -2785,8 +2816,7 @@ rd_store_view_expr_string(String8 string) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_release_all_children(expr); - rd_cfg_new(expr, string); + rd_cfg_new_replace(expr, string); } internal void @@ -2794,8 +2824,7 @@ rd_store_view_filter(String8 string) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); - rd_cfg_release_all_children(filter); - rd_cfg_new(filter, string); + rd_cfg_new_replace(filter, string); } internal void @@ -2821,8 +2850,7 @@ rd_store_view_param(String8 key, String8 value) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *child = rd_cfg_child_from_string_or_alloc(view, key); - rd_cfg_release_all_children(child); - rd_cfg_new(child, value); + rd_cfg_new_replace(child, value); } internal void @@ -5691,8 +5719,7 @@ rd_window_frame(void) RD_RegsScope(.panel = 0, .view = view->id) { RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); - rd_cfg_release_all_children(expr); - rd_cfg_new(expr, ws->hover_eval_string); + rd_cfg_new_replace(expr, ws->hover_eval_string); EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); @@ -7267,6 +7294,7 @@ rd_window_frame(void) } // rjf: apply tab change + if(next_selected_tab != panel->selected_tab) { rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); } @@ -12633,8 +12661,7 @@ rd_frame(void) for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { RD_Cfg *hit_count = rd_cfg_child_from_string_or_alloc(n->v, str8_lit("hit_count")); - rd_cfg_release_all_children(hit_count); - rd_cfg_new(hit_count, str8_lit("0")); + rd_cfg_new_replace(hit_count, str8_lit("0")); } } } // fallthrough @@ -13001,8 +13028,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); - rd_cfg_release_all_children(main_font_size); - rd_cfg_newf(main_font_size, "%f", new_font_size); + rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecUIFontScale: { @@ -13011,8 +13037,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); - rd_cfg_release_all_children(main_font_size); - rd_cfg_newf(main_font_size, "%f", new_font_size); + rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; case RD_CmdKind_IncCodeFontScale: { @@ -13021,8 +13046,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - rd_cfg_release_all_children(code_font_size); - rd_cfg_newf(code_font_size, "%f", new_font_size); + rd_cfg_new_replacef(code_font_size, "%f", new_font_size); }break; case RD_CmdKind_DecCodeFontScale: { @@ -13031,8 +13055,7 @@ rd_frame(void) F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - rd_cfg_release_all_children(code_font_size); - rd_cfg_newf(code_font_size, "%f", new_font_size); + rd_cfg_new_replacef(code_font_size, "%f", new_font_size); }break; //- rjf: panel creation @@ -13204,20 +13227,30 @@ rd_frame(void) { RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); + RD_Cfg *selection_cfg = &rd_nil_cfg; for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) { RD_Cfg *p_cfg = p->cfg; RD_Cfg *p_selection = rd_cfg_child_from_string(p_cfg, str8_lit("selected")); - if(p_selection != &rd_nil_cfg) + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = p_selection; + } + else { rd_cfg_release(p_selection); } } + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = rd_cfg_alloc(); + rd_cfg_equip_string(selection_cfg, str8_lit("selected")); + } if(panel != &rd_nil_cfg) { - rd_cfg_new(panel, str8_lit("selected")); + rd_cfg_insert_child(panel, &rd_nil_cfg, selection_cfg); RD_Cfg *window = rd_window_from_cfg(panel); RD_WindowState *ws = rd_window_state_from_cfg(window); ws->menu_bar_focused = 0; @@ -13462,11 +13495,25 @@ rd_frame(void) RD_Cfg *panel = tab->parent; RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); RD_PanelNode *panel_node = rd_panel_node_from_tree_cfg(panel_tree.root, panel); + RD_Cfg *selection_cfg = &rd_nil_cfg; for(RD_CfgNode *n = panel_node->tabs.first; n != 0; n = n->next) { - rd_cfg_release(rd_cfg_child_from_string(n->v, str8_lit("selected"))); + RD_Cfg *tab_selection_cfg = rd_cfg_child_from_string(n->v, str8_lit("selected")); + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = tab_selection_cfg; + } + else + { + rd_cfg_release(tab_selection_cfg); + } } - rd_cfg_new(tab, str8_lit("selected")); + if(selection_cfg == &rd_nil_cfg) + { + selection_cfg = rd_cfg_alloc(); + rd_cfg_equip_string(selection_cfg, str8_lit("selected")); + } + rd_cfg_insert_child(tab, &rd_nil_cfg, selection_cfg); }break; case RD_CmdKind_NextTab: { @@ -15947,8 +15994,7 @@ Z(getting_started) hit_count += 1; } } - rd_cfg_release_all_children(hit_count_root); - rd_cfg_newf(hit_count_root, "%I64u", hit_count); + rd_cfg_new_replacef(hit_count_root, "%I64u", hit_count); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index d9fc5fe6..21209c55 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -967,6 +967,8 @@ internal void rd_cfg_release_all_children(RD_Cfg *cfg); internal RD_Cfg *rd_cfg_from_id(RD_CfgID id); internal RD_Cfg *rd_cfg_new(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_newf(RD_Cfg *parent, char *fmt, ...); +internal RD_Cfg *rd_cfg_new_replace(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_new_replacef(RD_Cfg *parent, char *fmt, ...); internal RD_Cfg *rd_cfg_deep_copy(RD_Cfg *src_root); internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string); internal void rd_cfg_equip_stringf(RD_Cfg *cfg, char *fmt, ...); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 08b06b69..50a1ef2e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1959,11 +1959,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) if(cfg != &rd_nil_cfg) { RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("expression")); - rd_cfg_release_all_children(expr); - if(new_string.size != 0) - { - rd_cfg_new(expr, new_string); - } + rd_cfg_new_replace(expr, new_string); } }break; case RD_WatchCellKind_Tag: From 295778f1caca6d4c3f429a78161ecbf308a5cb5b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 11:17:42 -0800 Subject: [PATCH 064/755] eval: prohibit identifier overrides in macro maps; raddbg: correctly mark dirty state & recompute given watch window mutations; do not escape unquoted value eval strings --- src/eval/eval_parse.c | 2 +- src/raddbg/raddbg_core.c | 6 +++++- src/raddbg/raddbg_views.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 3b32b756..daccd7f7 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -152,8 +152,8 @@ e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_ SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); node->string = push_str8_copy(arena, string); existing_node = node; + existing_node->expr = expr; } - existing_node->expr = expr; } internal void diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8c0b7a66..35ec78c2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8845,7 +8845,11 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); + String8 string_escaped = string; + if(!no_addr || depth > 0) + { + string_escaped = ev_escaped_from_raw_string(arena, string); + } space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; if(!no_addr || depth > 0) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 50a1ef2e..a7b03028 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2198,6 +2198,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; next_cursor_pt = new_pt; next_cursor_set = 1; + state_dirty = 1; } } }break; @@ -2208,6 +2209,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg, str8_lit("view_rule"))); } ev_key_set_view_rule(eval_view, row->key, str8_zero()); + state_dirty = 1; }break; case RD_WatchCellKind_Eval: { From eaa65a6b3d1f3c885bd43d3daee87e59634e0867 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 11:26:02 -0800 Subject: [PATCH 065/755] raddbg: cast basic type value commits to destination type; ensures numeric things are casted appropriately (fixes f32/f64 value writes) --- src/raddbg/raddbg_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 35ec78c2..2efb03a5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2341,7 +2341,9 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un if((E_TypeKind_FirstBasic <= type_kind && type_kind <= E_TypeKind_LastBasic) || type_kind == E_TypeKind_Enum) { - E_Eval src_eval = e_eval_from_string(scratch.arena, string); + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string); + E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); + E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } From d1541d3989d094210b8d6b3df075fe45f766785f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 11:36:56 -0800 Subject: [PATCH 066/755] fix handling of root-expr editing in watch views; eliminate dead code --- src/raddbg/raddbg_views.c | 97 ++++----------------------------------- 1 file changed, 9 insertions(+), 88 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a7b03028..71d6dfbf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1117,7 +1117,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // expression tree. case RD_WatchCellKind_Expr: { - if(row->string.size != 0 || row->expr == &e_expr_nil) + if(!ev_key_match(ev_key_root(), row->block->key) && (row->string.size != 0 || row->expr == &e_expr_nil)) { result.can_edit = 1; } @@ -1778,7 +1778,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) continue; } RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(!ev_key_match(ev_key_root(), row->block->key) && cell_info.can_edit) + if(cell_info.can_edit) { any_edits_started = 1; String8 string = cell_info.string; @@ -2003,92 +2003,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) } }break; } -#if 0 // TODO(rjf): @cfg - Vec2S64 tbl = v2s64(x, y); - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - { - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - if(modifiable) - { - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - if(!rd_entity_is_nil(entity) || editing_complete) - { - if(rd_entity_is_nil(entity) && new_string.size != 0) - { - entity = rd_entity_alloc(rd_entity_root(), row_info.collection_entity_kind); - rd_entity_equip_cfg_src(entity, RD_CfgSrc_Project); - } - if(!rd_entity_is_nil(entity)) - { - rd_entity_equip_name(entity, new_string); - } - state_dirty = 1; - snap_to_cursor = 1; - } - } - }break; - case RD_WatchViewColumnKind_Member: - case RD_WatchViewColumnKind_Value: - { - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(y, y+1)); - if(rows.first != 0) - { - B32 should_commit_asap = editing_complete; - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, row, col); - E_Eval dst_eval = e_eval_from_expr(scratch.arena, expr); - if(dst_eval.space.kind == RD_EvalSpaceKind_MetaEntity) - { - should_commit_asap = 1; - } - else if(evt->slot != UI_EventActionSlot_Cancel) - { - should_commit_asap = editing_complete; - } - if(should_commit_asap) - { - B32 success = 0; - success = rd_commit_eval_value_string(dst_eval, new_string, !col->dequote_string); - if(!success) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } - } - } - }break; - case RD_WatchViewColumnKind_Type:{}break; - case RD_WatchViewColumnKind_ViewRule: - if(editing_complete) - { - RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); - ev_key_set_view_rule(eval_view, pt.key, new_string); - if(row_info.collection_entity_kind != RD_EntityKind_Nil) - { - RD_Entity *entity = row_info.collection_entity; - RD_Entity *view_rule = rd_entity_child_from_kind(entity, RD_EntityKind_ViewRule); - if(rd_entity_is_nil(view_rule) && new_string.size != 0) - { - view_rule = rd_entity_alloc(entity, RD_EntityKind_ViewRule); - } - else if(!rd_entity_is_nil(view_rule) && new_string.size == 0) - { - rd_entity_mark_for_deletion(view_rule); - } - if(new_string.size != 0) - { - rd_entity_equip_name(view_rule, new_string); - } - state_dirty = 1; - snap_to_cursor = 1; - } - }break; - } - } -#endif } } } @@ -2777,6 +2691,13 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) .inline_depth = row_info.callstack_inline_depth); } + // rjf: can edit? -> begin editing + else if(cell_info.can_edit) + { + rd_cmd(RD_CmdKind_Edit); + } + + #if 0 // TODO(rjf): @cfg // rjf: can edit? -> begin editing else if(cell_can_edit) From 7bc1dd736294d1163c590b159fd7f5640a590207 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 12:14:12 -0800 Subject: [PATCH 067/755] eliminate old eval vis view rule paths; sketch out view-rule-lookup & expr-tag-equipping, & expr tag (view rule) inheritance --- .../eval_visualization.mdesk | 19 --- .../eval_visualization_builtin_view_rules.c | 2 +- .../eval_visualization_core.c | 161 +++++++++--------- .../eval_visualization_core.h | 72 ++++---- .../generated/eval_visualization.meta.c | 21 --- .../generated/eval_visualization.meta.h | 20 --- src/raddbg/generated/raddbg.meta.c | 26 +-- src/raddbg/generated/raddbg.meta.h | 14 +- src/raddbg/raddbg.mdesk | 8 +- src/raddbg/raddbg_core.c | 13 +- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 14 +- 12 files changed, 152 insertions(+), 220 deletions(-) diff --git a/src/eval_visualization/eval_visualization.mdesk b/src/eval_visualization/eval_visualization.mdesk index 416018f1..493c64a0 100644 --- a/src/eval_visualization/eval_visualization.mdesk +++ b/src/eval_visualization/eval_visualization.mdesk @@ -105,22 +105,3 @@ EV_ViewRuleTable: {x Hex hex "hex" x - - - "Display In Hexadecimal" x "" "Specifies that all numeric values should be shown in base 16 (hexadecimal)." } {x NoAddress no_addr "no_addr" x - - - "Omit Addresses" x "" "Specifies that addresses should be omitted from visualizations, if possible." } } - -@enum EV_ViewRuleKind: -{ - EV_ViewRuleKind_Null, - @expand(EV_ViewRuleTable a) `$(a.name)`, - COUNT, -} - -@gen -{ - @expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`; -} - -@data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table: -{ - `{0}`, - @expand(EV_ViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") }```; -} diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index 4618f35f..edd26587 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -99,7 +99,7 @@ ev_arch_from_eval_params(E_Eval eval, MD_Node *params) //////////////////////////////// //~ rjf: "list" -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(list) { EV_ExpandInfo info = {0}; return info; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index fd4598a1..24cb099d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -9,7 +9,7 @@ //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(nil) { EV_ExpandInfo info = {0}; return info; @@ -317,56 +317,50 @@ ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_string) //~ rjf: View Rule Info Table Building / Selection / Lookups internal void -ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info) +ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info) { if(table->slots_count == 0) { table->slots_count = 512; - table->slots = push_array(arena, EV_ViewRuleInfoSlot, table->slots_count); + table->slots = push_array(arena, EV_ExpandRuleSlot, table->slots_count); } U64 hash = ev_hash_from_seed_string(5381, info->string); U64 slot_idx = hash%table->slots_count; - EV_ViewRuleInfoSlot *slot = &table->slots[slot_idx]; - EV_ViewRuleInfoNode *n = push_array(arena, EV_ViewRuleInfoNode, 1); + EV_ExpandRuleSlot *slot = &table->slots[slot_idx]; + EV_ExpandRuleNode *n = push_array(arena, EV_ExpandRuleNode, 1); SLLQueuePush(slot->first, slot->last, n); MemoryCopyStruct(&n->v, info); n->v.string = push_str8_copy(arena, n->v.string); } internal void -ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table) -{ - for EachNonZeroEnumVal(EV_ViewRuleKind, kind) - { - ev_view_rule_info_table_push(arena, table, &ev_builtin_view_rule_info_table[kind]); - } -} - -internal void -ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table) +ev_select_expand_rule_table(EV_ExpandRuleTable *table) { ev_view_rule_info_table = table; } -internal EV_ViewRuleInfo * -ev_view_rule_info_from_string(String8 string) +internal EV_ExpandRule * +ev_expand_rule_from_string(String8 string) { - EV_ViewRuleInfo *info = &ev_nil_view_rule_info; - U64 hash = ev_hash_from_seed_string(5381, string); - U64 slot_idx = hash%ev_view_rule_info_table->slots_count; - EV_ViewRuleInfoSlot *slot = &ev_view_rule_info_table->slots[slot_idx]; - EV_ViewRuleInfoNode *node = 0; - for(EV_ViewRuleInfoNode *n = slot->first; n != 0; n = n->next) + EV_ExpandRule *info = &ev_nil_expand_rule; + if(ev_view_rule_info_table != 0 && ev_view_rule_info_table->slots_count != 0) { - if(str8_match(n->v.string, string, 0)) + U64 hash = ev_hash_from_seed_string(5381, string); + U64 slot_idx = hash%ev_view_rule_info_table->slots_count; + EV_ExpandRuleSlot *slot = &ev_view_rule_info_table->slots[slot_idx]; + EV_ExpandRuleNode *node = 0; + for(EV_ExpandRuleNode *n = slot->first; n != 0; n = n->next) { - node = n; - break; + if(str8_match(n->v.string, string, 0)) + { + node = n; + break; + } + } + if(node != 0) + { + info = &node->v; } - } - if(node != 0) - { - info = &node->v; } return info; } @@ -446,24 +440,55 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) } #endif +//////////////////////////////// +//~ rjf: Upgrading Expressions w/ Tags From All Sources + +internal void +ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); + E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + for(E_Expr *tag = tag_expr_parse.expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + { + next = tag->next; + e_expr_push_tag(expr, tag); + } + for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) + { + for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + { + e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + } + } + scratch_end(scratch); +} + //////////////////////////////// //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr) +ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; { Temp scratch = scratch_begin(&arena, 1); - EV_ViewRuleInfo *default_expand_view_rule_info = ev_view_rule_info_from_string(str8_lit("default")); + + //- rjf: produce root expression + EV_Key root_key = ev_key_root(); + E_TokenArray root_tokens = e_token_array_from_text(scratch.arena, string); + E_Parse root_parse = e_parse_expr_from_text_tokens(arena, string, &root_tokens); + E_Expr *root_expr = root_parse.expr; + ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_key, root_expr); //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); - tree.root->key = ev_key_root(); + tree.root->key = root_key; tree.root->string = string; - tree.root->expr = expr; + tree.root->expr = root_expr; tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -517,16 +542,16 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str // rjf: get expr's expansion rule EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ViewRuleInfo *expand_rule = expand_rule_and_tag.rule; + EV_ExpandRule *expand_rule = expand_rule_and_tag.rule; E_Expr *expand_rule_tag = expand_rule_and_tag.tag; // rjf: get top-level lookup/expansion info E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, filter); - EV_ExpandInfo expand_info = expand_rule->expr_expand_info(arena, view, filter, t->expr, expand_rule_tag); + EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); // rjf: determine expansion info U64 expansion_row_count = lookup_info.named_expr_count ? lookup_info.named_expr_count : lookup_info.idxed_expr_count; - if(expand_rule != &ev_nil_view_rule_info) + if(expand_rule != &ev_nil_expand_rule) { expansion_row_count = expand_info.row_count; } @@ -637,14 +662,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; - String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, child_key)); - E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); - for(E_Expr *expr = tag_expr_parse.expr, *next = &e_expr_nil; expr != &e_expr_nil; expr = next) - { - next = expr->next; - e_expr_push_tag(child_expr, expr); - } + ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; @@ -662,21 +680,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 str return tree; } -internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string) -{ - ProfBeginFunction(); - EV_BlockTree tree = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_Parse parse = e_parse_expr_from_text__cached(string); - tree = ev_block_tree_from_expr(arena, view, filter, string, parse.expr); - } - scratch_end(scratch); - ProfEnd(); - return tree; -} - internal U64 ev_depth_from_block(EV_Block *block) { @@ -971,6 +974,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 U64 child_id = n->v.block->lookup_rule->id_from_num(child_num, n->v.block->lookup_rule_user_data); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; + ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1059,28 +1063,26 @@ ev_row_is_expandable(EV_Row *row) { B32 result = 0; { + Temp scratch = scratch_begin(0, 0); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); + // rjf: determine if view rules force expandability if(!result) { - for(E_Expr *tag = row->expr->first_tag; tag != &e_expr_nil; tag = tag->next) + EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(row->expr, &irtree); + if(expand_rule_and_tag.rule != &ev_nil_expand_rule) { - EV_ViewRuleInfo *info = ev_view_rule_info_from_string(tag->string); - if(info->flags & EV_ViewRuleInfoFlag_Expandable) - { - result = 1; - break; - } + result = 1; } } // rjf: determine if type info force expandability if(!result) { - Temp scratch = scratch_begin(0, 0); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); - scratch_end(scratch); } + scratch_end(scratch); } return result; } @@ -1501,16 +1503,15 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { - EV_ViewRuleInfo *default_expand_view_rule = ev_view_rule_info_from_string(str8_lit("default")); - EV_ExpandRuleTagPair result = {default_expand_view_rule, &e_expr_nil}; + EV_ExpandRuleTagPair result = {&ev_nil_expand_rule, &e_expr_nil}; { // rjf: first try explicitly-stored tags - if(result.rule == default_expand_view_rule) + if(result.rule == &ev_nil_expand_rule) { for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(tag->string); - if(candidate != &ev_nil_view_rule_info) + EV_ExpandRule *candidate = ev_expand_rule_from_string(tag->string); + if(candidate != &ev_nil_expand_rule) { result.rule = candidate; result.tag = tag; @@ -1520,15 +1521,15 @@ ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } // rjf: next try implicit set name -> rule mapping - if(result.rule == default_expand_view_rule) + if(result.rule == &ev_nil_expand_rule) { E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); if(type_kind == E_TypeKind_Set) { E_Type *type = e_type_from_key__cached(irtree->type_key); String8 name = type->name; - EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(name); - if(candidate != &ev_nil_view_rule_info) + EV_ExpandRule *candidate = ev_expand_rule_from_string(name); + if(candidate != &ev_nil_expand_rule) { result.rule = candidate; } @@ -1536,13 +1537,13 @@ ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } // rjf: next try auto hook map - if(result.rule == default_expand_view_rule) + if(result.rule == &ev_nil_expand_rule) { E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) { - EV_ViewRuleInfo *candidate = ev_view_rule_info_from_string(n->v->string); - if(candidate != &ev_nil_view_rule_info) + EV_ExpandRule *candidate = ev_expand_rule_from_string(n->v->string); + if(candidate != &ev_nil_expand_rule) { result.rule = candidate; result.tag = n->v; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 0747f963..b9651404 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -87,44 +87,36 @@ struct EV_ExpandInfo B32 rows_default_expanded; }; -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name -#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name)) -typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType); +#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) +#define EV_EXPAND_RULE_INFO_FUNCTION_NAME(name) ev_expand_rule_info__##name +#define EV_EXPAND_RULE_INFO_FUNCTION_DEF(name) internal EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_EXPAND_RULE_INFO_FUNCTION_NAME(name)) +typedef EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_ExpandRuleInfoHookFunctionType); -typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info -enum -{ - EV_ViewRuleInfoFlag_Inherited = (1<<0), - EV_ViewRuleInfoFlag_Expandable = (1<<1), -}; - -typedef struct EV_ViewRuleInfo EV_ViewRuleInfo; -struct EV_ViewRuleInfo +typedef struct EV_ExpandRule EV_ExpandRule; +struct EV_ExpandRule { String8 string; - EV_ViewRuleInfoFlags flags; - EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; + EV_ExpandRuleInfoHookFunctionType *info; }; -typedef struct EV_ViewRuleInfoNode EV_ViewRuleInfoNode; -struct EV_ViewRuleInfoNode +typedef struct EV_ExpandRuleNode EV_ExpandRuleNode; +struct EV_ExpandRuleNode { - EV_ViewRuleInfoNode *next; - EV_ViewRuleInfo v; + EV_ExpandRuleNode *next; + EV_ExpandRule v; }; -typedef struct EV_ViewRuleInfoSlot EV_ViewRuleInfoSlot; -struct EV_ViewRuleInfoSlot +typedef struct EV_ExpandRuleSlot EV_ExpandRuleSlot; +struct EV_ExpandRuleSlot { - EV_ViewRuleInfoNode *first; - EV_ViewRuleInfoNode *last; + EV_ExpandRuleNode *first; + EV_ExpandRuleNode *last; }; -typedef struct EV_ViewRuleInfoTable EV_ViewRuleInfoTable; -struct EV_ViewRuleInfoTable +typedef struct EV_ExpandRuleTable EV_ExpandRuleTable; +struct EV_ExpandRuleTable { - EV_ViewRuleInfoSlot *slots; + EV_ExpandRuleSlot *slots; U64 slots_count; }; @@ -134,7 +126,7 @@ struct EV_ViewRuleInfoTable typedef struct EV_ExpandRuleTagPair EV_ExpandRuleTagPair; struct EV_ExpandRuleTagPair { - EV_ViewRuleInfo *rule; + EV_ExpandRule *rule; E_Expr *tag; }; @@ -163,7 +155,7 @@ struct EV_Block E_Expr *lookup_tag; E_Expr *expand_tag; E_LookupRule *lookup_rule; - EV_ViewRuleInfo *expand_rule; + EV_ExpandRule *expand_rule; void *lookup_rule_user_data; void *expand_rule_user_data; @@ -280,20 +272,19 @@ enum //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(nil); //////////////////////////////// //~ rjf: Globals -global read_only EV_ViewRuleInfo ev_nil_view_rule_info = +global read_only EV_ExpandRule ev_nil_expand_rule = { {0}, - 0, - EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), + EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; -thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0; +thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_view_rule_info}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_expand_rule}; //////////////////////////////// //~ rjf: Key Functions @@ -329,10 +320,9 @@ internal void ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_ //////////////////////////////// //~ rjf: View Rule Info Table Building / Selection / Lookups -internal void ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info); -internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table); -internal void ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table); -internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); +internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info); +internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); +internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) @@ -341,10 +331,14 @@ internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); #endif +//////////////////////////////// +//~ rjf: Upgrading Expressions w/ Tags From All Sources + +internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr); + //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr); internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string); internal U64 ev_depth_from_block(EV_Block *block); diff --git a/src/eval_visualization/generated/eval_visualization.meta.c b/src/eval_visualization/generated/eval_visualization.meta.c index 30964f74..3d32a4c2 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.c +++ b/src/eval_visualization/generated/eval_visualization.meta.c @@ -3,24 +3,3 @@ //- GENERATED CODE -C_LINKAGE_BEGIN -EV_ViewRuleInfo ev_builtin_view_rule_info_table[14] = -{ -{0}, -{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) }, -{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), }, -}; - -C_LINKAGE_END - diff --git a/src/eval_visualization/generated/eval_visualization.meta.h b/src/eval_visualization/generated/eval_visualization.meta.h index 5625eefd..efcc2c2a 100644 --- a/src/eval_visualization/generated/eval_visualization.meta.h +++ b/src/eval_visualization/generated/eval_visualization.meta.h @@ -6,24 +6,4 @@ #ifndef EVAL_VISUALIZATION_META_H #define EVAL_VISUALIZATION_META_H -typedef enum EV_ViewRuleKind -{ -EV_ViewRuleKind_EV_ViewRuleKind_Null, -EV_ViewRuleKind_Array, -EV_ViewRuleKind_List, -EV_ViewRuleKind_Slice, -EV_ViewRuleKind_ByteSwap, -EV_ViewRuleKind_Cast, -EV_ViewRuleKind_Wrap, -EV_ViewRuleKind_Only, -EV_ViewRuleKind_Omit, -EV_ViewRuleKind_Bin, -EV_ViewRuleKind_Oct, -EV_ViewRuleKind_Dec, -EV_ViewRuleKind_Hex, -EV_ViewRuleKind_NoAddress, -EV_ViewRuleKind_COUNT, -} EV_ViewRuleKind; - -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list); #endif // EVAL_VISUALIZATION_META_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f3cb056f..39bfee08 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -719,19 +719,19 @@ str8_lit_comp("c"), RD_ViewRuleInfo rd_view_rule_kind_info_table[13] = { -{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, -{str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, -{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(getting_started)}, -{str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, -{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, -{str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, -{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, -{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, -{str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, -{str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, -{str8_lit_comp("checkbox"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Checkbox"), str8_lit_comp(""), RD_IconKind_CheckFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*0), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(checkbox)}, -{str8_lit_comp("color_rgba"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), RD_IconKind_Palette, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(color_rgba) , RD_VIEW_RULE_UI_FUNCTION_NAME(color_rgba)}, -{str8_lit_comp("geo3d"), str8_lit_comp("Visualizes memory as 3D geometry."), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(geo3d) , RD_VIEW_RULE_UI_FUNCTION_NAME(geo3d)}, +{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, +{str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, +{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(getting_started)}, +{str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, +{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, +{str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, +{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, +{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, +{str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, +{str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, +{str8_lit_comp("checkbox"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Checkbox"), str8_lit_comp(""), RD_IconKind_CheckFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(checkbox)}, +{str8_lit_comp("color_rgba"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), RD_IconKind_Palette, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba) , RD_VIEW_RULE_UI_FUNCTION_NAME(color_rgba)}, +{str8_lit_comp("geo3d"), str8_lit_comp("Visualizes memory as 3D geometry."), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d) , RD_VIEW_RULE_UI_FUNCTION_NAME(geo3d)}, }; RD_IconKind rd_entity_kind_icon_kind_table[27] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 2beda79f..ad295fe4 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -587,7 +587,7 @@ String8 display_name; String8 params_schema; RD_IconKind icon_kind; RD_ViewRuleInfoFlags flags; -EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info; +EV_ExpandRuleInfoHookFunctionType *expr_expand_info; RD_ViewRuleUIFunctionType *ui; }; @@ -631,12 +631,12 @@ RD_ViewRuleUIFunctionType *ui; .os_event = rd_regs()->os_event,\ RD_VIEW_RULE_UI_FUNCTION_DEF(null); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(memory); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(bitmap); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba); -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); RD_VIEW_RULE_UI_FUNCTION_DEF(empty); RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); RD_VIEW_RULE_UI_FUNCTION_DEF(settings); diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 2c8359dd..b539fbec 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1057,21 +1057,21 @@ RD_ViewRuleTable: `String8 params_schema`; `RD_IconKind icon_kind`; `RD_ViewRuleInfoFlags flags`; - `EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info`; + `EV_ExpandRuleInfoHookFunctionType *expr_expand_info`; `RD_ViewRuleUIFunctionType *ui`; } @gen { `RD_VIEW_RULE_UI_FUNCTION_DEF(null);`, - @expand(RD_ViewRuleTable a) `$(a.can_use_in_watch_table != 0 && a.can_expand != 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`, + @expand(RD_ViewRuleTable a) `$(a.can_use_in_watch_table != 0 && a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`, @expand(RD_ViewRuleTable a) `RD_VIEW_RULE_UI_FUNCTION_DEF($(a.name_lower));`, } @data(RD_ViewRuleInfo) rd_view_rule_kind_info_table: { - `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, - @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, + `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, + @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, } //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2efb03a5..4ae3f566 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8008,7 +8008,7 @@ struct RD_EntityExpandAccel //- rjf: control entity hierarchies -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_machine) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_machine) { EV_ExpandInfo info = {0}; Temp scratch = scratch_begin(&arena, 1); @@ -8072,7 +8072,7 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine) return id; } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(scheduler_process) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_process) { EV_ExpandInfo info = {0}; Temp scratch = scratch_begin(&arena, 1); @@ -12572,13 +12572,10 @@ rd_frame(void) e_select_interpret_ctx(interpret_ctx); //////////////////////////// - //- rjf: build eval visualization view rule table + //- rjf: build eval visualization expand rule table // - 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); - } - ev_select_view_rule_info_table(view_rule_info_table); + EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); + ev_select_expand_rule_table(expand_rule_table); //////////////////////////// //- rjf: build eval visualization auto-view-rule table diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 21209c55..44ca4ca1 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -892,7 +892,7 @@ read_only global RD_ViewRuleInfo rd_nil_view_rule_info = {0}, RD_IconKind_Null, 0, - EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), + EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null) }; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 71d6dfbf..ba7cd8ce 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -4303,7 +4303,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) //////////////////////////////// //~ rjf: text @view_hook_impl -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(text) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(text) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -4558,7 +4558,7 @@ struct RD_DisasmViewState RD_CodeViewState cv; }; -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(disasm) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -4783,7 +4783,7 @@ struct RD_MemoryViewState B32 contain_cursor; }; -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(memory) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory) { EV_ExpandInfo info = {0}; info.row_count = 16; @@ -5618,7 +5618,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) //////////////////////////////// //~ rjf: "graph" -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(graph) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(graph) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -5710,7 +5710,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) } } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(bitmap) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -5958,7 +5958,7 @@ rd_rgba_from_eval_params(E_Eval eval, MD_Node *params) return rgba; } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(color_rgba) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -6119,7 +6119,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_geo3d_box_draw) dr_mesh(draw_data->vertex_buffer, draw_data->index_buffer, R_GeoTopologyKind_Triangles, R_GeoVertexFlag_TexCoord|R_GeoVertexFlag_Normals|R_GeoVertexFlag_RGB, r_handle_zero(), mat_4x4f32(1.f)); } -EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(geo3d) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d) { EV_ExpandInfo info = {0}; info.row_count = 16; From 712162af4a0ba5a53d0f62409dcdf0e53176857b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 12:32:09 -0800 Subject: [PATCH 068/755] correctly apply root view rules; apply inherited view rule tags first, since we apply all view rules in order, and we want explicitly-stored tags (nearest to the expression) to be strongest --- .../eval_visualization_core.c | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 24cb099d..abd2146f 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -447,6 +447,18 @@ internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) { Temp scratch = scratch_begin(&arena, 1); + + // rjf: push inherited tags first (we want these to be found first, since tags are applied + // in order, and explicit ones should always be strongest) + for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) + { + for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + { + e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + } + } + + // rjf: push explicitly-attached tags (via key) next String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); @@ -455,13 +467,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key next = tag->next; e_expr_push_tag(expr, tag); } - for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) - { - for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) - { - e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); - } - } + scratch_end(scratch); } @@ -478,10 +484,11 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s //- rjf: produce root expression EV_Key root_key = ev_key_root(); + EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); E_TokenArray root_tokens = e_token_array_from_text(scratch.arena, string); E_Parse root_parse = e_parse_expr_from_text_tokens(arena, string, &root_tokens); E_Expr *root_expr = root_parse.expr; - ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_key, root_expr); + ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); From e88f2e2e821cc9cc022047cbbd3442d1a6fe0a68 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 6 Feb 2025 12:51:59 -0800 Subject: [PATCH 069/755] eliminate old entity tables --- .../eval_visualization_core.c | 35 +- src/raddbg/generated/raddbg.meta.c | 610 ++++++------------ src/raddbg/generated/raddbg.meta.h | 39 -- src/raddbg/raddbg.mdesk | 133 +--- src/raddbg/raddbg_core.h | 43 -- 5 files changed, 244 insertions(+), 616 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index abd2146f..e131bf31 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -447,27 +447,28 @@ internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) { Temp scratch = scratch_begin(&arena, 1); - - // rjf: push inherited tags first (we want these to be found first, since tags are applied - // in order, and explicit ones should always be strongest) - for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) + if(expr != &e_expr_nil) { - for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + // rjf: push inherited tags first (we want these to be found first, since tags are applied + // in order, and explicit ones should always be strongest) + for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) { - e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + { + e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + } + } + + // rjf: push explicitly-attached tags (via key) next + String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); + E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + for(E_Expr *tag = tag_expr_parse.expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + { + next = tag->next; + e_expr_push_tag(expr, tag); } } - - // rjf: push explicitly-attached tags (via key) next - String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); - E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) - { - next = tag->next; - e_expr_push_tag(expr, tag); - } - scratch_end(scratch); } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 39bfee08..7d2b7370 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -91,161 +91,6 @@ RD_NameSchemaInfo rd_name_schema_info_table[10] = {str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, }; -String8 d_entity_kind_display_string_table[27] = -{ -str8_lit_comp("Nil"), -str8_lit_comp("Root"), -str8_lit_comp("Auto View Rule"), -str8_lit_comp("File Path Map"), -str8_lit_comp("Watch Pin"), -str8_lit_comp("Watch"), -str8_lit_comp("View Rule"), -str8_lit_comp("Breakpoint"), -str8_lit_comp("Condition"), -str8_lit_comp("Location"), -str8_lit_comp("Target"), -str8_lit_comp("Executable"), -str8_lit_comp("Arguments"), -str8_lit_comp("Working Directory"), -str8_lit_comp("Entry Point"), -str8_lit_comp("Standard Output Path"), -str8_lit_comp("Standard Error Path"), -str8_lit_comp("Standard Input Path"), -str8_lit_comp("Window"), -str8_lit_comp("Panel"), -str8_lit_comp("View"), -str8_lit_comp("Recent Project"), -str8_lit_comp("Recent File"), -str8_lit_comp("Source"), -str8_lit_comp("Destination"), -str8_lit_comp("Conversion Task"), -str8_lit_comp("Conversion Failure"), -}; - -String8 d_entity_kind_name_lower_table[27] = -{ -str8_lit_comp("nil"), -str8_lit_comp("root"), -str8_lit_comp("auto_view_rule"), -str8_lit_comp("file_path_map"), -str8_lit_comp("watch_pin"), -str8_lit_comp("watch"), -str8_lit_comp("view_rule"), -str8_lit_comp("breakpoint"), -str8_lit_comp("condition"), -str8_lit_comp("location"), -str8_lit_comp("target"), -str8_lit_comp("executable"), -str8_lit_comp("arguments"), -str8_lit_comp("working_directory"), -str8_lit_comp("entry_point"), -str8_lit_comp("stdout_path"), -str8_lit_comp("stderr_path"), -str8_lit_comp("stdin_path"), -str8_lit_comp("window"), -str8_lit_comp("panel"), -str8_lit_comp("view"), -str8_lit_comp("recent_project"), -str8_lit_comp("recent_file"), -str8_lit_comp("source"), -str8_lit_comp("dest"), -str8_lit_comp("conversion_task"), -str8_lit_comp("conversion_fail"), -}; - -String8 d_entity_kind_name_lower_plural_table[27] = -{ -str8_lit_comp("nils"), -str8_lit_comp("roots"), -str8_lit_comp("auto_view_rules"), -str8_lit_comp("file_path_maps"), -str8_lit_comp("watch_pins"), -str8_lit_comp("watches"), -str8_lit_comp("view_rules"), -str8_lit_comp("breakpoints"), -str8_lit_comp("conditions"), -str8_lit_comp("locations"), -str8_lit_comp("targets"), -str8_lit_comp("executables"), -str8_lit_comp("argumentses"), -str8_lit_comp("working_directories"), -str8_lit_comp("entry_points"), -str8_lit_comp("stdout_paths"), -str8_lit_comp("stderr_paths"), -str8_lit_comp("stdin_paths"), -str8_lit_comp("windows"), -str8_lit_comp("panels"), -str8_lit_comp("views"), -str8_lit_comp("recent_projects"), -str8_lit_comp("recent_files"), -str8_lit_comp("sources"), -str8_lit_comp("dests"), -str8_lit_comp("conversion_tasks"), -str8_lit_comp("conversion_fails"), -}; - -String8 d_entity_kind_name_label_table[27] = -{ -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Expression"), -str8_lit_comp("Expression"), -str8_lit_comp("Expression"), -str8_lit_comp("Label"), -str8_lit_comp("Expression"), -str8_lit_comp("Location"), -str8_lit_comp("Label"), -str8_lit_comp("Executable"), -str8_lit_comp("Arguments"), -str8_lit_comp("Path"), -str8_lit_comp("Symbol Name"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Path"), -str8_lit_comp("Label"), -str8_lit_comp("Label"), -}; - -RD_EntityKindFlags rd_entity_kind_flags_table[27] = -{ -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (1*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (1*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (1*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (1*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(1*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (1*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (1*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (1*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (1*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (0*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -(0*RD_EntityKindFlag_CanDelete) | (0*RD_EntityKindFlag_CanFreeze) | (0*RD_EntityKindFlag_CanEdit) | (1*RD_EntityKindFlag_CanRename) | (0*RD_EntityKindFlag_CanEnable) | (0*RD_EntityKindFlag_CanCondition) | (0*RD_EntityKindFlag_CanDuplicate) | (0*RD_EntityKindFlag_NameIsCode) | (0*RD_EntityKindFlag_NameIsPath) | (0*RD_EntityKindFlag_UserDefinedLifetime) | (0*RD_EntityKindFlag_IsSerializedToConfig), -}; - Rng1U64 rd_reg_slot_range_table[38] = { {0}, @@ -291,218 +136,218 @@ Rng1U64 rd_reg_slot_range_table[38] = RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_RecentFile, CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), str8_lit_comp("Show File In Explorer"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_RecentProject, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects an entity, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips an entity with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Breakpoint, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), RD_EntityKind_Target, CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), RD_EntityKind_Nil, CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), str8_lit_comp("Show File In Explorer"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, }; RD_StringBindingPair rd_default_binding_table[111] = @@ -734,37 +579,6 @@ RD_ViewRuleInfo rd_view_rule_kind_info_table[13] = {str8_lit_comp("geo3d"), str8_lit_comp("Visualizes memory as 3D geometry."), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d) , RD_VIEW_RULE_UI_FUNCTION_NAME(geo3d)}, }; -RD_IconKind rd_entity_kind_icon_kind_table[27] = -{ -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Binoculars, -RD_IconKind_FileOutline, -RD_IconKind_Pin, -RD_IconKind_Binoculars, -RD_IconKind_Binoculars, -RD_IconKind_CircleFilled, -RD_IconKind_CircleFilled, -RD_IconKind_Null, -RD_IconKind_Target, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Window, -RD_IconKind_XSplit, -RD_IconKind_Null, -RD_IconKind_Briefcase, -RD_IconKind_FileOutline, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -RD_IconKind_Null, -}; - String8 rd_theme_preset_display_string_table[9] = { str8_lit_comp("Default (Dark)"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index ad295fe4..21abb11c 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -15,38 +15,6 @@ RD_CfgSrc_Transient, RD_CfgSrc_COUNT, } RD_CfgSrc; -typedef enum RD_EntityKind -{ -RD_EntityKind_Nil, -RD_EntityKind_Root, -RD_EntityKind_AutoViewRule, -RD_EntityKind_FilePathMap, -RD_EntityKind_WatchPin, -RD_EntityKind_Watch, -RD_EntityKind_ViewRule, -RD_EntityKind_Breakpoint, -RD_EntityKind_Condition, -RD_EntityKind_Location, -RD_EntityKind_Target, -RD_EntityKind_Executable, -RD_EntityKind_Arguments, -RD_EntityKind_WorkingDirectory, -RD_EntityKind_EntryPoint, -RD_EntityKind_StdoutPath, -RD_EntityKind_StderrPath, -RD_EntityKind_StdinPath, -RD_EntityKind_Window, -RD_EntityKind_Panel, -RD_EntityKind_View, -RD_EntityKind_RecentProject, -RD_EntityKind_RecentFile, -RD_EntityKind_Source, -RD_EntityKind_Dest, -RD_EntityKind_ConversionTask, -RD_EntityKind_ConversionFail, -RD_EntityKind_COUNT, -} RD_EntityKind; - typedef enum RD_RegSlot { RD_RegSlot_Null, @@ -561,7 +529,6 @@ struct RD_Query RD_QueryFlags flags; RD_RegSlot slot; String8 view_name; -RD_EntityKind entity_kind; CTRL_EntityKind ctrl_entity_kind; }; @@ -655,18 +622,12 @@ extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; extern RD_VocabularyInfo rd_vocabulary_info_table[45]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; -extern String8 d_entity_kind_display_string_table[27]; -extern String8 d_entity_kind_name_lower_table[27]; -extern String8 d_entity_kind_name_lower_plural_table[27]; -extern String8 d_entity_kind_name_label_table[27]; -extern RD_EntityKindFlags rd_entity_kind_flags_table[27]; extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[13]; -extern RD_IconKind rd_entity_kind_icon_kind_table[27]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_color_version_remap_old_name_table[22]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b539fbec..d8aaf044 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -243,114 +243,20 @@ RD_VocabularyMap: @expand(RD_SchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.cmd_names)")}` } -//////////////////////////////// -//~ rjf: Entity Kind Tables - -@table(name name_lower name_lower_plural op_delete op_freeze op_edit op_rename op_enable op_cond op_dup name_is_code name_is_path user_lifetime is_serialized name_label icon_kind display_string) -// | | -// | _____________________________________________________________________________________________________________________________________/ -// | / -// operations________ names lt sz -// /..................\ /...\ | | -// dl fz ed rn en cn dp nc np ul iz -RD_EntityKindTable: -{ - {Nil nil nils 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Nil" } - {Root root roots 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Root" } - - //- rjf: auto view rules - {AutoViewRule auto_view_rule auto_view_rules 1 0 0 0 0 0 0 0 0 1 1 "Label" Binoculars "Auto View Rule" } - - //- rjf: file path maps - {FilePathMap file_path_map file_path_maps 1 0 0 0 0 0 0 0 0 0 1 "Label" FileOutline "File Path Map" } - - //- rjf: watch pins - {WatchPin watch_pin watch_pins 1 0 0 1 0 0 1 1 0 1 1 "Expression" Pin "Watch Pin" } - - //- rjf: watches - {Watch watch watches 1 0 0 1 1 0 1 1 0 1 1 "Expression" Binoculars "Watch" } - {ViewRule view_rule view_rules 1 0 0 1 1 0 1 1 0 1 0 "Expression" Binoculars "View Rule" } - - //- rjf: breakpoints - {Breakpoint breakpoint breakpoints 1 0 0 1 1 1 1 1 0 1 1 "Label" CircleFilled "Breakpoint" } - {Condition condition conditions 0 0 0 0 0 0 0 1 0 1 0 "Expression" CircleFilled "Condition" } - - //- rjf: user-controlled locations (source, addresses, symbol names) - {Location location locations 0 0 0 0 0 0 0 1 1 1 0 "Location" Null "Location" } - - //- rjf: targets - {Target target targets 1 0 1 1 1 0 1 0 0 1 1 "Label" Target "Target" } - {Executable executable executables 0 0 0 0 0 0 0 0 1 1 0 "Executable" Null "Executable" } - {Arguments arguments argumentses 0 0 0 0 0 0 0 0 0 1 0 "Arguments" Null "Arguments" } - {WorkingDirectory working_directory working_directories 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Working Directory" } - {EntryPoint entry_point entry_points 0 0 0 0 0 0 0 0 0 1 0 "Symbol Name" Null "Entry Point" } - {StdoutPath stdout_path stdout_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Output Path" } - {StderrPath stderr_path stderr_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Error Path" } - {StdinPath stdin_path stdin_paths 0 0 0 0 0 0 0 0 1 1 0 "Path" Null "Standard Input Path" } - - //- rjf: frontend containers (windows, panels, views) - {Window window windows 1 0 0 0 0 0 1 0 0 1 1 "Label" Window "Window" } - {Panel panel panels 1 0 0 0 0 0 1 0 0 1 1 "Label" XSplit "Panel" } - {View view views 1 0 0 0 0 0 1 0 0 1 1 "Label" Null "View" } - - //- rjf: recent projects - {RecentProject recent_project recent_projects 0 0 0 0 0 0 0 0 1 0 1 "Path" Briefcase "Recent Project" } - - //- rjf: recent files - {RecentFile recent_file recent_files 0 0 0 0 0 0 0 0 1 0 1 "Path" FileOutline "Recent File" } - - //- rjf: src -> dst mapping - {Source source sources 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Source" } - {Dest dest dests 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Destination" } - - //- rjf: parser task entities - {ConversionTask conversion_task conversion_tasks 0 0 0 1 0 0 0 0 0 0 0 "Label" Null "Conversion Task" } - {ConversionFail conversion_fail conversion_fails 0 0 0 1 0 0 0 0 0 0 0 "Label" Null "Conversion Failure" } -} - -@enum RD_EntityKind: -{ - @expand(RD_EntityKindTable a) `$(a.name)`, - COUNT, -} - -@data(String8) d_entity_kind_display_string_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.display_string)")`, -} - -@data(String8) d_entity_kind_name_lower_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_lower)")`, -} - -@data(String8) d_entity_kind_name_lower_plural_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_lower_plural)")`, -} - -@data(String8) d_entity_kind_name_label_table: -{ - @expand(RD_EntityKindTable a) `str8_lit_comp("$(a.name_label)")`, -} - -@data(RD_EntityKindFlags) rd_entity_kind_flags_table: -{ - @expand(RD_EntityKindTable a) `($(a.op_delete)*RD_EntityKindFlag_CanDelete) | ($(a.op_freeze)*RD_EntityKindFlag_CanFreeze) | ($(a.op_edit)*RD_EntityKindFlag_CanEdit) | ($(a.op_rename)*RD_EntityKindFlag_CanRename) | ($(a.op_enable)*RD_EntityKindFlag_CanEnable) | ($(a.op_cond)*RD_EntityKindFlag_CanCondition) | ($(a.op_dup)*RD_EntityKindFlag_CanDuplicate) | ($(a.name_is_code)*RD_EntityKindFlag_NameIsCode) | ($(a.name_is_path)*RD_EntityKindFlag_NameIsPath) | ($(a.user_lifetime)*RD_EntityKindFlag_UserDefinedLifetime) | ($(a.is_serialized)*RD_EntityKindFlag_IsSerializedToConfig)`, -} - //////////////////////////////// //~ rjf: Registers Type Table @table(c_type name_lower name) RD_RegTable: { - // rjf: entity slots + // rjf: ctrl entities {CTRL_Handle machine Machine } {CTRL_Handle module Module } {CTRL_Handle process Process } {CTRL_Handle thread Thread } {CTRL_Handle ctrl_entity CtrlEntity } + + // rjf: cfgs {RD_CfgID window Window } {RD_CfgID panel Panel } {RD_CfgID view View } @@ -605,14 +511,14 @@ RD_CmdTable: // | | | | {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general config operations - {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_cfg" "Enable Config Tree" "Enables an entity." "" "" } - {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_cfg" "Disable Config Tree" "Disables an entity." "" "" } - {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_cfg" "Select Config Tree" "Selects an entity, disabling all others of the same kind." "" "" } - {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes an entity." "" "" } - {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips an entity with a name." "" "" } - {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips an entity with a condition string." "" "" } - {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates an entity." "" "" } - {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates an entity." "" "" } + {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } + {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } @@ -699,7 +605,6 @@ RD_CmdTable: // | | | | `RD_QueryFlags flags`; `RD_RegSlot slot`; `String8 view_name`; - `RD_EntityKind entity_kind`; `CTRL_EntityKind ctrl_entity_kind`; } @@ -719,9 +624,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), RD_EntityKind_$(a.q_ent_kind), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -1029,10 +934,8 @@ RD_ViewRuleTable: //- rjf: temporary view for loading files - must analyze file before picking viewer { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } - //- rjf: watch view + //- rjf: visualizers { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } - - //- rjf: data visualizers { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } @@ -1074,14 +977,6 @@ RD_ViewRuleTable: @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, } -//////////////////////////////// -//~ rjf: Built-In Debug Engine Kind -> Icon Kind Table - -@data(RD_IconKind) rd_entity_kind_icon_kind_table: -{ - @expand(RD_EntityKindTable a) `RD_IconKind_$(a.icon_kind)`, -} - //////////////////////////////// //~ rjf: Theme Tables diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 44ca4ca1..289b7de6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -94,49 +94,6 @@ enum RD_EvalSpaceKind_MetaCmd, }; -//////////////////////////////// -//~ rjf: Entity Kind Flags - -typedef U32 RD_EntityKindFlags; -enum -{ - //- rjf: allowed operations - RD_EntityKindFlag_CanDelete = (1<<0), - RD_EntityKindFlag_CanFreeze = (1<<1), - RD_EntityKindFlag_CanEdit = (1<<2), - RD_EntityKindFlag_CanRename = (1<<3), - RD_EntityKindFlag_CanEnable = (1<<4), - RD_EntityKindFlag_CanCondition = (1<<5), - RD_EntityKindFlag_CanDuplicate = (1<<6), - - //- rjf: name categorization - RD_EntityKindFlag_NameIsCode = (1<<7), - RD_EntityKindFlag_NameIsPath = (1<<8), - - //- rjf: lifetime categorization - RD_EntityKindFlag_UserDefinedLifetime = (1<<9), - - //- rjf: serialization - RD_EntityKindFlag_IsSerializedToConfig = (1<<10), -}; - -//////////////////////////////// -//~ rjf: Entity Flags - -typedef U32 RD_EntityFlags; -enum -{ - //- rjf: allocationless, simple equipment - RD_EntityFlag_HasTextPoint = (1<<0), - RD_EntityFlag_HasEntityHandle = (1<<2), - RD_EntityFlag_HasU64 = (1<<4), - RD_EntityFlag_HasColor = (1<<6), - RD_EntityFlag_HasVAddr = (1<<15), - - //- rjf: deletion - RD_EntityFlag_MarkedForDeletion = (1<<31), -}; - //////////////////////////////// //~ rjf: View Rule Info Types From 31b0772137efe5426e5ffa0fee27eb63a85e5d93 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 7 Feb 2025 09:21:06 -0800 Subject: [PATCH 070/755] eval viz: view rule -> expansion rule; rd: view rule -> view ui rule --- src/eval/eval_bundles.c | 13 + src/eval/eval_bundles.h | 1 + src/eval/eval_parse.h | 2 +- .../eval_visualization_core.h | 5 +- src/raddbg/generated/raddbg.meta.c | 17 - src/raddbg/generated/raddbg.meta.h | 51 -- src/raddbg/raddbg.mdesk | 2 + src/raddbg/raddbg_core.c | 601 +++++++++++++++--- src/raddbg/raddbg_core.h | 75 ++- src/raddbg/raddbg_views.c | 389 +----------- src/raddbg/raddbg_views.h | 15 + 11 files changed, 659 insertions(+), 512 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index db040024..6d966dea 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -40,6 +40,19 @@ e_eval_from_string(Arena *arena, String8 string) return eval; } +internal E_Eval +e_eval_from_stringf(Arena *arena, char *fmt, ...) +{ + Temp scratch = scratch_begin(&arena, 1); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Eval eval = e_eval_from_string(arena, string); + va_end(args); + scratch_end(scratch); + return eval; +} + internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval) { diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index 957ff123..f835a6cb 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -24,6 +24,7 @@ struct E_Eval internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); internal E_Eval e_eval_from_string(Arena *arena, String8 string); +internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); internal E_Eval e_value_eval_from_eval(E_Eval eval); diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index d91a2c76..7e0fcaf6 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -214,7 +214,7 @@ struct E_ParseState global read_only E_String2NumMap e_string2num_map_nil = {0}; global read_only E_String2ExprMap e_string2expr_map_nil = {0}; -global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil}; +global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index b9651404..14548ec9 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -75,7 +75,7 @@ struct EV_View }; //////////////////////////////// -//~ rjf: View Rule Info Types +//~ rjf: Expansion Rule Types typedef struct EV_ExpandInfo EV_ExpandInfo; struct EV_ExpandInfo @@ -120,9 +120,6 @@ struct EV_ExpandRuleTable U64 slots_count; }; -//////////////////////////////// -//~ rjf: Expansion Rule Types - typedef struct EV_ExpandRuleTagPair EV_ExpandRuleTagPair; struct EV_ExpandRuleTagPair { diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7d2b7370..b20c50db 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -562,23 +562,6 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; -RD_ViewRuleInfo rd_view_rule_kind_info_table[13] = -{ -{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, -{str8_lit_comp("empty"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), RD_IconKind_Null, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(empty)}, -{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(getting_started)}, -{str8_lit_comp("settings"), str8_lit_comp("An interface to modify general settings for the debugger's appearance and behavior."), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(settings)}, -{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(pending_file)}, -{str8_lit_comp("watch"), str8_lit_comp("The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section."), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*1|RD_ViewRuleInfoFlag_FilterIsCode*1|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*1|RD_ViewRuleInfoFlag_CanUseInWatchTable*0|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(watch)}, -{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), RD_IconKind_FileOutline, (RD_ViewRuleInfoFlag_ShowInDocs*0|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text) , RD_VIEW_RULE_UI_FUNCTION_NAME(text)}, -{str8_lit_comp("disasm"), str8_lit_comp("Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space."), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}"), RD_IconKind_Glasses, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm) , RD_VIEW_RULE_UI_FUNCTION_NAME(disasm)}, -{str8_lit_comp("memory"), str8_lit_comp("A hex-editor-like grid interface for viewing memory."), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), RD_IconKind_Grid, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory) , RD_VIEW_RULE_UI_FUNCTION_NAME(memory)}, -{str8_lit_comp("bitmap"), str8_lit_comp("Visualizes memory as a bitmap."), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap) , RD_VIEW_RULE_UI_FUNCTION_NAME(bitmap)}, -{str8_lit_comp("checkbox"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Checkbox"), str8_lit_comp(""), RD_IconKind_CheckFilled, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*0), EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(checkbox)}, -{str8_lit_comp("color_rgba"), str8_lit_comp("Visualizes memory as an RGBA color."), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), RD_IconKind_Palette, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*1|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba) , RD_VIEW_RULE_UI_FUNCTION_NAME(color_rgba)}, -{str8_lit_comp("geo3d"), str8_lit_comp("Visualizes memory as 3D geometry."), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), RD_IconKind_Binoculars, (RD_ViewRuleInfoFlag_ShowInDocs*1|RD_ViewRuleInfoFlag_CanFilter*0|RD_ViewRuleInfoFlag_FilterIsCode*0|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*0|RD_ViewRuleInfoFlag_CanUseInWatchTable*1|RD_ViewRuleInfoFlag_CanFillValueCell*0|RD_ViewRuleInfoFlag_CanExpand*1), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d) , RD_VIEW_RULE_UI_FUNCTION_NAME(geo3d)}, -}; - String8 rd_theme_preset_display_string_table[9] = { str8_lit_comp("Default (Dark)"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 21abb11c..7de4f395 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -350,24 +350,6 @@ RD_IconKind_Dot, RD_IconKind_COUNT, } RD_IconKind; -typedef enum RD_ViewRuleKind -{ -RD_ViewRuleKind_Null, -RD_ViewRuleKind_Empty, -RD_ViewRuleKind_GettingStarted, -RD_ViewRuleKind_Settings, -RD_ViewRuleKind_PendingFile, -RD_ViewRuleKind_Watch, -RD_ViewRuleKind_Text, -RD_ViewRuleKind_Disasm, -RD_ViewRuleKind_Memory, -RD_ViewRuleKind_Bitmap, -RD_ViewRuleKind_Checkbox, -RD_ViewRuleKind_ColorRGBA, -RD_ViewRuleKind_Geo3D, -RD_ViewRuleKind_COUNT, -} RD_ViewRuleKind; - typedef enum RD_ThemeColor { RD_ThemeColor_Null, @@ -545,19 +527,6 @@ RD_CmdKindFlags flags; RD_Query query; }; -typedef struct RD_ViewRuleInfo RD_ViewRuleInfo; -struct RD_ViewRuleInfo -{ -String8 string; -String8 description; -String8 display_name; -String8 params_schema; -RD_IconKind icon_kind; -RD_ViewRuleInfoFlags flags; -EV_ExpandRuleInfoHookFunctionType *expr_expand_info; -RD_ViewRuleUIFunctionType *ui; -}; - #define rd_regs_lit_init_top \ .machine = rd_regs()->machine,\ .module = rd_regs()->module,\ @@ -597,25 +566,6 @@ RD_ViewRuleUIFunctionType *ui; .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ -RD_VIEW_RULE_UI_FUNCTION_DEF(null); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); -RD_VIEW_RULE_UI_FUNCTION_DEF(empty); -RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started); -RD_VIEW_RULE_UI_FUNCTION_DEF(settings); -RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file); -RD_VIEW_RULE_UI_FUNCTION_DEF(watch); -RD_VIEW_RULE_UI_FUNCTION_DEF(text); -RD_VIEW_RULE_UI_FUNCTION_DEF(disasm); -RD_VIEW_RULE_UI_FUNCTION_DEF(memory); -RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap); -RD_VIEW_RULE_UI_FUNCTION_DEF(checkbox); -RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba); -RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d); C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; @@ -627,7 +577,6 @@ extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; -extern RD_ViewRuleInfo rd_view_rule_kind_info_table[13]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_color_version_remap_old_name_table[22]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d8aaf044..ec0bf8a1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -945,6 +945,7 @@ RD_ViewRuleTable: { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } } +/* @enum RD_ViewRuleKind: { Null, @@ -976,6 +977,7 @@ RD_ViewRuleTable: `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, } +*/ //////////////////////////////// //~ rjf: Theme Tables diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4ae3f566..f9c6a537 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -76,6 +76,7 @@ rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs //////////////////////////////// //~ rjf: View Spec Type Functions +#if 0 // TODO(rjf): @cfg internal RD_ViewRuleKind rd_view_rule_kind_from_string(String8 string) { @@ -110,6 +111,50 @@ rd_view_rule_info_from_string(String8 string) } return result; } +#endif + +//////////////////////////////// +//~ rjf: View UI Rule Functions + +internal RD_ViewUIRuleMap * +rd_view_ui_rule_map_make(Arena *arena, U64 slots_count) +{ + RD_ViewUIRuleMap *map = push_array(arena, RD_ViewUIRuleMap, 1); + map->slots_count = slots_count; + map->slots = push_array(arena, RD_ViewUIRuleSlot, map->slots_count); + return map; +} + +internal void +rd_view_ui_rule_map_insert(Arena *arena, RD_ViewUIRuleMap *map, String8 string, RD_ViewUIFunctionType *ui) +{ + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + RD_ViewUIRuleNode *n = push_array(arena, RD_ViewUIRuleNode, 1); + n->v.name = push_str8_copy(arena, string); + n->v.ui = ui; + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); +} + +internal RD_ViewUIRule * +rd_view_ui_rule_from_string(String8 string) +{ + RD_ViewUIRule *rule = &rd_nil_view_ui_rule; + { + RD_ViewUIRuleMap *map = rd_state->view_ui_rule_map; + U64 hash = d_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + for(RD_ViewUIRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->v.name, string, 0)) + { + rule = &n->v; + break; + } + } + } + return rule; +} //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions @@ -1533,6 +1578,16 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) return result; } +internal E_Expr * +rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + E_Expr *expr = &e_expr_nil; + { + // TODO(rjf): @cfg + } + return expr; +} + //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -2410,16 +2465,6 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un //- rjf: view rule config tree info extraction -internal U64 -rd_base_offset_from_eval(E_Eval eval) -{ - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - internal E_Value rd_value_from_params_key(MD_Node *params, String8 key) { @@ -2739,6 +2784,272 @@ rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query return result; } +internal void +rd_view_ui(Rng2F32 rect) +{ + ProfBeginFunction(); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + String8 view_name = view->string; + String8 expr_string = rd_expr_from_cfg(view); + + ////////////////////////////// + //- rjf: special-case view: "getting started" + // + if(0){} + else if(str8_match(view_name, str8_lit("getting_started"), 0)) + { + Temp scratch = scratch_begin(0, 0); + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + + //- rjf: icon & info + UI_Padding(ui_em(2.f, 1.f)) + { + //- rjf: icon + { + F32 icon_dim = ui_top_font_size()*10.f; + UI_PrefHeight(ui_px(icon_dim, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_PrefWidth(ui_px(icon_dim, 1.f)) + { + R_Handle texture = rd_state->icon_texture; + Vec2S32 texture_dim = r_size_from_tex2d(texture); + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + } + } + + //- rjf: info + UI_Padding(ui_em(2.f, 1.f)) + UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_text_dim(10, 1)) + { + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); + } + } + + //- rjf: targets state dependent helper + B32 helper_built = 0; + if(processes.count == 0) + { + helper_built = 1; + switch(targets.count) + { + //- rjf: user has no targets. build helper for adding them + case 0: + { + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + RD_Palette(RD_PaletteCode_NeutralPopButton) + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + } + }break; + + //- rjf: user has 1 target. build helper for launching it + case 1: + { + RD_Cfg *target_cfg = rd_cfg_list_first(&targets); + D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); + String8 target_full_path = target.exe; + String8 target_name = str8_skip_last_slash(target_full_path); + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + RD_Palette(RD_PaletteCode_PositivePopButton) + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); + } + ui_spacer(ui_em(1.5f, 1)); + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); + } + } + }break; + + //- rjf: user has N targets. + default: + { + helper_built = 0; + }break; + } + } + + //- rjf: or text + if(helper_built) + { + UI_PrefHeight(ui_em(2.25f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_WidthFill + ui_labelf("- or -"); + } + + //- rjf: helper text for command lister activation + UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + UI_Padding(ui_pct(1, 0)) + RD_Palette(RD_PaletteCode_Floating) + { + ui_labelf("use"); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + ui_labelf("to open the lister for commands and options"); + } + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: special-case view: pending + // + else if(str8_match(view_name, str8_lit("pending"), 0)) + { + Temp scratch = scratch_begin(0, 0); + typedef struct State State; + struct State + { + Arena *deferred_cmd_arena; + RD_CmdList deferred_cmds; + }; + State *state = rd_view_state(State); + if(state->deferred_cmd_arena == 0) + { + state->deferred_cmd_arena = rd_push_view_arena(); + } + rd_store_view_loading_info(1, 0, 0); + + // rjf: any commands sent to this view need to be deferred until loading is complete + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) + { + default:{}break; + case RD_CmdKind_GoToLine: + case RD_CmdKind_GoToAddress: + case RD_CmdKind_CenterCursor: + case RD_CmdKind_ContainCursor: + { + rd_cmd_list_push_new(state->deferred_cmd_arena, &state->deferred_cmds, cmd->name, cmd->regs); + }break; + } + } + + // rjf: unpack view's target expression & hash + String8 expr_string = rd_view_expr_string(); + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + Rng1U64 range = r1u64(0, 1024); + U128 key = rd_key_from_eval_space_range(eval.space, range, 0); + U128 hash = hs_hash_from_key(key, 0); + + // rjf: determine if hash's blob is ready, and which viewer to use + B32 data_is_ready = 0; + String8 new_view_name = {0}; + { + HS_Scope *hs_scope = hs_scope_open(); + if(!u128_match(hash, u128_zero())) + { + String8 data = hs_data_from_hash(hs_scope, hash); + U64 num_utf8_bytes = 0; + U64 num_unknown_bytes = 0; + for(U64 idx = 0; idx < data.size && idx < range.max;) + { + UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); + if(decode.codepoint != max_U32 && (decode.inc > 1 || + (10 <= decode.codepoint && decode.codepoint <= 13) || + (32 <= decode.codepoint && decode.codepoint <= 126))) + { + num_utf8_bytes += decode.inc; + idx += decode.inc; + } + else + { + num_unknown_bytes += 1; + idx += 1; + } + } + data_is_ready = 1; + if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) + { + new_view_name = str8_lit("text"); + } + else + { + new_view_name = str8_lit("memory"); + } + } + hs_scope_close(hs_scope); + } + + // rjf: if we don't have a viewer, just use the memory viewer. + if(new_view_name.size != 0) + { + new_view_name = str8_lit("memory"); + } + + // rjf: if data is ready and we have the name of a new visualizer, + // dispatch deferred commands & change this view's string to be + // that of the new visualizer. + if(data_is_ready && new_view_name.size != 0) + { + for(RD_CmdNode *cmd_node = state->deferred_cmds.first; + cmd_node != 0; + cmd_node = cmd_node->next) + { + RD_Cmd *cmd = &cmd_node->cmd; + rd_push_cmd(cmd->name, cmd->regs); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + rd_cfg_equip_string(view, new_view_name); + } + + // rjf: if we don't have a viewer, for whatever reason, then just + // close the tab. + if(data_is_ready && new_view_name.size == 0) + { + rd_cmd(RD_CmdKind_CloseTab); + } + + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: visualizer hook + // + else + { + Temp scratch = scratch_begin(0, 0); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); + E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); + E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); + view_ui_rule->ui(expr_eval, tag, rect); + scratch_end(scratch); + } + + ProfEnd(); +} + //////////////////////////////// //~ rjf: View Building API @@ -2786,6 +3097,117 @@ rd_view_filter(void) return filter_string; } +internal RD_Cfg * +rd_view_cfg_from_string(String8 string) +{ + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *cfg = rd_cfg_child_from_string(view, string); + return cfg; +} + +internal E_Value +rd_view_cfg_value_from_string(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + RD_Cfg *root = rd_view_cfg_from_string(string); + String8 expr = root->first->string; + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Value result = e_value_eval_from_eval(eval).value; + scratch_end(scratch); + return result; +} + +//- rjf: evaluation & tag (a view's 'call') parameter extraction + +internal U64 +rd_base_offset_from_eval(E_Eval eval) +{ + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) + { + eval = e_value_eval_from_eval(eval); + } + return eval.value.u64; +} + +internal Rng1U64 +rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + Temp scratch = scratch_begin(0, 0); + U64 size = 0; + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("size"), 0)) + { + size = e_eval_from_expr(scratch.arena, param->first->next).value.u64; + break; + } + } + E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKind type_kind = e_type_kind_from_key(type_key); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); + } + if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Union || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); + } + if(size == 0) + { + size = KB(16); + } + Rng1U64 result = {0}; + result.min = rd_base_offset_from_eval(eval); + result.max = result.min + size; + scratch_end(scratch); + return result; +} + +internal TXT_LangKind +rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + TXT_LangKind lang_kind = TXT_LangKind_Null; + if(eval.expr->kind == E_ExprKind_LeafFilePath) + { + lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.expr->string)); + } + else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(param->first->next->string); + break; + } + } + return lang_kind; +} + +internal Arch +rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + +} + +internal Vec2S32 +rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + +} + +internal R_Tex2DFormat +rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) +{ + +} + //- rjf: pushing/attaching view resources internal void * @@ -3454,8 +3876,6 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("expression")); - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); { //- rjf: tab dragging if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg) @@ -3475,20 +3895,11 @@ rd_window_frame(void) UI_Box *container = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(container) { - UI_Row + UI_Row UI_PrefWidth(ui_text_dim(10, 1)) { - RD_IconKind icon_kind = view_rule_info->icon_kind; - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, query->first->string, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(2.5f, 1.f)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[icon_kind]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); - } + DR_FancyStringList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view, ui_top_palette()->text_weak, ui_top_font_size()); + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(name_box, &fstrs); } ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); @@ -3496,11 +3907,7 @@ rd_window_frame(void) UI_Box *view_preview_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_preview_container"); UI_Parent(view_preview_container) UI_Focus(UI_FocusKind_Off) UI_WidthFill { - RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - String8 expr = rd_view_expr_string(); - String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); - MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; - view_ui(expr, params, view_preview_container->rect); + rd_view_ui(view_preview_container->rect); } } } @@ -4318,6 +4725,7 @@ rd_window_frame(void) // case RD_RegSlot_View: { +#if 0 // TODO(rjf): @cfg RD_Cfg *tab = rd_cfg_from_id(regs->view); RD_RegsScope(.view = regs->view) { @@ -4440,6 +4848,7 @@ rd_window_frame(void) } #endif } +#endif }break; ////////////////////// @@ -5720,7 +6129,6 @@ rd_window_frame(void) RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); RD_RegsScope(.panel = 0, .view = view->id) { - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); rd_cfg_new_replace(expr, ws->hover_eval_string); EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); @@ -5769,10 +6177,7 @@ rd_window_frame(void) UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); UI_Parent(view_contents_container) UI_WidthFill { - RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - String8 params_string = rd_string_from_cfg_tree(scratch.arena, view); - MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; - view_ui(expr->first->string, params, view_contents_container->rect); + rd_view_ui(view_contents_container->rect); } } UI_Signal sig = ui_signal_from_box(container); @@ -6777,6 +7182,7 @@ rd_window_frame(void) ////////////////////////// //- rjf: build filtering box // +#if 0 // TODO(rjf): @cfg { RD_Cfg *view = selected_tab; RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); @@ -6831,6 +7237,7 @@ rd_window_frame(void) } } } +#endif ////////////////////////// //- rjf: panel not selected? -> darken @@ -6879,7 +7286,7 @@ rd_window_frame(void) rd_push_regs(.panel = panel->cfg->id, .view = selected_tab->id); { - String8 view_expr = rd_view_expr_string(); + String8 view_expr = rd_expr_from_cfg(selected_tab); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); if(view_file_path.size != 0) { @@ -6899,18 +7306,30 @@ rd_window_frame(void) //- rjf: build empty view UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) { - RD_VIEW_RULE_UI_FUNCTION_NAME(empty)(str8_zero(), &md_nil_node, content_rect); + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + UI_PrefHeight(ui_em(3.f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(15.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + RD_Palette(RD_PaletteCode_NegativePopButton) + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) + { + rd_cmd(RD_CmdKind_ClosePanel); + } + } + } } //- rjf: build tab view UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") { - String8 view_expr = rd_expr_from_cfg(selected_tab); - String8 params_string = rd_string_from_cfg_tree(scratch.arena, selected_tab); - MD_Node *params = md_tree_from_string(scratch.arena, params_string)->first; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(selected_tab->string); - RD_ViewRuleUIFunctionType *view_ui = view_rule_info->ui; - view_ui(view_expr, params, content_rect); + rd_view_ui(content_rect); } //- rjf: pop interaction registers; commit if this is the selected view @@ -6935,6 +7354,7 @@ rd_window_frame(void) ////////////////////////// //- rjf: take events to automatically start/end filtering, if applicable // +#if 0 // TODO(rjf): @cfg UI_Focus(UI_FocusKind_On) { RD_Cfg *view = selected_tab; @@ -6963,6 +7383,7 @@ rd_window_frame(void) rd_cmd(RD_CmdKind_ClearFilter); } } +#endif ////////////////////////// //- rjf: consume panel fallthrough interaction events @@ -7037,7 +7458,6 @@ rd_window_frame(void) { prev_tab = tab; tab = tab_n->v; - RD_ViewRuleInfo *tab_view_rule_info = rd_view_rule_info_from_string(tab->string); temp_end(scratch); if(rd_cfg_is_project_filtered(tab)) { continue; } @@ -7078,9 +7498,7 @@ rd_window_frame(void) { // rjf: gather info for this tab B32 view_is_selected = (tab == panel->selected_tab); - RD_IconKind icon_kind = tab_view_rule_info->icon_kind; - String8 view_expr = rd_view_expr_string(); - DR_FancyStringList title_fstrs = rd_title_fstrs_from_view(scratch.arena, tab_view_rule_info->display_name, view_expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FancyStringList title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); // rjf: begin vertical region for this tab ui_set_next_child_layout_axis(Axis2_Y); @@ -7111,14 +7529,6 @@ rd_window_frame(void) UI_WidthFill UI_Row { ui_spacer(ui_em(0.5f, 1.f)); - if(icon_kind != RD_IconKind_Null) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(1.75f, 1.f)) - ui_label(rd_icon_kind_text_table[icon_kind]); - } UI_PrefWidth(ui_text_dim(10, 0)) { UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); @@ -9733,6 +10143,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St //- rjf: gather settings if(flags & RD_ListerFlag_Settings) { +#if 0 // TODO(rjf): @cfg String8List schema_strings = {0}; // rjf: push schema for view @@ -9765,6 +10176,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St } } } +#endif } //- rjf: gather system processes @@ -11257,6 +11669,20 @@ rd_next_cmd(RD_Cmd **cmd) return !!cmd[0]; } +internal B32 +rd_next_view_cmd(RD_Cmd **cmd) +{ + for(;rd_next_cmd(cmd);) + { + if(rd_regs()->view == cmd[0]->regs->view) + { + break; + } + } + B32 result = !!cmd[0]; + return result; +} + //////////////////////////////// //~ rjf: Main Layer Top-Level Calls @@ -12549,6 +12975,18 @@ rd_frame(void) e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, parse.expr); } } + + //- rjf: add auto-hook rules for auto-view-rules + { + RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); + for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) + { + RD_Cfg *rule = n->v; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("source"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("dest"))->first->string; + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + } + } } e_select_ir_ctx(ir_ctx); @@ -12572,34 +13010,38 @@ rd_frame(void) e_select_interpret_ctx(interpret_ctx); //////////////////////////// - //- rjf: build eval visualization expand rule table + //- rjf: build eval expand rule table // EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); ev_select_expand_rule_table(expand_rule_table); //////////////////////////// - //- rjf: build eval visualization auto-view-rule table + //- rjf: build view ui rule map // - // TODO(rjf): @cfg - // - EV_AutoViewRuleTable *auto_view_rule_table = push_array(scratch.arena, EV_AutoViewRuleTable, 1); + rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); { - RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); - for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) + // TODO(rjf): generate via metaprogram + struct { - RD_Cfg *rule = n->v; - String8 type_string = rd_cfg_child_from_string(rule, str8_lit("source"))->first->string; - String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("dest"))->first->string; - E_TokenArray tokens = e_token_array_from_text(scratch.arena, type_string); - E_Parse type_parse = e_parse_type_from_text_tokens(scratch.arena, type_string, &tokens); - E_TypeKey type_key = e_type_from_expr(type_parse.expr); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - // ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, type_key, view_rule_string, 0); - } + String8 name; + RD_ViewUIFunctionType *ui; + } + table[] = + { + {str8_lit("watch"), RD_VIEW_UI_FUNCTION_NAME(watch)}, + {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text)}, + {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox)}, + {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d)}, + }; + for EachElement(idx, table) + { + rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, table[idx].name, table[idx].ui); } } - // ev_select_auto_view_rule_table(auto_view_rule_table); //////////////////////////// //- rjf: autosave if needed @@ -12691,11 +13133,13 @@ rd_frame(void) } // rjf: try to open tabs for "view driver" commands +#if 0 // TODO(rjf): @cfg RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(cmd->name); if(view_rule_info != &rd_nil_view_rule_info) { rd_cmd(RD_CmdKind_OpenTab, .string = str8_zero(), .params_tree = md_tree_from_string(scratch.arena, cmd->name)->first); } +#endif }break; //- rjf: top-level lister @@ -13684,9 +14128,11 @@ rd_frame(void) if(props.created != 0) { rd_cmd(RD_CmdKind_RecordFileInProject); +#if 0 // TODO(rjf): @cfg rd_cmd(RD_CmdKind_OpenTab, .string = rd_eval_string_from_file_path(scratch.arena, path), .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); +#endif } else { @@ -14377,8 +14823,7 @@ Z(getting_started) { String8 tab_expr = rd_view_expr_string(); String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); - RD_ViewRuleKind tab_view_kind = rd_view_rule_kind_from_string(tab->string); - if((tab_view_kind == RD_ViewRuleKind_Text || tab_view_kind == RD_ViewRuleKind_PendingFile) && + if((str8_match(tab->string, str8_lit("text"), 0) || str8_match(tab->string, str8_lit("pending"), 0)) && path_match_normalized(tab_file_path, file_path)) { panel_w_this_src_code = panel; @@ -14412,10 +14857,9 @@ Z(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); String8 view_expr = rd_expr_from_cfg(tab); String8 file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); - if(view_kind == RD_ViewRuleKind_Text && file_path.size != 0 && panel_area > best_panel_area) + if(str8_match(tab->string, str8_lit("text"), 0) && file_path.size != 0 && panel_area > best_panel_area) { panel_w_any_src_code = panel; best_panel_area = panel_area; @@ -14449,9 +14893,8 @@ Z(getting_started) RD_RegsScope(.view = tab->id) { B32 tab_is_selected = (tab == panel->selected_tab); - RD_ViewRuleKind view_kind = rd_view_rule_kind_from_string(tab->string); String8 expr_string = rd_view_expr_string(); - if(view_kind == RD_ViewRuleKind_Disasm && expr_string.size == 0 && panel_area > best_panel_area) + if(str8_match(tab->string, str8_lit("disasm"), 0) && expr_string.size == 0 && panel_area > best_panel_area) { panel_w_disasm = panel; view_w_disasm = tab; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 289b7de6..ab55cf8e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -25,7 +25,7 @@ struct RD_CfgIDList }; //////////////////////////////// -//~ rjf: Key Binding Types +//~ rjf: Key Bindings typedef struct RD_Binding RD_Binding; struct RD_Binding @@ -94,6 +94,42 @@ enum RD_EvalSpaceKind_MetaCmd, }; +//////////////////////////////// +//~ rjf: View UI Hook Types + +#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, E_Expr *tag, Rng2F32 rect) +#define RD_VIEW_UI_FUNCTION_NAME(name) rd_view_ui__##name +#define RD_VIEW_UI_FUNCTION_DEF(name) internal RD_VIEW_UI_FUNCTION_SIG(RD_VIEW_UI_FUNCTION_NAME(name)) +typedef RD_VIEW_UI_FUNCTION_SIG(RD_ViewUIFunctionType); + +typedef struct RD_ViewUIRule RD_ViewUIRule; +struct RD_ViewUIRule +{ + String8 name; + RD_ViewUIFunctionType *ui; +}; + +typedef struct RD_ViewUIRuleNode RD_ViewUIRuleNode; +struct RD_ViewUIRuleNode +{ + RD_ViewUIRuleNode *next; + RD_ViewUIRule v; +}; + +typedef struct RD_ViewUIRuleSlot RD_ViewUIRuleSlot; +struct RD_ViewUIRuleSlot +{ + RD_ViewUIRuleNode *first; + RD_ViewUIRuleNode *last; +}; + +typedef struct RD_ViewUIRuleMap RD_ViewUIRuleMap; +struct RD_ViewUIRuleMap +{ + RD_ViewUIRuleSlot *slots; + U64 slots_count; +}; + //////////////////////////////// //~ rjf: View Rule Info Types @@ -721,6 +757,9 @@ struct RD_State RD_Cfg2EvalBlobMap *cfg2evalblob_map; RD_Entity2EvalBlobMap *entity2evalblob_map; + // rjf: name -> view ui map (constructed from-scratch each frame) + RD_ViewUIRuleMap *view_ui_rule_map; + // rjf: registers stack RD_RegsNode base_regs; RD_RegsNode *top_regs; @@ -841,6 +880,14 @@ read_only global RD_PanelNode rd_nil_panel_node = read_only global RD_CmdKindInfo rd_nil_cmd_kind_info = {0}; +RD_VIEW_UI_FUNCTION_DEF(null); +read_only global RD_ViewUIRule rd_nil_view_ui_rule = +{ + {0}, + RD_VIEW_UI_FUNCTION_NAME(null), +}; + +#if 0 // TODO(rjf): @cfg read_only global RD_ViewRuleInfo rd_nil_view_rule_info = { {0}, @@ -852,6 +899,7 @@ read_only global RD_ViewRuleInfo rd_nil_view_rule_info = EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null) }; +#endif read_only global RD_ViewState rd_nil_view_state = { @@ -891,9 +939,19 @@ internal void rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, //////////////////////////////// //~ rjf: View Spec Type Functions +#if 0 // TODO(rjf): @cfg internal RD_ViewRuleKind rd_view_rule_kind_from_string(String8 string); internal RD_ViewRuleInfo *rd_view_rule_info_from_kind(RD_ViewRuleKind kind); internal RD_ViewRuleInfo *rd_view_rule_info_from_string(String8 string); +#endif + +//////////////////////////////// +//~ rjf: View UI Rule Functions + +internal RD_ViewUIRuleMap *rd_view_ui_rule_map_make(Arena *arena, U64 slots_count); +internal void rd_view_ui_rule_map_insert(Arena *arena, RD_ViewUIRuleMap *map, String8 string, RD_ViewUIFunctionType *ui); + +internal RD_ViewUIRule *rd_view_ui_rule_from_string(String8 string); //////////////////////////////// //~ rjf: Global Cross-Window UI Interaction State Functions @@ -977,6 +1035,8 @@ internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path); internal String8List rd_possible_overrides_from_file_path(Arena *arena, String8 file_path); +internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); + //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -1023,7 +1083,6 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); //- rjf: eval / view rule params tree info extraction -internal U64 rd_base_offset_from_eval(E_Eval eval); internal E_Value rd_value_from_params_key(MD_Node *params, String8 key); internal Rng1U64 rd_range_from_eval_params(E_Eval eval, MD_Node *params); internal TXT_LangKind rd_lang_kind_from_eval_params(E_Eval eval, MD_Node *params); @@ -1040,6 +1099,7 @@ internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); +internal void rd_view_ui(Rng2F32 rect); //////////////////////////////// //~ rjf: View Building API @@ -1050,6 +1110,16 @@ internal UI_ScrollPt2 rd_view_scroll_pos(void); internal EV_View *rd_view_eval_view(void); internal String8 rd_view_expr_string(void); internal String8 rd_view_filter(void); +internal RD_Cfg *rd_view_cfg_from_string(String8 string); +internal E_Value rd_view_cfg_value_from_string(String8 string); + +//- rjf: evaluation & tag (a view's 'call') parameter extraction +internal U64 rd_base_offset_from_eval(E_Eval eval); +internal Rng1U64 rd_range_from_eval_tag(E_Eval eval, E_Expr *tag); +internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag); +internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag); +internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag); +internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); @@ -1185,6 +1255,7 @@ internal void rd_push_cmd(String8 name, RD_Regs *regs); //- rjf: iterating internal B32 rd_next_cmd(RD_Cmd **cmd); +internal B32 rd_next_view_cmd(RD_Cmd **cmd); //////////////////////////////// //~ rjf: Main Layer Top-Level Calls diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index ba7cd8ce..c25e69e3 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -55,15 +55,8 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: process commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(rd_regs()->view != cmd->regs->view) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -3995,166 +3988,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) //////////////////////////////// //~ rjf: null @view_hook_impl -RD_VIEW_RULE_UI_FUNCTION_DEF(null) {} - -//////////////////////////////// -//~ rjf: empty @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(empty) -{ - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) - { - UI_PrefHeight(ui_em(3.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(15.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NegativePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) - { - rd_cmd(RD_CmdKind_ClosePanel); - } - } - } -} - -//////////////////////////////// -//~ rjf: getting_started @view_hook_impl - -RD_VIEW_RULE_UI_FUNCTION_DEF(getting_started) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) - { - RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - - //- rjf: icon & info - UI_Padding(ui_em(2.f, 1.f)) - { - //- rjf: icon - { - F32 icon_dim = ui_top_font_size()*10.f; - UI_PrefHeight(ui_px(icon_dim, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_PrefWidth(ui_px(icon_dim, 1.f)) - { - R_Handle texture = rd_state->icon_texture; - Vec2S32 texture_dim = r_size_from_tex2d(texture); - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); - } - } - - //- rjf: info - UI_Padding(ui_em(2.f, 1.f)) - UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_text_dim(10, 1)) - { - ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); - } - } - - //- rjf: targets state dependent helper - B32 helper_built = 0; - if(processes.count == 0) - { - helper_built = 1; - switch(targets.count) - { - //- rjf: user has no targets. build helper for adding them - case 0: - { - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NeutralPopButton) - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - }break; - - //- rjf: user has 1 target. build helper for launching it - case 1: - { - RD_Cfg *target_cfg = rd_cfg_list_first(&targets); - D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); - String8 target_full_path = target.exe; - String8 target_name = str8_skip_last_slash(target_full_path); - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_PositivePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); - } - ui_spacer(ui_em(1.5f, 1)); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); - } - } - }break; - - //- rjf: user has N targets. - default: - { - helper_built = 0; - }break; - } - } - - //- rjf: or text - if(helper_built) - { - UI_PrefHeight(ui_em(2.25f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_WidthFill - ui_labelf("- or -"); - } - - //- rjf: helper text for command lister activation - UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_Padding(ui_pct(1, 0)) - RD_Palette(RD_PaletteCode_Floating) - { - ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); - ui_labelf("to open the lister for commands and options"); - } - } - scratch_end(scratch); - ProfEnd(); -} +RD_VIEW_UI_FUNCTION_DEF(null) {} //////////////////////////////// //~ rjf: watch @view_hook_impl -RD_VIEW_RULE_UI_FUNCTION_DEF(watch) +RD_VIEW_UI_FUNCTION_DEF(watch) { ProfBeginFunction(); RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); @@ -4170,136 +4009,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(watch) ProfEnd(); } -//////////////////////////////// -//~ rjf: pending_file @view_hook_impl - -typedef struct RD_PendingFileViewState RD_PendingFileViewState; -struct RD_PendingFileViewState -{ - Arena *deferred_cmd_arena; - RD_CmdList deferred_cmds; -}; - -RD_VIEW_RULE_UI_FUNCTION_DEF(pending_file) -{ - Temp scratch = scratch_begin(0, 0); - RD_PendingFileViewState *pves = rd_view_state(RD_PendingFileViewState); - if(pves->deferred_cmd_arena == 0) - { - pves->deferred_cmd_arena = rd_push_view_arena(); - } - rd_store_view_loading_info(1, 0, 0); - - ////////////////////////////// - //- rjf: process commands - // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) - { - // rjf: mismatched window/panel => skip - if(rd_regs()->view != cmd->regs->view) - { - continue; - } - - // rjf: process - RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); - switch(kind) - { - default:break; - - // rjf: gather deferred commands to redispatch when entity is ready - case RD_CmdKind_GoToLine: - case RD_CmdKind_GoToAddress: - case RD_CmdKind_CenterCursor: - case RD_CmdKind_ContainCursor: - { - rd_cmd_list_push_new(pves->deferred_cmd_arena, &pves->deferred_cmds, cmd->name, cmd->regs); - }break; - } - } - - //- rjf: determine if file is ready, and which viewer to use - String8 expr_string = rd_view_expr_string(); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr_string); - Rng1U64 file_range = r1u64(0, 1024); - U128 file_hash = fs_hash_from_path_range(file_path, file_range, 0); - B32 file_is_ready = 0; - RD_ViewRuleKind viewer_kind = RD_ViewRuleKind_Text; - { - HS_Scope *hs_scope = hs_scope_open(); - String8 data = hs_data_from_hash(hs_scope, file_hash); - if(!u128_match(file_hash, u128_zero())) - { - U64 num_utf8_bytes = 0; - U64 num_unknown_bytes = 0; - for(U64 idx = 0; idx < data.size && idx < file_range.max;) - { - UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); - if(decode.codepoint != max_U32 && (decode.inc > 1 || - (10 <= decode.codepoint && decode.codepoint <= 13) || - (32 <= decode.codepoint && decode.codepoint <= 126))) - { - num_utf8_bytes += decode.inc; - idx += decode.inc; - } - else - { - num_unknown_bytes += 1; - idx += 1; - } - } - file_is_ready = 1; - if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) - { - viewer_kind = RD_ViewRuleKind_Text; - } - else - { - viewer_kind = RD_ViewRuleKind_Memory; - } - } - hs_scope_close(hs_scope); - } - - //- rjf: if file is ready, dispatch all deferred commands - if(file_is_ready) - { - for(RD_CmdNode *cmd_node = pves->deferred_cmds.first; cmd_node != 0; cmd_node = cmd_node->next) - { - RD_Cmd *cmd = &cmd_node->cmd; - rd_push_cmd(cmd->name, cmd->regs); - } - arena_clear(pves->deferred_cmd_arena); - MemoryZeroStruct(&pves->deferred_cmds); - } - - //- rjf: if file is ready, move params tree to scratch for new command -#if 0 // TODO(rjf): @cfg - MD_Node *params_copy = &md_nil_node; - if(file_is_ready) - { - params_copy = md_tree_copy(scratch.arena, params); - } - - //- rjf: if file is ready, replace this view with the correct one, if any viewer is specified - if(file_is_ready && viewer_kind != RD_ViewRuleKind_Null) - { - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_kind(viewer_kind); - String8 query = rd_eval_string_from_file_path(scratch.arena, file_path); - RD_View *view = rd_view_from_handle(rd_regs()->view); - rd_view_equip_spec(view, view_rule_info, query, params_copy); - } -#endif - - //- rjf: if entity is ready, but we have no viewer for it, then just close this tab - if(file_is_ready && viewer_kind == RD_ViewRuleKind_Null) - { - rd_cmd(RD_CmdKind_CloseTab); - } - - scratch_end(scratch); -} - //////////////////////////////// //~ rjf: text @view_hook_impl @@ -4311,7 +4020,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(text) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(text) +RD_VIEW_UI_FUNCTION_DEF(text) { RD_CodeViewState *cv = rd_view_state(RD_CodeViewState); rd_code_view_init(cv); @@ -4329,15 +4038,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: process code-file commands // - ProfScope("process code-file commands") for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + ProfScope("process code-file commands") for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(rd_regs()->view != cmd->regs->view) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -4364,30 +4066,23 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) //- rjf: unpack parameterization info // ProfBegin("unpack parameterization info"); - String8 path = rd_file_path_from_eval_string(rd_frame_arena(), string); - rd_regs()->file_path = path; rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; - rd_regs()->cursor.line = rd_value_from_params_key(params, str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_value_from_params_key(params, str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_value_from_params_key(params, str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_value_from_params_key(params, str8_lit("mark_column")).s64; + rd_regs()->cursor.line = rd_view_cfg_value_from_string(str8_lit("cursor_line")).s64; + rd_regs()->cursor.column = rd_view_cfg_value_from_string(str8_lit("cursor_column")).s64; + rd_regs()->mark.line = rd_view_cfg_value_from_string(str8_lit("mark_line")).s64; + rd_regs()->mark.column = rd_view_cfg_value_from_string(str8_lit("mark_column")).s64; if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } - if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } - if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - E_Eval eval = e_eval_from_string(scratch.arena, string); - Rng1U64 range = rd_range_from_eval_params(eval, params); + if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } + if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } + Rng1U64 range = rd_range_from_eval_tag(eval, tag); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval_params(eval, params); - if(rd_regs()->lang_kind == TXT_LangKind_Null && path.size != 0) - { - rd_regs()->lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(path)); - } + rd_regs()->lang_kind = rd_lang_kind_from_eval_tag(eval, tag); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); - B32 file_is_missing = (path.size != 0 && os_properties_from_file_path(path).modified == 0); + B32 file_is_missing = (rd_regs()->file_path.size != 0 && os_properties_from_file_path(rd_regs()->file_path).modified == 0); B32 key_has_data = !u128_match(hash, u128_zero()) && info.lines_count; ProfEnd(); @@ -4405,7 +4100,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) { RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); - ui_labelf("Could not find \"%S\".", path); + ui_labelf("Could not find \"%S\".", rd_regs()->file_path); } UI_PrefHeight(ui_em(3, 1)) UI_Row UI_Padding(ui_pct(1, 0)) @@ -4444,11 +4139,11 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: unpack cursor info // - if(path.size != 0) + if(rd_regs()->file_path.size != 0) { CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, path, rd_regs()->cursor.line); + rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line); } ////////////////////////////// @@ -4457,7 +4152,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) B32 file_is_out_of_date = 0; String8 out_of_date_dbgi_name = {0}; { - U64 file_timestamp = fs_timestamp_from_path(path); + U64 file_timestamp = fs_timestamp_from_path(rd_regs()->file_path); if(file_timestamp != 0) { for(DI_KeyNode *n = dbgi_keys.first; n != 0; n = n->next) @@ -4512,9 +4207,9 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(text) } RD_Font(RD_FontSlot_Code) { - if(path.size != 0) + if(rd_regs()->file_path.size != 0) { - ui_label(path); + ui_label(rd_regs()->file_path); ui_spacer(ui_em(1.5f, 1)); } ui_labelf("Line: %I64d, Column: %I64d", rd_regs()->cursor.line, rd_regs()->cursor.column); @@ -4566,7 +4261,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) +RD_VIEW_UI_FUNCTION_DEF(disasm) { RD_DisasmViewState *dv = rd_view_state(RD_DisasmViewState); if(dv->initialized == 0) @@ -4591,19 +4286,19 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) // B32 auto_selected = 0; E_Space auto_space = {0}; - if(string.size == 0) + if(eval.space.kind == E_SpaceKind_Null) { if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); - string = push_str8f(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); + eval = e_eval_from_stringf(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); } else { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); - string = str8_lit("(rip.u64 & (~(0x4000 - 1)))"); + eval = e_eval_from_stringf(scratch.arena, "(rip.u64 & (~(0x4000 - 1)))"); } } @@ -4620,15 +4315,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) ////////////////////////////// //- rjf: process disassembly-specific commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(rd_regs()->view != cmd->regs->view) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -4648,7 +4336,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(disasm) ////////////////////////////// //- rjf: unpack parameterization info // - E_Eval eval = e_eval_from_string(scratch.arena, string); E_Space space = eval.space; if(auto_selected) { @@ -4791,7 +4478,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(memory) +RD_VIEW_UI_FUNCTION_DEF(memory) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -4801,7 +4488,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - E_Eval eval = e_eval_from_string(scratch.arena, string); Rng1U64 space_range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); if(eval.space.kind == 0) { @@ -4827,15 +4513,8 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: process commands // - for(RD_Cmd *cmd = 0; rd_next_cmd(&cmd);) + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - // rjf: mismatched window/panel => skip - if(rd_regs()->view != cmd->regs->view) - { - continue; - } - - // rjf: process RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); switch(kind) { @@ -5718,7 +5397,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) +RD_VIEW_UI_FUNCTION_DEF(bitmap) { Temp scratch = scratch_begin(0, 0); HS_Scope *hs_scope = hs_scope_open(); @@ -5727,7 +5406,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - E_Eval eval = e_eval_from_string(scratch.arena, string); Vec2S32 dim = {0}; // TODO(rjf): @cfg rd_dim2s32_from_eval_params(eval, params); R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; // TODO(rjf): @cfg rd_tex2dformat_from_eval_params(eval, params); U64 base_offset = rd_base_offset_from_eval(eval); @@ -5921,16 +5599,13 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(bitmap) //////////////////////////////// //~ rjf: "checkbox" -RD_VIEW_RULE_UI_FUNCTION_DEF(checkbox) +RD_VIEW_UI_FUNCTION_DEF(checkbox) { - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, string); E_Eval value_eval = e_value_eval_from_eval(eval); if(ui_clicked(rd_icon_buttonf(value_eval.value.u64 == 0 ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled, 0, "###check"))) { rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0"), 0); } - scratch_end(scratch); } //////////////////////////////// @@ -5966,12 +5641,11 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(color_rgba) +RD_VIEW_UI_FUNCTION_DEF(color_rgba) { Temp scratch = scratch_begin(0, 0); Vec2F32 dim = dim_2f32(rect); F32 padding = ui_top_font_size()*3.f; - E_Eval eval = e_eval_from_string(scratch.arena, string); Vec4F32 rgba = {0}; // TODO(rjf): @cfg rd_rgba_from_eval_params(eval, params); Vec4F32 hsva = hsva_from_rgba(rgba); @@ -6127,7 +5801,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d) return info; } -RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) +RD_VIEW_UI_FUNCTION_DEF(geo3d) { Temp scratch = scratch_begin(0, 0); GEO_Scope *geo_scope = geo_scope_open(); @@ -6146,7 +5820,6 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: evaluate & unpack expression // - E_Eval eval = e_eval_from_string(scratch.arena, string); U64 base_offset = rd_base_offset_from_eval(eval); Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32)); Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 36744ed0..c3f22abd 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -235,4 +235,19 @@ internal void rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewCo internal void rd_watch_view_init(RD_WatchViewState *ewv); internal void rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect); +//////////////////////////////// +//~ rjf: View Hooks + +// TODO(rjf): @cfg eliminate once we are predeclaring these with metacode + +RD_VIEW_UI_FUNCTION_DEF(null); +RD_VIEW_UI_FUNCTION_DEF(watch); +RD_VIEW_UI_FUNCTION_DEF(text); +RD_VIEW_UI_FUNCTION_DEF(disasm); +RD_VIEW_UI_FUNCTION_DEF(memory); +RD_VIEW_UI_FUNCTION_DEF(bitmap); +RD_VIEW_UI_FUNCTION_DEF(checkbox); +RD_VIEW_UI_FUNCTION_DEF(color_rgba); +RD_VIEW_UI_FUNCTION_DEF(geo3d); + #endif // RADDBG_VIEWS_H From 412c55a474f87d91304a2592e21096b177d20e4d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 7 Feb 2025 11:40:49 -0800 Subject: [PATCH 071/755] plug in visualizer view ui rules in new eval viz code; cfg-tree/vocab-driven tab titles --- src/eval/eval_parse.c | 9 +- src/eval/eval_parse.h | 1 + .../eval_visualization_core.h | 1 + src/raddbg/generated/raddbg.meta.c | 14 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 12 ++ src/raddbg/raddbg_core.c | 143 +++++++++++++++--- src/raddbg/raddbg_core.h | 4 + src/raddbg/raddbg_views.c | 33 +++- src/raddbg/raddbg_views.h | 11 ++ 10 files changed, 197 insertions(+), 33 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index daccd7f7..cacbdd1b 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1924,7 +1924,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } }break; - // rjf: string => leaf string literal, or file path + //- rjf: string => leaf string literal, or file path case E_TokenKind_StringLiteral: { if(str8_match(resolution_qualifier, str8_lit("file"), 0)) @@ -1944,7 +1944,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; } }break; - + } + + //- rjf: upgrade atom w/ qualifier + if(resolution_qualifier.size != 0) + { + atom->qualifier = resolution_qualifier; } } } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 7e0fcaf6..2b57c552 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -64,6 +64,7 @@ struct E_Expr E_TypeKey type_key; E_Value value; String8 string; + String8 qualifier; String8 bytecode; }; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 14548ec9..0eab57a5 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -318,6 +318,7 @@ internal void ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_ //~ rjf: View Rule Info Table Building / Selection / Lookups internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info); +#define ev_expand_rule_table_push_new(arena, table, ...) ev_expand_rule_table_push((arena), (table), &(EV_ExpandRule){__VA_ARGS__}) internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b20c50db..ab3d1b0a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,7 +28,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[45] = +RD_VocabularyInfo rd_vocabulary_info_table[57] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -75,6 +75,18 @@ RD_VocabularyInfo rd_vocabulary_info_table[45] = {str8_lit_comp("process"), str8_lit_comp("processes"), str8_lit_comp("Process"), str8_lit_comp("Processes"), RD_IconKind_Threads}, {str8_lit_comp("machine"), str8_lit_comp("machines"), str8_lit_comp("Machine"), str8_lit_comp("Machines"), RD_IconKind_Machine}, {str8_lit_comp("module"), str8_lit_comp("modules"), str8_lit_comp("Module"), str8_lit_comp("Modules"), RD_IconKind_Module}, +{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, +{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("type"), str8_lit_comp("types"), str8_lit_comp("Type"), str8_lit_comp("Types"), RD_IconKind_Null}, +{str8_lit_comp("procedure"), str8_lit_comp("procedures"), str8_lit_comp("Procedure"), str8_lit_comp("Procedures"), RD_IconKind_Null}, +{str8_lit_comp("global_variable"), str8_lit_comp("global_variables"), str8_lit_comp("Global Variable"), str8_lit_comp("Global Variables"), RD_IconKind_Null}, +{str8_lit_comp("global"), str8_lit_comp("globals"), str8_lit_comp("Global"), str8_lit_comp("Globals"), RD_IconKind_Null}, +{str8_lit_comp("thread_variable"), str8_lit_comp("thread_variables"), str8_lit_comp("Thread Variable"), str8_lit_comp("Thread Variables"), RD_IconKind_Null}, +{str8_lit_comp("thread_local"), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Local"), str8_lit_comp("Thread Locals"), RD_IconKind_Null}, +{str8_lit_comp("call_stack"), str8_lit_comp("call_stacks"), str8_lit_comp("Call Stack"), str8_lit_comp("Call Stacks"), RD_IconKind_Thread}, +{str8_lit_comp("output"), str8_lit_comp("outputs"), str8_lit_comp("Output"), str8_lit_comp("Outputs"), RD_IconKind_List}, +{str8_lit_comp("scheduler"), str8_lit_comp("schedulers"), str8_lit_comp("Scheduler"), str8_lit_comp("Schedulers"), RD_IconKind_Scheduler}, }; RD_NameSchemaInfo rd_name_schema_info_table[10] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 7de4f395..3afe1eec 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -570,7 +570,7 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[45]; +extern RD_VocabularyInfo rd_vocabulary_info_table[57]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index ec0bf8a1..8c8e17a3 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -96,6 +96,18 @@ RD_VocabularyMap: {process processes "Process" "Processes" Threads } {machine _ "Machine" _ Machine } {module _ "Module" _ Module } + {getting_started "" "Getting Started" "" QuestionMark } + {disasm "" "Disassembly" "" Glasses } + {text "" "Text" "" FileOutline } + {type _ "Type" _ Null } + {procedure _ "Procedure" _ Null } + {global_variable _ "Global Variable" _ Null } + {global _ "Global" _ Null } + {thread_variable _ "Thread Variable" _ Null } + {thread_local _ "Thread Local" _ Null } + {call_stack _ "Call Stack" _ Thread } + {output _ "Output" _ List } + {scheduler _ "Scheduler" _ Scheduler } } @struct RD_VocabularyInfo: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f9c6a537..f9bd7907 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1137,6 +1137,14 @@ rd_location_from_cfg(RD_Cfg *cfg) return dst_loc; } +internal String8 +rd_label_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *label_root = rd_cfg_child_from_string(cfg, str8_lit("label")); + String8 result = label_root->first->string; + return result; +} + internal String8 rd_expr_from_cfg(RD_Cfg *cfg) { @@ -1176,6 +1184,10 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 B32 is_disabled = rd_disabled_from_cfg(cfg); RD_Location loc = rd_location_from_cfg(cfg); D_Target target = rd_target_from_cfg(scratch.arena, cfg); + String8 label_string = rd_label_from_cfg(cfg); + String8 expr_string = rd_expr_from_cfg(cfg); + String8 collection_name = {0}; + String8 file_path = {0}; Vec4F32 rgba = rd_rgba_from_cfg(cfg); if(rgba.w == 0) { @@ -1194,6 +1206,45 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 } } } + B32 is_within_window = 0; + { + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("window"), 0)) + { + is_within_window = 1; + break; + } + } + } + if(expr_string.size != 0) + { + String8 query_name = rd_query_from_eval_string(arena, expr_string); + if(query_name.size != 0) + { + String8 query_code_name = query_name; + String8 query_display_name = rd_display_from_code_name(query_code_name); + collection_name = query_display_name; + if(query_display_name.size == 0) + { + query_code_name = rd_singular_from_code_name_plural(query_name); + collection_name = rd_display_plural_from_code_name(query_code_name); + } + RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); + if(query_icon_kind != RD_IconKind_Null) + { + icon_kind = query_icon_kind; + } + } + else + { + file_path = rd_file_path_from_eval_string(arena, expr_string); + if(file_path.size != 0) + { + icon_kind = RD_IconKind_FileOutline; + } + } + } //- rjf: set up color/size for all parts of the title // @@ -1223,24 +1274,44 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); } - //- rjf: push label + //- rjf: push view title, if from window, and no file path + if(is_within_window && file_path.size == 0 && collection_name.size == 0) { - String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; - if(label.size != 0) + String8 view_display_name = rd_display_from_code_name(cfg->string); + if(view_display_name.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, label); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, view_display_name); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); start_secondary(); } } - //- rjf: push expression + //- rjf: push label + if(label_string.size != 0) { - String8 expr = rd_cfg_child_from_string(cfg, str8_lit("expression"))->first->string; - if(expr.size != 0) - { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, expr); - start_secondary(); - } + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, label_string); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push expression + if(collection_name.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, collection_name); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + start_secondary(); + } + else if(file_path.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, file_path); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + start_secondary(); + } + else if(expr_string.size != 0) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, expr_string); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + start_secondary(); } //- rjf: push text location @@ -2578,10 +2649,10 @@ rd_file_path_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_string(scratch.arena, string); - if(eval.expr->kind == E_ExprKind_LeafFilePath) + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string); + if(expr->kind == E_ExprKind_LeafFilePath) { - result = raw_from_escaped_str8(arena, eval.expr->string); + result = raw_from_escaped_str8(arena, expr->string); } scratch_end(scratch); } @@ -2598,6 +2669,25 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) return result; } +//- rjf: eval -> query + +internal String8 +rd_query_from_eval_string(Arena *arena, String8 string) +{ + String8 result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string); + if(expr->kind == E_ExprKind_LeafIdent && + str8_match(expr->qualifier, str8_lit("query"), 0)) + { + result = expr->string; + } + scratch_end(scratch); + } + return result; +} + //////////////////////////////// //~ rjf: View Functions @@ -12959,7 +13049,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output_log"), expr); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output"), expr); hs_scope_close(hs_scope); } @@ -13025,21 +13115,26 @@ rd_frame(void) { String8 name; RD_ViewUIFunctionType *ui; + EV_ExpandRuleInfoHookFunctionType *expand; } table[] = { - {str8_lit("watch"), RD_VIEW_UI_FUNCTION_NAME(watch)}, - {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text)}, - {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm)}, - {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory)}, - {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox)}, - {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d)}, + {str8_lit("watch"), RD_VIEW_UI_FUNCTION_NAME(watch), EV_EXPAND_RULE_INFO_FUNCTION_NAME(watch)}, + {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; for EachElement(idx, table) { rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, table[idx].name, table[idx].ui); + if(table[idx].expand != 0) + { + ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, table[idx].name, table[idx].expand); + } } } @@ -14321,7 +14416,7 @@ X(watch_pins)\ X(targets)\ X(scheduler)\ X(modules)\ -Y(output, text, "query:output_log")\ +Y(output, text, "query:output")\ Y(disasm, disasm, "")\ Y(memory, memory, "")\ Z(getting_started) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ab55cf8e..2098ca47 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1019,6 +1019,7 @@ internal Vec4F32 rd_rgba_from_cfg(RD_Cfg *cfg); internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); +internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); @@ -1094,6 +1095,9 @@ internal R_Tex2DFormat rd_tex2dformat_from_eval_params(E_Eval eval, MD_Node *par internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); +//- rjf: eval -> query +internal String8 rd_query_from_eval_string(Arena *arena, String8 string); + //////////////////////////////// //~ rjf: View Functions diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index c25e69e3..015b18a2 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -909,6 +909,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .group_cfg = &rd_nil_cfg, .group_entity = &ctrl_entity_nil, .callstack_thread = &ctrl_entity_nil, + .view_ui_rule = &rd_nil_view_ui_rule, }; { Temp scratch = scratch_begin(&arena, 1); @@ -964,12 +965,26 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.group_cfg = rd_cfg_from_id(id); } + // rjf: determine view ui rule + info.view_ui_rule = rd_view_ui_rule_from_string(row->block->expand_rule->string); + // rjf: fill row's cells - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.35f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .pct = 0.25f); - // rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("sizeof($expr)"), .pct = 0.15f); + { + // rjf: singular cell for view ui + if(info.view_ui_rule != &rd_nil_view_ui_rule) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); + } + + // rjf: default cells + else + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.35f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .pct = 0.25f); + } + } di_scope_close(di_scope); scratch_end(scratch); @@ -3993,6 +4008,14 @@ RD_VIEW_UI_FUNCTION_DEF(null) {} //////////////////////////////// //~ rjf: watch @view_hook_impl +EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch) +{ + EV_ExpandInfo info = {0}; + info.row_count = 8; + info.single_item = 1; + return info; +} + RD_VIEW_UI_FUNCTION_DEF(watch) { ProfBeginFunction(); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index c3f22abd..e466ea19 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -46,6 +46,7 @@ typedef enum RD_WatchCellKind RD_WatchCellKind_Expr, // strings to represent expression itself RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` + RD_WatchCellKind_ViewUI, } RD_WatchCellKind; @@ -78,6 +79,7 @@ struct RD_WatchRowInfo U64 callstack_unwind_index; U64 callstack_inline_depth; RD_WatchCellList cells; + RD_ViewUIRule *view_ui_rule; }; typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; @@ -241,6 +243,15 @@ internal void rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect); // TODO(rjf): @cfg eliminate once we are predeclaring these with metacode RD_VIEW_UI_FUNCTION_DEF(null); + +EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); + RD_VIEW_UI_FUNCTION_DEF(watch); RD_VIEW_UI_FUNCTION_DEF(text); RD_VIEW_UI_FUNCTION_DEF(disasm); From 3582ab10e227c3bb08ff16c3a1f0bf657398e367 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 7 Feb 2025 12:45:30 -0800 Subject: [PATCH 072/755] eliminate old watch view column state; plug in on-the-fly computed per-row cells; eliminate old table helper usage in watch window; plug in visualizers to watch window --- .../eval_visualization_core.c | 3 +- src/raddbg/generated/raddbg.meta.c | 5 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 3 + src/raddbg/raddbg_views.c | 3074 ++++++++--------- src/raddbg/raddbg_views.h | 24 +- 6 files changed, 1540 insertions(+), 1571 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index e131bf31..719e85d2 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -950,7 +950,8 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - if(n->v.block->lookup_rule == &e_lookup_rule__nil) + if(n->v.block->lookup_rule == &e_lookup_rule__nil || + n->v.block->single_item) { is_root = 1; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index ab3d1b0a..47ded9cf 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,7 +28,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[57] = +RD_VocabularyInfo rd_vocabulary_info_table[60] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -87,6 +87,9 @@ RD_VocabularyInfo rd_vocabulary_info_table[57] = {str8_lit_comp("call_stack"), str8_lit_comp("call_stacks"), str8_lit_comp("Call Stack"), str8_lit_comp("Call Stacks"), RD_IconKind_Thread}, {str8_lit_comp("output"), str8_lit_comp("outputs"), str8_lit_comp("Output"), str8_lit_comp("Outputs"), RD_IconKind_List}, {str8_lit_comp("scheduler"), str8_lit_comp("schedulers"), str8_lit_comp("Scheduler"), str8_lit_comp("Schedulers"), RD_IconKind_Scheduler}, +{str8_lit_comp("register"), str8_lit_comp("registers"), str8_lit_comp("Register"), str8_lit_comp("Registers"), RD_IconKind_Null}, +{str8_lit_comp("local"), str8_lit_comp("locals"), str8_lit_comp("Local"), str8_lit_comp("Locals"), RD_IconKind_Null}, +{str8_lit_comp("memory"), str8_lit_comp("memories"), str8_lit_comp("Memory"), str8_lit_comp("Memories"), RD_IconKind_Grid}, }; RD_NameSchemaInfo rd_name_schema_info_table[10] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3afe1eec..1ea0df18 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -570,7 +570,7 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[57]; +extern RD_VocabularyInfo rd_vocabulary_info_table[60]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8c8e17a3..57079711 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -108,6 +108,9 @@ RD_VocabularyMap: {call_stack _ "Call Stack" _ Thread } {output _ "Output" _ List } {scheduler _ "Scheduler" _ Scheduler } + {register _ "Register" _ Null } + {local _ "Local" _ Null } + {memory memories "Memory" "Memories" Grid } } @struct RD_VocabularyInfo: diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 015b18a2..be714f74 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -816,24 +816,6 @@ rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell return cell; } -//- rjf: index -> column - -internal RD_WatchViewColumn * -rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index) -{ - RD_WatchViewColumn *result = wv->first_column; - S64 idx = 0; - for(RD_WatchViewColumn *c = wv->first_column; c != 0; c = c->next, idx += 1) - { - result = c; - if(idx == index) - { - break; - } - } - return result; -} - //- rjf: watch view points <-> table coordinates internal B32 @@ -910,6 +892,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .group_entity = &ctrl_entity_nil, .callstack_thread = &ctrl_entity_nil, .view_ui_rule = &rd_nil_view_ui_rule, + .view_ui_tag = &e_expr_nil, }; { Temp scratch = scratch_begin(&arena, 1); @@ -967,6 +950,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: determine view ui rule info.view_ui_rule = rd_view_ui_rule_from_string(row->block->expand_rule->string); + if(info.view_ui_rule != &rd_nil_view_ui_rule) + { + info.view_ui_tag = row->block->expand_tag; + } // rjf: fill row's cells { @@ -1119,8 +1106,12 @@ internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { RD_WatchRowCellInfo result = {0}; + result.view_ui_rule = &rd_nil_view_ui_rule; + result.view_ui_tag = &e_expr_nil; switch(cell->kind) { + default:{}break; + //- rjf: expression cells -> if no string attached to row itself, form one from the // expression tree. case RD_WatchCellKind_Expr: @@ -1230,6 +1221,14 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.string = ev_view_rule_from_key(ev_view, row->key); result.can_edit = 1; }break; + + //- rjf: view ui cells + case RD_WatchCellKind_ViewUI: + { + result.eval = e_eval_from_expr(arena, row->expr); + result.view_ui_rule = row_info->view_ui_rule; + result.view_ui_tag = row_info->view_ui_tag; + }break; } return result; } @@ -1457,62 +1456,44 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt) return result; } -//- rjf: watch view column state mutation - -internal RD_WatchViewColumn * -rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params) -{ - if(!wv->free_column) - { - RD_WatchViewColumn *col = push_array(wv->column_arena, RD_WatchViewColumn, 1); - SLLStackPush(wv->free_column, col); - } - RD_WatchViewColumn *col = wv->free_column; - SLLStackPop(wv->free_column); - DLLPushBack(wv->first_column, wv->last_column, col); - wv->column_count += 1; - col->kind = kind; - col->pct = pct; - col->string_size = Min(sizeof(col->string_buffer), params->string.size); - MemoryCopy(col->string_buffer, params->string.str, col->string_size); - col->display_string_size = Min(sizeof(col->display_string_buffer), params->display_string.size); - MemoryCopy(col->display_string_buffer, params->display_string.str, col->display_string_size); - col->view_rule_size = Min(sizeof(col->view_rule_buffer), params->view_rule.size); - MemoryCopy(col->view_rule_buffer, params->view_rule.str, col->view_rule_size); - col->is_non_code = params->is_non_code; - col->dequote_string = params->dequote_string; - col->rangify_braces = params->rangify_braces; - return col; -} - -internal void -rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewColumn *col) -{ - DLLRemove(wv->first_column, wv->last_column, col); - SLLStackPush(wv->free_column, col); - wv->column_count -= 1; -} - //- rjf: watch view main hooks -internal void -rd_watch_view_init(RD_WatchViewState *ewv) -{ - if(ewv->initialized == 0) - { - ewv->initialized = 1; - ewv->column_arena = rd_push_view_arena(); - ewv->text_edit_arena = rd_push_view_arena(); - } -} - internal void rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) { ProfBeginFunction(); + + ProfEnd(); +} + +//////////////////////////////// +//~ rjf: null @view_hook_impl + +RD_VIEW_UI_FUNCTION_DEF(null) {} + +//////////////////////////////// +//~ rjf: watch @view_hook_impl + +EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch) +{ + EV_ExpandInfo info = {0}; + info.row_count = 8; + info.single_item = 1; + return info; +} + +RD_VIEW_UI_FUNCTION_DEF(watch) +{ + ProfBeginFunction(); + RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + if(ewv->initialized == 0) + { + ewv->initialized = 1; + ewv->text_edit_arena = rd_push_view_arena(); + } ////////////////////////////// //- rjf: unpack arguments @@ -2390,22 +2371,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) B32 pressed = 0; ProfScope("build ui") { - F32 **col_pcts = push_array(scratch.arena, F32*, ewv->column_count); - { - S64 x = 0; - for(RD_WatchViewColumn *c = ewv->first_column; c != 0; c = c->next, x += 1) - { - col_pcts[x] = &c->pct; - } - } Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; { scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); + scroll_list_params.row_height_px = row_height_px; scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(ewv->column_count-1, block_tree.total_item_count)); - scroll_list_params.item_range = r1s64(0, block_tree.total_row_count); + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); + scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; scroll_list_params.row_blocks = row_blocks; } @@ -2422,983 +2395,133 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) &visible_row_rng, &scroll_list_sig) UI_Focus(UI_FocusKind_Null) - UI_TableF(ewv->column_count, col_pcts, "table") { - Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; - - //////////////////////////// - //- rjf: viz blocks -> rows - // - EV_WindowedRowList rows = {0}; + ui_set_next_pref_height(ui_children_sum(1)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); + UI_Parent(table) { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); - } - - //////////////////////////// - //- rjf: build table - // - ProfScope("build table") - { - U64 global_row_idx = rows.count_before_semantic; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) + Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; + + //////////////////////////// + //- rjf: viz blocks -> rows + // + EV_WindowedRowList rows = {0}; { - //////////////////////// - //- rjf: unpack row info - // - ProfBegin("unpack row info"); - EV_Row *row = &row_node->row; - U64 row_hash = ev_hash_from_key(row->key); - U64 row_depth = ev_depth_from_block(row->block); - B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); - B32 row_expanded = ev_expansion_from_key(eval_view, row->key); - B32 next_row_expanded = row_expanded; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - B32 row_is_expandable = ev_row_is_expandable(row); - if(implicit_root && row_depth > 0) + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); + } + + //////////////////////////// + //- rjf: build table + // + ProfScope("build table") + { + U64 global_row_idx = rows.count_before_semantic; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) { - row_depth -= 1; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine if row's data is fresh and/or bad - // - ProfBegin("determine if row's data is fresh and/or bad"); - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row_info.eval.mode) - { - default:{}break; - case E_Mode_Offset: + //////////////////////// + //- rjf: unpack row info + // + ProfBegin("unpack row info"); + EV_Row *row = &row_node->row; + U64 row_hash = ev_hash_from_key(row->key); + U64 row_depth = ev_depth_from_block(row->block); + B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); + B32 row_expanded = ev_expansion_from_key(eval_view, row->key); + B32 next_row_expanded = row_expanded; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + B32 row_is_expandable = ev_row_is_expandable(row); + if(implicit_root && row_depth > 0) { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info.eval.space); - if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row_info.eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_info.eval.value.u64, row_info.eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - {row_is_bad = 1; - } - } - } - }break; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine row's flags & color palette - // - ProfBegin("determine row's flags & color palette"); - UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; - UI_Palette *palette = ui_top_palette(); - { - if(row_is_fresh) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - row_flags |= UI_BoxFlag_DrawBackground; + row_depth -= 1; } - else if(global_row_idx & 1) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); - row_flags |= UI_BoxFlag_DrawBackground; - } -#if 0 // TODO(rjf): @cfg - switch(row_kind) + ProfEnd(); + + //////////////////////// + //- rjf: determine if row's data is fresh and/or bad + // + ProfBegin("determine if row's data is fresh and/or bad"); + B32 row_is_fresh = 0; + B32 row_is_bad = 0; + switch(row_info.eval.mode) { default:{}break; - case RD_WatchViewRowKind_Normal:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Header:{row_flags |= UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Canvas:{row_flags |= UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder;}break; - case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; + case E_Mode_Offset: + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info.eval.space); + if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + { + U64 size = e_type_byte_size_from_key(row_info.eval.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(row_info.eval.value.u64, row_info.eval.value.u64+size); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + row_is_fresh = 1; + } + if(slice.byte_bad_flags[idx] != 0) + {row_is_bad = 1; + } + } + } + }break; } -#endif - } - ProfEnd(); - - //////////////////////// - //- rjf: build row box - // - ui_set_next_palette(palette); - ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_px(scroll_list_params.row_height_px*row->visual_size, 1.f)); - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row_node->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); - ui_ts_vector_idx += 1; - ui_ts_cell_idx = 0; - - ////////////////////// - //- rjf: build row contents - // - RD_RegsScope(.module = row_info.module->handle) UI_Parent(row_box) - { - //////////////////// - //- rjf: draw start of cache lines in expansions + ProfEnd(); + + //////////////////////// + //- rjf: determine row's flags & color palette // + ProfBegin("determine row's flags & color palette"); + UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; + UI_Palette *palette = ui_top_palette(); { - U64 row_offset = row_info.eval.value.u64; - if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) + if(row_is_fresh) { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); + row_flags |= UI_BoxFlag_DrawBackground; } + else if(global_row_idx & 1) + { + palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); + row_flags |= UI_BoxFlag_DrawBackground; + } +#if 0 // TODO(rjf): @cfg + switch(row_kind) + { + default:{}break; + case RD_WatchViewRowKind_Normal:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; + case RD_WatchViewRowKind_Header:{row_flags |= UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DisableFocusOverlay;}break; + case RD_WatchViewRowKind_Canvas:{row_flags |= UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder;}break; + case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; + } +#endif } + ProfEnd(); - //////////////////// - //- rjf: draw mid-row cache line boundaries in expansions + //////////////////////// + //- rjf: build row box // - { - if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && - row_info.eval.value.u64%64 != 0 && - row_depth > 0 && - !row_expanded) - { - U64 next_off = (row_info.eval.value.u64 + e_type_byte_size_from_key(row_info.eval.type_key)); - if(next_off%64 != 0 && row_info.eval.value.u64/64 < next_off/64) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); - ui_set_next_fixed_height(ui_top_font_size()*1.f); - Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - boundary_color.w *= 0.5f; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } + ui_set_next_palette(palette); + ui_set_next_flags(disabled_flags); + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row_node->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); - //////////////////// - //- rjf: build all cells + ////////////////////// + //- rjf: build row contents // - S64 cell_x = 0; - F32 cell_x_px = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + RD_RegsScope(.module = row_info.module->handle) UI_Parent(row_box) { - //- rjf: unpack cell info - U64 cell_id = rd_id_from_watch_cell(cell); - RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - - //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); - UI_BoxFlags cell_flags = 0; - UI_Palette *palette = ui_top_palette(); - { - if(cell_info.is_errored) - { - palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(cell_info.inheritance_tooltip.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - } - ProfEnd(); - - //- rjf: build cell - UI_Signal sig = {0}; - ProfScope("build cell") - UI_Palette(palette) - UI_TableCell - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(RD_FontSlot_Code) - UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) - { - ui_set_next_flags(ui_top_flags() | cell_flags); - - // rjf: cell has errors? -> build error box - if(cell_info.is_errored) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_info.string); - } - } - - // rjf: cell has hook? -> build ui by calling hook - else if(cell_info.ui != 0) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); - UI_Parent(box) - { - String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_info.ui(row_expr, cell_info.ui_params, r2f32p(cell_x_px, 0, cell_x_px + cell->pct*dim_2f32(rect).x, row_height_px)); - } - sig = ui_signal_from_box(box); - } - - // rjf: build cell line edit - else - { - sig = rd_line_editf((RD_LineEditFlag_CodeContents| - RD_LineEditFlag_NoBackground| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)), - cell_x == 0 ? row_depth : 0, - 0, - &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_info.string, - "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); -#if 0 // TODO(rjf): @cfg - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); - } -#endif - } - } - - //- rjf: handle interactions - { - // rjf: single-click -> move selection here - if(ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: double-click actions - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) - { - ui_kill_action(); - - // rjf: has callstack info? -> select unwind - if(row_info.callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info.callstack_unwind_index, - .inline_depth = row_info.callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(cell_info.can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - - -#if 0 // TODO(rjf): @cfg - // rjf: can edit? -> begin editing - else if(cell_can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: cannot edit, has addr info? -> go to address - else if(row_kind == RD_WatchViewRowKind_Normal && - (col->kind == RD_WatchViewColumnKind_Value || - col->kind == RD_WatchViewColumnKind_Member) && - cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) - { - U64 vaddr = cell_eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - } - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } - } -#endif - } - - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_info.inheritance_tooltip); - } - } - - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); - } - } - - //- rjf: bump x pixel coordinate - cell_x_px += cell->pct*dim_2f32(rect).x; - - //- 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_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); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 ext = {0}; - switch(t->expr->kind) - { - default: - { - if(t->expr->string.size != 0) - { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: - { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; - } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) - { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); - } - } - } - } - } - - ////////////////////// - //- rjf: build row contents - // -#if 0 // TODO(rjf): @cfg - RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) switch(row_kind) - { - //////////////////// - //- rjf: header row - // - case RD_WatchViewRowKind_Header: - ProfScope("header row") - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next) - UI_TableCell - { - String8 name = str8(col->display_string_buffer, col->display_string_size); - if(name.size == 0) - { - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {name = str8_lit("Expression");}break; - case RD_WatchViewColumnKind_Value: {name = str8_lit("Value");}break; - case RD_WatchViewColumnKind_Type: {name = str8_lit("Type");}break; - case RD_WatchViewColumnKind_ViewRule:{name = str8_lit("View Rule");}break; - case RD_WatchViewColumnKind_Member: - { - name = str8(col->string_buffer, col->string_size); - }break; - } - } - switch(col->kind) - { - default: - { - ui_label(name); - }break; - case RD_WatchViewColumnKind_ViewRule: - { - if(rd_help_label(name)) UI_Tooltip - { - F32 max_width = ui_top_font_size()*35; - ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form. Some examples follow:")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("array:(N)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that a pointer points to N elements, rather than only 1.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("omit:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Omits a list of member names from appearing in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("only:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that only the specified members should appear in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); -#if 0 // TODO(rjf): disabling until post-0.9.12 - RD_Font(RD_FontSlot_Code) ui_labelf("list:(next_link_member_name)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that some struct, union, or class forms the top of a linked list, with next_link_member_name being the member which points at the next element in the list.")); - ui_spacer(ui_em(1.5f, 1)); -#endif - RD_Font(RD_FontSlot_Code) ui_labelf("dec"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-10 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("hex"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-16 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("oct"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-8 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("bin"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-2 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("no_addr"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Displays only what pointers point to, if possible, without the pointer's address value.")); - ui_spacer(ui_em(1.5f, 1)); - } - }break; - } - } - } - }break; - - //////////////////// - //- rjf: canvas row - // - case RD_WatchViewRowKind_Canvas: - ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) - { -#if 0 // TODO(rjf): @cfg - //- rjf: unpack - RD_WatchPt pt = {0, row->block->key, row->key}; - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); - RD_View *canvas_view = canvas_view_node->view; - String8 canvas_view_expr = e_string_from_expr(scratch.arena, row->expr); - B32 need_new_spec = (!str8_match(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view_expr, 0) || - !md_tree_match(canvas_view_node->initial_params, ui_view_rule_params_root, 0)); - if(need_new_spec) - { - arena_clear(canvas_view_node->initial_params_arena); - canvas_view_node->initial_params = md_tree_copy(canvas_view_node->initial_params_arena, ui_view_rule_params_root); - rd_view_equip_spec(canvas_view, ui_view_rule_info, canvas_view_expr, ui_view_rule_params_root); - } - Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f, - (row->visual_size_skipped+row->visual_size+row->visual_size_chopped)*scroll_list_params.row_height_px); - Rng2F32 canvas_rect = r2f32p(rect.x0, - rect.y0 + ui_top_fixed_y(), - rect.x0 + canvas_dim.x, - rect.y0 + ui_top_fixed_y() + canvas_dim.y); - - //- rjf: peek clicks in canvas region, mark clicked - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && evt->key == OS_Key_LeftMouseButton && contains_2f32(canvas_rect, evt->pos) && - contains_2f32(rect, evt->pos)) - { - pressed = 1; - break; - } - } - - //- rjf: build meta controls - ui_set_next_fixed_x(ui_top_font_size()*1.f); - ui_set_next_fixed_y(ui_top_font_size()*1.f + scroll_list_view_off_px.y*(row == rows.first)); - ui_set_next_pref_width(ui_em(3, 1)); - ui_set_next_pref_height(ui_em(3, 1)); - UI_Flags(UI_BoxFlag_DrawDropShadow) UI_CornerRadius(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_Window, 0, "###pop_out"); - if(ui_hovering(sig)) UI_Tooltip - { - ui_labelf("Pop out"); - } - if(ui_pressed(sig)) - { - pressed = 1; - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_OpenTab, - .string = e_string_from_expr(scratch.arena, row->expr), - .params_tree = ui_view_rule_params_root); - } - } - - //- rjf: build main column for canvas - ui_set_next_fixed_y(-1.f * (row->visual_size_skipped) * scroll_list_params.row_height_px); - ui_set_next_fixed_height((row->visual_size_skipped + row->visual_size + row->visual_size_chopped) * scroll_list_params.row_height_px); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *canvas_box = ui_build_box_from_stringf(UI_BoxFlag_FloatingY, "###canvas_%I64x", row_hash); - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - //- rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - //- rjf: push interaction registers, fill with per-view states - rd_push_regs(); - { - rd_regs()->view = rd_handle_from_view(canvas_view); - rd_regs()->file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(canvas_view->query_buffer, canvas_view->query_string_size)); - } - - //- rjf: build - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - { - ui_view_rule_info->ui(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view->params_roots[canvas_view->params_read_gen%ArrayCount(canvas_view->params_roots)], canvas_rect); - } - - //- rjf: loading overlay fill - UI_Parent(loading_overlay_container) - { - rd_loading_overlay(canvas_rect, canvas_view->loading_t, canvas_view->loading_progress_v, canvas_view->loading_progress_v_target); - } - - //- rjf: pop interaction registers - rd_pop_regs(); - } -#endif - }break; - - //////////////////// - //- rjf: pretty entity controls row - // - case RD_WatchViewRowKind_PrettyEntityControls: - ProfScope("pretty entity controls row") - { - //- rjf: unpack - RD_EntityKind collection_entity_kind = row_info.collection_entity_kind; - CTRL_EntityKind collection_ctrl_entity_kind = row_info.collection_ctrl_entity_kind; - RD_Entity *entity = row_info.collection_entity; - CTRL_Entity *ctrl_entity = row_info.collection_ctrl_entity; - B32 entity_box_selected = (row_selected && selection_tbl.min.x <= 1 && 1 <= selection_tbl.max.x); - B32 is_hovering = ((rd_handle_match(rd_state->hover_regs->entity, rd_handle_from_entity(entity)) && - rd_state->hover_regs_slot == RD_RegSlot_Entity) || - (ctrl_handle_match(rd_state->hover_regs->thread, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread) || - (ctrl_handle_match(rd_state->hover_regs->module, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Module) || - (ctrl_handle_match(rd_state->hover_regs->process, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Process)); - - //- rjf: pick palette - UI_Palette *palette = ui_build_palette(ui_top_palette()); - if(entity->kind == RD_EntityKind_Target && !entity->disabled) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else if(ctrl_entity->kind == CTRL_EntityKind_Thread && ctrl_handle_match(ctrl_entity->handle, rd_regs()->thread)) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else - { - palette->background = v4f32(0, 0, 0, 0); - } - - //- rjf: build indentation - for(U64 idx = 0; idx < row_depth; idx += 1) - { - ui_set_next_flags(UI_BoxFlag_DrawSideLeft); - ui_spacer(ui_em(1.f, 1.f)); - } - - //- rjf: build add-new buttons - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Target) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Breakpoint) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); - } - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 2 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_WatchPin) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_FilePathMap) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Add File Path Map"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_AutoViewRule) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Add Auto View Rule"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_AutoViewRule); - } - } - - //- rjf: build entity box - if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) - { - //- rjf: unpack entity info - DR_FancyStringList fstrs = {0}; - if(!rd_entity_is_nil(entity)) - { - fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); - } - else if(ctrl_entity != &ctrl_entity_nil) - { - fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); - } - String8 fstrs_string = dr_string_from_fancy_string_list(scratch.arena, &fstrs); - FuzzyMatchRangeList fstrs_matches = fuzzy_match_find(scratch.arena, filter, fstrs_string); - UI_Key hover_t_key = ui_key_from_stringf(ui_key_zero(), "entity_hover_t_%p_%p", entity, ctrl_entity); - F32 hover_t = ui_anim(hover_t_key, (F32)!!is_hovering, .rate = entity_hover_t_rate); - if(!rd_entity_is_nil(entity)) - { - palette->overlay = rd_rgba_from_entity(entity); - palette->overlay.w *= 0.3f; - } - else if(ctrl_entity != &ctrl_entity_nil) - { - palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); - palette->overlay.w *= 0.3f; - } - if(palette->overlay.x == 0 && palette->overlay.y == 0 && palette->overlay.z == 0 && palette->overlay.w == 0) - { - palette->overlay = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - } - palette->overlay.w *= hover_t; - - //- rjf: build - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *entity_box = &ui_nil_box; - UI_FocusHot(entity_box_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) - { - entity_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawOverlay| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawSideLeft| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects, - "###entity_%p_%p", entity, ctrl_entity); - } - { - UI_Parent(entity_box) RD_RegsScope(.entity = rd_handle_from_entity(entity)) - { - RD_RegSlot slot = RD_RegSlot_Entity; - switch(ctrl_entity->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{slot = RD_RegSlot_Machine; rd_regs()->machine = ctrl_entity->handle;}break; - case CTRL_EntityKind_Thread: {slot = RD_RegSlot_Thread; rd_regs()->thread = ctrl_entity->handle;}break; - case CTRL_EntityKind_Process:{slot = RD_RegSlot_Process; rd_regs()->process = ctrl_entity->handle;}break; - case CTRL_EntityKind_Module: {slot = RD_RegSlot_Module; rd_regs()->module = ctrl_entity->handle;}break; - } - UI_PrefWidth(ui_em(2.f, 1.f)) if(ui_pressed(ui_expander(row->block->rows_default_expanded ? !row_expanded : row_expanded, str8_lit("###expanded")))) - { - next_row_expanded = !row_expanded; - } - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &fstrs_matches); - UI_Signal sig = ui_signal_from_box(entity_box); - if(ui_hovering(sig)) - { - rd_set_hover_regs(slot); - } - if(ui_right_clicked(sig)) - { - rd_open_ctx_menu(entity_box->key, v2f32(0, dim_2f32(entity_box->rect).y), slot); - } - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) - { - rd_drag_begin(slot); - } - if(ui_pressed(sig)) - { - RD_WatchPt cell_pt = {1, row->block->key, row->key}; - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - if(ui_double_clicked(sig)) - { -#if 0 // TODO(rjf): @cfg - if(entity->kind == RD_EntityKind_Target) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - if(entity->kind == RD_EntityKind_Breakpoint || - entity->kind == RD_EntityKind_WatchPin) - { - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - rd_cmd(RD_CmdKind_FindCodeLocation, - .file_path = (loc->flags & RD_EntityFlag_HasTextPoint) ? loc->string : str8_zero(), - .cursor = loc->text_point, - .vaddr = loc->vaddr); - } -#endif - } - } - } - - //- rjf: build extra entity controls - UI_PrefWidth(ui_em(3.f, 1.f)) - { -#if 0 // TODO(rjf): @cfg - U64 ctrl_idx = 1; - for EachIndex(idx, row_ctrls_count) - { - RD_WatchViewRowCtrl *ctrl = &row_ctrls[idx]; - if(ctrl->entity_kind == entity->kind && - ctrl->ctrl_entity_kind == ctrl_entity->kind) - { - UI_FocusHot(row_selected && selection_tbl.min.x <= ctrl_idx+1 && ctrl_idx+1 <= selection_tbl.max.x ? UI_FocusKind_On : UI_FocusKind_Off) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); - RD_IconKind icon_kind = rd_cmd_kind_info_table[ctrl->kind].icon_kind; - UI_Palette *palette = ui_top_palette(); - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - icon_kind = entity->disabled ? RD_IconKind_RadioHollow : RD_IconKind_RadioFilled; - } - if(ctrl->kind == RD_CmdKind_EnableEntity) - { - icon_kind = entity->disabled ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled; - } - if(ctrl->kind == RD_CmdKind_SelectThread) - { - icon_kind = (ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread) ? RD_IconKind_RadioFilled : RD_IconKind_RadioHollow); - } - if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - icon_kind = is_frozen ? RD_IconKind_Locked : RD_IconKind_Unlocked; - palette = rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton); - } - UI_Palette(palette) - { - UI_Signal sig = rd_icon_buttonf(icon_kind, 0, "###row_ctrl_%I64x", idx); - if(ui_clicked(sig)) - { - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_EnableEntity) - { - rd_cmd(entity->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_SelectThread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - rd_cmd(is_frozen ? RD_CmdKind_ThawEntity : RD_CmdKind_FreezeEntity, - .ctrl_entity = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_Kill) - { - rd_cmd(RD_CmdKind_Kill, .process = ctrl_entity->handle); - } - else - { - rd_cmd(ctrl->kind, .entity = rd_handle_from_entity(entity)); - } - } - } - } - ctrl_idx += 1; - } - } -#endif - } - } - }break; - - //////////////////// - //- rjf: normal row - // - default: - case RD_WatchViewRowKind_Normal: - ProfScope("normal row") UI_HeightFill - { - ////////////////////// + //////////////////// //- rjf: draw start of cache lines in expansions // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + if(row_info.view_ui_rule == &rd_nil_view_ui_rule) { - U64 row_offset = row_eval.value.u64; - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + U64 row_offset = row_info.eval.value.u64; + if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && row_offset%64 == 0 && row_depth > 0) { ui_set_next_fixed_x(0); @@ -3409,21 +2532,21 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) } } - ////////////////////// + //////////////////// //- rjf: draw mid-row cache line boundaries in expansions // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + if(row_info.view_ui_rule == &rd_nil_view_ui_rule) { - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_eval.value.u64%64 != 0 && + if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && + row_info.eval.value.u64%64 != 0 && row_depth > 0 && !row_expanded) { - U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); - if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) + U64 next_off = (row_info.eval.value.u64 + e_type_byte_size_from_key(row_info.eval.type_key)); + if(next_off%64 != 0 && row_info.eval.value.u64/64 < next_off/64) { ui_set_next_fixed_x(0); - ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); ui_set_next_fixed_height(ui_top_font_size()*1.f); Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); boundary_color.w *= 0.5f; @@ -3433,117 +2556,1055 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) } } - ////////////////////// - //- rjf: build all columns + //////////////////// + //- rjf: build all cells // - ProfScope("build all columns") + S64 cell_x = 0; + F32 cell_x_px = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { - S64 x = 0; - F32 x_px = 0; - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) + //- rjf: unpack cell info + U64 cell_id = rd_id_from_watch_cell(cell); + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + + //- rjf: determine cell's palette + ProfBegin("determine cell's palette"); + UI_BoxFlags cell_flags = 0; + UI_Palette *palette = ui_top_palette(); { - //- rjf: unpack cell info - RD_WatchPt cell_pt = {x, row->block->key, row->key}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); - String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - - //- rjf: unpack column-kind-specific info - ProfBegin("unpack column-kind-specific info"); - E_Eval cell_eval = row_eval; - E_Type *cell_type = row_type; - B32 cell_can_edit = 0; - FuzzyMatchRangeList cell_matches = {0}; - String8 cell_inheritance_string = {0}; - String8 cell_error_string = {0}; - String8 cell_error_tooltip_string = {0}; - RD_ListerFlags cell_autocomp_flags = 0; - RD_ViewRuleUIFunctionType *cell_ui_hook = 0; - MD_Node *cell_ui_params = &md_nil_node; - Vec4F32 cell_base_color = ui_top_palette()->text; - RD_IconKind cell_icon = RD_IconKind_Null; - String8 cell_ghost_text = {0}; - switch(col->kind) + if(cell_info.is_errored) { - default:{}break; - case RD_WatchViewColumnKind_Expr: + palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); + cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(cell_info.inheritance_tooltip.size != 0) + { + palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); + cell_flags |= UI_BoxFlag_DrawBackground; + } + } + ProfEnd(); + + //- rjf: build cell + UI_Box *cell_box = &ui_nil_box; + UI_Palette(palette) + { + ui_set_next_fixed_height(row->visual_size * row_height_px); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft, "cell_%I64x_%I64x", row_hash, cell_id); + } + + //- rjf: build cell + UI_Signal sig = {0}; + ProfScope("build cell") + UI_Parent(cell_box) + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(RD_FontSlot_Code) + UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) + { + ui_set_next_flags(ui_top_flags() | cell_flags); + + // rjf: cell has errors? -> build error box + if(cell_info.is_errored) RD_Font(RD_FontSlot_Main) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + UI_Parent(box) UI_Flags(0) { - cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); - if(filter.size != 0) + rd_error_label(cell_info.string); + } + } + + // rjf: cell has hook? -> build ui by calling hook + else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + { + Rng2F32 cell_rect = r2f32p(cell_x_px, 0, cell_x_px + cell->pct*(dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)), row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); + ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); + UI_Parent(box) + { + RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.expr)); + rd_cfg_new(view, str8_lit("selected")); + RD_RegsScope(.panel = 0, .view = view->id) + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) { - cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); - } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(row->member != 0 && row->member->inheritance_key_chain.first != 0) - { - String8List inheritance_chain_type_names = {0}; - for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) + // rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_HeightFill { - String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); - inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); - str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); } - if(inheritance_chain_type_names.node_count != 0) + + // rjf: view ui contents + cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); + + // rjf: loading fill + UI_Parent(loading_overlay_container) { - StringJoin join = {0}; - join.sep = str8_lit("::"); - String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); - cell_inheritance_string = inheritance_type; + RD_ViewState *vs = rd_view_state_from_cfg(view); + rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); } } - }break; - case RD_WatchViewColumnKind_Value: + + } + sig = ui_signal_from_box(box); + } + + // rjf: build cell line edit + else + { + sig = rd_line_editf((RD_LineEditFlag_CodeContents| + RD_LineEditFlag_NoBackground| + RD_LineEditFlag_KeyboardClickable| + RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)), + cell_x == 0 ? row_depth : 0, + 0, + &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, + cell_info.string, + "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); +#if 0 // TODO(rjf): @cfg + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { - }goto value_cell; - case RD_WatchViewColumnKind_Member: + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } +#endif + } + } + + //- rjf: handle interactions + { + // rjf: single-click -> move selection here + if(ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: double-click actions + if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) + { + ui_kill_action(); + + // rjf: has callstack info? -> select unwind + if(row_info.callstack_thread != &ctrl_entity_nil) { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - cell_eval = e_eval_from_expr(scratch.arena, expr); - cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); - }goto value_cell; - value_cell:; + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info.callstack_unwind_index, + .inline_depth = row_info.callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(cell_info.can_edit) { - E_MsgList msgs = cell_eval.msgs; - if(row_depth == 0 && row->string.size != 0) + rd_cmd(RD_CmdKind_Edit); + } + + +#if 0 // TODO(rjf): @cfg + // rjf: can edit? -> begin editing + else if(cell_can_edit) + { + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: cannot edit, has addr info? -> go to address + else if(row_kind == RD_WatchViewRowKind_Normal && + (col->kind == RD_WatchViewColumnKind_Value || + col->kind == RD_WatchViewColumnKind_Member) && + cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); - e_msg_list_concat_in_place(&parse.msgs, &msgs); - msgs = parse.msgs; - } - if(msgs.max_kind > E_MsgKind_Null) - { - String8List strings = {0}; - for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) + U64 vaddr = cell_eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) { - str8_list_push(scratch.arena, &strings, msg->text); + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - cell_error_string = str8_list_join(scratch.arena, &strings, &join); + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); } - if(row_is_bad) + } +#endif + } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_info.inheritance_tooltip); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); + } + } + + //- rjf: bump x pixel coordinate + cell_x_px += cell->pct*dim_2f32(rect).x; + + //- 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_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); + } + + //- rjf: [DEV] hovering -> eval system tooltips + if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) + { + local_persist char *spaces = " "; + String8 string = ev_expr_string_from_row(scratch.arena, row, 0); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); + ui_label(string); + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); + for(U64 idx = 0; idx < tokens.count; idx += 1) + { + ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_Expr *expr; + S64 depth; + }; + Task start_task = {0, 0, parse.expr}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 ext = {0}; + switch(t->expr->kind) { - cell_error_tooltip_string = str8_lit("Could not read memory successfully."); + default: + { + if(t->expr->string.size != 0) + { + ext = push_str8f(scratch.arena, "'%S'", t->expr->string); + } + else if(t->expr->value.u32 != 0) + { + ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); + } + else if(t->expr->value.f32 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); + } + else if(t->expr->value.f64 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); + } + else if(t->expr->value.u64 != 0) + { + ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); + } + }break; } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(cell_type->flags & E_TypeFlag_IsPathText) + ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) { - cell_autocomp_flags = RD_ListerFlag_Files; + Task *task = push_array(scratch.arena, Task, 1); + task->expr = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); } - if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_IRNode *node; + S64 depth; + }; + Task start_task = {0, 0, irtree.root}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 op_string = {0}; + switch(t->node->op) { - cell_ui_hook = ui_view_rule_info->ui; - cell_ui_params = ui_view_rule_params_root; + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X } - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) + String8 ext = {0}; + ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); + for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->node = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); + { + for(E_Op *op = oplist.first; op != 0; op = op->next) + { + String8 op_string = {0}; + switch(op->opcode) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + switch(op->opcode) + { + case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; + default: + { + ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); + }break; + } + ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); + { + for(U64 idx = 0; idx < bytecode.size; idx += 1) + { + ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); + } + } + } + } + } + + ////////////////////// + //- rjf: build row contents + // +#if 0 // TODO(rjf): @cfg + RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) switch(row_kind) + { + //////////////////// + //- rjf: header row + // + case RD_WatchViewRowKind_Header: + ProfScope("header row") + { + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + { + for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next) + UI_TableCell + { + String8 name = str8(col->display_string_buffer, col->display_string_size); + if(name.size == 0) + { + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: {name = str8_lit("Expression");}break; + case RD_WatchViewColumnKind_Value: {name = str8_lit("Value");}break; + case RD_WatchViewColumnKind_Type: {name = str8_lit("Type");}break; + case RD_WatchViewColumnKind_ViewRule:{name = str8_lit("View Rule");}break; + case RD_WatchViewColumnKind_Member: + { + name = str8(col->string_buffer, col->string_size); + }break; + } + } + switch(col->kind) + { + default: + { + ui_label(name); + }break; + case RD_WatchViewColumnKind_ViewRule: + { + if(rd_help_label(name)) UI_Tooltip + { + F32 max_width = ui_top_font_size()*35; + ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form. Some examples follow:")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("array:(N)"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that a pointer points to N elements, rather than only 1.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("omit:(member_1 ... member_n)"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Omits a list of member names from appearing in struct, union, or class evaluations.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("only:(member_1 ... member_n)"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that only the specified members should appear in struct, union, or class evaluations.")); + ui_spacer(ui_em(1.5f, 1)); +#if 0 // TODO(rjf): disabling until post-0.9.12 + RD_Font(RD_FontSlot_Code) ui_labelf("list:(next_link_member_name)"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that some struct, union, or class forms the top of a linked list, with next_link_member_name being the member which points at the next element in the list.")); + ui_spacer(ui_em(1.5f, 1)); +#endif + RD_Font(RD_FontSlot_Code) ui_labelf("dec"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-10 form.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("hex"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-16 form.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("oct"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-8 form.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("bin"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-2 form.")); + ui_spacer(ui_em(1.5f, 1)); + RD_Font(RD_FontSlot_Code) ui_labelf("no_addr"); + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Displays only what pointers point to, if possible, without the pointer's address value.")); + ui_spacer(ui_em(1.5f, 1)); + } + }break; + } + } + } + }break; + + //////////////////// + //- rjf: canvas row + // + case RD_WatchViewRowKind_Canvas: + ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) + { +#if 0 // TODO(rjf): @cfg + //- rjf: unpack + RD_WatchPt pt = {0, row->block->key, row->key}; + RD_View *view = rd_view_from_handle(rd_regs()->view); + RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); + RD_View *canvas_view = canvas_view_node->view; + String8 canvas_view_expr = e_string_from_expr(scratch.arena, row->expr); + B32 need_new_spec = (!str8_match(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view_expr, 0) || + !md_tree_match(canvas_view_node->initial_params, ui_view_rule_params_root, 0)); + if(need_new_spec) + { + arena_clear(canvas_view_node->initial_params_arena); + canvas_view_node->initial_params = md_tree_copy(canvas_view_node->initial_params_arena, ui_view_rule_params_root); + rd_view_equip_spec(canvas_view, ui_view_rule_info, canvas_view_expr, ui_view_rule_params_root); + } + Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f, + (row->visual_size_skipped+row->visual_size+row->visual_size_chopped)*scroll_list_params.row_height_px); + Rng2F32 canvas_rect = r2f32p(rect.x0, + rect.y0 + ui_top_fixed_y(), + rect.x0 + canvas_dim.x, + rect.y0 + ui_top_fixed_y() + canvas_dim.y); + + //- rjf: peek clicks in canvas region, mark clicked + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && evt->key == OS_Key_LeftMouseButton && contains_2f32(canvas_rect, evt->pos) && + contains_2f32(rect, evt->pos)) + { + pressed = 1; + break; + } + } + + //- rjf: build meta controls + ui_set_next_fixed_x(ui_top_font_size()*1.f); + ui_set_next_fixed_y(ui_top_font_size()*1.f + scroll_list_view_off_px.y*(row == rows.first)); + ui_set_next_pref_width(ui_em(3, 1)); + ui_set_next_pref_height(ui_em(3, 1)); + UI_Flags(UI_BoxFlag_DrawDropShadow) UI_CornerRadius(ui_top_font_size()*0.5f) + { + UI_Signal sig = rd_icon_buttonf(RD_IconKind_Window, 0, "###pop_out"); + if(ui_hovering(sig)) UI_Tooltip + { + ui_labelf("Pop out"); + } + if(ui_pressed(sig)) + { + pressed = 1; + } + if(ui_clicked(sig)) + { + rd_cmd(RD_CmdKind_OpenTab, + .string = e_string_from_expr(scratch.arena, row->expr), + .params_tree = ui_view_rule_params_root); + } + } + + //- rjf: build main column for canvas + ui_set_next_fixed_y(-1.f * (row->visual_size_skipped) * scroll_list_params.row_height_px); + ui_set_next_fixed_height((row->visual_size_skipped + row->visual_size + row->visual_size_chopped) * scroll_list_params.row_height_px); + ui_set_next_child_layout_axis(Axis2_X); + UI_Box *canvas_box = ui_build_box_from_stringf(UI_BoxFlag_FloatingY, "###canvas_%I64x", row_hash); + UI_Parent(canvas_box) UI_WidthFill UI_HeightFill + { + //- rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(canvas_box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + //- rjf: push interaction registers, fill with per-view states + rd_push_regs(); + { + rd_regs()->view = rd_handle_from_view(canvas_view); + rd_regs()->file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(canvas_view->query_buffer, canvas_view->query_string_size)); + } + + //- rjf: build + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + { + ui_view_rule_info->ui(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view->params_roots[canvas_view->params_read_gen%ArrayCount(canvas_view->params_roots)], canvas_rect); + } + + //- rjf: loading overlay fill + UI_Parent(loading_overlay_container) + { + rd_loading_overlay(canvas_rect, canvas_view->loading_t, canvas_view->loading_progress_v, canvas_view->loading_progress_v_target); + } + + //- rjf: pop interaction registers + rd_pop_regs(); + } +#endif + }break; + + //////////////////// + //- rjf: pretty entity controls row + // + case RD_WatchViewRowKind_PrettyEntityControls: + ProfScope("pretty entity controls row") + { + //- rjf: unpack + RD_EntityKind collection_entity_kind = row_info.collection_entity_kind; + CTRL_EntityKind collection_ctrl_entity_kind = row_info.collection_ctrl_entity_kind; + RD_Entity *entity = row_info.collection_entity; + CTRL_Entity *ctrl_entity = row_info.collection_ctrl_entity; + B32 entity_box_selected = (row_selected && selection_tbl.min.x <= 1 && 1 <= selection_tbl.max.x); + B32 is_hovering = ((rd_handle_match(rd_state->hover_regs->entity, rd_handle_from_entity(entity)) && + rd_state->hover_regs_slot == RD_RegSlot_Entity) || + (ctrl_handle_match(rd_state->hover_regs->thread, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread) || + (ctrl_handle_match(rd_state->hover_regs->module, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Module) || + (ctrl_handle_match(rd_state->hover_regs->process, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Process)); + + //- rjf: pick palette + UI_Palette *palette = ui_build_palette(ui_top_palette()); + if(entity->kind == RD_EntityKind_Target && !entity->disabled) + { + palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); + } + else if(ctrl_entity->kind == CTRL_EntityKind_Thread && ctrl_handle_match(ctrl_entity->handle, rd_regs()->thread)) + { + palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); + } + else + { + palette->background = v4f32(0, 0, 0, 0); + } + + //- rjf: build indentation + for(U64 idx = 0; idx < row_depth; idx += 1) + { + ui_set_next_flags(UI_BoxFlag_DrawSideLeft); + ui_spacer(ui_em(1.f, 1.f)); + } + + //- rjf: build add-new buttons + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Target) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + } + } + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Breakpoint) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); + } + ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 2 ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); + } + } + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_WatchPin) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); + } + } + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_FilePathMap) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Add File Path Map"))) + { + rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); + } + } + if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_AutoViewRule) + UI_Palette(palette) + { + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Add Auto View Rule"))) + { + rd_entity_alloc(rd_entity_root(), RD_EntityKind_AutoViewRule); + } + } + + //- rjf: build entity box + if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) + { + //- rjf: unpack entity info + DR_FancyStringList fstrs = {0}; + if(!rd_entity_is_nil(entity)) + { + fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); + } + else if(ctrl_entity != &ctrl_entity_nil) + { + fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); + } + String8 fstrs_string = dr_string_from_fancy_string_list(scratch.arena, &fstrs); + FuzzyMatchRangeList fstrs_matches = fuzzy_match_find(scratch.arena, filter, fstrs_string); + UI_Key hover_t_key = ui_key_from_stringf(ui_key_zero(), "entity_hover_t_%p_%p", entity, ctrl_entity); + F32 hover_t = ui_anim(hover_t_key, (F32)!!is_hovering, .rate = entity_hover_t_rate); + if(!rd_entity_is_nil(entity)) + { + palette->overlay = rd_rgba_from_entity(entity); + palette->overlay.w *= 0.3f; + } + else if(ctrl_entity != &ctrl_entity_nil) + { + palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); + palette->overlay.w *= 0.3f; + } + if(palette->overlay.x == 0 && palette->overlay.y == 0 && palette->overlay.z == 0 && palette->overlay.w == 0) + { + palette->overlay = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + } + palette->overlay.w *= hover_t; + + //- rjf: build + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *entity_box = &ui_nil_box; + UI_FocusHot(entity_box_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) + { + entity_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawOverlay| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawSideLeft| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawHotEffects, + "###entity_%p_%p", entity, ctrl_entity); + } + { + UI_Parent(entity_box) RD_RegsScope(.entity = rd_handle_from_entity(entity)) + { + RD_RegSlot slot = RD_RegSlot_Entity; + switch(ctrl_entity->kind) + { + default:{}break; + case CTRL_EntityKind_Machine:{slot = RD_RegSlot_Machine; rd_regs()->machine = ctrl_entity->handle;}break; + case CTRL_EntityKind_Thread: {slot = RD_RegSlot_Thread; rd_regs()->thread = ctrl_entity->handle;}break; + case CTRL_EntityKind_Process:{slot = RD_RegSlot_Process; rd_regs()->process = ctrl_entity->handle;}break; + case CTRL_EntityKind_Module: {slot = RD_RegSlot_Module; rd_regs()->module = ctrl_entity->handle;}break; + } + UI_PrefWidth(ui_em(2.f, 1.f)) if(ui_pressed(ui_expander(row->block->rows_default_expanded ? !row_expanded : row_expanded, str8_lit("###expanded")))) + { + next_row_expanded = !row_expanded; + } + UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); + ui_box_equip_display_fancy_strings(title_box, &fstrs); + ui_box_equip_fuzzy_match_ranges(title_box, &fstrs_matches); + UI_Signal sig = ui_signal_from_box(entity_box); + if(ui_hovering(sig)) + { + rd_set_hover_regs(slot); + } + if(ui_right_clicked(sig)) + { + rd_open_ctx_menu(entity_box->key, v2f32(0, dim_2f32(entity_box->rect).y), slot); + } + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + { + rd_drag_begin(slot); + } + if(ui_pressed(sig)) + { + RD_WatchPt cell_pt = {1, row->block->key, row->key}; + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + if(ui_double_clicked(sig)) + { +#if 0 // TODO(rjf): @cfg + if(entity->kind == RD_EntityKind_Target) + { + rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : + sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : + RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); + } + if(ctrl_entity->kind == CTRL_EntityKind_Thread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); + } + if(entity->kind == RD_EntityKind_Breakpoint || + entity->kind == RD_EntityKind_WatchPin) + { + RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); + rd_cmd(RD_CmdKind_FindCodeLocation, + .file_path = (loc->flags & RD_EntityFlag_HasTextPoint) ? loc->string : str8_zero(), + .cursor = loc->text_point, + .vaddr = loc->vaddr); + } +#endif + } + } + } + + //- rjf: build extra entity controls + UI_PrefWidth(ui_em(3.f, 1.f)) + { +#if 0 // TODO(rjf): @cfg + U64 ctrl_idx = 1; + for EachIndex(idx, row_ctrls_count) + { + RD_WatchViewRowCtrl *ctrl = &row_ctrls[idx]; + if(ctrl->entity_kind == entity->kind && + ctrl->ctrl_entity_kind == ctrl_entity->kind) + { + UI_FocusHot(row_selected && selection_tbl.min.x <= ctrl_idx+1 && ctrl_idx+1 <= selection_tbl.max.x ? UI_FocusKind_On : UI_FocusKind_Off) + { + B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); + RD_IconKind icon_kind = rd_cmd_kind_info_table[ctrl->kind].icon_kind; + UI_Palette *palette = ui_top_palette(); + if(ctrl->kind == RD_CmdKind_SelectEntity) + { + icon_kind = entity->disabled ? RD_IconKind_RadioHollow : RD_IconKind_RadioFilled; + } + if(ctrl->kind == RD_CmdKind_EnableEntity) + { + icon_kind = entity->disabled ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled; + } + if(ctrl->kind == RD_CmdKind_SelectThread) + { + icon_kind = (ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread) ? RD_IconKind_RadioFilled : RD_IconKind_RadioHollow); + } + if(ctrl->kind == RD_CmdKind_FreezeEntity) + { + icon_kind = is_frozen ? RD_IconKind_Locked : RD_IconKind_Unlocked; + palette = rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton); + } + UI_Palette(palette) + { + UI_Signal sig = rd_icon_buttonf(icon_kind, 0, "###row_ctrl_%I64x", idx); + if(ui_clicked(sig)) + { + if(ctrl->kind == RD_CmdKind_SelectEntity) + { + rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : + sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : + RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); + } + else if(ctrl->kind == RD_CmdKind_EnableEntity) + { + rd_cmd(entity->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(entity)); + } + else if(ctrl->kind == RD_CmdKind_SelectThread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); + } + else if(ctrl->kind == RD_CmdKind_FreezeEntity) + { + rd_cmd(is_frozen ? RD_CmdKind_ThawEntity : RD_CmdKind_FreezeEntity, + .ctrl_entity = ctrl_entity->handle); + } + else if(ctrl->kind == RD_CmdKind_Kill) + { + rd_cmd(RD_CmdKind_Kill, .process = ctrl_entity->handle); + } + else + { + rd_cmd(ctrl->kind, .entity = rd_handle_from_entity(entity)); + } + } + } + } + ctrl_idx += 1; + } + } +#endif + } + } + }break; + + //////////////////// + //- rjf: normal row + // + default: + case RD_WatchViewRowKind_Normal: + ProfScope("normal row") UI_HeightFill + { + ////////////////////// + //- rjf: draw start of cache lines in expansions + // + if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + { + U64 row_offset = row_eval.value.u64; + if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + + ////////////////////// + //- rjf: draw mid-row cache line boundaries in expansions + // + if(!(flags & RD_WatchViewFlag_DisableCacheLines)) + { + if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && + row_eval.value.u64%64 != 0 && + row_depth > 0 && + !row_expanded) + { + U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); + if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_height(ui_top_font_size()*1.f); + Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); + boundary_color.w *= 0.5f; + ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + + ////////////////////// + //- rjf: build all columns + // + ProfScope("build all columns") + { + S64 x = 0; + F32 x_px = 0; + for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) + { + //- rjf: unpack cell info + RD_WatchPt cell_pt = {x, row->block->key, row->key}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); + String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + + //- rjf: unpack column-kind-specific info + ProfBegin("unpack column-kind-specific info"); + E_Eval cell_eval = row_eval; + E_Type *cell_type = row_type; + B32 cell_can_edit = 0; + FuzzyMatchRangeList cell_matches = {0}; + String8 cell_inheritance_string = {0}; + String8 cell_error_string = {0}; + String8 cell_error_tooltip_string = {0}; + RD_ListerFlags cell_autocomp_flags = 0; + RD_ViewRuleUIFunctionType *cell_ui_hook = 0; + MD_Node *cell_ui_params = &md_nil_node; + Vec4F32 cell_base_color = ui_top_palette()->text; + RD_IconKind cell_icon = RD_IconKind_Null; + String8 cell_ghost_text = {0}; + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: + { + cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); + if(filter.size != 0) + { + cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); + } + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); + if(row->member != 0 && row->member->inheritance_key_chain.first != 0) + { + String8List inheritance_chain_type_names = {0}; + for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) + { + String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); + inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); + str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); + } + if(inheritance_chain_type_names.node_count != 0) + { + StringJoin join = {0}; + join.sep = str8_lit("::"); + String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); + cell_inheritance_string = inheritance_type; + } + } + }break; + case RD_WatchViewColumnKind_Value: + { + }goto value_cell; + case RD_WatchViewColumnKind_Member: + { + E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); + cell_eval = e_eval_from_expr(scratch.arena, expr); + cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); + }goto value_cell; + value_cell:; + { + E_MsgList msgs = cell_eval.msgs; + if(row_depth == 0 && row->string.size != 0) + { + E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); + e_msg_list_concat_in_place(&parse.msgs, &msgs); + msgs = parse.msgs; + } + if(msgs.max_kind > E_MsgKind_Null) + { + String8List strings = {0}; + for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) + { + str8_list_push(scratch.arena, &strings, msg->text); + } + StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; + cell_error_string = str8_list_join(scratch.arena, &strings, &join); + } + if(row_is_bad) + { + cell_error_tooltip_string = str8_lit("Could not read memory successfully."); + } + cell_autocomp_flags = (RD_ListerFlag_Locals| + RD_ListerFlag_Procedures| + RD_ListerFlag_Globals| + RD_ListerFlag_ThreadLocals| + RD_ListerFlag_Types); + if(cell_type->flags & E_TypeFlag_IsPathText) + { + cell_autocomp_flags = RD_ListerFlag_Files; + } + if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) + { + cell_ui_hook = ui_view_rule_info->ui; + cell_ui_params = ui_view_rule_params_root; + } + for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) + { + EV_ViewRule *vr = &n->v; + RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); + if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) + { + cell_ui_hook = info->ui; + cell_ui_params = vr->root; + } + } + cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); + }break; + case RD_WatchViewColumnKind_Type: + { + cell_can_edit = 0; + }break; + case RD_WatchViewColumnKind_ViewRule: + { + cell_can_edit = 1; + cell_autocomp_flags = RD_ListerFlag_ViewRules; + if(cell_pre_edit_string.size == 0) + { + EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); + String8List strings = {0}; + for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &strings, n->v.root->string); + } + cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); + } + }break; + case RD_WatchViewColumnKind_CallStackFrameSelection: + { + if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && + row_info.callstack_unwind_index == rd_regs()->unwind_count && + row_info.callstack_inline_depth == rd_regs()->inline_depth) + { + cell_icon = RD_IconKind_RightArrow; + cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); + } + }break; + } + ProfEnd(); + + //- rjf: apply column-specified view rules + ProfBegin("apply column-specified view rules"); + if(col->view_rule_size != 0) + { + String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); + EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); + for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) { EV_ViewRule *vr = &n->v; RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); @@ -3553,433 +3614,384 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) cell_ui_params = vr->root; } } - cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); - }break; - case RD_WatchViewColumnKind_Type: + } + ProfEnd(); + + //- rjf: determine cell's palette + ProfBegin("determine cell's palette"); + UI_BoxFlags cell_flags = 0; + UI_Palette *palette = ui_top_palette(); { - cell_can_edit = 0; - }break; - case RD_WatchViewColumnKind_ViewRule: - { - cell_can_edit = 1; - cell_autocomp_flags = RD_ListerFlag_ViewRules; - if(cell_pre_edit_string.size == 0) + if(cell_error_tooltip_string.size != 0 || + cell_error_string.size != 0) { - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); - String8List strings = {0}; - for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &strings, n->v.root->string); - } - cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); + palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); + cell_flags |= UI_BoxFlag_DrawBackground; } - }break; - case RD_WatchViewColumnKind_CallStackFrameSelection: - { - if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && - row_info.callstack_unwind_index == rd_regs()->unwind_count && - row_info.callstack_inline_depth == rd_regs()->inline_depth) + else if(cell_inheritance_string.size != 0) { - cell_icon = RD_IconKind_RightArrow; - cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); + palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); + cell_flags |= UI_BoxFlag_DrawBackground; } - }break; - } - ProfEnd(); - - //- rjf: apply column-specified view rules - ProfBegin("apply column-specified view rules"); - if(col->view_rule_size != 0) - { - String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) + else { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; + palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); } } - } - ProfEnd(); - - //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); - UI_BoxFlags cell_flags = 0; - UI_Palette *palette = ui_top_palette(); - { - if(cell_error_tooltip_string.size != 0 || - cell_error_string.size != 0) + ProfEnd(); + + //- rjf: determine if cell needs code styling + B32 cell_is_code = !col->is_non_code; + switch(col->kind) { - palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(cell_inheritance_string.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else - { - palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); - } - } - ProfEnd(); - - //- rjf: determine if cell needs code styling - B32 cell_is_code = !col->is_non_code; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_is_code = 1; - if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) - { - cell_is_code = 0; - } - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - { - if(cell_type->flags & E_TypeFlag_IsCodeText) + default:{}break; + case RD_WatchViewColumnKind_Expr: { cell_is_code = 1; - } - else if(cell_type->flags & E_TypeFlag_IsPathText || - cell_type->flags & E_TypeFlag_IsPlainText) - { - cell_is_code = 0; - } - }break; - } - - //- rjf: build cell - UI_Signal sig = {0}; - ProfScope("build cell") - UI_Palette(palette) - UI_TableCell - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) - { - ui_set_next_flags(ui_top_flags() | cell_flags); - - // rjf: cell has errors? -> build error box - if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_error_string); - } - } - - // rjf: cell has hook? -> build ui by calling hook - else if(cell_ui_hook != 0) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); - UI_Parent(box) - { - String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); - } - sig = ui_signal_from_box(box); - } - - // rjf: cell has icon? build icon - else if(cell_icon != RD_IconKind_Null) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); - UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[cell_icon]); - } - sig = ui_signal_from_box(box); - } - - // rjf: build cell line edit - else - { - sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| - RD_LineEditFlag_NoBackground| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_DisableEdit*(!cell_can_edit)| - RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && col->kind == RD_WatchViewColumnKind_Expr)), - x == 0 ? row_depth : 0, - &cell_matches, - &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_pre_edit_string, - "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); - } - } - } - - //- rjf: handle interactions - { - // rjf: single-click -> move selection here - if(ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: double-click actions - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) - { - ui_kill_action(); - - // rjf: has callstack info? -> select unwind - if(row_info.callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info.callstack_unwind_index, - .inline_depth = row_info.callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(cell_can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: cannot edit, has addr info? -> go to address - else if(row_kind == RD_WatchViewRowKind_Normal && - (col->kind == RD_WatchViewColumnKind_Value || - col->kind == RD_WatchViewColumnKind_Member) && - cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) + if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) { - U64 vaddr = cell_eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) + cell_is_code = 0; + } + }break; + case RD_WatchViewColumnKind_Value: + case RD_WatchViewColumnKind_Member: + { + if(cell_type->flags & E_TypeFlag_IsCodeText) + { + cell_is_code = 1; + } + else if(cell_type->flags & E_TypeFlag_IsPathText || + cell_type->flags & E_TypeFlag_IsPlainText) + { + cell_is_code = 0; + } + }break; + } + + //- rjf: build cell + UI_Signal sig = {0}; + ProfScope("build cell") + UI_Palette(palette) + UI_TableCell + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) + UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) + { + ui_set_next_flags(ui_top_flags() | cell_flags); + + // rjf: cell has errors? -> build error box + if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); + sig = ui_signal_from_box(box); + UI_Parent(box) UI_Flags(0) + { + rd_error_label(cell_error_string); + } + } + + // rjf: cell has hook? -> build ui by calling hook + else if(cell_ui_hook != 0) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); + UI_Parent(box) + { + String8 row_expr = e_string_from_expr(scratch.arena, row->expr); + cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); + } + sig = ui_signal_from_box(box); + } + + // rjf: cell has icon? build icon + else if(cell_icon != RD_IconKind_Null) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); + UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) + { + ui_label(rd_icon_kind_text_table[cell_icon]); + } + sig = ui_signal_from_box(box); + } + + // rjf: build cell line edit + else + { + sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| + RD_LineEditFlag_NoBackground| + RD_LineEditFlag_KeyboardClickable| + RD_LineEditFlag_DisableEdit*(!cell_can_edit)| + RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && col->kind == RD_WatchViewColumnKind_Expr)| + RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && col->kind == RD_WatchViewColumnKind_Expr)| + RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && col->kind == RD_WatchViewColumnKind_Expr)), + x == 0 ? row_depth : 0, + &cell_matches, + &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, + cell_pre_edit_string, + "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + { + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } + } + } + + //- rjf: handle interactions + { + // rjf: single-click -> move selection here + if(ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: double-click actions + if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) + { + ui_kill_action(); + + // rjf: has callstack info? -> select unwind + if(row_info.callstack_thread != &ctrl_entity_nil) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info.callstack_unwind_index, + .inline_depth = row_info.callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(cell_can_edit) + { + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: cannot edit, has addr info? -> go to address + else if(row_kind == RD_WatchViewRowKind_Normal && + (col->kind == RD_WatchViewColumnKind_Value || + col->kind == RD_WatchViewColumnKind_Member) && + cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; + U64 vaddr = cell_eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) + { + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; + } + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); } - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); } } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); + } } - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip + //- rjf: bump x pixel coordinate + x_px += col->pct*dim_2f32(rect).x; + + //- rjf: [DEV] hovering -> watch key tooltips + if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); - } + 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); } - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip + //- rjf: [DEV] hovering -> eval system tooltips + if(DEV_eval_compiler_tooltips && x == 0 && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); - } - } - - //- rjf: bump x pixel coordinate - x_px += col->pct*dim_2f32(rect).x; - - //- 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_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); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && x == 0 && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task + local_persist char *spaces = " "; + String8 string = ev_expr_string_from_row(scratch.arena, row, 0); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); + ui_label(string); + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); + for(U64 idx = 0; idx < tokens.count; idx += 1) { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) + ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); { - String8 ext = {0}; - switch(t->expr->kind) + typedef struct Task Task; + struct Task { - default: + Task *next; + Task *prev; + E_Expr *expr; + S64 depth; + }; + Task start_task = {0, 0, parse.expr}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 ext = {0}; + switch(t->expr->kind) { - if(t->expr->string.size != 0) + default: { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: + if(t->expr->string.size != 0) + { + ext = push_str8f(scratch.arena, "'%S'", t->expr->string); + } + else if(t->expr->value.u32 != 0) + { + ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); + } + else if(t->expr->value.f32 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); + } + else if(t->expr->value.f64 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); + } + else if(t->expr->value.u64 != 0) + { + ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); + } + }break; + } + ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; + Task *task = push_array(scratch.arena, Task, 1); + task->expr = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_IRNode *node; + S64 depth; + }; + Task start_task = {0, 0, irtree.root}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 op_string = {0}; + switch(t->node->op) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); + for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->node = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); + { + for(E_Op *op = oplist.first; op != 0; op = op->next) + { + String8 op_string = {0}; + switch(op->opcode) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + switch(op->opcode) + { + case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; + default: + { + ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); + }break; + } + ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); + } + } + ui_spacer(ui_em(2.f, 1.f)); + UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); + { + for(U64 idx = 0; idx < bytecode.size; idx += 1) + { + ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); + } } } } } - } - }break; - } + }break; + } #endif - - ////////////////////// - //- rjf: commit expansion state changes - // - if(next_row_expanded != row_expanded) - { - if(!ev_key_match(ev_key_root(), row->key)) + + ////////////////////// + //- rjf: commit expansion state changes + // + if(next_row_expanded != row_expanded) { - ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + if(!ev_key_match(ev_key_root(), row->key)) + { + ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + } } } } @@ -4000,38 +4012,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) ProfEnd(); } -//////////////////////////////// -//~ rjf: null @view_hook_impl - -RD_VIEW_UI_FUNCTION_DEF(null) {} - -//////////////////////////////// -//~ rjf: watch @view_hook_impl - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch) -{ - EV_ExpandInfo info = {0}; - info.row_count = 8; - info.single_item = 1; - return info; -} - -RD_VIEW_UI_FUNCTION_DEF(watch) -{ - ProfBeginFunction(); - RD_WatchViewState *wv = rd_view_state(RD_WatchViewState); - if(!wv->initialized) - { - rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.25f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.3f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Type, 0.15f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_ViewRule, 0.30f); - } - rd_watch_view_build(wv, rect); - ProfEnd(); -} - //////////////////////////////// //~ rjf: text @view_hook_impl diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index e466ea19..f9588f5d 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -80,6 +80,7 @@ struct RD_WatchRowInfo U64 callstack_inline_depth; RD_WatchCellList cells; RD_ViewUIRule *view_ui_rule; + E_Expr *view_ui_tag; }; typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; @@ -91,8 +92,8 @@ struct RD_WatchRowCellInfo B32 is_errored; String8 error_tooltip; String8 inheritance_tooltip; - RD_ViewRuleUIFunctionType *ui; - MD_Node *ui_params; + RD_ViewUIRule *view_ui_rule; + E_Expr *view_ui_tag; }; typedef enum RD_WatchViewColumnKind @@ -164,13 +165,6 @@ struct RD_WatchViewState { B32 initialized; - // rjf: column state - Arena *column_arena; - RD_WatchViewColumn *first_column; - RD_WatchViewColumn *last_column; - RD_WatchViewColumn *free_column; - U64 column_count; - // rjf; table cursor state RD_WatchPt cursor; RD_WatchPt mark; @@ -200,9 +194,6 @@ internal RD_WatchCell *rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *l internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params); #define rd_watch_cell_list_push_new(arena, list, kind_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), __VA_ARGS__}) -//- rjf: index -> column -internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index); - //- rjf: watch view points <-> table coordinates internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b); internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); @@ -228,15 +219,6 @@ internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, R //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); -//- rjf: watch view column state mutation -internal RD_WatchViewColumn *rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params); -#define rd_watch_view_column_alloc(wv, kind, pct, ...) rd_watch_view_column_alloc_((wv), (kind), (pct), &(RD_WatchViewColumnParams){.string = str8_zero(), __VA_ARGS__}) -internal void rd_watch_view_column_release(RD_WatchViewState *wv, RD_WatchViewColumn *col); - -//- rjf: watch view main hooks -internal void rd_watch_view_init(RD_WatchViewState *ewv); -internal void rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect); - //////////////////////////////// //~ rjf: View Hooks From 3de43b8c74becbbdf95be925d7166c6746bfc1c3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 7 Feb 2025 15:20:19 -0800 Subject: [PATCH 073/755] view params, pulled either from cfg trees or view rule params (tag calls); expr chain parsing; correctly use tags in nested single-line eval visualization --- src/eval/eval_bundles.c | 35 + src/eval/eval_bundles.h | 3 + src/eval/eval_parse.c | 2031 +++++++++++++++++++------------------ src/raddbg/raddbg_core.c | 125 ++- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 10 +- 6 files changed, 1195 insertions(+), 1011 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 6d966dea..4c9c5f32 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -273,3 +273,38 @@ e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name) } return result; } + +internal E_Value +e_value_from_string(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval value_eval = e_value_eval_from_eval(eval); + E_Value result = value_eval.value; + scratch_end(scratch); + return result; +} + +internal E_Value +e_value_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_Value result = e_value_from_string(string); + va_end(args); + scratch_end(scratch); + return result; +} + +internal E_Value +e_value_from_expr(E_Expr *expr) +{ + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_expr(scratch.arena, expr); + E_Eval value_eval = e_value_eval_from_eval(eval); + E_Value result = value_eval.value; + scratch_end(scratch); + return result; +} \ No newline at end of file diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index f835a6cb..c83b33f5 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -30,5 +30,8 @@ internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); internal E_Eval e_value_eval_from_eval(E_Eval eval); internal E_Eval e_element_eval_from_array_eval_index(E_Eval eval, U64 index); internal E_Eval e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name); +internal E_Value e_value_from_string(String8 string); +internal E_Value e_value_from_stringf(char *fmt, ...); +internal E_Value e_value_from_expr(E_Expr *expr); #endif // EVAL_BUNDLES_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index cacbdd1b..cc9a5232 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1195,1081 +1195,921 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Token *it = tokens->v; E_Token *it_opl = tokens->v + tokens->count; E_Parse result = {0, &e_expr_nil}; + E_Expr *last_expr = &e_expr_nil; - //- rjf: parse prefix unaries - typedef struct PrefixUnaryNode PrefixUnaryNode; - struct PrefixUnaryNode + //- rjf: parse chain of expressions + for(;it < it_opl;) { - PrefixUnaryNode *next; - E_ExprKind kind; - E_Expr *cast_expr; - void *location; - }; - PrefixUnaryNode *first_prefix_unary = 0; - PrefixUnaryNode *last_prefix_unary = 0; - { - for(;it < it_opl;) + //- rjf: exit on symbols callers may be waiting on { - E_Token *start_it = it; E_Token token = e_token_at_it(it, tokens); String8 token_string = str8_substr(text, token.range); - S64 prefix_unary_precedence = 0; - E_ExprKind prefix_unary_kind = 0; - E_Expr *cast_expr = &e_expr_nil; - void *location = 0; - - // rjf: try op table - for EachNonZeroEnumVal(E_ExprKind, k) + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit(")"), 0) || + str8_match(token_string, str8_lit("]"), 0))) { - E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0)) + break; + } + } + + //- rjf: skip commas, semicolons, etc. + for(;it < it_opl;) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit(","), 0) || + str8_match(token_string, str8_lit(";"), 0))) + { + it += 1; + } + else + { + break; + } + } + + //- rjf: parse prefix unaries + typedef struct PrefixUnaryNode PrefixUnaryNode; + struct PrefixUnaryNode + { + PrefixUnaryNode *next; + E_ExprKind kind; + E_Expr *cast_expr; + void *location; + }; + PrefixUnaryNode *first_prefix_unary = 0; + PrefixUnaryNode *last_prefix_unary = 0; + { + for(;it < it_opl;) + { + E_Token *start_it = it; + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + S64 prefix_unary_precedence = 0; + E_ExprKind prefix_unary_kind = 0; + E_Expr *cast_expr = &e_expr_nil; + void *location = 0; + + // rjf: try op table + for EachNonZeroEnumVal(E_ExprKind, k) + { + E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; + if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0)) + { + prefix_unary_precedence = op_info->precedence; + prefix_unary_kind = k; + break; + } + } + + // rjf: consume valid op + if(prefix_unary_precedence != 0) + { + location = token_string.str; + it += 1; + } + + // rjf: try casting expression + if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) + { + E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); + String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); + if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) + { + E_TypeKey type_key = e_leaf_type_from_name(some_type_identifier_maybe_string); + if(!e_type_key_match(type_key, e_type_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) + { + // rjf: move past open paren + it += 1; + + // rjf: parse type expr + E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Expr *type = type_parse.expr; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + location = token_string.str; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); + } + + // rjf: consume ) + else + { + it += 1; + } + + // rjf: fill + prefix_unary_precedence = 2; + prefix_unary_kind = E_ExprKind_Cast; + cast_expr = type; + } + } + } + + // rjf: break if we got no operators + if(prefix_unary_precedence == 0) { - prefix_unary_precedence = op_info->precedence; - prefix_unary_kind = k; break; } - } - - // rjf: consume valid op - if(prefix_unary_precedence != 0) - { - location = token_string.str; - it += 1; - } - - // rjf: try casting expression - if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) - { - E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); - String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); - if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) + + // rjf: break if the token node iterator has not changed + if(it == start_it) { - E_TypeKey type_key = e_leaf_type_from_name(some_type_identifier_maybe_string); - if(!e_type_key_match(type_key, e_type_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) - { - // rjf: move past open paren - it += 1; - - // rjf: parse type expr - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - location = token_string.str; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); - } - - // rjf: consume ) - else - { - it += 1; - } - - // rjf: fill - prefix_unary_precedence = 2; - prefix_unary_kind = E_ExprKind_Cast; - cast_expr = type; - } + break; + } + + // rjf: push prefix unary if we got one + { + PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); + op_n->kind = prefix_unary_kind; + op_n->cast_expr = cast_expr; + op_n->location = location; + SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); + } + } + } + + //- rjf: parse atom + E_Expr *atom = &e_expr_nil; + String8 atom_implicit_member_name = {0}; + if(it < it_opl) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + + //- rjf: gather resolution qualifier + String8 resolution_qualifier = {0}; + if(token.kind == E_TokenKind_Identifier) + { + E_Token next_token = e_token_at_it(it+1, tokens); + String8 next_token_string = str8_substr(text, next_token.range); + if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) + { + it += 2; + resolution_qualifier = token_string; + token = e_token_at_it(it, tokens); + token_string = str8_substr(text, token.range); } } - // rjf: break if we got no operators - if(prefix_unary_precedence == 0) - { - break; - } - - // rjf: break if the token node iterator has not changed - if(it == start_it) - { - break; - } - - // rjf: push prefix unary if we got one - { - PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); - op_n->kind = prefix_unary_kind; - op_n->cast_expr = cast_expr; - op_n->location = location; - SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); - } - } - } - - //- rjf: parse atom - E_Expr *atom = &e_expr_nil; - String8 atom_implicit_member_name = {0}; - if(it < it_opl) - { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: gather resolution qualifier - String8 resolution_qualifier = {0}; - if(token.kind == E_TokenKind_Identifier) - { - E_Token next_token = e_token_at_it(it+1, tokens); - String8 next_token_string = str8_substr(text, next_token.range); - if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) - { - it += 2; - resolution_qualifier = token_string; - token = e_token_at_it(it, tokens); - token_string = str8_substr(text, token.range); - } - } - - //- rjf: descent to nested expression - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) - { - // rjf: skip ( - it += 1; - - // rjf: parse () contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); - } - - // rjf: consume ) - else + //- rjf: descent to nested expression + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { + // rjf: skip ( it += 1; - } - } - - //- rjf: descent to assembly-style dereference sub-expression - else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) - { - // rjf: skip [ - it += 1; - - // rjf: parse [] contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); - } - else - { - E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); - E_Expr *casted = atom; - E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); - e_expr_push_child(cast, type); - e_expr_push_child(cast, casted); - atom = e_push_expr(arena, E_ExprKind_Deref, token_string.str); - e_expr_push_child(atom, cast); - } - - // rjf: expect ] - E_Token close_paren_maybe = e_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `]`."); - } - - // rjf: consume ) - else - { - it += 1; - } - } - - //- rjf: leaf (identifier, literal) - else if(token.kind != E_TokenKind_Symbol) - { - switch(token.kind) - { - //- rjf: identifier => name resolution - default: - case E_TokenKind_Identifier: + + // rjf: parse () contents + E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.expr; + it = nested_parse.last_token; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { - B32 mapped_identifier = 0; - B32 identifier_is_constant_value = 0; - B32 identifier_type_is_possibly_dynamically_overridden = 0; - B32 identifier_looks_like_type_expr = 0; - RDI_LocationKind loc_kind = RDI_LocationKind_NULL; - RDI_LocationReg loc_reg = {0}; - RDI_LocationRegPlusU16 loc_reg_u16 = {0}; - String8 loc_bytecode = {0}; - U64 constant_value = 0; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - E_TypeKey type_key = zero_struct; - String8 local_lookup_string = token_string; - E_Space space = {0}; - Arch arch = Arch_Null; - - //- rjf: identifiers surrounded by ``s should have those `s stripped - if(local_lookup_string.size >= 2 && - local_lookup_string.str[0] == '`' && - local_lookup_string.str[local_lookup_string.size-1] == '`') + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } + + //- rjf: descent to assembly-style dereference sub-expression + else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) + { + // rjf: skip [ + it += 1; + + // rjf: parse [] contents + E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.expr; + it = nested_parse.last_token; + + // rjf: build cast-to-U64*, and dereference operators + if(nested_parse.expr == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); + } + else + { + E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); + E_Expr *casted = atom; + E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); + e_expr_push_child(cast, type); + e_expr_push_child(cast, casted); + atom = e_push_expr(arena, E_ExprKind_Deref, token_string.str); + e_expr_push_child(atom, cast); + } + + // rjf: expect ] + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `]`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } + + //- rjf: leaf (identifier, literal) + else if(token.kind != E_TokenKind_Symbol) + { + switch(token.kind) + { + //- rjf: identifier => name resolution + default: + case E_TokenKind_Identifier: { - token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) + B32 mapped_identifier = 0; + B32 identifier_is_constant_value = 0; + B32 identifier_type_is_possibly_dynamically_overridden = 0; + B32 identifier_looks_like_type_expr = 0; + RDI_LocationKind loc_kind = RDI_LocationKind_NULL; + RDI_LocationReg loc_reg = {0}; + RDI_LocationRegPlusU16 loc_reg_u16 = {0}; + String8 loc_bytecode = {0}; + U64 constant_value = 0; + REGS_RegCode reg_code = 0; + REGS_AliasCode alias_code = 0; + E_TypeKey type_key = zero_struct; + String8 local_lookup_string = token_string; + E_Space space = {0}; + Arch arch = Arch_Null; + + //- rjf: identifiers surrounded by ``s should have those `s stripped + if(local_lookup_string.size >= 2 && + local_lookup_string.str[0] == '`' && + local_lookup_string.str[local_lookup_string.size-1] == '`') { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); - str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; + token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); } - } - - //- rjf: try members - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") - { - U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); - if(data_member_num != 0) + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_token_strings = {0}; { - atom_implicit_member_name = token_string; - local_lookup_string = str8_lit("this"); - } - } - - //- rjf: try locals - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - identifier_type_is_possibly_dynamically_overridden = 1; - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); - - // rjf: grab location info - for(U32 loc_block_idx = local_var->location_first; - loc_block_idx < local_var->location_opl; - loc_block_idx += 1) + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) { - mapped_identifier = 1; - space = module->space; - arch = module->arch; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); + str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try members + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") + { + U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); + if(data_member_num != 0) + { + atom_implicit_member_name = token_string; + local_lookup_string = str8_lit("this"); + } + } + + //- rjf: try locals + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); + if(local_num != 0) + { + identifier_type_is_possibly_dynamically_overridden = 1; + RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); + + // rjf: grab location info + for(U32 loc_block_idx = local_var->location_first; + loc_block_idx < local_var->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; + mapped_identifier = 1; + space = module->space; + arch = module->arch; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) + default:{mapped_identifier = 0;}break; + case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; + bytecode_stream:; { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) { - break; + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; + loc_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); + }break; + case RDI_LocationKind_ValReg: + { + MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); + }break; + } } } } } - } - - //- rjf: try registers - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") - { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") - { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - // NOTE(rjf): apparently, PDBs can be produced such that they - // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I - // don't know of a magic hash table fixup path in PDBs, so - // in this case, I'm going to prefer the latest-added global. - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try procedures - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try types - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") - { - type_key = e_leaf_type_from_name(token_string); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - MemoryZeroStruct(&space); - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try basic constants - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 1; - } - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 0; - } - - //- rjf: attach on map - if(mapped_identifier != 0) ProfScope("attach on map") - { - it += 1; - // rjf: build atom - switch(loc_kind) + //- rjf: try registers + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") { - default: + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); + if(reg_num != 0) { - if(identifier_is_constant_value) + reg_code = reg_num; + type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try register aliases + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") + { + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); + if(alias_num != 0) + { + alias_code = (REGS_AliasCode)alias_num; + type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try global variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) { - atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); - atom->value.u64 = constant_value; - atom->type_key = type_key; + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); } - else if(identifier_looks_like_type_expr) + if(matches_count != 0) { - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; + // NOTE(rjf): apparently, PDBs can be produced such that they + // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I + // don't know of a magic hash table fixup path in PDBs, so + // in this case, I'm going to prefer the latest-added global. + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try thread variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try procedures + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + loc_kind = RDI_LocationKind_ValBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try types + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") + { + type_key = e_leaf_type_from_name(token_string); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + mapped_identifier = 1; + identifier_looks_like_type_expr = 1; + MemoryZeroStruct(&space); + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try basic constants + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 1; + } + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 0; + } + + //- rjf: attach on map + if(mapped_identifier != 0) ProfScope("attach on map") + { + it += 1; + + // rjf: build atom + switch(loc_kind) + { + default: + { + if(identifier_is_constant_value) + { + atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); + atom->value.u64 = constant_value; + atom->type_key = type_key; + } + else if(identifier_looks_like_type_expr) + { + E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Expr *type = type_parse.expr; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + atom = type; + } + else if(reg_code != 0) + { + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else if(alias_code != 0) + { + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); + } + }break; + case RDI_LocationKind_AddrBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_ValBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_AddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); atom->mode = E_Mode_Offset; atom->space = space; atom->type_key = type_key; atom->string = token_string; atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else if(alias_code != 0) + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); atom->mode = E_Mode_Offset; atom->space = space; atom->type_key = type_key; atom->string = token_string; atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else + }break; + case RDI_LocationKind_ValReg: { - e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + } + + // rjf: implicit local lookup -> attach member access node + if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); + member_expr->string = atom_implicit_member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); + atom->space = space; + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } } - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) + //- rjf: map failure -> attach as leaf identifier, to be resolved later + if(!mapped_identifier) { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); - member_expr->string = atom_implicit_member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); - atom->space = space; - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); + atom = e_push_expr(arena, E_ExprKind_LeafIdent, token_string.str); + atom->string = token_string; + it += 1; } - } + }break; - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) + //- rjf: numeric => directly extract value + case E_TokenKind_Numeric: { - atom = e_push_expr(arena, E_ExprKind_LeafIdent, token_string.str); - atom->string = token_string; + U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); it += 1; - } - }break; - - //- rjf: numeric => directly extract value - case E_TokenKind_Numeric: - { - U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); - it += 1; - - // rjf: no . => integral - if(dot_pos == token_string.size) - { - U64 val = 0; - try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = val; - break; - } - - // rjf: presence of . => double or float - if(dot_pos < token_string.size) - { - F64 val = f64_from_str8(token_string); - U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); - // rjf: presence of f after . => f32 - if(f_pos < token_string.size) + // rjf: no . => integral + if(dot_pos == token_string.size) { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); - atom->value.f32 = val; + U64 val = 0; + try_u64_from_str8_c_rules(token_string, &val); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = val; + break; } - // rjf: no f => f64 + // rjf: presence of . => double or float + if(dot_pos < token_string.size) + { + F64 val = f64_from_str8(token_string); + U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); + + // rjf: presence of f after . => f32 + if(f_pos < token_string.size) + { + atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); + atom->value.f32 = val; + } + + // rjf: no f => f64 + else + { + atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); + atom->value.f64 = val; + } + } + }break; + + //- rjf: char => extract char value + case E_TokenKind_CharLiteral: + { + it += 1; + if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + { + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = (U64)char_val; + } else { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); - atom->value.f64 = val; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); } - } - }break; + }break; + + //- rjf: string => leaf string literal, or file path + case E_TokenKind_StringLiteral: + { + if(str8_match(resolution_qualifier, str8_lit("file"), 0)) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); + atom->string = string_value_raw; + it += 1; + } + else + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); + atom->string = string_value_raw; + it += 1; + } + }break; + } - //- rjf: char => extract char value - case E_TokenKind_CharLiteral: + //- rjf: upgrade atom w/ qualifier + if(resolution_qualifier.size != 0) { - it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') - { - String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); - String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); - U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = (U64)char_val; - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); - } - }break; + atom->qualifier = resolution_qualifier; + } + } + } + + //- rjf: upgrade atom w/ postfix unaries + if(atom != &e_expr_nil) for(;it < it_opl;) + { + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + B32 is_postfix_unary = 0; + + // rjf: dot/arrow operator + if(token.kind == E_TokenKind_Symbol && + (str8_match(token_string, str8_lit("."), 0) || + str8_match(token_string, str8_lit("->"), 0))) + { + is_postfix_unary = 1; - //- rjf: string => leaf string literal, or file path - case E_TokenKind_StringLiteral: - { - if(str8_match(resolution_qualifier, str8_lit("file"), 0)) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); - atom->string = string_value_raw; - it += 1; - } - else - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); - atom->string = string_value_raw; - it += 1; - } - }break; - } - - //- rjf: upgrade atom w/ qualifier - if(resolution_qualifier.size != 0) - { - atom->qualifier = resolution_qualifier; - } - } - } - - //- rjf: upgrade atom w/ postfix unaries - if(atom != &e_expr_nil) for(;it < it_opl;) - { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - B32 is_postfix_unary = 0; - - // rjf: dot/arrow operator - if(token.kind == E_TokenKind_Symbol && - (str8_match(token_string, str8_lit("."), 0) || - str8_match(token_string, str8_lit("->"), 0))) - { - is_postfix_unary = 1; - - // rjf: advance past operator - it += 1; - - // rjf: expect member name - String8 member_name = {0}; - B32 good_member_name = 0; - { - E_Token member_name_maybe = e_token_at_it(it, tokens); - String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - if(member_name_maybe.kind != E_TokenKind_Identifier) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); - } - else - { - member_name = member_name_maybe_string; - good_member_name = 1; - } - } - - // rjf: produce lookup member expr - if(good_member_name) - { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); - member_expr->string = member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - - // rjf: increment past good member names - if(good_member_name) - { - it += 1; - } - } - - // rjf: array index - if(token.kind == E_TokenKind_Symbol && - str8_match(token_string, str8_lit("["), 0)) - { - is_postfix_unary = 1; - - // rjf: advance past [ - it += 1; - - // rjf: parse indexing expression - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); - it = idx_expr_parse.last_token; - - // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.expr != &e_expr_nil) - { - E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); - e_expr_push_child(atom, array_expr); - e_expr_push_child(atom, index_expr); - } - - // rjf: expect ] - { - E_Token close_brace_maybe = e_token_at_it(it, tokens); - String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); - if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `[`."); - } - else - { - it += 1; - } - } - } - - // rjf: calls - if(token.kind == E_TokenKind_Symbol && - str8_match(token_string, str8_lit("("), 0)) - { - it += 1; - E_Expr *callee_expr = atom; - E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); - if(callee_expr->kind == E_ExprKind_LeafIdent) - { - call_expr->string = callee_expr->string; - } - e_expr_push_child(call_expr, callee_expr); - for(B32 done = 0; !done && it < it_opl;) - { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0)) - { - done = 1; - it += 1; - } - else - { - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs); - if(arg_parse.expr != &e_expr_nil) - { - e_expr_push_child(call_expr, arg_parse.expr); - } - it = arg_parse.last_token; - E_Token maybe_comma = e_token_at_it(it, tokens); - String8 maybe_comma_string = str8_substr(text, token.range); - if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) - { - it += 1; - } - } - } - atom = call_expr; - } - - // rjf: quit if this doesn't look like any patterns of postfix unary we know - if(!is_postfix_unary) - { - break; - } - } - - //- rjf: upgrade atom w/ previously parsed prefix unaries - if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) - { - atom = first_prefix_unary->cast_expr; - for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - else if(atom == &e_expr_nil && first_prefix_unary != 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); - } - else - { - for(PrefixUnaryNode *prefix_unary = first_prefix_unary; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - - //- rjf: parse complex operators - if(atom != &e_expr_nil) for(;it < it_opl;) - { - E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: parse binaries - { - // rjf: first try to find a matching binary operator - S64 binary_precedence = 0; - E_ExprKind binary_kind = 0; - for EachNonZeroEnumVal(E_ExprKind, k) - { - E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0)) - { - binary_precedence = op_info->precedence; - binary_kind = k; - break; - } - } - - // rjf: if we got a valid binary precedence, and it's not to be handled by - // a caller, then we need to parse the right-hand-side with a tighter - // precedence - if(binary_precedence != 0 && binary_precedence <= max_precedence) - { - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1); - e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.expr; - it = rhs_expr_parse.last_token; - if(rhs == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); - } - else - { - E_Expr *lhs = atom; - atom = e_push_expr(arena, binary_kind, token_string.str); - e_expr_push_child(atom, lhs); - e_expr_push_child(atom, rhs); - } - } - } - - //- rjf: parse ternaries - { - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) - { + // rjf: advance past operator it += 1; - // rjf: parse middle expression - E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence); - it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.expr == &e_expr_nil) + // rjf: expect member name + String8 member_name = {0}; + B32 good_member_name = 0; { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); - } - - // rjf: expect : - B32 got_colon = 0; - E_Token colon_token = zero_struct; - String8 colon_token_string = {0}; - { - E_Token colon_token_maybe = e_token_at_it(it, tokens); - String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); - if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) + E_Token member_name_maybe = e_token_at_it(it, tokens); + String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); + if(member_name_maybe.kind != E_TokenKind_Identifier) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected `:` after `?`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); + } + else + { + member_name = member_name_maybe_string; + good_member_name = 1; + } + } + + // rjf: produce lookup member expr + if(good_member_name) + { + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); + member_expr->string = member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } + + // rjf: increment past good member names + if(good_member_name) + { + it += 1; + } + } + + // rjf: array index + if(token.kind == E_TokenKind_Symbol && + str8_match(token_string, str8_lit("["), 0)) + { + is_postfix_unary = 1; + + // rjf: advance past [ + it += 1; + + // rjf: parse indexing expression + E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); + e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); + it = idx_expr_parse.last_token; + + // rjf: valid indexing expression => produce index expr + if(idx_expr_parse.expr != &e_expr_nil) + { + E_Expr *array_expr = atom; + E_Expr *index_expr = idx_expr_parse.expr; + atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); + e_expr_push_child(atom, array_expr); + e_expr_push_child(atom, index_expr); + } + + // rjf: expect ] + { + E_Token close_brace_maybe = e_token_at_it(it, tokens); + String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); + if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `[`."); } else { - got_colon = 1; - colon_token = colon_token_maybe; - colon_token_string = colon_token_maybe_string; it += 1; } } - - // rjf: parse rhs - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence); - if(got_colon) - { - it = rhs_expr_parse.last_token; - e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); - } - } - - // rjf: build ternary - if(atom != &e_expr_nil && - middle_expr_parse.expr != &e_expr_nil && - rhs_expr_parse.expr != &e_expr_nil) - { - E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.expr; - E_Expr *rhs = rhs_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); - e_expr_push_child(atom, lhs); - e_expr_push_child(atom, mhs); - e_expr_push_child(atom, rhs); - } } - } - - //- rjf: parse tags - { - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) + + // rjf: calls + if(token.kind == E_TokenKind_Symbol && + str8_match(token_string, str8_lit("("), 0)) { + it += 1; + E_Expr *callee_expr = atom; + E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); + if(callee_expr->kind == E_ExprKind_LeafIdent) + { + call_expr->string = callee_expr->string; + } + e_expr_push_child(call_expr, callee_expr); for(B32 done = 0; !done && it < it_opl;) { - E_Token maybe_identifier = e_token_at_it(it, tokens); - E_Token maybe_open_paren = e_token_at_it(it+1, tokens); - String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range); - if(maybe_identifier.kind == E_TokenKind_Identifier && - maybe_open_paren.kind == E_TokenKind_Symbol && - str8_match(maybe_open_paren_string, str8_lit("("), 0)) + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0)) { - E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens); - e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs); - it = tag_parse.last_token; - if(tag_parse.expr != &e_expr_nil) + done = 1; + it += 1; + } + else + { + E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); + e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs); + if(arg_parse.expr != &e_expr_nil) { - e_expr_push_tag(atom, tag_parse.expr); - } - else - { - done = 1; + e_expr_push_child(call_expr, arg_parse.expr); } + it = arg_parse.last_token; E_Token maybe_comma = e_token_at_it(it, tokens); String8 maybe_comma_string = str8_substr(text, token.range); if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) @@ -2277,16 +2117,220 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; } } - else - { - done = 1; - } } + atom = call_expr; + } + + // rjf: quit if this doesn't look like any patterns of postfix unary we know + if(!is_postfix_unary) + { + break; } } - // rjf: if we parsed nothing successfully, we're done - if(it == start_it) + //- rjf: upgrade atom w/ previously parsed prefix unaries + if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) + { + atom = first_prefix_unary->cast_expr; + for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; + prefix_unary != 0; + prefix_unary = prefix_unary->next) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); + if(prefix_unary->cast_expr != &e_expr_nil) + { + e_expr_push_child(atom, prefix_unary->cast_expr); + } + e_expr_push_child(atom, rhs); + } + } + else if(atom == &e_expr_nil && first_prefix_unary != 0) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); + } + else + { + for(PrefixUnaryNode *prefix_unary = first_prefix_unary; + prefix_unary != 0; + prefix_unary = prefix_unary->next) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); + if(prefix_unary->cast_expr != &e_expr_nil) + { + e_expr_push_child(atom, prefix_unary->cast_expr); + } + e_expr_push_child(atom, rhs); + } + } + + //- rjf: parse complex operators + if(atom != &e_expr_nil) for(;it < it_opl;) + { + E_Token *start_it = it; + E_Token token = e_token_at_it(it, tokens); + String8 token_string = str8_substr(text, token.range); + + //- rjf: parse binaries + { + // rjf: first try to find a matching binary operator + S64 binary_precedence = 0; + E_ExprKind binary_kind = 0; + for EachNonZeroEnumVal(E_ExprKind, k) + { + E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; + if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0)) + { + binary_precedence = op_info->precedence; + binary_kind = k; + break; + } + } + + // rjf: if we got a valid binary precedence, and it's not to be handled by + // a caller, then we need to parse the right-hand-side with a tighter + // precedence + if(binary_precedence != 0 && binary_precedence <= max_precedence) + { + E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1); + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + E_Expr *rhs = rhs_expr_parse.expr; + it = rhs_expr_parse.last_token; + if(rhs == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); + } + else + { + E_Expr *lhs = atom; + atom = e_push_expr(arena, binary_kind, token_string.str); + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, rhs); + } + } + } + + //- rjf: parse ternaries + { + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) + { + it += 1; + + // rjf: parse middle expression + E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence); + it = middle_expr_parse.last_token; + E_Expr *middle_expr = middle_expr_parse.expr; + e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); + if(middle_expr_parse.expr == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); + } + + // rjf: expect : + B32 got_colon = 0; + E_Token colon_token = zero_struct; + String8 colon_token_string = {0}; + { + E_Token colon_token_maybe = e_token_at_it(it, tokens); + String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); + if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected `:` after `?`."); + } + else + { + got_colon = 1; + colon_token = colon_token_maybe; + colon_token_string = colon_token_maybe_string; + it += 1; + } + } + + // rjf: parse rhs + E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence); + if(got_colon) + { + it = rhs_expr_parse.last_token; + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + if(rhs_expr_parse.expr == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); + } + } + + // rjf: build ternary + if(atom != &e_expr_nil && + middle_expr_parse.expr != &e_expr_nil && + rhs_expr_parse.expr != &e_expr_nil) + { + E_Expr *lhs = atom; + E_Expr *mhs = middle_expr_parse.expr; + E_Expr *rhs = rhs_expr_parse.expr; + atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, mhs); + e_expr_push_child(atom, rhs); + } + } + } + + //- rjf: parse tags + { + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) + { + for(B32 done = 0; !done && it < it_opl;) + { + E_Token maybe_identifier = e_token_at_it(it, tokens); + E_Token maybe_open_paren = e_token_at_it(it+1, tokens); + String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range); + if(maybe_identifier.kind == E_TokenKind_Identifier && + maybe_open_paren.kind == E_TokenKind_Symbol && + str8_match(maybe_open_paren_string, str8_lit("("), 0)) + { + E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens); + e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs); + it = tag_parse.last_token; + if(tag_parse.expr != &e_expr_nil) + { + e_expr_push_tag(atom, tag_parse.expr); + } + else + { + done = 1; + } + E_Token maybe_comma = e_token_at_it(it, tokens); + String8 maybe_comma_string = str8_substr(text, token.range); + if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) + { + it += 1; + } + } + else + { + done = 1; + } + } + } + } + + // rjf: if we parsed nothing successfully, we're done + if(it == start_it) + { + break; + } + } + + //- rjf: store parsed atom to expression chain - if we didn't get an expression, break + if(atom != &e_expr_nil) + { + DLLPushBack_NPZ(&e_expr_nil, result.expr, last_expr, atom, next, prev); + } + else { break; } @@ -2294,7 +2338,6 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: fill result & return result.last_token = it; - result.expr = atom; scratch_end(scratch); ProfEnd(); return result; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f9bd7907..92c49185 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1220,7 +1220,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(expr_string.size != 0) { String8 query_name = rd_query_from_eval_string(arena, expr_string); - if(query_name.size != 0) + if(query_name.size != 0 && !str8_match(query_name, str8_lit("watches"), 0)) { String8 query_code_name = query_name; String8 query_display_name = rd_display_from_code_name(query_code_name); @@ -1303,11 +1303,11 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 } else if(file_path.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, file_path); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, str8_skip_last_slash(file_path)); dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); start_secondary(); } - else if(expr_string.size != 0) + else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) { dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, expr_string); dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); @@ -3222,13 +3222,12 @@ rd_base_offset_from_eval(E_Eval eval) internal Rng1U64 rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) { - Temp scratch = scratch_begin(0, 0); U64 size = 0; for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) { if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("size"), 0)) { - size = e_eval_from_expr(scratch.arena, param->first->next).value.u64; + size = e_value_from_expr(param->first->next).u64; break; } } @@ -3257,7 +3256,6 @@ rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) Rng1U64 result = {0}; result.min = rd_base_offset_from_eval(eval); result.max = result.min + size; - scratch_end(scratch); return result; } @@ -3283,19 +3281,124 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) { + // rjf: try implicitly from either `eval` itself, or from context + CTRL_Entity *ctrl_entity = rd_ctrl_entity_from_eval_space(eval.space); + CTRL_Entity *process = ctrl_process_from_entity(ctrl_entity); + if(process == &ctrl_entity_nil) + { + process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + } + Arch arch = process->arch; + if(arch == Arch_Null) + { + arch = arch_from_context(); + } + // rjf: try arch parameters + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + String8 param_arch_string = param->string; + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("arch"), 0)) + { + param_arch_string = param->first->next->string; + } + if(str8_match(param->first->next->string, str8_lit("x64"), 0)) + { + arch = Arch_x64; + break; + } + } + + return arch; } internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) { + Vec2S32 dim = v2s32(1, 1); + B32 got_x = 0; + B32 got_y = 0; + // rjf: try explicitly passed dimensions + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define) + { + if(str8_match(param->first->string, str8_lit("w"), 0)) + { + got_x = 1; + dim.x = e_value_from_expr(param->first->next).s64; + } + if(str8_match(param->first->string, str8_lit("h"), 0)) + { + got_y = 1; + dim.y = e_value_from_expr(param->first->next).s64; + } + } + } + + // rjf: try ordered non-define arguments + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind != E_ExprKind_Define) + { + if(!got_x) + { + got_x = 1; + dim.x = e_value_from_expr(param).s64; + } + else if(!got_y) + { + got_y = 1; + dim.y = e_value_from_expr(param).s64; + break; + } + } + } + + return dim; } internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) { + R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; + B32 got_fmt = 0; + // rjf: try explicitly passed formats + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + { + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("fmt"), 0)) + { + got_fmt = 1; + for EachEnumVal(R_Tex2DFormat, f) + { + if(str8_match(param->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } + } + } + } + + // rjf: try implicit non-define arguments + for(E_Expr *param = tag->first->next; param != &e_expr_nil && !got_fmt; param = param->next) + { + if(param->kind == E_ExprKind_LeafIdent) + { + for EachEnumVal(R_Tex2DFormat, f) + { + if(str8_match(param->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } + } + } + } + + return fmt; } //- rjf: pushing/attaching view resources @@ -9222,7 +9325,7 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) } 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, String8List *out) +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_Expr *root_expr, E_Eval eval, String8List *out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -9234,7 +9337,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul B32 no_addr = 0; B32 no_string = 0; B32 has_array = 0; - for(E_Expr *tag = eval.expr->first_tag; tag != &e_expr_nil; tag = tag->next) + for(E_Expr *tag = root_expr->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} else if(str8_match(tag->string, str8_lit("dec"), 0)) {radix = 10;} @@ -9430,7 +9533,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, deref_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); } else { @@ -9553,7 +9656,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } is_first = 0; E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, child_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); if(space_taken > max_size && idx+1 < total_possible_child_count) { String8 ellipses = str8_lit(", ..."); @@ -9589,7 +9692,7 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval, &strs); + rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval.expr, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 2098ca47..03b49a4c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1152,7 +1152,7 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -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, String8List *out); +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_Expr *root_expr, E_Eval eval, 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); //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index be714f74..d92319cb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -5409,8 +5409,8 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - Vec2S32 dim = {0}; // TODO(rjf): @cfg rd_dim2s32_from_eval_params(eval, params); - R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; // TODO(rjf): @cfg rd_tex2dformat_from_eval_params(eval, params); + Vec2S32 dim = rd_dim2s32_from_eval_tag(eval, tag); + R_Tex2DFormat fmt = rd_tex2dformat_from_eval_tag(eval, tag); U64 base_offset = rd_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -5418,11 +5418,11 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: unpack params // - F32 zoom = 1.f; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("zoom")).f32; + F32 zoom = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; Vec2F32 view_center_pos = { - 0.f, // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("x")).f32, - 0.f, // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("y")).f32, + rd_view_cfg_value_from_string(str8_lit("x")).f32, + rd_view_cfg_value_from_string(str8_lit("y")).f32, }; if(zoom == 0) { From 4b85df07259abd241594ffb5368cc2edac09ae9a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 09:44:32 -0800 Subject: [PATCH 074/755] fix expr chain parsing; fix panel tree building --- src/eval/eval_bundles.c | 2 +- src/eval/eval_ir.c | 2 +- src/eval/eval_parse.c | 155 ++++++++---------- src/eval/eval_parse.h | 5 +- .../eval_visualization_builtin_view_rules.c | 2 +- .../eval_visualization_core.c | 4 +- src/raddbg/raddbg_core.c | 52 +----- src/raddbg/raddbg_core.h | 9 - src/raddbg/raddbg_views.c | 4 +- 9 files changed, 84 insertions(+), 151 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 4c9c5f32..b1753efa 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -35,7 +35,7 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); - E_Eval eval = e_eval_from_expr(arena, parse.expr); + E_Eval eval = e_eval_from_expr(arena, parse.last_expr); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index cfa03ed4..7914c058 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -718,7 +718,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.last_expr); type_key = irtree.type_key; } E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index cc9a5232..13ea164b 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1099,7 +1099,7 @@ e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { - E_Parse parse = {0, &e_expr_nil}; + E_Parse parse = {0, &e_expr_nil, &e_expr_nil}; E_Token *token_it = tokens->v; //- rjf: parse unsigned marker @@ -1151,14 +1151,14 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } // rjf: construct leaf type - parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - parse.expr->type_key = type_key; + parse.first_expr = parse.last_expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.first_expr->type_key = type_key; } } } //- rjf: parse extensions - if(parse.expr != &e_expr_nil) + if(parse.first_expr != &e_expr_nil) { for(;;) { @@ -1171,9 +1171,9 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) if(str8_match(token_string, str8_lit("*"), 0)) { token_it += 1; - E_Expr *ptee = parse.expr; - parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); - e_expr_push_child(parse.expr, ptee); + E_Expr *ptee = parse.first_expr; + parse.first_expr = parse.last_expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(parse.first_expr, ptee); } else { @@ -1188,17 +1188,16 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } internal E_Parse -e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence) +e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); E_Token *it = tokens->v; E_Token *it_opl = tokens->v + tokens->count; - E_Parse result = {0, &e_expr_nil}; - E_Expr *last_expr = &e_expr_nil; + E_Parse result = {0, &e_expr_nil, &e_expr_nil}; //- rjf: parse chain of expressions - for(;it < it_opl;) + for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { //- rjf: exit on symbols callers may be waiting on { @@ -1206,7 +1205,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to String8 token_string = str8_substr(text, token.range); if(token.kind == E_TokenKind_Symbol && (str8_match(token_string, str8_lit(")"), 0) || - str8_match(token_string, str8_lit("]"), 0))) + str8_match(token_string, str8_lit("]"), 0) || + str8_match(token_string, str8_lit(":"), 0) || + str8_match(token_string, str8_lit("?"), 0))) { break; } @@ -1286,7 +1287,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse type expr E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; + E_Expr *type = type_parse.last_expr; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; @@ -1367,9 +1368,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse () contents E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; + atom = nested_parse.last_expr; it = nested_parse.last_token; // rjf: expect ) @@ -1395,13 +1396,13 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse [] contents E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; + atom = nested_parse.last_expr; it = nested_parse.last_token; // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.expr == &e_expr_nil) + if(nested_parse.last_expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); } @@ -1777,7 +1778,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to { E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.expr; + E_Expr *type = type_parse.last_expr; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; atom = type; @@ -2050,15 +2051,15 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse indexing expression E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); + E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); it = idx_expr_parse.last_token; // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.expr != &e_expr_nil) + if(idx_expr_parse.last_expr != &e_expr_nil) { E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.expr; + E_Expr *index_expr = idx_expr_parse.last_expr; atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); e_expr_push_child(atom, array_expr); e_expr_push_child(atom, index_expr); @@ -2083,7 +2084,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { + // rjf: skip ( it += 1; + + // rjf: parse all argument expressions E_Expr *callee_expr = atom; E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); if(callee_expr->kind == E_ExprKind_LeafIdent) @@ -2091,34 +2095,31 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to call_expr->string = callee_expr->string; } e_expr_push_child(call_expr, callee_expr); - for(B32 done = 0; !done && it < it_opl;) + E_TokenArray args_parse_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); + e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); + it = args_parse.last_token; + if(args_parse.first_expr != &e_expr_nil) { - E_Token token = e_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0)) + call_expr->last->next = args_parse.first_expr; + args_parse.first_expr->prev = call_expr->last; + call_expr->last = args_parse.last_expr; + } + atom = call_expr; + + // rjf: expect ) + { + E_Token close_paren_maybe = e_token_at_it(it, tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { - done = 1; - it += 1; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `(`."); } else { - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence); - e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs); - if(arg_parse.expr != &e_expr_nil) - { - e_expr_push_child(call_expr, arg_parse.expr); - } - it = arg_parse.last_token; - E_Token maybe_comma = e_token_at_it(it, tokens); - String8 maybe_comma_string = str8_substr(text, token.range); - if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) - { - it += 1; - } + it += 1; } } - atom = call_expr; } // rjf: quit if this doesn't look like any patterns of postfix unary we know @@ -2194,9 +2195,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(binary_precedence != 0 && binary_precedence <= max_precedence) { E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.expr; + E_Expr *rhs = rhs_expr_parse.last_expr; it = rhs_expr_parse.last_token; if(rhs == &e_expr_nil) { @@ -2220,11 +2221,11 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse middle expression E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence); + E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence, 1); it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.expr; + E_Expr *middle_expr = middle_expr_parse.last_expr; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.expr == &e_expr_nil) + if(middle_expr_parse.last_expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); } @@ -2251,12 +2252,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse rhs E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence, 1); if(got_colon) { it = rhs_expr_parse.last_token; e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.expr == &e_expr_nil) + if(rhs_expr_parse.last_expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); } @@ -2264,12 +2265,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: build ternary if(atom != &e_expr_nil && - middle_expr_parse.expr != &e_expr_nil && - rhs_expr_parse.expr != &e_expr_nil) + middle_expr_parse.last_expr != &e_expr_nil && + rhs_expr_parse.last_expr != &e_expr_nil) { E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.expr; - E_Expr *rhs = rhs_expr_parse.expr; + E_Expr *mhs = middle_expr_parse.last_expr; + E_Expr *rhs = rhs_expr_parse.last_expr; atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); e_expr_push_child(atom, lhs); e_expr_push_child(atom, mhs); @@ -2282,38 +2283,15 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to { if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) { - for(B32 done = 0; !done && it < it_opl;) + it += 1; + E_TokenArray tags_tokens = e_token_array_make_first_opl(it, it_opl); + E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, &tags_tokens, e_max_precedence, max_U64); + e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); + it = tags_parse.last_token; + for(E_Expr *tag = tags_parse.first_expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { - E_Token maybe_identifier = e_token_at_it(it, tokens); - E_Token maybe_open_paren = e_token_at_it(it+1, tokens); - String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range); - if(maybe_identifier.kind == E_TokenKind_Identifier && - maybe_open_paren.kind == E_TokenKind_Symbol && - str8_match(maybe_open_paren_string, str8_lit("("), 0)) - { - E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens); - e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs); - it = tag_parse.last_token; - if(tag_parse.expr != &e_expr_nil) - { - e_expr_push_tag(atom, tag_parse.expr); - } - else - { - done = 1; - } - E_Token maybe_comma = e_token_at_it(it, tokens); - String8 maybe_comma_string = str8_substr(text, token.range); - if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0)) - { - it += 1; - } - } - else - { - done = 1; - } + next = tag->next; + e_expr_push_tag(atom, tag); } } } @@ -2328,7 +2306,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: store parsed atom to expression chain - if we didn't get an expression, break if(atom != &e_expr_nil) { - DLLPushBack_NPZ(&e_expr_nil, result.expr, last_expr, atom, next, prev); + DLLPushBack_NPZ(&e_expr_nil, result.first_expr, result.last_expr, atom, next, prev); + chain_count += 1; } else { @@ -2347,7 +2326,7 @@ internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { ProfBegin("parse '%.*s'", str8_varg(text)); - E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence); + E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); ProfEnd(); return parse; } @@ -2359,7 +2338,7 @@ e_parse_expr_from_text(Arena *arena, String8 text) E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); E_Parse parse = e_parse_expr_from_text_tokens(arena, text, &tokens); scratch_end(scratch); - return parse.expr; + return parse.last_expr; } internal E_Parse diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 2b57c552..75c6d399 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -153,7 +153,8 @@ typedef struct E_Parse E_Parse; struct E_Parse { E_Token *last_token; - E_Expr *expr; + E_Expr *first_expr; + E_Expr *last_expr; E_MsgList msgs; }; @@ -290,7 +291,7 @@ internal E_TypeKey e_leaf_type_from_name(String8 name); internal E_TypeKey e_type_from_expr(E_Expr *expr); internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence); +internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); internal E_Expr *e_parse_expr_from_text(Arena *arena, String8 text); internal E_Parse e_parse_expr_from_text__cached(String8 text); diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index edd26587..b8d293c7 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -32,7 +32,7 @@ ev_type_key_from_params(MD_Node *params) String8 expr = md_string_from_children(scratch.arena, params); E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, expr, &tokens); - E_TypeKey type_key = e_type_from_expr(parse.expr); + E_TypeKey type_key = e_type_from_expr(parse.last_expr); scratch_end(scratch); return type_key; } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 719e85d2..9fc3a3e0 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -463,7 +463,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + for(E_Expr *tag = tag_expr_parse.first_expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { next = tag->next; e_expr_push_tag(expr, tag); @@ -488,7 +488,7 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); E_TokenArray root_tokens = e_token_array_from_text(scratch.arena, string); E_Parse root_parse = e_parse_expr_from_text_tokens(arena, string, &root_tokens); - E_Expr *root_expr = root_parse.expr; + E_Expr *root_expr = root_parse.last_expr; ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 92c49185..89d3d206 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -73,46 +73,6 @@ rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs cmds->count += 1; } -//////////////////////////////// -//~ rjf: View Spec Type Functions - -#if 0 // TODO(rjf): @cfg -internal RD_ViewRuleKind -rd_view_rule_kind_from_string(String8 string) -{ - RD_ViewRuleKind kind = RD_ViewRuleKind_Null; - for EachEnumVal(RD_ViewRuleKind, k) - { - if(str8_match(string, rd_view_rule_kind_info_table[k].string, 0)) - { - kind = k; - break; - } - } - return kind; -} - -internal RD_ViewRuleInfo * -rd_view_rule_info_from_kind(RD_ViewRuleKind kind) -{ - return &rd_view_rule_kind_info_table[kind]; -} - -internal RD_ViewRuleInfo * -rd_view_rule_info_from_string(String8 string) -{ - RD_ViewRuleInfo *result = &rd_nil_view_rule_info; - { - RD_ViewRuleKind kind = rd_view_rule_kind_from_string(string); - if(kind != RD_ViewRuleKind_Null) - { - result = &rd_view_rule_kind_info_table[kind]; - } - } - return result; -} -#endif - //////////////////////////////// //~ rjf: View UI Rule Functions @@ -847,7 +807,7 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) } // rjf: extract cfg info - B32 panel_has_tabs = 0; + B32 panel_has_children = 0; dst->cfg = src; dst->pct_of_parent = (F32)f64_from_str8(src->string); dst->tab_side = (rd_cfg_child_from_string(src, str8_lit("tabs_on_bottom")) != &rd_nil_cfg ? Side_Max : Side_Min); @@ -857,7 +817,7 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_child->string); if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) { - // NOTE(rjf): skip - this is a panel. + panel_has_children = 1; } else if(str8_match(src_child->string, str8_lit("tabs_on_bottom"), 0)) { @@ -869,7 +829,6 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) } else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Identifier) { - panel_has_tabs = 1; rd_cfg_list_push(arena, &dst->tabs, src_child); if(rd_cfg_child_from_string(src_child, str8_lit("selected")) != &rd_nil_cfg) { @@ -880,7 +839,7 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) // rjf: recurse rec = rd_cfg_rec__depth_first(src_root, src); - if(panel_has_tabs) + if(!panel_has_children) { MemoryZeroStruct(&rec); rec.next = &rd_nil_cfg; @@ -13165,7 +13124,10 @@ rd_frame(void) E_Parse parse = e_parse_expr_from_text__cached(expr); if(parse.msgs.max_kind == E_MsgKind_Null) { - e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, parse.expr); + for(E_Expr *expr = parse.first_expr; expr != &e_expr_nil; expr = expr->next) + { + e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); + } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 03b49a4c..e2a079ec 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -936,15 +936,6 @@ internal RD_Regs *rd_regs_copy(Arena *arena, RD_Regs *src); internal void rd_cmd_list_push_new(Arena *arena, RD_CmdList *cmds, String8 name, RD_Regs *regs); -//////////////////////////////// -//~ rjf: View Spec Type Functions - -#if 0 // TODO(rjf): @cfg -internal RD_ViewRuleKind rd_view_rule_kind_from_string(String8 string); -internal RD_ViewRuleInfo *rd_view_rule_info_from_kind(RD_ViewRuleKind kind); -internal RD_ViewRuleInfo *rd_view_rule_info_from_string(String8 string); -#endif - //////////////////////////////// //~ rjf: View UI Rule Functions diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d92319cb..a3d6577e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2793,7 +2793,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) String8 string = ev_expr_string_from_row(scratch.arena, row, 0); E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.last_expr); E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); @@ -2815,7 +2815,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) E_Expr *expr; S64 depth; }; - Task start_task = {0, 0, parse.expr}; + Task start_task = {0, 0, parse.last_expr}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) From 2da83dd7327998ce605e56deabcf9739e5955991 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 09:47:37 -0800 Subject: [PATCH 075/755] bump to 0.9.15 - hook disasm back up --- src/base/base_context_cracking.h | 2 +- src/raddbg/raddbg_views.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index bac701dd..ba452a5a 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -159,7 +159,7 @@ #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 14 +# define BUILD_VERSION_PATCH 15 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a3d6577e..c41cc6f8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -4289,7 +4289,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) // B32 auto_selected = 0; E_Space auto_space = {0}; - if(eval.space.kind == E_SpaceKind_Null) + if(eval.expr == &e_expr_nil) { if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { @@ -4344,8 +4344,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); - Arch arch = Arch_Null; // TODO(rjf): @cfg rd_arch_from_eval_params(eval, params); + Rng1U64 range = rd_range_from_eval_tag(eval, tag); + Arch arch = rd_arch_from_eval_tag(eval, tag); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; DI_Key dbgi_key = {0}; From d48cd460d1e643eec8995f7c3680f7a0dd94728d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 12:15:03 -0800 Subject: [PATCH 076/755] begin prepping watch window ui for reintroduction of fancy rows; extend target/thread evaluations with .environment & .call_stack sketch; more convergence progress --- src/dbg_engine/dbg_engine_core.c | 1 + src/eval/eval_ir.c | 8 + src/eval/eval_ir.h | 1 + src/hash_store/hash_store.c | 20 +- src/raddbg/raddbg_core.c | 356 ++++++++++++++++-- src/raddbg/raddbg_views.c | 46 ++- src/raddbg/raddbg_views.h | 9 +- src/raddbg/raddbg_widgets.c | 138 +++---- src/raddbg/raddbg_widgets.h | 20 +- .../rdi_breakpad_from_pdb_main.c | 6 +- 10 files changed, 485 insertions(+), 120 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 6e35ae7d..5c7493cb 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1597,6 +1597,7 @@ d_init(void) d_state->arena = arena; d_state->cmds_arena = arena_alloc(); d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key")); + hs_submit_data(d_state->output_log_key, 0, str8_zero()); d_state->ctrl_entity_store = ctrl_entity_store_alloc(); d_state->ctrl_stop_arena = arena_alloc(); d_state->view_rule_spec_table_size = 1024; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 7914c058..4211b35f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -969,6 +969,14 @@ e_irtree_const_u(Arena *arena, U64 v) return n; } +internal E_IRNode * +e_irtree_leaf_u128(Arena *arena, U128 u128) +{ + E_IRNode *n = e_push_irnode(arena, RDI_EvalOp_ConstU128); + n->value.u128 = u128; + return n; +} + internal E_IRNode * e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c) { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 0e26ed6e..bc642f31 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -398,6 +398,7 @@ internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child); //- rjf: ir subtree building helpers internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v); +internal E_IRNode *e_irtree_leaf_u128(Arena *arena, U128 u128); internal E_IRNode *e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c); internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r); diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 82e84617..26dc64ba 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -108,7 +108,10 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) node = push_array(stripe->arena, HS_Node, 1); } node->hash = hash; - node->arena = *data_arena; + if(data_arena != 0) + { + node->arena = *data_arena; + } node->data = data; node->scope_ref_count = 0; node->key_ref_count = 1; @@ -117,9 +120,15 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) else { existing_node->key_ref_count += 1; - arena_release(*data_arena); + if(data_arena != 0) + { + arena_release(*data_arena); + } + } + if(data_arena != 0) + { + *data_arena = 0; } - *data_arena = 0; } //- rjf: commit this hash to key cache @@ -330,7 +339,10 @@ hs_evictor_thread__entry_point(void *p) { DLLRemove(slot->first, slot->last, n); SLLStackPush(hs_shared->stripes_free_nodes[stripe_idx], n); - arena_release(n->arena); + if(n->arena != 0) + { + arena_release(n->arena); + } } } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 89d3d206..e367567a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4350,6 +4350,7 @@ rd_window_frame(void) { UI_PrefHeight(ui_px(line_edit_height_px, 1.f)) { +#if 0 // TODO(rjf): @cfg UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, @@ -4361,6 +4362,7 @@ rd_window_frame(void) 0, str8(lister->input_buffer, lister->input_string_size), str8_lit("###lister_text_input")); +#endif } } @@ -5042,11 +5044,13 @@ rd_window_frame(void) //- rjf: name editor if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) { +#if 0 // TODO(rjf): @cfg UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, ctrl_entity->string, "Name###ctrl_entity_string_edit_%p", ctrl_entity); if(ui_committed(sig)) { rd_cmd(RD_CmdKind_SetEntityName, .ctrl_entity = ctrl_entity->handle, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); } +#endif } // rjf: copy full path @@ -8730,7 +8734,7 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) } #endif -//- rjf: debug info tables +//- rjf: watch expressions E_LOOKUP_INFO_FUNCTION_DEF(watches) { @@ -8817,6 +8821,8 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) return num; } +//- rjf: local variables + E_LOOKUP_INFO_FUNCTION_DEF(locals) { E_LookupInfo result = {0}; @@ -8857,6 +8863,8 @@ E_LOOKUP_RANGE_FUNCTION_DEF(locals) } } +//- rjf: registers + E_LOOKUP_INFO_FUNCTION_DEF(registers) { Temp scratch = scratch_begin(&arena, 1); @@ -8905,6 +8913,8 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) } } +//- rjf: top-level configurations + typedef struct RD_TopLevelCfgLookupAccel RD_TopLevelCfgLookupAccel; struct RD_TopLevelCfgLookupAccel { @@ -9045,6 +9055,251 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) return num; } +//- rjf: threads / callstacks + +E_LOOKUP_INFO_FUNCTION_DEF(thread) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(thread) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("call_stack"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0])); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(thread) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_ref_member_access(arena, lhs, str8_lit("call_stack")); + } + scratch_end(scratch); +} + +typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; +struct RD_CallStackLookupAccel +{ + Arch arch; + CTRL_CallStack call_stack; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(call_stack) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + U128 u128 = interp.value.u128; + CTRL_Handle handle = {0}; + MemoryCopyStruct(&handle, &u128); + CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + if(entity->kind == CTRL_EntityKind_Thread) + { + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); + accel->arch = entity->arch; + accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); + result.idxed_expr_count = accel->call_stack.total_frame_count; + } + result.user_data = accel; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; + CTRL_CallStack *call_stack = &accel->call_stack; + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->total_frame_count) + { + U64 frame_idx = 0; +#if 0 + for(U64 base_idx = 0; base_idx < call_stack->concrete_frame_count; base_idx += 1, frame_idx += 1) + { + CTRL_CallStackFrame *base_frame = call_stack->frames + base_idx; + for(CTRL_CallStackInlineFrame *inline_frame = base_frame->first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, frame_idx += 1) + { + if(frame_idx == rhs_value.u64) + { + result.irtree_and_type.root = e_irtree_const_u(arena, ); + break; + } + } + } +#endif + } + scratch_end(scratch); + } + return result; +} + +//- rjf: targets / environment + +E_LOOKUP_INFO_FUNCTION_DEF(target) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(target) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("environment"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_const_u(arena, cfg->id); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(target) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_ref_member_access(arena, lhs, str8_lit("environment")); + } + scratch_end(scratch); +} + +E_LOOKUP_INFO_FUNCTION_DEF(environment) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + RD_CfgID id = interpret.value.u64; + RD_Cfg *target = rd_cfg_from_id(id); + RD_Cfg *env = rd_cfg_child_from_string(target, str8_lit("environment")); + RD_CfgList env_strings = {0}; + for(RD_Cfg *child = env->first; child != &rd_nil_cfg; child = child->next) + { + rd_cfg_list_push(scratch.arena, &env_strings, child); + } + RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); + *accel = rd_cfg_array_from_list(arena, &env_strings); + result.user_data = accel; + result.idxed_expr_count = accel->count + 1; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(environment) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *accel = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + U64 rhs_index = rhs_value.u64; + if(contains_1u64(r1u64(0, accel->count), rhs_index)) + { + RD_Cfg *env_string = accel->v[rhs_index]; + E_TypeKey type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(env_string), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//- rjf: control entities + E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) { E_LookupInfo result = {0}; @@ -9113,6 +9368,8 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) return result; } +//- rjf: debug info tables + typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; struct RD_DebugInfoTableLookupAccel { @@ -12932,17 +13189,37 @@ rd_frame(void) } //- rjf: add macros for evallable config trees - String8 evallable_cfg_names[] = + struct { - str8_lit("breakpoint"), - str8_lit("watch_pin"), - str8_lit("target"), - str8_lit("file_path_map"), - str8_lit("auto_view_rule"), + String8 name; + E_LookupInfoFunctionType *info; + E_LookupAccessFunctionType *access; + E_LookupRangeFunctionType *range; + E_LookupIDFromNumFunctionType *id_from_num; + E_LookupNumFromIDFunctionType *num_from_id; + } + evallable_cfg_table[] = + { + { str8_lit("breakpoint") }, + { str8_lit("watch_pin") }, + { str8_lit("target"), .info = E_LOOKUP_INFO_FUNCTION_NAME(target), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(target), .range = E_LOOKUP_RANGE_FUNCTION_NAME(target) }, + { str8_lit("file_path_map") }, + { str8_lit("auto_view_rule") }, }; - for EachElement(idx, evallable_cfg_names) + for EachElement(idx, evallable_cfg_table) { - String8 name = evallable_cfg_names[idx]; + String8 name = evallable_cfg_table[idx].name; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + if(evallable_cfg_table[idx].info != 0) + { + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = evallable_cfg_table[idx].info, + .access = evallable_cfg_table[idx].access, + .range = evallable_cfg_table[idx].range, + .id_from_num = evallable_cfg_table[idx].id_from_num, + .num_from_id = evallable_cfg_table[idx].num_from_id); + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); + } RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { @@ -12953,7 +13230,7 @@ rd_frame(void) E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = space; expr->mode = E_Mode_Offset; - expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + expr->type_key = type_key; e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64u", cfg->id), expr); if(exe.size != 0) { @@ -12967,19 +13244,38 @@ rd_frame(void) } //- rjf: add macros for evallable control entities - String8 evallable_ctrl_names[] = + struct { - str8_lit("machine"), - str8_lit("process"), - str8_lit("thread"), - str8_lit("module"), + String8 name; + E_LookupInfoFunctionType *info; + E_LookupAccessFunctionType *access; + E_LookupRangeFunctionType *range; + E_LookupIDFromNumFunctionType *id_from_num; + E_LookupNumFromIDFunctionType *num_from_id; + } + evallable_ctrl_table[] = + { + { str8_lit("machine") }, + { str8_lit("process") }, + { str8_lit("thread"), .info = E_LOOKUP_INFO_FUNCTION_NAME(thread), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(thread), .range = E_LOOKUP_RANGE_FUNCTION_NAME(thread) }, + { str8_lit("module") }, }; - for EachElement(idx, evallable_ctrl_names) + for EachElement(idx, evallable_ctrl_table) { - String8 name = evallable_ctrl_names[idx]; + String8 name = evallable_ctrl_table[idx].name; CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + if(evallable_ctrl_table[idx].info != 0) + { + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = evallable_ctrl_table[idx].info, + .access = evallable_ctrl_table[idx].access, + .range = evallable_ctrl_table[idx].range, + .id_from_num = evallable_ctrl_table[idx].id_from_num, + .num_from_id = evallable_ctrl_table[idx].num_from_id); + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); + } for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) { CTRL_Entity *entity = n->v; @@ -13008,6 +13304,12 @@ rd_frame(void) e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); } + //- rjf: add macro for 'call_stack' -> 'current_thread.callstack' + { + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("current_thread.call_stack")); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); + } + //- rjf: add macro for watches group { String8 collection_name = str8_lit("watches"); @@ -13021,6 +13323,18 @@ rd_frame(void) .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(watches)); } + //- rjf: add lookup rules for queries + { + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment)); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(call_stack), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(call_stack)); + } + //- rjf: add macro for collections with specific lookup rules (but no unique id rules) { struct @@ -13070,9 +13384,9 @@ rd_frame(void) } //- rjf: add macros for all config collections - for EachElement(cfg_name_idx, evallable_cfg_names) + for EachElement(cfg_name_idx, evallable_cfg_table) { - String8 cfg_name = evallable_cfg_names[cfg_name_idx]; + String8 cfg_name = evallable_cfg_table[cfg_name_idx].name; String8 collection_name = rd_plural_from_code_name(cfg_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); @@ -13086,9 +13400,9 @@ rd_frame(void) } //- rjf: add macros for all ctrl entity collections - for EachElement(ctrl_name_idx, evallable_ctrl_names) + for EachElement(ctrl_name_idx, evallable_ctrl_table) { - String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; + String8 kind_name = evallable_ctrl_table[ctrl_name_idx].name; String8 collection_name = rd_plural_from_code_name(kind_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index c41cc6f8..4cd17116 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -957,8 +957,17 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's cells { +#if 0 + // rjf: singular cell for cfgs + if(info.group_cfg != &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f); + } +#endif + if(0){} + // rjf: singular cell for view ui - if(info.view_ui_rule != &rd_nil_view_ui_rule) + else if(info.view_ui_rule != &rd_nil_view_ui_rule) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); } @@ -2660,17 +2669,24 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: build cell line edit else { - sig = rd_line_editf((RD_LineEditFlag_CodeContents| - RD_LineEditFlag_NoBackground| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)), - cell_x == 0 ? row_depth : 0, - 0, - &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_info.string, - "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); + RD_LineEditParams line_edit_params = {0}; + { + line_edit_params.flags = (RD_LineEditFlag_CodeContents| + RD_LineEditFlag_NoBackground| + RD_LineEditFlag_KeyboardClickable| + RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)); + line_edit_params.depth = (cell_x == 0 ? row_depth : 0); + line_edit_params.cursor = &cell_edit_state->cursor; + line_edit_params.mark = &cell_edit_state->mark; + line_edit_params.edit_buffer = cell_edit_state->input_buffer; + line_edit_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); + line_edit_params.edit_string_size_out = &cell_edit_state->input_size; + line_edit_params.expanded_out = &next_row_expanded; + line_edit_params.pre_edit_value = cell_info.string; + } + sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); #if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && @@ -2718,12 +2734,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) #if 0 // TODO(rjf): @cfg - // rjf: can edit? -> begin editing - else if(cell_can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - // rjf: cannot edit, has addr info? -> go to address else if(row_kind == RD_WatchViewRowKind_Normal && (col->kind == RD_WatchViewColumnKind_Value || diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index f9588f5d..8d724f2b 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -43,10 +43,11 @@ struct RD_CodeViewBuildResult typedef enum RD_WatchCellKind { - RD_WatchCellKind_Expr, // strings to represent expression itself - RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity - RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` - RD_WatchCellKind_ViewUI, + RD_WatchCellKind_Expr, // strings to represent expression itself + RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity + RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` + RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook + RD_WatchCellKind_Button, // a fancy button dedicated to the entire row's evaluation, used for listers/etc. } RD_WatchCellKind; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 8240b5d6..2b7fd381 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2424,7 +2424,7 @@ rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String //~ rjf: UI Widgets: Line Edit internal UI_Signal -rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, String8 string) +rd_line_edit(RD_LineEditParams *params, String8 string) { ProfBeginFunction(); @@ -2450,36 +2450,36 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_set_next_hover_cursor(OS_Cursor_IBar); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - (!!(flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| + (!!(params->flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| UI_BoxFlag_DrawHotEffects| - (!(flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| - (!!(flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| + (!(params->flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| + (!!(params->flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip), key); //- rjf: build indent - UI_Parent(box) for(S32 idx = 0; idx < depth; idx += 1) + UI_Parent(box) for(S32 idx = 0; idx < params->depth; idx += 1) { ui_set_next_flags(UI_BoxFlag_DrawSideLeft); ui_spacer(ui_em(1.f, 1.f)); } //- rjf: build expander - if(flags & RD_LineEditFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) + if(params->flags & RD_LineEditFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) UI_Flags(UI_BoxFlag_DrawSideLeft) UI_Focus(UI_FocusKind_Off) { - UI_Signal expander_sig = ui_expanderf(*expanded_out, "expander"); + UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); if(ui_pressed(expander_sig)) { - *expanded_out ^= 1; + params->expanded_out[0] ^= 1; } } //- rjf: build expander placeholder - else if(flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) + else if(params->flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) { UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_Flags(UI_BoxFlag_DrawSideLeft) @@ -2489,7 +2489,7 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } //- rjf: build expander space - else if(flags & RD_LineEditFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) + else if(params->flags & RD_LineEditFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) { UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); } @@ -2498,7 +2498,7 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx UI_Box *scrollable_box = &ui_nil_box; UI_Parent(box) UI_PrefWidth(ui_children_sum(0)) { - scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", edit_buffer); + scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); } //- rjf: do non-textual edits (delete, copy, cut) @@ -2509,12 +2509,12 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { if(evt->flags & UI_EventFlag_Copy) { - os_set_clipboard_text(pre_edit_value); + os_set_clipboard_text(params->pre_edit_value); } if(evt->flags & UI_EventFlag_Delete) { commit = 1; - edit_string_size_out[0] = 0; + params->edit_string_size_out[0] = 0; } } } @@ -2549,14 +2549,14 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } if(start_editing_via_sig || start_editing_via_typing) { - String8 edit_string = pre_edit_value; - edit_string.size = Min(edit_buffer_size, pre_edit_value.size); - MemoryCopy(edit_buffer, edit_string.str, edit_string.size); - edit_string_size_out[0] = edit_string.size; + String8 edit_string = params->pre_edit_value; + edit_string.size = Min(params->edit_buffer_size, params->pre_edit_value.size); + MemoryCopy(params->edit_buffer, edit_string.str, edit_string.size); + params->edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); ui_kill_action(); - *cursor = txt_pt(1, edit_string.size+1); - *mark = txt_pt(1, 1); + params->cursor[0] = txt_pt(1, edit_string.size+1); + params->mark[0] = txt_pt(1, 1); focus_started = 1; } } @@ -2580,13 +2580,13 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx //- rjf: take navigation actions for editing B32 changes_made = 0; - if(!(flags & RD_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) + if(!(params->flags & RD_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) { Temp scratch = scratch_begin(0, 0); rd_state->text_edit_mode = 1; for(UI_Event *evt = 0; ui_next_event(&evt);) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); // rjf: do not consume anything that doesn't fit a single-line's operations if((evt->kind != UI_EventKind_Edit && evt->kind != UI_EventKind_Navigate && evt->kind != UI_EventKind_Text) || evt->delta_2s32.y != 0) @@ -2595,20 +2595,20 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } // rjf: map this action to an op - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op if(autocomplete_hint_string.size != 0) { - String8 word_query = rd_lister_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 word_query = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); U64 word_off = (U64)(word_query.str - edit_string.str); String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); - new_string.size = Min(edit_buffer_size, new_string.size); - MemoryCopy(edit_buffer, new_string.str, new_string.size); - edit_string_size_out[0] = new_string.size; - *cursor = *mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); - edit_string = str8(edit_buffer, edit_string_size_out[0]); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, *cursor, *mark); + new_string.size = Min(params->edit_buffer_size, new_string.size); + MemoryCopy(params->edit_buffer, new_string.str, new_string.size); + params->edit_string_size_out[0] = new_string.size; + params->cursor[0] = params->mark[0] = txt_pt(1, word_off+1+autocomplete_hint_string.size); + edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); } @@ -2616,9 +2616,9 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) { String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(op.range.min.column, op.range.max.column), op.replace); - new_string.size = Min(edit_buffer_size, new_string.size); - MemoryCopy(edit_buffer, new_string.str, new_string.size); - edit_string_size_out[0] = new_string.size; + new_string.size = Min(params->edit_buffer_size, new_string.size); + MemoryCopy(params->edit_buffer, new_string.str, new_string.size); + params->edit_string_size_out[0] = new_string.size; } // rjf: perform copy @@ -2628,8 +2628,8 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } // rjf: commit op's changed cursor & mark to caller-provided state - *cursor = op.cursor; - *mark = op.mark; + params->cursor[0] = op.cursor; + params->mark[0] = op.mark; // rjf: consume event { @@ -2645,68 +2645,68 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(!is_focus_active && !is_focus_active_disabled && flags & RD_LineEditFlag_CodeContents) + if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); - if(!(flags & RD_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) + if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { - display_string = pre_edit_value; + display_string = params->pre_edit_value; UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if(flags & RD_LineEditFlag_DisplayStringIsCode) + else if(params->flags & RD_LineEditFlag_DisplayStringIsCode) { UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } else { ui_set_next_flags(UI_BoxFlag_DrawTextWeak); UI_Box *box = ui_label(display_string).box; - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } } - else if(!is_focus_active && !is_focus_active_disabled && !(flags & RD_LineEditFlag_CodeContents)) + else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_LineEditFlag_CodeContents)) { String8 display_string = ui_display_part_from_key_string(string); - if(!(flags & RD_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) + if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { - display_string = pre_edit_value; + display_string = params->pre_edit_value; } else { ui_set_next_flags(UI_BoxFlag_DrawTextWeak); } UI_Box *box = ui_label(display_string).box; - if(matches != 0) + if(params->fuzzy_matches != 0) { - ui_box_equip_fuzzy_match_ranges(box, matches); + ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if((is_focus_active || is_focus_active_disabled) && flags & RD_LineEditFlag_CodeContents) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_LineEditFlag_CodeContents) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); DR_FancyStringList code_fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); if(autocomplete_hint_string.size != 0) { - String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, cursor->column-1); + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); U64 off = 0; - U64 cursor_off = cursor->column-1; + U64 cursor_off = params->cursor->column-1; DR_FancyStringNode *prev_n = 0; for(DR_FancyStringNode *n = code_fancy_strings.first; n != 0; n = n->next) { @@ -2768,28 +2768,28 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); - draw_data->cursor = *cursor; - draw_data->mark = *mark; + draw_data->cursor = params->cursor[0]; + draw_data->mark = params->mark[0]; ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; scratch_end(scratch); } - else if((is_focus_active || is_focus_active_disabled) && !(flags & RD_LineEditFlag_CodeContents)) + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_LineEditFlag_CodeContents)) { - String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); - draw_data->cursor = *cursor; - draw_data->mark = *mark; + draw_data->cursor = params->cursor[0]; + draw_data->mark = params->mark[0]; ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; } } @@ -2798,18 +2798,18 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { if(ui_pressed(sig)) { - *mark = mouse_pt; + params->mark[0] = mouse_pt; } - *cursor = mouse_pt; + params->cursor[0] = mouse_pt; } if(!is_focus_active && is_focus_active_disabled && ui_pressed(sig)) { - *cursor = *mark = mouse_pt; + params->cursor[0] = params->mark[0] = mouse_pt; } //- rjf: focus cursor { - F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*depth; + F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) { Rng1F32 cursor_range_px = r1f32(cursor_off-ui_top_font_size()*2.f, cursor_off+ui_top_font_size()*2.f); @@ -2838,14 +2838,14 @@ rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } internal UI_Signal -rd_line_editf(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, char *fmt, ...) +rd_line_editf(RD_LineEditParams *params, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - UI_Signal sig = rd_line_edit(flags, depth, matches, cursor, mark, edit_buffer, edit_buffer_size, edit_string_size_out, expanded_out, pre_edit_value, string); + UI_Signal sig = rd_line_edit(params, string); scratch_end(scratch); return sig; } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 3774f7fe..bad8acbf 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -22,6 +22,22 @@ enum RD_LineEditFlag_DisplayStringIsCode = (1<<9), }; +typedef struct RD_LineEditParams RD_LineEditParams; +struct RD_LineEditParams +{ + RD_LineEditFlags flags; + S32 depth; + FuzzyMatchRangeList *fuzzy_matches; + TxtPt *cursor; + TxtPt *mark; + U8 *edit_buffer; + U64 edit_buffer_size; + U64 *edit_string_size_out; + B32 *expanded_out; + String8 pre_edit_value; + DR_FancyStringList fancy_strings; +}; + //////////////////////////////// //~ rjf: Code Slice Types @@ -114,7 +130,7 @@ internal UI_Box *rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 b //////////////////////////////// //~ rjf: UI Widgets: Line Edit -internal UI_Signal rd_line_edit(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, String8 string); -internal UI_Signal rd_line_editf(RD_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, U64 *edit_string_size_out, B32 *expanded_out, String8 pre_edit_value, char *fmt, ...); +internal UI_Signal rd_line_edit(RD_LineEditParams *params, String8 string); +internal UI_Signal rd_line_editf(RD_LineEditParams *params, char *fmt, ...); #endif // RADDBG_WIDGETS_H diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index 45239fd6..0a3f52cb 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -25,7 +25,8 @@ #include "rdi_make/rdi_make_local.h" #include "coff/coff.h" #include "codeview/codeview.h" -#include "codeview/codeview_stringize.h" +#include "codeview/codeview_parse.h" +#include "codeview/codeview_enum.h" #include "msf/msf.h" #include "msf/msf_parse.h" #include "pdb/pdb.h" @@ -40,7 +41,8 @@ #include "rdi_make/rdi_make_local.c" #include "coff/coff.c" #include "codeview/codeview.c" -#include "codeview/codeview_stringize.c" +#include "codeview/codeview_parse.c" +#include "codeview/codeview_enum.c" #include "msf/msf.c" #include "msf/msf_parse.c" #include "pdb/pdb.c" From 3b19334075f421f92221287bae41884748a6f48c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 14:12:44 -0800 Subject: [PATCH 077/755] tear out old meta evaluation code; robustify filesystem streaming async reads --- src/ctrl/ctrl_core.c | 184 ++++++++++--------- src/ctrl/ctrl_core.h | 246 +------------------------ src/dbg_engine/dbg_engine_core.c | 8 +- src/dbg_engine/dbg_engine_core.h | 2 +- src/file_stream/file_stream.c | 28 +-- src/raddbg/raddbg_core.c | 306 +++++++------------------------ src/raddbg/raddbg_core.h | 26 --- 7 files changed, 183 insertions(+), 617 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 4d285810..4ab0d345 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -216,7 +216,6 @@ ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src) dst->env_string_list = str8_list_copy(arena, &src->env_string_list); dst->traps = ctrl_trap_list_copy(arena, &src->traps); dst->user_bps = ctrl_user_breakpoint_list_copy(arena, &src->user_bps); - dst->meta_evals = *deep_copy_from_struct(arena, CTRL_MetaEvalArray, &src->meta_evals); } //- rjf: list building @@ -347,10 +346,6 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs) str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->condition.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->condition.str, bp->condition.size); } - - // rjf: write meta-eval-info array - String8 meta_evals_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEvalArray, &msg->meta_evals); - str8_serial_push_string(scratch.arena, &msgs_srlzed, meta_evals_srlzed); } } String8 string = str8_serial_end(arena, &msgs_srlzed); @@ -474,12 +469,6 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string) bp->condition.str = push_array_no_zero(arena, U8, bp->condition.size); read_off += str8_deserial_read(string, read_off, bp->condition.str, bp->condition.size, 1); } - - // rjf: read meta-eval-info array - String8 meta_evals_data = str8_skip(string, read_off); - U64 meta_evals_size = 0; - msg->meta_evals = *struct_from_serialized(arena, CTRL_MetaEvalArray, meta_evals_data, .advance_out = &meta_evals_size); - read_off += meta_evals_size; } } return msgs; @@ -1320,7 +1309,6 @@ ctrl_init(void) ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); ctrl_state->user_entry_point_arena = arena_alloc(); - ctrl_state->user_meta_eval_arena = arena_alloc(); ctrl_state->dbg_dir_arena = arena_alloc(); for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) { @@ -3009,44 +2997,114 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind) { + Temp scratch = scratch_begin(&arena, 1); Arch arch = process->arch; CTRL_CallStack result = {0}; - result.concrete_frame_count = base_unwind->frames.count; - result.total_frame_count = result.concrete_frame_count; - result.frames = push_array(arena, CTRL_CallStackFrame, result.concrete_frame_count); - for(U64 idx = 0; idx < result.concrete_frame_count; idx += 1) { - CTRL_UnwindFrame *src = &base_unwind->frames.v[idx]; - CTRL_CallStackFrame *dst = &result.frames[idx]; - U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff); - - // rjf: fill concrete frame info - dst->regs = src->regs; - dst->rdi = rdi; - dst->procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx); - - // rjf: push inline frames - for(RDI_Scope *s = scope; - s->inline_site_idx != 0; - s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx)) + typedef struct FrameNode FrameNode; + struct FrameNode { - RDI_InlineSite *site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); - CTRL_CallStackInlineFrame *inline_frame = push_array(arena, CTRL_CallStackInlineFrame, 1); - DLLPushFront(dst->first_inline_frame, dst->last_inline_frame, inline_frame); - inline_frame->inline_site = site; - dst->inline_frame_count += 1; - result.inline_frame_count += 1; - result.total_frame_count += 1; + FrameNode *next; + CTRL_CallStackFrame v; + }; + + //- rjf: gather all frames + FrameNode *first_frame = 0; + FrameNode *last_frame = 0; + U64 frame_count = 0; + for(U64 base_frame_idx = 0; base_frame_idx < base_unwind->frames.count; base_frame_idx += 1) + { + // rjf: unpack + CTRL_UnwindFrame *src = &base_unwind->frames.v[base_frame_idx]; + U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); + U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff); + + // rjf: build inline frames (minus parent & inline depth) + FrameNode *first_inline_frame = 0; + FrameNode *last_inline_frame = 0; + U64 inline_frame_count = 0; + for(RDI_Scope *s = scope; + s->inline_site_idx != 0; + s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx)) + { + FrameNode *dst_inline = push_array(scratch.arena, FrameNode, 1); + if(first_inline_frame == 0) + { + first_inline_frame = dst_inline; + } + last_inline_frame = dst_inline; + SLLQueuePush(first_frame, last_frame, dst_inline); + dst_inline->v.unwind_count = base_frame_idx; + dst_inline->v.regs = src->regs; + dst_inline->v.rdi = rdi; + dst_inline->v.inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + frame_count += 1; + inline_frame_count += 1; + } + + // rjf: build concrete frame + FrameNode *dst_base = push_array(scratch.arena, FrameNode, 1); + SLLQueuePush(first_frame, last_frame, dst_base); + dst_base->v.unwind_count = base_frame_idx; + dst_base->v.regs = src->regs; + dst_base->v.rdi = rdi; + dst_base->v.procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx); + frame_count += 1; + + // rjf: hook up inline frames to point to concrete frame, and to account for inline depth + U64 inline_frame_idx = 0; + for(FrameNode *inline_frame = first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, inline_frame_idx += 1) + { + inline_frame->v.parent_num = frame_count; + inline_frame->v.inline_depth = inline_frame_count - inline_frame_idx; + } + } + + //- rjf: package + result.count = frame_count; + result.frames = push_array(arena, CTRL_CallStackFrame, result.count); + { + U64 idx = 0; + for(FrameNode *n = first_frame; n != 0; n = n->next, idx += 1) + { + MemoryCopyStruct(&result.frames[idx], &n->v); + } } } + scratch_end(scratch); return result; } +internal CTRL_CallStackFrame * +ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth) +{ + CTRL_CallStackFrame *f = 0; + { + U64 base_frame_idx = 0; + for(U64 idx = 0; idx < call_stack->count; idx += 1) + { + if(call_stack->frames[idx].parent_num == 0) + { + if(base_frame_idx == unwind_count) + { + f = &call_stack->frames[idx]; + break; + } + base_frame_idx += 1; + } + } + if(f != 0 && call_stack->frames + inline_depth < f) + { + f -= inline_depth; + } + } + return f; +} + //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -3257,8 +3315,6 @@ ctrl_thread__entry_point(void *p) //- rjf: unpack per-message parameterizations & store { MemoryCopyArray(ctrl_state->exception_code_filters, msg->exception_code_filters); - arena_clear(ctrl_state->user_meta_eval_arena); - ctrl_state->user_meta_evals = *deep_copy_from_struct(ctrl_state->user_meta_eval_arena, CTRL_MetaEvalArray, &msg->meta_evals); } //- rjf: process message @@ -4419,37 +4475,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: meta evaluations case CTRL_EvalSpaceKind_Meta: { - Temp scratch = scratch_begin(0, 0); - U64 meta_eval_idx = space.u64s[0]; - if(meta_eval_idx < ctrl_state->user_meta_evals.count) - { - CTRL_MetaEval *meval = &ctrl_state->user_meta_evals.v[meta_eval_idx]; - - // 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 actual read - Rng1U64 legal_range = r1u64(0, pos_opl-pos_min); - if(contains_1u64(legal_range, range.min)) - { - result = 1; - U64 range_dim = dim_1u64(range); - U64 bytes_to_read = Min(range_dim, (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); - } - } - } - scratch_end(scratch); + }break; } return result; @@ -5503,16 +5529,6 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) E_IRCtx *ctx = &ir_ctx; ctx->macro_map = push_array(temp.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(temp.arena, 512); - E_TypeKey meval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); - for EachIndex(idx, ctrl_state->user_meta_evals.count) - { - E_Space space = e_space_make(CTRL_EvalSpaceKind_Meta); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = meval_type_key; - e_string2expr_map_insert(temp.arena, ctx->macro_map, ctrl_state->user_meta_evals.v[idx].label, expr); - } } e_select_ir_ctx(&ir_ctx); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 73e0d3eb..071748d4 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -12,229 +12,6 @@ typedef U64 CTRL_MachineID; #define CTRL_MachineID_Local (1) -//////////////////////////////// -//~ rjf: Meta Evaluation Types - -//- rjf: auto-checkbox b32s - -typedef struct CTRL_CheckB32 CTRL_CheckB32; -struct CTRL_CheckB32 -{ - B32 b32; -}; - -struct_members(CTRL_CheckB32) -{ - member_lit_comp(CTRL_CheckB32, type(B32), b32), -}; -struct_type(CTRL_CheckB32); - -//- rjf: styled string types - -ptr_type(CTRL_PlainString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPlainText,.count_delimiter_name = str8_lit_comp("size")); -ptr_type(CTRL_CodeString8__str_ptr_type, type(U8), .flags = TypeFlag_IsCodeText, .count_delimiter_name = str8_lit_comp("size")); -ptr_type(CTRL_PathString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPathText, .count_delimiter_name = str8_lit_comp("size")); -Member CTRL_PlainString8__members[] = -{ - member_lit_comp(String8, &CTRL_PlainString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -Member CTRL_CodeString8__members[] = -{ - member_lit_comp(String8, &CTRL_CodeString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -Member CTRL_PathString8__members[] = -{ - member_lit_comp(String8, &CTRL_PathString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), - member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), -}; -named_struct_type(CTRL_PlainString8, String8, .name = str8_lit_comp("string")); -named_struct_type(CTRL_CodeString8, String8, .name = str8_lit_comp("string")); -named_struct_type(CTRL_PathString8, String8, .name = str8_lit_comp("string")); - -//- rjf: meta evaluation callstack types - -typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame; -struct CTRL_MetaEvalFrame -{ - U64 vaddr; - U64 inline_depth; -}; -ptr_type(CTRL_MetaEvalFrame__vaddr_type, type(void), .flags = TypeFlag_IsExternal, .size = sizeof(U64)); -struct_members(CTRL_MetaEvalFrame) -{ - member_lit_comp(CTRL_MetaEvalFrame, &CTRL_MetaEvalFrame__vaddr_type, vaddr), - member_lit_comp(CTRL_MetaEvalFrame, type(U64), inline_depth), -}; -struct_type(CTRL_MetaEvalFrame, .name = str8_lit_comp("callstack_frame")); -typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray; -struct CTRL_MetaEvalFrameArray -{ - U64 count; - CTRL_MetaEvalFrame *v; -}; -ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count")); -struct_members(CTRL_MetaEvalFrameArray) -{ - member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count, .pretty_name = str8_lit_comp("Frame Count")), - {str8_lit_comp("v"), str8_lit_comp("Frame Addresses"), &CTRL_MetaEvalFrameArray__v_ptr_type, OffsetOf(CTRL_MetaEvalFrameArray, v)}, -}; -struct_type(CTRL_MetaEvalFrameArray, .name = str8_lit_comp("callstack_frames")); - -//- rjf: meta evaluation instance types - -typedef struct CTRL_MetaEval CTRL_MetaEval; -struct CTRL_MetaEval -{ -#define CTRL_MetaEval_MemberXList \ -X(B32, enabled, "Enabled")\ -X(B32, frozen, "Frozen")\ -X(U64, hit_count, "Hit Count")\ -X(U64, id, "ID")\ -X(Rng1U64, vaddr_range, "Address Range")\ -X(U32, color, "Color")\ -X(CTRL_CheckB32, debug_subprocesses,"Debug Subprocesses")\ -Y(String8, type(CTRL_CodeString8), label, "Label")\ -Y(String8, type(CTRL_PathString8), exe, "Executable Path")\ -Y(String8, type(CTRL_PathString8), dbg, "Debug Info Path")\ -Y(String8, type(CTRL_PlainString8), args, "Arguments")\ -Y(String8, type(CTRL_PathString8), working_directory, "Working Directory")\ -Y(String8, type(CTRL_CodeString8), entry_point, "Custom Entry Point")\ -Y(String8, type(CTRL_PathString8), stdout_path, "Standard Output Path")\ -Y(String8, type(CTRL_PathString8), stderr_path, "Standard Error Path")\ -Y(String8, type(CTRL_PathString8), stdin_path, "Standard Input Path")\ -Y(String8, type(CTRL_PathString8), source_location, "Source Location")\ -Y(String8, type(CTRL_CodeString8), function_location, "Function Location")\ -Y(String8, type(CTRL_CodeString8), address_location, "Address Location")\ -Y(String8, type(CTRL_PathString8), source_path, "Source Path")\ -Y(String8, type(CTRL_PathString8), destination_path, "Destination Path")\ -Y(String8, type(CTRL_CodeString8), type, "Type")\ -Y(String8, type(CTRL_CodeString8), view_rule, "View Rule")\ -Y(String8, type(CTRL_CodeString8), condition, "Condition")\ -X(CTRL_MetaEvalFrameArray, callstack, "Call Stack") -#define X(T, name, pretty_name) T name; -#define Y(T, ti, name, pretty_name) T name; - CTRL_MetaEval_MemberXList -#undef X -#undef Y -}; -struct_members(CTRL_MetaEval) -{ -#define X(T, name, pretty_name_) member_lit_comp(CTRL_MetaEval, type(T), name, .pretty_name = str8_lit_comp(pretty_name_)), -#define Y(T, ti, name, pretty_name_) member_lit_comp(CTRL_MetaEval, (ti), name, .pretty_name = str8_lit_comp(pretty_name_)), - CTRL_MetaEval_MemberXList -#undef X -#undef Y -}; -struct_type(CTRL_MetaEval); - -//- rjf: filters on main meta evaluation bundle - -struct_members(CTRL_BreakpointMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), enabled, .pretty_name = str8_lit_comp("Enabled")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(U64), hit_count, .pretty_name = str8_lit_comp("Hit Count")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), condition, .pretty_name = str8_lit_comp("Condition")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), function_location, .pretty_name = str8_lit_comp("Function Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")), -}; - -struct_members(CTRL_TargetMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PlainString8),args, .pretty_name = str8_lit_comp("Arguments")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), working_directory, .pretty_name = str8_lit_comp("Working Directory")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), entry_point, .pretty_name = str8_lit_comp("Custom Entry Point")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdout_path, .pretty_name = str8_lit_comp("Standard Output Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stderr_path, .pretty_name = str8_lit_comp("Standard Error Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdin_path, .pretty_name = str8_lit_comp("Standard Input Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CheckB32), debug_subprocesses, .pretty_name = str8_lit_comp("Debug Subprocesses")), -}; - -struct_members(CTRL_PinMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Expression")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")), -}; - -struct_members(CTRL_FilePathMapMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_path, .pretty_name = str8_lit_comp("Source Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), destination_path, .pretty_name = str8_lit_comp("Destination Path")), -}; - -struct_members(CTRL_AutoViewRuleMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), type, .pretty_name = str8_lit_comp("Type")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), view_rule, .pretty_name = str8_lit_comp("View Rule")), -}; - -struct_members(CTRL_MachineMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), -}; - -struct_members(CTRL_ProcessMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")), -}; - -struct_members(CTRL_ModuleMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable Path")), - member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), dbg, .pretty_name = str8_lit_comp("Debug Info Path")), - member_lit_comp(CTRL_MetaEval, type(Rng1U64), vaddr_range, .pretty_name = str8_lit_comp("Address Range")), -}; - -struct_members(CTRL_ThreadMetaEval) -{ - member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")), - member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), - member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")), - member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")), - member_lit_comp(CTRL_MetaEval, type(CTRL_MetaEvalFrameArray), callstack, .pretty_name = str8_lit_comp("Call Stack")), -}; - -named_struct_type(CTRL_BreakpointMetaEval, CTRL_MetaEval, .name = str8_lit_comp("breakpoint")); -named_struct_type(CTRL_TargetMetaEval, CTRL_MetaEval, .name = str8_lit_comp("target")); -named_struct_type(CTRL_PinMetaEval, CTRL_MetaEval, .name = str8_lit_comp("pin")); -named_struct_type(CTRL_FilePathMapMetaEval, CTRL_MetaEval, .name = str8_lit_comp("file_path_map")); -named_struct_type(CTRL_AutoViewRuleMetaEval,CTRL_MetaEval, .name = str8_lit_comp("auto_view_rule")); -named_struct_type(CTRL_MachineMetaEval, CTRL_MetaEval, .name = str8_lit_comp("machine")); -named_struct_type(CTRL_ProcessMetaEval, CTRL_MetaEval, .name = str8_lit_comp("process")); -named_struct_type(CTRL_ModuleMetaEval, CTRL_MetaEval, .name = str8_lit_comp("module")); -named_struct_type(CTRL_ThreadMetaEval, CTRL_MetaEval, .name = str8_lit_comp("thread")); - -//- rjf: meta evaluation array - -typedef struct CTRL_MetaEvalArray CTRL_MetaEvalArray; -struct CTRL_MetaEvalArray -{ - CTRL_MetaEval *v; - U64 count; -}; -ptr_type(CTRL_MetaEvalArray__v_ptr_type, type(CTRL_BreakpointMetaEval), .count_delimiter_name = str8_lit_comp("count")); -struct_members(CTRL_MetaEvalArray) -{ - {str8_lit_comp("v"), {0}, &CTRL_MetaEvalArray__v_ptr_type, OffsetOf(CTRL_MetaEvalArray, v)}, - member_lit_comp(CTRL_MetaEvalArray, type(U64), count), -}; -struct_type(CTRL_MetaEvalArray); - //////////////////////////////// //~ rjf: Entity Handle Types @@ -404,32 +181,23 @@ struct CTRL_Unwind //////////////////////////////// //~ rjf: Call Stack Types -typedef struct CTRL_CallStackInlineFrame CTRL_CallStackInlineFrame; -struct CTRL_CallStackInlineFrame -{ - CTRL_CallStackInlineFrame *next; - CTRL_CallStackInlineFrame *prev; - RDI_InlineSite *inline_site; -}; - typedef struct CTRL_CallStackFrame CTRL_CallStackFrame; struct CTRL_CallStackFrame { - CTRL_CallStackInlineFrame *first_inline_frame; - CTRL_CallStackInlineFrame *last_inline_frame; - U64 inline_frame_count; + U64 parent_num; + U64 unwind_count; + U64 inline_depth; void *regs; RDI_Parsed *rdi; RDI_Procedure *procedure; + RDI_InlineSite *inline_site; }; typedef struct CTRL_CallStack CTRL_CallStack; struct CTRL_CallStack { CTRL_CallStackFrame *frames; - U64 concrete_frame_count; - U64 inline_frame_count; - U64 total_frame_count; + U64 count; }; //////////////////////////////// @@ -573,7 +341,6 @@ struct CTRL_Msg String8 stdin_path; CTRL_TrapList traps; CTRL_UserBreakpointList user_bps; - CTRL_MetaEvalArray meta_evals; }; typedef struct CTRL_MsgNode CTRL_MsgNode; @@ -909,8 +676,6 @@ struct CTRL_State DMN_EventNode *free_dmn_event_node; Arena *user_entry_point_arena; String8List user_entry_points; - Arena *user_meta_eval_arena; - CTRL_MetaEvalArray user_meta_evals; U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; U64 process_counter; Arena *dbg_dir_arena; @@ -1121,6 +886,7 @@ internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *sto //~ rjf: Call Stack Building Functions internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind); +internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth); //////////////////////////////// //~ rjf: Halting All Attached Processes diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 5c7493cb..2ec23504 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1631,7 +1631,7 @@ d_init(void) } internal D_EventList -d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals) +d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -1972,7 +1972,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->debug_subprocesses = target->debug_subprocesses; msg->env_inherit = 1; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name); msg->env_string_list = env; } @@ -2005,7 +2004,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->exit_code = 1; msg->entity = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; case D_CmdKind_KillAll: @@ -2014,7 +2012,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_KillAll; msg->exit_code = 1; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); }break; case D_CmdKind_Detach: { @@ -2029,7 +2026,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_Detach; msg->entity = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; case D_CmdKind_Continue: @@ -2305,7 +2301,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->kind = CTRL_MsgKind_Attach; msg->entity_id = pid; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); } }break; } @@ -2327,7 +2322,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P msg->entity = run_thread->handle; msg->parent = process->handle; MemoryCopyArray(msg->exception_code_filters, exception_code_filters); - MemoryCopyStruct(&msg->meta_evals, meta_evals); MemoryCopyStruct(&msg->traps, &run_traps); D_BreakpointArray *bp_batches[] = { diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index f39bbde7..1a83ba35 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -495,6 +495,6 @@ internal B32 d_next_cmd(D_Cmd **cmd); //~ rjf: Main Layer Top-Level Calls internal void d_init(void); -internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals); +internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]); #endif // DBG_ENGINE_CORE_H diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index cd161dd8..b28f630d 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -328,8 +328,11 @@ ASYNC_WORK_DEF(fs_stream_work) os_file_close(file); FileProperties post_props = os_properties_from_file_path(path); - //- rjf: abort if modification timestamps differ - we did not successfully read the file - if(pre_props.modified != post_props.modified) + //- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file + B32 read_good = (pre_props.modified == post_props.modified && + pre_props.size == post_props.size && + read_size == data.size); + if(!read_good) { ProfScope("abort") { @@ -360,29 +363,14 @@ ASYNC_WORK_DEF(fs_stream_work) break; } } - if(node != 0) + if(node != 0 && read_good) { if(node->timestamp != 0) { ins_atomic_u64_inc_eval(&fs_shared->change_gen); } - if(post_props.modified == pre_props.modified) - { - node->timestamp = post_props.modified; - node->size = post_props.size; - } - U64 range_hash = fs_little_hash_from_string(str8_struct(&range)); - U64 range_slot_idx = range_hash%node->slots_count; - FS_RangeSlot *range_slot = &node->slots[range_slot_idx]; - FS_RangeNode *range_node = 0; - for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next) - { - if(MemoryMatchStruct(&n->range, &range)) - { - range_node = n; - break; - } - } + node->timestamp = post_props.modified; + node->size = post_props.size; } } os_condition_variable_broadcast(path_stripe->cv); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e367567a..dea44896 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2017,52 +2017,6 @@ rd_eval_blob_from_entity__cached(CTRL_Entity *entity) return result; } -//- rjf: entity -> meta eval - -internal CTRL_MetaEval * -rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) -{ - ProfBeginFunction(); - CTRL_MetaEval *meval = push_array(arena, CTRL_MetaEval, 1); - meval->frozen = entity->is_frozen; - meval->vaddr_range = entity->vaddr_range; - meval->color = entity->rgba; - meval->label = entity->string; - meval->id = entity->id; - if(entity->kind == CTRL_EntityKind_Thread) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(arena, di_scope, process, &base_unwind); - meval->callstack.count = rich_unwind.total_frame_count; - meval->callstack.v = push_array(arena, CTRL_MetaEvalFrame, meval->callstack.count); - U64 idx = 0; - for(U64 base_idx = 0; base_idx < rich_unwind.concrete_frame_count; base_idx += 1) - { - U64 inline_idx = 0; - for(CTRL_CallStackInlineFrame *f = rich_unwind.frames[base_idx].first_inline_frame; f != 0; f = f->next, inline_idx += 1) - { - meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs); - meval->callstack.v[idx].inline_depth = inline_idx + 1; - idx += 1; - } - meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs); - idx += 1; - } - di_scope_close(di_scope); - } - if(entity->kind == CTRL_EntityKind_Module) - { - DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); - meval->label = str8_skip_last_slash(entity->string); - meval->exe = path_normalized_from_string(arena, entity->string); - meval->dbg = path_normalized_from_string(arena, dbgi_key.path); - } - ProfEnd(); - return meval; -} - //- rjf: eval space reads/writes internal B32 @@ -2070,8 +2024,6 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); B32 result = 0; - CTRL_MetaEval *meval_read = 0; - Rng1U64 meval_legal_range = {0}; switch(space.kind) { //- rjf: filesystem reads @@ -3954,49 +3906,37 @@ rd_window_frame(void) { CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - if(rich_unwind.concrete_frame_count != 0) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + if(call_stack.count != 0) { ui_spacer(ui_em(1.5f, 1.f)); } - for(U64 idx = 0; idx < rich_unwind.concrete_frame_count; idx += 1) + for(U64 idx = 0; idx < call_stack.count; idx += 1) { - CTRL_CallStackFrame *f = &rich_unwind.frames[idx]; + CTRL_CallStackFrame *f = &call_stack.frames[idx]; RDI_Parsed *rdi = f->rdi; RDI_Procedure *procedure = f->procedure; U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string); - - // rjf: inline frames - for(CTRL_CallStackInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev) - UI_PrefWidth(ui_children_sum(1)) UI_Row - { - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, fin->inline_site->name_string_idx, &name.size); - name.size = Min(512, name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - } - - // rjf: concrete frame UI_PrefWidth(ui_children_sum(1)) UI_Row { String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - name.size = Min(512, name.size); + if(f->inline_site != 0) + { + name.str = rdi_string_from_idx(rdi, f->inline_site->name_string_idx, &name.size); + name.size = Min(512, name.size); + } + else if(f->procedure != 0) + { + name.str = rdi_name_from_procedure(rdi, procedure, &name.size); + name.size = Min(512, name.size); + } UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); + if(f->parent_num != 0) + { + RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); + } if(name.size != 0) { RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) @@ -5070,56 +5010,6 @@ rd_window_frame(void) ui_ctx_menu_close(); } - // rjf: copy call stack - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Call Stack"))) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - String8List lines = {0}; - for(U64 frame_idx = 0; frame_idx < rich_unwind.concrete_frame_count; frame_idx += 1) - { - CTRL_CallStackFrame *concrete_frame = &rich_unwind.frames[frame_idx]; - U64 rip_vaddr = regs_rip_from_arch_block(ctrl_entity->arch, concrete_frame->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - RDI_Parsed *rdi = concrete_frame->rdi; - RDI_Procedure *procedure = concrete_frame->procedure; - for(CTRL_CallStackInlineFrame *inline_frame = concrete_frame->last_inline_frame; - inline_frame != 0; - inline_frame = inline_frame->prev) - { - RDI_InlineSite *inline_site = inline_frame->inline_site; - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string); - } - if(procedure != 0) - { - String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string); - } - else if(module != &ctrl_entity_nil) - { - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in %S]", rip_vaddr, module->string); - } - else - { - str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in ???]", rip_vaddr); - } - } - StringJoin join = {0}; - join.sep = join.post = str8_lit("\n"); - String8 text = str8_list_join(scratch.arena, &lines, &join); - os_set_clipboard_text(text); - ui_ctx_menu_close(); - di_scope_close(di_scope); - } - } - // rjf: find if(ctrl_entity->kind == CTRL_EntityKind_Thread) { @@ -9101,6 +8991,7 @@ typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; struct RD_CallStackLookupAccel { Arch arch; + CTRL_Handle process; CTRL_CallStack call_stack; }; @@ -9122,8 +9013,9 @@ E_LOOKUP_INFO_FUNCTION_DEF(call_stack) CTRL_Entity *process = ctrl_process_from_entity(entity); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); accel->arch = entity->arch; + accel->process = process->handle; accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); - result.idxed_expr_count = accel->call_stack.total_frame_count; + result.idxed_expr_count = accel->call_stack.count; } result.user_data = accel; } @@ -9144,23 +9036,13 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) E_Value rhs_value = rhs_interp.value; RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; CTRL_CallStack *call_stack = &accel->call_stack; - if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->total_frame_count) + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) { - U64 frame_idx = 0; -#if 0 - for(U64 base_idx = 0; base_idx < call_stack->concrete_frame_count; base_idx += 1, frame_idx += 1) - { - CTRL_CallStackFrame *base_frame = call_stack->frames + base_idx; - for(CTRL_CallStackInlineFrame *inline_frame = base_frame->first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, frame_idx += 1) - { - if(frame_idx == rhs_value.u64) - { - result.irtree_and_type.root = e_irtree_const_u(arena, ); - break; - } - } - } -#endif + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); + CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); + result.irtree_and_type.type_key = e_type_key_cons_ptr(process->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); + result.irtree_and_type.mode = E_Mode_Value; } scratch_end(scratch); } @@ -9234,30 +9116,20 @@ E_LOOKUP_INFO_FUNCTION_DEF(environment) return result; } -E_LOOKUP_ACCESS_FUNCTION_DEF(environment) +E_LOOKUP_RANGE_FUNCTION_DEF(environment) { - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) { - Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *accel = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - U64 rhs_index = rhs_value.u64; - if(contains_1u64(r1u64(0, accel->count), rhs_index)) + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) { - RD_Cfg *env_string = accel->v[rhs_index]; - E_TypeKey type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(env_string), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = type_key; - result.irtree_and_type.mode = E_Mode_Offset; + } - scratch_end(scratch); } - return result; } E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) @@ -12351,8 +12223,6 @@ rd_frame(void) } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; - rd_state->ctrl_entity_meval_cache_slots_count = 1024; - rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count); 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); @@ -13080,7 +12950,6 @@ rd_frame(void) //////////////////////////// //- rjf: build eval IR context // - E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); if(e_ir_state != 0) { e_ir_state->ctx = 0; } { @@ -13327,7 +13196,7 @@ rd_frame(void) { e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"), .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment)); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), @@ -16074,19 +15943,16 @@ Z(getting_started) CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - if(rd_regs()->unwind_count < rich_unwind.concrete_frame_count) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); + if(frame == 0) + { + frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, 0); + } + if(frame) { - CTRL_CallStackFrame *frame = &rich_unwind.frames[rd_regs()->unwind_count]; - U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - rd_state->base_regs.v.module = module->handle; rd_state->base_regs.v.unwind_count = rd_regs()->unwind_count; - rd_state->base_regs.v.inline_depth = 0; - if(rd_regs()->inline_depth <= frame->inline_frame_count) - { - rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; - } + rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; } rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth); di_scope_close(di_scope); @@ -16098,46 +15964,30 @@ Z(getting_started) CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - U64 crnt_unwind_idx = rd_state->base_regs.v.unwind_count; - U64 crnt_inline_dpt = rd_state->base_regs.v.inline_depth; - U64 next_unwind_idx = crnt_unwind_idx; - U64 next_inline_dpt = crnt_inline_dpt; - if(crnt_unwind_idx < rich_unwind.concrete_frame_count) + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); + CTRL_CallStackFrame *next_frame = current_frame; + if(current_frame != 0) switch(kind) { - CTRL_CallStackFrame *f = &rich_unwind.frames[crnt_unwind_idx]; - switch(kind) + default:{}break; + case RD_CmdKind_UpOneFrame: + if(current_frame > call_stack.frames) { - default:{}break; - case RD_CmdKind_UpOneFrame: - { - if(crnt_inline_dpt < f->inline_frame_count) - { - next_inline_dpt += 1; - } - else if(crnt_unwind_idx > 0) - { - next_unwind_idx -= 1; - next_inline_dpt = 0; - } - }break; - case RD_CmdKind_DownOneFrame: - { - if(crnt_inline_dpt > 0) - { - next_inline_dpt -= 1; - } - else if(crnt_unwind_idx < rich_unwind.concrete_frame_count) - { - next_unwind_idx += 1; - next_inline_dpt = (f+1)->inline_frame_count; - } - }break; - } + next_frame = current_frame-1; + }break; + case RD_CmdKind_DownOneFrame: + if(current_frame+1 < call_stack.frames + call_stack.count) + { + next_frame = current_frame+1; + }break; + } + if(next_frame != 0) + { + CTRL_CallStackFrame *next_base_frame = next_frame + next_frame->inline_depth; + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = next_frame->unwind_count, + .inline_depth = next_frame->inline_depth); } - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = next_unwind_idx, - .inline_depth = next_inline_dpt); di_scope_close(di_scope); }break; @@ -16628,18 +16478,8 @@ Z(getting_started) //- rjf: gather breakpoints & meta-evals (for the engine, meta-evals can only be referenced by breakpoints) // D_BreakpointArray breakpoints = {0}; - CTRL_MetaEvalArray meta_evals = {0}; ProfScope("gather breakpoints & meta-evals") { - typedef struct MetaEvalNode MetaEvalNode; - struct MetaEvalNode - { - MetaEvalNode *next; - CTRL_MetaEval *meval; - }; - U64 meval_count = 0; - MetaEvalNode *first_meval = 0; - MetaEvalNode *last_meval = 0; RD_CfgList bp_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); breakpoints.count = bp_cfgs.count; breakpoints.v = push_array(scratch.arena, D_Breakpoint, breakpoints.count); @@ -16737,18 +16577,6 @@ Z(getting_started) dst_bp->condition = src_bp_cnd; idx += 1; } - - //- rjf: meta-eval list -> array - meta_evals.count = meval_count; - meta_evals.v = push_array(scratch.arena, CTRL_MetaEval, meta_evals.count); - { - U64 idx = 0; - for(MetaEvalNode *n = first_meval; n != 0; n = n->next) - { - MemoryCopyStruct(&meta_evals.v[idx], n->meval); - idx += 1; - } - } } //////////////////////////// @@ -16823,7 +16651,7 @@ Z(getting_started) //- rjf: tick debug engine // U64 cmd_count_pre_tick = rd_state->cmds[0].count; - D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters, &meta_evals); + D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters); //////////////////////////// //- rjf: process debug engine events diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index e2a079ec..741063e4 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -617,25 +617,6 @@ struct RD_WindowStateSlot RD_WindowState *last; }; -//////////////////////////////// -//~ rjf: Meta Evaluation Cache Types - -typedef struct RD_CtrlEntityMetaEvalCacheNode RD_CtrlEntityMetaEvalCacheNode; -struct RD_CtrlEntityMetaEvalCacheNode -{ - RD_CtrlEntityMetaEvalCacheNode *next; - CTRL_Handle handle; - CTRL_MetaEval *meval; - Rng1U64 range; -}; - -typedef struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheSlot; -struct RD_CtrlEntityMetaEvalCacheSlot -{ - RD_CtrlEntityMetaEvalCacheNode *first; - RD_CtrlEntityMetaEvalCacheNode *last; -}; - //////////////////////////////// //~ rjf: Config -> Eval Blob Cache Types @@ -788,10 +769,6 @@ struct RD_State Arena *string_search_arena; String8 string_search_string; - // rjf: ctrl entity meta eval cache - U64 ctrl_entity_meval_cache_slots_count; - RD_CtrlEntityMetaEvalCacheSlot *ctrl_entity_meval_cache_slots; - // rjf: contextual hover info RD_Regs *hover_regs; RD_RegSlot hover_regs_slot; @@ -1055,9 +1032,6 @@ internal String8 rd_eval_blob_from_cfg__cached(RD_Cfg *cfg); 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_ctrl_entity(Arena *arena, CTRL_Entity *entity); - //- rjf: eval space reads/writes internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); From 300231ad759700cc5623dbbadabc204982be2256 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 14:22:42 -0800 Subject: [PATCH 078/755] require file handle validity for file stream cache submits; simply retry on missing files --- src/file_stream/file_stream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index b28f630d..3f23f113 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -316,6 +316,7 @@ ASYNC_WORK_DEF(fs_stream_work) U64 range_size = dim_1u64(range); U64 read_size = Min(pre_props.size, range_size); OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path); + B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file); U64 data_arena_size = read_size+ARENA_HEADER_SIZE; data_arena_size += KB(4)-1; data_arena_size -= data_arena_size%KB(4); @@ -331,7 +332,8 @@ ASYNC_WORK_DEF(fs_stream_work) //- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file B32 read_good = (pre_props.modified == post_props.modified && pre_props.size == post_props.size && - read_size == data.size); + read_size == data.size && + file_handle_is_valid); if(!read_good) { ProfScope("abort") From f3c17a4e2cc75f67cfed536de1c12092b959fd35 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 15:32:48 -0800 Subject: [PATCH 079/755] target environment string editing --- src/raddbg/raddbg_core.c | 149 ++++++++++++++++++++++---------------- src/raddbg/raddbg_views.c | 51 +++++++++---- src/raddbg/raddbg_views.h | 3 +- 3 files changed, 123 insertions(+), 80 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index dea44896..757ace7f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1827,7 +1827,17 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) String8 result = {0}; String8 name = cfg->string; 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)) + if(e_type_key_match(e_type_key_zero(), type_key)) + { + String8List parts = {0}; + U64 offset = 8; + String8Node offset_node = {0, str8_struct(&offset)}; + String8Node string_node = {0, cfg->first->string}; + str8_list_push_node(&parts, &offset_node); + str8_list_push_node(&parts, &string_node); + result = str8_list_join(arena, &parts, 0); + } + else { Temp scratch = scratch_begin(&arena, 1); MD_Node *schema = rd_schema_from_name(scratch.arena, name); @@ -2236,6 +2246,14 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } } + // rjf: if no members? -> treat this as a commit to the cfg's children + if(type->members == 0) + { + String8 new_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); + rd_cfg_new_replace(cfg, new_string); + result = 1; + } + // rjf: commit to the eval blob cache { RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; @@ -8624,6 +8642,13 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) } #endif +//- rjf: commands + +E_LOOKUP_INFO_FUNCTION_DEF(commands) +{ + +} + //- rjf: watch expressions E_LOOKUP_INFO_FUNCTION_DEF(watches) @@ -8843,7 +8868,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); accel->cmds = str8_array_from_list(arena, &cmds_list); accel->cmds_idx_range = r1u64(0, accel->cmds.count); - accel->cfgs_idx_range = r1u64(accel->cmds.count, accel->cmds.count + accel->cfgs.count); + accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); result.user_data = accel; result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; } @@ -8863,19 +8888,9 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; - if(contains_1u64(accel->cmds_idx_range, rhs_value.u64)) + if(rhs_value.u64 < accel->cfgs.count) { - String8 cmd_name = accel->cmds.v[rhs_value.u64 - accel->cmds_idx_range.min]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - E_TypeKey type_key = e_type_key_basic(E_TypeKind_U64); - E_Space cmd_space = e_space_make(RD_EvalSpaceKind_MetaCmd); - result.irtree_and_type.root = e_irtree_set_space(arena, cmd_space, e_irtree_const_u(arena, cmd_kind)); - result.irtree_and_type.type_key = type_key; - result.irtree_and_type.mode = E_Mode_Value; - } - else if(contains_1u64(accel->cfgs_idx_range, rhs_value.u64)) - { - RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64 - accel->cfgs_idx_range.min]; + RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64]; E_Space cfg_space = rd_eval_space_from_cfg(cfg); String8 cfg_name = cfg->string; E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); @@ -8888,61 +8903,41 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) return result; } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) { - U64 id = 0; RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - if(num != 0) + Rng1U64 cmds_idx_range = accel->cmds_idx_range; + Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; + U64 dst_idx = 0; + + // rjf: fill commands { - U64 idx = (num-1); - if(contains_1u64(accel->cfgs_idx_range, idx)) + Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { - id = accel->cfgs.v[idx - accel->cfgs_idx_range.min]->id; - } - else if(contains_1u64(accel->cmds_idx_range, idx)) - { - String8 cmd_name = accel->cmds.v[idx - accel->cmds_idx_range.min]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - id = (U64)cmd_kind; - id |= (1ull<<63); } } - return id; + + // rjf: fill cfgs + { + Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + exprs[dst_idx] = e_expr_ref_array_index(arena, lhs, idx + read_range.min - cfgs_idx_range.min); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) +{ + return num; } E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) { - U64 num = 0; - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - if(id != 0) - { - if(id & (1ull<<63)) - { - for EachIndex(idx, accel->cmds.count) - { - String8 cmd_name = accel->cmds.v[idx - accel->cmds_idx_range.min]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - U64 cmd_id = (U64)cmd_kind; - cmd_id |= (1ull<<63); - if(cmd_id == id) - { - num = idx+1+accel->cmds_idx_range.min; - } - } - } - else - { - for EachIndex(idx, accel->cfgs.count) - { - if(accel->cfgs.v[idx]->id == id) - { - num = idx+1+accel->cfgs_idx_range.min; - break; - } - } - } - } - return num; + return id; } //- rjf: threads / callstacks @@ -9101,11 +9096,13 @@ E_LOOKUP_INFO_FUNCTION_DEF(environment) E_Interpretation interpret = e_interpret(bytecode); RD_CfgID id = interpret.value.u64; RD_Cfg *target = rd_cfg_from_id(id); - RD_Cfg *env = rd_cfg_child_from_string(target, str8_lit("environment")); RD_CfgList env_strings = {0}; - for(RD_Cfg *child = env->first; child != &rd_nil_cfg; child = child->next) + for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) { - rd_cfg_list_push(scratch.arena, &env_strings, child); + if(str8_match(child->string, str8_lit("environment"), 0)) + { + rd_cfg_list_push(scratch.arena, &env_strings, child); + } } RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); *accel = rd_cfg_array_from_list(arena, &env_strings); @@ -9116,6 +9113,30 @@ E_LOOKUP_INFO_FUNCTION_DEF(environment) return result; } +E_LOOKUP_ACCESS_FUNCTION_DEF(environment) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + E_LOOKUP_RANGE_FUNCTION_DEF(environment) { RD_CfgArray *cfgs = (RD_CfgArray *)user_data; @@ -9127,7 +9148,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(environment) U64 cfg_idx = read_range.min + idx; if(cfg_idx < cfgs->count) { - + exprs[idx] = e_expr_ref_array_index(arena, lhs, cfg_idx); } } } @@ -13196,6 +13217,7 @@ rd_frame(void) { e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"), .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment), .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment)); @@ -13264,6 +13286,7 @@ rd_frame(void) e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(top_level_cfg), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(top_level_cfg), .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(top_level_cfg), .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(top_level_cfg)); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4cd17116..d9385ea7 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -888,7 +888,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_WatchRowInfo info = { .module = &ctrl_entity_nil, - .group_cfg = &rd_nil_cfg, + .group_cfg_parent = &rd_nil_cfg, + .group_cfg_child = &rd_nil_cfg, .group_entity = &ctrl_entity_nil, .callstack_thread = &ctrl_entity_nil, .view_ui_rule = &rd_nil_view_ui_rule, @@ -929,15 +930,24 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine cfg group name + // rjf: determine cfg group name / parent { - E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, row->block->expr); - E_TypeKey block_type_key = block_irtree.type_key; + E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); + E_TypeKey block_type_key = block_eval.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); if(block_type_kind == E_TypeKind_Set) { + info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); E_Type *block_type = e_type_from_key__cached(block_type_key); - info.group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + String8 singular_name = rd_singular_from_code_name_plural(block_type->name); + if(singular_name.size != 0) + { + info.group_cfg_name = singular_name; + } + else + { + info.group_cfg_name = block_type->name; + } } } @@ -945,7 +955,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(info.group_cfg_name.size != 0) { RD_CfgID id = row->key.child_id; - info.group_cfg = rd_cfg_from_id(id); + info.group_cfg_child = rd_cfg_from_id(id); } // rjf: determine view ui rule @@ -1941,11 +1951,20 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { case RD_WatchCellKind_Expr: { - RD_Cfg *cfg = row_info.group_cfg; + RD_Cfg *cfg = row_info.group_cfg_child; + String8 child_key = str8_lit("expression"); if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) { - RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); - RD_Cfg *new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; + if(new_cfg_parent != &rd_nil_cfg) + { + child_key = str8_zero(); + } + if(new_cfg_parent == &rd_nil_cfg) + { + RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); + new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + } if(new_cfg_parent == &rd_nil_cfg) { new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); @@ -1956,7 +1975,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } if(cfg != &rd_nil_cfg) { - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("expression")); + RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; rd_cfg_new_replace(expr, new_string); } }break; @@ -1964,7 +1983,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) if(editing_complete) { ev_key_set_view_rule(eval_view, pt.key, new_string); - RD_Cfg *cfg = row_info.group_cfg; + RD_Cfg *cfg = row_info.group_cfg_child; if(cfg != &rd_nil_cfg && new_string.size != 0) { RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); @@ -2086,7 +2105,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) default:{}break; case RD_WatchCellKind_Expr: { - RD_Cfg *cfg = row_info.group_cfg; + RD_Cfg *cfg = row_info.group_cfg_child; if(cfg != &rd_nil_cfg) { rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); @@ -2116,9 +2135,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) }break; case RD_WatchCellKind_Tag: { - if(row_info.group_cfg != &rd_nil_cfg) + if(row_info.group_cfg_child != &rd_nil_cfg) { - rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg, str8_lit("view_rule"))); + rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg_child, str8_lit("view_rule"))); } ev_key_set_view_rule(eval_view, row->key, str8_zero()); state_dirty = 1; @@ -2527,7 +2546,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////// //- rjf: draw start of cache lines in expansions // - if(row_info.view_ui_rule == &rd_nil_view_ui_rule) + if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info.view_ui_rule == &rd_nil_view_ui_rule) { U64 row_offset = row_info.eval.value.u64; if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && @@ -2544,7 +2563,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////// //- rjf: draw mid-row cache line boundaries in expansions // - if(row_info.view_ui_rule == &rd_nil_view_ui_rule) + if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info.view_ui_rule == &rd_nil_view_ui_rule) { if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && row_info.eval.value.u64%64 != 0 && diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 8d724f2b..e75b5c75 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -74,7 +74,8 @@ struct RD_WatchRowInfo E_Eval eval; CTRL_Entity *module; String8 group_cfg_name; - RD_Cfg *group_cfg; + RD_Cfg *group_cfg_parent; + RD_Cfg *group_cfg_child; CTRL_Entity *group_entity; CTRL_Entity *callstack_thread; U64 callstack_unwind_index; From 428617de91898d82652b930a2249df088947862c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 15:51:36 -0800 Subject: [PATCH 080/755] re-add id stability to top-level-cfg evaluation expansions --- .../eval_visualization_core.c | 2 +- src/raddbg/raddbg_core.c | 38 ++++++++++++++++++- src/raddbg/raddbg_views.c | 4 ++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 9fc3a3e0..c71bc788 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -770,7 +770,7 @@ internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num) { EV_BlockRange result = {&ev_nil_block}; - U64 base_num = 0; + U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 757ace7f..2d47cdea 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8932,12 +8932,46 @@ E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) { - return num; + U64 id = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(num != 0) + { + U64 idx = num-1; + if(contains_1u64(accel->cfgs_idx_range, idx)) + { + RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; + id = cfg->id; + } + else if(contains_1u64(accel->cmds_idx_range, idx)) + { + id = num; + id |= (1ull<<63); + } + } + return id; } E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) { - return id; + U64 num = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(id != 0) + { + if(id & (1ull<<63)) + { + num = id; + num &= ~(1ull<<63); + } + else for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx + accel->cfgs_idx_range.min + 1; + break; + } + } + } + return num; } //- rjf: threads / callstacks diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d9385ea7..8a063fe2 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2319,6 +2319,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { E_Type *block_type = e_type_from_key__cached(block_type_key); group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + if(group_cfg_name.size == 0) + { + group_cfg_name = block_type->name; + } } } From 052efc7f64be1f032b0e54db78818705f3f0ee38 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 16:11:34 -0800 Subject: [PATCH 081/755] meta command evaluation in frontend eval/eval-viz --- src/raddbg/raddbg_core.c | 59 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2d47cdea..bf4347db 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8646,7 +8646,48 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) E_LOOKUP_INFO_FUNCTION_DEF(commands) { - + E_LookupInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + String8List cmd_names = {0}; + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 name = info->string; + str8_list_push(scratch.arena, &cmd_names, name); + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &cmd_names); + result.user_data = accel; + result.idxed_expr_count = accel->count; + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(commands) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + String8Array *accel = (String8Array *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(rhs_value.u64 < accel->count) + { + String8 cmd_name = accel->v[rhs_value.u64]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, (U64)cmd_kind)); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); + } + return result; } //- rjf: watch expressions @@ -8914,8 +8955,12 @@ E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { + String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + exprs[dst_idx] = e_expr_ref_array_index(arena, commands, (U64)cmd_kind-1); } } @@ -13339,6 +13384,18 @@ rd_frame(void) .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities)); } + //- rjf: add macro for commands + { + String8 name = str8_lit("commands"); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands)); + } + //- rjf: add macro for output log { HS_Scope *hs_scope = hs_scope_open(); From 29033fe6ccbf196ea164c10c97fba900d9bb47ec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 16:14:11 -0800 Subject: [PATCH 082/755] fix incorrect type usage in default lookup-range eval path; fixes broken pointer/reference expansions to structs/unions/classes --- src/eval/eval_ir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4211b35f..b2fce86d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -472,15 +472,15 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) //- rjf: struct case -> the lookup-range will return a range of members if(do_struct_range) { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - Rng1U64 legal_idx_range = r1u64(0, lhs_type->count); + E_Type *struct_type = e_type_from_key__cached(struct_type_key); + Rng1U64 legal_idx_range = r1u64(0, struct_type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 member_idx = idx + read_range.min; - String8 member_name = (lhs_type->members ? lhs_type->members[member_idx].name : - lhs_type->enum_vals ? lhs_type->enum_vals[member_idx].name : str8_lit("")); + String8 member_name = (struct_type->members ? struct_type->members[member_idx].name : + struct_type->enum_vals ? struct_type->enum_vals[member_idx].name : str8_lit("")); exprs[idx] = e_expr_ref_member_access(arena, lhs, member_name); } } From 80b0138ea30c22ccc39a91e97fe0f86d5f6ae6d8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 16:32:07 -0800 Subject: [PATCH 083/755] fix expansion rules being applied to traditionally non-expandable type info; plug memory view back in --- src/eval_visualization/eval_visualization_core.c | 14 +++++++------- src/raddbg/raddbg_views.c | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index c71bc788..5c7f4e5b 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -537,8 +537,13 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s // rjf: unpack expr E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); - // rjf: skip if type info disallows expansion - if(!ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) + // rjf: get expr's expansion rule + EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + EV_ExpandRule *expand_rule = expand_rule_and_tag.rule; + E_Expr *expand_rule_tag = expand_rule_and_tag.tag; + + // rjf: skip if no expansion rule, & type info disallows expansion + if(expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) { continue; } @@ -548,11 +553,6 @@ ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 s E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - // rjf: get expr's expansion rule - EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ExpandRule *expand_rule = expand_rule_and_tag.rule; - E_Expr *expand_rule_tag = expand_rule_and_tag.tag; - // rjf: get top-level lookup/expansion info E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, filter); EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8a063fe2..a26fd985 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -4524,7 +4524,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - Rng1U64 space_range = {0}; // TODO(rjf): @cfg rd_range_from_eval_params(eval, params); + Rng1U64 space_range = rd_range_from_eval_tag(eval, tag); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -4534,10 +4534,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) space_range = r1u64(0, 0x7FFFFFFFFFFFull); } } - U64 cursor = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("cursor_vaddr")).u64; - U64 mark = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("mark_vaddr")).u64; - U64 bytes_per_cell = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("bytes_per_cell")).u64; - U64 num_columns = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("num_columns")).u64; + U64 cursor = rd_view_cfg_value_from_string(str8_lit("cursor_vaddr")).u64; + U64 mark = rd_view_cfg_value_from_string(str8_lit("mark_vaddr")).u64; + U64 bytes_per_cell = rd_view_cfg_value_from_string(str8_lit("bytes_per_cell")).u64; + U64 num_columns = rd_view_cfg_value_from_string(str8_lit("num_columns")).u64; if(num_columns == 0) { num_columns = 16; From 2a543ee7d758156d0e1456043ca5aa6725fa9e7b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 16:36:53 -0800 Subject: [PATCH 084/755] fix environment string piping to control thread --- src/raddbg/raddbg_core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bf4347db..494d9f35 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1124,10 +1124,12 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) target.stderr_path = rd_cfg_child_from_string(cfg, str8_lit("stderr_path"))->first->string; target.stdin_path = rd_cfg_child_from_string(cfg, str8_lit("stdin_path"))->first->string; target.debug_subprocesses = (rd_cfg_child_from_string(cfg, str8_lit("debug_subprocesses")) != &rd_nil_cfg); - RD_Cfg *env_root = rd_cfg_child_from_string(cfg, str8_lit("environment")); - for(RD_Cfg *env_child = env_root->first; env_child != &rd_nil_cfg; env_child = env_child->next) + for(RD_Cfg *child = cfg->first; child != &rd_nil_cfg; child = child->next) { - str8_list_push(arena, &target.env, env_child->string); + if(str8_match(child->string, str8_lit("environment"), 0)) + { + str8_list_push(arena, &target.env, child->first->string); + } } return target; } From 045aad85789826f0e40a1ee4b3fa7e0fbca3de0b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 10 Feb 2025 16:54:29 -0800 Subject: [PATCH 085/755] request reanimation on view loading-persist --- src/raddbg/raddbg_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 494d9f35..c4a29a6c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12515,6 +12515,10 @@ rd_frame(void) RD_Cfg *vcfg = rd_cfg_from_id(vs->cfg_id); if(rd_cfg_child_from_string(vcfg, str8_lit("selected")) != &rd_nil_cfg) { + if(vs->loading_t_target > 0.5f) + { + rd_request_frame(); + } vs->loading_t_target = 0; } } From 1162841b6e0555bd197c68713f2c6390eb69c2b2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 11:14:38 -0800 Subject: [PATCH 086/755] begin sketching out watch row button cells, for intermixing fancy buttons for cfgs/entities/etc. with regular watch rows --- src/raddbg/raddbg_core.c | 4 ++++ src/raddbg/raddbg_views.c | 47 +++++++++++++++++++++++++++++++------ src/raddbg/raddbg_views.h | 3 +++ src/raddbg/raddbg_widgets.c | 12 +++++++++- src/raddbg/raddbg_widgets.h | 5 ++-- src/ui/ui_basic_widgets.c | 2 +- 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c4a29a6c..24843273 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1287,6 +1287,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(target.exe.size != 0) { dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, target.exe); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); start_secondary(); } @@ -1294,6 +1295,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(target.args.size != 0) { dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, target.args); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); } //- rjf: push conditions @@ -1302,6 +1304,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(condition.size != 0) { dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, condition); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); } } @@ -1309,6 +1312,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(is_disabled) { dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, str8_lit("(Disabled)")); + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); } //- rjf: push hit count diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a26fd985..1b5c1a21 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -958,6 +958,17 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.group_cfg_child = rd_cfg_from_id(id); } + // rjf: determine if the row's evaluation matches the group configuration + // this distinguishes between e.g. "watches", which uses the group of watch cfgs, + // but does not evaluate them, from e.g. "targets", which uses the group of target + // cfgs, and the evaluations are of the targets themselves. + // + B32 row_eval_matches_group = 0; + { + RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); + row_eval_matches_group = (evalled_cfg == info.group_cfg_child); + } + // rjf: determine view ui rule info.view_ui_rule = rd_view_ui_rule_from_string(row->block->expand_rule->string); if(info.view_ui_rule != &rd_nil_view_ui_rule) @@ -967,14 +978,25 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's cells { -#if 0 - // rjf: singular cell for cfgs - if(info.group_cfg != &rd_nil_cfg) + if(0){} + + // rjf: singular button for top-level cfgs + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fancy_strings = rd_title_fstrs_from_cfg(arena, info.group_cfg_child, ui_top_palette()->text_weak, ui_top_font_size())); + } + + // rjf: singular button for entities + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f); + } + + // rjf: singular button for commands + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f); } -#endif - if(0){} // rjf: singular cell for view ui else if(info.view_ui_rule != &rd_nil_view_ui_rule) @@ -1127,6 +1149,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla RD_WatchRowCellInfo result = {0}; result.view_ui_rule = &rd_nil_view_ui_rule; result.view_ui_tag = &e_expr_nil; + result.fancy_strings = cell->fancy_strings; switch(cell->kind) { default:{}break; @@ -1248,6 +1271,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.view_ui_rule = row_info->view_ui_rule; result.view_ui_tag = row_info->view_ui_tag; }break; + + //- rjf: button cells + case RD_WatchCellKind_Button: + { + result.is_button = 1; + }break; } return result; } @@ -2104,6 +2133,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { default:{}break; case RD_WatchCellKind_Expr: + case RD_WatchCellKind_Button: { RD_Cfg *cfg = row_info.group_cfg_child; if(cfg != &rd_nil_cfg) @@ -2695,10 +2725,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_LineEditParams line_edit_params = {0}; { line_edit_params.flags = (RD_LineEditFlag_CodeContents| - RD_LineEditFlag_NoBackground| + RD_LineEditFlag_NoBackground*!(cell_info.is_button)| + RD_LineEditFlag_Border*!!(cell_info.is_button)| + RD_LineEditFlag_Button*!!(cell_info.is_button)| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first && !cell_info.is_button)| RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; @@ -2708,6 +2740,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.edit_string_size_out = &cell_edit_state->input_size; line_edit_params.expanded_out = &next_row_expanded; line_edit_params.pre_edit_value = cell_info.string; + line_edit_params.fancy_strings = cell_info.fancy_strings; } sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); #if 0 // TODO(rjf): @cfg diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index e75b5c75..4d0abe90 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -57,6 +57,7 @@ struct RD_WatchCell RD_WatchCell *next; RD_WatchCellKind kind; String8 string; + DR_FancyStringList fancy_strings; F32 pct; }; @@ -90,6 +91,8 @@ struct RD_WatchRowCellInfo { E_Eval eval; String8 string; + DR_FancyStringList fancy_strings; + B32 is_button; B32 can_edit; B32 is_errored; String8 error_tooltip; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2b7fd381..579ae4d1 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2449,10 +2449,15 @@ rd_line_edit(RD_LineEditParams *params, String8 string) { ui_set_next_hover_cursor(OS_Cursor_IBar); } + if(params->flags & RD_LineEditFlag_Button) + { + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| (!!(params->flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| UI_BoxFlag_DrawHotEffects| + //(!!(params->flags & RD_LineEditFlag_Button)*UI_BoxFlag_DrawActiveEffects)| (!(params->flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| (!!(params->flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| @@ -2645,7 +2650,12 @@ rd_line_edit(RD_LineEditParams *params, String8 string) F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) + if(!is_focus_active && !is_focus_active_disabled && params->fancy_strings.total_size != 0) + { + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(label, ¶ms->fancy_strings); + } + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index bad8acbf..4a905424 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -18,8 +18,9 @@ enum RD_LineEditFlag_KeyboardClickable = (1<<5), RD_LineEditFlag_Border = (1<<6), RD_LineEditFlag_NoBackground = (1<<7), - RD_LineEditFlag_PreferDisplayString = (1<<8), - RD_LineEditFlag_DisplayStringIsCode = (1<<9), + RD_LineEditFlag_Button = (1<<8), + RD_LineEditFlag_PreferDisplayString = (1<<9), + RD_LineEditFlag_DisplayStringIsCode = (1<<10), }; typedef struct RD_LineEditParams RD_LineEditParams; diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 22c61052..5c163c27 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -1264,7 +1264,7 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } // rjf: scroller - UI_Flags(disabled_flags) UI_PrefSize(axis, ui_pct(Clamp(0.01f, (F32)((F64)Max(view_num_indices, 1)/(F64)idx_range_dim), 1.f), 0.f)) + UI_Flags(disabled_flags) UI_PrefSize(axis, ui_pct(Clamp(0.05f, (F32)((F64)Max(view_num_indices, 1)/(F64)idx_range_dim), 1.f), 0.f)) { scroller_sig = ui_buttonf("##_scroller_%i", axis); scroller_box = scroller_sig.box; From ee984877b0f8accb836bc1346a202e944484e398 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 13:30:07 -0800 Subject: [PATCH 087/755] work on multi-topology watch tables; fancy evaluation for cfgs, regardless of where they are spawned --- src/eval/eval_interpret.c | 6 ++- src/raddbg/raddbg_core.c | 26 +++++++---- src/raddbg/raddbg_views.c | 91 ++++++++++++++++++++++++++++++--------- src/raddbg/raddbg_views.h | 1 + 4 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 630bd720..60f71996 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -58,7 +58,11 @@ e_interpret(String8 bytecode) U64 stack_cap = 128; // TODO(rjf): scan bytecode; determine maximum stack depth E_Value *stack = push_array_no_zero(scratch.arena, E_Value, stack_cap); U64 stack_count = 0; - E_Space selected_space = e_interpret_ctx->primary_space; + E_Space selected_space = {0}; + if(bytecode.size != 0) + { + selected_space = e_interpret_ctx->primary_space; + } //- rjf: iterate bytecode & perform ops U8 *ptr = bytecode.str; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 24843273..1931d4d3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1414,6 +1414,14 @@ rd_setting_from_name(String8 name) { // rjf: find most-granular config scope to begin looking for the setting RD_Cfg *start_cfg = rd_cfg_from_id(rd_regs()->view); + for(RD_Cfg *p = start_cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("transient"), 0)) + { + start_cfg = &rd_nil_cfg; + break; + } + } if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->panel); } if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } @@ -6197,7 +6205,9 @@ rd_window_frame(void) RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - RD_RegsScope(.panel = 0, .view = view->id) + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + RD_RegsScope(.view = view->id) { rd_cfg_new_replace(expr, ws->hover_eval_string); EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); @@ -8084,7 +8094,7 @@ rd_window_frame(void) { // rjf: main rectangle { - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1), box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -8321,22 +8331,22 @@ rd_window_frame(void) { Rng2F32 r = b->rect; F32 half_thickness = 1.f; - F32 softness = 0.5f; + F32 softness = 0.f; if(b->flags & UI_BoxFlag_DrawSideTop) { - dr_rect(r2f32p(r.x0, r.y0-half_thickness, r.x1, r.y0+half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x1, r.y0+2*half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideBottom) { - dr_rect(r2f32p(r.x0, r.y1-half_thickness, r.x1, r.y1+half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y1-2*half_thickness, r.x1, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideLeft) { - dr_rect(r2f32p(r.x0-half_thickness, r.y0, r.x0+half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x0+2*half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideRight) { - dr_rect(r2f32p(r.x1-half_thickness, r.y0, r.x1+half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x1-2*half_thickness, r.y0, r.x1, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); } } @@ -9146,7 +9156,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(target) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_const_u(arena, cfg->id); + result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_const_u(arena, cfg->id)); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); result.irtree_and_type.mode = E_Mode_Offset; } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 1b5c1a21..71645143 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -964,8 +964,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // cfgs, and the evaluations are of the targets themselves. // B32 row_eval_matches_group = 0; + RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); { - RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); row_eval_matches_group = (evalled_cfg == info.group_cfg_child); } @@ -980,12 +980,18 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: singular button for top-level cfgs + // rjf: singular button for top-level cfg group elements else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fancy_strings = rd_title_fstrs_from_cfg(arena, info.group_cfg_child, ui_top_palette()->text_weak, ui_top_font_size())); } + // rjf: singular button for top-level cfg roots + else if(row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fancy_strings = rd_title_fstrs_from_cfg(arena, evalled_cfg, ui_top_palette()->text_weak, ui_top_font_size())); + } + // rjf: singular button for entities else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) { @@ -1004,6 +1010,19 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); } + // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr + else if(info.eval.space.kind == E_SpaceKind_Null && info.group_cfg_parent != &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + + // rjf: for meta-cfg evaluation spaces, only do expr/value + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.75f); + } + // rjf: default cells else { @@ -1566,15 +1585,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // the "collection of all watches", to build a watch window. but this behavior is not // as desirable if we are just using some other expression as the root. // - B32 implicit_root = 0; - { - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_TypeKind kind = e_type_kind_from_key(eval.type_key); - if(kind == E_TypeKind_Set) - { - implicit_root = 1; - } - } + B32 implicit_root = !rd_view_cfg_value_from_string(str8_lit("explicit_root")).u64; ////////////////////////////// //- rjf: determine autocompletion string @@ -2479,6 +2490,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ProfScope("build table") { U64 global_row_idx = rows.count_before_semantic; + RD_WatchRowInfo last_row_info = {0}; for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) { //////////////////////// @@ -2499,6 +2511,37 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } ProfEnd(); + //////////////////////// + //- rjf: determine if this row fits the last row's topology + // + B32 row_matches_last_row_topology = 1; + if(row_node != rows.first) + { + for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info.cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + row_matches_last_row_topology = 0; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + row_matches_last_row_topology = 0; + break; + } + } + } + + //////////////////////// + //- rjf: store last row's info, for next iteration + // + last_row_info = row_info; + //////////////////////// //- rjf: determine if row's data is fresh and/or bad // @@ -2516,7 +2559,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) U64 size = e_type_byte_size_from_key(row_info.eval.type_key); size = Min(size, 64); Rng1U64 vaddr_rng = r1u64(row_info.eval.value.u64, row_info.eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { if(slice.byte_changed_flags[idx] != 0) @@ -2549,6 +2592,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); row_flags |= UI_BoxFlag_DrawBackground; } + if(!row_matches_last_row_topology) + { + row_flags |= UI_BoxFlag_DrawSideTop; + } #if 0 // TODO(rjf): @cfg switch(row_kind) { @@ -2570,7 +2617,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|(!row_node->next)*UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); ////////////////////// //- rjf: build row contents @@ -2631,6 +2678,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + F32 next_cell_x_px = cell_x_px + cell_width_px; //- rjf: determine cell's palette ProfBegin("determine cell's palette"); @@ -2652,15 +2701,15 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //- rjf: build cell UI_Box *cell_box = &ui_nil_box; - UI_Palette(palette) + UI_Palette(palette) UI_PrefWidth(ui_px(cell_width_px, 1.f)) { - ui_set_next_fixed_height(row->visual_size * row_height_px); + ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft, "cell_%I64x_%I64x", row_hash, cell_id); } - //- rjf: build cell + //- rjf: build cell contents UI_Signal sig = {0}; - ProfScope("build cell") + ProfScope("build cell contents") UI_Parent(cell_box) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) @@ -2683,7 +2732,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: cell has hook? -> build ui by calling hook else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) { - Rng2F32 cell_rect = r2f32p(cell_x_px, 0, cell_x_px + cell->pct*(dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)), row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); @@ -2694,8 +2743,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.expr)); rd_cfg_new(view, str8_lit("selected")); - RD_RegsScope(.panel = 0, .view = view->id) + RD_RegsScope(.view = view->id) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + UI_Flags(0) { // rjf: loading animation container UI_Box *loading_overlay_container = &ui_nil_box; @@ -2726,7 +2776,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { line_edit_params.flags = (RD_LineEditFlag_CodeContents| RD_LineEditFlag_NoBackground*!(cell_info.is_button)| - RD_LineEditFlag_Border*!!(cell_info.is_button)| RD_LineEditFlag_Button*!!(cell_info.is_button)| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| @@ -2840,7 +2889,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } //- rjf: bump x pixel coordinate - cell_x_px += cell->pct*dim_2f32(rect).x; + cell_x_px = next_cell_x_px; //- rjf: [DEV] hovering -> watch key tooltips if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 4d0abe90..e7c52942 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -59,6 +59,7 @@ struct RD_WatchCell String8 string; DR_FancyStringList fancy_strings; F32 pct; + F32 px; }; typedef struct RD_WatchCellList RD_WatchCellList; From 82803e710e4f75eec05c3baeb5fb2a5470fd0db2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 14:03:28 -0800 Subject: [PATCH 088/755] plug in fancy member names to watch views --- src/raddbg/generated/raddbg.meta.c | 6 +++++- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 4 ++++ src/raddbg/raddbg_views.c | 19 +++++++++++++++++-- src/raddbg/raddbg_views.h | 1 + 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 47ded9cf..76ff60a7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,7 +28,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[60] = +RD_VocabularyInfo rd_vocabulary_info_table[64] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -90,6 +90,10 @@ RD_VocabularyInfo rd_vocabulary_info_table[60] = {str8_lit_comp("register"), str8_lit_comp("registers"), str8_lit_comp("Register"), str8_lit_comp("Registers"), RD_IconKind_Null}, {str8_lit_comp("local"), str8_lit_comp("locals"), str8_lit_comp("Local"), str8_lit_comp("Locals"), RD_IconKind_Null}, {str8_lit_comp("memory"), str8_lit_comp("memories"), str8_lit_comp("Memory"), str8_lit_comp("Memories"), RD_IconKind_Grid}, +{str8_lit_comp("hit_count"), str8_lit_comp("hit_counts"), str8_lit_comp("Hit Count"), str8_lit_comp("Hit Counts"), RD_IconKind_Null}, +{str8_lit_comp("disabled"), str8_lit_comp(""), str8_lit_comp("Disabled"), str8_lit_comp("Disabled"), RD_IconKind_Null}, +{str8_lit_comp("debug_subprocesses"), str8_lit_comp(""), str8_lit_comp("Debug Subprocesses"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, }; RD_NameSchemaInfo rd_name_schema_info_table[10] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 1ea0df18..797b8bc7 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -570,7 +570,7 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[60]; +extern RD_VocabularyInfo rd_vocabulary_info_table[64]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 57079711..4a5be8d2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -111,6 +111,10 @@ RD_VocabularyMap: {register _ "Register" _ Null } {local _ "Local" _ Null } {memory memories "Memory" "Memories" Grid } + {hit_count hit_counts "Hit Count" "Hit Counts" Null } + {disabled "" "Disabled" "Disabled" Null } + {debug_subprocesses "" "Debug Subprocesses" "" Null } + {environment _ "Environment" _ Null } } @struct RD_VocabularyInfo: diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 71645143..19958806 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1214,7 +1214,22 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla }break; case E_ExprKind_MemberAccess: { - result.string = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); + E_Eval row_eval = e_eval_from_expr(arena, row->expr); + String8 member_name = e_string_from_expr(arena, notable_expr->last); + B32 is_non_code = 0; + String8 string = push_str8f(arena, ".%S", member_name); + if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + String8 fancy_name = rd_display_from_code_name(member_name); + if(fancy_name.size != 0) + { + string = fancy_name; + is_non_code = 1; + } + } + result.is_non_code = is_non_code; + result.string = string; }break; } } @@ -2770,7 +2785,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } // rjf: build cell line edit - else + else RD_Font(cell_info.is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { RD_LineEditParams line_edit_params = {0}; { diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index e7c52942..b017a4f8 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -93,6 +93,7 @@ struct RD_WatchRowCellInfo E_Eval eval; String8 string; DR_FancyStringList fancy_strings; + B32 is_non_code; B32 is_button; B32 can_edit; B32 is_errored; From fa7143a3e46e0f650a045d36ae06f6aa207679ad Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 14:07:43 -0800 Subject: [PATCH 089/755] never build hover evals if we cannot evaluate the root expression successfully --- src/raddbg/raddbg_core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1931d4d3..072b8ef9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6174,6 +6174,13 @@ rd_window_frame(void) #endif } + // rjf: evaluate hover-evaluation expression - if it doesn't evaluate, then don't build anything + E_Eval hover_eval = e_eval_from_string(scratch.arena, ws->hover_eval_string); + if(hover_eval.msgs.max_kind > E_MsgKind_Null) + { + build_hover_eval = 0; + } + // rjf: reset open animation if(ws->hover_eval_string.size == 0) { From 50e4f6a22a72ee7fc382f99ec1bd54779a726548 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 14:14:55 -0800 Subject: [PATCH 090/755] move watch window to using exclusively view ui rule input eval, rather than looking at the expression string itself --- .../eval_visualization_core.c | 10 ++++----- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 21 ++++++------------- src/raddbg/raddbg_core.h | 1 - src/raddbg/raddbg_views.c | 9 ++------ 5 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5c7f4e5b..0490511a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -476,26 +476,24 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string) +ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; { Temp scratch = scratch_begin(&arena, 1); - //- rjf: produce root expression + //- rjf: generate root expression EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); - E_TokenArray root_tokens = e_token_array_from_text(scratch.arena, string); - E_Parse root_parse = e_parse_expr_from_text_tokens(arena, string, &root_tokens); - E_Expr *root_expr = root_parse.last_expr; + E_Expr *root_expr = e_expr_copy(arena, eval.expr); ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = root_key; - tree.root->string = string; + tree.root->string = str8_zero(); tree.root->expr = root_expr; tree.root->row_count = 1; tree.total_row_count += 1; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 0eab57a5..fa875eef 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -337,7 +337,7 @@ internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *blo //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string); +internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 072b8ef9..3b0b832c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2990,7 +2990,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: unpack view's target expression & hash - String8 expr_string = rd_view_expr_string(); + String8 expr_string = rd_expr_from_cfg(view); E_Eval eval = e_eval_from_string(scratch.arena, expr_string); Rng1U64 range = r1u64(0, 1024); U128 key = rd_key_from_eval_space_range(eval.space, range, 0); @@ -3112,15 +3112,6 @@ rd_view_eval_view(void) return view_state->ev_view; } -internal String8 -rd_view_expr_string(void) -{ - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *expr = rd_cfg_child_from_string(view, str8_lit("expression")); - String8 expr_string = expr->first->string; - return expr_string; -} - internal String8 rd_view_filter(void) { @@ -6217,7 +6208,7 @@ rd_window_frame(void) RD_RegsScope(.view = view->id) { rd_cfg_new_replace(expr, ws->hover_eval_string); - EV_BlockTree predicted_block_tree = ev_block_tree_from_string(scratch.arena, rd_view_eval_view(), str8_zero(), ws->hover_eval_string); + EV_BlockTree predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); if(ws->hover_eval_focused) @@ -15138,7 +15129,7 @@ Z(getting_started) // rjf: get source path RD_Cfg *src_view = rd_cfg_from_id(rd_regs()->view); - String8 src_view_expr = rd_view_expr_string(); + String8 src_view_expr = rd_expr_from_cfg(src_view); String8 src_file_path = rd_file_path_from_eval_string(scratch.arena, src_view_expr); String8List src_file_parts = str8_split_path(scratch.arena, src_file_path); @@ -15305,7 +15296,7 @@ Z(getting_started) if(rd_cfg_is_project_filtered(tab)) { continue; } RD_RegsScope(.view = tab->id) { - String8 tab_expr = rd_view_expr_string(); + String8 tab_expr = rd_expr_from_cfg(tab); String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); if((str8_match(tab->string, str8_lit("text"), 0) || str8_match(tab->string, str8_lit("pending"), 0)) && path_match_normalized(tab_file_path, file_path)) @@ -15377,7 +15368,7 @@ Z(getting_started) RD_RegsScope(.view = tab->id) { B32 tab_is_selected = (tab == panel->selected_tab); - String8 expr_string = rd_view_expr_string(); + String8 expr_string = rd_expr_from_cfg(tab); if(str8_match(tab->string, str8_lit("disasm"), 0) && expr_string.size == 0 && panel_area > best_panel_area) { panel_w_disasm = panel; @@ -17020,7 +17011,7 @@ Z(getting_started) } RD_RegsScope(.view = tab->id) { - String8 eval_string = rd_view_expr_string(); + String8 eval_string = rd_expr_from_cfg(tab); String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); if(file_path.size != 0) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 741063e4..ed63c9be 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1077,7 +1077,6 @@ internal void rd_view_ui(Rng2F32 rect); internal Arena *rd_view_arena(void); internal UI_ScrollPt2 rd_view_scroll_pos(void); internal EV_View *rd_view_eval_view(void); -internal String8 rd_view_expr_string(void); internal String8 rd_view_filter(void); internal RD_Cfg *rd_view_cfg_from_string(String8 string); internal E_Value rd_view_cfg_value_from_string(String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 19958806..3cd88127 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1586,11 +1586,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; String8 filter = rd_view_filter(); - String8 expr = rd_view_expr_string(); - if(expr.size == 0) - { - expr = str8_lit("query:watches"); - } ////////////////////////////// //- rjf: decide if root should be implicit @@ -1642,7 +1637,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - block_tree = ev_block_tree_from_string(scratch.arena, eval_view, filter, expr); + block_tree = ev_block_tree_from_eval(scratch.arena, eval_view, filter, eval); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); if(implicit_root && block_ranges.first != 0) { @@ -4181,7 +4176,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) // rjf: override file picking case RD_CmdKind_PickFile: { - String8 src = rd_file_path_from_eval_string(scratch.arena, rd_view_expr_string()); + String8 src = rd_regs()->file_path; String8 dst = cmd->regs->file_path; if(src.size != 0 && dst.size != 0) { From 312ddd589982eb056580daf5b8e43fab554cc4b2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 15:25:42 -0800 Subject: [PATCH 091/755] fix array-index ir tree generation - was incorrectly applying array value rules to address value evaluations; plug in ir-generation hooks for slices, arrays, etc.; eliminate old view rule code --- src/eval/eval_ir.c | 110 ++++++++++-------- src/eval/eval_types.c | 7 +- .../eval_visualization_builtin_view_rules.c | 106 ----------------- .../eval_visualization_builtin_view_rules.h | 17 --- .../eval_visualization_core.c | 3 +- .../eval_visualization_inc.c | 1 - .../eval_visualization_inc.h | 1 - src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 2 + src/raddbg/raddbg_core.c | 4 +- 11 files changed, 77 insertions(+), 180 deletions(-) delete mode 100644 src/eval_visualization/eval_visualization_builtin_view_rules.c delete mode 100644 src/eval_visualization/eval_visualization_builtin_view_rules.h diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index b2fce86d..f87ee218 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -146,15 +146,18 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) { E_Type *type = e_type_from_key__cached(lhs_type_key); lookup_info.idxed_expr_count = type->count; - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Enum) + if(type->count == 1) { - E_Type *direct_type = e_type_from_key__cached(direct_type_key); - lookup_info.named_expr_count = direct_type->count; + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(direct_type_key); + lookup_info.named_expr_count = direct_type->count; + } } } else if(lhs_type_kind == E_TypeKind_Struct || @@ -361,57 +364,54 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) // rjf: generate E_IRNode *new_tree = &e_irnode_nil; + E_Mode mode = l.mode; { - switch(l.mode) + // rjf: reading from an array value -> read from stack value + if(l.mode == E_Mode_Value && l_restype_kind == E_TypeKind_Array) { - // rjf: offsets -> read from base offset - default: - case E_Mode_Null: - case E_Mode_Offset: + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) - E_IRNode *base_tree = l.root; - if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) - { - base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); - } - - // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - }break; + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } - // rjf: values -> read from stack value - case E_Mode_Value: + // rjf: ops to push stack value, push offset, + read from stack value + new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); + new_tree->value.u64 = direct_type_size; + e_irnode_push_child(new_tree, offset_tree); + e_irnode_push_child(new_tree, l.root); + } + + // rjf: all other cases -> read from base offset + else + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to push stack value, push offset, + read from stack value - new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); - new_tree->value.u64 = direct_type_size; - e_irnode_push_child(new_tree, offset_tree); - e_irnode_push_child(new_tree, l.root); - }break; + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) + E_IRNode *base_tree = l.root; + if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) + { + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); + } + + // rjf: ops to compute the final address + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + mode = E_Mode_Offset; } } // rjf: fill result.irtree_and_type.root = new_tree; result.irtree_and_type.type_key = direct_type; - result.irtree_and_type.mode = l.mode; + result.irtree_and_type.mode = mode; }break; } return result; @@ -607,7 +607,10 @@ E_IRGEN_FUNCTION_DEF(slice) } // rjf: overwrite type - irtree.type_key = slice_type_key; + if(!e_type_key_match(slice_type_key, e_type_key_zero())) + { + irtree.type_key = slice_type_key; + } } scratch_end(scratch); return irtree; @@ -662,6 +665,11 @@ e_irgen_rule_map_make(Arena *arena, U64 slots_count) E_IRGenRuleMap map = {0}; map.slots_count = slots_count; map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("slice"), .irgen = E_IRGEN_FUNCTION_NAME(slice)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); return map; } @@ -2018,6 +2026,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) { result = t->rule->irgen(arena, expr, t->tag); + if(result.root == &e_irnode_nil && t->rule != &e_irgen_rule__default) + { + result = e_irgen_rule__default.irgen(arena, expr, &e_expr_nil); + } } // rjf: find any auto hooks according to this generation's type diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index fa5fd05d..6a06b71f 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -460,7 +460,7 @@ e_type_key_cons_array(E_TypeKey element_type_key, U64 count) internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags) { - E_TypeKey key = e_type_key_cons(.arch = arch, .kind = E_TypeKind_Ptr, .flags = flags, .direct_key = element_type_key); + E_TypeKey key = e_type_key_cons(.arch = arch, .kind = E_TypeKind_Ptr, .flags = flags, .direct_key = element_type_key, .count = count); return key; } @@ -1683,6 +1683,11 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("*")); + E_Type *type = e_type_from_key__cached(key); + if(type->count != 1) + { + str8_list_pushf(arena, out, ".%I64u", type->count); + } }break; case E_TypeKind_SpacePtr: diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c deleted file mode 100644 index b8d293c7..00000000 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: View Rule Tree Info Extraction Helpers - -internal U64 -ev_base_offset_from_eval(E_Eval eval) -{ - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - -internal E_Value -ev_value_from_params(MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - String8 expr = md_string_from_children(scratch.arena, params); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal E_TypeKey -ev_type_key_from_params(MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - String8 expr = md_string_from_children(scratch.arena, params); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr); - E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, expr, &tokens); - E_TypeKey type_key = e_type_from_expr(parse.last_expr); - scratch_end(scratch); - return type_key; -} - -internal E_Value -ev_value_from_params_key(MD_Node *params, String8 key) -{ - Temp scratch = scratch_begin(0, 0); - MD_Node *key_node = md_child_from_string(params, key, 0); - String8 expr = md_string_from_children(scratch.arena, key_node); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal Rng1U64 -ev_range_from_eval_params(E_Eval eval, MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - U64 size = ev_value_from_params_key(params, str8_lit("size")).u64; - E_TypeKey type_key = e_type_unwrap(eval.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); - } - if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); - } - if(size == 0) - { - size = 16384; - } - Rng1U64 result = {0}; - result.min = ev_base_offset_from_eval(eval); - result.max = result.min + size; - scratch_end(scratch); - return result; -} - -internal Arch -ev_arch_from_eval_params(E_Eval eval, MD_Node *params) -{ - Arch arch = Arch_Null; - MD_Node *arch_node = md_child_from_string(params, str8_lit("arch"), 0); - String8 arch_kind_string = arch_node->first->string; - if(str8_match(arch_kind_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive)) - { - arch = Arch_x64; - } - return arch; -} - -//////////////////////////////// -//~ rjf: "list" - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(list) -{ - EV_ExpandInfo info = {0}; - return info; -} diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.h b/src/eval_visualization/eval_visualization_builtin_view_rules.h deleted file mode 100644 index 1eb1312c..00000000 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H -#define EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H - -//////////////////////////////// -//~ rjf: View Rule Tree Info Extraction Helpers - -internal U64 ev_base_offset_from_eval(E_Eval eval); -internal E_Value ev_value_from_params(MD_Node *params); -internal E_TypeKey ev_type_key_from_params(MD_Node *params); -internal E_Value ev_value_from_params_key(MD_Node *params, String8 key); -internal Rng1U64 ev_range_from_eval_params(E_Eval eval, MD_Node *params); -internal Arch ev_arch_from_eval_params(E_Eval eval, MD_Node *params); - -#endif // EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 0490511a..226d1a24 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -451,9 +451,8 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key { // rjf: push inherited tags first (we want these to be found first, since tags are applied // in order, and explicit ones should always be strongest) - for(EV_Block *b = block; b != &ev_nil_block; b = b->parent) { - for(E_Expr *src_tag = b->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) + for(E_Expr *src_tag = block->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) { e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); } diff --git a/src/eval_visualization/eval_visualization_inc.c b/src/eval_visualization/eval_visualization_inc.c index 44e7f6cb..d944d937 100644 --- a/src/eval_visualization/eval_visualization_inc.c +++ b/src/eval_visualization/eval_visualization_inc.c @@ -2,4 +2,3 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) #include "eval_visualization_core.c" -#include "eval_visualization_builtin_view_rules.c" diff --git a/src/eval_visualization/eval_visualization_inc.h b/src/eval_visualization/eval_visualization_inc.h index 2e01e21a..11c9b212 100644 --- a/src/eval_visualization/eval_visualization_inc.h +++ b/src/eval_visualization/eval_visualization_inc.h @@ -5,6 +5,5 @@ #define EVAL_VISUALIZATION_INC_H #include "eval_visualization_core.h" -#include "eval_visualization_builtin_view_rules.h" #endif // EVAL_VISUALIZATION_INC_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 76ff60a7..66bcbe91 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -28,7 +28,7 @@ RD_CmdKind_Null, RD_CmdKind_Null, }; -RD_VocabularyInfo rd_vocabulary_info_table[64] = +RD_VocabularyInfo rd_vocabulary_info_table[66] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -94,6 +94,8 @@ RD_VocabularyInfo rd_vocabulary_info_table[64] = {str8_lit_comp("disabled"), str8_lit_comp(""), str8_lit_comp("Disabled"), str8_lit_comp("Disabled"), RD_IconKind_Null}, {str8_lit_comp("debug_subprocesses"), str8_lit_comp(""), str8_lit_comp("Debug Subprocesses"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, +{str8_lit_comp("frozen"), str8_lit_comp(""), str8_lit_comp("Frozen"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("id"), str8_lit_comp("ids"), str8_lit_comp("ID"), str8_lit_comp("IDs"), RD_IconKind_Null}, }; RD_NameSchemaInfo rd_name_schema_info_table[10] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 797b8bc7..9ea1d068 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -570,7 +570,7 @@ C_LINKAGE_BEGIN extern String8 rd_cfg_src_string_table[4]; extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[64]; +extern RD_VocabularyInfo rd_vocabulary_info_table[66]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern RD_StringBindingPair rd_default_binding_table[111]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4a5be8d2..a87d7e23 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -115,6 +115,8 @@ RD_VocabularyMap: {disabled "" "Disabled" "Disabled" Null } {debug_subprocesses "" "Debug Subprocesses" "" Null } {environment _ "Environment" _ Null } + {frozen "" "Frozen" "" Null } + {id _ "ID" _ Null } } @struct RD_VocabularyInfo: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3b0b832c..aa8e5188 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9050,7 +9050,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(thread) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0])); + result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); result.irtree_and_type.mode = E_Mode_Offset; } @@ -13076,6 +13076,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->irgen_rule_map = push_array(scratch.arena, E_IRGenRuleMap, 1); + ctx->irgen_rule_map[0] = e_irgen_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); From 98ec6ee3bba6efde74f60bcd891e0aeae6388b7f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 16:16:44 -0800 Subject: [PATCH 092/755] extend constructed type info with 'pointer depth', to distinguish between inline-depths; use in symbolizing & call stack expression formation --- src/dbg_engine/dbg_engine.mdesk | 1 - src/dbg_engine/dbg_engine_core.c | 117 ++++++++++++++++----- src/dbg_engine/dbg_engine_core.h | 4 +- src/dbg_engine/generated/dbg_engine.meta.h | 1 - src/eval/eval_types.c | 6 +- src/eval/eval_types.h | 2 + src/raddbg/generated/raddbg.meta.c | 3 +- src/raddbg/generated/raddbg.meta.h | 1 - src/raddbg/raddbg_core.c | 17 ++- src/raddbg/raddbg_views.c | 9 +- src/raddbg/raddbg_views.h | 1 + src/render/d3d11/render_d3d11.c | 30 +++--- src/render/d3d11/render_d3d11.h | 6 +- 13 files changed, 140 insertions(+), 58 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index d4f40b62..6f1e56eb 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -27,7 +27,6 @@ D_CmdTable: // | | | | //- rjf: high-level composite target control operations {RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } - {RunToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" "" } {Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } {Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } {StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 2ec23504..2d096a35 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -669,35 +669,101 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) //- rjf: symbol lookups internal String8 -d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated) +d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated) { String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); DI_Scope *scope = di_scope_open(); RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0); + + //- rjf: try scopes if(result.size == 0) { + // rjf: voff -> scope U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - if(decorated && procedure->type_idx != 0) + + // rjf: scope -> # of max possible inline depth + U64 inline_site_count = 0; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { - String8List list = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); - str8_list_push(scratch.arena, &list, name); - e_type_rhs_string_from_key(scratch.arena, type, &list, 0); - result = str8_list_join(arena, &list, 0); + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s->inline_site_idx != 0) + { + inline_site_count += 1; + } + else + { + break; + } } + + // rjf: depth in [1, max]? -> form name from inline site + if(0 < depth && depth <= inline_site_count) + { + RDI_InlineSite *inline_site = 0; + U64 s_inline_depth = inline_site_count; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) + { + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s_inline_depth == depth) + { + inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + break; + } + s_inline_depth -= 1; + if(s_inline_depth == 0) + { + break; + } + } + if(inline_site != 0) + { + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + if(decorated && inline_site->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + result = str8_list_join(arena, &list, 0); + } + else + { + result = push_str8_copy(arena, name); + } + } + } + + // rjf: depth == 0 or depth >= max? -> form name from scope procedure else { - result = push_str8_copy(arena, name); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + if(decorated && procedure->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + result = str8_list_join(arena, &list, 0); + } + else + { + result = push_str8_copy(arena, name); + } } } + + //- rjf: try global variables if(result.size == 0) { U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, voff); @@ -706,6 +772,7 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 d U8 *name_ptr = rdi_string_from_idx(rdi, global_var->name_string_idx, &name_size); result = push_str8_copy(arena, str8(name_ptr, name_size)); } + di_scope_close(scope); scratch_end(scratch); } @@ -713,7 +780,7 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 d } internal String8 -d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated) +d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated) { ProfBeginFunction(); String8 result = {0}; @@ -721,7 +788,7 @@ d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); - result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, decorated); + result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, depth, decorated); } ProfEnd(); return result; @@ -2173,15 +2240,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { run_extra_bps.count = 1; run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); - run_extra_bps.v[0].file_path = params->file_path; - run_extra_bps.v[0].pt = params->cursor; - d_cmd(D_CmdKind_Run); - }break; - case D_CmdKind_RunToAddress: - { - run_extra_bps.count = 1; - run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); - run_extra_bps.v[0].vaddr = params->vaddr; + if(params->file_path.size != 0) + { + run_extra_bps.v[0].file_path = params->file_path; + run_extra_bps.v[0].pt = params->cursor; + } + else if(params->vaddr != 0) + { + run_extra_bps.v[0].vaddr = params->vaddr; + } d_cmd(D_CmdKind_Run); }break; case D_CmdKind_Run: diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 1a83ba35..6ed68067 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -433,8 +433,8 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL //~ rjf: Debug Info Lookups //- rjf: voff|vaddr -> symbol lookups -internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated); -internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated); +internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated); +internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated); //- rjf: symbol -> voff lookups internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name); diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index d129e3d2..38519f1a 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -24,7 +24,6 @@ D_CmdKind_Halt, D_CmdKind_SoftHaltRefresh, D_CmdKind_SetThreadIP, D_CmdKind_RunToLine, -D_CmdKind_RunToAddress, D_CmdKind_Run, D_CmdKind_Restart, D_CmdKind_StepInto, diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6a06b71f..6f3adae4 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -323,6 +323,8 @@ e_hash_from_cons_type_params(E_ConsTypeParams *params) params->direct_key.u32[2], (U32)((params->count & 0x00000000ffffffffull)>> 0), (U32)((params->count & 0xffffffff00000000ull)>> 32), + (U32)((params->depth & 0x00000000ffffffffull)>> 0), + (U32)((params->depth & 0xffffffff00000000ull)>> 32), }; U64 hash = e_hash_from_string(5381, str8((U8 *)buffer, sizeof(buffer))); hash = e_hash_from_string(hash, params->name); @@ -336,7 +338,8 @@ e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r) l->flags == r->flags && str8_match(l->name, r->name, 0) && e_type_key_match(l->direct_key, r->direct_key) && - l->count == r->count); + l->count == r->count && + l->depth == r->depth); if(result && l->members != 0 && r->members != 0) { for(U64 idx = 0; idx < l->count; idx += 1) @@ -628,6 +631,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, node->params.name); type->direct_type_key = node->params.direct_key; type->count = node->params.count; + type->depth = node->params.depth; type->byte_size = node->byte_size; switch(type->kind) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index d17a4297..30cdfee3 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -129,6 +129,7 @@ struct E_Type String8 name; U64 byte_size; U64 count; + U64 depth; U32 off; E_TypeKey direct_type_key; E_TypeKey owner_type_key; @@ -176,6 +177,7 @@ struct E_ConsTypeParams String8 name; E_TypeKey direct_key; U64 count; + U64 depth; E_Member *members; E_EnumVal *enum_vals; }; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 66bcbe91..39b45bcb 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -154,7 +154,7 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[212] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -172,7 +172,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Run To Address"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 9ea1d068..11d009de 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -76,7 +76,6 @@ RD_CmdKind_Halt, RD_CmdKind_SoftHaltRefresh, RD_CmdKind_SetThreadIP, RD_CmdKind_RunToLine, -RD_CmdKind_RunToAddress, RD_CmdKind_Run, RD_CmdKind_Restart, RD_CmdKind_StepInto, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index aa8e5188..f938372b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4775,7 +4775,7 @@ rd_window_frame(void) } else { - rd_cmd(RD_CmdKind_RunToAddress, .vaddr = regs->vaddr); + rd_cmd(RD_CmdKind_RunToLine, .vaddr = regs->vaddr); } ui_ctx_menu_close(); } @@ -7366,10 +7366,7 @@ rd_window_frame(void) { String8 view_expr = rd_expr_from_cfg(selected_tab); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - if(view_file_path.size != 0) - { - rd_regs()->file_path = view_file_path; - } + rd_regs()->file_path = view_file_path; } //- rjf: build view container @@ -9129,7 +9126,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); - result.irtree_and_type.type_key = e_type_key_cons_ptr(process->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); + result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); result.irtree_and_type.mode = E_Mode_Value; } scratch_end(scratch); @@ -9605,8 +9602,10 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul case E_TypeKind_RRef: { // rjf: unpack type info - E_TypeKind type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(e_type_unwrap(eval.type_key))); + E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_Type *type = e_type_from_key__cached(type_key); + E_TypeKind type_kind = type->kind; + E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(type_key)); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); // rjf: unpack info about pointer destination @@ -9623,7 +9622,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); process = ctrl_process_from_entity(thread); } - String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1); + String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, type->depth, 1); // rjf: special case: push strings for textual string content B32 did_content = 0; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3cd88127..5df53e09 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1287,6 +1287,13 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); + //- rjf: determine if inlined + E_Type *type = e_type_from_key__cached(result.eval.type_key); + if(type->depth > 0) + { + result.is_inlined = 1; + } + scratch_end(scratch); }break; @@ -4900,7 +4907,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, f_rip); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 rip_voff = ctrl_voff_from_vaddr(module, f_rip); - String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 1); + String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 0, 1); Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->kind_string = str8_lit("Call Stack Frame"); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index b017a4f8..43d040b1 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -97,6 +97,7 @@ struct RD_WatchRowCellInfo B32 is_button; B32 can_edit; B32 is_errored; + B32 is_inlined; String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index 84ac64a7..dc5cb244 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -672,8 +672,11 @@ r_tex2d_release(R_Handle handle) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { + SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); + } } ProfEnd(); } @@ -705,16 +708,19 @@ r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); - U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; - Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); - D3D11_BOX dst_box = - { - (UINT)subrect.x0, (UINT)subrect.y0, 0, - (UINT)subrect.x1, (UINT)subrect.y1, 1, - }; - r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { + Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); + U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; + Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); + D3D11_BOX dst_box = + { + (UINT)subrect.x0, (UINT)subrect.y0, 0, + (UINT)subrect.x1, (UINT)subrect.y1, 1, + }; + r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); + } } ProfEnd(); } diff --git a/src/render/d3d11/render_d3d11.h b/src/render/d3d11/render_d3d11.h index 5bdec2ab..aba28899 100644 --- a/src/render/d3d11/render_d3d11.h +++ b/src/render/d3d11/render_d3d11.h @@ -171,9 +171,9 @@ struct R_D3D11_State //~ rjf: Globals global R_D3D11_State *r_d3d11_state = 0; -global R_D3D11_Window r_d3d11_window_nil = {&r_d3d11_window_nil}; -global R_D3D11_Tex2D r_d3d11_tex2d_nil = {&r_d3d11_tex2d_nil}; -global R_D3D11_Buffer r_d3d11_buffer_nil = {&r_d3d11_buffer_nil}; +global read_only R_D3D11_Window r_d3d11_window_nil = {&r_d3d11_window_nil}; +global read_only R_D3D11_Tex2D r_d3d11_tex2d_nil = {&r_d3d11_tex2d_nil}; +global read_only R_D3D11_Buffer r_d3d11_buffer_nil = {&r_d3d11_buffer_nil}; //////////////////////////////// //~ rjf: Helpers From 6c37db2105393a6f69c511dbf95eac2498cf7dfb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 16:36:20 -0800 Subject: [PATCH 093/755] more inline visualization; do not require qualifier if view rule names collide with locals --- src/dbg_engine/dbg_engine_core.c | 1 + src/eval/eval_parse.c | 5 +---- src/raddbg/raddbg_views.c | 8 -------- src/raddbg/raddbg_views.h | 1 - src/render/d3d11/render_d3d11.c | 6 ++++-- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 2d096a35..a3f72a26 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -727,6 +727,7 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 d if(decorated && inline_site->type_idx != 0) { String8List list = {0}; + str8_list_pushf(scratch.arena, &list, "[inlined] "); e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); str8_list_push(scratch.arena, &list, name); e_type_rhs_string_from_key(scratch.arena, type, &list, 0); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 13ea164b..e6509523 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -2090,10 +2090,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse all argument expressions E_Expr *callee_expr = atom; E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); - if(callee_expr->kind == E_ExprKind_LeafIdent) - { - call_expr->string = callee_expr->string; - } + call_expr->string = callee_expr->string; e_expr_push_child(call_expr, callee_expr); E_TokenArray args_parse_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5df53e09..b37ea013 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1286,14 +1286,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.eval = e_eval_from_expr(scratch.arena, root_expr); result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); - - //- rjf: determine if inlined - E_Type *type = e_type_from_key__cached(result.eval.type_key); - if(type->depth > 0) - { - result.is_inlined = 1; - } - scratch_end(scratch); }break; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 43d040b1..b017a4f8 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -97,7 +97,6 @@ struct RD_WatchRowCellInfo B32 is_button; B32 can_edit; B32 is_errored; - B32 is_inlined; String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index dc5cb244..20e5ab91 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -826,8 +826,10 @@ r_end_frame(void) tex = next) { next = tex->next; - tex->view->lpVtbl->Release(tex->view); - tex->texture->lpVtbl->Release(tex->texture); + tex->view->lpVtbl->Release(tex->view); + tex->texture->lpVtbl->Release(tex->texture); + tex->view = 0; + tex->texture = 0; tex->generation += 1; SLLStackPush(r_d3d11_state->first_free_tex2d, tex); } From 5f88db68ec4dacf96b3db0b9781acad56729c6d4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 16:48:12 -0800 Subject: [PATCH 094/755] preserve fancy string list on a per-ui_box basis - do not rely on fancy *run* list for truncated-string-hover, as this will invalidly hold onto stale render handles (fixes crash on font resizes) --- src/draw/draw.c | 13 ++++++++++ src/draw/draw.h | 1 + src/raddbg/raddbg_core.c | 9 ++++--- src/ui/ui_core.c | 52 +++++++++++++++++++--------------------- src/ui/ui_core.h | 11 +++++---- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index 272571b3..3325c098 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -71,6 +71,19 @@ dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList MemoryZeroStruct(to_push); } +internal DR_FancyStringList +dr_fancy_string_list_copy(Arena *arena, DR_FancyStringList *src) +{ + DR_FancyStringList dst = {0}; + for(DR_FancyStringNode *src_n = src->first; src_n != 0; src_n = src_n->next) + { + DR_FancyString fstr = src_n->v; + fstr.string = push_str8_copy(arena, fstr.string); + dr_fancy_string_list_push(arena, &dst, &fstr); + } + return dst; +} + internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list) { diff --git a/src/draw/draw.h b/src/draw/draw.h index 1efb2bed..622ac6ca 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -111,6 +111,7 @@ internal U64 dr_hash_from_string(String8 string); internal void dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str); #define dr_fancy_string_list_push_new(arena, list, font_, size_, color_, string_, ...) dr_fancy_string_list_push((arena), (list), &(DR_FancyString){.font = (font_), .string = (string_), .color = (color_), .size = (size_), __VA_ARGS__}) internal void dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push); +internal DR_FancyStringList dr_fancy_string_list_copy(Arena *arena, DR_FancyStringList *src); internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list); internal DR_FancyRunList dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs); internal DR_FancyRunList dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f938372b..a3a06ea0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3825,10 +3825,9 @@ rd_window_frame(void) if(ui_string_hover_active()) UI_Tooltip { Temp scratch = scratch_begin(0, 0); - String8 string = ui_string_hover_string(scratch.arena); - DR_FancyRunList runs = ui_string_hover_runs(scratch.arena); + DR_FancyStringList fstrs = ui_string_hover_fstrs(scratch.arena); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_string_fancy_runs(box, string, &runs); + ui_box_equip_display_fancy_strings(box, &fstrs); scratch_end(scratch); } @@ -8201,11 +8200,11 @@ rd_window_frame(void) max_x = (box->rect.x1-text_position.x); ellipses_run = fnt_push_run_from_string(scratch.arena, box->font, box->font_size, 0, box->tab_size, 0, str8_lit("...")); } - dr_truncated_fancy_run_list(text_position, &box->display_string_runs, max_x, ellipses_run); + dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) { Vec4F32 match_color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_string_runs, max_x, &box->fuzzy_match_ranges, match_color); + dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 532ed66f..4b1f0350 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -717,17 +717,10 @@ ui_string_hover_begin_time_us(void) return ui_state->string_hover_begin_us; } -internal String8 -ui_string_hover_string(Arena *arena) +internal DR_FancyStringList +ui_string_hover_fstrs(Arena *arena) { - String8 result = push_str8_copy(arena, ui_state->string_hover_string); - return result; -} - -internal DR_FancyRunList -ui_string_hover_runs(Arena *arena) -{ - DR_FancyRunList result = dr_fancy_run_list_copy(arena, &ui_state->string_hover_fancy_runs); + DR_FancyStringList result = dr_fancy_string_list_copy(arena, &ui_state->string_hover_fstrs); return result; } @@ -1533,7 +1526,13 @@ ui_end_build(void) } String8 box_display_string = ui_box_display_string(b); Vec2F32 text_pos = ui_box_text_position(b); - Vec2F32 drawn_text_dim = b->display_string_runs.dim; + Vec2F32 drawn_text_dim = {0}; + { + Temp scratch = scratch_begin(0, 0); + DR_FancyRunList fruns = dr_fancy_run_list_from_fancy_string_list(scratch.arena, b->tab_size, b->text_raster_flags, &b->display_fstrs); + drawn_text_dim = fruns.dim; + scratch_end(scratch); + } B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > rect.x1); B32 mouse_is_hovering = contains_2f32(r2f32p(text_pos.x, rect.y0, @@ -1542,11 +1541,12 @@ ui_end_build(void) ui_state->mouse); if(text_is_truncated && mouse_is_hovering && !(b->flags & UI_BoxFlag_DisableTruncatedHover)) { - if(!str8_match(box_display_string, ui_state->string_hover_string, 0)) + if(!str8_match(box_display_string, ui_state->string_hover_string, 0) || box->font_size != ui_state->string_hover_size) { arena_clear(ui_state->string_hover_arena); ui_state->string_hover_string = push_str8_copy(ui_state->string_hover_arena, box_display_string); - ui_state->string_hover_fancy_runs = dr_fancy_run_list_copy(ui_state->string_hover_arena, &b->display_string_runs); + ui_state->string_hover_size = box->font_size; + ui_state->string_hover_fstrs = dr_fancy_string_list_copy(ui_state->string_hover_arena, &b->display_fstrs); ui_state->string_hover_begin_us = os_now_microseconds(); } ui_state->string_hover_build_index = ui_state->build_index; @@ -1599,7 +1599,7 @@ ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis) case UI_SizeKind_TextContent: { F32 padding = root->pref_size[axis].value; - F32 text_size = root->display_string_runs.dim.x; + F32 text_size = root->display_fruns.dim.x; root->fixed_size.v[axis] = padding + text_size + root->text_padding*2; }break; } @@ -2423,7 +2423,8 @@ ui_box_equip_display_string(UI_Box *box, String8 string) String8 display_string = ui_box_display_string(box); DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[text_color_code], box->font_size, 0, 0}}; DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); + box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2438,13 +2439,15 @@ ui_box_equip_display_string(UI_Box *box, String8 string) DR_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->palette->colors[text_color_code], box->font_size, 3.f, 0}}; DR_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->palette->colors[text_color_code], box->font_size, 0, 0}}; DR_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); + box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); } else { DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[UI_ColorCode_Text], box->font_size, 0, 0}}; DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &fancy_strings); + box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); + box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); } scratch_end(scratch); } @@ -2456,15 +2459,8 @@ ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; box->string = dr_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_string_runs = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, strings); -} - -internal inline void -ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, DR_FancyRunList *runs) -{ - box->flags |= UI_BoxFlag_HasDisplayString; - box->string = push_str8_copy(ui_build_arena(), string); - box->display_string_runs = dr_fancy_run_list_copy(ui_build_arena(), runs); + box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), strings); + box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); } internal inline void @@ -2529,13 +2525,13 @@ ui_box_text_position(UI_Box *box) }break; case UI_TextAlign_Center: { - Vec2F32 text_dim = box->display_string_runs.dim; + Vec2F32 text_dim = box->display_fruns.dim; result.x = round_f32((box->rect.p0.x + box->rect.p1.x)/2 - text_dim.x/2); result.x = ClampBot(result.x, box->rect.x0); }break; case UI_TextAlign_Right: { - Vec2F32 text_dim = box->display_string_runs.dim; + Vec2F32 text_dim = box->display_fruns.dim; result.x = round_f32((box->rect.p1.x) - text_dim.x - box->text_padding); result.x = ClampBot(result.x, box->rect.x0); }break; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 45c9c8b2..6bf7496b 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -433,7 +433,8 @@ struct UI_Box F32 text_padding; //- rjf: per-build artifacts - DR_FancyRunList display_string_runs; + DR_FancyStringList display_fstrs; + DR_FancyRunList display_fruns; Rng2F32 rect; Vec2F32 fixed_position_animated; Vec2F32 position_delta; @@ -680,7 +681,8 @@ struct UI_State String8 drag_state_data; Arena *string_hover_arena; String8 string_hover_string; - DR_FancyRunList string_hover_fancy_runs; + F32 string_hover_size; + DR_FancyStringList string_hover_fstrs; U64 string_hover_begin_us; U64 string_hover_build_index; U64 last_time_mousemoved_us; @@ -812,8 +814,8 @@ internal String8 ui_get_drag_data(U64 min_required_size); #define ui_get_drag_struct(type) ((type *)ui_get_drag_data(sizeof(type)).str) //- rjf: hovered string info -internal B32 ui_string_hover_active(void); -internal DR_FancyRunList ui_string_hover_runs(Arena *arena); +internal B32 ui_string_hover_active(void); +internal DR_FancyStringList ui_string_hover_fstrs(Arena *arena); //- rjf: interaction keys internal UI_Key ui_hot_key(void); @@ -881,7 +883,6 @@ internal UI_Box * ui_build_box_from_stringf(UI_BoxFlags flags, char *fm //- rjf: box node equipment internal inline void ui_box_equip_display_string(UI_Box *box, String8 string); internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings); -internal inline void ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, DR_FancyRunList *runs); internal inline void ui_box_equip_fuzzy_match_ranges(UI_Box *box, FuzzyMatchRangeList *matches); internal inline void ui_box_equip_draw_bucket(UI_Box *box, DR_Bucket *bucket); internal inline void ui_box_equip_custom_draw(UI_Box *box, UI_BoxCustomDrawFunctionType *custom_draw, void *user_data); From c555166af68e8e970e232eff2376cf0a69118729 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 16:58:17 -0800 Subject: [PATCH 095/755] visualize *.N ptrs in single-line eval visualization; eliminate old hover eval code --- src/raddbg/raddbg_core.c | 352 +++++++-------------------------------- 1 file changed, 58 insertions(+), 294 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a3a06ea0..8adb184b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6288,297 +6288,6 @@ rd_window_frame(void) } } } - -#if 0 // TODO(rjf): @cfg - Temp scratch = scratch_begin(0, 0); - DI_Scope *scope = di_scope_open(); - String8 expr = ws->hover_eval_string; - E_Eval eval = e_eval_from_string(scratch.arena, expr); - EV_ViewRuleList top_level_view_rules = {0}; - - //- rjf: build if good - if(!e_type_key_match(eval.type_key, e_type_key_zero()) && !ui_any_ctx_menu_is_open()) - UI_Focus((hover_eval_is_open && !ui_any_ctx_menu_is_open() && ws->hover_eval_focused && !query_is_open) ? UI_FocusKind_Null : UI_FocusKind_Off) - { - //- rjf: eval -> viz artifacts - F32 row_height = floor_f32(ui_top_font_size()*2.8f); - RD_CfgTable cfg_table = {0}; - U64 expr_hash = d_hash_from_string(expr); - String8 ev_view_key_string = push_str8f(scratch.arena, "eval_hover_%I64x", expr_hash); - 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_BlockTree block_tree = ev_block_tree_from_string(scratch.arena, ev_view, str8_zero(), expr, &top_level_view_rules); - EV_BlockRangeList block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); - // 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 rows = ev_windowed_row_list_from_block_range_list(scratch.arena, ev_view, str8_zero(), &block_ranges, r1u64(0, 50)); - // EV_WindowedRowList viz_rows = ev_windowed_row_list_from_block_list(scratch.arena, ev_view, r1s64(0, 50), &viz_blocks); - - //- rjf: animate - { - B32 do_menu_animations = rd_setting_b32_from_name(str8_lit("menu_animations")); - F32 rate = do_menu_animations ? 1 - pow_f32(2, (-60.f * rd_state->frame_dt)) : 1.f; - - // rjf: animate height - { - F32 hover_eval_container_height_target = row_height * Min(30, block_tree.total_row_count); - ws->hover_eval_num_visible_rows_t += (hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) * rate; - if(abs_f32(hover_eval_container_height_target - ws->hover_eval_num_visible_rows_t) > 0.5f) - { - rd_request_frame(); - } - else - { - ws->hover_eval_num_visible_rows_t = hover_eval_container_height_target; - } - } - - // rjf: animate open - { - F32 diff = 1.f - ws->hover_eval_open_t; - ws->hover_eval_open_t += diff*rate; - if(abs_f32(diff) < 0.01f) - { - ws->hover_eval_open_t = 1.f; - } - else - { - rd_request_frame(); - } - } - } - - //- rjf: calculate width - F32 width_px = 40.f*ui_top_font_size(); - F32 expr_column_width_px = 15.f*ui_top_font_size(); - F32 value_column_width_px = 25.f*ui_top_font_size(); - if(rows.first != 0) - { - EV_Row *row = rows.first; - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - String8 row_expr_string = ev_expr_string_from_row(scratch.arena, row, 0); - String8 row_display_value = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - expr_column_width_px = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, 0, row_expr_string).x + ui_top_font_size()*10.f; - value_column_width_px = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, 0, row_display_value).x + ui_top_font_size()*5.f; - F32 total_dim_px = (expr_column_width_px + value_column_width_px); - width_px = Min(80.f*ui_top_font_size(), total_dim_px*1.5f); - } - - //- rjf: build hover eval box - F32 hover_eval_container_height = ws->hover_eval_num_visible_rows_t; - F32 corner_radius = ui_top_font_size()*0.25f; - ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); - ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); - ui_set_next_pref_width(ui_px(width_px, 1.f)); - ui_set_next_pref_height(ui_px(hover_eval_container_height, 1.f)); - ui_set_next_corner_radius_00(0); - ui_set_next_corner_radius_01(corner_radius); - ui_set_next_corner_radius_10(corner_radius); - ui_set_next_corner_radius_11(corner_radius); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_squish(0.25f-0.25f*ws->hover_eval_open_t); - ui_set_next_transparency(1.f-ws->hover_eval_open_t); - UI_Focus(UI_FocusKind_On) - { - hover_eval_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_Clip| - UI_BoxFlag_AllowOverflowY| - UI_BoxFlag_ViewScroll| - UI_BoxFlag_ViewClamp| - UI_BoxFlag_Floating| - UI_BoxFlag_AnimatePos| - UI_BoxFlag_Clickable| - UI_BoxFlag_DefaultFocusNav, - "###hover_eval"); - } - - //- rjf: build contents - UI_Parent(hover_eval_box) UI_PrefHeight(ui_px(row_height, 1.f)) - { - //- rjf: build rows - for(EV_Row *row = rows.first; row != 0; row = row->next) - { - //- rjf: unpack row - U64 row_depth = ev_depth_from_block(row->block); - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - String8 row_expr_string = ev_expr_string_from_row(scratch.arena, row, 0); - String8 row_edit_value = rd_value_string_from_eval(scratch.arena, 0, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - String8 row_display_value = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), 500.f, row_eval, row->member, row->view_rules); - B32 row_is_editable = ev_row_is_editable(row); - B32 row_is_expandable = ev_row_is_expandable(row); - - //- rjf: determine if row's data is fresh and/or bad - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row_eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - if(space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row_eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_eval.value.u64, row_eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 0); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - { - row_is_bad = 1; - } - } - } - }break; - } - - //- rjf: build row - UI_WidthFill UI_Row - { - ui_spacer(ui_em(0.5f, 1.f)); - if(row_depth > 0) - { - for(U64 indent = 0; indent < row_depth; indent += 1) - { - ui_spacer(ui_em(0.5f, 1.f)); - UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_em(1.f, 1.f)); - } - } - U64 row_hash = ev_hash_from_key(row->key); - B32 row_is_expanded = ev_expansion_from_key(ev_view, row->key); - if(row_is_expandable) - UI_PrefWidth(ui_em(1.f, 1)) - if(ui_pressed(ui_expanderf(row->block->rows_default_expanded ? !row_is_expanded : 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); - } - if(!row_is_expandable) - { - UI_PrefWidth(ui_em(1.f, 1)) - UI_Flags(UI_BoxFlag_DrawTextWeak) - RD_Font(RD_FontSlot_Icons) - ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); - } - UI_WidthFill UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Code)) - { - UI_PrefWidth(ui_px(expr_column_width_px, 1.f)) rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), row_expr_string); - ui_spacer(ui_em(1.5f, 1.f)); - if(row_is_editable) - { - if(row_is_fresh) - { - Vec4F32 rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rgba)); - } - UI_Signal sig = rd_line_editf(RD_LineEditFlag_CodeContents| - RD_LineEditFlag_DisplayStringIsCode| - RD_LineEditFlag_PreferDisplayString| - RD_LineEditFlag_Border, - 0, 0, &ws->hover_eval_txt_cursor, &ws->hover_eval_txt_mark, ws->hover_eval_txt_buffer, sizeof(ws->hover_eval_txt_buffer), &ws->hover_eval_txt_size, 0, row_edit_value, "%S###val_%I64x", row_display_value, row_hash); - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_committed(sig)) - { - String8 commit_string = str8(ws->hover_eval_txt_buffer, ws->hover_eval_txt_size); - B32 success = rd_commit_eval_value_string(row_eval, commit_string, 1); - if(success == 0) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } - } - } - else - { - if(row_is_fresh) - { - Vec4F32 rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rgba)); - ui_set_next_flags(UI_BoxFlag_DrawBackground); - } - rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), row_display_value); - } - } - if(row == rows.first) - { - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - UI_Signal watch_sig = rd_icon_buttonf(RD_IconKind_List, 0, "###watch_hover_eval"); - if(ui_hovering(watch_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - { - ui_labelf("Add the hovered expression to an opened watch view."); - } - if(ui_clicked(watch_sig)) - { - rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = expr); - } - } - if(ws->hover_eval_file_path.size != 0 || ws->hover_eval_vaddr != 0) - UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(3.f, 1.f)) - UI_CornerRadius10(corner_radius) - UI_CornerRadius11(corner_radius) - { - UI_Signal pin_sig = rd_icon_buttonf(RD_IconKind_Pin, 0, "###pin_hover_eval"); - if(ui_hovering(pin_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - UI_CornerRadius10(0) - UI_CornerRadius11(0) - { - ui_labelf("Pin the hovered expression to this code location."); - } - if(ui_clicked(pin_sig)) - { - rd_cmd(RD_CmdKind_ToggleWatchPin, - .file_path = ws->hover_eval_file_path, - .cursor = ws->hover_eval_file_pt, - .vaddr = ws->hover_eval_vaddr, - .string = expr); - } - } - } - } - } - UI_PrefWidth(ui_px(0, 0)) ui_spacer(ui_px(hover_eval_container_height-row_height, 1.f)); - } - - //- rjf: interact - { - UI_Signal hover_eval_sig = ui_signal_from_box(hover_eval_box); - if(ui_mouse_over(hover_eval_sig)) - { - ws->hover_eval_last_frame_idx = rd_state->frame_index; - } - else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) - { - rd_request_frame(); - } - if(ui_pressed(hover_eval_sig)) - { - ws->hover_eval_focused = 1; - } - } - } - - di_scope_close(scope); - scratch_end(scratch); -#endif } } @@ -9731,9 +9440,64 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul did_content = 1; if(depth < 4) { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); - E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); + if(type->count == 1) + { + E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); + E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); + } + else + { + String8 opener_string = str8_lit("["); + String8 closer_string = str8_lit("]"); + + // rjf: opener ({, [) + { + str8_list_push(arena, out, opener_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; + } + + // rjf: contents + { + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.expr, &irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); + B32 is_first = 1; + for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) + { + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + lookup_rule->range(scratch.arena, eval.expr, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + if(expr != &e_expr_nil) + { + if(!is_first) + { + String8 comma = str8_lit(", "); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; + str8_list_push(arena, out, comma); + } + is_first = 0; + E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); + space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); + if(space_taken > max_size && idx+1 < total_possible_child_count) + { + String8 ellipses = str8_lit(", ..."); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; + str8_list_push(arena, out, ellipses); + } + } + } + } + + // rjf: closer (}, ]) + { + str8_list_push(arena, out, closer_string); + space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; + } + } } else { From 295cfa8698c7733c97ee8f47ca53fb9f06242acb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 11 Feb 2025 17:21:24 -0800 Subject: [PATCH 096/755] fix new window creation --- src/raddbg/raddbg_core.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8adb184b..ebe426b0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -805,11 +805,15 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) DLLPushBack_NPZ(&rd_nil_panel_node, dst_active_parent->first, dst_active_parent->last, dst, next, prev); dst_active_parent->child_count += 1; } + if(dst_root == &rd_nil_panel_node) + { + dst_root = dst; + } // rjf: extract cfg info B32 panel_has_children = 0; dst->cfg = src; - dst->pct_of_parent = (F32)f64_from_str8(src->string); + dst->pct_of_parent = (src == src_root ? 1.f : (F32)f64_from_str8(src->string)); dst->tab_side = (rd_cfg_child_from_string(src, str8_lit("tabs_on_bottom")) != &rd_nil_cfg ? Side_Max : Side_Min); dst->split_axis = active_split_axis; for(RD_Cfg *src_child = src->first; src_child != &rd_nil_cfg; src_child = src_child->next) @@ -855,10 +859,6 @@ rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) if(rec.push_count > 0) { dst_active_parent = dst; - if(dst_root == &rd_nil_panel_node) - { - dst_root = dst; - } active_split_axis = axis2_flip(active_split_axis); } else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) @@ -12579,7 +12579,12 @@ rd_frame(void) //- rjf: animate theme // { - RD_Theme *last = rd_state->theme; + Temp scratch = scratch_begin(0, 0); + RD_Theme *last = push_array(scratch.arena, RD_Theme, 1); + if(rd_state->theme != 0) + { + MemoryCopyStruct(last, rd_state->theme); + } rd_state->theme = push_array(rd_frame_arena(), RD_Theme, 1); RD_Theme *current = rd_state->theme; RD_Theme *target = rd_state->theme_target; @@ -12611,6 +12616,7 @@ rd_frame(void) current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; } } + scratch_end(scratch); } ////////////////////////////// @@ -13459,12 +13465,15 @@ rd_frame(void) rd_cfg_newf(size, "720"); for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { - if(!str8_match(old_child->string, str8_lit("panels"), 0)) + if(!str8_match(old_child->string, str8_lit("panels"), 0) && + !str8_match(old_child->string, str8_lit("size"), 0)) { RD_Cfg *new_child = rd_cfg_deep_copy(old_child); rd_cfg_insert_child(new_window, new_window->last, new_child); } } + RD_Cfg *panels = rd_cfg_new(new_window, str8_lit("panels")); + rd_cfg_new(panels, str8_lit("selected")); }break; case RD_CmdKind_CloseWindow: { From 204ac609997a47327ce44a81613fade581b7bd29 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 14:01:21 -0800 Subject: [PATCH 097/755] extend fancy string lists to include per-node rasterization flags, to correctly mix flags from various fonts; pull command tables into the vocabulary map & accelerate lookups; drive icons/display-strings for commands with vocabulary map; plug in commands/fstrs to command evaluations in watch windows --- src/dbg_engine/dbg_engine.mdesk | 1 - src/dbg_engine/generated/dbg_engine.meta.h | 2 - src/draw/draw.c | 82 +- src/draw/draw.h | 67 +- src/raddbg/generated/raddbg.meta.c | 661 +++++++---- src/raddbg/generated/raddbg.meta.h | 21 +- src/raddbg/raddbg.mdesk | 55 +- src/raddbg/raddbg_core.c | 1157 +++++--------------- src/raddbg/raddbg_core.h | 67 +- src/raddbg/raddbg_views.c | 65 +- src/raddbg/raddbg_views.h | 4 +- src/raddbg/raddbg_widgets.c | 172 +-- src/raddbg/raddbg_widgets.h | 4 +- src/ui/ui_core.c | 44 +- src/ui/ui_core.h | 10 +- 15 files changed, 983 insertions(+), 1429 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 6f1e56eb..22961677 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -113,7 +113,6 @@ D_DevToggleTable: {eval_compiler_tooltips} {eval_watch_key_tooltips} {cmd_context_tooltips} - {scratch_mouse_draw} {updating_indicator} } diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index 38519f1a..f8d99632 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -77,7 +77,6 @@ global B32 DEV_draw_ui_box_heatmap = 0; global B32 DEV_eval_compiler_tooltips = 0; global B32 DEV_eval_watch_key_tooltips = 0; global B32 DEV_cmd_context_tooltips = 0; -global B32 DEV_scratch_mouse_draw = 0; global B32 DEV_updating_indicator = 0; struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = { @@ -88,7 +87,6 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = {&DEV_eval_compiler_tooltips, str8_lit_comp("eval_compiler_tooltips")}, {&DEV_eval_watch_key_tooltips, str8_lit_comp("eval_watch_key_tooltips")}, {&DEV_cmd_context_tooltips, str8_lit_comp("cmd_context_tooltips")}, -{&DEV_scratch_mouse_draw, str8_lit_comp("scratch_mouse_draw")}, {&DEV_updating_indicator, str8_lit_comp("updating_indicator")}, }; #endif // DBG_ENGINE_META_H diff --git a/src/draw/draw.c b/src/draw/draw.c index 3325c098..095edf51 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -45,9 +45,9 @@ dr_hash_from_string(String8 string) //~ rjf: Fancy String Type Functions internal void -dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str) +dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str) { - DR_FancyStringNode *n = push_array_no_zero(arena, DR_FancyStringNode, 1); + DR_FStrNode *n = push_array_no_zero(arena, DR_FStrNode, 1); MemoryCopyStruct(&n->v, str); SLLQueuePush(list->first, list->last, n); list->node_count += 1; @@ -55,7 +55,21 @@ dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString } internal void -dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push) +dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string) +{ + DR_FStr fstr = {string, *params}; + for(U64 idx = 0; idx < sizeof(DR_FStrParams); idx += 1) + { + if(((U8 *)overrides)[idx] != 0) + { + ((U8 *)&fstr.params)[idx] = ((U8 *)overrides)[idx]; + } + } + dr_fstrs_push(arena, list, &fstr); +} + +internal void +dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push) { if(dst->last != 0 && to_push->first != 0) { @@ -71,27 +85,27 @@ dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList MemoryZeroStruct(to_push); } -internal DR_FancyStringList -dr_fancy_string_list_copy(Arena *arena, DR_FancyStringList *src) +internal DR_FStrList +dr_fstrs_copy(Arena *arena, DR_FStrList *src) { - DR_FancyStringList dst = {0}; - for(DR_FancyStringNode *src_n = src->first; src_n != 0; src_n = src_n->next) + DR_FStrList dst = {0}; + for(DR_FStrNode *src_n = src->first; src_n != 0; src_n = src_n->next) { - DR_FancyString fstr = src_n->v; + DR_FStr fstr = src_n->v; fstr.string = push_str8_copy(arena, fstr.string); - dr_fancy_string_list_push(arena, &dst, &fstr); + dr_fstrs_push(arena, &dst, &fstr); } return dst; } internal String8 -dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list) +dr_string_from_fstrs(Arena *arena, DR_FStrList *list) { String8 result = {0}; result.size = list->total_size; result.str = push_array_no_zero(arena, U8, result.size); U64 idx = 0; - for(DR_FancyStringNode *n = list->first; n != 0; n = n->next) + for(DR_FStrNode *n = list->first; n != 0; n = n->next) { MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); idx += n->v.string.size; @@ -99,19 +113,19 @@ dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list) return result; } -internal DR_FancyRunList -dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs) +internal DR_FRunList +dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) { ProfBeginFunction(); - DR_FancyRunList run_list = {0}; + DR_FRunList run_list = {0}; F32 base_align_px = 0; - for(DR_FancyStringNode *n = strs->first; n != 0; n = n->next) + for(DR_FStrNode *n = strs->first; n != 0; n = n->next) { - DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); - dst_n->v.run = fnt_push_run_from_string(arena, n->v.font, n->v.size, base_align_px, tab_size_px, flags, n->v.string); - dst_n->v.color = n->v.color; - dst_n->v.underline_thickness = n->v.underline_thickness; - dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; + DR_FRunNode *dst_n = push_array(arena, DR_FRunNode, 1); + dst_n->v.run = fnt_push_run_from_string(arena, n->v.params.font, n->v.params.size, base_align_px, tab_size_px, n->v.params.raster_flags, n->v.string); + dst_n->v.color = n->v.params.color; + dst_n->v.underline_thickness = n->v.params.underline_thickness; + dst_n->v.strikethrough_thickness = n->v.params.strikethrough_thickness; SLLQueuePush(run_list.first, run_list.last, dst_n); run_list.node_count += 1; run_list.dim.x += dst_n->v.run.dim.x; @@ -122,22 +136,6 @@ dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_Rast return run_list; } -internal DR_FancyRunList -dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src) -{ - DR_FancyRunList dst = {0}; - for(DR_FancyRunNode *src_n = src->first; src_n != 0; src_n = src_n->next) - { - DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); - SLLQueuePush(dst.first, dst.last, dst_n); - MemoryCopyStruct(&dst_n->v, &src_n->v); - dst_n->v.run.pieces = fnt_piece_array_copy(arena, &src_n->v.run.pieces); - dst.node_count += 1; - } - dst.dim = src->dim; - return dst; -} - //////////////////////////////// //~ rjf: Top-Level API // @@ -468,7 +466,7 @@ dr_sub_bucket(DR_Bucket *bucket) //- rjf: text internal void -dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run) +dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run) { ProfBeginFunction(); @@ -480,9 +478,9 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run B32 trailer_found = 0; Vec4F32 last_color = {0}; U64 byte_off = 0; - for(DR_FancyRunNode *n = list->first; n != 0; n = n->next) + for(DR_FRunNode *n = list->first; n != 0; n = n->next) { - DR_FancyRun *fr = &n->v; + DR_FRun *fr = &n->v; Rng1F32 pixel_range = {0}; { pixel_range.min = 100000; @@ -571,7 +569,7 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run } internal void -dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) +dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) { for(FuzzyMatchRangeNode *match_n = ranges->first; match_n != 0; match_n = match_n->next) { @@ -586,9 +584,9 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x F32 advance = 0; F32 ascent = 0; F32 descent = 0; - for(DR_FancyRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) + for(DR_FRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) { - DR_FancyRun *fr = &fr_n->v; + DR_FRun *fr = &fr_n->v; FNT_Run *run = &fr->run; ascent = run->ascent; descent = run->descent; diff --git a/src/draw/draw.h b/src/draw/draw.h index 622ac6ca..4f0d26bb 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -7,35 +7,42 @@ //////////////////////////////// //~ rjf: Fancy String Types -typedef struct DR_FancyString DR_FancyString; -struct DR_FancyString +typedef struct DR_FStrParams DR_FStrParams; +struct DR_FStrParams { FNT_Tag font; - String8 string; + FNT_RasterFlags raster_flags; Vec4F32 color; F32 size; F32 underline_thickness; F32 strikethrough_thickness; }; -typedef struct DR_FancyStringNode DR_FancyStringNode; -struct DR_FancyStringNode +typedef struct DR_FStr DR_FStr; +struct DR_FStr { - DR_FancyStringNode *next; - DR_FancyString v; + String8 string; + DR_FStrParams params; }; -typedef struct DR_FancyStringList DR_FancyStringList; -struct DR_FancyStringList +typedef struct DR_FStrNode DR_FStrNode; +struct DR_FStrNode { - DR_FancyStringNode *first; - DR_FancyStringNode *last; + DR_FStrNode *next; + DR_FStr v; +}; + +typedef struct DR_FStrList DR_FStrList; +struct DR_FStrList +{ + DR_FStrNode *first; + DR_FStrNode *last; U64 node_count; U64 total_size; }; -typedef struct DR_FancyRun DR_FancyRun; -struct DR_FancyRun +typedef struct DR_FRun DR_FRun; +struct DR_FRun { FNT_Run run; Vec4F32 color; @@ -43,18 +50,18 @@ struct DR_FancyRun F32 strikethrough_thickness; }; -typedef struct DR_FancyRunNode DR_FancyRunNode; -struct DR_FancyRunNode +typedef struct DR_FRunNode DR_FRunNode; +struct DR_FRunNode { - DR_FancyRunNode *next; - DR_FancyRun v; + DR_FRunNode *next; + DR_FRun v; }; -typedef struct DR_FancyRunList DR_FancyRunList; -struct DR_FancyRunList +typedef struct DR_FRunList DR_FRunList; +struct DR_FRunList { - DR_FancyRunNode *first; - DR_FancyRunNode *last; + DR_FRunNode *first; + DR_FRunNode *last; U64 node_count; Vec2F32 dim; }; @@ -108,13 +115,13 @@ internal U64 dr_hash_from_string(String8 string); //////////////////////////////// //~ rjf: Fancy String Type Functions -internal void dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str); -#define dr_fancy_string_list_push_new(arena, list, font_, size_, color_, string_, ...) dr_fancy_string_list_push((arena), (list), &(DR_FancyString){.font = (font_), .string = (string_), .color = (color_), .size = (size_), __VA_ARGS__}) -internal void dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push); -internal DR_FancyStringList dr_fancy_string_list_copy(Arena *arena, DR_FancyStringList *src); -internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list); -internal DR_FancyRunList dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs); -internal DR_FancyRunList dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src); +internal void dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str); +internal void dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string); +#define dr_fstrs_push_new(arena, list, params, string, ...) dr_fstrs_push_new_((arena), (list), (params), &(DR_FStrParams){.size = 0, __VA_ARGS__}, (string)) +internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push); +internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src); +internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list); +internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs); //////////////////////////////// //~ rjf: Top-Level API @@ -185,8 +192,8 @@ internal void dr_sub_bucket(DR_Bucket *bucket); //~ rjf: Draw Call Helpers //- rjf: text -internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run); -internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); +internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run); +internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run); internal void dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 39b45bcb..8480458c 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,31 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 rd_cfg_src_string_table[4] = -{ -str8_lit_comp("user"), -str8_lit_comp("project"), -str8_lit_comp("command_line"), -str8_lit_comp("transient"), -}; - -RD_CmdKind rd_cfg_src_load_cmd_kind_table[4] = -{ -RD_CmdKind_OpenUser, -RD_CmdKind_OpenProject, -RD_CmdKind_Null, -RD_CmdKind_Null, -}; - -RD_CmdKind rd_cfg_src_write_cmd_kind_table[4] = -{ -RD_CmdKind_WriteUserData, -RD_CmdKind_WriteProjectData, -RD_CmdKind_Null, -RD_CmdKind_Null, -}; - -RD_VocabularyInfo rd_vocabulary_info_table[66] = +RD_VocabInfo rd_vocab_info_table[277] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -96,6 +72,217 @@ RD_VocabularyInfo rd_vocabulary_info_table[66] = {str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, {str8_lit_comp("frozen"), str8_lit_comp(""), str8_lit_comp("Frozen"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("id"), str8_lit_comp("ids"), str8_lit_comp("ID"), str8_lit_comp("IDs"), RD_IconKind_Null}, +{str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("launch_and_init"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, +{str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("kill_all"), str8_lit_comp(""), str8_lit_comp("Kill All"), str8_lit_comp(""), RD_IconKind_Stop}, +{str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("continue"), str8_lit_comp(""), str8_lit_comp("Continue"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("step_into_inst"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over_inst"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("step_into_line"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over_line"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("step_out"), str8_lit_comp(""), str8_lit_comp("Step Out"), str8_lit_comp(""), RD_IconKind_StepOut}, +{str8_lit_comp("halt"), str8_lit_comp(""), str8_lit_comp("Halt"), str8_lit_comp(""), RD_IconKind_Pause}, +{str8_lit_comp("soft_halt_refresh"), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), str8_lit_comp(""), RD_IconKind_Refresh}, +{str8_lit_comp("set_thread_ip"), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("run_to_line"), str8_lit_comp(""), str8_lit_comp("Run To Line"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("run"), str8_lit_comp(""), str8_lit_comp("Run"), str8_lit_comp(""), RD_IconKind_Play}, +{str8_lit_comp("restart"), str8_lit_comp(""), str8_lit_comp("Restart"), str8_lit_comp(""), RD_IconKind_Redo}, +{str8_lit_comp("step_into"), str8_lit_comp(""), str8_lit_comp("Step Into"), str8_lit_comp(""), RD_IconKind_StepInto}, +{str8_lit_comp("step_over"), str8_lit_comp(""), str8_lit_comp("Step Over"), str8_lit_comp(""), RD_IconKind_StepOver}, +{str8_lit_comp("freeze_thread"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_thread"), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_process"), str8_lit_comp(""), str8_lit_comp("Freeze Process"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_process"), str8_lit_comp(""), str8_lit_comp("Thaw Process"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_machine"), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), str8_lit_comp(""), RD_IconKind_Locked}, +{str8_lit_comp("thaw_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("freeze_local_machine"), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("thaw_local_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("freeze_entity"), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("thaw_entity"), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("set_entity_color"), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("set_entity_name"), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("attach"), str8_lit_comp(""), str8_lit_comp("Attach"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("exit"), str8_lit_comp(""), str8_lit_comp("Exit"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("open_lister"), str8_lit_comp(""), str8_lit_comp("Open Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("run_command"), str8_lit_comp(""), str8_lit_comp("Run Command"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp("OS Event"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_unwind"), str8_lit_comp(""), str8_lit_comp("Select Unwind"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("up_one_frame"), str8_lit_comp(""), str8_lit_comp("Up One Frame"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("inc_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("inc_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_window"), str8_lit_comp(""), str8_lit_comp("Open New Window"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("close_window"), str8_lit_comp(""), str8_lit_comp("Close Window"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("toggle_fullscreen"), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("bring_to_front"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("popup_accept"), str8_lit_comp(""), str8_lit_comp("Popup Accept"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("popup_cancel"), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("reset_to_default_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("reset_to_compact_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("new_panel_left"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), str8_lit_comp(""), RD_IconKind_XSplit}, +{str8_lit_comp("new_panel_up"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), str8_lit_comp(""), RD_IconKind_YSplit}, +{str8_lit_comp("new_panel_right"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), str8_lit_comp(""), RD_IconKind_XSplit}, +{str8_lit_comp("new_panel_down"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), str8_lit_comp(""), RD_IconKind_YSplit}, +{str8_lit_comp("split_panel"), str8_lit_comp(""), str8_lit_comp("Split Panel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("rotate_panel_columns"), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("next_panel"), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("prev_panel"), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("focus_panel"), str8_lit_comp(""), str8_lit_comp("Focus Panel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("focus_panel_right"), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("focus_panel_left"), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("focus_panel_up"), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("focus_panel_down"), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("undo"), str8_lit_comp(""), str8_lit_comp("Undo"), str8_lit_comp(""), RD_IconKind_Undo}, +{str8_lit_comp("redo"), str8_lit_comp(""), str8_lit_comp("Redo"), str8_lit_comp(""), RD_IconKind_Redo}, +{str8_lit_comp("go_back"), str8_lit_comp(""), str8_lit_comp("Go Back"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("go_forward"), str8_lit_comp(""), str8_lit_comp("Go Forward"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("close_panel"), str8_lit_comp(""), str8_lit_comp("Close Panel"), str8_lit_comp(""), RD_IconKind_ClosePanel}, +{str8_lit_comp("focus_tab"), str8_lit_comp(""), str8_lit_comp("Focus Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("next_tab"), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("prev_tab"), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("move_tab_right"), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("move_tab_left"), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, +{str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, +{str8_lit_comp("tab_bar_bottom"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("set_current_path"), str8_lit_comp(""), str8_lit_comp("Set Current Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("open"), str8_lit_comp(""), str8_lit_comp("Open"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("switch"), str8_lit_comp(""), str8_lit_comp("Switch"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("switch_to_partner_file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("record_file_in_project"), str8_lit_comp(""), str8_lit_comp("Record File In Project"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("show_file_in_explorer"), str8_lit_comp(""), str8_lit_comp("Show File In Explorer"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("go_to_disassembly"), str8_lit_comp(""), str8_lit_comp("Go To Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("go_to_source"), str8_lit_comp(""), str8_lit_comp("Go To Source"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("set_file_replacement_path"), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_user"), str8_lit_comp(""), str8_lit_comp("Open User"), str8_lit_comp(""), RD_IconKind_Person}, +{str8_lit_comp("open_project"), str8_lit_comp(""), str8_lit_comp("Open Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, +{str8_lit_comp("open_recent_project"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, +{str8_lit_comp("write_user_data"), str8_lit_comp(""), str8_lit_comp("Write User Data"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("write_project_data"), str8_lit_comp(""), str8_lit_comp("Write Project Data"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("edit"), str8_lit_comp(""), str8_lit_comp("Edit"), str8_lit_comp(""), RD_IconKind_Pencil}, +{str8_lit_comp("accept"), str8_lit_comp(""), str8_lit_comp("Accept"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("cancel"), str8_lit_comp(""), str8_lit_comp("Cancel"), str8_lit_comp(""), RD_IconKind_X}, +{str8_lit_comp("move_left"), str8_lit_comp(""), str8_lit_comp("Move Left"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right"), str8_lit_comp(""), str8_lit_comp("Move Right"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up"), str8_lit_comp(""), str8_lit_comp("Move Up"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down"), str8_lit_comp(""), str8_lit_comp("Move Down"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_select"), str8_lit_comp(""), str8_lit_comp("Move Left Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_select"), str8_lit_comp(""), str8_lit_comp("Move Right Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_select"), str8_lit_comp(""), str8_lit_comp("Move Up Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_select"), str8_lit_comp(""), str8_lit_comp("Move Down Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_chunk"), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_chunk"), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_chunk"), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_chunk"), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_page"), str8_lit_comp(""), str8_lit_comp("Move Up Page"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_page"), str8_lit_comp(""), str8_lit_comp("Move Down Page"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_whole"), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_whole"), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_left_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_right_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_chunk_select"), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_page_select"), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_page_select"), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_whole_select"), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_whole_select"), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_up_reorder"), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_down_reorder"), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_home"), str8_lit_comp(""), str8_lit_comp("Move Home"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_end"), str8_lit_comp(""), str8_lit_comp("Move End"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_home_select"), str8_lit_comp(""), str8_lit_comp("Move Home Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_end_select"), str8_lit_comp(""), str8_lit_comp("Move End Select"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_all"), str8_lit_comp(""), str8_lit_comp("Select All"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("delete_single"), str8_lit_comp(""), str8_lit_comp("Delete Single"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("delete_chunk"), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("backspace_single"), str8_lit_comp(""), str8_lit_comp("Backspace Single"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("backspace_chunk"), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("copy"), str8_lit_comp(""), str8_lit_comp("Copy"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("cut"), str8_lit_comp(""), str8_lit_comp("Cut"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("paste"), str8_lit_comp(""), str8_lit_comp("Paste"), str8_lit_comp(""), RD_IconKind_Clipboard}, +{str8_lit_comp("insert_text"), str8_lit_comp(""), str8_lit_comp("Insert Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_line"), str8_lit_comp(""), str8_lit_comp("Go To Line"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_address"), str8_lit_comp(""), str8_lit_comp("Go To Address"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("center_cursor"), str8_lit_comp(""), str8_lit_comp("Center Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("contain_cursor"), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("find_text_forward"), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_text_backward"), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_next"), str8_lit_comp(""), str8_lit_comp("Find Next"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_prev"), str8_lit_comp(""), str8_lit_comp("Find Previous"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_thread"), str8_lit_comp(""), str8_lit_comp("Find Thread"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("find_selected_thread"), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("goto_name"), str8_lit_comp(""), str8_lit_comp("Go To Name"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("goto_name_at_cursor"), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("toggle_watch_expr"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("set_columns"), str8_lit_comp(""), str8_lit_comp("Set Columns"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("toggle_address_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, +{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), str8_lit_comp(""), RD_IconKind_Trash}, +{str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_function_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, +{str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, +{str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("enable_target"), str8_lit_comp(""), str8_lit_comp("Enable Target"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("disable_target"), str8_lit_comp(""), str8_lit_comp("Disable Target"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("register_as_jit_debugger"), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("filter"), str8_lit_comp(""), str8_lit_comp("Filter"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("apply_filter"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("clear_filter"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, +{str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("target"), str8_lit_comp(""), str8_lit_comp("Target"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("targets"), str8_lit_comp(""), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("file_path_map"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("breakpoints"), str8_lit_comp(""), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("watch_pins"), str8_lit_comp(""), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin}, +{str8_lit_comp("scheduler"), str8_lit_comp(""), str8_lit_comp("Scheduler"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("call_stack"), str8_lit_comp(""), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread}, +{str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, +{str8_lit_comp("watch"), str8_lit_comp(""), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("locals"), str8_lit_comp(""), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("registers"), str8_lit_comp(""), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("globals"), str8_lit_comp(""), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("thread_locals"), str8_lit_comp(""), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("types"), str8_lit_comp(""), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("procedures"), str8_lit_comp(""), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, +{str8_lit_comp("settings"), str8_lit_comp(""), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear}, +{str8_lit_comp("pick_file"), str8_lit_comp(""), str8_lit_comp("Pick File"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("pick_folder"), str8_lit_comp(""), str8_lit_comp("Pick Folder"), str8_lit_comp(""), RD_IconKind_FolderOpenFilled}, +{str8_lit_comp("pick_file_or_folder"), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("push_lister"), str8_lit_comp(""), str8_lit_comp("Push Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("complete_lister"), str8_lit_comp(""), str8_lit_comp("Complete Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("cancel_lister"), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; RD_NameSchemaInfo rd_name_schema_info_table[10] = @@ -157,220 +344,220 @@ Rng1U64 rd_reg_slot_range_table[38] = RD_CmdKindInfo rd_cmd_kind_info_table[212] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), RD_IconKind_PlayStepForward, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), str8_lit_comp("Kill"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), str8_lit_comp("Kill All"), RD_IconKind_Stop, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Continue"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Assembly)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Assembly)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Into (Line)"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), str8_lit_comp("Step Over (Line)"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Out"), RD_IconKind_StepOut, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), str8_lit_comp("Halt"), RD_IconKind_Pause, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), RD_IconKind_Refresh, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Run To Line"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), str8_lit_comp("Run"), RD_IconKind_Play, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), str8_lit_comp("Restart"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Into"), RD_IconKind_StepInto, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Step Over"), RD_IconKind_StepOver, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Process"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Process"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), RD_IconKind_Locked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), RD_IconKind_Unlocked, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), RD_IconKind_Machine, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Attach"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), str8_lit_comp("Exit"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Open Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), str8_lit_comp("Run Command"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("OS Event"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Thread"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Unwind"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Up One Frame"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open New Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Window"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Accept"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), RD_IconKind_Window, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), RD_IconKind_XSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), str8_lit_comp("Split Panel Down"), RD_IconKind_YSplit, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Split Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Undo"), RD_IconKind_Undo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Redo"), RD_IconKind_Redo, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Back"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go Forward"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Close Panel"), RD_IconKind_ClosePanel, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Right"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Move Tab Left"), RD_IconKind_LeftArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Open Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Close Tab"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Tab"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Top"), RD_IconKind_UpArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), str8_lit_comp("Anchor Tab Bar To Bottom"), RD_IconKind_DownArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Current Path"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Open"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Record File In Project"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), str8_lit_comp("Show File In Explorer"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), str8_lit_comp("Go To Source"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), str8_lit_comp("Open User"), RD_IconKind_Person, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), RD_IconKind_Briefcase, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write User Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Write Project Data"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Edit"), RD_IconKind_Pencil, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Accept"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel"), RD_IconKind_X, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Up Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Down Reorder"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move Home Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Move End Select"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select All"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Single"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), str8_lit_comp("Copy"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cut"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Paste"), RD_IconKind_Clipboard, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Insert Text"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Line"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Address"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Center Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Next"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Previous"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Go To Name"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Watch Expression"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Set Columns"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Address Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), str8_lit_comp("Toggle Code Bytes Visibility"), RD_IconKind_Thumbnails, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), RD_IconKind_Trash, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Address Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), str8_lit_comp("Add Function Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Toggle Breakpoint"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), str8_lit_comp("Add Watch Pin"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), str8_lit_comp("Set Next Statement"), RD_IconKind_RightArrow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), str8_lit_comp("Add Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Select Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Enable Target"), RD_IconKind_CheckFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Disable Target"), RD_IconKind_CheckHollow, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Find Code Location"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), str8_lit_comp("Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), RD_IconKind_Find, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), str8_lit_comp("Getting Started"), RD_IconKind_QuestionMark, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Commands"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Target"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Targets"), RD_IconKind_Target, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("File Path Map"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch Pins"), RD_IconKind_Pin, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), str8_lit_comp("Scheduler"), RD_IconKind_Scheduler, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), str8_lit_comp("Call Stack"), RD_IconKind_Thread, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Modules"), RD_IconKind_Module, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Watch"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Registers"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Globals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Thread Locals"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Types"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Procedures"), RD_IconKind_Binoculars, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pending File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), RD_IconKind_Glasses, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Output"), RD_IconKind_List, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Memory"), RD_IconKind_Grid, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), str8_lit_comp("Settings"), RD_IconKind_Gear, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick Folder"), RD_IconKind_FolderOpenFilled, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), RD_IconKind_FileOutline, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Push Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Complete Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Log Marker"), RD_IconKind_Null, (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -RD_StringBindingPair rd_default_binding_table[111] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 11d009de..a153b1eb 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -6,15 +6,6 @@ #ifndef RADDBG_META_H #define RADDBG_META_H -typedef enum RD_CfgSrc -{ -RD_CfgSrc_User, -RD_CfgSrc_Project, -RD_CfgSrc_CommandLine, -RD_CfgSrc_Transient, -RD_CfgSrc_COUNT, -} RD_CfgSrc; - typedef enum RD_RegSlot { RD_RegSlot_Null, @@ -444,8 +435,8 @@ RD_ThemePreset_FarManager, RD_ThemePreset_COUNT, } RD_ThemePreset; -typedef struct RD_VocabularyInfo RD_VocabularyInfo; -struct RD_VocabularyInfo +typedef struct RD_VocabInfo RD_VocabInfo; +struct RD_VocabInfo { String8 code_name; String8 code_name_plural; @@ -520,8 +511,6 @@ String8 string; String8 description; String8 search_tags; String8 ctx_filter; -String8 display_name; -RD_IconKind icon_kind; RD_CmdKindFlags flags; RD_Query query; }; @@ -566,13 +555,9 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern String8 rd_cfg_src_string_table[4]; -extern RD_CmdKind rd_cfg_src_load_cmd_kind_table[4]; -extern RD_CmdKind rd_cfg_src_write_cmd_kind_table[4]; -extern RD_VocabularyInfo rd_vocabulary_info_table[66]; +extern RD_VocabInfo rd_vocab_info_table[277]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; -extern RD_StringBindingPair rd_default_binding_table[111]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a87d7e23..345d81dc 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -11,43 +11,10 @@ @embed_file rd_icon_file_bytes: "../data/logo.ico" //////////////////////////////// -//~ rjf: Config Sources +//~ rjf: Vocabulary Map -@table(string, name, load_cmd, write_cmd, apply_cmd) -RD_CfgSrcTable: -{ - {"user" User OpenUser WriteUserData ApplyUserData } - {"project" Project OpenProject WriteProjectData ApplyProjectData } - {"command_line" CommandLine Null Null Null } - {"transient" Transient Null Null Null } -} - -@enum RD_CfgSrc: -{ - @expand(RD_CfgSrcTable a) `$(a.name)`, - COUNT, -} - -@data(String8) rd_cfg_src_string_table: -{ - @expand(RD_CfgSrcTable a) `str8_lit_comp("$(a.string)")`, -} - -@data(RD_CmdKind) rd_cfg_src_load_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.load_cmd)`, -} - -@data(RD_CmdKind) rd_cfg_src_write_cmd_kind_table: -{ - @expand(RD_CfgSrcTable a) `RD_CmdKind_$(a.write_cmd)`, -} - -//////////////////////////////// -//~ rjf: Vocabulary Maps - -@table(code_name code_name_plural display_name display_name_plural icon_kind) -RD_VocabularyMap: +@table(code_name code_name_plural display_name display_name_plural icon_kind) +RD_VocabTable: // NOTE(rjf): the _ character is used as a fastpath for default rules. when // pluralizing, you just append an `s`, and so on. { @@ -119,7 +86,7 @@ RD_VocabularyMap: {id _ "ID" _ Null } } -@struct RD_VocabularyInfo: +@struct RD_VocabInfo: { `String8 code_name`; `String8 code_name_plural`; @@ -128,9 +95,11 @@ RD_VocabularyMap: `RD_IconKind icon_kind`; } -@data(RD_VocabularyInfo) rd_vocabulary_info_table: +@data(RD_VocabInfo) rd_vocab_info_table: { - @expand(RD_VocabularyMap a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; + @expand(RD_VocabTable a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; + @expand(D_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; + @expand(RD_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; } //////////////////////////////// @@ -635,8 +604,6 @@ RD_CmdTable: // | | | | `String8 description`; `String8 search_tags`; `String8 ctx_filter`; - `String8 display_name`; - `RD_IconKind icon_kind`; `RD_CmdKindFlags flags`; `RD_Query query`; }; @@ -645,9 +612,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), str8_lit_comp("$(a.display_name)"), RD_IconKind_$(a.canonical_icon), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -819,7 +786,7 @@ RD_DefaultBindingTable: { "toggle_dev_menu" D ctrl shift alt } } -@data(RD_StringBindingPair) rd_default_binding_table: +@data(`struct {String8 string; RD_Binding binding;}`) @c_file rd_default_binding_table: { @expand(RD_DefaultBindingTable a) ```{str8_lit_comp("$(a.name)"), {OS_Key_$(a.key), 0 $(a.ctrl != 0 -> `|OS_Modifier_Ctrl`) $(a.shift != 0 -> `|OS_Modifier_Shift`) $(a.alt != 0 -> `|OS_Modifier_Alt`)}}```; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ebe426b0..0eac4e3e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1134,10 +1134,10 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) return target; } -internal DR_FancyStringList +internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size) { - DR_FancyStringList result = {0}; + DR_FStrList result = {0}; { Temp scratch = scratch_begin(&arena, 1); @@ -1214,25 +1214,22 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 // more faded/smaller, but only after a primary title is pushed, // which could be caused by many different potential parts of a cfg. // - Vec4F32 secondary_rgba = secondary_color; - F32 secondary_size = size*0.8f; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, size}; B32 running_is_secondary = 0; - Vec4F32 running_rgba = rgba; - F32 running_size = size; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; running_rgba = secondary_rgba; running_size = secondary_size;} +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.8f;} //- rjf: push icon if(icon_kind != RD_IconKind_Null) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push warning icon for command-line entities if(is_from_command_line) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), rd_icon_kind_text_table[RD_IconKind_Info]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push view title, if from window, and no file path @@ -1241,8 +1238,8 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 view_display_name = rd_display_from_code_name(cfg->string); if(view_display_name.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, view_display_name); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, view_display_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } } @@ -1250,28 +1247,28 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 //- rjf: push label if(label_string.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, label_string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } //- rjf: push expression if(collection_name.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, collection_name); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, collection_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } else if(file_path.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, str8_skip_last_slash(file_path)); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(file_path)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), running_size, running_rgba, expr_string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, expr_string); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } @@ -1279,23 +1276,23 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(loc.file_path.size != 0) { String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", loc.file_path, loc.pt.line, loc.pt.column); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, location_string); + dr_fstrs_push_new(arena, &result, ¶ms, location_string); start_secondary(); } //- rjf: push target executable name if(target.exe.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), running_size, running_rgba, target.exe); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(target.exe)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } //- rjf: push target arguments if(target.args.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, target.args); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, target.args); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push conditions @@ -1303,16 +1300,17 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; if(condition.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, condition); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); + dr_fstrs_concat_in_place(&result, &fstrs); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } } //- rjf: push disabled marker if(is_disabled) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, str8_lit("(Disabled)")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Disabled)")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push hit count @@ -1322,7 +1320,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count)) { String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), secondary_size, secondary_rgba, hit_count_text); + dr_fstrs_push_new(arena, &result, ¶ms, hit_count_text); } } @@ -1333,33 +1331,33 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; Vec4F32 src_color = rgba; Vec4F32 dst_color = rgba; - DR_FancyStringList src_fstrs = {0}; - DR_FancyStringList dst_fstrs = {0}; + DR_FStrList src_fstrs = {0}; + DR_FStrList dst_fstrs = {0}; if(src_string.size == 0) { src_string = str8_lit("(type)"); src_color = secondary_color; - dr_fancy_string_list_push_new(arena, &src_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); + dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); } else RD_Font(RD_FontSlot_Code) { - src_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, src_color, src_string); + src_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, src_color, src_string); } if(dst_string.size == 0) { dst_string = str8_lit("(view rule)"); dst_color = secondary_color; - dr_fancy_string_list_push_new(arena, &dst_fstrs, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); + dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); } else RD_Font(RD_FontSlot_Code) { - dst_fstrs = rd_fancy_string_list_from_code_string(arena, 1.f, 0, dst_color, dst_string); + dst_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, dst_color, dst_string); } - dr_fancy_string_list_concat_in_place(&result, &src_fstrs); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&result, &dst_fstrs); + dr_fstrs_concat_in_place(&result, &src_fstrs); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&result, &dst_fstrs); } //- rjf: special case: file path maps @@ -1379,11 +1377,11 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 dst_string = str8_lit("(destination path)"); dst_color = secondary_color; } - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, src_color, src_string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[RD_IconKind_RightArrow]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, v4f32(0, 0, 0, 0), str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, dst_color, dst_string); + dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); } #undef start_secondary @@ -1678,10 +1676,10 @@ rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) return string; } -internal DR_FancyStringList +internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras) { - DR_FancyStringList result = {0}; + DR_FStrList result = {0}; //- rjf: unpack entity info F32 extras_size = size*0.95f; @@ -1698,11 +1696,14 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon case CTRL_EntityKind_Module: {icon_kind = RD_IconKind_Module;}break; } + //- rjf: set up drawing params + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), rd_rgba_from_theme_color(RD_ThemeColor_Text), size}; + //- rjf: push icon if(icon_kind != RD_IconKind_Null) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push containing process prefix @@ -1717,19 +1718,22 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon Vec4F32 process_color = rd_rgba_from_ctrl_entity(process); if(process_name.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size, process_color, process_name); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" / ")); + dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); } } } //- rjf: push name - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), size, color, name); + dr_fstrs_push_new(arena, &result, ¶ms, name, + .font = rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .raster_flags = rd_raster_flags_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .color = color); //- rjf: threads get callstack extras if(entity->kind == CTRL_EntityKind_Thread && include_extras) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; @@ -1750,13 +1754,13 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon name = push_str8_copy(arena, name); if(name.size != 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); + dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol)); if(idx+1 < unwind.frames.count) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, secondary_color, str8_lit(" > ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); if(idx+1 == limit) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), extras_size, secondary_color, str8_lit("...")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("..."), .color = secondary_color, .size = extras_size); } } } @@ -1773,8 +1777,8 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); if(rdi->raw_data_size == 0) { - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), extras_size, secondary_color, str8_lit("(Symbols not found)")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Symbols not found)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color); } di_scope_close(di_scope); } @@ -2675,148 +2679,6 @@ rd_view_state_from_cfg(RD_Cfg *cfg) return view_state; } -internal DR_FancyStringList -rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size) -{ - DR_FancyStringList result = {0}; - Temp scratch = scratch_begin(&arena, 1); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, query); - - //- rjf: query is file path - do specific file name strings - if(file_path.size != 0) - { - // rjf: compute disambiguated file name - String8List qualifiers = {0}; - String8 file_name = str8_skip_last_slash(file_path); - if(rd_state->ambiguous_path_slots_count != 0) - { - U64 hash = d_hash_from_string__case_insensitive(file_name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - { - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) - { - if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) - { - node = n; - break; - } - } - } - if(node != 0 && node->paths.node_count > 1) - { - // rjf: get all colliding paths - String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); - - // rjf: get all reversed path parts for each collision - String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); - for EachIndex(idx, collisions.count) - { - String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); - } - } - - // rjf: get the search path & its reversed parts - String8List parts = str8_split_path(scratch.arena, file_path); - String8List parts_reversed = {0}; - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &parts_reversed, n->string); - } - - // rjf: iterate all collision part reversed lists, in lock-step with - // search path; disqualify until we only have one path remaining; gather - // qualifiers - { - U64 num_collisions_left = collisions.count; - String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); - for EachIndex(idx, collisions.count) - { - collision_nodes[idx] = collision_parts_reversed[idx].first; - } - for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) - { - B32 part_is_qualifier = 0; - for EachIndex(idx, collisions.count) - { - if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) - { - collision_nodes[idx] = 0; - num_collisions_left -= 1; - part_is_qualifier = 1; - } - else if(collision_nodes[idx] != 0) - { - collision_nodes[idx] = collision_nodes[idx]->next; - } - } - if(part_is_qualifier) - { - str8_list_push_front(scratch.arena, &qualifiers, n->string); - } - } - } - } - } - - // rjf: push qualifiers - for(String8Node *n = qualifiers.first; n != 0; n = n->next) - { - String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Main), size*0.95f, secondary_color, string); - } - - // rjf: push file name - DR_FancyString fstr = - { - rd_font_from_slot(RD_FontSlot_Main), - push_str8_copy(arena, file_name), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr); - } - - //- rjf: query is not file path - do general case, for view rule & expression - else - { - DR_FancyString fstr1 = - { - rd_font_from_slot(RD_FontSlot_Main), - viewer_name_string, - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr1); - if(query.size != 0) - { - DR_FancyString fstr2 = - { - rd_font_from_slot(RD_FontSlot_Code), - str8_lit(" "), - primary_color, - size, - }; - dr_fancy_string_list_push(arena, &result, &fstr2); - DR_FancyString fstr3 = - { - rd_font_from_slot(RD_FontSlot_Code), - push_str8_copy(arena, query), - secondary_color, - size*0.8f, - }; - dr_fancy_string_list_push(arena, &result, &fstr3); - } - } - scratch_end(scratch); - return result; -} - internal void rd_view_ui(Rng2F32 rect) { @@ -2834,14 +2696,13 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) { RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); //- rjf: icon & info - UI_Padding(ui_em(2.f, 1.f)) + UI_Padding(ui_em(2.f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) { //- rjf: icon { @@ -2912,7 +2773,7 @@ rd_view_ui(Rng2F32 rect) rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); } ui_spacer(ui_em(1.5f, 1)); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Step Into %S", target_name))) + if(ui_clicked(rd_icon_buttonf(RD_IconKind_StepInto, 0, "Step Into %S", target_name))) { rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); } @@ -2930,7 +2791,8 @@ rd_view_ui(Rng2F32 rect) //- rjf: or text if(helper_built) { - UI_PrefHeight(ui_em(2.25f, 1.f)) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) @@ -2939,7 +2801,8 @@ rd_view_ui(Rng2F32 rect) } //- rjf: helper text for command lister activation - UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_Padding(ui_pct(1, 0)) @@ -3825,9 +3688,9 @@ rd_window_frame(void) if(ui_string_hover_active()) UI_Tooltip { Temp scratch = scratch_begin(0, 0); - DR_FancyStringList fstrs = ui_string_hover_fstrs(scratch.arena); + DR_FStrList fstrs = ui_string_hover_fstrs(scratch.arena); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); scratch_end(scratch); } @@ -3853,13 +3716,13 @@ rd_window_frame(void) { // rjf: unpack RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); - DR_FancyStringList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) { UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); } }break; @@ -3878,15 +3741,15 @@ rd_window_frame(void) DI_Scope *di_scope = di_scope_open(); Arch arch = ctrl_entity->arch; String8 arch_str = string_from_arch(arch); - DR_FancyStringList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, - rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), - ui_top_font_size(), 0); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, + rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), + ui_top_font_size(), 0); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) { UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); ui_spacer(ui_em(0.5f, 1.f)); UI_FontSize(ui_top_font_size() - 1.f) UI_CornerRadius(ui_top_font_size()*0.5f) @@ -4011,9 +3874,9 @@ rd_window_frame(void) { UI_Row UI_PrefWidth(ui_text_dim(10, 1)) { - DR_FancyStringList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view, ui_top_palette()->text_weak, ui_top_font_size()); UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); + ui_box_equip_display_fstrs(name_box, &fstrs); } ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); @@ -4848,7 +4711,7 @@ rd_window_frame(void) String8 expr = rd_view_expr_string(); RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(tab->string); RD_IconKind view_icon = view_rule_info->icon_kind; - DR_FancyStringList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr); // rjf: title @@ -4865,7 +4728,7 @@ rd_window_frame(void) UI_PrefWidth(ui_text_dim(10, 1)) { UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &fstrs); + ui_box_equip_display_fstrs(name_box, &fstrs); } } @@ -4874,7 +4737,7 @@ rd_window_frame(void) // rjf: copy name if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) { - os_set_clipboard_text(dr_string_from_fancy_string_list(scratch.arena, &fstrs)); + os_set_clipboard_text(dr_string_from_fstrs(scratch.arena, &fstrs)); ui_ctx_menu_close(); } @@ -4983,9 +4846,9 @@ rd_window_frame(void) UI_TextAlignment(UI_TextAlign_Center) UI_TextPadding(ui_top_font_size()*1.5f) { - DR_FancyStringList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 0); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 0); UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); + ui_box_equip_display_fstrs(title_box, &fstrs); if(ctrl_entity->kind == CTRL_EntityKind_Thread) { ui_spacer(ui_em(0.5f, 1.f)); @@ -5821,9 +5684,9 @@ rd_window_frame(void) for(RD_CfgNode *n = targets.first; n != 0; n = n->next) { RD_Cfg *target = n->v; - DR_FancyStringList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target, ui_top_palette()->text_weak, ui_top_font_size()); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &title_fstrs); + ui_box_equip_display_fstrs(box, &title_fstrs); } } } @@ -6358,9 +6221,9 @@ rd_window_frame(void) else { Temp scratch = scratch_begin(0, 0); - DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &explanation_fstrs); + ui_box_equip_display_fstrs(box, &explanation_fstrs); scratch_end(scratch); } } @@ -6371,12 +6234,13 @@ rd_window_frame(void) if(rd_state->bind_change_active) { RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); + String8 display_name = rd_display_from_code_name(info->string); UI_PrefWidth(ui_text_dim(10, 1)) UI_Flags(UI_BoxFlag_DrawBackground) UI_TextAlignment(UI_TextAlign_Center) UI_CornerRadius(4) RD_Palette(RD_PaletteCode_NeutralPopButton) - ui_labelf("Currently rebinding \"%S\" hotkey", info->display_name); + ui_labelf("Currently rebinding \"%S\" hotkey", display_name); } // rjf: error visualization @@ -7281,7 +7145,7 @@ rd_window_frame(void) { // rjf: gather info for this tab B32 view_is_selected = (tab == panel->selected_tab); - DR_FancyStringList title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); // rjf: begin vertical region for this tab ui_set_next_child_layout_axis(Axis2_Y); @@ -7315,7 +7179,7 @@ rd_window_frame(void) UI_PrefWidth(ui_text_dim(10, 0)) { UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(name_box, &title_fstrs); + ui_box_equip_display_fstrs(name_box, &title_fstrs); } } UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) @@ -7795,6 +7659,23 @@ rd_window_frame(void) // rjf: draw background if(box->flags & UI_BoxFlag_DrawBackground) { + F32 effective_active_t = box->active_t; + if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) + { + effective_active_t = 0; + } + F32 t = box->hot_t*(1-effective_active_t); + + // rjf: hot effect extension (drop shadow) + if(box->flags & UI_BoxFlag_DrawHotEffects) + { + Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); + Vec4F32 drop_shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); + drop_shadow_color.w *= t; + drop_shadow_color.w *= box->palette->colors[UI_ColorCode_Background].w; + dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + } + // rjf: main rectangle { R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); @@ -7804,24 +7685,13 @@ rd_window_frame(void) // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { - F32 effective_active_t = box->active_t; - if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) - { - effective_active_t = 0; - } - F32 t = box->hot_t*(1-effective_active_t); - // rjf: brighten { R_Rect2DInst *inst = dr_rect(box->rect, v4f32(0, 0, 0, 0), 0, 0, 1.f); Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); color.w *= t*0.2f; inst->colors[Corner_00] = color; - inst->colors[Corner_01] = color; inst->colors[Corner_10] = color; - inst->colors[Corner_11] = color; - inst->colors[Corner_10].w *= t; - inst->colors[Corner_11].w *= t; MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -7844,10 +7714,7 @@ rd_window_frame(void) // rjf: active effect extension if(box->flags & UI_BoxFlag_DrawActiveEffects) { - Vec4F32 shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - shadow_color.x *= 0.3f; - shadow_color.y *= 0.3f; - shadow_color.z *= 0.3f; + Vec4F32 shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); shadow_color.w *= 0.5f*box->active_t; Vec2F32 shadow_size = { @@ -7906,8 +7773,17 @@ rd_window_frame(void) FNT_Run ellipses_run = {0}; if(!(box->flags & UI_BoxFlag_DisableTextTrunc)) { + FNT_Tag ellipses_font = box->font; + F32 ellipses_size = box->font_size; + FNT_RasterFlags ellipses_raster_flags = box->text_raster_flags; + if(box->display_fstrs.last) + { + ellipses_font = box->display_fstrs.last->v.params.font; + ellipses_size = box->display_fstrs.last->v.params.size; + ellipses_raster_flags = box->display_fstrs.last->v.params.raster_flags; + } max_x = (box->rect.x1-text_position.x); - ellipses_run = fnt_push_run_from_string(scratch.arena, box->font, box->font_size, 0, box->tab_size, 0, str8_lit("...")); + ellipses_run = fnt_push_run_from_string(scratch.arena, ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); } dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) @@ -8019,6 +7895,8 @@ rd_window_frame(void) Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); color.w *= b->hot_t; R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); + inst->colors[Corner_01].w *= 0.2f; + inst->colors[Corner_11].w *= 0.2f; MemoryCopyArray(inst->corner_radii, b->corner_radii); } } @@ -8134,39 +8012,6 @@ rd_window_frame(void) dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.05f), 0, 0, 0); } - //- rjf: scratch debug mouse drawing - if(DEV_scratch_mouse_draw) - { -#if 1 - Vec2F32 p = add_2f32(os_mouse_from_window(ws->os), v2f32(30, 0)); - dr_rect(os_client_rect_from_window(ws->os), v4f32(0, 0, 0, 0.9f), 0, 0, 0); - FNT_Run trailer_run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); - DR_FancyStringList strs = {0}; - DR_FancyString str = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("Shift + F5"), v4f32(1, 1, 1, 1), 72.f, 0.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str); - DR_FancyRunList runs = dr_fancy_run_list_from_fancy_string_list(scratch.arena, 0, FNT_RasterFlag_Smooth, &strs); - dr_truncated_fancy_run_list(p, &runs, 1000000.f, trailer_run); - dr_rect(r2f32(p, add_2f32(p, runs.dim)), v4f32(1, 0, 0, 0.5f), 0, 1, 0); - dr_rect(r2f32(sub_2f32(p, v2f32(4, 4)), add_2f32(p, v2f32(4, 4))), v4f32(1, 0, 1, 1), 0, 0, 0); -#else - Vec2F32 p = add_2f32(os_mouse_from_window(ws->os), v2f32(30, 0)); - dr_rect(os_client_rect_from_window(ws->os), v4f32(0, 0, 0, 0.4f), 0, 0, 0); - DR_FancyStringList strs = {0}; - DR_FancyString str1 = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("T"), v4f32(1, 1, 1, 1), 16.f, 4.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str1); - DR_FancyString str2 = {rd_font_from_slot(RD_FontSlot_Main), str8_lit("his is a test of some "), v4f32(1, 0.5f, 0.5f, 1), 14.f, 0.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str2); - DR_FancyString str3 = {rd_font_from_slot(RD_FontSlot_Code), str8_lit("very fancy text!"), v4f32(1, 0.8f, 0.4f, 1), 18.f, 4.f, 4.f}; - dr_fancy_string_list_push(scratch.arena, &strs, &str3); - DR_FancyRunList runs = dr_fancy_run_list_from_fancy_string_list(scratch.arena, 0, 0, &strs); - FNT_Run trailer_run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); - F32 limit = 500.f + sin_f32(rd_state->time_in_seconds/10.f)*200.f; - dr_truncated_fancy_run_list(p, &runs, limit, trailer_run); - dr_rect(r2f32p(p.x+limit, 0, p.x+limit+2.f, 1000), v4f32(1, 0, 0, 1), 0, 0, 0); - rd_request_frame(); -#endif - } - scratch_end(scratch); } @@ -9794,6 +9639,8 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St 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); +#if 0 // TODO(rjf): @cfg + ////////////////////////// //- rjf: determine all ctx filters // @@ -10317,7 +10164,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St MD_Node *schema = md_tree_from_string(scratch.arena, n->string)->first; for MD_EachNode(param, schema->first) { - RD_VocabularyInfo *param_vocab_info = rd_vocabulary_info_from_code_name(param->string); + RD_VocabInfo *param_vocab_info = rd_vocab_info_from_code_name(param->string); String8 name = param_vocab_info->display_name; RD_IconKind icon_kind = param_vocab_info->icon_kind; FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); @@ -10367,7 +10214,8 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St //- rjf: lister item list -> sorted array RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(arena, &item_list); rd_lister_item_array_sort__in_place(&item_array); - +#endif + RD_ListerItemArray item_array = {0}; di_scope_close(di_scope); scratch_end(scratch); return item_array; @@ -10878,552 +10726,6 @@ rd_raster_flags_from_slot(RD_FontSlot slot) return flags; } -//- rjf: config serialization - -internal int -rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingPair *b) -{ - return strncmp((char *)a->string.str, (char *)b->string.str, Min(a->string.size, b->string.size)); -} - -internal String8List -rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source) -{ - String8List strs = {0}; -#if 0 // TODO(rjf): @cfg - ProfBeginFunction(); - local_persist char *spaces = " "; - local_persist char *slashes= "////////////////////////////////////////////////////////////////////////////////"; - - //- rjf: write all entities - { - for EachEnumVal(RD_EntityKind, k) - { - RD_EntityKindFlags k_flags = rd_entity_kind_flags_table[k]; - if(!(k_flags & RD_EntityKindFlag_IsSerializedToConfig)) - { - continue; - } - B32 first = 1; - RD_EntityList entities = rd_query_cached_entity_list_with_kind(k); - for(RD_EntityNode *n = entities.first; n != 0; n = n->next) - { - RD_Entity *entity = n->entity; - if(entity->cfg_src != source) - { - continue; - } - if(first) - { - first = 0; - String8 title_name = d_entity_kind_name_lower_plural_table[k]; - str8_list_pushf(arena, &strs, "/// %S %.*s\n\n", - title_name, - (int)Max(0, 79 - (title_name.size + 5)), - slashes); - } - RD_EntityRec rec = {0}; - S64 depth = 0; - for(RD_Entity *e = entity; !rd_entity_is_nil(e); e = rec.next) - { - //- rjf: get next iteration - rec = rd_entity_rec_depth_first_pre(e, entity); - - //- rjf: unpack entity info - typedef U32 EntityInfoFlags; - enum - { - EntityInfoFlag_HasName = (1<<0), - EntityInfoFlag_HasDisabled = (1<<1), - EntityInfoFlag_HasTxtPt = (1<<2), - EntityInfoFlag_HasVAddr = (1<<3), - EntityInfoFlag_HasColor = (1<<4), - EntityInfoFlag_HasChildren = (1<<5), - EntityInfoFlag_HasDebugSubprocesses = (1<<6), - }; - String8 entity_name_escaped = e->string; - // TODO(rjf): @hack - hardcoding in the "EntityKind_Location" here - this is because - // i am assuming an entity *kind* can 'know' about the 'pathness' of a string. this is - // not the case. post-0.9.12 i need to fix this. - if(rd_entity_kind_flags_table[e->kind] & RD_EntityKindFlag_NameIsPath && - (e->kind != RD_EntityKind_Location || e->flags & RD_EntityFlag_HasTextPoint)) - { - Temp scratch = scratch_begin(&arena, 1); - String8 path_normalized = path_normalized_from_string(scratch.arena, e->string); - entity_name_escaped = path_relative_dst_from_absolute_dst_src(arena, path_normalized, root_path); - scratch_end(scratch); - } - else - { - entity_name_escaped = escaped_from_raw_str8(arena, e->string); - } - EntityInfoFlags info_flags = 0; - if(entity_name_escaped.size != 0) { info_flags |= EntityInfoFlag_HasName; } - if(!!e->disabled) { info_flags |= EntityInfoFlag_HasDisabled; } - if(e->flags & RD_EntityFlag_HasTextPoint) { info_flags |= EntityInfoFlag_HasTxtPt; } - if(e->flags & RD_EntityFlag_HasVAddr) { info_flags |= EntityInfoFlag_HasVAddr; } - if(e->flags & RD_EntityFlag_HasColor) { info_flags |= EntityInfoFlag_HasColor; } - if(!rd_entity_is_nil(e->first)) { info_flags |= EntityInfoFlag_HasChildren; } - if(e->debug_subprocesses) { info_flags |= EntityInfoFlag_HasDebugSubprocesses; } - - //- rjf: write entity info - B32 opened_brace = 0; - switch(info_flags) - { - //- rjf: default path -> entity has lots of stuff, so write all info generically - default: - { - opened_brace = 1; - - // rjf: write entity title - str8_list_pushf(arena, &strs, "%S:\n{\n", d_entity_kind_name_lower_table[e->kind]); - - // rjf: write this entity's info - if(entity_name_escaped.size != 0) - { - str8_list_pushf(arena, &strs, "name: \"%S\"\n", entity_name_escaped); - } - if(e->disabled) - { - str8_list_pushf(arena, &strs, "disabled: 1\n"); - } - if(e->debug_subprocesses) - { - str8_list_pushf(arena, &strs, "debug_subprocesses: 1\n"); - } - if(e->flags & RD_EntityFlag_HasColor) - { - Vec4F32 hsva = rd_hsva_from_entity(e); - Vec4F32 rgba = rgba_from_hsva(hsva); - U32 rgba_hex = u32_from_rgba(rgba); - str8_list_pushf(arena, &strs, "color: 0x%x\n", rgba_hex); - } - if(e->flags & RD_EntityFlag_HasTextPoint) - { - str8_list_pushf(arena, &strs, "line: %I64d\n", e->text_point.line); - } - if(e->flags & RD_EntityFlag_HasVAddr) - { - str8_list_pushf(arena, &strs, "vaddr: (0x%I64x)\n", e->vaddr); - } - }break; - - //- rjf: single-line fast-paths - case EntityInfoFlag_HasName: - {str8_list_pushf(arena, &strs, "%S: \"%S\"\n", d_entity_kind_name_lower_table[e->kind], entity_name_escaped);}break; - case EntityInfoFlag_HasName|EntityInfoFlag_HasTxtPt: - {str8_list_pushf(arena, &strs, "%S: (\"%S\":%I64d)\n", d_entity_kind_name_lower_table[e->kind], entity_name_escaped, e->text_point.line);}break; - case EntityInfoFlag_HasVAddr: - {str8_list_pushf(arena, &strs, "%S: (0x%I64x)\n", d_entity_kind_name_lower_table[e->kind], e->vaddr);}break; - - //- rjf: empty - case 0: - {}break; - } - - // rjf: push - depth += rec.push_count; - - // rjf: pop - if(rec.push_count == 0) - { - for(S64 pop_idx = 0; pop_idx < rec.pop_count + opened_brace; pop_idx += 1) - { - if(depth > 0) - { - depth -= 1; - } - str8_list_pushf(arena, &strs, "}\n"); - } - } - - // rjf: separate top-level entities with extra newline - if(rd_entity_is_nil(rec.next) && (rec.pop_count != 0 || n->next == 0)) - { - str8_list_pushf(arena, &strs, "\n"); - } - } - } - } - } - - //- rjf: write exception code filters - if(source == RD_CfgSrc_Project) - { - str8_list_push(arena, &strs, str8_lit("/// exception code filters ////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_push(arena, &strs, str8_lit("exception_code_filters:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - String8 name = ctrl_exception_code_kind_lowercase_code_string_table[k]; - B32 value = !!(rd_state->ctrl_exception_code_filters[k/64] & (1ull<<(k%64))); - str8_list_pushf(arena, &strs, " %S: %i\n", name, value); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - - //- rjf: serialize windows - if(source == RD_CfgSrc_User) - { - B32 first = 1; - for(RD_WindowState *window = rd_state->first_window_state; window != &rd_nil_window_state; window = window->order_next) - { - if(first) - { - first = 0; - str8_list_push(arena, &strs, str8_lit("/// windows ///////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - } - OS_Handle monitor = os_monitor_from_window(window->os); - String8 monitor_name = os_name_from_monitor(arena, monitor); - RD_Panel *root_panel = window->root_panel; - Rng2F32 rect = os_rect_from_window(window->os); - Vec2F32 size = dim_2f32(rect); - str8_list_push (arena, &strs, str8_lit("window:\n")); - str8_list_push (arena, &strs, str8_lit("{\n")); - str8_list_pushf(arena, &strs, " %s%s%s\n", - root_panel->split_axis == Axis2_X ? "split_x" : "split_y", - os_window_is_fullscreen(window->os) ? " fullscreen" : "", - os_window_is_maximized(window->os) ? " maximized" : ""); - str8_list_pushf(arena, &strs, " monitor: \"%S\"\n", monitor_name); - str8_list_pushf(arena, &strs, " size: (%i %i)\n", (int)size.x, (int)size.y); - str8_list_pushf(arena, &strs, " dpi: %f\n", os_dpi_from_window(window->os)); - for EachEnumVal(RD_SettingCode, code) - { - RD_SettingVal current = window->setting_vals[code]; - if(current.set) - { - str8_list_pushf(arena, &strs, " %S: %i\n", rd_setting_code_lower_string_table[code], current.s32); - } - } - { - RD_PanelRec rec = {0}; - S32 indentation = 2; - String8 indent_str = str8_lit(" "); - str8_list_pushf(arena, &strs, " panels:\n"); - str8_list_pushf(arena, &strs, " {\n"); - for(RD_Panel *p = root_panel; !rd_panel_is_nil(p); p = rec.next) - { - // rjf: get recursion - rec = rd_panel_rec_depth_first_pre(p); - - // rjf: non-root needs pct node - if(p != root_panel) - { - str8_list_pushf(arena, &strs, "%.*s%g:\n", indentation*2, indent_str.str, p->pct_of_parent); - str8_list_pushf(arena, &strs, "%.*s{\n", indentation*2, indent_str.str); - indentation += 1; - } - - // rjf: per-panel options - struct { String8 key; B32 value; } options[] = - { - {str8_lit_comp("tabs_on_bottom"), p->tab_side == Side_Max}, - }; - B32 has_options = 0; - for(U64 op_idx = 0; op_idx < ArrayCount(options); op_idx += 1) - { - if(options[op_idx].value) - { - if(has_options == 0) - { - str8_list_pushf(arena, &strs, "%.*s", indentation*2, indent_str.str); - } - else - { - str8_list_pushf(arena, &strs, " "); - } - has_options = 1; - str8_list_push(arena, &strs, options[op_idx].key); - } - } - if(has_options) - { - str8_list_pushf(arena, &strs, "\n"); - } - - // rjf: views - for(RD_View *view = p->first_tab_view; !rd_view_is_nil(view); view = view->order_next) - { - String8 view_string = view->spec->string; - - // rjf: serialize views - { - str8_list_pushf(arena, &strs, "%.*s", indentation*2, indent_str.str); - - // rjf: serialize view string - str8_list_push(arena, &strs, view_string); - - // rjf: serialize view parameterizations - str8_list_push(arena, &strs, str8_lit(": {")); - if(view == rd_selected_tab_from_panel(p)) - { - str8_list_push(arena, &strs, str8_lit("selected ")); - } - { - if(view->project_path.size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8 project_path_absolute = path_normalized_from_string(scratch.arena, view->project_path); - String8 project_path_relative = path_relative_dst_from_absolute_dst_src(scratch.arena, project_path_absolute, root_path); - str8_list_pushf(arena, &strs, "project:{\"%S\"} ", project_path_relative); - scratch_end(scratch); - } - } - if(view->query_string_size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8 query_raw = str8(view->query_buffer, view->query_string_size); - { - String8 query_file_path = rd_file_path_from_eval_string(scratch.arena, query_raw); - if(query_file_path.size != 0) - { - query_file_path = path_relative_dst_from_absolute_dst_src(scratch.arena, query_file_path, root_path); - query_raw = push_str8f(scratch.arena, "file:\"%S\"", query_file_path); - } - } - String8 query_sanitized = escaped_from_raw_str8(scratch.arena, query_raw); - str8_list_pushf(arena, &strs, "query:{\"%S\"} ", query_sanitized); - scratch_end(scratch); - } - { - String8 reserved_keys[] = - { - str8_lit("project"), - str8_lit("query"), - str8_lit("selected"), - }; - MD_NodeRec rec = {0}; - MD_Node *params_root = view->params_roots[view->params_read_gen%ArrayCount(view->params_roots)]; - for(MD_Node *n = params_root; - !md_node_is_nil(n); - n = rec.next) - { - rec = md_node_rec_depth_first_pre(n, params_root); - B32 is_reserved_key = 0; - for(U64 idx = 0; idx < ArrayCount(reserved_keys); idx += 1) - { - if(str8_match(n->string, reserved_keys[idx], 0)) - { - is_reserved_key = 1; - break; - } - } - if(is_reserved_key) - { - rec = md_node_rec_depth_first(n, params_root, OffsetOf(MD_Node, next), OffsetOf(MD_Node, next)); - } - if(!is_reserved_key && n != params_root) - { - str8_list_pushf(arena, &strs, "%S", n->string); - if(n->first != &md_nil_node) - { - str8_list_pushf(arena, &strs, ":{"); - } - for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) - { - if(pop_idx == rec.pop_count-1 && rec.next == &md_nil_node) - { - break; - } - str8_list_pushf(arena, &strs, "}"); - } - if(rec.pop_count != 0 || n->next != &md_nil_node) - { - str8_list_pushf(arena, &strs, " "); - } - } - } - } - str8_list_push(arena, &strs, str8_lit("}\n")); - } - } - - // rjf: non-roots need closer - if(p != root_panel && rec.push_count == 0) - { - indentation -= 1; - str8_list_pushf(arena, &strs, "%.*s}\n", indentation*2, indent_str.str); - } - - // rjf: pop - for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) - { - indentation -= 1; - if(pop_idx == rec.pop_count-1 && rec.next == &rd_nil_panel) - { - break; - } - str8_list_pushf(arena, &strs, "%.*s}\n", indentation*2, indent_str.str); - } - } - str8_list_pushf(arena, &strs, " }\n"); - } - str8_list_push (arena, &strs, str8_lit("}\n")); - str8_list_push (arena, &strs, str8_lit("\n")); - } - } - - //- rjf: serialize keybindings - if(source == RD_CfgSrc_User) - { - Temp scratch = scratch_begin(&arena, 1); - String8 indent_str = str8_lit(" "); - U64 string_binding_pair_count = 0; - RD_StringBindingPair *string_binding_pairs = push_array(scratch.arena, RD_StringBindingPair, rd_state->key_map_total_count); - for(U64 idx = 0; - idx < rd_state->key_map_table_size && string_binding_pair_count < rd_state->key_map_total_count; - idx += 1) - { - for(RD_KeyMapNode *n = rd_state->key_map_table[idx].first; - n != 0 && string_binding_pair_count < rd_state->key_map_total_count; - n = n->hash_next) - { - RD_StringBindingPair *pair = string_binding_pairs + string_binding_pair_count; - pair->string = n->name; - pair->binding = n->binding; - string_binding_pair_count += 1; - } - } - quick_sort(string_binding_pairs, string_binding_pair_count, sizeof(RD_StringBindingPair), rd_qsort_compare__cfg_string_bindings); - if(string_binding_pair_count != 0) - { - str8_list_push(arena, &strs, str8_lit("/// keybindings ///////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_push(arena, &strs, str8_lit("keybindings:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(U64 idx = 0; idx < string_binding_pair_count; idx += 1) - { - RD_StringBindingPair *pair = string_binding_pairs + idx; - String8List modifiers_strings = os_string_list_from_modifiers(scratch.arena, pair->binding.modifiers); - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - String8 event_flags_string = str8_list_join(scratch.arena, &modifiers_strings, &join); - String8 key_string = push_str8_copy(scratch.arena, os_g_key_cfg_string_table[pair->binding.key]); - for(U64 i = 0; i < event_flags_string.size; i += 1) - { - event_flags_string.str[i] = char_to_lower(event_flags_string.str[i]); - } - String8 binding_string = push_str8f(scratch.arena, "%S%s%S", - event_flags_string, - event_flags_string.size > 0 ? " " : "", - key_string); - str8_list_pushf(arena, &strs, " {\"%S\"%.*s%S%.*s}\n", - pair->string, - 40 > pair->string.size ? ((int)(40 - pair->string.size)) : 0, indent_str.str, - binding_string, - 20 > binding_string.size ? ((int)(20 - binding_string.size)) : 0, indent_str.str); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - scratch_end(scratch); - } - - //- rjf: serialize theme colors - if(source == RD_CfgSrc_User) - { - // rjf: determine if this theme matches an existing preset - B32 is_preset = 0; - RD_ThemePreset matching_preset = RD_ThemePreset_DefaultDark; - { - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - B32 matches_this_preset = 1; - for(RD_ThemeColor c = (RD_ThemeColor)(RD_ThemeColor_Null+1); c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(!MemoryMatchStruct(&rd_state->cfg_theme_target.colors[c], &rd_theme_preset_colors_table[p][c])) - { - matches_this_preset = 0; - break; - } - } - if(matches_this_preset) - { - is_preset = 1; - matching_preset = p; - break; - } - } - } - - // rjf: serialize header - String8 indent_str = str8_lit(" "); - str8_list_push(arena, &strs, str8_lit("/// colors ////////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - - // rjf: serialize preset theme - if(is_preset) - { - str8_list_pushf(arena, &strs, "color_preset: \"%S\"\n\n", rd_theme_preset_code_string_table[matching_preset]); - } - - // rjf: serialize non-preset theme - if(!is_preset) - { - str8_list_push(arena, &strs, str8_lit("colors:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - String8 color_name = rd_theme_color_cfg_string_table[color]; - Vec4F32 color_rgba = rd_state->cfg_theme_target.colors[color]; - String8 color_hex = hex_string_from_rgba_4f32(arena, color_rgba); - str8_list_pushf(arena, &strs, " %S:%.*s0x%S\n", - color_name, - 30 > color_name.size ? ((int)(30 - color_name.size)) : 0, indent_str.str, - color_hex); - } - str8_list_push(arena, &strs, str8_lit("}\n\n")); - } - } - - //- rjf: serialize fonts - if(source == RD_CfgSrc_User) - { - String8 code_font_path_escaped = escaped_from_raw_str8(arena, rd_state->cfg_code_font_path); - String8 main_font_path_escaped = escaped_from_raw_str8(arena, rd_state->cfg_main_font_path); - str8_list_push(arena, &strs, str8_lit("/// fonts /////////////////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_pushf(arena, &strs, "code_font: \"%S\"\n", code_font_path_escaped); - str8_list_pushf(arena, &strs, "main_font: \"%S\"\n", main_font_path_escaped); - str8_list_push(arena, &strs, str8_lit("\n")); - } - - //- rjf: serialize global settings - { - B32 first = 1; - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - RD_SettingVal current = rd_state->cfg_setting_vals[source][code]; - if(current.set) - { - if(first) - { - first = 0; - str8_list_push(arena, &strs, str8_lit("/// global settings ///////////////////////////////////////////////////////////\n")); - str8_list_push(arena, &strs, str8_lit("\n")); - } - str8_list_pushf(arena, &strs, "%S: %i\n", rd_setting_code_lower_string_table[code], current.s32); - } - } - if(!first) - { - str8_list_push(arena, &strs, str8_lit("\n")); - } - } - - ProfEnd(); -#endif - return strs; -} - //////////////////////////////// //~ rjf: Process Control Info Stringification @@ -11442,12 +10744,13 @@ rd_string_from_exception_code(U32 code) return string; } -internal DR_FancyStringList +internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); - DR_FancyStringList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, ui_top_palette()->text, ui_top_font_size(), 0); - DR_FancyStringList fstrs = {0}; + DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, ui_top_palette()->text, ui_top_font_size(), 0); + DR_FStrList fstrs = {0}; + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_top_palette()->text, ui_top_font_size()}; switch(event->cause) { default:{}break; @@ -11457,12 +10760,12 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" completed step")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" completed step")); } else { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Stopped")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Stopped")); } }break; @@ -11471,12 +10774,12 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" stopped at entry point")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" stopped at entry point")); } else { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Stopped at entry point")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Stopped at entry point")); } }break; @@ -11485,10 +10788,10 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_CircleFilled]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a breakpoint")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_CircleFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a breakpoint")); } }break; @@ -11497,14 +10800,14 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { if(thread != &ctrl_entity_nil) { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); switch(event->exception_kind) { default: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -11512,49 +10815,49 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) exception_explanation_string.size != 0 ? " (" : "", exception_explanation_string, exception_explanation_string.size != 0 ? ")" : ""); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_CppThrow: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a C++ exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a C++ exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_code_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_code_string); }break; case CTRL_ExceptionKind_MemoryRead: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_info_string = push_str8f(arena, "%S (Access violation reading 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryWrite: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_info_string = push_str8f(arena, "%S (Access violation writing 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryExecute: { - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_info_string = push_str8f(arena, "%S (Access violation executing 0x%I64x)", exception_code_string, event->vaddr_rng.min); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; } } else { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Hit an exception - ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -11562,60 +10865,117 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) exception_explanation_string.size != 0 ? " (" : "", exception_explanation_string, exception_explanation_string.size != 0 ? ")" : ""); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, exception_info_string); + dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); } }break; //- rjf: trap case CTRL_EventCause_InterruptedByTrap: { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_WarningBig]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" ")); - dr_fancy_string_list_concat_in_place(&fstrs, &thread_fstrs); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit(" hit a trap")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a trap")); }break; //- rjf: halt case CTRL_EventCause_InterruptedByHalt: { - dr_fancy_string_list_push_new(arena, &fstrs, rd_font_from_slot(RD_FontSlot_Icons), ui_top_font_size(), ui_top_palette()->text, rd_icon_kind_text_table[RD_IconKind_Pause]); - dr_fancy_string_list_push_new(arena, &fstrs, ui_top_font(), ui_top_font_size(), ui_top_palette()->text, str8_lit("Halted")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_Pause], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Halted")); }break; } return fstrs; } //////////////////////////////// -//~ rjf: Vocabulary Info Lookups +//~ rjf: Vocab Info Lookups -internal RD_VocabularyInfo * -rd_vocabulary_info_from_code_name(String8 code_name) +internal RD_VocabInfo * +rd_vocab_info_from_code_name(String8 code_name) { - RD_VocabularyInfo *info = &rd_nil_vocabulary_info; - for EachElement(idx, rd_vocabulary_info_table) + RD_VocabInfo *result = &rd_nil_vocab_info; + if(code_name.size != 0) { - if(str8_match(rd_vocabulary_info_table[idx].code_name, code_name, 0)) + U64 hash = d_hash_from_string(code_name); + U64 slot_idx = hash%rd_state->vocab_info_map.single_slots_count; + for(RD_VocabInfoMapNode *n = rd_state->vocab_info_map.single_slots[slot_idx].first; + n != 0; + n = n->single_next) { - info = &rd_vocabulary_info_table[idx]; - break; + if(str8_match(n->v.code_name, code_name, 0)) + { + result = &n->v; + break; + } } } - return info; + return result; } -internal RD_VocabularyInfo * -rd_vocabulary_info_from_code_name_plural(String8 code_name_plural) +internal RD_VocabInfo * +rd_vocab_info_from_code_name_plural(String8 code_name_plural) { - RD_VocabularyInfo *info = &rd_nil_vocabulary_info; - for EachElement(idx, rd_vocabulary_info_table) + RD_VocabInfo *result = &rd_nil_vocab_info; + if(code_name_plural.size != 0) { - if(str8_match(rd_vocabulary_info_table[idx].code_name_plural, code_name_plural, 0)) + U64 hash = d_hash_from_string(code_name_plural); + U64 slot_idx = hash%rd_state->vocab_info_map.plural_slots_count; + for(RD_VocabInfoMapNode *n = rd_state->vocab_info_map.plural_slots[slot_idx].first; + n != 0; + n = n->plural_next) { - info = &rd_vocabulary_info_table[idx]; - break; + if(str8_match(n->v.code_name_plural, code_name_plural, 0)) + { + result = &n->v; + break; + } } } - return info; + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary_color, F32 size) +{ + DR_FStrList result = {0}; + { + RD_VocabInfo *info = rd_vocab_info_from_code_name(code_name); + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rd_rgba_from_theme_color(RD_ThemeColor_Text), size}; + B32 running_is_secondary = 0; +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.8f;} + + //- rjf: push icon + if(info->icon_kind != RD_IconKind_Null) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push display name + if(info->display_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, info->display_name); + } + + //- rjf: push code name as a fallback + else + { + dr_fstrs_push_new(arena, &result, ¶ms, code_name, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + } + +#undef start_secondary + } + return result; } //////////////////////////////// @@ -11902,6 +11262,31 @@ rd_init(CmdLine *cmdln) } } + // rjf: set up vocab info map + { + rd_state->vocab_info_map.single_slots_count = 1024; + rd_state->vocab_info_map.single_slots = push_array(rd_state->arena, RD_VocabInfoMapSlot, rd_state->vocab_info_map.single_slots_count); + rd_state->vocab_info_map.plural_slots_count = 1024; + rd_state->vocab_info_map.plural_slots = push_array(rd_state->arena, RD_VocabInfoMapSlot, rd_state->vocab_info_map.plural_slots_count); + for EachElement(idx, rd_vocab_info_table) + { + RD_VocabInfoMapNode *n = push_array(rd_state->arena, RD_VocabInfoMapNode, 1); + MemoryCopyStruct(&n->v, &rd_vocab_info_table[idx]); + U64 single_hash = d_hash_from_string(n->v.code_name); + U64 plural_hash = d_hash_from_string(n->v.code_name_plural); + U64 single_slot_idx = single_hash%rd_state->vocab_info_map.single_slots_count; + U64 plural_slot_idx = plural_hash%rd_state->vocab_info_map.plural_slots_count; + if(n->v.code_name.size != 0) + { + SLLQueuePush_N(rd_state->vocab_info_map.single_slots[single_slot_idx].first, rd_state->vocab_info_map.single_slots[single_slot_idx].last, n, single_next); + } + if(n->v.code_name_plural.size != 0) + { + SLLQueuePush_N(rd_state->vocab_info_map.plural_slots[plural_slot_idx].first, rd_state->vocab_info_map.plural_slots[plural_slot_idx].last, n, plural_next); + } + } + } + // rjf: set up top-level config entity trees & tables { rd_state->cfg_id_slots_count = 1024; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ed63c9be..7e834b1b 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -34,13 +34,6 @@ struct RD_Binding OS_Modifiers modifiers; }; -typedef struct RD_StringBindingPair RD_StringBindingPair; -struct RD_StringBindingPair -{ - String8 string; - RD_Binding binding; -}; - typedef struct RD_KeyMapNode RD_KeyMapNode; struct RD_KeyMapNode { @@ -274,6 +267,33 @@ enum #include "generated/raddbg.meta.h" +//////////////////////////////// +//~ rjf: Vocabulary Map + +typedef struct RD_VocabInfoMapNode RD_VocabInfoMapNode; +struct RD_VocabInfoMapNode +{ + RD_VocabInfoMapNode *single_next; + RD_VocabInfoMapNode *plural_next; + RD_VocabInfo v; +}; + +typedef struct RD_VocabInfoMapSlot RD_VocabInfoMapSlot; +struct RD_VocabInfoMapSlot +{ + RD_VocabInfoMapNode *first; + RD_VocabInfoMapNode *last; +}; + +typedef struct RD_VocabInfoMap RD_VocabInfoMap; +struct RD_VocabInfoMap +{ + U64 single_slots_count; + RD_VocabInfoMapSlot *single_slots; + U64 plural_slots_count; + RD_VocabInfoMapSlot *plural_slots; +}; + //////////////////////////////// //~ rjf: Config Tree @@ -702,6 +722,9 @@ struct RD_State // rjf: schema table MD_Node **schemas; + // rjf: vocab table + RD_VocabInfoMap vocab_info_map; + // rjf: log Log *log; String8 log_path; @@ -832,7 +855,7 @@ struct RD_State //////////////////////////////// //~ rjf: Globals -read_only global RD_VocabularyInfo rd_nil_vocabulary_info = {0}; +read_only global RD_VocabInfo rd_nil_vocab_info = {0}; read_only global RD_Cfg rd_nil_cfg = { @@ -990,7 +1013,7 @@ internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); -internal DR_FancyStringList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); +internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); @@ -1011,7 +1034,7 @@ internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); internal Vec4F32 rd_rgba_from_ctrl_entity(CTRL_Entity *entity); internal String8 rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); -internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras); +internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras); //////////////////////////////// //~ rjf: Evaluation Spaces @@ -1067,7 +1090,6 @@ internal String8 rd_query_from_eval_string(Arena *arena, String8 string); //~ rjf: View Functions internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); -internal DR_FancyStringList rd_title_fstrs_from_view(Arena *arena, String8 viewer_name_string, String8 query, Vec4F32 primary_color, Vec4F32 secondary_color, F32 size); internal void rd_view_ui(Rng2F32 rect); //////////////////////////////// @@ -1167,26 +1189,23 @@ internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); internal F32 rd_font_size_from_slot(RD_FontSlot slot); internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); -//- rjf: config serialization -internal int rd_qsort_compare__cfg_string_bindings(RD_StringBindingPair *a, RD_StringBindingPair *b); -internal String8List rd_cfg_strings_from_gfx(Arena *arena, String8 root_path, RD_CfgSrc source); - //////////////////////////////// //~ rjf: Process Control Info Stringification internal String8 rd_string_from_exception_code(U32 code); -internal DR_FancyStringList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event); +internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event); //////////////////////////////// -//~ rjf: Vocabulary Info Lookups +//~ rjf: Vocab Info Lookups -internal RD_VocabularyInfo *rd_vocabulary_info_from_code_name(String8 code_name); -internal RD_VocabularyInfo *rd_vocabulary_info_from_code_name_plural(String8 code_name_plural); -#define rd_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->code_name_plural) -#define rd_display_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name) -#define rd_display_plural_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->display_name_plural) -#define rd_icon_kind_from_code_name(code_name) (rd_vocabulary_info_from_code_name(code_name)->icon_kind) -#define rd_singular_from_code_name_plural(code_name_plural) (rd_vocabulary_info_from_code_name_plural(code_name_plural)->code_name) +internal RD_VocabInfo *rd_vocab_info_from_code_name(String8 code_name); +internal RD_VocabInfo *rd_vocab_info_from_code_name_plural(String8 code_name_plural); +#define rd_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->code_name_plural) +#define rd_display_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name) +#define rd_display_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name_plural) +#define rd_icon_kind_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->icon_kind) +#define rd_singular_from_code_name_plural(code_name_plural) (rd_vocab_info_from_code_name_plural(code_name_plural)->code_name) +internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary_color, F32 size); //////////////////////////////// //~ rjf: Continuous Frame Requests diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b37ea013..d67a669a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -983,13 +983,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular button for top-level cfg group elements else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fancy_strings = rd_title_fstrs_from_cfg(arena, info.group_cfg_child, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, info.group_cfg_child, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular button for top-level cfg roots else if(row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fancy_strings = rd_title_fstrs_from_cfg(arena, evalled_cfg, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, evalled_cfg, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular button for entities @@ -1001,7 +1001,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular button for commands else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f); + RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; + RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular cell for view ui @@ -1168,7 +1170,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla RD_WatchRowCellInfo result = {0}; result.view_ui_rule = &rd_nil_view_ui_rule; result.view_ui_tag = &e_expr_nil; - result.fancy_strings = cell->fancy_strings; + result.fstrs = cell->fstrs; switch(cell->kind) { default:{}break; @@ -2787,9 +2789,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_LineEditFlag_NoBackground*!(cell_info.is_button)| RD_LineEditFlag_Button*!!(cell_info.is_button)| RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(cell_x == 0 && row_is_expandable && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(cell_x == 0 && row_depth==0 && cell == row_info.cells.first && !cell_info.is_button)| - RD_LineEditFlag_ExpanderSpace*(cell_x == 0 && row_depth!=0 && cell == row_info.cells.first)); + RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info.cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info.cells.first && !cell_info.is_button)| + RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info.cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; line_edit_params.mark = &cell_edit_state->mark; @@ -2798,7 +2800,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.edit_string_size_out = &cell_edit_state->input_size; line_edit_params.expanded_out = &next_row_expanded; line_edit_params.pre_edit_value = cell_info.string; - line_edit_params.fancy_strings = cell_info.fancy_strings; + line_edit_params.fstrs = cell_info.fstrs; } sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); #if 0 // TODO(rjf): @cfg @@ -3337,7 +3339,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) { //- rjf: unpack entity info - DR_FancyStringList fstrs = {0}; + DR_FStrList fstrs = {0}; if(!rd_entity_is_nil(entity)) { fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); @@ -3346,7 +3348,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); } - String8 fstrs_string = dr_string_from_fancy_string_list(scratch.arena, &fstrs); + String8 fstrs_string = dr_string_from_fstrs(scratch.arena, &fstrs); FuzzyMatchRangeList fstrs_matches = fuzzy_match_find(scratch.arena, filter, fstrs_string); UI_Key hover_t_key = ui_key_from_stringf(ui_key_zero(), "entity_hover_t_%p_%p", entity, ctrl_entity); F32 hover_t = ui_anim(hover_t_key, (F32)!!is_hovering, .rate = entity_hover_t_rate); @@ -3396,7 +3398,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) next_row_expanded = !row_expanded; } UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); - ui_box_equip_display_fancy_strings(title_box, &fstrs); + ui_box_equip_display_fstrs(title_box, &fstrs); ui_box_equip_fuzzy_match_ranges(title_box, &fstrs_matches); UI_Signal sig = ui_signal_from_box(entity_box); if(ui_hovering(sig)) @@ -4670,6 +4672,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) //- rjf: unpack visual params // FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); + FNT_RasterFlags font_raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); F32 font_size = rd_font_size_from_slot(RD_FontSlot_Code); F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; F32 row_height_px = floor_f32(font_size*2.f); @@ -4830,11 +4833,11 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: produce fancy string runs for all possible byte values in all cells // - DR_FancyStringList byte_fancy_strings[256] = {0}; + DR_FStrList byte_fstrs[256] = {0}; { Vec4F32 full_color = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive); Vec4F32 zero_color = rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); - for(U64 idx = 0; idx < ArrayCount(byte_fancy_strings); idx += 1) + for(U64 idx = 0; idx < ArrayCount(byte_fstrs); idx += 1) { U8 byte = (U8)idx; F32 pct = (byte/255.f); @@ -4843,8 +4846,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { text_color.w *= 0.5f; } - DR_FancyString fstr = {font, push_str8f(scratch.arena, "%02x", byte), text_color, font_size, 0, 0}; - dr_fancy_string_list_push(scratch.arena, &byte_fancy_strings[idx], &fstr); + DR_FStr fstr = {push_str8f(scratch.arena, "%02x", byte), {font, font_raster_flags, text_color, font_size, 0, 0}}; + dr_fstrs_push(scratch.arena, &byte_fstrs[idx], &fstr); } } @@ -5245,7 +5248,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // rjf: build ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = cell_bg_rgba)); UI_Box *cell_box = ui_build_box_from_key(UI_BoxFlag_DrawText|cell_flags, ui_key_zero()); - ui_box_equip_display_fancy_strings(cell_box, &byte_fancy_strings[byte_value]); + ui_box_equip_display_fstrs(cell_box, &byte_fstrs[byte_value]); { F32 off = 0; for(Annotation *a = annotation; a != 0; a = a->next) @@ -5784,26 +5787,20 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) UI_WidthFill RD_Font(RD_FontSlot_Code) { text_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - DR_FancyStringList fancy_strings = {0}; + DR_FStrList fstrs = {0}; { - DR_FancyString open_paren = {ui_top_font(), str8_lit("("), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - DR_FancyString comma = {ui_top_font(), str8_lit(", "), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - DR_FancyString r_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.x), v4f32(1.f, 0.25f, 0.25f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString g_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.y), v4f32(0.25f, 1.f, 0.25f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString b_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.z), v4f32(0.25f, 0.25f, 1.f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString a_fstr = {ui_top_font(), push_str8f(scratch.arena, "%.2f", rgba.w), v4f32(1.f, 1.f, 1.f, 1.f), ui_top_font_size(), 4.f, 0}; - DR_FancyString clse_paren = {ui_top_font(), str8_lit(")"), ui_top_palette()->text, ui_top_font_size(), 0, 0}; - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &open_paren); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &r_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &g_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &b_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &comma); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &a_fstr); - dr_fancy_string_list_push(scratch.arena, &fancy_strings, &clse_paren); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_top_palette()->text, ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("(")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = v4f32(1.f, 0.25f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.y), .color = v4f32(0.25f, 1.f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.z), .color = v4f32(0.25f, 0.25f, 1.f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.w), .color = v4f32(1.f, 1.f, 1.f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")")); } - ui_box_equip_display_fancy_strings(text_box, &fancy_strings); + ui_box_equip_display_fstrs(text_box, &fstrs); } //- rjf: build color box diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index b017a4f8..456075d4 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -57,7 +57,7 @@ struct RD_WatchCell RD_WatchCell *next; RD_WatchCellKind kind; String8 string; - DR_FancyStringList fancy_strings; + DR_FStrList fstrs; F32 pct; F32 px; }; @@ -92,7 +92,7 @@ struct RD_WatchRowCellInfo { E_Eval eval; String8 string; - DR_FancyStringList fancy_strings; + DR_FStrList fstrs; B32 is_non_code; B32 is_button; B32 can_edit; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 579ae4d1..93ae1495 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -202,8 +202,8 @@ rd_cmd_binding_buttons(String8 name) { if(!str8_match(n2->v->name, n->v->name, 0)) { - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(n2->v->name); - ui_labelf("%S", info->display_name); + String8 display_name = rd_display_from_code_name(n2->v->name); + ui_labelf("%S", display_name); } } } @@ -300,7 +300,7 @@ rd_cmd_spec_button(String8 name) "###cmd_%p", info); UI_Parent(box) UI_HeightFill UI_Padding(ui_em(1.f, 1.f)) { - RD_IconKind canonical_icon = info->icon_kind; + RD_IconKind canonical_icon = rd_icon_kind_from_code_name(name); if(canonical_icon != RD_IconKind_Null) { RD_Font(RD_FontSlot_Icons) @@ -315,7 +315,7 @@ rd_cmd_spec_button(String8 name) { UI_Flags(UI_BoxFlag_DrawTextFastpathCodepoint) UI_FastpathCodepoint(box->fastpath_codepoint) - ui_label(info->display_name); + ui_label(rd_display_from_code_name(name)); ui_spacer(ui_pct(1, 0)); ui_set_next_flags(UI_BoxFlag_Clickable); ui_set_next_group_key(ui_key_zero()); @@ -1250,12 +1250,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe (stop_event.cause == CTRL_EventCause_InterruptedByException || stop_event.cause == CTRL_EventCause_InterruptedByTrap)) { - DR_FancyStringList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###exception_info"); - ui_box_equip_display_fancy_strings(box, &explanation_fstrs); + ui_box_equip_display_fstrs(box, &explanation_fstrs); } } } @@ -1730,20 +1730,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe dr_push_bucket(line_bucket); // rjf: string * tokens -> fancy string list - DR_FancyStringList line_fancy_strings = {0}; + DR_FStrList line_fstrs = {0}; { if(line_tokens->count == 0) { - DR_FancyString fstr = + DR_FStrParams fstr_params = { params->font, - line_string, + ui_top_text_raster_flags(), rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), params->font_size, - 0, - 0, }; - dr_fancy_string_list_push(scratch.arena, &line_fancy_strings, &fstr); + dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, line_string); } else { @@ -1778,22 +1776,20 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: push fancy string - DR_FancyString fstr = + DR_FStrParams fstr_params = { params->font, - token_string, + ui_top_text_raster_flags(), token_color, params->font_size, - 0, - 0, }; - dr_fancy_string_list_push(scratch.arena, &line_fancy_strings, &fstr); + dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, token_string); } } } // rjf: equip fancy strings to line box - ui_box_equip_display_fancy_strings(line_box, &line_fancy_strings); + ui_box_equip_display_fstrs(line_box, &line_fstrs); // rjf: extra rendering for strings that are currently being searched for if(params->search_query.size != 0) @@ -2182,25 +2178,26 @@ rd_label(String8 string) active_part_flags ^= StringPartFlag_Code; } } - DR_FancyStringList fstrs = {0}; + DR_FStrList fstrs = {0}; for(StringPart *p = first_part; p != 0; p = p->next) { - DR_FancyString fstr = {0}; + DR_FStr fstr = {0}; { - fstr.font = ui_top_font(); fstr.string = p->string; - fstr.color = ui_top_palette()->colors[UI_ColorCode_Text]; - fstr.size = ui_top_font_size(); + fstr.params.font = ui_top_font(); + fstr.params.color = ui_top_palette()->colors[UI_ColorCode_Text]; + fstr.params.size = ui_top_font_size(); if(p->flags & StringPartFlag_Code) { - fstr.font = rd_font_from_slot(RD_FontSlot_Code); - fstr.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + fstr.params.font = rd_font_from_slot(RD_FontSlot_Code); + fstr.params.raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); + fstr.params.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } } - dr_fancy_string_list_push(scratch.arena, &fstrs, &fstr); + dr_fstrs_push(scratch.arena, &fstrs, &fstr); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fstrs(box, &fstrs); UI_Signal sig = ui_signal_from_box(box); scratch_end(scratch); return sig; @@ -2249,12 +2246,12 @@ rd_help_label(String8 string) return result; } -internal DR_FancyStringList -rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) +internal DR_FStrList +rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); - DR_FancyStringList fancy_strings = {0}; + DR_FStrList fstrs = {0}; TXT_TokenArray tokens = txt_token_array_from_string__c_cpp(scratch.arena, 0, string); TXT_Token *tokens_opl = tokens.v+tokens.count; S32 indirection_counter = 0; @@ -2272,14 +2269,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s { default: { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), token_string, - token_color_rgba, - ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + } }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); }break; case TXT_TokenKind_Identifier: case TXT_TokenKind_Keyword: @@ -2291,14 +2291,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); token_color_rgba = mix_4f32(token_color_rgba, lookup_color, lookup_color_mix_t); } - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), token_string, - token_color_rgba, - ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)), + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); }break; case TXT_TokenKind_Numeric: { @@ -2344,14 +2347,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s // rjf: push prefix { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), prefix, - token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); } // rjf: push digit groups @@ -2367,14 +2373,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s num_digits_passed = 0; if(start_idx < idx) { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), str8_substr(whole, r1u64(start_idx, idx)), - odd ? token_color_rgba_alt : token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + odd ? token_color_rgba_alt : token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); start_idx = idx; odd ^= 1; } @@ -2388,14 +2397,17 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s // rjf: push decimal { - DR_FancyString fancy_string = + DR_FStr fstr = { - ui_top_font(), decimal, - token_color_rgba, - font_size, + { + ui_top_font(), + ui_top_text_raster_flags(), + token_color_rgba, + font_size, + }, }; - dr_fancy_string_list_push(arena, &fancy_strings, &fancy_string); + dr_fstrs_push(arena, &fstrs, &fstr); } }break; @@ -2406,16 +2418,16 @@ rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s } scratch_end(scratch); ProfEnd(); - return fancy_strings; + return fstrs; } internal UI_Box * rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string) { Temp scratch = scratch_begin(0, 0); - DR_FancyStringList fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); + DR_FStrList fstrs = rd_fstrs_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fancy_strings); + ui_box_equip_display_fstrs(box, &fstrs); scratch_end(scratch); return box; } @@ -2650,10 +2662,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(!is_focus_active && !is_focus_active_disabled && params->fancy_strings.total_size != 0) + if(!is_focus_active && !is_focus_active_disabled && params->fstrs.total_size != 0) { UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(label, ¶ms->fancy_strings); + ui_box_equip_display_fstrs(label, ¶ms->fstrs); } else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) { @@ -2710,15 +2722,15 @@ rd_line_edit(RD_LineEditParams *params, String8 string) F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); - DR_FancyStringList code_fancy_strings = rd_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); if(autocomplete_hint_string.size != 0) { String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); U64 off = 0; U64 cursor_off = params->cursor->column-1; - DR_FancyStringNode *prev_n = 0; - for(DR_FancyStringNode *n = code_fancy_strings.first; n != 0; n = n->next) + DR_FStrNode *prev_n = 0; + for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) { if(off <= cursor_off && cursor_off <= off+n->v.string.size) { @@ -2728,13 +2740,13 @@ rd_line_edit(RD_LineEditParams *params, String8 string) off += n->v.string.size; } { - DR_FancyStringNode *autocomp_fstr_n = push_array(scratch.arena, DR_FancyStringNode, 1); - DR_FancyString *fstr = &autocomp_fstr_n->v; - fstr->font = ui_top_font(); + DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *fstr = &autocomp_fstr_n->v; fstr->string = autocomplete_append_string; - fstr->color = ui_top_palette()->text; - fstr->color.w *= 0.5f; - fstr->size = ui_top_font_size(); + fstr->params.font = ui_top_font(); + fstr->params.color = ui_top_palette()->text; + fstr->params.color.w *= 0.5f; + fstr->params.size = ui_top_font_size(); autocomp_fstr_n->next = prev_n ? prev_n->next : 0; if(prev_n != 0) { @@ -2742,40 +2754,40 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } if(prev_n == 0) { - code_fancy_strings.first = code_fancy_strings.last = autocomp_fstr_n; + code_fstrs.first = code_fstrs.last = autocomp_fstr_n; } if(prev_n != 0 && prev_n->next == 0) { - code_fancy_strings.last = autocomp_fstr_n; + code_fstrs.last = autocomp_fstr_n; } - code_fancy_strings.node_count += 1; - code_fancy_strings.total_size += autocomplete_hint_string.size; + code_fstrs.node_count += 1; + code_fstrs.total_size += autocomplete_hint_string.size; if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) { String8 full_string = prev_n->v.string; U64 chop_amt = full_string.size - (cursor_off - off); prev_n->v.string = str8_chop(full_string, chop_amt); - code_fancy_strings.total_size -= chop_amt; + code_fstrs.total_size -= chop_amt; if(chop_amt != 0) { String8 post_cursor = str8_skip(full_string, cursor_off - off); - DR_FancyStringNode *post_fstr_n = push_array(scratch.arena, DR_FancyStringNode, 1); - DR_FancyString *post_fstr = &post_fstr_n->v; + DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *post_fstr = &post_fstr_n->v; MemoryCopyStruct(post_fstr, &prev_n->v); post_fstr->string = post_cursor; if(autocomp_fstr_n->next == 0) { - code_fancy_strings.last = post_fstr_n; + code_fstrs.last = post_fstr_n; } post_fstr_n->next = autocomp_fstr_n->next; autocomp_fstr_n->next = post_fstr_n; - code_fancy_strings.node_count += 1; - code_fancy_strings.total_size += post_cursor.size; + code_fstrs.node_count += 1; + code_fstrs.total_size += post_cursor.size; } } } } - ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); + ui_box_equip_display_fstrs(editstr_box, &code_fstrs); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = params->cursor[0]; diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 4a905424..0de9354f 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -36,7 +36,7 @@ struct RD_LineEditParams U64 *edit_string_size_out; B32 *expanded_out; String8 pre_edit_value; - DR_FancyStringList fancy_strings; + DR_FStrList fstrs; }; //////////////////////////////// @@ -125,7 +125,7 @@ internal B32 rd_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count internal UI_Signal rd_label(String8 string); internal UI_Signal rd_error_label(String8 string); internal B32 rd_help_label(String8 string); -internal DR_FancyStringList rd_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); +internal DR_FStrList rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); internal UI_Box *rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string); //////////////////////////////// diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 4b1f0350..6426ff4e 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -717,10 +717,10 @@ ui_string_hover_begin_time_us(void) return ui_state->string_hover_begin_us; } -internal DR_FancyStringList +internal DR_FStrList ui_string_hover_fstrs(Arena *arena) { - DR_FancyStringList result = dr_fancy_string_list_copy(arena, &ui_state->string_hover_fstrs); + DR_FStrList result = dr_fstrs_copy(arena, &ui_state->string_hover_fstrs); return result; } @@ -1529,7 +1529,7 @@ ui_end_build(void) Vec2F32 drawn_text_dim = {0}; { Temp scratch = scratch_begin(0, 0); - DR_FancyRunList fruns = dr_fancy_run_list_from_fancy_string_list(scratch.arena, b->tab_size, b->text_raster_flags, &b->display_fstrs); + DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, b->tab_size, &b->display_fstrs); drawn_text_dim = fruns.dim; scratch_end(scratch); } @@ -1546,7 +1546,7 @@ ui_end_build(void) arena_clear(ui_state->string_hover_arena); ui_state->string_hover_string = push_str8_copy(ui_state->string_hover_arena, box_display_string); ui_state->string_hover_size = box->font_size; - ui_state->string_hover_fstrs = dr_fancy_string_list_copy(ui_state->string_hover_arena, &b->display_fstrs); + ui_state->string_hover_fstrs = dr_fstrs_copy(ui_state->string_hover_arena, &b->display_fstrs); ui_state->string_hover_begin_us = os_now_microseconds(); } ui_state->string_hover_build_index = ui_state->build_index; @@ -2421,10 +2421,10 @@ ui_box_equip_display_string(UI_Box *box, String8 string) if(box->flags & UI_BoxFlag_DrawText && (box->fastpath_codepoint == 0 || !(box->flags & UI_BoxFlag_DrawTextFastpathCodepoint))) { String8 display_string = ui_box_display_string(box); - DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); - box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2435,19 +2435,19 @@ ui_box_equip_display_string(UI_Box *box, String8 string) U64 fpcp_pos = str8_find_needle(display_string, 0, fpcp, StringMatchFlag_CaseInsensitive); if(fpcp_pos < display_string.size) { - DR_FancyStringNode pst_fancy_string_n = {0, {box->font, str8_skip(display_string, fpcp_pos+fpcp.size), box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->palette->colors[text_color_code], box->font_size, 3.f, 0}}; - DR_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->palette->colors[text_color_code], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); - box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); + DR_FStrNode pst_fstr_n = {0, {str8_skip(display_string, fpcp_pos+fpcp.size), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; + DR_FStrNode cdp_fstr_n = {&pst_fstr_n, {str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 3.f, 0}}}; + DR_FStrNode pre_fstr_n = {&cdp_fstr_n, {str8_prefix(display_string, fpcp_pos), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&pre_fstr_n, &pst_fstr_n, 3}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } else { - DR_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->palette->colors[UI_ColorCode_Text], box->font_size, 0, 0}}; - DR_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), &fancy_strings); - box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, box->palette->colors[UI_ColorCode_Text], box->font_size, 0, 0}}}; + DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } scratch_end(scratch); } @@ -2455,12 +2455,12 @@ ui_box_equip_display_string(UI_Box *box, String8 string) } internal void -ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings) +ui_box_equip_display_fstrs(UI_Box *box, DR_FStrList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; - box->string = dr_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_fstrs = dr_fancy_string_list_copy(ui_build_arena(), strings); - box->display_fruns = dr_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, box->text_raster_flags, &box->display_fstrs); + box->string = dr_string_from_fstrs(ui_build_arena(), strings); + box->display_fstrs = dr_fstrs_copy(ui_build_arena(), strings); + box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } internal inline void diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 6bf7496b..7ec57ded 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -433,8 +433,8 @@ struct UI_Box F32 text_padding; //- rjf: per-build artifacts - DR_FancyStringList display_fstrs; - DR_FancyRunList display_fruns; + DR_FStrList display_fstrs; + DR_FRunList display_fruns; Rng2F32 rect; Vec2F32 fixed_position_animated; Vec2F32 position_delta; @@ -682,7 +682,7 @@ struct UI_State Arena *string_hover_arena; String8 string_hover_string; F32 string_hover_size; - DR_FancyStringList string_hover_fstrs; + DR_FStrList string_hover_fstrs; U64 string_hover_begin_us; U64 string_hover_build_index; U64 last_time_mousemoved_us; @@ -815,7 +815,7 @@ internal String8 ui_get_drag_data(U64 min_required_size); //- rjf: hovered string info internal B32 ui_string_hover_active(void); -internal DR_FancyStringList ui_string_hover_fstrs(Arena *arena); +internal DR_FStrList ui_string_hover_fstrs(Arena *arena); //- rjf: interaction keys internal UI_Key ui_hot_key(void); @@ -882,7 +882,7 @@ internal UI_Box * ui_build_box_from_stringf(UI_BoxFlags flags, char *fm //- rjf: box node equipment internal inline void ui_box_equip_display_string(UI_Box *box, String8 string); -internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, DR_FancyStringList *strings); +internal inline void ui_box_equip_display_fstrs(UI_Box *box, DR_FStrList *strings); internal inline void ui_box_equip_fuzzy_match_ranges(UI_Box *box, FuzzyMatchRangeList *matches); internal inline void ui_box_equip_draw_bucket(UI_Box *box, DR_Bucket *bucket); internal inline void ui_box_equip_custom_draw(UI_Box *box, UI_BoxCustomDrawFunctionType *custom_draw, void *user_data); From c8fb9a0ec933024b59aed1cf05921109593bc2de Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 14:27:14 -0800 Subject: [PATCH 098/755] clean up panel drop site jank --- src/draw/draw.c | 27 +++++++++++--- src/raddbg/raddbg_core.c | 78 +++++++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index 095edf51..152a75c5 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -58,12 +58,29 @@ internal void dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string) { DR_FStr fstr = {string, *params}; - for(U64 idx = 0; idx < sizeof(DR_FStrParams); idx += 1) + if(!fnt_tag_match(fnt_tag_zero(), overrides->font)) { - if(((U8 *)overrides)[idx] != 0) - { - ((U8 *)&fstr.params)[idx] = ((U8 *)overrides)[idx]; - } + fstr.params.font = overrides->font; + } + if(overrides->raster_flags != 0) + { + fstr.params.raster_flags = overrides->raster_flags; + } + if(overrides->color.x != 0 || overrides->color.y != 0 || overrides->color.z != 0 || overrides->color.w != 0) + { + fstr.params.color = overrides->color; + } + if(overrides->size != 0) + { + fstr.params.size = overrides->size; + } + if(overrides->underline_thickness != 0) + { + fstr.params.underline_thickness = overrides->underline_thickness; + } + if(overrides->strikethrough_thickness != 0) + { + fstr.params.strikethrough_thickness = overrides->strikethrough_thickness; } dr_fstrs_push(arena, list, &fstr); } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0eac4e3e..90a159f0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3560,7 +3560,7 @@ rd_window_frame(void) ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_DropSiteOverlay]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_BaseBorder]; if(rd_setting_b32_from_name(str8_lit("opaque_backgrounds"))) { for EachEnumVal(RD_PaletteCode, code) @@ -6323,7 +6323,8 @@ rd_window_frame(void) // rjf: build UI_Box *site_box = &ui_nil_box; { - UI_Rect(site_rect) + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); ui_signal_from_box(site_box); @@ -6359,14 +6360,23 @@ rd_window_frame(void) // rjf: viz if(ui_key_match(site_box->key, ui_drop_hot_key())) { - Rng2F32 future_split_rect = site_rect; - future_split_rect.p0.v[axis] -= drop_site_major_dim_px; - future_split_rect.p1.v[axis] += drop_site_major_dim_px; - future_split_rect.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)]; - future_split_rect.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)]; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) + Rng2F32 future_split_rect_target = site_rect; + future_split_rect_target.p0.v[axis] -= drop_site_major_dim_px; + future_split_rect_target.p1.v[axis] += drop_site_major_dim_px; + future_split_rect_target.p0.v[axis2_flip(axis)] = panel_rect.p0.v[axis2_flip(axis)]; + future_split_rect_target.p1.v[axis2_flip(axis)] = panel_rect.p1.v[axis2_flip(axis)]; + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -6396,7 +6406,7 @@ rd_window_frame(void) // rjf: form rect Rng2F32 child_rect = rd_target_rect_from_panel_node_child(panel_rect, panel, child); Vec2F32 child_rect_center = center_2f32(child_rect); - UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel, child); + UI_Key key = ui_key_from_stringf(ui_key_zero(), "drop_boundary_%p_%p", panel->cfg, child->cfg); Rng2F32 site_rect = r2f32(child_rect_center, child_rect_center); site_rect.p0.v[split_axis] = child_rect.p0.v[split_axis] - drop_site_minor_dim_px/2; site_rect.p1.v[split_axis] = child_rect.p0.v[split_axis] + drop_site_minor_dim_px/2; @@ -6406,7 +6416,8 @@ rd_window_frame(void) // rjf: build UI_Box *site_box = &ui_nil_box; { - UI_Rect(site_rect) + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); ui_signal_from_box(site_box); @@ -6442,14 +6453,23 @@ rd_window_frame(void) // rjf: viz if(ui_key_match(site_box->key, ui_drop_hot_key())) { - Rng2F32 future_split_rect = site_rect; - future_split_rect.p0.v[split_axis] -= drop_site_major_dim_px; - future_split_rect.p1.v[split_axis] += drop_site_major_dim_px; - future_split_rect.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)]; - future_split_rect.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)]; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) + Rng2F32 future_split_rect_target = site_rect; + future_split_rect_target.p0.v[split_axis] -= drop_site_major_dim_px; + future_split_rect_target.p1.v[split_axis] += drop_site_major_dim_px; + future_split_rect_target.p0.v[axis2_flip(split_axis)] = child_rect.p0.v[axis2_flip(split_axis)]; + future_split_rect_target.p1.v[axis2_flip(split_axis)] = child_rect.p1.v[axis2_flip(split_axis)]; + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -6655,7 +6675,7 @@ rd_window_frame(void) // { RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse())) + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) { F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); @@ -6723,7 +6743,8 @@ rd_window_frame(void) } UI_Box *site_box = &ui_nil_box; { - UI_Rect(rect) + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); ui_signal_from_box(site_box); @@ -6799,15 +6820,24 @@ rd_window_frame(void) { Axis2 split_axis = axis2_from_dir2(sites[idx].split_dir); Side split_side = side_from_dir2(sites[idx].split_dir); - Rng2F32 future_split_rect = panel_rect; + Rng2F32 future_split_rect_target = panel_rect; if(sites[idx].split_dir != Dir2_Invalid) { Vec2F32 panel_center = center_2f32(panel_rect); - future_split_rect.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; + future_split_rect_target.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; } - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } } From e84f8e66f5ad80fd2df1dd56904214633f763733 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 16:05:37 -0800 Subject: [PATCH 099/755] precompute watch row infos before build --- src/raddbg/raddbg_core.c | 2 +- src/raddbg/raddbg_views.c | 1122 ++----------------------------------- 2 files changed, 44 insertions(+), 1080 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 90a159f0..41cf1080 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13077,7 +13077,7 @@ rd_frame(void) { RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("targets[1]")); + rd_cfg_new(expr, str8_lit("targets[0]")); } { RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d67a669a..eb9996db 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2487,7 +2487,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; - //////////////////////////// + //////////////////////// //- rjf: viz blocks -> rows // EV_WindowedRowList rows = {0}; @@ -2495,26 +2495,40 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); } - //////////////////////////// + //////////////////////// + //- rjf: rows -> row infos + // + RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// //- rjf: build table // ProfScope("build table") { + U64 local_row_idx = 0; U64 global_row_idx = rows.count_before_semantic; RD_WatchRowInfo last_row_info = {0}; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1) + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) { //////////////////////// //- rjf: unpack row info // ProfBegin("unpack row info"); EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; U64 row_hash = ev_hash_from_key(row->key); U64 row_depth = ev_depth_from_block(row->block); B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); B32 row_expanded = ev_expansion_from_key(eval_view, row->key); B32 next_row_expanded = row_expanded; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); B32 row_is_expandable = ev_row_is_expandable(row); if(implicit_root && row_depth > 0) { @@ -2528,7 +2542,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) B32 row_matches_last_row_topology = 1; if(row_node != rows.first) { - for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info.cells.first;; + for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; last_cell = last_cell->next, this_cell = this_cell->next) { if(last_cell == 0 && this_cell == 0) @@ -2551,7 +2565,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////////// //- rjf: store last row's info, for next iteration // - last_row_info = row_info; + last_row_info = *row_info; //////////////////////// //- rjf: determine if row's data is fresh and/or bad @@ -2559,17 +2573,17 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ProfBegin("determine if row's data is fresh and/or bad"); B32 row_is_fresh = 0; B32 row_is_bad = 0; - switch(row_info.eval.mode) + switch(row_info->eval.mode) { default:{}break; case E_Mode_Offset: { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info.eval.space); - if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) { - U64 size = e_type_byte_size_from_key(row_info.eval.type_key); + U64 size = e_type_byte_size_from_key(row_info->eval.type_key); size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_info.eval.value.u64, row_info.eval.value.u64+size); + Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { @@ -2633,15 +2647,15 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ////////////////////// //- rjf: build row contents // - RD_RegsScope(.module = row_info.module->handle) UI_Parent(row_box) + RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) { //////////////////// //- rjf: draw start of cache lines in expansions // - if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info.view_ui_rule == &rd_nil_view_ui_rule) + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - U64 row_offset = row_info.eval.value.u64; - if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && + U64 row_offset = row_info->eval.value.u64; + if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && row_offset%64 == 0 && row_depth > 0) { ui_set_next_fixed_x(0); @@ -2655,15 +2669,15 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////// //- rjf: draw mid-row cache line boundaries in expansions // - if(row_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info.view_ui_rule == &rd_nil_view_ui_rule) + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - if((row_info.eval.mode == E_Mode_Offset || row_info.eval.mode == E_Mode_Null) && - row_info.eval.value.u64%64 != 0 && + if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && + row_info->eval.value.u64%64 != 0 && row_depth > 0 && !row_expanded) { - U64 next_off = (row_info.eval.value.u64 + e_type_byte_size_from_key(row_info.eval.type_key)); - if(next_off%64 != 0 && row_info.eval.value.u64/64 < next_off/64) + U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.type_key)); + if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) { ui_set_next_fixed_x(0); ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); @@ -2681,14 +2695,14 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // S64 cell_x = 0; F32 cell_x_px = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) { //- rjf: unpack cell info U64 cell_id = rd_id_from_watch_cell(cell); RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; @@ -2789,9 +2803,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_LineEditFlag_NoBackground*!(cell_info.is_button)| RD_LineEditFlag_Button*!!(cell_info.is_button)| RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info.cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info.cells.first && !cell_info.is_button)| - RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info.cells.first))); + RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !cell_info.is_button)| + RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; line_edit_params.mark = &cell_edit_state->mark; @@ -2834,12 +2848,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ui_kill_action(); // rjf: has callstack info? -> select unwind - if(row_info.callstack_thread != &ctrl_entity_nil) + if(row_info->callstack_thread != &ctrl_entity_nil) { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info.callstack_unwind_index, - .inline_depth = row_info.callstack_inline_depth); + .unwind_count = row_info->callstack_unwind_index, + .inline_depth = row_info->callstack_inline_depth); } // rjf: can edit? -> begin editing @@ -3059,1056 +3073,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } - ////////////////////// - //- rjf: build row contents - // -#if 0 // TODO(rjf): @cfg - RD_RegsScope(.module = row_module->handle) UI_Parent(row_box) switch(row_kind) - { - //////////////////// - //- rjf: header row - // - case RD_WatchViewRowKind_Header: - ProfScope("header row") - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - { - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next) - UI_TableCell - { - String8 name = str8(col->display_string_buffer, col->display_string_size); - if(name.size == 0) - { - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {name = str8_lit("Expression");}break; - case RD_WatchViewColumnKind_Value: {name = str8_lit("Value");}break; - case RD_WatchViewColumnKind_Type: {name = str8_lit("Type");}break; - case RD_WatchViewColumnKind_ViewRule:{name = str8_lit("View Rule");}break; - case RD_WatchViewColumnKind_Member: - { - name = str8(col->string_buffer, col->string_size); - }break; - } - } - switch(col->kind) - { - default: - { - ui_label(name); - }break; - case RD_WatchViewColumnKind_ViewRule: - { - if(rd_help_label(name)) UI_Tooltip - { - F32 max_width = ui_top_font_size()*35; - ui_label_multiline(max_width, str8_lit("View rules are used to tweak the way evaluated expressions are visualized. Multiple rules can be specified on each row. They are specified in a key:(value) form. Some examples follow:")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("array:(N)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that a pointer points to N elements, rather than only 1.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("omit:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Omits a list of member names from appearing in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("only:(member_1 ... member_n)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that only the specified members should appear in struct, union, or class evaluations.")); - ui_spacer(ui_em(1.5f, 1)); -#if 0 // TODO(rjf): disabling until post-0.9.12 - RD_Font(RD_FontSlot_Code) ui_labelf("list:(next_link_member_name)"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that some struct, union, or class forms the top of a linked list, with next_link_member_name being the member which points at the next element in the list.")); - ui_spacer(ui_em(1.5f, 1)); -#endif - RD_Font(RD_FontSlot_Code) ui_labelf("dec"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-10 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("hex"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-16 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("oct"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-8 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("bin"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Specifies that all integral evaluations should appear in base-2 form.")); - ui_spacer(ui_em(1.5f, 1)); - RD_Font(RD_FontSlot_Code) ui_labelf("no_addr"); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label_multiline(max_width, str8_lit("Displays only what pointers point to, if possible, without the pointer's address value.")); - ui_spacer(ui_em(1.5f, 1)); - } - }break; - } - } - } - }break; - - //////////////////// - //- rjf: canvas row - // - case RD_WatchViewRowKind_Canvas: - ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) - { -#if 0 // TODO(rjf): @cfg - //- rjf: unpack - RD_WatchPt pt = {0, row->block->key, row->key}; - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); - RD_View *canvas_view = canvas_view_node->view; - String8 canvas_view_expr = e_string_from_expr(scratch.arena, row->expr); - B32 need_new_spec = (!str8_match(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view_expr, 0) || - !md_tree_match(canvas_view_node->initial_params, ui_view_rule_params_root, 0)); - if(need_new_spec) - { - arena_clear(canvas_view_node->initial_params_arena); - canvas_view_node->initial_params = md_tree_copy(canvas_view_node->initial_params_arena, ui_view_rule_params_root); - rd_view_equip_spec(canvas_view, ui_view_rule_info, canvas_view_expr, ui_view_rule_params_root); - } - Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f, - (row->visual_size_skipped+row->visual_size+row->visual_size_chopped)*scroll_list_params.row_height_px); - Rng2F32 canvas_rect = r2f32p(rect.x0, - rect.y0 + ui_top_fixed_y(), - rect.x0 + canvas_dim.x, - rect.y0 + ui_top_fixed_y() + canvas_dim.y); - - //- rjf: peek clicks in canvas region, mark clicked - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && evt->key == OS_Key_LeftMouseButton && contains_2f32(canvas_rect, evt->pos) && - contains_2f32(rect, evt->pos)) - { - pressed = 1; - break; - } - } - - //- rjf: build meta controls - ui_set_next_fixed_x(ui_top_font_size()*1.f); - ui_set_next_fixed_y(ui_top_font_size()*1.f + scroll_list_view_off_px.y*(row == rows.first)); - ui_set_next_pref_width(ui_em(3, 1)); - ui_set_next_pref_height(ui_em(3, 1)); - UI_Flags(UI_BoxFlag_DrawDropShadow) UI_CornerRadius(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_Window, 0, "###pop_out"); - if(ui_hovering(sig)) UI_Tooltip - { - ui_labelf("Pop out"); - } - if(ui_pressed(sig)) - { - pressed = 1; - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_OpenTab, - .string = e_string_from_expr(scratch.arena, row->expr), - .params_tree = ui_view_rule_params_root); - } - } - - //- rjf: build main column for canvas - ui_set_next_fixed_y(-1.f * (row->visual_size_skipped) * scroll_list_params.row_height_px); - ui_set_next_fixed_height((row->visual_size_skipped + row->visual_size + row->visual_size_chopped) * scroll_list_params.row_height_px); - ui_set_next_child_layout_axis(Axis2_X); - UI_Box *canvas_box = ui_build_box_from_stringf(UI_BoxFlag_FloatingY, "###canvas_%I64x", row_hash); - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - //- rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(canvas_box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - //- rjf: push interaction registers, fill with per-view states - rd_push_regs(); - { - rd_regs()->view = rd_handle_from_view(canvas_view); - rd_regs()->file_path = rd_file_path_from_eval_string(rd_frame_arena(), str8(canvas_view->query_buffer, canvas_view->query_string_size)); - } - - //- rjf: build - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - { - ui_view_rule_info->ui(str8(canvas_view->query_buffer, canvas_view->query_string_size), canvas_view->params_roots[canvas_view->params_read_gen%ArrayCount(canvas_view->params_roots)], canvas_rect); - } - - //- rjf: loading overlay fill - UI_Parent(loading_overlay_container) - { - rd_loading_overlay(canvas_rect, canvas_view->loading_t, canvas_view->loading_progress_v, canvas_view->loading_progress_v_target); - } - - //- rjf: pop interaction registers - rd_pop_regs(); - } -#endif - }break; - - //////////////////// - //- rjf: pretty entity controls row - // - case RD_WatchViewRowKind_PrettyEntityControls: - ProfScope("pretty entity controls row") - { - //- rjf: unpack - RD_EntityKind collection_entity_kind = row_info.collection_entity_kind; - CTRL_EntityKind collection_ctrl_entity_kind = row_info.collection_ctrl_entity_kind; - RD_Entity *entity = row_info.collection_entity; - CTRL_Entity *ctrl_entity = row_info.collection_ctrl_entity; - B32 entity_box_selected = (row_selected && selection_tbl.min.x <= 1 && 1 <= selection_tbl.max.x); - B32 is_hovering = ((rd_handle_match(rd_state->hover_regs->entity, rd_handle_from_entity(entity)) && - rd_state->hover_regs_slot == RD_RegSlot_Entity) || - (ctrl_handle_match(rd_state->hover_regs->thread, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Thread) || - (ctrl_handle_match(rd_state->hover_regs->module, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Module) || - (ctrl_handle_match(rd_state->hover_regs->process, ctrl_entity->handle) && rd_state->hover_regs_slot == RD_RegSlot_Process)); - - //- rjf: pick palette - UI_Palette *palette = ui_build_palette(ui_top_palette()); - if(entity->kind == RD_EntityKind_Target && !entity->disabled) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else if(ctrl_entity->kind == CTRL_EntityKind_Thread && ctrl_handle_match(ctrl_entity->handle, rd_regs()->thread)) - { - palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_NeutralPopButton)); - } - else - { - palette->background = v4f32(0, 0, 0, 0); - } - - //- rjf: build indentation - for(U64 idx = 0; idx < row_depth; idx += 1) - { - ui_set_next_flags(UI_BoxFlag_DrawSideLeft); - ui_spacer(ui_em(1.f, 1.f)); - } - - //- rjf: build add-new buttons - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Target) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_Breakpoint) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); - } - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 2 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_WatchPin) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected && selection_tbl.min.x == 1 ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_FilePathMap) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Add File Path Map"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_FilePathMap); - } - } - if(rd_entity_is_nil(entity) && collection_entity_kind == RD_EntityKind_AutoViewRule) - UI_Palette(palette) - { - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Add Auto View Rule"))) - { - rd_entity_alloc(rd_entity_root(), RD_EntityKind_AutoViewRule); - } - } - - //- rjf: build entity box - if(!rd_entity_is_nil(entity) || ctrl_entity != &ctrl_entity_nil) - { - //- rjf: unpack entity info - DR_FStrList fstrs = {0}; - if(!rd_entity_is_nil(entity)) - { - fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, ui_top_palette()->text_weak, ui_top_font_size()); - } - else if(ctrl_entity != &ctrl_entity_nil) - { - fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); - } - String8 fstrs_string = dr_string_from_fstrs(scratch.arena, &fstrs); - FuzzyMatchRangeList fstrs_matches = fuzzy_match_find(scratch.arena, filter, fstrs_string); - UI_Key hover_t_key = ui_key_from_stringf(ui_key_zero(), "entity_hover_t_%p_%p", entity, ctrl_entity); - F32 hover_t = ui_anim(hover_t_key, (F32)!!is_hovering, .rate = entity_hover_t_rate); - if(!rd_entity_is_nil(entity)) - { - palette->overlay = rd_rgba_from_entity(entity); - palette->overlay.w *= 0.3f; - } - else if(ctrl_entity != &ctrl_entity_nil) - { - palette->overlay = rd_rgba_from_ctrl_entity(ctrl_entity); - palette->overlay.w *= 0.3f; - } - if(palette->overlay.x == 0 && palette->overlay.y == 0 && palette->overlay.z == 0 && palette->overlay.w == 0) - { - palette->overlay = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - } - palette->overlay.w *= hover_t; - - //- rjf: build - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *entity_box = &ui_nil_box; - UI_FocusHot(entity_box_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) - { - entity_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawOverlay| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawSideLeft| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects, - "###entity_%p_%p", entity, ctrl_entity); - } - { - UI_Parent(entity_box) RD_RegsScope(.entity = rd_handle_from_entity(entity)) - { - RD_RegSlot slot = RD_RegSlot_Entity; - switch(ctrl_entity->kind) - { - default:{}break; - case CTRL_EntityKind_Machine:{slot = RD_RegSlot_Machine; rd_regs()->machine = ctrl_entity->handle;}break; - case CTRL_EntityKind_Thread: {slot = RD_RegSlot_Thread; rd_regs()->thread = ctrl_entity->handle;}break; - case CTRL_EntityKind_Process:{slot = RD_RegSlot_Process; rd_regs()->process = ctrl_entity->handle;}break; - case CTRL_EntityKind_Module: {slot = RD_RegSlot_Module; rd_regs()->module = ctrl_entity->handle;}break; - } - UI_PrefWidth(ui_em(2.f, 1.f)) if(ui_pressed(ui_expander(row->block->rows_default_expanded ? !row_expanded : row_expanded, str8_lit("###expanded")))) - { - next_row_expanded = !row_expanded; - } - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTruncatedHover, ui_key_zero()); - ui_box_equip_display_fstrs(title_box, &fstrs); - ui_box_equip_fuzzy_match_ranges(title_box, &fstrs_matches); - UI_Signal sig = ui_signal_from_box(entity_box); - if(ui_hovering(sig)) - { - rd_set_hover_regs(slot); - } - if(ui_right_clicked(sig)) - { - rd_open_ctx_menu(entity_box->key, v2f32(0, dim_2f32(entity_box->rect).y), slot); - } - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) - { - rd_drag_begin(slot); - } - if(ui_pressed(sig)) - { - RD_WatchPt cell_pt = {1, row->block->key, row->key}; - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - if(ui_double_clicked(sig)) - { -#if 0 // TODO(rjf): @cfg - if(entity->kind == RD_EntityKind_Target) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - if(entity->kind == RD_EntityKind_Breakpoint || - entity->kind == RD_EntityKind_WatchPin) - { - RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); - rd_cmd(RD_CmdKind_FindCodeLocation, - .file_path = (loc->flags & RD_EntityFlag_HasTextPoint) ? loc->string : str8_zero(), - .cursor = loc->text_point, - .vaddr = loc->vaddr); - } -#endif - } - } - } - - //- rjf: build extra entity controls - UI_PrefWidth(ui_em(3.f, 1.f)) - { -#if 0 // TODO(rjf): @cfg - U64 ctrl_idx = 1; - for EachIndex(idx, row_ctrls_count) - { - RD_WatchViewRowCtrl *ctrl = &row_ctrls[idx]; - if(ctrl->entity_kind == entity->kind && - ctrl->ctrl_entity_kind == ctrl_entity->kind) - { - UI_FocusHot(row_selected && selection_tbl.min.x <= ctrl_idx+1 && ctrl_idx+1 <= selection_tbl.max.x ? UI_FocusKind_On : UI_FocusKind_Off) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); - RD_IconKind icon_kind = rd_cmd_kind_info_table[ctrl->kind].icon_kind; - UI_Palette *palette = ui_top_palette(); - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - icon_kind = entity->disabled ? RD_IconKind_RadioHollow : RD_IconKind_RadioFilled; - } - if(ctrl->kind == RD_CmdKind_EnableEntity) - { - icon_kind = entity->disabled ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled; - } - if(ctrl->kind == RD_CmdKind_SelectThread) - { - icon_kind = (ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread) ? RD_IconKind_RadioFilled : RD_IconKind_RadioHollow); - } - if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - icon_kind = is_frozen ? RD_IconKind_Locked : RD_IconKind_Unlocked; - palette = rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton); - } - UI_Palette(palette) - { - UI_Signal sig = rd_icon_buttonf(icon_kind, 0, "###row_ctrl_%I64x", idx); - if(ui_clicked(sig)) - { - if(ctrl->kind == RD_CmdKind_SelectEntity) - { - rd_cmd(sig.event_flags & OS_Modifier_Ctrl && entity->disabled ? RD_CmdKind_EnableEntity : - sig.event_flags & OS_Modifier_Ctrl && !entity->disabled ? RD_CmdKind_DisableEntity : - RD_CmdKind_SelectEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_EnableEntity) - { - rd_cmd(entity->disabled ? RD_CmdKind_EnableEntity : RD_CmdKind_DisableEntity, .entity = rd_handle_from_entity(entity)); - } - else if(ctrl->kind == RD_CmdKind_SelectThread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_FreezeEntity) - { - rd_cmd(is_frozen ? RD_CmdKind_ThawEntity : RD_CmdKind_FreezeEntity, - .ctrl_entity = ctrl_entity->handle); - } - else if(ctrl->kind == RD_CmdKind_Kill) - { - rd_cmd(RD_CmdKind_Kill, .process = ctrl_entity->handle); - } - else - { - rd_cmd(ctrl->kind, .entity = rd_handle_from_entity(entity)); - } - } - } - } - ctrl_idx += 1; - } - } -#endif - } - } - }break; - - //////////////////// - //- rjf: normal row - // - default: - case RD_WatchViewRowKind_Normal: - ProfScope("normal row") UI_HeightFill - { - ////////////////////// - //- rjf: draw start of cache lines in expansions - // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) - { - U64 row_offset = row_eval.value.u64; - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - - ////////////////////// - //- rjf: draw mid-row cache line boundaries in expansions - // - if(!(flags & RD_WatchViewFlag_DisableCacheLines)) - { - if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_eval.value.u64%64 != 0 && - row_depth > 0 && - !row_expanded) - { - U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key)); - if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f); - ui_set_next_fixed_height(ui_top_font_size()*1.f); - Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - boundary_color.w *= 0.5f; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - - ////////////////////// - //- rjf: build all columns - // - ProfScope("build all columns") - { - S64 x = 0; - F32 x_px = 0; - for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) - { - //- rjf: unpack cell info - RD_WatchPt cell_pt = {x, row->block->key, row->key}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); - String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - - //- rjf: unpack column-kind-specific info - ProfBegin("unpack column-kind-specific info"); - E_Eval cell_eval = row_eval; - E_Type *cell_type = row_type; - B32 cell_can_edit = 0; - FuzzyMatchRangeList cell_matches = {0}; - String8 cell_inheritance_string = {0}; - String8 cell_error_string = {0}; - String8 cell_error_tooltip_string = {0}; - RD_ListerFlags cell_autocomp_flags = 0; - RD_ViewRuleUIFunctionType *cell_ui_hook = 0; - MD_Node *cell_ui_params = &md_nil_node; - Vec4F32 cell_base_color = ui_top_palette()->text; - RD_IconKind cell_icon = RD_IconKind_Null; - String8 cell_ghost_text = {0}; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_can_edit = (row_depth == 0 && modifiable && filter.size == 0); - if(filter.size != 0) - { - cell_matches = fuzzy_match_find(scratch.arena, filter, ev_expr_string_from_row(scratch.arena, row, string_flags)); - } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(row->member != 0 && row->member->inheritance_key_chain.first != 0) - { - String8List inheritance_chain_type_names = {0}; - for(E_TypeKeyNode *n = row->member->inheritance_key_chain.first; n != 0; n = n->next) - { - String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v); - inherited_type_name = str8_skip_chop_whitespace(inherited_type_name); - str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name); - } - if(inheritance_chain_type_names.node_count != 0) - { - StringJoin join = {0}; - join.sep = str8_lit("::"); - String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join); - cell_inheritance_string = inheritance_type; - } - } - }break; - case RD_WatchViewColumnKind_Value: - { - }goto value_cell; - case RD_WatchViewColumnKind_Member: - { - E_Expr *expr = rd_expr_from_watch_view_row_column(scratch.arena, eval_view, row, col); - cell_eval = e_eval_from_expr(scratch.arena, expr); - cell_type = e_type_from_key(scratch.arena, cell_eval.type_key); - }goto value_cell; - value_cell:; - { - E_MsgList msgs = cell_eval.msgs; - if(row_depth == 0 && row->string.size != 0) - { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, row->string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, row->string, &tokens); - e_msg_list_concat_in_place(&parse.msgs, &msgs); - msgs = parse.msgs; - } - if(msgs.max_kind > E_MsgKind_Null) - { - String8List strings = {0}; - for(E_Msg *msg = msgs.first; msg != 0; msg = msg->next) - { - str8_list_push(scratch.arena, &strings, msg->text); - } - StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; - cell_error_string = str8_list_join(scratch.arena, &strings, &join); - } - if(row_is_bad) - { - cell_error_tooltip_string = str8_lit("Could not read memory successfully."); - } - cell_autocomp_flags = (RD_ListerFlag_Locals| - RD_ListerFlag_Procedures| - RD_ListerFlag_Globals| - RD_ListerFlag_ThreadLocals| - RD_ListerFlag_Types); - if(cell_type->flags & E_TypeFlag_IsPathText) - { - cell_autocomp_flags = RD_ListerFlag_Files; - } - if(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanFillValueCell) - { - cell_ui_hook = ui_view_rule_info->ui; - cell_ui_params = ui_view_rule_params_root; - } - for(EV_ViewRuleNode *n = row->view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - cell_can_edit = ev_type_key_is_editable(cell_eval.type_key); - }break; - case RD_WatchViewColumnKind_Type: - { - cell_can_edit = 0; - }break; - case RD_WatchViewColumnKind_ViewRule: - { - cell_can_edit = 1; - cell_autocomp_flags = RD_ListerFlag_ViewRules; - if(cell_pre_edit_string.size == 0) - { - EV_ViewRuleList *auto_view_rules = ev_auto_view_rules_from_type_key(scratch.arena, row_eval.type_key, 0, 1); - String8List strings = {0}; - for(EV_ViewRuleNode *n = auto_view_rules->first; n != 0; n = n->next) - { - str8_list_push(scratch.arena, &strings, n->v.root->string); - } - cell_ghost_text = str8_list_join(scratch.arena, &strings, &(StringJoin){.sep = str8_lit(", ")}); - } - }break; - case RD_WatchViewColumnKind_CallStackFrameSelection: - { - if(ctrl_handle_match(row_info.callstack_thread->handle, rd_regs()->thread) && - row_info.callstack_unwind_index == rd_regs()->unwind_count && - row_info.callstack_inline_depth == rd_regs()->inline_depth) - { - cell_icon = RD_IconKind_RightArrow; - cell_base_color = rd_rgba_from_ctrl_entity(row_info.callstack_thread); - } - }break; - } - ProfEnd(); - - //- rjf: apply column-specified view rules - ProfBegin("apply column-specified view rules"); - if(col->view_rule_size != 0) - { - String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(scratch.arena, col_view_rule); - for(EV_ViewRuleNode *n = view_rules->first; n != 0; n = n->next) - { - EV_ViewRule *vr = &n->v; - RD_ViewRuleInfo *info = rd_view_rule_info_from_string(vr->root->string); - if(info->flags & RD_ViewRuleInfoFlag_CanFillValueCell && info->ui != 0) - { - cell_ui_hook = info->ui; - cell_ui_params = vr->root; - } - } - } - ProfEnd(); - - //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); - UI_BoxFlags cell_flags = 0; - UI_Palette *palette = ui_top_palette(); - { - if(cell_error_tooltip_string.size != 0 || - cell_error_string.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(cell_inheritance_string.size != 0) - { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - cell_flags |= UI_BoxFlag_DrawBackground; - } - else - { - palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); - } - } - ProfEnd(); - - //- rjf: determine if cell needs code styling - B32 cell_is_code = !col->is_non_code; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - { - cell_is_code = 1; - if(row->member != 0 && row->member->pretty_name.size != 0 && flags & RD_WatchViewFlag_PrettyNameMembers) - { - cell_is_code = 0; - } - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - { - if(cell_type->flags & E_TypeFlag_IsCodeText) - { - cell_is_code = 1; - } - else if(cell_type->flags & E_TypeFlag_IsPathText || - cell_type->flags & E_TypeFlag_IsPlainText) - { - cell_is_code = 0; - } - }break; - } - - //- rjf: build cell - UI_Signal sig = {0}; - ProfScope("build cell") - UI_Palette(palette) - UI_TableCell - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(cell_is_code ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) - { - ui_set_next_flags(ui_top_flags() | cell_flags); - - // rjf: cell has errors? -> build error box - if(cell_error_string.size != 0) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_row_%I64x", x, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_error_string); - } - } - - // rjf: cell has hook? -> build ui by calling hook - else if(cell_ui_hook != 0) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash); - UI_Parent(box) - { - String8 row_expr = e_string_from_expr(scratch.arena, row->expr); - cell_ui_hook(row_expr, cell_ui_params, r2f32p(x_px, 0, x_px + col->pct*dim_2f32(rect).x, row_height_px)); - } - sig = ui_signal_from_box(box); - } - - // rjf: cell has icon? build icon - else if(cell_icon != RD_IconKind_Null) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###cell_%I64x", row_hash); - UI_Parent(box) RD_Font(RD_FontSlot_Icons) UI_WidthFill UI_TextAlignment(UI_TextAlign_Center) - { - ui_label(rd_icon_kind_text_table[cell_icon]); - } - sig = ui_signal_from_box(box); - } - - // rjf: build cell line edit - else - { - sig = rd_line_editf((RD_LineEditFlag_CodeContents*(!!cell_is_code)| - RD_LineEditFlag_NoBackground| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_DisableEdit*(!cell_can_edit)| - RD_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderPlaceholder*(x == 0 && row_depth==0 && col->kind == RD_WatchViewColumnKind_Expr)| - RD_LineEditFlag_ExpanderSpace*(x == 0 && row_depth!=0 && col->kind == RD_WatchViewColumnKind_Expr)), - x == 0 ? row_depth : 0, - &cell_matches, - &cell_edit_state->cursor, &cell_edit_state->mark, cell_edit_state->input_buffer, sizeof(cell_edit_state->input_buffer), &cell_edit_state->input_size, &next_row_expanded, - cell_pre_edit_string, - "%S###%I64x_row_%I64x", cell_ghost_text, x, row_hash); - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); - } - } - } - - //- rjf: handle interactions - { - // rjf: single-click -> move selection here - if(ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: double-click actions - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) - { - ui_kill_action(); - - // rjf: has callstack info? -> select unwind - if(row_info.callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info.callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info.callstack_unwind_index, - .inline_depth = row_info.callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(cell_can_edit) - { - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: cannot edit, has addr info? -> go to address - else if(row_kind == RD_WatchViewRowKind_Normal && - (col->kind == RD_WatchViewColumnKind_Value || - col->kind == RD_WatchViewColumnKind_Member) && - cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) - { - U64 vaddr = cell_eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - } - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } - } - } - - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_inheritance_string.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_inheritance_string); - } - } - - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_error_tooltip_string.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_error_tooltip_string); - } - } - - //- rjf: bump x pixel coordinate - x_px += col->pct*dim_2f32(rect).x; - - //- 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_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); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && x == 0 && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 ext = {0}; - switch(t->expr->kind) - { - default: - { - if(t->expr->string.size != 0) - { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: - { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; - } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); - } - } - ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) - { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); - } - } - } - } - } - }break; - } -#endif - ////////////////////// //- rjf: commit expansion state changes // From 96afe943c20ca5e96939fc4af019dd9067f98e95 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 16:54:48 -0800 Subject: [PATCH 100/755] multi-row-topology watch window column dragging & saving to cfg tree --- src/raddbg/raddbg_views.c | 180 ++++++++++++++++++++++++++++++++++++-- src/raddbg/raddbg_views.h | 2 + 2 files changed, 176 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index eb9996db..3a8c5f6f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -812,6 +812,10 @@ rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell { RD_WatchCell *cell = rd_watch_cell_list_push(arena, list); MemoryCopyStruct(cell, params); + if(cell->pct == 0) + { + cell->pct = cell->default_pct; + } cell->next = 0; return cell; } @@ -1021,17 +1025,31 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: for meta-cfg evaluation spaces, only do expr/value else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.75f); + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); +#undef take_pct } // rjf: default cells else { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .pct = 0.35f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .pct = 0.15f); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .pct = 0.25f); + info.cell_style_key = str8_lit("normal"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); +#undef take_pct } } @@ -2508,6 +2526,156 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } + //////////////////////// + //- rjf: build boundaries + // + ProfScope("build boundaries") + { + U64 idx = 0; + U64 boundary_start_idx = 0; + EV_Row *last_row = 0; + RD_WatchRowInfo *last_row_info = 0; + for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) + { + //- rjf: determine if this row breaks the topology + B32 is_new_topology = (row_node == 0); + if(row_node != 0 && last_row_info != 0) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[idx]; + for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + is_new_topology = 1; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + is_new_topology = 1; + break; + } + } + } + + //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations + if(is_new_topology) + { + EV_Row *row = last_row; + RD_WatchRowInfo *row_info = last_row_info; + F32 row_width_px = (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + if(row_info != 0) + { + U64 row_hash = ev_hash_from_key(row->key); + F32 cell_x_px = 0; + U64 cell_idx = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) + { + U64 cell_id = rd_id_from_watch_cell(cell); + F32 cell_width_px = cell->px + cell->pct * row_width_px; + F32 next_cell_x_px = cell_x_px + cell_width_px; + { + Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.2f, + boundary_start_idx*row_height_px, + next_cell_x_px + ui_top_font_size()*0.2f, + idx*row_height_px); + UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig)) + { + typedef struct DragData DragData; + struct DragData + { + F32 min_pct; + F32 max_pct; + }; + if(ui_pressed(sig)) + { + DragData drag_data = {cell->pct, cell->next->pct}; + ui_store_drag_struct(&drag_data); + } + DragData *drag_data = ui_get_drag_struct(DragData); + F32 min_pct__pre = drag_data->min_pct; + F32 max_pct__pre = drag_data->max_pct; + F32 min_px__pre = min_pct__pre*row_width_px; + F32 max_px__pre = max_pct__pre*row_width_px; + F32 min_px__post = min_px__pre + ui_drag_delta().x; + F32 max_px__post = max_px__pre - ui_drag_delta().x; + F32 min_pct__post = min_px__post/row_width_px; + F32 max_pct__post = max_px__post/row_width_px; + if(min_pct__post < 0.05f) + { + min_pct__post = 0.05f; + max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; + } + if(max_pct__post < 0.05f) + { + max_pct__post = 0.05f; + min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; + } + if(ui_double_clicked(sig)) + { + min_pct__post = cell->default_pct; + max_pct__post = cell->next->default_pct; + ui_kill_action(); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); + RD_Cfg *min_cfg = &rd_nil_cfg; + RD_Cfg *max_cfg = &rd_nil_cfg; + { + RD_Cfg *pct_child = style->first; + U64 c_idx = 0; + for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) + { + if(pct_child == &rd_nil_cfg) + { + pct_child = rd_cfg_newf(style, "%f", c->pct); + } + if(c_idx == cell_idx) + { + min_cfg = pct_child; + } + if(c_idx == cell_idx+1) + { + max_cfg = pct_child; + } + pct_child = pct_child->next; + } + rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); + rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); + cell->pct = min_pct__post; + cell->next->pct = max_pct__post; + } + } + } + } + cell_x_px = next_cell_x_px; + } + } + boundary_start_idx = idx; + } + + //- rjf: advance + if(row_node == 0) + { + break; + } + else + { + last_row = &row_node->row; + last_row_info = &row_infos[idx]; + } + } + } + //////////////////////// //- rjf: build table // diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 456075d4..acc769af 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -58,6 +58,7 @@ struct RD_WatchCell RD_WatchCellKind kind; String8 string; DR_FStrList fstrs; + F32 default_pct; F32 pct; F32 px; }; @@ -82,6 +83,7 @@ struct RD_WatchRowInfo CTRL_Entity *callstack_thread; U64 callstack_unwind_index; U64 callstack_inline_depth; + String8 cell_style_key; RD_WatchCellList cells; RD_ViewUIRule *view_ui_rule; E_Expr *view_ui_tag; From f165eb7b8ef35643338083e83de4b0b2f269f2d2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 16:58:24 -0800 Subject: [PATCH 101/755] recompute row infos on watch column drag --- src/raddbg/raddbg_views.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3a8c5f6f..5740afaf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2529,6 +2529,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////////// //- rjf: build boundaries // + B32 cell_pcts_are_dirty = 0; ProfScope("build boundaries") { U64 idx = 0; @@ -2651,8 +2652,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); - cell->pct = min_pct__post; - cell->next->pct = max_pct__post; + cell_pcts_are_dirty = 1; } } } @@ -2676,6 +2676,19 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } + //////////////////////// + //- rjf: if cell widths are dirty -> recompute row infos + // + if(cell_pcts_are_dirty) + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + //////////////////////// //- rjf: build table // From 374317abd75dd40cafde534fcce4b7a3b6babfbe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 17:39:17 -0800 Subject: [PATCH 102/755] call stack info extraction in watch row building; special style for call stack frames --- src/raddbg/raddbg_core.c | 6 ++-- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 65 ++++++++++++++++++++++++++++++--------- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 41cf1080..ca48aee6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8630,7 +8630,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(thread) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); result.irtree_and_type.mode = E_Mode_Offset; } @@ -8734,7 +8734,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(target) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_const_u(arena, cfg->id)); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCfgCollection), e_irtree_const_u(arena, cfg->id)); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); result.irtree_and_type.mode = E_Mode_Offset; } @@ -12487,6 +12487,7 @@ rd_frame(void) String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), @@ -12564,6 +12565,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7e834b1b..50a44504 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -83,6 +83,7 @@ enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, + RD_EvalSpaceKind_MetaCfgCollection, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaCmd, }; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5740afaf..14e04aa8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -908,6 +908,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) EV_Key key = row->key; E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); + E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); + E_TypeKey block_type_key = block_eval.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + E_Type *block_type = e_type_from_key__cached(block_type_key); // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); @@ -934,27 +938,43 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine cfg group name / parent + // rjf: determine call stack info + if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && block_type_kind == E_TypeKind_Set) { - E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); - E_TypeKey block_type_key = block_eval.type_key; - E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Set) + CTRL_Handle handle = {0}; + handle.machine_id = (CTRL_MachineID)block_eval.value.u128.u64[0]; + handle.dmn_handle.u64[0] = (U64)block_eval.value.u128.u64[1]; + CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + if(entity->kind == CTRL_EntityKind_Thread) { - info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); - E_Type *block_type = e_type_from_key__cached(block_type_key); - String8 singular_name = rd_singular_from_code_name_plural(block_type->name); - if(singular_name.size != 0) + info.callstack_thread = entity; + U64 frame_num = block->lookup_rule->num_from_id(key.child_id, block->lookup_rule_user_data); + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_process_from_entity(entity), &unwind); + if(1 <= frame_num && frame_num <= call_stack.count) { - info.group_cfg_name = singular_name; - } - else - { - info.group_cfg_name = block_type->name; + CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; + info.callstack_unwind_index = f->unwind_count; + info.callstack_inline_depth = f->inline_depth; } } } + // rjf: determine cfg group name / parent + if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) + { + info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); + String8 singular_name = rd_singular_from_code_name_plural(block_type->name); + if(singular_name.size != 0) + { + info.group_cfg_name = singular_name; + } + else + { + info.group_cfg_name = block_type->name; + } + } + // rjf: determine row's cfg if(info.group_cfg_name.size != 0) { @@ -1023,7 +1043,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1036,6 +1056,20 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } + // rjf: callstack frames + else if(info.callstack_thread != &ctrl_entity_nil) + { + info.cell_style_key = str8_lit("call_stack_frame"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.35f, .pct = take_pct()); +#undef take_pct + } + // rjf: default cells else { @@ -1239,6 +1273,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { String8 fancy_name = rd_display_from_code_name(member_name); From 4dfa4a120f2bedee24d2719b95bb08d0cdc92f66 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 17:50:18 -0800 Subject: [PATCH 103/755] re-add special-case watch cell style for call stack frame selection --- src/raddbg/raddbg_views.c | 21 ++++++++++++++++++++- src/raddbg/raddbg_views.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 14e04aa8..8f9f509c 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1065,8 +1065,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.30f, .pct = take_pct()); #undef take_pct } @@ -3010,6 +3011,24 @@ RD_VIEW_UI_FUNCTION_DEF(watch) sig = ui_signal_from_box(box); } + // rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + else if(cell->kind == RD_WatchCellKind_CallStackFrame) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + if(row_info->callstack_unwind_index == rd_regs()->unwind_count && + row_info->callstack_inline_depth == rd_regs()->inline_depth) + { + UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) + { + RD_Font(RD_FontSlot_Icons) + UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_ctrl_entity(row_info->callstack_thread))) + ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); + } + } + } + // rjf: build cell line edit else RD_Font(cell_info.is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index acc769af..b2b65a13 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -48,6 +48,7 @@ typedef enum RD_WatchCellKind RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook RD_WatchCellKind_Button, // a fancy button dedicated to the entire row's evaluation, used for listers/etc. + RD_WatchCellKind_CallStackFrame, // a slot for a yellow arrow, to show call stack frame selection } RD_WatchCellKind; From c31b15524a91646a95e058ec077d26882edc0841 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 12 Feb 2025 17:53:41 -0800 Subject: [PATCH 104/755] ensure threads match before visualizing call stack frame selection --- src/raddbg/raddbg_views.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8f9f509c..bbfe81cb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3016,8 +3016,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); sig = ui_signal_from_box(box); - if(row_info->callstack_unwind_index == rd_regs()->unwind_count && - row_info->callstack_inline_depth == rd_regs()->inline_depth) + if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && + row_info->callstack_unwind_index == rd_base_regs()->unwind_count && + row_info->callstack_inline_depth == rd_base_regs()->inline_depth) { UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) { From 50b195deb37555d665ff16a05c8bbf0122dec911 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 06:51:50 -0800 Subject: [PATCH 105/755] eliminate member-expr-extension irtree/oplist/etc. recomputations; just convert lhs irtree to bytecode and attach that to new expr as a leaf bytecode --- src/eval/eval_ir.c | 24 ++++++++++++++++++++++-- src/eval/eval_ir.h | 3 +++ src/eval/eval_parse.c | 18 ------------------ src/eval/eval_parse.h | 2 -- src/raddbg/raddbg_core.c | 4 ++-- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index f87ee218..9a2204c3 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -481,7 +481,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) U64 member_idx = idx + read_range.min; String8 member_name = (struct_type->members ? struct_type->members[member_idx].name : struct_type->enum_vals ? struct_type->enum_vals[member_idx].name : str8_lit("")); - exprs[idx] = e_expr_ref_member_access(arena, lhs, member_name); + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); } } @@ -582,7 +582,7 @@ E_IRGEN_FUNCTION_DEF(slice) U64 count = 0; if(count_member != 0) { - E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name); + E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, &irtree, count_member->name); E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr); E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval); count = count_member_value_eval.value.u64; @@ -2283,6 +2283,26 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) return result; } +//- rjf: leaf-bytecode expression extensions + +internal E_Expr * +e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); + E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); + E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); + lhs_bytecode->string = lhs->string; + lhs_bytecode->space = lhs->space; + lhs_bytecode->mode = lhs_irtree->mode; + lhs_bytecode->type_key = lhs_irtree->type_key; + lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + rhs->string = push_str8_copy(arena, member_name); + e_expr_push_child(root, lhs_bytecode); + e_expr_push_child(root, rhs); + return root; +} + //////////////////////////////// //~ rjf: IRified Expression Cache diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index bc642f31..2d97568d 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -420,6 +420,9 @@ internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root); internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); +//- rjf: leaf-bytecode expression extensions +internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name); + //////////////////////////////// //~ rjf: IRified Expression Cache diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index e6509523..7f1e4ef5 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -698,15 +698,6 @@ e_expr_ref(Arena *arena, E_Expr *ref) return expr; } -internal E_Expr * -e_expr_ref_addr(Arena *arena, E_Expr *rhs) -{ - E_Expr *expr = e_push_expr(arena, E_ExprKind_Address, 0); - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(expr, rhs_ref); - return expr; -} - internal E_Expr * e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name) { @@ -752,15 +743,6 @@ e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs) return root; } -internal E_Expr * -e_expr_ref_bswap(Arena *arena, E_Expr *rhs) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_ByteSwap, 0); - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(root, rhs_ref); - return root; -} - internal E_Expr * e_expr_copy(Arena *arena, E_Expr *src) { diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 75c6d399..d525a155 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -269,12 +269,10 @@ internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); internal void e_expr_push_tag(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); -internal E_Expr *e_expr_ref_addr(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name); internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index); 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); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ca48aee6..6819994c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8650,7 +8650,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(thread) for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) { U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_ref_member_access(arena, lhs, str8_lit("call_stack")); + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("call_stack")); } scratch_end(scratch); } @@ -8754,7 +8754,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(target) for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) { U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_ref_member_access(arena, lhs, str8_lit("environment")); + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("environment")); } scratch_end(scratch); } From 863d98c43e18aa5d95cb71bb1197557dc204290c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 08:13:53 -0800 Subject: [PATCH 106/755] do the same reuse of the computed irtree for array-index expr extensions --- src/eval/eval_ir.c | 55 ++++++++++++++++++- src/eval/eval_ir.h | 3 + src/eval/eval_parse.c | 24 -------- src/eval/eval_parse.h | 2 - .../eval_visualization_core.c | 2 +- src/raddbg/raddbg_core.c | 9 ++- 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9a2204c3..6f6c5544 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -491,7 +491,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs[idx] = e_expr_ref_array_index(arena, lhs, idx_range.min + idx); + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx_range.min + idx); } } } @@ -2291,7 +2291,7 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); - lhs_bytecode->string = lhs->string; + lhs_bytecode->string = e_string_from_expr(arena, lhs); lhs_bytecode->space = lhs->space; lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; @@ -2303,6 +2303,57 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre return root; } +internal E_Expr * +e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); + E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); + E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); + lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->space = lhs->space; + lhs_bytecode->mode = lhs_irtree->mode; + lhs_bytecode->type_key = lhs_irtree->type_key; + lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0); + rhs->value.u64 = index; + e_expr_push_child(root, lhs_bytecode); + e_expr_push_child(root, rhs); + return root; +} + +internal E_Expr * +e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0); + E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); + E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); + rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->space = rhs->space; + rhs_bytecode->mode = rhs_irtree->mode; + rhs_bytecode->type_key = rhs_irtree->type_key; + rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); + e_expr_push_child(root, rhs_bytecode); + return root; +} + +internal E_Expr * +e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key) +{ + E_Expr *root = e_push_expr(arena, E_ExprKind_Cast, 0); + E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); + E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); + rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->space = rhs->space; + rhs_bytecode->mode = rhs_irtree->mode; + rhs_bytecode->type_key = rhs_irtree->type_key; + rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); + E_Expr *lhs = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + lhs->type_key = type_key; + e_expr_push_child(root, lhs); + e_expr_push_child(root, rhs_bytecode); + return root; +} + //////////////////////////////// //~ rjf: IRified Expression Cache diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 2d97568d..2e1d451f 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -422,6 +422,9 @@ internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); //- rjf: leaf-bytecode expression extensions internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name); +internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index); +internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); +internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); //////////////////////////////// //~ rjf: IRified Expression Cache diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 7f1e4ef5..78770336 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -698,30 +698,6 @@ e_expr_ref(Arena *arena, E_Expr *ref) return expr; } -internal E_Expr * -e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *lhs_ref = e_expr_ref(arena, lhs); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); - rhs->string = push_str8_copy(arena, member_name); - e_expr_push_child(root, lhs_ref); - e_expr_push_child(root, rhs); - return root; -} - -internal E_Expr * -e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); - E_Expr *lhs_ref = e_expr_ref(arena, lhs); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0); - rhs->value.u64 = index; - e_expr_push_child(root, lhs_ref); - e_expr_push_child(root, rhs); - return root; -} - internal E_Expr * e_expr_ref_deref(Arena *arena, E_Expr *rhs) { diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index d525a155..4ba88b90 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -269,8 +269,6 @@ internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); internal void e_expr_push_tag(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); -internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name); -internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index); 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_copy(Arena *arena, E_Expr *src); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 226d1a24..9dc14c77 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -427,7 +427,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); - expr = e_expr_ref_cast(arena, ptr_to_derived_type_key, expr); + expr = e_expr_irext_cast(arena, ptr_to_derived_type_key); } } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6819994c..10a9af61 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8544,17 +8544,19 @@ E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) Rng1U64 cmds_idx_range = accel->cmds_idx_range; Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; U64 dst_idx = 0; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); // rjf: fill commands { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")); + E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - exprs[dst_idx] = e_expr_ref_array_index(arena, commands, (U64)cmd_kind-1); + exprs[dst_idx] = e_expr_irext_array_index(arena, commands, &commands_irtree, (U64)cmd_kind-1); } } @@ -8564,7 +8566,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) U64 read_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { - exprs[dst_idx] = e_expr_ref_array_index(arena, lhs, idx + read_range.min - cfgs_idx_range.min); + exprs[dst_idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx + read_range.min - cfgs_idx_range.min); } } } @@ -8813,6 +8815,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(environment) E_LOOKUP_RANGE_FUNCTION_DEF(environment) { RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); Rng1U64 legal_idx_range = r1u64(0, cfgs->count); Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); U64 read_range_count = dim_1u64(read_range); @@ -8821,7 +8824,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(environment) U64 cfg_idx = read_range.min + idx; if(cfg_idx < cfgs->count) { - exprs[idx] = e_expr_ref_array_index(arena, lhs, cfg_idx); + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); } } } From fba0053e9bd19123fb0e807f5ff7829608bbe640 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 08:21:48 -0800 Subject: [PATCH 107/755] preserve ambiguous path rendering --- src/raddbg/raddbg_core.c | 119 ++++++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 13 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 10a9af61..391c27b5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1222,14 +1222,14 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(icon_kind != RD_IconKind_Null) { dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push warning icon for command-line entities if(is_from_command_line) { dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push view title, if from window, and no file path @@ -1239,7 +1239,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(view_display_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, view_display_name); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } } @@ -1248,7 +1248,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(label_string.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } @@ -1256,27 +1256,119 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(collection_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, collection_name); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } + + //- rjf: query is file path - do specific file name strings else if(file_path.size != 0) { - dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(file_path)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + // rjf: compute disambiguated file name + String8List qualifiers = {0}; + String8 file_name = str8_skip_last_slash(file_path); + if(rd_state->ambiguous_path_slots_count != 0) + { + U64 hash = d_hash_from_string__case_insensitive(file_name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + { + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) + { + if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } + } + } + if(node != 0 && node->paths.node_count > 1) + { + // rjf: get all colliding paths + String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); + + // rjf: get all reversed path parts for each collision + String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); + for EachIndex(idx, collisions.count) + { + String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); + } + } + + // rjf: get the search path & its reversed parts + String8List parts = str8_split_path(scratch.arena, file_path); + String8List parts_reversed = {0}; + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &parts_reversed, n->string); + } + + // rjf: iterate all collision part reversed lists, in lock-step with + // search path; disqualify until we only have one path remaining; gather + // qualifiers + { + U64 num_collisions_left = collisions.count; + String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); + for EachIndex(idx, collisions.count) + { + collision_nodes[idx] = collision_parts_reversed[idx].first; + } + for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) + { + B32 part_is_qualifier = 0; + for EachIndex(idx, collisions.count) + { + if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) + { + collision_nodes[idx] = 0; + num_collisions_left -= 1; + part_is_qualifier = 1; + } + else if(collision_nodes[idx] != 0) + { + collision_nodes[idx] = collision_nodes[idx]->next; + } + } + if(part_is_qualifier) + { + str8_list_push_front(scratch.arena, &qualifiers, n->string); + } + } + } + } + } + + // rjf: push qualifiers + for(String8Node *n = qualifiers.first; n != 0; n = n->next) + { + String8 string = push_str8f(arena, "<%S> ", n->string); + dr_fstrs_push_new(arena, &result, ¶ms, string, .color = secondary_color); + } + + // rjf: push file name + dr_fstrs_push_new(arena, &result, ¶ms, push_str8_copy(arena, str8_skip_last_slash(file_path))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } + + //- rjf: cfg has expression attached -> use that else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) { dr_fstrs_push_new(arena, &result, ¶ms, expr_string); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } //- rjf: push text location if(loc.file_path.size != 0) { - String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", loc.file_path, loc.pt.line, loc.pt.column); + String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", str8_skip_last_slash(loc.file_path), loc.pt.line, loc.pt.column); dr_fstrs_push_new(arena, &result, ¶ms, location_string); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } @@ -1284,7 +1376,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(target.exe.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(target.exe)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } @@ -1292,7 +1384,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(target.args.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, target.args); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push conditions @@ -1300,9 +1392,10 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; if(condition.size != 0) { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code)); DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); dr_fstrs_concat_in_place(&result, &fstrs); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } } @@ -1310,7 +1403,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(is_disabled) { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Disabled)")); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push hit count From 6498666619478fa35687e639089c399f4fc73571 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 09:26:05 -0800 Subject: [PATCH 108/755] begin moving per-row style info to per-cell style info --- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 52 +++++++++++++++++++++++---------------- src/raddbg/raddbg_views.h | 4 +-- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 391c27b5..b8b999ce 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12691,6 +12691,7 @@ rd_frame(void) E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmdCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 50a44504..6e2b40c0 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -84,6 +84,7 @@ enum RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaCfgCollection, + RD_EvalSpaceKind_MetaCmdCollection, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaCmd, }; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index bbfe81cb..2b42fab9 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1004,30 +1004,29 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: singular button for top-level cfg group elements - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) + // rjf: singular button for cfgs + else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || + (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, info.group_cfg_child, ui_top_palette()->text_weak, ui_top_font_size())); - } - - // rjf: singular button for top-level cfg roots - else if(row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, evalled_cfg, ui_top_palette()->text_weak, ui_top_font_size())); + RD_Cfg *cfg = evalled_cfg; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular button for entities else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f); } // rjf: singular button for commands - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) && + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd && + row_eval_matches_group) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular cell for view ui @@ -1221,9 +1220,14 @@ internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { RD_WatchRowCellInfo result = {0}; + + //- rjf: fill basics/defaults result.view_ui_rule = &rd_nil_view_ui_rule; result.view_ui_tag = &e_expr_nil; result.fstrs = cell->fstrs; + result.is_button = cell->is_button; + + //- rjf: do per-kind fills switch(cell->kind) { default:{}break; @@ -1236,6 +1240,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.can_edit = 1; } + result.eval = e_eval_from_expr(arena, row->expr); result.string = row->string; if(result.string.size == 0) { @@ -1269,7 +1274,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla }break; case E_ExprKind_MemberAccess: { - E_Eval row_eval = e_eval_from_expr(arena, row->expr); + E_Eval row_eval = result.eval; String8 member_name = e_string_from_expr(arena, notable_expr->last); B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); @@ -1342,6 +1347,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.eval = e_eval_from_expr(scratch.arena, root_expr); result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); + scratch_end(scratch); }break; @@ -1360,13 +1366,18 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.view_ui_rule = row_info->view_ui_rule; result.view_ui_tag = row_info->view_ui_tag; }break; - - //- rjf: button cells - case RD_WatchCellKind_Button: - { - result.is_button = 1; - }break; } + + //- rjf: adjust style based on evaluation +#if 0 + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + RD_Cfg *cfg = rd_cfg_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size()); + result.is_button = 1; + } +#endif + return result; } @@ -2209,7 +2220,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { default:{}break; case RD_WatchCellKind_Expr: - case RD_WatchCellKind_Button: { RD_Cfg *cfg = row_info.group_cfg_child; if(cfg != &rd_nil_cfg) @@ -3050,7 +3060,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.edit_string_size_out = &cell_edit_state->input_size; line_edit_params.expanded_out = &next_row_expanded; line_edit_params.pre_edit_value = cell_info.string; - line_edit_params.fstrs = cell_info.fstrs; + line_edit_params.fstrs = cell_info.fstrs; } sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); #if 0 // TODO(rjf): @cfg diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index b2b65a13..037a45e9 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -47,7 +47,6 @@ typedef enum RD_WatchCellKind RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook - RD_WatchCellKind_Button, // a fancy button dedicated to the entire row's evaluation, used for listers/etc. RD_WatchCellKind_CallStackFrame, // a slot for a yellow arrow, to show call stack frame selection } RD_WatchCellKind; @@ -59,6 +58,7 @@ struct RD_WatchCell RD_WatchCellKind kind; String8 string; DR_FStrList fstrs; + B32 is_button; F32 default_pct; F32 pct; F32 px; @@ -96,8 +96,8 @@ struct RD_WatchRowCellInfo E_Eval eval; String8 string; DR_FStrList fstrs; - B32 is_non_code; B32 is_button; + B32 is_non_code; B32 can_edit; B32 is_errored; String8 error_tooltip; From 18010db753d9b22d05e54f8d7b3c86c76268e0dc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 11:20:10 -0800 Subject: [PATCH 109/755] per-row command cells in watch windows when evaluating cfgs; table-drive per-collection commands --- src/raddbg/generated/raddbg.meta.c | 24 +- src/raddbg/generated/raddbg.meta.h | 1 - src/raddbg/raddbg.mdesk | 33 +-- src/raddbg/raddbg_core.c | 48 +--- src/raddbg/raddbg_core.h | 14 -- src/raddbg/raddbg_views.c | 387 +++++------------------------ src/raddbg/raddbg_views.h | 11 - src/raddbg/raddbg_widgets.c | 4 + 8 files changed, 108 insertions(+), 414 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8480458c..7e27408a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -226,8 +226,8 @@ RD_VocabInfo rd_vocab_info_table[277] = {str8_lit_comp("set_columns"), str8_lit_comp(""), str8_lit_comp("Set Columns"), str8_lit_comp(""), RD_IconKind_Thumbnails}, {str8_lit_comp("toggle_address_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, {str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, -{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), str8_lit_comp(""), RD_IconKind_Trash}, {str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, @@ -287,16 +287,16 @@ RD_VocabInfo rd_vocab_info_table[277] = RD_NameSchemaInfo rd_name_schema_info_table[10] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n"), str8_lit_comp("")}, -{str8_lit_comp("target"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n"), str8_lit_comp("launch_and_run,launch_and_init,select_cfg,remove_cfg")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("x:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n"), str8_lit_comp("enable_cfg,remove_cfg")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("x:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n"), str8_lit_comp("remove_cfg")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("x:{'source':path, 'dest':path}"), str8_lit_comp("remove_cfg")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("x:{'source':code_string, 'dest':code_string}"), str8_lit_comp("remove_cfg")}, -{str8_lit_comp("machine"), str8_lit_comp("x:{'frozen':bool, 'label':code_string}"), str8_lit_comp("")}, -{str8_lit_comp("process"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, -{str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}"), str8_lit_comp("")}, -{str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}"), str8_lit_comp("")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'frozen':bool, 'label':code_string}")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}")}, +{str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}")}, }; Rng1U64 rd_reg_slot_range_table[38] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index a153b1eb..c5caebe9 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -450,7 +450,6 @@ struct RD_NameSchemaInfo { String8 name; String8 schema; -String8 cmd_names; }; typedef struct RD_Regs RD_Regs; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 345d81dc..36cd78a5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -105,7 +105,7 @@ RD_VocabTable: //////////////////////////////// //~ rjf: Schemas -@table(name schema cmd_names) RD_SchemaTable: +@table(name schema) RD_SchemaTable: { //- rjf: settings { @@ -138,7 +138,10 @@ RD_VocabTable: //- rjf: targets { target, - ```x: + ``` + @commands(launch_and_run, launch_and_init, select_cfg, remove_cfg) + @collection_commands(add_target) + x: { 'label': code_string, 'executable': path, @@ -151,13 +154,15 @@ RD_VocabTable: 'debug_subprocesses': bool, } ```, - `launch_and_run,launch_and_init,select_cfg,remove_cfg`, } //- rjf: breakpoints { breakpoint, - ```x: + ``` + @commands(enable_cfg, remove_cfg) + @collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint) + x: { 'label': code_string, 'condition': code_string, @@ -166,34 +171,33 @@ RD_VocabTable: 'disabled': bool, } ```, - `enable_cfg,remove_cfg`, } //- rjf: watch pins { watch_pin, - ```x: + ``` + @commands(remove_cfg) + @collection_commands(add_watch_pin) + x: { 'expression': code_string, 'view_rule': code_string, 'location': location, } ```, - `remove_cfg`, } //- rjf: file path maps { file_path_map, - ```x:{'source':path, 'dest':path}```, - `remove_cfg`, + ```@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}```, } //- rjf: auto view rules { auto_view_rule, - ```x:{'source':code_string, 'dest':code_string}```, - `remove_cfg`, + ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}```, } //- rjf: machines @@ -225,12 +229,11 @@ RD_VocabTable: { `String8 name`; `String8 schema`; - `String8 cmd_names`; } @data(RD_NameSchemaInfo) rd_name_schema_info_table: { - @expand(RD_SchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.cmd_names)")}` + @expand(RD_SchemaTable a) `{str8_lit_comp("$(a.name)"), str8_lit_comp("$(a.schema)")}` } //////////////////////////////// @@ -501,8 +504,8 @@ RD_CmdTable: // | | | | {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general config operations - {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } - {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b8b999ce..d80d8c21 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1393,8 +1393,11 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(condition.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code)); - DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); - dr_fstrs_concat_in_place(&result, &fstrs); + RD_Font(RD_FontSlot_Code) + { + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); + dr_fstrs_concat_in_place(&result, &fstrs); + } dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } } @@ -5732,7 +5735,7 @@ rd_window_frame(void) //- rjf: center column UI_PrefWidth(ui_children_sum(1.f)) UI_Row - UI_PrefWidth(ui_em(2.25f, 1)) + UI_PrefWidth(ui_em(2.5f, 1)) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.85f) { @@ -8577,20 +8580,11 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name);\ String8List cmds_list = {0}; - // TODO(rjf): @cfg hack - probably want to table-drive this - if(str8_match(cfg_name, str8_lit("target"), 0)) + MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) { - str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - else if(str8_match(cfg_name, str8_lit("breakpoint"), 0)) - { - str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddBreakpoint].string); - str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddAddressBreakpoint].string); - str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddFunctionBreakpoint].string); - } - else if(str8_match(cfg_name, str8_lit("watch_pin"), 0)) - { - str8_list_push(arena, &cmds_list, rd_cmd_kind_info_table[RD_CmdKind_AddWatchPin].string); + str8_list_push(arena, &cmds_list, cmd->string); } RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); @@ -11082,7 +11076,6 @@ rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary //- rjf: push icon if(info->icon_kind != RD_IconKind_Null) { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -13163,27 +13156,6 @@ rd_frame(void) rd_cfg_release(recent_projects.last->v); } } - - //- TODO(rjf): @cfg set up debugging config state - if(kind == RD_CmdKind_OpenUser) - { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - { - RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("current_thread")); - } - { - RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("targets[0]")); - } - { - RD_Cfg *watch = rd_cfg_new(user, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, str8_lit("basics")); - } - } }break; //- rjf: writing config changes diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 6e2b40c0..39c4a7f9 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -889,20 +889,6 @@ read_only global RD_ViewUIRule rd_nil_view_ui_rule = RD_VIEW_UI_FUNCTION_NAME(null), }; -#if 0 // TODO(rjf): @cfg -read_only global RD_ViewRuleInfo rd_nil_view_rule_info = -{ - {0}, - {0}, - {0}, - {0}, - RD_IconKind_Null, - 0, - EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), - RD_VIEW_RULE_UI_FUNCTION_NAME(null) -}; -#endif - read_only global RD_ViewState rd_nil_view_state = { &rd_nil_view_state, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2b42fab9..dcbef461 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1004,15 +1004,46 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: singular button for cfgs + // rjf: cfg rows else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) { RD_Cfg *cfg = evalled_cfg; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); + MD_Node *schema = rd_schema_from_name(arena, cfg->string); + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); + for MD_EachNode(cmd, cmds_root->first) + { + String8 cmd_name = cmd->string; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + switch(cmd_kind) + { + default:{}break; + case RD_CmdKind_EnableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DisableCfg; + } + }break; + case RD_CmdKind_DisableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_EnableCfg; + } + }break; + } + if(cmd_kind != RD_CmdKind_Null) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); + } + } } - // rjf: singular button for entities + // rjf: entity rows else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f); @@ -1042,7 +1073,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection) { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1093,127 +1127,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) return info; } -//- rjf: row -> context info - -#if 0 // TODO(rjf): @cfg -internal RD_WatchViewRowInfo -rd_watch_view_row_info_from_row(EV_Row *row) -{ - RD_WatchViewRowInfo info = {0}; - { - Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); - - // rjf: unpack block/key coordinates - EV_Block *block = row->block; - EV_Key key = row->key; - - // rjf: unpack parent block's expression - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); - E_Type *type = e_type_from_key(scratch.arena, irtree.type_key); - - // rjf: evaluate row - E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr); - - // rjf: determine collection entity kind, if any - RD_EntityKind collection_entity_kind = RD_EntityKind_Nil; - CTRL_EntityKind collection_ctrl_entity_kind = CTRL_EntityKind_Null; - for EachElement(idx, rd_collection_name_table) - { - if(str8_match(type->name, rd_collection_name_table[idx], 0)) - { - collection_entity_kind = rd_collection_entity_kind_table[idx]; - collection_ctrl_entity_kind = rd_collection_ctrl_entity_kind_table[idx]; - break; - } - } - - // rjf: extract frontend entity, if any - RD_Entity *entity = &rd_nil_entity; - if(collection_entity_kind != RD_EntityKind_Nil) - { - entity = rd_entity_from_id(key.child_id); - } - - // rjf: extract control entity, if any - CTRL_Entity *ctrl_entity = &ctrl_entity_nil; - if(collection_ctrl_entity_kind != CTRL_EntityKind_Null && block->expand_view_rule_info_user_data != 0) - { - U64 block_relative_num = block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, block->expand_view_rule_info_user_data); - RD_CtrlEntityExpandAccel *accel = block->expand_view_rule_info_user_data; - if(1 <= block_relative_num && block_relative_num <= accel->entities.count) - { - ctrl_entity = accel->entities.v[block_relative_num-1]; - } - } - else if(row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - ctrl_entity = rd_ctrl_entity_from_eval_space(row_eval.space); - } - - // rjf: extract callstack thread, if any - CTRL_Entity *thread = &ctrl_entity_nil; - for(E_Expr *expr = block->expr, *next = &e_expr_nil; expr != &e_expr_nil; expr = next) - { - next = &e_expr_nil; - switch(expr->kind) - { - default:{}break; - case E_ExprKind_Ref:{next = expr->ref;}break; - case E_ExprKind_Cast:{next = expr->last;}break; - case E_ExprKind_MemberAccess:{next = expr->first;}break; - case E_ExprKind_ArrayIndex:{next = expr->first;}break; - case E_ExprKind_LeafIdent: - { - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - if(entity->kind == CTRL_EntityKind_Thread) - { - thread = entity; - goto done; - } - }break; - } - } - done:; - - // rjf: extract callstack row information, if any - U64 unwind_count = 0; - U64 inline_depth = 0; - if(thread != &ctrl_entity_nil) - { - U64 block_relative_num = block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, block->expand_view_rule_info_user_data); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process), &base_unwind); - U64 frame_num = 1; - for(U64 base_frame_idx = 0; base_frame_idx < rich_unwind.concrete_frame_count; base_frame_idx += 1, frame_num += 1) - { - if(frame_num <= block_relative_num && block_relative_num < frame_num+1+rich_unwind.frames[base_frame_idx].inline_frame_count) - { - unwind_count = base_frame_idx; - inline_depth = block_relative_num - frame_num; - break; - } - frame_num += rich_unwind.frames[base_frame_idx].inline_frame_count; - } - } - - // rjf: fill - info.collection_entity_kind = collection_entity_kind; - info.collection_entity = entity; - info.collection_ctrl_entity_kind = collection_ctrl_entity_kind; - info.collection_ctrl_entity = ctrl_entity; - info.callstack_thread = thread; - info.callstack_unwind_index = unwind_count; - info.callstack_inline_depth = inline_depth; - - di_scope_close(di_scope); - scratch_end(scratch); - } - return info; -} -#endif - //- rjf: row * cell -> string internal RD_WatchRowCellInfo @@ -1369,219 +1282,42 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: adjust style based on evaluation -#if 0 - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + switch(cell->kind) { - RD_Cfg *cfg = rd_cfg_from_id(result.eval.value.u64); - result.fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size()); - result.is_button = 1; - } -#endif - - return result; -} - -//- rjf: row/column -> strings - -#if 0 // TODO(rjf): @cfg - -internal E_Expr * -rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col) -{ - E_Expr *expr = row->expr; - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Member: + case RD_WatchCellKind_Eval: { - Temp scratch = scratch_begin(&arena, 1); - String8 access_string = str8(col->string_buffer, col->string_size); - String8List accesses = str8_split(scratch.arena, access_string, (U8 *)".", 1, 0); - for(String8Node *n = accesses.first; n != 0; n = n->next) + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) { - expr = e_expr_ref_member_access(arena, expr, n->string); + RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); + if(e_type_key_match(cfg_type, result.eval.type_key)) + { + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size()); + result.is_button = 1; + } } - scratch_end(scratch); - }break; - } - if(col->view_rule_size != 0) - { - EV_ViewRuleList *view_rules = ev_view_rule_list_from_string(arena, str8(col->view_rule_buffer, col->view_rule_size)); - expr = ev_resolved_from_expr(arena, expr, view_rules); - } - return expr; -} - -internal String8 -rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px) -{ - ProfBeginFunction(); - String8 result = {0}; - E_Expr *row_col_expr = rd_expr_from_watch_view_row_column(arena, row, col); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: - ProfScope("expr cell string") - { - result = ev_expr_string_from_row(arena, row, string_flags); - }break; - case RD_WatchViewColumnKind_Value: - case RD_WatchViewColumnKind_Member: - ProfScope("value/member cell string") - { - EV_ViewRuleList *view_rules = row->view_rules; - if(col->view_rule_size != 0) + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - view_rules = ev_view_rule_list_copy(arena, row->view_rules); - ev_view_rule_list_push_string(arena, view_rules, str8(col->view_rule_buffer, col->view_rule_size)); - } - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - result = rd_value_string_from_eval(arena, string_flags, default_radix, font, font_size, max_size_px, eval, row->member, view_rules); - }break; - case RD_WatchViewColumnKind_Type: - ProfScope("type cell string") - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, row_col_expr); - E_TypeKey type_key = irtree.type_key; - result = !e_type_key_match(type_key, e_type_key_zero()) ? e_type_string_from_key(arena, type_key) : str8_zero(); - result = str8_skip_chop_whitespace(result); - }break; - case RD_WatchViewColumnKind_ViewRule: - ProfScope("view rule cell string") - { - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_ViewState *vs = rd_view_state_from_cfg(view); - EV_View *ev = vs->ev_view; - result = ev_view_rule_from_key(ev, row->key); - }break; - case RD_WatchViewColumnKind_Module: - ProfScope("module cell string") - { - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, value_eval.value.u64); - result = push_str8_copy(arena, str8_skip_last_slash(module->string)); - }break; - case RD_WatchViewColumnKind_CallStackFrame: - ProfScope("call stack frame cell string") - { - Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); - E_Eval eval = e_eval_from_expr(arena, row_col_expr); - E_Expr *vaddr_expr = e_expr_ref_member_access(scratch.arena, row_col_expr, str8_lit("vaddr")); - E_Expr *depth_expr = e_expr_ref_member_access(scratch.arena, row_col_expr, str8_lit("inline_depth")); - E_Eval vaddr_eval = e_eval_from_expr(scratch.arena, vaddr_expr); - E_Eval depth_eval = e_eval_from_expr(scratch.arena, depth_expr); - E_Eval vaddr_value_eval = e_value_eval_from_eval(vaddr_eval); - E_Eval depth_value_eval = e_value_eval_from_eval(depth_eval); - U64 vaddr = vaddr_value_eval.value.u64; - U64 depth = depth_value_eval.value.u64; - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi, 0); - if(rdi != &di_rdi_parsed_nil) - { - typedef struct ScopeTask ScopeTask; - struct ScopeTask + RD_CmdKind cmd_kind = (RD_CmdKind)result.eval.value.u64; + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + if(cell->px != 0) { - ScopeTask *next; - RDI_Scope *scope; - }; - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - RDI_Scope *root_scope = rdi_scope_from_voff(rdi, voff); - ScopeTask start_task = {0, root_scope}; - ScopeTask *first_task = &start_task; - ScopeTask *last_task = &start_task; - for(;root_scope->parent_scope_idx != 0;) - { - root_scope = rdi_parent_from_scope(rdi, root_scope); - ScopeTask *t = push_array(scratch.arena, ScopeTask, 1); - SLLQueuePushFront(first_task, last_task, t); - t->scope = root_scope; - } - RDI_Scope *scope = root_scope; - U64 idx = 0; - for(ScopeTask *t = first_task; t != 0; t = t->next, idx += 1) - { - if(idx == depth) - { - scope = t->scope; - break; - } - } - RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); - RDI_InlineSite *inline_site = rdi_inline_site_from_scope(rdi, scope); - if(inline_site->name_string_idx != 0 || inline_site->type_idx != 0) - { - String8List parts = {0}; - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - String8List type_lhs_parts = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); - String8List type_rhs_parts = {0}; - e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); - str8_list_pushf(scratch.arena, &parts, "[inlined] "); - str8_list_concat_in_place(&parts, &type_lhs_parts); - str8_list_push(scratch.arena, &parts, name); - str8_list_concat_in_place(&parts, &type_rhs_parts); - result = str8_list_join(arena, &parts, 0); - } - else if(procedure->name_string_idx != 0 || procedure->type_idx != 0) - { - String8List parts = {0}; - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - String8List type_lhs_parts = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); - String8List type_rhs_parts = {0}; - e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); - str8_list_concat_in_place(&parts, &type_lhs_parts); - str8_list_push(scratch.arena, &parts, name); - str8_list_concat_in_place(&parts, &type_rhs_parts); - result = str8_list_join(arena, &parts, 0); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_top_palette()->text_weak, ui_top_font_size()}; + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); } else { - result = str8_lit("???"); + result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name, ui_top_palette()->text_weak, ui_top_font_size()); } + result.is_button = 1; } - else - { - result = str8_lit("???"); - } - di_scope_close(di_scope); - scratch_end(scratch); }break; } - if(col->dequote_string && - result.size >= 2 && - result.str[0] == '"' && - result.str[result.size-1] == '"') - { - result = str8_skip(str8_chop(result, 1), 1); - result = raw_from_escaped_str8(arena, result); - } - if(col->rangify_braces && result.size >= 2 && - result.str[0] == '{' && - result.str[result.size-1] == '}') - { - result = push_str8_copy(arena, result); - result.str[0] = '['; - result.str[result.size-1] = ')'; - } - ProfEnd(); + return result; } -#endif - //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState * @@ -2623,6 +2359,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) U64 cell_idx = 0; for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) { + if(cell->pct == 0 || cell->next->pct == 0) + { + continue; + } U64 cell_id = rd_id_from_watch_cell(cell); F32 cell_width_px = cell->px + cell->pct * row_width_px; F32 next_cell_x_px = cell_x_px + cell_width_px; @@ -2953,7 +2693,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //- rjf: build cell UI_Box *cell_box = &ui_nil_box; - UI_Palette(palette) UI_PrefWidth(ui_px(cell_width_px, 1.f)) + UI_Palette(palette) UI_PrefWidth(ui_px(cell_width_px, 0.f)) { ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft, "cell_%I64x_%I64x", row_hash, cell_id); @@ -3062,7 +2802,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.pre_edit_value = cell_info.string; line_edit_params.fstrs = cell_info.fstrs; } - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); + UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) + sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); #if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 037a45e9..76ad5d9e 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -212,20 +212,9 @@ internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchP //- rjf: row -> info internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); -//- rjf: row -> context info -#if 0 // TODO(rjf): @cfg -internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); -#endif - //- rjf: row * cell -> info internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px); -//- rjf: row/column -> exprs / strings -#if 0 // TODO(rjf): @cfg -internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col); -internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); -#endif - //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 93ae1495..009c1443 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2664,6 +2664,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) { if(!is_focus_active && !is_focus_active_disabled && params->fstrs.total_size != 0) { + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) == 0) + { + ui_spacer(ui_em(0.5f, 1.f)); + } UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(label, ¶ms->fstrs); } From c39cc5d642baa2f067f6553e884f389de630e38d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 11:36:57 -0800 Subject: [PATCH 110/755] call stack rows -> module evaluation column --- src/raddbg/raddbg_views.c | 22 +++++++++++++++++----- src/raddbg/raddbg_views.h | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index dcbef461..059b4e41 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -794,6 +794,7 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); + result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); result = e_hash_from_string(result, cell->string); return result; } @@ -956,6 +957,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; info.callstack_unwind_index = f->unwind_count; info.callstack_inline_depth = f->inline_depth; + info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); } } } @@ -1093,14 +1095,23 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.callstack_thread != &ctrl_entity_nil) { info.cell_style_key = str8_lit("call_stack_frame"); + CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); + E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); + E_Eval module_eval = e_eval_from_expr(arena, expr); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.30f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = module_eval, .default_pct = 0.20f, .pct = take_pct()); #undef take_pct } @@ -1153,7 +1164,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.can_edit = 1; } - result.eval = e_eval_from_expr(arena, row->expr); + result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); result.string = row->string; if(result.string.size == 0) { @@ -1257,7 +1268,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: evaluate wrapped expression - result.eval = e_eval_from_expr(scratch.arena, root_expr); + result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); @@ -1275,7 +1286,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: view ui cells case RD_WatchCellKind_ViewUI: { - result.eval = e_eval_from_expr(arena, row->expr); + result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); result.view_ui_rule = row_info->view_ui_rule; result.view_ui_tag = row_info->view_ui_tag; }break; @@ -1378,6 +1389,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ewv->initialized = 1; ewv->text_edit_arena = rd_push_view_arena(); } + B32 is_query = (rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("query")) != &rd_nil_cfg); ////////////////////////////// //- rjf: unpack arguments diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 76ad5d9e..eed0aa32 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -57,6 +57,7 @@ struct RD_WatchCell RD_WatchCell *next; RD_WatchCellKind kind; String8 string; + E_Eval eval; DR_FStrList fstrs; B32 is_button; F32 default_pct; @@ -84,6 +85,7 @@ struct RD_WatchRowInfo CTRL_Entity *callstack_thread; U64 callstack_unwind_index; U64 callstack_inline_depth; + U64 callstack_vaddr; String8 cell_style_key; RD_WatchCellList cells; RD_ViewUIRule *view_ui_rule; From 141dd69ebafdb8e9b5d0e5e7b755957f98cafa9b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 15:12:34 -0800 Subject: [PATCH 111/755] correct rich hovering for rich watch window rows; distinguish between single/double-click watch cells; more convergence --- .../eval_visualization_core.c | 23 ++++ src/raddbg/raddbg_core.c | 43 ++++++- src/raddbg/raddbg_views.c | 115 +++++++++++------- src/raddbg/raddbg_views.h | 19 ++- src/raddbg/raddbg_widgets.c | 25 ++-- src/raddbg/raddbg_widgets.h | 5 +- 6 files changed, 169 insertions(+), 61 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 9dc14c77..dc346cdb 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -110,6 +110,29 @@ ev_type_key_is_editable(E_TypeKey type_key) for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) { E_TypeKind kind = e_type_kind_from_key(t); + if(kind == E_TypeKind_Array) + { + E_TypeKind element_kind = e_type_kind_from_key(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))); + if(element_kind != E_TypeKind_U8 && + element_kind != E_TypeKind_U16 && + element_kind != E_TypeKind_U32 && + element_kind != E_TypeKind_S8 && + element_kind != E_TypeKind_S16 && + element_kind != E_TypeKind_S32 && + element_kind != E_TypeKind_UChar8 && + element_kind != E_TypeKind_UChar16 && + element_kind != E_TypeKind_UChar32 && + element_kind != E_TypeKind_Char8 && + element_kind != E_TypeKind_Char16 && + element_kind != E_TypeKind_Char32) + { + break; + } + else + { + result = 1; + } + } if(kind == E_TypeKind_Null || kind == E_TypeKind_Function) { break; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d80d8c21..b005a611 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1152,7 +1152,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 Vec4F32 rgba = rd_rgba_from_cfg(cfg); if(rgba.w == 0) { - rgba = ui_top_palette()->text; + rgba = rd_rgba_from_theme_color(RD_ThemeColor_Text); } RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); B32 is_from_command_line = 0; @@ -2522,7 +2522,11 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un E_Eval src_eval_value = e_value_eval_from_eval(src_eval); E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.type_key); if(direct_type_kind == E_TypeKind_Char8 || + direct_type_kind == E_TypeKind_Char16 || + direct_type_kind == E_TypeKind_Char32 || direct_type_kind == E_TypeKind_UChar8 || + direct_type_kind == E_TypeKind_UChar16 || + direct_type_kind == E_TypeKind_UChar32 || e_type_kind_is_integer(direct_type_kind)) { B32 is_quoted = 0; @@ -2551,6 +2555,26 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un { commit_at_ptr_dest = 1; } + switch(direct_type_kind) + { + default:{}break; + case E_TypeKind_S16: + case E_TypeKind_U16: + case E_TypeKind_Char16: + case E_TypeKind_UChar16: + { + String16 data16 = str16_from_8(scratch.arena, commit_data); + commit_data = str8((U8 *)data16.str, data16.size*sizeof(U16)); + }break; + case E_TypeKind_Char32: + case E_TypeKind_UChar32: + case E_TypeKind_S32: + case E_TypeKind_U32: + { + String32 data32 = str32_from_8(scratch.arena, commit_data); + commit_data = str8((U8 *)data32.str, data32.size*sizeof(U32)); + }break; + } } else if(type_kind == E_TypeKind_Ptr && (e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || @@ -7821,6 +7845,19 @@ rd_window_frame(void) MemoryCopyArray(inst->corner_radii, box->corner_radii); } + // rjf: soft circle around mouse + if(ui_key_match(ui_hot_key(), box->key)) + { + DR_ClipScope(box->rect) + { + Vec2F32 center = ui_mouse(); + F32 radius = box->font_size*12.f; + Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + color.w *= 0.1f*t; + dr_rect(pad_2f32(r2f32p(center.x, center.y, center.x, center.y), radius), color, radius, 0, radius/3.f); + } + } + // rjf: slight emboss fadeoff if(0) { @@ -14068,6 +14105,7 @@ Z(getting_started) #undef Z //- rjf: find all the fixed tabs, and all text viewers + B32 any_fixed_tabs_found = 0; RD_CfgList texts = {0}; for(RD_PanelNode *panel = panel_tree.root; panel != &rd_nil_panel_node; @@ -14093,6 +14131,7 @@ Z(getting_started) if(need_unhook) { rd_cfg_unhook(panel->cfg, tab); + any_fixed_tabs_found = 1; } } } @@ -14103,7 +14142,7 @@ Z(getting_started) //- rjf: allocate any missing tabs #define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit("watch")); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit("query:" #name));} #define Y(name, rule, expr) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#rule)); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit(expr));} -#define Z(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} +#define Z(name) if(name == &rd_nil_cfg && !any_fixed_tabs_found) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} FixedTab_XList #undef X #undef Y diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 059b4e41..5bb6326e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1011,7 +1011,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); MD_Node *schema = rd_schema_from_name(arena, cfg->string); MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); for MD_EachNode(cmd, cmds_root->first) @@ -1040,7 +1040,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind != RD_CmdKind_Null) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); } } } @@ -1048,7 +1048,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: entity rows else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); } // rjf: singular button for commands @@ -1059,7 +1059,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .is_button = 1, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } // rjf: singular cell for view ui @@ -1149,7 +1149,9 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.view_ui_rule = &rd_nil_view_ui_rule; result.view_ui_tag = &e_expr_nil; result.fstrs = cell->fstrs; - result.is_button = cell->is_button; + result.flags = cell->flags; + result.cfg = &rd_nil_cfg; + result.entity = &ctrl_entity_nil; //- rjf: do per-kind fills switch(cell->kind) @@ -1162,7 +1164,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { if(!ev_key_match(ev_key_root(), row->block->key) && (row->string.size != 0 || row->expr == &e_expr_nil)) { - result.can_edit = 1; + result.flags |= RD_WatchCellFlag_CanEdit; } result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); result.string = row->string; @@ -1213,7 +1215,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla is_non_code = 1; } } - result.is_non_code = is_non_code; + result.flags |= (!!is_non_code * RD_WatchCellFlag_IsNonCode); result.string = string; }break; } @@ -1270,7 +1272,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: evaluate wrapped expression result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); - result.can_edit = (ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset); + result.flags |= !!(ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; scratch_end(scratch); }break; @@ -1280,7 +1282,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { EV_View *ev_view = rd_view_eval_view(); result.string = ev_view_rule_from_key(ev_view, row->key); - result.can_edit = 1; + result.flags |= RD_WatchCellFlag_CanEdit; }break; //- rjf: view ui cells @@ -1295,6 +1297,20 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: adjust style based on evaluation switch(cell->kind) { + default:{}break; + case RD_WatchCellKind_Expr: + { + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); + if(e_type_key_match(cfg_type, result.eval.type_key)) + { + result.cfg = cfg; + } + } + }break; case RD_WatchCellKind_Eval: { if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && @@ -1305,7 +1321,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla if(e_type_key_match(cfg_type, result.eval.type_key)) { result.fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size()); - result.is_button = 1; + result.flags |= RD_WatchCellFlag_Button; + result.cfg = cfg; } } else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) @@ -1321,7 +1338,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name, ui_top_palette()->text_weak, ui_top_font_size()); } - result.is_button = 1; + result.flags |= RD_WatchCellFlag_Button; } }break; } @@ -1649,8 +1666,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { continue; } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.can_edit) + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.flags & RD_WatchCellFlag_CanEdit) { any_edits_started = 1; String8 string = cell_info.string; @@ -2690,7 +2707,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_BoxFlags cell_flags = 0; UI_Palette *palette = ui_top_palette(); { - if(cell_info.is_errored) + if(cell_info.flags & RD_WatchCellFlag_IsErrored) { palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); cell_flags |= UI_BoxFlag_DrawBackground; @@ -2700,6 +2717,19 @@ RD_VIEW_UI_FUNCTION_DEF(watch) palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); cell_flags |= UI_BoxFlag_DrawBackground; } + else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && + rd_state->hover_regs_slot == RD_RegSlot_Cfg) + { + RD_Cfg *cfg = cell_info.cfg; + Vec4F32 rgba = rd_rgba_from_cfg(cfg); + if(rgba.w == 0) + { + rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); + palette = ui_build_palette(ui_top_palette(), .overlay = rgba); + cell_flags |= UI_BoxFlag_DrawOverlay; + } } ProfEnd(); @@ -2708,7 +2738,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_Palette(palette) UI_PrefWidth(ui_px(cell_width_px, 0.f)) { ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); - cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft, "cell_%I64x_%I64x", row_hash, cell_id); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); } //- rjf: build cell contents @@ -2720,10 +2750,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) { - ui_set_next_flags(ui_top_flags() | cell_flags); - // rjf: cell has errors? -> build error box - if(cell_info.is_errored) RD_Font(RD_FontSlot_Main) + if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); sig = ui_signal_from_box(box); @@ -2793,16 +2821,17 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } // rjf: build cell line edit - else RD_Font(cell_info.is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + else RD_Font(cell_info.flags & RD_WatchCellFlag_IsNonCode ? RD_FontSlot_Main : RD_FontSlot_Code) { RD_LineEditParams line_edit_params = {0}; { line_edit_params.flags = (RD_LineEditFlag_CodeContents| - RD_LineEditFlag_NoBackground*!(cell_info.is_button)| - RD_LineEditFlag_Button*!!(cell_info.is_button)| + RD_LineEditFlag_NoBackground*!(cell_info.flags & RD_WatchCellFlag_Button)| + RD_LineEditFlag_Button*!!(cell_info.flags & RD_WatchCellFlag_Button)| + RD_LineEditFlag_SingleClickActivate*!!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !cell_info.is_button)| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !(cell_info.flags & RD_WatchCellFlag_Button))| RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; @@ -2834,17 +2863,27 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //- rjf: handle interactions { + // rjf: hover -> rich hover cfgs + if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); + } + // rjf: single-click -> move selection here - if(ui_pressed(sig)) + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) { ewv->next_cursor = ewv->next_mark = cell_pt; pressed = 1; } // rjf: double-click actions - if(ui_double_clicked(sig) || sig.f & UI_SignalFlag_KeyboardPressed) + if(ui_double_clicked(sig) || + ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) { - ui_kill_action(); + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) + { + ui_kill_action(); + } // rjf: has callstack info? -> select unwind if(row_info->callstack_thread != &ctrl_entity_nil) @@ -2856,24 +2895,19 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } // rjf: can edit? -> begin editing - else if(cell_info.can_edit) + else if(cell_info.flags & RD_WatchCellFlag_CanEdit) { rd_cmd(RD_CmdKind_Edit); } - -#if 0 // TODO(rjf): @cfg - // rjf: cannot edit, has addr info? -> go to address - else if(row_kind == RD_WatchViewRowKind_Normal && - (col->kind == RD_WatchViewColumnKind_Value || - col->kind == RD_WatchViewColumnKind_Member) && - cell_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + // rjf: can't edit, but has address info? -> go to address + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_eval.space); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); CTRL_Entity *process = ctrl_process_from_entity(entity); if(process != &ctrl_entity_nil) { - U64 vaddr = cell_eval.value.u64; + U64 vaddr = cell_info.eval.value.u64; CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); @@ -2884,15 +2918,14 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { file_path = lines.first->v.file_path; pt = lines.first->v.pt; + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); } - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); } } -#endif } // rjf: hovering with inheritance string -> show tooltip diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index eed0aa32..d1e51735 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -51,6 +51,16 @@ typedef enum RD_WatchCellKind } RD_WatchCellKind; +typedef U32 RD_WatchCellFlags; +enum +{ + RD_WatchCellFlag_Button = (1<<0), + RD_WatchCellFlag_ActivateWithSingleClick = (1<<1), + RD_WatchCellFlag_IsNonCode = (1<<2), + RD_WatchCellFlag_CanEdit = (1<<3), + RD_WatchCellFlag_IsErrored = (1<<4), +}; + typedef struct RD_WatchCell RD_WatchCell; struct RD_WatchCell { @@ -59,7 +69,7 @@ struct RD_WatchCell String8 string; E_Eval eval; DR_FStrList fstrs; - B32 is_button; + RD_WatchCellFlags flags; F32 default_pct; F32 pct; F32 px; @@ -95,13 +105,12 @@ struct RD_WatchRowInfo typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; struct RD_WatchRowCellInfo { + RD_WatchCellFlags flags; E_Eval eval; + RD_Cfg *cfg; + CTRL_Entity *entity; String8 string; DR_FStrList fstrs; - B32 is_button; - B32 is_non_code; - B32 can_edit; - B32 is_errored; String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 009c1443..e92b4d8d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -755,8 +755,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe rd_state->hover_regs_slot == RD_RegSlot_Thread); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; - u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); - u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); + u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; u->do_lines = do_thread_lines; @@ -903,8 +903,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe rd_state->hover_regs_slot == RD_RegSlot_Thread); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; - u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); - u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); + u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); + u->hover_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_hover_t_%p", thread), (F32)!!is_hovering, .rate = entity_hover_t_rate); u->is_selected = (thread == selected_thread); u->is_frozen = !!thread->is_frozen; ui_box_equip_custom_draw(thread_box, rd_thread_box_draw_extensions, u); @@ -960,11 +960,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_Cfg *bp = n->v; Vec4F32 bp_rgba = rd_rgba_from_cfg(bp); - B32 bp_is_disabled = rd_disabled_from_cfg(bp); if(bp_rgba.w == 0) { bp_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); } + B32 bp_is_disabled = rd_disabled_from_cfg(bp); if(bp_is_disabled) { bp_rgba = v4f32(bp_rgba.x * 0.6f, bp_rgba.y * 0.6f, bp_rgba.z * 0.6f, bp_rgba.w * 0.6f); @@ -976,8 +976,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_Regs *hover_regs = rd_get_hover_regs(); B32 is_hovering = (rd_cfg_from_id(hover_regs->cfg) == bp && rd_state->hover_regs_slot == RD_RegSlot_Cfg); bp_draw->color = bp_rgba; - bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); - bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "bp_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); + bp_draw->alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "cfg_alive_t_%p", bp), 1.f, .rate = entity_alive_t_rate); + bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "cfg_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); bp_draw->do_lines = do_bp_lines; bp_draw->do_glow = do_bp_glow; if(params->line_vaddrs[line_idx] == 0) @@ -1015,7 +1015,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(ui_hovering(bp_sig) && !rd_drag_is_active()) { rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", bp->id)); - // RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: shift+click => enable breakpoint @@ -1055,7 +1055,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 color = rd_rgba_from_cfg(pin); if(color.w == 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_Text); + color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } // rjf: build box for watch @@ -2469,7 +2469,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) (!!(params->flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| UI_BoxFlag_DrawHotEffects| - //(!!(params->flags & RD_LineEditFlag_Button)*UI_BoxFlag_DrawActiveEffects)| + (!!(params->flags & RD_LineEditFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| (!(params->flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| (!!(params->flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| @@ -2571,7 +2571,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) MemoryCopy(params->edit_buffer, edit_string.str, edit_string.size); params->edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); - ui_kill_action(); + if(!(params->flags & RD_LineEditFlag_Button)) + { + ui_kill_action(); + } params->cursor[0] = txt_pt(1, edit_string.size+1); params->mark[0] = txt_pt(1, 1); focus_started = 1; diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 0de9354f..913375db 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -19,8 +19,9 @@ enum RD_LineEditFlag_Border = (1<<6), RD_LineEditFlag_NoBackground = (1<<7), RD_LineEditFlag_Button = (1<<8), - RD_LineEditFlag_PreferDisplayString = (1<<9), - RD_LineEditFlag_DisplayStringIsCode = (1<<10), + RD_LineEditFlag_SingleClickActivate = (1<<9), + RD_LineEditFlag_PreferDisplayString = (1<<10), + RD_LineEditFlag_DisplayStringIsCode = (1<<11), }; typedef struct RD_LineEditParams RD_LineEditParams; From f58c13b3a0861c4d38e6ca62667aa041883924d1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 15:26:21 -0800 Subject: [PATCH 112/755] plug full data member calculation path & padding member visualization back in --- src/eval/eval_ir.c | 48 +++++++++++++++++++++++++++++++--------- src/raddbg/raddbg_core.c | 11 +++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 6f6c5544..2ff4ff15 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -152,8 +152,12 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); if(direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Enum) + direct_type_kind == E_TypeKind_Union) + { + E_MemberArray data_members = e_type_data_members_from_key__cached(direct_type_key); + lookup_info.named_expr_count = data_members.count; + } + else if(direct_type_kind == E_TypeKind_Enum) { E_Type *direct_type = e_type_from_key__cached(direct_type_key); lookup_info.named_expr_count = direct_type->count; @@ -430,7 +434,9 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) //- rjf: pull out specific kinds of types B32 do_struct_range = 0; + B32 do_enum_range = 0; B32 do_index_range = 0; + E_TypeKey enum_type_key = zero_struct; E_TypeKey struct_type_key = zero_struct; E_TypeKind struct_type_kind = E_TypeKind_Null; if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) @@ -439,13 +445,17 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) if(lhs_type->count == 1 && (direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Enum)) + direct_type_kind == E_TypeKind_Class)) { struct_type_key = direct_type_key; struct_type_kind = direct_type_kind; do_struct_range = 1; } + else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) + { + do_enum_range = 1; + enum_type_key = direct_type_key; + } else { do_index_range = 1; @@ -453,13 +463,17 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) } else if(lhs_type_kind == E_TypeKind_Struct || lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Enum) + lhs_type_kind == E_TypeKind_Class) { struct_type_key = lhs_type_key; struct_type_kind = lhs_type_kind; do_struct_range = 1; } + else if(lhs_type_kind == E_TypeKind_Enum) + { + enum_type_key = lhs_type_key; + do_enum_range = 1; + } else if(lhs_type_kind == E_TypeKind_Set) { do_index_range = 1; @@ -472,15 +486,29 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) //- rjf: struct case -> the lookup-range will return a range of members if(do_struct_range) { - E_Type *struct_type = e_type_from_key__cached(struct_type_key); - Rng1U64 legal_idx_range = r1u64(0, struct_type->count); + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + Rng1U64 legal_idx_range = r1u64(0, data_members.count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 member_idx = idx + read_range.min; - String8 member_name = (struct_type->members ? struct_type->members[member_idx].name : - struct_type->enum_vals ? struct_type->enum_vals[member_idx].name : str8_lit("")); + String8 member_name = data_members.v[member_idx].name; + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); + } + } + + //- rjf: enum case -> the lookup-range will return a range of enum constants + else if(do_enum_range) + { + E_Type *type = e_type_from_key__cached(enum_type_key); + Rng1U64 legal_idx_range = r1u64(0, type->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = type->enum_vals[member_idx].name; exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b005a611..702d4d6b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9282,6 +9282,17 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } } + //- rjf: force no_string, if we are looking at padding members + if(eval.expr->kind == E_ExprKind_MemberAccess) + { + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr->first); + E_Member member = e_type_member_from_key_name__cached(irtree.type_key, eval.expr->last->string); + if(member.kind == E_MemberKind_Padding) + { + no_string = 1; + } + } + //- rjf: type evaluations -> display type string if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key)) { From af8f1ff16264572e49f3a16c01c08869e1fceec9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 21:33:40 -0800 Subject: [PATCH 113/755] frontend cleanups, cmd running from watch --- src/eval/eval_parse.c | 1 + src/raddbg/raddbg_core.c | 24 ++++++++++-------------- src/raddbg/raddbg_views.c | 23 +++++++++++++++++++---- src/raddbg/raddbg_views.h | 1 + 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 78770336..a61717b5 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -724,6 +724,7 @@ e_expr_copy(Arena *arena, E_Expr *src) { E_Expr *result = &e_expr_nil; Temp scratch = scratch_begin(&arena, 1); + if(src != &e_expr_nil) { typedef struct Task Task; struct Task diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 702d4d6b..36b58108 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3815,10 +3815,9 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: rich hover, drag/drop tooltips + //- rjf: drag/drop tooltips // - if(rd_state->hover_regs_slot != RD_RegSlot_Null || - (rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active())) + if(rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) { Temp scratch = scratch_begin(0, 0); RD_RegSlot slot = ((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs_slot : rd_state->hover_regs_slot); @@ -5608,10 +5607,10 @@ rd_window_frame(void) UI_TextAlignment(UI_TextAlign_Center) UI_Padding(ui_pct(1, 0)) { - ui_labelf("Search for commands by pressing "); + ui_labelf("Search for commands and options by pressing "); UI_Flags(UI_BoxFlag_DrawBorder) UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_RunCommand].string); + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); } ui_spacer(ui_em(1.f, 1.f)); RD_Palette(RD_PaletteCode_NeutralPopButton) @@ -7846,16 +7845,13 @@ rd_window_frame(void) } // rjf: soft circle around mouse - if(ui_key_match(ui_hot_key(), box->key)) + if(ui_key_match(ui_hot_key(), box->key)) DR_ClipScope(box->rect) { - DR_ClipScope(box->rect) - { - Vec2F32 center = ui_mouse(); - F32 radius = box->font_size*12.f; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - color.w *= 0.1f*t; - dr_rect(pad_2f32(r2f32p(center.x, center.y, center.x, center.y), radius), color, radius, 0, radius/3.f); - } + Vec2F32 center = ui_mouse(); + F32 radius = box->font_size*12.f; + Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + color.w *= 0.1f*t; + dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } // rjf: slight emboss fadeoff diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5bb6326e..4679f5ec 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1310,6 +1310,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.cfg = cfg; } } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + RD_CmdKind cmd_kind = (RD_CmdKind)result.eval.value.u64; + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + result.cmd_name = cmd_name; + } }break; case RD_WatchCellKind_Eval: { @@ -1339,6 +1345,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name, ui_top_palette()->text_weak, ui_top_font_size()); } result.flags |= RD_WatchCellFlag_Button; + result.cmd_name = cmd_name; } }break; } @@ -2869,24 +2876,32 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); } - // rjf: single-click -> move selection here + // rjf: (normally) single-click -> move selection here if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) { ewv->next_cursor = ewv->next_mark = cell_pt; pressed = 1; } - // rjf: double-click actions + // rjf: activation (double-click normally, or single-clicks with special buttons) if(ui_double_clicked(sig) || ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) { + // rjf: kill if a double-clickable cell if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) { ui_kill_action(); } - // rjf: has callstack info? -> select unwind - if(row_info->callstack_thread != &ctrl_entity_nil) + // rjf: has a command name? -> push command + if(cell_info.cmd_name.size != 0) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cell_info.cmd_name); + rd_cmd(kind, .cfg = row_info->group_cfg_child->id); + } + + // rjf: row has callstack info? -> select unwind + else if(row_info->callstack_thread != &ctrl_entity_nil) { rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); rd_cmd(RD_CmdKind_SelectUnwind, diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index d1e51735..568b04f0 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -109,6 +109,7 @@ struct RD_WatchRowCellInfo E_Eval eval; RD_Cfg *cfg; CTRL_Entity *entity; + String8 cmd_name; String8 string; DR_FStrList fstrs; String8 error_tooltip; From 87ee37d19e06fd3790413a1a936b4befa978103b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Feb 2025 21:55:04 -0800 Subject: [PATCH 114/755] if cell activates on single-click, disable double-click path --- src/raddbg/raddbg_views.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4679f5ec..d96dd303 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2884,7 +2884,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } // rjf: activation (double-click normally, or single-clicks with special buttons) - if(ui_double_clicked(sig) || + if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) { // rjf: kill if a double-clickable cell From 35ba41f7128cdcc7ce6fd92ca27c695c4c31d0f5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Feb 2025 09:04:46 -0800 Subject: [PATCH 115/755] correctly hook up watch window commands to their associated cfg; plug in ctrl entity detection / fancy rows --- src/raddbg/raddbg_core.c | 9 +++++++ src/raddbg/raddbg_core.h | 3 ++- src/raddbg/raddbg_views.c | 56 ++++++++++++++++++++++++++++++++++----- src/ui/ui_core.c | 14 ++++------ 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 36b58108..a0bb5170 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12716,6 +12716,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntityCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), @@ -14787,6 +14788,14 @@ Z(getting_started) disasm_dst_panel = &rd_nil_panel_node; } + // rjf: if disasm is not preferred, and we have no disassembly view + // *selected* at all, cancel disasm, so that it doesn't open if the user + // doesn't want it. + if(!rd_regs()->prefer_disasm && view_w_disasm != &rd_nil_cfg && rd_cfg_child_from_string(view_w_disasm, str8_lit("selected")) == &rd_nil_cfg) + { + disasm_dst_panel = &rd_nil_panel_node; + } + // rjf: given the above, find source code location. if(file_path.size != 0 && src_code_dst_panel != &rd_nil_panel_node) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 39c4a7f9..13b17b3e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -84,9 +84,10 @@ enum RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaCfgCollection, + RD_EvalSpaceKind_MetaCmd, RD_EvalSpaceKind_MetaCmdCollection, RD_EvalSpaceKind_MetaCtrlEntity, - RD_EvalSpaceKind_MetaCmd, + RD_EvalSpaceKind_MetaCtrlEntityCollection, }; //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d96dd303..3f2cff90 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -962,6 +962,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } + // rjf: determine ctrl entity + if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntityCollection) + { + info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + } + // rjf: determine cfg group name / parent if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) { @@ -1048,7 +1054,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: entity rows else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, info.group_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); } // rjf: singular button for commands @@ -1078,7 +1084,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || - info.eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection) + info.eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntityCollection) { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1300,8 +1308,18 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla default:{}break; case RD_WatchCellKind_Expr: { - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && result.eval.value.u64 == 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); + if(e_type_key_match(cfg_type, result.eval.type_key)) + { + result.entity = entity; + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) { RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); @@ -1319,8 +1337,20 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla }break; case RD_WatchCellKind_Eval: { - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && result.eval.value.u64 == 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); + E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); + if(e_type_key_match(cfg_type, result.eval.type_key)) + { + result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); + result.flags |= RD_WatchCellFlag_Button; + result.entity = entity; + } + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && + result.eval.value.u64 == 0) { RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); @@ -2612,7 +2642,11 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(row_is_fresh) { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); + Vec4F32 start_color = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground); + start_color.w *= 0.5f; + Vec4F32 end_color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + Vec4F32 color = mix_4f32(start_color, end_color, ui_anim(ui_key_from_stringf(ui_key_zero(), "row_fresh_%I64x", row_hash), 1.f)); + palette = ui_build_palette(ui_top_palette(), .background = color); row_flags |= UI_BoxFlag_DrawBackground; } else if(global_row_idx & 1) @@ -2876,6 +2910,15 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); } + // rjf: dragging -> drag/drop + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + { + if(cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); + } + } + // rjf: (normally) single-click -> move selection here if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) { @@ -2896,8 +2939,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: has a command name? -> push command if(cell_info.cmd_name.size != 0) { + RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); RD_CmdKind kind = rd_cmd_kind_from_string(cell_info.cmd_name); - rd_cmd(kind, .cfg = row_info->group_cfg_child->id); + rd_cmd(kind, .cfg = cfg->id); } // rjf: row has callstack info? -> select unwind diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 6426ff4e..15cd4167 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -795,7 +795,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->build_box_count = 0; ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; - ui_state->default_animation_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + ui_state->default_animation_rate = 1 - pow_f32(2, (-80.f * ui_state->animation_dt)); } //- rjf: prune unused animation nodes @@ -1306,19 +1306,15 @@ ui_end_build(void) ui_state->is_animating = (ui_state->is_animating || abs_f32(n->params.target - n->current) > n->params.epsilon); } } - F32 vast_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); - F32 fast_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); - F32 fish_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); + F32 fast_rate = ui_state->default_animation_rate; F32 slow_rate = 1 - pow_f32(2, (-30.f * ui_state->animation_dt)); - F32 slug_rate = 1 - pow_f32(2, (-15.f * ui_state->animation_dt)); - F32 slaf_rate = 1 - pow_f32(2, (-8.f * ui_state->animation_dt)); - ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? vast_rate : 1); + ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? fast_rate : 1); ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) > 0.01f); if(ui_state->ctx_menu_open_t >= 0.99f && ui_state->ctx_menu_open) { ui_state->ctx_menu_open_t = 1.f; } - ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_TooltipAnimations ? vast_rate : 1); + ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_TooltipAnimations ? fast_rate : 1); ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) > 0.01f); if(ui_state->tooltip_open_t >= 0.99f && ui_state->tooltip_open) { @@ -1374,7 +1370,7 @@ ui_end_build(void) // rjf: animate interaction transition states box->hot_t += hot_rate * ((F32)is_hot - box->hot_t); - box->active_t += active_rate * ((F32)is_active - box->active_t); + box->active_t = is_active ? 1.f : box->active_t + (active_rate * ((F32)is_active - box->active_t)); box->disabled_t += disabled_rate * ((F32)is_disabled - box->disabled_t); box->focus_hot_t += focus_rate * ((F32)is_focus_hot - box->focus_hot_t); box->focus_active_t += focus_rate * ((F32)is_focus_active - box->focus_active_t); From c5de847fa5e552b0e8eb1558ad88563fa75ec6d3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Feb 2025 09:19:25 -0800 Subject: [PATCH 116/755] ctrl entity rich hovering --- src/raddbg/generated/raddbg.meta.c | 7 ++++++- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 5 +++++ src/raddbg/raddbg_views.c | 27 +++++++++++++++++++++++++++ src/raddbg/raddbg_widgets.c | 10 +++++----- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7e27408a..2ae34d4b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[277] = +RD_VocabInfo rd_vocab_info_table[282] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -17,6 +17,11 @@ RD_VocabInfo rd_vocab_info_table[277] = {str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, {str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, {str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, +{str8_lit_comp("exe"), str8_lit_comp("exes"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, +{str8_lit_comp("dbg"), str8_lit_comp("dbgs"), str8_lit_comp("Debug Info Path"), str8_lit_comp("Debug Info Paths"), RD_IconKind_Module}, +{str8_lit_comp("vaddr_range"), str8_lit_comp("vaddr_ranges"), str8_lit_comp("Virtual Address Range"), str8_lit_comp("Virtual Address Ranges"), RD_IconKind_Null}, +{str8_lit_comp("min"), str8_lit_comp("mins"), str8_lit_comp("Minimum"), str8_lit_comp("Minimums"), RD_IconKind_Null}, +{str8_lit_comp("max"), str8_lit_comp("maxs"), str8_lit_comp("Maximum"), str8_lit_comp("Maximums"), RD_IconKind_Null}, {str8_lit_comp("working_directory"), str8_lit_comp("working_directories"), str8_lit_comp("Working Directory"), str8_lit_comp("Working Directories"), RD_IconKind_FolderClosedFilled}, {str8_lit_comp("entry_point"), str8_lit_comp("entry_points"), str8_lit_comp("Entry Point"), str8_lit_comp("Entry Points"), RD_IconKind_Null}, {str8_lit_comp("stdout_path"), str8_lit_comp("stdout_paths"), str8_lit_comp("Standard Output Path"), str8_lit_comp("Standard Output Paths"), RD_IconKind_Null}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index c5caebe9..6ffbba5c 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -554,7 +554,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[277]; +extern RD_VocabInfo rd_vocab_info_table[282]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 36cd78a5..6382d4ec 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -29,6 +29,11 @@ RD_VocabTable: {target _ "Target" _ Target } {executable _ "Executable" _ Module } {arguments arguments "Arguments" "Arguments" Null } + {exe exes "Executable" _ Module } + {dbg dbgs "Debug Info Path" _ Module } + {vaddr_range _ "Virtual Address Range" _ Null } + {min _ "Minimum" _ Null } + {max _ "Maximum" _ Null } {working_directory working_directories "Working Directory" "Working Directories" FolderClosedFilled } {entry_point _ "Entry Point" _ Null } {stdout_path _ "Standard Output Path" _ Null } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3f2cff90..99297be1 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2767,10 +2767,31 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); } + else + { + rgba.w *= 0.2f; + } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); palette = ui_build_palette(ui_top_palette(), .overlay = rgba); cell_flags |= UI_BoxFlag_DrawOverlay; } + else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) + { + CTRL_Entity *entity = cell_info.entity; + Vec4F32 rgba = rd_rgba_from_ctrl_entity(entity); + if(rgba.w == 0) + { + rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + } + else + { + rgba.w *= 0.2f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); + palette = ui_build_palette(ui_top_palette(), .overlay = rgba); + cell_flags |= UI_BoxFlag_DrawOverlay; + } } ProfEnd(); @@ -2910,6 +2931,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); } + // rjf: hover -> rich hover entities + if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); + } + // rjf: dragging -> drag/drop if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index e92b4d8d..b3b01423 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -751,8 +751,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: custom draw { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (ctrl_handle_match(hover_regs->thread, thread->handle) && - rd_state->hover_regs_slot == RD_RegSlot_Thread); + B32 is_hovering = (ctrl_handle_match(hover_regs->ctrl_entity, thread->handle) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); @@ -899,8 +899,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: custom draw { RD_Regs *hover_regs = rd_get_hover_regs(); - B32 is_hovering = (ctrl_handle_match(hover_regs->thread, thread->handle) && - rd_state->hover_regs_slot == RD_RegSlot_Thread); + B32 is_hovering = (ctrl_handle_match(hover_regs->ctrl_entity, thread->handle) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity); RD_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), RD_ThreadBoxDrawExtData, 1); u->thread_color = color; u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###entity_alive_t_%p", thread), 1.f, .rate = entity_alive_t_rate); @@ -938,7 +938,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - RD_RegsScope(.thread = thread->handle) rd_set_hover_regs(RD_RegSlot_Thread); + RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) { From ecb4e0d28224e2ee3bd1d689e17072f87bcb4564 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Feb 2025 09:43:19 -0800 Subject: [PATCH 117/755] rich hover for thread-hover editors --- src/ctrl/ctrl_core.c | 7 +++++++ src/ctrl/ctrl_core.h | 1 + src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_views.c | 28 ++++++++++++++++++++++------ src/raddbg/raddbg_widgets.c | 3 ++- 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 4ab0d345..2c0d0086 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -151,6 +151,13 @@ ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src) return dst; } +internal String8 +ctrl_string_from_handle(Arena *arena, CTRL_Handle handle) +{ + String8 result = push_str8f(arena, "$%I64x_%I64x", handle.machine_id, handle.dmn_handle.u64[0]); + return result; +} + //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 071748d4..024304aa 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -726,6 +726,7 @@ internal CTRL_Handle ctrl_handle_make(CTRL_MachineID machine_id, DMN_Handle dmn_ internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b); internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair); internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); +internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle); //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2ae34d4b..098160e1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -867,7 +867,7 @@ rgba_from_u32_lit_comp(0xffffffff), rgba_from_u32_lit_comp(0x0000007f), rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), +rgba_from_u32_lit_comp(0x0000002f), rgba_from_u32_lit_comp(0x99ccff4c), rgba_from_u32_lit_comp(0xffffff1e), rgba_from_u32_lit_comp(0x5f12005f), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6382d4ec..b67689d1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1010,7 +1010,7 @@ RD_ThemeColorTable: {DropShadow "Drop Shadow" drop_shadow 0x0000007f 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} {DisabledOverlay "Disabled Overlay" disabled_overlay 0x0000003f 0xa6a6a63f 0x0000003f 0x0000003f 0x0000003f 0xe4dac090 0x0000003f 0x0000003f 0x0000003f ""} {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0xffffff0c 0x4848480c 0xffffff0c 0x0000000c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c ""} - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x0000003f 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} + {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x0000002f 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} {SelectionOverlay "Selection Overlay" selection_overlay 0x99ccff4c 0x003d7a48 0x99ccff4c 0x3d74ab4b 0x99ccff4c 0x678cb24c 0x99ccff4c 0x99ccff4c 0x99ccff4c ""} {HighlightOverlay "Highlight Overlay" highlight_overlay 0xffffff1e 0xffffff1e 0xffffff1e 0x0000001e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e ""} {HighlightOverlayError "Error Highlight Overlay" error_highlight_overlay 0x5f12005f 0xff30005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f ""} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a0bb5170..fb335dd4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12589,6 +12589,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, ctrl_string_from_handle(scratch.arena, entity->handle), expr); if(entity->string.size != 0) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 99297be1..5618a379 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -995,10 +995,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // but does not evaluate them, from e.g. "targets", which uses the group of target // cfgs, and the evaluations are of the targets themselves. // - B32 row_eval_matches_group = 0; + B32 row_cfg_eval_matches_group = 0; RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); + B32 row_entity_eval_matches_group = 0; + CTRL_Entity *evalled_entity = (info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(info.eval.space) : &ctrl_entity_nil); { - row_eval_matches_group = (evalled_cfg == info.group_cfg_child); + row_cfg_eval_matches_group = (evalled_cfg == info.group_cfg_child); + row_entity_eval_matches_group = (evalled_entity == info.group_entity); } // rjf: determine view ui rule @@ -1013,7 +1016,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(0){} // rjf: cfg rows - else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || + else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_cfg_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) { RD_Cfg *cfg = evalled_cfg; @@ -1052,16 +1055,18 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: entity rows - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && info.group_entity != &ctrl_entity_nil) + else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && row_entity_eval_matches_group && info.group_entity != &ctrl_entity_nil) || + (row->block->parent == &ev_nil_block && evalled_entity != &ctrl_entity_nil)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, info.group_entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); + CTRL_Entity *entity = evalled_entity; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); } // rjf: singular button for commands else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection || block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) && info.eval.space.kind == RD_EvalSpaceKind_MetaCmd && - row_eval_matches_group) + row_cfg_eval_matches_group) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; @@ -2944,6 +2949,17 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); } + else if(cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) + { + default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; + case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; + case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; + case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; + case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; + } + } } // rjf: (normally) single-click -> move selection here diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b3b01423..0e1921ef 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -792,7 +792,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - RD_RegsScope(.thread = thread->handle) rd_set_hover_regs(RD_RegSlot_Thread); + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle)); + RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) { From 81be64dac638bfacc4d4bbda2e1916b508c2c5b0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Feb 2025 13:40:12 -0800 Subject: [PATCH 118/755] more covergence, freeze controls on applicable ctrl entities when evalled --- src/dbg_engine/dbg_engine.mdesk | 6 +- src/raddbg/generated/raddbg.meta.c | 17 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 2143 ++++++++++++++-------------- src/raddbg/raddbg_core.h | 21 - src/raddbg/raddbg_views.c | 57 +- src/raddbg/raddbg_views.h | 1 + src/raddbg/raddbg_widgets.c | 2 +- 9 files changed, 1152 insertions(+), 1102 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 22961677..c75666ab 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -22,7 +22,7 @@ D_CmdTable: // | | | | {StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } {StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } {Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } - {SoftHaltRefresh 1 1 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SoftHaltRefresh 0 0 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } {SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations @@ -41,8 +41,8 @@ D_CmdTable: // | | | | {ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } {FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } {ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } - {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } - {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } + {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration {SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 098160e1..0d3ece11 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[282] = +RD_VocabInfo rd_vocab_info_table[283] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -104,8 +104,8 @@ RD_VocabInfo rd_vocab_info_table[282] = {str8_lit_comp("thaw_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), str8_lit_comp(""), RD_IconKind_Unlocked}, {str8_lit_comp("freeze_local_machine"), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, {str8_lit_comp("thaw_local_machine"), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), str8_lit_comp(""), RD_IconKind_Machine}, -{str8_lit_comp("freeze_entity"), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("thaw_entity"), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("freeze_entity"), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), str8_lit_comp(""), RD_IconKind_Unlocked}, +{str8_lit_comp("thaw_entity"), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), str8_lit_comp(""), RD_IconKind_Locked}, {str8_lit_comp("set_entity_color"), str8_lit_comp(""), str8_lit_comp("Set Entity Color"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("set_entity_name"), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("attach"), str8_lit_comp(""), str8_lit_comp("Attach"), str8_lit_comp(""), RD_IconKind_Null}, @@ -233,7 +233,8 @@ RD_VocabInfo rd_vocab_info_table[282] = {str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, {str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckFilled}, -{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_cfg"), str8_lit_comp(""), str8_lit_comp("Deselect Config Tree"), str8_lit_comp(""), RD_IconKind_RadioFilled}, {str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), str8_lit_comp(""), RD_IconKind_Trash}, {str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, @@ -346,7 +347,7 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[212] = +RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -361,7 +362,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -506,6 +507,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -562,7 +564,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -570,7 +572,6 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = {str8_lit_comp("step_out"), {OS_Key_F11, 0 |OS_Modifier_Shift }}, {str8_lit_comp("halt"), {OS_Key_X, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("halt"), {OS_Key_Pause, 0 }}, -{str8_lit_comp("soft_halt_refresh"), {OS_Key_R, 0 |OS_Modifier_Alt}}, {str8_lit_comp("run"), {OS_Key_F5, 0 }}, {str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("step_into"), {OS_Key_F11, 0 }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6ffbba5c..f1e41461 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -209,6 +209,7 @@ RD_CmdKind_ToggleCodeBytesVisibility, RD_CmdKind_EnableCfg, RD_CmdKind_DisableCfg, RD_CmdKind_SelectCfg, +RD_CmdKind_DeselectCfg, RD_CmdKind_RemoveCfg, RD_CmdKind_NameCfg, RD_CmdKind_ConditionCfg, @@ -554,7 +555,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[282]; +extern RD_VocabInfo rd_vocab_info_table[283]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b67689d1..da45f4af 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -511,7 +511,8 @@ RD_CmdTable: // | | | | //- rjf: general config operations {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } - {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } @@ -638,7 +639,6 @@ RD_DefaultBindingTable: { "step_out" F11 0 shift 0 } { "halt" X ctrl shift 0 } { "halt" Pause 0 0 0 } - { "soft_halt_refresh" R 0 0 alt } //- rjf: high-level composite target control operations { "run" F5 0 0 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fb335dd4..b3b80cf4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9,6 +9,1058 @@ #include "generated/raddbg.meta.c" +//////////////////////////////// +//~ rjf: Scheduler Eval Hooks + +typedef struct RD_CtrlEntityExpandAccel RD_CtrlEntityExpandAccel; +struct RD_CtrlEntityExpandAccel +{ + CTRL_EntityArray entities; +}; + +#if 0 // TODO(rjf): @cfg +typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; +struct RD_EntityExpandAccel +{ + RD_EntityArray entities; +}; + +EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_machine) +{ + EV_ExpandInfo info = {0}; + Temp scratch = scratch_begin(&arena, 1); + E_Eval eval = e_eval_from_expr(scratch.arena, expr); + CTRL_Entity *machine = rd_ctrl_entity_from_eval_space(eval.space); + if(machine->kind == CTRL_EntityKind_Machine) + { + CTRL_EntityList processes = {0}; + for(CTRL_Entity *child = machine->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == CTRL_EntityKind_Process) + { + ctrl_entity_list_push(scratch.arena, &processes, child); + } + } + CTRL_EntityArray *processes_array = push_array(arena, CTRL_EntityArray, 1); + *processes_array = ctrl_entity_array_from_list(arena, &processes); + info.user_data = processes_array; + info.row_count = processes.count; + info.rows_default_expanded = 1; + } + scratch_end(scratch); + return info; +} + +EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine) +{ + EV_ExpandRangeInfo info = {0}; + { + CTRL_EntityArray *processes = (CTRL_EntityArray *)user_data; + if(processes != 0) + { + info.row_exprs_count = dim_1u64(idx_range); + info.row_strings = push_array(arena, String8, info.row_exprs_count); + info.row_view_rules = push_array(arena, String8, info.row_exprs_count); + info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); + info.row_members = push_array(arena, E_Member *, info.row_exprs_count); + U64 row_expr_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) + { + CTRL_Entity *process = processes->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_MetaCtrlEntity); + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_base(type(CTRL_ProcessMetaEval));; + info.row_exprs[row_expr_idx] = expr; + info.row_members[row_expr_idx] = &e_member_nil; + } + } + } + return info; +} + +EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine) +{ + return num; +} + +EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine) +{ + return id; +} + +EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_process) +{ + EV_ExpandInfo info = {0}; + Temp scratch = scratch_begin(&arena, 1); + E_Eval eval = e_eval_from_expr(scratch.arena, expr); + CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space); + if(process->kind == CTRL_EntityKind_Process) + { + CTRL_EntityList threads = {0}; + for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == CTRL_EntityKind_Thread) + { + B32 is_in_filter = 1; + if(filter.size != 0) + { + is_in_filter = 0; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); + if(matches.count == matches.needle_part_count) + { + is_in_filter = 1; + } + else + { + DI_Scope *di_scope = di_scope_open(); + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(child); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &unwind); + for(U64 idx = 0; idx < call_stack.concrete_frame_count && idx < 5; idx += 1) + { + CTRL_CallStackFrame *f = &call_stack.frames[idx]; + String8 name = {0}; + name.str = rdi_string_from_idx(f->rdi, f->procedure->name_string_idx, &name.size); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); + if(matches.count == matches.needle_part_count) + { + is_in_filter = 1; + break; + } + } + di_scope_close(di_scope); + } + } + if(is_in_filter) + { + ctrl_entity_list_push(scratch.arena, &threads, child); + } + } + } + CTRL_EntityArray *threads_array = push_array(arena, CTRL_EntityArray, 1); + *threads_array = ctrl_entity_array_from_list(arena, &threads); + info.user_data = threads_array; + info.row_count = threads.count; + } + scratch_end(scratch); + return info; +} + +EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process) +{ + EV_ExpandRangeInfo info = {0}; + { + CTRL_EntityArray *threads = (CTRL_EntityArray *)user_data; + if(threads != 0) + { + info.row_exprs_count = dim_1u64(idx_range); + info.row_strings = push_array(arena, String8, info.row_exprs_count); + info.row_view_rules = push_array(arena, String8, info.row_exprs_count); + info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); + info.row_members = push_array(arena, E_Member *, info.row_exprs_count); + U64 row_expr_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) + { + CTRL_Entity *thread = threads->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCtrlEntity); + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_base(type(CTRL_ThreadMetaEval)); + info.row_exprs[row_expr_idx] = expr; + info.row_members[row_expr_idx] = &e_member_nil; + } + } + } + return info; +} + +EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process) +{ + return num; +} + +EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) +{ + return id; +} +#endif + +//////////////////////////////// +//~ rjf: Commands Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(commands) +{ + E_LookupInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + String8List cmd_names = {0}; + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 name = info->string; + str8_list_push(scratch.arena, &cmd_names, name); + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &cmd_names); + result.user_data = accel; + result.idxed_expr_count = accel->count; + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(commands) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + String8Array *accel = (String8Array *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(rhs_value.u64 < accel->count) + { + String8 cmd_name = accel->v[rhs_value.u64]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, (U64)cmd_kind)); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); + } + return result; +} + +//////////////////////////////// +//~ rjf: Watches Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(watches) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + String8 expr = rd_expr_from_cfg(n->v); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); + if(matches.count == matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + result.user_data = cfgs; + result.idxed_expr_count = cfgs->count + 1; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(watches) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; + exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs_strings[idx] = push_str8_copy(arena, expr_string); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(watches) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: Locals Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(locals) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); + e_string2num_map_node_array_sort__in_place(&nodes); + String8List exprs_filtered = {0}; + for EachIndex(idx, nodes.count) + { + String8 local_expr_string = nodes.v[idx]->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_filtered); + result.user_data = accel; + result.idxed_expr_count = accel->count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(locals) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 expr_string = accel->v[read_range.min + idx]; + exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs_strings[idx] = push_str8_copy(arena, expr_string); + } +} + +//////////////////////////////// +//~ rjf: Registers Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(registers) +{ + 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); + U64 alias_count = regs_alias_code_count_from_arch(arch); + String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); + String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); + String8List exprs_list = {0}; + for(U64 idx = 1; idx < reg_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); + } + } + for(U64 idx = 1; idx < alias_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_list); + E_LookupInfo info = {accel, 0, accel->count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(registers) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 register_name = accel->v[read_range.min + idx]; + String8 register_expr = push_str8f(arena, "reg:%S", register_name); + exprs_strings[idx] = register_name; + exprs[idx] = e_parse_expr_from_text(arena, register_expr); + } +} + +//////////////////////////////// +//~ rjf: Top-Level Config Eval Hooks + +typedef struct RD_TopLevelCfgLookupAccel RD_TopLevelCfgLookupAccel; +struct RD_TopLevelCfgLookupAccel +{ + String8Array cmds; + RD_CfgArray cfgs; + Rng1U64 cmds_idx_range; + Rng1U64 cfgs_idx_range; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name);\ + String8List cmds_list = {0}; + MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(arena, &cmds_list, cmd->string); + } + RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); + accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); + accel->cmds = str8_array_from_list(arena, &cmds_list); + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); + result.user_data = accel; + result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(rhs_value.u64 < accel->cfgs.count) + { + RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64]; + E_Space cfg_space = rd_eval_space_from_cfg(cfg); + String8 cfg_name = cfg->string; + E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); + result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = cfg_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) +{ + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + Rng1U64 cmds_idx_range = accel->cmds_idx_range; + Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; + U64 dst_idx = 0; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: fill commands + { + Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")); + E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + exprs[dst_idx] = e_expr_irext_array_index(arena, commands, &commands_irtree, (U64)cmd_kind-1); + } + } + + // rjf: fill cfgs + { + Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + exprs[dst_idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx + read_range.min - cfgs_idx_range.min); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) +{ + U64 id = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(num != 0) + { + U64 idx = num-1; + if(contains_1u64(accel->cfgs_idx_range, idx)) + { + RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; + id = cfg->id; + } + else if(contains_1u64(accel->cmds_idx_range, idx)) + { + id = num; + id |= (1ull<<63); + } + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) +{ + U64 num = 0; + RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + if(id != 0) + { + if(id & (1ull<<63)) + { + num = id; + num &= ~(1ull<<63); + } + else for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx + accel->cfgs_idx_range.min + 1; + break; + } + } + } + return num; +} + +//////////////////////////////// +//~ rjf: Thread Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(thread) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(thread) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("call_stack"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(thread) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("call_stack")); + } + scratch_end(scratch); +} + +//////////////////////////////// +//~ rjf: Call Stack Eval Hooks + +typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; +struct RD_CallStackLookupAccel +{ + Arch arch; + CTRL_Handle process; + CTRL_CallStack call_stack; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(call_stack) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + U128 u128 = interp.value.u128; + CTRL_Handle handle = {0}; + MemoryCopyStruct(&handle, &u128); + CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + if(entity->kind == CTRL_EntityKind_Thread) + { + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); + accel->arch = entity->arch; + accel->process = process->handle; + accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); + result.idxed_expr_count = accel->call_stack.count; + } + result.user_data = accel; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; + CTRL_CallStack *call_stack = &accel->call_stack; + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) + { + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); + CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); + result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); + } + return result; +} + +//////////////////////////////// +//~ rjf: Target / Environment Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(target) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(target) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("environment"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCfgCollection), e_irtree_const_u(arena, cfg->id)); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(target) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("environment")); + } + scratch_end(scratch); +} + +E_LOOKUP_INFO_FUNCTION_DEF(environment) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + RD_CfgID id = interpret.value.u64; + RD_Cfg *target = rd_cfg_from_id(id); + RD_CfgList env_strings = {0}; + for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("environment"), 0)) + { + rd_cfg_list_push(scratch.arena, &env_strings, child); + } + } + RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); + *accel = rd_cfg_array_from_list(arena, &env_strings); + result.user_data = accel; + result.idxed_expr_count = accel->count + 1; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(environment) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(environment) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: Control Entity Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 name = rd_singular_from_code_name_plural(lhs_type->name); + CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) + { + entity_kind = k; + break; + } + } + CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + CTRL_EntityList list__filtered = list; + if(filter.size != 0) + { + MemoryZeroStruct(&list__filtered); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); + if(matches.count == matches.needle_part_count) + { + ctrl_entity_list_push(scratch.arena, &list__filtered, entity); + } + } + } + CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); + *array = ctrl_entity_array_from_list(arena, &list__filtered); + result.user_data = array; + result.idxed_expr_count = list.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < entities->count) + { + CTRL_Entity *entity = entities->v[rhs_value.u64]; + E_Space entity_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 entity_name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey entity_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, entity_name); + result.irtree_and_type.root = e_irtree_set_space(arena, entity_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = entity_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +//////////////////////////////// +//~ rjf: Debug Info Tables Eval Hooks + +typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; +struct RD_DebugInfoTableLookupAccel +{ + RDI_SectionKind section; + U64 rdis_count; + RDI_Parsed **rdis; + DI_SearchItemArray items; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) +{ + Temp scratch = scratch_begin(&arena, 1); + + // rjf: determine which debug info section we're dealing with + RDI_SectionKind section = RDI_SectionKind_NULL; + { + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(0){} + else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} + else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} + else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} + else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} + } + + // rjf: gather debug info table items + RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); + if(section != RDI_SectionKind_NULL) + { + U64 endt_us = d_state->frame_eval_memread_endt_us; + + //- 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(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: query all filtered items from dbgi searching system + U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; + B32 items_stale = 0; + DI_SearchParams params = {section, dbgi_keys}; + accel->section = section; + accel->rdis_count = rdis_count; + accel->rdis = rdis; + accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + if(items_stale) + { + rd_request_frame(); + } + } + E_LookupInfo info = {accel, 0, accel->items.count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 needed_row_count = dim_1u64(idx_range); + for EachIndex(idx, needed_row_count) + { + // rjf: unpack row + DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; + + // rjf: skip bad elements + if(item->dbgi_idx >= accel->rdis_count) + { + continue; + } + + // rjf: unpack row info + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; + + // rjf: build expr + E_Expr *item_expr = &e_expr_nil; + { + U64 element_idx = item->idx; + switch(accel->section) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); + RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Value; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_GlobalVariables: + { + RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); + U64 voff = gvar->voff; + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = gvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_ThreadVariables: + { + RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = tvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_UDTs: + { + RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + item_expr->type_key = type_key; + }break; + } + } + + // rjf: fill + exprs[idx] = item_expr; + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 id = 0; + if(0 < num && num <= accel->items.count) + { + id = accel->items.v[num-1].idx+1; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); + return num; +} + //////////////////////////////// //~ rjf: Config ID Type Functions @@ -5561,7 +6613,6 @@ rd_window_frame(void) rd_cmd_kind_info_table[D_CmdKind_KillAll].string, rd_cmd_kind_info_table[D_CmdKind_Restart].string, rd_cmd_kind_info_table[D_CmdKind_Halt].string, - rd_cmd_kind_info_table[D_CmdKind_SoftHaltRefresh].string, rd_cmd_kind_info_table[D_CmdKind_StepInto].string, rd_cmd_kind_info_table[D_CmdKind_StepOver].string, rd_cmd_kind_info_table[D_CmdKind_StepOut].string, @@ -5573,7 +6624,6 @@ rd_window_frame(void) 'k', 's', 'h', - 'f', 'i', 'o', 't', @@ -6126,24 +7176,25 @@ rd_window_frame(void) // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) { -#if 0 // TODO(rjf): @cfg_panels - for(RD_Panel *panel = ws->root_panel; - !rd_panel_is_nil(panel); - panel = rd_panel_rec_depth_first_pre(panel).next) + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - if(!rd_panel_is_nil(panel->first)) { continue; } - Rng2F32 panel_rect = rd_target_rect_from_panel(content_rect, ws->root_panel, panel); - RD_View *view = rd_selected_tab_from_panel(panel); - if(!rd_view_is_nil(view) && - contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(view->scroll_pos.x.off) > 0.01f || - abs_f32(view->scroll_pos.y.off) > 0.01f)) + if(panel->first != &rd_nil_panel_node) { continue; } + RD_Cfg *tab = panel->selected_tab; + if(tab != &rd_nil_cfg) { - build_hover_eval = 0; - ws->hover_eval_first_frame_idx = rd_state->frame_index; + RD_ViewState *vs = rd_view_state_from_cfg(tab); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + if(contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(vs->scroll_pos.x.off) > 0.01f || + abs_f32(vs->scroll_pos.y.off) > 0.01f)) + { + build_hover_eval = 0; + ws->hover_eval_first_frame_idx = rd_state->frame_index; + } } } -#endif } // rjf: evaluate hover-evaluation expression - if it doesn't evaluate, then don't build anything @@ -8190,1045 +9241,6 @@ rd_window_frame(void) //////////////////////////////// //~ rjf: Eval Visualization -typedef struct RD_CtrlEntityExpandAccel RD_CtrlEntityExpandAccel; -struct RD_CtrlEntityExpandAccel -{ - CTRL_EntityArray entities; -}; - -#if 0 // TODO(rjf): @cfg -typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; -struct RD_EntityExpandAccel -{ - RD_EntityArray entities; -}; - -//- rjf: control entity hierarchies - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *machine = rd_ctrl_entity_from_eval_space(eval.space); - if(machine->kind == CTRL_EntityKind_Machine) - { - CTRL_EntityList processes = {0}; - for(CTRL_Entity *child = machine->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Process) - { - ctrl_entity_list_push(scratch.arena, &processes, child); - } - } - CTRL_EntityArray *processes_array = push_array(arena, CTRL_EntityArray, 1); - *processes_array = ctrl_entity_array_from_list(arena, &processes); - info.user_data = processes_array; - info.row_count = processes.count; - info.rows_default_expanded = 1; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *processes = (CTRL_EntityArray *)user_data; - if(processes != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *process = processes->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ProcessMetaEval));; - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine) -{ - return id; -} - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space); - if(process->kind == CTRL_EntityKind_Process) - { - CTRL_EntityList threads = {0}; - for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Thread) - { - B32 is_in_filter = 1; - if(filter.size != 0) - { - is_in_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - } - else - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(child); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &unwind); - for(U64 idx = 0; idx < call_stack.concrete_frame_count && idx < 5; idx += 1) - { - CTRL_CallStackFrame *f = &call_stack.frames[idx]; - String8 name = {0}; - name.str = rdi_string_from_idx(f->rdi, f->procedure->name_string_idx, &name.size); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - break; - } - } - di_scope_close(di_scope); - } - } - if(is_in_filter) - { - ctrl_entity_list_push(scratch.arena, &threads, child); - } - } - } - CTRL_EntityArray *threads_array = push_array(arena, CTRL_EntityArray, 1); - *threads_array = ctrl_entity_array_from_list(arena, &threads); - info.user_data = threads_array; - info.row_count = threads.count; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *threads = (CTRL_EntityArray *)user_data; - if(threads != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *thread = threads->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ThreadMetaEval)); - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) -{ - return id; -} -#endif - -//- rjf: commands - -E_LOOKUP_INFO_FUNCTION_DEF(commands) -{ - E_LookupInfo result = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - String8List cmd_names = {0}; - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - String8 name = info->string; - str8_list_push(scratch.arena, &cmd_names, name); - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &cmd_names); - result.user_data = accel; - result.idxed_expr_count = accel->count; - scratch_end(scratch); - } - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(commands) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - String8Array *accel = (String8Array *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(rhs_value.u64 < accel->count) - { - String8 cmd_name = accel->v[rhs_value.u64]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, (U64)cmd_kind)); - result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); - result.irtree_and_type.mode = E_Mode_Value; - } - scratch_end(scratch); - } - return result; -} - -//- rjf: watch expressions - -E_LOOKUP_INFO_FUNCTION_DEF(watches) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - RD_CfgList cfgs_list__filtered = cfgs_list; - if(filter.size != 0) - { - MemoryZeroStruct(&cfgs_list__filtered); - for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) - { - String8 expr = rd_expr_from_cfg(n->v); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); - if(matches.count == matches.needle_part_count) - { - rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); - } - } - } - RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); - cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); - result.user_data = cfgs; - result.idxed_expr_count = cfgs->count + 1; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(watches) -{ - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) - { - String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs[idx] = e_parse_expr_from_text(arena, expr_string); - exprs_strings[idx] = push_str8_copy(arena, expr_string); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(watches) -{ - U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) - { - U64 idx = (num-1); - id = cfgs->v[idx]->id; - } - else if(num == cfgs->count+1) - { - id = max_U64; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) -{ - U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(id != 0 && id != max_U64) - { - for EachIndex(idx, cfgs->count) - { - if(cfgs->v[idx]->id == id) - { - num = idx+1; - break; - } - } - } - else if(id == max_U64) - { - num = cfgs->count + 1; - } - return num; -} - -//- rjf: local variables - -E_LOOKUP_INFO_FUNCTION_DEF(locals) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); - e_string2num_map_node_array_sort__in_place(&nodes); - String8List exprs_filtered = {0}; - for EachIndex(idx, nodes.count) - { - String8 local_expr_string = nodes.v[idx]->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_filtered); - result.user_data = accel; - result.idxed_expr_count = accel->count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(locals) -{ - String8Array *accel = (String8Array *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - String8 expr_string = accel->v[read_range.min + idx]; - exprs[idx] = e_parse_expr_from_text(arena, expr_string); - exprs_strings[idx] = push_str8_copy(arena, expr_string); - } -} - -//- rjf: registers - -E_LOOKUP_INFO_FUNCTION_DEF(registers) -{ - 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); - U64 alias_count = regs_alias_code_count_from_arch(arch); - String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); - String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); - String8List exprs_list = {0}; - for(U64 idx = 1; idx < reg_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); - } - } - for(U64 idx = 1; idx < alias_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_list); - E_LookupInfo info = {accel, 0, accel->count}; - scratch_end(scratch); - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(registers) -{ - String8Array *accel = (String8Array *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - String8 register_name = accel->v[read_range.min + idx]; - String8 register_expr = push_str8f(arena, "reg:%S", register_name); - exprs_strings[idx] = register_name; - exprs[idx] = e_parse_expr_from_text(arena, register_expr); - } -} - -//- rjf: top-level configurations - -typedef struct RD_TopLevelCfgLookupAccel RD_TopLevelCfgLookupAccel; -struct RD_TopLevelCfgLookupAccel -{ - String8Array cmds; - RD_CfgArray cfgs; - Rng1U64 cmds_idx_range; - Rng1U64 cfgs_idx_range; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name);\ - String8List cmds_list = {0}; - MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); - MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); - for MD_EachNode(cmd, collection_cmds_root->first) - { - str8_list_push(arena, &cmds_list, cmd->string); - } - RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); - accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); - accel->cmds = str8_array_from_list(arena, &cmds_list); - accel->cmds_idx_range = r1u64(0, accel->cmds.count); - accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); - result.user_data = accel; - result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(rhs_value.u64 < accel->cfgs.count) - { - RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64]; - E_Space cfg_space = rd_eval_space_from_cfg(cfg); - String8 cfg_name = cfg->string; - E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); - result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = cfg_type_key; - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) -{ - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - Rng1U64 cmds_idx_range = accel->cmds_idx_range; - Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; - U64 dst_idx = 0; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - - // rjf: fill commands - { - Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); - U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")); - E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); - for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) - { - String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - exprs[dst_idx] = e_expr_irext_array_index(arena, commands, &commands_irtree, (U64)cmd_kind-1); - } - } - - // rjf: fill cfgs - { - Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); - U64 read_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) - { - exprs[dst_idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx + read_range.min - cfgs_idx_range.min); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) -{ - U64 id = 0; - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - if(num != 0) - { - U64 idx = num-1; - if(contains_1u64(accel->cfgs_idx_range, idx)) - { - RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; - id = cfg->id; - } - else if(contains_1u64(accel->cmds_idx_range, idx)) - { - id = num; - id |= (1ull<<63); - } - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) -{ - U64 num = 0; - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; - if(id != 0) - { - if(id & (1ull<<63)) - { - num = id; - num &= ~(1ull<<63); - } - else for EachIndex(idx, accel->cfgs.count) - { - if(accel->cfgs.v[idx]->id == id) - { - num = idx + accel->cfgs_idx_range.min + 1; - break; - } - } - } - return num; -} - -//- rjf: threads / callstacks - -E_LOOKUP_INFO_FUNCTION_DEF(thread) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(thread) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("call_stack"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(thread) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("call_stack")); - } - scratch_end(scratch); -} - -typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; -struct RD_CallStackLookupAccel -{ - Arch arch; - CTRL_Handle process; - CTRL_CallStack call_stack; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(call_stack) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - U128 u128 = interp.value.u128; - CTRL_Handle handle = {0}; - MemoryCopyStruct(&handle, &u128); - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); - if(entity->kind == CTRL_EntityKind_Thread) - { - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); - accel->arch = entity->arch; - accel->process = process->handle; - accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); - result.idxed_expr_count = accel->call_stack.count; - } - result.user_data = accel; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; - CTRL_CallStack *call_stack = &accel->call_stack; - if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) - { - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); - CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); - result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); - result.irtree_and_type.mode = E_Mode_Value; - } - scratch_end(scratch); - } - return result; -} - -//- rjf: targets / environment - -E_LOOKUP_INFO_FUNCTION_DEF(target) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(target) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("environment"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCfgCollection), e_irtree_const_u(arena, cfg->id)); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(target) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("environment")); - } - scratch_end(scratch); -} - -E_LOOKUP_INFO_FUNCTION_DEF(environment) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interpret = e_interpret(bytecode); - RD_CfgID id = interpret.value.u64; - RD_Cfg *target = rd_cfg_from_id(id); - RD_CfgList env_strings = {0}; - for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) - { - if(str8_match(child->string, str8_lit("environment"), 0)) - { - rd_cfg_list_push(scratch.arena, &env_strings, child); - } - } - RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); - *accel = rd_cfg_array_from_list(arena, &env_strings); - result.user_data = accel; - result.idxed_expr_count = accel->count + 1; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(environment) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) - { - RD_Cfg *cfg = cfgs->v[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(environment) -{ - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) - { - exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) -{ - U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) - { - U64 idx = (num-1); - id = cfgs->v[idx]->id; - } - else if(num == cfgs->count+1) - { - id = max_U64; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) -{ - U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(id != 0 && id != max_U64) - { - for EachIndex(idx, cfgs->count) - { - if(cfgs->v[idx]->id == id) - { - num = idx+1; - break; - } - } - } - else if(id == max_U64) - { - num = cfgs->count + 1; - } - return num; -} - -//- rjf: control entities - -E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - String8 name = rd_singular_from_code_name_plural(lhs_type->name); - CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; - for EachNonZeroEnumVal(CTRL_EntityKind, k) - { - if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) - { - entity_kind = k; - break; - } - } - CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); - CTRL_EntityList list__filtered = list; - if(filter.size != 0) - { - MemoryZeroStruct(&list__filtered); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); - if(matches.count == matches.needle_part_count) - { - ctrl_entity_list_push(scratch.arena, &list__filtered, entity); - } - } - } - CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); - *array = ctrl_entity_array_from_list(arena, &list__filtered); - result.user_data = array; - result.idxed_expr_count = list.count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < entities->count) - { - CTRL_Entity *entity = entities->v[rhs_value.u64]; - E_Space entity_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - String8 entity_name = ctrl_entity_kind_code_name_table[entity->kind]; - E_TypeKey entity_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, entity_name); - result.irtree_and_type.root = e_irtree_set_space(arena, entity_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = entity_type_key; - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -//- rjf: debug info tables - -typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; -struct RD_DebugInfoTableLookupAccel -{ - RDI_SectionKind section; - U64 rdis_count; - RDI_Parsed **rdis; - DI_SearchItemArray items; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) -{ - Temp scratch = scratch_begin(&arena, 1); - - // rjf: determine which debug info section we're dealing with - RDI_SectionKind section = RDI_SectionKind_NULL; - { - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if(0){} - else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} - else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} - else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} - else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} - } - - // rjf: gather debug info table items - RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); - if(section != RDI_SectionKind_NULL) - { - U64 endt_us = d_state->frame_eval_memread_endt_us; - - //- 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(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: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; - B32 items_stale = 0; - DI_SearchParams params = {section, dbgi_keys}; - accel->section = section; - accel->rdis_count = rdis_count; - accel->rdis = rdis; - accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - } - E_LookupInfo info = {accel, 0, accel->items.count}; - scratch_end(scratch); - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 needed_row_count = dim_1u64(idx_range); - for EachIndex(idx, needed_row_count) - { - // rjf: unpack row - DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; - - // rjf: skip bad elements - if(item->dbgi_idx >= accel->rdis_count) - { - continue; - } - - // rjf: unpack row info - RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; - - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; - { - U64 element_idx = item->idx; - switch(accel->section) - { - default:{}break; - case RDI_SectionKind_Procedures: - { - RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); - RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_GlobalVariables: - { - RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_ThreadVariables: - { - RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_UDTs: - { - RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; - }break; - } - } - - // rjf: fill - exprs[idx] = item_expr; - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 id = 0; - if(0 < num && num <= accel->items.count) - { - id = accel->items.v[num-1].idx+1; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); - return num; -} - 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_Expr *root_expr, E_Eval eval, String8List *out) { @@ -9282,7 +9294,23 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul if(eval.expr->kind == E_ExprKind_MemberAccess) { E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr->first); - E_Member member = e_type_member_from_key_name__cached(irtree.type_key, eval.expr->last->string); + E_TypeKey struct_type = irtree.type_key; + for(B32 done = 0; !done;) + { + E_TypeKind kind = e_type_kind_from_key(struct_type); + if(kind == E_TypeKind_Null || + kind == E_TypeKind_Struct || + kind == E_TypeKind_Union || + kind == E_TypeKind_Class) + { + done = 1; + } + else if(e_type_kind_is_pointer_or_ref(kind)) + { + struct_type = e_type_direct_from_key(struct_type); + } + } + E_Member member = e_type_member_from_key_name__cached(struct_type, eval.expr->last->string); if(member.kind == E_MemberKind_Padding) { no_string = 1; @@ -14997,7 +15025,7 @@ Z(getting_started) { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_CfgList all_of_the_same_kind = rd_cfg_top_level_list_from_string(scratch.arena, cfg->string); - B32 is_selected = rd_disabled_from_cfg(cfg); + B32 is_selected = !rd_disabled_from_cfg(cfg); for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) { RD_Cfg *c = n->v; @@ -15018,6 +15046,7 @@ Z(getting_started) case RD_CmdKind_DisableCfg: case RD_CmdKind_DisableBreakpoint: case RD_CmdKind_DisableTarget: + case RD_CmdKind_DeselectCfg: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 13b17b3e..502fe28c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -126,27 +126,6 @@ struct RD_ViewUIRuleMap U64 slots_count; }; -//////////////////////////////// -//~ rjf: View Rule Info Types - -typedef U32 RD_ViewRuleInfoFlags; -enum -{ - RD_ViewRuleInfoFlag_ShowInDocs = (1<<0), - RD_ViewRuleInfoFlag_CanFilter = (1<<1), - RD_ViewRuleInfoFlag_FilterIsCode = (1<<2), - RD_ViewRuleInfoFlag_TypingAutomaticallyFilters = (1<<3), - RD_ViewRuleInfoFlag_CanUseInWatchTable = (1<<4), - RD_ViewRuleInfoFlag_CanFillValueCell = (1<<5), - RD_ViewRuleInfoFlag_CanExpand = (1<<6), - RD_ViewRuleInfoFlag_ProjectFiltered = (1<<7), -}; - -#define RD_VIEW_RULE_UI_FUNCTION_SIG(name) void name(String8 string, MD_Node *params, Rng2F32 rect) -#define RD_VIEW_RULE_UI_FUNCTION_NAME(name) rd_view_rule_ui_##name -#define RD_VIEW_RULE_UI_FUNCTION_DEF(name) internal RD_VIEW_RULE_UI_FUNCTION_SIG(RD_VIEW_RULE_UI_FUNCTION_NAME(name)) -typedef RD_VIEW_RULE_UI_FUNCTION_SIG(RD_ViewRuleUIFunctionType); - //////////////////////////////// //~ rjf: View State Types diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5618a379..55736d88 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -795,7 +795,8 @@ rd_id_from_watch_cell(RD_WatchCell *cell) U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); - result = e_hash_from_string(result, cell->string); + result = e_hash_from_string(result, str8_struct(&cell->index)); + result = e_hash_from_string(result, str8_struct(&cell->default_pct)); return result; } @@ -803,6 +804,7 @@ internal RD_WatchCell * rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list) { RD_WatchCell *cell = push_array(arena, RD_WatchCell, 1); + cell->index = list->count; SLLQueuePush(list->first, list->last, cell); list->count += 1; return cell; @@ -812,7 +814,9 @@ internal RD_WatchCell * rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params) { RD_WatchCell *cell = rd_watch_cell_list_push(arena, list); + U64 index = cell->index; MemoryCopyStruct(cell, params); + cell->index = index; if(cell->pct == 0) { cell->pct = cell->default_pct; @@ -1046,6 +1050,22 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) cmd_kind = RD_CmdKind_EnableCfg; } }break; + case RD_CmdKind_SelectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DeselectCfg; + } + }break; + case RD_CmdKind_DeselectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_SelectCfg; + } + }break; } if(cmd_kind != RD_CmdKind_Null) { @@ -1060,6 +1080,17 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); + if(entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) + { + RD_CmdKind cmd_kind = RD_CmdKind_FreezeEntity; + if(ctrl_entity_tree_is_frozen(entity)) + { + cmd_kind = RD_CmdKind_ThawEntity; + } + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); + } } // rjf: singular button for commands @@ -1442,9 +1473,11 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); Temp scratch = scratch_begin(0, 0); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + B32 is_first_frame = 0; if(ewv->initialized == 0) { + is_first_frame = 1; ewv->initialized = 1; ewv->text_edit_arena = rd_push_view_arena(); } @@ -1509,7 +1542,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + if(implicit_root || is_first_frame) + { + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + } block_tree = ev_block_tree_from_eval(scratch.arena, eval_view, filter, eval); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); if(implicit_root && block_ranges.first != 0) @@ -2480,8 +2516,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } if(ui_double_clicked(sig)) { - min_pct__post = cell->default_pct; - max_pct__post = cell->next->default_pct; + F32 default_sum = cell->default_pct + cell->next->default_pct; + F32 current_sum = min_pct__pre + max_pct__pre;; + min_pct__post = current_sum * (cell->default_pct / default_sum); + max_pct__post = current_sum * (cell->next->default_pct / default_sum); ui_kill_action(); } RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -2982,9 +3020,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: has a command name? -> push command if(cell_info.cmd_name.size != 0) { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); RD_CmdKind kind = rd_cmd_kind_from_string(cell_info.cmd_name); - rd_cmd(kind, .cfg = cfg->id); + rd_cmd(kind, .cfg = cfg->id, .ctrl_entity = entity->handle); } // rjf: row has callstack info? -> select unwind @@ -5211,9 +5250,9 @@ rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) } #endif +#if 0 // TODO(rjf): @cfg RD_VIEW_RULE_UI_FUNCTION_DEF(settings) { -#if 0 // TODO(rjf): @cfg ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); @@ -5684,7 +5723,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) }break; case RD_SettingsItemKind_WindowSetting: { - // TODO(rjf): @cfg val_table = &window->setting_vals[0]; + val_table = &window->setting_vals[0]; }goto setting; case RD_SettingsItemKind_GlobalSetting:{}goto setting; setting:; @@ -5838,5 +5877,5 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(settings) rd_store_view_scroll_pos(scroll_pos); scratch_end(scratch); ProfEnd(); -#endif } +#endif diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 568b04f0..68e84df8 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -66,6 +66,7 @@ struct RD_WatchCell { RD_WatchCell *next; RD_WatchCellKind kind; + U64 index; String8 string; E_Eval eval; DR_FStrList fstrs; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0e1921ef..1f46e14f 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -614,7 +614,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); - F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-20.f * rd_state->frame_dt))) : 1.f; + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; B32 do_thread_lines = rd_setting_b32_from_name(str8_lit("thread_lines")); B32 do_thread_glow = rd_setting_b32_from_name(str8_lit("thread_glow")); B32 do_bp_lines = rd_setting_b32_from_name(str8_lit("breakpoint_lines")); From 404ad620ef76fc2527b154fec38eae54f5fafc6e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Feb 2025 13:32:46 -0800 Subject: [PATCH 119/755] more convergence; split scheduler into machines, process, and threads tabs. most people just care about threads, and so that should be the default/common case --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 194 +++++++++++++++++++++++++++-- src/raddbg/raddbg_views.c | 7 +- 5 files changed, 201 insertions(+), 12 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0d3ece11..433a1468 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[283] = +RD_VocabInfo rd_vocab_info_table[285] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -53,7 +53,9 @@ RD_VocabInfo rd_vocab_info_table[283] = {str8_lit_comp("vtx_size"), str8_lit_comp("vtx_sizes"), str8_lit_comp("Vertex Buffer Size"), str8_lit_comp("Vertex Buffer Sizes"), RD_IconKind_Null}, {str8_lit_comp("label"), str8_lit_comp("labels"), str8_lit_comp("Label"), str8_lit_comp("Labels"), RD_IconKind_Null}, {str8_lit_comp("thread"), str8_lit_comp("threads"), str8_lit_comp("Thread"), str8_lit_comp("Threads"), RD_IconKind_Thread}, -{str8_lit_comp("process"), str8_lit_comp("processes"), str8_lit_comp("Process"), str8_lit_comp("Processes"), RD_IconKind_Threads}, +{str8_lit_comp("threads"), str8_lit_comp(""), str8_lit_comp("Threads"), str8_lit_comp(""), RD_IconKind_Threads}, +{str8_lit_comp("process"), str8_lit_comp("processes"), str8_lit_comp("Process"), str8_lit_comp("Processes"), RD_IconKind_Scheduler}, +{str8_lit_comp("processes"), str8_lit_comp(""), str8_lit_comp("Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, {str8_lit_comp("machine"), str8_lit_comp("machines"), str8_lit_comp("Machine"), str8_lit_comp("Machines"), RD_IconKind_Machine}, {str8_lit_comp("module"), str8_lit_comp("modules"), str8_lit_comp("Module"), str8_lit_comp("Modules"), RD_IconKind_Module}, {str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index f1e41461..ac4d4898 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -555,7 +555,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[283]; +extern RD_VocabInfo rd_vocab_info_table[285]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index da45f4af..d4644d21 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -65,7 +65,9 @@ RD_VocabTable: {vtx_size _ "Vertex Buffer Size" _ Null } {label _ "Label" _ Null } {thread _ "Thread" _ Thread } - {process processes "Process" "Processes" Threads } + {threads "" "Threads" "" Threads } + {process processes "Process" "Processes" Scheduler } + {processes "" "Processes" "" Scheduler } {machine _ "Machine" _ Machine } {module _ "Module" _ Module } {getting_started "" "Getting Started" "" QuestionMark } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b3b80cf4..4678613c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -560,6 +560,161 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) return num; } +//////////////////////////////// +//~ rjf: Machine Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(machine) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(machine) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("processes"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("machine_processes")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(machine) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + String8 extras[] = + { + str8_lit("processes"), + }; + Rng1U64 extras_idx_range = r1u64(lhs_type->count, lhs_type->count + ArrayCount(extras)); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, extras[extras_idx]); + } + scratch_end(scratch); +} + +//////////////////////////////// +//~ rjf: Process Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(process) +{ + E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + result.named_expr_count += 1; + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(process) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("modules"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("process_modules")); + result.irtree_and_type.mode = E_Mode_Offset; + } + if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("threads"), 0)) + { + E_Eval eval = e_eval_from_expr(scratch.arena, lhs); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("process_threads")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(process) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + String8 extras[] = + { + str8_lit("modules"), + //str8_lit("threads"), + }; + Rng1U64 extras_idx_range = r1u64(lhs_type->count, lhs_type->count + ArrayCount(extras)); + Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); + U64 extras_count = dim_1u64(extras_read_range); + for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) + { + U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, extras[0]); + } + scratch_end(scratch); +} + +typedef struct RD_ProcessLookupAccel RD_ProcessLookupAccel; +struct RD_ProcessLookupAccel +{ + CTRL_EntityArray children; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(process_modules) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + CTRL_Entity *process = rd_ctrl_entity_from_eval_space(interpret.space); + CTRL_EntityList modules = {0}; + for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == CTRL_EntityKind_Module) + { + ctrl_entity_list_push(scratch.arena, &modules, child); + } + } + RD_ProcessLookupAccel *accel = push_array(arena, RD_ProcessLookupAccel, 1); + accel->children = ctrl_entity_array_from_list(arena, &modules); + result.user_data = accel; + result.idxed_expr_count = modules.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(process_modules) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_ProcessLookupAccel *accel = (RD_ProcessLookupAccel *)user_data; + E_Value rhs_value = e_value_from_expr(rhs); + if(0 <= rhs_value.u64 && rhs_value.u64 < accel->children.count) + { + CTRL_Entity *entity = accel->children.v[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + //////////////////////////////// //~ rjf: Thread Eval Hooks @@ -2854,6 +3009,16 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } + //- rjf: push frozen icon, if frozen + if((entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) && + ctrl_entity_tree_is_frozen(entity)) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + //- rjf: push containing process prefix if(entity->kind == CTRL_EntityKind_Thread || entity->kind == CTRL_EntityKind_Module) @@ -2867,6 +3032,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon if(process_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = size*0.9f); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); } } @@ -2878,6 +3044,13 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon .raster_flags = rd_raster_flags_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), .color = color); + //- rjf: push PID + if(entity->kind == CTRL_EntityKind_Process) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = size*0.85f); + } + //- rjf: threads get callstack extras if(entity->kind == CTRL_EntityKind_Thread && include_extras) { @@ -12588,8 +12761,8 @@ rd_frame(void) } evallable_ctrl_table[] = { - { str8_lit("machine") }, - { str8_lit("process") }, + { str8_lit("machine"), .info = E_LOOKUP_INFO_FUNCTION_NAME(machine), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(machine), .range = E_LOOKUP_RANGE_FUNCTION_NAME(machine) }, + { str8_lit("process"), .info = E_LOOKUP_INFO_FUNCTION_NAME(process), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(process), .range = E_LOOKUP_RANGE_FUNCTION_NAME(process) }, { str8_lit("thread"), .info = E_LOOKUP_INFO_FUNCTION_NAME(thread), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(thread), .range = E_LOOKUP_RANGE_FUNCTION_NAME(thread) }, { str8_lit("module") }, }; @@ -12669,6 +12842,9 @@ rd_frame(void) e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), .info = E_LOOKUP_INFO_FUNCTION_NAME(call_stack), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(call_stack)); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("process_modules"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(process_modules), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(process_modules)); } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) @@ -14127,7 +14303,9 @@ X(call_stack)\ X(breakpoints)\ X(watch_pins)\ X(targets)\ -X(scheduler)\ +X(threads)\ +X(processes)\ +X(machines)\ X(modules)\ Y(output, text, "query:output")\ Y(disasm, disasm, "")\ @@ -14222,9 +14400,11 @@ Z(getting_started) RD_Cfg *root_1_0 = rd_cfg_new(root_1, str8_lit("0.50")); RD_Cfg *root_1_1 = rd_cfg_new(root_1, str8_lit("0.50")); rd_cfg_insert_child(root_1_0, root_1_0->last, targets); - rd_cfg_insert_child(root_1_1, root_1_1->last, scheduler); + rd_cfg_insert_child(root_1_1, root_1_1->last, threads); + rd_cfg_insert_child(root_1_1, root_1_1->last, processes); + rd_cfg_insert_child(root_1_1, root_1_1->last, machines); rd_cfg_new(targets, str8_lit("selected")); - rd_cfg_new(scheduler, str8_lit("selected")); + rd_cfg_new(threads, str8_lit("selected")); // rjf: root 0_0 split RD_Cfg *root_0_0_0 = rd_cfg_new(root_0_0, str8_lit("0.25")); @@ -14294,11 +14474,11 @@ Z(getting_started) rd_cfg_insert_child(root_0_0, root_0_0->last, watches); rd_cfg_insert_child(root_0_0, root_0_0->last, types); rd_cfg_new(watches, str8_lit("selected")); - rd_cfg_insert_child(root_0_1, root_0_1->last, scheduler); + rd_cfg_insert_child(root_0_1, root_0_1->last, threads); rd_cfg_insert_child(root_0_1, root_0_1->last, targets); rd_cfg_insert_child(root_0_1, root_0_1->last, breakpoints); rd_cfg_insert_child(root_0_1, root_0_1->last, watch_pins); - rd_cfg_new(scheduler, str8_lit("selected")); + rd_cfg_new(threads, str8_lit("selected")); rd_cfg_insert_child(root_0_2, root_0_2->last, disasm); rd_cfg_insert_child(root_0_2, root_0_2->last, output); rd_cfg_new(disasm, str8_lit("selected")); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 55736d88..92e3d6b5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3398,7 +3398,12 @@ RD_VIEW_UI_FUNCTION_DEF(text) DI_KeyList dbgi_keys = {0}; if(!file_is_missing) { - RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, RD_CodeViewBuildFlag_All, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); + RD_CodeViewBuildFlags flags = RD_CodeViewBuildFlag_All; + if(rd_regs()->file_path.size == 0) + { + flags &= ~RD_CodeViewBuildFlag_Margins; + } + RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, flags, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); dbgi_keys = result.dbgi_keys; } From b7f6b301ec747cfe47e5bbf8111b72fccc498c7f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Feb 2025 14:52:40 -0800 Subject: [PATCH 120/755] eliminate unnecessary complication for debugger query evaluations; formalize them in the schemas, use set-hook rule to automatically plug in querying functions for them --- src/eval/eval_ir.c | 8 +- src/eval/eval_types.c | 3 +- src/eval/eval_types.h | 2 +- src/raddbg/generated/raddbg.meta.c | 8 +- src/raddbg/raddbg.mdesk | 7 +- src/raddbg/raddbg_core.c | 409 ++++++----------------------- src/raddbg/raddbg_core.h | 3 - src/raddbg/raddbg_views.c | 23 +- src/raddbg/raddbg_widgets.c | 1 + 9 files changed, 109 insertions(+), 355 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 2ff4ff15..e38c4423 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -221,6 +221,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) B32 r_found = 0; E_TypeKey r_type = zero_struct; U64 r_value = 0; + String8 r_query_name = {0}; B32 r_is_constant_value = 0; { Temp scratch = scratch_begin(&arena, 1); @@ -231,6 +232,10 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) r_type = match.type_key; r_value = match.off; } + if(match.kind == E_MemberKind_Query) + { + r_query_name = exprr->string; + } if(match.kind == E_MemberKind_Null) { E_Type *type = e_type_from_key__cached(check_type_key); @@ -290,6 +295,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) { // rjf: build tree E_IRNode *new_tree = l.root; + E_TypeKey new_tree_type = r_type; E_Mode mode = l.mode; if(l_restype_kind == E_TypeKind_Ptr || l_restype_kind == E_TypeKind_LRef || @@ -625,7 +631,7 @@ E_IRGEN_FUNCTION_DEF(slice) E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count, 0); E_MemberList slice_type_members = {0}; e_member_list_push(scratch.arena, &slice_type_members, count_member); - e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off}); + e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .off = base_ptr_member->off}); E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members); slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch, .kind = E_TypeKind_Struct, diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6f3adae4..78943d80 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -501,7 +501,7 @@ e_type_key_cons_base(Type *type) for(U64 idx = 0; idx < type->count; idx += 1) { E_TypeKey member_type_key = e_type_key_cons_base(type->members[idx].type); - e_member_list_push_new(scratch.arena, &members, .name = type->members[idx].name, .off = type->members[idx].value, .type_key = member_type_key, .pretty_name = type->members[idx].pretty_name); + e_member_list_push_new(scratch.arena, &members, .name = type->members[idx].name, .off = type->members[idx].value, .type_key = member_type_key); } E_MemberArray members_array = e_member_array_from_list(scratch.arena, &members); result = e_type_key_cons(.arch = arch_from_context(), @@ -1413,7 +1413,6 @@ e_type_member_copy(Arena *arena, E_Member *src) E_Member *dst = push_array(arena, E_Member, 1); MemoryCopyStruct(dst, src); dst->name = push_str8_copy(arena, src->name); - dst->pretty_name = push_str8_copy(arena, src->pretty_name); dst->inheritance_key_chain = e_type_key_list_copy(arena, &src->inheritance_key_chain); return dst; } diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 30cdfee3..8dae9878 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -59,6 +59,7 @@ typedef enum E_MemberKind E_MemberKind_VirtualBase, E_MemberKind_NestedType, E_MemberKind_Padding, + E_MemberKind_Query, E_MemberKind_COUNT } E_MemberKind; @@ -80,7 +81,6 @@ struct E_Member E_MemberKind kind; E_TypeKey type_key; String8 name; - String8 pretty_name; U64 off; E_TypeKeyList inheritance_key_chain; }; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 433a1468..e130a444 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -296,15 +296,15 @@ RD_VocabInfo rd_vocab_info_table[285] = RD_NameSchemaInfo rd_name_schema_info_table[10] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}")}, -{str8_lit_comp("machine"), str8_lit_comp("x:{'frozen':bool, 'label':code_string}")}, -{str8_lit_comp("process"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'processes':query}")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}")}, {str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, -{str8_lit_comp("thread"), str8_lit_comp("x:{'frozen':bool, 'label':code_string, 'id':u64}")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")}, }; Rng1U64 rd_reg_slot_range_table[38] = diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d4644d21..d8daf92e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -159,6 +159,7 @@ RD_VocabTable: 'stderr_path': path, 'stdin_path': path, 'debug_subprocesses': bool, + 'environment': query, } ```, } @@ -210,13 +211,13 @@ RD_VocabTable: //- rjf: machines { machine, - ```x:{'frozen':bool, 'label':code_string}```, + ```x:{'label':code_string, 'frozen':bool, 'processes':query}```, } //- rjf: processes { process, - ```x:{'frozen':bool, 'label':code_string, 'id':u64}```, + ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}```, } //- rjf: modules @@ -228,7 +229,7 @@ RD_VocabTable: //- rjf: threads { thread, - ```x:{'frozen':bool, 'label':code_string, 'id':u64}```, + ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}```, } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4678613c..6a0d3e00 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -560,204 +560,6 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) return num; } -//////////////////////////////// -//~ rjf: Machine Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(machine) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(machine) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("processes"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("machine_processes")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(machine) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - String8 extras[] = - { - str8_lit("processes"), - }; - Rng1U64 extras_idx_range = r1u64(lhs_type->count, lhs_type->count + ArrayCount(extras)); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, extras[extras_idx]); - } - scratch_end(scratch); -} - -//////////////////////////////// -//~ rjf: Process Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(process) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(process) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("modules"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("process_modules")); - result.irtree_and_type.mode = E_Mode_Offset; - } - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("threads"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("process_threads")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(process) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - String8 extras[] = - { - str8_lit("modules"), - //str8_lit("threads"), - }; - Rng1U64 extras_idx_range = r1u64(lhs_type->count, lhs_type->count + ArrayCount(extras)); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, extras[0]); - } - scratch_end(scratch); -} - -typedef struct RD_ProcessLookupAccel RD_ProcessLookupAccel; -struct RD_ProcessLookupAccel -{ - CTRL_EntityArray children; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(process_modules) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interpret = e_interpret(bytecode); - CTRL_Entity *process = rd_ctrl_entity_from_eval_space(interpret.space); - CTRL_EntityList modules = {0}; - for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Module) - { - ctrl_entity_list_push(scratch.arena, &modules, child); - } - } - RD_ProcessLookupAccel *accel = push_array(arena, RD_ProcessLookupAccel, 1); - accel->children = ctrl_entity_array_from_list(arena, &modules); - result.user_data = accel; - result.idxed_expr_count = modules.count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(process_modules) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - RD_ProcessLookupAccel *accel = (RD_ProcessLookupAccel *)user_data; - E_Value rhs_value = e_value_from_expr(rhs); - if(0 <= rhs_value.u64 && rhs_value.u64 < accel->children.count) - { - CTRL_Entity *entity = accel->children.v[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -//////////////////////////////// -//~ rjf: Thread Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(thread) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(thread) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("call_stack"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(thread) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("call_stack")); - } - scratch_end(scratch); -} - //////////////////////////////// //~ rjf: Call Stack Eval Hooks @@ -779,9 +581,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(call_stack) String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interp = e_interpret(bytecode); U128 u128 = interp.value.u128; - CTRL_Handle handle = {0}; - MemoryCopyStruct(&handle, &u128); - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); if(entity->kind == CTRL_EntityKind_Thread) { CTRL_Entity *process = ctrl_process_from_entity(entity); @@ -826,46 +626,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) //////////////////////////////// //~ rjf: Target / Environment Eval Hooks -E_LOOKUP_INFO_FUNCTION_DEF(target) -{ - E_LookupInfo result = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); - result.named_expr_count += 1; - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(target) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = E_LOOKUP_ACCESS_FUNCTION_NAME(default)(arena, kind, lhs, rhs, user_data); - if(kind == E_ExprKind_MemberAccess && rhs->kind == E_ExprKind_LeafMember && str8_match(rhs->string, str8_lit("environment"), 0)) - { - E_Eval eval = e_eval_from_expr(scratch.arena, lhs); - RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCfgCollection), e_irtree_const_u(arena, cfg->id)); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(target) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - Rng1U64 extras_idx_range = r1u64(lhs_type->count, max_U64); - Rng1U64 extras_read_range = intersect_1u64(extras_idx_range, idx_range); - U64 extras_count = dim_1u64(extras_read_range); - for(U64 extras_idx = 0; extras_idx < extras_count; extras_idx += 1) - { - U64 out_idx = extras_idx_range.min - idx_range.min + extras_idx; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, str8_lit("environment")); - } - scratch_end(scratch); -} - E_LOOKUP_INFO_FUNCTION_DEF(environment) { E_LookupInfo result = {0}; @@ -874,8 +634,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(environment) E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); - RD_CfgID id = interpret.value.u64; - RD_Cfg *target = rd_cfg_from_id(id); + RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); RD_CfgList env_strings = {0}; for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) { @@ -980,6 +739,17 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { + //- rjf: determine which entity we're looking under + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *scoping_entity = &ctrl_entity_nil; + if(lhs_interp.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + scoping_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + } + + //- rjf: determine which type of child we're gathering E_TypeKey lhs_type_key = lhs->type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 name = rd_singular_from_code_name_plural(lhs_type->name); @@ -992,7 +762,25 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) break; } } - CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + + //- rjf: gather list of all entities which fit the bill + CTRL_EntityList list = {0}; + if(scoping_entity == &ctrl_entity_nil) + { + list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + } + else + { + for(CTRL_Entity *child = scoping_entity->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == entity_kind) + { + ctrl_entity_list_push(scratch.arena, &list, child); + } + } + } + + //- rjf: filter the list CTRL_EntityList list__filtered = list; if(filter.size != 0) { @@ -1007,6 +795,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) } } } + + //- rjf: list -> array & fill CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); *array = ctrl_entity_array_from_list(arena, &list__filtered); result.user_data = array; @@ -3032,6 +2822,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon if(process_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = size*0.9f); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); } @@ -6999,7 +6790,7 @@ rd_window_frame(void) if(can_play || !have_targets || processes.count == 0) UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive))) + UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_play ? RD_ThemeColor_TextPositive : RD_ThemeColor_TextWeak))) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -7062,7 +6853,7 @@ rd_window_frame(void) //- rjf: pause button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral))) + UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_pause ? RD_ThemeColor_TextNeutral : RD_ThemeColor_TextWeak))) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -7088,7 +6879,7 @@ rd_window_frame(void) //- rjf: stop button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_stop ? RD_ThemeColor_TextNegative : RD_ThemeColor_TextWeak))) { UI_Signal sig = {0}; { @@ -12659,23 +12450,30 @@ rd_frame(void) U64 off = 0; for MD_EachNode(child, schema->first) { - String8 member_name = child->string; - String8 member_pretty_name = rd_display_from_code_name(member_name); - E_TypeKey member_type_key = zero_struct; - for EachElement(schema_type_name_idx, schema_type_name_key_map) + if(str8_match(child->first->string, str8_lit("query"), 0)) { - if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) - { - member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; - break; - } + e_member_list_push_new(scratch.arena, &members_list, + .type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child->string), + .name = child->string); + } + else + { + String8 member_name = child->string; + E_TypeKey member_type_key = zero_struct; + for EachElement(schema_type_name_idx, schema_type_name_key_map) + { + if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) + { + member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; + break; + } + } + e_member_list_push_new(scratch.arena, &members_list, + .type_key = member_type_key, + .name = member_name, + .off = off); + off += e_type_byte_size_from_key(member_type_key); } - e_member_list_push_new(scratch.arena, &members_list, - .type_key = member_type_key, - .name = member_name, - .pretty_name = member_pretty_name, - .off = off); - off += e_type_byte_size_from_key(member_type_key); } E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); evallable_meta_types[idx] = e_type_key_cons(.name = name, @@ -12695,37 +12493,18 @@ rd_frame(void) } //- rjf: add macros for evallable config trees - struct + String8 evallable_cfg_names[] = { - String8 name; - E_LookupInfoFunctionType *info; - E_LookupAccessFunctionType *access; - E_LookupRangeFunctionType *range; - E_LookupIDFromNumFunctionType *id_from_num; - E_LookupNumFromIDFunctionType *num_from_id; - } - evallable_cfg_table[] = - { - { str8_lit("breakpoint") }, - { str8_lit("watch_pin") }, - { str8_lit("target"), .info = E_LOOKUP_INFO_FUNCTION_NAME(target), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(target), .range = E_LOOKUP_RANGE_FUNCTION_NAME(target) }, - { str8_lit("file_path_map") }, - { str8_lit("auto_view_rule") }, + str8_lit("breakpoint"), + str8_lit("watch_pin"), + str8_lit("target"), + str8_lit("file_path_map"), + str8_lit("auto_view_rule"), }; - for EachElement(idx, evallable_cfg_table) + for EachElement(idx, evallable_cfg_names) { - String8 name = evallable_cfg_table[idx].name; + String8 name = evallable_cfg_names[idx]; E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - if(evallable_cfg_table[idx].info != 0) - { - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, - .info = evallable_cfg_table[idx].info, - .access = evallable_cfg_table[idx].access, - .range = evallable_cfg_table[idx].range, - .id_from_num = evallable_cfg_table[idx].id_from_num, - .num_from_id = evallable_cfg_table[idx].num_from_id); - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); - } RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { @@ -12750,38 +12529,19 @@ rd_frame(void) } //- rjf: add macros for evallable control entities - struct + String8 evallable_ctrl_names[] = { - String8 name; - E_LookupInfoFunctionType *info; - E_LookupAccessFunctionType *access; - E_LookupRangeFunctionType *range; - E_LookupIDFromNumFunctionType *id_from_num; - E_LookupNumFromIDFunctionType *num_from_id; - } - evallable_ctrl_table[] = - { - { str8_lit("machine"), .info = E_LOOKUP_INFO_FUNCTION_NAME(machine), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(machine), .range = E_LOOKUP_RANGE_FUNCTION_NAME(machine) }, - { str8_lit("process"), .info = E_LOOKUP_INFO_FUNCTION_NAME(process), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(process), .range = E_LOOKUP_RANGE_FUNCTION_NAME(process) }, - { str8_lit("thread"), .info = E_LOOKUP_INFO_FUNCTION_NAME(thread), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(thread), .range = E_LOOKUP_RANGE_FUNCTION_NAME(thread) }, - { str8_lit("module") }, + str8_lit("machine"), + str8_lit("process"), + str8_lit("thread"), + str8_lit("module"), }; - for EachElement(idx, evallable_ctrl_table) + for EachElement(idx, evallable_ctrl_names) { - String8 name = evallable_ctrl_table[idx].name; + String8 name = evallable_ctrl_names[idx]; CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - if(evallable_ctrl_table[idx].info != 0) - { - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, - .info = evallable_ctrl_table[idx].info, - .access = evallable_ctrl_table[idx].access, - .range = evallable_ctrl_table[idx].range, - .id_from_num = evallable_ctrl_table[idx].id_from_num, - .num_from_id = evallable_ctrl_table[idx].num_from_id); - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); - } for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) { CTRL_Entity *entity = n->v; @@ -12822,7 +12582,7 @@ rd_frame(void) String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), @@ -12842,9 +12602,6 @@ rd_frame(void) e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), .info = E_LOOKUP_INFO_FUNCTION_NAME(call_stack), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(call_stack)); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("process_modules"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(process_modules), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(process_modules)); } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) @@ -12896,14 +12653,14 @@ rd_frame(void) } //- rjf: add macros for all config collections - for EachElement(cfg_name_idx, evallable_cfg_table) + for EachElement(cfg_name_idx, evallable_cfg_names) { - String8 cfg_name = evallable_cfg_table[cfg_name_idx].name; + String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), @@ -12914,14 +12671,14 @@ rd_frame(void) } //- rjf: add macros for all ctrl entity collections - for EachElement(ctrl_name_idx, evallable_ctrl_table) + for EachElement(ctrl_name_idx, evallable_ctrl_names) { - String8 kind_name = evallable_ctrl_table[ctrl_name_idx].name; + String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; String8 collection_name = rd_plural_from_code_name(kind_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntityCollection); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), @@ -12934,7 +12691,7 @@ rd_frame(void) E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmdCollection); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 502fe28c..f35a941c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -83,11 +83,8 @@ enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, - RD_EvalSpaceKind_MetaCfgCollection, RD_EvalSpaceKind_MetaCmd, - RD_EvalSpaceKind_MetaCmdCollection, RD_EvalSpaceKind_MetaCtrlEntity, - RD_EvalSpaceKind_MetaCtrlEntityCollection, }; //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 92e3d6b5..b23712a0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -944,12 +944,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine call stack info - if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && block_type_kind == E_TypeKind_Set) + if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && str8_match(str8_lit("call_stack"), block_type->name, 0)) { - CTRL_Handle handle = {0}; - handle.machine_id = (CTRL_MachineID)block_eval.value.u128.u64[0]; - handle.dmn_handle.u64[0] = (U64)block_eval.value.u128.u64[1]; - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); if(entity->kind == CTRL_EntityKind_Thread) { info.callstack_thread = entity; @@ -967,15 +964,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine ctrl entity - if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntityCollection) + if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); } // rjf: determine cfg group name / parent - if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) + if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); + info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); String8 singular_name = rd_singular_from_code_name_plural(block_type->name); if(singular_name.size != 0) { @@ -1094,8 +1091,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: singular button for commands - else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection || - block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) && + else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmd || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfg) && info.eval.space.kind == RD_EvalSpaceKind_MetaCmd && row_cfg_eval_matches_group) { @@ -1118,11 +1115,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: for meta-cfg evaluation spaces, only do expr/value else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || - info.eval.space.kind == RD_EvalSpaceKind_MetaCmdCollection || - info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntityCollection) + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1249,7 +1243,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || - row_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { String8 fancy_name = rd_display_from_code_name(member_name); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1f46e14f..2add2b9f 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -939,6 +939,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle)); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) From 5ce74bd66bc2b2bf010b9f54a7687d88d49771b9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Feb 2025 15:02:58 -0800 Subject: [PATCH 121/755] readjust cfg lookup rule to apply to not just top-level queries but scoped queries too; eliminate old scheduler code --- src/raddbg/raddbg_core.c | 233 +++++++-------------------------------- 1 file changed, 39 insertions(+), 194 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6a0d3e00..d91f7de0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9,182 +9,6 @@ #include "generated/raddbg.meta.c" -//////////////////////////////// -//~ rjf: Scheduler Eval Hooks - -typedef struct RD_CtrlEntityExpandAccel RD_CtrlEntityExpandAccel; -struct RD_CtrlEntityExpandAccel -{ - CTRL_EntityArray entities; -}; - -#if 0 // TODO(rjf): @cfg -typedef struct RD_EntityExpandAccel RD_EntityExpandAccel; -struct RD_EntityExpandAccel -{ - RD_EntityArray entities; -}; - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *machine = rd_ctrl_entity_from_eval_space(eval.space); - if(machine->kind == CTRL_EntityKind_Machine) - { - CTRL_EntityList processes = {0}; - for(CTRL_Entity *child = machine->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Process) - { - ctrl_entity_list_push(scratch.arena, &processes, child); - } - } - CTRL_EntityArray *processes_array = push_array(arena, CTRL_EntityArray, 1); - *processes_array = ctrl_entity_array_from_list(arena, &processes); - info.user_data = processes_array; - info.row_count = processes.count; - info.rows_default_expanded = 1; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_machine) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *processes = (CTRL_EntityArray *)user_data; - if(processes != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *process = processes->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ProcessMetaEval));; - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_machine) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_machine) -{ - return id; -} - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandInfo info = {0}; - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space); - if(process->kind == CTRL_EntityKind_Process) - { - CTRL_EntityList threads = {0}; - for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Thread) - { - B32 is_in_filter = 1; - if(filter.size != 0) - { - is_in_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - } - else - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(child); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &unwind); - for(U64 idx = 0; idx < call_stack.concrete_frame_count && idx < 5; idx += 1) - { - CTRL_CallStackFrame *f = &call_stack.frames[idx]; - String8 name = {0}; - name.str = rdi_string_from_idx(f->rdi, f->procedure->name_string_idx, &name.size); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) - { - is_in_filter = 1; - break; - } - } - di_scope_close(di_scope); - } - } - if(is_in_filter) - { - ctrl_entity_list_push(scratch.arena, &threads, child); - } - } - } - CTRL_EntityArray *threads_array = push_array(arena, CTRL_EntityArray, 1); - *threads_array = ctrl_entity_array_from_list(arena, &threads); - info.user_data = threads_array; - info.row_count = threads.count; - } - scratch_end(scratch); - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(scheduler_process) -{ - EV_ExpandRangeInfo info = {0}; - { - CTRL_EntityArray *threads = (CTRL_EntityArray *)user_data; - if(threads != 0) - { - info.row_exprs_count = dim_1u64(idx_range); - info.row_strings = push_array(arena, String8, info.row_exprs_count); - info.row_view_rules = push_array(arena, String8, info.row_exprs_count); - info.row_exprs = push_array(arena, E_Expr *, info.row_exprs_count); - info.row_members = push_array(arena, E_Member *, info.row_exprs_count); - U64 row_expr_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, row_expr_idx += 1) - { - CTRL_Entity *thread = threads->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCtrlEntity); - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_base(type(CTRL_ThreadMetaEval)); - info.row_exprs[row_expr_idx] = expr; - info.row_members[row_expr_idx] = &e_member_nil; - } - } - } - return info; -} - -EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(scheduler_process) -{ - return num; -} - -EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(scheduler_process) -{ - return id; -} -#endif - //////////////////////////////// //~ rjf: Commands Eval Hooks @@ -419,8 +243,8 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) //////////////////////////////// //~ rjf: Top-Level Config Eval Hooks -typedef struct RD_TopLevelCfgLookupAccel RD_TopLevelCfgLookupAccel; -struct RD_TopLevelCfgLookupAccel +typedef struct RD_CfgLookupAccel RD_CfgLookupAccel; +struct RD_CfgLookupAccel { String8Array cmds; RD_CfgArray cfgs; @@ -428,15 +252,34 @@ struct RD_TopLevelCfgLookupAccel Rng1U64 cfgs_idx_range; }; -E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_INFO_FUNCTION_DEF(cfg) { E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { + //- rjf: determine which cfg we'll use to scope the lookups + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + RD_Cfg *scoping_cfg = rd_cfg_from_eval_space(lhs_interp.space); + + //- rjf: determine which kind of child we'll be gathering E_TypeKey lhs_type_key = lhs->type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name);\ + + //- rjf: gather cfgs + RD_CfgList cfgs_list = {0}; + if(scoping_cfg == &rd_nil_cfg) + { + cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); + } + else + { + cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); + } + + //- rjf: gather commands String8List cmds_list = {0}; MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); @@ -444,7 +287,9 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) { str8_list_push(arena, &cmds_list, cmd->string); } - RD_TopLevelCfgLookupAccel *accel = push_array(arena, RD_TopLevelCfgLookupAccel, 1); + + //- rjf: package & fill + RD_CfgLookupAccel *accel = push_array(arena, RD_CfgLookupAccel, 1); accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); accel->cmds = str8_array_from_list(arena, &cmds_list); accel->cmds_idx_range = r1u64(0, accel->cmds.count); @@ -456,13 +301,13 @@ E_LOOKUP_INFO_FUNCTION_DEF(top_level_cfg) return result; } -E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_ACCESS_FUNCTION_DEF(cfg) { E_LookupAccess result = {{&e_irnode_nil}}; if(kind == E_ExprKind_ArrayIndex) { Temp scratch = scratch_begin(&arena, 1); - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); @@ -483,9 +328,9 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(top_level_cfg) return result; } -E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_RANGE_FUNCTION_DEF(cfg) { - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; Rng1U64 cmds_idx_range = accel->cmds_idx_range; Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; U64 dst_idx = 0; @@ -516,10 +361,10 @@ E_LOOKUP_RANGE_FUNCTION_DEF(top_level_cfg) } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfg) { U64 id = 0; - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; if(num != 0) { U64 idx = num-1; @@ -537,10 +382,10 @@ E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(top_level_cfg) return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(top_level_cfg) +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfg) { U64 num = 0; - RD_TopLevelCfgLookupAccel *accel = (RD_TopLevelCfgLookupAccel *)user_data; + RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; if(id != 0) { if(id & (1ull<<63)) @@ -12663,11 +12508,11 @@ rd_frame(void) expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(top_level_cfg), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(top_level_cfg), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(top_level_cfg), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(top_level_cfg)); + .info = E_LOOKUP_INFO_FUNCTION_NAME(cfg), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(cfg), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(cfg), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(cfg), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(cfg)); } //- rjf: add macros for all ctrl entity collections From 176c2590a0c1329b486560b992bdab64e3c63c72 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Feb 2025 15:10:04 -0800 Subject: [PATCH 122/755] ghosted 'view rule' hint --- src/raddbg/raddbg_views.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b23712a0..53fad55d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2919,7 +2919,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } // rjf: build cell line edit - else RD_Font(cell_info.flags & RD_WatchCellFlag_IsNonCode ? RD_FontSlot_Main : RD_FontSlot_Code) + else { RD_LineEditParams line_edit_params = {0}; { @@ -2942,7 +2942,19 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.fstrs = cell_info.fstrs; } UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", str8_zero(), cell_x, row_hash); + { + B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); + String8 ghost_text = {0}; + if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) + { + ghost_text = str8_lit("View Rules"); + is_non_code = !ui_is_focus_active(); + } + RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + } + } #if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && From c603457460d931d800319e01a3713a89702484e8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Feb 2025 18:11:22 -0800 Subject: [PATCH 123/755] dead code deletion, begin extending eval/eval-viz to work on expr-chains rather than single expressions; fixes / convergence for watch window --- src/eval/eval_bundles.c | 14 +- src/eval/eval_bundles.h | 3 +- src/eval/eval_ir.c | 37 ++-- src/eval/eval_ir.h | 2 +- src/eval/eval_parse.c | 60 +++---- src/eval/eval_parse.h | 12 +- .../eval_visualization_core.c | 4 +- .../dwrite/font_provider_dwrite.c | 7 +- src/raddbg/raddbg.mdesk | 8 +- src/raddbg/raddbg_core.c | 167 ++++-------------- src/raddbg/raddbg_core.h | 8 - src/raddbg/raddbg_views.c | 62 ++++--- 12 files changed, 152 insertions(+), 232 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index b1753efa..0ee41d92 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -6,9 +6,17 @@ internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) +{ + E_ExprChain exprs = {expr, expr}; + E_Eval result = e_eval_from_exprs(arena, exprs); + return result; +} + +internal E_Eval +e_eval_from_exprs(Arena *arena, E_ExprChain exprs) { ProfBeginFunction(); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); E_Interpretation interp = e_interpret(bytecode); @@ -17,7 +25,7 @@ e_eval_from_expr(Arena *arena, E_Expr *expr) .value = interp.value, .mode = irtree.mode, .space = interp.space, - .expr = expr, + .exprs = exprs, .type_key = irtree.type_key, .code = interp.code, }; @@ -35,7 +43,7 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); - E_Eval eval = e_eval_from_expr(arena, parse.last_expr); + E_Eval eval = e_eval_from_exprs(arena, parse.exprs); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index c83b33f5..c72fa6ee 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -13,7 +13,7 @@ struct E_Eval E_Value value; E_Mode mode; E_Space space; - E_Expr *expr; + E_ExprChain exprs; E_TypeKey type_key; E_InterpretationCode code; E_MsgList msgs; @@ -23,6 +23,7 @@ struct E_Eval //~ rjf: Bundled Evaluation Functions internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); +internal E_Eval e_eval_from_exprs(Arena *arena, E_ExprChain exprs); internal E_Eval e_eval_from_string(Arena *arena, String8 string); internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e38c4423..0d975fec 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -166,11 +166,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) } else if(lhs_type_kind == E_TypeKind_Struct || lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Enum) + lhs_type_kind == E_TypeKind_Union) { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - lookup_info.named_expr_count = lhs_type->count; + E_MemberArray data_members = e_type_data_members_from_key__cached(lhs_type_key); + lookup_info.named_expr_count = data_members.count; + } + else if(lhs_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(lhs_type_key); + lookup_info.named_expr_count = direct_type->count; } else if(lhs_type_kind == E_TypeKind_Array) { @@ -570,12 +574,10 @@ E_IRGEN_FUNCTION_DEF(array) E_TypeKind type_kind = e_type_kind_from_key(type_key); if(e_type_kind_is_pointer_or_ref(type_kind)) { - Temp scratch = scratch_begin(&arena, 1); - E_Eval count_eval = e_eval_from_expr(scratch.arena, tag->first->next); + E_Value count_value = e_value_from_expr(tag->first->next); E_TypeKey element_type_key = e_type_ptee_from_key(type_key); - E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_eval.value.u64, 0); + E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); irtree.type_key = ptr_type_key; - scratch_end(scratch); } return irtree; } @@ -617,9 +619,8 @@ E_IRGEN_FUNCTION_DEF(slice) if(count_member != 0) { E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, &irtree, count_member->name); - E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr); - E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval); - count = count_member_value_eval.value.u64; + E_Value count_member_value = e_value_from_expr(count_member_expr); + count = count_member_value.u64; } // rjf: generate new struct slice type @@ -760,14 +761,14 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.last_expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); 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, params->type_pattern, &pattern_split, 1, 0); - node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)); + node->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; if(!e_type_key_match(e_type_key_zero(), type_key)) { U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); @@ -800,7 +801,10 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { if(e_type_key_match(n->type_key, type_key)) { - e_expr_list_push(arena, &exprs, n->tag_expr); + for(E_Expr *e = n->tag_exprs.first; e != &e_expr_nil; e = e->next) + { + e_expr_list_push(arena, &exprs, e); + } } } } @@ -829,7 +833,10 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } if(fits_this_type_string) { - e_expr_list_push(arena, &exprs, auto_hook_node->tag_expr); + for(E_Expr *e = auto_hook_node->tag_exprs.first; e != &e_expr_nil; e = e->next) + { + e_expr_list_push(arena, &exprs, e); + } } } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 2e1d451f..2fcc65a9 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -189,7 +189,7 @@ struct E_AutoHookNode E_AutoHookNode *pattern_order_next; E_TypeKey type_key; String8List type_pattern_parts; - E_Expr *tag_expr; + E_ExprChain tag_exprs; }; typedef struct E_AutoHookSlot E_AutoHookSlot; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index a61717b5..56e78ee7 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -660,7 +660,7 @@ internal E_Expr * e_push_expr(Arena *arena, E_ExprKind kind, void *location) { E_Expr *e = push_array(arena, E_Expr, 1); - e->first = e->last = e->next = e->ref = e->first_tag = e->last_tag = &e_expr_nil; + e->first = e->last = e->next = e->prev = e->ref = e->first_tag = e->last_tag = &e_expr_nil; e->location = location; e->kind = kind; return e; @@ -1110,14 +1110,14 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } // rjf: construct leaf type - parse.first_expr = parse.last_expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - parse.first_expr->type_key = type_key; + parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.exprs.first->type_key = type_key; } } } //- rjf: parse extensions - if(parse.first_expr != &e_expr_nil) + if(parse.exprs.first != &e_expr_nil) { for(;;) { @@ -1130,9 +1130,9 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) if(str8_match(token_string, str8_lit("*"), 0)) { token_it += 1; - E_Expr *ptee = parse.first_expr; - parse.first_expr = parse.last_expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); - e_expr_push_child(parse.first_expr, ptee); + E_Expr *ptee = parse.exprs.first; + parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(parse.exprs.first, ptee); } else { @@ -1246,7 +1246,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: parse type expr E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.last_expr; + E_Expr *type = type_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; @@ -1329,7 +1329,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.last_expr; + atom = nested_parse.exprs.last; it = nested_parse.last_token; // rjf: expect ) @@ -1357,11 +1357,11 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.last_expr; + atom = nested_parse.exprs.last; it = nested_parse.last_token; // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.last_expr == &e_expr_nil) + if(nested_parse.exprs.last == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); } @@ -1737,7 +1737,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to { E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.last_expr; + E_Expr *type = type_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; atom = type; @@ -2015,10 +2015,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it = idx_expr_parse.last_token; // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.last_expr != &e_expr_nil) + if(idx_expr_parse.exprs.last != &e_expr_nil) { E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.last_expr; + E_Expr *index_expr = idx_expr_parse.exprs.last; atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); e_expr_push_child(atom, array_expr); e_expr_push_child(atom, index_expr); @@ -2055,11 +2055,11 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; - if(args_parse.first_expr != &e_expr_nil) + if(args_parse.exprs.first != &e_expr_nil) { - call_expr->last->next = args_parse.first_expr; - args_parse.first_expr->prev = call_expr->last; - call_expr->last = args_parse.last_expr; + call_expr->last->next = args_parse.exprs.first; + args_parse.exprs.first->prev = call_expr->last; + call_expr->last = args_parse.exprs.last; } atom = call_expr; @@ -2153,7 +2153,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.last_expr; + E_Expr *rhs = rhs_expr_parse.exprs.last; it = rhs_expr_parse.last_token; if(rhs == &e_expr_nil) { @@ -2179,9 +2179,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence, 1); it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.last_expr; + E_Expr *middle_expr = middle_expr_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.last_expr == &e_expr_nil) + if(middle_expr_parse.exprs.last == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); } @@ -2213,7 +2213,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to { it = rhs_expr_parse.last_token; e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.last_expr == &e_expr_nil) + if(rhs_expr_parse.exprs.last == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); } @@ -2221,12 +2221,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: build ternary if(atom != &e_expr_nil && - middle_expr_parse.last_expr != &e_expr_nil && - rhs_expr_parse.last_expr != &e_expr_nil) + middle_expr_parse.exprs.last != &e_expr_nil && + rhs_expr_parse.exprs.last != &e_expr_nil) { E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.last_expr; - E_Expr *rhs = rhs_expr_parse.last_expr; + E_Expr *mhs = middle_expr_parse.exprs.last; + E_Expr *rhs = rhs_expr_parse.exprs.last; atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); e_expr_push_child(atom, lhs); e_expr_push_child(atom, mhs); @@ -2244,7 +2244,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, &tags_tokens, e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); it = tags_parse.last_token; - for(E_Expr *tag = tags_parse.first_expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + for(E_Expr *tag = tags_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { next = tag->next; e_expr_push_tag(atom, tag); @@ -2262,7 +2262,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: store parsed atom to expression chain - if we didn't get an expression, break if(atom != &e_expr_nil) { - DLLPushBack_NPZ(&e_expr_nil, result.first_expr, result.last_expr, atom, next, prev); + DLLPushBack_NPZ(&e_expr_nil, result.exprs.first, result.exprs.last, atom, next, prev); chain_count += 1; } else @@ -2287,14 +2287,14 @@ e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) return parse; } -internal E_Expr * +internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text) { Temp scratch = scratch_begin(&arena, 1); E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); E_Parse parse = e_parse_expr_from_text_tokens(arena, text, &tokens); scratch_end(scratch); - return parse.last_expr; + return parse; } internal E_Parse diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 4ba88b90..37343f2e 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -68,6 +68,13 @@ struct E_Expr String8 bytecode; }; +typedef struct E_ExprChain E_ExprChain; +struct E_ExprChain +{ + E_Expr *first; + E_Expr *last; +}; + typedef struct E_ExprNode E_ExprNode; struct E_ExprNode { @@ -153,8 +160,7 @@ typedef struct E_Parse E_Parse; struct E_Parse { E_Token *last_token; - E_Expr *first_expr; - E_Expr *last_expr; + E_ExprChain exprs; E_MsgList msgs; }; @@ -289,7 +295,7 @@ internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Expr *e_parse_expr_from_text(Arena *arena, String8 text); +internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); internal E_Parse e_parse_expr_from_text__cached(String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index dc346cdb..2cce058e 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -485,7 +485,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.first_expr, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { next = tag->next; e_expr_push_tag(expr, tag); @@ -508,7 +508,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval //- rjf: generate root expression EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); - E_Expr *root_expr = e_expr_copy(arena, eval.expr); + E_Expr *root_expr = e_expr_copy(arena, eval.exprs.last); ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 4bfbddb2..1868c85f 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -432,7 +432,7 @@ fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, S F32 right_side_bearing = 0; if(font.face != 0) { - atlas_dim.y = (S16)ceil_f32((96.f/72.f) * size * (font_metrics.ascent + font_metrics.descent) / design_units_per_em) + 1; + atlas_dim.y = (S16)round_f32((96.f/72.f) * size * (font_metrics.ascent + font_metrics.descent + font_metrics.lineGap) / design_units_per_em) + 1; for(U64 idx = 0; idx < glyphs_count; idx += 1) { DWRITE_GLYPH_METRICS *glyph_metrics = glyphs_metrics + idx; @@ -476,11 +476,14 @@ fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, S } //- rjf: draw glyph run - Vec2F32 draw_p = {0, (F32)atlas_dim.y}; + Vec2F32 draw_p = {0, (F32)atlas_dim.y - 1}; if(font.face != 0) { F32 descent = round_f32((96.f/72.f)*size * font_metrics.descent / design_units_per_em); + F32 line_gap = round_f32((96.f/72.f)*size * font_metrics.lineGap / design_units_per_em); draw_p.y -= descent; + draw_p.y -= line_gap; + draw_p.y += 1; } DWRITE_GLYPH_RUN glyph_run = {0}; if(font.face != 0) diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d8daf92e..8d1c8289 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -208,25 +208,19 @@ RD_VocabTable: ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}```, } - //- rjf: machines + //- rjf: control entities { machine, ```x:{'label':code_string, 'frozen':bool, 'processes':query}```, } - - //- rjf: processes { process, ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}```, } - - //- rjf: modules { module, ```x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}```, } - - //- rjf: threads { thread, ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}```, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d91f7de0..fe8264d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -102,7 +102,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(watches) if(cfg_idx < cfgs->count) { String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; exprs_strings[idx] = push_str8_copy(arena, expr_string); } } @@ -184,7 +184,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(locals) for(U64 idx = 0; idx < read_range_count; idx += 1) { String8 expr_string = accel->v[read_range.min + idx]; - exprs[idx] = e_parse_expr_from_text(arena, expr_string); + exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; exprs_strings[idx] = push_str8_copy(arena, expr_string); } } @@ -236,7 +236,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) String8 register_name = accel->v[read_range.min + idx]; String8 register_expr = push_str8f(arena, "reg:%S", register_name); exprs_strings[idx] = register_name; - exprs[idx] = e_parse_expr_from_text(arena, register_expr); + exprs[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; } } @@ -340,7 +340,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfg) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")); + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { @@ -425,7 +425,6 @@ E_LOOKUP_INFO_FUNCTION_DEF(call_stack) E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interp = e_interpret(bytecode); - U128 u128 = interp.value.u128; CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); if(entity->kind == CTRL_EntityKind_Thread) { @@ -3371,7 +3370,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un if((E_TypeKind_FirstBasic <= type_kind && type_kind <= E_TypeKind_LastBasic) || type_kind == E_TypeKind_Enum) { - E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string); + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); @@ -3462,113 +3461,6 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un return result; } -//- rjf: view rule config tree info extraction - -internal E_Value -rd_value_from_params_key(MD_Node *params, String8 key) -{ - Temp scratch = scratch_begin(0, 0); - MD_Node *key_node = md_child_from_string(params, key, 0); - String8 expr = md_string_from_children(scratch.arena, key_node); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - scratch_end(scratch); - return value_eval.value; -} - -internal Rng1U64 -rd_range_from_eval_params(E_Eval eval, MD_Node *params) -{ - Temp scratch = scratch_begin(0, 0); - U64 size = rd_value_from_params_key(params, str8_lit("size")).u64; - E_TypeKey type_key = e_type_unwrap(eval.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); - } - if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); - } - if(size == 0) - { - size = KB(16); - } - Rng1U64 result = {0}; - result.min = rd_base_offset_from_eval(eval); - result.max = result.min + size; - scratch_end(scratch); - return result; -} - -internal TXT_LangKind -rd_lang_kind_from_eval_params(E_Eval eval, MD_Node *params) -{ - TXT_LangKind lang_kind = TXT_LangKind_Null; - if(eval.expr->kind == E_ExprKind_LeafFilePath) - { - lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.expr->string)); - } - else - { - MD_Node *lang_node = md_child_from_string(params, str8_lit("lang"), 0); - String8 lang_kind_string = lang_node->first->string; - lang_kind = txt_lang_kind_from_extension(lang_kind_string); - } - return lang_kind; -} - -internal Arch -rd_arch_from_eval_params(E_Eval eval, MD_Node *params) -{ - Arch arch = Arch_Null; - MD_Node *arch_node = md_child_from_string(params, str8_lit("arch"), 0); - String8 arch_kind_string = arch_node->first->string; - if(str8_match(arch_kind_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive)) - { - arch = Arch_x64; - } - return arch; -} - -internal Vec2S32 -rd_dim2s32_from_eval_params(E_Eval eval, MD_Node *params) -{ - Vec2S32 dim = v2s32(1, 1); - { - dim.x = rd_value_from_params_key(params, str8_lit("w")).s32; - dim.y = rd_value_from_params_key(params, str8_lit("h")).s32; - } - return dim; -} - -internal R_Tex2DFormat -rd_tex2dformat_from_eval_params(E_Eval eval, MD_Node *params) -{ - R_Tex2DFormat result = R_Tex2DFormat_RGBA8; - { - MD_Node *fmt_node = md_child_from_string(params, str8_lit("fmt"), 0); - for EachNonZeroEnumVal(R_Tex2DFormat, fmt) - { - if(str8_match(r_tex2d_format_display_string_table[fmt], fmt_node->first->string, StringMatchFlag_CaseInsensitive)) - { - result = fmt; - break; - } - } - } - return result; -} - //- rjf: eval <-> file path internal String8 @@ -3577,7 +3469,7 @@ rd_file_path_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; if(expr->kind == E_ExprKind_LeafFilePath) { result = raw_from_escaped_str8(arena, expr->string); @@ -3605,7 +3497,7 @@ rd_query_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; if(expr->kind == E_ExprKind_LeafIdent && str8_match(expr->qualifier, str8_lit("query"), 0)) { @@ -3791,7 +3683,7 @@ rd_view_ui(Rng2F32 rect) { ui_labelf("use"); UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); - ui_labelf("to open the lister for commands and options"); + ui_labelf("to search for commands and options"); } } scratch_end(scratch); @@ -4041,9 +3933,9 @@ internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) { TXT_LangKind lang_kind = TXT_LangKind_Null; - if(eval.expr->kind == E_ExprKind_LeafFilePath) + if(eval.exprs.last->kind == E_ExprKind_LeafFilePath) { - lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.expr->string)); + lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.exprs.last->string)); } else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) { @@ -9100,9 +8992,9 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } //- rjf: force no_string, if we are looking at padding members - if(eval.expr->kind == E_ExprKind_MemberAccess) + if(eval.exprs.last->kind == E_ExprKind_MemberAccess) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr->first); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last->first); E_TypeKey struct_type = irtree.type_key; for(B32 done = 0; !done;) { @@ -9118,8 +9010,12 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { struct_type = e_type_direct_from_key(struct_type); } + else + { + break; + } } - E_Member member = e_type_member_from_key_name__cached(struct_type, eval.expr->last->string); + E_Member member = e_type_member_from_key_name__cached(struct_type, eval.exprs.last->last->string); if(member.kind == E_MemberKind_Padding) { no_string = 1; @@ -9288,7 +9184,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { if(type->count == 1) { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); + E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.exprs.last); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); } @@ -9305,8 +9201,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul // rjf: contents { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.expr, &irtree); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); @@ -9316,7 +9212,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.expr, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) @@ -9444,8 +9340,8 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul // rjf: build contents if(depth < 4) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.expr, &irtree); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); @@ -9455,7 +9351,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.expr, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) @@ -9502,7 +9398,7 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval.expr, eval, &strs); + rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval.exprs.last, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; @@ -12418,7 +12314,7 @@ rd_frame(void) //- rjf: add macro for 'call_stack' -> 'current_thread.callstack' { - E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("current_thread.call_stack")); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("current_thread.call_stack")).exprs.first; e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } @@ -12568,7 +12464,7 @@ rd_frame(void) E_Parse parse = e_parse_expr_from_text__cached(expr); if(parse.msgs.max_kind == E_MsgKind_Null) { - for(E_Expr *expr = parse.first_expr; expr != &e_expr_nil; expr = expr->next) + for(E_Expr *expr = parse.exprs.first; expr != &e_expr_nil; expr = expr->next) { e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); } @@ -14561,6 +14457,7 @@ Z(getting_started) // rjf: choose panel for source code RD_PanelNode *src_code_dst_panel = &rd_nil_panel_node; + if(file_path.size != 0) { if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_this_src_code; } if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_any_src_code; } @@ -14570,6 +14467,7 @@ Z(getting_started) // rjf: choose panel for disassembly RD_PanelNode *disasm_dst_panel = &rd_nil_panel_node; + if(vaddr != 0) { if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = panel_w_disasm; } if(disasm_dst_panel == &rd_nil_panel_node) { disasm_dst_panel = biggest_empty_panel; } @@ -14594,7 +14492,7 @@ Z(getting_started) // rjf: if disasm is not preferred, and we have no disassembly view // open at all, cancel disasm, so that it doesn't open if the user // doesn't want it. - if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel_node) + if(!rd_regs()->prefer_disasm && panel_w_disasm == &rd_nil_panel_node && file_path.size != 0) { disasm_dst_panel = &rd_nil_panel_node; } @@ -14602,7 +14500,8 @@ Z(getting_started) // rjf: if disasm is not preferred, and we have no disassembly view // *selected* at all, cancel disasm, so that it doesn't open if the user // doesn't want it. - if(!rd_regs()->prefer_disasm && view_w_disasm != &rd_nil_cfg && rd_cfg_child_from_string(view_w_disasm, str8_lit("selected")) == &rd_nil_cfg) + if(!rd_regs()->prefer_disasm && view_w_disasm != &rd_nil_cfg && rd_cfg_child_from_string(view_w_disasm, str8_lit("selected")) == &rd_nil_cfg && + file_path.size != 0) { disasm_dst_panel = &rd_nil_panel_node; } @@ -15773,7 +15672,7 @@ Z(getting_started) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).exprs.last; ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index f35a941c..ffe25121 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1036,14 +1036,6 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); //- rjf: writing values back to child processes internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); -//- rjf: eval / view rule params tree info extraction -internal E_Value rd_value_from_params_key(MD_Node *params, String8 key); -internal Rng1U64 rd_range_from_eval_params(E_Eval eval, MD_Node *params); -internal TXT_LangKind rd_lang_kind_from_eval_params(E_Eval eval, MD_Node *params); -internal Arch rd_arch_from_eval_params(E_Eval eval, MD_Node *params); -internal Vec2S32 rd_dim2s32_from_eval_params(E_Eval eval, MD_Node *params); -internal R_Tex2DFormat rd_tex2dformat_from_eval_params(E_Eval eval, MD_Node *params); - //- rjf: eval <-> file path internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 53fad55d..3cb30460 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1108,7 +1108,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr - else if(info.eval.space.kind == E_SpaceKind_Null && info.group_cfg_parent != &rd_nil_cfg) + else if(info.eval.exprs.last == &e_expr_nil && info.group_cfg_name.size != 0) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } @@ -1269,7 +1269,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla E_Expr *root_expr = row->expr; if(wrap_string.size != 0) { - E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string); + E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).exprs.last; root_expr = wrap_expr; typedef struct Task Task; struct Task @@ -1308,8 +1308,23 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: evaluate wrapped expression result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); - result.string = rd_value_string_from_eval(arena, string_flags, 10, font, font_size, max_size_px, result.eval); + + //- rjf: determine default radix + U32 default_radix = 10; + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + { + default_radix = 16; + } + + //- rjf: generate strings/flags based on that expression & fill + result.string = rd_value_string_from_eval(arena, string_flags, default_radix, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; + E_Type *type = e_type_from_key__cached(result.eval.type_key); + if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) + { + result.flags |= RD_WatchCellFlag_IsNonCode; + } scratch_end(scratch); }break; @@ -2061,22 +2076,22 @@ RD_VIEW_UI_FUNCTION_DEF(watch) if(cfg != &rd_nil_cfg) { rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); - U64 deleted_num = ev_num_from_key(&block_ranges, row->key); + U64 deleted_num = row->block->lookup_rule->num_from_id(row->key.child_id, row->block->lookup_rule_user_data); if(deleted_num != 0) { EV_Key parent_key = row->block->parent->key; EV_Key key = row->block->key; - EV_Key fallback_key_prev = ev_key_from_num(&block_ranges, deleted_num-1); - EV_Key fallback_key_next = ev_key_from_num(&block_ranges, deleted_num+1); - if(fallback_key_next.child_id != 0) + U64 fallback_id_prev = row->block->lookup_rule->id_from_num(deleted_num-1, row->block->lookup_rule_user_data); + U64 fallback_id_next = row->block->lookup_rule->id_from_num(deleted_num+1, row->block->lookup_rule_user_data); + if(fallback_id_next != 0) { parent_key = row->block->key; - key = fallback_key_next; + key = ev_key_make(row->key.parent_hash, fallback_id_next); } - else if(fallback_key_prev.child_id != 0) + else if(fallback_id_prev != 0) { parent_key = row->block->key; - key = fallback_key_prev; + key = ev_key_make(row->key.parent_hash, fallback_id_prev); } RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; next_cursor_pt = new_pt; @@ -2694,16 +2709,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { row_flags |= UI_BoxFlag_DrawSideTop; } -#if 0 // TODO(rjf): @cfg - switch(row_kind) - { - default:{}break; - case RD_WatchViewRowKind_Normal:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Header:{row_flags |= UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DisableFocusOverlay;}break; - case RD_WatchViewRowKind_Canvas:{row_flags |= UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder;}break; - case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; - } -#endif } ProfEnd(); @@ -2871,7 +2876,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.expr)); + rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); rd_cfg_new(view, str8_lit("selected")); RD_RegsScope(.view = view->id) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) @@ -2945,10 +2950,15 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; - if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) + if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) + { + ghost_text = str8_lit("Expression"); + is_non_code = !cell_selected || !ewv->text_editing; + } + else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) { ghost_text = str8_lit("View Rules"); - is_non_code = !ui_is_focus_active(); + is_non_code = !cell_selected || !ewv->text_editing; } RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { @@ -3111,7 +3121,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) String8 string = ev_expr_string_from_row(scratch.arena, row, 0); E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.last_expr); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); @@ -3133,7 +3143,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) E_Expr *expr; S64 depth; }; - Task start_task = {0, 0, parse.last_expr}; + Task start_task = {0, 0, parse.exprs.last}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -3562,7 +3572,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) // B32 auto_selected = 0; E_Space auto_space = {0}; - if(eval.expr == &e_expr_nil) + if(eval.exprs.last == &e_expr_nil) { if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { From 7d84ec79c56e2c6417e12ef067f5afbe8f361ff4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 16 Feb 2025 14:13:48 -0800 Subject: [PATCH 124/755] formalize file/folder evaluations; use set-types for files/folders so that we can evaluate both file metadata & contents, rather than just assuming the contents; adjust `slice` view rule to just expand to the contents, rather than achieving the slice with a changed type --- src/eval/eval.mdesk | 1 - src/eval/eval_core.h | 1 + src/eval/eval_ir.c | 387 ++++++++++++++---- src/eval/eval_ir.h | 36 ++ src/eval/eval_types.c | 10 - src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- .../eval_visualization_core.c | 4 +- .../eval_visualization_core.h | 2 +- src/file_stream/file_stream.c | 43 +- src/file_stream/file_stream.h | 6 +- src/font_cache/font_cache.c | 4 +- src/raddbg/raddbg_core.c | 6 +- src/raddbg/raddbg_views.c | 6 +- 14 files changed, 371 insertions(+), 146 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index ffb12495..fd5be091 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,7 +71,6 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } - {SpacePtr "space_ptr" 0 } {Set "set" 0 } } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index c27e2e57..01eb7685 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -94,6 +94,7 @@ enum { E_SpaceKind_Null, E_SpaceKind_HashStoreKey, + E_SpaceKind_FileSystem, E_SpaceKind_FirstUserDefined, }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0d975fec..5d4895fd 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -84,6 +84,233 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); e_ir_state->irtree_and_type_cache_slots_count = 1024; e_ir_state->irtree_and_type_cache_slots = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheSlot, e_ir_state->irtree_and_type_cache_slots_count); + e_ir_state->string_id_gen = 0; + e_ir_state->string_id_map = push_array(e_ir_state->arena, E_StringIDMap, 1); + e_ir_state->string_id_map->id_slots_count = 1024; + e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); + e_ir_state->string_id_map->hash_slots_count = 1024; + e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); +} + +//////////////////////////////// +//~ rjf: File System Lookup Rules + +typedef struct E_FolderAccel E_FolderAccel; +struct E_FolderAccel +{ + String8 folder_path; + String8Array folders; + String8Array files; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(folder) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + + //- rjf: gather files in this folder + String8 folder_path = e_string_from_id(lhs_string_id); + String8List folder_paths = {0}; + String8List file_paths = {0}; + { + OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);) + { + if(info.props.flags & FilePropertyFlag_IsFolder) + { + str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); + } + else + { + str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); + } + } + os_file_iter_end(iter); + } + + //- rjf: build filtered paths + String8List folder_paths__filtered = {0}; + String8List file_paths__filtered = {0}; + { + // TODO(rjf) + folder_paths__filtered = folder_paths; + file_paths__filtered = file_paths; + } + + //- rjf: build accelerator + E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1); + accel->folder_path = push_str8_copy(arena, folder_path); + accel->folders = str8_array_from_list(arena, &folder_paths__filtered); + accel->files = str8_array_from_list(arena, &file_paths__filtered); + info.user_data = accel; + info.idxed_expr_count = accel->folders.count + accel->files.count; + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(folder) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + E_FolderAccel *accel = (E_FolderAccel *)user_data; + U64 idx = e_value_from_expr(rhs).u64; + if(0 <= idx && idx < accel->folders.count) + { + String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, accel->folders.v[idx - 0]); + U64 string_id = e_id_from_string(folder_path); + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, string_id)); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) + { + String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, accel->files.v[idx - accel->folders.count]); + U64 string_id = e_id_from_string(file_path); + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, string_id)); + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_INFO_FUNCTION_DEF(file) +{ + E_LookupInfo info = {0}; + return info; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(file) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + return result; +} + +//////////////////////////////// +//~ rjf: Slice Lookup Rules + +typedef struct E_SliceAccel E_SliceAccel; +struct E_SliceAccel +{ + U64 count; + U64 base_ptr_vaddr; + E_TypeKey element_type_key; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(slice) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + E_TypeKind type_kind = e_type_kind_from_key(lhs->type_key); + if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) + { + // rjf: unpack members + E_MemberArray members = e_type_data_members_from_key__cached(lhs->type_key); + + // rjf: choose base pointer & count members + E_Member *base_ptr_member = 0; + E_Member *count_member = 0; + for(U64 idx = 0; idx < members.count; idx += 1) + { + E_Member *member = &members.v[idx]; + E_TypeKey member_type = e_type_unwrap(member->type_key); + E_TypeKind member_type_kind = e_type_kind_from_key(member_type); + if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) + { + count_member = member; + } + if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + base_ptr_member = &members.v[idx]; + } + if(count_member != 0 && base_ptr_member != 0) + { + break; + } + } + + // rjf: evaluate count member, determine count + U64 count = 0; + if(count_member != 0) + { + E_Expr *count_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, count_member->name); + E_Value count_member_value = e_value_from_expr(count_member_expr); + count = count_member_value.u64; + } + + // rjf: evaluate base ptr member, determine base address + U64 base_ptr_vaddr = 0; + if(base_ptr_member != 0) + { + E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, base_ptr_member->name); + E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr); + base_ptr_vaddr = base_ptr_member_value.u64; + } + + // rjf: determine element type + E_TypeKey element_type_key = zero_struct; + if(base_ptr_member != 0) + { + element_type_key = e_type_direct_from_key(base_ptr_member->type_key); + } + + // rjf: fill + if(count_member && base_ptr_member) + { + E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + accel->count = count; + accel->base_ptr_vaddr = base_ptr_vaddr; + accel->element_type_key = element_type_key; + info.user_data = accel; + info.idxed_expr_count = accel->count; + } + + // rjf: fall back to default + else + { + info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + } + } + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(slice) +{ + if(user_data == 0) + { + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + } + else + { + E_SliceAccel *accel = (E_SliceAccel *)user_data; + U64 out_idx = 0; + U64 element_type_size = e_type_byte_size_from_key(accel->element_type_key); + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->value.u64 = accel->base_ptr_vaddr + idx*element_type_size; + expr->type_key = accel->element_type_key; + exprs[out_idx] = expr; + exprs_strings[out_idx] = push_str8f(arena, "[%I64u]", idx); + } + } } //////////////////////////////// @@ -95,6 +322,15 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count) E_LookupRuleMap map = {0}; map.slots_count = slots_count; map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(folder)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(file), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); return map; } @@ -582,75 +818,6 @@ E_IRGEN_FUNCTION_DEF(array) return irtree; } -E_IRGEN_FUNCTION_DEF(slice) -{ - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key); - if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) - { - // rjf: unpack members - E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key); - - // rjf: choose base pointer & count members - E_Member *base_ptr_member = 0; - E_Member *count_member = 0; - for(U64 idx = 0; idx < members.count; idx += 1) - { - E_Member *member = &members.v[idx]; - E_TypeKey member_type = e_type_unwrap(member->type_key); - E_TypeKind member_type_kind = e_type_kind_from_key(member_type); - if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) - { - count_member = member; - } - if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) - { - base_ptr_member = &members.v[idx]; - } - if(count_member != 0 && base_ptr_member != 0) - { - break; - } - } - - // rjf: evaluate count member, determine count - U64 count = 0; - if(count_member != 0) - { - E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, &irtree, count_member->name); - E_Value count_member_value = e_value_from_expr(count_member_expr); - count = count_member_value.u64; - } - - // rjf: generate new struct slice type - E_TypeKey slice_type_key = zero_struct; - if(base_ptr_member != 0 && count_member != 0) - { - String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key); - E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key); - E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count, 0); - E_MemberList slice_type_members = {0}; - e_member_list_push(scratch.arena, &slice_type_members, count_member); - e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .off = base_ptr_member->off}); - E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members); - slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch, - .kind = E_TypeKind_Struct, - .name = struct_name, - .members = slice_type_members_array.v, - .count = slice_type_members_array.count); - } - - // rjf: overwrite type - if(!e_type_key_match(slice_type_key, e_type_key_zero())) - { - irtree.type_key = slice_type_key; - } - } - scratch_end(scratch); - return irtree; -} - E_IRGEN_FUNCTION_DEF(wrap) { Temp scratch = scratch_begin(&arena, 1); @@ -703,7 +870,6 @@ e_irgen_rule_map_make(Arena *arena, U64 slots_count) e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("slice"), .irgen = E_IRGEN_FUNCTION_NAME(slice)); e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); return map; } @@ -877,6 +1043,59 @@ e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) return exprs; } +//////////////////////////////// +//~ rjf: Evaluated String IDs + +internal U64 +e_id_from_string(String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 hash_slot_idx = hash%e_ir_state->string_id_map->hash_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_ir_state->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_ir_state->string_id_gen += 1; + U64 id = e_ir_state->string_id_gen; + U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; + node = push_array(e_ir_state->arena, E_StringIDNode, 1); + SLLQueuePush_N(e_ir_state->string_id_map->hash_slots[hash_slot_idx].first, e_ir_state->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next); + SLLQueuePush_N(e_ir_state->string_id_map->id_slots[id_slot_idx].first, e_ir_state->string_id_map->hash_slots[id_slot_idx].last, node, id_next); + node->id = id; + node->string = push_str8_copy(e_ir_state->arena, string); + } + U64 result = node->id; + return result; +} + +internal String8 +e_string_from_id(U64 id) +{ + U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_ir_state->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: IR-ization Functions @@ -1910,14 +2129,26 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { - U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); - E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; - U64 size = fs_size_from_path(expr->string); - E_IRNode *base_offset = e_irtree_const_u(arena, 0); - base_offset->space = space; - result.root = base_offset; - result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); - result.mode = E_Mode_Offset; + FileProperties props = fs_properties_from_path(expr->string); + if(props.flags & FilePropertyFlag_IsFolder) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(expr->string))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.mode = E_Mode_Value; + } + else + { + U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); + E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; + U64 size = props.size; + E_IRNode *base_offset = e_irtree_const_u(arena, 0); + base_offset->space = space; + result.root = base_offset; + result.root->string = push_str8_copy(arena, expr->string); + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); + result.mode = E_Mode_Offset; + } }break; //- rjf: types diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 2fcc65a9..cfcecfb3 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -266,6 +266,34 @@ struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheSlot *slots; }; +//////////////////////////////// +//~ rjf: Evaluated String ID Map + +typedef struct E_StringIDNode E_StringIDNode; +struct E_StringIDNode +{ + E_StringIDNode *hash_next; + E_StringIDNode *id_next; + U64 id; + String8 string; +}; + +typedef struct E_StringIDSlot E_StringIDSlot; +struct E_StringIDSlot +{ + E_StringIDNode *first; + E_StringIDNode *last; +}; + +typedef struct E_StringIDMap E_StringIDMap; +struct E_StringIDMap +{ + U64 id_slots_count; + E_StringIDSlot *id_slots; + U64 hash_slots_count; + E_StringIDSlot *hash_slots; +}; + //////////////////////////////// //~ rjf: IR Context @@ -310,6 +338,8 @@ struct E_IRState E_TypeAutoHookCacheMap *type_auto_hook_cache_map; U64 irtree_and_type_cache_slots_count; E_IRTreeAndTypeCacheSlot *irtree_and_type_cache_slots; + U64 string_id_gen; + E_StringIDMap *string_id_map; }; //////////////////////////////// @@ -380,6 +410,12 @@ internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_Au internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key); internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key); +//////////////////////////////// +//~ rjf: Evaluated String IDs + +internal U64 e_id_from_string(String8 string); +internal String8 e_string_from_id(U64 id); + //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 78943d80..4e800955 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -432,10 +432,6 @@ e_type_key_cons_(E_ConsTypeParams *params) { node->byte_size = bit_size_from_arch(node->params.arch)/8; }break; - case E_TypeKind_SpacePtr: - { - node->byte_size = sizeof(U64) + sizeof(E_Space); - }break; case E_TypeKind_Array: { U64 ptee_size = e_type_byte_size_from_key(node->params.direct_key); @@ -1693,12 +1689,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } }break; - case E_TypeKind_SpacePtr: - { - E_TypeKey direct = e_type_direct_from_key(key); - e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - }break; - case E_TypeKind_LRef: { E_TypeKey direct = e_type_direct_from_key(key); diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 673119c9..85f5c32c 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -139,7 +139,7 @@ E_OpInfo e_expr_kind_op_info_table[51] = { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; -U8 e_kind_basic_byte_size_table[57] = +U8 e_kind_basic_byte_size_table[56] = { 0, 0, @@ -197,10 +197,9 @@ U8 e_kind_basic_byte_size_table[57] = 0, 0, 0, -0, }; -String8 e_kind_basic_string_table[57] = +String8 e_kind_basic_string_table[56] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -257,7 +256,6 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), -str8_lit_comp("space_ptr"), str8_lit_comp("set"), }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index f227b316..666ad046 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,7 +74,6 @@ E_TypeKind_IncompleteClass, E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, -E_TypeKind_SpacePtr, E_TypeKind_Set, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, @@ -167,8 +166,8 @@ extern String8 e_token_kind_strings[6]; extern String8 e_expr_kind_strings[51]; extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[51]; -extern U8 e_kind_basic_byte_size_table[57]; -extern String8 e_kind_basic_string_table[57]; +extern U8 e_kind_basic_byte_size_table[56]; +extern String8 e_kind_basic_string_table[56]; C_LINKAGE_END diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 2cce058e..8c6af7d8 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -498,7 +498,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval) +ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -508,7 +508,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval //- rjf: generate root expression EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); - E_Expr *root_expr = e_expr_copy(arena, eval.exprs.last); + E_Expr *root_expr = e_expr_copy(arena, exprs.last); ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); //- rjf: generate root block diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index fa875eef..fceef439 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -337,7 +337,7 @@ internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *blo //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval); +internal EV_BlockTree ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index 3f23f113..1d086113 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -189,11 +189,11 @@ fs_key_from_path_range(String8 path, Rng1U64 range) return key; } -internal U64 -fs_timestamp_from_path(String8 path) +internal FileProperties +fs_properties_from_path(String8 path) { Temp scratch = scratch_begin(0, 0); - U64 result = 0; + FileProperties result = {0}; path = path_normalized_from_string(scratch.arena, path); U64 path_hash = fs_little_hash_from_string(path); U64 slot_idx = path_hash%fs_shared->slots_count; @@ -206,33 +206,7 @@ fs_timestamp_from_path(String8 path) { if(str8_match(path, n->path, 0)) { - result = n->timestamp; - break; - } - } - } - scratch_end(scratch); - return result; -} - -internal U64 -fs_size_from_path(String8 path) -{ - Temp scratch = scratch_begin(0, 0); - U64 result = 0; - path = path_normalized_from_string(scratch.arena, path); - U64 path_hash = fs_little_hash_from_string(path); - U64 slot_idx = path_hash%fs_shared->slots_count; - U64 stripe_idx = slot_idx%fs_shared->stripes_count; - FS_Slot *slot = &fs_shared->slots[slot_idx]; - FS_Stripe *stripe = &fs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) - { - for(FS_Node *n = slot->first; n != 0; n = n->next) - { - if(str8_match(path, n->path, 0)) - { - result = n->size; + result = n->props; break; } } @@ -333,7 +307,7 @@ ASYNC_WORK_DEF(fs_stream_work) B32 read_good = (pre_props.modified == post_props.modified && pre_props.size == post_props.size && read_size == data.size && - file_handle_is_valid); + (file_handle_is_valid || pre_props.flags & FilePropertyFlag_IsFolder)); if(!read_good) { ProfScope("abort") @@ -367,12 +341,11 @@ ASYNC_WORK_DEF(fs_stream_work) } if(node != 0 && read_good) { - if(node->timestamp != 0) + if(node->props.modified != 0) { ins_atomic_u64_inc_eval(&fs_shared->change_gen); } - node->timestamp = post_props.modified; - node->size = post_props.size; + node->props = post_props; } } os_condition_variable_broadcast(path_stripe->cv); @@ -403,7 +376,7 @@ fs_detector_thread__entry_point(void *p) for(FS_Node *n = slot->first; n != 0; n = n->next) { FileProperties props = os_properties_from_file_path(n->path); - if(props.modified != n->timestamp) + if(props.modified != n->props.modified) { for(U64 range_slot_idx = 0; range_slot_idx < n->slots_count; range_slot_idx += 1) { diff --git a/src/file_stream/file_stream.h b/src/file_stream/file_stream.h index 80b1e34a..d1ec870b 100644 --- a/src/file_stream/file_stream.h +++ b/src/file_stream/file_stream.h @@ -31,8 +31,7 @@ struct FS_Node // rjf: file metadata String8 path; - U64 timestamp; - U64 size; + FileProperties props; // rjf: sub-table of per-requested-file-range info U64 slots_count; @@ -108,8 +107,7 @@ internal U64 fs_change_gen(void); internal U128 fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us); internal U128 fs_key_from_path_range(String8 path, Rng1U64 range); -internal U64 fs_timestamp_from_path(String8 path); -internal U64 fs_size_from_path(String8 path); +internal FileProperties fs_properties_from_path(String8 path); //////////////////////////////// //~ rjf: Streaming Work diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index f302dd22..52c4aa3a 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -555,8 +555,8 @@ fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) hash2style_node = push_array(f_state->raster_arena, FNT_Hash2StyleRasterCacheNode, 1); DLLPushBack_NP(slot->first, slot->last, hash2style_node, hash_next, hash_prev); hash2style_node->style_hash = style_hash; - hash2style_node->ascent = metrics.ascent; - hash2style_node->descent= metrics.descent; + hash2style_node->ascent = metrics.ascent; + hash2style_node->descent = metrics.descent; hash2style_node->utf8_class1_direct_map = push_array_no_zero(f_state->raster_arena, F_RasterCacheInfo, 256); hash2style_node->hash2info_slots_count = 1024; hash2style_node->hash2info_slots = push_array(f_state->raster_arena, FNT_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fe8264d8..09e8648a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -241,7 +241,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) } //////////////////////////////// -//~ rjf: Top-Level Config Eval Hooks +//~ rjf: Config Eval Hooks typedef struct RD_CfgLookupAccel RD_CfgLookupAccel; struct RD_CfgLookupAccel @@ -2057,7 +2057,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 // DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, size}; B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.8f;} +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.95f;} //- rjf: push icon if(icon_kind != RD_IconKind_Null) @@ -6941,7 +6941,7 @@ rd_window_frame(void) RD_RegsScope(.view = view->id) { rd_cfg_new_replace(expr, ws->hover_eval_string); - EV_BlockTree predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); if(ws->hover_eval_focused) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3cb30460..22226539 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1108,7 +1108,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr - else if(info.eval.exprs.last == &e_expr_nil && info.group_cfg_name.size != 0) + else if(info.eval.exprs.last == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } @@ -1554,7 +1554,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); } - block_tree = ev_block_tree_from_eval(scratch.arena, eval_view, filter, eval); + block_tree = ev_block_tree_from_exprs(scratch.arena, eval_view, filter, eval.exprs); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); if(implicit_root && block_ranges.first != 0) { @@ -3438,7 +3438,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) B32 file_is_out_of_date = 0; String8 out_of_date_dbgi_name = {0}; { - U64 file_timestamp = fs_timestamp_from_path(rd_regs()->file_path); + U64 file_timestamp = fs_properties_from_path(rd_regs()->file_path).modified; if(file_timestamp != 0) { for(DI_KeyNode *n = dbgi_keys.first; n != 0; n = n->next) From 95493b6c300c1099d7c07795f8d711311cb7cb47 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 16 Feb 2025 14:22:01 -0800 Subject: [PATCH 125/755] do not lex/highlight non-code strings in watch cell --- src/raddbg/raddbg_views.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 22226539..52a9ad60 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2926,9 +2926,24 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: build cell line edit else { + // rjf: compute visual params + B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); + String8 ghost_text = {0}; + if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) + { + ghost_text = str8_lit("Expression"); + is_non_code = !cell_selected || !ewv->text_editing; + } + else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) + { + ghost_text = str8_lit("View Rules"); + is_non_code = !cell_selected || !ewv->text_editing; + } + + // rjf: build RD_LineEditParams line_edit_params = {0}; { - line_edit_params.flags = (RD_LineEditFlag_CodeContents| + line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| RD_LineEditFlag_NoBackground*!(cell_info.flags & RD_WatchCellFlag_Button)| RD_LineEditFlag_Button*!!(cell_info.flags & RD_WatchCellFlag_Button)| RD_LineEditFlag_SingleClickActivate*!!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)| @@ -2947,23 +2962,9 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.fstrs = cell_info.fstrs; } UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) - { - B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); - String8 ghost_text = {0}; - if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) - { - ghost_text = str8_lit("Expression"); - is_non_code = !cell_selected || !ewv->text_editing; - } - else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) - { - ghost_text = str8_lit("View Rules"); - is_non_code = !cell_selected || !ewv->text_editing; - } RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); - } + { + sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); } #if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && From 5e98e40af7897058d706f8c6dd8e7d42658b74ac Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 16 Feb 2025 17:57:00 -0800 Subject: [PATCH 126/755] file/folder evaluation work --- src/eval/eval_ir.c | 122 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 24 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5d4895fd..acfb92f2 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -157,47 +157,121 @@ E_LOOKUP_INFO_FUNCTION_DEF(folder) return info; } -E_LOOKUP_ACCESS_FUNCTION_DEF(folder) +E_LOOKUP_RANGE_FUNCTION_DEF(folder) { - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + E_FolderAccel *accel = (E_FolderAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { Temp scratch = scratch_begin(&arena, 1); - E_FolderAccel *accel = (E_FolderAccel *)user_data; - U64 idx = e_value_from_expr(rhs).u64; + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; if(0 <= idx && idx < accel->folders.count) { - String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, accel->folders.v[idx - 0]); - U64 string_id = e_id_from_string(folder_path); - E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, string_id)); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); - result.irtree_and_type.mode = E_Mode_Value; + String8 folder_name = accel->folders.v[idx - 0]; + String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, folder_name); + expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(folder_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); } else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) { - String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, accel->files.v[idx - accel->folders.count]); - U64 string_id = e_id_from_string(file_path); - E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, string_id)); - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); - result.irtree_and_type.mode = E_Mode_Value; + String8 file_name = accel->files.v[idx - accel->folders.count]; + String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, file_name); + expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(file_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); } + exprs[out_idx] = expr; + exprs_strings[out_idx] = expr_string; scratch_end(scratch); } - return result; } +typedef struct E_FileAccel E_FileAccel; +struct E_FileAccel +{ + String8 file_path; + FileProperties props; + String8Array fields; +}; + E_LOOKUP_INFO_FUNCTION_DEF(file) { - E_LookupInfo info = {0}; + E_FileAccel *accel = push_array(arena, E_FileAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + + //- rjf: get file path + String8 file_path = e_string_from_id(lhs_string_id); + + //- rjf: build field list + String8List fields = {0}; + str8_list_pushf(arena, &fields, "size"); + str8_list_pushf(arena, &fields, "last_modified_time"); + str8_list_pushf(arena, &fields, "creation_time"); + str8_list_pushf(arena, &fields, "data"); + + //- rjf: fill accel + accel->file_path = push_str8_copy(arena, file_path); + accel->props = os_properties_from_file_path(file_path); + accel->fields = str8_array_from_list(arena, &fields); + + scratch_end(scratch); + } + E_LookupInfo info = {accel, accel->fields.count}; return info; } -E_LOOKUP_ACCESS_FUNCTION_DEF(file) +E_LOOKUP_RANGE_FUNCTION_DEF(file) { - E_LookupAccess result = {{&e_irnode_nil}}; - return result; + E_FileAccel *accel = (E_FileAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = &e_expr_nil; + String8 string = {0}; + if(0 <= idx && idx < accel->fields.count) + { + String8 name = accel->fields.v[idx]; + if(str8_match(name, str8_lit("size"), 0)) + { + expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); + expr->value.u64 = accel->props.size; + } + else if(str8_match(name, str8_lit("last_modified_time"), 0)) + { + expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); + expr->value.u64 = accel->props.modified; + } + else if(str8_match(name, str8_lit("creation_time"), 0)) + { + expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); + expr->value.u64 = accel->props.created; + } + else if(str8_match(name, str8_lit("data"), 0)) + { + expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = e_space_make(E_SpaceKind_HashStoreKey); + expr->space.u128 = fs_key_from_path_range(accel->file_path, r1u64(0, max_U64)); + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size); + } + string = push_str8f(arena, ".%S", name); + } + exprs[out_idx] = expr; + exprs_strings[out_idx] = string; + } } //////////////////////////////// @@ -324,10 +398,10 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count) map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(folder)); + .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), .info = E_LOOKUP_INFO_FUNCTION_NAME(file), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file)); + .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); From c77f2de156175b283951150af00d43219099de7a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 16 Feb 2025 18:36:45 -0800 Subject: [PATCH 127/755] more work on file evaluation; move eval_string <-> eval <-> file_path to formal filesystem/file spaces, rather than inferring from the expression tree; imply '.data' when generating file contents visualizer tabs --- src/eval/eval_core.h | 3 +- src/eval/eval_ir.c | 74 +++++++++++----- .../eval_visualization_core.c | 12 ++- src/raddbg/raddbg_core.c | 88 ++++++++++++++----- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 2 +- 6 files changed, 132 insertions(+), 48 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 01eb7685..650597b8 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -93,8 +93,9 @@ typedef U64 E_SpaceKind; enum { E_SpaceKind_Null, - E_SpaceKind_HashStoreKey, + E_SpaceKind_File, E_SpaceKind_FileSystem, + E_SpaceKind_HashStoreKey, E_SpaceKind_FirstUserDefined, }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index acfb92f2..d2d81b93 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -234,6 +234,43 @@ E_LOOKUP_INFO_FUNCTION_DEF(file) return info; } +E_LOOKUP_ACCESS_FUNCTION_DEF(file) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_MemberAccess) + { + E_FileAccel *accel = (E_FileAccel *)user_data; + String8 member_name = rhs->string; + if(str8_match(member_name, str8_lit("size"), 0)) + { + result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.size); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("last_modified_time"), 0)) + { + result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.modified); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("creation_time"), 0)) + { + result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.created); + result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); + result.irtree_and_type.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("data"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_File); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size); + result.irtree_and_type.mode = E_Mode_Offset; + } + } + return result; +} + E_LOOKUP_RANGE_FUNCTION_DEF(file) { E_FileAccel *accel = (E_FileAccel *)user_data; @@ -245,29 +282,11 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file) if(0 <= idx && idx < accel->fields.count) { String8 name = accel->fields.v[idx]; - if(str8_match(name, str8_lit("size"), 0)) - { - expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = accel->props.size; - } - else if(str8_match(name, str8_lit("last_modified_time"), 0)) - { - expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = accel->props.modified; - } - else if(str8_match(name, str8_lit("creation_time"), 0)) - { - expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = accel->props.created; - } - else if(str8_match(name, str8_lit("data"), 0)) - { - expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = e_space_make(E_SpaceKind_HashStoreKey); - expr->space.u128 = fs_key_from_path_range(accel->file_path, r1u64(0, max_U64)); - expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size); - } - string = push_str8f(arena, ".%S", name); + expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + rhs->string = push_str8_copy(arena, name); + e_expr_push_child(expr, e_expr_ref(arena, lhs)); + e_expr_push_child(expr, rhs); } exprs[out_idx] = expr; exprs_strings[out_idx] = string; @@ -401,6 +420,7 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count) .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), .info = E_LOOKUP_INFO_FUNCTION_NAME(file), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), @@ -2203,7 +2223,7 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { - FileProperties props = fs_properties_from_path(expr->string); + FileProperties props = os_properties_from_file_path(expr->string); if(props.flags & FilePropertyFlag_IsFolder) { E_Space space = e_space_make(E_SpaceKind_FileSystem); @@ -2213,6 +2233,11 @@ E_IRGEN_FUNCTION_DEF(default) } else { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(expr->string))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.mode = E_Mode_Value; +#if 0 U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; U64 size = props.size; @@ -2222,6 +2247,7 @@ E_IRGEN_FUNCTION_DEF(default) result.root->string = push_str8_copy(arena, expr->string); result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); result.mode = E_Mode_Offset; +#endif } }break; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 8c6af7d8..4ac042e4 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -584,6 +584,14 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai expansion_row_count = expand_info.row_count; } + // rjf: determine if this expansion supports child expansions + B32 allow_child_expansions = 1; + if(expand_info.single_item) + { + // NOTE(rjf): for now, just plugging in the heuristic of "is this a single row (a.k.a. visualizer)?" + allow_child_expansions = 0; + } + // rjf: generate block for expansion EV_Block *expansion_block = &ev_nil_block; if(expansion_row_count != 0) @@ -612,7 +620,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai U64 child_count = 0; EV_Key *child_keys = 0; U64 *child_nums = 0; - if(!child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) + if(allow_child_expansions && !child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) { // rjf: count children for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} @@ -659,7 +667,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai } // rjf: gather children expansions from inverse of expansion state - if(!child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) + if(allow_child_expansions && !child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) { child_count = expand_info.row_count; child_keys = push_array(scratch.arena, EV_Key, child_count); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 09e8648a..6177e6cf 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3010,7 +3010,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) B32 result = 0; switch(space.kind) { - //- rjf: filesystem reads + //- rjf: reads from hash store key case E_SpaceKind_HashStoreKey: { U128 key = space.u128; @@ -3029,6 +3029,27 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) hs_scope_close(scope); }break; + //- rjf: file reads + case E_SpaceKind_File: + { + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + U128 key = fs_key_from_path_range(file_path, range); + U128 hash = hs_hash_from_key(key, 0); + HS_Scope *scope = hs_scope_open(); + { + String8 data = hs_data_from_hash(scope, hash); + Rng1U64 legal_range = r1u64(0, data.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) + { + result = 1; + MemoryCopy(out, data.str + read_range.min, dim_1u64(read_range)); + } + } + hs_scope_close(scope); + }break; + //- rjf: interior control entity reads (inside process address space or thread register block) case RD_EvalSpaceKind_CtrlEntity: { @@ -3301,6 +3322,12 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) { result = space.u128; }break; + case E_SpaceKind_File: + { + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + result = fs_key_from_path_range(file_path, range); + }break; case RD_EvalSpaceKind_CtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); @@ -3323,19 +3350,21 @@ rd_whole_range_from_eval_space(E_Space space) { case E_SpaceKind_HashStoreKey: { - HS_Scope *scope = hs_scope_open(); - U128 hash = {0}; - for(U64 idx = 0; idx < 2; idx += 1) + U128 key = space.u128; + U128 hash = hs_hash_from_key(key, 0); + HS_Scope *hs_scope = hs_scope_open(); { - hash = hs_hash_from_key(space.u128, idx); - if(!u128_match(hash, u128_zero())) - { - break; - } + String8 data = hs_data_from_hash(hs_scope, hash); + result = r1u64(0, data.size); } - String8 data = hs_data_from_hash(scope, hash); - result = r1u64(0, data.size); - hs_scope_close(scope); + hs_scope_close(hs_scope); + }break; + case E_SpaceKind_File: + { + U64 file_path_string_id = space.u64_0; + String8 file_path = e_string_from_id(file_path_string_id); + FileProperties props = os_properties_from_file_path(file_path); + result = r1u64(0, props.size); }break; case RD_EvalSpaceKind_CtrlEntity: { @@ -3463,17 +3492,33 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un //- rjf: eval <-> file path +internal String8 +rd_file_path_from_eval(Arena *arena, E_Eval eval) +{ + String8 result = {0}; + switch(eval.space.kind) + { + default:{}break; + case E_SpaceKind_File: + { + result = push_str8_copy(arena, e_string_from_id(eval.space.u64_0)); + }break; + case E_SpaceKind_FileSystem: + { + result = push_str8_copy(arena, e_string_from_id(eval.value.u64)); + }break; + } + return result; +} + internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string) { String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; - if(expr->kind == E_ExprKind_LeafFilePath) - { - result = raw_from_escaped_str8(arena, expr->string); - } + E_Eval eval = e_eval_from_string(scratch.arena, string); + result = rd_file_path_from_eval(arena, eval); scratch_end(scratch); } return result; @@ -3484,7 +3529,7 @@ rd_eval_string_from_file_path(Arena *arena, String8 string) { Temp scratch = scratch_begin(&arena, 1); String8 string_escaped = escaped_from_raw_str8(scratch.arena, string); - String8 result = push_str8f(arena, "file:\"%S\"", string_escaped); + String8 result = push_str8f(arena, "file:\"%S\".data", string_escaped); scratch_end(scratch); return result; } @@ -3933,9 +3978,11 @@ internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) { TXT_LangKind lang_kind = TXT_LangKind_Null; - if(eval.exprs.last->kind == E_ExprKind_LeafFilePath) + Temp scratch = scratch_begin(0, 0); + String8 file_path = rd_file_path_from_eval(scratch.arena, eval); + if(file_path.size != 0) { - lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.exprs.last->string)); + lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path)); } else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) { @@ -3945,6 +3992,7 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) break; } } + scratch_end(scratch); return lang_kind; } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ffe25121..484c74b0 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1037,6 +1037,7 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); //- rjf: eval <-> file path +internal String8 rd_file_path_from_eval(Arena *arena, E_Eval eval); internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 52a9ad60..5b00ac72 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2878,7 +2878,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); rd_cfg_new(view, str8_lit("selected")); - RD_RegsScope(.view = view->id) + RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) UI_Flags(0) { From 5d8e6dac910b2921c2c6f3bd34144a807de5edaa Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 16 Feb 2025 22:16:59 -0800 Subject: [PATCH 128/755] begin working on watch window stylization for file system evaluations --- src/eval/eval.mdesk | 2 - src/eval/eval_ir.c | 80 ++++++------------------------ src/eval/generated/eval.meta.c | 6 +-- src/eval/generated/eval.meta.h | 5 +- src/file_stream/file_stream.c | 2 +- src/raddbg/generated/raddbg.meta.c | 5 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 3 ++ src/raddbg/raddbg_core.c | 20 ++++++-- src/raddbg/raddbg_views.c | 40 ++++++++++++++- 10 files changed, 83 insertions(+), 82 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index fd5be091..a80bcb2d 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -134,8 +134,6 @@ E_ExprKindTable: { Array Null 0 "array" "" "" "" } { Func Null 0 "function" "" "" "" } - { Line Binary 1 ":" "" ":" "" } - { Define Binary 13 "=" "" "=" "" } { Tag Null 0 "=>" "=>" "," "" } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index d2d81b93..c5b90c48 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -243,19 +243,25 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(file) String8 member_name = rhs->string; if(str8_match(member_name, str8_lit("size"), 0)) { - result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.size); + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.size)); result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); result.irtree_and_type.mode = E_Mode_Value; } else if(str8_match(member_name, str8_lit("last_modified_time"), 0)) { - result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.modified); + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.modified)); result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); result.irtree_and_type.mode = E_Mode_Value; } else if(str8_match(member_name, str8_lit("creation_time"), 0)) { - result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.created); + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.created)); result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); result.irtree_and_type.mode = E_Mode_Value; } @@ -2223,32 +2229,24 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { - FileProperties props = os_properties_from_file_path(expr->string); + Temp scratch = scratch_begin(&arena, 1); + String8 file_path = path_normalized_from_string(scratch.arena, expr->string); + FileProperties props = os_properties_from_file_path(file_path); if(props.flags & FilePropertyFlag_IsFolder) { E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(expr->string))); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); result.mode = E_Mode_Value; } else { E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(expr->string))); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); result.mode = E_Mode_Value; -#if 0 - U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); - E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; - U64 size = props.size; - E_IRNode *base_offset = e_irtree_const_u(arena, 0); - base_offset->space = space; - result.root = base_offset; - result.root->string = push_str8_copy(arena, expr->string); - result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); - result.mode = E_Mode_Offset; -#endif } + scratch_end(scratch); }break; //- rjf: types @@ -2268,54 +2266,6 @@ E_IRGEN_FUNCTION_DEF(default) e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Type expression not expected."); }break; - //- rjf: textual line slicing - case E_ExprKind_Line: - { - E_Expr *lhs = expr->first; - E_Expr *rhs = expr->last; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - U64 line_num = rhs->value.u64; - B32 space_is_good = 1; - E_Space space = {0}; - if(lhs_irtree.root->op != E_IRExtKind_SetSpace) - { - space_is_good = 0; - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, lhs->location, "Cannot take a line from a non-file."); - } - else - { - MemoryCopy(&space, &lhs_irtree.root->value, sizeof(space)); - } - B32 line_num_is_good = 1; - if(rhs->kind != E_ExprKind_LeafU64) - { - line_num_is_good = 0; - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, rhs->location, "Line number must be specified as a constant number."); - } - if(space_is_good && line_num_is_good) - { - TXT_Scope *txt_scope = txt_scope_open(); - U128 key = space.u128; - U128 hash = {0}; - TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, TXT_LangKind_Null, &hash); - if(1 <= line_num && line_num <= text_info.lines_count) - { - Rng1U64 line_range = text_info.lines_ranges[line_num-1]; - U64 line_size = dim_1u64(line_range); - E_IRNode *line_offset = e_irtree_const_u(arena, line_range.min); - result.root = line_offset; - result.root->space = space; - result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size); - result.mode = E_Mode_Offset; - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, rhs->location, "Line %I64u is out of bounds.", line_num); - } - txt_scope_close(txt_scope); - } - }break; - //- rjf: definitions case E_ExprKind_Define: { diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 85f5c32c..25e429c6 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[51] = +String8 e_expr_kind_strings[50] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -64,7 +64,6 @@ str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), -str8_lit_comp("Line"), str8_lit_comp("Define"), str8_lit_comp("Tag"), }; @@ -84,7 +83,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[51] = +E_OpInfo e_expr_kind_op_info_table[50] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -134,7 +133,6 @@ E_OpInfo e_expr_kind_op_info_table[51] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Binary, 1, str8_lit_comp(""), str8_lit_comp(":"), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 666ad046..ad31221e 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -139,7 +139,6 @@ E_ExprKind_TypeIdent, E_ExprKind_Ptr, E_ExprKind_Array, E_ExprKind_Func, -E_ExprKind_Line, E_ExprKind_Define, E_ExprKind_Tag, E_ExprKind_COUNT, @@ -163,9 +162,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[51]; +extern String8 e_expr_kind_strings[50]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[51]; +extern E_OpInfo e_expr_kind_op_info_table[50]; extern U8 e_kind_basic_byte_size_table[56]; extern String8 e_kind_basic_string_table[56]; diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index 1d086113..792bc6d7 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -288,7 +288,7 @@ ASYNC_WORK_DEF(fs_stream_work) ProfBegin("load \"%.*s\"", str8_varg(path)); FileProperties pre_props = os_properties_from_file_path(path); U64 range_size = dim_1u64(range); - U64 read_size = Min(pre_props.size, range_size); + U64 read_size = Min(pre_props.size - range.min, range_size); OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path); B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file); U64 data_arena_size = read_size+ARENA_HEADER_SIZE; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e130a444..0b5cf13b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[285] = +RD_VocabInfo rd_vocab_info_table[288] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -79,6 +79,9 @@ RD_VocabInfo rd_vocab_info_table[285] = {str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, {str8_lit_comp("frozen"), str8_lit_comp(""), str8_lit_comp("Frozen"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("id"), str8_lit_comp("ids"), str8_lit_comp("ID"), str8_lit_comp("IDs"), RD_IconKind_Null}, +{str8_lit_comp("last_modified_time"), str8_lit_comp("last_modified_times"), str8_lit_comp("Last Modified Time"), str8_lit_comp("Last Modified Times"), RD_IconKind_Null}, +{str8_lit_comp("creation_time"), str8_lit_comp("creation_times"), str8_lit_comp("Creation Time"), str8_lit_comp("Creation Times"), RD_IconKind_Null}, +{str8_lit_comp("data"), str8_lit_comp("datas"), str8_lit_comp("Data"), str8_lit_comp("Datas"), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_init"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index ac4d4898..8fc45d3e 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -555,7 +555,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[285]; +extern RD_VocabInfo rd_vocab_info_table[288]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8d1c8289..6396fd4f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -91,6 +91,9 @@ RD_VocabTable: {environment _ "Environment" _ Null } {frozen "" "Frozen" "" Null } {id _ "ID" _ Null } + {last_modified_time _ "Last Modified Time" _ Null } + {creation_time _ "Creation Time" _ Null } + {data _ "Data" _ Null } } @struct RD_VocabInfo: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6177e6cf..6b82b9a9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3032,19 +3032,31 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: file reads case E_SpaceKind_File: { + // rjf: unpack space/path U64 file_path_string_id = space.u64_0; String8 file_path = e_string_from_id(file_path_string_id); - U128 key = fs_key_from_path_range(file_path, range); + + // rjf: find containing chunk range + U64 chunk_size = KB(4); + Rng1U64 containing_range = range; + containing_range.min -= containing_range.min%chunk_size; + containing_range.max += chunk_size-1; + containing_range.max -= containing_range.max%chunk_size; + + // rjf: map to hash + U128 key = fs_key_from_path_range(file_path, containing_range); U128 hash = hs_hash_from_key(key, 0); + + // rjf: look up from hash store HS_Scope *scope = hs_scope_open(); { String8 data = hs_data_from_hash(scope, hash); - Rng1U64 legal_range = r1u64(0, data.size); + Rng1U64 legal_range = r1u64(containing_range.min, containing_range.min + data.size); Rng1U64 read_range = intersect_1u64(range, legal_range); if(read_range.min < read_range.max) { result = 1; - MemoryCopy(out, data.str + read_range.min, dim_1u64(read_range)); + MemoryCopy(out, data.str + read_range.min - containing_range.min, dim_1u64(read_range)); } } hs_scope_close(scope); @@ -8636,7 +8648,7 @@ rd_window_frame(void) { // rjf: brighten { - R_Rect2DInst *inst = dr_rect(box->rect, v4f32(0, 0, 0, 0), 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); color.w *= t*0.2f; inst->colors[Corner_00] = color; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5b00ac72..a655fd05 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1101,6 +1101,42 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } + // rjf: singular button for folders & files + else if(info.eval.space.kind == E_SpaceKind_FileSystem) + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; + E_Type *type = e_type_from_key__cached(info.eval.type_key); + String8 file_path = e_string_from_id(info.eval.value.u64); + String8 file_name = str8_skip_last_slash(file_path); + if(str8_match(type->name, str8_lit("folder"), 0)) + { + DR_FStrList fstrs = {0}; + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, + .pct = 1.f, + .fstrs = fstrs); + } + else + { + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + DR_FStrList fstrs = {0}; + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, + .default_pct = 0.35f, + .pct = take_pct(), + .fstrs = fstrs); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); +#undef take_pct + } + } + // rjf: singular cell for view ui else if(info.view_ui_rule != &rd_nil_view_ui_rule) { @@ -1243,7 +1279,9 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || - row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + row_eval.space.kind == E_SpaceKind_File || + row_eval.space.kind == E_SpaceKind_FileSystem) { String8 fancy_name = rd_display_from_code_name(member_name); if(fancy_name.size != 0) From 2636f296cc6c58fed7cba2f08f4e6590590bbd47 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 09:48:26 -0800 Subject: [PATCH 129/755] simplify stylized watch row building rules; allow buttons to be editable, maintain expr key stability even in different watch row styles --- src/eval/eval.mdesk | 1 + src/eval/eval_ir.c | 27 +++++++++-- src/eval/eval_types.c | 13 +++++ src/eval/eval_types.h | 14 +++--- src/eval/generated/eval.meta.c | 6 ++- src/eval/generated/eval.meta.h | 5 +- src/raddbg/raddbg_core.c | 13 +++-- src/raddbg/raddbg_views.c | 89 ++++++++++++++++++++++------------ src/raddbg/raddbg_views.h | 1 + 9 files changed, 120 insertions(+), 49 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index a80bcb2d..4f281812 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -127,6 +127,7 @@ E_ExprKindTable: { LeafF32 Null 0 "F32" "" "" "" } { LeafIdent Null 0 "leaf_ident" "" "" "" } { LeafOffset Null 0 "leaf_offset" "" "" "" } + { LeafValue Null 0 "leaf_value" "" "" "" } { LeafFilePath Null 0 "leaf_filepath" "" "" "" } { TypeIdent Null 0 "type_ident" "" "" "" } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index c5b90c48..68eaf957 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -170,7 +170,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) { String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, folder_name); - expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(folder_path); @@ -180,7 +180,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) { String8 file_name = accel->files.v[idx - accel->folders.count]; String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, file_name); - expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(file_path); @@ -305,6 +305,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file) typedef struct E_SliceAccel E_SliceAccel; struct E_SliceAccel { + Arch arch; U64 count; U64 base_ptr_vaddr; E_TypeKey element_type_key; @@ -343,6 +344,14 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) } } + // rjf: determine architecture + Arch arch = e_type_state->ctx->primary_module->arch; + if(base_ptr_member != 0) + { + E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); + arch = type->arch; + } + // rjf: evaluate count member, determine count U64 count = 0; if(count_member != 0) @@ -372,6 +381,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) if(count_member && base_ptr_member) { E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + accel->arch = arch; accel->count = count; accel->base_ptr_vaddr = base_ptr_vaddr; accel->element_type_key = element_type_key; @@ -2219,13 +2229,24 @@ E_IRGEN_FUNCTION_DEF(default) case E_ExprKind_LeafOffset: { E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); - new_tree->value.u64 = expr->value.u64; + new_tree->value = expr->value; new_tree->space = expr->space; result.root = new_tree; result.type_key = expr->type_key; result.mode = E_Mode_Offset; }break; + //- rjf: leaf values + case E_ExprKind_LeafValue: + { + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); + new_tree->value = expr->value; + new_tree->space = expr->space; + result.root = new_tree; + result.type_key = expr->type_key; + result.mode = E_Mode_Value; + }break; + //- rjf: leaf file paths case E_ExprKind_LeafFilePath: { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 4e800955..6a4195e0 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -628,6 +628,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = node->params.direct_key; type->count = node->params.count; type->depth = node->params.depth; + type->arch = node->params.arch; type->byte_size = node->byte_size; switch(type->kind) { @@ -706,6 +707,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = members_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->members = members; } @@ -750,6 +752,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = enum_vals_count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; type->enum_vals = enum_vals; type->direct_type_key = direct_type_key; } @@ -789,6 +792,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = direct_type_byte_size; type->flags = flags; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Ptr: case RDI_TypeKind_LRef: @@ -799,6 +803,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; type->count = 1; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Array: @@ -808,6 +813,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = rdi_type->constructed.count; type->byte_size = direct_type_byte_size * type->count; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Function: { @@ -823,6 +829,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -856,6 +863,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->owner_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -893,6 +901,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; type->owner_type_key = owner_type_key; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; }break; } } @@ -921,6 +930,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = direct_type_byte_size; type->direct_type_key = direct_type_key; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: bitfields @@ -944,6 +954,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->off = (U32)rdi_type->bitfield.off; type->count = (U64)rdi_type->bitfield.size; + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } //- rjf: incomplete types @@ -957,6 +968,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type = push_array(arena, E_Type, 1); type->kind = kind; type->name = push_str8_copy(arena, name); + type->arch = e_type_state->ctx->modules[rdi_idx].arch; } } @@ -984,6 +996,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->kind = E_TypeKind_Union; type->name = push_str8f(arena, "reg_%I64u_bit", reg_byte_count*8); type->byte_size = (U64)reg_byte_count; + type->arch = (Arch)key.u32[0]; // rjf: build register type members E_MemberList members = {0}; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 8dae9878..e59c09c4 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -67,12 +67,13 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_External = (1<<2), - E_TypeFlag_IsPlainText= (1<<3), - E_TypeFlag_IsCodeText = (1<<4), - E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_External = (1<<2), + E_TypeFlag_IsPlainText = (1<<3), + E_TypeFlag_IsCodeText = (1<<4), + E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), }; typedef struct E_Member E_Member; @@ -131,6 +132,7 @@ struct E_Type U64 count; U64 depth; U32 off; + Arch arch; E_TypeKey direct_type_key; E_TypeKey owner_type_key; E_TypeKey *param_type_keys; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 25e429c6..770eb9c2 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[50] = +String8 e_expr_kind_strings[51] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -59,6 +59,7 @@ str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), str8_lit_comp("LeafIdent"), str8_lit_comp("LeafOffset"), +str8_lit_comp("LeafValue"), str8_lit_comp("LeafFilePath"), str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), @@ -83,7 +84,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -E_OpInfo e_expr_kind_op_info_table[50] = +E_OpInfo e_expr_kind_op_info_table[51] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -133,6 +134,7 @@ E_OpInfo e_expr_kind_op_info_table[50] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index ad31221e..3288fa6c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -134,6 +134,7 @@ E_ExprKind_LeafF64, E_ExprKind_LeafF32, E_ExprKind_LeafIdent, E_ExprKind_LeafOffset, +E_ExprKind_LeafValue, E_ExprKind_LeafFilePath, E_ExprKind_TypeIdent, E_ExprKind_Ptr, @@ -162,9 +163,9 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_expr_kind_strings[50]; +extern String8 e_expr_kind_strings[51]; extern String8 e_interpretation_code_display_strings[11]; -extern E_OpInfo e_expr_kind_op_info_table[50]; +extern E_OpInfo e_expr_kind_op_info_table[51]; extern U8 e_kind_basic_byte_size_table[56]; extern String8 e_kind_basic_string_table[56]; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6b82b9a9..272bf9d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3996,12 +3996,15 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) { lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path)); } - else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + if(lang_kind == TXT_LangKind_Null) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) { - lang_kind = txt_lang_kind_from_extension(param->first->next->string); - break; + if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(param->first->next->string); + break; + } } } scratch_end(scratch); @@ -12382,7 +12385,7 @@ rd_frame(void) { String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a655fd05..8df9729e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -794,9 +794,12 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); - result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); - result = e_hash_from_string(result, str8_struct(&cell->index)); - result = e_hash_from_string(result, str8_struct(&cell->default_pct)); + if(cell->kind != RD_WatchCellKind_Expr) + { + result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); + result = e_hash_from_string(result, str8_struct(&cell->index)); + result = e_hash_from_string(result, str8_struct(&cell->default_pct)); + } return result; } @@ -921,6 +924,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); + // rjf: determine if row's expression is editable + if(block_type->flags & E_TypeFlag_EditableChildren || row->expr == &e_expr_nil) + { + info.expr_is_editable = 1; + } + // rjf: determine row's module CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(info.eval.space); CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); @@ -984,25 +993,30 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine row's cfg + // rjf: determine row's group cfg if(info.group_cfg_name.size != 0) { RD_CfgID id = row->key.child_id; info.group_cfg_child = rd_cfg_from_id(id); } - // rjf: determine if the row's evaluation matches the group configuration - // this distinguishes between e.g. "watches", which uses the group of watch cfgs, - // but does not evaluate them, from e.g. "targets", which uses the group of target - // cfgs, and the evaluations are of the targets themselves. - // - B32 row_cfg_eval_matches_group = 0; + // rjf: determine cfgs/entities that this row is evaluating RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); - B32 row_entity_eval_matches_group = 0; CTRL_Entity *evalled_entity = (info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(info.eval.space) : &ctrl_entity_nil); + + // rjf: determine if this cfg/entity evaluation is top-level - e.g. if we + // are evaluating a cfg tree, or some descendant of it + B32 is_top_level = 0; + if(evalled_cfg != &rd_nil_cfg) { - row_cfg_eval_matches_group = (evalled_cfg == info.group_cfg_child); - row_entity_eval_matches_group = (evalled_entity == info.group_entity); + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); + } + if(evalled_entity != &ctrl_entity_nil) + { + String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); } // rjf: determine view ui rule @@ -1016,9 +1030,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: cfg rows - else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCfg && row_cfg_eval_matches_group && info.group_cfg_parent == &rd_nil_cfg) || - (row->block->parent == &ev_nil_block && evalled_cfg != &rd_nil_cfg)) + // rjf: top-level cfg rows + else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); @@ -1071,9 +1084,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: entity rows - else if((info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && row_entity_eval_matches_group && info.group_entity != &ctrl_entity_nil) || - (row->block->parent == &ev_nil_block && evalled_entity != &ctrl_entity_nil)) + // rjf: top-level entity rows + else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); @@ -1091,17 +1103,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: singular button for commands - else if((block_eval.space.kind == RD_EvalSpaceKind_MetaCmd || - block_eval.space.kind == RD_EvalSpaceKind_MetaCfg) && - info.eval.space.kind == RD_EvalSpaceKind_MetaCmd && - row_cfg_eval_matches_group) + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); } - // rjf: singular button for folders & files + // rjf: folder / file rows else if(info.eval.space.kind == E_SpaceKind_FileSystem) { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; @@ -1111,7 +1120,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(str8_match(type->name, str8_lit("folder"), 0)) { DR_FStrList fstrs = {0}; - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + if(file_name.size) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FolderClosedFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f, @@ -1126,7 +1140,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) DR_FStrList fstrs = {0}; - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + if(file_name.size) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FileOutline], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .default_pct = 0.35f, @@ -1236,7 +1255,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // expression tree. case RD_WatchCellKind_Expr: { - if(!ev_key_match(ev_key_root(), row->block->key) && (row->string.size != 0 || row->expr == &e_expr_nil)) + if(row_info->expr_is_editable) { result.flags |= RD_WatchCellFlag_CanEdit; } @@ -2965,6 +2984,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) else { // rjf: compute visual params + B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) @@ -2977,17 +2998,23 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ghost_text = str8_lit("View Rules"); is_non_code = !cell_selected || !ewv->text_editing; } + if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + { + is_non_code = 0; + is_button = 0; + is_activated_on_single_click = 0; + } // rjf: build RD_LineEditParams line_edit_params = {0}; { line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| - RD_LineEditFlag_NoBackground*!(cell_info.flags & RD_WatchCellFlag_Button)| - RD_LineEditFlag_Button*!!(cell_info.flags & RD_WatchCellFlag_Button)| - RD_LineEditFlag_SingleClickActivate*!!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)| + RD_LineEditFlag_NoBackground*!is_button| + RD_LineEditFlag_Button*is_button| + RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !(cell_info.flags & RD_WatchCellFlag_Button))| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !is_button)| RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 68e84df8..9524d108 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -89,6 +89,7 @@ struct RD_WatchRowInfo { E_Eval eval; CTRL_Entity *module; + B32 expr_is_editable; String8 group_cfg_name; RD_Cfg *group_cfg_parent; RD_Cfg *group_cfg_child; From dc79b82991ab65a7fe9483bd15e99a1127638d21 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 10:13:34 -0800 Subject: [PATCH 130/755] watch pin view rules --- src/raddbg/raddbg_core.c | 27 +++++++++++++++++++-------- src/raddbg/raddbg_core.h | 4 +++- src/raddbg/raddbg_widgets.c | 12 +++++++----- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 272bf9d8..00ea63da 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1953,6 +1953,14 @@ rd_expr_from_cfg(RD_Cfg *cfg) return result; } +internal String8 +rd_view_rule_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *view_rule = rd_cfg_child_from_string(cfg, str8_lit("view_rule")); + String8 result = view_rule->first->string; + return result; +} + internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) { @@ -2088,12 +2096,12 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 //- rjf: push label if(label_string.size != 0) { - dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } - //- rjf: push expression + //- rjf: push collection name if(collection_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, collection_name); @@ -2199,7 +2207,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 //- rjf: cfg has expression attached -> use that else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) { - dr_fstrs_push_new(arena, &result, ¶ms, expr_string); + dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); start_secondary(); } @@ -2233,7 +2241,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; if(condition.size != 0) { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); RD_Font(RD_FontSlot_Code) { DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); @@ -6962,7 +6970,8 @@ rd_window_frame(void) } // rjf: evaluate hover-evaluation expression - if it doesn't evaluate, then don't build anything - E_Eval hover_eval = e_eval_from_string(scratch.arena, ws->hover_eval_string); + String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); if(hover_eval.msgs.max_kind > E_MsgKind_Null) { build_hover_eval = 0; @@ -7003,7 +7012,7 @@ rd_window_frame(void) rd_cfg_new(explicit_root, str8_lit("1")); RD_RegsScope(.view = view->id) { - rd_cfg_new_replace(expr, ws->hover_eval_string); + rd_cfg_new_replace(expr, hover_eval_expr); EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); @@ -9471,7 +9480,7 @@ rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, //~ rjf: Hover Eval internal void -rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string) +rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string, String8 view_rules) { RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); @@ -9480,12 +9489,14 @@ rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 s ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero())) { - B32 is_new_string = !str8_match(ws->hover_eval_string, string, 0); + B32 is_new_string = (!str8_match(ws->hover_eval_string, string, 0) || + !str8_match(ws->hover_eval_view_rules, view_rules, 0)); if(is_new_string) { ws->hover_eval_first_frame_idx = ws->hover_eval_last_frame_idx = rd_state->frame_index; arena_clear(ws->hover_eval_arena); ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); + ws->hover_eval_view_rules = push_str8_copy(ws->hover_eval_arena, view_rules); ws->hover_eval_file_path = push_str8_copy(ws->hover_eval_arena, file_path); ws->hover_eval_file_pt = pt; ws->hover_eval_vaddr = vaddr; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 484c74b0..7a06a6c0 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -589,6 +589,7 @@ struct RD_WindowState Arena *hover_eval_arena; Vec2F32 hover_eval_spawn_pos; String8 hover_eval_string; + String8 hover_eval_view_rules; U64 hover_eval_first_frame_idx; U64 hover_eval_last_frame_idx; String8 hover_eval_file_path; @@ -977,6 +978,7 @@ internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); +internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); @@ -1102,7 +1104,7 @@ internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U //////////////////////////////// //~ rjf: Hover Eval -internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string); +internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string, String8 view_rules); //////////////////////////////// //~ rjf: Lister Functions diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2add2b9f..8aea3796 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -792,7 +792,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle)); + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) @@ -939,7 +939,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle)); + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) @@ -1016,7 +1016,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", bp->id)); + rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", bp->id), str8_zero()); RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1078,6 +1078,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", pin->id), str8_zero()); RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1285,6 +1286,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_Cfg *pin = n->v; String8 pin_expr = rd_expr_from_cfg(pin); + String8 pin_view_rule = rd_view_rule_from_cfg(pin); E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.type_key)) @@ -1332,7 +1334,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal pin_sig = ui_signal_from_box(pin_box); if(ui_key_match(pin_box_key, ui_hot_key())) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(1, 1), 0, pin_expr); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(1, 1), 0, pin_expr, pin_view_rule); } } } @@ -1627,7 +1629,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_idx = mouse_pt.line-params->line_num_range.min; line_vaddr = params->line_vaddrs[line_idx]; } - rd_set_hover_eval(mouse_expr_baseline_pos, rd_regs()->file_path, mouse_pt, line_vaddr, mouse_expr); + rd_set_hover_eval(mouse_expr_baseline_pos, rd_regs()->file_path, mouse_pt, line_vaddr, mouse_expr, str8_zero()); } } From 72869bc73bbf72bb02ed7d657afd22f61ddb9119 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 12:05:51 -0800 Subject: [PATCH 131/755] simplify name alloctors in rd/ctrl layers; port panel-closure path --- src/ctrl/ctrl_core.c | 127 ++++---- src/ctrl/ctrl_core.h | 16 +- .../eval_visualization_core.c | 8 + src/raddbg/raddbg_core.c | 301 +++++++++--------- src/raddbg/raddbg_core.h | 16 +- src/ui/ui_core.c | 4 + src/ui/ui_core.h | 1 + 7 files changed, 263 insertions(+), 210 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 2c0d0086..5104d4f1 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -650,95 +650,100 @@ ctrl_entity_store_release(CTRL_EntityStore *cache) //- rjf: string allocation/deletion internal U64 -ctrl_name_bucket_idx_from_string_size(U64 size) +ctrl_name_bucket_num_from_string_size(U64 size) { - U64 size_rounded = u64_up_to_pow2(size+1); - size_rounded = ClampBot((1<<4), size_rounded); - U64 bucket_idx = 0; - switch(size_rounded) + U64 bucket_num = 0; + if(size > 0) { - case 1<<4: {bucket_idx = 0;}break; - case 1<<5: {bucket_idx = 1;}break; - case 1<<6: {bucket_idx = 2;}break; - case 1<<7: {bucket_idx = 3;}break; - case 1<<8: {bucket_idx = 4;}break; - case 1<<9: {bucket_idx = 5;}break; - case 1<<10:{bucket_idx = 6;}break; - default:{bucket_idx = ArrayCount(((CTRL_EntityStore *)0)->free_string_chunks)-1;}break; + for EachElement(idx, ctrl_entity_string_bucket_chunk_sizes) + { + if(size <= ctrl_entity_string_bucket_chunk_sizes[idx]) + { + bucket_num = idx+1; + break; + } + } } - return bucket_idx; + return bucket_num; } internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string) { - if(string.size == 0) {return str8_zero();} - U64 bucket_idx = ctrl_name_bucket_idx_from_string_size(string.size); - CTRL_EntityStringChunkNode *node = store->free_string_chunks[bucket_idx]; - - // rjf: pull from bucket free list - if(node != 0) + //- rjf: allocate node + CTRL_EntityStringChunkNode *node = 0; { - if(bucket_idx == ArrayCount(store->free_string_chunks)-1) + U64 bucket_num = ctrl_name_bucket_num_from_string_size(string.size); + if(bucket_num == ArrayCount(ctrl_entity_string_bucket_chunk_sizes)) { - node = 0; - CTRL_EntityStringChunkNode *prev = 0; - for(CTRL_EntityStringChunkNode *n = store->free_string_chunks[bucket_idx]; - n != 0; - prev = n, n = n->next) + CTRL_EntityStringChunkNode *best_node = 0; + CTRL_EntityStringChunkNode *best_node_prev = 0; + U64 best_node_size = max_U64; { - if(n->size >= string.size) + for(CTRL_EntityStringChunkNode *n = store->free_string_chunks[bucket_num-1], *prev = 0; n != 0; (prev = n, n = n->next)) { - if(prev == 0) + if(n->size >= string.size && n->size < best_node_size) { - store->free_string_chunks[bucket_idx] = n->next; + best_node = n; + best_node_prev = prev; + best_node_size = n->size; } - else - { - prev->next = n->next; - } - node = n; - break; } } + if(best_node != 0) + { + node = best_node; + if(best_node_prev) + { + best_node_prev->next = best_node->next; + } + else + { + store->free_string_chunks[bucket_num-1] = best_node->next; + } + } + else + { + U64 chunk_size = u64_up_to_pow2(string.size); + node = (CTRL_EntityStringChunkNode *)push_array(store->arena, U8, chunk_size); + } } - else + else if(bucket_num != 0) { - SLLStackPop(store->free_string_chunks[bucket_idx]); + node = store->free_string_chunks[bucket_num-1]; + if(node != 0) + { + SLLStackPop(store->free_string_chunks[bucket_num-1]); + } + else + { + node = (CTRL_EntityStringChunkNode *)push_array(store->arena, U8, ctrl_entity_string_bucket_chunk_sizes[bucket_num-1]); + } } } - // rjf: no found node -> allocate new - if(node == 0) + //- rjf: fill node + String8 result = {0}; + if(node != 0) { - U64 chunk_size = 0; - if(bucket_idx < ArrayCount(store->free_string_chunks)-1) - { - chunk_size = 1<<(bucket_idx+4); - } - else - { - chunk_size = u64_up_to_pow2(string.size); - } - U8 *chunk_memory = push_array(store->arena, U8, chunk_size); - node = (CTRL_EntityStringChunkNode *)chunk_memory; - node->size = chunk_size; + result.str = (U8 *)node; + result.size = string.size; + MemoryCopy(result.str, string.str, result.size); } - - // rjf: fill string & return - String8 allocated_string = str8((U8 *)node, string.size); - MemoryCopy((U8 *)node, string.str, string.size); - return allocated_string; + return result; } internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string) { - if(string.size == 0) {return;} - U64 bucket_idx = ctrl_name_bucket_idx_from_string_size(string.size); - CTRL_EntityStringChunkNode *node = (CTRL_EntityStringChunkNode *)string.str; - node->size = u64_up_to_pow2(string.size); - SLLStackPush(store->free_string_chunks[bucket_idx], node); + U64 bucket_num = ctrl_name_bucket_num_from_string_size(string.size); + if(1 <= bucket_num && bucket_num <= ArrayCount(rd_name_bucket_chunk_sizes)) + { + U64 bucket_idx = bucket_num-1; + CTRL_EntityStringChunkNode *node = (CTRL_EntityStringChunkNode *)string.str; + SLLStackPush(store->free_string_chunks[bucket_idx], node); + node->size = u64_up_to_pow2(string.size); + } } //- rjf: entity construction/deletion diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 024304aa..c21f5394 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -117,6 +117,18 @@ struct CTRL_EntityStringChunkNode U64 size; }; +read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] = +{ + 16, + 64, + 256, + 1024, + 4096, + 16384, + 65536, + 0xffffffffffffffffull, +}; + typedef struct CTRL_EntityStore CTRL_EntityStore; struct CTRL_EntityStore { @@ -126,7 +138,7 @@ struct CTRL_EntityStore CTRL_EntityHashSlot *hash_slots; CTRL_EntityHashNode *hash_node_free; U64 hash_slots_count; - CTRL_EntityStringChunkNode *free_string_chunks[8]; + CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)]; U64 entity_kind_counts[CTRL_EntityKind_COUNT]; Arena *entity_kind_lists_arenas[CTRL_EntityKind_COUNT]; U64 entity_kind_lists_gens[CTRL_EntityKind_COUNT]; @@ -782,7 +794,7 @@ internal CTRL_EntityStore *ctrl_entity_store_alloc(void); internal void ctrl_entity_store_release(CTRL_EntityStore *store); //- rjf: string allocation/deletion -internal U64 ctrl_name_bucket_idx_from_string_size(U64 size); +internal U64 ctrl_name_bucket_num_from_string_size(U64 size); internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string); internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 4ac042e4..ed8ad052 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -99,6 +99,14 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { result = 1; } + if(kind == E_TypeKind_Ptr) + { + E_Type *type = e_type_from_key__cached(t); + if(type->count > 1) + { + result = 1; + } + } } return result; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 00ea63da..5f05025e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1028,109 +1028,100 @@ rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot) //~ rjf: Name Allocation internal U64 -rd_name_bucket_idx_from_string_size(U64 size) +rd_name_bucket_num_from_string_size(U64 size) { - U64 size_rounded = u64_up_to_pow2(size+1); - size_rounded = ClampBot((1<<4), size_rounded); - U64 bucket_idx = 0; - switch(size_rounded) + U64 bucket_num = 0; + if(size > 0) { - case 1<<4: {bucket_idx = 0;}break; - case 1<<5: {bucket_idx = 1;}break; - case 1<<6: {bucket_idx = 2;}break; - case 1<<7: {bucket_idx = 3;}break; - case 1<<8: {bucket_idx = 4;}break; - case 1<<9: {bucket_idx = 5;}break; - case 1<<10:{bucket_idx = 6;}break; - default:{bucket_idx = ArrayCount(rd_state->free_name_chunks)-1;}break; + for EachElement(idx, rd_name_bucket_chunk_sizes) + { + if(size <= rd_name_bucket_chunk_sizes[idx]) + { + bucket_num = idx+1; + break; + } + } } - return bucket_idx; + return bucket_num; } internal String8 rd_name_alloc(String8 string) { - if(string.size == 0) {return str8_zero();} - U64 bucket_idx = rd_name_bucket_idx_from_string_size(string.size); - - // rjf: loop -> find node, allocate if not there - // - // (we do a loop here so that all allocation logic goes through - // the same path, such that we *always* pull off a free list, - // rather than just using what was pushed onto an arena directly, - // which is not undoable; the free lists we control, and are thus - // trivially undoable) - // + //- rjf: allocate node RD_NameChunkNode *node = 0; - for(;node == 0;) { - node = rd_state->free_name_chunks[bucket_idx]; - - // rjf: pull from bucket free list - if(node != 0) + U64 bucket_num = rd_name_bucket_num_from_string_size(string.size); + if(bucket_num == ArrayCount(rd_name_bucket_chunk_sizes)) { - if(bucket_idx == ArrayCount(rd_state->free_name_chunks)-1) + RD_NameChunkNode *best_node = 0; + RD_NameChunkNode *best_node_prev = 0; + U64 best_node_size = max_U64; { - node = 0; - RD_NameChunkNode *prev = 0; - for(RD_NameChunkNode *n = rd_state->free_name_chunks[bucket_idx]; - n != 0; - prev = n, n = n->next) + for(RD_NameChunkNode *n = rd_state->free_name_chunks[bucket_num-1], *prev = 0; n != 0; (prev = n, n = n->next)) { - if(n->size >= string.size) + if(n->size >= string.size && n->size < best_node_size) { - if(prev == 0) - { - rd_state->free_name_chunks[bucket_idx] = n->next; - } - else - { - prev->next = n->next; - } - node = n; - break; + best_node = n; + best_node_prev = prev; + best_node_size = n->size; } } } + if(best_node != 0) + { + node = best_node; + if(best_node_prev) + { + best_node_prev->next = best_node->next; + } + else + { + rd_state->free_name_chunks[bucket_num-1] = best_node->next; + } + } else { - SLLStackPop(rd_state->free_name_chunks[bucket_idx]); + U64 chunk_size = u64_up_to_pow2(string.size); + node = (RD_NameChunkNode *)push_array(rd_state->arena, U8, chunk_size); } } - - // rjf: no found node -> allocate new, push onto associated free list - if(node == 0) + else if(bucket_num != 0) { - U64 chunk_size = 0; - if(bucket_idx < ArrayCount(rd_state->free_name_chunks)-1) + node = rd_state->free_name_chunks[bucket_num-1]; + if(node != 0) { - chunk_size = 1<<(bucket_idx+4); + SLLStackPop(rd_state->free_name_chunks[bucket_num-1]); } else { - chunk_size = u64_up_to_pow2(string.size); + node = (RD_NameChunkNode *)push_array(rd_state->arena, U8, rd_name_bucket_chunk_sizes[bucket_num-1]); } - U8 *chunk_memory = push_array(rd_state->arena, U8, chunk_size); - RD_NameChunkNode *chunk = (RD_NameChunkNode *)chunk_memory; - chunk->size = chunk_size; - SLLStackPush(rd_state->free_name_chunks[bucket_idx], chunk); } } - // rjf: fill string & return - String8 allocated_string = str8((U8 *)node, string.size); - MemoryCopy((U8 *)node, string.str, string.size); - return allocated_string; + //- rjf: fill node + String8 result = {0}; + if(node != 0) + { + result.str = (U8 *)node; + result.size = string.size; + MemoryCopy(result.str, string.str, result.size); + } + return result; } internal void rd_name_release(String8 string) { - if(string.size == 0) {return;} - U64 bucket_idx = rd_name_bucket_idx_from_string_size(string.size); - RD_NameChunkNode *node = (RD_NameChunkNode *)string.str; - node->size = u64_up_to_pow2(string.size); - SLLStackPush(rd_state->free_name_chunks[bucket_idx], node); + U64 bucket_num = rd_name_bucket_num_from_string_size(string.size); + if(1 <= bucket_num && bucket_num <= ArrayCount(rd_name_bucket_chunk_sizes)) + { + U64 bucket_idx = bucket_num-1; + RD_NameChunkNode *node = (RD_NameChunkNode *)string.str; + SLLStackPush(rd_state->free_name_chunks[bucket_idx], node); + node->size = u64_up_to_pow2(string.size); + } } //////////////////////////////// @@ -1323,10 +1314,7 @@ rd_cfg_deep_copy(RD_Cfg *src_root) internal void rd_cfg_equip_string(RD_Cfg *cfg, String8 string) { - if(cfg->string.size != 0) - { - rd_name_release(cfg->string); - } + rd_name_release(cfg->string); cfg->string = rd_name_alloc(string); } @@ -7517,40 +7505,27 @@ rd_window_frame(void) //////////////////////////// //- rjf: animate panels // -#if 0 // TODO(rjf): @cfg_panels { - F32 rate = rd_setting_val_from_code(RD_SettingCode_MenuAnimations).s32 ? 1 - pow_f32(2, (-50.f * rd_state->frame_dt)) : 1.f; Vec2F32 content_rect_dim = dim_2f32(content_rect); if(content_rect_dim.x > 0 && content_rect_dim.y > 0) { for(RD_PanelNode *panel = panel_tree.root; panel != &rd_nil_panel_node; - panel = rd_panel_node_rec__depth_first_pre(panel).next) + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0/content_rect_dim.x, target_rect_px.y0/content_rect_dim.y, target_rect_px.x1/content_rect_dim.x, target_rect_px.y1/content_rect_dim.y); - if(abs_f32(target_rect_pct.x0 - panel->animated_rect_pct.x0) > 0.005f || - abs_f32(target_rect_pct.y0 - panel->animated_rect_pct.y0) > 0.005f || - abs_f32(target_rect_pct.x1 - panel->animated_rect_pct.x1) > 0.005f || - abs_f32(target_rect_pct.y1 - panel->animated_rect_pct.y1) > 0.005f) - { - rd_request_frame(); - } - panel->animated_rect_pct.x0 += rate * (target_rect_pct.x0 - panel->animated_rect_pct.x0); - panel->animated_rect_pct.y0 += rate * (target_rect_pct.y0 - panel->animated_rect_pct.y0); - panel->animated_rect_pct.x1 += rate * (target_rect_pct.x1 - panel->animated_rect_pct.x1); - panel->animated_rect_pct.y1 += rate * (target_rect_pct.y1 - panel->animated_rect_pct.y1); - if(ws->frames_alive < 5 || is_changing_panel_boundaries) - { - panel->animated_rect_pct = target_rect_pct; - } + B32 reset = (ws->frames_alive < 5 || is_changing_panel_boundaries); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset); } } } -#endif //////////////////////////// //- rjf: panel leaf UI @@ -7582,8 +7557,10 @@ rd_window_frame(void) target_rect_px.y0 / content_rect_dim.y, target_rect_px.x1 / content_rect_dim.x, target_rect_px.y1 / content_rect_dim.y); - // TODO(rjf): @cfg_panels animate `target_rect_pct` - Rng2F32 panel_rect_pct = target_rect_pct; + Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1)); Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, panel_rect_pct.y0*content_rect_dim.y, panel_rect_pct.x1*content_rect_dim.x, @@ -13077,6 +13054,10 @@ rd_frame(void) // rjf: unpack Axis2 split_axis = axis2_from_dir2(split_dir); Side split_side = side_from_dir2(split_dir); + if(split_panel == &rd_nil_cfg) + { + split_panel = rd_cfg_from_id(rd_regs()->panel); + } RD_Cfg *new_panel_cfg = &rd_nil_cfg; RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, split_panel); RD_PanelNode *panel_root = panel_tree.root; @@ -13090,7 +13071,7 @@ rd_frame(void) RD_Cfg *panel_cfg = panel->cfg; RD_Cfg *new_cfg = rd_cfg_alloc(); rd_cfg_insert_child(parent_cfg, split_side == Side_Max ? panel_cfg : panel_cfg->prev, new_cfg); - rd_cfg_equip_stringf(new_cfg, "%f", 1.f/parent->child_count); + rd_cfg_equip_stringf(new_cfg, "%f", 1.f/(parent->child_count+1)); for(RD_PanelNode *child = parent->first; child != &rd_nil_panel_node; child = child->next) { F32 old_pct = child->pct_of_parent; @@ -13159,10 +13140,22 @@ rd_frame(void) rd_cfg_insert_child(new_panel_cfg, new_panel_cfg->last, dragdrop_tab); RD_PanelTree origin_panel_tree = rd_panel_tree_from_cfg(scratch.arena, dragdrop_origin_panel_cfg); RD_PanelNode *origin_panel = rd_panel_node_from_tree_cfg(origin_panel_tree.root, dragdrop_origin_panel_cfg); + if(origin_panel->selected_tab == &rd_nil_cfg) + { + for(RD_CfgNode *n = origin_panel->tabs.first; n != 0; n = n->next) + { + if(!rd_cfg_is_project_filtered(n->v)) + { + rd_cmd(RD_CmdKind_FocusTab, .panel = origin_panel->cfg->id, .view = n->v->id); + break; + } + } + } if(origin_panel->tabs.count == 0) { rd_cmd(RD_CmdKind_ClosePanel); } + rd_cmd(RD_CmdKind_FocusTab, .panel = new_panel_cfg->id, .view = dragdrop_tab->id); } // rjf: focus new panel @@ -13206,7 +13199,7 @@ rd_frame(void) p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) { - if(p->first == &rd_nil_panel_node) + if(p != panel_tree.focused && p->first == &rd_nil_panel_node) { next_focused = p; break; @@ -13218,9 +13211,10 @@ rd_frame(void) p != &rd_nil_panel_node; p = rd_panel_node_rec__depth_first(panel_tree.root, p, panel_sib_off, panel_child_off).next) { - if(p->first == &rd_nil_panel_node) + if(p != panel_tree.focused && p->first == &rd_nil_panel_node) { next_focused = p; + break; } } } @@ -13395,11 +13389,11 @@ rd_frame(void) //- rjf: panel removal case RD_CmdKind_ClosePanel: { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_Panel *parent = panel->parent; - if(!rd_panel_is_nil(parent)) + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, rd_cfg_from_id(rd_regs()->panel)); + RD_PanelNode *parent = panel->parent; + if(parent != &rd_nil_panel_node) { Axis2 split_axis = parent->split_axis; @@ -13407,88 +13401,105 @@ rd_frame(void) // we should just remove both children. if(parent->child_count == 2) { - RD_Panel *discard_child = panel; - RD_Panel *keep_child = panel == parent->first ? parent->last : parent->first; - RD_Panel *grandparent = parent->parent; - RD_Panel *parent_prev = parent->prev; + RD_PanelNode *discard_child = panel; + RD_PanelNode *keep_child = (panel == parent->first ? parent->last : parent->first); + RD_PanelNode *grandparent = parent->parent; + RD_PanelNode *parent_prev = parent->prev; F32 pct_of_parent = parent->pct_of_parent; // rjf: unhook kept child - rd_panel_remove(parent, keep_child); + rd_cfg_unhook(parent->cfg, keep_child->cfg); // rjf: unhook this subtree - if(!rd_panel_is_nil(grandparent)) + if(grandparent != &rd_nil_panel_node) { - rd_panel_remove(grandparent, parent); + rd_cfg_unhook(grandparent->cfg, parent->cfg); } - // rjf: release the things we should discard + // rjf: release the containing tree { - rd_panel_release(ws, parent); - rd_panel_release(ws, discard_child); + rd_cfg_release(parent->cfg); } // rjf: re-hook our kept child into the overall tree - if(rd_panel_is_nil(grandparent)) + if(grandparent == &rd_nil_panel_node) { - ws->root_panel = keep_child; + rd_cfg_equip_string(keep_child->cfg, str8_lit("panels")); + rd_cfg_insert_child(window, window->last, keep_child->cfg); } else { - rd_panel_insert(grandparent, parent_prev, keep_child); - } - keep_child->pct_of_parent = pct_of_parent; - - // rjf: reset focus, if needed - if(ws->focused_panel == discard_child) - { - ws->focused_panel = keep_child; - for(RD_Panel *grandchild = ws->focused_panel; !rd_panel_is_nil(grandchild); grandchild = grandchild->first) - { - ws->focused_panel = grandchild; - } + rd_cfg_insert_child(grandparent->cfg, parent_prev->cfg, keep_child->cfg); + rd_cfg_equip_stringf(keep_child->cfg, "%f", pct_of_parent); } // rjf: keep-child split-axis == grandparent split-axis? bubble keep-child up into grandparent's children - if(!rd_panel_is_nil(grandparent) && grandparent->split_axis == keep_child->split_axis && !rd_panel_is_nil(keep_child->first)) + if(grandparent != &rd_nil_panel_node && grandparent->split_axis == keep_child->split_axis && keep_child->first != &rd_nil_panel_node) { - rd_panel_remove(grandparent, keep_child); - RD_Panel *prev = parent_prev; - for(RD_Panel *child = keep_child->first, *next = 0; !rd_panel_is_nil(child); child = next) + rd_cfg_unhook(grandparent->cfg, keep_child->cfg); + RD_PanelNode *prev = parent_prev; + for(RD_PanelNode *child = keep_child->first, *next = &rd_nil_panel_node; child != &rd_nil_panel_node; child = next) { next = child->next; - rd_panel_remove(keep_child, child); - rd_panel_insert(grandparent, prev, child); + rd_cfg_unhook(keep_child->cfg, child->cfg); + rd_cfg_insert_child(grandparent->cfg, prev->cfg, child->cfg); prev = child; - child->pct_of_parent *= keep_child->pct_of_parent; + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct * keep_child->pct_of_parent; + rd_cfg_equip_stringf(child->cfg, "%f", new_pct); } - rd_panel_release(ws, keep_child); + rd_cfg_release(keep_child->cfg); + } + + // rjf: reset focus, if needed + if(panel_tree.focused == discard_child) + { + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_focused = rd_panel_node_from_tree_cfg(panel_tree.root, keep_child->cfg); + for(RD_PanelNode *grandchild = new_focused; grandchild != &rd_nil_panel_node; grandchild = grandchild->first) + { + new_focused = grandchild; + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_focused->cfg->id); } } // NOTE(rjf): Otherwise we can just remove this child. else { - RD_Panel *next = &rd_nil_panel; + // rjf: remove + RD_PanelNode *next = &rd_nil_panel_node; F32 removed_size_pct = panel->pct_of_parent; - if(rd_panel_is_nil(next)) { next = panel->prev; } - if(rd_panel_is_nil(next)) { next = panel->next; } - rd_panel_remove(parent, panel); - rd_panel_release(ws, panel); - if(ws->focused_panel == panel) + if(next == &rd_nil_panel_node) { next = panel->prev; } + if(next == &rd_nil_panel_node) { next = panel->next; } + rd_cfg_unhook(parent->cfg, panel->cfg); + rd_cfg_release(panel->cfg); + + // rjf: resize siblings to this node { - ws->focused_panel = next; - for(RD_Panel *grandchild = ws->focused_panel; !rd_panel_is_nil(grandchild); grandchild = grandchild->first) + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_parent = rd_panel_node_from_tree_cfg(new_panel_tree.root, parent->cfg); + for(RD_PanelNode *child = new_parent->first; child != &rd_nil_panel_node; child = child->next) { - ws->focused_panel = grandchild; + RD_Cfg *cfg = child->cfg; + F32 old_pct = child->pct_of_parent; + F32 new_pct = old_pct / (1.f-removed_size_pct); + rd_cfg_equip_stringf(cfg, "%f", new_pct); } } - for(RD_Panel *child = parent->first; !rd_panel_is_nil(child); child = child->next) + + // rjf: reset focus, if needed + if(panel_tree.focused == panel) { - child->pct_of_parent /= 1.f-removed_size_pct; + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *new_focused = rd_panel_node_from_tree_cfg(panel_tree.root, next->cfg); + for(RD_PanelNode *grandchild = new_focused; grandchild != &rd_nil_panel_node; grandchild = grandchild->first) + { + new_focused = grandchild; + } + rd_cmd(RD_CmdKind_FocusPanel, .panel = new_focused->cfg->id); } } } -#endif }break; //- rjf: panel tab controls diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7a06a6c0..bbe2f41a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -670,6 +670,18 @@ struct RD_Entity2EvalBlobMap //////////////////////////////// //~ rjf: Main Per-Process Graphical State +read_only global U64 rd_name_bucket_chunk_sizes[] = +{ + 16, + 64, + 256, + 1024, + 4096, + 16384, + 65536, + 0xffffffffffffffffull, +}; + typedef struct RD_NameChunkNode RD_NameChunkNode; struct RD_NameChunkNode { @@ -796,7 +808,7 @@ struct RD_State RD_DragDropState drag_drop_state; // rjf: cfg state - RD_NameChunkNode *free_name_chunks[8]; + RD_NameChunkNode *free_name_chunks[ArrayCount(rd_name_bucket_chunk_sizes)]; RD_Cfg *free_cfg; RD_Cfg *root_cfg; U64 cfg_id_slots_count; @@ -926,7 +938,7 @@ internal void rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD //////////////////////////////// //~ rjf: Name Allocation -internal U64 rd_name_bucket_idx_from_string_size(U64 size); +internal U64 rd_name_bucket_num_from_string_size(U64 size); internal String8 rd_name_alloc(String8 string); internal void rd_name_release(String8 string); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 15cd4167..44f08e2b 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -3008,6 +3008,10 @@ ui_anim_(UI_Key key, UI_AnimParams *params) // rjf: touch node & update parameters - grab current node->last_touched_build_index = ui_state->build_index; DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); + if(params->reset) + { + node->current = params->initial; + } MemoryCopyStruct(&node->params, params); if(node->params.epsilon == 0) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 7ec57ded..c2878f75 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -582,6 +582,7 @@ struct UI_AnimParams F32 target; F32 rate; F32 epsilon; + B32 reset; }; typedef struct UI_AnimNode UI_AnimNode; From 40d762756b3e7b1c76fb23a916d95e1b726db6a7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 13:25:06 -0800 Subject: [PATCH 132/755] more convergence on panel creation/removal paths --- src/raddbg/raddbg_core.c | 68 ++++++++++++++++++++++++++++++---------- src/ui/ui_core.c | 32 ++++++++++--------- 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5f05025e..755bf652 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13113,21 +13113,55 @@ rd_frame(void) } // rjf: pre-emptively set up the animation rectangle, depending on where - // the new panel was inserted (?) -#if 0 // TODO(rjf): @cfg - if(!rd_panel_is_nil(new_panel->prev)) + // the new panel was inserted { - Rng2F32 prev_rect_pct = new_panel->prev->animated_rect_pct; - new_panel->animated_rect_pct = prev_rect_pct; - new_panel->animated_rect_pct.p0.v[split_axis] = new_panel->animated_rect_pct.p1.v[split_axis]; + RD_WindowState *ws = rd_window_state_from_cfg(new_panel_cfg); + if(ws != &rd_nil_window_state) + { + ui_select_state(ws->ui); + RD_PanelTree new_panel_tree = rd_panel_tree_from_cfg(scratch.arena, new_panel_cfg); + RD_PanelNode *new_panel = rd_panel_node_from_tree_cfg(new_panel_tree.root, new_panel_cfg); + Rng2F32 stub_content_rect = r2f32p(0, 0, 1000, 1000); + Vec2F32 stub_content_rect_dim = dim_2f32(stub_content_rect); + Rng2F32 new_rect_px = rd_target_rect_from_panel_node(stub_content_rect, new_panel_tree.root, new_panel); + Rng2F32 new_rect_pct = r2f32p(new_rect_px.x0/stub_content_rect_dim.x, + new_rect_px.y0/stub_content_rect_dim.y, + new_rect_px.x1/stub_content_rect_dim.x, + new_rect_px.y1/stub_content_rect_dim.y); + if(new_panel->prev != &rd_nil_panel_node) + { + Rng2F32 target_prev_rect_px = rd_target_rect_from_panel_node(stub_content_rect, panel_tree.root, rd_panel_node_from_tree_cfg(panel_tree.root, new_panel->prev->cfg)); + Rng2F32 target_prev_rect_pct = r2f32p(target_prev_rect_px.x0/stub_content_rect_dim.x, + target_prev_rect_px.y0/stub_content_rect_dim.y, + target_prev_rect_px.x1/stub_content_rect_dim.x, + target_prev_rect_px.y1/stub_content_rect_dim.y); + Rng2F32 prev_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->prev->cfg), target_prev_rect_pct.x0, .initial = target_prev_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->prev->cfg), target_prev_rect_pct.y0, .initial = target_prev_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->prev->cfg), target_prev_rect_pct.x1, .initial = target_prev_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->prev->cfg), target_prev_rect_pct.y1, .initial = target_prev_rect_pct.y1)); + new_rect_pct = prev_rect_pct; + new_rect_pct.p0.v[split_axis] = new_rect_pct.p1.v[split_axis]; + } + if(new_panel->next != &rd_nil_panel_node) + { + Rng2F32 target_next_rect_px = rd_target_rect_from_panel_node(stub_content_rect, panel_tree.root, rd_panel_node_from_tree_cfg(panel_tree.root, new_panel->next->cfg)); + Rng2F32 target_next_rect_pct = r2f32p(target_next_rect_px.x0/stub_content_rect_dim.x, + target_next_rect_px.y0/stub_content_rect_dim.y, + target_next_rect_px.x1/stub_content_rect_dim.x, + target_next_rect_px.y1/stub_content_rect_dim.y); + Rng2F32 next_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->next->cfg), target_next_rect_pct.x0, .initial = target_next_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->next->cfg), target_next_rect_pct.y0, .initial = target_next_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->next->cfg), target_next_rect_pct.x1, .initial = target_next_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->next->cfg), target_next_rect_pct.y1, .initial = target_next_rect_pct.y1)); + new_rect_pct = next_rect_pct; + new_rect_pct.p1.v[split_axis] = new_rect_pct.p0.v[split_axis]; + } + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->cfg), new_rect_pct.x0, .initial = new_rect_pct.x0, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->cfg), new_rect_pct.x1, .initial = new_rect_pct.x1, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->cfg), new_rect_pct.y0, .initial = new_rect_pct.y0, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->cfg), new_rect_pct.y1, .initial = new_rect_pct.y1, .reset = 1); + } } - if(!rd_panel_is_nil(new_panel->next)) - { - Rng2F32 next_rect_pct = new_panel->next->animated_rect_pct; - new_panel->animated_rect_pct = next_rect_pct; - new_panel->animated_rect_pct.p1.v[split_axis] = new_panel->animated_rect_pct.p0.v[split_axis]; - } -#endif // rjf: if this split was caused by drag/dropping a tab, and the originating panel // has no further tabs, then close the originating panel @@ -13437,15 +13471,15 @@ rd_frame(void) if(grandparent != &rd_nil_panel_node && grandparent->split_axis == keep_child->split_axis && keep_child->first != &rd_nil_panel_node) { rd_cfg_unhook(grandparent->cfg, keep_child->cfg); - RD_PanelNode *prev = parent_prev; + RD_Cfg *prev = parent_prev->cfg; for(RD_PanelNode *child = keep_child->first, *next = &rd_nil_panel_node; child != &rd_nil_panel_node; child = next) { next = child->next; rd_cfg_unhook(keep_child->cfg, child->cfg); - rd_cfg_insert_child(grandparent->cfg, prev->cfg, child->cfg); - prev = child; + rd_cfg_insert_child(grandparent->cfg, prev, child->cfg); + prev = child->cfg; F32 old_pct = child->pct_of_parent; - F32 new_pct = old_pct * keep_child->pct_of_parent; + F32 new_pct = old_pct * pct_of_parent; rd_cfg_equip_stringf(child->cfg, "%f", new_pct); } rd_cfg_release(keep_child->cfg); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 44f08e2b..b3ab2322 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -804,7 +804,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U for(UI_AnimNode *n = ui_state->lru_anim_node, *next = &ui_nil_anim_node; n != &ui_nil_anim_node && n != 0; n = next) { next = n->lru_next; - if(n->last_touched_build_index+1 < ui_state->build_index) + if(n->last_touched_build_index+2 < ui_state->build_index) { U64 slot_idx = n->key.u64[0]%ui_state->anim_slots_count; UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx]; @@ -2971,6 +2971,7 @@ ui_anim_(UI_Key key, UI_AnimParams *params) { // rjf: get animation cache node UI_AnimNode *node = &ui_nil_anim_node; + if(ui_state != 0) { U64 slot_idx = key.u64[0]%ui_state->anim_slots_count; UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx]; @@ -3006,20 +3007,23 @@ ui_anim_(UI_Key key, UI_AnimParams *params) } // rjf: touch node & update parameters - grab current - node->last_touched_build_index = ui_state->build_index; - DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); - if(params->reset) + if(node != &ui_nil_anim_node) { - node->current = params->initial; - } - MemoryCopyStruct(&node->params, params); - if(node->params.epsilon == 0) - { - node->params.epsilon = 0.01f; - } - if(node->params.rate == 1) - { - node->current = node->params.target; + node->last_touched_build_index = ui_state->build_index; + DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); + if(params->reset) + { + node->current = params->initial; + } + MemoryCopyStruct(&node->params, params); + if(node->params.epsilon == 0) + { + node->params.epsilon = 0.01f; + } + if(node->params.rate == 1) + { + node->current = node->params.target; + } } return node->current; } From 36798def1bedbcc32a32d7208ccca5e1caa162f2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 16:03:05 -0800 Subject: [PATCH 133/755] convergence & cleanup & simplification & fixes of tab drag/drop, panel rearranging --- src/draw/draw.c | 10 + src/draw/draw.h | 1 + src/raddbg/raddbg_core.c | 734 +++++++++++++++++++-------------------- src/raddbg/raddbg_core.h | 1 + src/ui/ui_core.c | 18 +- src/ui/ui_core.h | 1 + 6 files changed, 394 insertions(+), 371 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index 152a75c5..e9fc8627 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -153,6 +153,16 @@ dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) return run_list; } +internal Vec2F32 +dr_dim_from_fstrs(DR_FStrList *fstrs) +{ + Temp scratch = scratch_begin(0, 0); + DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, 0, fstrs); + Vec2F32 dim = fruns.dim; + scratch_end(scratch); + return dim; +} + //////////////////////////////// //~ rjf: Top-Level API // diff --git a/src/draw/draw.h b/src/draw/draw.h index 4f0d26bb..67a24171 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -122,6 +122,7 @@ internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push); internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src); internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list); internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs); +internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs); //////////////////////////////// //~ rjf: Top-Level API diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 755bf652..90dc8c67 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4797,6 +4797,7 @@ rd_window_frame(void) UI_PrefHeight(main_height) UI_TextAlignment(main_text_align) { + ui_state->tooltip_can_overflow_window = 1; ui_set_next_pref_width(ui_em(60.f, 1.f)); ui_set_next_pref_height(ui_em(40.f, 1.f)); ui_set_next_child_layout_axis(Axis2_Y); @@ -7257,7 +7258,7 @@ rd_window_frame(void) F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); } UI_Box *site_box_viz = &ui_nil_box; @@ -7265,16 +7266,14 @@ rd_window_frame(void) UI_Padding(ui_px(padding, 1.f)) UI_Column UI_Padding(ui_px(padding, 1.f)) + UI_GroupKey(key) { ui_set_next_child_layout_axis(axis2_flip(axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); } UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) { @@ -7350,7 +7349,7 @@ rd_window_frame(void) F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); } UI_Box *site_box_viz = &ui_nil_box; @@ -7358,16 +7357,14 @@ rd_window_frame(void) UI_Padding(ui_px(padding, 1.f)) UI_Column UI_Padding(ui_px(padding, 1.f)) + UI_GroupKey(key) { ui_set_next_child_layout_axis(axis2_flip(split_axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); } UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) { @@ -7518,13 +7515,14 @@ rd_window_frame(void) target_rect_px.y0/content_rect_dim.y, target_rect_px.x1/content_rect_dim.x, target_rect_px.y1/content_rect_dim.y); - B32 reset = (ws->frames_alive < 5 || is_changing_panel_boundaries); + B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset); } } + ws->window_layout_reset = 0; } //////////////////////////// @@ -7598,6 +7596,8 @@ rd_window_frame(void) if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) { F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); + drop_site_dim_px = Min(drop_site_dim_px, dim_2f32(panel_rect).v[panel->split_axis]/4.f); + drop_site_dim_px = Max(drop_site_dim_px, ceil_f32(ui_top_font_size()*3.f)); Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); Vec2F32 panel_center = center_2f32(panel_rect); F32 corner_radius = ui_top_font_size()*0.5f; @@ -7666,24 +7666,22 @@ rd_window_frame(void) F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key); + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); } UI_Box *site_box_viz = &ui_nil_box; - UI_Parent(site_box) UI_WidthFill UI_HeightFill + UI_GroupKey(key) + UI_Parent(site_box) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) UI_Column UI_Padding(ui_px(padding, 1.f)) { ui_set_next_child_layout_axis(axis2_flip(split_axis)); - if(ui_key_match(key, ui_drop_hot_key())) - { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover))); - } site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur, ui_key_zero()); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); } if(dir != Dir2_Invalid) { @@ -7767,16 +7765,11 @@ rd_window_frame(void) ////////////////////////// //- rjf: build catch-all panel drop-site // - B32 catchall_drop_site_hovered = 0; - if(rd_drag_is_active() && ui_key_match(ui_key_zero(), ui_drop_hot_key())) + UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); + UI_Rect(panel_rect) { - UI_Rect(panel_rect) - { - UI_Key key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); - UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, key); - ui_signal_from_box(catchall_drop_site); - catchall_drop_site_hovered = ui_key_match(key, ui_drop_hot_key()); - } + UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); + ui_signal_from_box(catchall_drop_site); } ////////////////////////// @@ -8002,361 +7995,325 @@ rd_window_frame(void) } ////////////////////////// - //- rjf: build tab bar + //- rjf: compute tab build tasks // - UI_Focus(UI_FocusKind_Off) + typedef struct TabTask TabTask; + struct TabTask { - Temp scratch = scratch_begin(0, 0); - - // rjf: types - typedef struct DropSite DropSite; - struct DropSite + TabTask *next; + RD_Cfg *tab; + DR_FStrList fstrs; + F32 tab_width; + }; + TabTask *first_tab_task = 0; + TabTask *last_tab_task = 0; + U64 tab_task_count = 0; + F32 tab_close_width_px = ui_top_font_size()*2.5f; + { + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - F32 p; - RD_Cfg *prev_view; - }; - - // rjf: prep output data - RD_Cfg *next_selected_tab = selected_tab; - UI_Box *tab_bar_box = &ui_nil_box; - U64 drop_site_count = panel->tabs.count+1; - DropSite *drop_sites = push_array(scratch.arena, DropSite, drop_site_count); - F32 drop_site_max_p = 0; - U64 view_idx = 0; - - // rjf: build - UI_CornerRadius(0) - { - UI_Rect(tab_bar_rect) tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClampX|UI_BoxFlag_ViewScrollX|UI_BoxFlag_Clickable, "tab_bar_%p", panel->cfg); - if(panel->tab_side == Side_Max) + RD_Cfg *tab = n->v; + if(rd_cfg_is_project_filtered(tab)) { - tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); + continue; } - else + TabTask *t = push_array(scratch.arena, TabTask, 1); + t->tab = tab; + t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); + t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + SLLQueuePush(first_tab_task, last_tab_task, t); + tab_task_count += 1; + } + } + + ////////////////////////// + //- rjf: build tab bar container + // + UI_Box *tab_bar_box = &ui_nil_box; + UI_CornerRadius(0) UI_Rect(tab_bar_rect) + { + tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| + UI_BoxFlag_AllowOverflowY| + UI_BoxFlag_ViewClampX| + UI_BoxFlag_ViewScrollX| + UI_BoxFlag_Clickable, + "tab_bar_%p", panel->cfg); + if(panel->tab_side == Side_Max) + { + tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); + } + else + { + tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0; + } + } + + ////////////////////////// + //- rjf: determine tab drop site + // + B32 tab_drop_is_active = ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); + RD_Cfg *tab_drop_prev = &rd_nil_cfg; + { + F32 best_prev_distance_px = 1000000.f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + F32 off = 0; + for(TabTask *task = &start_boundary_tab_task; task != 0; task = task->next) + { + off += task->tab_width; + Vec2F32 anchor_pt = v2f32(tab_bar_box->rect.x0 + off, tab_bar_box->rect.y1); + F32 distance = length_2f32(sub_2f32(ui_mouse(), anchor_pt)); + if(distance < best_prev_distance_px) { - tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0; + best_prev_distance_px = distance; + tab_drop_prev = task->tab; } } - UI_Parent(tab_bar_box) UI_PrefHeight(ui_pct(1, 0)) + } + + ////////////////////////// + //- rjf: turn off drop visualization if this drag would be a no-op + // + if(tab_drop_is_active && rd_state->drag_drop_regs->panel == panel->cfg->id) + { + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + if(tab_drop_prev->id == rd_state->drag_drop_regs->view) { - Temp scratch = scratch_begin(0, 0); - F32 corner_radius = ui_em(0.6f, 1.f).value; - ui_spacer(ui_px(1.f, 1.f)); - - // rjf: build tabs - RD_Cfg *tab = &rd_nil_cfg; - RD_Cfg *prev_tab = &rd_nil_cfg; - UI_PrefWidth(ui_em(18.f, 0.5f)) - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) - for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next, view_idx += 1) + tab_drop_is_active = 0; + } + if(tab_drop_is_active) for(TabTask *t = &start_boundary_tab_task; t != 0; t = t->next) + { + if(t->tab == tab_drop_prev && t->next != 0 && t->next->tab->id == rd_state->drag_drop_regs->view) { - prev_tab = tab; - tab = tab_n->v; - temp_end(scratch); - if(rd_cfg_is_project_filtered(tab)) { continue; } + tab_drop_is_active = 0; + break; + } + } + } + + ////////////////////////// + //- rjf: build tab bar contents + // + UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) + { + F32 corner_radius = ui_top_font_size()*0.6f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) + for(TabTask *tab_task = &start_boundary_tab_task; tab_task != 0; tab_task = tab_task->next) + { + RD_Cfg *tab = tab_task->tab; + + //- rjf: build tab + DR_FStrList tab_fstrs = tab_task->fstrs; + F32 tab_width_px = tab_task->tab_width; + if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) + { + // rjf: gather info for this tab + B32 tab_is_selected = (tab == panel->selected_tab); - // rjf: if before this tab is the prev-view of the current tab drag, - // draw empty space - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && catchall_drop_site_hovered) + // rjf: begin vertical region for this tab + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(tab_width_px, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: choose palette + B32 omit_name = 0; + RD_PaletteCode palette_code = RD_PaletteCode_TabInactive; + if(tab_is_selected) { -#if 0 // TODO(rjf): @cfg_dragdrop - RD_Panel *dst_panel = rd_panel_from_handle(rd_last_drag_drop_panel); - RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - RD_View *dst_prev_view = rd_view_from_handle(rd_last_drag_drop_prev_tab); - if(dst_panel == panel && - ((!rd_view_is_nil(view) && dst_prev_view == view->order_prev && drag_view != view && drag_view != view->order_prev) || - (rd_view_is_nil(view) && dst_prev_view == panel->last_tab_view && drag_view != panel->last_tab_view))) + palette_code = RD_PaletteCode_Tab; + } + if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) + { + palette_code = RD_PaletteCode_DropSiteOverlay; + omit_name = 1; + } + + // rjf: build tab container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + RD_Palette(palette_code) + { + if(panel->tab_side == Side_Max) { - UI_PrefWidth(ui_em(9.f, 0.2f)) UI_Column - { - ui_spacer(ui_em(0.2f, 1.f)); - UI_CornerRadius00(corner_radius) - UI_CornerRadius10(corner_radius) - RD_Palette(RD_PaletteCode_DropSiteOverlay) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); - } - } + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); } -#endif - } - - // rjf: end on nil view - if(tab == &rd_nil_cfg) - { - break; - } - - // rjf: build per-tab info - RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) - { - // rjf: gather info for this tab - B32 view_is_selected = (tab == panel->selected_tab); - DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); - - // rjf: begin vertical region for this tab - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); - - // rjf: build tab container box - UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) RD_Palette(view_is_selected ? RD_PaletteCode_Tab : RD_PaletteCode_TabInactive) + else { - if(panel->tab_side == Side_Max) + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + (UI_BoxFlag_DrawDropShadow*tab_is_selected)| + UI_BoxFlag_Clickable, + "tab_%p", tab); + + // rjf: build tab contents + if(!omit_name) UI_Parent(tab_box) + { + UI_WidthFill UI_Row { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - (UI_BoxFlag_DrawDropShadow*view_is_selected)| - UI_BoxFlag_Clickable, - "tab_%p", tab); - - // rjf: build tab contents - UI_Parent(tab_box) - { - UI_WidthFill UI_Row + ui_spacer(ui_em(0.5f, 1.f)); + UI_PrefWidth(ui_text_dim(10, 0)) { - ui_spacer(ui_em(0.5f, 1.f)); - UI_PrefWidth(ui_text_dim(10, 0)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(name_box, &title_fstrs); - } - } - UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_Flags(UI_BoxFlag_DrawTextWeak) - UI_CornerRadius00(0) - UI_CornerRadius01(0) - { - UI_Palette *palette = ui_build_palette(ui_top_palette()); - palette->background = v4f32(0, 0, 0, 0); - ui_set_next_palette(palette); - UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); - if(ui_clicked(sig) || ui_middle_clicked(sig)) - { - rd_cmd(RD_CmdKind_CloseTab); - } + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &tab_fstrs); } } - - // rjf: consume events for tab clicking + UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) + UI_Flags(UI_BoxFlag_DrawTextWeak) + UI_CornerRadius00(0) + UI_CornerRadius01(0) { - UI_Signal sig = ui_signal_from_box(tab_box); - if(ui_pressed(sig)) - { - next_selected_tab = tab; - rd_cmd(RD_CmdKind_FocusPanel); - } - else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) - { - rd_drag_begin(RD_RegSlot_View); - } - else if(ui_right_clicked(sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .reg_slot = RD_RegSlot_View, - .ui_key = sig.box->key, - .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); - } - else if(ui_middle_clicked(sig)) + UI_Palette *palette = ui_build_palette(ui_top_palette()); + palette->background = v4f32(0, 0, 0, 0); + ui_set_next_palette(palette); + UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + if(ui_clicked(sig) || ui_middle_clicked(sig)) { rd_cmd(RD_CmdKind_CloseTab); } } } - // rjf: space for next tab + // rjf: consume events for tab clicking { - ui_spacer(ui_em(0.3f, 1.f)); - } - - // rjf: store off drop-site - drop_sites[view_idx].p = tab_column_box->rect.x0 - tab_spacing/2; - drop_sites[view_idx].prev_view = prev_tab; - drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p); - } - } - - // rjf: build add-new-tab button - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) - UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column - { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - UI_HoverCursor(OS_Cursor_HandPoint) - RD_Palette(RD_PaletteCode_ImplicitButton) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel->cfg); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); - } - } - } - - scratch_end(scratch); - } - - // rjf: interact with tab bar - ui_signal_from_box(tab_bar_box); - - // rjf: fill out last drop site - { - drop_sites[drop_site_count-1].p = drop_site_max_p; - drop_sites[drop_site_count-1].prev_view = rd_cfg_list_last(&panel->tabs); - } - - // rjf: more precise drop-sites on tab bar - { - Vec2F32 mouse = ui_mouse(); - RD_Cfg *drag_tab = rd_cfg_from_id(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg) - { - // rjf: mouse => hovered drop site - F32 min_distance = 0; - DropSite *active_drop_site = 0; - if(catchall_drop_site_hovered) - { - for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1) - { - F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x); - if(drop_site_idx == 0 || distance < min_distance) + UI_Signal sig = ui_signal_from_box(tab_box); + if(ui_pressed(sig)) { - active_drop_site = &drop_sites[drop_site_idx]; - min_distance = distance; + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_FocusPanel); + } + else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) + { + rd_drag_begin(RD_RegSlot_View); + } + else if(ui_right_clicked(sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .reg_slot = RD_RegSlot_View, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + } + else if(ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); } } } - // rjf: store closest prev-view - if(active_drop_site != 0) + // rjf: space for next tab { - rd_last_drag_drop_prev_tab = active_drop_site->prev_view->id; - } - else - { - rd_last_drag_drop_prev_tab = 0; + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); } + } + + //- rjf: if this is the currently active drop site's previous tab, then build empty space + // to visualize where tab will be moved once dropped + if(tab_drop_is_active && + rd_drag_is_active() && + rd_state->drag_drop_regs_slot == RD_RegSlot_View && + tab == tab_drop_prev) + { + // rjf: begin vertical region for this spot + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(ui_top_font_size()*4.f, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); - // rjf: vis - if(drag_tab != &rd_nil_cfg && active_drop_site != 0) + // rjf: build spot container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + RD_Palette(RD_PaletteCode_DropSiteOverlay) { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop())) - { - RD_Cfg *drag_view = rd_cfg_from_id(rd_state->drag_drop_regs->view); - RD_Cfg *src_panel = rd_cfg_from_id(rd_state->drag_drop_regs->panel); - RD_Cfg *dst_panel = panel->cfg; - if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg) + if(panel->tab_side == Side_Max) { - rd_cmd(RD_CmdKind_MoveTab, - .panel = src_panel->id, - .dst_panel = dst_panel->id, - .view = drag_view->id, - .prev_view = active_drop_site->prev_view->id); + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_group_key(catchall_drop_site_key); + UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_Clickable, + ui_key_zero()); + } + + // rjf: space for next tab + { + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); } } } - // rjf: apply tab change - if(next_selected_tab != panel->selected_tab) + // rjf: build add-new-tab button + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) + UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + UI_Column { - rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + if(panel->tab_side == Side_Max) + { + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Palette(RD_PaletteCode_ImplicitButton) + { + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel->cfg); + UI_Signal sig = ui_signal_from_box(add_new_box); + if(ui_clicked(sig)) + { + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + } + } } - scratch_end(scratch); + // rjf: interact with tab bar + ui_signal_from_box(tab_bar_box); } ////////////////////////// - //- rjf: less granular panel-wide drop-site + //- rjf: accept tab drops // - if(catchall_drop_site_hovered) + if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { -#if 0 // TODO(rjf): @cfg_dragdrop - rd_last_drag_drop_panel = rd_handle_from_panel(panel); - - RD_View *dragged_view = rd_view_from_handle(rd_state->drag_drop_regs->view); - B32 view_is_in_panel = 0; - for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next) - { - if(rd_view_is_project_filtered(view)) { continue; } - if(view == dragged_view) - { - view_is_in_panel = 1; - break; - } - } - - if(view_is_in_panel == 0) - { - // rjf: vis - { - RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(content_rect) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - // rjf: drop - { - if(rd_drag_drop()) - { - RD_Panel *src_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel); - RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view)) - { - rd_cmd(RD_CmdKind_MoveTab, - .prev_view = rd_handle_from_view(panel->last_tab_view), - .panel = rd_handle_from_panel(src_panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view)); - } - } - } - } -#endif + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .prev_view = tab_drop_prev->id); } ////////////////////////// @@ -8646,7 +8603,7 @@ rd_window_frame(void) } // rjf: soft circle around mouse - if(ui_key_match(ui_hot_key(), box->key)) DR_ClipScope(box->rect) + if(box->hot_t > 0.01f) DR_ClipScope(box->rect) { Vec2F32 center = ui_mouse(); F32 radius = box->font_size*12.f; @@ -13197,6 +13154,12 @@ rd_frame(void) { rd_cmd(RD_CmdKind_FocusPanel, .panel = new_panel_cfg->id); } + + // rjf: tabs on bottom on split panel? -> tabs on bottom on new panel + if(panel->tab_side == Side_Max && split_axis == Axis2_X) + { + rd_cmd(RD_CmdKind_TabBarBottom, .panel = new_panel_cfg->id); + } }break; //- rjf: panel rotation @@ -13628,20 +13591,47 @@ rd_frame(void) case RD_CmdKind_MoveTabRight: case RD_CmdKind_MoveTabLeft: { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *panel = ws->focused_panel; - RD_View *view = rd_selected_tab_from_panel(panel); - RD_View *prev_view = (kind == RD_CmdKind_MoveTabRight ? view->order_next : view->order_prev->order_prev); - if(!rd_view_is_nil(prev_view) || kind == RD_CmdKind_MoveTabLeft) + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *window = rd_window_from_cfg(tab); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); + RD_CfgList filtered_tabs = {0}; + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - rd_cmd(RD_CmdKind_MoveTab, - .panel = rd_handle_from_panel(panel), - .dst_panel = rd_handle_from_panel(panel), - .view = rd_handle_from_view(view), - .prev_view = rd_handle_from_view(prev_view)); + if(rd_cfg_is_project_filtered(n->v)) + { + continue; + } + rd_cfg_list_push(scratch.arena, &filtered_tabs, n->v); } -#endif + RD_Cfg *tab_prev2 = &rd_nil_cfg; + RD_Cfg *tab_prev = &rd_nil_cfg; + RD_Cfg *tab_next = &rd_nil_cfg; + { + RD_Cfg *prev2 = &rd_nil_cfg; + RD_Cfg *prev = &rd_nil_cfg; + RD_Cfg *next = &rd_nil_cfg; + for(RD_CfgNode *n = filtered_tabs.first; n != 0; (prev2 = prev, prev = n->v, n = n->next)) + { + next = n->next ? n->next->v : &rd_nil_cfg; + if(n->v == tab) + { + tab_prev2 = prev2; + tab_prev = prev; + tab_next = next; + break; + } + } + } + RD_Cfg *new_prev = (kind == RD_CmdKind_MoveTabRight ? tab_next : tab_prev2); + if(new_prev == tab_prev && filtered_tabs.last) + { + new_prev = filtered_tabs.last->v; + } + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .view = tab->id, + .prev_view = new_prev->id); }break; case RD_CmdKind_OpenTab: { @@ -13681,34 +13671,37 @@ rd_frame(void) }break; case RD_CmdKind_MoveTab: { -#if 0 // TODO(rjf): @cfg - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_Panel *dst_panel = rd_panel_from_handle(rd_regs()->dst_panel); - RD_View *prev_view = rd_view_from_handle(rd_regs()->prev_view); - if(!rd_panel_is_nil(src_panel) && - !rd_panel_is_nil(dst_panel) && - prev_view != view) + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_view); + RD_Cfg *src_panel = tab->parent; + RD_Cfg *dst_panel = rd_cfg_from_id(rd_regs()->dst_panel); + if(dst_panel != &rd_nil_cfg && prev_tab != tab) { - rd_panel_remove_tab_view(src_panel, view); - rd_panel_insert_tab_view(dst_panel, prev_view, view); - ws->focused_panel = dst_panel; - B32 src_panel_is_empty = 1; - for(RD_View *v = src_panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) + rd_cfg_unhook(src_panel, tab); + rd_cfg_insert_child(dst_panel, prev_tab, tab); + rd_cmd(RD_CmdKind_FocusTab, .panel = dst_panel->id, .view = tab->id); + rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->id); + RD_PanelTree src_panel_tree = rd_panel_tree_from_cfg(scratch.arena, src_panel); + RD_PanelNode *src_panel_node = rd_panel_node_from_tree_cfg(src_panel_tree.root, src_panel); + B32 src_panel_is_empty = 0; + if(src_panel != dst_panel) { - if(!rd_view_is_project_filtered(v)) + src_panel_is_empty = 1; + for(RD_CfgNode *n = src_panel_node->tabs.first; n != 0; n = n->next) { - src_panel_is_empty = 0; - break; + if(!rd_cfg_is_project_filtered(n->v)) + { + rd_cmd(RD_CmdKind_FocusTab, .panel = src_panel->id, .view = n->v->id); + src_panel_is_empty = 0; + break; + } } } - if(src_panel_is_empty && src_panel != ws->root_panel) + if(src_panel_is_empty) { - rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(src_panel)); + rd_cmd(RD_CmdKind_ClosePanel, .panel = src_panel->id); } } -#endif }break; case RD_CmdKind_TabBarTop: { @@ -14132,6 +14125,13 @@ Z(getting_started) #undef X #undef Y #undef Z + + //- rjf: remember that we reset the panel layouts + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) + { + ws->window_layout_reset = 1; + } }break; //- rjf: thread finding diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index bbe2f41a..57891ba6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -540,6 +540,7 @@ struct RD_WindowState UI_State *ui; F32 last_dpi; B32 window_temporarily_focused_ipc; + B32 window_layout_reset; // rjf: config/settings UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index b3ab2322..bf47fa37 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -796,6 +796,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; ui_state->default_animation_rate = 1 - pow_f32(2, (-80.f * ui_state->animation_dt)); + ui_state->tooltip_can_overflow_window = 0; } //- rjf: prune unused animation nodes @@ -1234,9 +1235,7 @@ ui_end_build(void) UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root}; B32 force_contain[] = { - (ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && - ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) && - ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())), + !ui_state->tooltip_can_overflow_window, 1, }; for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1) @@ -1327,7 +1326,8 @@ ui_end_build(void) box = box->hash_next) { // rjf: grab states informing animation - B32 is_hot = ui_key_match(box->key, ui_state->hot_box_key); + B32 is_hot = (ui_key_match(box->key, ui_state->hot_box_key) || + ui_key_match(box->key, ui_state->drop_hot_box_key)); B32 is_active = ui_key_match(box->key, ui_state->active_box_key[UI_MouseButtonKind_Left]); B32 is_disabled = !!(box->flags & UI_BoxFlag_Disabled) && (box->first_disabled_build_index+2 < ui_state->build_index || box->first_touched_build_index == box->first_disabled_build_index); @@ -1419,6 +1419,16 @@ ui_end_build(void) } } + //- rjf: use group keys for box animation data if possible + for(UI_Box *b = ui_state->root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, ui_state->root).next) + { + if(ui_key_match(b->key, ui_key_zero()) && !ui_key_match(b->group_key, ui_key_zero())) + { + UI_Box *group_box = ui_box_from_key(b->group_key); + b->hot_t = group_box->hot_t; + } + } + //- rjf: animate context menu if(ui_state->ctx_menu_open && !ui_box_is_nil(ui_state->ctx_menu_root) && !ui_state->ctx_menu_changed) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index c2878f75..69ab988f 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -657,6 +657,7 @@ struct UI_State U64 build_box_count; U64 last_build_box_count; B32 ctx_menu_touched_this_frame; + B32 tooltip_can_overflow_window; B32 is_animating; //- rjf: build parameters From 877e0126c970728e9d0ee8ff4f8099e213743cbb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 16:24:17 -0800 Subject: [PATCH 134/755] file path drag/drops; a few fixes with tab drag/drop --- src/raddbg/raddbg_core.c | 19 +++++++++++++++++-- src/raddbg/raddbg_views.c | 7 ++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 90dc8c67..74cfc9b1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4639,6 +4639,21 @@ rd_window_frame(void) { default:{}break; + //////////////////////// + //- rjf: file path tooltips + // + case RD_RegSlot_FilePath: + UI_Tooltip + { + FileProperties props = os_properties_from_file_path(regs->file_path); + ui_set_next_pref_width(ui_children_sum(1)); + UI_Row + { + RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline]); + ui_label(regs->file_path); + } + }break; + //////////////////////// //- rjf: cfg tooltips // @@ -8051,7 +8066,7 @@ rd_window_frame(void) ////////////////////////// //- rjf: determine tab drop site // - B32 tab_drop_is_active = ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); + B32 tab_drop_is_active = rd_drag_is_active() && ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); RD_Cfg *tab_drop_prev = &rd_nil_cfg; { F32 best_prev_distance_px = 1000000.f; @@ -13142,7 +13157,7 @@ rd_frame(void) } } } - if(origin_panel->tabs.count == 0) + if(origin_panel->cfg != split_panel && origin_panel->tabs.count == 0) { rd_cmd(RD_CmdKind_ClosePanel); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8df9729e..7598f487 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3064,7 +3064,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // rjf: dragging -> drag/drop if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) { - if(cell_info.cfg != &rd_nil_cfg) + if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval); + RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); + } + else if(cell_info.cfg != &rd_nil_cfg) { RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); } From 21a41e91051f27f31d53948b04fd2eee41e3b66c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 16:47:44 -0800 Subject: [PATCH 135/755] sketch out unattached process evaluation --- src/raddbg/generated/raddbg.meta.c | 5 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 3 +- src/raddbg/raddbg_core.c | 102 +++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0b5cf13b..b8a7a024 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[288] = +RD_VocabInfo rd_vocab_info_table[289] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -82,6 +82,7 @@ RD_VocabInfo rd_vocab_info_table[288] = {str8_lit_comp("last_modified_time"), str8_lit_comp("last_modified_times"), str8_lit_comp("Last Modified Time"), str8_lit_comp("Last Modified Times"), RD_IconKind_Null}, {str8_lit_comp("creation_time"), str8_lit_comp("creation_times"), str8_lit_comp("Creation Time"), str8_lit_comp("Creation Times"), RD_IconKind_Null}, {str8_lit_comp("data"), str8_lit_comp("datas"), str8_lit_comp("Data"), str8_lit_comp("Datas"), RD_IconKind_Null}, +{str8_lit_comp("unattached_processes"), str8_lit_comp(""), str8_lit_comp("Unattached Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_init"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -304,7 +305,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[10] = {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}")}, -{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'processes':query}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, {str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}")}, {str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 8fc45d3e..87712d4d 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -555,7 +555,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[288]; +extern RD_VocabInfo rd_vocab_info_table[289]; extern RD_NameSchemaInfo rd_name_schema_info_table[10]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6396fd4f..af104bc6 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -94,6 +94,7 @@ RD_VocabTable: {last_modified_time _ "Last Modified Time" _ Null } {creation_time _ "Creation Time" _ Null } {data _ "Data" _ Null } + {unattached_processes "" "Unattached Processes" "" Scheduler } } @struct RD_VocabInfo: @@ -214,7 +215,7 @@ RD_VocabTable: //- rjf: control entities { machine, - ```x:{'label':code_string, 'frozen':bool, 'processes':query}```, + ```x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}```, } { process, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 74cfc9b1..dd81dbb0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -575,6 +575,97 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) return num; } +//////////////////////////////// +//~ rjf: Unattached System Process List Eval Hooks + +typedef struct RD_UnattachedProcessesAccel RD_UnattachedProcessesAccel; +struct RD_UnattachedProcessesAccel +{ + DMN_ProcessInfo *infos; + U64 infos_count; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(unattached_processes) +{ + E_LookupInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs machine + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + + //- rjf: gather system processes from this machine + typedef struct Node Node; + struct Node + { + Node *next; + DMN_ProcessInfo info; + }; + Node *first = 0; + Node *last = 0; + if(lhs_entity->kind == CTRL_EntityKind_Machine) + { + DMN_ProcessIter iter = {0}; + dmn_process_iter_begin(&iter); + for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) + { + Node *node = push_array(scratch.arena, Node, 1); + SLLQueuePush(first, last, node); + node->info = info; + } + dmn_process_iter_end(&iter); + } + + //- rjf: list -> filtered list + Node *first_filtered = 0; + Node *last_filtered = 0; + U64 filtered_count = 0; + for(Node *n = first; n != 0; n = n->next) + { + Node *node = push_array(scratch.arena, Node, 1); + SLLQueuePush(first_filtered, last_filtered, node); + node->info = n->info; + filtered_count += 1; + } + + //- rjf: list -> array + U64 infos_count = filtered_count; + DMN_ProcessInfo *infos = push_array(arena, DMN_ProcessInfo, infos_count); + { + U64 idx = 0; + for(Node *n = first_filtered; n != 0; n = n->next, idx += 1) + { + infos[idx] = n->info; + infos[idx].name = push_str8_copy(arena, infos[idx].name); + } + } + + //- rjf: build accelerator + RD_UnattachedProcessesAccel *accel = push_array(arena, RD_UnattachedProcessesAccel, 1); + accel->infos = infos; + accel->infos_count = infos_count; + info.user_data = accel; + info.idxed_expr_count = infos_count; + scratch_end(scratch); + } + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(unattached_processes) +{ + RD_UnattachedProcessesAccel *accel = (RD_UnattachedProcessesAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); + expr->value.u64 = accel->infos[idx].pid; + exprs[out_idx] = expr; + } +} + //////////////////////////////// //~ rjf: Control Entity Eval Hooks @@ -12319,6 +12410,10 @@ rd_frame(void) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); } + if(kind == CTRL_EntityKind_Machine && entity->handle.machine_id == CTRL_MachineID_Local) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("local_machine"), expr); + } if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); @@ -12449,6 +12544,13 @@ rd_frame(void) .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities)); } + //- rjf: add lookup rules for unattached processes on a machine + { + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("unattached_processes"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); + } + //- rjf: add macro for commands { String8 name = str8_lit("commands"); From 2b54f48aab3900909a9bc39b5b5934c1f2bb19b3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 18:02:43 -0800 Subject: [PATCH 136/755] test with srgba buffer, hack in srgb -> linear conversion in shader for testing --- .../dwrite/font_provider_dwrite.c | 3 +++ .../d3d11/generated/render_d3d11.meta.h | 26 +++++++++++++++---- src/render/d3d11/render_d3d11.c | 6 ++--- src/render/d3d11/render_d3d11.mdesk | 26 +++++++++++++++---- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 1868c85f..4770ebba 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -191,6 +191,7 @@ fp_init(void) //- rjf: make sharp-hinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { @@ -219,6 +220,7 @@ fp_init(void) //- rjf: make sharp-unhinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { @@ -247,6 +249,7 @@ fp_init(void) //- rjf: make smooth-hinted rendering params { FLOAT gamma = IDWriteRenderingParams_GetGamma(fp_dwrite_state->base_rendering_params); + gamma = 1.f; FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(fp_dwrite_state->base_rendering_params); if(fp_dwrite_state->dwrite2_is_supported) { diff --git a/src/render/d3d11/generated/render_d3d11.meta.h b/src/render/d3d11/generated/render_d3d11.meta.h index 1031599d..370fe2ea 100644 --- a/src/render/d3d11/generated/render_d3d11.meta.h +++ b/src/render/d3d11/generated/render_d3d11.meta.h @@ -83,6 +83,20 @@ str8_lit_comp( " return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" "}\n" "\n" +"float linear_from_srgb_f32(float x)\n" +"{\n" +" return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);\n" +"}\n" +"\n" +"float4 linear_from_srgba(float4 v)\n" +"{\n" +" float4 result = float4(linear_from_srgb_f32(v.x),\n" +" linear_from_srgb_f32(v.y),\n" +" linear_from_srgb_f32(v.z),\n" +" v.w);\n" +" return result;\n" +"}\n" +"\n" "//- rjf: vertex shader\n" "\n" "Vertex2Pixel\n" @@ -122,11 +136,12 @@ str8_lit_comp( " cpu2vertex.corner_radii_px.w,\n" " cpu2vertex.corner_radii_px.z,\n" " };\n" -" float4 src_color[] = {\n" -" cpu2vertex.color01,\n" -" cpu2vertex.color00,\n" -" cpu2vertex.color11,\n" -" cpu2vertex.color10,\n" +" float4 src_color[] =\n" +" {\n" +" linear_from_srgba(cpu2vertex.color01),\n" +" linear_from_srgba(cpu2vertex.color00),\n" +" linear_from_srgba(cpu2vertex.color11),\n" +" linear_from_srgba(cpu2vertex.color10),\n" " };\n" " float2 dst_verts_pct = float2((cpu2vertex.vertex_id >> 1) ? 1.f : 0.f,\n" " (cpu2vertex.vertex_id & 1) ? 0.f : 1.f);\n" @@ -164,6 +179,7 @@ str8_lit_comp( " if(vertex2pixel.omit_texture < 1)\n" " {\n" " albedo_sample = mul(main_t2d.Sample(main_sampler, vertex2pixel.texcoord_pct), texture_sample_channel_map);\n" +" albedo_sample = linear_from_srgba(albedo_sample);\n" " }\n" " \n" " // rjf: determine SDF sample position\n" diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index 20e5ab91..d4cdd22c 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -520,7 +520,7 @@ r_window_equip(OS_Handle handle) { swapchain_desc.Width = 0; // NOTE(rjf): use window width swapchain_desc.Height = 0; // NOTE(rjf): use window height - swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; swapchain_desc.Stereo = FALSE; swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; @@ -896,7 +896,7 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip) D3D11_TEXTURE2D_DESC color_desc = zero_struct; { wnd->framebuffer->lpVtbl->GetDesc(wnd->framebuffer, &color_desc); - color_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + color_desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; color_desc.BindFlags = D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE; } D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = zero_struct; @@ -906,7 +906,7 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip) } D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = zero_struct; { - srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srv_desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srv_desc.Texture2D.MipLevels = -1; } diff --git a/src/render/d3d11/render_d3d11.mdesk b/src/render/d3d11/render_d3d11.mdesk index d05aad0f..4e8796f6 100644 --- a/src/render/d3d11/render_d3d11.mdesk +++ b/src/render/d3d11/render_d3d11.mdesk @@ -81,6 +81,20 @@ float rect_sdf(float2 sample_pos, float2 rect_half_size, float r) return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r; } +float linear_from_srgb_f32(float x) +{ + return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4); +} + +float4 linear_from_srgba(float4 v) +{ + float4 result = float4(linear_from_srgb_f32(v.x), + linear_from_srgb_f32(v.y), + linear_from_srgb_f32(v.z), + v.w); + return result; +} + //- rjf: vertex shader Vertex2Pixel @@ -120,11 +134,12 @@ vs_main(CPU2Vertex cpu2vertex) cpu2vertex.corner_radii_px.w, cpu2vertex.corner_radii_px.z, }; - float4 src_color[] = { - cpu2vertex.color01, - cpu2vertex.color00, - cpu2vertex.color11, - cpu2vertex.color10, + float4 src_color[] = + { + linear_from_srgba(cpu2vertex.color01), + linear_from_srgba(cpu2vertex.color00), + linear_from_srgba(cpu2vertex.color11), + linear_from_srgba(cpu2vertex.color10), }; float2 dst_verts_pct = float2((cpu2vertex.vertex_id >> 1) ? 1.f : 0.f, (cpu2vertex.vertex_id & 1) ? 0.f : 1.f); @@ -162,6 +177,7 @@ ps_main(Vertex2Pixel vertex2pixel) : SV_TARGET if(vertex2pixel.omit_texture < 1) { albedo_sample = mul(main_t2d.Sample(main_sampler, vertex2pixel.texcoord_pct), texture_sample_channel_map); + albedo_sample = linear_from_srgba(albedo_sample); } // rjf: determine SDF sample position From 42e3c406cd2f59e862f52ebd22156d6e8c32cfc2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Feb 2025 18:33:56 -0800 Subject: [PATCH 137/755] oklab <-> linear, linear <-> srgb --- src/base/base_math.c | 112 ++++++++++++++++++++++++++++++++++++++++--- src/base/base_math.h | 22 +++++++-- 2 files changed, 124 insertions(+), 10 deletions(-) diff --git a/src/base/base_math.c b/src/base/base_math.c index 2c6201f3..3d3766bd 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -480,7 +480,9 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0 internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} //////////////////////////////// -//~ rjf: Miscellaneous Ops +//~ rjf: Color Operations + +//- rjf: hsv <-> rgb internal Vec3F32 hsv_from_rgb(Vec3F32 rgb) @@ -567,16 +569,102 @@ rgba_from_hsva(Vec4F32 hsva) return rgba; } -internal Vec4F32 -rgba_from_u32(U32 hex) +//- rjf: srgb <-> linear + +internal Vec3F32 +linear_from_srgb(Vec3F32 srgb) { - Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f, - ((hex&0x00ff0000)>>16)/255.f, - ((hex&0x0000ff00)>> 8)/255.f, - ((hex&0x000000ff)>> 0)/255.f); + Vec3F32 result; + for EachElement(idx, srgb.v) + { + result.v[idx] = (srgb.v[idx] < 0.0404482362771082f ? srgb.v[idx] / 12.92f : pow_f32((srgb.v[idx] + 0.055f) / 1.055f, 2.4f)); + } return result; } +internal Vec3F32 +srgb_from_linear(Vec3F32 linear) +{ + Vec3F32 result; + for EachElement(idx, linear.v) + { + result.v[idx] = (0 <= linear.v[idx] && linear.v[idx] < 0.00313066844250063) ? linear.v[idx]*12.92f : 1.05f * pow_f32(linear.v[idx], 1.f/2.4f) - 0.055f; + } + return result; +} + +internal Vec4F32 +linear_from_srgba(Vec4F32 srgba) +{ + Vec4F32 result; + result.xyz = linear_from_srgb(srgba.xyz); + result.w = srgba.w; + return result; +} + +internal Vec4F32 +srgba_from_linear(Vec4F32 linear) +{ + Vec4F32 result; + result.xyz = srgb_from_linear(linear.xyz); + result.w = linear.w; + return result; +} + +//- rjf: oklab <-> linear + +internal Vec3F32 +oklab_from_linear(Vec3F32 linear) +{ + F32 l = (0.4122214708f * linear.x + 0.5363325363f * linear.y + 0.0514459929f * linear.z); + F32 m = (0.2119034982f * linear.x + 0.6806995451f * linear.y + 0.1073969566f * linear.z); + F32 s = (0.0883024619f * linear.x + 0.2817188376f * linear.y + 0.6299787005f * linear.z); + F32 l_ = cbrt_f32(l); + F32 m_ = cbrt_f32(m); + F32 s_ = cbrt_f32(s); + Vec3F32 result; + result.x = 0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_; + result.y = 1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_; + result.z = 0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_; + return result; +} + +internal Vec3F32 +linear_from_oklab(Vec3F32 oklab) +{ + F32 l_ = oklab.x + 0.3963377774f * oklab.y + 0.2158037573f * oklab.z; + F32 m_ = oklab.x - 0.1055613458f * oklab.y - 0.0638541728f * oklab.z; + F32 s_ = oklab.x - 0.0894841775f * oklab.y - 1.2914855480f * oklab.z; + F32 l = l_*l_*l_; + F32 m = m_*m_*m_; + F32 s = s_*s_*s_; + Vec3F32 result; + result.x = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s; + result.y = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s; + result.z = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s; + return result; +} + +internal Vec4F32 +oklab_from_lineara(Vec4F32 lineara) +{ + Vec4F32 result; + result.xyz = oklab_from_linear(lineara.xyz); + result.w = lineara.w; + return result; +} + +internal Vec4F32 +lineara_from_oklab(Vec4F32 oklab) +{ + Vec4F32 result; + result.xyz = linear_from_oklab(oklab.xyz); + result.w = oklab.w; + return result; +} + +//- rjf: rgba <-> u32 + internal U32 u32_from_rgba(Vec4F32 rgba) { @@ -588,6 +676,16 @@ u32_from_rgba(Vec4F32 rgba) return result; } +internal Vec4F32 +rgba_from_u32(U32 hex) +{ + Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f, + ((hex&0x00ff0000)>>16)/255.f, + ((hex&0x0000ff00)>> 8)/255.f, + ((hex&0x000000ff)>> 0)/255.f); + return result; +} + //////////////////////////////// //~ rjf: List Type Functions diff --git a/src/base/base_math.h b/src/base/base_math.h index b6063ad5..7ffaca46 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -379,6 +379,7 @@ struct Rng1S64Array #define abs_s64(v) (S64)llabs(v) #define sqrt_f32(v) sqrtf(v) +#define cbrt_f32(v) cbrtf(v) #define mod_f32(a, b) fmodf((a), (b)) #define pow_f32(b, e) powf((b), (e)) #define ceil_f32(v) ceilf(v) @@ -396,6 +397,7 @@ struct Rng1S64Array #define tan_f32(v) tanf(radians_from_turns_f32(v)) #define sqrt_f64(v) sqrt(v) +#define cbrt_f64(v) cbrt(v) #define mod_f64(a, b) fmod((a), (b)) #define pow_f64(b, e) pow((b), (e)) #define ceil_f64(v) ceil(v) @@ -651,15 +653,29 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b); internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v); //////////////////////////////// -//~ rjf: Miscellaneous Ops +//~ rjf: Color Operations +//- rjf: hsv <-> rgb internal Vec3F32 hsv_from_rgb(Vec3F32 rgb); internal Vec3F32 rgb_from_hsv(Vec3F32 hsv); internal Vec4F32 hsva_from_rgba(Vec4F32 rgba); internal Vec4F32 rgba_from_hsva(Vec4F32 hsva); -internal Vec4F32 rgba_from_u32(U32 hex); -internal U32 u32_from_rgba(Vec4F32 rgba); +//- rjf: srgb <-> linear +internal Vec3F32 linear_from_srgb(Vec3F32 srgb); +internal Vec3F32 srgb_from_linear(Vec3F32 linear); +internal Vec4F32 linear_from_srgba(Vec4F32 srgba); +internal Vec4F32 srgba_from_linear(Vec4F32 linear); + +//- rjf: oklab <-> linear +internal Vec3F32 oklab_from_linear(Vec3F32 linear); +internal Vec3F32 linear_from_oklab(Vec3F32 oklab); +internal Vec4F32 oklab_from_lineara(Vec4F32 lineara); +internal Vec4F32 lineara_from_oklab(Vec4F32 oklab); + +//- rjf: rgba <-> u32 +internal U32 u32_from_rgba(Vec4F32 rgba); +internal Vec4F32 rgba_from_u32(U32 hex); #define rgba_from_u32_lit_comp(h) { (((h)&0xff000000)>>24)/255.f, (((h)&0x00ff0000)>>16)/255.f, (((h)&0x0000ff00)>> 8)/255.f, (((h)&0x000000ff)>> 0)/255.f } //////////////////////////////// From e45bdfd90d8a8f5ab72d6dd6eef55edc3b20ff28 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Feb 2025 10:39:43 -0800 Subject: [PATCH 138/755] linearize theme from srgba on load, use linear colors everywhere; begin simplifying ui colors --- src/raddbg/generated/raddbg.meta.c | 186 +++++++++++----- src/raddbg/generated/raddbg.meta.h | 30 ++- src/raddbg/raddbg.mdesk | 82 +++---- src/raddbg/raddbg_core.c | 206 +++++++++++------- src/raddbg/raddbg_views.c | 11 +- src/raddbg/raddbg_widgets.c | 4 +- .../d3d11/generated/render_d3d11.meta.h | 8 +- src/render/d3d11/render_d3d11.mdesk | 8 +- src/ui/ui_core.h | 63 +++--- 9 files changed, 377 insertions(+), 221 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b8a7a024..c8f34e16 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -859,52 +859,60 @@ str8_lit_comp("negative_pop_button_background"), str8_lit_comp("neutral_pop_button_background"), }; -Vec4F32 rd_theme_preset_colors__default_dark[76] = +Vec4F32 rd_theme_preset_colors__default_dark[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0x4dc221ff), rgba_from_u32_lit_comp(0xc56452ff), rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0xa4a4a4ff), rgba_from_u32_lit_comp(0x8aff00ff), rgba_from_u32_lit_comp(0xb23217ff), rgba_from_u32_lit_comp(0xfda200ff), rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000002f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x222222fe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x99ccffff), +rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x5f1200ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0x2b3740ff), +rgba_from_u32_lit_comp(0x2b3740ff), +rgba_from_u32_lit_comp(0x3e4c57ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x3f3f3fff), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0xffffffff), rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x3f3f3fff), rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), +rgba_from_u32_lit_comp(0xffc800ff), +rgba_from_u32_lit_comp(0x3f3f3fff), rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), +rgba_from_u32_lit_comp(0xe88774ff), +rgba_from_u32_lit_comp(0x3f3f3fff), rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x6f5135fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0xffbb00ff), +rgba_from_u32_lit_comp(0x3f3f3fff), +rgba_from_u32_lit_comp(0x2b2b2bff), +rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x3f3f3fff), +rgba_from_u32_lit_comp(0x6f5135ff), +rgba_from_u32_lit_comp(0xffa600ff), +rgba_from_u32_lit_comp(0x8a6e54ff), +rgba_from_u32_lit_comp(0x2b3740ff), +rgba_from_u32_lit_comp(0xffa600ff), +rgba_from_u32_lit_comp(0x3e4c57ff), rgba_from_u32_lit_comp(0xcbcbcbff), -rgba_from_u32_lit_comp(0x42a2cffe), +rgba_from_u32_lit_comp(0x42a2cfff), rgba_from_u32_lit_comp(0xfec746ff), rgba_from_u32_lit_comp(0x98bc80ff), rgba_from_u32_lit_comp(0xb7afd5ff), @@ -917,14 +925,14 @@ rgba_from_u32_lit_comp(0xd96759ff), rgba_from_u32_lit_comp(0x717171ff), rgba_from_u32_lit_comp(0x7f7f7fff), rgba_from_u32_lit_comp(0xbebebeff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), +rgba_from_u32_lit_comp(0x99503dff), +rgba_from_u32_lit_comp(0xfe8249ff), +rgba_from_u32_lit_comp(0xffba17ff), +rgba_from_u32_lit_comp(0xcefd69ff), +rgba_from_u32_lit_comp(0x99503dff), +rgba_from_u32_lit_comp(0xfe8249ff), +rgba_from_u32_lit_comp(0xffba17ff), +rgba_from_u32_lit_comp(0xcefd69ff), rgba_from_u32_lit_comp(0xffcb7fff), rgba_from_u32_lit_comp(0xb2ff65ff), rgba_from_u32_lit_comp(0xff99e5ff), @@ -939,7 +947,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__default_light[76] = +Vec4F32 rd_theme_preset_colors__default_light[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x4c4c4cff), @@ -969,19 +977,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0xa4a4a4fe), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x65f534ff), +rgba_from_u32_lit_comp(0x65f534ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0xff694cff), +rgba_from_u32_lit_comp(0xff694cff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0xa6becaff), +rgba_from_u32_lit_comp(0xa6becaff), rgba_from_u32_lit_comp(0xa6a6a6fd), rgba_from_u32_lit_comp(0xa9a9a9fe), +rgba_from_u32_lit_comp(0xa9a9a9fe), rgba_from_u32_lit_comp(0xc0c0c0fe), rgba_from_u32_lit_comp(0xa98b6fff), +rgba_from_u32_lit_comp(0xa98b6fff), rgba_from_u32_lit_comp(0xffffff4d), rgba_from_u32_lit_comp(0x8282827f), +rgba_from_u32_lit_comp(0x8282827f), rgba_from_u32_lit_comp(0xffffff19), rgba_from_u32_lit_comp(0x4d4d4dff), rgba_from_u32_lit_comp(0x205670fe), @@ -1019,7 +1035,7 @@ rgba_from_u32_lit_comp(0xff2800ff), rgba_from_u32_lit_comp(0xa6becaff), }; -Vec4F32 rd_theme_preset_colors__vs_dark[76] = +Vec4F32 rd_theme_preset_colors__vs_dark[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0xe5e5e5ff), @@ -1049,19 +1065,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x2c5b36ff), +rgba_from_u32_lit_comp(0x2c5b36ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x803425ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x355b6eff), +rgba_from_u32_lit_comp(0x355b6eff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x0079ccff), +rgba_from_u32_lit_comp(0x0079ccff), rgba_from_u32_lit_comp(0xfefefe4d), rgba_from_u32_lit_comp(0xfefefe14), +rgba_from_u32_lit_comp(0xfefefe14), rgba_from_u32_lit_comp(0xffffff00), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xdcdcaaff), @@ -1099,7 +1123,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__vs_light[76] = +Vec4F32 rd_theme_preset_colors__vs_light[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x000000ff), @@ -1129,19 +1153,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x84ce93ff), +rgba_from_u32_lit_comp(0x84ce93ff), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0xbd3e24ff), +rgba_from_u32_lit_comp(0xbd3e24ff), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x6e9db5ff), +rgba_from_u32_lit_comp(0x6e9db5ff), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0xe8e8e8fe), +rgba_from_u32_lit_comp(0xe8e8e8fe), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0xfffffffe), +rgba_from_u32_lit_comp(0xfffffffe), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0xcdd4dc7f), +rgba_from_u32_lit_comp(0xcdd4dc7f), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0x000000ff), @@ -1179,7 +1211,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x6e9db5ff), }; -Vec4F32 rd_theme_preset_colors__solarized_dark[76] = +Vec4F32 rd_theme_preset_colors__solarized_dark[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x999999ff), @@ -1209,19 +1241,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0xfdfdfd3a), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0xfefefe3a), rgba_from_u32_lit_comp(0x2c5b36ff), +rgba_from_u32_lit_comp(0x2c5b36ff), rgba_from_u32_lit_comp(0xfefefe3a), rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x803425ff), rgba_from_u32_lit_comp(0xfefefe3a), rgba_from_u32_lit_comp(0x355b6eff), +rgba_from_u32_lit_comp(0x355b6eff), rgba_from_u32_lit_comp(0xfefefe3a), rgba_from_u32_lit_comp(0x005e77fe), +rgba_from_u32_lit_comp(0x005e77fe), rgba_from_u32_lit_comp(0xfefefe3a), rgba_from_u32_lit_comp(0x005e77fe), +rgba_from_u32_lit_comp(0x005e77fe), rgba_from_u32_lit_comp(0xfefefe4d), rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x3e4c577f), rgba_from_u32_lit_comp(0xffffff19), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1259,7 +1299,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__solarized_light[76] = +Vec4F32 rd_theme_preset_colors__solarized_light[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x333333ff), @@ -1288,20 +1328,28 @@ rgba_from_u32_lit_comp(0xffffff7c), rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0xbdb9aa00), rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xb6ddbeff), +rgba_from_u32_lit_comp(0xb6ddbeff), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xf8b0a1ff), +rgba_from_u32_lit_comp(0xf8b0a1ff), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xb2d3e3ff), +rgba_from_u32_lit_comp(0xb2d3e3ff), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xe3dbc7fe), +rgba_from_u32_lit_comp(0xe3dbc7fe), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xfdf6e3ff), +rgba_from_u32_lit_comp(0xfdf6e3ff), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0xd4cfc0fe), +rgba_from_u32_lit_comp(0xd4cfc0fe), rgba_from_u32_lit_comp(0xbebaabfe), rgba_from_u32_lit_comp(0x657b83ff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1339,7 +1387,7 @@ rgba_from_u32_lit_comp(0xff684bff), rgba_from_u32_lit_comp(0xb2d3e3ff), }; -Vec4F32 rd_theme_preset_colors__handmade_hero[76] = +Vec4F32 rd_theme_preset_colors__handmade_hero[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0xa08462ff), @@ -1369,18 +1417,26 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0x423425fe), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x132e19ff), +rgba_from_u32_lit_comp(0x132e19ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x803425ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x15445cff), +rgba_from_u32_lit_comp(0x15445cff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0xfefefe4d), rgba_from_u32_lit_comp(0x1f1f27fe), rgba_from_u32_lit_comp(0xfefefe4d), +rgba_from_u32_lit_comp(0x1f1f27fe), +rgba_from_u32_lit_comp(0x1f1f27fe), +rgba_from_u32_lit_comp(0xfefefe4d), +rgba_from_u32_lit_comp(0x131315ee), rgba_from_u32_lit_comp(0x131315ee), rgba_from_u32_lit_comp(0xffffff19), rgba_from_u32_lit_comp(0xa08462ff), @@ -1419,7 +1475,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x15445cff), }; -Vec4F32 rd_theme_preset_colors__four_coder[76] = +Vec4F32 rd_theme_preset_colors__four_coder[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x90b080ff), @@ -1449,19 +1505,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x152f1bff), +rgba_from_u32_lit_comp(0x152f1bff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x43150cff), +rgba_from_u32_lit_comp(0x43150cff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x1b323eff), +rgba_from_u32_lit_comp(0x1b323eff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x212721fe), +rgba_from_u32_lit_comp(0x212721fe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x212721fe), +rgba_from_u32_lit_comp(0x212721fe), rgba_from_u32_lit_comp(0xfefefe4d), rgba_from_u32_lit_comp(0x3a3a3a7f), +rgba_from_u32_lit_comp(0x3a3a3a7f), rgba_from_u32_lit_comp(0x00000019), rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x42a2cffe), @@ -1499,7 +1563,7 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x1b323eff), }; -Vec4F32 rd_theme_preset_colors__far_manager[76] = +Vec4F32 rd_theme_preset_colors__far_manager[84] = { rgba_from_u32_lit_comp(0xff00ffff), rgba_from_u32_lit_comp(0x00fefeff), @@ -1529,19 +1593,27 @@ rgba_from_u32_lit_comp(0x33333333), rgba_from_u32_lit_comp(0x00ffff55), rgba_from_u32_lit_comp(0x00000000), rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x2c5b36ff), +rgba_from_u32_lit_comp(0x2c5b36ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x803425ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x933100ff), +rgba_from_u32_lit_comp(0x933100ff), rgba_from_u32_lit_comp(0x3f3f3ffd), rgba_from_u32_lit_comp(0x007d7dff), +rgba_from_u32_lit_comp(0x007d7dff), rgba_from_u32_lit_comp(0x3f3f3ffe), rgba_from_u32_lit_comp(0x007d7dff), +rgba_from_u32_lit_comp(0x007d7dff), rgba_from_u32_lit_comp(0xfefefe4d), rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x3e4c577f), rgba_from_u32_lit_comp(0xfefefe19), rgba_from_u32_lit_comp(0x00fefeff), rgba_from_u32_lit_comp(0x65b1ffff), @@ -1592,7 +1664,7 @@ rd_theme_preset_colors__four_coder, rd_theme_preset_colors__far_manager, }; -String8 rd_theme_color_display_string_table[76] = +String8 rd_theme_color_display_string_table[84] = { str8_lit_comp("Null"), str8_lit_comp("Text"), @@ -1621,20 +1693,28 @@ str8_lit_comp("Floating Background"), str8_lit_comp("Floating Background (Alternate)"), str8_lit_comp("Floating Border"), str8_lit_comp("Implicit Button Background"), +str8_lit_comp("Implicit Button Hover"), str8_lit_comp("Implicit Button Border"), str8_lit_comp("Plain Button Background"), +str8_lit_comp("Plain Button Hover"), str8_lit_comp("Plain Button Border"), str8_lit_comp("Positive Pop Button Background"), +str8_lit_comp("Positive Pop Button Hover"), str8_lit_comp("Positive Pop Button Border"), str8_lit_comp("Negative Pop Button Background"), +str8_lit_comp("Negative Pop Button Hover"), str8_lit_comp("Negative Pop Button Border"), str8_lit_comp("Neutral Pop Button Background"), +str8_lit_comp("Neutral Pop Button Hover"), str8_lit_comp("Neutral Pop Button Border"), str8_lit_comp("Scroll Bar Button Background"), +str8_lit_comp("Scroll Bar Button Hover"), str8_lit_comp("Scroll Bar Button Border"), str8_lit_comp("Tab Background"), +str8_lit_comp("Tab Hover"), str8_lit_comp("Tab Border"), str8_lit_comp("Tab Background (Inactive)"), +str8_lit_comp("Tab Hover (Inactive)"), str8_lit_comp("Tab Border (Inactive)"), str8_lit_comp("Code (Default)"), str8_lit_comp("Code (Symbol)"), @@ -1672,7 +1752,7 @@ str8_lit_comp("Breakpoint"), str8_lit_comp("Cache Line Boundary"), }; -String8 rd_theme_color_cfg_string_table[76] = +String8 rd_theme_color_cfg_string_table[84] = { str8_lit_comp("null"), str8_lit_comp("text"), @@ -1701,20 +1781,28 @@ str8_lit_comp("floating_background"), str8_lit_comp("floating_background_alt"), str8_lit_comp("floating_border"), str8_lit_comp("implicit_button_background"), +str8_lit_comp("implicit_button_hover"), str8_lit_comp("implicit_button_border"), str8_lit_comp("plain_button_background"), +str8_lit_comp("plain_button_hover"), str8_lit_comp("plain_button_border"), str8_lit_comp("positive_pop_button_background"), +str8_lit_comp("positive_pop_button_hover"), str8_lit_comp("positive_pop_button_border"), str8_lit_comp("negative_pop_button_background"), +str8_lit_comp("negative_pop_button_hover"), str8_lit_comp("negative_pop_button_border"), str8_lit_comp("neutral_pop_button_background"), +str8_lit_comp("neutral_pop_button_hover"), str8_lit_comp("neutral_pop_button_border"), str8_lit_comp("scroll_bar_button_background"), +str8_lit_comp("scroll_bar_button_hover"), str8_lit_comp("scroll_bar_button_border"), str8_lit_comp("tab_background"), +str8_lit_comp("tab_hover"), str8_lit_comp("tab_border"), str8_lit_comp("tab_background_inactive"), +str8_lit_comp("tab_hover_inactive"), str8_lit_comp("tab_border_inactive"), str8_lit_comp("code_default"), str8_lit_comp("code_symbol"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 87712d4d..e079cef6 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -370,20 +370,28 @@ RD_ThemeColor_FloatingBackground, RD_ThemeColor_FloatingBackgroundAlt, RD_ThemeColor_FloatingBorder, RD_ThemeColor_ImplicitButtonBackground, +RD_ThemeColor_ImplicitButtonHover, RD_ThemeColor_ImplicitButtonBorder, RD_ThemeColor_PlainButtonBackground, +RD_ThemeColor_PlainButtonHover, RD_ThemeColor_PlainButtonBorder, RD_ThemeColor_PositivePopButtonBackground, +RD_ThemeColor_PositivePopButtonHover, RD_ThemeColor_PositivePopButtonBorder, RD_ThemeColor_NegativePopButtonBackground, +RD_ThemeColor_NegativePopButtonHover, RD_ThemeColor_NegativePopButtonBorder, RD_ThemeColor_NeutralPopButtonBackground, +RD_ThemeColor_NeutralPopButtonHover, RD_ThemeColor_NeutralPopButtonBorder, RD_ThemeColor_ScrollBarButtonBackground, +RD_ThemeColor_ScrollBarButtonHover, RD_ThemeColor_ScrollBarButtonBorder, RD_ThemeColor_TabBackground, +RD_ThemeColor_TabHover, RD_ThemeColor_TabBorder, RD_ThemeColor_TabBackgroundInactive, +RD_ThemeColor_TabHoverInactive, RD_ThemeColor_TabBorderInactive, RD_ThemeColor_CodeDefault, RD_ThemeColor_CodeSymbol, @@ -565,18 +573,18 @@ extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_color_version_remap_old_name_table[22]; extern String8 rd_theme_color_version_remap_new_name_table[22]; -extern Vec4F32 rd_theme_preset_colors__default_dark[76]; -extern Vec4F32 rd_theme_preset_colors__default_light[76]; -extern Vec4F32 rd_theme_preset_colors__vs_dark[76]; -extern Vec4F32 rd_theme_preset_colors__vs_light[76]; -extern Vec4F32 rd_theme_preset_colors__solarized_dark[76]; -extern Vec4F32 rd_theme_preset_colors__solarized_light[76]; -extern Vec4F32 rd_theme_preset_colors__handmade_hero[76]; -extern Vec4F32 rd_theme_preset_colors__four_coder[76]; -extern Vec4F32 rd_theme_preset_colors__far_manager[76]; +extern Vec4F32 rd_theme_preset_colors__default_dark[84]; +extern Vec4F32 rd_theme_preset_colors__default_light[84]; +extern Vec4F32 rd_theme_preset_colors__vs_dark[84]; +extern Vec4F32 rd_theme_preset_colors__vs_light[84]; +extern Vec4F32 rd_theme_preset_colors__solarized_dark[84]; +extern Vec4F32 rd_theme_preset_colors__solarized_light[84]; +extern Vec4F32 rd_theme_preset_colors__handmade_hero[84]; +extern Vec4F32 rd_theme_preset_colors__four_coder[84]; +extern Vec4F32 rd_theme_preset_colors__far_manager[84]; extern Vec4F32* rd_theme_preset_colors_table[9]; -extern String8 rd_theme_color_display_string_table[76]; -extern String8 rd_theme_color_cfg_string_table[76]; +extern String8 rd_theme_color_display_string_table[84]; +extern String8 rd_theme_color_cfg_string_table[84]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index af104bc6..a5395ca8 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1003,55 +1003,63 @@ RD_ThemeColorTable: {TextPositive "Text (Positive)" text_positive 0x4dc221ff 0x4d9e2eff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff ""} {TextNegative "Text (Negative)" text_negative 0xc56452ff 0xbd371eff 0xc56452ff 0xc46451ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff ""} {TextNeutral "Text (Neutral)" text_neutral 0x307eb2ff 0x0064a7ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff ""} - {TextWeak "Text (Weak)" text_weak 0xa4a4a4fe 0x4c4c4cff 0xa4a4a4fe 0x0000007f 0x9999998a 0x818181ff 0x6e512eff 0x566e4bff 0x00a9a9ff ""} + {TextWeak "Text (Weak)" text_weak 0xa4a4a4ff 0x4c4c4cff 0xa4a4a4fe 0x0000007f 0x9999998a 0x818181ff 0x6e512eff 0x566e4bff 0x00a9a9ff ""} {Cursor "Cursor" cursor 0x8aff00ff 0x699830ff 0x8aff00ff 0x000000ff 0x8aff00ff 0x586e75ff 0x8aff00ff 0x8aff00ff 0x8aff00ff ""} {CursorInactive "Cursor (Inactive)" cursor_inactive 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff ""} {Focus "Focus" focus 0xfda200ff 0x9c5900ff 0xfda200ff 0x002affff 0xfda200ff 0x92743dff 0xfda200ff 0xfda200ff 0x00fefeff ""} {Hover "Hover" hover 0xffffffff 0xffffffff 0xffffffff 0x000000ff 0xffffffff 0x747474ff 0xffffffff 0xffffffff 0xffffffff ""} - {DropShadow "Drop Shadow" drop_shadow 0x0000007f 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - {DisabledOverlay "Disabled Overlay" disabled_overlay 0x0000003f 0xa6a6a63f 0x0000003f 0x0000003f 0x0000003f 0xe4dac090 0x0000003f 0x0000003f 0x0000003f ""} - {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0xffffff0c 0x4848480c 0xffffff0c 0x0000000c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c ""} - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x0000002f 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} - {SelectionOverlay "Selection Overlay" selection_overlay 0x99ccff4c 0x003d7a48 0x99ccff4c 0x3d74ab4b 0x99ccff4c 0x678cb24c 0x99ccff4c 0x99ccff4c 0x99ccff4c ""} - {HighlightOverlay "Highlight Overlay" highlight_overlay 0xffffff1e 0xffffff1e 0xffffff1e 0x0000001e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e ""} - {HighlightOverlayError "Error Highlight Overlay" error_highlight_overlay 0x5f12005f 0xff30005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f ""} + {DropShadow "Drop Shadow" drop_shadow 0x000000ff 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} + {DisabledOverlay "Disabled Overlay" disabled_overlay 0x000000ff 0xa6a6a63f 0x0000003f 0x0000003f 0x0000003f 0xe4dac090 0x0000003f 0x0000003f 0x0000003f ""} + {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0xffffffff 0x4848480c 0xffffff0c 0x0000000c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c ""} + {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x000000ff 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} + {SelectionOverlay "Selection Overlay" selection_overlay 0x99ccffff 0x003d7a48 0x99ccff4c 0x3d74ab4b 0x99ccff4c 0x678cb24c 0x99ccff4c 0x99ccff4c 0x99ccff4c ""} + {HighlightOverlay "Highlight Overlay" highlight_overlay 0xffffffff 0xffffff1e 0xffffff1e 0x0000001e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e ""} + {HighlightOverlayError "Error Highlight Overlay" error_highlight_overlay 0x5f1200ff 0xff30005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f ""} //- rjf: base ui container colors - {BaseBackground "Base Background" base_background 0x1b1b1bfe 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222fe 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBorder "Base Border" base_border 0x3f3f3ffe 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {BaseBackground "Base Background" base_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBorder "Base Border" base_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} //- rjf: menu bar ui container colors - {MenuBarBackground "Menu Bar Background" menu_bar_background 0x3e4c577f 0xeaeaea7f 0x1b1b1bfd 0xffffff7f 0x00202bff 0xeee8d5ff 0x0c0c0cfe 0x0c0c0cfe 0x007d7dff ""} - {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x3e4c577f 0x3e4c577f 0x1b1b1bfd 0xffffff7f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x007d7dff ""} - {MenuBarBorder "Menu Bar Border" menu_bar_border 0xffffff19 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0xffffff19 0xfefefe00 ""} + {MenuBarBackground "Menu Bar Background" menu_bar_background 0x2b3740ff 0xeaeaea7f 0x1b1b1bfd 0xffffff7f 0x00202bff 0xeee8d5ff 0x0c0c0cfe 0x0c0c0cfe 0x007d7dff ""} + {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x2b3740ff 0x3e4c577f 0x1b1b1bfd 0xffffff7f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x007d7dff ""} + {MenuBarBorder "Menu Bar Border" menu_bar_border 0x3e4c57ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0xffffff19 0xfefefe00 ""} //- rjf: floating ui container colors - {FloatingBackground "Floating Background" floating_background 0x33333333 0xccccccc0 0x33333333 0xfefefec7 0x007fa14e 0xffffff7c 0x0c0c0c32 0x0c0c0c3e 0x007c7c55 ""} - {FloatingBackgroundAlt "Floating Background (Alternate)" floating_background_alt 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 ""} - {FloatingBorder "Floating Border" floating_border 0x3f3f3ffd 0xa4a4a4fe 0x3f3f3ffd 0xb6b6b6ff 0xfdfdfd3a 0xbebaabfe 0x423425fe 0x3f3f3ffd 0x00ffff55 ""} + {FloatingBackground "Floating Background" floating_background 0x333333ff 0xccccccc0 0x33333333 0xfefefec7 0x007fa14e 0xffffff7c 0x0c0c0c32 0x0c0c0c3e 0x007c7c55 ""} + {FloatingBackgroundAlt "Floating Background (Alternate)" floating_background_alt 0x333333ff 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 ""} + {FloatingBorder "Floating Border" floating_border 0x3f3f3fff 0xa4a4a4fe 0x3f3f3ffd 0xb6b6b6ff 0xfdfdfd3a 0xbebaabfe 0x423425fe 0x3f3f3ffd 0x00ffff55 ""} //- rjf: ui element colors {ImplicitButtonBackground "Implicit Button Background" implicit_button_background 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ""} + {ImplicitButtonHover "Implicit Button Hover" implicit_button_hover 0xffffffff 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ""} {ImplicitButtonBorder "Implicit Button Border" implicit_button_border 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xbdb9aa00 0x00000000 0x00000000 0x00000000 ""} - {PlainButtonBackground "Plain Button Background" plain_button_background 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} - {PlainButtonBorder "Plain Button Border" plain_button_border 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe ""} + {PlainButtonBackground "Plain Button Background" plain_button_background 0x1b1b1bff 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} + {PlainButtonHover "Plain Button Hover" plain_button_hover 0xffffffff 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} + {PlainButtonBorder "Plain Button Border" plain_button_border 0x3f3f3fff 0x3f3f3ffe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe ""} {PositivePopButtonBackground "Positive Pop Button Background" positive_pop_button_background 0x2c5b36ff 0x65f534ff 0x2c5b36ff 0x84ce93ff 0x2c5b36ff 0xb6ddbeff 0x132e19ff 0x152f1bff 0x2c5b36ff ""} - {PositivePopButtonBorder "Positive Pop Button Border" positive_pop_button_border 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} + {PositivePopButtonHover "Positive Pop Button Hover" positive_pop_button_hover 0xffc800ff 0x65f534ff 0x2c5b36ff 0x84ce93ff 0x2c5b36ff 0xb6ddbeff 0x132e19ff 0x152f1bff 0x2c5b36ff ""} + {PositivePopButtonBorder "Positive Pop Button Border" positive_pop_button_border 0x3f3f3fff 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} {NegativePopButtonBackground "Negative Pop Button Background" negative_pop_button_background 0x803425ff 0xff694cff 0x803425ff 0xbd3e24ff 0x803425ff 0xf8b0a1ff 0x803425ff 0x43150cff 0x803425ff ""} - {NegativePopButtonBorder "Negative Pop Button Border" negative_pop_button_border 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} + {NegativePopButtonHover "Negative Pop Button Hover" negative_pop_button_hover 0xe88774ff 0xff694cff 0x803425ff 0xbd3e24ff 0x803425ff 0xf8b0a1ff 0x803425ff 0x43150cff 0x803425ff ""} + {NegativePopButtonBorder "Negative Pop Button Border" negative_pop_button_border 0x3f3f3fff 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} {NeutralPopButtonBackground "Neutral Pop Button Background" neutral_pop_button_background 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} - {NeutralPopButtonBorder "Neutral Pop Button Border" neutral_pop_button_border 0x3f3f3ffd 0xa6a6a6fd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {ScrollBarButtonBackground "Scroll Bar Button Background" scroll_bar_button_background 0x2b2b2bfe 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {ScrollBarButtonBorder "Scroll Bar Button Border" scroll_bar_button_border 0x3f3f3ffe 0xc0c0c0fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0xfefefe4d 0x3f3f3ffe 0x3f3f3ffe ""} - {TabBackground "Tab Background" tab_background 0x6f5135fe 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {TabBorder "Tab Border" tab_border 0xfefefe4d 0xffffff4d 0xfefefe4d 0xb6b6b6ff 0xfefefe4d 0xbebaabfe 0xfefefe4d 0xfefefe4d 0xfefefe4d ""} - {TabBackgroundInactive "Tab Background (Inactive)" tab_background_inactive 0x3e4c577f 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} - {TabBorderInactive "Tab Border (Inactive)" tab_border_inactive 0xffffff19 0xffffff19 0xffffff00 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0x00000019 0xfefefe19 ""} + {NeutralPopButtonHover "Neutral Pop Button Hover" neutral_pop_button_hover 0xffbb00ff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} + {NeutralPopButtonBorder "Neutral Pop Button Border" neutral_pop_button_border 0x3f3f3fff 0xa6a6a6fd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} + {ScrollBarButtonBackground "Scroll Bar Button Background" scroll_bar_button_background 0x2b2b2bff 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} + {ScrollBarButtonHover "Scroll Bar Button Hover" scroll_bar_button_hover 0xffffffff 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} + {ScrollBarButtonBorder "Scroll Bar Button Border" scroll_bar_button_border 0x3f3f3fff 0xc0c0c0fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0xfefefe4d 0x3f3f3ffe 0x3f3f3ffe ""} + {TabBackground "Tab Background" tab_background 0x6f5135ff 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} + {TabHover "Tab Hover" tab_hover 0xffa600ff 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} + {TabBorder "Tab Border" tab_border 0x8a6e54ff 0xffffff4d 0xfefefe4d 0xb6b6b6ff 0xfefefe4d 0xbebaabfe 0xfefefe4d 0xfefefe4d 0xfefefe4d ""} + {TabBackgroundInactive "Tab Background (Inactive)" tab_background_inactive 0x2b3740ff 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} + {TabHoverInactive "Tab Hover (Inactive)" tab_hover_inactive 0xffa600ff 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} + {TabBorderInactive "Tab Border (Inactive)" tab_border_inactive 0x3e4c57ff 0xffffff19 0xffffff00 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0x00000019 0xfefefe19 ""} //- rjf: code colors {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cffe 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} + {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cfff 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} @@ -1066,14 +1074,14 @@ RD_ThemeColorTable: {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} //- rjf: debugging colors - {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index dd81dbb0..0ff81e2e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4536,54 +4536,66 @@ rd_window_frame(void) ws->cfg_palettes[code].cursor = current->colors[RD_ThemeColor_Cursor]; ws->cfg_palettes[code].selection = current->colors[RD_ThemeColor_SelectionOverlay]; } - ws->cfg_palettes[RD_PaletteCode_Base].background = current->colors[RD_ThemeColor_BaseBackground]; - ws->cfg_palettes[RD_PaletteCode_Base].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Base].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Base].border = current->colors[RD_ThemeColor_BaseBorder]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].background = current->colors[RD_ThemeColor_MenuBarBackground]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].border = current->colors[RD_ThemeColor_MenuBarBorder]; - ws->cfg_palettes[RD_PaletteCode_Floating].background = current->colors[RD_ThemeColor_FloatingBackground]; - ws->cfg_palettes[RD_PaletteCode_Floating].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Floating].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Floating].border = current->colors[RD_ThemeColor_FloatingBorder]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background = current->colors[RD_ThemeColor_ImplicitButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].border = current->colors[RD_ThemeColor_ImplicitButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].background = current->colors[RD_ThemeColor_PlainButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].border = current->colors[RD_ThemeColor_PlainButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background = current->colors[RD_ThemeColor_PositivePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].border = current->colors[RD_ThemeColor_PositivePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background = current->colors[RD_ThemeColor_NegativePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].border = current->colors[RD_ThemeColor_NegativePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].border = current->colors[RD_ThemeColor_NeutralPopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].border = current->colors[RD_ThemeColor_ScrollBarButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_Tab].background = current->colors[RD_ThemeColor_TabBackground]; - ws->cfg_palettes[RD_PaletteCode_Tab].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Tab].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Tab].border = current->colors[RD_ThemeColor_TabBorder]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].background = current->colors[RD_ThemeColor_TabBackgroundInactive]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].border = current->colors[RD_ThemeColor_TabBorderInactive]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_BaseBorder]; + ws->cfg_palettes[RD_PaletteCode_Base].background = current->colors[RD_ThemeColor_BaseBackground]; + ws->cfg_palettes[RD_PaletteCode_Base].background_alt = current->colors[RD_ThemeColor_BaseBackgroundAlt]; + ws->cfg_palettes[RD_PaletteCode_Base].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_Base].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_Base].border = current->colors[RD_ThemeColor_BaseBorder]; + ws->cfg_palettes[RD_PaletteCode_MenuBar].background = current->colors[RD_ThemeColor_MenuBarBackground]; + ws->cfg_palettes[RD_PaletteCode_MenuBar].background_alt = current->colors[RD_ThemeColor_MenuBarBackgroundAlt]; + ws->cfg_palettes[RD_PaletteCode_MenuBar].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_MenuBar].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_MenuBar].border = current->colors[RD_ThemeColor_MenuBarBorder]; + ws->cfg_palettes[RD_PaletteCode_Floating].background = current->colors[RD_ThemeColor_FloatingBackground]; + ws->cfg_palettes[RD_PaletteCode_Floating].background_alt = current->colors[RD_ThemeColor_FloatingBackgroundAlt]; + ws->cfg_palettes[RD_PaletteCode_Floating].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_Floating].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_Floating].border = current->colors[RD_ThemeColor_FloatingBorder]; + ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background = current->colors[RD_ThemeColor_ImplicitButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background_alt = current->colors[RD_ThemeColor_ImplicitButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_ImplicitButton].border = current->colors[RD_ThemeColor_ImplicitButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_PlainButton].background = current->colors[RD_ThemeColor_PlainButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_PlainButton].background_alt = current->colors[RD_ThemeColor_PlainButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_PlainButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_PlainButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_PlainButton].border = current->colors[RD_ThemeColor_PlainButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background = current->colors[RD_ThemeColor_PositivePopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background_alt = current->colors[RD_ThemeColor_PositivePopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_PositivePopButton].border = current->colors[RD_ThemeColor_PositivePopButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background = current->colors[RD_ThemeColor_NegativePopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background_alt = current->colors[RD_ThemeColor_NegativePopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_NegativePopButton].border = current->colors[RD_ThemeColor_NegativePopButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background_alt = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].border = current->colors[RD_ThemeColor_NeutralPopButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background_alt = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; + ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].border = current->colors[RD_ThemeColor_ScrollBarButtonBorder]; + ws->cfg_palettes[RD_PaletteCode_Tab].background = current->colors[RD_ThemeColor_TabBackground]; + ws->cfg_palettes[RD_PaletteCode_Tab].background_alt = current->colors[RD_ThemeColor_TabBackground]; + ws->cfg_palettes[RD_PaletteCode_Tab].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_Tab].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_Tab].border = current->colors[RD_ThemeColor_TabBorder]; + ws->cfg_palettes[RD_PaletteCode_TabInactive].background = current->colors[RD_ThemeColor_TabBackgroundInactive]; + ws->cfg_palettes[RD_PaletteCode_TabInactive].background_alt = current->colors[RD_ThemeColor_TabBackgroundInactive]; + ws->cfg_palettes[RD_PaletteCode_TabInactive].text = current->colors[RD_ThemeColor_Text]; + ws->cfg_palettes[RD_PaletteCode_TabInactive].text_weak = current->colors[RD_ThemeColor_TextWeak]; + ws->cfg_palettes[RD_PaletteCode_TabInactive].border = current->colors[RD_ThemeColor_TabBorderInactive]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background = current->colors[RD_ThemeColor_DropSiteOverlay]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background_alt = current->colors[RD_ThemeColor_DropSiteOverlay]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; + ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_BaseBorder]; if(rd_setting_b32_from_name(str8_lit("opaque_backgrounds"))) { for EachEnumVal(RD_PaletteCode, code) @@ -4594,6 +4606,12 @@ rd_window_frame(void) { ws->cfg_palettes[code].background.w = 1; } + if(ws->cfg_palettes[code].background_alt.x != 0 || + ws->cfg_palettes[code].background_alt.y != 0 || + ws->cfg_palettes[code].background_alt.z != 0) + { + ws->cfg_palettes[code].background_alt.w = 1; + } } } } @@ -7669,7 +7687,7 @@ rd_window_frame(void) panel_rect_pct.y0*content_rect_dim.y, panel_rect_pct.x1*content_rect_dim.x, panel_rect_pct.y1*content_rect_dim.y); - panel_rect = pad_2f32(panel_rect, -1.f); + panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); F32 tab_bar_rheight = ui_top_font_size()*3.f; F32 tab_bar_vheight = ui_top_font_size()*2.6f; F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; @@ -7693,10 +7711,18 @@ rd_window_frame(void) content_rect.y0 += filter_bar_height*selected_tab_is_filtering_t; filter_rect.y1 = content_rect.y0; } + tab_bar_rect = intersect_2f32(tab_bar_rect, panel_rect); + content_rect = intersect_2f32(content_rect, panel_rect); + + ////////////////////////// + //- rjf: decide to skip this panel (e.g. if it is too small + // + B32 build_panel = (content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0); ////////////////////////// //- rjf: build combined split+movetab drag/drop sites // + if(build_panel) { RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) @@ -7872,7 +7898,7 @@ rd_window_frame(void) //- rjf: build catch-all panel drop-site // UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); - UI_Rect(panel_rect) + if(build_panel) UI_Rect(panel_rect) { UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); ui_signal_from_box(catchall_drop_site); @@ -7941,9 +7967,11 @@ rd_window_frame(void) ////////////////////////// //- rjf: panel not selected? -> darken // - if(panel != panel_tree.focused) + if(build_panel) if(panel != panel_tree.focused) { - UI_Palette(ui_build_palette(0, .background = rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay))) + Vec4F32 darken_color = rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay); + darken_color.w *= 0.2f; + UI_Palette(ui_build_palette(0, .background = darken_color)) UI_Rect(content_rect) { ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); @@ -7954,7 +7982,7 @@ rd_window_frame(void) //- rjf: build panel container box // UI_Box *panel_box = &ui_nil_box; - UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) + if(build_panel) UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) { UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_box_%p", panel->cfg); panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| @@ -7969,7 +7997,7 @@ rd_window_frame(void) //- rjf: loading animation for stable view // UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(panel_box) UI_WidthFill UI_HeightFill + if(build_panel) UI_Parent(panel_box) UI_WidthFill UI_HeightFill { loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); } @@ -7977,7 +8005,8 @@ rd_window_frame(void) ////////////////////////// //- rjf: build selected tab view // - UI_Parent(panel_box) + if(build_panel) + UI_Parent(panel_box) UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) UI_WidthFill { @@ -8039,6 +8068,7 @@ rd_window_frame(void) //////////////////////// //- rjf: loading? -> fill loading overlay container // + if(build_panel) { F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target); if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) @@ -8084,20 +8114,23 @@ rd_window_frame(void) ////////////////////////// //- rjf: consume panel fallthrough interaction events // - UI_Signal panel_sig = ui_signal_from_box(panel_box); - if(ui_pressed(panel_sig)) + if(build_panel) { - rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); - } - if(ui_right_clicked(panel_sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .view = panel->selected_tab->id, - .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), - .ui_key = panel_box->key, - .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), - .reg_slot = RD_RegSlot_View, - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + UI_Signal panel_sig = ui_signal_from_box(panel_box); + if(ui_pressed(panel_sig)) + { + rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); + } + if(ui_right_clicked(panel_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .view = panel->selected_tab->id, + .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), + .ui_key = panel_box->key, + .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), + .reg_slot = RD_RegSlot_View, + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + } } ////////////////////////// @@ -8115,6 +8148,7 @@ rd_window_frame(void) TabTask *last_tab_task = 0; U64 tab_task_count = 0; F32 tab_close_width_px = ui_top_font_size()*2.5f; + if(build_panel) { for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { @@ -8136,7 +8170,7 @@ rd_window_frame(void) //- rjf: build tab bar container // UI_Box *tab_bar_box = &ui_nil_box; - UI_CornerRadius(0) UI_Rect(tab_bar_rect) + if(build_panel) UI_CornerRadius(0) UI_Rect(tab_bar_rect) { tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| UI_BoxFlag_AllowOverflowY| @@ -8159,6 +8193,7 @@ rd_window_frame(void) // B32 tab_drop_is_active = rd_drag_is_active() && ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); RD_Cfg *tab_drop_prev = &rd_nil_cfg; + if(build_panel) { F32 best_prev_distance_px = 1000000.f; TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; @@ -8199,7 +8234,7 @@ rd_window_frame(void) ////////////////////////// //- rjf: build tab bar contents // - UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) + if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) { F32 corner_radius = ui_top_font_size()*0.6f; TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; @@ -8691,7 +8726,7 @@ rd_window_frame(void) // rjf: main rectangle { - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box->flags & UI_BoxFlag_DrawBackgroundAlt ? box->palette->colors[UI_ColorCode_BackgroundAlt] : box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -8702,7 +8737,7 @@ rd_window_frame(void) { R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - color.w *= t*0.2f; + color.w *= t*0.1f; inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; MemoryCopyArray(inst->corner_radii, box->corner_radii); @@ -8714,7 +8749,7 @@ rd_window_frame(void) Vec2F32 center = ui_mouse(); F32 radius = box->font_size*12.f; Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); - color.w *= 0.1f*t; + color.w *= 0.05f*t; dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } @@ -8759,7 +8794,7 @@ rd_window_frame(void) { R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y1 - shadow_size.y, box->rect.x1, box->rect.y1), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = inst->colors[Corner_10] = v4f32(0, 0, 0, 0); - inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(0.4f, 0.4f, 0.4f, 0.4f*box->active_t); + inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(1.0f, 1.0f, 1.0f, 0.08f*box->active_t); MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -8901,7 +8936,7 @@ rd_window_frame(void) // rjf: draw overlay if(b->flags & UI_BoxFlag_DrawOverlay) { - R_Rect2DInst *inst = dr_rect(b->rect, b->palette->colors[UI_ColorCode_Overlay], 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, b->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -8958,7 +8993,7 @@ rd_window_frame(void) if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - color.w *= 0.2f*b->focus_hot_t; + color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -8982,7 +9017,7 @@ rd_window_frame(void) if(b->disabled_t >= 0.005f) { Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_DisabledOverlay); - color.w *= b->disabled_t; + color.w *= b->disabled_t*0.5f; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 1); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -11909,15 +11944,14 @@ rd_frame(void) // ProfScope("build theme from config") { - rd_state->theme_target = push_array(rd_frame_arena(), RD_Theme, 1); - RD_Theme *theme = rd_state->theme_target; + RD_Theme *theme_srgba = push_array(scratch.arena, RD_Theme, 1); //- rjf: gather globally-applying config options RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("color_preset")); RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("colors")); //- rjf: assume default-dark - MemoryCopy(theme->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); + MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); //- rjf: apply explicitly-specified presets for(RD_CfgNode *n = preset_roots.first; n != 0; n = n->next) @@ -11937,7 +11971,7 @@ rd_frame(void) } if(found_preset_kind) { - MemoryCopy(theme->colors, rd_theme_preset_colors_table[preset_kind], sizeof(rd_theme_preset_colors__default_dark)); + MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[preset_kind], sizeof(rd_theme_preset_colors__default_dark)); } } @@ -11963,11 +11997,19 @@ rd_frame(void) if(try_u64_from_str8_c_rules(color->first->string, &color_val)) { Vec4F32 color_rgba = rgba_from_u32((U32)color_val); - theme->colors[color_code] = color_rgba; + theme_srgba->colors[color_code] = color_rgba; } } } } + + //- rjf: srgba -> linear, compute final theme + rd_state->theme_target = push_array(rd_frame_arena(), RD_Theme, 1); + RD_Theme *theme = rd_state->theme_target; + for EachEnumVal(RD_ThemeColor, c) + { + theme->colors[c] = linear_from_srgba(theme_srgba->colors[c]); + } } ////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 7598f487..4fd2f042 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2759,8 +2759,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } else if(global_row_idx & 1) { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundAlt)); - row_flags |= UI_BoxFlag_DrawBackground; + row_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundAlt; } if(!row_matches_last_row_topology) { @@ -2870,8 +2869,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rgba.w *= 0.2f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); - palette = ui_build_palette(ui_top_palette(), .overlay = rgba); - cell_flags |= UI_BoxFlag_DrawOverlay; + palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); + cell_flags |= UI_BoxFlag_DrawBackground; } else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) @@ -2887,8 +2886,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rgba.w *= 0.2f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); - palette = ui_build_palette(ui_top_palette(), .overlay = rgba); - cell_flags |= UI_BoxFlag_DrawOverlay; + palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); + cell_flags |= UI_BoxFlag_DrawBackground; } } ProfEnd(); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 8aea3796..2fd73467 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -467,7 +467,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->hover_t > 0.001f) { Vec4F32 weak_thread_color = u->thread_color; - weak_thread_color.w *= 0.5f*u->hover_t; + weak_thread_color.w *= 0.15f*u->hover_t; R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->parent->rect.y0, box->rect.x0 + ui_top_font_size()*22.f*u->hover_t, @@ -481,7 +481,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->is_selected && u->do_glow) { Vec4F32 weak_thread_color = u->thread_color; - weak_thread_color.w *= 0.3f; + weak_thread_color.w *= 0.1f; R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->parent->rect.y0, box->rect.x0 + ui_top_font_size()*22.f*u->alive_t, diff --git a/src/render/d3d11/generated/render_d3d11.meta.h b/src/render/d3d11/generated/render_d3d11.meta.h index 370fe2ea..5f5e1f12 100644 --- a/src/render/d3d11/generated/render_d3d11.meta.h +++ b/src/render/d3d11/generated/render_d3d11.meta.h @@ -138,10 +138,10 @@ str8_lit_comp( " };\n" " float4 src_color[] =\n" " {\n" -" linear_from_srgba(cpu2vertex.color01),\n" -" linear_from_srgba(cpu2vertex.color00),\n" -" linear_from_srgba(cpu2vertex.color11),\n" -" linear_from_srgba(cpu2vertex.color10),\n" +" cpu2vertex.color01,\n" +" cpu2vertex.color00,\n" +" cpu2vertex.color11,\n" +" cpu2vertex.color10,\n" " };\n" " float2 dst_verts_pct = float2((cpu2vertex.vertex_id >> 1) ? 1.f : 0.f,\n" " (cpu2vertex.vertex_id & 1) ? 0.f : 1.f);\n" diff --git a/src/render/d3d11/render_d3d11.mdesk b/src/render/d3d11/render_d3d11.mdesk index 4e8796f6..1c78b56b 100644 --- a/src/render/d3d11/render_d3d11.mdesk +++ b/src/render/d3d11/render_d3d11.mdesk @@ -136,10 +136,10 @@ vs_main(CPU2Vertex cpu2vertex) }; float4 src_color[] = { - linear_from_srgba(cpu2vertex.color01), - linear_from_srgba(cpu2vertex.color00), - linear_from_srgba(cpu2vertex.color11), - linear_from_srgba(cpu2vertex.color10), + cpu2vertex.color01, + cpu2vertex.color00, + cpu2vertex.color11, + cpu2vertex.color10, }; float2 dst_verts_pct = float2((cpu2vertex.vertex_id >> 1) ? 1.f : 0.f, (cpu2vertex.vertex_id & 1) ? 0.f : 1.f); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 69ab988f..baac0660 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -223,10 +223,15 @@ typedef enum UI_ColorCode { UI_ColorCode_Null, UI_ColorCode_Background, + UI_ColorCode_BackgroundAlt, + UI_ColorCode_BackgroundGood, + UI_ColorCode_BackgroundBad, + UI_ColorCode_BackgroundPop, + UI_ColorCode_Border, UI_ColorCode_Text, UI_ColorCode_TextWeak, - UI_ColorCode_Border, - UI_ColorCode_Overlay, + UI_ColorCode_Hover, + UI_ColorCode_Focus, UI_ColorCode_Cursor, UI_ColorCode_Selection, UI_ColorCode_COUNT @@ -243,10 +248,15 @@ struct UI_Palette { Vec4F32 null; Vec4F32 background; + Vec4F32 background_alt; + Vec4F32 background_good; + Vec4F32 background_bad; + Vec4F32 background_pop; + Vec4F32 border; Vec4F32 text; Vec4F32 text_weak; - Vec4F32 border; - Vec4F32 overlay; + Vec4F32 hover; + Vec4F32 focus; Vec4F32 cursor; Vec4F32 selection; }; @@ -356,28 +366,29 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_DrawDropShadow (UI_BoxFlags)(1ull<<27) # define UI_BoxFlag_DrawBackgroundBlur (UI_BoxFlags)(1ull<<28) # define UI_BoxFlag_DrawBackground (UI_BoxFlags)(1ull<<29) -# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<30) -# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<31) -# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<32) -# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<33) -# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<34) -# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<35) -# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<36) -# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<37) -# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<38) -# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<39) -# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<40) -# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<41) -# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<42) -# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<43) -# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<44) -# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<45) -# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<46) -# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<47) -# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<48) -# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<49) -# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<50) -# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) +# define UI_BoxFlag_DrawBackgroundAlt (UI_BoxFlags)(1ull<<30) +# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<31) +# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<32) +# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<33) +# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<34) +# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<35) +# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<36) +# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<37) +# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<38) +# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<39) +# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<40) +# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<41) +# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<42) +# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<43) +# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<44) +# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<45) +# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<46) +# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<47) +# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<48) +# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<49) +# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<50) +# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<51) +# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<52) //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) From 6c9f7018f1f805582b959a4a46c8f761cc2832f9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Feb 2025 15:13:59 -0800 Subject: [PATCH 139/755] sketch out tag-based theme, per-window computation --- src/raddbg/generated/raddbg.meta.c | 1606 ++++++++++++++++++++-------- src/raddbg/generated/raddbg.meta.h | 164 ++- src/raddbg/raddbg.mdesk | 370 +++++-- src/raddbg/raddbg_core.c | 547 ++++++---- src/raddbg/raddbg_core.h | 37 +- src/raddbg/raddbg_views.c | 77 +- src/raddbg/raddbg_widgets.c | 112 +- src/ui/generated/ui.meta.c | 6 + src/ui/generated/ui.meta.h | 69 +- src/ui/ui.mdesk | 3 +- src/ui/ui_core.c | 16 + src/ui/ui_core.h | 54 +- 12 files changed, 2076 insertions(+), 985 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c8f34e16..b0b5f6a9 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -807,6 +807,19 @@ str8_lit_comp("four_coder"), str8_lit_comp("far_manager"), }; +String8 rd_theme_preset_cfg_string_table[9] = +{ +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n good: background: 0x222222ff,\n bad: background: 0x222222ff,\n pop: background: 0x222222ff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xe5e5e5ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n good:\n {\n background: 0x2c5b36ff,\n border: 0x3f3f3fff,\n }\n\n bad:\n {\n background: 0x803425ff,\n border: 0xe88774ff,\n }\n\n pop:\n {\n background: 0x355b6eff,\n border: 0x355b6eff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffffff,\n border: 0xffffffff,\n }\n\n code:\n {\n default: text: 0xcbcbcbff,\n symbol: text: 0x42a2cfff,\n type: text: 0xfec746ff,\n local: text: 0x98bc80ff,\n register: text: 0xb7afd5ff,\n keyword: text: 0xb38d4cff,\n delimiter_or_operator: text: 0x767676ff,\n numeric: text: 0x98abb1ff,\n numeric_alt_digit_group: text: 0x738287ff,\n string: text: 0x98abb1ff,\n meta: text: 0xd96759ff,\n comment: text: 0x717171ff,\n line_info_0: background: 0x99503dff,\n line_info_1: background: 0xfe8249ff,\n line_info_2: background: 0xffba17ff,\n line_info_3: background: 0xcefd69ff,\n line_info_4: background: 0x99503dff,\n line_info_5: background: 0xfe8249ff,\n line_info_6: background: 0xcefd69ff,\n line_info_7: background: 0x99503dff,\n }\n\n debug_state:\n {\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n }\n}\n"), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +}; + String8 rd_theme_color_version_remap_old_name_table[22] = { str8_lit_comp("plain_text"), @@ -859,58 +872,119 @@ str8_lit_comp("negative_pop_button_background"), str8_lit_comp("neutral_pop_button_background"), }; -Vec4F32 rd_theme_preset_colors__default_dark[84] = +Vec4F32 rd_theme_preset_colors__default_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0xa4a4a4ff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x99ccffff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x5f1200ff), rgba_from_u32_lit_comp(0x1b1b1bff), rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0x2b3740ff), rgba_from_u32_lit_comp(0x2b3740ff), -rgba_from_u32_lit_comp(0x3e4c57ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0xffc800ff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0xe88774ff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0xffbb00ff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x2b2b2bff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x3f3f3fff), -rgba_from_u32_lit_comp(0x6f5135ff), -rgba_from_u32_lit_comp(0xffa600ff), -rgba_from_u32_lit_comp(0x8a6e54ff), -rgba_from_u32_lit_comp(0x2b3740ff), -rgba_from_u32_lit_comp(0xffa600ff), -rgba_from_u32_lit_comp(0x3e4c57ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x222222ff), +rgba_from_u32_lit_comp(0x404040ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0x42a2cfff), rgba_from_u32_lit_comp(0xfec746ff), @@ -947,58 +1021,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__default_light[84] = +Vec4F32 rd_theme_preset_colors__default_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4d9e2eff), -rgba_from_u32_lit_comp(0xbd371eff), -rgba_from_u32_lit_comp(0x0064a7ff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x699830ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x9c5900ff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x0000004c), -rgba_from_u32_lit_comp(0xa6a6a63f), -rgba_from_u32_lit_comp(0x4848480c), rgba_from_u32_lit_comp(0xa4a4a43f), -rgba_from_u32_lit_comp(0x003d7a48), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0xff30005f), +rgba_from_u32_lit_comp(0x0000004c), rgba_from_u32_lit_comp(0xccccccfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0xeaeaea7f), -rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0xccccccc0), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x65f534ff), -rgba_from_u32_lit_comp(0x65f534ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0xff694cff), -rgba_from_u32_lit_comp(0xff694cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0xa6becaff), -rgba_from_u32_lit_comp(0xa6becaff), -rgba_from_u32_lit_comp(0xa6a6a6fd), -rgba_from_u32_lit_comp(0xa9a9a9fe), -rgba_from_u32_lit_comp(0xa9a9a9fe), -rgba_from_u32_lit_comp(0xc0c0c0fe), -rgba_from_u32_lit_comp(0xa98b6fff), -rgba_from_u32_lit_comp(0xa98b6fff), -rgba_from_u32_lit_comp(0xffffff4d), -rgba_from_u32_lit_comp(0x8282827f), -rgba_from_u32_lit_comp(0x8282827f), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0xccccccfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xa4a4a4fe), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), +rgba_from_u32_lit_comp(0x4c4c4cff), rgba_from_u32_lit_comp(0x4d4d4dff), rgba_from_u32_lit_comp(0x205670fe), rgba_from_u32_lit_comp(0x996b00ff), @@ -1035,58 +1170,119 @@ rgba_from_u32_lit_comp(0xff2800ff), rgba_from_u32_lit_comp(0xa6becaff), }; -Vec4F32 rd_theme_preset_colors__vs_dark[84] = +Vec4F32 rd_theme_preset_colors__vs_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x1b1b1bfd), -rgba_from_u32_lit_comp(0x1b1b1bfd), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x0079ccff), -rgba_from_u32_lit_comp(0x0079ccff), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0xfefefe14), -rgba_from_u32_lit_comp(0xfefefe14), -rgba_from_u32_lit_comp(0xffffff00), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), +rgba_from_u32_lit_comp(0xe5e5e5ff), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xdcdcaaff), rgba_from_u32_lit_comp(0x4ec9afff), @@ -1123,60 +1319,121 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__vs_light[84] = +Vec4F32 rd_theme_preset_colors__vs_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc46451ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x002affff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xa3a3a37e), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000000c), rgba_from_u32_lit_comp(0xfefefe53), -rgba_from_u32_lit_comp(0x3d74ab4b), -rgba_from_u32_lit_comp(0x0000001e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0xa3a3a37e), rgba_from_u32_lit_comp(0xfefefefe), rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xffffff7f), -rgba_from_u32_lit_comp(0xffffff7f), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xfefefec7), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x84ce93ff), -rgba_from_u32_lit_comp(0x84ce93ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xbd3e24ff), -rgba_from_u32_lit_comp(0xbd3e24ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x6e9db5ff), -rgba_from_u32_lit_comp(0x6e9db5ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xe8e8e8fe), -rgba_from_u32_lit_comp(0xe8e8e8fe), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xfffffffe), -rgba_from_u32_lit_comp(0xfffffffe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0xcdd4dc7f), -rgba_from_u32_lit_comp(0xcdd4dc7f), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0xfefefefe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), +rgba_from_u32_lit_comp(0xe7e7e7fe), rgba_from_u32_lit_comp(0xb6b6b6ff), rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), +rgba_from_u32_lit_comp(0x000000ff), rgba_from_u32_lit_comp(0xa33700ff), rgba_from_u32_lit_comp(0x007666ff), rgba_from_u32_lit_comp(0xb7afd5ff), @@ -1211,58 +1468,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x6e9db5ff), }; -Vec4F32 rd_theme_preset_colors__solarized_dark[84] = +Vec4F32 rd_theme_preset_colors__solarized_dark[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x9999998a), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x002a35fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x00202bff), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x007fa14e), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0xfdfdfd3a), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x2c5b36ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x803425ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x355b6eff), -rgba_from_u32_lit_comp(0x355b6eff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x005e77fe), -rgba_from_u32_lit_comp(0x005e77fe), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x005e77fe), -rgba_from_u32_lit_comp(0x005e77fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x002a35fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0xfefefe3a), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), +rgba_from_u32_lit_comp(0x999999ff), rgba_from_u32_lit_comp(0xcbcbcbff), rgba_from_u32_lit_comp(0xcb4a15ff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1299,58 +1617,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x355b6eff), }; -Vec4F32 rd_theme_preset_colors__solarized_light[84] = +Vec4F32 rd_theme_preset_colors__solarized_light[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x818181ff), -rgba_from_u32_lit_comp(0x586e75ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x92743dff), -rgba_from_u32_lit_comp(0x747474ff), -rgba_from_u32_lit_comp(0xc9bfa394), -rgba_from_u32_lit_comp(0xe4dac090), -rgba_from_u32_lit_comp(0xffffff0c), rgba_from_u32_lit_comp(0x0000001c), -rgba_from_u32_lit_comp(0x678cb24c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), +rgba_from_u32_lit_comp(0xc9bfa394), rgba_from_u32_lit_comp(0xfcf5e2fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xeee8d5ff), -rgba_from_u32_lit_comp(0x3e4c577f), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xffffff7c), -rgba_from_u32_lit_comp(0x33333333), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0xbdb9aa00), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xb6ddbeff), -rgba_from_u32_lit_comp(0xb6ddbeff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xf8b0a1ff), -rgba_from_u32_lit_comp(0xf8b0a1ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xb2d3e3ff), -rgba_from_u32_lit_comp(0xb2d3e3ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xe3dbc7fe), -rgba_from_u32_lit_comp(0xe3dbc7fe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xfdf6e3ff), -rgba_from_u32_lit_comp(0xfdf6e3ff), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0xd4cfc0fe), -rgba_from_u32_lit_comp(0xd4cfc0fe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0xfcf5e2fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0xbebaabfe), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), +rgba_from_u32_lit_comp(0x333333ff), rgba_from_u32_lit_comp(0x657b83ff), rgba_from_u32_lit_comp(0xcb4a15ff), rgba_from_u32_lit_comp(0xcb4a15ff), @@ -1387,58 +1766,119 @@ rgba_from_u32_lit_comp(0xff684bff), rgba_from_u32_lit_comp(0xb2d3e3ff), }; -Vec4F32 rd_theme_preset_colors__handmade_hero[84] = +Vec4F32 rd_theme_preset_colors__handmade_hero[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x6e512eff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x0c0c0cfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x0c0c0c32), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x423425fe), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x132e19ff), -rgba_from_u32_lit_comp(0x132e19ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x15445cff), -rgba_from_u32_lit_comp(0x15445cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0x1f1f27fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x131315ee), -rgba_from_u32_lit_comp(0x131315ee), -rgba_from_u32_lit_comp(0xffffff19), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x423525fe), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), +rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0xa08462ff), rgba_from_u32_lit_comp(0xcc5634ff), rgba_from_u32_lit_comp(0xd8a51bff), @@ -1475,58 +1915,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x15445cff), }; -Vec4F32 rd_theme_preset_colors__four_coder[84] = +Vec4F32 rd_theme_preset_colors__four_coder[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x566e4bff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0xfda200ff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x0c0c0cfe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xffffff19), -rgba_from_u32_lit_comp(0x0c0c0c3e), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x152f1bff), -rgba_from_u32_lit_comp(0x152f1bff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x43150cff), -rgba_from_u32_lit_comp(0x43150cff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x1b323eff), -rgba_from_u32_lit_comp(0x1b323eff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x212721fe), -rgba_from_u32_lit_comp(0x212721fe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x212721fe), -rgba_from_u32_lit_comp(0x212721fe), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3a3a3a7f), -rgba_from_u32_lit_comp(0x3a3a3a7f), -rgba_from_u32_lit_comp(0x00000019), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x0c0c0cfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x3f3f3ffe), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), +rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x90b080ff), rgba_from_u32_lit_comp(0x42a2cffe), rgba_from_u32_lit_comp(0xfd7c52ff), @@ -1563,58 +2064,119 @@ rgba_from_u32_lit_comp(0xa72911ff), rgba_from_u32_lit_comp(0x1b323eff), }; -Vec4F32 rd_theme_preset_colors__far_manager[84] = +Vec4F32 rd_theme_preset_colors__far_manager[145] = { rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x4dc221ff), -rgba_from_u32_lit_comp(0xc56452ff), -rgba_from_u32_lit_comp(0x307eb2ff), -rgba_from_u32_lit_comp(0x00a9a9ff), -rgba_from_u32_lit_comp(0x8aff00ff), -rgba_from_u32_lit_comp(0xb23217ff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0xffffffff), +rgba_from_u32_lit_comp(0x0000003f), rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0xffffff0c), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x99ccff4c), -rgba_from_u32_lit_comp(0xffffff1e), -rgba_from_u32_lit_comp(0x5f12005f), rgba_from_u32_lit_comp(0x000081fe), rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0xfefefe00), -rgba_from_u32_lit_comp(0x007c7c55), -rgba_from_u32_lit_comp(0x33333333), -rgba_from_u32_lit_comp(0x00ffff55), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x00000000), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x2c5b36ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x803425ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x933100ff), -rgba_from_u32_lit_comp(0x933100ff), -rgba_from_u32_lit_comp(0x3f3f3ffd), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0xfefefe4d), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0x3e4c577f), -rgba_from_u32_lit_comp(0xfefefe19), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x000081fe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x2b2b2bfe), +rgba_from_u32_lit_comp(0x0000fffe), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), +rgba_from_u32_lit_comp(0x00fefeff), rgba_from_u32_lit_comp(0x00fefeff), rgba_from_u32_lit_comp(0x65b1ffff), rgba_from_u32_lit_comp(0xfec746ff), @@ -1664,58 +2226,119 @@ rd_theme_preset_colors__four_coder, rd_theme_preset_colors__far_manager, }; -String8 rd_theme_color_display_string_table[84] = +String8 rd_theme_color_display_string_table[145] = { str8_lit_comp("Null"), -str8_lit_comp("Text"), -str8_lit_comp("Text (Positive)"), -str8_lit_comp("Text (Negative)"), -str8_lit_comp("Text (Neutral)"), -str8_lit_comp("Text (Weak)"), -str8_lit_comp("Cursor"), -str8_lit_comp("Cursor (Inactive)"), -str8_lit_comp("Focus"), -str8_lit_comp("Hover"), -str8_lit_comp("Drop Shadow"), -str8_lit_comp("Disabled Overlay"), -str8_lit_comp("Drop Site Overlay"), str8_lit_comp("Inactive Panel Overlay"), -str8_lit_comp("Selection Overlay"), -str8_lit_comp("Highlight Overlay"), -str8_lit_comp("Error Highlight Overlay"), +str8_lit_comp("Drop Shadow"), str8_lit_comp("Base Background"), str8_lit_comp("Base Background (Alternate)"), +str8_lit_comp("Base Background (Good)"), +str8_lit_comp("Base Background (Bad)"), +str8_lit_comp("Base Background (Pop)"), str8_lit_comp("Base Border"), +str8_lit_comp("Base Text"), +str8_lit_comp("Base Text (Weak)"), +str8_lit_comp("Base Hover"), +str8_lit_comp("Base Focus"), +str8_lit_comp("Base Cursor"), +str8_lit_comp("Base Selection"), str8_lit_comp("Menu Bar Background"), str8_lit_comp("Menu Bar Background (Alternate)"), +str8_lit_comp("Menu Bar Background (Good)"), +str8_lit_comp("Menu Bar Background (Bad)"), +str8_lit_comp("Menu Bar Background (Pop)"), str8_lit_comp("Menu Bar Border"), -str8_lit_comp("Floating Background"), -str8_lit_comp("Floating Background (Alternate)"), -str8_lit_comp("Floating Border"), -str8_lit_comp("Implicit Button Background"), -str8_lit_comp("Implicit Button Hover"), -str8_lit_comp("Implicit Button Border"), -str8_lit_comp("Plain Button Background"), -str8_lit_comp("Plain Button Hover"), -str8_lit_comp("Plain Button Border"), -str8_lit_comp("Positive Pop Button Background"), -str8_lit_comp("Positive Pop Button Hover"), -str8_lit_comp("Positive Pop Button Border"), -str8_lit_comp("Negative Pop Button Background"), -str8_lit_comp("Negative Pop Button Hover"), -str8_lit_comp("Negative Pop Button Border"), -str8_lit_comp("Neutral Pop Button Background"), -str8_lit_comp("Neutral Pop Button Hover"), -str8_lit_comp("Neutral Pop Button Border"), -str8_lit_comp("Scroll Bar Button Background"), -str8_lit_comp("Scroll Bar Button Hover"), -str8_lit_comp("Scroll Bar Button Border"), +str8_lit_comp("Menu Bar Text"), +str8_lit_comp("Menu Bar Text (Weak)"), +str8_lit_comp("Menu Bar Hover"), +str8_lit_comp("Menu Bar Focus"), +str8_lit_comp("Menu Bar Cursor"), +str8_lit_comp("Menu Bar Selection"), +str8_lit_comp("Good Background"), +str8_lit_comp("Good Background (Alternate)"), +str8_lit_comp("Good Background (Good)"), +str8_lit_comp("Good Background (Bad)"), +str8_lit_comp("Good Background (Pop)"), +str8_lit_comp("Good Border"), +str8_lit_comp("Good Text"), +str8_lit_comp("Good Text (Weak)"), +str8_lit_comp("Good Hover"), +str8_lit_comp("Good Focus"), +str8_lit_comp("Good Cursor"), +str8_lit_comp("Good Selection"), +str8_lit_comp("Bad Background"), +str8_lit_comp("Bad Background (Alternate)"), +str8_lit_comp("Bad Background (Good)"), +str8_lit_comp("Bad Background (Bad)"), +str8_lit_comp("Bad Background (Pop)"), +str8_lit_comp("Bad Border"), +str8_lit_comp("Bad Text"), +str8_lit_comp("Bad Text (Weak)"), +str8_lit_comp("Bad Hover"), +str8_lit_comp("Bad Focus"), +str8_lit_comp("Bad Cursor"), +str8_lit_comp("Bad Selection"), +str8_lit_comp("Pop Background"), +str8_lit_comp("Pop Background (Alternate)"), +str8_lit_comp("Pop Background (Good)"), +str8_lit_comp("Pop Background (Bad)"), +str8_lit_comp("Pop Background (Pop)"), +str8_lit_comp("Pop Border"), +str8_lit_comp("Pop Text"), +str8_lit_comp("Pop Text (Weak)"), +str8_lit_comp("Pop Hover"), +str8_lit_comp("Pop Focus"), +str8_lit_comp("Pop Cursor"), +str8_lit_comp("Pop Selection"), +str8_lit_comp("Scroll Bar Background"), +str8_lit_comp("Scroll Bar Background (Alternate)"), +str8_lit_comp("Scroll Bar Background (Good)"), +str8_lit_comp("Scroll Bar Background (Bad)"), +str8_lit_comp("Scroll Bar Background (Pop)"), +str8_lit_comp("Scroll Bar Border"), +str8_lit_comp("Scroll Bar Text"), +str8_lit_comp("Scroll Bar Text (Weak)"), +str8_lit_comp("Scroll Bar Hover"), +str8_lit_comp("Scroll Bar Focus"), +str8_lit_comp("Scroll Bar Cursor"), +str8_lit_comp("Scroll Bar Selection"), str8_lit_comp("Tab Background"), -str8_lit_comp("Tab Hover"), +str8_lit_comp("Tab Background (Alternate)"), +str8_lit_comp("Tab Background (Good)"), +str8_lit_comp("Tab Background (Bad)"), +str8_lit_comp("Tab Background (Pop)"), str8_lit_comp("Tab Border"), -str8_lit_comp("Tab Background (Inactive)"), -str8_lit_comp("Tab Hover (Inactive)"), -str8_lit_comp("Tab Border (Inactive)"), +str8_lit_comp("Tab Text"), +str8_lit_comp("Tab Text (Weak)"), +str8_lit_comp("Tab Hover"), +str8_lit_comp("Tab Focus"), +str8_lit_comp("Tab Cursor"), +str8_lit_comp("Tab Selection"), +str8_lit_comp("Tab (Inactive) Background"), +str8_lit_comp("Tab (Inactive) Background (Alternate)"), +str8_lit_comp("Tab (Inactive) Background (Good)"), +str8_lit_comp("Tab (Inactive) Background (Bad)"), +str8_lit_comp("Tab (Inactive) Background (Pop)"), +str8_lit_comp("Tab (Inactive) Border"), +str8_lit_comp("Tab (Inactive) Text"), +str8_lit_comp("Tab (Inactive) Text (Weak)"), +str8_lit_comp("Tab (Inactive) Hover"), +str8_lit_comp("Tab (Inactive) Focus"), +str8_lit_comp("Tab (Inactive) Cursor"), +str8_lit_comp("Tab (Inactive) Selection"), +str8_lit_comp("Drop Site Background"), +str8_lit_comp("Drop Site Background (Alternate)"), +str8_lit_comp("Drop Site Background (Good)"), +str8_lit_comp("Drop Site Background (Bad)"), +str8_lit_comp("Drop Site Background (Pop)"), +str8_lit_comp("Drop Site Border"), +str8_lit_comp("Drop Site Text"), +str8_lit_comp("Drop Site Text (Weak)"), +str8_lit_comp("Drop Site Hover"), +str8_lit_comp("Drop Site Focus"), +str8_lit_comp("Drop Site Cursor"), +str8_lit_comp("Drop Site Selection"), str8_lit_comp("Code (Default)"), str8_lit_comp("Code (Symbol)"), str8_lit_comp("Code (Type)"), @@ -1752,58 +2375,119 @@ str8_lit_comp("Breakpoint"), str8_lit_comp("Cache Line Boundary"), }; -String8 rd_theme_color_cfg_string_table[84] = +String8 rd_theme_color_cfg_string_table[145] = { str8_lit_comp("null"), -str8_lit_comp("text"), -str8_lit_comp("text_positive"), -str8_lit_comp("text_negative"), -str8_lit_comp("text_neutral"), -str8_lit_comp("text_weak"), -str8_lit_comp("cursor"), -str8_lit_comp("cursor_inactive"), -str8_lit_comp("focus"), -str8_lit_comp("hover"), -str8_lit_comp("drop_shadow"), -str8_lit_comp("disabled_overlay"), -str8_lit_comp("drop_site_overlay"), str8_lit_comp("inactive_panel_overlay"), -str8_lit_comp("selection_overlay"), -str8_lit_comp("highlight_overlay"), -str8_lit_comp("error_highlight_overlay"), +str8_lit_comp("drop_shadow"), str8_lit_comp("base_background"), str8_lit_comp("base_background_alt"), +str8_lit_comp("base_background_good"), +str8_lit_comp("base_background_bad"), +str8_lit_comp("base_background_pop"), str8_lit_comp("base_border"), +str8_lit_comp("base_text"), +str8_lit_comp("base_text_weak"), +str8_lit_comp("base_hover"), +str8_lit_comp("base_focus"), +str8_lit_comp("base_cursor"), +str8_lit_comp("base_cursor"), str8_lit_comp("menu_bar_background"), str8_lit_comp("menu_bar_background_alt"), +str8_lit_comp("menu_bar_background_good"), +str8_lit_comp("menu_bar_background_bad"), +str8_lit_comp("menu_bar_background_pop"), str8_lit_comp("menu_bar_border"), -str8_lit_comp("floating_background"), -str8_lit_comp("floating_background_alt"), -str8_lit_comp("floating_border"), -str8_lit_comp("implicit_button_background"), -str8_lit_comp("implicit_button_hover"), -str8_lit_comp("implicit_button_border"), -str8_lit_comp("plain_button_background"), -str8_lit_comp("plain_button_hover"), -str8_lit_comp("plain_button_border"), -str8_lit_comp("positive_pop_button_background"), -str8_lit_comp("positive_pop_button_hover"), -str8_lit_comp("positive_pop_button_border"), -str8_lit_comp("negative_pop_button_background"), -str8_lit_comp("negative_pop_button_hover"), -str8_lit_comp("negative_pop_button_border"), -str8_lit_comp("neutral_pop_button_background"), -str8_lit_comp("neutral_pop_button_hover"), -str8_lit_comp("neutral_pop_button_border"), -str8_lit_comp("scroll_bar_button_background"), -str8_lit_comp("scroll_bar_button_hover"), -str8_lit_comp("scroll_bar_button_border"), +str8_lit_comp("menu_bar_text"), +str8_lit_comp("menu_bar_text_weak"), +str8_lit_comp("menu_bar_hover"), +str8_lit_comp("menu_bar_focus"), +str8_lit_comp("menu_bar_cursor"), +str8_lit_comp("menu_bar_cursor"), +str8_lit_comp("good_background"), +str8_lit_comp("good_background_alt"), +str8_lit_comp("good_background_good"), +str8_lit_comp("good_background_bad"), +str8_lit_comp("good_background_pop"), +str8_lit_comp("good_border"), +str8_lit_comp("good_text"), +str8_lit_comp("good_text_weak"), +str8_lit_comp("good_hover"), +str8_lit_comp("good_focus"), +str8_lit_comp("good_cursor"), +str8_lit_comp("good_cursor"), +str8_lit_comp("bad_background"), +str8_lit_comp("bad_background_alt"), +str8_lit_comp("bad_background_good"), +str8_lit_comp("bad_background_bad"), +str8_lit_comp("bad_background_pop"), +str8_lit_comp("bad_border"), +str8_lit_comp("bad_text"), +str8_lit_comp("bad_text_weak"), +str8_lit_comp("bad_hover"), +str8_lit_comp("bad_focus"), +str8_lit_comp("bad_cursor"), +str8_lit_comp("bad_cursor"), +str8_lit_comp("pop_background"), +str8_lit_comp("pop_background_alt"), +str8_lit_comp("pop_background_good"), +str8_lit_comp("pop_background_bad"), +str8_lit_comp("pop_background_pop"), +str8_lit_comp("pop_border"), +str8_lit_comp("pop_text"), +str8_lit_comp("pop_text_weak"), +str8_lit_comp("pop_hover"), +str8_lit_comp("pop_focus"), +str8_lit_comp("pop_cursor"), +str8_lit_comp("pop_cursor"), +str8_lit_comp("scroll_bar_background"), +str8_lit_comp("scroll_bar_background_alt"), +str8_lit_comp("scroll_bar_background_good"), +str8_lit_comp("scroll_bar_background_bad"), +str8_lit_comp("scroll_bar_background_pop"), +str8_lit_comp("scroll_bar_border"), +str8_lit_comp("scroll_bar_text"), +str8_lit_comp("scroll_bar_text_weak"), +str8_lit_comp("scroll_bar_hover"), +str8_lit_comp("scroll_bar_focus"), +str8_lit_comp("scroll_bar_cursor"), +str8_lit_comp("scroll_bar_cursor"), str8_lit_comp("tab_background"), -str8_lit_comp("tab_hover"), +str8_lit_comp("tab_background_alt"), +str8_lit_comp("tab_background_good"), +str8_lit_comp("tab_background_bad"), +str8_lit_comp("tab_background_pop"), str8_lit_comp("tab_border"), -str8_lit_comp("tab_background_inactive"), -str8_lit_comp("tab_hover_inactive"), -str8_lit_comp("tab_border_inactive"), +str8_lit_comp("tab_text"), +str8_lit_comp("tab_text_weak"), +str8_lit_comp("tab_hover"), +str8_lit_comp("tab_focus"), +str8_lit_comp("tab_cursor"), +str8_lit_comp("tab_cursor"), +str8_lit_comp("tab_inactive_background"), +str8_lit_comp("tab_inactive_background_alt"), +str8_lit_comp("tab_inactive_background_good"), +str8_lit_comp("tab_inactive_background_bad"), +str8_lit_comp("tab_inactive_background_pop"), +str8_lit_comp("tab_inactive_border"), +str8_lit_comp("tab_inactive_text"), +str8_lit_comp("tab_inactive_text_weak"), +str8_lit_comp("tab_inactive_hover"), +str8_lit_comp("tab_inactive_focus"), +str8_lit_comp("tab_inactive_cursor"), +str8_lit_comp("tab_inactive_cursor"), +str8_lit_comp("drop_site_background"), +str8_lit_comp("drop_site_background_alt"), +str8_lit_comp("drop_site_background_good"), +str8_lit_comp("drop_site_background_bad"), +str8_lit_comp("drop_site_background_pop"), +str8_lit_comp("drop_site_border"), +str8_lit_comp("drop_site_text"), +str8_lit_comp("drop_site_text_weak"), +str8_lit_comp("drop_site_hover"), +str8_lit_comp("drop_site_focus"), +str8_lit_comp("drop_site_cursor"), +str8_lit_comp("drop_site_cursor"), str8_lit_comp("code_default"), str8_lit_comp("code_symbol"), str8_lit_comp("code_type"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e079cef6..954e4d60 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -344,55 +344,116 @@ RD_IconKind_COUNT, typedef enum RD_ThemeColor { RD_ThemeColor_Null, -RD_ThemeColor_Text, -RD_ThemeColor_TextPositive, -RD_ThemeColor_TextNegative, -RD_ThemeColor_TextNeutral, -RD_ThemeColor_TextWeak, -RD_ThemeColor_Cursor, -RD_ThemeColor_CursorInactive, -RD_ThemeColor_Focus, -RD_ThemeColor_Hover, -RD_ThemeColor_DropShadow, -RD_ThemeColor_DisabledOverlay, -RD_ThemeColor_DropSiteOverlay, RD_ThemeColor_InactivePanelOverlay, -RD_ThemeColor_SelectionOverlay, -RD_ThemeColor_HighlightOverlay, -RD_ThemeColor_HighlightOverlayError, +RD_ThemeColor_DropShadow, RD_ThemeColor_BaseBackground, RD_ThemeColor_BaseBackgroundAlt, +RD_ThemeColor_BaseBackgroundGood, +RD_ThemeColor_BaseBackgroundBad, +RD_ThemeColor_BaseBackgroundPop, RD_ThemeColor_BaseBorder, +RD_ThemeColor_BaseText, +RD_ThemeColor_BaseTextWeak, +RD_ThemeColor_BaseHover, +RD_ThemeColor_BaseFocus, +RD_ThemeColor_BaseCursor, +RD_ThemeColor_BaseSelection, RD_ThemeColor_MenuBarBackground, RD_ThemeColor_MenuBarBackgroundAlt, +RD_ThemeColor_MenuBarBackgroundGood, +RD_ThemeColor_MenuBarBackgroundBad, +RD_ThemeColor_MenuBarBackgroundPop, RD_ThemeColor_MenuBarBorder, -RD_ThemeColor_FloatingBackground, -RD_ThemeColor_FloatingBackgroundAlt, -RD_ThemeColor_FloatingBorder, -RD_ThemeColor_ImplicitButtonBackground, -RD_ThemeColor_ImplicitButtonHover, -RD_ThemeColor_ImplicitButtonBorder, -RD_ThemeColor_PlainButtonBackground, -RD_ThemeColor_PlainButtonHover, -RD_ThemeColor_PlainButtonBorder, -RD_ThemeColor_PositivePopButtonBackground, -RD_ThemeColor_PositivePopButtonHover, -RD_ThemeColor_PositivePopButtonBorder, -RD_ThemeColor_NegativePopButtonBackground, -RD_ThemeColor_NegativePopButtonHover, -RD_ThemeColor_NegativePopButtonBorder, -RD_ThemeColor_NeutralPopButtonBackground, -RD_ThemeColor_NeutralPopButtonHover, -RD_ThemeColor_NeutralPopButtonBorder, -RD_ThemeColor_ScrollBarButtonBackground, -RD_ThemeColor_ScrollBarButtonHover, -RD_ThemeColor_ScrollBarButtonBorder, +RD_ThemeColor_MenuBarText, +RD_ThemeColor_MenuBarTextWeak, +RD_ThemeColor_MenuBarHover, +RD_ThemeColor_MenuBarFocus, +RD_ThemeColor_MenuBarCursor, +RD_ThemeColor_MenuBarSelection, +RD_ThemeColor_GoodBackground, +RD_ThemeColor_GoodBackgroundAlt, +RD_ThemeColor_GoodBackgroundGood, +RD_ThemeColor_GoodBackgroundBad, +RD_ThemeColor_GoodBackgroundPop, +RD_ThemeColor_GoodBorder, +RD_ThemeColor_GoodText, +RD_ThemeColor_GoodTextWeak, +RD_ThemeColor_GoodHover, +RD_ThemeColor_GoodFocus, +RD_ThemeColor_GoodCursor, +RD_ThemeColor_GoodSelection, +RD_ThemeColor_BadBackground, +RD_ThemeColor_BadBackgroundAlt, +RD_ThemeColor_BadBackgroundGood, +RD_ThemeColor_BadBackgroundBad, +RD_ThemeColor_BadBackgroundPop, +RD_ThemeColor_BadBorder, +RD_ThemeColor_BadText, +RD_ThemeColor_BadTextWeak, +RD_ThemeColor_BadHover, +RD_ThemeColor_BadFocus, +RD_ThemeColor_BadCursor, +RD_ThemeColor_BadSelection, +RD_ThemeColor_PopBackground, +RD_ThemeColor_PopBackgroundAlt, +RD_ThemeColor_PopBackgroundGood, +RD_ThemeColor_PopBackgroundBad, +RD_ThemeColor_PopBackgroundPop, +RD_ThemeColor_PopBorder, +RD_ThemeColor_PopText, +RD_ThemeColor_PopTextWeak, +RD_ThemeColor_PopHover, +RD_ThemeColor_PopFocus, +RD_ThemeColor_PopCursor, +RD_ThemeColor_PopSelection, +RD_ThemeColor_ScrollBarBackground, +RD_ThemeColor_ScrollBarBackgroundAlt, +RD_ThemeColor_ScrollBarBackgroundGood, +RD_ThemeColor_ScrollBarBackgroundBad, +RD_ThemeColor_ScrollBarBackgroundPop, +RD_ThemeColor_ScrollBarBorder, +RD_ThemeColor_ScrollBarText, +RD_ThemeColor_ScrollBarTextWeak, +RD_ThemeColor_ScrollBarHover, +RD_ThemeColor_ScrollBarFocus, +RD_ThemeColor_ScrollBarCursor, +RD_ThemeColor_ScrollBarSelection, RD_ThemeColor_TabBackground, -RD_ThemeColor_TabHover, +RD_ThemeColor_TabBackgroundAlt, +RD_ThemeColor_TabBackgroundGood, +RD_ThemeColor_TabBackgroundBad, +RD_ThemeColor_TabBackgroundPop, RD_ThemeColor_TabBorder, -RD_ThemeColor_TabBackgroundInactive, -RD_ThemeColor_TabHoverInactive, -RD_ThemeColor_TabBorderInactive, +RD_ThemeColor_TabText, +RD_ThemeColor_TabTextWeak, +RD_ThemeColor_TabHover, +RD_ThemeColor_TabFocus, +RD_ThemeColor_TabCursor, +RD_ThemeColor_TabSelection, +RD_ThemeColor_TabInactiveBackground, +RD_ThemeColor_TabInactiveBackgroundAlt, +RD_ThemeColor_TabInactiveBackgroundGood, +RD_ThemeColor_TabInactiveBackgroundBad, +RD_ThemeColor_TabInactiveBackgroundPop, +RD_ThemeColor_TabInactiveBorder, +RD_ThemeColor_TabInactiveText, +RD_ThemeColor_TabInactiveTextWeak, +RD_ThemeColor_TabInactiveHover, +RD_ThemeColor_TabInactiveFocus, +RD_ThemeColor_TabInactiveCursor, +RD_ThemeColor_TabInactiveSelection, +RD_ThemeColor_DropSiteBackground, +RD_ThemeColor_DropSiteBackgroundAlt, +RD_ThemeColor_DropSiteBackgroundGood, +RD_ThemeColor_DropSiteBackgroundBad, +RD_ThemeColor_DropSiteBackgroundPop, +RD_ThemeColor_DropSiteBorder, +RD_ThemeColor_DropSiteText, +RD_ThemeColor_DropSiteTextWeak, +RD_ThemeColor_DropSiteHover, +RD_ThemeColor_DropSiteFocus, +RD_ThemeColor_DropSiteCursor, +RD_ThemeColor_DropSiteSelection, RD_ThemeColor_CodeDefault, RD_ThemeColor_CodeSymbol, RD_ThemeColor_CodeType, @@ -571,20 +632,21 @@ extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; +extern String8 rd_theme_preset_cfg_string_table[9]; extern String8 rd_theme_color_version_remap_old_name_table[22]; extern String8 rd_theme_color_version_remap_new_name_table[22]; -extern Vec4F32 rd_theme_preset_colors__default_dark[84]; -extern Vec4F32 rd_theme_preset_colors__default_light[84]; -extern Vec4F32 rd_theme_preset_colors__vs_dark[84]; -extern Vec4F32 rd_theme_preset_colors__vs_light[84]; -extern Vec4F32 rd_theme_preset_colors__solarized_dark[84]; -extern Vec4F32 rd_theme_preset_colors__solarized_light[84]; -extern Vec4F32 rd_theme_preset_colors__handmade_hero[84]; -extern Vec4F32 rd_theme_preset_colors__four_coder[84]; -extern Vec4F32 rd_theme_preset_colors__far_manager[84]; +extern Vec4F32 rd_theme_preset_colors__default_dark[145]; +extern Vec4F32 rd_theme_preset_colors__default_light[145]; +extern Vec4F32 rd_theme_preset_colors__vs_dark[145]; +extern Vec4F32 rd_theme_preset_colors__vs_light[145]; +extern Vec4F32 rd_theme_preset_colors__solarized_dark[145]; +extern Vec4F32 rd_theme_preset_colors__solarized_light[145]; +extern Vec4F32 rd_theme_preset_colors__handmade_hero[145]; +extern Vec4F32 rd_theme_preset_colors__four_coder[145]; +extern Vec4F32 rd_theme_preset_colors__far_manager[145]; extern Vec4F32* rd_theme_preset_colors_table[9]; -extern String8 rd_theme_color_display_string_table[84]; -extern String8 rd_theme_color_cfg_string_table[84]; +extern String8 rd_theme_color_display_string_table[145]; +extern String8 rd_theme_color_cfg_string_table[145]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a5395ca8..a196fe68 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -979,10 +979,116 @@ RD_ViewRuleTable: //////////////////////////////// //~ rjf: Theme Tables -@table(name_upper name_lower display_string) +@table(name_upper name_lower display_string cfg) RD_ThemePresetTable: { - { DefaultDark default_dark "Default (Dark)" } + //- rjf: default dark theme + { + DefaultDark default_dark "Default (Dark)", + ```theme: + { + background: 0x1b1b1bff, + alt: background: 0x222222ff, + good: background: 0x222222ff, + bad: background: 0x222222ff, + pop: background: 0x222222ff, + border: 0x404040ff, + text: 0xe5e5e5ff, + weak: text: 0xe5e5e5ff, + hover: 0xffffffff, + focus: 0xfda200ff, + cursor: 0x8aff00ff, + selection: 0x99ccffff, + + menu_bar: + { + background: 0x2b3740ff, + border: 0x3e4c57ff, + } + + good: + { + background: 0x2c5b36ff, + border: 0x3f3f3fff, + } + + bad: + { + background: 0x803425ff, + border: 0xe88774ff, + } + + pop: + { + background: 0x355b6eff, + border: 0x355b6eff, + } + + scroll_bar: + { + background: 0x2b2b2bff, + border: 0x3f3f3fff, + } + + tab: + { + background: 0x6f5135ff, + border: 0x8a6e54ff, + inactive: + { + background: 0x2b3740ff, + border: 0x3e4c57ff, + } + } + + drop_site: + { + background: 0xffffffff, + border: 0xffffffff, + } + + code: + { + default: text: 0xcbcbcbff, + symbol: text: 0x42a2cfff, + type: text: 0xfec746ff, + local: text: 0x98bc80ff, + register: text: 0xb7afd5ff, + keyword: text: 0xb38d4cff, + delimiter_or_operator: text: 0x767676ff, + numeric: text: 0x98abb1ff, + numeric_alt_digit_group: text: 0x738287ff, + string: text: 0x98abb1ff, + meta: text: 0xd96759ff, + comment: text: 0x717171ff, + line_info_0: background: 0x99503dff, + line_info_1: background: 0xfe8249ff, + line_info_2: background: 0xffba17ff, + line_info_3: background: 0xcefd69ff, + line_info_4: background: 0x99503dff, + line_info_5: background: 0xfe8249ff, + line_info_6: background: 0xcefd69ff, + line_info_7: background: 0x99503dff, + } + + debug_state: + { + thread_0: 0xffcb7fff, + thread_1: 0xb2ff65ff, + thread_2: 0xff99e5ff, + thread_3: 0x6598ffff, + thread_4: 0x65ffcbff, + thread_5: 0xff9819ff, + thread_6: 0x9932ffff, + thread_7: 0x65ff4cff, + thread_unwound: 0xb2ccd8ff, + thread_error: 0xb23219ff, + breakpoint: 0xa72911ff, + } + } + ``` + } + { DefaultLight default_light "Default (Light)" } { VSDark vs_dark "VS (Dark)" } { VSLight vs_light "VS (Light)" } @@ -993,107 +1099,178 @@ RD_ThemePresetTable: { FarManager far_manager "Far Manager" } } -@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) +@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) RD_ThemeColorTable: { - {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} + {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} - //- rjf: global ui colors - {Text "Text" text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TextPositive "Text (Positive)" text_positive 0x4dc221ff 0x4d9e2eff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff 0x4dc221ff ""} - {TextNegative "Text (Negative)" text_negative 0xc56452ff 0xbd371eff 0xc56452ff 0xc46451ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff 0xc56452ff ""} - {TextNeutral "Text (Neutral)" text_neutral 0x307eb2ff 0x0064a7ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff 0x307eb2ff ""} - {TextWeak "Text (Weak)" text_weak 0xa4a4a4ff 0x4c4c4cff 0xa4a4a4fe 0x0000007f 0x9999998a 0x818181ff 0x6e512eff 0x566e4bff 0x00a9a9ff ""} - {Cursor "Cursor" cursor 0x8aff00ff 0x699830ff 0x8aff00ff 0x000000ff 0x8aff00ff 0x586e75ff 0x8aff00ff 0x8aff00ff 0x8aff00ff ""} - {CursorInactive "Cursor (Inactive)" cursor_inactive 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff 0xb23217ff ""} - {Focus "Focus" focus 0xfda200ff 0x9c5900ff 0xfda200ff 0x002affff 0xfda200ff 0x92743dff 0xfda200ff 0xfda200ff 0x00fefeff ""} - {Hover "Hover" hover 0xffffffff 0xffffffff 0xffffffff 0x000000ff 0xffffffff 0x747474ff 0xffffffff 0xffffffff 0xffffffff ""} - {DropShadow "Drop Shadow" drop_shadow 0x000000ff 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - {DisabledOverlay "Disabled Overlay" disabled_overlay 0x000000ff 0xa6a6a63f 0x0000003f 0x0000003f 0x0000003f 0xe4dac090 0x0000003f 0x0000003f 0x0000003f ""} - {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0xffffffff 0x4848480c 0xffffff0c 0x0000000c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c ""} - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x000000ff 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} - {SelectionOverlay "Selection Overlay" selection_overlay 0x99ccffff 0x003d7a48 0x99ccff4c 0x3d74ab4b 0x99ccff4c 0x678cb24c 0x99ccff4c 0x99ccff4c 0x99ccff4c ""} - {HighlightOverlay "Highlight Overlay" highlight_overlay 0xffffffff 0xffffff1e 0xffffff1e 0x0000001e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e 0xffffff1e ""} - {HighlightOverlayError "Error Highlight Overlay" error_highlight_overlay 0x5f1200ff 0xff30005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f 0x5f12005f ""} + //- rjf: global colors + {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x000000ff 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} + {DropShadow "Drop Shadow" drop_shadow 0x000000ff 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - //- rjf: base ui container colors - {BaseBackground "Base Background" base_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBorder "Base Border" base_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + //- rjf: base palette + {BaseBackground "Base Background" base_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundGood "Base Background (Good)" base_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundBad "Base Background (Bad)" base_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBackgroundPop "Base Background (Pop)" base_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BaseBorder "Base Border" base_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {BaseText "Base Text" base_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseTextWeak "Base Text (Weak)" base_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseHover "Base Hover" base_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseFocus "Base Focus" base_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseCursor "Base Cursor" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BaseSelection "Base Selection" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: menu bar ui container colors - {MenuBarBackground "Menu Bar Background" menu_bar_background 0x2b3740ff 0xeaeaea7f 0x1b1b1bfd 0xffffff7f 0x00202bff 0xeee8d5ff 0x0c0c0cfe 0x0c0c0cfe 0x007d7dff ""} - {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x2b3740ff 0x3e4c577f 0x1b1b1bfd 0xffffff7f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x3e4c577f 0x007d7dff ""} - {MenuBarBorder "Menu Bar Border" menu_bar_border 0x3e4c57ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0xffffff19 0xfefefe00 ""} + //- rjf: menu bar palette + {MenuBarBackground "Menu Bar Background" menu_bar_background 0x2b3740ff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x2b3740ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundGood "Menu Bar Background (Good)" menu_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundBad "Menu Bar Background (Bad)" menu_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBackgroundPop "Menu Bar Background (Pop)" menu_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {MenuBarBorder "Menu Bar Border" menu_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {MenuBarText "Menu Bar Text" menu_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarTextWeak "Menu Bar Text (Weak)" menu_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarHover "Menu Bar Hover" menu_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarFocus "Menu Bar Focus" menu_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarCursor "Menu Bar Cursor" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {MenuBarSelection "Menu Bar Selection" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: floating ui container colors - {FloatingBackground "Floating Background" floating_background 0x333333ff 0xccccccc0 0x33333333 0xfefefec7 0x007fa14e 0xffffff7c 0x0c0c0c32 0x0c0c0c3e 0x007c7c55 ""} - {FloatingBackgroundAlt "Floating Background (Alternate)" floating_background_alt 0x333333ff 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 0x33333333 ""} - {FloatingBorder "Floating Border" floating_border 0x3f3f3fff 0xa4a4a4fe 0x3f3f3ffd 0xb6b6b6ff 0xfdfdfd3a 0xbebaabfe 0x423425fe 0x3f3f3ffd 0x00ffff55 ""} + //- rjf: good palette + {GoodBackground "Good Background" good_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {GoodBackgroundAlt "Good Background (Alternate)" good_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundGood "Good Background (Good)" good_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundBad "Good Background (Bad)" good_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBackgroundPop "Good Background (Pop)" good_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {GoodBorder "Good Border" good_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {GoodText "Good Text" good_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodTextWeak "Good Text (Weak)" good_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodHover "Good Hover" good_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodFocus "Good Focus" good_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodCursor "Good Cursor" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {GoodSelection "Good Selection" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: ui element colors - {ImplicitButtonBackground "Implicit Button Background" implicit_button_background 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ""} - {ImplicitButtonHover "Implicit Button Hover" implicit_button_hover 0xffffffff 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ""} - {ImplicitButtonBorder "Implicit Button Border" implicit_button_border 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xbdb9aa00 0x00000000 0x00000000 0x00000000 ""} - {PlainButtonBackground "Plain Button Background" plain_button_background 0x1b1b1bff 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} - {PlainButtonHover "Plain Button Hover" plain_button_hover 0xffffffff 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe 0x1b1b1bfe ""} - {PlainButtonBorder "Plain Button Border" plain_button_border 0x3f3f3fff 0x3f3f3ffe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffe 0x3f3f3ffe 0x3f3f3ffe ""} - {PositivePopButtonBackground "Positive Pop Button Background" positive_pop_button_background 0x2c5b36ff 0x65f534ff 0x2c5b36ff 0x84ce93ff 0x2c5b36ff 0xb6ddbeff 0x132e19ff 0x152f1bff 0x2c5b36ff ""} - {PositivePopButtonHover "Positive Pop Button Hover" positive_pop_button_hover 0xffc800ff 0x65f534ff 0x2c5b36ff 0x84ce93ff 0x2c5b36ff 0xb6ddbeff 0x132e19ff 0x152f1bff 0x2c5b36ff ""} - {PositivePopButtonBorder "Positive Pop Button Border" positive_pop_button_border 0x3f3f3fff 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {NegativePopButtonBackground "Negative Pop Button Background" negative_pop_button_background 0x803425ff 0xff694cff 0x803425ff 0xbd3e24ff 0x803425ff 0xf8b0a1ff 0x803425ff 0x43150cff 0x803425ff ""} - {NegativePopButtonHover "Negative Pop Button Hover" negative_pop_button_hover 0xe88774ff 0xff694cff 0x803425ff 0xbd3e24ff 0x803425ff 0xf8b0a1ff 0x803425ff 0x43150cff 0x803425ff ""} - {NegativePopButtonBorder "Negative Pop Button Border" negative_pop_button_border 0x3f3f3fff 0x3f3f3ffd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {NeutralPopButtonBackground "Neutral Pop Button Background" neutral_pop_button_background 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} - {NeutralPopButtonHover "Neutral Pop Button Hover" neutral_pop_button_hover 0xffbb00ff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} - {NeutralPopButtonBorder "Neutral Pop Button Border" neutral_pop_button_border 0x3f3f3fff 0xa6a6a6fd 0x3f3f3ffd 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x3f3f3ffd 0x3f3f3ffd 0x3f3f3ffd ""} - {ScrollBarButtonBackground "Scroll Bar Button Background" scroll_bar_button_background 0x2b2b2bff 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {ScrollBarButtonHover "Scroll Bar Button Hover" scroll_bar_button_hover 0xffffffff 0xa9a9a9fe 0x2b2b2bfe 0xe8e8e8fe 0x005e77fe 0xe3dbc7fe 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {ScrollBarButtonBorder "Scroll Bar Button Border" scroll_bar_button_border 0x3f3f3fff 0xc0c0c0fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0xfefefe4d 0x3f3f3ffe 0x3f3f3ffe ""} - {TabBackground "Tab Background" tab_background 0x6f5135ff 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {TabHover "Tab Hover" tab_hover 0xffa600ff 0xa98b6fff 0x0079ccff 0xfffffffe 0x005e77fe 0xfdf6e3ff 0x1f1f27fe 0x212721fe 0x007d7dff ""} - {TabBorder "Tab Border" tab_border 0x8a6e54ff 0xffffff4d 0xfefefe4d 0xb6b6b6ff 0xfefefe4d 0xbebaabfe 0xfefefe4d 0xfefefe4d 0xfefefe4d ""} - {TabBackgroundInactive "Tab Background (Inactive)" tab_background_inactive 0x2b3740ff 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} - {TabHoverInactive "Tab Hover (Inactive)" tab_hover_inactive 0xffa600ff 0x8282827f 0xfefefe14 0xcdd4dc7f 0x3e4c577f 0xd4cfc0fe 0x131315ee 0x3a3a3a7f 0x3e4c577f ""} - {TabBorderInactive "Tab Border (Inactive)" tab_border_inactive 0x3e4c57ff 0xffffff19 0xffffff00 0xb6b6b6ff 0xffffff19 0xbebaabfe 0xffffff19 0x00000019 0xfefefe19 ""} + //- rjf: bad palette + {BadBackground "Bad Background" bad_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {BadBackgroundAlt "Bad Background (Alternate)" bad_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundGood "Bad Background (Good)" bad_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundBad "Bad Background (Bad)" bad_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBackgroundPop "Bad Background (Pop)" bad_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {BadBorder "Bad Border" bad_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {BadText "Bad Text" bad_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadTextWeak "Bad Text (Weak)" bad_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadHover "Bad Hover" bad_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadFocus "Bad Focus" bad_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadCursor "Bad Cursor" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {BadSelection "Bad Selection" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: code colors - {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cfff 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} - {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} - {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} - {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} - {CodeKeyword "Code (Keyword)" code_keyword 0xb38d4cff 0x573700ff 0x569cd6ff 0x0000ffff 0x849803ff 0x586e75ff 0xac7a09ff 0xd08f1eff 0x00ffffff ""} - {CodeDelimiterOperator "Code (Delimiters/Operators)" code_delimiter_operator 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0xa08462ff 0x90b080ff 0xffffffff ""} - {CodeNumeric "Code (Numeric)" code_numeric 0x98abb1ff 0x3f6e7dff 0xb5cea8ff 0x088658ff 0xd33582ff 0xd33482ef 0x698e21ff 0x4fff2eff 0x00ff00ff ""} - {CodeNumericAltDigitGroup "Code (Numeric, Alt. Digit Group)" code_numeric_alt_digit_group 0x738287ff 0x1f4450ff 0x729360ff 0x0c3828ff 0x902559ff 0x8e2659ff 0x3a4e11ff 0x3ccd21ff 0x738287ff ""} - {CodeString "Code (String)" code_string 0x98abb1ff 0x3c606bff 0xd59b85ff 0xa31414ff 0x1f9d91ff 0x29a198ff 0x6a8e22ff 0x4fff2eff 0x98abb1ff ""} - {CodeMeta "Code (Meta)" code_meta 0xd96759ff 0xad3627ff 0xd59c85ff 0x0000ffff 0x839802ff 0xd96759ff 0xdab98fff 0xa0b8a0ff 0xff0000ff ""} - {CodeComment "Code (Comment)" code_comment 0x717171ff 0x4b4b4bff 0x57a54aff 0x008000ff 0x556a6fff 0x93a1a1ff 0x686868ff 0x1e8fefff 0xffffffff ""} - {CodeLineNumbers "Code Line Numbers" code_line_numbers 0x7f7f7fff 0x4b4b4bff 0x2a91afff 0x227893ff 0x566c73ff 0x227893ef 0xa08462ff 0x7e7e7ffe 0x007d7dff ""} - {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} + //- rjf: pop palette + {PopBackground "Pop Background" pop_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {PopBackgroundAlt "Pop Background (Alternate)" pop_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundGood "Pop Background (Good)" pop_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundBad "Pop Background (Bad)" pop_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBackgroundPop "Pop Background (Pop)" pop_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {PopBorder "Pop Border" pop_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {PopText "Pop Text" pop_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopTextWeak "Pop Text (Weak)" pop_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopHover "Pop Hover" pop_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopFocus "Pop Focus" pop_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopCursor "Pop Cursor" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {PopSelection "Pop Selection" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - //- rjf: debugging colors - {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} - {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} - {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} - {Thread3 "Thread 3" thread_3 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x6598ffff 0x6598ffff ""} - {Thread4 "Thread 4" thread_4 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x65ffcbff 0x65ffcbff ""} - {Thread5 "Thread 5" thread_5 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0xff9819ff 0xff9819ff ""} - {Thread6 "Thread 6" thread_6 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x9932ffff 0x9932ffff ""} - {Thread7 "Thread 7" thread_7 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x65ff4cff 0x65ff4cff ""} - {ThreadUnwound "Thread (Unwound)" thread_unwound 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff ""} - {ThreadError "Thread (Error)" thread_error 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23218ff 0xb23219ff 0xb23219ff 0xb23219ff ""} - {Breakpoint "Breakpoint" breakpoint 0xa72911ff 0xff2800ff 0xa72911ff 0xa72911ff 0xa72911ff 0xff684bff 0xa72911ff 0xa72911ff 0xff2800ff ""} - {CacheLineBoundary "Cache Line Boundary" cache_line_boundary 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} + //- rjf: scroll bar palette + {ScrollBarBackground "Scroll Bar Background" scroll_bar_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {ScrollBarBackgroundAlt "Scroll Bar Background (Alternate)" scroll_bar_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundGood "Scroll Bar Background (Good)" scroll_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundBad "Scroll Bar Background (Bad)" scroll_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBackgroundPop "Scroll Bar Background (Pop)" scroll_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {ScrollBarBorder "Scroll Bar Border" scroll_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {ScrollBarText "Scroll Bar Text" scroll_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarTextWeak "Scroll Bar Text (Weak)" scroll_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarHover "Scroll Bar Hover" scroll_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarFocus "Scroll Bar Focus" scroll_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarCursor "Scroll Bar Cursor" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {ScrollBarSelection "Scroll Bar Selection" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: tab (active) palette + {TabBackground "Tab Background" tab_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {TabBackgroundAlt "Tab Background (Alternate)" tab_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundGood "Tab Background (Good)" tab_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundBad "Tab Background (Bad)" tab_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBackgroundPop "Tab Background (Pop)" tab_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabBorder "Tab Border" tab_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {TabText "Tab Text" tab_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabTextWeak "Tab Text (Weak)" tab_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabHover "Tab Hover" tab_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabFocus "Tab Focus" tab_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabCursor "Tab Cursor" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabSelection "Tab Selection" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: tab (inactive) palette + {TabInactiveBackground "Tab (Inactive) Background" tab_inactive_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {TabInactiveBackgroundAlt "Tab (Inactive) Background (Alternate)" tab_inactive_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundGood "Tab (Inactive) Background (Good)" tab_inactive_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundBad "Tab (Inactive) Background (Bad)" tab_inactive_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBackgroundPop "Tab (Inactive) Background (Pop)" tab_inactive_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {TabInactiveBorder "Tab (Inactive) Border" tab_inactive_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {TabInactiveText "Tab (Inactive) Text" tab_inactive_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveTextWeak "Tab (Inactive) Text (Weak)" tab_inactive_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveHover "Tab (Inactive) Hover" tab_inactive_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveFocus "Tab (Inactive) Focus" tab_inactive_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveCursor "Tab (Inactive) Cursor" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {TabInactiveSelection "Tab (Inactive) Selection" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: drop site palette + {DropSiteBackground "Drop Site Background" drop_site_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} + {DropSiteBackgroundAlt "Drop Site Background (Alternate)" drop_site_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundGood "Drop Site Background (Good)" drop_site_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundBad "Drop Site Background (Bad)" drop_site_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBackgroundPop "Drop Site Background (Pop)" drop_site_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} + {DropSiteBorder "Drop Site Border" drop_site_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} + {DropSiteText "Drop Site Text" drop_site_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteTextWeak "Drop Site Text (Weak)" drop_site_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteHover "Drop Site Hover" drop_site_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteFocus "Drop Site Focus" drop_site_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteCursor "Drop Site Cursor" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {DropSiteSelection "Drop Site Selection" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + + //- rjf: code colors (extra text colors which extend 'base') + {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} + {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cfff 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} + {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} + {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} + {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} + {CodeKeyword "Code (Keyword)" code_keyword 0xb38d4cff 0x573700ff 0x569cd6ff 0x0000ffff 0x849803ff 0x586e75ff 0xac7a09ff 0xd08f1eff 0x00ffffff ""} + {CodeDelimiterOperator "Code (Delimiters/Operators)" code_delimiter_operator 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0xa08462ff 0x90b080ff 0xffffffff ""} + {CodeNumeric "Code (Numeric)" code_numeric 0x98abb1ff 0x3f6e7dff 0xb5cea8ff 0x088658ff 0xd33582ff 0xd33482ef 0x698e21ff 0x4fff2eff 0x00ff00ff ""} + {CodeNumericAltDigitGroup "Code (Numeric, Alt. Digit Group)" code_numeric_alt_digit_group 0x738287ff 0x1f4450ff 0x729360ff 0x0c3828ff 0x902559ff 0x8e2659ff 0x3a4e11ff 0x3ccd21ff 0x738287ff ""} + {CodeString "Code (String)" code_string 0x98abb1ff 0x3c606bff 0xd59b85ff 0xa31414ff 0x1f9d91ff 0x29a198ff 0x6a8e22ff 0x4fff2eff 0x98abb1ff ""} + {CodeMeta "Code (Meta)" code_meta 0xd96759ff 0xad3627ff 0xd59c85ff 0x0000ffff 0x839802ff 0xd96759ff 0xdab98fff 0xa0b8a0ff 0xff0000ff ""} + {CodeComment "Code (Comment)" code_comment 0x717171ff 0x4b4b4bff 0x57a54aff 0x008000ff 0x556a6fff 0x93a1a1ff 0x686868ff 0x1e8fefff 0xffffffff ""} + {CodeLineNumbers "Code Line Numbers" code_line_numbers 0x7f7f7fff 0x4b4b4bff 0x2a91afff 0x227893ff 0x566c73ff 0x227893ef 0xa08462ff 0x7e7e7ffe 0x007d7dff ""} + {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} + + //- rjf: debugging colors (extra text/element colors which extend 'base') + {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} + {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} + {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} + {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} + {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} + {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} + {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} + {Thread3 "Thread 3" thread_3 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x6598ffff 0x6598ffff ""} + {Thread4 "Thread 4" thread_4 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x65ffcbff 0x65ffcbff ""} + {Thread5 "Thread 5" thread_5 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0xff9819ff 0xff9819ff ""} + {Thread6 "Thread 6" thread_6 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x9932ffff 0x9932ffff ""} + {Thread7 "Thread 7" thread_7 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x65ff4cff 0x65ff4cff ""} + {ThreadUnwound "Thread (Unwound)" thread_unwound 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff ""} + {ThreadError "Thread (Error)" thread_error 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23218ff 0xb23219ff 0xb23219ff 0xb23219ff ""} + {Breakpoint "Breakpoint" breakpoint 0xa72911ff 0xff2800ff 0xa72911ff 0xa72911ff 0xa72911ff 0xff684bff 0xa72911ff 0xa72911ff 0xff2800ff ""} + {CacheLineBoundary "Cache Line Boundary" cache_line_boundary 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} } @table(old_name new_name) @@ -1145,6 +1322,11 @@ RD_ThemeColorVersionRemapTable: @expand(RD_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)")`, } +@data(String8) rd_theme_preset_cfg_string_table: +{ + @expand(RD_ThemePresetTable a) `str8_lit_comp("$(a.cfg)")`, +} + @data(String8) rd_theme_color_version_remap_old_name_table: { @expand(RD_ThemeColorVersionRemapTable a) `str8_lit_comp("$(a.old_name)")` diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0ff81e2e..5c572a61 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1471,6 +1471,17 @@ rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string) return child; } +internal RD_Cfg * +rd_cfg_child_from_string_or_parent(RD_Cfg *parent, String8 string) +{ + RD_Cfg *result = rd_cfg_child_from_string(parent, string); + if(result == &rd_nil_cfg) + { + result = parent; + } + return result; +} + internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string) { @@ -1702,6 +1713,23 @@ rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) list->count += 1; } +internal void +rd_cfg_list_push_front(Arena *arena, RD_CfgList *list, RD_Cfg *cfg) +{ + RD_CfgNode *n = push_array(arena, RD_CfgNode, 1); + n->v = cfg; + if(list->first != 0) + { + n->next = list->first; + } + else + { + list->last = n; + } + list->first = n; + list->count += 1; +} + internal RD_PanelTree rd_panel_tree_from_cfg(Arena *arena, RD_Cfg *cfg) { @@ -2063,7 +2091,7 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) } internal DR_FStrList -rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size) +rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) { DR_FStrList result = {0}; { @@ -2077,10 +2105,10 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 String8 expr_string = rd_expr_from_cfg(cfg); String8 collection_name = {0}; String8 file_path = {0}; - Vec4F32 rgba = rd_rgba_from_cfg(cfg); + Vec4F32 rgba = linear_from_srgba(rd_rgba_from_cfg(cfg)); if(rgba.w == 0) { - rgba = rd_rgba_from_theme_color(RD_ThemeColor_Text); + rgba = ui_top_palette()->text; } RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); B32 is_from_command_line = 0; @@ -2142,21 +2170,21 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 // more faded/smaller, but only after a primary title is pushed, // which could be caused by many different potential parts of a cfg. // - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, size}; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, ui_top_font_size()}; B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.95f;} +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = ui_top_palette()->text_weak; params.size = ui_top_font_size()*0.95f;} //- rjf: push icon if(icon_kind != RD_IconKind_Null) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push warning icon for command-line entities if(is_from_command_line) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative)); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -2274,7 +2302,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 for(String8Node *n = qualifiers.first; n != 0; n = n->next) { String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fstrs_push_new(arena, &result, ¶ms, string, .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_top_palette()->text_weak); } // rjf: push file name @@ -2360,7 +2388,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(src_string.size == 0) { src_string = str8_lit("(type)"); - src_color = secondary_color; + src_color = ui_top_palette()->text_weak; dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); } else RD_Font(RD_FontSlot_Code) @@ -2370,7 +2398,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(dst_string.size == 0) { dst_string = str8_lit("(view rule)"); - dst_color = secondary_color; + dst_color = ui_top_palette()->text_weak; dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); } else RD_Font(RD_FontSlot_Code) @@ -2379,7 +2407,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 } dr_fstrs_concat_in_place(&result, &src_fstrs); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&result, &dst_fstrs); } @@ -2394,16 +2422,16 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 if(src_string.size == 0) { src_string = str8_lit("(source path)"); - src_color = secondary_color; + src_color = ui_top_palette()->text_weak; } if(dst_string.size == 0) { dst_string = str8_lit("(destination path)"); - dst_color = secondary_color; + dst_color = ui_top_palette()->text_weak; } dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); } @@ -2660,7 +2688,7 @@ rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) internal Vec4F32 rd_rgba_from_ctrl_entity(CTRL_Entity *entity) { - Vec4F32 result = rd_rgba_from_theme_color(RD_ThemeColor_Text); + Vec4F32 result = {0}; if(entity->rgba != 0) { result = rgba_from_u32(entity->rgba); @@ -2674,11 +2702,11 @@ rd_rgba_from_ctrl_entity(CTRL_Entity *entity) CTRL_Entity *main_thread = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Thread); if(main_thread != entity) { - result = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + result = srgba_from_linear(rd_rgba_from_theme_color(RD_ThemeColor_Thread1)); } else { - result = rd_rgba_from_theme_color(RD_ThemeColor_Thread0); + result = srgba_from_linear(rd_rgba_from_theme_color(RD_ThemeColor_Thread0)); } }break; } @@ -2701,13 +2729,18 @@ rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) } internal DR_FStrList -rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras) +rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras) { DR_FStrList result = {0}; //- rjf: unpack entity info - F32 extras_size = size*0.95f; - Vec4F32 color = rd_rgba_from_ctrl_entity(entity); + F32 extras_size = ui_top_font_size()*0.95f; + Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(entity)); + if(color.w == 0) + { + color = ui_top_palette()->text; + } + Vec4F32 secondary_color = ui_top_palette()->text_weak; String8 name = rd_name_from_ctrl_entity(arena, entity); RD_IconKind icon_kind = RD_IconKind_Null; B32 name_is_code = 0; @@ -2721,7 +2754,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon } //- rjf: set up drawing params - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), rd_rgba_from_theme_color(RD_ThemeColor_Text), size}; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), color, ui_top_font_size()}; //- rjf: push icon if(icon_kind != RD_IconKind_Null) @@ -2736,7 +2769,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon entity->kind == CTRL_EntityKind_Thread) && ctrl_entity_tree_is_frozen(entity)) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative)); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->background_bad); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -2750,11 +2783,15 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); String8 process_name = rd_name_from_ctrl_entity(arena, process); Vec4F32 process_color = rd_rgba_from_ctrl_entity(process); + if(process_color.w == 0) + { + process_color = color; + } if(process_name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = size*0.9f); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.9f); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); } } @@ -2770,7 +2807,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secon if(entity->kind == CTRL_EntityKind_Process) { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = size*0.85f); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.85f); } //- rjf: threads get callstack extras @@ -3763,7 +3800,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(22.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NeutralPopButton) + RD_Palette(RD_PaletteCode_Pop) if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); @@ -3783,7 +3820,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(22.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_PositivePopButton) + RD_Palette(RD_PaletteCode_Good) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) { @@ -3823,7 +3860,6 @@ rd_view_ui(Rng2F32 rect) UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_Padding(ui_pct(1, 0)) - RD_Palette(RD_PaletteCode_Floating) { ui_labelf("use"); UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); @@ -4532,88 +4568,32 @@ rd_window_frame(void) RD_Theme *current = rd_state->theme; for EachEnumVal(RD_PaletteCode, code) { - ws->cfg_palettes[code].null = v4f32(1, 0, 1, 1); - ws->cfg_palettes[code].cursor = current->colors[RD_ThemeColor_Cursor]; - ws->cfg_palettes[code].selection = current->colors[RD_ThemeColor_SelectionOverlay]; - } - ws->cfg_palettes[RD_PaletteCode_Base].background = current->colors[RD_ThemeColor_BaseBackground]; - ws->cfg_palettes[RD_PaletteCode_Base].background_alt = current->colors[RD_ThemeColor_BaseBackgroundAlt]; - ws->cfg_palettes[RD_PaletteCode_Base].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Base].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Base].border = current->colors[RD_ThemeColor_BaseBorder]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].background = current->colors[RD_ThemeColor_MenuBarBackground]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].background_alt = current->colors[RD_ThemeColor_MenuBarBackgroundAlt]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_MenuBar].border = current->colors[RD_ThemeColor_MenuBarBorder]; - ws->cfg_palettes[RD_PaletteCode_Floating].background = current->colors[RD_ThemeColor_FloatingBackground]; - ws->cfg_palettes[RD_PaletteCode_Floating].background_alt = current->colors[RD_ThemeColor_FloatingBackgroundAlt]; - ws->cfg_palettes[RD_PaletteCode_Floating].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Floating].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Floating].border = current->colors[RD_ThemeColor_FloatingBorder]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background = current->colors[RD_ThemeColor_ImplicitButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].background_alt = current->colors[RD_ThemeColor_ImplicitButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ImplicitButton].border = current->colors[RD_ThemeColor_ImplicitButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].background = current->colors[RD_ThemeColor_PlainButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].background_alt = current->colors[RD_ThemeColor_PlainButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PlainButton].border = current->colors[RD_ThemeColor_PlainButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background = current->colors[RD_ThemeColor_PositivePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].background_alt = current->colors[RD_ThemeColor_PositivePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_PositivePopButton].border = current->colors[RD_ThemeColor_PositivePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background = current->colors[RD_ThemeColor_NegativePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].background_alt = current->colors[RD_ThemeColor_NegativePopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NegativePopButton].border = current->colors[RD_ThemeColor_NegativePopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].background_alt = current->colors[RD_ThemeColor_NeutralPopButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_NeutralPopButton].border = current->colors[RD_ThemeColor_NeutralPopButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].background_alt = current->colors[RD_ThemeColor_ScrollBarButtonBackground]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_ScrollBarButton].border = current->colors[RD_ThemeColor_ScrollBarButtonBorder]; - ws->cfg_palettes[RD_PaletteCode_Tab].background = current->colors[RD_ThemeColor_TabBackground]; - ws->cfg_palettes[RD_PaletteCode_Tab].background_alt = current->colors[RD_ThemeColor_TabBackground]; - ws->cfg_palettes[RD_PaletteCode_Tab].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_Tab].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_Tab].border = current->colors[RD_ThemeColor_TabBorder]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].background = current->colors[RD_ThemeColor_TabBackgroundInactive]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].background_alt = current->colors[RD_ThemeColor_TabBackgroundInactive]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text = current->colors[RD_ThemeColor_Text]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].text_weak = current->colors[RD_ThemeColor_TextWeak]; - ws->cfg_palettes[RD_PaletteCode_TabInactive].border = current->colors[RD_ThemeColor_TabBorderInactive]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].background_alt = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].text_weak = current->colors[RD_ThemeColor_DropSiteOverlay]; - ws->cfg_palettes[RD_PaletteCode_DropSiteOverlay].border = current->colors[RD_ThemeColor_BaseBorder]; - if(rd_setting_b32_from_name(str8_lit("opaque_backgrounds"))) - { - for EachEnumVal(RD_PaletteCode, code) - { - if(ws->cfg_palettes[code].background.x != 0 || - ws->cfg_palettes[code].background.y != 0 || - ws->cfg_palettes[code].background.z != 0) - { - ws->cfg_palettes[code].background.w = 1; - } - if(ws->cfg_palettes[code].background_alt.x != 0 || - ws->cfg_palettes[code].background_alt.y != 0 || - ws->cfg_palettes[code].background_alt.z != 0) - { - ws->cfg_palettes[code].background_alt.w = 1; - } - } + ws->cfg_palettes[code].null = v4f32(1, 0, 1, 1); } +#define fill_palette(name) \ +{\ +ws->cfg_palettes[RD_PaletteCode_##name].background = current->colors[RD_ThemeColor_##name##Background];\ +ws->cfg_palettes[RD_PaletteCode_##name].background_alt = current->colors[RD_ThemeColor_##name##BackgroundAlt];\ +ws->cfg_palettes[RD_PaletteCode_##name].background_good = current->colors[RD_ThemeColor_##name##BackgroundGood];\ +ws->cfg_palettes[RD_PaletteCode_##name].background_bad = current->colors[RD_ThemeColor_##name##BackgroundBad];\ +ws->cfg_palettes[RD_PaletteCode_##name].background_pop = current->colors[RD_ThemeColor_##name##BackgroundPop];\ +ws->cfg_palettes[RD_PaletteCode_##name].border = current->colors[RD_ThemeColor_##name##Border];\ +ws->cfg_palettes[RD_PaletteCode_##name].text = current->colors[RD_ThemeColor_##name##Text];\ +ws->cfg_palettes[RD_PaletteCode_##name].text_weak = current->colors[RD_ThemeColor_##name##TextWeak];\ +ws->cfg_palettes[RD_PaletteCode_##name].hover = current->colors[RD_ThemeColor_##name##Hover];\ +ws->cfg_palettes[RD_PaletteCode_##name].focus = current->colors[RD_ThemeColor_##name##Focus];\ +ws->cfg_palettes[RD_PaletteCode_##name].cursor = current->colors[RD_ThemeColor_##name##Cursor];\ +ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_ThemeColor_##name##Selection];\ +} + fill_palette(Base); + fill_palette(MenuBar); + fill_palette(Good); + fill_palette(Bad); + fill_palette(Pop); + fill_palette(ScrollBar); + fill_palette(Tab); + fill_palette(TabInactive); + fill_palette(DropSite); } ////////////////////////////// @@ -4681,9 +4661,9 @@ rd_window_frame(void) // rjf: build widget palette info UI_WidgetPaletteInfo widget_palette_info = {0}; { - widget_palette_info.tooltip_palette = rd_palette_from_code(RD_PaletteCode_Floating); - widget_palette_info.ctx_menu_palette = rd_palette_from_code(RD_PaletteCode_Floating); - widget_palette_info.scrollbar_palette = rd_palette_from_code(RD_PaletteCode_ScrollBarButton); + widget_palette_info.tooltip_palette = rd_palette_from_code(RD_PaletteCode_Base); + widget_palette_info.ctx_menu_palette = rd_palette_from_code(RD_PaletteCode_Base); + widget_palette_info.scrollbar_palette = rd_palette_from_code(RD_PaletteCode_ScrollBar); } // rjf: build animation info @@ -4744,7 +4724,7 @@ rd_window_frame(void) RD_RegSlot slot = ((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs_slot : rd_state->hover_regs_slot); RD_Regs *regs = (((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs : rd_state->hover_regs)); CTRL_Entity *ctrl_entity = &ctrl_entity_nil; - RD_Palette(RD_PaletteCode_Floating) switch(slot) + switch(slot) { default:{}break; @@ -4771,7 +4751,7 @@ rd_window_frame(void) { // rjf: unpack RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); - DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) @@ -4796,9 +4776,7 @@ rd_window_frame(void) DI_Scope *di_scope = di_scope_open(); Arch arch = ctrl_entity->arch; String8 arch_str = string_from_arch(arch); - DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, - rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), - ui_top_font_size(), 0); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, 0); // rjf: title UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) @@ -4808,7 +4786,6 @@ rd_window_frame(void) ui_spacer(ui_em(0.5f, 1.f)); UI_FontSize(ui_top_font_size() - 1.f) UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) { UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(arch_str); ui_spacer(ui_em(0.5f, 1.f)); @@ -4930,7 +4907,7 @@ rd_window_frame(void) { UI_Row UI_PrefWidth(ui_text_dim(10, 1)) { - DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, view); UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(name_box, &fstrs); } @@ -5207,7 +5184,6 @@ rd_window_frame(void) UI_Focus(UI_FocusKind_On) UI_Squish(squish) UI_Transparency(transparency) - RD_Palette(RD_PaletteCode_Floating) { lister_box = ui_build_box_from_key(UI_BoxFlag_Clickable| UI_BoxFlag_Clip| @@ -5266,7 +5242,6 @@ rd_window_frame(void) UI_Focus(UI_FocusKind_On) UI_ScrollList(¶ms, &lister->scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) UI_Focus(UI_FocusKind_Null) - RD_Palette(RD_PaletteCode_ImplicitButton) { UI_HoverCursor(OS_Cursor_HandPoint) for(S64 idx = visible_row_range.min; 0 <= idx && idx < visible_row_range.max && idx < item_array.count; idx += 1) @@ -5308,7 +5283,7 @@ rd_window_frame(void) if(flags & RD_ListerFlag_KindLabel && item->kind_name.size != 0) { ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_Floating) UI_CornerRadius(ui_top_font_size()*0.5f) + UI_CornerRadius(ui_top_font_size()*0.5f) { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_flags(UI_BoxFlag_DrawBorder); @@ -5333,7 +5308,7 @@ rd_window_frame(void) } // rjf: bindings - if(item->flags & RD_ListerItemFlag_Bindings) RD_Palette(RD_PaletteCode_Floating) UI_Focus(UI_FocusKind_Off) + if(item->flags & RD_ListerItemFlag_Bindings) UI_Focus(UI_FocusKind_Off) { ui_set_next_flags(UI_BoxFlag_Clickable); UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_px(row_height_px/4.f, 0.f)) @@ -5630,9 +5605,7 @@ rd_window_frame(void) //////////////////////////// //- rjf: top-level registers context menu // - RD_Palette(RD_PaletteCode_Floating) UI_CtxMenu(rd_state->ctx_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(rd_state->ctx_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { Temp scratch = scratch_begin(0, 0); RD_Regs *regs = ws->ctx_menu_regs; @@ -5896,13 +5869,14 @@ rd_window_frame(void) case RD_RegSlot_CtrlEntity: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->ctrl_entity); goto ctrl_entity_title; ctrl_entity_title:; { +#if 0 // TODO(rjf): @cfg //- rjf: title UI_Row UI_PrefWidth(ui_text_dim(5, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_TextPadding(ui_top_font_size()*1.5f) { - DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, ui_top_palette()->text_weak, ui_top_font_size(), 0); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, 0); UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(title_box, &fstrs); if(ctrl_entity->kind == CTRL_EntityKind_Thread) @@ -5910,7 +5884,6 @@ rd_window_frame(void) ui_spacer(ui_em(0.5f, 1.f)); UI_FontSize(ui_top_font_size() - 1.f) UI_CornerRadius(ui_top_font_size()*0.5f) - RD_Palette(RD_PaletteCode_NeutralPopButton) UI_TextPadding(ui_top_font_size()*0.5f) { UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(string_from_arch(ctrl_entity->arch)); @@ -5920,7 +5893,7 @@ rd_window_frame(void) } } - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + ui_divider(ui_em(1.f, 1.f)); //- rjf: name editor if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) @@ -6130,6 +6103,7 @@ rd_window_frame(void) ui_spacer(ui_em(1.5f, 1.f)); } +#endif #endif }break; } @@ -6143,9 +6117,7 @@ rd_window_frame(void) // if(ws->drop_completion_paths.node_count != 0) { - RD_Palette(RD_PaletteCode_Floating) UI_CtxMenu(rd_state->drop_completion_key) - RD_Palette(RD_PaletteCode_ImplicitButton) - UI_PrefWidth(ui_em(40.f, 1.f)) + UI_CtxMenu(rd_state->drop_completion_key) UI_PrefWidth(ui_em(40.f, 1.f)) { UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) for(String8Node *n = ws->drop_completion_paths.first; n != 0; n = n->next) @@ -6156,7 +6128,7 @@ rd_window_frame(void) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(n->string); } } - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); + ui_divider(ui_em(1.f, 1.f)); if(ui_clicked(rd_icon_buttonf(RD_IconKind_Target, 0, "Add File%s As Target%s", (ws->drop_completion_paths.node_count > 1) ? "s" : "", (ws->drop_completion_paths.node_count > 1) ? "s" : ""))) @@ -6225,13 +6197,11 @@ rd_window_frame(void) { Vec2F32 window_dim = dim_2f32(window_rect); UI_Box *bg_box = &ui_nil_box; - UI_Palette *palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_Floating)); - palette->background.w *= rd_state->popup_t; UI_Rect(window_rect) UI_ChildLayoutAxis(Axis2_X) UI_Focus(UI_FocusKind_On) UI_BlurSize(10*rd_state->popup_t) - UI_Palette(palette) + UI_Transparency(1-rd_state->popup_t) { bg_box = ui_build_box_from_stringf(UI_BoxFlag_FixedSize| UI_BoxFlag_Floating| @@ -6239,8 +6209,7 @@ rd_window_frame(void) UI_BoxFlag_Scroll| UI_BoxFlag_DefaultFocusNav| UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawBackground, "###popup_%p", ws); + UI_BoxFlag_DrawBackgroundBlur, "###popup_%p", ws); } if(rd_state->popup_active) UI_Parent(bg_box) UI_Transparency(1-rd_state->popup_t) { @@ -6252,7 +6221,7 @@ rd_window_frame(void) ui_spacer(ui_em(1.5f, 1.f)); UI_Row UI_Padding(ui_pct(1.f, 0.f)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_PrefHeight(ui_em(3.5f, 1.f)) UI_CornerRadius(ui_top_font_size()*0.5f) { - RD_Palette(RD_PaletteCode_NeutralPopButton) + RD_Palette(RD_PaletteCode_Pop) if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_slot_press(UI_EventActionSlot_Accept))) { rd_cmd(RD_CmdKind_PopupAccept); @@ -6312,10 +6281,7 @@ rd_window_frame(void) { // rjf: file menu UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(file_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { String8 cmds[] = { @@ -6339,10 +6305,7 @@ rd_window_frame(void) // rjf: window menu UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(window_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { String8 cmds[] = { @@ -6362,10 +6325,7 @@ rd_window_frame(void) // rjf: panel menu UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(panel_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { String8 cmds[] = { @@ -6409,10 +6369,7 @@ rd_window_frame(void) // rjf: view menu UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(view_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { String8 cmds[] = { @@ -6466,10 +6423,7 @@ rd_window_frame(void) // rjf: targets menu UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(targets_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { Temp scratch = scratch_begin(0, 0); String8 cmds[] = @@ -6487,10 +6441,7 @@ rd_window_frame(void) // rjf: ctrl menu UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(ctrl_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { String8 cmds[] = { @@ -6520,10 +6471,7 @@ rd_window_frame(void) // rjf: help menu UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(help_menu_key) - UI_PrefWidth(ui_em(50.f, 1.f)) - RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); @@ -6548,7 +6496,7 @@ rd_window_frame(void) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); } ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_NeutralPopButton) + RD_Palette(RD_PaletteCode_Pop) UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) UI_CornerRadius(ui_top_font_size()*0.5f) { @@ -6662,8 +6610,7 @@ rd_window_frame(void) ui_spacer(ui_em(0.75f, 1)); // rjf: conversion task visualization - UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill - RD_Palette(RD_PaletteCode_NeutralPopButton) + UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill RD_Palette(RD_PaletteCode_Pop) { Temp scratch = scratch_begin(0, 0); RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); @@ -6711,7 +6658,7 @@ rd_window_frame(void) if(can_play || !have_targets || processes.count == 0) UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_play ? RD_ThemeColor_TextPositive : RD_ThemeColor_TextWeak))) + RD_Palette(can_play ? RD_PaletteCode_Good : RD_PaletteCode_MenuBar) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6738,7 +6685,7 @@ rd_window_frame(void) for(RD_CfgNode *n = targets.first; n != 0; n = n->next) { RD_Cfg *target = n->v; - DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target, ui_top_palette()->text_weak, ui_top_font_size()); + DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(box, &title_fstrs); } @@ -6753,7 +6700,7 @@ rd_window_frame(void) //- rjf: restart button else UI_TextAlignment(UI_TextAlign_Center) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive))) + RD_Palette(RD_PaletteCode_Good) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Redo]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6774,7 +6721,7 @@ rd_window_frame(void) //- rjf: pause button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_pause ? RD_ThemeColor_TextNeutral : RD_ThemeColor_TextWeak))) + RD_Palette(can_pause ? RD_PaletteCode_Pop : RD_PaletteCode_MenuBar) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6800,7 +6747,7 @@ rd_window_frame(void) //- rjf: stop button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(can_stop ? RD_ThemeColor_TextNegative : RD_ThemeColor_TextWeak))) + RD_Palette(can_stop ? RD_PaletteCode_Bad : RD_PaletteCode_MenuBar) { UI_Signal sig = {0}; { @@ -6926,7 +6873,7 @@ rd_window_frame(void) ui_spacer(ui_pct(1, 0)); // rjf: loaded user viz - if(do_user_prof) RD_Palette(RD_PaletteCode_NeutralPopButton) + if(do_user_prof) RD_Palette(RD_PaletteCode_Pop) { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -6960,7 +6907,7 @@ rd_window_frame(void) } // rjf: loaded project viz - if(do_user_prof) RD_Palette(RD_PaletteCode_NeutralPopButton) + if(do_user_prof) RD_Palette(RD_PaletteCode_Pop) { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -6994,7 +6941,7 @@ rd_window_frame(void) // rjf: close dropdown UI_Key close_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###close_ctx_menu"); - UI_CtxMenu(close_ctx_menu_key) RD_Palette(RD_PaletteCode_ImplicitButton) + UI_CtxMenu(close_ctx_menu_key) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Window, 0, "Close Window"))) { @@ -7019,7 +6966,7 @@ rd_window_frame(void) max_sig = rd_icon_buttonf(RD_IconKind_Window, 0, "##maximize"); } UI_PrefWidth(ui_px(button_dim, 1.f)) - RD_Palette(RD_PaletteCode_NegativePopButton) + RD_Palette(RD_PaletteCode_Bad) { cls_sig = rd_icon_buttonf(RD_IconKind_X, 0, "##close"); } @@ -7115,7 +7062,6 @@ rd_window_frame(void) if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) RD_Font(RD_FontSlot_Code) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - RD_Palette(RD_PaletteCode_Floating) { F32 hover_eval_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_open_t"), 1.f); RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); @@ -7217,9 +7163,9 @@ rd_window_frame(void) { B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); CTRL_Event stop_event = d_ctrl_last_stop_event(); - UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_PositivePopButton); - UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_NeutralPopButton); - UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_NegativePopButton); + UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_Good); + UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_Pop); + UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_Bad); UI_Palette *palette = running_scheme; if(!is_running) { @@ -7295,7 +7241,7 @@ rd_window_frame(void) UI_Flags(UI_BoxFlag_DrawBackground) UI_TextAlignment(UI_TextAlign_Center) UI_CornerRadius(4) - RD_Palette(RD_PaletteCode_NeutralPopButton) + RD_Palette(RD_PaletteCode_Pop) ui_labelf("Currently rebinding \"%S\" hotkey", display_name); } @@ -7428,7 +7374,7 @@ rd_window_frame(void) ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -7519,7 +7465,7 @@ rd_window_frame(void) ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -7823,10 +7769,10 @@ rd_window_frame(void) UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) { if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSiteOverlay) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + RD_Palette(RD_PaletteCode_DropSite) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); ui_spacer(ui_px(padding, 1.f)); if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSiteOverlay) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + RD_Palette(RD_PaletteCode_DropSite) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); } } } @@ -7836,7 +7782,7 @@ rd_window_frame(void) { ui_set_next_child_layout_axis(split_axis); UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); - UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) RD_Palette(RD_PaletteCode_DropSiteOverlay) + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) RD_Palette(RD_PaletteCode_DropSite) { ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); } @@ -7885,7 +7831,7 @@ rd_window_frame(void) ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -8041,7 +7987,7 @@ rd_window_frame(void) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(15.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_NegativePopButton) + RD_Palette(RD_PaletteCode_Bad) { if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) { @@ -8159,7 +8105,7 @@ rd_window_frame(void) } TabTask *t = push_array(scratch.arena, TabTask, 1); t->tab = tab; - t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size()); + t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; SLLQueuePush(first_tab_task, last_tab_task, t); tab_task_count += 1; @@ -8268,7 +8214,7 @@ rd_window_frame(void) } if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - palette_code = RD_PaletteCode_DropSiteOverlay; + palette_code = RD_PaletteCode_DropSite; omit_name = 1; } @@ -8371,7 +8317,7 @@ rd_window_frame(void) // rjf: build spot container box UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - RD_Palette(RD_PaletteCode_DropSiteOverlay) + RD_Palette(RD_PaletteCode_DropSite) { if(panel->tab_side == Side_Max) { @@ -8419,7 +8365,6 @@ rd_window_frame(void) UI_FontSize(ui_top_font_size()) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_HoverCursor(OS_Cursor_HandPoint) - RD_Palette(RD_PaletteCode_ImplicitButton) { UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawText| @@ -8726,7 +8671,20 @@ rd_window_frame(void) // rjf: main rectangle { - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box->flags & UI_BoxFlag_DrawBackgroundAlt ? box->palette->colors[UI_ColorCode_BackgroundAlt] : box->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); + Vec4F32 color = box->palette->colors[UI_ColorCode_Background]; + if(box->flags & UI_BoxFlag_DrawBad) + { + color = box->palette->colors[UI_ColorCode_BackgroundBad]; + } + else if(box->flags & UI_BoxFlag_DrawGood) + { + color = box->palette->colors[UI_ColorCode_BackgroundGood]; + } + else if(box->flags & UI_BoxFlag_DrawPop) + { + color = box->palette->colors[UI_ColorCode_BackgroundPop]; + } + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), color, 0, 0, 1.f); MemoryCopyArray(inst->corner_radii, box->corner_radii); } @@ -8736,7 +8694,7 @@ rd_window_frame(void) // rjf: brighten { R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + Vec4F32 color = box->palette->hover; color.w *= t*0.1f; inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; @@ -8748,7 +8706,7 @@ rd_window_frame(void) { Vec2F32 center = ui_mouse(); F32 radius = box->font_size*12.f; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + Vec4F32 color = box->palette->hover; color.w *= 0.05f*t; dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } @@ -8846,7 +8804,7 @@ rd_window_frame(void) dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) { - Vec4F32 match_color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + Vec4F32 match_color = box->palette->background_pop; dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } } @@ -8950,7 +8908,7 @@ rd_window_frame(void) // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Hover); + Vec4F32 color = box->palette->hover; color.w *= b->hot_t; R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; @@ -8992,7 +8950,7 @@ rd_window_frame(void) // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); + Vec4F32 color = box->palette->focus; color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -9007,7 +8965,7 @@ rd_window_frame(void) rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Focus); + Vec4F32 color = box->palette->focus; color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -9016,9 +8974,8 @@ rd_window_frame(void) // rjf: disabled overlay if(b->disabled_t >= 0.005f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_DisabledOverlay); - color.w *= b->disabled_t*0.5f; - R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 1); + Vec4F32 disabled_overlay_color = v4f32(0, 0, 0, b->disabled_t*0.5f); + R_Rect2DInst *inst = dr_rect(b->rect, disabled_overlay_color, 0, 0, 1); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -9063,7 +9020,7 @@ rd_window_frame(void) //- rjf: draw border/overlay color to signify error if(ws->error_t > 0.01f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground); + Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundBad); color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); @@ -10534,6 +10491,49 @@ rd_push_search_string(Arena *arena) //- rjf: colors +internal Vec4F32 +rd_color_from_tags(String8Array tags) +{ + Vec4F32 result = {0}; + { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + RD_Theme *theme = ws->theme; + RD_ThemePattern *pattern = 0; + U64 best_match_count = 0; + for(U64 idx = 0; idx < theme->patterns_count; idx += 1) + { + RD_ThemePattern *p = &theme->patterns[idx]; + U64 match_count = 0; + for EachIndex(key_tags_idx, tags.count) + { + for EachIndex(p_tags_idx, p->tags.count) + { + if(str8_match(p->tags.v[p_tags_idx], tags.v[key_tags_idx], 0)) + { + match_count += 1; + break; + } + } + } + if(match_count > best_match_count) + { + pattern = p; + best_match_count = match_count; + } + if(match_count == tags.count) + { + break; + } + } + if(pattern != 0) + { + result = pattern->linear; + } + } + return result; +} + internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color) { @@ -10794,7 +10794,7 @@ internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); - DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, ui_top_palette()->text, ui_top_font_size(), 0); + DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0); DR_FStrList fstrs = {0}; DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_top_palette()->text, ui_top_font_size()}; switch(event->cause) @@ -10982,7 +10982,7 @@ rd_vocab_info_from_code_name_plural(String8 code_name_plural) } internal DR_FStrList -rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary_color, F32 size) +rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) { DR_FStrList result = {0}; { @@ -10995,14 +10995,14 @@ rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary // more faded/smaller, but only after a primary title is pushed, // which could be caused by many different potential parts of a cfg. // - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rd_rgba_from_theme_color(RD_ThemeColor_Text), size}; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = size*0.8f;} +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = ui_top_font_size()*0.95f;} //- rjf: push icon if(info->icon_kind != RD_IconKind_Null) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -11307,6 +11307,14 @@ rd_init(CmdLine *cmdln) } } + // rjf: set up theme presets + { + for EachEnumVal(RD_ThemePreset, p) + { + rd_state->theme_preset_trees[p] = md_tree_from_string(rd_state->arena, rd_theme_preset_cfg_string_table[p])->first; + } + } + // rjf: set up vocab info map { rd_state->vocab_info_map.single_slots_count = 1024; @@ -11939,6 +11947,125 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: compute all window themes + // + ProfScope("compute window themes") + { + Temp scratch = scratch_begin(0, 0); + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + { + //- rjf: for each window, scan upwards, and then try the project, then the user, until we + // find explicit preset / colors trees in the config. we will prefer the tightest ones, so + // that windows can have their own colors, and have those override higher-up settings. + RD_Cfg *preset_cfg = &rd_nil_cfg; + RD_CfgList colors_cfgs = {0}; + RD_Cfg *window_cfg = rd_cfg_from_id(ws->cfg_id); + RD_Cfg *scan_parents[] = {window_cfg, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; + for EachElement(idx, scan_parents) + { + for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) + { + if(preset_cfg == &rd_nil_cfg) + { + preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); + } + RD_Cfg *colors_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("colors")); + if(colors_cfg != &rd_nil_cfg) + { + rd_cfg_list_push_front(scratch.arena, &colors_cfgs, colors_cfg); + } + if(preset_cfg != &rd_nil_cfg && colors_cfg != &rd_nil_cfg) + { + break; + } + } + } + + //- rjf: map the preset config to the associated preset tree + MD_Node *preset_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; + if(preset_cfg != &rd_nil_cfg) + { + String8 preset_name = preset_cfg->first->string; + for EachEnumVal(RD_ThemePreset, p) + { + if(str8_match(preset_name, rd_theme_preset_code_string_table[p], 0)) + { + preset_tree = rd_state->theme_preset_trees[p]; + break; + } + } + } + + //- rjf: build tasks for color applications - each task comprises of a metadesk + // tree, describing the color patterns + typedef struct ThemeTask ThemeTask; + struct ThemeTask + { + ThemeTask *next; + MD_Node *tree; + }; + ThemeTask start_task = {0, preset_tree}; + ThemeTask *first_task = &start_task; + ThemeTask *last_task = first_task; + { + for(RD_CfgNode *n = colors_cfgs.first; n != 0; n = n->next) + { + ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); + SLLQueuePush(first_task, last_task, t); + t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); + } + } + + //- rjf: apply theme tasks, build each color pattern for this window's + // structured theme + typedef struct ThemePatternNode ThemePatternNode; + struct ThemePatternNode + { + ThemePatternNode *next; + RD_ThemePattern pattern; + }; + ThemePatternNode *first_pattern = 0; + ThemePatternNode *last_pattern = 0; + U64 pattern_count = 0; + for(ThemeTask *t = first_task; t != 0; t = t->next) + { + MD_Node *tree_root = t->tree; + for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) + { + if(n->flags & MD_NodeFlag_Numeric && md_node_is_nil(n)) + { + Vec4F32 color_srgba = rgba_from_hex_string_4f32(n->string); + Vec4F32 color_linear = linear_from_srgba(color_srgba); + String8List tags = {0}; + for(MD_Node *parent = n->parent; parent != tree_root && !md_node_is_nil(parent); parent = parent->parent) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), parent->string)); + } + ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); + node->pattern.tags = str8_array_from_list(ui_build_arena(), &tags); + node->pattern.linear = color_linear; + SLLQueuePush(first_pattern, last_pattern, node); + pattern_count += 1; + } + } + } + + //- rjf: convert to final pattern array + ws->theme = push_array(ui_build_arena(), RD_Theme, 1); + ws->theme->patterns_count = pattern_count; + ws->theme->patterns = push_array(ui_build_arena(), RD_ThemePattern, ws->theme->patterns_count); + { + U64 idx = 0; + for(ThemePatternNode *n = first_pattern; n != 0; n = n->next, idx += 1) + { + ws->theme->patterns[idx] = n->pattern; + } + } + } + scratch_end(scratch); + } + ////////////////////////////// //- rjf: build theme from config // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 57891ba6..bb09bd6f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -419,9 +419,18 @@ struct RD_RegsNode //////////////////////////////// //~ rjf: Structured Theme Types, Parsed From Config +typedef struct RD_ThemePattern RD_ThemePattern; +struct RD_ThemePattern +{ + String8Array tags; + Vec4F32 linear; +}; + typedef struct RD_Theme RD_Theme; struct RD_Theme { + RD_ThemePattern *patterns; + U64 patterns_count; Vec4F32 colors[RD_ThemeColor_COUNT]; }; @@ -438,16 +447,13 @@ typedef enum RD_PaletteCode { RD_PaletteCode_Base, RD_PaletteCode_MenuBar, - RD_PaletteCode_Floating, - RD_PaletteCode_ImplicitButton, - RD_PaletteCode_PlainButton, - RD_PaletteCode_PositivePopButton, - RD_PaletteCode_NegativePopButton, - RD_PaletteCode_NeutralPopButton, - RD_PaletteCode_ScrollBarButton, + RD_PaletteCode_Good, + RD_PaletteCode_Bad, + RD_PaletteCode_Pop, + RD_PaletteCode_ScrollBar, RD_PaletteCode_Tab, RD_PaletteCode_TabInactive, - RD_PaletteCode_DropSiteOverlay, + RD_PaletteCode_DropSite, RD_PaletteCode_COUNT } RD_PaletteCode; @@ -542,6 +548,9 @@ struct RD_WindowState B32 window_temporarily_focused_ipc; B32 window_layout_reset; + // rjf: theme + RD_Theme *theme; + // rjf: config/settings UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme @@ -715,6 +724,9 @@ struct RD_State // rjf: schema table MD_Node **schemas; + // rjf: default theme table + MD_Node *theme_preset_trees[RD_ThemePreset_COUNT]; + // rjf: vocab table RD_VocabInfoMap vocab_info_map; @@ -961,6 +973,7 @@ internal void rd_cfg_insert_child(RD_Cfg *parent, RD_Cfg *prev_child, RD_Cfg *ne internal void rd_cfg_unhook(RD_Cfg *parent, RD_Cfg *child); internal RD_Cfg *rd_cfg_child_from_string(RD_Cfg *parent, String8 string); internal RD_Cfg *rd_cfg_child_from_string_or_alloc(RD_Cfg *parent, String8 string); +internal RD_Cfg *rd_cfg_child_from_string_or_parent(RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_top_level_list_from_string(Arena *arena, String8 string); internal RD_CfgArray rd_cfg_array_from_list(Arena *arena, RD_CfgList *list); @@ -968,6 +981,7 @@ internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string); internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); internal void rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); +internal void rd_cfg_list_push_front(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); #define rd_cfg_list_first(list) ((list)->count ? (list)->first->v : &rd_nil_cfg) #define rd_cfg_list_last(list) ((list)->count ? (list)->last->v : &rd_nil_cfg) @@ -993,7 +1007,7 @@ internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); -internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg, Vec4F32 secondary_color, F32 size); +internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg); internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); @@ -1014,7 +1028,7 @@ internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); internal Vec4F32 rd_rgba_from_ctrl_entity(CTRL_Entity *entity); internal String8 rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); -internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, Vec4F32 secondary_color, F32 size, B32 include_extras); +internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras); //////////////////////////////// //~ rjf: Evaluation Spaces @@ -1150,6 +1164,7 @@ internal String8 rd_push_search_string(Arena *arena); //~ rjf: Colors, Fonts, Config //- rjf: colors +internal Vec4F32 rd_color_from_tags(String8Array tags); internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); @@ -1178,7 +1193,7 @@ internal RD_VocabInfo *rd_vocab_info_from_code_name_plural(String8 code_name_plu #define rd_display_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name_plural) #define rd_icon_kind_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->icon_kind) #define rd_singular_from_code_name_plural(code_name_plural) (rd_vocab_info_from_code_name_plural(code_name_plural)->code_name) -internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name, Vec4F32 secondary_color, F32 size); +internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name); //////////////////////////////// //~ rjf: Continuous Frame Requests diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4fd2f042..5f372f75 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1034,7 +1034,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); MD_Node *schema = rd_schema_from_name(arena, cfg->string); MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); for MD_EachNode(cmd, cmds_root->first) @@ -1088,7 +1088,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); if(entity->kind == CTRL_EntityKind_Machine || entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) @@ -1107,7 +1107,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string, ui_top_palette()->text_weak, ui_top_font_size())); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); } // rjf: folder / file rows @@ -1445,7 +1445,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); if(e_type_key_match(cfg_type, result.eval.type_key)) { - result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, ui_top_palette()->text_weak, ui_top_font_size(), 1); + result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1); result.flags |= RD_WatchCellFlag_Button; result.entity = entity; } @@ -1457,7 +1457,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); if(e_type_key_match(cfg_type, result.eval.type_key)) { - result.fstrs = rd_title_fstrs_from_cfg(arena, cfg, ui_top_palette()->text_weak, ui_top_font_size()); + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); result.flags |= RD_WatchCellFlag_Button; result.cfg = cfg; } @@ -1473,7 +1473,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } else { - result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name, ui_top_palette()->text_weak, ui_top_font_size()); + result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name); } result.flags |= RD_WatchCellFlag_Button; result.cmd_name = cmd_name; @@ -2750,16 +2750,11 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(row_is_fresh) { - Vec4F32 start_color = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground); - start_color.w *= 0.5f; - Vec4F32 end_color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - Vec4F32 color = mix_4f32(start_color, end_color, ui_anim(ui_key_from_stringf(ui_key_zero(), "row_fresh_%I64x", row_hash), 1.f)); - palette = ui_build_palette(ui_top_palette(), .background = color); - row_flags |= UI_BoxFlag_DrawBackground; + row_flags |= UI_BoxFlag_DrawPop; } - else if(global_row_idx & 1) + if(global_row_idx & 1) { - row_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundAlt; + row_flags |= UI_BoxFlag_DrawAlt; } if(!row_matches_last_row_topology) { @@ -2847,44 +2842,36 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(cell_info.flags & RD_WatchCellFlag_IsErrored) { - palette = ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError)); - cell_flags |= UI_BoxFlag_DrawBackground; + cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBad; } else if(cell_info.inheritance_tooltip.size != 0) { - palette = ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay)); - cell_flags |= UI_BoxFlag_DrawBackground; + cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawPop; } else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && rd_state->hover_regs_slot == RD_RegSlot_Cfg) { RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = rd_rgba_from_cfg(cfg); + Vec4F32 rgba = linear_from_srgba(rd_rgba_from_cfg(cfg)); if(rgba.w == 0) { - rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - } - else - { - rgba.w *= 0.2f; + rgba = ui_top_palette()->background_pop; } + rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); - cell_flags |= UI_BoxFlag_DrawBackground; + cell_flags |= UI_BoxFlag_DrawPop|UI_BoxFlag_DrawBackground; } else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) { CTRL_Entity *entity = cell_info.entity; - Vec4F32 rgba = rd_rgba_from_ctrl_entity(entity); + Vec4F32 rgba = linear_from_srgba(rd_rgba_from_ctrl_entity(entity)); if(rgba.w == 0) { - rgba = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); - } - else - { - rgba.w *= 0.2f; + rgba = ui_top_palette()->background_pop;; } + rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); cell_flags |= UI_BoxFlag_DrawBackground; @@ -3440,7 +3427,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: build missing file interface // - if(file_is_missing && !u128_match(hash, u128_zero())) + if(file_is_missing) { UI_WidthFill UI_HeightFill UI_Column UI_Padding(ui_pct(1, 0)) { @@ -3448,7 +3435,6 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_em(3, 1)) UI_Row UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_text_dim(10, 1)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) { RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); ui_labelf("Could not find \"%S\".", rd_regs()->file_path); @@ -3459,7 +3445,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_CornerRadius(ui_top_font_size()/3) UI_PrefWidth(ui_text_dim(10, 1)) UI_Focus(UI_FocusKind_On) - RD_Palette(RD_PaletteCode_NeutralPopButton) + RD_Palette(RD_PaletteCode_Pop) UI_TextAlignment(UI_TextAlign_Center) if(ui_clicked(ui_buttonf("Find alternative..."))) { @@ -3534,7 +3520,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_Palette *palette = ui_top_palette(); if(file_is_out_of_date) { - palette = rd_palette_from_code(RD_PaletteCode_NegativePopButton); + palette = rd_palette_from_code(RD_PaletteCode_Bad); } UI_Palette(palette) UI_Row @@ -3545,8 +3531,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(file_is_out_of_date) { UI_Box *box = &ui_nil_box; - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) - RD_Font(RD_FontSlot_Icons) + RD_Font(RD_FontSlot_Icons) { box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable, "%S###file_ood_warning", rd_icon_kind_text_table[RD_IconKind_WarningBig]); } @@ -3556,7 +3541,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) { ui_labelf("This file has changed since ", out_of_date_dbgi_name); - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral))) ui_label(out_of_date_dbgi_name); + ui_label(out_of_date_dbgi_name); ui_labelf(" was produced."); } } @@ -4062,8 +4047,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // DR_FStrList byte_fstrs[256] = {0}; { - Vec4F32 full_color = rd_rgba_from_theme_color(RD_ThemeColor_TextPositive); - Vec4F32 zero_color = rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); + Vec4F32 full_color = ui_top_palette()->text; + Vec4F32 zero_color = ui_top_palette()->text_weak; for(U64 idx = 0; idx < ArrayCount(byte_fstrs); idx += 1) { U8 byte = (U8)idx; @@ -4133,7 +4118,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->kind_string = str8_lit("Call Stack Frame"); - annotation->color = symbol_name.size != 0 ? rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol) : rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); + annotation->color = symbol_name.size != 0 ? rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol) : ui_top_palette()->text_weak; annotation->vaddr_range = frame_vaddr_range; for(U64 vaddr = frame_vaddr_range_in_viz.min; vaddr < frame_vaddr_range_in_viz.max; vaddr += 1) { @@ -4446,12 +4431,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // rjf: unpack visual cell info UI_BoxFlags cell_flags = 0; - Vec4F32 cell_border_rgba = {0}; Vec4F32 cell_bg_rgba = {0}; if(global_byte_num == mouse_hover_byte_num) { cell_flags |= UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight; - cell_border_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Hover); } if(annotation != 0) { @@ -4469,7 +4452,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) if(selection.min <= global_byte_idx && global_byte_idx <= selection.max) { cell_flags |= UI_BoxFlag_DrawBackground; - cell_bg_rgba = rd_rgba_from_theme_color(RD_ThemeColor_SelectionOverlay); + cell_bg_rgba = ui_top_palette()->selection; } // rjf: build @@ -4551,7 +4534,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), - rd_rgba_from_theme_color(RD_ThemeColor_SelectionOverlay), + ui_top_palette()->selection, 0, 0, 1.f); } ui_box_equip_draw_bucket(ascii_box, bucket); @@ -4562,7 +4545,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) DR_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + Vec4F32 color = ui_top_palette()->border; dr_rect(r2f32p(text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num-1-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num+0-row_range_bytes.min)).x + font_size/4.f, @@ -4726,7 +4709,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) Rng2F32 rect_cvs = rd_bitmap_canvas_from_screen_rect(draw_data->view_center_pos, draw_data->zoom, rect_scrn, rect_scrn); F32 grid_cell_size_cvs = box->font_size*10.f; F32 grid_line_thickness_px = Max(2.f, box->font_size*0.1f); - Vec4F32 grid_line_color = rd_rgba_from_theme_color(RD_ThemeColor_TextWeak); + Vec4F32 grid_line_color = ui_top_palette()->background_alt; for EachEnumVal(Axis2, axis) { for(F32 v = rect_cvs.p0.v[axis] - mod_f32(rect_cvs.p0.v[axis], grid_cell_size_cvs); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2fd73467..ad48dec5 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -20,8 +20,8 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t // rjf: colors Vec4F32 bg_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackground); - Vec4F32 bd_color = rd_rgba_from_theme_color(RD_ThemeColor_FloatingBorder); - Vec4F32 hl_color = rd_rgba_from_theme_color(RD_ThemeColor_TextNeutral); + Vec4F32 bd_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBorder); + Vec4F32 hl_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundPop); bg_color.w *= loading_t; bd_color.w *= loading_t; hl_color.w *= loading_t; @@ -140,21 +140,13 @@ rd_cmd_binding_buttons(String8 name) //- rjf: form color palette UI_Palette *palette = ui_top_palette(); - if(has_conflicts || rebinding_active_for_this_binding) + if(has_conflicts) { - palette = push_array(ui_build_arena(), UI_Palette, 1); - MemoryCopyStruct(palette, ui_top_palette()); - if(has_conflicts) - { - palette->colors[UI_ColorCode_Text] = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); - palette->colors[UI_ColorCode_TextWeak] = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); - } - if(rebinding_active_for_this_binding) - { - palette->colors[UI_ColorCode_Border] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background].w *= 0.25f; - } + palette = rd_palette_from_code(RD_PaletteCode_Bad); + } + if(rebinding_active_for_this_binding) + { + palette = rd_palette_from_code(RD_PaletteCode_Pop); } //- rjf: build box @@ -212,10 +204,7 @@ rd_cmd_binding_buttons(String8 name) //- rjf: delete button if(rebinding_active_for_this_binding) UI_PrefWidth(ui_em(2.5f, 1.f)) - UI_Palette(ui_build_palette(ui_top_palette(), - .background = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBackground), - .border = rd_rgba_from_theme_color(RD_ThemeColor_NegativePopButtonBorder), - .text = rd_rgba_from_theme_color(RD_ThemeColor_Text))) + RD_Palette(RD_PaletteCode_Bad) { ui_set_next_group_key(ui_key_zero()); UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding")); @@ -231,20 +220,17 @@ rd_cmd_binding_buttons(String8 name) } //- rjf: build "add new binding" button - RD_Font(RD_FontSlot_Icons) + B32 adding_new_binding = (rd_state->bind_change_active && + str8_match(rd_state->bind_change_cmd_name, name, 0) && + rd_state->bind_change_binding.key == OS_Key_Null && + rd_state->bind_change_binding.modifiers == 0); + UI_Palette *palette = ui_top_palette(); + if(adding_new_binding) + { + palette = rd_palette_from_code(RD_PaletteCode_Pop); + } + RD_Font(RD_FontSlot_Icons) UI_Palette(palette) { - UI_Palette *palette = ui_top_palette(); - B32 adding_new_binding = (rd_state->bind_change_active && - str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding.key == OS_Key_Null && - rd_state->bind_change_binding.modifiers == 0); - if(adding_new_binding) - { - palette = ui_build_palette(ui_top_palette()); - palette->colors[UI_ColorCode_Border] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background] = rd_rgba_from_theme_color(RD_ThemeColor_Focus); - palette->colors[UI_ColorCode_Background].w *= 0.25f; - } ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); @@ -495,7 +481,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->is_frozen) { F32 lock_icon_off = ui_top_font_size()*0.2f; - Vec4F32 lock_icon_color = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative); + Vec4F32 lock_icon_color = ui_top_palette()->background_bad; dr_text(rd_font_from_slot(RD_FontSlot_Icons), box->font_size, 0, 0, FNT_RasterFlag_Smooth, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, @@ -609,9 +595,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground2), rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground3), }; - UI_Palette *margin_palette = rd_palette_from_code(RD_PaletteCode_Floating); - UI_Palette *margin_contents_palette = ui_build_palette(rd_palette_from_code(RD_PaletteCode_Floating)); - margin_contents_palette->background = v4f32(0, 0, 0, 0); F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; @@ -656,7 +639,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) { - line_bg_colors[line_idx] = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlayError); + line_bg_colors[line_idx] = ui_top_palette()->background_bad; } } } @@ -666,7 +649,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build priority margin // UI_Box *priority_margin_container_box = &ui_nil_box; - if(params->flags & RD_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) UI_Palette(margin_palette) ProfScope("build priority margins") + if(params->flags & RD_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build priority margins") { if(params->margin_float_off_px != 0) { @@ -679,7 +662,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); priority_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("priority_margin_container")); - UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Palette(margin_contents_palette) + UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; for(S64 line_num = params->line_num_range.min; @@ -708,8 +691,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = rd_rgba_from_ctrl_entity(thread); + Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); { + if(color.w == 0) + { + color = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + } if(unwind_count != 0) { color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); @@ -727,7 +714,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } if(thread != selected_thread) { - color.w *= 0.8f; + color.w *= 0.5f; } } @@ -813,7 +800,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build catchall margin // UI_Box *catchall_margin_container_box = &ui_nil_box; - if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Palette(margin_palette) UI_Parent(top_container_box) ProfScope("build catchall margins") + if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins") { if(params->margin_float_off_px != 0) { @@ -826,7 +813,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); - UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_Palette(margin_contents_palette) + UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; for(S64 line_num = params->line_num_range.min; @@ -857,8 +844,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = rd_rgba_from_ctrl_entity(thread); + Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); { + if(color.w == 0) + { + color = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + } if(unwind_count != 0) { color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); @@ -1182,7 +1173,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build background for line numbers & margins // { - UI_Parent(top_container_box) RD_Palette(RD_PaletteCode_Floating) + UI_Parent(top_container_box) { ui_set_next_pref_width(ui_px(params->priority_margin_width_px + params->catchall_margin_width_px + params->line_num_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); @@ -1255,7 +1246,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + RD_Palette(RD_PaletteCode_Bad) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###exception_info"); ui_box_equip_display_fstrs(box, &explanation_fstrs); @@ -1413,7 +1404,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 line_drag_drop = 0; RD_Cfg *line_drag_cfg = &rd_nil_cfg; CTRL_Entity *line_drag_ctrl_entity = &ctrl_entity_nil; - Vec4F32 line_drag_drop_color = rd_rgba_from_theme_color(RD_ThemeColor_DropSiteOverlay); + Vec4F32 line_drag_drop_color = ui_top_palette()->background_pop; { //- rjf: determine mouse drag range TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); @@ -1494,19 +1485,21 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { line_drag_drop = 1; line_drag_cfg = cfg; - line_drag_drop_color = rd_rgba_from_cfg(cfg); - line_drag_drop_color.w *= 0.5f; + line_drag_drop_color = linear_from_srgba(rd_rgba_from_cfg(cfg)); if(line_drag_drop_color.w == 0) { - line_drag_drop_color = rd_rgba_from_theme_color(RD_ThemeColor_DropSiteOverlay); + line_drag_drop_color = ui_top_palette()->background_pop; } } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) { line_drag_drop = 1; line_drag_ctrl_entity = thread; - line_drag_drop_color = rd_rgba_from_ctrl_entity(thread); - line_drag_drop_color.w *= 0.5f; + line_drag_drop_color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); + if(line_drag_drop_color.w == 0) + { + line_drag_drop_color = ui_top_palette()->background_pop; + } } } @@ -1678,7 +1671,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = result.mouse_expr_rng; - n->color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + n->color = ui_top_palette()->background_pop; SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } } @@ -1816,7 +1809,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_box->rect.x0+line_num_padding_px+match_column_pixel_off_range.max+2.f, line_box->rect.y1, }; - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay); + Vec4F32 color = ui_top_palette()->background_pop; if(cursor->line == line_num && needle_pos+1 <= cursor->column && cursor->column < needle_pos+params->search_query.size+1) { color.x += (1.f - color.x) * 0.5f; @@ -1900,7 +1893,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness/2.f, line_box->rect.y1+params->font_size*0.25f, }; - dr_rect(cursor_rect, rd_rgba_from_theme_color(is_focused ? RD_ThemeColor_Cursor : RD_ThemeColor_CursorInactive), 1.f, 0, 1.f); + Vec4F32 cursor_color = ui_top_palette()->cursor; + if(!is_focused) + { + cursor_color.w *= 0.5f; + } + dr_rect(cursor_rect, cursor_color, 1.f, 0, 1.f); } // rjf: extra rendering for lines with line-info that match the hovered @@ -2212,7 +2210,7 @@ rd_error_label(String8 string) { UI_Box *box = ui_build_box_from_key(0, ui_key_zero()); UI_Signal sig = ui_signal_from_box(box); - UI_Parent(box) UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative), .text_weak = rd_rgba_from_theme_color(RD_ThemeColor_TextNegative))) + UI_Parent(box) { ui_set_next_font(rd_font_from_slot(RD_FontSlot_Icons)); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index f1490347..3b0a771b 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -20,6 +20,7 @@ #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) #define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) +#define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) @@ -50,6 +51,7 @@ internal U32 ui_top_fastpath_codepoint(void) { UI_StackTopImpl(ui_state, Fastpat internal UI_Key ui_top_group_key(void) { UI_StackTopImpl(ui_state, GroupKey, group_key) } internal F32 ui_top_transparency(void) { UI_StackTopImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_top_palette(void) { UI_StackTopImpl(ui_state, Palette, palette) } +internal String8 ui_top_tag(void) { UI_StackTopImpl(ui_state, Tag, tag) } internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } @@ -79,6 +81,7 @@ internal U32 ui_bottom_fastpath_codepoint(void) { UI_StackBottomImpl(ui_state, F internal UI_Key ui_bottom_group_key(void) { UI_StackBottomImpl(ui_state, GroupKey, group_key) } internal F32 ui_bottom_transparency(void) { UI_StackBottomImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_bottom_palette(void) { UI_StackBottomImpl(ui_state, Palette, palette) } +internal String8 ui_bottom_tag(void) { UI_StackBottomImpl(ui_state, Tag, tag) } internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squish) } internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } @@ -108,6 +111,7 @@ internal U32 ui_push_fastpath_codepoint(U32 v) { UI_StackPushImpl(ui_state, Fast internal UI_Key ui_push_group_key(UI_Key v) { UI_StackPushImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_push_transparency(F32 v) { UI_StackPushImpl(ui_state, Transparency, transparency, F32, v) } internal UI_Palette* ui_push_palette(UI_Palette* v) { UI_StackPushImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal String8 ui_push_tag(String8 v) { UI_StackPushImpl(ui_state, Tag, tag, String8, v) } internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_push_font(FNT_Tag v) { UI_StackPushImpl(ui_state, Font, font, FNT_Tag, v) } @@ -137,6 +141,7 @@ internal U32 ui_pop_fastpath_codepoint(void) { UI_StackPopImpl(ui_state, Fastpat internal UI_Key ui_pop_group_key(void) { UI_StackPopImpl(ui_state, GroupKey, group_key) } internal F32 ui_pop_transparency(void) { UI_StackPopImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_pop_palette(void) { UI_StackPopImpl(ui_state, Palette, palette) } +internal String8 ui_pop_tag(void) { UI_StackPopImpl(ui_state, Tag, tag) } internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } @@ -166,6 +171,7 @@ internal U32 ui_set_next_fastpath_codepoint(U32 v) { UI_StackSetNextImpl(ui_stat internal UI_Key ui_set_next_group_key(UI_Key v) { UI_StackSetNextImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_set_next_transparency(F32 v) { UI_StackSetNextImpl(ui_state, Transparency, transparency, F32, v) } internal UI_Palette* ui_set_next_palette(UI_Palette* v) { UI_StackSetNextImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal String8 ui_set_next_tag(String8 v) { UI_StackSetNextImpl(ui_state, Tag, tag, String8, v) } internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_set_next_font(FNT_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, FNT_Tag, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index 28c38de8..0adc1ad9 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -22,6 +22,7 @@ typedef struct UI_FastpathCodepointNode UI_FastpathCodepointNode; struct UI_Fast typedef struct UI_GroupKeyNode UI_GroupKeyNode; struct UI_GroupKeyNode{UI_GroupKeyNode *next; UI_Key v;}; typedef struct UI_TransparencyNode UI_TransparencyNode; struct UI_TransparencyNode{UI_TransparencyNode *next; F32 v;}; typedef struct UI_PaletteNode UI_PaletteNode; struct UI_PaletteNode{UI_PaletteNode *next; UI_Palette* v;}; +typedef struct UI_TagNode UI_TagNode; struct UI_TagNode{UI_TagNode *next; String8 v;}; typedef struct UI_SquishNode UI_SquishNode; struct UI_SquishNode{UI_SquishNode *next; F32 v;}; typedef struct UI_HoverCursorNode UI_HoverCursorNode; struct UI_HoverCursorNode{UI_HoverCursorNode *next; OS_Cursor v;}; typedef struct UI_FontNode UI_FontNode; struct UI_FontNode{UI_FontNode *next; FNT_Tag v;}; @@ -54,6 +55,7 @@ UI_FastpathCodepointNode fastpath_codepoint_nil_stack_top;\ UI_GroupKeyNode group_key_nil_stack_top;\ UI_TransparencyNode transparency_nil_stack_top;\ UI_PaletteNode palette_nil_stack_top;\ +UI_TagNode tag_nil_stack_top;\ UI_SquishNode squish_nil_stack_top;\ UI_HoverCursorNode hover_cursor_nil_stack_top;\ UI_FontNode font_nil_stack_top;\ @@ -85,6 +87,7 @@ state->fastpath_codepoint_nil_stack_top.v = 0;\ state->group_key_nil_stack_top.v = ui_key_zero();\ state->transparency_nil_stack_top.v = 0;\ state->palette_nil_stack_top.v = &ui_g_nil_palette;\ +state->tag_nil_stack_top.v = str8_lit("");\ state->squish_nil_stack_top.v = 0;\ state->hover_cursor_nil_stack_top.v = OS_Cursor_Pointer;\ state->font_nil_stack_top.v = fnt_tag_zero();\ @@ -102,35 +105,36 @@ state->text_alignment_nil_stack_top.v = UI_TextAlign_Left;\ #define UI_DeclStacks \ struct\ {\ -struct { UI_ParentNode *top; UI_Box * bottom_val; UI_ParentNode *free; B32 auto_pop; } parent_stack;\ -struct { UI_ChildLayoutAxisNode *top; Axis2 bottom_val; UI_ChildLayoutAxisNode *free; B32 auto_pop; } child_layout_axis_stack;\ -struct { UI_FixedXNode *top; F32 bottom_val; UI_FixedXNode *free; B32 auto_pop; } fixed_x_stack;\ -struct { UI_FixedYNode *top; F32 bottom_val; UI_FixedYNode *free; B32 auto_pop; } fixed_y_stack;\ -struct { UI_FixedWidthNode *top; F32 bottom_val; UI_FixedWidthNode *free; B32 auto_pop; } fixed_width_stack;\ -struct { UI_FixedHeightNode *top; F32 bottom_val; UI_FixedHeightNode *free; B32 auto_pop; } fixed_height_stack;\ -struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; B32 auto_pop; } pref_width_stack;\ -struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; B32 auto_pop; } pref_height_stack;\ -struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; B32 auto_pop; } permission_flags_stack;\ -struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; B32 auto_pop; } flags_stack;\ -struct { UI_FocusHotNode *top; UI_FocusKind bottom_val; UI_FocusHotNode *free; B32 auto_pop; } focus_hot_stack;\ -struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *free; B32 auto_pop; } focus_active_stack;\ -struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; B32 auto_pop; } fastpath_codepoint_stack;\ -struct { UI_GroupKeyNode *top; UI_Key bottom_val; UI_GroupKeyNode *free; B32 auto_pop; } group_key_stack;\ -struct { UI_TransparencyNode *top; F32 bottom_val; UI_TransparencyNode *free; B32 auto_pop; } transparency_stack;\ -struct { UI_PaletteNode *top; UI_Palette* bottom_val; UI_PaletteNode *free; B32 auto_pop; } palette_stack;\ -struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; B32 auto_pop; } squish_stack;\ -struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; B32 auto_pop; } hover_cursor_stack;\ -struct { UI_FontNode *top; FNT_Tag bottom_val; UI_FontNode *free; B32 auto_pop; } font_stack;\ -struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; B32 auto_pop; } font_size_stack;\ -struct { UI_TextRasterFlagsNode *top; FNT_RasterFlags bottom_val; UI_TextRasterFlagsNode *free; B32 auto_pop; } text_raster_flags_stack;\ -struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; B32 auto_pop; } tab_size_stack;\ -struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; B32 auto_pop; } corner_radius_00_stack;\ -struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; B32 auto_pop; } corner_radius_01_stack;\ -struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; B32 auto_pop; } corner_radius_10_stack;\ -struct { UI_CornerRadius11Node *top; F32 bottom_val; UI_CornerRadius11Node *free; B32 auto_pop; } corner_radius_11_stack;\ -struct { UI_BlurSizeNode *top; F32 bottom_val; UI_BlurSizeNode *free; B32 auto_pop; } blur_size_stack;\ -struct { UI_TextPaddingNode *top; F32 bottom_val; UI_TextPaddingNode *free; B32 auto_pop; } text_padding_stack;\ -struct { UI_TextAlignmentNode *top; UI_TextAlign bottom_val; UI_TextAlignmentNode *free; B32 auto_pop; } text_alignment_stack;\ +struct { UI_ParentNode *top; UI_Box * bottom_val; UI_ParentNode *free; U64 gen; B32 auto_pop; } parent_stack;\ +struct { UI_ChildLayoutAxisNode *top; Axis2 bottom_val; UI_ChildLayoutAxisNode *free; U64 gen; B32 auto_pop; } child_layout_axis_stack;\ +struct { UI_FixedXNode *top; F32 bottom_val; UI_FixedXNode *free; U64 gen; B32 auto_pop; } fixed_x_stack;\ +struct { UI_FixedYNode *top; F32 bottom_val; UI_FixedYNode *free; U64 gen; B32 auto_pop; } fixed_y_stack;\ +struct { UI_FixedWidthNode *top; F32 bottom_val; UI_FixedWidthNode *free; U64 gen; B32 auto_pop; } fixed_width_stack;\ +struct { UI_FixedHeightNode *top; F32 bottom_val; UI_FixedHeightNode *free; U64 gen; B32 auto_pop; } fixed_height_stack;\ +struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; U64 gen; B32 auto_pop; } pref_width_stack;\ +struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; U64 gen; B32 auto_pop; } pref_height_stack;\ +struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; U64 gen; B32 auto_pop; } permission_flags_stack;\ +struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; U64 gen; B32 auto_pop; } flags_stack;\ +struct { UI_FocusHotNode *top; UI_FocusKind bottom_val; UI_FocusHotNode *free; U64 gen; B32 auto_pop; } focus_hot_stack;\ +struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *free; U64 gen; B32 auto_pop; } focus_active_stack;\ +struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; U64 gen; B32 auto_pop; } fastpath_codepoint_stack;\ +struct { UI_GroupKeyNode *top; UI_Key bottom_val; UI_GroupKeyNode *free; U64 gen; B32 auto_pop; } group_key_stack;\ +struct { UI_TransparencyNode *top; F32 bottom_val; UI_TransparencyNode *free; U64 gen; B32 auto_pop; } transparency_stack;\ +struct { UI_PaletteNode *top; UI_Palette* bottom_val; UI_PaletteNode *free; U64 gen; B32 auto_pop; } palette_stack;\ +struct { UI_TagNode *top; String8 bottom_val; UI_TagNode *free; U64 gen; B32 auto_pop; } tag_stack;\ +struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; U64 gen; B32 auto_pop; } squish_stack;\ +struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; U64 gen; B32 auto_pop; } hover_cursor_stack;\ +struct { UI_FontNode *top; FNT_Tag bottom_val; UI_FontNode *free; U64 gen; B32 auto_pop; } font_stack;\ +struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; U64 gen; B32 auto_pop; } font_size_stack;\ +struct { UI_TextRasterFlagsNode *top; FNT_RasterFlags bottom_val; UI_TextRasterFlagsNode *free; U64 gen; B32 auto_pop; } text_raster_flags_stack;\ +struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; U64 gen; B32 auto_pop; } tab_size_stack;\ +struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; U64 gen; B32 auto_pop; } corner_radius_00_stack;\ +struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; U64 gen; B32 auto_pop; } corner_radius_01_stack;\ +struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; U64 gen; B32 auto_pop; } corner_radius_10_stack;\ +struct { UI_CornerRadius11Node *top; F32 bottom_val; UI_CornerRadius11Node *free; U64 gen; B32 auto_pop; } corner_radius_11_stack;\ +struct { UI_BlurSizeNode *top; F32 bottom_val; UI_BlurSizeNode *free; U64 gen; B32 auto_pop; } blur_size_stack;\ +struct { UI_TextPaddingNode *top; F32 bottom_val; UI_TextPaddingNode *free; U64 gen; B32 auto_pop; } text_padding_stack;\ +struct { UI_TextAlignmentNode *top; UI_TextAlign bottom_val; UI_TextAlignmentNode *free; U64 gen; B32 auto_pop; } text_alignment_stack;\ } #define UI_InitStacks(state) \ state->parent_stack.top = &state->parent_nil_stack_top; state->parent_stack.bottom_val = &ui_nil_box; state->parent_stack.free = 0; state->parent_stack.auto_pop = 0;\ @@ -149,6 +153,7 @@ state->fastpath_codepoint_stack.top = &state->fastpath_codepoint_nil_stack_top; state->group_key_stack.top = &state->group_key_nil_stack_top; state->group_key_stack.bottom_val = ui_key_zero(); state->group_key_stack.free = 0; state->group_key_stack.auto_pop = 0;\ state->transparency_stack.top = &state->transparency_nil_stack_top; state->transparency_stack.bottom_val = 0; state->transparency_stack.free = 0; state->transparency_stack.auto_pop = 0;\ state->palette_stack.top = &state->palette_nil_stack_top; state->palette_stack.bottom_val = &ui_g_nil_palette; state->palette_stack.free = 0; state->palette_stack.auto_pop = 0;\ +state->tag_stack.top = &state->tag_nil_stack_top; state->tag_stack.bottom_val = str8_lit(""); state->tag_stack.free = 0; state->tag_stack.auto_pop = 0;\ state->squish_stack.top = &state->squish_nil_stack_top; state->squish_stack.bottom_val = 0; state->squish_stack.free = 0; state->squish_stack.auto_pop = 0;\ state->hover_cursor_stack.top = &state->hover_cursor_nil_stack_top; state->hover_cursor_stack.bottom_val = OS_Cursor_Pointer; state->hover_cursor_stack.free = 0; state->hover_cursor_stack.auto_pop = 0;\ state->font_stack.top = &state->font_nil_stack_top; state->font_stack.bottom_val = fnt_tag_zero(); state->font_stack.free = 0; state->font_stack.auto_pop = 0;\ @@ -180,6 +185,7 @@ if(state->fastpath_codepoint_stack.auto_pop) { ui_pop_fastpath_codepoint(); stat if(state->group_key_stack.auto_pop) { ui_pop_group_key(); state->group_key_stack.auto_pop = 0; }\ if(state->transparency_stack.auto_pop) { ui_pop_transparency(); state->transparency_stack.auto_pop = 0; }\ if(state->palette_stack.auto_pop) { ui_pop_palette(); state->palette_stack.auto_pop = 0; }\ +if(state->tag_stack.auto_pop) { ui_pop_tag(); state->tag_stack.auto_pop = 0; }\ if(state->squish_stack.auto_pop) { ui_pop_squish(); state->squish_stack.auto_pop = 0; }\ if(state->hover_cursor_stack.auto_pop) { ui_pop_hover_cursor(); state->hover_cursor_stack.auto_pop = 0; }\ if(state->font_stack.auto_pop) { ui_pop_font(); state->font_stack.auto_pop = 0; }\ @@ -210,6 +216,7 @@ internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); internal UI_Palette* ui_top_palette(void); +internal String8 ui_top_tag(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -239,6 +246,7 @@ internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); internal UI_Palette* ui_bottom_palette(void); +internal String8 ui_bottom_tag(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -268,6 +276,7 @@ internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); internal UI_Palette* ui_push_palette(UI_Palette* v); +internal String8 ui_push_tag(String8 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -297,6 +306,7 @@ internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); internal UI_Palette* ui_pop_palette(void); +internal String8 ui_pop_tag(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -326,6 +336,7 @@ internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); internal UI_Palette* ui_set_next_palette(UI_Palette* v); +internal String8 ui_set_next_tag(String8 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index 07978b11..36c794ff 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -33,6 +33,7 @@ UI_StackTable: //- rjf: colors { Transparency transparency F32 0 } { Palette palette `UI_Palette* ` `&ui_g_nil_palette` } + { Tag tag String8 `str8_lit("")` } //- rjf: squish { Squish squish F32 0 } @@ -94,7 +95,7 @@ UI_StackTable: `#define UI_DeclStacks \\`; `struct\\`; `{\\`; - @expand(UI_StackTable a) `struct { UI_$(a.name)Node *top; $(a.type) bottom_val; UI_$(a.name)Node *free; B32 auto_pop; } $(a.name_lower)_stack;\\`; + @expand(UI_StackTable a) `struct { UI_$(a.name)Node *top; $(a.type) bottom_val; UI_$(a.name)Node *free; U64 gen; B32 auto_pop; } $(a.name_lower)_stack;\\`; `}`; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index bf47fa37..864302bc 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2350,6 +2350,19 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_padding = ui_state->text_padding_stack.top->v; box->hover_cursor = ui_state->hover_cursor_stack.top->v; box->custom_draw = 0; + if(ui_state->current_gen_tags_gen != ui_state->tag_stack.gen) + { + ui_state->current_gen_tags_gen = ui_state->tag_stack.gen; + Temp scratch = scratch_begin(0, 0); + String8List tags = {0}; + for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) + { + str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); + } + ui_state->current_gen_tags = str8_array_from_list(ui_build_arena(), &tags); + scratch_end(scratch); + } + box->tags = ui_state->current_gen_tags; } //- rjf: auto-pop all stacks @@ -3147,6 +3160,7 @@ if(node->next == &state->name_lower##_nil_stack_top)\ state->name_lower##_stack.bottom_val = (new_value);\ }\ state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ return old_value; #define UI_StackPopImpl(state, name_upper, name_lower) \ @@ -3156,6 +3170,7 @@ if(popped != &state->name_lower##_nil_stack_top)\ SLLStackPop(state->name_lower##_stack.top);\ SLLStackPush(state->name_lower##_stack.free, popped);\ state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ }\ return popped->v;\ @@ -3167,6 +3182,7 @@ type old_value = state->name_lower##_stack.top->v;\ node->v = new_value;\ SLLStackPush(state->name_lower##_stack.top, node);\ state->name_lower##_stack.auto_pop = 1;\ +state->name_lower##_stack.gen += 1;\ return old_value; #include "generated/ui.meta.c" diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index baac0660..0a23acb5 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -366,29 +366,32 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_DrawDropShadow (UI_BoxFlags)(1ull<<27) # define UI_BoxFlag_DrawBackgroundBlur (UI_BoxFlags)(1ull<<28) # define UI_BoxFlag_DrawBackground (UI_BoxFlags)(1ull<<29) -# define UI_BoxFlag_DrawBackgroundAlt (UI_BoxFlags)(1ull<<30) -# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<31) -# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<32) -# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<33) -# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<34) -# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<35) -# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<36) -# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<37) -# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<38) -# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<39) -# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<40) -# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<41) -# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<42) -# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<43) -# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<44) -# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<45) -# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<46) -# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<47) -# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<48) -# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<49) -# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<50) -# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<51) -# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<52) +# define UI_BoxFlag_DrawAlt (UI_BoxFlags)(1ull<<30) +# define UI_BoxFlag_DrawGood (UI_BoxFlags)(1ull<<31) +# define UI_BoxFlag_DrawBad (UI_BoxFlags)(1ull<<32) +# define UI_BoxFlag_DrawPop (UI_BoxFlags)(1ull<<33) +# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<34) +# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<35) +# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<36) +# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<37) +# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<38) +# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<39) +# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<40) +# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<41) +# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<42) +# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<43) +# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<44) +# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<45) +# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<46) +# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<47) +# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<48) +# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<49) +# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<50) +# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<51) +# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<52) +# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<53) +# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<54) +# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<55) //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) @@ -420,6 +423,7 @@ struct UI_Box //- rjf: per-build equipment UI_Key key; UI_BoxFlags flags; + String8Array tags; String8 string; UI_TextAlign text_align; Vec2F32 fixed_position; @@ -659,6 +663,9 @@ struct UI_State //- rjf: build state machine state B32 is_in_open_ctx_menu; + B32 tooltip_can_overflow_window; + String8Array current_gen_tags; + U64 current_gen_tags_gen; //- rjf: build phase output UI_Box *root; @@ -668,7 +675,6 @@ struct UI_State U64 build_box_count; U64 last_build_box_count; B32 ctx_menu_touched_this_frame; - B32 tooltip_can_overflow_window; B32 is_animating; //- rjf: build parameters From 1b8e39c635868d1674e27fe076f37c72b760ed19 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Feb 2025 18:08:18 -0800 Subject: [PATCH 140/755] work on tag-based styling --- src/base/base_strings.c | 47 +-- src/base/base_strings.h | 1 + src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 104 +++--- src/raddbg/raddbg_core.c | 514 ++++++++++++++--------------- src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_views.c | 46 ++- src/raddbg/raddbg_widgets.c | 51 +-- src/ui/generated/ui.meta.c | 11 +- src/ui/generated/ui.meta.h | 11 + src/ui/ui.mdesk | 17 +- src/ui/ui_core.c | 121 ++++--- src/ui/ui_core.h | 9 + 13 files changed, 501 insertions(+), 439 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 9e42e0cd..ed5d3147 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -242,7 +242,7 @@ str8_cstring_capped_reverse(void *raw_start, void *raw_cap) for(; ptr > start; ) { ptr -= 1; - + if (*ptr == '\0') { break; @@ -619,7 +619,7 @@ internal String8 str8_from_memory_size(Arena *arena, U64 size) { String8 result; - + if(size < KB(1)) { result = push_str8f(arena, "%llu Bytes", size); @@ -640,7 +640,7 @@ str8_from_memory_size(Arena *arena, U64 size) { result = push_str8f(arena, "%llu.%02llu TiB", size / TB(1), ((size * 100) / TB(1)) % 100); } - + return result; } @@ -648,7 +648,7 @@ internal String8 str8_from_count(Arena *arena, U64 count) { String8 result; - + if(count < 1 * 1000) { result = push_str8f(arena, "%llu", count); @@ -689,7 +689,7 @@ str8_from_count(Arena *arena, U64 count) result = push_str8f(arena, "%lluB", count / 1000000000, frac); } } - + return result; } @@ -1114,6 +1114,13 @@ str8_list_from_flags(Arena *arena, String8List *list, //////////////////////////////// //~ rjf; String Arrays +internal String8Array +str8_array_zero(void) +{ + String8Array result = {0}; + return result; +} + internal String8Array str8_array_from_list(Arena *arena, String8List *list) { @@ -1827,10 +1834,10 @@ try_guid_from_string(String8 string, Guid *guid_out) String8 data4_hi_str = list.first->next->next->next->string; String8 data4_lo_str = list.first->next->next->next->next->string; if(str8_is_integer(data1_str, 16) && - str8_is_integer(data2_str, 16) && - str8_is_integer(data3_str, 16) && - str8_is_integer(data4_hi_str, 16) && - str8_is_integer(data4_lo_str, 16)) + str8_is_integer(data2_str, 16) && + str8_is_integer(data3_str, 16) && + str8_is_integer(data4_hi_str, 16) && + str8_is_integer(data4_lo_str, 16)) { U64 data1 = u64_from_str8(data1_str, 16); U64 data2 = u64_from_str8(data2_str, 16); @@ -1838,10 +1845,10 @@ try_guid_from_string(String8 string, Guid *guid_out) U64 data4_hi = u64_from_str8(data4_hi_str, 16); U64 data4_lo = u64_from_str8(data4_lo_str, 16); if(data1 <= max_U32 && - data2 <= max_U16 && - data3 <= max_U16 && - data4_hi <= max_U16 && - data4_lo <= 0xffffffffffff) + data2 <= max_U16 && + data3 <= max_U16 && + data4_hi <= max_U16 && + data4_lo <= 0xffffffffffff) { guid_out->data1 = (U32)data1; guid_out->data2 = (U16)data2; @@ -2381,18 +2388,18 @@ str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) { U8 byte = 0; U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); - + if(bytes_read != sizeof(byte)) { break; } - + U8 val = byte & 0x7fu; value |= ((U64)val) << shift; - + cursor += bytes_read; shift += 7u; - + if((byte & 0x80u) == 0) { break; @@ -2420,13 +2427,13 @@ str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) { break; } - + U8 val = byte & 0x7fu; value |= ((U64)val) << shift; - + cursor += bytes_read; shift += 7u; - + if((byte & 0x80u) == 0) { if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) diff --git a/src/base/base_strings.h b/src/base/base_strings.h index fc946dd8..9c1eee7b 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -284,6 +284,7 @@ internal void str8_list_from_flags(Arena *arena, String8List *list, U32 //////////////////////////////// //~ rjf; String Arrays +internal String8Array str8_array_zero(void); internal String8Array str8_array_from_list(Arena *arena, String8List *list); internal String8Array str8_array_reserve(Arena *arena, U64 count); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b0b5f6a9..e427e354 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -809,7 +809,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n good: background: 0x222222ff,\n bad: background: 0x222222ff,\n pop: background: 0x222222ff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xe5e5e5ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n good:\n {\n background: 0x2c5b36ff,\n border: 0x3f3f3fff,\n }\n\n bad:\n {\n background: 0x803425ff,\n border: 0xe88774ff,\n }\n\n pop:\n {\n background: 0x355b6eff,\n border: 0x355b6eff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffffff,\n border: 0xffffffff,\n }\n\n code:\n {\n default: text: 0xcbcbcbff,\n symbol: text: 0x42a2cfff,\n type: text: 0xfec746ff,\n local: text: 0x98bc80ff,\n register: text: 0xb7afd5ff,\n keyword: text: 0xb38d4cff,\n delimiter_or_operator: text: 0x767676ff,\n numeric: text: 0x98abb1ff,\n numeric_alt_digit_group: text: 0x738287ff,\n string: text: 0x98abb1ff,\n meta: text: 0xd96759ff,\n comment: text: 0x717171ff,\n line_info_0: background: 0x99503dff,\n line_info_1: background: 0xfe8249ff,\n line_info_2: background: 0xffba17ff,\n line_info_3: background: 0xcefd69ff,\n line_info_4: background: 0x99503dff,\n line_info_5: background: 0xfe8249ff,\n line_info_6: background: 0xcefd69ff,\n line_info_7: background: 0x99503dff,\n }\n\n debug_state:\n {\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n good_pop: background: 0x2c5b36ff,\n bad_pop: background: 0x803425ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xe5e5e5ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x2222225f,\n background: alt: 0x2222225f,\n border: 0xbfbfbf1f,\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n good:\n {\n background: 0x2c5b36ff,\n border: 0x3f3f3fff,\n }\n\n bad:\n {\n background: 0x803425ff,\n border: 0xe88774ff,\n }\n\n pop:\n {\n background: 0x355b6eff,\n border: 0x355b6eff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a196fe68..bb2db7ca 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -989,9 +989,11 @@ RD_ThemePresetTable: { background: 0x1b1b1bff, alt: background: 0x222222ff, - good: background: 0x222222ff, - bad: background: 0x222222ff, - pop: background: 0x222222ff, + good_pop: background: 0x2c5b36ff, + bad_pop: background: 0x803425ff, + good: text: 0x32a852ff, + bad: text: 0xcf5242ff, + pop: background: 0x355b6eff, border: 0x404040ff, text: 0xe5e5e5ff, weak: text: 0xe5e5e5ff, @@ -999,6 +1001,47 @@ RD_ThemePresetTable: focus: 0xfda200ff, cursor: 0x8aff00ff, selection: 0x99ccffff, + inactive: background: 0x0000002f, + drop_shadow: 0x0000007f, + + code_default: 0xcbcbcbff, + code_symbol: 0x42a2cfff, + code_type: 0xfec746ff, + code_local: 0x98bc80ff, + code_register: 0xb7afd5ff, + code_keyword: 0xb38d4cff, + code_delimiter_or_operator: 0x767676ff, + code_numeric: 0x98abb1ff, + code_numeric_alt_digit_group: 0x738287ff, + code_string: 0x98abb1ff, + code_meta: 0xd96759ff, + code_comment: 0x717171ff, + line_info_0: 0x99503dff, + line_info_1: 0xfe8249ff, + line_info_2: 0xffba17ff, + line_info_3: 0xcefd69ff, + line_info_4: 0x99503dff, + line_info_5: 0xfe8249ff, + line_info_6: 0xcefd69ff, + line_info_7: 0x99503dff, + thread_0: 0xffcb7fff, + thread_1: 0xb2ff65ff, + thread_2: 0xff99e5ff, + thread_3: 0x6598ffff, + thread_4: 0x65ffcbff, + thread_5: 0xff9819ff, + thread_6: 0x9932ffff, + thread_7: 0x65ff4cff, + thread_unwound: 0xb2ccd8ff, + thread_error: 0xb23219ff, + breakpoint: 0xa72911ff, + + floating: + { + background: 0x2222225f, + background: alt: 0x2222225f, + border: 0xbfbfbf1f, + } menu_bar: { @@ -1030,6 +1073,18 @@ RD_ThemePresetTable: border: 0x3f3f3fff, } + implicit: + { + background: 0x00000000, + border: 0x00000000, + } + + hollow: + { + background: 0x00000000, + border: 0xffffff1f, + } + tab: { background: 0x6f5135ff, @@ -1043,47 +1098,8 @@ RD_ThemePresetTable: drop_site: { - background: 0xffffffff, - border: 0xffffffff, - } - - code: - { - default: text: 0xcbcbcbff, - symbol: text: 0x42a2cfff, - type: text: 0xfec746ff, - local: text: 0x98bc80ff, - register: text: 0xb7afd5ff, - keyword: text: 0xb38d4cff, - delimiter_or_operator: text: 0x767676ff, - numeric: text: 0x98abb1ff, - numeric_alt_digit_group: text: 0x738287ff, - string: text: 0x98abb1ff, - meta: text: 0xd96759ff, - comment: text: 0x717171ff, - line_info_0: background: 0x99503dff, - line_info_1: background: 0xfe8249ff, - line_info_2: background: 0xffba17ff, - line_info_3: background: 0xcefd69ff, - line_info_4: background: 0x99503dff, - line_info_5: background: 0xfe8249ff, - line_info_6: background: 0xcefd69ff, - line_info_7: background: 0x99503dff, - } - - debug_state: - { - thread_0: 0xffcb7fff, - thread_1: 0xb2ff65ff, - thread_2: 0xff99e5ff, - thread_3: 0x6598ffff, - thread_4: 0x65ffcbff, - thread_5: 0xff9819ff, - thread_6: 0x9932ffff, - thread_7: 0x65ff4cff, - thread_unwound: 0xb2ccd8ff, - thread_error: 0xb23219ff, - breakpoint: 0xa72911ff, + background: 0xffffff05, + border: 0xffffff0f, } } ``` diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5c572a61..53816c65 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1997,10 +1997,10 @@ rd_hsva_from_cfg(RD_Cfg *cfg) } internal Vec4F32 -rd_rgba_from_cfg(RD_Cfg *cfg) +rd_color_from_cfg(RD_Cfg *cfg) { Vec4F32 hsva = rd_hsva_from_cfg(cfg); - Vec4F32 rgba = rgba_from_hsva(hsva); + Vec4F32 rgba = linear_from_srgba(rgba_from_hsva(hsva)); return rgba; } @@ -2105,7 +2105,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) String8 expr_string = rd_expr_from_cfg(cfg); String8 collection_name = {0}; String8 file_path = {0}; - Vec4F32 rgba = linear_from_srgba(rd_rgba_from_cfg(cfg)); + Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); if(rgba.w == 0) { rgba = ui_top_palette()->text; @@ -2686,12 +2686,12 @@ rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) //~ rjf: Control Entity Info Extraction internal Vec4F32 -rd_rgba_from_ctrl_entity(CTRL_Entity *entity) +rd_color_from_ctrl_entity(CTRL_Entity *entity) { Vec4F32 result = {0}; if(entity->rgba != 0) { - result = rgba_from_u32(entity->rgba); + result = linear_from_srgba(rgba_from_u32(entity->rgba)); } if(entity->rgba == 0) switch(entity->kind) { @@ -2702,11 +2702,11 @@ rd_rgba_from_ctrl_entity(CTRL_Entity *entity) CTRL_Entity *main_thread = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Thread); if(main_thread != entity) { - result = srgba_from_linear(rd_rgba_from_theme_color(RD_ThemeColor_Thread1)); + result = rd_color_from_tags(str8_array_zero(), str8_lit("thread_1")); } else { - result = srgba_from_linear(rd_rgba_from_theme_color(RD_ThemeColor_Thread0)); + result = rd_color_from_tags(str8_array_zero(), str8_lit("thread_0")); } }break; } @@ -2735,7 +2735,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e //- rjf: unpack entity info F32 extras_size = ui_top_font_size()*0.95f; - Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(entity)); + Vec4F32 color = rd_color_from_ctrl_entity(entity); if(color.w == 0) { color = ui_top_palette()->text; @@ -2782,7 +2782,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e { CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); String8 process_name = rd_name_from_ctrl_entity(arena, process); - Vec4F32 process_color = rd_rgba_from_ctrl_entity(process); + Vec4F32 process_color = rd_color_from_ctrl_entity(process); if(process_color.w == 0) { process_color = color; @@ -2813,6 +2813,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e //- rjf: threads get callstack extras if(entity->kind == CTRL_EntityKind_Thread && include_extras) { + Vec4F32 symbol_color = rd_color_from_tags(str8_array_zero(), str8_lit("code_symbol")); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); @@ -2834,7 +2835,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e name = push_str8_copy(arena, name); if(name.size != 0) { - dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol)); + dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color); if(idx+1 < unwind.frames.count) { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); @@ -3756,7 +3757,7 @@ rd_view_ui(Rng2F32 rect) CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); //- rjf: icon & info - UI_Padding(ui_em(2.f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") { //- rjf: icon { @@ -3800,7 +3801,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(22.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_Pop) + UI_TagF("pop") if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); @@ -3820,7 +3821,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(22.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_Good) + UI_TagF("good_pop") { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) { @@ -3845,7 +3846,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: or text if(helper_built) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) @@ -3855,7 +3856,7 @@ rd_view_ui(Rng2F32 rect) } //- rjf: helper text for command lister activation - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) @@ -4509,6 +4510,124 @@ rd_window_frame(void) ws->window_temporarily_focused_ipc = 0; ui_select_state(ws->ui); + ////////////////////////////// + //- rjf: compute window's theme + // + { + //- rjf: for this window, scan upwards, and then try the project, then the user, until we + // find explicit preset / colors trees in the config. we will prefer the tightest ones, so + // that windows can have their own colors, and have those override higher-up settings. + RD_Cfg *preset_cfg = &rd_nil_cfg; + RD_CfgList colors_cfgs = {0}; + RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; + for EachElement(idx, scan_parents) + { + for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) + { + if(preset_cfg != &rd_nil_cfg) + { + RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); + if(possible_preset_cfg != &rd_nil_cfg) + { + preset_cfg = possible_preset_cfg; + } + } + RD_Cfg *colors_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("colors")); + if(colors_cfg != &rd_nil_cfg) + { + rd_cfg_list_push_front(scratch.arena, &colors_cfgs, colors_cfg); + } + if(preset_cfg != &rd_nil_cfg && colors_cfg != &rd_nil_cfg) + { + break; + } + } + } + + //- rjf: map the preset config to the associated preset tree + MD_Node *preset_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; + if(preset_cfg != &rd_nil_cfg) + { + String8 preset_name = preset_cfg->first->string; + for EachEnumVal(RD_ThemePreset, p) + { + if(str8_match(preset_name, rd_theme_preset_code_string_table[p], 0)) + { + preset_tree = rd_state->theme_preset_trees[p]; + break; + } + } + } + + //- rjf: build tasks for color applications - each task comprises of a metadesk + // tree, describing the color patterns + typedef struct ThemeTask ThemeTask; + struct ThemeTask + { + ThemeTask *next; + MD_Node *tree; + }; + ThemeTask start_task = {0, preset_tree}; + ThemeTask *first_task = &start_task; + ThemeTask *last_task = first_task; + { + for(RD_CfgNode *n = colors_cfgs.first; n != 0; n = n->next) + { + ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); + SLLQueuePush(first_task, last_task, t); + t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); + } + } + + //- rjf: apply theme tasks, build each color pattern for this window's + // structured theme + typedef struct ThemePatternNode ThemePatternNode; + struct ThemePatternNode + { + ThemePatternNode *next; + RD_ThemePattern pattern; + }; + ThemePatternNode *first_pattern = 0; + ThemePatternNode *last_pattern = 0; + U64 pattern_count = 0; + for(ThemeTask *t = first_task; t != 0; t = t->next) + { + MD_Node *tree_root = t->tree; + for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) + { + if(n->flags & MD_NodeFlag_Numeric && md_node_is_nil(n->first)) + { + U64 color_srgba_u64 = 0; + try_u64_from_str8_c_rules(n->string, &color_srgba_u64); + Vec4F32 color_srgba = rgba_from_u32((U32)color_srgba_u64); + Vec4F32 color_linear = linear_from_srgba(color_srgba); + String8List tags = {0}; + for(MD_Node *parent = n->parent; parent != tree_root && !md_node_is_nil(parent); parent = parent->parent) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(rd_frame_arena(), parent->string)); + } + ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); + node->pattern.tags = str8_array_from_list(rd_frame_arena(), &tags); + node->pattern.linear = color_linear; + SLLQueuePush(first_pattern, last_pattern, node); + pattern_count += 1; + } + } + } + + //- rjf: convert to final pattern array + ws->theme = push_array(rd_frame_arena(), RD_Theme, 1); + ws->theme->patterns_count = pattern_count; + ws->theme->patterns = push_array(rd_frame_arena(), RD_ThemePattern, ws->theme->patterns_count); + { + U64 idx = 0; + for(ThemePatternNode *n = first_pattern; n != 0; n = n->next, idx += 1) + { + ws->theme->patterns[idx] = n->pattern; + } + } + } + ////////////////////////////// //- rjf: pre-emptively rasterize common glyphs on the first frame // @@ -4787,18 +4906,18 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_FontSize(ui_top_font_size() - 1.f) UI_CornerRadius(ui_top_font_size()*0.5f) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(arch_str); + UI_TagF("weak") UI_FlagsAdd(UI_BoxFlag_DrawBorder) ui_label(arch_str); ui_spacer(ui_em(0.5f, 1.f)); if(ctrl_entity->kind == CTRL_EntityKind_Thread || ctrl_entity->kind == CTRL_EntityKind_Process) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("ID: %i", (U32)ctrl_entity->id); + UI_TagF("weak") UI_FlagsAdd(UI_BoxFlag_DrawBorder) ui_labelf("ID: %i", (U32)ctrl_entity->id); } } } // rjf: debug info status - if(ctrl_entity->kind == CTRL_EntityKind_Module) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + if(ctrl_entity->kind == CTRL_EntityKind_Module) UI_TagF("weak") { DI_Scope *di_scope = di_scope_open(); DI_Key dbgi_key = ctrl_dbgi_key_from_module(ctrl_entity); @@ -4821,6 +4940,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: unwind if(ctrl_entity->kind == CTRL_EntityKind_Thread) { + Vec4F32 symbol_color = rd_color_from_tags(str8_array_zero(), str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); @@ -4849,21 +4969,21 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The name.str = rdi_name_from_procedure(rdi, procedure, &name.size); name.size = Min(512, name.size); } - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); + UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); if(f->parent_num != 0) { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); + RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); } if(name.size != 0) { RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); + rd_code_label(1.f, 0, symbol_color, name); } } else { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); + RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); } } } @@ -4892,8 +5012,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Size main_width = ui_top_pref_width(); UI_Size main_height = ui_top_pref_height(); UI_TextAlign main_text_align = ui_top_text_alignment(); - RD_Palette(RD_PaletteCode_Tab) - UI_Tooltip + UI_Tooltip UI_PrefWidth(main_width) UI_PrefHeight(main_height) UI_TextAlignment(main_text_align) @@ -5287,9 +5406,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_flags(UI_BoxFlag_DrawBorder); - UI_Row UI_Padding(ui_em(0.5f, 1.f)) + UI_Row UI_Padding(ui_em(0.5f, 1.f)) UI_TagF("weak") { - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, ui_key_zero()); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_string(box, item->kind_name); } } @@ -5299,7 +5418,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: description if(flags & RD_ListerFlag_Descriptions) { - if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_Flags(UI_BoxFlag_DrawTextWeak) + if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TagF("weak") { UI_Box *box = ui_label(item->description).box; ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); @@ -6117,9 +6236,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // if(ws->drop_completion_paths.node_count != 0) { - UI_CtxMenu(rd_state->drop_completion_key) UI_PrefWidth(ui_em(40.f, 1.f)) + UI_CtxMenu(rd_state->drop_completion_key) UI_PrefWidth(ui_em(40.f, 1.f)) UI_TagF("implicit") { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") for(String8Node *n = ws->drop_completion_paths.first; n != 0; n = n->next) { UI_Row UI_Padding(ui_em(1.f, 1.f)) @@ -6217,11 +6336,11 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_WidthFill UI_PrefHeight(ui_children_sum(1.f)) UI_Column UI_Padding(ui_pct(1, 0)) { UI_TextRasterFlags(rd_raster_flags_from_slot(RD_FontSlot_Main)) UI_FontSize(ui_top_font_size()*2.f) UI_PrefHeight(ui_em(3.f, 1.f)) ui_label(rd_state->popup_title); - UI_PrefHeight(ui_em(3.f, 1.f)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(rd_state->popup_desc); + UI_PrefHeight(ui_em(3.f, 1.f)) UI_TagF("weak") ui_label(rd_state->popup_desc); ui_spacer(ui_em(1.5f, 1.f)); UI_Row UI_Padding(ui_pct(1.f, 0.f)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_PrefHeight(ui_em(3.5f, 1.f)) UI_CornerRadius(ui_top_font_size()*0.5f) { - RD_Palette(RD_PaletteCode_Pop) + UI_TagF("pop") if(ui_clicked(ui_buttonf("OK")) || (ui_key_match(bg_box->default_nav_focus_hot_key, ui_key_zero()) && ui_slot_press(UI_EventActionSlot_Accept))) { rd_cmd(RD_CmdKind_PopupAccept); @@ -6248,8 +6367,8 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The os_window_push_custom_edges(ws->os, window_edge_px); os_window_push_custom_title_bar(ws->os, dim_2f32(top_bar_rect).y); ui_set_next_flags(UI_BoxFlag_DefaultFocusNav|UI_BoxFlag_DisableFocusOverlay); - RD_Palette(RD_PaletteCode_MenuBar) - UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused) ? UI_FocusKind_On : UI_FocusKind_Null) + UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused) ? UI_FocusKind_On : UI_FocusKind_Null) + UI_TagF("menu_bar") UI_Pane(top_bar_rect, str8_lit("###top_bar")) UI_WidthFill UI_Row UI_Focus(UI_FocusKind_Null) @@ -6281,7 +6400,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { // rjf: file menu UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); - UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -6305,7 +6424,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: window menu UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); - UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -6325,7 +6444,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: panel menu UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); - UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -6369,7 +6488,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: view menu UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -6423,7 +6542,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: targets menu UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); - UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { Temp scratch = scratch_begin(0, 0); String8 cmds[] = @@ -6441,7 +6560,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: ctrl menu UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); - UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -6471,9 +6590,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: help menu UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); - UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) + UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { - UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_TagF("weak") ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); ui_spacer(ui_em(1.f, 1.f)); UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1, 0)) @@ -6496,7 +6615,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); } ui_spacer(ui_em(1.f, 1.f)); - RD_Palette(RD_PaletteCode_Pop) + UI_TagF("pop") UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) UI_CornerRadius(ui_top_font_size()*0.5f) { @@ -6610,7 +6729,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_spacer(ui_em(0.75f, 1)); // rjf: conversion task visualization - UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill RD_Palette(RD_PaletteCode_Pop) + UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill UI_TagF("pop") { Temp scratch = scratch_begin(0, 0); RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); @@ -6658,7 +6777,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The if(can_play || !have_targets || processes.count == 0) UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - RD_Palette(can_play ? RD_PaletteCode_Good : RD_PaletteCode_MenuBar) + UI_TagF(can_play ? "good" : "") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6700,7 +6819,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: restart button else UI_TextAlignment(UI_TextAlign_Center) - RD_Palette(RD_PaletteCode_Good) + UI_TagF("good") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Redo]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6721,7 +6840,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: pause button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) - RD_Palette(can_pause ? RD_PaletteCode_Pop : RD_PaletteCode_MenuBar) { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6747,7 +6865,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: stop button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - RD_Palette(can_stop ? RD_PaletteCode_Bad : RD_PaletteCode_MenuBar) + UI_TagF(can_stop ? "bad" : "") { UI_Signal sig = {0}; { @@ -6873,7 +6991,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_spacer(ui_pct(1, 0)); // rjf: loaded user viz - if(do_user_prof) RD_Palette(RD_PaletteCode_Pop) + if(do_user_prof) UI_TagF("pop") { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -6907,7 +7025,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } // rjf: loaded project viz - if(do_user_prof) RD_Palette(RD_PaletteCode_Pop) + if(do_user_prof) UI_TagF("pop") { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); @@ -6966,7 +7084,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The max_sig = rd_icon_buttonf(RD_IconKind_Window, 0, "##maximize"); } UI_PrefWidth(ui_px(button_dim, 1.f)) - RD_Palette(RD_PaletteCode_Bad) + UI_TagF("bad_pop") { cls_sig = rd_icon_buttonf(RD_IconKind_X, 0, "##close"); } @@ -7062,6 +7180,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) RD_Font(RD_FontSlot_Code) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") { F32 hover_eval_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_open_t"), 1.f); RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); @@ -7241,7 +7360,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Flags(UI_BoxFlag_DrawBackground) UI_TextAlignment(UI_TextAlign_Center) UI_CornerRadius(4) - RD_Palette(RD_PaletteCode_Pop) + UI_TagF("pop") ui_labelf("Currently rebinding \"%S\" hotkey", display_name); } @@ -7374,7 +7493,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -7465,7 +7584,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -7766,13 +7885,14 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) { ui_set_next_child_layout_axis(split_axis); - UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) + UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") { if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSite) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); ui_spacer(ui_px(padding, 1.f)); if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - RD_Palette(RD_PaletteCode_DropSite) ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); } } } @@ -7782,7 +7902,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { ui_set_next_child_layout_axis(split_axis); UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); - UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) RD_Palette(RD_PaletteCode_DropSite) + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") { ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); } @@ -7831,7 +7951,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), }; - UI_Rect(future_split_rect) RD_Palette(RD_PaletteCode_DropSite) UI_CornerRadius(ui_top_font_size()*2.f) + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -7875,7 +7995,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Parent(filter_box) UI_WidthFill UI_HeightFill { UI_PrefWidth(ui_em(3.f, 1.f)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") RD_Font(RD_FontSlot_Icons) UI_TextAlignment(UI_TextAlign_Center) ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); @@ -7915,13 +8035,8 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // if(build_panel) if(panel != panel_tree.focused) { - Vec4F32 darken_color = rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay); - darken_color.w *= 0.2f; - UI_Palette(ui_build_palette(0, .background = darken_color)) - UI_Rect(content_rect) - { + UI_Rect(content_rect) UI_TagF("inactive") ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } } ////////////////////////// @@ -7978,7 +8093,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) { ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_TagF("weak") UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) { UI_PrefHeight(ui_em(3.f, 1.f)) @@ -7987,7 +8102,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_em(15.f, 1.f)) UI_CornerRadius(ui_top_font_size()/2.f) - RD_Palette(RD_PaletteCode_Bad) + UI_TagF("bad_pop") { if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) { @@ -8180,7 +8295,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ////////////////////////// //- rjf: build tab bar contents // - if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) + if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) UI_TagF("tab") { F32 corner_radius = ui_top_font_size()*0.6f; TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; @@ -8207,21 +8322,16 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: choose palette B32 omit_name = 0; - RD_PaletteCode palette_code = RD_PaletteCode_TabInactive; - if(tab_is_selected) - { - palette_code = RD_PaletteCode_Tab; - } if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - palette_code = RD_PaletteCode_DropSite; omit_name = 1; } // rjf: build tab container box UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - RD_Palette(palette_code) + UI_TagF(omit_name ? "hollow" : "") + UI_TagF(!tab_is_selected ? "inactive" : "") { if(panel->tab_side == Side_Max) { @@ -8254,14 +8364,21 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_Flags(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_CornerRadius00(0) UI_CornerRadius01(0) { UI_Palette *palette = ui_build_palette(ui_top_palette()); palette->background = v4f32(0, 0, 0, 0); ui_set_next_palette(palette); - UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects, + "%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + UI_Signal sig = ui_signal_from_box(close_box); if(ui_clicked(sig) || ui_middle_clicked(sig)) { rd_cmd(RD_CmdKind_CloseTab); @@ -8317,7 +8434,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: build spot container box UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - RD_Palette(RD_PaletteCode_DropSite) + UI_TagF("hollow") { if(panel->tab_side == Side_Max) { @@ -8363,12 +8480,13 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("implicit") + UI_TagF("weak") UI_HoverCursor(OS_Cursor_HandPoint) { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawText| + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawActiveEffects| UI_BoxFlag_Clickable| @@ -8568,6 +8686,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: unpack settings B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); + Vec4F32 base_background_color = rd_color_from_tags(str8_array_zero(), str8_lit("background")); + Vec4F32 base_border_color = rd_color_from_tags(str8_array_zero(), str8_lit("border")); + Vec4F32 drop_shadow_color = rd_color_from_tags(str8_array_zero(), str8_lit("drop_shadow")); //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; @@ -8586,14 +8707,12 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: draw background color { - Vec4F32 bg_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackground); - dr_rect(os_client_rect_from_window(ws->os), bg_color, 0, 0, 0); + dr_rect(os_client_rect_from_window(ws->os), base_background_color, 0, 0, 0); } //- rjf: draw window border { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBorder); - dr_rect(os_client_rect_from_window(ws->os), color, 0, 1.f, 0.5f); + dr_rect(os_client_rect_from_window(ws->os), base_border_color, 0, 1.f, 0.5f); } //- rjf: recurse & draw @@ -8638,7 +8757,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The if(box->flags & UI_BoxFlag_DrawDropShadow) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); - Vec4F32 drop_shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); } @@ -8649,53 +8767,47 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The MemoryCopyArray(params->corner_radii, box->corner_radii); } + // rjf: compute effective active t + F32 effective_active_t = box->active_t; + if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) + { + effective_active_t = 0; + } + F32 t = box->hot_t*(1-effective_active_t); + + // rjf: compute background color + Vec4F32 box_background_color = {0}; + if(box->flags & UI_BoxFlag_DrawBackground) + { + box_background_color = rd_color_from_tags(box->tags, str8_lit("background")); + } + // rjf: draw background if(box->flags & UI_BoxFlag_DrawBackground) { - F32 effective_active_t = box->active_t; - if(!(box->flags & UI_BoxFlag_DrawActiveEffects)) - { - effective_active_t = 0; - } - F32 t = box->hot_t*(1-effective_active_t); - // rjf: hot effect extension (drop shadow) if(box->flags & UI_BoxFlag_DrawHotEffects) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); - Vec4F32 drop_shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); - drop_shadow_color.w *= t; - drop_shadow_color.w *= box->palette->colors[UI_ColorCode_Background].w; - dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + Vec4F32 color = drop_shadow_color; + color.w *= t*box_background_color.w; + dr_rect(drop_shadow_rect, color, 0.8f, 0, 8.f); } - // rjf: main rectangle - { - Vec4F32 color = box->palette->colors[UI_ColorCode_Background]; - if(box->flags & UI_BoxFlag_DrawBad) - { - color = box->palette->colors[UI_ColorCode_BackgroundBad]; - } - else if(box->flags & UI_BoxFlag_DrawGood) - { - color = box->palette->colors[UI_ColorCode_BackgroundGood]; - } - else if(box->flags & UI_BoxFlag_DrawPop) - { - color = box->palette->colors[UI_ColorCode_BackgroundPop]; - } - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), color, 0, 0, 1.f); - MemoryCopyArray(inst->corner_radii, box->corner_radii); - } + // rjf: draw background + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box_background_color, 0, 0, 1.f); + MemoryCopyArray(inst->corner_radii, box->corner_radii); // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { + Vec4F32 hover_color = rd_color_from_tags(box->tags, str8_lit("hover")); + // rjf: brighten { + Vec4F32 color = hover_color; + color.w *= t*0.05f; R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); - Vec4F32 color = box->palette->hover; - color.w *= t*0.1f; inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; MemoryCopyArray(inst->corner_radii, box->corner_radii); @@ -8704,33 +8816,18 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: soft circle around mouse if(box->hot_t > 0.01f) DR_ClipScope(box->rect) { + Vec4F32 color = hover_color; + color.w *= 0.015f*t; Vec2F32 center = ui_mouse(); F32 radius = box->font_size*12.f; - Vec4F32 color = box->palette->hover; - color.w *= 0.05f*t; dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } - - // rjf: slight emboss fadeoff - if(0) - { - Rng2F32 rect = r2f32p(box->rect.x0, - box->rect.y0, - box->rect.x1, - box->rect.y1); - R_Rect2DInst *inst = dr_rect(rect, v4f32(0, 0, 0, 0), 0, 0, 1.f); - inst->colors[Corner_00] = v4f32(0.f, 0.f, 0.f, 0.0f*t); - inst->colors[Corner_01] = v4f32(0.f, 0.f, 0.f, 0.3f*t); - inst->colors[Corner_10] = v4f32(0.f, 0.f, 0.f, 0.0f*t); - inst->colors[Corner_11] = v4f32(0.f, 0.f, 0.f, 0.3f*t); - MemoryCopyArray(inst->corner_radii, box->corner_radii); - } } // rjf: active effect extension if(box->flags & UI_BoxFlag_DrawActiveEffects) { - Vec4F32 shadow_color = rd_rgba_from_theme_color(RD_ThemeColor_DropShadow); + Vec4F32 shadow_color = drop_shadow_color; shadow_color.w *= 0.5f*box->active_t; Vec2F32 shadow_size = { @@ -8901,14 +8998,15 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { + Vec4F32 border_color = rd_color_from_tags(box->tags, str8_lit("border")); Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); - R_Rect2DInst *inst = dr_rect(b_border_rect, b->palette->colors[UI_ColorCode_Border], 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 color = box->palette->hover; + Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("hover")); color.w *= b->hot_t; R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; @@ -8950,7 +9048,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = box->palette->focus; + Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("focus")); color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -8965,7 +9063,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } - Vec4F32 color = box->palette->focus; + Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("focus")); color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -8974,7 +9072,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: disabled overlay if(b->disabled_t >= 0.005f) { - Vec4F32 disabled_overlay_color = v4f32(0, 0, 0, b->disabled_t*0.5f); + Vec4F32 disabled_overlay_color = v4f32(base_background_color.x, base_background_color.y, base_background_color.z, b->disabled_t*0.3f); R_Rect2DInst *inst = dr_rect(b->rect, disabled_overlay_color, 0, 0, 1); MemoryCopyArray(inst->corner_radii, b->corner_radii); } @@ -9020,7 +9118,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: draw border/overlay color to signify error if(ws->error_t > 0.01f) { - Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundBad); + String8 tags[] = {str8_lit("bad")}; + String8Array tags_array = {tags, ArrayCount(tags)}; + Vec4F32 color = rd_color_from_tags(tags_array, str8_lit("text")); color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); @@ -10492,7 +10592,7 @@ rd_push_search_string(Arena *arena) //- rjf: colors internal Vec4F32 -rd_color_from_tags(String8Array tags) +rd_color_from_tags(String8Array tags, String8 name) { Vec4F32 result = {0}; { @@ -10505,23 +10605,26 @@ rd_color_from_tags(String8Array tags) { RD_ThemePattern *p = &theme->patterns[idx]; U64 match_count = 0; - for EachIndex(key_tags_idx, tags.count) + B32 name_matches = 0; + for EachIndex(key_tags_idx, tags.count+1) { + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; for EachIndex(p_tags_idx, p->tags.count) { - if(str8_match(p->tags.v[p_tags_idx], tags.v[key_tags_idx], 0)) + if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) { + name_matches = (key_tags_idx == tags.count); match_count += 1; break; } } } - if(match_count > best_match_count) + if(name_matches && match_count > best_match_count) { pattern = p; best_match_count = match_count; } - if(match_count == tags.count) + if(match_count == tags.count+1) { break; } @@ -11947,125 +12050,6 @@ rd_frame(void) } } - ////////////////////////////// - //- rjf: compute all window themes - // - ProfScope("compute window themes") - { - Temp scratch = scratch_begin(0, 0); - for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) - { - //- rjf: for each window, scan upwards, and then try the project, then the user, until we - // find explicit preset / colors trees in the config. we will prefer the tightest ones, so - // that windows can have their own colors, and have those override higher-up settings. - RD_Cfg *preset_cfg = &rd_nil_cfg; - RD_CfgList colors_cfgs = {0}; - RD_Cfg *window_cfg = rd_cfg_from_id(ws->cfg_id); - RD_Cfg *scan_parents[] = {window_cfg, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; - for EachElement(idx, scan_parents) - { - for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) - { - if(preset_cfg == &rd_nil_cfg) - { - preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); - } - RD_Cfg *colors_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("colors")); - if(colors_cfg != &rd_nil_cfg) - { - rd_cfg_list_push_front(scratch.arena, &colors_cfgs, colors_cfg); - } - if(preset_cfg != &rd_nil_cfg && colors_cfg != &rd_nil_cfg) - { - break; - } - } - } - - //- rjf: map the preset config to the associated preset tree - MD_Node *preset_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; - if(preset_cfg != &rd_nil_cfg) - { - String8 preset_name = preset_cfg->first->string; - for EachEnumVal(RD_ThemePreset, p) - { - if(str8_match(preset_name, rd_theme_preset_code_string_table[p], 0)) - { - preset_tree = rd_state->theme_preset_trees[p]; - break; - } - } - } - - //- rjf: build tasks for color applications - each task comprises of a metadesk - // tree, describing the color patterns - typedef struct ThemeTask ThemeTask; - struct ThemeTask - { - ThemeTask *next; - MD_Node *tree; - }; - ThemeTask start_task = {0, preset_tree}; - ThemeTask *first_task = &start_task; - ThemeTask *last_task = first_task; - { - for(RD_CfgNode *n = colors_cfgs.first; n != 0; n = n->next) - { - ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); - SLLQueuePush(first_task, last_task, t); - t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); - } - } - - //- rjf: apply theme tasks, build each color pattern for this window's - // structured theme - typedef struct ThemePatternNode ThemePatternNode; - struct ThemePatternNode - { - ThemePatternNode *next; - RD_ThemePattern pattern; - }; - ThemePatternNode *first_pattern = 0; - ThemePatternNode *last_pattern = 0; - U64 pattern_count = 0; - for(ThemeTask *t = first_task; t != 0; t = t->next) - { - MD_Node *tree_root = t->tree; - for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) - { - if(n->flags & MD_NodeFlag_Numeric && md_node_is_nil(n)) - { - Vec4F32 color_srgba = rgba_from_hex_string_4f32(n->string); - Vec4F32 color_linear = linear_from_srgba(color_srgba); - String8List tags = {0}; - for(MD_Node *parent = n->parent; parent != tree_root && !md_node_is_nil(parent); parent = parent->parent) - { - str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), parent->string)); - } - ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); - node->pattern.tags = str8_array_from_list(ui_build_arena(), &tags); - node->pattern.linear = color_linear; - SLLQueuePush(first_pattern, last_pattern, node); - pattern_count += 1; - } - } - } - - //- rjf: convert to final pattern array - ws->theme = push_array(ui_build_arena(), RD_Theme, 1); - ws->theme->patterns_count = pattern_count; - ws->theme->patterns = push_array(ui_build_arena(), RD_ThemePattern, ws->theme->patterns_count); - { - U64 idx = 0; - for(ThemePatternNode *n = first_pattern; n != 0; n = n->next, idx += 1) - { - ws->theme->patterns[idx] = n->pattern; - } - } - } - scratch_end(scratch); - } - ////////////////////////////// //- rjf: build theme from config // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index bb09bd6f..4cf31c1f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -999,7 +999,7 @@ internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, S internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding); internal Vec4F32 rd_hsva_from_cfg(RD_Cfg *cfg); -internal Vec4F32 rd_rgba_from_cfg(RD_Cfg *cfg); +internal Vec4F32 rd_color_from_cfg(RD_Cfg *cfg); internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); @@ -1026,7 +1026,7 @@ internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); //////////////////////////////// //~ rjf: Control Entity Info Extraction -internal Vec4F32 rd_rgba_from_ctrl_entity(CTRL_Entity *entity); +internal Vec4F32 rd_color_from_ctrl_entity(CTRL_Entity *entity); internal String8 rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras); @@ -1164,7 +1164,7 @@ internal String8 rd_push_search_string(Arena *arena); //~ rjf: Colors, Fonts, Config //- rjf: colors -internal Vec4F32 rd_color_from_tags(String8Array tags); +internal Vec4F32 rd_color_from_tags(String8Array tags, String8 name); internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5f372f75..97cfdeca 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2750,11 +2750,13 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(row_is_fresh) { - row_flags |= UI_BoxFlag_DrawPop; + ui_set_next_tag(str8_lit("pop")); + row_flags |= UI_BoxFlag_DrawBackground; } - if(global_row_idx & 1) + else if(global_row_idx & 1) { - row_flags |= UI_BoxFlag_DrawAlt; + ui_set_next_tag(str8_lit("alt")); + row_flags |= UI_BoxFlag_DrawBackground; } if(!row_matches_last_row_topology) { @@ -2852,7 +2854,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rd_state->hover_regs_slot == RD_RegSlot_Cfg) { RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = linear_from_srgba(rd_rgba_from_cfg(cfg)); + Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); if(rgba.w == 0) { rgba = ui_top_palette()->background_pop; @@ -2866,7 +2868,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) { CTRL_Entity *entity = cell_info.entity; - Vec4F32 rgba = linear_from_srgba(rd_rgba_from_ctrl_entity(entity)); + Vec4F32 rgba = rd_color_from_ctrl_entity(entity); if(rgba.w == 0) { rgba = ui_top_palette()->background_pop;; @@ -2894,7 +2896,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(RD_FontSlot_Code) - UI_FlagsAdd(row_depth > 0 ? UI_BoxFlag_DrawTextWeak : 0) { // rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) @@ -2960,7 +2961,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { RD_Font(RD_FontSlot_Icons) UI_Flags(UI_BoxFlag_DisableTextTrunc) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_rgba_from_ctrl_entity(row_info->callstack_thread))) + UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_color_from_ctrl_entity(row_info->callstack_thread))) ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); } } @@ -3181,16 +3182,16 @@ RD_VIEW_UI_FUNCTION_DEF(watch) E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:"); + ui_labelf("Text:"); ui_label(string); ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:"); + ui_labelf("Tokens:"); for(U64 idx = 0; idx < tokens.count; idx += 1) { ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); } ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:"); + ui_labelf("Expression:"); { typedef struct Task Task; struct Task @@ -3243,7 +3244,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:"); + ui_labelf("IR Tree:"); { typedef struct Task Task; struct Task @@ -3280,7 +3281,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:"); + ui_labelf("Op List:"); { for(E_Op *op = oplist.first; op != 0; op = op->next) { @@ -3307,7 +3308,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) } } ui_spacer(ui_em(2.f, 1.f)); - UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:"); + ui_labelf("Bytecode:"); { for(U64 idx = 0; idx < bytecode.size; idx += 1) { @@ -3526,7 +3527,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { if(file_is_out_of_date) { @@ -3773,7 +3774,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") RD_Font(RD_FontSlot_Code) { U64 cursor_vaddr = (1 <= rd_regs()->cursor.line && rd_regs()->cursor.line <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[rd_regs()->cursor.line-1].code_off) : 0; @@ -4141,7 +4142,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = thread->string.size ? thread->string : push_str8f(scratch.arena, "TID: %I64u", thread->id); annotation->kind_string = str8_lit("Stack"); - annotation->color = rd_rgba_from_ctrl_entity(thread); + annotation->color = rd_color_from_ctrl_entity(thread); annotation->vaddr_range = stack_vaddr_range; for(U64 vaddr = stack_vaddr_range_in_viz.min; vaddr < stack_vaddr_range_in_viz.max; vaddr += 1) { @@ -4220,7 +4221,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) UI_Parent(header_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { UI_PrefWidth(ui_px(big_glyph_advance*20.f, 1.f)) ui_labelf("Address"); UI_PrefWidth(ui_px(cell_width_px, 1.f)) @@ -4229,10 +4230,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Rng1U64 col_selection_rng = r1u64(cursor%num_columns, mark%num_columns); for(U64 row_off = 0; row_off < num_columns*bytes_per_cell; row_off += bytes_per_cell) { - if(!(col_selection_rng.min <= row_off && row_off <= col_selection_rng.max)) - { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); - } ui_labelf("%I64X", row_off); } } @@ -4401,7 +4398,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { if(!(selection.max >= row_range_bytes.min && selection.min < row_range_bytes.max)) { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); + ui_set_next_tag(str8_lit("weak")); } ui_labelf("0x%016I64X", row_range_bytes.min); } @@ -4573,7 +4570,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) footer_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, "footer"); UI_Parent(footer_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) { - UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_TagF("weak") UI_PrefHeight(ui_px(row_height_px, 0.f)) { ui_labelf("Address:"); @@ -5049,7 +5046,8 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) { UI_Signal h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); } - UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) + UI_TagF("weak") { ui_labelf("Hex"); ui_labelf("R"); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ad48dec5..24e33ef8 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -292,7 +292,7 @@ rd_cmd_spec_button(String8 name) RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_em(2.f, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") { ui_label(rd_icon_kind_text_table[canonical_icon]); } @@ -308,7 +308,7 @@ rd_cmd_spec_button(String8 name) UI_PrefWidth(ui_children_sum(1)) UI_FontSize(ui_top_font_size()*0.95f) UI_HeightFill UI_NamedRow(str8_lit("###bindings")) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_FastpathCodepoint(0) { rd_cmd_binding_buttons(name); @@ -365,7 +365,8 @@ rd_icon_button(RD_IconKind kind, FuzzyMatchRangeList *matches, String8 string) RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_em(2.f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) - UI_FlagsAdd(UI_BoxFlag_DisableTextTrunc|UI_BoxFlag_DrawTextWeak) + UI_FlagsAdd(UI_BoxFlag_DisableTextTrunc) + UI_TagF("weak") ui_label(rd_icon_kind_text_table[kind]); if(display_string.size != 0) { @@ -481,12 +482,14 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) if(u->is_frozen) { F32 lock_icon_off = ui_top_font_size()*0.2f; - Vec4F32 lock_icon_color = ui_top_palette()->background_bad; + String8 tags[] = {str8_lit("bad")}; + String8Array tags_array = {tags, ArrayCount(tags)}; + Vec4F32 color = rd_color_from_tags(tags_array, str8_lit("text")); dr_text(rd_font_from_slot(RD_FontSlot_Icons), box->font_size, 0, 0, FNT_RasterFlag_Smooth, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, box->rect.y0 + lock_icon_off/2), - lock_icon_color, + color, rd_icon_kind_text_table[RD_IconKind_Locked]); } } @@ -590,10 +593,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 ctrlified = (os_get_modifiers() & OS_Modifier_Ctrl); Vec4F32 code_line_bgs[] = { - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground0), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground1), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground2), - rd_rgba_from_theme_color(RD_ThemeColor_LineInfoBackground3), + rd_color_from_tags(str8_array_zero(), str8_lit("line_info_0")), + rd_color_from_tags(str8_array_zero(), str8_lit("line_info_1")), + rd_color_from_tags(str8_array_zero(), str8_lit("line_info_2")), + rd_color_from_tags(str8_array_zero(), str8_lit("line_info_3")), }; F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); @@ -671,7 +674,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { CTRL_EntityList line_ips = params->line_ips[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); + UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) { //- rjf: build margin thread ip ui @@ -691,7 +694,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); + Vec4F32 color = rd_color_from_ctrl_entity(thread); { if(color.w == 0) { @@ -801,6 +804,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // UI_Box *catchall_margin_container_box = &ui_nil_box; if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins") + UI_TagF("implicit") { if(params->margin_float_off_px != 0) { @@ -844,7 +848,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); // rjf: thread info => color - Vec4F32 color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); + Vec4F32 color = rd_color_from_ctrl_entity(thread); { if(color.w == 0) { @@ -952,7 +956,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe for(RD_CfgNode *n = line_bps.first; n != 0; n = n->next) { RD_Cfg *bp = n->v; - Vec4F32 bp_rgba = rd_rgba_from_cfg(bp); + Vec4F32 bp_rgba = rd_color_from_cfg(bp); if(bp_rgba.w == 0) { bp_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); @@ -1045,7 +1049,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe for(RD_CfgNode *n = line_pins.first; n != 0; n = n->next) { RD_Cfg *pin = n->v; - Vec4F32 color = rd_rgba_from_cfg(pin); + Vec4F32 color = rd_color_from_cfg(pin); if(color.w == 0) { color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); @@ -1115,6 +1119,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build line numbers // if(params->flags & RD_CodeSliceFlag_LineNums) UI_Parent(top_container_box) ProfScope("build line numbers") UI_Focus(UI_FocusKind_Off) + UI_TagF("implicit") { TxtRng select_rng = txt_rng(*cursor, *mark); Vec4F32 active_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeLineNumbersSelected); @@ -1173,7 +1178,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build background for line numbers & margins // { - UI_Parent(top_container_box) + UI_Parent(top_container_box) UI_TagF("floating") { ui_set_next_pref_width(ui_px(params->priority_margin_width_px + params->catchall_margin_width_px + params->line_num_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); @@ -1293,7 +1298,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_BoxFlag_DrawBorder, pin_box_key); UI_Parent(pin_box) UI_PrefWidth(ui_text_dim(10, 1)) { - Vec4F32 pin_color = rd_rgba_from_cfg(pin); + Vec4F32 pin_color = rd_color_from_cfg(pin); if(pin_color.w == 0) { pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); @@ -1485,7 +1490,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { line_drag_drop = 1; line_drag_cfg = cfg; - line_drag_drop_color = linear_from_srgba(rd_rgba_from_cfg(cfg)); + line_drag_drop_color = linear_from_srgba(rd_color_from_cfg(cfg)); if(line_drag_drop_color.w == 0) { line_drag_drop_color = ui_top_palette()->background_pop; @@ -1495,7 +1500,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { line_drag_drop = 1; line_drag_ctrl_entity = thread; - line_drag_drop_color = linear_from_srgba(rd_rgba_from_ctrl_entity(thread)); + line_drag_drop_color = rd_color_from_ctrl_entity(thread); if(line_drag_drop_color.w == 0) { line_drag_drop_color = ui_top_palette()->background_pop; @@ -2215,8 +2220,7 @@ rd_error_label(String8 string) ui_set_next_font(rd_font_from_slot(RD_FontSlot_Icons)); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_text_alignment(UI_TextAlign_Center); - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); - UI_PrefWidth(ui_em(2.25f, 1.f)) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); + UI_TagF("weak") UI_PrefWidth(ui_em(2.25f, 1.f)) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); UI_PrefWidth(ui_text_dim(10, 0)) rd_label(string); } return sig; @@ -2500,7 +2504,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) //- rjf: build expander placeholder else if(params->flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) + UI_TagF("weak") UI_Flags(UI_BoxFlag_DrawSideLeft) RD_Font(RD_FontSlot_Icons) UI_TextAlignment(UI_TextAlign_Center) @@ -2696,9 +2700,8 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else + else UI_TagF("weak") { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); UI_Box *box = ui_label(display_string).box; if(params->fuzzy_matches != 0) { @@ -2715,7 +2718,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } else { - ui_set_next_flags(UI_BoxFlag_DrawTextWeak); + ui_set_next_tag(str8_lit("weak")); } UI_Box *box = ui_label(display_string).box; if(params->fuzzy_matches != 0) diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index 3b0a771b..89017afd 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -14,6 +14,7 @@ #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) +#define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) #define UI_FocusHot(v) DeferLoop(ui_push_focus_hot(v), ui_pop_focus_hot()) #define UI_FocusActive(v) DeferLoop(ui_push_focus_active(v), ui_pop_focus_active()) #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) @@ -45,13 +46,13 @@ internal UI_Size ui_top_pref_width(void) { UI_StackTopImpl(ui_state, PrefWidth, internal UI_Size ui_top_pref_height(void) { UI_StackTopImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_top_permission_flags(void) { UI_StackTopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_top_flags(void) { UI_StackTopImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_top_omit_flags(void) { UI_StackTopImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_top_focus_hot(void) { UI_StackTopImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_top_focus_active(void) { UI_StackTopImpl(ui_state, FocusActive, focus_active) } internal U32 ui_top_fastpath_codepoint(void) { UI_StackTopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_top_group_key(void) { UI_StackTopImpl(ui_state, GroupKey, group_key) } internal F32 ui_top_transparency(void) { UI_StackTopImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_top_palette(void) { UI_StackTopImpl(ui_state, Palette, palette) } -internal String8 ui_top_tag(void) { UI_StackTopImpl(ui_state, Tag, tag) } internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } @@ -75,13 +76,13 @@ internal UI_Size ui_bottom_pref_width(void) { UI_StackBottomImpl(ui_state, PrefW internal UI_Size ui_bottom_pref_height(void) { UI_StackBottomImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_bottom_permission_flags(void) { UI_StackBottomImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_bottom_flags(void) { UI_StackBottomImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_bottom_omit_flags(void) { UI_StackBottomImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_bottom_focus_hot(void) { UI_StackBottomImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_bottom_focus_active(void) { UI_StackBottomImpl(ui_state, FocusActive, focus_active) } internal U32 ui_bottom_fastpath_codepoint(void) { UI_StackBottomImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_bottom_group_key(void) { UI_StackBottomImpl(ui_state, GroupKey, group_key) } internal F32 ui_bottom_transparency(void) { UI_StackBottomImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_bottom_palette(void) { UI_StackBottomImpl(ui_state, Palette, palette) } -internal String8 ui_bottom_tag(void) { UI_StackBottomImpl(ui_state, Tag, tag) } internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squish) } internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } @@ -105,13 +106,13 @@ internal UI_Size ui_push_pref_width(UI_Size v) { UI_StackPushImpl(ui_state, Pref internal UI_Size ui_push_pref_height(UI_Size v) { UI_StackPushImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v) { UI_StackPushImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_push_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, Flags, flags, UI_BoxFlags, v) } +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v) { UI_StackPushImpl(ui_state, FocusHot, focus_hot, UI_FocusKind, v) } internal UI_FocusKind ui_push_focus_active(UI_FocusKind v) { UI_StackPushImpl(ui_state, FocusActive, focus_active, UI_FocusKind, v) } internal U32 ui_push_fastpath_codepoint(U32 v) { UI_StackPushImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_push_group_key(UI_Key v) { UI_StackPushImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_push_transparency(F32 v) { UI_StackPushImpl(ui_state, Transparency, transparency, F32, v) } internal UI_Palette* ui_push_palette(UI_Palette* v) { UI_StackPushImpl(ui_state, Palette, palette, UI_Palette* , v) } -internal String8 ui_push_tag(String8 v) { UI_StackPushImpl(ui_state, Tag, tag, String8, v) } internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_push_font(FNT_Tag v) { UI_StackPushImpl(ui_state, Font, font, FNT_Tag, v) } @@ -135,13 +136,13 @@ internal UI_Size ui_pop_pref_width(void) { UI_StackPopImpl(ui_state, PrefWidth, internal UI_Size ui_pop_pref_height(void) { UI_StackPopImpl(ui_state, PrefHeight, pref_height) } internal UI_PermissionFlags ui_pop_permission_flags(void) { UI_StackPopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_pop_flags(void) { UI_StackPopImpl(ui_state, Flags, flags) } +internal UI_BoxFlags ui_pop_omit_flags(void) { UI_StackPopImpl(ui_state, OmitFlags, omit_flags) } internal UI_FocusKind ui_pop_focus_hot(void) { UI_StackPopImpl(ui_state, FocusHot, focus_hot) } internal UI_FocusKind ui_pop_focus_active(void) { UI_StackPopImpl(ui_state, FocusActive, focus_active) } internal U32 ui_pop_fastpath_codepoint(void) { UI_StackPopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_pop_group_key(void) { UI_StackPopImpl(ui_state, GroupKey, group_key) } internal F32 ui_pop_transparency(void) { UI_StackPopImpl(ui_state, Transparency, transparency) } internal UI_Palette* ui_pop_palette(void) { UI_StackPopImpl(ui_state, Palette, palette) } -internal String8 ui_pop_tag(void) { UI_StackPopImpl(ui_state, Tag, tag) } internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } @@ -165,13 +166,13 @@ internal UI_Size ui_set_next_pref_width(UI_Size v) { UI_StackSetNextImpl(ui_stat internal UI_Size ui_set_next_pref_height(UI_Size v) { UI_StackSetNextImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v) { UI_StackSetNextImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, Flags, flags, UI_BoxFlags, v) } +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v) { UI_StackSetNextImpl(ui_state, FocusHot, focus_hot, UI_FocusKind, v) } internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v) { UI_StackSetNextImpl(ui_state, FocusActive, focus_active, UI_FocusKind, v) } internal U32 ui_set_next_fastpath_codepoint(U32 v) { UI_StackSetNextImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_set_next_group_key(UI_Key v) { UI_StackSetNextImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_set_next_transparency(F32 v) { UI_StackSetNextImpl(ui_state, Transparency, transparency, F32, v) } internal UI_Palette* ui_set_next_palette(UI_Palette* v) { UI_StackSetNextImpl(ui_state, Palette, palette, UI_Palette* , v) } -internal String8 ui_set_next_tag(String8 v) { UI_StackSetNextImpl(ui_state, Tag, tag, String8, v) } internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_set_next_font(FNT_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, FNT_Tag, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index 0adc1ad9..ccd7dc65 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -16,6 +16,7 @@ typedef struct UI_PrefWidthNode UI_PrefWidthNode; struct UI_PrefWidthNode{UI_Pre typedef struct UI_PrefHeightNode UI_PrefHeightNode; struct UI_PrefHeightNode{UI_PrefHeightNode *next; UI_Size v;}; typedef struct UI_PermissionFlagsNode UI_PermissionFlagsNode; struct UI_PermissionFlagsNode{UI_PermissionFlagsNode *next; UI_PermissionFlags v;}; typedef struct UI_FlagsNode UI_FlagsNode; struct UI_FlagsNode{UI_FlagsNode *next; UI_BoxFlags v;}; +typedef struct UI_OmitFlagsNode UI_OmitFlagsNode; struct UI_OmitFlagsNode{UI_OmitFlagsNode *next; UI_BoxFlags v;}; typedef struct UI_FocusHotNode UI_FocusHotNode; struct UI_FocusHotNode{UI_FocusHotNode *next; UI_FocusKind v;}; typedef struct UI_FocusActiveNode UI_FocusActiveNode; struct UI_FocusActiveNode{UI_FocusActiveNode *next; UI_FocusKind v;}; typedef struct UI_FastpathCodepointNode UI_FastpathCodepointNode; struct UI_FastpathCodepointNode{UI_FastpathCodepointNode *next; U32 v;}; @@ -49,6 +50,7 @@ UI_PrefWidthNode pref_width_nil_stack_top;\ UI_PrefHeightNode pref_height_nil_stack_top;\ UI_PermissionFlagsNode permission_flags_nil_stack_top;\ UI_FlagsNode flags_nil_stack_top;\ +UI_OmitFlagsNode omit_flags_nil_stack_top;\ UI_FocusHotNode focus_hot_nil_stack_top;\ UI_FocusActiveNode focus_active_nil_stack_top;\ UI_FastpathCodepointNode fastpath_codepoint_nil_stack_top;\ @@ -81,6 +83,7 @@ state->pref_width_nil_stack_top.v = ui_px(250.f, 1.f);\ state->pref_height_nil_stack_top.v = ui_px(30.f, 1.f);\ state->permission_flags_nil_stack_top.v = UI_PermissionFlag_All;\ state->flags_nil_stack_top.v = 0;\ +state->omit_flags_nil_stack_top.v = 0;\ state->focus_hot_nil_stack_top.v = UI_FocusKind_Null;\ state->focus_active_nil_stack_top.v = UI_FocusKind_Null;\ state->fastpath_codepoint_nil_stack_top.v = 0;\ @@ -115,6 +118,7 @@ struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; U64 struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; U64 gen; B32 auto_pop; } pref_height_stack;\ struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; U64 gen; B32 auto_pop; } permission_flags_stack;\ struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; U64 gen; B32 auto_pop; } flags_stack;\ +struct { UI_OmitFlagsNode *top; UI_BoxFlags bottom_val; UI_OmitFlagsNode *free; U64 gen; B32 auto_pop; } omit_flags_stack;\ struct { UI_FocusHotNode *top; UI_FocusKind bottom_val; UI_FocusHotNode *free; U64 gen; B32 auto_pop; } focus_hot_stack;\ struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *free; U64 gen; B32 auto_pop; } focus_active_stack;\ struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; U64 gen; B32 auto_pop; } fastpath_codepoint_stack;\ @@ -147,6 +151,7 @@ state->pref_width_stack.top = &state->pref_width_nil_stack_top; state->pref_widt state->pref_height_stack.top = &state->pref_height_nil_stack_top; state->pref_height_stack.bottom_val = ui_px(30.f, 1.f); state->pref_height_stack.free = 0; state->pref_height_stack.auto_pop = 0;\ state->permission_flags_stack.top = &state->permission_flags_nil_stack_top; state->permission_flags_stack.bottom_val = UI_PermissionFlag_All; state->permission_flags_stack.free = 0; state->permission_flags_stack.auto_pop = 0;\ state->flags_stack.top = &state->flags_nil_stack_top; state->flags_stack.bottom_val = 0; state->flags_stack.free = 0; state->flags_stack.auto_pop = 0;\ +state->omit_flags_stack.top = &state->omit_flags_nil_stack_top; state->omit_flags_stack.bottom_val = 0; state->omit_flags_stack.free = 0; state->omit_flags_stack.auto_pop = 0;\ state->focus_hot_stack.top = &state->focus_hot_nil_stack_top; state->focus_hot_stack.bottom_val = UI_FocusKind_Null; state->focus_hot_stack.free = 0; state->focus_hot_stack.auto_pop = 0;\ state->focus_active_stack.top = &state->focus_active_nil_stack_top; state->focus_active_stack.bottom_val = UI_FocusKind_Null; state->focus_active_stack.free = 0; state->focus_active_stack.auto_pop = 0;\ state->fastpath_codepoint_stack.top = &state->fastpath_codepoint_nil_stack_top; state->fastpath_codepoint_stack.bottom_val = 0; state->fastpath_codepoint_stack.free = 0; state->fastpath_codepoint_stack.auto_pop = 0;\ @@ -179,6 +184,7 @@ if(state->pref_width_stack.auto_pop) { ui_pop_pref_width(); state->pref_width_st if(state->pref_height_stack.auto_pop) { ui_pop_pref_height(); state->pref_height_stack.auto_pop = 0; }\ if(state->permission_flags_stack.auto_pop) { ui_pop_permission_flags(); state->permission_flags_stack.auto_pop = 0; }\ if(state->flags_stack.auto_pop) { ui_pop_flags(); state->flags_stack.auto_pop = 0; }\ +if(state->omit_flags_stack.auto_pop) { ui_pop_omit_flags(); state->omit_flags_stack.auto_pop = 0; }\ if(state->focus_hot_stack.auto_pop) { ui_pop_focus_hot(); state->focus_hot_stack.auto_pop = 0; }\ if(state->focus_active_stack.auto_pop) { ui_pop_focus_active(); state->focus_active_stack.auto_pop = 0; }\ if(state->fastpath_codepoint_stack.auto_pop) { ui_pop_fastpath_codepoint(); state->fastpath_codepoint_stack.auto_pop = 0; }\ @@ -210,6 +216,7 @@ internal UI_Size ui_top_pref_width(void); internal UI_Size ui_top_pref_height(void); internal UI_PermissionFlags ui_top_permission_flags(void); internal UI_BoxFlags ui_top_flags(void); +internal UI_BoxFlags ui_top_omit_flags(void); internal UI_FocusKind ui_top_focus_hot(void); internal UI_FocusKind ui_top_focus_active(void); internal U32 ui_top_fastpath_codepoint(void); @@ -240,6 +247,7 @@ internal UI_Size ui_bottom_pref_width(void); internal UI_Size ui_bottom_pref_height(void); internal UI_PermissionFlags ui_bottom_permission_flags(void); internal UI_BoxFlags ui_bottom_flags(void); +internal UI_BoxFlags ui_bottom_omit_flags(void); internal UI_FocusKind ui_bottom_focus_hot(void); internal UI_FocusKind ui_bottom_focus_active(void); internal U32 ui_bottom_fastpath_codepoint(void); @@ -270,6 +278,7 @@ internal UI_Size ui_push_pref_width(UI_Size v); internal UI_Size ui_push_pref_height(UI_Size v); internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_push_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_push_focus_active(UI_FocusKind v); internal U32 ui_push_fastpath_codepoint(U32 v); @@ -300,6 +309,7 @@ internal UI_Size ui_pop_pref_width(void); internal UI_Size ui_pop_pref_height(void); internal UI_PermissionFlags ui_pop_permission_flags(void); internal UI_BoxFlags ui_pop_flags(void); +internal UI_BoxFlags ui_pop_omit_flags(void); internal UI_FocusKind ui_pop_focus_hot(void); internal UI_FocusKind ui_pop_focus_active(void); internal U32 ui_pop_fastpath_codepoint(void); @@ -330,6 +340,7 @@ internal UI_Size ui_set_next_pref_width(UI_Size v); internal UI_Size ui_set_next_pref_height(UI_Size v); internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v); internal U32 ui_set_next_fastpath_codepoint(U32 v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index 36c794ff..b934c760 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -3,11 +3,11 @@ //- rjf: stack table -@table(name, name_lower, type, default) +@table(name, name_lower, type, default, manual_impl) UI_StackTable: { //- rjf: parents - { Parent parent `UI_Box *` `&ui_nil_box` } + { Parent parent `UI_Box *` `&ui_nil_box` } //- rjf: layout params { ChildLayoutAxis child_layout_axis Axis2 `Axis2_X` } @@ -23,6 +23,7 @@ UI_StackTable: //- rjf: flags { PermissionFlags permission_flags UI_PermissionFlags UI_PermissionFlag_All } { Flags flags UI_BoxFlags 0 } + { OmitFlags omit_flags UI_BoxFlags 0 } //- rjf: interaction { FocusHot focus_hot UI_FocusKind UI_FocusKind_Null } @@ -33,7 +34,7 @@ UI_StackTable: //- rjf: colors { Transparency transparency F32 0 } { Palette palette `UI_Palette* ` `&ui_g_nil_palette` } - { Tag tag String8 `str8_lit("")` } + { Tag tag String8 `str8_lit("")` 1 } //- rjf: squish { Squish squish F32 0 } @@ -149,13 +150,13 @@ UI_StackTable: @gen @c_file { @expand(UI_StackTable a) - `internal $(a.type) ui_top_$(a.name_lower)(void) { UI_StackTopImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_top_" .. a.name_lower .. "(void) { UI_StackTopImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_bottom_$(a.name_lower)(void) { UI_StackBottomImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_bottom_" .. a.name_lower .. "(void) { UI_StackBottomImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_push_$(a.name_lower)($(a.type) v) { UI_StackPushImpl(ui_state, $(a.name), $(a.name_lower), $(a.type), v) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_push_" .. a.name_lower .. "(" .. a.type .. " v) { UI_StackPushImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ", " .. a.type .. ", v) }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_pop_$(a.name_lower)(void) { UI_StackPopImpl(ui_state, $(a.name), $(a.name_lower)) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_pop_" .. a.name_lower .. "(void) { UI_StackPopImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ") }")`; @expand(UI_StackTable a) - `internal $(a.type) ui_set_next_$(a.name_lower)($(a.type) v) { UI_StackSetNextImpl(ui_state, $(a.name), $(a.name_lower), $(a.type), v) }`; + `$(a.manual_impl == "" -> "internal " .. a.type .. " ui_set_next_" .. a.name_lower .. "(" .. a.type .. " v) { UI_StackSetNextImpl(ui_state, " .. a.name .. ", " .. a.name_lower .. ", " .. a.type .. ", v) }")`; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 864302bc..8aba4805 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1918,11 +1918,13 @@ ui_tooltip_begin_base(void) ui_push_flags(0); ui_push_text_raster_flags(ui_bottom_text_raster_flags()); ui_push_palette(ui_bottom_palette()); + ui_push_tag(str8_lit(".")); } internal void ui_tooltip_end_base(void) { + ui_pop_tag(); ui_pop_palette(); ui_pop_text_raster_flags(); ui_pop_flags(); @@ -2005,6 +2007,7 @@ ui_begin_ctx_menu(UI_Key key) ui_push_focus_hot(UI_FocusKind_Root); ui_push_focus_active(UI_FocusKind_Root); ui_push_palette(ui_state->widget_palette_info.ctx_menu_palette); + ui_push_tag(str8_lit(".")); B32 is_open = ui_key_match(key, ui_state->ctx_menu_key) && ui_state->ctx_menu_open; if(is_open != 0) { @@ -2033,6 +2036,7 @@ ui_end_ctx_menu(void) ui_state->is_in_open_ctx_menu = 0; ui_spacer(ui_em(1.f, 1.f)); } + ui_pop_tag(); ui_pop_palette(); ui_pop_focus_active(); ui_pop_focus_hot(); @@ -2262,7 +2266,7 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) //- rjf: fill box { box->key = key; - box->flags = flags|ui_state->flags_stack.top->v; + box->flags = (flags | ui_state->flags_stack.top->v) & ~ui_state->omit_flags_stack.top->v; box->fastpath_codepoint = ui_state->fastpath_codepoint_stack.top->v; box->group_key = ui_state->group_key_stack.top->v; @@ -2357,7 +2361,14 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) String8List tags = {0}; for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) { - str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); + if(n->v.size == 1 && n->v.str[0] == '.') + { + break; + } + if(n->v.size != 0) + { + str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); + } } ui_state->current_gen_tags = str8_array_from_list(ui_build_arena(), &tags); scratch_end(scratch); @@ -3054,6 +3065,57 @@ ui_anim_(UI_Key key, UI_AnimParams *params) //////////////////////////////// //~ rjf: Stacks +#define UI_StackTopImpl(state, name_upper, name_lower) \ +return state->name_lower##_stack.top->v; + +#define UI_StackBottomImpl(state, name_upper, name_lower) \ +return state->name_lower##_stack.bottom_val; + +#define UI_StackPushImpl(state, name_upper, name_lower, type, new_value) \ +UI_##name_upper##Node *node = state->name_lower##_stack.free;\ +if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ +else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ +type old_value = state->name_lower##_stack.top->v;\ +node->v = new_value;\ +SLLStackPush(state->name_lower##_stack.top, node);\ +if(node->next == &state->name_lower##_nil_stack_top)\ +{\ +state->name_lower##_stack.bottom_val = (new_value);\ +}\ +state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ +return old_value; + +#define UI_StackPopImpl(state, name_upper, name_lower) \ +UI_##name_upper##Node *popped = state->name_lower##_stack.top;\ +if(popped != &state->name_lower##_nil_stack_top)\ +{\ +SLLStackPop(state->name_lower##_stack.top);\ +SLLStackPush(state->name_lower##_stack.free, popped);\ +state->name_lower##_stack.auto_pop = 0;\ +state->name_lower##_stack.gen += 1;\ +}\ +return popped->v;\ + +#define UI_StackSetNextImpl(state, name_upper, name_lower, type, new_value) \ +UI_##name_upper##Node *node = state->name_lower##_stack.free;\ +if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ +else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ +type old_value = state->name_lower##_stack.top->v;\ +node->v = new_value;\ +SLLStackPush(state->name_lower##_stack.top, node);\ +state->name_lower##_stack.auto_pop = 1;\ +state->name_lower##_stack.gen += 1;\ +return old_value; + +//- rjf: manual implementations + +internal String8 ui_top_tag(void) { UI_StackTopImpl(ui_state, Tag, tag) } +internal String8 ui_bottom_tag(void) { UI_StackBottomImpl(ui_state, Tag, tag) } +internal String8 ui_push_tag(String8 v) { UI_StackPushImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) } +internal String8 ui_pop_tag(void) { UI_StackPopImpl(ui_state, Tag, tag) } +internal String8 ui_set_next_tag(String8 v) { UI_StackSetNextImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) } + //- rjf: helpers internal Rng2F32 @@ -3139,50 +3201,19 @@ ui_pop_corner_radius(void) ui_pop_corner_radius_11(); } +internal void +ui_push_tagf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + ui_push_tag(string); + va_end(args); + scratch_end(scratch); +} + //////////////////////////////// //~ rjf: Generated Code -#define UI_StackTopImpl(state, name_upper, name_lower) \ -return state->name_lower##_stack.top->v; - -#define UI_StackBottomImpl(state, name_upper, name_lower) \ -return state->name_lower##_stack.bottom_val; - -#define UI_StackPushImpl(state, name_upper, name_lower, type, new_value) \ -UI_##name_upper##Node *node = state->name_lower##_stack.free;\ -if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ -else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ -type old_value = state->name_lower##_stack.top->v;\ -node->v = new_value;\ -SLLStackPush(state->name_lower##_stack.top, node);\ -if(node->next == &state->name_lower##_nil_stack_top)\ -{\ -state->name_lower##_stack.bottom_val = (new_value);\ -}\ -state->name_lower##_stack.auto_pop = 0;\ -state->name_lower##_stack.gen += 1;\ -return old_value; - -#define UI_StackPopImpl(state, name_upper, name_lower) \ -UI_##name_upper##Node *popped = state->name_lower##_stack.top;\ -if(popped != &state->name_lower##_nil_stack_top)\ -{\ -SLLStackPop(state->name_lower##_stack.top);\ -SLLStackPush(state->name_lower##_stack.free, popped);\ -state->name_lower##_stack.auto_pop = 0;\ -state->name_lower##_stack.gen += 1;\ -}\ -return popped->v;\ - -#define UI_StackSetNextImpl(state, name_upper, name_lower, type, new_value) \ -UI_##name_upper##Node *node = state->name_lower##_stack.free;\ -if(node != 0) {SLLStackPop(state->name_lower##_stack.free);}\ -else {node = push_array(ui_build_arena(), UI_##name_upper##Node, 1);}\ -type old_value = state->name_lower##_stack.top->v;\ -node->v = new_value;\ -SLLStackPush(state->name_lower##_stack.top, node);\ -state->name_lower##_stack.auto_pop = 1;\ -state->name_lower##_stack.gen += 1;\ -return old_value; - #include "generated/ui.meta.c" diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 0a23acb5..32bc53fd 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -948,6 +948,7 @@ internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); internal UI_Palette* ui_top_palette(void); +internal String8 ui_top_tag(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -977,6 +978,7 @@ internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); internal UI_Palette* ui_bottom_palette(void); +internal String8 ui_bottom_tag(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -1006,6 +1008,7 @@ internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); internal UI_Palette* ui_push_palette(UI_Palette* v); +internal String8 ui_push_tag(String8 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -1035,6 +1038,7 @@ internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); internal UI_Palette* ui_pop_palette(void); +internal String8 ui_pop_tag(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -1064,6 +1068,7 @@ internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); internal UI_Palette* ui_set_next_palette(UI_Palette* v); +internal String8 ui_set_next_tag(String8 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); @@ -1087,6 +1092,7 @@ internal UI_Size ui_pop_pref_size(Axis2 axis); internal UI_Size ui_set_next_pref_size(Axis2 axis, UI_Size v); internal void ui_push_corner_radius(F32 v); internal void ui_pop_corner_radius(void); +internal void ui_push_tagf(char *fmt, ...); //////////////////////////////// //~ rjf: Macro Loop Wrappers @@ -1102,12 +1108,14 @@ internal void ui_pop_corner_radius(void); #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) +#define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) #define UI_FocusHot(v) DeferLoop(ui_push_focus_hot(v), ui_pop_focus_hot()) #define UI_FocusActive(v) DeferLoop(ui_push_focus_active(v), ui_pop_focus_active()) #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) #define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) +#define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) @@ -1132,6 +1140,7 @@ internal void ui_pop_corner_radius(void); #define UI_CornerRadius(v) DeferLoop(ui_push_corner_radius(v), ui_pop_corner_radius()) #define UI_Focus(kind) DeferLoop((ui_push_focus_hot(kind), ui_push_focus_active(kind)), (ui_pop_focus_hot(), ui_pop_focus_active())) #define UI_FlagsAdd(v) DeferLoop(ui_push_flags(ui_top_flags()|(v)), ui_pop_flags()) +#define UI_TagF(...) DeferLoop(ui_push_tagf(__VA_ARGS__), ui_pop_tag()) //- rjf: tooltip #define UI_TooltipBase DeferLoop(ui_tooltip_begin_base(), ui_tooltip_end_base()) From 8706e7c56dca1168cd3e31085b4b582fbf80c07b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Feb 2025 19:27:27 -0800 Subject: [PATCH 141/755] dead code elimination, eliminating old theme usage --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 47 ++-- src/raddbg/raddbg_core.c | 398 ++++------------------------- src/raddbg/raddbg_core.h | 14 +- src/raddbg/raddbg_views.c | 39 ++- src/raddbg/raddbg_widgets.c | 39 +-- src/ui/ui_basic_widgets.c | 8 +- src/ui/ui_core.c | 116 +++++++-- src/ui/ui_core.h | 27 +- 9 files changed, 230 insertions(+), 460 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e427e354..d8bcb888 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -809,7 +809,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n good_pop: background: 0x2c5b36ff,\n bad_pop: background: 0x803425ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xe5e5e5ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x2222225f,\n background: alt: 0x2222225f,\n border: 0xbfbfbf1f,\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n good:\n {\n background: 0x2c5b36ff,\n border: 0x3f3f3fff,\n }\n\n bad:\n {\n background: 0x803425ff,\n border: 0xe88774ff,\n }\n\n pop:\n {\n background: 0x355b6eff,\n border: 0x355b6eff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x2222225f,\n background: alt: 0x0000005f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index bb2db7ca..b2dfeb79 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -989,14 +989,12 @@ RD_ThemePresetTable: { background: 0x1b1b1bff, alt: background: 0x222222ff, - good_pop: background: 0x2c5b36ff, - bad_pop: background: 0x803425ff, - good: text: 0x32a852ff, - bad: text: 0xcf5242ff, pop: background: 0x355b6eff, border: 0x404040ff, text: 0xe5e5e5ff, - weak: text: 0xe5e5e5ff, + weak: text: 0xa4a4a4ff, + good: text: 0x32a852ff, + bad: text: 0xcf5242ff, hover: 0xffffffff, focus: 0xfda200ff, cursor: 0x8aff00ff, @@ -1004,6 +1002,20 @@ RD_ThemePresetTable: inactive: background: 0x0000002f, drop_shadow: 0x0000007f, + good_pop: + { + background: 0x2c5b36ff, + border: 0x568761ff, + hover: 0xe3f5d3ff, + weak: text: 0xe3f5d3ff, + } + + bad_pop: + { + background: 0x803425ff, + hover: 0xff825cff, + } + code_default: 0xcbcbcbff, code_symbol: 0x42a2cfff, code_type: 0xfec746ff, @@ -1039,8 +1051,13 @@ RD_ThemePresetTable: floating: { background: 0x2222225f, - background: alt: 0x2222225f, + background: alt: 0x0000005f, border: 0xbfbfbf1f, + scroll_bar: + { + background: 0x3b3b3b5f, + border: 0x5f5f5f5f, + } } menu_bar: @@ -1049,24 +1066,6 @@ RD_ThemePresetTable: border: 0x3e4c57ff, } - good: - { - background: 0x2c5b36ff, - border: 0x3f3f3fff, - } - - bad: - { - background: 0x803425ff, - border: 0xe88774ff, - } - - pop: - { - background: 0x355b6eff, - border: 0x355b6eff, - } - scroll_bar: { background: 0x2b2b2bff, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 53816c65..1ebd1da5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2105,10 +2105,15 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) String8 expr_string = rd_expr_from_cfg(cfg); String8 collection_name = {0}; String8 file_path = {0}; - Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); + Vec4F32 rgba = rd_color_from_cfg(cfg); if(rgba.w == 0) { - rgba = ui_top_palette()->text; + rgba = ui_color_from_name(str8_lit("text")); + } + Vec4F32 rgba_secondary = rgba; + UI_TagF("weak") + { + rgba_secondary = ui_color_from_name(str8_lit("text")); } RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); B32 is_from_command_line = 0; @@ -2172,19 +2177,19 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) // DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, ui_top_font_size()}; B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = ui_top_palette()->text_weak; params.size = ui_top_font_size()*0.95f;} +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = rgba_secondary; params.size = ui_top_font_size()*0.95f;} //- rjf: push icon if(icon_kind != RD_IconKind_Null) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } //- rjf: push warning icon for command-line entities if(is_from_command_line) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -2702,11 +2707,11 @@ rd_color_from_ctrl_entity(CTRL_Entity *entity) CTRL_Entity *main_thread = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Thread); if(main_thread != entity) { - result = rd_color_from_tags(str8_array_zero(), str8_lit("thread_1")); + result = ui_color_from_name(str8_lit("thread_1")); } else { - result = rd_color_from_tags(str8_array_zero(), str8_lit("thread_0")); + result = ui_color_from_name(str8_lit("thread_0")); } }break; } @@ -2813,7 +2818,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e //- rjf: threads get callstack extras if(entity->kind == CTRL_EntityKind_Thread && include_extras) { - Vec4F32 symbol_color = rd_color_from_tags(str8_array_zero(), str8_lit("code_symbol")); + Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); @@ -4585,7 +4590,7 @@ rd_window_frame(void) struct ThemePatternNode { ThemePatternNode *next; - RD_ThemePattern pattern; + UI_ThemePattern pattern; }; ThemePatternNode *first_pattern = 0; ThemePatternNode *last_pattern = 0; @@ -4616,9 +4621,9 @@ rd_window_frame(void) } //- rjf: convert to final pattern array - ws->theme = push_array(rd_frame_arena(), RD_Theme, 1); + ws->theme = push_array(rd_frame_arena(), UI_Theme, 1); ws->theme->patterns_count = pattern_count; - ws->theme->patterns = push_array(rd_frame_arena(), RD_ThemePattern, ws->theme->patterns_count); + ws->theme->patterns = push_array(rd_frame_arena(), UI_ThemePattern, ws->theme->patterns_count); { U64 idx = 0; for(ThemePatternNode *n = first_pattern; n != 0; n = n->next, idx += 1) @@ -4797,7 +4802,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } // rjf: begin & push initial stack values - ui_begin_build(ws->os, &ws->ui_events, &icon_info, &widget_palette_info, &animation_info, rd_state->frame_dt, rd_state->frame_dt); + ui_begin_build(ws->os, &ws->ui_events, &icon_info, ws->theme, &widget_palette_info, &animation_info, rd_state->frame_dt, rd_state->frame_dt); ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_text_padding(main_font_size*0.3f); @@ -4940,7 +4945,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: unwind if(ctrl_entity->kind == CTRL_EntityKind_Thread) { - Vec4F32 symbol_color = rd_color_from_tags(str8_array_zero(), str8_lit("code_symbol")); + Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); @@ -5975,254 +5980,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } #endif } -#endif - }break; - - ////////////////////// - //- rjf: ctrl entities - // - case RD_RegSlot_Machine: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->machine); goto ctrl_entity_title; - case RD_RegSlot_Process: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->process); goto ctrl_entity_title; - case RD_RegSlot_Module: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->module); goto ctrl_entity_title; - case RD_RegSlot_Thread: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->thread); goto ctrl_entity_title; - case RD_RegSlot_CtrlEntity: ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->ctrl_entity); goto ctrl_entity_title; - ctrl_entity_title:; - { -#if 0 // TODO(rjf): @cfg - //- rjf: title - UI_Row - UI_PrefWidth(ui_text_dim(5, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_TextPadding(ui_top_font_size()*1.5f) - { - DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, 0); - UI_Box *title_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(title_box, &fstrs); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - ui_spacer(ui_em(0.5f, 1.f)); - UI_FontSize(ui_top_font_size() - 1.f) - UI_CornerRadius(ui_top_font_size()*0.5f) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_label(string_from_arch(ctrl_entity->arch)); - ui_spacer(ui_em(0.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak|UI_BoxFlag_DrawBorder) ui_labelf("TID: %i", (U32)ctrl_entity->id); - } - } - } - - ui_divider(ui_em(1.f, 1.f)); - - //- rjf: name editor - if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) UI_TextPadding(ui_top_font_size()*1.5f) - { -#if 0 // TODO(rjf): @cfg - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, ctrl_entity->string, "Name###ctrl_entity_string_edit_%p", ctrl_entity); - if(ui_committed(sig)) - { - rd_cmd(RD_CmdKind_SetEntityName, .ctrl_entity = ctrl_entity->handle, .string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size)); - } -#endif - } - - // rjf: copy full path - if(ctrl_entity->kind == CTRL_EntityKind_Module) if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"))) - { - os_set_clipboard_text(ctrl_entity->string); - ui_ctx_menu_close(); - } - - // rjf: copy ID - if((ctrl_entity->kind == CTRL_EntityKind_Thread || - ctrl_entity->kind == CTRL_EntityKind_Process) && - ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy ID"))) - { - String8 string = str8_from_u64(scratch.arena, ctrl_entity->id, 10, 0, 0); - os_set_clipboard_text(string); - ui_ctx_menu_close(); - } - - // rjf: find - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_FileOutline, 0, "Find"))) - { - rd_cmd(RD_CmdKind_FindThread, .thread = ctrl_entity->handle); - ui_ctx_menu_close(); - } - } - - // rjf: selection - if(ctrl_entity->kind == CTRL_EntityKind_Thread) - { - B32 is_selected = ctrl_handle_match(rd_base_regs()->thread, ctrl_entity->handle); - if(is_selected) - { - rd_icon_buttonf(RD_IconKind_Thread, 0, "[Selected]###select_entity"); - } - else if(ui_clicked(rd_icon_buttonf(RD_IconKind_Thread, 0, "Select###select_entity"))) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = ctrl_entity->handle); - ui_ctx_menu_close(); - } - } - - // rjf: freezing - if(ctrl_entity->kind == CTRL_EntityKind_Thread || - ctrl_entity->kind == CTRL_EntityKind_Process || - ctrl_entity->kind == CTRL_EntityKind_Machine) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(ctrl_entity); - ui_set_next_palette(rd_palette_from_code(is_frozen ? RD_PaletteCode_NegativePopButton : RD_PaletteCode_PositivePopButton)); - if(is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Locked, 0, "Thaw###freeze_thaw"))) - { - rd_cmd(RD_CmdKind_ThawThread, .ctrl_entity = ctrl_entity->handle); - } - if(!is_frozen && ui_clicked(rd_icon_buttonf(RD_IconKind_Unlocked, 0, "Freeze###freeze_thaw"))) - { - rd_cmd(RD_CmdKind_FreezeThread, .ctrl_entity = ctrl_entity->handle); - } - } - - // rjf: callstack -#if 0 - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - if(ctrl_entity->kind == CTRL_EntityKind_Thread) UI_TextPadding(ui_top_font_size()*1.5f) - { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *thread = ctrl_entity; - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); - for(U64 idx = 0; idx < rich_unwind.concrete_frame_count; idx += 1) - { - CTRL_CallStackFrame *f = &rich_unwind.frames[idx]; - RDI_Parsed *rdi = f->rdi; - RDI_Procedure *procedure = f->procedure; - U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string); - - // rjf: inline frames - for(CTRL_CallStackInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev) - { - UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_ClickToFocus, "###callstack_row_%I64x", idx); - UI_Signal sig = ui_signal_from_box(row); - ui_push_parent(row); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, fin->inline_site->name_string_idx, &name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(16.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - ui_pop_parent(); - } - - // rjf: concrete frame - { - UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_ClickToFocus, "###callstack_row_%I64x", idx); - UI_Signal sig = ui_signal_from_box(row); - ui_push_parent(row); - String8 name = {0}; - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(16.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } - ui_pop_parent(); - } - } - di_scope_close(di_scope); - } -#endif - - // rjf: color editor -#if 0 - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - { - UI_Padding(ui_em(1.5f, 1.f)) - { - ui_set_next_pref_height(ui_em(9.f, 1.f)); - UI_Row UI_Padding(ui_pct(1, 0)) - { - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) UI_Column UI_PrefHeight(ui_em(1.5f, 0.f)) - { - Vec4F32 presets[] = - { - v4f32(1.0f, 0.2f, 0.1f, 1.0f), - v4f32(1.0f, 0.8f, 0.2f, 1.0f), - v4f32(0.3f, 0.8f, 0.2f, 1.0f), - v4f32(0.1f, 0.8f, 0.4f, 1.0f), - v4f32(0.1f, 0.6f, 0.8f, 1.0f), - v4f32(0.5f, 0.3f, 0.8f, 1.0f), - v4f32(0.8f, 0.3f, 0.5f, 1.0f), - }; - UI_CornerRadius(ui_em(0.3f, 1.f).value) - for(U64 preset_idx = 0; preset_idx < ArrayCount(presets); preset_idx += 1) - { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = presets[preset_idx])); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_Clickable| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "###color_preset_%i", (int)preset_idx); - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) - { - Vec3F32 hsv = hsv_from_rgb(v3f32(presets[preset_idx].x, presets[preset_idx].y, presets[preset_idx].z)); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, 1); - entity->color_hsva = hsva; - } - ui_spacer(ui_em(0.3f, 1.f)); - } - } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(9.f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) - { - ui_sat_val_pickerf(entity->color_hsva.x, &entity->color_hsva.y, &entity->color_hsva.z, "###ent_satval_picker"); - } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(9.f, 1.f)) - ui_hue_pickerf(&entity->color_hsva.x, entity->color_hsva.y, entity->color_hsva.z, "###ent_hue_picker"); - } - } - - UI_Row UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_em(16.f, 1.f)) UI_CornerRadius(8.f) UI_TextAlignment(UI_TextAlign_Center) - RD_Palette(RD_PaletteCode_Floating) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Trash, 0, "Remove Color###color_toggle"))) - { - entity->flags &= ~RD_EntityFlag_HasColor; - } - } - - ui_spacer(ui_em(1.5f, 1.f)); - } -#endif #endif }break; } @@ -6777,7 +6534,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The if(can_play || !have_targets || processes.count == 0) UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_TagF(can_play ? "good" : "") + UI_TagF(can_play ? "good" : "weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6840,6 +6597,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: pause button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6865,7 +6623,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: stop button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - UI_TagF(can_stop ? "bad" : "") + UI_TagF(can_stop ? "bad" : "weak") { UI_Signal sig = {0}; { @@ -6894,6 +6652,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: step over button UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOver]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6922,6 +6681,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: step into button UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepInto]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -6950,6 +6710,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: step out button UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_step ? 0 : UI_BoxFlag_Disabled) + UI_TagF("weak") { UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOut]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); @@ -7282,10 +7043,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); CTRL_Event stop_event = d_ctrl_last_stop_event(); - UI_Palette *positive_scheme = rd_palette_from_code(RD_PaletteCode_Good); - UI_Palette *running_scheme = rd_palette_from_code(RD_PaletteCode_Pop); - UI_Palette *negative_scheme = rd_palette_from_code(RD_PaletteCode_Bad); - UI_Palette *palette = running_scheme; + String8 tag = str8_lit("pop"); if(!is_running) { switch(stop_event.cause) @@ -7293,32 +7051,19 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The default: case CTRL_EventCause_Finished: { - palette = positive_scheme; + tag = str8_lit("good_pop"); }break; case CTRL_EventCause_UserBreakpoint: case CTRL_EventCause_InterruptedByException: case CTRL_EventCause_InterruptedByTrap: case CTRL_EventCause_InterruptedByHalt: { - palette = negative_scheme; + tag = str8_lit("bad_pop"); }break; } } - if(ws->error_t > 0.01f) - { - UI_Palette *blended_scheme = push_array(ui_build_arena(), UI_Palette, 1); - MemoryCopyStruct(blended_scheme, palette); - for EachEnumVal(UI_ColorCode, code) - { - for(U64 idx = 0; idx < 4; idx += 1) - { - blended_scheme->colors[code].v[idx] += (negative_scheme->colors[code].v[idx] - blended_scheme->colors[code].v[idx]) * ws->error_t; - } - } - palette = blended_scheme; - } UI_Flags(UI_BoxFlag_DrawBackground) UI_CornerRadius(0) - UI_Palette(palette) + UI_Tag(tag) UI_Pane(bottom_bar_rect, str8_lit("###bottom_bar")) UI_WidthFill UI_Row UI_Flags(0) { @@ -8686,9 +8431,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: unpack settings B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); - Vec4F32 base_background_color = rd_color_from_tags(str8_array_zero(), str8_lit("background")); - Vec4F32 base_border_color = rd_color_from_tags(str8_array_zero(), str8_lit("border")); - Vec4F32 drop_shadow_color = rd_color_from_tags(str8_array_zero(), str8_lit("drop_shadow")); + Vec4F32 base_background_color = ui_color_from_name(str8_lit("background")); + Vec4F32 base_border_color = ui_color_from_name(str8_lit("border")); + Vec4F32 drop_shadow_color = ui_color_from_name(str8_lit("drop_shadow")); //- rjf: set up heatmap buckets F32 heatmap_bucket_size = 32.f; @@ -8779,7 +8524,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The Vec4F32 box_background_color = {0}; if(box->flags & UI_BoxFlag_DrawBackground) { - box_background_color = rd_color_from_tags(box->tags, str8_lit("background")); + box_background_color = ui_color_from_tags_name(box->tags, str8_lit("background")); } // rjf: draw background @@ -8801,7 +8546,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 hover_color = rd_color_from_tags(box->tags, str8_lit("hover")); + Vec4F32 hover_color = ui_color_from_tags_name(box->tags, str8_lit("hover")); // rjf: brighten { @@ -8901,7 +8646,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) { - Vec4F32 match_color = box->palette->background_pop; + String8 tags[] = {str8_lit("pop")}; + String8Array tags_array = {tags, ArrayCount(tags)}; + Vec4F32 match_color = ui_color_from_tags_name(tags_array, str8_lit("background")); dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } } @@ -8988,17 +8735,10 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The dr_pop_clip(); } - // rjf: draw overlay - if(b->flags & UI_BoxFlag_DrawOverlay) - { - R_Rect2DInst *inst = dr_rect(b->rect, b->palette->colors[UI_ColorCode_Background], 0, 0, 1.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); - } - // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { - Vec4F32 border_color = rd_color_from_tags(box->tags, str8_lit("border")); + Vec4F32 border_color = ui_color_from_tags_name(box->tags, str8_lit("border")); Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -9006,7 +8746,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("hover")); + Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("hover")); color.w *= b->hot_t; R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; @@ -9023,32 +8763,34 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } // rjf: draw sides + if(b->flags & UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight) { + Vec4F32 border_color = ui_color_from_tags_name(box->tags, str8_lit("border")); Rng2F32 r = b->rect; F32 half_thickness = 1.f; F32 softness = 0.f; if(b->flags & UI_BoxFlag_DrawSideTop) { - dr_rect(r2f32p(r.x0, r.y0, r.x1, r.y0+2*half_thickness), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x1, r.y0+2*half_thickness), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideBottom) { - dr_rect(r2f32p(r.x0, r.y1-2*half_thickness, r.x1, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y1-2*half_thickness, r.x1, r.y1), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideLeft) { - dr_rect(r2f32p(r.x0, r.y0, r.x0+2*half_thickness, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x0, r.y0, r.x0+2*half_thickness, r.y1), border_color, 0, 0, softness); } if(b->flags & UI_BoxFlag_DrawSideRight) { - dr_rect(r2f32p(r.x1-2*half_thickness, r.y0, r.x1, r.y1), b->palette->colors[UI_ColorCode_Border], 0, 0, softness); + dr_rect(r2f32p(r.x1-2*half_thickness, r.y0, r.x1, r.y1), border_color, 0, 0, softness); } } // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("focus")); + Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("focus")); color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -9063,7 +8805,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } - Vec4F32 color = rd_color_from_tags(box->tags, str8_lit("focus")); + Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("focus")); color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -9120,7 +8862,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { String8 tags[] = {str8_lit("bad")}; String8Array tags_array = {tags, ArrayCount(tags)}; - Vec4F32 color = rd_color_from_tags(tags_array, str8_lit("text")); + Vec4F32 color = ui_color_from_tags_name(tags_array, str8_lit("text")); color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); @@ -10591,52 +10333,6 @@ rd_push_search_string(Arena *arena) //- rjf: colors -internal Vec4F32 -rd_color_from_tags(String8Array tags, String8 name) -{ - Vec4F32 result = {0}; - { - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window); - RD_Theme *theme = ws->theme; - RD_ThemePattern *pattern = 0; - U64 best_match_count = 0; - for(U64 idx = 0; idx < theme->patterns_count; idx += 1) - { - RD_ThemePattern *p = &theme->patterns[idx]; - U64 match_count = 0; - B32 name_matches = 0; - for EachIndex(key_tags_idx, tags.count+1) - { - String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; - for EachIndex(p_tags_idx, p->tags.count) - { - if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) - { - name_matches = (key_tags_idx == tags.count); - match_count += 1; - break; - } - } - } - if(name_matches && match_count > best_match_count) - { - pattern = p; - best_match_count = match_count; - } - if(match_count == tags.count+1) - { - break; - } - } - if(pattern != 0) - { - result = pattern->linear; - } - } - return result; -} - internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 4cf31c1f..202ea108 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -419,18 +419,9 @@ struct RD_RegsNode //////////////////////////////// //~ rjf: Structured Theme Types, Parsed From Config -typedef struct RD_ThemePattern RD_ThemePattern; -struct RD_ThemePattern -{ - String8Array tags; - Vec4F32 linear; -}; - typedef struct RD_Theme RD_Theme; struct RD_Theme { - RD_ThemePattern *patterns; - U64 patterns_count; Vec4F32 colors[RD_ThemeColor_COUNT]; }; @@ -548,8 +539,8 @@ struct RD_WindowState B32 window_temporarily_focused_ipc; B32 window_layout_reset; - // rjf: theme - RD_Theme *theme; + // rjf: theme (recomputed each frame) + UI_Theme *theme; // rjf: config/settings UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme @@ -1164,7 +1155,6 @@ internal String8 rd_push_search_string(Arena *arena); //~ rjf: Colors, Fonts, Config //- rjf: colors -internal Vec4F32 rd_color_from_tags(String8Array tags, String8 name); internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 97cfdeca..5964b9ea 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -126,13 +126,13 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3); + F32 line_num_width_px = floor_f32(big_glyph_advance * (log10(visible_line_num_range.max) + 3)); F32 priority_margin_width_px = 0; F32 catchall_margin_width_px = 0; if(flags & RD_CodeViewBuildFlag_Margins) { - priority_margin_width_px = big_glyph_advance*3.5f; - catchall_margin_width_px = big_glyph_advance*3.5f; + priority_margin_width_px = floor_f32(big_glyph_advance*3.5f); + catchall_margin_width_px = floor_f32(big_glyph_advance*3.5f); } TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, text_info, text_data, visible_line_num_range); @@ -185,7 +185,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla code_slice_params.catchall_margin_width_px = catchall_margin_width_px; code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; - code_slice_params.margin_float_off_px = scroll_pos.x.idx + scroll_pos.x.off; + code_slice_params.margin_float_off_px = scroll_pos.x.idx + floor_f32(scroll_pos.x.off); // rjf: fill text info { @@ -2792,7 +2792,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ui_set_next_fixed_x(0); ui_set_next_fixed_y(0); ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary))); + ui_set_next_tag(str8_lit("pop")); ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); } } @@ -2813,9 +2813,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ui_set_next_fixed_x(0); ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); ui_set_next_fixed_height(ui_top_font_size()*1.f); - Vec4F32 boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - boundary_color.w *= 0.5f; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = boundary_color)); + ui_set_next_tag(str8_lit("pop")); + ui_set_next_transparency(0.5f); ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); } } @@ -2841,14 +2840,17 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ProfBegin("determine cell's palette"); UI_BoxFlags cell_flags = 0; UI_Palette *palette = ui_top_palette(); + String8 cell_tag = {0}; { if(cell_info.flags & RD_WatchCellFlag_IsErrored) { cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBad; + cell_tag = str8_lit("bad"); } else if(cell_info.inheritance_tooltip.size != 0) { cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawPop; + cell_tag = str8_lit("pop"); } else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && rd_state->hover_regs_slot == RD_RegSlot_Cfg) @@ -2896,6 +2898,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(RD_FontSlot_Code) + UI_TagF(cell->kind == RD_WatchCellKind_Expr ? "weak" : "") { // rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) @@ -3148,7 +3151,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) { ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), cell_info.inheritance_tooltip); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); } } @@ -4099,7 +4102,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); //- rjf: fill unwind frame annotations - if(unwind.frames.count != 0) + if(unwind.frames.count != 0) UI_Tag(str8_lit("weak")) { U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs); for(U64 idx = 1; idx < unwind.frames.count; idx += 1) @@ -4119,7 +4122,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->kind_string = str8_lit("Call Stack Frame"); - annotation->color = symbol_name.size != 0 ? rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol) : ui_top_palette()->text_weak; + annotation->color = symbol_name.size != 0 ? ui_color_from_name(str8_lit("code_symbol")) : ui_color_from_name(str8_lit("text")); annotation->vaddr_range = frame_vaddr_range; for(U64 vaddr = frame_vaddr_range_in_viz.min; vaddr < frame_vaddr_range_in_viz.max; vaddr += 1) { @@ -4157,14 +4160,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) DI_Scope *scope = di_scope_open(); Vec4F32 color_gen_table[] = { - rd_rgba_from_theme_color(RD_ThemeColor_Thread0), - rd_rgba_from_theme_color(RD_ThemeColor_Thread1), - rd_rgba_from_theme_color(RD_ThemeColor_Thread2), - rd_rgba_from_theme_color(RD_ThemeColor_Thread3), - rd_rgba_from_theme_color(RD_ThemeColor_Thread4), - rd_rgba_from_theme_color(RD_ThemeColor_Thread5), - rd_rgba_from_theme_color(RD_ThemeColor_Thread6), - rd_rgba_from_theme_color(RD_ThemeColor_Thread7), + ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); for(E_String2NumMapNode *n = e_parse_state->ctx->locals_map->first; n != 0; n = n->order_next) @@ -4388,8 +4384,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) if(row_range_bytes.min%64 == 0) { row_is_boundary = 1; - Vec4F32 row_boundary_color = rd_rgba_from_theme_color(RD_ThemeColor_CacheLineBoundary); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = row_boundary_color)); + ui_set_next_tag(str8_lit("pop")); } UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_DrawSideTop*!!row_is_boundary, "row_%I64x", row_range_bytes.min); UI_Parent(row) @@ -4487,7 +4482,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } if(a->type_string.size != 0) { - rd_code_label(1.f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeType), a->type_string); + rd_code_label(1.f, 1, ui_color_from_name(str8_lit("code_type")), a->type_string); } UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(str8_from_memory_size(scratch.arena, dim_1u64(a->vaddr_range))); if(a->next != 0) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 24e33ef8..0f6376d3 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -484,7 +484,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) F32 lock_icon_off = ui_top_font_size()*0.2f; String8 tags[] = {str8_lit("bad")}; String8Array tags_array = {tags, ArrayCount(tags)}; - Vec4F32 color = rd_color_from_tags(tags_array, str8_lit("text")); + Vec4F32 color = ui_color_from_tags_name(tags_array, str8_lit("text")); dr_text(rd_font_from_slot(RD_FontSlot_Icons), box->font_size, 0, 0, FNT_RasterFlag_Smooth, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, @@ -593,10 +593,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 ctrlified = (os_get_modifiers() & OS_Modifier_Ctrl); Vec4F32 code_line_bgs[] = { - rd_color_from_tags(str8_array_zero(), str8_lit("line_info_0")), - rd_color_from_tags(str8_array_zero(), str8_lit("line_info_1")), - rd_color_from_tags(str8_array_zero(), str8_lit("line_info_2")), - rd_color_from_tags(str8_array_zero(), str8_lit("line_info_3")), + ui_color_from_name(str8_lit("line_info_0")), + ui_color_from_name(str8_lit("line_info_1")), + ui_color_from_name(str8_lit("line_info_2")), + ui_color_from_name(str8_lit("line_info_3")), }; F32 line_num_padding_px = ui_top_font_size()*1.f; F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); @@ -698,18 +698,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { if(color.w == 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + color = ui_color_from_name(str8_lit("thread_1")); } if(unwind_count != 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); + color = ui_color_from_name(str8_lit("thread_unwound")); } else if(thread == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByHalt || stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadError); + color = ui_color_from_name(str8_lit("thread_error")); } if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index()) { @@ -852,18 +852,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { if(color.w == 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_Thread1); + color = ui_color_from_name(str8_lit("thread_1")); } if(unwind_count != 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadUnwound); + color = ui_color_from_name(str8_lit("thread_unwound")); } else if(thread == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByHalt || stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) { - color = rd_rgba_from_theme_color(RD_ThemeColor_ThreadError); + color = ui_color_from_name(str8_lit("thread_error")); } if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index()) { @@ -959,7 +959,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 bp_rgba = rd_color_from_cfg(bp); if(bp_rgba.w == 0) { - bp_rgba = rd_rgba_from_theme_color(RD_ThemeColor_Breakpoint); + bp_rgba = ui_color_from_name(str8_lit("breakpoint")); } B32 bp_is_disabled = rd_disabled_from_cfg(bp); if(bp_is_disabled) @@ -1052,7 +1052,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 color = rd_color_from_cfg(pin); if(color.w == 0) { - color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + color = ui_color_from_name(str8_lit("code_default")); } // rjf: build box for watch @@ -1667,16 +1667,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = txt_rng(*cursor, *mark); - n->color = ui_top_palette()->colors[UI_ColorCode_Selection]; + n->color = ui_color_from_name(str8_lit("selection")); SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } // rjf: push for ctrlified mouse expr - if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min)) + if(ctrlified && !txt_pt_match(result.mouse_expr_rng.max, result.mouse_expr_rng.min)) UI_Tag(str8_lit("pop")) { TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = result.mouse_expr_rng; - n->color = ui_top_palette()->background_pop; + n->color = ui_color_from_name(str8_lit("background")); SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } } @@ -1870,6 +1870,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ceil_f32(line_box->rect.y1) + 1.f, }; Vec4F32 color = n->color; + color.w = ClampTop(color.w, 0.1f); if(!is_focused) { color.w *= 0.5f; @@ -1898,7 +1899,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness/2.f, line_box->rect.y1+params->font_size*0.25f, }; - Vec4F32 cursor_color = ui_top_palette()->cursor; + Vec4F32 cursor_color = ui_color_from_name(str8_lit("cursor")); if(!is_focused) { cursor_color.w *= 0.5f; @@ -2192,7 +2193,7 @@ rd_label(String8 string) { fstr.string = p->string; fstr.params.font = ui_top_font(); - fstr.params.color = ui_top_palette()->colors[UI_ColorCode_Text]; + fstr.params.color = ui_color_from_name(str8_lit("text")); fstr.params.size = ui_top_font_size(); if(p->flags & StringPartFlag_Code) { @@ -2686,7 +2687,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { display_string = params->pre_edit_value; - UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); + UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); if(params->fuzzy_matches != 0) { ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 5c163c27..9ac55cf7 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -134,10 +134,10 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) FNT_Tag font = box->font; F32 font_size = box->font_size; F32 tab_size = box->tab_size; - Vec4F32 cursor_color = box->palette->colors[UI_ColorCode_Cursor]; + Vec4F32 cursor_color = ui_color_from_tags_name(box->tags, str8_lit("cursor")); cursor_color.w *= box->parent->parent->focus_active_t; - Vec4F32 select_color = box->palette->colors[UI_ColorCode_Selection]; - select_color.w *= (box->parent->parent->focus_active_t*0.2f + 0.8f); + Vec4F32 select_color = ui_color_from_tags_name(box->tags, str8_lit("selection")); + select_color.w *= 0.1f*(box->parent->parent->focus_active_t*0.2f + 0.8f); Vec2F32 text_position = ui_box_text_position(box); String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; @@ -1213,6 +1213,7 @@ internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices) { ui_push_palette(ui_state->widget_palette_info.scrollbar_palette); + ui_push_tag(str8_lit("scroll_bar")); //- rjf: unpack S64 idx_range_dim = Max(dim_1s64(idx_range), 1); @@ -1332,6 +1333,7 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } } + ui_pop_tag(); ui_pop_palette(); return new_pt; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 8aba4805..8c01f6ed 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -782,7 +782,7 @@ ui_box_from_key(UI_Key key) //~ rjf: Top-Level Building API internal void -ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) +ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) { //- rjf: reset per-build ui state { @@ -844,6 +844,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U //- rjf: fill build phase parameters { + ui_state->theme = theme; ui_state->events = events; ui_state->window = window; ui_state->mouse = (os_window_is_focused(window) || ui_state->last_time_mousemoved_us+500000 >= os_now_microseconds()) ? os_mouse_from_window(window) : v2f32(-100, -100); @@ -2194,6 +2195,86 @@ ui_build_palette_(UI_Palette *base, UI_Palette *overrides) return palette; } +//- rjf: tag gathering + +internal String8Array +ui_top_tags(void) +{ + if(ui_state->current_gen_tags_gen != ui_state->tag_stack.gen) + { + ui_state->current_gen_tags_gen = ui_state->tag_stack.gen; + Temp scratch = scratch_begin(0, 0); + String8List tags = {0}; + for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) + { + if(n->v.size == 1 && n->v.str[0] == '.') + { + break; + } + if(n->v.size != 0) + { + str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); + } + } + ui_state->current_gen_tags = str8_array_from_list(ui_build_arena(), &tags); + scratch_end(scratch); + } + return ui_state->current_gen_tags; +} + +//- rjf: theme color lookups + +internal Vec4F32 +ui_color_from_name(String8 name) +{ + Vec4F32 result = ui_color_from_tags_name(ui_top_tags(), name); + return result; +} + +internal Vec4F32 +ui_color_from_tags_name(String8Array tags, String8 name) +{ + Vec4F32 result = {0}; + { + UI_Theme *theme = ui_state->theme; + UI_ThemePattern *pattern = 0; + U64 best_match_count = 0; + for(U64 idx = 0; idx < theme->patterns_count; idx += 1) + { + UI_ThemePattern *p = &theme->patterns[idx]; + U64 match_count = 0; + B32 name_matches = 0; + for EachIndex(key_tags_idx, tags.count+1) + { + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; + for EachIndex(p_tags_idx, p->tags.count) + { + if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) + { + name_matches = (key_tags_idx == tags.count); + match_count += 1; + break; + } + } + } + if(name_matches && match_count > best_match_count) + { + pattern = p; + best_match_count = match_count; + } + if(match_count == tags.count+1) + { + break; + } + } + if(pattern != 0) + { + result = pattern->linear; + } + } + return result; +} + //- rjf: box node construction internal UI_Box * @@ -2354,26 +2435,7 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_padding = ui_state->text_padding_stack.top->v; box->hover_cursor = ui_state->hover_cursor_stack.top->v; box->custom_draw = 0; - if(ui_state->current_gen_tags_gen != ui_state->tag_stack.gen) - { - ui_state->current_gen_tags_gen = ui_state->tag_stack.gen; - Temp scratch = scratch_begin(0, 0); - String8List tags = {0}; - for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) - { - if(n->v.size == 1 && n->v.str[0] == '.') - { - break; - } - if(n->v.size != 0) - { - str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); - } - } - ui_state->current_gen_tags = str8_array_from_list(ui_build_arena(), &tags); - scratch_end(scratch); - } - box->tags = ui_state->current_gen_tags; + box->tags = ui_top_tags(); } //- rjf: auto-pop all stacks @@ -2445,13 +2507,13 @@ internal void ui_box_equip_display_string(UI_Box *box, String8 string) { ProfBeginFunction(); + Vec4F32 text_color = ui_color_from_name(str8_lit("text")); box->string = push_str8_copy(ui_build_arena(), string); box->flags |= UI_BoxFlag_HasDisplayString; - UI_ColorCode text_color_code = (box->flags & UI_BoxFlag_DrawTextWeak ? UI_ColorCode_TextWeak : UI_ColorCode_Text); if(box->flags & UI_BoxFlag_DrawText && (box->fastpath_codepoint == 0 || !(box->flags & UI_BoxFlag_DrawTextFastpathCodepoint))) { String8 display_string = ui_box_display_string(box); - DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); @@ -2465,16 +2527,16 @@ ui_box_equip_display_string(UI_Box *box, String8 string) U64 fpcp_pos = str8_find_needle(display_string, 0, fpcp, StringMatchFlag_CaseInsensitive); if(fpcp_pos < display_string.size) { - DR_FStrNode pst_fstr_n = {0, {str8_skip(display_string, fpcp_pos+fpcp.size), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; - DR_FStrNode cdp_fstr_n = {&pst_fstr_n, {str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 3.f, 0}}}; - DR_FStrNode pre_fstr_n = {&cdp_fstr_n, {str8_prefix(display_string, fpcp_pos), {box->font, box->text_raster_flags, box->palette->colors[text_color_code], box->font_size, 0, 0}}}; + DR_FStrNode pst_fstr_n = {0, {str8_skip(display_string, fpcp_pos+fpcp.size), {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; + DR_FStrNode cdp_fstr_n = {&pst_fstr_n, {str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), {box->font, box->text_raster_flags, text_color, box->font_size, 3.f, 0}}}; + DR_FStrNode pre_fstr_n = {&cdp_fstr_n, {str8_prefix(display_string, fpcp_pos), {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; DR_FStrList fstrs = {&pre_fstr_n, &pst_fstr_n, 3}; box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); } else { - DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, box->palette->colors[UI_ColorCode_Text], box->font_size, 0, 0}}}; + DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; box->display_fstrs = dr_fstrs_copy(ui_build_arena(), &fstrs); box->display_fruns = dr_fruns_from_fstrs(ui_build_arena(), box->tab_size, &box->display_fstrs); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 32bc53fd..a020f576 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -216,6 +216,23 @@ struct UI_Size F32 strictness; }; +//////////////////////////////// +//~ rjf: Themes + +typedef struct UI_ThemePattern UI_ThemePattern; +struct UI_ThemePattern +{ + String8Array tags; + Vec4F32 linear; +}; + +typedef struct UI_Theme UI_Theme; +struct UI_Theme +{ + UI_ThemePattern *patterns; + U64 patterns_count; +}; + //////////////////////////////// //~ rjf: Palettes @@ -679,6 +696,7 @@ struct UI_State //- rjf: build parameters UI_IconInfo icon_info; + UI_Theme *theme; UI_WidgetPaletteInfo widget_palette_info; UI_AnimationInfo animation_info; OS_Handle window; @@ -850,7 +868,7 @@ internal UI_Box * ui_box_from_key(UI_Key key); //////////////////////////////// //~ rjf: Top-Level Building API -internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); +internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); internal void ui_end_build(void); internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis); internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); @@ -893,6 +911,13 @@ internal void ui_set_auto_focus_hot_key(UI_Key key); internal UI_Palette * ui_build_palette_(UI_Palette *base, UI_Palette *overrides); #define ui_build_palette(base, ...) ui_build_palette_((base), &(UI_Palette){.text = v4f32(0, 0, 0, 0), __VA_ARGS__}) +//- rjf: tag gathering +internal String8Array ui_top_tags(void); + +//- rjf: theme color lookups +internal Vec4F32 ui_color_from_name(String8 name); +internal Vec4F32 ui_color_from_tags_name(String8Array tags, String8 name); + //- rjf: box node construction internal UI_Box * ui_build_box_from_key(UI_BoxFlags flags, UI_Key key); internal UI_Key ui_active_seed_key(void); From eb4fe472f972e5523474afc9f7c011485b451528 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Feb 2025 19:33:47 -0800 Subject: [PATCH 142/755] tweaks --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_views.c | 2 +- src/ui/ui_core.c | 5 ++++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d8bcb888..dff9c85c 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -809,7 +809,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x2222225f,\n background: alt: 0x0000005f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b2dfeb79..a2f034b3 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1050,7 +1050,7 @@ RD_ThemePresetTable: floating: { - background: 0x2222225f, + background: 0x1b1b1baf, background: alt: 0x0000005f, border: 0xbfbfbf1f, scroll_bar: diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5964b9ea..cef5752f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2898,7 +2898,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(RD_FontSlot_Code) - UI_TagF(cell->kind == RD_WatchCellKind_Expr ? "weak" : "") + UI_TagF("weak") { // rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 8c01f6ed..0240d53c 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1920,11 +1920,13 @@ ui_tooltip_begin_base(void) ui_push_text_raster_flags(ui_bottom_text_raster_flags()); ui_push_palette(ui_bottom_palette()); ui_push_tag(str8_lit(".")); + ui_push_tag(str8_lit("floating")); } internal void ui_tooltip_end_base(void) { + ui_pop_tag(); ui_pop_tag(); ui_pop_palette(); ui_pop_text_raster_flags(); @@ -2010,7 +2012,7 @@ ui_begin_ctx_menu(UI_Key key) ui_push_palette(ui_state->widget_palette_info.ctx_menu_palette); ui_push_tag(str8_lit(".")); B32 is_open = ui_key_match(key, ui_state->ctx_menu_key) && ui_state->ctx_menu_open; - if(is_open != 0) + if(is_open != 0) UI_TagF("floating") { ui_state->ctx_menu_touched_this_frame = 1; ui_state->ctx_menu_root->flags |= UI_BoxFlag_RoundChildrenByParent; @@ -2021,6 +2023,7 @@ ui_begin_ctx_menu(UI_Key key) ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clip; ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clickable; ui_state->ctx_menu_root->corner_radii[Corner_00] = ui_state->ctx_menu_root->corner_radii[Corner_01] = ui_state->ctx_menu_root->corner_radii[Corner_10] = ui_state->ctx_menu_root->corner_radii[Corner_11] = ui_top_font_size()*0.25f; + ui_state->ctx_menu_root->tags = ui_top_tags(); ui_state->ctx_menu_root->palette = ui_top_palette(); ui_state->ctx_menu_root->blur_size = ui_top_blur_size(); ui_spacer(ui_em(1.f, 1.f)); From 73351b755042583e0926424dc4a18292aa2d42b9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 07:21:53 -0800 Subject: [PATCH 143/755] fix zero-sized content rect busting panel rectangles --- src/raddbg/raddbg_core.c | 1531 +++++++++++++++++++------------------- 1 file changed, 765 insertions(+), 766 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1ebd1da5..7ece409f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7462,840 +7462,843 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //////////////////////////// //- rjf: panel leaf UI // - ProfScope("leaf panel UI") - for(RD_PanelNode *panel = panel_tree.root; - panel != &rd_nil_panel_node; - panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + if(content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0) { - if(panel->first != &rd_nil_panel_node) {continue;} - B32 panel_is_focused = (window_is_focused && - !ws->menu_bar_focused && - !query_is_open && - !ui_any_ctx_menu_is_open() && - !ws->hover_eval_focused && - panel_tree.focused == panel); - RD_Cfg *selected_tab = panel->selected_tab; - RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); - F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); - ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) - UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + ProfScope("leaf panel UI") + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) { - ////////////////////////// - //- rjf: calculate UI rectangles - // - Vec2F32 content_rect_dim = dim_2f32(content_rect); - Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); - Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0 / content_rect_dim.x, - target_rect_px.y0 / content_rect_dim.y, - target_rect_px.x1 / content_rect_dim.x, - target_rect_px.y1 / content_rect_dim.y); - Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1)); - Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, - panel_rect_pct.y0*content_rect_dim.y, - panel_rect_pct.x1*content_rect_dim.x, - panel_rect_pct.y1*content_rect_dim.y); - panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); - F32 tab_bar_rheight = ui_top_font_size()*3.f; - F32 tab_bar_vheight = ui_top_font_size()*2.6f; - F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; - F32 tab_spacing = ui_top_font_size()*0.4f; - F32 filter_bar_height = ui_top_font_size()*3.f; - Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); - Rng2F32 content_rect = r2f32p(panel_rect.x0, panel_rect.y0+tab_bar_vheight, panel_rect.x1, panel_rect.y1); - Rng2F32 filter_rect = {0}; - if(panel->tab_side == Side_Max) + if(panel->first != &rd_nil_panel_node) {continue;} + B32 panel_is_focused = (window_is_focused && + !ws->menu_bar_focused && + !query_is_open && + !ui_any_ctx_menu_is_open() && + !ws->hover_eval_focused && + panel_tree.focused == panel); + RD_Cfg *selected_tab = panel->selected_tab; + RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); + F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); + ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) + UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { - tab_bar_rect.y0 = panel_rect.y1 - tab_bar_vheight; - tab_bar_rect.y1 = panel_rect.y1; - content_rect.y0 = panel_rect.y0; - content_rect.y1 = panel_rect.y1 - tab_bar_vheight; - } - if(selected_tab_is_filtering_t > 0.01f) - { - filter_rect.x0 = content_rect.x0; - filter_rect.y0 = content_rect.y0; - filter_rect.x1 = content_rect.x1; - content_rect.y0 += filter_bar_height*selected_tab_is_filtering_t; - filter_rect.y1 = content_rect.y0; - } - tab_bar_rect = intersect_2f32(tab_bar_rect, panel_rect); - content_rect = intersect_2f32(content_rect, panel_rect); - - ////////////////////////// - //- rjf: decide to skip this panel (e.g. if it is too small - // - B32 build_panel = (content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0); - - ////////////////////////// - //- rjf: build combined split+movetab drag/drop sites - // - if(build_panel) - { - RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); - if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) + ////////////////////////// + //- rjf: calculate UI rectangles + // + Vec2F32 content_rect_dim = dim_2f32(content_rect); + Rng2F32 target_rect_px = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + Rng2F32 target_rect_pct = r2f32p(target_rect_px.x0 / content_rect_dim.x, + target_rect_px.y0 / content_rect_dim.y, + target_rect_px.x1 / content_rect_dim.x, + target_rect_px.y1 / content_rect_dim.y); + Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1)); + Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, + panel_rect_pct.y0*content_rect_dim.y, + panel_rect_pct.x1*content_rect_dim.x, + panel_rect_pct.y1*content_rect_dim.y); + panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); + F32 tab_bar_rheight = ui_top_font_size()*3.f; + F32 tab_bar_vheight = ui_top_font_size()*2.6f; + F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; + F32 tab_spacing = ui_top_font_size()*0.4f; + F32 filter_bar_height = ui_top_font_size()*3.f; + Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); + Rng2F32 content_rect = r2f32p(panel_rect.x0, panel_rect.y0+tab_bar_vheight, panel_rect.x1, panel_rect.y1); + Rng2F32 filter_rect = {0}; + if(panel->tab_side == Side_Max) { - F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); - drop_site_dim_px = Min(drop_site_dim_px, dim_2f32(panel_rect).v[panel->split_axis]/4.f); - drop_site_dim_px = Max(drop_site_dim_px, ceil_f32(ui_top_font_size()*3.f)); - Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); - Vec2F32 panel_center = center_2f32(panel_rect); - F32 corner_radius = ui_top_font_size()*0.5f; - F32 padding = ceil_f32(ui_top_font_size()*0.5f); - struct - { - UI_Key key; - Dir2 split_dir; - Rng2F32 rect; - } - sites[] = + tab_bar_rect.y0 = panel_rect.y1 - tab_bar_vheight; + tab_bar_rect.y1 = panel_rect.y1; + content_rect.y0 = panel_rect.y0; + content_rect.y1 = panel_rect.y1 - tab_bar_vheight; + } + if(selected_tab_is_filtering_t > 0.01f) + { + filter_rect.x0 = content_rect.x0; + filter_rect.y0 = content_rect.y0; + filter_rect.x1 = content_rect.x1; + content_rect.y0 += filter_bar_height*selected_tab_is_filtering_t; + filter_rect.y1 = content_rect.y0; + } + tab_bar_rect = intersect_2f32(tab_bar_rect, panel_rect); + content_rect = intersect_2f32(content_rect, panel_rect); + + ////////////////////////// + //- rjf: decide to skip this panel (e.g. if it is too small + // + B32 build_panel = (content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0); + + ////////////////////////// + //- rjf: build combined split+movetab drag/drop sites + // + if(build_panel) + { + RD_Cfg *view = rd_cfg_from_id(rd_state->drag_drop_regs->view); + if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero())) { + F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f); + drop_site_dim_px = Min(drop_site_dim_px, dim_2f32(panel_rect).v[panel->split_axis]/4.f); + drop_site_dim_px = Max(drop_site_dim_px, ceil_f32(ui_top_font_size()*3.f)); + Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2); + Vec2F32 panel_center = center_2f32(panel_rect); + F32 corner_radius = ui_top_font_size()*0.5f; + F32 padding = ceil_f32(ui_top_font_size()*0.5f); + struct { - ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel->cfg), - Dir2_Invalid, - r2f32(sub_2f32(panel_center, drop_site_half_dim), - add_2f32(panel_center, drop_site_half_dim)) - }, + UI_Key key; + Dir2 split_dir; + Rng2F32 rect; + } + sites[] = { - ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel->cfg), - Dir2_Up, - r2f32p(panel_center.x-drop_site_half_dim.x, - panel_center.y-drop_site_half_dim.y - drop_site_half_dim.y*2, - panel_center.x+drop_site_half_dim.x, - panel_center.y+drop_site_half_dim.y - drop_site_half_dim.y*2), - }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_center_%p", panel->cfg), + Dir2_Invalid, + r2f32(sub_2f32(panel_center, drop_site_half_dim), + add_2f32(panel_center, drop_site_half_dim)) + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_up_%p", panel->cfg), + Dir2_Up, + r2f32p(panel_center.x-drop_site_half_dim.x, + panel_center.y-drop_site_half_dim.y - drop_site_half_dim.y*2, + panel_center.x+drop_site_half_dim.x, + panel_center.y+drop_site_half_dim.y - drop_site_half_dim.y*2), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel->cfg), + Dir2_Down, + r2f32p(panel_center.x-drop_site_half_dim.x, + panel_center.y-drop_site_half_dim.y + drop_site_half_dim.y*2, + panel_center.x+drop_site_half_dim.x, + panel_center.y+drop_site_half_dim.y + drop_site_half_dim.y*2), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel->cfg), + Dir2_Left, + r2f32p(panel_center.x-drop_site_half_dim.x - drop_site_half_dim.x*2, + panel_center.y-drop_site_half_dim.y, + panel_center.x+drop_site_half_dim.x - drop_site_half_dim.x*2, + panel_center.y+drop_site_half_dim.y), + }, + { + ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel->cfg), + Dir2_Right, + r2f32p(panel_center.x-drop_site_half_dim.x + drop_site_half_dim.x*2, + panel_center.y-drop_site_half_dim.y, + panel_center.x+drop_site_half_dim.x + drop_site_half_dim.x*2, + panel_center.y+drop_site_half_dim.y), + }, + }; + UI_CornerRadius(corner_radius) + for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) { - ui_key_from_stringf(ui_key_zero(), "drop_split_down_%p", panel->cfg), - Dir2_Down, - r2f32p(panel_center.x-drop_site_half_dim.x, - panel_center.y-drop_site_half_dim.y + drop_site_half_dim.y*2, - panel_center.x+drop_site_half_dim.x, - panel_center.y+drop_site_half_dim.y + drop_site_half_dim.y*2), - }, - { - ui_key_from_stringf(ui_key_zero(), "drop_split_left_%p", panel->cfg), - Dir2_Left, - r2f32p(panel_center.x-drop_site_half_dim.x - drop_site_half_dim.x*2, - panel_center.y-drop_site_half_dim.y, - panel_center.x+drop_site_half_dim.x - drop_site_half_dim.x*2, - panel_center.y+drop_site_half_dim.y), - }, - { - ui_key_from_stringf(ui_key_zero(), "drop_split_right_%p", panel->cfg), - Dir2_Right, - r2f32p(panel_center.x-drop_site_half_dim.x + drop_site_half_dim.x*2, - panel_center.y-drop_site_half_dim.y, - panel_center.x+drop_site_half_dim.x + drop_site_half_dim.x*2, - panel_center.y+drop_site_half_dim.y), - }, - }; - UI_CornerRadius(corner_radius) + UI_Key key = sites[idx].key; + Dir2 dir = sites[idx].split_dir; + Rng2F32 rect = sites[idx].rect; + Axis2 split_axis = axis2_from_dir2(dir); + Side split_side = side_from_dir2(dir); + if(dir != Dir2_Invalid && split_axis == panel->parent->split_axis) + { + continue; + } + UI_Box *site_box = &ui_nil_box; + { + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) + { + site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); + ui_signal_from_box(site_box); + } + UI_Box *site_box_viz = &ui_nil_box; + UI_GroupKey(key) + UI_Parent(site_box) UI_WidthFill UI_HeightFill + UI_Padding(ui_px(padding, 1.f)) + UI_Column + UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(axis2_flip(split_axis)); + site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawHotEffects, ui_key_zero()); + } + if(dir != Dir2_Invalid) + { + UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(split_axis); + UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") + { + if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + ui_spacer(ui_px(padding, 1.f)); + if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } + ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); + } + } + } + else + { + UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) + { + ui_set_next_child_layout_axis(split_axis); + UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); + UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") + { + ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + } + if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) + { + if(dir != Dir2_Invalid) + { + rd_cmd(RD_CmdKind_SplitPanel, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .dir2 = dir); + } + else + { + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .prev_view = rd_cfg_list_last(&panel->tabs)->id); + } + } + } for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) + { + B32 is_drop_hot = ui_key_match(ui_drop_hot_key(), sites[idx].key); + if(is_drop_hot) + { + Axis2 split_axis = axis2_from_dir2(sites[idx].split_dir); + Side split_side = side_from_dir2(sites[idx].split_dir); + Rng2F32 future_split_rect_target = panel_rect; + if(sites[idx].split_dir != Dir2_Invalid) + { + Vec2F32 panel_center = center_2f32(panel_rect); + future_split_rect_target.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; + } + future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); + Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); + Rng2F32 future_split_rect = + { + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + }; + UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + } + } + } + } + } + + ////////////////////////// + //- rjf: build catch-all panel drop-site + // + UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); + if(build_panel) UI_Rect(panel_rect) + { + UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); + ui_signal_from_box(catchall_drop_site); + } + + ////////////////////////// + //- rjf: build filtering box + // +#if 0 // TODO(rjf): @cfg + { + RD_Cfg *view = selected_tab; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); + RD_ViewState *view_state = rd_view_state_from_cfg(view); + UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = view->id) { - UI_Key key = sites[idx].key; - Dir2 dir = sites[idx].split_dir; - Rng2F32 rect = sites[idx].rect; - Axis2 split_axis = axis2_from_dir2(dir); - Side split_side = side_from_dir2(dir); - if(dir != Dir2_Invalid && split_axis == panel->parent->split_axis) + if(view_state->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + { + rd_cmd(RD_CmdKind_ApplyFilter); + } + if(view_state->is_filtering || selected_tab_is_filtering_t > 0.01f) + { + UI_Box *filter_box = &ui_nil_box; + UI_Rect(filter_rect) + { + ui_set_next_child_layout_axis(Axis2_X); + filter_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder, "filter_box_%p", view); + } + UI_Parent(filter_box) UI_WidthFill UI_HeightFill + { + UI_PrefWidth(ui_em(3.f, 1.f)) + UI_TagF("weak") + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); + UI_PrefWidth(ui_text_dim(10, 1)) + { + ui_label(str8_lit("Filter")); + } + ui_spacer(ui_em(0.5f, 1.f)); + RD_Font(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) + UI_Focus(view_state->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) + UI_TextPadding(ui_top_font_size()*0.5f) + { + UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode), + 0, + 0, + &view_state->filter_cursor, + &view_state->filter_mark, + view_state->filter_buffer, + sizeof(view_state->filter_buffer), + &view_state->filter_string_size, + 0, + str8(view_state->filter_buffer, view_state->filter_string_size), + str8_lit("###filter_text_input")); + if(ui_pressed(sig)) + { + rd_cmd(RD_CmdKind_FocusPanel); + } + } + } + } + } + } +#endif + + ////////////////////////// + //- rjf: panel not selected? -> darken + // + if(build_panel) if(panel != panel_tree.focused) + { + UI_Rect(content_rect) UI_TagF("inactive") + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + + ////////////////////////// + //- rjf: build panel container box + // + UI_Box *panel_box = &ui_nil_box; + if(build_panel) UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) + { + UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_box_%p", panel->cfg); + panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| + UI_BoxFlag_Clip| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DisableFocusOverlay| + ((panel_tree.focused != panel)*UI_BoxFlag_DisableFocusBorder), + panel_key); + } + + ////////////////////////// + //- rjf: loading animation for stable view + // + UI_Box *loading_overlay_container = &ui_nil_box; + if(build_panel) UI_Parent(panel_box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + ////////////////////////// + //- rjf: build selected tab view + // + if(build_panel) + UI_Parent(panel_box) + UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + UI_WidthFill + { + //- rjf: push interaction registers, fill with per-view states + rd_push_regs(.panel = panel->cfg->id, + .view = selected_tab->id); + { + String8 view_expr = rd_expr_from_cfg(selected_tab); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + rd_regs()->file_path = view_file_path; + } + + //- rjf: build view container + UI_Box *view_container_box = &ui_nil_box; + UI_FixedWidth(dim_2f32(content_rect).x) + UI_FixedHeight(dim_2f32(content_rect).y) + UI_ChildLayoutAxis(Axis2_Y) + { + view_container_box = ui_build_box_from_key(0, ui_key_zero()); + } + + //- rjf: build empty view + UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) + { + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_TagF("weak") + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + UI_PrefHeight(ui_em(3.f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(15.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("bad_pop") + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) + { + rd_cmd(RD_CmdKind_ClosePanel); + } + } + } + } + + //- rjf: build tab view + UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") + { + rd_view_ui(content_rect); + } + + //- rjf: pop interaction registers; commit if this is the selected view + RD_Regs *view_regs = rd_pop_regs(); + if(panel_tree.focused == panel) + { + MemoryCopyStruct(rd_regs(), view_regs); + } + } + + //////////////////////// + //- rjf: loading? -> fill loading overlay container + // + if(build_panel) + { + F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target); + if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); + } + } + + ////////////////////////// + //- rjf: take events to automatically start/end filtering, if applicable + // +#if 0 // TODO(rjf): @cfg + UI_Focus(UI_FocusKind_On) + { + RD_Cfg *view = selected_tab; + RD_ViewState *view_state = selected_tab_view_state; + RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); + if(ui_is_focus_active() && view_rule_info->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view_state->is_filtering) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->flags & UI_EventFlag_Paste) + { + ui_eat_event(evt); + rd_cmd(RD_CmdKind_Filter); + rd_cmd(RD_CmdKind_Paste); + } + else if(evt->string.size != 0 && evt->kind == UI_EventKind_Text) + { + ui_eat_event(evt); + rd_cmd(RD_CmdKind_Filter); + rd_cmd(RD_CmdKind_InsertText, .string = evt->string); + } + } + } + if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter && (view_state->filter_string_size != 0 || view_state->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_ClearFilter); + } + } +#endif + + ////////////////////////// + //- rjf: consume panel fallthrough interaction events + // + if(build_panel) + { + UI_Signal panel_sig = ui_signal_from_box(panel_box); + if(ui_pressed(panel_sig)) + { + rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); + } + if(ui_right_clicked(panel_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .view = panel->selected_tab->id, + .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), + .ui_key = panel_box->key, + .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), + .reg_slot = RD_RegSlot_View, + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + } + } + + ////////////////////////// + //- rjf: compute tab build tasks + // + typedef struct TabTask TabTask; + struct TabTask + { + TabTask *next; + RD_Cfg *tab; + DR_FStrList fstrs; + F32 tab_width; + }; + TabTask *first_tab_task = 0; + TabTask *last_tab_task = 0; + U64 tab_task_count = 0; + F32 tab_close_width_px = ui_top_font_size()*2.5f; + if(build_panel) + { + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) + { + RD_Cfg *tab = n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } - UI_Box *site_box = &ui_nil_box; - { - F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); - UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) - { - site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); - ui_signal_from_box(site_box); - } - UI_Box *site_box_viz = &ui_nil_box; - UI_GroupKey(key) - UI_Parent(site_box) UI_WidthFill UI_HeightFill - UI_Padding(ui_px(padding, 1.f)) - UI_Column - UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(axis2_flip(split_axis)); - site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawHotEffects, ui_key_zero()); - } - if(dir != Dir2_Invalid) - { - UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(split_axis); - UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); - UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") - { - if(split_side == Side_Min) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); - ui_spacer(ui_px(padding, 1.f)); - if(split_side == Side_Max) { ui_set_next_flags(UI_BoxFlag_DrawBackground); } - ui_build_box_from_key(UI_BoxFlag_DrawBorder, ui_key_zero()); - } - } - } - else - { - UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f)) - { - ui_set_next_child_layout_axis(split_axis); - UI_Box *row_or_column = ui_build_box_from_key(0, ui_key_zero()); - UI_Parent(row_or_column) UI_Padding(ui_px(padding, 1.f)) UI_TagF("drop_site") - { - ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - } - if(ui_key_match(site_box->key, ui_drop_hot_key()) && rd_drag_drop()) - { - if(dir != Dir2_Invalid) - { - rd_cmd(RD_CmdKind_SplitPanel, - .dst_panel = panel->cfg->id, - .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, - .dir2 = dir); - } - else - { - rd_cmd(RD_CmdKind_MoveTab, - .dst_panel = panel->cfg->id, - .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, - .prev_view = rd_cfg_list_last(&panel->tabs)->id); - } - } + TabTask *t = push_array(scratch.arena, TabTask, 1); + t->tab = tab; + t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); + t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + SLLQueuePush(first_tab_task, last_tab_task, t); + tab_task_count += 1; } - for(U64 idx = 0; idx < ArrayCount(sites); idx += 1) - { - B32 is_drop_hot = ui_key_match(ui_drop_hot_key(), sites[idx].key); - if(is_drop_hot) - { - Axis2 split_axis = axis2_from_dir2(sites[idx].split_dir); - Side split_side = side_from_dir2(sites[idx].split_dir); - Rng2F32 future_split_rect_target = panel_rect; - if(sites[idx].split_dir != Dir2_Invalid) - { - Vec2F32 panel_center = center_2f32(panel_rect); - future_split_rect_target.v[side_flip(split_side)].v[split_axis] = panel_center.v[split_axis]; - } - future_split_rect_target = pad_2f32(future_split_rect_target, -ui_top_font_size()*2.f); - Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); - Rng2F32 future_split_rect = - { - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), - }; - UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); - } - } - } - } - } - - ////////////////////////// - //- rjf: build catch-all panel drop-site - // - UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); - if(build_panel) UI_Rect(panel_rect) - { - UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); - ui_signal_from_box(catchall_drop_site); - } - - ////////////////////////// - //- rjf: build filtering box - // -#if 0 // TODO(rjf): @cfg - { - RD_Cfg *view = selected_tab; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); - RD_ViewState *view_state = rd_view_state_from_cfg(view); - UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = view->id) - { - if(view_state->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) - { - rd_cmd(RD_CmdKind_ApplyFilter); - } - if(view_state->is_filtering || selected_tab_is_filtering_t > 0.01f) - { - UI_Box *filter_box = &ui_nil_box; - UI_Rect(filter_rect) - { - ui_set_next_child_layout_axis(Axis2_X); - filter_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder, "filter_box_%p", view); - } - UI_Parent(filter_box) UI_WidthFill UI_HeightFill - { - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TagF("weak") - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - ui_label(str8_lit("Filter")); - } - ui_spacer(ui_em(0.5f, 1.f)); - RD_Font(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_Focus(view_state->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode), - 0, - 0, - &view_state->filter_cursor, - &view_state->filter_mark, - view_state->filter_buffer, - sizeof(view_state->filter_buffer), - &view_state->filter_string_size, - 0, - str8(view_state->filter_buffer, view_state->filter_string_size), - str8_lit("###filter_text_input")); - if(ui_pressed(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel); - } - } - } - } - } - } -#endif - - ////////////////////////// - //- rjf: panel not selected? -> darken - // - if(build_panel) if(panel != panel_tree.focused) - { - UI_Rect(content_rect) UI_TagF("inactive") - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - - ////////////////////////// - //- rjf: build panel container box - // - UI_Box *panel_box = &ui_nil_box; - if(build_panel) UI_Rect(content_rect) UI_ChildLayoutAxis(Axis2_Y) UI_CornerRadius(0) UI_Focus(UI_FocusKind_On) - { - UI_Key panel_key = ui_key_from_stringf(ui_key_zero(), "panel_box_%p", panel->cfg); - panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - UI_BoxFlag_Clip| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DisableFocusOverlay| - ((panel_tree.focused != panel)*UI_BoxFlag_DisableFocusBorder), - panel_key); - } - - ////////////////////////// - //- rjf: loading animation for stable view - // - UI_Box *loading_overlay_container = &ui_nil_box; - if(build_panel) UI_Parent(panel_box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - ////////////////////////// - //- rjf: build selected tab view - // - if(build_panel) - UI_Parent(panel_box) - UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - UI_WidthFill - { - //- rjf: push interaction registers, fill with per-view states - rd_push_regs(.panel = panel->cfg->id, - .view = selected_tab->id); - { - String8 view_expr = rd_expr_from_cfg(selected_tab); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - rd_regs()->file_path = view_file_path; } - //- rjf: build view container - UI_Box *view_container_box = &ui_nil_box; - UI_FixedWidth(dim_2f32(content_rect).x) - UI_FixedHeight(dim_2f32(content_rect).y) - UI_ChildLayoutAxis(Axis2_Y) + ////////////////////////// + //- rjf: build tab bar container + // + UI_Box *tab_bar_box = &ui_nil_box; + if(build_panel) UI_CornerRadius(0) UI_Rect(tab_bar_rect) { - view_container_box = ui_build_box_from_key(0, ui_key_zero()); + tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| + UI_BoxFlag_AllowOverflowY| + UI_BoxFlag_ViewClampX| + UI_BoxFlag_ViewScrollX| + UI_BoxFlag_Clickable, + "tab_bar_%p", panel->cfg); + if(panel->tab_side == Side_Max) + { + tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); + } + else + { + tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0; + } } - //- rjf: build empty view - UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) + ////////////////////////// + //- rjf: determine tab drop site + // + B32 tab_drop_is_active = rd_drag_is_active() && ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); + RD_Cfg *tab_drop_prev = &rd_nil_cfg; + if(build_panel) { - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_TagF("weak") - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + F32 best_prev_distance_px = 1000000.f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + F32 off = 0; + for(TabTask *task = &start_boundary_tab_task; task != 0; task = task->next) { - UI_PrefHeight(ui_em(3.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(15.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - UI_TagF("bad_pop") + off += task->tab_width; + Vec2F32 anchor_pt = v2f32(tab_bar_box->rect.x0 + off, tab_bar_box->rect.y1); + F32 distance = length_2f32(sub_2f32(ui_mouse(), anchor_pt)); + if(distance < best_prev_distance_px) { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Panel"))) - { - rd_cmd(RD_CmdKind_ClosePanel); - } + best_prev_distance_px = distance; + tab_drop_prev = task->tab; } } } - //- rjf: build tab view - UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") + ////////////////////////// + //- rjf: turn off drop visualization if this drag would be a no-op + // + if(tab_drop_is_active && rd_state->drag_drop_regs->panel == panel->cfg->id) { - rd_view_ui(content_rect); - } - - //- rjf: pop interaction registers; commit if this is the selected view - RD_Regs *view_regs = rd_pop_regs(); - if(panel_tree.focused == panel) - { - MemoryCopyStruct(rd_regs(), view_regs); - } - } - - //////////////////////// - //- rjf: loading? -> fill loading overlay container - // - if(build_panel) - { - F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target); - if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) - { - rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); - } - } - - ////////////////////////// - //- rjf: take events to automatically start/end filtering, if applicable - // -#if 0 // TODO(rjf): @cfg - UI_Focus(UI_FocusKind_On) - { - RD_Cfg *view = selected_tab; - RD_ViewState *view_state = selected_tab_view_state; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); - if(ui_is_focus_active() && view_rule_info->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view_state->is_filtering) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->flags & UI_EventFlag_Paste) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_Paste); - } - else if(evt->string.size != 0 && evt->kind == UI_EventKind_Text) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_InsertText, .string = evt->string); - } - } - } - if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter && (view_state->filter_string_size != 0 || view_state->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_ClearFilter); - } - } -#endif - - ////////////////////////// - //- rjf: consume panel fallthrough interaction events - // - if(build_panel) - { - UI_Signal panel_sig = ui_signal_from_box(panel_box); - if(ui_pressed(panel_sig)) - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); - } - if(ui_right_clicked(panel_sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .view = panel->selected_tab->id, - .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), - .ui_key = panel_box->key, - .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), - .reg_slot = RD_RegSlot_View, - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); - } - } - - ////////////////////////// - //- rjf: compute tab build tasks - // - typedef struct TabTask TabTask; - struct TabTask - { - TabTask *next; - RD_Cfg *tab; - DR_FStrList fstrs; - F32 tab_width; - }; - TabTask *first_tab_task = 0; - TabTask *last_tab_task = 0; - U64 tab_task_count = 0; - F32 tab_close_width_px = ui_top_font_size()*2.5f; - if(build_panel) - { - for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) - { - RD_Cfg *tab = n->v; - if(rd_cfg_is_project_filtered(tab)) - { - continue; - } - TabTask *t = push_array(scratch.arena, TabTask, 1); - t->tab = tab; - t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); - t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; - SLLQueuePush(first_tab_task, last_tab_task, t); - tab_task_count += 1; - } - } - - ////////////////////////// - //- rjf: build tab bar container - // - UI_Box *tab_bar_box = &ui_nil_box; - if(build_panel) UI_CornerRadius(0) UI_Rect(tab_bar_rect) - { - tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| - UI_BoxFlag_AllowOverflowY| - UI_BoxFlag_ViewClampX| - UI_BoxFlag_ViewScrollX| - UI_BoxFlag_Clickable, - "tab_bar_%p", panel->cfg); - if(panel->tab_side == Side_Max) - { - tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight); - } - else - { - tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0; - } - } - - ////////////////////////// - //- rjf: determine tab drop site - // - B32 tab_drop_is_active = rd_drag_is_active() && ui_key_match(ui_drop_hot_key(), catchall_drop_site_key); - RD_Cfg *tab_drop_prev = &rd_nil_cfg; - if(build_panel) - { - F32 best_prev_distance_px = 1000000.f; - TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; - F32 off = 0; - for(TabTask *task = &start_boundary_tab_task; task != 0; task = task->next) - { - off += task->tab_width; - Vec2F32 anchor_pt = v2f32(tab_bar_box->rect.x0 + off, tab_bar_box->rect.y1); - F32 distance = length_2f32(sub_2f32(ui_mouse(), anchor_pt)); - if(distance < best_prev_distance_px) - { - best_prev_distance_px = distance; - tab_drop_prev = task->tab; - } - } - } - - ////////////////////////// - //- rjf: turn off drop visualization if this drag would be a no-op - // - if(tab_drop_is_active && rd_state->drag_drop_regs->panel == panel->cfg->id) - { - TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; - if(tab_drop_prev->id == rd_state->drag_drop_regs->view) - { - tab_drop_is_active = 0; - } - if(tab_drop_is_active) for(TabTask *t = &start_boundary_tab_task; t != 0; t = t->next) - { - if(t->tab == tab_drop_prev && t->next != 0 && t->next->tab->id == rd_state->drag_drop_regs->view) + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + if(tab_drop_prev->id == rd_state->drag_drop_regs->view) { tab_drop_is_active = 0; - break; + } + if(tab_drop_is_active) for(TabTask *t = &start_boundary_tab_task; t != 0; t = t->next) + { + if(t->tab == tab_drop_prev && t->next != 0 && t->next->tab->id == rd_state->drag_drop_regs->view) + { + tab_drop_is_active = 0; + break; + } } } - } - - ////////////////////////// - //- rjf: build tab bar contents - // - if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) UI_TagF("tab") - { - F32 corner_radius = ui_top_font_size()*0.6f; - TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) - for(TabTask *tab_task = &start_boundary_tab_task; tab_task != 0; tab_task = tab_task->next) + + ////////////////////////// + //- rjf: build tab bar contents + // + if(build_panel) UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0)) UI_TagF("tab") { - RD_Cfg *tab = tab_task->tab; - - //- rjf: build tab - DR_FStrList tab_fstrs = tab_task->fstrs; - F32 tab_width_px = tab_task->tab_width; - if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) + F32 corner_radius = ui_top_font_size()*0.6f; + TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg}; + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius) + for(TabTask *tab_task = &start_boundary_tab_task; tab_task != 0; tab_task = tab_task->next) { - // rjf: gather info for this tab - B32 tab_is_selected = (tab == panel->selected_tab); + RD_Cfg *tab = tab_task->tab; - // rjf: begin vertical region for this tab - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_pref_width(ui_px(tab_width_px, 1)); - UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); - - // rjf: choose palette - B32 omit_name = 0; - if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) + //- rjf: build tab + DR_FStrList tab_fstrs = tab_task->fstrs; + F32 tab_width_px = tab_task->tab_width; + if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) { - omit_name = 1; - } - - // rjf: build tab container box - UI_Parent(tab_column_box) - UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - UI_TagF(omit_name ? "hollow" : "") - UI_TagF(!tab_is_selected ? "inactive" : "") - { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - (UI_BoxFlag_DrawDropShadow*tab_is_selected)| - UI_BoxFlag_Clickable, - "tab_%p", tab); + // rjf: gather info for this tab + B32 tab_is_selected = (tab == panel->selected_tab); - // rjf: build tab contents - if(!omit_name) UI_Parent(tab_box) + // rjf: begin vertical region for this tab + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(tab_width_px, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: choose palette + B32 omit_name = 0; + if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - UI_WidthFill UI_Row + omit_name = 1; + } + + // rjf: build tab container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + UI_TagF(omit_name ? "hollow" : "") + UI_TagF(!tab_is_selected ? "inactive" : "") + { + if(panel->tab_side == Side_Max) { - ui_spacer(ui_em(0.5f, 1.f)); - UI_PrefWidth(ui_text_dim(10, 0)) + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + (UI_BoxFlag_DrawDropShadow*tab_is_selected)| + UI_BoxFlag_Clickable, + "tab_%p", tab); + + // rjf: build tab contents + if(!omit_name) UI_Parent(tab_box) + { + UI_WidthFill UI_Row { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(name_box, &tab_fstrs); + ui_spacer(ui_em(0.5f, 1.f)); + UI_PrefWidth(ui_text_dim(10, 0)) + { + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &tab_fstrs); + } + } + UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) + UI_TagF("weak") + UI_CornerRadius00(0) + UI_CornerRadius01(0) + { + UI_Palette *palette = ui_build_palette(ui_top_palette()); + palette->background = v4f32(0, 0, 0, 0); + ui_set_next_palette(palette); + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects, + "%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); + UI_Signal sig = ui_signal_from_box(close_box); + if(ui_clicked(sig) || ui_middle_clicked(sig)) + { + rd_cmd(RD_CmdKind_CloseTab); + } } } - UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_TagF("weak") - UI_CornerRadius00(0) - UI_CornerRadius01(0) + + // rjf: consume events for tab clicking { - UI_Palette *palette = ui_build_palette(ui_top_palette()); - palette->background = v4f32(0, 0, 0, 0); - ui_set_next_palette(palette); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects, - "%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab); - UI_Signal sig = ui_signal_from_box(close_box); - if(ui_clicked(sig) || ui_middle_clicked(sig)) + UI_Signal sig = ui_signal_from_box(tab_box); + if(ui_pressed(sig)) + { + rd_cmd(RD_CmdKind_FocusTab); + rd_cmd(RD_CmdKind_FocusPanel); + } + else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) + { + rd_drag_begin(RD_RegSlot_View); + } + else if(ui_right_clicked(sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .reg_slot = RD_RegSlot_View, + .ui_key = sig.box->key, + .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), + .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + } + else if(ui_middle_clicked(sig)) { rd_cmd(RD_CmdKind_CloseTab); } } } - // rjf: consume events for tab clicking + // rjf: space for next tab { - UI_Signal sig = ui_signal_from_box(tab_box); - if(ui_pressed(sig)) - { - rd_cmd(RD_CmdKind_FocusTab); - rd_cmd(RD_CmdKind_FocusPanel); - } - else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f) - { - rd_drag_begin(RD_RegSlot_View); - } - else if(ui_right_clicked(sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .reg_slot = RD_RegSlot_View, - .ui_key = sig.box->key, - .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); - } - else if(ui_middle_clicked(sig)) - { - rd_cmd(RD_CmdKind_CloseTab); - } + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); } } - // rjf: space for next tab + //- rjf: if this is the currently active drop site's previous tab, then build empty space + // to visualize where tab will be moved once dropped + if(tab_drop_is_active && + rd_drag_is_active() && + rd_state->drag_drop_regs_slot == RD_RegSlot_View && + tab == tab_drop_prev) { - ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); + // rjf: begin vertical region for this spot + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_pref_width(ui_px(ui_top_font_size()*4.f, 1)); + UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); + + // rjf: build spot container box + UI_Parent(tab_column_box) + UI_PrefHeight(ui_px(tab_bar_vheight, 1)) + UI_TagF("hollow") + { + if(panel->tab_side == Side_Max) + { + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_group_key(catchall_drop_site_key); + UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_Clickable, + ui_key_zero()); + } + + // rjf: space for next tab + { + ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); + } } } - //- rjf: if this is the currently active drop site's previous tab, then build empty space - // to visualize where tab will be moved once dropped - if(tab_drop_is_active && - rd_drag_is_active() && - rd_state->drag_drop_regs_slot == RD_RegSlot_View && - tab == tab_drop_prev) + // rjf: build add-new-tab button + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) + UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + UI_Column { - // rjf: begin vertical region for this spot - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_pref_width(ui_px(ui_top_font_size()*4.f, 1)); - UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab); - - // rjf: build spot container box - UI_Parent(tab_column_box) - UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - UI_TagF("hollow") + if(panel->tab_side == Side_Max) { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_group_key(catchall_drop_site_key); - UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_Clickable, - ui_key_zero()); + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); } - - // rjf: space for next tab + else { - ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f)); + ui_spacer(ui_px(1.f, 1.f)); + } + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_TagF("implicit") + UI_TagF("weak") + UI_HoverCursor(OS_Cursor_HandPoint) + { + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel->cfg); + UI_Signal sig = ui_signal_from_box(add_new_box); + if(ui_clicked(sig)) + { + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + } } } + + // rjf: interact with tab bar + ui_signal_from_box(tab_bar_box); } - // rjf: build add-new-tab button - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) - UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column + ////////////////////////// + //- rjf: accept tab drops + // + if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - if(panel->tab_side == Side_Max) - { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_TagF("implicit") - UI_TagF("weak") - UI_HoverCursor(OS_Cursor_HandPoint) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel->cfg); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); - } - } + rd_cmd(RD_CmdKind_MoveTab, + .dst_panel = panel->cfg->id, + .panel = rd_state->drag_drop_regs->panel, + .view = rd_state->drag_drop_regs->view, + .prev_view = tab_drop_prev->id); } - // rjf: interact with tab bar - ui_signal_from_box(tab_bar_box); - } - - ////////////////////////// - //- rjf: accept tab drops - // - if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) - { - rd_cmd(RD_CmdKind_MoveTab, - .dst_panel = panel->cfg->id, - .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, - .prev_view = tab_drop_prev->id); - } - - ////////////////////////// - //- rjf: accept file drops - // - { - for(UI_Event *evt = 0; ui_next_event(&evt);) + ////////////////////////// + //- rjf: accept file drops + // { - if(evt->kind == UI_EventKind_FileDrop && contains_2f32(content_rect, evt->pos)) + for(UI_Event *evt = 0; ui_next_event(&evt);) { - B32 need_drop_completion = 0; - arena_clear(ws->drop_completion_arena); - MemoryZeroStruct(&ws->drop_completion_paths); - for(String8Node *n = evt->paths.first; n != 0; n = n->next) + if(evt->kind == UI_EventKind_FileDrop && contains_2f32(content_rect, evt->pos)) { - Temp scratch = scratch_begin(0, 0); - String8 path = path_normalized_from_string(scratch.arena, n->string); - if(str8_match(str8_skip_last_dot(path), str8_lit("exe"), StringMatchFlag_CaseInsensitive)) + B32 need_drop_completion = 0; + arena_clear(ws->drop_completion_arena); + MemoryZeroStruct(&ws->drop_completion_paths); + for(String8Node *n = evt->paths.first; n != 0; n = n->next) { - str8_list_push(ws->drop_completion_arena, &ws->drop_completion_paths, push_str8_copy(ws->drop_completion_arena, path)); - need_drop_completion = 1; + Temp scratch = scratch_begin(0, 0); + String8 path = path_normalized_from_string(scratch.arena, n->string); + if(str8_match(str8_skip_last_dot(path), str8_lit("exe"), StringMatchFlag_CaseInsensitive)) + { + str8_list_push(ws->drop_completion_arena, &ws->drop_completion_paths, push_str8_copy(ws->drop_completion_arena, path)); + need_drop_completion = 1; + } + else + { + rd_cmd(RD_CmdKind_Open, .file_path = path); + } + scratch_end(scratch); } - else + if(need_drop_completion) { - rd_cmd(RD_CmdKind_Open, .file_path = path); + ui_ctx_menu_open(rd_state->drop_completion_key, ui_key_zero(), evt->pos); } - scratch_end(scratch); + ui_eat_event(evt); } - if(need_drop_completion) - { - ui_ctx_menu_open(rd_state->drop_completion_key, ui_key_zero(), evt->pos); - } - ui_eat_event(evt); } } } @@ -10794,14 +10797,12 @@ rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) // more faded/smaller, but only after a primary title is pushed, // which could be caused by many different potential parts of a cfg. // - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; - B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = secondary_color; params.size = ui_top_font_size()*0.95f;} + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; //- rjf: push icon - if(info->icon_kind != RD_IconKind_Null) + if(info->icon_kind != RD_IconKind_Null) UI_Tag(str8_lit("weak")) { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -10816,8 +10817,6 @@ rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) { dr_fstrs_push_new(arena, &result, ¶ms, code_name, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); } - -#undef start_secondary } return result; } From 9805f8cd203fc0880d751f4b0055fecefc037a58 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 08:37:34 -0800 Subject: [PATCH 144/755] begin work on lister-flavored watch windows; begin on using that for the query ui --- src/eval/eval_ir.c | 6 +- src/os/core/win32/os_core_win32.c | 21 + src/raddbg/raddbg_core.c | 659 +++++------------------------- src/raddbg/raddbg_core.h | 3 - src/raddbg/raddbg_views.c | 28 +- src/raddbg/raddbg_widgets.c | 567 +++++++++++++++++++++++++ src/raddbg/raddbg_widgets.h | 8 + 7 files changed, 711 insertions(+), 581 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 68eaf957..54c09a1f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -169,7 +169,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) if(0 <= idx && idx < accel->folders.count) { String8 folder_name = accel->folders.v[idx - 0]; - String8 folder_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, folder_name); + String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); expr->space = e_space_make(E_SpaceKind_FileSystem); @@ -179,7 +179,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) { String8 file_name = accel->files.v[idx - accel->folders.count]; - String8 file_path = push_str8f(scratch.arena, "%S/%S", accel->folder_path, file_name); + String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); expr->space = e_space_make(E_SpaceKind_FileSystem); @@ -2253,7 +2253,7 @@ E_IRGEN_FUNCTION_DEF(default) Temp scratch = scratch_begin(&arena, 1); String8 file_path = path_normalized_from_string(scratch.arena, expr->string); FileProperties props = os_properties_from_file_path(file_path); - if(props.flags & FilePropertyFlag_IsFolder) + if(props.flags & FilePropertyFlag_IsFolder || props.modified == 0) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 6a0e0281..f6ab35c3 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -547,6 +547,27 @@ os_properties_from_file_path(String8 path) os_w32_dense_time_from_file_time(&props.modified, &find_data.ftLastWriteTime); props.flags = os_w32_file_property_flags_from_dwFileAttributes(find_data.dwFileAttributes); } + else + { + Temp scratch = scratch_begin(0, 0); + WCHAR buffer[512] = {0}; + DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer); + U64 last_slash_pos = str8_find_needle(path, 0, str8_lit("/"), StringMatchFlag_SlashInsensitive); + String8 path_trimmed = str8_prefix(path, last_slash_pos); + for(U64 off = 0; off < (U64)length;) + { + String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off); + off += next_drive_string_16.size+1; + String8 next_drive_string = str8_from_16(scratch.arena, next_drive_string_16); + next_drive_string = str8_chop_last_slash(next_drive_string); + if(str8_match(path_trimmed, next_drive_string, StringMatchFlag_CaseInsensitive)) + { + props.flags |= FilePropertyFlag_IsFolder; + break; + } + } + scratch_end(scratch); + } FindClose(handle); scratch_end(scratch); return props; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7ece409f..32dda593 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2090,362 +2090,7 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) return target; } -internal DR_FStrList -rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) -{ - DR_FStrList result = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: unpack config - B32 is_disabled = rd_disabled_from_cfg(cfg); - RD_Location loc = rd_location_from_cfg(cfg); - D_Target target = rd_target_from_cfg(scratch.arena, cfg); - String8 label_string = rd_label_from_cfg(cfg); - String8 expr_string = rd_expr_from_cfg(cfg); - String8 collection_name = {0}; - String8 file_path = {0}; - Vec4F32 rgba = rd_color_from_cfg(cfg); - if(rgba.w == 0) - { - rgba = ui_color_from_name(str8_lit("text")); - } - Vec4F32 rgba_secondary = rgba; - UI_TagF("weak") - { - rgba_secondary = ui_color_from_name(str8_lit("text")); - } - RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); - B32 is_from_command_line = 0; - { - RD_Cfg *cmd_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); - for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) - { - if(p == cmd_line_root) - { - is_from_command_line = 1; - break; - } - } - } - B32 is_within_window = 0; - { - for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) - { - if(str8_match(p->string, str8_lit("window"), 0)) - { - is_within_window = 1; - break; - } - } - } - if(expr_string.size != 0) - { - String8 query_name = rd_query_from_eval_string(arena, expr_string); - if(query_name.size != 0 && !str8_match(query_name, str8_lit("watches"), 0)) - { - String8 query_code_name = query_name; - String8 query_display_name = rd_display_from_code_name(query_code_name); - collection_name = query_display_name; - if(query_display_name.size == 0) - { - query_code_name = rd_singular_from_code_name_plural(query_name); - collection_name = rd_display_plural_from_code_name(query_code_name); - } - RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); - if(query_icon_kind != RD_IconKind_Null) - { - icon_kind = query_icon_kind; - } - } - else - { - file_path = rd_file_path_from_eval_string(arena, expr_string); - if(file_path.size != 0) - { - icon_kind = RD_IconKind_FileOutline; - } - } - } - - //- rjf: set up color/size for all parts of the title - // - // the "running" part implies that it changes as things are added - - // so if a primary title is pushed, we can make the rest of the title - // more faded/smaller, but only after a primary title is pushed, - // which could be caused by many different potential parts of a cfg. - // - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, ui_top_font_size()}; - B32 running_is_secondary = 0; -#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = rgba_secondary; params.size = ui_top_font_size()*0.95f;} - - //- rjf: push icon - if(icon_kind != RD_IconKind_Null) - { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push warning icon for command-line entities - if(is_from_command_line) - { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push view title, if from window, and no file path - if(is_within_window && file_path.size == 0 && collection_name.size == 0) - { - String8 view_display_name = rd_display_from_code_name(cfg->string); - if(view_display_name.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, view_display_name); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - } - - //- rjf: push label - if(label_string.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: push collection name - if(collection_name.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, collection_name); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: query is file path - do specific file name strings - else if(file_path.size != 0) - { - // rjf: compute disambiguated file name - String8List qualifiers = {0}; - String8 file_name = str8_skip_last_slash(file_path); - if(rd_state->ambiguous_path_slots_count != 0) - { - U64 hash = d_hash_from_string__case_insensitive(file_name); - U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; - RD_AmbiguousPathNode *node = 0; - { - for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; - n != 0; - n = n->next) - { - if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) - { - node = n; - break; - } - } - } - if(node != 0 && node->paths.node_count > 1) - { - // rjf: get all colliding paths - String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); - - // rjf: get all reversed path parts for each collision - String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); - for EachIndex(idx, collisions.count) - { - String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); - } - } - - // rjf: get the search path & its reversed parts - String8List parts = str8_split_path(scratch.arena, file_path); - String8List parts_reversed = {0}; - for(String8Node *n = parts.first; n != 0; n = n->next) - { - str8_list_push_front(scratch.arena, &parts_reversed, n->string); - } - - // rjf: iterate all collision part reversed lists, in lock-step with - // search path; disqualify until we only have one path remaining; gather - // qualifiers - { - U64 num_collisions_left = collisions.count; - String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); - for EachIndex(idx, collisions.count) - { - collision_nodes[idx] = collision_parts_reversed[idx].first; - } - for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) - { - B32 part_is_qualifier = 0; - for EachIndex(idx, collisions.count) - { - if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) - { - collision_nodes[idx] = 0; - num_collisions_left -= 1; - part_is_qualifier = 1; - } - else if(collision_nodes[idx] != 0) - { - collision_nodes[idx] = collision_nodes[idx]->next; - } - } - if(part_is_qualifier) - { - str8_list_push_front(scratch.arena, &qualifiers, n->string); - } - } - } - } - } - - // rjf: push qualifiers - for(String8Node *n = qualifiers.first; n != 0; n = n->next) - { - String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_top_palette()->text_weak); - } - - // rjf: push file name - dr_fstrs_push_new(arena, &result, ¶ms, push_str8_copy(arena, str8_skip_last_slash(file_path))); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: cfg has expression attached -> use that - else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) - { - dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: push text location - if(loc.file_path.size != 0) - { - String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", str8_skip_last_slash(loc.file_path), loc.pt.line, loc.pt.column); - dr_fstrs_push_new(arena, &result, ¶ms, location_string); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: push target executable name - if(target.exe.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(target.exe)); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - start_secondary(); - } - - //- rjf: push target arguments - if(target.args.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, target.args); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push conditions - { - String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; - if(condition.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); - RD_Font(RD_FontSlot_Code) - { - DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); - dr_fstrs_concat_in_place(&result, &fstrs); - } - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - } - - //- rjf: push disabled marker - if(is_disabled) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Disabled)")); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push hit count - { - String8 hit_count_value_string = rd_cfg_child_from_string(cfg, str8_lit("hit_count"))->first->string; - U64 hit_count = 0; - if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count)) - { - String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); - dr_fstrs_push_new(arena, &result, ¶ms, hit_count_text); - } - } - - //- rjf: special case: auto view rule - if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) - { - String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; - String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; - Vec4F32 src_color = rgba; - Vec4F32 dst_color = rgba; - DR_FStrList src_fstrs = {0}; - DR_FStrList dst_fstrs = {0}; - if(src_string.size == 0) - { - src_string = str8_lit("(type)"); - src_color = ui_top_palette()->text_weak; - dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); - } - else RD_Font(RD_FontSlot_Code) - { - src_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, src_color, src_string); - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(view rule)"); - dst_color = ui_top_palette()->text_weak; - dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); - } - else RD_Font(RD_FontSlot_Code) - { - dst_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, dst_color, dst_string); - } - dr_fstrs_concat_in_place(&result, &src_fstrs); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_concat_in_place(&result, &dst_fstrs); - } - - //- rjf: special case: file path maps - if(str8_match(cfg->string, str8_lit("file_path_map"), 0)) - { - String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; - String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; - Vec4F32 src_color = rgba; - Vec4F32 dst_color = rgba; - if(src_string.size == 0) - { - src_string = str8_lit("(source path)"); - src_color = ui_top_palette()->text_weak; - } - if(dst_string.size == 0) - { - dst_string = str8_lit("(destination path)"); - dst_color = ui_top_palette()->text_weak; - } - dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); - } - -#undef start_secondary - scratch_end(scratch); - } - return result; -} + internal MD_Node * rd_schema_from_name(Arena *arena, String8 name) @@ -2733,145 +2378,6 @@ rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity) return string; } -internal DR_FStrList -rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras) -{ - DR_FStrList result = {0}; - - //- rjf: unpack entity info - F32 extras_size = ui_top_font_size()*0.95f; - Vec4F32 color = rd_color_from_ctrl_entity(entity); - if(color.w == 0) - { - color = ui_top_palette()->text; - } - Vec4F32 secondary_color = ui_top_palette()->text_weak; - String8 name = rd_name_from_ctrl_entity(arena, entity); - RD_IconKind icon_kind = RD_IconKind_Null; - B32 name_is_code = 0; - switch(entity->kind) - { - default:{}break; - case CTRL_EntityKind_Machine: {icon_kind = RD_IconKind_Machine;}break; - case CTRL_EntityKind_Process: {icon_kind = RD_IconKind_Threads;}break; - case CTRL_EntityKind_Thread: {icon_kind = RD_IconKind_Thread; name_is_code = 1;}break; - case CTRL_EntityKind_Module: {icon_kind = RD_IconKind_Module;}break; - } - - //- rjf: set up drawing params - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), color, ui_top_font_size()}; - - //- rjf: push icon - if(icon_kind != RD_IconKind_Null) - { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push frozen icon, if frozen - if((entity->kind == CTRL_EntityKind_Machine || - entity->kind == CTRL_EntityKind_Process || - entity->kind == CTRL_EntityKind_Thread) && - ctrl_entity_tree_is_frozen(entity)) - { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->background_bad); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push containing process prefix - if(entity->kind == CTRL_EntityKind_Thread || - entity->kind == CTRL_EntityKind_Module) - { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - if(processes.count > 1) - { - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - String8 process_name = rd_name_from_ctrl_entity(arena, process); - Vec4F32 process_color = rd_color_from_ctrl_entity(process); - if(process_color.w == 0) - { - process_color = color; - } - if(process_name.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.9f); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); - } - } - } - - //- rjf: push name - dr_fstrs_push_new(arena, &result, ¶ms, name, - .font = rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), - .raster_flags = rd_raster_flags_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), - .color = color); - - //- rjf: push PID - if(entity->kind == CTRL_EntityKind_Process) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.85f); - } - - //- rjf: threads get callstack extras - if(entity->kind == CTRL_EntityKind_Thread && include_extras) - { - Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - Arch arch = entity->arch; - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1) - { - CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx]; - U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - if(rdi != &di_rdi_parsed_nil) - { - RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - name = push_str8_copy(arena, name); - if(name.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color); - if(idx+1 < unwind.frames.count) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); - if(idx+1 == limit) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("..."), .color = secondary_color, .size = extras_size); - } - } - } - } - } - di_scope_close(di_scope); - } - - //- rjf: modules get debug info status extras - if(entity->kind == CTRL_EntityKind_Module && include_extras) - { - DI_Scope *di_scope = di_scope_open(); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - if(rdi->raw_data_size == 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Symbols not found)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color); - } - di_scope_close(di_scope); - } - - return result; -} - //////////////////////////////// //~ rjf: Evaluation Spaces @@ -4503,8 +4009,9 @@ rd_window_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); B32 popup_is_open = (rd_state->popup_active); - B32 query_is_open = (ws->top_query_lister != 0); + B32 query_is_open = (rd_cfg_child_from_string(window, str8_lit("query")) != &rd_nil_cfg); B32 hover_eval_is_open = (!popup_is_open && + !query_is_open && ws->hover_eval_string.size != 0 && ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && rd_state->frame_index-ws->hover_eval_last_frame_idx < 20); @@ -5173,8 +4680,10 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } //////////////////////////// - //- rjf: do query lister stack controls + //- rjf: build listers // +#if 0 // TODO(rjf): @cfg + //- rjf: do query lister stack controls if(ws->top_query_lister != 0) { if(ui_slot_press(UI_EventActionSlot_Cancel)) @@ -5192,10 +4701,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The scratch_end(scratch); } } - - //////////////////////////// - //- rjf: build listers - // for(ListerTask *task = first_lister_task; task != 0; task = task->next) { DI_Scope *di_scope = di_scope_open(); @@ -5490,6 +4995,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The di_scope_close(di_scope); } +#endif #if 0 // TODO(rjf): @cfg_lister //////////////////////////// @@ -6115,6 +5621,92 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } } + //////////////////////////// + //- rjf: build query + // + { + RD_Cfg *query = rd_cfg_child_from_string(window, str8_lit("query")); + if(query != &rd_nil_cfg) + { + //- rjf: unpack query parameters + RD_Cfg *root = query; + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + rd_cfg_new(view, str8_lit("lister")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + String8 query_expression = str8_lit("query:procedures"); + rd_cfg_new_replace(expr, query_expression); + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + + //- rjf: build + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), query_eval.exprs); + F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); + F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + Rng2F32 query_rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); + + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + UI_Focus(UI_FocusKind_On) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + { + //- rjf: build top-level container + UI_Box *container = &ui_nil_box; + UI_Rect(query_rect) + UI_Squish(0.25f-0.25f*query_open_t) + UI_Transparency(1.f-query_open_t) + UI_ChildLayoutAxis(Axis2_Y) + { + container = ui_build_box_from_string(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow, + str8_lit("query_container")); + } + + //- rjf: fill container + UI_Parent(container) UI_Focus(UI_FocusKind_Null) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(view_contents_container->rect); + } + } + } + } + + //- rjf: do interactions + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + if(ui_slot_press(UI_EventActionSlot_Accept)) + { + } + + //- rjf: build darkening rectangle over rest of screen + UI_Rect(window_rect) UI_TagF("inactive") + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + //////////////////////////// //- rjf: top bar // @@ -6820,7 +6412,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: close dropdown UI_Key close_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###close_ctx_menu"); - UI_CtxMenu(close_ctx_menu_key) + UI_CtxMenu(close_ctx_menu_key) UI_TagF("implicit") { if(ui_clicked(rd_icon_buttonf(RD_IconKind_Window, 0, "Close Window"))) { @@ -10783,44 +10375,6 @@ rd_vocab_info_from_code_name_plural(String8 code_name_plural) return result; } -internal DR_FStrList -rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) -{ - DR_FStrList result = {0}; - { - RD_VocabInfo *info = rd_vocab_info_from_code_name(code_name); - - //- rjf: set up color/size for all parts of the title - // - // the "running" part implies that it changes as things are added - - // so if a primary title is pushed, we can make the rest of the title - // more faded/smaller, but only after a primary title is pushed, - // which could be caused by many different potential parts of a cfg. - // - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - - //- rjf: push icon - if(info->icon_kind != RD_IconKind_Null) UI_Tag(str8_lit("weak")) - { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - } - - //- rjf: push display name - if(info->display_name.size != 0) - { - dr_fstrs_push_new(arena, &result, ¶ms, info->display_name); - } - - //- rjf: push code name as a fallback - else - { - dr_fstrs_push_new(arena, &result, ¶ms, code_name, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); - } - } - return result; -} - //////////////////////////////// //~ rjf: Continuous Frame Requests @@ -14704,19 +14258,10 @@ Z(getting_started) //- rjf: query stack case RD_CmdKind_PushQuery: { - RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - if(ws != &rd_nil_window_state) - { - Arena *arena = arena_alloc(); - RD_Lister *lister = push_array(arena, RD_Lister, 1); - lister->arena = arena; - lister->regs = rd_regs_copy(lister->arena, rd_regs()); - lister->input_string_size = Min(rd_regs()->string.size, sizeof(lister->input_buffer)); - lister->input_cursor = lister->input_mark = txt_pt(1, lister->input_string_size+1); - MemoryCopy(lister->input_buffer, rd_regs()->string.str, lister->input_string_size); - SLLStackPush(ws->top_query_lister, lister); - } + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_Cfg *current_query = rd_cfg_child_from_string(window, str8_lit("query")); + rd_cfg_release(current_query); + RD_Cfg *new_query = rd_cfg_new(window, str8_lit("query")); }break; case RD_CmdKind_CompleteQuery: { @@ -14767,13 +14312,7 @@ Z(getting_started) case RD_CmdKind_CancelQuery: { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window); - RD_Lister *top_lister = ws->top_query_lister; - if(top_lister != 0) - { - SLLStackPop(ws->top_query_lister); - arena_release(top_lister->arena); - } + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("query"))); }break; //- rjf: developer commands diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 202ea108..10f2d07a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -998,7 +998,6 @@ internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); -internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg); internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); @@ -1019,7 +1018,6 @@ internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); internal Vec4F32 rd_color_from_ctrl_entity(CTRL_Entity *entity); internal String8 rd_name_from_ctrl_entity(Arena *arena, CTRL_Entity *entity); -internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras); //////////////////////////////// //~ rjf: Evaluation Spaces @@ -1183,7 +1181,6 @@ internal RD_VocabInfo *rd_vocab_info_from_code_name_plural(String8 code_name_plu #define rd_display_plural_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->display_name_plural) #define rd_icon_kind_from_code_name(code_name) (rd_vocab_info_from_code_name(code_name)->icon_kind) #define rd_singular_from_code_name_plural(code_name_plural) (rd_vocab_info_from_code_name_plural(code_name_plural)->code_name) -internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name); //////////////////////////////// //~ rjf: Continuous Frame Requests diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index cef5752f..a1fee200 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1030,6 +1030,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} + // rjf: lister rows + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + } + // rjf: top-level cfg rows else if(is_top_level && evalled_cfg != &rd_nil_cfg) { @@ -1116,16 +1122,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; E_Type *type = e_type_from_key__cached(info.eval.type_key); String8 file_path = e_string_from_id(info.eval.value.u64); - String8 file_name = str8_skip_last_slash(file_path); + DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); if(str8_match(type->name, str8_lit("folder"), 0)) { - DR_FStrList fstrs = {0}; - if(file_name.size) - { - dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FolderClosedFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); - } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f, @@ -1139,13 +1138,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - DR_FStrList fstrs = {0}; - if(file_name.size) - { - dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_FileOutline], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); - } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .default_pct = 0.35f, @@ -1435,6 +1427,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; result.cmd_name = cmd_name; } + else if(result.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } }break; case RD_WatchCellKind_Eval: { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0f6376d3..0088425b 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1,6 +1,573 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: UI Widgets: Fancy Title Strings + +internal DR_FStrList +rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) +{ + DR_FStrList result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: unpack config + B32 is_disabled = rd_disabled_from_cfg(cfg); + RD_Location loc = rd_location_from_cfg(cfg); + D_Target target = rd_target_from_cfg(scratch.arena, cfg); + String8 label_string = rd_label_from_cfg(cfg); + String8 expr_string = rd_expr_from_cfg(cfg); + String8 collection_name = {0}; + String8 file_path = {0}; + Vec4F32 rgba = rd_color_from_cfg(cfg); + if(rgba.w == 0) + { + rgba = ui_color_from_name(str8_lit("text")); + } + Vec4F32 rgba_secondary = rgba; + UI_TagF("weak") + { + rgba_secondary = ui_color_from_name(str8_lit("text")); + } + RD_IconKind icon_kind = rd_icon_kind_from_code_name(cfg->string); + B32 is_from_command_line = 0; + { + RD_Cfg *cmd_line_root = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(p == cmd_line_root) + { + is_from_command_line = 1; + break; + } + } + } + B32 is_within_window = 0; + { + for(RD_Cfg *p = cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("window"), 0)) + { + is_within_window = 1; + break; + } + } + } + if(expr_string.size != 0) + { + String8 query_name = rd_query_from_eval_string(arena, expr_string); + if(query_name.size != 0 && !str8_match(query_name, str8_lit("watches"), 0)) + { + String8 query_code_name = query_name; + String8 query_display_name = rd_display_from_code_name(query_code_name); + collection_name = query_display_name; + if(query_display_name.size == 0) + { + query_code_name = rd_singular_from_code_name_plural(query_name); + collection_name = rd_display_plural_from_code_name(query_code_name); + } + RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); + if(query_icon_kind != RD_IconKind_Null) + { + icon_kind = query_icon_kind; + } + } + else + { + file_path = rd_file_path_from_eval_string(arena, expr_string); + if(file_path.size != 0) + { + icon_kind = RD_IconKind_FileOutline; + } + } + } + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), rgba, ui_top_font_size()}; + B32 running_is_secondary = 0; +#define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = rgba_secondary; params.size = ui_top_font_size()*0.95f;} + + //- rjf: push icon + if(icon_kind != RD_IconKind_Null) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push warning icon for command-line entities + if(is_from_command_line) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Info], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push view title, if from window, and no file path + if(is_within_window && file_path.size == 0 && collection_name.size == 0) + { + String8 view_display_name = rd_display_from_code_name(cfg->string); + if(view_display_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, view_display_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + } + + //- rjf: push label + if(label_string.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, label_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push collection name + if(collection_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, collection_name); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: query is file path - do specific file name strings + else if(file_path.size != 0) + { + // rjf: compute disambiguated file name + String8List qualifiers = {0}; + String8 file_name = str8_skip_last_slash(file_path); + if(rd_state->ambiguous_path_slots_count != 0) + { + U64 hash = d_hash_from_string__case_insensitive(file_name); + U64 slot_idx = hash%rd_state->ambiguous_path_slots_count; + RD_AmbiguousPathNode *node = 0; + { + for(RD_AmbiguousPathNode *n = rd_state->ambiguous_path_slots[slot_idx]; + n != 0; + n = n->next) + { + if(str8_match(n->name, file_name, StringMatchFlag_CaseInsensitive)) + { + node = n; + break; + } + } + } + if(node != 0 && node->paths.node_count > 1) + { + // rjf: get all colliding paths + String8Array collisions = str8_array_from_list(scratch.arena, &node->paths); + + // rjf: get all reversed path parts for each collision + String8List *collision_parts_reversed = push_array(scratch.arena, String8List, collisions.count); + for EachIndex(idx, collisions.count) + { + String8List parts = str8_split_path(scratch.arena, collisions.v[idx]); + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &collision_parts_reversed[idx], n->string); + } + } + + // rjf: get the search path & its reversed parts + String8List parts = str8_split_path(scratch.arena, file_path); + String8List parts_reversed = {0}; + for(String8Node *n = parts.first; n != 0; n = n->next) + { + str8_list_push_front(scratch.arena, &parts_reversed, n->string); + } + + // rjf: iterate all collision part reversed lists, in lock-step with + // search path; disqualify until we only have one path remaining; gather + // qualifiers + { + U64 num_collisions_left = collisions.count; + String8Node **collision_nodes = push_array(scratch.arena, String8Node *, collisions.count); + for EachIndex(idx, collisions.count) + { + collision_nodes[idx] = collision_parts_reversed[idx].first; + } + for(String8Node *n = parts_reversed.first; num_collisions_left > 1 && n != 0; n = n->next) + { + B32 part_is_qualifier = 0; + for EachIndex(idx, collisions.count) + { + if(collision_nodes[idx] != 0 && !str8_match(collision_nodes[idx]->string, n->string, StringMatchFlag_CaseInsensitive)) + { + collision_nodes[idx] = 0; + num_collisions_left -= 1; + part_is_qualifier = 1; + } + else if(collision_nodes[idx] != 0) + { + collision_nodes[idx] = collision_nodes[idx]->next; + } + } + if(part_is_qualifier) + { + str8_list_push_front(scratch.arena, &qualifiers, n->string); + } + } + } + } + } + + // rjf: push qualifiers + for(String8Node *n = qualifiers.first; n != 0; n = n->next) + { + String8 string = push_str8f(arena, "<%S> ", n->string); + dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_top_palette()->text_weak); + } + + // rjf: push file name + dr_fstrs_push_new(arena, &result, ¶ms, push_str8_copy(arena, str8_skip_last_slash(file_path))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: cfg has expression attached -> use that + else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) + { + dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push text location + if(loc.file_path.size != 0) + { + String8 location_string = push_str8f(arena, "%S:%I64d:%I64d", str8_skip_last_slash(loc.file_path), loc.pt.line, loc.pt.column); + dr_fstrs_push_new(arena, &result, ¶ms, location_string); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push target executable name + if(target.exe.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_skip_last_slash(target.exe)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + + //- rjf: push target arguments + if(target.args.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, target.args); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push conditions + { + String8 condition = rd_cfg_child_from_string(cfg, str8_lit("condition"))->first->string; + if(condition.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("if "), .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + RD_Font(RD_FontSlot_Code) + { + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, condition); + dr_fstrs_concat_in_place(&result, &fstrs); + } + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + } + + //- rjf: push disabled marker + if(is_disabled) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Disabled)")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push hit count + { + String8 hit_count_value_string = rd_cfg_child_from_string(cfg, str8_lit("hit_count"))->first->string; + U64 hit_count = 0; + if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count)) + { + String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); + dr_fstrs_push_new(arena, &result, ¶ms, hit_count_text); + } + } + + //- rjf: special case: auto view rule + if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + DR_FStrList src_fstrs = {0}; + DR_FStrList dst_fstrs = {0}; + if(src_string.size == 0) + { + src_string = str8_lit("(type)"); + src_color = ui_top_palette()->text_weak; + dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); + } + else RD_Font(RD_FontSlot_Code) + { + src_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, src_color, src_string); + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(view rule)"); + dst_color = ui_top_palette()->text_weak; + dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); + } + else RD_Font(RD_FontSlot_Code) + { + dst_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, dst_color, dst_string); + } + dr_fstrs_concat_in_place(&result, &src_fstrs); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&result, &dst_fstrs); + } + + //- rjf: special case: file path maps + if(str8_match(cfg->string, str8_lit("file_path_map"), 0)) + { + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + Vec4F32 src_color = rgba; + Vec4F32 dst_color = rgba; + if(src_string.size == 0) + { + src_string = str8_lit("(source path)"); + src_color = ui_top_palette()->text_weak; + } + if(dst_string.size == 0) + { + dst_string = str8_lit("(destination path)"); + dst_color = ui_top_palette()->text_weak; + } + dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); + } + +#undef start_secondary + scratch_end(scratch); + } + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras) +{ + DR_FStrList result = {0}; + + //- rjf: unpack entity info + F32 extras_size = ui_top_font_size()*0.95f; + Vec4F32 color = rd_color_from_ctrl_entity(entity); + if(color.w == 0) + { + color = ui_top_palette()->text; + } + Vec4F32 secondary_color = ui_top_palette()->text_weak; + String8 name = rd_name_from_ctrl_entity(arena, entity); + RD_IconKind icon_kind = RD_IconKind_Null; + B32 name_is_code = 0; + switch(entity->kind) + { + default:{}break; + case CTRL_EntityKind_Machine: {icon_kind = RD_IconKind_Machine;}break; + case CTRL_EntityKind_Process: {icon_kind = RD_IconKind_Threads;}break; + case CTRL_EntityKind_Thread: {icon_kind = RD_IconKind_Thread; name_is_code = 1;}break; + case CTRL_EntityKind_Module: {icon_kind = RD_IconKind_Module;}break; + } + + //- rjf: set up drawing params + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), color, ui_top_font_size()}; + + //- rjf: push icon + if(icon_kind != RD_IconKind_Null) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = secondary_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push frozen icon, if frozen + if((entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) && + ctrl_entity_tree_is_frozen(entity)) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->background_bad); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push containing process prefix + if(entity->kind == CTRL_EntityKind_Thread || + entity->kind == CTRL_EntityKind_Module) + { + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + if(processes.count > 1) + { + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + String8 process_name = rd_name_from_ctrl_entity(arena, process); + Vec4F32 process_color = rd_color_from_ctrl_entity(process); + if(process_color.w == 0) + { + process_color = color; + } + if(process_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, process_name, .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = process_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, "(PID: %I64u)", process->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.9f); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" / "), .color = secondary_color); + } + } + } + + //- rjf: push name + dr_fstrs_push_new(arena, &result, ¶ms, name, + .font = rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .raster_flags = rd_raster_flags_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), + .color = color); + + //- rjf: push PID + if(entity->kind == CTRL_EntityKind_Process) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, push_str8f(arena, " (PID: %I64u)", entity->id), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .color = secondary_color, .size = ui_top_font_size()*0.85f); + } + + //- rjf: threads get callstack extras + if(entity->kind == CTRL_EntityKind_Thread && include_extras) + { + Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + DI_Scope *di_scope = di_scope_open(); + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + Arch arch = entity->arch; + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); + for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1) + { + CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx]; + U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); + U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + if(rdi != &di_rdi_parsed_nil) + { + RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + name = push_str8_copy(arena, name); + if(name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color); + if(idx+1 < unwind.frames.count) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); + if(idx+1 == limit) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("..."), .color = secondary_color, .size = extras_size); + } + } + } + } + } + di_scope_close(di_scope); + } + + //- rjf: modules get debug info status extras + if(entity->kind == CTRL_EntityKind_Module && include_extras) + { + DI_Scope *di_scope = di_scope_open(); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); + if(rdi->raw_data_size == 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("(Symbols not found)"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main), .size = extras_size, .color = secondary_color); + } + di_scope_close(di_scope); + } + + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_code_name(Arena *arena, String8 code_name) +{ + DR_FStrList result = {0}; + { + RD_VocabInfo *info = rd_vocab_info_from_code_name(code_name); + + //- rjf: set up color/size for all parts of the title + // + // the "running" part implies that it changes as things are added - + // so if a primary title is pushed, we can make the rest of the title + // more faded/smaller, but only after a primary title is pushed, + // which could be caused by many different potential parts of a cfg. + // + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + + //- rjf: push icon + if(info->icon_kind != RD_IconKind_Null) UI_Tag(str8_lit("weak")) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[info->icon_kind], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + + //- rjf: push display name + if(info->display_name.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, info->display_name); + } + + //- rjf: push code name as a fallback + else + { + dr_fstrs_push_new(arena, &result, ¶ms, code_name, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); + } + } + return result; +} + +internal DR_FStrList +rd_title_fstrs_from_file_path(Arena *arena, String8 file_path) +{ + DR_FStrList fstrs = {0}; + String8 file_name = str8_skip_last_slash(file_path); + FileProperties props = os_properties_from_file_path(file_path); + RD_IconKind icon_kind = RD_IconKind_FileOutline; + if(props.flags & FilePropertyFlag_IsFolder) + { + icon_kind = RD_IconKind_FolderClosedFilled; + } + if(file_path.size == 0 || str8_match(file_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + icon_kind = RD_IconKind_Machine; + file_name = str8_lit("File System"); + } + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[icon_kind], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, file_name); + return fstrs; +} + //////////////////////////////// //~ rjf: UI Widgets: Loading Overlay diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 913375db..dfd3691c 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -95,6 +95,14 @@ struct RD_CodeSliceSignal #define RD_Palette(code) UI_Palette(rd_palette_from_code(code)) #define RD_Font(slot) UI_Font(rd_font_from_slot(slot)) UI_TextRasterFlags(rd_raster_flags_from_slot((slot))) +//////////////////////////////// +//~ rjf: UI Widgets: Fancy Title Strings + +internal DR_FStrList rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg); +internal DR_FStrList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_extras); +internal DR_FStrList rd_title_fstrs_from_code_name(Arena *arena, String8 code_name); +internal DR_FStrList rd_title_fstrs_from_file_path(Arena *arena, String8 file_path); + //////////////////////////////// //~ rjf: UI Widgets: Loading Overlay From f87dd1be8285df5a9cce082772242c649a628104 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 09:35:45 -0800 Subject: [PATCH 145/755] per-box tags -> per-box tags key; cache (key -> tags_list), and (key * string -> theme_pattern) separately; accelerate all theme lookups --- src/raddbg/raddbg_core.c | 26 ++-- src/raddbg/raddbg_widgets.c | 6 +- src/ui/ui_basic_widgets.c | 4 +- src/ui/ui_core.c | 257 ++++++++++++++++++++++++++++-------- src/ui/ui_core.h | 59 ++++++++- 5 files changed, 274 insertions(+), 78 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 32dda593..8f358979 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8119,7 +8119,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The Vec4F32 box_background_color = {0}; if(box->flags & UI_BoxFlag_DrawBackground) { - box_background_color = ui_color_from_tags_name(box->tags, str8_lit("background")); + box_background_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("background")); } // rjf: draw background @@ -8141,7 +8141,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 hover_color = ui_color_from_tags_name(box->tags, str8_lit("hover")); + Vec4F32 hover_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); // rjf: brighten { @@ -8239,11 +8239,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ellipses_run = fnt_push_run_from_string(scratch.arena, ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); } dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); - if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) + if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) UI_TagF("pop") { - String8 tags[] = {str8_lit("pop")}; - String8Array tags_array = {tags, ArrayCount(tags)}; - Vec4F32 match_color = ui_color_from_tags_name(tags_array, str8_lit("background")); + Vec4F32 match_color = ui_color_from_tags_key_name(ui_top_tags_key(), str8_lit("background")); dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } } @@ -8333,7 +8331,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { - Vec4F32 border_color = ui_color_from_tags_name(box->tags, str8_lit("border")); + Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -8341,7 +8339,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) { - Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("hover")); + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); color.w *= b->hot_t; R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; @@ -8360,7 +8358,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: draw sides if(b->flags & UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight) { - Vec4F32 border_color = ui_color_from_tags_name(box->tags, str8_lit("border")); + Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 r = b->rect; F32 half_thickness = 1.f; F32 softness = 0.f; @@ -8385,7 +8383,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("focus")); + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -8400,7 +8398,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } - Vec4F32 color = ui_color_from_tags_name(box->tags, str8_lit("focus")); + Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); @@ -8453,11 +8451,9 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } //- rjf: draw border/overlay color to signify error - if(ws->error_t > 0.01f) + if(ws->error_t > 0.01f) UI_TagF("bad") { - String8 tags[] = {str8_lit("bad")}; - String8Array tags_array = {tags, ArrayCount(tags)}; - Vec4F32 color = ui_color_from_tags_name(tags_array, str8_lit("text")); + Vec4F32 color = ui_color_from_name(str8_lit("text")); color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0088425b..1b83745d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1046,12 +1046,10 @@ internal UI_BOX_CUSTOM_DRAW(rd_thread_box_draw_extensions) } // rjf: locked icon on frozen threads - if(u->is_frozen) + if(u->is_frozen) UI_TagF("bad") { F32 lock_icon_off = ui_top_font_size()*0.2f; - String8 tags[] = {str8_lit("bad")}; - String8Array tags_array = {tags, ArrayCount(tags)}; - Vec4F32 color = ui_color_from_tags_name(tags_array, str8_lit("text")); + Vec4F32 color = ui_color_from_name(str8_lit("text")); dr_text(rd_font_from_slot(RD_FontSlot_Icons), box->font_size, 0, 0, FNT_RasterFlag_Smooth, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 9ac55cf7..2917ed6a 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -134,9 +134,9 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) FNT_Tag font = box->font; F32 font_size = box->font_size; F32 tab_size = box->tab_size; - Vec4F32 cursor_color = ui_color_from_tags_name(box->tags, str8_lit("cursor")); + Vec4F32 cursor_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("cursor")); cursor_color.w *= box->parent->parent->focus_active_t; - Vec4F32 select_color = ui_color_from_tags_name(box->tags, str8_lit("selection")); + Vec4F32 select_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("selection")); select_color.w *= 0.1f*(box->parent->parent->focus_active_t*0.2f + 0.8f); Vec2F32 text_position = ui_box_text_position(box); String8 edited_string = draw_data->edited_string; diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 0240d53c..074c0439 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -797,6 +797,11 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->ctx_menu_changed = 0; ui_state->default_animation_rate = 1 - pow_f32(2, (-80.f * ui_state->animation_dt)); ui_state->tooltip_can_overflow_window = 0; + ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; + ui_state->tags_cache_slots_count = 512; + ui_state->tags_cache_slots = push_array(ui_build_arena(), UI_TagsCacheSlot, ui_state->tags_cache_slots_count); + ui_state->theme_pattern_cache_slots_count = 512; + ui_state->theme_pattern_cache_slots = push_array(ui_build_arena(), UI_ThemePatternCacheSlot, ui_state->theme_pattern_cache_slots_count); } //- rjf: prune unused animation nodes @@ -2023,7 +2028,7 @@ ui_begin_ctx_menu(UI_Key key) ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clip; ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clickable; ui_state->ctx_menu_root->corner_radii[Corner_00] = ui_state->ctx_menu_root->corner_radii[Corner_01] = ui_state->ctx_menu_root->corner_radii[Corner_10] = ui_state->ctx_menu_root->corner_radii[Corner_11] = ui_top_font_size()*0.25f; - ui_state->ctx_menu_root->tags = ui_top_tags(); + ui_state->ctx_menu_root->tags_key = ui_top_tags_key(); ui_state->ctx_menu_root->palette = ui_top_palette(); ui_state->ctx_menu_root->blur_size = ui_top_blur_size(); ui_spacer(ui_em(1.f, 1.f)); @@ -2198,31 +2203,17 @@ ui_build_palette_(UI_Palette *base, UI_Palette *overrides) return palette; } -//- rjf: tag gathering +//- rjf: current style tags key -internal String8Array -ui_top_tags(void) +internal UI_Key +ui_top_tags_key(void) { - if(ui_state->current_gen_tags_gen != ui_state->tag_stack.gen) + UI_Key key = ui_key_zero(); + if(ui_state->tags_key_stack_top != 0) { - ui_state->current_gen_tags_gen = ui_state->tag_stack.gen; - Temp scratch = scratch_begin(0, 0); - String8List tags = {0}; - for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) - { - if(n->v.size == 1 && n->v.str[0] == '.') - { - break; - } - if(n->v.size != 0) - { - str8_list_push(ui_build_arena(), &tags, push_str8_copy(ui_build_arena(), n->v)); - } - } - ui_state->current_gen_tags = str8_array_from_list(ui_build_arena(), &tags); - scratch_end(scratch); + key = ui_state->tags_key_stack_top->key; } - return ui_state->current_gen_tags; + return key; } //- rjf: theme color lookups @@ -2230,49 +2221,94 @@ ui_top_tags(void) internal Vec4F32 ui_color_from_name(String8 name) { - Vec4F32 result = ui_color_from_tags_name(ui_top_tags(), name); + Vec4F32 result = ui_color_from_tags_key_name(ui_top_tags_key(), name); return result; } internal Vec4F32 -ui_color_from_tags_name(String8Array tags, String8 name) +ui_color_from_tags_key_name(UI_Key key, String8 name) { Vec4F32 result = {0}; { - UI_Theme *theme = ui_state->theme; - UI_ThemePattern *pattern = 0; - U64 best_match_count = 0; - for(U64 idx = 0; idx < theme->patterns_count; idx += 1) + //- rjf: compute final key, mixing (tags_key, name) + UI_Key final_key = ui_key_from_string(key, name); + + //- rjf: map to existing node + U64 slot_idx = final_key.u64[0]%ui_state->theme_pattern_cache_slots_count; + UI_ThemePatternCacheSlot *slot = &ui_state->theme_pattern_cache_slots[slot_idx]; + UI_ThemePatternCacheNode *node = 0; + for(UI_ThemePatternCacheNode *n = slot->first; + n != 0; + n = n->next) { - UI_ThemePattern *p = &theme->patterns[idx]; - U64 match_count = 0; - B32 name_matches = 0; - for EachIndex(key_tags_idx, tags.count+1) + if(ui_key_match(n->key, final_key)) { - String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; - for EachIndex(p_tags_idx, p->tags.count) + node = n; + } + } + + //- rjf: no node? create + if(node == 0) + { + // rjf: map tags_key (without name) -> full list of tags + String8Array tags = {0}; + { + U64 tags_cache_slot_idx = key.u64[0]%ui_state->tags_cache_slots_count; + UI_TagsCacheSlot *tags_cache_slot = &ui_state->tags_cache_slots[tags_cache_slot_idx]; + for(UI_TagsCacheNode *n = tags_cache_slot->first; n != 0; n = n->next) { - if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) + if(ui_key_match(n->key, key)) { - name_matches = (key_tags_idx == tags.count); - match_count += 1; + tags = n->tags; break; } } } - if(name_matches && match_count > best_match_count) + + // rjf: map tags to theme pattern + UI_Theme *theme = ui_state->theme; + UI_ThemePattern *pattern = 0; + U64 best_match_count = 0; + for(U64 idx = 0; idx < theme->patterns_count; idx += 1) { - pattern = p; - best_match_count = match_count; - } - if(match_count == tags.count+1) - { - break; + UI_ThemePattern *p = &theme->patterns[idx]; + U64 match_count = 0; + B32 name_matches = 0; + for EachIndex(key_tags_idx, tags.count+1) + { + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; + for EachIndex(p_tags_idx, p->tags.count) + { + if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) + { + name_matches = (key_tags_idx == tags.count); + match_count += 1; + break; + } + } + } + if(name_matches && match_count > best_match_count) + { + pattern = p; + best_match_count = match_count; + } + if(match_count == tags.count+1) + { + break; + } } + + // rjf: store in (key, name) -> (pattern) cache + node = push_array(ui_build_arena(), UI_ThemePatternCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = final_key; + node->pattern = pattern; } - if(pattern != 0) + + //- rjf: grab resultant color + if(node != 0 && node->pattern != 0) { - result = pattern->linear; + result = node->pattern->linear; } } return result; @@ -2438,7 +2474,11 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_padding = ui_state->text_padding_stack.top->v; box->hover_cursor = ui_state->hover_cursor_stack.top->v; box->custom_draw = 0; - box->tags = ui_top_tags(); + box->tags_key = ui_key_zero(); + if(ui_state->tags_key_stack_top != 0) + { + box->tags_key = ui_state->tags_key_stack_top->key; + } } //- rjf: auto-pop all stacks @@ -3145,7 +3185,7 @@ node->v = new_value;\ SLLStackPush(state->name_lower##_stack.top, node);\ if(node->next == &state->name_lower##_nil_stack_top)\ {\ -state->name_lower##_stack.bottom_val = (new_value);\ +state->name_lower##_stack.bottom_val = (node->v);\ }\ state->name_lower##_stack.auto_pop = 0;\ state->name_lower##_stack.gen += 1;\ @@ -3173,13 +3213,124 @@ state->name_lower##_stack.auto_pop = 1;\ state->name_lower##_stack.gen += 1;\ return old_value; +internal void +ui__push_tags_key_from_appended_string(String8 string) +{ + // rjf: generate new key, by combining hash of this new string with the top + // of the tags key stack + UI_Key seed_key = {0}; + if(ui_state->tags_key_stack_top != 0) + { + seed_key = ui_state->tags_key_stack_top->key; + } + UI_Key key = seed_key; + if(!str8_match(str8_lit("."), string, 0) && string.size > 0) + { + key = ui_key_from_string(seed_key, string); + } + + // rjf: push this new key onto the stack + { + UI_TagsKeyStackNode *node = ui_state->tags_key_stack_free; + if(node != 0) + { + SLLStackPop(ui_state->tags_key_stack_free); + } + else + { + node = push_array(ui_build_arena(), UI_TagsKeyStackNode, 1); + } + SLLStackPush(ui_state->tags_key_stack_top, node); + node->key = key; + } + + // rjf: store in tags cache + U64 slot_idx = key.u64[0] % ui_state->tags_cache_slots_count; + UI_TagsCacheSlot *slot = &ui_state->tags_cache_slots[slot_idx]; + UI_TagsCacheNode *node = 0; + for(UI_TagsCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ui_key_match(n->key, key)) + { + node = n; + break; + } + } + if(node == 0) + { + Temp scratch = scratch_begin(0, 0); + String8List tags = {0}; + if(!str8_match(string, str8_lit("."), 0)) + { + if(string.size != 0) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), string)); + } + for(UI_TagNode *n = ui_state->tag_stack.top; n != 0; n = n->next) + { + if(n->v.size == 1 && n->v.str[0] == '.') + { + break; + } + if(n->v.size != 0) + { + str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), n->v)); + } + } + } + node = push_array(ui_build_arena(), UI_TagsCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = key; + node->tags = str8_array_from_list(ui_build_arena(), &tags); + scratch_end(scratch); + } +} + +internal void +ui__pop_tags_key(void) +{ + if(ui_state->tags_key_stack_top != 0) + { + UI_TagsKeyStackNode *popped = ui_state->tags_key_stack_top; + SLLStackPop(ui_state->tags_key_stack_top); + SLLStackPush(ui_state->tags_key_stack_free, popped); + } +} + //- rjf: manual implementations -internal String8 ui_top_tag(void) { UI_StackTopImpl(ui_state, Tag, tag) } -internal String8 ui_bottom_tag(void) { UI_StackBottomImpl(ui_state, Tag, tag) } -internal String8 ui_push_tag(String8 v) { UI_StackPushImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) } -internal String8 ui_pop_tag(void) { UI_StackPopImpl(ui_state, Tag, tag) } -internal String8 ui_set_next_tag(String8 v) { UI_StackSetNextImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) } +internal String8 +ui_top_tag(void) +{ + UI_StackTopImpl(ui_state, Tag, tag) +} + +internal String8 +ui_bottom_tag(void) +{ + UI_StackBottomImpl(ui_state, Tag, tag) +} + +internal String8 +ui_push_tag(String8 v) +{ + ui__push_tags_key_from_appended_string(v); + UI_StackPushImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) +} + +internal String8 +ui_pop_tag(void) +{ + ui__pop_tags_key(); + UI_StackPopImpl(ui_state, Tag, tag) +} + +internal String8 +ui_set_next_tag(String8 v) +{ + ui__push_tags_key_from_appended_string(v); + UI_StackSetNextImpl(ui_state, Tag, tag, String8, push_str8_copy(ui_build_arena(), v)) +} //- rjf: helpers diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index a020f576..ade38b1c 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -440,7 +440,7 @@ struct UI_Box //- rjf: per-build equipment UI_Key key; UI_BoxFlags flags; - String8Array tags; + UI_Key tags_key; String8 string; UI_TextAlign text_align; Vec2F32 fixed_position; @@ -646,6 +646,49 @@ struct UI_AnimSlot //////////////////////////////// //~ rjf: State Types +//- rjf: cache for mapping 64-bit key -> array of tags + +typedef struct UI_TagsCacheNode UI_TagsCacheNode; +struct UI_TagsCacheNode +{ + UI_TagsCacheNode *next; + UI_Key key; + String8Array tags; +}; + +typedef struct UI_TagsCacheSlot UI_TagsCacheSlot; +struct UI_TagsCacheSlot +{ + UI_TagsCacheNode *first; + UI_TagsCacheNode *last; +}; + +typedef struct UI_TagsKeyStackNode UI_TagsKeyStackNode; +struct UI_TagsKeyStackNode +{ + UI_TagsKeyStackNode *next; + UI_Key key; +}; + +//- rjf: cache for mapping 64-bit key * string -> theme pattern + +typedef struct UI_ThemePatternCacheNode UI_ThemePatternCacheNode; +struct UI_ThemePatternCacheNode +{ + UI_ThemePatternCacheNode *next; + UI_Key key; + UI_ThemePattern *pattern; +}; + +typedef struct UI_ThemePatternCacheSlot UI_ThemePatternCacheSlot; +struct UI_ThemePatternCacheSlot +{ + UI_ThemePatternCacheNode *first; + UI_ThemePatternCacheNode *last; +}; + +//- rjf: cache for mapping 64-bit key -> box + typedef struct UI_BoxHashSlot UI_BoxHashSlot; struct UI_BoxHashSlot { @@ -653,6 +696,8 @@ struct UI_BoxHashSlot UI_Box *hash_last; }; +//- rjf: main state bundle + typedef struct UI_State UI_State; struct UI_State { @@ -683,6 +728,12 @@ struct UI_State B32 tooltip_can_overflow_window; String8Array current_gen_tags; U64 current_gen_tags_gen; + UI_TagsKeyStackNode *tags_key_stack_top; + UI_TagsKeyStackNode *tags_key_stack_free; + U64 tags_cache_slots_count; + UI_TagsCacheSlot *tags_cache_slots; + U64 theme_pattern_cache_slots_count; + UI_ThemePatternCacheSlot *theme_pattern_cache_slots; //- rjf: build phase output UI_Box *root; @@ -911,12 +962,12 @@ internal void ui_set_auto_focus_hot_key(UI_Key key); internal UI_Palette * ui_build_palette_(UI_Palette *base, UI_Palette *overrides); #define ui_build_palette(base, ...) ui_build_palette_((base), &(UI_Palette){.text = v4f32(0, 0, 0, 0), __VA_ARGS__}) -//- rjf: tag gathering -internal String8Array ui_top_tags(void); +//- rjf: current style tags key +internal UI_Key ui_top_tags_key(void); //- rjf: theme color lookups internal Vec4F32 ui_color_from_name(String8 name); -internal Vec4F32 ui_color_from_tags_name(String8Array tags, String8 name); +internal Vec4F32 ui_color_from_tags_key_name(UI_Key key, String8 name); //- rjf: box node construction internal UI_Box * ui_build_box_from_key(UI_BoxFlags flags, UI_Key key); From a8f72dd5f185c1dda7b17dabc6c7c4c936fdd28c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 11:33:16 -0800 Subject: [PATCH 146/755] progress on per-view searching operation - will be specialized & used for replacements for finding text, for going to line/address, and filtering in query views --- src/eval/eval_ir.c | 2 +- src/os/core/win32/os_core_win32.c | 3 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 + src/raddbg/raddbg_core.c | 571 ++++++++++++++++------------- src/raddbg/raddbg_core.h | 14 +- src/raddbg/raddbg_views.c | 24 +- src/raddbg/raddbg_widgets.c | 57 +-- src/ui/ui_core.c | 5 +- src/ui/ui_core.h | 48 ++- 10 files changed, 386 insertions(+), 342 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 54c09a1f..e1186967 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2253,7 +2253,7 @@ E_IRGEN_FUNCTION_DEF(default) Temp scratch = scratch_begin(&arena, 1); String8 file_path = path_normalized_from_string(scratch.arena, expr->string); FileProperties props = os_properties_from_file_path(file_path); - if(props.flags & FilePropertyFlag_IsFolder || props.modified == 0) + if(props.flags & FilePropertyFlag_IsFolder || file_path.size == 0 || str8_match(file_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index f6ab35c3..0aa5cce0 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -552,7 +552,8 @@ os_properties_from_file_path(String8 path) Temp scratch = scratch_begin(0, 0); WCHAR buffer[512] = {0}; DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer); - U64 last_slash_pos = str8_find_needle(path, 0, str8_lit("/"), StringMatchFlag_SlashInsensitive); + U64 last_slash_pos = 0; + for(;last_slash_pos < path.size; last_slash_pos = str8_find_needle(path, last_slash_pos+1, str8_lit("/"), StringMatchFlag_SlashInsensitive)); String8 path_trimmed = str8_prefix(path, last_slash_pos); for(U64 off = 0; off < (U64)length;) { diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index dff9c85c..41f86d8c 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -809,7 +809,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x446142ff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x4461425f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a2f034b3..1ffe235a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -990,6 +990,7 @@ RD_ThemePresetTable: background: 0x1b1b1bff, alt: background: 0x222222ff, pop: background: 0x355b6eff, + fresh: background: 0x446142ff, border: 0x404040ff, text: 0xe5e5e5ff, weak: text: 0xa4a4a4ff, @@ -1052,6 +1053,7 @@ RD_ThemePresetTable: { background: 0x1b1b1baf, background: alt: 0x0000005f, + background: fresh: 0x4461425f, border: 0xbfbfbf1f, scroll_bar: { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8f358979..a351afb5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3250,262 +3250,332 @@ rd_view_ui(Rng2F32 rect) { ProfBeginFunction(); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); String8 view_name = view->string; String8 expr_string = rd_expr_from_cfg(view); ////////////////////////////// - //- rjf: special-case view: "getting started" + //- rjf: searching extension // - if(0){} - else if(str8_match(view_name, str8_lit("getting_started"), 0)) + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), !!vs->is_searching); + if(search_row_open_t > 0.001f) RD_Font(RD_FontSlot_Code) { - Temp scratch = scratch_begin(0, 0); - ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); - UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) - UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + //- rjf: clamp cursor + if(vs->search_cursor.column == 0) { - RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - - //- rjf: icon & info - UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") + vs->search_mark = txt_pt(1, 1); + vs->search_cursor = txt_pt(1, vs->search_string_size+1); + } + + //- rjf: determine dimensions + F32 search_row_height_target = floor_f32(ui_top_font_size()*2.5f); + F32 search_row_height = search_row_open_t*search_row_height_target; + search_row_height = Min(search_row_height, dim_2f32(rect).y); + rect.y0 += search_row_height; + rect.y0 = floor_f32(rect.y0); + + //- rjf: build container + UI_Box *search_row = &ui_nil_box; + UI_PrefHeight(ui_px(search_row_height, 1.f)) + { + search_row = ui_build_box_from_stringf(UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawDropShadow, "###search"); + } + + //- rjf: build contents + UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->is_searching ? UI_FocusKind_On : UI_FocusKind_Off) + { + UI_TextAlignment(UI_TextAlign_Center) + UI_Transparency(1-search_row_open_t) + UI_PrefWidth(ui_em(2.5f, 1.f)) + UI_TagF("weak") + RD_Font(RD_FontSlot_Icons) + ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); + RD_LineEditParams params = {0}; { - //- rjf: icon + params.flags |= RD_LineEditFlag_CodeContents; + params.flags |= RD_LineEditFlag_Border; + params.cursor = &vs->search_cursor; + params.mark = &vs->search_mark; + params.edit_buffer = vs->search_buffer; + params.edit_string_size_out = &vs->search_string_size; + params.edit_buffer_size = sizeof(vs->search_buffer); + } + rd_line_editf(¶ms, "###search"); + } + + //- rjf: commit string to view + RD_Cfg *search = rd_cfg_child_from_string_or_alloc(view, str8_lit("search")); + rd_cfg_new_replace(search, str8(vs->search_buffer, vs->search_string_size)); + } + + ////////////////////////////// + //- rjf: build main view container + // + UI_Box *view_container = &ui_nil_box; + UI_WidthFill UI_HeightFill + { + view_container = ui_build_box_from_key(0, ui_key_zero()); + } + + ////////////////////////////// + //- rjf: fill view container + // + UI_Parent(view_container) + { + //////////////////////////// + //- rjf: special-case view: "getting started" + // + if(0){} + else if(str8_match(view_name, str8_lit("getting_started"), 0)) + { + Temp scratch = scratch_begin(0, 0); + ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); + UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) + UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) + { + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + + //- rjf: icon & info + UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") { - F32 icon_dim = ui_top_font_size()*10.f; - UI_PrefHeight(ui_px(icon_dim, 1.f)) + //- rjf: icon + { + F32 icon_dim = ui_top_font_size()*10.f; + UI_PrefHeight(ui_px(icon_dim, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_PrefWidth(ui_px(icon_dim, 1.f)) + { + R_Handle texture = rd_state->icon_texture; + Vec2S32 texture_dim = r_size_from_tex2d(texture); + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + } + } + + //- rjf: info + UI_Padding(ui_em(2.f, 1.f)) + UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) - UI_PrefWidth(ui_px(icon_dim, 1.f)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_text_dim(10, 1)) { - R_Handle texture = rd_state->icon_texture; - Vec2S32 texture_dim = r_size_from_tex2d(texture); - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); } } - //- rjf: info - UI_Padding(ui_em(2.f, 1.f)) - UI_WidthFill UI_PrefHeight(ui_em(2.f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_text_dim(10, 1)) + //- rjf: targets state dependent helper + B32 helper_built = 0; + if(processes.count == 0) { - ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); + helper_built = 1; + switch(targets.count) + { + //- rjf: user has no targets. build helper for adding them + case 0: + { + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("pop") + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + } + }break; + + //- rjf: user has 1 target. build helper for launching it + case 1: + { + RD_Cfg *target_cfg = rd_cfg_list_first(&targets); + D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); + String8 target_full_path = target.exe; + String8 target_name = str8_skip_last_slash(target_full_path); + UI_PrefHeight(ui_em(3.75f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_PrefWidth(ui_em(22.f, 1.f)) + UI_CornerRadius(ui_top_font_size()/2.f) + UI_TagF("good_pop") + { + if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); + } + ui_spacer(ui_em(1.5f, 1)); + if(ui_clicked(rd_icon_buttonf(RD_IconKind_StepInto, 0, "Step Into %S", target_name))) + { + rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); + } + } + }break; + + //- rjf: user has N targets. + default: + { + helper_built = 0; + }break; + } } - } - - //- rjf: targets state dependent helper - B32 helper_built = 0; - if(processes.count == 0) - { - helper_built = 1; - switch(targets.count) + + //- rjf: or text + if(helper_built) { - //- rjf: user has no targets. build helper for adding them - case 0: - { - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - UI_TagF("pop") - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Add, 0, "Add Target"))) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); - } - }break; - - //- rjf: user has 1 target. build helper for launching it - case 1: - { - RD_Cfg *target_cfg = rd_cfg_list_first(&targets); - D_Target target = rd_target_from_cfg(scratch.arena, target_cfg); - String8 target_full_path = target.exe; - String8 target_name = str8_skip_last_slash(target_full_path); - UI_PrefHeight(ui_em(3.75f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_PrefWidth(ui_em(22.f, 1.f)) - UI_CornerRadius(ui_top_font_size()/2.f) - UI_TagF("good_pop") - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Launch %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndRun, .cfg = target_cfg->id); - } - ui_spacer(ui_em(1.5f, 1)); - if(ui_clicked(rd_icon_buttonf(RD_IconKind_StepInto, 0, "Step Into %S", target_name))) - { - rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); - } - } - }break; - - //- rjf: user has N targets. - default: - { - helper_built = 0; - }break; + UI_TagF("weak") + UI_PrefHeight(ui_em(2.25f, 1.f)) + UI_Row + UI_Padding(ui_pct(1, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_WidthFill + ui_labelf("- or -"); } - } - - //- rjf: or text - if(helper_built) - { + + //- rjf: helper text for command lister activation UI_TagF("weak") - UI_PrefHeight(ui_em(2.25f, 1.f)) - UI_Row - UI_Padding(ui_pct(1, 0)) + UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) - UI_WidthFill - ui_labelf("- or -"); + UI_Padding(ui_pct(1, 0)) + { + ui_labelf("use"); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + ui_labelf("to search for commands and options"); + } + } + scratch_end(scratch); + } + + //////////////////////////// + //- rjf: special-case view: pending + // + else if(str8_match(view_name, str8_lit("pending"), 0)) + { + Temp scratch = scratch_begin(0, 0); + typedef struct State State; + struct State + { + Arena *deferred_cmd_arena; + RD_CmdList deferred_cmds; + }; + State *state = rd_view_state(State); + if(state->deferred_cmd_arena == 0) + { + state->deferred_cmd_arena = rd_push_view_arena(); + } + rd_store_view_loading_info(1, 0, 0); + + // rjf: any commands sent to this view need to be deferred until loading is complete + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) + { + default:{}break; + case RD_CmdKind_GoToLine: + case RD_CmdKind_GoToAddress: + case RD_CmdKind_CenterCursor: + case RD_CmdKind_ContainCursor: + { + rd_cmd_list_push_new(state->deferred_cmd_arena, &state->deferred_cmds, cmd->name, cmd->regs); + }break; + } } - //- rjf: helper text for command lister activation - UI_TagF("weak") - UI_PrefHeight(ui_em(2.25f, 1.f)) UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_Padding(ui_pct(1, 0)) + // rjf: unpack view's target expression & hash + String8 expr_string = rd_expr_from_cfg(view); + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + Rng1U64 range = r1u64(0, 1024); + U128 key = rd_key_from_eval_space_range(eval.space, range, 0); + U128 hash = hs_hash_from_key(key, 0); + + // rjf: determine if hash's blob is ready, and which viewer to use + B32 data_is_ready = 0; + String8 new_view_name = {0}; { - ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); - ui_labelf("to search for commands and options"); - } - } - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: special-case view: pending - // - else if(str8_match(view_name, str8_lit("pending"), 0)) - { - Temp scratch = scratch_begin(0, 0); - typedef struct State State; - struct State - { - Arena *deferred_cmd_arena; - RD_CmdList deferred_cmds; - }; - State *state = rd_view_state(State); - if(state->deferred_cmd_arena == 0) - { - state->deferred_cmd_arena = rd_push_view_arena(); - } - rd_store_view_loading_info(1, 0, 0); - - // rjf: any commands sent to this view need to be deferred until loading is complete - for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) - { - RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); - switch(kind) - { - default:{}break; - case RD_CmdKind_GoToLine: - case RD_CmdKind_GoToAddress: - case RD_CmdKind_CenterCursor: - case RD_CmdKind_ContainCursor: + HS_Scope *hs_scope = hs_scope_open(); + if(!u128_match(hash, u128_zero())) { - rd_cmd_list_push_new(state->deferred_cmd_arena, &state->deferred_cmds, cmd->name, cmd->regs); - }break; - } - } - - // rjf: unpack view's target expression & hash - String8 expr_string = rd_expr_from_cfg(view); - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); - Rng1U64 range = r1u64(0, 1024); - U128 key = rd_key_from_eval_space_range(eval.space, range, 0); - U128 hash = hs_hash_from_key(key, 0); - - // rjf: determine if hash's blob is ready, and which viewer to use - B32 data_is_ready = 0; - String8 new_view_name = {0}; - { - HS_Scope *hs_scope = hs_scope_open(); - if(!u128_match(hash, u128_zero())) - { - String8 data = hs_data_from_hash(hs_scope, hash); - U64 num_utf8_bytes = 0; - U64 num_unknown_bytes = 0; - for(U64 idx = 0; idx < data.size && idx < range.max;) - { - UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); - if(decode.codepoint != max_U32 && (decode.inc > 1 || - (10 <= decode.codepoint && decode.codepoint <= 13) || - (32 <= decode.codepoint && decode.codepoint <= 126))) + String8 data = hs_data_from_hash(hs_scope, hash); + U64 num_utf8_bytes = 0; + U64 num_unknown_bytes = 0; + for(U64 idx = 0; idx < data.size && idx < range.max;) { - num_utf8_bytes += decode.inc; - idx += decode.inc; + UnicodeDecode decode = utf8_decode(data.str+idx, data.size-idx); + if(decode.codepoint != max_U32 && (decode.inc > 1 || + (10 <= decode.codepoint && decode.codepoint <= 13) || + (32 <= decode.codepoint && decode.codepoint <= 126))) + { + num_utf8_bytes += decode.inc; + idx += decode.inc; + } + else + { + num_unknown_bytes += 1; + idx += 1; + } + } + data_is_ready = 1; + if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) + { + new_view_name = str8_lit("text"); } else { - num_unknown_bytes += 1; - idx += 1; + new_view_name = str8_lit("memory"); } } - data_is_ready = 1; - if(num_utf8_bytes > num_unknown_bytes*4 || num_unknown_bytes == 0) - { - new_view_name = str8_lit("text"); - } - else - { - new_view_name = str8_lit("memory"); - } + hs_scope_close(hs_scope); } - hs_scope_close(hs_scope); - } - - // rjf: if we don't have a viewer, just use the memory viewer. - if(new_view_name.size != 0) - { - new_view_name = str8_lit("memory"); - } - - // rjf: if data is ready and we have the name of a new visualizer, - // dispatch deferred commands & change this view's string to be - // that of the new visualizer. - if(data_is_ready && new_view_name.size != 0) - { - for(RD_CmdNode *cmd_node = state->deferred_cmds.first; - cmd_node != 0; - cmd_node = cmd_node->next) + + // rjf: if we don't have a viewer, just use the memory viewer. + if(new_view_name.size != 0) { - RD_Cmd *cmd = &cmd_node->cmd; - rd_push_cmd(cmd->name, cmd->regs); + new_view_name = str8_lit("memory"); } - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - rd_cfg_equip_string(view, new_view_name); + + // rjf: if data is ready and we have the name of a new visualizer, + // dispatch deferred commands & change this view's string to be + // that of the new visualizer. + if(data_is_ready && new_view_name.size != 0) + { + for(RD_CmdNode *cmd_node = state->deferred_cmds.first; + cmd_node != 0; + cmd_node = cmd_node->next) + { + RD_Cmd *cmd = &cmd_node->cmd; + rd_push_cmd(cmd->name, cmd->regs); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + rd_cfg_equip_string(view, new_view_name); + } + + // rjf: if we don't have a viewer, for whatever reason, then just + // close the tab. + if(data_is_ready && new_view_name.size == 0) + { + rd_cmd(RD_CmdKind_CloseTab); + } + + scratch_end(scratch); } - // rjf: if we don't have a viewer, for whatever reason, then just - // close the tab. - if(data_is_ready && new_view_name.size == 0) + //////////////////////////// + //- rjf: visualizer hook + // + else { - rd_cmd(RD_CmdKind_CloseTab); + Temp scratch = scratch_begin(0, 0); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); + E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); + E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); + view_ui_rule->ui(expr_eval, tag, rect); + scratch_end(scratch); } - - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: visualizer hook - // - else - { - Temp scratch = scratch_begin(0, 0); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); - E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); - view_ui_rule->ui(expr_eval, tag, rect); - scratch_end(scratch); } ProfEnd(); @@ -3541,12 +3611,12 @@ rd_view_eval_view(void) } internal String8 -rd_view_filter(void) +rd_view_search(void) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *filter = rd_cfg_child_from_string(view, str8_lit("filter")); - String8 filter_string = filter->first->string; - return filter_string; + RD_Cfg *search = rd_cfg_child_from_string(view, str8_lit("search")); + String8 search_string = search->first->string; + return search_string; } internal RD_Cfg * @@ -5631,9 +5701,11 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: unpack query parameters RD_Cfg *root = query; RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - rd_cfg_new(view, str8_lit("lister")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->is_searching = 1; RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - String8 query_expression = str8_lit("query:procedures"); + String8 query_expression = str8_lit("procedures"); rd_cfg_new_replace(expr, query_expression); E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); @@ -5643,7 +5715,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The { Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), query_eval.exprs); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_search(), query_eval.exprs); F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); F32 max_query_height_px = content_rect_dim.y*0.8f; @@ -7070,7 +7142,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The panel_tree.focused == panel); RD_Cfg *selected_tab = panel->selected_tab; RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); - F32 selected_tab_is_filtering_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_filtering_t_%p", selected_tab), (F32)!!selected_tab_view_state->is_filtering); ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { @@ -7107,14 +7178,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The content_rect.y0 = panel_rect.y0; content_rect.y1 = panel_rect.y1 - tab_bar_vheight; } - if(selected_tab_is_filtering_t > 0.01f) - { - filter_rect.x0 = content_rect.x0; - filter_rect.y0 = content_rect.y0; - filter_rect.x1 = content_rect.x1; - content_rect.y0 += filter_bar_height*selected_tab_is_filtering_t; - filter_rect.y1 = content_rect.y0; - } tab_bar_rect = intersect_2f32(tab_bar_rect, panel_rect); content_rect = intersect_2f32(content_rect, panel_rect); @@ -7399,7 +7462,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_Box *loading_overlay_container = &ui_nil_box; if(build_panel) UI_Parent(panel_box) UI_WidthFill UI_HeightFill { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); } ////////////////////////// @@ -7454,7 +7517,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The //- rjf: build tab view UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") { - rd_view_ui(content_rect); + rd_view_ui(pad_2f32(content_rect, -1.f)); } //- rjf: pop interaction registers; commit if this is the selected view @@ -7470,7 +7533,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The // if(build_panel) { - F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target); + F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target, .initial = selected_tab_view_state->loading_t_target); if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) { rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); @@ -7548,6 +7611,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The TabTask *last_tab_task = 0; U64 tab_task_count = 0; F32 tab_close_width_px = ui_top_font_size()*2.5f; + F32 max_tab_width_px = ui_top_font_size()*20.f; if(build_panel) { for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) @@ -7561,6 +7625,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The t->tab = tab; t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + t->tab_width = Min(max_tab_width_px, t->tab_width); SLLQueuePush(first_tab_task, last_tab_task, t); tab_task_count += 1; } @@ -7703,7 +7768,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) - UI_TagF("weak") + UI_TagF(".") UI_TagF("weak") UI_TagF("implicit") UI_CornerRadius00(0) UI_CornerRadius01(0) { @@ -7713,6 +7778,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawText| UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawActiveEffects, @@ -8157,9 +8223,12 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The if(box->hot_t > 0.01f) DR_ClipScope(box->rect) { Vec4F32 color = hover_color; - color.w *= 0.015f*t; + color.w *= 0.02f*t; Vec2F32 center = ui_mouse(); + Vec2F32 box_dim = dim_2f32(box->rect); + F32 max_dim = Max(box_dim.x, box_dim.y); F32 radius = box->font_size*12.f; + radius = Min(max_dim, radius); dr_rect(pad_2f32(r2f32(center, center), radius), color, radius, 0, radius/3.f); } } @@ -14207,26 +14276,14 @@ Z(getting_started) //- rjf: filtering case RD_CmdKind_Filter: { -#if 0 // TODO(rjf): @cfg - RD_View *view = rd_view_from_handle(rd_regs()->view); - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - B32 view_is_tab = 0; - for(RD_View *tab = panel->first_tab_view; !rd_view_is_nil(tab); tab = tab->order_next) + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->is_searching) { - if(rd_view_is_project_filtered(tab)) { continue; } - if(tab == view) - { - view_is_tab = 1; - break; - } + vs->search_cursor = txt_pt(1, 1+vs->search_string_size); + vs->search_mark = txt_pt(1, 1); } - if(view_is_tab && view->spec->flags & RD_ViewRuleInfoFlag_CanFilter) - { - view->is_filtering ^= 1; - view->query_cursor = txt_pt(1, 1+(S64)view->query_string_size); - view->query_mark = txt_pt(1, 1); - } -#endif + vs->is_searching ^= 1; }break; case RD_CmdKind_ClearFilter: { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 10f2d07a..c8c5b42c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -162,12 +162,12 @@ struct RD_ViewState RD_ArenaExt *last_arena_ext; void *user_data; - // rjf: filter editing controls - B32 is_filtering; - TxtPt filter_cursor; - TxtPt filter_mark; - U8 filter_buffer[KB(1)]; - U64 filter_string_size; + // rjf: search editing controls + B32 is_searching; + TxtPt search_cursor; + TxtPt search_mark; + U8 search_buffer[KB(1)]; + U64 search_string_size; }; typedef struct RD_ViewStateSlot RD_ViewStateSlot; @@ -1075,7 +1075,7 @@ internal void rd_view_ui(Rng2F32 rect); internal Arena *rd_view_arena(void); internal UI_ScrollPt2 rd_view_scroll_pos(void); internal EV_View *rd_view_eval_view(void); -internal String8 rd_view_filter(void); +internal String8 rd_view_search(void); internal RD_Cfg *rd_view_cfg_from_string(String8 string); internal E_Value rd_view_cfg_value_from_string(String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a1fee200..9ed4a54f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -844,7 +844,7 @@ rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) RD_WatchPt pt = zero_struct; { Temp scratch = scratch_begin(0, 0); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_filter(), block_ranges, (U64)tbl.y); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_search(), block_ranges, (U64)tbl.y); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); { S64 x = 0; @@ -871,7 +871,7 @@ rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Temp scratch = scratch_begin(0, 0); U64 num = ev_num_from_key(block_ranges, pt.key); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_filter(), block_ranges, num); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_search(), block_ranges, num); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); tbl.x = 0; { @@ -1119,10 +1119,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: folder / file rows else if(info.eval.space.kind == E_SpaceKind_FileSystem) { - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_top_palette()->text, ui_top_font_size()}; - E_Type *type = e_type_from_key__cached(info.eval.type_key); String8 file_path = e_string_from_id(info.eval.value.u64); DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); + E_Type *type = e_type_from_key__cached(info.eval.type_key); if(str8_match(type->name, str8_lit("folder"), 0)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, @@ -1476,6 +1475,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.flags |= RD_WatchCellFlag_Button; result.cmd_name = cmd_name; } + else if(result.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } }break; } @@ -1544,7 +1549,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) ewv->initialized = 1; ewv->text_edit_arena = rd_push_view_arena(); } - B32 is_query = (rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("query")) != &rd_nil_cfg); ////////////////////////////// //- rjf: unpack arguments @@ -1554,7 +1558,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; - String8 filter = rd_view_filter(); + String8 filter = rd_view_search(); ////////////////////////////// //- rjf: decide if root should be implicit @@ -2748,7 +2752,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(row_is_fresh) { - ui_set_next_tag(str8_lit("pop")); + ui_set_next_tag(str8_lit("fresh")); row_flags |= UI_BoxFlag_DrawBackground; } else if(global_row_idx & 1) @@ -2842,12 +2846,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { if(cell_info.flags & RD_WatchCellFlag_IsErrored) { - cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBad; + cell_flags |= UI_BoxFlag_DrawBackground; cell_tag = str8_lit("bad"); } else if(cell_info.inheritance_tooltip.size != 0) { - cell_flags |= UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawPop; + cell_flags |= UI_BoxFlag_DrawBackground; cell_tag = str8_lit("pop"); } else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && @@ -2862,7 +2866,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); - cell_flags |= UI_BoxFlag_DrawPop|UI_BoxFlag_DrawBackground; + cell_flags |= UI_BoxFlag_DrawBackground; } else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1b83745d..4edd7ef6 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -371,7 +371,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e Vec4F32 color = rd_color_from_ctrl_entity(entity); if(color.w == 0) { - color = ui_top_palette()->text; + color = ui_color_from_name(str8_lit("text")); } Vec4F32 secondary_color = ui_top_palette()->text_weak; String8 name = rd_name_from_ctrl_entity(arena, entity); @@ -401,8 +401,9 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) && ctrl_entity_tree_is_frozen(entity)) + UI_TagF("bad") { - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->background_bad); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_Locked], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } @@ -585,19 +586,8 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t F32 t = pow_f32(sin_f32((F32)rd_state->time_in_seconds / 1.8f), 2.f); F64 v = 1.f - abs_f32(0.5f - t); - // rjf: colors - Vec4F32 bg_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackground); - Vec4F32 bd_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBorder); - Vec4F32 hl_color = rd_rgba_from_theme_color(RD_ThemeColor_BaseBackgroundPop); - bg_color.w *= loading_t; - bd_color.w *= loading_t; - hl_color.w *= loading_t; - - // rjf: grab animation params - F32 bg_work_indicator_t = 1.f; - // rjf: build indicator - UI_CornerRadius(height/3.f) + UI_CornerRadius(height/3.f) UI_Transparency(1-loading_t) { // rjf: rects Rng2F32 indicator_region_rect = @@ -615,42 +605,35 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t indicator_rect = pad_2f32(indicator_rect, -1.f); // rjf: does the view have loading *progress* info? -> draw extra progress layer - if(progress_v != progress_v_target) + if(progress_v != progress_v_target) UI_TagF("drop_site") { F64 pct_done_f64 = ((F64)progress_v/(F64)progress_v_target); F32 pct_done = (F32)pct_done_f64; - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = v4f32(1, 1, 1, 0.2f*loading_t))); - ui_set_next_fixed_x(indicator_region_rect.x0); - ui_set_next_fixed_y(indicator_region_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_region_rect).x*pct_done); - ui_set_next_fixed_height(dim_2f32(indicator_region_rect).y); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + Rng2F32 pct_rect = r2f32p(indicator_region_rect.x0, + indicator_region_rect.y0, + indicator_region_rect.x0 + (indicator_region_rect.x1 - indicator_region_rect.x0)*pct_done, + indicator_region_rect.y1); + UI_Rect(pct_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); } // rjf: fill - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = hl_color)); - ui_set_next_fixed_x(indicator_rect.x0); - ui_set_next_fixed_y(indicator_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_rect).x); - ui_set_next_fixed_height(dim_2f32(indicator_rect).y); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + UI_TagF("pop") UI_Rect(indicator_rect) + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); // rjf: animated bar - ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = bd_color, .background = bg_color)); - ui_set_next_fixed_x(indicator_region_rect.x0); - ui_set_next_fixed_y(indicator_region_rect.y0); - ui_set_next_fixed_width(dim_2f32(indicator_region_rect).x); - ui_set_next_fixed_height(dim_2f32(indicator_region_rect).y); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY|UI_BoxFlag_Clickable, "bg_system_status"); - UI_Signal sig = ui_signal_from_box(box); + UI_Rect(indicator_region_rect) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_Floating|UI_BoxFlag_Clickable, "bg_system_status"); + UI_Signal sig = ui_signal_from_box(box); + } } // rjf: build background - UI_WidthFill UI_HeightFill + UI_WidthFill UI_HeightFill UI_Transparency(1-loading_t) UI_BlurSize(10.f*loading_t) { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = bg_color)); ui_set_next_blur_size(10.f*loading_t); - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_Floating, ui_key_zero()); } } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 074c0439..b60eb9ce 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -795,7 +795,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->build_box_count = 0; ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; - ui_state->default_animation_rate = 1 - pow_f32(2, (-80.f * ui_state->animation_dt)); + ui_state->default_animation_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); ui_state->tooltip_can_overflow_window = 0; ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; ui_state->tags_cache_slots_count = 512; @@ -2550,11 +2550,11 @@ internal void ui_box_equip_display_string(UI_Box *box, String8 string) { ProfBeginFunction(); - Vec4F32 text_color = ui_color_from_name(str8_lit("text")); box->string = push_str8_copy(ui_build_arena(), string); box->flags |= UI_BoxFlag_HasDisplayString; if(box->flags & UI_BoxFlag_DrawText && (box->fastpath_codepoint == 0 || !(box->flags & UI_BoxFlag_DrawTextFastpathCodepoint))) { + Vec4F32 text_color = ui_color_from_name(str8_lit("text")); String8 display_string = ui_box_display_string(box); DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; @@ -2564,6 +2564,7 @@ ui_box_equip_display_string(UI_Box *box, String8 string) else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { Temp scratch = scratch_begin(0, 0); + Vec4F32 text_color = ui_color_from_name(str8_lit("text")); String8 display_string = ui_box_display_string(box); String32 fpcp32 = str32(&box->fastpath_codepoint, 1); String8 fpcp = str8_from_32(scratch.arena, fpcp32); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index ade38b1c..e36562e4 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -383,32 +383,28 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_DrawDropShadow (UI_BoxFlags)(1ull<<27) # define UI_BoxFlag_DrawBackgroundBlur (UI_BoxFlags)(1ull<<28) # define UI_BoxFlag_DrawBackground (UI_BoxFlags)(1ull<<29) -# define UI_BoxFlag_DrawAlt (UI_BoxFlags)(1ull<<30) -# define UI_BoxFlag_DrawGood (UI_BoxFlags)(1ull<<31) -# define UI_BoxFlag_DrawBad (UI_BoxFlags)(1ull<<32) -# define UI_BoxFlag_DrawPop (UI_BoxFlags)(1ull<<33) -# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<34) -# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<35) -# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<36) -# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<37) -# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<38) -# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<39) -# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<40) -# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<41) -# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<42) -# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<43) -# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<44) -# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<45) -# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<46) -# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<47) -# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<48) -# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<49) -# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<50) -# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<51) -# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<52) -# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<53) -# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<54) -# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<55) +# define UI_BoxFlag_DrawBorder (UI_BoxFlags)(1ull<<30) +# define UI_BoxFlag_DrawSideTop (UI_BoxFlags)(1ull<<31) +# define UI_BoxFlag_DrawSideBottom (UI_BoxFlags)(1ull<<32) +# define UI_BoxFlag_DrawSideLeft (UI_BoxFlags)(1ull<<33) +# define UI_BoxFlag_DrawSideRight (UI_BoxFlags)(1ull<<34) +# define UI_BoxFlag_DrawText (UI_BoxFlags)(1ull<<35) +# define UI_BoxFlag_DrawTextFastpathCodepoint (UI_BoxFlags)(1ull<<36) +# define UI_BoxFlag_DrawTextWeak (UI_BoxFlags)(1ull<<37) +# define UI_BoxFlag_DrawHotEffects (UI_BoxFlags)(1ull<<38) +# define UI_BoxFlag_DrawActiveEffects (UI_BoxFlags)(1ull<<39) +# define UI_BoxFlag_DrawOverlay (UI_BoxFlags)(1ull<<40) +# define UI_BoxFlag_DrawBucket (UI_BoxFlags)(1ull<<41) +# define UI_BoxFlag_Clip (UI_BoxFlags)(1ull<<42) +# define UI_BoxFlag_AnimatePosX (UI_BoxFlags)(1ull<<43) +# define UI_BoxFlag_AnimatePosY (UI_BoxFlags)(1ull<<44) +# define UI_BoxFlag_DisableTextTrunc (UI_BoxFlags)(1ull<<45) +# define UI_BoxFlag_DisableIDString (UI_BoxFlags)(1ull<<46) +# define UI_BoxFlag_DisableFocusBorder (UI_BoxFlags)(1ull<<47) +# define UI_BoxFlag_DisableFocusOverlay (UI_BoxFlags)(1ull<<48) +# define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<49) +# define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<50) +# define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) From 26514ddc6a9de50a45a139666ce6cd3d9c40601d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 11:35:30 -0800 Subject: [PATCH 147/755] dead code elimination --- src/raddbg/raddbg_core.c | 660 --------------------------------------- 1 file changed, 660 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a351afb5..380ab03c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4749,559 +4749,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } } - //////////////////////////// - //- rjf: build listers - // -#if 0 // TODO(rjf): @cfg - //- rjf: do query lister stack controls - if(ws->top_query_lister != 0) - { - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - if(ui_slot_press(UI_EventActionSlot_Accept)) - { - Temp scratch = scratch_begin(0, 0); - RD_RegsScope() - { - //rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); - } - scratch_end(scratch); - } - } - for(ListerTask *task = first_lister_task; task != 0; task = task->next) - { - DI_Scope *di_scope = di_scope_open(); - - ////////////////////////// - //- rjf: unpack - // - RD_Lister *lister = task->lister; - RD_ListerFlags flags = lister->regs->lister_flags; - UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); - - ////////////////////////// - //- rjf: parameters -> lister items - // - RD_ListerItemArray item_array = rd_lister_item_array_from_regs_needle_cursor_off(scratch.arena, lister->regs, str8(lister->input_buffer, lister->input_string_size), lister->input_cursor.column-1); - - ////////////////////////// - //- rjf: selected item hash -> cursor - // - Vec2S64 cursor = {0}; - for EachIndex(idx, item_array.count) - { - RD_ListerItem *item = &item_array.v[idx]; - U64 hash = rd_hash_from_lister_item(item); - if(hash == lister->selected_item_hash) - { - cursor.y = (S64)(idx+1); - break; - } - } - - ////////////////////////// - //- rjf: push autocompletion hint - // - if(1 <= cursor.y && cursor.y <= item_array.count) - { - RD_ListerItem *item = &item_array.v[cursor.y-1]; - if(item->flags & RD_ListerItemFlag_Autocompletion) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } - } - - ////////////////////////// - //- rjf: animate values - // - F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); - F32 lister_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_open_%p", lister), 1.f); - F32 lister_num_of_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "lister_num_of_rows_%p", lister), (F32)item_array.count); - lister->scroll_pt.off -= lister->scroll_pt.off*fast_rate; - - ////////////////////////// - //- rjf: unpack build parameters - // - F32 squish = (0.25f - 0.25f*lister_open_t); - F32 transparency = (1.f - lister_open_t); - F32 row_height_px = floor_f32(ui_top_font_size()*3.f); - if(lister->regs->lister_flags & RD_ListerFlag_Descriptions) - { - row_height_px += floor_f32(ui_top_font_size()*3.f); - } - Vec2F32 content_rect_dim = dim_2f32(content_rect); - Vec2F32 content_rect_center = center_2f32(content_rect); - F32 line_edit_height_px = 0; - if(lister->regs->lister_flags & RD_ListerFlag_LineEdit) - { - line_edit_height_px = floor_f32(ui_top_font_size()*3.f); - } - line_edit_height_px = Min(line_edit_height_px, row_height_px); - F32 lister_height_max = content_rect_dim.y*0.9f; - Vec2F32 lister_dim_px = - { - content_rect_dim.x*0.5f, - line_edit_height_px + lister_num_of_rows_t*row_height_px, - }; - if(!ui_box_is_nil(anchor_box) && flags & RD_ListerFlag_SizeByAnchor) - { - lister_dim_px.x = dim_2f32(anchor_box->rect).x; - } - else if(!ui_box_is_nil(anchor_box)) - { - lister_dim_px.x = ui_top_font_size()*50.f; - } - lister_dim_px.x = Max(lister_dim_px.x, ui_top_font_size()*50.f); - lister_dim_px.y = Min(lister_dim_px.y, lister_height_max); - Vec2F32 lister_pos_px = - { - content_rect_center.x - lister_dim_px.x/2, - content_rect_center.y - content_rect_dim.y*0.9f/2, - }; - if(!ui_box_is_nil(anchor_box)) - { - lister_pos_px = v2f32(anchor_box->rect.x0 + lister->regs->off_px.x, - anchor_box->rect.y0 + lister->regs->off_px.y); - } - - ////////////////////////// - //- rjf: build top-level lister box - // - ui_set_next_fixed_x(lister_pos_px.x); - ui_set_next_fixed_y(lister_pos_px.y); - ui_set_next_pref_width(ui_px(lister_dim_px.x, 1.f)); - ui_set_next_pref_height(ui_px(lister_dim_px.y, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_corner_radius_01(ui_top_font_size()*0.25f); - ui_set_next_corner_radius_11(ui_top_font_size()*0.25f); - UI_Focus(UI_FocusKind_On) - UI_Squish(squish) - UI_Transparency(transparency) - { - lister_box = ui_build_box_from_key(UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_RoundChildrenByParent| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow| - UI_BoxFlag_DrawBackground, - task->root_key); - } - - ////////////////////////// - //- rjf: build lister line edit - // - if(flags & RD_ListerFlag_LineEdit) - UI_WidthFill - UI_Parent(lister_box) - UI_Focus(UI_FocusKind_On) - RD_Font(RD_FontSlot_Code) - { - UI_PrefHeight(ui_px(line_edit_height_px, 1.f)) - { -#if 0 // TODO(rjf): @cfg - UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, - 0, - 0, - &lister->input_cursor, - &lister->input_mark, - lister->input_buffer, - sizeof(lister->input_buffer), - &lister->input_string_size, - 0, - str8(lister->input_buffer, lister->input_string_size), - str8_lit("###lister_text_input")); -#endif - } - } - - ////////////////////////// - //- rjf: build lister contents - // - UI_ScrollListParams params = - { - .flags = UI_ScrollListFlag_All, - .dim_px = v2f32(lister_dim_px.x, lister_dim_px.y - line_edit_height_px), - .row_height_px = row_height_px, - .cursor_range = r2s64(v2s64(0, 0), v2s64(0, item_array.count)), - .item_range = r1s64(0, item_array.count), - .cursor_min_is_empty_selection[Axis2_Y] = 1, - }; - Rng1S64 visible_row_range = {0}; - UI_ScrollListSignal scroll_list_signal = {0}; - UI_WidthFill UI_HeightFill - UI_Parent(lister_box) - UI_Focus(UI_FocusKind_On) - UI_ScrollList(¶ms, &lister->scroll_pt, &cursor, 0, &visible_row_range, &scroll_list_signal) - UI_Focus(UI_FocusKind_Null) - { - UI_HoverCursor(OS_Cursor_HandPoint) - for(S64 idx = visible_row_range.min; 0 <= idx && idx < visible_row_range.max && idx < item_array.count; idx += 1) - { - RD_ListerItem *item = &item_array.v[idx]; - B32 item_is_selected = (idx == cursor.y-1); - UI_FocusHot(item_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) - { - //- rjf: build the top-level box for the item - UI_Box *item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects|UI_BoxFlag_MouseClickable, "autocomp_%I64x", idx); - - //- rjf: build item contents - UI_Parent(item_box) UI_Padding(ui_em(1.f, 1.f)) - { - // rjf: icon - if(item->icon_kind != RD_IconKind_Null) - UI_PrefWidth(ui_em(2.f, 1.f)) - UI_Column - UI_Padding(ui_pct(1, 0)) - RD_Font(RD_FontSlot_Icons) - { - ui_label(rd_icon_kind_text_table[item->icon_kind]); - } - - // rjf: name / description - UI_Column UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) - { - // rjf: name - UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TextAlignment(UI_TextAlign_Center) - { - // rjf: display name - RD_Font(item->flags & RD_ListerItemFlag_IsNonCode ? RD_FontSlot_Main : RD_FontSlot_Code) - { - UI_Box *box = item->flags & RD_ListerItemFlag_IsNonCode ? ui_label(item->display_name).box : rd_code_label(1.f, 0, ui_top_palette()->text, item->display_name); - ui_box_equip_fuzzy_match_ranges(box, &item->display_name__matches); - } - - // rjf: kind name - if(flags & RD_ListerFlag_KindLabel && item->kind_name.size != 0) - { - ui_spacer(ui_em(1.f, 1.f)); - UI_CornerRadius(ui_top_font_size()*0.5f) - { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_flags(UI_BoxFlag_DrawBorder); - UI_Row UI_Padding(ui_em(0.5f, 1.f)) UI_TagF("weak") - { - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_string(box, item->kind_name); - } - } - } - } - - // rjf: description - if(flags & RD_ListerFlag_Descriptions) - { - if(item->description.size != 0) UI_WidthFill UI_Row UI_PrefWidth(ui_text_dim(1, 0)) UI_TagF("weak") - { - UI_Box *box = ui_label(item->description).box; - ui_box_equip_fuzzy_match_ranges(box, &item->description__matches); - } - } - } - - // rjf: bindings - if(item->flags & RD_ListerItemFlag_Bindings) UI_Focus(UI_FocusKind_Off) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_NamedColumn(str8_lit("binding_column")) UI_Padding(ui_px(row_height_px/4.f, 0.f)) - { - ui_set_next_flags(UI_BoxFlag_Clickable); - UI_NamedRow(str8_lit("binding_row")) - { - rd_cmd_binding_buttons(item->string); - } - } - } - } - - //- rjf: do interaction with top-level item - UI_Signal item_sig = ui_signal_from_box(item_box); - if(ui_clicked(item_sig)) - { -#if 0 // TODO(rjf): @cfg_lister - UI_Event move_back_evt = zero_struct; - move_back_evt.kind = UI_EventKind_Navigate; - move_back_evt.flags = UI_EventFlag_KeepMark; - move_back_evt.delta_2s32.x = -(S32)query_word.size; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &move_back_evt); - UI_Event paste_evt = zero_struct; - paste_evt.kind = UI_EventKind_Text; - paste_evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &paste_evt); - lister_box->default_nav_focus_hot_key = lister_box->default_nav_focus_active_key = lister_box->default_nav_focus_next_hot_key = lister_box->default_nav_focus_next_active_key = ui_key_zero(); -#endif - } - else if(item_box->flags & UI_BoxFlag_FocusHot && !(item_box->flags & UI_BoxFlag_FocusHotDisabled)) - { - UI_Event evt = zero_struct; - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = item->string; - ui_event_list_push(ui_build_arena(), &ws->ui_events, &evt); - } - } - } - } - - ////////////////////////// - //- rjf: cursor -> selected item hash - // - if(1 <= cursor.y && cursor.y <= item_array.count) - { - RD_ListerItem *item = &item_array.v[cursor.y-1]; - U64 hash = rd_hash_from_lister_item(item); - lister->selected_item_hash = hash; - } - else - { - lister->selected_item_hash = 0; - } - - di_scope_close(di_scope); - } -#endif - -#if 0 // TODO(rjf): @cfg_lister - //////////////////////////// - //- rjf: prepare query state for the in-progress query command - // - if(ws->query_cmd_name.size != 0) - { - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(ws->query_cmd_name); - RD_RegSlot missing_slot = cmd_kind_info->query.slot; - - //- rjf: if our input is stale, w.r.t. the current query command, initialize input state - if(ws->query_input_gen < ws->query_cmd_gen) - { - ws->query_input_gen = ws->query_cmd_gen; - String8 default_query_input = {0}; - ws->query_input_string_size = Min(sizeof(ws->query_input_buffer), default_query_input.size); - MemoryCopy(ws->query_input_buffer, default_query_input.str, ws->query_input_string_size); - ws->query_input_cursor = ws->query_input_mark = txt_pt(1, ws->query_input_string_size+1); - } - -#if 0 // TODO(rjf): @cfg_lister (query state prep) - String8 query_view_name = cmd_kind_info->query.view_name; - if(query_view_name.size == 0) - { - switch(missing_slot) - { - default:{}break; - case RD_RegSlot_Thread: - case RD_RegSlot_Module: - case RD_RegSlot_Process: - case RD_RegSlot_Machine: - case RD_RegSlot_CtrlEntity:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_CtrlEntityLister].string;}break; - case RD_RegSlot_Entity: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_EntityList:{query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_EntityLister].string;}break; - case RD_RegSlot_FilePath: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_FileSystem].string;}break; - case RD_RegSlot_PID: {query_view_name = rd_view_rule_kind_info_table[RD_ViewRuleKind_SystemProcesses].string;}break; - } - } - RD_ViewRuleInfo *view_spec = rd_view_rule_info_from_string(query_view_name); - if(!str8_match(ws->query_view_stack_top->string, view_spec->string, 0) || - ws->query_view_stack_top == &rd_nil_cfg) - { - Temp scratch = scratch_begin(0, 0); - - // rjf: clear existing query stack - rd_cfg_release(ws->query_view_stack_top); - - // rjf: determine default query - String8 default_query = {0}; - switch(missing_slot) - { - default: - if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) - { - default_query = rd_push_search_string(scratch.arena); - }break; - case RD_RegSlot_FilePath: - { - default_query = path_normalized_from_string(scratch.arena, rd_state->current_path); - default_query = push_str8f(scratch.arena, "%S/", default_query); - }break; - } - - // rjf: construct & push new view - RD_Cfg *bucket = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); - RD_Cfg *view = rd_cfg_new(bucket, view_spec->string); - RD_Cfg *filter = rd_cfg_new(view, str8_lit("filter")); - rd_cfg_new(filter, default_query); - RD_ViewState *view_state = rd_view_state_from_cfg(view); - view_state->filter_cursor = txt_pt(1, default_query.size+1); - if(cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) - { - view_state->filter_mark = txt_pt(1, 1); - } - ws->query_view_stack_top = view; - ws->query_view_selected = 1; - - scratch_end(scratch); - } -#endif - } - - //////////////////////////// - //- rjf: build query - // - if(query_is_open) - UI_Focus((window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && ws->query_input_selected) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Palette(RD_PaletteCode_Floating) - { - String8 query_cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *query_cmd_info = rd_cmd_kind_info_from_string(query_cmd_name); - RD_Query *query = &query_cmd_info->query; - F32 query_view_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###%p_query_view_t", ws), 1.f); - F32 query_squish = 0.25f - query_view_t*0.25f; - F32 query_transparency = 1.f - query_view_t; - - //- rjf: calculate rectangles - Vec2F32 window_center = center_2f32(window_rect); - Vec2F32 query_input_dim = v2f32(dim_2f32(window_rect).x*0.5f, ui_top_font_size()*3.f); - F32 query_input_margin = ui_top_font_size()*8.f; - Rng2F32 query_input_rect = r2f32p(window_center.x - query_input_dim.x/2, - window_rect.y0 + query_input_margin, - window_center.x + query_input_dim.x/2, - window_rect.y0 + query_input_margin + query_input_dim.y); - - //- rjf: build floating query container - UI_Box *query_container_box = &ui_nil_box; - UI_Rect(query_input_rect) - UI_CornerRadius00(ui_top_font_size()*0.2f) - UI_CornerRadius10(ui_top_font_size()*0.2f) - UI_ChildLayoutAxis(Axis2_Y) - UI_Squish(query_squish) - UI_Transparency(query_transparency) - { - query_container_box = ui_build_box_from_stringf(UI_BoxFlag_Floating| - UI_BoxFlag_AllowOverflow| - UI_BoxFlag_Clickable| - UI_BoxFlag_Clip| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DrawDropShadow, - "query_container"); - } - - //- rjf: set up autocompletion lister info - if(ui_is_focus_active()) - { - rd_set_autocomp_lister_query(.anchor_key = query_container_box->key, - .anchor_off = v2f32(0, dim_2f32(query_container_box->rect).y - dim_2f32(query_container_box->rect).y*(1-query_view_t)*0.25f - 2.f), - .flags = 0xffffffff, - .input = str8(ws->query_input_buffer, ws->query_input_string_size), - .cursor_off = ws->query_input_cursor.column-1, - .squish = query_squish, - .transparency= query_transparency); - } - - //- rjf: build query text input - B32 query_completed = 0; - B32 query_cancelled = 0; - UI_Parent(query_container_box) - UI_WidthFill UI_HeightFill - UI_Focus(UI_FocusKind_On) - { - ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); - UI_Row - { - UI_PrefWidth(ui_text_dim(0.f, 1.f)) UI_Padding(ui_em(1.f, 1.f)) - { - RD_IconKind icon_kind = query_cmd_info->icon_kind; - if(icon_kind != RD_IconKind_Null) - { - RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[icon_kind]); - } - ui_labelf("%S", query_cmd_info->display_name); - } - RD_Font((query->flags & RD_QueryFlag_CodeInput) ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_Border| - (RD_LineEditFlag_CodeContents * !!(query->flags & RD_QueryFlag_CodeInput)), - 0, - 0, - &ws->query_input_cursor, - &ws->query_input_mark, - ws->query_input_buffer, - sizeof(ws->query_input_buffer), - &ws->query_input_string_size, - 0, - str8(ws->query_input_buffer, ws->query_input_string_size), - str8_lit("###query_text_input")); - if(ui_pressed(sig)) - { - ws->query_input_selected = 1; - } - } - UI_PrefWidth(ui_em(5.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PositivePopButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "##complete_query"))) - { - query_completed = 1; - } - } - UI_PrefWidth(ui_em(3.f, 1.f)) UI_Focus(UI_FocusKind_Off) RD_Palette(RD_PaletteCode_PlainButton) - { - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "##cancel_query"))) - { - query_cancelled = 1; - } - } - } - } - - //- rjf: query submission - if(((ui_is_focus_active() || (window_is_focused && !ui_any_ctx_menu_is_open() && !ws->menu_bar_focused && !ws->query_input_selected)) && - ui_slot_press(UI_EventActionSlot_Cancel)) || query_cancelled) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - if((ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) || query_completed) - { - Temp scratch = scratch_begin(0, 0); - RD_RegsScope() - { - rd_regs_fill_slot_from_string(query->slot, str8(ws->query_input_buffer, ws->query_input_string_size)); - rd_cmd(RD_CmdKind_CompleteQuery); - } - scratch_end(scratch); - } - - //- rjf: take fallthrough interaction in query view - { - UI_Signal sig = ui_signal_from_box(query_container_box); - if(ui_pressed(sig)) - { - ws->query_input_selected = 1; - } - } - } - else - { - ws->query_input_selected = 0; - } - - //////////////////////////// - //- rjf: darken lower layer ui when query is selected - // - F32 query_input_selected_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%p_query_input_selected", ws), (F32)!!ws->query_input_selected); - UI_Palette(ui_build_palette(0, .background = mix_4f32(rd_rgba_from_theme_color(RD_ThemeColor_InactivePanelOverlay), v4f32(0, 0, 0, 0), 1-query_input_selected_t))) - UI_Rect(window_rect) - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } -#endif - //////////////////////////// //- rjf: top-level registers context menu // @@ -7372,66 +6819,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The ui_signal_from_box(catchall_drop_site); } - ////////////////////////// - //- rjf: build filtering box - // -#if 0 // TODO(rjf): @cfg - { - RD_Cfg *view = selected_tab; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); - RD_ViewState *view_state = rd_view_state_from_cfg(view); - UI_Focus(UI_FocusKind_On) RD_RegsScope(.view = view->id) - { - if(view_state->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) - { - rd_cmd(RD_CmdKind_ApplyFilter); - } - if(view_state->is_filtering || selected_tab_is_filtering_t > 0.01f) - { - UI_Box *filter_box = &ui_nil_box; - UI_Rect(filter_rect) - { - ui_set_next_child_layout_axis(Axis2_X); - filter_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip|UI_BoxFlag_DrawBorder, "filter_box_%p", view); - } - UI_Parent(filter_box) UI_WidthFill UI_HeightFill - { - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TagF("weak") - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - ui_label(str8_lit("Filter")); - } - ui_spacer(ui_em(0.5f, 1.f)); - RD_Font(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode ? RD_FontSlot_Code : RD_FontSlot_Main) - UI_Focus(view_state->is_filtering ? UI_FocusKind_On : UI_FocusKind_Off) - UI_TextPadding(ui_top_font_size()*0.5f) - { - UI_Signal sig = rd_line_edit(RD_LineEditFlag_CodeContents*!!(view_rule_info->flags & RD_ViewRuleInfoFlag_FilterIsCode), - 0, - 0, - &view_state->filter_cursor, - &view_state->filter_mark, - view_state->filter_buffer, - sizeof(view_state->filter_buffer), - &view_state->filter_string_size, - 0, - str8(view_state->filter_buffer, view_state->filter_string_size), - str8_lit("###filter_text_input")); - if(ui_pressed(sig)) - { - rd_cmd(RD_CmdKind_FocusPanel); - } - } - } - } - } - } -#endif - ////////////////////////// //- rjf: panel not selected? -> darken // @@ -7540,40 +6927,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } } - ////////////////////////// - //- rjf: take events to automatically start/end filtering, if applicable - // -#if 0 // TODO(rjf): @cfg - UI_Focus(UI_FocusKind_On) - { - RD_Cfg *view = selected_tab; - RD_ViewState *view_state = selected_tab_view_state; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view->string); - if(ui_is_focus_active() && view_rule_info->flags & RD_ViewRuleInfoFlag_TypingAutomaticallyFilters && !view_state->is_filtering) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->flags & UI_EventFlag_Paste) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_Paste); - } - else if(evt->string.size != 0 && evt->kind == UI_EventKind_Text) - { - ui_eat_event(evt); - rd_cmd(RD_CmdKind_Filter); - rd_cmd(RD_CmdKind_InsertText, .string = evt->string); - } - } - } - if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter && (view_state->filter_string_size != 0 || view_state->is_filtering) && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_ClearFilter); - } - } -#endif - ////////////////////////// //- rjf: consume panel fallthrough interaction events // @@ -12148,19 +11501,6 @@ rd_frame(void) } } - //////////////////////////// - //- rjf: sanitize the window/panel/tab tree structure - // - { - // TODO(rjf): @cfg_panels in the past, we had a spot in the rd_window_frame, - // which ensured to select tabs, if a panel had tabs but had none - // selected, and if a panel had a selected tab but it was project-filtered. - // this is effectively just fixing up unexpected malformations of the - // panel tree - because we are adopting some number of new possibilities - // of this via the cfg change, we can just actually do a single fixup - // point here. - } - //////////////////////////// //- rjf: process top-level graphical commands // From b0cff76501e955b3c7cd20b834e0b103e1d28a39 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 12:09:28 -0800 Subject: [PATCH 148/755] eliminate old palette system entirely --- src/raddbg/raddbg_core.c | 68 +--- src/raddbg/raddbg_core.h | 6 - src/raddbg/raddbg_views.c | 768 ++---------------------------------- src/raddbg/raddbg_widgets.c | 106 +++-- src/ui/generated/ui.meta.c | 18 +- src/ui/generated/ui.meta.h | 33 +- src/ui/ui.mdesk | 3 +- src/ui/ui_basic_widgets.c | 6 +- src/ui/ui_core.c | 53 +-- src/ui/ui_core.h | 93 +---- 10 files changed, 163 insertions(+), 991 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 380ab03c..56af04b3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4262,41 +4262,6 @@ rd_window_frame(void) rd_regs()->panel = panel_tree.focused->cfg->id; rd_regs()->view = panel_tree.focused->selected_tab->id; - ////////////////////////////// - //- rjf: compute ui palettes from theme - // - { - RD_Theme *current = rd_state->theme; - for EachEnumVal(RD_PaletteCode, code) - { - ws->cfg_palettes[code].null = v4f32(1, 0, 1, 1); - } -#define fill_palette(name) \ -{\ -ws->cfg_palettes[RD_PaletteCode_##name].background = current->colors[RD_ThemeColor_##name##Background];\ -ws->cfg_palettes[RD_PaletteCode_##name].background_alt = current->colors[RD_ThemeColor_##name##BackgroundAlt];\ -ws->cfg_palettes[RD_PaletteCode_##name].background_good = current->colors[RD_ThemeColor_##name##BackgroundGood];\ -ws->cfg_palettes[RD_PaletteCode_##name].background_bad = current->colors[RD_ThemeColor_##name##BackgroundBad];\ -ws->cfg_palettes[RD_PaletteCode_##name].background_pop = current->colors[RD_ThemeColor_##name##BackgroundPop];\ -ws->cfg_palettes[RD_PaletteCode_##name].border = current->colors[RD_ThemeColor_##name##Border];\ -ws->cfg_palettes[RD_PaletteCode_##name].text = current->colors[RD_ThemeColor_##name##Text];\ -ws->cfg_palettes[RD_PaletteCode_##name].text_weak = current->colors[RD_ThemeColor_##name##TextWeak];\ -ws->cfg_palettes[RD_PaletteCode_##name].hover = current->colors[RD_ThemeColor_##name##Hover];\ -ws->cfg_palettes[RD_PaletteCode_##name].focus = current->colors[RD_ThemeColor_##name##Focus];\ -ws->cfg_palettes[RD_PaletteCode_##name].cursor = current->colors[RD_ThemeColor_##name##Cursor];\ -ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_ThemeColor_##name##Selection];\ -} - fill_palette(Base); - fill_palette(MenuBar); - fill_palette(Good); - fill_palette(Bad); - fill_palette(Pop); - fill_palette(ScrollBar); - fill_palette(Tab); - fill_palette(TabInactive); - fill_palette(DropSite); - } - ////////////////////////////// //- rjf: gather listers // @@ -4359,14 +4324,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The icon_info.icon_kind_text_map[UI_IconKind_CheckFilled] = rd_icon_kind_text_table[RD_IconKind_CheckFilled]; } - // rjf: build widget palette info - UI_WidgetPaletteInfo widget_palette_info = {0}; - { - widget_palette_info.tooltip_palette = rd_palette_from_code(RD_PaletteCode_Base); - widget_palette_info.ctx_menu_palette = rd_palette_from_code(RD_PaletteCode_Base); - widget_palette_info.scrollbar_palette = rd_palette_from_code(RD_PaletteCode_ScrollBar); - } - // rjf: build animation info UI_AnimationInfo animation_info = {0}; { @@ -4379,13 +4336,12 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The } // rjf: begin & push initial stack values - ui_begin_build(ws->os, &ws->ui_events, &icon_info, ws->theme, &widget_palette_info, &animation_info, rd_state->frame_dt, rd_state->frame_dt); + ui_begin_build(ws->os, &ws->ui_events, &icon_info, ws->theme, &animation_info, rd_state->frame_dt, rd_state->frame_dt); ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_text_padding(main_font_size*0.3f); ui_push_pref_width(ui_em(20.f, 1)); ui_push_pref_height(ui_em(2.75f, 1.f)); - ui_push_palette(rd_palette_from_code(RD_PaletteCode_Base)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; if(rd_setting_b32_from_name(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} @@ -7125,9 +7081,6 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The UI_CornerRadius00(0) UI_CornerRadius01(0) { - UI_Palette *palette = ui_build_palette(ui_top_palette()); - palette->background = v4f32(0, 0, 0, 0); - ui_set_next_palette(palette); ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| @@ -7535,11 +7488,7 @@ ws->cfg_palettes[RD_PaletteCode_##name].selection = current->colors[RD_The F32 t = box->hot_t*(1-effective_active_t); // rjf: compute background color - Vec4F32 box_background_color = {0}; - if(box->flags & UI_BoxFlag_DrawBackground) - { - box_background_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("background")); - } + Vec4F32 box_background_color = box->background_color; // rjf: draw background if(box->flags & UI_BoxFlag_DrawBackground) @@ -9471,17 +9420,6 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str return color; } -//- rjf: code -> palette - -internal UI_Palette * -rd_palette_from_code(RD_PaletteCode code) -{ - RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(wcfg); - UI_Palette *result = &ws->cfg_palettes[code]; - return result; -} - //- rjf: fonts/sizes internal FNT_Tag @@ -9608,7 +9546,7 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0); DR_FStrList fstrs = {0}; - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_top_palette()->text, ui_top_font_size()}; + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; switch(event->cause) { default:{}break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index c8c5b42c..8c46be56 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -542,9 +542,6 @@ struct RD_WindowState // rjf: theme (recomputed each frame) UI_Theme *theme; - // rjf: config/settings - UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme - // rjf: dev interface state B32 dev_menu_is_open; @@ -1157,9 +1154,6 @@ internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); -//- rjf: code -> palette -internal UI_Palette *rd_palette_from_code(RD_PaletteCode code); - //- rjf: fonts/sizes internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); internal F32 rd_font_size_from_slot(RD_FontSlot slot); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9ed4a54f..4d91d8a9 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1463,9 +1463,9 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { RD_CmdKind cmd_kind = (RD_CmdKind)result.eval.value.u64; String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - if(cell->px != 0) + if(cell->px != 0) UI_TagF("weak") { - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_top_palette()->text_weak, ui_top_font_size()}; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; dr_fstrs_push_new(arena, &result.fstrs, ¶ms, rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); } else @@ -1559,6 +1559,8 @@ RD_VIEW_UI_FUNCTION_DEF(watch) F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; String8 filter = rd_view_search(); + Vec4F32 pop_background_rgba = {0}; + UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); ////////////////////////////// //- rjf: decide if root should be implicit @@ -2748,7 +2750,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) // ProfBegin("determine row's flags & color palette"); UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; - UI_Palette *palette = ui_top_palette(); { if(row_is_fresh) { @@ -2770,7 +2771,6 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //////////////////////// //- rjf: build row box // - ui_set_next_palette(palette); ui_set_next_flags(disabled_flags); ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); @@ -2841,7 +2841,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //- rjf: determine cell's palette ProfBegin("determine cell's palette"); UI_BoxFlags cell_flags = 0; - UI_Palette *palette = ui_top_palette(); + Vec4F32 cell_background_color_override = {0}; String8 cell_tag = {0}; { if(cell_info.flags & RD_WatchCellFlag_IsErrored) @@ -2861,11 +2861,11 @@ RD_VIEW_UI_FUNCTION_DEF(watch) Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); if(rgba.w == 0) { - rgba = ui_top_palette()->background_pop; + rgba = pop_background_rgba; } rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); - palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); + cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; } else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && @@ -2875,11 +2875,11 @@ RD_VIEW_UI_FUNCTION_DEF(watch) Vec4F32 rgba = rd_color_from_ctrl_entity(entity); if(rgba.w == 0) { - rgba = ui_top_palette()->background_pop;; + rgba = pop_background_rgba; } rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); - palette = ui_build_palette(ui_top_palette(), .background_pop = rgba); + cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; } } @@ -2887,7 +2887,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) //- rjf: build cell UI_Box *cell_box = &ui_nil_box; - UI_Palette(palette) UI_PrefWidth(ui_px(cell_width_px, 0.f)) + UI_PrefWidth(ui_px(cell_width_px, 0.f)) { ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); @@ -2964,9 +2964,10 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) { + Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); RD_Font(RD_FontSlot_Icons) UI_Flags(UI_BoxFlag_DisableTextTrunc) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rd_color_from_ctrl_entity(row_info->callstack_thread))) + UI_TextColor(color) ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); } } @@ -3451,8 +3452,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_CornerRadius(ui_top_font_size()/3) UI_PrefWidth(ui_text_dim(10, 1)) UI_Focus(UI_FocusKind_On) - RD_Palette(RD_PaletteCode_Pop) UI_TextAlignment(UI_TextAlign_Center) + UI_TagF("pop") if(ui_clicked(ui_buttonf("Find alternative..."))) { rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_PickFile].string); @@ -3523,18 +3524,12 @@ RD_VIEW_UI_FUNCTION_DEF(text) { ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_Palette *palette = ui_top_palette(); - if(file_is_out_of_date) - { - palette = rd_palette_from_code(RD_PaletteCode_Bad); - } - UI_Palette(palette) - UI_Row + UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) UI_TagF("weak") { - if(file_is_out_of_date) + if(file_is_out_of_date) UI_TagF("bad_pop") { UI_Box *box = &ui_nil_box; RD_Font(RD_FontSlot_Icons) @@ -3856,6 +3851,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory) num_columns = ClampBot(1, num_columns); bytes_per_cell = ClampBot(1, bytes_per_cell); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + Vec4F32 selection_color = ui_color_from_name(str8_lit("selection")); + Vec4F32 border_color = ui_color_from_name(str8_lit("border")); ////////////////////////////// //- rjf: process commands @@ -4053,8 +4050,9 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // DR_FStrList byte_fstrs[256] = {0}; { - Vec4F32 full_color = ui_top_palette()->text; - Vec4F32 zero_color = ui_top_palette()->text_weak; + Vec4F32 full_color = ui_color_from_name(str8_lit("text")); + Vec4F32 zero_color = full_color; + UI_TagF("weak") zero_color = ui_color_from_name(str8_lit("text")); for(U64 idx = 0; idx < ArrayCount(byte_fstrs); idx += 1) { U8 byte = (U8)idx; @@ -4446,11 +4444,11 @@ RD_VIEW_UI_FUNCTION_DEF(memory) if(selection.min <= global_byte_idx && global_byte_idx <= selection.max) { cell_flags |= UI_BoxFlag_DrawBackground; - cell_bg_rgba = ui_top_palette()->selection; + cell_bg_rgba = selection_color; } // rjf: build - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = cell_bg_rgba)); + ui_set_next_background_color(cell_bg_rgba); UI_Box *cell_box = ui_build_box_from_key(UI_BoxFlag_DrawText|cell_flags, ui_key_zero()); ui_box_equip_display_fstrs(cell_box, &byte_fstrs[byte_value]); { @@ -4459,7 +4457,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { if(global_byte_idx == a->vaddr_range.min) UI_Parent(row_overlay_box) { - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = annotation->color)); + ui_set_next_background_color(annotation->color); ui_set_next_fixed_x(big_glyph_advance*20.f + col_idx*cell_width_px + -cell_width_px/8.f + off); ui_set_next_fixed_y((row_idx-viz_range_rows.min)*row_height_px + -cell_width_px/8.f); ui_set_next_fixed_width(cell_width_px/4.f); @@ -4528,7 +4526,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), - ui_top_palette()->selection, + selection_color, 0, 0, 1.f); } ui_box_equip_draw_bucket(ascii_box, bucket); @@ -4539,7 +4537,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) DR_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); - Vec4F32 color = ui_top_palette()->border; + Vec4F32 color = border_color; dr_rect(r2f32p(text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num-1-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num+0-row_range_bytes.min)).x + font_size/4.f, @@ -4703,7 +4701,11 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) Rng2F32 rect_cvs = rd_bitmap_canvas_from_screen_rect(draw_data->view_center_pos, draw_data->zoom, rect_scrn, rect_scrn); F32 grid_cell_size_cvs = box->font_size*10.f; F32 grid_line_thickness_px = Max(2.f, box->font_size*0.1f); - Vec4F32 grid_line_color = ui_top_palette()->background_alt; + Vec4F32 grid_line_color = {0}; + UI_TagF("alt") + { + grid_line_color = ui_color_from_name(str8_lit("background")); + } for EachEnumVal(Axis2, axis) { for(F32 v = rect_cvs.p0.v[axis] - mod_f32(rect_cvs.p0.v[axis], grid_cell_size_cvs); @@ -4993,7 +4995,7 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) text_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); DR_FStrList fstrs = {0}; { - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_top_palette()->text, ui_top_font_size()}; + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("(")); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = v4f32(1.f, 0.25f, 0.25f, 1.f), .underline_thickness = 4.f); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); @@ -5014,7 +5016,7 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) color_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "color_box"); UI_Parent(color_box) UI_PrefHeight(ui_em(1.875f, 1.f)) UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = rgba)) UI_CornerRadius(ui_top_font_size()*0.5f) + UI_BackgroundColor(rgba) UI_CornerRadius(ui_top_font_size()*0.5f) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } } @@ -5241,709 +5243,3 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) geo_scope_close(geo_scope); scratch_end(scratch); } - -//////////////////////////////// -//~ rjf: settings @view_hook_impl - -#if 0 // TODO(rjf): @cfg -typedef enum RD_SettingsItemKind -{ - RD_SettingsItemKind_CategoryHeader, - RD_SettingsItemKind_GlobalSetting, - RD_SettingsItemKind_WindowSetting, - RD_SettingsItemKind_ThemeColor, - RD_SettingsItemKind_ThemePreset, - RD_SettingsItemKind_COUNT -} -RD_SettingsItemKind; - -typedef struct RD_SettingsItem RD_SettingsItem; -struct RD_SettingsItem -{ - RD_SettingsItemKind kind; - String8 kind_string; - String8 string; - FuzzyMatchRangeList kind_string_matches; - FuzzyMatchRangeList string_matches; - RD_IconKind icon_kind; - RD_SettingCode code; - RD_ThemeColor color; - RD_ThemePreset preset; - RD_SettingsItemKind category; -}; - -typedef struct RD_SettingsItemNode RD_SettingsItemNode; -struct RD_SettingsItemNode -{ - RD_SettingsItemNode *next; - RD_SettingsItem v; -}; - -typedef struct RD_SettingsItemList RD_SettingsItemList; -struct RD_SettingsItemList -{ - RD_SettingsItemNode *first; - RD_SettingsItemNode *last; - U64 count; -}; - -typedef struct RD_SettingsItemArray RD_SettingsItemArray; -struct RD_SettingsItemArray -{ - RD_SettingsItem *v; - U64 count; -}; - -internal int -rd_qsort_compare_settings_item(RD_SettingsItem *a, RD_SettingsItem *b) -{ - int result = 0; - if(a->string_matches.count > b->string_matches.count) - { - result = -1; - } - else if(a->string_matches.count < b->string_matches.count) - { - result = +1; - } - else if(a->kind_string_matches.count > b->kind_string_matches.count) - { - result = -1; - } - else if(a->kind_string_matches.count < b->kind_string_matches.count) - { - result = +1; - } - return result; -} -#endif - -#if 0 // TODO(rjf): @cfg -RD_VIEW_RULE_UI_FUNCTION_DEF(settings) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - String8 query = string; - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - - ////////////////////////////// - //- rjf: get state - // - typedef struct RD_SettingsViewState RD_SettingsViewState; - struct RD_SettingsViewState - { - B32 initialized; - Vec2S64 cursor; - TxtPt txt_cursor; - TxtPt txt_mark; - U8 txt_buffer[1024]; - U64 txt_size; - RD_ThemeColor color_ctx_menu_color; - Vec4F32 color_ctx_menu_color_hsva; - RD_ThemePreset preset_apply_confirm; - B32 category_opened[RD_SettingsItemKind_COUNT]; - }; - RD_SettingsViewState *sv = rd_view_state(RD_SettingsViewState); - if(!sv->initialized) - { - sv->initialized = 1; - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - - ////////////////////////////// - //- rjf: gather all filtered settings items - // - RD_SettingsItemArray items = {0}; - { - RD_SettingsItemList items_list = {0}; - - //- rjf: global settings header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Global Interface Settings"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_GlobalSetting] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_GlobalSetting; - } - - //- rjf: gather all global settings - if(sv->category_opened[RD_SettingsItemKind_GlobalSetting] || query.size != 0) - { - for EachEnumVal(RD_SettingCode, code) - { - if(rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - String8 kind_string = str8_lit("Global Interface Setting"); - String8 string = rd_setting_code_display_string_table[code]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_GlobalSetting; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Window; - n->v.code = code; - } - } - } - - //- rjf: window settings header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Window Interface Settings"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_WindowSetting] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_WindowSetting; - } - - //- rjf: gather all window settings - if(sv->category_opened[RD_SettingsItemKind_WindowSetting] || query.size != 0) - { - for EachEnumVal(RD_SettingCode, code) - { - if(!rd_setting_code_default_is_per_window_table[code]) - { - continue; - } - String8 kind_string = str8_lit("Window Interface Setting"); - String8 string = rd_setting_code_display_string_table[code]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_WindowSetting; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Window; - n->v.code = code; - } - } - } - - //- rjf: theme presets header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Theme Presets"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_ThemePreset] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_ThemePreset; - } - - //- rjf: gather theme presets - if(sv->category_opened[RD_SettingsItemKind_ThemePreset] || query.size != 0) - { - for EachEnumVal(RD_ThemePreset, preset) - { - String8 kind_string = str8_lit("Theme Preset"); - String8 string = rd_theme_preset_display_string_table[preset]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_ThemePreset; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Palette; - n->v.preset = preset; - } - } - } - - //- rjf: theme colors header - if(query.size == 0) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_CategoryHeader; - n->v.string = str8_lit("Theme Colors"); - n->v.icon_kind = sv->category_opened[RD_SettingsItemKind_ThemeColor] ? RD_IconKind_DownCaret : RD_IconKind_RightCaret; - n->v.category = RD_SettingsItemKind_ThemeColor; - } - - //- rjf: gather all theme colors - if(sv->category_opened[RD_SettingsItemKind_ThemeColor] || query.size != 0) - { - for EachNonZeroEnumVal(RD_ThemeColor, color) - { - String8 kind_string = str8_lit("Theme Color"); - String8 string = rd_theme_color_display_string_table[color]; - FuzzyMatchRangeList kind_string_matches = fuzzy_match_find(scratch.arena, query, kind_string); - FuzzyMatchRangeList string_matches = fuzzy_match_find(scratch.arena, query, string); - if(string_matches.count == string_matches.needle_part_count || - kind_string_matches.count == kind_string_matches.needle_part_count) - { - RD_SettingsItemNode *n = push_array(scratch.arena, RD_SettingsItemNode, 1); - SLLQueuePush(items_list.first, items_list.last, n); - items_list.count += 1; - n->v.kind = RD_SettingsItemKind_ThemeColor; - n->v.kind_string = kind_string; - n->v.string = string; - n->v.kind_string_matches = kind_string_matches; - n->v.string_matches = string_matches; - n->v.icon_kind = RD_IconKind_Palette; - n->v.color = color; - } - } - } - - //- rjf: convert to array - items.count = items_list.count; - items.v = push_array(scratch.arena, RD_SettingsItem, items.count); - { - U64 idx = 0; - for(RD_SettingsItemNode *n = items_list.first; n != 0; n = n->next, idx += 1) - { - items.v[idx] = n->v; - } - } - } - - ////////////////////////////// - //- rjf: sort filtered settings item list - // - if(query.size != 0) - { - quick_sort(items.v, items.count, sizeof(items.v[0]), rd_qsort_compare_settings_item); - } - - ////////////////////////////// - //- rjf: produce per-color context menu keys - // - UI_Key *color_ctx_menu_keys = push_array(scratch.arena, UI_Key, RD_ThemeColor_COUNT); - { - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - color_ctx_menu_keys[color] = ui_key_from_stringf(ui_key_zero(), "###settings_color_ctx_menu_%I64x", (U64)color); - } - } - - ////////////////////////////// - //- rjf: build color context menus - // - for(RD_ThemeColor color = (RD_ThemeColor)(RD_ThemeColor_Null+1); - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - RD_Palette(RD_PaletteCode_Floating) - UI_CtxMenu(color_ctx_menu_keys[color]) - UI_Padding(ui_em(1.5f, 1.f)) - UI_PrefWidth(ui_em(28.5f, 1)) UI_PrefHeight(ui_children_sum(1.f)) - { - // rjf: build title - UI_Row - { - ui_spacer(ui_em(1.5f, 1.f)); - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) ui_label(rd_theme_color_display_string_table[color]); - } - - ui_spacer(ui_em(1.5f, 1.f)); - - // rjf: build picker - { - ui_set_next_pref_height(ui_em(22.f, 1.f)); - UI_Row UI_Padding(ui_pct(1, 0)) - { - UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - { - ui_sat_val_pickerf(sv->color_ctx_menu_color_hsva.x, &sv->color_ctx_menu_color_hsva.y, &sv->color_ctx_menu_color_hsva.z, "###settings_satval_picker"); - } - - ui_spacer(ui_em(0.75f, 1.f)); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - ui_hue_pickerf(&sv->color_ctx_menu_color_hsva.x, sv->color_ctx_menu_color_hsva.y, sv->color_ctx_menu_color_hsva.z, "###settings_hue_picker"); - - UI_PrefWidth(ui_em(1.5f, 1.f)) UI_PrefHeight(ui_em(22.f, 1.f)) UI_Flags(UI_BoxFlag_FocusNavSkip) - ui_alpha_pickerf(&sv->color_ctx_menu_color_hsva.w, "###settings_alpha_picker"); - } - } - - ui_spacer(ui_em(1.5f, 1.f)); - - // rjf: build line edits - UI_Row - UI_WidthFill - UI_Padding(ui_em(1.5f, 1.f)) - UI_PrefHeight(ui_children_sum(1.f)) - UI_Column - UI_PrefHeight(ui_em(2.25f, 1.f)) - { - Vec4F32 hsva = sv->color_ctx_menu_color_hsva; - Vec3F32 hsv = v3f32(hsva.x, hsva.y, hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - Vec4F32 rgba = v4f32(rgb.x, rgb.y, rgb.z, sv->color_ctx_menu_color_hsva.w); - String8 hex_string = hex_string_from_rgba_4f32(scratch.arena, rgba); - hex_string = push_str8f(scratch.arena, "#%S", hex_string); - String8 r_string = push_str8f(scratch.arena, "%.2f", rgba.x); - String8 g_string = push_str8f(scratch.arena, "%.2f", rgba.y); - String8 b_string = push_str8f(scratch.arena, "%.2f", rgba.z); - String8 h_string = push_str8f(scratch.arena, "%.2f", hsva.x); - String8 s_string = push_str8f(scratch.arena, "%.2f", hsva.y); - String8 v_string = push_str8f(scratch.arena, "%.2f", hsva.z); - String8 a_string = push_str8f(scratch.arena, "%.2f", rgba.w); - UI_Row RD_Font(RD_FontSlot_Code) - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("Hex"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, hex_string, "###hex_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = rgba_from_hex_string_4f32(string); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("R"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, r_string, "###r_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32((F32)f64_from_str8(string), rgba.y, rgba.z, rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("G"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, g_string, "###g_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32(rgba.x, (F32)f64_from_str8(string), rgba.z, rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("B"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, b_string, "###b_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_rgba = v4f32(rgba.x, rgba.y, (F32)f64_from_str8(string), rgba.w); - Vec4F32 new_hsva = hsva_from_rgba(new_rgba); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("H"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, h_string, "###h_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32((F32)f64_from_str8(string), hsva.y, hsva.z, hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("S"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, s_string, "###s_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, (F32)f64_from_str8(string), hsva.z, hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("V"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, v_string, "###v_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, hsva.y, (F32)f64_from_str8(string), hsva.w); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - ui_spacer(ui_em(0.75f, 1.f)); - UI_Row - { - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(4.5f, 1.f)) ui_labelf("A"); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border, 0, 0, &sv->txt_cursor, &sv->txt_mark, sv->txt_buffer, sizeof(sv->txt_buffer), &sv->txt_size, 0, a_string, "###a_edit"); - if(ui_committed(sig)) - { - String8 string = str8(sv->txt_buffer, sv->txt_size); - Vec4F32 new_hsva = v4f32(hsva.x, hsva.y, hsva.z, (F32)f64_from_str8(string)); - sv->color_ctx_menu_color_hsva = new_hsva; - } - } - } - - // rjf: commit state to theme - Vec4F32 hsva = sv->color_ctx_menu_color_hsva; - Vec3F32 hsv = v3f32(hsva.x, hsva.y, hsva.z); - Vec3F32 rgb = rgb_from_hsv(hsv); - Vec4F32 rgba = v4f32(rgb.x, rgb.y, rgb.z, sv->color_ctx_menu_color_hsva.w); - rd_state->cfg_theme_target.colors[sv->color_ctx_menu_color] = rgba; - } - } - - ////////////////////////////// - //- rjf: cancels - // - UI_Focus(UI_FocusKind_On) if(ui_is_focus_active() && sv->preset_apply_confirm < RD_ThemePreset_COUNT && ui_slot_press(UI_EventActionSlot_Cancel)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - - ////////////////////////////// - //- rjf: build items list - // - Rng1S64 visible_row_range = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - Vec2F32 rect_dim = dim_2f32(rect); - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = v2f32(rect_dim.x, rect_dim.y); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, items.count)); - scroll_list_params.item_range = r1s64(0, items.count); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &scroll_pos.y, &sv->cursor, 0, &visible_row_range, &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - for(S64 row_num = visible_row_range.min; row_num <= visible_row_range.max && row_num < items.count; row_num += 1) - { - //- rjf: unpack item - RD_SettingsItem *item = &items.v[row_num]; - UI_Palette *palette = ui_top_palette(); - Vec4F32 rgba = ui_top_palette()->text_weak; - OS_Cursor cursor = OS_Cursor_HandPoint; - Rng1S32 s32_range = {0}; - B32 is_toggler = 0; - B32 is_toggled = 0; - B32 is_slider = 0; - S32 slider_s32_val = 0; - F32 slider_pct = 0.f; - UI_BoxFlags flags = UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects; - RD_SettingVal *val_table = &rd_state->cfg_setting_vals[RD_CfgSrc_User][0]; - switch(item->kind) - { - case RD_SettingsItemKind_COUNT:{}break; - case RD_SettingsItemKind_CategoryHeader: - { - cursor = OS_Cursor_HandPoint; - flags = UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawHotEffects; - }break; - case RD_SettingsItemKind_ThemePreset: - { - Vec4F32 *colors = rd_theme_preset_colors_table[item->preset]; - Vec4F32 bg_color = colors[RD_ThemeColor_BaseBackground]; - Vec4F32 tx_color = colors[RD_ThemeColor_Text]; - Vec4F32 tw_color = colors[RD_ThemeColor_TextWeak]; - Vec4F32 bd_color = colors[RD_ThemeColor_BaseBorder]; - palette = ui_build_palette(ui_top_palette(), - .text = tx_color, - .text_weak = tw_color, - .border = bd_color, - .background = bg_color); - }break; - case RD_SettingsItemKind_ThemeColor: - { - rgba = rd_rgba_from_theme_color(item->color); - }break; - case RD_SettingsItemKind_WindowSetting: - { - val_table = &window->setting_vals[0]; - }goto setting; - case RD_SettingsItemKind_GlobalSetting:{}goto setting; - setting:; - { - s32_range = rd_setting_code_s32_range_table[item->code]; - if(s32_range.min != 0 || s32_range.max != 1) - { - cursor = OS_Cursor_LeftRight; - is_slider = 1; - slider_s32_val = val_table[item->code].s32; - slider_pct = (F32)(slider_s32_val - s32_range.min) / dim_1s32(s32_range); - } - else - { - is_toggler = 1; - is_toggled = !!val_table[item->code].s32; - } - }break; - } - - //- rjf: build item widget - UI_Box *item_box = &ui_nil_box; - UI_Row - { - if(query.size == 0 && item->kind != RD_SettingsItemKind_CategoryHeader) - { - ui_set_next_flags(UI_BoxFlag_DrawSideLeft); - ui_spacer(ui_em(2.f, 1.f)); - } - UI_Focus(row_num+1 == sv->cursor.y ? UI_FocusKind_On : UI_FocusKind_Off) UI_Palette(palette) - { - ui_set_next_hover_cursor(cursor); - item_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|flags, "###option_%S_%S", item->kind_string, item->string); - UI_Parent(item_box) - { - if(item->icon_kind != RD_IconKind_Null) - { - UI_PrefWidth(ui_em(3.f, 1.f)) - RD_Font(RD_FontSlot_Icons) - UI_Palette(ui_build_palette(ui_top_palette(), .text = rgba)) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[item->icon_kind]); - } - if(query.size != 0 && item->kind_string.size != 0) UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DrawTextWeak, "%S", item->kind_string); - ui_box_equip_fuzzy_match_ranges(box, &item->kind_string_matches); - } - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S", item->string); - ui_box_equip_fuzzy_match_ranges(box, &item->string_matches); - } - if(is_slider) UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Flags(UI_BoxFlag_DrawTextWeak) - ui_labelf("(%i)", slider_s32_val); - UI_PrefWidth(ui_pct(slider_pct, 1.f)) UI_HeightFill UI_FixedX(0) UI_FixedY(0) - UI_Palette(ui_build_palette(ui_top_palette(), .background = rd_rgba_from_theme_color(RD_ThemeColor_HighlightOverlay))) - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } - if(is_toggler) - { - ui_spacer(ui_pct(1, 0)); - UI_PrefWidth(ui_em(2.5f, 1.f)) - RD_Font(RD_FontSlot_Icons) - UI_Flags(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[is_toggled ? RD_IconKind_CheckFilled : RD_IconKind_CheckHollow]); - } - if(item->kind == RD_SettingsItemKind_ThemePreset && sv->preset_apply_confirm == item->preset) - { - ui_spacer(ui_pct(1, 0)); - UI_PrefWidth(ui_text_dim(10, 1)) - RD_Palette(RD_PaletteCode_NegativePopButton) - UI_CornerRadius(ui_top_font_size()*0.5f) - UI_FontSize(ui_top_font_size()*0.9f) - UI_TextAlignment(UI_TextAlign_Center) - ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DrawBackground, "Click Again To Apply"); - } - } - } - } - - //- rjf: interact - UI_Signal sig = ui_signal_from_box(item_box); - if(item->kind == RD_SettingsItemKind_ThemeColor && ui_pressed(sig)) - { - Vec3F32 rgb = v3f32(rgba.x, rgba.y, rgba.z); - Vec3F32 hsv = hsv_from_rgb(rgb); - Vec4F32 hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - if(ui_ctx_menu_is_open(color_ctx_menu_keys[item->color])) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(color_ctx_menu_keys[item->color], item_box->key, v2f32(0, dim_2f32(item_box->rect).y)); - } - sv->color_ctx_menu_color = item->color; - sv->color_ctx_menu_color_hsva = v4f32(hsv.x, hsv.y, hsv.z, rgba.w); - rd_cmd(RD_CmdKind_FocusPanel); - } - if((item->kind == RD_SettingsItemKind_GlobalSetting || item->kind == RD_SettingsItemKind_WindowSetting) && - is_toggler && ui_clicked(sig)) - { - val_table[item->code].s32 ^= 1; - val_table[item->code].set = 1; - } - if((item->kind == RD_SettingsItemKind_GlobalSetting || item->kind == RD_SettingsItemKind_WindowSetting) && - is_slider && ui_dragging(sig)) - { - if(ui_pressed(sig)) - { - ui_store_drag_struct(&slider_s32_val); - } - S32 pre_drag_val = *ui_get_drag_struct(S32); - Vec2F32 delta = ui_drag_delta(); - S32 pst_drag_val = pre_drag_val + (S32)(delta.x/(ui_top_font_size()*2.f)); - pst_drag_val = clamp_1s32(s32_range, pst_drag_val); - val_table[item->code].s32 = pst_drag_val; - val_table[item->code].set = 1; - } - if(item->kind == RD_SettingsItemKind_ThemePreset && ui_clicked(sig)) - { - if(sv->preset_apply_confirm == item->preset) - { - Vec4F32 *colors = rd_theme_preset_colors_table[item->preset]; - MemoryCopy(rd_state->cfg_theme_target.colors, colors, sizeof(rd_state->cfg_theme_target.colors)); - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - else - { - sv->preset_apply_confirm = item->preset; - } - } - if(item->kind != RD_SettingsItemKind_ThemePreset && ui_pressed(sig)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - if(item->kind != RD_SettingsItemKind_ThemePreset && ui_pressed(sig)) - { - sv->preset_apply_confirm = RD_ThemePreset_COUNT; - } - if(item->kind == RD_SettingsItemKind_CategoryHeader && ui_pressed(sig)) - { - sv->category_opened[item->category] ^= 1; - } - } - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} -#endif diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 4edd7ef6..f2404cef 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -218,10 +218,13 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } // rjf: push qualifiers - for(String8Node *n = qualifiers.first; n != 0; n = n->next) + if(qualifiers.node_count != 0) UI_TagF("weak") { - String8 string = push_str8f(arena, "<%S> ", n->string); - dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_top_palette()->text_weak); + for(String8Node *n = qualifiers.first; n != 0; n = n->next) + { + String8 string = push_str8f(arena, "<%S> ", n->string); + dr_fstrs_push_new(arena, &result, ¶ms, string, .color = ui_color_from_name(str8_lit("text"))); + } } // rjf: push file name @@ -307,7 +310,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) if(src_string.size == 0) { src_string = str8_lit("(type)"); - src_color = ui_top_palette()->text_weak; + src_color = rgba_secondary; dr_fstrs_push_new(arena, &src_fstrs, ¶ms, src_string, .color = src_color); } else RD_Font(RD_FontSlot_Code) @@ -317,7 +320,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) if(dst_string.size == 0) { dst_string = str8_lit("(view rule)"); - dst_color = ui_top_palette()->text_weak; + dst_color = rgba_secondary; dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); } else RD_Font(RD_FontSlot_Code) @@ -326,7 +329,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } dr_fstrs_concat_in_place(&result, &src_fstrs); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&result, &dst_fstrs); } @@ -341,16 +344,16 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) if(src_string.size == 0) { src_string = str8_lit("(source path)"); - src_color = ui_top_palette()->text_weak; + src_color = rgba_secondary; } if(dst_string.size == 0) { dst_string = str8_lit("(destination path)"); - dst_color = ui_top_palette()->text_weak; + dst_color = rgba_secondary; } dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_top_palette()->text_weak); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); } @@ -373,7 +376,11 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e { color = ui_color_from_name(str8_lit("text")); } - Vec4F32 secondary_color = ui_top_palette()->text_weak; + Vec4F32 secondary_color = color; + UI_TagF("weak") + { + secondary_color = ui_color_from_name(str8_lit("text")); + } String8 name = rd_name_from_ctrl_entity(arena, entity); RD_IconKind icon_kind = RD_IconKind_Null; B32 name_is_code = 0; @@ -688,21 +695,10 @@ rd_cmd_binding_buttons(String8 name) } } - //- rjf: form color palette - UI_Palette *palette = ui_top_palette(); - if(has_conflicts) - { - palette = rd_palette_from_code(RD_PaletteCode_Bad); - } - if(rebinding_active_for_this_binding) - { - palette = rd_palette_from_code(RD_PaletteCode_Pop); - } - //- rjf: build box + ui_set_next_tag(has_conflicts ? str8_lit("bad_pop") : rebinding_active_for_this_binding ? str8_lit("pop") : str8_zero()); ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); - ui_set_next_palette(palette); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| @@ -754,7 +750,7 @@ rd_cmd_binding_buttons(String8 name) //- rjf: delete button if(rebinding_active_for_this_binding) UI_PrefWidth(ui_em(2.5f, 1.f)) - RD_Palette(RD_PaletteCode_Bad) + UI_TagF("bad_pop") { ui_set_next_group_key(ui_key_zero()); UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding")); @@ -774,18 +770,12 @@ rd_cmd_binding_buttons(String8 name) str8_match(rd_state->bind_change_cmd_name, name, 0) && rd_state->bind_change_binding.key == OS_Key_Null && rd_state->bind_change_binding.modifiers == 0); - UI_Palette *palette = ui_top_palette(); - if(adding_new_binding) - { - palette = rd_palette_from_code(RD_PaletteCode_Pop); - } - RD_Font(RD_FontSlot_Icons) UI_Palette(palette) + RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") { ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); - ui_set_next_palette(palette); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable| UI_BoxFlag_DrawActiveEffects| @@ -1153,6 +1143,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 do_thread_glow = rd_setting_b32_from_name(str8_lit("thread_glow")); B32 do_bp_lines = rd_setting_b32_from_name(str8_lit("breakpoint_lines")); B32 do_bp_glow = rd_setting_b32_from_name(str8_lit("breakpoint_glow")); + Vec4F32 pop_color = {0}; + UI_TagF("pop") + { + pop_color = ui_color_from_name(str8_lit("background")); + } ////////////////////////////// //- rjf: build top-level container @@ -1180,17 +1175,20 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 *line_bg_colors = push_array(scratch.arena, Vec4F32, dim_1s64(params->line_num_range)+1); { //- rjf: color line with stopper-thread red - U64 line_idx = 0; - for(S64 line_num = params->line_num_range.min; - line_num < params->line_num_range.max; - line_num += 1, line_idx += 1) + UI_TagF("bad_pop") { - CTRL_EntityList threads = params->line_ips[line_idx]; - for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) + U64 line_idx = 0; + for(S64 line_num = params->line_num_range.min; + line_num < params->line_num_range.max; + line_num += 1, line_idx += 1) { - if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) + CTRL_EntityList threads = params->line_ips[line_idx]; + for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) { - line_bg_colors[line_idx] = ui_top_palette()->background_bad; + if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException)) + { + line_bg_colors[line_idx] = ui_color_from_name(str8_lit("background")); + } } } } @@ -1276,8 +1274,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%I64x_%p", line_num, thread); UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| @@ -1430,8 +1428,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%I64x_catchall_%p", line_num, thread); UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| @@ -1545,8 +1543,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = bp_rgba)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(bp_rgba); UI_Box *bp_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, @@ -1608,8 +1606,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = color)); ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_text_color(color); UI_Box *pin_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, @@ -1716,8 +1714,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: build line num box - ui_set_next_palette(ui_build_palette(ui_top_palette(), .text = text_color, .background = bg_color)); - ui_build_box_from_stringf(UI_BoxFlag_DrawText|(UI_BoxFlag_DrawBackground*!!has_line_info), "%I64u##line_num", line_num); + UI_TextColor(text_color) UI_BackgroundColor(bg_color) + ui_build_box_from_stringf(UI_BoxFlag_DrawText|(UI_BoxFlag_DrawBackground*!!has_line_info), "%I64u##line_num", line_num); } } } @@ -1799,7 +1797,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) - RD_Palette(RD_PaletteCode_Bad) + UI_TagF("bad_pop") { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###exception_info"); ui_box_equip_display_fstrs(box, &explanation_fstrs); @@ -1853,9 +1851,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } UI_PrefWidth(ui_em(1.5f, 1.f)) RD_Font(RD_FontSlot_Icons) - UI_Palette(ui_build_palette(ui_top_palette(), .text = pin_color)) UI_TextAlignment(UI_TextAlign_Center) UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_TextColor(pin_color) { UI_Signal sig = ui_buttonf("%S###pin_nub", rd_icon_kind_text_table[RD_IconKind_Pin]); if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) @@ -1957,7 +1955,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 line_drag_drop = 0; RD_Cfg *line_drag_cfg = &rd_nil_cfg; CTRL_Entity *line_drag_ctrl_entity = &ctrl_entity_nil; - Vec4F32 line_drag_drop_color = ui_top_palette()->background_pop; + Vec4F32 line_drag_drop_color = pop_color; { //- rjf: determine mouse drag range TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); @@ -2041,7 +2039,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_drag_drop_color = linear_from_srgba(rd_color_from_cfg(cfg)); if(line_drag_drop_color.w == 0) { - line_drag_drop_color = ui_top_palette()->background_pop; + line_drag_drop_color = pop_color; } } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) @@ -2051,7 +2049,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_drag_drop_color = rd_color_from_ctrl_entity(thread); if(line_drag_drop_color.w == 0) { - line_drag_drop_color = ui_top_palette()->background_pop; + line_drag_drop_color = pop_color; } } } @@ -2272,7 +2270,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(line_bg_color.w != 0) { ui_set_next_flags(UI_BoxFlag_DrawBackground); - ui_set_next_palette(ui_build_palette(ui_top_palette(), .background = line_bg_color)); + ui_set_next_background_color(line_bg_color); } ui_set_next_tab_size(params->tab_size); UI_Box *line_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, line_key); @@ -2362,7 +2360,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_box->rect.x0+line_num_padding_px+match_column_pixel_off_range.max+2.f, line_box->rect.y1, }; - Vec4F32 color = ui_top_palette()->background_pop; + Vec4F32 color = pop_color; if(cursor->line == line_num && needle_pos+1 <= cursor->column && cursor->column < needle_pos+params->search_query.size+1) { color.x += (1.f - color.x) * 0.5f; @@ -3243,7 +3241,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } else if(params->flags & RD_LineEditFlag_DisplayStringIsCode) { - UI_Box *box = rd_code_label(1.f, 1, ui_top_palette()->text, display_string); + UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); if(params->fuzzy_matches != 0) { ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); @@ -3283,7 +3281,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); - DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_top_palette()->text, edit_string); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); if(autocomplete_hint_string.size != 0) { String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); @@ -3305,7 +3303,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) DR_FStr *fstr = &autocomp_fstr_n->v; fstr->string = autocomplete_append_string; fstr->params.font = ui_top_font(); - fstr->params.color = ui_top_palette()->text; + fstr->params.color = ui_color_from_name(str8_lit("text")); fstr->params.color.w *= 0.5f; fstr->params.size = ui_top_font_size(); autocomp_fstr_n->next = prev_n ? prev_n->next : 0; diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index 89017afd..4748e2a6 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -20,8 +20,9 @@ #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) -#define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) #define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) +#define UI_BackgroundColor(v) DeferLoop(ui_push_background_color(v), ui_pop_background_color()) +#define UI_TextColor(v) DeferLoop(ui_push_text_color(v), ui_pop_text_color()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) @@ -52,7 +53,8 @@ internal UI_FocusKind ui_top_focus_active(void) { UI_StackTopImpl(ui_state, Focu internal U32 ui_top_fastpath_codepoint(void) { UI_StackTopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_top_group_key(void) { UI_StackTopImpl(ui_state, GroupKey, group_key) } internal F32 ui_top_transparency(void) { UI_StackTopImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_top_palette(void) { UI_StackTopImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_top_background_color(void) { UI_StackTopImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_top_text_color(void) { UI_StackTopImpl(ui_state, TextColor, text_color) } internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } @@ -82,7 +84,8 @@ internal UI_FocusKind ui_bottom_focus_active(void) { UI_StackBottomImpl(ui_state internal U32 ui_bottom_fastpath_codepoint(void) { UI_StackBottomImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_bottom_group_key(void) { UI_StackBottomImpl(ui_state, GroupKey, group_key) } internal F32 ui_bottom_transparency(void) { UI_StackBottomImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_bottom_palette(void) { UI_StackBottomImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_bottom_background_color(void) { UI_StackBottomImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_bottom_text_color(void) { UI_StackBottomImpl(ui_state, TextColor, text_color) } internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squish) } internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } @@ -112,7 +115,8 @@ internal UI_FocusKind ui_push_focus_active(UI_FocusKind v) { UI_StackPushImpl(ui internal U32 ui_push_fastpath_codepoint(U32 v) { UI_StackPushImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_push_group_key(UI_Key v) { UI_StackPushImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_push_transparency(F32 v) { UI_StackPushImpl(ui_state, Transparency, transparency, F32, v) } -internal UI_Palette* ui_push_palette(UI_Palette* v) { UI_StackPushImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal Vec4F32 ui_push_background_color(Vec4F32 v) { UI_StackPushImpl(ui_state, BackgroundColor, background_color, Vec4F32, v) } +internal Vec4F32 ui_push_text_color(Vec4F32 v) { UI_StackPushImpl(ui_state, TextColor, text_color, Vec4F32, v) } internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_push_font(FNT_Tag v) { UI_StackPushImpl(ui_state, Font, font, FNT_Tag, v) } @@ -142,7 +146,8 @@ internal UI_FocusKind ui_pop_focus_active(void) { UI_StackPopImpl(ui_state, Focu internal U32 ui_pop_fastpath_codepoint(void) { UI_StackPopImpl(ui_state, FastpathCodepoint, fastpath_codepoint) } internal UI_Key ui_pop_group_key(void) { UI_StackPopImpl(ui_state, GroupKey, group_key) } internal F32 ui_pop_transparency(void) { UI_StackPopImpl(ui_state, Transparency, transparency) } -internal UI_Palette* ui_pop_palette(void) { UI_StackPopImpl(ui_state, Palette, palette) } +internal Vec4F32 ui_pop_background_color(void) { UI_StackPopImpl(ui_state, BackgroundColor, background_color) } +internal Vec4F32 ui_pop_text_color(void) { UI_StackPopImpl(ui_state, TextColor, text_color) } internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal FNT_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } @@ -172,7 +177,8 @@ internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v) { UI_StackSetNext internal U32 ui_set_next_fastpath_codepoint(U32 v) { UI_StackSetNextImpl(ui_state, FastpathCodepoint, fastpath_codepoint, U32, v) } internal UI_Key ui_set_next_group_key(UI_Key v) { UI_StackSetNextImpl(ui_state, GroupKey, group_key, UI_Key, v) } internal F32 ui_set_next_transparency(F32 v) { UI_StackSetNextImpl(ui_state, Transparency, transparency, F32, v) } -internal UI_Palette* ui_set_next_palette(UI_Palette* v) { UI_StackSetNextImpl(ui_state, Palette, palette, UI_Palette* , v) } +internal Vec4F32 ui_set_next_background_color(Vec4F32 v) { UI_StackSetNextImpl(ui_state, BackgroundColor, background_color, Vec4F32, v) } +internal Vec4F32 ui_set_next_text_color(Vec4F32 v) { UI_StackSetNextImpl(ui_state, TextColor, text_color, Vec4F32, v) } internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, squish, F32, v) } internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal FNT_Tag ui_set_next_font(FNT_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, FNT_Tag, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index ccd7dc65..3148b82e 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -22,8 +22,9 @@ typedef struct UI_FocusActiveNode UI_FocusActiveNode; struct UI_FocusActiveNode{ typedef struct UI_FastpathCodepointNode UI_FastpathCodepointNode; struct UI_FastpathCodepointNode{UI_FastpathCodepointNode *next; U32 v;}; typedef struct UI_GroupKeyNode UI_GroupKeyNode; struct UI_GroupKeyNode{UI_GroupKeyNode *next; UI_Key v;}; typedef struct UI_TransparencyNode UI_TransparencyNode; struct UI_TransparencyNode{UI_TransparencyNode *next; F32 v;}; -typedef struct UI_PaletteNode UI_PaletteNode; struct UI_PaletteNode{UI_PaletteNode *next; UI_Palette* v;}; typedef struct UI_TagNode UI_TagNode; struct UI_TagNode{UI_TagNode *next; String8 v;}; +typedef struct UI_BackgroundColorNode UI_BackgroundColorNode; struct UI_BackgroundColorNode{UI_BackgroundColorNode *next; Vec4F32 v;}; +typedef struct UI_TextColorNode UI_TextColorNode; struct UI_TextColorNode{UI_TextColorNode *next; Vec4F32 v;}; typedef struct UI_SquishNode UI_SquishNode; struct UI_SquishNode{UI_SquishNode *next; F32 v;}; typedef struct UI_HoverCursorNode UI_HoverCursorNode; struct UI_HoverCursorNode{UI_HoverCursorNode *next; OS_Cursor v;}; typedef struct UI_FontNode UI_FontNode; struct UI_FontNode{UI_FontNode *next; FNT_Tag v;}; @@ -56,8 +57,9 @@ UI_FocusActiveNode focus_active_nil_stack_top;\ UI_FastpathCodepointNode fastpath_codepoint_nil_stack_top;\ UI_GroupKeyNode group_key_nil_stack_top;\ UI_TransparencyNode transparency_nil_stack_top;\ -UI_PaletteNode palette_nil_stack_top;\ UI_TagNode tag_nil_stack_top;\ +UI_BackgroundColorNode background_color_nil_stack_top;\ +UI_TextColorNode text_color_nil_stack_top;\ UI_SquishNode squish_nil_stack_top;\ UI_HoverCursorNode hover_cursor_nil_stack_top;\ UI_FontNode font_nil_stack_top;\ @@ -89,8 +91,9 @@ state->focus_active_nil_stack_top.v = UI_FocusKind_Null;\ state->fastpath_codepoint_nil_stack_top.v = 0;\ state->group_key_nil_stack_top.v = ui_key_zero();\ state->transparency_nil_stack_top.v = 0;\ -state->palette_nil_stack_top.v = &ui_g_nil_palette;\ state->tag_nil_stack_top.v = str8_lit("");\ +state->background_color_nil_stack_top.v = v4f32(0, 0, 0, 0);\ +state->text_color_nil_stack_top.v = v4f32(0, 0, 0, 0);\ state->squish_nil_stack_top.v = 0;\ state->hover_cursor_nil_stack_top.v = OS_Cursor_Pointer;\ state->font_nil_stack_top.v = fnt_tag_zero();\ @@ -124,8 +127,9 @@ struct { UI_FocusActiveNode *top; UI_FocusKind bottom_val; UI_FocusActiveNode *f struct { UI_FastpathCodepointNode *top; U32 bottom_val; UI_FastpathCodepointNode *free; U64 gen; B32 auto_pop; } fastpath_codepoint_stack;\ struct { UI_GroupKeyNode *top; UI_Key bottom_val; UI_GroupKeyNode *free; U64 gen; B32 auto_pop; } group_key_stack;\ struct { UI_TransparencyNode *top; F32 bottom_val; UI_TransparencyNode *free; U64 gen; B32 auto_pop; } transparency_stack;\ -struct { UI_PaletteNode *top; UI_Palette* bottom_val; UI_PaletteNode *free; U64 gen; B32 auto_pop; } palette_stack;\ struct { UI_TagNode *top; String8 bottom_val; UI_TagNode *free; U64 gen; B32 auto_pop; } tag_stack;\ +struct { UI_BackgroundColorNode *top; Vec4F32 bottom_val; UI_BackgroundColorNode *free; U64 gen; B32 auto_pop; } background_color_stack;\ +struct { UI_TextColorNode *top; Vec4F32 bottom_val; UI_TextColorNode *free; U64 gen; B32 auto_pop; } text_color_stack;\ struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; U64 gen; B32 auto_pop; } squish_stack;\ struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; U64 gen; B32 auto_pop; } hover_cursor_stack;\ struct { UI_FontNode *top; FNT_Tag bottom_val; UI_FontNode *free; U64 gen; B32 auto_pop; } font_stack;\ @@ -157,8 +161,9 @@ state->focus_active_stack.top = &state->focus_active_nil_stack_top; state->focus state->fastpath_codepoint_stack.top = &state->fastpath_codepoint_nil_stack_top; state->fastpath_codepoint_stack.bottom_val = 0; state->fastpath_codepoint_stack.free = 0; state->fastpath_codepoint_stack.auto_pop = 0;\ state->group_key_stack.top = &state->group_key_nil_stack_top; state->group_key_stack.bottom_val = ui_key_zero(); state->group_key_stack.free = 0; state->group_key_stack.auto_pop = 0;\ state->transparency_stack.top = &state->transparency_nil_stack_top; state->transparency_stack.bottom_val = 0; state->transparency_stack.free = 0; state->transparency_stack.auto_pop = 0;\ -state->palette_stack.top = &state->palette_nil_stack_top; state->palette_stack.bottom_val = &ui_g_nil_palette; state->palette_stack.free = 0; state->palette_stack.auto_pop = 0;\ state->tag_stack.top = &state->tag_nil_stack_top; state->tag_stack.bottom_val = str8_lit(""); state->tag_stack.free = 0; state->tag_stack.auto_pop = 0;\ +state->background_color_stack.top = &state->background_color_nil_stack_top; state->background_color_stack.bottom_val = v4f32(0, 0, 0, 0); state->background_color_stack.free = 0; state->background_color_stack.auto_pop = 0;\ +state->text_color_stack.top = &state->text_color_nil_stack_top; state->text_color_stack.bottom_val = v4f32(0, 0, 0, 0); state->text_color_stack.free = 0; state->text_color_stack.auto_pop = 0;\ state->squish_stack.top = &state->squish_nil_stack_top; state->squish_stack.bottom_val = 0; state->squish_stack.free = 0; state->squish_stack.auto_pop = 0;\ state->hover_cursor_stack.top = &state->hover_cursor_nil_stack_top; state->hover_cursor_stack.bottom_val = OS_Cursor_Pointer; state->hover_cursor_stack.free = 0; state->hover_cursor_stack.auto_pop = 0;\ state->font_stack.top = &state->font_nil_stack_top; state->font_stack.bottom_val = fnt_tag_zero(); state->font_stack.free = 0; state->font_stack.auto_pop = 0;\ @@ -190,8 +195,9 @@ if(state->focus_active_stack.auto_pop) { ui_pop_focus_active(); state->focus_act if(state->fastpath_codepoint_stack.auto_pop) { ui_pop_fastpath_codepoint(); state->fastpath_codepoint_stack.auto_pop = 0; }\ if(state->group_key_stack.auto_pop) { ui_pop_group_key(); state->group_key_stack.auto_pop = 0; }\ if(state->transparency_stack.auto_pop) { ui_pop_transparency(); state->transparency_stack.auto_pop = 0; }\ -if(state->palette_stack.auto_pop) { ui_pop_palette(); state->palette_stack.auto_pop = 0; }\ if(state->tag_stack.auto_pop) { ui_pop_tag(); state->tag_stack.auto_pop = 0; }\ +if(state->background_color_stack.auto_pop) { ui_pop_background_color(); state->background_color_stack.auto_pop = 0; }\ +if(state->text_color_stack.auto_pop) { ui_pop_text_color(); state->text_color_stack.auto_pop = 0; }\ if(state->squish_stack.auto_pop) { ui_pop_squish(); state->squish_stack.auto_pop = 0; }\ if(state->hover_cursor_stack.auto_pop) { ui_pop_hover_cursor(); state->hover_cursor_stack.auto_pop = 0; }\ if(state->font_stack.auto_pop) { ui_pop_font(); state->font_stack.auto_pop = 0; }\ @@ -222,8 +228,9 @@ internal UI_FocusKind ui_top_focus_active(void); internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); -internal UI_Palette* ui_top_palette(void); internal String8 ui_top_tag(void); +internal Vec4F32 ui_top_background_color(void); +internal Vec4F32 ui_top_text_color(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -253,8 +260,9 @@ internal UI_FocusKind ui_bottom_focus_active(void); internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); -internal UI_Palette* ui_bottom_palette(void); internal String8 ui_bottom_tag(void); +internal Vec4F32 ui_bottom_background_color(void); +internal Vec4F32 ui_bottom_text_color(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -284,8 +292,9 @@ internal UI_FocusKind ui_push_focus_active(UI_FocusKind v); internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); -internal UI_Palette* ui_push_palette(UI_Palette* v); internal String8 ui_push_tag(String8 v); +internal Vec4F32 ui_push_background_color(Vec4F32 v); +internal Vec4F32 ui_push_text_color(Vec4F32 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -315,8 +324,9 @@ internal UI_FocusKind ui_pop_focus_active(void); internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); -internal UI_Palette* ui_pop_palette(void); internal String8 ui_pop_tag(void); +internal Vec4F32 ui_pop_background_color(void); +internal Vec4F32 ui_pop_text_color(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -346,8 +356,9 @@ internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v); internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); -internal UI_Palette* ui_set_next_palette(UI_Palette* v); internal String8 ui_set_next_tag(String8 v); +internal Vec4F32 ui_set_next_background_color(Vec4F32 v); +internal Vec4F32 ui_set_next_text_color(Vec4F32 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index b934c760..b5945493 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -33,8 +33,9 @@ UI_StackTable: //- rjf: colors { Transparency transparency F32 0 } - { Palette palette `UI_Palette* ` `&ui_g_nil_palette` } { Tag tag String8 `str8_lit("")` 1 } + { BackgroundColor background_color Vec4F32 `v4f32(0, 0, 0, 0)` } + { TextColor text_color Vec4F32 `v4f32(0, 0, 0, 0)` } //- rjf: squish { Squish squish F32 0 } diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 2917ed6a..7a5296be 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -480,7 +480,7 @@ ui_do_color_tooltip_hsv(Vec3F32 hsv) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = v4f32(rgb.x, rgb.y, rgb.z, 1.f))) + UI_BackgroundColor(v4f32(rgb.x, rgb.y, rgb.z, 1.f)) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); @@ -519,7 +519,7 @@ ui_do_color_tooltip_hsva(Vec4F32 hsva) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_Palette(ui_build_palette(ui_top_palette(), .background = rgba)) + UI_BackgroundColor(rgba) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); @@ -1212,7 +1212,6 @@ ui_scroll_list_item_from_row(UI_ScrollListRowBlockArray *blocks, U64 row) internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices) { - ui_push_palette(ui_state->widget_palette_info.scrollbar_palette); ui_push_tag(str8_lit("scroll_bar")); //- rjf: unpack @@ -1334,7 +1333,6 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } ui_pop_tag(); - ui_pop_palette(); return new_pt; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index b60eb9ce..1ab48035 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -782,7 +782,7 @@ ui_box_from_key(UI_Key key) //~ rjf: Top-Level Building API internal void -ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) +ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt) { //- rjf: reset per-build ui state { @@ -862,7 +862,6 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U { ui_state->icon_info.icon_kind_text_map[icon_kind] = push_str8_copy(ui_build_arena(), icon_info->icon_kind_text_map[icon_kind]); } - MemoryCopyStruct(&ui_state->widget_palette_info, widget_palette_info); MemoryCopyStruct(&ui_state->animation_info, animation_info); } @@ -1923,7 +1922,6 @@ ui_tooltip_begin_base(void) ui_push_parent(ui_state->tooltip_root); ui_push_flags(0); ui_push_text_raster_flags(ui_bottom_text_raster_flags()); - ui_push_palette(ui_bottom_palette()); ui_push_tag(str8_lit(".")); ui_push_tag(str8_lit("floating")); } @@ -1933,7 +1931,6 @@ ui_tooltip_end_base(void) { ui_pop_tag(); ui_pop_tag(); - ui_pop_palette(); ui_pop_text_raster_flags(); ui_pop_flags(); ui_pop_parent(); @@ -1944,7 +1941,6 @@ internal void ui_tooltip_begin(void) { ui_tooltip_begin_base(); - ui_push_palette(ui_state->widget_palette_info.tooltip_palette); ui_set_next_squish(0.25f-ui_state->tooltip_open_t*0.25f); ui_set_next_transparency(1-ui_state->tooltip_open_t); UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow) @@ -1976,7 +1972,6 @@ ui_tooltip_end(void) ui_row_end(); UI_PrefWidth(ui_px(0, 1)) ui_spacer(ui_em(1.f, 1.f)); ui_column_end(); - ui_pop_palette(); ui_tooltip_end_base(); } @@ -2014,7 +2009,6 @@ ui_begin_ctx_menu(UI_Key key) ui_push_pref_height(ui_bottom_pref_height()); ui_push_focus_hot(UI_FocusKind_Root); ui_push_focus_active(UI_FocusKind_Root); - ui_push_palette(ui_state->widget_palette_info.ctx_menu_palette); ui_push_tag(str8_lit(".")); B32 is_open = ui_key_match(key, ui_state->ctx_menu_key) && ui_state->ctx_menu_open; if(is_open != 0) UI_TagF("floating") @@ -2029,7 +2023,6 @@ ui_begin_ctx_menu(UI_Key key) ui_state->ctx_menu_root->flags |= UI_BoxFlag_Clickable; ui_state->ctx_menu_root->corner_radii[Corner_00] = ui_state->ctx_menu_root->corner_radii[Corner_01] = ui_state->ctx_menu_root->corner_radii[Corner_10] = ui_state->ctx_menu_root->corner_radii[Corner_11] = ui_top_font_size()*0.25f; ui_state->ctx_menu_root->tags_key = ui_top_tags_key(); - ui_state->ctx_menu_root->palette = ui_top_palette(); ui_state->ctx_menu_root->blur_size = ui_top_blur_size(); ui_spacer(ui_em(1.f, 1.f)); } @@ -2046,7 +2039,6 @@ ui_end_ctx_menu(void) ui_spacer(ui_em(1.f, 1.f)); } ui_pop_tag(); - ui_pop_palette(); ui_pop_focus_active(); ui_pop_focus_hot(); ui_pop_pref_width(); @@ -2180,29 +2172,6 @@ ui_set_auto_focus_hot_key(UI_Key key) } } -//- rjf: palette forming - -internal UI_Palette * -ui_build_palette_(UI_Palette *base, UI_Palette *overrides) -{ - UI_Palette *palette = push_array(ui_build_arena(), UI_Palette, 1); - if(base != 0) - { - MemoryCopyStruct(palette, base); - } - for EachEnumVal(UI_ColorCode, code) - { - if(overrides->colors[code].x != 0 || - overrides->colors[code].y != 0 || - overrides->colors[code].z != 0 || - overrides->colors[code].w != 0) - { - palette->colors[code] = overrides->colors[code]; - } - } - return palette; -} - //- rjf: current style tags key internal UI_Key @@ -2459,7 +2428,6 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->text_align = ui_state->text_alignment_stack.top->v; box->child_layout_axis = ui_state->child_layout_axis_stack.top->v; - box->palette = ui_state->palette_stack.top->v; box->font = ui_state->font_stack.top->v; box->font_size = ui_state->font_size_stack.top->v; box->tab_size = ui_state->tab_size_stack.top->v; @@ -2479,6 +2447,22 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) { box->tags_key = ui_state->tags_key_stack_top->key; } + if(ui_state->background_color_stack.top != &ui_state->background_color_nil_stack_top) + { + box->background_color = ui_state->background_color_stack.top->v; + } + else + { + box->background_color = ui_color_from_name(str8_lit("background")); + } + if(ui_state->text_color_stack.top != &ui_state->text_color_nil_stack_top) + { + box->text_color = ui_state->text_color_stack.top->v; + } + else + { + box->text_color = ui_color_from_name(str8_lit("text")); + } } //- rjf: auto-pop all stacks @@ -2552,9 +2536,9 @@ ui_box_equip_display_string(UI_Box *box, String8 string) ProfBeginFunction(); box->string = push_str8_copy(ui_build_arena(), string); box->flags |= UI_BoxFlag_HasDisplayString; + Vec4F32 text_color = box->text_color; if(box->flags & UI_BoxFlag_DrawText && (box->fastpath_codepoint == 0 || !(box->flags & UI_BoxFlag_DrawTextFastpathCodepoint))) { - Vec4F32 text_color = ui_color_from_name(str8_lit("text")); String8 display_string = ui_box_display_string(box); DR_FStrNode fstr_n = {0, {display_string, {box->font, box->text_raster_flags, text_color, box->font_size, 0, 0}}}; DR_FStrList fstrs = {&fstr_n, &fstr_n, 1}; @@ -2564,7 +2548,6 @@ ui_box_equip_display_string(UI_Box *box, String8 string) else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { Temp scratch = scratch_begin(0, 0); - Vec4F32 text_color = ui_color_from_name(str8_lit("text")); String8 display_string = ui_box_display_string(box); String32 fpcp32 = str32(&box->fastpath_codepoint, 1); String8 fpcp = str8_from_32(scratch.arena, fpcp32); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index e36562e4..fcfcc0b2 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -233,61 +233,6 @@ struct UI_Theme U64 patterns_count; }; -//////////////////////////////// -//~ rjf: Palettes - -typedef enum UI_ColorCode -{ - UI_ColorCode_Null, - UI_ColorCode_Background, - UI_ColorCode_BackgroundAlt, - UI_ColorCode_BackgroundGood, - UI_ColorCode_BackgroundBad, - UI_ColorCode_BackgroundPop, - UI_ColorCode_Border, - UI_ColorCode_Text, - UI_ColorCode_TextWeak, - UI_ColorCode_Hover, - UI_ColorCode_Focus, - UI_ColorCode_Cursor, - UI_ColorCode_Selection, - UI_ColorCode_COUNT -} -UI_ColorCode; - -typedef struct UI_Palette UI_Palette; -struct UI_Palette -{ - union - { - Vec4F32 colors[UI_ColorCode_COUNT]; - struct - { - Vec4F32 null; - Vec4F32 background; - Vec4F32 background_alt; - Vec4F32 background_good; - Vec4F32 background_bad; - Vec4F32 background_pop; - Vec4F32 border; - Vec4F32 text; - Vec4F32 text_weak; - Vec4F32 hover; - Vec4F32 focus; - Vec4F32 cursor; - Vec4F32 selection; - }; - }; -}; - -typedef struct UI_WidgetPaletteInfo UI_WidgetPaletteInfo; -struct UI_WidgetPaletteInfo -{ - UI_Palette *tooltip_palette; - UI_Palette *ctx_menu_palette; - UI_Palette *scrollbar_palette; -}; - //////////////////////////////// //~ rjf: Animation Info @@ -449,7 +394,8 @@ struct UI_Box DR_Bucket *draw_bucket; UI_BoxCustomDrawFunctionType *custom_draw; void *custom_draw_user_data; - UI_Palette *palette; + Vec4F32 background_color; + Vec4F32 text_color; FNT_Tag font; F32 font_size; F32 tab_size; @@ -744,7 +690,6 @@ struct UI_State //- rjf: build parameters UI_IconInfo icon_info; UI_Theme *theme; - UI_WidgetPaletteInfo widget_palette_info; UI_AnimationInfo animation_info; OS_Handle window; UI_EventList *events; @@ -827,11 +772,6 @@ internal UI_Size ui_size(UI_SizeKind kind, F32 value, F32 strictness); #define ui_pct(value, strictness) ui_size(UI_SizeKind_ParentPct, value, strictness) #define ui_children_sum(strictness) ui_size(UI_SizeKind_ChildrenSum, 0.f, strictness) -//////////////////////////////// -//~ rjf: Color Scheme Type Functions - -read_only global UI_Palette ui_g_nil_palette = {0}; - //////////////////////////////// //~ rjf: Scroll Point Type Functions @@ -915,7 +855,7 @@ internal UI_Box * ui_box_from_key(UI_Key key); //////////////////////////////// //~ rjf: Top-Level Building API -internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_WidgetPaletteInfo *widget_palette_info, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); +internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); internal void ui_end_build(void); internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis); internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); @@ -954,10 +894,6 @@ internal B32 ui_is_key_auto_focus_hot(UI_Key key); internal void ui_set_auto_focus_active_key(UI_Key key); internal void ui_set_auto_focus_hot_key(UI_Key key); -//- rjf: palette forming -internal UI_Palette * ui_build_palette_(UI_Palette *base, UI_Palette *overrides); -#define ui_build_palette(base, ...) ui_build_palette_((base), &(UI_Palette){.text = v4f32(0, 0, 0, 0), __VA_ARGS__}) - //- rjf: current style tags key internal UI_Key ui_top_tags_key(void); @@ -1014,13 +950,15 @@ internal UI_Size ui_top_pref_width(void); internal UI_Size ui_top_pref_height(void); internal UI_PermissionFlags ui_top_permission_flags(void); internal UI_BoxFlags ui_top_flags(void); +internal UI_BoxFlags ui_top_omit_flags(void); internal UI_FocusKind ui_top_focus_hot(void); internal UI_FocusKind ui_top_focus_active(void); internal U32 ui_top_fastpath_codepoint(void); internal UI_Key ui_top_group_key(void); internal F32 ui_top_transparency(void); -internal UI_Palette* ui_top_palette(void); internal String8 ui_top_tag(void); +internal Vec4F32 ui_top_background_color(void); +internal Vec4F32 ui_top_text_color(void); internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal FNT_Tag ui_top_font(void); @@ -1044,13 +982,15 @@ internal UI_Size ui_bottom_pref_width(void); internal UI_Size ui_bottom_pref_height(void); internal UI_PermissionFlags ui_bottom_permission_flags(void); internal UI_BoxFlags ui_bottom_flags(void); +internal UI_BoxFlags ui_bottom_omit_flags(void); internal UI_FocusKind ui_bottom_focus_hot(void); internal UI_FocusKind ui_bottom_focus_active(void); internal U32 ui_bottom_fastpath_codepoint(void); internal UI_Key ui_bottom_group_key(void); internal F32 ui_bottom_transparency(void); -internal UI_Palette* ui_bottom_palette(void); internal String8 ui_bottom_tag(void); +internal Vec4F32 ui_bottom_background_color(void); +internal Vec4F32 ui_bottom_text_color(void); internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal FNT_Tag ui_bottom_font(void); @@ -1074,13 +1014,15 @@ internal UI_Size ui_push_pref_width(UI_Size v); internal UI_Size ui_push_pref_height(UI_Size v); internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_push_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_push_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_push_focus_active(UI_FocusKind v); internal U32 ui_push_fastpath_codepoint(U32 v); internal UI_Key ui_push_group_key(UI_Key v); internal F32 ui_push_transparency(F32 v); -internal UI_Palette* ui_push_palette(UI_Palette* v); internal String8 ui_push_tag(String8 v); +internal Vec4F32 ui_push_background_color(Vec4F32 v); +internal Vec4F32 ui_push_text_color(Vec4F32 v); internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal FNT_Tag ui_push_font(FNT_Tag v); @@ -1104,13 +1046,15 @@ internal UI_Size ui_pop_pref_width(void); internal UI_Size ui_pop_pref_height(void); internal UI_PermissionFlags ui_pop_permission_flags(void); internal UI_BoxFlags ui_pop_flags(void); +internal UI_BoxFlags ui_pop_omit_flags(void); internal UI_FocusKind ui_pop_focus_hot(void); internal UI_FocusKind ui_pop_focus_active(void); internal U32 ui_pop_fastpath_codepoint(void); internal UI_Key ui_pop_group_key(void); internal F32 ui_pop_transparency(void); -internal UI_Palette* ui_pop_palette(void); internal String8 ui_pop_tag(void); +internal Vec4F32 ui_pop_background_color(void); +internal Vec4F32 ui_pop_text_color(void); internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal FNT_Tag ui_pop_font(void); @@ -1134,13 +1078,15 @@ internal UI_Size ui_set_next_pref_width(UI_Size v); internal UI_Size ui_set_next_pref_height(UI_Size v); internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v); +internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v); internal UI_FocusKind ui_set_next_focus_hot(UI_FocusKind v); internal UI_FocusKind ui_set_next_focus_active(UI_FocusKind v); internal U32 ui_set_next_fastpath_codepoint(U32 v); internal UI_Key ui_set_next_group_key(UI_Key v); internal F32 ui_set_next_transparency(F32 v); -internal UI_Palette* ui_set_next_palette(UI_Palette* v); internal String8 ui_set_next_tag(String8 v); +internal Vec4F32 ui_set_next_background_color(Vec4F32 v); +internal Vec4F32 ui_set_next_text_color(Vec4F32 v); internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal FNT_Tag ui_set_next_font(FNT_Tag v); @@ -1186,8 +1132,9 @@ internal void ui_push_tagf(char *fmt, ...); #define UI_FastpathCodepoint(v) DeferLoop(ui_push_fastpath_codepoint(v), ui_pop_fastpath_codepoint()) #define UI_GroupKey(v) DeferLoop(ui_push_group_key(v), ui_pop_group_key()) #define UI_Transparency(v) DeferLoop(ui_push_transparency(v), ui_pop_transparency()) -#define UI_Palette(v) DeferLoop(ui_push_palette(v), ui_pop_palette()) #define UI_Tag(v) DeferLoop(ui_push_tag(v), ui_pop_tag()) +#define UI_BackgroundColor(v) DeferLoop(ui_push_background_color(v), ui_pop_background_color()) +#define UI_TextColor(v) DeferLoop(ui_push_text_color(v), ui_pop_text_color()) #define UI_Squish(v) DeferLoop(ui_push_squish(v), ui_pop_squish()) #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) From f61d87e0cef02663cf62bba94abb6c095b477ccd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 17:09:48 -0800 Subject: [PATCH 149/755] extend command info with query expressions for lister --- src/dbg_engine/dbg_engine.mdesk | 72 ++--- src/eval/eval_ir.c | 16 +- src/eval/eval_parse.c | 2 +- src/raddbg/generated/raddbg.meta.c | 444 +++++++++++++++-------------- src/raddbg/generated/raddbg.meta.h | 10 +- src/raddbg/raddbg.mdesk | 417 ++++++++++++++------------- src/raddbg/raddbg_core.c | 291 +++++++++++++------ src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_views.c | 130 ++++++--- src/raddbg/raddbg_widgets.c | 19 +- src/ui/ui_core.c | 2 + 11 files changed, 812 insertions(+), 597 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index c75666ab..86fb8111 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -4,52 +4,52 @@ //////////////////////////////// //~ rjf: Built-In Command Tables -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | \___ _________________________________/ | | | | | | -// / | | | \ / | | | | | | -D_CmdTable: // | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ _________________________________/ | | | | | | +// / | | | | \ / | | | | | | +D_CmdTable: // | | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 Cfg null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } - {LaunchAndInit 1 1 Cfg null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } - {Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } - {KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } - {Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } - {Continue 1 1 Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } - {StepIntoInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } - {StepOverInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } - {StepIntoLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } - {StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } - {StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } - {Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } - {SoftHaltRefresh 0 0 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } - {SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } + {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndInit 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } + {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } + {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } + {Continue 1 1 "" Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } + {StepIntoInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } + {StepOverInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } + {StepIntoLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } + {StepOverLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } + {StepOut 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } + {Halt 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } + {SoftHaltRefresh 0 0 "" Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } - {Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } - {Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } - {StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } - {StepOver 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } + {RunToLine 0 1 "" Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } + {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } + {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } + {StepOver 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } //- rjf: debug control context management operations - {FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } - {ThawThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } - {FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } - {ThawProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } - {FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } - {ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } - {FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } - {ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } - {FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } - {ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } + {FreezeThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } + {ThawThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } + {FreezeProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } + {ThawProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } + {FreezeMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } + {ThawMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } + {FreezeLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } + {ThawLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } + {FreezeEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration - {SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } - {SetEntityName 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } + {SetEntityColor 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } + {SetEntityName 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } //- rjf: attaching - {Attach 1 1 PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } + {Attach 1 1 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } } @enum D_CmdKind: diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e1186967..c90c7ccc 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1043,7 +1043,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); node->type_key = type_key; U8 pattern_split = '?'; - node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, 0); + node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); node->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; if(!e_type_key_match(e_type_key_zero(), type_key)) { @@ -1089,12 +1089,18 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) if(map != 0 && 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) + 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) { @@ -1103,10 +1109,6 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } scan_pos = pattern_part_pos + n->string.size; } - if(scan_pos < type_string.size) - { - fits_this_type_string = 0; - } if(fits_this_type_string) { for(E_Expr *e = auto_hook_node->tag_exprs.first; e != &e_expr_nil; e = e->next) @@ -2239,7 +2241,7 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf values case E_ExprKind_LeafValue: { - E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU128); new_tree->value = expr->value; new_tree->space = expr->space; result.root = new_tree; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 56e78ee7..df2d70af 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1940,7 +1940,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } //- rjf: upgrade atom w/ qualifier - if(resolution_qualifier.size != 0) + if(atom != &e_expr_nil && resolution_qualifier.size != 0) { atom->qualifier = resolution_qualifier; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 41f86d8c..33fac2a7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[289] = +RD_VocabInfo rd_vocab_info_table[292] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -83,6 +83,10 @@ RD_VocabInfo rd_vocab_info_table[289] = {str8_lit_comp("creation_time"), str8_lit_comp("creation_times"), str8_lit_comp("Creation Time"), str8_lit_comp("Creation Times"), RD_IconKind_Null}, {str8_lit_comp("data"), str8_lit_comp("datas"), str8_lit_comp("Data"), str8_lit_comp("Datas"), RD_IconKind_Null}, {str8_lit_comp("unattached_processes"), str8_lit_comp(""), str8_lit_comp("Unattached Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("user"), str8_lit_comp("users"), str8_lit_comp("User"), str8_lit_comp("Users"), RD_IconKind_Person}, +{str8_lit_comp("project"), str8_lit_comp("projects"), str8_lit_comp("Project"), str8_lit_comp("Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, +{str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_init"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -254,6 +258,7 @@ RD_VocabInfo rd_vocab_info_table[289] = {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -261,9 +266,7 @@ RD_VocabInfo rd_vocab_info_table[289] = {str8_lit_comp("disable_target"), str8_lit_comp(""), str8_lit_comp("Disable Target"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("register_as_jit_debugger"), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("filter"), str8_lit_comp(""), str8_lit_comp("Filter"), str8_lit_comp(""), RD_IconKind_Find}, -{str8_lit_comp("apply_filter"), str8_lit_comp(""), str8_lit_comp("Apply Filter"), str8_lit_comp(""), RD_IconKind_Find}, -{str8_lit_comp("clear_filter"), str8_lit_comp(""), str8_lit_comp("Clear Filter"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("search"), str8_lit_comp(""), str8_lit_comp("Search"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, {str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, {str8_lit_comp("target"), str8_lit_comp(""), str8_lit_comp("Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -297,7 +300,7 @@ RD_VocabInfo rd_vocab_info_table[289] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[10] = +RD_NameSchemaInfo rd_name_schema_info_table[12] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, @@ -305,6 +308,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[10] = {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}")}, +{str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, +{str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, {str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}")}, {str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, @@ -353,221 +358,220 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[212] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("commands"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:\"\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = @@ -665,6 +669,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = {str8_lit_comp("insert_text"), {OS_Key_Null, 0 }}, {str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_Modifier_Alt}}, +{str8_lit_comp("search"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_next"), {OS_Key_F3, 0 }}, @@ -678,7 +683,6 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, {str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, -{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("open_lister"), {OS_Key_F1, 0 }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("toggle_dev_menu"), {OS_Key_D, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, @@ -809,7 +813,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x446142ff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x99503dff,\n line_info_1: 0xfe8249ff,\n line_info_2: 0xffba17ff,\n line_info_3: 0xcefd69ff,\n line_info_4: 0x99503dff,\n line_info_5: 0xfe8249ff,\n line_info_6: 0xcefd69ff,\n line_info_7: 0x99503dff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x4461425f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x633112ff,\n line_info_1: 0x754e1aff,\n line_info_2: 0x75721aff,\n line_info_3: 0x48751bff,\n line_info_4: 0x732112ff,\n line_info_5: 0x754e1aff,\n line_info_6: 0x75721aff,\n line_info_7: 0x48751bff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 954e4d60..b162da04 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -223,6 +223,7 @@ RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, +RD_CmdKind_AddAutoViewRule, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -230,9 +231,7 @@ RD_CmdKind_EnableTarget, RD_CmdKind_DisableTarget, RD_CmdKind_RegisterAsJITDebugger, RD_CmdKind_FindCodeLocation, -RD_CmdKind_Filter, -RD_CmdKind_ApplyFilter, -RD_CmdKind_ClearFilter, +RD_CmdKind_Search, RD_CmdKind_GettingStarted, RD_CmdKind_Commands, RD_CmdKind_Target, @@ -569,6 +568,7 @@ struct RD_Query { RD_QueryFlags flags; RD_RegSlot slot; +String8 expr; String8 view_name; CTRL_EntityKind ctrl_entity_kind; }; @@ -624,8 +624,8 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[289]; -extern RD_NameSchemaInfo rd_name_schema_info_table[10]; +extern RD_VocabInfo rd_vocab_info_table[292]; +extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1ffe235a..1fc83808 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -95,6 +95,10 @@ RD_VocabTable: {creation_time _ "Creation Time" _ Null } {data _ "Data" _ Null } {unattached_processes "" "Unattached Processes" "" Scheduler } + {user _ "User" _ Person } + {project _ "Project" _ Briefcase } + {recent_project _ "Recent Project" _ Briefcase } + {recent_file _ "Recent File" _ FileOutline } } @struct RD_VocabInfo: @@ -212,6 +216,18 @@ RD_VocabTable: ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}```, } + //- rjf: recent projects + { + recent_project, + ```x:{'path':path}```, + } + + //- rjf: recent files + { + recent_file, + ```x:{'path':path}```, + } + //- rjf: control entities { machine, @@ -326,270 +342,271 @@ RD_RegTable: //////////////////////////////// //~ rjf: Command Table -@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | \___ _____________________________________________________/ | | | | | | -// / | | | \ / | | | | | | -RD_CmdTable: // | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ _____________________________________________________/ | | | | | | +// / | | | | \ / | | | | | | +RD_CmdTable: // | | | | | | | | | | | | { //- rjf: exiting - {Exit 1 1 Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } + {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } //- rjf: top-level lister - {OpenLister 1 1 Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } + {OpenLister 1 1 "query:lister" Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } //- rjf: command runner - {RunCommand 1 1 CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } + {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } //- rjf: os event passthrough - {OSEvent 0 0 Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } + {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } - {SelectUnwind 0 1 Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } - {UpOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } - {DownOneFrame 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } + {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 1 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } + {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } //- rjf: font sizes - {IncUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } - {DecUIFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } - {IncCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } - {DecCodeFontScale 1 1 Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } + {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } + {DecUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } + {IncCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } + {DecCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } //- rjf: windows - {OpenWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } - {CloseWindow 1 1 Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } - {ToggleFullscreen 1 1 Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } - {BringToFront 0 1 Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } + {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } + {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } + {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } //- rjf: popups - {PopupAccept 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } - {PopupCancel 0 1 Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } + {PopupAccept 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } + {PopupCancel 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } //- rjf: panel splitting - {ResetToDefaultPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } - {ResetToCompactPanels 1 1 Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } - {NewPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } - {NewPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } - {NewPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } - {NewPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } - {SplitPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } + {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } + {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } + {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } + {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } + {NewPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } + {SplitPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } //- rjf: panel rotation - {RotatePanelColumns 1 1 Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } + {RotatePanelColumns 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } //- rjf: focused panel changing - {NextPanel 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } - {PrevPanel 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } - {FocusPanel 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } - {FocusPanelRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } - {FocusPanelLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } - {FocusPanelUp 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } - {FocusPanelDown 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } + {NextPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } + {PrevPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } + {FocusPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } + {FocusPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } + {FocusPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } + {FocusPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } + {FocusPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } //- rjf: undo/redo - {Undo 0 0 Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } - {Redo 0 0 Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } + {Undo 0 0 "" Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } + {Redo 0 0 "" Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } //- rjf: focus history - {GoBack 0 0 Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } - {GoForward 0 0 Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } + {GoBack 0 0 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } + {GoForward 0 0 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } //- rjf: panel removal - {ClosePanel 1 1 Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } + {ClosePanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } //- rjf: panel tab - {FocusTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } - {NextTab 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } - {PrevTab 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } - {MoveTabRight 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } - {MoveTabLeft 1 1 Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } - {OpenTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } - {CloseTab 1 1 View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } - {MoveTab 0 0 Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } - {TabBarTop 1 1 Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } - {TabBarBottom 1 1 Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } + {FocusTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } + {NextTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } + {PrevTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } + {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } + {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } + {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } + {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } //- rjf: files - {SetCurrentPath 0 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } - {Open 1 1 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } - {Switch 1 1 Cfg null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } - {SwitchToPartnerFile 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } - {RecordFileInProject 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } - {ShowFileInExplorer 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } + {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } + {Open 1 1 `file:\\"\\"` FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } + {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } + {ShowFileInExplorer 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm - {GoToDisassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } - {GoToSource 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } + {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } + {GoToSource 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } //- rjf: override file links - {SetFileReplacementPath 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } + {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } - {OpenProject 1 1 FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } - {OpenRecentProject 1 1 Cfg null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } + {OpenUser 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes - {WriteUserData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } - {WriteProjectData 0 1 Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } + {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } + {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } //- rjf: meta controls - {Edit 1 1 Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } - {Accept 1 1 Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } - {Cancel 1 1 Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } + {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } + {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } + {Cancel 1 1 "" Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } //- rjf: directional movement & text controls - {MoveLeft 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } - {MoveRight 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } - {MoveUp 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } - {MoveDown 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } - {MoveLeftSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } - {MoveRightSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } - {MoveUpSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } - {MoveDownSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } - {MoveLeftChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } - {MoveDownPage 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } - {MoveUpWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } - {MoveDownWhole 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } - {MoveLeftChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunkSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } - {MoveDownPageSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } - {MoveUpWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } - {MoveDownWholeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } - {MoveUpReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } - {MoveDownReorder 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } - {MoveHome 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } - {MoveEnd 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } - {MoveHomeSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } - {MoveEndSelect 1 1 Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } - {SelectAll 1 1 Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } - {DeleteSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } - {DeleteChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } - {BackspaceSingle 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } - {BackspaceChunk 1 1 Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } - {Copy 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } - {Cut 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } - {Paste 1 1 Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } - {InsertText 0 1 Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } + {MoveLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } + {MoveRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } + {MoveUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } + {MoveDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } + {MoveLeftSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } + {MoveRightSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } + {MoveUpSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } + {MoveDownSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } + {MoveLeftChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } + {MoveDownPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } + {MoveUpWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } + {MoveDownWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } + {MoveLeftChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } + {MoveDownPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } + {MoveUpWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } + {MoveDownWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } + {MoveUpReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } + {MoveDownReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } + {MoveHome 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } + {MoveEnd 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } + {MoveHomeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } + {MoveEndSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } + {SelectAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } + {DeleteSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } + {DeleteChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } + {BackspaceSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } + {BackspaceChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } + {Copy 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } + {Cut 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } + {Paste 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } + {InsertText 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } //- rjf: code navigation - {GoToLine 1 1 Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } - {GoToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } - {CenterCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } - {ContainCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } - {FindTextForward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } - {FindTextBackward 1 1 String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } - {FindNext 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } - {FindPrev 1 1 Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } + {GoToLine 1 1 "" Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } + {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } + {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } + {FindTextForward 1 1 "" String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } + {FindTextBackward 1 1 "" String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } + {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } + {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } //- rjf: thread finding - {FindThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } - {FindSelectedThread 1 1 Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } + {FindThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } + {FindSelectedThread 1 1 "" Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } //- rjf: name finding - {GoToName 1 1 String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } - {GoToNameAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } + {GoToName 1 1 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } + {GoToNameAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } //- rjf: watch expressions - {ToggleWatchExpression 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } - {ToggleWatchExpressionAtCursor 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } - {ToggleWatchExpressionAtMouse 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } + {ToggleWatchExpression 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } + {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } + {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: memory view parameterization - {SetColumns 1 1 Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } + {SetColumns 1 1 "" Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } //- rjf: disassembly view parameterization - {ToggleAddressVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } - {ToggleCodeBytesVisibility 1 1 Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } + {ToggleAddressVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } + {ToggleCodeBytesVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general config operations - {EnableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } - {DisableCfg 0 0 Null null Nil Null 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } - {SelectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } - {DeselectCfg 0 0 Null null Nil Null 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } - {RemoveCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } - {NameCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } - {ConditionCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } - {DuplicateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } - {RelocateCfg 0 0 Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } + {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } + {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } + {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } - {AddAddressBreakpoint 1 0 Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {AddFunctionBreakpoint 1 0 String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } - {ToggleBreakpoint 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } - {EnableBreakpoint 1 1 Cfg null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } - {DisableBreakpoint 1 1 Cfg null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddAddressBreakpoint 1 0 "" Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {AddFunctionBreakpoint 1 0 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } + {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } - {ToggleWatchPin 1 0 String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + {AddWatchPin 1 1 "" String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 "" String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + + //- rjf: auto view rule + {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } //- rjf: line operations - {SetNextStatement 1 1 Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } + {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } - {SelectTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } - {EnableTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } - {DisableTarget 1 1 Cfg null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } + {AddTarget 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching - {RegisterAsJITDebugger 1 1 Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } + {RegisterAsJITDebugger 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } //- rjf: snap-to-code-location - {FindCodeLocation 0 1 FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } + {FindCodeLocation 0 1 "" FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } - //- rjf: general-purpose view filtering - {Filter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "filter" "Filter" "Begins filtering the active view." "sort,search,filter,find" "" } - {ApplyFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "apply_filter" "Apply Filter" "Applies the typed filter to the active view." "sort,search,filter,find,apply" "" } - {ClearFilter 1 1 Null null Nil Null 0 0 0 0 0 0 Find "clear_filter" "Clear Filter" "Clears the filter applied to the active view." "sort,search,filter,find,clear" "" } + //- rjf: searching + {Search 1 1 "" Null null Nil Null 0 0 0 0 0 0 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } //- rjf: view drivers - {GettingStarted 1 1 Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } - {Commands 0 0 Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } - {Target 0 0 Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } - {Targets 1 1 Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } - {FilePathMap 1 1 Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } - {AutoViewRules 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } - {Breakpoints 1 1 Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } - {WatchPins 1 1 Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } - {Scheduler 1 1 Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } - {CallStack 1 1 Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } - {Modules 1 1 Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } - {Watch 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } - {Locals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } - {Registers 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } - {Globals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } - {ThreadLocals 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } - {Types 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } - {Procedures 1 1 Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } - {PendingFile 0 0 Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } - {Disassembly 1 1 Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } - {Output 1 1 Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } - {Memory 1 1 Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } - {Settings 1 1 Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } + {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } + {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } + {Target 0 0 "" Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } + {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } + {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } + {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } + {Breakpoints 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } + {WatchPins 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } + {Scheduler 1 1 "" Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } + {CallStack 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } + {Modules 1 1 "" Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } + {Watch 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } + {Locals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } + {Registers 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } + {Globals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } + {ThreadLocals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } + {Types 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } + {Procedures 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } + {PendingFile 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } + {Disassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } + {Output 1 1 "" Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } + {Memory 1 1 "" Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } + {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } - {PickFolder 0 0 FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } - {PickFileOrFolder 0 0 FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } + {PickFile 0 0 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 "file:\"\"" FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 "file:\"\"" FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack - {PushQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } - {CompleteQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } - {CancelQuery 0 0 Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } + {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } + {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } + {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } //- rjf: developer commands - {ToggleDevMenu 1 1 Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } - {LogMarker 1 1 Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } + {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } + {LogMarker 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } } @enum RD_CmdKind: @@ -604,6 +621,7 @@ RD_CmdTable: // | | | | { `RD_QueryFlags flags`; `RD_RegSlot slot`; + `String8 expr`; `String8 view_name`; `CTRL_EntityKind ctrl_entity_kind`; } @@ -622,9 +640,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -757,6 +775,7 @@ RD_DefaultBindingTable: //- rjf: code navigation { "goto_line" G ctrl 0 0 } { "goto_address" G 0 0 alt } + { "search" F ctrl 0 0 } { "find_text_forward" F ctrl 0 0 } { "find_text_backward" R ctrl 0 0 } { "find_next" F3 0 0 0 } @@ -783,9 +802,6 @@ RD_DefaultBindingTable: //- rjf: attaching { "attach" F6 0 shift 0 } - //- rjf: filtering - { "filter" Slash ctrl 0 0 } - //- rjf: command lister // { "run_command" F1 0 0 0 } { "open_lister" F1 0 0 0 } @@ -990,7 +1006,8 @@ RD_ThemePresetTable: background: 0x1b1b1bff, alt: background: 0x222222ff, pop: background: 0x355b6eff, - fresh: background: 0x446142ff, + fresh: background: 0x31393dff, + match: background: 0x31393dff, border: 0x404040ff, text: 0xe5e5e5ff, weak: text: 0xa4a4a4ff, @@ -1029,14 +1046,14 @@ RD_ThemePresetTable: code_string: 0x98abb1ff, code_meta: 0xd96759ff, code_comment: 0x717171ff, - line_info_0: 0x99503dff, - line_info_1: 0xfe8249ff, - line_info_2: 0xffba17ff, - line_info_3: 0xcefd69ff, - line_info_4: 0x99503dff, - line_info_5: 0xfe8249ff, - line_info_6: 0xcefd69ff, - line_info_7: 0x99503dff, + line_info_0: 0x633112ff, + line_info_1: 0x754e1aff, + line_info_2: 0x75721aff, + line_info_3: 0x48751bff, + line_info_4: 0x732112ff, + line_info_5: 0x754e1aff, + line_info_6: 0x75721aff, + line_info_7: 0x48751bff, thread_0: 0xffcb7fff, thread_1: 0xb2ff65ff, thread_2: 0xff99e5ff, @@ -1053,7 +1070,7 @@ RD_ThemePresetTable: { background: 0x1b1b1baf, background: alt: 0x0000005f, - background: fresh: 0x4461425f, + background: fresh: 0x31393d5f, border: 0xbfbfbf1f, scroll_bar: { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 56af04b3..88902174 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -22,7 +22,11 @@ E_LOOKUP_INFO_FUNCTION_DEF(commands) { RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; String8 name = info->string; - str8_list_push(scratch.arena, &cmd_names, name); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &cmd_names, name); + } } String8Array *accel = push_array(arena, String8Array, 1); *accel = str8_array_from_list(arena, &cmd_names); @@ -36,28 +40,31 @@ E_LOOKUP_INFO_FUNCTION_DEF(commands) E_LOOKUP_ACCESS_FUNCTION_DEF(commands) { E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + if(kind == E_ExprKind_MemberAccess) { - Temp scratch = scratch_begin(&arena, 1); - String8Array *accel = (String8Array *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(rhs_value.u64 < accel->count) - { - String8 cmd_name = accel->v[rhs_value.u64]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, (U64)cmd_kind)); - result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); - result.irtree_and_type.mode = E_Mode_Value; - } - scratch_end(scratch); + String8 cmd_name = rhs->string; + result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + result.irtree_and_type.mode = E_Mode_Value; + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, e_id_from_string(cmd_name))); } return result; } +E_LOOKUP_RANGE_FUNCTION_DEF(commands) +{ + U64 out_idx = 0; + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 cmd_name = accel->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs[out_idx] = expr; + } +} + //////////////////////////////// //~ rjf: Watches Eval Hooks @@ -74,8 +81,22 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) { String8 expr = rd_expr_from_cfg(n->v); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); - if(matches.count == matches.needle_part_count) + B32 passes_filter = 1; + if(filter.size != 0) + { + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Type *type = e_type_from_key__cached(eval.type_key); + if(type->kind != E_TypeKind_Set) + { + passes_filter = 0; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); + if(matches.count == matches.needle_part_count) + { + passes_filter = 1; + } + } + } + if(passes_filter) { rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); } @@ -279,18 +300,38 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfg) cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); } + //- rjf: filter cfgs + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); + String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); + if(fuzzy_matches.count == fuzzy_matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + //- rjf: gather commands String8List cmds_list = {0}; - MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); - MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); - for MD_EachNode(cmd, collection_cmds_root->first) + if(filter.size == 0) { - str8_list_push(arena, &cmds_list, cmd->string); + MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(arena, &cmds_list, cmd->string); + } } //- rjf: package & fill RD_CfgLookupAccel *accel = push_array(arena, RD_CfgLookupAccel, 1); - accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); + accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); accel->cmds = str8_array_from_list(arena, &cmds_list); accel->cmds_idx_range = r1u64(0, accel->cmds.count); accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); @@ -345,8 +386,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfg) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - exprs[dst_idx] = e_expr_irext_array_index(arena, commands, &commands_irtree, (U64)cmd_kind-1); + exprs[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); } } @@ -582,6 +622,7 @@ typedef struct RD_UnattachedProcessesAccel RD_UnattachedProcessesAccel; struct RD_UnattachedProcessesAccel { DMN_ProcessInfo *infos; + CTRL_Entity **machines; U64 infos_count; }; @@ -591,55 +632,75 @@ E_LOOKUP_INFO_FUNCTION_DEF(unattached_processes) { Temp scratch = scratch_begin(&arena, 1); - //- rjf: evaluate lhs machine + //- rjf: evaluate lhs machine, if we have one E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); E_Interpretation lhs_interp = e_interpret(lhs_bytecode); CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + //- rjf: gather all machines we're searching through + CTRL_EntityList machines = {0}; + if(lhs_entity->kind == CTRL_EntityKind_Machine) + { + ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); + } + else + { + machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + } + //- rjf: gather system processes from this machine typedef struct Node Node; struct Node { Node *next; + CTRL_Entity *machine; DMN_ProcessInfo info; }; Node *first = 0; Node *last = 0; - if(lhs_entity->kind == CTRL_EntityKind_Machine) + U64 count = 0; + for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) { + CTRL_Entity *machine = n->v; DMN_ProcessIter iter = {0}; dmn_process_iter_begin(&iter); for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) { - Node *node = push_array(scratch.arena, Node, 1); - SLLQueuePush(first, last, node); - node->info = info; + B32 passes_filter = 1; + if(filter.size != 0) + { + passes_filter = 0; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, info.name); + FuzzyMatchRangeList pid_matches = fuzzy_match_find(scratch.arena, filter, push_str8f(scratch.arena, "%I64u", info.pid)); + if(name_matches.count == name_matches.needle_part_count || pid_matches.count == pid_matches.needle_part_count) + { + passes_filter = 1; + } + } + if(passes_filter) + { + Node *node = push_array(scratch.arena, Node, 1); + SLLQueuePush(first, last, node); + node->machine = machine; + node->info = info; + count += 1; + } } dmn_process_iter_end(&iter); } - //- rjf: list -> filtered list - Node *first_filtered = 0; - Node *last_filtered = 0; - U64 filtered_count = 0; - for(Node *n = first; n != 0; n = n->next) - { - Node *node = push_array(scratch.arena, Node, 1); - SLLQueuePush(first_filtered, last_filtered, node); - node->info = n->info; - filtered_count += 1; - } - //- rjf: list -> array - U64 infos_count = filtered_count; + U64 infos_count = count; DMN_ProcessInfo *infos = push_array(arena, DMN_ProcessInfo, infos_count); + CTRL_Entity **infos_machines = push_array(arena, CTRL_Entity *, infos_count); { U64 idx = 0; - for(Node *n = first_filtered; n != 0; n = n->next, idx += 1) + for(Node *n = first; n != 0; n = n->next, idx += 1) { infos[idx] = n->info; infos[idx].name = push_str8_copy(arena, infos[idx].name); + infos_machines[idx] = n->machine; } } @@ -647,6 +708,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(unattached_processes) RD_UnattachedProcessesAccel *accel = push_array(arena, RD_UnattachedProcessesAccel, 1); accel->infos = infos; accel->infos_count = infos_count; + accel->machines = infos_machines; info.user_data = accel; info.idxed_expr_count = infos_count; scratch_end(scratch); @@ -658,10 +720,14 @@ E_LOOKUP_RANGE_FUNCTION_DEF(unattached_processes) { RD_UnattachedProcessesAccel *accel = (RD_UnattachedProcessesAccel *)user_data; U64 out_idx = 0; + E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = accel->infos[idx].pid; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = unattached_process_type; + expr->value.u128.u64[0] = accel->infos[idx].pid; + expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); + expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); exprs[out_idx] = expr; } } @@ -723,7 +789,9 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) { CTRL_Entity *entity = n->v; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity->string); + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, 1); + String8 title_string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, title_string); if(matches.count == matches.needle_part_count) { ctrl_entity_list_push(scratch.arena, &list__filtered, entity); @@ -735,7 +803,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); *array = ctrl_entity_array_from_list(arena, &list__filtered); result.user_data = array; - result.idxed_expr_count = list.count; + result.idxed_expr_count = array->count; } scratch_end(scratch); return result; @@ -858,6 +926,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) default:{}break; case RDI_SectionKind_Procedures: { + Temp scratch = scratch_begin(&arena, 1); RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); @@ -867,12 +936,19 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) U32 type_idx = procedure->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + String8 symbol_name = {0}; + symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); + String8List strings = {0}; + e_type_lhs_string_from_key(scratch.arena, type_key, &strings, 0, 0); + str8_list_push(scratch.arena, &strings, symbol_name); + e_type_rhs_string_from_key(scratch.arena, type_key, &strings, 0); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Value; item_expr->space = module->space; item_expr->type_key = type_key; item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size); + item_expr->string = str8_list_join(arena, &strings, 0); + scratch_end(scratch); }break; case RDI_SectionKind_GlobalVariables: { @@ -2068,6 +2144,14 @@ rd_view_rule_from_cfg(RD_Cfg *cfg) return result; } +internal String8 +rd_path_from_cfg(RD_Cfg *cfg) +{ + RD_Cfg *root = rd_cfg_child_from_string(cfg, str8_lit("path")); + String8 result = root->first->string; + return result; +} + internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) { @@ -2090,8 +2174,6 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) return target; } - - internal MD_Node * rd_schema_from_name(Arena *arena, String8 name) { @@ -2410,7 +2492,8 @@ rd_ctrl_entity_from_eval_space(E_Space space) { CTRL_Entity *entity = &ctrl_entity_nil; if(space.kind == RD_EvalSpaceKind_CtrlEntity || - space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { CTRL_Handle handle; handle.machine_id = space.u64s[0]; @@ -3257,7 +3340,8 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: searching extension // - F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), !!vs->is_searching); + B32 search_row_is_open = (vs->is_searching || vs->search_string_size != 0); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); if(search_row_open_t > 0.001f) RD_Font(RD_FontSlot_Code) { //- rjf: clamp cursor @@ -3284,6 +3368,11 @@ rd_view_ui(Rng2F32 rect) //- rjf: build contents UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->is_searching ? UI_FocusKind_On : UI_FocusKind_Off) { + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } UI_TextAlignment(UI_TextAlign_Center) UI_Transparency(1-search_row_open_t) UI_PrefWidth(ui_em(2.5f, 1.f)) @@ -3299,8 +3388,13 @@ rd_view_ui(Rng2F32 rect) params.edit_buffer = vs->search_buffer; params.edit_string_size_out = &vs->search_string_size; params.edit_buffer_size = sizeof(vs->search_buffer); + params.pre_edit_value = str8(vs->search_buffer, vs->search_string_size); + } + UI_Signal sig = rd_line_editf(¶ms, "###search"); + if(ui_pressed(sig)) + { + vs->is_searching = 1; } - rd_line_editf(¶ms, "###search"); } //- rjf: commit string to view @@ -5103,16 +5197,25 @@ rd_window_frame(void) { //- rjf: unpack query parameters RD_Cfg *root = query; + RD_Cfg *cmd = rd_cfg_child_from_string(root, str8_lit("cmd")); + String8 cmd_name = cmd->first->string; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); RD_ViewState *vs = rd_view_state_from_cfg(view); vs->is_searching = 1; RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - String8 query_expression = str8_lit("procedures"); + String8 query_expression = cmd_kind_info->query.expr; rd_cfg_new_replace(expr, query_expression); E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + //- rjf: cancel + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + //- rjf: build RD_RegsScope(.view = view->id) { @@ -5162,14 +5265,13 @@ rd_window_frame(void) rd_view_ui(view_contents_container->rect); } } + + //- rjf: fallthrough interactions on container + UI_Signal sig = ui_signal_from_box(container); } } - //- rjf: do interactions - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } + //- rjf: accept if(ui_slot_press(UI_EventActionSlot_Accept)) { } @@ -6835,7 +6937,7 @@ rd_window_frame(void) } //- rjf: build empty view - UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg) + UI_Parent(view_container_box) if(selected_tab == &rd_nil_cfg && panel->parent != &rd_nil_panel_node) { ui_set_next_flags(UI_BoxFlag_DefaultFocusNav); UI_Focus(UI_FocusKind_On) UI_WidthFill UI_HeightFill UI_NamedColumn(str8_lit("empty_view")) UI_TagF("weak") @@ -7609,12 +7711,12 @@ rd_window_frame(void) max_x = (box->rect.x1-text_position.x); ellipses_run = fnt_push_run_from_string(scratch.arena, ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); } - dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); - if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) UI_TagF("pop") + if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) UI_TagF("match") { Vec4F32 match_color = ui_color_from_tags_key_name(ui_top_tags_key(), str8_lit("background")); dr_truncated_fancy_run_fuzzy_matches(text_position, &box->display_fruns, max_x, &box->fuzzy_match_ranges, match_color); } + dr_truncated_fancy_run_list(text_position, &box->display_fruns, max_x, ellipses_run); } // rjf: draw focus viz @@ -7851,7 +7953,7 @@ rd_window_frame(void) //~ rjf: Eval Visualization 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_Expr *root_expr, E_Eval eval, String8List *out) +rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Expr *root_expr, E_Eval eval, String8List *out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -8094,7 +8196,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul { E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.exprs.last); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); } else { @@ -8113,7 +8215,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); B32 is_first = 1; for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) @@ -8131,7 +8233,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } is_first = 0; E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); if(space_taken > max_size && idx+1 < total_possible_child_count) { String8 ellipses = str8_lit(", ..."); @@ -8252,7 +8354,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, str8_zero()); + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); B32 is_first = 1; for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) @@ -8270,7 +8372,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } is_first = 0; E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); if(space_taken > max_size && idx+1 < total_possible_child_count) { String8 ellipses = str8_lit(", ..."); @@ -8302,11 +8404,11 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } 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) +rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, flags, default_radix, font, font_size, max_size, 0, eval.exprs.last, eval, &strs); + rd_append_value_strings_from_eval(scratch.arena, filter, flags, default_radix, font, font_size, max_size, 0, eval.exprs.last, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; @@ -11010,6 +11112,8 @@ rd_frame(void) str8_lit("target"), str8_lit("file_path_map"), str8_lit("auto_view_rule"), + str8_lit("recent_project"), + str8_lit("recent_file"), str8_lit("machine"), str8_lit("process"), str8_lit("thread"), @@ -11113,6 +11217,8 @@ rd_frame(void) str8_lit("target"), str8_lit("file_path_map"), str8_lit("auto_view_rule"), + str8_lit("recent_project"), + str8_lit("recent_file"), }; for EachElement(idx, evallable_cfg_names) { @@ -11302,8 +11408,14 @@ rd_frame(void) .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities)); } - //- rjf: add lookup rules for unattached processes on a machine + //- rjf: add macro / lookup rules for unattached processes { + String8 collection_name = str8_lit("unattached_processes"); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("unattached_processes"), .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); @@ -11319,7 +11431,8 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands)); + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(commands)); } //- rjf: add macro for output log @@ -11591,7 +11704,8 @@ rd_frame(void) for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { if(!str8_match(old_child->string, str8_lit("panels"), 0) && - !str8_match(old_child->string, str8_lit("size"), 0)) + !str8_match(old_child->string, str8_lit("size"), 0) && + !str8_match(old_child->string, str8_lit("query"), 0)) { RD_Cfg *new_child = rd_cfg_deep_copy(old_child); rd_cfg_insert_child(new_window, new_window->last, new_child); @@ -11764,7 +11878,8 @@ rd_frame(void) if(recent_project == &rd_nil_cfg) { recent_project = rd_cfg_new(user, str8_lit("recent_project")); - rd_cfg_new(recent_project, path_normalized_from_string(scratch.arena, file_path)); + RD_Cfg *path_root = rd_cfg_new(recent_project, str8_lit("path")); + rd_cfg_new(path_root, path_normalized_from_string(scratch.arena, file_path)); } rd_cfg_unhook(user, recent_project); rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); @@ -12707,7 +12822,8 @@ rd_frame(void) if(recent_file == &rd_nil_cfg) { recent_file = rd_cfg_new(project, str8_lit("recent_file")); - rd_cfg_new(recent_file, path); + RD_Cfg *path_root = rd_cfg_new(recent_file, str8_lit("path")); + rd_cfg_new(path_root, path); } rd_cfg_unhook(project, recent_file); rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); @@ -13551,8 +13667,8 @@ Z(getting_started) } }break; - //- rjf: filtering - case RD_CmdKind_Filter: + //- rjf: search operations + case RD_CmdKind_Search: { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *vs = rd_view_state_from_cfg(view); @@ -13563,9 +13679,9 @@ Z(getting_started) } vs->is_searching ^= 1; }break; +#if 0 // TODO(rjf): @cfg case RD_CmdKind_ClearFilter: { -#if 0 // TODO(rjf): @cfg RD_View *view = rd_view_from_handle(rd_regs()->view); if(!rd_view_is_nil(view)) { @@ -13573,18 +13689,16 @@ Z(getting_started) view->is_filtering = 0; view->query_cursor = view->query_mark = txt_pt(1, 1); } -#endif }break; case RD_CmdKind_ApplyFilter: { -#if 0 // TODO(rjf): @cfg RD_View *view = rd_view_from_handle(rd_regs()->view); if(!rd_view_is_nil(view)) { view->is_filtering = 0; } -#endif }break; +#endif //- rjf: query stack case RD_CmdKind_PushQuery: @@ -13593,6 +13707,8 @@ Z(getting_started) RD_Cfg *current_query = rd_cfg_child_from_string(window, str8_lit("query")); rd_cfg_release(current_query); RD_Cfg *new_query = rd_cfg_new(window, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_new(new_query, str8_lit("cmd")); + rd_cfg_new(cmd, rd_regs()->cmd_name); }break; case RD_CmdKind_CompleteQuery: { @@ -13859,6 +13975,13 @@ Z(getting_started) } }break; + //- rjf: auto view rules + case RD_CmdKind_AddAutoViewRule: + { + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + rd_cfg_new(project, str8_lit("auto_view_rule")); + }break; + //- rjf: watches case RD_CmdKind_ToggleWatchExpression: if(rd_regs()->string.size != 0) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 8c46be56..c86c2133 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -85,6 +85,7 @@ enum RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaCmd, RD_EvalSpaceKind_MetaCtrlEntity, + RD_EvalSpaceKind_MetaUnattachedProcess, }; //////////////////////////////// @@ -994,6 +995,7 @@ internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); +internal String8 rd_path_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); @@ -1111,8 +1113,8 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -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_Expr *root_expr, E_Eval eval, 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); +internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Expr *root_expr, E_Eval eval, String8List *out); +internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// //~ rjf: Hover Eval diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4d91d8a9..63230edb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -139,22 +139,8 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: get active search query // - String8 search_query = {0}; - Side search_query_side = Side_Invalid; + String8 search_query = rd_view_search(); B32 search_query_is_active = 0; - { -#if 0 // TODO(rjf): @cfg - RD_Window *window = rd_window_from_handle(rd_regs()->window); - RD_CmdKind query_cmd_kind = rd_cmd_kind_from_string(window->query_cmd_name); - if(query_cmd_kind == RD_CmdKind_FindTextForward || - query_cmd_kind == RD_CmdKind_FindTextBackward) - { - search_query = str8(window->query_view_stack_top->query_buffer, window->query_view_stack_top->query_string_size); - search_query_is_active = 1; - search_query_side = (query_cmd_kind == RD_CmdKind_FindTextForward) ? Side_Max : Side_Min; - } -#endif - } ////////////////////////////// //- rjf: prepare code slice info bundle, for the viewable region of text @@ -1030,12 +1016,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} - // rjf: lister rows - else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Button, .pct = 1.f); - } - // rjf: top-level cfg rows else if(is_top_level && evalled_cfg != &rd_nil_cfg) { @@ -1085,7 +1065,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind != RD_CmdKind_Null) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); } } } @@ -1104,16 +1085,51 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { cmd_kind = RD_CmdKind_ThawEntity; } - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands[%I64u]", (U64)cmd_kind-1)); + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } + } + + // rjf: singular button for unattached processes + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + { + E_Type *type = e_type_from_key__cached(info.eval.type_key); + if(str8_match(type->name, str8_lit("unattached_process"), 0)) + { + U64 pid = info.eval.value.u128.u64[0]; + String8 name = e_string_from_id(info.eval.value.u128.u64[1]); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Scheduler], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = fstrs); } } // rjf: singular button for commands else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - RD_CmdKind cmd_kind = e_value_eval_from_eval(info.eval).value.u64; - RD_CmdKindInfo *cmd_kind_info = &rd_cmd_kind_info_table[cmd_kind]; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + E_Type *type = e_type_from_key__cached(info.eval.type_key); + if(type->kind == E_TypeKind_Set) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); + } + else + { + String8 cmd_name = e_string_from_id(e_value_eval_from_eval(info.eval).value.u64); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + } } // rjf: folder / file rows @@ -1147,6 +1163,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } + // rjf: lister rows + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + } + // rjf: singular cell for view ui else if(info.view_ui_rule != &rd_nil_view_ui_rule) { @@ -1159,6 +1181,21 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } + // rjf: procedures collections get only expr/value/view-rule + else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) + { + info.cell_style_key = str8_lit("expr_value_viewrule"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); +#undef take_pct + } + // rjf: for meta-cfg evaluation spaces, only do expr/value else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || @@ -1366,7 +1403,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: generate strings/flags based on that expression & fill - result.string = rd_value_string_from_eval(arena, string_flags, default_radix, font, font_size, max_size_px, result.eval); + result.string = rd_value_string_from_eval(arena, rd_view_search(), string_flags, default_radix, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.type_key); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) @@ -1422,9 +1459,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - RD_CmdKind cmd_kind = (RD_CmdKind)result.eval.value.u64; - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - result.cmd_name = cmd_name; + result.cmd_name = e_string_from_id(result.eval.value.u64); } else if(result.eval.space.kind == E_SpaceKind_FileSystem) { @@ -1461,8 +1496,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - RD_CmdKind cmd_kind = (RD_CmdKind)result.eval.value.u64; - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + String8 cmd_name = e_string_from_id(result.eval.value.u64); if(cell->px != 0) UI_TagF("weak") { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; @@ -2862,8 +2896,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) if(rgba.w == 0) { rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + else + { + rgba.w *= 0.15f; } - rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; @@ -2876,8 +2914,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) if(rgba.w == 0) { rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + else + { + rgba.w *= 0.15f; } - rgba.w *= 0.2f; rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; @@ -2997,6 +3039,12 @@ RD_VIEW_UI_FUNCTION_DEF(watch) is_button = 0; is_activated_on_single_click = 0; } + String8 searched_string = cell_info.string; + if(cell->fstrs.node_count != 0) + { + searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + } + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, rd_view_search(), searched_string); // rjf: build RD_LineEditParams line_edit_params = {0}; @@ -3018,12 +3066,21 @@ RD_VIEW_UI_FUNCTION_DEF(watch) line_edit_params.expanded_out = &next_row_expanded; line_edit_params.pre_edit_value = cell_info.string; line_edit_params.fstrs = cell_info.fstrs; + line_edit_params.fuzzy_matches = &fuzzy_matches; + } + if(cell_background_color_override.w != 0) + { + ui_push_background_color(cell_background_color_override); } UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); } + if(cell_background_color_override.w != 0) + { + ui_pop_background_color(); + } #if 0 // TODO(rjf): @cfg if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && @@ -4445,6 +4502,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { cell_flags |= UI_BoxFlag_DrawBackground; cell_bg_rgba = selection_color; + cell_bg_rgba.w *= 0.2f; } // rjf: build @@ -4522,11 +4580,13 @@ RD_VIEW_UI_FUNCTION_DEF(memory) DR_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); + Vec4F32 color = selection_color; + color.w *= 0.2f; dr_rect(r2f32p(text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.min+0-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, text_pos.x + fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), - selection_color, + color, 0, 0, 1.f); } ui_box_equip_draw_bucket(ascii_box, bucket); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index f2404cef..84e15b68 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -18,7 +18,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) String8 label_string = rd_label_from_cfg(cfg); String8 expr_string = rd_expr_from_cfg(cfg); String8 collection_name = {0}; - String8 file_path = {0}; + String8 file_path = rd_path_from_cfg(cfg); Vec4F32 rgba = rd_color_from_cfg(cfg); if(rgba.w == 0) { @@ -1350,7 +1350,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // UI_Box *catchall_margin_container_box = &ui_nil_box; if(params->flags & RD_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins") - UI_TagF("implicit") + UI_TagF("floating") { if(params->margin_float_off_px != 0) { @@ -1510,7 +1510,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe B32 bp_is_disabled = rd_disabled_from_cfg(bp); if(bp_is_disabled) { - bp_rgba = v4f32(bp_rgba.x * 0.6f, bp_rgba.y * 0.6f, bp_rgba.z * 0.6f, bp_rgba.w * 0.6f); + bp_rgba = v4f32(bp_rgba.x*0.45f, bp_rgba.y*0.45f, bp_rgba.z*0.45f, bp_rgba.w*0.45f); } // rjf: prep custom rendering data @@ -1665,7 +1665,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe //- rjf: build line numbers // if(params->flags & RD_CodeSliceFlag_LineNums) UI_Parent(top_container_box) ProfScope("build line numbers") UI_Focus(UI_FocusKind_Off) - UI_TagF("implicit") + UI_TagF("floating") { TxtRng select_rng = txt_rng(*cursor, *mark); Vec4F32 active_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeLineNumbersSelected); @@ -1708,7 +1708,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(has_line_info) { Vec4F32 color = code_line_bgs[line_info_line_num % ArrayCount(code_line_bgs)]; - color.w *= line_info_t; + color.w *= line_info_t*0.2f; bg_color = color; } } @@ -1833,7 +1833,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.type_key)) { - eval_string = rd_value_string_from_eval(scratch.arena, EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); + eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); } ui_spacer(ui_em(1.5f, 1.f)); ui_set_next_pref_width(ui_children_sum(1)); @@ -2372,6 +2372,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { color.w *= 0.5f; } + color.w *= 0.2f; dr_rect(match_rect, color, 4.f, 0, 1.f); needle_pos += 1; } @@ -2475,7 +2476,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(matches) { Vec4F32 highlight_color = code_line_bgs[line_info_line_num % ArrayCount(code_line_bgs)]; - highlight_color.w *= 0.25f; + highlight_color.w *= 0.05f; dr_rect(line_box->rect, highlight_color, 0, 0, 0); } } @@ -3226,6 +3227,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(label, ¶ms->fstrs); + if(params->fuzzy_matches != 0) + { + ui_box_equip_fuzzy_match_ranges(label, params->fuzzy_matches); + } } else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) { diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 1ab48035..7e4ffacc 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2024,6 +2024,8 @@ ui_begin_ctx_menu(UI_Key key) ui_state->ctx_menu_root->corner_radii[Corner_00] = ui_state->ctx_menu_root->corner_radii[Corner_01] = ui_state->ctx_menu_root->corner_radii[Corner_10] = ui_state->ctx_menu_root->corner_radii[Corner_11] = ui_top_font_size()*0.25f; ui_state->ctx_menu_root->tags_key = ui_top_tags_key(); ui_state->ctx_menu_root->blur_size = ui_top_blur_size(); + ui_state->ctx_menu_root->text_color = ui_color_from_name(str8_lit("text")); + ui_state->ctx_menu_root->background_color = ui_color_from_name(str8_lit("background")); ui_spacer(ui_em(1.f, 1.f)); } ui_state->is_in_open_ctx_menu = is_open; From 1a84f1cedd4553bab0f2c8510eb3c847cb2e4a2f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Feb 2025 17:22:49 -0800 Subject: [PATCH 150/755] macroify 'search_path', use in file system queries --- src/raddbg/generated/raddbg.meta.c | 14 +++++++------- src/raddbg/raddbg.mdesk | 14 +++++++------- src/raddbg/raddbg_core.c | 12 ++++++++++-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 33fac2a7..8fdbe22f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -442,7 +442,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:\"\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -450,8 +450,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -534,7 +534,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -564,9 +564,9 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("file:"""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1fc83808..decee7a1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -427,7 +427,7 @@ RD_CmdTable: // | | | | //- rjf: files {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } - {Open 1 1 `file:\\"\\"` FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Open 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } @@ -441,8 +441,8 @@ RD_CmdTable: // | | | | {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } - {OpenProject 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenUser 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes @@ -555,7 +555,7 @@ RD_CmdTable: // | | | | {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {AddTarget 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } @@ -595,9 +595,9 @@ RD_CmdTable: // | | | | {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 "file:\"\"" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } - {PickFolder 0 0 "file:\"\"" FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } - {PickFileOrFolder 0 0 "file:\"\"" FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } + {PickFile 0 0 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 "query:search_path" FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 "query:search_path" FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 88902174..3f8c68cb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10301,9 +10301,8 @@ rd_init(CmdLine *cmdln) { Temp scratch = scratch_begin(0, 0); String8 current_path = os_get_current_path(scratch.arena); - String8 current_path_with_slash = push_str8f(scratch.arena, "%S/", current_path); rd_state->current_path_arena = arena_alloc(); - rd_state->current_path = push_str8_copy(rd_state->current_path_arena, current_path_with_slash); + rd_state->current_path = push_str8_copy(rd_state->current_path_arena, current_path); scratch_end(scratch); } @@ -11300,6 +11299,15 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } + //- rjf: add macro for 'search path' + { + String8 search_path = rd_state->current_path; + String8 search_path_escaped = escaped_from_raw_str8(scratch.arena, search_path); + String8 search_path_eval_string = push_str8f(scratch.arena, "file:\"%S\"", search_path_escaped); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, search_path_eval_string).exprs.first; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("search_path"), expr); + } + //- rjf: add macro for watches group { String8 collection_name = str8_lit("watches"); From 6653a0e437ae58f88d6bf7902d8e98670c38edd0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 10:04:48 -0800 Subject: [PATCH 151/755] auto tabs --- project.4coder | 2 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 10 +++++ src/raddbg/raddbg_core.c | 67 ++++++++++++++++++++++-------- src/raddbg/raddbg_widgets.c | 1 + 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/project.4coder b/project.4coder index 6e727228..6031a91c 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8fdbe22f..7afc647c 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -813,7 +813,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x633112ff,\n line_info_1: 0x754e1aff,\n line_info_2: 0x75721aff,\n line_info_3: 0x48751bff,\n line_info_4: 0x732112ff,\n line_info_5: 0x754e1aff,\n line_info_6: 0x75721aff,\n line_info_7: 0x48751bff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x633112ff,\n line_info_1: 0x754e1aff,\n line_info_2: 0x75721aff,\n line_info_3: 0x48751bff,\n line_info_4: 0x732112ff,\n line_info_5: 0x754e1aff,\n line_info_6: 0x75721aff,\n line_info_7: 0x48751bff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x442f4dff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index decee7a1..069a212a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1112,6 +1112,16 @@ RD_ThemePresetTable: background: 0x2b3740ff, border: 0x3e4c57ff, } + auto: + { + background: 0x693847ff, + border: 0x9e6274ff, + inactive: + { + background: 0x442f4dff, + border: 0x685073ff, + } + } } drop_site: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3f8c68cb..42f9ec72 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6051,7 +6051,7 @@ rd_window_frame(void) // ProfScope("build hover eval") { - B32 build_hover_eval = hover_eval_is_open; + B32 build_hover_eval = hover_eval_is_open && !rd_drag_is_active(); // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) @@ -7129,6 +7129,7 @@ rd_window_frame(void) { // rjf: gather info for this tab B32 tab_is_selected = (tab == panel->selected_tab); + B32 tab_is_auto = (rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg); // rjf: begin vertical region for this tab ui_set_next_child_layout_axis(Axis2_Y); @@ -7147,6 +7148,7 @@ rd_window_frame(void) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) UI_TagF(omit_name ? "hollow" : "") UI_TagF(!tab_is_selected ? "inactive" : "") + UI_TagF(tab_is_auto ? "auto" : "") { if(panel->tab_side == Side_Max) { @@ -7930,7 +7932,7 @@ rd_window_frame(void) color.w *= ws->error_t; Rng2F32 rect = os_client_rect_from_window(ws->os); dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); - dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.05f), 0, 0, 0); + dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.025f), 0, 0, 0); } scratch_end(scratch); @@ -11877,7 +11879,7 @@ rd_frame(void) RD_Cfg *recent_project = &rd_nil_cfg; for(RD_CfgNode *n = recent_projects.first; n != 0; n = n->next) { - if(path_match_normalized(n->v->string, file_path)) + if(path_match_normalized(rd_path_from_cfg(n->v), file_path)) { recent_project = n->v; break; @@ -12817,11 +12819,11 @@ rd_frame(void) { String8 path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); + RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_file")); RD_Cfg *recent_file = &rd_nil_cfg; for(RD_CfgNode *n = recent_files.first; n != 0; n = n->next) { - if(path_match_normalized(n->v->string, path)) + if(path_match_normalized(rd_path_from_cfg(n->v), path)) { recent_file = n->v; break; @@ -12835,7 +12837,7 @@ rd_frame(void) } rd_cfg_unhook(project, recent_file); rd_cfg_insert_child(project, &rd_nil_cfg, recent_file); - recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_files")); + recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_file")); if(recent_files.count > 256) { rd_cfg_release(recent_files.last->v); @@ -13412,24 +13414,45 @@ Z(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_RegsScope(.view = tab->id) + String8 tab_expr = rd_expr_from_cfg(tab); + String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); + if((str8_match(tab->string, str8_lit("text"), 0) || str8_match(tab->string, str8_lit("pending"), 0)) && + path_match_normalized(tab_file_path, file_path)) { - String8 tab_expr = rd_expr_from_cfg(tab); - String8 tab_file_path = rd_file_path_from_eval_string(scratch.arena, tab_expr); - if((str8_match(tab->string, str8_lit("text"), 0) || str8_match(tab->string, str8_lit("pending"), 0)) && - path_match_normalized(tab_file_path, file_path)) + panel_w_this_src_code = panel; + view_w_this_src_code = tab; + if(tab == panel->selected_tab) { - panel_w_this_src_code = panel; - view_w_this_src_code = tab; - if(tab == panel->selected_tab) - { - break; - } + break; } } } } + // rjf: try to find panel/view pair that has any *auto* source code tab open + RD_PanelNode *panel_w_auto = &rd_nil_panel_node; + RD_Cfg *view_w_auto = &rd_nil_cfg; + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + if(panel->first != &rd_nil_panel_node) + { + continue; + } + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) + { + RD_Cfg *tab = tab_n->v; + if(rd_cfg_is_project_filtered(tab)) { continue; } + if(str8_match(tab->string, str8_lit("text"), 0) && + rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg) + { + panel_w_auto = panel; + view_w_auto = tab; + } + } + } + // rjf: find a panel that already has *any* code open (prioritize largest) RD_PanelNode *panel_w_any_src_code = &rd_nil_panel_node; { @@ -13565,6 +13588,7 @@ Z(getting_started) if(file_path.size != 0) { if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_this_src_code; } + if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_auto; } if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = panel_w_any_src_code; } if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_empty_panel; } if(src_code_dst_panel == &rd_nil_panel_node) { src_code_dst_panel = biggest_panel; } @@ -13618,11 +13642,18 @@ Z(getting_started) // rjf: construct new view if needed RD_Cfg *dst_tab = view_w_this_src_code; - if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) + if(dst_tab == &rd_nil_cfg && dst_panel == panel_w_auto && view_w_auto != &rd_nil_cfg) + { + dst_tab = view_w_auto; + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(dst_tab, str8_lit("expression")); + rd_cfg_new_replace(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); + } + else if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) { dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("text")); RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("expression")); rd_cfg_new(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); + rd_cfg_new(dst_tab, str8_lit("auto")); } // rjf: determine if we need a contain or center diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 84e15b68..6f8dcd6e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2186,6 +2186,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe DR_BucketScope(bucket) { Vec4F32 color = line_drag_drop_color; + color.w *= 0.2f; Rng2F32 drop_line_rect = r2f32p(top_container_box->rect.x0, top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min) * params->line_height_px, top_container_box->rect.x1, From eae15a3d4158eae720e27a4ca460ae70741ca9fd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 13:30:28 -0800 Subject: [PATCH 152/755] work on command queries, distinguish floating vs. embedded --- project.4coder | 2 +- src/ctrl/ctrl_core.c | 4 + src/dbg_engine/dbg_engine.mdesk | 72 ++--- src/raddbg/generated/raddbg.meta.c | 435 +++++++++++++++-------------- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 392 +++++++++++++------------- src/raddbg/raddbg_core.c | 286 +++++++++++-------- src/raddbg/raddbg_core.h | 120 ++++---- src/raddbg/raddbg_views.c | 7 +- src/raddbg/raddbg_widgets.c | 4 +- 10 files changed, 703 insertions(+), 622 deletions(-) diff --git a/project.4coder b/project.4coder index 6031a91c..6e727228 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 5104d4f1..ee778ba6 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3073,6 +3073,10 @@ ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *proce { inline_frame->v.parent_num = frame_count; inline_frame->v.inline_depth = inline_frame_count - inline_frame_idx; + if(inline_frame == last_inline_frame) + { + break; + } } } diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 86fb8111..be9213b8 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -4,52 +4,52 @@ //////////////////////////////// //~ rjf: Built-In Command Tables -@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | | \___ _________________________________/ | | | | | | -// / | | | | \ / | | | | | | -D_CmdTable: // | | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ _________________________________/ | | | | | | +// / | | | | \ / | | | | | | +D_CmdTable: // | | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } - {LaunchAndInit 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } - {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } - {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } - {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } - {Continue 1 1 "" Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } - {StepIntoInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } - {StepOverInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } - {StepIntoLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } - {StepOverLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } - {StepOut 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } - {Halt 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } - {SoftHaltRefresh 0 0 "" Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } - {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } + {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndInit 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } + {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } + {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } + {Continue 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } + {StepIntoInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } + {StepOverInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } + {StepIntoLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } + {StepOverLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } + {StepOut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } + {Halt 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } + {SoftHaltRefresh 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 0 1 "" Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } - {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } - {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } - {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } - {StepOver 1 1 "" Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } + {RunToLine 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } + {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } + {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } + {StepOver 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } //- rjf: debug control context management operations - {FreezeThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } - {ThawThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } - {FreezeProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } - {ThawProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } - {FreezeMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } - {ThawMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } - {FreezeLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } - {ThawLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } - {FreezeEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } - {ThawEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } + {FreezeThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } + {ThawThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } + {FreezeProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } + {ThawProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } + {FreezeMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } + {ThawMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } + {FreezeLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } + {ThawLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } + {FreezeEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration - {SetEntityColor 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } - {SetEntityName 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } + {SetEntityColor 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } + {SetEntityName 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } //- rjf: attaching - {Attach 1 1 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } + {Attach 1 1 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } } @enum D_CmdKind: diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7afc647c..cc6054a8 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[292] = +RD_VocabInfo rd_vocab_info_table[293] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -267,6 +267,7 @@ RD_VocabInfo rd_vocab_info_table[292] = {str8_lit_comp("register_as_jit_debugger"), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("search"), str8_lit_comp(""), str8_lit_comp("Search"), str8_lit_comp(""), RD_IconKind_Find}, +{str8_lit_comp("search_backwards"), str8_lit_comp(""), str8_lit_comp("Search Backwards"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, {str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, {str8_lit_comp("target"), str8_lit_comp(""), str8_lit_comp("Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -358,223 +359,224 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[212] = +RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -670,8 +672,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[110] = {str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_Modifier_Alt}}, {str8_lit_comp("search"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_Modifier_Ctrl }}, +{str8_lit_comp("search_backwards"), {OS_Key_R, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_next"), {OS_Key_F3, 0 }}, {str8_lit_comp("find_prev"), {OS_Key_F3, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("find_selected_thread"), {OS_Key_F4, 0 }}, @@ -813,7 +814,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x633112ff,\n line_info_1: 0x754e1aff,\n line_info_2: 0x75721aff,\n line_info_3: 0x48751bff,\n line_info_4: 0x732112ff,\n line_info_5: 0x754e1aff,\n line_info_6: 0x75721aff,\n line_info_7: 0x48751bff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x442f4dff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x341f3dff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b162da04..348bb4fc 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -232,6 +232,7 @@ RD_CmdKind_DisableTarget, RD_CmdKind_RegisterAsJITDebugger, RD_CmdKind_FindCodeLocation, RD_CmdKind_Search, +RD_CmdKind_SearchBackwards, RD_CmdKind_GettingStarted, RD_CmdKind_Commands, RD_CmdKind_Target, @@ -624,7 +625,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[292]; +extern RD_VocabInfo rd_vocab_info_table[293]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[38]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 069a212a..21c58fc2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -342,271 +342,272 @@ RD_RegTable: //////////////////////////////// //~ rjf: Command Table -@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | | \___ _____________________________________________________/ | | | | | | -// / | | | | \ / | | | | | | -RD_CmdTable: // | | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | \___ __________________________/ | | | | | | +// / | | | | \ / | | | | | | +RD_CmdTable: // | | | | | | | | | | | | { //- rjf: exiting - {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } + {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } //- rjf: top-level lister - {OpenLister 1 1 "query:lister" Null null Nil Null 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } + {OpenLister 1 1 "query:lister" Null null Nil Null 0 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } //- rjf: command runner - {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } + {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } //- rjf: os event passthrough - {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } + {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } - {SelectUnwind 1 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } - {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } - {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } + {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 1 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } + {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } //- rjf: font sizes - {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } - {DecUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } - {IncCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } - {DecCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } + {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } + {DecUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } + {IncCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } + {DecCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } //- rjf: windows - {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } - {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } - {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } - {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } + {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } + {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } + {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } //- rjf: popups - {PopupAccept 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } - {PopupCancel 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } + {PopupAccept 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } + {PopupCancel 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } //- rjf: panel splitting - {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } - {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } - {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } - {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } - {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } - {NewPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } - {SplitPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } + {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } + {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } + {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } + {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } + {NewPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } + {SplitPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } //- rjf: panel rotation - {RotatePanelColumns 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } + {RotatePanelColumns 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } //- rjf: focused panel changing - {NextPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } - {PrevPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } - {FocusPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } - {FocusPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } - {FocusPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } - {FocusPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } - {FocusPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } + {NextPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } + {PrevPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } + {FocusPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } + {FocusPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } + {FocusPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } + {FocusPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } + {FocusPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } //- rjf: undo/redo - {Undo 0 0 "" Null null Nil Null 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } - {Redo 0 0 "" Null null Nil Null 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } + {Undo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } + {Redo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } //- rjf: focus history - {GoBack 0 0 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } - {GoForward 0 0 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } + {GoBack 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } + {GoForward 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } //- rjf: panel removal - {ClosePanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } + {ClosePanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } //- rjf: panel tab - {FocusTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } - {NextTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } - {PrevTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } - {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } - {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } - {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } - {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } - {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } - {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } - {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } + {FocusTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } + {NextTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } + {PrevTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } + {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } + {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } + {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } + {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } //- rjf: files - {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } - {Open 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } - {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } - {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } - {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } - {ShowFileInExplorer 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } + {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } + {Open 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } + {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } + {ShowFileInExplorer 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm - {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } - {GoToSource 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } + {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } + {GoToSource 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } //- rjf: override file links - {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } + {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } - {OpenProject 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } - {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } + {OpenUser 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes - {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } - {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } + {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } + {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } //- rjf: meta controls - {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } - {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } - {Cancel 1 1 "" Null null Nil Null 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } + {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } + {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } + {Cancel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } //- rjf: directional movement & text controls - {MoveLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } - {MoveRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } - {MoveUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } - {MoveDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } - {MoveLeftSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } - {MoveRightSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } - {MoveUpSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } - {MoveDownSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } - {MoveLeftChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } - {MoveDownPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } - {MoveUpWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } - {MoveDownWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } - {MoveLeftChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } - {MoveDownPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } - {MoveUpWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } - {MoveDownWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } - {MoveUpReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } - {MoveDownReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } - {MoveHome 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } - {MoveEnd 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } - {MoveHomeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } - {MoveEndSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } - {SelectAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } - {DeleteSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } - {DeleteChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } - {BackspaceSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } - {BackspaceChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } - {Copy 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } - {Cut 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } - {Paste 1 1 "" Null null Nil Null 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } - {InsertText 0 1 "" Null null Nil Null 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } + {MoveLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } + {MoveRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } + {MoveUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } + {MoveDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } + {MoveLeftSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } + {MoveRightSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } + {MoveUpSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } + {MoveDownSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } + {MoveLeftChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } + {MoveDownPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } + {MoveUpWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } + {MoveDownWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } + {MoveLeftChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } + {MoveDownPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } + {MoveUpWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } + {MoveDownWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } + {MoveUpReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } + {MoveDownReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } + {MoveHome 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } + {MoveEnd 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } + {MoveHomeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } + {MoveEndSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } + {SelectAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } + {DeleteSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } + {DeleteChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } + {BackspaceSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } + {BackspaceChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } + {Copy 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } + {Cut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } + {Paste 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } + {InsertText 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } //- rjf: code navigation - {GoToLine 1 1 "" Cursor null Nil Null 0 0 0 0 1 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } - {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } - {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } - {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } - {FindTextForward 1 1 "" String null Nil Null 0 0 1 1 1 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } - {FindTextBackward 1 1 "" String null Nil Null 0 0 1 1 1 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } - {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } - {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } + {GoToLine 1 1 "" Cursor null Nil Null 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } + {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } + {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } + {FindTextForward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } + {FindTextBackward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } + {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } + {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } //- rjf: thread finding - {FindThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } - {FindSelectedThread 1 1 "" Null null Nil Null 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } + {FindThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } + {FindSelectedThread 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } //- rjf: name finding - {GoToName 1 1 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } - {GoToNameAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } + {GoToName 1 1 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } + {GoToNameAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } //- rjf: watch expressions - {ToggleWatchExpression 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } - {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } - {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } + {ToggleWatchExpression 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } + {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } + {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: memory view parameterization - {SetColumns 1 1 "" Null null Nil Null 0 0 0 0 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } + {SetColumns 1 1 "" Null null Nil Null 0 0 0 0 1 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } //- rjf: disassembly view parameterization - {ToggleAddressVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } - {ToggleCodeBytesVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } + {ToggleAddressVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } + {ToggleCodeBytesVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } //- rjf: general config operations - {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } - {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } - {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } - {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } - {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } - {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } - {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } - {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } - {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } + {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } + {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } + {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } - {AddAddressBreakpoint 1 0 "" Vaddr null Nil Null 0 0 0 0 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {AddFunctionBreakpoint 1 0 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } - {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } - {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } - {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddAddressBreakpoint 1 0 "" Vaddr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {AddFunctionBreakpoint 1 0 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } + {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 "" String null Nil Null 0 0 0 0 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } - {ToggleWatchPin 1 0 "" String null Nil Null 0 0 0 0 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + {AddWatchPin 1 1 "" String null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 "" String null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } //- rjf: auto view rule - {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } //- rjf: line operations - {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } + {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } - {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" "" } - {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } - {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } + {AddTarget 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching - {RegisterAsJITDebugger 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } + {RegisterAsJITDebugger 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } //- rjf: snap-to-code-location - {FindCodeLocation 0 1 "" FilePath null Nil Null 0 0 0 0 0 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } + {FindCodeLocation 0 1 "" FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } //- rjf: searching - {Search 1 1 "" Null null Nil Null 0 0 0 0 0 0 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } + {Search 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } + {SearchBackwards 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search_backwards" "Search Backwards" "Begins searching backwards within the active interface." "sort,search,filter,find" "" } //- rjf: view drivers - {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } - {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } - {Target 0 0 "" Null null Nil Null 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } - {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } - {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } - {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } - {Breakpoints 1 1 "" Null null Nil Null 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } - {WatchPins 1 1 "" Null null Nil Null 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } - {Scheduler 1 1 "" Null null Nil Null 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } - {CallStack 1 1 "" Null null Nil Null 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } - {Modules 1 1 "" Null null Nil Null 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } - {Watch 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } - {Locals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } - {Registers 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } - {Globals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } - {ThreadLocals 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } - {Types 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } - {Procedures 1 1 "" Null null Nil Null 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } - {PendingFile 0 0 "" Null null Nil Null 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } - {Disassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } - {Output 1 1 "" Null null Nil Null 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } - {Memory 1 1 "" Null null Nil Null 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } - {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } + {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } + {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } + {Target 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } + {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } + {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } + {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } + {Breakpoints 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } + {WatchPins 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } + {Scheduler 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } + {CallStack 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } + {Modules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } + {Watch 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } + {Locals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } + {Registers 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } + {Globals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } + {ThreadLocals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } + {Types 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } + {Procedures 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } + {PendingFile 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } + {Disassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } + {Output 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } + {Memory 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } + {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } - {PickFolder 0 0 "query:search_path" FilePath null Nil Null 0 1 0 0 0 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } - {PickFileOrFolder 0 0 "query:search_path" FilePath null Nil Null 1 1 0 0 0 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } + {PickFile 0 0 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 "query:search_path" FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 "query:search_path" FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack - {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } - {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } - {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } + {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } + {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } + {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } //- rjf: developer commands - {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } - {LogMarker 1 1 "" Null null Nil Null 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } + {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } + {LogMarker 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } } @enum RD_CmdKind: @@ -640,9 +641,9 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; } //////////////////////////////// @@ -776,8 +777,7 @@ RD_DefaultBindingTable: { "goto_line" G ctrl 0 0 } { "goto_address" G 0 0 alt } { "search" F ctrl 0 0 } - { "find_text_forward" F ctrl 0 0 } - { "find_text_backward" R ctrl 0 0 } + { "search_backwards" R ctrl 0 0 } { "find_next" F3 0 0 0 } { "find_prev" F3 shift 0 0 } @@ -1046,14 +1046,14 @@ RD_ThemePresetTable: code_string: 0x98abb1ff, code_meta: 0xd96759ff, code_comment: 0x717171ff, - line_info_0: 0x633112ff, - line_info_1: 0x754e1aff, - line_info_2: 0x75721aff, - line_info_3: 0x48751bff, - line_info_4: 0x732112ff, - line_info_5: 0x754e1aff, - line_info_6: 0x75721aff, - line_info_7: 0x48751bff, + line_info_0: 0x4f3022ff, + line_info_1: 0x4f3e15ff, + line_info_2: 0x434e2aff, + line_info_3: 0x36241fff, + line_info_4: 0x4f3022ff, + line_info_5: 0x4f3e15ff, + line_info_6: 0x434e2aff, + line_info_7: 0x36241fff, thread_0: 0xffcb7fff, thread_1: 0xb2ff65ff, thread_2: 0xff99e5ff, @@ -1118,7 +1118,7 @@ RD_ThemePresetTable: border: 0x9e6274ff, inactive: { - background: 0x442f4dff, + background: 0x341f3dff, border: 0x685073ff, } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 42f9ec72..5ff918b6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3320,6 +3320,7 @@ rd_view_state_from_cfg(RD_Cfg *cfg) view_state->arena = arena_alloc(); view_state->ev_view = ev_view_alloc(); view_state->loading_t = 1.f; + view_state->search_arena = arena_alloc(); } if(view_state != &rd_nil_view_state) { @@ -3342,8 +3343,12 @@ rd_view_ui(Rng2F32 rect) // B32 search_row_is_open = (vs->is_searching || vs->search_string_size != 0); F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); - if(search_row_open_t > 0.001f) RD_Font(RD_FontSlot_Code) + if(search_row_open_t > 0.001f) { + String8 cmd_name = vs->search_cmd_name; + RD_IconKind icon = rd_icon_kind_from_code_name(cmd_name); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + //- rjf: clamp cursor if(vs->search_cursor.column == 0) { @@ -3367,21 +3372,21 @@ rd_view_ui(Rng2F32 rect) //- rjf: build contents UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->is_searching ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) { - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) - { - vs->is_searching = 0; - vs->search_string_size = 0; - } UI_TextAlignment(UI_TextAlign_Center) UI_Transparency(1-search_row_open_t) UI_PrefWidth(ui_em(2.5f, 1.f)) UI_TagF("weak") RD_Font(RD_FontSlot_Icons) - ui_label(rd_icon_kind_text_table[RD_IconKind_Find]); + ui_label(rd_icon_kind_text_table[icon == RD_IconKind_Null ? RD_IconKind_Find : icon]); + UI_Transparency(1-search_row_open_t) + RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) + ui_label(rd_display_from_code_name(cmd_name)); + ui_spacer(ui_em(0.5f, 1.f)); RD_LineEditParams params = {0}; { - params.flags |= RD_LineEditFlag_CodeContents; + params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_LineEditFlag_CodeContents; params.flags |= RD_LineEditFlag_Border; params.cursor = &vs->search_cursor; params.mark = &vs->search_mark; @@ -3395,6 +3400,25 @@ rd_view_ui(Rng2F32 rect) { vs->is_searching = 1; } + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + { + RD_RegsScope() + { + rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); + rd_push_cmd(cmd_name, rd_regs()); + } + if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } + } } //- rjf: commit string to view @@ -4105,6 +4129,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); + ws->query_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); OS_Handle zero_monitor = {0}; if(!os_handle_match(zero_monitor, preferred_monitor)) @@ -4173,7 +4198,7 @@ rd_window_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); B32 popup_is_open = (rd_state->popup_active); - B32 query_is_open = (rd_cfg_child_from_string(window, str8_lit("query")) != &rd_nil_cfg); + B32 query_is_open = (ws->query_is_active); B32 hover_eval_is_open = (!popup_is_open && !query_is_open && ws->hover_eval_string.size != 0 && @@ -5191,96 +5216,112 @@ rd_window_frame(void) //////////////////////////// //- rjf: build query // + if(query_is_open) { - RD_Cfg *query = rd_cfg_child_from_string(window, str8_lit("query")); - if(query != &rd_nil_cfg) + //- rjf: unpack query parameters + RD_Cfg *query = rd_immediate_cfg_from_keyf("window_query_%p", window); + String8 cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(query, str8_lit("watch")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->is_searching = 1; + arena_clear(vs->search_arena); + vs->search_cmd_name = push_str8_copy(vs->search_arena, ws->query_cmd_name); + vs->search_regs = rd_regs_copy(vs->search_arena, ws->query_regs); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + String8 query_expression = cmd_kind_info->query.expr; + B32 size_query_by_expr_eval = 0; + if(query_expression.size == 0) { - //- rjf: unpack query parameters - RD_Cfg *root = query; - RD_Cfg *cmd = rd_cfg_child_from_string(root, str8_lit("cmd")); - String8 cmd_name = cmd->first->string; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->is_searching = 1; - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - String8 query_expression = cmd_kind_info->query.expr; - rd_cfg_new_replace(expr, query_expression); - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - - //- rjf: cancel - if(ui_slot_press(UI_EventActionSlot_Cancel)) + query_expression = str8(vs->search_buffer, vs->search_string_size); + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + size_query_by_expr_eval = 1; + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + rd_cfg_new_replace(expr, query_expression); + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + + //- rjf: cancel + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + + //- rjf: build + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_search(), query_eval.exprs); + F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); + F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + if(size_query_by_expr_eval) { - rd_cmd(RD_CmdKind_CancelQuery); + query_height_px = row_height_px*predicted_block_tree.total_row_count; + query_height_px = Min(query_height_px, max_query_height_px); } + Rng2F32 query_rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); - //- rjf: build - RD_RegsScope(.view = view->id) + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + UI_Focus(UI_FocusKind_On) + UI_PrefHeight(ui_px(row_height_px, 1.f)) { - Vec2F32 content_rect_center = center_2f32(content_rect); - Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_search(), query_eval.exprs); - F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); - F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); - F32 max_query_height_px = content_rect_dim.y*0.8f; - F32 query_height_px = max_query_height_px; - Rng2F32 query_rect = r2f32p(content_rect_center.x - query_width_px/2, - content_rect_center.y - max_query_height_px/2.f, - content_rect_center.x + query_width_px/2, - content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); - - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_TagF("floating") - UI_Focus(UI_FocusKind_On) - UI_PrefHeight(ui_px(row_height_px, 1.f)) + //- rjf: build top-level container + UI_Box *container = &ui_nil_box; + UI_Rect(query_rect) + UI_Squish(0.25f-0.25f*query_open_t) + UI_Transparency(1.f-query_open_t) + UI_ChildLayoutAxis(Axis2_Y) { - //- rjf: build top-level container - UI_Box *container = &ui_nil_box; - UI_Rect(query_rect) - UI_Squish(0.25f-0.25f*query_open_t) - UI_Transparency(1.f-query_open_t) - UI_ChildLayoutAxis(Axis2_Y) - { - container = ui_build_box_from_string(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow, - str8_lit("query_container")); - } - - //- rjf: fill container - UI_Parent(container) UI_Focus(UI_FocusKind_Null) - { - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_WidthFill - { - rd_view_ui(view_contents_container->rect); - } - } - - //- rjf: fallthrough interactions on container - UI_Signal sig = ui_signal_from_box(container); + container = ui_build_box_from_string(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow, + str8_lit("query_container")); } + + //- rjf: fill container + UI_Parent(container) UI_Focus(UI_FocusKind_Null) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(view_contents_container->rect); + } + } + + //- rjf: fallthrough interactions on container + UI_Signal sig = ui_signal_from_box(container); } - - //- rjf: accept - if(ui_slot_press(UI_EventActionSlot_Accept)) - { - } - - //- rjf: build darkening rectangle over rest of screen - UI_Rect(window_rect) UI_TagF("inactive") - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } + } + + //- rjf: accept + if(ui_slot_press(UI_EventActionSlot_Accept)) + { + } + + //- rjf: build darkening rectangle over rest of screen + UI_Rect(window_rect) UI_TagF("inactive") + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); } } @@ -10434,6 +10475,7 @@ rd_frame(void) arena_release(ws->ctx_menu_arena); arena_release(ws->drop_completion_arena); arena_release(ws->hover_eval_arena); + arena_release(ws->query_arena); arena_release(ws->arena); DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); @@ -10460,6 +10502,7 @@ rd_frame(void) { arena_release(ext->arena); } + arena_release(vs->search_arena); arena_release(vs->arena); DLLRemove_NP(rd_state->view_state_slots[slot_idx].first, rd_state->view_state_slots[slot_idx].last, vs, hash_next, hash_prev); SLLStackPush_N(rd_state->free_view_state, vs, hash_next); @@ -11714,8 +11757,7 @@ rd_frame(void) for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { if(!str8_match(old_child->string, str8_lit("panels"), 0) && - !str8_match(old_child->string, str8_lit("size"), 0) && - !str8_match(old_child->string, str8_lit("query"), 0)) + !str8_match(old_child->string, str8_lit("size"), 0)) { RD_Cfg *new_child = rd_cfg_deep_copy(old_child); rd_cfg_insert_child(new_window, new_window->last, new_child); @@ -13707,17 +13749,6 @@ Z(getting_started) }break; //- rjf: search operations - case RD_CmdKind_Search: - { - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!vs->is_searching) - { - vs->search_cursor = txt_pt(1, 1+vs->search_string_size); - vs->search_mark = txt_pt(1, 1); - } - vs->is_searching ^= 1; - }break; #if 0 // TODO(rjf): @cfg case RD_CmdKind_ClearFilter: { @@ -13742,12 +13773,41 @@ Z(getting_started) //- rjf: query stack case RD_CmdKind_PushQuery: { - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *current_query = rd_cfg_child_from_string(window, str8_lit("query")); - rd_cfg_release(current_query); - RD_Cfg *new_query = rd_cfg_new(window, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_new(new_query, str8_lit("cmd")); - rd_cfg_new(cmd, rd_regs()->cmd_name); + String8 cmd_name = rd_regs()->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) + { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) + { + ws->query_is_active = 1; + arena_clear(ws->query_arena); + ws->query_cmd_name = push_str8_copy(ws->query_arena, cmd_name); + ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); + } + } + else + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!str8_match(vs->search_cmd_name, cmd_name, 0)) + { + arena_clear(vs->search_arena); + vs->search_regs = rd_regs_copy(vs->search_arena, rd_regs()); + vs->search_cmd_name = push_str8_copy(vs->search_arena, cmd_name); + if(!vs->is_searching) + { + vs->search_cursor = txt_pt(1, 1+vs->search_string_size); + vs->search_mark = txt_pt(1, 1); + } + vs->is_searching = 1; + } + else + { + vs->is_searching ^= 1; + } + } }break; case RD_CmdKind_CompleteQuery: { @@ -13798,7 +13858,13 @@ Z(getting_started) case RD_CmdKind_CancelQuery: { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("query"))); + RD_WindowState *ws = rd_window_state_from_cfg(window); + if(ws != &rd_nil_window_state) + { + ws->query_is_active = 0; + arena_clear(ws->query_arena); + ws->query_cmd_name = str8_zero(); + } }break; //- rjf: developer commands diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index c86c2133..4c78ebe3 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -124,60 +124,6 @@ struct RD_ViewUIRuleMap U64 slots_count; }; -//////////////////////////////// -//~ rjf: View State Types - -typedef struct RD_ArenaExt RD_ArenaExt; -struct RD_ArenaExt -{ - RD_ArenaExt *next; - Arena *arena; -}; - -typedef struct RD_ViewState RD_ViewState; -struct RD_ViewState -{ - // rjf: hash links & key - RD_ViewState *hash_next; - RD_ViewState *hash_prev; - RD_CfgID cfg_id; - - // rjf: touch info - U64 last_frame_index_touched; - - // rjf: loading indicator info - F32 loading_t; - F32 loading_t_target; - U64 loading_progress_v; - U64 loading_progress_v_target; - - // rjf: scroll position - UI_ScrollPt2 scroll_pos; - - // rjf: eval visualization view state - EV_View *ev_view; - - // rjf: view-lifetime allocation & user data extensions - Arena *arena; - RD_ArenaExt *first_arena_ext; - RD_ArenaExt *last_arena_ext; - void *user_data; - - // rjf: search editing controls - B32 is_searching; - TxtPt search_cursor; - TxtPt search_mark; - U8 search_buffer[KB(1)]; - U64 search_string_size; -}; - -typedef struct RD_ViewStateSlot RD_ViewStateSlot; -struct RD_ViewStateSlot -{ - RD_ViewState *first; - RD_ViewState *last; -}; - //////////////////////////////// //~ rjf: Drag/Drop Types @@ -201,7 +147,8 @@ enum RD_QueryFlag_CodeInput = (1<<2), RD_QueryFlag_KeepOldInput = (1<<3), RD_QueryFlag_SelectOldInput = (1<<4), - RD_QueryFlag_Required = (1<<5), + RD_QueryFlag_Floating = (1<<5), + RD_QueryFlag_Required = (1<<6), }; typedef U32 RD_CmdKindFlags; @@ -247,6 +194,63 @@ enum #include "generated/raddbg.meta.h" +//////////////////////////////// +//~ rjf: View State Types + +typedef struct RD_ArenaExt RD_ArenaExt; +struct RD_ArenaExt +{ + RD_ArenaExt *next; + Arena *arena; +}; + +typedef struct RD_ViewState RD_ViewState; +struct RD_ViewState +{ + // rjf: hash links & key + RD_ViewState *hash_next; + RD_ViewState *hash_prev; + RD_CfgID cfg_id; + + // rjf: touch info + U64 last_frame_index_touched; + + // rjf: loading indicator info + F32 loading_t; + F32 loading_t_target; + U64 loading_progress_v; + U64 loading_progress_v_target; + + // rjf: scroll position + UI_ScrollPt2 scroll_pos; + + // rjf: eval visualization view state + EV_View *ev_view; + + // rjf: view-lifetime allocation & user data extensions + Arena *arena; + RD_ArenaExt *first_arena_ext; + RD_ArenaExt *last_arena_ext; + void *user_data; + + // rjf: search editing controls + B32 is_searching; + Arena *search_arena; + RD_Regs *search_regs; + String8 search_cmd_name; + TxtPt search_cursor; + TxtPt search_mark; + U8 search_buffer[KB(1)]; + U64 search_string_size; +}; + +typedef struct RD_ViewStateSlot RD_ViewStateSlot; +struct RD_ViewStateSlot +{ + RD_ViewState *first; + RD_ViewState *last; +}; + //////////////////////////////// //~ rjf: Vocabulary Map @@ -571,6 +575,12 @@ struct RD_WindowState Arena *drop_completion_arena; String8List drop_completion_paths; + // rjf: query state + B32 query_is_active; + Arena *query_arena; + String8 query_cmd_name; + RD_Regs *query_regs; + // rjf: query view stack #if 0 Arena *query_cmd_arena; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 63230edb..d820323e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -73,12 +73,12 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { cv->contain_cursor = 1; }break; - case RD_CmdKind_FindTextForward: + case RD_CmdKind_Search: { arena_clear(cv->find_text_arena); cv->find_text_fwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); }break; - case RD_CmdKind_FindTextBackward: + case RD_CmdKind_SearchBackwards: { arena_clear(cv->find_text_arena); cv->find_text_bwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); @@ -3158,8 +3158,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); - RD_CmdKind kind = rd_cmd_kind_from_string(cell_info.cmd_name); - rd_cmd(kind, .cfg = cfg->id, .ctrl_entity = entity->handle); + rd_cmd(RD_CmdKind_RunCommand, .cfg = cfg->id, .ctrl_entity = entity->handle, .cmd_name = cell_info.cmd_name); } // rjf: row has callstack info? -> select unwind diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 6f8dcd6e..6d33df6e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1708,7 +1708,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(has_line_info) { Vec4F32 color = code_line_bgs[line_info_line_num % ArrayCount(code_line_bgs)]; - color.w *= line_info_t*0.2f; + color.w *= line_info_t; bg_color = color; } } @@ -2477,7 +2477,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(matches) { Vec4F32 highlight_color = code_line_bgs[line_info_line_num % ArrayCount(code_line_bgs)]; - highlight_color.w *= 0.05f; + highlight_color.w *= 0.2f; dr_rect(line_box->rect, highlight_color, 0, 0, 0); } } From 13bfa42acf94ba204ed71ccb5341c860245199f2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 14:49:25 -0800 Subject: [PATCH 153/755] more work on watch-window-driven file lister --- src/base/base_strings.c | 42 ++++++++-- src/base/base_strings.h | 1 + src/draw/draw.c | 16 +++- src/draw/draw.h | 4 +- src/eval/eval_ir.c | 119 ++++++++++++++++++++++------- src/eval/eval_parse.c | 4 +- src/raddbg/generated/raddbg.meta.c | 14 ++-- src/raddbg/raddbg.mdesk | 14 ++-- src/raddbg/raddbg_core.c | 25 +++--- src/raddbg/raddbg_views.c | 11 ++- 10 files changed, 181 insertions(+), 69 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index ed5d3147..549cc9d7 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -427,23 +427,53 @@ str8_chop(String8 str, U64 amt){ } internal String8 -str8_skip_chop_whitespace(String8 string){ +str8_skip_chop_whitespace(String8 string) +{ U8 *first = string.str; U8 *opl = first + string.size; - for (;first < opl; first += 1){ - if (!char_is_space(*first)){ + for(;first < opl; first += 1) + { + if(!char_is_space(*first)) + { break; } } - for (;opl > first;){ + for(;opl > first;) + { opl -= 1; - if (!char_is_space(*opl)){ + if(!char_is_space(*opl)) + { opl += 1; break; } } String8 result = str8_range(first, opl); - return(result); + return result; +} + +internal String8 +str8_skip_chop_slashes(String8 string) +{ + U8 *first = string.str; + U8 *opl = first + string.size; + for(;first < opl; first += 1) + { + if(!char_is_slash(*first)) + { + break; + } + } + for(;opl > first;) + { + opl -= 1; + if(!char_is_slash(*opl)) + { + opl += 1; + break; + } + } + String8 result = str8_range(first, opl); + return result; } //////////////////////////////// diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 9c1eee7b..eae374d2 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -220,6 +220,7 @@ internal String8 str8_skip(String8 str, U64 amt); internal String8 str8_postfix(String8 str, U64 size); internal String8 str8_chop(String8 str, U64 amt); internal String8 str8_skip_chop_whitespace(String8 string); +internal String8 str8_skip_chop_slashes(String8 string); //////////////////////////////// //~ rjf: String Formatting & Copying diff --git a/src/draw/draw.c b/src/draw/draw.c index e9fc8627..24b39995 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -124,8 +124,11 @@ dr_string_from_fstrs(Arena *arena, DR_FStrList *list) U64 idx = 0; for(DR_FStrNode *n = list->first; n != 0; n = n->next) { - MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); - idx += n->v.string.size; + if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)) + { + MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); + idx += n->v.string.size; + } } return result; } @@ -143,6 +146,7 @@ dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) dst_n->v.color = n->v.params.color; dst_n->v.underline_thickness = n->v.params.underline_thickness; dst_n->v.strikethrough_thickness = n->v.params.strikethrough_thickness; + dst_n->v.icon = (fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)); SLLQueuePush(run_list.first, run_list.last, dst_n); run_list.node_count += 1; run_list.dim.x += dst_n->v.run.dim.x; @@ -169,7 +173,7 @@ dr_dim_from_fstrs(DR_FStrList *fstrs) // (Frame boundaries) internal void -dr_begin_frame(void) +dr_begin_frame(FNT_Tag icon_font) { if(dr_thread_ctx == 0) { @@ -181,6 +185,7 @@ dr_begin_frame(void) arena_pop_to(dr_thread_ctx->arena, dr_thread_ctx->arena_frame_start_pos); dr_thread_ctx->free_bucket_selection = 0; dr_thread_ctx->top_bucket = 0; + dr_thread_ctx->icon_font = icon_font; } internal void @@ -627,7 +632,10 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, Fu pixel_range.min = Min(pre_advance, pixel_range.min); pixel_range.max = Max(post_advance, pixel_range.max); } - byte_off += piece->decode_size; + if(!fr->icon) + { + byte_off += piece->decode_size; + } advance += piece->advance; } } diff --git a/src/draw/draw.h b/src/draw/draw.h index 67a24171..d905818f 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -48,6 +48,7 @@ struct DR_FRun Vec4F32 color; F32 underline_thickness; F32 strikethrough_thickness; + B32 icon; }; typedef struct DR_FRunNode DR_FRunNode; @@ -98,6 +99,7 @@ struct DR_ThreadCtx { Arena *arena; U64 arena_frame_start_pos; + FNT_Tag icon_font; DR_BucketSelectionNode *top_bucket; DR_BucketSelectionNode *free_bucket_selection; }; @@ -129,7 +131,7 @@ internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs); // // (Frame boundaries & bucket submission) -internal void dr_begin_frame(void); +internal void dr_begin_frame(FNT_Tag icon_font); internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket); //////////////////////////////// diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index c90c7ccc..6daeb12b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -115,41 +115,51 @@ E_LOOKUP_INFO_FUNCTION_DEF(folder) E_Interpretation lhs_interp = e_interpret(lhs_bytecode); E_Value lhs_value = lhs_interp.value; U64 lhs_string_id = lhs_value.u64; - - //- rjf: gather files in this folder String8 folder_path = e_string_from_id(lhs_string_id); + + //- rjf: compute filter - omit common prefixes (common parent paths) + String8 local_filter = filter; + { + U64 folder_pos_in_filter = str8_find_needle(filter, 0, folder_path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive); + if(folder_pos_in_filter < filter.size) + { + local_filter = str8_skip(local_filter, folder_pos_in_filter+folder_path.size); + local_filter = str8_skip_chop_slashes(local_filter); + } + else + { + MemoryZeroStruct(&local_filter); + } + } + + //- rjf: gather & filter files in this folder String8List folder_paths = {0}; String8List file_paths = {0}; { OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0); for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);) { - if(info.props.flags & FilePropertyFlag_IsFolder) + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name); + if(matches.count == matches.needle_part_count) { - str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); - } - else - { - str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); + if(info.props.flags & FilePropertyFlag_IsFolder) + { + str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); + } + else + { + str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); + } } } os_file_iter_end(iter); } - //- rjf: build filtered paths - String8List folder_paths__filtered = {0}; - String8List file_paths__filtered = {0}; - { - // TODO(rjf) - folder_paths__filtered = folder_paths; - file_paths__filtered = file_paths; - } - //- rjf: build accelerator E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1); accel->folder_path = push_str8_copy(arena, folder_path); - accel->folders = str8_array_from_list(arena, &folder_paths__filtered); - accel->files = str8_array_from_list(arena, &file_paths__filtered); + accel->folders = str8_array_from_list(arena, &folder_paths); + accel->files = str8_array_from_list(arena, &file_paths); info.user_data = accel; info.idxed_expr_count = accel->folders.count + accel->files.count; scratch_end(scratch); @@ -192,6 +202,48 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) } } +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(folder) +{ + U64 id = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + String8 name = {0}; + if(0 < num && num <= accel->folders.count) + { + name = accel->folders.v[num-1]; + } + else if(accel->folders.count < num && num <= accel->folders.count+accel->files.count) + { + name = accel->files.v[num-accel->folders.count-1]; + } + id = e_hash_from_string(5381, name); + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(folder) +{ + U64 num = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + for(U64 idx = 0; idx < accel->folders.count+accel->files.count; idx += 1) + { + String8 name = {0}; + if(0 <= idx && idx < accel->folders.count) + { + name = accel->folders.v[idx]; + } + else if(accel->folders.count <= idx && idx < accel->folders.count+accel->files.count) + { + name = accel->files.v[idx-accel->folders.count]; + } + U64 hash = e_hash_from_string(5381, name); + if(hash == id) + { + num = idx+1; + break; + } + } + return num; +} + typedef struct E_FileAccel E_FileAccel; struct E_FileAccel { @@ -433,7 +485,9 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count) map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder)); + .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), .info = E_LOOKUP_INFO_FUNCTION_NAME(file), .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), @@ -2253,22 +2307,27 @@ E_IRGEN_FUNCTION_DEF(default) case E_ExprKind_LeafFilePath: { Temp scratch = scratch_begin(&arena, 1); - String8 file_path = path_normalized_from_string(scratch.arena, expr->string); + String8 file_path = expr->string; FileProperties props = os_properties_from_file_path(file_path); - if(props.flags & FilePropertyFlag_IsFolder || file_path.size == 0 || str8_match(file_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); - result.mode = E_Mode_Value; - } - else + if(!str8_match(expr->qualifier, str8_lit("folder"), 0) && !(props.flags & FilePropertyFlag_IsFolder) && file_path.size != 0) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); result.mode = E_Mode_Value; } + else + { + String8 folder_path = str8_chop_last_slash(file_path); + props = os_properties_from_file_path(folder_path); + if(props.flags & FilePropertyFlag_IsFolder || folder_path.size == 0 || str8_match(folder_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.mode = E_Mode_Value; + } + } scratch_end(scratch); }break; @@ -2637,6 +2696,7 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->qualifier = lhs->qualifier; lhs_bytecode->space = lhs->space; lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; @@ -2655,6 +2715,7 @@ e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->qualifier = lhs->qualifier; lhs_bytecode->space = lhs->space; lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index df2d70af..661c49af 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -747,6 +747,7 @@ e_expr_copy(Arena *arena, E_Expr *src) dst->value = t->src->value; dst->string = push_str8_copy(arena, t->src->string); dst->bytecode = push_str8_copy(arena, t->src->bytecode); + dst->qualifier = push_str8_copy(arena, t->src->qualifier); if(t->dst_parent == &e_expr_nil) { result = dst; @@ -1920,7 +1921,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: string => leaf string literal, or file path case E_TokenKind_StringLiteral: { - if(str8_match(resolution_qualifier, str8_lit("file"), 0)) + if(str8_match(resolution_qualifier, str8_lit("file"), 0) || + str8_match(resolution_qualifier, str8_lit("folder"), 0)) { String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index cc6054a8..87859791 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -443,7 +443,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -451,8 +451,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -535,7 +535,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -566,9 +566,9 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("query:search_path"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 21c58fc2..4294ddd7 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -427,7 +427,7 @@ RD_CmdTable: // | | | | //- rjf: files {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } - {Open 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Open 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } @@ -441,8 +441,8 @@ RD_CmdTable: // | | | | {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } - {OpenProject 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenUser 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes @@ -555,7 +555,7 @@ RD_CmdTable: // | | | | {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {AddTarget 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Target "select_target" "Select Target" "Selects a target." "" "" } {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } @@ -596,9 +596,9 @@ RD_CmdTable: // | | | | {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } //- rjf: queries - {PickFile 0 0 "query:search_path" FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } - {PickFolder 0 0 "query:search_path" FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } - {PickFileOrFolder 0 0 "query:search_path" FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } + {PickFile 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5ff918b6..95836e97 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5223,24 +5223,32 @@ rd_window_frame(void) String8 cmd_name = ws->query_cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(query, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(view, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); RD_ViewState *vs = rd_view_state_from_cfg(view); vs->is_searching = 1; arena_clear(vs->search_arena); vs->search_cmd_name = push_str8_copy(vs->search_arena, ws->query_cmd_name); vs->search_regs = rd_regs_copy(vs->search_arena, ws->query_regs); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); String8 query_expression = cmd_kind_info->query.expr; - B32 size_query_by_expr_eval = 0; if(query_expression.size == 0) { query_expression = str8(vs->search_buffer, vs->search_string_size); RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); - size_query_by_expr_eval = 1; } else { + U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expression.size) + { + String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); + String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); + query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->search_buffer, vs->search_string_size), post_insertion); + } rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); } rd_cfg_new_replace(expr, query_expression); @@ -11344,15 +11352,6 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } - //- rjf: add macro for 'search path' - { - String8 search_path = rd_state->current_path; - String8 search_path_escaped = escaped_from_raw_str8(scratch.arena, search_path); - String8 search_path_eval_string = push_str8f(scratch.arena, "file:\"%S\"", search_path_escaped); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, search_path_eval_string).exprs.first; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("search_path"), expr); - } - //- rjf: add macro for watches group { String8 collection_name = str8_lit("watches"); @@ -15264,7 +15263,7 @@ Z(getting_started) //- rjf: update/render all windows // { - dr_begin_frame(); + dr_begin_frame(rd_font_from_slot(RD_FontSlot_Icons)); RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d820323e..dbfa0d5a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3044,7 +3044,16 @@ RD_VIEW_UI_FUNCTION_DEF(watch) { searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); } - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, rd_view_search(), searched_string); + String8 search_query = rd_view_search(); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); + if(fuzzy_matches.count == 0) + { + String8 path_needle = str8_skip_last_slash(search_query); + if(0 < path_needle.size && path_needle.size < search_query.size) + { + fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); + } + } // rjf: build RD_LineEditParams line_edit_params = {0}; From ec782fa39c9698dc07de863e029c2721bf248bea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 16:26:40 -0800 Subject: [PATCH 154/755] correct tag poisoning in lookup-rule tag usage within ir generation, allow lookup-rules to call dependent irgens --- src/eval/eval_ir.c | 146 +++++++----------- src/eval/eval_ir.h | 5 + .../eval_visualization_core.c | 10 ++ src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 40 ++--- 6 files changed, 95 insertions(+), 110 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 6daeb12b..0d9f6a65 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1565,6 +1565,50 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type return result; } +//- rjf: rule tag poison checking + +internal B32 +e_tag_is_poisoned(E_Expr *tag) +{ + B32 tag_is_poisoned = 0; + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + { + if(n->tag == tag) + { + tag_is_poisoned = 1; + break; + } + } + return tag_is_poisoned; +} + +internal void +e_tag_poison(E_Expr *tag) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + E_UsedTagNode *n = push_array(e_ir_state->arena, E_UsedTagNode, 1); + n->tag = tag; + DLLPushBack(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); +} + +internal void +e_tag_unpoison(E_Expr *tag) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&tag)); + U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + { + if(n->tag == tag) + { + DLLRemove(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); + break; + } + } +} + //- rjf: top-level irtree/type extraction E_IRGEN_FUNCTION_DEF(default) @@ -1583,55 +1627,14 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - - // rjf: determine lookup rule - first check explicitly-specified tags - E_LookupRule *lookup_rule = &e_lookup_rule__default; - for(E_Expr *tag = lhs->first_tag; tag != &e_expr_nil; tag = tag->next) + E_LookupRuleTagPair lhs_lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(lhs, &lhs_irtree); + ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule_and_tag.rule->name)) { - E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); - if(candidate != &e_lookup_rule__nil) - { - lookup_rule = candidate; - break; - } - } - - // rjf: if the lookup rule is the default, try to (a) apply set-name hooks, or (b) apply auto-hooks - if(lookup_rule == &e_lookup_rule__default) - { - // rjf: try set name - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - if(lhs_type->kind == E_TypeKind_Set) - { - E_LookupRule *candidate = e_lookup_rule_from_string(lhs_type->name); - if(candidate != &e_lookup_rule__nil) - { - lookup_rule = candidate; - } - } - - // rjf: try auto tags - if(lookup_rule == &e_lookup_rule__default) - { - E_ExprList auto_tags = e_auto_hook_tag_exprs_from_type_key__cached(lhs_irtree.type_key); - for(E_ExprNode *n = auto_tags.first; n != 0; n = n->next) - { - E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); - if(candidate != &e_lookup_rule__nil) - { - lookup_rule = candidate; - break; - } - } - } - } - - // rjf: use lookup rule to actually do the access - ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name)) - { - E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, str8_zero()); - E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); + e_tag_poison(lhs_lookup_rule_and_tag.tag); + E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, str8_zero()); + E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); result = lookup_access.irtree_and_type; + e_tag_unpoison(lhs_lookup_rule_and_tag.tag); } scratch_end(scratch); }break; @@ -2383,17 +2386,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); if(irgen_rule_candidate != &e_irgen_rule__default) { - B32 tag_is_poisoned = 0; - U64 hash = e_hash_from_string(5381, str8_struct(&tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) - { - if(n->tag == tag) - { - tag_is_poisoned = 1; - break; - } - } + B32 tag_is_poisoned = e_tag_is_poisoned(tag); if(!tag_is_poisoned) { explicit_irgen_rule = irgen_rule_candidate; @@ -2417,14 +2410,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) 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) - { - U64 hash = e_hash_from_string(5381, str8_struct(&t->tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1); - n->tag = t->tag; - DLLPushBack(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); - } + e_tag_poison(t->tag); // rjf: do this rule's generation ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) @@ -2443,17 +2429,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next) { - B32 tag_is_poisoned = 0; - U64 hash = e_hash_from_string(5381, str8_struct(&tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) - { - if(n->tag == tag) - { - tag_is_poisoned = 1; - break; - } - } + B32 tag_is_poisoned = e_tag_is_poisoned(tag); if(!tag_is_poisoned) { E_IRGenRule *rule = e_irgen_rule_from_string(tag->string); @@ -2474,19 +2450,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) //- 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_state->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) - { - if(n->tag == t->tag) - { - DLLRemove(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); - break; - } - } - } + e_tag_unpoison(t->tag); } scratch_end(scratch); @@ -2806,6 +2770,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) { + if(e_tag_is_poisoned(tag)) { continue; } E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); if(candidate != &e_lookup_rule__nil) { @@ -2838,6 +2803,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) { + if(e_tag_is_poisoned(n->v)) { continue; } E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); if(candidate != &e_lookup_rule__nil) { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index cfcecfb3..c1cfad6d 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -448,6 +448,11 @@ internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key) internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in); internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); +//- rjf: rule tag poison checking +internal B32 e_tag_is_poisoned(E_Expr *tag); +internal void e_tag_poison(E_Expr *tag); +internal void e_tag_unpoison(E_Expr *tag); + //- rjf: top-level irtree/type extraction internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ed8ad052..ee6db1d9 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -498,6 +498,16 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key next = tag->next; e_expr_push_tag(expr, tag); } + + // rjf: push tags inferred from the type + { + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); + E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree.type_key); + for(E_ExprNode *n = tags.first; n != 0; n = n->next) + { + e_expr_push_tag(expr, e_expr_copy(arena, n->v)); + } + } } scratch_end(scratch); } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 87859791..cfb3a3ff 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -814,7 +814,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x341f3dff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x2f2633ff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4294ddd7..e8561041 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1118,7 +1118,7 @@ RD_ThemePresetTable: border: 0x9e6274ff, inactive: { - background: 0x341f3dff, + background: 0x2f2633ff, border: 0x685073ff, } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 95836e97..2ab193ed 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7196,8 +7196,8 @@ rd_window_frame(void) UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) UI_TagF(omit_name ? "hollow" : "") - UI_TagF(!tab_is_selected ? "inactive" : "") - UI_TagF(tab_is_auto ? "auto" : "") + UI_TagF(!omit_name && !tab_is_selected ? "inactive" : "") + UI_TagF(!omit_name && tab_is_auto ? "auto" : "") { if(panel->tab_side == Side_Max) { @@ -8251,6 +8251,13 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } else { + // rjf: unpack + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("["); String8 closer_string = str8_lit("]"); @@ -8262,12 +8269,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f // rjf: contents { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); - U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); B32 is_first = 1; for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) { @@ -8384,9 +8385,16 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f case E_TypeKind_Set: arrays_and_sets_and_structs: { + // rjf: unpack + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); + E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); + U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("{"); String8 closer_string = str8_lit("}"); - if(kind == E_TypeKind_Array) + if(lookup_info.idxed_expr_count > lookup_info.named_expr_count) { opener_string = str8_lit("["); closer_string = str8_lit("]"); @@ -8401,12 +8409,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f // rjf: build contents if(depth < 4) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); - U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); B32 is_first = 1; for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) { @@ -11969,6 +11971,8 @@ rd_frame(void) }break; //- rjf: code navigation + case RD_CmdKind_Search: + case RD_CmdKind_SearchBackwards: case RD_CmdKind_FindTextForward: case RD_CmdKind_FindTextBackward: { @@ -11978,11 +11982,11 @@ rd_frame(void) //- rjf: find next and find prev case RD_CmdKind_FindNext: { - rd_cmd(RD_CmdKind_FindTextForward, .string = rd_push_search_string(scratch.arena)); + rd_cmd(RD_CmdKind_Search, .string = rd_push_search_string(scratch.arena)); }break; case RD_CmdKind_FindPrev: { - rd_cmd(RD_CmdKind_FindTextBackward, .string = rd_push_search_string(scratch.arena)); + rd_cmd(RD_CmdKind_SearchBackwards, .string = rd_push_search_string(scratch.arena)); }break; //- rjf: font sizes @@ -13769,7 +13773,7 @@ Z(getting_started) }break; #endif - //- rjf: query stack + //- rjf: queries case RD_CmdKind_PushQuery: { String8 cmd_name = rd_regs()->cmd_name; From 428a3f2536df32e8972ac16aeb752f657c261b93 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 16:38:27 -0800 Subject: [PATCH 155/755] always prefer explicitly attached tags (view rules); give all tags a chance in sequence; allow 'default' to be explicitly attached, to disable auto-view-rules etc. --- src/eval/eval_ir.c | 17 +++++++++------- .../eval_visualization_core.c | 20 +++++++++---------- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 4 ++-- src/raddbg/raddbg_widgets.c | 8 ++++---- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0d9f6a65..9394872a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -483,6 +483,11 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count) E_LookupRuleMap map = {0}; map.slots_count = slots_count; map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(default), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), @@ -1031,10 +1036,11 @@ e_irgen_rule_map_make(Arena *arena, U64 slots_count) E_IRGenRuleMap map = {0}; map.slots_count = slots_count; map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("default"), .irgen = E_IRGEN_FUNCTION_NAME(default)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); + e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); return map; } @@ -2391,7 +2397,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { explicit_irgen_rule = irgen_rule_candidate; explicit_irgen_rule_tag = tag; - break; } } } @@ -2776,7 +2781,6 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { result.rule = candidate; result.tag = tag; - break; } } } @@ -2809,7 +2813,6 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { result.rule = candidate; result.tag = n->v; - break; } } } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ee6db1d9..5b3ba0c0 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -489,16 +489,6 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key } } - // rjf: push explicitly-attached tags (via key) next - String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); - E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) - { - next = tag->next; - e_expr_push_tag(expr, tag); - } - // rjf: push tags inferred from the type { E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); @@ -508,6 +498,16 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key e_expr_push_tag(expr, e_expr_copy(arena, n->v)); } } + + // rjf: push explicitly-attached tags (via key) next + String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); + E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) + { + next = tag->next; + e_expr_push_tag(expr, tag); + } } scratch_end(scratch); } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index cfb3a3ff..fac3994b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -308,7 +308,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[12] = {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e8561041..b1124a51 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -213,7 +213,7 @@ RD_VocabTable: //- rjf: auto view rules { auto_view_rule, - ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'source':code_string, 'dest':code_string}```, + ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, } //- rjf: recent projects diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2ab193ed..4afdd2b0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11527,8 +11527,8 @@ rd_frame(void) for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) { RD_Cfg *rule = n->v; - String8 type_string = rd_cfg_child_from_string(rule, str8_lit("source"))->first->string; - String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("dest"))->first->string; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 6d33df6e..566b3095 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -301,8 +301,8 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) //- rjf: special case: auto view rule if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) { - String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("source"))->first->string; - String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("dest"))->first->string; + String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("type"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("view_rule"))->first->string; Vec4F32 src_color = rgba; Vec4F32 dst_color = rgba; DR_FStrList src_fstrs = {0}; @@ -328,9 +328,9 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) dst_fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, dst_color, dst_string); } dr_fstrs_concat_in_place(&result, &src_fstrs); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&result, &dst_fstrs); } From cc966deb7ceb07ab790c046dcbdd027dcd6e7e30 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 17:25:38 -0800 Subject: [PATCH 156/755] eliminate 'watch' as a view ui rule, move formally into just being a regular view ui build. hook up user file saving. fix metadesk parser - newlines must terminate *all* active implicit set parsing work. --- src/mdesk/mdesk.c | 7 +- src/os/core/linux/os_core_linux.c | 6 + src/os/core/os_core.h | 1 + src/os/core/win32/os_core_win32.c | 11 + src/raddbg/raddbg_core.c | 1879 ++++++++++++++++++++++++++++- src/raddbg/raddbg_views.c | 1861 ---------------------------- src/raddbg/raddbg_views.h | 2 - 7 files changed, 1901 insertions(+), 1866 deletions(-) diff --git a/src/mdesk/mdesk.c b/src/mdesk/mdesk.c index 92c9bcff..bc314dd2 100644 --- a/src/mdesk/mdesk.c +++ b/src/mdesk/mdesk.c @@ -1052,10 +1052,13 @@ if(work_top == 0) {work_top = &broken_work;}\ goto end_consume; } - //- rjf: [main_implicit] newline -> pop + //- rjf: [main_implicit] newline -> pop *all* current implicit work tasks if(work_top->kind == MD_ParseWorkKind_MainImplicit && token->flags & MD_TokenFlag_Newline) { - MD_ParseWorkPop(); + for(;work_top->kind == MD_ParseWorkKind_MainImplicit;) + { + MD_ParseWorkPop(); + } token += 1; goto end_consume; } diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 3b2c73b1..5acd5cf8 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -443,6 +443,12 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + // TODO(rjf) +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 5f09ca8b..8edba0ea 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -208,6 +208,7 @@ internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); +internal B32 os_move_file_path(String8 dst, String8 src); internal String8 os_full_path_from_path(Arena *arena, String8 path); internal B32 os_file_path_exists(String8 path); internal B32 os_folder_path_exists(String8 path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 0aa5cce0..0f9150f9 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -490,6 +490,17 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + Temp scratch = scratch_begin(0, 0); + String16 dst16 = str16_from_8(scratch.arena, dst); + String16 src16 = str16_from_8(scratch.arena, src); + B32 result = MoveFileW((WCHAR*)src16.str, (WCHAR*)dst16.str); + scratch_end(scratch); + return result; +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4afdd2b0..bfb2e0b9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3682,6 +3682,1858 @@ rd_view_ui(Rng2F32 rect) scratch_end(scratch); } + //////////////////////////// + //- rjf: watch view + // + else if(str8_match(view_name, str8_lit("watch"), 0)) + { + Temp scratch = scratch_begin(0, 0); + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); + UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + B32 is_first_frame = 0; + if(ewv->initialized == 0) + { + is_first_frame = 1; + ewv->initialized = 1; + ewv->text_edit_arena = rd_push_view_arena(); + } + + ////////////////////////////// + //- rjf: unpack arguments + // + EV_View *eval_view = rd_view_eval_view(); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); + F32 row_string_max_size_px = dim_2f32(rect).x; + EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; + String8 filter = rd_view_search(); + Vec4F32 pop_background_rgba = {0}; + UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); + + ////////////////////////////// + //- rjf: decide if root should be implicit + // + // "implicit" means -> root is automatically expanded, row depth is 1 less than the + // block tree structure would suggest. this would be used if the root is, for instance, + // the "collection of all watches", to build a watch window. but this behavior is not + // as desirable if we are just using some other expression as the root. + // + B32 implicit_root = !rd_view_cfg_value_from_string(str8_lit("explicit_root")).u64; + + ////////////////////////////// + //- rjf: determine autocompletion string + // + String8 autocomplete_hint_string = {0}; + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = evt->string; + break; + } + } + } + + ////////////////////////////// + //- rjf: consume events & perform navigations/edits - calculate state + // + EV_BlockTree block_tree = {0}; + EV_BlockRangeList block_ranges = {0}; + UI_ScrollListRowBlockArray row_blocks = {0}; + Vec2S64 cursor_tbl = {0}; + Vec2S64 mark_tbl = {0}; + Rng2S64 selection_tbl = {0}; + ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) + { + B32 state_dirty = 1; + B32 snap_to_cursor = 0; + B32 cursor_dirty__tbl = 0; + B32 take_autocomplete = 0; + for(UI_Event *event = 0;;) + { + ////////////////////////// + //- rjf: state -> viz blocks + // + if(state_dirty) ProfScope("state -> viz blocks") + { + MemoryZeroStruct(&block_tree); + MemoryZeroStruct(&block_ranges); + if(implicit_root || is_first_frame) + { + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + } + block_tree = ev_block_tree_from_exprs(scratch.arena, eval_view, filter, eval.exprs); + block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); + if(implicit_root && block_ranges.first != 0) + { + block_ranges.count -= 1; + block_ranges.first = block_ranges.first->next; + } + } + + ////////////////////////// + //- rjf: block ranges -> ui row blocks + // + ProfScope("block ranges -> ui row blocks") + { + UI_ScrollListRowBlockChunkList row_block_chunks = {0}; + for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) + { + UI_ScrollListRowBlock block = {0}; + block.row_count = dim_1u64(n->v.range); + block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); + } + row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); + } + + ////////////////////////// + //- rjf: conclude state update + // + if(state_dirty) + { + state_dirty = 0; + } + + ////////////////////////////// + //- rjf: 2D table coordinates * blocks -> stable cursor state + // + if(cursor_dirty__tbl) + { + cursor_dirty__tbl = 0; + struct + { + RD_WatchPt *pt_state; + Vec2S64 pt_tbl; + } + points[] = + { + {&ewv->cursor, cursor_tbl}, + {&ewv->mark, mark_tbl}, + }; + for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) + { + EV_Key last_key = points[point_idx].pt_state->key; + EV_Key last_parent_key = points[point_idx].pt_state->parent_key; + points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); + if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) + { + points[point_idx].pt_state->key = last_parent_key; + EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); + for(EV_ExpandNode *n = node; n != 0; n = n->parent) + { + points[point_idx].pt_state->key = n->key; + if(n->expanded == 0) + { + break; + } + } + } + if(point_idx == 0 && + (!ev_key_match(ewv->cursor.key, last_key) || + !ev_key_match(ewv->cursor.parent_key, last_parent_key))) + { + ewv->text_editing = 0; + } + } + ewv->next_cursor = ewv->cursor; + ewv->next_mark = ewv->mark; + } + + ////////////////////////// + //- rjf: stable cursor state * blocks -> 2D table coordinates + // + EV_WindowedRowList mark_rows = {0}; + Rng2S64 cursor_tbl_range = {0}; + { + // rjf: compute 2d table coordinates + cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); + mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); + + // rjf: compute legal coordinate range, given selection-defining row + Rng1S64 cursor_x_range = {0}; + { + EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); + } + cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); + + // rjf: clamp x positions of cursor/mark tbl + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); + } + + // rjf: form selection range table coordinates + selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), + Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); + } + + ////////////////////////// + //- rjf: [table] snap to cursor + // + if(snap_to_cursor) + { + Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); + if(contains_1s64(global_vnum_range, cursor_tbl.y)) + { + UI_ScrollPt *scroll_pt = &scroll_pos.y; + + //- rjf: compute visible row range + Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), + scroll_pt->idx + 1 + num_possible_visible_rows); + + //- rjf: compute cursor row range from cursor item + Rng1S64 cursor_visibility_row_num_range = {0}; + cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; + cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; + + //- rjf: compute deltas & apply + S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); + S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); + S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; + new_num = clamp_1s64(global_vnum_range, new_num); + if(new_num > 0) + { + U64 new_idx = (U64)(new_num - 1); + ui_scroll_pt_target_idx(scroll_pt, new_idx); + } + } + } + + ////////////////////////////// + //- rjf: apply cursor/mark rugpull change + // + B32 cursor_rugpull = 0; + if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) + { + cursor_rugpull = 1; + ewv->cursor = ewv->next_cursor; + ewv->mark = ewv->next_mark; + } + + ////////////////////////// + //- rjf: grab next event, if any - otherwise exit the loop, as we now have + // the most up-to-date state + // + B32 next_event_good = ui_next_event(&event); + if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) + { + break; + } + UI_Event dummy_evt = zero_struct; + UI_Event *evt = &dummy_evt; + if(next_event_good) + { + evt = event; + } + B32 taken = 0; + + ////////////////////////// + //- rjf: begin editing on some operations + // + if(!ewv->text_editing && + (evt->kind == UI_EventKind_Text || + evt->flags & UI_EventFlag_Paste || + (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && + selection_tbl.min.x == selection_tbl.max.x && + (selection_tbl.min.y != 0 || selection_tbl.min.y != 0)) + { + Vec2S64 selection_dim = dim_2s64(selection_tbl); + arena_clear(ewv->text_edit_arena); + ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); + ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); + ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + B32 any_edits_started = 0; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.flags & RD_WatchCellFlag_CanEdit) + { + any_edits_started = 1; + String8 string = cell_info.string; + string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + U64 hash = ev_hash_from_key(pt.key); + U64 slot_idx = hash%ewv->text_edit_state_slots_count; + RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); + SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); + edit_state->pt = pt; + edit_state->cursor = txt_pt(1, string.size+1); + edit_state->mark = txt_pt(1, 1); + edit_state->input_size = string.size; + MemoryCopy(edit_state->input_buffer, string.str, string.size); + edit_state->initial_size = string.size; + MemoryCopy(edit_state->initial_buffer, string.str, string.size); + } + } + } + ewv->text_editing = any_edits_started; + } + + ////////////////////////// + //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if + // cannot apply to multi-cursor, then just don't take the event + // + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept) + { + taken = 1; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + { + // rjf: unpack row info + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + + // rjf: loop through X selections and perform operations for each + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + { +#if 0 // TODO(rjf): @cfg + //- rjf: determine operation for this cell + typedef enum OpKind + { + OpKind_Null, + OpKind_DoExpand, + } + OpKind; + OpKind kind = OpKind_Null; + switch(row_kind) + { + default:{}break; + case RD_WatchViewRowKind_Normal: + { + RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; + } + }break; + case RD_WatchViewRowKind_PrettyEntityControls: + if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) + { + kind = OpKind_DoExpand; + }break; + } + + //- rjf: perform operation + switch(kind) + { + default:{taken = 0;}break; + case OpKind_DoExpand: + if(ev_row_is_expandable(row)) + { + B32 is_expanded = ev_expansion_from_key(eval_view, row->key); + ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); + }break; + } +#endif + } + } + } + + ////////////////////////// + //- rjf: [text] apply textual edits + // + if(ewv->text_editing) + { + B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || + (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || + cursor_rugpull); + rd_state->text_edit_mode = 1; + if(editing_complete || + ((evt->kind == UI_EventKind_Edit || + evt->kind == UI_EventKind_Navigate || + evt->kind == UI_EventKind_Text) && + evt->delta_2s32.y == 0)) + { + taken = 1; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); + String8 string = str8(edit_state->input_buffer, edit_state->input_size); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + + // rjf: copy + if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) + { + os_set_clipboard_text(op.copy); + } + + // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(autocomplete_hint_string.size != 0) + { + take_autocomplete = 1; + String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); + U64 word_off = (U64)(word_query.str - string.str); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + string = str8(edit_state->input_buffer, edit_state->input_size); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + } + + // rjf: cancel? -> revert to initial string + if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) + { + string = str8(edit_state->initial_buffer, edit_state->initial_size); + } + + // rjf: obtain edited string + String8 new_string = string; + if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + { + new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); + } + + // rjf: commit to edit state + new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = op.cursor; + edit_state->mark = op.mark; + + // rjf: commit edited cell string + switch(cell->kind) + { + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg_child; + String8 child_key = str8_lit("expression"); + if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) + { + RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; + if(new_cfg_parent != &rd_nil_cfg) + { + child_key = str8_zero(); + } + if(new_cfg_parent == &rd_nil_cfg) + { + RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); + new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + } + if(new_cfg_parent == &rd_nil_cfg) + { + new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + } + cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); + state_dirty = 1; + snap_to_cursor = 1; + } + if(cfg != &rd_nil_cfg) + { + RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; + rd_cfg_new_replace(expr, new_string); + } + }break; + case RD_WatchCellKind_Tag: + if(editing_complete) + { + ev_key_set_view_rule(eval_view, pt.key, new_string); + RD_Cfg *cfg = row_info.group_cfg_child; + if(cfg != &rd_nil_cfg && new_string.size != 0) + { + RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); + rd_cfg_new(view_rule, new_string); + } + else if(cfg != &rd_nil_cfg && new_string.size == 0) + { + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("view_rule"))); + } + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.eval.mode == E_Mode_Offset) + { + B32 should_commit_asap = editing_complete; + if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + should_commit_asap = 1; + } + else if(evt->slot != UI_EventActionSlot_Cancel) + { + should_commit_asap = editing_complete; + } + if(should_commit_asap) + { + B32 success = 0; + success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); + if(!success) + { + log_user_error(str8_lit("Could not commit value successfully.")); + } + } + } + }break; + } + } + } + } + if(editing_complete) + { + ewv->text_editing = 0; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity copies + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) + { + taken = 1; + String8List strs = {0}; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 cell_string = cell_info.string; + cell_string = str8_skip_chop_whitespace(cell_string); + U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); + if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) + { + str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", + comma_pos < cell_string.size ? "\"" : "", + cell_string, + comma_pos < cell_string.size ? "\"" : "", + cell_x+1 <= selection_tbl.max.x ? "," : ""); + } + else + { + str8_list_push(scratch.arena, &strs, cell_string); + } + } + if(y+1 <= selection_tbl.max.y) + { + str8_list_push(scratch.arena, &strs, str8_lit("\n")); + } + } + String8 string = str8_list_join(scratch.arena, &strs, 0); + os_set_clipboard_text(string); + } + + ////////////////////////// + //- rjf: [table] do cell-granularity deletions + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) + { + taken = 1; + state_dirty = 1; + snap_to_cursor = 1; + RD_CfgList cfgs_to_remove = {0}; + RD_WatchPt next_cursor_pt = {0}; + B32 next_cursor_set = 0; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + switch(cell->kind) + { + default:{}break; + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg_child; + if(cfg != &rd_nil_cfg) + { + rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); + U64 deleted_num = row->block->lookup_rule->num_from_id(row->key.child_id, row->block->lookup_rule_user_data); + if(deleted_num != 0) + { + EV_Key parent_key = row->block->parent->key; + EV_Key key = row->block->key; + U64 fallback_id_prev = row->block->lookup_rule->id_from_num(deleted_num-1, row->block->lookup_rule_user_data); + U64 fallback_id_next = row->block->lookup_rule->id_from_num(deleted_num+1, row->block->lookup_rule_user_data); + if(fallback_id_next != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_next); + } + else if(fallback_id_prev != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_prev); + } + RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; + next_cursor_pt = new_pt; + next_cursor_set = 1; + state_dirty = 1; + } + } + }break; + case RD_WatchCellKind_Tag: + { + if(row_info.group_cfg_child != &rd_nil_cfg) + { + rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg_child, str8_lit("view_rule"))); + } + ev_key_set_view_rule(eval_view, row->key, str8_zero()); + state_dirty = 1; + }break; + case RD_WatchCellKind_Eval: + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); + }break; + } + } + } + for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + if(next_cursor_set) + { + ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; + } + } + + ////////////////////////// + //- rjf: [table] apply deltas to cursor & mark + // + if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) + { + B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; + Vec2S32 delta = evt->delta_2s32; + if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + if(delta.x > 0 || delta.y > 0) + { + cursor_tbl.x = selection_tbl.max.x; + cursor_tbl.y = selection_tbl.max.y; + } + else if(delta.x < 0 || delta.y < 0) + { + cursor_tbl.x = selection_tbl.min.x; + cursor_tbl.y = selection_tbl.min.y; + } + } + if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + MemoryZeroStruct(&delta); + } + B32 moved = 1; + switch(evt->delta_unit) + { + default:{moved = 0;}break; + case UI_EventDeltaUnit_Char: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] += delta.v[axis]; + if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; + } + if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; + } + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + } + }break; + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Page: + { + cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : + delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : + cursor_tbl.x); + cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : + delta.y<0 ? -(num_possible_visible_rows-3) : + 0)); + cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], + cursor_tbl_range.max.y), + cursor_tbl.y); + }break; + case UI_EventDeltaUnit_Whole: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); + } + }break; + } + if(moved) + { + taken = 1; + cursor_dirty__tbl = 1; + snap_to_cursor = 1; + } + } + + ////////////////////////// + //- rjf: [table] stick table mark to cursor if needed + // + if(!ewv->text_editing) + { + if(taken && !(evt->flags & UI_EventFlag_KeepMark)) + { + mark_tbl = cursor_tbl; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity reorders + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) + { + taken = 1; + if(filter.size == 0) + { + // rjf: determine blocks of each endpoint of the table selection + EV_Block *selection_endpoint_blocks[2] = + { + ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, + ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, + }; + + // rjf: pick shallowest block within which we can do reordering + U64 selection_depths[2] = + { + ev_depth_from_block(selection_endpoint_blocks[0]), + ev_depth_from_block(selection_endpoint_blocks[1]), + }; + EV_Block *selection_block = (selection_depths[1] < selection_depths[0] + ? selection_endpoint_blocks[1] + : selection_endpoint_blocks[0]); + + // rjf: find selection keys within the block in which we are doing reordering + EV_Key selection_keys_in_block[2] = {0}; + { + for EachElement(idx, selection_endpoint_blocks) + { + EV_Block *endpoint_block = selection_endpoint_blocks[idx]; + if(endpoint_block == selection_block) + { + selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); + } + else + { + for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) + { + endpoint_block = endpoint_block->parent; + } + if(endpoint_block->parent == selection_block) + { + selection_keys_in_block[idx] = endpoint_block->key; + } + } + } + EV_Key fallback_key = {0}; + for EachElement(idx, selection_endpoint_blocks) + { + if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + fallback_key = selection_keys_in_block[idx]; + } + } + for EachElement(idx, selection_endpoint_blocks) + { + if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + selection_keys_in_block[idx] = fallback_key; + } + } + } + + // rjf: determine collection info for the block + String8 group_cfg_name = {0}; + { + E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); + E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + if(block_type_kind == E_TypeKind_Set) + { + E_Type *block_type = e_type_from_key__cached(block_type_key); + group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + if(group_cfg_name.size == 0) + { + group_cfg_name = block_type->name; + } + } + } + + // rjf: map selection endpoints to cfgs + RD_Cfg *first_cfg = &rd_nil_cfg; + RD_Cfg *last_cfg = &rd_nil_cfg; + if(group_cfg_name.size != 0) + { + first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); + last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); + } + + // rjf: reorder + if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) + { + RD_Cfg *first_cfg_prev = &rd_nil_cfg; + RD_Cfg *last_cfg_next = &rd_nil_cfg; + for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) + { + if(str8_match(prev->string, first_cfg->string, 0)) + { + first_cfg_prev = prev; + break; + } + } + for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) + { + if(str8_match(next->string, last_cfg->string, 0)) + { + last_cfg_next = next; + break; + } + } + if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = first_cfg_prev->parent; + rd_cfg_unhook(parent, first_cfg_prev); + rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); + } + if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = last_cfg_next->parent; + rd_cfg_unhook(parent, last_cfg_next); + rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); + } + } + } + } + + ////////////////////////// + //- rjf: consume event, if taken + // + if(taken && evt != &dummy_evt) + { + ui_eat_event(evt); + } + } + if(take_autocomplete) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + ui_eat_event(evt); + break; + } + } + } + } + + ////////////////////////////// + //- rjf: build ui + // + B32 pressed = 0; + ProfScope("build ui") + { + Rng1S64 visible_row_rng = {0}; + UI_ScrollListParams scroll_list_params = {0}; + { + scroll_list_params.flags = UI_ScrollListFlag_All; + scroll_list_params.row_height_px = row_height_px; + scroll_list_params.dim_px = dim_2f32(rect); + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); + scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); + scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; + scroll_list_params.row_blocks = row_blocks; + } + UI_BoxFlags disabled_flags = ui_top_flags(); + if(d_ctrl_targets_running()) + { + disabled_flags |= UI_BoxFlag_Disabled; + } + UI_ScrollListSignal scroll_list_sig = {0}; + UI_Focus(UI_FocusKind_On) + UI_ScrollList(&scroll_list_params, &scroll_pos.y, + 0, + 0, + &visible_row_rng, + &scroll_list_sig) + UI_Focus(UI_FocusKind_Null) + { + ui_set_next_pref_height(ui_children_sum(1)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); + UI_Parent(table) + { + Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; + + //////////////////////// + //- rjf: viz blocks -> rows + // + EV_WindowedRowList rows = {0}; + { + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); + } + + //////////////////////// + //- rjf: rows -> row infos + // + RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build boundaries + // + B32 cell_pcts_are_dirty = 0; + ProfScope("build boundaries") + { + U64 idx = 0; + U64 boundary_start_idx = 0; + EV_Row *last_row = 0; + RD_WatchRowInfo *last_row_info = 0; + for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) + { + //- rjf: determine if this row breaks the topology + B32 is_new_topology = (row_node == 0); + if(row_node != 0 && last_row_info != 0) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[idx]; + for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + is_new_topology = 1; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + is_new_topology = 1; + break; + } + } + } + + //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations + if(is_new_topology) + { + EV_Row *row = last_row; + RD_WatchRowInfo *row_info = last_row_info; + F32 row_width_px = (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + if(row_info != 0) + { + U64 row_hash = ev_hash_from_key(row->key); + F32 cell_x_px = 0; + U64 cell_idx = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) + { + if(cell->pct == 0 || cell->next->pct == 0) + { + continue; + } + U64 cell_id = rd_id_from_watch_cell(cell); + F32 cell_width_px = cell->px + cell->pct * row_width_px; + F32 next_cell_x_px = cell_x_px + cell_width_px; + { + Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.2f, + boundary_start_idx*row_height_px, + next_cell_x_px + ui_top_font_size()*0.2f, + idx*row_height_px); + UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig)) + { + typedef struct DragData DragData; + struct DragData + { + F32 min_pct; + F32 max_pct; + }; + if(ui_pressed(sig)) + { + DragData drag_data = {cell->pct, cell->next->pct}; + ui_store_drag_struct(&drag_data); + } + DragData *drag_data = ui_get_drag_struct(DragData); + F32 min_pct__pre = drag_data->min_pct; + F32 max_pct__pre = drag_data->max_pct; + F32 min_px__pre = min_pct__pre*row_width_px; + F32 max_px__pre = max_pct__pre*row_width_px; + F32 min_px__post = min_px__pre + ui_drag_delta().x; + F32 max_px__post = max_px__pre - ui_drag_delta().x; + F32 min_pct__post = min_px__post/row_width_px; + F32 max_pct__post = max_px__post/row_width_px; + if(min_pct__post < 0.05f) + { + min_pct__post = 0.05f; + max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; + } + if(max_pct__post < 0.05f) + { + max_pct__post = 0.05f; + min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; + } + if(ui_double_clicked(sig)) + { + F32 default_sum = cell->default_pct + cell->next->default_pct; + F32 current_sum = min_pct__pre + max_pct__pre;; + min_pct__post = current_sum * (cell->default_pct / default_sum); + max_pct__post = current_sum * (cell->next->default_pct / default_sum); + ui_kill_action(); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); + RD_Cfg *min_cfg = &rd_nil_cfg; + RD_Cfg *max_cfg = &rd_nil_cfg; + { + RD_Cfg *pct_child = style->first; + U64 c_idx = 0; + for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) + { + if(pct_child == &rd_nil_cfg) + { + pct_child = rd_cfg_newf(style, "%f", c->pct); + } + if(c_idx == cell_idx) + { + min_cfg = pct_child; + } + if(c_idx == cell_idx+1) + { + max_cfg = pct_child; + } + pct_child = pct_child->next; + } + rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); + rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); + cell_pcts_are_dirty = 1; + } + } + } + } + cell_x_px = next_cell_x_px; + } + } + boundary_start_idx = idx; + } + + //- rjf: advance + if(row_node == 0) + { + break; + } + else + { + last_row = &row_node->row; + last_row_info = &row_infos[idx]; + } + } + } + + //////////////////////// + //- rjf: if cell widths are dirty -> recompute row infos + // + if(cell_pcts_are_dirty) + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build table + // + ProfScope("build table") + { + U64 local_row_idx = 0; + U64 global_row_idx = rows.count_before_semantic; + RD_WatchRowInfo last_row_info = {0}; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) + { + //////////////////////// + //- rjf: unpack row info + // + ProfBegin("unpack row info"); + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; + U64 row_hash = ev_hash_from_key(row->key); + U64 row_depth = ev_depth_from_block(row->block); + B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); + B32 row_expanded = ev_expansion_from_key(eval_view, row->key); + B32 next_row_expanded = row_expanded; + B32 row_is_expandable = ev_row_is_expandable(row); + if(implicit_root && row_depth > 0) + { + row_depth -= 1; + } + ProfEnd(); + + //////////////////////// + //- rjf: determine if this row fits the last row's topology + // + B32 row_matches_last_row_topology = 1; + if(row_node != rows.first) + { + for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + row_matches_last_row_topology = 0; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + row_matches_last_row_topology = 0; + break; + } + } + } + + //////////////////////// + //- rjf: store last row's info, for next iteration + // + last_row_info = *row_info; + + //////////////////////// + //- rjf: determine if row's data is fresh and/or bad + // + ProfBegin("determine if row's data is fresh and/or bad"); + B32 row_is_fresh = 0; + B32 row_is_bad = 0; + switch(row_info->eval.mode) + { + default:{}break; + case E_Mode_Offset: + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + { + U64 size = e_type_byte_size_from_key(row_info->eval.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + row_is_fresh = 1; + } + if(slice.byte_bad_flags[idx] != 0) + {row_is_bad = 1; + } + } + } + }break; + } + ProfEnd(); + + //////////////////////// + //- rjf: determine row's flags & color palette + // + ProfBegin("determine row's flags & color palette"); + UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; + { + if(row_is_fresh) + { + ui_set_next_tag(str8_lit("fresh")); + row_flags |= UI_BoxFlag_DrawBackground; + } + else if(global_row_idx & 1) + { + ui_set_next_tag(str8_lit("alt")); + row_flags |= UI_BoxFlag_DrawBackground; + } + if(!row_matches_last_row_topology) + { + row_flags |= UI_BoxFlag_DrawSideTop; + } + } + ProfEnd(); + + //////////////////////// + //- rjf: build row box + // + ui_set_next_flags(disabled_flags); + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + + ////////////////////// + //- rjf: build row contents + // + RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) + { + //////////////////// + //- rjf: draw start of cache lines in expansions + // + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + { + U64 row_offset = row_info->eval.value.u64; + if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_tag(str8_lit("pop")); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + + //////////////////// + //- rjf: draw mid-row cache line boundaries in expansions + // + if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + { + if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && + row_info->eval.value.u64%64 != 0 && + row_depth > 0 && + !row_expanded) + { + U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.type_key)); + if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_height(ui_top_font_size()*1.f); + ui_set_next_tag(str8_lit("pop")); + ui_set_next_transparency(0.5f); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } + } + + //////////////////// + //- rjf: build all cells + // + S64 cell_x = 0; + F32 cell_x_px = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + //- rjf: unpack cell info + U64 cell_id = rd_id_from_watch_cell(cell); + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + F32 next_cell_x_px = cell_x_px + cell_width_px; + + //- rjf: determine cell's palette + ProfBegin("determine cell's palette"); + UI_BoxFlags cell_flags = 0; + Vec4F32 cell_background_color_override = {0}; + String8 cell_tag = {0}; + { + if(cell_info.flags & RD_WatchCellFlag_IsErrored) + { + cell_flags |= UI_BoxFlag_DrawBackground; + cell_tag = str8_lit("bad"); + } + else if(cell_info.inheritance_tooltip.size != 0) + { + cell_flags |= UI_BoxFlag_DrawBackground; + cell_tag = str8_lit("pop"); + } + else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && + rd_state->hover_regs_slot == RD_RegSlot_Cfg) + { + RD_Cfg *cfg = cell_info.cfg; + Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + else + { + rgba.w *= 0.15f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) + { + CTRL_Entity *entity = cell_info.entity; + Vec4F32 rgba = rd_color_from_ctrl_entity(entity); + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + else + { + rgba.w *= 0.15f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + } + ProfEnd(); + + //- rjf: build cell + UI_Box *cell_box = &ui_nil_box; + UI_PrefWidth(ui_px(cell_width_px, 0.f)) + { + ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); + } + + //- rjf: build cell contents + UI_Signal sig = {0}; + ProfScope("build cell contents") + UI_Parent(cell_box) + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(RD_FontSlot_Code) + UI_TagF("weak") + { + // rjf: cell has errors? -> build error box + if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + UI_Parent(box) UI_Flags(0) + { + rd_error_label(cell_info.string); + } + } + + // rjf: cell has hook? -> build ui by calling hook + else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + { + Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); + ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); + UI_Parent(box) + { + RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); + rd_cfg_new(view, str8_lit("selected")); + RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + UI_Flags(0) + { + // rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + // rjf: view ui contents + cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); + + // rjf: loading fill + UI_Parent(loading_overlay_container) + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + } + sig = ui_signal_from_box(box); + } + + // rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + else if(cell->kind == RD_WatchCellKind_CallStackFrame) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && + row_info->callstack_unwind_index == rd_base_regs()->unwind_count && + row_info->callstack_inline_depth == rd_base_regs()->inline_depth) + { + UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) + { + Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); + RD_Font(RD_FontSlot_Icons) + UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_TextColor(color) + ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); + } + } + } + + // rjf: build cell line edit + else + { + // rjf: compute visual params + B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); + B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); + String8 ghost_text = {0}; + if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) + { + ghost_text = str8_lit("Expression"); + is_non_code = !cell_selected || !ewv->text_editing; + } + else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) + { + ghost_text = str8_lit("View Rules"); + is_non_code = !cell_selected || !ewv->text_editing; + } + if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + { + is_non_code = 0; + is_button = 0; + is_activated_on_single_click = 0; + } + String8 searched_string = cell_info.string; + if(cell->fstrs.node_count != 0) + { + searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + } + String8 search_query = rd_view_search(); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); + if(fuzzy_matches.count == 0) + { + String8 path_needle = str8_skip_last_slash(search_query); + if(0 < path_needle.size && path_needle.size < search_query.size) + { + fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); + } + } + + // rjf: build + RD_LineEditParams line_edit_params = {0}; + { + line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| + RD_LineEditFlag_NoBackground*!is_button| + RD_LineEditFlag_Button*is_button| + RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| + RD_LineEditFlag_KeyboardClickable| + RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| + RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !is_button)| + RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); + line_edit_params.depth = (cell_x == 0 ? row_depth : 0); + line_edit_params.cursor = &cell_edit_state->cursor; + line_edit_params.mark = &cell_edit_state->mark; + line_edit_params.edit_buffer = cell_edit_state->input_buffer; + line_edit_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); + line_edit_params.edit_string_size_out = &cell_edit_state->input_size; + line_edit_params.expanded_out = &next_row_expanded; + line_edit_params.pre_edit_value = cell_info.string; + line_edit_params.fstrs = cell_info.fstrs; + line_edit_params.fuzzy_matches = &fuzzy_matches; + } + if(cell_background_color_override.w != 0) + { + ui_push_background_color(cell_background_color_override); + } + UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) + RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + } + if(cell_background_color_override.w != 0) + { + ui_pop_background_color(); + } +#if 0 // TODO(rjf): @cfg + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + { + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } +#endif + } + } + + //- rjf: handle interactions + { + // rjf: hover -> rich hover cfgs + if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); + } + + // rjf: hover -> rich hover entities + if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); + } + + // rjf: dragging -> drag/drop + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + { + if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval); + RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); + } + else if(cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); + } + else if(cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) + { + default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; + case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; + case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; + case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; + case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; + } + } + } + + // rjf: (normally) single-click -> move selection here + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: activation (double-click normally, or single-clicks with special buttons) + if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || + ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) + { + // rjf: kill if a double-clickable cell + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) + { + ui_kill_action(); + } + + // rjf: has a command name? -> push command + if(cell_info.cmd_name.size != 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); + RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); + rd_cmd(RD_CmdKind_RunCommand, .cfg = cfg->id, .ctrl_entity = entity->handle, .cmd_name = cell_info.cmd_name); + } + + // rjf: row has callstack info? -> select unwind + else if(row_info->callstack_thread != &ctrl_entity_nil) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info->callstack_unwind_index, + .inline_depth = row_info->callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(cell_info.flags & RD_WatchCellFlag_CanEdit) + { + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: can't edit, but has address info? -> go to address + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) + { + U64 vaddr = cell_info.eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) + { + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); + } + } + } + } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); + } + } + + //- rjf: bump x pixel coordinate + cell_x_px = next_cell_x_px; + + //- 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_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); + } + + //- rjf: [DEV] hovering -> eval system tooltips + if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) + { + local_persist char *spaces = " "; + String8 string = ev_expr_string_from_row(scratch.arena, row, 0); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + ui_labelf("Text:"); + ui_label(string); + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Tokens:"); + for(U64 idx = 0; idx < tokens.count; idx += 1) + { + ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); + } + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Expression:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_Expr *expr; + S64 depth; + }; + Task start_task = {0, 0, parse.exprs.last}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 ext = {0}; + switch(t->expr->kind) + { + default: + { + if(t->expr->string.size != 0) + { + ext = push_str8f(scratch.arena, "'%S'", t->expr->string); + } + else if(t->expr->value.u32 != 0) + { + ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); + } + else if(t->expr->value.f32 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); + } + else if(t->expr->value.f64 != 0) + { + ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); + } + else if(t->expr->value.u64 != 0) + { + ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); + } + }break; + } + ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->expr = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("IR Tree:"); + { + typedef struct Task Task; + struct Task + { + Task *next; + Task *prev; + E_IRNode *node; + S64 depth; + }; + Task start_task = {0, 0, irtree.root}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + String8 op_string = {0}; + switch(t->node->op) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); + for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->node = child; + task->depth = t->depth+1; + DLLInsert(first_task, last_task, t, task); + } + } + } + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Op List:"); + { + for(E_Op *op = oplist.first; op != 0; op = op->next) + { + String8 op_string = {0}; + switch(op->opcode) + { + default:{}break; + case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; + case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; +#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; + RDI_EvalOp_XList +#undef X + } + String8 ext = {0}; + switch(op->opcode) + { + case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; + default: + { + ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); + }break; + } + ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); + } + } + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Bytecode:"); + { + for(U64 idx = 0; idx < bytecode.size; idx += 1) + { + ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); + } + } + } + } + } + + ////////////////////// + //- rjf: commit expansion state changes + // + if(next_row_expanded != row_expanded) + { + if(!ev_key_match(ev_key_root(), row->key)) + { + ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + } + } + } + } + } + } + } + + ////////////////////////////// + //- rjf: general table-wide press logic + // + if(pressed) + { + rd_cmd(RD_CmdKind_FocusPanel); + } + + rd_store_view_scroll_pos(scroll_pos); + scratch_end(scratch); + } + //////////////////////////// //- rjf: visualizer hook // @@ -11574,7 +13426,6 @@ rd_frame(void) } table[] = { - {str8_lit("watch"), RD_VIEW_UI_FUNCTION_NAME(watch), EV_EXPAND_RULE_INFO_FUNCTION_NAME(watch)}, {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, @@ -11946,6 +13797,32 @@ rd_frame(void) //- rjf: writing config changes case RD_CmdKind_WriteUserData: + { + String8 dst_path = rd_state->user_path; + String8 bucket_name = str8_lit("user"); + B32 dst_exists = (os_properties_from_file_path(dst_path).created != 0); + String8 temp_path = push_str8f(scratch.arena, "%S.temp", dst_path); + String8 overwritten_path = push_str8f(scratch.arena, "%S.old", dst_path); + RD_Cfg *tree_root = rd_cfg_child_from_string(rd_state->root_cfg, bucket_name); + String8List strings = {0}; + str8_list_pushf(scratch.arena, &strings, "// raddbg %s %S file\n\n", BUILD_VERSION_STRING_LITERAL, bucket_name); + for(RD_Cfg *child = tree_root->first; child != &rd_nil_cfg; child = child->next) + { + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, child)); + } + String8 data = str8_list_join(scratch.arena, &strings, 0); + B32 temp_write_good = os_write_data_to_file_path(temp_path, data); + B32 old_move_good = (temp_write_good && (!dst_exists || os_move_file_path(overwritten_path, dst_path))); + B32 new_move_good = (old_move_good && os_move_file_path(dst_path, temp_path)); + if(new_move_good && dst_exists) + { + os_delete_file_at_path(overwritten_path); + } + else if(!new_move_good && old_move_good && dst_exists) + { + os_move_file_path(dst_path, overwritten_path); + } + }break; case RD_CmdKind_WriteProjectData: { #if 0 // TODO(rjf): @cfg diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index dbfa0d5a..3202b4c0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1558,1867 +1558,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) RD_VIEW_UI_FUNCTION_DEF(null) {} -//////////////////////////////// -//~ rjf: watch @view_hook_impl - -EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch) -{ - EV_ExpandInfo info = {0}; - info.row_count = 8; - info.single_item = 1; - return info; -} - -RD_VIEW_UI_FUNCTION_DEF(watch) -{ - ProfBeginFunction(); - RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); - Temp scratch = scratch_begin(0, 0); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - B32 is_first_frame = 0; - if(ewv->initialized == 0) - { - is_first_frame = 1; - ewv->initialized = 1; - ewv->text_edit_arena = rd_push_view_arena(); - } - - ////////////////////////////// - //- rjf: unpack arguments - // - EV_View *eval_view = rd_view_eval_view(); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); - F32 row_string_max_size_px = dim_2f32(rect).x; - EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; - String8 filter = rd_view_search(); - Vec4F32 pop_background_rgba = {0}; - UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); - - ////////////////////////////// - //- rjf: decide if root should be implicit - // - // "implicit" means -> root is automatically expanded, row depth is 1 less than the - // block tree structure would suggest. this would be used if the root is, for instance, - // the "collection of all watches", to build a watch window. but this behavior is not - // as desirable if we are just using some other expression as the root. - // - B32 implicit_root = !rd_view_cfg_value_from_string(str8_lit("explicit_root")).u64; - - ////////////////////////////// - //- rjf: determine autocompletion string - // - String8 autocomplete_hint_string = {0}; - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - autocomplete_hint_string = evt->string; - break; - } - } - } - - ////////////////////////////// - //- rjf: consume events & perform navigations/edits - calculate state - // - EV_BlockTree block_tree = {0}; - EV_BlockRangeList block_ranges = {0}; - UI_ScrollListRowBlockArray row_blocks = {0}; - Vec2S64 cursor_tbl = {0}; - Vec2S64 mark_tbl = {0}; - Rng2S64 selection_tbl = {0}; - ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) - { - B32 state_dirty = 1; - B32 snap_to_cursor = 0; - B32 cursor_dirty__tbl = 0; - B32 take_autocomplete = 0; - for(UI_Event *event = 0;;) - { - ////////////////////////// - //- rjf: state -> viz blocks - // - if(state_dirty) ProfScope("state -> viz blocks") - { - MemoryZeroStruct(&block_tree); - MemoryZeroStruct(&block_ranges); - if(implicit_root || is_first_frame) - { - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - } - block_tree = ev_block_tree_from_exprs(scratch.arena, eval_view, filter, eval.exprs); - block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); - if(implicit_root && block_ranges.first != 0) - { - block_ranges.count -= 1; - block_ranges.first = block_ranges.first->next; - } - } - - ////////////////////////// - //- rjf: block ranges -> ui row blocks - // - ProfScope("block ranges -> ui row blocks") - { - UI_ScrollListRowBlockChunkList row_block_chunks = {0}; - for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) - { - UI_ScrollListRowBlock block = {0}; - block.row_count = dim_1u64(n->v.range); - block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); - ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); - } - row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); - } - - ////////////////////////// - //- rjf: conclude state update - // - if(state_dirty) - { - state_dirty = 0; - } - - ////////////////////////////// - //- rjf: 2D table coordinates * blocks -> stable cursor state - // - if(cursor_dirty__tbl) - { - cursor_dirty__tbl = 0; - struct - { - RD_WatchPt *pt_state; - Vec2S64 pt_tbl; - } - points[] = - { - {&ewv->cursor, cursor_tbl}, - {&ewv->mark, mark_tbl}, - }; - for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) - { - EV_Key last_key = points[point_idx].pt_state->key; - EV_Key last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); - if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) - { - points[point_idx].pt_state->key = last_parent_key; - EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); - for(EV_ExpandNode *n = node; n != 0; n = n->parent) - { - points[point_idx].pt_state->key = n->key; - if(n->expanded == 0) - { - break; - } - } - } - if(point_idx == 0 && - (!ev_key_match(ewv->cursor.key, last_key) || - !ev_key_match(ewv->cursor.parent_key, last_parent_key))) - { - ewv->text_editing = 0; - } - } - ewv->next_cursor = ewv->cursor; - ewv->next_mark = ewv->mark; - } - - ////////////////////////// - //- rjf: stable cursor state * blocks -> 2D table coordinates - // - EV_WindowedRowList mark_rows = {0}; - Rng2S64 cursor_tbl_range = {0}; - { - // rjf: compute 2d table coordinates - cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); - mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); - - // rjf: compute legal coordinate range, given selection-defining row - Rng1S64 cursor_x_range = {0}; - { - EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); - } - cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); - - // rjf: clamp x positions of cursor/mark tbl - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); - } - - // rjf: form selection range table coordinates - selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), - Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); - } - - ////////////////////////// - //- rjf: [table] snap to cursor - // - if(snap_to_cursor) - { - Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); - if(contains_1s64(global_vnum_range, cursor_tbl.y)) - { - UI_ScrollPt *scroll_pt = &scroll_pos.y; - - //- rjf: compute visible row range - Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), - scroll_pt->idx + 1 + num_possible_visible_rows); - - //- rjf: compute cursor row range from cursor item - Rng1S64 cursor_visibility_row_num_range = {0}; - cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; - cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; - - //- rjf: compute deltas & apply - S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); - S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); - S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; - new_num = clamp_1s64(global_vnum_range, new_num); - if(new_num > 0) - { - U64 new_idx = (U64)(new_num - 1); - ui_scroll_pt_target_idx(scroll_pt, new_idx); - } - } - } - - ////////////////////////////// - //- rjf: apply cursor/mark rugpull change - // - B32 cursor_rugpull = 0; - if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) - { - cursor_rugpull = 1; - ewv->cursor = ewv->next_cursor; - ewv->mark = ewv->next_mark; - } - - ////////////////////////// - //- rjf: grab next event, if any - otherwise exit the loop, as we now have - // the most up-to-date state - // - B32 next_event_good = ui_next_event(&event); - if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) - { - break; - } - UI_Event dummy_evt = zero_struct; - UI_Event *evt = &dummy_evt; - if(next_event_good) - { - evt = event; - } - B32 taken = 0; - - ////////////////////////// - //- rjf: begin editing on some operations - // - if(!ewv->text_editing && - (evt->kind == UI_EventKind_Text || - evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && - selection_tbl.min.x == selection_tbl.max.x && - (selection_tbl.min.y != 0 || selection_tbl.min.y != 0)) - { - Vec2S64 selection_dim = dim_2s64(selection_tbl); - arena_clear(ewv->text_edit_arena); - ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); - ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); - ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - B32 any_edits_started = 0; - for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.flags & RD_WatchCellFlag_CanEdit) - { - any_edits_started = 1; - String8 string = cell_info.string; - string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - U64 hash = ev_hash_from_key(pt.key); - U64 slot_idx = hash%ewv->text_edit_state_slots_count; - RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); - SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); - edit_state->pt = pt; - edit_state->cursor = txt_pt(1, string.size+1); - edit_state->mark = txt_pt(1, 1); - edit_state->input_size = string.size; - MemoryCopy(edit_state->input_buffer, string.str, string.size); - edit_state->initial_size = string.size; - MemoryCopy(edit_state->initial_buffer, string.str, string.size); - } - } - } - ewv->text_editing = any_edits_started; - } - - ////////////////////////// - //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if - // cannot apply to multi-cursor, then just don't take the event - // - if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept) - { - taken = 1; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) - { - // rjf: unpack row info - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - - // rjf: loop through X selections and perform operations for each - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) - { -#if 0 // TODO(rjf): @cfg - //- rjf: determine operation for this cell - typedef enum OpKind - { - OpKind_Null, - OpKind_DoExpand, - } - OpKind; - OpKind kind = OpKind_Null; - switch(row_kind) - { - default:{}break; - case RD_WatchViewRowKind_Normal: - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; - } - }break; - case RD_WatchViewRowKind_PrettyEntityControls: - if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) - { - kind = OpKind_DoExpand; - }break; - } - - //- rjf: perform operation - switch(kind) - { - default:{taken = 0;}break; - case OpKind_DoExpand: - if(ev_row_is_expandable(row)) - { - B32 is_expanded = ev_expansion_from_key(eval_view, row->key); - ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); - }break; - } -#endif - } - } - } - - ////////////////////////// - //- rjf: [text] apply textual edits - // - if(ewv->text_editing) - { - B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || - (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || - cursor_rugpull); - rd_state->text_edit_mode = 1; - if(editing_complete || - ((evt->kind == UI_EventKind_Edit || - evt->kind == UI_EventKind_Navigate || - evt->kind == UI_EventKind_Text) && - evt->delta_2s32.y == 0)) - { - taken = 1; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); - String8 string = str8(edit_state->input_buffer, edit_state->input_size); - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - - // rjf: copy - if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) - { - os_set_clipboard_text(op.copy); - } - - // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op - if(autocomplete_hint_string.size != 0) - { - take_autocomplete = 1; - String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); - U64 word_off = (U64)(word_query.str - string.str); - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); - new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); - string = str8(edit_state->input_buffer, edit_state->input_size); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - } - - // rjf: cancel? -> revert to initial string - if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) - { - string = str8(edit_state->initial_buffer, edit_state->initial_size); - } - - // rjf: obtain edited string - String8 new_string = string; - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) - { - new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); - } - - // rjf: commit to edit state - new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = op.cursor; - edit_state->mark = op.mark; - - // rjf: commit edited cell string - switch(cell->kind) - { - case RD_WatchCellKind_Expr: - { - RD_Cfg *cfg = row_info.group_cfg_child; - String8 child_key = str8_lit("expression"); - if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) - { - RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; - if(new_cfg_parent != &rd_nil_cfg) - { - child_key = str8_zero(); - } - if(new_cfg_parent == &rd_nil_cfg) - { - RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); - new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; - } - if(new_cfg_parent == &rd_nil_cfg) - { - new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - } - cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); - state_dirty = 1; - snap_to_cursor = 1; - } - if(cfg != &rd_nil_cfg) - { - RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; - rd_cfg_new_replace(expr, new_string); - } - }break; - case RD_WatchCellKind_Tag: - if(editing_complete) - { - ev_key_set_view_rule(eval_view, pt.key, new_string); - RD_Cfg *cfg = row_info.group_cfg_child; - if(cfg != &rd_nil_cfg && new_string.size != 0) - { - RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); - rd_cfg_new(view_rule, new_string); - } - else if(cfg != &rd_nil_cfg && new_string.size == 0) - { - rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("view_rule"))); - } - }break; - case RD_WatchCellKind_Eval: - { - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.eval.mode == E_Mode_Offset) - { - B32 should_commit_asap = editing_complete; - if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) - { - should_commit_asap = 1; - } - else if(evt->slot != UI_EventActionSlot_Cancel) - { - should_commit_asap = editing_complete; - } - if(should_commit_asap) - { - B32 success = 0; - success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); - if(!success) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } - } - } - }break; - } - } - } - } - if(editing_complete) - { - ewv->text_editing = 0; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity copies - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) - { - taken = 1; - String8List strs = {0}; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - String8 cell_string = cell_info.string; - cell_string = str8_skip_chop_whitespace(cell_string); - U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); - if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) - { - str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", - comma_pos < cell_string.size ? "\"" : "", - cell_string, - comma_pos < cell_string.size ? "\"" : "", - cell_x+1 <= selection_tbl.max.x ? "," : ""); - } - else - { - str8_list_push(scratch.arena, &strs, cell_string); - } - } - if(y+1 <= selection_tbl.max.y) - { - str8_list_push(scratch.arena, &strs, str8_lit("\n")); - } - } - String8 string = str8_list_join(scratch.arena, &strs, 0); - os_set_clipboard_text(string); - } - - ////////////////////////// - //- rjf: [table] do cell-granularity deletions - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) - { - taken = 1; - state_dirty = 1; - snap_to_cursor = 1; - RD_CfgList cfgs_to_remove = {0}; - RD_WatchPt next_cursor_pt = {0}; - B32 next_cursor_set = 0; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - switch(cell->kind) - { - default:{}break; - case RD_WatchCellKind_Expr: - { - RD_Cfg *cfg = row_info.group_cfg_child; - if(cfg != &rd_nil_cfg) - { - rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); - U64 deleted_num = row->block->lookup_rule->num_from_id(row->key.child_id, row->block->lookup_rule_user_data); - if(deleted_num != 0) - { - EV_Key parent_key = row->block->parent->key; - EV_Key key = row->block->key; - U64 fallback_id_prev = row->block->lookup_rule->id_from_num(deleted_num-1, row->block->lookup_rule_user_data); - U64 fallback_id_next = row->block->lookup_rule->id_from_num(deleted_num+1, row->block->lookup_rule_user_data); - if(fallback_id_next != 0) - { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_next); - } - else if(fallback_id_prev != 0) - { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_prev); - } - RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; - next_cursor_pt = new_pt; - next_cursor_set = 1; - state_dirty = 1; - } - } - }break; - case RD_WatchCellKind_Tag: - { - if(row_info.group_cfg_child != &rd_nil_cfg) - { - rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg_child, str8_lit("view_rule"))); - } - ev_key_set_view_rule(eval_view, row->key, str8_zero()); - state_dirty = 1; - }break; - case RD_WatchCellKind_Eval: - { - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); - }break; - } - } - } - for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) - { - rd_cfg_release(n->v); - } - if(next_cursor_set) - { - ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; - } - } - - ////////////////////////// - //- rjf: [table] apply deltas to cursor & mark - // - if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) - { - B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; - Vec2S32 delta = evt->delta_2s32; - if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - if(delta.x > 0 || delta.y > 0) - { - cursor_tbl.x = selection_tbl.max.x; - cursor_tbl.y = selection_tbl.max.y; - } - else if(delta.x < 0 || delta.y < 0) - { - cursor_tbl.x = selection_tbl.min.x; - cursor_tbl.y = selection_tbl.min.y; - } - } - if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - MemoryZeroStruct(&delta); - } - B32 moved = 1; - switch(evt->delta_unit) - { - default:{moved = 0;}break; - case UI_EventDeltaUnit_Char: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] += delta.v[axis]; - if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; - } - if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; - } - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - } - }break; - case UI_EventDeltaUnit_Word: - case UI_EventDeltaUnit_Line: - case UI_EventDeltaUnit_Page: - { - cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : - delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : - cursor_tbl.x); - cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : - delta.y<0 ? -(num_possible_visible_rows-3) : - 0)); - cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], - cursor_tbl_range.max.y), - cursor_tbl.y); - }break; - case UI_EventDeltaUnit_Whole: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); - } - }break; - } - if(moved) - { - taken = 1; - cursor_dirty__tbl = 1; - snap_to_cursor = 1; - } - } - - ////////////////////////// - //- rjf: [table] stick table mark to cursor if needed - // - if(!ewv->text_editing) - { - if(taken && !(evt->flags & UI_EventFlag_KeepMark)) - { - mark_tbl = cursor_tbl; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity reorders - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) - { - taken = 1; - if(filter.size == 0) - { - // rjf: determine blocks of each endpoint of the table selection - EV_Block *selection_endpoint_blocks[2] = - { - ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, - ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, - }; - - // rjf: pick shallowest block within which we can do reordering - U64 selection_depths[2] = - { - ev_depth_from_block(selection_endpoint_blocks[0]), - ev_depth_from_block(selection_endpoint_blocks[1]), - }; - EV_Block *selection_block = (selection_depths[1] < selection_depths[0] - ? selection_endpoint_blocks[1] - : selection_endpoint_blocks[0]); - - // rjf: find selection keys within the block in which we are doing reordering - EV_Key selection_keys_in_block[2] = {0}; - { - for EachElement(idx, selection_endpoint_blocks) - { - EV_Block *endpoint_block = selection_endpoint_blocks[idx]; - if(endpoint_block == selection_block) - { - selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); - } - else - { - for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) - { - endpoint_block = endpoint_block->parent; - } - if(endpoint_block->parent == selection_block) - { - selection_keys_in_block[idx] = endpoint_block->key; - } - } - } - EV_Key fallback_key = {0}; - for EachElement(idx, selection_endpoint_blocks) - { - if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - fallback_key = selection_keys_in_block[idx]; - } - } - for EachElement(idx, selection_endpoint_blocks) - { - if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - selection_keys_in_block[idx] = fallback_key; - } - } - } - - // rjf: determine collection info for the block - String8 group_cfg_name = {0}; - { - E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); - E_TypeKey block_type_key = block_irtree.type_key; - E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Set) - { - E_Type *block_type = e_type_from_key__cached(block_type_key); - group_cfg_name = rd_singular_from_code_name_plural(block_type->name); - if(group_cfg_name.size == 0) - { - group_cfg_name = block_type->name; - } - } - } - - // rjf: map selection endpoints to cfgs - RD_Cfg *first_cfg = &rd_nil_cfg; - RD_Cfg *last_cfg = &rd_nil_cfg; - if(group_cfg_name.size != 0) - { - first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); - last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); - } - - // rjf: reorder - if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) - { - RD_Cfg *first_cfg_prev = &rd_nil_cfg; - RD_Cfg *last_cfg_next = &rd_nil_cfg; - for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) - { - if(str8_match(prev->string, first_cfg->string, 0)) - { - first_cfg_prev = prev; - break; - } - } - for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) - { - if(str8_match(next->string, last_cfg->string, 0)) - { - last_cfg_next = next; - break; - } - } - if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) - { - state_dirty = 1; - snap_to_cursor = 1; - RD_Cfg *parent = first_cfg_prev->parent; - rd_cfg_unhook(parent, first_cfg_prev); - rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); - } - if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) - { - state_dirty = 1; - snap_to_cursor = 1; - RD_Cfg *parent = last_cfg_next->parent; - rd_cfg_unhook(parent, last_cfg_next); - rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); - } - } - } - } - - ////////////////////////// - //- rjf: consume event, if taken - // - if(taken && evt != &dummy_evt) - { - ui_eat_event(evt); - } - } - if(take_autocomplete) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - ui_eat_event(evt); - break; - } - } - } - } - - ////////////////////////////// - //- rjf: build ui - // - B32 pressed = 0; - ProfScope("build ui") - { - Rng1S64 visible_row_rng = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); - scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - scroll_list_params.row_blocks = row_blocks; - } - UI_BoxFlags disabled_flags = ui_top_flags(); - if(d_ctrl_targets_running()) - { - disabled_flags |= UI_BoxFlag_Disabled; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &scroll_pos.y, - 0, - 0, - &visible_row_rng, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - ui_set_next_pref_height(ui_children_sum(1)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); - UI_Parent(table) - { - Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; - - //////////////////////// - //- rjf: viz blocks -> rows - // - EV_WindowedRowList rows = {0}; - { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); - } - - //////////////////////// - //- rjf: rows -> row infos - // - RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); - { - U64 idx = 0; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) - { - EV_Row *row = &row_node->row; - row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); - } - } - - //////////////////////// - //- rjf: build boundaries - // - B32 cell_pcts_are_dirty = 0; - ProfScope("build boundaries") - { - U64 idx = 0; - U64 boundary_start_idx = 0; - EV_Row *last_row = 0; - RD_WatchRowInfo *last_row_info = 0; - for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) - { - //- rjf: determine if this row breaks the topology - B32 is_new_topology = (row_node == 0); - if(row_node != 0 && last_row_info != 0) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo *row_info = &row_infos[idx]; - for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; - last_cell = last_cell->next, this_cell = this_cell->next) - { - if(last_cell == 0 && this_cell == 0) - { - break; - } - if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) - { - is_new_topology = 1; - break; - } - if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) - { - is_new_topology = 1; - break; - } - } - } - - //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations - if(is_new_topology) - { - EV_Row *row = last_row; - RD_WatchRowInfo *row_info = last_row_info; - F32 row_width_px = (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); - if(row_info != 0) - { - U64 row_hash = ev_hash_from_key(row->key); - F32 cell_x_px = 0; - U64 cell_idx = 0; - for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) - { - if(cell->pct == 0 || cell->next->pct == 0) - { - continue; - } - U64 cell_id = rd_id_from_watch_cell(cell); - F32 cell_width_px = cell->px + cell->pct * row_width_px; - F32 next_cell_x_px = cell_x_px + cell_width_px; - { - Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.2f, - boundary_start_idx*row_height_px, - next_cell_x_px + ui_top_font_size()*0.2f, - idx*row_height_px); - UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); - UI_Signal sig = ui_signal_from_box(box); - if(ui_dragging(sig)) - { - typedef struct DragData DragData; - struct DragData - { - F32 min_pct; - F32 max_pct; - }; - if(ui_pressed(sig)) - { - DragData drag_data = {cell->pct, cell->next->pct}; - ui_store_drag_struct(&drag_data); - } - DragData *drag_data = ui_get_drag_struct(DragData); - F32 min_pct__pre = drag_data->min_pct; - F32 max_pct__pre = drag_data->max_pct; - F32 min_px__pre = min_pct__pre*row_width_px; - F32 max_px__pre = max_pct__pre*row_width_px; - F32 min_px__post = min_px__pre + ui_drag_delta().x; - F32 max_px__post = max_px__pre - ui_drag_delta().x; - F32 min_pct__post = min_px__post/row_width_px; - F32 max_pct__post = max_px__post/row_width_px; - if(min_pct__post < 0.05f) - { - min_pct__post = 0.05f; - max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; - } - if(max_pct__post < 0.05f) - { - max_pct__post = 0.05f; - min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; - } - if(ui_double_clicked(sig)) - { - F32 default_sum = cell->default_pct + cell->next->default_pct; - F32 current_sum = min_pct__pre + max_pct__pre;; - min_pct__post = current_sum * (cell->default_pct / default_sum); - max_pct__post = current_sum * (cell->next->default_pct / default_sum); - ui_kill_action(); - } - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); - RD_Cfg *min_cfg = &rd_nil_cfg; - RD_Cfg *max_cfg = &rd_nil_cfg; - { - RD_Cfg *pct_child = style->first; - U64 c_idx = 0; - for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) - { - if(pct_child == &rd_nil_cfg) - { - pct_child = rd_cfg_newf(style, "%f", c->pct); - } - if(c_idx == cell_idx) - { - min_cfg = pct_child; - } - if(c_idx == cell_idx+1) - { - max_cfg = pct_child; - } - pct_child = pct_child->next; - } - rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); - rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); - cell_pcts_are_dirty = 1; - } - } - } - } - cell_x_px = next_cell_x_px; - } - } - boundary_start_idx = idx; - } - - //- rjf: advance - if(row_node == 0) - { - break; - } - else - { - last_row = &row_node->row; - last_row_info = &row_infos[idx]; - } - } - } - - //////////////////////// - //- rjf: if cell widths are dirty -> recompute row infos - // - if(cell_pcts_are_dirty) - { - U64 idx = 0; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) - { - EV_Row *row = &row_node->row; - row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); - } - } - - //////////////////////// - //- rjf: build table - // - ProfScope("build table") - { - U64 local_row_idx = 0; - U64 global_row_idx = rows.count_before_semantic; - RD_WatchRowInfo last_row_info = {0}; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) - { - //////////////////////// - //- rjf: unpack row info - // - ProfBegin("unpack row info"); - EV_Row *row = &row_node->row; - RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; - U64 row_hash = ev_hash_from_key(row->key); - U64 row_depth = ev_depth_from_block(row->block); - B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); - B32 row_expanded = ev_expansion_from_key(eval_view, row->key); - B32 next_row_expanded = row_expanded; - B32 row_is_expandable = ev_row_is_expandable(row); - if(implicit_root && row_depth > 0) - { - row_depth -= 1; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine if this row fits the last row's topology - // - B32 row_matches_last_row_topology = 1; - if(row_node != rows.first) - { - for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; - last_cell = last_cell->next, this_cell = this_cell->next) - { - if(last_cell == 0 && this_cell == 0) - { - break; - } - if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) - { - row_matches_last_row_topology = 0; - break; - } - if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) - { - row_matches_last_row_topology = 0; - break; - } - } - } - - //////////////////////// - //- rjf: store last row's info, for next iteration - // - last_row_info = *row_info; - - //////////////////////// - //- rjf: determine if row's data is fresh and/or bad - // - ProfBegin("determine if row's data is fresh and/or bad"); - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row_info->eval.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row_info->eval.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - {row_is_bad = 1; - } - } - } - }break; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine row's flags & color palette - // - ProfBegin("determine row's flags & color palette"); - UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; - { - if(row_is_fresh) - { - ui_set_next_tag(str8_lit("fresh")); - row_flags |= UI_BoxFlag_DrawBackground; - } - else if(global_row_idx & 1) - { - ui_set_next_tag(str8_lit("alt")); - row_flags |= UI_BoxFlag_DrawBackground; - } - if(!row_matches_last_row_topology) - { - row_flags |= UI_BoxFlag_DrawSideTop; - } - } - ProfEnd(); - - //////////////////////// - //- rjf: build row box - // - ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); - - ////////////////////// - //- rjf: build row contents - // - RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) - { - //////////////////// - //- rjf: draw start of cache lines in expansions - // - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) - { - U64 row_offset = row_info->eval.value.u64; - if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_tag(str8_lit("pop")); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - - //////////////////// - //- rjf: draw mid-row cache line boundaries in expansions - // - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) - { - if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && - row_info->eval.value.u64%64 != 0 && - row_depth > 0 && - !row_expanded) - { - U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.type_key)); - if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); - ui_set_next_fixed_height(ui_top_font_size()*1.f); - ui_set_next_tag(str8_lit("pop")); - ui_set_next_transparency(0.5f); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - - //////////////////// - //- rjf: build all cells - // - S64 cell_x = 0; - F32 cell_x_px = 0; - for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - //- rjf: unpack cell info - U64 cell_id = rd_id_from_watch_cell(cell); - RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); - F32 next_cell_x_px = cell_x_px + cell_width_px; - - //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); - UI_BoxFlags cell_flags = 0; - Vec4F32 cell_background_color_override = {0}; - String8 cell_tag = {0}; - { - if(cell_info.flags & RD_WatchCellFlag_IsErrored) - { - cell_flags |= UI_BoxFlag_DrawBackground; - cell_tag = str8_lit("bad"); - } - else if(cell_info.inheritance_tooltip.size != 0) - { - cell_flags |= UI_BoxFlag_DrawBackground; - cell_tag = str8_lit("pop"); - } - else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && - rd_state->hover_regs_slot == RD_RegSlot_Cfg) - { - RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); - if(rgba.w == 0) - { - rgba = pop_background_rgba; - rgba.w *= 0.5f; - } - else - { - rgba.w *= 0.15f; - } - rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); - cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && - rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) - { - CTRL_Entity *entity = cell_info.entity; - Vec4F32 rgba = rd_color_from_ctrl_entity(entity); - if(rgba.w == 0) - { - rgba = pop_background_rgba; - rgba.w *= 0.5f; - } - else - { - rgba.w *= 0.15f; - } - rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); - cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; - } - } - ProfEnd(); - - //- rjf: build cell - UI_Box *cell_box = &ui_nil_box; - UI_PrefWidth(ui_px(cell_width_px, 0.f)) - { - ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); - cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); - } - - //- rjf: build cell contents - UI_Signal sig = {0}; - ProfScope("build cell contents") - UI_Parent(cell_box) - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(RD_FontSlot_Code) - UI_TagF("weak") - { - // rjf: cell has errors? -> build error box - if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_info.string); - } - } - - // rjf: cell has hook? -> build ui by calling hook - else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) - { - Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); - ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); - ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); - UI_Parent(box) - { - RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); - rd_cfg_new(view, str8_lit("selected")); - RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - UI_Flags(0) - { - // rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - // rjf: view ui contents - cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); - - // rjf: loading fill - UI_Parent(loading_overlay_container) - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); - } - } - - } - sig = ui_signal_from_box(box); - } - - // rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty - else if(cell->kind == RD_WatchCellKind_CallStackFrame) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); - sig = ui_signal_from_box(box); - if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && - row_info->callstack_unwind_index == rd_base_regs()->unwind_count && - row_info->callstack_inline_depth == rd_base_regs()->inline_depth) - { - UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) - { - Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); - RD_Font(RD_FontSlot_Icons) - UI_Flags(UI_BoxFlag_DisableTextTrunc) - UI_TextColor(color) - ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); - } - } - } - - // rjf: build cell line edit - else - { - // rjf: compute visual params - B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); - B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); - B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); - String8 ghost_text = {0}; - if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) - { - ghost_text = str8_lit("Expression"); - is_non_code = !cell_selected || !ewv->text_editing; - } - else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) - { - ghost_text = str8_lit("View Rules"); - is_non_code = !cell_selected || !ewv->text_editing; - } - if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) - { - is_non_code = 0; - is_button = 0; - is_activated_on_single_click = 0; - } - String8 searched_string = cell_info.string; - if(cell->fstrs.node_count != 0) - { - searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); - } - String8 search_query = rd_view_search(); - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); - if(fuzzy_matches.count == 0) - { - String8 path_needle = str8_skip_last_slash(search_query); - if(0 < path_needle.size && path_needle.size < search_query.size) - { - fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); - } - } - - // rjf: build - RD_LineEditParams line_edit_params = {0}; - { - line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| - RD_LineEditFlag_NoBackground*!is_button| - RD_LineEditFlag_Button*is_button| - RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !is_button)| - RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); - line_edit_params.depth = (cell_x == 0 ? row_depth : 0); - line_edit_params.cursor = &cell_edit_state->cursor; - line_edit_params.mark = &cell_edit_state->mark; - line_edit_params.edit_buffer = cell_edit_state->input_buffer; - line_edit_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); - line_edit_params.edit_string_size_out = &cell_edit_state->input_size; - line_edit_params.expanded_out = &next_row_expanded; - line_edit_params.pre_edit_value = cell_info.string; - line_edit_params.fstrs = cell_info.fstrs; - line_edit_params.fuzzy_matches = &fuzzy_matches; - } - if(cell_background_color_override.w != 0) - { - ui_push_background_color(cell_background_color_override); - } - UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) - RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); - } - if(cell_background_color_override.w != 0) - { - ui_pop_background_color(); - } -#if 0 // TODO(rjf): @cfg - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); - } -#endif - } - } - - //- rjf: handle interactions - { - // rjf: hover -> rich hover cfgs - if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) - { - RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); - } - - // rjf: hover -> rich hover entities - if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) - { - RD_RegsScope(.ctrl_entity = cell_info.entity->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); - } - - // rjf: dragging -> drag/drop - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) - { - if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) - { - String8 file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval); - RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); - } - else if(cell_info.cfg != &rd_nil_cfg) - { - RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); - } - else if(cell_info.entity != &ctrl_entity_nil) - { - RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) - { - default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; - case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; - case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; - case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; - case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; - } - } - } - - // rjf: (normally) single-click -> move selection here - if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: activation (double-click normally, or single-clicks with special buttons) - if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || - ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) - { - // rjf: kill if a double-clickable cell - if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) - { - ui_kill_action(); - } - - // rjf: has a command name? -> push command - if(cell_info.cmd_name.size != 0) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); - RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); - rd_cmd(RD_CmdKind_RunCommand, .cfg = cfg->id, .ctrl_entity = entity->handle, .cmd_name = cell_info.cmd_name); - } - - // rjf: row has callstack info? -> select unwind - else if(row_info->callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info->callstack_unwind_index, - .inline_depth = row_info->callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(cell_info.flags & RD_WatchCellFlag_CanEdit) - { - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: can't edit, but has address info? -> go to address - else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) - { - U64 vaddr = cell_info.eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } - } - } - } - - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); - } - } - - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); - } - } - - //- rjf: bump x pixel coordinate - cell_x_px = next_cell_x_px; - - //- 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_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); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.exprs.last}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 ext = {0}; - switch(t->expr->kind) - { - default: - { - if(t->expr->string.size != 0) - { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: - { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; - } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) - { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); - } - } - } - } - } - - ////////////////////// - //- rjf: commit expansion state changes - // - if(next_row_expanded != row_expanded) - { - if(!ev_key_match(ev_key_root(), row->key)) - { - ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); - } - } - } - } - } - } - } - - ////////////////////////////// - //- rjf: general table-wide press logic - // - if(pressed) - { - rd_cmd(RD_CmdKind_FocusPanel); - } - - rd_store_view_scroll_pos(scroll_pos); - scratch_end(scratch); - ProfEnd(); -} - //////////////////////////////// //~ rjf: text @view_hook_impl diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 9524d108..224c320d 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -239,7 +239,6 @@ internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_Wat RD_VIEW_UI_FUNCTION_DEF(null); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(watch); EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); @@ -247,7 +246,6 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); -RD_VIEW_UI_FUNCTION_DEF(watch); RD_VIEW_UI_FUNCTION_DEF(text); RD_VIEW_UI_FUNCTION_DEF(disasm); RD_VIEW_UI_FUNCTION_DEF(memory); From e4de4dd52f9c9f54530f8eba6a3f531a15ed4b1d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 17:28:56 -0800 Subject: [PATCH 157/755] hook up project cfg saving --- src/raddbg/raddbg_core.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bfb2e0b9..19182ee8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13472,6 +13472,8 @@ rd_frame(void) rd_request_frame(); // rjf: process command + String8 dst_path = {0}; + String8 bucket_name = {0}; Dir2 split_dir = Dir2_Invalid; RD_Cfg *split_panel = &rd_nil_cfg; U64 panel_sib_off = 0; @@ -13796,10 +13798,10 @@ rd_frame(void) }break; //- rjf: writing config changes - case RD_CmdKind_WriteUserData: + case RD_CmdKind_WriteUserData: dst_path = rd_state->user_path; bucket_name = str8_lit("user"); goto write; + case RD_CmdKind_WriteProjectData: dst_path = rd_state->project_path; bucket_name = str8_lit("project"); goto write; + write:; { - String8 dst_path = rd_state->user_path; - String8 bucket_name = str8_lit("user"); B32 dst_exists = (os_properties_from_file_path(dst_path).created != 0); String8 temp_path = push_str8f(scratch.arena, "%S.temp", dst_path); String8 overwritten_path = push_str8f(scratch.arena, "%S.old", dst_path); @@ -13823,29 +13825,6 @@ rd_frame(void) os_move_file_path(dst_path, overwritten_path); } }break; - case RD_CmdKind_WriteProjectData: - { -#if 0 // TODO(rjf): @cfg - RD_CfgSrc src = RD_CfgSrc_User; - for(RD_CfgSrc s = (RD_CfgSrc)0; s < RD_CfgSrc_COUNT; s = (RD_CfgSrc)(s+1)) - { - if(kind == rd_cfg_src_write_cmd_kind_table[s]) - { - src = s; - break; - } - } - String8 path = rd_cfg_path_from_src(src); - String8List rd_strs = rd_cfg_strings_from_gfx(scratch.arena, path, src); - String8 header = push_str8f(scratch.arena, "// raddbg %s file\n\n", rd_cfg_src_string_table[src].str); - String8List strs = {0}; - str8_list_push(scratch.arena, &strs, header); - str8_list_concat_in_place(&strs, &rd_strs); - String8 data = str8_list_join(scratch.arena, &strs, 0); - String8 data_indented = indented_from_string(scratch.arena, data); - os_write_data_to_file_path(path, data_indented); -#endif - }break; //- rjf: code navigation case RD_CmdKind_Search: From 2373af25ceb6c9197cc9b009abc892f3c8a0104d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 18:11:25 -0800 Subject: [PATCH 158/755] watch expr drag/drop -> watch pin creation --- src/raddbg/generated/raddbg.meta.c | 8 ++-- src/raddbg/generated/raddbg.meta.h | 8 +++- src/raddbg/raddbg.mdesk | 8 +++- src/raddbg/raddbg_core.c | 67 ++++++++++++++++-------------- src/raddbg/raddbg_views.c | 10 ----- src/raddbg/raddbg_widgets.c | 28 +++++++++++-- 6 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index fac3994b..1bdd54e4 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -317,7 +317,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[12] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[38] = +Rng1U64 rd_reg_slot_range_table[40] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -345,6 +345,8 @@ Rng1U64 rd_reg_slot_range_table[38] = {OffsetOf(RD_Regs, voff), OffsetOf(RD_Regs, voff) + sizeof(U64)}, {OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)}, {OffsetOf(RD_Regs, voff_range), OffsetOf(RD_Regs, voff_range) + sizeof(Rng1U64)}, +{OffsetOf(RD_Regs, expr), OffsetOf(RD_Regs, expr) + sizeof(String8)}, +{OffsetOf(RD_Regs, view_rule), OffsetOf(RD_Regs, view_rule) + sizeof(String8)}, {OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)}, {OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)}, {OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)}, @@ -531,8 +533,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 348bb4fc..0ec59375 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -34,6 +34,8 @@ RD_RegSlot_Vaddr, RD_RegSlot_Voff, RD_RegSlot_VaddrRange, RD_RegSlot_VoffRange, +RD_RegSlot_Expr, +RD_RegSlot_ViewRule, RD_RegSlot_UIKey, RD_RegSlot_OffPx, RD_RegSlot_ListerFlags, @@ -550,6 +552,8 @@ U64 vaddr; U64 voff; Rng1U64 vaddr_range; Rng1U64 voff_range; +String8 expr; +String8 view_rule; UI_Key ui_key; Vec2F32 off_px; RD_ListerFlags lister_flags; @@ -611,6 +615,8 @@ RD_Query query; .voff = rd_regs()->voff,\ .vaddr_range = rd_regs()->vaddr_range,\ .voff_range = rd_regs()->voff_range,\ +.expr = rd_regs()->expr,\ +.view_rule = rd_regs()->view_rule,\ .ui_key = rd_regs()->ui_key,\ .off_px = rd_regs()->off_px,\ .lister_flags = rd_regs()->lister_flags,\ @@ -627,7 +633,7 @@ RD_Query query; C_LINKAGE_BEGIN extern RD_VocabInfo rd_vocab_info_table[293]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; -extern Rng1U64 rd_reg_slot_range_table[38]; +extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b1124a51..38125746 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -297,6 +297,10 @@ RD_RegTable: {Rng1U64 vaddr_range VaddrRange } {Rng1U64 voff_range VoffRange } + // rjf: evaluation + {String8 expr Expr } + {String8 view_rule ViewRule } + // rjf: ui context {UI_Key ui_key UIKey } {Vec2F32 off_px OffPx } @@ -545,8 +549,8 @@ RD_CmdTable: // | | | | {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 "" String null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } - {ToggleWatchPin 1 0 "" String null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + {AddWatchPin 1 1 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } //- rjf: auto view rule {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 19182ee8..74186fc7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1051,6 +1051,8 @@ rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src) dst->file_path = push_str8_copy(arena, src->file_path); dst->lines = d_line_list_copy(arena, &src->lines); dst->dbgi_key = di_key_copy(arena, &src->dbgi_key); + dst->expr = push_str8_copy(arena, src->expr); + dst->view_rule = push_str8_copy(arena, src->view_rule); dst->string = push_str8_copy(arena, src->string); dst->cmd_name = push_str8_copy(arena, src->cmd_name); dst->params_tree = md_tree_copy(arena, src->params_tree); @@ -5259,6 +5261,12 @@ rd_view_ui(Rng2F32 rect) case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; } } + else + { + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row_info->eval.exprs.last), + .view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key)) + rd_drag_begin(RD_RegSlot_Expr); + } } // rjf: (normally) single-click -> move selection here @@ -6267,7 +6275,6 @@ rd_window_frame(void) //- rjf: build UI // UI_Box *lister_box = &ui_nil_box; - UI_Box *hover_eval_box = &ui_nil_box; ProfScope("build UI") { //////////////////////////// @@ -6500,6 +6507,26 @@ rd_window_frame(void) di_scope_close(di_scope); }break; + + //////////////////////// + //- rjf: expression tooltips + // + case RD_RegSlot_Expr: + UI_Tooltip RD_Font(RD_FontSlot_Code) + { + ui_set_next_pref_width(ui_children_sum(1)); + UI_Row + { + rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); + ui_spacer(ui_em(2.f, 1.f)); + E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); + if(eval.mode != E_Mode_Null) + { + String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); + rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); + } + } + }break; } scratch_end(scratch); } @@ -8031,6 +8058,8 @@ rd_window_frame(void) } U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); + + // rjf: build container UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) UI_PrefHeight(ui_px(row_height_px, 1.f)) { @@ -9305,33 +9334,6 @@ rd_window_frame(void) ui_end_build(); } - ////////////////////////////// - //- rjf: ensure hover eval is in-bounds - // - if(!ui_box_is_nil(hover_eval_box)) - { - UI_Box *root = hover_eval_box; - Rng2F32 window_rect = os_client_rect_from_window(ui_window()); - Rng2F32 root_rect = root->rect; - Vec2F32 shift = - { - -ClampBot(0, root_rect.x1 - window_rect.x1), - -ClampBot(0, root_rect.y1 - window_rect.y1), - }; - Rng2F32 new_root_rect = shift_2f32(root_rect, shift); - root->fixed_position = new_root_rect.p0; - root->fixed_size = dim_2f32(new_root_rect); - root->rect = new_root_rect; - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) - { - ui_calc_sizes_standalone__in_place_rec(root, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(root, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(root, axis); - ui_layout_enforce_constraints__in_place_rec(root, axis); - ui_layout_position__in_place_rec(root, axis); - } - } - ////////////////////////////// //- rjf: attach lister boxes to root, or hide if it has not been renewed // @@ -15896,7 +15898,8 @@ Z(getting_started) { String8 file_path = rd_regs()->file_path; TxtPt pt = rd_regs()->cursor; - String8 string = rd_regs()->string; + String8 expr_string = rd_regs()->expr; + String8 view_rule_string = rd_regs()->view_rule; U64 vaddr = rd_regs()->vaddr; B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleWatchPin) @@ -15911,7 +15914,7 @@ Z(getting_started) U64 loc_vaddr = 0; B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - B32 loc_matches_expr = (string.size != 0 && str8_match(expr->first->string, string, 0)); + B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr->first->string, expr_string, 0)); if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) { rd_cfg_release(wp); @@ -15925,8 +15928,10 @@ Z(getting_started) RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); + RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule")); RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); - rd_cfg_new(expr, string); + rd_cfg_new(expr, expr_string); + rd_cfg_new(view_rule, view_rule_string); if(vaddr != 0) { rd_cfg_newf(loc, "0x%I64x", vaddr); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3202b4c0..0d2e47d7 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1543,16 +1543,6 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt) return result; } -//- rjf: watch view main hooks - -internal void -rd_watch_view_build(RD_WatchViewState *ewv, Rng2F32 rect) -{ - ProfBeginFunction(); - - ProfEnd(); -} - //////////////////////////////// //~ rjf: null @view_hook_impl diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 566b3095..0e3f87b7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -234,7 +234,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } //- rjf: cfg has expression attached -> use that - else if(expr_string.size != 0 && !str8_match(cfg->string, str8_lit("watch"), 0)) + else if(expr_string.size != 0 && !is_within_window) { dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); @@ -1829,7 +1829,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_Cfg *pin = n->v; String8 pin_expr = rd_expr_from_cfg(pin); String8 pin_view_rule = rd_view_rule_from_cfg(pin); - E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); + String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); + E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.type_key)) { @@ -2042,6 +2043,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_drag_drop_color = pop_color; } } + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) + { + line_drag_drop = 1; + line_drag_cfg = cfg; + line_drag_drop_color = pop_color; + } if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) { line_drag_drop = 1; @@ -2055,8 +2062,21 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } //- rjf: drop target is dropped -> process + if(contains_1s64(params->line_num_range, mouse_pt.line) && contains_2f32(clipped_top_container_rect, ui_mouse())) { - if(line_drag_cfg != &rd_nil_cfg && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && rd_drag_drop()) + { + S64 line_num = mouse_pt.line; + U64 line_idx = line_num - params->line_num_range.min; + U64 line_vaddr = params->line_vaddrs[line_idx]; + rd_cmd(RD_CmdKind_AddWatchPin, + .expr = rd_state->drag_drop_regs->expr, + .view_rule = rd_state->drag_drop_regs->view_rule, + .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), + .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), + .vaddr = line_vaddr); + } + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && line_drag_cfg != &rd_nil_cfg && rd_drag_drop()) { RD_Cfg *dropped_cfg = line_drag_cfg; S64 line_num = mouse_pt.line; @@ -2068,7 +2088,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); } - if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop() && contains_1s64(params->line_num_range, mouse_pt.line)) + if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop()) { S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; From 92df402ad1e73af6cdc3fa7dc8cd4ae057f361be Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 18:46:22 -0800 Subject: [PATCH 159/755] member filtering --- src/eval/eval_ir.c | 321 ++++++++++++++---- src/eval/eval_ir.h | 6 +- .../eval_visualization_core.c | 6 +- src/raddbg/raddbg_core.c | 8 +- 4 files changed, 260 insertions(+), 81 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9394872a..a7328d80 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -444,7 +444,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) // rjf: fall back to default else { - info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, filter); + info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); } } scratch_end(scratch); @@ -456,7 +456,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(slice) { if(user_data == 0) { - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, idx_range, exprs, exprs_strings, user_data); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, idx_range, exprs, exprs_strings, user_data); } else { @@ -474,73 +474,6 @@ E_LOOKUP_RANGE_FUNCTION_DEF(slice) } } -//////////////////////////////// -//~ rjf: Lookups - -internal E_LookupRuleMap -e_lookup_rule_map_make(Arena *arena, U64 slots_count) -{ - E_LookupRuleMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(default), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(file), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); - return map; -} - -internal void -e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) -{ - U64 hash = e_hash_from_string(5381, rule->name); - U64 slot_idx = hash%map->slots_count; - E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); - MemoryCopyStruct(&n->v, rule); - if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } - if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } - if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } - if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } - if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } - n->v.name = push_str8_copy(arena, n->v.name); -} - -internal E_LookupRule * -e_lookup_rule_from_string(String8 string) -{ - E_LookupRule *result = &e_lookup_rule__nil; - if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; - for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->v.name, string, 0)) - { - result = &n->v; - break; - } - } - } - return result; -} - E_LOOKUP_INFO_FUNCTION_DEF(default) { E_LookupInfo lookup_info = {0}; @@ -951,6 +884,252 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) return id; } +//////////////////////////////// +//~ rjf: Member Filtering Lookup Rules + +typedef struct E_MemberFilterAccel E_MemberFilterAccel; +struct E_MemberFilterAccel +{ + E_MemberArray members; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(only) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupInfo lookup_info = {0}; + { + //- rjf: extract struct type + E_TypeKey struct_type_key = zero_struct; + { + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + struct_type_key = direct_type_key; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + struct_type_key = lhs_type_key; + } + } + + //- rjf: not struct -> fall back on default + if(e_type_key_match(struct_type_key, e_type_key_zero())) + { + lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); + } + + //- struct -> filter + else + { + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberList data_members_list__filtered = {0}; + for EachIndex(idx, data_members.count) + { + B32 fits_filter = 0; + for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) + { + if(str8_match(name->string, data_members.v[idx].name, 0)) + { + fits_filter = 1; + break; + } + } + if(fits_filter) + { + e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); + } + } + E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); + accel->members = e_member_array_from_list(arena, &data_members_list__filtered); + lookup_info.user_data = accel; + lookup_info.named_expr_count = accel->members.count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_INFO_FUNCTION_DEF(omit) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupInfo lookup_info = {0}; + { + //- rjf: extract struct type + E_TypeKey struct_type_key = zero_struct; + { + E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + struct_type_key = direct_type_key; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + struct_type_key = lhs_type_key; + } + } + + //- rjf: not struct -> fall back on default + if(e_type_key_match(struct_type_key, e_type_key_zero())) + { + lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); + } + + //- struct -> filter + else + { + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberList data_members_list__filtered = {0}; + for EachIndex(idx, data_members.count) + { + B32 fits_filter = 1; + for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) + { + if(str8_match(name->string, data_members.v[idx].name, 0)) + { + fits_filter = 0; + break; + } + } + if(fits_filter) + { + e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); + } + } + E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); + accel->members = e_member_array_from_list(arena, &data_members_list__filtered); + lookup_info.user_data = accel; + lookup_info.named_expr_count = accel->members.count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) +{ + if(user_data == 0) + { + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, idx_range, exprs, exprs_strings, user_data); + } + else + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_MemberFilterAccel *accel = (E_MemberFilterAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->members.count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = accel->members.v[member_idx].name; + exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); + } + scratch_end(scratch); + } +} + +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRuleMap +e_lookup_rule_map_make(Arena *arena, U64 slots_count) +{ + E_LookupRuleMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(default), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(file), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("only"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(only), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); + e_lookup_rule_map_insert_new(arena, &map, str8_lit("omit"), + .info = E_LOOKUP_INFO_FUNCTION_NAME(omit), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); + return map; +} + +internal void +e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) +{ + U64 hash = e_hash_from_string(5381, rule->name); + U64 slot_idx = hash%map->slots_count; + E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + MemoryCopyStruct(&n->v, rule); + if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } + if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } + if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } + if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } + if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } + n->v.name = push_str8_copy(arena, n->v.name); +} + +internal E_LookupRule * +e_lookup_rule_from_string(String8 string) +{ + E_LookupRule *result = &e_lookup_rule__nil; + if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; + for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->v.name, string, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + //////////////////////////////// //~ rjf: IR Gen Rules @@ -1637,8 +1816,8 @@ E_IRGEN_FUNCTION_DEF(default) ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule_and_tag.rule->name)) { e_tag_poison(lhs_lookup_rule_and_tag.tag); - E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, str8_zero()); - E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data); + E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, lhs_lookup_rule_and_tag.tag, str8_zero()); + E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule_and_tag.tag, lookup_info.user_data); result = lookup_access.irtree_and_type; e_tag_unpoison(lhs_lookup_rule_and_tag.tag); } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index c1cfad6d..fa0cb283 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -73,19 +73,19 @@ struct E_LookupAccess E_IRTreeAndType irtree_and_type; }; -#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, String8 filter) +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter) #define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name #define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); E_LOOKUP_INFO_FUNCTION_DEF(default); -#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) +#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data) #define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name #define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); E_LOOKUP_ACCESS_FUNCTION_DEF(default); -#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) #define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name #define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5b3ba0c0..bb500064 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -592,7 +592,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; // rjf: get top-level lookup/expansion info - E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, filter); + E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_and_tag.tag, filter); EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); // rjf: determine expansion info @@ -712,7 +712,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Expr *child_expr = &e_expr_nil; String8 child_string = {0}; - lookup_rule->range(arena, t->expr, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); + lookup_rule->range(arena, t->expr, lookup_rule_tag, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; @@ -1003,7 +1003,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } else { - n->v.block->lookup_rule->range(arena, n->v.block->expr, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + n->v.block->lookup_rule->range(arena, n->v.block->expr, n->v.block->lookup_tag, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); } // rjf: no expansion operator applied -> push row for block expression; pass through block info diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 74186fc7..2c5a71d4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10110,7 +10110,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("["); String8 closer_string = str8_lit("]"); @@ -10128,7 +10128,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) @@ -10244,7 +10244,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, filter); + E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("{"); String8 closer_string = str8_lit("}"); @@ -10268,7 +10268,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) From 04c40e8359404f66f610558d2a0fb482cbf03fec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 19:16:27 -0800 Subject: [PATCH 160/755] expand eval to collecting irtree/type/lookup-rule, base all value string generation on entire root_eval rather than just root_expr; fixes wrong inheritance of tags in single-line visualization --- src/eval/eval_bundles.c | 108 ++++-------------- src/eval/eval_bundles.h | 6 +- .../eval_visualization_core.c | 2 +- src/raddbg/raddbg_core.c | 102 +++++++++-------- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 46 ++++---- src/raddbg/raddbg_widgets.c | 4 +- 7 files changed, 107 insertions(+), 163 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 0ee41d92..11c8e68a 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -16,18 +16,19 @@ internal E_Eval e_eval_from_exprs(Arena *arena, E_ExprChain exprs) { ProfBeginFunction(); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); - E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); + E_LookupRuleTagPair lookup = e_lookup_rule_tag_pair_from_expr_irtree(exprs.last, &irtree); + E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); E_Eval eval = { - .value = interp.value, - .mode = irtree.mode, - .space = interp.space, - .exprs = exprs, - .type_key = irtree.type_key, - .code = interp.code, + .value = interp.value, + .space = interp.space, + .exprs = exprs, + .irtree = irtree, + .lookup_rule_tag = lookup, + .code = interp.code, }; e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT) @@ -68,10 +69,10 @@ e_autoresolved_eval_from_eval(E_Eval eval) e_interpret_ctx && e_parse_state->ctx->modules_count > 0 && e_interpret_ctx->module_base != 0 && - (e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S64)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U64)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S32)) || - e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U32)))) + (e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S64)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U64)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S32)) || + e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U32)))) { U64 vaddr = eval.value.u64; U64 voff = vaddr - e_interpret_ctx->module_base[0]; @@ -84,7 +85,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) if(string_idx == 0) { string_idx = gvar->name_string_idx; } if(string_idx != 0) { - eval.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); + eval.irtree.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); } } return eval; @@ -93,7 +94,7 @@ e_autoresolved_eval_from_eval(E_Eval eval) internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval) { - E_TypeKey type_key = eval.type_key; + E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); if(e_type_state != 0 && e_interpret_ctx != 0 && @@ -151,7 +152,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); - eval.type_key = ptr_to_derived_type_key; + eval.irtree.type_key = ptr_to_derived_type_key; } } } @@ -166,13 +167,13 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval) { ProfBeginFunction(); - if(eval.mode == E_Mode_Offset) + if(eval.irtree.mode == E_Mode_Offset) { - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); if(type_kind == E_TypeKind_Array) { - eval.mode = E_Mode_Value; + eval.irtree.mode = E_Mode_Value; } else { @@ -183,7 +184,7 @@ e_value_eval_from_eval(E_Eval eval) type_byte_size <= sizeof(E_Value) && e_space_read(eval.space, &eval.value, value_vaddr_range)) { - eval.mode = E_Mode_Value; + eval.irtree.mode = E_Mode_Value; // rjf: mask&shift, for bitfields if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64)) @@ -197,7 +198,7 @@ e_value_eval_from_eval(E_Eval eval) } eval.value.u64 = eval.value.u64 >> type->off; eval.value.u64 = eval.value.u64 & valid_bits_mask; - eval.type_key = type->direct_type_key; + eval.irtree.type_key = type->direct_type_key; scratch_end(scratch); } @@ -219,69 +220,6 @@ e_value_eval_from_eval(E_Eval eval) return eval; } -internal E_Eval -e_element_eval_from_array_eval_index(E_Eval eval, U64 index) -{ - E_Eval result = {0}; - result.mode = eval.mode; - result.space = eval.space; - result.type_key = e_type_direct_from_key(eval.type_key); - result.code = eval.code; - result.msgs = eval.msgs; - U64 element_size = e_type_byte_size_from_key(result.type_key); - switch(eval.mode) - { - default:{}break; - case E_Mode_Value: - if(element_size <= sizeof(E_Value) && - index < sizeof(E_Value)/element_size) - { - MemoryCopy((U8 *)(&result.value.u512[0]), - (U8 *)(&eval.value.u512[0]) + index*element_size, - element_size); - }break; - case E_Mode_Offset: - { - result.value.u64 = eval.value.u64 + element_size*index; - }break; - } - return result; -} - -internal E_Eval -e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name) -{ - E_Eval result = {0}; - { - E_Member member = e_type_member_from_key_name__cached(eval.type_key, member_name); - if(member.kind != E_MemberKind_Null) - { - result.mode = eval.mode; - result.space = eval.space; - result.type_key = member.type_key; - result.code = eval.code; - result.msgs = eval.msgs; - switch(eval.mode) - { - default:{}break; - case E_Mode_Value: - if(member.off < sizeof(eval.value)) - { - U64 member_size = e_type_byte_size_from_key(member.type_key); - MemoryCopy((U8 *)(&result.value.u512[0]), - (U8 *)(&eval.value.u512[0]) + member.off, - Min(member_size, sizeof(eval.value) - member.off)); - }break; - case E_Mode_Offset: - { - result.value.u64 = eval.value.u64 + member.off; - }break; - } - } - } - return result; -} - internal E_Value e_value_from_string(String8 string) { diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index c72fa6ee..311a752e 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -11,10 +11,10 @@ typedef struct E_Eval E_Eval; struct E_Eval { E_Value value; - E_Mode mode; E_Space space; E_ExprChain exprs; - E_TypeKey type_key; + E_IRTreeAndType irtree; + E_LookupRuleTagPair lookup_rule_tag; E_InterpretationCode code; E_MsgList msgs; }; @@ -29,8 +29,6 @@ internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); internal E_Eval e_value_eval_from_eval(E_Eval eval); -internal E_Eval e_element_eval_from_array_eval_index(E_Eval eval, U64 index); -internal E_Eval e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name); internal E_Value e_value_from_string(String8 string); internal E_Value e_value_from_stringf(char *fmt, ...); internal E_Value e_value_from_expr(E_Expr *expr); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index bb500064..9ab53f7a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1341,7 +1341,7 @@ internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval) { String8 result = {0}; - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_byte_size = e_type_byte_size_from_key(type_key); U8 digit_group_separator = 0; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2c5a71d4..81afc10e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -85,7 +85,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) if(filter.size != 0) { E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Type *type = e_type_from_key__cached(eval.type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); if(type->kind != E_TypeKind_Set) { passes_filter = 0; @@ -3120,12 +3120,12 @@ internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping) { B32 result = 0; - if(dst_eval.mode == E_Mode_Offset) + if(dst_eval.irtree.mode == E_Mode_Offset) { Temp scratch = scratch_begin(0, 0); - E_TypeKey type_key = e_type_unwrap(dst_eval.type_key); + E_TypeKey type_key = e_type_unwrap(dst_eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.type_key))); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.irtree.type_key))); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); String8 commit_data = {0}; B32 commit_at_ptr_dest = 0; @@ -3142,7 +3142,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un { E_Eval src_eval = e_eval_from_string(scratch.arena, string); E_Eval src_eval_value = e_value_eval_from_eval(src_eval); - E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.type_key); + E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); if(direct_type_kind == E_TypeKind_Char8 || direct_type_kind == E_TypeKind_Char16 || direct_type_kind == E_TypeKind_Char32 || @@ -3201,17 +3201,17 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un else if(type_kind == E_TypeKind_Ptr && (e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || e_type_kind_is_integer(src_eval_value_type_kind)) && - src_eval_value.mode == E_Mode_Value) + src_eval_value.irtree.mode == E_Mode_Value) { commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); - commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.type_key)); + commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.irtree.type_key)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } } if(commit_data.size != 0 && e_type_byte_size_from_key(type_key) != 0) { U64 dst_offset = dst_eval.value.u64; - if(dst_eval.mode == E_Mode_Offset && commit_at_ptr_dest) + if(dst_eval.irtree.mode == E_Mode_Offset && commit_at_ptr_dest) { E_Eval dst_value_eval = e_value_eval_from_eval(dst_eval); dst_offset = dst_value_eval.value.u64; @@ -4177,7 +4177,7 @@ rd_view_ui(Rng2F32 rect) case RD_WatchCellKind_Eval: { RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.eval.mode == E_Mode_Offset) + if(cell_info.eval.irtree.mode == E_Mode_Offset) { B32 should_commit_asap = editing_complete; if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) @@ -4870,7 +4870,7 @@ rd_view_ui(Rng2F32 rect) ProfBegin("determine if row's data is fresh and/or bad"); B32 row_is_fresh = 0; B32 row_is_bad = 0; - switch(row_info->eval.mode) + switch(row_info->eval.irtree.mode) { default:{}break; case E_Mode_Offset: @@ -4878,7 +4878,7 @@ rd_view_ui(Rng2F32 rect) CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) { - U64 size = e_type_byte_size_from_key(row_info->eval.type_key); + U64 size = e_type_byte_size_from_key(row_info->eval.irtree.type_key); size = Min(size, 64); Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); @@ -4940,7 +4940,7 @@ rd_view_ui(Rng2F32 rect) if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { U64 row_offset = row_info->eval.value.u64; - if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && + if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && row_offset%64 == 0 && row_depth > 0) { ui_set_next_fixed_x(0); @@ -4956,12 +4956,12 @@ rd_view_ui(Rng2F32 rect) // if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - if((row_info->eval.mode == E_Mode_Offset || row_info->eval.mode == E_Mode_Null) && + if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && row_info->eval.value.u64%64 != 0 && row_depth > 0 && !row_expanded) { - U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.type_key)); + U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.irtree.type_key)); if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) { ui_set_next_fixed_x(0); @@ -5622,7 +5622,7 @@ rd_view_cfg_value_from_string(String8 string) internal U64 rd_base_offset_from_eval(E_Eval eval) { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key))) + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.irtree.type_key))) { eval = e_value_eval_from_eval(eval); } @@ -5641,23 +5641,23 @@ rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) break; } } - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key)); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.irtree.type_key)); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Union || direct_type_kind == E_TypeKind_Class || direct_type_kind == E_TypeKind_Array)) { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key))); + size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.irtree.type_key))); } - if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) + if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Union || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Array)) { - size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key)); + size = e_type_byte_size_from_key(e_type_unwrap(eval.irtree.type_key)); } if(size == 0) { @@ -6520,7 +6520,7 @@ rd_window_frame(void) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); ui_spacer(ui_em(2.f, 1.f)); E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); - if(eval.mode != E_Mode_Null) + if(eval.irtree.mode != E_Mode_Null) { String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); @@ -9858,7 +9858,7 @@ rd_window_frame(void) //~ rjf: Eval Visualization internal F32 -rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Expr *root_expr, E_Eval eval, String8List *out) +rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -9870,7 +9870,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f B32 no_addr = 0; B32 no_string = 0; B32 has_array = 0; - for(E_Expr *tag = root_expr->first_tag; tag != &e_expr_nil; tag = tag->next) + for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} else if(str8_match(tag->string, str8_lit("dec"), 0)) {radix = 10;} @@ -9891,14 +9891,14 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - E_TypeKind kind = e_type_kind_from_key(eval.type_key); + E_TypeKind kind = e_type_kind_from_key(eval.irtree.type_key); if(kind != E_TypeKind_Ptr) { no_addr = 1; } else { - E_Type *type = e_type_from_key__cached(eval.type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); if(!(type->flags & E_TypeFlag_External)) { no_addr = 1; @@ -9938,16 +9938,16 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } //- rjf: type evaluations -> display type string - if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key)) + if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { - String8 string = e_type_string_from_key(arena, eval.type_key); + String8 string = e_type_string_from_key(arena, eval.irtree.type_key); str8_list_push(arena, out, string); } //- rjf: value/offset evaluations else if(max_size > 0) { - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind kind = e_type_kind_from_key(type_key); switch(kind) { @@ -9967,7 +9967,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f case E_TypeKind_RRef: { // rjf: unpack type info - E_TypeKey type_key = e_type_unwrap(eval.type_key); + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_Type *type = e_type_from_key__cached(type_key); E_TypeKind type_kind = type->kind; E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(type_key)); @@ -10101,15 +10101,19 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.exprs.last); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, deref_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, deref_eval, out); } else { // rjf: unpack - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; + E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; + if(lookup_rule == &e_lookup_rule__default) + { + lookup_rule = root_eval.lookup_rule_tag.rule; + lookup_rule_tag = root_eval.lookup_rule_tag.tag; + } E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("["); @@ -10139,7 +10143,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } is_first = 0; E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); if(space_taken > max_size && idx+1 < total_possible_child_count) { String8 ellipses = str8_lit(", ..."); @@ -10170,7 +10174,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f case E_TypeKind_Array: { // rjf: unpack type info - E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.type_key)); + E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.irtree.type_key)); E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); U64 array_count = eval_type->count; @@ -10188,7 +10192,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f did_content = 1; U64 string_buffer_size = Clamp(1, array_count, 1024); U8 *string_buffer = push_array(arena, U8, string_buffer_size); - switch(eval.mode) + switch(eval.irtree.mode) { default:{}break; case E_Mode_Offset: @@ -10240,10 +10244,14 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f arrays_and_sets_and_structs: { // rjf: unpack - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last); - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(eval.exprs.last, &irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; + E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; + if(lookup_rule == &e_lookup_rule__default) + { + lookup_rule = root_eval.lookup_rule_tag.rule; + lookup_rule_tag = root_eval.lookup_rule_tag.tag; + } E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("{"); @@ -10279,7 +10287,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } is_first = 0; E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_expr, child_eval, out); + space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); if(space_taken > max_size && idx+1 < total_possible_child_count) { String8 ellipses = str8_lit(", ..."); @@ -10315,7 +10323,7 @@ rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U3 { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, filter, flags, default_radix, font, font_size, max_size, 0, eval.exprs.last, eval, &strs); + rd_append_value_strings_from_eval(scratch.arena, filter, flags, default_radix, font, font_size, max_size, 0, eval, eval, &strs); String8 result = str8_list_join(arena, &strs, 0); scratch_end(scratch); return result; @@ -11843,7 +11851,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) E_Eval eval = e_eval_from_string(scratch.arena, string); if(eval.msgs.max_kind == E_MsgKind_Null) { - E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_unwrap(eval.type_key)); + E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)); if(eval_type_kind == E_TypeKind_Ptr || eval_type_kind == E_TypeKind_LRef || eval_type_kind == E_TypeKind_RRef) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 4c78ebe3..644cd104 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1123,7 +1123,7 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Expr *root_expr, E_Eval eval, String8List *out); +internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out); internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0d2e47d7..e14a5b0a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -782,7 +782,7 @@ rd_id_from_watch_cell(RD_WatchCell *cell) result = e_hash_from_string(result, str8_struct(&cell->kind)); if(cell->kind != RD_WatchCellKind_Expr) { - result = e_hash_from_string(result, str8_struct(&cell->eval.mode)); + result = e_hash_from_string(result, str8_struct(&cell->eval.irtree.mode)); result = e_hash_from_string(result, str8_struct(&cell->index)); result = e_hash_from_string(result, str8_struct(&cell->default_pct)); } @@ -903,7 +903,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); - E_TypeKey block_type_key = block_eval.type_key; + E_TypeKey block_type_key = block_eval.irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); E_Type *block_type = e_type_from_key__cached(block_type_key); @@ -925,12 +925,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { default: case CTRL_EntityKind_Process: - if(info.eval.mode == E_Mode_Offset) + if(info.eval.irtree.mode == E_Mode_Offset) { info.module = ctrl_module_from_process_vaddr(row_ctrl_entity, info.eval.value.u64); }break; case CTRL_EntityKind_Thread: - if(info.eval.mode == E_Mode_Value) + if(info.eval.irtree.mode == E_Mode_Value) { CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); info.module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); @@ -996,13 +996,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(evalled_cfg != &rd_nil_cfg) { E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); - is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); } if(evalled_entity != &ctrl_entity_nil) { String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); - is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.type_key)); + is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); } // rjf: determine view ui rule @@ -1093,7 +1093,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular button for unattached processes else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { - E_Type *type = e_type_from_key__cached(info.eval.type_key); + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); if(str8_match(type->name, str8_lit("unattached_process"), 0)) { U64 pid = info.eval.value.u128.u64[0]; @@ -1119,7 +1119,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular button for commands else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - E_Type *type = e_type_from_key__cached(info.eval.type_key); + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); @@ -1137,7 +1137,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { String8 file_path = e_string_from_id(info.eval.value.u64); DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); - E_Type *type = e_type_from_key__cached(info.eval.type_key); + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); if(str8_match(type->name, str8_lit("folder"), 0)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, @@ -1287,7 +1287,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.flags |= RD_WatchCellFlag_CanEdit; } - result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); result.string = row->string; if(result.string.size == 0) { @@ -1392,7 +1392,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: evaluate wrapped expression - result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); //- rjf: determine default radix U32 default_radix = 10; @@ -1404,8 +1404,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: generate strings/flags based on that expression & fill result.string = rd_value_string_from_eval(arena, rd_view_search(), string_flags, default_radix, font, font_size, max_size_px, result.eval); - result.flags |= !!(ev_type_key_is_editable(result.eval.type_key) && result.eval.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; - E_Type *type = e_type_from_key__cached(result.eval.type_key); + result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) { result.flags |= RD_WatchCellFlag_IsNonCode; @@ -1425,7 +1425,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: view ui cells case RD_WatchCellKind_ViewUI: { - result.eval = (cell->eval.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); result.view_ui_rule = row_info->view_ui_rule; result.view_ui_tag = row_info->view_ui_tag; }break; @@ -1442,7 +1442,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); - if(e_type_key_match(cfg_type, result.eval.type_key)) + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) { result.entity = entity; } @@ -1452,7 +1452,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); - if(e_type_key_match(cfg_type, result.eval.type_key)) + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) { result.cfg = cfg; } @@ -1475,7 +1475,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); - if(e_type_key_match(cfg_type, result.eval.type_key)) + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) { result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1); result.flags |= RD_WatchCellFlag_Button; @@ -1487,7 +1487,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); - if(e_type_key_match(cfg_type, result.eval.type_key)) + if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) { result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); result.flags |= RD_WatchCellFlag_Button; @@ -2361,10 +2361,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { String8 local_name = n->string; E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); - if(local_eval.mode == E_Mode_Offset) + if(local_eval.irtree.mode == E_Mode_Offset) { - E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.type_key); - U64 local_eval_type_size = e_type_byte_size_from_key(local_eval.type_key); + E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.irtree.type_key); + U64 local_eval_type_size = e_type_byte_size_from_key(local_eval.irtree.type_key); Rng1U64 vaddr_rng = r1u64(local_eval.value.u64, local_eval.value.u64+local_eval_type_size); Rng1U64 vaddr_rng_in_visible = intersect_1u64(viz_range_bytes, vaddr_rng); if(vaddr_rng_in_visible.max != vaddr_rng_in_visible.min) @@ -2373,7 +2373,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { annotation->name_string = push_str8_copy(scratch.arena, local_name); annotation->kind_string = str8_lit("Local"); - annotation->type_string = e_type_string_from_key(scratch.arena, local_eval.type_key); + annotation->type_string = e_type_string_from_key(scratch.arena, local_eval.irtree.type_key); annotation->color = color_gen_table[(vaddr_rng.min/8)%ArrayCount(color_gen_table)]; annotation->vaddr_range = vaddr_rng; } @@ -3150,7 +3150,7 @@ rd_rgba_from_eval_params(E_Eval eval, MD_Node *params) Vec4F32 rgba = {0}; { E_Eval value_eval = e_value_eval_from_eval(eval); - E_TypeKey type_key = eval.type_key; + E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_size = e_type_byte_size_from_key(type_key); if(16 <= type_size) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0e3f87b7..3ccc4d96 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1832,7 +1832,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); String8 eval_string = {0}; - if(!e_type_key_match(e_type_key_zero(), eval.type_key)) + if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); } @@ -2185,7 +2185,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(!ui_dragging(text_container_sig) && text_container_sig.event_flags == 0 && mouse_expr.size != 0) { E_Eval eval = e_eval_from_string(scratch.arena, mouse_expr); - if(eval.msgs.max_kind == E_MsgKind_Null && (eval.mode != E_Mode_Null || mouse_expr_is_explicit)) + if(eval.msgs.max_kind == E_MsgKind_Null && (eval.irtree.mode != E_Mode_Null || mouse_expr_is_explicit)) { U64 line_vaddr = 0; if(contains_1s64(params->line_num_range, mouse_pt.line)) From 0a588d4058cf140129e7da06138e1df10507ebb3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 19:46:41 -0800 Subject: [PATCH 161/755] fix keyboard input delegation between meta-interfaces (query lister line edit) and watch window controls; always accept single-visible-button presses, if multiline logic does not consume an event --- src/raddbg/raddbg_core.c | 155 +++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 81afc10e..fdcbd7d0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2644,7 +2644,8 @@ rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity) 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)); + B32 is_frozen = ctrl_entity_tree_is_frozen(entity); + str8_list_push(scratch.arena, &fixed_width_parts, str8((U8 *)&is_frozen, 1)); } else if(str8_match(member_name, str8_lit("vaddr_range"), 0)) { @@ -3402,25 +3403,6 @@ rd_view_ui(Rng2F32 rect) { vs->is_searching = 1; } - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) - { - vs->is_searching = 0; - vs->search_string_size = 0; - } - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) - { - RD_RegsScope() - { - rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); - rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); - rd_push_cmd(cmd_name, rd_regs()); - } - if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) - { - vs->is_searching = 0; - vs->search_string_size = 0; - } - } } //- rjf: commit string to view @@ -3944,7 +3926,7 @@ rd_view_ui(Rng2F32 rect) evt->flags & UI_EventFlag_Paste || (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && selection_tbl.min.x == selection_tbl.max.x && - (selection_tbl.min.y != 0 || selection_tbl.min.y != 0)) + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0)) { Vec2S64 selection_dim = dim_2s64(selection_tbl); arena_clear(ewv->text_edit_arena); @@ -3993,60 +3975,65 @@ rd_view_ui(Rng2F32 rect) //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if // cannot apply to multi-cursor, then just don't take the event // - if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept) + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0) && + (selection_tbl.max.y - selection_tbl.min.y > 0)) { - taken = 1; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + if(row_node != 0) { - // rjf: unpack row info - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - - // rjf: loop through X selections and perform operations for each - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + taken = 1; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { -#if 0 // TODO(rjf): @cfg - //- rjf: determine operation for this cell - typedef enum OpKind - { - OpKind_Null, - OpKind_DoExpand, - } - OpKind; - OpKind kind = OpKind_Null; - switch(row_kind) - { - default:{}break; - case RD_WatchViewRowKind_Normal: - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; - } - }break; - case RD_WatchViewRowKind_PrettyEntityControls: - if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) - { - kind = OpKind_DoExpand; - }break; - } + // rjf: unpack row info + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - //- rjf: perform operation - switch(kind) + // rjf: loop through X selections and perform operations for each + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { - default:{taken = 0;}break; - case OpKind_DoExpand: - if(ev_row_is_expandable(row)) +#if 0 // TODO(rjf): @cfg + //- rjf: determine operation for this cell + typedef enum OpKind { - B32 is_expanded = ev_expansion_from_key(eval_view, row->key); - ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); - }break; - } + OpKind_Null, + OpKind_DoExpand, + } + OpKind; + OpKind kind = OpKind_Null; + switch(row_kind) + { + default:{}break; + case RD_WatchViewRowKind_Normal: + { + RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; + } + }break; + case RD_WatchViewRowKind_PrettyEntityControls: + if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) + { + kind = OpKind_DoExpand; + }break; + } + + //- rjf: perform operation + switch(kind) + { + default:{taken = 0;}break; + case OpKind_DoExpand: + if(ev_row_is_expandable(row)) + { + B32 is_expanded = ev_expansion_from_key(eval_view, row->key); + ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); + }break; + } #endif + } } } } @@ -5278,7 +5265,8 @@ rd_view_ui(Rng2F32 rect) // rjf: activation (double-click normally, or single-clicks with special buttons) if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || - ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig))) + ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig)) || + sig.f & UI_SignalFlag_KeyboardPressed) { // rjf: kill if a double-clickable cell if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) @@ -5556,6 +5544,34 @@ rd_view_ui(Rng2F32 rect) } } + //////////////////////////// + //- rjf: catchall query completion controls + // + if(vs->is_searching) UI_Focus(UI_FocusKind_On) + { + String8 cmd_name = vs->search_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + { + RD_RegsScope() + { + rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); + rd_push_cmd(cmd_name, rd_regs()); + } + if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } + } + } + ProfEnd(); } @@ -7200,11 +7216,6 @@ rd_window_frame(void) } } - //- rjf: accept - if(ui_slot_press(UI_EventActionSlot_Accept)) - { - } - //- rjf: build darkening rectangle over rest of screen UI_Rect(window_rect) UI_TagF("inactive") { From f3c6ee6f1f6d63b5f5298641ab894674826c4922 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Feb 2025 19:52:17 -0800 Subject: [PATCH 162/755] fix statically-disqualifiable breakpoint evaluations from being sent to the control thread as actual control thread conditions --- src/raddbg/raddbg_core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fdcbd7d0..c5a89a2f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12243,12 +12243,6 @@ rd_frame(void) local_persist S32 depth = 0; log_scope_begin(); - //- TODO(rjf): @cfg debugging: stringify the current cfg tree - { - String8 string = rd_string_from_cfg_tree(scratch.arena, rd_state->root_cfg); - int x = 0; - } - ////////////////////////////// //- rjf: do per-frame resets // @@ -16773,6 +16767,7 @@ Z(getting_started) // we can evaluate this condition early, and decide whether or not to send this // breakpoint. B32 is_statically_disqualified = 0; + String8 non_ctrl_thread_static_condition = src_bp_cnd; if(is_static_for_ctrl_thread) { E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd); @@ -16781,6 +16776,7 @@ Z(getting_started) { is_statically_disqualified = 1; } + MemoryZeroStruct(&non_ctrl_thread_static_condition); } //- rjf: statically disqualified? -> skip @@ -16796,7 +16792,7 @@ Z(getting_started) dst_bp->pt = src_bp_loc.pt; dst_bp->symbol_name = src_bp_loc.name; dst_bp->vaddr = src_bp_loc.vaddr; - dst_bp->condition = src_bp_cnd; + dst_bp->condition = non_ctrl_thread_static_condition; idx += 1; } } From c7da3e8a13fb47ffb046bffb8cfe84d7d65ffe4c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 08:42:33 -0800 Subject: [PATCH 163/755] distinguish cfg (breakpoints, watch pins) source-locations from address locations; expand breakpoint addresses to being full expressions, & use this to implement symbol breakpoints (we now support fancier address resolution breakpoints too) --- src/ctrl/ctrl_core.c | 354 ++++++++++++++++------------- src/ctrl/ctrl_core.h | 24 +- src/dbg_engine/dbg_engine_core.c | 24 +- src/dbg_engine/dbg_engine_core.h | 3 +- src/raddbg/generated/raddbg.meta.c | 12 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 24 +- src/raddbg/raddbg_core.c | 168 ++++++-------- src/raddbg/raddbg_core.h | 3 +- src/raddbg/raddbg_views.c | 10 +- src/raddbg/raddbg_widgets.c | 14 +- 11 files changed, 335 insertions(+), 303 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ee778ba6..ff10a7d6 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3418,11 +3418,11 @@ ctrl_thread__entry_point(void *p) //- rjf: breakpoint resolution internal void -ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) +ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) { if(user_bps->first == 0) { return; } Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); + DI_Scope *di_scope = eval_scope->di_scope; CTRL_Entity *module_entity = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module); CTRL_Entity *debug_info_path_entity = ctrl_entity_child_from_kind(module_entity, CTRL_EntityKind_DebugInfoPath); DI_Key dbgi_key = {debug_info_path_entity->string, debug_info_path_entity->timestamp}; @@ -3486,45 +3486,37 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle proc } }break; - //- rjf: symbol:voff-based breakpoints - case CTRL_UserBreakpointKind_SymbolNameAndOffset: + //- rjf: expression-based breakpoints + case CTRL_UserBreakpointKind_Expression: { - String8 symbol_name = bp->string; - U64 voff = bp->u64; - RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap map = {0}; - rdi_parsed_from_name_map(rdi, mapptr, &map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, symbol_name.str, symbol_name.size); - if(node != 0) + String8 expr = bp->string; + E_Value value = e_value_from_string(expr); + if(value.u64 != 0) { - U32 id_count = 0; - U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count); - for(U32 match_i = 0; match_i < id_count; match_i += 1) - { - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, ids[match_i]); - U64 proc_voff = rdi_first_voff_from_procedure(rdi, procedure); - U64 proc_vaddr = proc_voff + base_vaddr; - DMN_Trap trap = {process.dmn_handle, proc_vaddr + voff, (U64)bp}; - dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); - } + DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); } }break; } } - di_scope_close(di_scope); scratch_end(scratch); } internal void -ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) +ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out) { for(CTRL_UserBreakpointNode *n = user_bps->first; n != 0; n = n->next) { CTRL_UserBreakpoint *bp = &n->v; - if(bp->kind == CTRL_UserBreakpointKind_VirtualAddress) + if(bp->kind == CTRL_UserBreakpointKind_Expression) { - DMN_Trap trap = {process.dmn_handle, bp->u64, (U64)bp}; - dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); + String8 expr = bp->string; + E_Value value = e_value_from_string(expr); + if(value.u64 != 0) + { + DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); + } } } } @@ -4497,6 +4489,128 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) return result; } +//- rjf: control thread eval scopes + +internal CTRL_EvalScope * +ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) +{ + CTRL_EvalScope *scope = push_array(arena, CTRL_EvalScope, 1); + scope->di_scope = di_scope_open(); + + // rjf: unpack thread + Arch arch = thread->arch; + U64 thread_rip_vaddr = dmn_rip_from_thread(thread->handle.dmn_handle); + CTRL_Entity *process = ctrl_process_from_entity(thread); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); + + // rjf: gather evaluation modules + U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); + E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); + E_Module *eval_modules_primary = &eval_modules[0]; + eval_modules_primary->rdi = &di_rdi_parsed_nil; + eval_modules_primary->vaddr_range = r1u64(0, max_U64); + { + U64 eval_module_idx = 0; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + machine != &ctrl_entity_nil; + machine = machine->next) + { + if(machine->kind != CTRL_EntityKind_Machine) { continue; } + for(CTRL_Entity *process = machine->first; + process != &ctrl_entity_nil; + process = process->next) + { + if(process->kind != CTRL_EntityKind_Process) { continue; } + for(CTRL_Entity *mod = process->first; + mod != &ctrl_entity_nil; + mod = mod->next) + { + if(mod->kind != CTRL_EntityKind_Module) { continue; } + CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(mod, CTRL_EntityKind_DebugInfoPath); + DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp}; + eval_modules[eval_module_idx].arch = arch; + eval_modules[eval_module_idx].rdi = di_rdi_from_key(scope->di_scope, &dbgi_key, max_U64); + eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range; + eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity); + eval_modules[eval_module_idx].space.u64_0 = (U64)process; + if(mod == module) + { + eval_modules_primary = &eval_modules[eval_module_idx]; + } + eval_module_idx += 1; + } + } + } + } + + // rjf: build eval type context + { + E_TypeCtx *ctx = &scope->type_ctx; + ctx->ip_vaddr = thread_rip_vaddr; + ctx->ip_voff = thread_rip_voff; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + } + e_select_type_ctx(&scope->type_ctx); + + // rjf: build eval parse context + ProfScope("build eval parse context") + { + E_ParseCtx *ctx = &scope->parse_ctx; + ctx->ip_vaddr = thread_rip_vaddr; + ctx->ip_voff = thread_rip_voff; + ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); + ctx->ip_thread_space.u64_0 = (U64)thread; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + ctx->regs_map = ctrl_string2reg_from_arch(arch); + ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); + ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); + ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); + } + e_select_parse_ctx(&scope->parse_ctx); + + // rjf: build eval IR context + { + E_IRCtx *ctx = &scope->ir_ctx; + ctx->macro_map = push_array(arena, E_String2ExprMap, 1); + ctx->macro_map[0] = e_string2expr_map_make(arena, 512); + ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); + ctx->lookup_rule_map[0] = e_lookup_rule_map_make(arena, 512); + ctx->irgen_rule_map = push_array(arena, E_IRGenRuleMap, 1); + ctx->irgen_rule_map[0] = e_irgen_rule_map_make(arena, 512); + ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); + ctx->auto_hook_map[0] = e_auto_hook_map_make(arena, 512); + } + e_select_ir_ctx(&scope->ir_ctx); + + // rjf: build eval interpretation context + { + E_InterpretCtx *ctx = &scope->interpret_ctx; + ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; + ctx->space_read = ctrl_eval_space_read; + ctx->primary_space = eval_modules_primary->space; + ctx->reg_arch = eval_modules_primary->arch; + ctx->reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); + ctx->reg_space.u64_0 = (U64)thread; + ctx->module_base = push_array(arena, U64, 1); + ctx->module_base[0]= module->vaddr_range.min; + ctx->tls_base = push_array(arena, U64, 1); + } + e_select_interpret_ctx(&scope->interpret_ctx); + + return scope; +} + +internal void +ctrl_thread__eval_scope_end(CTRL_EvalScope *scope) +{ + di_scope_close(scope->di_scope); +} + //- rjf: log flusher internal void @@ -4828,25 +4942,30 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: gather all initial breakpoints // DMN_TrapChunkList user_traps = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; - machine != &ctrl_entity_nil; - machine = machine->next) { - if(machine->kind != CTRL_EntityKind_Machine) { continue; } - for(CTRL_Entity *process = machine->first; process != &ctrl_entity_nil; process = process->next) + CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, target_thread); + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + machine != &ctrl_entity_nil; + machine = machine->next) { - if(process->kind != CTRL_EntityKind_Process) { continue; } - - // rjf: resolve module-dependent user bps - for(CTRL_Entity *module = process->first; module != &ctrl_entity_nil; module = module->next) + if(machine->kind != CTRL_EntityKind_Machine) { continue; } + for(CTRL_Entity *process = machine->first; process != &ctrl_entity_nil; process = process->next) { - if(module->kind != CTRL_EntityKind_Module) { continue; } - ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, process->handle, module->handle, &msg->user_bps, &user_traps); + if(process->kind != CTRL_EntityKind_Process) { continue; } + + // rjf: resolve module-dependent user bps + for(CTRL_Entity *module = process->first; module != &ctrl_entity_nil; module = module->next) + { + if(module->kind != CTRL_EntityKind_Module) { continue; } + ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, process->handle, module->handle, &msg->user_bps, &user_traps); + } + + // rjf: push virtual-address user breakpoints per-process + ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, process->handle, &msg->user_bps, &user_traps); } - - // rjf: push virtual-address user breakpoints per-process - ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, process->handle, &msg->user_bps, &user_traps); } + ctrl_thread__eval_scope_end(eval_scope); } ////////////////////////////// @@ -5110,39 +5229,48 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) }break; case DMN_EventKind_CreateProcess: { - DMN_TrapChunkList new_traps = {0}; - ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, ctrl_handle_make(CTRL_MachineID_Local, event->process), &msg->user_bps, &new_traps); - log_infof("step_rule: create_process -> resolve traps\n"); - log_infof("new_traps:\n{\n"); - for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, &ctrl_entity_nil); { - for(U64 idx = 0; idx < n->count; idx += 1) + DMN_TrapChunkList new_traps = {0}; + ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, ctrl_handle_make(CTRL_MachineID_Local, event->process), &msg->user_bps, &new_traps); + log_infof("step_rule: create_process -> resolve traps\n"); + log_infof("new_traps:\n{\n"); + for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) { - DMN_Trap *trap = &n->v[idx]; - log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + for(U64 idx = 0; idx < n->count; idx += 1) + { + DMN_Trap *trap = &n->v[idx]; + log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + } } + log_infof("}\n\n"); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); } - log_infof("}\n\n"); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); + ctrl_thread__eval_scope_end(eval_scope); }break; case DMN_EventKind_LoadModule: { - DMN_TrapChunkList new_traps = {0}; - ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, ctrl_handle_make(CTRL_MachineID_Local, event->process), ctrl_handle_make(CTRL_MachineID_Local, event->module), &msg->user_bps, &new_traps); - log_infof("step_rule: load_module -> resolve traps\n"); - log_infof("new_traps:\n{\n"); - for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) + CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); { - for(U64 idx = 0; idx < n->count; idx += 1) + DMN_TrapChunkList new_traps = {0}; + ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, ctrl_handle_make(CTRL_MachineID_Local, event->process), ctrl_handle_make(CTRL_MachineID_Local, event->module), &msg->user_bps, &new_traps); + log_infof("step_rule: load_module -> resolve traps\n"); + log_infof("new_traps:\n{\n"); + for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next) { - DMN_Trap *trap = &n->v[idx]; - log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + for(U64 idx = 0; idx < n->count; idx += 1) + { + DMN_Trap *trap = &n->v[idx]; + log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr); + } } + log_infof("}\n\n"); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); } - log_infof("}\n\n"); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); - dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); + ctrl_thread__eval_scope_end(eval_scope); }break; } @@ -5463,107 +5591,9 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) // rjf: evaluate hit stop conditions if(conditions.node_count != 0) ProfScope("evaluate hit stop conditions") { - DI_Scope *di_scope = di_scope_open(); - - // rjf: gather evaluation modules - U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); - E_Module *eval_modules = push_array(temp.arena, E_Module, eval_modules_count); - E_Module *eval_modules_primary = &eval_modules[0]; - eval_modules_primary->rdi = &di_rdi_parsed_nil; - eval_modules_primary->vaddr_range = r1u64(0, max_U64); - { - U64 eval_module_idx = 0; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; - machine != &ctrl_entity_nil; - machine = machine->next) - { - if(machine->kind != CTRL_EntityKind_Machine) { continue; } - for(CTRL_Entity *process = machine->first; - process != &ctrl_entity_nil; - process = process->next) - { - if(process->kind != CTRL_EntityKind_Process) { continue; } - for(CTRL_Entity *mod = process->first; - mod != &ctrl_entity_nil; - mod = mod->next) - { - if(mod->kind != CTRL_EntityKind_Module) { continue; } - CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(mod, CTRL_EntityKind_DebugInfoPath); - DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp}; - eval_modules[eval_module_idx].arch = arch; - eval_modules[eval_module_idx].rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64); - eval_modules[eval_module_idx].vaddr_range = mod->vaddr_range; - eval_modules[eval_module_idx].space = e_space_make(CTRL_EvalSpaceKind_Entity); - eval_modules[eval_module_idx].space.u64_0 = (U64)process; - if(mod == module) - { - eval_modules_primary = &eval_modules[eval_module_idx]; - } - eval_module_idx += 1; - } - } - } - } - - // rjf: loop through all conditions, check all + CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(temp.arena, thread); for(String8Node *condition_n = conditions.first; condition_n != 0; condition_n = condition_n->next) { - // rjf: build eval type context - E_TypeCtx type_ctx = zero_struct; - { - E_TypeCtx *ctx = &type_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_type_ctx(&type_ctx); - - // rjf: build eval parse context - E_ParseCtx parse_ctx = zero_struct; - ProfScope("build eval parse context") - { - E_ParseCtx *ctx = &parse_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->ip_thread_space.u64_0 = (U64)thread; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - ctx->regs_map = ctrl_string2reg_from_arch(arch); - ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); - ctx->locals_map = e_push_locals_map_from_rdi_voff(temp.arena, eval_modules_primary->rdi, thread_rip_voff); - ctx->member_map = e_push_member_map_from_rdi_voff(temp.arena, eval_modules_primary->rdi, thread_rip_voff); - } - e_select_parse_ctx(&parse_ctx); - - // rjf: build eval IR context - E_IRCtx ir_ctx = zero_struct; - { - E_IRCtx *ctx = &ir_ctx; - ctx->macro_map = push_array(temp.arena, E_String2ExprMap, 1); - ctx->macro_map[0] = e_string2expr_map_make(temp.arena, 512); - } - e_select_ir_ctx(&ir_ctx); - - // rjf: build eval interpretation context - E_InterpretCtx interpret_ctx = zero_struct; - { - E_InterpretCtx *ctx = &interpret_ctx; - ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; - ctx->space_read = ctrl_eval_space_read; - ctx->primary_space = eval_modules_primary->space; - ctx->reg_arch = eval_modules_primary->arch; - ctx->reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->reg_space.u64_0 = (U64)thread; - ctx->module_base = push_array(temp.arena, U64, 1); - ctx->module_base[0]= module->vaddr_range.min; - ctx->tls_base = push_array(temp.arena, U64, 1); - } - e_select_interpret_ctx(&interpret_ctx); - // rjf: evaluate E_Eval eval = zero_struct; ProfScope("evaluate expression") @@ -5586,7 +5616,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) break; } } - di_scope_close(di_scope); + ctrl_thread__eval_scope_end(eval_scope); } // rjf: gather trap net hits diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index c21f5394..1102c178 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -263,8 +263,7 @@ typedef enum CTRL_UserBreakpointKind { CTRL_UserBreakpointKind_Null, CTRL_UserBreakpointKind_FileNameAndLineColNumber, - CTRL_UserBreakpointKind_SymbolNameAndOffset, - CTRL_UserBreakpointKind_VirtualAddress, + CTRL_UserBreakpointKind_Expression, CTRL_UserBreakpointKind_COUNT } CTRL_UserBreakpointKind; @@ -636,6 +635,19 @@ struct CTRL_DbgDirNode U64 module_direct_count; }; +//////////////////////////////// +//~ rjf: Control Thread Evaluation Scopes + +typedef struct CTRL_EvalScope CTRL_EvalScope; +struct CTRL_EvalScope +{ + DI_Scope *di_scope; + E_TypeCtx type_ctx; + E_ParseCtx parse_ctx; + E_IRCtx ir_ctx; + E_InterpretCtx interpret_ctx; +}; + //////////////////////////////// //~ rjf: Wakeup Hook Function Types @@ -933,8 +945,8 @@ internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena); internal void ctrl_thread__entry_point(void *p); //- rjf: breakpoint resolution -internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); -internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); //- rjf: module lifetime open/close work internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); @@ -946,6 +958,10 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ //- rjf: eval helpers internal B32 ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 vaddr_range); +//- rjf: control thread eval scopes +internal CTRL_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread); +internal void ctrl_thread__eval_scope_end(CTRL_EvalScope *scope); + //- rjf: log flusher internal void ctrl_thread__flush_info_log(String8 string); internal void ctrl_thread__end_and_flush_info_log(void); diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index a3f72a26..0c51c544 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -61,7 +61,7 @@ d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src) for(U64 idx = 0; idx < dst.count; idx += 1) { dst.v[idx].file_path = push_str8_copy(arena, dst.v[idx].file_path); - dst.v[idx].symbol_name = push_str8_copy(arena, dst.v[idx].symbol_name); + dst.v[idx].vaddr_expr = push_str8_copy(arena, dst.v[idx].vaddr_expr); dst.v[idx].condition = push_str8_copy(arena, dst.v[idx].condition); } return dst; @@ -1902,8 +1902,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P D_Breakpoint *bp = &breakpoints->v[idx]; str8_list_push(scratch.arena, &strings, bp->file_path); str8_list_push(scratch.arena, &strings, str8_struct(&bp->pt)); - str8_list_push(scratch.arena, &strings, bp->symbol_name); - str8_list_push(scratch.arena, &strings, str8_struct(&bp->vaddr)); + str8_list_push(scratch.arena, &strings, bp->vaddr_expr); str8_list_push(scratch.arena, &strings, bp->condition); } } @@ -2248,7 +2247,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } else if(params->vaddr != 0) { - run_extra_bps.v[0].vaddr = params->vaddr; + run_extra_bps.v[0].vaddr_expr = push_str8f(scratch.arena, "0x%I64x", params->vaddr); } d_cmd(D_CmdKind_Run); }break; @@ -2418,20 +2417,11 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } } - // rjf: virtual address location -> add breakpoint for address - else if(bp->vaddr != 0) + // rjf: virtual address expression -> add expression breakpoint + else if(bp->vaddr_expr.size != 0) { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_VirtualAddress}; - ctrl_user_bp.u64 = bp->vaddr; - ctrl_user_bp.condition = bp->condition; - ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); - } - - // rjf: symbol name location -> add breakpoint for symbol name - else if(bp->symbol_name.size != 0) - { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_SymbolNameAndOffset}; - ctrl_user_bp.string = bp->symbol_name; + CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression}; + ctrl_user_bp.string = bp->vaddr_expr; ctrl_user_bp.condition = bp->condition; ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); } diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 6ed68067..45a3caf8 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -33,8 +33,7 @@ struct D_Breakpoint { String8 file_path; TxtPt pt; - String8 symbol_name; - U64 vaddr; + String8 vaddr_expr; String8 condition; }; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 1bdd54e4..7e1a9599 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[293] = +RD_VocabInfo rd_vocab_info_table[295] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -14,6 +14,8 @@ RD_VocabInfo rd_vocab_info_table[293] = {str8_lit_comp("breakpoint"), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoint"), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled}, {str8_lit_comp("condition"), str8_lit_comp("conditions"), str8_lit_comp("Condition"), str8_lit_comp("Conditions"), RD_IconKind_Null}, {str8_lit_comp("location"), str8_lit_comp("locations"), str8_lit_comp("Location"), str8_lit_comp("Locations"), RD_IconKind_Null}, +{str8_lit_comp("source_location"), str8_lit_comp("source_locations"), str8_lit_comp("Source Location"), str8_lit_comp("Source Locations"), RD_IconKind_Null}, +{str8_lit_comp("address_location"), str8_lit_comp("address_locations"), str8_lit_comp("Address Location"), str8_lit_comp("Address Locations"), RD_IconKind_Null}, {str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, {str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, {str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, @@ -305,8 +307,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[12] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'location': location,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'location': location,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, @@ -528,8 +530,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 0ec59375..11182c9d 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -631,7 +631,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[293]; +extern RD_VocabInfo rd_vocab_info_table[295]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 38125746..d1365410 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -26,6 +26,8 @@ RD_VocabTable: {breakpoint _ "Breakpoint" _ CircleFilled } {condition _ "Condition" _ Null } {location _ "Location" _ Null } + {source_location _ "Source Location" _ Null } + {address_location _ "Address Location" _ Null } {target _ "Target" _ Target } {executable _ "Executable" _ Module } {arguments arguments "Arguments" "Arguments" Null } @@ -180,11 +182,12 @@ RD_VocabTable: @collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint) x: { - 'label': code_string, - 'condition': code_string, - 'location': location, - 'hit_count': u64, - 'disabled': bool, + 'label': code_string, + 'condition': code_string, + 'source_location': path_pt, + 'address_location': code_string, + 'hit_count': u64, + 'disabled': bool, } ```, } @@ -197,9 +200,10 @@ RD_VocabTable: @collection_commands(add_watch_pin) x: { - 'expression': code_string, - 'view_rule': code_string, - 'location': location, + 'expression': code_string, + 'view_rule': code_string, + 'source_location': path_pt, + 'address_location': code_string, } ```, } @@ -542,8 +546,8 @@ RD_CmdTable: // | | | | //- rjf: breakpoints {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } - {AddAddressBreakpoint 1 0 "" Vaddr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {AddFunctionBreakpoint 1 0 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } + {AddAddressBreakpoint 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {AddFunctionBreakpoint 1 0 "query:procedures" Expr symbol_lister Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c5a89a2f..235c58fc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1627,12 +1627,12 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 string) rd_cfg_insert_child(dst_active_parent_n, dst_active_parent_n->last, dst_n); } rec = md_node_rec_depth_first_pre(src_n, tln); + if(dst_active_parent_n == &rd_nil_cfg) + { + dst_root_n = dst_n; + } if(rec.push_count > 0) { - if(dst_active_parent_n == &rd_nil_cfg) - { - dst_root_n = dst_n; - } dst_active_parent_n = dst_n; } else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) @@ -2094,8 +2094,9 @@ rd_location_from_cfg(RD_Cfg *cfg) { RD_Location dst_loc = {0}; { - RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("location")); - if(src_loc->first != &rd_nil_cfg && src_loc->first->first != &rd_nil_cfg) + RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("source_location")); + RD_Cfg *addr_loc = rd_cfg_child_from_string(cfg, str8_lit("address_location")); + if(src_loc != &rd_nil_cfg) { dst_loc.file_path = src_loc->first->string; try_s64_from_str8_c_rules(src_loc->first->first->string, &dst_loc.pt.line); @@ -2104,19 +2105,9 @@ rd_location_from_cfg(RD_Cfg *cfg) dst_loc.pt.column = 1; } } - else + else if(addr_loc != &rd_nil_cfg) { - Temp scratch = scratch_begin(0, 0); - MD_TokenizeResult tokenize = md_tokenize_from_text(scratch.arena, src_loc->first->string); - if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) - { - dst_loc.name = src_loc->first->string; - } - else if(tokenize.tokens.count == 1 && tokenize.tokens.v[0].flags & MD_TokenFlag_Numeric) - { - try_u64_from_str8_c_rules(src_loc->first->string, &dst_loc.vaddr); - } - scratch_end(scratch); + dst_loc.expr = addr_loc->first->string; } } return dst_loc; @@ -2547,7 +2538,7 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) MD_Node *member_schema = md_child_from_string(schema, child_name, 0); String8 member_type_name = member_schema->first->string; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); - if(str8_match(member_type_name, str8_lit("location"), 0)) + if(str8_match(member_type_name, str8_lit("path_pt"), 0)) { 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))); @@ -5292,11 +5283,17 @@ rd_view_ui(Rng2F32 rect) } // rjf: can edit? -> begin editing - else if(cell_info.flags & RD_WatchCellFlag_CanEdit) + else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { rd_cmd(RD_CmdKind_Edit); } + // rjf: can expand? -> expand + else if(sig.f & UI_SignalFlag_KeyboardPressed && row_is_expandable) + { + next_row_expanded = !row_expanded; + } + // rjf: can't edit, but has address info? -> go to address else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) { @@ -11838,6 +11835,10 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) rd_regs()->cursor = pair.pt; } }break; + case RD_RegSlot_Expr: + { + rd_regs()->expr = push_str8_copy(rd_frame_arena(), string); + }break; case RD_RegSlot_Cursor: { U64 v = 0; @@ -13048,7 +13049,7 @@ rd_frame(void) E_TypeKey code_string_type_key = {0}; E_TypeKey path_type_key = {0}; E_TypeKey string_type_key = {0}; - E_TypeKey location_type_key = {0}; + E_TypeKey path_pt_type_key = {0}; { E_MemberList vaddr_range_members_list = {0}; e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); @@ -13060,7 +13061,7 @@ rd_frame(void) code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText); - location_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText|E_TypeFlag_IsCodeText|E_TypeFlag_IsPathText); + path_pt_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); } //- rjf: build types for each evallable meta name @@ -13077,7 +13078,7 @@ rd_frame(void) { str8_lit("code_string"), code_string_type_key }, { str8_lit("path"), path_type_key }, { str8_lit("string"), string_type_key }, - { str8_lit("location"), location_type_key }, + { str8_lit("path_pt"), path_pt_type_key }, }; E_TypeKey evallable_meta_types[ArrayCount(evallable_meta_names)] = {0}; for EachElement(idx, evallable_meta_names) @@ -15822,25 +15823,38 @@ Z(getting_started) case RD_CmdKind_RelocateCfg: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); - RD_Cfg *loc = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("location")); - for(RD_Cfg *child = loc->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + + // rjf: release old location info { - next = child->next; - rd_cfg_release(child); + RD_Cfg *src_loc = rd_cfg_child_from_string(cfg, str8_lit("source_location")); + RD_Cfg *addr_loc = rd_cfg_child_from_string(cfg, str8_lit("address_location")); + rd_cfg_release(src_loc); + rd_cfg_release(addr_loc); } - if(rd_regs()->cursor.line != 0) + + // rjf: attach new location info { - RD_Cfg *file = rd_cfg_new(loc, rd_regs()->file_path); - RD_Cfg *line = rd_cfg_newf(file, "%I64d", rd_regs()->cursor.line); - rd_cfg_newf(line, "%I64d", rd_regs()->cursor.column); - } - else if(rd_regs()->vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", rd_regs()->vaddr); - } - else if(rd_regs()->string.size != 0) - { - rd_cfg_new(loc, rd_regs()->string); + String8 file_path = rd_regs()->file_path; + TxtPt pt = rd_regs()->cursor; + String8 expr_string = rd_regs()->expr; + U64 vaddr = rd_regs()->vaddr; + if(expr_string.size == 0 && vaddr != 0) + { + expr_string = push_str8f(scratch.arena, "0x%I64x", vaddr); + } + if(file_path.size != 0 && pt.line != 0) + { + RD_Cfg *src_loc = rd_cfg_new(cfg, str8_lit("source_location")); + RD_Cfg *file = rd_cfg_new(src_loc, file_path); + RD_Cfg *line = rd_cfg_newf(file, "%I64d", pt.line); + RD_Cfg *col = rd_cfg_newf(line, "%I64d", pt.column); + (void)col; + } + else if(expr_string.size != 0) + { + RD_Cfg *vaddr_loc = rd_cfg_new(cfg, str8_lit("address_location")); + rd_cfg_new(vaddr_loc, expr_string); + } } }break; @@ -15850,9 +15864,13 @@ Z(getting_started) { String8 file_path = rd_regs()->file_path; TxtPt pt = rd_regs()->cursor; - String8 string = rd_regs()->string; U64 vaddr = rd_regs()->vaddr; - if(file_path.size != 0 || string.size != 0 || vaddr != 0) + String8 expr = rd_regs()->expr; + if(expr.size == 0 && vaddr != 0) + { + expr = push_str8f(scratch.arena, "0x%I64x", vaddr); + } + if(file_path.size != 0 || expr.size != 0) { B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleBreakpoint) @@ -15861,13 +15879,10 @@ Z(getting_started) for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { RD_Cfg *bp = n->v; - RD_Cfg *loc = rd_cfg_child_from_string(bp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_string = (string.size != 0 && str8_match(loc->first->string, string, 0)); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - if(loc_matches_file_pt || loc_matches_string || loc_matches_vaddr) + RD_Location loc = rd_location_from_cfg(bp); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_expr = (expr.size != 0 && str8_match(expr, loc.expr, 0)); + if(loc_matches_file_pt || loc_matches_expr) { rd_cfg_release(bp); removed_already_existing = 1; @@ -15879,30 +15894,14 @@ Z(getting_started) { RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); - RD_Cfg *loc = rd_cfg_new(bp, str8_lit("location")); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(string.size != 0) - { - rd_cfg_new(loc, string); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); - } + rd_cmd(RD_CmdKind_RelocateCfg, .cfg = bp->id); } } }break; case RD_CmdKind_AddAddressBreakpoint: - { - rd_cmd(RD_CmdKind_AddBreakpoint, .string = str8_zero()); - }break; case RD_CmdKind_AddFunctionBreakpoint: { - rd_cmd(RD_CmdKind_AddBreakpoint, .vaddr = 0); + rd_cmd(RD_CmdKind_AddBreakpoint); }break; //- rjf: watch pins @@ -15922,17 +15921,13 @@ Z(getting_started) { RD_Cfg *wp = n->v; RD_Cfg *expr = rd_cfg_child_from_string(wp, str8_lit("expression")); - RD_Cfg *loc = rd_cfg_child_from_string(wp, str8_lit("location")); - S64 loc_line = 0; - U64 loc_vaddr = 0; - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc->first->string, file_path) && try_s64_from_str8_c_rules(loc->first->first->string, &loc_line) && loc_line == pt.line); - B32 loc_matches_vaddr = (vaddr != 0 && try_u64_from_str8_c_rules(loc->first->string, &loc_vaddr) && loc_vaddr == vaddr); - B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr->first->string, expr_string, 0)); - if(loc_matches_expr && (loc_matches_file_pt || loc_matches_vaddr)) + RD_Location loc = rd_location_from_cfg(wp); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_expr = (expr_string.size != 0 && str8_match(expr_string, loc.expr, 0)); + if((loc_matches_file_pt || loc_matches_expr) && str8_match(expr->first->string, expr_string, 0)) { rd_cfg_release(wp); removed_already_existing = 1; - break; } } } @@ -15942,18 +15937,9 @@ Z(getting_started) RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule")); - RD_Cfg *loc = rd_cfg_new(wp, str8_lit("location")); rd_cfg_new(expr, expr_string); rd_cfg_new(view_rule, view_rule_string); - if(vaddr != 0) - { - rd_cfg_newf(loc, "0x%I64x", vaddr); - } - else if(file_path.size != 0) - { - RD_Cfg *file_path_cfg = rd_cfg_new(loc, file_path); - rd_cfg_newf(file_path_cfg, "%I64d", pt.line); - } + rd_cmd(RD_CmdKind_RelocateCfg, .cfg = wp->id); } }break; @@ -16790,8 +16776,7 @@ Z(getting_started) D_Breakpoint *dst_bp = &breakpoints.v[idx]; dst_bp->file_path = src_bp_loc.file_path; dst_bp->pt = src_bp_loc.pt; - dst_bp->symbol_name = src_bp_loc.name; - dst_bp->vaddr = src_bp_loc.vaddr; + dst_bp->vaddr_expr = src_bp_loc.expr; dst_bp->condition = non_ctrl_thread_static_condition; idx += 1; } @@ -16937,6 +16922,7 @@ Z(getting_started) try_u64_from_str8_c_rules(hit_count_root->first->string, &hit_count); RD_Location loc = rd_location_from_cfg(bp); D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc.file_path, loc.pt.line); + E_Value loc_value = e_value_from_string(loc.expr); if(loc_lines.first != 0) { for(D_LineNode *n = loc_lines.first; n != 0; n = n->next) @@ -16948,18 +16934,10 @@ Z(getting_started) } } } - else if(loc.vaddr != 0 && vaddr == loc.vaddr) + else if(loc_value.u64 != 0 && vaddr == loc_value.u64) { hit_count += 1; } - else if(loc.name.size != 0) - { - U64 symb_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, loc.name); - if(symb_voff == voff) - { - hit_count += 1; - } - } rd_cfg_new_replacef(hit_count_root, "%I64u", hit_count); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 644cd104..f87ff098 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -339,8 +339,7 @@ struct RD_Location { String8 file_path; TxtPt pt; - U64 vaddr; - String8 name; + String8 expr; }; //////////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index e14a5b0a..41ecf5e0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -319,9 +319,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { RD_Cfg *bp = n->v; RD_Location loc = rd_location_from_cfg(bp); - if(contains_1u64(dasm_vaddr_range, loc.vaddr)) + E_Value loc_value = e_value_from_string(loc.expr); + if(contains_1u64(dasm_vaddr_range, loc_value.u64)) { - U64 off = loc.vaddr - dasm_vaddr_range.min; + U64 off = loc_value.u64 - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) @@ -341,9 +342,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { RD_Cfg *wp = n->v; RD_Location loc = rd_location_from_cfg(wp); - if(contains_1u64(dasm_vaddr_range, loc.vaddr)) + E_Value loc_value = e_value_from_string(loc.expr); + if(contains_1u64(dasm_vaddr_range, loc_value.u64)) { - U64 off = loc.vaddr - dasm_vaddr_range.min; + U64 off = loc_value.u64 - dasm_vaddr_range.min; U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off); S64 line_num = (S64)idx+1; if(contains_1s64(visible_line_num_range, line_num)) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 3ccc4d96..7d2b0217 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -250,6 +250,18 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) start_secondary(); } + //- rjf: push address location + if(loc.expr.size != 0) + { + RD_Font(RD_FontSlot_Code) + { + DR_FStrList fstrs = rd_fstrs_from_code_string(arena, 1.f, 0, params.color, loc.expr); + dr_fstrs_concat_in_place(&result, &fstrs); + } + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + //- rjf: push target executable name if(target.exe.size != 0) { @@ -291,7 +303,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) { String8 hit_count_value_string = rd_cfg_child_from_string(cfg, str8_lit("hit_count"))->first->string; U64 hit_count = 0; - if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count)) + if(try_u64_from_str8_c_rules(hit_count_value_string, &hit_count) && hit_count != 0) { String8 hit_count_text = push_str8f(arena, "(%I64u hit%s)", hit_count, hit_count == 1 ? "" : "s"); dr_fstrs_push_new(arena, &result, ¶ms, hit_count_text); From 2f2bb0d7979c748d408b941dd3793dc2eb640ab7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 09:25:26 -0800 Subject: [PATCH 164/755] plug rebindings back in --- .../eval_visualization_core.c | 2 +- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 139 ++++++++---------- src/raddbg/raddbg_core.h | 15 +- src/raddbg/raddbg_views.c | 16 +- src/raddbg/raddbg_views.h | 2 +- src/raddbg/raddbg_widgets.c | 12 +- 7 files changed, 83 insertions(+), 105 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 9ab53f7a..39dc30ba 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -399,7 +399,7 @@ ev_expand_rule_from_string(String8 string) //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (dynamic type resolution) internal E_Expr * ev_resolved_from_expr(Arena *arena, E_Expr *expr) { diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index fceef439..57e24759 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -325,7 +325,7 @@ internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (dynamic type resolution) internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); #endif diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 235c58fc..ccc8cd90 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3984,7 +3984,7 @@ rd_view_ui(Rng2F32 rect) // rjf: loop through X selections and perform operations for each for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (multicursor watch window press operations) //- rjf: determine operation for this cell typedef enum OpKind { @@ -5186,7 +5186,7 @@ rd_view_ui(Rng2F32 rect) { ui_pop_background_color(); } -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (autocompletion) if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) @@ -5830,6 +5830,21 @@ rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) return fmt; } +internal E_Value +rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key) +{ + E_Value value = zero_struct; + for(E_Expr *arg = tag->first->next; arg != &e_expr_nil; arg = arg->next) + { + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + { + value = e_value_from_expr(arg->first->next); + break; + } + } + return value; +} + //- rjf: pushing/attaching view resources internal void * @@ -6847,7 +6862,7 @@ rd_window_frame(void) // case RD_RegSlot_View: { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (context menus) RD_Cfg *tab = rd_cfg_from_id(regs->view); RD_RegsScope(.view = regs->view) { @@ -10471,7 +10486,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St 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); -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (lister) ////////////////////////// //- rjf: determine all ctx filters @@ -10836,7 +10851,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St } //- rjf: gather view rule params -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (lister) if(flags & RD_ListerFlag_ViewRuleParams) { for(String8Node *n = strings.first; n != 0; n = n->next) @@ -10979,7 +10994,7 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St //- rjf: gather settings if(flags & RD_ListerFlag_Settings) { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (lister) String8List schema_strings = {0}; // rjf: push schema for view @@ -11112,7 +11127,7 @@ rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } -#if 0 // TODO(rjf): @cfg_lister +#if 0 // TODO(rjf): @cfg (lister) internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) @@ -12539,7 +12554,7 @@ rd_frame(void) if(os_key_press(&events, os_handle_zero(), 0, OS_Key_Delete)) { rd_request_frame(); - // TODO(rjf): @cfg_bindchange rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); + rd_cfg_release(rd_cfg_from_id(rd_state->bind_change_binding_id)); rd_state->bind_change_active = 0; } for(OS_Event *event = events.first, *next = 0; event != 0; event = next) @@ -12557,13 +12572,19 @@ rd_frame(void) event->key != OS_Key_Shift) { rd_state->bind_change_active = 0; - RD_Binding binding = zero_struct; + RD_Cfg *binding = rd_cfg_from_id(rd_state->bind_change_binding_id); + if(binding == &rd_nil_cfg) { - binding.key = event->key; - binding.modifiers = event->modifiers; + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *keybindings = rd_cfg_child_from_string_or_alloc(user, str8_lit("keybindings")); + binding = rd_cfg_new(keybindings, str8_lit("")); } - // TODO(rjf): @cfg_bindchange rd_unbind_name(rd_state->bind_change_cmd_name, rd_state->bind_change_binding); - // TODO(rjf): @cfg_bindchange rd_bind_name(rd_state->bind_change_cmd_name, binding); + rd_cfg_release_all_children(binding); + rd_cfg_new(binding, rd_state->bind_change_cmd_name); + rd_cfg_new(binding, os_g_key_cfg_string_table[event->key]); + if(event->modifiers & OS_Modifier_Ctrl) { rd_cfg_new(binding, str8_lit("ctrl")); } + if(event->modifiers & OS_Modifier_Shift) { rd_cfg_new(binding, str8_lit("shift")); } + if(event->modifiers & OS_Modifier_Alt) { rd_cfg_new(binding, str8_lit("alt")); } U32 codepoint = os_codepoint_from_modifiers_and_key(event->modifiers, event->key); os_text(&events, event->window, codepoint); os_eat_event(&events, event); @@ -12636,7 +12657,7 @@ rd_frame(void) U64 name_slot_idx = name_hash%key_map->name_slots_count; U64 binding_slot_idx = binding_hash%key_map->binding_slots_count; RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1); - n->cfg = keybinding; + n->cfg_id = keybinding->id; n->name = push_str8_copy(rd_frame_arena(), name); n->binding = binding; SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next); @@ -12644,39 +12665,6 @@ rd_frame(void) } } } - - //- rjf: iterate default bindings - if their commands are not found in the - // map, then use the default binding. - // - // TODO(rjf): @dynamic_cmds - // - for EachElement(idx, rd_default_binding_table) - { - String8 name = rd_default_binding_table[idx].string; - B32 name_was_mapped = 0; - U64 name_hash = d_hash_from_string(name); - U64 name_slot_idx = name_hash%key_map->name_slots_count; - for(RD_KeyMapNode *n = key_map->name_slots[name_slot_idx].first; n != 0; n = n->name_hash_next) - { - if(str8_match(n->name, name, 0)) - { - name_was_mapped = 1; - break; - } - } - if(!name_was_mapped) - { - RD_Binding binding = rd_default_binding_table[idx].binding; - U64 binding_hash = d_hash_from_string(str8_struct(&binding)); - U64 binding_slot_idx = binding_hash%key_map->binding_slots_count; - RD_KeyMapNode *n = push_array(rd_frame_arena(), RD_KeyMapNode, 1); - n->cfg = &rd_nil_cfg; - n->name = push_str8_copy(rd_frame_arena(), name); - n->binding = binding; - SLLQueuePush_N(key_map->name_slots[name_slot_idx].first, key_map->name_slots[name_slot_idx].last, n, name_hash_next); - SLLQueuePush_N(key_map->binding_slots[binding_slot_idx].first, key_map->binding_slots[binding_slot_idx].last, n, binding_hash_next); - } - } } ////////////////////////////// @@ -13539,7 +13527,7 @@ rd_frame(void) } // rjf: try to open tabs for "view driver" commands -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (tab opening) RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(cmd->name); if(view_rule_info != &rd_nil_view_rule_info) { @@ -13783,6 +13771,27 @@ rd_frame(void) } } + //- rjf: if config did not define any keybindings for the user, then we need to build a sensible default + if(file_is_okay && kind == RD_CmdKind_OpenUser) + { + RD_CfgList all_keybindings = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("keybindings")); + if(all_keybindings.count == 0) + { + RD_Cfg *keybindings = rd_cfg_new(file_root, str8_lit("keybindings")); + for EachElement(idx, rd_default_binding_table) + { + String8 name = rd_default_binding_table[idx].string; + RD_Binding binding = rd_default_binding_table[idx].binding; + RD_Cfg *binding_root = rd_cfg_new(keybindings, str8_zero()); + rd_cfg_new(binding_root, name); + rd_cfg_new(binding_root, os_g_key_cfg_string_table[binding.key]); + if(binding.modifiers & OS_Modifier_Ctrl) {rd_cfg_newf(binding_root, "ctrl");} + if(binding.modifiers & OS_Modifier_Shift) {rd_cfg_newf(binding_root, "shift");} + if(binding.modifiers & OS_Modifier_Alt) {rd_cfg_newf(binding_root, "alt");} + } + } + } + //- rjf: record recently-opened projects in the user if(file_is_okay && kind == RD_CmdKind_OpenProject) { @@ -14539,7 +14548,7 @@ rd_frame(void) }break; case RD_CmdKind_OpenTab: { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (tab opening) RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_alloc(); String8 query = rd_regs()->string; @@ -14626,7 +14635,7 @@ rd_frame(void) if(props.created != 0) { rd_cmd(RD_CmdKind_RecordFileInProject); -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (opening file) rd_cmd(RD_CmdKind_OpenTab, .string = rd_eval_string_from_file_path(scratch.arena, path), .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); @@ -14639,7 +14648,7 @@ rd_frame(void) }break; case RD_CmdKind_Switch: { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (opening recent files) RD_Window *ws = rd_window_from_handle(rd_regs()->window); RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); RD_View *src_view = rd_view_from_handle(rd_regs()->view); @@ -14686,7 +14695,7 @@ rd_frame(void) }break; case RD_CmdKind_SwitchToPartnerFile: { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (opening partner files) RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_selected_tab_from_panel(panel); { @@ -15623,28 +15632,6 @@ Z(getting_started) } }break; - //- rjf: search operations -#if 0 // TODO(rjf): @cfg - case RD_CmdKind_ClearFilter: - { - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) - { - view->query_string_size = 0; - view->is_filtering = 0; - view->query_cursor = view->query_mark = txt_pt(1, 1); - } - }break; - case RD_CmdKind_ApplyFilter: - { - RD_View *view = rd_view_from_handle(rd_regs()->view); - if(!rd_view_is_nil(view)) - { - view->is_filtering = 0; - } - }break; -#endif - //- rjf: queries case RD_CmdKind_PushQuery: { @@ -15686,7 +15673,7 @@ Z(getting_started) }break; case RD_CmdKind_CompleteQuery: { -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (query completion) RD_Window *ws = rd_window_from_handle(rd_regs()->window); String8 query_cmd_name = ws->query_cmd_name; RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(query_cmd_name); @@ -15939,7 +15926,7 @@ Z(getting_started) RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule")); rd_cfg_new(expr, expr_string); rd_cfg_new(view_rule, view_rule_string); - rd_cmd(RD_CmdKind_RelocateCfg, .cfg = wp->id); + rd_cmd(RD_CmdKind_RelocateCfg, .cfg = wp->id, .expr = str8_zero()); } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index f87ff098..1393ea01 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -39,7 +39,7 @@ struct RD_KeyMapNode { RD_KeyMapNode *name_hash_next; RD_KeyMapNode *binding_hash_next; - struct RD_Cfg *cfg; + RD_CfgID cfg_id; String8 name; RD_Binding binding; }; @@ -840,19 +840,11 @@ struct RD_State RD_ViewStateSlot *view_state_slots; RD_ViewState *free_view_state; - //- - // TODO(rjf): TO BE ELIMINATED OR REPLACED VVVVVVVVVVVVVVVV - //- - // rjf: bind change Arena *bind_change_arena; B32 bind_change_active; + RD_CfgID bind_change_binding_id; String8 bind_change_cmd_name; - RD_Binding bind_change_binding; - - //- - // TODO(rjf): TO BE ELIMINATED OR REPLACED ^^^^^^^^^^^^^^^^^^ - //- }; //////////////////////////////// @@ -1094,6 +1086,7 @@ internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag); internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag); internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag); internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag); +internal E_Value rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); @@ -1143,7 +1136,7 @@ internal U64 rd_hash_from_lister_item(RD_ListerItem *item); internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); -#if 0 // TODO(rjf): @cfg +#if 0 // TODO(rjf): @cfg (lister) internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); #define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 41ecf5e0..77b3b3bf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -451,7 +451,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->center_cursor = found; if(found == 0) { - log_user_errorf("Could not find \"%S\"", cv->find_text_fwd); + log_user_errorf("Could not find `%S`", cv->find_text_fwd); } } @@ -507,7 +507,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->center_cursor = found; if(found == 0) { - log_user_errorf("Could not find \"%S\"", cv->find_text_bwd); + log_user_errorf("Could not find `%S`", cv->find_text_bwd); } } @@ -3340,12 +3340,12 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("count")).u64; - U64 vtx_base_off = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("vtx")).u64; - U64 vtx_size = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("vtx_size")).u64; - F32 yaw_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("yaw")).f32; - F32 pitch_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("pitch")).f32; - F32 zoom_target = 0; // TODO(rjf): @cfg rd_value_from_params_key(params, str8_lit("zoom")).f32; + U64 count = rd_value_from_eval_tag_key(eval, tag, str8_lit("count")).u64; + U64 vtx_base_off = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx")).u64; + U64 vtx_size = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx_size")).u64; + F32 yaw_target = rd_view_cfg_value_from_string(str8_lit("yaw")).f32; + F32 pitch_target = rd_view_cfg_value_from_string(str8_lit("pitch")).f32; + F32 zoom_target = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; ////////////////////////////// //- rjf: evaluate & unpack expression diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 224c320d..da9c8420 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -235,7 +235,7 @@ internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_Wat //////////////////////////////// //~ rjf: View Hooks -// TODO(rjf): @cfg eliminate once we are predeclaring these with metacode +// TODO(rjf): eliminate once we are predeclaring these with metacode RD_VIEW_UI_FUNCTION_DEF(null); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 7d2b0217..ca23b41b 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -672,8 +672,7 @@ rd_cmd_binding_buttons(String8 name) RD_Binding binding = n->v->binding; B32 rebinding_active_for_this_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding.key == binding.key && - rd_state->bind_change_binding.modifiers == binding.modifiers); + n->v->cfg_id == rd_state->bind_change_binding_id); //- rjf: grab all conflicts B32 has_conflicts = 0; @@ -736,7 +735,7 @@ rd_cmd_binding_buttons(String8 name) arena_clear(rd_state->bind_change_arena); rd_state->bind_change_active = 1; rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); - rd_state->bind_change_binding = binding; + rd_state->bind_change_binding_id = n->v->cfg_id; } } else if(rd_state->bind_change_active && ui_clicked(sig)) @@ -768,7 +767,7 @@ rd_cmd_binding_buttons(String8 name) UI_Signal sig = rd_icon_button(RD_IconKind_X, 0, str8_lit("###delete_binding")); if(ui_clicked(sig)) { - // TODO(rjf): @cfg rd_unbind_name(name, binding); + rd_cfg_release(rd_cfg_from_id(rd_state->bind_change_binding_id)); rd_state->bind_change_active = 0; } } @@ -780,8 +779,7 @@ rd_cmd_binding_buttons(String8 name) //- rjf: build "add new binding" button B32 adding_new_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding.key == OS_Key_Null && - rd_state->bind_change_binding.modifiers == 0); + rd_state->bind_change_binding_id == 0); RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") { ui_set_next_hover_cursor(OS_Cursor_HandPoint); @@ -803,7 +801,7 @@ rd_cmd_binding_buttons(String8 name) arena_clear(rd_state->bind_change_arena); rd_state->bind_change_active = 1; rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); - MemoryZeroStruct(&rd_state->bind_change_binding); + rd_state->bind_change_binding_id = 0; } else if(rd_state->bind_change_active && ui_clicked(sig)) { From 4f1e0dedb220feabcd678749532bb89508aac26e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 09:52:50 -0800 Subject: [PATCH 165/755] start plugging tab-opening back in --- src/raddbg/raddbg_core.c | 30 ++++++++++++++++++++++-------- src/raddbg/raddbg_core.h | 2 ++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ccc8cd90..50c97f35 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3312,8 +3312,8 @@ rd_view_state_from_cfg(RD_Cfg *cfg) DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_id = id; view_state->arena = arena_alloc(); + view_state->arena_reset_pos = arena_pos(view_state->arena); view_state->ev_view = ev_view_alloc(); - view_state->loading_t = 1.f; view_state->search_arena = arena_alloc(); } if(view_state != &rd_nil_view_state) @@ -3626,7 +3626,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: if we don't have a viewer, just use the memory viewer. - if(new_view_name.size != 0) + if(new_view_name.size == 0) { new_view_name = str8_lit("memory"); } @@ -3645,6 +3645,14 @@ rd_view_ui(Rng2F32 rect) } RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); rd_cfg_equip_string(view, new_view_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + for(RD_ArenaExt *ext = vs->first_arena_ext; ext != 0; ext = ext->next) + { + arena_release(ext->arena); + } + arena_pop_to(vs->arena, vs->arena_reset_pos); + vs->user_data = 0; + vs->first_arena_ext = vs->last_arena_ext = 0; } // rjf: if we don't have a viewer, for whatever reason, then just @@ -5569,6 +5577,7 @@ rd_view_ui(Rng2F32 rect) } } + vs->last_frame_index_built = rd_state->frame_index; ProfEnd(); } @@ -5896,6 +5905,10 @@ rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_ta view_state->loading_t_target = (F32)!!is_loading; view_state->loading_progress_v = progress_u64; view_state->loading_progress_v_target = progress_u64_target; + if(view_state->last_frame_index_built+1 < rd_state->frame_index) + { + view_state->loading_t = view_state->loading_t_target; + } } internal void @@ -8931,7 +8944,7 @@ rd_window_frame(void) // if(build_panel) { - F32 selected_tab_loading_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###is_view_loading_%p", selected_tab), selected_tab_view_state->loading_t_target, .initial = selected_tab_view_state->loading_t_target); + F32 selected_tab_loading_t = selected_tab_view_state->loading_t; if(selected_tab_loading_t > 0.01f) UI_Parent(loading_overlay_container) { rd_loading_overlay(panel_rect, selected_tab_loading_t, selected_tab_view_state->loading_progress_v, selected_tab_view_state->loading_progress_v_target); @@ -14548,6 +14561,11 @@ rd_frame(void) }break; case RD_CmdKind_OpenTab: { + RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); + RD_Cfg *tab = rd_cfg_new(panel, rd_regs()->string); + RD_Cfg *expr = rd_cfg_new(tab, str8_lit("expression")); + rd_cfg_new(expr, rd_regs()->expr); + rd_cmd(RD_CmdKind_FocusTab, .view = tab->id); #if 0 // TODO(rjf): @cfg (tab opening) RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); RD_View *view = rd_view_alloc(); @@ -14635,11 +14653,7 @@ rd_frame(void) if(props.created != 0) { rd_cmd(RD_CmdKind_RecordFileInProject); -#if 0 // TODO(rjf): @cfg (opening file) - rd_cmd(RD_CmdKind_OpenTab, - .string = rd_eval_string_from_file_path(scratch.arena, path), - .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); -#endif + rd_cmd(RD_CmdKind_OpenTab, .string = str8_lit("pending"), .expr = rd_eval_string_from_file_path(scratch.arena, path)); } else { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 1393ea01..182e08be 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -214,6 +214,7 @@ struct RD_ViewState // rjf: touch info U64 last_frame_index_touched; + U64 last_frame_index_built; // rjf: loading indicator info F32 loading_t; @@ -229,6 +230,7 @@ struct RD_ViewState // rjf: view-lifetime allocation & user data extensions Arena *arena; + U64 arena_reset_pos; RD_ArenaExt *first_arena_ext; RD_ArenaExt *last_arena_ext; void *user_data; From 9e0fe942e6d966253b11559815c291c2cdf1d636 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 10:20:11 -0800 Subject: [PATCH 166/755] allow base/opl style slices in slice view rule --- src/eval/eval_ir.c | 28 +++++++++++++++++++++++ src/raddbg/raddbg_core.c | 48 ++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index a7328d80..72198bec 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -376,6 +376,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) // rjf: choose base pointer & count members E_Member *base_ptr_member = 0; + E_Member *opl_ptr_member = 0; E_Member *count_member = 0; for(U64 idx = 0; idx < members.count; idx += 1) { @@ -390,10 +391,18 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) { base_ptr_member = &members.v[idx]; } + if(opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + opl_ptr_member = &members.v[idx]; + } if(count_member != 0 && base_ptr_member != 0) { break; } + else if(base_ptr_member != 0 && opl_ptr_member != 0) + { + break; + } } // rjf: determine architecture @@ -422,6 +431,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) base_ptr_vaddr = base_ptr_member_value.u64; } + // rjf: evaluate opl ptr member, determine opl address + U64 opl_ptr_vaddr = 0; + if(count_member == 0 && opl_ptr_member != 0) + { + E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, opl_ptr_member->name); + E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr); + opl_ptr_vaddr = opl_ptr_member_value.u64; + } + // rjf: determine element type E_TypeKey element_type_key = zero_struct; if(base_ptr_member != 0) @@ -429,6 +447,16 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) element_type_key = e_type_direct_from_key(base_ptr_member->type_key); } + // rjf: if no count, but base/opl, swap base/opl if needed, and measure count + if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0) + { + U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr); + U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr); + base_ptr_vaddr = min_vaddr; + opl_ptr_vaddr = max_vaddr; + count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key); + } + // rjf: fill if(count_member && base_ptr_member) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 50c97f35..5d899a55 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5554,8 +5554,6 @@ rd_view_ui(Rng2F32 rect) // if(vs->is_searching) UI_Focus(UI_FocusKind_On) { - String8 cmd_name = vs->search_cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { vs->is_searching = 0; @@ -5563,17 +5561,7 @@ rd_view_ui(Rng2F32 rect) } if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { - RD_RegsScope() - { - rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); - rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); - rd_push_cmd(cmd_name, rd_regs()); - } - if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) - { - vs->is_searching = 0; - vs->search_string_size = 0; - } + rd_cmd(RD_CmdKind_CompleteQuery); } } @@ -7139,19 +7127,19 @@ rd_window_frame(void) if(query_is_open) { //- rjf: unpack query parameters - RD_Cfg *query = rd_immediate_cfg_from_keyf("window_query_%p", window); String8 cmd_name = ws->query_cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); + + //- rjf: build & prepare view for query ui + RD_Cfg *query = rd_immediate_cfg_from_keyf("window_query_%p", window); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(query, str8_lit("watch")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(view, str8_lit("cmd")); - rd_cfg_new_replace(cmd, cmd_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); RD_ViewState *vs = rd_view_state_from_cfg(view); vs->is_searching = 1; arena_clear(vs->search_arena); - vs->search_cmd_name = push_str8_copy(vs->search_arena, ws->query_cmd_name); + vs->search_cmd_name = push_str8_copy(vs->search_arena, cmd_name); vs->search_regs = rd_regs_copy(vs->search_arena, ws->query_regs); String8 query_expression = cmd_kind_info->query.expr; if(query_expression.size == 0) @@ -15687,6 +15675,28 @@ Z(getting_started) }break; case RD_CmdKind_CompleteQuery: { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + String8 cmd_name = vs->search_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_RegsScope() + { + rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); + rd_push_cmd(cmd_name, rd_regs()); + } + if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) + { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + ws->query_is_active = 0; + } + else if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) + { + vs->is_searching = 0; + vs->search_string_size = 0; + } + #if 0 // TODO(rjf): @cfg (query completion) RD_Window *ws = rd_window_from_handle(rd_regs()->window); String8 query_cmd_name = ws->query_cmd_name; @@ -16046,7 +16056,7 @@ Z(getting_started) RD_Cfg *wdir = rd_cfg_new(target, str8_lit("working_directory")); rd_cfg_newf(wdir, "%S/", working_directory); } - rd_cmd(RD_CmdKind_SelectCfg, .cfg = target->id); + rd_cmd(RD_CmdKind_SelectTarget, .cfg = target->id); }break; //- rjf: jit-debugger registration From 4f99a76acea8ce8a929960d5e88468fd4642deca Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 10:57:32 -0800 Subject: [PATCH 167/755] commit window placement/etc. to cfg tree, pass through all monitor/pos/size/fullscreen/maximize info to initialization --- src/os/gfx/linux/os_gfx_linux.c | 4 +- src/os/gfx/os_gfx.h | 5 +- src/os/gfx/stub/os_gfx_stub.c | 2 +- src/os/gfx/win32/os_gfx_win32.c | 12 ++-- src/raddbg/raddbg_core.c | 103 +++++++++++++++++++++++++++++++- 5 files changed, 116 insertions(+), 10 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index b2b08312..be83091f 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -71,8 +71,10 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { + Vec2F32 resolution = dim_2f32(rect); + //- rjf: allocate window OS_LNX_Window *w = os_lnx_gfx_state->free_window; if(w) diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index c0ddb4ea..9c50c5d3 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -21,7 +21,8 @@ struct OS_GfxInfo typedef U32 OS_WindowFlags; enum { - OS_WindowFlag_CustomBorder = (1<<0), + OS_WindowFlag_CustomBorder = (1<<0), + OS_WindowFlag_UseDefaultPosition = (1<<1), }; //////////////////////////////// @@ -139,7 +140,7 @@ internal String8 os_get_clipboard_text(Arena *arena); //////////////////////////////// //~ rjf: @os_hooks Windows (Implemented Per-OS) -internal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title); +internal OS_Handle os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title); internal void os_window_close(OS_Handle window); internal void os_window_first_paint(OS_Handle window); internal void os_window_focus(OS_Handle window); diff --git a/src/os/gfx/stub/os_gfx_stub.c b/src/os/gfx/stub/os_gfx_stub.c index fc481446..66b3f898 100644 --- a/src/os/gfx/stub/os_gfx_stub.c +++ b/src/os/gfx/stub/os_gfx_stub.c @@ -34,7 +34,7 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { OS_Handle handle = {1}; return handle; diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index fdcac746..4e8daab1 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -1015,9 +1015,12 @@ os_get_clipboard_text(Arena *arena) //~ rjf: @os_hooks Windows (Implemented Per-OS) internal OS_Handle -os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) +os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) { B32 custom_border = !!(flags & OS_WindowFlag_CustomBorder); + B32 use_default_position = !!(flags & OS_WindowFlag_UseDefaultPosition); + Vec2F32 pos = rect.p0; + Vec2F32 dim = dim_2f32(rect); //- rjf: make hwnd HWND hwnd = 0; @@ -1029,9 +1032,10 @@ os_window_open(Vec2F32 resolution, OS_WindowFlags flags, String8 title) L"graphical-window", (WCHAR*)title16.str, WS_OVERLAPPEDWINDOW | WS_SIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, - (int)resolution.x, - (int)resolution.y, + use_default_position ? CW_USEDEFAULT : (S32)pos.x, + use_default_position ? CW_USEDEFAULT : (S32)pos.y, + (S32)dim.x, + (S32)dim.y, 0, 0, os_w32_gfx_state->hInstance, 0); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5d899a55..2c5282c1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5972,11 +5972,17 @@ rd_window_state_from_cfg(RD_Cfg *cfg) Temp scratch = scratch_begin(0, 0); // rjf: unpack configuration options + B32 has_pos = 0; + Vec2F32 pos = {0}; Vec2F32 size = {0}; OS_Handle preferred_monitor = {0}; { + RD_Cfg *pos_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("pos")); + has_pos = (pos_cfg != &rd_nil_cfg); RD_Cfg *size_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("size")); RD_Cfg *monitor_cfg = rd_cfg_child_from_string(window_cfg, str8_lit("monitor")); + pos.x = (F32)f64_from_str8(pos_cfg->first->string); + pos.y = (F32)f64_from_str8(pos_cfg->first->next->string); size.x = (F32)f64_from_str8(size_cfg->first->string); size.y = (F32)f64_from_str8(size_cfg->first->next->string); OS_HandleArray monitors = os_push_monitors_array(scratch.arena); @@ -6008,7 +6014,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->arena = arena_alloc(); { String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); - ws->os = os_window_open(size, OS_WindowFlag_CustomBorder, title); + ws->os = os_window_open(r2f32p(pos.x, pos.y, pos.x+size.x, pos.y+size.y), (!has_pos*OS_WindowFlag_UseDefaultPosition)|OS_WindowFlag_CustomBorder, title); } ws->r = r_window_equip(ws->os); ws->ui = ui_state_alloc(); @@ -6264,6 +6270,94 @@ rd_window_frame(void) } } + ////////////////////////////// + //- rjf: commit window's position/status to underlying cfg tree + // + { + Temp scratch = scratch_begin(0, 0); + B32 is_fullscreen = os_window_is_fullscreen(ws->os); + B32 is_maximized = os_window_is_maximized(ws->os); + if(is_fullscreen) + { + rd_cfg_child_from_string_or_alloc(window, str8_lit("fullscreen")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("fullscreen"))); + } + if(is_maximized) + { + rd_cfg_child_from_string_or_alloc(window, str8_lit("maximized")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("maximized"))); + } + + //- rjf: commit position + Rng2F32 window_rect = os_rect_from_window(ws->os); + if(!is_fullscreen && !is_maximized) + { + Vec2F32 pos = window_rect.p0; + RD_Cfg *pos_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("pos")); + if((S32)pos.x != (S32)f64_from_str8(pos_root->first->string) || + (S32)pos.y != (S32)f64_from_str8(pos_root->last->string)) + { + RD_Cfg *x = pos_root->first; + if(x == &rd_nil_cfg) + { + x= rd_cfg_alloc(); + rd_cfg_insert_child(pos_root, &rd_nil_cfg, x); + } + RD_Cfg *y = x->next; + if(y == &rd_nil_cfg) + { + y = rd_cfg_alloc(); + rd_cfg_insert_child(pos_root, x, y); + } + rd_cfg_equip_stringf(x, "%i", (S32)pos.x); + rd_cfg_equip_stringf(y, "%i", (S32)pos.y); + } + } + + //- rjf: commit size + if(!is_fullscreen && !is_maximized) + { + Vec2F32 size = dim_2f32(window_rect); + RD_Cfg *size_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("size")); + if((S32)size.x != (S32)f64_from_str8(size_root->first->string) || + (S32)size.y != (S32)f64_from_str8(size_root->last->string)) + { + RD_Cfg *width = size_root->first; + if(width == &rd_nil_cfg) + { + width = rd_cfg_alloc(); + rd_cfg_insert_child(size_root, &rd_nil_cfg, width); + } + RD_Cfg *height = width->next; + if(height == &rd_nil_cfg) + { + height = rd_cfg_alloc(); + rd_cfg_insert_child(size_root, width, height); + } + rd_cfg_equip_stringf(width, "%i", (S32)size.x); + rd_cfg_equip_stringf(height, "%i", (S32)size.y); + } + } + + //- rjf: commit monitor + { + OS_Handle monitor = os_monitor_from_window(ws->os); + String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); + RD_Cfg *monitor_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("monitor")); + if(!str8_match(monitor_root->first->string, monitor_name, 0)) + { + rd_cfg_new_replace(monitor_root, monitor_name); + } + } + scratch_end(scratch); + } + ////////////////////////////// //- rjf: fill panel/view interaction registers // @@ -13616,7 +13710,11 @@ rd_frame(void) for(RD_Cfg *old_child = old_window->first; old_child != &rd_nil_cfg; old_child = old_child->next) { if(!str8_match(old_child->string, str8_lit("panels"), 0) && - !str8_match(old_child->string, str8_lit("size"), 0)) + !str8_match(old_child->string, str8_lit("size"), 0) && + !str8_match(old_child->string, str8_lit("pos"), 0) && + !str8_match(old_child->string, str8_lit("monitor"), 0) && + !str8_match(old_child->string, str8_lit("fullscreen"), 0) && + !str8_match(old_child->string, str8_lit("maximized"), 0)) { RD_Cfg *new_child = rd_cfg_deep_copy(old_child); rd_cfg_insert_child(new_window, new_window->last, new_child); @@ -16048,6 +16146,7 @@ Z(getting_started) String8 file_path = rd_regs()->file_path; RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); + rd_cfg_new(target, str8_lit("disabled")); RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); rd_cfg_new(exe, file_path); String8 working_directory = str8_chop_last_slash(file_path); From 96fbcc848ebd12551d8eb6d574b5cdfdae14b6d0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 11:30:45 -0800 Subject: [PATCH 168/755] double clicking cfgs with location info -> snap --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 36 ++++++++++++++++++++++++++++-- src/raddbg/raddbg_views.c | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7e1a9599..b75bd92f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -307,7 +307,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[12] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d1365410..f65064dc 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -179,7 +179,7 @@ RD_VocabTable: breakpoint, ``` @commands(enable_cfg, remove_cfg) - @collection_commands(add_breakpoint, add_address_breakpoint, add_function_breakpoint) + @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint) x: { 'label': code_string, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2c5282c1..e15da07a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5247,7 +5247,10 @@ rd_view_ui(Rng2F32 rect) case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; } } - else + else if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || + row_info->eval.space.kind == E_SpaceKind_FileSystem || + row_info->eval.space.kind == E_SpaceKind_File || + row_info->eval.space.kind == E_SpaceKind_Null) { RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row_info->eval.exprs.last), .view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key)) @@ -5328,6 +5331,22 @@ rd_view_ui(Rng2F32 rect) } } } + + // rjf: can't edit, but has cfg location info? -> find + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(cell_info.eval.space); + RD_Location loc = rd_location_from_cfg(cfg); + if(loc.file_path.size != 0) + { + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = 0, .file_path = loc.file_path, .cursor = loc.pt); + } + else if(loc.expr.size != 0) + { + U64 value = e_value_from_string(loc.expr).u64; + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); + } + } } // rjf: hovering with inheritance string -> show tooltip @@ -8972,7 +8991,14 @@ rd_window_frame(void) { String8 view_expr = rd_expr_from_cfg(selected_tab); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - rd_regs()->file_path = view_file_path; + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } } //- rjf: build view container @@ -14647,10 +14673,16 @@ rd_frame(void) }break; case RD_CmdKind_OpenTab: { + String8 expr_file_path = rd_file_path_from_eval_string(scratch.arena, rd_regs()->expr); RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); RD_Cfg *tab = rd_cfg_new(panel, rd_regs()->string); RD_Cfg *expr = rd_cfg_new(tab, str8_lit("expression")); rd_cfg_new(expr, rd_regs()->expr); + if(expr_file_path.size != 0) + { + RD_Cfg *project = rd_cfg_new(tab, str8_lit("project")); + rd_cfg_new(project, rd_state->project_path); + } rd_cmd(RD_CmdKind_FocusTab, .view = tab->id); #if 0 // TODO(rjf): @cfg (tab opening) RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 77b3b3bf..a998c148 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1607,6 +1607,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) //- rjf: unpack parameterization info // ProfBegin("unpack parameterization info"); + rd_regs()->file_path = rd_file_path_from_eval(rd_frame_arena(), eval); rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; rd_regs()->cursor.line = rd_view_cfg_value_from_string(str8_lit("cursor_line")).s64; From b0486d942e07fc96936a872215623bee198f664b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 11:46:28 -0800 Subject: [PATCH 169/755] correctly pipe through exception info, visualize exceptions better --- src/ctrl/ctrl_core.c | 17 +++++++++++++++++ src/ctrl/ctrl_core.h | 1 + src/raddbg/raddbg_core.c | 31 +++++++++++++++---------------- src/raddbg/raddbg_widgets.c | 6 +++--- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ff10a7d6..f0cb14d2 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -43,6 +43,21 @@ ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind) return cause; } +internal CTRL_ExceptionKind +ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind) +{ + CTRL_ExceptionKind result = CTRL_ExceptionKind_Null; + switch(kind) + { + default:{}break; + case DMN_ExceptionKind_MemoryRead: {result = CTRL_ExceptionKind_MemoryRead;}break; + case DMN_ExceptionKind_MemoryWrite: {result = CTRL_ExceptionKind_MemoryWrite;}break; + case DMN_ExceptionKind_MemoryExecute: {result = CTRL_ExceptionKind_MemoryExecute;}break; + case DMN_ExceptionKind_CppThrow: {result = CTRL_ExceptionKind_CppThrow;}break; + } + return result; +} + internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind) { @@ -5924,6 +5939,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->entity = ctrl_handle_make(CTRL_MachineID_Local, stop_event->thread); event->parent = ctrl_handle_make(CTRL_MachineID_Local, stop_event->process); event->exception_code = stop_event->code; + event->exception_kind = ctrl_exception_kind_from_dmn(stop_event->exception_kind); event->vaddr_rng = r1u64(stop_event->address, stop_event->address); event->rip_vaddr = stop_event->instruction_pointer; ctrl_c2u_push_events(&evts); @@ -5998,6 +6014,7 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->entity = ctrl_handle_make(CTRL_MachineID_Local, stop_event->thread); event->parent = ctrl_handle_make(CTRL_MachineID_Local, stop_event->process); event->exception_code = stop_event->code; + event->exception_kind = ctrl_exception_kind_from_dmn(stop_event->exception_kind); event->vaddr_rng = r1u64(stop_event->address, stop_event->address); event->rip_vaddr = stop_event->instruction_pointer; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 1102c178..92541b1c 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -738,6 +738,7 @@ read_only global CTRL_Entity ctrl_entity_nil = internal U64 ctrl_hash_from_string(String8 string); internal U64 ctrl_hash_from_handle(CTRL_Handle handle); internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind); +internal CTRL_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind); internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e15da07a..cce6a98b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11758,13 +11758,14 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) if(thread != &ctrl_entity_nil) { dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); switch(event->exception_kind) { default: { - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -11776,37 +11777,35 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) }break; case CTRL_ExceptionKind_CppThrow: { - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a C++ exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit a C++ exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_code_string); }break; case CTRL_ExceptionKind_MemoryRead: { - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); - String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation reading 0x%I64x)", exception_code_string, event->vaddr_rng.min); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); + String8 exception_info_string = push_str8f(arena, "Access violation reading from address 0x%I64x", event->vaddr_rng.min); dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryWrite: { - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); - String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation writing 0x%I64x)", exception_code_string, event->vaddr_rng.min); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); + String8 exception_info_string = push_str8f(arena, "Access violation writing to address 0x%I64x", event->vaddr_rng.min); dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; case CTRL_ExceptionKind_MemoryExecute: { - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_concat_in_place(&fstrs, &thread_fstrs); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); - String8 exception_info_string = push_str8f(arena, "%S (Access violation executing 0x%I64x)", exception_code_string, event->vaddr_rng.min); + String8 exception_info_string = push_str8f(arena, "Access violation executing at address 0x%I64x", event->vaddr_rng.min); dr_fstrs_push_new(arena, &fstrs, ¶ms, exception_info_string); }break; } @@ -11814,7 +11813,7 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) else { dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Hit an exception - ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ca23b41b..3bfbaa19 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1765,8 +1765,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px; - line_extras_off[line_idx] = Max(line_text_dim, params->font_size*50); + F32 line_text_dim = fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; + line_extras_off[line_idx] = Max(line_text_dim, params->font_size*30); } } @@ -1806,7 +1806,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe stop_event.cause == CTRL_EventCause_InterruptedByTrap)) { DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); - UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + UI_Parent(line_extras_boxes[line_idx]) UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) UI_TagF("bad_pop") { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###exception_info"); From 03337a7280487a17d476e194c2bdd8616d73997b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 13:01:28 -0800 Subject: [PATCH 170/755] more convergence on lister/queries --- src/eval/eval_ir.c | 4 +- src/raddbg/generated/raddbg.meta.c | 6 +-- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 1 - src/raddbg/raddbg_core.c | 26 ++++++++- src/raddbg/raddbg_views.c | 85 +++++++++++++++++------------- src/raddbg/raddbg_views.h | 1 + 7 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 72198bec..8fb35c42 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -391,7 +391,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) { base_ptr_member = &members.v[idx]; } - if(opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + else if(base_ptr_member != 0 && opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) { opl_ptr_member = &members.v[idx]; } @@ -458,7 +458,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) } // rjf: fill - if(count_member && base_ptr_member) + if((count_member || opl_ptr_member) && base_ptr_member) { E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); accel->arch = arch; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b75bd92f..db9b2325 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[295] = +RD_VocabInfo rd_vocab_info_table[294] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -272,7 +272,6 @@ RD_VocabInfo rd_vocab_info_table[295] = {str8_lit_comp("search_backwards"), str8_lit_comp(""), str8_lit_comp("Search Backwards"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, {str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, -{str8_lit_comp("target"), str8_lit_comp(""), str8_lit_comp("Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("targets"), str8_lit_comp(""), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("file_path_map"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, @@ -363,7 +362,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[212] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -549,7 +548,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 11182c9d..5f3daa04 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -237,7 +237,6 @@ RD_CmdKind_Search, RD_CmdKind_SearchBackwards, RD_CmdKind_GettingStarted, RD_CmdKind_Commands, -RD_CmdKind_Target, RD_CmdKind_Targets, RD_CmdKind_FilePathMap, RD_CmdKind_AutoViewRules, @@ -631,7 +630,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[295]; +extern RD_VocabInfo rd_vocab_info_table[294]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f65064dc..e1b57e48 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -581,7 +581,6 @@ RD_CmdTable: // | | | | //- rjf: view drivers {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } - {Target 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Target "target" "Target" "Opens the editor for a target." "" "" } {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cce6a98b..eae92e73 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2012,7 +2012,7 @@ internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg) { RD_Cfg *project = rd_cfg_child_from_string(cfg, str8_lit("project")); - B32 result = path_match_normalized(rd_state->project_path, project->first->string); + B32 result = (project != &rd_nil_cfg && !path_match_normalized(rd_state->project_path, project->first->string)); return result; } @@ -3720,6 +3720,17 @@ rd_view_ui(Rng2F32 rect) } } + ////////////////////////////// + //- rjf: consume query-completion events, if this view is being used as a query + // + if(vs->is_searching && + ui_is_focus_active() && + ui_slot_press(UI_EventActionSlot_Accept)) + { + // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): + // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): + } + ////////////////////////////// //- rjf: consume events & perform navigations/edits - calculate state // @@ -4812,7 +4823,7 @@ rd_view_ui(Rng2F32 rect) B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); B32 row_expanded = ev_expansion_from_key(eval_view, row->key); B32 next_row_expanded = row_expanded; - B32 row_is_expandable = ev_row_is_expandable(row); + B32 row_is_expandable = row_info->can_expand; if(implicit_root && row_depth > 0) { row_depth -= 1; @@ -8149,6 +8160,17 @@ rd_window_frame(void) { build_hover_eval = 0; } + else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) + { + build_hover_eval = 0; + } + else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) + { + build_hover_eval = 0; + } // rjf: reset open animation if(ws->hover_eval_string.size == 0) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a998c148..810bc207 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -888,6 +888,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_WatchRowInfo info = { .module = &ctrl_entity_nil, + .can_expand = ev_row_is_expandable(row), .group_cfg_parent = &rd_nil_cfg, .group_cfg_child = &rd_nil_cfg, .group_entity = &ctrl_entity_nil, @@ -1137,15 +1138,19 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: folder / file rows else if(info.eval.space.kind == E_SpaceKind_FileSystem) { - String8 file_path = e_string_from_id(info.eval.value.u64); - DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(str8_match(type->name, str8_lit("folder"), 0)) + if(type->kind == E_TypeKind_Set) { + String8 file_path = e_string_from_id(info.eval.value.u64); + DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f, .fstrs = fstrs); + if(str8_match(type->name, str8_lit("file"), 0)) + { + info.can_expand = 0; + } } else { @@ -1155,22 +1160,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, - .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, - .default_pct = 0.35f, - .pct = take_pct(), - .fstrs = fstrs); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); #undef take_pct } } - // rjf: lister rows - else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); - } - // rjf: singular cell for view ui else if(info.view_ui_rule != &rd_nil_view_ui_rule) { @@ -1183,6 +1178,30 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } + // rjf: for meta-cfg evaluation spaces, only do expr/value + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + info.eval.space.kind == E_SpaceKind_File) + { + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); +#undef take_pct + } + + // rjf: lister rows + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + info.can_expand = 0; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + } + // rjf: procedures collections get only expr/value/view-rule else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) { @@ -1198,22 +1217,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } - // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || - info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - info.cell_style_key = str8_lit("expr_and_eval"); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); -#undef take_pct - } - // rjf: callstack frames else if(info.callstack_thread != &ctrl_entity_nil) { @@ -1465,9 +1468,13 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } else if(result.eval.space.kind == E_SpaceKind_FileSystem) { - String8 file_path = e_string_from_id(result.eval.value.u64); - result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); - result.flags |= RD_WatchCellFlag_Button; + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } } }break; case RD_WatchCellKind_Eval: @@ -1513,9 +1520,13 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } else if(result.eval.space.kind == E_SpaceKind_FileSystem) { - String8 file_path = e_string_from_id(result.eval.value.u64); - result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); - result.flags |= RD_WatchCellFlag_Button; + E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(result.eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } } }break; } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index da9c8420..5bc84acd 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -89,6 +89,7 @@ struct RD_WatchRowInfo { E_Eval eval; CTRL_Entity *module; + B32 can_expand; B32 expr_is_editable; String8 group_cfg_name; RD_Cfg *group_cfg_parent; From 3c8f58cb3896a36cc42a1cd1403815e8431962c1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 13:23:12 -0800 Subject: [PATCH 171/755] add tracking to dbgi scopes --- src/dbgi/dbgi.c | 10 ++++++++-- src/dbgi/dbgi.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 063be596..a3fbccaf 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -262,12 +262,14 @@ di_scope_open(void) scope = push_array_no_zero(di_tctx->arena, DI_Scope, 1); } MemoryZeroStruct(scope); + DLLPushBack(di_tctx->first_scope, di_tctx->last_scope, scope); return scope; } internal void di_scope_close(DI_Scope *scope) { + DLLRemove(di_tctx->first_scope, di_tctx->last_scope, scope); for(DI_Touch *t = scope->first_touch, *next = 0; t != 0; t = next) { next = t->next; @@ -1349,7 +1351,6 @@ di_search_thread__entry_point(void *p) for(;;) { Temp scratch = scratch_begin(0, 0); - DI_Scope *di_scope = di_scope_open(); //- rjf: get next key, unpack U128 key = di_u2s_dequeue_req(thread_idx); @@ -1380,6 +1381,9 @@ di_search_thread__entry_point(void *p) } } + //- rjf: begin debug info scope + DI_Scope *di_scope = di_scope_open(); + //- rjf: get all rdis U64 rdis_count = params.dbgi_keys.count; RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); @@ -1428,6 +1432,9 @@ di_search_thread__entry_point(void *p) cancelled = (cancelled || out->cancelled); } + //- rjf: end debug info scope + di_scope_close(di_scope); + //- rjf: list -> array DI_SearchItemArray items = {0}; if(arena != 0 && !cancelled) @@ -1496,7 +1503,6 @@ di_search_thread__entry_point(void *p) } } - di_scope_close(di_scope); scratch_end(scratch); } } diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index 3b3b23ea..76754bd4 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -225,6 +225,7 @@ typedef struct DI_Scope DI_Scope; struct DI_Scope { DI_Scope *next; + DI_Scope *prev; DI_Touch *first_touch; DI_Touch *last_touch; }; @@ -233,6 +234,8 @@ typedef struct DI_TCTX DI_TCTX; struct DI_TCTX { Arena *arena; + DI_Scope *first_scope; + DI_Scope *last_scope; DI_Scope *free_scope; DI_Touch *free_touch; }; From e76da7892ab2871b396fac5f47ad68056cf2d335 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 13:57:54 -0800 Subject: [PATCH 172/755] fix bad debug info scope search usage --- src/dbg_engine/dbg_engine_core.c | 1 - src/dbg_engine/dbg_engine_core.h | 1 - src/raddbg/raddbg_core.c | 46 +++++++++++++++++--------------- src/raddbg/raddbg_core.h | 2 ++ 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 0c51c544..fc6abd8e 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1705,7 +1705,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P Temp scratch = scratch_begin(&arena, 1); D_EventList result = {0}; d_state->frame_index += 1; - d_state->frame_eval_memread_endt_us = os_now_microseconds() + 1000; ////////////////////////////// //- rjf: sync with ctrl thread diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 45a3caf8..cabaca1d 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -330,7 +330,6 @@ struct D_State // rjf: top-level state Arena *arena; U64 frame_index; - U64 frame_eval_memread_endt_us; // rjf: commands Arena *cmds_arena; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index eae92e73..21c435f8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -868,7 +868,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); if(section != RDI_SectionKind_NULL) { - U64 endt_us = d_state->frame_eval_memread_endt_us; + U64 endt_us = rd_state->frame_eval_memread_endt_us; //- rjf: unpack context DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); @@ -2784,7 +2784,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) default:{}break; case CTRL_EntityKind_Process: { - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, d_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, rd_state->frame_eval_memread_endt_us); String8 data = slice.data; if(data.size == dim_1u64(range)) { @@ -4878,7 +4878,7 @@ rd_view_ui(Rng2F32 rect) U64 size = e_type_byte_size_from_key(row_info->eval.irtree.type_key); size = Min(size, 64); Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, d_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { if(slice.byte_changed_flags[idx] != 0) @@ -6000,6 +6000,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state) { Temp scratch = scratch_begin(0, 0); + rd_state->frame_depth += 1; // rjf: unpack configuration options B32 has_pos = 0; @@ -6074,6 +6075,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); + rd_state->frame_depth -= 1; scratch_end(scratch); } @@ -12398,7 +12400,6 @@ rd_frame(void) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - local_persist S32 depth = 0; log_scope_begin(); ////////////////////////////// @@ -12418,10 +12419,6 @@ 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(); - } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; rd_state->cfg2evalblob_map = push_array(rd_frame_arena(), RD_Cfg2EvalBlobMap, 1); @@ -12430,11 +12427,12 @@ rd_frame(void) 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); + rd_state->frame_eval_memread_endt_us = os_now_microseconds() + 5000; ////////////////////////////// //- rjf: iterate all tabs, touch their view-states // - if(depth == 0) + if(rd_state->frame_depth == 0) { Temp scratch = scratch_begin(0, 0); RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); @@ -12461,7 +12459,7 @@ rd_frame(void) ////////////////////////////// //- rjf: garbage collect untouched immediate cfg trees // - if(depth == 0) + if(rd_state->frame_depth == 0) { RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); for(RD_Cfg *tln = transient->first, *next = &rd_nil_cfg; tln != &rd_nil_cfg; tln = next) @@ -12487,7 +12485,7 @@ rd_frame(void) ////////////////////////////// //- rjf: garbage collect untouched window states // - if(depth == 0) DeferLoop(depth += 1, depth -= 1) + if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) { for EachIndex(slot_idx, rd_state->window_state_slots_count) { @@ -12523,7 +12521,7 @@ rd_frame(void) ////////////////////////////// //- rjf: garbage collect untouched view states // - if(depth == 0) + if(rd_state->frame_depth == 0) { for EachIndex(slot_idx, rd_state->view_state_slots_count) { @@ -12583,7 +12581,7 @@ rd_frame(void) ////////////////////////////// //- rjf: animate all views // - if(depth == 0) + if(rd_state->frame_depth == 0) { F32 slow_rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); @@ -12630,11 +12628,18 @@ rd_frame(void) //- rjf: get events from the OS // OS_EventList events = {0}; - if(depth == 0) DeferLoop(depth += 1, depth -= 1) + if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) { events = os_get_events(scratch.arena, rd_state->num_frames_requested == 0); } + ////////////////////////////// + //- rjf: open frame debug info scope + // + { + rd_state->frame_di_scope = di_scope_open(); + } + ////////////////////////////// //- rjf: pick target hz // @@ -13606,7 +13611,7 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // - if(depth == 0) + if(rd_state->frame_depth == 0) { for(;rd_next_cmd(&cmd);) RD_RegsScope() { @@ -17187,7 +17192,7 @@ Z(getting_started) // the commands pushed by the view will be in the queue, and the core can // treat that queue as r/w again. // - if(depth == 0) + if(rd_state->frame_depth == 0) { // rjf: rotate { @@ -17332,9 +17337,8 @@ Z(getting_started) } ////////////////////////////// - //- rjf: close scopes + //- rjf: close frame debug info scope // - if(depth == 0) { di_scope_close(rd_state->frame_di_scope); } @@ -17357,7 +17361,7 @@ Z(getting_started) ////////////////////////////// //- rjf: show windows after first frame // - if(depth == 0) + if(rd_state->frame_depth == 0) { RD_CfgIDList windows_to_show = {0}; for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) @@ -17371,7 +17375,7 @@ Z(getting_started) { RD_Cfg *window = rd_cfg_from_id(n->v); RD_WindowState *ws = rd_window_state_from_cfg(window); - DeferLoop(depth += 1, depth -= 1) os_window_first_paint(ws->os); + DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) os_window_first_paint(ws->os); } } @@ -17391,7 +17395,7 @@ Z(getting_started) ////////////////////////////// //- rjf: bump command batch ring buffer generation // - if(depth == 0) + if(rd_state->frame_depth == 0) { rd_state->cmds_gen += 1; } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 182e08be..3a2d8608 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -714,6 +714,8 @@ struct RD_State Arena *arena; B32 quit; B32 quit_after_success; + S32 frame_depth; + U64 frame_eval_memread_endt_us; // rjf: config bucket paths Arena *user_path_arena; From 9b636568fd92819db2f31fdf0c5c3bcd6b52c947 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 15:29:54 -0800 Subject: [PATCH 173/755] more convergence --- src/ctrl/ctrl_core.c | 4 +- src/raddbg/generated/raddbg.meta.c | 16 ++- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 8 +- src/raddbg/raddbg_core.c | 224 ++++++++++++++++------------- src/raddbg/raddbg_core.h | 18 ++- src/raddbg/raddbg_views.c | 18 ++- src/raddbg/raddbg_widgets.c | 2 +- 8 files changed, 168 insertions(+), 126 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index f0cb14d2..a80721cc 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1400,6 +1400,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 //- rjf: try to read from cache B32 is_good = 0; + B32 process_node_exists = 0; B32 is_stale = 1; OS_MutexScopeR(process_stripe->rw_mutex) { @@ -1407,6 +1408,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 { if(ctrl_handle_match(n->handle, process)) { + process_node_exists = 1; U64 range_slot_idx = range_hash%n->range_hash_slots_count; CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) @@ -1425,7 +1427,7 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 } //- rjf: not good -> create process cache node if necessary - if(!is_good) + if(!is_good && !process_node_exists) { OS_MutexScopeW(process_stripe->rw_mutex) { diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index db9b2325..fbda345d 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[294] = +RD_VocabInfo rd_vocab_info_table[296] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -125,10 +125,12 @@ RD_VocabInfo rd_vocab_info_table[294] = {str8_lit_comp("open_lister"), str8_lit_comp(""), str8_lit_comp("Open Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("run_command"), str8_lit_comp(""), str8_lit_comp("Run Command"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp("OS Event"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Thread}, {str8_lit_comp("select_unwind"), str8_lit_comp(""), str8_lit_comp("Select Unwind"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("up_one_frame"), str8_lit_comp(""), str8_lit_comp("Up One Frame"), str8_lit_comp(""), RD_IconKind_UpArrow}, {str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select Entity"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect Entity"), str8_lit_comp(""), RD_IconKind_RadioFilled}, {str8_lit_comp("inc_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("dec_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("inc_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, @@ -362,7 +364,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[212] = +RD_CmdKindInfo rd_cmd_kind_info_table[214] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -401,10 +403,12 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -522,7 +526,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 5f3daa04..3261a8da 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -94,6 +94,8 @@ RD_CmdKind_SelectThread, RD_CmdKind_SelectUnwind, RD_CmdKind_UpOneFrame, RD_CmdKind_DownOneFrame, +RD_CmdKind_SelectEntity, +RD_CmdKind_DeselectEntity, RD_CmdKind_IncUIFontScale, RD_CmdKind_DecUIFontScale, RD_CmdKind_IncCodeFontScale, @@ -630,7 +632,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[294]; +extern RD_VocabInfo rd_vocab_info_table[296]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e1b57e48..58e3e47c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -368,10 +368,12 @@ RD_CmdTable: // | | | | {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Null "select_thread" "Select Thread" "Selects a thread." "" "" } - {SelectUnwind 1 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {SelectThread 0 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 0 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } + {SelectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select Entity" "Selects a control entity." "" "" } + {DeselectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } //- rjf: font sizes {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } @@ -537,7 +539,7 @@ RD_CmdTable: // | | | | {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } - {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree." "" "" } {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 21c435f8..8b9c90d1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -396,7 +396,9 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfg) U64 read_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { - exprs[dst_idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx + read_range.min - cfgs_idx_range.min); + RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; + exprs[dst_idx] = e_push_expr(arena, E_ExprKind_LeafIdent, 0); + exprs[dst_idx]->string = push_str8f(arena, "$%I64d", cfg->id); } } } @@ -836,6 +838,20 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) return result; } +E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) +{ + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + Rng1U64 legal_range = r1u64(0, entities->count); + Rng1U64 read_range = intersect_1u64(legal_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) + { + CTRL_Entity *entity = entities->v[out_idx + read_range.min]; + exprs[out_idx] = e_push_expr(arena, E_ExprKind_LeafIdent, 0); + exprs[out_idx]->string = ctrl_string_from_handle(arena, entity->handle); + } +} + //////////////////////////////// //~ rjf: Debug Info Tables Eval Hooks @@ -3314,7 +3330,6 @@ rd_view_state_from_cfg(RD_Cfg *cfg) view_state->arena = arena_alloc(); view_state->arena_reset_pos = arena_pos(view_state->arena); view_state->ev_view = ev_view_alloc(); - view_state->search_arena = arena_alloc(); } if(view_state != &rd_nil_view_state) { @@ -3333,21 +3348,29 @@ rd_view_ui(Rng2F32 rect) String8 expr_string = rd_expr_from_cfg(view); ////////////////////////////// - //- rjf: searching extension + //- rjf: query extension // - B32 search_row_is_open = (vs->is_searching || vs->search_string_size != 0); + RD_Cfg *query_root = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input_root = rd_cfg_child_from_string(query_root, str8_lit("input")); + RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); + String8 current_input = input_root->first->string; + B32 search_row_is_open = (vs->query_is_selected || current_input.size != 0); F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); if(search_row_open_t > 0.001f) { - String8 cmd_name = vs->search_cmd_name; + String8 cmd_name = cmd_root->first->string; RD_IconKind icon = rd_icon_kind_from_code_name(cmd_name); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + //- rjf: store cfg's string into view's + vs->query_string_size = Min(sizeof(vs->query_buffer), current_input.size); + MemoryCopy(vs->query_buffer, current_input.str, vs->query_string_size); + //- rjf: clamp cursor - if(vs->search_cursor.column == 0) + if(vs->query_cursor.column == 0) { - vs->search_mark = txt_pt(1, 1); - vs->search_cursor = txt_pt(1, vs->search_string_size+1); + vs->query_mark = txt_pt(1, 1); + vs->query_cursor = txt_pt(1, vs->query_string_size+1); } //- rjf: determine dimensions @@ -3365,7 +3388,7 @@ rd_view_ui(Rng2F32 rect) } //- rjf: build contents - UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->is_searching ? UI_FocusKind_On : UI_FocusKind_Off) + UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) { UI_TextAlignment(UI_TextAlign_Center) @@ -3382,23 +3405,27 @@ rd_view_ui(Rng2F32 rect) { params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_LineEditFlag_CodeContents; params.flags |= RD_LineEditFlag_Border; - params.cursor = &vs->search_cursor; - params.mark = &vs->search_mark; - params.edit_buffer = vs->search_buffer; - params.edit_string_size_out = &vs->search_string_size; - params.edit_buffer_size = sizeof(vs->search_buffer); - params.pre_edit_value = str8(vs->search_buffer, vs->search_string_size); + params.cursor = &vs->query_cursor; + params.mark = &vs->query_mark; + params.edit_buffer = vs->query_buffer; + params.edit_string_size_out = &vs->query_string_size; + params.edit_buffer_size = sizeof(vs->query_buffer); + params.pre_edit_value = current_input; } UI_Signal sig = rd_line_editf(¶ms, "###search"); if(ui_pressed(sig)) { - vs->is_searching = 1; + vs->query_is_selected = 1; + rd_cmd(RD_CmdKind_FocusPanel); } } //- rjf: commit string to view - RD_Cfg *search = rd_cfg_child_from_string_or_alloc(view, str8_lit("search")); - rd_cfg_new_replace(search, str8(vs->search_buffer, vs->search_string_size)); + if(input_root == &rd_nil_cfg) + { + input_root = rd_cfg_child_from_string_or_alloc(query_root, str8_lit("input")); + } + rd_cfg_new_replace(input_root, str8(vs->query_buffer, vs->query_string_size)); } ////////////////////////////// @@ -3691,7 +3718,7 @@ rd_view_ui(Rng2F32 rect) S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; - String8 filter = rd_view_search(); + String8 filter = rd_view_query_input(); Vec4F32 pop_background_rgba = {0}; UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); @@ -3720,16 +3747,35 @@ rd_view_ui(Rng2F32 rect) } } + ////////////////////////////// + //- rjf: process commands + // + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) + { + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) + { + default:{}break; + case RD_CmdKind_Search: + case RD_CmdKind_SearchBackwards: + { + vs->query_is_selected = 0; + }break; + } + } + ////////////////////////////// //- rjf: consume query-completion events, if this view is being used as a query // - if(vs->is_searching && +#if 0 + if(vs->query_is_selected && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): } +#endif ////////////////////////////// //- rjf: consume events & perform navigations/edits - calculate state @@ -5159,7 +5205,7 @@ rd_view_ui(Rng2F32 rect) { searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); } - String8 search_query = rd_view_search(); + String8 search_query = rd_view_query_input(); FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); if(fuzzy_matches.count == 0) { @@ -5582,12 +5628,12 @@ rd_view_ui(Rng2F32 rect) //////////////////////////// //- rjf: catchall query completion controls // - if(vs->is_searching) UI_Focus(UI_FocusKind_On) + if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) { if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { - vs->is_searching = 0; - vs->search_string_size = 0; + vs->query_is_selected = 0; + vs->query_string_size = 0; } if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { @@ -5629,12 +5675,23 @@ rd_view_eval_view(void) } internal String8 -rd_view_search(void) +rd_view_query_cmd(void) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *search = rd_cfg_child_from_string(view, str8_lit("search")); - String8 search_string = search->first->string; - return search_string; + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 string = cmd->first->string; + return string; +} + +internal String8 +rd_view_query_input(void) +{ + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + String8 string = input->first->string; + return string; } internal RD_Cfg * @@ -7258,19 +7315,19 @@ rd_window_frame(void) B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); //- rjf: build & prepare view for query ui - RD_Cfg *query = rd_immediate_cfg_from_keyf("window_query_%p", window); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(query, str8_lit("watch")); + RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->is_searching = 1; - arena_clear(vs->search_arena); - vs->search_cmd_name = push_str8_copy(vs->search_arena, cmd_name); - vs->search_regs = rd_regs_copy(vs->search_arena, ws->query_regs); + vs->query_is_selected = 1; String8 query_expression = cmd_kind_info->query.expr; if(query_expression.size == 0) { - query_expression = str8(vs->search_buffer, vs->search_string_size); + query_expression = str8(vs->query_buffer, vs->query_string_size); RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); } @@ -7281,7 +7338,7 @@ rd_window_frame(void) { String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); - query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->search_buffer, vs->search_string_size), post_insertion); + query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); } rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); } @@ -7300,7 +7357,7 @@ rd_window_frame(void) { Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_search(), query_eval.exprs); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); F32 max_query_height_px = content_rect_dim.y*0.8f; @@ -12535,7 +12592,6 @@ rd_frame(void) { arena_release(ext->arena); } - arena_release(vs->search_arena); arena_release(vs->arena); DLLRemove_NP(rd_state->view_state_slots[slot_idx].first, rd_state->view_state_slots[slot_idx].last, vs, hash_next, hash_prev); SLLStackPush_N(rd_state->free_view_state, vs, hash_next); @@ -13462,7 +13518,8 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities)); + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(ctrl_entities)); } //- rjf: add macro / lookup rules for unattached processes @@ -15795,6 +15852,8 @@ Z(getting_started) { String8 cmd_name = rd_regs()->cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: floating queries -> set up window to build immediate-mode top-level query if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); @@ -15807,38 +15866,40 @@ Z(getting_started) ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); } } + + // rjf: non-floating -> embed in tab parameter else { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + String8 current_query_cmd_name = cmd->first->string; RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!str8_match(vs->search_cmd_name, cmd_name, 0)) + if(!str8_match(current_query_cmd_name, cmd_name, 0)) { - arena_clear(vs->search_arena); - vs->search_regs = rd_regs_copy(vs->search_arena, rd_regs()); - vs->search_cmd_name = push_str8_copy(vs->search_arena, cmd_name); - if(!vs->is_searching) + rd_cfg_new_replace(cmd, cmd_name); + if(!vs->query_is_selected) { - vs->search_cursor = txt_pt(1, 1+vs->search_string_size); - vs->search_mark = txt_pt(1, 1); + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); } - vs->is_searching = 1; + vs->query_is_selected = 1; } else { - vs->is_searching ^= 1; + vs->query_is_selected ^= 1; } } }break; case RD_CmdKind_CompleteQuery: { - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_ViewState *vs = rd_view_state_from_cfg(view); - String8 cmd_name = vs->search_cmd_name; + String8 cmd_name = rd_view_query_cmd(); + String8 input = rd_view_query_input(); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); RD_RegsScope() { - rd_regs_copy_contents(vs->search_arena, rd_regs(), vs->search_regs); - rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, str8(vs->search_buffer, vs->search_string_size)); + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); rd_push_cmd(cmd_name, rd_regs()); } if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) @@ -15849,53 +15910,12 @@ Z(getting_started) } else if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) { - vs->is_searching = 0; - vs->search_string_size = 0; + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_is_selected = 0; + vs->query_string_size = 0; + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("query"))); } - -#if 0 // TODO(rjf): @cfg (query completion) - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - String8 query_cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(query_cmd_name); - RD_RegSlot slot = info->query.slot; - - // rjf: compound command parameters - if(slot != RD_RegSlot_Null && !(ws->query_cmd_regs_mask[slot/64] & (1ull<<(slot%64)))) - { - RD_Regs *regs_copy = rd_regs_copy(ws->query_cmd_arena, rd_regs()); - Rng1U64 offset_range_in_regs = rd_reg_slot_range_table[slot]; - MemoryCopy((U8 *)(ws->query_cmd_regs) + offset_range_in_regs.min, - (U8 *)(regs_copy) + offset_range_in_regs.min, - dim_1u64(offset_range_in_regs)); - ws->query_cmd_regs_mask[slot/64] |= (1ull<<(slot%64)); - } - - // rjf: determine if command is ready to run - B32 command_ready = 1; - if(slot != RD_RegSlot_Null && !(ws->query_cmd_regs_mask[slot/64] & (1ull<<(slot%64)))) - { - command_ready = 0; - } - - // rjf: end this query - if(!(info->query.flags & RD_QueryFlag_KeepOldInput)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - - // rjf: unset command register slot, if we keep old input (and thus need - // to re-query user) - if(info->query.flags & RD_QueryFlag_KeepOldInput) - { - ws->query_cmd_regs_mask[slot/64] &= ~(1ull<<(slot%64)); - } - - // rjf: push command if possible - if(command_ready) - { - rd_push_cmd(ws->query_cmd_name, ws->query_cmd_regs); - } -#endif }break; case RD_CmdKind_CancelQuery: { @@ -16068,7 +16088,7 @@ Z(getting_started) case RD_CmdKind_AddAddressBreakpoint: case RD_CmdKind_AddFunctionBreakpoint: { - rd_cmd(RD_CmdKind_AddBreakpoint); + rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero()); }break; //- rjf: watch pins @@ -16293,6 +16313,10 @@ Z(getting_started) }break; //- rjf: debug control context management operations + case RD_CmdKind_SelectEntity: + { + rd_cmd(RD_CmdKind_SelectThread, .thread = rd_regs()->ctrl_entity); + }break; case RD_CmdKind_SelectThread: { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 3a2d8608..33fc8eaa 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -235,15 +235,12 @@ struct RD_ViewState RD_ArenaExt *last_arena_ext; void *user_data; - // rjf: search editing controls - B32 is_searching; - Arena *search_arena; - RD_Regs *search_regs; - String8 search_cmd_name; - TxtPt search_cursor; - TxtPt search_mark; - U8 search_buffer[KB(1)]; - U64 search_string_size; + // rjf: query state + B32 query_is_selected; + TxtPt query_cursor; + TxtPt query_mark; + U8 query_buffer[KB(1)]; + U64 query_string_size; }; typedef struct RD_ViewStateSlot RD_ViewStateSlot; @@ -1079,7 +1076,8 @@ internal void rd_view_ui(Rng2F32 rect); internal Arena *rd_view_arena(void); internal UI_ScrollPt2 rd_view_scroll_pos(void); internal EV_View *rd_view_eval_view(void); -internal String8 rd_view_search(void); +internal String8 rd_view_query_cmd(void); +internal String8 rd_view_query_input(void); internal RD_Cfg *rd_view_cfg_from_string(String8 string); internal E_Value rd_view_cfg_value_from_string(String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 810bc207..4b07362c 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -139,7 +139,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: get active search query // - String8 search_query = rd_view_search(); + String8 search_query = rd_view_query_input(); B32 search_query_is_active = 0; ////////////////////////////// @@ -832,7 +832,7 @@ rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) RD_WatchPt pt = zero_struct; { Temp scratch = scratch_begin(0, 0); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_search(), block_ranges, (U64)tbl.y); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, (U64)tbl.y); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); { S64 x = 0; @@ -859,7 +859,7 @@ rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Temp scratch = scratch_begin(0, 0); U64 num = ev_num_from_key(block_ranges, pt.key); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_search(), block_ranges, num); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, num); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); tbl.x = 0; { @@ -1091,6 +1091,16 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); } + if(entity->kind == CTRL_EntityKind_Thread) + { + RD_CmdKind cmd_kind = RD_CmdKind_SelectEntity; + if(ctrl_handle_match(entity->handle, rd_base_regs()->thread)) + { + cmd_kind = RD_CmdKind_DeselectEntity; + } + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } } // rjf: singular button for unattached processes @@ -1408,7 +1418,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: generate strings/flags based on that expression & fill - result.string = rd_value_string_from_eval(arena, rd_view_search(), string_flags, default_radix, font, font_size, max_size_px, result.eval); + result.string = rd_value_string_from_eval(arena, rd_view_query_input(), string_flags, default_radix, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 3bfbaa19..b2c11429 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -438,7 +438,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e Vec4F32 process_color = rd_color_from_ctrl_entity(process); if(process_color.w == 0) { - process_color = color; + process_color = ui_color_from_name(str8_lit("text")); } if(process_name.size != 0) { From 1b4a5e529f577bfb56b95111c362d3cf4b9213f1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 16:33:57 -0800 Subject: [PATCH 174/755] more convergence / fixes relating to searching/queries/filters --- src/eval/eval_parse.c | 16 +++-- src/raddbg/raddbg_core.c | 138 +++++++++++++++++++----------------- src/raddbg/raddbg_core.h | 10 --- src/raddbg/raddbg_views.c | 63 +++++++++++----- src/raddbg/raddbg_widgets.c | 16 ++--- 5 files changed, 141 insertions(+), 102 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 661c49af..e318b97e 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -819,12 +819,20 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) op_info->sep, op_info->post, }; - U64 idx = 0; - for(E_Expr *child = expr->first;; child = child->next, idx += 1) + U64 sep_idx = 0; + for(E_Expr *child = expr->first;; child = child->next) { - if(seps[idx].size != 0) + if(seps[sep_idx].size != 0) { - str8_list_push(arena, out, seps[idx]); + if(sep_idx == 1 && child == &e_expr_nil) + { + sep_idx += 1; + } + str8_list_push(arena, out, seps[sep_idx]); + if(sep_idx == 0) + { + sep_idx += 1; + } } if(child == &e_expr_nil) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8b9c90d1..1130807d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1443,6 +1443,8 @@ rd_cfg_newf(RD_Cfg *parent, char *fmt, ...) internal RD_Cfg * rd_cfg_new_replace(RD_Cfg *parent, String8 string) { + Temp scratch = scratch_begin(0, 0); + string = push_str8_copy(scratch.arena, string); for(RD_Cfg *child = parent->first->next, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) { next = child->next; @@ -1454,6 +1456,7 @@ rd_cfg_new_replace(RD_Cfg *parent, String8 string) } RD_Cfg *child = parent->first; rd_cfg_equip_string(child, string); + scratch_end(scratch); return child; } @@ -3354,7 +3357,7 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *input_root = rd_cfg_child_from_string(query_root, str8_lit("input")); RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); String8 current_input = input_root->first->string; - B32 search_row_is_open = (vs->query_is_selected || current_input.size != 0); + B32 search_row_is_open = (vs->query_is_selected); F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); if(search_row_open_t > 0.001f) { @@ -3412,11 +3415,14 @@ rd_view_ui(Rng2F32 rect) params.edit_buffer_size = sizeof(vs->query_buffer); params.pre_edit_value = current_input; } - UI_Signal sig = rd_line_editf(¶ms, "###search"); - if(ui_pressed(sig)) + UI_Transparency(1-search_row_open_t) { - vs->query_is_selected = 1; - rd_cmd(RD_CmdKind_FocusPanel); + UI_Signal sig = rd_line_editf(¶ms, "###search"); + if(ui_pressed(sig)) + { + vs->query_is_selected = 1; + rd_cmd(RD_CmdKind_FocusPanel); + } } } @@ -5389,7 +5395,7 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: can't edit, but has cfg location info? -> find + // rjf: can't edit, but has cfg? -> find or select else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) { RD_Cfg *cfg = rd_cfg_from_eval_space(cell_info.eval.space); @@ -5403,6 +5409,24 @@ rd_view_ui(Rng2F32 rect) U64 value = e_value_from_string(loc.expr).u64; rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); } + else if(str8_match(cfg->string, str8_lit("target"), 0) && sig.event_flags & OS_Modifier_Ctrl) + { + rd_cmd(RD_CmdKind_EnableCfg, .cfg = cfg->id); + } + else if(str8_match(cfg->string, str8_lit("target"), 0)) + { + rd_cmd(RD_CmdKind_SelectCfg, .cfg = cfg->id); + } + } + + // rjf: can't edit, but has thread? -> select + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); + if(entity->kind == CTRL_EntityKind_Thread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = entity->handle); + } } } @@ -11515,23 +11539,6 @@ rd_set_autocomp_lister_query_(RD_Regs *regs) ws->autocomp_lister_last_frame_idx = rd_state->frame_index; } -//////////////////////////////// -//~ rjf: Search Strings - -internal void -rd_set_search_string(String8 string) -{ - arena_clear(rd_state->string_search_arena); - rd_state->string_search_string = push_str8_copy(rd_state->string_search_arena, string); -} - -internal String8 -rd_push_search_string(Arena *arena) -{ - String8 result = push_str8_copy(arena, rd_state->string_search_string); - return result; -} - //////////////////////////////// //~ rjf: Colors, Fonts, Config @@ -12244,7 +12251,6 @@ rd_init(CmdLine *cmdln) rd_state->popup_arena = arena_alloc(); rd_state->ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("top_level_ctx_menu")); rd_state->drop_completion_key = ui_key_from_string(ui_key_zero(), str8_lit("drop_completion_ctx_menu")); - rd_state->string_search_arena = arena_alloc(); rd_state->bind_change_arena = arena_alloc(); rd_state->drag_drop_arena = arena_alloc(); rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1); @@ -14059,25 +14065,6 @@ rd_frame(void) } }break; - //- rjf: code navigation - case RD_CmdKind_Search: - case RD_CmdKind_SearchBackwards: - case RD_CmdKind_FindTextForward: - case RD_CmdKind_FindTextBackward: - { - rd_set_search_string(rd_regs()->string); - }break; - - //- rjf: find next and find prev - case RD_CmdKind_FindNext: - { - rd_cmd(RD_CmdKind_Search, .string = rd_push_search_string(scratch.arena)); - }break; - case RD_CmdKind_FindPrev: - { - rd_cmd(RD_CmdKind_SearchBackwards, .string = rd_push_search_string(scratch.arena)); - }break; - //- rjf: font sizes case RD_CmdKind_IncUIFontScale: { @@ -15854,6 +15841,7 @@ Z(getting_started) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: floating queries -> set up window to build immediate-mode top-level query + RD_Cfg *view = &rd_nil_cfg; if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); @@ -15865,31 +15853,54 @@ Z(getting_started) ws->query_cmd_name = push_str8_copy(ws->query_arena, cmd_name); ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); } + RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); + view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); } // rjf: non-floating -> embed in tab parameter else { - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); - String8 current_query_cmd_name = cmd->first->string; - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!str8_match(current_query_cmd_name, cmd_name, 0)) - { - rd_cfg_new_replace(cmd, cmd_name); - if(!vs->query_is_selected) - { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = txt_pt(1, 1); - } - vs->query_is_selected = 1; - } - else - { - vs->query_is_selected ^= 1; - } + view = rd_cfg_from_id(rd_regs()->view); + } + + // rjf: unpack view's query info + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + + // rjf: choose initial input string + String8 initial_input = {0}; + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + initial_input = rd_state->current_path; + } + else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + { + initial_input = input->first->string; + } + + // rjf: build query state + rd_cfg_new_replace(input, initial_input); + rd_cfg_new_replace(cmd, cmd_name); + String8 current_query_cmd_name = cmd->first->string; + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); + } + else + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = vs->query_cursor; + } + if(!str8_match(current_query_cmd_name, cmd_name, 0)) + { + vs->query_is_selected = 1; + } + else + { + vs->query_is_selected ^= 1; } }break; case RD_CmdKind_CompleteQuery: @@ -15914,7 +15925,6 @@ Z(getting_started) RD_ViewState *vs = rd_view_state_from_cfg(view); vs->query_is_selected = 0; vs->query_string_size = 0; - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("query"))); } }break; case RD_CmdKind_CancelQuery: diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 33fc8eaa..2bd8628f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -792,10 +792,6 @@ struct RD_State // rjf: text editing mode state B32 text_edit_mode; - // rjf: string search state - Arena *string_search_arena; - String8 string_search_string; - // rjf: contextual hover info RD_Regs *hover_regs; RD_RegSlot hover_regs_slot; @@ -1146,12 +1142,6 @@ internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); internal void rd_set_autocomp_lister_query_(RD_Regs *regs); #define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) -//////////////////////////////// -//~ rjf: Search Strings - -internal void rd_set_search_string(String8 string); -internal String8 rd_push_search_string(Arena *arena); - //////////////////////////////// //~ rjf: Colors, Fonts, Config diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4b07362c..56d5ae16 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -83,6 +83,18 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla arena_clear(cv->find_text_arena); cv->find_text_bwd = push_str8_copy(cv->find_text_arena, cmd->regs->string); }break; + case RD_CmdKind_FindNext: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_fwd = push_str8_copy(cv->find_text_arena, string); + }break; + case RD_CmdKind_FindPrev: + { + String8 string = rd_view_query_input(); + arena_clear(cv->find_text_arena); + cv->find_text_bwd = push_str8_copy(cv->find_text_arena, string); + }break; case RD_CmdKind_ToggleWatchExpressionAtMouse: { cv->watch_expr_at_mouse = 1; @@ -136,6 +148,29 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, text_info, text_data, visible_line_num_range); + ////////////////////////////// + //- rjf: selection on single line, no query? -> set search text + // + if(rd_regs()->cursor.line == rd_regs()->mark.line) + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(!vs->query_is_selected) + { + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); + if(text.size < 256) + { + rd_cfg_new_replace(input, text); + } + else + { + rd_cfg_new_replace(input, str8_zero()); + } + } + } + ////////////////////////////// //- rjf: get active search query // @@ -428,9 +463,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive); if(needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_fwd.size; found = 1; break; } @@ -460,15 +496,16 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { B32 found = 0; B32 first = 1; - S64 line_num_start = rd_regs()->cursor.line; + TxtRng rng = txt_rng(rd_regs()->cursor, rd_regs()->mark); + S64 line_num_start = rng.min.line; S64 line_num_last = (S64)text_info->lines_count; for(S64 line_num = line_num_start; 1 <= line_num && line_num <= line_num_last; first = 0) { // rjf: gather line info String8 line_string = str8_substr(text_data, text_info->lines_ranges[line_num-1]); - if(rd_regs()->cursor.line == line_num && first) + if(rng.min.line == line_num && first) { - line_string = str8_prefix(line_string, rd_regs()->cursor.column-1); + line_string = str8_prefix(line_string, rng.min.column-1); } // rjf: search string @@ -484,9 +521,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } if(next_needle_pos < line_string.size) { - rd_regs()->cursor.line = line_num; - rd_regs()->cursor.column = next_needle_pos+1; - rd_regs()->mark = rd_regs()->cursor; + rd_regs()->mark.line = line_num; + rd_regs()->mark.column = next_needle_pos+1; + rd_regs()->cursor = rd_regs()->mark; + rd_regs()->cursor.column += cv->find_text_bwd.size; found = 1; break; } @@ -588,13 +626,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->watch_expr_at_mouse = 0; rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = txt_string_from_info_data_txt_rng(text_info, text_data, sig.mouse_expr_rng)); } - - //- rjf: selected text on single line, no query? -> set search text - if(!txt_pt_match(rd_regs()->cursor, rd_regs()->mark) && rd_regs()->cursor.line == rd_regs()->mark.line && search_query.size == 0) - { - String8 text = txt_string_from_info_data_txt_rng(text_info, text_data, txt_rng(rd_regs()->cursor, rd_regs()->mark)); - rd_set_search_string(text); - } } ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b2c11429..253dcd91 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1960,6 +1960,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: interact with margin box & text box // + B32 search_query_invalidated = 0; UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box); UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); @@ -2010,6 +2011,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe *preferred_column = cursor->column; } + //- rjf: dragging will invalidate the search string, so we don't want to draw it while dragging/releasing + if(ui_dragging(text_container_sig) || ui_released(text_container_sig)) + { + search_query_invalidated = 1; + } + //- rjf: right-click => code context menu if(ui_right_clicked(text_container_sig)) { @@ -2371,7 +2378,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_box_equip_display_fstrs(line_box, &line_fstrs); // rjf: extra rendering for strings that are currently being searched for - if(params->search_query.size != 0) + if(!search_query_invalidated && params->search_query.size != 0) { for(U64 needle_pos = 0; needle_pos < line_string.size;) { @@ -2392,13 +2399,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_box->rect.y1, }; Vec4F32 color = pop_color; - if(cursor->line == line_num && needle_pos+1 <= cursor->column && cursor->column < needle_pos+params->search_query.size+1) - { - color.x += (1.f - color.x) * 0.5f; - color.y += (1.f - color.y) * 0.5f; - color.z += (1.f - color.z) * 0.5f; - color.w += (1.f - color.w) * 0.5f; - } if(!is_focused) { color.w *= 0.5f; From 8bca57ef7fbefbe89ca54b538c9d1b0ca44b7e38 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 18:14:02 -0800 Subject: [PATCH 175/755] improved stability w.r.t. cfgs and ctrl entities expansion across changes --- src/ctrl/ctrl_core.c | 26 ++++- src/eval/eval_ir.c | 7 +- src/eval/eval_ir.h | 1 + src/raddbg/raddbg_core.c | 235 +++++++++++++++++++++++++------------- src/raddbg/raddbg_core.h | 4 - src/raddbg/raddbg_views.c | 44 +++++-- 6 files changed, 224 insertions(+), 93 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index a80721cc..7eede03b 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -169,10 +169,34 @@ ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src) internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle) { - String8 result = push_str8f(arena, "$%I64x_%I64x", handle.machine_id, handle.dmn_handle.u64[0]); + String8 result = push_str8f(arena, "$0x%I64x$0x%I64x", handle.machine_id, handle.dmn_handle.u64[0]); return result; } +internal CTRL_Handle +ctrl_handle_from_string(String8 string) +{ + CTRL_Handle handle = {0}; + { + Temp scratch = scratch_begin(0, 0); + U8 split = '$'; + String8List parts = str8_split(scratch.arena, string, &split, 1, 0); + if(parts.first && parts.first->next) + { + CTRL_MachineID machine_id = 0; + DMN_Handle dmn_handle = {0}; + if(try_u64_from_str8_c_rules(parts.first->string, &machine_id) && + try_u64_from_str8_c_rules(parts.first->next->string, &dmn_handle.u64[0])) + { + handle.machine_id = machine_id; + handle.dmn_handle = dmn_handle; + } + } + scratch_end(scratch); + } + return handle; +} + //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 8fb35c42..0e118ac1 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -588,6 +588,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); // rjf: look up member + E_Member member = zero_struct; B32 r_found = 0; E_TypeKey r_type = zero_struct; U64 r_value = 0; @@ -596,6 +597,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) { Temp scratch = scratch_begin(&arena, 1); E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); + member = match; if(match.kind != E_MemberKind_Null) { r_found = 1; @@ -688,6 +690,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) // rjf: fill result.irtree_and_type.root = new_tree; result.irtree_and_type.type_key = r_type; + result.irtree_and_type.member = member; result.irtree_and_type.mode = mode; } }break; @@ -1166,7 +1169,7 @@ E_IRGEN_FUNCTION_DEF(cast) E_Expr *type_expr = tag->first->next; E_TypeKey type_key = e_type_from_expr(type_expr); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_IRTreeAndType result = {irtree.root, type_key, irtree.mode, irtree.msgs}; + E_IRTreeAndType result = {irtree.root, type_key, irtree.member, irtree.mode, irtree.msgs}; return result; } @@ -1175,7 +1178,7 @@ E_IRGEN_FUNCTION_DEF(bswap) E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); e_irnode_push_child(root, irtree.root); - E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs}; + E_IRTreeAndType result = {root, irtree.type_key, irtree.member, irtree.mode, irtree.msgs}; return result; } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index fa0cb283..c2c87531 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -52,6 +52,7 @@ struct E_IRTreeAndType { E_IRNode *root; E_TypeKey type_key; + E_Member member; E_Mode mode; E_MsgList msgs; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1130807d..d3071173 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15,6 +15,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(commands) { E_LookupInfo result = {0}; + if(filter.size != 0) { Temp scratch = scratch_begin(&arena, 1); String8List cmd_names = {0}; @@ -34,6 +35,10 @@ E_LOOKUP_INFO_FUNCTION_DEF(commands) result.idxed_expr_count = accel->count; scratch_end(scratch); } + else + { + result.idxed_expr_count = RD_CmdKind_COUNT; + } return result; } @@ -53,15 +58,31 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(commands) E_LOOKUP_RANGE_FUNCTION_DEF(commands) { U64 out_idx = 0; - String8Array *accel = (String8Array *)user_data; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + if(user_data != 0) { - String8 cmd_name = accel->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs[out_idx] = expr; + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 cmd_name = accel->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs[out_idx] = expr; + } + } + else + { + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + RD_CmdKind cmd_kind = (RD_CmdKind)idx; + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs[out_idx] = expr; + } } } @@ -344,28 +365,43 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfg) E_LOOKUP_ACCESS_FUNCTION_DEF(cfg) { + Temp scratch = scratch_begin(&arena, 1); E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + RD_Cfg *cfg = &rd_nil_cfg; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + RD_CfgID id = 0; + if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && + try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + { + cfg = rd_cfg_from_id(id); + } + } + else if(kind == E_ExprKind_ArrayIndex) { - Temp scratch = scratch_begin(&arena, 1); - RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; - if(rhs_value.u64 < accel->cfgs.count) + U64 rhs_idx = rhs_value.u64; + RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; + if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) { - RD_Cfg *cfg = accel->cfgs.v[rhs_value.u64]; - E_Space cfg_space = rd_eval_space_from_cfg(cfg); - String8 cfg_name = cfg->string; - E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); - result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = cfg_type_key; - result.irtree_and_type.mode = E_Mode_Offset; + cfg = accel->cfgs.v[rhs_idx]; } - scratch_end(scratch); } + if(cfg != &rd_nil_cfg) + { + E_Space cfg_space = rd_eval_space_from_cfg(cfg); + String8 cfg_name = cfg->string; + E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); + result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = cfg_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); return result; } @@ -397,8 +433,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfg) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - exprs[dst_idx] = e_push_expr(arena, E_ExprKind_LeafIdent, 0); - exprs[dst_idx]->string = push_str8f(arena, "$%I64d", cfg->id); + exprs[dst_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, push_str8f(arena, "$%I64d", cfg->id)); } } } @@ -813,42 +848,53 @@ E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) { + Temp scratch = scratch_begin(&arena, 1); E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + CTRL_Entity *entity = &ctrl_entity_nil; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + CTRL_Handle handle = ctrl_handle_from_string(rhs_name); + entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + } + else if(kind == E_ExprKind_ArrayIndex) { - Temp scratch = scratch_begin(&arena, 1); - CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < entities->count) + U64 rhs_idx = rhs_value.u64; + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + if(0 <= rhs_idx && rhs_idx < entities->count) { - CTRL_Entity *entity = entities->v[rhs_value.u64]; - E_Space entity_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - String8 entity_name = ctrl_entity_kind_code_name_table[entity->kind]; - E_TypeKey entity_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, entity_name); - result.irtree_and_type.root = e_irtree_set_space(arena, entity_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = entity_type_key; - result.irtree_and_type.mode = E_Mode_Offset; + entity = entities->v[rhs_idx]; } - scratch_end(scratch); } + if(entity != &ctrl_entity_nil) + { + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); return result; } E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) { CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); Rng1U64 legal_range = r1u64(0, entities->count); Rng1U64 read_range = intersect_1u64(legal_range, idx_range); U64 read_count = dim_1u64(read_range); for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) { CTRL_Entity *entity = entities->v[out_idx + read_range.min]; - exprs[out_idx] = e_push_expr(arena, E_ExprKind_LeafIdent, 0); - exprs[out_idx]->string = ctrl_string_from_handle(arena, entity->handle); + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, ctrl_string_from_handle(arena, entity->handle)); } } @@ -5045,18 +5091,8 @@ rd_view_ui(Rng2F32 rect) Vec4F32 cell_background_color_override = {0}; String8 cell_tag = {0}; { - if(cell_info.flags & RD_WatchCellFlag_IsErrored) - { - cell_flags |= UI_BoxFlag_DrawBackground; - cell_tag = str8_lit("bad"); - } - else if(cell_info.inheritance_tooltip.size != 0) - { - cell_flags |= UI_BoxFlag_DrawBackground; - cell_tag = str8_lit("pop"); - } - else if(cell_info.cfg->id == rd_get_hover_regs()->cfg && - rd_state->hover_regs_slot == RD_RegSlot_Cfg) + if(cell_info.cfg->id == rd_get_hover_regs()->cfg && + rd_state->hover_regs_slot == RD_RegSlot_Cfg) { RD_Cfg *cfg = cell_info.cfg; Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); @@ -5110,6 +5146,7 @@ rd_view_ui(Rng2F32 rect) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(RD_FontSlot_Code) UI_TagF("weak") + UI_Tag(cell_tag) { // rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) @@ -7436,6 +7473,17 @@ rd_window_frame(void) } } + //- rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) + { + String8 path_chopped = str8_chop_last_slash(input->first->string); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } + } + //- rjf: build darkening rectangle over rest of screen UI_Rect(window_rect) UI_TagF("inactive") { @@ -7889,9 +7937,13 @@ rd_window_frame(void) for(RD_CfgNode *n = targets.first; n != 0; n = n->next) { RD_Cfg *target = n->v; - DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(box, &title_fstrs); + B32 target_is_enabled = !rd_disabled_from_cfg(target); + if(target_is_enabled) + { + DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(box, &title_fstrs); + } } } } @@ -8819,7 +8871,7 @@ rd_window_frame(void) panel_tree.focused == panel); RD_Cfg *selected_tab = panel->selected_tab; RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab); - ProfScope("leaf panel UI work - %.*s", str8_varg(selected_tab->string)) + ProfScope("leaf panel UI work - %.*s: %.*s", str8_varg(selected_tab->string), str8_varg(rd_expr_from_cfg(selected_tab))) UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { ////////////////////////// @@ -12446,15 +12498,6 @@ rd_init(CmdLine *cmdln) scratch_end(scratch); } - // rjf: set up initial browse path - { - Temp scratch = scratch_begin(0, 0); - String8 current_path = os_get_current_path(scratch.arena); - rd_state->current_path_arena = arena_alloc(); - rd_state->current_path = push_str8_copy(rd_state->current_path_arena, current_path); - scratch_end(scratch); - } - ProfEnd(); } @@ -12490,7 +12533,6 @@ rd_frame(void) 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); - rd_state->frame_eval_memread_endt_us = os_now_microseconds() + 5000; ////////////////////////////// //- rjf: iterate all tabs, touch their view-states @@ -12702,24 +12744,34 @@ rd_frame(void) rd_state->frame_di_scope = di_scope_open(); } + ////////////////////////////// + //- rjf: calculate avg length in us of last many frames + // + U64 frame_time_history_avg_us = 0; + { + U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); + U64 frame_time_history_sum_us = 0; + if(num_frames_in_history > 0) + { + for(U64 idx = 0; idx < num_frames_in_history; idx += 1) + { + frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; + } + frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; + } + } + ////////////////////////////// //- rjf: pick target hz // + // pick among a number of sensible targets to snap to, given how well + // we've been performing + // // TODO(rjf): maximize target, given all windows and their monitors + // F32 target_hz = os_get_gfx_info()->default_refresh_rate; if(rd_state->frame_index > 32) { - // rjf: calculate average frame time out of the last N - U64 num_frames_in_history = Min(ArrayCount(rd_state->frame_time_us_history), rd_state->frame_index); - U64 frame_time_history_sum_us = 0; - for(U64 idx = 0; idx < num_frames_in_history; idx += 1) - { - frame_time_history_sum_us += rd_state->frame_time_us_history[idx]; - } - U64 frame_time_history_avg_us = frame_time_history_sum_us/num_frames_in_history; - - // rjf: pick among a number of sensible targets to snap to, given how well - // we've been performing F32 possible_alternate_hz_targets[] = {target_hz, 60.f, 120.f, 144.f, 240.f}; F32 best_target_hz = target_hz; S64 best_target_hz_frame_time_us_diff = max_S64; @@ -12740,6 +12792,20 @@ rd_frame(void) target_hz = best_target_hz; } + ////////////////////////////// + //- rjf: given frame time history, decide on amount of time we're willing to wait for memory read results + // for evaluations + // + { + rd_state->frame_eval_memread_endt_us = 0; + U64 frame_time_target_cap_us = (U64)(1000000/target_hz); + if(frame_time_history_avg_us < frame_time_target_cap_us) + { + U64 spare_time = (frame_time_target_cap_us - frame_time_history_avg_us) + 4000; + rd_state->frame_eval_memread_endt_us = os_now_microseconds() + spare_time; + } + } + ////////////////////////////// //- rjf: target Hz -> delta time // @@ -13413,9 +13479,9 @@ rd_frame(void) e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); } - //- rjf: add macro for 'call_stack' -> 'current_thread.callstack' + //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' { - E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("current_thread.call_stack")).exprs.first; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).exprs.first; e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } @@ -14414,8 +14480,9 @@ rd_frame(void) //- rjf: files case RD_CmdKind_SetCurrentPath: { - arena_clear(rd_state->current_path_arena); - rd_state->current_path = push_str8_copy(rd_state->current_path_arena, rd_regs()->file_path); + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string_or_alloc(user, str8_lit("current_path")); + rd_cfg_new_replace(current_path, rd_regs()->file_path); }break; case RD_CmdKind_SetFileReplacementPath: { @@ -15872,7 +15939,19 @@ Z(getting_started) String8 initial_input = {0}; if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) { - initial_input = rd_state->current_path; + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); + String8 current_path_string = current_path->first->string; + if(current_path_string.size == 0) + { + current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + } + else + { + current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + } + initial_input = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = push_str8f(scratch.arena, "%S/", initial_input); } else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 2bd8628f..3a028c2d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -801,10 +801,6 @@ struct RD_State // rjf: icon texture R_Handle icon_texture; - // rjf: current path - Arena *current_path_arena; - String8 current_path; - // rjf: fixed ui keys UI_Key drop_completion_key; UI_Key ctx_menu_key; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 56d5ae16..1a478a1d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1367,14 +1367,25 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla }break; case E_ExprKind_MemberAccess: { - E_Eval row_eval = result.eval; - String8 member_name = e_string_from_expr(arena, notable_expr->last); + Temp scratch = scratch_begin(&arena, 1); + E_Member member = result.eval.irtree.member; + String8 member_name = member.name; + if(member.inheritance_key_chain.count != 0) + { + String8List strings = {0}; + for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) + { + String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); + str8_list_push(scratch.arena, &strings, base_class_name); + } + result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); + } B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); - if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || - row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - row_eval.space.kind == E_SpaceKind_File || - row_eval.space.kind == E_SpaceKind_FileSystem) + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + result.eval.space.kind == E_SpaceKind_File || + result.eval.space.kind == E_SpaceKind_FileSystem) { String8 fancy_name = rd_display_from_code_name(member_name); if(fancy_name.size != 0) @@ -1385,6 +1396,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } result.flags |= (!!is_non_code * RD_WatchCellFlag_IsNonCode); result.string = string; + scratch_end(scratch); }break; } } @@ -1520,8 +1532,24 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla }break; case RD_WatchCellKind_Eval: { - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - result.eval.value.u64 == 0) + if(result.eval.msgs.max_kind != E_MsgKind_Null) + { + Temp scratch = scratch_begin(&arena, 1); + result.flags |= RD_WatchCellFlag_IsErrored|RD_WatchCellFlag_IsNonCode; + String8List error_strings = {0}; + for(E_Msg *msg = result.eval.msgs.first; msg != 0; msg = msg->next) + { + str8_list_push(scratch.arena, &error_strings, msg->text); + if(msg->next) + { + str8_list_pushf(scratch.arena, &error_strings, " "); + } + } + result.string = str8_list_join(arena, &error_strings, 0); + scratch_end(scratch); + } + else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + result.eval.value.u64 == 0) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); From a3062dfeb1fb466ac3f36c83042184c9a31b1841 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 19:15:26 -0800 Subject: [PATCH 176/755] watch-window-defined/driven query lister completion --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 131 +++++++++++++++++++++++++---- src/raddbg/raddbg_views.h | 4 + 5 files changed, 125 insertions(+), 20 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index fbda345d..9dad2728 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[296] = +RD_VocabInfo rd_vocab_info_table[297] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -300,6 +300,7 @@ RD_VocabInfo rd_vocab_info_table[296] = {str8_lit_comp("push_lister"), str8_lit_comp(""), str8_lit_comp("Push Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("complete_lister"), str8_lit_comp(""), str8_lit_comp("Complete Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("cancel_lister"), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("update_lister"), str8_lit_comp(""), str8_lit_comp("Update Lister"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; @@ -364,7 +365,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[214] = +RD_CmdKindInfo rd_cmd_kind_info_table[215] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -578,6 +579,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("update_lister"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3261a8da..6a70cc3f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -265,6 +265,7 @@ RD_CmdKind_PickFileOrFolder, RD_CmdKind_PushQuery, RD_CmdKind_CompleteQuery, RD_CmdKind_CancelQuery, +RD_CmdKind_UpdateQuery, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, RD_CmdKind_COUNT, @@ -632,7 +633,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[296]; +extern RD_VocabInfo rd_vocab_info_table[297]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 58e3e47c..f3058905 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -613,6 +613,7 @@ RD_CmdTable: // | | | | {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } + {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_lister" "Update Lister" "Updates a query input." "" "" } //- rjf: developer commands {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d3071173..8401e40a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3759,6 +3759,7 @@ rd_view_ui(Rng2F32 rect) { is_first_frame = 1; ewv->initialized = 1; + ewv->filter_arena = rd_push_view_arena(); ewv->text_edit_arena = rd_push_view_arena(); } @@ -3774,6 +3775,19 @@ rd_view_ui(Rng2F32 rect) Vec4F32 pop_background_rgba = {0}; UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); + ////////////////////////////// + //- rjf: whenever the filter changes, we want to reset the cursor/mark state + // + if(!str8_match(filter, ewv->last_filter, 0)) + { + MemoryZeroStruct(&ewv->cursor); + MemoryZeroStruct(&ewv->mark); + MemoryZeroStruct(&ewv->next_cursor); + MemoryZeroStruct(&ewv->next_mark); + arena_clear(ewv->filter_arena); + ewv->last_filter = push_str8_copy(ewv->filter_arena, filter); + } + ////////////////////////////// //- rjf: decide if root should be implicit // @@ -3816,19 +3830,6 @@ rd_view_ui(Rng2F32 rect) } } - ////////////////////////////// - //- rjf: consume query-completion events, if this view is being used as a query - // -#if 0 - if(vs->query_is_selected && - ui_is_focus_active() && - ui_slot_press(UI_EventActionSlot_Accept)) - { - // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): - // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): // TODO(rjf): - } -#endif - ////////////////////////////// //- rjf: consume events & perform navigations/edits - calculate state // @@ -4026,6 +4027,75 @@ rd_view_ui(Rng2F32 rect) } B32 taken = 0; + ////////////////////////////// + //- rjf: consume query-completion events, if this view is being used as a query + // + { + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg && + evt->kind == UI_EventKind_Press && + evt->slot == UI_EventActionSlot_Accept && + selection_tbl.min.y == selection_tbl.max.y) + { + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 cmd_name = cmd->first->string; + + // rjf: if we have no selection, just pick the first row + EV_Row *row = 0; + if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); + } + + // rjf: if we do have a selection, compute that row + else + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); + } + + // rjf: use row to complete query + if(row != 0) + { + taken = 1; + E_Eval eval = e_eval_from_expr(scratch.arena, row->expr); + switch(eval.space.kind) + { + default: + { + String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); + rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); + }break; + case E_SpaceKind_File: + case E_SpaceKind_FileSystem: + { + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + String8 file = rd_file_path_from_eval(scratch.arena, eval); + if(str8_match(type->name, str8_lit("folder"), 0)) + { + String8 new_input_string = push_str8f(scratch.arena, "%S/", file); + rd_cmd(RD_CmdKind_UpdateQuery, .string = new_input_string); + } + else + { + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file); + } + }break; + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); + }break; + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = eval.value.u128.u64[0]; + rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); + }break; + } + } + } + } + ////////////////////////// //- rjf: begin editing on some operations // @@ -5376,8 +5446,16 @@ rd_view_ui(Rng2F32 rect) ui_kill_action(); } + // rjf: this watch window is being queried? -> move curosr & accept + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); + } + // rjf: has a command name? -> push command - if(cell_info.cmd_name.size != 0) + else if(cell_info.cmd_name.size != 0) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); @@ -5396,6 +5474,7 @@ rd_view_ui(Rng2F32 rect) // rjf: can edit? -> begin editing else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { + ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Edit); } @@ -5698,7 +5777,14 @@ rd_view_ui(Rng2F32 rect) } if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { - rd_cmd(RD_CmdKind_CompleteQuery); + String8 cmd_name = rd_view_query_cmd(); + String8 input = rd_view_query_input(); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + RD_RegsScope() + { + rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); + rd_cmd(RD_CmdKind_CompleteQuery); + } } } @@ -15840,6 +15926,8 @@ Z(getting_started) if(dst_tab == &rd_nil_cfg && dst_panel == panel_w_auto && view_w_auto != &rd_nil_cfg) { dst_tab = view_w_auto; + RD_ViewState *vs = rd_view_state_from_cfg(dst_tab); + vs->last_frame_index_built = 0; RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(dst_tab, str8_lit("expression")); rd_cfg_new_replace(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); } @@ -15985,11 +16073,9 @@ Z(getting_started) case RD_CmdKind_CompleteQuery: { String8 cmd_name = rd_view_query_cmd(); - String8 input = rd_view_query_input(); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); RD_RegsScope() { - rd_regs_fill_slot_from_string(cmd_kind_info->query.slot, input); rd_push_cmd(cmd_name, rd_regs()); } if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) @@ -16017,6 +16103,17 @@ Z(getting_started) ws->query_cmd_name = str8_zero(); } }break; + case RD_CmdKind_UpdateQuery: + { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + rd_cfg_new_replace(input, rd_regs()->string); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_cursor = vs->query_mark = txt_pt(1, rd_regs()->string.size+1); + vs->query_string_size = Min(sizeof(vs->query_buffer), rd_regs()->string.size); + MemoryCopy(vs->query_buffer, rd_regs()->string.str, vs->query_string_size); + }break; //- rjf: developer commands case RD_CmdKind_ToggleDevMenu: diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 5bc84acd..8f4b7570 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -190,6 +190,10 @@ struct RD_WatchViewState { B32 initialized; + // rjf: filter history + Arena *filter_arena; + String8 last_filter; + // rjf; table cursor state RD_WatchPt cursor; RD_WatchPt mark; From f753e9bd18f64566d4949c359aa7406f14ef4eb4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 19:20:09 -0800 Subject: [PATCH 177/755] small fix --- src/raddbg/raddbg_core.c | 70 +++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8401e40a..0e3c8dc2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9596,42 +9596,46 @@ rd_window_frame(void) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) - UI_Column { - if(panel->tab_side == Side_Max) + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *container = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "###add_new_tab"); + UI_Parent(container) { - ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); - } - else - { - ui_spacer(ui_px(1.f, 1.f)); - } - UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) - UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) - UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()) - UI_TagF("implicit") - UI_TagF("weak") - UI_HoverCursor(OS_Cursor_HandPoint) - { - UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_Clickable| - UI_BoxFlag_DisableTextTrunc, - "%S##add_new_tab_button_%p", - rd_icon_kind_text_table[RD_IconKind_Add], - panel->cfg); - UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) + if(panel->tab_side == Side_Max) { - rd_cmd(RD_CmdKind_FocusPanel); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f)); + } + else + { + ui_spacer(ui_px(1.f, 1.f)); + } + UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0) + UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0) + UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()) + UI_TagF("implicit") + UI_TagF("weak") + UI_HoverCursor(OS_Cursor_HandPoint) + { + UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableTextTrunc, + "%S##add_new_tab_button_%p", + rd_icon_kind_text_table[RD_IconKind_Add], + panel->cfg); + UI_Signal sig = ui_signal_from_box(add_new_box); + if(ui_clicked(sig)) + { + rd_cmd(RD_CmdKind_FocusPanel); + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + } } } } From 74ce085adc5e3fda7151cb7246ac8d7f2267ae48 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Feb 2025 19:59:26 -0800 Subject: [PATCH 178/755] start on new 'pull/pop out' button for visualizers --- src/raddbg/raddbg_core.c | 26 ++++++++++++++++++++++++++ src/raddbg/raddbg_views.c | 4 ++-- src/raddbg/raddbg_widgets.c | 8 ++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0e3c8dc2..db44095c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5247,6 +5247,32 @@ rd_view_ui(Rng2F32 rect) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) UI_Flags(0) { + // rjf: 'pull out' button + UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) + UI_CornerRadius(ui_top_font_size()*1.5f) + UI_TextAlignment(UI_TextAlign_Center) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Font(RD_FontSlot_Icons) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Floating| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects, + "%S###pull_out", + rd_icon_kind_text_table[RD_IconKind_Window]); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) + { + rd_drag_begin(RD_RegSlot_View); + } + } + // rjf: loading animation container UI_Box *loading_overlay_container = &ui_nil_box; UI_Parent(box) UI_WidthFill UI_HeightFill diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 1a478a1d..9fd3b210 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2982,9 +2982,9 @@ internal UI_BOX_CUSTOM_DRAW(rd_bitmap_view_canvas_box_draw) F32 grid_cell_size_cvs = box->font_size*10.f; F32 grid_line_thickness_px = Max(2.f, box->font_size*0.1f); Vec4F32 grid_line_color = {0}; - UI_TagF("alt") + UI_TagF("weak") { - grid_line_color = ui_color_from_name(str8_lit("background")); + grid_line_color = ui_color_from_name(str8_lit("text")); } for EachEnumVal(Axis2, axis) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 253dcd91..6717155d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -56,7 +56,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) if(expr_string.size != 0) { String8 query_name = rd_query_from_eval_string(arena, expr_string); - if(query_name.size != 0 && !str8_match(query_name, str8_lit("watches"), 0)) + if(query_name.size != 0) { String8 query_code_name = query_name; String8 query_display_name = rd_display_from_code_name(query_code_name); @@ -65,6 +65,10 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) { query_code_name = rd_singular_from_code_name_plural(query_name); collection_name = rd_display_plural_from_code_name(query_code_name); + if(str8_match(collection_name, str8_lit("Watches"), 0)) + { + collection_name = str8_lit("Watch"); + } } RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); if(query_icon_kind != RD_IconKind_Null) @@ -234,7 +238,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } //- rjf: cfg has expression attached -> use that - else if(expr_string.size != 0 && !is_within_window) + else if(expr_string.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, expr_string, .font = rd_font_from_slot(RD_FontSlot_Code), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code)); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); From 8d9f85bfccb0330f264a3876d6124bcd8431ba09 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 31 Jan 2025 13:25:12 -0800 Subject: [PATCH 179/755] move magic check to PE layer --- src/pe/pe.c | 14 ++++++++++++++ src/pe/pe.h | 1 + src/raddump/raddump.c | 10 +--------- src/raddump/raddump.h | 1 - src/raddump/raddump_main.c | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/pe/pe.c b/src/pe/pe.c index b823bbbf..3726df0c 100644 --- a/src/pe/pe.c +++ b/src/pe/pe.c @@ -408,6 +408,20 @@ pe_subsystem_from_string(String8 string) //////////////////////////////// //~ rjf: Parser Functions +internal B32 +pe_check_magic(String8 data) +{ + B32 is_pe = 0; + PE_DosHeader dos_header = {0}; + str8_deserial_read_struct(data, 0, &dos_header); + if (dos_header.magic == PE_DOS_MAGIC) { + U32 pe_magic = 0; + str8_deserial_read_struct(data, dos_header.coff_file_offset, &pe_magic); + is_pe= pe_magic == PE_MAGIC; + } + return is_pe; +} + internal PE_BinInfo pe_bin_info_from_data(Arena *arena, String8 data) { diff --git a/src/pe/pe.h b/src/pe/pe.h index c6e40254..8ff6a741 100644 --- a/src/pe/pe.h +++ b/src/pe/pe.h @@ -1072,6 +1072,7 @@ internal String8 pe_string_from_dll_characteristics(Arena *arena, PE_DllCharacte //////////////////////////////// //~ rjf: Parser Functions +internal B32 pe_check_magic(String8 data); internal PE_BinInfo pe_bin_info_from_data(Arena *arena, String8 data); internal PE_DebugInfoList pe_parse_debug_directory(Arena *arena, String8 raw_image, String8 raw_debug_dir); diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 479ffe1e..0af1b6e1 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -214,14 +214,6 @@ rd_format_line_from_voff(Arena *arena, RDI_Parsed *rdi, U64 voff, PathStyle path return result; } -internal B32 -rd_is_pe(String8 raw_data) -{ - PE_DosHeader header = {0}; - str8_deserial_read_struct(raw_data, 0, &header); - return header.magic == PE_DOS_MAGIC; -} - internal B32 rd_is_rdi(String8 raw_data) { @@ -316,7 +308,7 @@ rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input input_type_string = "Big Obj"; } else if (coff_is_obj(raw_data)) { input_type_string = "Obj"; - } else if (rd_is_pe(raw_data)) { + } else if (pe_check_magic(raw_data)) { input_type_string = "COFF/PE"; } else if (rd_is_rdi(raw_data)) { input_type_string = "RDI"; diff --git a/src/raddump/raddump.h b/src/raddump/raddump.h index 16e074db..37a2c360 100644 --- a/src/raddump/raddump.h +++ b/src/raddump/raddump.h @@ -140,7 +140,6 @@ typedef struct RD_Line // raddump -internal B32 rd_is_pe (String8 raw_data); internal B32 rd_is_rdi(String8 raw_data); internal String8 rd_string_from_flags(Arena *arena, String8List list, U64 remaining_flags); diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index 98888163..48b48b1b 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -269,7 +269,7 @@ entry_point(CmdLine *cmdline) coff_print_big_obj(arena, out, indent, raw_data, opts); } else if (coff_is_obj(raw_data)) { coff_print_obj(arena, out, indent, raw_data, opts); - } else if (rd_is_pe(raw_data)) { + } else if (pe_check_magic(raw_data)) { RDI_Parsed *rdi = 0; if (!(opts & RD_Option_NoRdi)) { rdi = rd_rdi_from_pe(arena, file_path, raw_data); From ea6a84ca578f155dcbaacade8a1e4357f0fa1a8c Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 31 Jan 2025 13:26:33 -0800 Subject: [PATCH 180/755] helper for extracting DWARF sections in COFF files --- src/dwarf/dwarf_coff.c | 7 ++++++ src/dwarf/dwarf_coff.h | 45 ++++++++++++++++++++++++++++++++++++++ src/raddump/raddump.c | 45 ++------------------------------------ src/raddump/raddump_main.c | 2 ++ 4 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 src/dwarf/dwarf_coff.c create mode 100644 src/dwarf/dwarf_coff.h diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c new file mode 100644 index 00000000..942ca306 --- /dev/null +++ b/src/dwarf/dwarf_coff.c @@ -0,0 +1,7 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#pragma once + +internal DW_SectionArray dw_sections_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); + diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h new file mode 100644 index 00000000..368bff78 --- /dev/null +++ b/src/dwarf/dwarf_coff.h @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal DW_SectionArray +dw_sections_from_coff_section_table(Arena *arena, + String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + DW_SectionArray result = {0}; + B32 sect_status[ArrayCount(result.v)] = {0}; + + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = §ions[i]; + Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); + String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + + DW_SectionKind s = DW_Section_Null; + B32 is_dwo = 0; + #define X(_K,_L,_M,_W) \ + if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } + DW_SectionKind_XList(X) + #undef X + + if (s != DW_Section_Null) { + if (sect_status[s]) { + Assert(!"too many debug sections with identical name, picking first"); + } else { + sect_status[s] = 1; + DW_Section *d = &result.v[s]; + d->name = push_str8_copy(arena, name); + d->data = str8_substr(raw_image, raw_data_range); + d->mode = dim_1u64(raw_data_range) > max_U32 ? DW_Mode_64Bit : DW_Mode_32Bit; + d->is_dwo = is_dwo; + } + } + } + + return result; +} + + diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 0af1b6e1..15566eed 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -474,47 +474,6 @@ rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 st return result; } -internal DW_SectionArray -rd_dw_sections_from_coff_section_table(Arena *arena, - String8 raw_image, - U64 string_table_off, - U64 section_count, - COFF_SectionHeader *sections) -{ - DW_SectionArray result = {0}; - B32 sect_status[ArrayCount(result.v)] = {0}; - - for (U64 i = 0; i < section_count; ++i) { - COFF_SectionHeader *header = §ions[i]; - Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); - String8 name = coff_name_from_section_header(raw_image, header, string_table_off); - - DW_SectionKind s = DW_Section_Null; - B32 is_dwo = 0; - #define X(_K,_L,_M,_W) \ - if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } - DW_SectionKind_XList(X) - #undef X - - if (s != DW_Section_Null) { - if (sect_status[s]) { - rd_warningf("file contains multiple %S sections, picking first", name); - } else { - sect_status[s] = 1; - DW_Section *d = &result.v[s]; - d->name = push_str8_copy(arena, name); - d->data = str8_substr(raw_image, raw_data_range); - d->mode = dim_1u64(raw_data_range) > max_U32 ? DW_Mode_64Bit : DW_Mode_32Bit; - d->is_dwo = is_dwo; - } - } - } - - return result; -} - internal RD_DisasmResult rd_disasm_next_instruction(Arena *arena, Arch arch, U64 addr, String8 raw_code) { @@ -6210,7 +6169,7 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); + DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); } @@ -7952,7 +7911,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); + DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); } diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index 48b48b1b..ef0a3b6a 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -44,6 +44,7 @@ #include "dwarf/dwarf_parse.h" #include "dwarf/dwarf_expr.h" #include "dwarf/dwarf_unwind.h" +#include "dwarf/dwarf_coff.h" #include "dwarf/dwarf_enum.h" #include "base/base_inc.c" @@ -70,6 +71,7 @@ #include "dwarf/dwarf_parse.c" #include "dwarf/dwarf_expr.c" #include "dwarf/dwarf_unwind.c" +#include "dwarf/dwarf_coff.c" #include "dwarf/dwarf_enum.c" #include "linker/base_ext/base_inc.h" From 87ae36329243ada43bce18bd7d854f448e952c79 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 31 Jan 2025 13:28:09 -0800 Subject: [PATCH 181/755] print file path in DW_Attrib_DeclFile --- src/raddump/raddump.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 15566eed..09cfba11 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -2160,6 +2160,18 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr rd_printf("Tags Range: %#llx-%#llx (Size %#llx)", comp_root.tags_info_range.min, comp_root.tags_info_range.max, dim_1u64(comp_root.tags_info_range)); rd_newline(); + DW_LineVMHeader vm_header = {0}; + dw_read_line_vm_header(comp_temp.arena, + dw_base_from_sec(sections, DW_Section_Line), + dw_range_from_sec(sections, DW_Section_Line), + comp_root.line_off, + dw_mode_from_sec(sections, DW_Section_Line), + sections, + resolve_params, + comp_root.compile_dir, + comp_root.name, + &vm_header); + // prase tags U32 tag_depth = 0; for (U64 info_off = comp_root.tags_info_range.min; info_off < comp_root.tags_info_range.max; /* empty */) { @@ -2218,12 +2230,28 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx %#llx", attrib_value.v[0], attrib_value.v[1]); } break; case DW_AttribClass_Const: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); switch (attrib->attrib_kind) { case DW_Attrib_Language: { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + String8 lang_str = dw_string_from_language(attrib_temp.arena, attrib_value.v[0]); str8_list_pushf(attrib_temp.arena, &attrib_list, " (%S)", lang_str); } break; + case DW_Attrib_DeclFile: { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu", attrib_value.v[0]); + + String8 path = str8_lit("\?\?\?"); + if (attrib_value.v[0] < vm_header.file_table.count) { + path = dw_path_from_file_idx(attrib_temp.arena, &vm_header, attrib_value.v[0]); + } + str8_list_pushf(attrib_temp.arena, &attrib_list, " (%S)", path); + } break; + case DW_Attrib_DeclLine: { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu", attrib_value.v[0]); + } break; + default: { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + } break; } } break; case DW_AttribClass_ExprLoc: { From b74c304f3971c262398d247bd1a1ae2dedbe33a3 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 7 Feb 2025 16:30:17 -0800 Subject: [PATCH 182/755] added ELF header and parser --- src/elf/elf.c | 143 +++++++ src/elf/elf.h | 992 ++++++++++++++++++++++++++++++++++++++++++++ src/elf/elf_parse.c | 90 ++++ src/elf/elf_parse.h | 29 ++ 4 files changed, 1254 insertions(+) create mode 100644 src/elf/elf.c create mode 100644 src/elf/elf.h create mode 100644 src/elf/elf_parse.c create mode 100644 src/elf/elf_parse.h diff --git a/src/elf/elf.c b/src/elf/elf.c new file mode 100644 index 00000000..1a094baa --- /dev/null +++ b/src/elf/elf.c @@ -0,0 +1,143 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: 32 => 64 bit conversions + +internal ELF_Hdr64 +elf_hdr64_from_hdr32(ELF_Hdr32 h32) +{ + ELF_Hdr64 h64 = {0}; + MemoryCopy(h64.e_ident, h32.e_ident, sizeof(h64.e_ident)); + h64.e_type = h32.e_type; + h64.e_machine = h32.e_machine; + h64.e_version = h32.e_version; + h64.e_entry = (U64)h32.e_entry; + h64.e_phoff = (U64)h32.e_phoff; + h64.e_shoff = (U64)h32.e_shoff; + h64.e_flags = h32.e_flags; + h64.e_ehsize = h32.e_ehsize; + h64.e_phentsize = h32.e_phentsize; + h64.e_phnum = h32.e_phnum; + h64.e_shentsize = h32.e_shentsize; + h64.e_shnum = h32.e_shnum; + h64.e_shstrndx = h32.e_shstrndx; + return h64; +} + +internal ELF_Shdr64 +elf_shdr64_from_shdr32(ELF_Shdr32 h32) +{ + ELF_Shdr64 h64 = {0}; + h64.sh_name = h32.sh_name; + h64.sh_type = h32.sh_type; + h64.sh_flags = (U64)h32.sh_flags; + h64.sh_addr = (U64)h32.sh_addr; + h64.sh_offset = (U64)h32.sh_offset; + h64.sh_size = (U64)h32.sh_size; + h64.sh_link = h32.sh_link; + h64.sh_info = h32.sh_info; + h64.sh_addralign = (U64)h32.sh_addralign; + h64.sh_entsize = (U64)h32.sh_entsize; + return h64; +} + +internal ELF_Phdr64 +elf_phdr64_from_phdr32(ELF_Phdr32 h32) +{ + ELF_Phdr64 h64 = {0}; + h64.p_type = h32.p_type; + h64.p_flags = h32.p_flags; + h64.p_offset = (U64)h32.p_offset; + h64.p_vaddr = (U64)h32.p_vaddr; + h64.p_paddr = (U64)h32.p_paddr; + h64.p_filesz = (U64)h32.p_filesz; + h64.p_memsz = (U64)h32.p_memsz; + h64.p_align = (U64)h32.p_align; + return h64; +} + +internal ELF_Dyn64 +elf_dyn64_from_dyn32(ELF_Dyn32 h32) +{ + ELF_Dyn64 h64 = {0}; + h64.tag = (U64)h32.tag; + h64.val = (U64)h32.val; + return h64; +} + +internal ELF_Sym64 +elf_sym64_from_sym32(ELF_Sym32 sym32) +{ + ELF_Sym64 sym64 = {0}; + sym64.st_name = sym32.st_name; + sym64.st_value = sym32.st_value; + sym64.st_size = sym32.st_size; + sym64.st_info = sym32.st_info; + sym64.st_other = sym32.st_other; + sym64.st_shndx = sym32.st_shndx; + return sym64; +} + +internal ELF_Rel64 +elf_rel64_from_rel32(ELF_Rel32 rel32) +{ + U32 sym = SYMS_ELF32_R_SYM(rel32.r_info); + U32 type = SYMS_ELF32_R_TYPE(rel32.r_info); + ELF_Rel64 rel64 = {0}; + rel64.r_info = SYMS_ELF64_R_INFO(sym, type); + rel64.r_offset = rel32.r_offset; + return rel64; +} + +internal ELF_Rela64 +elf_rela64_from_rela32(ELF_Rela32 rela32) +{ + U32 sym = SYMS_ELF32_R_SYM(rela32.r_info); + U32 type = SYMS_ELF32_R_TYPE(rela32.r_info); + ELF_Rela64 rela64 = {0}; + rela64.r_offset = rela32.r_info; + rela64.r_info = SYMS_ELF64_R_INFO(sym, type); + rela64.r_addend = rela32.r_addend; + return rela64; +} + +internal ELF_Chdr64 +elf_chdr64_from_chdr32(ELF_Chdr32 chdr32) +{ + ELF_Chdr64 chdr64 = {0}; + chdr64.ch_type = chdr32.ch_type; + chdr64.ch_size = chdr32.ch_size; + chdr64.ch_addr_align = chdr32.ch_addr_align; + return chdr64; +} + +//////////////////////////////// + +internal String8 +elf_string_from_class(Arena *arena, ELF_Class v) +{ + switch (v) { + case ELF_Class_None: return str8_lit("None"); + case ELF_Class_32: return str8_lit("32Bit"); + case ELF_Class_64: return str8_lit("64Bit"); + } + return push_str8f(arena, "%#x", v); +} + +//////////////////////////////// + +internal Arch +arch_from_elf_machine(ELF_MachineKind e_machine) +{ + Arch arch = Arch_Null; + switch (e_machine) { + case ELF_MachineKind_None: arch = Arch_Null; break; + case ELF_MachineKind_AARCH64: arch = Arch_arm32; break; + case ELF_MachineKind_ARM: arch = Arch_arm32; break; + case ELF_MachineKind_386: arch = Arch_x86; break; + case ELF_MachineKind_X86_64: arch = Arch_x64; break; + default: NotImplemented; break; + } + return arch; +} diff --git a/src/elf/elf.h b/src/elf/elf.h new file mode 100644 index 00000000..2ee63aa3 --- /dev/null +++ b/src/elf/elf.h @@ -0,0 +1,992 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef ELF_H +#define ELF_H + +typedef U8 ELF_Class; +enum +{ + ELF_Class_None = 0, + ELF_Class_32 = 1, + ELF_Class_64 = 2, + ELF_Class_Count = 3 +}; + +typedef U8 ELF_OsAbi; +enum +{ + ELF_OsAbi_None, + ELF_OsAbi_SYSV, + ELF_OsAbi_HPUX, + ELF_OsAbi_NETBSD, + ELF_OsAbi_GNU, + ELF_OsAbi_LINUX, + ELF_OsAbi_SOLARIS, + ELF_OsAbi_IRIX, + ELF_OsAbi_FREEBSD, + ELF_OsAbi_TRU64, + ELF_OsAbi_ARM = 97, + ELF_OsAbi_STANDALONE = 255, +}; + +typedef U8 ELF_Version; +enum +{ + ELF_Version_None, + ELF_Version_Current, +}; + +typedef U16 ELF_MachineKind; +enum +{ + ELF_MachineKind_None = 0, + ELF_MachineKind_M32 = 1, + ELF_MachineKind_SPARC = 2, + ELF_MachineKind_386 = 3, + ELF_MachineKind_68K = 4, + ELF_MachineKind_88K = 5, + ELF_MachineKind_IAMCU = 6, + ELF_MachineKind_860 = 7, + ELF_MachineKind_MIPS = 8, + ELF_MachineKind_S370 = 9, + ELF_MachineKind_MIPS_RS3_LE = 10, + // 11-14 reserved + ELF_MachineKind_PARISC = 15, + // 16 reserved + ELF_MachineKind_VPP500 = 17, + ELF_MachineKind_SPARC32PLUS = 18, + // nick: Sun's "v8plus" + ELF_MachineKind_INTEL960 = 19, + ELF_MachineKind_PPC = 20, + ELF_MachineKind_PPC64 = 21, + ELF_MachineKind_S390 = 22, + ELF_MachineKind_SPU = 23, + // 24-35 reserved + ELF_MachineKind_V800 = 36, + ELF_MachineKind_FR20 = 37, + ELF_MachineKind_RH32 = 38, + ELF_MachineKind_MCORE = 39, + ELF_MachineKind_ARM = 40, + ELF_MachineKind_SH = 42, + ELF_MachineKind_ALPHA = 41, + ELF_MachineKind_SPARCV9 = 43, + ELF_MachineKind_TRICORE = 44, + ELF_MachineKind_ARC = 45, + ELF_MachineKind_H8_300 = 46, + ELF_MachineKind_H8_300H = 47, + ELF_MachineKind_H8S = 48, + ELF_MachineKind_H8_500 = 49, + ELF_MachineKind_IA_64 = 50, + ELF_MachineKind_MIPS_X = 51, + ELF_MachineKind_COLDFILE = 52, + ELF_MachineKind_68HC12 = 53, + ELF_MachineKind_MMA = 54, + ELF_MachineKind_PCP = 55, + ELF_MachineKind_NCPU = 56, + ELF_MachineKind_NDR1 = 57, + ELF_MachineKind_STARCORE = 58, + ELF_MachineKind_ME16 = 59, + ELF_MachineKind_ST100 = 60, + ELF_MachineKind_TINYJ = 61, + ELF_MachineKind_X86_64 = 62, + ELF_MachineKind_AARCH64 = 183, + ELF_MachineKind_TI_C6000 = 140, + ELF_MachineKind_L1OM = 180, + ELF_MachineKind_K1OM = 181, + ELF_MachineKind_RISCV = 243, + ELF_MachineKind_S390_OLD = 0xA390, +}; + +typedef U16 ELF_Type; +enum +{ + ELF_Type_None, + ELF_Type_Rel, + ELF_Type_Exec, + ELF_Type_Dyn, + ELF_Type_Core, +}; + +typedef U8 ELF_Data; +enum +{ + ELF_Data_None = 0, + ELF_Data_2LSB = 1, + ELF_Data_2MSB = 2, +}; + +typedef U32 ELF_PType; +enum +{ + ELF_PType_Null = 0, + ELF_PType_Load = 1, + ELF_PType_Dynamic = 2, + ELF_PType_Interp = 3, + ELF_PType_Note = 4, + ELF_PType_ShLib = 5, + ELF_PType_PHdr = 6, + ELF_PType_Tls = 7, + ELF_PType_LoOs = 0x60000000, + ELF_PType_HiOs = 0x6fffffff, + + ELF_PType_LowProc = 0x70000000, + ELF_PType_HighProc = 0x7fffffff, + + // specific to Sun + ELF_PType_LowSunW = 0x6ffffffa, + ELF_PType_SunWBSS = 0x6ffffffb, + ELF_PType_GnuEHFrame = 0x6474E550, + + ELF_PType_GnuStack = ELF_PType_LoOs + 0x474e550, // frame unwind information + ELF_PType_GnuRelro = ELF_PType_LoOs + 0x474e551, // stack flags + ELF_PType_GnuProperty = ELF_PType_LoOs + 0x474e552, // read-only after relocations + ELF_PType_SunEHFrame = ELF_PType_GnuEHFrame, +}; + +typedef U32 ELF_PFlag; +enum +{ + ELF_PFlag_Exec = (1 << 0), + ELF_PFlag_Write = (1 << 1), + ELF_PFlag_Read = (1 << 2), +}; + +typedef U32 ELF_SectionCode; +enum +{ + ELF_SectionCode_Null = 0, + ELF_SectionCode_ProgBits = 1, + ELF_SectionCode_Symtab = 2, + ELF_SectionCode_Strtab = 3, + ELF_SectionCode_Rela = 4, + ELF_SectionCode_Hash = 5, + ELF_SectionCode_Dynamic = 6, + ELF_SectionCode_Note = 7, + ELF_SectionCode_NoBits = 8, + ELF_SectionCode_Rel = 9, + ELF_SectionCode_Shlib = 10, + ELF_SectionCode_Dynsym = 11, + ELF_SectionCode_InitArray = 14, + ELF_SectionCode_FiniArray = 15, // Array of ptrs to init functions + ELF_SectionCode_PreinitArray = 16, // Array of ptrs to finish functions + ELF_SectionCode_Group = 17, // Array of ptrs to pre-init funcs + ELF_SectionCode_SymtabShndx = 18, // Section contains a section group + ELF_SectionCode_GNU_IncrementalInputs = 0x6fff4700, // Indices for SHN_XINDEX entries + ELF_SectionCode_GNU_Attributes = 0x6ffffff5, // Incremental build data + ELF_SectionCode_GNU_Hash = 0x6ffffff6, // Object attributes + ELF_SectionCode_GNU_LibList = 0x6ffffff7, // GNU style symbol hash table + ELF_SectionCode_SUNW_verdef = 0x6ffffffd, + ELF_SectionCode_SUNW_verneed = 0x6ffffffe, // Versions defined by file + ELF_SectionCode_SUNW_versym = 0x6fffffff, // Versions needed by file + + // Symbol versions + ELF_SectionCode_GNU_verdef = ELF_SectionCode_SUNW_verdef, + ELF_SectionCode_GNU_verneed = ELF_SectionCode_SUNW_verneed, + ELF_SectionCode_GNU_versym = ELF_SectionCode_SUNW_versym, + ELF_SectionCode_Proc, + ELF_SectionCode_User, +}; + +typedef U32 ELF_SectionIndex; +enum +{ + + ELF_SectionIndex_Undef = 0, // Symbol with section index is undefined and must be resolved by the link editor + ELF_SectionIndex_Abs = 0xfff1, // Symbol has absolute value and wont change after relocations + ELF_SectionIndex_Common = 0xfff2, // This symbol indicates to linker to allocate the storage at address multiple of st_value + + ELF_SectionIndex_LoReserve = 0xff00, + ELF_SectionIndex_HiReserve = 0xffff, + + // Processor specific + ELF_SectionIndex_LoProc = ELF_SectionIndex_LoReserve, + ELF_SectionIndex_HiProc = 0xff1f, + + // Reserved for OS + ELF_SectionIndex_LoOs = 0xff20, + ELF_SectionIndex_HiOs = 0xff3f, + + ELF_SectionIndex_IA64_ASNI_Common = ELF_SectionIndex_LoProc, + ELF_SectionIndex_X8664_LCommon = 0xff02, + ELF_SectionIndex_MIPS_SCommon = 0xff03, + + ELF_SectionIndex_TIC6X_Common = ELF_SectionIndex_LoReserve, + ELF_SectionIndex_MIPS_SUndefined = 0xff04, +}; + +typedef U32 ELF_SectionFlag; +enum +{ + ELF_Shf_Write = (1 << 0), + ELF_Shf_Alloc = (1 << 1), + ELF_Shf_ExecInstr = (1 << 2), + ELF_Shf_Merge = (1 << 4), + ELF_Shf_Strings = (1 << 5), + ELF_Shf_InfoLink = (1 << 6), + ELF_Shf_LinkOrder = (1 << 7), + ELF_Shf_OsNonConforming = (1 << 8), + ELF_Shf_Group = (1 << 9), + ELF_Shf_Tls = (1 << 10), + ELF_Shf_Compressed = (1 << 11), + ELF_Shf_MaskOs_Shift = 16, ELF_Shf_MaskOs_Mask = 0xff, + ELF_Shf_AMD64Large = (1 << 28), + ELF_Shf_Ordered = (1 << 30), + ELF_Shf_Exclude = (1 << 31), + ELF_Shf_MaskProc_Shift = 28, ELF_Shf_MaskProc_Mask = 0xf, +}; + +#define ELF_SectionFlag_Extract_MaskOs(f) (U8)(((f) >> ELF_SectionFlag_MaskOs_Shift) & ELF_SectionFlag_MaskOs_Mask) +#define ELF_SectionFlag_Extract_MaskProc(f) (U8)(((f) >> ELF_SectionFlag_MaskProc_shift) & ELF_SectionFlag_MaskProc_Mask) +typedef U32 ELF_AuxType; +enum +{ + ELF_AuxType_Null = 0, + ELF_AuxType_Phdr = 3, // program headers + ELF_AuxType_Phent = 4, // size of a program header + ELF_AuxType_Phnum = 5, // number of program headers + ELF_AuxType_Pagesz = 6, // system page size + ELF_AuxType_Base = 7, // interpreter base address + ELF_AuxType_Flags = 8, + ELF_AuxType_Entry = 9, // program entry point + ELF_AuxType_Uid = 11, + ELF_AuxType_Euid = 12, + ELF_AuxType_Gid = 13, + ELF_AuxType_Egid = 14, + ELF_AuxType_Platform = 15, + ELF_AuxType_Hwcap = 16, + ELF_AuxType_Clktck = 17, + ELF_AuxType_DCacheBSize = 19, + ELF_AuxType_ICacheBSize = 20, + ELF_AuxType_UCacheBSize = 21, + ELF_AuxType_IgnorePPC = 22, + ELF_AuxType_Secure = 23, + ELF_AuxType_BasePlatform = 24, + ELF_AuxType_Random = 25, + ELF_AuxType_Hwcap2 = 26, // addres to 16 random bytes + ELF_AuxType_ExecFn = 31, + ELF_AuxType_SysInfo = 32, // file name of executable + ELF_AuxType_SysInfoEhdr = 33, + ELF_AuxType_L1I_CacheSize = 40, + ELF_AuxType_L1I_CacheGeometry = 41, + ELF_AuxType_L1D_CacheSize = 42, + ELF_AuxType_L1D_CacheGeometry = 43, + ELF_AuxType_L2_CacheSize = 44, + ELF_AuxType_L2_CacheGeometry = 45, + ELF_AuxType_L3_CacheSize = 46, + ELF_AuxType_L3_CacheGeometry = 47, +}; + +typedef U32 ELF_DynTag; +enum +{ + ELF_DynTag_Null = 0, + + ELF_DynTag_Needed = 1, + ELF_DynTag_PltRelsz = 2, + ELF_DynTag_PltGot = 3, + ELF_DynTag_Hash = 4, + ELF_DynTag_Strtab = 5, + ELF_DynTag_Symtab = 6, + ELF_DynTag_Rela = 7, + ELF_DynTag_Relasz = 8, + ELF_DynTag_Relaent = 9, + ELF_DynTag_Strsz = 10, + ELF_DynTag_Syment = 11, + ELF_DynTag_Init = 12, + ELF_DynTag_Fini = 13, + ELF_DynTag_SoName = 14, + ELF_DynTag_RPath = 15, + ELF_DynTag_Symbolic = 16, + ELF_DynTag_Rel = 17, + ELF_DynTag_Relsz = 18, + ELF_DynTag_Relent = 19, + ELF_DynTag_Pltrel = 20, + ELF_DynTag_Debug = 21, + ELF_DynTag_TextRel = 22, + ELF_DynTag_JmpRel = 23, + ELF_DynTag_BindNow = 24, + ELF_DynTag_InitArray = 25, + ELF_DynTag_FiniArray = 26, + ELF_DynTag_InitArraysz = 27, + ELF_DynTag_FIniArraysz = 28, + ELF_DynTag_RunPath = 29, + ELF_DynTag_Flags = 30, + ELF_DynTag_PreInitArray = 32, + ELF_DynTag_PreInitArraysz = 33, + ELF_DynTag_SymtabShndx = 34, + + ELF_DynTag_LoOs = 0x6000000D, + ELF_DynTag_HiOs = 0x6ffff000, + + ELF_DynTag_ValRngLo = 0x6ffffd00, + ELF_DynTag_GNU_PreLinked = 0x6ffffdf5, + ELF_DynTag_GNU_Conflictsz = 0x6ffffdf6, + ELF_DynTag_GNU_LibListsz = 0x6ffffdf7, + ELF_DynTag_Checksum = 0x6ffffdf8, + ELF_DynTag_Pltpadsz = 0x6ffffdf9, + ELF_DynTag_Moveent = 0x6ffffdfa, + ELF_DynTag_Movesz = 0x6ffffdfb, + ELF_DynTag_Feature = 0x6ffffdfc, + ELF_DynTag_PosFlag_1 = 0x6ffffdfd, + ELF_DynTag_SymInSz = 0x6ffffdfe, + ELF_DynTag_SymInEnt = 0x6ffffdff, + ELF_DynTag_ValRngHi = ELF_DynTag_SymInEnt, + + ELF_DynTag_AddrRngLo = 0x6ffffe00, + ELF_DynTag_GNU_Hash = 0x6ffffef5, + ELF_DynTag_TlsDescPlt = 0x6ffffef6, + ELF_DynTag_TlsDescGot = 0x6ffffef7, + ELF_DynTag_GNU_Conflict = 0x6ffffef8, + ELF_DynTag_GNU_LibList = 0x6ffffef9, + ELF_DynTag_Config = 0x6ffffefa, + ELF_DynTag_DepAudit = 0x6ffffefb, + ELF_DynTag_Audit = 0x6ffffefc, + ELF_DynTag_PltPad = 0x6ffffefd, + ELF_DynTag_MoveTab = 0x6ffffefe, + ELF_DynTag_SymInfo = 0x6ffffeff, + ELF_DynTag_AddrRngHi = ELF_DynTag_SymInfo, + + ELF_DynTag_RelaCount = 0x6ffffff9, + ELF_DynTag_RelCount = 0x6ffffffa, + ELF_DynTag_Flags_1 = 0x6ffffffb, + ELF_DynTag_VerDef = 0x6ffffffc, + ELF_DynTag_VerDefNum = 0x6ffffffd, + ELF_DynTag_VerNeed = 0x6ffffffe, + ELF_DynTag_VerNeedNum = 0x6fffffff, + ELF_DynTag_VerSym = 0x6ffffff0, + ELF_DynTag_LoProc = 0x70000000, + ELF_DynTag_HiProc = 0x7fffffff, +}; + +typedef U32 ELF_DynFlag; +enum +{ + ELF_DynFlag_Origin = (1 << 0), + ELF_DynFlag_Symbolic = (1 << 1), + ELF_DynFlag_TextTel = (1 << 2), + ELF_DynFlag_BindNow = (1 << 3), + ELF_DynFlag_StaticTls = (1 << 4), +}; + +typedef U32 ELF_DynFeatureFlag; +enum +{ + ELF_DynFeatureFlag_ParInit = (1 << 0), + ELF_DynFeatureFlag_ConfExp = (1 << 1), +}; + +typedef U8 ELF_SymBind; +enum +{ + // the same name may exists in multiple files without interfering with each other. + ELF_SymBind_Local = 0, + // Visible to all objects that are linked together. + ELF_SymBind_Global = 1, + // If there is a global symbol with identical name linker doesn't issue an error. + ELF_SymBind_Weak = 2, + ELF_SymBind_LoProc = 13, + ELF_SymBind_HiProc = 15, +}; + +typedef U8 ELF_SymType; +enum +{ + ELF_SymType_NoType = 0, + // Type is not specified. + ELF_SymType_Object = 1, + // Symbol is associated with data object, such as a variable, an array, etc. + ELF_SymType_Func = 2, + // Symbol is associated with a function. + ELF_SymType_Section = 3, + // Symbol is used to relocate sections and normally have LOCAL binding. + ELF_SymType_File = 4, + // Gives name of the source file associated with object. + ELF_SymType_Common = 5, + ELF_SymType_Tls = 6, + ELF_SymType_LoProc = 13, + ELF_SymType_HiProc = 15, +}; + +typedef U8 ELF_SymVisibility; +enum +{ + ELF_SymVisibility_Default = 0, + ELF_SymVisibility_Internal = 1, + ELF_SymVisibility_Hidden = 2, + ELF_SymVisibility_Protected = 3, +}; + +typedef U32 ELF_RelocI386; +enum +{ + ELF_RelocI386_None = 0, + ELF_RelocI386_32 = 1, + ELF_RelocI386_PC32 = 2, + ELF_RelocI386_GOT32 = 3, + ELF_RelocI386_PLT32 = 4, + ELF_RelocI386_Copy = 5, + ELF_RelocI386_GlobDat = 6, + ELF_RelocI386_JumpSlot = 7, + ELF_RelocI386_Relative = 8, + ELF_RelocI386_GotOff = 9, + ELF_RelocI386_GotPc = 10, + ELF_RelocI386_32Plt = 11, + ELF_RelocI386_Tls_tpoff = 14, + ELF_RelocI386_Tls_ie = 15, + ELF_RelocI386_Tls_gotie = 16, + ELF_RelocI386_Tls_le = 17, + ELF_RelocI386_Tls_gd = 18, + ELF_RelocI386_Tls_ldm = 19, + ELF_RelocI386_16 = 20, + ELF_RelocI386_PC16 = 21, + ELF_RelocI386_8 = 22, + ELF_RelocI386_Pc8 = 23, + ELF_RelocI386_TlsGd32 = 24, + ELF_RelocI386_TlsGdPush = 25, + ELF_RelocI386_TlsGdCall = 26, + ELF_RelocI386_TlsGdPop = 27, + ELF_RelocI386_TlsLdm32 = 28, + ELF_RelocI386_TlsLdmPush = 29, + ELF_RelocI386_TlsLdmCall = 30, + ELF_RelocI386_TlsLdmPop = 31, + ELF_RelocI386_TlsLdo32 = 32, + ELF_RelocI386_TlsIe32 = 33, + ELF_RelocI386_TlsLe32 = 34, + ELF_RelocI386_TlsDtpmod32 = 35, + ELF_RelocI386_TlsDtpoff32 = 36, + ELF_RelocI386_TlsTpoff32 = 37, + // 38 is not taken + ELF_RelocI386_TlsGotDesc = 39, + ELF_RelocI386_TlsDescCall = 40, + ELF_RelocI386_TlsDesc = 41, + ELF_RelocI386_IRelative = 42, + ELF_RelocI386_Gotx32x = 43, + ELF_RelocI386_UsedByIntel200 = 200, + ELF_RelocI386_GNU_VTInherit = 250, + ELF_RelocI386_GNU_VTEntry = 251, +}; + +typedef U32 ELF_RelocX8664; +enum +{ + ELF_RelocX8664_None = 0, + ELF_RelocX8664_64 = 1, + ELF_RelocX8664_Pc32 = 2, + ELF_RelocX8664_Got32 = 3, + ELF_RelocX8664_Plt32 = 4, + ELF_RelocX8664_Copy = 5, + ELF_RelocX8664_GlobDat = 6, + ELF_RelocX8664_JumpSlot = 7, + ELF_RelocX8664_Relative = 8, + ELF_RelocX8664_GotPcRel = 9, + ELF_RelocX8664_32 = 10, + ELF_RelocX8664_32S = 11, + ELF_RelocX8664_16 = 12, + ELF_RelocX8664_Pc16 = 13, + ELF_RelocX8664_8 = 14, + ELF_RelocX8664_Pc8 = 15, + ELF_RelocX8664_DtpMod64 = 16, + ELF_RelocX8664_DtpOff64 = 17, + ELF_RelocX8664_TpOff64 = 18, + ELF_RelocX8664_TlsGd = 19, + ELF_RelocX8664_TlsLd = 20, + ELF_RelocX8664_DtpOff32 = 21, + ELF_RelocX8664_GotTpOff = 22, + ELF_RelocX8664_TpOff32 = 23, + ELF_RelocX8664_Pc64 = 24, + ELF_RelocX8664_GotOff64 = 25, + ELF_RelocX8664_GotPc32 = 26, + ELF_RelocX8664_Got64 = 27, + ELF_RelocX8664_GotPcRel64 = 28, + ELF_RelocX8664_GotPc64 = 29, + ELF_RelocX8664_GotPlt64 = 30, + ELF_RelocX8664_PltOff64 = 31, + ELF_RelocX8664_Size32 = 32, + ELF_RelocX8664_Size64 = 33, + ELF_RelocX8664_GotPc32TlsDesc = 34, + ELF_RelocX8664_TlsDescCall = 35, + ELF_RelocX8664_TlsDesc = 36, + ELF_RelocX8664_IRelative = 37, + ELF_RelocX8664_Relative64 = 38, + ELF_RelocX8664_Pc32Bnd = 39, + ELF_RelocX8664_Plt32Bnd = 40, + ELF_RelocX8664_GotPcRelx = 41, + ELF_RelocX8664_RexGotPcRelx = 42, + ELF_RelocX8664_GNU_VTInherit = 250, + ELF_RelocX8664_GNU_VTEntry = 251, +}; + +typedef U32 ELF_ExternalVerFlag; +enum +{ + ELF_ExternalVerFlag_Base = (1 << 0), + ELF_ExternalVerFlag_Weak = (1 << 1), + ELF_ExternalVerFlag_Info = (1 << 2), +}; + +typedef U32 ELF_NoteType; +enum +{ + ELF_NoteType_GNU_Abi = 1, + ELF_NoteType_GNU_HwCap = 2, + ELF_NoteType_GNU_BuildId = 3, + ELF_NoteType_GNU_GoldVersion = 4, + ELF_NoteType_GNU_PropertyType0 = 5, +}; + +typedef U32 ELF_GnuABITag; +enum +{ + ELF_GnuABITag_Linux = 0, + ELF_GnuABITag_Hurd = 1, + ELF_GnuABITag_Solaris = 2, + ELF_GnuABITag_FreeBsd = 3, + ELF_GnuABITag_NetBsd = 4, + ELF_GnuABITag_Syllable = 5, + ELF_GnuABITag_Nacl = 6, +}; + +typedef S32 ELF_GnuProperty; +enum +{ + ELF_GnuProperty_LoProc = 0xc0000000, + // processor-specific range + ELF_GnuProperty_HiProc = 0xdfffffff, + ELF_GnuProperty_LoUser = 0xe0000000, + // application-specific range + ELF_GnuProperty_HiUser = 0xffffffff, + ELF_GnuProperty_StackSize = 1, + ELF_GnuProperty_NoCopyOnProtected = 2, +}; + +typedef U32 ELF_GnuPropertyX86Isa1; +enum +{ + ELF_GnuPropertyX86Isa1_BaseLine = (1 << 0), + ELF_GnuPropertyX86Isa1_V2 = (1 << 1), + ELF_GnuPropertyX86Isa1_V3 = (1 << 2), + ELF_GnuPropertyX86Isa1_V4 = (1 << 3), +}; + +typedef U32 ELF_GnuPropertyX86Compat1Isa1; +enum +{ + ELF_GnuPropertyX86Compat1Isa1_486 = (1 << 0), + ELF_GnuPropertyX86Compat1Isa1_586 = (1 << 1), + ELF_GnuPropertyX86Compat1Isa1_686 = (1 << 2), + ELF_GnuPropertyX86Compat1Isa1_SSE = (1 << 3), + ELF_GnuPropertyX86Compat1Isa1_SSE2 = (1 << 4), + ELF_GnuPropertyX86Compat1Isa1_SSE3 = (1 << 5), + ELF_GnuPropertyX86Compat1Isa1_SSSE3 = (1 << 6), + ELF_GnuPropertyX86Compat1Isa1_SSE4_1 = (1 << 7), + ELF_GnuPropertyX86Compat1Isa1_SSE4_2 = (1 << 8), + ELF_GnuPropertyX86Compat1Isa1_AVX = (1 << 9), + ELF_GnuPropertyX86Compat1Isa1_AVX2 = (1 << 10), + ELF_GnuPropertyX86Compat1Isa1_AVX512F = (1 << 11), + ELF_GnuPropertyX86Compat1Isa1_AVX512ER = (1 << 12), + ELF_GnuPropertyX86Compat1Isa1_AVX512PF = (1 << 13), + ELF_GnuPropertyX86Compat1Isa1_AVX512VL = (1 << 14), + ELF_GnuPropertyX86Compat1Isa1_AVX512DQ = (1 << 15), + ELF_GnuPropertyX86Compat1Isa1_AVX512BW = (1 << 16), +}; + +typedef U32 ELF_GnuPropertyX86Compat2Isa1; +enum +{ + ELF_GnuPropertyX86Compat2Isa1_CMOVE = (1 << 0), + ELF_GnuPropertyX86Compat2Isa1_SSE = (1 << 1), + ELF_GnuPropertyX86Compat2Isa1_SSE2 = (1 << 2), + ELF_GnuPropertyX86Compat2Isa1_SSE3 = (1 << 3), + ELF_GnuPropertyX86Compat2Isa1_SSE4_1 = (1 << 4), + ELF_GnuPropertyX86Compat2Isa1_SSE4_2 = (1 << 5), + ELF_GnuPropertyX86Compat2Isa1_AVX = (1 << 6), + ELF_GnuPropertyX86Compat2Isa1_AVX2 = (1 << 7), + ELF_GnuPropertyX86Compat2Isa1_FMA = (1 << 8), + ELF_GnuPropertyX86Compat2Isa1_AVX512F = (1 << 9), + ELF_GnuPropertyX86Compat2Isa1_AVX512CD = (1 << 10), + ELF_GnuPropertyX86Compat2Isa1_AVX512ER = (1 << 11), + ELF_GnuPropertyX86Compat2Isa1_AVX512PF = (1 << 12), + ELF_GnuPropertyX86Compat2Isa1_AVX512VL = (1 << 13), + ELF_GnuPropertyX86Compat2Isa1_AVX512DQ = (1 << 14), + ELF_GnuPropertyX86Compat2Isa1_AVX512BW = (1 << 15), + ELF_GnuPropertyX86Compat2Isa1_AVX512_4FMAPS = (1 << 16), + ELF_GnuPropertyX86Compat2Isa1_AVX512_4VNNIW = (1 << 17), + ELF_GnuPropertyX86Compat2Isa1_AVX512_BITALG = (1 << 18), + ELF_GnuPropertyX86Compat2Isa1_AVX512_IFMA = (1 << 19), + ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI = (1 << 20), + ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI2 = (1 << 21), + ELF_GnuPropertyX86Compat2Isa1_AVX512_VNNI = (1 << 22), + ELF_GnuPropertyX86Compat2Isa1_AVX512_BF16 = (1 << 23), +}; + +typedef S32 ELF_GnuPropertyX86; +enum +{ + ELF_GnuPropertyX86_Feature1And = 0xc0000002, + ELF_GnuPropertyX86_Feature2Used = 0xc0010001, + ELF_GnuPropertyX86_Isa1needed = 0xc0008002, + ELF_GnuPropertyX86_Isa2Needed = 0xc0008001, + ELF_GnuPropertyX86_Isa1Used = 0xc0010002, + ELF_GnuPropertyX86_Compat_isa_1_used = 0xc0000000, + ELF_GnuPropertyX86_Compat_isa_1_needed = 0xc0000001, + ELF_GnuPropertyX86_UInt32AndLo = ELF_GnuPropertyX86_Feature1And, + ELF_GnuPropertyX86_UInt32AndHi = 0xc0007fff, + ELF_GnuPropertyX86_UInt32OrLo = 0xc0008000, + ELF_GnuPropertyX86_UInt32OrHi = 0xc000ffff, + ELF_GnuPropertyX86_UInt32OrAndLo = 0xc0010000, + ELF_GnuPropertyX86_UInt32OrAndHi = 0xc0017fff, +}; + +typedef U32 ELF_GnuPropertyX86Feature1; +enum +{ + ELF_GnuPropertyX86Feature1_Ibt = (1 << 0), + ELF_GnuPropertyX86Feature1_Shstk = (1 << 1), + ELF_GnuPropertyX86Feature1_LamU48 = (1 << 2), + ELF_GnuPropertyX86Feature1_LamU57 = (1 << 3), +}; + +typedef U32 ELF_GnuPropertyX86Feature2; +enum +{ + ELF_GnuPropertyX86Feature2_X86 = (1 << 0), + ELF_GnuPropertyX86Feature2_X87 = (1 << 1), + ELF_GnuPropertyX86Feature2_MMX = (1 << 2), + ELF_GnuPropertyX86Feature2_XMM = (1 << 3), + ELF_GnuPropertyX86Feature2_YMM = (1 << 4), + ELF_GnuPropertyX86Feature2_ZMM = (1 << 5), + ELF_GnuPropertyX86Feature2_FXSR = (1 << 6), + ELF_GnuPropertyX86Feature2_XSAVE = (1 << 7), + ELF_GnuPropertyX86Feature2_XSAVEOPT = (1 << 8), + ELF_GnuPropertyX86Feature2_XSAVEC = (1 << 9), + ELF_GnuPropertyX86Feature2_TMM = (1 << 10), + ELF_GnuPropertyX86Feature2_MASK = (1 << 11), +}; + +#define ELF_HdrIs64Bit(e_ident) (e_ident[ELF_Identifier_Class] == ELF_Class_64) +#define ELF_HdrIs32Bit(e_ident) (e_ident[ELF_Identifier_Class] == ELF_Class_32) + +typedef enum ELF_Identifier +{ + ELF_Identifier_Mag0 = 0, + ELF_Identifier_Mag1 = 1, + ELF_Identifier_Mag2 = 2, + ELF_Identifier_Mag3 = 3, + ELF_Identifier_Class = 4, + ELF_Identifier_Data = 5, + ELF_Identifier_Version = 6, + ELF_Identifier_OsAbi = 7, + ELF_Identfiier_AbiBersion = 8, + ELF_Identifier_Max = 16, +} ELF_Identifier; + +typedef struct ELF_Hdr64 +{ + U8 e_ident[ELF_Identifier_Max]; + U16 e_type; + U16 e_machine; + U32 e_version; + U64 e_entry; + U64 e_phoff; + U64 e_shoff; + U32 e_flags; + U16 e_ehsize; + U16 e_phentsize; + U16 e_phnum; + U16 e_shentsize; + U16 e_shnum; + U16 e_shstrndx; +} ELF_Hdr64; + +typedef struct ELF_Hdr32 +{ + U8 e_ident[ELF_Identifier_Max]; + U16 e_type; + U16 e_machine; + U32 e_version; + U32 e_entry; + U32 e_phoff; + U32 e_shoff; + U32 e_flags; + U16 e_ehsize; + U16 e_phentsize; + U16 e_phnum; + U16 e_shentsize; + U16 e_shnum; + U16 e_shstrndx; +} ELF_Hdr32; + +typedef struct ELF_Shdr64 +{ + U32 sh_name; + U32 sh_type; + U64 sh_flags; + U64 sh_addr; + U64 sh_offset; + U64 sh_size; + U32 sh_link; + U32 sh_info; + U64 sh_addralign; + U64 sh_entsize; +} ELF_Shdr64; + +typedef struct ELF_Shdr32 +{ + U32 sh_name; + U32 sh_type; + U32 sh_flags; + U32 sh_addr; + U32 sh_offset; + U32 sh_size; + U32 sh_link; + U32 sh_info; + U32 sh_addralign; + U32 sh_entsize; +} ELF_Shdr32; + +typedef struct ELF_Phdr64 +{ + U32 p_type; + U32 p_flags; + U64 p_offset; + U64 p_vaddr; + U64 p_paddr; + U64 p_filesz; + U64 p_memsz; + U64 p_align; +} ELF_Phdr64; + +typedef struct ELF_Phdr32 +{ + U32 p_type; + U32 p_offset; + U32 p_vaddr; + U32 p_paddr; + U32 p_filesz; + U32 p_memsz; + U32 p_flags; + U32 p_align; +} ELF_Phdr32; + +//////////////////////////////// +// Auxiliary Vectors + +// these appear in /proc//auxv of a process, they are not in elf files + +typedef struct ELF_Auxv32 +{ + U32 a_type; + U32 a_val; +} ELF_Auxv32; + +typedef struct ELF_Auxv64 +{ + U64 a_type; + U64 a_val; +} ELF_Auxv64; + +//////////////////////////////// +// Dynamic Structures + +// these appear in the virtual address space of a process, they are not in elf files + +typedef struct ELF_Dyn32 +{ + U32 tag; + U32 val; +} ELF_Dyn32; + +typedef struct ELF_Dyn64 +{ + U64 tag; + U64 val; +} ELF_Dyn64; + +typedef struct ELF_LinkMap32 +{ + U32 base; + U32 name; + U32 ld; + U32 next; +} ELF_LinkMap32; + +typedef struct ELF_LinkMap64 +{ + U64 base; + U64 name; + U64 ld; + U64 next; +} ELF_LinkMap64; + +//////////////////////////////// +// Imports and Exports + +typedef struct +{ + U32 st_name; // Holds index into files string table. + U32 st_value; // Depending on the context, this may be address, size, etc. + U32 st_size; // Data size in bytes. Zero when size is unknown. + U8 st_info; // Contains symbols type and binding. + U8 st_other; // Reserved for future use, currenly zero. + U16 st_shndx; // Section index to which symbol is relevant. +} ELF_Sym32; + +typedef struct +{ + U32 st_name; + U8 st_info; + U8 st_other; + U16 st_shndx; + U64 st_value; + U64 st_size; +} ELF_Sym64; + +#define ELF_ST_INFO(b,t) (((b) << 4) + ((t) & 0xF)) +#define ELF_ST_BIND(x) ((x) >> 4) +#define ELF_ST_TYPE(x) ((x) & 0xF) +#define ELF_ST_VISIBILITY(v) ((v) & 0x3) + +typedef struct +{ + U32 r_offset; + U32 r_info; +} ELF_Rel32; + +typedef struct +{ + U32 r_offset; + U32 r_info; + S32 r_addend; +} ELF_Rela32; + +typedef struct +{ + U64 r_offset; + U64 r_info; +} ELF_Rel64; + +typedef struct +{ + U64 r_offset; + U64 r_info; + S64 r_addend; +} ELF_Rela64; + +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xFF) + +#define ELF64_R_INFO(s,t) (((U64)(s) << 32) | (U64)t) +#define ELF64_R_SYM(x) ((x) >> 32) +#define ELF64_R_TYPE(x) ((x) & 0xffffffff) + +// This flag is set to indicate that symbol is not available outside shared object +#define ELF_EXTERNAL_VERSYM_HIDDEN 0x8000 +#define ELF_EXTERNAL_VERSYM_MASK 0x7FFF + +// Appears in .gnu.verdef (SHT_GNU_verdef) +typedef struct +{ + U16 vd_version; + U16 vd_flags; + U16 vd_ndx; + U16 vd_cnt; + U32 vd_hash; + U32 vd_aux; + U32 vd_next; +} ELF_ExternalVerdef; + +// Appears in .gnu.verdef (SHT_GNU_verdef) +typedef struct +{ + U32 vda_name; + U32 vda_next; +} ELF_ExternalVerdaux; + +// Appears in .gnu.verneed (SHT_GNU_verneed) +typedef struct +{ + U16 vn_version; + U16 vn_cnt; + U32 vn_file; + U32 vn_aux; + U32 vn_next; +} ELF_ExternalVerneed; + +// Appears in .gnu.verneed (SHT_GNU_verneed) +typedef struct +{ + U32 vna_hash; + U16 vna_flags; + U16 vna_other; + U32 vna_name; + U32 vna_next; +} ELF_ExternalVernaux; + +// Appears in .gnu.version (SHT_GNU_versym) +typedef struct +{ + U16 vs_vers; +} ELF_ExternalVersym; + +typedef struct +{ + U32 name_size; + U32 desc_size; + U32 type; + // name + desc + // U8 data[1]; +} ELF_Note; + +//////////////////////////////// +// Extensions + +typedef U8 ELF_CompressType; +enum ELF_CompressTypeEnum +{ + ELF_CompressType_None = 0, + ELF_CompressType_ZLib = 1, + ELF_CompressType_ZStd = 2, + + ELF_CompressType_LoOs = 0x60000000, + ELF_CompressType_HiOs = 0x6fffffff, + + ELF_CompressType_LoProc = 0x70000000, + ELF_CompressType_HiProc = 0x7fffffff, +}; + +typedef struct ELF_Chdr32 +{ + U32 ch_type; + U32 ch_size; + U32 ch_addr_align; +} ELF_Chdr32; + +typedef struct ELF_Chdr64 +{ + U64 ch_type; + U64 ch_size; + U64 ch_addr_align; +} ELF_Chdr64; + +//////////////////////////////// + +internal ELF_Hdr64 elf_hdr64_from_ehdr32(ELF_Hdr32 h32); +internal ELF_Shdr64 elf_shdr64_from_shdr32(ELF_Shdr32 h32); +internal ELF_Phdr64 elf_phdr64_from_phdr32(ELF_Phdr32 h32); +internal ELF_Dyn64 elf_dyn64_from_dyn32 (ELF_Dyn32 h32); +internal ELF_Sym64 elf_sym64_from_sym32 (ELF_Sym32 sym32); +internal ELF_Rel64 elf_rel64_from_rel32 (ELF_Rel32 rel32); +internal ELF_Rela64 elf_rela64_from_rela32(ELF_Rela32 rela32); +internal ELF_Chdr64 elf_chdr64_from_chdr32(ELF_Chdr32 chdr32); + +//////////////////////////////// + +internal String8 elf_string_from_class(Arena *arena, ELF_Class v); + +//////////////////////////////// + +internal Arch arch_from_elf_machine(ELF_MachineKind machine); + +#endif // ELF_H + diff --git a/src/elf/elf_parse.c b/src/elf/elf_parse.c new file mode 100644 index 00000000..22bb47be --- /dev/null +++ b/src/elf/elf_parse.c @@ -0,0 +1,90 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal B32 +elf_check_magic(String8 data) +{ + U8 sig[ELF_Identifier_Max] = {0}; + str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1); + B32 is_magic_valid = (sig[ELF_Identifier_Mag0] == 0x7f && sig[ELF_Identifier_Mag1] == 'E' && sig[ELF_Identifier_Mag2] == 'L' && sig[ELF_Identifier_Mag3] == 'F'); + return is_magic_valid; +} + +internal ELF_BinInfo +elf_bin_from_data(String8 data) +{ + ELF_Hdr64 hdr64 = {0}; + Rng1U64 sh_name_range = rng_1u64(0,0); + + if (elf_check_magic(data)) { + U8 sig[ELF_Identifier_Max] = {0}; + str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1); + + switch (sig[ELF_Identifier_Class]) { + case ELF_Class_None: break; + case ELF_Class_32: { + ELF_Hdr32 hdr32 = {0}; + U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr32); + if (hdr_size == sizeof(hdr32)) { + hdr64 = elf_hdr64_from_hdr32(hdr32); + + U64 shstr_off = hdr32.e_shoff + hdr32.e_shentsize*hdr32.e_shstrndx; + ELF_Shdr32 shdr = {0}; + U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); + + if (shdr_size == sizeof(shdr)) { + sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + } + } + } break; + case ELF_Class_64: { + U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr64); + if (hdr_size == sizeof(hdr64)) { + U64 shstr_off = hdr64.e_shoff + hdr64.e_shentsize*hdr64.e_shstrndx; + ELF_Shdr64 shdr = {0}; + U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr); + + if (shdr_size == sizeof(shdr)) { + sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size); + } + } + } break; + default: Assert(!"invalid elf header"); break; + } + } + + ELF_BinInfo info = {0}; + info.hdr = hdr64; + info.sh_name_range = sh_name_range; + + return info; +} + +internal ELF_Shdr64Array +elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr) +{ + Rng1U64 shdr_range = rng_1u64(hdr->e_shoff, hdr->e_shoff + hdr->e_shentsize*hdr->e_shnum); + String8 shdr_data = str8_substr(raw_data, shdr_range); + + ELF_Shdr64Array result = {0}; + result.count = hdr->e_shnum; + result.v = push_array(arena, ELF_Shdr64, hdr->e_shnum); + + for(U64 shdr_idx = 0; shdr_idx < hdr->e_shnum; ++shdr_idx) { + switch (hdr->e_ident[ELF_Identifier_Class]) { + case ELF_Class_None: break; + case ELF_Class_32: { + ELF_Shdr32 shdr32 = {0}; + str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr32), &shdr32); + result.v[shdr_idx] = elf_shdr64_from_shdr32(shdr32); + } break; + case ELF_Class_64: { + str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr64), &result.v[shdr_idx]); + } break; + default: InvalidPath; break; + } + } + + return result; +} + diff --git a/src/elf/elf_parse.h b/src/elf/elf_parse.h new file mode 100644 index 00000000..fccbc233 --- /dev/null +++ b/src/elf/elf_parse.h @@ -0,0 +1,29 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef ELF_PARSE_H +#define ELF_PARSE_H + +//////////////////////////////// + +typedef struct ELF_BinInfo +{ + ELF_Hdr64 hdr; + Rng1U64 sh_name_range; +} ELF_BinInfo; + +typedef struct ELF_Shdr64Array +{ + U64 count; + ELF_Shdr64 *v; +} ELF_Shdr64Array; + +//////////////////////////////// + +internal B32 elf_check_magic(String8 data); +internal ELF_BinInfo elf_bin_from_data(String8 data); + +internal ELF_Shdr64Array elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr); +internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr); + +#endif // ELF_PARSE_H From 90c05d56b54cf5d455664f25b269fb1ddbf5a182 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 7 Feb 2025 15:13:00 -0800 Subject: [PATCH 183/755] added zlib decompressor for DWARF extraction --- src/third_party/sinfl/sinfl.h | 616 ++++++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 src/third_party/sinfl/sinfl.h diff --git a/src/third_party/sinfl/sinfl.h b/src/third_party/sinfl/sinfl.h new file mode 100644 index 00000000..ca225d58 --- /dev/null +++ b/src/third_party/sinfl/sinfl.h @@ -0,0 +1,616 @@ +// NOTE: changed input and output var types from int to size_t + +/* +# Small Deflate +`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90) +which implements the Deflate (RFC 1951) compressed data format specification standard. +It is mainly tuned to get as much speed and compression ratio from as little code +as needed to keep the implementation as concise as possible. + +## Features +- Portable single header and source file duo written in ANSI C (ISO C90) +- Dual license with either MIT or public domain +- Small implementation + - Deflate: 525 LoC + - Inflate: 500 LoC +- Webassembly: + - Deflate ~3.7 KB (~2.2KB compressed) + - Inflate ~3.6 KB (~2.2KB compressed) + +## Usage: +This file behaves differently depending on what symbols you define +before including it. + +Header-File mode: +If you do not define `SINFL_IMPLEMENTATION` before including this file, it +will operate in header only mode. In this mode it declares all used structs +and the API of the library without including the implementation of the library. + +Implementation mode: +If you define `SINFL_IMPLEMENTATION` before including this file, it will +compile the implementation. Make sure that you only include +this file implementation in *one* C or C++ file to prevent collisions. + +### Benchmark + +| Compressor name | Compression| Decompress.| Compr. size | Ratio | +| ------------------------| -----------| -----------| ----------- | ----- | +| miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 | +| miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 | +| miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 | +| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 | +| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 | +| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 | +| sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 | +| sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 | +| sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 | +| sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 | +| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 | +| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 | +| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 | +| libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 | + +### Compression +Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia): + +| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` | +| --------| -----------| -------------| ---------- | ------------| +| dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 | +| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 | +| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 | +| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 | +| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 | +| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 | +| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 | +| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 | +| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 | +| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 | +| xml | 5.345.280 | 886,620 | 674,009 | 662,141 | +| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 | + +## License +``` +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2020-2023 Micha Mettke +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +``` +*/ +#ifndef SINFL_H_INCLUDED +#define SINFL_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define SINFL_PRE_TBL_SIZE 128 +#define SINFL_LIT_TBL_SIZE 1334 +#define SINFL_OFF_TBL_SIZE 402 + +struct sinfl { + const unsigned char *bitptr; + unsigned long long bitbuf; + int bitcnt; + + unsigned lits[SINFL_LIT_TBL_SIZE]; + unsigned dsts[SINFL_OFF_TBL_SIZE]; +}; +extern size_t sinflate(void *out, size_t cap, const void *in, size_t size); +extern size_t zsinflate(void *out, size_t cap, const void *in, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* SINFL_H_INCLUDED */ + +#ifdef SINFL_IMPLEMENTATION + +#include /* memcpy, memset */ +#include /* assert */ + +#if defined(__GNUC__) || defined(__clang__) +#define sinfl_likely(x) __builtin_expect((x),1) +#define sinfl_unlikely(x) __builtin_expect((x),0) +#else +#define sinfl_likely(x) (x) +#define sinfl_unlikely(x) (x) +#endif + +#ifndef SINFL_NO_SIMD +#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64) + #include + #define sinfl_char16 uint8x16_t + #define sinfl_char16_ld(p) vld1q_u8((const unsigned char*)(p)) + #define sinfl_char16_str(d, v) vst1q_u8((unsigned char*)(d), v) + #define sinfl_char16_char(c) vdupq_n_u8(c) +#elif defined(__x86_64__) || defined(_WIN32) || defined(_WIN64) + #include + #define sinfl_char16 __m128i + #define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p)) + #define sinfl_char16_str(d,v) _mm_storeu_si128((__m128i*)(void*)(d), v) + #define sinfl_char16_char(c) _mm_set1_epi8(c) +#else + #define SINFL_NO_SIMD +#endif +#endif + +static int +sinfl_bsr(unsigned n) { +#ifdef _MSC_VER + unsigned long r = 0; + _BitScanReverse(&r, n); + return (int)r; +#elif defined(__GNUC__) || defined(__clang__) + return 31 - __builtin_clz(n); +#endif +} +static unsigned long long +sinfl_read64(const void *p) { + unsigned long long n; + memcpy(&n, p, 8); + return n; +} +static void +sinfl_copy64(unsigned char **dst, unsigned char **src) { + unsigned long long n; + memcpy(&n, *src, 8); + memcpy(*dst, &n, 8); + *dst += 8, *src += 8; +} +static unsigned char* +sinfl_write64(unsigned char *dst, unsigned long long w) { + memcpy(dst, &w, 8); + return dst + 8; +} +#ifndef SINFL_NO_SIMD +static unsigned char* +sinfl_write128(unsigned char *dst, sinfl_char16 w) { + sinfl_char16_str(dst, w); + return dst + 8; +} +static void +sinfl_copy128(unsigned char **dst, unsigned char **src) { + sinfl_char16 n = sinfl_char16_ld(*src); + sinfl_char16_str(*dst, n); + *dst += 16, *src += 16; +} +#endif +static void +sinfl_refill(struct sinfl *s) { + s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt; + s->bitptr += (63 - s->bitcnt) >> 3; + s->bitcnt |= 56; /* bitcount in range [56,63] */ +} +static int +sinfl_peek(struct sinfl *s, int cnt) { + assert(cnt >= 0 && cnt <= 56); + assert(cnt <= s->bitcnt); + return s->bitbuf & ((1ull << cnt) - 1); +} +static void +sinfl_eat(struct sinfl *s, int cnt) { + assert(cnt <= s->bitcnt); + s->bitbuf >>= cnt; + s->bitcnt -= cnt; +} +static int +sinfl__get(struct sinfl *s, int cnt) { + int res = sinfl_peek(s, cnt); + sinfl_eat(s, cnt); + return res; +} +static int +sinfl_get(struct sinfl *s, int cnt) { + sinfl_refill(s); + return sinfl__get(s, cnt); +} +struct sinfl_gen { + int len; + int cnt; + int word; + short* sorted; +}; +static int +sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits, + const int *cnt) { + int tbl_end = 0; + while (!(gen->cnt = cnt[gen->len])) { + ++gen->len; + } + tbl_end = 1 << gen->len; + while (gen->len <= tbl_bits) { + do {unsigned bit = 0; + tbl[gen->word] = (*gen->sorted++ << 16) | gen->len; + if (gen->word == tbl_end - 1) { + for (; gen->len < tbl_bits; gen->len++) { + memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0])); + tbl_end <<= 1; + } + return 1; + } + bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1))); + gen->word &= bit - 1; + gen->word |= bit; + } while (--gen->cnt); + do { + if (++gen->len <= tbl_bits) { + memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0])); + tbl_end <<= 1; + } + } while (!(gen->cnt = cnt[gen->len])); + } + return 0; +} +static void +sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits, + const int *cnt) { + int sub_bits = 0; + int sub_start = 0; + int sub_prefix = -1; + int tbl_end = 1 << tbl_bits; + while (1) { + unsigned entry; + int bit, stride, i; + /* start new sub-table */ + if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) { + int used = 0; + sub_prefix = gen->word & ((1 << tbl_bits)-1); + sub_start = tbl_end; + sub_bits = gen->len - tbl_bits; + used = gen->cnt; + while (used < (1 << sub_bits)) { + sub_bits++; + used = (used << 1) + cnt[tbl_bits + sub_bits]; + } + tbl_end = sub_start + (1 << sub_bits); + tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf); + } + /* fill sub-table */ + entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf); + gen->sorted++; + i = sub_start + (gen->word >> tbl_bits); + stride = 1 << (gen->len - tbl_bits); + do { + tbl[i] = entry; + i += stride; + } while (i < tbl_end); + if (gen->word == (1 << gen->len)-1) { + return; + } + bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1)); + gen->word &= bit - 1; + gen->word |= bit; + gen->cnt--; + while (!gen->cnt) { + gen->cnt = cnt[++gen->len]; + } + } +} +static void +sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen, + int symcnt) { + int i, used = 0; + short sort[288]; + int cnt[16] = {0}, off[16]= {0}; + struct sinfl_gen gen = {0}; + gen.sorted = sort; + gen.len = 1; + + for (i = 0; i < symcnt; ++i) + cnt[lens[i]]++; + off[1] = cnt[0]; + for (i = 1; i < maxlen; ++i) { + off[i + 1] = off[i] + cnt[i]; + used = (used << 1) + cnt[i]; + } + used = (used << 1) + cnt[i]; + for (i = 0; i < symcnt; ++i) + gen.sorted[off[lens[i]]++] = (short)i; + gen.sorted += off[0]; + + if (used < (1 << maxlen)){ + for (i = 0; i < 1 << tbl_bits; ++i) + tbl[i] = (0 << 16u) | 1; + return; + } + if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){ + sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt); + } +} +static int +sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) { + int idx = sinfl_peek(s, bit_len); + unsigned key = tbl[idx]; + if (key & 0x10) { + /* sub-table lookup */ + int len = key & 0x0f; + sinfl_eat(s, bit_len); + idx = sinfl_peek(s, len); + key = tbl[((key >> 16) & 0xffff) + (unsigned)idx]; + } + sinfl_eat(s, key & 0x0f); + return (key >> 16) & 0x0fff; +} +static size_t +sinfl_decompress(unsigned char *out, size_t cap, const unsigned char *in, size_t size) { + static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, + 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577}; + static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9, + 10,10,11,11,12,12,13,13,0,0}; + static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35, + 43,51,59,67,83,99,115,131,163,195,227,258,0,0}; + static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4, + 4,4,4,5,5,5,5,0,0,0}; + + const unsigned char *oe = out + cap; + const unsigned char *e = in + size, *o = out; + enum sinfl_states {hdr,stored,fixed,dyn,blk}; + enum sinfl_states state = hdr; + struct sinfl s = {0}; + int last = 0; + + s.bitptr = in; + while (1) { + switch (state) { + case hdr: { + /* block header */ + int type = 0; + sinfl_refill(&s); + last = sinfl__get(&s,1); + type = sinfl__get(&s,2); + + switch (type) {default: return (int)(out-o); + case 0x00: state = stored; break; + case 0x01: state = fixed; break; + case 0x02: state = dyn; break;} + } break; + case stored: { + /* uncompressed block */ + unsigned len, nlen; + sinfl__get(&s,s.bitcnt & 7); + len = (unsigned short)sinfl__get(&s,16); + nlen = (unsigned short)sinfl__get(&s,16); + s.bitptr -= s.bitcnt / 8; + s.bitbuf = s.bitcnt = 0; + + if ((unsigned short)len != (unsigned short)~nlen) + return (int)(out-o); + if (len > (e - s.bitptr) || !len) + return (int)(out-o); + + memcpy(out, s.bitptr, (size_t)len); + s.bitptr += len, out += len; + if (last) return (int)(out-o); + state = hdr; + } break; + case fixed: { + /* fixed huffman codes */ + int n; unsigned char lens[288+32]; + for (n = 0; n <= 143; n++) lens[n] = 8; + for (n = 144; n <= 255; n++) lens[n] = 9; + for (n = 256; n <= 279; n++) lens[n] = 7; + for (n = 280; n <= 287; n++) lens[n] = 8; + for (n = 0; n < 32; n++) lens[288+n] = 5; + + /* build lit/dist tables */ + sinfl_build(s.lits, lens, 10, 15, 288); + sinfl_build(s.dsts, lens + 288, 8, 15, 32); + state = blk; + } break; + case dyn: { + /* dynamic huffman codes */ + int n, i; + unsigned hlens[SINFL_PRE_TBL_SIZE]; + unsigned char nlens[19] = {0}, lens[288+32]; + + sinfl_refill(&s); + {int nlit = 257 + sinfl__get(&s,5); + int ndist = 1 + sinfl__get(&s,5); + int nlen = 4 + sinfl__get(&s,4); + for (n = 0; n < nlen; n++) + nlens[order[n]] = (unsigned char)sinfl_get(&s,3); + sinfl_build(hlens, nlens, 7, 7, 19); + + /* decode code lengths */ + for (n = 0; n < nlit + ndist;) { + int sym = 0; + sinfl_refill(&s); + sym = sinfl_decode(&s, hlens, 7); + switch (sym) {default: lens[n++] = (unsigned char)sym; break; + case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break; + case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break; + case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;} + } + /* build lit/dist tables */ + sinfl_build(s.lits, lens, 10, 15, nlit); + sinfl_build(s.dsts, lens + nlit, 8, 15, ndist); + state = blk;} + } break; + case blk: { + /* decompress block */ + while (1) { + int sym; + sinfl_refill(&s); + sym = sinfl_decode(&s, s.lits, 10); + if (sym < 256) { + /* literal */ + if (sinfl_unlikely(out >= oe)) { + return (int)(out-o); + } + *out++ = (unsigned char)sym; + sym = sinfl_decode(&s, s.lits, 10); + if (sym < 256) { + *out++ = (unsigned char)sym; + continue; + } + } + if (sinfl_unlikely(sym == 256)) { + /* end of block */ + if (last) return (int)(out-o); + state = hdr; + break; + } + /* match */ + if (sym >= 286) { + /* length codes 286 and 287 must not appear in compressed data */ + return (int)(out-o); + } + sym -= 257; + {int len = sinfl__get(&s, lbits[sym]) + lbase[sym]; + int dsym = sinfl_decode(&s, s.dsts, 8); + int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym]; + unsigned char *dst = out, *src = out - offs; + if (sinfl_unlikely(offs > (int)(out-o))) { + return (int)(out-o); + } + out = out + len; + +#ifndef SINFL_NO_SIMD + if (sinfl_likely(oe - out >= 16 * 3)) { + if (offs >= 16) { + /* simd copy match */ + sinfl_copy128(&dst, &src); + sinfl_copy128(&dst, &src); + do sinfl_copy128(&dst, &src); + while (dst < out); + } else if (offs >= 8) { + /* word copy match */ + sinfl_copy64(&dst, &src); + sinfl_copy64(&dst, &src); + do sinfl_copy64(&dst, &src); + while (dst < out); + } else if (offs == 1) { + /* rle match copying */ + sinfl_char16 w = sinfl_char16_char(src[0]); + dst = sinfl_write128(dst, w); + dst = sinfl_write128(dst, w); + do dst = sinfl_write128(dst, w); + while (dst < out); + } else { + /* byte copy match */ + *dst++ = *src++; + *dst++ = *src++; + do *dst++ = *src++; + while (dst < out); + } + } +#else + if (sinfl_likely(oe - out >= 3 * 8 - 3)) { + if (offs >= 8) { + /* word copy match */ + sinfl_copy64(&dst, &src); + sinfl_copy64(&dst, &src); + do sinfl_copy64(&dst, &src); + while (dst < out); + } else if (offs == 1) { + /* rle match copying */ + unsigned int c = src[0]; + unsigned int hw = (c << 24u) | (c << 16u) | (c << 8u) | (unsigned)c; + unsigned long long w = (unsigned long long)hw << 32llu | hw; + dst = sinfl_write64(dst, w); + dst = sinfl_write64(dst, w); + do dst = sinfl_write64(dst, w); + while (dst < out); + } else { + /* byte copy match */ + *dst++ = *src++; + *dst++ = *src++; + do *dst++ = *src++; + while (dst < out); + } + } +#endif + else { + *dst++ = *src++; + *dst++ = *src++; + do *dst++ = *src++; + while (dst < out); + }} + } + } break;} + } + return (size_t)(out-o); +} +extern size_t +sinflate(void *out, size_t cap, const void *in, size_t size) { + return sinfl_decompress((unsigned char*)out, cap, (const unsigned char*)in, size); +} +static unsigned +sinfl_adler32(unsigned adler32, const unsigned char *in, size_t in_len) { + const unsigned ADLER_MOD = 65521; + unsigned s1 = adler32 & 0xffff; + unsigned s2 = adler32 >> 16; + unsigned blk_len, i; + + blk_len = in_len % 5552; + while (in_len) { + for (i=0; i + 7 < blk_len; i += 8) { + s1 += in[0]; s2 += s1; + s1 += in[1]; s2 += s1; + s1 += in[2]; s2 += s1; + s1 += in[3]; s2 += s1; + s1 += in[4]; s2 += s1; + s1 += in[5]; s2 += s1; + s1 += in[6]; s2 += s1; + s1 += in[7]; s2 += s1; + in += 8; + } + for (; i < blk_len; ++i) + s1 += *in++, s2 += s1; + s1 %= ADLER_MOD; s2 %= ADLER_MOD; + in_len -= blk_len; + blk_len = 5552; + } return (unsigned)(s2 << 16) + (unsigned)s1; +} +extern size_t +zsinflate(void *out, size_t cap, const void *mem, size_t size) { + const unsigned char *in = (const unsigned char*)mem; + if (size >= 6) { + const unsigned char *eob = in + size - 4; + int n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size); + unsigned a = sinfl_adler32(1u, (unsigned char*)out, n); + unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0; + return a == h ? n : -1; + } else { + return -1; + } +} +#endif + From 1d441bac309753ccb47a6d93e628c362628cb893 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 7 Feb 2025 15:16:14 -0800 Subject: [PATCH 184/755] minor fixes and renames in DWARF enums --- src/dwarf/dwarf.h | 138 +++++++++++++++++++++++---------------- src/dwarf/dwarf_enum.c | 55 +++++++++++++++- src/dwarf/dwarf_enum.h | 1 + src/dwarf/dwarf_unwind.c | 2 +- 4 files changed, 136 insertions(+), 60 deletions(-) diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 4fd083ce..19d3a24a 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -119,6 +119,20 @@ typedef enum DW_LanguageEnum DW_Language_UserHi = 0xffff, } DW_LanguageEnum; +#define DW_Inl_XList(X) \ + X(NotInlined, 0) \ + X(Inlined, 1) \ + X(DeclaredNotInlined, 2) \ + X(DeclaredInlined, 3) + +typedef U32 DW_InlKind; +typedef enum DW_InlKindEnum +{ +#define X(_N,_ID) DW_Inl_##_N = _ID, + DW_Inl_XList(X) +#undef X +} DW_InlKindEnum; + #define DW_StdOpcode_XList(X) \ X(ExtendedOpcode, 0x00) \ X(Copy, 0x01) \ @@ -250,6 +264,7 @@ typedef enum DW_NameCase typedef U64 DW_TagKind; typedef enum DW_TagKindEnum { + DW_Tag_Null, #define X(_N,_ID) DW_Tag_##_N = _ID, DW_Tag_V3_XList(X) DW_Tag_V5_XList(X) @@ -1172,12 +1187,12 @@ typedef enum DW_AttribTypeEncodingKindEnum #undef X } DW_AttribTypeEncodingKindEnum; -#define DW_CallingConventionKind_XList(X) \ - X(DW_CallingConvention_Normal, 0x0) \ - X(DW_CallingConvention_Program, 0x1) \ - X(DW_CallingConvention_NoCall, 0x2) \ - X(DW_CallingConvention_PassByValue, 0x1) \ - X(DW_CallingConvention_PassByReference, 0x2) +#define DW_CallingConventionKind_XList(X) \ + X(Normal, 0x0) \ + X(Program, 0x1) \ + X(NoCall, 0x3) \ + X(PassByValue, 0x4) \ + X(PassByReference, 0x5) typedef U64 DW_CallingConventionKind; typedef enum DW_CallingConventionKindEnum @@ -1188,9 +1203,9 @@ typedef enum DW_CallingConventionKindEnum } DW_CallingConventionKindEnum; #define DW_AccessKind_XList(X) \ - X(DW_Access_Public, 0x00) \ - X(DW_Access_Private, 0x01) \ - X(DW_Access_Protected, 0x02) + X(Public, 0x00) \ + X(Private, 0x01) \ + X(Protected, 0x02) typedef U64 DW_AccessKind; typedef enum DW_AccessKindEnum @@ -1505,9 +1520,18 @@ enum X(Convert, 0xa8) \ X(ReInterpret, 0xa9) -#define DW_Expr_GNU_XList(X) \ - X(GNU_PushTlsAddress, 0xe0) \ - X(GNU_UnInit, 0xf0) +#define DW_Expr_GNU_XList(X) \ + X(GNU_PushTlsAddress, 0xe0) \ + X(GNU_UnInit, 0xf0) \ + X(GNU_ImplicitPointer, 0xf2) \ + X(GNU_EntryValue, 0xf3) \ + X(GNU_ConstType, 0xf4) \ + X(GNU_RegvalType, 0xf5) \ + X(GNU_DerefType, 0xf6) \ + X(GNU_Convert, 0xf7) \ + X(GNU_AddrIndex, 0xfb) \ + X(GNU_ConstIndex, 0xfc) + typedef U64 DW_ExprOp; typedef enum DW_ExprOpEnum { @@ -1541,22 +1565,22 @@ typedef enum DW_ExprOpEnum X(St5, 16, st5, 0, 10) \ X(St6, 17, st6, 0, 10) \ X(St7, 18, st7, 0, 10) \ - X(Xmm0, 21, xmm0, 0, 16) \ - X(Xmm1, 22, xmm1, 0, 16) \ - X(Xmm2, 23, xmm2, 0, 16) \ - X(Xmm3, 24, xmm3, 0, 16) \ - X(Xmm4, 25, xmm4, 0, 16) \ - X(Xmm5, 26, xmm5, 0, 16) \ - X(Xmm6, 27, xmm6, 0, 16) \ - X(Xmm7, 28, xmm7, 0, 16) \ - X(Mm0, 29, mm0, 0, 4) \ - X(Mm1, 30, mm1, 0, 4) \ - X(Mm2, 31, mm2, 0, 4) \ - X(Mm3, 32, mm3, 0, 4) \ - X(Mm4, 33, mm4, 0, 4) \ - X(Mm5, 34, mm5, 0, 4) \ - X(Mm6, 35, mm6, 0, 4) \ - X(Mm7, 36, mm7, 0, 4) \ + X(Xmm0, 21, ymm0, 0, 16) \ + X(Xmm1, 22, ymm1, 0, 16) \ + X(Xmm2, 23, ymm2, 0, 16) \ + X(Xmm3, 24, ymm3, 0, 16) \ + X(Xmm4, 25, ymm4, 0, 16) \ + X(Xmm5, 26, ymm5, 0, 16) \ + X(Xmm6, 27, ymm6, 0, 16) \ + X(Xmm7, 28, ymm7, 0, 16) \ + X(Mm0, 29, fpr0, 0, 8) \ + X(Mm1, 30, fpr1, 0, 8) \ + X(Mm2, 31, fpr2, 0, 8) \ + X(Mm3, 32, fpr3, 0, 8) \ + X(Mm4, 33, fpr4, 0, 8) \ + X(Mm5, 34, fpr5, 0, 8) \ + X(Mm6, 35, fpr6, 0, 8) \ + X(Mm7, 36, fpr7, 0, 8) \ X(Fcw, 37, fcw, 0, 2) \ X(Fsw, 38, fsw, 0, 2) \ X(Mxcsr, 39, mxcsr, 0, 4) \ @@ -1587,22 +1611,22 @@ typedef enum DW_ExprOpEnum X(R14, 14, r14, 0, 8) \ X(R15, 15, r15, 0, 8) \ X(Rip, 16, rip, 0, 8) \ - X(Xmm0, 17, ymm0, 0, 16) \ - X(Xmm1, 18, ymm1, 0, 16) \ - X(Xmm2, 19, ymm2, 0, 16) \ - X(Xmm3, 20, ymm3, 0, 16) \ - X(Xmm4, 21, ymm4, 0, 16) \ - X(Xmm5, 22, ymm5, 0, 16) \ - X(Xmm6, 23, ymm6, 0, 16) \ - X(Xmm7, 24, ymm7, 0, 16) \ - X(Xmm8, 25, ymm8, 0, 16) \ - X(Xmm9, 26, ymm9, 0, 16) \ - X(Xmm10, 27, ymm10, 0, 16) \ - X(Xmm11, 28, ymm11, 0, 16) \ - X(Xmm12, 29, ymm12, 0, 16) \ - X(Xmm13, 30, ymm13, 0, 16) \ - X(Xmm14, 31, ymm14, 0, 16) \ - X(Xmm15, 32, ymm15, 0, 16) \ + X(Xmm0, 17, zmm0, 0, 16) \ + X(Xmm1, 18, zmm1, 0, 16) \ + X(Xmm2, 19, zmm2, 0, 16) \ + X(Xmm3, 20, zmm3, 0, 16) \ + X(Xmm4, 21, zmm4, 0, 16) \ + X(Xmm5, 22, zmm5, 0, 16) \ + X(Xmm6, 23, zmm6, 0, 16) \ + X(Xmm7, 24, zmm7, 0, 16) \ + X(Xmm8, 25, zmm8, 0, 16) \ + X(Xmm9, 26, zmm9, 0, 16) \ + X(Xmm10, 27, zmm10, 0, 16) \ + X(Xmm11, 28, zmm11, 0, 16) \ + X(Xmm12, 29, zmm12, 0, 16) \ + X(Xmm13, 30, zmm13, 0, 16) \ + X(Xmm14, 31, zmm14, 0, 16) \ + X(Xmm15, 32, zmm15, 0, 16) \ X(St0, 33, st0, 0, 10) \ X(St1, 34, st1, 0, 10) \ X(St2, 35, st2, 0, 10) \ @@ -1611,14 +1635,14 @@ typedef enum DW_ExprOpEnum X(St5, 38, st5, 0, 10) \ X(St6, 39, st6, 0, 10) \ X(St7, 40, st7, 0, 10) \ - X(Mm0, 41, mm0, 0, 8) \ - X(Mm1, 42, mm1, 0, 8) \ - X(Mm2, 43, mm2, 0, 8) \ - X(Mm3, 44, mm3, 0, 8) \ - X(Mm4, 45, mm4, 0, 8) \ - X(Mm5, 46, mm5, 0, 8) \ - X(Mm6, 47, mm6, 0, 8) \ - X(Mm7, 48, mm7, 0, 8) \ + X(Mm0, 41, fpr0, 0, 8) \ + X(Mm1, 42, fpr1, 0, 8) \ + X(Mm2, 43, fpr2, 0, 8) \ + X(Mm3, 44, fpr3, 0, 8) \ + X(Mm4, 45, fpr4, 0, 8) \ + X(Mm5, 46, fpr5, 0, 8) \ + X(Mm6, 47, fpr6, 0, 8) \ + X(Mm7, 48, fpr7, 0, 8) \ X(Rflags, 49, rflags, 0, 4) \ X(Es, 50, es, 0, 2) \ X(Cs, 51, cs, 0, 2) \ @@ -1631,18 +1655,20 @@ typedef enum DW_ExprOpEnum X(Tr, 62, nil, 0, 0) \ X(Ldtr, 63, nil, 0, 0) -typedef U32 DW_RegX86; +typedef U32 DW_Reg; + +typedef DW_Reg DW_RegX86; typedef enum DW_RegX86Enum { -#define X(_N,_ID,...) DW_Reg_x86_##_N = _ID, +#define X(_N,_ID,...) DW_RegX86_##_N = _ID, DW_Regs_X86_XList(X) #undef X } DW_RegX86Enum; -typedef U32 DW_RegX64; +typedef DW_Reg DW_RegX64; typedef enum DW_RegX64Enum { -#define X(_N,_ID,...) DW_Reg_x64_##_N = _ID, +#define X(_N,_ID,...) DW_RegX64_##_N = _ID, DW_Regs_X64_XList(X) #undef X } DW_RegX64Enum; diff --git a/src/dwarf/dwarf_enum.c b/src/dwarf/dwarf_enum.c index 68b29463..8ea41d98 100644 --- a/src/dwarf/dwarf_enum.c +++ b/src/dwarf/dwarf_enum.c @@ -12,7 +12,11 @@ dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op) case DW_Ext_LLVM: break; case DW_Ext_APPLE: break; case DW_Ext_MIPS: break; - case DW_Ext_GNU: DW_Expr_GNU_XList(X); break; + case DW_Ext_GNU: { + switch (op) { + DW_Expr_GNU_XList(X); + } + } break; } switch (ver) { @@ -48,6 +52,7 @@ internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind) { switch (kind) { + case DW_Tag_Null: return str8_lit("Null"); #define X(_N,_ID) case DW_Tag_##_N: return str8_lit(Stringify(_N)); DW_Tag_V3_XList(X) DW_Tag_V5_XList(X) @@ -149,6 +154,50 @@ dw_string_from_language(Arena *arena, DW_Language kind) return push_str8f(arena, "%x", kind); } +internal String8 +dw_string_from_inl(Arena *arena, DW_InlKind kind) +{ + switch (kind) { +#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N)); + DW_Inl_XList(X) +#undef X + } + return push_str8f(arena, "%x", kind); +} + +internal String8 +dw_string_from_access_kind(Arena *arena, DW_AccessKind kind) +{ + switch (kind) { +#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N)); + DW_AccessKind_XList(X) +#undef X + } + return push_str8f(arena, "%llx", kind); +} + +internal String8 +dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind) +{ + switch (kind) { +#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N)); + DW_CallingConventionKind_XList(X) +#undef X + } + return push_str8f(arena, "%llx", kind); +} + +internal String8 +dw_string_from_attrib_type_encoding(Arena *arena, DW_AttribTypeEncodingKind kind) +{ + switch (kind) { +#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N)); + DW_AttribTypeEncodingKind_XList(X) +#undef X + } + return push_str8f(arena, "%llx", kind); +} + internal String8 dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind) { @@ -201,14 +250,14 @@ dw_string_from_register(Arena *arena, Arch arch, U64 reg_id) case Arch_Null: break; case Arch_x86: { switch (reg_id) { - #define X(_N, _ID, ...) case DW_Reg_x86_##_N: reg_str = str8_lit(Stringify(_ID)); break; + #define X(_N, _ID, ...) case DW_RegX86_##_N: reg_str = str8_lit(Stringify(_N)); break; DW_Regs_X86_XList(X) #undef X } } break; case Arch_x64: { switch (reg_id) { - #define X(_N, _ID, ...) case DW_Reg_x64_##_N: reg_str = str8_lit(Stringify(_ID)); break; + #define X(_N, _ID, ...) case DW_RegX64_##_N: reg_str = str8_lit(Stringify(_N)); break; DW_Regs_X64_XList(X) #undef X } diff --git a/src/dwarf/dwarf_enum.h b/src/dwarf/dwarf_enum.h index 1bbc3898..1a770ee9 100644 --- a/src/dwarf/dwarf_enum.h +++ b/src/dwarf/dwarf_enum.h @@ -8,6 +8,7 @@ internal String8 dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind); internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind); internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind); +internal String8 dw_string_access_kind(Arena *arena, DW_AccessKind kind); //internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id); diff --git a/src/dwarf/dwarf_unwind.c b/src/dwarf/dwarf_unwind.c index 2731dd9c..4ca39ce9 100644 --- a/src/dwarf/dwarf_unwind.c +++ b/src/dwarf/dwarf_unwind.c @@ -148,7 +148,7 @@ dw_unwind_x64__apply_frame_rules(String8 raw_eh_frame, // is this a roll-over CFA? B32 is_roll_over_cfa = 0; - if (reg_idx == DW_Reg_x64_Rsp) { + if (reg_idx == DW_RegX64_Rsp) { DW_CFIRegisterRule rule = row->cells[reg_idx].rule; if (rule == DW_CFIRegisterRule_Undefined || rule == DW_CFIRegisterRule_SameValue) { is_roll_over_cfa = 1; From 8a8a8bcc8db69d7946bbd26744e805d757885744 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 10 Feb 2025 11:57:38 -0800 Subject: [PATCH 185/755] resource id compar typo --- src/coff/coff_parse.c | 122 +++++++++++++++++++++--------------------- src/pe/pe.c | 2 +- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/coff/coff_parse.c b/src/coff/coff_parse.c index 6628722b..3e0aaee4 100644 --- a/src/coff/coff_parse.c +++ b/src/coff/coff_parse.c @@ -8,9 +8,9 @@ coff_is_big_obj(String8 raw_coff) if (raw_coff.size >= sizeof(COFF_BigObjHeader)) { COFF_BigObjHeader *file_header32 = (COFF_BigObjHeader*)(raw_coff.str); is_big_obj = file_header32->sig1 == COFF_Machine_Unknown && - file_header32->sig2 == max_U16 && - file_header32->version >= 2 && - MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0; + file_header32->sig2 == max_U16 && + file_header32->version >= 2 && + MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0; } return is_big_obj; } @@ -163,11 +163,11 @@ coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_ Rng1U64 sym16_arr_range = rng_1u64(symbol_array_off, symbol_array_off + sizeof(COFF_Symbol16) * symbol_count); String8 raw_sym16_arr = str8_substr(raw_coff, sym16_arr_range); COFF_Symbol16 *sym16_arr = (COFF_Symbol16 *)raw_sym16_arr.str; - + for (U64 isymbol = 0, count = raw_sym16_arr.size / sizeof(COFF_Symbol16); isymbol < count; isymbol += 1) { COFF_Symbol16 *sym16 = &sym16_arr[isymbol]; COFF_Symbol32 *sym32 = &result.v[isymbol]; - + sym32->name = sym16->name; sym32->value = sym16->value; if (sym16->section_number == COFF_Symbol_DebugSection16) { @@ -185,7 +185,7 @@ coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_ for (U64 iaux = isymbol+1, iaux_hi = Min(count, iaux+sym16->aux_symbol_count); iaux < iaux_hi; iaux += 1) { COFF_Symbol16 *aux16 = sym16_arr + iaux; COFF_Symbol32 *aux32 = result.v + iaux; - + // 32bit COFF uses 16bit aux symbols MemoryCopy(aux32, aux16, sizeof(COFF_Symbol16)); MemoryZero((U8 *)aux32 + sizeof(COFF_Symbol16), sizeof(COFF_Symbol32)-sizeof(COFF_Symbol16)); @@ -286,11 +286,11 @@ coff_resource_string_from_str16(Arena *arena, String16 string) { AssertAlways(string.size <= max_U16); U16 size16 = (U16)string.size; - + U16 *buffer = push_array_no_zero(arena, U16, size16 + 1); MemoryCopy(buffer + 0, &size16, sizeof(size16)); MemoryCopy(buffer + 1, string.str, size16 * sizeof(string.str[0])); - + return str8_array(buffer, size16 + 1); } @@ -358,14 +358,14 @@ coff_read_resource(Arena *arena, String8 raw_res, U64 off, COFF_ParsedResource * { String8 raw_header = str8_skip(raw_res, off); U64 header_cursor = 0; - + // prefix COFF_ResourceHeaderPrefix prefix = {0}; header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &prefix); - + Assert(prefix.header_size >= sizeof(COFF_ResourceHeaderPrefix)); raw_header = str8_prefix(raw_header, prefix.header_size); - + // header COFF_ResourceID16 type_16 = {0}; COFF_ResourceID16 name_16 = {0}; @@ -377,11 +377,11 @@ coff_read_resource(Arena *arena, String8 raw_res, U64 off, COFF_ParsedResource * header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->version); header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->characteristics); Assert(prefix.header_size == header_cursor); - + // convert utf-16 resource ids to utf-8 res_out->type = coff_utf8_resource_id_from_utf16(arena, &type_16); res_out->name = coff_utf8_resource_id_from_utf16(arena, &name_16); - + // read data U64 data_read_size = str8_deserial_read_block(raw_res, off + prefix.header_size, prefix.data_size, &res_out->data); Assert(prefix.data_size == data_read_size); @@ -411,14 +411,14 @@ coff_write_resource_id(Arena *arena, COFF_ResourceID id) { String8 result = str8_zero(); switch (id.type) { - case COFF_ResourceIDType_Null: break; - case COFF_ResourceIDType_Number: { - result = coff_resource_number_from_u16(arena, id.u.number); - } break; - case COFF_ResourceIDType_String: { - result = coff_resource_string_from_str8(arena, id.u.string); - } break; - default: InvalidPath; + case COFF_ResourceIDType_Null: break; + case COFF_ResourceIDType_Number: { + result = coff_resource_number_from_u16(arena, id.u.number); + } break; + case COFF_ResourceIDType_String: { + result = coff_resource_string_from_str8(arena, id.u.string); + } break; + default: InvalidPath; } return result; } @@ -435,13 +435,13 @@ coff_write_resource(Arena *arena, String8 data) { Temp scratch = scratch_begin(&arena, 1); - + String8List list = {0}; - + COFF_ResourceHeaderPrefix *prefix = push_array(scratch.arena, COFF_ResourceHeaderPrefix, 1); String8 packed_type = coff_write_resource_id(scratch.arena, type); String8 packed_name = coff_write_resource_id(scratch.arena, name); - + // prefix + header str8_list_push(scratch.arena, &list, str8_struct(prefix)); str8_list_push(scratch.arena, &list, packed_type); @@ -451,24 +451,24 @@ coff_write_resource(Arena *arena, str8_list_push(scratch.arena, &list, str8_struct(&language_id)); str8_list_push(scratch.arena, &list, str8_struct(&version)); str8_list_push(scratch.arena, &list, str8_struct(&characteristics)); - + prefix->data_size = safe_cast_u32(data.size); prefix->header_size = safe_cast_u32(list.total_size); - + // data str8_list_push(scratch.arena, &list, data); - + // magic str8_list_push_front(scratch.arena, &list, str8_array_fixed(g_coff_res_magic)); - + // align U64 align_size = AlignPow2(list.total_size, COFF_ResourceAlign) - list.total_size; U8 *align = push_array(scratch.arena, U8, align_size); str8_list_push(scratch.arena, &list, str8(align, align_size)); - + // join String8 res = str8_list_join(arena, &list, 0); - + scratch_end(scratch); return res; } @@ -476,15 +476,15 @@ coff_write_resource(Arena *arena, internal int coff_resource_id_compar(void *raw_a, void *raw_b) { - int cmp = 0; + int cmp; COFF_ResourceID *a = raw_a; COFF_ResourceID *b = raw_b; if (a->type == b->type) { switch (a->type) { - case COFF_ResourceIDType_Null: cmp = 0; break; - case COFF_ResourceIDType_Number: cmp = MemoryCompare(&a->u.number, &b->u.number, sizeof(a->u.number)); break; - case COFF_ResourceIDType_String: cmp = strncmp((char *)a->u.string.str, (char *)b->u.string.str, Min(a->u.string.size, b->u.string.size)); break; - default: InvalidPath; break; + default: + case COFF_ResourceIDType_Null: cmp = 0; break; + case COFF_ResourceIDType_Number: cmp = MemoryCompare(&a->u.number, &b->u.number, sizeof(a->u.number)); break; + case COFF_ResourceIDType_String: cmp = strncmp((char *)a->u.string.str, (char *)b->u.string.str, Min(a->u.string.size, b->u.string.size)); break; } } else { cmp = a->type < b->type ? -1 : a->type > b->type ? +1 : 0; @@ -563,10 +563,10 @@ coff_parse_archive_member_header(String8 raw_archive, U64 offset, COFF_ParsedArc String8 mode = str8_skip_chop_whitespace(str8_cstring_capped(header->mode, header->mode + sizeof(header->mode) )); String8 size = str8_skip_chop_whitespace(str8_cstring_capped(header->size, header->size + sizeof(header->size) )); String8 end = str8_cstring_capped(header->end, header->end + sizeof(header->end)); - + U32 data_size = u32_from_str8(size, 10); U64 data_off = offset + sizeof(COFF_ArchiveMemberHeader); - + header_out->name = name; header_out->time_stamp = u32_from_str8(date, 10); header_out->user_id = u32_from_str8(user_id, 10); @@ -574,7 +574,7 @@ coff_parse_archive_member_header(String8 raw_archive, U64 offset, COFF_ParsedArc header_out->mode = mode; header_out->is_end_correct = str8_match_lit("`\n", end, 0); header_out->data_range = rng_1u64(data_off, data_off + data_size); - + return sizeof(*header); } return 0; @@ -584,7 +584,7 @@ internal COFF_ArchiveFirstMember coff_parse_first_archive_member(COFF_ArchiveMember *member) { Assert(str8_match_lit("/", member->header.name, 0)); - + U64 cursor = 0; U32 symbol_count = 0; @@ -597,17 +597,17 @@ coff_parse_first_archive_member(COFF_ArchiveMember *member) Rng1U64 string_table_range = rng_1u64(cursor, member->data.size); cursor += dim_1u64(string_table_range); - + String8 raw_member_offsets = str8_substr(member->data, member_offsets_range); U32 *member_offsets = (U32 *)raw_member_offsets.str; U64 member_offset_count = raw_member_offsets.size / sizeof(member_offsets[0]); - + COFF_ArchiveFirstMember result = {0}; result.symbol_count = symbol_count; result.member_offset_count = member_offset_count; result.member_offsets = member_offsets; result.string_table = str8_substr(member->data, string_table_range); - + return result; } @@ -615,7 +615,7 @@ internal COFF_ArchiveSecondMember coff_parse_second_archive_member(COFF_ArchiveMember *member) { COFF_ArchiveSecondMember result = {0}; - + if (str8_match_lit("/", member->header.name, 0)) { U64 cursor = 0; @@ -632,13 +632,13 @@ coff_parse_second_archive_member(COFF_ArchiveMember *member) cursor += dim_1u64(symbol_indices_range); Rng1U64 string_table_range = rng_1u64(cursor, member->data.size); - + String8 raw_member_offsets = str8_substr(member->data, member_offsets_range); String8 raw_indices = str8_substr(member->data, symbol_indices_range); - + U32 *member_offsets = (U32 *)raw_member_offsets.str; U64 member_offset_count = raw_member_offsets.size / sizeof(member_offsets[0]); - + U16 *symbol_indices = (U16 *)raw_indices.str; U64 symbol_index_count = raw_indices.size / sizeof(symbol_indices[0]); @@ -650,7 +650,7 @@ coff_parse_second_archive_member(COFF_ArchiveMember *member) result.symbol_index_count = symbol_index_count; result.string_table = str8_substr(member->data, string_table_range); } - + return result; } @@ -683,7 +683,7 @@ coff_parse_import(String8 raw_archive_member, U64 offset, COFF_ParsedArchiveImpo Rng1U64 data_range = rng_1u64(offset + sizeof(*header), offset + sizeof(*header) + header->data_size); String8 raw_data = str8_substr(raw_archive_member, data_range); U64 data_cursor = 0; - + header_out->version = header->version; header_out->machine = header->machine; header_out->time_stamp = header->time_stamp; @@ -744,7 +744,7 @@ coff_regular_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_Arc if (member_out->header.is_end_correct) { member_out->offset = *offset; member_out->data = str8_substr(raw_archive, member_out->header.data_range); - + U64 read_size = AlignPow2(header_size + dim_1u64(member_out->header.data_range), COFF_Archive_MemberAlign); *offset += read_size; @@ -771,19 +771,19 @@ coff_thin_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_Archiv member_out->header.is_end_correct = 0; U64 header_size = coff_parse_archive_member_header(raw_archive, *offset, &member_out->header); - + if (member_out->header.is_end_correct) { Rng1U64 data_in_archive_range = {0}; if (str8_match_lit("/", member_out->header.name, 0) || str8_match_lit("//", member_out->header.name, 0)) { data_in_archive_range = member_out->header.data_range; } - + member_out->offset = *offset; member_out->data = str8_substr(raw_archive, data_in_archive_range); - + U64 read_size = AlignPow2(header_size + dim_1u64(data_in_archive_range), COFF_Archive_MemberAlign); *offset += read_size; - + is_parsed = 1; } @@ -806,9 +806,9 @@ coff_archive_parse_from_member_list(COFF_ArchiveMemberList member_list) COFF_ArchiveMember first_header = {0}; COFF_ArchiveMember second_header = {0}; COFF_ArchiveMember long_names_member = {0}; - + COFF_ArchiveMemberNode *ptr = member_list.first; - + if (ptr) { if (str8_match_lit("/", ptr->data.header.name, 0)) { if (ptr->data.header.is_end_correct) { @@ -821,7 +821,7 @@ coff_archive_parse_from_member_list(COFF_ArchiveMemberList member_list) } else { error = str8_lit("missing first header"); } - + if (!error.size && ptr) { if (str8_match_lit("/", ptr->data.header.name, 0)) { if (ptr->data.header.is_end_correct) { @@ -833,7 +833,7 @@ coff_archive_parse_from_member_list(COFF_ArchiveMemberList member_list) } } } - + if (!error.size && ptr) { if (str8_match_lit("//", ptr->data.header.name, 0)) { if (ptr->data.header.is_end_correct) { @@ -853,7 +853,7 @@ coff_archive_parse_from_member_list(COFF_ArchiveMemberList member_list) parse.second_member = coff_parse_second_archive_member(&second_header); parse.long_names = long_names_member.data; parse.error = error; - + return parse; } @@ -894,9 +894,9 @@ coff_archive_parse_from_data(String8 raw_archive) { COFF_ArchiveType type = coff_archive_type_from_data(raw_archive); switch (type) { - case COFF_Archive_Null: break; - case COFF_Archive_Regular: return coff_regular_archive_parse_from_data(raw_archive); - case COFF_Archive_Thin: return coff_thin_archive_parse_from_data(raw_archive); + case COFF_Archive_Null: break; + case COFF_Archive_Regular: return coff_regular_archive_parse_from_data(raw_archive); + case COFF_Archive_Thin: return coff_thin_archive_parse_from_data(raw_archive); } COFF_ArchiveParse null_parse = {0}; return null_parse; diff --git a/src/pe/pe.c b/src/pe/pe.c index 3726df0c..f6dc53b5 100644 --- a/src/pe/pe.c +++ b/src/pe/pe.c @@ -1568,7 +1568,7 @@ pe_resource_dir_push_dir(Arena *arena, PE_ResourceDir *dir, COFF_ResourceID id, internal PE_ResourceNode * pe_resource_dir_search_node(PE_ResourceDir *dir, COFF_ResourceID id) { - for (PE_ResourceNode *i = dir->id_list.first; i != NULL; i = i->next) { + for (PE_ResourceNode *i = dir->id_list.first; i != 0; i = i->next) { if (coff_resource_id_compar(&i->data.id, &id) == 0) { return i; } From bbce89eadaf44bac13dffc768996a4143c37fff0 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 10 Feb 2025 16:18:59 -0800 Subject: [PATCH 186/755] added /RAD_WRITE_TEMP_FILES When enabled linker writes image and debug info to temporary files and renames them after all writes are done. --- src/linker/lnk.c | 27 +++++++----- src/linker/lnk.h | 1 + src/linker/lnk_config.c | 15 ++++++- src/linker/lnk_config.h | 5 +++ src/linker/lnk_debug_info.c | 2 +- src/linker/lnk_io.c | 73 ++++++++++++++++++++++++------- src/linker/lnk_io.h | 6 ++- src/os/core/os_core.c | 10 +++++ src/os/core/os_core.h | 17 ++++--- src/os/core/win32/os_core_win32.c | 39 ++++++++++++++--- 10 files changed, 148 insertions(+), 47 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 4960fb17..83c368db 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -358,7 +358,7 @@ lnk_manifest_from_inputs(Arena *arena, // write linker manifest to temp file String8 linker_manifest_path = push_str8f(scratch.arena, "%S.manifest.temp", manifest_name); - lnk_write_data_to_file_path(linker_manifest_path, linker_manifest); + lnk_write_data_to_file_path(linker_manifest_path, str8_zero(), linker_manifest); // push linker manifest str8_list_push(scratch.arena, &input_manifest_path_list, linker_manifest_path); @@ -3079,7 +3079,7 @@ lnk_write_thread(void *raw_ctx) { ProfBeginFunction(); LNK_WriteThreadContext *ctx = raw_ctx; - lnk_write_data_to_file_path(ctx->path, ctx->data); + lnk_write_data_to_file_path(ctx->path, ctx->temp_path, ctx->data); ProfEnd(); } @@ -3254,7 +3254,7 @@ lnk_run(int argc, char **argv) LNK_ObjList obj_list = {0}; LNK_LibList lib_index[LNK_InputSource_Count] = {0}; String8 image_data = str8_zero(); - OS_Handle image_write_thread = {0}; + OS_Handle image_write_thread = {0}; // init state machine struct StateList state_list = {0}; @@ -3763,7 +3763,7 @@ lnk_run(int argc, char **argv) ProfBeginDynamic("Write Manifest To: %.*s", str8_varg(config->manifest_name)); Temp temp = temp_begin(scratch.arena); String8 manifest_data = lnk_manifest_from_inputs(temp.arena, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, input_manifest_path_list, manifest_dep_list); - lnk_write_data_to_file_path(config->manifest_name, manifest_data); + lnk_write_data_to_file_path(config->manifest_name, str8_zero(), manifest_data); temp_end(temp); ProfEnd(); } break; @@ -4080,10 +4080,14 @@ lnk_run(int argc, char **argv) } } - LNK_WriteThreadContext *ctx = push_array(scratch.arena, LNK_WriteThreadContext, 1); - ctx->path = config->image_name; - ctx->data = image_data; - image_write_thread = os_thread_launch(lnk_write_thread, ctx, 0); + // write image file in background + { + LNK_WriteThreadContext *ctx = push_array(scratch.arena, LNK_WriteThreadContext, 1); + ctx->path = config->image_name; + ctx->temp_path = config->temp_image_name; + ctx->data = image_data; + image_write_thread = os_thread_launch(lnk_write_thread, ctx, 0); + } if (lnk_get_log_status(LNK_Log_InputObj)) { U64 total_input_size = 0; @@ -4110,7 +4114,7 @@ lnk_run(int argc, char **argv) ProfBegin("Build Imp Lib"); lnk_timer_begin(LNK_Timer_Lib); String8List lib_list = lnk_build_import_lib(tp, tp_arena, config->machine, config->time_stamp, config->imp_lib_name, config->image_name, exptab); - lnk_write_data_list_to_file_path(config->imp_lib_name, lib_list); + lnk_write_data_list_to_file_path(config->imp_lib_name, str8_zero(), lib_list); lnk_timer_end(LNK_Timer_Lib); ProfEnd(); } break; @@ -4143,7 +4147,8 @@ lnk_run(int argc, char **argv) input.parsed_symbols, types); - lnk_write_data_list_to_file_path(config->rad_debug_name, rdi_data); + lnk_write_data_list_to_file_path(config->rad_debug_name, config->temp_rad_debug_name, rdi_data); + lnk_timer_end(LNK_Timer_Rdi); } @@ -4177,7 +4182,7 @@ lnk_run(int argc, char **argv) input.parsed_symbols, types); - lnk_write_data_list_to_file_path(config->pdb_name, pdb_data); + lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data); lnk_timer_end(LNK_Timer_Pdb); } diff --git a/src/linker/lnk.h b/src/linker/lnk.h index 9f2b1b35..d6732174 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -224,6 +224,7 @@ typedef struct typedef struct { String8 path; + String8 temp_path; String8 data; } LNK_WriteThreadContext; diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 7d123f23..0f07977f 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -152,17 +152,17 @@ global read_only struct { LNK_CmdSwitch_Rad_PdbHashTypeNames, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." }, { LNK_CmdSwitch_Rad_SectVirtOff, "RAD_SECT_VIRT_OFF", ":#", "Set RVA where section data is placed in memory. For internal use only." }, { LNK_CmdSwitch_Rad_SharedThreadPool, "RAD_SHARED_THREAD_POOL", "[:STRING]", "Default value \"" LNK_DEFAULT_THREAD_POOL_NAME "\"" }, - { LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Sets maximum number of workers in a thread pool." }, + { LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Sets maximum number of workers in a thread pool." }, { LNK_CmdSwitch_Rad_SuppressError, "RAD_SUPPRESS_ERROR", ":#", "" }, { LNK_CmdSwitch_Rad_SymbolTableCapDefined, "RAD_SYMBOL_TABLE_CAP_DEFINED", ":#", "Number of buckets allocated in the symbol table for defined symbols." }, { LNK_CmdSwitch_Rad_SymbolTableCapInternal, "RAD_SYMBOL_TABLE_CAP_INTERNAL", ":#", "Number of buckets allocated in the symbol table for internal symbols." }, { LNK_CmdSwitch_Rad_SymbolTableCapLib, "RAD_SYMBOL_TABLE_CAP_LIB", ":#", "Number of buckets allocated in the symbol table for library symbols." }, { LNK_CmdSwitch_Rad_SymbolTableCapWeak, "RAD_SYMBOL_TABLE_CAP_WEAK", ":#", "Number of buckets allocated in the symbol table for weak symbols." }, { LNK_CmdSwitch_Rad_TargetOs, "RAD_TARGET_OS", ":{WINDOWS,LINUX,MAC}" }, + { LNK_CmdSwitch_Rad_WriteTempFiles, "RAD_WRITE_TEMP_FILES", "[:NO]", "When speicifed linker writes image and debug info to temporary files and renames after link is done." }, { LNK_CmdSwitch_Rad_TimeStamp, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." }, { LNK_CmdSwitch_Rad_Version, "RAD_VERSION", "", "Print version and exit." }, { LNK_CmdSwitch_Rad_Workers, "RAD_WORKERS", ":#", "Sets number of workers created in the pool. Number is capped at 1024. When /RAD_SHARED_THREAD_POOL is specified this number cant exceed /RAD_SHARED_THREAD_POOL_MAX_WORKERS." }, - { LNK_CmdSwitch_Help, "HELP", "", "" }, { LNK_CmdSwitch_Help, "?", "", "" }, }; @@ -1754,6 +1754,10 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam } } break; + case LNK_CmdSwitch_Rad_WriteTempFiles: { + lnk_cmd_switch_parse_flag(obj_path, lib_path, cmd_switch, value_strings, &config->write_temp_files); + } break; + case LNK_CmdSwitch_Rad_TimeStamp: { lnk_cmd_switch_parse_u32(obj_path, lib_path, cmd_switch, value_strings, &config->time_stamp, 0); } break; @@ -2054,6 +2058,13 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line) // :Rad_DebugAltPath config->rad_debug_alt_path = lnk_expand_env_vars_windows(arena, env_vars, config->rad_debug_alt_path); + // create temporary files names + if (config->write_temp_files == LNK_SwitchState_Yes) { + config->temp_image_name = push_str8f(arena, "%S.tmp%x", config->image_name, config->time_stamp); + config->temp_pdb_name = push_str8f(arena, "%S.tmp%x", config->pdb_name, config->time_stamp); + config->temp_rad_debug_name = push_str8f(arena, "%S.tmp%x", config->rad_debug_name, config->time_stamp); + } + if (lnk_get_log_status(LNK_Log_Debug)) { String8 full_cmd_line = str8_list_join(scratch.arena, &raw_cmd_line, &(StringJoin){ .sep = str8_lit_comp(" ") }); fprintf(stderr, "--------------------------------------------------------------------------------\n"); diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index 871e9662..ea9d3edc 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -155,6 +155,7 @@ typedef enum LNK_CmdSwitch_Rad_SymbolTableCapInternal, LNK_CmdSwitch_Rad_SymbolTableCapWeak, LNK_CmdSwitch_Rad_SymbolTableCapLib, + LNK_CmdSwitch_Rad_WriteTempFiles, LNK_CmdSwitch_Rad_TargetOs, LNK_CmdSwitch_Rad_TimeStamp, LNK_CmdSwitch_Rad_Version, @@ -364,6 +365,10 @@ typedef struct LNK_Config U64 symbol_table_cap_lib; B32 build_imp_lib; B32 build_exp; + LNK_SwitchState write_temp_files; + String8 temp_image_name; + String8 temp_pdb_name; + String8 temp_rad_debug_name; } LNK_Config; typedef enum diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index b3418b83..7e857d20 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -2676,7 +2676,7 @@ lnk_replace_type_names_with_hashes(TP_Context *tp, TP_Arena *arena, CV_DebugT de if (task.make_map) { String8List map = {0}; str8_list_concat_in_place_array(&map, task.maps, tp->worker_count); - lnk_write_data_list_to_file_path(map_name, map); + lnk_write_data_list_to_file_path(map_name, str8_zero(), map); tp_arena_release(&task.map_arena); } diff --git a/src/linker/lnk_io.c b/src/linker/lnk_io.c index 8969cd50..e781b1e8 100644 --- a/src/linker/lnk_io.c +++ b/src/linker/lnk_io.c @@ -10,6 +10,15 @@ lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t return !os_handle_match(handle, os_handle_zero()); } +shared_function int +lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max) +{ + OS_Handle handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, str8((U8*)path, path_size)); + Assert(sizeof(handle) <= handle_buffer_max); + MemoryCopy(handle_buffer, &handle, sizeof(handle)); + return !os_handle_match(handle, os_handle_zero()); +} + shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max) { @@ -26,6 +35,14 @@ lnk_close_file(void *raw_handle) os_file_close(handle); } +shared_function int +lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size) +{ + OS_Handle handle = *(OS_Handle *)raw_handle; + B32 is_renamed = os_rename_file_by_handle(handle, str8((U8*)new_file_path, new_file_path_size)); + return (int)is_renamed; +} + shared_function uint64_t lnk_size_from_file(void *raw_handle) { @@ -163,34 +180,56 @@ lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array } internal void -lnk_write_data_list_to_file_path(String8 path, String8List data) +lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List data) { ProfBeginV("Write %M to %S", data.total_size, path); - B32 is_written = 0; + U64 bytes_written = 0; - OS_Handle handle; - if (lnk_open_file_write((char*)path.str, path.size, &handle, sizeof(handle))) { - U64 offset = 0; - for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) { - U64 write_size = lnk_write_file(&handle, offset, data_n->string.str, data_n->string.size); - if (write_size != data_n->string.size) { - break; + B32 open_with_rename = (temp_path.size > 0); + OS_Handle file_handle = {0}; + if (open_with_rename) { + lnk_open_file_write_rename((char*)temp_path.str, temp_path.size, &file_handle, sizeof(file_handle)); + } else { + lnk_open_file_write((char*)path.str, path.size, &file_handle, sizeof(file_handle)); + } + + if (!os_handle_match(file_handle, os_handle_zero())) { + // write data nodes + { + for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) { + U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size); + if (write_size != data_n->string.size) { + break; + } + bytes_written += data_n->string.size; } - offset += data_n->string.size; } - lnk_close_file(&handle); + B32 is_write_complete = (bytes_written == data.total_size); - is_written = (offset == data.total_size); - if (is_written) { + if (is_write_complete) { + // rename file to original name + if (open_with_rename) { + if (lnk_rename_file(&file_handle, (char*)path.str, path.size)) { + lnk_log(LNK_Log_IO_Write, "Renamed %S -> %S", temp_path, path); + } else { + lnk_error(LNK_Error_IO, "failed to rename %S -> %S", temp_path, path); + } + } + } + + // log write + if (is_write_complete) { if (lnk_get_log_status(LNK_Log_IO_Write)) { lnk_log(LNK_Log_IO_Write, "File \"%S\" %M written", path, data.total_size); } } else { - lnk_error(LNK_Error_IO, "incomplete write occurred, %M written, expected %M, file %S", - offset, data.total_size, path); + lnk_error(LNK_Error_IO, "incomplete write, %M written, expected %M, file %S", bytes_written, data.total_size, path); } + + // clean up handle + lnk_close_file(&file_handle); } else { lnk_error(LNK_Error_NoAccess, "don't have access to write to %S", path); } @@ -199,12 +238,12 @@ lnk_write_data_list_to_file_path(String8 path, String8List data) } internal void -lnk_write_data_to_file_path(String8 path, String8 data) +lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data) { Temp scratch = scratch_begin(0,0); String8List data_list = {0}; str8_list_push(scratch.arena, &data_list, data); - lnk_write_data_list_to_file_path(path, data_list); + lnk_write_data_list_to_file_path(path, temp_path, data_list); scratch_end(scratch); } diff --git a/src/linker/lnk_io.h b/src/linker/lnk_io.h index 9bd504bb..7771caf0 100644 --- a/src/linker/lnk_io.h +++ b/src/linker/lnk_io.h @@ -17,7 +17,9 @@ typedef struct shared_function int lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); +shared_function int lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); shared_function void lnk_close_file(void *raw_handle); +shared_function int lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size); shared_function uint64_t lnk_size_from_file(void *raw_handle); shared_function uint64_t lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max); shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size); @@ -27,8 +29,8 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void internal String8 lnk_read_data_from_file_path(Arena *arena, String8 path); internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array path_arr); -internal void lnk_write_data_list_to_file_path(String8 path, String8List list); -internal void lnk_write_data_to_file_path(String8 path, String8 data); +internal void lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List list); +internal void lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data); internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path); diff --git a/src/os/core/os_core.c b/src/os/core/os_core.c index 21a0a413..f44d5cb8 100644 --- a/src/os/core/os_core.c +++ b/src/os/core/os_core.c @@ -151,6 +151,16 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range) return result; } +internal B32 +os_rename_file(String8 orig_name, String8 new_name) +{ + Temp scratch = scratch_begin(0,0); + OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, orig_name); + B32 is_renamed = os_rename_file_by_handle(file, new_name); + os_file_close(file); + return is_renamed; +} + //////////////////////////////// //~ rjf: Process Launcher Helpers diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 5f09ca8b..3f4075b0 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -38,13 +38,14 @@ struct OS_ProcessInfo typedef U32 OS_AccessFlags; enum { - OS_AccessFlag_Read = (1<<0), - OS_AccessFlag_Write = (1<<1), - OS_AccessFlag_Execute = (1<<2), - OS_AccessFlag_Append = (1<<3), - OS_AccessFlag_ShareRead = (1<<4), - OS_AccessFlag_ShareWrite = (1<<5), - OS_AccessFlag_Inherited = (1<<6), + OS_AccessFlag_Read = (1<<0), + OS_AccessFlag_Write = (1<<1), + OS_AccessFlag_Execute = (1<<2), + OS_AccessFlag_Append = (1<<3), + OS_AccessFlag_ShareRead = (1<<4), + OS_AccessFlag_ShareWrite = (1<<5), + OS_AccessFlag_ShareDelete = (1<<6), + OS_AccessFlag_Inherited = (1<<7), }; //////////////////////////////// @@ -206,6 +207,8 @@ internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); +internal B32 os_rename_file_by_handle(OS_Handle file, String8 new_name); +internal B32 os_rename_file(String8 orig_name, String8 new_name); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); internal String8 os_full_path_from_path(Arena *arena, String8 path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 6a0e0281..d2b01c69 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -321,13 +321,14 @@ os_file_open(OS_AccessFlags flags, String8 path) DWORD share_mode = 0; DWORD creation_disposition = OPEN_EXISTING; SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0}; - if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;} - if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;} - if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;} - if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;} - if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;} - if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;} - if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; } + if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;} + if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;} + if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;} + if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;} + if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;} + if(flags & OS_AccessFlag_ShareDelete) {share_mode |= FILE_SHARE_DELETE; access_flags |= DELETE;} + if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;} + if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; } if(flags & OS_AccessFlag_Inherited) { security_attributes.bInheritHandle = 1; @@ -469,6 +470,30 @@ os_id_from_file(OS_Handle file) return result; } +internal B32 +os_rename_file_by_handle(OS_Handle file, String8 new_name) +{ + Temp scratch = scratch_begin(0,0); + + HANDLE handle = (HANDLE)file.u64[0]; + + String16 new_name16 = str16_from_8(scratch.arena, new_name); + + U64 file_rename_info_size = sizeof(FILE_RENAME_INFO); + U64 buffer_size = file_rename_info_size + sizeof(WCHAR)*new_name16.size; + U8 *buffer = push_array(scratch.arena, U8, buffer_size); + + FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer; + rename_info->ReplaceIfExists = 1; + rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]); + MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0])); + + BOOL is_renamed = SetFileInformationByHandle(handle, FileRenameInfo, buffer, buffer_size); + + scratch_end(scratch); + return is_renamed; +} + internal B32 os_delete_file_at_path(String8 path) { From d5ab121183ddcbd4482e690886000f0c1d14faaa Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 10 Feb 2025 13:56:38 -0800 Subject: [PATCH 187/755] pre-allocate file size before write --- src/linker/lnk_io.c | 4 ++++ src/os/core/os_core.h | 1 + src/os/core/win32/os_core_win32.c | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/linker/lnk_io.c b/src/linker/lnk_io.c index e781b1e8..792c28e7 100644 --- a/src/linker/lnk_io.c +++ b/src/linker/lnk_io.c @@ -195,6 +195,10 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da } if (!os_handle_match(file_handle, os_handle_zero())) { + if (!os_file_reserve_size(file_handle, data.total_size)) { + lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", path, data.total_size); + } + // write data nodes { for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) { diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 3f4075b0..30b7c142 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -209,6 +209,7 @@ internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); internal B32 os_rename_file_by_handle(OS_Handle file, String8 new_name); internal B32 os_rename_file(String8 orig_name, String8 new_name); +internal B32 os_file_reserve_size(OS_Handle file, U64 size); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); internal String8 os_full_path_from_path(Arena *arena, String8 path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index d2b01c69..fc615797 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -494,6 +494,19 @@ os_rename_file_by_handle(OS_Handle file, String8 new_name) return is_renamed; } +internal B32 +os_file_reserve_size(OS_Handle file, U64 size) +{ + HANDLE handle = (HANDLE)file.u64[0]; + + FILE_ALLOCATION_INFO alloc_info = {0}; + alloc_info.AllocationSize.LowPart = size & max_U32; + alloc_info.AllocationSize.HighPart = (size >> 32) & max_U32; + + BOOL is_reserved = SetFileInformationByHandle(handle, FileAllocationInfo, &alloc_info, sizeof(alloc_info)); + return is_reserved; +} + internal B32 os_delete_file_at_path(String8 path) { From 6c5d2a05cbc0786ac3a0378f26291d441937a53c Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 11 Feb 2025 13:10:03 -0800 Subject: [PATCH 188/755] moved platform depended code from OS layer to linkers IO --- src/linker/lnk_io.c | 219 +++++++++++++++++++----------- src/linker/lnk_io.h | 9 +- src/os/core/os_core.c | 10 -- src/os/core/os_core.h | 4 +- src/os/core/win32/os_core_win32.c | 25 ---- 5 files changed, 146 insertions(+), 121 deletions(-) diff --git a/src/linker/lnk_io.c b/src/linker/lnk_io.c index 792c28e7..6b9aee8d 100644 --- a/src/linker/lnk_io.c +++ b/src/linker/lnk_io.c @@ -10,15 +10,6 @@ lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t return !os_handle_match(handle, os_handle_zero()); } -shared_function int -lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max) -{ - OS_Handle handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, str8((U8*)path, path_size)); - Assert(sizeof(handle) <= handle_buffer_max); - MemoryCopy(handle_buffer, &handle, sizeof(handle)); - return !os_handle_match(handle, os_handle_zero()); -} - shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max) { @@ -35,14 +26,6 @@ lnk_close_file(void *raw_handle) os_file_close(handle); } -shared_function int -lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size) -{ - OS_Handle handle = *(OS_Handle *)raw_handle; - B32 is_renamed = os_rename_file_by_handle(handle, str8((U8*)new_file_path, new_file_path_size)); - return (int)is_renamed; -} - shared_function uint64_t lnk_size_from_file(void *raw_handle) { @@ -70,6 +53,118 @@ lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_ //////////////////////////////// +internal String8List +lnk_file_search(Arena *arena, String8List dir_list, String8 file_path) +{ + ProfBeginFunction(); + Temp scratch = scratch_begin(&arena, 1); + String8List match_list; MemoryZeroStruct(&match_list); + + if (os_file_path_exists(file_path)) { + String8 str = push_str8_copy(arena, file_path); + str8_list_push(arena, &match_list, str); + } + + PathStyle file_path_style = path_style_from_str8(file_path); + B32 is_relative = file_path_style != PathStyle_WindowsAbsolute && + file_path_style != PathStyle_UnixAbsolute; + + if (is_relative) { + for (String8Node *i = dir_list.first; i != 0; i = i->next) { + String8List path_list = {0}; + str8_list_push(scratch.arena, &path_list, i->string); + str8_list_push(scratch.arena, &path_list, file_path); + String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute); + B32 file_exists = os_file_path_exists(path); + if (file_exists) { + B32 is_unique = 1; + OS_FileID file_id = os_id_from_file_path(path); + for (String8Node *k = match_list.first; k != 0; k = k->next) { + OS_FileID test_id = os_id_from_file_path(k->string); + int cmp = os_file_id_compare(test_id, file_id) != 0; + if (cmp == 0) { + is_unique = 0; + break; + } + } + if (is_unique) { + String8 str = push_str8_copy(arena, path); + str8_list_push(arena, &match_list, str); + } + } + } + } + + scratch_end(scratch); + ProfEnd(); + return match_list; +} + +internal OS_Handle +lnk_file_open_with_rename_permissions(String8 path) +{ + OS_Handle file_handle = os_handle_zero(); +#if _WIN32 + Temp scratch = scratch_begin(0,0); + + // open file with permissions to rename + String16 path16 = str16_from_8(scratch.arena, path); + SECURITY_ATTRIBUTES security_attributes = { sizeof(security_attributes) }; + HANDLE native_handle = CreateFileW((WCHAR*)path16.str, + GENERIC_WRITE|DELETE, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + &security_attributes, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + if (native_handle != INVALID_HANDLE_VALUE) { + file_handle.u64[0] = (U64)native_handle; + } + + scratch_end(scratch); +#else +#error "TODO: file rename" +#endif + return file_handle; +} + +internal B32 +lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file) +{ +#if _WIN32 + FILE_DISPOSITION_INFO file_disposition = {0}; + file_disposition.DeleteFile = (BOOL)delete_file; + B32 is_set = SetFileInformationByHandle((HANDLE)handle.u64[0], FileDispositionInfo, &file_disposition, sizeof(file_disposition)); +#else +#error "TODO: file rename" +#endif + return is_set; +} + +internal B32 +lnk_file_rename(OS_Handle handle, String8 new_name) +{ + Temp scratch = scratch_begin(0,0); +#if _WIN32 + String16 new_name16 = str16_from_8(scratch.arena, new_name); + + U64 file_rename_info_size = sizeof(FILE_RENAME_INFO); + U64 buffer_size = file_rename_info_size + sizeof(new_name16.str)*new_name16.size; + U8 *buffer = push_array(scratch.arena, U8, buffer_size); + + FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer; + rename_info->ReplaceIfExists = 1; + rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]); + MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0])); + + B32 is_renamed = SetFileInformationByHandle((HANDLE)handle.u64[0], FileRenameInfo, buffer, buffer_size); +#else +#error "TODO: file rename" +#endif + scratch_end(scratch); + return is_renamed; +} + internal void lnk_log_read(String8 path, U64 size) { @@ -184,38 +279,48 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da { ProfBeginV("Write %M to %S", data.total_size, path); - U64 bytes_written = 0; - B32 open_with_rename = (temp_path.size > 0); OS_Handle file_handle = {0}; + String8 open_file_path = {0}; if (open_with_rename) { - lnk_open_file_write_rename((char*)temp_path.str, temp_path.size, &file_handle, sizeof(file_handle)); + file_handle = lnk_file_open_with_rename_permissions(temp_path); + open_file_path = temp_path; + + // mark file to be deleted on exit, so we don't leave corrupted files on disk + if (!lnk_file_set_delete_on_close(file_handle, 1)) { + lnk_error(LNK_Error_IO, "failed to update file disposition on %S", open_file_path); + } } else { lnk_open_file_write((char*)path.str, path.size, &file_handle, sizeof(file_handle)); + open_file_path = path; } if (!os_handle_match(file_handle, os_handle_zero())) { + // try to reserve up front file size if (!os_file_reserve_size(file_handle, data.total_size)) { - lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", path, data.total_size); + lnk_log(LNK_Log_IO_Write, "Failed to pre-allocate file %S with size %M", open_file_path, data.total_size); } // write data nodes - { - for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) { - U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size); - if (write_size != data_n->string.size) { - break; - } - bytes_written += data_n->string.size; + U64 bytes_written = 0; + for (String8Node *data_n = data.first; data_n != 0; data_n = data_n->next) { + U64 write_size = lnk_write_file(&file_handle, bytes_written, data_n->string.str, data_n->string.size); + if (write_size != data_n->string.size) { + break; } + bytes_written += data_n->string.size; } - B32 is_write_complete = (bytes_written == data.total_size); if (is_write_complete) { - // rename file to original name + // rename temp file if (open_with_rename) { - if (lnk_rename_file(&file_handle, (char*)path.str, path.size)) { + // all writes succeeded, remove delete on exit flag + if (!lnk_file_set_delete_on_close(file_handle, 0)) { + lnk_error(LNK_Error_IO, "failed to update file disposition on %S", open_file_path); + } + + if (lnk_file_rename(file_handle, path)) { lnk_log(LNK_Log_IO_Write, "Renamed %S -> %S", temp_path, path); } else { lnk_error(LNK_Error_IO, "failed to rename %S -> %S", temp_path, path); @@ -223,6 +328,9 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da } } + // clean up file handle + lnk_close_file(&file_handle); + // log write if (is_write_complete) { if (lnk_get_log_status(LNK_Log_IO_Write)) { @@ -231,9 +339,6 @@ lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List da } else { lnk_error(LNK_Error_IO, "incomplete write, %M written, expected %M, file %S", bytes_written, data.total_size, path); } - - // clean up handle - lnk_close_file(&file_handle); } else { lnk_error(LNK_Error_NoAccess, "don't have access to write to %S", path); } @@ -251,50 +356,4 @@ lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data) scratch_end(scratch); } -internal String8List -lnk_file_search(Arena *arena, String8List dir_list, String8 file_path) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - String8List match_list; MemoryZeroStruct(&match_list); - - if (os_file_path_exists(file_path)) { - String8 str = push_str8_copy(arena, file_path); - str8_list_push(arena, &match_list, str); - } - - PathStyle file_path_style = path_style_from_str8(file_path); - B32 is_relative = file_path_style != PathStyle_WindowsAbsolute && - file_path_style != PathStyle_UnixAbsolute; - - if (is_relative) { - for (String8Node *i = dir_list.first; i != 0; i = i->next) { - String8List path_list = {0}; - str8_list_push(scratch.arena, &path_list, i->string); - str8_list_push(scratch.arena, &path_list, file_path); - String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute); - B32 file_exists = os_file_path_exists(path); - if (file_exists) { - B32 is_unique = 1; - OS_FileID file_id = os_id_from_file_path(path); - for (String8Node *k = match_list.first; k != 0; k = k->next) { - OS_FileID test_id = os_id_from_file_path(k->string); - int cmp = os_file_id_compare(test_id, file_id) != 0; - if (cmp == 0) { - is_unique = 0; - break; - } - } - if (is_unique) { - String8 str = push_str8_copy(arena, path); - str8_list_push(arena, &match_list, str); - } - } - } - } - - scratch_end(scratch); - ProfEnd(); - return match_list; -} diff --git a/src/linker/lnk_io.h b/src/linker/lnk_io.h index 7771caf0..13b0d777 100644 --- a/src/linker/lnk_io.h +++ b/src/linker/lnk_io.h @@ -17,20 +17,23 @@ typedef struct shared_function int lnk_open_file_read(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); shared_function int lnk_open_file_write(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); -shared_function int lnk_open_file_write_rename(char *path, uint64_t path_size, void *handle_buffer, uint64_t handle_buffer_max); shared_function void lnk_close_file(void *raw_handle); -shared_function int lnk_rename_file(void *raw_handle, char *new_file_path, uint64_t new_file_path_size); shared_function uint64_t lnk_size_from_file(void *raw_handle); shared_function uint64_t lnk_read_file(void *raw_handle, void *buffer, uint64_t buffer_max); shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_size); //////////////////////////////// +internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path); + +internal OS_Handle lnk_file_open_with_rename_permissions(String8 path); +internal B32 lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file); +internal B32 lnk_file_rename(OS_Handle handle, String8 new_name); + internal String8 lnk_read_data_from_file_path(Arena *arena, String8 path); internal String8Array lnk_read_data_from_file_path_parallel(TP_Context *tp, Arena *arena, String8Array path_arr); internal void lnk_write_data_list_to_file_path(String8 path, String8 temp_path, String8List list); internal void lnk_write_data_to_file_path(String8 path, String8 temp_path, String8 data); -internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path); diff --git a/src/os/core/os_core.c b/src/os/core/os_core.c index f44d5cb8..21a0a413 100644 --- a/src/os/core/os_core.c +++ b/src/os/core/os_core.c @@ -151,16 +151,6 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range) return result; } -internal B32 -os_rename_file(String8 orig_name, String8 new_name) -{ - Temp scratch = scratch_begin(0,0); - OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareWrite|OS_AccessFlag_ShareDelete, orig_name); - B32 is_renamed = os_rename_file_by_handle(file, new_name); - os_file_close(file); - return is_renamed; -} - //////////////////////////////// //~ rjf: Process Launcher Helpers diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 30b7c142..2c07e759 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -44,8 +44,7 @@ enum OS_AccessFlag_Append = (1<<3), OS_AccessFlag_ShareRead = (1<<4), OS_AccessFlag_ShareWrite = (1<<5), - OS_AccessFlag_ShareDelete = (1<<6), - OS_AccessFlag_Inherited = (1<<7), + OS_AccessFlag_Inherited = (1<<6), }; //////////////////////////////// @@ -207,7 +206,6 @@ internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); -internal B32 os_rename_file_by_handle(OS_Handle file, String8 new_name); internal B32 os_rename_file(String8 orig_name, String8 new_name); internal B32 os_file_reserve_size(OS_Handle file, U64 size); internal B32 os_delete_file_at_path(String8 path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index fc615797..90b1277c 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -326,7 +326,6 @@ os_file_open(OS_AccessFlags flags, String8 path) if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;} if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;} if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;} - if(flags & OS_AccessFlag_ShareDelete) {share_mode |= FILE_SHARE_DELETE; access_flags |= DELETE;} if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;} if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; } if(flags & OS_AccessFlag_Inherited) @@ -470,30 +469,6 @@ os_id_from_file(OS_Handle file) return result; } -internal B32 -os_rename_file_by_handle(OS_Handle file, String8 new_name) -{ - Temp scratch = scratch_begin(0,0); - - HANDLE handle = (HANDLE)file.u64[0]; - - String16 new_name16 = str16_from_8(scratch.arena, new_name); - - U64 file_rename_info_size = sizeof(FILE_RENAME_INFO); - U64 buffer_size = file_rename_info_size + sizeof(WCHAR)*new_name16.size; - U8 *buffer = push_array(scratch.arena, U8, buffer_size); - - FILE_RENAME_INFO *rename_info = (FILE_RENAME_INFO *)buffer; - rename_info->ReplaceIfExists = 1; - rename_info->FileNameLength = new_name16.size * sizeof(new_name16.str[0]); - MemoryCopy(rename_info->FileName, new_name16.str, new_name16.size * sizeof(new_name16.str[0])); - - BOOL is_renamed = SetFileInformationByHandle(handle, FileRenameInfo, buffer, buffer_size); - - scratch_end(scratch); - return is_renamed; -} - internal B32 os_file_reserve_size(OS_Handle file, U64 size) { From a06f57616121023cdd7b696057d8533c8015122d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 25 Feb 2025 14:39:48 -0800 Subject: [PATCH 189/755] detect and error out on PDB linked with /DEBUG:FASTLINK --- src/pdb/pdb_parse.c | 64 ++++++++++++------- src/pdb/pdb_parse.h | 1 + .../rdi_breakpad_from_pdb_main.c | 4 +- src/rdi_from_pdb/rdi_from_pdb.c | 5 ++ 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/pdb/pdb_parse.c b/src/pdb/pdb_parse.c index 5ae4bff3..8d75a0d2 100644 --- a/src/pdb/pdb_parse.c +++ b/src/pdb/pdb_parse.c @@ -74,34 +74,50 @@ pdb_info_from_data(Arena *arena, String8 data){ // table layout: epilogue U32 epilogue_base_off = deleted_words_array_off + num_deleted_words*sizeof(U32); - // read table - if (hash_table_count > 0 && epilogue_base_off <= data.size){ - PDB_InfoNode *first = 0; - PDB_InfoNode *last = 0; - - U32 record_off = epilogue_base_off; - for (U32 i = 0; i < hash_table_count; i += 1, record_off += 8){ - U32 *record = (U32*)(data.str + record_off); - U32 relative_name_off = record[0]; - MSF_StreamNumber sn = (MSF_StreamNumber)record[1]; + if (epilogue_base_off <= data.size){ + U64 record_off = epilogue_base_off; + + // read table + if (hash_table_count > 0) { + PDB_InfoNode *first = 0; + PDB_InfoNode *last = 0; - U32 name_off = names_base_off + relative_name_off; - String8 name = str8_cstring_capped((char*)(data.str + name_off), - (char*)(data.str + names_base_opl)); + for (U32 i = 0; i < hash_table_count; i += 1, record_off += 8){ + U32 *record = (U32*)(data.str + record_off); + U32 relative_name_off = record[0]; + MSF_StreamNumber sn = (MSF_StreamNumber)record[1]; + + U32 name_off = names_base_off + relative_name_off; + String8 name = str8_cstring_capped((char*)(data.str + name_off), + (char*)(data.str + names_base_opl)); + + // push info node + PDB_InfoNode *node = push_array(arena, PDB_InfoNode, 1); + SLLQueuePush(first, last, node); + node->string = name; + node->sn = sn; + } - // push info node - PDB_InfoNode *node = push_array(arena, PDB_InfoNode, 1); - SLLQueuePush(first, last, node); - node->string = name; - node->sn = sn; + result = push_array(arena, PDB_Info, 1); + result->first = first; + result->last = last; + result->auth_guid = *auth_guid; } - - result = push_array(arena, PDB_Info, 1); - result->first = first; - result->last = last; - result->auth_guid = *auth_guid; + + // read PDB features + PDB_FeatureFlags features = 0; + for (; record_off + sizeof(PDB_FeatureSig) <= data.size; ) { + PDB_FeatureSig sig = 0; + record_off += str8_deserial_read_struct(data, record_off, &sig); + switch (sig) { + case PDB_FeatureSig_NULL: break; + case PDB_FeatureSig_VC140: features |= PDB_FeatureFlag_HAS_ID_STREAM; break; + case PDB_FeatureSig_NO_TYPE_MERGE: features |= PDB_FeatureFlag_NO_TYPE_MERGE; break; + case PDB_FeatureSig_MINIMAL_DEBUG_INFO: features |= PDB_FeatureFlag_MINIMAL_DBG_INFO; break; + } + } + result->features = features; } - } } diff --git a/src/pdb/pdb_parse.h b/src/pdb/pdb_parse.h index eb9f56e7..ec827408 100644 --- a/src/pdb/pdb_parse.h +++ b/src/pdb/pdb_parse.h @@ -45,6 +45,7 @@ typedef struct PDB_Info PDB_InfoNode *first; PDB_InfoNode *last; Guid auth_guid; + PDB_FeatureFlags features; } PDB_Info; typedef struct PDB_InfoHeader diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index f3c72e7e..4d16f78b 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -27,7 +27,6 @@ #include "coff/coff_parse.h" #include "codeview/codeview.h" #include "codeview/codeview_parse.h" -#include "codeview/codeview_enum.h" #include "msf/msf.h" #include "msf/msf_parse.h" #include "pdb/pdb.h" @@ -44,7 +43,6 @@ #include "coff/coff_parse.c" #include "codeview/codeview.c" #include "codeview/codeview_parse.c" -#include "codeview/codeview_enum.c" #include "msf/msf.c" #include "msf/msf_parse.c" #include "pdb/pdb.c" @@ -225,7 +223,7 @@ entry_point(CmdLine *cmdline) { convert2bake = p2r_convert(arena, user2convert); } - + //- rjf: dump breakpad text String8List dump = {0}; ProfScope("dump breakpad text") diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 943dcca1..a56b5e6f 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -2957,6 +2957,11 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) named_streams = pdb_named_stream_table_from_info(arena, info); MemoryCopyStruct(&auth_guid, &info->auth_guid); scratch_end(scratch); + + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { + fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); + os_abort(1); + } } ////////////////////////////////////////////////////////////// From d5811b7748e54298d057aa6f7026d4d526918431 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:04:07 -0800 Subject: [PATCH 190/755] binary search for U64 and Rng1U64 arrays --- src/base/base_core.c | 34 ++++++++++++++++++++++++++++++++++ src/base/base_core.h | 4 ++++ src/base/base_math.c | 32 ++++++++++++++++++++++++++++++++ src/base/base_math.h | 1 + 4 files changed, 71 insertions(+) diff --git a/src/base/base_core.c b/src/base/base_core.c index b392e4a0..e5faadde 100644 --- a/src/base/base_core.c +++ b/src/base/base_core.c @@ -602,3 +602,37 @@ ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_data, U64 read_s } return read_size; } + +//////////////////////////////// + +internal U64 +u64_array_bsearch(U64 *arr, U64 count, U64 value) +{ + if(count > 1 && arr[0] <= value && value < arr[count-1]) + { + U64 l = 0; + U64 r = count - 1; + for(; l <= r; ) + { + U64 m = l + (r - l) / 2; + if(arr[m] == value) + { + return m; + } + else if(arr[m] < value) + { + l = m + 1; + } + else + { + r = m - 1; + } + } + } + else if (count == 1 && arr[0] == value) + { + return 0; + } + return max_U64; +} + diff --git a/src/base/base_core.h b/src/base/base_core.h index 191e1e7f..9e2d686a 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -885,4 +885,8 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat #define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function)) +//////////////////////////////// + +internal U64 u64_array_bsearch(U64 *arr, U64 count, U64 value); + #endif // BASE_CORE_H diff --git a/src/base/base_math.c b/src/base/base_math.c index 2c6201f3..b0a85bfe 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -634,6 +634,37 @@ rng1u64_array_from_list(Arena *arena, Rng1U64List *list) return arr; } +internal U64 +rng_1u64_array_bsearch(Rng1U64Array arr, U64 value) +{ + if(arr.count > 0 && arr.v[0].min <= value && value < arr.v[arr.count-1].max) + { + U64 l = 0; + U64 r = arr.count - 1; + for(; l <= r; ) + { + U64 m = l + (r - l) / 2; + if(contains_1u64(arr.v[m], value)) + { + return m; + } + else if(arr.v[m].min < value) + { + l = m + 1; + } + else + { + r = m - 1; + } + } + } + else if(arr.count == 1 && contains_1u64(arr.v[0], value)) + { + return 0; + } + return max_U64; +} + internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng) { @@ -657,3 +688,4 @@ rng1s64_array_from_list(Arena *arena, Rng1S64List *list) } return arr; } + diff --git a/src/base/base_math.h b/src/base/base_math.h index b6063ad5..d13adbf4 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -668,6 +668,7 @@ internal U32 u32_from_rgba(Vec4F32 rgba); internal void rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng); internal void rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat); internal Rng1U64Array rng1u64_array_from_list(Arena *arena, Rng1U64List *list); +internal U64 rng_1u64_array_bsearch(Rng1U64Array arr, U64 value); internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng); internal Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list); From 53bff614e6354ad94c5e6565e667391e9fb6c7de Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:04:41 -0800 Subject: [PATCH 191/755] moved LEB helpers to DWARF layer --- src/base/base_strings.c | 73 ----------------------------------------- src/base/base_strings.h | 2 -- 2 files changed, 75 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 9e42e0cd..dcdc2a4d 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -2371,76 +2371,3 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out) return block_out->size; } -internal U64 -str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) -{ - U64 value = 0; - U64 shift = 0; - U64 cursor = off; - for(;;) - { - U8 byte = 0; - U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); - - if(bytes_read != sizeof(byte)) - { - break; - } - - U8 val = byte & 0x7fu; - value |= ((U64)val) << shift; - - cursor += bytes_read; - shift += 7u; - - if((byte & 0x80u) == 0) - { - break; - } - } - if(value_out != 0) - { - *value_out = value; - } - U64 bytes_read = cursor - off; - return bytes_read; -} - -internal U64 -str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) -{ - U64 value = 0; - U64 shift = 0; - U64 cursor = off; - for(;;) - { - U8 byte; - U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); - if(bytes_read != sizeof(byte)) - { - break; - } - - U8 val = byte & 0x7fu; - value |= ((U64)val) << shift; - - cursor += bytes_read; - shift += 7u; - - if((byte & 0x80u) == 0) - { - if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) - { - value |= -(S64)(1ull << shift); - } - break; - } - } - if(value_out != 0) - { - *value_out = value; - } - U64 bytes_read = cursor - off; - return bytes_read; -} - diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 67e90349..0d456cac 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -407,8 +407,6 @@ internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size); internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16 *str_out); internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out); -internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); -internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) #define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1) From 8b4f97223e2a447a54229bcfe19a8ee24615d3a8 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:09:01 -0800 Subject: [PATCH 192/755] moved async bakers from PDB converter to a stand-alone file to reuse them in DWARF converter --- src/lib_rdi_make/rdi_make.c | 22 + src/lib_rdi_make/rdi_make.h | 15 + src/raddbg/raddbg_main.c | 2 + src/rdi_from_pdb/rdi_from_pdb.c | 877 +------------------------- src/rdi_from_pdb/rdi_from_pdb.h | 308 --------- src/rdi_from_pdb/rdi_from_pdb_main.c | 2 + src/rdi_make/rdi_make_help.c | 901 +++++++++++++++++++++++++++ src/rdi_make/rdi_make_help.h | 330 ++++++++++ 8 files changed, 1280 insertions(+), 1177 deletions(-) create mode 100644 src/rdi_make/rdi_make_help.c create mode 100644 src/rdi_make/rdi_make_help.h diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 3f37b9f5..272e2dd9 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -652,6 +652,28 @@ rdim_unit_chunk_list_concat_in_place(RDIM_UnitChunkList *dst, RDIM_UnitChunkList //////////////////////////////// //~ rjf: [Building] Type Info Building +RDI_PROC RDIM_Type ** +rdim_array_from_type_list(RDIM_Arena *arena, RDIM_TypeList list) +{ + RDIM_Type **arr = push_array(arena, RDIM_Type *, list.count); + U64 i = 0; + for(RDIM_TypeNode *n = list.first; n != 0; n = n->next, ++i) + { + arr[i] = n->v; + } + return arr; +} + +RDI_PROC RDIM_TypeNode * +rdim_type_list_push(RDIM_Arena *arena, RDIM_TypeList *list, RDIM_Type *v) +{ + RDIM_TypeNode *n = push_array(arena, RDIM_TypeNode, 1); + n->v = v; + SLLQueuePush(list->first, list->last, n); + list->count += 1; + return n; +} + RDI_PROC RDIM_Type * rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap) { diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 47ff5ade..176dbbac 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -610,6 +610,21 @@ struct RDIM_Type struct RDIM_UDT *udt; }; +typedef struct RDIM_TypeNode RDIM_TypeNode; +struct RDIM_TypeNode +{ + struct RDIM_TypeNode *next; + RDIM_Type *v; +}; + +typedef struct RDIM_TypeList RDIM_TypeList; +struct RDIM_TypeList +{ + U64 count; + RDIM_TypeNode *first; + RDIM_TypeNode *last; +}; + typedef struct RDIM_TypeChunkNode RDIM_TypeChunkNode; struct RDIM_TypeChunkNode { diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index e47ebe6e..54ca6ba9 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -333,6 +333,7 @@ #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" #include "file_stream/file_stream.h" @@ -375,6 +376,7 @@ #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" #include "file_stream/file_stream.c" diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index a56b5e6f..a2f067b6 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -3977,387 +3977,6 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) return out; } -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: bake string map building - -#define p2r_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) - -ASYNC_WORK_DEF(p2r_bake_src_files_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeSrcFilesStringsIn *in = (P2R_BakeSrcFilesStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_units_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeUnitsStringsIn *in = (P2R_BakeUnitsStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_types_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeTypesStringsIn *in = (P2R_BakeTypesStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake type strings") - { - for(P2R_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_udts_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeUDTsStringsIn *in = (P2R_BakeUDTsStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake udt strings") - { - for(P2R_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_symbols_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeSymbolsStringsIn *in = (P2R_BakeSymbolsStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake symbol strings") - { - for(P2R_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_inline_site_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeInlineSiteStringsIn *in = input; - p2r_make_string_map_if_needed(); - ProfScope("bake inline site strings") - { - for(P2R_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_scopes_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeScopesStringsIn *in = (P2R_BakeScopesStringsIn *)input; - p2r_make_string_map_if_needed(); - ProfScope("bake scope strings") - { - for(P2R_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_bake_line_tables_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeLineTablesIn *in = (P2R_BakeLineTablesIn *)input; - RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); - ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); - ProfEnd(); - return out; -} - -#undef p2r_make_string_map_if_needed - -//- rjf: bake string map joining - -ASYNC_WORK_DEF(p2r_bake_string_map_join_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_JoinBakeStringMapSlotsIn *in = (P2R_JoinBakeStringMapSlotsIn *)input; - ProfScope("join bake string maps") - { - for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) - { - for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) - { - B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); - B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); - if(src_slots_good && dst_slot_is_zero) - { - in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; - } - else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) - { - rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: bake string map sorting - -ASYNC_WORK_DEF(p2r_bake_string_map_sort_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_SortBakeStringMapSlotsIn *in = (P2R_SortBakeStringMapSlotsIn *)input; - ProfScope("sort bake string chunk list map range") - { - for(U64 slot_idx = in->slot_idx; - slot_idx < in->slot_idx+in->slot_count; - slot_idx += 1) - { - if(in->src_map->slots[slot_idx] != 0) - { - if(in->src_map->slots[slot_idx]->total_count > 1) - { - in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); - *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); - } - else - { - in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: pass 1: interner/deduper map builds - -ASYNC_WORK_DEF(p2r_build_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BuildBakeNameMapIn *in = (P2R_BuildBakeNameMapIn *)input; - RDIM_BakeNameMap *name_map = 0; - ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->params); - ProfEnd(); - return name_map; -} - -//- rjf: pass 2: string-map-dependent debug info stream builds - -ASYNC_WORK_DEF(p2r_bake_units_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeUnitsIn *in = (P2R_BakeUnitsIn *)input; - RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); - ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_unit_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeUnitVMapIn *in = (P2R_BakeUnitVMapIn *)input; - RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); - ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_src_files_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeSrcFilesIn *in = (P2R_BakeSrcFilesIn *)input; - RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); - ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_udts_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeUDTsIn *in = (P2R_BakeUDTsIn *)input; - RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); - ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->udts); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_global_variables_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeGlobalVariablesIn *in = (P2R_BakeGlobalVariablesIn *)input; - RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); - ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_global_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeGlobalVMapIn *in = (P2R_BakeGlobalVMapIn *)input; - RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); - ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_thread_variables_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeThreadVariablesIn *in = (P2R_BakeThreadVariablesIn *)input; - RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); - ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->thread_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_procedures_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeProceduresIn *in = (P2R_BakeProceduresIn *)input; - RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); - ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->procedures); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_scopes_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeScopesIn *in = (P2R_BakeScopesIn *)input; - RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); - ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_scope_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeScopeVMapIn *in = (P2R_BakeScopeVMapIn *)input; - RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); - ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_inline_sites_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeInlineSitesIn *in = (P2R_BakeInlineSitesIn *)input; - RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); - ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_file_paths_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeFilePathsIn *in = (P2R_BakeFilePathsIn *)input; - RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); - ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_strings_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeStringsIn *in = (P2R_BakeStringsIn *)input; - RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); - ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); - ProfEnd(); - return out; -} - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds - -ASYNC_WORK_DEF(p2r_bake_type_nodes_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeTypeNodesIn *in = (P2R_BakeTypeNodesIn *)input; - RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); - ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->types); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeNameMapIn *in = (P2R_BakeNameMapIn *)input; - RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); - ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_bake_idx_runs_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_BakeIdxRunsIn *in = (P2R_BakeIdxRunsIn *)input; - RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); - ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); - ProfEnd(); - return out; -} - //////////////////////////////// //~ rjf: Top-Level Initialization @@ -4381,468 +4000,14 @@ p2r_init(void) internal P2R_Bake2Serialize * p2r_bake(Arena *arena, P2R_Convert2Bake *in) { - Temp scratch = scratch_begin(&arena, 1); - RDIM_BakeParams *in_params = &in->bake_params; - P2R_Bake2Serialize *out = push_array(arena, P2R_Bake2Serialize, 1); - RDIM_BakeResults *out_results = &out->bake_results; - - ////////////////////////////// - //- rjf: kick off line tables baking - // - ASYNC_Task *bake_line_tables_task = 0; - { - P2R_BakeLineTablesIn *in = push_array(scratch.arena, P2R_BakeLineTablesIn, 1); - in->line_tables = &in_params->line_tables; - bake_line_tables_task = async_task_launch(scratch.arena, p2r_bake_line_tables_work, .input = in); - } - - ////////////////////////////// - //- rjf: build interned path tree - // - RDIM_BakePathTree *path_tree = 0; - ProfScope("build interned path tree") - { - path_tree = rdim_bake_path_tree_from_params(arena, in_params); - } - - ////////////////////////////// - //- rjf: kick off string map building tasks - // - RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + - in_params->procedures.total_count*1 + - in_params->global_variables.total_count*1 + - in_params->thread_variables.total_count*1 + - in_params->types.total_count/2)}; - RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); - ASYNC_TaskList bake_string_map_build_tasks = {0}; - { - // rjf: src files - ProfScope("kick off src files string map build task") - { - P2R_BakeSrcFilesStringsIn *in = push_array(scratch.arena, P2R_BakeSrcFilesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->src_files; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_src_files_strings_work, .input = in)); - } - - // rjf: units - ProfScope("kick off units string map build task") - { - P2R_BakeUnitsStringsIn *in = push_array(scratch.arena, P2R_BakeUnitsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->units; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_units_strings_work, .input = in)); - } - - // rjf: types - ProfScope("kick off types string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; - RDIM_TypeChunkNode *chunk = in_params->types.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_BakeTypesStringsIn *in = push_array(scratch.arena, P2R_BakeTypesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - P2R_BakeTypesStringsInNode *n = push_array(scratch.arena, P2R_BakeTypesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_types_strings_work, .input = in)); - } - } - - // rjf: UDTs - ProfScope("kick off udts string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; - RDIM_UDTChunkNode *chunk = in_params->udts.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_BakeUDTsStringsIn *in = push_array(scratch.arena, P2R_BakeUDTsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - P2R_BakeUDTsStringsInNode *n = push_array(scratch.arena, P2R_BakeUDTsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_udts_strings_work, .input = in)); - } - } - - // rjf: symbols - ProfScope("kick off symbols string map build tasks") - { - RDIM_SymbolChunkList *symbol_lists[] = - { - &in_params->global_variables, - &in_params->thread_variables, - &in_params->procedures, - }; - for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) - { - U64 items_per_task = 4096; - U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; - RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_BakeSymbolsStringsIn *in = push_array(scratch.arena, P2R_BakeSymbolsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - P2R_BakeSymbolsStringsInNode *n = push_array(scratch.arena, P2R_BakeSymbolsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_symbols_strings_work, .input = in)); - } - } - } + RDIM_HelpState help_state = {0}; + help_state.arena = p2r_state->arena; + help_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; + help_state.work_thread_arenas = p2r_state->work_thread_arenas; - ProfScope("kick off inline site string map build task") - { - U64 items_per_task = 4096; - U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); - RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_BakeInlineSiteStringsIn *in = push_array(scratch.arena, P2R_BakeInlineSiteStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - P2R_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, P2R_BakeInlineSiteStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_inline_site_strings_work, .input = in)); - } - } - - // rjf: scope chunks - ProfScope("kick off scope chunks string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; - RDIM_ScopeChunkNode *chunk = in_params->scopes.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_BakeScopesStringsIn *in = push_array(scratch.arena, P2R_BakeScopesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - P2R_BakeScopesStringsInNode *n = push_array(scratch.arena, P2R_BakeScopesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, p2r_bake_scopes_strings_work, .input = in)); - } - } - } - - ////////////////////////////// - //- rjf: kick off name map building tasks - // - P2R_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; - ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - build_bake_name_map_in[k].k = k; - build_bake_name_map_in[k].params = in_params; - build_bake_name_map_task[k] = async_task_launch(scratch.arena, p2r_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); - } - - ////////////////////////////// - //- rjf: join string map building tasks - // - ProfScope("join string map building tasks") - { - for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - - ////////////////////////////// - //- rjf: produce joined string map - // - RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(arena, &bake_string_map_topology); - ProfScope("produce joined string map") - { - U64 slots_per_task = 16384; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); - - // rjf: kickoff tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, P2R_JoinBakeStringMapSlotsIn, 1); - in->top = &bake_string_map_topology; - in->src_maps = bake_string_maps__in_progress; - in->src_maps_count = async_thread_count(); - in->dst_map = unsorted_bake_string_map; - in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); - in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); - tasks[task_idx] = async_task_launch(scratch.arena, p2r_bake_string_map_join_work, .input = in); - } - - // rjf: join tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - async_task_join(tasks[task_idx]); - } - - // rjf: insert small top-level stuff - rdim_bake_string_map_loose_push_top_level_info(arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(arena, &bake_string_map_topology, unsorted_bake_string_map, path_tree); - } - - ////////////////////////////// - //- rjf: kick off string map sorting tasks - // - ASYNC_TaskList sort_bake_string_map_tasks = {0}; - RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(arena, &bake_string_map_topology); - { - U64 slots_per_task = 4096; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - P2R_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, P2R_SortBakeStringMapSlotsIn, 1); - { - in->top = &bake_string_map_topology; - in->src_map = unsorted_bake_string_map; - in->dst_map = sorted_bake_string_map__in_progress; - in->slot_idx = task_idx*slots_per_task; - in->slot_count = slots_per_task; - if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) - { - in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; - } - } - async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, p2r_bake_string_map_sort_work, .input = in)); - } - } - - ////////////////////////////// - //- rjf: join string map sorting tasks - // - ProfScope("join string map sorting tasks") - { - for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; - - ////////////////////////////// - //- rjf: build finalized string map - // - ProfBegin("build finalized string map base indices"); - RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(arena, &bake_string_map_topology, sorted_bake_string_map); - ProfEnd(); - ProfBegin("build finalized string map"); - RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(arena, &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); - ProfEnd(); - - ////////////////////////////// - //- rjf: kick off pass 2 tasks - // - P2R_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; - ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, p2r_bake_units_work, .input = &bake_units_top_level_in); - P2R_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; - ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, p2r_bake_unit_vmap_work, .input = &bake_unit_vmap_in); - P2R_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; - ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, p2r_bake_src_files_work, .input = &bake_src_files_in); - P2R_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts}; - ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, p2r_bake_udts_work, .input = &bake_udts_in); - P2R_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; - ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, p2r_bake_global_variables_work, .input = &bake_global_variables_in); - P2R_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; - ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, p2r_bake_global_vmap_work, .input = &bake_global_vmap_in); - P2R_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; - ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, p2r_bake_thread_variables_work, .input = &bake_thread_variables_in); - P2R_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures}; - ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, p2r_bake_procedures_work, .input = &bake_procedures_in); - P2R_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes}; - ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, p2r_bake_scopes_work, .input = &bake_scopes_in); - P2R_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; - ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, p2r_bake_scope_vmap_work, .input = &bake_scope_vmap_in); - P2R_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites}; - ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, p2r_bake_inline_sites_work, .input = &bake_inline_sites_in); - P2R_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; - ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, p2r_bake_file_paths_work, .input = &bake_file_paths_in); - P2R_BakeStringsIn bake_strings_in = {&bake_strings}; - ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, p2r_bake_strings_work, .input = &bake_strings_in); - - ////////////////////////////// - //- rjf: join name map building tasks - // - RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; - ProfScope("join name map building tasks") - { - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); - } - } - - ////////////////////////////// - //- rjf: build interned idx run map - // - RDIM_BakeIdxRunMap *idx_runs = 0; - ProfScope("build interned idx run map") - { - idx_runs = rdim_bake_idx_run_map_from_params(arena, name_maps, in_params); - } - - ////////////////////////////// - //- rjf: do small top-level bakes - // - ProfScope("top level info") out_results->top_level_info = rdim_bake_top_level_info(arena, &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out_results->binary_sections = rdim_bake_binary_sections(arena, &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out_results->top_level_name_maps = rdim_bake_name_maps_top_level(arena, &bake_strings, idx_runs, name_maps); - - ////////////////////////////// - //- rjf: kick off pass 3 tasks - // - P2R_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types}; - ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, p2r_bake_type_nodes_work, .input = &bake_type_nodes_in); - ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - if(name_maps[k] == 0 || name_maps[k]->name_count == 0) - { - continue; - } - P2R_BakeNameMapIn *in = push_array(scratch.arena, P2R_BakeNameMapIn, 1); - in->strings = &bake_strings; - in->idx_runs = idx_runs; - in->map = name_maps[k]; - in->kind = k; - bake_name_maps_tasks[k] = async_task_launch(scratch.arena, p2r_bake_name_map_work, .input = in); - } - } - P2R_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; - ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, p2r_bake_idx_runs_work, .input = &bake_idx_runs_in); - - ////////////////////////////// - //- rjf: join remaining completed bakes - // - ProfScope("top-level units info") out_results->units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); - ProfScope("unit vmap") out_results->unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); - ProfScope("source files") out_results->src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); - ProfScope("UDTs") out_results->udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); - ProfScope("global variables") out_results->global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - ProfScope("global vmap") out_results->global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); - ProfScope("thread variables") out_results->thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - ProfScope("procedures") out_results->procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - ProfScope("scopes") out_results->scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - ProfScope("scope vmap") out_results->scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); - ProfScope("inline sites") out_results->inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); - ProfScope("file paths") out_results->file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); - ProfScope("strings") out_results->strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); - ProfScope("type nodes") out_results->type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); - ProfScope("idx runs") out_results->idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); - ProfScope("line tables") out_results->line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); - - ////////////////////////////// - //- rjf: join individual name map bakes - // - RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; - ProfScope("name maps") - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); - if(bake != 0) - { - name_map_bakes[k] = *bake; - } - } - } - - ////////////////////////////// - //- rjf: join all individual name map bakes - // - ProfScope("join all name map bakes into final name map bake") - { - out_results->name_maps = rdim_name_map_bake_results_combine(arena, name_map_bakes, ArrayCount(name_map_bakes)); - } - - scratch_end(scratch); - return out; + P2R_Bake2Serialize *result = push_array(arena, P2R_Bake2Serialize, 1); + result->bake_results = rdim_bake(&help_state, &in->bake_params); + return result; } //////////////////////////////// @@ -4852,33 +4017,7 @@ internal P2R_Serialize2File * p2r_compress(Arena *arena, P2R_Serialize2File *in) { P2R_Serialize2File *out = push_array(arena, P2R_Serialize2File, 1); - { - //- rjf: set up compression context - rr_lzb_simple_context ctx = {0}; - ctx.m_tableSizeBits = 14; - ctx.m_hashTable = push_array(arena, U16, 1<bundle.sections[k]; - RDIM_SerializedSection *dst = &out->bundle.sections[k]; - MemoryCopyStruct(dst, src); - - // rjf: determine if this section should be compressed - B32 should_compress = 1; - - // rjf: compress if needed - if(should_compress) - { - MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); - dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); - dst->unpacked_size = src->encoded_size; - dst->encoding = RDI_SectionEncoding_LZB; - } - } - } + out->bundle = rdim_compress(arena, &in->bundle); return out; } diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index ced21a66..03cae2d2 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -273,274 +273,6 @@ struct P2R_SymbolStreamConvertOut RDIM_InlineSiteChunkList inline_sites; }; -//////////////////////////////// -//~ rjf: Baking Task Types - -//- rjf: line table baking task types - -typedef struct P2R_BakeLineTablesIn P2R_BakeLineTablesIn; -struct P2R_BakeLineTablesIn -{ - RDIM_LineTableChunkList *line_tables; -}; - -//- rjf: string map baking task types - -typedef struct P2R_BakeSrcFilesStringsIn P2R_BakeSrcFilesStringsIn; -struct P2R_BakeSrcFilesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_SrcFileChunkList *list; -}; - -typedef struct P2R_BakeUnitsStringsIn P2R_BakeUnitsStringsIn; -struct P2R_BakeUnitsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_UnitChunkList *list; -}; - -typedef struct P2R_BakeTypesStringsInNode P2R_BakeTypesStringsInNode; -struct P2R_BakeTypesStringsInNode -{ - P2R_BakeTypesStringsInNode *next; - RDIM_Type *v; - RDI_U64 count; -}; - -typedef struct P2R_BakeTypesStringsIn P2R_BakeTypesStringsIn; -struct P2R_BakeTypesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - P2R_BakeTypesStringsInNode *first; - P2R_BakeTypesStringsInNode *last; -}; - -typedef struct P2R_BakeUDTsStringsInNode P2R_BakeUDTsStringsInNode; -struct P2R_BakeUDTsStringsInNode -{ - P2R_BakeUDTsStringsInNode *next; - RDIM_UDT *v; - RDI_U64 count; -}; - -typedef struct P2R_BakeUDTsStringsIn P2R_BakeUDTsStringsIn; -struct P2R_BakeUDTsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - P2R_BakeUDTsStringsInNode *first; - P2R_BakeUDTsStringsInNode *last; -}; - -typedef struct P2R_BakeSymbolsStringsInNode P2R_BakeSymbolsStringsInNode; -struct P2R_BakeSymbolsStringsInNode -{ - P2R_BakeSymbolsStringsInNode *next; - RDIM_Symbol *v; - RDI_U64 count; -}; - -typedef struct P2R_BakeSymbolsStringsIn P2R_BakeSymbolsStringsIn; -struct P2R_BakeSymbolsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - P2R_BakeSymbolsStringsInNode *first; - P2R_BakeSymbolsStringsInNode *last; -}; - -typedef struct P2R_BakeInlineSiteStringsInNode P2R_BakeInlineSiteStringsInNode; -struct P2R_BakeInlineSiteStringsInNode -{ - P2R_BakeInlineSiteStringsInNode *next; - RDIM_InlineSite *v; - RDI_U64 count; -}; - -typedef struct P2R_BakeInlineSiteStringsIn P2R_BakeInlineSiteStringsIn; -struct P2R_BakeInlineSiteStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - P2R_BakeInlineSiteStringsInNode *first; - P2R_BakeInlineSiteStringsInNode *last; -}; - -typedef struct P2R_BakeScopesStringsInNode P2R_BakeScopesStringsInNode; -struct P2R_BakeScopesStringsInNode -{ - P2R_BakeScopesStringsInNode *next; - RDIM_Scope *v; - RDI_U64 count; -}; - -typedef struct P2R_BakeScopesStringsIn P2R_BakeScopesStringsIn; -struct P2R_BakeScopesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - P2R_BakeScopesStringsInNode *first; - P2R_BakeScopesStringsInNode *last; -}; - -//- rjf: string map joining task types - -typedef struct P2R_JoinBakeStringMapSlotsIn P2R_JoinBakeStringMapSlotsIn; -struct P2R_JoinBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **src_maps; - U64 src_maps_count; - RDIM_BakeStringMapLoose *dst_map; - Rng1U64 slot_idx_range; -}; - -//- rjf: string map sorting task types - -typedef struct P2R_SortBakeStringMapSlotsIn P2R_SortBakeStringMapSlotsIn; -struct P2R_SortBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose *src_map; - RDIM_BakeStringMapLoose *dst_map; - U64 slot_idx; - U64 slot_count; -}; - -//- rjf: OLD string map baking types - -typedef struct P2R_BuildBakeStringMapIn P2R_BuildBakeStringMapIn; -struct P2R_BuildBakeStringMapIn -{ - RDIM_BakePathTree *path_tree; - RDIM_BakeParams *params; -}; - -typedef struct P2R_BuildBakeNameMapIn P2R_BuildBakeNameMapIn; -struct P2R_BuildBakeNameMapIn -{ - RDI_NameMapKind k; - RDIM_BakeParams *params; -}; - -//- rjf: debug info baking task types - -typedef struct P2R_BakeUnitsIn P2R_BakeUnitsIn; -struct P2R_BakeUnitsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_UnitChunkList *units; -}; - -typedef struct P2R_BakeUnitVMapIn P2R_BakeUnitVMapIn; -struct P2R_BakeUnitVMapIn -{ - RDIM_UnitChunkList *units; -}; - -typedef struct P2R_BakeSrcFilesIn P2R_BakeSrcFilesIn; -struct P2R_BakeSrcFilesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_SrcFileChunkList *src_files; -}; - -typedef struct P2R_BakeUDTsIn P2R_BakeUDTsIn; -struct P2R_BakeUDTsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_UDTChunkList *udts; -}; - -typedef struct P2R_BakeGlobalVariablesIn P2R_BakeGlobalVariablesIn; -struct P2R_BakeGlobalVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *global_variables; -}; - -typedef struct P2R_BakeGlobalVMapIn P2R_BakeGlobalVMapIn; -struct P2R_BakeGlobalVMapIn -{ - RDIM_SymbolChunkList *global_variables; -}; - -typedef struct P2R_BakeThreadVariablesIn P2R_BakeThreadVariablesIn; -struct P2R_BakeThreadVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *thread_variables; -}; - -typedef struct P2R_BakeProceduresIn P2R_BakeProceduresIn; -struct P2R_BakeProceduresIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *procedures; -}; - -typedef struct P2R_BakeScopesIn P2R_BakeScopesIn; -struct P2R_BakeScopesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_ScopeChunkList *scopes; -}; - -typedef struct P2R_BakeScopeVMapIn P2R_BakeScopeVMapIn; -struct P2R_BakeScopeVMapIn -{ - RDIM_ScopeChunkList *scopes; -}; - -typedef struct P2R_BakeInlineSitesIn P2R_BakeInlineSitesIn; -struct P2R_BakeInlineSitesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_InlineSiteChunkList *inline_sites; -}; - -typedef struct P2R_BakeFilePathsIn P2R_BakeFilePathsIn; -struct P2R_BakeFilePathsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; -}; - -typedef struct P2R_BakeStringsIn P2R_BakeStringsIn; -struct P2R_BakeStringsIn -{ - RDIM_BakeStringMapTight *strings; -}; - -typedef struct P2R_BakeTypeNodesIn P2R_BakeTypeNodesIn; -struct P2R_BakeTypeNodesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_TypeChunkList *types; -}; - -typedef struct P2R_BakeNameMapIn P2R_BakeNameMapIn; -struct P2R_BakeNameMapIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_BakeNameMap *map; - RDI_NameMapKind kind; -}; - -typedef struct P2R_BakeIdxRunsIn P2R_BakeIdxRunsIn; -struct P2R_BakeIdxRunsIn -{ - RDIM_BakeIdxRunMap *idx_runs; -}; - //////////////////////////////// //~ rjf: Top-Level State @@ -630,46 +362,6 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work); internal P2R_Convert2Bake *p2r_convert(Arena *arena, P2R_User2Convert *in); -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: unsorted bake string map building -ASYNC_WORK_DEF(p2r_bake_src_files_strings_work); -ASYNC_WORK_DEF(p2r_bake_units_strings_work); -ASYNC_WORK_DEF(p2r_bake_types_strings_work); -ASYNC_WORK_DEF(p2r_bake_udts_strings_work); -ASYNC_WORK_DEF(p2r_bake_symbols_strings_work); -ASYNC_WORK_DEF(p2r_bake_scopes_strings_work); -ASYNC_WORK_DEF(p2r_bake_line_tables_work); - -//- rjf: bake string map joining -ASYNC_WORK_DEF(p2r_bake_string_map_join_work); - -//- rjf: bake string map sorting -ASYNC_WORK_DEF(p2r_bake_string_map_sort_work); - -//- rjf: pass 1: interner/deduper map builds -ASYNC_WORK_DEF(p2r_build_bake_name_map_work); - -//- rjf: pass 2: string-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_units_work); -ASYNC_WORK_DEF(p2r_bake_unit_vmap_work); -ASYNC_WORK_DEF(p2r_bake_src_files_work); -ASYNC_WORK_DEF(p2r_bake_udts_work); -ASYNC_WORK_DEF(p2r_bake_global_variables_work); -ASYNC_WORK_DEF(p2r_bake_global_vmap_work); -ASYNC_WORK_DEF(p2r_bake_thread_variables_work); -ASYNC_WORK_DEF(p2r_bake_procedures_work); -ASYNC_WORK_DEF(p2r_bake_scopes_work); -ASYNC_WORK_DEF(p2r_bake_scope_vmap_work); -ASYNC_WORK_DEF(p2r_bake_file_paths_work); -ASYNC_WORK_DEF(p2r_bake_strings_work); - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_type_nodes_work); -ASYNC_WORK_DEF(p2r_bake_name_map_work); -ASYNC_WORK_DEF(p2r_bake_idx_runs_work); - //////////////////////////////// //~ rjf: Top-Level Initialization diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index 9b2e49b5..8b24e350 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -21,6 +21,7 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" #include "coff/coff.h" #include "coff/coff_parse.h" #include "codeview/codeview.h" @@ -37,6 +38,7 @@ #include "os/os_inc.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" #include "coff/coff.c" #include "coff/coff_parse.c" #include "codeview/codeview.c" diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c new file mode 100644 index 00000000..488030c0 --- /dev/null +++ b/src/rdi_make/rdi_make_help.c @@ -0,0 +1,901 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: bake string map building + +#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) + +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_units_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_types_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake type strings") + { + for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_udts_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake udt strings") + { + for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake symbol strings") + { + for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSiteStringsIn *in = input; + rdim_make_string_map_if_needed(); + ProfScope("bake inline site strings") + { + for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake scope strings") + { + for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_line_tables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; + RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); + ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); + return out; +} + +#undef rdim_make_string_map_if_needed + +//- rjf: bake string map joining + +ASYNC_WORK_DEF(rdim_bake_string_map_join_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; + ProfScope("join bake string maps") + { + for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) + { + for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) + { + B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); + B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); + if(src_slots_good && dst_slot_is_zero) + { + in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; + } + else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) + { + rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: bake string map sorting + +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; + ProfScope("sort bake string chunk list map range") + { + for(U64 slot_idx = in->slot_idx; + slot_idx < in->slot_idx+in->slot_count; + slot_idx += 1) + { + if(in->src_map->slots[slot_idx] != 0) + { + if(in->src_map->slots[slot_idx]->total_count > 1) + { + in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); + *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); + } + else + { + in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: pass 1: interner/deduper map builds + +ASYNC_WORK_DEF(rdim_build_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; + RDIM_BakeNameMap *name_map = 0; + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->params); + ProfEnd(); + return name_map; +} + +//- rjf: pass 2: string-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_units_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; + RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); + ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; + RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); + ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_src_files_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; + RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); + ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_udts_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; + RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->udts); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; + RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; + RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); + ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_thread_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; + RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->thread_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_procedures_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; + RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->procedures); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; + RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; + RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); + ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_inline_sites_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; + RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_file_paths_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; + RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); + ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; + RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); + ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); + ProfEnd(); + return out; +} + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_type_nodes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; + RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->types); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; + RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); + ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_idx_runs_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; + RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); + ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); + ProfEnd(); + return out; +} + +internal RDIM_HelpState * +rdim_help_init(void) +{ + Arena *arena = arena_alloc(); + RDIM_HelpState *state = push_array(arena, RDIM_HelpState, 1); + state->arena = arena; + state->work_thread_arenas_count = async_thread_count(); + state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); + for EachIndex(idx, state->work_thread_arenas_count) + { + state->work_thread_arenas[idx] = arena_alloc(); + } + return state; +} + +internal RDIM_BakeResults +rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +{ + Temp scratch = scratch_begin(0,0); + RDIM_BakeResults out = {0}; + + rdim_help_state = state; + + ////////////////////////////// + //- rjf: kick off line tables baking + // + ASYNC_Task *bake_line_tables_task = 0; + { + RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); + in->line_tables = &in_params->line_tables; + bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); + } + + ////////////////////////////// + //- rjf: build interned path tree + // + RDIM_BakePathTree *path_tree = 0; + ProfScope("build interned path tree") + { + path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + } + + ////////////////////////////// + //- rjf: kick off string map building tasks + // + RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + + in_params->procedures.total_count*1 + + in_params->global_variables.total_count*1 + + in_params->thread_variables.total_count*1 + + in_params->types.total_count/2)}; + RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); + ASYNC_TaskList bake_string_map_build_tasks = {0}; + { + // rjf: src files + ProfScope("kick off src files string map build task") + { + RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->src_files; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); + } + + // rjf: units + ProfScope("kick off units string map build task") + { + RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->units; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); + } + + // rjf: types + ProfScope("kick off types string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; + RDIM_TypeChunkNode *chunk = in_params->types.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); + } + } + + // rjf: UDTs + ProfScope("kick off udts string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; + RDIM_UDTChunkNode *chunk = in_params->udts.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); + } + } + + // rjf: symbols + ProfScope("kick off symbols string map build tasks") + { + RDIM_SymbolChunkList *symbol_lists[] = + { + &in_params->global_variables, + &in_params->thread_variables, + &in_params->procedures, + }; + for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) + { + U64 items_per_task = 4096; + U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; + RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); + } + } + } + + ProfScope("kick off inline site string map build task") + { + U64 items_per_task = 4096; + U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); + RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); + } + } + + // rjf: scope chunks + ProfScope("kick off scope chunks string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; + RDIM_ScopeChunkNode *chunk = in_params->scopes.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); + } + } + } + + ////////////////////////////// + //- rjf: kick off name map building tasks + // + RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; + ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + build_bake_name_map_in[k].k = k; + build_bake_name_map_in[k].params = in_params; + build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); + } + + ////////////////////////////// + //- rjf: join string map building tasks + // + ProfScope("join string map building tasks") + { + for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + + ////////////////////////////// + //- rjf: produce joined string map + // + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + ProfScope("produce joined string map") + { + U64 slots_per_task = 16384; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); + + // rjf: kickoff tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); + in->top = &bake_string_map_topology; + in->src_maps = bake_string_maps__in_progress; + in->src_maps_count = async_thread_count(); + in->dst_map = unsorted_bake_string_map; + in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); + in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); + tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); + } + + // rjf: join tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + async_task_join(tasks[task_idx]); + } + + // rjf: insert small top-level stuff + rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + } + + ////////////////////////////// + //- rjf: kick off string map sorting tasks + // + ASYNC_TaskList sort_bake_string_map_tasks = {0}; + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + { + U64 slots_per_task = 4096; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); + { + in->top = &bake_string_map_topology; + in->src_map = unsorted_bake_string_map; + in->dst_map = sorted_bake_string_map__in_progress; + in->slot_idx = task_idx*slots_per_task; + in->slot_count = slots_per_task; + if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) + { + in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; + } + } + async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); + } + } + + ////////////////////////////// + //- rjf: join string map sorting tasks + // + ProfScope("join string map sorting tasks") + { + for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; + + ////////////////////////////// + //- rjf: build finalized string map + // + ProfBegin("build finalized string map base indices"); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + ProfEnd(); + ProfBegin("build finalized string map"); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + ProfEnd(); + + ////////////////////////////// + //- rjf: kick off pass 2 tasks + // + RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; + ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); + RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; + ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); + RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; + ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts}; + ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; + ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); + RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; + ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; + ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures}; + ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes}; + ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); + RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; + ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites}; + ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); + RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; + ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); + RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; + ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); + + ////////////////////////////// + //- rjf: join name map building tasks + // + RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; + ProfScope("join name map building tasks") + { + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); + } + } + + ////////////////////////////// + //- rjf: build interned idx run map + // + RDIM_BakeIdxRunMap *idx_runs = 0; + ProfScope("build interned idx run map") + { + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, in_params); + } + + ////////////////////////////// + //- rjf: do small top-level bakes + // + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + + ////////////////////////////// + //- rjf: kick off pass 3 tasks + // + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types}; + ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); + ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + if(name_maps[k] == 0 || name_maps[k]->name_count == 0) + { + continue; + } + RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); + in->strings = &bake_strings; + in->idx_runs = idx_runs; + in->map = name_maps[k]; + in->kind = k; + bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); + } + } + RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; + ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); + + ////////////////////////////// + //- rjf: join remaining completed bakes + // + ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); + ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); + ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); + ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); + ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); + ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); + ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); + ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); + ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); + ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); + ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); + ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); + ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); + ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); + ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); + ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); + + ////////////////////////////// + //- rjf: join individual name map bakes + // + RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; + ProfScope("name maps") + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); + if(bake != 0) + { + name_map_bakes[k] = *bake; + } + } + } + + ////////////////////////////// + //- rjf: join all individual name map bakes + // + ProfScope("join all name map bakes into final name map bake") + { + out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + } + + rdim_help_state = 0; + + scratch_end(scratch); + return out; +} + +internal RDIM_SerializedSectionBundle +rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) +{ + RDIM_SerializedSectionBundle out = {0}; + + //- rjf: set up compression context + rr_lzb_simple_context ctx = {0}; + ctx.m_tableSizeBits = 14; + ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; + RDIM_SerializedSection *dst = &out.sections[k]; + MemoryCopyStruct(dst, src); + + // rjf: determine if this section should be compressed + B32 should_compress = 1; + + // rjf: compress if needed + if(should_compress) + { + MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); + dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); + dst->unpacked_size = src->encoded_size; + dst->encoding = RDI_SectionEncoding_LZB; + } + } + + return out; +} diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h new file mode 100644 index 00000000..159e3a3e --- /dev/null +++ b/src/rdi_make/rdi_make_help.h @@ -0,0 +1,330 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RDIM_MAKE_HELP +#define RDIM_MAKE_HELP + +//- rjf: line table baking task types + +typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; +struct RDIM_BakeLineTablesIn +{ + RDIM_LineTableChunkList *line_tables; +}; + +//- rjf: string map baking task types + +typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; +struct RDIM_BakeSrcFilesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_SrcFileChunkList *list; +}; + +typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; +struct RDIM_BakeUnitsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_UnitChunkList *list; +}; + +typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; +struct RDIM_BakeUDTsStringsInNode +{ + RDIM_BakeUDTsStringsInNode *next; + RDIM_UDT *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; +struct RDIM_BakeTypesStringsInNode +{ + RDIM_BakeTypesStringsInNode *next; + RDIM_Type *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; +struct RDIM_BakeTypesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeTypesStringsInNode *first; + RDIM_BakeTypesStringsInNode *last; +}; + +typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; +struct RDIM_BakeUDTsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeUDTsStringsInNode *first; + RDIM_BakeUDTsStringsInNode *last; +}; + +typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; +struct RDIM_BakeSymbolsStringsInNode +{ + RDIM_BakeSymbolsStringsInNode *next; + RDIM_Symbol *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; +struct RDIM_BakeSymbolsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeSymbolsStringsInNode *first; + RDIM_BakeSymbolsStringsInNode *last; +}; + +typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; +struct RDIM_BakeInlineSiteStringsInNode +{ + RDIM_BakeInlineSiteStringsInNode *next; + RDIM_InlineSite *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; +struct RDIM_BakeInlineSiteStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeInlineSiteStringsInNode *first; + RDIM_BakeInlineSiteStringsInNode *last; +}; + +typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; +struct RDIM_BakeScopesStringsInNode +{ + RDIM_BakeScopesStringsInNode *next; + RDIM_Scope *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; +struct RDIM_BakeScopesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeScopesStringsInNode *first; + RDIM_BakeScopesStringsInNode *last; +}; + +//- rjf: OLD string map baking types + +typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; +struct RDIM_BuildBakeStringMapIn +{ + RDIM_BakePathTree *path_tree; + RDIM_BakeParams *params; +}; + +typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; +struct RDIM_BuildBakeNameMapIn +{ + RDI_NameMapKind k; + RDIM_BakeParams *params; +}; + +//- rjf: string map joining task types + +typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; +struct RDIM_JoinBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **src_maps; + U64 src_maps_count; + RDIM_BakeStringMapLoose *dst_map; + Rng1U64 slot_idx_range; +}; + +//- rjf: string map sorting task types + +typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; +struct RDIM_SortBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose *src_map; + RDIM_BakeStringMapLoose *dst_map; + U64 slot_idx; + U64 slot_count; +}; + +//- rjf: debug info baking task types + +typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; +struct RDIM_BakeUnitsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; +struct RDIM_BakeUnitVMapIn +{ + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; +struct RDIM_BakeSrcFilesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_SrcFileChunkList *src_files; +}; + +typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; +struct RDIM_BakeUDTsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_UDTChunkList *udts; +}; + +typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; +struct RDIM_BakeGlobalVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *global_variables; +}; + +typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; +struct RDIM_BakeGlobalVMapIn +{ + RDIM_SymbolChunkList *global_variables; +}; + +typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; +struct RDIM_BakeThreadVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *thread_variables; +}; + +typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; +struct RDIM_BakeProceduresIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *procedures; +}; + +typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; +struct RDIM_BakeScopesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_ScopeChunkList *scopes; +}; + +typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; +struct RDIM_BakeScopeVMapIn +{ + RDIM_ScopeChunkList *scopes; +}; + +typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; +struct RDIM_BakeInlineSitesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_InlineSiteChunkList *inline_sites; +}; + +typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; +struct RDIM_BakeFilePathsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; +}; + +typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; +struct RDIM_BakeStringsIn +{ + RDIM_BakeStringMapTight *strings; +}; + +typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; +struct RDIM_BakeTypeNodesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_TypeChunkList *types; +}; + +typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; +struct RDIM_BakeNameMapIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_BakeNameMap *map; + RDI_NameMapKind kind; +}; + +typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; +struct RDIM_BakeIdxRunsIn +{ + RDIM_BakeIdxRunMap *idx_runs; +}; + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: unsorted bake string map building +ASYNC_WORK_DEF(p2r_bake_src_files_strings_work); +ASYNC_WORK_DEF(p2r_bake_units_strings_work); +ASYNC_WORK_DEF(p2r_bake_types_strings_work); +ASYNC_WORK_DEF(p2r_bake_udts_strings_work); +ASYNC_WORK_DEF(p2r_bake_symbols_strings_work); +ASYNC_WORK_DEF(p2r_bake_scopes_strings_work); +ASYNC_WORK_DEF(p2r_bake_line_tables_work); + +//- rjf: bake string map joining +ASYNC_WORK_DEF(p2r_bake_string_map_join_work); + +//- rjf: bake string map sorting +ASYNC_WORK_DEF(p2r_bake_string_map_sort_work); + +//- rjf: pass 1: interner/deduper map builds +ASYNC_WORK_DEF(p2r_build_bake_name_map_work); + +//- rjf: pass 2: string-map-dependent debug info stream builds +ASYNC_WORK_DEF(p2r_bake_units_work); +ASYNC_WORK_DEF(p2r_bake_unit_vmap_work); +ASYNC_WORK_DEF(p2r_bake_src_files_work); +ASYNC_WORK_DEF(p2r_bake_udts_work); +ASYNC_WORK_DEF(p2r_bake_global_variables_work); +ASYNC_WORK_DEF(p2r_bake_global_vmap_work); +ASYNC_WORK_DEF(p2r_bake_thread_variables_work); +ASYNC_WORK_DEF(p2r_bake_procedures_work); +ASYNC_WORK_DEF(p2r_bake_scopes_work); +ASYNC_WORK_DEF(p2r_bake_scope_vmap_work); +ASYNC_WORK_DEF(p2r_bake_file_paths_work); +ASYNC_WORK_DEF(p2r_bake_strings_work); + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds +ASYNC_WORK_DEF(p2r_bake_type_nodes_work); +ASYNC_WORK_DEF(p2r_bake_name_map_work); +ASYNC_WORK_DEF(p2r_bake_idx_runs_work); + +typedef struct RDIM_HelpState RDIM_HelpState; +struct RDIM_HelpState +{ + Arena *arena; + U64 work_thread_arenas_count; + Arena **work_thread_arenas; +}; + +//////////////////////////////// + +global RDIM_HelpState *rdim_help_state = 0; + +//////////////////////////////// + +internal RDIM_HelpState * rdim_help_init(void); +internal RDIM_BakeResults rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in); +internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); + +#endif // RDIM_MAKE_HELP From 35ed8d6a1edfc70459da6d9a4fa315f11c86d0bc Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:10:06 -0800 Subject: [PATCH 193/755] bugfixed zero-length block decomp and fixed 64-bit casts --- src/third_party/sinfl/sinfl.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/third_party/sinfl/sinfl.h b/src/third_party/sinfl/sinfl.h index ca225d58..8075a12d 100644 --- a/src/third_party/sinfl/sinfl.h +++ b/src/third_party/sinfl/sinfl.h @@ -1,4 +1,6 @@ -// NOTE: changed input and output var types from int to size_t +// NOTE: +// - updated library to handle 64-bit inputs +// - fixed a bug where on decomp would exit on blocks with zero length /* # Small Deflate @@ -396,7 +398,7 @@ sinfl_decompress(unsigned char *out, size_t cap, const unsigned char *in, size_t last = sinfl__get(&s,1); type = sinfl__get(&s,2); - switch (type) {default: return (int)(out-o); + switch (type) {default: return (size_t)(out-o); case 0x00: state = stored; break; case 0x01: state = fixed; break; case 0x02: state = dyn; break;} @@ -411,13 +413,13 @@ sinfl_decompress(unsigned char *out, size_t cap, const unsigned char *in, size_t s.bitbuf = s.bitcnt = 0; if ((unsigned short)len != (unsigned short)~nlen) - return (int)(out-o); - if (len > (e - s.bitptr) || !len) - return (int)(out-o); + return (size_t)(out-o); + if (len > (e - s.bitptr)) + return (size_t)(out-o); memcpy(out, s.bitptr, (size_t)len); s.bitptr += len, out += len; - if (last) return (int)(out-o); + if (last) return (size_t)(out-o); state = hdr; } break; case fixed: { @@ -472,7 +474,7 @@ sinfl_decompress(unsigned char *out, size_t cap, const unsigned char *in, size_t if (sym < 256) { /* literal */ if (sinfl_unlikely(out >= oe)) { - return (int)(out-o); + return (size_t)(out-o); } *out++ = (unsigned char)sym; sym = sinfl_decode(&s, s.lits, 10); @@ -483,22 +485,22 @@ sinfl_decompress(unsigned char *out, size_t cap, const unsigned char *in, size_t } if (sinfl_unlikely(sym == 256)) { /* end of block */ - if (last) return (int)(out-o); + if (last) return (size_t)(out-o); state = hdr; break; } /* match */ if (sym >= 286) { /* length codes 286 and 287 must not appear in compressed data */ - return (int)(out-o); + return (size_t)(out-o); } sym -= 257; {int len = sinfl__get(&s, lbits[sym]) + lbase[sym]; int dsym = sinfl_decode(&s, s.dsts, 8); int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym]; unsigned char *dst = out, *src = out - offs; - if (sinfl_unlikely(offs > (int)(out-o))) { - return (int)(out-o); + if (sinfl_unlikely(offs > (size_t)(out-o))) { + return (size_t)(out-o); } out = out + len; @@ -577,7 +579,7 @@ sinfl_adler32(unsigned adler32, const unsigned char *in, size_t in_len) { const unsigned ADLER_MOD = 65521; unsigned s1 = adler32 & 0xffff; unsigned s2 = adler32 >> 16; - unsigned blk_len, i; + size_t blk_len, i; blk_len = in_len % 5552; while (in_len) { @@ -604,7 +606,7 @@ zsinflate(void *out, size_t cap, const void *mem, size_t size) { const unsigned char *in = (const unsigned char*)mem; if (size >= 6) { const unsigned char *eob = in + size - 4; - int n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size); + size_t n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size); unsigned a = sinfl_adler32(1u, (unsigned char*)out, n); unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0; return a == h ? n : -1; From 6c425aa9dc7384db5a968f9efaa8d8830270151a Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:10:44 -0800 Subject: [PATCH 194/755] misc NATVIS types --- src/natvis/base.natvis | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/natvis/base.natvis b/src/natvis/base.natvis index ad19ed09..5ef4ef74 100644 --- a/src/natvis/base.natvis +++ b/src/natvis/base.natvis @@ -147,6 +147,10 @@ + + + + {{ count={count} first={first} }} count From ed897979ca727fa8b8cf7ee37b405dd68486a48b Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:11:52 -0800 Subject: [PATCH 195/755] added fields for user defined ELF types --- src/elf/elf.h | 80 +++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/elf/elf.h b/src/elf/elf.h index 2ee63aa3..791b8351 100644 --- a/src/elf/elf.h +++ b/src/elf/elf.h @@ -98,16 +98,6 @@ enum ELF_MachineKind_S390_OLD = 0xA390, }; -typedef U16 ELF_Type; -enum -{ - ELF_Type_None, - ELF_Type_Rel, - ELF_Type_Exec, - ELF_Type_Dyn, - ELF_Type_Core, -}; - typedef U8 ELF_Data; enum { @@ -681,40 +671,54 @@ typedef enum ELF_Identifier ELF_Identifier_Max = 16, } ELF_Identifier; +typedef U16 ELF_Type; +typedef enum ELF_TypeEnum +{ + ELF_Type_None = 0, + ELF_Type_Rel = 1, + ELF_Type_Exec = 2, + ELF_Type_Dyn = 3, + ELF_Type_Core = 4, + ELF_Type_LoOs = 0xfe00, + ELF_Type_HiOs = 0xfeff, + ELF_Type_LoProc = 0xff00, + ELF_Type_HiProc = 0xffff, +} ELF_TypeEnum; + typedef struct ELF_Hdr64 { - U8 e_ident[ELF_Identifier_Max]; - U16 e_type; - U16 e_machine; - U32 e_version; - U64 e_entry; - U64 e_phoff; - U64 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; + U8 e_ident[ELF_Identifier_Max]; + ELF_Type e_type; + ELF_MachineKind e_machine; + U32 e_version; + U64 e_entry; + U64 e_phoff; + U64 e_shoff; + U32 e_flags; + U16 e_ehsize; + U16 e_phentsize; + U16 e_phnum; + U16 e_shentsize; + U16 e_shnum; + U16 e_shstrndx; } ELF_Hdr64; typedef struct ELF_Hdr32 { - U8 e_ident[ELF_Identifier_Max]; - U16 e_type; - U16 e_machine; - U32 e_version; - U32 e_entry; - U32 e_phoff; - U32 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; + U8 e_ident[ELF_Identifier_Max]; + ELF_Type e_type; + ELF_MachineKind e_machine; + U32 e_version; + U32 e_entry; + U32 e_phoff; + U32 e_shoff; + U32 e_flags; + U16 e_ehsize; + U16 e_phentsize; + U16 e_phnum; + U16 e_shentsize; + U16 e_shnum; + U16 e_shstrndx; } ELF_Hdr32; typedef struct ELF_Shdr64 From 2ba1a0d502cf926b09c95ae374a9b56ecdb5eb22 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:14:22 -0800 Subject: [PATCH 196/755] pass over DWARF header - added new types - renamed mode -> format - fixed section naming - added helper for picking array lower bound --- src/dwarf/dwarf.c | 74 +++++++++++++-- src/dwarf/dwarf.h | 211 +++++++++++++++++++++++++---------------- src/dwarf/dwarf_enum.c | 22 ++--- 3 files changed, 200 insertions(+), 107 deletions(-) diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index 6a224f34..ea440ee3 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -135,6 +135,11 @@ internal DW_AttribClass dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k) { #define X(_N,_C) case DW_Form_##_N: return _C; + + switch (k) { + DW_Form_AttribClass_GNU_XList(X) + } + switch (ver) { case DW_Version_5: { switch (k) { @@ -207,20 +212,20 @@ dw_dwo_name_string_from_section_kind(DW_SectionKind k) } internal U64 -dw_offset_size_from_mode(DW_Mode mode) +dw_size_from_format(DW_Format format) { U64 result = 0; - switch (mode) { - case DW_Mode_Null: break; - case DW_Mode_32Bit: result = 4; break; - case DW_Mode_64Bit: result = 8; break; + switch (format) { + case DW_Format_Null: break; + case DW_Format_32Bit: result = 4; break; + case DW_Format_64Bit: result = 8; break; default: InvalidPath; break; } return result; } internal DW_AttribClass -dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind) +dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind) { // NOTE(rjf): DWARF's spec specifies two mappings: // (DW_AttribKind) => List(DW_AttribClass) @@ -257,10 +262,59 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 rel } } - if (attrib_kind != DW_Attrib_Null && form_kind != DW_Form_Null) { - //Assert(result != DW_AttribClass_Null && result != DW_AttribClass_Undefined); - } - return result; } +internal U64 +dw_pick_default_lower_bound(DW_Language lang) +{ + U64 lower_bound = max_U64; + switch (lang) { + case DW_Language_Null: break; + case DW_Language_C89: + case DW_Language_C: + case DW_Language_CPlusPlus: + case DW_Language_C99: + case DW_Language_CPlusPlus03: + case DW_Language_CPlusPlus11: + case DW_Language_C11: + case DW_Language_CPlusPlus14: + case DW_Language_Java: + case DW_Language_ObjC: + case DW_Language_ObjCPlusPlus: + case DW_Language_UPC: + case DW_Language_D: + case DW_Language_Python: + case DW_Language_OpenCL: + case DW_Language_Go: + case DW_Language_Haskell: + case DW_Language_OCaml: + case DW_Language_Rust: + case DW_Language_Swift: + case DW_Language_Dylan: + case DW_Language_RenderScript: + case DW_Language_BLISS: + lower_bound = 0; + break; + case DW_Language_Ada83: + case DW_Language_Cobol74: + case DW_Language_Cobol85: + case DW_Language_Fortran77: + case DW_Language_Fortran90: + case DW_Language_Pascal83: + case DW_Language_Modula2: + case DW_Language_Ada95: + case DW_Language_Fortran95: + case DW_Language_PLI: + case DW_Language_Modula3: + case DW_Language_Julia: + case DW_Language_Fortran03: + case DW_Language_Fortran08: + lower_bound = 1; + default: + NotImplemented; + break; + } + return lower_bound; +} + diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 19d3a24a..860d8ab5 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -29,32 +29,35 @@ typedef enum DW_ExtEnum DW_Ext_All = DW_Ext_GNU|DW_Ext_LLVM|DW_Ext_APPLE|DW_Ext_MIPS, } DW_ExtEnum; -typedef enum DW_Mode +#define DW_FormatFromSize(size) ((size) >= max_U32 ? DW_Format_64Bit : DW_Format_32Bit) +typedef enum DW_Format { - DW_Mode_Null, - DW_Mode_32Bit, - DW_Mode_64Bit -} DW_Mode; + DW_Format_Null, + DW_Format_32Bit, + DW_Format_64Bit +} DW_Format; -#define DW_SectionKind_XList(X) \ - X(Null, "", "", "" ) \ - X(Abbrev, ".debug_abbrev", "__debug_abbrev", ".debug_abbrev.dwo" ) \ - X(ARanges, ".debug_aranges", "__debug_aranges", ".debug_aranges.dwo" ) \ - X(Frame, ".debug_frame", "__debug_frame", ".debug_frame.dwo" ) \ - X(Info, ".debug_info", "__debug_info", ".debug_info.dwo" ) \ - X(Line, ".debug_line", "__debug_line", ".debug_line.dwo" ) \ - X(Loc, ".debug_loc", "__debug_loc", ".debug_loc.dwo" ) \ - X(MacInfo, ".debug_macinfo", "__debug_macinfo", ".debug_macinfo.dwo" ) \ - X(PubNames, ".debug_pubnames", "__debug_pubnames", ".debug_pubnames.dwo" ) \ - X(PubTypes, ".debug_pubtypes", "__debug_pubtypes", ".debug_pubtypes.dwo" ) \ - X(Ranges, ".debug_ranges", "__debug_ranges", ".debug_ranges.dwo" ) \ - X(Str, ".debug_str", "__debug_str", ".debug_str.dwo" ) \ - X(Addr, ".debug_addr", "__debug_addr", ".debug_addr.dwo" ) \ - X(LocLists, ".debug_loclists", "__debug_loclists", ".debug_loclists.dwo" ) \ - X(RngLists, ".debug_rnglists", "__debug_rnglists", ".debug_rnglists.dwo" ) \ - X(StrOffsets, ".debug_stroffsets", "__debug_stroffsets", ".debug_stroffsets.dwo" ) \ - X(LineStr, ".debug_linestr", "__debug_linestr", ".debug_linestr.dwo" ) \ - X(Names, ".debug_names", "__debug_names", ".debug_names.dwo" ) +#define DW_SentinelFromSize(address_size) ((address_size) == 4 ? max_U32 : (address_size) == 8 ? max_U64 : 0) + +#define DW_SectionKind_XList(X )\ + X(Null, "", "", "" )\ + X(Abbrev, ".debug_abbrev", "__debug_abbrev", ".debug_abbrev.dwo" )\ + X(ARanges, ".debug_aranges", "__debug_aranges", ".debug_aranges.dwo" )\ + X(Frame, ".debug_frame", "__debug_frame", ".debug_frame.dwo" )\ + X(Info, ".debug_info", "__debug_info", ".debug_info.dwo" )\ + X(Line, ".debug_line", "__debug_line", ".debug_line.dwo" )\ + X(Loc, ".debug_loc", "__debug_loc", ".debug_loc.dwo" )\ + X(MacInfo, ".debug_macinfo", "__debug_macinfo", ".debug_macinfo.dwo" )\ + X(PubNames, ".debug_pubnames", "__debug_pubnames", ".debug_pubnames.dwo" )\ + X(PubTypes, ".debug_pubtypes", "__debug_pubtypes", ".debug_pubtypes.dwo" )\ + X(Ranges, ".debug_ranges", "__debug_ranges", ".debug_ranges.dwo" )\ + X(Str, ".debug_str", "__debug_str", ".debug_str.dwo" )\ + X(Addr, ".debug_addr", "__debug_addr", ".debug_addr.dwo" )\ + X(LocLists, ".debug_loclists", "__debug_loclists", ".debug_loclists.dwo" )\ + X(RngLists, ".debug_rnglists", "__debug_rnglists", ".debug_rnglists.dwo" )\ + X(StrOffsets, ".debug_str_offsets", "__debug_str_offsets", ".debug_str_offsets.dwo")\ + X(LineStr, ".debug_line_str", "__debug_line_str", ".debug_line_str.dwo" )\ + X(Names, ".debug_names", "__debug_names", ".debug_names.dwo" ) typedef U64 DW_SectionKind; typedef enum DW_SectionKindEnum @@ -82,8 +85,8 @@ typedef enum DW_SectionKindEnum X(Ada95, 0x0D) \ X(Fortran95, 0x0E) \ X(PLI, 0x0F) \ - X(ObjectiveC, 0x10) \ - X(ObjectiveCPlusPlus, 0x11) \ + X(ObjC, 0x10) \ + X(ObjCPlusPlus, 0x11) \ X(UPC, 0x12) \ X(D, 0x13) \ X(Python, 0x14) \ @@ -171,19 +174,19 @@ typedef enum DW_ExtOpcode #undef X } DW_ExtOpcode; -#define DW_NameCase_XList(X) \ - X(Sensitive, 0x00) \ - X(Upper, 0x01) \ - X(Lower, 0x02) \ - X(Insensitive, 0x03) +#define DW_IDCaseKind_XList(X) \ + X(CaseSensitive, 0x00) \ + X(UpCase, 0x01) \ + X(DownCase, 0x02) \ + X(CaseInsensitive, 0x03) -typedef enum DW_NameCase +typedef U64 DW_IDCaseKind; +typedef enum DW_IDCaseKindEnum { -#define X(_N,_ID) DW_NameCase_##_N = _ID, - DW_NameCase_XList(X) +#define X(_N,_ID) DW_IDCase_##_N = _ID, + DW_IDCaseKind_XList(X) #undef X - DW_NameCase_Count -} DW_NameCase; +} DW_IDCaseKindEnum; #define DW_Tag_V3_XList(X) \ X(ArrayType, 0x01) \ @@ -462,6 +465,18 @@ typedef enum DW_AttribClassEnum X(Addrx3, DW_AttribClass_Address) \ X(Addrx4, DW_AttribClass_Address) +#define DW_Form_GNU_XList(X) \ + X(GNU_AddrIndex, 0x1f01) \ + X(GNU_StrIndex, 0x1f02) \ + X(GNU_RefAlt, 0x1f20) \ + X(GNU_StrpAlt, 0x1f21) + +#define DW_Form_AttribClass_GNU_XList(X) \ + X(GNU_AddrIndex, DW_AttribClass_Undefined) \ + X(GNU_StrIndex, DW_AttribClass_Undefined) \ + X(GNU_RefAlt, DW_AttribClass_Undefined) \ + X(GNU_StrpAlt, DW_AttribClass_String) + typedef U64 DW_FormKind; typedef enum DW_FormEnum { @@ -470,6 +485,7 @@ typedef enum DW_FormEnum DW_Form_V2_XList(X) DW_Form_V4_XList(X) DW_Form_V5_XList(X) + DW_Form_GNU_XList(X) #undef X } DW_FormEnum; @@ -1158,34 +1174,34 @@ typedef enum DW_AttribKindEnum DW_Attrib_UserHi = 0x3fff } DW_AttribKindEnum; -#define DW_AttribTypeEncodingKind_XList(X) \ - X(Null, 0x00) \ - X(Address, 0x01) \ - X(Boolean, 0x02) \ - X(ComplexFloat, 0x03) \ - X(Float, 0x04) \ - X(Signed, 0x05) \ - X(SignedChar, 0x06) \ - X(Unsigned, 0x07) \ - X(UnsignedChar, 0x08) \ - X(ImaginaryFloat, 0x09) \ - X(PackedDecimal, 0x0A) \ - X(NumericString, 0x0B) \ - X(Edited, 0x0C) \ - X(SignedFixed, 0x0D) \ - X(UnsignedFixed, 0x0E) \ - X(DecimalFloat, 0x0F) \ - X(Utf, 0x10) \ - X(Ucs, 0x11) \ +#define DW_ATE_XList(X) \ + X(Null, 0x00) \ + X(Address, 0x01) \ + X(Boolean, 0x02) \ + X(ComplexFloat, 0x03) \ + X(Float, 0x04) \ + X(Signed, 0x05) \ + X(SignedChar, 0x06) \ + X(Unsigned, 0x07) \ + X(UnsignedChar, 0x08) \ + X(ImaginaryFloat, 0x09) \ + X(PackedDecimal, 0x0A) \ + X(NumericString, 0x0B) \ + X(Edited, 0x0C) \ + X(SignedFixed, 0x0D) \ + X(UnsignedFixed, 0x0E) \ + X(DecimalFloat, 0x0F) \ + X(Utf, 0x10) \ + X(Ucs, 0x11) \ X(Ascii, 0x12) -typedef U64 DW_AttribTypeEncodingKind; -typedef enum DW_AttribTypeEncodingKindEnum +typedef U64 DW_ATE; +typedef enum DW_ATEEnum { -#define X(_N,_ID) DW_AttribTypeEncodingKind_##_N = _ID, - DW_AttribTypeEncodingKind_XList(X) +#define X(_N,_ID) DW_ATE_##_N = _ID, + DW_ATE_XList(X) #undef X -} DW_AttribTypeEncodingKindEnum; +} DW_ATEnum; #define DW_CallingConventionKind_XList(X) \ X(Normal, 0x0) \ @@ -1230,7 +1246,7 @@ typedef enum DW_VirtualityEnum #define DW_RngListEntryKind(X) \ X(EndOfList, 0x00) \ - X(BaseAddressX, 0x01) \ + X(BaseAddressx, 0x01) \ X(StartxEndx, 0x02) \ X(StartxLength, 0x03) \ X(OffsetPair, 0x04) \ @@ -1238,32 +1254,51 @@ typedef enum DW_VirtualityEnum X(StartEnd, 0x06) \ X(StartLength, 0x07) -typedef U64 DW_RngListEntryKind; -typedef enum DW_RngListEntryKindEnum +typedef U8 DW_RLE; +typedef enum DW_RLE_Enum { -#define X(_N,_ID) DW_RngListEntryKind_##_N = _ID, +#define X(_N,_ID) DW_RLE_##_N = _ID, DW_RngListEntryKind(X) #undef X -} DW_RngListEntryKindEnum; +} DW_RLE_Enum; #define DW_LocListEntry_XList(X) \ X(EndOfList, 0x00) \ - X(BaseAddressX, 0x01) \ - X(StartXEndX, 0x02) \ - X(StartXLength, 0x03) \ + X(BaseAddressx, 0x01) \ + X(StartxEndx, 0x02) \ + X(StartxLength, 0x03) \ X(OffsetPair, 0x04) \ X(DefaultLocation, 0x05) \ X(BaseAddress, 0x06) \ X(StartEnd, 0x07) \ X(StartLength, 0x08) -typedef U64 DW_LocListEntryKind; -typedef enum DW_LocListEntryEnum +#define DW_LocListEntry_GNU_XList(X) \ + X(GNU_ViewPair, 0x9) + +typedef U8 DW_LLE; +typedef enum DW_LLE_Enum { -#define X(_N,_ID) DW_LocListEntryKind_##_N = _ID, +#define X(_N,_ID) DW_LLE_##_N = _ID, DW_LocListEntry_XList(X) #undef X -} DW_LocListEntryEnum; +} DW_LLEEnum; + +#define DW_AddrClass_XList(X) \ + X(None, 0) \ + X(Near16, 1) \ + X(Far16, 2) \ + X(Huge16, 3) \ + X(Near32, 4) \ + X(Far32, 5) + +typedef U64 DW_AddrClass; +typedef enum DW_AddrClassEnum +{ +#define X(_N, _ID) DW_AddrClassKind_##_N = _ID, + DW_AddrClass_XList(X) +#undef X +} DW_AddrClassEnum; #define DW_CompUnitKind_XList(X) \ X(Reserved, 0) \ @@ -1284,16 +1319,23 @@ typedef enum DW_CompUnitKindEnum DW_CompUnitKind_UserHi = 0xff } DW_CompUnitKindEnum; -typedef enum DW_LNCT +#define DW_LNCT_XList(X) \ + X(Path, 0x1) \ + X(DirectoryIndex, 0x2) \ + X(TimeStamp, 0x3) \ + X(Size, 0x4) \ + X(MD5, 0x5) \ + X(LLVM_Source, 0x2001) + +typedef U64 DW_LNCT; +typedef enum DW_LNCTEnum { - DW_LNCT_Path = 0x1, - DW_LNCT_DirectoryIndex = 0x2, - DW_LNCT_TimeStamp = 0x3, - DW_LNCT_Size = 0x4, - DW_LNCT_MD5 = 0x5, - DW_LNCT_UserLo = 0x2000, - DW_LNCT_UserHi = 0x3fff -} DW_LNCT; +#define X(_N, _ID) DW_LNCT_##_N = _ID, + DW_LNCT_XList(X) +#undef X + DW_LNCT_UserLo = 0x2000, + DW_LNCT_UserHi = 0x3fff +} DW_LNCTEnum; #define DW_CFA_Kind1_XList(X) \ X(Nop, 0x0) \ @@ -1529,6 +1571,7 @@ enum X(GNU_RegvalType, 0xf5) \ X(GNU_DerefType, 0xf6) \ X(GNU_Convert, 0xf7) \ + X(GNU_ParameterRef, 0xfa) \ X(GNU_AddrIndex, 0xfb) \ X(GNU_ConstIndex, 0xfc) @@ -1705,10 +1748,12 @@ internal String8 dw_dwo_name_string_from_section_kind (DW_SectionKind k); //////////////////////////////// -internal U64 dw_offset_size_from_mode(DW_Mode mode); +internal U64 dw_size_from_format(DW_Format format); //////////////////////////////// -internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind); +internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind); + +internal U64 dw_pick_default_lower_bound(DW_Language lang); #endif // DWARF_H diff --git a/src/dwarf/dwarf_enum.c b/src/dwarf/dwarf_enum.c index 8ea41d98..ae41b06b 100644 --- a/src/dwarf/dwarf_enum.c +++ b/src/dwarf/dwarf_enum.c @@ -7,16 +7,10 @@ dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op) String8 result = {0}; #define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit; - switch (ext) { - case DW_Ext_Null: break; - case DW_Ext_LLVM: break; - case DW_Ext_APPLE: break; - case DW_Ext_MIPS: break; - case DW_Ext_GNU: { - switch (op) { - DW_Expr_GNU_XList(X); - } - } break; + if (ext & DW_Ext_GNU) { + switch (op) { + DW_Expr_GNU_XList(X); + } } switch (ver) { @@ -188,11 +182,11 @@ dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind) } internal String8 -dw_string_from_attrib_type_encoding(Arena *arena, DW_AttribTypeEncodingKind kind) +dw_string_from_attrib_type_encoding(Arena *arena, DW_ATE kind) { switch (kind) { #define X(_N,_ID) case _ID: return str8_lit(Stringify(_N)); - DW_AttribTypeEncodingKind_XList(X) + DW_ATE_XList(X) #undef X } return push_str8f(arena, "%llx", kind); @@ -222,7 +216,7 @@ dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind) } internal String8 -dw_string_from_loc_list_entry_kind(Arena *arena, DW_LocListEntryKind kind) +dw_string_from_loc_list_entry_kind(Arena *arena, DW_LLE kind) { NotImplemented; return str8_zero(); @@ -236,7 +230,7 @@ dw_string_from_section_kind(Arena *arena, DW_SectionKind kind) } internal String8 -dw_string_from_rng_list_entry_kind(Arena *arena, DW_RngListEntryKind kind) +dw_string_from_rng_list_entry_kind(Arena *arena, DW_RLE kind) { NotImplemented; return str8_zero(); From dfd6950ff3cd5be318b821e19d6487d6c0d79781 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 3 Mar 2025 17:20:22 -0800 Subject: [PATCH 197/755] deleted obsolete DWARF parser files --- src/rdi_from_dwarf/rdi_dwarf.c | 1892 ---------------------- src/rdi_from_dwarf/rdi_dwarf.h | 1493 ----------------- src/rdi_from_dwarf/rdi_dwarf_stringize.c | 102 -- src/rdi_from_dwarf/rdi_dwarf_stringize.h | 28 - src/rdi_from_dwarf/rdi_elf.c | 557 ------- src/rdi_from_dwarf/rdi_elf.h | 517 ------ 6 files changed, 4589 deletions(-) delete mode 100644 src/rdi_from_dwarf/rdi_dwarf.c delete mode 100644 src/rdi_from_dwarf/rdi_dwarf.h delete mode 100644 src/rdi_from_dwarf/rdi_dwarf_stringize.c delete mode 100644 src/rdi_from_dwarf/rdi_dwarf_stringize.h delete mode 100644 src/rdi_from_dwarf/rdi_elf.c delete mode 100644 src/rdi_from_dwarf/rdi_elf.h diff --git a/src/rdi_from_dwarf/rdi_dwarf.c b/src/rdi_from_dwarf/rdi_dwarf.c deleted file mode 100644 index eb257f0f..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf.c +++ /dev/null @@ -1,1892 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ Dwarf Decode Helpers - -static U64 -dwarf_leb128_decode_U64(U8 *ptr, U8 *opl){ - U64 r = 0; - switch (opl - ptr){ - case 10: r |= ((U64)(ptr[9]&0x7F) << 63); - case 9: r |= ((U64)(ptr[8]&0x7F) << 56); - case 8: r |= ((U64)(ptr[7]&0x7F) << 49); - case 7: r |= ((U64)(ptr[6]&0x7F) << 42); - case 6: r |= ((U64)(ptr[5]&0x7F) << 35); - case 5: r |= ((U64)(ptr[4]&0x7F) << 28); - case 4: r |= ((U64)(ptr[3]&0x7F) << 21); - case 3: r |= ((U64)(ptr[2]&0x7F) << 14); - case 2: r |= ((U64)(ptr[1]&0x7F) << 7); - case 1: r |= ((U64)(ptr[0]&0x7F) ); - case 0: default: break; - } - return(r); -} - -static S64 -dwarf_leb128_decode_S64(U8 *ptr, U8 *opl){ - U64 u = dwarf_leb128_decode_U32(ptr, opl); - U64 s = (U64)(opl - ptr)*7; - B32 neg = ((u & (1llu << s)) != 0); - if (neg){ - switch (opl - ptr){ - case 9: u |= ~0x7FFFFFFFFFFFFFFFllu; break; - case 8: u |= ~0x00FFFFFFFFFFFFFFllu; break; - case 7: u |= ~ 0x01FFFFFFFFFFFFllu; break; - case 6: u |= ~ 0x03FFFFFFFFFFllu; break; - case 5: u |= ~ 0x07FFFFFFFFllu; break; - case 4: u |= ~ 0x0FFFFFFFllu; break; - case 3: u |= ~ 0x1FFFFFllu; break; - case 2: u |= ~ 0x3FFFllu; break; - case 1: u |= ~ 0x7Fllu; break; - } - } - S64 r = (S64)(u); - return(r); -} - -static U32 -dwarf_leb128_decode_U32(U8 *ptr, U8 *opl){ - U32 r = 0; - switch (opl - ptr){ - case 5: r |= ((U32)(ptr[4]&0x7F) << 28); - case 4: r |= ((U32)(ptr[3]&0x7F) << 21); - case 3: r |= ((U32)(ptr[2]&0x7F) << 14); - case 2: r |= ((U32)(ptr[1]&0x7F) << 7); - case 1: r |= ((U32)(ptr[0]&0x7F) ); - case 0: default: break; - } - return(r); -} - - -//////////////////////////////// -//~ Dwarf Parser Functions - -static DWARF_Parsed* -dwarf_parsed_from_elf(Arena *arena, ELF_Parsed *elf){ - DWARF_Parsed *result = 0; - - if (elf != 0){ - //- extract debug info - U32 debug_section_idx[DWARF_SectionCode_COUNT] = {0}; - String8 debug_section_name[DWARF_SectionCode_COUNT] = {0}; - String8 debug_data[DWARF_SectionCode_COUNT] = {0}; - for (U64 i = 1; i < DWARF_SectionCode_COUNT; i += 1){ - DWARF_SectionNameRow *row = dwarf_section_name_table + i; - U32 idx = 0; - for (U32 j = 0; idx == 0 && j < DWARF_SECTION_NAME_VARIANT_COUNT; j += 1){ - idx = elf_section_idx_from_name(elf, row->name[j]); - } - debug_section_idx[i] = idx; - debug_section_name[i] = elf_section_name_from_idx(elf, idx); - debug_data[i] = elf_section_data_from_idx(elf, idx); - } - - //- fill result - { - result = push_array(arena, DWARF_Parsed, 1); - result->elf = elf; - MemoryCopyArray(result->debug_section_idx, debug_section_idx); - MemoryCopyArray(result->debug_section_name, debug_section_name); - MemoryCopyArray(result->debug_data, debug_data); - } - } - - return(result); -} - -static DWARF_IndexParsed* -dwarf_index_from_data(Arena *arena, String8 data){ - DWARF_IndexParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_SupParsed* -dwarf_sup_from_data(Arena *arena, String8 data){ - DWARF_SupParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_InfoParsed* -dwarf_info_from_data(Arena *arena, String8 data){ - // supported version numbers: 4,5 - - - // empty unit list - DWARF_InfoUnit *first = 0; - DWARF_InfoUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // rest of header depends on version - U64 abbrev_off = 0; - U8 address_size = 0; - U8 unit_type = 0; - U64 unit_dwo_id = 0; - U64 unit_type_signature = 0; - U64 unit_type_offset = 0; - switch (version){ - case 4: - { - // abbrev_off - if (is_64bit){ - abbrev_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_off = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - }break; - - case 5: - { - // unit_type - unit_type = (DWARF_UnitType)MemoryConsume(U8, ptr, unit_opl); - - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - - // abbrev_off - if (is_64bit){ - abbrev_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_off = MemoryConsume(U32, ptr, unit_opl); - } - - // rest of header depends on unit_type - switch (unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - unit_dwo_id = MemoryConsume(U64, ptr, unit_opl); - }break; - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - unit_type_signature = MemoryConsume(U64, ptr, unit_opl); - if (is_64bit){ - unit_type_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - unit_type_offset = MemoryConsume(U32, ptr, unit_opl); - } - }break; - } - }break; - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_InfoUnit *unit = push_array(arena, DWARF_InfoUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->version = version; - unit->unit_type = unit_type; - unit->address_size = address_size; - unit->abbrev_off = abbrev_off; - - switch (unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - unit->dwo_id = unit_dwo_id; - }break; - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - unit->type_signature = unit_type_signature; - unit->type_offset = unit_type_offset; - }break; - } - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_InfoParsed *result = push_array(arena, DWARF_InfoParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_PubNamesParsed* -dwarf_pubnames_from_data(Arena *arena, String8 data){ - // supported version numbers: 2 - - - // empty unit list - DWARF_PubNamesUnit *first = 0; - DWARF_PubNamesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // info_off - U64 info_off = 0; - if (is_64bit){ - info_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_off = MemoryConsume(U32, ptr, unit_opl); - } - - // info_length - U64 info_length = 0; - if (is_64bit){ - info_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_length = MemoryConsume(U32, ptr, unit_opl); - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_PubNamesUnit *unit = push_array(arena, DWARF_PubNamesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->version = version; - unit->info_off = info_off; - unit->info_length = info_length; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_PubNamesParsed *result = push_array(arena, DWARF_PubNamesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_NamesParsed* -dwarf_names_from_data(Arena *arena, String8 data){ - // supported version numbers: 5 - - - // empty unit list - DWARF_NamesUnit *first = 0; - DWARF_NamesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // *padding* - MemoryConsume(U16, ptr, unit_opl); - - // comp_unit_count - U32 comp_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // local_type_unit_count - U32 local_type_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // foreign_type_unit_count - U32 foreign_type_unit_count = MemoryConsume(U32, ptr, unit_opl); - - // bucket_count - U32 bucket_count = MemoryConsume(U32, ptr, unit_opl); - - // name_count - U32 name_count = MemoryConsume(U32, ptr, unit_opl); - - // abbrev_table_size - U32 abbrev_table_size = MemoryConsume(U32, ptr, unit_opl); - - // augmentation_string_size - U32 augmentation_string_size = MemoryConsume(U32, ptr, unit_opl); - - // augmentation_string - U8 *augmentation_string = ptr; - { - U8 *ptr_raw = ptr + augmentation_string_size; - ptr = ClampTop(ptr_raw, unit_opl); - } - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_NamesUnit *unit = push_array(arena, DWARF_NamesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - unit->comp_unit_count = comp_unit_count; - unit->local_type_unit_count = local_type_unit_count; - unit->foreign_type_unit_count = foreign_type_unit_count; - unit->bucket_count = bucket_count; - unit->name_count = name_count; - unit->abbrev_table_size = abbrev_table_size; - unit->augmentation_string = str8_cstring_capped(augmentation_string, unit_opl); - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_NamesParsed *result = push_array(arena, DWARF_NamesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_ArangesParsed* -dwarf_aranges_from_data(Arena *arena, String8 data){ - // supported version numbers: 2 - - - // empty unit list - DWARF_ArangesUnit *first = 0; - DWARF_ArangesUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // info_off - U64 info_off = 0; - if (is_64bit){ - info_off = MemoryConsume(U64, ptr, unit_opl); - } - else{ - info_off = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size - U8 address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment_selector_size - U8 segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // offset size - U8 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_ArangesUnit *unit = push_array(arena, DWARF_ArangesUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - unit->address_size = address_size; - unit->segment_selector_size = segment_selector_size; - unit->offset_size = offset_size; - unit->info_off = info_off; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_ArangesParsed *result = push_array(arena, DWARF_ArangesParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_LineParsed* -dwarf_line_from_data(Arena *arena, String8 data){ - // supported version numbers: 4, 5 - - - // empty unit list - DWARF_LineUnit *first = 0; - DWARF_LineUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // remember header offset - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // offset size - U8 offset_size = is_64bit?8:4; - - // rest of header depends on version - U8 minimum_instruction_length = 0; - U8 maximum_operations_per_instruction = 0; - U8 default_is_stmt = 0; - S8 line_base = 0; - U8 line_range = 0; - U8 opcode_base = 0; - U8 *standard_opcode_lengths = 0; - // v4 - String8List include_directories = {0}; - DWARF_V4LineFileNamesList file_names = {0}; - // v5 - U8 address_size = 0; - U8 segment_selector_size = 0; - U8 directory_entry_format_count = 0; - DWARF_V5LinePathEntryFormat *directory_entry_format = 0; - U64 directories_count = 0; - U8 file_name_entry_format_count = 0; - DWARF_V5LinePathEntryFormat *file_name_entry_format = 0; - U64 file_names_count = 0; - - switch (version){ - case 4: - { - // header_length - U64 header_length = 0; - if (is_64bit){ - header_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - header_length = MemoryConsume(U32, ptr, unit_opl); - } - - // header opl - U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = ClampTop(header_opl_raw, unit_opl); - - // minimum_instruction_length - minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); - - // maximum_operations_per_instruction - maximum_operations_per_instruction = MemoryConsume(U8, ptr, header_opl); - - // default_is_stmt - default_is_stmt = MemoryConsume(U8, ptr, header_opl); - - // line_base - line_base = MemoryConsume(S8, ptr, header_opl); - - // line_range - line_range = MemoryConsume(U8, ptr, header_opl); - - // opcode_base - opcode_base = MemoryConsume(U8, ptr, header_opl); - - // standard_opcode_lengths - if (opcode_base > 1){ - standard_opcode_lengths = ptr; - ptr += opcode_base - 1; - } - - // include_directories - for (;ptr < header_opl;){ - // null byte ends entries - if (*ptr == 0){ - ptr += 1; - break; - } - - // extract dir range - U8 *dir_first = ptr; - for (;ptr < header_opl && *ptr != 0;) ptr += 1; - U8 *dir_opl = ptr; - if (ptr < header_opl){ - ptr += 1; - } - - // attach dir to list - String8 dir = str8_range(dir_first, dir_opl); - str8_list_push(arena, &include_directories, dir); - } - - // file_names - for (;ptr < header_opl;){ - // null byte ends entries - if (*ptr == 0){ - ptr += 1; - break; - } - - // extract file_name range - U8 *file_name_first = ptr; - for (;ptr < header_opl && *ptr != 0;) ptr += 1; - U8 *file_name_opl = ptr; - if (ptr < header_opl){ - ptr += 1; - } - - // extract include directory index - U64 include_directory_idx = 0; - DWARF_LEB128_DECODE_ADV(U64, include_directory_idx, ptr, header_opl); - - // extract last modified time - U64 last_modified_time = 0; - DWARF_LEB128_DECODE_ADV(U64, last_modified_time, ptr, header_opl); - - // extract file size - U64 file_size = 0; - DWARF_LEB128_DECODE_ADV(U64, file_size, ptr, header_opl); - - // emit file name entry - DWARF_V4LineFileNamesEntry *entry = push_array(arena, DWARF_V4LineFileNamesEntry, 1); - SLLQueuePush(file_names.first, file_names.last, entry); - file_names.count += 1; - entry->file_name = str8_range(file_name_first, file_name_opl); - entry->include_directory_idx = include_directory_idx; - entry->last_modified_time = last_modified_time; - entry->file_size = file_size; - } - - ptr = header_opl; - }break; - - case 5: - { - // address_size - address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment_selector_size - segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // header_length - U64 header_length = 0; - if (is_64bit){ - header_length = MemoryConsume(U64, ptr, unit_opl); - } - else{ - header_length = MemoryConsume(U32, ptr, unit_opl); - } - - // header opl - U8 *header_opl_raw = ptr + header_length; - U8 *header_opl = ClampTop(header_opl_raw, unit_opl); - - // minimum_instruction_length - minimum_instruction_length = MemoryConsume(U8, ptr, header_opl); - - // maximum_operations_per_instruction - maximum_operations_per_instruction = MemoryConsume(U8, ptr, header_opl); - - // default_is_stmt - default_is_stmt = MemoryConsume(U8, ptr, header_opl); - - // line_base - line_base = MemoryConsume(S8, ptr, header_opl); - - // line_range - line_range = MemoryConsume(U8, ptr, header_opl); - - // opcode_base - opcode_base = MemoryConsume(U8, ptr, header_opl); - - // standard_opcode_lengths - if (opcode_base > 1){ - standard_opcode_lengths = ptr; - ptr += opcode_base - 1; - } - - // directory_entry_format_count - directory_entry_format_count = MemoryConsume(U8, ptr, header_opl); - - // directory_entry_format - { - directory_entry_format = push_array(arena, DWARF_V5LinePathEntryFormat, - directory_entry_format_count); - DWARF_V5LinePathEntryFormat *entry = directory_entry_format; - DWARF_V5LinePathEntryFormat *entry_opl = - directory_entry_format + directory_entry_format_count; - for (;entry < entry_opl && ptr < header_opl; entry += 1){ - DWARF_LEB128_DECODE_ADV(U64, entry->content_type, ptr, header_opl); - DWARF_LEB128_DECODE_ADV(U64, entry->form, ptr, header_opl); - } - } - - // directories_count - DWARF_LEB128_DECODE_ADV(U64, directories_count, ptr, header_opl); - - // directories - DWARF_V5Directory *directories = push_array(arena, DWARF_V5Directory, directories_count); - dwarf__line_v5_directories(address_size, offset_size, - directory_entry_format, directory_entry_format_count, - directories, directories_count, - &ptr, header_opl); - - // file_name_entry_format_count - file_name_entry_format_count = MemoryConsume(U8, ptr, header_opl); - - // file_name_entry_format - { - file_name_entry_format = push_array(arena, DWARF_V5LinePathEntryFormat, - file_name_entry_format_count); - DWARF_V5LinePathEntryFormat *entry = file_name_entry_format; - for (;ptr < header_opl; entry += 1){ - DWARF_LEB128_DECODE_ADV(U64, entry->content_type, ptr, header_opl); - DWARF_LEB128_DECODE_ADV(U64, entry->form, ptr, header_opl); - } - } - - // file_names_count - DWARF_LEB128_DECODE_ADV(U64, file_names_count, ptr, header_opl); - - // file_names - DWARF_V5Directory *file_names = push_array(arena, DWARF_V5Directory, file_names_count); - dwarf__line_v5_directories(address_size, offset_size, - directory_entry_format, directory_entry_format_count, - file_names, file_names_count, - &ptr, header_opl); - }break; - } - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit unit - DWARF_LineUnit *unit = push_array(arena, DWARF_LineUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->version = version; - - // advance to end of unit - ptr = unit_opl; - } - - // fill result - DWARF_LineParsed *result = push_array(arena, DWARF_LineParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_MacInfoParsed* -dwarf_mac_info_from_data(Arena *arena, String8 data){ - DWARF_MacInfoParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_MacroParsed* -dwarf_macro_from_data(Arena *arena, String8 data){ - DWARF_MacroParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_FrameParsed* -dwarf_frame_from_data(Arena *arena, String8 data){ - DWARF_FrameParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_RangesParsed* -dwarf_ranges_from_data(Arena *arena, String8 data){ - DWARF_RangesParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_StrOffsetsParsed* -dwarf_str_offsets_from_data(Arena *arena, String8 data){ - DWARF_StrOffsetsParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_AddrParsed* -dwarf_addr_from_data(Arena *arena, String8 data){ - // supported version numbers: 5 - - - // addr unit list - DWARF_AddrUnit *first = 0; - DWARF_AddrUnit *last = 0; - U64 count = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - U64 hdr_off = (ptr - data.str); - - // initial length - U8 *unit_opl = 0; - B32 is_64bit = 0; - dwarf__initial_length(data, &ptr, &unit_opl, &is_64bit); - - // version - U8 version = MemoryConsume(U16, ptr, unit_opl); - - // address size - U8 address_size = MemoryConsume(U8, ptr, unit_opl); - - // segment selector size - U8 segment_selector_size = MemoryConsume(U8, ptr, unit_opl); - - // offset size - U32 offset_size = is_64bit?8:4; - - // unit offsets - U64 base_off = (ptr - data.str); - U64 opl_off = (unit_opl - data.str); - - // emit addr unit - DWARF_AddrUnit *unit = push_array(arena, DWARF_AddrUnit, 1); - SLLQueuePush(first, last, unit); - count += 1; - - unit->hdr_off = hdr_off; - unit->base_off = base_off; - unit->opl_off = opl_off; - - unit->offset_size = offset_size; - unit->dwarf_version = version; - unit->address_size = address_size; - unit->segment_selector_size = segment_selector_size; - - // advance to next unit - ptr = unit_opl; - } - - // fill result - DWARF_AddrParsed *result = push_array(arena, DWARF_AddrParsed, 1); - result->unit_first = first; - result->unit_last = last; - result->unit_count = count; - return(result); -} - -static DWARF_RngListsParsed* -dwarf_rng_lists_from_data(Arena *arena, String8 data){ - DWARF_RngListsParsed *result = 0; - // TODO(allen): - return(result); -} - -static DWARF_LocListsParsed* -dwarf_loc_lists_from_data(Arena *arena, String8 data){ - DWARF_LocListsParsed *result = 0; - // TODO(allen): - return(result); -} - - -// parse helpers - -static void -dwarf__initial_length(String8 data, U8 **ptr_inout, U8 **unit_opl_out, B32 *is_64bit_out){ - U8 *unit_opl = 0; - B32 is_64bit = 0; - - U8 *opl = data.str + data.size; - U8 *ptr = *ptr_inout; - { - U64 length = 0; - U32 m = MemoryConsume(U32, ptr, opl); - if (m == 0xFFFFFFFF){ - is_64bit = 1; - length = MemoryConsume(U64, ptr, opl); - } - else{ - length = ClampTop(m, 0xFFFFFFF0); - } - if (length > 0){ - U64 unit_opl_off_raw = (ptr - data.str) + length; - U64 unit_opl_off = ClampTop(unit_opl_off_raw, data.size); - unit_opl = data.str + unit_opl_off; - } - else{ - unit_opl = ptr; - } - } - - *ptr_inout = ptr; - *unit_opl_out = unit_opl; - *is_64bit_out = is_64bit; -} - -static void -dwarf__line_v5_directories(U64 address_size, U64 offset_size, - DWARF_V5LinePathEntryFormat *format, U64 format_count, - DWARF_V5Directory *directories_out, U64 dir_count, - U8 **ptr_io, U8 *opl){ - - U8 *ptr = *ptr_io; - - DWARF_V5Directory *directory_ptr = directories_out; - for (U32 i = 0; i < dir_count; i += 1, directory_ptr += 1){ - DWARF_V5LinePathEntryFormat *fmt = format; - for (U32 j = 0; j < format_count; j += 1){ - - // form decode - DWARF_FormDecodeRules rules = - dwarf_form_decode_rule(fmt->form, address_size, offset_size); - - // execute decoding - DWARF_FormDecoded decoded = dwarf_form_decode(&rules, &ptr, opl, 0, 0); - - // store to correct field - U64 *target = 0; - switch (fmt->content_type){ - case DWARF_LineEntryFormat_path: - { - if (decoded.dataptr != 0){ - directory_ptr->path_str = str8(decoded.dataptr, decoded.val); - } - else{ - directory_ptr->path_off = decoded.val; - directory_ptr->path_sec_form = fmt->form; - } - }break; - - case DWARF_LineEntryFormat_directory_index: - { - target = &directory_ptr->directory_index; - }goto v5_directory_u64; - - case DWARF_LineEntryFormat_timestamp: - { - target = &directory_ptr->timestamp; - }goto v5_directory_u64; - - case DWARF_LineEntryFormat_size: - { - target = &directory_ptr->size; - }goto v5_directory_u64; - - v5_directory_u64: - { - if (decoded.dataptr != 0){ - U64 size = ClampTop(decoded.val, 8); - MemoryCopy(target, decoded.dataptr, size); - } - else{ - *target = decoded.val; - } - }break; - - case DWARF_LineEntryFormat_MD5: - { - if (decoded.dataptr != 0){ - U64 size = ClampTop(decoded.val, 16); - MemoryCopy(directory_ptr->md5_checksum, decoded.dataptr, size); - } - }break; - } - } - } - - *ptr_io = ptr; -} - - -// debug sections - -static String8 -dwarf_name_from_debug_section(DWARF_Parsed *dwarf, DWARF_SectionCode sec_code){ - String8 result = str8_lit("invalid_debug_section"); - if (sec_code < DWARF_SectionCode_COUNT){ - if (dwarf->debug_section_idx[sec_code] != 0){ - result = dwarf->debug_section_name[sec_code]; - } - } - return(result); -} - - -// abbrev functions - -static DWARF_AbbrevUnit* -dwarf_abbrev_unit_from_offset(DWARF_AbbrevParsed *abbrev, U64 offset){ - DWARF_AbbrevUnit *result = 0; - for (DWARF_AbbrevUnit *unit = abbrev->unit_first; - unit != 0; - unit = unit->next){ - if (unit->offset == offset){ - result = unit; - break; - } - } - return(result); -} - -static DWARF_AbbrevDecl* -dwarf_abbrev_decl_from_code(DWARF_AbbrevUnit *unit, U32 abbrev_code){ - DWARF_AbbrevDecl *result = 0; - for (DWARF_AbbrevDecl *decl = unit->first; - decl != 0; - decl = decl->next){ - if (decl->abbrev_code == abbrev_code){ - result = decl; - break; - } - } - return(result); -} - -// attribute decoding functions - -static DWARF_AttributeClassFlags -dwarf_attribute_class_from_form(DWARF_AttributeForm form){ - DWARF_AttributeClassFlags result = 0; - switch (form){ -#define X(N,C,f) case C: result = DWARF_AttributeClassFlag_##f; break; - DWARF_AttributeFormXList(X) -#undef X - } - return(result); -} - -static DWARF_AttributeClassFlags -dwarf_attribute_class_from_name(DWARF_AttributeName name){ - DWARF_AttributeClassFlags result = 0; - switch (name){ -#define X(N,C,f1,f2,f3,f4) case C: result = 0\ -|DWARF_AttributeClassFlag_##f1\ -|DWARF_AttributeClassFlag_##f2\ -|DWARF_AttributeClassFlag_##f3\ -|DWARF_AttributeClassFlag_##f4\ -;break; - DWARF_AttributeNameXList(X) -#undef X - } - return(result); -} - -// form decoding functions - -static DWARF_FormDecodeRules -dwarf_form_decode_rule(DWARF_AttributeForm form, U64 address_size, U64 offset_size){ - DWARF_FormDecodeRules result = {0}; - switch (form){ - case DWARF_AttributeForm_null: - case DWARF_AttributeForm_indirect:{}break; - - case DWARF_AttributeForm_addr: result.size = address_size; break; - case DWARF_AttributeForm_addrx: result.uleb128 = 1; break; - case DWARF_AttributeForm_addrx1: result.size = 1; break; - case DWARF_AttributeForm_addrx2: result.size = 2; break; - case DWARF_AttributeForm_addrx3: result.size = 3; break; - case DWARF_AttributeForm_addrx4: result.size = 4; break; - - case DWARF_AttributeForm_sec_offset: result.size = offset_size; break; - - case DWARF_AttributeForm_block1: result.size = 1; result.block = 1; break; - case DWARF_AttributeForm_block2: result.size = 2; result.block = 1; break; - case DWARF_AttributeForm_block4: result.size = 4; result.block = 1; break; - case DWARF_AttributeForm_block: result.uleb128 = 1; result.block = 1; break; - - case DWARF_AttributeForm_data1: result.size = 1; break; - case DWARF_AttributeForm_data2: result.size = 2; break; - case DWARF_AttributeForm_data4: result.size = 4; break; - case DWARF_AttributeForm_data8: result.size = 8; break; - case DWARF_AttributeForm_data16: result.size = 16; break; - - case DWARF_AttributeForm_sdata: result.sleb128 = 1; break; - case DWARF_AttributeForm_udata: result.uleb128 = 1; break; - - case DWARF_AttributeForm_implicit_const: result.in_abbrev = 1; break; - - case DWARF_AttributeForm_exprloc: result.uleb128 = 1; result.block = 1; break; - - case DWARF_AttributeForm_flag: result.size = 1; break; - case DWARF_AttributeForm_flag_present: result.auto_1 = 1; break; - - case DWARF_AttributeForm_loclistx: result.uleb128 = 1; break; - case DWARF_AttributeForm_rnglistx: result.uleb128 = 1; break; - - case DWARF_AttributeForm_ref1: result.size = 1; break; - case DWARF_AttributeForm_ref2: result.size = 2; break; - case DWARF_AttributeForm_ref4: result.size = 4; break; - case DWARF_AttributeForm_ref8: result.size = 8; break; - case DWARF_AttributeForm_ref_udata: result.uleb128 = 1; break; - - case DWARF_AttributeForm_ref_addr: result.size = offset_size; break; - - case DWARF_AttributeForm_ref_sig8: result.size = 8; break; - - case DWARF_AttributeForm_ref_sup4: result.size = 4; break; - case DWARF_AttributeForm_ref_sup8: result.size = 8; break; - - case DWARF_AttributeForm_string: result.null_terminated = 1; break; - - case DWARF_AttributeForm_strp: result.size = offset_size; break; - case DWARF_AttributeForm_line_strp: result.size = offset_size; break; - case DWARF_AttributeForm_strp_sup: result.size = offset_size; break; - - case DWARF_AttributeForm_strx: result.uleb128 = 1; break; - case DWARF_AttributeForm_strx1: result.size = 1; break; - case DWARF_AttributeForm_strx2: result.size = 2; break; - case DWARF_AttributeForm_strx3: result.size = 3; break; - case DWARF_AttributeForm_strx4: result.size = 4; break; - } - - return(result); -} - -static DWARF_FormDecoded -dwarf_form_decode(DWARF_FormDecodeRules *rules, U8 **ptr_io, U8 *opl, - DWARF_AbbrevDecl *abbrev_decl, U32 attrib_i){ - - // local copy of ptr - U8 *ptr = *ptr_io; - - // apply rules - U64 val = 0; - U8 *dataptr = 0; - - B32 success = 1; - if (rules->size > 0){ - if (ptr + rules->size <= opl){ - MemoryCopy(&val, ptr, rules->size); - ptr += rules->size; - } - else{ - success = 0; - } - } - else if (rules->uleb128 || rules->sleb128){ - U8 *val_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - if (success){ - if (rules->uleb128){ - val = dwarf_leb128_decode_U64(val_ptr, ptr); - } - else{ - val = (U64)dwarf_leb128_decode_S64(val_ptr, ptr); - } - } - } - else if (rules->in_abbrev){ - if (abbrev_decl != 0){ - if (abbrev_decl->implicit_const != 0){ - val = (U64)abbrev_decl->implicit_const[attrib_i]; - } - } - else{ - success = 0; - } - } - else if (rules->auto_1){ - val = 1; - } - if (rules->block){ - dataptr = ptr; - ptr += val; - } - else if (rules->null_terminated){ - dataptr = ptr; - for (;ptr < opl && *ptr != 0;) ptr += 1; - val = (U64)(ptr - dataptr); - if (ptr < opl){ - ptr += 1; - } - } - - // store out ptr - *ptr_io = ptr; - - // fill result - DWARF_FormDecoded result = {0}; - result.val = val; - result.dataptr = dataptr; - result.error = !success; - return(result); -} - - -// string functions - -static String8 -dwarf_string_from_unit_type(DWARF_UnitType type){ - String8 result = str8_lit("unrecognized_type"); - switch (type){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_UnitTypeXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_tag(DWARF_Tag tag){ - String8 result = str8_lit("unrecognized_tag"); - switch (tag){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_TagXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_attribute_name(DWARF_AttributeName name){ - String8 result = str8_lit("unrecognized_attribute_name"); - switch (name){ -#define X(N,C,f1,f2,f3,f4) case C: result = str8_lit(#N); break; - DWARF_AttributeNameXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_attribute_form(DWARF_AttributeForm form){ - String8 result = str8_lit("unrecognized_attribute_form"); - switch (form){ -#define X(N,C,k) case C: result = str8_lit(#N); break; - DWARF_AttributeFormXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_std_op(DWARF_LineStdOp op){ - String8 result = str8_lit("unrecognized_line_std_op"); - switch (op){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineStdOpXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_ext_op(DWARF_LineExtOp op){ - String8 result = str8_lit("unrecognized_line_ext_op"); - switch (op){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineExtOpXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_line_entry_format(DWARF_LineEntryFormat format){ - String8 result = str8_lit("unrecognized_line_entry_format"); - switch (format){ -#define X(N,C) case C: result = str8_lit(#N); break; - DWARF_LineEntryFormatXList(X) -#undef X - } - return(result); -} - -static String8 -dwarf_string_from_section_code(DWARF_SectionCode sec_code){ - String8 result = str8_lit("unrecognized_section_code"); - switch (sec_code){ - case DWARF_SectionCode_COUNT:{}break; -#define X(Nc,Vf,N0,N1,N2) case DWARF_SectionCode_##Nc: result = str8_lit(#Nc); break; - DWARF_SectionNameXList(X,0,0) -#undef X - } - return(result); -} - - - - - -#if 0 -static DWARF_InfoParsed* -dwarf_info_from_data(Arena *arena, String8 data, DWARF_InfoParams *params, - DWARF_AbbrevParsed *abbrev){ - - // unit index range to extract - U64 unit_idx_min = params->unit_idx_min; - U64 unit_idx_max = params->unit_idx_max; - - // empty unit list - DWARF_InfoUnit *unit_first = 0; - DWARF_InfoUnit *unit_last = 0; - U64 unit_count = 0; - B32 decoding_error = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // early escape on unit idx - if (unit_idx > unit_idx_max){ - break; - } - - // determine whether to full parse this unit - B32 full_parse = (unit_idx_min <= unit_idx); - - // header fields - U8 *unit_opl = 0; - B32 is_64bit = 0; - U16 version = 0; - U64 abbrev_offset = 0; - U32 address_size = 0; - DWARF_UnitType unit_type = DWARF_UnitType_null; - U64 unit_dwo_id = 0; - U64 unit_type_signature = 0; - U64 unit_type_offset = 0; - - // initial length - dwarf__initial_length(&ptr, opl, &unit_opl, &is_64bit); - - // if this is not a full parse we may use - // unit_opl to skip to the next unit now - if (full_parse){ - - // version (part of header) - version = MemoryConsume(U16, ptr, unit_opl); - - // rest of header depends on version - switch (version){ - case 4: - { - // abbrev_offset (part of header) - if (is_64bit){ - abbrev_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_offset = MemoryConsume(U32, ptr, unit_opl); - } - - // address_size (part of header) - address_size = MemoryConsume(U8, ptr, unit_opl); - }break; - - case 5: - { - // unit_type (part of header) - unit_type = (DWARF_UnitType)MemoryConsume(U8, ptr, unit_opl); - - // address_size (part of header) - address_size = MemoryConsume(U8, ptr, unit_opl); - - // abbrev_offset (part of header) - if (is_64bit){ - abbrev_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - abbrev_offset = MemoryConsume(U32, ptr, unit_opl); - } - - // rest of header depends on unit_type - switch (unit_type){ - case DWARF_UnitType_skeleton: - case DWARF_UnitType_split_compile: - { - unit_dwo_id = MemoryConsume(U64, ptr, unit_opl); - }break; - case DWARF_UnitType_type: - case DWARF_UnitType_split_type: - { - unit_type_signature = MemoryConsume(U64, ptr, unit_opl); - if (is_64bit){ - unit_type_offset = MemoryConsume(U64, ptr, unit_opl); - } - else{ - unit_type_offset = MemoryConsume(U32, ptr, unit_opl); - } - }break; - } - }break; - } - - // offset size - U32 offset_size = is_64bit?8:4; - - // find matching abbrev unit - DWARF_AbbrevUnit *abbrev_unit = dwarf_abbrev_unit_from_offset(abbrev, abbrev_offset); - if (abbrev_unit == 0){ - // TODO: preserve error info - decoding_error = 1; - } - - // consume info entries - DWARF_InfoEntry *entry_root = 0; - U64 entry_count = 0; - - DWARF_InfoEntry *entry_consptr = 0; - if (abbrev_unit != 0){ - for (;ptr < unit_opl;){ - B32 success = 1; - - // mark beginning of entry - U8 *entry_start_ptr = ptr; - - // extract abbrev code - U8 *abbrev_code_ptr = ptr; - DWARF_LEB128_ADV(ptr, unit_opl, success); - if (!success){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - - U32 abbrev_code = dwarf_leb128_decode_U32(abbrev_code_ptr, ptr); - - // null abbrev code means pop - if (abbrev_code == 0){ - if (entry_consptr == 0){ - goto exit_unit_loop; - } - else{ - entry_consptr = entry_consptr->parent; - goto skip_entry; - } - } - - // get abbrev decl - DWARF_AbbrevDecl *abbrev_decl = dwarf_abbrev_decl_from_code(abbrev_unit, abbrev_code); - if (abbrev_decl == 0){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - - // allocate entry - U32 attrib_count = abbrev_decl->attrib_count; - DWARF_InfoEntry *entry = push_array(arena, DWARF_InfoEntry, 1); - DWARF_InfoAttribVal *attrib_vals = - push_array_no_zero(arena, DWARF_InfoAttribVal, attrib_count); - - // save entry offset - entry->info_offset = (U64)(entry_start_ptr - data.str); - - // set root at beginning - if (entry_root == 0){ - entry_root = entry; - } - - // attribute loop - DWARF_AbbrevAttribSpec *attrib_spec = abbrev_decl->attrib_specs; - DWARF_InfoAttribVal *attrib_val = attrib_vals; - for (U32 i = 0; i < attrib_count; i += 1, attrib_spec += 1, attrib_val += 1){ - - // determine decoding rules - U32 size = 0; - B8 uleb128 = 0; - B8 sleb128 = 0; - B8 in_abbrev = 0; - B8 auto_1 = 0; - B8 block = 0; - B8 null_terminated = 0; - { - DWARF_AttributeForm form = attrib_spec->form; - switch (form){ - case DWARF_AttributeForm_addr: size = address_size; break; - case DWARF_AttributeForm_addrx: uleb128 = 1; break; - case DWARF_AttributeForm_addrx1: size = 1; break; - case DWARF_AttributeForm_addrx2: size = 2; break; - case DWARF_AttributeForm_addrx3: size = 3; break; - case DWARF_AttributeForm_addrx4: size = 4; break; - - case DWARF_AttributeForm_sec_offset: size = offset_size; break; - - case DWARF_AttributeForm_block1: size = 1; block = 1; break; - case DWARF_AttributeForm_block2: size = 2; block = 1; break; - case DWARF_AttributeForm_block4: size = 4; block = 1; break; - case DWARF_AttributeForm_block: uleb128 = 1; block = 1; break; - - case DWARF_AttributeForm_data1: size = 1; break; - case DWARF_AttributeForm_data2: size = 2; break; - case DWARF_AttributeForm_data4: size = 4; break; - case DWARF_AttributeForm_data8: size = 8; break; - case DWARF_AttributeForm_data16: size = 16; break; - - case DWARF_AttributeForm_sdata: sleb128 = 1; break; - case DWARF_AttributeForm_udata: uleb128 = 1; break; - - case DWARF_AttributeForm_implicit_const: in_abbrev = 1; break; - - case DWARF_AttributeForm_exprloc: uleb128 = 1; block = 1; break; - - case DWARF_AttributeForm_flag: size = 1; break; - case DWARF_AttributeForm_flag_present: auto_1 = 1; break; - - case DWARF_AttributeForm_loclistx: uleb128 = 1; break; - case DWARF_AttributeForm_rnglistx: uleb128 = 1; break; - - case DWARF_AttributeForm_ref1: size = 1; break; - case DWARF_AttributeForm_ref2: size = 2; break; - case DWARF_AttributeForm_ref4: size = 4; break; - case DWARF_AttributeForm_ref8: size = 8; break; - case DWARF_AttributeForm_ref_udata: uleb128 = 1; break; - - case DWARF_AttributeForm_ref_addr: size = offset_size; break; - - case DWARF_AttributeForm_ref_sig8: size = 8; break; - - case DWARF_AttributeForm_ref_sup4: size = 4; break; - case DWARF_AttributeForm_ref_sup8: size = 8; break; - - case DWARF_AttributeForm_string: null_terminated = 1; break; - - case DWARF_AttributeForm_strp: size = offset_size; break; - case DWARF_AttributeForm_line_strp: size = offset_size; break; - case DWARF_AttributeForm_strp_sup: size = offset_size; break; - - case DWARF_AttributeForm_strx: uleb128 = 1; break; - case DWARF_AttributeForm_strx1: size = 1; break; - case DWARF_AttributeForm_strx2: size = 2; break; - case DWARF_AttributeForm_strx3: size = 3; break; - case DWARF_AttributeForm_strx4: size = 4; break; - } - } - - // execute decoding rules - U64 val = 0; - U8 *dataptr = 0; - { - if (size > 0){ - if (ptr + size <= unit_opl){ - MemoryCopy(&val, ptr, size); - ptr += size; - } - else{ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - } - else if (uleb128 || sleb128){ - U8 *val_ptr = ptr; - DWARF_LEB128_ADV(ptr, unit_opl, success); - if (!success){ - // TODO: preserve error info - decoding_error = 1; - goto exit_unit_loop; - } - else{ - if (uleb128){ - val = dwarf_leb128_decode_U64(val_ptr, ptr); - } - else{ - val = (U64)dwarf_leb128_decode_S64(val_ptr, ptr); - } - } - } - else if (in_abbrev){ - if (abbrev_decl->implicit_const != 0){ - val = (U64)abbrev_decl->implicit_const[i]; - } - } - else if (auto_1){ - val = 1; - } - if (block){ - dataptr = ptr; - ptr += val; - } - else if (null_terminated){ - dataptr = ptr; - for (;ptr < unit_opl && *ptr != 0;) ptr += 1; - val = (U64)(ptr - dataptr); - } - } - - // save attribute - attrib_val->val = val; - attrib_val->dataptr = dataptr; - } - - // emit entry - if (entry_consptr != 0){ - SLLQueuePush_N(entry_consptr->first_child, entry_consptr->last_child, - entry, next_sibling); - entry_consptr->child_count += 1; - entry->parent = entry_consptr; - } - entry_count += 1; - entry->abbrev_decl = abbrev_decl; - entry->attrib_vals = attrib_vals; - - // move consptr down if has children - if (abbrev_decl->has_children){ - entry_consptr = entry; - } - - skip_entry:; - } - } - exit_unit_loop:; - - // TODO: notice errors, emit them, and exit loop here - if (decoding_error){ - break; - } - - // extract root attributes - U64 language = 0; - U64 str_offsets_base = 0; - U64 line_info_offset = 0; - U64 vbase = 0; - U64 addr_base = 0; - U64 rnglists_base = 0; - U64 loclists_base = 0; - if (entry_root != 0){ - - // pull out attributes - DWARF_AbbrevDecl *root_abbrev_decl = entry_root->abbrev_decl; - DWARF_AbbrevAttribSpec *attrib_specs = root_abbrev_decl->attrib_specs; - DWARF_InfoAttribVal *attrib_vals = entry_root->attrib_vals; - U32 attrib_count = root_abbrev_decl->attrib_count; - - // examine each attribute - DWARF_AbbrevAttribSpec *attrib_spec = attrib_specs; - DWARF_InfoAttribVal *attrib_val = attrib_vals; - for (U32 i = 0; i < attrib_count; i += 1, attrib_spec += 1, attrib_val += 1){ - - // determine if there is a root attribute to extract here - U64 *target_u64 = 0; - switch (attrib_spec->name){ - case DWARF_AttributeName_language: target_u64 = &language; break; - case DWARF_AttributeName_str_offsets_base: target_u64 = &str_offsets_base; break; - case DWARF_AttributeName_stmt_list: target_u64 = &line_info_offset; break; - case DWARF_AttributeName_low_pc: target_u64 = &vbase; break; - case DWARF_AttributeName_addr_base: target_u64 = &addr_base; break; - case DWARF_AttributeName_rnglists_base: target_u64 = &rnglists_base; break; - case DWARF_AttributeName_loclists_base: target_u64 = &loclists_base; break; - } - - // set target from attrib value - if (target_u64 != 0){ - *target_u64 = attrib_val->val; - } - } - } - - // allocate unit - DWARF_InfoUnit *unit = push_array(arena, DWARF_InfoUnit, 1); - - // fill & emit unit - SLLQueuePush(unit_first, unit_last, unit); - unit_count += 1; - // [header] - unit->dwarf_version = version; - unit->offset_size = offset_size; - unit->address_size = address_size; - // [root attributes] - unit->language = (DWARF_Language)language; - unit->str_offsets_base = str_offsets_base; - unit->line_info_offset = line_info_offset; - unit->vbase = vbase; - unit->addr_base = addr_base; - unit->rnglists_base = rnglists_base; - unit->loclists_base = loclists_base; - // [entries] - unit->entry_root = entry_root; - unit->entry_count = entry_count; - - } - - // set ptr to end of this unit - ptr = unit_opl; - } - - // fill result - DWARF_InfoParsed *result = push_array(arena, DWARF_InfoParsed, 1); - result->unit_first = unit_first; - result->unit_last = unit_last; - result->unit_count = unit_count; - result->decoding_error = decoding_error; - return(result); -} - -static DWARF_AbbrevParsed* -dwarf_abbrev_from_data(Arena *arena, String8 data, DWARF_AbbrevParams *params){ - /* .debug_abbrev - ** Layout - ** List(Tag) - ** Tag = { id:ULEB128, tag:ULEB128, has_children:B8, ListNullTerminated(Attribute) } - ** Attribute = { name:ULEB128, form:ULEB128, (val:SLEB128)? } - */ - - // unit index range to extract - U64 unit_idx_min = params->unit_idx_min; - U64 unit_idx_max = params->unit_idx_max; - - // empty unit list - DWARF_AbbrevUnit *unit_first = 0; - DWARF_AbbrevUnit *unit_last = 0; - U64 unit_count = 0; - B32 decoding_error = 0; - - // whole section loop - U64 unit_idx = 0; - U8 *ptr = data.str; - U8 *opl = data.str + data.size; - for (;ptr < opl; unit_idx += 1){ - - // early escape on unit idx - if (unit_idx > unit_idx_max){ - break; - } - - // determine whether to full parse this unit - B32 full_parse = (unit_idx_min <= unit_idx); - - // save unit offset - U64 abbrev_unit_offset = (U64)(ptr - data.str); - - // allocate unit - DWARF_AbbrevUnit *unit = push_array(arena, DWARF_AbbrevUnit, 1); - - // empty abbrev list - DWARF_AbbrevDecl *abbrev_first = 0; - DWARF_AbbrevDecl *abbrev_last = 0; - U64 abbrev_count = 0; - - // abbrev decl loop - for (;ptr < opl;){ - B32 success = 1; - - // mark abbrev_code field - U8 *abbrev_code_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - - // null abbrev code means end of unit - if (success && *abbrev_code_ptr == 0){ - break; - } - - // mark tag - U8 *tag_ptr = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - U8 *end_tag_ptr = ptr; - - // extract has_children - B8 has_children = 0; - if (ptr < opl){ - has_children = *ptr; - ptr += 1; - } - else{ - success = 0; - } - - // count attributes - U8 *attrib_start_ptr = ptr; - U32 attrib_count = 0; - B32 has_implicit_const = 0; - if (success){ - for (;;){ - // decode normal attribute layout - U8 *attrib_name = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - U8 *attrib_form = ptr; - DWARF_LEB128_ADV(ptr, opl, success); - - // handle special case implicit_const - if (success && *attrib_form == (U8)DWARF_AttributeForm_implicit_const){ - DWARF_LEB128_ADV(ptr, opl, success); - has_implicit_const = 1; - } - - // termination conditions - if (ptr == opl || - (*attrib_name == 0 && *attrib_form == 0)){ - break; - } - - // increment - attrib_count += 1; - } - } - - // build the abbreviation declaration - if (full_parse && success){ - - // allocate abbrev - DWARF_AbbrevDecl *abbrev = push_array(arena, DWARF_AbbrevDecl, 1); - DWARF_AbbrevAttribSpec *attribs = - push_array_no_zero(arena, DWARF_AbbrevAttribSpec, attrib_count); - U64 *implicit_const = 0; - if (has_implicit_const){ - implicit_const = push_array(arena, U64, attrib_count); - } - - // extract abbrev fields - U32 abbrev_code = dwarf_leb128_decode_U32(abbrev_code_ptr, tag_ptr); - U32 tag = dwarf_leb128_decode_U32(tag_ptr, end_tag_ptr); - - U8 *attrib_ptr = attrib_start_ptr; - DWARF_AbbrevAttribSpec *attrib = attribs; - for (U32 i = 0; i < attrib_count; i += 1, attrib += 1){ - // mark attribute fields - U8 *attrib_name = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - U8 *attrib_form = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - - // extract attribute fields - U32 name = dwarf_leb128_decode_U32(attrib_name, attrib_form); - U32 form = dwarf_leb128_decode_U32(attrib_form, attrib_ptr); - - // fill attribute spec - attrib->name = (DWARF_AttributeName)name; - attrib->form = (DWARF_AttributeForm)form; - - // handle special case implicit_const - if (form == DWARF_AttributeForm_implicit_const){ - U8 *attrib_value = attrib_ptr; - DWARF_LEB128_ADV_NOCAP(attrib_ptr); - S64 value = dwarf_leb128_decode_S64(attrib_form, attrib_ptr); - implicit_const[i] = value; - } - } - - // fill abbreviation - SLLQueuePush(abbrev_first, abbrev_last, abbrev); - abbrev_count += 1; - abbrev->abbrev_code = abbrev_code; - abbrev->tag = (DWARF_Tag)tag; - abbrev->has_children = has_children; - abbrev->attrib_count = attrib_count; - abbrev->attrib_specs = attribs; - abbrev->implicit_const = implicit_const; - } - - // handle failure - if (!success){ - // TODO: emit error message - decoding_error = 1; - goto done_parse; - } - } - - // fill unit - if (full_parse){ - SLLQueuePush(unit_first, unit_last, unit); - unit_count += 1; - unit->offset = abbrev_unit_offset; - unit->first = abbrev_first; - unit->last = abbrev_last; - unit->count = abbrev_count; - } - } - - done_parse:; - - // fill result - DWARF_AbbrevParsed *result = push_array(arena, DWARF_AbbrevParsed, 1); - result->unit_first = unit_first; - result->unit_last = unit_last; - result->unit_count = unit_count; - result->decoding_error = decoding_error; - return(result); -} -#endif diff --git a/src/rdi_from_dwarf/rdi_dwarf.h b/src/rdi_from_dwarf/rdi_dwarf.h deleted file mode 100644 index 405cd817..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf.h +++ /dev/null @@ -1,1493 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_DWARF_H -#define RDI_DWARF_H - -// https://dwarfstd.org/doc/DWARF4.pdf -// https://dwarfstd.org/doc/DWARF5.pdf - -// TODO(allen): -// [ ] function to parse info just for unit headers & root attributes -// [ ] put together unit info from all sections in one structure -// [ ] actually check version numbers in unit header parsers - -#pragma pack(push,1) - -//////////////////////////////// -//~ Dwarf Format Code X Lists - -// unit type X(name, code) -#define DWARF_UnitTypeXList(X)\ -X(null, 0x00)\ -X(compile, 0x01)\ -X(type, 0x02)\ -X(partial, 0x03)\ -X(skeleton, 0x04)\ -X(split_compile, 0x05)\ -X(split_type, 0x06)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_UnitType{ -#define X(N,C) DWARF_UnitType_##N = C, - DWARF_UnitTypeXList(X) -#undef X -} DWARF_UnitType; - - -// tag X(name, code) -#define DWARF_TagXList(X)\ -X(null, 0x00)\ -X(array_type, 0x01)\ -X(class_type, 0x02)\ -X(entry_point, 0x03)\ -X(enumeration_type, 0x04)\ -X(formal_parameter, 0x05)\ -X(imported_declaration, 0x08)\ -X(label, 0x0a)\ -X(lexical_block, 0x0b)\ -X(member, 0x0d)\ -X(pointer_type, 0x0f)\ -X(reference_type, 0x10)\ -X(compile_unit, 0x11)\ -X(string_type, 0x12)\ -X(structure_type, 0x13)\ -X(subroutine_type, 0x15)\ -X(typedef, 0x16)\ -X(union_type, 0x17)\ -X(unspecified_parameters, 0x18)\ -X(variant, 0x19)\ -X(common_block, 0x1a)\ -X(common_inclusion, 0x1b)\ -X(inheritance, 0x1c)\ -X(inlined_subroutine, 0x1d)\ -X(module, 0x1e)\ -X(ptr_to_member_type, 0x1f)\ -X(set_type, 0x20)\ -X(subrange_type, 0x21)\ -X(with_stmt, 0x22)\ -X(access_declaration, 0x23)\ -X(base_type, 0x24)\ -X(catch_block, 0x25)\ -X(const_type, 0x26)\ -X(constant, 0x27)\ -X(enumerator, 0x28)\ -X(file_type, 0x29)\ -X(friend, 0x2a)\ -X(namelist, 0x2b)\ -X(namelist_item, 0x2c)\ -X(packed_type, 0x2d)\ -X(subprogram, 0x2e)\ -X(template_type_parameter, 0x2f)\ -X(template_value_parameter, 0x30)\ -X(thrown_type, 0x31)\ -X(try_block, 0x32)\ -X(variant_part, 0x33)\ -X(variable, 0x34)\ -X(volatile_type, 0x35)\ -X(dwarf_procedure, 0x36)\ -X(restrict_type, 0x37)\ -X(interface_type, 0x38)\ -X(namespace, 0x39)\ -X(imported_module, 0x3a)\ -X(unspecified_type, 0x3b)\ -X(partial_unit, 0x3c)\ -X(imported_unit, 0x3d)\ -X(condition, 0x3f)\ -X(shared_type, 0x40)\ -X(type_unit, 0x41)\ -X(rvalue_reference_type, 0x42)\ -X(template_alias, 0x43)\ -X(coarray_type, 0x44)\ -X(generic_subrange, 0x45)\ -X(dynamic_type, 0x46)\ -X(atomic_type, 0x47)\ -X(call_site, 0x48)\ -X(call_site_parameter, 0x49)\ -X(skeleton_unit, 0x4a)\ -X(immutable_type, 0x4b)\ -X(lo_user, 0x4080)\ -X(hi_user, 0xffff) - -typedef enum DWARF_Tag{ -#define X(N,C) DWARF_Tag_##N = C, - DWARF_TagXList(X) -#undef X -} DWARF_Tag; - - -// attribute classes: X(name,code) -#define DWARF_AttributeClassXList(X)\ -X(address, 0)\ -X(addrptr, 1)\ -X(block, 2)\ -X(constant, 3)\ -X(exprloc, 4)\ -X(flag, 5)\ -X(lineptr, 6)\ -X(loclist, 7)\ -X(loclistsptr, 8)\ -X(macptr, 9)\ -X(reference, 10)\ -X(rnglist, 11)\ -X(rnglistsptr, 12)\ -X(string, 13)\ -X(stroffsetsptr, 14) - -typedef U32 DWARF_AttributeClassFlags; -enum{ -#define X(N,C) DWARF_AttributeClassFlag_##N = (1 << C), - DWARF_AttributeClassXList(X) -#undef X - - DWARF_AttributeClassFlag_0 = 0, - DWARF_AttributeClassFlag_specialcase = ~0, - DWARF_AttributeClassFlag_sec_offset_classes = - (DWARF_AttributeClassFlag_addrptr | - DWARF_AttributeClassFlag_lineptr | - DWARF_AttributeClassFlag_loclist | - DWARF_AttributeClassFlag_loclistsptr | - DWARF_AttributeClassFlag_macptr | - DWARF_AttributeClassFlag_rnglist | - DWARF_AttributeClassFlag_rnglistsptr | - DWARF_AttributeClassFlag_stroffsetsptr | - 0), - -}; - - -// attribute name: X(name, code, classflag1, classflag2, classflag3, classflag4) -#define DWARF_AttributeNameXList(X)\ -X(null, 0x00, 0, 0, 0, 0)\ -X(sibling, 0x01, reference, 0, 0, 0)\ -X(location, 0x02, exprloc, loclist, 0, 0)\ -X(name, 0x03, string, 0, 0, 0)\ -X(ordering, 0x09, constant, 0, 0, 0)\ -X(byte_size, 0x0b, constant, exprloc, reference, 0)\ -X(bit_size, 0x0d, constant, exprloc, reference, 0)\ -X(stmt_list, 0x10, lineptr, 0, 0, 0)\ -X(low_pc, 0x11, address, 0, 0, 0)\ -X(high_pc, 0x12, address, constant, 0, 0)\ -X(language, 0x13, constant, 0, 0, 0)\ -X(discr, 0x15, reference, 0, 0, 0)\ -X(discr_value, 0x16, constant, 0, 0, 0)\ -X(visibility, 0x17, constant, 0, 0, 0)\ -X(import, 0x18, reference, 0, 0, 0)\ -X(string_length, 0x19, exprloc, loclist, reference, 0)\ -X(common_reference, 0x1a, reference, 0, 0, 0)\ -X(comp_dir, 0x1b, string, 0, 0, 0)\ -X(const_value, 0x1c, block, constant, string, 0)\ -X(containing_type, 0x1d, reference, 0, 0, 0)\ -X(default_value, 0x1e, constant, reference, flag, 0)\ -X(inline, 0x20, constant, 0, 0, 0)\ -X(is_optional, 0x21, flag, 0, 0, 0)\ -X(lower_bound, 0x22, constant, exprloc, reference, 0)\ -X(producer, 0x25, string, 0, 0, 0)\ -X(prototyped, 0x27, flag, 0, 0, 0)\ -X(return_addr, 0x2a, exprloc, loclist, 0, 0)\ -X(start_scope, 0x2c, constant, rnglist, 0, 0)\ -X(bit_stride, 0x2e, constant, exprloc, reference, 0)\ -X(upper_bound, 0x2f, constant, exprloc, reference, 0)\ -X(abstract_origin, 0x31, reference, 0, 0, 0)\ -X(accessibility, 0x32, constant, 0, 0, 0)\ -X(address_class, 0x33, constant, 0, 0, 0)\ -X(artificial, 0x34, flag, 0, 0, 0)\ -X(base_types, 0x35, reference, 0, 0, 0)\ -X(calling_convention, 0x36, constant, 0, 0, 0)\ -X(count, 0x37, constant, exprloc, reference, 0)\ -X(data_member_location, 0x38, constant, exprloc, loclist, 0)\ -X(decl_column, 0x39, constant, 0, 0, 0)\ -X(decl_file, 0x3a, constant, 0, 0, 0)\ -X(decl_line, 0x3b, constant, 0, 0, 0)\ -X(declaration, 0x3c, flag, 0, 0, 0)\ -X(discr_list, 0x3d, block, 0, 0, 0)\ -X(encoding, 0x3e, constant, 0, 0, 0)\ -X(external, 0x3f, flag, 0, 0, 0)\ -X(frame_base, 0x40, exprloc, loclist, 0, 0)\ -X(friend, 0x41, reference, 0, 0, 0)\ -X(identifier_case, 0x42, constant, 0, 0, 0)\ -X(namelist_item, 0x44, reference, 0, 0, 0)\ -X(priority, 0x45, reference, 0, 0, 0)\ -X(segment, 0x46, exprloc, loclist, 0, 0)\ -X(specification, 0x47, reference, 0, 0, 0)\ -X(static_link, 0x48, exprloc, loclist, 0, 0)\ -X(type, 0x49, reference, 0, 0, 0)\ -X(use_location, 0x4a, exprloc, loclist, 0, 0)\ -X(variable_parameter, 0x4b, flag, 0, 0, 0)\ -X(virtuality, 0x4c, constant, 0, 0, 0)\ -X(vtable_elem_location, 0x4d, exprloc, loclist, 0, 0)\ -X(allocated, 0x4e, constant, exprloc, reference, 0)\ -X(associated, 0x4f, constant, exprloc, reference, 0)\ -X(data_location, 0x50, exprloc, 0, 0, 0)\ -X(byte_stride, 0x51, constant, exprloc, reference, 0)\ -X(entry_pc, 0x52, address, constant, 0, 0)\ -X(use_UTF8, 0x53, flag, 0, 0, 0)\ -X(extension, 0x54, reference, 0, 0, 0)\ -X(ranges, 0x55, rnglist, 0, 0, 0)\ -X(trampoline, 0x56, address, flag, reference, string)\ -X(call_column, 0x57, constant, 0, 0, 0)\ -X(call_file, 0x58, constant, 0, 0, 0)\ -X(call_line, 0x59, constant, 0, 0, 0)\ -X(description, 0x5a, string, 0, 0, 0)\ -X(binary_scale, 0x5b, constant, 0, 0, 0)\ -X(decimal_scale, 0x5c, constant, 0, 0, 0)\ -X(small, 0x5d, reference, 0, 0, 0)\ -X(decimal_sign, 0x5e, constant, 0, 0, 0)\ -X(digit_count, 0x5f, constant, 0, 0, 0)\ -X(picture_string, 0x60, string, 0, 0, 0)\ -X(mutable, 0x61, flag, 0, 0, 0)\ -X(threads_scaled, 0x62, flag, 0, 0, 0)\ -X(explicit, 0x63, flag, 0, 0, 0)\ -X(object_pointer, 0x64, reference, 0, 0, 0)\ -X(endianity, 0x65, constant, 0, 0, 0)\ -X(elemental, 0x66, flag, 0, 0, 0)\ -X(pure, 0x67, flag, 0, 0, 0)\ -X(recursive, 0x68, flag, 0, 0, 0)\ -X(signature, 0x69, reference, 0, 0, 0)\ -X(main_subprogram, 0x6a, flag, 0, 0, 0)\ -X(data_bit_offset, 0x6b, constant, 0, 0, 0)\ -X(const_expr, 0x6c, flag, 0, 0, 0)\ -X(enum_class, 0x6d, flag, 0, 0, 0)\ -X(linkage_name, 0x6e, string, 0, 0, 0)\ -X(string_length_bit_size, 0x6f, constant, 0, 0, 0)\ -X(string_length_byte_size, 0x70, constant, 0, 0, 0)\ -X(rank, 0x71, constant, exprloc, 0, 0)\ -X(str_offsets_base, 0x72, stroffsetsptr, 0, 0, 0)\ -X(addr_base, 0x73, addrptr, 0, 0, 0)\ -X(rnglists_base, 0x74, rnglistsptr, 0, 0, 0)\ -X(dwo_name, 0x76, string, 0, 0, 0)\ -X(reference, 0x77, flag, 0, 0, 0)\ -X(rvalue_reference, 0x78, flag, 0, 0, 0)\ -X(macros, 0x79, macptr, 0, 0, 0)\ -X(call_all_calls, 0x7a, flag, 0, 0, 0)\ -X(call_all_source_calls, 0x7b, flag, 0, 0, 0)\ -X(call_all_tail_calls, 0x7c, flag, 0, 0, 0)\ -X(call_return_pc, 0x7d, address, 0, 0, 0)\ -X(call_value, 0x7e, exprloc, 0, 0, 0)\ -X(call_origin, 0x7f, exprloc, 0, 0, 0)\ -X(call_parameter, 0x80, reference, 0, 0, 0)\ -X(call_pc, 0x81, address, 0, 0, 0)\ -X(call_tail_call, 0x82, flag, 0, 0, 0)\ -X(call_target, 0x83, exprloc, 0, 0, 0)\ -X(call_target_clobbered, 0x84, exprloc, 0, 0, 0)\ -X(call_data_location, 0x85, exprloc, 0, 0, 0)\ -X(call_data_value, 0x86, exprloc, 0, 0, 0)\ -X(noreturn, 0x87, flag, 0, 0, 0)\ -X(alignment, 0x88, constant, 0, 0, 0)\ -X(export_symbols, 0x89, flag, 0, 0, 0)\ -X(deleted, 0x8a, flag, 0, 0, 0)\ -X(defaulted, 0x8b, constant, 0, 0, 0)\ -X(loclists_base, 0x8c, loclistsptr, 0, 0, 0)\ -X(lo_user, 0x2000, 0, 0, 0, 0)\ -X(hi_user, 0x3fff, 0, 0, 0, 0) - -typedef enum DWARF_AttributeName{ -#define X(N,C,f1,f2,f3,f4) DWARF_AttributeName_##N = C, - DWARF_AttributeNameXList(X) -#undef X -} DWARF_AttributeName; - - -// attribute forms: X(name, code, classflag) -#define DWARF_AttributeFormXList(X)\ -X(null, 0x00, 0)\ -X(addr, 0x01, address)\ -X(block2, 0x03, block)\ -X(block4, 0x04, block)\ -X(data2, 0x05, constant)\ -X(data4, 0x06, constant)\ -X(data8, 0x07, constant)\ -X(string, 0x08, string)\ -X(block, 0x09, block)\ -X(block1, 0x0a, block)\ -X(data1, 0x0b, constant)\ -X(flag, 0x0c, flag)\ -X(sdata, 0x0d, constant)\ -X(strp, 0x0e, string)\ -X(udata, 0x0f, constant)\ -X(ref_addr, 0x10, reference)\ -X(ref1, 0x11, reference)\ -X(ref2, 0x12, reference)\ -X(ref4, 0x13, reference)\ -X(ref8, 0x14, reference)\ -X(ref_udata, 0x15, reference)\ -X(indirect, 0x16, specialcase)\ -X(sec_offset, 0x17, sec_offset_classes)\ -X(exprloc, 0x18, exprloc)\ -X(flag_present, 0x19, flag)\ -X(strx, 0x1a, string)\ -X(addrx, 0x1b, address)\ -X(ref_sup4, 0x1c, reference)\ -X(strp_sup, 0x1d, string)\ -X(data16, 0x1e, constant)\ -X(line_strp, 0x1f, string)\ -X(ref_sig8, 0x20, reference)\ -X(implicit_const, 0x21, specialcase)\ -X(loclistx, 0x22, loclist)\ -X(rnglistx, 0x23, rnglist)\ -X(ref_sup8, 0x24, reference)\ -X(strx1, 0x25, string)\ -X(strx2, 0x26, string)\ -X(strx3, 0x27, string)\ -X(strx4, 0x28, string)\ -X(addrx1, 0x29, address)\ -X(addrx2, 0x2a, address)\ -X(addrx3, 0x2b, address)\ -X(addrx4, 0x2c, address) - -typedef enum DWARF_AttributeForm{ -#define X(N,C,f) DWARF_AttributeForm_##N = C, - DWARF_AttributeFormXList(X) -#undef X -} DWARF_AttributeForm; - - -// ops: X(name, code, opnum) -#define DWARF_OpXList(X)\ -X(addr, 0x03, 1)\ -X(deref, 0x06, 0)\ -X(const1u, 0x08, 1)\ -X(const1s, 0x09, 1)\ -X(const2u, 0x0a, 1)\ -X(const2s, 0x0b, 1)\ -X(const4u, 0x0c, 1)\ -X(const4s, 0x0d, 1)\ -X(const8u, 0x0e, 1)\ -X(const8s, 0x0f, 1)\ -X(constu, 0x10, 1)\ -X(consts, 0x11, 1)\ -X(dup, 0x12, 0)\ -X(drop, 0x13, 0)\ -X(over, 0x14, 0)\ -X(pick, 0x15, 1)\ -X(swap, 0x16, 0)\ -X(rot, 0x17, 0)\ -X(xderef, 0x18, 0)\ -X(abs, 0x19, 0)\ -X(and, 0x1a, 0)\ -X(div, 0x1b, 0)\ -X(minus, 0x1c, 0)\ -X(mod, 0x1d, 0)\ -X(mul, 0x1e, 0)\ -X(neg, 0x1f, 0)\ -X(not, 0x20, 0)\ -X(or, 0x21, 0)\ -X(plus, 0x22, 0)\ -X(plus_uconst, 0x23, 1)\ -X(shl, 0x24, 0)\ -X(shr, 0x25, 0)\ -X(shra, 0x26, 0)\ -X(xor, 0x27, 0)\ -X(bra, 0x28, 1)\ -X(eq, 0x29, 0)\ -X(ge, 0x2a, 0)\ -X(gt, 0x2b, 0)\ -X(le, 0x2c, 0)\ -X(lt, 0x2d, 0)\ -X(ne, 0x2e, 0)\ -X(skip, 0x2f, 1)\ -X(lit0, 0x30, 0)\ -X(lit1, 0x31, 0)\ -X(lit31, 0x4f, 0)\ -X(reg0, 0x50, 0)\ -X(reg1, 0x51, 0)\ -X(reg31, 0x6f, 0)\ -X(breg0, 0x70, 1)\ -X(breg1, 0x71, 1)\ -X(breg31, 0x8f, 1)\ -X(regx, 0x90, 1)\ -X(fbreg, 0x91, 1)\ -X(bregx, 0x92, 2)\ -X(piece, 0x93, 1)\ -X(deref_size, 0x94, 1)\ -X(xderef_size, 0x95, 1)\ -X(nop, 0x96, 0)\ -X(push_object_address, 0x97, 0)\ -X(call2, 0x98, 1)\ -X(call4, 0x99, 1)\ -X(call_ref, 0x9a, 1)\ -X(form_tls_address, 0x9b, 0)\ -X(call_frame_cfa, 0x9c, 0)\ -X(bit_piece, 0x9d, 2)\ -X(implicit_value, 0x9e, 2)\ -X(stack_value, 0x9f, 0)\ -X(implicit_pointer, 0xa0, 2)\ -X(addrx, 0xa1, 1)\ -X(constx, 0xa2, 1)\ -X(entry_value, 0xa3, 2)\ -X(const_type, 0xa4, 3)\ -X(regval_type, 0xa5, 2)\ -X(deref_type, 0xa6, 2)\ -X(xderef_type, 0xa7, 2)\ -X(convert, 0xa8, 1)\ -X(reinterpret, 0xa9, 1)\ -X(lo_user, 0xe0, 0)\ -X(hi_user, 0xff, 0) - -typedef enum DWARF_Op{ -#define X(N,C,k) DWARF_Op_##N = C, - DWARF_OpXList(X) -#undef X -} DWARF_Op; - - -// location list entry: X(name, code) -#define DWARF_LocationListEntryXList(X)\ -X(end_of_list, 0x00)\ -X(base_addressx, 0x01)\ -X(startx_endx, 0x02)\ -X(startx_length, 0x03)\ -X(offset_pair, 0x04)\ -X(default_location, 0x05)\ -X(base_address, 0x06)\ -X(start_end, 0x07)\ -X(start_length, 0x08) - -typedef enum DWARF_LocationListEntry{ -#define X(N,C) DWARF_LocationListEntry_##N = C, - DWARF_LocationListEntryXList(X) -#undef X -} DWARF_LocationListEntry; - - -// base type: X(name, code) -#define DWARF_BaseTypeXList(X)\ -X(address, 0x01)\ -X(boolean, 0x02)\ -X(complex_float, 0x03)\ -X(float, 0x04)\ -X(signed, 0x05)\ -X(signed_char, 0x06)\ -X(unsigned, 0x07)\ -X(unsigned_char, 0x08)\ -X(imaginary_float, 0x09)\ -X(packed_decimal, 0x0a)\ -X(numeric_string, 0x0b)\ -X(edited, 0x0c)\ -X(signed_fixed, 0x0d)\ -X(unsigned_fixed, 0x0e)\ -X(decimal_float, 0x0f)\ -X(UTF, 0x10)\ -X(UCS, 0x11)\ -X(ASCII, 0x12)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_BaseType{ -#define X(N,C) DWARF_BaseType_##N = C, - DWARF_BaseTypeXList(X) -#undef X -} DWARF_BaseType; - - -// decimal sign: X(name, code) -#define DWARF_DecimalSignXList(X)\ -X(unsigned, 0x01)\ -X(leading_overpunch, 0x02)\ -X(trailing_overpunch, 0x03)\ -X(leading_separate, 0x04)\ -X(trailing_separate, 0x05) - -typedef enum DWARF_DecimalSign{ -#define X(N,C) DWARF_DecimalSign_##N = C, - DWARF_DecimalSignXList(X) -#undef X -} DWARF_DecimalSign; - - -// endianity: X(name, code) -#define DWARF_EndianityXList(X)\ -X(default, 0x00)\ -X(big, 0x01)\ -X(little, 0x02)\ -X(lo_user, 0x40)\ -X(hi_user, 0xff) - -typedef enum DWARF_Endianity{ -#define X(N,C) DWARF_Endianity_##N = C, - DWARF_EndianityXList(X) -#undef X -} DWARF_Endianity; - - -// access: X(name, code) -#define DWARF_AccessXList(X)\ -X(public, 0x01)\ -X(protected, 0x02)\ -X(private, 0x03) - -typedef enum DWARF_Access{ -#define X(N,C) DWARF_Access_##N = C, - DWARF_AccessXList(X) -#undef X -} DWARF_Access; - - -// visibility: X(name, code) -#define DWARF_VisibilityXList(X)\ -X(local, 0x01)\ -X(exported, 0x02)\ -X(qualified, 0x03) - -typedef enum DWARF_Visibility{ -#define X(N,C) DWARF_Visibility_##N = C, - DWARF_VisibilityXList(X) -#undef X -} DWARF_Visibility; - - -// virtuality: X(name, code) -#define DWARF_VirtualityXList(X)\ -X(none, 0x00)\ -X(virtual, 0x01)\ -X(pure_virtual, 0x02) - -typedef enum DWARF_Virtuality{ -#define X(N,C) DWARF_Virtuality_##N = C, - DWARF_VirtualityXList(X) -#undef X -} DWARF_Virtuality; - - -// language: X(name, code, deflowerbound) -#define DWARF_LanguageXList(X)\ -X(C89, 0x0001, 0)\ -X(C, 0x0002, 0)\ -X(Ada83, 0x0003, 1)\ -X(C_plus_plus, 0x0004, 0)\ -X(Cobol74, 0x0005, 1)\ -X(Cobol85, 0x0006, 1)\ -X(Fortran77, 0x0007, 1)\ -X(Fortran90, 0x0008, 1)\ -X(Pascal83, 0x0009, 1)\ -X(Modula2, 0x000a, 1)\ -X(Java, 0x000b, 0)\ -X(C99, 0x000c, 0)\ -X(Ada95, 0x000d, 1)\ -X(Fortran95, 0x000e, 1)\ -X(PLI, 0x000f, 1)\ -X(ObjC, 0x0010, 0)\ -X(ObjC_plus_plus, 0x0011, 0)\ -X(UPC, 0x0012, 0)\ -X(D, 0x0013, 0)\ -X(Python, 0x0014, 0)\ -X(OpenCL, 0x0015, 0)\ -X(Go, 0x0016, 0)\ -X(Modula3, 0x0017, 1)\ -X(Haskell, 0x0018, 0)\ -X(C_plus_plus_03, 0x0019, 0)\ -X(C_plus_plus_11, 0x001a, 0)\ -X(OCaml, 0x001b, 0)\ -X(Rust, 0x001c, 0)\ -X(C11, 0x001d, 0)\ -X(Swift, 0x001e, 0)\ -X(Julia, 0x001f, 1)\ -X(Dylan, 0x0020, 0)\ -X(C_plus_plus_14, 0x0021, 0)\ -X(Fortran03, 0x0022, 1)\ -X(Fortran08, 0x0023, 1)\ -X(RenderScript, 0x0024, 0)\ -X(BLISS, 0x0025, 0)\ -X(lo_user, 0x8000, 0)\ -X(hi_user, 0xffff, 0) - -typedef enum DWARF_Language{ -#define X(N,C,k) DWARF_Language_##N = C, - DWARF_LanguageXList(X) -#undef X -} DWARF_Language; - - -// identifier case: X(name, code) -#define DWARF_IdentifierCaseXList(X)\ -X(case_sensitive, 0x00)\ -X(up_case, 0x01)\ -X(down_case, 0x02)\ -X(case_insensitive, 0x03) - -typedef enum DWARF_IdentifierCase{ -#define X(N,C) DWARF_IdentifierCase_##N = C, - DWARF_IdentifierCaseXList(X) -#undef X -} DWARF_IdentifierCase; - - -// calling convention: X(name, code) -#define DWARF_CallingConventionXList(X)\ -X(normal, 0x01)\ -X(program, 0x02)\ -X(nocall, 0x03)\ -X(pass_by_reference, 0x04)\ -X(pass_by_value, 0x05)\ -X(lo_user, 0x40)\ -X(hi_user, 0xff) - -typedef enum DWARF_CallingConvention{ -#define X(N,C) DWARF_CallingConvention_##N = C, - DWARF_CallingConventionXList(X) -#undef X -} DWARF_CallingConvention; - - -// inline: X(name, code) -#define DWARF_InlineXList(X)\ -X(not_inlined, 0x00)\ -X(inlined, 0x01)\ -X(declared_not_inlined, 0x02)\ -X(declared_inlined, 0x03) - -typedef enum DWARF_Inline{ -#define X(N,C) DWARF_Inline_##N = C, - DWARF_InlineXList(X) -#undef X -} DWARF_Inline; - - -// array ordering: X(name, code) -#define DWARF_ArrayOrderingXList(X)\ -X(row_major, 0x00)\ -X(col_major, 0x01) - -typedef enum DWARF_ArrayOrdering{ -#define X(N,C) DWARF_ArrayOrdering_##N = C, - DWARF_ArrayOrderingXList(X) -#undef X -} DWARF_ArrayOrdering; - - -// discriminant: X(name, code) -#define DWARF_DiscriminantXList(X)\ -X(label, 0x00)\ -X(range, 0x01) - -typedef enum DWARF_Discriminant{ -#define X(N,C) DWARF_Discriminant_##N = C, - DWARF_DiscriminantXList(X) -#undef X -} DWARF_Discriminant; - - -// name index: X(name, code) -#define DWARF_NameIndexXList(X)\ -X(compile_unit, 1)\ -X(type_unit, 2)\ -X(die_offset, 3)\ -X(parent, 4)\ -X(type_hash, 5)\ -X(lo_user, 0x2000)\ -X(hi_user, 0x3fff) - -typedef enum DWARF_NameIndex{ -#define X(N,C) DWARF_NameIndex_##N = C, - DWARF_NameIndexXList(X) -#undef X -} DWARF_NameIndex; - - -// defaulted: X(name, code) -#define DWARF_DefaultedXList(X)\ -X(no, 0x00)\ -X(in_class, 0x01)\ -X(out_of_class, 0x02) - -typedef enum DWARF_Defaulted{ -#define X(N,C) DWARF_Defaulted_##N = C, - DWARF_DefaultedXList(X) -#undef X -} DWARF_Defaulted; - -// call frame instruction: X(N, hi2bits, matchlow, low6bits, operand1, operand2) -// "CFA" -#define DWARF_CallFrameInsnXList(X)\ -X(advance_loc, 0x1, 0, 0, NULL, NULL)\ -X(offset, 0x2, 0, 0, ULEB, NULL)\ -X(restore, 0x3, 0, 0, NULL, NULL)\ -X(nop, 0x0, 1, 0, NULL, NULL)\ -X(set_loc, 0x0, 1, 0x01, ADDRESS, NULL)\ -X(advance_loc1, 0x0, 1, 0x02, 1BYTE, NULL)\ -X(advance_loc2, 0x0, 1, 0x03, 2BYTE, NULL)\ -X(advance_loc4, 0x0, 1, 0x04, 4BYTE, NULL)\ -X(offset_extended, 0x0, 1, 0x05, ULEB, ULEB)\ -X(restore_extended, 0x0, 1, 0x06, ULEB, NULL)\ -X(undefined, 0x0, 1, 0x07, ULEB, NULL)\ -X(same_value, 0x0, 1, 0x08, ULEB, NULL)\ -X(register, 0x0, 1, 0x09, ULEB, ULEB)\ -X(remember_state, 0x0, 1, 0x0a, NULL, NULL)\ -X(restore_state, 0x0, 1, 0x0b, NULL, NULL)\ -X(def_cfa, 0x0, 1, 0x0c, ULEB, ULEB)\ -X(def_cfa_register, 0x0, 1, 0x0d, ULEB, NULL)\ -X(def_cfa_offset, 0x0, 1, 0x0e, ULEB, NULL)\ -X(def_cfa_expression,0x0, 1, 0x0f, BLOCK, NULL)\ -X(expression, 0x0, 1, 0x10, ULEB, BLOCK)\ -X(offset_extended_sf,0x0, 1, 0x11, ULEB, SLEB)\ -X(def_cfa_sf, 0x0, 1, 0x12, ULEB, SLEB)\ -X(def_cfa_offset_sf, 0x0, 1, 0x13, SLEB, NULL)\ -X(val_offset, 0x0, 1, 0x14, ULEB, ULEB)\ -X(val_offset_sf, 0x0, 1, 0x15, ULEB, SLEB)\ -X(val_expression, 0x0, 1, 0x16, ULEB, BLOCK)\ -X(lo_user, 0x0, 1, 0x1c, NULL, NULL)\ -X(hi_user, 0x0, 1, 0x3f, NULL, NULL) - -// line number encoding codes -// (DWARF4.pdf + 7.21) (DWARF5.pdf + 7.22) - -// X(name, code) (V4 & V5) -#define DWARF_LineStdOpXList(X) \ -X(copy, 0x01)\ -X(advance_pc, 0x02)\ -X(advance_line, 0x03)\ -X(set_file, 0x04)\ -X(set_column, 0x05)\ -X(negate_stmt, 0x06)\ -X(set_basic_block, 0x07)\ -X(const_add_pc, 0x08)\ -X(fixed_advance_pc, 0x09)\ -X(set_prologue_end, 0x0a)\ -X(set_epilogue_begin, 0x0b)\ -X(set_isa, 0x0c) - -typedef enum DWARF_LineStdOp{ -#define X(N,C) DWARF_LineStdOp_##N = C, - DWARF_LineStdOpXList(X) -#undef X -} DWARF_LineStdOp; - -// X(name, code) (V4 & V5) -#define DWARF_LineExtOpXList(X) \ -X(end_sequence, 0x01)\ -X(set_address, 0x02)\ -X(define_file, 0x03)\ -X(set_discriminator, 0x04)\ -X(lo_user, 0x80)\ -X(hi_user, 0xff) - -typedef enum DWARF_LineExtOp{ -#define X(N,C) DWARF_LineExtOp_##N = C, - DWARF_LineExtOpXList(X) -#undef X -} DWARF_LineExtOp; - -// X(name, code) (V5) -#define DWARF_LineEntryFormatXList(X) \ -X(path, 0x1)\ -X(directory_index, 0x2)\ -X(timestamp, 0x3)\ -X(size, 0x4)\ -X(MD5, 0x5)\ -X(lo_user, 0x2000)\ -X(hi_user, 0x3fff) - -typedef enum DWARF_LineEntryFormat{ -#define X(N,C) DWARF_LineEntryFormat_##N = C, - DWARF_LineEntryFormatXList(X) -#undef X -} DWARF_LineEntryFormat; - -//////////////////////////////// -//~ Dwarf Parser Codes and Data Tables - -#define DWARF_SECTION_NAME_VARIANT_COUNT 3 - -// X(section_code_name, versionflags, section_name0, section_name1, section_name2) -#define DWARF_SectionNameXList(X,V4,V5)\ -X(Null, 0, "", "", "")\ -X(Loc, V4, ".debug_loc", ".debug_loc.dwo", "__debug_loc")\ -X(Str, V4|V5, ".debug_str", ".debug_str.dwo", "__debug_str")\ -X(LineStr, V5, ".debug_line_str", ".debug_line_str.dwo", "__debug_line_str")\ -X(CmpUnitIdx, V5, ".debug_cu_index", ".debug_cu_index.dwo", "__debug_cu_index")\ -X(TypeIdx, V5, ".debug_tu_index", ".debug_tu_index.dwo", "__debug_tu_index")\ -X(Supplement, V5, ".debug_sup", ".debug_sup.dwo", "__debug_sup")\ -X(Info, V4|V5, ".debug_info", ".debug_info.dwo", "__debug_info")\ -X(Abbrev, V4|V5, ".debug_abbrev", ".debug_abbrev.dwo", "__debug_abbrev")\ -X(PubNames, V4, ".debug_pubnames", ".debug_pubnames.dwo", "__debug_pubnames")\ -X(PubTypes, V4, ".debug_pubtypes", ".debug_pubtypes.dwo", "__debug_pubtypes")\ -X(Names, V5, ".debug_names", ".debug_names.dwo", "__debug_names")\ -X(Aranges, V4|V5, ".debug_aranges", ".debug_aranges.dwo", "__debug_aranges")\ -X(Line, V4|V5, ".debug_line", ".debug_line.dwo", "__debug_line")\ -X(MacInfo, V4, ".debug_macinfo", ".debug_macinfo.dwo", "__debug_macinfo")\ -X(Macro, V5, ".debug_macro", ".debug_macro.dwo", "__debug_macro")\ -X(Frame, V4|V5, ".debug_frame", ".debug_frame.dwo", "__debug_frame")\ -X(Ranges, V4, ".debug_ranges", ".debug_ranges.dwo", "__debug_ranges")\ -X(StrOffsets, V5, ".debug_str_offsets", ".debug_str_offsets.dwo", "__debug_str_offsets")\ -X(Addr, V5, ".debug_addr", ".debug_addr.dwo", "__debug_addr")\ -X(RngLists, V5, ".debug_rnglists", ".debug_rnglists.dwo", "__debug_rnglists")\ -X(LocLists, V5, ".debug_loclists", ".debug_loclists.dwo", "__debug_loclists") - - -typedef enum DWARF_SectionCode{ -#define X(c,vf,n0,n1,n2) DWARF_SectionCode_##c, - DWARF_SectionNameXList(X,0,0) -#undef X - DWARF_SectionCode_COUNT -} DWARF_SectionCode; - -typedef struct DWARF_SectionNameRow{ - String8 name[DWARF_SECTION_NAME_VARIANT_COUNT]; -} DWARF_SectionNameRow; - -read_only global DWARF_SectionNameRow dwarf_section_name_table[] = { -#define X(c,vf,n0,n1,n2) \ -{ { str8_lit_comp(n0), str8_lit_comp(n1), str8_lit_comp(n2) } }, - DWARF_SectionNameXList(X,0,0) -#undef X -}; - - -#pragma pack(pop) - - -//////////////////////////////// -//~ Dwarf Parser Types - -typedef struct DWARF_Parsed{ - ELF_Parsed *elf; - U32 debug_section_idx[DWARF_SectionCode_COUNT]; - String8 debug_section_name[DWARF_SectionCode_COUNT]; - String8 debug_data[DWARF_SectionCode_COUNT]; -} DWARF_Parsed; - - -// form decoding - -typedef struct DWARF_FormDecodeRules{ - union{ - // form decode fields - struct{ - U8 size; - B8 uleb128; - B8 sleb128; - B8 in_abbrev; - B8 auto_1; - B8 block; - B8 null_terminated; - }; - - // for alignment and padding to 8 - U64 x; - }; -} DWARF_FormDecodeRules; - -typedef struct DWARF_FormDecoded{ - U64 val; - U8 *dataptr; - B32 error; -} DWARF_FormDecoded; - - -// index section: .debug_cu_index .debug_tu_index -// (DWARF5.pdf + 7.3.5) - -// ** not implemented yet ** - -typedef struct DWARF_IndexParsed{ - U32 dummy; -} DWARF_IndexParsed; - - -// supplementary section: .debug_sup -// (DWARF5.pdf + 7.3.6) - -// ** not implemented yet ** - -typedef struct DWARF_SupParsed{ - U32 dummy; -} DWARF_SupParsed; - - -// info section: .debug_info -// (DWARF4.pdb + 7.5) (DWARF5.pdf + 7.5) - -typedef struct DWARF_InfoAttribVal{ - U64 val; - U8 *dataptr; -} DWARF_InfoAttribVal; - -typedef struct DWARF_InfoEntry{ - struct DWARF_InfoEntry *next_sibling; - struct DWARF_InfoEntry *first_child; - struct DWARF_InfoEntry *last_child; - U64 child_count; - struct DWARF_InfoEntry *parent; - - U64 info_offset; - struct DWARF_AbbrevDecl *abbrev_decl; - DWARF_InfoAttribVal *attrib_vals; -} DWARF_InfoEntry; - -#if 0 -typedef struct DWARF_InfoUnit{ - struct DWARF_InfoUnit *next; - - // header - U32 version; - U32 offset_size; - U32 address_size; - - // root attributes - DWARF_Language language; - U64 line_info_offset; - U64 vbase; - U64 str_offsets_base; - U64 addr_base; - U64 rnglists_base; - U64 loclists_base; - - // info entries - DWARF_InfoEntry *entry_root; - U64 entry_count; -} DWARF_InfoUnit; -#endif - -#if 0 -typedef struct DWARF_InfoParams{ - U64 unit_idx_min; - U64 unit_idx_max; -} DWARF_InfoParams; -#endif - -typedef struct DWARF_InfoUnit{ - struct DWARF_InfoUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 version; - U8 unit_type; // (DWARF_UnitType) - U8 address_size; - U64 abbrev_off; - - union{ - // unit_type: skeleton, split_compile - U64 dwo_id; - // unit_type: type, split_type - struct{ - U64 type_signature; - U64 type_offset; - }; - }; -} DWARF_InfoUnit; - -typedef struct DWARF_InfoParsed{ - DWARF_InfoUnit *unit_first; - DWARF_InfoUnit *unit_last; - U64 unit_count; -} DWARF_InfoParsed; - - -// abbreviations section: .debug_abbrev -// (DWARF4.pdf + 7.5.3) (DWARF5.pdf + 7.5.3) - -typedef struct DWARF_AbbrevAttribSpec{ - DWARF_AttributeName name; - DWARF_AttributeForm form; -} DWARF_AbbrevAttribSpec; - -typedef struct DWARF_AbbrevDecl{ - struct DWARF_AbbrevDecl *next; - U32 abbrev_code; - DWARF_Tag tag; - B8 has_children; - U8 __filler__; - U16 attrib_count; - DWARF_AbbrevAttribSpec *attrib_specs; - S64 *implicit_const; -} DWARF_AbbrevDecl; - -typedef struct DWARF_AbbrevUnit{ - struct DWARF_AbbrevUnit *next; - U64 offset; - DWARF_AbbrevDecl *first; - DWARF_AbbrevDecl *last; - U64 count; -} DWARF_AbbrevUnit; - -#if 0 -typedef struct DWARF_AbbrevParams{ - U64 unit_idx_min; - U64 unit_idx_max; -} DWARF_AbbrevParams; -#endif - -typedef struct DWARF_AbbrevParsed{ - DWARF_AbbrevUnit *unit_first; - DWARF_AbbrevUnit *unit_last; - U64 unit_count; - B32 decoding_error; -} DWARF_AbbrevParsed; - - -// name lookup tables (V4): .debug_pubnames .debug_pubtypes -// (DWARF4.pdf + 7.19) - -typedef struct DWARF_PubNamesUnit{ - struct DWARF_PubNamesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 version; - U64 info_off; - U64 info_length; -} DWARF_PubNamesUnit; - -typedef struct DWARF_PubNamesParsed{ - DWARF_PubNamesUnit *unit_first; - DWARF_PubNamesUnit *unit_last; - U64 unit_count; -} DWARF_PubNamesParsed; - - -// name lookup tables (V5): .debug_names -// (DWARF5.pdf + 6.1.1.4.1 & 7.19) - -typedef struct DWARF_NamesUnit{ - struct DWARF_NamesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - U32 comp_unit_count; - U32 local_type_unit_count; - U32 foreign_type_unit_count; - U32 bucket_count; - U32 name_count; - U32 abbrev_table_size; - String8 augmentation_string; - -} DWARF_NamesUnit; - -typedef struct DWARF_NamesParsed{ - DWARF_NamesUnit *unit_first; - DWARF_NamesUnit *unit_last; - U64 unit_count; -} DWARF_NamesParsed; - - -// address range table: .debug_aranges -// (DWARF4.pdf + 7.20) (DWARF5.pdf + 7.21) - -typedef struct DWARF_ArangesUnit{ - struct DWARF_ArangesUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - U8 address_size; - U8 segment_selector_size; - U8 offset_size; - U64 info_off; -} DWARF_ArangesUnit; - -typedef struct DWARF_ArangesParsed{ - DWARF_ArangesUnit *unit_first; - DWARF_ArangesUnit *unit_last; - U64 unit_count; -} DWARF_ArangesParsed; - - -// line number information: .debug_line -// (DWARF4.pdf + 6.2.4 & 7.21) (DWARF5.pdf + 6.2.4 & 7.22) - -typedef struct DWARF_V4LineFileNamesEntry{ - struct DWARF_V4LineFileNamesEntry *next; - String8 file_name; - U64 include_directory_idx; - U64 last_modified_time; - U64 file_size; -} DWARF_V4LineFileNamesEntry; - -typedef struct DWARF_V4LineFileNamesList{ - DWARF_V4LineFileNamesEntry *first; - DWARF_V4LineFileNamesEntry *last; - U64 count; -} DWARF_V4LineFileNamesList; - -typedef struct DWARF_V5LinePathEntryFormat{ - U32 content_type; /* DWARF_LineEntryFormat */ - U32 form; /* DWARF_AttributeForm */ -} DWARF_V5LinePathEntryFormat; - -typedef struct DWARF_V5Directory{ - String8 path_str; - U64 path_off; - U64 path_sec_form; - U64 directory_index; - U64 timestamp; - U64 size; - U8 md5_checksum[16]; -} DWARF_V5Directory; - -typedef struct DWARF_LineUnit{ - struct DWARF_LineUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 version; - -} DWARF_LineUnit; - -typedef struct DWARF_LineParsed{ - DWARF_LineUnit *unit_first; - DWARF_LineUnit *unit_last; - U64 unit_count; -} DWARF_LineParsed; - - -// macro information (V4): .debug_macinfo -// (DWARF4.pdf + 7.22) - -// ** not implemented yet ** - -typedef struct DWARF_MacInfoParsed{ - U32 dummy; -} DWARF_MacInfoParsed; - - -// macro information (V5): .debug_macro -// (DWARF5.pdf + 7.23) - -// ** not implemented yet ** - -typedef struct DWARF_MacroParsed{ - U32 dummy; -} DWARF_MacroParsed; - - -// call frame information: .debug_frame -// (DWARF4.pdf + 7.23) (DWARF5.pdf + 7.24) - -// ** not implemented yet ** - -typedef struct DWARF_FrameParsed{ - U32 dummy; -} DWARF_FrameParsed; - - -// range lists (V4): .debug_ranges -// (DWARF4.pdf + 7.24) - -// ** not implemented yet ** - -typedef struct DWARF_RangesParsed{ - U32 dummy; -} DWARF_RangesParsed; - - -// string offsets table: .debug_str_offsets -// (DWARF5.pdf + 7.26) - -// ** not implemented yet ** - -typedef struct DWARF_StrOffsetsParsed{ - U32 dummy; -} DWARF_StrOffsetsParsed; - - -// address table: .debug_addr -// (DWARF5.pdf + 7.27) - -typedef struct DWARF_AddrUnit{ - struct DWARF_AddrUnit *next; - - U64 hdr_off; - U64 base_off; - U64 opl_off; - - U8 offset_size; - U8 dwarf_version; - U8 address_size; - U8 segment_selector_size; -} DWARF_AddrUnit; - -typedef struct DWARF_AddrParsed{ - DWARF_AddrUnit *unit_first; - DWARF_AddrUnit *unit_last; - U64 unit_count; -} DWARF_AddrParsed; - - -// range lists (V5): .debug_rnglists -// (DWARF5.pdf + 7.28 & 7.25) - -// ** not implemented yet ** - -typedef struct DWARF_RngListsParsed{ - U32 dummy; -} DWARF_RngListsParsed; - - -// location lists: .debug_loclists -// (DWARF5.pdf + 7.29) - -// ** not implemented yet ** - -typedef struct DWARF_LocListsParsed{ - U32 dummy; -} DWARF_LocListsParsed; - - -//////////////////////////////// -//~ Dwarf Decode Helpers - -#define DWARF_LEB128_ADV(p,o,s) do{ (s)=1; for(;; (p)+=1){\ -if ((p) == (o)) { (s)=0; break; } \ -if (((*(p))&0x80) == 0) { (p)+=1; break; } \ -} }while(0) - -#define DWARF_LEB128_ADV_NOCAP(p) for((p)+=1; ((*(p-1))&0x80) != 0; (p)+=1) - -static U64 dwarf_leb128_decode_U64(U8 *ptr, U8 *opl); -static S64 dwarf_leb128_decode_S64(U8 *ptr, U8 *opl); -static U32 dwarf_leb128_decode_U32(U8 *ptr, U8 *opl); - -#define dwarf_leb128_decode(T,ptr,opl) dwarf_leb128_decode_##T(ptr,opl) - -#define DWARF_LEB128_DECODE_ADV(T,x,p,o) do{ \ -U8 *first__ = (p); B32 success__; \ -DWARF_LEB128_ADV(p,o,success__); \ -if (success__) \ -(x) = dwarf_leb128_decode(T,first__, (p)); \ -}while(0) - - -//////////////////////////////// -//~ allen: ELF/DW Unwind Types -// -// TODO(rjf): OLD TYPES FROM UNWINDER CODE. bucketing this here, and deferring dwarf-based -// unwinding info to future DWARF/linux work. -// -#if 0 - -// * applies to (any X: unwind(ELF/DW, X)) - -// EH: Exception Frames -typedef U8 UNW_DW_EhPtrEnc; -enum{ - UNW_DW_EhPtrEnc_TYPE_MASK = 0x0F, - UNW_DW_EhPtrEnc_PTR = 0x00, // Pointer sized unsigned value - UNW_DW_EhPtrEnc_ULEB128 = 0x01, // Unsigned LE base-128 value - UNW_DW_EhPtrEnc_UDATA2 = 0x02, // Unsigned 16-bit value - UNW_DW_EhPtrEnc_UDATA4 = 0x03, // Unsigned 32-bit value - UNW_DW_EhPtrEnc_UDATA8 = 0x04, // Unsigned 64-bit value - UNW_DW_EhPtrEnc_SIGNED = 0x08, // Signed pointer - UNW_DW_EhPtrEnc_SLEB128 = 0x09, // Signed LE base-128 value - UNW_DW_EhPtrEnc_SDATA2 = 0x0A, // Signed 16-bit value - UNW_DW_EhPtrEnc_SDATA4 = 0x0B, // Signed 32-bit value - UNW_DW_EhPtrEnc_SDATA8 = 0x0C, // Signed 64-bit value -}; -enum{ - UNW_DW_EhPtrEnc_MODIF_MASK = 0x70, - UNW_DW_EhPtrEnc_PCREL = 0x10, // Value is relative to the current program counter. - UNW_DW_EhPtrEnc_TEXTREL = 0x20, // Value is relative to the .text section. - UNW_DW_EhPtrEnc_DATAREL = 0x30, // Value is relative to the .got or .eh_frame_hdr section. - UNW_DW_EhPtrEnc_FUNCREL = 0x40, // Value is relative to the function. - UNW_DW_EhPtrEnc_ALIGNED = 0x50, // Value is aligned to an address unit sized boundary. -}; -enum{ - UNW_DW_EhPtrEnc_INDIRECT = 0x80, // This flag indicates that value is stored in virtual memory. - UNW_DW_EhPtrEnc_OMIT = 0xFF, -}; - -typedef struct UNW_DW_EhPtrCtx{ - U64 raw_base_vaddr; // address where pointer is being read - U64 text_vaddr; // base address of section with instructions (used for encoding pointer on SH and IA64) - U64 data_vaddr; // base address of data section (used for encoding pointer on x86-64) - U64 func_vaddr; // base address of function where IP is located -} UNW_DW_EhPtrCtx; - -// CIE: Common Information Entry -typedef struct UNW_DW_CIEUnpacked{ - U8 version; - UNW_DW_EhPtrEnc lsda_encoding; - UNW_DW_EhPtrEnc addr_encoding; - - B8 has_augmentation_size; - U64 augmentation_size; - String8 augmentation; - - U64 code_align_factor; - S64 data_align_factor; - U64 ret_addr_reg; - - U64 handler_ip; - - U64 cfi_range_min; - U64 cfi_range_max; -} UNW_DW_CIEUnpacked; - -typedef struct UNW_DW_CIEUnpackedNode{ - struct UNW_DW_CIEUnpackedNode *next; - UNW_DW_CIEUnpacked cie; - U64 offset; -} UNW_DW_CIEUnpackedNode; - -// FDE: Frame Description Entry -typedef struct UNW_DW_FDEUnpacked{ - U64 ip_voff_min; - U64 ip_voff_max; - U64 lsda_ip; - - U64 cfi_range_min; - U64 cfi_range_max; -} UNW_DW_FDEUnpacked; - -// CFI: Call Frame Information -typedef struct UNW_DW_CFIRecords{ - B32 valid; - UNW_DW_CIEUnpacked cie; - UNW_DW_FDEUnpacked fde; -} UNW_DW_CFIRecords; - -typedef enum UNW_DW_CFICFARule{ - UNW_DW_CFICFARule_REGOFF, - UNW_DW_CFICFARule_EXPR, -} UNW_DW_CFICFARule; - -typedef struct UNW_DW_CFICFACell{ - UNW_DW_CFICFARule rule; - union{ - struct{ - U64 reg_idx; - S64 offset; - }; - U64 expr_min; - U64 expr_max; - }; -} UNW_DW_CFICFACell; - -typedef enum UNW_DW_CFIRegisterRule{ - UNW_DW_CFIRegisterRule_SAME_VALUE, - UNW_DW_CFIRegisterRule_UNDEFINED, - UNW_DW_CFIRegisterRule_OFFSET, - UNW_DW_CFIRegisterRule_VAL_OFFSET, - UNW_DW_CFIRegisterRule_REGISTER, - UNW_DW_CFIRegisterRule_EXPRESSION, - UNW_DW_CFIRegisterRule_VAL_EXPRESSION, -} UNW_DW_CFIRegisterRule; - -typedef struct UNW_DW_CFICell{ - UNW_DW_CFIRegisterRule rule; - union{ - S64 n; - struct{ - U64 expr_min; - U64 expr_max; - }; - }; -} UNW_DW_CFICell; - -typedef struct UNW_DW_CFIRow{ - struct UNW_DW_CFIRow *next; - UNW_DW_CFICell *cells; - UNW_DW_CFICFACell cfa_cell; -} UNW_DW_CFIRow; - -typedef struct UNW_DW_CFIMachine{ - U64 cells_per_row; - UNW_DW_CIEUnpacked *cie; - UNW_DW_EhPtrCtx *ptr_ctx; - UNW_DW_CFIRow *initial_row; - U64 fde_ip; -} UNW_DW_CFIMachine; - -typedef U8 UNW_DW_CFADecode; -enum{ - UNW_DW_CFADecode_NOP = 0x0, - // 1,2,4,8 reserved for literal byte sizes - UNW_DW_CFADecode_ADDRESS = 0x9, - UNW_DW_CFADecode_ULEB128 = 0xA, - UNW_DW_CFADecode_SLEB128 = 0xB, -}; - -typedef U16 UNW_DW_CFAControlBits; -enum{ - UNW_DW_CFAControlBits_DEC1_MASK = 0x00F, - UNW_DW_CFAControlBits_DEC2_MASK = 0x0F0, - UNW_DW_CFAControlBits_IS_REG_0 = 0x100, - UNW_DW_CFAControlBits_IS_REG_1 = 0x200, - UNW_DW_CFAControlBits_IS_REG_2 = 0x400, - UNW_DW_CFAControlBits_NEW_ROW = 0x800, -}; -#endif - -//////////////////////////////// -//~ Dwarf Parser Functions - -static DWARF_Parsed* dwarf_parsed_from_elf(Arena *arena, ELF_Parsed *elf); - -static DWARF_IndexParsed* dwarf_index_from_data(Arena *arena, String8 data); -static DWARF_SupParsed* dwarf_sup_from_data(Arena *arena, String8 data); -static DWARF_InfoParsed* dwarf_info_from_data(Arena *arena, String8 data); -static DWARF_PubNamesParsed* dwarf_pubnames_from_data(Arena *arena, String8 data); -static DWARF_NamesParsed* dwarf_names_from_data(Arena *arena, String8 data); -static DWARF_ArangesParsed* dwarf_aranges_from_data(Arena *arena, String8 data); -static DWARF_LineParsed* dwarf_line_from_data(Arena *arena, String8 data); -static DWARF_MacInfoParsed* dwarf_mac_info_from_data(Arena *arena, String8 data); -static DWARF_MacroParsed* dwarf_macro_from_data(Arena *arena, String8 data); -static DWARF_FrameParsed* dwarf_frame_from_data(Arena *arena, String8 data); -static DWARF_RangesParsed* dwarf_ranges_from_data(Arena *arena, String8 data); -static DWARF_StrOffsetsParsed* dwarf_str_offsets_from_data(Arena *arena, String8 data); -static DWARF_AddrParsed* dwarf_addr_from_data(Arena *arena, String8 data); -static DWARF_RngListsParsed* dwarf_rng_lists_from_data(Arena *arena, String8 data); -static DWARF_LocListsParsed* dwarf_loc_lists_from_data(Arena *arena, String8 data); - - -// parse helpers - -// (DWARF4.pdf + 7.2.2) (DWARF5.pdf + 7.2.2) -static void dwarf__initial_length(String8 data, - U8 **ptr_inout, U8 **unit_opl_out, B32 *is_64bit_out); - -static void -dwarf__line_v5_directories(U64 address_size, U64 offset_size, - DWARF_V5LinePathEntryFormat *format, U64 format_count, - DWARF_V5Directory *directories_out, U64 dir_count, - U8 **ptr_io, U8 *opl); - -// debug sections - -static String8 dwarf_name_from_debug_section(DWARF_Parsed *dwarf, DWARF_SectionCode sec_code); - -// abbrev functions - -static DWARF_AbbrevUnit* dwarf_abbrev_unit_from_offset(DWARF_AbbrevParsed *abbrev, U64 off); -static DWARF_AbbrevDecl* dwarf_abbrev_decl_from_code(DWARF_AbbrevUnit *unit, U32 code); - -// attribute decoding functions - -static DWARF_AttributeClassFlags dwarf_attribute_class_from_form(DWARF_AttributeForm form); -static DWARF_AttributeClassFlags dwarf_attribute_class_from_name(DWARF_AttributeName name); - -// form decoding functions - -static DWARF_FormDecodeRules -dwarf_form_decode_rule(DWARF_AttributeForm form, U64 address_size, U64 offset_size); - -static DWARF_FormDecoded -dwarf_form_decode(DWARF_FormDecodeRules *rules, U8 **ptr_io, U8 *opl, - DWARF_AbbrevDecl *abbrev_decl, U32 attrib_i); - -// string functions - -static String8 dwarf_string_from_unit_type(DWARF_UnitType type); -static String8 dwarf_string_from_tag(DWARF_Tag tag); -static String8 dwarf_string_from_attribute_name(DWARF_AttributeName name); -static String8 dwarf_string_from_attribute_form(DWARF_AttributeForm form); -static String8 dwarf_string_from_line_std_op(DWARF_LineStdOp op); -static String8 dwarf_string_from_line_ext_op(DWARF_LineExtOp op); -static String8 dwarf_string_from_line_entry_format(DWARF_LineEntryFormat format); -static String8 dwarf_string_from_section_code(DWARF_SectionCode sec_code); - -#endif //RDI_DWARF_H - diff --git a/src/rdi_from_dwarf/rdi_dwarf_stringize.c b/src/rdi_from_dwarf/rdi_dwarf_stringize.c deleted file mode 100644 index 67865813..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf_stringize.c +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ DWARF Stringize Functions - -static char dwarf_spaces[] = " "; - -static void -dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent){ - String8 unit_type_string = dwarf_string_from_unit_type((DWARF_UnitType)unit->unit_type); - - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, - unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*sunit_type=%.*s\n", indent, dwarf_spaces, - str8_varg(unit_type_string)); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*sabbrev_off=0x%llx\n", indent, dwarf_spaces, - unit->abbrev_off); - - switch (unit->unit_type){ - case DWARF_UnitType_skeleton: case DWARF_UnitType_split_compile: - { - str8_list_pushf(arena, out, "%.*sdwo_id=%llu\n", indent, dwarf_spaces, unit->dwo_id); - }break; - - case DWARF_UnitType_type: case DWARF_UnitType_split_type: - { - str8_list_pushf(arena, out, "%.*stype_signature=%llu\n", indent, dwarf_spaces, - unit->type_signature); - str8_list_pushf(arena, out, "%.*stype_offset=%llu\n", indent, dwarf_spaces, - unit->type_offset); - }break; - } -} - -static void -dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit, - U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off); - str8_list_pushf(arena, out, "%.*sinfo_length=0x%llx\n", indent, dwarf_spaces, - unit->info_length); -} - -static void -dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*scomp_unit_count=%u\n", indent, dwarf_spaces, - unit->comp_unit_count); - str8_list_pushf(arena, out, "%.*slocal_type_unit_count=%u\n", indent, dwarf_spaces, - unit->local_type_unit_count); - str8_list_pushf(arena, out, "%.*sforeign_type_unit_count=%u\n", indent, dwarf_spaces, - unit->foreign_type_unit_count); - str8_list_pushf(arena, out, "%.*sbucket_count=%u\n", indent, dwarf_spaces, - unit->bucket_count); - str8_list_pushf(arena, out, "%.*sname_count=%u\n", indent, dwarf_spaces, unit->name_count); - str8_list_pushf(arena, out, "%.*sabbrev_table_size=%u\n", indent, dwarf_spaces, - unit->abbrev_table_size); - str8_list_pushf(arena, out, "%.*saugmentation_string=%.*s\n", indent, dwarf_spaces, - str8_varg(unit->augmentation_string)); -} - -static void -dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->version); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces, - unit->segment_selector_size); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, unit->offset_size); - str8_list_pushf(arena, out, "%.*sinfo_off=0x%llx\n", indent, dwarf_spaces, unit->info_off); -} - -static void -dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent){ - str8_list_pushf(arena, out, "%.*shdr_off=0x%llx\n", indent, dwarf_spaces, unit->hdr_off); - str8_list_pushf(arena, out, "%.*sbase_off=0x%llx\n", indent, dwarf_spaces, unit->base_off); - str8_list_pushf(arena, out, "%.*sopl_off=0x%llx\n", indent, dwarf_spaces, unit->opl_off); - str8_list_pushf(arena, out, "%.*soffset_size=%u\n", indent, dwarf_spaces, - unit->offset_size); - str8_list_pushf(arena, out, "%.*sversion=%u\n", indent, dwarf_spaces, unit->dwarf_version); - str8_list_pushf(arena, out, "%.*saddress_size=%u\n", indent, dwarf_spaces, - unit->address_size); - str8_list_pushf(arena, out, "%.*ssegment_selector_size=%u\n", indent, dwarf_spaces, - unit->segment_selector_size); -} diff --git a/src/rdi_from_dwarf/rdi_dwarf_stringize.h b/src/rdi_from_dwarf/rdi_dwarf_stringize.h deleted file mode 100644 index 30a13254..00000000 --- a/src/rdi_from_dwarf/rdi_dwarf_stringize.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_DWARF_STRINGIZE_H -#define RDI_DWARF_STRINGIZE_H - -//////////////////////////////// -//~ DWARF Stringize Functions - -static void -dwarf_stringize_info(Arena *arena, String8List *out, DWARF_InfoUnit *unit, U32 indent); - -static void -dwarf_stringize_pubnames(Arena *arena, String8List *out, DWARF_PubNamesUnit *unit, - U32 indent); - -static void -dwarf_stringize_names(Arena *arena, String8List *out, DWARF_NamesUnit *unit, U32 indent); - -static void -dwarf_stringize_aranges(Arena *arena, String8List *out, DWARF_ArangesUnit *unit, U32 indent); - -static void -dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 indent); - - - -#endif //RDI_DWARF_STRINGIZE_H diff --git a/src/rdi_from_dwarf/rdi_elf.c b/src/rdi_from_dwarf/rdi_elf.c deleted file mode 100644 index bda90ef1..00000000 --- a/src/rdi_from_dwarf/rdi_elf.c +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ ELF Parser Functions - -static ELF_Parsed* -elf_parsed_from_data(Arena *arena, String8 elf_data){ - //- test magic number - B32 has_good_magic_number = 0; - if (elf_data.size >= sizeof(ELF_NIDENT) && - MemoryMatch(elf_data.str, elf_magic, sizeof(elf_magic))){ - has_good_magic_number = 1; - } - - //- determine elf class - U8 elf_class = ELF_Class_NONE; - if (has_good_magic_number){ - elf_class = elf_data.str[ELF_Identification_CLASS]; - } - - //- extract header information - B32 decoded_header = 0; - - U8 e_data_encoding = ELF_DataEncoding_NONE; - U16 e_machine = ELF_Machine_NONE; - - U64 e_entry = 0; - - U64 e_shoff = 0; - U16 e_shentsize = 0; - U16 e_shnum = 0; - - U64 e_phoff = 0; - U16 e_phentsize = 0; - U16 e_phnum = 0; - - U16 e_shstrndx = 0; - - switch (elf_class){ - case ELF_Class_NONE: /* not good */ break; - - case ELF_Class_32: - { - if (elf_data.size >= sizeof(ELF_Ehdr32)){ - ELF_Ehdr32 *hdr = (ELF_Ehdr32*)elf_data.str; - - decoded_header = 1; - e_data_encoding = hdr->e_ident[ELF_Identification_DATA]; - e_machine = hdr->e_machine; - e_entry = hdr->e_entry; - e_phoff = hdr->e_phoff; - e_shoff = hdr->e_shoff; - e_phentsize = hdr->e_phentsize; - e_phnum = hdr->e_phnum; - e_shentsize = hdr->e_shentsize; - e_shnum = hdr->e_shnum; - e_shstrndx = hdr->e_shstrndx; - } - }break; - - case ELF_Class_64: - { - if (elf_data.size >= sizeof(ELF_Ehdr64)){ - ELF_Ehdr64 *hdr = (ELF_Ehdr64*)elf_data.str; - - decoded_header = 1; - e_data_encoding = hdr->e_ident[ELF_Identification_DATA]; - e_machine = hdr->e_machine; - e_entry = hdr->e_entry; - e_phoff = hdr->e_phoff; - e_shoff = hdr->e_shoff; - e_phentsize = hdr->e_phentsize; - e_phnum = hdr->e_phnum; - e_shentsize = hdr->e_shentsize; - e_shnum = hdr->e_shnum; - e_shstrndx = hdr->e_shstrndx; - } - }break; - } - - //- validate & translate header values - B32 header_is_good = 0; - Arch arch = Arch_Null; - if (decoded_header){ - header_is_good = 1; - - // only supporting little-endian versions right now - if (header_is_good){ - if (e_data_encoding != ELF_DataEncoding_2LSB){ - header_is_good = 0; - } - } - - // make sure this is a supported machine type - if (header_is_good){ - switch (e_machine){ - default: header_is_good = 0; - case ELF_Machine_386: arch = Arch_x86; break; - case ELF_Machine_X86_64: arch = Arch_x64; break; - } - } - - // make sure section & segment sizes are correct - if (header_is_good){ - switch (elf_class){ - case ELF_Class_32: - { - if (e_shentsize != sizeof(ELF_Shdr32) || - e_phentsize != sizeof(ELF_Phdr32)){ - header_is_good = 0; - } - }break; - case ELF_Class_64: - { - if (e_shentsize != sizeof(ELF_Shdr64) || - e_phentsize != sizeof(ELF_Phdr64)){ - header_is_good = 0; - } - }break; - } - } - } - - //- extract extra information from the special first section - U64 section_count_raw = e_shnum; - U32 section_header_string_table_index = e_shstrndx; - if (header_is_good){ - if (e_shoff <= elf_data.size && e_shentsize <= elf_data.size && - e_shoff + e_shentsize <= elf_data.size){ - U64 size = 0; - U32 link = 0; - switch (elf_class){ - case ELF_Class_32: - { - ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + e_shoff); - size = shdr->sh_size; - link = shdr->sh_link; - }break; - case ELF_Class_64: - { - ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + e_shoff); - size = shdr->sh_size; - link = shdr->sh_link; - }break; - } - - // extended section count - if (size != 0){ - section_count_raw = size; - } - - // extended section header string table index - if (link != 0){ - section_header_string_table_index = link; - } - } - } - - //- clamp section & program arrays to size - U64 section_foff = 0; - U64 section_size = 0; - U64 section_count = 0; - - U64 segment_foff = 0; - U64 segment_size = 0; - U64 segment_count = 0; - - if (header_is_good){ - if (e_shentsize > 0){ - U64 section_opl_raw = e_shoff + e_shentsize*section_count_raw; - U64 section_opl = ClampTop(section_opl_raw, elf_data.size); - if (section_opl > e_shoff){ - section_foff = e_shoff; - section_size = e_shentsize; - section_count = (section_opl - e_shoff)/e_shentsize; - } - } - - if (e_phentsize > 0){ - U64 segment_opl_raw = e_phoff + e_phentsize*e_phnum; - U64 segment_opl = ClampTop(segment_opl_raw, elf_data.size); - if (segment_opl > e_phoff){ - segment_foff = e_phoff; - segment_size = e_phentsize; - segment_count = (segment_opl - e_phoff)/e_phentsize; - } - } - } - - //- determine the vbase for this file - U64 vbase = 0; - if (header_is_good){ - // find the first LOAD segment - U64 load_segment_off = 0; - { - U64 segment_cursor = segment_foff; - U64 segment_opl = segment_foff + segment_size*segment_count; - for (;segment_cursor < segment_opl; segment_cursor += segment_size){ - U32 p_type = *(U32*)(elf_data.str + segment_cursor); - if (p_type == ELF_SegmentType_LOAD){ - load_segment_off = segment_cursor; - break; - } - } - } - - // use the segment's p_vaddr to determine vbase - if (load_segment_off != 0){ - switch (elf_class){ - case ELF_Class_32: - { - ELF_Phdr32 *phdr = (ELF_Phdr32*)(elf_data.str + load_segment_off); - vbase = phdr->p_vaddr; - }break; - case ELF_Class_64: - { - ELF_Phdr64 *phdr = (ELF_Phdr64*)(elf_data.str + load_segment_off); - vbase = phdr->p_vaddr; - }break; - } - } - } - - //- locate the section header string table - U64 section_name_table_foff = 0; - U64 section_name_table_opl = 0; - if (header_is_good){ - if (section_header_string_table_index < section_count){ - U64 sec_foff = section_foff + section_header_string_table_index*section_size; - switch (elf_class){ - case ELF_Class_32: - { - ELF_Shdr32 *shdr = (ELF_Shdr32*)(elf_data.str + sec_foff); - section_name_table_foff = shdr->sh_offset; - section_name_table_opl = shdr->sh_offset + shdr->sh_size; - }break; - case ELF_Class_64: - { - ELF_Shdr64 *shdr = (ELF_Shdr64*)(elf_data.str + sec_foff); - section_name_table_foff = shdr->sh_offset; - section_name_table_opl = shdr->sh_offset + shdr->sh_size; - }break; - } - } - } - - //- format sections data - ELF_Shdr64 *sections = 0; - if (header_is_good && section_count > 0){ - switch (elf_class){ - case ELF_Class_32: - { - sections = push_array(arena, ELF_Shdr64, section_count); - { - ELF_Shdr32 *shdr32 = (ELF_Shdr32*)(elf_data.str + section_foff); - ELF_Shdr64 *shdr64 = sections; - for (U64 i = 0; i < section_count; i += 1, shdr32 += 1, shdr64 += 1){ - shdr64->sh_name = shdr32->sh_name; - shdr64->sh_type = shdr32->sh_type; - shdr64->sh_flags = shdr32->sh_flags; - shdr64->sh_addr = shdr32->sh_addr; - shdr64->sh_offset = shdr32->sh_offset; - shdr64->sh_size = shdr32->sh_size; - shdr64->sh_link = shdr32->sh_link; - shdr64->sh_info = shdr32->sh_info; - shdr64->sh_addralign = shdr32->sh_addralign; - shdr64->sh_entsize = shdr32->sh_entsize; - } - } - }break; - case ELF_Class_64: - { - sections = (ELF_Shdr64*)(elf_data.str + section_foff); - }break; - } - } - - //- extract section names - String8 *section_names = 0; - if (sections != 0 && section_count > 0){ - U8 *string_table_opl = elf_data.str + section_name_table_opl; - - section_names = push_array(arena, String8, section_count); - String8 *sec_name = section_names; - ELF_Shdr64 *sec = sections; - for (U64 i = 0; - i < section_count; - i += 1, sec += 1, sec_name += 1){ - U64 name_foff = section_name_table_foff + sec->sh_name; - if (section_name_table_foff <= name_foff && name_foff < section_name_table_opl){ - U8 *base = elf_data.str + name_foff; - U8 *opl = base; - for (;opl < string_table_opl && *opl != 0; opl += 1); - sec_name->str = base; - sec_name->size = (U64)(opl - base); - } - } - } - - //- format segments data - ELF_Phdr64 *segments = 0; - if (header_is_good && segment_count > 0){ - switch (elf_class){ - case ELF_Class_32: - { - segments = push_array(arena, ELF_Phdr64, segment_count); - { - ELF_Phdr32 *phdr32 = (ELF_Phdr32*)(elf_data.str + segment_foff); - ELF_Phdr64 *phdr64 = segments; - for (U64 i = 0; i < segment_count; i += 1, phdr32 += 1, phdr64 += 1){ - phdr64->p_type = phdr32->p_type; - phdr64->p_flags = phdr32->p_flags; - phdr64->p_offset = phdr32->p_offset; - phdr64->p_vaddr = phdr32->p_vaddr; - phdr64->p_paddr = phdr32->p_paddr; - phdr64->p_filesz = phdr32->p_filesz; - phdr64->p_memsz = phdr32->p_memsz; - phdr64->p_align = phdr32->p_align; - } - } - }break; - case ELF_Class_64: - { - segments = (ELF_Phdr64*)(elf_data.str + segment_foff); - }break; - } - } - - //- find special sections - U64 strtab_idx = 0; - U64 symtab_idx = 0; - U64 dynsym_idx = 0; - if (section_names != 0){ - for (U64 i = 0; i < section_count; i += 1){ - String8 name = section_names[i]; - if (str8_match(name, str8_lit(".strtab"), 0)){ - strtab_idx = i; - } - else if (str8_match(name, str8_lit(".symtab"), 0)){ - symtab_idx = i; - } - else if (str8_match(name, str8_lit(".dynsym"), 0)){ - dynsym_idx = i; - } - } - } - - - //- fill result - ELF_Parsed *result = 0; - if (header_is_good){ - result = push_array(arena, ELF_Parsed, 1); - result->data = elf_data; - result->elf_class = elf_class; - result->arch = arch; - result->sections = sections; - result->section_names = section_names; - result->section_foff = section_foff; - result->section_count = section_count; - result->segments = segments; - result->segment_foff = segment_foff; - result->segment_count = segment_count; - result->vbase = vbase; - result->entry_vaddr = e_entry; - result->section_name_table_foff = section_name_table_foff; - result->section_name_table_opl = section_name_table_opl; - result->strtab_idx = strtab_idx; - result->symtab_idx = symtab_idx; - result->dynsym_idx = dynsym_idx; - } - - return(result); -} - -static ELF_SectionArray -elf_section_array_from_elf(ELF_Parsed *elf){ - ELF_SectionArray result = {0}; - if (elf != 0){ - result.sections = elf->sections; - result.count = elf->section_count; - } - return(result); -} - -static String8Array -elf_section_name_array_from_elf(ELF_Parsed *elf){ - String8Array result = {0}; - if (elf != 0){ - result.v = elf->section_names; - result.count = elf->section_count; - } - return(result); -} - -static ELF_SegmentArray -elf_segment_array_from_elf(ELF_Parsed *elf){ - ELF_SegmentArray result = {0}; - if (elf != 0){ - result.segments = elf->segments; - result.count = elf->segment_count; - } - return(result); -} - -static String8 -elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset){ - String8 result = {0}; - if (elf != 0){ - if (offset > 0){ - U64 foff = elf->section_name_table_foff + offset; - if (elf->section_name_table_foff <= foff && foff < elf->section_name_table_opl){ - U8 *base = elf->data.str + foff; - U8 *section_opl = elf->data.str + elf->section_name_table_opl; - U8 *opl = base; - for (;opl < section_opl && *opl != 0; opl += 1); - result.str = base; - result.size = opl - base; - } - } - } - return(result); -} - -static String8 -elf_section_name_from_idx(ELF_Parsed *elf, U32 idx){ - String8 result = {0}; - if (elf != 0){ - if (idx < elf->section_count){ - result = elf->section_names[idx]; - } - } - return(result); -} - -static U32 -elf_section_idx_from_name(ELF_Parsed *elf, String8 name){ - U32 result = 0; - if (elf != 0){ - String8 *sec_name = elf->section_names; - U64 count = elf->section_count; - for (U64 i = 0; i < count; i += 1, sec_name += 1){ - if (str8_match(*sec_name, name, 0)){ - result = i; - break; - } - } - } - return(result); -} - -static String8 -elf_section_data_from_idx(ELF_Parsed *elf, U32 idx){ - String8 result = {0}; - if (elf != 0){ - if (idx < elf->section_count){ - ELF_Shdr64 *shdr = elf->sections + idx; - U64 off_raw = shdr->sh_offset; - U64 size = shdr->sh_size; - if (shdr->sh_flags & ELF_SectionType_NOBITS){ - size = 0; - } - U64 opl_raw = off_raw + size; - U64 opl = ClampTop(opl_raw, elf->data.size); - U64 off = ClampTop(off_raw, opl); - result.str = elf->data.str + off; - result.size = opl - off; - } - } - return(result); -} - -static ELF_SymArray -elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data){ - // converge to sym64 layout - ELF_Sym64 *symbols = 0; - U64 count = 0; - switch (elf_class){ - default:{}break; - - case ELF_Class_32: - { - count = data.size/sizeof(ELF_Sym32); - symbols = push_array(arena, ELF_Sym64, count); - { - ELF_Sym32 *sym32 = (ELF_Sym32*)(data.str); - ELF_Sym64 *sym64 = symbols; - for (U64 i = 0; i < count; i += 1, sym32 += 1, sym64 += 1){ - sym64->st_name = sym32->st_name; - sym64->st_value = sym32->st_value; - sym64->st_size = sym32->st_size; - sym64->st_info = sym32->st_info; - sym64->st_other = sym32->st_other; - sym64->st_shndx = sym32->st_shndx; - } - } - }break; - - case ELF_Class_64: - { - count = data.size/sizeof(ELF_Sym64); - symbols = (ELF_Sym64*)(data.str); - }break; - } - - // fill result - ELF_SymArray result = {0}; - result.symbols = symbols; - result.count = count; - return(result); -} - -// string functions - -static String8 -elf_string_from_section_type(ELF_SectionType section_type){ - String8 result = str8_lit("INVALID_SECTION_TYPE"); - switch (section_type){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SectionTypeXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_binding(ELF_SymbolBinding binding){ - String8 result = str8_lit("INVALID_SYMBOL_BINDING"); - switch (binding){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolBindingXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_type(ELF_SymbolType type){ - String8 result = str8_lit("INVALID_SYMBOL_TYPE"); - switch (type){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolTypeXList(X) -#undef X - } - return(result); -} - -static String8 -elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility){ - String8 result = str8_lit("INVALID_SYMBOL_VISIBILITY"); - switch (visibility){ -#define X(N,C) case C: result = str8_lit(#N); break; - ELF_SymbolVisibilityXList(X) -#undef X - } - return(result); -} diff --git a/src/rdi_from_dwarf/rdi_elf.h b/src/rdi_from_dwarf/rdi_elf.h deleted file mode 100644 index 8643f8bf..00000000 --- a/src/rdi_from_dwarf/rdi_elf.h +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_ELF_H -#define RDI_ELF_H - -// https://refspecs.linuxfoundation.org/elf/elf.pdf - -//////////////////////////////// -//~ Elf Format Types - -// elf header - -#define ELF_NIDENT 16 - -typedef struct ELF_Ehdr32{ - U8 e_ident[ELF_NIDENT]; - U16 e_type; - U16 e_machine; - U32 e_version; - U32 e_entry; - U32 e_phoff; - U32 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; -} ELF_Ehdr32; - -typedef struct ELF_Ehdr64{ - U8 e_ident[ELF_NIDENT]; - U16 e_type; - U16 e_machine; - U32 e_version; - U64 e_entry; - U64 e_phoff; - U64 e_shoff; - U32 e_flags; - U16 e_ehsize; - U16 e_phentsize; - U16 e_phnum; - U16 e_shentsize; - U16 e_shnum; - U16 e_shstrndx; -} ELF_Ehdr64; - -typedef enum ELF_Type{ - ELF_Type_NONE = 0, - ELF_Type_REL = 1, - ELF_Type_EXEC = 2, - ELF_Type_DYN = 3, - ELF_Type_CORE = 4, - ELF_Type_LOOS = 0xfe00, - ELF_Type_HIOS = 0xfeff, - ELF_Type_LOPROC = 0xff00, - ELF_Type_HIPROC = 0xffff, -} ELF_Type; - -typedef enum ELF_Machine{ - ELF_Machine_NONE = 0, - ELF_Machine_M32 = 1, - ELF_Machine_SPARC = 2, - ELF_Machine_386 = 3, - ELF_Machine_68K = 4, - ELF_Machine_88K = 5, - ELF_Machine_860 = 7, - ELF_Machine_MIPS = 8, - ELF_Machine_S370 = 9, - ELF_Machine_MIPS_RS3_LE = 10, - ELF_Machine_PARISC = 15, - ELF_Machine_VPP500 = 17, - ELF_Machine_SPARC32PLUS = 18, - ELF_Machine_960 = 19, - ELF_Machine_PPC = 20, - ELF_Machine_PPC64 = 21, - ELF_Machine_S390 = 22, - ELF_Machine_V800 = 36, - ELF_Machine_FR20 = 37, - ELF_Machine_RH32 = 38, - ELF_Machine_RCE = 39, - ELF_Machine_ARM = 40, - ELF_Machine_ALPHA = 41, - ELF_Machine_SH = 42, - ELF_Machine_SPARCV9 = 43, - ELF_Machine_TRICORE = 44, - ELF_Machine_ARC = 45, - ELF_Machine_H8_300 = 46, - ELF_Machine_H8_300H = 47, - ELF_Machine_H8S = 48, - ELF_Machine_H8_500 = 49, - ELF_Machine_IA_64 = 50, - ELF_Machine_MIPS_X = 51, - ELF_Machine_COLDFIRE = 52, - ELF_Machine_68HC12 = 53, - ELF_Machine_MMA = 54, - ELF_Machine_PCP = 55, - ELF_Machine_NCPU = 56, - ELF_Machine_NDR1 = 57, - ELF_Machine_STARCORE = 58, - ELF_Machine_ME16 = 59, - ELF_Machine_ST100 = 60, - ELF_Machine_TINYJ = 61, - ELF_Machine_X86_64 = 62, - ELF_Machine_PDSP = 63, - ELF_Machine_PDP10 = 64, - ELF_Machine_PDP11 = 65, - ELF_Machine_FX66 = 66, - ELF_Machine_ST9PLUS = 67, - ELF_Machine_ST7 = 68, - ELF_Machine_68HC16 = 69, - ELF_Machine_68HC11 = 70, - ELF_Machine_68HC08 = 71, - ELF_Machine_68HC05 = 72, - ELF_Machine_SVX = 73, - ELF_Machine_ST19 = 74, - ELF_Machine_VAX = 75, - ELF_Machine_CRIS = 76, - ELF_Machine_JAVELIN = 77, - ELF_Machine_FIREPATH = 78, - ELF_Machine_ZSP = 79, - ELF_Machine_MMIX = 80, - ELF_Machine_HUANY = 81, - ELF_Machine_PRISM = 82, - ELF_Machine_AVR = 83, - ELF_Machine_FR30 = 84, - ELF_Machine_D10V = 85, - ELF_Machine_D30V = 86, - ELF_Machine_V850 = 87, - ELF_Machine_M32R = 88, - ELF_Machine_MN10300 = 89, - ELF_Machine_MN10200 = 90, - ELF_Machine_PJ = 91, - ELF_Machine_OPENRISC = 92, - ELF_Machine_ARC_A5 = 93, - ELF_Machine_XTENSA = 94, - ELF_Machine_VIDEOCORE = 95, - ELF_Machine_TMM_GPP = 96, - ELF_Machine_NS32K = 97, - ELF_Machine_TPC = 98, - ELF_Machine_SNP1K = 99, - ELF_Machine_ST200 = 100, -} ELF_Machine; - -typedef enum ELF_Version{ - ELF_Version_NONE = 0, - ELF_Version_CURRENT = 1, -} ELF_Version; - -typedef enum ELF_Identification{ - ELF_Identification_MAG0 = 0, - ELF_Identification_MAG1 = 1, - ELF_Identification_MAG2 = 2, - ELF_Identification_MAG3 = 3, - ELF_Identification_CLASS = 4, - ELF_Identification_DATA = 5, - ELF_Identification_VERSION = 6, - ELF_Identification_OSABI = 7, - ELF_Identification_ABIVERSION = 8, - ELF_Identification_PAD = 9, -} ELF_Identification; - -read_only global U8 elf_magic[] = {0x7F, 'E', 'L', 'F'}; - -typedef enum ELF_Class{ - ELF_Class_NONE = 0, - ELF_Class_32 = 1, - ELF_Class_64 = 2, -} ELF_Class; - -typedef enum ELF_DataEncoding{ - ELF_DataEncoding_NONE = 0, - ELF_DataEncoding_2LSB = 1, - ELF_DataEncoding_2MSB = 2, -} ELF_DataEncoding; - -typedef enum ELF_OsAbi{ - ELF_OsAbi_NONE = 0, - ELF_OsAbi_HPUX = 1, - ELF_OsAbi_NETBSD = 2, - ELF_OsAbi_LINUX = 3, - ELF_OsAbi_SOLARIS = 6, - ELF_OsAbi_AIX = 7, - ELF_OsAbi_IRIX = 8, - ELF_OsAbi_FREEBSD = 9, - ELF_OsAbi_TRU64 = 10, - ELF_OsAbi_MODESTO = 11, - ELF_OsAbi_OPENBSD = 12, - ELF_OsAbi_OPENVMS = 13, - ELF_OsAbi_NSK = 14, -} ELF_OsAbi; - -// sections - -typedef enum ELF_ReservedSectionIndex{ - ELF_ReservedSectionIndex_UNDEF = 0, - ELF_ReservedSectionIndex_LORESERVE = 0xFF00, - ELF_ReservedSectionIndex_LOPROC = 0xFF00, - ELF_ReservedSectionIndex_HIPROC = 0xFF1F, - ELF_ReservedSectionIndex_LOOS = 0xFF20, - ELF_ReservedSectionIndex_HIOS = 0xFF3F, - ELF_ReservedSectionIndex_ABS = 0xFFF1, - ELF_ReservedSectionIndex_COMMON = 0xFFF2, - ELF_ReservedSectionIndex_XINDEX = 0xFFFF, - ELF_ReservedSectionIndex_HIRESERVE = 0xFFFF, -} ELF_ReservedSectionIndex; - -typedef struct ELF_Shdr32{ - U32 sh_name; - U32 sh_type; - U32 sh_flags; - U32 sh_addr; - U32 sh_offset; - U32 sh_size; - U32 sh_link; - U32 sh_info; - U32 sh_addralign; - U32 sh_entsize; -} ELF_Shdr32; - -typedef struct ELF_Shdr64{ - U32 sh_name; - U32 sh_type; - U64 sh_flags; - U64 sh_addr; - U64 sh_offset; - U64 sh_size; - U32 sh_link; - U32 sh_info; - U64 sh_addralign; - U64 sh_entsize; -} ELF_Shdr64; - -// X(name, code) -#define ELF_SectionTypeXList(X)\ -X(NULL, 0)\ -X(PROGBITS, 1)\ -X(SYMTAB, 2)\ -X(STRTAB, 3)\ -X(RELA, 4)\ -X(HASH, 5)\ -X(DYNAMIC, 6)\ -X(NOTE, 7)\ -X(NOBITS, 8)\ -X(REL, 9)\ -X(SHLIB, 10)\ -X(DYNSYM, 11)\ -X(INIT_ARRAY, 14)\ -X(FINI_ARRAY, 15)\ -X(PREINIT_ARRAY, 16)\ -X(GROUP, 17)\ -X(SYMTAB_SHNDX, 18)\ -X(LOOS, 0x60000000)\ -X(HIOS, 0x6FFFFFFF)\ -X(LOPROC, 0x70000000)\ -X(HIPROC, 0x7FFFFFFF)\ -X(LOUSER, 0x80000000)\ -X(HIUSER, 0x8FFFFFFF) - -typedef enum ELF_SectionType{ -#define X(N,C) ELF_SectionType_##N = C, - ELF_SectionTypeXList(X) -#undef X -} ELF_SectionType; - -typedef enum ELF_SectionAttributeFlags{ - ELF_SectionAttributeFlag_WRITE = 0x001, - ELF_SectionAttributeFlag_ALLOC = 0x002, - ELF_SectionAttributeFlag_EXECINSTR = 0x004, - ELF_SectionAttributeFlag_MERGE = 0x010, - ELF_SectionAttributeFlag_STRINGS = 0x020, - ELF_SectionAttributeFlag_INFO_LINK = 0x040, - ELF_SectionAttributeFlag_LINK_ORDER = 0x080, - ELF_SectionAttributeFlag_OS_NONCONFORMING = 0x100, - ELF_SectionAttributeFlag_GROUP = 0x200, - ELF_SectionAttributeFlag_TLS = 0x400, - ELF_SectionAttributeFlag_MASKOS = 0x0FF00000, - ELF_SectionAttributeFlag_MASKPROC = 0xF0000000, -} ELF_SectionAttributeFlags; - -typedef enum ELF_SectionGroupFlags{ - ELF_SectionGroupFlag_COMDAT = 0x1, - ELF_SectionGroupFlag_MASKOS = 0x0FF00000, - ELF_SectionGroupFlag_MASKPROC = 0xF0000000, -} ELF_SectionGroupFlags; - -typedef enum ELF_ReservedSymbolTableIndex{ - ELF_ReservedSymbolTableIndex_UNDEF = 0, -} ELF_ReservedSymbolTableIndex; - -// symbol table - -typedef struct ELF_Sym32{ - U32 st_name; - U32 st_value; - U32 st_size; - U8 st_info; - U8 st_other; - U16 st_shndx; -} ELF_Sym32; - -typedef struct ELF_Sym64{ - U32 st_name; - U8 st_info; - U8 st_other; - U16 st_shndx; - U64 st_value; - U64 st_size; -} ELF_Sym64; - -#define ELF_SymBindingFromInfo(x) (ELF_SymbolBinding)((x)>>4) -#define ELF_SymTypeFromInfo(x) (ELF_SymbolType)((x)&0xF) -#define ELF_SymInfoFromBindingType(b,t) ((((b)<<4)&0xF)|((t)&0xF)) - -#define ELF_SymVisibilityFromOther(x) ((x)&0x3) -#define ELF_SymOtherFromVisibility(x) ((x)&0x3) - -#define ELF_SymbolBindingXList(X)\ -X(LOCAL, 0)\ -X(GLOBAL, 1)\ -X(WEAK, 2)\ -X(LOOS, 10)\ -X(HIOS, 12)\ -X(LOPROC, 13)\ -X(HIPROC, 15)\ - -typedef enum ELF_SymbolBinding{ -#define X(N,C) ELF_SymbolBinding_##N = C, - ELF_SymbolBindingXList(X) -#undef X -} ELF_SymbolBinding; - -#define ELF_SymbolTypeXList(X)\ -X(NOTYPE, 0)\ -X(OBJECT, 1)\ -X(FUNC, 2)\ -X(SECTION, 3)\ -X(FILE, 4)\ -X(COMMON, 5)\ -X(TLS, 6)\ -X(LOOS, 10)\ -X(HIOS, 12)\ -X(LOPROC, 13)\ -X(HIPROC, 15) - -typedef enum ELF_SymbolType{ -#define X(N,C) ELF_SymbolType_##N = C, - ELF_SymbolTypeXList(X) -#undef X -} ELF_SymbolType; - -#define ELF_SymbolVisibilityXList(X)\ -X(DEFAULT, 0)\ -X(INTERNAL, 1)\ -X(HIDDEN, 2)\ -X(PROTECTED, 3) - -typedef enum ELF_SymbolVisibility{ -#define X(N,C) ELF_SymbolVisibility_##N = C, - ELF_SymbolVisibilityXList(X) -#undef X -} ELF_SymbolVisibility; - -// relocation - -typedef struct ELF_Rel32{ - U32 r_offset; - U32 r_info; -} ELF_Rel32; - -typedef struct ELF_Rela32{ - U32 r_offset; - U32 r_info; - S32 r_addend; -} ELF_Rela32; - -typedef struct ELF_Rel64{ - U64 r_offset; - U64 r_info; -} ELF_Rel64; - -typedef struct ELF_Rela64{ - U64 r_offset; - U64 r_info; - S64 r_addend; -} ELF_Rela64; - -#define ELF_RelSymIndexFromInfo32(x) ((x)>>8) -#define ELF_RelTypeFromInfo32(x) ((x)&0xF) -#define ELF_RelInfoFromSymIndexType32(n,t) (((n)<<8)|((t)&0xF)) - -#define ELF_RelSymIndexFromInfo64(x) ((x)>>32) -#define ELF_RelTypeFromInfo64(x) ((x)&0xFFFFFFFFL) -#define ELF_RelInfoFromSymIndexType64(n,t) (((n)<<8)|((t)&0xFFFFFFFFL)) - - - -// program header - -typedef struct ELF_Phdr32{ - U32 p_type; - U32 p_offset; - U32 p_vaddr; - U32 p_paddr; - U32 p_filesz; - U32 p_memsz; - U32 p_flags; - U32 p_align; -} ELF_Phdr32; - -typedef struct ELF_Phdr64{ - U32 p_type; - U32 p_flags; - U64 p_offset; - U64 p_vaddr; - U64 p_paddr; - U64 p_filesz; - U64 p_memsz; - U64 p_align; -} ELF_Phdr64; - -typedef enum ELF_SegmentType{ - ELF_SegmentType_NULL = 0, - ELF_SegmentType_LOAD = 1, - ELF_SegmentType_DYNAMIC = 2, - ELF_SegmentType_INTERP = 3, - ELF_SegmentType_NOTE = 4, - ELF_SegmentType_SHLIB = 5, - ELF_SegmentType_PHDR = 6, - ELF_SegmentType_TLS = 7, - ELF_SegmentType_LOOS = 0x60000000, - ELF_SegmentType_HIOS = 0x6fffffff, - ELF_SegmentType_LOPROC = 0x70000000, - ELF_SegmentType_HIPROC = 0x7fffffff, -} ELF_SegmentType; - -typedef enum ELF_SegmentFlags{ - ELF_SegmentFlag_X = 0x1, - ELF_SegmentFlag_W = 0x2, - ELF_SegmentFlag_R = 0x4, - ELF_SegmentFlag_MASKOS = 0x0FF00000, - ELF_SegmentFlag_MASKPROC = 0xF0000000, -} ELF_SegmentFlags; - -//////////////////////////////// -//~ ELF Parser Types - -// elf top level - -typedef struct ELF_SectionArray{ - ELF_Shdr64 *sections; - U64 count; -} ELF_SectionArray; - -typedef struct ELF_SegmentArray{ - ELF_Phdr64 *segments; - U64 count; -} ELF_SegmentArray; - -typedef struct ELF_Parsed{ - String8 data; - ELF_Class elf_class; - Arch arch; - - ELF_Shdr64 *sections; - String8 *section_names; - U64 section_foff; - U64 section_count; - - ELF_Phdr64 *segments; - U64 segment_foff; - U64 segment_count; - - U64 vbase; - U64 entry_vaddr; - U64 section_name_table_foff; - U64 section_name_table_opl; - - U64 strtab_idx; - U64 symtab_idx; - U64 dynsym_idx; -} ELF_Parsed; - -// elf symtab - -typedef struct ELF_SymArray{ - ELF_Sym64 *symbols; - U64 count; -} ELF_SymArray; - -//////////////////////////////// -//~ ELF Parser Functions - -static ELF_Parsed* elf_parsed_from_data(Arena *arena, String8 elf_data); - -static ELF_SectionArray elf_section_array_from_elf(ELF_Parsed *elf); -static String8Array elf_section_name_array_from_elf(ELF_Parsed *elf); -static ELF_SegmentArray elf_segment_array_from_elf(ELF_Parsed *elf); - -static String8 elf_section_name_from_name_offset(ELF_Parsed *elf, U64 offset); -static String8 elf_section_name_from_idx(ELF_Parsed *elf, U32 idx); -static U32 elf_section_idx_from_name(ELF_Parsed *elf, String8 name); - -static String8 elf_section_data_from_idx(ELF_Parsed *elf, U32 idx); - -static ELF_SymArray elf_sym_array_from_data(Arena *arena, ELF_Class elf_class, String8 data); - -// string functions - -static String8 elf_string_from_section_type(ELF_SectionType section_type); -static String8 elf_string_from_symbol_binding(ELF_SymbolBinding binding); -static String8 elf_string_from_symbol_type(ELF_SymbolType type); -static String8 elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility); - -#endif //RDI_ELF_H From 4e775d5b6c1aba068a36c9dc4e7bd74dccb567ed Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 4 Mar 2025 11:39:26 -0800 Subject: [PATCH 198/755] hash table helper --- src/linker/hash_table.c | 14 ++++++++++++++ src/linker/hash_table.h | 17 ++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index 4566eb67..219ac87c 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -199,6 +199,20 @@ hash_table_search_path(HashTable *ht, String8 path) return result; } +internal void * +hash_table_search_path_raw(HashTable *ht, String8 path) +{ + KeyValuePair *kv = hash_table_search_path(ht, path); + return kv ? kv->value_raw : 0; +} + +internal void * +hash_table_(HashTable *ht, String8 path) +{ + KeyValuePair *result = hash_table_search_path(ht, path); + return result ? result->value_raw : 0; +} + internal B32 hash_table_search_path_u64(HashTable *ht, String8 key, U64 *value_out) { diff --git a/src/linker/hash_table.h b/src/linker/hash_table.h index 51e55a0e..20163a17 100644 --- a/src/linker/hash_table.h +++ b/src/linker/hash_table.h @@ -7,6 +7,7 @@ typedef struct KeyValuePair { union { String8 key_string; + void *key_raw; U32 key_u32; U64 key_u64; }; @@ -67,19 +68,21 @@ internal BucketNode * hash_table_push_u64_u64 (Arena *arena, HashTable *ht, //- search internal KeyValuePair * hash_table_search_string (HashTable *ht, String8 string); -internal KeyValuePair * hash_table_search_u32 (HashTable *ht, U32 key); -internal KeyValuePair * hash_table_search_u64 (HashTable *ht, U64 key); -internal KeyValuePair * hash_table_search_path (HashTable *ht, String8 path); +internal KeyValuePair * hash_table_search_u32 (HashTable *ht, U32 key ); +internal KeyValuePair * hash_table_search_u64 (HashTable *ht, U64 key ); +internal KeyValuePair * hash_table_search_path (HashTable *ht, String8 path ); +internal void * hash_table_search_path_raw(HashTable *ht, String8 path ); internal B32 hash_table_search_path_u64(HashTable *ht, String8 key, U64 *value_out); //- key-value helpers -internal U32 * keys_from_hash_table_u32(Arena *arena, HashTable *ht); -internal U64 * keys_from_hash_table_u64(Arena *arena, HashTable *ht); +internal U32 * keys_from_hash_table_u32 (Arena *arena, HashTable *ht); +internal U64 * keys_from_hash_table_u64 (Arena *arena, HashTable *ht); internal KeyValuePair * key_value_pairs_from_hash_table(Arena *arena, HashTable *ht); -internal void sort_key_value_pairs_as_u32(KeyValuePair *pairs, U64 count); -internal void sort_key_value_pairs_as_u64(KeyValuePair *pairs, U64 count); + +internal void sort_key_value_pairs_as_u32(KeyValuePair *pairs, U64 count); +internal void sort_key_value_pairs_as_u64(KeyValuePair *pairs, U64 count); //////////////////////////////// From 5717d6c54ca0af9043dfcfd4d6e89c2cf7b7b56f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 4 Mar 2025 13:26:24 -0800 Subject: [PATCH 199/755] export restrict modifier --- src/lib_rdi_format/rdi_format.h | 2 ++ src/rdi_format/rdi_format.mdesk | 1 + src/rdi_from_pdb/rdi_from_pdb.c | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index f440f03c..73323def 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -386,6 +386,7 @@ typedef enum RDI_TypeModifierFlagsEnum { RDI_TypeModifierFlag_Const = 1<<0, RDI_TypeModifierFlag_Volatile = 1<<1, +RDI_TypeModifierFlag_Restrict = 1<<2, } RDI_TypeModifierFlagsEnum; typedef RDI_U32 RDI_UDTFlags; @@ -887,6 +888,7 @@ X(Count)\ #define RDI_TypeModifierFlags_XList \ X(Const)\ X(Volatile)\ +X(Restrict)\ #define RDI_TypeNode_XList \ X(RDI_TypeKind, kind)\ diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 2a515898..5294e4ca 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -785,6 +785,7 @@ RDI_TypeModifierFlagTable: { {Const `1<<0`} {Volatile `1<<1`} + {Restrict `1<<2`} } @table(name type_lhs type_rhs desc) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index a2f067b6..cbbec26a 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -3526,8 +3526,9 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) // rjf: cv -> rdi modifier flags RDI_TypeModifierFlags modifier_flags = 0; - if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} - if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} + if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} + if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} + if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} // rjf: cv info -> rdi pointer type kind RDI_TypeKind type_kind = RDI_TypeKind_Ptr; From 44249f35fc3284a0224e2e6cfc47ded006798e09 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 10 Mar 2025 16:49:54 -0700 Subject: [PATCH 200/755] pass over the make RDI library - Handle type layout in the library so converts simply define type graph and let the library handle DAG layout. - Changed location baking. For now the library waits for scope, procs, global vars, and thread vars steps to serially finish because of common dependency on location sections, we need to parallel for each step. - Changed encoded offset size for RDI_EvalOp_FrameOff to 8 bytes (1 byte is not enough to cover all cases) - Added frame base location to RDI_Procedure (WASM encodes frame base as an index into a global array and so we have to resolve the base at runtime). --- src/lib_rdi_format/rdi_format.c | 2 +- src/lib_rdi_format/rdi_format.h | 4 + src/lib_rdi_format/rdi_format_parse.c | 22 ++ src/lib_rdi_format/rdi_format_parse.h | 1 + src/lib_rdi_make/rdi_make.c | 376 ++++++++++++++++---------- src/lib_rdi_make/rdi_make.h | 37 ++- src/raddump/raddump.c | 177 ++++++------ src/rdi_format/rdi_format.mdesk | 16 +- src/rdi_make/rdi_make_help.c | 74 +++-- src/rdi_make/rdi_make_help.h | 12 + 10 files changed, 457 insertions(+), 264 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 4e79ae5e..d2143de0 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -101,7 +101,7 @@ RDI_EVAL_CTRLBITS(2, 0, 0), RDI_EVAL_CTRLBITS(1, 1, 1), RDI_EVAL_CTRLBITS(4, 0, 1), RDI_EVAL_CTRLBITS(0, 1, 1), -RDI_EVAL_CTRLBITS(1, 0, 1), +RDI_EVAL_CTRLBITS(8, 0, 1), RDI_EVAL_CTRLBITS(4, 0, 1), RDI_EVAL_CTRLBITS(4, 0, 1), RDI_EVAL_CTRLBITS(0, 0, 0), diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index 73323def..ec01827e 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -970,6 +970,8 @@ X(RDI_LinkFlags, link_flags)\ X(RDI_U32, type_idx)\ X(RDI_U32, root_scope_idx)\ X(RDI_U32, container_idx)\ +X(RDI_U32, frame_base_location_first)\ +X(RDI_U32, frame_base_location_opl)\ #define RDI_Scope_XList \ X(RDI_U32, proc_idx)\ @@ -1397,6 +1399,8 @@ RDI_LinkFlags link_flags; RDI_U32 type_idx; RDI_U32 root_scope_idx; RDI_U32 container_idx; +RDI_U32 frame_base_location_first; +RDI_U32 frame_base_location_opl; }; typedef struct RDI_Scope RDI_Scope; diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index b396f76a..7ce26cc4 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -813,3 +813,25 @@ rdi_cstring_length(char *cstr) for(;cstr[result] != 0; result += 1){} return result; } + +RDI_PROC RDI_U64 +rdi_size_from_bytecode_stream(U8 *ptr, U8 *opl) +{ + RDI_U64 bytecode_size = 0; + RDI_U8 *off_first = ptr + sizeof(RDI_LocationKind); + for(RDI_U8 *off = off_first, *next_off = opl; off < opl; off = next_off) + { + RDI_U8 op = *off; + if(op == 0) + { + break; + } + + RDI_U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + RDI_U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + return bytecode_size; +} + diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index dc948f70..455b7eb2 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -225,5 +225,6 @@ RDI_PROC RDI_U8 *rdi_name_from_file_path_node(RDI_Parsed *rdi, RDI_FilePathNode #define rdi_parse__min(a,b) (((a)<(b))?(a):(b)) RDI_PROC RDI_U64 rdi_cstring_length(char *cstr); +RDI_PROC RDI_U64 rdi_size_from_bytecode_stream(U8 *ptr, U8 *opl); #endif // RDI_FORMAT_PARSE_H diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 272e2dd9..5fc16a59 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -705,6 +705,14 @@ rdim_idx_from_type(RDIM_Type *type) return idx; } +RDI_PROC RDI_U64 +rdim_final_idx_from_type(RDI_U64 *type_indices, RDIM_Type *type) +{ + RDI_U64 pos = rdim_idx_from_type(type); + RDI_U64 idx = type_indices[pos]; + return idx; +} + RDI_PROC void rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push) { @@ -1131,6 +1139,67 @@ rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM scopes->location_count +=1; } +//- location block chunk list + +RDI_PROC RDI_LocationBlock * +rdim_location_block_chunk_list_push_array(RDIM_Arena *arena, RDIM_String8List *list, RDI_U32 count) +{ + RDI_LocationBlock *result = rdim_push_array(arena, RDI_LocationBlock, count); + RDIM_String8 string = rdim_str8((RDI_U8*)result, sizeof(result[0]) * count); + rdim_str8_list_push(arena, list, string); + return result; +} + +RDI_PROC RDI_U32 +rdim_count_from_location_block_chunk_list(RDIM_String8List *list) +{ + RDI_U32 count = list->total_size / sizeof(RDI_LocationBlock); + return count; +} + +//////////////////////////////// + +RDI_PROC void +rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) +{ + RDI_U64 type_pos = rdim_idx_from_type(type); + if(type_indices[type_pos] == 0) + { + if(type->param_types) + { + for(RDI_U64 param_idx = 0; param_idx < type->count; param_idx += 1) + { + rdim_assign_type_index(type->param_types[param_idx], type_indices, curr_type_idx); + } + } + + if(type->direct_type) + { + rdim_assign_type_index(type->direct_type, type_indices, curr_type_idx); + } + + type_indices[type_pos] = *curr_type_idx; + *curr_type_idx += 1; + } +} + +RDI_PROC RDI_U64 * +rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) +{ + RDI_U64 *type_indices = rdim_push_array(arena, RDI_U64, types->total_count + 1); + RDI_U64 type_indices_count = 1; + + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + rdim_assign_type_index(&chunk->v[i], type_indices, &type_indices_count); + } + } + + return type_indices; +} + //////////////////////////////// //~ rjf: [Baking Helpers] Baked VMap Building @@ -2070,7 +2139,7 @@ rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopo //- rjf: bake name map building RDI_PROC RDIM_BakeNameMap * -rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params) +rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI_U64 *type_indices, RDIM_BakeParams *params) { RDIM_BakeNameMap *map = rdim_push_array(arena, RDIM_BakeNameMap, 1); switch(kind) @@ -2123,7 +2192,7 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI { for(RDI_U64 idx = 0; idx < n->count; idx += 1) { - RDI_U32 type_idx = (RDI_U32)rdim_idx_from_type(&n->v[idx]); // TODO(rjf): @u64_to_u32 + RDI_U32 type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, &n->v[idx]); // TODO(rjf): @u64_to_u32 rdim_bake_name_map_push(arena, map, n->v[idx].name, type_idx); } } @@ -2162,7 +2231,7 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI //- rjf: idx run map building RDI_PROC RDIM_BakeIdxRunMap * -rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params) +rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDI_U64 *type_indices, RDIM_BakeParams *params) { //- rjf: set up map RDIM_BakeIdxRunMap *idx_runs = rdim_push_array(arena, RDIM_BakeIdxRunMap, 1); @@ -2182,7 +2251,7 @@ rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(type->param_types[idx]); // TODO(rjf): @u64_to_u32 + param_idx_run[idx] = (RDI_U32)rdim_final_idx_from_type(type_indices, type->param_types[idx]); // TODO(rjf): @u64_to_u32 } rdim_bake_idx_run_map_insert(arena, idx_runs, param_idx_run, param_idx_run_count); } @@ -2958,16 +3027,16 @@ rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src) } RDI_PROC RDIM_TypeNodeBakeResult -rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src) +rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDI_U64 *type_indices, RDIM_TypeChunkList *src) { RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, src->total_count+1); - RDI_U32 dst_idx = 1; for(RDIM_TypeChunkNode *n = src->first; n != 0; n = n->next) { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) { - RDIM_Type *src = &n->v[chunk_idx]; - RDI_TypeNode *dst = &type_nodes[dst_idx]; + RDIM_Type *src = &n->v[chunk_idx]; + U64 dst_idx = rdim_final_idx_from_type(type_indices, src); + RDI_TypeNode *dst = &type_nodes[dst_idx]; //- rjf: fill shared type node info dst->kind = src->kind; @@ -2980,10 +3049,21 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId dst->built_in.name_string_idx = rdim_bake_idx_from_string(strings, src->name); } + else if(dst->kind == RDI_TypeKind_Array) + { + U64 direct_byte_size = 1; + if(src->direct_type && src->direct_type->byte_size > 0) + { + direct_byte_size = src->direct_type->byte_size; + } + dst->constructed.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); + dst->constructed.count = src->byte_size / direct_byte_size; + } + //- rjf: fill constructed type node info else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) { - dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + dst->constructed.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 dst->constructed.count = src->count; if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) { @@ -2991,7 +3071,7 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(src->param_types[idx]); // TODO(rjf): @u64_to_u32 + param_idx_run[idx] = (RDI_U32)rdim_final_idx_from_type(type_indices, src->param_types[idx]); // TODO(rjf): @u64_to_u32 } dst->constructed.param_idx_run_first = rdim_bake_idx_from_idx_run(idx_runs, param_idx_run, param_idx_run_count); } @@ -3006,13 +3086,13 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId { dst->user_defined.name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->user_defined.udt_idx = (RDI_U32)rdim_idx_from_udt(src->udt); // TODO(rjf): @u64_to_u32 - dst->user_defined.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + dst->user_defined.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 } //- rjf: fill bitfield info else if(dst->kind == RDI_TypeKind_Bitfield) { - dst->bitfield.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + dst->bitfield.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 dst->bitfield.off = src->off; dst->bitfield.size = src->count; } @@ -3025,7 +3105,7 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId } RDI_PROC RDIM_UDTBakeResult -rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src) +rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_UDTChunkList *src) { //- rjf: build tables RDI_UDT * udts = push_array(arena, RDI_UDT, src->total_count+1); @@ -3043,7 +3123,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChun RDI_UDT *dst_udt = &udts[dst_udt_idx]; //- rjf: fill basics - dst_udt->self_type_idx = (RDI_U32)rdim_idx_from_type(src_udt->self_type); // TODO(rjf): @u64_to_u32 + dst_udt->self_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_udt->self_type); // TODO(rjf): @u64_to_u32 dst_udt->file_idx = (RDI_U32)rdim_idx_from_src_file(src_udt->src_file); // TODO(rjf): @u64_to_u32 dst_udt->line = src_udt->line; dst_udt->col = src_udt->col; @@ -3060,7 +3140,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChun RDI_Member *dst_member = &members[dst_member_idx]; dst_member->kind = src_member->kind; dst_member->name_string_idx = rdim_bake_idx_from_string(strings, src_member->name); - dst_member->type_idx = (RDI_U32)rdim_idx_from_type(src_member->type); // TODO(rjf): @u64_to_u32 + dst_member->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_member->type); // TODO(rjf): @u64_to_u32 dst_member->off = src_member->off; } } @@ -3098,7 +3178,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChun } RDI_PROC RDIM_GlobalVariableBakeResult -rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) +rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src) { RDI_GlobalVariable *global_variables = push_array(arena, RDI_GlobalVariable, src->total_count+1); RDI_U32 dst_idx = 1; @@ -3110,7 +3190,7 @@ rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_GlobalVariable *dst = &global_variables[dst_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->voff = src->offset; - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 if(src->is_extern) { dst->link_flags |= RDI_LinkFlag_External; @@ -3211,7 +3291,7 @@ rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src) } RDI_PROC RDIM_ThreadVariableBakeResult -rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) +rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src) { RDI_ThreadVariable *thread_variables = push_array(arena, RDI_ThreadVariable, src->total_count+1); RDI_U32 dst_idx = 1; @@ -3223,7 +3303,7 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_ThreadVariable *dst = &thread_variables[dst_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->tls_off = (RDI_U32)src->offset; // TODO(rjf): @u64_to_u32 - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); + dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); if(src->is_extern) { dst->link_flags |= RDI_LinkFlag_External; @@ -3246,8 +3326,104 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, return result; } +RDI_PROC U64 +rdim_bake_location(Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) +{ + U64 location_data_off = location_data_blobs->total_size; + + // rjf: nil location + if(src_location == 0) + { + rdim_str8_list_push_align(arena, location_data_blobs, 8); + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_lit("\0")); + } + + // rjf: valid location + else switch(src_location->kind) + { + // rjf: catchall unsupported case + default: + { + rdim_str8_list_push_align(arena, location_data_blobs, 8); + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_lit("\0")); + }break; + + // rjf: bytecode streams + case RDI_LocationKind_AddrBytecodeStream: + case RDI_LocationKind_ValBytecodeStream: + { + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&src_location->kind))); + for(RDIM_EvalBytecodeOp *op_node = src_location->bytecode.first_op; + op_node != 0; + op_node = op_node->next) + { + RDI_U8 op_data[9]; + op_data[0] = op_node->op; + rdim_memcpy(op_data + 1, &op_node->p, op_node->p_size); + RDIM_String8 op_data_str = rdim_str8(op_data, 1 + op_node->p_size); + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, op_data_str)); + } + { + RDI_U64 data = 0; + RDIM_String8 data_str = rdim_str8((RDI_U8 *)&data, 1); + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, data_str)); + } + }break; + + // rjf: simple addr+off cases + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + RDI_LocationRegPlusU16 loc = {0}; + loc.kind = src_location->kind; + loc.reg_code = src_location->reg_code; + loc.offset = src_location->offset; + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&loc))); + }break; + + // rjf: register cases + case RDI_LocationKind_ValReg: + { + RDI_LocationReg loc = {0}; + loc.kind = src_location->kind; + loc.reg_code = src_location->reg_code; + rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&loc))); + }break; + } + + return location_data_off; +} + +RDI_PROC RDI_U32 +rdim_bake_locset(RDIM_Arena *arena, + RDIM_String8List *location_blocks, + RDIM_String8List *location_data_blobs, + RDIM_LocationSet locset) +{ + RDI_U32 locset_idx = 0; + if(locset.location_case_count > 0) + { + locset_idx = rdim_count_from_location_block_chunk_list(location_blocks); + + RDI_LocationBlock *dst_arr = rdim_location_block_chunk_list_push_array(arena, location_blocks, locset.location_case_count); + RDI_LocationBlock *dst = dst_arr; + for(RDIM_LocationCase *src = locset.first_location_case; src != 0; src = src->next, ++dst) + { + dst->scope_off_first = src->voff_range.min; + dst->scope_off_opl = src->voff_range.max; + dst->location_data_off = rdim_bake_location(arena, location_data_blobs, src->location); + } + } + return locset_idx; +} + RDI_PROC RDIM_ProcedureBakeResult -rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) +rdim_bake_procedures(RDIM_Arena *arena, + RDIM_BakeStringMapTight *strings, + RDI_U64 *type_indices, + RDIM_String8List *location_blocks, + RDIM_String8List *location_data_blobs, + RDIM_SymbolChunkList *src) { RDI_Procedure *procedures = push_array(arena, RDI_Procedure, src->total_count+1); RDI_U32 dst_idx = 1; @@ -3255,8 +3431,12 @@ rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_S { for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) { - RDIM_Symbol *src = &n->v[chunk_idx]; + RDIM_Symbol *src = &n->v[chunk_idx]; RDI_Procedure *dst = &procedures[dst_idx]; + + RDI_U32 frame_base_location_first = rdim_bake_locset(arena, location_blocks, location_data_blobs, src->frame_base); + RDI_U32 frame_base_location_opl = frame_base_location_first + src->frame_base.location_case_count; + dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->link_name_string_idx = rdim_bake_idx_from_string(strings, src->link_name); if(src->is_extern) @@ -3273,8 +3453,10 @@ rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_S dst->link_flags |= RDI_LinkFlag_ProcScoped; dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 } - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 + dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 + dst->frame_base_location_first = frame_base_location_first; + dst->frame_base_location_opl = frame_base_location_opl; } } RDIM_ProcedureBakeResult result = {0}; @@ -3284,30 +3466,33 @@ rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_S } RDI_PROC RDIM_ScopeBakeResult -rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_ScopeChunkList *src) +rdim_bake_scopes(RDIM_Arena *arena, + RDIM_BakeStringMapTight *strings, + RDI_U64 *type_indices, + RDIM_String8List *location_blocks, + RDIM_String8List *location_data_blobs, + RDIM_ScopeChunkList *src) { RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); //////////////////////////// //- rjf: build all scopes, scope voffs, locals, and location blocks // - RDI_Scope * scopes = rdim_push_array(arena, RDI_Scope, src->total_count+1); - RDI_U64 * scope_voffs = rdim_push_array(arena, RDI_U64, src->scope_voff_count+1); - RDI_Local * locals = rdim_push_array(arena, RDI_Local, src->local_count+1); - RDI_LocationBlock * location_blocks = rdim_push_array(arena, RDI_LocationBlock, src->location_count+1); - RDIM_String8List location_data_blobs = {0}; + RDI_Scope *scopes = rdim_push_array(arena, RDI_Scope, src->total_count+1); + RDI_U64 *scope_voffs = rdim_push_array(arena, RDI_U64, src->scope_voff_count+1); + RDI_Local *locals = rdim_push_array(arena, RDI_Local, src->local_count+1); + RDIM_ProfScope("build all scopes, scope voffs, locals, and location blocks") { - RDI_U64 dst_scope_idx = 1; + RDI_U64 dst_scope_idx = 1; RDI_U64 dst_scope_voff_idx = 1; - RDI_U64 dst_local_idx = 1; - RDI_U64 dst_location_block_idx = 1; + RDI_U64 dst_local_idx = 1; for(RDIM_ScopeChunkNode *chunk_n = src->first; chunk_n != 0; chunk_n = chunk_n->next) { for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1, dst_scope_idx += 1) { RDIM_Scope *src_scope = &chunk_n->v[chunk_idx]; - RDI_Scope *dst_scope = &scopes[dst_scope_idx]; + RDI_Scope *dst_scope = &scopes[dst_scope_idx]; //- rjf: push scope's voffs RDI_U64 voff_idx_first = dst_scope_voff_idx; @@ -3328,91 +3513,17 @@ rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_Scope src_local != 0; src_local = src_local->next, dst_local_idx += 1) { - //- rjf: push local's locations - RDI_U64 location_block_idx_first = dst_location_block_idx; - for(RDIM_LocationCase *loccase = src_local->locset.first_location_case; - loccase != 0; - loccase = loccase->next, dst_location_block_idx += 1) - { - // rjf: fill location block - RDI_LocationBlock *dst_locblock = &location_blocks[dst_location_block_idx]; - dst_locblock->scope_off_first = loccase->voff_range.min; - dst_locblock->scope_off_opl = loccase->voff_range.max; - dst_locblock->location_data_off = location_data_blobs.total_size; - - // rjf: serialize location into location data - RDIM_Location *src_location = loccase->location; - { - // rjf: nil location - if(src_location == 0) - { - rdim_str8_list_push_align(scratch.arena, &location_data_blobs, 8); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_lit("\0")); - } - - // rjf: valid location - else switch(src_location->kind) - { - // rjf: catchall unsupported case - default: - { - rdim_str8_list_push_align(scratch.arena, &location_data_blobs, 8); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_lit("\0")); - }break; - - // rjf: bytecode streams - case RDI_LocationKind_AddrBytecodeStream: - case RDI_LocationKind_ValBytecodeStream: - { - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&src_location->kind))); - for(RDIM_EvalBytecodeOp *op_node = src_location->bytecode.first_op; - op_node != 0; - op_node = op_node->next) - { - RDI_U8 op_data[9]; - op_data[0] = op_node->op; - rdim_memcpy(op_data + 1, &op_node->p, op_node->p_size); - RDIM_String8 op_data_str = rdim_str8(op_data, 1 + op_node->p_size); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, op_data_str)); - } - { - RDI_U64 data = 0; - RDIM_String8 data_str = rdim_str8((RDI_U8 *)&data, 1); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, data_str)); - } - }break; - - // rjf: simple addr+off cases - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - RDI_LocationRegPlusU16 loc = {0}; - loc.kind = src_location->kind; - loc.reg_code = src_location->reg_code; - loc.offset = src_location->offset; - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); - }break; - - // rjf: register cases - case RDI_LocationKind_ValReg: - { - RDI_LocationReg loc = {0}; - loc.kind = src_location->kind; - loc.reg_code = src_location->reg_code; - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); - }break; - } - } - } - RDI_U64 location_block_idx_opl = dst_location_block_idx; + // bake location sets + RDI_U32 location_block_idx_first = rdim_bake_locset(arena, location_blocks, location_data_blobs, src_local->locset); + RDI_U32 location_block_idx_opl = location_block_idx_first + src_local->locset.location_case_count; //- rjf: fill local - RDI_Local *dst_local = &locals[dst_local_idx]; + RDI_Local *dst_local = &locals[dst_local_idx]; dst_local->kind = src_local->kind; dst_local->name_string_idx = rdim_bake_idx_from_string(strings, src_local->name); - dst_local->type_idx = (RDI_U32)rdim_idx_from_type(src_local->type); // TODO(rjf): @u64_to_u32 - dst_local->location_first = (RDI_U32)location_block_idx_first; // TODO(rjf): @u64_to_u32 - dst_local->location_opl = (RDI_U32)location_block_idx_opl; // TODO(rjf): @u64_to_u32 + dst_local->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_local->type); // TODO(rjf): @u64_to_u32 + dst_local->location_first = location_block_idx_first; + dst_local->location_opl = location_block_idx_opl; } RDI_U64 local_idx_opl = dst_local_idx; @@ -3430,29 +3541,16 @@ rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_Scope } } - //////////////////////////// - //- rjf: build flattened location data - // - RDIM_String8 location_data_blob = {0}; - RDIM_ProfScope("build flattened location data") - { - location_data_blob = rdim_str8_list_join(arena, &location_data_blobs, rdim_str8_lit("")); - } - //////////////////////////// //- rjf: fill result // RDIM_ScopeBakeResult result = {0}; - result.scopes = scopes; - result.scopes_count = src->total_count+1; - result.scope_voffs = scope_voffs; - result.scope_voffs_count = src->scope_voff_count+1; - result.locals = locals; - result.locals_count = src->local_count+1; - result.location_blocks = location_blocks; - result.location_blocks_count = src->location_count+1; - result.location_data = location_data_blob.str; - result.location_data_size = location_data_blob.size; + result.scopes = scopes; + result.scopes_count = src->total_count+1; + result.scope_voffs = scope_voffs; + result.scope_voffs_count = src->scope_voff_count+1; + result.locals = locals; + result.locals_count = src->local_count+1; rdim_scratch_end(scratch); return result; } @@ -3508,7 +3606,7 @@ rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src) } RDI_PROC RDIM_InlineSiteBakeResult -rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src) +rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_InlineSiteChunkList *src) { RDIM_InlineSiteBakeResult result = {0}; { @@ -3522,8 +3620,8 @@ rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM RDI_InlineSite *dst = &result.inline_sites[dst_idx]; RDIM_InlineSite *src = &n->v[chunk_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 + dst->owner_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->owner); // TODO(rjf): @u64_to_u32 dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 } } @@ -3709,8 +3807,8 @@ rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results) bundle.sections[RDI_SectionKind_ScopeVMap] = rdim_serialized_section_make_unpacked_array(results->scope_vmap.vmap.vmap, results->scope_vmap.vmap.count+1); bundle.sections[RDI_SectionKind_InlineSites] = rdim_serialized_section_make_unpacked_array(results->inline_sites.inline_sites, results->inline_sites.inline_sites_count); bundle.sections[RDI_SectionKind_Locals] = rdim_serialized_section_make_unpacked_array(results->scopes.locals, results->scopes.locals_count); - bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->scopes.location_blocks, results->scopes.location_blocks_count); - bundle.sections[RDI_SectionKind_LocationData] = rdim_serialized_section_make_unpacked_array(results->scopes.location_data, results->scopes.location_data_size); + bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->location_blocks.str, results->location_blocks.size); + bundle.sections[RDI_SectionKind_LocationData] = rdim_serialized_section_make_unpacked_array(results->location_data.str, results->location_data.size); bundle.sections[RDI_SectionKind_NameMaps] = rdim_serialized_section_make_unpacked_array(results->top_level_name_maps.name_maps, results->top_level_name_maps.name_maps_count); bundle.sections[RDI_SectionKind_NameMapBuckets] = rdim_serialized_section_make_unpacked_array(results->name_maps.buckets, results->name_maps.buckets_count); bundle.sections[RDI_SectionKind_NameMapNodes] = rdim_serialized_section_make_unpacked_array(results->name_maps.nodes, results->name_maps.nodes_count); diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 176dbbac..68887dc0 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -773,6 +773,7 @@ struct RDIM_Symbol RDIM_Symbol *container_symbol; RDIM_Type *container_type; struct RDIM_Scope *root_scope; + RDIM_LocationSet frame_base; }; typedef struct RDIM_SymbolChunkNode RDIM_SymbolChunkNode; @@ -1195,10 +1196,6 @@ struct RDIM_ScopeBakeResult RDI_U64 scope_voffs_count; RDI_Local *locals; RDI_U64 locals_count; - RDI_LocationBlock *location_blocks; - RDI_U64 location_blocks_count; - RDI_U8 *location_data; - RDI_U64 location_data_size; }; typedef struct RDIM_ScopeVMapBakeResult RDIM_ScopeVMapBakeResult; @@ -1276,6 +1273,8 @@ struct RDIM_BakeResults RDIM_FilePathBakeResult file_paths; RDIM_StringBakeResult strings; RDIM_IndexRunBakeResult idx_runs; + RDIM_String8 location_blocks; + RDIM_String8 location_data; }; //////////////////////////////// @@ -1382,6 +1381,7 @@ RDI_PROC void rdim_unit_chunk_list_concat_in_place(RDIM_UnitChunkList *dst, RDIM RDI_PROC RDIM_Type *rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_type(RDIM_Type *type); +RDI_PROC RDI_U64 rdim_final_idx_from_type(RDI_U64 *type_indices, RDIM_Type *type); RDI_PROC void rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push); RDI_PROC RDIM_UDT *rdim_udt_chunk_list_push(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_udt(RDIM_UDT *udt); @@ -1429,6 +1429,17 @@ RDI_PROC RDIM_Location *rdim_push_location_val_reg(RDIM_Arena *arena, RDI_U8 reg //- rjf: location sets RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Rng1U64 voff_range, RDIM_Location *location); +//- location block chunk list + +RDI_PROC RDI_LocationBlock * rdim_location_block_chunk_list_push_array(RDIM_Arena *arena, RDIM_String8List *list, RDI_U32 count); +RDI_PROC RDI_U32 rdim_count_from_location_block_chunk_list(RDIM_String8List *list); + +//////////////////////////////// +// Type Index + +RDI_PROC void rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx); +RDI_PROC RDI_U64 * rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types); + //////////////////////////////// //~ rjf: [Baking Helpers] Baked VMap Building @@ -1499,10 +1510,10 @@ RDI_PROC void rdim_bake_string_map_loose_push_symbols(RDIM_Arena *arena, RDIM_Ba RDI_PROC void rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_ScopeChunkList *list); //- rjf: bake name map building -RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params); +RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI_U64 *type_indices, RDIM_BakeParams *params); //- rjf: bake idx run map building -RDI_PROC RDIM_BakeIdxRunMap *rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params); +RDI_PROC RDIM_BakeIdxRunMap *rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDI_U64 *type_indices, RDIM_BakeParams *params); //- rjf: bake path tree building RDI_PROC RDIM_BakePathTree *rdim_bake_path_tree_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); @@ -1523,15 +1534,15 @@ RDI_PROC RDIM_UnitBakeResult rdim_bake_units(RDIM_Arena *arena, RDIM_ RDI_PROC RDIM_UnitVMapBakeResult rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units); RDI_PROC RDIM_SrcFileBakeResult rdim_bake_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_SrcFileChunkList *src); RDI_PROC RDIM_LineTableBakeResult rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src); -RDI_PROC RDIM_TypeNodeBakeResult rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src); -RDI_PROC RDIM_UDTBakeResult rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src); -RDI_PROC RDIM_GlobalVariableBakeResult rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_TypeNodeBakeResult rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDI_U64 *type_indices, RDIM_TypeChunkList *src); +RDI_PROC RDIM_UDTBakeResult rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_UDTChunkList *src); +RDI_PROC RDIM_GlobalVariableBakeResult rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src); RDI_PROC RDIM_GlobalVMapBakeResult rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_ScopeChunkList *src); +RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_ScopeChunkList *src); RDI_PROC RDIM_ScopeVMapBakeResult rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src); -RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src); +RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_InlineSiteChunkList *src); RDI_PROC RDIM_TopLevelNameMapBakeResult rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]); RDI_PROC RDIM_FilePathBakeResult rdim_bake_file_paths(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree); RDI_PROC RDIM_StringBakeResult rdim_bake_strings(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings); diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 09cfba11..f06082ed 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -978,6 +978,7 @@ rdi_print_type_node(Arena *arena, String8List *out, String8 indent, RDI_Parsed * U32 *param_idx_array = rdi_idx_run_from_first_count(rdi, type->constructed.param_idx_run_first, type->constructed.count, ¶m_idx_count); String8 param_idx_str = rd_string_from_array_u32(scratch.arena, param_idx_array, param_idx_count); rd_printf("constructed.params =%S", param_idx_str); + rd_printf("return type =%u", type->constructed.direct_type_idx); } else if (type->kind == RDI_TypeKind_Method) { U32 param_idx_count = 0; U32 *param_idx_array = rdi_idx_run_from_first_count(rdi, type->constructed.param_idx_run_first, type->constructed.count, ¶m_idx_count); @@ -990,6 +991,7 @@ rdi_print_type_node(Arena *arena, String8List *out, String8 indent, RDI_Parsed * String8 param_idx_str = rd_string_from_array_u32(scratch.arena, param_idx_array, param_idx_count); rd_printf("constructed.this_type =%S", this_type_str); rd_printf("constructed.params =%S", param_idx_str); + rd_printf("return type =%u", type->constructed.direct_type_idx); } else if (RDI_TypeKind_FirstConstructed <= type->kind && type->kind <= RDI_TypeKind_LastConstructed) { rd_printf("constructed.direct_type =%u", type->constructed.direct_type_idx); @@ -1058,6 +1060,86 @@ rdi_print_udt(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, R scratch_end(scratch); } +internal void +rdi_print_locations(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, Arch arch, U64 block_lo, U64 block_hi) +{ + Temp scratch = scratch_begin(&arena, 1); + + U64 location_block_count = 0; + U64 location_data_size = 0; + RDI_LocationBlock *location_block_array = rdi_table_from_name(rdi, LocationBlocks, &location_block_count); + RDI_U8 *location_data = rdi_table_from_name(rdi, LocationData, &location_data_size); + + block_lo = ClampTop(block_lo, location_block_count); + block_hi = ClampTop(block_hi, location_block_count); + + for (U32 block_idx = block_lo; block_idx < block_hi; ++block_idx) { + RDI_LocationBlock *block_ptr = &location_block_array[block_idx]; + + if (block_ptr->scope_off_first == 0 && block_ptr->scope_off_opl == max_U32) { + rd_printf("case *always*:"); + } else { + rd_printf("case [%#08x, %#08x):", block_ptr->scope_off_first, block_ptr->scope_off_opl); + } + + if (block_ptr->location_data_off >= location_data_size) { + rd_printf("", block_ptr->location_data_off); + } else { + U8 *loc_data_opl = location_data + location_data_size; + U8 *loc_base_ptr = location_data + block_ptr->location_data_off; + RDI_LocationKind kind = *(RDI_LocationKind*)loc_base_ptr; + switch (kind) { + default: { + rd_printf("\?\?\?: %u", kind); + } break; + + case RDI_LocationKind_AddrBytecodeStream: { + Temp temp = temp_begin(scratch.arena); + String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); + rd_printf("AddrBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); + temp_end(temp); + } break; + + case RDI_LocationKind_ValBytecodeStream: { + Temp temp = temp_begin(scratch.arena); + String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); + rd_printf("ValBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); + temp_end(temp); + } break; + + case RDI_LocationKind_AddrRegPlusU16: { + if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl) { + rd_printf("AddrRegPlusU16(\?\?\?)"); + } else { + RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr; + rd_printf("AddrRegPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); + } + } break; + + case RDI_LocationKind_AddrAddrRegPlusU16: { + if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){ + rd_printf("AddrAddrRegPlusU16(\?\?\?)"); + } else { + RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16 *)loc_base_ptr; + rd_printf("AddrAddrRegisterPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); + } + } break; + + case RDI_LocationKind_ValReg: { + if (loc_base_ptr + sizeof(RDI_LocationReg) > loc_data_opl) { + rd_printf("ValReg(\?\?\?)"); + } else { + RDI_LocationReg *loc = (RDI_LocationReg*)loc_base_ptr; + rd_printf("ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code)); + } + } break; + } + } + } + + scratch_end(scratch); +} + internal void rdi_print_global_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_GlobalVariable *gvar) { @@ -1083,15 +1165,20 @@ rdi_print_thread_variable(Arena *arena, String8List *out, String8 indent, RDI_Pa } internal void -rdi_print_procedure(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc) +rdi_print_procedure(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc, RDI_Arch arch) { Temp scratch = scratch_begin(&arena, 1); - rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, proc->name_string_idx)); - rd_printf("link_name ='%S'", str8_from_rdi_string_idx(rdi, proc->link_name_string_idx)); - rd_printf("link_flags =%S", rdi_string_from_link_flags(scratch.arena, proc->link_flags)); - rd_printf("type_idx =%u", proc->type_idx); - rd_printf("root_scope_idx=%u", proc->root_scope_idx); - rd_printf("container_idx =%u", proc->container_idx); + rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, proc->name_string_idx)); + rd_printf("link_name ='%S'", str8_from_rdi_string_idx(rdi, proc->link_name_string_idx)); + rd_printf("link_flags =%S", rdi_string_from_link_flags(scratch.arena, proc->link_flags)); + rd_printf("type_idx =%u", proc->type_idx); + rd_printf("root_scope_idx =%u", proc->root_scope_idx); + rd_printf("container_idx =%u", proc->container_idx); + rd_printf("frame_base (first=%u, opl=%u)", proc->frame_base_location_first, proc->frame_base_location_opl); + rd_indent(); + rdi_print_locations(arena, out, indent, rdi, arch, proc->frame_base_location_first, proc->frame_base_location_opl); + rd_unindent(); + scratch_end(scratch); } @@ -1103,19 +1190,15 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, U64 scope_count = 0; U64 scope_voff_count = 0; U64 local_count = 0; - U64 location_block_count = 0; - U64 location_data_size = 0; U64 proc_count = 0; RDI_Scope *scope_array = rdi_table_from_name(rdi, Scopes, &scope_count); U64 *scope_voff_array = rdi_table_from_name(rdi, ScopeVOffData, &scope_voff_count); RDI_Local *local_array = rdi_table_from_name(rdi, Locals, &local_count); - RDI_LocationBlock *location_block_array = rdi_table_from_name(rdi, LocationBlocks, &location_block_count); - RDI_U8 *location_data = rdi_table_from_name(rdi, LocationData, &location_data_size); RDI_Procedure *proc_array = rdi_table_from_name(rdi, Procedures, &proc_count); U32 voff_range_lo = ClampTop(scope->voff_range_first, scope_voff_count); U32 voff_range_hi = ClampTop(scope->voff_range_opl, scope_voff_count); - U32 voff_range_count = (voff_range_hi - voff_range_lo) / 2; + U32 voff_range_count = (voff_range_hi - voff_range_lo); U64 *voff_ptr = scope_voff_array + voff_range_lo; String8 voff_str = rd_string_from_range_array_u64_hex(scratch.arena, voff_ptr, voff_range_count); @@ -1147,74 +1230,10 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, local_ptr->name_string_idx)); rd_printf("type_idx=%u", local_ptr->type_idx); - U32 block_lo = ClampTop(local_ptr->location_first, location_block_count); - U32 block_hi = ClampTop(local_ptr->location_opl, location_block_count); - if (block_lo < block_hi) { + if (local_ptr->location_first < local_ptr->location_opl) { rd_printf("locations:"); rd_indent(); - for (U32 block_idx = block_lo; block_idx < block_hi; ++block_idx) { - RDI_LocationBlock *block_ptr = &location_block_array[block_idx]; - - if (block_ptr->scope_off_first == 0 && block_ptr->scope_off_opl == max_U32) { - rd_printf("case *always*:"); - } else { - rd_printf("case [%#08x, %#08x):", block_ptr->scope_off_first, block_ptr->scope_off_opl); - } - - if (block_ptr->location_data_off >= location_data_size) { - rd_printf("", block_ptr->location_data_off); - } else { - U8 *loc_data_opl = location_data + location_data_size; - U8 *loc_base_ptr = location_data + block_ptr->location_data_off; - RDI_LocationKind kind = *(RDI_LocationKind*)loc_base_ptr; - switch (kind) { - default: { - rd_printf("\?\?\?: %u", kind); - } break; - - case RDI_LocationKind_AddrBytecodeStream: { - Temp temp = temp_begin(scratch.arena); - String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); - rd_printf("AddrBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); - temp_end(temp); - } break; - - case RDI_LocationKind_ValBytecodeStream: { - Temp temp = temp_begin(scratch.arena); - String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); - rd_printf("ValBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); - temp_end(temp); - } break; - - case RDI_LocationKind_AddrRegPlusU16: { - if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl) { - rd_printf("AddrRegPlusU16(\?\?\?)"); - } else { - RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr; - rd_printf("AddrRegPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); - } - } break; - - case RDI_LocationKind_AddrAddrRegPlusU16: { - if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){ - rd_printf("AddrAddrRegPlusU16(\?\?\?)"); - } else { - RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16 *)loc_base_ptr; - rd_printf("AddrAddrRegisterPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); - } - } break; - - case RDI_LocationKind_ValReg: { - if (loc_base_ptr + sizeof(RDI_LocationReg) > loc_data_opl) { - rd_printf("ValReg(\?\?\?)"); - } else { - RDI_LocationReg *loc = (RDI_LocationReg*)loc_base_ptr; - rd_printf("ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code)); - } - } break; - } - } - } + rdi_print_locations(arena, out, indent, rdi, arch, local_ptr->location_first, local_ptr->location_opl); rd_unindent(); } rd_unindent(); @@ -1446,7 +1465,7 @@ rdi_print(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RD_Op for (U64 i = 0; i < proc_count; ++i) { rd_printf("procedure[%llu]:", i); rd_indent(); - rdi_print_procedure(arena, out, indent, rdi, &proc_array[i]); + rdi_print_procedure(arena, out, indent, rdi, &proc_array[i], tli->arch); rd_unindent(); } rd_unindent(); diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 5294e4ca..1842cb38 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1027,12 +1027,14 @@ RDI_ThreadVariableMemberTable: @table(name type desc) RDI_ProcedureMemberTable: { - {name_string_idx RDI_U32 ""} - {link_name_string_idx RDI_U32 ""} - {link_flags RDI_LinkFlags ""} - {type_idx RDI_U32 ""} - {root_scope_idx RDI_U32 ""} - {container_idx RDI_U32 ""} + {name_string_idx RDI_U32 ""} + {link_name_string_idx RDI_U32 ""} + {link_flags RDI_LinkFlags ""} + {type_idx RDI_U32 ""} + {root_scope_idx RDI_U32 ""} + {container_idx RDI_U32 ""} + {frame_base_location_first RDI_U32 ""} + {frame_base_location_opl RDI_U32 ""} } @table(name type desc) @@ -1250,7 +1252,7 @@ RDI_EvalOpTable: {MemRead 4 1 1 1} {RegRead 5 4 0 1} {RegReadDyn 6 0 1 1} - {FrameOff 7 1 0 1} + {FrameOff 7 8 0 1} {ModuleOff 8 4 0 1} {TLSOff 9 4 0 1} {ObjectOff 10 0 0 0} diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c index 488030c0..28d27f22 100644 --- a/src/rdi_make/rdi_make_help.c +++ b/src/rdi_make/rdi_make_help.c @@ -197,7 +197,7 @@ ASYNC_WORK_DEF(rdim_build_bake_name_map_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; RDIM_BakeNameMap *name_map = 0; - ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->params); + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); ProfEnd(); return name_map; } @@ -243,7 +243,7 @@ ASYNC_WORK_DEF(rdim_bake_udts_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); - ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->udts); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); ProfEnd(); return out; } @@ -254,7 +254,7 @@ ASYNC_WORK_DEF(rdim_bake_global_variables_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); - ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->global_variables); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); ProfEnd(); return out; } @@ -276,7 +276,7 @@ ASYNC_WORK_DEF(rdim_bake_thread_variables_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); - ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->thread_variables); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); ProfEnd(); return out; } @@ -287,7 +287,7 @@ ASYNC_WORK_DEF(rdim_bake_procedures_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); - ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->procedures); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); ProfEnd(); return out; } @@ -298,7 +298,7 @@ ASYNC_WORK_DEF(rdim_bake_scopes_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); - ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->scopes); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); ProfEnd(); return out; } @@ -320,7 +320,7 @@ ASYNC_WORK_DEF(rdim_bake_inline_sites_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); - ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); ProfEnd(); return out; } @@ -355,7 +355,7 @@ ASYNC_WORK_DEF(rdim_bake_type_nodes_work) Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); - ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->types); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); ProfEnd(); return out; } @@ -404,6 +404,11 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) RDIM_BakeResults out = {0}; rdim_help_state = state; + + //////////////////////////////// + // compute type indices + + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); ////////////////////////////// //- rjf: kick off line tables baking @@ -634,6 +639,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) k = (RDI_NameMapKind)(k+1)) { build_bake_name_map_in[k].k = k; + build_bake_name_map_in[k].type_indices = type_indices; build_bake_name_map_in[k].params = in_params; build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); } @@ -741,27 +747,43 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); - RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts}; + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); - RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; - ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); - RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; - ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); - RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures}; - ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); - RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes}; - ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); - RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites}; + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); - + + RDIM_String8List location_blocks = {0}; + RDIM_String8List location_data_blobs = {0}; + + // reserve null location block for opl + rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); + + // TODO: export location instead of VOFF + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; + ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); + ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); + + // TODO: export location instead of VOFF + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; + ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); + ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); + + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); + ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); + + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); + ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); + ////////////////////////////// //- rjf: join name map building tasks // @@ -782,7 +804,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) RDIM_BakeIdxRunMap *idx_runs = 0; ProfScope("build interned idx run map") { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, in_params); + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); } ////////////////////////////// @@ -795,7 +817,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) ////////////////////////////// //- rjf: kick off pass 3 tasks // - RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types}; + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; { @@ -823,11 +845,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); - ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); - ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); @@ -860,6 +878,12 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); } + + //////////////////////////////// + + out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); + rdim_help_state = 0; scratch_end(scratch); diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h index 159e3a3e..08c64391 100644 --- a/src/rdi_make/rdi_make_help.h +++ b/src/rdi_make/rdi_make_help.h @@ -128,6 +128,7 @@ typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; struct RDIM_BuildBakeNameMapIn { RDI_NameMapKind k; + RDI_U64 *type_indices; RDIM_BakeParams *params; }; @@ -184,6 +185,7 @@ struct RDIM_BakeUDTsIn { RDIM_BakeStringMapTight *strings; RDIM_UDTChunkList *udts; + RDI_U64 *type_indices; }; typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; @@ -191,6 +193,7 @@ struct RDIM_BakeGlobalVariablesIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *global_variables; + RDI_U64 *type_indices; }; typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; @@ -204,6 +207,7 @@ struct RDIM_BakeThreadVariablesIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *thread_variables; + RDI_U64 *type_indices; }; typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; @@ -211,6 +215,9 @@ struct RDIM_BakeProceduresIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *procedures; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; }; typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; @@ -218,6 +225,9 @@ struct RDIM_BakeScopesIn { RDIM_BakeStringMapTight *strings; RDIM_ScopeChunkList *scopes; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; }; typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; @@ -231,6 +241,7 @@ struct RDIM_BakeInlineSitesIn { RDIM_BakeStringMapTight *strings; RDIM_InlineSiteChunkList *inline_sites; + RDI_U64 *type_indices; }; typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; @@ -252,6 +263,7 @@ struct RDIM_BakeTypeNodesIn RDIM_BakeStringMapTight *strings; RDIM_BakeIdxRunMap *idx_runs; RDIM_TypeChunkList *types; + RDI_U64 *type_indices; }; typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; From 3eedcb191205cf3774c9dd638623db2bcf5a2235 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 12 Mar 2025 14:49:14 -0700 Subject: [PATCH 201/755] initialize frame base in interp context --- src/ctrl/ctrl_core.c | 5 +++-- src/eval/eval_interpret.c | 43 ++++++++++++++++++++++++++++++++++++++- src/eval/eval_interpret.h | 2 +- src/raddbg/raddbg_core.c | 5 +++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 3be0a2fb..17433604 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -5513,10 +5513,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ctx->reg_space.u64_0 = (U64)thread; ctx->module_base = push_array(temp.arena, U64, 1); ctx->module_base[0]= module->vaddr_range.min; + ctx->frame_base = push_array(temp.arena, U64, 1); ctx->tls_base = push_array(temp.arena, U64, 1); } - e_select_interpret_ctx(&interpret_ctx); - + e_select_interpret_ctx(&interpret_ctx, type_ctx.primary_module->rdi, type_ctx.ip_voff); + // rjf: evaluate E_Eval eval = zero_struct; ProfScope("evaluate expression") diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index c7c824a4..9af391ad 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -11,9 +11,50 @@ e_selected_interpret_ctx(void) } internal void -e_select_interpret_ctx(E_InterpretCtx *ctx) +e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff) { e_interpret_ctx = ctx; + + // compute and apply frame base + { + E_Interpretation frame_base = { .code = ~0 }; + + RDI_Procedure *proc = rdi_procedure_from_voff(primary_rdi, ip_voff); + for(U64 loc_block_idx = proc->frame_base_location_first; loc_block_idx < proc->frame_base_location_opl; loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(primary_rdi, LocationBlocks, loc_block_idx); + if (block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) { + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(primary_rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + RDI_LocationKind loc_kind = *(RDI_LocationKind *)(all_location_data + block->location_data_off); + if(loc_kind == RDI_LocationKind_ValBytecodeStream || loc_kind == RDI_LocationKind_AddrBytecodeStream) + { + U8 *bytecode_ptr = all_location_data + block->location_data_off + sizeof(RDI_LocationKind); + U8 *bytecode_opl = all_location_data + all_location_data_size; + U64 bytecode_size = rdi_size_from_bytecode_stream(bytecode_ptr, bytecode_opl); + String8 bytecode = str8(bytecode_ptr, bytecode_size); + frame_base = e_interpret(bytecode); + } + else if(loc_kind != RDI_LocationKind_NULL) + { + NotImplemented; + } + } + break; + } + } + + if(frame_base.code == E_InterpretationCode_Good) + { + *ctx->frame_base = frame_base.value.u64; + } + else + { + ctx->frame_base = 0; + } + } } //////////////////////////////// diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 3a9d0b51..f91cc7e2 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -43,7 +43,7 @@ thread_static E_InterpretCtx *e_interpret_ctx = 0; //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) internal E_InterpretCtx *e_selected_interpret_ctx(void); -internal void e_select_interpret_ctx(E_InterpretCtx *ctx); +internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff); //////////////////////////////// //~ rjf: Space Reading Helpers diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8ba4a716..575fd4c1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12159,11 +12159,12 @@ rd_frame(void) ctx->reg_unwind_count = unwind_count; ctx->module_base = push_array(scratch.arena, U64, 1); ctx->module_base[0] = module->vaddr_range.min; + ctx->frame_base = push_array(scratch.arena, U64, 1); ctx->tls_base = push_array(scratch.arena, U64, 1); ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr); } - e_select_interpret_ctx(interpret_ctx); - + e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); + //////////////////////////// //- rjf: build eval visualization view rule table // From 631106b0a8d29705db941a95c5facedad824aac6 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 12 Mar 2025 14:52:09 -0700 Subject: [PATCH 202/755] natvis for RDI Make types --- src/natvis/base.natvis | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/natvis/base.natvis b/src/natvis/base.natvis index 5ef4ef74..644b583c 100644 --- a/src/natvis/base.natvis +++ b/src/natvis/base.natvis @@ -162,4 +162,32 @@ + + + + + + + + + + + chunk_count + + + + + + idx = 0 + + + node->v[idx] + idx += 1 + + node = node->next + + + + + From d10547d2c0f540e9e9cb7c16b0196fef914e2d2f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Mar 2025 08:30:16 -0700 Subject: [PATCH 203/755] don't assume offset evaluation mode in array dereferences; could apply to type info too, thus null mode; fix visualizer drag/drop causing close of hover eval, invalidating the dragged view too early; fix close-window not exiting if last window --- src/eval/eval_ir.c | 1 - src/raddbg/raddbg_core.c | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0e118ac1..00c87283 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -787,7 +787,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) // rjf: ops to compute the final address new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - mode = E_Mode_Offset; } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index db44095c..be5957f7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8374,7 +8374,7 @@ rd_window_frame(void) // ProfScope("build hover eval") { - B32 build_hover_eval = hover_eval_is_open && !rd_drag_is_active(); + B32 build_hover_eval = hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View); // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) @@ -14022,8 +14022,16 @@ rd_frame(void) }break; case RD_CmdKind_CloseWindow: { + RD_CfgList all_windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); RD_Cfg *wcfg = rd_cfg_from_id(rd_regs()->window); - rd_cfg_release(wcfg); + if(all_windows.count == 1 && all_windows.first->v == wcfg) + { + rd_cmd(RD_CmdKind_Exit); + } + else + { + rd_cfg_release(wcfg); + } }break; case RD_CmdKind_ToggleFullscreen: { From c331133388e7e6e76f4838f39037d12fb42f63b2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Mar 2025 14:02:06 -0700 Subject: [PATCH 204/755] adjust hash store - first, don't keep strong refcounts for key history past the 2nd hash - this is prohibitively expensive. but, keep 'downstream' refcounts - this is a mechanism which downstream caches (e.g. text visualization info parsing etc.) can use to ensure a hash stays held in the hash store, given some other data's dependence on it - this stops the storing of unnecessary OutputDebugString log copies --- src/hash_store/hash_store.c | 57 +++++++++++++++++++++++++++++++++---- src/hash_store/hash_store.h | 8 ++++++ src/raddbg/raddbg_core.c | 18 +++++++++--- src/text_cache/text_cache.c | 7 +++-- 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 26dc64ba..587a45c0 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -152,17 +152,17 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) } if(key_node) { - if(key_node->hash_history_gen >= ArrayCount(key_node->hash_history)) + if(key_node->hash_history_gen >= HS_KEY_HASH_HISTORY_STRONG_REF_COUNT) { - key_expired_hash = key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)]; + key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-HS_KEY_HASH_HISTORY_STRONG_REF_COUNT)%ArrayCount(key_node->hash_history)]; } key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; key_node->hash_history_gen += 1; } } - //- rjf: if this key's history cache was full, dec key ref count of oldest hash - ProfScope("if this key's history cache was full, dec key ref count of oldest hash") + //- rjf: decrement key ref count of expired hash + ProfScope("decrement key ref count of expired hash") if(!u128_match(key_expired_hash, u128_zero())) { U64 old_hash_slot_idx = key_expired_hash.u64[1]%hs_shared->slots_count; @@ -250,6 +250,49 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) SLLStackPush(scope->top_touch, touch); } +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void +hs_hash_downstream_inc(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_inc_eval(&n->downstream_ref_count); + break; + } + } + } +} + +internal void +hs_hash_downstream_dec(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_dec_eval(&n->downstream_ref_count); + break; + } + } + } +} + //////////////////////////////// //~ rjf: Cache Lookup @@ -321,7 +364,8 @@ hs_evictor_thread__entry_point(void *p) { U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { slot_has_work = 1; break; @@ -335,7 +379,8 @@ hs_evictor_thread__entry_point(void *p) next = n->next; U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { DLLRemove(slot->first, slot->last, n); SLLStackPush(hs_shared->stripes_free_nodes[stripe_idx], n); diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index ff886e79..784a9203 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -8,6 +8,7 @@ //~ rjf: Cache Types #define HS_KEY_HASH_HISTORY_COUNT 64 +#define HS_KEY_HASH_HISTORY_STRONG_REF_COUNT 2 typedef struct HS_KeyNode HS_KeyNode; struct HS_KeyNode @@ -35,6 +36,7 @@ struct HS_Node String8 data; U64 scope_ref_count; U64 key_ref_count; + U64 downstream_ref_count; }; typedef struct HS_Slot HS_Slot; @@ -138,6 +140,12 @@ internal HS_Scope *hs_scope_open(void); internal void hs_scope_close(HS_Scope *scope); internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node); +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void hs_hash_downstream_inc(U128 hash); +internal void hs_hash_downstream_dec(U128 hash); + //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index be5957f7..e40062b1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5173,7 +5173,7 @@ rd_view_ui(Rng2F32 rect) } else { - rgba.w *= 0.15f; + rgba.w *= 0.05f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; @@ -5191,7 +5191,7 @@ rd_view_ui(Rng2F32 rect) } else { - rgba.w *= 0.15f; + rgba.w *= 0.05f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; @@ -7544,7 +7544,17 @@ rd_window_frame(void) content_rect_center.y - max_query_height_px/2.f, content_rect_center.x + query_width_px/2, content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); - + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + query_rect.x0 = anchor_box->rect.x0; + query_rect.y0 = anchor_box->rect.y1; + query_rect.x1 = query_rect.x0 + ui_top_font_size()*40.f; + query_rect.y1 = query_rect.y0 + query_height_px; + } + } RD_Font(RD_FontSlot_Code) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") @@ -16035,7 +16045,7 @@ Z(getting_started) // rjf: floating queries -> set up window to build immediate-mode top-level query RD_Cfg *view = &rd_nil_cfg; - if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) + if(cmd_name.size == 0 || cmd_kind_info->query.flags & RD_QueryFlag_Floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 377ee516..7a1fae94 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -2313,6 +2313,7 @@ ASYNC_WORK_DEF(txt_parse_work) { if(u128_match(n->hash, hash) && n->lang == lang) { + hs_hash_downstream_inc(n->hash); n->arena = info_arena; info.bytes_processed = n->info.bytes_processed; info.bytes_to_process = n->info.bytes_to_process; @@ -2340,7 +2341,7 @@ txt_evictor_thread__entry_point(void *p) { U64 check_time_us = os_now_microseconds(); U64 check_time_user_clocks = update_tick_idx(); - U64 evict_threshold_us = 10*1000000; + U64 evict_threshold_us = 2*1000000; U64 evict_threshold_user_clocks = 10; for(U64 slot_idx = 0; slot_idx < txt_shared->slots_count; slot_idx += 1) { @@ -2375,6 +2376,7 @@ txt_evictor_thread__entry_point(void *p) n->is_working == 0) { DLLRemove(slot->first, slot->last, n); + hs_hash_downstream_dec(n->hash); if(n->arena != 0) { arena_release(n->arena); @@ -2383,8 +2385,7 @@ txt_evictor_thread__entry_point(void *p) } } } - os_sleep_milliseconds(5); } - os_sleep_milliseconds(1000); + os_sleep_milliseconds(500); } } From f1e88b566784939b458f1190002d5e851d7c70c5 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 13 Mar 2025 23:03:51 -0700 Subject: [PATCH 205/755] pass over PDB converter - moved incomplete type resolution from the converter to RDI make helper layer so we don't need to duplicate code in DWARF converter - changed code for building basic types to handle various data models --- src/lib_rdi_make/rdi_make.c | 155 ++- src/lib_rdi_make/rdi_make.h | 25 + src/rdi_from_pdb/rdi_from_pdb.c | 1481 +++++++++----------------- src/rdi_from_pdb/rdi_from_pdb.h | 39 - src/rdi_from_pdb/rdi_from_pdb_main.c | 3 + src/rdi_make/rdi_make_help.c | 187 ++++ src/rdi_make/rdi_make_help.h | 4 + 7 files changed, 899 insertions(+), 995 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 5fc16a59..484845cc 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -438,6 +438,144 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r } } +//////////////////////////////// +//~ Data Model + +RDI_PROC RDI_TypeKind +rdim_short_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_int_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_long_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model) +{ + switch (data_model) { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + //////////////////////////////// //~ rjf: [Building] Binary Section List Building @@ -1163,6 +1301,13 @@ RDI_PROC void rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) { RDI_U64 type_pos = rdim_idx_from_type(type); + + if(type->kind == RDI_TypeKind_NULL) + { + type_indices[type_pos] = 0; + return; + } + if(type_indices[type_pos] == 0) { if(type->param_types) @@ -1186,6 +1331,8 @@ rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) RDI_PROC RDI_U64 * rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) { + ProfBeginFunction(); + RDI_U64 *type_indices = rdim_push_array(arena, RDI_U64, types->total_count + 1); RDI_U64 type_indices_count = 1; @@ -1197,6 +1344,7 @@ rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) } } + ProfEnd(); return type_indices; } @@ -3037,6 +3185,11 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId RDIM_Type *src = &n->v[chunk_idx]; U64 dst_idx = rdim_final_idx_from_type(type_indices, src); RDI_TypeNode *dst = &type_nodes[dst_idx]; + + if(src->kind == RDI_TypeKind_NULL) + { + continue; + } //- rjf: fill shared type node info dst->kind = src->kind; @@ -3327,7 +3480,7 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, } RDI_PROC U64 -rdim_bake_location(Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) +rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) { U64 location_data_off = location_data_blobs->total_size; diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 68887dc0..943b373f 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -595,6 +595,17 @@ struct RDIM_UnitChunkList //////////////////////////////// //~ rjf: Type System Node Types +typedef RDI_U32 RDIM_DataModel; +enum RDIM_DataModelEnum +{ + RDIM_DataModel_Null, + RDIM_DataModel_ILP32, + RDIM_DataModel_LLP64, + RDIM_DataModel_LP64, + RDIM_DataModel_ILP64, + RDIM_DataModel_SILP64 +}; + typedef struct RDIM_Type RDIM_Type; struct RDIM_Type { @@ -605,6 +616,7 @@ struct RDIM_Type RDI_U32 off; RDI_U32 count; RDIM_String8 name; + RDIM_String8 link_name; RDIM_Type *direct_type; RDIM_Type **param_types; struct RDIM_UDT *udt; @@ -1348,6 +1360,19 @@ RDI_PROC RDIM_SortKey *rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys //- rjf: rng1u64 list RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r); +//////////////////////////////// +//~ Data Model + +RDI_PROC RDI_TypeKind rdim_short_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_int_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_long_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model); + //////////////////////////////// //~ rjf: [Building] Binary Section Info Building diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index cbbec26a..bcec4915 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -994,439 +994,6 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) return 0; } -//////////////////////////////// -//~ rjf: Type Parsing/Conversion Tasks - -ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - P2R_ITypeFwdMapFillIn *in = (P2R_ITypeFwdMapFillIn *)input; - ProfScope("fill itype fwd map") for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) - { - //- rjf: skip if not in the actually stored itype range - if(itype < in->tpi_leaf->itype_first) - { - continue; - } - - //- rjf: determine if this itype resolves to another - CV_TypeId itype_fwd = 0; - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[itype-in->tpi_leaf->itype_first]; - CV_LeafKind kind = range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - if(range->off+range->hdr.size <= in->tpi_leaf->data.size && - range->off+2+header_struct_size <= in->tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - default:{}break; - - //- rjf: CLASS/STRUCTURE - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - { - // rjf: unpack leaf header - CV_LeafStruct *lf_struct = (CV_LeafStruct *)itype_leaf_first; - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_struct->props & CV_TypeProp_FwdRef) - { - // rjf: unpack rest of leaf - U8 *numeric_ptr = (U8 *)(lf_struct + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: lookup - B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && - ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: CLASS2/STRUCT2 - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: - { - // rjf: unpack leaf header - CV_LeafStruct2 *lf_struct = (CV_LeafStruct2 *)itype_leaf_first; - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_struct->props & CV_TypeProp_FwdRef) - { - // rjf: unpack rest of leaf - U8 *numeric_ptr = (U8 *)(lf_struct + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = (U8 *)numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: lookup - B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && - ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: UNION - case CV_LeafKind_UNION: - { - // rjf: unpack leaf - CV_LeafUnion *lf_union = (CV_LeafUnion *)itype_leaf_first; - U8 *numeric_ptr = (U8 *)(lf_union + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: has fwd ref flag -> lookup itype that this itype resolves tos - if(lf_union->props & CV_TypeProp_FwdRef) - { - B32 do_unique_name_lookup = (((lf_union->props & CV_TypeProp_Scoped) != 0) && - ((lf_union->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - // rjf: unpack leaf - CV_LeafEnum *lf_enum = (CV_LeafEnum*)itype_leaf_first; - U8 *name_ptr = (U8 *)(lf_enum + 1); - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_enum->props & CV_TypeProp_FwdRef) - { - B32 do_unique_name_lookup = (((lf_enum->props & CV_TypeProp_Scoped) != 0) && - ((lf_enum->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - } - } - - //- rjf: if the forwarded itype is nonzero & in TPI range -> save to map - if(itype_fwd != 0 && itype_fwd < in->tpi_leaf->itype_opl) - { - in->itype_fwd_map[itype] = itype_fwd; - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_itype_chain_build_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - Temp scratch = scratch_begin(&arena, 1); - P2R_ITypeChainBuildIn *in = (P2R_ITypeChainBuildIn *)input; - ProfScope("dependency itype chain build") - { - for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) - { - //- rjf: push initial itype - should be final-visited-itype for this itype - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = itype; - SLLStackPush(in->itype_chains[itype], c); - } - - //- rjf: skip basic types for dependency walk - if(itype < in->tpi_leaf->itype_first) - { - continue; - } - - //- rjf: walk dependent types, push to chain - P2R_TypeIdChain start_walk_task = {0, itype}; - P2R_TypeIdChain *first_walk_task = &start_walk_task; - P2R_TypeIdChain *last_walk_task = &start_walk_task; - for(P2R_TypeIdChain *walk_task = first_walk_task; - walk_task != 0; - walk_task = walk_task->next) - { - CV_TypeId walk_itype = in->itype_fwd_map[walk_task->itype] ? in->itype_fwd_map[walk_task->itype] : walk_task->itype; - if(walk_itype < in->tpi_leaf->itype_first) - { - continue; - } - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[walk_itype-in->tpi_leaf->itype_first]; - CV_LeafKind kind = range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - if(range->off+range->hdr.size <= in->tpi_leaf->data.size && - range->off+2+header_struct_size <= in->tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - default:{}break; - - //- rjf: MODIFIER - case CV_LeafKind_MODIFIER: - { - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: POINTER - case CV_LeafKind_POINTER: - { - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: PROCEDURE - case CV_LeafKind_PROCEDURE: - { - CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; - - // rjf: push return itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk return itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: push arg types to chain - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk arg types - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: MFUNCTION - case CV_LeafKind_MFUNCTION: - { - CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->arg_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->this_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->arg_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->this_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: push arg types to chain - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk arg types - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: BITFIELD - case CV_LeafKind_BITFIELD: - { - CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: ARRAY - case CV_LeafKind_ARRAY: - { - CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->entry_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->index_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->entry_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->index_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->base_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->base_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - } - } - } - } - } - scratch_end(scratch); - ProfEnd(); - return 0; -} - //////////////////////////////// //~ rjf: UDT Conversion Tasks @@ -1435,7 +1002,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; -#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); RDI_U64 udts_chunk_cap = 1024; ProfScope("convert UDT info") @@ -2073,21 +1640,21 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) Arena *arena = p2r_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; -#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) ////////////////////////// //- rjf: set up outputs for this sym stream // - U64 sym_procedures_chunk_cap = 1024; + U64 sym_procedures_chunk_cap = 1024; U64 sym_global_variables_chunk_cap = 1024; U64 sym_thread_variables_chunk_cap = 1024; - U64 sym_scopes_chunk_cap = 1024; - U64 sym_inline_sites_chunk_cap = 1024; - RDIM_SymbolChunkList sym_procedures = {0}; - RDIM_SymbolChunkList sym_global_variables = {0}; - RDIM_SymbolChunkList sym_thread_variables = {0}; - RDIM_ScopeChunkList sym_scopes = {0}; - RDIM_InlineSiteChunkList sym_inline_sites = {0}; + U64 sym_scopes_chunk_cap = 1024; + U64 sym_inline_sites_chunk_cap = 1024; + RDIM_SymbolChunkList sym_procedures = {0}; + RDIM_SymbolChunkList sym_global_variables = {0}; + RDIM_SymbolChunkList sym_thread_variables = {0}; + RDIM_ScopeChunkList sym_scopes = {0}; + RDIM_InlineSiteChunkList sym_inline_sites = {0}; ////////////////////////// //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) @@ -3298,9 +2865,9 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) //- rjf: join ipi/tpi hash/leaf parses // PDB_TpiHashParsed *tpi_hash = 0; - CV_LeafParsed *tpi_leaf = 0; + CV_LeafParsed *tpi_leaf = 0; PDB_TpiHashParsed *ipi_hash = 0; - CV_LeafParsed *ipi_leaf = 0; + CV_LeafParsed *ipi_leaf = 0; { tpi_hash = async_task_join_struct(tpi_hash_task, PDB_TpiHashParsed); tpi_leaf = async_task_join_struct(tpi_leaf_task, CV_LeafParsed); @@ -3309,546 +2876,551 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) } ////////////////////////////////////////////////////////////// - //- rjf: types pass 1: produce type forward resolution map - // - // this map is used to resolve usage of "incomplete structs" in codeview's - // type info. this often happens when e.g. "struct Foo" is used to refer to - // a later-defined "Foo", which actually contains members and so on. we want - // to hook types up to their actual destination complete types wherever - // possible, and so this map can be used to do that in subsequent stages. - // - CV_TypeId *itype_fwd_map = 0; - CV_TypeId itype_first = 0; - CV_TypeId itype_opl = 0; - if(tpi_leaf != 0 && in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: produce type forward resolution map") - { - //- rjf: allocate forward resolution map - itype_first = tpi_leaf->itype_first; - itype_opl = tpi_leaf->itype_opl; - itype_fwd_map = push_array(arena, CV_TypeId, (U64)itype_opl); - - //- rjf: kick off tasks to fill forward resolution map - U64 task_size_itypes = 1024; - U64 tasks_count = ((U64)itype_opl+(task_size_itypes-1))/task_size_itypes; - P2R_ITypeFwdMapFillIn *tasks_inputs = push_array(scratch.arena, P2R_ITypeFwdMapFillIn, tasks_count); - ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, tasks_count); - for(U64 idx = 0; idx < tasks_count; idx += 1) - { - tasks_inputs[idx].tpi_hash = tpi_hash; - tasks_inputs[idx].tpi_leaf = tpi_leaf; - tasks_inputs[idx].itype_first = idx*task_size_itypes; - tasks_inputs[idx].itype_opl = tasks_inputs[idx].itype_first + task_size_itypes; - tasks_inputs[idx].itype_opl = ClampTop(tasks_inputs[idx].itype_opl, itype_opl); - tasks_inputs[idx].itype_fwd_map = itype_fwd_map; - tasks[idx] = async_task_launch(scratch.arena, p2r_itype_fwd_map_fill_work, .input = &tasks_inputs[idx]); - } - - //- rjf: join all tasks - for(U64 idx = 0; idx < tasks_count; idx += 1) - { - async_task_join(tasks[idx]); - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: types pass 2: produce per-itype itype chain - // - // this pass is to ensure that subsequent passes always produce types for - // dependent itypes first - guaranteeing rdi's "only reference backward" - // rule (which eliminates cycles). each itype slot gets a list of itypes, - // starting with the deepest dependency - when types are produced per-itype, - // this chain is walked, so that deeper dependencies are built first, and - // as such, always show up *earlier* in the actually built types. - // - P2R_TypeIdChain **itype_chains = 0; - if(tpi_leaf != 0 && in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 2: produce per-itype itype chain (for producing dependent types first)") - { - //- rjf: allocate itype chain table - itype_chains = push_array(arena, P2R_TypeIdChain *, (U64)itype_opl); - - //- rjf: kick off tasks to fill itype chain table - U64 task_size_itypes = 1024; - U64 tasks_count = ((U64)itype_opl+(task_size_itypes-1))/task_size_itypes; - P2R_ITypeChainBuildIn *tasks_inputs = push_array(scratch.arena, P2R_ITypeChainBuildIn, tasks_count); - ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, tasks_count); - for(U64 idx = 0; idx < tasks_count; idx += 1) - { - tasks_inputs[idx].tpi_leaf = tpi_leaf; - tasks_inputs[idx].itype_first = idx*task_size_itypes; - tasks_inputs[idx].itype_opl = tasks_inputs[idx].itype_first + task_size_itypes; - tasks_inputs[idx].itype_opl = ClampTop(tasks_inputs[idx].itype_opl, itype_opl); - tasks_inputs[idx].itype_chains = itype_chains; - tasks_inputs[idx].itype_fwd_map = itype_fwd_map; - tasks[idx] = async_task_launch(scratch.arena, p2r_itype_chain_build_work, .input = &tasks_inputs[idx]); - } - - //- rjf: join all tasks - for(U64 idx = 0; idx < tasks_count; idx += 1) - { - async_task_join(tasks[idx]); - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: types pass 3: construct all types from TPI + //- rjf: types pass 1: construct all types from TPI // // this doesn't gather struct/class/union/enum members, which is done by // subsequent passes, to build RDI "UDT" information, which is distinct // from regular type info. // - RDIM_Type **itype_type_ptrs = 0; - RDIM_TypeChunkList all_types = {0}; -#define p2r_type_ptr_from_itype(itype) ((itype_type_ptrs && (itype) < itype_opl) ? (itype_type_ptrs[(itype_fwd_map[(itype)] ? itype_fwd_map[(itype)] : (itype))]) : 0) - if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 3: construct all root/stub types from TPI") + RDIM_Type **itype_type_ptrs = 0; + RDIM_TypeChunkList all_types = {0}; +#define p2r_type_ptr_from_itype(itype) (((itype) < tpi_leaf->itype_opl) ? itype_type_ptrs[itype] : 0) + if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") { - itype_type_ptrs = push_array(arena, RDIM_Type *, (U64)(itype_opl)); - for(CV_TypeId root_itype = 0; root_itype < itype_opl; root_itype += 1) + itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); + + ////////////////////////// + //- build basic type + // { - for(P2R_TypeIdChain *itype_chain = itype_chains[root_itype]; - itype_chain != 0; - itype_chain = itype_chain->next) + RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); + + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); + RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); + RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); + RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); + RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); + RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); + RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); + RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); + RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); + + struct { - CV_TypeId itype = (root_itype != itype_chain->itype && itype_chain->itype < itype_opl && itype_fwd_map[itype_chain->itype]) ? itype_fwd_map[itype_chain->itype] : itype_chain->itype; - B32 itype_is_basic = (itype < 0x1000); - - ////////////////////////// - //- rjf: skip forward-reference itypes - all future resolutions will - // reference whatever this itype resolves to, and so there is no point - // in filling out this slot - // - if(itype_fwd_map[root_itype] != 0) + char * name; + RDI_TypeKind kind_rdi; + CV_LeafKind kind_cv; + B32 make_pointer_near; + B32 make_pointer_32; + B32 make_pointer_64; + } + table[] = + { + { "" , RDI_TypeKind_NULL , CV_BasicType_NOTYPE , 0, 0, 0 }, + { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, + { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, + { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, + { "short" , short_type , CV_BasicType_SHORT , 1, 1, 1 }, + { "long" , long_type , CV_BasicType_LONG , 1, 1, 1 }, + { "long long" , long_long_type , CV_BasicType_QUAD , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT , 1, 1, 1 }, // Clang type + { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR , 1, 1, 1 }, + { "unsigned short" , ushort_type , CV_BasicType_USHORT , 1, 1, 1 }, + { "unsigned long" , ulong_type , CV_BasicType_ULONG , 1, 1, 1 }, + { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT , 1, 1, 1 }, // Clang type + { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 , 1, 1, 1 }, + { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 , 1, 1, 1 }, // not real C type + { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 , 1, 1, 1 }, // not real C type + { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 , 1, 1, 1 }, + { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 , 1, 1, 1 }, + { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 , 1, 1, 1 }, + { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 , 1, 1, 1 }, // Clang type + { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 , 1, 1, 1 }, // not real C type + { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP , 1, 1, 1 }, // not real C type + { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 , 0, 0, 0 }, + { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 , 0, 0, 0 }, + { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 , 0, 0, 0 }, + { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 , 0, 0, 0 }, + { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 , 1, 1, 1 }, + { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, + { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, + { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, + { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, + { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, + { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, + { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 , 1, 1, 1 }, + { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR , 1, 1, 1 }, // always ASCII + { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR , 1, 1, 1 }, // on windows always UTF-16 + { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 , 1, 1, 1 }, // always UTF-8 + { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 , 1, 1, 1 }, // always UTF-16 + { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 + { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } + }; + + for(U64 i = 0; i < ArrayCount(table); i += 1) + { + U64 builtin_size; + if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) { - continue; + builtin_size = arch_addr_size; } - - ////////////////////////// - //- rjf: skip already produced dependencies - // - if(itype_type_ptrs[itype] != 0) + else { - continue; + builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); } - - ////////////////////////// - //- rjf: build basic type - // - if(itype_is_basic) + + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + builtin->kind = table[i].kind_rdi; + builtin->name = str8_cstring(table[i].name); + builtin->byte_size = builtin_size; + + itype_type_ptrs[table[i].kind_cv] = builtin; + + if(table[i].make_pointer_near) { - RDIM_Type *dst_type = 0; - - // rjf: unpack itype - CV_BasicPointerKind cv_basic_ptr_kind = CV_BasicPointerKindFromTypeId(itype); - CV_BasicType cv_basic_type_code = CV_BasicTypeFromTypeId(itype); - - // rjf: get basic type slot, fill if unfilled - RDIM_Type *basic_type = itype_type_ptrs[cv_basic_type_code]; - if(basic_type == 0) - { - RDI_TypeKind type_kind = p2r_rdi_type_kind_from_cv_basic_type(cv_basic_type_code); - U32 byte_size = rdi_size_from_basic_type_kind(type_kind); - basic_type = dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(byte_size == 0xffffffff) - { - byte_size = arch_addr_size; - } - basic_type->kind = type_kind; - basic_type->name = cv_type_name_from_basic_type(cv_basic_type_code); - basic_type->byte_size = byte_size; - } - - // rjf: nonzero ptr kind -> form ptr type to basic tpye - if(cv_basic_ptr_kind != 0) - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Ptr; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = basic_type; - } - - // rjf: fill this itype's slot with the finished type - itype_type_ptrs[itype] = dst_type; + CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; + RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_near->kind = RDI_TypeKind_Ptr; + ptr_near->byte_size = 2; + ptr_near->direct_type = builtin; + + itype_type_ptrs[near_ptr_itype] = ptr_near; } - - ////////////////////////// - //- rjf: build non-basic type - // - if(!itype_is_basic && itype >= itype_first) + if(table[i].make_pointer_32) { - RDIM_Type *dst_type = 0; - CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-itype_first]; - CV_LeafKind kind = range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - if(range->off+range->hdr.size <= tpi_leaf->data.size && - range->off+2+header_struct_size <= tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - //- rjf: MODIFIER - case CV_LeafKind_MODIFIER: - { - // rjf: unpack leaf - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: cv -> rdi flags - RDI_TypeModifierFlags flags = 0; - if(lf->flags & CV_ModifierFlag_Const) {flags |= RDI_TypeModifierFlag_Const;} - if(lf->flags & CV_ModifierFlag_Volatile) {flags |= RDI_TypeModifierFlag_Volatile;} - - // rjf: fill type - if(flags == 0) - { - dst_type = p2r_type_ptr_from_itype(lf->itype); - } - else - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Modifier; - dst_type->flags = flags; - dst_type->direct_type = p2r_type_ptr_from_itype(lf->itype); - dst_type->byte_size = dst_type->direct_type ? dst_type->direct_type->byte_size : 0; - } - }break; - - //- rjf: POINTER - case CV_LeafKind_POINTER: - { - // TODO(rjf): if ptr_mode in {PtrMem, PtrMethod} then output a member pointer instead - - // rjf: unpack leaf - CV_LeafPointer *lf = (CV_LeafPointer *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); - CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(lf->attribs); - CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(lf->attribs); - U32 ptr_size = CV_PointerAttribs_Extract_Size(lf->attribs); - - // rjf: cv -> rdi modifier flags - RDI_TypeModifierFlags modifier_flags = 0; - if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} - if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} - if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} - - // rjf: cv info -> rdi pointer type kind - RDI_TypeKind type_kind = RDI_TypeKind_Ptr; - { - if(lf->attribs & CV_PointerAttrib_LRef) - { - type_kind = RDI_TypeKind_LRef; - } - else if(lf->attribs & CV_PointerAttrib_RRef) - { - type_kind = RDI_TypeKind_RRef; - } - if(ptr_mode == CV_PointerMode_LRef) - { - type_kind = RDI_TypeKind_LRef; - } - else if(ptr_mode == CV_PointerMode_RRef) - { - type_kind = RDI_TypeKind_RRef; - } - } - - // rjf: fill type - if(modifier_flags != 0) - { - RDIM_Type *pointer_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Modifier; - dst_type->flags = modifier_flags; - dst_type->direct_type = pointer_type; - dst_type->byte_size = arch_addr_size; - pointer_type->kind = type_kind; - pointer_type->byte_size = arch_addr_size; - pointer_type->direct_type = direct_type; - } - else - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = type_kind; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = direct_type; - } - }break; - - //- rjf: PROCEDURE - case CV_LeafKind_PROCEDURE: - { - // TODO(rjf): handle call_kind & attribs - - // rjf: unpack leaf - CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; - RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); - - // rjf: fill type's basics - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Function; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = ret_type; - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: build param type array - RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count); - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - params[idx] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); - } - - // rjf: fill dst type - dst_type->count = arglist_itypes_count; - dst_type->param_types = params; - }break; - - //- rjf: MFUNCTION - case CV_LeafKind_MFUNCTION: - { - // TODO(rjf): handle call_kind & attribs - // TODO(rjf): preserve "this_adjust" - - // rjf: unpack leaf - CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; - RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = (lf->this_itype != 0) ? RDI_TypeKind_Method : RDI_TypeKind_Function; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = ret_type; - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: build param type array - U64 num_this_extras = 1; - if(lf->this_itype == 0) - { - num_this_extras = 0; - } - RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count+num_this_extras); - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - params[idx+num_this_extras] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); - } - if(lf->this_itype != 0) - { - params[0] = p2r_type_ptr_from_itype(lf->this_itype); - } - - // rjf: fill dst type - dst_type->count = arglist_itypes_count+num_this_extras; - dst_type->param_types = params; - }break; - - //- rjf: BITFIELD - case CV_LeafKind_BITFIELD: - { - // rjf: unpack leaf - CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Bitfield; - dst_type->off = lf->pos; - dst_type->count = lf->len; - dst_type->byte_size = direct_type?direct_type->byte_size:0; - dst_type->direct_type = direct_type; - }break; - - //- rjf: ARRAY - case CV_LeafKind_ARRAY: - { - // rjf: unpack leaf - CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->entry_itype); - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed array_count = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 full_size = cv_u64_from_numeric(&array_count); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Array; - dst_type->direct_type = direct_type; - dst_type->byte_size = full_size; - dst_type->count = (direct_type && direct_type->byte_size) ? (dst_type->byte_size/direct_type->byte_size) : 0; - }break; - - //- rjf: CLASS/STRUCTURE - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); - dst_type->name = name; - } - else - { - dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); - dst_type->byte_size = (U32)size_u64; - dst_type->name = name; - } - }break; - - //- rjf: CLASS2/STRUCT2 - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); - dst_type->name = name; - } - else - { - dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_Class : RDI_TypeKind_Struct); - dst_type->byte_size = (U32)size_u64; - dst_type->name = name; - } - }break; - - //- rjf: UNION - case CV_LeafKind_UNION: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = RDI_TypeKind_IncompleteUnion; - dst_type->name = name; - } - else - { - dst_type->kind = RDI_TypeKind_Union; - dst_type->byte_size = (U32)size_u64; - dst_type->name = name; - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->base_itype); - U8 *name_ptr = (U8 *)(lf + 1); - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = RDI_TypeKind_IncompleteEnum; - dst_type->name = name; - } - else - { - dst_type->kind = RDI_TypeKind_Enum; - dst_type->direct_type = direct_type; - dst_type->byte_size = direct_type ? direct_type->byte_size : 0; - dst_type->name = name; - } - }break; - } - } - - //- rjf: store finalized type to this itype's slot - itype_type_ptrs[itype] = dst_type; + CV_TypeIndex ptr_32_itype = table[i].kind_cv | 0x400; + RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_32->kind = RDI_TypeKind_Ptr; + ptr_32->byte_size = 4; + ptr_32->direct_type = builtin; + + itype_type_ptrs[ptr_32_itype] = ptr_32; + } + if(table[i].make_pointer_64) + { + CV_TypeIndex ptr_64_itype = table[i].kind_cv | 0x600; + RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_64->kind = RDI_TypeKind_Ptr; + ptr_64->byte_size = 8; + ptr_64->direct_type = builtin; + + itype_type_ptrs[ptr_64_itype] = ptr_64; } } } + + ////////////////////////// + //- rjf: build non-basic type + // + for(CV_TypeId itype = tpi_leaf->itype_first; itype < tpi_leaf->itype_opl; itype += 1) + { + RDIM_Type *dst_type = 0; + CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + + if(range->off+range->hdr.size <= tpi_leaf->data.size && + range->off+2+header_struct_size <= tpi_leaf->data.size && + range->hdr.size >= 2) + { + U8 *itype_leaf_first = tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + switch(kind) + { + //- rjf: MODIFIER + case CV_LeafKind_MODIFIER: + { + // rjf: unpack leaf + CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; + + // rjf: cv -> rdi flags + RDI_TypeModifierFlags flags = 0; + if(lf->flags & CV_ModifierFlag_Const) {flags |= RDI_TypeModifierFlag_Const;} + if(lf->flags & CV_ModifierFlag_Volatile) {flags |= RDI_TypeModifierFlag_Volatile;} + + // rjf: fill type + if(flags == 0) + { + dst_type = p2r_type_ptr_from_itype(lf->itype); + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = flags; + dst_type->direct_type = p2r_type_ptr_from_itype(lf->itype); + dst_type->byte_size = dst_type->direct_type ? dst_type->direct_type->byte_size : 0; + } + }break; + + //- rjf: POINTER + case CV_LeafKind_POINTER: + { + // TODO(rjf): if ptr_mode in {PtrMem, PtrMethod} then output a member pointer instead + + // rjf: unpack leaf + CV_LeafPointer *lf = (CV_LeafPointer *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(lf->attribs); + CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(lf->attribs); + U32 ptr_size = CV_PointerAttribs_Extract_Size(lf->attribs); + + // rjf: cv -> rdi modifier flags + RDI_TypeModifierFlags modifier_flags = 0; + if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} + if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} + if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} + + // rjf: cv info -> rdi pointer type kind + RDI_TypeKind type_kind = RDI_TypeKind_Ptr; + { + if(lf->attribs & CV_PointerAttrib_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(lf->attribs & CV_PointerAttrib_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + if(ptr_mode == CV_PointerMode_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(ptr_mode == CV_PointerMode_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + } + + // rjf: fill type + if(modifier_flags != 0) + { + RDIM_Type *pointer_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = modifier_flags; + dst_type->direct_type = pointer_type; + dst_type->byte_size = arch_addr_size; + pointer_type->kind = type_kind; + pointer_type->byte_size = arch_addr_size; + pointer_type->direct_type = direct_type; + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = type_kind; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = direct_type; + } + }break; + + //- rjf: PROCEDURE + case CV_LeafKind_PROCEDURE: + { + // TODO(rjf): handle call_kind & attribs + + // rjf: unpack leaf + CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type's basics + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count; + dst_type->param_types = params; + }break; + + //- rjf: MFUNCTION + case CV_LeafKind_MFUNCTION: + { + // TODO(rjf): handle call_kind & attribs + // TODO(rjf): preserve "this_adjust" + + // rjf: unpack leaf + CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = (lf->this_itype != 0) ? RDI_TypeKind_Method : RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + U64 num_this_extras = 1; + if(lf->this_itype == 0) + { + num_this_extras = 0; + } + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count+num_this_extras); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx+num_this_extras] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + if(lf->this_itype != 0) + { + params[0] = p2r_type_ptr_from_itype(lf->this_itype); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count+num_this_extras; + dst_type->param_types = params; + }break; + + //- rjf: BITFIELD + case CV_LeafKind_BITFIELD: + { + // rjf: unpack leaf + CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Bitfield; + dst_type->off = lf->pos; + dst_type->count = lf->len; + dst_type->byte_size = direct_type?direct_type->byte_size:0; + dst_type->direct_type = direct_type; + }break; + + //- rjf: ARRAY + case CV_LeafKind_ARRAY: + { + // rjf: unpack leaf + CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->entry_itype); + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed array_count = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 full_size = cv_u64_from_numeric(&array_count); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Array; + dst_type->direct_type = direct_type; + dst_type->byte_size = full_size; + }break; + + //- rjf: CLASS/STRUCTURE + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + + dst_type->name = name; + dst_type->byte_size = safe_cast_u32(size_u64); + }break; + + //- rjf: CLASS2/STRUCT2 + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + dst_type->name = name; + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + + //- rjf: UNION + case CV_LeafKind_UNION: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteUnion; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Union; + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + + //- rjf: ENUM + case CV_LeafKind_ENUM: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->base_itype); + U8 *name_ptr = (U8 *)(lf + 1); + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteEnum; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Enum; + dst_type->direct_type = direct_type; + dst_type->byte_size = direct_type ? direct_type->byte_size : 0; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + } + } + + //- rjf: store finalized type to this itype's slot + itype_type_ptrs[itype] = dst_type; + } } ////////////////////////////////////////////////////////////// - //- rjf: types pass 4: kick off UDT build + //- rjf: types pass 2: kick off UDT build // U64 udt_task_size_itypes = 4096; - U64 udt_tasks_count = ((U64)itype_opl+(udt_task_size_itypes-1))/udt_task_size_itypes; + U64 udt_tasks_count = (tpi_leaf->itype_opl+(udt_task_size_itypes-1))/udt_task_size_itypes; P2R_UDTConvertIn *udt_tasks_inputs = push_array(scratch.arena, P2R_UDTConvertIn, udt_tasks_count); ASYNC_Task **udt_tasks = push_array(scratch.arena, ASYNC_Task *, udt_tasks_count); - if(in->flags & P2R_ConvertFlag_UDTs) ProfScope("types pass 4: kick off UDT build") + if(in->flags & P2R_ConvertFlag_UDTs) ProfScope("types pass 2: kick off UDT build") { for(U64 idx = 0; idx < udt_tasks_count; idx += 1) { udt_tasks_inputs[idx].tpi_leaf = tpi_leaf; udt_tasks_inputs[idx].itype_first = idx*udt_task_size_itypes; udt_tasks_inputs[idx].itype_opl = udt_tasks_inputs[idx].itype_first + udt_task_size_itypes; - udt_tasks_inputs[idx].itype_opl = ClampTop(udt_tasks_inputs[idx].itype_opl, itype_opl); - udt_tasks_inputs[idx].itype_fwd_map = itype_fwd_map; + udt_tasks_inputs[idx].itype_opl = ClampTop(udt_tasks_inputs[idx].itype_opl, tpi_leaf->itype_opl); udt_tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; udt_tasks[idx] = async_task_launch(scratch.arena, p2r_udt_convert_work, .input = &udt_tasks_inputs[idx]); } @@ -3907,7 +3479,6 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) tasks_inputs[idx].tpi_hash = tpi_hash; tasks_inputs[idx].tpi_leaf = tpi_leaf; tasks_inputs[idx].ipi_leaf = ipi_leaf; - tasks_inputs[idx].itype_fwd_map = itype_fwd_map; tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; tasks_inputs[idx].link_name_map = link_name_map; if(idx < global_stream_subdivision_tasks_count) diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index 03cae2d2..f9effda5 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -201,37 +201,6 @@ struct P2R_LinkNameMapBuildIn P2R_LinkNameMap *link_name_map; }; -//- rjf: type forward resolution map build - -typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn; -struct P2R_ITypeFwdMapFillIn -{ - PDB_TpiHashParsed *tpi_hash; - CV_LeafParsed *tpi_leaf; - CV_TypeId itype_first; - CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; -}; - -//- rjf: itype chain build - -typedef struct P2R_TypeIdChain P2R_TypeIdChain; -struct P2R_TypeIdChain -{ - P2R_TypeIdChain *next; - CV_TypeId itype; -}; - -typedef struct P2R_ITypeChainBuildIn P2R_ITypeChainBuildIn; -struct P2R_ITypeChainBuildIn -{ - CV_LeafParsed *tpi_leaf; - CV_TypeId itype_first; - CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; - P2R_TypeIdChain **itype_chains; -}; - //- rjf: udt conversion typedef struct P2R_UDTConvertIn P2R_UDTConvertIn; @@ -240,7 +209,6 @@ struct P2R_UDTConvertIn CV_LeafParsed *tpi_leaf; CV_TypeId itype_first; CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; RDIM_Type **itype_type_ptrs; }; @@ -257,7 +225,6 @@ struct P2R_SymbolStreamConvertIn CV_SymParsed *sym; U64 sym_ranges_first; U64 sym_ranges_opl; - CV_TypeId *itype_fwd_map; RDIM_Type **itype_type_ptrs; P2R_LinkNameMap *link_name_map; RDIM_LineTable *first_inline_site_line_table; @@ -341,12 +308,6 @@ ASYNC_WORK_DEF(p2r_units_convert_work); ASYNC_WORK_DEF(p2r_link_name_map_build_work); -//////////////////////////////// -//~ rjf: Type Parsing/Conversion Tasks - -ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work); -ASYNC_WORK_DEF(p2r_itype_chain_build_work); - //////////////////////////////// //~ rjf: UDT Conversion Tasks diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index 8b24e350..d2fc8707 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -15,6 +15,9 @@ #include "lib_rdi_format/rdi_format.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" +#define XXH_STATIC_LINKING_ONLY +#include "third_party/xxHash/xxhash.h" +#include "third_party/xxHash/xxhash.c" //- rjf: [h] #include "base/base_inc.h" diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c index 28d27f22..d3b039ac 100644 --- a/src/rdi_make/rdi_make_help.c +++ b/src/rdi_make/rdi_make_help.c @@ -1,6 +1,40 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// + +internal RDIM_DataModel +rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) +{ + RDIM_DataModel data_model = RDIM_DataModel_Null; + switch (os) { + case OperatingSystem_Null: break; + case OperatingSystem_Windows: { + switch (arch) { + case RDI_Arch_X86: + case RDI_Arch_X64: + data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Linux: { + switch (arch) { + case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Mac: { + switch (arch) { + case RDI_Arch_X86: NotImplemented; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; + } + } break; + default: InvalidPath; + } + return data_model; +} + //////////////////////////////// //~ rjf: Baking Stage Tasks @@ -382,6 +416,154 @@ ASYNC_WORK_DEF(rdim_bake_idx_runs_work) return out; } +internal U64 +rdim_help_hash(RDIM_String8 string) +{ + return XXH3_64bits(string.str, string.size); +} + +internal void +rdim_help_resolve_incomplete_types(RDIM_TypeChunkList *types) +{ + ProfBeginFunction(); + + Temp scratch = scratch_begin(0,0); + + ProfBegin("Build Hash Table"); + RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + if(RDI_TypeKind_FirstUserDefined <= type->kind && type->kind <= RDI_TypeKind_LastRecord) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_help_hash(name); + + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + do + { + RDIM_Type *s = name_ht[slot]; + if(s == 0) + { + break; + } + + if(s->link_name.size) + { + if(str8_match(s->link_name, name, 0)) + { + break; + } + } + else if(s->name.size) + { + if(str8_match(s->name, type->name, 0)) + { + break; + } + } + + slot = (slot + 1) % types->total_count; + } while (slot != best_slot); + + if(name_ht[slot] == 0) + { + name_ht[slot] = type; + } + } + } + } + ProfEnd(); + + ProfBegin("Make Fwd Map"); + RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + + if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_help_hash(name); + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + + RDIM_Type *match = 0; + do + { + if(name_ht[slot] == 0) + { + break; + } + RDIM_Type *s = name_ht[slot]; + if(s->link_name.size) + { + if(str8_match(s->link_name, type->link_name, 0)) + { + match = s; + break; + } + } + else + { + if(str8_match(s->name, type->name, 0)) + { + match = s; + break; + } + } + } while(slot != best_slot); + + if(match) + { + type->kind = RDI_TypeKind_NULL; + + RDI_U64 type_idx = rdim_idx_from_type(type); + fwd_map[type_idx] = match; + } + } + } + } + ProfEnd(); + + ProfBegin("Resolve Types"); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; ++i) + { + RDIM_Type *t = &chunk->v[i]; + if(t->direct_type) + { + RDI_U64 direct_idx = rdim_idx_from_type(t->direct_type); + if(fwd_map[direct_idx]) + { + t->direct_type = fwd_map[direct_idx]; + } + } + if(t->param_types) + { + for(RDI_U64 param_idx = 0; param_idx < t->count; param_idx += 1) + { + RDI_U64 type_idx = rdim_idx_from_type(t->param_types[param_idx]); + if(fwd_map[type_idx]) + { + t->param_types[param_idx] = fwd_map[type_idx]; + } + } + } + } + } + ProfEnd(); + + scratch_end(scratch); + ProfEnd(); +} + internal RDIM_HelpState * rdim_help_init(void) { @@ -405,6 +587,11 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) rdim_help_state = state; + //////////////////////////////// + // resolve incomplete types + + rdim_help_resolve_incomplete_types(&in_params->types); + //////////////////////////////// // compute type indices diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h index 08c64391..d8b28160 100644 --- a/src/rdi_make/rdi_make_help.h +++ b/src/rdi_make/rdi_make_help.h @@ -281,6 +281,10 @@ struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunMap *idx_runs; }; +//////////////////////////////// + +internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); + //////////////////////////////// //~ rjf: Baking Stage Tasks From 41aa23b71ba7cc010a1e4d5a3915429b01765bd4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Mar 2025 09:54:48 -0700 Subject: [PATCH 206/755] work on hover eval visualizers; skip watch window level if all we're doing is spawning a visualizer at the top-level; more convergence / cleanup / fixes --- src/raddbg/raddbg_core.c | 237 +++++++++++++++++++++++------------- src/raddbg/raddbg_widgets.c | 2 +- 2 files changed, 154 insertions(+), 85 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e40062b1..ad93dbc0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5248,10 +5248,10 @@ rd_view_ui(Rng2F32 rect) UI_Flags(0) { // rjf: 'pull out' button - UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) UI_CornerRadius(ui_top_font_size()*1.5f) UI_TextAlignment(UI_TextAlign_Center) UI_HoverCursor(OS_Cursor_HandPoint) @@ -7486,6 +7486,7 @@ rd_window_frame(void) String8 cmd_name = ws->query_cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); + B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); //- rjf: build & prepare view for query ui RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); @@ -7607,7 +7608,7 @@ rd_window_frame(void) } //- rjf: build darkening rectangle over rest of screen - UI_Rect(window_rect) UI_TagF("inactive") + if(!query_is_anchored) UI_Rect(window_rect) UI_TagF("inactive") { ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); } @@ -8429,6 +8430,10 @@ rd_window_frame(void) build_hover_eval = 0; } + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + // rjf: reset open animation if(ws->hover_eval_string.size == 0) { @@ -8456,98 +8461,162 @@ rd_window_frame(void) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") { + // rjf: build cfg tree for temporary view + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } F32 hover_eval_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_open_t"), 1.f); RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(view, str8_lit("selected")); rd_cfg_new(explicit_root, str8_lit("1")); - RD_RegsScope(.view = view->id) + rd_cfg_new_replace(expr, hover_eval_expr); + + // rjf: push view regs + rd_push_regs(.view = view->id); { - rd_cfg_new_replace(expr, hover_eval_expr); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); + F32 width_px = 60.f*ui_top_font_size(); + F32 height_px = num_rows_t*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = 40.f*ui_top_font_size(); + } + + // rjf: build container + UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + { + // rjf: build top-level container box + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + ui_set_next_fixed_x(rect.x0); + ui_set_next_fixed_y(rect.y0); + ui_set_next_pref_width(ui_px(rect.x1-rect.x0, 1.f)); + ui_set_next_pref_height(ui_px(rect.y1-rect.y0, 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + ui_set_next_squish(0.25f-0.25f*hover_eval_t); + ui_set_next_transparency(1.f-hover_eval_t); + UI_Box *container = ui_build_box_from_string(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow, + str8_lit("hover_eval_container")); + + // rjf: peek press events -> focus hover eval if we have a press + if(!ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + contains_2f32(container->rect, evt->pos)) + { + ws->hover_eval_focused = 1; + break; + } + } + } + + // rjf: build overlay container for loading animation + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(container) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + // rjf: build contents + UI_Parent(container) UI_Focus(ws->hover_eval_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(rect); + } + } + + // rjf: build loading overlay + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + F32 loading_t = vs->loading_t; + if(loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + // rjf: interact with container + UI_Signal sig = ui_signal_from_box(container); + if(ui_pressed(sig)) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_last_frame_idx = rd_state->frame_index; + } + else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) + { + rd_request_frame(); + } if(ws->hover_eval_focused) { - max_row_count *= 3; - } - U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); - - // rjf: build container - UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) - UI_PrefHeight(ui_px(row_height_px, 1.f)) - { - ui_set_next_fixed_x(ws->hover_eval_spawn_pos.x); - ui_set_next_fixed_y(ws->hover_eval_spawn_pos.y); - ui_set_next_pref_width(ui_em(60.f, 1.f)); - ui_set_next_pref_height(ui_px(num_rows_t*row_height_px, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_squish(0.25f-0.25f*hover_eval_t); - ui_set_next_transparency(1.f-hover_eval_t); - UI_Box *container = ui_build_box_from_string(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow, - str8_lit("hover_eval_container")); - if(!ws->hover_eval_focused) + for(UI_Event *evt = 0; ui_next_event(&evt);) { - for(UI_Event *evt = 0; ui_next_event(&evt);) + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + !contains_2f32(container->rect, evt->pos)) { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 1; - break; - } - } - } - UI_Parent(container) UI_Focus(ws->hover_eval_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - { - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_WidthFill - { - rd_view_ui(view_contents_container->rect); - } - } - UI_Signal sig = ui_signal_from_box(container); - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_mouse_over(sig) || ws->hover_eval_focused) - { - ws->hover_eval_last_frame_idx = rd_state->frame_index; - } - else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) - { - rd_request_frame(); - } - if(ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - !contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 0; - MemoryZeroStruct(&ws->hover_eval_string); - arena_clear(ws->hover_eval_arena); - rd_request_frame(); - break; - } + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + break; } } } } + + // rjf: pop interaction registers; commit if this is the selected view + RD_Regs *view_regs = rd_pop_regs(); + if(ws->hover_eval_focused) + { + MemoryCopyStruct(rd_regs(), view_regs); + } } } @@ -9320,7 +9389,7 @@ rd_window_frame(void) //- rjf: pop interaction registers; commit if this is the selected view RD_Regs *view_regs = rd_pop_regs(); - if(panel_tree.focused == panel) + if(panel_is_focused) { MemoryCopyStruct(rd_regs(), view_regs); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 6717155d..6c12ce3c 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -598,7 +598,7 @@ rd_title_fstrs_from_file_path(Arena *arena, String8 file_path) internal void rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_target) { - if(loading_t >= 0.001f) + if(loading_t >= 0.001f) UI_Focus(UI_FocusKind_Off) { // rjf: set up dimensions F32 edge_padding = 30.f; From 24ddab0db2933b2f571a7474f02ab24743e1510e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Mar 2025 12:41:48 -0700 Subject: [PATCH 207/755] fix slice view rule to apply correctly to pointers/refs->structs too --- src/base/base_context_cracking.h | 2 +- src/eval/eval_ir.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index ba452a5a..62a6881f 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -159,7 +159,7 @@ #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 15 +# define BUILD_VERSION_PATCH 16 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 00c87283..bdb88716 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -368,11 +368,27 @@ E_LOOKUP_INFO_FUNCTION_DEF(slice) E_LookupInfo info = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_TypeKind type_kind = e_type_kind_from_key(lhs->type_key); + + // rjf: unpack struct type + E_TypeKey struct_type_key = e_type_unwrap(lhs->type_key); + for(;;) + { + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key))) + { + struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key)); + } + else + { + break; + } + } + + // rjf: build info from struct type + E_TypeKind type_kind = e_type_kind_from_key(struct_type_key); if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) { // rjf: unpack members - E_MemberArray members = e_type_data_members_from_key__cached(lhs->type_key); + E_MemberArray members = e_type_data_members_from_key__cached(struct_type_key); // rjf: choose base pointer & count members E_Member *base_ptr_member = 0; From cb6a66b98d0606e1e4569c126bae87df09af64d6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Mar 2025 13:27:26 -0700 Subject: [PATCH 208/755] member filtering, better visualization for selection state in targets/bps/threads/etc. --- src/eval/eval_ir.c | 10 ++-- src/eval/eval_ir.h | 2 +- src/eval/eval_types.c | 51 +++++++++++++++++++ src/eval/eval_types.h | 18 +++++++ .../eval_visualization_core.c | 4 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 4 +- src/raddbg/raddbg_widgets.c | 17 +++++++ src/ui/ui_core.c | 2 +- 10 files changed, 99 insertions(+), 13 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index bdb88716..3113346f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -500,7 +500,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(slice) { if(user_data == 0) { - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, idx_range, exprs, exprs_strings, user_data); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); } else { @@ -536,7 +536,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) direct_type_kind == E_TypeKind_Class || direct_type_kind == E_TypeKind_Union) { - E_MemberArray data_members = e_type_data_members_from_key__cached(direct_type_key); + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); lookup_info.named_expr_count = data_members.count; } else if(direct_type_kind == E_TypeKind_Enum) @@ -550,7 +550,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(default) lhs_type_kind == E_TypeKind_Class || lhs_type_kind == E_TypeKind_Union) { - E_MemberArray data_members = e_type_data_members_from_key__cached(lhs_type_key); + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(lhs_type_key, filter); lookup_info.named_expr_count = data_members.count; } else if(lhs_type_kind == E_TypeKind_Enum) @@ -880,7 +880,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) //- rjf: struct case -> the lookup-range will return a range of members if(do_struct_range) { - E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); Rng1U64 legal_idx_range = r1u64(0, data_members.count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -1083,7 +1083,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) { if(user_data == 0) { - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, idx_range, exprs, exprs_strings, user_data); + E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); } else { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index c2c87531..d06cb232 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -86,7 +86,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(default); typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); E_LOOKUP_ACCESS_FUNCTION_DEF(default); -#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) #define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name #define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6a4195e0..ef07ee7f 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1935,6 +1935,8 @@ e_member_cache_node_from_type_key(E_TypeKey key) node->members = e_type_data_members_from_key(e_type_state->arena, key); node->member_hash_slots_count = node->members.count; node->member_hash_slots = push_array(e_type_state->arena, E_MemberHashSlot, node->member_hash_slots_count); + node->member_filter_slots_count = 16; + node->member_filter_slots = push_array(e_type_state->arena, E_MemberFilterSlot, node->member_filter_slots_count); for EachIndex(idx, node->members.count) { U64 hash = e_hash_from_string(5381, node->members.v[idx].name); @@ -1947,6 +1949,55 @@ e_member_cache_node_from_type_key(E_TypeKey key) return node; } +internal E_MemberArray +e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) +{ + E_MemberArray members = {0}; + E_MemberCacheNode *node = e_member_cache_node_from_type_key(key); + if(node != 0) + { + if(filter.size == 0) + { + members = node->members; + } + else + { + U64 hash = e_hash_from_string(5381, filter); + U64 slot_idx = hash%node->member_filter_slots_count; + E_MemberFilterSlot *slot = &node->member_filter_slots[slot_idx]; + E_MemberFilterNode *filter_node = 0; + for(E_MemberFilterNode *n = slot->first; n != 0; n = n->next) + { + if(str8_match(n->filter, filter, 0)) + { + filter_node = n; + break; + } + } + if(filter_node == 0) + { + Temp scratch = scratch_begin(0, 0); + filter_node = push_array(e_type_state->arena, E_MemberFilterNode, 1); + filter_node->filter = push_str8_copy(e_type_state->arena, filter); + E_MemberList member_list__filtered = {0}; + for EachIndex(idx, node->members.count) + { + E_Member *member = &node->members.v[idx]; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, member->name); + if(matches.count == matches.needle_part_count) + { + e_member_list_push(scratch.arena, &member_list__filtered, member); + } + } + filter_node->members_filtered = e_member_array_from_list(e_type_state->arena, &member_list__filtered); + scratch_end(scratch); + } + members = filter_node->members_filtered; + } + } + return members; +} + internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index e59c09c4..2ca62b9f 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -234,6 +234,21 @@ struct E_MemberHashSlot E_MemberHashNode *last; }; +typedef struct E_MemberFilterNode E_MemberFilterNode; +struct E_MemberFilterNode +{ + E_MemberFilterNode *next; + String8 filter; + E_MemberArray members_filtered; +}; + +typedef struct E_MemberFilterSlot E_MemberFilterSlot; +struct E_MemberFilterSlot +{ + E_MemberFilterNode *first; + E_MemberFilterNode *last; +}; + typedef struct E_MemberCacheNode E_MemberCacheNode; struct E_MemberCacheNode { @@ -242,6 +257,8 @@ struct E_MemberCacheNode E_MemberArray members; U64 member_hash_slots_count; E_MemberHashSlot *member_hash_slots; + U64 member_filter_slots_count; + E_MemberFilterSlot *member_filter_slots; }; typedef struct E_MemberCacheSlot E_MemberCacheSlot; @@ -381,6 +398,7 @@ internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 internal E_Type *e_type_from_key__cached(E_TypeKey key); internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); +internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 39dc30ba..1b2787a6 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -712,7 +712,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Expr *child_expr = &e_expr_nil; String8 child_string = {0}; - lookup_rule->range(arena, t->expr, lookup_rule_tag, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); + lookup_rule->range(arena, t->expr, lookup_rule_tag, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; @@ -1003,7 +1003,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } else { - n->v.block->lookup_rule->range(arena, n->v.block->expr, n->v.block->lookup_tag, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + n->v.block->lookup_rule->range(arena, n->v.block->expr, n->v.block->lookup_tag, filter, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); } // rjf: no expansion operator applied -> push row for block expression; pass through block info diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 9dad2728..7ea36428 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -308,7 +308,7 @@ RD_VocabInfo rd_vocab_info_table[297] = RD_NameSchemaInfo rd_name_schema_info_table[12] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, select_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f3058905..42feaf07 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -156,7 +156,7 @@ RD_VocabTable: { target, ``` - @commands(launch_and_run, launch_and_init, select_cfg, remove_cfg) + @commands(launch_and_run, launch_and_init, enable_cfg, remove_cfg) @collection_commands(add_target) x: { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ad93dbc0..1d386e02 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10628,7 +10628,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) @@ -10772,7 +10772,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { E_Expr *expr = &e_expr_nil; String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); + lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); if(expr != &e_expr_nil) { if(!is_first) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 6c12ce3c..bad4f9ec 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -97,6 +97,12 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) B32 running_is_secondary = 0; #define start_secondary() if(!running_is_secondary){running_is_secondary = 1; params.color = rgba_secondary; params.size = ui_top_font_size()*0.95f;} + //- rjf: disabled? -> soften color + if(is_disabled) + { + params.color = rgba_secondary; + } + //- rjf: push icon if(icon_kind != RD_IconKind_Null) { @@ -430,6 +436,17 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } + //- rjf: push selected icon, if selected thread + if(entity->kind == CTRL_EntityKind_Thread) + { + B32 is_selected = ctrl_handle_match(entity->handle, rd_base_regs()->thread); + if(is_selected) + { + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + } + //- rjf: push containing process prefix if(entity->kind == CTRL_EntityKind_Thread || entity->kind == CTRL_EntityKind_Module) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 7e4ffacc..89490c01 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -3143,7 +3143,7 @@ ui_anim_(UI_Key key, UI_AnimParams *params) MemoryCopyStruct(&node->params, params); if(node->params.epsilon == 0) { - node->params.epsilon = 0.01f; + node->params.epsilon = 0.005f; } if(node->params.rate == 1) { From a4888055e2d96a42c29bb2a0ef991ef3e14ea830 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 14 Mar 2025 21:16:19 -0700 Subject: [PATCH 209/755] better disabled/conditional rendering of breakpoints --- src/raddbg/raddbg_core.c | 32 ++++++++++++++++++-------------- src/raddbg/raddbg_widgets.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1d386e02..1f47ae9b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5256,6 +5256,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(UI_TextAlign_Center) UI_HoverCursor(OS_Cursor_HandPoint) RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()*0.8f) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_Floating| @@ -9447,6 +9448,7 @@ rd_window_frame(void) F32 max_tab_width_px = ui_top_font_size()*20.f; if(build_panel) { + B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { RD_Cfg *tab = n->v; @@ -9457,8 +9459,9 @@ rd_window_frame(void) TabTask *t = push_array(scratch.arena, TabTask, 1); t->tab = tab; t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); - t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; - t->tab_width = Min(max_tab_width_px, t->tab_width); + F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + tab_width_target = Min(max_tab_width_px, tab_width_target); + t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0)); SLLQueuePush(first_tab_task, last_tab_task, t); tab_task_count += 1; } @@ -16362,25 +16365,26 @@ Z(getting_started) } if(file_path.size != 0 || expr.size != 0) { - B32 removed_already_existing = 0; - if(kind == RD_CmdKind_ToggleBreakpoint) + B32 already_exists = 0; + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) { - RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); - for(RD_CfgNode *n = bps.first; n != 0; n = n->next) + RD_Cfg *bp = n->v; + RD_Cfg *cnd = rd_cfg_child_from_string(bp, str8_lit("condition")); + RD_Location loc = rd_location_from_cfg(bp); + B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); + B32 loc_matches_expr = (expr.size != 0 && str8_match(expr, loc.expr, 0)); + if((loc_matches_file_pt || loc_matches_expr) && cnd->first->string.size == 0) { - RD_Cfg *bp = n->v; - RD_Location loc = rd_location_from_cfg(bp); - B32 loc_matches_file_pt = (file_path.size != 0 && path_match_normalized(loc.file_path, file_path) && loc.pt.line == pt.line); - B32 loc_matches_expr = (expr.size != 0 && str8_match(expr, loc.expr, 0)); - if(loc_matches_file_pt || loc_matches_expr) + if(kind == RD_CmdKind_ToggleBreakpoint) { rd_cfg_release(bp); - removed_already_existing = 1; - break; } + already_exists = 1; + break; } } - if(!removed_already_existing) + if(!already_exists) { RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index bad4f9ec..b39dbc6f 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1072,6 +1072,8 @@ struct RD_BreakpointBoxDrawExtData F32 remap_px_delta; B32 do_lines; B32 do_glow; + B32 is_disabled; + B32 is_conditioned; }; internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) @@ -1141,6 +1143,33 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) remap_color, rd_icon_kind_text_table[RD_IconKind_CircleFilled]); } + + // rjf: draw conditioned marker + if(u->is_conditioned) UI_TagF(u->is_disabled ? "weak" : "") + { + Temp scratch = scratch_begin(0, 0); + Vec4F32 color = ui_color_from_name(str8_lit("text")); + FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("?")); + Vec2F32 p = center_2f32(box->rect); + p.x -= run.dim.x*0.5f; + p.y += run.descent; + dr_text_run(p, color, run); + scratch_end(scratch); + } + + // rjf: draw disabled marker + if(u->is_disabled) + { + Temp scratch = scratch_begin(0, 0); + Vec4F32 color = ui_color_from_name(str8_lit("breakpoint")); + FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Icons), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("x")); + Vec2F32 box_dim = dim_2f32(box->rect); + Vec2F32 p = center_2f32(box->rect); + p.x += box_dim.x*0.1f; + p.y -= box_dim.y*0.2f; + dr_text_run(p, color, run); + scratch_end(scratch); + } } internal RD_CodeSliceSignal @@ -1554,6 +1583,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe bp_draw->hover_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "cfg_hover_t_%p", bp), (F32)!!is_hovering, .rate = entity_hover_t_rate); bp_draw->do_lines = do_bp_lines; bp_draw->do_glow = do_bp_glow; + bp_draw->is_disabled = bp_is_disabled; + bp_draw->is_conditioned = (rd_cfg_child_from_string(bp, str8_lit("condition"))->first->string.size != 0); if(params->line_vaddrs[line_idx] == 0) { D_LineList *lines = ¶ms->line_infos[line_idx]; From 41a252e5639a2c8c607aac9d9f64f09e8fed808d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 15 Mar 2025 11:42:20 -0700 Subject: [PATCH 210/755] notes on low-priority odd edge-case behavior --- src/raddbg/raddbg_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 7f340862..1573b936 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -28,6 +28,11 @@ // // [ ] r8 bitmap view rule seems incorrect? // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) +// +// [ ] stepping-onto a line with a conditional breakpoint, which fails, causes a +// single step over the first instruction of that line, even if the thread +// would've stopped at the first instruction due to the step, were that bp not +// there. //////////////////////////////// //~ rjf: post-0.9.12 TODO notes From 9c763c45542b5aadeb03ec71248bcec8bb5882e6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 17 Mar 2025 07:13:52 -0700 Subject: [PATCH 211/755] fix open-recent-project according to recent_project schema --- src/raddbg/raddbg_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1f47ae9b..1ee9adf8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14159,9 +14159,11 @@ rd_frame(void) case RD_CmdKind_OpenRecentProject: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); - if(str8_match(cfg->string, str8_lit("recent_project"), 0)) + RD_Cfg *path = rd_cfg_child_from_string(cfg, str8_lit("path")); + if(str8_match(cfg->string, str8_lit("recent_project"), 0) && + path->first->string.size != 0) { - rd_cmd(RD_CmdKind_OpenProject, .file_path = cfg->first->string); + rd_cmd(RD_CmdKind_OpenProject, .file_path = path->first->string); } }break; case RD_CmdKind_OpenUser: From 57208909f1251687026f32caaf74d6cb4d562027 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 17 Mar 2025 10:28:56 -0700 Subject: [PATCH 212/755] updated DWARF expression printer, added ELF preamble, transitioned debug info and debug line printers to new parser --- src/codeview/codeview_enum.c | 9 - src/codeview/codeview_enum.h | 1 - src/raddump/raddump.c | 1403 ++++++++++++++++++++-------------- src/raddump/raddump.h | 59 +- src/raddump/raddump_main.c | 36 +- 5 files changed, 886 insertions(+), 622 deletions(-) diff --git a/src/codeview/codeview_enum.c b/src/codeview/codeview_enum.c index 3b03411b..4413fcca 100644 --- a/src/codeview/codeview_enum.c +++ b/src/codeview/codeview_enum.c @@ -930,15 +930,6 @@ cv_string_from_itemid(Arena *arena, CV_ItemId itemid) return result; } -internal String8 -cv_string_from_reg_off(Arena *arena, CV_Arch arch, U32 reg, U32 off) -{ - Temp scratch = scratch_begin(&arena, 1); - String8 result = push_str8f(arena, "%S+%x", cv_string_from_reg_id(scratch.arena, arch, reg), off); - scratch_end(scratch); - return result; -} - internal String8 cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type) { diff --git a/src/codeview/codeview_enum.h b/src/codeview/codeview_enum.h index 02167351..67095f78 100644 --- a/src/codeview/codeview_enum.h +++ b/src/codeview/codeview_enum.h @@ -41,7 +41,6 @@ internal String8 cv_string_from_defrange_register_rel_flags(Arena *arena, CV_Def internal String8 cv_string_from_field_attribs(Arena *arena, CV_FieldAttribs attribs); internal String8 cv_string_from_itype(Arena *arena, CV_TypeIndex min_itype, CV_TypeIndex itype); internal String8 cv_string_from_itemid(Arena *arena, CV_ItemId itemid); -internal String8 cv_string_from_reg_off(Arena *arena, CV_Arch arch, U32 reg, U32 off); internal String8 cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type); internal String8 cv_string_from_symbol_kind(Arena *arena, CV_SymKind kind); internal String8 cv_string_from_leaf_name(Arena *arena, U32 leaf_type); diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index f06082ed..531f5d74 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -225,6 +225,18 @@ rd_is_rdi(String8 raw_data) return is_rdi; } +internal String8 +rd_string_from_reg_off(Arena *arena, String8 reg_str, S64 reg_off) +{ + String8 result; + if (reg_off > 0) { + result = push_str8f(arena, "%S%+lld", reg_str, reg_off); + } else { + result = push_str8f(arena, "%S", reg_str); + } + return result; +} + internal String8 rd_string_from_flags(Arena *arena, String8List list, U64 remaining_flags) { @@ -255,6 +267,19 @@ rd_string_from_array_u32(Arena *arena, U32 *v, U64 count) return result; } +internal String8 +rd_string_from_hex_u8(Arena *arena, U8 *v, U64 count) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List list = {0}; + for (U64 i = 0; i < count; ++i) { + str8_list_pushf(scratch.arena, &list, "%#x", v[i]); + } + String8 result = str8_list_join(arena, &list, &(StringJoin){.sep=str8_lit(", ")}); + scratch_end(scratch); + return result; +} + internal String8 rd_string_from_array_hex_u32(Arena *arena, U32 *v, U64 count) { @@ -299,28 +324,30 @@ rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input { Temp scratch = scratch_begin(&arena, 1); - char *input_type_string = "???"; + String8 input_type_string = str8_lit("???"); if (coff_is_regular_archive(raw_data)) { - input_type_string = "Archive"; + input_type_string = str8_lit("Archive"); } else if (coff_is_thin_archive(raw_data)) { - input_type_string = "Thin Archive"; + input_type_string = str8_lit("Thin Archive"); } else if (coff_is_big_obj(raw_data)) { - input_type_string = "Big Obj"; + input_type_string = str8_lit("Big Obj"); } else if (coff_is_obj(raw_data)) { - input_type_string = "Obj"; + input_type_string = str8_lit("Obj"); } else if (pe_check_magic(raw_data)) { - input_type_string = "COFF/PE"; + input_type_string = str8_lit("COFF/PE"); } else if (rd_is_rdi(raw_data)) { - input_type_string = "RDI"; - } else if (pe_is_res(raw_data)) { - input_type_string = "RES"; + input_type_string = str8_lit("RDI"); + } else if (elf_check_magic(raw_data)) { + U8 sig[ELF_Identifier_Max] = {0}; + str8_deserial_read(raw_data, 0, &sig[0], sizeof(sig), 1); + input_type_string = push_str8f(scratch.arena, "ELF (Class: %S)", elf_string_from_class(scratch.arena, sig[ELF_Identifier_Class])); } DateTime universal_dt = os_now_universal_time(); DateTime local_dt = os_local_time_from_universal(&universal_dt); String8 time = push_date_time_string(scratch.arena, &local_dt); String8 full_path = os_full_path_from_path(scratch.arena, input_path); - rd_printf("# %S, [%s] %S", time, input_type_string, full_path); + rd_printf("# %S, [%S] %S", time, input_type_string, full_path); scratch_end(scratch); } @@ -1202,8 +1229,8 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, U64 *voff_ptr = scope_voff_array + voff_range_lo; String8 voff_str = rd_string_from_range_array_u64_hex(scratch.arena, voff_ptr, voff_range_count); - U64 this_idx = (U64)(scope - scope_array); - rd_printf("[%llu]", this_idx); + U64 scope_idx = (U64)(scope - scope_array); + rd_printf("[%llu]", scope_idx); rd_indent(); String8 proc_name = str8_lit("???"); @@ -1212,9 +1239,11 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx); } - rd_printf("proc_idx =%u '%S'", scope->proc_idx, proc_name); - rd_printf("inline_site_idx=%u", scope->inline_site_idx); - rd_printf("voff_ranges =%S", voff_str); + rd_printf("proc_idx =%u '%S'", scope->proc_idx, proc_name); + rd_printf("first_child_scope_idx =%u", scope->first_child_scope_idx); + rd_printf("next_sibling_scope_idx=%u", scope->next_sibling_scope_idx); + rd_printf("inline_site_idx =%u", scope->inline_site_idx); + rd_printf("voff_ranges =%S", voff_str); // local_array { @@ -1257,7 +1286,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, } rd_unindent(); - rd_printf("[/%llu]", this_idx); + rd_printf("[/%llu]", scope_idx); scratch_end(scratch); } @@ -1566,8 +1595,20 @@ rdi_print(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RD_Op } } +internal String8 +dw_string_from_reg_off(Arena *arena, Arch arch, U64 reg_idx, S64 reg_off) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 reg_str = dw_string_from_register(scratch.arena, arch, reg_idx); + String8 result = rd_string_from_reg_off(arena, reg_str, reg_off); + scratch_end(scratch); + return result; +} + +B32 is_global_var = 0; + internal String8List -dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64) +dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 cu_base, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format) { Temp scratch = scratch_begin(&arena, 1); String8List result = {0}; @@ -1604,15 +1645,16 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, case DW_ExprOp_Const8S:size_param = 8; is_signed = 1; goto const_n; const_n: { - U64 x = 0; - cursor += str8_deserial_read(raw_data, cursor, &x, size_param, 1); - if (is_signed){ - U64 bit_shift = (size_param << 3) - 1; - if ((x >> bit_shift) != 0){ - x |= ~((1 << bit_shift) - 1); - } + if (is_signed) { + S64 x = 0; + cursor += str8_deserial_read(raw_data, cursor, &x, size_param, 1); + x = extend_sign64(x, size_param); + op_value = push_str8f(scratch.arena, "%lld", x); + } else { + U64 x = 0; + cursor += str8_deserial_read(raw_data, cursor, &x, size_param, 1); + op_value = push_str8f(scratch.arena, "%llu", x); } - op_value = push_str8f(scratch.arena, "%llu", x); } break; case DW_ExprOp_Addr: { @@ -1645,19 +1687,24 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { U64 reg_idx = op - DW_ExprOp_Reg0; - op_value = push_str8f(scratch.arena, "%S", dw_string_from_register(scratch.arena, arch, reg_idx)); + op_value = dw_string_from_reg_off(scratch.arena, arch, reg_idx, 0); } break; case DW_ExprOp_RegX: { U64 reg_idx = 0; cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); - op_value = push_str8f(scratch.arena, "register %llu (%S)", reg_idx, dw_string_from_register(scratch.arena, arch, reg_idx)); + op_value = dw_string_from_reg_off(scratch.arena, arch, reg_idx, 0); } break; case DW_ExprOp_ImplicitValue: { - U64 size = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, &size); - op_value = push_str8f(scratch.arena, "block @ %#llx with size %u", cursor, size); + U64 value_size = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, &value_size); + Rng1U64 value_range = rng_1u64(cursor, cursor + value_size); + String8 value_data = str8_substr(raw_data, value_range); + cursor += value_size; + + String8 value_str = rd_string_from_hex_u8(scratch.arena, value_data.str, value_data.size); + op_value = push_str8f(scratch.arena, "{ %S }", value_str); } break; case DW_ExprOp_Piece: { @@ -1688,20 +1735,13 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, case DW_ExprOp_Skip: { S16 x = 0; cursor += str8_deserial_read_struct(raw_data, cursor, &x); - - S64 new_offset = (S64)cursor + x; - if (new_offset >= 0) { - cursor = (U64)new_offset; - op_value = push_str8f(scratch.arena, "constant %lld", x); - } else { - op_value = push_str8f(scratch.arena, "ERROR: negative read offset %lld", new_offset); - } + op_value = push_str8f(scratch.arena, "%+d bytes", x); } break; case DW_ExprOp_Bra: { S16 x = 0; cursor += str8_deserial_read_struct(raw_data, cursor, &x); - op_value = push_str8f(scratch.arena, "%d", x); + op_value = push_str8f(scratch.arena, "%+d", x); } break; case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2: @@ -1718,7 +1758,7 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, U64 reg_idx = op - DW_ExprOp_BReg0; S64 reg_off = 0; cursor += str8_deserial_read_sleb128(raw_data, cursor, ®_off); - op_value = push_str8f(scratch.arena, "%S offset %lld", dw_string_from_register(scratch.arena, arch, reg_idx), reg_off); + op_value = dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off); } break; case DW_ExprOp_FBReg: { @@ -1732,7 +1772,7 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, S64 reg_off = 0; cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); cursor += str8_deserial_read_sleb128(raw_data, cursor, ®_off); - op_value = push_str8f(scratch.arena, "register %u (%S) offset %lld", reg_idx, dw_string_from_register(scratch.arena, arch, reg_idx), reg_off); + op_value = dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off); } break; case DW_ExprOp_XDerefSize: @@ -1754,13 +1794,72 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, } break; case DW_ExprOp_CallRef: { U64 x = 0; - if (is_dwarf64) { - cursor += str8_deserial_read(raw_data, cursor, &x, 8, 1); - } else { - cursor += str8_deserial_read(raw_data, cursor, &x, 4, 1); - } + cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &x); op_value = push_str8f(scratch.arena, "%llu", x); } break; + case DW_ExprOp_ImplicitPointer: + case DW_ExprOp_GNU_ImplicitPointer: { + U64 info_off = 0; + cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &info_off); + S64 ptr = 0; + cursor += str8_deserial_read_sleb128(raw_data, cursor, &ptr); + + op_value = push_str8f(scratch.arena, ".debug_info+%#llx, ptr %llx", info_off, ptr); + } break; + case DW_ExprOp_Convert: + case DW_ExprOp_GNU_Convert: { + U64 type_cu_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, &type_cu_off); + op_value = push_str8f(scratch.arena, "TypeCuOff %#llx", cu_base + type_cu_off); + } break; + case DW_ExprOp_GNU_ParameterRef: { + // TODO: always 4 bytes? + U32 cu_off = 0; + cursor += str8_deserial_read_struct(raw_data, cursor, &cu_off); + op_value = push_str8f(scratch.arena, "CuOff %#x", cu_base + cu_off); + } break; + case DW_ExprOp_DerefType: + case DW_ExprOp_GNU_DerefType: { + U8 deref_size = 0; + U64 type_cu_off = 0; + cursor += str8_deserial_read_struct(raw_data, cursor, &deref_size); + cursor += str8_deserial_read_uleb128(raw_data, cursor, &type_cu_off); + op_value = push_str8f(scratch.arena, "%#x, TypeCuOff %#llx", deref_size, cu_base + type_cu_off); + } break; + case DW_ExprOp_ConstType: + case DW_ExprOp_GNU_ConstType: { + U64 type_cu_off = 0; + U8 const_value_size = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, &type_cu_off); + cursor += str8_deserial_read_struct(raw_data, cursor, &const_value_size); + Rng1U64 const_value_range = rng_1u64(cursor, cursor + const_value_size); + String8 const_value_data = str8_substr(raw_data, const_value_range); + String8 const_value_str = rd_string_from_hex_u8(scratch.arena, const_value_data.str, const_value_data.size); + op_value = push_str8f(scratch.arena, "TypeCuOff %#llx, Const Value { %S }", cu_base + type_cu_off, const_value_str); + cursor += const_value_size; + } break; + case DW_ExprOp_RegvalType: + case DW_ExprOp_GNU_RegvalType: { + U64 reg_idx = 0, type_cu_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_uleb128(raw_data, cursor, &type_cu_off); + op_value = push_str8f(scratch.arena, "%S, TypeCuOff %#llx", dw_string_from_register(scratch.arena, arch, reg_idx), cu_base + type_cu_off); + } break; + case DW_ExprOp_EntryValue: + case DW_ExprOp_GNU_EntryValue: { + U64 block_size = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, &block_size); + Rng1U64 block_range = rng_1u64(cursor, cursor + block_size); + String8 block_data = str8_substr(raw_data, block_range); + String8List block_expr = dw_string_list_from_expression(scratch.arena, block_data, cu_base, address_size, arch, ver, ext, format); + op_value = str8_list_join(scratch.arena, &block_expr, &(StringJoin){.pre = str8_lit("{ "), .sep = str8_lit(","), .post = str8_lit(" }")}); + cursor += block_size; + } break; + case DW_ExprOp_Addrx: { + U64 addr = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, &addr); + op_value = push_str8f(scratch.arena, "%#llx", addr); + } break; case DW_ExprOp_CallFrameCfa: case DW_ExprOp_FormTlsAddress: @@ -1797,7 +1896,7 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, // no operands } break; } - + String8 opcode_str = dw_string_from_expr_op(scratch.arena, ver, ext, op); if (op_value.size == 0) { str8_list_pushf(arena, &result, "DW_OP_%S", opcode_str); @@ -1810,17 +1909,17 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 address_size, } internal String8 -dw_format_expression_single_line(Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64) +dw_format_expression_single_line(Arena *arena, String8 raw_data, U64 cu_base, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format) { Temp scratch = scratch_begin(&arena, 1); - String8List list = dw_string_list_from_expression(scratch.arena, raw_data, address_size, arch, ver, ext, is_dwarf64); + String8List list = dw_string_list_from_expression(scratch.arena, raw_data, cu_base, address_size, arch, ver, ext, format); String8 expression = str8_list_join(arena, &list, &(StringJoin){.sep=str8_lit(", ")}); scratch_end(scratch); return expression; } internal void -dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64) +dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format) { Temp scratch = scratch_begin(&arena, 1); @@ -1869,14 +1968,12 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw rd_printf("DW_CFA_advance_loc4: %+u", delta * cie->code_align_factor); } break; case DW_CFA_OffsetExt: { - U64 reg = 0, offset = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - cursor += str8_deserial_read_uleb128(raw_data, cursor, &offset); + U64 reg_idx = 0, reg_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_off); - rd_printf("DW_CFA_offset_extended: register %llu (%S), offset %+llu", - reg, - dw_string_from_register(arena, arch, reg), - (S64)offset * cie->data_align_factor); + rd_printf("DW_CFA_offset_extended: %S register %llu (%S), offset %+llu", + dw_string_from_reg_off(scratch.arena, arch, reg_idx, (S64)reg_off * cie->data_align_factor)); } break; case DW_CFA_RestoreExt: { rd_printf("DW_CFA_restore_extended"); @@ -1891,19 +1988,14 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw U64 reg = 0; cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - rd_printf("DW_CFA_same_value: register %llu (%S)", - reg, - dw_string_from_register(scratch.arena, arch, reg)); + rd_printf("DW_CFA_same_value: %S", dw_string_from_register(scratch.arena, arch, reg)); } break; case DW_CFA_Register: { - U64 reg = 0, offset = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - cursor += str8_deserial_read_uleb128(raw_data, cursor, &offset); - - rd_printf("DW_CFA_register: register %llu (%S), offset %+llu", - reg, - dw_string_from_register(scratch.arena, arch, reg), - offset); + U64 reg_idx = 0, reg_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_off); + + rd_printf("DW_CFA_register: %S", dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off)); } break; case DW_CFA_RememberState: { rd_printf("DW_CFA_remember_state"); @@ -1912,14 +2004,11 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw rd_printf("DW_CFA_restore_state"); } break; case DW_CFA_DefCfa: { - U64 reg = 0, offset = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - cursor += str8_deserial_read_uleb128(raw_data, cursor, &offset); + U64 reg_idx = 0, reg_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_off); - rd_printf("DW_CFA_def_cfa: register %llu (%S), offset %llu", - reg, - dw_string_from_register(scratch.arena, arch, reg), - offset); + rd_printf("DW_CFA_def_cfa: %S", dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off)); } break; case DW_CFA_DefCfaRegister: { U64 reg = 0; @@ -1942,7 +2031,7 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw cursor += block_size; rd_printf("DW_CFA_def_cfa_expression: %S", - dw_format_expression_single_line(scratch.arena, raw_expr, address_size, arch, ver, ext, is_dwarf64)); + dw_format_expression_single_line(scratch.arena, raw_expr, 0, address_size, arch, ver, ext, format)); } break; case DW_CFA_Expr: { U64 reg = 0, block_size = 0; @@ -1951,28 +2040,25 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw String8 raw_expr = str8_substr(raw_data, rng_1u64(cursor, cursor + block_size)); cursor += block_size; - rd_printf("DW_CFA_expression: register %llu (%S), expression %S", - reg, + rd_printf("DW_CFA_expression: %S, expression %S", dw_string_from_register(scratch.arena, arch, reg), - dw_format_expression_single_line(scratch.arena, raw_expr, address_size, arch, ver, ext, is_dwarf64)); + dw_format_expression_single_line(scratch.arena, raw_expr, 0, address_size, arch, ver, ext, format)); } break; case DW_CFA_OffsetExtSf: { - U64 reg = 0; - S64 offset = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - cursor += str8_deserial_read_sleb128(raw_data, cursor, &offset); + U64 reg_idx = 0; + S64 reg_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_sleb128(raw_data, cursor, ®_off); - rd_printf("DW_CFA_offset_ext_sf: register %llu (%S), offset %+lld", - reg, dw_string_from_register(scratch.arena, arch, reg), offset * cie->data_align_factor); + rd_printf("DW_CFA_offset_ext_sf: %S", dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off * cie->data_align_factor)); } break; case DW_CFA_DefCfaSf: { - U64 reg = 0; - S64 offset = 0; - cursor += str8_deserial_read_uleb128(raw_data, cursor, ®); - cursor += str8_deserial_read_sleb128(raw_data, cursor, &offset); + U64 reg_idx = 0; + S64 reg_off = 0; + cursor += str8_deserial_read_uleb128(raw_data, cursor, ®_idx); + cursor += str8_deserial_read_sleb128(raw_data, cursor, ®_off); - rd_printf("DW_CFA_def_cfa_sf: register %llu (%S), offset %+lld", - reg, dw_string_from_register(scratch.arena, arch, reg), offset * cie->data_align_factor); + rd_printf("DW_CFA_def_cfa_sf: %S", dw_string_from_reg_off(scratch.arena, arch, reg_idx, reg_off * cie->data_align_factor)); } break; case DW_CFA_ValOffset: { U64 val = 0, offset = 0; @@ -1999,7 +2085,7 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw rd_printf("DW_CFA_val_expr: value %+llu, expression %S", val, - dw_format_expression_single_line(scratch.arena, raw_expr, address_size, arch, ver, ext, is_dwarf64)); + dw_format_expression_single_line(scratch.arena, raw_expr, 0, address_size, arch, ver, ext, format)); } break; case DW_CFA_AdvanceLoc: { rd_printf("DW_CFA_advance_loc: %+llu", operand); @@ -2009,10 +2095,10 @@ dw_print_cfi_program(Arena *arena, String8List *out, String8 indent, String8 raw cursor += str8_deserial_read_uleb128(raw_data, cursor, &offset); S64 v = (S64)offset * cie->data_align_factor; - rd_printf("DW_CFA_offset: register %llu (%S), offset %lld", operand, dw_string_from_register(arena, arch, operand), v); + rd_printf("DW_CFA_offset: %S", dw_string_from_reg_off(scratch.arena, arch, operand, v)); } break; case DW_CFA_Restore: { - rd_printf("DW_CFA_restore: register %llu (%S)", operand, dw_string_from_register(scratch.arena, arch, operand)); + rd_printf("DW_CFA_restore: %S", operand, dw_string_from_register(scratch.arena, arch, operand)); } break; default: { rd_errorf("unknown CFI opcode %u", opcode); @@ -2121,9 +2207,9 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh rd_printf("CFI Program:"); rd_indent(); - B32 is_dwarf64 = length > max_U32; - String8 raw_cfi = str8_substr(raw_eh_frame, cfi_range); - dw_print_cfi_program(scratch.arena, out, indent, raw_cfi, &cie, ptr_ctx, arch, ver, ext, is_dwarf64); + DW_Format format = DW_FormatFromSize(length); + String8 raw_cfi = str8_substr(raw_eh_frame, cfi_range); + dw_print_cfi_program(scratch.arena, out, indent, raw_cfi, &cie, ptr_ctx, arch, ver, ext, format); rd_unindent(); rd_newline(); @@ -2135,83 +2221,60 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh scratch_end(scratch); } -internal DW_AttribValueResolveParams -rd_dw_resolve_params_from_comp_root(DW_CompRoot comp_root) -{ - DW_AttribValueResolveParams resolve_params = {0}; - resolve_params.version = comp_root.version; - resolve_params.addr_size = comp_root.address_size; - resolve_params.containing_unit_info_off = comp_root.info_off; - resolve_params.debug_addrs_base = comp_root.addrs_base; - resolve_params.debug_rnglists_base = comp_root.rnglist_base; - resolve_params.debug_str_offs_base = comp_root.stroffs_base; - resolve_params.debug_loclists_base = comp_root.loclist_base; - return resolve_params; -} - internal void -dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed) +dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, Arch arch, B32 relaxed) { Temp scratch = scratch_begin(&arena, 1); - Rng1U64List comp_unit_ranges = dw_comp_unit_ranges_from_info(scratch.arena, sections->v[DW_Section_Info]); + Rng1U64List cu_ranges = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Info].data); - if (comp_unit_ranges.count > 0) { - rd_printf("# %S", sections->v[DW_Section_Info].name); + if (cu_ranges.count > 0) { + rd_printf("# %S", input->sec[DW_Section_Info].name); rd_indent(); } U64 comp_idx = 0; - for (Rng1U64Node *comp_unit_range_n = comp_unit_ranges.first; comp_unit_range_n != 0; comp_unit_range_n = comp_unit_range_n->next, ++comp_idx) { + for (Rng1U64Node *cu_range_n = cu_ranges.first; cu_range_n != 0; cu_range_n = cu_range_n->next, ++comp_idx) { Temp comp_temp = temp_begin(scratch.arena); - Rng1U64 comp_unit_range = comp_unit_range_n->v; - DW_CompRoot comp_root = dw_comp_root_from_range(comp_temp.arena, sections, comp_unit_range, relaxed); - DW_AttribValueResolveParams resolve_params = dw_attrib_value_resolve_params_from_comp_root(&comp_root); - DW_Ext ext = dw_ext_from_params(comp_root.producer, arch, image_type); + U64 cu_base = cu_range_n->v.min; + Rng1U64 cu_range = cu_range_n->v; + DW_CompUnit cu = dw_cu_from_info_off(comp_temp.arena, input, lu_input, cu_range.min, relaxed); + + String8 cu_dir = dw_string_from_attrib (input, &cu, cu.tag, DW_Attrib_CompDir ); + String8 cu_name = dw_string_from_attrib (input, &cu, cu.tag, DW_Attrib_Name ); + String8 stmt_list = dw_line_ptr_from_attrib(input, &cu, cu.tag, DW_Attrib_StmtList); + + DW_LineVMHeader line_vm = {0}; + dw_read_line_vm_header(comp_temp.arena, stmt_list, 0, input, cu_dir, cu_name, cu.address_size, cu.str_offsets_lu, &line_vm); // print comp info rd_printf("Compilation Unit #%u", comp_idx); rd_indent(); - rd_printf("Version: %u", comp_root.version); - rd_printf("Address Size: %llu", comp_root.address_size); - rd_printf("Abbrev Offset: %#llx", comp_root.abbrev_off); - rd_printf("Tags Range: %#llx-%#llx (Size %#llx)", comp_root.tags_info_range.min, comp_root.tags_info_range.max, dim_1u64(comp_root.tags_info_range)); + rd_printf("Version: %u", cu.version); + rd_printf("Address Size: %llu", cu.address_size); + rd_printf("Abbrev Offset: %#llx", cu.abbrev_off); + rd_printf("Info Range: %#llx-%#llx (%M)", cu.info_range.min, cu.info_range.max, dim_1u64(cu.info_range)); rd_newline(); - DW_LineVMHeader vm_header = {0}; - dw_read_line_vm_header(comp_temp.arena, - dw_base_from_sec(sections, DW_Section_Line), - dw_range_from_sec(sections, DW_Section_Line), - comp_root.line_off, - dw_mode_from_sec(sections, DW_Section_Line), - sections, - resolve_params, - comp_root.compile_dir, - comp_root.name, - &vm_header); - // prase tags U32 tag_depth = 0; - for (U64 info_off = comp_root.tags_info_range.min; info_off < comp_root.tags_info_range.max; /* empty */) { + for (U64 info_off = cu.first_tag_info_off; info_off < cu.info_range.max; ) { Temp tag_temp = temp_begin(scratch.arena); - U64 tag_info_off = info_off; - DW_Tag *tag = dw_tag_from_info_offset(tag_temp.arena, sections, comp_root.abbrev_table, comp_root.version, ext, comp_root.language, comp_root.address_size, info_off, relaxed); + U64 tag_info_off = info_off; + DW_Tag tag = {0}; + info_off += dw_read_tag_cu(tag_temp.arena, input, &cu, tag_info_off, &tag); - // advance parse - info_off = tag->info_range.max; - - String8 tag_str = dw_string_from_tag_kind(tag_temp.arena, tag->kind); - rd_printf("<%x><%llx> DW_Tag_%S (Abbrev Number: %llu)", tag_depth, tag_info_off, tag_str, tag->abbrev_id); + String8 tag_str = dw_string_from_tag_kind(tag_temp.arena, tag.kind); + rd_printf("<%x><%llx> DW_Tag_%S (Abbrev Number: %llu)", tag_depth, tag_info_off, tag_str, tag.abbrev_id); rd_indent(); // parse attributes - for (DW_AttribNode *attrib_node = tag->attribs.first; attrib_node != 0; attrib_node = attrib_node->next) { + for (DW_AttribNode *attrib_n = tag.attribs.first; attrib_n != 0; attrib_n = attrib_n->next) { Temp attrib_temp = temp_begin(tag_temp.arena); - DW_Attrib *attrib = &attrib_node->attrib; - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, attrib->form_kind, attrib->value_class, attrib->form_value); + DW_Attrib *attrib = &attrib_n->v; String8List attrib_list = {0}; @@ -2219,10 +2282,10 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx> ", attrib->info_off); // attribute kind - String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, comp_root.version, ext, attrib->attrib_kind); + String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, cu.version, cu.ext, attrib->attrib_kind); if (attrib_kind_str.size == 0) { if (relaxed) { - attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, DW_Version_Last, ext, attrib->attrib_kind); + attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, DW_Version_Last, cu.ext, attrib->attrib_kind); } } if (attrib_kind_str.size == 0) { @@ -2232,105 +2295,165 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr } // form kind - String8 form_kind_str = dw_string_from_form_kind(scratch.arena, comp_root.version, attrib->form_kind); + String8 form_kind_str = dw_string_from_form_kind(scratch.arena, cu.version, attrib->form_kind); str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_Form_%-15S", form_kind_str); - switch (attrib->value_class) { + DW_AttribClass value_class = dw_value_class_from_attrib(&cu, attrib); + switch (value_class) { default: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: Unknown value class"); + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unknown value class"); } break; case DW_AttribClass_Undefined: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: Undefined value class"); + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: undefined value class"); } break; case DW_AttribClass_Address: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + U64 address = dw_address_from_attrib_ptr(input, &cu, attrib); + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", address); } break; case DW_AttribClass_Block: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx %#llx", attrib_value.v[0], attrib_value.v[1]); + String8 block = dw_block_from_attrib_ptr(input, &cu, attrib); + String8 block_str = rd_string_from_hex_u8(attrib_temp.arena, block.str, block.size); + str8_list_pushf(attrib_temp.arena, &attrib_list, "%S", block_str); } break; case DW_AttribClass_Const: { - switch (attrib->attrib_kind) { - case DW_Attrib_Language: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); - - String8 lang_str = dw_string_from_language(attrib_temp.arena, attrib_value.v[0]); - str8_list_pushf(attrib_temp.arena, &attrib_list, " (%S)", lang_str); - } break; - case DW_Attrib_DeclFile: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu", attrib_value.v[0]); - - String8 path = str8_lit("\?\?\?"); - if (attrib_value.v[0] < vm_header.file_table.count) { - path = dw_path_from_file_idx(attrib_temp.arena, &vm_header, attrib_value.v[0]); - } - str8_list_pushf(attrib_temp.arena, &attrib_list, " (%S)", path); - } break; - case DW_Attrib_DeclLine: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu", attrib_value.v[0]); - } break; - default: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); - } break; - } + U64 constant = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", constant); } break; case DW_AttribClass_ExprLoc: { - DW_Mode mode = dw_mode_from_sec(sections, DW_Section_Info); - Rng1U64 sect_range = rng_1u64(0, sections->v[DW_Section_Info].data.size); - Rng1U64 expr_range = rng_1u64(sect_range.min+attrib_value.v[0], sect_range.min+attrib_value.v[0]+attrib_value.v[1]); - String8 raw_expr = str8_substr(sections->v[DW_Section_Info].data, expr_range); - B32 is_dwarf64 = mode == DW_Mode_32Bit ? 1 : 0; - String8 expression = dw_format_expression_single_line(attrib_temp.arena, raw_expr, comp_root.address_size, arch, comp_root.version, ext, is_dwarf64); - str8_list_push(attrib_temp.arena, &attrib_list, expression); + String8 exprloc = dw_exprloc_from_attrib_ptr(input, &cu, attrib); + String8 exprloc_str = dw_format_expression_single_line(attrib_temp.arena, exprloc, cu_base, cu.address_size, arch, cu.version, cu.ext, cu.format); + str8_list_push(attrib_temp.arena, &attrib_list, exprloc_str); } break; case DW_AttribClass_Flag: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + B32 flag = dw_flag_from_attrib_ptr(input, &cu, attrib); + str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu (%s)", flag, flag == 0 ? "false" : "true"); } break; case DW_AttribClass_LinePtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind)); + } } break; case DW_AttribClass_LocListPtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind)); + } } break; case DW_AttribClass_MacPtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?"); + } } break; case DW_AttribClass_RngListPtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?"); + } } break; case DW_AttribClass_RngList: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?"); + } } break; case DW_AttribClass_Reference: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx>", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_Ref1 || + attrib->form_kind == DW_Form_Ref2 || + attrib->form_kind == DW_Form_Ref4 || + attrib->form_kind == DW_Form_Ref8 || + attrib->form_kind == DW_Form_RefUData) { + U64 info_off = cu.info_range.min + attrib->form.ref; + str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx>", info_off); + if (!contains_1u64(cu.info_range, attrib->form.ref)) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "(ERROR: out of bounds reference)"); + } + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.ref); + } } break; case DW_AttribClass_String: { - String8 string = dw_string_from_attrib_value(sections, attrib_value); - str8_list_pushf(attrib_temp.arena, &attrib_list, "\"%S\"", string); + if (attrib->form_kind == DW_Form_Strp) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } + String8 string = dw_string_from_attrib_ptr(input, &cu, attrib); + str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", string); } break; case DW_AttribClass_StrOffsetsPtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind)); + } } break; case DW_AttribClass_AddrPtr: { - str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib_value.v[0]); + if (attrib->form_kind == DW_Form_SecOffset) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset); + } else { + str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind)); + } } break; } - String8 print = str8_list_join(attrib_temp.arena, &attrib_list, 0); + String8 attrib_str = {0}; + switch (attrib->attrib_kind) { + case DW_Attrib_Language: { + DW_Language lang = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = dw_string_from_language(attrib_temp.arena, lang); + } break; + case DW_Attrib_DeclFile: { + U64 file_idx = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + DW_LineFile *file = dw_file_from_attrib_ptr(&cu, &line_vm, attrib); + attrib_str = str8_lit("\?\?\?"); + if (file) { + attrib_str = dw_path_from_file(attrib_temp.arena, &line_vm, file); + } + } break; + case DW_Attrib_DeclLine: { + U64 line = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = push_str8f(attrib_temp.arena, "%llu", line); + } break; + case DW_Attrib_Inline: { + DW_InlKind inl = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = dw_string_from_inl(attrib_temp.arena, inl); + } break; + case DW_Attrib_Accessibility: { + DW_AccessKind access = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = dw_string_from_access_kind(attrib_temp.arena, access); + } break; + case DW_Attrib_CallingConvention: { + DW_CallingConventionKind calling_convetion = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = dw_string_from_calling_convetion(attrib_temp.arena, calling_convetion); + } break; + case DW_Attrib_Encoding: { + DW_ATE encoding = dw_const_u64_from_attrib_ptr(input, &cu, attrib); + attrib_str = dw_string_from_attrib_type_encoding(attrib_temp.arena, encoding); + } break; + } + + if (attrib_str.size) { + str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", attrib_str); + } + String8 print = str8_list_join(attrib_temp.arena, &attrib_list, &(StringJoin){.sep=str8_lit(" ")}); rd_printf("%S", print); temp_end(attrib_temp); } - B32 is_ender_tag = tag->abbrev_id == 0; - - if (tag->has_children) { + B32 is_ender_tag = tag.abbrev_id == 0; + if (tag.has_children) { if (is_ender_tag) { rd_errorf("null-tag cannot have children"); } rd_indent(); tag_depth += 1; } - if (is_ender_tag) { if (tag_depth == 0) { rd_errorf("malformed data detected, too many null tags"); @@ -2341,7 +2464,6 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr } rd_unindent(); - temp_end(tag_temp); } temp_end(comp_temp); @@ -2350,7 +2472,7 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr rd_newline(); } - if (comp_unit_ranges.count > 0) { + if (cu_ranges.count > 0) { rd_unindent(); } @@ -2358,19 +2480,21 @@ dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_SectionAr } internal void -dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Input *input) { Temp scratch = scratch_begin(&arena, 1); - DW_Section abbrev = sections->v[DW_Section_Abbrev]; + DW_Section abbrev = input->sec[DW_Section_Abbrev]; String8 raw_abbrev = abbrev.data; if (raw_abbrev.size) { - rd_printf("# %S", sections->v[DW_Section_Abbrev].name); + rd_printf("# %S", input->sec[DW_Section_Abbrev].name); rd_indent(); } for (U64 cursor = 0; cursor < raw_abbrev.size; ) { + U64 id_off = cursor; + U64 id = 0; cursor += str8_deserial_read_uleb128(raw_abbrev, cursor, &id); @@ -2385,9 +2509,11 @@ dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Section cursor += str8_deserial_read_uleb128(raw_abbrev, cursor, &tag); cursor += str8_deserial_read_struct(raw_abbrev, cursor, &has_children); - rd_printf("%llu DW_Tag_%S %s", id, dw_string_from_tag_kind(temp.arena, tag), has_children ? "[has children]" : "[no children]"); + rd_printf("<%llx> %llu DW_Tag_%S %s", id_off, id, dw_string_from_tag_kind(temp.arena, tag), has_children ? "[has children]" : "[no children]"); rd_indent(); for (;;) { + U64 attrib_off = cursor; + U64 attrib_id = 0, form_id = 0; cursor += str8_deserial_read_uleb128(raw_abbrev, cursor, &attrib_id); cursor += str8_deserial_read_uleb128(raw_abbrev, cursor, &form_id); @@ -2396,7 +2522,7 @@ dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Section } String8 attrib_str = dw_string_from_attrib_kind(temp.arena, DW_Version_Last, DW_Ext_All, attrib_id); String8 form_str = dw_string_from_form_kind(temp.arena, DW_Version_Last, form_id); - rd_printf("DW_Attrib_%-20S DW_Form_%S", attrib_str, form_str); + rd_printf("<%llx> DW_Attrib_%-20S DW_Form_%S", attrib_off, attrib_str, form_str); } rd_unindent(); @@ -2411,282 +2537,287 @@ dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Section } internal void -dw_print_debug_line(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, B32 relaxed) +dw_print_debug_line(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, B32 relaxed) { Temp scratch = scratch_begin(&arena, 1); - DW_Mode mode = dw_mode_from_sec(sections, DW_Section_Line); - Rng1U64 range = dw_range_from_sec(sections, DW_Section_Line); - void *base = dw_base_from_sec(sections, DW_Section_Line); - Rng1U64List comp_unit_range_list = dw_comp_unit_ranges_from_info(scratch.arena, sections->v[DW_Section_Info]); + rd_printf("# .debug_line"); - if (dim_1u64(range)) { - rd_printf("# %S", sections->v[DW_Section_Line].name); - rd_indent(); - } + Rng1U64List unit_ranges = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Line].data); + for (Rng1U64Node *unit_range_n = unit_ranges.first; unit_range_n != 0; unit_range_n = unit_range_n->next) { + Temp unit_temp = temp_begin(scratch.arena); - U64 cursor = 0; - for (Rng1U64Node *comp_unit_range_n = comp_unit_range_list.first; comp_unit_range_n != 0; comp_unit_range_n = comp_unit_range_n->next) { - Temp comp_temp = temp_begin(scratch.arena); + String8 unit_data = str8_substr(input->sec[DW_Section_Line].data, unit_range_n->v); + String8 cu_dir = {0}; + String8 cu_name = {0}; + DW_ListUnit cu_str_offsets = {0}; + DW_LineVMHeader line_vm = {0}; + U64 line_vm_size = dw_read_line_vm_header(unit_temp.arena, unit_data, 0, input, cu_dir, cu_name, line_vm.address_size, &cu_str_offsets, &line_vm); - Rng1U64 comp_unit_range = comp_unit_range_n->v; - U64 line_table_offset = cursor; - DW_CompRoot comp_root = dw_comp_root_from_range(comp_temp.arena, sections, comp_unit_range, relaxed); - DW_AttribValueResolveParams resolve_params = dw_attrib_value_resolve_params_from_comp_root(&comp_root); - - DW_LineVMHeader vm_header = {0}; - cursor += dw_read_line_vm_header(arena, base, range, cursor, mode, sections, resolve_params, comp_root.compile_dir, comp_root.name, &vm_header); - - if (vm_header.unit_length == 0) { + if (line_vm_size == 0) { continue; } - rd_printf("Line table offset: %#llx", line_table_offset); - rd_printf("Line table length: %llu", vm_header.unit_length); - rd_printf("Version: %u", vm_header.version); - rd_printf("Address size: %u", vm_header.address_size); - rd_printf("Segment selector size: %u", vm_header.segment_selector_size); - rd_printf("Header length: %llu", vm_header.header_length); - rd_printf("Program offset: %#llx", vm_header.program_off); - rd_printf("Min instruction length: %u", vm_header.min_inst_len); - rd_printf("Max ops for instruction: %u", vm_header.max_ops_for_inst); - rd_printf("Default Is Stmt: %u", vm_header.default_is_stmt); - rd_printf("Line base: %d", vm_header.line_base); - rd_printf("Line range: %u", vm_header.line_range); - rd_printf("Opcode base: %u", vm_header.opcode_base); - rd_printf("Opcode lengths: %S", rd_format_hex_array(comp_temp.arena, vm_header.opcode_lens, vm_header.num_opcode_lens)); - rd_newline(); - - rd_printf("Directory Table:"); - rd_indent(); - rd_printf("%-4s %-8s", "No.", "String"); - for (U64 dir_idx = 0; dir_idx < vm_header.dir_table.count; ++dir_idx) { - rd_printf("%-4llu %S", dir_idx, vm_header.dir_table.v[dir_idx]); + { + rd_printf("Header:", line_vm_size); + rd_indent(); + String8 opcode_lengths = rd_format_hex_array(unit_temp.arena, line_vm.opcode_lens, line_vm.num_opcode_lens); + rd_printf("Version: %u", line_vm.version ); + rd_printf("Line table offset: %#llx", line_vm.unit_range.min ); + rd_printf("Line table length: %llu", dim_1u64(line_vm.unit_range) ); + rd_printf("Version: %u", line_vm.version ); + rd_printf("Address size: %u", line_vm.address_size ); + rd_printf("Segment selector size: %u", line_vm.segment_selector_size); + rd_printf("Header length: %llu", line_vm.header_length ); + rd_printf("Min instruction length: %u", line_vm.min_inst_len ); + rd_printf("Max ops for instruction: %u", line_vm.max_ops_for_inst ); + rd_printf("Default Is Stmt: %u", line_vm.default_is_stmt ); + rd_printf("Line base: %d", line_vm.line_base ); + rd_printf("Line range: %u", line_vm.line_range ); + rd_printf("Opcode base: %u", line_vm.opcode_base ); + rd_printf("Opcode lengths: %S", opcode_lengths ); + rd_unindent(); + rd_newline(); } - rd_unindent(); - rd_newline(); - rd_printf("File Table:"); - rd_indent(); - rd_printf("%-4s %-8s %-8s %-17s %-8s %-8s", "No.", "DirIdx", "Time", "MD5", "Size", "Name"); - for (U64 file_idx = 0; file_idx < vm_header.file_table.count; ++file_idx) { - DW_LineFile *file = &vm_header.file_table.v[file_idx]; - rd_printf("%-4llu %-8llu %-8llu %08llx-%08llx %-8llu %S", - file_idx, - file->dir_idx, - file->modify_time, - file->md5_digest[0], - file->md5_digest[1], - file->file_size, - file->file_name); + { + rd_printf("Directory Table:"); + rd_indent(); + rd_printf("%-4s %-8s", "No.", "String"); + for (U64 dir_idx = 0; dir_idx < line_vm.dir_table.count; ++dir_idx) { + rd_printf("%-4llu %S", dir_idx, line_vm.dir_table.v[dir_idx]); + } + rd_unindent(); + rd_newline(); } - rd_unindent(); - rd_newline(); - B32 end_of_seq = 0; - DW_LineVMState vm_state = {0}; - dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); + { + rd_printf("File Table:"); + rd_indent(); + rd_printf("%-4s %-8s %-8s %-33s %-8s %-8s", "No.", "DirIdx", "Time", "MD5", "Size", "Name"); + for (U64 file_idx = 0; file_idx < line_vm.file_table.count; ++file_idx) { + DW_LineFile *file = &line_vm.file_table.v[file_idx]; + rd_printf("%-4llu %-8llu %-8llu %016llx-%016llx %-8llu %S", + file_idx, + file->dir_idx, + file->modify_time, + file->md5_digest.u64[1], + file->md5_digest.u64[0], + file->file_size, + file->file_name); + } + rd_unindent(); + rd_newline(); + } - rd_printf("Opcodes:"); - for (; cursor < vm_header.unit_opl; ) { - U64 opcode_offset = cursor; + { + rd_printf("Opcodes:"); + rd_indent(); - Temp opcode_temp = temp_begin(scratch.arena); + String8 opcodes = str8_skip(unit_data, line_vm_size); + B32 end_of_seq = 0; + DW_LineVMState vm_state = {0}; + dw_line_vm_reset(&vm_state, line_vm.default_is_stmt); - String8List list = {0}; + for (U64 cursor = 0; cursor < opcodes.size; ) { + Temp opcode_temp = temp_begin(unit_temp.arena); - // parse opcode - U8 opcode = 0; - cursor += dw_based_range_read_struct(base, range, cursor, &opcode); + String8List opcode_fmt = {0}; - // push opcode id - String8 opcode_str = dw_string_from_std_opcode(opcode_temp.arena, opcode); - str8_list_push(arena, &list, opcode_str); - - // format operands - switch (opcode) { - default: { - if (opcode >= vm_header.opcode_base) { - U32 adjusted_opcode = 0; - U32 op_advance = 0; - S32 line_advance = 0; - U64 addr_advance = 0; - if (vm_header.line_range > 0 && vm_header.max_ops_for_inst > 0) { - adjusted_opcode = (U32)(opcode - vm_header.opcode_base); - op_advance = adjusted_opcode / vm_header.line_range; - line_advance = (S32)vm_header.line_base + ((S32)adjusted_opcode) % (S32)vm_header.line_range; - addr_advance = vm_header.min_inst_len * ((vm_state.op_index+op_advance) / vm_header.max_ops_for_inst); + // opcode offset + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "[%08llx]", cursor); + + // parse opcode + U8 opcode = 0; + cursor += str8_deserial_read_struct(opcodes, cursor, &opcode); + + // push opcode id + String8 opcode_str = dw_string_from_std_opcode(opcode_temp.arena, opcode); + str8_list_push(arena, &opcode_fmt, opcode_str); + + // format operands + switch (opcode) { + default: { + if (opcode >= line_vm.opcode_base) { + U32 adjusted_opcode = 0; + U32 op_advance = 0; + S32 line_advance = 0; + U64 addr_advance = 0; + if (line_vm.line_range > 0 && line_vm.max_ops_for_inst > 0) { + adjusted_opcode = (U32)(opcode - line_vm.opcode_base); + op_advance = adjusted_opcode / line_vm.line_range; + line_advance = (S32)line_vm.line_base + ((S32)adjusted_opcode) % (S32)line_vm.line_range; + addr_advance = line_vm.min_inst_len * ((vm_state.op_index+op_advance) / line_vm.max_ops_for_inst); + } + + vm_state.address += addr_advance; + vm_state.op_index = (vm_state.op_index + op_advance) % line_vm.max_ops_for_inst; + vm_state.line = (U32)((S32)vm_state.line + line_advance); + vm_state.basic_block = 0; + vm_state.prologue_end = 0; + vm_state.epilogue_begin = 0; + vm_state.discriminator = 0; + + end_of_seq = 0; + + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance line by %d, advance address by %lld", line_advance, addr_advance); + } else { + if (opcode > 0 && opcode <= line_vm.num_opcode_lens) { + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "skip operands:"); + U64 num_operands = line_vm.opcode_lens[opcode - 1]; + for (U8 i = 0; i < num_operands; i += 1){ + U64 operand = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &operand); + str8_list_pushf(opcode_temp.arena, &opcode_fmt, " %llx", operand); + } + } } + }break; - vm_state.address += addr_advance; - vm_state.op_index = (vm_state.op_index + op_advance) % vm_header.max_ops_for_inst; - vm_state.line = (U32)((S32)vm_state.line + line_advance); + case DW_StdOpcode_Copy: { + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "Line = %u, Column = %u, Address = %#llx", vm_state.line, vm_state.column, vm_state.address); + end_of_seq = 0; + vm_state.discriminator = 0; vm_state.basic_block = 0; vm_state.prologue_end = 0; vm_state.epilogue_begin = 0; - vm_state.discriminator = 0; - - end_of_seq = 0; - - str8_list_pushf(opcode_temp.arena, &list, "advance line by %d, advance address by %lld", line_advance, addr_advance); - } else { - if (opcode > 0 && opcode <= vm_header.num_opcode_lens) { - str8_list_pushf(opcode_temp.arena, &list, "skip operands:"); - U64 num_operands = vm_header.opcode_lens[opcode - 1]; - for (U8 i = 0; i < num_operands; i += 1){ - U64 operand = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &operand); - str8_list_pushf(opcode_temp.arena, &list, " %llx", operand); - } - } - } - }break; - - case DW_StdOpcode_Copy: { - str8_list_pushf(opcode_temp.arena, &list, "Line = %u, Column = %u, Address = %#llx", vm_state.line, vm_state.column, vm_state.address); - end_of_seq = 0; - vm_state.discriminator = 0; - vm_state.basic_block = 0; - vm_state.prologue_end = 0; - vm_state.epilogue_begin = 0; - } break; - case DW_StdOpcode_AdvancePc: { - U64 advance = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &advance); - dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - str8_list_pushf(opcode_temp.arena, &list, "advance %#llx ; current address %#llx", advance, vm_state.address); - } break; - - case DW_StdOpcode_AdvanceLine: { - S64 advance = 0; - cursor += dw_based_range_read_sleb128(base, range, cursor, &advance); - vm_state.line += advance; - str8_list_pushf(opcode_temp.arena, &list, "advance %lld ; current line %u", advance, vm_state.line); - } break; - - case DW_StdOpcode_SetFile: { - U64 file_idx = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &file_idx); - vm_state.file_index = file_idx; - - String8 path = dw_path_from_file_idx(opcode_temp.arena, &vm_header, file_idx); - str8_list_pushf(opcode_temp.arena, &list, "%llu \"%S\"", file_idx, path); - } break; - - case DW_StdOpcode_SetColumn: { - U64 column = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &column); - vm_state.column = column; - str8_list_pushf(opcode_temp.arena, &list, "%llu", column); - } break; - - case DW_StdOpcode_NegateStmt: { - vm_state.is_stmt = !vm_state.is_stmt; - str8_list_pushf(opcode_temp.arena, &list, "is_stmt = %u", vm_state.is_stmt); - } break; - - case DW_StdOpcode_SetBasicBlock: { - vm_state.basic_block = 1; - } break; - - case DW_StdOpcode_ConstAddPc: { - U64 advance = (0xffu - vm_header.opcode_base)/vm_header.line_range; - dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - str8_list_pushf(opcode_temp.arena, &list, "%lld ; address %#llx", advance, vm_state.address); - }break; - - case DW_StdOpcode_FixedAdvancePc: { - U64 operand = 0; - cursor += dw_based_range_read_struct(base, range, cursor, &operand); - vm_state.address += operand; - vm_state.op_index = 0; - str8_list_pushf(opcode_temp.arena, &list, "%llu", operand); - } break; - - case DW_StdOpcode_SetPrologueEnd: { - vm_state.prologue_end = 1; - } break; - - case DW_StdOpcode_SetEpilogueBegin: { - vm_state.epilogue_begin = 1; - } break; - - case DW_StdOpcode_SetIsa: { - U64 v = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &v); - vm_state.isa = v; - str8_list_pushf(opcode_temp.arena, &list, "%llu", v); - } break; - - case DW_StdOpcode_ExtendedOpcode: { - U64 length = 0; - U8 ext_opcode = 0; - - cursor += dw_based_range_read_uleb128(base, range, cursor, &length); - U64 opcode_end = cursor + length; - - cursor += dw_based_range_read_struct(base, range, cursor, &ext_opcode); - - String8 ext_opcode_str = dw_string_from_ext_opcode(opcode_temp.arena, ext_opcode); - //str8_list_pushf(opcode_temp.arena, &list, "length: %u", length); - str8_list_push(opcode_temp.arena, &list, ext_opcode_str); - switch (ext_opcode) { - case DW_ExtOpcode_EndSequence: { - vm_state.end_sequence = 1; - dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); - end_of_seq = 1; } break; - case DW_ExtOpcode_SetAddress: { - U64 address = 0; - cursor += dw_based_range_read(base, range, cursor, comp_root.address_size, &address); - vm_state.address = address; - vm_state.op_index = 0; - vm_state.busted_seq = address != 0; - str8_list_pushf(opcode_temp.arena, &list, "%#llx", address); + case DW_StdOpcode_AdvancePc: { + U64 advance = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &advance); + dw_line_vm_advance(&vm_state, advance, line_vm.min_inst_len, line_vm.max_ops_for_inst); + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %#llx ; current address %#llx", advance, vm_state.address); } break; - case DW_ExtOpcode_DefineFile: { - String8 file_name = dw_based_range_read_string(base, range, cursor); - cursor += file_name.size + 1; - U64 dir_idx = 0, modify_time = 0, file_size = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &dir_idx); - cursor += dw_based_range_read_uleb128(base, range, cursor, &modify_time); - cursor += dw_based_range_read_uleb128(base, range, cursor, &file_size); - str8_list_pushf(opcode_temp.arena, &list, "%S Dir: %llu, Time: %llu, Size: %llu", file_name, dir_idx, modify_time, file_size); + + case DW_StdOpcode_AdvanceLine: { + S64 advance = 0; + cursor += str8_deserial_read_sleb128(opcodes, cursor, &advance); + vm_state.line += advance; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %lld ; current line %u", advance, vm_state.line); } break; - case DW_ExtOpcode_SetDiscriminator: { + + case DW_StdOpcode_SetFile: { + U64 file_idx = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &file_idx); + vm_state.file_index = file_idx; + + String8 path = dw_path_from_file_idx(opcode_temp.arena, &line_vm, file_idx); + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%llu \"%S\"", file_idx, path); + } break; + + case DW_StdOpcode_SetColumn: { + U64 column = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &column); + vm_state.column = column; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%llu", column); + } break; + + case DW_StdOpcode_NegateStmt: { + vm_state.is_stmt = !vm_state.is_stmt; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "is_stmt = %u", vm_state.is_stmt); + } break; + + case DW_StdOpcode_SetBasicBlock: { + vm_state.basic_block = 1; + } break; + + case DW_StdOpcode_ConstAddPc: { + U64 advance = (0xffu - line_vm.opcode_base)/line_vm.line_range; + dw_line_vm_advance(&vm_state, advance, line_vm.min_inst_len, line_vm.max_ops_for_inst); + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%lld ; address %#llx", advance, vm_state.address); + }break; + + case DW_StdOpcode_FixedAdvancePc: { + U64 operand = 0; + cursor += str8_deserial_read_struct(opcodes, cursor, &operand); + vm_state.address += operand; + vm_state.op_index = 0; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%llu", operand); + } break; + + case DW_StdOpcode_SetPrologueEnd: { + vm_state.prologue_end = 1; + } break; + + case DW_StdOpcode_SetEpilogueBegin: { + vm_state.epilogue_begin = 1; + } break; + + case DW_StdOpcode_SetIsa: { U64 v = 0; - cursor += dw_based_range_read_uleb128(base, range, cursor, &v); - vm_state.discriminator = v; - str8_list_pushf(arena, &list, "%llu", v); + cursor += str8_deserial_read_uleb128(opcodes, cursor, &v); + vm_state.isa = v; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%llu", v); + } break; + + case DW_StdOpcode_ExtendedOpcode: { + U64 length = 0; + U8 ext_opcode = 0; + + cursor += str8_deserial_read_uleb128(opcodes, cursor, &length); + U64 opcode_end = cursor + length; + + cursor += str8_deserial_read_struct(opcodes, cursor, &ext_opcode); + + String8 ext_opcode_str = dw_string_from_ext_opcode(opcode_temp.arena, ext_opcode); + //str8_list_pushf(opcode_temp.arena, &opcode_fmt, "length: %u", length); + str8_list_push(opcode_temp.arena, &opcode_fmt, ext_opcode_str); + switch (ext_opcode) { + case DW_ExtOpcode_EndSequence: { + vm_state.end_sequence = 1; + dw_line_vm_reset(&vm_state, line_vm.default_is_stmt); + end_of_seq = 1; + } break; + case DW_ExtOpcode_SetAddress: { + U64 address = 0; + cursor += str8_deserial_read(opcodes, cursor, &address, line_vm.address_size, line_vm.address_size); + vm_state.address = address; + vm_state.op_index = 0; + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%#llx", address); + } break; + case DW_ExtOpcode_DefineFile: { + String8 file_name = {0}; + cursor += str8_deserial_read_cstr(opcodes, cursor, &file_name); + + U64 dir_idx = 0, modify_time = 0, file_size = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &dir_idx); + cursor += str8_deserial_read_uleb128(opcodes, cursor, &modify_time); + cursor += str8_deserial_read_uleb128(opcodes, cursor, &file_size); + str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%S Dir: %llu, Time: %llu, Size: %llu", file_name, dir_idx, modify_time, file_size); + } break; + case DW_ExtOpcode_SetDiscriminator: { + U64 v = 0; + cursor += str8_deserial_read_uleb128(opcodes, cursor, &v); + vm_state.discriminator = v; + str8_list_pushf(arena, &opcode_fmt, "%llu", v); + } break; + } + + cursor = opcode_end; } break; } - cursor = opcode_end; - } break; + String8 string = str8_list_join(opcode_temp.arena, &opcode_fmt, &(StringJoin){.sep=str8_lit(" ")}); + rd_printf("%S", string); + + temp_end(opcode_temp); } - String8 string = str8_list_join(opcode_temp.arena, &list, &(StringJoin){.sep=str8_lit(" ")}); - rd_printf("[%08llx] %S", opcode_offset, string); - - temp_end(opcode_temp); + rd_unindent(); + rd_newline(); } - temp_end(comp_temp); - rd_newline(); - } - - if (dim_1u64(range)) { - rd_unindent(); + temp_end(unit_temp); } scratch_end(scratch); } internal void -dw_print_debug_str(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_str(Arena *arena, String8List *out, String8 indent, DW_Input *input) { - String8 data = sections->v[DW_Section_Str].data; - rd_printf("# %S", sections->v[DW_Section_Str].name); + String8 data = input->sec[DW_Section_Str].data; + rd_printf("# %S", input->sec[DW_Section_Str].name); rd_indent(); for (U64 cursor = 0, read_size = 0; cursor < data.size; cursor += read_size) { String8 string = {0}; @@ -2697,10 +2828,11 @@ dw_print_debug_str(Arena *arena, String8List *out, String8 indent, DW_SectionArr } internal void -dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed) +dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ImageType image_type, B32 relaxed) { - DW_Section info = sections->v[DW_Section_Info]; - DW_Section loc = sections->v[DW_Section_Loc]; +#if 0 + DW_Section info = input->sec[DW_Section_Info]; + DW_Section loc = input->sec[DW_Section_Loc]; if (loc.data.size == 0) { return; @@ -2708,55 +2840,54 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArr Temp scratch = scratch_begin(&arena, 1); - rd_printf("# %S", sections->v[DW_Section_Loc].name); + rd_printf("# %S", input->sec[DW_Section_Loc].name); rd_indent(); // TODO: warn about overlaps in ranges - Rng1U64List comp_unit_range_list = dw_comp_unit_ranges_from_info(scratch.arena, info); + Rng1U64List cu_range_list = dw_comp_unit_ranges_from_info(scratch.arena, info); // parse debug_info for attributes with LOCLIST and store .debug_loc offsets - U64List *loc_lists = push_array(scratch.arena, U64List, comp_unit_range_list.count); - U64 *address_sizes = push_array(scratch.arena, U64, comp_unit_range_list.count); - U64 *address_bases = push_array(scratch.arena, U64, comp_unit_range_list.count); - DW_Version *ver_arr = push_array(scratch.arena, DW_Version, comp_unit_range_list.count); - DW_Ext *ext_arr = push_array(scratch.arena, DW_Ext, comp_unit_range_list.count); + U64List *loc_lists = push_array(scratch.arena, U64List, cu_range_list.count); + U64 *address_sizes = push_array(scratch.arena, U64, cu_range_list.count); + U64 *address_bases = push_array(scratch.arena, U64, cu_range_list.count); + U64 *cu_bases = push_array(scratch.arena, U64, cu_range_list.count); + DW_Version *ver_arr = push_array(scratch.arena, DW_Version, cu_range_list.count); + DW_Ext *ext_arr = push_array(scratch.arena, DW_Ext, cu_range_list.count); U64 comp_idx = 0; - for (Rng1U64Node *comp_unit_range_n = comp_unit_range_list.first; comp_unit_range_n != 0; comp_unit_range_n = comp_unit_range_n->next, ++comp_idx) { + for (Rng1U64Node *cu_range_n = cu_range_list.first; cu_range_n != 0; cu_range_n = cu_range_n->next, ++comp_idx) { Temp comp_temp = temp_begin(arena); - Rng1U64 comp_unit_range = comp_unit_range_n->v; - DW_CompRoot comp_root = dw_comp_root_from_range(comp_temp.arena, sections, comp_unit_range, relaxed); - DW_AttribValueResolveParams resolve_params = dw_attrib_value_resolve_params_from_comp_root(&comp_root); + Rng1U64 cu_range = cu_range_n->v; + DW_CompUnit cu = dw_comp_unit_from_info_off(comp_temp.arena, input, cu_range.min, relaxed); // store info about comp unit - address_sizes[comp_idx] = comp_root.address_size; - address_bases[comp_idx] = comp_root.base_addr; - ver_arr[comp_idx] = comp_root.version; - ext_arr[comp_idx] = dw_ext_from_params(comp_root.producer, arch, image_type); + address_sizes[comp_idx] = cu.address_size; + address_bases[comp_idx] = cu.base_addr; + ver_arr[comp_idx] = cu.version; + cu_bases[comp_idx] = cu_range_n->v.min; // parse tags - for (U64 info_off = comp_root.tags_info_range.min; info_off < comp_root.tags_info_range.max; /* empty */) { + for (U64 info_off = cu.tags_range.min; info_off < cu.tags_range.max; /* empty */) { Temp tag_temp = temp_begin(scratch.arena); - DW_Tag *tag = dw_tag_from_info_offset(tag_temp.arena, sections, comp_root.abbrev_table, ver_arr[comp_idx], ext_arr[comp_idx], comp_root.language, comp_root.address_size, info_off, relaxed); + DW_Tag tag = dw_tag_from_info_offset_cu(tag_temp.arena, input, &cu, ext_arr[comp_idx], info_off); // parse attribs - for (DW_AttribNode *attrib_node = tag->attribs.first; attrib_node != 0; attrib_node = attrib_node->next) { - DW_Attrib *attrib = &attrib_node->attrib; + for (DW_AttribNode *attrib_node = tag.attribs.first; attrib_node != 0; attrib_node = attrib_node->next) { + DW_Attrib *attrib = &attrib_node->v; B32 is_sect_offset = attrib->value_class == DW_AttribClass_LocListPtr || (attrib->value_class == DW_AttribClass_LocList && attrib->form_kind == DW_Form_SecOffset); B32 is_sect_index = attrib->value_class == DW_AttribClass_LocList && attrib->form_kind == DW_Form_LocListx; if (is_sect_offset) { - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, attrib->form_kind, attrib->value_class, attrib->form_value); - u64_list_push(scratch.arena, &loc_lists[comp_idx], attrib_value.v[0]); + u64_list_push(scratch.arena, &loc_lists[comp_idx], attrib->value.v[0]); } else if (is_sect_index) { // TODO: support for section indexing } } // advance to next tag - info_off = tag->info_range.max; + info_off = tag.next_info_off; temp_end(tag_temp); } @@ -2764,13 +2895,13 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArr temp_end(comp_temp); } - void *base = dw_base_from_sec(sections, DW_Section_Loc); - Rng1U64 range = dw_range_from_sec(sections, DW_Section_Loc); + void *base = dw_base_from_sec(input, DW_Section_Loc); + Rng1U64 range = dw_range_from_sec(input, DW_Section_Loc); - rd_printf("%S:", dw_string_from_section_kind(scratch.arena, DW_Section_Loc)); + rd_printf(".debug_loc"); rd_indent(); rd_printf("%-8s %-8s %-8s %s", "Offset", "Min", "Max", "Expression"); - for (U32 comp_idx = 0; comp_idx < comp_unit_range_list.count; ++comp_idx) { + for (U32 comp_idx = 0; comp_idx < cu_range_list.count; ++comp_idx) { Temp locs_temp = temp_begin(scratch.arena); DW_Version ver = ver_arr[comp_idx]; @@ -2804,8 +2935,6 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArr } else if (v0 == base_selector) { base_address = v1; } else { - // this is not mentioned in the spec (june 10, 2010) - // found reference in gdb/binutils/dwarf.c => display_loc_list U16 expr_size = 0; cursor += dw_based_range_read_struct(base, range, cursor, &expr_size); Rng1U64 expr_range = rng_1u64(range.min+cursor, range.min+cursor+expr_size); @@ -2814,7 +2943,7 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArr // format dwarf expression B32 is_dwarf64 = (address_size == 8); String8 raw_expr = str8((U8*)base+expr_range.min, dim_1u64(expr_range)); - String8 expression = dw_format_expression_single_line(range_temp.arena, raw_expr, address_size, arch, ver, ext, is_dwarf64); + String8 expression = dw_format_expression_single_line(range_temp.arena, raw_expr, cu_bases[comp_idx], address_size, arch, ver, ext, input->sec[DW_Section_Loc].mode); // push entry U64 min = base_address + v0; @@ -2842,14 +2971,17 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_SectionArr rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed) +dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ImageType image_type, B32 relaxed) { - DW_Section ranges = sections->v[DW_Section_Ranges]; - void *base = dw_base_from_sec(sections, DW_Section_Ranges); - Rng1U64 range = dw_range_from_sec(sections, DW_Section_Ranges); + NotImplemented; +#if 0 + DW_Section ranges = input->sec[DW_Section_Ranges]; + void *base = dw_base_from_sec(input, DW_Section_Ranges); + Rng1U64 range = dw_range_from_sec(input, DW_Section_Ranges); if (dim_1u64(range) == 0) { return; @@ -2857,42 +2989,40 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Section Temp scratch = scratch_begin(&arena, 1); - Rng1U64List comp_unit_range_list = dw_comp_unit_ranges_from_info(scratch.arena, sections->v[DW_Section_Info]); + Rng1U64List cu_range_list = dw_comp_unit_ranges_from_info(scratch.arena, sections->v[DW_Section_Info]); // parse debug_info for attributes with LOCLIST and store .debug_loc offsets - U64List *loc_lists = push_array(scratch.arena, U64List, comp_unit_range_list.count); - U64 *address_sizes = push_array(scratch.arena, U64, comp_unit_range_list.count); - U64 *address_bases = push_array(scratch.arena, U64, comp_unit_range_list.count); + U64List *loc_lists = push_array(scratch.arena, U64List, cu_range_list.count); + U64 *address_sizes = push_array(scratch.arena, U64, cu_range_list.count); + U64 *address_bases = push_array(scratch.arena, U64, cu_range_list.count); { U64 comp_idx = 0; - for (Rng1U64Node *comp_unit_range_n = comp_unit_range_list.first; comp_unit_range_n != 0; comp_unit_range_n = comp_unit_range_n->next, ++comp_idx) { - Rng1U64 comp_unit_range = comp_unit_range_n->v; - DW_CompRoot comp_root = dw_comp_root_from_range(scratch.arena, sections, comp_unit_range, relaxed); - DW_AttribValueResolveParams resolve_params = dw_attrib_value_resolve_params_from_comp_root(&comp_root); - DW_Ext ext = dw_ext_from_params(comp_root.producer, arch, image_type); + for (Rng1U64Node *cu_range_n = cu_range_list.first; cu_range_n != 0; cu_range_n = cu_range_n->next, ++comp_idx) { + Rng1U64 cu_range = cu_range_n->v; + DW_CompUnit cu = dw_comp_unit_from_info_offset(scratch.arena, sections, cu_range.min, relaxed); // store info about comp unit - address_sizes[comp_idx] = comp_root.address_size; - address_bases[comp_idx] = comp_root.base_addr; + address_sizes[comp_idx] = cu.address_size; + address_bases[comp_idx] = cu.base_addr; // parse tags - for (U64 info_off = comp_root.tags_info_range.min; info_off < comp_root.tags_info_range.max; /* empty */) { - DW_Tag *tag = dw_tag_from_info_offset(scratch.arena, sections, comp_root.abbrev_table, comp_root.version, ext, comp_root.language, comp_root.address_size, info_off, relaxed); + for (U64 info_off = cu.tags_range.min; info_off < cu.tags_range.max; /* empty */) { + DW_Tag tag = dw_tag_from_info_offset_cu(scratch.arena, sections, &cu, info_off); // parse attribs - for (DW_AttribNode *attrib_node = tag->attribs.first; attrib_node != 0; attrib_node = attrib_node->next) { - DW_Attrib *attrib = &attrib_node->attrib; + for (DW_AttribNode *attrib_node = tag.attribs.first; attrib_node != 0; attrib_node = attrib_node->next) { + DW_Attrib *attrib = &attrib_node->v; B32 is_sect_offset = attrib->value_class == DW_AttribClass_RngListPtr || (attrib->value_class == DW_AttribClass_RngList && attrib->form_kind == DW_Form_SecOffset); B32 is_sect_index = attrib->value_class == DW_AttribClass_RngList && attrib->form_kind == DW_Form_RngListx; if (is_sect_offset) { - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, attrib->form_kind, attrib->value_class, attrib->form_value); - u64_list_push(scratch.arena, &loc_lists[comp_idx], attrib_value.v[0]); + u64_list_push(scratch.arena, &loc_lists[comp_idx], attrib->value.v[0]); } else if (is_sect_index) { // TODO: support for section indexing } } - info_off = tag->info_range.max; + + info_off = tag.next_info_off; } } } @@ -2900,7 +3030,7 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Section rd_printf("# %S", sections->v[DW_Section_Ranges].name); rd_indent(); rd_printf("%-8s %-8s %-8s", "Offset", "Min", "Max"); - for (U32 comp_idx = 0; comp_idx < comp_unit_range_list.count; ++comp_idx) { + for (U32 comp_idx = 0; comp_idx < cu_range_list.count; ++comp_idx) { U64Array locs = u64_array_from_list(scratch.arena, &loc_lists[comp_idx]); u64_array_sort(locs.count, locs.v); U64Array locs_set = remove_duplicates_u64_array(scratch.arena, locs); @@ -2947,11 +3077,14 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Section } } } +#endif } internal void -dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Input *input) { + NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_ARanges); Rng1U64 range = dw_range_from_sec(sections, DW_Section_ARanges); @@ -3033,11 +3166,14 @@ dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Sectio rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_Input *input) { + NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_Addr); Rng1U64 range = dw_range_from_sec(sections, DW_Section_Addr); @@ -3112,6 +3248,7 @@ dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_SectionAr rd_unindent(); scratch_end(scratch); +#endif } internal U64 @@ -3142,8 +3279,10 @@ dw_based_range_read_address(void *base, Rng1U64 range, U64 offset, Rng1U64Array } internal void -dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_virtual_ranges, Arch arch) +dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_virtual_ranges, Arch arch) { + NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_LocLists); Rng1U64 range = dw_range_from_sec(sections, DW_Section_LocLists); @@ -3259,8 +3398,10 @@ dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Secti String8 raw_expr = str8((U8*)base+cursor, expr_length); cursor += expr_length; - - String8 expression = dw_format_expression_single_line(temp.arena, raw_expr, address_size, arch, version, DW_Ext_Null, is_dwarf64); + + // TODO: we need actual cu base to format expression correctly + NotImplemented; + String8 expression = dw_format_expression_single_line(temp.arena, raw_expr, 0, address_size, arch, version, DW_Ext_Null, is_dwarf64); str8_list_pushf(temp.arena, &list, "(%S)", expression); } break; case DW_LocListEntryKind_StartXLength: { @@ -3287,11 +3428,14 @@ dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Secti rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_ranges) +dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_ranges) { + NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_RngLists); Rng1U64 range = dw_range_from_sec(sections, DW_Section_RngLists); @@ -3423,11 +3567,14 @@ dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Secti rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, DW_SectionKind sec) +dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_SectionKind sec) { +NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, sec); Rng1U64 range = dw_range_from_sec(sections, sec); @@ -3482,23 +3629,26 @@ dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Sectio rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_Input *input) { - dw_format_string_table(arena, out, indent, sections, DW_Section_PubNames); + dw_format_string_table(arena, out, indent, input, DW_Section_PubNames); } internal void -dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_Input *input) { - dw_format_string_table(arena, out, indent, sections, DW_Section_PubTypes); + dw_format_string_table(arena, out, indent, input, DW_Section_PubTypes); } internal void -dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Input *input) { +NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_LineStr); Rng1U64 range = dw_range_from_sec(sections, DW_Section_LineStr); @@ -3521,11 +3671,14 @@ dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Secti rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections) +dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input) { +NotImplemented; +#if 0 void *base = dw_base_from_sec(sections, DW_Section_StrOffsets); Rng1U64 range = dw_range_from_sec(sections, DW_Section_StrOffsets); @@ -3584,61 +3737,77 @@ dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Se rd_unindent(); scratch_end(scratch); +#endif } internal void -dw_format(Arena *arena, String8List *out, String8 indent, RD_Option opts, DW_SectionArray *sections, Arch arch, ImageType image_type) +dw_format(Arena *arena, String8List *out, String8 indent, RD_Option opts, DW_Input *input, Arch arch, ImageType image_type) { + Temp scratch = scratch_begin(&arena, 1); + Rng1U64Array segment_vranges = {0}; - B32 relaxed = !!(opts & RD_Option_RelaxDwarfParser); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input); + B32 relaxed = !!(opts & RD_Option_RelaxDwarfParser); if (opts & RD_Option_DebugInfo) { - dw_print_debug_info(arena, out, indent, sections, arch, image_type, relaxed); + dw_print_debug_info(arena, out, indent, input, lu_input, arch, relaxed); } if (opts & RD_Option_DebugAbbrev) { - dw_print_debug_abbrev(arena, out, indent, sections); + dw_print_debug_abbrev(arena, out, indent, input); } if (opts & RD_Option_DebugLine) { - dw_print_debug_line(arena, out, indent, sections, relaxed); + dw_print_debug_line(arena, out, indent, input, lu_input, relaxed); } if (opts & RD_Option_DebugStr) { - dw_print_debug_str(arena, out, indent, sections); + dw_print_debug_str(arena, out, indent, input); } if (opts & RD_Option_DebugLoc) { - dw_print_debug_loc(arena, out, indent, sections, arch, image_type, relaxed); + dw_print_debug_loc(arena, out, indent, input, arch, image_type, relaxed); } if (opts & RD_Option_DebugRanges) { - dw_print_debug_ranges(arena, out, indent, sections, arch, image_type, relaxed); + dw_print_debug_ranges(arena, out, indent, input, arch, image_type, relaxed); } if (opts & RD_Option_DebugARanges) { - dw_print_debug_aranges(arena, out, indent, sections); + dw_print_debug_aranges(arena, out, indent, input); } if (opts & RD_Option_DebugAddr) { - dw_print_debug_addr(arena, out, indent, sections); + dw_print_debug_addr(arena, out, indent, input); } if (opts & RD_Option_DebugLocLists) { - dw_print_debug_loclists(arena, out, indent, sections, segment_vranges, arch); + dw_print_debug_loclists(arena, out, indent, input, segment_vranges, arch); } if (opts & RD_Option_DebugRngLists) { - dw_print_debug_rnglists(arena, out, indent, sections, segment_vranges); + dw_print_debug_rnglists(arena, out, indent, input, segment_vranges); } if (opts & RD_Option_DebugPubNames) { - dw_print_debug_pubnames(arena, out, indent, sections); + dw_print_debug_pubnames(arena, out, indent, input); } if (opts & RD_Option_DebugPubTypes) { - dw_print_debug_pubtypes(arena, out, indent, sections); + dw_print_debug_pubtypes(arena, out, indent, input); } if (opts & RD_Option_DebugLineStr) { - dw_print_debug_line_str(arena, out, indent, sections); + dw_print_debug_line_str(arena, out, indent, input); } if (opts & RD_Option_DebugStrOffsets) { - dw_print_debug_str_offsets(arena, out, indent, sections); + dw_print_debug_str_offsets(arena, out, indent, input); } + + scratch_end(scratch); } // CodeView +internal String8 +cv_string_from_reg_off(Arena *arena, CV_Arch arch, U32 reg_idx, U32 reg_off) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 reg_str = cv_string_from_reg_id(scratch.arena, arch, reg_idx); + String8 result = rd_string_from_reg_off(arena, reg_str, reg_off); + scratch_end(scratch); + return result; +} + internal void cv_print_binary_annots(Arena *arena, String8List *out, String8 indent, CV_Arch arch, String8 raw_data) { @@ -6216,8 +6385,8 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); - dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); + DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); + dw_format(arena, out, indent, opts, &dwarf_input, arch, Image_CoffPe); } exit:; @@ -6385,56 +6554,6 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a scratch_end(scratch); } -internal String8 -coff_string_from_resource_id(Arena *arena, COFF_ResourceID id) -{ - String8 result = str8_zero(); - switch (id.type) { - case COFF_ResourceIDType_Null: result = str8_lit("\?\?\?"); break; - case COFF_ResourceIDType_Number: result = push_str8f(arena, "%u", id.u.number); break; - case COFF_ResourceIDType_String: result = id.u.string; break; - } - return result; -} - -internal void -coff_print_parsed_res(Arena *arena, String8List *out, String8 indent, COFF_ParsedResource *res) -{ - Temp scratch = scratch_begin(&arena, 1); - - String8 type; - if (res->type.type == COFF_ResourceIDType_Number) { - type = pe_resource_kind_to_string(res->type.u.number); - } else { - type = coff_string_from_resource_id(scratch.arena, res->type); - } - - String8 name = coff_string_from_resource_id(scratch.arena, res->name); - String8 flags = coff_string_from_resource_memory_flags(scratch.arena, res->memory_flags); - - rd_printf("Type: %S", type); - rd_printf("Name: %S", name); - rd_printf("Language ID: %u", res->language_id); - rd_printf("Data Version: %u", res->data_version); - rd_printf("Version: %u", res->version); - rd_printf("Memory Flags: %S", flags); - rd_printf("Data size: %u (bytes)", res->data.size); - - scratch_end(scratch); -} - -internal void -coff_print_res(Arena *arena, String8List *out, String8 indent, String8 raw_res) -{ - Temp scratch = scratch_begin(&arena, 1); - COFF_ParsedResourceList res_list = coff_resource_list_from_data(scratch.arena, raw_res); - for (COFF_ParsedResourceNode *n = res_list.first; n != 0; n = n->next) { - coff_print_parsed_res(arena, out, indent, &n->data); - rd_newline(); - } - scratch_end(scratch); -} - // MSVC CRT internal void @@ -7200,9 +7319,6 @@ pe_print_exceptions_x8664(Arena *arena, PE_IntelPdata *pdata = str8_deserial_get_raw_ptr(raw_except, pdata_offset, sizeof(*pdata)); String8 pdata_name = rd_proc_name_from_voff(rdi, pdata->voff_first); - if (pdata->voff_first == 0x0020cf44) { - int x = 0; - } U64 unwind_info_offset = coff_foff_from_voff(sections, section_count, pdata->voff_unwind_info); PE_UnwindInfo *uwinfo = str8_deserial_get_raw_ptr(raw_data, unwind_info_offset, sizeof(*uwinfo)); @@ -7958,11 +8074,130 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op } if (opts & RD_Option_Dwarf) { - DW_SectionArray dwarf_sections = dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); - dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe); + DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); + dw_format(arena, out, indent, opts, &dwarf_input, arch, Image_CoffPe); } exit:; scratch_end(scratch); } +#if 0 +internal void +elf_print_dwarf_expressions(Arena *arena, String8List *out, String8 indent, String8 raw_data) +{ + Temp scratch = scratch_begin(&arena, 1); + + ELF_BinInfo bin = elf_bin_from_data(raw_data); + Arch arch = arch_from_elf_machine(bin.hdr.e_machine); + DW_Input dwarf_input = dw_input_from_elf_section_table(scratch.arena, raw_data, &bin); + ELF_Class elf_class = bin.hdr.e_ident[ELF_Identifier_Class]; + ImageType image_type = elf_class == ELF_Class_32 ? Image_Elf32 : elf_class == ELF_Class_64 ? Image_Elf64 : ELF_Class_None; + B32 relaxed = 1; + Rng1U64List cu_ranges = dw_unit_ranges_from_data(scratch.arena, dwarf_input.sec[DW_Section_Info].data); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &dwarf_input); + + if (bin.hdr.e_type == ELF_Type_Exec || bin.hdr.e_type == ELF_Type_Dyn) { + U64 cu_idx = 0; + for (Rng1U64Node *cu_range_n = cu_ranges.first; cu_range_n != 0; cu_range_n = cu_range_n->next, ++cu_idx) { + Temp comp_temp = temp_begin(scratch.arena); + + U64 cu_base = cu_range_n->v.min; + Rng1U64 cu_range = cu_range_n->v; + DW_CompUnit cu = dw_cu_from_info_off(comp_temp.arena, &dwarf_input, lu_input, cu_range.min, relaxed); + + struct TagNode { + struct TagNode *next; + DW_Tag tag; + }; + struct TagNode *tag_stack = 0; + struct TagNode *free_tags = 0; + + S32 lexical_block_depth = 0; + + for (U64 info_off = cu.first_tag_info_off, tag_size = 0; info_off < cu.info_range.max; info_off += tag_size) { + DW_Tag tag = {0}; + tag_size = dw_read_tag_cu(comp_temp.arena, &dwarf_input, &cu, info_off, &tag); + if (tag.has_children) { + struct TagNode *n = free_tags; + if (n == 0) { + n = push_array(comp_temp.arena, struct TagNode, 1); + } else { + SLLStackPop(free_tags); + } + n->tag = tag; + SLLStackPush(tag_stack, n); + } + + if (tag.kind == DW_Tag_Null) { + if (tag_stack) { + struct TagNode *n = tag_stack; + if ((n->tag.kind == DW_Tag_SubProgram || n->tag.kind == DW_Tag_LexicalBlock)) { + Assert(lexical_block_depth > 0); + --lexical_block_depth; + } + SLLStackPop(tag_stack); + SLLStackPush(free_tags, n); + } + } else if (tag.kind == DW_Tag_LexicalBlock || tag.kind == DW_Tag_SubProgram) { + ++lexical_block_depth; + if (tag.kind == DW_Tag_SubProgram) { + String8 expr = dw_exprloc_from_attrib(&dwarf_input, &cu, tag, DW_Attrib_FrameBase); + if (expr.size > 0) { + String8 expr_str = dw_format_expression_single_line(comp_temp.arena, expr, cu_base, cu.address_size, arch, cu.version, cu.ext, cu.format); + } + } + } else if (tag.kind == DW_Tag_Variable || tag.kind == DW_Tag_FormalParameter) { +#if 0 + String8 name = dw_string_from_attrib(&dwarf_input, &cu, tag, DW_Attrib_Name); + DW_Attrib *location_attrib = dw_attrib_from_tag(&dwarf_input, &cu, tag, DW_Attrib_Location); + DW_AttribClass value_class = dw_value_class_from_attrib(&cu, location_attrib); + if (value_class != DW_AttribClass_Null) { + if (lexical_block_depth == 0) { + rd_printf("%llx Global: %S", info_off, name); + is_global_var = 1; + } else { + rd_printf("%llx Local: %S", info_off, name); + is_global_var = 0; + } + + rd_indent(); + if (value_class == DW_AttribClass_LocListPtr || value_class == DW_AttribClass_LocList) { + DW_LocList location = dw_loclist_from_attrib_ptr(comp_temp.arena, &dwarf_input, &cu, location_attrib); + for (DW_LocNode *loc_n = location.first; loc_n != 0; loc_n = loc_n->next) { + String8 expr_str = dw_format_expression_single_line(comp_temp.arena, loc_n->v.expr, cu_base, cu.address_size, arch, cu.version, cu.ext, cu.format); + rd_printf("[%llx-%llx] %S", loc_n->v.range.min, loc_n->v.range.max, expr_str); + } + } else if (value_class == DW_AttribClass_ExprLoc) { + String8 expr = dw_exprloc_from_attrib_ptr(&dwarf_input, &cu, location_attrib); + String8 expr_str = dw_format_expression_single_line(comp_temp.arena, expr, cu_base, cu.address_size, arch, cu.version, cu.ext, cu.format); + rd_printf("%S", expr_str); + } + rd_unindent(); + } +#endif + } + +#if 0 + if (tag.kind == DW_Tag_LexicalBlock || tag.kind == DW_Tag_CompileUnit || tag.kind == DW_Tag_InlinedSubroutine || tag.kind == DW_Tag_SubProgram) { + Temp temp = temp_begin(comp_temp.arena); + DW_Attrib *ranges_attrib = dw_attrib_from_tag(&dwarf_input, &cu, tag, DW_Attrib_Ranges); + if (ranges_attrib->attrib_kind == DW_Attrib_Ranges) { + Rng1U64List ranges = dw_rnglist_from_attrib_ptr(temp.arena, &dwarf_input, &cu, ranges_attrib); + } + temp_end(temp); + } +#endif + } + + temp_end(comp_temp); + } + } else { + fprintf(stderr, "Skipping unexpected ELF type %u\n", bin.hdr.e_type); + } + + scratch_end(scratch); +} +#endif + + diff --git a/src/raddump/raddump.h b/src/raddump/raddump.h index 37a2c360..684d154f 100644 --- a/src/raddump/raddump.h +++ b/src/raddump/raddump.h @@ -65,7 +65,7 @@ typedef U64 RD_Option; RD_Option_DebugStrOffsets) #define RD_Option_RelaxDwarfParser (1ull << 31ull) // RDI -#define RD_Option_NoRdi (1ull << 32ull) +#define RD_Option_NoRdi (1ull << 32ull) #define RD_Option_RdiDataSections (1ull << 33ull) #define RD_Option_RdiTopLevelInfo (1ull << 34ull) #define RD_Option_RdiBinarySections (1ull << 35ull) @@ -86,6 +86,27 @@ typedef U64 RD_Option; #define RD_Option_RdiInlineSites (1ull << 51ull) #define RD_Option_RdiNameMaps (1ull << 52ull) #define RD_Option_RdiStrings (1ull << 53ull) +#define RD_Option_RdiAll (RD_Option_RdiDataSections | \ + RD_Option_RdiTopLevelInfo | \ + RD_Option_RdiBinarySections | \ + RD_Option_RdiFilePaths | \ + RD_Option_RdiSourceFiles | \ + RD_Option_RdiLineTables | \ + RD_Option_RdiSourceLineMaps | \ + RD_Option_RdiUnits | \ + RD_Option_RdiUnitVMap | \ + RD_Option_RdiTypeNodes | \ + RD_Option_RdiUserDefinedTypes | \ + RD_Option_RdiGlobalVars | \ + RD_Option_RdiGlobalVarsVMap | \ + RD_Option_RdiThreadVars | \ + RD_Option_RdiProcedures | \ + RD_Option_RdiScopes | \ + RD_Option_RdiScopeVMap | \ + RD_Option_RdiInlineSites | \ + RD_Option_RdiNameMaps | \ + RD_Option_RdiStrings) + typedef struct RD_Marker { @@ -190,33 +211,33 @@ internal void rdi_print_type_node (Arena *arena, String8List *out, String8 internal void rdi_print_udt (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_UDT *udt); internal void rdi_print_global_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_GlobalVariable *gvar); internal void rdi_print_thread_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_ThreadVariable *tvar); -internal void rdi_print_procedure (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc); +internal void rdi_print_procedure (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc, RDI_Arch arch); internal void rdi_print_scope (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Scope *scope, RDI_Arch arch); internal void rdi_print_inline_site (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_InlineSite *inline_site); internal void rdi_print_vmap_entry (Arena *arena, String8List *out, String8 indent, RDI_VMapEntry *v); // DWARF -internal String8List dw_string_list_from_expression (Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64); -internal String8 dw_format_expression_single_line(Arena *arena, String8 raw_data, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64); +internal String8List dw_string_list_from_expression (Arena *arena, String8 raw_data, U64 cu_base, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format); +internal String8 dw_format_expression_single_line(Arena *arena, String8 raw_data, U64 cu_base, U64 address_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format); internal String8 dw_format_eh_ptr_enc (Arena *arena, DW_EhPtrEnc enc); -internal void dw_print_cfi_program (Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, B32 is_dwarf64); +internal void dw_print_cfi_program (Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format); internal void dw_print_eh_frame (Arena *arena, String8List *out, String8 indent, String8 raw_eh_frame, Arch arch, DW_Version ver, DW_Ext ext, DW_EhPtrCtx *ptr_ctx); -internal void dw_print_debug_info (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed); -internal void dw_print_debug_abbrev (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_line (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, B32 relaxed); -internal void dw_print_debug_str (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed); -internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Arch arch, ImageType image_type, B32 relaxed); -internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_vranges, Arch arch); -internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections, Rng1U64Array segment_vranges); -internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); -internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_SectionArray *sections); +internal void dw_print_debug_info (Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, Arch arch, B32 relaxed); +internal void dw_print_debug_abbrev (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_line (Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, B32 relaxed); +internal void dw_print_debug_str (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ImageType image_type, B32 relaxed); +internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ImageType image_type, B32 relaxed); +internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges, Arch arch); +internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges); +internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input); // CodeView diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index ef0a3b6a..cd465cfb 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -17,19 +17,27 @@ #include "third_party/zydis/zydis.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" +#define SINFL_IMPLEMENTATION +#include "third_party/sinfl/sinfl.h" //////////////////////////////// #include "base/base_inc.h" +#include "linker/base_ext/base_inc.h" #include "os/os_inc.h" #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" #include "path/path.h" +#include "linker/path_ext/path.h" +#include "linker/hash_table.h" #include "coff/coff.h" #include "coff/coff_enum.h" #include "coff/coff_parse.h" #include "pe/pe.h" +#include "elf/elf.h" +#include "elf/elf_parse.h" #include "msvc_crt/msvc_crt.h" #include "msvc_crt/msvc_crt_enum.h" #include "codeview/codeview.h" @@ -39,24 +47,32 @@ #include "msf/msf_parse.h" #include "pdb/pdb.h" #include "pdb/pdb_parse.h" -#include "rdi_from_pdb/rdi_from_pdb.h" #include "dwarf/dwarf.h" #include "dwarf/dwarf_parse.h" #include "dwarf/dwarf_expr.h" #include "dwarf/dwarf_unwind.h" #include "dwarf/dwarf_coff.h" +#include "dwarf/dwarf_elf.h" #include "dwarf/dwarf_enum.h" +#include "rdi_from_pdb/rdi_from_pdb.h" +#include "rdi_from_dwarf/rdi_from_dwarf.h" #include "base/base_inc.c" +#include "linker/base_ext/base_inc.c" #include "os/os_inc.c" #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" #include "path/path.c" +#include "linker/path_ext/path.c" +#include "linker/hash_table.c" #include "coff/coff.c" #include "coff/coff_enum.c" #include "coff/coff_parse.c" #include "pe/pe.c" +#include "elf/elf.c" +#include "elf/elf_parse.c" #include "msvc_crt/msvc_crt.c" #include "msvc_crt/msvc_crt_enum.c" #include "codeview/codeview.c" @@ -66,24 +82,20 @@ #include "msf/msf_parse.c" #include "pdb/pdb.c" #include "pdb/pdb_parse.c" -#include "rdi_from_pdb/rdi_from_pdb.c" #include "dwarf/dwarf.c" #include "dwarf/dwarf_parse.c" #include "dwarf/dwarf_expr.c" #include "dwarf/dwarf_unwind.c" #include "dwarf/dwarf_coff.c" +#include "dwarf/dwarf_elf.c" #include "dwarf/dwarf_enum.c" +#include "rdi_from_pdb/rdi_from_pdb.c" +#include "rdi_from_dwarf/rdi_from_dwarf.c" -#include "linker/base_ext/base_inc.h" -#include "linker/base_ext/base_inc.c" -#include "linker/path_ext/path.h" -#include "linker/path_ext/path.c" #include "linker/thread_pool/thread_pool.h" #include "linker/thread_pool/thread_pool.c" #include "linker/codeview_ext/codeview.h" #include "linker/codeview_ext/codeview.c" -#include "linker/hash_table.h" -#include "linker/hash_table.c" #include "linker/rdi/rdi.h" #include "linker/rdi/rdi.c" @@ -265,6 +277,10 @@ entry_point(CmdLine *cmdline) case RDI_ParseStatus_MissingRequiredSection: rd_errorf("RDI Parse: missing required section"); break; default: rd_errorf("RDI Parse: unknown parse status %u", parse_status); break; } + if ((opts & RD_Option_RdiAll) == 0) { + opts = RD_Option_RdiAll; + } + rdi_print(arena, out, indent, &rdi, opts); } else if (coff_is_regular_archive(raw_data) || coff_is_thin_archive(raw_data)) { coff_print_archive(arena, out, indent, raw_data, opts); } else if (coff_is_big_obj(raw_data)) { @@ -278,7 +294,9 @@ entry_point(CmdLine *cmdline) } pe_print(arena, out, indent, raw_data, opts, rdi); } else if (pe_is_res(raw_data)) { - coff_print_res(arena, out, indent, raw_data); + //tool_out_coff_res(stdout, file_data); + } else if (elf_check_magic(raw_data)) { + //elf_print_dwarf_expressions(arena, out, indent, raw_data); } exit:; From 13352751ec00d1e557d67fce6043ef953dce4cd7 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 17 Mar 2025 10:40:59 -0700 Subject: [PATCH 213/755] moved DWARF parser to use str8_deserial-style API, added to the parser layer functionality for interpreting different types of attributes, added support for location lists, and API to enable parsing tags with abstract origin. --- build.bat | 2 +- src/dwarf/dwarf_coff.c | 2 +- src/dwarf/dwarf_coff.h | 23 +- src/dwarf/dwarf_elf.c | 104 + src/dwarf/dwarf_elf.h | 11 + src/dwarf/dwarf_parse.c | 4709 +++++++++++++--------- src/dwarf/dwarf_parse.h | 651 ++- src/dwarf/dwarf_unwind.c | 3 + src/linker/hash_table.c | 7 + src/rdi_from_dwarf/rdi_from_dwarf.c | 2741 +++++++++---- src/rdi_from_dwarf/rdi_from_dwarf.h | 95 +- src/rdi_from_dwarf/rdi_from_dwarf_main.c | 122 + 12 files changed, 5222 insertions(+), 3248 deletions(-) create mode 100644 src/dwarf/dwarf_elf.c create mode 100644 src/dwarf/dwarf_elf.h create mode 100644 src/rdi_from_dwarf/rdi_from_dwarf_main.c diff --git a/build.bat b/build.bat index 2187d8f6..6529d9e5 100644 --- a/build.bat +++ b/build.bat @@ -109,7 +109,7 @@ if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 -if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 +if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf_main.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1 if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1 if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1 diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c index 942ca306..d8158251 100644 --- a/src/dwarf/dwarf_coff.c +++ b/src/dwarf/dwarf_coff.c @@ -3,5 +3,5 @@ #pragma once -internal DW_SectionArray dw_sections_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); +internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h index 368bff78..3a772531 100644 --- a/src/dwarf/dwarf_coff.h +++ b/src/dwarf/dwarf_coff.h @@ -1,15 +1,15 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal DW_SectionArray -dw_sections_from_coff_section_table(Arena *arena, - String8 raw_image, - U64 string_table_off, - U64 section_count, - COFF_SectionHeader *sections) +internal DW_Input +dw_input_from_coff_section_table(Arena *arena, + String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) { - DW_SectionArray result = {0}; - B32 sect_status[ArrayCount(result.v)] = {0}; + DW_Input input = {0}; + B32 sect_status[ArrayCount(input.sec)] = {0}; for (U64 i = 0; i < section_count; ++i) { COFF_SectionHeader *header = §ions[i]; @@ -18,7 +18,7 @@ dw_sections_from_coff_section_table(Arena *arena, DW_SectionKind s = DW_Section_Null; B32 is_dwo = 0; - #define X(_K,_L,_M,_W) \ + #define X(_K,_L,_M,_W) \ if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } @@ -30,16 +30,15 @@ dw_sections_from_coff_section_table(Arena *arena, Assert(!"too many debug sections with identical name, picking first"); } else { sect_status[s] = 1; - DW_Section *d = &result.v[s]; + DW_Section *d = &input.sec[s]; d->name = push_str8_copy(arena, name); d->data = str8_substr(raw_image, raw_data_range); - d->mode = dim_1u64(raw_data_range) > max_U32 ? DW_Mode_64Bit : DW_Mode_32Bit; d->is_dwo = is_dwo; } } } - return result; + return input; } diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c new file mode 100644 index 00000000..55d6e4f7 --- /dev/null +++ b/src/dwarf/dwarf_elf.c @@ -0,0 +1,104 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal DW_Input +dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin) +{ + Temp scratch = scratch_begin(&arena, 1); + + DW_Input result = {0}; + B32 sect_status[ArrayCount(result.sec)] = {0}; + + ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); + String8 sh_names = str8_substr(raw_image, bin->sh_name_range); + + for (U64 sect_idx = 1; sect_idx < sections.count; ++sect_idx) { + ELF_Shdr64 *shdr = §ions.v[sect_idx]; + + // skip BSS sections + if (shdr->sh_type != ELF_SectionCode_ProgBits) { + continue; + } + + String8 name = {0}; + str8_deserial_read_cstr(sh_names, shdr->sh_name, &name); + + DW_SectionKind s = DW_Section_Null; + B32 is_dwo = 0; + #define X(_K,_L,_M,_W) \ + if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } + DW_SectionKind_XList(X) + #undef X + + if (s != DW_Section_Null) { + if (sect_status[s]) { + Assert(!"too many debug sections with identical name, picking first"); + } else { + Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size); + String8 data = str8_substr(raw_image, raw_data_range); + + // ELF was compiled with compressed debug info + if (shdr->sh_flags & ELF_Shf_Compressed) { + String8 comp_data_with_header = data; + + // read header + ELF_Chdr64 chdr64 = {0}; + U64 chdr_size = 0; + if (ELF_HdrIs64Bit(bin->hdr.e_ident)) { + chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr64); + if (chdr_size != sizeof(chdr64)) { + Assert(!"not enough bytes to read header"); + } + } else if (ELF_HdrIs32Bit(bin->hdr.e_ident)) { + ELF_Chdr32 chdr32 = {0}; + chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr32); + if (chdr_size == sizeof(chdr32)) { + chdr64 = elf_chdr64_from_chdr32(chdr32); + } + } + + AssertAlways(IsPow2(chdr64.ch_addr_align)); + + // skip header + String8 comp_data = str8_skip(comp_data_with_header, chdr_size); + + // push buffer for the decompressor + U8 *decomp_buffer = push_array_no_zero_aligned(arena, U8, chdr64.ch_size, chdr64.ch_addr_align); + U64 actual_decomp_size = 0; + + // decompress + switch (chdr64.ch_type) { + case ELF_CompressType_None: { + AssertAlways(!"unexpected compression type"); + } break; + case ELF_CompressType_ZLib: { + actual_decomp_size = zsinflate(decomp_buffer, chdr64.ch_size, comp_data.str, comp_data.size); + } break; + case ELF_CompressType_ZStd: { + // TODO: zstd lib + NotImplemented; + } break; + default: InvalidPath; break; + } + + // TODO: error handling + AssertAlways(actual_decomp_size == chdr64.ch_size); + + // set decompressed section data + data = str8(decomp_buffer, actual_decomp_size); + } + + sect_status[s] = 1; + DW_Section *d = &result.sec[s]; + d->name = push_str8_copy(arena, name); + d->data = data; + d->is_dwo = is_dwo; + } + } + } + + scratch_end(scratch); + return result; +} diff --git a/src/dwarf/dwarf_elf.h b/src/dwarf/dwarf_elf.h new file mode 100644 index 00000000..776e7b2c --- /dev/null +++ b/src/dwarf/dwarf_elf.h @@ -0,0 +1,11 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef DWARF_ELF_H +#define DWARF_ELF_H + +internal DW_Input dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin); + +#endif // DWARF_ELF_H + + diff --git a/src/dwarf/dwarf_parse.c b/src/dwarf/dwarf_parse.c index aa2c7d3e..e0cd5e4e 100644 --- a/src/dwarf/dwarf_parse.c +++ b/src/dwarf/dwarf_parse.c @@ -1,66 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -// TODO(rjf): -// -// [ ] Any time we encode a subrange of a section inside of a -// DW_AttribValue, we need to do that consistently, regardless of -// whether or not it is a string, memory block, etc. We should just use -// the DW_SectionKind and then the min/max pair. -// -// [ ] Things we are not reporting, or haven't figured out: -// @dwarf_expr @dwarf_v5 @dw_cross_unit -// [ ] currently, we're filtering out template arguments in the member accelerator. -// this is because they don't correspond one-to-one with anything in PDB, but -// they do contain useful information that we might want to expose another way -// somehow. -// [ ] DWARF V5 features that nobody seems to use right now -// [ ] ref_addr_desc + next_info_ctx -// apparently these are necessary when dereferencing some DWARF V5 ways of -// forming references. They don't seem to come up at all for any real data -// but might be a case somewhere. -// [ ] case when only .debug_line and .debug_line_str is available, without -// compilation unit debug info? do we care about this at all? -// [ ] DW_Form_RefSig8, which requires using .debug_names -// to do a lookup for a reference -// [ ] DWARF V5, but also V1 & V2 for dw_range_list_from_range_offset -// [ ] DW_AttribClass_RngList and DW_Form_RngListx -// [ ] DW_OpCode_XDEREF_SIZE + DW_OpCode_XDEREF -// [ ] DW_OpCode_PIECE + DW_OpCode_BIT_PIECE -// [ ] DW_ExtOpcode_DefineFile, for line info -// [ ] DWARF procedures in DWARF expr evaluation -// [ ] DW_Attrib_DataMemberLocation is not being *fully* handled right -// now; full handling requires evaluating a DWARF expression to find out the -// offset of a member. Right now we handle the common case, which is when it -// is encoded as a constant value. -// [ ] inline information -// [ ] full info we are not handling: -// [ ] friend classes -// [ ] DWARF macro info -// [ ] whether or not a function is the entry point -// [ ] attributes we are not handling that may be important: -// [ ] DW_Attrib_AbstractOrigin -// - ??? -// [ ] DW_Attrib_VariableParameter -// - determines whether or not a parameter to a function is mutable, I think? -// [ ] DW_Attrib_Mutable -// - I think this is for specific keywords, may not be relevant to C/++ -// [ ] DW_Attrib_CallColumn -// - column position of an inlined subroutine -// [ ] DW_Attrib_CallFile -// - file of inlined subroutine -// [ ] DW_Attrib_CallLine -// - line number of inlined subroutine -// [ ] DW_Attrib_ConstExpr -// - ??? maybe C++ constexpr? -// [ ] DW_Attrib_EnumClass -// - c++ thing that's an enum with a backing type -// [ ] DW_Attrib_LinkageName -// - name used to do linking - -//////////////////////////////// -//~ rjf: Basic Helpers - internal U64 dw_hash_from_string(String8 string) { @@ -68,86 +8,97 @@ dw_hash_from_string(String8 string) return hash64; } -//////////////////////////////// -//~ rjf: DWARF-Specific Based Range Reads - internal U64 -dw_based_range_read(void *base, Rng1U64 range, U64 offset, U64 size, void *out) +str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out) { - String8 data = str8((U8*)base+range.min, dim_1u64(range)); - return str8_deserial_read(data, offset, out, size, 1); -} - -internal String8 -dw_based_range_read_string(void *base, Rng1U64 range, U64 offset) -{ - String8 data = str8((U8*)base+range.min, dim_1u64(range)); - String8 result = {0}; - str8_deserial_read_cstr(data, offset, &result); - return result; -} - -internal void * -dw_based_range_ptr(void *base, Rng1U64 range, U64 offset) -{ - Assert(offset < dim_1u64(range)); - U8 *data = (U8*)base + range.min + offset; - return data; -} - -internal void * -dw_based_range_ptr_size(void *base, Rng1U64 range, U64 offset, U64 size) -{ - void *ptr = 0; - if (size > 0 && offset + size <= dim_1u64(range)) { - ptr = dw_based_range_ptr(base, range, offset); - } - return ptr; -} - -internal U64 -dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 offset, U64 *out_value) -{ - U64 value = 0; U64 bytes_read = 0; - U64 shift = 0; - U8 byte = 0; - for(U64 cursor = offset; - dw_based_range_read_struct(base, range, cursor, &byte) == 1; - cursor += 1) - { - bytes_read += 1; - U8 val = byte & 0x7fu; - value |= ((U64)val) << shift; - if((byte&0x80u) == 0) - { - break; + if (str8_deserial_read(string, off, size_out, sizeof(U32), sizeof(U32))) { + if (*size_out == max_U32) { + if (str8_deserial_read_struct(string, off+sizeof(U32), size_out)) { + bytes_read = sizeof(U32) + sizeof(U64); + } + } else { + *size_out &= (U64)max_U32; + bytes_read = sizeof(U32); } - shift += 7u; - } - if(out_value != 0) - { - *out_value = value; } return bytes_read; } internal U64 -dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_value) +str8_deserial_read_dwarf_uint(String8 string, U64 off, DW_Format format, U64 *uint_out) { - U64 value = 0; U64 bytes_read = 0; - U64 shift = 0; - U8 byte = 0; - for(U64 cursor = offset; - dw_based_range_read_struct(base, range, cursor, &byte) == 1; - cursor += 1) + switch (format) { + case DW_Format_Null: break; + case DW_Format_32Bit: { + *uint_out &= (U64)max_U32; + bytes_read = str8_deserial_read(string, off, uint_out, sizeof(U32), sizeof(U32)); + } break; + case DW_Format_64Bit: { + bytes_read = str8_deserial_read_struct(string, off, uint_out); + } break; + } + return bytes_read; +} + +internal U64 +str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) { - bytes_read += 1; + U8 byte = 0; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + + if(bytes_read != sizeof(byte)) + { + break; + } + U8 val = byte & 0x7fu; value |= ((U64)val) << shift; + + cursor += bytes_read; shift += 7u; - if((byte&0x80u) == 0) + + if((byte & 0x80u) == 0) + { + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) { if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) { @@ -156,43 +107,315 @@ dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_valu break; } } - if(out_value != 0) + if(value_out != 0) { - *out_value = value; + *value_out = value; } + U64 bytes_read = cursor - off; return bytes_read; } internal U64 -dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value) +str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out) { + Temp temp = temp_begin(arena); + + U64 *arr = push_array(arena, U64, count); + U64 i, cursor; + for (i = 0, cursor = off; i < count; ++i) { + U64 read_size = str8_deserial_read_uleb128(string, cursor, &arr[i]); + if (read_size == 0) { + break; + } + cursor += read_size; + } + U64 bytes_read = 0; - U64 value = 0; - U32 first32 = 0; - if(dw_based_range_read_struct(base, range, offset, &first32)) - { - // NOTE(rjf): DWARF 32-bit => use the first 32 bits as the size. - if(first32 != max_U32) - { - value = (U64)first32; - bytes_read = sizeof(U32); - } - // NOTE(rjf): DWARF 64-bit => first 32 are just a marker, use the next 64 bits as the size. - else if(dw_based_range_read_struct(base, range, offset + sizeof(U32), &value)) - { - value = 0; - bytes_read = sizeof(U32) + sizeof(U64); - } - } - if(out_value != 0) - { - *out_value = value; + if (i == count) { + *arr_out = arr; + bytes_read = cursor - off; + } else { + temp_end(temp); + *arr_out = 0; } + return bytes_read; } internal U64 -dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev) +str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out) +{ + Temp temp = temp_begin(arena); + + S64 *arr = push_array(arena, S64, count); + U64 i, cursor; + for (i = 0, cursor = off; i < count; ++i) { + U64 read_size = str8_deserial_read_sleb128(string, cursor, &arr[i]); + if (read_size == 0) { + break; + } + cursor += read_size; + } + + U64 bytes_read = 0; + if (i == count) { + *arr_out = arr; + bytes_read = cursor - off; + } else { + temp_end(temp); + *arr_out = 0; + } + + return bytes_read; +} + +internal Rng1U64List +dw_unit_ranges_from_data(Arena *arena, String8 data) +{ + Rng1U64List result = {0}; + + for (U64 cursor = 0; cursor < data.size; ) { + // read CU size + U64 cu_size = 0; + U64 cu_size_size = str8_deserial_read_dwarf_packed_size(data, cursor, &cu_size); + + // was read ok? + if (cu_size_size == 0) { + break; + } + + if (cu_size > 0) { + // push unit range + rng1u64_list_push(arena, &result, rng_1u64(cursor, cursor+cu_size+cu_size_size)); + } + + // advance + cursor += cu_size_size; + cursor += cu_size; + } + + return result; +} + +internal U64 +dw_read_list_unit_header_addr(String8 unit_data, DW_ListUnit *lu_out) +{ + U64 header_size = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); + + if (unit_length_size) { + DW_Version version = DW_Version_Null; + U64 version_size = str8_deserial_read_struct(unit_data, unit_length_size, &version); + + if (version_size) { + if (version >= DW_Version_5) { + U8 address_size = 0; + U64 address_size_size = str8_deserial_read_struct(unit_data, + unit_length_size + version_size, + &address_size); + + if (address_size_size && address_size) { + U8 segment_selector_size = 0; + U64 segment_selector_size_size = str8_deserial_read_struct(unit_data, + unit_length_size + version_size + address_size_size, + &segment_selector_size); + if (segment_selector_size_size) { + header_size = unit_length_size + version_size + address_size_size + segment_selector_size_size; + + lu_out->version = version; + lu_out->segment_selector_size = segment_selector_size; + lu_out->address_size = address_size; + lu_out->entry_size = segment_selector_size + address_size; + lu_out->entries = str8_skip(unit_data, header_size); + } + } + } + } + } + + return header_size; +} + +internal U64 +dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out) +{ + U64 header_size = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); + + if (unit_length_size) { + DW_Version version = DW_Version_Null; + U64 version_size = str8_deserial_read_struct(unit_data, unit_length_size, &version); + + if (version >= DW_Version_5) { + U16 padding = 0; + U64 padding_size = str8_deserial_read_struct(unit_data, unit_length_size + version_size, &padding); + + if (padding_size && padding == 0) { + header_size = unit_length_size + version_size + padding_size; + + lu_out->version = version; + lu_out->address_size = 0; + lu_out->segment_selector_size = 0; + lu_out->entry_size = dw_size_from_format(DW_FormatFromSize(unit_length)); + lu_out->entries = str8_skip(unit_data, header_size); + } + } + } + + return header_size; +} + +internal U64 +dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out) +{ + U64 header_size = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); + + if (unit_length_size) { + DW_Version version = DW_Version_Null; + U64 version_size = str8_deserial_read_struct(unit_data, unit_length_size, &version); + + if (version >= DW_Version_5) { + U8 address_size = 0; + U64 address_size_size = str8_deserial_read_struct(unit_data, unit_length_size + version_size, &address_size); + + if (address_size_size && address_size > 0) { + U8 segment_selector_size = 0; + U64 segment_selector_size_size = str8_deserial_read_struct(unit_data, unit_length_size + version_size + address_size_size, &segment_selector_size); + + if (segment_selector_size_size) { + U32 offset_entry_count = 0; + U64 offset_entry_count_size = str8_deserial_read_struct(unit_data, unit_length_size + version_size + address_size_size + segment_selector_size, &offset_entry_count); + + if (offset_entry_count_size) { + header_size = unit_length_size + version_size + address_size_size + segment_selector_size_size + offset_entry_count_size; + + lu_out->version = version; + lu_out->address_size = address_size; + lu_out->segment_selector_size = segment_selector_size; + lu_out->entry_size = dw_size_from_format(DW_FormatFromSize(unit_length)); + lu_out->entries = str8_skip(unit_data, header_size); + } + } + } + } + } + + return header_size; +} + +internal DW_ListUnitInput +dw_list_unit_input_from_input(Arena *arena, DW_Input *input) +{ + Temp scratch = scratch_begin(&arena, 1); + + DW_ListUnitInput result = {0}; + + DW_Section debug_addr = input->sec[DW_Section_Addr]; + { + String8 data = debug_addr.data; + Rng1U64List unit_ranges = dw_unit_ranges_from_data(scratch.arena, data); + + result.addr_ranges = rng1u64_array_from_list(arena, &unit_ranges); + result.addr_count = unit_ranges.count; + result.addrs = push_array(arena, DW_ListUnit, unit_ranges.count); + + for (U64 unit_idx = 0; unit_idx < result.addr_ranges.count; ++unit_idx) { + String8 unit_data = str8_substr(debug_addr.data, result.addr_ranges.v[unit_idx]); + dw_read_list_unit_header_addr(unit_data, &result.addrs[unit_idx]); + } + } + + DW_Section debug_str_offsets = input->sec[DW_Section_StrOffsets]; + { + String8 data = debug_str_offsets.data; + Rng1U64List unit_ranges = dw_unit_ranges_from_data(scratch.arena, data); + + result.str_offset_ranges = rng1u64_array_from_list(arena, &unit_ranges); + result.str_offset_count = unit_ranges.count; + result.str_offsets = push_array(arena, DW_ListUnit, unit_ranges.count); + + for (U64 unit_idx = 0; unit_idx < result.str_offset_ranges.count; ++unit_idx) { + String8 unit_data = str8_substr(data, result.str_offset_ranges.v[unit_idx]); + dw_read_list_unit_header_str_offsets(unit_data, &result.str_offsets[unit_idx]); + } + } + + DW_Section debug_rnglists = input->sec[DW_Section_RngLists]; + { + String8 data = debug_rnglists.data; + Rng1U64List unit_ranges = dw_unit_ranges_from_data(scratch.arena, data); + + result.rnglist_ranges = rng1u64_array_from_list(arena, &unit_ranges); + result.rnglist_count = unit_ranges.count; + result.rnglists = push_array(arena, DW_ListUnit, unit_ranges.count); + + for (U64 unit_idx = 0; unit_idx < result.rnglist_ranges.count; ++unit_idx) { + String8 unit_data = str8_substr(data, result.rnglist_ranges.v[unit_idx]); + dw_read_list_unit_header_list(unit_data, &result.rnglists[unit_idx]); + } + } + + DW_Section debug_loclists = input->sec[DW_Section_LocLists]; + { + String8 data = debug_loclists.data; + Rng1U64List unit_ranges = dw_unit_ranges_from_data(scratch.arena, data); + + result.loclist_ranges = rng1u64_array_from_list(arena, &unit_ranges); + result.loclist_count = unit_ranges.count; + result.loclists = push_array(arena, DW_ListUnit, unit_ranges.count); + + for (U64 unit_idx = 0; unit_idx < result.loclist_ranges.count; ++unit_idx) { + String8 unit_data = str8_substr(data, result.loclist_ranges.v[unit_idx]); + dw_read_list_unit_header_list(unit_data, &result.loclists[unit_idx]); + } + } + + scratch_end(scratch); + return result; +} + +internal U64 +dw_offset_from_list_unit(DW_ListUnit *lu, U64 index) +{ + U64 offset; + U64 entry_off = index * lu->entry_size; + if (entry_off + lu->entry_size <= lu->entries.size) { + offset = 0; + MemoryCopy(&offset, lu->entries.str + entry_off, lu->entry_size); + } else { + offset = max_U64; + } + return offset; +} + +internal U64 +dw_addr_from_list_unit(DW_ListUnit *lu, U64 index) +{ + U64 seg = 0; + U64 addr = max_U64; + U64 entry_count = lu->entries.size / lu->entry_size; + if (index < entry_count) { + U64 seg_off = lu->entry_size * index; + U64 addr_off = seg_off + lu->segment_selector_size; + MemoryCopy(&seg, lu->entries.str + seg_off, lu->segment_selector_size); + MemoryCopy(&addr, lu->entries.str + addr_off, lu->address_size); + // TODO: segment-based addressing + AssertAlways(seg == 0); + } else { + Assert(!"out of bounds index"); + } + return addr; +} + +internal U64 +dw_read_abbrev_tag(String8 data, U64 offset, DW_Abbrev *out_abbrev) { U64 total_bytes_read = 0; @@ -201,7 +424,7 @@ dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev U64 sub_kind_off = id_off; U64 id = 0; { - U64 bytes_read = dw_based_range_read_uleb128(base, range, id_off, &id); + U64 bytes_read = str8_deserial_read_uleb128(data, id_off, &id); sub_kind_off += bytes_read; total_bytes_read += bytes_read; } @@ -211,7 +434,7 @@ dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev U64 next_off = sub_kind_off; if(id != 0) { - U64 bytes_read = dw_based_range_read_uleb128(base, range, sub_kind_off, &sub_kind); + U64 bytes_read = str8_deserial_read_uleb128(data, sub_kind_off, &sub_kind); next_off += bytes_read; total_bytes_read += bytes_read; } @@ -220,17 +443,16 @@ dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev U8 has_children = 0; if(id != 0) { - total_bytes_read += dw_based_range_read_struct(base, range, next_off, &has_children); + total_bytes_read += str8_deserial_read_struct(data, next_off, &has_children); } //- rjf: fill abbrev if(out_abbrev != 0) { - DW_Abbrev abbrev = {0}; - abbrev.kind = DW_Abbrev_Tag; - abbrev.abbrev_range = rng_1u64(range.min+offset, range.min+offset+total_bytes_read); - abbrev.sub_kind = sub_kind; - abbrev.id = id; + DW_Abbrev abbrev = {0}; + abbrev.kind = DW_Abbrev_Tag; + abbrev.sub_kind = sub_kind; + abbrev.id = id; if(has_children) { abbrev.flags |= DW_AbbrevFlag_HasChildren; @@ -242,7 +464,7 @@ dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev } internal U64 -dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev) +dw_read_abbrev_attrib(String8 data, U64 offset, DW_Abbrev *out_abbrev) { U64 total_bytes_read = 0; @@ -251,7 +473,7 @@ dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW U64 sub_kind_off = id_off; U64 id = 0; { - U64 bytes_read = dw_based_range_read_uleb128(base, range, id_off, &id); + U64 bytes_read = str8_deserial_read_uleb128(data, id_off, &id); sub_kind_off += bytes_read; total_bytes_read += bytes_read; } @@ -260,7 +482,7 @@ dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW U64 sub_kind = 0; U64 next_off = sub_kind_off; { - U64 bytes_read = dw_based_range_read_uleb128(base, range, sub_kind_off, &sub_kind); + U64 bytes_read = str8_deserial_read_uleb128(data, sub_kind_off, &sub_kind); next_off += bytes_read; total_bytes_read += bytes_read; } @@ -269,7 +491,7 @@ dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW U64 implicit_const = 0; if(sub_kind == DW_Form_ImplicitConst) { - U64 bytes_read = dw_based_range_read_uleb128(base, range, next_off, &implicit_const); + U64 bytes_read = str8_deserial_read_uleb128(data, next_off, &implicit_const); total_bytes_read += bytes_read; } @@ -278,7 +500,6 @@ dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW { DW_Abbrev abbrev = {0}; abbrev.kind = DW_Abbrev_Attrib; - abbrev.abbrev_range = rng_1u64(offset, offset+total_bytes_read); abbrev.sub_kind = sub_kind; abbrev.id = id; if(sub_kind == DW_Form_ImplicitConst) @@ -292,200 +513,16 @@ dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW return total_bytes_read; } -internal U64 -dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out) -{ - U64 bytes_read = 0; - U64 bytes_to_read = 0; - DW_AttribValue form_value = {0}; - - switch(form_kind) - { - case DW_Form_Null: break; - - //- rjf: 1-byte uint reads - case DW_Form_Ref1: case DW_Form_Data1: case DW_Form_Flag: - case DW_Form_Strx1: case DW_Form_Addrx1: - bytes_to_read = 1; goto read_fixed_uint; - - //- rjf: 2-byte uint reads - case DW_Form_Ref2: case DW_Form_Data2: case DW_Form_Strx2: - case DW_Form_Addrx2: - bytes_to_read = 2; goto read_fixed_uint; - - //- rjf: 3-byte uint reads - case DW_Form_Strx3: case DW_Form_Addrx3: - bytes_to_read = 3; goto read_fixed_uint; - - //- rjf: 4-byte uint reads - case DW_Form_Data4: case DW_Form_Ref4: case DW_Form_RefSup4: case DW_Form_Strx4: case DW_Form_Addrx4: - bytes_to_read = 4; goto read_fixed_uint; - - //- rjf: 8-byte uint reads - case DW_Form_Data8: case DW_Form_Ref8: case DW_Form_RefSig8: case DW_Form_RefSup8: - bytes_to_read = 8; goto read_fixed_uint; - - //- rjf: address-size reads - case DW_Form_Addr: bytes_to_read = address_size; goto read_fixed_uint; - - //- rjf: offset-size reads - case DW_Form_RefAddr: case DW_Form_SecOffset: case DW_Form_LineStrp: - case DW_Form_Strp: case DW_Form_StrpSup: - bytes_to_read = dw_offset_size_from_mode(mode); goto read_fixed_uint; - - //- rjf: fixed-size uint reads - { - read_fixed_uint:; - U64 value = 0; - bytes_read = dw_based_range_read(base, range, offset, bytes_to_read, &value); - form_value.v[0] = value; - } break; - - //- rjf: uleb128 reads - case DW_Form_UData: case DW_Form_RefUData: case DW_Form_Strx: - case DW_Form_Addrx: case DW_Form_LocListx: case DW_Form_RngListx: - { - U64 value = 0; - bytes_read = dw_based_range_read_uleb128(base, range, offset, &value); - form_value.v[0] = value; - } break; - - //- rjf: sleb128 reads - case DW_Form_SData: - { - S64 value = 0; - bytes_read = dw_based_range_read_sleb128(base, range, offset, &value); - form_value.v[0] = value; - } break; - - //- rjf: fixed-size uint read + skip - case DW_Form_Block1: bytes_to_read = 1; goto read_fixed_uint_skip; - case DW_Form_Block2: bytes_to_read = 2; goto read_fixed_uint_skip; - case DW_Form_Block4: bytes_to_read = 4; goto read_fixed_uint_skip; - { - read_fixed_uint_skip:; - U64 size = 0; - bytes_read = dw_based_range_read(base, range, offset, bytes_to_read, &size); - form_value.v[0] = size; - form_value.v[1] = offset; - bytes_read += size; - } break; - - //- rjf: uleb 128 read + skip - case DW_Form_Block: - { - U64 size = 0; - bytes_read = dw_based_range_read_uleb128(base, range, offset, &size); - form_value.v[0] = size; - form_value.v[1] = offset; - bytes_read += size; - } break; - - //- rjf: u64 ranges - case DW_Form_Data16: - { - U64 value1 = 0; - U64 value2 = 0; - bytes_read += dw_based_range_read_struct(base, range, offset, &value1); - bytes_read += dw_based_range_read_struct(base, range, offset + sizeof(U64), &value2); - form_value.v[0] = value1; - form_value.v[1] = value2; - } break; - - //- rjf: strings - case DW_Form_String: - { - String8 string = dw_based_range_read_string(base, range, offset); - bytes_read = string.size + 1; - U64 string_offset = offset; - U64 string_size = (offset + bytes_read) - string_offset; - form_value.v[0] = string_offset; - form_value.v[1] = string_offset+string_size-1; - } break; - - //- rjf: implicit const - case DW_Form_ImplicitConst: - { - // Special case. - // Unlike other forms that have their values stored in the .debug_info section, - // This one defines it's value in the .debug_abbrev section. - form_value.v[0] = implicit_const; - } break; - - //- rjf: expr loc - case DW_Form_ExprLoc: - { - U64 size = 0; - bytes_read = dw_based_range_read_uleb128(base, range, offset, &size); - form_value.v[0] = offset + bytes_read; - form_value.v[1] = size; - bytes_read += size; - } break; - - //- rjf: flag present - case DW_Form_FlagPresent: - { - form_value.v[0] = 1; - } break; - - case DW_Form_Indirect: - { - InvalidPath; - } break; - } - - if(form_value_out != 0) - { - *form_value_out = form_value; - } - - return bytes_read; -} - -//- rjf: important DWARF section base/range accessors - -internal DW_Mode -dw_mode_from_sec(DW_SectionArray *sections, DW_SectionKind kind) -{ - if(sections->v[kind].data.size > 0xffffffff) - { - return DW_Mode_64Bit; - } - else - { - return DW_Mode_32Bit; - } -} - -internal Rng1U64 -dw_range_from_sec(DW_SectionArray *sections, DW_SectionKind kind) -{ - Rng1U64 result = rng_1u64(0, sections->v[kind].data.size); - return result; -} - -internal void * -dw_base_from_sec(DW_SectionArray *sections, DW_SectionKind kind) -{ - return sections->v[kind].data.str; -} - -//////////////////////////////// -//~ rjf: Abbrev Table - internal DW_AbbrevTable -dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 abbrev_offset) +dw_make_abbrev_table(Arena *arena, String8 abbrev_data, U64 abbrev_offset) { - void *file_base = dw_base_from_sec(sections, DW_Section_Abbrev); - Rng1U64 abbrev_range = dw_range_from_sec(sections, DW_Section_Abbrev); - //- rjf: count the tags we have U64 tag_count = 0; - for(U64 abbrev_read_off = abbrev_offset - abbrev_range.min;;) + for(U64 abbrev_read_off = abbrev_offset;;) { DW_Abbrev tag; { - U64 bytes_read = dw_based_range_read_abbrev_tag(file_base, abbrev_range, abbrev_read_off, &tag); + U64 bytes_read = dw_read_abbrev_tag(abbrev_data, abbrev_read_off, &tag); abbrev_read_off += bytes_read; if(bytes_read == 0 || tag.id == 0) { @@ -495,7 +532,7 @@ dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 abbrev_offset) for(;;) { DW_Abbrev attrib = {0}; - U64 bytes_read = dw_based_range_read_abbrev_attrib_info(file_base, abbrev_range, abbrev_read_off, &attrib); + U64 bytes_read = dw_read_abbrev_attrib(abbrev_data, abbrev_read_off, &attrib); abbrev_read_off += bytes_read; if(bytes_read == 0 || attrib.id == 0) { @@ -512,11 +549,13 @@ dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 abbrev_offset) MemorySet(table.entries, 0, sizeof(DW_AbbrevTableEntry)*table.count); U64 tag_idx = 0; - for(U64 abbrev_read_off = abbrev_offset - abbrev_range.min;;) + for(U64 abbrev_read_off = abbrev_offset;;) { + U64 tag_abbrev_off = abbrev_read_off; + DW_Abbrev tag; { - U64 bytes_read = dw_based_range_read_abbrev_tag(file_base, abbrev_range, abbrev_read_off, &tag); + U64 bytes_read = dw_read_abbrev_tag(abbrev_data, abbrev_read_off, &tag); abbrev_read_off += bytes_read; if(bytes_read == 0 || tag.id == 0) { @@ -527,14 +566,14 @@ dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 abbrev_offset) // rjf: insert this tag into the table { table.entries[tag_idx].id = tag.id; - table.entries[tag_idx].off = tag.abbrev_range.min; + table.entries[tag_idx].off = tag_abbrev_off; tag_idx += 1; } for(;;) { DW_Abbrev attrib = {0}; - U64 bytes_read = dw_based_range_read_abbrev_attrib_info(file_base, abbrev_range, abbrev_read_off, &attrib); + U64 bytes_read = dw_read_abbrev_attrib(abbrev_data, abbrev_read_off, &attrib); abbrev_read_off += bytes_read; if(bytes_read == 0 || attrib.id == 0) { @@ -551,24 +590,15 @@ internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U64 abbrev_id) { U64 abbrev_offset = max_U64; - if(table.count > 0) - { - S64 min = 0; - S64 max = (S64)table.count - 1; - while(min <= max) - { - S64 mid = (min + max) / 2; - if (abbrev_id > table.entries[mid].id) - { - min = mid + 1; - } - else if (abbrev_id < table.entries[mid].id) - { - max = mid - 1; - } - else - { - abbrev_offset = table.entries[mid].off; + if (table.count > 0) { + for (S64 l = 0, r = (S64)table.count - 1; l <= r; ) { + S64 m = l + (r - l) / 2; + if (abbrev_id > table.entries[m].id) { + l = m + 1; + } else if (abbrev_id < table.entries[m].id) { + r = m - 1; + } else { + abbrev_offset = table.entries[m].off; break; } } @@ -576,1168 +606,2108 @@ dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U64 abbrev_id) return abbrev_offset; } -//////////////////////////////// -//~ rjf: Miscellaneous DWARF Section Parsing - -//- rjf: .debug_ranges (DWARF V4) - -internal Rng1U64List -dw_v4_range_list_from_range_offset(Arena *arena, DW_SectionArray *sections, U64 addr_size, U64 comp_unit_base_addr, U64 range_off) +internal U64 +dw_read_form(String8 data, + U64 off, + DW_Version version, + DW_Format unit_format, + U64 address_size, + DW_FormKind form_kind, + U64 implicit_const, + DW_Form *form_out) { - void *base = dw_base_from_sec(sections, DW_Section_Ranges); - Rng1U64 rng = dw_range_from_sec(sections, DW_Section_Ranges); + U64 bytes_read = 0; + DW_Form form = {0}; - Rng1U64List list = {0}; - - U64 read_off = range_off; - U64 base_addr = comp_unit_base_addr; - - for(;read_off < rng.max;) - { - U64 v0 = 0; - U64 v1 = 0; - read_off += dw_based_range_read(base, rng, read_off, addr_size, &v0); - read_off += dw_based_range_read(base, rng, read_off, addr_size, &v1); - - //- rjf: base address entry - if((addr_size == 4 && v0 == 0xffffffff) || - (addr_size == 8 && v0 == 0xffffffffffffffff)) - { - base_addr = v1; + switch (form_kind) { + case DW_Form_Null: break; + + case DW_Form_Addr: { + bytes_read = str8_deserial_read_block(data, off, address_size, &form.addr); + } break; + case DW_Form_Block2: { + U16 size = 0; + U64 size_size = str8_deserial_read_struct(data, off, &size); + if (size_size) { + U64 block_size = str8_deserial_read_block(data, off + size_size, size, &form.block); + if (block_size) { + bytes_read = size_size + block_size; + } } - //- rjf: end-of-list entry - else if(v0 == 0 && v1 == 0) - { - break; + } break; + case DW_Form_Block4: { + U32 size = 0; + U64 size_size = str8_deserial_read_struct(data, off, &size); + if (size_size) { + U64 block_size = str8_deserial_read_block(data, off + size_size, size, &form.block); + if (block_size) { + bytes_read = size_size + block_size; + } } - //- rjf: range list entry - else - { - U64 min_addr = v0 + base_addr; - U64 max_addr = v1 + base_addr; - rng1u64_list_push(arena, &list, rng_1u64(min_addr, max_addr)); + } break; + case DW_Form_Data2: { + bytes_read = str8_deserial_read_block(data, off, sizeof(U16), &form.data); + } break; + case DW_Form_Data4: { + bytes_read = str8_deserial_read_block(data, off, sizeof(U32), &form.data); + } break; + case DW_Form_Data8: { + bytes_read = str8_deserial_read_block(data, off, sizeof(U64), &form.data); + } break; + case DW_Form_String: { + bytes_read = str8_deserial_read_cstr(data, off, &form.string); + } break; + case DW_Form_Block: { + U64 size = 0; + U64 size_size = str8_deserial_read_uleb128(data, off, &size); + if (size_size) { + U64 block_size = str8_deserial_read_block(data, off + size_size, size, &form.block); + if (block_size) { + bytes_read = size_size + block_size; + } } + } break; + case DW_Form_Block1: { + U8 size = 0; + U64 size_size = str8_deserial_read_struct(data, off, &size); + if (size_size) { + U64 block_size = str8_deserial_read_block(data, off, size, &form.block); + if (block_size == size) { + bytes_read = size_size + block_size; + } + } + } break; + case DW_Form_Data1: { + bytes_read = str8_deserial_read_block(data, off, sizeof(U8), &form.data); + } break; + case DW_Form_Flag: { + bytes_read = str8_deserial_read_struct(data, off, &form.flag); + } break; + case DW_Form_SData: { + bytes_read = str8_deserial_read_sleb128(data, off, &form.sdata); + } break; + case DW_Form_UData: { + bytes_read = str8_deserial_read_uleb128(data, off, &form.udata); + } break; + case DW_Form_RefAddr: { + if (version < DW_Version_3) { + bytes_read = str8_deserial_read(data, off, &form.ref, address_size, address_size); + } else { + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.ref); + } + } break; + case DW_Form_GNU_RefAlt: { + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.ref); + } break; + case DW_Form_Ref1: { + bytes_read = str8_deserial_read(data, off, &form.ref, 1, 1); + } break; + case DW_Form_Ref2: { + bytes_read = str8_deserial_read(data, off, &form.ref, 2, 2); + } break; + case DW_Form_Ref4: { + bytes_read = str8_deserial_read(data, off, &form.ref, 4, 4); + } break; + case DW_Form_Ref8: { + bytes_read = str8_deserial_read(data, off, &form.ref, 8, 8); + } break; + case DW_Form_RefUData: { + bytes_read = str8_deserial_read_uleb128(data, off, &form.ref); + } break; + case DW_Form_SecOffset: + case DW_Form_LineStrp: + case DW_Form_GNU_StrpAlt: + case DW_Form_Strp: { + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.sec_offset); + } break; + case DW_Form_ExprLoc: { + U64 expr_size = 0; + U64 expr_size_size = str8_deserial_read_uleb128(data, off, &expr_size); + if (expr_size_size) { + if (str8_deserial_read_block(data, off + expr_size_size, expr_size, &form.exprloc)) { + bytes_read = expr_size_size + expr_size; + } + } + } break; + case DW_Form_FlagPresent: { + form.flag = 1; + } break; + case DW_Form_RefSig8: { + //U64 ref = 0; + //bytes_read = str8_deserial_read_struct(data, off, &ref); + NotImplemented; + } break; + case DW_Form_Addrx: + case DW_Form_RngListx: + case DW_Form_Strx: { + bytes_read = str8_deserial_read_uleb128(data, off, &form.xval); + } break; + case DW_Form_RefSup4: { + //U32 ref_sup4 = 0; + //bytes_read = str8_deserial_read_struct(data, off, &ref_sup4); + NotImplemented; + } break; + case DW_Form_StrpSup: { + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.strp_sup); + } break; + case DW_Form_Data16: { + bytes_read = str8_deserial_read_block(data, off, 16, &form.data); + } break; + case DW_Form_ImplicitConst: { + // Special case. + // Unlike other forms that have their values stored in the .debug_info section, + // This one defines it's value in the .debug_abbrev section. + form.implicit_const = implicit_const; + } break; + case DW_Form_LocListx: { + bytes_read = str8_deserial_read_uleb128(data, off, &form.xval); + } break; + case DW_Form_RefSup8: { + NotImplemented; + } break; + case DW_Form_Strx1: { + bytes_read = str8_deserial_read(data, off, &form.xval, 1, 1); + } break; + case DW_Form_Strx2: { + bytes_read = str8_deserial_read(data, off, &form.xval, 2, 2); + } break; + case DW_Form_Strx3: { + bytes_read = str8_deserial_read(data, off, &form.xval, 3, 3); + } break; + case DW_Form_Strx4: { + bytes_read = str8_deserial_read(data, off, &form.xval, 4, 4); + } break; + case DW_Form_Addrx1: { + bytes_read = str8_deserial_read(data, off, &form.xval, 1, 1); + } break; + case DW_Form_Addrx2: { + bytes_read = str8_deserial_read(data, off, &form.xval, 2, 2); + } break; + case DW_Form_Addrx3: { + bytes_read = str8_deserial_read(data, off, &form.xval, 3, 3); + } break; + case DW_Form_Addrx4: { + bytes_read = str8_deserial_read(data, off, &form.xval, 4, 4); + } break; + default: InvalidPath; break; + } + + if (form_out) { + *form_out = form; } - return list; + return bytes_read; } -//- rjf: .debug_pubtypes + .debug_pubnames (DWARF V4) - -internal DW_PubStringsTable -dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_SectionArray *sections, DW_SectionKind section_kind) +internal U64 +dw_read_tag(Arena *arena, + String8 tag_data, + U64 tag_off, + U64 tag_base, + DW_AbbrevTable abbrev_table, + String8 abbrev_data, + DW_Version version, + DW_Format unit_format, + U64 address_size, + DW_Tag *tag_out) { - Temp scratch = scratch_begin(&arena, 1); + U64 tag_cursor = tag_off; - DW_PubStringsTable names_table = {0}; - - // TODO(rjf): Arbitrary choice. - names_table.size = 16384; - names_table.buckets = push_array(arena, DW_PubStringsBucket*, names_table.size); - - void *base = dw_base_from_sec(sections, section_kind); - Rng1U64 rng = dw_range_from_sec(sections, section_kind); - DW_Mode mode = sections->v[section_kind].mode; - U64 off_size = dw_offset_size_from_mode(mode); - U64 cursor = 0; - - U64 table_length = 0; - U16 unit_version = 0; - U64 cu_info_off = 0; - U64 cu_info_len = 0; - cursor += dw_based_range_read_length(base, rng, cursor, &table_length); - cursor += dw_based_range_read_struct(base, rng, cursor, &unit_version); - cursor += dw_based_range_read(base, rng, cursor, off_size, &cu_info_off); - cursor += dw_based_range_read_length(base, rng, cursor, &cu_info_len); - - for(;;) - { - U64 info_off = 0; - { - U64 bytes_read = dw_based_range_read(base, rng, cursor, off_size, &info_off); - cursor += bytes_read; - if(bytes_read == 0) - { + // read tag abbrev id + U64 tag_abbrev_id = 0; + U64 tag_abbrev_id_size = str8_deserial_read_uleb128(tag_data, tag_cursor, &tag_abbrev_id); + Assert(tag_abbrev_id_size); + tag_cursor += tag_abbrev_id_size; + + // read tag abbrev + U64 abbrev_cursor = dw_abbrev_offset_from_abbrev_id(abbrev_table, tag_abbrev_id); + DW_Abbrev tag_abbrev = {0}; + U64 tag_abbrev_size = dw_read_abbrev_tag(abbrev_data, abbrev_cursor, &tag_abbrev); + + // read attribs + DW_AttribList attribs = {0}; + if (tag_abbrev_size > 0) { + abbrev_cursor += tag_abbrev_size; + + for (; tag_cursor < tag_data.size && abbrev_cursor < abbrev_data.size; ) { + U64 attrib_tag_cursor = tag_cursor; + U64 attrib_abbrev_off = abbrev_cursor; + + // read attrib abbrev + DW_Abbrev attrib_abbrev = {0}; + abbrev_cursor += dw_read_abbrev_attrib(abbrev_data, abbrev_cursor, &attrib_abbrev); + if (attrib_abbrev.id == 0) { break; } - } - - //- rjf: if we got a nonzero .debug_info offset, we've found a valid entry. - if(info_off != 0) - { - String8 string = dw_based_range_read_string(base, rng, cursor); - cursor += string.size + 1; - U64 hash = dw_hash_from_string(string); - U64 bucket_idx = hash % names_table.size; - - DW_PubStringsBucket *bucket = push_array(arena, DW_PubStringsBucket, 1); - bucket->next = names_table.buckets[bucket_idx]; - bucket->string = string; - bucket->info_off = info_off; - bucket->cu_info_off = cu_info_off; - names_table.buckets[bucket_idx] = bucket; - } - - //- rjf: if we did not read a proper entry in the table, we need to try to - // read the header of the next table. - else - { - U64 next_table_length = 0; - { - U64 bytes_read = dw_based_range_read_length(base, rng, cursor, &next_table_length); - if(bytes_read == 0 || next_table_length == 0) - { + DW_AttribKind attrib_kind = (DW_AttribKind)attrib_abbrev.id; + DW_FormKind form_kind = (DW_FormKind)attrib_abbrev.sub_kind; + + // special case, allows producer to embed form in .debug_info + if (form_kind == DW_Form_Indirect) { + U64 form_kind_size = str8_deserial_read_uleb128(tag_data, tag_cursor, &form_kind); + + if (form_kind_size == 0) { + Assert(!"unable to read indirect form kind"); break; } - cursor += bytes_read; + + tag_cursor += form_kind_size; } - cursor += dw_based_range_read_struct(base, rng, cursor, &unit_version); - cursor += dw_based_range_read(base, rng, cursor, off_size, &cu_info_off); - cursor += dw_based_range_read_length(base, rng, cursor, &cu_info_len); + + // read form value + DW_Form form = {0}; + tag_cursor += dw_read_form(tag_data, tag_cursor, version, unit_format, address_size, form_kind, attrib_abbrev.const_value, &form); + + // fill out node + DW_AttribNode *attrib_n = push_array(arena, DW_AttribNode, 1); + attrib_n->v.info_off = tag_base + attrib_tag_cursor; + attrib_n->v.abbrev_off = attrib_abbrev_off; + attrib_n->v.abbrev_id = attrib_abbrev.id; + attrib_n->v.attrib_kind = attrib_kind; + attrib_n->v.form_kind = form_kind; + attrib_n->v.form = form; + + // push node to list + SLLQueuePush(attribs.first, attribs.last, attrib_n); + ++attribs.count; } } - - scratch_end(scratch); - - return names_table; + + // fill out tag + tag_out->abbrev_id = tag_abbrev_id; + tag_out->has_children = !!(tag_abbrev.flags & DW_AbbrevFlag_HasChildren); + tag_out->kind = (DW_TagKind)tag_abbrev.sub_kind; + tag_out->attribs = attribs; + tag_out->info_off = tag_base + tag_off; + + U64 bytes_read = tag_cursor - tag_off; + return bytes_read; } -//- rjf: .debug_str_offsets (DWARF V5) - internal U64 -dw_v5_offset_from_offs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index) +dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out) { - U64 result = 0; - - DW_Mode mode = sections->v[section].mode; - void *sec_base = dw_base_from_sec(sections, section); - Rng1U64 rng = dw_range_from_sec(sections, section); - U64 cursor = base; - - //- rjf: get the length of each entry - U64 entry_len = mode == DW_Mode_64Bit ? 8 : 4; - - //- rjf: parse the unit's length (not including the length itself) - U64 unit_length = 0; - cursor += dw_based_range_read_length(sec_base, rng, cursor, &unit_length); - - //- rjf: parse version - U16 version = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &version); - Assert(version == 5); // must be 5 as of V5. - - //- rjf: parse padding - U16 padding = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &padding); - Assert(padding == 0); // must be 0 as of V5. - - //- rjf: read - if (unit_length >= sizeof(U16)*2) - { - void *entries = (U8 *)sec_base + cursor; - U64 count = (unit_length - sizeof(U16)*2) / entry_len; - if(0 <= index && index < count) - { - switch(entry_len) - { - default: break; - case 4: result = ((U32 *)entries)[index]; break; - case 8: result = ((U64 *)entries)[index]; break; + String8 tag_data = str8_substr(input->sec[DW_Section_Info].data, cu->info_range); + U64 tag_off = info_off - cu->info_range.min; + return dw_read_tag(arena, tag_data, tag_off, cu->info_range.min, cu->abbrev_table, cu->abbrev_data, cu->version, cu->format, cu->address_size, tag_out); +} + +internal B32 +dw_try_u64_from_const_value(U64 type_byte_size, DW_ATE type_encoding, String8 const_value, U64 *value_out) +{ + B32 is_parsed = 0; + if (const_value.size <= type_byte_size) { + U64 value_size = Min(type_byte_size, const_value.size); + if (value_size <= sizeof(*value_out)) { + MemoryZeroStruct(value_out); + MemoryCopy(value_out, const_value.str, value_size); + if (type_encoding == DW_ATE_Signed || type_encoding == DW_ATE_SignedChar) { + *value_out = extend_sign64(*value_out, value_size); } + is_parsed = 1; + } else { + Assert(!"out value overflow"); } } - - return result; + return is_parsed; } -//- rjf: .debug_addr parsing - internal U64 -dw_v5_addr_from_addrs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index) +dw_u64_from_const_value(String8 const_value) { - U64 result = 0; - - void *sec_base = dw_base_from_sec(sections, section); - Rng1U64 rng = dw_range_from_sec(sections, section); - U64 cursor = base; - - //- rjf: parse the unit's length (not including the length itself) - U64 unit_length = 0; - cursor += dw_based_range_read_length(sec_base, rng, cursor, &unit_length); - - //- rjf: parse version - U16 version = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &version); - Assert(version == 5); // must be 5 as of V5. - - //- rjf: parse address size - U8 address_size = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &address_size); - - //- rjf: parse segment selector size - U8 segment_selector_size = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &segment_selector_size); - - //- rjf: read - U64 entry_size = address_size + segment_selector_size; - U64 count = (unit_length - sizeof(U16)*2) / entry_size; - if(0 <= index && index < count) - { - void *entry = (U8 *)dw_based_range_ptr(sec_base, rng, cursor) + entry_size*index; - Rng1U64 entry_rng = rng_1u64(0, entry_size); - U64 segment = 0; - U64 addr = 0; - dw_based_range_read(entry, entry_rng, 0, sizeof(segment), &segment); - dw_based_range_read(entry, entry_rng, segment_selector_size, sizeof(addr), &addr); - result = addr; - } - + U64 result = 0; + B32 is_converted = dw_try_u64_from_const_value(sizeof(U64), DW_ATE_Unsigned, const_value, &result); + Assert(is_converted); // TODO: error handling return result; } -//- rjf: .debug_rnglists + .debug_loclists parsing - internal U64 -dw_v5_sec_offset_from_rnglist_or_loclist_section_base_index(DW_SectionArray *sections, DW_SectionKind section_kind, U64 base, U64 index) +dw_interp_sec_offset(DW_FormKind form_kind, DW_Form form) { - // - // NOTE(rjf): This is only appropriate to call when DW_Form_RngListx is - // used to access a range list, *OR* when DW_Form_LocListx is used to - // access a location list. Otherwise, DW_Form_SecOffset is required. - // - // See the DWARF V5 spec (February 13, 2017), page 242. (rnglists) - // See the DWARF V5 spec (February 13, 2017), page 215. (loclists) - // - - U64 result = 0; - - DW_Mode mode = sections->v[section_kind].mode; - void *sec_base = dw_base_from_sec(sections, section_kind); - Rng1U64 rng = dw_range_from_sec(sections, section_kind); - U64 cursor = base; - - //- rjf: get the length of each entry - U64 entry_len = mode == DW_Mode_64Bit ? 8 : 4; - - //- rjf: parse the unit's length (not including the length itself) - U64 unit_length = 0; - cursor += dw_based_range_read_length(sec_base, rng, cursor, &unit_length); - - //- rjf: parse version - U16 version = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &version); - Assert(version == 5); // must be 5 as of V5. - - //- rjf: parse address size - U8 address_size = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &address_size); - - //- rjf: parse segment selector size - U8 segment_selector_size = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &segment_selector_size); - - //- rjf: parse offset entry count - U32 offset_entry_count = 0; - cursor += dw_based_range_read_struct(sec_base, rng, cursor, &offset_entry_count); - - //- rjf: read from offsets array - U64 table_off = cursor; - void *offsets_arr = dw_based_range_ptr(sec_base, rng, cursor); - if(0 <= index && index < (U64)offset_entry_count) - { - U64 rnglist_offset = 0; - switch(entry_len) - { - default: break; - case 4: rnglist_offset = ((U32 *)offsets_arr)[index]; break; - case 8: rnglist_offset = ((U64 *)offsets_arr)[index]; break; - } - result = rnglist_offset+table_off; + U64 sec_offset = 0; + if (form_kind == DW_Form_SecOffset) { + sec_offset = form.sec_offset; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); } - - return result; -} - -internal Rng1U64List -dw_v5_range_list_from_rnglist_offset(Arena *arena, DW_SectionArray *sections, DW_SectionKind section, U64 addr_size, U64 addr_section_base, U64 offset) -{ - Rng1U64List list = {0}; - - void *base = dw_base_from_sec(sections, section); - Rng1U64 rng = dw_range_from_sec(sections, section); - U64 cursor = offset; - - U64 base_addr = 0; - - for(B32 done = 0; !done;) - { - U8 kind8 = 0; - cursor += dw_based_range_read_struct(base, rng, cursor, &kind8); - DW_RngListEntryKind kind = (DW_RngListEntryKind)kind8; - - switch(kind) - { - //- rjf: can be used in split and non-split units: - default: - case DW_RngListEntryKind_EndOfList: - { - done = 1; - } break; - - case DW_RngListEntryKind_BaseAddressX: - { - U64 base_addr_idx = 0; - cursor += dw_based_range_read_uleb128(base, rng, cursor, &base_addr_idx); - base_addr = dw_v5_addr_from_addrs_section_base_index(sections, DW_Section_Addr, addr_section_base, base_addr_idx); - } break; - - case DW_RngListEntryKind_StartxEndx: - { - U64 start_addr_idx = 0; - U64 end_addr_idx = 0; - cursor += dw_based_range_read_uleb128(base, rng, cursor, &start_addr_idx); - cursor += dw_based_range_read_uleb128(base, rng, cursor, &end_addr_idx); - U64 start_addr = dw_v5_addr_from_addrs_section_base_index(sections, DW_Section_Addr, addr_section_base, start_addr_idx); - U64 end_addr = dw_v5_addr_from_addrs_section_base_index(sections, DW_Section_Addr, addr_section_base, end_addr_idx); - rng1u64_list_push(arena, &list, rng_1u64(start_addr, end_addr)); - } break; - - case DW_RngListEntryKind_StartxLength: - { - U64 start_addr_idx = 0; - U64 length = 0; - cursor += dw_based_range_read_uleb128(base, rng, cursor, &start_addr_idx); - cursor += dw_based_range_read_uleb128(base, rng, cursor, &length); - U64 start_addr = dw_v5_addr_from_addrs_section_base_index(sections, DW_Section_Addr, addr_section_base, start_addr_idx); - U64 end_addr = start_addr + length; - rng1u64_list_push(arena, &list, rng_1u64(start_addr, end_addr)); - } break; - - case DW_RngListEntryKind_OffsetPair: - { - U64 start_offset = 0; - U64 end_offset = 0; - cursor += dw_based_range_read_uleb128(base, rng, cursor, &start_offset); - cursor += dw_based_range_read_uleb128(base, rng, cursor, &end_offset); - rng1u64_list_push(arena, &list, rng_1u64(start_offset + base_addr, end_offset + base_addr)); - } break; - - //- rjf: non-split units only: - - case DW_RngListEntryKind_BaseAddress: - { - U64 new_base_addr = 0; - cursor += dw_based_range_read(base, rng, cursor, addr_size, &new_base_addr); - base_addr = new_base_addr; - } break; - - case DW_RngListEntryKind_StartEnd: - { - U64 start = 0; - U64 end = 0; - cursor += dw_based_range_read(base, rng, cursor, addr_size, &start); - cursor += dw_based_range_read(base, rng, cursor, addr_size, &end); - rng1u64_list_push(arena, &list, rng_1u64(start, end)); - } break; - - case DW_RngListEntryKind_StartLength: - { - U64 start = 0; - U64 length = 0; - cursor += dw_based_range_read(base, rng, cursor, addr_size, &start); - cursor += dw_based_range_read_uleb128(base, rng, cursor, &length); - rng1u64_list_push(arena, &list, rng_1u64(start, start+length)); - } break; - } - } - - return list; -} - -//////////////////////////////// -//~ rjf: Attrib Value Parsing - -internal DW_AttribValueResolveParams -dw_attrib_value_resolve_params_from_comp_root(DW_CompRoot *root) -{ - DW_AttribValueResolveParams params = {0}; - params.version = root->version; - params.language = root->language; - params.addr_size = root->address_size; - params.containing_unit_info_off = root->info_off; - params.debug_addrs_base = root->addrs_base; - params.debug_rnglists_base = root->rnglist_base; - params.debug_str_offs_base = root->stroffs_base; - params.debug_loclists_base = root->loclist_base; - return params; -} - -internal DW_AttribValue -dw_attrib_value_from_form_value(DW_SectionArray *sections, - DW_AttribValueResolveParams resolve_params, - DW_FormKind form_kind, - DW_AttribClass value_class, - DW_AttribValue form_value) -{ - DW_AttribValue value = {0}; - - //~ rjf: DWARF V5 value parsing - - //- rjf: (DWARF V5 ONLY) the form value is storing an address index (ADDRess indeX), which we - // must resolve to an actual address using the containing comp unit's contribution to the - // .debug_addr section. - if(resolve_params.version >= DW_Version_5 && - value_class == DW_AttribClass_Address && - (form_kind == DW_Form_Addrx || form_kind == DW_Form_Addrx1 || - form_kind == DW_Form_Addrx2 || form_kind == DW_Form_Addrx3 || - form_kind == DW_Form_Addrx4)) - { - U64 addr_index = form_value.v[0]; - U64 addr = dw_v5_addr_from_addrs_section_base_index(sections, DW_Section_Addr, resolve_params.debug_addrs_base, addr_index); - value.v[0] = addr; - } - //- rjf: (DWARF V5 ONLY) lookup into the .debug_loclists section via an index - else if(resolve_params.version >= DW_Version_5 && - value_class == DW_AttribClass_LocList && - form_kind == DW_Form_LocListx) - { - U64 loclist_index = form_value.v[0]; - U64 loclist_offset = dw_v5_sec_offset_from_rnglist_or_loclist_section_base_index(sections, DW_Section_LocLists, resolve_params.debug_loclists_base, loclist_index); - value.section = DW_Section_LocLists; - value.v[0] = loclist_offset; - } - //- rjf: (DWARF V5 ONLY) lookup into the .debug_loclists section via an offset - else if(resolve_params.version >= DW_Version_5 && - (value_class == DW_AttribClass_LocList || value_class == DW_AttribClass_LocListPtr) && - form_kind == DW_Form_SecOffset) - { - U64 loclist_offset = form_value.v[0]; - value.section = DW_Section_LocLists; - value.v[0] = loclist_offset; - } - //- rjf: (DWARF V5 ONLY) lookup into the .debug_rnglists section via an index - else if(resolve_params.version >= DW_Version_5 && - (value_class == DW_AttribClass_RngListPtr || value_class == DW_AttribClass_RngList) && - form_kind == DW_Form_RngListx) - { - U64 rnglist_index = form_value.v[0]; - U64 rnglist_offset = dw_v5_sec_offset_from_rnglist_or_loclist_section_base_index(sections, DW_Section_RngLists, resolve_params.debug_rnglists_base, rnglist_index); - value.section = DW_Section_RngLists; - value.v[0] = rnglist_offset; - } - //- rjf: (DWARF V5 ONLY) lookup into the .debug_rnglists section via an offset - else if(resolve_params.version >= DW_Version_5 && - (value_class == DW_AttribClass_RngListPtr || value_class == DW_AttribClass_RngList) && - form_kind != DW_Form_RngListx) - { - U64 rnglist_offset = form_value.v[0]; - value.section = DW_Section_RngLists; - value.v[0] = rnglist_offset; - } - //- rjf: (DWARF V5 ONLY) .debug_str_offsets table index, that we need to resolve - // using the containing compilation unit's contribution to the section - else if(resolve_params.version >= DW_Version_5 && - value_class == DW_AttribClass_String && - (form_kind == DW_Form_Strx || - form_kind == DW_Form_Strx1 || - form_kind == DW_Form_Strx2 || - form_kind == DW_Form_Strx3 || - form_kind == DW_Form_Strx4)) - { - DW_SectionKind section = DW_Section_Str; - U64 str_index = form_value.v[0]; - U64 str_offset = dw_v5_offset_from_offs_section_base_index(sections, DW_Section_StrOffsets, resolve_params.debug_str_offs_base, str_index); - void *base = dw_base_from_sec(sections, section); - Rng1U64 range = dw_range_from_sec(sections, section); - String8 string = dw_based_range_read_string(base, range, str_offset); - value.section = section; - value.v[0] = str_offset; - value.v[1] = value.v[0] + string.size; - } - //- rjf: (DWARF V5 ONLY) reference that we should resolve through ref_addr_desc - else if(resolve_params.version >= DW_Version_5 && - value_class == DW_AttribClass_Reference && - form_kind == DW_Form_RefAddr) - { - // TODO(nick): DWARF 5 @dwarf_v5 - } - //- TODO(rjf): (DWARF V5 ONLY) reference resolution using the .debug_names section - else if(resolve_params.version >= DW_Version_5 && - form_kind == DW_Form_RefSig8) - { - // TODO(nick): DWARF 5: We need to handle .debug_names section in order to resolve this value. @dwarf_v5 - value.v[0] = max_U64; - } - - //~ rjf: All other value parsing (DWARF V4 and below) - - //- rjf: reference to an offset relative to the compilation unit's info base - else if (value_class == DW_AttribClass_Reference && - (form_kind == DW_Form_Ref1 || - form_kind == DW_Form_Ref2 || - form_kind == DW_Form_Ref4 || - form_kind == DW_Form_Ref8 || - form_kind == DW_Form_RefUData)) - { - value.v[0] = resolve_params.containing_unit_info_off + form_value.v[0]; - } - - //- rjf: info-section string -- this is a string that is just pasted straight - // into the .debug_info section - else if(value_class == DW_AttribClass_String && form_kind == DW_Form_String) - { - value = form_value; - value.section = DW_Section_Info; - } - - //- rjf: string-section string -- this is a string that's inside the .debug_str - // section, and we've been provided an offset to it - else if(value_class == DW_AttribClass_String && - (form_kind == DW_Form_Strp || - form_kind == DW_Form_StrpSup)) - { - - DW_SectionKind section = DW_Section_Str; - void *base = dw_base_from_sec(sections, section); - Rng1U64 range = dw_range_from_sec(sections, section); - String8 string = dw_based_range_read_string(base, range, form_value.v[0]); - value.section = section; - value.v[0] = form_value.v[0]; - value.v[1] = value.v[0] + string.size; - } - //- rjf: line-string - else if(value_class == DW_AttribClass_String && form_kind == DW_Form_LineStrp) - { - DW_SectionKind section = DW_Section_LineStr; - void *base = dw_base_from_sec(sections, section); - Rng1U64 range = dw_range_from_sec(sections, section); - String8 string = dw_based_range_read_string(base, range, form_value.v[0]); - value.section = section; - value.v[0] = form_value.v[0]; - value.v[1] = value.v[0] + string.size; - } - //- rjf: .debug_ranges - else if(resolve_params.version < DW_Version_5 && - (value_class == DW_AttribClass_RngListPtr || value_class == DW_AttribClass_RngList) && - (form_kind == DW_Form_SecOffset)) - { - U64 ranges_offset = form_value.v[0]; - value.section = DW_Section_Ranges; - value.v[0] = ranges_offset; - } - //- rjf: .debug_loc - else if(resolve_params.version < DW_Version_5 && - (value_class == DW_AttribClass_LocListPtr || value_class == DW_AttribClass_LocList) && - (form_kind == DW_Form_SecOffset)) - { - U64 offset = form_value.v[0]; - value.section = DW_Section_Loc; - value.v[0] = offset; - } - //- rjf: invalid attribute class - else if(value_class == 0) - { - Assert(!"attribute class was not resolved"); - } - //- rjf: in all other cases, we can accept the form_value as the correct - // representation for the parsed value, so we can just copy it over. - else - { - value = form_value; - } - - return value; + return sec_offset; } internal String8 -dw_string_from_attrib_value(DW_SectionArray *sections, DW_AttribValue value) +dw_interp_exprloc(DW_FormKind form_kind, DW_Form form) { - DW_SectionKind section_kind = value.section; - void *base = dw_base_from_sec(sections, section_kind); - Rng1U64 range = dw_range_from_sec(sections, section_kind); + String8 expr = {0}; + if (form_kind == DW_Form_ExprLoc) { + expr = form.exprloc; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + return expr; +} +internal U128 +dw_interp_const_u128(DW_FormKind form_kind, DW_Form form) +{ + AssertAlways(form.data.size <= sizeof(U128)); + U128 result = {0}; + MemoryCopy(&result.u64[0], form.data.str, form.data.size); + return result; +} + +internal U64 +dw_interp_const64(U64 type_byte_size, DW_ATE type_encoding, DW_FormKind form_kind, DW_Form form) +{ + U64 result = max_U64; + if (form_kind == DW_Form_Data1 || form_kind == DW_Form_Data2 || form_kind == DW_Form_Data4 || form_kind == DW_Form_Data16) { + if (form.data.size <= sizeof(result)) { + if (!dw_try_u64_from_const_value(type_byte_size, type_encoding, form.data, &result)) { + Assert(!"unable to decode data"); + } + } else { + Assert(!"unable to cast U128 to U64"); + } + } else if (form_kind == DW_Form_UData) { + result = form.udata; + } else if (form_kind == DW_Form_SData) { + result = form.sdata; + } else if (form_kind == DW_Form_ImplicitConst) { + result = form.implicit_const; + } else if (form_kind == DW_Form_Null) { + // skip + } else { + AssertAlways(!"unexpected form"); + } + return result; +} + +internal U64 +dw_interp_const_u64(DW_FormKind form_kind, DW_Form form) +{ + return dw_interp_const64(DW_ATE_Unsigned, sizeof(U64), form_kind, form); +} + +internal U32 +dw_interp_const_u32(DW_FormKind form_kind, DW_Form form) +{ + U64 const64 = dw_interp_const_u64(form_kind, form); + U32 const32 = safe_cast_u32(const64); + return const32; +} + +internal S64 +dw_interp_const_s64(DW_FormKind form_kind, DW_Form form) +{ + U64 const_u64 = dw_interp_const_u64(form_kind, form); + S64 const_s64 = (S64)const_u64; + return const_s64; +} + +internal S32 +dw_interp_const_s32(DW_FormKind form_kind, DW_Form form) +{ + U32 const_u32 = dw_interp_const_u32(form_kind, form); + S32 const_s32 = (S32)const_u32; + return const_s32; +} + +internal U64 +dw_interp_address(U64 address_size, U64 base_addr, DW_ListUnit *addr_lu, DW_FormKind form_kind, DW_Form form) +{ + U64 address = 0; + if (form_kind == DW_Form_Addr) { + if (!dw_try_u64_from_const_value(address_size, DW_ATE_Address, form.addr, &address)) { + AssertAlways(!"unable to decode address"); + } + } else if (form_kind == DW_Form_Addrx || form_kind == DW_Form_Addrx1 || form_kind == DW_Form_Addrx2 || + form_kind == DW_Form_Addrx3 || form_kind == DW_Form_Addrx4) { + address = dw_addr_from_list_unit(addr_lu, form.xval); + } else if (form_kind == DW_Form_SecOffset) { + if (addr_lu->segment_selector_size > 0) { + AssertAlways(!"TODO: support for segmented address space"); + } + if (form.sec_offset + addr_lu->segment_selector_size + addr_lu->address_size <= addr_lu->entries.size) { + MemoryCopy(&address, addr_lu->entries.str + form.sec_offset, addr_lu->address_size); + } else { + Assert(!"out of bounds .debug_addr offset"); + } + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + return address; +} + +internal String8 +dw_interp_block(DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +{ + NotImplemented; + return str8_zero(); +} + +internal String8 +dw_interp_string(DW_Input *input, + DW_Format unit_format, + DW_ListUnit *str_offsets, + DW_FormKind form_kind, + DW_Form form) +{ String8 string = {0}; - string.str = (U8 *)dw_based_range_ptr(base, range, value.v[0]); - string.size = value.v[1] - value.v[0]; + if (form_kind == DW_Form_String) { + string = form.string; + } else if (form_kind == DW_Form_Strp) { + U64 bytes_read = str8_deserial_read_cstr(input->sec[DW_Section_Str].data, form.sec_offset, &string); + Assert(bytes_read > 0); + } else if (form_kind == DW_Form_LineStrp) { + U64 bytes_read = str8_deserial_read_cstr(input->sec[DW_Section_LineStr].data, form.sec_offset, &string); + Assert(bytes_read > 0); + } else if (form_kind == DW_Form_StrpSup) { + U64 bytes_read = str8_deserial_read_cstr(input->sec[DW_Section_Str].data, form.strp_sup, &string); + Assert(bytes_read > 0); + } else if (form_kind == DW_Form_Strx || form_kind == DW_Form_Strx1 || + form_kind == DW_Form_Strx2 || form_kind == DW_Form_Strx3 || + form_kind == DW_Form_Strx4) { + U64 sec_offset = dw_offset_from_list_unit(str_offsets, form.xval); + if (sec_offset < input->sec[DW_Section_Str].data.size) { + U64 bytes_read = str8_deserial_read_cstr(input->sec[DW_Section_Str].data, sec_offset, &string); + Assert(bytes_read > 0); + } else { + AssertAlways(!"unable to translate index to offset"); + } + } else if (form_kind == DW_Form_GNU_StrpAlt) { + NotImplemented; + } else if (form_kind == DW_Form_GNU_StrIndex) { + NotImplemented; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } return string; } -internal Rng1U64List -dw_range_list_from_high_low_pc_and_ranges_attrib_value(Arena *arena, DW_SectionArray *sections, U64 address_size, U64 comp_unit_base_addr, U64 addr_section_base, U64 low_pc, U64 high_pc, DW_AttribValue ranges_value) +internal String8 +dw_interp_line_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { - Rng1U64List list = {0}; - switch(ranges_value.section) - { - //- rjf: (DWARF V5 ONLY) .debug_rnglists offset - case DW_Section_RngLists: - { - list = dw_v5_range_list_from_rnglist_offset(arena, sections, ranges_value.section, address_size, addr_section_base, ranges_value.v[0]); - } break; - - //- rjf: (DWARF V4 and earlier) .debug_ranges parsing - case DW_Section_Ranges: - { - list = dw_v4_range_list_from_range_offset(arena, sections, address_size, comp_unit_base_addr, ranges_value.v[0]); - } break; - - //- rjf: fall back to trying to use low/high PCs - default: - { - rng1u64_list_push(arena, &list, rng_1u64(low_pc, high_pc)); - } break; - } - return list; -} - -//////////////////////////////// -//~ rjf: Tag Parsing - -internal DW_AttribListParseResult -dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, - DW_SectionArray *sections, - DW_Version ver, - DW_Ext ext, - DW_Language lang, - U64 address_size, - U64 info_off, - U64 abbrev_off, - B32 relaxed) -{ - //- rjf: set up prereqs - DW_Mode info_mode = sections->v[DW_Section_Info].mode; - DW_Mode abbrev_mode = sections->v[DW_Section_Abbrev].mode; - void *info_base = dw_base_from_sec(sections, DW_Section_Info); - void *abbrev_base = dw_base_from_sec(sections, DW_Section_Abbrev); - Rng1U64 info_range = dw_range_from_sec(sections, DW_Section_Info); - Rng1U64 abbrev_range = dw_range_from_sec(sections, DW_Section_Abbrev); - - //- rjf: set up read offsets - U64 info_read_off = info_off; - U64 abbrev_read_off = abbrev_off; - - //- rjf: parse all attributes - DW_AttribListParseResult result = {0}; - for(B32 good_abbrev = 1; good_abbrev;) - { - U64 attrib_info_offset = info_read_off; - - //- rjf: parse abbrev attrib info - DW_Abbrev abbrev = {0}; - { - U64 bytes_read = dw_based_range_read_abbrev_attrib_info(abbrev_base, abbrev_range, abbrev_read_off, &abbrev); - abbrev_read_off += bytes_read; - good_abbrev = abbrev.id != 0; - } - - //- rjf: extract attrib info from abbrev - DW_AttribKind attrib_kind = (DW_AttribKind)abbrev.id; - DW_FormKind form_kind = (DW_FormKind)abbrev.sub_kind; - DW_AttribClass attrib_class = dw_pick_attrib_value_class(ver, ext, lang, relaxed, attrib_kind, form_kind); - - //- rjf: parse the form value from the file - DW_AttribValue form_value = {0}; - if(good_abbrev) - { - // Special case form that allows user to encode attribute form in .debug_info - if(form_kind == DW_Form_Indirect) - { - U64 override_form_kind = 0; - info_read_off += dw_based_range_read_uleb128(info_base, info_range, info_read_off, &override_form_kind); - form_kind = (DW_FormKind)override_form_kind; - } - U64 bytes_read = dw_based_range_read_attrib_form_value(info_base, info_range, info_read_off, info_mode, address_size, - form_kind, abbrev.const_value, &form_value); - info_read_off += bytes_read; - } - - //- rjf: push this parsed attrib to the list - if(good_abbrev) - { - DW_AttribNode *node = push_array(arena, DW_AttribNode, 1); - node->attrib.info_off = attrib_info_offset; - node->attrib.abbrev_id = abbrev.id; - node->attrib.attrib_kind = attrib_kind; - node->attrib.form_kind = form_kind; - node->attrib.value_class = attrib_class; - node->attrib.form_value = form_value; - result.attribs.count += 1; - SLLQueuePush(result.attribs.first, result.attribs.last, node); - } - } - - result.max_info_off = info_read_off; - result.max_abbrev_off = abbrev_read_off; - return result; -} - -internal DW_Tag * -dw_tag_from_info_offset(Arena *arena, - DW_SectionArray *sections, - DW_AbbrevTable abbrev_table, - DW_Version ver, - DW_Ext ext, - DW_Language lang, - U64 address_size, - U64 info_offset, - B32 relaxed) -{ - void *info_base = dw_base_from_sec(sections, DW_Section_Info); - Rng1U64 info_range = dw_range_from_sec(sections, DW_Section_Info); - void *abbrev_base = dw_base_from_sec(sections, DW_Section_Abbrev); - Rng1U64 abbrev_range = dw_range_from_sec(sections, DW_Section_Abbrev); - - DW_Tag *tag = push_array(arena, DW_Tag, 1); - - //- rjf: calculate .debug_info read cursor, relative to info range minimum - U64 info_read_off = info_offset - info_range.min; - - //- rjf: read abbrev ID - U64 abbrev_id = 0; - info_read_off += dw_based_range_read_uleb128(info_base, info_range, info_read_off, &abbrev_id); - B32 good_abbrev_id = abbrev_id != 0; - - //- rjf: figure out abbrev offset for this ID - U64 abbrev_offset = 0; - if(good_abbrev_id) - { - abbrev_offset = dw_abbrev_offset_from_abbrev_id(abbrev_table, abbrev_id); - } - - //- rjf: calculate .debug_abbrev read cursor, relative to abbrev range minimum - U64 abbrev_read_off = abbrev_offset - abbrev_range.min; - - //- rjf: parse abbrev tag info - DW_Abbrev abbrev_tag_info = {0}; - B32 good_tag_abbrev = 0; - if(good_abbrev_id) - { - abbrev_read_off += dw_based_range_read_abbrev_tag(abbrev_base, abbrev_range, abbrev_read_off, &abbrev_tag_info); - good_tag_abbrev = 1;//abbrev_tag_info.id != 0; - } - - //- rjf: parse all attributes for this tag - U64 attribs_info_off = 0; - U64 attribs_abbrev_off = 0; - DW_AttribList attribs = {0}; - if(good_tag_abbrev) - { - DW_AttribListParseResult attribs_parse = dw_parse_attrib_list_from_info_abbrev_offsets(arena, sections, ver, ext, lang, address_size, info_read_off, abbrev_read_off, relaxed); - attribs_info_off = info_read_off; - attribs_abbrev_off = abbrev_read_off; - info_read_off = attribs_parse.max_info_off; - abbrev_read_off = attribs_parse.max_abbrev_off; - attribs = attribs_parse.attribs; - } - - //- rjf: fill tag - { - tag->abbrev_id = abbrev_id; - tag->info_range = rng_1u64(info_offset, info_range.min + info_read_off); - tag->abbrev_range = rng_1u64(abbrev_offset, abbrev_range.min + abbrev_read_off); - tag->has_children = !!(abbrev_tag_info.flags & DW_AbbrevFlag_HasChildren); - tag->kind = (DW_TagKind)abbrev_tag_info.sub_kind; - tag->attribs_info_off = attribs_info_off; - tag->attribs_abbrev_off = attribs_abbrev_off; - tag->attribs = attribs; - } - - return tag; -} - -//////////////////////////////// - -internal U64 -dw_v5_header_offset_from_table_offset(DW_SectionArray *sections, DW_SectionKind section, U64 table_off) -{ - // NOTE(rjf): From the DWARF V5 spec (February 13, 2017), page 401: - // - // " - // Each skeleton compilation unit also has a DW_AT_addr_base attribute, - // which provides the relocated offset to that compilation unit’s - // contribution in the executable’s .debug_addr section. Unlike the - // DW_AT_stmt_list attribute, the offset refers to the first address table - // slot, not to the section header. In this example, we see that the first - // address (slot 0) from demo1.o begins at offset 48. Because the - // .debug_addr section contains an 8-byte header, the object file’s - // contribution to the section actually begins at offset 40 (for a 64-bit - // DWARF object, the header would be 16 bytes long, and the value for the - // DW_AT_addr_base attribute would then be 56). All attributes in demo1.dwo - // that use DW_FORM_addrx, DW_FORM_addrx1, DW_FORM_addrx2, DW_FORM_addrx3 - // or DW_FORM_addrx4 would then refer to address table slots relative to - // that offset. Likewise, the .debug_addr contribution from demo2.dwo begins - // at offset 72, and its first address slot is at offset 80. Because these - // contributions have been processed by the linker, they contain relocated - // values for the addresses in the program that are referred to by the - // debug information. - // " - // - // This seems to at least partially explain why the addr_base is showing up - // 8 bytes later than we are expecting it to. We can't actually just store - // the base that we read from the DW_Attrib_AddrBase attrib, because - // it's showing up *after* the header, so we need to bump it back. - - // NOTE(rjf): From the DWARF V5 spec (February 13, 2017), page 66: - // - // " - // A DW_AT_rnglists_base attribute, whose value is of class rnglistsptr. This - // attribute points to the beginning of the offsets table (immediately - // following the header) of the compilation unit's contribution to the - // .debug_rnglists section. References to range lists (using DW_FORM_rnglistx) - // within the compilation unit are interpreted relative to this base. - // " - // - // Similarly, we need to figure out where to go to parse the header. - - U64 max_header_size = 0; - U64 min_header_size = 0; - switch(section) - { - default: - case DW_Section_Addr: - { - max_header_size = 16; - min_header_size = 8; - } break; - case DW_Section_StrOffsets: - { - max_header_size = 16; - min_header_size = 8; - } break; - case DW_Section_RngLists: - { - max_header_size = 20; - min_header_size = 12; - } break; - case DW_Section_LocLists: - { - // TODO(rjf) - NotImplemented; - } break; - } - - U64 past_header = table_off; - void *addr_base = dw_base_from_sec(sections, section); - Rng1U64 addr_rng = dw_range_from_sec(sections, section); - - //- rjf: figure out which sized header we have - U64 header_size = 0; - { - // rjf: try max header, and if it works, the header is the max size, otherwise we will - // need to rely on the min header size - U32 first32 = 0; - dw_based_range_read_struct(addr_base, addr_rng, past_header-max_header_size, &first32); - if(first32 == max_U32) - { - header_size = max_header_size; - } - else - { - header_size = min_header_size; - } - } - - return table_off - header_size; -} - -internal Rng1U64List -dw_comp_unit_ranges_from_info(Arena *arena, DW_Section info) -{ - Rng1U64List result = {0}; - void *base = info.data.str; - Rng1U64 range = rng_1u64(0, info.data.size); - for(U64 cursor = 0; cursor < info.data.size; ) - { - // read unit length - U64 unit_length = 0; - U64 bytes_read = dw_based_range_read_length(base, range, cursor, &unit_length); - - // was read ok? - if(bytes_read == 0) - { - break; - } - - // push unit range - rng1u64_list_push(arena, &result, rng_1u64(cursor, cursor+unit_length+bytes_read)); - - // advance - cursor += unit_length+bytes_read; + String8 result = {0}; + if (form_kind == DW_Form_SecOffset) { + result = str8_skip(input->sec[DW_Section_Line].data, form.sec_offset); + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); } return result; } -internal DW_Ext -dw_ext_from_params(String8 producer, Arch arch, ImageType image_type) +internal DW_LineFile * +dw_interp_file(DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form) { - DW_Ext ext = DW_Ext_Null; - switch (image_type) { - case Image_Null: break; - case Image_CoffPe: { - if (str8_match_lit("clang", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_GNU | DW_Ext_LLVM; - } else if (str8_match_lit("GNU", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_GNU; - } - } break; - case Image_Elf32: - case Image_Elf64: { - if (str8_match_lit("clang", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_GNU | DW_Ext_LLVM; - } else if (str8_match_lit("GNU", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_GNU; - } - } break; - case Image_Macho: { - if (str8_match_lit("clang", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_LLVM | DW_Ext_APPLE; - } else if (str8_match_lit("GNU", producer, StringMatchFlag_RightSideSloppy|StringMatchFlag_CaseInsensitive)) { - ext = DW_Ext_GNU | DW_Ext_APPLE; - } - } break; + DW_LineFile *result = 0; + U64 file_idx = dw_interp_const_u64(form_kind, form); + if (file_idx < line_vm->file_table.count) { + result = &line_vm->file_table.v[file_idx]; + } else { + Assert(!"out of bounds file index"); } - return ext; + return result; } -internal DW_CompRoot -dw_comp_root_from_range(Arena *arena, DW_SectionArray *sections, Rng1U64 range, B32 relaxed) +internal DW_Reference +dw_interp_ref(DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) { - Temp scratch = scratch_begin(&arena, 1); - - void *info_base = dw_base_from_sec(sections, DW_Section_Info); - B32 is_info_dwo = sections->v[DW_Section_Info].is_dwo; - - //- rjf: up-front known parsing offsets (yep, that's right, it's only 1!) - U64 size_off = 0; - - //- rjf: parse size of this compilation unit's data - U64 size = 0; - U64 version_off = size_off; - { - U64 bytes_read = dw_based_range_read_length(info_base, range, size_off, &size); - version_off += bytes_read; + DW_Reference ref = {0}; + if (form_kind == DW_Form_Ref1 || form_kind == DW_Form_Ref2 || + form_kind == DW_Form_Ref4 || form_kind == DW_Form_Ref8 || + form_kind == DW_Form_RefUData) { + ref.cu = cu; + ref.info_off = form.ref; + } else if (form_kind == DW_Form_RefAddr) { + NotImplemented; + } else if (form_kind == DW_Form_RefSig8) { + NotImplemented; + } else if (form_kind == DW_Form_RefSup4 || form_kind == DW_Form_RefSup8) { + NotImplemented; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); } - - //- rjf: parse version - B32 got_version = 0; - DW_Version version = 0; - U64 unit_off = version_off; - if(dw_based_range_read_struct(info_base, range, version_off, &version)) - { - unit_off += sizeof(version); - got_version = 1; - } - - //- rjf: parse unit kind, abbrev_base, address size - B32 got_unit_kind = 0; - U64 next_off = unit_off; - DW_CompUnitKind unit_kind = DW_CompUnitKind_Reserved; - U64 abbrev_base = max_U64; - U64 address_size = 0; - U64 spec_dwo_id = 0; - if(got_version) - { - switch(version) - { - default: break; - case DW_Version_2: { - abbrev_base = 0; - next_off += dw_based_range_read(info_base, range, next_off, 4, &abbrev_base); - next_off += dw_based_range_read(info_base, range, next_off, 1, &address_size); - got_unit_kind = 1; - } break; - case DW_Version_3: - case DW_Version_4: - { - next_off += dw_based_range_read_length(info_base, range, next_off, &abbrev_base); - next_off += dw_based_range_read(info_base, range, next_off, 1, &address_size); - got_unit_kind = 1; - } break; - case DW_Version_5: - { - next_off += dw_based_range_read_struct(info_base, range, next_off, &unit_kind); - next_off += dw_based_range_read(info_base, range, next_off, 1, &address_size); - next_off += dw_based_range_read_length(info_base, range, next_off, &abbrev_base); - got_unit_kind = 1; - - //- rjf: parse DWO ID if appropriate - if(unit_kind == DW_CompUnitKind_Skeleton || is_info_dwo) - { - next_off += dw_based_range_read(info_base, range, next_off, 8, &spec_dwo_id); - } - } break; - } - } - - //- rjf: build abbrev table - DW_AbbrevTable abbrev_table = {0}; - if(got_unit_kind) - { - abbrev_table = dw_make_abbrev_table(arena, sections, abbrev_base); - } - - //- rjf: parse compilation unit's tag - B32 got_comp_unit_tag = 0; - DW_Tag *comp_unit_tag = 0; - if(got_unit_kind) - { - U64 comp_root_tag_off = range.min + next_off; - comp_unit_tag = dw_tag_from_info_offset(scratch.arena, sections, abbrev_table, version, DW_Ext_Null, DW_Language_Null, address_size, comp_root_tag_off, relaxed); - got_comp_unit_tag = 1; - } - - //- rjf: get all of the attribute values we need to start resolving attribute values - DW_AttribValueResolveParams resolve_params = { .version = version }; - if(got_comp_unit_tag) - { - for(DW_AttribNode *attrib_n = comp_unit_tag->attribs.first; attrib_n; attrib_n = attrib_n->next) - { - DW_Attrib *attrib = &attrib_n->attrib; - - // NOTE(rjf): We'll have to rely on just the form value at this point, - // since we can't use the unit yet (since we're currently in the process - // of building it). This should always be enough, otherwise there would - // be a cyclic dependency in the requirements of each part of the - // compilation unit's parse. DWARF is pretty crazy, but not *that* crazy, - // so this should be good. - switch(attrib->attrib_kind) - { - default: break; - case DW_Attrib_AddrBase: resolve_params.debug_addrs_base = attrib->form_value.v[0]; break; - case DW_Attrib_StrOffsetsBase: resolve_params.debug_str_offs_base = attrib->form_value.v[0]; break; - case DW_Attrib_RngListsBase: resolve_params.debug_rnglists_base = attrib->form_value.v[0]; break; - case DW_Attrib_LocListsBase: resolve_params.debug_loclists_base = attrib->form_value.v[0]; break; - } - } - } - - //- rjf: correct table offsets to header offsets (since DWARF V5 insists on being as useless as possible) - if(got_comp_unit_tag && version >= DW_Version_5) - { - resolve_params.debug_addrs_base = dw_v5_header_offset_from_table_offset(sections, DW_Section_Addr, resolve_params.debug_addrs_base); - resolve_params.debug_str_offs_base = dw_v5_header_offset_from_table_offset(sections, DW_Section_StrOffsets, resolve_params.debug_str_offs_base); - resolve_params.debug_loclists_base = dw_v5_header_offset_from_table_offset(sections, DW_Section_LocLists, resolve_params.debug_loclists_base); - resolve_params.debug_rnglists_base = dw_v5_header_offset_from_table_offset(sections, DW_Section_RngLists, resolve_params.debug_rnglists_base); - } - - //- rjf: parse the rest of the compilation unit tag's attributes that we'd - // like to cache - String8 name = {0}; - String8 producer = {0}; - String8 compile_dir = {0}; - String8 external_dwo_name = {0}; - String8 external_gnu_dwo_name = {0}; - U64 gnu_dwo_id = 0; - DW_Language language = 0; - U64 name_case = 0; - B32 use_utf8 = 0; - U64 low_pc = 0; - U64 high_pc = 0; - B32 high_pc_is_relative = 0; - DW_AttribValue ranges_attrib_value = {DW_Section_Null}; - U64 line_base = 0; - if(got_comp_unit_tag) - { - for(DW_AttribNode *attrib_n = comp_unit_tag->attribs.first; attrib_n; attrib_n = attrib_n->next) - { - DW_Attrib *attrib = &attrib_n->attrib; - - //- rjf: form value => value - DW_AttribValue value = {0}; - B32 good_value = 0; - { - if(dw_are_attrib_class_and_form_kind_compatible(version, attrib->value_class, attrib->form_kind)) - { - value = dw_attrib_value_from_form_value(sections, resolve_params, attrib->form_kind, attrib->value_class, attrib->form_value); - good_value = 1; - } - } - - //- rjf: map value to extracted info - if(good_value) - { - switch(attrib->attrib_kind) - { - case DW_Attrib_Name: name = dw_string_from_attrib_value(sections, value); break; - case DW_Attrib_Producer: producer = dw_string_from_attrib_value(sections, value); break; - case DW_Attrib_CompDir: compile_dir = dw_string_from_attrib_value(sections, value); break; - case DW_Attrib_DwoName: external_dwo_name = dw_string_from_attrib_value(sections, value); break; - case DW_Attrib_GNU_DwoName: external_gnu_dwo_name = dw_string_from_attrib_value(sections, value); break; - case DW_Attrib_GNU_DwoId: gnu_dwo_id = value.v[0]; break; - case DW_Attrib_Language: language = safe_cast_u32(value.v[0]); break; - case DW_Attrib_IdentifierCase: name_case = value.v[0]; break; - case DW_Attrib_UseUtf8: use_utf8 = (B32)value.v[0]; break; - case DW_Attrib_LowPc: low_pc = value.v[0]; break; - case DW_Attrib_HighPc: high_pc = value.v[0]; high_pc_is_relative = attrib->value_class != DW_AttribClass_Address; break; - case DW_Attrib_Ranges: ranges_attrib_value = value; break; - case DW_Attrib_StmtList: line_base = value.v[0]; break; - default: break; - } - } - } - } - - //- rjf: build+fill unit - DW_CompRoot unit = {0}; - - //- rjf: fill header data - unit.size = size; - unit.kind = unit_kind; - unit.version = version; - unit.address_size = address_size; - unit.abbrev_off = abbrev_base; - unit.info_off = range.min; - unit.tags_info_range = rng_1u64(range.min+next_off, range.max); - unit.abbrev_table = abbrev_table; - - //- rjf: fill out offsets we need for attrib value resolution - unit.rnglist_base = resolve_params.debug_rnglists_base; - unit.loclist_base = resolve_params.debug_loclists_base; - unit.addrs_base = resolve_params.debug_addrs_base; - unit.stroffs_base = resolve_params.debug_str_offs_base; - - //- rjf: fill out general info - unit.name = name; - unit.producer = producer; - unit.compile_dir = compile_dir; - unit.external_dwo_name = external_dwo_name.size ? external_dwo_name : external_gnu_dwo_name; - if(external_dwo_name.size) - { - unit.dwo_id = spec_dwo_id; - } - else if(external_gnu_dwo_name.size) - { - unit.dwo_id = gnu_dwo_id; - } - unit.language = language; - unit.name_case = name_case; - unit.use_utf8 = use_utf8; - unit.line_off = line_base; - unit.low_pc = low_pc; - unit.high_pc = high_pc; - unit.ranges_attrib_value = ranges_attrib_value; - unit.base_addr = unit.low_pc; - - //- rjf: fill fixup of low/high PC situation - if(high_pc_is_relative) - { - unit.high_pc += unit.low_pc; - } - - scratch_end(scratch); - return unit; -} - -internal DW_ExtDebugRef -dw_ext_debug_ref_from_comp_root(DW_CompRoot *root) -{ - DW_ExtDebugRef ref = {0}; - ref.dwo_path = root->external_dwo_name; - ref.dwo_id = root->dwo_id; return ref; } -//- rjf: line info +internal DW_LocList +dw_interp_loclist(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +{ + DW_LocList loclist = {0}; + + if (cu->version < DW_Version_5) { + if (form_kind == DW_Form_SecOffset) { + U64 sec_offset = max_U64; + if (form_kind == DW_Form_SecOffset) { + sec_offset = form.sec_offset; + } else if (form_kind == DW_Form_Data8 || form_kind == DW_Form_Data4 || + form_kind == DW_Form_Data2 || form_kind == DW_Form_Data1) { + if (!dw_try_u64_from_const_value(form.data.size, DW_ATE_Unsigned, form.data, &sec_offset)) { + Assert(!"unable to extract section offset"); + } + } else if (form_kind == DW_Form_Null) { + Assert(!"unexpected form"); + } + + String8 sec = str8_skip(input->sec[DW_Section_Loc].data, sec_offset); + U64 base_addr = cu->low_pc; + U64 base_sel = DW_SentinelFromSize(cu->address_size); + for (U64 cursor = 0; cursor < sec.size; ) { + U64 range_min = 0; + U64 range_min_off = cursor; + U64 range_min_size = str8_deserial_read(sec, range_min_off, &range_min, cu->address_size, cu->address_size); + if (range_min_size == 0) { + break; + } + U64 range_max = 0; + U64 range_max_off = cursor + cu->address_size; + U64 range_max_size = str8_deserial_read(sec, range_max_off, &range_max, cu->address_size, cu->address_size); + if (range_max_size == 0) { + break; + } + cursor += cu->address_size * 2; + + // series terminator + if (range_min == 0 && range_max == 0) { + break; + } + // set new base address + else if (range_min == base_sel) { + base_addr = range_max; + } + // location + else { + U16 expr_size = 0; + U64 expr_size_size = str8_deserial_read_struct(sec, cursor, &expr_size); + if (expr_size_size == 0) { + Assert(!"unable to read expression size"); + break; + } + cursor += expr_size_size; + + Assert(cursor + expr_size <= sec.size); + Rng1U64 expr_range = rng_1u64(cursor, ClampTop(cursor + expr_size, sec.size)); + + DW_LocNode *loc_n = push_array(arena, DW_LocNode, 1); + loc_n->v.range = rng_1u64(base_addr + range_min, base_addr + range_max); + loc_n->v.expr = str8_substr(sec, expr_range); + + SLLQueuePush(loclist.first, loclist.last, loc_n); + ++loclist.count; + + // advance past expression + cursor += expr_size; + } + } + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + } else { + DW_Version version = DW_Version_Null; + String8 raw_lle = {0}; + if (form_kind == DW_Form_SecOffset) { + // offset is from beginning of the section + U64 sec_offset = form.sec_offset; + raw_lle = str8_skip(input->sec[DW_Section_LocLists].data, sec_offset); + } else if (form_kind == DW_Form_LocListx) { + // offset is from beginning of the entries + U64 entries_off = dw_offset_from_list_unit(cu->loclists_lu, form.xval); + raw_lle = str8_skip(cu->loclists_lu->entries, entries_off); + version = cu->loclists_lu->version; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + + for (U64 cursor = 0, keep_parsing = 1, base_addr = cu->low_pc; + cursor < raw_lle.size && keep_parsing; ) { + DW_LLE kind = DW_LLE_EndOfList; + cursor += str8_deserial_read_struct(raw_lle, cursor, &kind); + + Rng1U64 range = {0}; + switch (kind) { + default: + Assert(!"unknown kind"); + case DW_LLE_EndOfList: { + keep_parsing = 0; + } break; + case DW_LLE_BaseAddressx: { + if (!cu->addr_lu) { + keep_parsing = 0; + break; + } + + U64 addrx = 0; + U64 addrx_size = str8_deserial_read_uleb128(raw_lle, cursor, &addrx); + if (addrx_size == 0) { + keep_parsing = 0; + break; + } + + U64 base_addr_new = dw_addr_from_list_unit(cu->addr_lu, addrx); + if (base_addr_new == max_U64) { + InvalidPath; + break; + } + + base_addr = base_addr_new; + cursor += addrx_size; + } break; + case DW_LLE_StartxEndx: { + U64 start_addrx = 0; + U64 start_addrx_size = str8_deserial_read_uleb128(raw_lle, cursor, &start_addrx); + if (start_addrx_size == 0) { + keep_parsing = 0; + break; + } + U64 end_addrx = 0; + U64 end_addrx_size = str8_deserial_read_uleb128(raw_lle, cursor + start_addrx_size, &end_addrx); + if (end_addrx_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_addrx_size; + cursor += end_addrx_size; + + U64 start = dw_addr_from_list_unit(cu->addr_lu, start_addrx); + U64 end = dw_addr_from_list_unit(cu->addr_lu, end_addrx); + Assert(start != max_U64); + Assert(end != max_U64); + + range = rng_1u64(start, end); + } break; + case DW_LLE_StartxLength: { + U64 start_addrx = 0; + U64 start_addrx_size = str8_deserial_read_uleb128(raw_lle, cursor, &start_addrx); + if (start_addrx_size == 0) { + keep_parsing = 0; + break; + } + + // parse pre-standard & standard length + U64 length_off = cursor + start_addrx_size; + U64 length = 0; + U64 length_size = str8_deserial_read_uleb128(raw_lle, length_off, &length); + if (length_size == 0) { + keep_parsing = 0; + break; + } + + cursor += start_addrx_size; + cursor += length_size; + + if (cu->addr_lu) { + U64 start = dw_addr_from_list_unit(cu->addr_lu, start_addrx); + Assert(start < max_U64); + + range = rng_1u64(start, start + length); + } else { + Assert(!".debug_addr section is missing -- unable to interpret address index"); + } + } break; + case DW_LLE_OffsetPair: { + U64 start = 0; + U64 start_size = str8_deserial_read_uleb128(raw_lle, cursor, &start); + if (start_size == 0) { + keep_parsing = 0; + break; + } + U64 end = 0; + U64 end_size = str8_deserial_read_uleb128(raw_lle, cursor + start_size, &end); + if (end_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_size; + cursor += end_size; + + range = rng_1u64(base_addr + start, base_addr + end); + } break; + case DW_LLE_DefaultLocation: { + // no range + int x = 0; + } break; + case DW_LLE_BaseAddress: { + U64 base_addr_size = str8_deserial_read(raw_lle, cursor, &base_addr, cu->address_size, cu->address_size); + if (base_addr_size == 0) { + keep_parsing = 0; + break; + } + cursor += base_addr_size; + } break; + case DW_LLE_StartEnd: { + U64 start = 0; + U64 start_size = str8_deserial_read(raw_lle, cursor, &start, cu->address_size, cu->address_size); + if (start_size == 0) { + keep_parsing = 0; + break; + } + + U64 end = 0; + U64 end_size = str8_deserial_read(raw_lle, cursor + start_size, &end, cu->address_size, cu->address_size); + if (end_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_size; + cursor += end_size; + + range = rng_1u64(start, end); + } break; + case DW_LLE_StartLength: { + U64 start = 0; + U64 start_size = str8_deserial_read(raw_lle, cursor, &start, cu->address_size, cu->address_size); + if (start_size == 0) { + keep_parsing = 0; + break; + } + U64 length = 0; + U64 length_size = str8_deserial_read_uleb128(raw_lle, cursor + start_size, &length); + if (length_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_size; + cursor += length_size; + + range = rng_1u64(start, start + length); + } break; + } + + B32 has_expr = keep_parsing && kind != DW_LLE_BaseAddressx && kind != DW_LLE_BaseAddress; + if (has_expr) { + U64 expr_size = 0; + U64 expr_size_size = str8_deserial_read_uleb128(raw_lle, cursor, &expr_size); + if (expr_size_size == 0) { + keep_parsing = 0; + break; + } + + String8 expr = {0}; + U64 expr_read_size = str8_deserial_read_block(raw_lle, cursor + expr_size_size, expr_size, &expr); + if (expr_read_size != expr_size) { + keep_parsing = 0; + break; + } + + cursor += expr_size_size; + cursor += expr_size; + + DW_LocNode *loc_n = push_array(arena, DW_LocNode, 1); + loc_n->v.range = range; + loc_n->v.expr = expr; + + SLLQueuePush(loclist.first, loclist.last, loc_n); + ++loclist.count; + } + } + } + + return loclist; +} + +internal B32 +dw_interp_flag(DW_FormKind form_kind, DW_Form form) +{ + B32 flag = 0; + if (form_kind == DW_Form_Flag || form_kind == DW_Form_FlagPresent) { + flag = form.flag; + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + return flag; +} + +internal Rng1U64List +dw_interp_rnglist(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +{ + Rng1U64List rnglist = {0}; + + if (cu->version < DW_Version_5) { + // decode section offset + U64 sec_offset = max_U64; + if (form_kind == DW_Form_SecOffset) { + sec_offset = form.sec_offset; + } else if (form_kind == DW_Form_Data8 || form_kind == DW_Form_Data4 || + form_kind == DW_Form_Data2 || form_kind == DW_Form_Data1) { + if (!dw_try_u64_from_const_value(form.data.size, DW_ATE_Unsigned, form.data, &sec_offset)) { + Assert(!"unable to extract section offset"); + } + } else if (form_kind != DW_Form_Null) { + Assert(!"unexpected form"); + } + + String8 sec = str8_skip(input->sec[DW_Section_Ranges].data, sec_offset); + U64 base_addr = cu->low_pc; + U64 base_sel = DW_SentinelFromSize(cu->address_size); + for (U64 cursor = 0; cursor < sec.size; ) { + U64 range_min = 0; + U64 range_min_off = cursor; + U64 range_min_size = str8_deserial_read(sec, range_min_off, &range_min, cu->address_size, cu->address_size); + if (range_min_size == 0) { + break; + } + U64 range_max = 0; + U64 range_max_off = cursor + cu->address_size; + U64 range_max_size = str8_deserial_read(sec, range_max_off, &range_max, cu->address_size, cu->address_size); + if (range_max_size == 0) { + break; + } + cursor += cu->address_size * 2; + + // series terminator + if (range_min == 0 && range_max == 0) { + break; + } + // set new base address + else if (range_min == base_sel) { + base_addr = range_max; + } + // range + else { + Rng1U64 range = rng_1u64(base_addr + range_min, base_addr + range_max); + rng1u64_list_push(arena, &rnglist, range); + } + } + } else { + String8 raw_rle = {0}; + if (form_kind == DW_Form_SecOffset) { + // offset is from beginning of the section + U64 sec_offset = form.sec_offset; + raw_rle = str8_skip(input->sec[DW_Section_RngLists].data, sec_offset); + } else if (form_kind == DW_Form_RngListx) { + // offset is from beginning of the entries + U64 sec_offset = dw_offset_from_list_unit(cu->rnglists_lu, form.xval); + raw_rle = str8_skip(cu->rnglists_lu->entries, sec_offset); + } else if (form_kind != DW_Form_Null) { + AssertAlways(!"unexpected form"); + } + + U64 rle_invalid_value = DW_SentinelFromSize(cu->address_size); + U64 base_addr = cu->low_pc; + for (U64 cursor = 0, keep_parsing = 1; cursor < raw_rle.size && keep_parsing; ) { + DW_RLE kind = DW_RLE_EndOfList; + cursor += str8_deserial_read_struct(raw_rle, cursor, &kind); + + Rng1U64 range = rng_1u64(rle_invalid_value, rle_invalid_value); + switch (kind) { + default: + case DW_RLE_EndOfList: { + keep_parsing = 0; + } break; + case DW_RLE_BaseAddressx: { + U64 addrx = 0; + U64 addrx_size = str8_deserial_read_uleb128(raw_rle, cursor, &addrx); + if (addrx_size == 0) { + keep_parsing = 0; + break; + } + if (cu->addr_lu == 0) { + keep_parsing = 0; + break; + } + U64 base_addr_new = dw_addr_from_list_unit(cu->addr_lu, addrx); + if (base_addr_new < max_U64) { + base_addr = base_addr_new; + cursor += addrx_size; + } else { + keep_parsing = 0; + Assert(!"invalid addrx"); + } + } break; + case DW_RLE_StartxLength: { + U64 start_addrx = 0; + U64 start_addrx_size = str8_deserial_read_uleb128(raw_rle, cursor, &start_addrx); + if (start_addrx_size == 0) { + keep_parsing = 0; + break; + } + U64 length = 0; + U64 length_size = str8_deserial_read_uleb128(raw_rle, cursor + start_addrx_size, &length); + if (length_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_addrx_size; + cursor += length_size; + + if (cu->addr_lu) { + U64 start = dw_addr_from_list_unit(cu->addr_lu, start_addrx); + AssertAlways(start < max_U64); + range = rng_1u64(start, start + length); + } + } break; + case DW_RLE_OffsetPair: { + U64 offset_start, offset_end = 0; + U64 offset_start_size = str8_deserial_read_uleb128(raw_rle, cursor, &offset_start); + if (offset_start_size == 0) { + keep_parsing = 0; + break; + } + U64 offset_end_size = str8_deserial_read_uleb128(raw_rle, cursor + offset_start_size, &offset_end); + if (offset_end_size == 0) { + keep_parsing = 0; + break; + } + cursor += offset_start_size; + cursor += offset_end_size; + + range = rng_1u64(base_addr + offset_start, base_addr + offset_end); + } break; + case DW_RLE_BaseAddress: { + U64 base_addr_size = str8_deserial_read(raw_rle, cursor, &base_addr, cu->address_size, cu->address_size); + if (base_addr_size == 0) { + keep_parsing = 0; + break; + } + cursor += base_addr_size; + } break; + case DW_RLE_StartEnd: { + U64 start = 0, end = 0; + + U64 start_size = str8_deserial_read(raw_rle, cursor, &start, cu->address_size, cu->address_size); + if (start_size == 0) { + keep_parsing = 0; + break; + } + U64 end_size = str8_deserial_read(raw_rle, cursor + start_size, &end, cu->address_size, cu->address_size); + if (end_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_size; + cursor += end_size; + + range = rng_1u64(start, end); + } break; + case DW_RLE_StartLength: { + U64 start = 0, length = 0; + + U64 start_size = str8_deserial_read(raw_rle, cursor, &start, cu->address_size, cu->address_size); + if (start_size == 0) { + keep_parsing = 0; + break; + } + U64 length_size = str8_deserial_read_uleb128(raw_rle, cursor + start_size, &length); + if (length_size == 0) { + keep_parsing = 0; + break; + } + cursor += start_size; + cursor += length_size; + + range = rng_1u64(start, start + length); + } break; + } + + if (range.min != rle_invalid_value) { + rng1u64_list_push(arena, &rnglist, range); + } + } + } + + return rnglist; +} + +internal String8 +dw_interp_secptr(DW_Input *input, DW_SectionKind section, DW_FormKind form_kind, DW_Form form) +{ + String8 secptr = {0}; + if (form_kind == DW_Form_SecOffset) { + String8 sect = input->sec[section].data; + Rng1U64 range = rng_1u64(form.sec_offset, sect.size); + secptr = str8_substr(sect, range); + } else if (form_kind != DW_Form_Null) { + Assert(!"unexpected form"); + } + return secptr; +} + +internal String8 +dw_interp_addrptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) +{ + return dw_interp_secptr(input, DW_Section_Addr, form_kind, form); +} + +internal String8 +dw_interp_str_offsets_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) +{ + return dw_interp_secptr(input, DW_Section_StrOffsets, form_kind, form); +} + +internal String8 +dw_interp_rnglists_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) +{ + return dw_interp_secptr(input, DW_Section_RngLists, form_kind, form); +} + +internal String8 +dw_interp_loclists_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) +{ + return dw_interp_secptr(input, DW_Section_LocLists, form_kind, form); +} + +internal DW_AttribClass +dw_value_class_from_attrib(DW_CompUnit *cu, DW_Attrib *attrib) +{ + return dw_pick_attrib_value_class(cu->version, cu->ext, cu->relaxed, attrib->attrib_kind, attrib->form_kind); +} + +internal String8 +dw_exprloc_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_ExprLoc || value_class == DW_AttribClass_Block); + return dw_interp_exprloc(attrib->form_kind, attrib->form); +} + +internal U128 +dw_const_u128_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_const_u128(attrib->form_kind, attrib->form); +} + +internal U64 +dw_const_u64_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_const_u64(attrib->form_kind, attrib->form); +} + +internal U32 +dw_const_u32_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_const_u32(attrib->form_kind, attrib->form); +} + +internal S64 +dw_const_s64_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_const_s64(attrib->form_kind, attrib->form); +} + +internal S32 +dw_const_s32_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_const_s32(attrib->form_kind, attrib->form); +} + +internal B32 +dw_flag_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Flag); + return dw_interp_flag(attrib->form_kind, attrib->form); +} + +internal U64 +dw_address_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || + value_class == DW_AttribClass_Address || + value_class == DW_AttribClass_AddrPtr); + DW_FormKind form_kind = attrib->form_kind; + DW_Form form = attrib->form; + if (value_class == DW_AttribClass_AddrPtr) { + + if (attrib->form_kind == DW_Form_SecOffset) { + + + } else { + AssertAlways(!"unexpected form"); + } + + + form_kind = DW_Form_Addr; + form.addr = dw_interp_addrptr(input, attrib->form_kind, attrib->form); + } + return dw_interp_address(cu->address_size, cu->low_pc, cu->addr_lu, form_kind, form); +} + +internal String8 +dw_block_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Block); + return dw_interp_block(input, cu, attrib->form_kind, attrib->form); +} + +internal String8 +dw_string_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_String || value_class == DW_AttribClass_StrOffsetsPtr); + return dw_interp_string(input, cu->format, cu->str_offsets_lu, attrib->form_kind, attrib->form); +} + +internal String8 +dw_line_ptr_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_LinePtr); + return dw_interp_line_ptr(input, attrib->form_kind, attrib->form); +} + +internal DW_LineFile * +dw_file_from_attrib_ptr(DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); + return dw_interp_file(line_vm, attrib->form_kind, attrib->form); +} + +internal DW_Reference +dw_ref_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Reference); + return dw_interp_ref(input, cu, attrib->form_kind, attrib->form); +} + +internal DW_LocList +dw_loclist_from_attrib_ptr(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + AssertAlways(value_class == DW_AttribClass_Null || + value_class == DW_AttribClass_LocList || + value_class == DW_AttribClass_LocListPtr); + return dw_interp_loclist(arena, input, cu, attrib->form_kind, attrib->form); +} + +internal Rng1U64List +dw_rnglist_from_attrib_ptr(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) +{ + Rng1U64List rnglist = {0}; + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + if (value_class == DW_AttribClass_RngListPtr || DW_AttribClass_RngList) { + rnglist = dw_interp_rnglist(arena, input, cu, attrib->form_kind, attrib->form); + } else if (value_class != DW_AttribClass_Null) { + Assert(!"unexpected value class"); + } + return rnglist; +} + +internal DW_Attrib * +dw_attrib_from_tag_(DW_Tag tag, DW_AttribKind kind) +{ + local_persist read_only DW_Attrib null_attrib; + DW_Attrib *attrib = &null_attrib; + for (DW_AttribNode *attrib_n = tag.attribs.first; attrib_n != 0; attrib_n = attrib_n->next) { + if (attrib_n->v.attrib_kind == kind) { + attrib = &attrib_n->v; + break; + } + } + return attrib; +} + +internal DW_Attrib * +dw_attrib_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + DW_Attrib *attrib = dw_attrib_from_tag_(tag, kind); + + if (attrib->attrib_kind == DW_Attrib_Null) { + if (cu && cu->tag_ht) { + DW_Attrib *ao_attrib = dw_attrib_from_tag_(tag, DW_Attrib_AbstractOrigin); + if (ao_attrib->attrib_kind == DW_Attrib_AbstractOrigin) { + DW_Reference ref = dw_interp_ref(input, cu, ao_attrib->form_kind, ao_attrib->form); + DW_TagNode *ref_tag = dw_tag_node_from_info_off(ref.cu, ref.info_off); + attrib = dw_attrib_from_tag_(ref_tag->tag, kind); + } + } + } + + return attrib; +} + +internal B32 +dw_tag_has_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + B32 has_attrib = attrib->attrib_kind != DW_Attrib_Null; + return has_attrib; +} + +internal String8 +dw_exprloc_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_exprloc_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal String8 +dw_block_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_block_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal U128 +dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_const_u128_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal U64 +dw_const_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_const_u64_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal U32 +dw_const_u32_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_const_u32_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal U64 +dw_address_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_address_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal String8 +dw_string_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_string_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal String8 +dw_line_ptr_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_line_ptr_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal DW_Reference +dw_ref_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_ref_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal DW_LocList +dw_loclist_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_loclist_from_attrib_ptr(arena, input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal Rng1U64List +dw_rnglist_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_rnglist_from_attrib_ptr(arena, input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal B32 +dw_flag_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + return dw_flag_from_attrib_ptr(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal DW_LineFile * +dw_file_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind) +{ + return dw_file_from_attrib_ptr(cu, line_vm, dw_attrib_from_tag(input, cu, tag, kind)); +} + +internal B32 +dw_try_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, U64 *byte_size_out) +{ + B32 has_byte_size = dw_tag_has_attrib(input, cu, tag, DW_Attrib_ByteSize); + B32 has_bit_size = dw_tag_has_attrib(input, cu, tag, DW_Attrib_BitSize ); + + if (has_byte_size && has_bit_size) { + Assert(!"ill formated byte size"); + } + + if (has_byte_size) { + *byte_size_out = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_ByteSize); + return 1; + } else if (has_bit_size) { + U64 bit_size = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_BitSize); + *byte_size_out = bit_size / 8; + return 1; + } + + return 0; +} + +internal U64 +dw_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) +{ + U64 byte_size = max_U64; + dw_try_byte_size_from_tag(input, cu, tag, &byte_size); + return byte_size; +} + +internal U32 +dw_byte_size_32_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) +{ + U32 byte_size32; + U64 byte_size64; + if (dw_try_byte_size_from_tag(input, cu, tag, &byte_size64)) { + byte_size32 = safe_cast_u32(byte_size64); + } + return byte_size32; +} + +internal U64 +dw_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + U64 result = 0; + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + DW_AttribClass attrib_class = dw_value_class_from_attrib(cu, attrib); + if (attrib_class == DW_AttribClass_Const || attrib_class == DW_AttribClass_Block) { + if (dw_tag_has_attrib(input, cu, tag, DW_Attrib_Type)) { + Temp scratch = scratch_begin(0,0); + DW_Reference type_ref = dw_ref_from_attrib(input, cu, tag, DW_Attrib_Type); + DW_Tag type_tag = {0}; + dw_read_tag_cu(scratch.arena, input, type_ref.cu, type_ref.info_off, &type_tag); + U64 type_byte_size = dw_byte_size_from_tag(input, cu, type_tag); + DW_ATE type_encoding = dw_const_u64_from_attrib(input, type_ref.cu, type_tag, DW_Attrib_Encoding); + if (type_encoding == DW_ATE_Unsigned || type_encoding == DW_ATE_UnsignedChar) { + result = dw_interp_const64(type_byte_size, type_encoding, attrib->form_kind, attrib->form); + } + scratch_end(scratch); + } else { + result = dw_interp_const_u64(attrib->form_kind, attrib->form); + } + } else if (attrib_class == DW_AttribClass_Reference) { + NotImplemented; + } else if (attrib_class != DW_AttribClass_Null) { + AssertAlways(!"unexpected attrib class"); + } + return result; +} + +internal DW_CompUnit +dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed) +{ + DW_CompUnit cu = {0}; + + String8 info_data = input->sec[DW_Section_Info].data; + + // read unit size in bytes + U64 length = 0; + U64 length_size = str8_deserial_read_dwarf_packed_size(info_data, offset, &length); + + if (length_size) { + // compute unit range + Rng1U64 range = rng_1u64(offset, offset + length_size + length); + String8 data = str8_substr(info_data, range); + U64 cursor = length_size; + + // read version + DW_Version version = 0; + U64 version_size = str8_deserial_read_struct(data, cursor, &version); + cursor += version_size; + + if (version_size) { + DW_Format format = DW_FormatFromSize(length); + B32 is_header_ok = 0; + U64 abbrev_base = max_U64; + U8 address_size = 0; + DW_CompUnitKind unit_kind = DW_CompUnitKind_Reserved; + U64 spec_dwo_id = max_U64; + + switch (version) { + default: + case DW_Version_Null: + case DW_Version_1: + break; + case DW_Version_2: { + U32 abbrev_base32 = 0; + U64 abbrev_base_off = cursor; + U64 abbrev_base_size = str8_deserial_read_struct(data, abbrev_base_off, &abbrev_base32); + if (!abbrev_base_size) { + break; + } + + U64 address_size_off = abbrev_base_off + abbrev_base_size; + U64 address_size_size = str8_deserial_read_struct(data, address_size_off, &address_size); + if (!address_size_size) { + break; + } + + abbrev_base = abbrev_base32; + cursor = address_size_off + address_size_size; + is_header_ok = 1; + } break; + case DW_Version_3: + case DW_Version_4: { + U64 abbrev_base_off = cursor; + U64 abbrev_base_size = str8_deserial_read_dwarf_uint(data, abbrev_base_off, format, &abbrev_base); + if (!abbrev_base_size) { + break; + } + + U64 address_size_off = abbrev_base_off + abbrev_base_size; + U64 address_size_size = str8_deserial_read_struct(data, address_size_off, &address_size); + if (!address_size_size) { + break; + } + + cursor = address_size_off + address_size_size; + is_header_ok = 1; + } break; + case DW_Version_5: { + U64 unit_kind_off = cursor; + U64 unit_kind_size = str8_deserial_read_struct(data, unit_kind_off, &unit_kind); + if (unit_kind_size == 0) { + break; + } + + U64 address_size_off = unit_kind_off + unit_kind_size; + U64 address_size_size = str8_deserial_read_struct(data, address_size_off, &address_size); + if (!address_size_size) { + break; + } + + U64 abbrev_base_off = address_size_off + address_size_size; + U64 abbrev_base_size = str8_deserial_read_dwarf_uint(data, abbrev_base_off, format, &abbrev_base); + if (!abbrev_base_size) { + break; + } + + U64 spec_dwo_id_off = abbrev_base_off + abbrev_base_size; + U64 spec_dwo_id_size = 0; + if (unit_kind == DW_CompUnitKind_Skeleton || input->sec[DW_Section_Info].is_dwo) { + spec_dwo_id_size = str8_deserial_read_struct(data, spec_dwo_id_off, &spec_dwo_id); + if (!spec_dwo_id_size) { + break; + } + } + + cursor = spec_dwo_id_off + spec_dwo_id_size; + is_header_ok = 1; + } break; + } + + if (is_header_ok) { + Temp temp = temp_begin(arena); + + // TODO: cache abbrev tables with identical offsets + String8 abbrev_data = input->sec[DW_Section_Abbrev].data; + DW_AbbrevTable abbrev_table = dw_make_abbrev_table(arena, abbrev_data, abbrev_base); + + DW_Tag cu_tag = {0}; + dw_read_tag(arena, data, cursor, range.min, abbrev_table, abbrev_data, version, format, address_size, &cu_tag); + + // TODO: handle these unit types + Assert(cu_tag.kind != DW_Tag_SkeletonUnit); + Assert(cu_tag.kind != DW_Tag_TypeUnit); + + if (cu_tag.kind == DW_Tag_CompileUnit || cu_tag.kind == DW_Tag_PartialUnit) { + // fetch attribs for list sections + DW_Attrib *addr_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_AddrBase ); + DW_Attrib *str_offsets_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_StrOffsetsBase); + DW_Attrib *rnglists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_RngListsBase ); + DW_Attrib *loclists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_LocListsBase ); + + // interp attribs as section offsets + U64 addr_sec_off = dw_interp_sec_offset(addr_base_attrib->form_kind, addr_base_attrib->form ); + U64 str_offsets_sec_off = dw_interp_sec_offset(str_offsets_base_attrib->form_kind, str_offsets_base_attrib->form); + U64 rnglists_sec_off = dw_interp_sec_offset(rnglists_base_attrib->form_kind, rnglists_base_attrib->form ); + U64 loclists_sec_off = dw_interp_sec_offset(loclists_base_attrib->form_kind, loclists_base_attrib->form ); + + // map section offset to unit index + U64 addr_lu_idx = rng_1u64_array_bsearch(lu_input.addr_ranges, addr_sec_off ); + U64 str_offsets_lu_idx = rng_1u64_array_bsearch(lu_input.str_offset_ranges, str_offsets_sec_off); + U64 rnglists_lu_idx = rng_1u64_array_bsearch(lu_input.rnglist_ranges, rnglists_sec_off ); + U64 loclists_lu_idx = rng_1u64_array_bsearch(lu_input.loclist_ranges, loclists_sec_off ); + + // map index to unit + DW_ListUnit *addr_lu = addr_lu_idx < lu_input.addr_count ? &lu_input.addrs[addr_lu_idx] : 0; + DW_ListUnit *str_offsets_lu = str_offsets_lu_idx < lu_input.str_offset_count ? &lu_input.str_offsets[str_offsets_lu_idx] : 0; + DW_ListUnit *rnglists_lu = rnglists_lu_idx < lu_input.rnglist_count ? &lu_input.rnglists[rnglists_lu_idx] : 0; + DW_ListUnit *loclists_lu = loclists_lu_idx < lu_input.loclist_count ? &lu_input.loclists[loclists_lu_idx] : 0; + + // find compile unit base address + DW_Attrib *low_pc_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_LowPc); + U64 low_pc = dw_interp_address(address_size, max_U64, addr_lu, low_pc_attrib->form_kind, low_pc_attrib->form); + + // fill out compile unit + cu.relaxed = relaxed; + cu.ext = DW_Ext_All; + cu.kind = unit_kind; + cu.version = version; + cu.format = format; + cu.address_size = address_size; + cu.abbrev_off = abbrev_base; + cu.info_range = range; + cu.first_tag_info_off = range.min + cursor; + cu.abbrev_table = abbrev_table; + cu.abbrev_data = abbrev_data; + cu.addr_lu = addr_lu; + cu.str_offsets_lu = str_offsets_lu; + cu.rnglists_lu = rnglists_lu; + cu.loclists_lu = loclists_lu; + cu.low_pc = low_pc; + cu.tag = cu_tag; + } else { + // unexpected tag, release memory and exit + temp_end(temp); + } + } + } + } + + return cu; +} + +internal void +dw_tag_tree_from_data(Arena *arena, String8 info_data, String8 abbrev_data, DW_CompUnit *cu, DW_TagNode *parent, U64 *cursor, U64 *tag_count) +{ + while (*cursor < info_data.size) { + // read tag + DW_Tag tag = {0}; + U64 tag_size = dw_read_tag(arena, info_data, *cursor, cu->info_range.min, cu->abbrev_table, abbrev_data, cu->version, cu->format, cu->address_size, &tag); + if (tag_size == 0) { + break; + } + *cursor += tag_size; + + // is this sentinel tag? + if (tag.kind == DW_Tag_Null) { + break; + } + + // normal tag + DW_TagNode *tag_n = push_array(arena, DW_TagNode, 1); + tag_n->tag = tag; + + SLLQueuePush_N(parent->first_child, parent->last_child, tag_n, sibling); + + // update tag count + *tag_count += 1; + + if (tag.has_children) { + dw_tag_tree_from_data(arena, info_data, abbrev_data, cu, tag_n, cursor, tag_count); + } + } +} + +internal DW_TagTree +dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu) +{ + String8 abbrev_data = input->sec[DW_Section_Abbrev].data; + String8 info_data = str8_substr(input->sec[DW_Section_Info].data, cu->info_range); + DW_TagNode root = {0}; + U64 cursor = cu->first_tag_info_off; + U64 tag_count = 0; + dw_tag_tree_from_data(arena, info_data, abbrev_data, cu, &root, &cursor, &tag_count); + + DW_TagTree result = {0}; + result.root = root.first_child; + result.tag_count = tag_count; + + return result; +} + +internal HashTable * +dw_make_tag_hash_table(Arena *arena, DW_TagTree tag_tree) +{ + Temp scratch = scratch_begin(&arena, 1); + + struct Frame { + struct Frame *next; + DW_TagNode *node; + }; + + struct Frame *free_frames = 0; + struct Frame *stack = push_array(scratch.arena, struct Frame, 1); + stack->node = tag_tree.root; + + HashTable *ht = hash_table_init(arena, (U64)((F64)tag_tree.tag_count * 1.3)); + + while (stack) { + while (stack->node) { + hash_table_push_u64_raw(arena, ht, stack->node->tag.info_off, stack->node); + + if (stack->node->first_child) { + struct Frame *frame = free_frames; + if (frame) { + SLLStackPop(free_frames); + MemoryZeroStruct(frame); + } else { + frame = push_array(scratch.arena, struct Frame, 1); + } + frame->node = stack->node->first_child; + SLLStackPush(stack, frame); + } else { + stack->node = stack->node->sibling; + } + } + + // recycle free frame + struct Frame *frame = stack; + SLLStackPop(stack); + SLLStackPush(free_frames, frame); + + if (stack) { + stack->node = stack->node->sibling; + } + } + + scratch_end(scratch); + return ht; +} + +internal DW_TagNode * +dw_tag_node_from_info_off(DW_CompUnit *cu, U64 info_off) +{ + DW_TagNode *tag_node = hash_table_search_u64_raw(cu->tag_ht, info_off); + return tag_node; +} + +internal DW_LineVMFileArray +dw_line_vm_file_array_from_list(Arena *arena, DW_LineVMFileList list) +{ + DW_LineVMFileArray result = {0}; + result.count = 0; + result.v = push_array(arena, DW_LineFile, list.node_count); + + for (DW_LineVMFileNode *src = list.first; src != 0; src = src->next) { + DW_LineFile *dst = &result.v[result.count++]; + dst->file_name = push_str8_copy(arena, src->file.file_name); + dst->dir_idx = src->file.dir_idx; + dst->modify_time = src->file.modify_time; + dst->file_size = src->file.file_size; + } + + return result; +} + +internal U64 +dw_read_line_file(String8 data, + U64 off, + DW_Input *input, + DW_Version version, + DW_Format format, + DW_Ext ext, + U64 address_size, + DW_ListUnit *str_offsets, + U64 enc_count, + U64 *enc_arr, + DW_LineFile *line_file_out) +{ + MemoryZeroStruct(line_file_out); + U64 cursor = off; + for (U64 enc_idx = 0; enc_idx < enc_count; ++enc_idx) { + DW_LNCT lnct = enc_arr[enc_idx*2 + 0]; + DW_FormKind form_kind = enc_arr[enc_idx*2 + 1]; + DW_Form form = {0}; + U64 bytes_read; + switch (lnct) { + case DW_LNCT_Path: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->file_name = dw_interp_string(input, format, str_offsets, form_kind, form); + } break; + case DW_LNCT_DirectoryIndex: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->dir_idx = dw_interp_const_u64(form_kind, form); + } break; + case DW_LNCT_TimeStamp: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->modify_time = dw_interp_const_u64(form_kind, form); + } break; + case DW_LNCT_Size: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->file_size = dw_interp_const_u64(form_kind, form); + } break; + case DW_LNCT_MD5: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->md5_digest = dw_interp_const_u128(form_kind, form); + } break; + case DW_LNCT_LLVM_Source: { + if (ext & DW_Ext_LLVM) { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + line_file_out->source = dw_interp_string(input, format, str_offsets, form_kind, form); + } else { + Assert(!"extension not supported"); + } + } break; + default: { + bytes_read = dw_read_form(data, cursor, version, format, address_size, form_kind, max_U64, &form); + Assert(!"unexpected LNTC encoding"); + } break; + } + Assert(bytes_read); + cursor += bytes_read; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +dw_read_line_file_array(Arena *arena, + String8 data, + U64 off, + DW_Input *input, + DW_Version version, + DW_Format format, + DW_Ext ext, + U64 address_size, + DW_ListUnit *str_offsets, + U64 enc_count, + U64 *enc_arr, + U64 table_count, + DW_LineVMFileArray *table_out) +{ + Temp temp = temp_begin(arena); + + table_out->count = table_count; + table_out->v = push_array(arena, DW_LineFile, table_count); + + U64 i, cursor; + for (i = 0, cursor = off; i < table_count; ++i) { + U64 bytes_read = dw_read_line_file(data, + cursor, + input, + version, + format, + ext, + address_size, + str_offsets, + enc_count, + enc_arr, + &table_out->v[i]); + if (bytes_read == 0) { + break; + } + cursor += bytes_read; + } + + U64 bytes_read = 0; + if (i == table_count) { + bytes_read = cursor - off; + } else { + temp_end(temp); + table_out->count = 0; + table_out->v = 0; + } + + return bytes_read; +} + +internal U64 +dw_read_line_vm_header(Arena *arena, + String8 line_data, + U64 line_off, + DW_Input *input, + String8 cu_dir, + String8 cu_name, + U8 cu_address_size, + DW_ListUnit *cu_str_offsets, + DW_LineVMHeader *header_out) +{ + Temp scratch = scratch_begin(&arena, 1); + + U64 bytes_read = 0; + + // read unit length + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(line_data, line_off, &unit_length); + + U64 unit_opl = line_off + unit_length_size + unit_length; + Rng1U64 unit_range = rng_1u64(line_off, unit_opl); + DW_Format format = DW_FormatFromSize(unit_length); + U64 unit_cursor = unit_length_size; + String8 unit_data = str8_substr(line_data, unit_range); + + // read unit version + DW_Version version = DW_Version_Null; + U64 version_size = str8_deserial_read_struct(unit_data, unit_cursor, &version); + if (version_size == 0) { + goto exit; + } + unit_cursor += version_size; + + // read DWARF5 address & segment selector + U8 address_size = 0; + U8 segsel_size = 0; + if (version == DW_Version_5) { + U64 address_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &address_size); + if (address_size_size == 0) { + goto exit; + } + unit_cursor += address_size_size; + + U64 segsel_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &segsel_size); + if (segsel_size_size == 0) { + goto exit; + } + unit_cursor += segsel_size_size; + } else { + address_size = cu_address_size; + } + + // read header length + U64 header_length = 0; + U64 header_length_size = str8_deserial_read_dwarf_uint(unit_data, unit_cursor, format, &header_length); + if (header_length_size == 0) { + goto exit; + } + unit_cursor += header_length_size; + + // read min instruction length + U8 min_inst_len = 0; + U64 min_inst_len_size = str8_deserial_read_struct(unit_data, unit_cursor, &min_inst_len); + if (min_inst_len_size == 0) { + goto exit; + } + unit_cursor += min_inst_len_size; + + // read max operands for instruction + U8 max_ops_for_inst = 1; + if (version > DW_Version_3) { + U64 max_ops_for_inst_size = str8_deserial_read_struct(unit_data, unit_cursor, &max_ops_for_inst); + if (max_ops_for_inst_size == 0) { + goto exit; + } + unit_cursor += max_ops_for_inst_size; + } + Assert(max_ops_for_inst > 0); + + U8 default_is_stmt = 0; + U64 default_is_stmt_size = str8_deserial_read_struct(unit_data, unit_cursor, &default_is_stmt); + if (default_is_stmt_size == 0) { + goto exit; + } + unit_cursor += default_is_stmt_size; + + S8 line_base = 0; + U64 line_base_size = str8_deserial_read_struct(unit_data, unit_cursor, &line_base); + if (line_base_size == 0) { + goto exit; + } + unit_cursor += line_base_size; + + U8 line_range = 0; + U64 line_range_size = str8_deserial_read_struct(unit_data, unit_cursor, &line_range); + if (line_range_size == 0) { + goto exit; + } + unit_cursor += line_range_size; + + U8 opcode_base = 0; + U64 opcode_base_size = str8_deserial_read_struct(unit_data, unit_cursor, &opcode_base); + if (opcode_base_size == 0) { + goto exit; + } + unit_cursor += opcode_base_size; + + U64 num_opcode_lens = opcode_base > 0 ? opcode_base - 1 : 0; + U8 *opcode_lens = str8_deserial_get_raw_ptr(unit_data, unit_cursor, num_opcode_lens * sizeof(opcode_lens[0])); + if (opcode_lens == 0) { + goto exit; + } + unit_cursor += num_opcode_lens * sizeof(opcode_lens[0]); + + DW_LineVMFileArray dir_table = {0}; + DW_LineVMFileArray file_table = {0}; + if (version < DW_Version_5) { + // read directory table + DW_LineVMFileList dir_list = {0}; + { + // compile directory is always first in the table + DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); + node->file.file_name = cu_dir; + SLLQueuePush(dir_list.first, dir_list.last, node); + ++dir_list.node_count; + } + + // parse additional directories + for (; unit_cursor < unit_data.size; ) { + String8 dir = {0}; + unit_cursor += str8_deserial_read_cstr(unit_data, unit_cursor, &dir); + if (dir.size == 0) { + break; + } + + DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); + node->file.file_name = dir; + SLLQueuePush(dir_list.first, dir_list.last, node); + ++dir_list.node_count; + } + + DW_LineVMFileList file_list = {0}; + { + // compile unit name is always first in the file table + { + DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); + node->file.file_name = cu_name; + SLLQueuePush(file_list.first, file_list.last, node); + ++file_list.node_count; + } + + // read file table + for (; unit_cursor < unit_data.size; ) { + String8 file_name = {0}; + unit_cursor += str8_deserial_read_cstr(unit_data, unit_cursor, &file_name); + if (file_name.size == 0) { + break; + } + + U64 dir_index = 0; + U64 dir_index_size = str8_deserial_read_uleb128(unit_data, unit_cursor, &dir_index); + if (dir_index_size == 0) { + goto exit; + } + unit_cursor += dir_index_size; + + U64 modify_time = 0; + U64 modify_time_size = str8_deserial_read_uleb128(unit_data, unit_cursor, &modify_time); + if (modify_time_size == 0) { + goto exit; + } + unit_cursor += modify_time_size; + + U64 file_size = 0; + U64 file_size_size = str8_deserial_read_uleb128(unit_data, unit_cursor, &file_size); + if (file_size_size == 0) { + goto exit; + } + unit_cursor += file_size_size; + + DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); + node->file.file_name = file_name; + node->file.dir_idx = dir_index; + node->file.modify_time = modify_time; + node->file.file_size = file_size; + + SLLQueuePush(file_list.first, file_list.last, node); + ++file_list.node_count; + } + } + + // list -> array + dir_table = dw_line_vm_file_array_from_list(arena, dir_list); + file_table = dw_line_vm_file_array_from_list(arena, file_list); + } + // DWARF5 + else { + // directory table + { + // read table entry encoding count + U8 enc_count = 0; + U64 enc_count_size = str8_deserial_read_struct(unit_data, unit_cursor, &enc_count); + if (enc_count_size == 0) { + goto exit; + } + unit_cursor += enc_count_size; + + // read table entry encodings + U64 *enc_arr = 0; + U64 enc_arr_size = str8_deserial_read_uleb128_array(scratch.arena, unit_data, unit_cursor, enc_count*2, &enc_arr); + if (enc_arr_size == 0) { + goto exit; + } + unit_cursor += enc_arr_size; + + // read table count + U64 table_count = 0; + U64 table_count_size = str8_deserial_read_uleb128(unit_data, unit_cursor, &table_count); + if (table_count_size == 0) { + goto exit; + } + unit_cursor += table_count_size; + + // read table + U64 table_size = dw_read_line_file_array(arena, + unit_data, + unit_cursor, + input, + version, + format, + DW_Ext_All, + address_size, + cu_str_offsets, + enc_count, + enc_arr, + table_count, + &dir_table); + if (table_size == 0) { + goto exit; + } + unit_cursor += table_size; + } + + // file table + { + // read table entry encoding count + U8 enc_count = 0; + U64 enc_count_size = str8_deserial_read_struct(unit_data, unit_cursor, &enc_count); + if (enc_count == 0) { + goto exit; + } + unit_cursor += enc_count_size; + + // read table entry encodings + U64 *enc_arr = 0; + U64 enc_arr_size = str8_deserial_read_uleb128_array(scratch.arena, unit_data, unit_cursor, enc_count*2, &enc_arr); + if (enc_arr_size == 0) { + goto exit; + } + unit_cursor += enc_arr_size; + + // read table count + U64 table_count = 0; + U64 table_count_size = str8_deserial_read_uleb128(unit_data, unit_cursor, &table_count); + if (table_count_size == 0) { + goto exit; + } + unit_cursor += table_count_size; + + // read table + U64 file_table_size = dw_read_line_file_array(arena, + unit_data, + unit_cursor, + input, + version, + format, + DW_Ext_All, + address_size, + cu_str_offsets, + enc_count, + enc_arr, + table_count, + &file_table); + if (file_table_size == 0) { + goto exit; + } + unit_cursor += file_table_size; + } + } + + if (header_out) { + header_out->unit_range = unit_range; + header_out->version = version; + header_out->address_size = address_size; + header_out->segment_selector_size = segsel_size; + header_out->header_length = header_length; + header_out->min_inst_len = min_inst_len; + header_out->max_ops_for_inst = max_ops_for_inst; + header_out->default_is_stmt = default_is_stmt; + header_out->line_base = line_base; + header_out->line_range = line_range; + header_out->opcode_base = opcode_base; + header_out->num_opcode_lens = num_opcode_lens; + header_out->opcode_lens = opcode_lens; + header_out->dir_table = dir_table; + header_out->file_table = file_table; + } + + bytes_read = unit_cursor; + +exit:; + scratch_end(scratch); + return bytes_read; +} internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt) @@ -1775,286 +2745,44 @@ dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl) internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence) { - DW_LineNode *n = 0; - if(vm_state->busted_seq == 0) + DW_LineSeqNode *seq = tbl->last_seq; + if(seq == 0 || start_of_sequence) { - DW_LineSeqNode *seq = tbl->last_seq; - if(seq == 0 || start_of_sequence) - { - // ERROR! do not emit sequences with only one line... - Assert(seq && seq->count > 1); - seq = dw_push_line_seq(arena, tbl); - } - - n = push_array(arena, DW_LineNode, 1); - n->v.file_index = vm_state->file_index; - n->v.line = vm_state->line; - n->v.column = vm_state->column; - n->v.voff = vm_state->address; - - SLLQueuePush(seq->first, seq->last, n); - seq->count += 1; + seq = dw_push_line_seq(arena, tbl); } + + DW_LineNode *n = push_array(arena, DW_LineNode, 1); + n->v.file_index = vm_state->file_index; + n->v.line = vm_state->line; + n->v.column = vm_state->column; + n->v.address = vm_state->address; + + SLLQueuePush(seq->first, seq->last, n); + seq->count += 1; return n; } -internal DW_LineTableParseResult -dw_parsed_line_table_from_comp_root(Arena *arena, DW_SectionArray *sections, DW_CompRoot *root) -{ - DW_Mode mode = sections->v[DW_Section_Line].mode; - void *base = dw_base_from_sec(sections, DW_Section_Line); - Rng1U64 line_info_range = dw_range_from_sec(sections, DW_Section_Line); - U64 read_off_start = root->line_off - line_info_range.min; - U64 cursor = read_off_start; - - DW_AttribValueResolveParams resolve_params = dw_attrib_value_resolve_params_from_comp_root(root); - - DW_LineVMHeader vm_header = {0}; - cursor += dw_read_line_vm_header(arena, base, line_info_range, cursor, mode, sections, resolve_params, root->compile_dir, root->name, &vm_header); - - //- rjf: prep state for VM - DW_LineVMState vm_state = {0}; - dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); - - //- rjf: VM loop; build output list - DW_LineTableParseResult result = {0}; - B32 end_of_seq = 0; - B32 error = 0; - for (;!error && cursor < vm_header.unit_opl;) { - //- rjf: parse opcode - U8 opcode = 0; - cursor += dw_based_range_read_struct(base, line_info_range, cursor, &opcode); - - //- rjf: do opcode action - switch (opcode) { - default: - { - //- rjf: special opcode case - if(opcode >= vm_header.opcode_base) - { - U32 adjusted_opcode = (U32)(opcode - vm_header.opcode_base); - U32 op_advance = adjusted_opcode / vm_header.line_range; - S32 line_inc = (S32)vm_header.line_base + ((S32)adjusted_opcode) % (S32)vm_header.line_range; - // TODO: can we just call dw_advance_line_vm_state_pc - U64 addr_inc = vm_header.min_inst_len * ((vm_state.op_index+op_advance) / vm_header.max_ops_for_inst); - - vm_state.address += addr_inc; - vm_state.op_index = (vm_state.op_index + op_advance) % vm_header.max_ops_for_inst; - vm_state.line = (U32)((S32)vm_state.line + line_inc); - vm_state.basic_block = 0; - vm_state.prologue_end = 0; - vm_state.epilogue_begin = 0; - vm_state.discriminator = 0; - - dw_push_line(arena, &result, &vm_state, end_of_seq); - end_of_seq = 0; - -#if 0 - // NOTE(rjf): DWARF has dummy lines at the end of groups of line ranges, where we'd like - // to break line info into sequences. - if(vm_state.line == 0) - { - end_of_seq = 1; - } -#endif - } - // Skipping unknown opcode. This is a valid case and - // it works because compiler stores operand lengths. - else - { - if(opcode > 0 && opcode <= vm_header.num_opcode_lens) - { - U8 num_operands = vm_header.opcode_lens[opcode - 1]; - for(U8 i = 0; i < num_operands; ++i) - { - U64 operand = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &operand); - } - } - else - { - error = 1; - goto exit; - } - } - } break; - - //- Standard opcodes - - case DW_StdOpcode_Copy: - { - dw_push_line(arena, &result, &vm_state, end_of_seq); - end_of_seq = 0; - vm_state.discriminator = 0; - vm_state.basic_block = 0; - vm_state.prologue_end = 0; - vm_state.epilogue_begin = 0; - } break; - - case DW_StdOpcode_AdvancePc: - { - U64 advance = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &advance); - dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - } break; - - case DW_StdOpcode_AdvanceLine: - { - S64 s = 0; - cursor += dw_based_range_read_sleb128(base, line_info_range, cursor, &s); - vm_state.line += s; - } break; - - case DW_StdOpcode_SetFile: - { - U64 file_index = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &file_index); - vm_state.file_index = file_index; - } break; - - case DW_StdOpcode_SetColumn: - { - U64 column = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &column); - vm_state.column = column; - } break; - - case DW_StdOpcode_NegateStmt: - { - vm_state.is_stmt = !vm_state.is_stmt; - } break; - - case DW_StdOpcode_SetBasicBlock: - { - vm_state.basic_block = 1; - } break; - - case DW_StdOpcode_ConstAddPc: - { - U64 advance = (0xffu - vm_header.opcode_base)/vm_header.line_range; - dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - } break; - - case DW_StdOpcode_FixedAdvancePc: - { - U16 operand = 0; - cursor += dw_based_range_read_struct(base, line_info_range, cursor, &operand); - vm_state.address += operand; - vm_state.op_index = 0; - } break; - - case DW_StdOpcode_SetPrologueEnd: - { - vm_state.prologue_end = 1; - } break; - - case DW_StdOpcode_SetEpilogueBegin: - { - vm_state.epilogue_begin = 1; - } break; - - case DW_StdOpcode_SetIsa: - { - U64 v = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &v); - vm_state.isa = v; - } break; - - //- Extended opcodes - case DW_StdOpcode_ExtendedOpcode: - { - U64 length = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &length); - U64 start_off = cursor; - U8 extended_opcode = 0; - cursor += dw_based_range_read_struct(base, line_info_range, cursor, &extended_opcode); - - switch (extended_opcode) { - case DW_ExtOpcode_EndSequence: - { - vm_state.end_sequence = 1; - dw_push_line(arena, &result, &vm_state, 0); - dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); - end_of_seq = 1; - } break; - - case DW_ExtOpcode_SetAddress: - { - U64 address = 0; - cursor += dw_based_range_read(base, line_info_range, cursor, root->address_size, &address); - vm_state.address = address; - vm_state.op_index = 0; - vm_state.busted_seq = address != 0; // !(dbg->acceptable_vrange.min <= address && address < dbg->acceptable_vrange.max); - } break; - - case DW_ExtOpcode_DefineFile: - { - String8 file_name = dw_based_range_read_string(base, line_info_range, cursor); - U64 dir_index = 0; - U64 modify_time = 0; - U64 file_size = 0; - cursor += file_name.size + 1; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &dir_index); - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &modify_time); - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &file_size); - - // TODO(rjf): Not fully implemented. By the DWARF V4 spec, the above is - // all that needs to be parsed, but the rest of the work that needs to - // happen here---allowing this file to be used by further opcodes---is - // not implemented. - // - // See the DWARF V4 spec (June 10, 2010), page 122. - error = 1; - AssertAlways(!"UNHANDLED DEFINE FILE!!!"); - } break; - - case DW_ExtOpcode_SetDiscriminator: - { - U64 v = 0; - cursor += dw_based_range_read_uleb128(base, line_info_range, cursor, &v); - vm_state.discriminator = v; - } break; - - default: break; - } - - U64 num_skip = cursor - (start_off + length); - cursor += num_skip; - if (dw_based_range_ptr(base, line_info_range, cursor) == 0 || start_off + length > cursor) { - error = 1; - } - - } break; - } - } - exit:; - - return result; -} - internal String8 -dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx) +dw_path_from_file(Arena *arena, DW_LineVMHeader *vm, DW_LineFile *file) { Temp scratch = scratch_begin(&arena, 1); - - DW_LineFile *lf = &vm->file_table.v[file_idx]; - String8 dir = vm->dir_table.v[lf->dir_idx]; + String8 dir = vm->dir_table.v[file->dir_idx].file_name; PathStyle style = path_style_from_str8(dir); if (style == PathStyle_Null || style == PathStyle_Relative) { - style = path_style_from_str8(lf->file_name); + style = path_style_from_str8(file->file_name); } String8List path_list = {0}; if (str8_match_lit("..", dir, StringMatchFlag_RightSideSloppy)) { - String8List comp_dir_list = str8_split_path(scratch.arena, vm->dir_table.v[0]); + String8List comp_dir_list = str8_split_path(scratch.arena, vm->dir_table.v[0].file_name); str8_list_concat_in_place(&path_list, &comp_dir_list); } String8List dir_list = str8_split_path(scratch.arena, dir); str8_list_concat_in_place(&path_list, &dir_list); - str8_list_push(scratch.arena, &path_list, lf->file_name); + str8_list_push(scratch.arena, &path_list, file->file_name); str8_path_list_resolve_dots_in_place(&path_list, style); @@ -2064,299 +2792,298 @@ dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx) return path; } -internal U64 -dw_read_line_file(void *line_base, - Rng1U64 line_rng, - U64 line_off, - DW_Mode mode, - DW_SectionArray *sections, - DW_AttribValueResolveParams resolve_params, - U8 address_size, - U64 format_count, - Rng1U64 *formats, - DW_LineFile *line_file_out) +internal String8 +dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx) { - MemoryZeroStruct(line_file_out); + return dw_path_from_file(arena, vm, &vm->file_table.v[file_idx]); +} + +internal DW_LineTableParseResult +dw_parsed_line_table_from_data(Arena *arena, + String8 unit_data, + DW_Input *input, + String8 cu_dir, + String8 cu_name, + U8 cu_address_size, + DW_ListUnit *cu_str_offsets) +{ + DW_LineVMHeader vm_header = {0}; + U64 vm_header_size = dw_read_line_vm_header(arena, unit_data, 0, input, cu_dir, cu_name, cu_address_size, cu_str_offsets, &vm_header); + + U64 unit_cursor = vm_header_size; - U64 line_off_start = line_off; - for (U64 format_idx = 0; format_idx < format_count; ++format_idx) - { - DW_LNCT lnct = (DW_LNCT)formats[format_idx].min; - DW_FormKind form_kind = (DW_FormKind)formats[format_idx].max; - DW_AttribValue form_value = {0}; - line_off += dw_based_range_read_attrib_form_value(line_base, line_rng, line_off, mode, address_size, form_kind, 0, &form_value); - switch (lnct) - { - case DW_LNCT_Path: + //- rjf: prep state for VM + DW_LineVMState vm_state = {0}; + dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); + + //- rjf: VM loop; build output list + DW_LineTableParseResult result = { .vm_header = vm_header }; + B32 end_of_seq = 0; + B32 error = 0; + for (; !error && unit_cursor < unit_data.size; ) { + //- rjf: parse opcode + U8 opcode = 0; + unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &opcode); + + //- rjf: do opcode action + switch (opcode) { + default: { + //- rjf: special opcode case + if (opcode >= vm_header.opcode_base) { + U32 adjusted_opcode = (U32)(opcode - vm_header.opcode_base); + U32 op_advance = adjusted_opcode / vm_header.line_range; + S32 line_inc = (S32)vm_header.line_base + ((S32)adjusted_opcode) % (S32)vm_header.line_range; + // TODO: can we just call dw_advance_line_vm_state_pc + U64 addr_inc = vm_header.min_inst_len * ((vm_state.op_index+op_advance) / vm_header.max_ops_for_inst); + + vm_state.address += addr_inc; + vm_state.op_index = (vm_state.op_index + op_advance) % vm_header.max_ops_for_inst; + vm_state.line = (U32)((S32)vm_state.line + line_inc); + vm_state.basic_block = 0; + vm_state.prologue_end = 0; + vm_state.epilogue_begin = 0; + vm_state.discriminator = 0; + + if(vm_state.is_stmt) + { + dw_push_line(arena, &result, &vm_state, end_of_seq); + } + end_of_seq = 0; + +#if 0 + // NOTE(rjf): DWARF has dummy lines at the end of groups of line ranges, where we'd like + // to break line info into sequences. + if(vm_state.line == 0) + { + end_of_seq = 1; + } +#endif + } + // Skipping unknown opcode. This is a valid case and + // it works because compiler stores operand lengths. + else { + if (0 < opcode && opcode <= vm_header.num_opcode_lens) { + U8 num_operands = vm_header.opcode_lens[opcode - 1]; + for (U8 i = 0; i < num_operands; ++i) { + U64 operand = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &operand); + } + } else { + error = 1; + goto exit; + } + } + } break; + + //- Standard opcodes + + case DW_StdOpcode_Copy: { + if(vm_state.is_stmt) { - Assert(form_kind == DW_Form_String || form_kind == DW_Form_LineStrp || - form_kind == DW_Form_Strp || form_kind == DW_Form_StrpSup || - form_kind == DW_Form_Strx || form_kind == DW_Form_Strx1 || - form_kind == DW_Form_Strx2 || form_kind == DW_Form_Strx3 || - form_kind == DW_Form_Strx4); - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, form_kind, DW_AttribClass_String, form_value); - line_file_out->file_name = dw_string_from_attrib_value(sections, attrib_value); + dw_push_line(arena, &result, &vm_state, end_of_seq); + } + end_of_seq = 0; + vm_state.discriminator = 0; + vm_state.basic_block = 0; + vm_state.prologue_end = 0; + vm_state.epilogue_begin = 0; + } break; + + case DW_StdOpcode_AdvancePc: { + U64 advance = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &advance); + dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); + } break; + + case DW_StdOpcode_AdvanceLine: { + S64 s = 0; + unit_cursor += str8_deserial_read_sleb128(unit_data, unit_cursor, &s); + vm_state.line += s; + } break; + + case DW_StdOpcode_SetFile: { + U64 file_index = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &file_index); + vm_state.file_index = file_index; + } break; + + case DW_StdOpcode_SetColumn: { + U64 column = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &column); + vm_state.column = column; + } break; + + case DW_StdOpcode_NegateStmt: { + vm_state.is_stmt = !vm_state.is_stmt; + } break; + + case DW_StdOpcode_SetBasicBlock: { + vm_state.basic_block = 1; + } break; + + case DW_StdOpcode_ConstAddPc: { + U64 advance = (0xffu - vm_header.opcode_base) / vm_header.line_range; + dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); + } break; + + case DW_StdOpcode_FixedAdvancePc: { + U16 operand = 0; + unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &operand); + vm_state.address += operand; + vm_state.op_index = 0; + } break; + + case DW_StdOpcode_SetPrologueEnd: { + vm_state.prologue_end = 1; + } break; + + case DW_StdOpcode_SetEpilogueBegin: { + vm_state.epilogue_begin = 1; + } break; + + case DW_StdOpcode_SetIsa: { + U64 v = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &v); + vm_state.isa = v; + } break; + + //- Extended opcodes + case DW_StdOpcode_ExtendedOpcode: { + U64 length = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &length); + + U64 extended_opl = unit_cursor + length; + U8 extended_opcode = 0; + unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &extended_opcode); + + switch (extended_opcode) { + case DW_ExtOpcode_EndSequence: { + vm_state.end_sequence = 1; + if(vm_state.is_stmt) + { + dw_push_line(arena, &result, &vm_state, 0); + } + dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); + end_of_seq = 1; } break; - case DW_LNCT_DirectoryIndex: - { - Assert(form_kind == DW_Form_Data1 || form_kind == DW_Form_Data2 || - form_kind == DW_Form_UData); - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, form_kind, DW_AttribClass_Block, form_value); - line_file_out->dir_idx = attrib_value.v[0]; + case DW_ExtOpcode_SetAddress: { + U64 address = 0; + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, vm_header.address_size, vm_header.address_size); + vm_state.address = address; + vm_state.op_index = 0; } break; - case DW_LNCT_TimeStamp: - { - Assert(form_kind == DW_Form_UData || form_kind == DW_Form_Data4 || - form_kind == DW_Form_Data8 || form_kind == DW_Form_Block); - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, form_kind, DW_AttribClass_Const, form_value); - line_file_out->modify_time = attrib_value.v[0]; + case DW_ExtOpcode_DefineFile: { + String8 file_name = {0}; + U64 dir_index = 0; + U64 modify_time = 0; + U64 file_size = 0; + + unit_cursor += str8_deserial_read_cstr(unit_data, unit_cursor, &file_name); + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &dir_index); + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &modify_time); + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &file_size); + + // TODO(rjf): Not fully implemented. By the DWARF V4 spec, the above is + // all that needs to be parsed, but the rest of the work that needs to + // happen here---allowing this file to be used by further opcodes---is + // not implemented. + // + // See the DWARF V4 spec (June 10, 2010), page 122. + error = 1; + AssertAlways(!"UNHANDLED DEFINE FILE!!!"); } break; - case DW_LNCT_Size: - { - Assert(form_kind == DW_Form_UData || form_kind == DW_Form_Data1 || - form_kind == DW_Form_Data2 || form_kind == DW_Form_Data4 || - form_kind == DW_Form_Data8); - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, form_kind, DW_AttribClass_Block, form_value); - line_file_out->file_size = attrib_value.v[0]; + case DW_ExtOpcode_SetDiscriminator: { + U64 v = 0; + unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &v); + vm_state.discriminator = v; } break; - case DW_LNCT_MD5: - { - Assert(form_kind == DW_Form_Data16); - DW_AttribValue attrib_value = dw_attrib_value_from_form_value(sections, resolve_params, form_kind, DW_AttribClass_Block, form_value); - line_file_out->md5_digest[0] = attrib_value.v[0]; - line_file_out->md5_digest[1] = attrib_value.v[1]; - } break; + default: break; + } - default: - { - Assert(DW_LNCT_UserLo < lnct && lnct < DW_LNCT_UserHi); - } break; + unit_cursor = extended_opl; + } break; } } - U64 result = line_off - line_off_start; + + exit:; + return result; } -internal U64 -dw_read_line_vm_header(Arena *arena, - void *line_base, - Rng1U64 line_rng, - U64 line_off, - DW_Mode mode, - DW_SectionArray *sections, - DW_AttribValueResolveParams resolve_params, - String8 compile_dir, - String8 unit_name, - DW_LineVMHeader *header_out) +internal DW_PubStringsTable +dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind) { Temp scratch = scratch_begin(&arena, 1); - MemoryZeroStruct(header_out); + DW_PubStringsTable names_table = {0}; + names_table.size = 16384; + names_table.buckets = push_array(arena, DW_PubStringsBucket*, names_table.size); - //- rjf: parse unit length - U64 unit_length = 0; - U64 unit_length_size = dw_based_range_read_length(line_base, line_rng, line_off, &unit_length); - - header_out->unit_length = unit_length; - header_out->unit_opl = line_off + unit_length + unit_length_size; + String8 section_data = input->sec[section_kind].data; + for(U64 cursor = 0; cursor < section_data.size; ) { - U64 cursor = unit_length_size; - Rng1U64 parse_rng = rng_1u64(line_off, header_out->unit_opl); + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(section_data, cursor, &unit_length); + if (unit_length_size == 0) { + break; + } + cursor += unit_length_size; - //- rjf: parse version and header length - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->version); - - if(header_out->version == DW_Version_5) - { - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->address_size); - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->segment_selector_size); - } - - cursor += dw_based_range_read(line_base, parse_rng, cursor, dw_offset_size_from_mode(mode), &header_out->header_length); - - //- rjf: calculate program offset - header_out->program_off = parse_rng.min + cursor + header_out->header_length; - - //- rjf: parse minimum instruction length - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->min_inst_len); - - //- rjf: parse max ops for instruction - switch(header_out->version) - { - case DW_Version_5: - case DW_Version_4: - { - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->max_ops_for_inst); - Assert(header_out->max_ops_for_inst > 0); - } break; - case DW_Version_3: - case DW_Version_2: - case DW_Version_1: - { - header_out->max_ops_for_inst = 1; - } break; - default: break; - } - - //- rjf: parse rest of program info - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->default_is_stmt); - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->line_base); - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->line_range); - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &header_out->opcode_base); - - //- rjf: calculate opcode length array - header_out->num_opcode_lens = header_out->opcode_base > 0 ? header_out->opcode_base - 1u : 0; - header_out->opcode_lens = dw_based_range_ptr_size(line_base, parse_rng, cursor, header_out->num_opcode_lens * sizeof(header_out->opcode_lens[0])); - cursor += header_out->num_opcode_lens * sizeof(header_out->opcode_lens[0]); - - if(header_out->version == DW_Version_5) - { - //- parse directory names - U8 directory_entry_format_count = 0; - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &directory_entry_format_count); - Assert(directory_entry_format_count == 1); - Rng1U64 *directory_entry_formats = push_array(scratch.arena, Rng1U64, directory_entry_format_count); - for(U8 format_idx = 0; format_idx < directory_entry_format_count; ++format_idx) - { - U64 content_type_code = 0, form_code = 0; - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &content_type_code); - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &form_code); - directory_entry_formats[format_idx] = rng_1u64(content_type_code, form_code); + U64 cursor_opl = Min(cursor + unit_length, section_data.size); + if (cursor >= cursor_opl) { + break; } - U64 directories_count = 0; - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &directories_count); - header_out->dir_table.count = directories_count; - header_out->dir_table.v = push_array(arena, String8, header_out->dir_table.count); - for(U64 dir_idx = 0; dir_idx < directories_count; ++dir_idx) - { - DW_LineFile line_file; - cursor += dw_read_line_file(line_base, - parse_rng, - cursor, - mode, - sections, - resolve_params, - header_out->address_size, - directory_entry_format_count, - directory_entry_formats, - &line_file); - header_out->dir_table.v[dir_idx] = push_str8_copy(arena, line_file.file_name); + DW_Version unit_version = 0; + cursor += str8_deserial_read_struct(section_data, cursor, &unit_version); + if (cursor >= cursor_opl) { + break; } - //- parse file table - U8 file_name_entry_format_count = 0; - cursor += dw_based_range_read_struct(line_base, parse_rng, cursor, &file_name_entry_format_count); - Rng1U64 *file_name_entry_formats = push_array(scratch.arena, Rng1U64, file_name_entry_format_count); - for(U8 format_idx = 0; format_idx < file_name_entry_format_count; ++format_idx) - { - U64 content_type_code = 0, form_code = 0; - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &content_type_code); - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &form_code); - file_name_entry_formats[format_idx] = rng_1u64(content_type_code, form_code); + DW_Format format = DW_FormatFromSize(unit_length); + + U64 debug_info_off = 0; + cursor += str8_deserial_read_dwarf_uint(section_data, cursor, format, &debug_info_off); + if (cursor >= cursor_opl) { + break; } - U64 file_names_count = 0; - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &file_names_count); - header_out->file_table.count = file_names_count; - header_out->file_table.v = push_array(arena, DW_LineFile, header_out->file_table.count); - for(U64 file_idx = 0; file_idx < file_names_count; ++file_idx) - { - cursor += dw_read_line_file(line_base, - parse_rng, - cursor, - mode, - sections, - resolve_params, - header_out->address_size, - file_name_entry_format_count, - file_name_entry_formats, - &header_out->file_table.v[file_idx]); + U64 debug_info_length = 0; + cursor += str8_deserial_read_dwarf_packed_size(section_data, cursor, &debug_info_length); + if (cursor >= cursor_opl) { + break; } - } - else - { - String8List dir_list = {0}; - str8_list_push(scratch.arena, &dir_list, compile_dir); - for (;;) - { - String8 dir = dw_based_range_read_string(line_base, parse_rng, cursor); - cursor += dir.size + 1; - if (dir.size == 0) - { + + U64 off_size = dw_size_from_format(format); + for (; (cursor + off_size) <= cursor_opl;) { + U64 info_off = 0; + U64 info_off_size = str8_deserial_read_dwarf_uint(section_data, cursor, format, &info_off); + cursor += info_off_size; + + if (info_off_size == 0 || info_off == 0) { break; } - str8_list_push(scratch.arena, &dir_list, dir); - } - - DW_LineVMFileList file_list = {0}; - - //- rjf: push 0-index file (compile file) - { - DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); - node->file.file_name = unit_name; - SLLQueuePush(file_list.first, file_list.last, node); - file_list.node_count += 1; - } - - for(;;) - { - String8 file_name = dw_based_range_read_string(line_base, parse_rng, cursor); - U64 dir_index = 0; - U64 modify_time = 0; - U64 file_size = 0; - cursor += file_name.size + 1; - if(file_name.size == 0) - { - break; - } - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &dir_index); - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &modify_time); - cursor += dw_based_range_read_uleb128(line_base, parse_rng, cursor, &file_size); - DW_LineVMFileNode *node = push_array(scratch.arena, DW_LineVMFileNode, 1); - node->file.file_name = file_name; - node->file.dir_idx = dir_index; - node->file.modify_time = modify_time; - node->file.file_size = file_size; - SLLQueuePush(file_list.first, file_list.last, node); - file_list.node_count += 1; - } - - //- rjf: build dir table - { - header_out->dir_table.count = dir_list.node_count; - header_out->dir_table.v = push_array(arena, String8, header_out->dir_table.count); + String8 string = {0}; + cursor += str8_deserial_read_cstr(section_data, cursor, &string); - String8Node *n = dir_list.first; - for(U64 idx = 0; n != 0 && idx < header_out->dir_table.count; idx += 1, n = n->next) - { - header_out->dir_table.v[idx] = push_str8_copy(arena, n->string); - } - } - - //- rjf: build file table - { - header_out->file_table.count = file_list.node_count; - header_out->file_table.v = push_array(arena, DW_LineFile, header_out->file_table.count); - - U64 file_idx = 0; - DW_LineVMFileNode *file_node = file_list.first; - for(; file_node != 0; file_idx += 1, file_node = file_node->next) - { - header_out->file_table.v[file_idx].file_name = push_str8_copy(arena, file_node->file.file_name); - header_out->file_table.v[file_idx].dir_idx = file_node->file.dir_idx; - header_out->file_table.v[file_idx].modify_time = file_node->file.modify_time; - header_out->file_table.v[file_idx].file_size = file_node->file.file_size; - } + U64 hash = dw_hash_from_string(string); + U64 bucket_idx = hash % names_table.size; + + DW_PubStringsBucket *bucket = push_array(arena, DW_PubStringsBucket, 1); + bucket->next = names_table.buckets[bucket_idx]; + bucket->string = string; + bucket->info_off = info_off; + bucket->cu_info_off = debug_info_off; + names_table.buckets[bucket_idx] = bucket; } } - + scratch_end(scratch); - return cursor; + return names_table; } diff --git a/src/dwarf/dwarf_parse.h b/src/dwarf/dwarf_parse.h index 6cce84b8..99a589d6 100644 --- a/src/dwarf/dwarf_parse.h +++ b/src/dwarf/dwarf_parse.h @@ -4,38 +4,49 @@ #ifndef DWARF_PARSE_H #define DWARF_PARSE_H -// NOTE(rjf): Some rules about the spaces of offsets and ranges: -// -// - Every stored/passed offset is relative to the base of its section. -// - Every stored/passed range has endpoints relative to the base of their section. -// - Upon calling a syms_based_range_* function, these offsets need to be -// converted into range-relative. - -//////////////////////////////// -//~ rjf: Constants - -#define DWARF_VOID_TYPE_ID 0xffffffffffffffffull - -//////////////////////////////// -//~ rjf: Files + External Debug References - -typedef struct DW_ExtDebugRef DW_ExtDebugRef; -struct DW_ExtDebugRef +typedef struct DW_Section { - // NOTE(rjf): .dwo => an external DWARF V5 .dwo file - String8 dwo_path; - U64 dwo_id; -}; + String8 name; + String8 data; + B32 is_dwo; +} DW_Section; -//////////////////////////////// -//~ rjf: Abbrev Table +typedef struct DW_Input +{ + DW_Section sec[DW_Section_Count]; + DW_Section sup[DW_Section_Count]; +} DW_Input; -typedef struct DW_AbbrevTableEntry DW_AbbrevTableEntry; -struct DW_AbbrevTableEntry +typedef struct DW_ListUnit +{ + DW_Version version; + U64 address_size; + U64 segment_selector_size; + U64 entry_size; + String8 entries; +} DW_ListUnit; + +typedef struct DW_ListUnitInput +{ + U64 addr_count; + U64 str_offset_count; + U64 rnglist_count; + U64 loclist_count; + Rng1U64Array addr_ranges; + Rng1U64Array str_offset_ranges; + Rng1U64Array rnglist_ranges; + Rng1U64Array loclist_ranges; + DW_ListUnit *addrs; + DW_ListUnit *str_offsets; + DW_ListUnit *rnglists; + DW_ListUnit *loclists; +} DW_ListUnitInput; + +typedef struct DW_AbbrevTableEntry { U64 id; U64 off; -}; +} DW_AbbrevTableEntry; typedef struct DW_AbbrevTable DW_AbbrevTable; struct DW_AbbrevTable @@ -44,62 +55,6 @@ struct DW_AbbrevTable DW_AbbrevTableEntry *entries; }; -//////////////////////////////// -//~ Sections - -typedef struct DW_Section DW_Section; -struct DW_Section -{ - String8 name; - String8 data; - DW_Mode mode; - B32 is_dwo; -}; - -typedef struct DW_SectionArray DW_SectionArray; -struct DW_SectionArray -{ - DW_Section v[DW_Section_Count]; -}; - -//////////////////////////////// -//~ rjf: Basic Line Info - -typedef struct DW_LineFile DW_LineFile; -struct DW_LineFile -{ - String8 file_name; - U64 dir_idx; - U64 modify_time; - U64 md5_digest[2]; - U64 file_size; -}; - -typedef struct DW_LineVMFileNode DW_LineVMFileNode; -struct DW_LineVMFileNode -{ - DW_LineVMFileNode *next; - DW_LineFile file; -}; - -typedef struct DW_LineVMFileList DW_LineVMFileList; -struct DW_LineVMFileList -{ - U64 node_count; - DW_LineVMFileNode *first; - DW_LineVMFileNode *last; -}; - -typedef struct DW_LineVMFileArray DW_LineVMFileArray; -struct DW_LineVMFileArray -{ - U64 count; - DW_LineFile *v; -}; - -//////////////////////////////// -//~ rjf: Abbrevs - typedef enum DW_AbbrevKind { DW_Abbrev_Null, @@ -108,215 +63,169 @@ typedef enum DW_AbbrevKind DW_Abbrev_AttribSequenceEnd, DW_Abbrev_DIEBegin, DW_Abbrev_DIEEnd, -} -DW_AbbrevKind; +} DW_AbbrevKind; typedef U32 DW_AbbrevFlags; -enum{ - DW_AbbrevFlag_HasImplicitConst = (1<<0), - DW_AbbrevFlag_HasChildren = (1<<1), +enum +{ + DW_AbbrevFlag_HasImplicitConst = (1 << 0), + DW_AbbrevFlag_HasChildren = (1 << 1), }; -typedef struct DW_Abbrev DW_Abbrev; -struct DW_Abbrev +typedef struct DW_Abbrev { DW_AbbrevKind kind; - Rng1U64 abbrev_range; U64 sub_kind; U64 id; U64 const_value; DW_AbbrevFlags flags; -}; +} DW_Abbrev; -//////////////////////////////// -//~ rjf: Attribs - -typedef struct DW_AttribValueResolveParams DW_AttribValueResolveParams; -struct DW_AttribValueResolveParams +typedef union DW_Form { - DW_Version version; - DW_Language language; - U64 addr_size; // NOTE(rjf): size in bytes of containing compilation unit's addresses - U64 containing_unit_info_off; // NOTE(rjf): containing compilation unit's offset into the .debug_info section - U64 debug_addrs_base; // NOTE(rjf): containing compilation unit's offset into the .debug_addrs section (DWARF V5 ONLY) - U64 debug_rnglists_base; // NOTE(rjf): containing compilation unit's offset into the .debug_rnglists section (DWARF V5 ONLY) - U64 debug_str_offs_base; // NOTE(rjf): containing compilation unit's offset into the .debug_str_offsets section (DWARF V5 ONLY) - U64 debug_loclists_base; // NOTE(rjf): containing compilation unit's offset into the .debug_loclists section (DWARF V5 ONLY) -}; + String8 addr; + String8 block; + String8 data; + String8 string; + String8 exprloc; + B8 flag; + S64 sdata; + U64 udata; + U64 sec_offset; + U64 ref; + U64 strp_sup; + U64 xval; + U64 addrx; + U64 strx; + U64 rnglistx; + U64 ptr; + U64 implicit_const; +} DW_Form; -typedef struct DW_AttribValue DW_AttribValue; -struct DW_AttribValue -{ - DW_SectionKind section; - U64 v[2]; -}; - -typedef struct DW_Attrib DW_Attrib; -struct DW_Attrib +typedef struct DW_Attrib { U64 info_off; + U64 abbrev_off; U64 abbrev_id; DW_AttribKind attrib_kind; DW_FormKind form_kind; - DW_AttribClass value_class; - DW_AttribValue form_value; -}; + DW_Form form; +} DW_Attrib; -typedef struct DW_AttribArray DW_AttribArray; -struct DW_AttribArray +typedef struct DW_AttribNode { - DW_Attrib *v; - U64 count; -}; + struct DW_AttribNode *next; + DW_Attrib v; +} DW_AttribNode; -typedef struct DW_AttribNode DW_AttribNode; -struct DW_AttribNode -{ - DW_AttribNode *next; - DW_Attrib attrib; -}; - -typedef struct DW_AttribList DW_AttribList; -struct DW_AttribList +typedef struct DW_AttribList { DW_AttribNode *first; DW_AttribNode *last; U64 count; -}; +} DW_AttribList; -typedef struct DW_AttribListParseResult DW_AttribListParseResult; -struct DW_AttribListParseResult +typedef struct DW_Tag { - DW_AttribList attribs; - U64 max_info_off; - U64 max_abbrev_off; -}; - -//////////////////////////////// -//~ rjf: Compilation Units + Accelerators - -typedef struct DW_CompRoot DW_CompRoot; -struct DW_CompRoot -{ - // NOTE(rjf): Header Data - U64 size; - DW_CompUnitKind kind; - DW_Version version; - U64 address_size; - U64 abbrev_off; - U64 info_off; - Rng1U64 tags_info_range; - DW_AbbrevTable abbrev_table; - - // NOTE(rjf): [parsed from DWARF attributes] Offsets For More Info (DWARF V5 ONLY) - U64 rnglist_base; // NOTE(rjf): Offset into the .debug_rnglists section where this comp unit's data is. - U64 loclist_base; // NOTE(rjf): Offset into the .debug_loclists section where this comp unit's data is. - U64 addrs_base; // NOTE(rjf): Offset into the .debug_addr section where this comp unit's data is. - U64 stroffs_base; // NOTE(rjf): Offset into the .debug_str_offsets section where this comp unit's data is. - - // NOTE(rjf): [parsed from DWARF attributes] General Info - String8 name; - String8 producer; - String8 compile_dir; - String8 external_dwo_name; - U64 dwo_id; - DW_Language language; - U64 name_case; - B32 use_utf8; - U64 line_off; - U64 low_pc; - U64 high_pc; - DW_AttribValue ranges_attrib_value; - U64 base_addr; -}; - -//////////////////////////////// -//~ rjf: Tags - -typedef struct DW_Tag DW_Tag; -struct DW_Tag -{ - DW_Tag *next_sibling; - DW_Tag *first_child; - DW_Tag *last_child; - DW_Tag *parent; - Rng1U64 info_range; - Rng1U64 abbrev_range; B32 has_children; U64 abbrev_id; DW_TagKind kind; - U64 attribs_info_off; - U64 attribs_abbrev_off; DW_AttribList attribs; -}; + U64 info_off; +} DW_Tag; -typedef U32 DW_TagStubFlags; -enum +typedef struct DW_TagNode { - DW_TagStubFlag_HasObjectPointerArg = (1<<0), - DW_TagStubFlag_HasLocation = (1<<1), - DW_TagStubFlag_HasExternal = (1<<2), - DW_TagStubFlag_HasSpecification = (1<<3), -}; + DW_Tag tag; + struct DW_TagNode *sibling; + struct DW_TagNode *first_child; + struct DW_TagNode *last_child; +} DW_TagNode; -typedef struct DW_TagStub DW_TagStub; -struct DW_TagStub +typedef struct DW_Loc { - U64 info_off; - DW_TagKind kind; - DW_TagStubFlags flags; - U64 children_info_off; - U64 attribs_info_off; - U64 attribs_abbrev_off; - - // NOTE(rjf): DW_Attrib_Specification is tacked onto definitions that - // are filling out more info about a "prototype". That attribute is a reference - // that points back at the declaration tag. The declaration tag has the - // DW_Attrib_Declaration attribute, which is sort of like the reverse - // of that, except there's no reference. So what we're doing here is just storing - // a reference on both, that point back to each other, so it's always easy to - // get from decl => spec, or from spec => decl. - //SYMS_SymbolID ref; - - // NOTE(rjf): DW_Attrib_AbstractOrigin is tacked onto some definitions - // that are used to specify information more specific to inlining, while wanting - // to refer to an "abstract" function DIE, that is not specific to any inline - // sites. The DWARF generator will not duplicate information across these, so - // we will occasionally need to look at an abstract origin to get abstract - // information, like name/linkage-name/etc. - //SYMS_SymbolID abstract_origin; - - U64 _unused_; -}; + Rng1U64 range; + String8 expr; +} DW_Loc; -typedef struct DW_TagStubNode DW_TagStubNode; -struct DW_TagStubNode +typedef struct DW_LocNode { - DW_TagStubNode *next; - DW_TagStub stub; -}; + DW_Loc v; + struct DW_LocNode *next; +} DW_LocNode; -typedef struct DW_TagStubList DW_TagStubList; -struct DW_TagStubList +typedef struct DW_LocList { - DW_TagStubNode *first; - DW_TagStubNode *last; - U64 count; -}; + U64 count; + DW_LocNode *first; + DW_LocNode *last; +} DW_LocList; -//////////////////////////////// -//~ rjf: Line Info VM Types - -typedef struct DW_LineVMHeader DW_LineVMHeader; -struct DW_LineVMHeader +typedef struct DW_CompUnit { - U64 unit_length; - U64 unit_opl; + B32 relaxed; + DW_Ext ext; + DW_CompUnitKind kind; + DW_Version version; + DW_Format format; + U64 address_size; + U64 abbrev_off; + Rng1U64 info_range; + U64 first_tag_info_off; + DW_AbbrevTable abbrev_table; + String8 abbrev_data; + DW_ListUnit *addr_lu; + DW_ListUnit *str_offsets_lu; + DW_ListUnit *rnglists_lu; + DW_ListUnit *loclists_lu; + U64 low_pc; + U64 dwo_id; + DW_Tag tag; + HashTable *tag_ht; +} DW_CompUnit; + +typedef struct DW_TagTree +{ + DW_TagNode *root; + U64 tag_count; +} DW_TagTree; + +typedef struct DW_LineFile +{ + String8 file_name; + U64 dir_idx; + U64 modify_time; + U64 file_size; + U128 md5_digest; + String8 source; +} DW_LineFile; + +typedef struct DW_LineVMFileNode +{ + struct DW_LineVMFileNode *next; + DW_LineFile file; +} DW_LineVMFileNode; + +typedef struct DW_LineVMFileList +{ + U64 node_count; + DW_LineVMFileNode *first; + DW_LineVMFileNode *last; +} DW_LineVMFileList; + +typedef struct DW_LineVMFileArray +{ + U64 count; + DW_LineFile *v; +} DW_LineVMFileArray; + +typedef struct DW_LineVMHeader +{ + Rng1U64 unit_range; DW_Version version; U8 address_size; // Duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str. U8 segment_selector_size; U64 header_length; - U64 program_off; U8 min_inst_len; U8 max_ops_for_inst; U8 default_is_stmt; @@ -325,12 +234,11 @@ struct DW_LineVMHeader U8 opcode_base; U64 num_opcode_lens; U8 *opcode_lens; - String8Array dir_table; + DW_LineVMFileArray dir_table; DW_LineVMFileArray file_table; -}; +} DW_LineVMHeader; -typedef struct DW_LineVMState DW_LineVMState; -struct DW_LineVMState +typedef struct DW_LineVMState { U64 address; // Address of a machine instruction. U32 op_index; // This is used by the VLIW instructions to indicate index of operation inside the instruction. @@ -351,144 +259,195 @@ struct DW_LineVMState // prepare stack for a function. B32 prologue_end; - B32 epilogue_begin; // NOTE(nick): Indicates that "address" points to section where function exits and unwinds stack. - U64 isa; // NOTE(nick): Instruction set that is used. - U64 discriminator; // NOTE(nick): Arbitrary id that indicates to which block these instructions belong. - B32 end_sequence; // NOTE(nick): Indicates that "address" points to the first instruction in the instruction block that follows. - - // NOTE(rjf): it looks like LTO might sometimes zero out high PC and low PCs, causing a - // swath of line info to map to a range starting at 0. This causes overlapping ranges - // which we do not want to report. So this B32 will turn on emission. - B32 busted_seq; -}; + B32 epilogue_begin; // Indicates that "address" points to section where function exits and unwinds stack. + U64 isa; // Instruction set that is used. + U64 discriminator; // Arbitrary id that indicates to which block these instructions belong. + B32 end_sequence; // Indicates that "address" points to the first instruction in the instruction block that follows. +} DW_LineVMState; -typedef struct DW_Line DW_Line; -struct DW_Line +typedef struct DW_Line { U64 file_index; U32 line; U32 column; - U64 voff; -}; + U64 address; +} DW_Line; -typedef struct DW_LineNode DW_LineNode; -struct DW_LineNode +typedef struct DW_LineNode { - DW_LineNode *next; - DW_Line v; -}; + struct DW_LineNode *next; + DW_Line v; +} DW_LineNode; -typedef struct DW_LineSeqNode DW_LineSeqNode; -struct DW_LineSeqNode +typedef struct DW_LineSeqNode { - DW_LineSeqNode *next; - U64 count; - DW_LineNode *first; - DW_LineNode *last; -}; + struct DW_LineSeqNode *next; + U64 count; + DW_LineNode *first; + DW_LineNode *last; +} DW_LineSeqNode; -typedef struct DW_LineTableParseResult DW_LineTableParseResult; -struct DW_LineTableParseResult +typedef struct DW_LineTableParseResult { + DW_LineVMHeader vm_header; U64 seq_count; DW_LineSeqNode *first_seq; DW_LineSeqNode *last_seq; -}; +} DW_LineTableParseResult; //////////////////////////////// -//~ rjf: .debug_pubnames and .debug_pubtypes +// .debug_pubnames and .debug_pubtypes -typedef struct DW_PubStringsBucket DW_PubStringsBucket; -struct DW_PubStringsBucket +typedef struct DW_PubStringsBucket { - DW_PubStringsBucket *next; - String8 string; - U64 info_off; - U64 cu_info_off; -}; + struct DW_PubStringsBucket *next; + String8 string; + U64 info_off; + U64 cu_info_off; +} DW_PubStringsBucket; -typedef struct DW_PubStringsTable DW_PubStringsTable; -struct DW_PubStringsTable +typedef struct DW_PubStringsTable { - U64 size; + U64 size; DW_PubStringsBucket **buckets; -}; +} DW_PubStringsTable; -//////////////////////////////// -//~ rjf: Basic Helpers +typedef struct DW_Reference +{ + DW_CompUnit *cu; + U64 info_off; +} DW_Reference; + +// hasher internal U64 dw_hash_from_string(String8 string); -//////////////////////////////// -//~ Specific Based Range Helpers +// deserial helpers -#define dw_based_range_read_struct(base, range, offset, out) dw_based_range_read(base, range, offset, sizeof(*out), out) +internal U64 str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out); +internal U64 str8_deserial_read_dwarf_uint (String8 string, U64 off, DW_Format format, U64 *uint_out); +internal U64 str8_deserial_read_uleb128 (String8 string, U64 off, U64 *value_out); +internal U64 str8_deserial_read_sleb128 (String8 string, U64 off, S64 *value_out); +internal U64 str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out); +internal U64 str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out); -internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 offset, U64 size, void *out); -internal String8 dw_based_range_read_string(void *base, Rng1U64 range, U64 offset); -internal void* dw_based_range_ptr(void *base, Rng1U64 range, U64 offset); -internal void* dw_based_range_ptr_size(void *base, Rng1U64 range, U64 offset, U64 size); -internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 offset, U64 *out_value); -internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_value); -internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value); -internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev); -internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev); -internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out); +internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data); -internal DW_Mode dw_mode_from_sec(DW_SectionArray *sections, DW_SectionKind kind); -internal B32 dw_sec_is_present(DW_SectionArray *sections, DW_SectionKind kind); -internal void* dw_base_from_sec(DW_SectionArray *sections, DW_SectionKind kind); -internal Rng1U64 dw_range_from_sec(DW_SectionArray *sections, DW_SectionKind kind); +// list units -//////////////////////////////// -//~ rjf: Abbrev Table +internal U64 dw_read_list_unit_header_addr (String8 unit_data, DW_ListUnit *lu_out); +internal U64 dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out); +internal U64 dw_read_list_unit_header_list (String8 unit_data, DW_ListUnit *lu_out); -internal DW_AbbrevTable dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 start_abbrev_off); +internal DW_ListUnitInput dw_list_unit_input_from_input(Arena *arena, DW_Input *input); + +internal U64 dw_offset_from_list_unit(DW_ListUnit *lu, U64 index); +internal U64 dw_addr_from_list_unit (DW_ListUnit *lu, U64 index); + +// abbrev table + +internal U64 dw_read_abbrev_tag (String8 data, U64 offset, DW_Abbrev *out_abbrev); +internal U64 dw_read_abbrev_attrib(String8 data, U64 offset, DW_Abbrev *out_abbrev); +internal DW_AbbrevTable dw_make_abbrev_table(Arena *arena, String8 abbrev_data, U64 start_abbrev_off); internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U64 abbrev_id); -//////////////////////////////// -//~ rjf: Miscellaneous DWARF Section Parsing +// form and tag -//- rjf: .debug_ranges (DWARF V4) -internal Rng1U64List dw_v4_range_list_from_range_offset(Arena *arena, DW_SectionArray *sections, U64 addr_size, U64 comp_unit_base_addr, U64 range_off); +internal U64 dw_read_form(String8 data, U64 off, DW_Version version, DW_Format unit_format, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_Form *form_out); +internal U64 dw_read_tag (Arena *arena, String8 tag_data, U64 tag_off, U64 tag_base, DW_AbbrevTable abbrev_table, String8 abbrev_data, DW_Version version, DW_Format unit_format, U64 address_size, DW_Tag *tag_out); +internal U64 dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out); -//- rjf: .debug_pubtypes + .debug_pubnames (DWARF V4) -internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_SectionArray *sections, DW_SectionKind section_kind); +// attrib interp -//- rjf: .debug_str_offsets (DWARF V5) -internal U64 dw_v5_offset_from_offs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index); +internal U64 dw_interp_sec_offset(DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_exprloc (DW_FormKind form_kind, DW_Form form); +internal U128 dw_interp_const_u128(DW_FormKind form_kind, DW_Form form); +internal U64 dw_interp_const_u64 (DW_FormKind form_kind, DW_Form form); +internal U32 dw_interp_const_u32 (DW_FormKind form_kind, DW_Form form); +internal S64 dw_interp_const_s64 (DW_FormKind form_kind, DW_Form form); +internal S32 dw_interp_const_s32 (DW_FormKind form_kind, DW_Form form); +internal B32 dw_interp_flag (DW_FormKind form_kind, DW_Form form); +internal U64 dw_interp_address (U64 address_size, U64 base_addr, DW_ListUnit *addr_xlist, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_block (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_string (DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_line_ptr (DW_Input *input, DW_FormKind form_kind, DW_Form form); +internal DW_LineFile * dw_interp_file (DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form); +internal DW_Reference dw_interp_ref (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal DW_LocList dw_interp_loclist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); -//- rjf: .debug_addr (DWARF V5) -internal U64 dw_v5_addr_from_addrs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index); +internal String8 dw_exprloc_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U128 dw_const_u128_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U64 dw_const_u64_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U32 dw_const_u32_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal S64 dw_const_s64_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal S32 dw_const_s32_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal B32 dw_flag_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U64 dw_address_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_block_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_string_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_line_ptr_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal DW_LineFile * dw_file_from_attrib_ptr (DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib); +internal DW_Reference dw_ref_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal DW_LocList dw_loclist_from_attrib_ptr (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal Rng1U64List dw_rnglist_from_attrib_ptr (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); -//- rjf: .debug_rnglists parsing (DWARF V5) -internal U64 dw_v5_sec_offset_from_rnglist_or_loclist_section_base_index(DW_SectionArray *sections, DW_SectionKind section_kind, U64 base, U64 index); -internal Rng1U64List dw_v5_range_list_from_rnglist_offset(Arena *arena, DW_SectionArray *sections, DW_SectionKind section, U64 addr_size, U64 addr_section_base, U64 offset); +internal String8 dw_exprloc_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U128 dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U64 dw_const_u64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U32 dw_const_u32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal B32 dw_flag_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U64 dw_address_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_block_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_string_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal DW_LineFile * dw_file_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind); +internal DW_Reference dw_ref_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -//////////////////////////////// -//~ rjf: Attrib Value Parsing +// compile unit -internal DW_AttribValueResolveParams dw_attrib_value_resolve_params_from_comp_root(DW_CompRoot *root); -internal DW_AttribValue dw_attrib_value_from_form_value(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_FormKind form_kind, DW_AttribClass value_class, DW_AttribValue form_value); -internal String8 dw_string_from_attrib_value(DW_SectionArray *sections, DW_AttribValue value); -internal Rng1U64List dw_range_list_from_high_low_pc_and_ranges_attrib_value(Arena *arena, DW_SectionArray *sections, U64 address_size, U64 comp_unit_base_addr, U64 addr_section_base, U64 low_pc, U64 high_pc, DW_AttribValue ranges_value); +internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed); +internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu); +internal HashTable * dw_make_tag_hash_table(Arena *arena, DW_TagTree tag_tree); +internal DW_TagNode * dw_tag_node_from_info_off(DW_CompUnit *cu, U64 info_off); -//////////////////////////////// -//~ rjf: Tag Parsing +// line info -internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off, B32 relaxed); -internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset, B32 relaxed); -internal DW_TagStub dw_stub_from_tag(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_Tag *tag); +internal U64 dw_read_line_file(String8 line_data, + U64 line_off, + DW_Input *input, + DW_Version unit_version, + DW_Format unit_format, + DW_Ext ext, + U64 address_size, + DW_ListUnit *str_offsets, + U64 enc_count, + U64 *enc_arr, + DW_LineFile *line_file_out); +internal U64 dw_read_line_vm_header(Arena *arena, + String8 line_data, + U64 line_off, + DW_Input *input, + String8 cu_dir, + String8 cu_name, + U8 cu_address_size, + DW_ListUnit *cu_str_offsets, + DW_LineVMHeader *header_out); -//- rjf: line info -internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt); -internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst); +internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt); +internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst); +internal DW_LineSeqNode * dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl); +internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence); +internal String8 dw_path_from_file(Arena *arena, DW_LineVMHeader *vm, DW_LineFile *file); +internal String8 dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx); -internal DW_LineSeqNode* dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl); -internal DW_LineNode* dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence); -internal DW_LineTableParseResult dw_parsed_line_table_from_comp_root(Arena *arena, DW_SectionArray *sections, DW_CompRoot *root); -internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out); -internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, String8 compile_dir, String8 unit_name, DW_LineVMHeader *header_out); +internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets); + +// helper for .debug_pubtypes and .debug_pubnames + +internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind); #endif // DWARF_PARSE_H - diff --git a/src/dwarf/dwarf_unwind.c b/src/dwarf/dwarf_unwind.c index 4ca39ce9..84931716 100644 --- a/src/dwarf/dwarf_unwind.c +++ b/src/dwarf/dwarf_unwind.c @@ -410,6 +410,8 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx * internal void dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off, DW_CIEUnpacked *cie_out) { + NotImplemented; +#if 0 MemoryZeroStruct(cie_out); // get version @@ -521,6 +523,7 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off cie_out->cfi_range.min = cfi_off; cie_out->cfi_range.max = cfi_off + cfi_size; } +#endif } internal void diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index 219ac87c..ae70ab2a 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -187,6 +187,13 @@ hash_table_search_u64(HashTable *ht, U64 key_u64) return 0; } +internal void * +hash_table_search_u64_raw(HashTable *ht, U64 key_u64) +{ + KeyValuePair *kv = hash_table_search_u64(ht, key_u64); + return kv ? kv->value_raw : 0; +} + internal KeyValuePair * hash_table_search_path(HashTable *ht, String8 path) { diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index bfb70be2..3d4dcba8 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -1,894 +1,1917 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: Build Options - -#define BUILD_TITLE "rdi_from_dwarf" -#define BUILD_CONSOLE_INTERFACE 1 - -//////////////////////////////// -//~ rjf: Includes - -//- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format.c" -#include "third_party/rad_lzb_simple/rad_lzb_simple.h" -#include "third_party/rad_lzb_simple/rad_lzb_simple.c" - -//- rjf: [h] -#include "base/base_inc.h" -#include "os/os_inc.h" -#include "rdi_make/rdi_make_local.h" -#include "rdi_elf.h" -#include "rdi_dwarf.h" -#include "rdi_dwarf_stringize.h" -#include "rdi_from_dwarf.h" - -//- rjf: [c] -#include "base/base_inc.c" -#include "os/os_inc.c" -#include "rdi_make/rdi_make_local.c" -#include "rdi_elf.c" -#include "rdi_dwarf.c" -#include "rdi_dwarf_stringize.c" - -// TODO(allen): -// [ ] need sample data for .debug_names - -//////////////////////////////// -//~ Program Parameters Parser - -static DWARFCONV_Params* -dwarf_convert_params_from_cmd_line(Arena *arena, CmdLine *cmdline){ - DWARFCONV_Params *result = push_array(arena, DWARFCONV_Params, 1); - result->unit_idx_max = ~0ull; - - // get input pdb - { - String8 input_name = cmd_line_string(cmdline, str8_lit("elf")); - if (input_name.size == 0){ - str8_list_push(arena, &result->errors, - str8_lit("missing required parameter '--elf:'")); - } - - if (input_name.size > 0){ - String8 input_data = os_data_from_file_path(arena, input_name); - - if (input_data.size == 0){ - str8_list_pushf(arena, &result->errors, - "could not load input file '%.*s'", str8_varg(input_name)); - } - - if (input_data.size != 0){ - result->input_elf_name = input_name; - result->input_elf_data = input_data; - } - } - } - - // get output name - { - result->output_name = cmd_line_string(cmdline, str8_lit("out")); - } - - // error options - if (cmd_line_has_flag(cmdline, str8_lit("hide_errors"))){ - String8List vals = cmd_line_strings(cmdline, str8_lit("hide_errors")); - - // if no values - set all to hidden - if (vals.node_count == 0){ - B8 *ptr = (B8*)&result->hide_errors; - B8 *opl = ptr + sizeof(result->hide_errors); - for (;ptr < opl; ptr += 1){ - *ptr = 1; - } - } - - // for each explicit value set the corresponding flag to hidden - for (String8Node *node = vals.first; - node != 0; - node = node->next){ - if (str8_match(node->string, str8_lit("input"), 0)){ - result->hide_errors.input = 1; - } - } - - } - - // unit idx selector - if (cmd_line_has_flag(cmdline, str8_lit("unit_idx"))){ - String8List vals = cmd_line_strings(cmdline, str8_lit("unit_idx")); - - // single value unit index - if (vals.node_count == 1){ - U64 idx = u64_from_str8(vals.first->string, 10); - result->unit_idx_min = idx; - result->unit_idx_max = idx; - } - - // range value unit index - else if (vals.node_count >= 2){ - U64 idx_a = u64_from_str8(vals.first->string, 10); - U64 idx_b = u64_from_str8(vals.first->next->string, 10); - result->unit_idx_min = Min(idx_a, idx_b); - result->unit_idx_max = Max(idx_a, idx_b); - } - } - - // dump options - if (cmd_line_has_flag(cmdline, str8_lit("dump"))){ - result->dump = 1; - - String8List vals = cmd_line_strings(cmdline, str8_lit("dump")); - if (vals.first == 0){ - B8 *ptr = &result->dump__first; - for (; ptr < &result->dump__last; ptr += 1){ - *ptr = 1; - } - } - else{ - for (String8Node *node = vals.first; - node != 0; - node = node->next){ - if (str8_match(node->string, str8_lit("header"), 0)){ - result->dump_header = 1; - } - else if (str8_match(node->string, str8_lit("sections"), 0)){ - result->dump_sections = 1; - } - else if (str8_match(node->string, str8_lit("segments"), 0)){ - result->dump_segments = 1; - } - else if (str8_match(node->string, str8_lit("symtab"), 0)){ - result->dump_symtab = 1; - } - else if (str8_match(node->string, str8_lit("dynsym"), 0)){ - result->dump_dynsym = 1; - } - else if (str8_match(node->string, str8_lit("debug_sections"), 0)){ - result->dump_debug_sections = 1; - } - else if (str8_match(node->string, str8_lit("debug_info"), 0)){ - result->dump_debug_info = 1; - } - else if (str8_match(node->string, str8_lit("debug_abbrev"), 0)){ - result->dump_debug_abbrev = 1; - } - else if (str8_match(node->string, str8_lit("debug_pubnames"), 0)){ - result->dump_debug_pubnames = 1; - } - else if (str8_match(node->string, str8_lit("debug_pubtypes"), 0)){ - result->dump_debug_pubtypes = 1; - } - else if (str8_match(node->string, str8_lit("debug_names"), 0)){ - result->dump_debug_names = 1; - } - else if (str8_match(node->string, str8_lit("debug_aranges"), 0)){ - result->dump_debug_aranges = 1; - } - else if (str8_match(node->string, str8_lit("debug_addr"), 0)){ - result->dump_debug_addr = 1; - } - } - } - } - - return(result); -} - -//////////////////////////////// -//~ Entry Point - -static void -dump_symtab(Arena *arena, String8List *out, ELF_SymArray *symbols, String8 strtab, - U32 indent){ - static char spaces[] = " "; - - U8 *str_first = strtab.str; - U8 *str_opl = strtab.str + strtab.size; - - ELF_Sym64 *symbol = symbols->symbols; - U64 count = symbols->count; - for (U64 i = 0; i < count; i += 1, symbol += 1){ - U8 *name_first = str_first + symbol->st_name; - U8 *name_opl = name_first; - for (;name_opl < str_opl && *name_opl != 0;) name_opl += 1; - String8 name = str8_range(name_first, name_opl); - - ELF_SymbolBinding binding = ELF_SymBindingFromInfo(symbol->st_info); - String8 binding_string = elf_string_from_symbol_binding(binding); - - ELF_SymbolType type = ELF_SymTypeFromInfo(symbol->st_info); - String8 type_string = elf_string_from_symbol_type(type); - - ELF_SymbolVisibility vis = ELF_SymVisibilityFromOther(symbol->st_other); - String8 vis_string = elf_string_from_symbol_visibility(vis); - - str8_list_pushf(arena, out, - "%.*ssymbol[%5llu] %6.*s %7.*s %9.*s 0x%08llx size=%-5llu sec=%-5u " - "%.*s\n", - indent, spaces, i, - str8_varg(binding_string), str8_varg(type_string), - str8_varg(vis_string), - symbol->st_value, symbol->st_size, - symbol->st_shndx, str8_varg(name)); - } -} - -#if 0 -static void -dump_entry_tree(Arena *arena, String8List *out, - DWARF_Parsed *dwarf, DWARF_InfoUnit *unit, - DWARF_InfoEntry *entry, U32 indent){ - static char spaces[] = " "; - - DWARF_AbbrevDecl *abbrev_decl = entry->abbrev_decl; - - // tag - DWARF_Tag tag = abbrev_decl->tag; - String8 tag_string = dwarf_string_from_tag(tag); - str8_list_pushf(arena, out, "%.*sentry(@%llx) TAG %.*s\n", - indent, spaces, entry->info_offset, str8_varg(tag_string)); - - // attributes - U32 attrib_count = abbrev_decl->attrib_count; - DWARF_AbbrevAttribSpec *attrib_spec = abbrev_decl->attrib_specs; - DWARF_InfoAttribVal *attrib_val = entry->attrib_vals; - for (U32 i = 0; i < attrib_count; i += 1, attrib_spec += 1, attrib_val += 1){ - // attribute name - DWARF_AttributeName name = attrib_spec->name; - String8 name_string = dwarf_string_from_attribute_name(name); - str8_list_pushf(arena, out, "%.*sATTR %.*s ", indent + 4, spaces, str8_varg(name_string)); - - // attribute value - switch (attrib_spec->form){ - default: - { - String8 form_string = dwarf_string_from_attribute_form(attrib_spec->form); - str8_list_pushf(arena, out, " {%llu, 0x%p}\n", - str8_varg(form_string), attrib_val->val, attrib_val->dataptr); - }break; - - case DWARF_AttributeForm_strp: - { - String8 str = {0}; - - String8 data = dwarf->debug_data[DWARF_SectionCode_Str]; - U64 off = attrib_val->val; - if (off < data.size){ - U8 *start = data.str + off; - U8 *opl = data.str + data.size; - U8 *ptr = start; - for (;ptr < opl && *ptr != 0;) ptr += 1; - str = str8_range(start, ptr); - } - - str8_list_pushf(arena, out, "'%.*s'\n", str8_varg(str)); - }break; - - case DWARF_AttributeForm_sec_offset: - { - DWARF_AttributeClassFlags attr_classes1 = dwarf_attribute_class_from_name(name); - DWARF_AttributeClassFlags attr_classes2 = DWARF_AttributeClassFlag_sec_offset_classes; - DWARF_AttributeClassFlags attr_classes = attr_classes1&attr_classes2; - - DWARF_SectionCode sec_code = DWARF_SectionCode_Null; - if (unit->dwarf_version == 5){ - switch (attr_classes){ - case DWARF_AttributeClassFlag_addrptr: sec_code = DWARF_SectionCode_Addr; break; - case DWARF_AttributeClassFlag_lineptr: sec_code = DWARF_SectionCode_Line; break; - case DWARF_AttributeClassFlag_loclist: sec_code = DWARF_SectionCode_LocLists; break; - case DWARF_AttributeClassFlag_loclistsptr: sec_code = DWARF_SectionCode_LocLists; break; - case DWARF_AttributeClassFlag_macptr: sec_code = DWARF_SectionCode_Macro; break; - case DWARF_AttributeClassFlag_rnglist: sec_code = DWARF_SectionCode_RngLists; break; - case DWARF_AttributeClassFlag_rnglistsptr: sec_code = DWARF_SectionCode_RngLists; break; - case DWARF_AttributeClassFlag_stroffsetsptr: sec_code = DWARF_SectionCode_StrOffsets; break; - } - } - else if (unit->dwarf_version == 4){ - switch (attr_classes){ - case DWARF_AttributeClassFlag_lineptr: sec_code = DWARF_SectionCode_Line; break; - case DWARF_AttributeClassFlag_loclist: sec_code = DWARF_SectionCode_Loc; break; - case DWARF_AttributeClassFlag_macptr: sec_code = DWARF_SectionCode_MacInfo; break; - case DWARF_AttributeClassFlag_rnglist: sec_code = DWARF_SectionCode_Ranges; break; - } - } - - String8 sec_name = dwarf_name_from_debug_section(dwarf, sec_code); - str8_list_pushf(arena, out, "sec(%.*s) + %llu\n", str8_varg(sec_name), attrib_val->val); - }break; - - case DWARF_AttributeForm_ref1: - case DWARF_AttributeForm_ref2: - case DWARF_AttributeForm_ref4: - case DWARF_AttributeForm_ref8: - case DWARF_AttributeForm_ref_udata: - { - str8_list_pushf(arena, out, "entry(@%llx)\n", attrib_val->val); - }break; - - case DWARF_AttributeForm_addr: - { - str8_list_pushf(arena, out, "0x%llx\n", attrib_val->val); - }break; - - case DWARF_AttributeForm_exprloc: - { - str8_list_pushf(arena, out, "expression\n"); - // TODO(allen): dwarf expression dumping - }break; - - case DWARF_AttributeForm_strx1: - case DWARF_AttributeForm_strx2: - case DWARF_AttributeForm_strx3: - case DWARF_AttributeForm_strx4: - { - String8 str = {0}; - - U32 idx = attrib_val->val; - U64 str_offsets_off = unit->str_offsets_base + idx*unit->offset_size; - - String8 str_offsets = dwarf->debug_data[DWARF_SectionCode_StrOffsets]; - if (str_offsets_off + unit->offset_size < str_offsets.size){ - U64 off = 0; - MemoryCopy(&off, str_offsets.str + str_offsets_off, unit->offset_size); - - String8 data = dwarf->debug_data[DWARF_SectionCode_Str]; - if (off < data.size){ - U8 *start = data.str + off; - U8 *opl = data.str + data.size; - U8 *ptr = start; - for (;ptr < opl && *ptr != 0;) ptr += 1; - str = str8_range(start, ptr); - } - } - - str8_list_pushf(arena, out, "'%.*s'\n", str8_varg(str)); - }break; - - case DWARF_AttributeForm_addrx: - case DWARF_AttributeForm_addrx1: - case DWARF_AttributeForm_addrx2: - case DWARF_AttributeForm_addrx3: - case DWARF_AttributeForm_addrx4: - { - U64 address = 0; - - U32 idx = attrib_val->val; - U64 address_off = unit->addr_base + idx*unit->address_size; - - String8 data = dwarf->debug_data[DWARF_SectionCode_Addr]; - if (address_off + unit->address_size < data.size){ - MemoryCopy(&address, data.str + address_off, unit->address_size); - } - - str8_list_pushf(arena, out, "0x%x\n", address); - }break; - - case DWARF_AttributeForm_rnglistx: - { - U64 rnglist_off = unit->rnglists_base + attrib_val->val; - int x = 0; - }break; - - case DWARF_AttributeForm_data1: - case DWARF_AttributeForm_data2: - case DWARF_AttributeForm_data4: - case DWARF_AttributeForm_data8: - case DWARF_AttributeForm_data16: - case DWARF_AttributeForm_udata: - case DWARF_AttributeForm_implicit_const: - case DWARF_AttributeForm_flag: - case DWARF_AttributeForm_flag_present: - { - str8_list_pushf(arena, out, "%llu\n", attrib_val->val); - }break; - - case DWARF_AttributeForm_sdata: - { - str8_list_pushf(arena, out, "%lld\n", (S64)attrib_val->val); - }break; - - case DWARF_AttributeForm_string: - { - str8_list_pushf(arena, out, "'%.*s'\n", (int)attrib_val->val, attrib_val->dataptr); - }break; - } - } - - // dump children - for (DWARF_InfoEntry *child = entry->first_child; - child != 0; - child = child->next_sibling){ - dump_entry_tree(arena, out, dwarf, unit, child, indent + 1); - } -} -#endif - -internal void -entry_point(CmdLine *cmd_line) +internal D2R_User2Convert * +d2r_user2convert_from_cmdln(Arena *arena, CmdLine *cmdline) { - Arena *arena = arena_alloc(); - - // parse arguments - DWARFCONV_Params *params = dwarf_convert_params_from_cmd_line(arena, cmd_line); - - // show input errors - if (params->errors.node_count > 0 && - !params->hide_errors.input){ - for (String8Node *node = params->errors.first; - node != 0; - node = node->next){ - fprintf(stdout, "error(input): %.*s\n", str8_varg(node->string)); + D2R_User2Convert *result = push_array(arena, D2R_User2Convert, 1); + + String8 exe_name = cmd_line_string(cmdline, str8_lit("exe")); + String8 debug_name = cmd_line_string(cmdline, str8_lit("debug")); + String8 out_name = cmd_line_string(cmdline, str8_lit("out")); + + // error check params + if (exe_name.size == 0 && debug_name.size == 0) { + str8_list_pushf(arena, &result->errors, "Missing one of the required parameters: '--exe:' or '--debug:'"); + } + if (out_name.size == 0) { + str8_list_pushf(arena, &result->errors, "Missing required parameter: '--out:'"); + } + + // get input EXE or ELF + if (exe_name.size > 0) { + String8 exe_data = os_data_from_file_path(arena, exe_name); + if (exe_data.size == 0) { + str8_list_pushf(arena, &result->errors, "Could not load input EXE file from '%S'", exe_name); + } else { + result->input_exe_name = exe_name; + result->input_exe_data = exe_data; } } - - // will we try to parse an input file? - B32 try_parse_input = (params->errors.node_count == 0); - - // track parse success - B32 successful_parse = 1; - -#define PARSE_CHECK_ERROR(p, fmt, ...) do{ if ((p) == 0){ \ -successful_parse = 0; \ -fprintf(stdout, "error(parsing): " fmt "\n",##__VA_ARGS__); \ -} }while(0) - - // parse elf - ELF_Parsed *elf = 0; - if (try_parse_input) ProfScope("parse elf"){ - elf = elf_parsed_from_data(arena, params->input_elf_data); - PARSE_CHECK_ERROR(elf, "ELF"); - } - - // parse strtab - String8 strtab = {0}; - if (elf != 0) ProfScope("parse strtab"){ - strtab = elf_section_data_from_idx(elf, elf->strtab_idx); - } - - // parse symtab - ELF_SymArray symtab = {0}; - if (elf != 0) ProfScope("parse symtab"){ - String8 data = elf_section_data_from_idx(elf, elf->symtab_idx); - symtab = elf_sym_array_from_data(arena, elf->elf_class, data); - } - - // parse dynsym - ELF_SymArray dynsym = {0}; - if (elf != 0) ProfScope("parse dynsym"){ - String8 data = elf_section_data_from_idx(elf, elf->dynsym_idx); - dynsym = elf_sym_array_from_data(arena, elf->elf_class, data); - } - - // parse dwarf - DWARF_Parsed *dwarf = 0; - if (elf != 0) ProfScope("parse dwarf"){ - dwarf = dwarf_parsed_from_elf(arena, elf); - PARSE_CHECK_ERROR(dwarf, "DWARF"); - } - - // parse info - DWARF_InfoParsed *info = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Info]; - if (data.size > 0) ProfScope("parse .debug_info"){ - info = dwarf_info_from_data(arena, data); - PARSE_CHECK_ERROR(info, "DEBUG INFO"); + + // get input DEBUG + if (debug_name.size > 0) { + String8 debug_data = os_data_from_file_path(arena, debug_name); + if (debug_data.size == 0) { + str8_list_pushf(arena, &result->errors, "Could not load input DEBUG file from '%S'", debug_name); + } else { + result->input_debug_name = debug_name; + result->input_debug_data = debug_data; } } - - // parse pubnames - DWARF_PubNamesParsed *pubnames = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_PubNames]; - if (data.size) ProfScope("parse .debug_pubnames"){ - pubnames = dwarf_pubnames_from_data(arena, data); - PARSE_CHECK_ERROR(pubnames, "DEBUG PUBNAMES"); + + result->output_name = out_name; + result->flags = ~0ull; + + String8List only_names = cmd_line_strings(cmdline, str8_lit("only")); + String8List omit_names = cmd_line_strings(cmdline, str8_lit("omit")); + + if (only_names.node_count > 0) { + result->flags = 0; + for (String8Node *i = only_names.first; i != 0; i = i->next) { +#define X(t,n,k) if (str8_match_lit(Stringify(n), i->string, StringMatchFlag_CaseInsensitive)) \ + result->flags |= D2R_ConvertFlag_##t; + RDI_SectionKind_XList +#undef X } } - - // parse pubtypes - DWARF_PubNamesParsed *pubtypes = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_PubTypes]; - if (data.size) ProfScope("parse .debug_pubtypes"){ - pubtypes = dwarf_pubnames_from_data(arena, data); - PARSE_CHECK_ERROR(pubtypes, "DEBUG PUBTYPES"); + + if (omit_names.node_count > 0) { + for (String8Node *i = omit_names.first; i != 0; i = i->next) { +#define X(t,n,k) if (str8_match_lit(Stringify(n), i->string, StringMatchFlag_CaseInsensitive)) \ + result->flags &= ~D2R_ConvertFlag_##t; + RDI_SectionKind_XList +#undef X } } - - // parse names - DWARF_NamesParsed *names = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Names]; - if (data.size) ProfScope("parse .debug_names"){ - names = dwarf_names_from_data(arena, data); - PARSE_CHECK_ERROR(names, "DEBUG NAMES"); + + return result; +} + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code_x64(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return RDI_RegCodeX64_##reg_name_rdi; + DW_Regs_X64_XList(X) +#undef X + } + InvalidPath; + return 0; +} + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code_x86(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return RDI_RegCodeX86_##reg_name_rdi; + DW_Regs_X86_XList(X) +#undef X + } + InvalidPath; + return 0; +} + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code(RDI_Arch arch, U64 reg_code) +{ + switch (arch) { + case RDI_Arch_NULL: return 0; + case RDI_Arch_X64: return d2r_rdi_reg_from_dw_reg_code_x64(reg_code); + case RDI_Arch_X86: return d2r_rdi_reg_from_dw_reg_code_x86(reg_code); + } + InvalidPath; + return 0; +} + +internal RDIM_Type * +d2r_create_type(Arena *arena, D2R_TypeTable *type_table) +{ + RDIM_Type *type = rdim_type_chunk_list_push(arena, type_table->types, type_table->type_chunk_cap); + return type; +} + +internal RDIM_Type * +d2r_find_or_create_type_from_offset(Arena *arena, D2R_TypeTable *type_table, U64 info_off) +{ + RDIM_Type *type = 0; + KeyValuePair *is_type_present = hash_table_search_u64(type_table->ht, info_off); + if (is_type_present) { + type = is_type_present->value_raw; + } else { + type = d2r_create_type(arena, type_table); + hash_table_push_u64_raw(arena, type_table->ht, info_off, type); + } + return type; +} + +internal RDIM_Type * +d2r_type_from_attrib(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + RDIM_Type *type = 0; + + // find attrib + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + + // does tag have this attribute? + if (attrib->attrib_kind == kind) { + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + + if (value_class == DW_AttribClass_Reference) { + // resolve reference + DW_Reference ref = dw_ref_from_attrib_ptr(input, cu, attrib); + + // TODO: support for external compile unit references + AssertAlways(ref.cu == cu); + + // find or create type + type = d2r_find_or_create_type_from_offset(arena, type_table, ref.info_off); + } else { + Assert(!"unexpected attrib class"); + } + } else if (attrib->attrib_kind == DW_Attrib_Null) { + type = type_table->void_type; + } + + return type; +} + +internal Rng1U64List +d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag) +{ + // collect non-contiguous range + Rng1U64List ranges = dw_rnglist_from_attrib(arena, input, cu, tag, DW_Attrib_Ranges); + + // collect contiguous range + DW_Attrib *lo_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_LowPc); + DW_Attrib *hi_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_HighPc); + if (lo_pc_attrib->attrib_kind != DW_Attrib_Null && hi_pc_attrib->attrib_kind != DW_Attrib_Null) { + U64 lo_pc = dw_address_from_attrib_ptr(input, cu, lo_pc_attrib); + + U64 hi_pc; + DW_AttribClass hi_pc_class = dw_value_class_from_attrib(cu, hi_pc_attrib); + if (hi_pc_class == DW_AttribClass_Address) { + hi_pc = dw_address_from_attrib_ptr(input, cu, hi_pc_attrib); + } else if (hi_pc_class == DW_AttribClass_Const) { + hi_pc = dw_const_u64_from_attrib_ptr(input, cu, hi_pc_attrib); + hi_pc += lo_pc; + } else { + AssertAlways(!"undefined attrib encoding"); + } + + // TODO: error handling + AssertAlways(lo_pc >= image_base); + AssertAlways(hi_pc >= image_base); + AssertAlways(lo_pc <= hi_pc); + + U64 lo_voff = lo_pc - image_base; + U64 hi_voff = hi_pc - image_base; + rng1u64_list_push(arena, &ranges, rng_1u64(lo_voff, hi_voff)); + } + + return ranges; +} + +internal RDIM_Type ** +d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out) +{ + Temp scratch = scratch_begin(&arena, 1); + + RDIM_TypeList list = {0}; + B32 has_vargs = 0; + for (DW_TagNode *i = cur_node->first_child; i != 0; i = i->sibling) { + if (i->tag.kind == DW_Tag_FormalParameter) { + RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1); + n->v = d2r_type_from_attrib(arena, type_table, input, cu, i->tag, DW_Attrib_Type); + SLLQueuePush(list.first, list.last, n); + ++list.count; + } else if (i->tag.kind == DW_Tag_UnspecifiedParameters) { + has_vargs = 1; } } - - // parse aranges - DWARF_ArangesParsed *aranges = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Aranges]; - if (data.size) ProfScope("parse .debug_aranges"){ - aranges = dwarf_aranges_from_data(arena, data); - PARSE_CHECK_ERROR(aranges, "DEBUG ARANGES"); - } + + if (has_vargs) { + RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1); + n->v = type_table->varg_type; + SLLQueuePush(list.first, list.last, n); + ++list.count; } - - // parse addr - DWARF_AddrParsed *addr = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Addr]; - if (data.size) ProfScope("parse .debug_addr"){ - addr = dwarf_addr_from_data(arena, data); - PARSE_CHECK_ERROR(addr, "DEBUG ADDR"); - } - } - -#if 0 - // parse abbrev - DWARF_AbbrevParsed *abbrev = 0; - if (dwarf != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Abbrev]; - if (data.size > 0) ProfScope("parse .debug_abbrev"){ - DWARF_AbbrevParams abbrev_params = {0}; - abbrev_params.unit_idx_min = params->unit_idx_min; - abbrev_params.unit_idx_max = params->unit_idx_max; - abbrev = dwarf_abbrev_from_data(arena, data, &abbrev_params); - PARSE_CHECK_ERROR(abbrev, "DEBUG ABBREV"); - } - } - - // parse info - DWARF_InfoParsed *info = 0; - if (abbrev != 0){ - String8 data = dwarf->debug_data[DWARF_SectionCode_Info]; - if (data.size > 0) ProfScope("parse .debug_info"){ - DWARF_InfoParams info_params = {0}; - info_params.unit_idx_min = params->unit_idx_min; - info_params.unit_idx_max = params->unit_idx_max; - info = dwarf_info_from_data(arena, data, &info_params, abbrev); - PARSE_CHECK_ERROR(info, "DEBUG INFO"); - } - } -#endif - - // dump - if (params->dump) ProfScope("dump"){ - String8List dump = {0}; - - // ELF - if (params->dump_header){ - if (elf != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "ELF:\n")); - - // TODO: better stringizers for fields here - str8_list_pushf(arena, &dump, " elf_class=%u\n", elf->elf_class); - str8_list_pushf(arena, &dump, " arch=%u\n", elf->arch); - str8_list_pushf(arena, &dump, " section_count=%llu\n", elf->section_count); - str8_list_pushf(arena, &dump, " segment_count=%llu\n", elf->segment_count); - str8_list_pushf(arena, &dump, " vbase=0x%llx\n", elf->vbase); - str8_list_pushf(arena, &dump, " entry_vaddr=0x%llx\n", elf->vbase); - - str8_list_push(arena, &dump, str8_lit("\n")); + + // collect params + *param_count_out = list.count; + RDIM_Type **params = rdim_array_from_type_list(arena, list); + + scratch_end(scratch); + return params; +} + + +internal RDIM_EvalBytecode +d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +{ + RDIM_EvalBytecode bc = {0}; + + for (U64 cursor = 0; cursor < expr.size; ) { + U8 op = 0; + cursor += str8_deserial_read_struct(expr, cursor, &op); + + U64 size_param; + switch (op) { + case DW_ExprOp_Lit0: case DW_ExprOp_Lit1: case DW_ExprOp_Lit2: + case DW_ExprOp_Lit3: case DW_ExprOp_Lit4: case DW_ExprOp_Lit5: + case DW_ExprOp_Lit6: case DW_ExprOp_Lit7: case DW_ExprOp_Lit8: + case DW_ExprOp_Lit9: case DW_ExprOp_Lit10: case DW_ExprOp_Lit11: + case DW_ExprOp_Lit12: case DW_ExprOp_Lit13: case DW_ExprOp_Lit14: + case DW_ExprOp_Lit15: case DW_ExprOp_Lit16: case DW_ExprOp_Lit17: + case DW_ExprOp_Lit18: case DW_ExprOp_Lit19: case DW_ExprOp_Lit20: + case DW_ExprOp_Lit21: case DW_ExprOp_Lit22: case DW_ExprOp_Lit23: + case DW_ExprOp_Lit24: case DW_ExprOp_Lit25: case DW_ExprOp_Lit26: + case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29: + case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: { + U64 lit = op - DW_ExprOp_Lit0; + rdim_bytecode_push_uconst(arena, &bc, lit); + } break; + + case DW_ExprOp_Const1U: size_param = 1; goto const_unsigned; + case DW_ExprOp_Const2U: size_param = 2; goto const_unsigned; + case DW_ExprOp_Const4U: size_param = 4; goto const_unsigned; + case DW_ExprOp_Const8U: size_param = 8; goto const_unsigned; + const_unsigned: { + U64 val = 0; + cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); + rdim_bytecode_push_uconst(arena, &bc, val); + } break; + + case DW_ExprOp_Const1S:size_param = 1; goto const_signed; + case DW_ExprOp_Const2S:size_param = 2; goto const_signed; + case DW_ExprOp_Const4S:size_param = 4; goto const_signed; + case DW_ExprOp_Const8S:size_param = 8; goto const_signed; + const_signed: { + S64 val = 0; + cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); + val = extend_sign64(val, size_param); + rdim_bytecode_push_sconst(arena, &bc, val); + } break; + + case DW_ExprOp_ConstU: { + U64 val = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &val); + rdim_bytecode_push_uconst(arena, &bc, val); + } break; + + case DW_ExprOp_ConstS: { + S64 val = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, &val); + rdim_bytecode_push_sconst(arena, &bc, val); + } break; + + case DW_ExprOp_Addr: { + U64 addr = 0; + cursor += str8_deserial_read(expr, cursor, &addr, address_size, address_size); + if (addr >= image_base) { + U64 voff = addr - image_base; + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_ModuleOff, voff); + } else { + // TODO: error handling + AssertAlways(!"unable to relocate address"); } - } - - // SECTIONS - if (params->dump_sections){ - if (elf != 0){ - ELF_SectionArray section_array = elf_section_array_from_elf(elf); - String8Array section_name_array = elf_section_name_array_from_elf(elf); - - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "SECTIONS:\n")); - - ELF_Shdr64 *sec = section_array.sections; - String8 *sec_name = section_name_array.v; - U64 count = section_array.count; - for (U64 i = 0 ; i < count; i += 1, sec += 1, sec_name += 1){ - String8 type_string = elf_string_from_section_type(sec->sh_type); - - // TODO: better stringizers for fields here - str8_list_pushf(arena, &dump, " section[%llu]:\n", i); - str8_list_pushf(arena, &dump, " name='%.*s'\n", str8_varg(*sec_name)); - str8_list_pushf(arena, &dump, " type=%.*s\n", str8_varg(type_string)); - str8_list_pushf(arena, &dump, " flags=0x%llx\n", sec->sh_flags); - str8_list_pushf(arena, &dump, " addr=0x%llx\n", sec->sh_addr); - str8_list_pushf(arena, &dump, " offset=0x%llx\n", sec->sh_offset); - str8_list_pushf(arena, &dump, " size=%llu\n", sec->sh_size); - str8_list_pushf(arena, &dump, " link=%u\n", sec->sh_link); - str8_list_pushf(arena, &dump, " info=%u\n", sec->sh_info); - str8_list_pushf(arena, &dump, " addralign=0x%llx\n", sec->sh_addralign); - str8_list_pushf(arena, &dump, " entsize=%llu\n", sec->sh_entsize); - str8_list_push(arena, &dump, str8_lit("\n")); + } break; + + case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2: + case DW_ExprOp_Reg3: case DW_ExprOp_Reg4: case DW_ExprOp_Reg5: + case DW_ExprOp_Reg6: case DW_ExprOp_Reg7: case DW_ExprOp_Reg8: + case DW_ExprOp_Reg9: case DW_ExprOp_Reg10: case DW_ExprOp_Reg11: + case DW_ExprOp_Reg12: case DW_ExprOp_Reg13: case DW_ExprOp_Reg14: + case DW_ExprOp_Reg15: case DW_ExprOp_Reg16: case DW_ExprOp_Reg17: + case DW_ExprOp_Reg18: case DW_ExprOp_Reg19: case DW_ExprOp_Reg20: + case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23: + case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26: + case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: + case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { + U64 reg_code_dw = op - DW_ExprOp_Reg0; + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + } break; + + case DW_ExprOp_RegX: { + U64 reg_code_dw = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, ®_code_dw); + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + } break; + + case DW_ExprOp_ImplicitValue: { + U64 value_size = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &value_size); + + String8 val = str8_substr(expr, rng_1u64(cursor, cursor + value_size)); + if (val.size <= sizeof(U64)) { + U64 val64 = 0; + MemoryCopy(&val64, val.str, val.size); + rdim_bytecode_push_uconst(arena, &bc, val64); + } else { + // TODO: currenlty no way to encode string in RDIM_EvalBytecodeOp + NotImplemented; + } + } break; + + case DW_ExprOp_Piece: { + NotImplemented; + } break; + + case DW_ExprOp_BitPiece: { + NotImplemented; + } break; + + case DW_ExprOp_Pick: { + U8 stack_idx = 0; + cursor += str8_deserial_read_struct(expr, cursor, &stack_idx); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Pick, stack_idx); + } break; + + case DW_ExprOp_PlusUConst: { + U64 addend = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &addend); + rdim_bytecode_push_uconst(arena, &bc, addend); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_Skip: { + S16 skip = 0; + cursor += str8_deserial_read_struct(expr, cursor, &skip); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Skip, skip); + } break; + + case DW_ExprOp_Bra: { + NotImplemented; + } break; + + case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2: + case DW_ExprOp_BReg3: case DW_ExprOp_BReg4: case DW_ExprOp_BReg5: + case DW_ExprOp_BReg6: case DW_ExprOp_BReg7: case DW_ExprOp_BReg8: + case DW_ExprOp_BReg9: case DW_ExprOp_BReg10: case DW_ExprOp_BReg11: + case DW_ExprOp_BReg12: case DW_ExprOp_BReg13: case DW_ExprOp_BReg14: + case DW_ExprOp_BReg15: case DW_ExprOp_BReg16: case DW_ExprOp_BReg17: + case DW_ExprOp_BReg18: case DW_ExprOp_BReg19: case DW_ExprOp_BReg20: + case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23: + case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26: + case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29: + case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: { + U64 reg_code_dw = op - DW_ExprOp_BReg0; + S64 reg_off = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, ®_off); + + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_BRegX: { + U64 reg_code_dw = 0; + S64 reg_off = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, ®_code_dw); + cursor += str8_deserial_read_sleb128(expr, cursor, ®_off); + + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_FBReg: { + S64 frame_off = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, &frame_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_FrameOff, frame_off); + } break; + + case DW_ExprOp_Deref: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_MemRead, address_size); + } break; + + case DW_ExprOp_DerefSize: { + U8 deref_size_in_bytes = 0; + cursor += str8_deserial_read_struct(expr, cursor, &deref_size_in_bytes); + if (0 < deref_size_in_bytes && deref_size_in_bytes <= address_size) { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_MemRead, deref_size_in_bytes); + } else { + // TODO: error handling + AssertAlways(!"ill formed expression"); + } + } break; + + case DW_ExprOp_XDerefSize: { + // TODO: error handling + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Call2: + case DW_ExprOp_Call4: + case DW_ExprOp_CallRef: { + // TODO: error handling + AssertAlways(!"calls are not supported"); + } break; + + case DW_ExprOp_ImplicitPointer: + case DW_ExprOp_GNU_ImplicitPointer: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Convert: + case DW_ExprOp_GNU_Convert: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_GNU_ParameterRef: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_DerefType: + case DW_ExprOp_GNU_DerefType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_ConstType: + case DW_ExprOp_GNU_ConstType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_RegvalType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_EntryValue: + case DW_ExprOp_GNU_EntryValue: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Addrx: { + U64 addr_idx = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &addr_idx); + U64 addr = dw_addr_from_list_unit(addr_lu, addr_idx); + if (addr != max_U64) { + if (addr >= image_base) { + U64 voff = addr - image_base; + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_ModuleOff, voff); + } else { + // TODO: error handling + AssertAlways(!"unable to relocate address"); } + } else { + // TODO: error handling + AssertAlways(!"out of bounds index"); } + } break; + + case DW_ExprOp_CallFrameCfa: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_FrameOff, 0); + } break; + + case DW_ExprOp_FormTlsAddress: { + // TODO: + AssertAlways(!"RDI_EvalOp_TLSOff accepts immediate"); + } break; + + case DW_ExprOp_PushObjectAddress: { + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Nop: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Noop, 0); + } break; + + case DW_ExprOp_Eq: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_EqEq, 0); + } break; + + case DW_ExprOp_Ge: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_GrEq, 0); + } break; + + case DW_ExprOp_Gt: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Grtr, 0); + } break; + + case DW_ExprOp_Le: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LsEq, 0); + } break; + + case DW_ExprOp_Lt: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Less, 0); + } break; + + case DW_ExprOp_Ne: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_NtEq, 0); + } break; + + case DW_ExprOp_Shl: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LShift, 0); + } break; + + case DW_ExprOp_Shr: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RShift, 0); + } break; + + case DW_ExprOp_Shra: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Xor: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitXor, 0); + } break; + + case DW_ExprOp_XDeref: { + // TODO: error handling + Assert(!"multiple address spaces are not supported"); + } break; + + case DW_ExprOp_Abs: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Abs, 0); + } break; + + case DW_ExprOp_And: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitAnd, 0); + } break; + + case DW_ExprOp_Div: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Div, 0); + } break; + + case DW_ExprOp_Minus: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Sub, 0); + } break; + + case DW_ExprOp_Mod: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mod, 0); + } break; + + case DW_ExprOp_Mul: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mul, 0); + } break; + + case DW_ExprOp_Neg: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Neg, 0); + } break; + + case DW_ExprOp_Not: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitNot, 0); + } break; + + case DW_ExprOp_Or: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitOr, 0); + } break; + + case DW_ExprOp_Plus: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_Rot: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Swap: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Dup: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Drop: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Over: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Pick, 1); + } break; + + case DW_ExprOp_StackValue: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Stop, 0); + } break; + + default: InvalidPath; break; } - - // SYMTAB - if (symtab.count > 0 && params->dump_symtab){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "SYMTAB:\n")); - str8_list_pushf(arena, &dump, " section: %llu\n", elf->symtab_idx); - dump_symtab(arena, &dump, &symtab, strtab, 1); - str8_list_push(arena, &dump, str8_lit("\n")); + } + + return bc; +} + +internal RDIM_Location * +d2r_transpile_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +{ + RDIM_Location *loc = 0; + if (expr.size) { + loc = push_array(arena, RDIM_Location, 1); + loc->kind = RDI_LocationKind_AddrBytecodeStream; + loc->bytecode = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, expr); + } + return loc; +} + +internal RDIM_LocationSet +d2r_convert_loclist(Arena *arena, RDIM_ScopeChunkList *scopes, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, DW_LocList loclist) +{ + RDIM_LocationSet locset = {0}; + for (DW_LocNode *loc_n = loclist.first; loc_n != 0; loc_n = loc_n->next) { + RDIM_Location *location = d2r_transpile_expression(arena, image_base, address_size, arch, addr_lu, loc_n->v.expr); + RDIM_Rng1U64 voff_range = { .min = loc_n->v.range.min - image_base, .min = loc_n->v.range.max - image_base }; + rdim_location_set_push_case(arena, scopes, &locset, voff_range, location); + } + return locset; +} + +internal RDIM_LocationSet +d2r_locset_from_attrib(Arena *arena, + DW_Input *input, + DW_CompUnit *cu, + RDIM_ScopeChunkList *scopes, + RDIM_Scope *curr_scope, + U64 image_base, + U64 address_size, + RDI_Arch arch, + DW_ListUnit *addr_lu, + DW_Tag tag, + DW_AttribKind kind) +{ + RDIM_LocationSet result = {0}; + + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + DW_AttribClass attrib_class = dw_value_class_from_attrib(cu, attrib); + + if (attrib_class == DW_AttribClass_LocList || attrib_class == DW_AttribClass_LocListPtr) { + Temp scratch = scratch_begin(&arena, 1); + DW_LocList loclist = dw_loclist_from_attrib_ptr(scratch.arena, input, cu, attrib); + result = d2r_convert_loclist(arena, scopes, image_base, address_size, arch, addr_lu, loclist); + } else if (attrib_class == DW_AttribClass_ExprLoc) { + String8 expr = dw_exprloc_from_attrib_ptr(input, cu, attrib); + RDIM_Location *location = d2r_transpile_expression(arena, image_base, address_size, arch, addr_lu, expr); + for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { + rdim_location_set_push_case(arena, scopes, &result, range_n->v, location); } - - // DYNSYM - if (dynsym.count > 0 && params->dump_dynsym){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DYNSYM:\n")); - str8_list_pushf(arena, &dump, " section: %llu\n", elf->dynsym_idx); - dump_symtab(arena, &dump, &dynsym, strtab, 1); - str8_list_push(arena, &dump, str8_lit("\n")); + } else if (attrib_class != DW_AttribClass_Null) { + AssertAlways(!"unexpected attrib class"); + } + + return result; +} + +internal D2R_CompUnitContribMap +d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8 aranges_data = input->sec[DW_Section_ARanges].data; + Rng1U64List unit_range_list = dw_unit_ranges_from_data(scratch.arena, aranges_data); + + D2R_CompUnitContribMap cm = {0}; + cm.count = 0; + cm.info_off_arr = push_array(arena, U64, unit_range_list.count); + cm.voff_range_arr = push_array(arena, RDIM_Rng1U64List, unit_range_list.count); + + for (Rng1U64Node *range_n = unit_range_list.first; range_n != 0; range_n = range_n->next) { + String8 unit_data = str8_substr(aranges_data, range_n->v); + U64 unit_cursor = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, unit_cursor, &unit_length); + if (unit_length_size == 0) { + continue; } - - // SEGMENTS - if (params->dump_segments){ - if (elf != 0){ - ELF_SegmentArray segment_array = elf_segment_array_from_elf(elf); - - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "SEGMENTS:\n")); - - ELF_Phdr64 *segments = segment_array.segments; - U64 count = segment_array.count; - for (U64 i = 0 ; i < count; i += 1){ - ELF_Phdr64 *seg = segments + i; - - // TODO: better stringizers for fields here - str8_list_pushf(arena, &dump, " segment[%llu]:\n", i); - str8_list_pushf(arena, &dump, " p_type=%u\n", seg->p_type); - str8_list_pushf(arena, &dump, " p_flags=0x%x\n", seg->p_flags); - str8_list_pushf(arena, &dump, " p_offset=0x%llx\n", seg->p_offset); - str8_list_pushf(arena, &dump, " p_vaddr=0x%llx\n", seg->p_vaddr); - str8_list_pushf(arena, &dump, " p_paddr=0x%llx\n", seg->p_paddr); - str8_list_pushf(arena, &dump, " p_filesz=%llu\n", seg->p_filesz); - str8_list_pushf(arena, &dump, " p_memsz=%llu\n", seg->p_memsz); - str8_list_pushf(arena, &dump, " p_align=%llu\n", seg->p_align); - str8_list_push(arena, &dump, str8_lit("\n")); + unit_cursor += unit_length_size; + + DW_Version version = 0; + U64 version_size = str8_deserial_read_struct(unit_data, unit_cursor, &version); + if (version_size == 0) { + continue; + } + unit_cursor += version; + + if (version != DW_Version_2) { + AssertAlways(!"unknown .debug_aranges version"); + continue; + } + + DW_Format unit_format = DW_FormatFromSize(unit_length); + U64 cu_info_off = 0; + U64 cu_info_off_size = str8_deserial_read_dwarf_uint(unit_data, unit_cursor, unit_format, &cu_info_off); + if (cu_info_off_size == 0) { + continue; + } + unit_cursor += cu_info_off_size; + + U8 address_size = 0; + U64 address_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &address_size); + if (address_size_size == 0) { + continue; + } + unit_cursor += address_size_size; + + U8 segment_selector_size = 0; + U64 segment_selector_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &segment_selector_size); + if (segment_selector_size_size == 0) { + continue; + } + unit_cursor += segment_selector_size_size; + + U64 tuple_size = address_size * 2 + segment_selector_size; + U64 bytes_too_far_past_boundary = unit_cursor % tuple_size; + if (bytes_too_far_past_boundary > 0) { + unit_cursor += tuple_size - bytes_too_far_past_boundary; + } + + RDIM_Rng1U64List voff_ranges = {0}; + if (segment_selector_size == 0) { + while (unit_cursor + address_size * 2 <= unit_data.size) { + U64 address = 0; + U64 length = 0; + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, address_size, address_size); + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &length, address_size, address_size); + + if (address == 0 && length == 0) { + break; } + + // TODO: error handling + AssertAlways(address >= image_base); + + U64 min = address - image_base; + U64 max = min + length; + rdim_rng1u64_list_push(arena, &voff_ranges, (RDIM_Rng1U64){.min = min, .max = max}); } + } else { + // TODO: segment relative addressing + NotImplemented; } - - // DEBUG SECTIONS - if (params->dump_debug_sections){ - if (dwarf != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG SECTIONS:\n")); - - U32 *debug_section_idx = dwarf->debug_section_idx; - String8 *debug_data = dwarf->debug_data; - for (U32 i = 1; i < DWARF_SectionCode_COUNT; i += 1, debug_data += 1){ - U32 idx = debug_section_idx[i]; - String8 name = dwarf_string_from_section_code(i); - str8_list_pushf(arena, &dump, " %-10.*s section_idx=%u\n", str8_varg(name), idx); - } - str8_list_push(arena, &dump, str8_lit("\n")); + + U64 map_idx = cm.count++; + cm.info_off_arr[map_idx] = cu_info_off; + cm.voff_range_arr[map_idx] = voff_ranges; + } + + scratch_end(scratch); + return cm; +} + +internal RDIM_Rng1U64List +d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off) +{ + RDIM_Rng1U64List voff_ranges = {0}; + U64 voff_list_idx = u64_array_bsearch(map.info_off_arr, map.count, info_off); + if (voff_list_idx < map.count) { + voff_ranges = map.voff_range_arr[voff_list_idx]; + } + return voff_ranges; +} + +internal RDIM_Scope * +d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D2R_TagNode *tag_stack, Rng1U64List ranges) +{ + // fill out scope + RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, scopes, scope_chunk_cap); + + // push ranges + for (Rng1U64Node *i = ranges.first; i != 0; i = i->next) { + rdim_scope_push_voff_range(arena, scopes, scope, (RDIM_Rng1U64){.min = i->v.min, i->v.max}); + } + + // associate scope with tag + tag_stack->scope = scope; + + // update scope hierarchy + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || parent_tag_kind == DW_Tag_InlinedSubroutine || parent_tag_kind == DW_Tag_LexicalBlock) { + RDIM_Scope *parent = tag_stack->next->scope; + + scope->parent_scope = tag_stack->next->scope; + + if (parent->last_child) { + parent->last_child->next_sibling = scope; + } + + SLLQueuePush_N(parent->first_child, parent->last_child, scope, next_sibling); + } + + // propagate scope symbol + if (tag_stack->cur_node->tag.kind == DW_Tag_LexicalBlock) { + scope->symbol = tag_stack->next->scope->symbol; + } + + return scope; +} + +internal RDIM_BakeParams * +d2r_convert(Arena *arena, D2R_User2Convert *in) +{ + Temp scratch = scratch_begin(&arena, 1); + + B32 is_parse_relaxed = !(in->flags & D2R_ConvertFlag_StrictParse); + + RDIM_BinarySectionList binary_sections = {0}; + Arch arch = Arch_Null; + U64 image_base = 0; + U64 voff_max = 0; + DW_Input input = {0}; + DW_ListUnitInput lui = {0}; + if (pe_check_magic(in->input_exe_data)) { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, in->input_exe_data); + + // infer exe info + arch = pe.arch; + image_base = pe.image_base; + + // get COFF sections + String8 raw_sections = str8_substr(in->input_exe_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); + U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); + COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; + + // loop over section headers and pick max virtual offset + for (U64 i = 0; i < section_count; ++i) { + U64 sec_voff_max = section_array[i].voff + section_array[i].vsize; + voff_max = Max(voff_max, sec_voff_max); + } + + ProfBegin("binary sections"); + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *coff_sec = §ion_array[i]; + RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections); + + sec->name = coff_name_from_section_header(in->input_exe_data, coff_sec, pe.string_table_off); + sec->flags = rdi_binary_section_flags_from_coff_section_flags(coff_sec->flags); + sec->voff_first = coff_sec->voff; + sec->voff_opl = coff_sec->voff + coff_sec->vsize; + sec->foff_first = coff_sec->foff; + sec->foff_opl = coff_sec->foff + coff_sec->fsize; + } + ProfEnd(); + + // find DWARF sections + input = dw_input_from_coff_section_table(scratch.arena, in->input_exe_data, pe.string_table_off, section_count, section_array); + } + + //////////////////////////////// + + RDI_Arch arch_rdi = RDI_Arch_NULL; + switch (arch) { + case Arch_Null: arch_rdi = RDI_Arch_NULL; break; + case Arch_x64: arch_rdi = RDI_Arch_X64; break; + case Arch_x86: arch_rdi = RDI_Arch_X86; break; + default: NotImplemented; break; + } + + U64 arch_addr_size = rdi_addr_size_from_arch(arch_rdi); + + //////////////////////////////// + + ProfBegin("compute exe hash"); + U64 exe_hash = rdi_hash(in->input_exe_data.str, in->input_exe_data.size); + ProfEnd(); + + //////////////////////////////// + + ProfBegin("top level info"); + RDIM_TopLevelInfo top_level_info = {0}; + top_level_info.arch = arch_rdi; + top_level_info.exe_name = str8_skip_last_slash(in->input_exe_name); + top_level_info.exe_hash = exe_hash; + top_level_info.voff_max = voff_max; + top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); + ProfEnd(); + + //////////////////////////////// + + static const U64 UNIT_CHUNK_CAP = 256; + static const U64 UDT_CHUNK_CAP = 256; + static const U64 TYPE_CHUNK_CAP = 256; + static const U64 GVAR_CHUNK_CAP = 256; + static const U64 TVAR_CHUNK_CAP = 256; + static const U64 PROC_CHUNK_CAP = 256; + static const U64 SCOPE_CHUNK_CAP = 256; + static const U64 INLINE_SITE_CHUNK_CAP = 256; + static const U64 SRC_FILE_CAP = 256; + static const U64 LINE_TABLE_CAP = 256; + + RDIM_UnitChunkList units = {0}; + RDIM_UDTChunkList udts = {0}; + RDIM_TypeChunkList types = {0}; + RDIM_SymbolChunkList gvars = {0}; + RDIM_SymbolChunkList tvars = {0}; + RDIM_SymbolChunkList procs = {0}; + RDIM_ScopeChunkList scopes = {0}; + RDIM_InlineSiteChunkList inline_sites = {0}; + RDIM_SrcFileChunkList src_files = {0}; + RDIM_LineTableChunkList line_tables = {0}; + + //////////////////////////////// + + ProfBegin("Make Unit Contrib Map"); + D2R_CompUnitContribMap cu_contrib_map = {0}; + if (input.sec[DW_Section_ARanges].data.size > 0) { + cu_contrib_map = d2r_cu_contrib_map_from_aranges(arena, &input, image_base); + } else { + // TODO: synthesize cu ranges from scopes + NotImplemented; + } + ProfEnd(); + + ProfBegin("Parse Comop Unit Ranges"); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &input); + Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input.sec[DW_Section_Info].data); + Rng1U64Array cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list); + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Parse Compile Unit Headers"); + DW_CompUnit *cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count); + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, &input, lu_input, cu_ranges.v[cu_idx].min, is_parse_relaxed); + } + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Parse Line Tables"); + DW_LineTableParseResult *cu_line_tables = push_array(scratch.arena, DW_LineTableParseResult, cu_ranges.count); + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + DW_CompUnit *cu = &cu_arr[cu_idx]; + String8 cu_stmt_list = dw_line_ptr_from_attrib(&input, cu, cu->tag, DW_Attrib_StmtList); + String8 cu_dir = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_CompDir); + String8 cu_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Name); + cu_line_tables[cu_idx] = dw_parsed_line_table_from_data(scratch.arena, cu_stmt_list, &input, cu_dir, cu_name, cu->address_size, cu->str_offsets_lu); + } + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Convert Line Tables"); + + HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000); + RDIM_LineTable **cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count); + + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP); + + DW_LineTableParseResult *line_table = &cu_line_tables[cu_idx]; + DW_LineVMFileArray *dir_table = &line_table->vm_header.dir_table; + DW_LineVMFileArray *file_table = &line_table->vm_header.file_table; + RDIM_SrcFile **src_file_map = push_array(scratch.arena, RDIM_SrcFile *, file_table->count); + for (U64 file_idx = 0; file_idx < file_table->count; ++file_idx) { + DW_LineFile *file = &file_table->v[file_idx]; + String8 file_path = dw_path_from_file_idx(scratch.arena, &line_table->vm_header, file_idx); + String8List file_path_split = str8_split_path(scratch.arena, file_path); + str8_path_list_resolve_dots_in_place(&file_path_split, PathStyle_WindowsAbsolute); + String8 file_path_resolved = str8_path_list_join_by_style(scratch.arena, &file_path_split, PathStyle_WindowsAbsolute); + String8 file_path_normalized = lower_from_str8(scratch.arena, file_path_resolved); + RDIM_SrcFile *src_file = hash_table_search_path_raw(source_file_ht, file_path_normalized); + if (src_file == 0) { + src_file = rdim_src_file_chunk_list_push(arena, &src_files, SRC_FILE_CAP); + src_file->normal_full_path = push_str8_copy(arena, file_path_normalized); + hash_table_push_path_raw(scratch.arena, source_file_ht, src_file->normal_full_path, src_file); } + src_file_map[file_idx] = src_file; } - - // DEBUG INFO - if (params->dump_debug_info){ - if (info != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG INFO:\n")); - - U32 i = 0; - for (DWARF_InfoUnit *unit = info->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_info(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - + + for (DW_LineSeqNode *line_seq = line_table->first_seq; line_seq != 0; line_seq = line_seq->next) { + if (line_seq->count == 0) { + continue; } - } - - // DEBUG PUBNAMES - if (params->dump_debug_pubnames){ - if (pubnames != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG PUBNAMES:\n")); - - U32 i = 0; - for (DWARF_PubNamesUnit *unit = pubnames->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_pubnames(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } - - // DEBUG PUBTYPES - if (params->dump_debug_pubtypes){ - if (pubtypes != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG PUBTYPES:\n")); - - U32 i = 0; - for (DWARF_PubNamesUnit *unit = pubtypes->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_pubnames(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } - - // DEBUG NAMES - if (params->dump_debug_names){ - if (names != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG NAMES:\n")); - - U32 i = 0; - for (DWARF_NamesUnit *unit = names->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_names(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } - - // DEBUG ARANGES - if (params->dump_debug_aranges){ - if (aranges != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG ARANGES:\n")); - - U32 i = 0; - for (DWARF_ArangesUnit *unit = aranges->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_aranges(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } - - // DEBUG ADDR - if (params->dump_debug_addr){ - if (addr != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG ADDR:\n")); - - U32 i = 0; - for (DWARF_AddrUnit *unit = addr->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - dwarf_stringize_addr(arena, &dump, unit, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } - -#if 0 - // DEBUG ABBREV - if (params->dump_debug_abbrev){ - if (abbrev != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG ABBREV:\n")); - - U32 i = 0; - for (DWARF_AbbrevUnit *unit = abbrev->unit_first; - unit != 0; - unit = unit->next, i += 1){ - U32 j = 0; - for (DWARF_AbbrevDecl *abbrev_decl = unit->first; - abbrev_decl != 0; - abbrev_decl = abbrev_decl->next, j += 1){ - String8 tag_string = dwarf_string_from_tag(abbrev_decl->tag); - - str8_list_pushf(arena, &dump, " unit[%u],abbrev[%u]:\n", i, j); - str8_list_pushf(arena, &dump, " code=%llu\n", abbrev_decl->abbrev_code); - str8_list_pushf(arena, &dump, " tag=%.*s\n", str8_varg(tag_string)); - str8_list_pushf(arena, &dump, " has_children=%u\n", abbrev_decl->has_children); - str8_list_pushf(arena, &dump, " attrib_count=%u\n", abbrev_decl->attrib_count); - str8_list_pushf(arena, &dump, " attribs:\n", abbrev_decl->attrib_count); - - U32 attrib_count = abbrev_decl->attrib_count; - DWARF_AbbrevAttribSpec *attrib_spec = abbrev_decl->attrib_specs; - for (U32 k = 0; k < attrib_count; k += 1, attrib_spec += 1){ - String8 name_string = dwarf_string_from_attribute_name(attrib_spec->name); - String8 form_string = dwarf_string_from_attribute_form(attrib_spec->form); - - str8_list_pushf(arena, &dump, " [%-14.*s %-10.*s]\n", - str8_varg(name_string), str8_varg(form_string)); + + U64 *voffs = push_array(arena, U64, line_seq->count); + U32 *line_nums = push_array(arena, U32, line_seq->count); + U16 *col_nums = 0; + U64 line_idx = 0; + + DW_LineNode *file_line_n = line_seq->first; + U64 file_line_count = 0; + + for (DW_LineNode *line_n = file_line_n; line_n != 0; line_n = line_n->next) { + if (file_line_n->v.file_index != line_n->v.file_index || line_n->next == 0) { + U64 file_index = file_line_n->v.file_index; + U64 *file_voffs = &voffs[line_idx]; + U32 *file_line_nums = &line_nums[line_idx]; + U16 *file_col_nums = 0; + + U64 lines_written = 0; + U64 prev_ln = max_U64; + DW_LineNode *sentinel = line_n->v.file_index != file_line_n->v.file_index ? line_n : 0; + for (; file_line_n != sentinel; file_line_n = file_line_n->next) { + if (file_line_n->v.line != prev_ln) { + // TODO: error handling + AssertAlways(file_line_n->v.address >= image_base); + + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + + ++lines_written; + ++line_idx; + + prev_ln = file_line_n->v.line; } + } + + RDIM_SrcFile *src_file = src_file_map[file_index]; + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, lines_written); + rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + + file_line_count = 1; + } else { + ++file_line_count; + } + } + + // handle last line + if (file_line_n) { + U64 file_index = file_line_n->v.file_index; + U64 *file_voffs = &voffs[line_idx]; + U32 *file_line_nums = &line_nums[line_idx]; + U16 *file_col_nums = 0; + + for (; file_line_n != 0; file_line_n = file_line_n->next, ++line_idx) { + // TODO: error handling + AssertAlways(file_line_n->v.address >= image_base); + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + } + + RDIM_SrcFile *src_file = src_file_map[file_index]; + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, file_line_count); + rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + } + + //Assert(line_idx == line_seq->count); + } + } + + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Convert Units"); + + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + Temp comp_temp = temp_begin(scratch.arena); + + DW_CompUnit *cu = &cu_arr[cu_idx]; + + // parse and build tag tree + DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu); + + // build tag hash table for abstract origin resolution + cu->tag_ht = dw_make_tag_hash_table(comp_temp.arena, tag_tree); + + String8 dwo_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_DwoName); + String8 gnu_dwo_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_GNU_DwoName); + if (dwo_name.size || gnu_dwo_name.size || cu->dwo_id) { + // TODO: report that we dont support DWO + continue; + } + + // get unit's contribution ranges + RDIM_Rng1U64List cu_voff_ranges = d2r_voff_ranges_from_cu_info_off(cu_contrib_map, cu_ranges.v[cu_idx].min); + + String8 cu_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Name); + String8 cu_dir = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_CompDir); + String8 cu_prod = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Producer); + DW_Language cu_lang = dw_const_u64_from_attrib(&input, cu, cu->tag, DW_Attrib_Language); + + RDIM_Unit *unit = rdim_unit_chunk_list_push(arena, &units, UNIT_CHUNK_CAP); + unit->unit_name = cu_name; + unit->compiler_name = cu_prod; + unit->source_file = str8_zero(); + unit->object_file = str8_zero(); + unit->archive_file = str8_zero(); + unit->build_path = cu_dir; + unit->language = rdi_language_from_dw_language(cu_lang); + unit->line_table = cu_line_tables_rdi[cu_idx]; + unit->voff_ranges = cu_voff_ranges; + + D2R_TypeTable *type_table = push_array(comp_temp.arena, D2R_TypeTable, 1); + type_table->ht = hash_table_init(comp_temp.arena, 0x4000); + type_table->types = &types; + type_table->type_chunk_cap = TYPE_CHUNK_CAP; + type_table->void_type = d2r_create_type(arena, type_table); + type_table->void_type->kind = RDI_TypeKind_Void; + type_table->varg_type = d2r_create_type(arena, type_table); + type_table->varg_type->kind = RDI_TypeKind_Variadic; + + D2R_TagNode *free_tags = push_array(comp_temp.arena, D2R_TagNode, 1); + D2R_TagNode *tag_stack = push_array(comp_temp.arena, D2R_TagNode, 1); + tag_stack->cur_node = tag_tree.root; + + while (tag_stack) { + while (tag_stack->cur_node) { + DW_TagNode *cur_node = tag_stack->cur_node; + DW_Tag tag = cur_node->tag; + B32 visit_children = 1; + + switch (tag.kind) { + case DW_Tag_Null: { + InvalidPath; + } break; + case DW_Tag_ClassType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteClass; + + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Class; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + tag_stack->type = type; + } + } break; + case DW_Tag_StructureType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteStruct; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Struct; + type->udt = udt; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); - str8_list_push(arena, &dump, str8_lit("\n")); + tag_stack->type = type; + } + } break; + case DW_Tag_UnionType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteUnion; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Union; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + + tag_stack->type = type; + } + } break; + case DW_Tag_EnumerationType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteEnum; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Enum; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + + tag_stack->type = type; + } + } break; + case DW_Tag_SubroutineType: { + // collect parameters + RDIM_TypeList param_list = {0}; + for (DW_TagNode *n = cur_node->first_child; n != 0; n = n->sibling) { + if (n->tag.kind == DW_Tag_FormalParameter) { + RDIM_Type *param_type = d2r_type_from_attrib(arena, type_table, &input, cu, n->tag, DW_Attrib_Type); + rdim_type_list_push(comp_temp.arena, ¶m_list, param_type); + } else if (n->tag.kind == DW_Tag_UnspecifiedParameters) { + rdim_type_list_push(comp_temp.arena, ¶m_list, type_table->varg_type); + } else { + // TODO: error handling + AssertAlways(!"unexpected tag"); + } + } + + // init proceudre type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Function; + type->byte_size = arch_addr_size; + type->direct_type = ret_type; + type->count = param_list.count; + type->param_types = rdim_array_from_type_list(arena, param_list); + + visit_children = 0; + } break; + case DW_Tag_Typedef: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Alias; + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_BaseType: { + DW_ATE encoding = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_Encoding); + U64 byte_size = dw_byte_size_from_tag(&input, cu, tag); + + // convert base type encoding to RDI version + RDI_TypeKind kind = RDI_TypeKind_NULL; + switch (encoding) { + case DW_ATE_Null: kind = RDI_TypeKind_NULL; break; + case DW_ATE_Address: kind = RDI_TypeKind_Void; break; + case DW_ATE_Boolean: kind = RDI_TypeKind_Bool; break; + case DW_ATE_ComplexFloat: { + switch (byte_size) { + case 4: kind = RDI_TypeKind_ComplexF32; break; + case 8: kind = RDI_TypeKind_ComplexF64; break; + case 10: kind = RDI_TypeKind_ComplexF80; break; + case 16: kind = RDI_TypeKind_ComplexF128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Float: { + switch (byte_size) { + case 2: kind = RDI_TypeKind_F16; break; + case 4: kind = RDI_TypeKind_F32; break; + case 6: kind = RDI_TypeKind_F48; break; + case 8: kind = RDI_TypeKind_F64; break; + case 16: kind = RDI_TypeKind_F128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Signed: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_S8; break; + case 2: kind = RDI_TypeKind_S16; break; + case 4: kind = RDI_TypeKind_S32; break; + case 8: kind = RDI_TypeKind_S64; break; + case 16: kind = RDI_TypeKind_S128; break; + case 32: kind = RDI_TypeKind_S256; break; + case 64: kind = RDI_TypeKind_S512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_SignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_Char8; break; + case 2: kind = RDI_TypeKind_Char16; break; + case 4: kind = RDI_TypeKind_Char32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Unsigned: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_U8; break; + case 2: kind = RDI_TypeKind_U16; break; + case 4: kind = RDI_TypeKind_U32; break; + case 8: kind = RDI_TypeKind_U64; break; + case 16: kind = RDI_TypeKind_U128; break; + case 32: kind = RDI_TypeKind_U256; break; + case 64: kind = RDI_TypeKind_U512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_UnsignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_UChar8; break; + case 2: kind = RDI_TypeKind_UChar16; break; + case 4: kind = RDI_TypeKind_UChar32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_ImaginaryFloat: { + NotImplemented; + } break; + case DW_ATE_PackedDecimal: { + NotImplemented; + } break; + case DW_ATE_NumericString: { + NotImplemented; + } break; + case DW_ATE_Edited: { + NotImplemented; + } break; + case DW_ATE_SignedFixed: { + NotImplemented; + } break; + case DW_ATE_UnsignedFixed: { + NotImplemented; + } break; + case DW_ATE_DecimalFloat: { + NotImplemented; + } break; + case DW_ATE_Utf: { + NotImplemented; + } break; + case DW_ATE_Ucs: { + NotImplemented; + } break; + case DW_ATE_Ascii: { + NotImplemented; + } break; + default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling + } + + RDIM_Type *base_type = d2r_create_type(arena, type_table); + base_type->kind = kind; + base_type->byte_size = byte_size; + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Alias; + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + type->direct_type = base_type; + } break; + case DW_Tag_PointerType: { + RDIM_Type *direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Allocated)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Associated)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_AddressClass)); + + U64 byte_size = arch_addr_size; + if (cu->version == DW_Version_5 || cu->relaxed) { + dw_try_byte_size_from_tag(&input, cu, tag, &byte_size); + } + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Ptr; + type->byte_size = byte_size; + type->direct_type = direct_type; + } break; + case DW_Tag_RestrictType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Restrict; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_VolatileType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Volatile; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_ConstType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Const; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_ArrayType: { + // * DWARF vs RDI Array Type Graph * + // + // For example lets take following decl: + // + // int (*foo[2])[3][4]; + // + // This compiles to in DWARF: + // + // foo -> DW_TAG_ArrayType -> (A0) DW_TAG_Subrange [2] + // \ + // -> (B0) DW_TAG_PointerType -> (A1) DW_TAG_ArrayType -> DW_TAG_Subrange [3] -> DW_Tag_Subrange [4] + // \ + // -> (B1) DW_TAG_BaseType (int) + // + // RDI expects: + // + // foo -> Array (2) -> Pointer -> Array (3) -> Array (4) -> int + // + // Note that DWARF forks the graph on DW_TAG_ArrayType to describe array ranges in branch A and + // in branch B describes array type which might be a struct, pointer, base type, or any other type tag. + // However, in RDI we have a simple list of type nodes and to convert we need to append type nodes from + // B to A. + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Array; + type->direct_type = 0; + + U64 subrange_count = 0; + RDIM_Type *t = type; + for (DW_TagNode *n = cur_node->first_child; n != 0; n = n->sibling) { + if (n->tag.kind != DW_Tag_SubrangeType) { + // TODO: error handling + AssertAlways(!"unexpected tag"); + continue; + } + + if (subrange_count > 0) { + // init array type node + RDIM_Type *s = d2r_create_type(arena, type_table); + s->kind = RDI_TypeKind_Array; + s->direct_type = 0; + + // append new array type node + t->direct_type = s; + t = s; + } + + // resolve array lower bound + U64 lower_bound = 0; + if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_LowerBound)) { + lower_bound = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_LowerBound); + } else { + lower_bound = dw_pick_default_lower_bound(cu_lang); + } + + // resolve array upper bound + U64 upper_bound = 0; + if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_Count)) { + U64 count = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_Count); + upper_bound = lower_bound + count; + } else if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_UpperBound)) { + upper_bound = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_UpperBound); + // turn upper bound into exclusive range + upper_bound += 1; + } else { + // zero size array + } + + t->count = upper_bound - lower_bound; + ++subrange_count; + } + + Assert(t->direct_type == 0); + t->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + visit_children = 0; + } break; + case DW_Tag_SubrangeType: { + // TODO: error handling + AssertAlways(!"unexpected tag"); + } break; + case DW_Tag_Inheritance: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_StructureType && + parent_node->tag.kind != DW_Tag_ClassType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + RDIM_Type *parent = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, parent->udt); + member->kind = RDI_MemberKind_Base; + member->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + member->off = safe_cast_u32(dw_const_u32_from_attrib(&input, cu, tag, DW_Attrib_DataMemberLocation)); + } break; + case DW_Tag_Enumerator: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_EnumerationType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTEnumVal *member = rdim_udt_push_enum_val(arena, &udts, type->udt); + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + member->val = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_ConstValue); + } break; + case DW_Tag_Member: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_StructureType && + parent_node->tag.kind != DW_Tag_ClassType && + parent_node->tag.kind != DW_Tag_UnionType && + parent_node->tag.kind != DW_Tag_EnumerationType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + DW_Attrib *data_member_location = dw_attrib_from_tag(&input, cu, tag, DW_Attrib_DataMemberLocation); + DW_AttribClass data_member_location_class = dw_value_class_from_attrib(cu, data_member_location); + if (data_member_location_class == DW_AttribClass_LocList) { + AssertAlways(!"UDT member with multiple locations are not supported"); + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, type->udt); + member->kind = RDI_MemberKind_DataField; + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + member->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + member->off = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_DataMemberLocation); + } break; + case DW_Tag_SubProgram: { + DW_InlKind inl = dw_u64_from_attrib(&input, cu, tag, DW_Attrib_Inline); + switch (inl) { + case DW_Inl_NotInlined: { + U64 param_count = 0; + RDIM_Type **params = d2r_collect_proc_params(arena, type_table, &input, cu, cur_node, ¶m_count); + + // get return type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // fill out proc type + RDIM_Type *proc_type = d2r_create_type(arena, type_table); + proc_type->kind = RDI_TypeKind_Function; + proc_type->byte_size = arch_addr_size; + proc_type->direct_type = ret_type; + proc_type->count = param_count; + proc_type->param_types = params; + + // get container type + RDIM_Type *container_type = 0; + if (dw_tag_has_attrib(&input, cu, tag, DW_Attrib_ContainingType)) { + container_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_ContainingType); + } + + // get frame base expression + String8 frame_base_expr = dw_exprloc_from_attrib(&input, cu, tag, DW_Attrib_FrameBase); + + // get proc container symbol + RDIM_Symbol *proc = rdim_symbol_chunk_list_push(arena, &procs, PROC_CHUNK_CAP ); + + // make scope + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + RDIM_Scope *root_scope = d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + root_scope->symbol = proc; + + // fill out proc + proc->is_extern = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_External); + proc->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + proc->link_name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_LinkageName); + proc->type = proc_type; + proc->container_symbol = 0; + proc->container_type = container_type; + proc->root_scope = root_scope; + proc->frame_base = d2r_locset_from_attrib(arena, &input, cu, &scopes, root_scope, image_base, cu->address_size, arch_rdi, cu->addr_lu, tag, DW_Attrib_FrameBase); + + // sub program with user-defined parent tag is a method + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_ClassType || parent_tag_kind == DW_Tag_StructureType) { + RDI_MemberKind member_kind = RDI_MemberKind_NULL; + DW_VirtualityKind virtuality = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_Virtuality); + switch (virtuality) { + case DW_VirtualityKind_None: member_kind = RDI_MemberKind_Method; break; + case DW_VirtualityKind_Virtual: member_kind = RDI_MemberKind_VirtualMethod; break; + case DW_VirtualityKind_PureVirtual: member_kind = RDI_MemberKind_VirtualMethod; break; // TODO: create kind for pure virutal + default: InvalidPath; break; + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, type->udt); + member->kind = member_kind; + member->type = type; + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + } else if (parent_tag_kind != DW_Tag_CompileUnit) { + AssertAlways(!"unexpected tag"); + } + + tag_stack->scope = root_scope; + } break; + case DW_Inl_DeclaredNotInlined: + case DW_Inl_DeclaredInlined: + case DW_Inl_Inlined: { + visit_children = 0; + } break; + default: InvalidPath; break; + } + } break; + case DW_Tag_InlinedSubroutine: { + U64 param_count = 0; + RDIM_Type **params = d2r_collect_proc_params(arena, type_table, &input, cu, tag_stack->cur_node, ¶m_count); + + // get return type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // fill out proc type + RDIM_Type *proc_type = d2r_create_type(arena, type_table); + proc_type->kind = RDI_TypeKind_Function; + proc_type->byte_size = arch_addr_size; + proc_type->direct_type = ret_type; + proc_type->count = param_count; + proc_type->param_types = params; + + // get container type + RDIM_Type *owner = 0; + if (dw_tag_has_attrib(&input, cu, tag, DW_Attrib_ContainingType)) { + owner = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_ContainingType); + } + + // fill out inline site + RDIM_InlineSite *inline_site = rdim_inline_site_chunk_list_push(arena, &inline_sites, INLINE_SITE_CHUNK_CAP); + inline_site->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + inline_site->type = proc_type; + inline_site->owner = owner; + inline_site->line_table = 0; + + // make scope + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + RDIM_Scope *root_scope = d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + root_scope->inline_site = inline_site; + } break; + case DW_Tag_Variable: { + String8 name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + RDIM_Type *type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || + parent_tag_kind == DW_Tag_InlinedSubroutine || + parent_tag_kind == DW_Tag_LexicalBlock) { + RDIM_Scope *scope = tag_stack->next->scope; + RDIM_Local *local = rdim_scope_push_local(arena, &scopes, tag_stack->next->scope); + local->kind = RDI_LocalKind_Variable; + local->name = name; + local->type = type; + local->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, cu->address_size, arch_rdi, cu->addr_lu, tag, DW_Attrib_Location); + } else { + + // NOTE: due to a bug in clang in stb_sprint.h local variables + // are declared in global scope without a name + if (name.size == 0) { + break; + } + + RDIM_Symbol *gvar = rdim_symbol_chunk_list_push(arena, &gvars, GVAR_CHUNK_CAP); + gvar->is_extern = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_External); + gvar->name = name; + gvar->link_name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_LinkageName); + gvar->type = type; + gvar->offset = 0; // TODO: NotImplemented; + gvar->container_symbol = 0; + gvar->container_type = 0; // TODO: NotImplemented; + } + } break; + case DW_Tag_FormalParameter: { + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || parent_tag_kind == DW_Tag_InlinedSubroutine) { + RDIM_Scope *scope = tag_stack->next->scope; + RDIM_Local *param = rdim_scope_push_local(arena, &scopes, scope); + param->kind = RDI_LocalKind_Parameter; + param->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + param->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + param->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, cu->address_size, arch_rdi, cu->addr_lu, tag, DW_Attrib_Location); + } else { + // TODO: error handling + AssertAlways(!"this is a local variable"); + } + } break; + case DW_Tag_LexicalBlock: { + if (tag_stack->next->cur_node->tag.kind == DW_Tag_SubProgram || + tag_stack->next->cur_node->tag.kind == DW_Tag_InlinedSubroutine || + tag_stack->next->cur_node->tag.kind == DW_Tag_LexicalBlock) { + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + } + } break; + case DW_Tag_Label: + case DW_Tag_CompileUnit: + case DW_Tag_UnspecifiedParameters: + break; + default: NotImplemented; break; + } + + if (tag_stack->cur_node->first_child && visit_children) { + D2R_TagNode *frame = free_tags; + if (frame) { + SLLStackPop(free_tags); + MemoryZeroStruct(frame); + } else { + frame = push_array(scratch.arena, D2R_TagNode, 1); + } + frame->cur_node = tag_stack->cur_node->first_child; + SLLStackPush(tag_stack, frame); + } else { + tag_stack->cur_node = tag_stack->cur_node->sibling; + } + } + + // recycle free frame + D2R_TagNode *frame = tag_stack; + SLLStackPop(tag_stack); + SLLStackPush(free_tags, frame); + + if (tag_stack) { + tag_stack->cur_node = tag_stack->cur_node->sibling; + } + } + + temp_end(comp_temp); + } + + ProfEnd(); + + { + for (RDIM_TypeChunkNode *chunk_n = types.first; chunk_n != 0; chunk_n = chunk_n->next) { + for (U64 i = 0; i < chunk_n->count; ++i) { + RDIM_Type *type = &chunk_n->v[i]; + if (type->kind == RDI_TypeKind_Alias) { + for (RDIM_Type *t = type->direct_type; t != 0; t = t->direct_type) { + if (t->byte_size != 0) { + type->byte_size = t->byte_size; + break; + } } } - } } -#endif - -#if 0 - // DEBUG INFO - if (params->dump_debug_info){ - if (info != 0){ - str8_list_push(arena, &dump, - str8_lit("################################" - "################################\n" - "DEBUG INFO:\n")); - - U32 i = 0; - for (DWARF_InfoUnit *unit = info->unit_first; - unit != 0; - unit = unit->next, i += 1){ - str8_list_pushf(arena, &dump, " unit[%u]:\n", i); - str8_list_pushf(arena, &dump, " [header]\n"); - str8_list_pushf(arena, &dump, " version=%u\n", unit->dwarf_version); - str8_list_pushf(arena, &dump, " offset_size=%u\n", unit->offset_size); - str8_list_pushf(arena, &dump, " address_size=%u\n", unit->address_size); - str8_list_pushf(arena, &dump, " [extracted attributes]\n"); - str8_list_pushf(arena, &dump, " langauge=%u\n", (U32)unit->language); - str8_list_pushf(arena, &dump, " line_info_offset=%llu\n", unit->line_info_offset); - str8_list_pushf(arena, &dump, " vbase=0x%llx\n", unit->vbase); - str8_list_pushf(arena, &dump, " str_offsets_base=%llu\n", unit->str_offsets_base); - str8_list_pushf(arena, &dump, " addr_base=%llu\n", unit->addr_base); - str8_list_pushf(arena, &dump, " rnglists_base=%llu\n", unit->rnglists_base); - str8_list_pushf(arena, &dump, " loclists_base=%llu\n", unit->loclists_base); - dump_entry_tree(arena, &dump, dwarf, unit, unit->entry_root, 2); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - } - } -#endif - - // print dump - for (String8Node *node = dump.first; - node != 0; - node = node->next){ - fwrite(node->string.str, 1, node->string.size, stdout); - } } + + { + RDIM_TypeNode *type_stack = 0; + RDIM_TypeNode *free_types = 0; + + for (RDIM_TypeChunkNode *chunk_n = types.first; chunk_n != 0; chunk_n = chunk_n->next) { + for (U64 i = 0; i < chunk_n->count; ++i) { + RDIM_Type *type = &chunk_n->v[i]; + if (type->kind == RDI_TypeKind_Array) { + if (type->byte_size != 0) + continue; + + RDIM_Type *t; + for (t = type; t != 0 && t->kind == RDI_TypeKind_Array; t = t->direct_type) { + RDIM_TypeNode *f = free_types; + if (f == 0) { + f = push_array(scratch.arena, RDIM_TypeNode, 1); + } else { + SLLStackPop(free_types); + } + f->v = t; + SLLStackPush(type_stack, f); + } + + U64 base_type_size = 0; + if (t) { + base_type_size = t->byte_size; + } + + U64 array_size = base_type_size; + while (type_stack) { + if (type_stack->v->count) { + array_size *= type_stack->v->count; + } else { + array_size += type_stack->v->byte_size; + } + SLLStackPop(type_stack); + } + + type->count = 0; + type->byte_size = array_size; + + // recycle frames + free_types = type_stack; + type_stack = 0; + } + } + } + } + + //////////////////////////////// + + RDIM_BakeParams *bake_params = push_array(arena, RDIM_BakeParams, 1); + bake_params->top_level_info = top_level_info; + bake_params->binary_sections = binary_sections; + bake_params->units = units; + bake_params->types = types; + bake_params->udts = udts; + bake_params->src_files = src_files; + bake_params->line_tables = line_tables; + bake_params->global_variables = gvars; + bake_params->thread_variables = tvars; + bake_params->procedures = procs; + bake_params->scopes = scopes; + bake_params->inline_sites = inline_sites; + + scratch_end(scratch); + return bake_params; } + +internal RDIM_BakeResults +d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +{ + return rdim_bake(state, in_params); +} + +internal RDIM_SerializedSectionBundle +d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in) +{ + RDIM_SerializedSectionBundle result = {0}; + return result; +} + +internal RDI_Language +rdi_language_from_dw_language(DW_Language v) +{ + RDI_Language result = RDI_Language_NULL; + switch (v) { + case DW_Language_Null: result = RDI_Language_NULL; break; + + case DW_Language_C89: + case DW_Language_C99: + case DW_Language_C11: + case DW_Language_C: + result = RDI_Language_C; + break; + + case DW_Language_CPlusPlus03: + case DW_Language_CPlusPlus11: + case DW_Language_CPlusPlus14: + case DW_Language_CPlusPlus: + result = RDI_Language_CPlusPlus; + break; + + default: NotImplemented; break; + } + return result; +} + +internal RDI_RegCodeX86 +rdi_reg_from_dw_reg_x86(DW_RegX86 v) +{ + RDI_RegCodeX86 result = RDI_RegCode_nil; + switch (v) { +#define X(reg_dw, val_dw, reg_rdi, ...) case DW_RegX86_##reg_dw: result = RDI_RegCodeX86_##reg_rdi; break; + DW_Regs_X86_XList(X) +#undef X + default: NotImplemented; break; + } + return result; +} + +internal B32 +rdi_reg_from_dw_reg_x64(DW_RegX64 v, RDI_RegCodeX64 *code_out, U64 *off_out, U64 *size_out) +{ + RDI_RegCodeX64 result = RDI_RegCode_nil; + switch (v) { +#define X(reg_dw, val_dw, reg_rdi, off, size) case DW_RegX64_##reg_dw: result = RDI_RegCodeX64_##reg_rdi; *off_out = off; *size_out = size; break; + DW_Regs_X64_XList(X) +#undef X + default: NotImplemented; break; + } + return result; +} + +internal B32 +rdi_reg_from_dw_reg(Arch arch, DW_Reg v, RDI_RegCode *code_out, U64 *off_out, U64 *size_out) +{ + RDI_RegCode result = RDI_RegCode_nil; + switch (arch) { + case Arch_Null: break; + case Arch_x86: ; break; + case Arch_x64: return rdi_reg_from_dw_reg_x64(v, code_out, off_out, size_out); + default: NotImplemented; break; + } + return 0; +} + diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.h b/src/rdi_from_dwarf/rdi_from_dwarf.h index c5ea8251..63d27b32 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.h +++ b/src/rdi_from_dwarf/rdi_from_dwarf.h @@ -1,50 +1,69 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef RDI_FROM_DWARF_H -#define RDI_FROM_DWARF_H +#pragma once + +typedef U64 D2R_ConvertFlags; +enum +{ +#define X(t,n,k) D2R_ConvertFlag_##t = (1ull << RDI_SectionKind_##t), + RDI_SectionKind_XList +#undef X + D2R_ConvertFlag_StrictParse, +}; + +typedef struct D2R_User2Convert +{ + String8 input_exe_name; + String8 input_exe_data; + String8 input_debug_name; + String8 input_debug_data; + String8 output_name; + D2R_ConvertFlags flags; + String8List errors; +} D2R_User2Convert; + +typedef struct D2R_TypeTable +{ + HashTable *ht; + RDIM_TypeChunkList *types; + U64 type_chunk_cap; + RDIM_Type *void_type; + RDIM_Type *varg_type; +} D2R_TypeTable; + +typedef struct D2R_TagNode +{ + struct D2R_TagNode *next; + DW_TagNode *cur_node; + RDIM_Type *type; + RDIM_Scope *scope; +} D2R_TagNode; + +typedef struct D2R_CompUnitContribMap +{ + U64 count; + U64 *info_off_arr; + RDIM_Rng1U64List *voff_range_arr; +} D2R_CompUnitContribMap; //////////////////////////////// -//~ Program Parameters Type +// Command Line -> Conversion Inputs -typedef struct DWARFCONV_Params{ - String8 input_elf_name; - String8 input_elf_data; - - String8 output_name; - - U64 unit_idx_min; - U64 unit_idx_max; - - struct{ - B8 input; - } hide_errors; - - B8 dump; - B8 dump__first; - B8 dump_header; - B8 dump_sections; - B8 dump_segments; - B8 dump_symtab; - B8 dump_dynsym; - B8 dump_debug_sections; - B8 dump_debug_info; - B8 dump_debug_abbrev; - B8 dump_debug_pubnames; - B8 dump_debug_pubtypes; - B8 dump_debug_names; - B8 dump_debug_aranges; - B8 dump_debug_addr; - B8 dump__last; - - String8List errors; -} DWARFCONV_Params; +internal D2R_User2Convert * d2r_user2convert_from_cmdln(Arena *arena, CmdLine *cmdline); //////////////////////////////// -//~ Program Parameters Parser +// Top-Level Conversion Entry Point -static DWARFCONV_Params *dwarf_convert_params_from_cmd_line(Arena *arena, CmdLine *cmdline); +internal RDIM_BakeParams * d2r_convert (Arena *arena, D2R_User2Convert *in); +internal RDIM_BakeResults d2r_bake (RDIM_HelpState *state, RDIM_BakeParams *in); +internal RDIM_SerializedSectionBundle d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in); +//////////////////////////////// +// Enum Conversion +internal RDI_Language rdi_language_from_dw_language(DW_Language v); +internal RDI_RegCodeX86 rdi_reg_from_dw_reg_x86(DW_RegX86 v); +internal B32 rdi_reg_from_dw_reg_x64(DW_RegX64 v, RDI_RegCodeX64 *code_out, U64 *off_out, U64 *size_out); +internal B32 rdi_reg_from_dw_reg(Arch arch, DW_Reg v, RDI_RegCode *code_out, U64 *off_out, U64 *size_out); -#endif //RDI_FROM_DWARF_H diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_main.c b/src/rdi_from_dwarf/rdi_from_dwarf_main.c new file mode 100644 index 00000000..32ea0331 --- /dev/null +++ b/src/rdi_from_dwarf/rdi_from_dwarf_main.c @@ -0,0 +1,122 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#define BUILD_TITLE "Epic Games Tools (R) DWARF Converter" +#define BUILD_CONSOLE_INTERFACE 1 + +//////////////////////////////// + +#include "third_party/rad_lzb_simple/rad_lzb_simple.h" +#include "third_party/rad_lzb_simple/rad_lzb_simple.c" +#include "third_party/xxHash/xxhash.c" +#include "third_party/xxHash/xxhash.h" + +//////////////////////////////// + +#include "lib_rdi_format/rdi_format.h" +#include "lib_rdi_format/rdi_format.c" +#include "lib_rdi_format/rdi_format_parse.h" +#include "lib_rdi_format/rdi_format_parse.c" + +//////////////////////////////// + +#include "base/base_inc.h" +#include "os/os_inc.h" +#include "async/async.h" +#include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" +#include "linker/path_ext/path.h" +#include "linker/hash_table.h" +#include "coff/coff.h" +#include "coff/coff_parse.h" +#include "dwarf/dwarf.h" +#include "dwarf/dwarf_parse.h" +#include "dwarf/dwarf_coff.h" +#include "pe/pe.h" +#include "linker/rdi/rdi_coff.h" +#include "rdi_from_dwarf/rdi_from_dwarf.h" + +#include "base/base_inc.c" +#include "os/os_inc.c" +#include "async/async.c" +#include "coff/coff.c" +#include "coff/coff_parse.c" +#include "pe/pe.c" +#include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" +#include "linker/rdi/rdi_coff.c" +#include "linker/path_ext/path.c" +#include "linker/hash_table.c" +#include "dwarf/dwarf.c" +#include "dwarf/dwarf_parse.c" +#include "dwarf/dwarf_coff.c" +#include "rdi_from_dwarf/rdi_from_dwarf.c" + +//////////////////////////////// +// Entry Point + +internal void +entry_point(CmdLine *cmdline) +{ + // initialize state and unpack command line + Arena *arena = arena_alloc(); + B32 do_help = (cmd_line_has_flag(cmdline, str8_lit("help")) || + cmd_line_has_flag(cmdline, str8_lit("h")) || + cmd_line_has_flag(cmdline, str8_lit("?"))); + + D2R_User2Convert *user2convert = d2r_user2convert_from_cmdln(arena, cmdline); + + // display help + if (do_help) { + fprintf(stderr, "--- rdi_from_dwarf ------------------------------------------------------------\n\n"); + + fprintf(stderr, "This utility converts debug information from DWARF into the RAD Debug Info\n"); + fprintf(stderr, "format. The following arguments are accepted:\n\n"); + + fprintf(stderr, "--exe: [optional] Specifies the path of the executable filefor which the\n"); + fprintf(stderr, " debug info was generated.\n"); + fprintf(stderr, "--debug: Specifies the path of the .DEBUG debug info file to\n"); + fprintf(stderr, " convert.\n"); + fprintf(stderr, "--out: Specifies the path at which the output will be written.\n\n"); + + if (!do_help) { + for (String8Node *n = user2convert->errors.first; n != 0; n = n->next) { + fprintf(stderr, "error(input): %.*s\n", str8_varg(n->string)); + } + } + + os_abort(0); + } + + RDIM_HelpState *rdim_help_state = rdim_help_init(); + + ProfBegin("convert"); + RDIM_BakeParams *convert2bake = d2r_convert(arena, user2convert); + ProfEnd(); + + ProfBegin("bake"); + RDIM_BakeResults bake2srlz = d2r_bake(rdim_help_state, convert2bake); + ProfEnd(); + + ProfBegin("serialize bake"); + RDIM_SerializedSectionBundle srlz2file = rdim_serialized_section_bundle_from_bake_results(&bake2srlz); + ProfEnd(); + + RDIM_SerializedSectionBundle srlz2file_compressed = srlz2file; + if (cmd_line_has_flag(cmdline, str8_lit("compress"))) { + ProfBegin("compress"); + srlz2file_compressed = d2r_compress(arena, srlz2file); + ProfEnd(); + } + + ProfBegin("serialize blobs"); + String8List blobs = rdim_file_blobs_from_section_bundle(arena, &srlz2file_compressed); + ProfEnd(); + + ProfBegin("write"); + if (!os_write_data_list_to_file_path(user2convert->output_name, blobs)) { + fprintf(stderr, "error(ouptut): unable to write to %.*s\n", str8_varg(user2convert->output_name)); + } + ProfEnd(); +} + From 4298f3d5f6086c2e1d5b26a4619e81c3d30e9f1e Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 17 Mar 2025 13:29:52 -0700 Subject: [PATCH 214/755] typo --- src/linker/lnk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 83c368db..8e7668d8 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -3285,7 +3285,7 @@ lnk_run(int argc, char **argv) switch (state) { case State_Null: break; case State_SearchEntryPoint: { - ProfBegin("Serach Entry Point"); + ProfBegin("Search Entry Point"); LNK_Symbol *entry_point_symbol = 0; B32 is_entry_point_unspecified = config->entry_point_name.size == 0; From 344cd8ffbf745ae66778abf69c8cdfcc98ae7db2 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 17 Mar 2025 14:20:20 -0700 Subject: [PATCH 215/755] use djb2 hash for now --- src/rdi_make/rdi_make_help.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c index d3b039ac..f85d38a1 100644 --- a/src/rdi_make/rdi_make_help.c +++ b/src/rdi_make/rdi_make_help.c @@ -419,7 +419,13 @@ ASYNC_WORK_DEF(rdim_bake_idx_runs_work) internal U64 rdim_help_hash(RDIM_String8 string) { - return XXH3_64bits(string.str, string.size); + U64 hash = 5381; + U8 *ptr = string.str; + U8 *opl = string.str + string.size; + for (;ptr < opl; ++ptr) { + hash = ((hash << 5) + hash) + (*ptr); + } + return hash; } internal void From 1dc01923226b33affd48567e939ca4351c2b2e07 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 17 Mar 2025 15:25:49 -0700 Subject: [PATCH 216/755] fix clang warning and errors --- src/dwarf/dwarf_parse.c | 4 ++-- src/linker/hash_table.c | 11 ++++++++++- src/rdi_from_dwarf/rdi_from_dwarf_main.c | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dwarf/dwarf_parse.c b/src/dwarf/dwarf_parse.c index e0cd5e4e..0e34a29a 100644 --- a/src/dwarf/dwarf_parse.c +++ b/src/dwarf/dwarf_parse.c @@ -1787,7 +1787,7 @@ dw_rnglist_from_attrib_ptr(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_At { Rng1U64List rnglist = {0}; DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); - if (value_class == DW_AttribClass_RngListPtr || DW_AttribClass_RngList) { + if (value_class == DW_AttribClass_RngListPtr || value_class == DW_AttribClass_RngList) { rnglist = dw_interp_rnglist(arena, input, cu, attrib->form_kind, attrib->form); } else if (value_class != DW_AttribClass_Null) { Assert(!"unexpected value class"); @@ -1947,7 +1947,7 @@ dw_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) internal U32 dw_byte_size_32_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) { - U32 byte_size32; + U32 byte_size32 = 0; U64 byte_size64; if (dw_try_byte_size_from_tag(input, cu, tag, &byte_size64)) { byte_size32 = safe_cast_u32(byte_size64); diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index ae70ab2a..cbb478ad 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -4,7 +4,16 @@ internal void bucket_list_concat_in_place(BucketList *list, BucketList *to_concat) { - SLLConcatInPlaceNoCount(list, to_concat); + if (to_concat->first) { + if (list->first) { + list->last->next = to_concat->first; + list->last = to_concat->last; + } else { + list->first = to_concat->first; + list->last = to_concat->last; + } + MemoryZeroStruct(to_concat); + } } internal BucketNode * diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_main.c b/src/rdi_from_dwarf/rdi_from_dwarf_main.c index 32ea0331..07c2410f 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf_main.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf_main.c @@ -10,6 +10,7 @@ #include "third_party/rad_lzb_simple/rad_lzb_simple.c" #include "third_party/xxHash/xxhash.c" #include "third_party/xxHash/xxhash.h" +#include "third_party/radsort/radsort.h" //////////////////////////////// From 6a44f6485d4bc733b67016d8ce70e1aa25566c0d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 18 Mar 2025 16:30:14 -0700 Subject: [PATCH 217/755] eliminate old and now unused parts of hover eval state --- src/raddbg/raddbg_core.c | 14 +------------- src/raddbg/raddbg_core.h | 9 --------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1ee9adf8..94adf190 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8435,19 +8435,10 @@ rd_window_frame(void) EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); - // rjf: reset open animation - if(ws->hover_eval_string.size == 0) - { - ws->hover_eval_open_t = 0; - ws->hover_eval_num_visible_rows_t = 0; - } - - // rjf: reset animation, but request frames if we're waiting to open + // rjf: request frames if we're waiting to open if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && ws->hover_eval_last_frame_idx < ws->hover_eval_first_frame_idx+20 && rd_state->frame_index-ws->hover_eval_last_frame_idx < 50) { rd_request_frame(); - ws->hover_eval_num_visible_rows_t = 0; - ws->hover_eval_open_t = 0; } // rjf: reset focus state if hover eval is not being built @@ -10849,9 +10840,6 @@ rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 s arena_clear(ws->hover_eval_arena); ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); ws->hover_eval_view_rules = push_str8_copy(ws->hover_eval_arena, view_rules); - ws->hover_eval_file_path = push_str8_copy(ws->hover_eval_arena, file_path); - ws->hover_eval_file_pt = pt; - ws->hover_eval_vaddr = vaddr; ws->hover_eval_focused = 0; } ws->hover_eval_spawn_pos = pos; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 3a028c2d..ee277276 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -589,21 +589,12 @@ struct RD_WindowState // rjf: hover eval state B32 hover_eval_focused; - TxtPt hover_eval_txt_cursor; - TxtPt hover_eval_txt_mark; - U8 hover_eval_txt_buffer[1024]; - U64 hover_eval_txt_size; Arena *hover_eval_arena; Vec2F32 hover_eval_spawn_pos; String8 hover_eval_string; String8 hover_eval_view_rules; U64 hover_eval_first_frame_idx; U64 hover_eval_last_frame_idx; - String8 hover_eval_file_path; - TxtPt hover_eval_file_pt; - U64 hover_eval_vaddr; - F32 hover_eval_open_t; - F32 hover_eval_num_visible_rows_t; // rjf: error state U8 error_buffer[512]; From eaa3711405a56c6e8c2b69242e3dbbd851651541 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 06:31:18 -0700 Subject: [PATCH 218/755] dead code elimination / small fixes in collection query eval --- src/raddbg/raddbg_core.c | 8 ++++---- src/raddbg/raddbg_core.h | 24 +----------------------- src/raddbg/raddbg_views.c | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 94adf190..03b6cafa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13676,7 +13676,7 @@ rd_frame(void) String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), @@ -13754,7 +13754,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCfg); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(cfg), @@ -13772,7 +13772,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), @@ -13799,7 +13799,7 @@ rd_frame(void) E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ee277276..0d25ce8c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -82,6 +82,7 @@ typedef U64 RD_EvalSpaceKind; enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, + RD_EvalSpaceKind_MetaQuery, RD_EvalSpaceKind_MetaCfg, RD_EvalSpaceKind_MetaCmd, RD_EvalSpaceKind_MetaCtrlEntity, @@ -437,21 +438,6 @@ typedef enum RD_FontSlot } RD_FontSlot; -typedef enum RD_PaletteCode -{ - RD_PaletteCode_Base, - RD_PaletteCode_MenuBar, - RD_PaletteCode_Good, - RD_PaletteCode_Bad, - RD_PaletteCode_Pop, - RD_PaletteCode_ScrollBar, - RD_PaletteCode_Tab, - RD_PaletteCode_TabInactive, - RD_PaletteCode_DropSite, - RD_PaletteCode_COUNT -} -RD_PaletteCode; - //////////////////////////////// //~ rjf: Lister Types @@ -579,14 +565,6 @@ struct RD_WindowState String8 query_cmd_name; RD_Regs *query_regs; - // rjf: query view stack -#if 0 - Arena *query_cmd_arena; - String8 query_cmd_name; - RD_Regs *query_cmd_regs; - U64 query_cmd_regs_mask[(RD_RegSlot_COUNT + 63) / 64]; -#endif - // rjf: hover eval state B32 hover_eval_focused; Arena *hover_eval_arena; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9fd3b210..a54b9342 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -993,15 +993,22 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine ctrl entity - if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); } // rjf: determine cfg group name / parent - if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfg) + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) { info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); + } + + // rjf: determine group cfg name + if(block_type_kind == E_TypeKind_Set) + { String8 singular_name = rd_singular_from_code_name_plural(block_type->name); if(singular_name.size != 0) { @@ -1134,6 +1141,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } + // rjf: singular row for queries + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaQuery) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + // rjf: singular button for unattached processes else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { From 7d4d8762b7bd29929e57d21410516c449e385d11 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 10:30:50 -0700 Subject: [PATCH 219/755] collapse query/hover-eval building paths into single floating-view-build path --- src/raddbg/raddbg_core.c | 841 ++++++++++++++++++------------------ src/raddbg/raddbg_core.h | 7 +- src/raddbg/raddbg_widgets.c | 12 +- 3 files changed, 421 insertions(+), 439 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 03b6cafa..77c5d55c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6349,7 +6349,7 @@ rd_window_frame(void) ProfBeginFunction(); ////////////////////////////// - //- rjf: unpack context + //- rjf: @window_frame_part unpack context // RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window)); @@ -6357,11 +6357,12 @@ rd_window_frame(void) B32 window_is_focused = (os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc); B32 popup_is_open = (rd_state->popup_active); B32 query_is_open = (ws->query_is_active); + U64 hover_eval_open_delay_us = 400000; B32 hover_eval_is_open = (!popup_is_open && !query_is_open && ws->hover_eval_string.size != 0 && - ws->hover_eval_first_frame_idx+20 < ws->hover_eval_last_frame_idx && - rd_state->frame_index-ws->hover_eval_last_frame_idx < 20); + ws->hover_eval_firstt_us+hover_eval_open_delay_us < ws->hover_eval_lastt_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us); if(!window_is_focused || popup_is_open) { ws->menu_bar_key_held = 0; @@ -6370,7 +6371,7 @@ rd_window_frame(void) ui_select_state(ws->ui); ////////////////////////////// - //- rjf: compute window's theme + //- rjf: @window_frame_part compute window's theme // { //- rjf: for this window, scan upwards, and then try the project, then the user, until we @@ -6488,7 +6489,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: pre-emptively rasterize common glyphs on the first frame + //- rjf: @window_frame_part pre-emptively rasterize common glyphs on the first frame // if(rd_state->first_window_state == ws && rd_state->last_window_state == ws && ws->frames_alive == 0) { @@ -6534,7 +6535,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: commit window's position/status to underlying cfg tree + //- rjf: @window_frame_part commit window's position/status to underlying cfg tree // { Temp scratch = scratch_begin(0, 0); @@ -6622,49 +6623,19 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: fill panel/view interaction registers + //- rjf: @window_frame_part fill panel/view interaction registers // rd_regs()->panel = panel_tree.focused->cfg->id; rd_regs()->view = panel_tree.focused->selected_tab->id; ////////////////////////////// - //- rjf: gather listers - // - typedef struct ListerTask ListerTask; - struct ListerTask - { - ListerTask *next; - RD_Lister *lister; - UI_Key root_key; - }; - ListerTask *first_lister_task = 0; - ListerTask *last_lister_task = 0; - ProfScope("build all listers") - { - if(ws->autocomp_lister != 0 && ws->autocomp_lister_last_frame_idx+1 >= rd_state->frame_index) - { - ListerTask *task = push_array(scratch.arena, ListerTask, 1); - SLLQueuePush(first_lister_task, last_lister_task, task); - task->lister = ws->autocomp_lister; - task->root_key = ui_key_from_stringf(ui_key_zero(), "###lister_%p", task->lister); - } - if(ws->top_query_lister != 0) - { - ListerTask *task = push_array(scratch.arena, ListerTask, 1); - SLLQueuePush(first_lister_task, last_lister_task, task); - task->lister = ws->top_query_lister; - task->root_key = ui_key_from_stringf(ui_key_zero(), "###lister_%p", task->lister); - } - } - - ////////////////////////////// - //- rjf: build UI + //- rjf: @window_frame_part build UI // UI_Box *lister_box = &ui_nil_box; ProfScope("build UI") { //////////////////////////// - //- rjf: set up + //- rjf: @window_ui_part set up // { // rjf: gather font info @@ -6714,7 +6685,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: calculate top-level rectangles + //- rjf: @window_ui_part calculate top-level rectangles/sizes // Rng2F32 window_rect = os_client_rect_from_window(ws->os); Vec2F32 window_rect_dim = dim_2f32(window_rect); @@ -6725,7 +6696,7 @@ rd_window_frame(void) content_rect = pad_2f32(content_rect, -window_edge_px); //////////////////////////// - //- rjf: truncated string hover + //- rjf: @window_ui_part truncated string hover // if(ui_string_hover_active()) UI_Tooltip { @@ -6737,7 +6708,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: drag/drop tooltips + //- rjf: @window_ui_part drag/drop tooltips // if(rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) { @@ -6918,7 +6889,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: drag/drop visualization tooltips + //- rjf: @window_ui_part drag/drop visualization tooltips // if(rd_drag_is_active() && window_is_focused) RD_RegsScope(.window = rd_state->drag_drop_regs->window, @@ -6968,7 +6939,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: developer menu + //- rjf: @window_ui_part developer menu // if(ws->dev_menu_is_open) RD_Font(RD_FontSlot_Code) { @@ -7090,7 +7061,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: top-level registers context menu + //- rjf: @window_ui_part top-level registers context menu // UI_CtxMenu(rd_state->ctx_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { @@ -7352,7 +7323,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: drop-completion context menu + //- rjf: @window_ui_part drop-completion context menu // if(ws->drop_completion_paths.node_count != 0) { @@ -7429,7 +7400,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: popup + //- rjf: @window_ui_part popup // { if(rd_state->popup_t > 0.005f) UI_TextAlignment(UI_TextAlign_Center) UI_Focus(rd_state->popup_active ? UI_FocusKind_Root : UI_FocusKind_Off) @@ -7479,108 +7450,328 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: build query + //- rjf: @window_ui_part gather all tasks to build floating views // - if(query_is_open) + typedef struct FloatingViewTask FloatingViewTask; + struct FloatingViewTask { - //- rjf: unpack query parameters - String8 cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); - B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); - - //- rjf: build & prepare view for query ui - RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - rd_cfg_new_replace(cmd, cmd_name); - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->query_is_selected = 1; - String8 query_expression = cmd_kind_info->query.expr; - if(query_expression.size == 0) + FloatingViewTask *next; + RD_Cfg *view; + F32 row_height_px; + Rng2F32 rect; + String8 view_name; + String8 expr; + B32 is_focused; + UI_Signal signal; // NOTE(rjf): output, from build + }; + FloatingViewTask *hover_eval_floating_view_task = 0; + FloatingViewTask *query_floating_view_task = 0; + FloatingViewTask *first_floating_view_task = 0; + FloatingViewTask *last_floating_view_task = 0; + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + { + //- rjf: try to add hover eval first + if(ws->hover_eval_string.size != 0) { - query_expression = str8(vs->query_buffer, vs->query_string_size); + B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); + + // rjf: disable hover eval if hovered view is actively scrolling + if(hover_eval_is_open) + { + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + if(panel->first != &rd_nil_panel_node) { continue; } + RD_Cfg *tab = panel->selected_tab; + if(tab != &rd_nil_cfg) + { + RD_ViewState *vs = rd_view_state_from_cfg(tab); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + if(contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(vs->scroll_pos.x.off) > 0.01f || + abs_f32(vs->scroll_pos.y.off) > 0.01f)) + { + build_hover_eval = 0; + ws->hover_eval_firstt_us = rd_state->time_in_us; + } + } + } + } + + // rjf: choose hover evaluation expression + String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + + // rjf: evaluate hover evaluation expression, & determine if it evaluates + // such that we want to build a hover eval. + E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + { + if(hover_eval.msgs.max_kind > E_MsgKind_Null) + { + build_hover_eval = 0; + } + else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) + { + build_hover_eval = 0; + } + else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) + { + build_hover_eval = 0; + } + } + + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + + // rjf: determine view name + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } + + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); - } - else - { - U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); - if(input_insertion_pos < query_expression.size) + + // rjf: request frames if we're waiting to open + if(ws->hover_eval_string.size != 0 && + !hover_eval_is_open && + ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) { - String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); - String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); - query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + rd_request_frame(); + } + + // rjf: reset focus state if hover eval is not being built + if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) + { + ws->hover_eval_focused = 0; + } + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id) + { + predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + } + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); + F32 width_px = 60.f*ui_top_font_size(); + F32 height_px = num_rows_t*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = 40.f*ui_top_font_size(); + } + + // rjf: determine hover eval top-level rect + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + + // rjf: push hover eval task + if(build_hover_eval) + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + hover_eval_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = view_name; + t->expr = hover_eval_expr; + t->is_focused = ws->hover_eval_focused; } - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); - } - rd_cfg_new_replace(expr, query_expression); - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - - //- rjf: cancel - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); } - //- rjf: build - RD_RegsScope(.view = view->id) + //- rjf: try to add opened query + if(query_is_open) { - Vec2F32 content_rect_center = center_2f32(content_rect); - Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); - F32 query_open_t = ui_anim(ui_key_from_string(ui_key_zero(), str8_lit("query_open_t")), 1.f); - F32 query_width_px = floor_f32(dim_2f32(content_rect).x * 0.35f); - F32 max_query_height_px = content_rect_dim.y*0.8f; - F32 query_height_px = max_query_height_px; - if(size_query_by_expr_eval) + if(ui_slot_press(UI_EventActionSlot_Cancel)) { - query_height_px = row_height_px*predicted_block_tree.total_row_count; - query_height_px = Min(query_height_px, max_query_height_px); + rd_cmd(RD_CmdKind_CancelQuery); } - Rng2F32 query_rect = r2f32p(content_rect_center.x - query_width_px/2, - content_rect_center.y - max_query_height_px/2.f, - content_rect_center.x + query_width_px/2, - content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); - if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + + // rjf: unpack query info + String8 cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); + B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + + // rjf: build view for query + RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_is_selected = 1; + + // rjf: compute query expression + String8 query_expression = cmd_kind_info->query.expr; + if(query_expression.size == 0) { - UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); - if(anchor_box != &ui_nil_box) + query_expression = str8(vs->query_buffer, vs->query_string_size); + } + else + { + U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expression.size) { - query_rect.x0 = anchor_box->rect.x0; - query_rect.y0 = anchor_box->rect.y1; - query_rect.x1 = query_rect.x0 + ui_top_font_size()*40.f; - query_rect.y1 = query_rect.y0 + query_height_px; + String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); + String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); + query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); } } - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_TagF("floating") - UI_Focus(UI_FocusKind_On) + + // rjf: based on query expression, determine if we have an explicit root + if(query_expression.size == 0) + { + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + + // rjf: evaluate query expression + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); + + // rjf: compute query view's top-level rectangle + Rng2F32 rect = {0}; + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); + F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + if(size_query_by_expr_eval) + { + query_height_px = row_height_px*predicted_block_tree.total_row_count; + query_height_px = Min(query_height_px, max_query_height_px); + } + rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px); + } + + // rjf: push query task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + query_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = str8_lit("watch"); + t->expr = query_expression; + t->is_focused = 1; + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part build all floating views + // + ProfScope("build all floating views") + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + { + for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) + { + // rjf: unpack + RD_Cfg *view = t->view; + F32 row_height_px = t->row_height_px; + Rng2F32 rect = t->rect; + String8 view_name = t->view_name; + String8 expr = t->expr; + B32 is_focused = t->is_focused; + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f); + + // rjf: build cfg tree + RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(view, str8_lit("selected")); + rd_cfg_new_replace(expr_root, expr); + + // rjf: push view regs + rd_push_regs(.view = view->id); + { + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + // rjf: build + UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) UI_PrefHeight(ui_px(row_height_px, 1.f)) { - //- rjf: build top-level container + // rjf: build top-level container box UI_Box *container = &ui_nil_box; - UI_Rect(query_rect) - UI_Squish(0.25f-0.25f*query_open_t) - UI_Transparency(1.f-query_open_t) - UI_ChildLayoutAxis(Axis2_Y) + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.25f-0.25f*open_t) UI_Transparency(1.f-open_t) { - container = ui_build_box_from_string(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow, - str8_lit("query_container")); + container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow, + "floating_view_container_%p", view); } - //- rjf: fill container - UI_Parent(container) UI_Focus(UI_FocusKind_Null) + // rjf: peek press events -> focus hover eval if we have a press + if(!ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + contains_2f32(container->rect, evt->pos)) + { + ws->hover_eval_focused = 1; + break; + } + } + } + + // rjf: build overlay container for loading animation + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(container) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + // rjf: build contents + UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) { ui_set_next_pref_width(ui_pct(1, 0)); ui_set_next_pref_height(ui_pct(1, 0)); @@ -7588,35 +7779,95 @@ rd_window_frame(void) UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); UI_Parent(view_contents_container) UI_WidthFill { - rd_view_ui(view_contents_container->rect); + rd_view_ui(rect); } } - //- rjf: fallthrough interactions on container + // rjf: build loading overlay + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + F32 loading_t = vs->loading_t; + if(loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + // rjf: interact with container UI_Signal sig = ui_signal_from_box(container); + t->signal = sig; } - } - - //- rjf: any queries which take a file path mutate the debugger's "current path" - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) - { - RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); - if(input != &rd_nil_cfg) + + // rjf: pop interaction registers; commit if this is focused + RD_Regs *view_regs = rd_pop_regs(); + if(is_focused) { - String8 path_chopped = str8_chop_last_slash(input->first->string); - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + MemoryCopyStruct(rd_regs(), view_regs); } } - - //- rjf: build darkening rectangle over rest of screen - if(!query_is_anchored) UI_Rect(window_rect) UI_TagF("inactive") - { - ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero()); - } } //////////////////////////// - //- rjf: top bar + //- rjf: @window_ui_part do special handling of floating view interactions + // + { + //- rjf: hover eval focus rules + if(hover_eval_floating_view_task) + { + UI_Signal sig = hover_eval_floating_view_task->signal; + if(ui_pressed(sig)) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_lastt_us = rd_state->time_in_us; + } + else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) + { + rd_request_frame(); + } + if(ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + !contains_2f32(hover_eval_floating_view_task->rect, evt->pos)) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + break; + } + } + } + } + + //- rjf: query interactions + if(query_floating_view_task) + { + String8 cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *view = query_floating_view_task->view; + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) + { + String8 path_chopped = str8_chop_last_slash(input->first->string); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part top bar // ProfScope("build top bar") { @@ -8382,238 +8633,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: build hover eval - // - ProfScope("build hover eval") - { - B32 build_hover_eval = hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View); - - // rjf: disable hover eval if hovered view is actively scrolling - if(hover_eval_is_open) - { - for(RD_PanelNode *panel = panel_tree.root; - panel != &rd_nil_panel_node; - panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) - { - if(panel->first != &rd_nil_panel_node) { continue; } - RD_Cfg *tab = panel->selected_tab; - if(tab != &rd_nil_cfg) - { - RD_ViewState *vs = rd_view_state_from_cfg(tab); - Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); - if(contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(vs->scroll_pos.x.off) > 0.01f || - abs_f32(vs->scroll_pos.y.off) > 0.01f)) - { - build_hover_eval = 0; - ws->hover_eval_first_frame_idx = rd_state->frame_index; - } - } - } - } - - // rjf: evaluate hover-evaluation expression - if it doesn't evaluate, then don't build anything - String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); - E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); - if(hover_eval.msgs.max_kind > E_MsgKind_Null) - { - build_hover_eval = 0; - } - else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && - rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) - { - build_hover_eval = 0; - } - else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && - rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) - { - build_hover_eval = 0; - } - - // rjf: determine if we have a top-level visualizer - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); - - // rjf: request frames if we're waiting to open - if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && ws->hover_eval_last_frame_idx < ws->hover_eval_first_frame_idx+20 && rd_state->frame_index-ws->hover_eval_last_frame_idx < 50) - { - rd_request_frame(); - } - - // rjf: reset focus state if hover eval is not being built - if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) - { - ws->hover_eval_focused = 0; - } - - // rjf: build hover eval - if(build_hover_eval && ws->hover_eval_string.size != 0 && hover_eval_is_open) - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_TagF("floating") - { - // rjf: build cfg tree for temporary view - String8 view_name = str8_lit("watch"); - if(view_ui_rule != &rd_nil_view_ui_rule) - { - view_name = view_ui_rule->name; - } - F32 hover_eval_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_open_t"), 1.f); - RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_%p", ws); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(view, str8_lit("selected")); - rd_cfg_new(explicit_root, str8_lit("1")); - rd_cfg_new_replace(expr, hover_eval_expr); - - // rjf: push view regs - rd_push_regs(.view = view->id); - { - String8 view_expr = rd_expr_from_cfg(view); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - // NOTE(rjf): we want to only fill out this view's file path slot if it - // evaluates one - this way, a view can use the slot to know the selected - // file path (if there is one). this is useful when pushing commandas which - // apply to a cursor, for example. - if(view_file_path.size != 0) - { - rd_regs()->file_path = view_file_path; - } - } - - // rjf: determine size of hover evaluation container - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); - if(ws->hover_eval_focused) - { - max_row_count *= 3; - } - U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); - F32 width_px = 60.f*ui_top_font_size(); - F32 height_px = num_rows_t*row_height_px; - - // rjf: if arbitrary visualizer, pick catchall size - if(view_ui_rule != &rd_nil_view_ui_rule) - { - height_px = 40.f*ui_top_font_size(); - } - - // rjf: build container - UI_Focus(ws->hover_eval_focused ? UI_FocusKind_On : UI_FocusKind_Off) - UI_PrefHeight(ui_px(row_height_px, 1.f)) - { - // rjf: build top-level container box - Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, - ws->hover_eval_spawn_pos.y, - ws->hover_eval_spawn_pos.x + width_px, - ws->hover_eval_spawn_pos.y + height_px); - ui_set_next_fixed_x(rect.x0); - ui_set_next_fixed_y(rect.y0); - ui_set_next_pref_width(ui_px(rect.x1-rect.x0, 1.f)); - ui_set_next_pref_height(ui_px(rect.y1-rect.y0, 1.f)); - ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_squish(0.25f-0.25f*hover_eval_t); - ui_set_next_transparency(1.f-hover_eval_t); - UI_Box *container = ui_build_box_from_string(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow, - str8_lit("hover_eval_container")); - - // rjf: peek press events -> focus hover eval if we have a press - if(!ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 1; - break; - } - } - } - - // rjf: build overlay container for loading animation - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(container) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); - } - - // rjf: build contents - UI_Parent(container) UI_Focus(ws->hover_eval_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - { - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_WidthFill - { - rd_view_ui(rect); - } - } - - // rjf: build loading overlay - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - F32 loading_t = vs->loading_t; - if(loading_t > 0.01f) UI_Parent(loading_overlay_container) - { - rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); - } - } - - // rjf: interact with container - UI_Signal sig = ui_signal_from_box(container); - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_mouse_over(sig) || ws->hover_eval_focused) - { - ws->hover_eval_last_frame_idx = rd_state->frame_index; - } - else if(ws->hover_eval_last_frame_idx+2 < rd_state->frame_index) - { - rd_request_frame(); - } - if(ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - !contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 0; - MemoryZeroStruct(&ws->hover_eval_string); - arena_clear(ws->hover_eval_arena); - rd_request_frame(); - break; - } - } - } - } - - // rjf: pop interaction registers; commit if this is the selected view - RD_Regs *view_regs = rd_pop_regs(); - if(ws->hover_eval_focused) - { - MemoryCopyStruct(rd_regs(), view_regs); - } - } - } - - //////////////////////////// - //- rjf: bottom bar + //- rjf: @window_ui_part bottom bar // ProfScope("build bottom bar") { @@ -8710,7 +8730,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: panel non-leaf UI (drag boundaries, drag/drop sites) + //- rjf: @window_ui_part panel non-leaf UI (drag boundaries, drag/drop sites) // B32 is_changing_panel_boundaries = 0; ProfScope("non-leaf panel UI") @@ -9010,7 +9030,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: animate panels + //- rjf: @window_ui_part animate panels // { Vec2F32 content_rect_dim = dim_2f32(content_rect); @@ -9036,7 +9056,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: panel leaf UI + //- rjf: @window_ui_part panel leaf UI // if(content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0) { @@ -9794,7 +9814,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: drag/drop cancelling + //- rjf: @window_ui_part drag/drop cancelling // if(rd_drag_is_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { @@ -9803,7 +9823,7 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: font size changing + //- rjf: @window_ui_part top-level font size changing // for(UI_Event *evt = 0; ui_next_event(&evt);) { @@ -9825,47 +9845,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: attach lister boxes to root, or hide if it has not been renewed - // - for(ListerTask *task = first_lister_task; task != 0; task = task->next) - { - RD_Lister *lister = task->lister; - RD_Regs *regs = lister->regs; - UI_Box *lister_box = ui_box_from_key(task->root_key); - if(!ui_box_is_nil(lister_box) && (lister != ws->autocomp_lister || ws->autocomp_lister_last_frame_idx+1 >= rd_state->frame_index+1)) - { - UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); - if(!ui_box_is_nil(anchor_box)) - { - Vec2F32 size = lister_box->fixed_size; - lister_box->fixed_position = v2f32(anchor_box->rect.x0 + lister->regs->off_px.x, - anchor_box->rect.y0 + lister->regs->off_px.y); - lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); - for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) - { - ui_calc_sizes_standalone__in_place_rec(lister_box, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(lister_box, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(lister_box, axis); - ui_layout_enforce_constraints__in_place_rec(lister_box, axis); - ui_layout_position__in_place_rec(lister_box, axis); - } - } - } - else if(!ui_box_is_nil(lister_box) && lister == ws->autocomp_lister && ws->autocomp_lister_last_frame_idx+1 < rd_state->frame_index+1) - { - UI_Box *anchor_box = ui_box_from_key(lister->regs->ui_key); - if(!ui_box_is_nil(anchor_box)) - { - Vec2F32 size = lister_box->fixed_size; - Rng2F32 window_rect = os_client_rect_from_window(ws->os); - lister_box->fixed_position = v2f32(window_rect.x1, window_rect.y1); - lister_box->rect = r2f32(lister_box->fixed_position, add_2f32(lister_box->fixed_position, size)); - } - } - } - - ////////////////////////////// - //- rjf: hover eval cancelling + //- rjf: @window_frame_part hover eval cancelling // if(ws->hover_eval_string.size != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) { @@ -9875,7 +9855,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: animate + //- rjf: @window_frame_part animate // if(ui_animating_from_state(ws->ui)) { @@ -9883,7 +9863,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: draw UI + //- rjf: @window_frame_part draw UI // ws->draw_bucket = dr_bucket_make(); DR_BucketScope(ws->draw_bucket) @@ -10332,7 +10312,7 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: increment per-window frame counter + //- rjf: @window_frame_part increment per-window frame counter // ws->frames_alive += 1; @@ -10823,11 +10803,11 @@ rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U3 //~ rjf: Hover Eval internal void -rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string, String8 view_rules) +rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules) { RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(ws->hover_eval_last_frame_idx+1 < rd_state->frame_index && + if(ws->hover_eval_lastt_us < rd_state->time_in_us && ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero())) @@ -10836,14 +10816,14 @@ rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 s !str8_match(ws->hover_eval_view_rules, view_rules, 0)); if(is_new_string) { - ws->hover_eval_first_frame_idx = ws->hover_eval_last_frame_idx = rd_state->frame_index; + ws->hover_eval_firstt_us = ws->hover_eval_lastt_us = rd_state->time_in_us; arena_clear(ws->hover_eval_arena); ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); ws->hover_eval_view_rules = push_str8_copy(ws->hover_eval_arena, view_rules); ws->hover_eval_focused = 0; } ws->hover_eval_spawn_pos = pos; - ws->hover_eval_last_frame_idx = rd_state->frame_index; + ws->hover_eval_lastt_us = rd_state->time_in_us; } } @@ -17712,6 +17692,7 @@ Z(getting_started) // rd_state->frame_index += 1; rd_state->time_in_seconds += rd_state->frame_dt; + rd_state->time_in_us += frame_time_us; ////////////////////////////// //- rjf: bump command batch ring buffer generation diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 0d25ce8c..aad81239 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -571,8 +571,8 @@ struct RD_WindowState Vec2F32 hover_eval_spawn_pos; String8 hover_eval_string; String8 hover_eval_view_rules; - U64 hover_eval_first_frame_idx; - U64 hover_eval_last_frame_idx; + U64 hover_eval_firstt_us; + U64 hover_eval_lastt_us; // rjf: error state U8 error_buffer[512]; @@ -708,6 +708,7 @@ struct RD_State U64 frame_time_us_history[64]; U64 num_frames_requested; F64 time_in_seconds; + U64 time_in_us; // rjf: frame parameters F32 frame_dt; @@ -1084,7 +1085,7 @@ internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_Stri //////////////////////////////// //~ rjf: Hover Eval -internal void rd_set_hover_eval(Vec2F32 pos, String8 file_path, TxtPt pt, U64 vaddr, String8 string, String8 view_rules); +internal void rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules); //////////////////////////////// //~ rjf: Lister Functions diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b39dbc6f..347e15b3 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1388,7 +1388,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) @@ -1540,7 +1540,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); + rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } if(ui_right_clicked(thread_sig)) @@ -1619,7 +1619,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", bp->id), str8_zero()); + rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64u", bp->id), str8_zero()); RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1681,7 +1681,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(0, 0), 0, push_str8f(scratch.arena, "$%I64u", pin->id), str8_zero()); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64u", pin->id), str8_zero()); RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1939,7 +1939,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal pin_sig = ui_signal_from_box(pin_box); if(ui_key_match(pin_box_key, ui_hot_key())) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), str8_zero(), txt_pt(1, 1), 0, pin_expr, pin_view_rule); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr, pin_view_rule); } } } @@ -2262,7 +2262,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_idx = mouse_pt.line-params->line_num_range.min; line_vaddr = params->line_vaddrs[line_idx]; } - rd_set_hover_eval(mouse_expr_baseline_pos, rd_regs()->file_path, mouse_pt, line_vaddr, mouse_expr, str8_zero()); + rd_set_hover_eval(mouse_expr_baseline_pos, mouse_expr, str8_zero()); } } From d3e25567acc3dfe27ab50c20d05b14b1659b7964 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 15:30:47 -0700 Subject: [PATCH 220/755] convergence on listers / visual fixes --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 115 ++++++++++++++++++++--------- src/raddbg/raddbg_core.h | 12 --- src/raddbg/raddbg_widgets.c | 10 +-- src/ui/ui_core.c | 18 ++--- src/ui/ui_core.h | 1 + 8 files changed, 96 insertions(+), 70 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7ea36428..7efc35bd 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[297] = +RD_VocabInfo rd_vocab_info_table[298] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -143,6 +143,7 @@ RD_VocabInfo rd_vocab_info_table[297] = {str8_lit_comp("popup_cancel"), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("reset_to_default_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("reset_to_compact_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("reset_to_simple_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Simple Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("new_panel_left"), str8_lit_comp(""), str8_lit_comp("Split Panel Left"), str8_lit_comp(""), RD_IconKind_XSplit}, {str8_lit_comp("new_panel_up"), str8_lit_comp(""), str8_lit_comp("Split Panel Up"), str8_lit_comp(""), RD_IconKind_YSplit}, {str8_lit_comp("new_panel_right"), str8_lit_comp(""), str8_lit_comp("Split Panel Right"), str8_lit_comp(""), RD_IconKind_XSplit}, @@ -365,7 +366,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[215] = +RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -422,6 +423,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[215] = { str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_simple_panels"), str8_lit_comp("Resets the window to the simple panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6a70cc3f..73ba2718 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -108,6 +108,7 @@ RD_CmdKind_PopupAccept, RD_CmdKind_PopupCancel, RD_CmdKind_ResetToDefaultPanels, RD_CmdKind_ResetToCompactPanels, +RD_CmdKind_ResetToSimplePanels, RD_CmdKind_NewPanelLeft, RD_CmdKind_NewPanelUp, RD_CmdKind_NewPanelRight, @@ -633,7 +634,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[297]; +extern RD_VocabInfo rd_vocab_info_table[298]; extern RD_NameSchemaInfo rd_name_schema_info_table[12]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 42feaf07..a8719278 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -394,6 +394,7 @@ RD_CmdTable: // | | | | //- rjf: panel splitting {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {ResetToSimplePanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_simple_panels" "Reset To Simple Panel Layout" "Resets the window to the simple panel layout." "panel" "" } {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 77c5d55c..7730d628 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1241,20 +1241,6 @@ rd_get_hover_regs(void) return rd_state->hover_regs; } -internal void -rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot) -{ - RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(ws != 0) - { - ui_ctx_menu_open(rd_state->ctx_menu_key, anchor_box_key, anchor_box_off); - arena_clear(ws->ctx_menu_arena); - ws->ctx_menu_regs = rd_regs_copy(ws->ctx_menu_arena, rd_regs()); - ws->ctx_menu_regs_slot = slot; - } -} - //////////////////////////////// //~ rjf: Name Allocation @@ -6280,10 +6266,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) } ws->r = r_window_equip(ws->os); ws->ui = ui_state_alloc(); - ws->ctx_menu_arena = arena_alloc(); - ws->ctx_menu_regs = push_array(ws->ctx_menu_arena, RD_Regs, 1); - ws->ctx_menu_input_buffer_size = KB(4); - ws->ctx_menu_input_buffer = push_array(ws->arena, U8, ws->ctx_menu_input_buffer_size); ws->drop_completion_arena = arena_alloc(); ws->hover_eval_arena = arena_alloc(); ws->query_arena = arena_alloc(); @@ -7063,6 +7045,7 @@ rd_window_frame(void) //////////////////////////// //- rjf: @window_ui_part top-level registers context menu // +#if 0 UI_CtxMenu(rd_state->ctx_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) { Temp scratch = scratch_begin(0, 0); @@ -7321,6 +7304,7 @@ rd_window_frame(void) scratch_end(scratch); } +#endif //////////////////////////// //- rjf: @window_ui_part drop-completion context menu @@ -7462,6 +7446,7 @@ rd_window_frame(void) String8 view_name; String8 expr; B32 is_focused; + B32 is_anchored; UI_Signal signal; // NOTE(rjf): output, from build }; FloatingViewTask *hover_eval_floating_view_task = 0; @@ -7472,7 +7457,6 @@ rd_window_frame(void) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) { //- rjf: try to add hover eval first - if(ws->hover_eval_string.size != 0) { B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); @@ -7550,12 +7534,6 @@ rd_window_frame(void) rd_request_frame(); } - // rjf: reset focus state if hover eval is not being built - if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) - { - ws->hover_eval_focused = 0; - } - // rjf: determine size of hover evaluation container EV_BlockTree predicted_block_tree = {0}; RD_RegsScope(.view = view->id) @@ -7597,6 +7575,13 @@ rd_window_frame(void) t->view_name = view_name; t->expr = hover_eval_expr; t->is_focused = ws->hover_eval_focused; + t->is_anchored = 1; + } + + // rjf: reset focus state if hover eval is not being built + if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) + { + ws->hover_eval_focused = 0; } } @@ -7675,6 +7660,17 @@ rd_window_frame(void) content_rect_center.y - max_query_height_px/2.f, content_rect_center.x + query_width_px/2, content_rect_center.y - max_query_height_px/2.f + query_height_px); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + rect.x0 = anchor_box->rect.x0; + rect.y0 = anchor_box->rect.y1; + rect.x1 = rect.x0 + ui_top_font_size()*40.f; + rect.y1 = rect.y0 + query_height_px; + } + } } // rjf: push query task @@ -7688,6 +7684,7 @@ rd_window_frame(void) t->view_name = str8_lit("watch"); t->expr = query_expression; t->is_focused = 1; + t->is_anchored = query_is_anchored; } } } @@ -7700,6 +7697,8 @@ rd_window_frame(void) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") { + F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); + F32 slow_open_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) { // rjf: unpack @@ -7709,7 +7708,8 @@ rd_window_frame(void) String8 view_name = t->view_name; String8 expr = t->expr; B32 is_focused = t->is_focused; - F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f); + B32 is_anchored = t->is_anchored; + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); // rjf: build cfg tree RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); @@ -7737,14 +7737,15 @@ rd_window_frame(void) { // rjf: build top-level container box UI_Box *container = &ui_nil_box; - UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.25f-0.25f*open_t) UI_Transparency(1.f-open_t) + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) { container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBackgroundBlur| UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow, + UI_BoxFlag_DrawDropShadow| + (UI_BoxFlag_SquishAnchored*!!is_anchored), "floating_view_container_%p", view); } @@ -7971,6 +7972,7 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, rd_cmd_kind_info_table[RD_CmdKind_ResetToCompactPanels].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToSimplePanels].string, }; U32 codepoints[] = { @@ -7989,6 +7991,7 @@ rd_window_frame(void) 0, 0, 0, + 0, }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); @@ -8786,7 +8789,7 @@ rd_window_frame(void) UI_Box *site_box = &ui_nil_box; { F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); - UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) + UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); @@ -8877,7 +8880,7 @@ rd_window_frame(void) UI_Box *site_box = &ui_nil_box; { F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); - UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) + UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); @@ -9195,7 +9198,7 @@ rd_window_frame(void) UI_Box *site_box = &ui_nil_box; { F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); - UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t) + UI_Rect(rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); ui_signal_from_box(site_box); @@ -9851,6 +9854,7 @@ rd_window_frame(void) { MemoryZeroStruct(&ws->hover_eval_string); arena_clear(ws->hover_eval_arena); + ws->hover_eval_focused = 0; rd_request_frame(); } @@ -9870,7 +9874,7 @@ rd_window_frame(void) ProfScope("draw UI") { Temp scratch = scratch_begin(0, 0); - F32 box_squish_epsilon = 0.01f; + F32 box_squish_epsilon = 0.001f; Rng2F32 window_rect = os_client_rect_from_window(ws->os); //- rjf: unpack settings @@ -9934,9 +9938,18 @@ rd_window_frame(void) if(box->squish > box_squish_epsilon) { Vec2F32 box_dim = dim_2f32(box->rect); - Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/2, -box->rect.y0)); + Vec2F32 anchor_off = {0}; + if(box->flags & UI_BoxFlag_SquishAnchored) + { + anchor_off.x = box_dim.x/2.f; + } + else + { + anchor_off.y = -box_dim.y/8.f; + } + Mat3x3F32 box2origin_xform = make_translate_3x3f32(v2f32(-box->rect.x0 - box_dim.x/2 + anchor_off.x, -box->rect.y0 + anchor_off.y)); Mat3x3F32 scale_xform = make_scale_3x3f32(v2f32(1-box->squish, 1-box->squish)); - Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/2, box->rect.y0)); + Mat3x3F32 origin2box_xform = make_translate_3x3f32(v2f32(box->rect.x0 + box_dim.x/2 - anchor_off.x, box->rect.y0 - anchor_off.y)); Mat3x3F32 xform = mul_3x3f32(origin2box_xform, mul_3x3f32(scale_xform, box2origin_xform)); dr_push_xform2d(xform); dr_push_tex2d_sample_kind(R_Tex2DSampleKind_Linear); @@ -12776,7 +12789,6 @@ rd_frame(void) { arena_release(lister->arena); } - arena_release(ws->ctx_menu_arena); arena_release(ws->drop_completion_arena); arena_release(ws->hover_eval_arena); arena_release(ws->query_arena); @@ -15254,6 +15266,7 @@ rd_frame(void) //- rjf: panel built-in layout builds case RD_CmdKind_ResetToDefaultPanels: case RD_CmdKind_ResetToCompactPanels: + case RD_CmdKind_ResetToSimplePanels: { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_Cfg *panels = rd_cfg_child_from_string(window, str8_lit("panels")); @@ -15474,6 +15487,38 @@ Z(getting_started) // rjf: set main panel as selected rd_cfg_new(main_panel, str8_lit("selected")); }break; + + //- rjf: simple layout + case RD_CmdKind_ResetToSimplePanels: + { + // rjf: root split + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + RD_Cfg *root_0 = rd_cfg_new(panels, str8_lit("0.25")); + RD_Cfg *root_1 = rd_cfg_new(panels, str8_lit("0.75")); + + // rjf: fill smaller panel with watch + rd_cfg_insert_child(root_0, root_0->last, watches); + rd_cfg_new(watches, str8_lit("selected")); + + // rjf: fill main panel with getting started, OR all collected code views + RD_Cfg *main_panel = root_1; + if(getting_started != &rd_nil_cfg) + { + rd_cfg_insert_child(main_panel, main_panel->last, getting_started); + rd_cfg_new(getting_started, str8_lit("selected")); + } + else if(texts.first) + { + rd_cfg_new(texts.first->v, str8_lit("selected")); + } + for(RD_CfgNode *n = texts.first; n != 0; n = n->next) + { + rd_cfg_insert_child(main_panel, main_panel->last, n->v); + } + + // rjf: set main panel as selected + rd_cfg_new(main_panel, str8_lit("selected")); + }break; } //- rjf: release any unused views from the previous layout diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index aad81239..ce58fcee 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -545,16 +545,6 @@ struct RD_WindowState RD_Lister *autocomp_lister; U64 autocomp_lister_last_frame_idx; - // rjf: context menu state - Arena *ctx_menu_arena; - RD_Regs *ctx_menu_regs; - RD_RegSlot ctx_menu_regs_slot; - U8 *ctx_menu_input_buffer; - U64 ctx_menu_input_buffer_size; - U64 ctx_menu_input_string_size; - TxtPt ctx_menu_input_cursor; - TxtPt ctx_menu_input_mark; - // rjf: drop-completion state Arena *drop_completion_arena; String8List drop_completion_paths; @@ -899,8 +889,6 @@ internal void rd_drag_kill(void); internal void rd_set_hover_regs(RD_RegSlot slot); internal RD_Regs *rd_get_hover_regs(void); -internal void rd_open_ctx_menu(UI_Key anchor_box_key, Vec2F32 anchor_box_off, RD_RegSlot slot); - //////////////////////////////// //~ rjf: Name Allocation diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 347e15b3..70ff3203 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1149,7 +1149,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) { Temp scratch = scratch_begin(0, 0); Vec4F32 color = ui_color_from_name(str8_lit("text")); - FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("?")); + FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.8f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("if")); Vec2F32 p = center_2f32(box->rect); p.x -= run.dim.x*0.5f; p.y += run.descent; @@ -1391,10 +1391,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } - if(ui_right_clicked(thread_sig)) - { - RD_RegsScope(.thread = thread->handle) rd_open_ctx_menu(thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0), RD_RegSlot_Thread); - } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { RD_RegsScope(.thread = thread->handle) rd_drag_begin(RD_RegSlot_Thread); @@ -1543,10 +1539,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } - if(ui_right_clicked(thread_sig)) - { - RD_RegsScope(.thread = thread->handle) rd_open_ctx_menu(thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0), RD_RegSlot_Thread); - } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { RD_RegsScope(.thread = thread->handle) rd_drag_begin(RD_RegSlot_Thread); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 89490c01..8b55ffd7 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -795,7 +795,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->build_box_count = 0; ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; - ui_state->default_animation_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); + ui_state->default_animation_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); ui_state->tooltip_can_overflow_window = 0; ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; ui_state->tags_cache_slots_count = 512; @@ -1117,11 +1117,15 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U Vec2F32 anchor = add_2f32(ui_state->ctx_menu_anchor_box_last_pos, ui_state->ctx_menu_anchor_off); UI_FixedX(anchor.x) UI_FixedY(anchor.y) UI_PrefWidth(ui_children_sum(1.f)) UI_PrefHeight(ui_children_sum(1.f)) UI_Focus(UI_FocusKind_On) - UI_Squish(0.25f-ui_state->ctx_menu_open_t*0.25f) + UI_Squish(0.1f-ui_state->ctx_menu_open_t*0.1f) UI_Transparency(1-ui_state->ctx_menu_open_t) { ui_set_next_child_layout_axis(Axis2_Y); - ui_state->ctx_menu_root = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_DrawDropShadow|(ui_state->ctx_menu_open*UI_BoxFlag_DefaultFocusNavY), "###ctx_menu_%I64x", window.u64[0]); + ui_state->ctx_menu_root = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_SquishAnchored| + UI_BoxFlag_DrawDropShadow| + (ui_state->ctx_menu_open*UI_BoxFlag_DefaultFocusNavY), + "###ctx_menu_%I64x", window.u64[0]); } } @@ -1434,14 +1438,6 @@ ui_end_build(void) } } - //- rjf: animate context menu - if(ui_state->ctx_menu_open && !ui_box_is_nil(ui_state->ctx_menu_root) && !ui_state->ctx_menu_changed) - { - UI_Box *root = ui_state->ctx_menu_root; - Rng2F32 rect = root->rect; - root->rect.y1 = root->rect.y0 + dim_2f32(rect).y * ui_state->ctx_menu_open_t; - } - //- rjf: fall-through interact with context menu if(ui_state->ctx_menu_open) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index fcfcc0b2..bfe298e8 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -350,6 +350,7 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_HasDisplayString (UI_BoxFlags)(1ull<<49) # define UI_BoxFlag_HasFuzzyMatchRanges (UI_BoxFlags)(1ull<<50) # define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) +# define UI_BoxFlag_SquishAnchored (UI_BoxFlags)(1ull<<52) //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) From 4316325b33248d02b47e354fae8826cd391bc09e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 16:08:29 -0700 Subject: [PATCH 221/755] demon win32: only alloc console when launching target if the exe is not a windows gui pe subsystem --- src/demon/win32/demon_core_win32.c | 79 +++++++++++++++++++++++++++++- src/os/core/os_core.h | 1 + src/raddbg/raddbg_views.c | 3 +- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index d31d029e..cb0a2515 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1229,6 +1229,75 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) cmd = str8_list_join(scratch.arena, &args, &join_params); } + //- rjf: determine if process needs a console + B32 needs_console = 1; + { + String8 exe_path = params->cmd_line.first->string; + OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, exe_path); + + // rjf: find PE offset + U32 pe_offset = 0; + { + U64 dos_magic_off = 0; + U16 dos_magic = 0; + os_file_read_struct(file, dos_magic_off, &dos_magic); + if(dos_magic == PE_DOS_MAGIC) + { + U64 pe_offset_off = OffsetOf(PE_DosHeader, coff_file_offset); + os_file_read_struct(file, pe_offset_off, &pe_offset); + } + } + + // rjf: get COFF header + B32 got_coff_header = 0; + U64 coff_header_off = 0; + COFF_Header coff_header = {0}; + if(pe_offset > 0) + { + U64 pe_magic_off = pe_offset; + U32 pe_magic = 0; + os_file_read_struct(file, pe_magic_off, &pe_magic); + if(pe_magic == PE_MAGIC) + { + coff_header_off = pe_magic_off + sizeof(pe_magic); + if(os_file_read_struct(file, coff_header_off, &coff_header)) + { + got_coff_header = 1; + } + } + } + + // rjf: get subsystem from PE header following COFF header + PE_WindowsSubsystem subsystem = 0; + { + U64 opt_header_off = coff_header_off + sizeof(coff_header); + switch(coff_header.machine) + { + default:{}break; + case COFF_MachineType_X64: + { + PE_OptionalHeader32Plus hdr = {0}; + os_file_read_struct(file, opt_header_off, &hdr); + subsystem = hdr.subsystem; + }break; + case COFF_MachineType_X86: + { + PE_OptionalHeader32 hdr = {0}; + os_file_read_struct(file, opt_header_off, &hdr); + subsystem = hdr.subsystem; + }break; + } + } + + // rjf: determine if we need a console depending on the subsystem + if(subsystem == PE_WindowsSubsystem_WINDOWS_GUI) + { + needs_console = 0; + } + + os_file_close(file); + } + //- rjf: produce environment strings String8 env = {0}; { @@ -1291,7 +1360,10 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) inherit_handles = 1; } PROCESS_INFORMATION process_info = {0}; - AllocConsole(); + if(needs_console) + { + AllocConsole(); + } if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, creation_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) { // check if we are 32-bit app, and just close it immediately @@ -1315,7 +1387,10 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) { MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP); } - FreeConsole(); + if(needs_console) + { + FreeConsole(); + } //- rjf: eliminate all handles which have stuck around from the AllocConsole { diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 8edba0ea..cf0e3000 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -202,6 +202,7 @@ internal void os_abort(S32 exit_code); internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path); internal void os_file_close(OS_Handle file); internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data); +#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr)) internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a54b9342..08ead8b1 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1731,7 +1731,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) Temp scratch = scratch_begin(0, 0); UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_em(3, 1)) UI_Row UI_Padding(ui_pct(1, 0)) - UI_PrefWidth(ui_text_dim(10, 1)) + UI_PrefWidth(ui_text_dim(1, 1)) + UI_TagF("weak") { RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); ui_labelf("Could not find \"%S\".", rd_regs()->file_path); From b9ed7b3f0fefb2ef76eca7bdf24bb35e7520246d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 16:22:42 -0700 Subject: [PATCH 222/755] fix menu bar focus rules breaking when hover eval focused --- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_widgets.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7730d628..7d49836e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6342,6 +6342,7 @@ rd_window_frame(void) U64 hover_eval_open_delay_us = 400000; B32 hover_eval_is_open = (!popup_is_open && !query_is_open && + !ws->menu_bar_focused && ws->hover_eval_string.size != 0 && ws->hover_eval_firstt_us+hover_eval_open_delay_us < ws->hover_eval_lastt_us && rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 70ff3203..549ad5ad 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2517,9 +2517,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Rng2F32 cursor_rect = { ui_box_text_position(line_box).x+cursor_off_pixels-cursor_thickness/2.f, - line_box->rect.y0-params->font_size*0.25f, + line_box->rect.y0-params->font_size*0.125f, ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness/2.f, - line_box->rect.y1+params->font_size*0.25f, + line_box->rect.y1+params->font_size*0.125f, }; Vec4F32 cursor_color = ui_color_from_name(str8_lit("cursor")); if(!is_focused) From 8df16b85083ee2791d3a3e866b196c97f298fa4c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 19 Mar 2025 16:42:14 -0700 Subject: [PATCH 223/755] fix ctx menu closing escape consumption rules; fix top bar prioritization rules --- src/raddbg/raddbg_core.c | 873 ++++++++++++++++++++------------------- src/ui/ui_core.c | 12 +- 2 files changed, 443 insertions(+), 442 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7d49836e..abe7e6f7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6342,7 +6342,6 @@ rd_window_frame(void) U64 hover_eval_open_delay_us = 400000; B32 hover_eval_is_open = (!popup_is_open && !query_is_open && - !ws->menu_bar_focused && ws->hover_eval_string.size != 0 && ws->hover_eval_firstt_us+hover_eval_open_delay_us < ws->hover_eval_lastt_us && rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us); @@ -7434,440 +7433,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: @window_ui_part gather all tasks to build floating views - // - typedef struct FloatingViewTask FloatingViewTask; - struct FloatingViewTask - { - FloatingViewTask *next; - RD_Cfg *view; - F32 row_height_px; - Rng2F32 rect; - String8 view_name; - String8 expr; - B32 is_focused; - B32 is_anchored; - UI_Signal signal; // NOTE(rjf): output, from build - }; - FloatingViewTask *hover_eval_floating_view_task = 0; - FloatingViewTask *query_floating_view_task = 0; - FloatingViewTask *first_floating_view_task = 0; - FloatingViewTask *last_floating_view_task = 0; - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - { - //- rjf: try to add hover eval first - { - B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); - - // rjf: disable hover eval if hovered view is actively scrolling - if(hover_eval_is_open) - { - for(RD_PanelNode *panel = panel_tree.root; - panel != &rd_nil_panel_node; - panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) - { - if(panel->first != &rd_nil_panel_node) { continue; } - RD_Cfg *tab = panel->selected_tab; - if(tab != &rd_nil_cfg) - { - RD_ViewState *vs = rd_view_state_from_cfg(tab); - Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); - if(contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(vs->scroll_pos.x.off) > 0.01f || - abs_f32(vs->scroll_pos.y.off) > 0.01f)) - { - build_hover_eval = 0; - ws->hover_eval_firstt_us = rd_state->time_in_us; - } - } - } - } - - // rjf: choose hover evaluation expression - String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); - - // rjf: evaluate hover evaluation expression, & determine if it evaluates - // such that we want to build a hover eval. - E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); - { - if(hover_eval.msgs.max_kind > E_MsgKind_Null) - { - build_hover_eval = 0; - } - else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && - rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) - { - build_hover_eval = 0; - } - else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && - rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) - { - build_hover_eval = 0; - } - } - - // rjf: determine if we have a top-level visualizer - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); - - // rjf: determine view name - String8 view_name = str8_lit("watch"); - if(view_ui_rule != &rd_nil_view_ui_rule) - { - view_name = view_ui_rule->name; - } - - // rjf: build view - RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - - // rjf: request frames if we're waiting to open - if(ws->hover_eval_string.size != 0 && - !hover_eval_is_open && - ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && - rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) - { - rd_request_frame(); - } - - // rjf: determine size of hover evaluation container - EV_BlockTree predicted_block_tree = {0}; - RD_RegsScope(.view = view->id) - { - predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); - } - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); - if(ws->hover_eval_focused) - { - max_row_count *= 3; - } - U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); - F32 width_px = 60.f*ui_top_font_size(); - F32 height_px = num_rows_t*row_height_px; - - // rjf: if arbitrary visualizer, pick catchall size - if(view_ui_rule != &rd_nil_view_ui_rule) - { - height_px = 40.f*ui_top_font_size(); - } - - // rjf: determine hover eval top-level rect - Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, - ws->hover_eval_spawn_pos.y, - ws->hover_eval_spawn_pos.x + width_px, - ws->hover_eval_spawn_pos.y + height_px); - - // rjf: push hover eval task - if(build_hover_eval) - { - FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); - SLLQueuePush(first_floating_view_task, last_floating_view_task, t); - hover_eval_floating_view_task = t; - t->view = view; - t->row_height_px = row_height_px; - t->rect = rect; - t->view_name = view_name; - t->expr = hover_eval_expr; - t->is_focused = ws->hover_eval_focused; - t->is_anchored = 1; - } - - // rjf: reset focus state if hover eval is not being built - if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) - { - ws->hover_eval_focused = 0; - } - } - - //- rjf: try to add opened query - if(query_is_open) - { - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - - // rjf: unpack query info - String8 cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); - B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); - - // rjf: build view for query - RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - rd_cfg_new_replace(cmd, cmd_name); - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->query_is_selected = 1; - - // rjf: compute query expression - String8 query_expression = cmd_kind_info->query.expr; - if(query_expression.size == 0) - { - query_expression = str8(vs->query_buffer, vs->query_string_size); - } - else - { - U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); - if(input_insertion_pos < query_expression.size) - { - String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); - String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); - query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); - } - } - - // rjf: based on query expression, determine if we have an explicit root - if(query_expression.size == 0) - { - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - } - else - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); - } - - // rjf: evaluate query expression - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); - - // rjf: compute query view's top-level rectangle - Rng2F32 rect = {0}; - RD_RegsScope(.view = view->id) - { - Vec2F32 content_rect_center = center_2f32(content_rect); - Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); - F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); - F32 max_query_height_px = content_rect_dim.y*0.8f; - F32 query_height_px = max_query_height_px; - if(size_query_by_expr_eval) - { - query_height_px = row_height_px*predicted_block_tree.total_row_count; - query_height_px = Min(query_height_px, max_query_height_px); - } - rect = r2f32p(content_rect_center.x - query_width_px/2, - content_rect_center.y - max_query_height_px/2.f, - content_rect_center.x + query_width_px/2, - content_rect_center.y - max_query_height_px/2.f + query_height_px); - if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) - { - UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); - if(anchor_box != &ui_nil_box) - { - rect.x0 = anchor_box->rect.x0; - rect.y0 = anchor_box->rect.y1; - rect.x1 = rect.x0 + ui_top_font_size()*40.f; - rect.y1 = rect.y0 + query_height_px; - } - } - } - - // rjf: push query task - { - FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); - SLLQueuePush(first_floating_view_task, last_floating_view_task, t); - query_floating_view_task = t; - t->view = view; - t->row_height_px = row_height_px; - t->rect = rect; - t->view_name = str8_lit("watch"); - t->expr = query_expression; - t->is_focused = 1; - t->is_anchored = query_is_anchored; - } - } - } - - //////////////////////////// - //- rjf: @window_ui_part build all floating views - // - ProfScope("build all floating views") - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_TagF("floating") - { - F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); - F32 slow_open_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); - for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) - { - // rjf: unpack - RD_Cfg *view = t->view; - F32 row_height_px = t->row_height_px; - Rng2F32 rect = t->rect; - String8 view_name = t->view_name; - String8 expr = t->expr; - B32 is_focused = t->is_focused; - B32 is_anchored = t->is_anchored; - F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); - - // rjf: build cfg tree - RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(view, str8_lit("selected")); - rd_cfg_new_replace(expr_root, expr); - - // rjf: push view regs - rd_push_regs(.view = view->id); - { - String8 view_expr = rd_expr_from_cfg(view); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - // NOTE(rjf): we want to only fill out this view's file path slot if it - // evaluates one - this way, a view can use the slot to know the selected - // file path (if there is one). this is useful when pushing commandas which - // apply to a cursor, for example. - if(view_file_path.size != 0) - { - rd_regs()->file_path = view_file_path; - } - } - - // rjf: build - UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) - UI_PrefHeight(ui_px(row_height_px, 1.f)) - { - // rjf: build top-level container box - UI_Box *container = &ui_nil_box; - UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) - { - container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow| - (UI_BoxFlag_SquishAnchored*!!is_anchored), - "floating_view_container_%p", view); - } - - // rjf: peek press events -> focus hover eval if we have a press - if(!ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 1; - break; - } - } - } - - // rjf: build overlay container for loading animation - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(container) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); - } - - // rjf: build contents - UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - { - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_WidthFill - { - rd_view_ui(rect); - } - } - - // rjf: build loading overlay - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - F32 loading_t = vs->loading_t; - if(loading_t > 0.01f) UI_Parent(loading_overlay_container) - { - rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); - } - } - - // rjf: interact with container - UI_Signal sig = ui_signal_from_box(container); - t->signal = sig; - } - - // rjf: pop interaction registers; commit if this is focused - RD_Regs *view_regs = rd_pop_regs(); - if(is_focused) - { - MemoryCopyStruct(rd_regs(), view_regs); - } - } - } - - //////////////////////////// - //- rjf: @window_ui_part do special handling of floating view interactions - // - { - //- rjf: hover eval focus rules - if(hover_eval_floating_view_task) - { - UI_Signal sig = hover_eval_floating_view_task->signal; - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_mouse_over(sig) || ws->hover_eval_focused) - { - ws->hover_eval_lastt_us = rd_state->time_in_us; - } - else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) - { - rd_request_frame(); - } - if(ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - !contains_2f32(hover_eval_floating_view_task->rect, evt->pos)) - { - ws->hover_eval_focused = 0; - MemoryZeroStruct(&ws->hover_eval_string); - arena_clear(ws->hover_eval_arena); - rd_request_frame(); - break; - } - } - } - } - - //- rjf: query interactions - if(query_floating_view_task) - { - String8 cmd_name = ws->query_cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - - // rjf: any queries which take a file path mutate the debugger's "current path" - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) - { - RD_Cfg *view = query_floating_view_task->view; - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); - RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); - if(input != &rd_nil_cfg) - { - String8 path_chopped = str8_chop_last_slash(input->first->string); - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); - } - } - } - } - //////////////////////////// //- rjf: @window_ui_part top bar // @@ -7877,7 +7442,7 @@ rd_window_frame(void) os_window_push_custom_edges(ws->os, window_edge_px); os_window_push_custom_title_bar(ws->os, dim_2f32(top_bar_rect).y); ui_set_next_flags(UI_BoxFlag_DefaultFocusNav|UI_BoxFlag_DisableFocusOverlay); - UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open() && !ws->hover_eval_focused) ? UI_FocusKind_On : UI_FocusKind_Null) + UI_Focus((ws->menu_bar_focused && window_is_focused && !ui_any_ctx_menu_is_open()) ? UI_FocusKind_On : UI_FocusKind_Null) UI_TagF("menu_bar") UI_Pane(top_bar_rect, str8_lit("###top_bar")) UI_WidthFill UI_Row @@ -8636,6 +8201,442 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: @window_ui_part gather all tasks to build floating views + // + typedef struct FloatingViewTask FloatingViewTask; + struct FloatingViewTask + { + FloatingViewTask *next; + RD_Cfg *view; + F32 row_height_px; + Rng2F32 rect; + String8 view_name; + String8 expr; + B32 is_focused; + B32 is_anchored; + UI_Signal signal; // NOTE(rjf): output, from build + }; + FloatingViewTask *hover_eval_floating_view_task = 0; + FloatingViewTask *query_floating_view_task = 0; + FloatingViewTask *first_floating_view_task = 0; + FloatingViewTask *last_floating_view_task = 0; + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + { + //- rjf: try to add hover eval first + { + B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); + + // rjf: disable hover eval if hovered view is actively scrolling + if(hover_eval_is_open) + { + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + if(panel->first != &rd_nil_panel_node) { continue; } + RD_Cfg *tab = panel->selected_tab; + if(tab != &rd_nil_cfg) + { + RD_ViewState *vs = rd_view_state_from_cfg(tab); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + if(contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(vs->scroll_pos.x.off) > 0.01f || + abs_f32(vs->scroll_pos.y.off) > 0.01f)) + { + build_hover_eval = 0; + ws->hover_eval_firstt_us = rd_state->time_in_us; + } + } + } + } + + // rjf: choose hover evaluation expression + String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + + // rjf: evaluate hover evaluation expression, & determine if it evaluates + // such that we want to build a hover eval. + E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + { + if(hover_eval.msgs.max_kind > E_MsgKind_Null) + { + build_hover_eval = 0; + } + else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) + { + build_hover_eval = 0; + } + else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) + { + build_hover_eval = 0; + } + } + + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + + // rjf: determine view name + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } + + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + + // rjf: request frames if we're waiting to open + if(ws->hover_eval_string.size != 0 && + !hover_eval_is_open && + ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) + { + rd_request_frame(); + } + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id) + { + predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + } + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); + F32 width_px = 60.f*ui_top_font_size(); + F32 height_px = num_rows_t*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = 40.f*ui_top_font_size(); + } + + // rjf: determine hover eval top-level rect + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + + // rjf: push hover eval task + if(build_hover_eval) + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + hover_eval_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = view_name; + t->expr = hover_eval_expr; + t->is_focused = ws->hover_eval_focused; + t->is_anchored = 1; + } + + // rjf: reset focus state if hover eval is not being built + if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) + { + ws->hover_eval_focused = 0; + } + } + + //- rjf: try to add opened query + if(query_is_open) + { + // rjf: close queries + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + + // rjf: unpack query info + String8 cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); + B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); + F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + + // rjf: build view for query + RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + RD_ViewState *vs = rd_view_state_from_cfg(view); + vs->query_is_selected = 1; + + // rjf: compute query expression + String8 query_expression = cmd_kind_info->query.expr; + if(query_expression.size == 0) + { + query_expression = str8(vs->query_buffer, vs->query_string_size); + } + else + { + U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expression.size) + { + String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); + String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); + query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + } + } + + // rjf: based on query expression, determine if we have an explicit root + if(query_expression.size == 0) + { + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + + // rjf: evaluate query expression + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); + + // rjf: compute query view's top-level rectangle + Rng2F32 rect = {0}; + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); + F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + if(size_query_by_expr_eval) + { + query_height_px = row_height_px*predicted_block_tree.total_row_count; + query_height_px = Min(query_height_px, max_query_height_px); + } + rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + rect.x0 = anchor_box->rect.x0; + rect.y0 = anchor_box->rect.y1; + rect.x1 = rect.x0 + ui_top_font_size()*40.f; + rect.y1 = rect.y0 + query_height_px; + } + } + } + + // rjf: push query task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + query_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = str8_lit("watch"); + t->expr = query_expression; + t->is_focused = 1; + t->is_anchored = query_is_anchored; + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part build all floating views + // + ProfScope("build all floating views") + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + UI_Focus(ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) + { + F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); + F32 slow_open_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); + for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) + { + // rjf: unpack + RD_Cfg *view = t->view; + F32 row_height_px = t->row_height_px; + Rng2F32 rect = t->rect; + String8 view_name = t->view_name; + String8 expr = t->expr; + B32 is_focused = t->is_focused; + B32 is_anchored = t->is_anchored; + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); + + // rjf: build cfg tree + RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(view, str8_lit("selected")); + rd_cfg_new_replace(expr_root, expr); + + // rjf: push view regs + rd_push_regs(.view = view->id); + { + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + // rjf: build + UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + { + // rjf: build top-level container box + UI_Box *container = &ui_nil_box; + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) + { + container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow| + (UI_BoxFlag_SquishAnchored*!!is_anchored), + "floating_view_container_%p", view); + } + + // rjf: peek press events -> focus hover eval if we have a press + if(!ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + contains_2f32(container->rect, evt->pos)) + { + ws->hover_eval_focused = 1; + break; + } + } + } + + // rjf: build overlay container for loading animation + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(container) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + // rjf: build contents + UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(rect); + } + } + + // rjf: build loading overlay + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + F32 loading_t = vs->loading_t; + if(loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + // rjf: interact with container + UI_Signal sig = ui_signal_from_box(container); + t->signal = sig; + } + + // rjf: pop interaction registers; commit if this is focused + RD_Regs *view_regs = rd_pop_regs(); + if(is_focused) + { + MemoryCopyStruct(rd_regs(), view_regs); + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part do special handling of floating view interactions + // + { + //- rjf: hover eval focus rules + if(hover_eval_floating_view_task) + { + UI_Signal sig = hover_eval_floating_view_task->signal; + if(ui_pressed(sig)) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_lastt_us = rd_state->time_in_us; + } + else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) + { + rd_request_frame(); + } + if(ws->hover_eval_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton && + !contains_2f32(hover_eval_floating_view_task->rect, evt->pos)) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + break; + } + } + } + } + + //- rjf: query interactions + if(query_floating_view_task) + { + String8 cmd_name = ws->query_cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *view = query_floating_view_task->view; + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) + { + String8 path_chopped = str8_chop_last_slash(input->first->string); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } + } + } + } + //////////////////////////// //- rjf: @window_ui_part bottom bar // diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 8b55ffd7..bef1b74c 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1172,6 +1172,12 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->active_box_key[k] = ui_key_zero(); } } + + //- rjf: escape -> close context menu + if(ui_any_ctx_menu_is_open() && ui_slot_press(UI_EventActionSlot_Cancel)) + { + ui_ctx_menu_close(); + } } internal void @@ -1179,12 +1185,6 @@ ui_end_build(void) { ProfBeginFunction(); - //- rjf: escape -> close context menu - if(ui_state->ctx_menu_open != 0 && ui_slot_press(UI_EventActionSlot_Cancel)) - { - ui_ctx_menu_close(); - } - //- rjf: prune untouched or transient boxes in the cache ProfScope("ui prune unused boxes") { From 1ffb8a082e9bc2b3e2c3b433fac518873825302d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 09:19:27 -0700 Subject: [PATCH 224/755] sketch out first several 0.9.16 release notes --- src/raddbg/raddbg_core.c | 8 ++++++-- src/raddbg/raddbg_main.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index abe7e6f7..b73276f0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8468,7 +8468,7 @@ rd_window_frame(void) UI_Focus(ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) { F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); - F32 slow_open_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); + F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) { // rjf: unpack @@ -13732,6 +13732,7 @@ rd_frame(void) String8 name = debug_info_table_collection_names[idx]; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(debug_info_table), @@ -16088,7 +16089,10 @@ Z(getting_started) .view = dst_tab->id) { rd_cmd(RD_CmdKind_FocusTab); - rd_cmd(RD_CmdKind_GoToLine, .cursor = point); + if(point.line != 0) + { + rd_cmd(RD_CmdKind_GoToLine, .cursor = point); + } rd_cmd(cursor_snap_kind); } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 1573b936..14788340 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -1,6 +1,48 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: 0.9.16 changes +// +// - Auto view rules have been upgraded to support type pattern-matching. This +// makes them usable for generic types in various languages. +// - The `slice` view rule has been streamlined and simplified. When an +// expression with a `slice` view rule is expanded, it will simply expand to +// the slice's contents, which matches the behavior with static arrays. +// - The `slice` view rule now supports `first, one-past-last` pointer pairs, +// as well as `base_pointer, length` pairs. +// - The syntax for view rules has changed to improve its familiarity, +// usability, and to improve its consistency with the rest of the evaluation +// language. It now appears like function calls, and many arguments no longer +// need to be explicitly named. For example, instead of +// `bitmap:{w:1024, h:1024}`, the new view rule syntax would be +// `bitmap(1024, 1024)`. Commas can still be omitted. Named arguments are +// still possible (and required in some cases): `disasm(size=1024, arch=x64)` +// - The hover evaluation feature has been majorly upgraded to support all +// features normally available in the `Watch` view. Hover evaluations now +// explicitly show type information, and contain a view rule column, which +// can be edited in an identical way as the `Watch` view. +// - Added "auto tabs", which are colored differently than normal tabs. These +// tabs are automatically opened by the debugger when snapping to source code +// which is not already opened. They are automatically replaced and recycled +// when the debugger needs to snap to new locations. This will greatly reduce +// the number of unused source code tabs accumulated throughout a debugging +// session. These tabs can still be promoted to permanent tabs, in which case +// they'll stay around until manually closed. +// - The `Scheduler` view has been removed, in favor of three separate views, +// which present various versions of the same information: `Threads`, +// `Processes`, and `Machines`. The justification for this is that the +// common case is debugging a small number of programs, usually 1, and for +// those purposes, the `Threads` view is sufficient if not desirable, and +// the extra information provided by `Processes` and `Machines`, while useful +// in other contexts, is not useful in that common case. +// - The two separate interfaces for editing threads, breakpoints, and watch +// pins (the right-click context menu and the dedicated tabs) have been +// merged. +// - Added the ability to add per-target environment strings. +// - Fixed an annoyance where the debugger would open a console window, even +// for graphical programs, causing a flicker. + //////////////////////////////// //~ rjf: feature cleanup, code dedup, code elimination pass: // From f5683b0f3dc0552bfc1dc567307d2ae9197f24ab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 10:09:06 -0700 Subject: [PATCH 225/755] convergence - source view switching commands --- src/dbg_engine/dbg_engine.mdesk | 2 +- src/dbg_engine/dbg_engine_core.c | 6 +- src/dbg_engine/generated/dbg_engine.meta.h | 2 +- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 127 +++++++------------- src/raddbg/raddbg_views.c | 129 +++++++++++---------- 8 files changed, 118 insertions(+), 158 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index be9213b8..cef6e19f 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -11,7 +11,7 @@ D_CmdTable: // | | | { //- rjf: low-level target control operations {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } - {LaunchAndInit 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {LaunchAndStepInto 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_step_into" "Launch and Step Into" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index fc6abd8e..b61e3c6d 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1967,7 +1967,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P //- rjf: low-level target control operations case D_CmdKind_LaunchAndRun: - case D_CmdKind_LaunchAndInit: + case D_CmdKind_LaunchAndStepInto: { // rjf: get list of targets to launch D_TargetArray *targets_to_launch = ¶ms->targets; @@ -2047,7 +2047,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P need_run = 1; run_kind = D_RunKind_Run; run_thread = &ctrl_entity_nil; - run_flags = (cmd->kind == D_CmdKind_LaunchAndInit) ? CTRL_RunFlag_StopOnEntryPoint : 0; + run_flags = (cmd->kind == D_CmdKind_LaunchAndStepInto) ? CTRL_RunFlag_StopOnEntryPoint : 0; } // rjf: no targets -> error @@ -2291,7 +2291,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } else if(!d_ctrl_targets_running()) { - d_cmd(D_CmdKind_LaunchAndInit, .targets = *targets); + d_cmd(D_CmdKind_LaunchAndStepInto, .targets = *targets); } }break; diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index f8d99632..9efa15b8 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -10,7 +10,7 @@ typedef enum D_CmdKind { D_CmdKind_Null, D_CmdKind_LaunchAndRun, -D_CmdKind_LaunchAndInit, +D_CmdKind_LaunchAndStepInto, D_CmdKind_Kill, D_CmdKind_KillAll, D_CmdKind_Detach, diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7efc35bd..81a5cf45 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -90,7 +90,7 @@ RD_VocabInfo rd_vocab_info_table[298] = {str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, {str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, -{str8_lit_comp("launch_and_init"), str8_lit_comp(""), str8_lit_comp("Launch and Initialize"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, +{str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, {str8_lit_comp("kill_all"), str8_lit_comp(""), str8_lit_comp("Kill All"), str8_lit_comp(""), RD_IconKind_Stop}, {str8_lit_comp("detach"), str8_lit_comp(""), str8_lit_comp("Detach"), str8_lit_comp(""), RD_IconKind_Null}, @@ -309,7 +309,7 @@ RD_VocabInfo rd_vocab_info_table[298] = RD_NameSchemaInfo rd_name_schema_info_table[12] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_init, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, @@ -370,7 +370,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_step_into"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, { str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 73ba2718..d5cec6da 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -55,7 +55,7 @@ typedef enum RD_CmdKind { RD_CmdKind_Null, RD_CmdKind_LaunchAndRun, -RD_CmdKind_LaunchAndInit, +RD_CmdKind_LaunchAndStepInto, RD_CmdKind_Kill, RD_CmdKind_KillAll, RD_CmdKind_Detach, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a8719278..b522d89b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -156,7 +156,7 @@ RD_VocabTable: { target, ``` - @commands(launch_and_run, launch_and_init, enable_cfg, remove_cfg) + @commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg) @collection_commands(add_target) x: { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b73276f0..8ad547fd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3568,7 +3568,7 @@ rd_view_ui(Rng2F32 rect) ui_spacer(ui_em(1.5f, 1)); if(ui_clicked(rd_icon_buttonf(RD_IconKind_StepInto, 0, "Step Into %S", target_name))) { - rd_cmd(RD_CmdKind_LaunchAndInit, .cfg = target_cfg->id); + rd_cmd(RD_CmdKind_LaunchAndStepInto, .cfg = target_cfg->id); } } }break; @@ -7625,10 +7625,14 @@ rd_window_frame(void) String8 cmds[] = { rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndRun].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndStepInto].string, }; U32 codepoints[] = { 'a', + 'r', + 's', }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); @@ -8575,6 +8579,12 @@ rd_window_frame(void) { MemoryCopyStruct(rd_regs(), view_regs); } + + // rjf: is not anchored? -> darken rest of screen + if(!is_anchored) + { + UI_TagF("inactive") UI_Transparency(1-open_t) UI_Rect(content_rect) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); + } } } @@ -13945,7 +13955,7 @@ rd_frame(void) //- rjf: default cases case RD_CmdKind_Run: case RD_CmdKind_LaunchAndRun: - case RD_CmdKind_LaunchAndInit: + case RD_CmdKind_LaunchAndStepInto: case RD_CmdKind_StepInto: case RD_CmdKind_StepOver: case RD_CmdKind_Restart: @@ -15108,97 +15118,42 @@ rd_frame(void) }break; case RD_CmdKind_Switch: { -#if 0 // TODO(rjf): @cfg (opening recent files) - RD_Window *ws = rd_window_from_handle(rd_regs()->window); - RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *src_view = rd_view_from_handle(rd_regs()->view); - RD_ViewRuleKind src_view_kind = rd_view_rule_kind_from_string(src_view->spec->string); - RD_Entity *recent_file = rd_entity_from_handle(rd_regs()->entity); - if(!rd_entity_is_nil(recent_file)) - { - String8 recent_file_path = recent_file->string; - RD_Panel *existing_panel = &rd_nil_panel; - RD_View *existing_view = &rd_nil_view; - for(RD_Panel *panel = ws->root_panel; !rd_panel_is_nil(panel); panel = rd_panel_rec_depth_first_pre(panel).next) - { - if(!rd_panel_is_nil(panel->first)) - { - continue; - } - for(RD_View *v = panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next) - { - if(rd_view_is_project_filtered(v)) { continue; } - String8 v_path = rd_file_path_from_eval_string(scratch.arena, str8(v->query_buffer, v->query_string_size)); - RD_ViewRuleKind v_kind = rd_view_rule_kind_from_string(v->spec->string); - if(str8_match(v_path, recent_file_path, StringMatchFlag_CaseInsensitive) && v_kind == src_view_kind) - { - existing_panel = panel; - existing_view = v; - goto done_existing_view_search__switch; - } - } - } - done_existing_view_search__switch:; - if(rd_view_is_nil(existing_view)) - { - rd_cmd(RD_CmdKind_OpenTab, - .string = rd_eval_string_from_file_path(scratch.arena, recent_file_path), - .params_tree = md_tree_from_string(scratch.arena, rd_view_rule_kind_info_table[RD_ViewRuleKind_PendingFile].string)->first); - } - else - { - rd_cmd(RD_CmdKind_FocusPanel, .panel = rd_handle_from_panel(existing_panel)); - existing_panel->selected_tab_view = rd_handle_from_view(existing_view); - } - } -#endif + RD_Cfg *recent_file = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *path_root = rd_cfg_child_from_string(recent_file, str8_lit("path")); + String8 path = path_root->first->string; + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .cursor = txt_pt(0, 0), .vaddr = 0); }break; case RD_CmdKind_SwitchToPartnerFile: { -#if 0 // TODO(rjf): @cfg (opening partner files) - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_selected_tab_from_panel(panel); + String8 file_path = rd_regs()->file_path; + String8 file_full_path = path_normalized_from_string(scratch.arena, file_path); + String8 file_folder = str8_chop_last_slash(file_full_path); + String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_full_path)); + String8 file_ext = str8_skip_last_dot(file_full_path); + String8 partner_ext_candidates[] = { - String8 file_path = rd_file_path_from_eval_string(scratch.arena, str8(view->query_buffer, view->query_string_size)); - String8 file_full_path = path_normalized_from_string(scratch.arena, file_path); - String8 file_folder = str8_chop_last_slash(file_full_path); - String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_full_path)); - String8 file_ext = str8_skip_last_dot(file_full_path); - String8 partner_ext_candidates[] = + str8_lit_comp("h"), + str8_lit_comp("hpp"), + str8_lit_comp("hxx"), + str8_lit_comp("c"), + str8_lit_comp("cc"), + str8_lit_comp("cxx"), + str8_lit_comp("cpp"), + }; + for(U64 idx = 0; idx < ArrayCount(partner_ext_candidates); idx += 1) + { + if(!str8_match(partner_ext_candidates[idx], file_ext, StringMatchFlag_CaseInsensitive)) { - str8_lit_comp("h"), - str8_lit_comp("hpp"), - str8_lit_comp("hxx"), - str8_lit_comp("c"), - str8_lit_comp("cc"), - str8_lit_comp("cxx"), - str8_lit_comp("cpp"), - }; - for(U64 idx = 0; idx < ArrayCount(partner_ext_candidates); idx += 1) - { - if(!str8_match(partner_ext_candidates[idx], file_ext, StringMatchFlag_CaseInsensitive)) + String8 candidate = push_str8f(scratch.arena, "%S.%S", file_name, partner_ext_candidates[idx]); + String8 candidate_path = push_str8f(scratch.arena, "%S/%S", file_folder, candidate); + FileProperties candidate_props = os_properties_from_file_path(candidate_path); + if(candidate_props.modified != 0) { - String8 candidate = push_str8f(scratch.arena, "%S.%S", file_name, partner_ext_candidates[idx]); - String8 candidate_path = push_str8f(scratch.arena, "%S/%S", file_folder, candidate); - FileProperties candidate_props = os_properties_from_file_path(candidate_path); - if(candidate_props.modified != 0) - { - RD_Entity *recent_file = rd_entity_from_name_and_kind(candidate_path, RD_EntityKind_RecentFile); - if(!rd_entity_is_nil(recent_file)) - { - rd_cmd(RD_CmdKind_Switch, .entity = rd_handle_from_entity(recent_file)); - } - else - { - rd_cmd(RD_CmdKind_RecordFileInProject, .file_path = candidate_path); - rd_cmd(RD_CmdKind_OpenTab, .string = rd_eval_string_from_file_path(scratch.arena, candidate_path), .params_tree = md_tree_from_string(scratch.arena, view->spec->string)->first); - } - break; - } + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = candidate_path, .cursor = txt_pt(0, 0), .vaddr = 0); + break; } } } -#endif }break; case RD_CmdKind_RecordFileInProject: if(rd_regs()->file_path.size != 0) @@ -16068,6 +16023,10 @@ Z(getting_started) vs->last_frame_index_built = 0; RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(dst_tab, str8_lit("expression")); rd_cfg_new_replace(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("cursor_line")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("cursor_column")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("mark_line")), str8_lit("1")); + rd_cfg_new_replace(rd_cfg_child_from_string(dst_tab, str8_lit("mark_column")), str8_lit("1")); } else if(dst_panel != &rd_nil_panel_node && dst_tab == &rd_nil_cfg) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 08ead8b1..7a6ee821 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1057,6 +1057,70 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { if(0){} + // rjf: folder / file rows + else if(info.eval.space.kind == E_SpaceKind_FileSystem) + { + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + String8 file_path = e_string_from_id(info.eval.value.u64); + DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, + .pct = 1.f, + .fstrs = fstrs); + if(str8_match(type->name, str8_lit("file"), 0)) + { + info.can_expand = 0; + } + } + else + { + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); +#undef take_pct + } + } + + // rjf: singular button for unattached processes + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + { + E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + if(str8_match(type->name, str8_lit("unattached_process"), 0)) + { + U64 pid = info.eval.value.u128.u64[0]; + String8 name = e_string_from_id(info.eval.value.u128.u64[1]); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Scheduler], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = fstrs); + } + } + + // rjf: lister rows + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + info.can_expand = 0; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + } + // rjf: top-level cfg rows else if(is_top_level && evalled_cfg != &rd_nil_cfg) { @@ -1147,32 +1211,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } - // rjf: singular button for unattached processes - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) - { - E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(str8_match(type->name, str8_lit("unattached_process"), 0)) - { - U64 pid = info.eval.value.u128.u64[0]; - String8 name = e_string_from_id(info.eval.value.u128.u64[1]); - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - DR_FStrList fstrs = {0}; - UI_TagF("weak") - { - dr_fstrs_push_new(arena, &fstrs, ¶ms, - rd_icon_kind_text_table[RD_IconKind_Scheduler], - .font = rd_font_from_slot(RD_FontSlot_Icons), - .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), - .color = ui_color_from_name(str8_lit("text"))); - } - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = fstrs); - } - } - // rjf: singular button for commands else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { @@ -1189,37 +1227,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: folder / file rows - else if(info.eval.space.kind == E_SpaceKind_FileSystem) - { - E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) - { - String8 file_path = e_string_from_id(info.eval.value.u64); - DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, - .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, - .pct = 1.f, - .fstrs = fstrs); - if(str8_match(type->name, str8_lit("file"), 0)) - { - info.can_expand = 0; - } - } - else - { - info.cell_style_key = str8_lit("expr_and_eval"); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); -#undef take_pct - } - } - // rjf: singular cell for view ui else if(info.view_ui_rule != &rd_nil_view_ui_rule) { @@ -1249,13 +1256,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } - // rjf: lister rows - else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) - { - info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); - } - // rjf: procedures collections get only expr/value/view-rule else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) { @@ -1526,6 +1526,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) { result.cfg = cfg; + result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); } } else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) From 43d8fd48866b3f43645b5c7ee6df80209e11b58a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 14:26:09 -0700 Subject: [PATCH 226/755] query watch windows progress; hook up visualizer schemas to cfg evaluator, use in tab query watch --- src/raddbg/generated/raddbg.meta.c | 13 +- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 54 ++++ src/raddbg/raddbg_core.c | 451 ++++++++++------------------- src/raddbg/raddbg_core.h | 1 - src/raddbg/raddbg_views.c | 37 ++- src/raddbg/raddbg_widgets.c | 38 +-- src/ui/ui_core.c | 15 + src/ui/ui_core.h | 1 + 9 files changed, 275 insertions(+), 339 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 81a5cf45..7d50c11b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[298] = +RD_VocabInfo rd_vocab_info_table[303] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -89,6 +89,11 @@ RD_VocabInfo rd_vocab_info_table[298] = {str8_lit_comp("project"), str8_lit_comp("projects"), str8_lit_comp("Project"), str8_lit_comp("Projects"), RD_IconKind_Briefcase}, {str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, {str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, +{str8_lit_comp("show_addresses"), str8_lit_comp(""), str8_lit_comp("Show Addresses"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_code_bytes"), str8_lit_comp(""), str8_lit_comp("Show Code Bytes"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_source_lines"), str8_lit_comp(""), str8_lit_comp("Show Source Lines"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_symbol_names"), str8_lit_comp(""), str8_lit_comp("Show Symbol Names"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -306,9 +311,13 @@ RD_VocabInfo rd_vocab_info_table[298] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[12] = +RD_NameSchemaInfo rd_name_schema_info_table[16] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n 'syntax': dasm_syntax,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d5cec6da..f1219447 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -634,8 +634,8 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[298]; -extern RD_NameSchemaInfo rd_name_schema_info_table[12]; +extern RD_VocabInfo rd_vocab_info_table[303]; +extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b522d89b..44c91b8f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -6,6 +6,7 @@ @embed_file rd_icon_font_bytes: "../data/icons.ttf" @embed_file rd_default_main_font_bytes: "../data/Roboto-Regular.ttf" +//@embed_file rd_default_main_font_bytes: "../data/seguisb.ttf" @embed_file rd_default_code_font_bytes: "../data/liberation-mono.ttf" //@embed_file rd_default_code_font_bytes: "../data/Inconsolata-Regular.ttf" @embed_file rd_icon_file_bytes: "../data/logo.ico" @@ -101,6 +102,11 @@ RD_VocabTable: {project _ "Project" _ Briefcase } {recent_project _ "Recent Project" _ Briefcase } {recent_file _ "Recent File" _ FileOutline } + {show_addresses "" "Show Addresses" "" Null } + {show_code_bytes "" "Show Code Bytes" "" Null } + {show_source_lines "" "Show Source Lines" "" Null } + {show_symbol_names "" "Show Symbol Names" "" Null } + {syntax syntaxes "Syntax" "Syntaxes" Null } } @struct RD_VocabInfo: @@ -152,6 +158,54 @@ RD_VocabTable: ``` } + //- rjf: views + { + text, + ``` + x: + { + 'lang':lang, + 'size':code_string, + } + ``` + } + { + disasm, + ``` + x: + { + 'arch': arch, + 'size': code_string, + @default(1) 'show_addresses': bool, + @default(0) 'show_code_bytes': bool, + @default(1) 'show_source_lines': bool, + @default(1) 'show_symbol_names': bool, + 'syntax': dasm_syntax, + } + ``` + } + { + memory, + ``` + x: + { + 'size': code_string, + @default(16) 'num_columns': @range[1, 64] u64, + } + ``` + } + { + bitmap, + ``` + x: + { + 'w': code_string, + 'h': code_string, + 'fmt': tex2dformat, + } + ``` + } + //- rjf: targets { target, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8ad547fd..2493bb20 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2261,14 +2261,26 @@ rd_setting_from_name(String8 name) // rjf: return resultant child string stored under this key result = setting->first->string; - // rjf: no result -> look for default in settings schema + // rjf: no result -> look for default in settings if(result.size == 0) ProfScope("default setting schema lookup") { Temp scratch = scratch_begin(0, 0); - MD_Node *schema = rd_schema_from_name(scratch.arena, str8_lit("settings")); - MD_Node *setting = md_child_from_string(schema, name, 0); - MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); - result = default_tag->first->string; + String8 schema_names[] = + { + start_cfg->string, + str8_lit("settings"), + }; + for EachElement(idx, schema_names) + { + MD_Node *schema = rd_schema_from_name(scratch.arena, schema_names[idx]); + MD_Node *setting = md_child_from_string(schema, name, 0); + MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + if(default_tag != &md_nil_node) + { + result = default_tag->first->string; + break; + } + } scratch_end(scratch); } } @@ -2587,8 +2599,14 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) E_Member *member = &type->members[member_idx]; String8 child_name = member->name; MD_Node *member_schema = md_child_from_string(schema, child_name, 0); + MD_Node *default_root = md_tag_from_string(member_schema, str8_lit("default"), 0); String8 member_type_name = member_schema->first->string; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); + String8 child_value = child->first->string; + if(child_value.size == 0) + { + child_value = default_root->first->string; + } if(str8_match(member_type_name, str8_lit("path_pt"), 0)) { U64 off = type->byte_size + variable_width_parts.total_size; @@ -2609,18 +2627,18 @@ rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) { 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, child->first->string); + str8_list_push(scratch.arena, &variable_width_parts, child_value); str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); } else if(str8_match(member_type_name, str8_lit("u64"), 0)) { U64 val = 0; - try_u64_from_str8_c_rules(child->first->string, &val); + try_u64_from_str8_c_rules(child_value, &val); str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&val))); } else if(str8_match(member_type_name, str8_lit("bool"), 0)) { - B32 val = str8_match(child->first->string, str8_lit("1"), 0); + B32 val = str8_match(child_value, str8_lit("1"), 0); str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8((U8 *)&val, e_type_byte_size_from_key(member->type_key)))); } } @@ -3000,18 +3018,11 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { U64 value = 0; MemoryCopy(&value, in, dim_1u64(range)); - if(value == 0) + if(child == &rd_nil_cfg) { - rd_cfg_release(child); - } - else - { - if(child == &rd_nil_cfg) - { - child = rd_cfg_new(cfg, child_name); - } - rd_cfg_new_replacef(child, "%I64u", value); + child = rd_cfg_new(cfg, child_name); } + rd_cfg_new_replacef(child, "%I64u", value); result = 1; break; } @@ -3409,7 +3420,7 @@ rd_view_ui(Rng2F32 rect) } //- rjf: determine dimensions - F32 search_row_height_target = floor_f32(ui_top_font_size()*2.5f); + F32 search_row_height_target = ui_top_px_height(); F32 search_row_height = search_row_open_t*search_row_height_target; search_row_height = Min(search_row_height, dim_2f32(rect).y); rect.y0 += search_row_height; @@ -3753,7 +3764,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: unpack arguments // EV_View *eval_view = rd_view_eval_view(); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + F32 row_height_px = ui_top_px_height(); S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; @@ -5327,7 +5338,7 @@ rd_view_ui(Rng2F32 rect) is_activated_on_single_click = 0; } String8 searched_string = cell_info.string; - if(cell->fstrs.node_count != 0) + if(cell_info.fstrs.node_count != 0) { searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); } @@ -5351,7 +5362,7 @@ rd_view_ui(Rng2F32 rect) RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderPlaceholder*(row_depth==0 && cell == row_info->cells.first && !is_button)| + RD_LineEditFlag_ExpanderSpace*(row_depth==0 && cell == row_info->cells.first && !is_button)| RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; @@ -5578,161 +5589,6 @@ rd_view_ui(Rng2F32 rect) //- rjf: bump x pixel coordinate cell_x_px = next_cell_x_px; - - //- 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_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); - } - - //- rjf: [DEV] hovering -> eval system tooltips - if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) - { - local_persist char *spaces = " "; - String8 string = ev_expr_string_from_row(scratch.arena, row, 0); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - ui_labelf("Text:"); - ui_label(string); - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Tokens:"); - for(U64 idx = 0; idx < tokens.count; idx += 1) - { - ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range)); - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Expression:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_Expr *expr; - S64 depth; - }; - Task start_task = {0, 0, parse.exprs.last}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 ext = {0}; - switch(t->expr->kind) - { - default: - { - if(t->expr->string.size != 0) - { - ext = push_str8f(scratch.arena, "'%S'", t->expr->string); - } - else if(t->expr->value.u32 != 0) - { - ext = push_str8f(scratch.arena, "0x%x", t->expr->value.u32); - } - else if(t->expr->value.f32 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f32); - } - else if(t->expr->value.f64 != 0) - { - ext = push_str8f(scratch.arena, "%f", t->expr->value.f64); - } - else if(t->expr->value.u64 != 0) - { - ext = push_str8f(scratch.arena, "0x%I64x", t->expr->value.u64); - } - }break; - } - ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext); - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->expr = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("IR Tree:"); - { - typedef struct Task Task; - struct Task - { - Task *next; - Task *prev; - E_IRNode *node; - S64 depth; - }; - Task start_task = {0, 0, irtree.root}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - String8 op_string = {0}; - switch(t->node->op) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string); - for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->node = child; - task->depth = t->depth+1; - DLLInsert(first_task, last_task, t, task); - } - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Op List:"); - { - for(E_Op *op = oplist.first; op != 0; op = op->next) - { - String8 op_string = {0}; - switch(op->opcode) - { - default:{}break; - case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break; - case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break; -#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break; - RDI_EvalOp_XList -#undef X - } - String8 ext = {0}; - switch(op->opcode) - { - case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break; - default: - { - ext = str8_from_u64(scratch.arena, op->value.u64, 16, 0, 0); - }break; - } - ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext); - } - } - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Bytecode:"); - { - for(U64 idx = 0; idx < bytecode.size; idx += 1) - { - ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]); - } - } - } } } @@ -5783,7 +5639,7 @@ rd_view_ui(Rng2F32 rect) // if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) { - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + if(ui_is_focus_active() && rd_cfg_child_from_string(view, str8_lit("lister")) == &rd_nil_cfg && ui_slot_press(UI_EventActionSlot_Cancel)) { vs->query_is_selected = 0; vs->query_string_size = 0; @@ -6657,8 +6513,8 @@ rd_window_frame(void) ui_push_font(main_font); ui_push_font_size(main_font_size); ui_push_text_padding(main_font_size*0.3f); - ui_push_pref_width(ui_em(20.f, 1)); - ui_push_pref_height(ui_em(2.75f, 1.f)); + ui_push_pref_width(ui_px(floor_f32(ui_top_font_size()*20.f), 1.f)); + ui_push_pref_height(ui_px(floor_f32(ui_top_font_size()*3.f), 1.f)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; if(rd_setting_b32_from_name(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} @@ -6671,8 +6527,8 @@ rd_window_frame(void) // Rng2F32 window_rect = os_client_rect_from_window(ws->os); Vec2F32 window_rect_dim = dim_2f32(window_rect); - Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_pref_height().value); - Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_pref_height().value, window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); + Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_px_height()); + Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_px_height(), window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); Rng2F32 content_rect = r2f32p(window_rect.x0, top_bar_rect.y1, window_rect.x0+window_rect_dim.x, bottom_bar_rect.y0); F32 window_edge_px = os_dpi_from_window(ws->os)*0.035f; content_rect = pad_2f32(content_rect, -window_edge_px); @@ -8312,21 +8168,20 @@ rd_window_frame(void) { predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); } - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + F32 row_height_px = ui_top_px_height(); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); if(ws->hover_eval_focused) { max_row_count *= 3; } U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 num_rows_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "hover_eval_num_rows_t"), (F32)needed_row_count); - F32 width_px = 60.f*ui_top_font_size(); - F32 height_px = num_rows_t*row_height_px; + F32 width_px = floor_f32(70.f*ui_top_font_size()); + F32 height_px = needed_row_count*row_height_px; // rjf: if arbitrary visualizer, pick catchall size if(view_ui_rule != &rd_nil_view_ui_rule) { - height_px = 40.f*ui_top_font_size(); + height_px = floor_f32(40.f*ui_top_font_size()); } // rjf: determine hover eval top-level rect @@ -8360,18 +8215,17 @@ rd_window_frame(void) //- rjf: try to add opened query if(query_is_open) { - // rjf: close queries - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - // rjf: unpack query info - String8 cmd_name = ws->query_cmd_name; + String8 cmd_name = ws->query_regs->cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - B32 size_query_by_expr_eval = (cmd_kind_info->query.expr.size == 0); + String8 query_expr = ws->query_regs->expr; + if(cmd_name.size != 0) + { + query_expr = cmd_kind_info->query.expr; + } B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); - F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); + B32 query_is_lister = (cmd_name.size != 0); + B32 size_query_by_expr_eval = (query_is_anchored || query_expr.size == 0); // rjf: build view for query RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); @@ -8379,29 +8233,35 @@ rd_window_frame(void) RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); rd_cfg_new_replace(cmd, cmd_name); - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->query_is_selected = 1; - - // rjf: compute query expression - String8 query_expression = cmd_kind_info->query.expr; - if(query_expression.size == 0) + if(query_is_lister) { - query_expression = str8(vs->query_buffer, vs->query_string_size); + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + vs->query_is_selected = 1; } else { - U64 input_insertion_pos = str8_find_needle(query_expression, 0, str8_lit("$input"), 0); - if(input_insertion_pos < query_expression.size) + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); + } + + // rjf: compute query expression + if(query_expr.size == 0) + { + query_expr = str8(vs->query_buffer, vs->query_string_size); + } + else + { + U64 input_insertion_pos = str8_find_needle(query_expr, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expr.size) { - String8 pre_insertion = str8_prefix(query_expression, input_insertion_pos); - String8 post_insertion = str8_skip(query_expression, input_insertion_pos + 6); - query_expression = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + String8 pre_insertion = str8_prefix(query_expr, input_insertion_pos); + String8 post_insertion = str8_skip(query_expr, input_insertion_pos + 6); + query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); } } // rjf: based on query expression, determine if we have an explicit root - if(query_expression.size == 0) + if(0 && (query_expr.size == 0 || !query_is_lister)) { RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); @@ -8412,9 +8272,10 @@ rd_window_frame(void) } // rjf: evaluate query expression - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expression); + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); // rjf: compute query view's top-level rectangle + F32 row_height_px = ui_top_px_height(); Rng2F32 rect = {0}; RD_RegsScope(.view = view->id) { @@ -8426,7 +8287,7 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - query_height_px = row_height_px*predicted_block_tree.total_row_count; + query_height_px = row_height_px * (predicted_block_tree.total_row_count-1); query_height_px = Min(query_height_px, max_query_height_px); } rect = r2f32p(content_rect_center.x - query_width_px/2, @@ -8440,7 +8301,7 @@ rd_window_frame(void) { rect.x0 = anchor_box->rect.x0; rect.y0 = anchor_box->rect.y1; - rect.x1 = rect.x0 + ui_top_font_size()*40.f; + rect.x1 = rect.x0 + ui_top_font_size()*60.f; rect.y1 = rect.y0 + query_height_px; } } @@ -8455,7 +8316,7 @@ rd_window_frame(void) t->row_height_px = row_height_px; t->rect = rect; t->view_name = str8_lit("watch"); - t->expr = query_expression; + t->expr = query_expr; t->is_focused = 1; t->is_anchored = query_is_anchored; } @@ -8469,7 +8330,7 @@ rd_window_frame(void) RD_Font(RD_FontSlot_Code) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") - UI_Focus(ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) + UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) { F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); @@ -8629,9 +8490,15 @@ rd_window_frame(void) //- rjf: query interactions if(query_floating_view_task) { - String8 cmd_name = ws->query_cmd_name; + String8 cmd_name = ws->query_regs->cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + // rjf: close queries + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + // rjf: any queries which take a file path mutate the debugger's "current path" if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) { @@ -9110,14 +8977,12 @@ rd_window_frame(void) panel_rect_pct.x1*content_rect_dim.x, panel_rect_pct.y1*content_rect_dim.y); panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); - F32 tab_bar_rheight = ui_top_font_size()*3.f; - F32 tab_bar_vheight = ui_top_font_size()*2.6f; + F32 tab_bar_rheight = floor_f32(ui_top_font_size()*3.5f); + F32 tab_bar_vheight = floor_f32(ui_top_font_size()*3.f); F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; - F32 tab_spacing = ui_top_font_size()*0.4f; - F32 filter_bar_height = ui_top_font_size()*3.f; + F32 tab_spacing = floor_f32(ui_top_font_size()*0.4f); Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); Rng2F32 content_rect = r2f32p(panel_rect.x0, panel_rect.y0+tab_bar_vheight, panel_rect.x1, panel_rect.y1); - Rng2F32 filter_rect = {0}; if(panel->tab_side == Side_Max) { tab_bar_rect.y0 = panel_rect.y1 - tab_bar_vheight; @@ -9444,16 +9309,6 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); } - if(ui_right_clicked(panel_sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .view = panel->selected_tab->id, - .file_path = rd_file_path_from_eval_string(rd_frame_arena(), rd_expr_from_cfg(panel->selected_tab)), - .ui_key = panel_box->key, - .off_px = sub_2f32(ui_mouse(), panel_box->rect.p0), - .reg_slot = RD_RegSlot_View, - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); - } } ////////////////////////// @@ -9667,10 +9522,9 @@ rd_window_frame(void) else if(ui_right_clicked(sig)) { rd_cmd(RD_CmdKind_PushQuery, - .reg_slot = RD_RegSlot_View, .ui_key = sig.box->key, .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), - .lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings); + .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); } else if(ui_middle_clicked(sig)) { @@ -13479,22 +13333,6 @@ rd_frame(void) 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[] = - { - str8_lit("breakpoint"), - str8_lit("watch_pin"), - str8_lit("target"), - str8_lit("file_path_map"), - str8_lit("auto_view_rule"), - str8_lit("recent_project"), - str8_lit("recent_file"), - str8_lit("machine"), - str8_lit("process"), - str8_lit("thread"), - str8_lit("module"), - }; - //- rjf: build special member types for evallable meta types E_TypeKey bool_type_key = {0}; E_TypeKey u64_type_key = {0}; @@ -13533,10 +13371,10 @@ rd_frame(void) { str8_lit("string"), string_type_key }, { str8_lit("path_pt"), path_pt_type_key }, }; - E_TypeKey evallable_meta_types[ArrayCount(evallable_meta_names)] = {0}; - for EachElement(idx, evallable_meta_names) + E_TypeKey evallable_meta_types[ArrayCount(rd_name_schema_info_table)] = {0}; + for EachElement(idx, rd_name_schema_info_table) { - String8 name = evallable_meta_names[idx]; + String8 name = rd_name_schema_info_table[idx].name; MD_Node *schema = rd_schema_from_name(scratch.arena, name); E_MemberList members_list = {0}; U64 off = 0; @@ -13577,14 +13415,14 @@ rd_frame(void) //- rjf: cache meta name -> type key correllation rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); - for EachElement(idx, evallable_meta_names) + for EachElement(idx, rd_name_schema_info_table) { - String8 name = evallable_meta_names[idx]; + String8 name = rd_name_schema_info_table[idx].name; E_TypeKey type_key = evallable_meta_types[idx]; e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); } - //- rjf: add macros for evallable config trees + //- rjf: add macros for evallable top-level config trees String8 evallable_cfg_names[] = { str8_lit("breakpoint"), @@ -13610,7 +13448,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64u", cfg->id), expr); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", cfg->id), expr); if(exe.size != 0) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); @@ -13622,6 +13460,32 @@ rd_frame(void) } } + //- rjf: add macros for windows/tabs + { + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) + { + RD_Cfg *window = n->v; + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *p = panel_tree.root; + p != &rd_nil_panel_node; + p = rd_panel_node_rec__depth_first_pre(panel_tree.root, p).next) + { + for(RD_CfgNode *tab_n = p->tabs.first; tab_n != 0; tab_n = tab_n->next) + { + RD_Cfg *tab = tab_n->v; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, tab->string); + E_Space space = rd_eval_space_from_cfg(tab); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", tab->id), expr); + } + } + } + } + //- rjf: add macros for evallable control entities String8 evallable_ctrl_names[] = { @@ -14607,9 +14471,9 @@ rd_frame(void) { selection_cfg = p_selection; } - else + else for(RD_Cfg *s = p_selection; s != &rd_nil_cfg; s = rd_cfg_child_from_string(p_cfg, str8_lit("selected"))) { - rd_cfg_release(p_selection); + rd_cfg_release(s); } } if(selection_cfg == &rd_nil_cfg) @@ -14890,9 +14754,9 @@ rd_frame(void) { selection_cfg = tab_selection_cfg; } - else + else for(RD_Cfg *s = tab_selection_cfg; s != &rd_nil_cfg; s = rd_cfg_child_from_string(n->v, str8_lit("selected"))) { - rd_cfg_release(tab_selection_cfg); + rd_cfg_release(s); } } if(selection_cfg == &rd_nil_cfg) @@ -16105,7 +15969,6 @@ Z(getting_started) { ws->query_is_active = 1; arena_clear(ws->query_arena); - ws->query_cmd_name = push_str8_copy(ws->query_arena, cmd_name); ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); } RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); @@ -16125,25 +15988,28 @@ Z(getting_started) // rjf: choose initial input string String8 initial_input = {0}; - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + if(cmd_name.size != 0) { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); - String8 current_path_string = current_path->first->string; - if(current_path_string.size == 0) + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) { - current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); + String8 current_path_string = current_path->first->string; + if(current_path_string.size == 0) + { + current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + } + else + { + current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + } + initial_input = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = push_str8f(scratch.arena, "%S/", initial_input); } - else + else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) { - current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = input->first->string; } - initial_input = path_normalized_from_string(scratch.arena, current_path_string); - initial_input = push_str8f(scratch.arena, "%S/", initial_input); - } - else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) - { - initial_input = input->first->string; } // rjf: build query state @@ -16151,23 +16017,26 @@ Z(getting_started) rd_cfg_new_replace(cmd, cmd_name); String8 current_query_cmd_name = cmd->first->string; RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + if(cmd_name.size != 0) { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = txt_pt(1, 1); - } - else - { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = vs->query_cursor; - } - if(!str8_match(current_query_cmd_name, cmd_name, 0)) - { - vs->query_is_selected = 1; - } - else - { - vs->query_is_selected ^= 1; + if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); + } + else + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = vs->query_cursor; + } + if(!str8_match(current_query_cmd_name, cmd_name, 0)) + { + vs->query_is_selected = 1; + } + else + { + vs->query_is_selected ^= 1; + } } }break; case RD_CmdKind_CompleteQuery: @@ -16200,7 +16069,7 @@ Z(getting_started) { ws->query_is_active = 0; arena_clear(ws->query_arena); - ws->query_cmd_name = str8_zero(); + ws->query_regs = 0; } }break; case RD_CmdKind_UpdateQuery: diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ce58fcee..a00facae 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -552,7 +552,6 @@ struct RD_WindowState // rjf: query state B32 query_is_active; Arena *query_arena; - String8 query_cmd_name; RD_Regs *query_regs; // rjf: hover eval state diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 7a6ee821..3f556bd6 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1082,8 +1082,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } } @@ -1251,8 +1251,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1879,7 +1879,6 @@ struct RD_DisasmViewState B32 initialized; TxtPt cursor; TxtPt mark; - DASM_StyleFlags style_flags; CTRL_Handle temp_look_process; U64 temp_look_vaddr; U64 temp_look_run_gen; @@ -1903,7 +1902,6 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) dv->initialized = 1; dv->cursor = txt_pt(1, 1); dv->mark = txt_pt(1, 1); - dv->style_flags = DASM_StyleFlag_Addresses|DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines|DASM_StyleFlag_SymbolNames; rd_code_view_init(&dv->cv); } RD_CodeViewState *cv = &dv->cv; @@ -1962,8 +1960,6 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) dv->temp_look_run_gen = ctrl_run_gen(); dv->goto_vaddr = cmd->regs->vaddr; }break; - case RD_CmdKind_ToggleCodeBytesVisibility: {dv->style_flags ^= DASM_StyleFlag_CodeBytes;}break; - case RD_CmdKind_ToggleAddressVisibility: {dv->style_flags ^= DASM_StyleFlag_Addresses;}break; } } @@ -1992,14 +1988,35 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) base_vaddr = dasm_module->vaddr_range.min; }break; } + DASM_StyleFlags style_flags = 0; + DASM_Syntax syntax = DASM_Syntax_Intel; + { + if(rd_setting_b32_from_name(str8_lit("show_addresses"))) + { + style_flags |= DASM_StyleFlag_Addresses; + } + if(rd_setting_b32_from_name(str8_lit("show_code_bytes"))) + { + style_flags |= DASM_StyleFlag_CodeBytes; + } + if(rd_setting_b32_from_name(str8_lit("show_source_lines"))) + { + style_flags |= DASM_StyleFlag_SourceFilesNames; + style_flags |= DASM_StyleFlag_SourceLines; + } + if(rd_setting_b32_from_name(str8_lit("show_symbol_names"))) + { + style_flags |= DASM_StyleFlag_SymbolNames; + } + } U128 dasm_key = rd_key_from_eval_space_range(space, range, 0); U128 dasm_data_hash = {0}; DASM_Params dasm_params = {0}; { dasm_params.vaddr = range.min; dasm_params.arch = arch; - dasm_params.style_flags = dv->style_flags; - dasm_params.syntax = DASM_Syntax_Intel; + dasm_params.style_flags = style_flags; + dasm_params.syntax = syntax; dasm_params.base_vaddr = base_vaddr; dasm_params.dbgi_key = dbgi_key; } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 549ad5ad..0b961ee4 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1611,7 +1611,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64u", bp->id), str8_zero()); + rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64x", bp->id), str8_zero()); RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1632,17 +1632,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_RegsScope(.cfg = bp->id) rd_drag_begin(RD_RegSlot_Cfg); } - - // rjf: bp right-click menu - if(ui_right_clicked(bp_sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .cfg = bp->id, - .reg_slot = RD_RegSlot_Cfg, - .ui_key = bp_box->key, - .off_px = v2f32(0, bp_box->rect.y1-bp_box->rect.y0), - .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); - } } //- rjf: build margin watch pin ui @@ -1673,7 +1662,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64u", pin->id), str8_zero()); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64x", pin->id), str8_zero()); RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); } @@ -1688,17 +1677,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } - - // rjf: watch right-click menu - if(ui_right_clicked(pin_sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .cfg = pin->id, - .reg_slot = RD_RegSlot_Cfg, - .ui_key = pin_box->key, - .off_px = v2f32(0, pin_box->rect.y1-pin_box->rect.y0), - .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); - } } } @@ -1915,15 +1893,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); } - if(ui_right_clicked(sig)) - { - rd_cmd(RD_CmdKind_PushQuery, - .cfg = pin->id, - .reg_slot = RD_RegSlot_Cfg, - .ui_key = sig.box->key, - .off_px = v2f32(0, sig.box->rect.y1-sig.box->rect.y0), - .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); - } } rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); rd_code_label(0.6f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), eval_string); @@ -2075,6 +2044,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min]; lines = params->line_infos[cursor->line - params->line_num_range.min]; } +#if 0 // TODO(rjf): @cfg rd_cmd(RD_CmdKind_PushQuery, .reg_slot = RD_RegSlot_Cursor, .ui_key = ui_get_selected_state()->root->key, @@ -2084,6 +2054,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe .vaddr = vaddr, .lines = lines, .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); +#endif } //- rjf: dragging threads, breakpoints, or watch pins over this slice -> @@ -2817,6 +2788,7 @@ rd_label(String8 string) fstr.params.font = ui_top_font(); fstr.params.color = ui_color_from_name(str8_lit("text")); fstr.params.size = ui_top_font_size(); + fstr.params.raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main); if(p->flags & StringPartFlag_Code) { fstr.params.font = rd_font_from_slot(RD_FontSlot_Code); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index bef1b74c..a35d5fc8 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -3411,6 +3411,21 @@ ui_push_tagf(char *fmt, ...) scratch_end(scratch); } +internal F32 +ui_top_px_height(void) +{ + F32 result = ui_top_font_size(); + for(UI_PrefHeightNode *n = ui_state->pref_height_stack.top; n != 0; n = n->next) + { + if(n->v.kind == UI_SizeKind_Pixels) + { + result = n->v.value; + break; + } + } + return result; +} + //////////////////////////////// //~ rjf: Generated Code diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index bfe298e8..5968c4fc 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -1112,6 +1112,7 @@ internal UI_Size ui_set_next_pref_size(Axis2 axis, UI_Size v); internal void ui_push_corner_radius(F32 v); internal void ui_pop_corner_radius(void); internal void ui_push_tagf(char *fmt, ...); +internal F32 ui_top_px_height(void); //////////////////////////////// //~ rjf: Macro Loop Wrappers From e2bfecc38405f8f989925e2ae920a8efa7c07084 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 15:01:40 -0700 Subject: [PATCH 227/755] further work on rich hover vs. hover eval vs. ctx menu arrangements; it's a bit too noisy/annoying when hover eval for breakpoints/threads/etc. is just turned on all the time, and now that we have the ability to hover-eval-style query views, because of tabs, we can just do that with breakpoints etc. too. the old rich hover tooltips / highlights / etc. can then just be used normally. also put in some mechanisms to block rich hover tooltips when it is strictly redundant information. --- .../eval_visualization_core.c | 1 + src/raddbg/generated/raddbg.meta.c | 3 +- src/raddbg/generated/raddbg.meta.h | 5 ++- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 15 ++++---- src/raddbg/raddbg_widgets.c | 36 ++++++++++++++++--- 6 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 1b2787a6..0fbf7636 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1117,6 +1117,7 @@ internal B32 ev_row_is_expandable(EV_Row *row) { B32 result = 0; + if(!ev_key_match(ev_key_root(), row->block->key)) { Temp scratch = scratch_begin(0, 0); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7d50c11b..3d0e2645 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -331,7 +331,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[40] = +Rng1U64 rd_reg_slot_range_table[41] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -368,6 +368,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, pid), OffsetOf(RD_Regs, pid) + sizeof(U32)}, {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, +{OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, {OffsetOf(RD_Regs, dir2), OffsetOf(RD_Regs, dir2) + sizeof(Dir2)}, {OffsetOf(RD_Regs, string), OffsetOf(RD_Regs, string) + sizeof(String8)}, {OffsetOf(RD_Regs, cmd_name), OffsetOf(RD_Regs, cmd_name) + sizeof(String8)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index f1219447..e9f13273 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -43,6 +43,7 @@ RD_RegSlot_RegSlot, RD_RegSlot_PID, RD_RegSlot_ForceConfirm, RD_RegSlot_PreferDisasm, +RD_RegSlot_NoRichTooltip, RD_RegSlot_Dir2, RD_RegSlot_String, RD_RegSlot_CmdName, @@ -564,6 +565,7 @@ RD_RegSlot reg_slot; U32 pid; B32 force_confirm; B32 prefer_disasm; +B32 no_rich_tooltip; Dir2 dir2; String8 string; String8 cmd_name; @@ -627,6 +629,7 @@ RD_Query query; .pid = rd_regs()->pid,\ .force_confirm = rd_regs()->force_confirm,\ .prefer_disasm = rd_regs()->prefer_disasm,\ +.no_rich_tooltip = rd_regs()->no_rich_tooltip,\ .dir2 = rd_regs()->dir2,\ .string = rd_regs()->string,\ .cmd_name = rd_regs()->cmd_name,\ @@ -636,7 +639,7 @@ RD_Query query; C_LINKAGE_BEGIN extern RD_VocabInfo rd_vocab_info_table[303]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; -extern Rng1U64 rd_reg_slot_range_table[40]; +extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[69]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 44c91b8f..436b155e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -369,6 +369,7 @@ RD_RegTable: {U32 pid PID } {B32 force_confirm ForceConfirm } {B32 prefer_disasm PreferDisasm } + {B32 no_rich_tooltip NoRichTooltip } {Dir2 dir2 Dir2 } {String8 string String } {String8 cmd_name CmdName } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2493bb20..98dca750 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2136,7 +2136,8 @@ rd_color_from_cfg(RD_Cfg *cfg) internal B32 rd_disabled_from_cfg(RD_Cfg *cfg) { - B32 is_disabled = (rd_cfg_child_from_string(cfg, str8_lit("disabled")) != &rd_nil_cfg); + String8 disabled_value_string = rd_cfg_child_from_string(cfg, str8_lit("disabled"))->first->string; + B32 is_disabled = (disabled_value_string.size != 0 && !str8_match(disabled_value_string, str8_lit("0"), 0)); return is_disabled; } @@ -5409,13 +5410,13 @@ rd_view_ui(Rng2F32 rect) // rjf: hover -> rich hover cfgs if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) { - RD_RegsScope(.cfg = cell_info.cfg->id) rd_set_hover_regs(RD_RegSlot_Cfg); + RD_RegsScope(.cfg = cell_info.cfg->id, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_Cfg); } // rjf: hover -> rich hover entities if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) { - RD_RegsScope(.ctrl_entity = cell_info.entity->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); + RD_RegsScope(.ctrl_entity = cell_info.entity->handle, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } // rjf: dragging -> drag/drop @@ -6546,9 +6547,9 @@ rd_window_frame(void) } //////////////////////////// - //- rjf: @window_ui_part drag/drop tooltips + //- rjf: @window_ui_part rich hover / drag/drop tooltips // - if(rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) + if((rd_state->hover_regs_slot != RD_RegSlot_Null && !rd_state->hover_regs->no_rich_tooltip) || (rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active())) { Temp scratch = scratch_begin(0, 0); RD_RegSlot slot = ((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs_slot : rd_state->hover_regs_slot); @@ -8261,7 +8262,7 @@ rd_window_frame(void) } // rjf: based on query expression, determine if we have an explicit root - if(0 && (query_expr.size == 0 || !query_is_lister)) + if(query_expr.size == 0 || !query_is_lister) { RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); @@ -8287,7 +8288,7 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - query_height_px = row_height_px * (predicted_block_tree.total_row_count-1); + query_height_px = row_height_px * predicted_block_tree.total_row_count; query_height_px = Min(query_height_px, max_query_height_px); } rect = r2f32p(content_rect_center.x - query_width_px/2, diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0b961ee4..8c553b87 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1388,9 +1388,15 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } + if(ui_right_clicked(thread_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = thread_box->key, + .off_px = v2f32(0, dim_2f32(thread_box->rect).y), + .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); + } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { RD_RegsScope(.thread = thread->handle) rd_drag_begin(RD_RegSlot_Thread); @@ -1536,9 +1542,15 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: interactions if(ui_hovering(thread_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(thread_box->rect.x0, thread_box->rect.y1-2.f), ctrl_string_from_handle(scratch.arena, thread->handle), str8_zero()); RD_RegsScope(.ctrl_entity = thread->handle) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } + if(ui_right_clicked(thread_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = thread_box->key, + .off_px = v2f32(0, dim_2f32(thread_box->rect).y), + .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); + } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { RD_RegsScope(.thread = thread->handle) rd_drag_begin(RD_RegSlot_Thread); @@ -1611,10 +1623,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: bp hovering if(ui_hovering(bp_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(bp_box->rect.x0, bp_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64x", bp->id), str8_zero()); RD_RegsScope(.cfg = bp->id) rd_set_hover_regs(RD_RegSlot_Cfg); } + // rjf: bp right-click => open query + if(ui_right_clicked(bp_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = bp_box->key, + .off_px = v2f32(0, dim_2f32(bp_box->rect).y), + .expr = push_str8f(scratch.arena, "$%I64x", bp->id)); + } + // rjf: shift+click => enable breakpoint if(ui_clicked(bp_sig) && bp_sig.event_flags & OS_Modifier_Shift) { @@ -1662,10 +1682,18 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: watch hovering if(ui_hovering(pin_sig) && !rd_drag_is_active()) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), push_str8f(scratch.arena, "$%I64x", pin->id), str8_zero()); RD_RegsScope(.cfg = pin->id) rd_set_hover_regs(RD_RegSlot_Cfg); } + // rjf: pin right-click => open query + if(ui_right_clicked(pin_sig)) + { + rd_cmd(RD_CmdKind_PushQuery, + .ui_key = pin_box->key, + .off_px = v2f32(0, dim_2f32(pin_box->rect).y), + .expr = push_str8f(scratch.arena, "$%I64x", pin->id)); + } + // rjf: click => remove pin if(ui_clicked(pin_sig)) { From 5596f1c8a364e6339e1578e089d2fe9457ab9040 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 16:00:23 -0700 Subject: [PATCH 228/755] more convergence, fixes, use new tab options mechanism to allow disabling line numbers in text/disasm --- src/raddbg/generated/raddbg.meta.c | 7 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 3 + src/raddbg/raddbg_core.c | 941 +++++++++++++++-------------- src/raddbg/raddbg_views.c | 13 +- src/raddbg/raddbg_views.h | 4 +- src/raddbg/raddbg_widgets.c | 8 +- src/ui/ui_basic_widgets.c | 8 +- 8 files changed, 516 insertions(+), 470 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 3d0e2645..e91c85cd 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[303] = +RD_VocabInfo rd_vocab_info_table[304] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -93,6 +93,7 @@ RD_VocabInfo rd_vocab_info_table[303] = {str8_lit_comp("show_code_bytes"), str8_lit_comp(""), str8_lit_comp("Show Code Bytes"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("show_source_lines"), str8_lit_comp(""), str8_lit_comp("Show Source Lines"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("show_symbol_names"), str8_lit_comp(""), str8_lit_comp("Show Symbol Names"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("show_line_numbers"), str8_lit_comp(""), str8_lit_comp("Show Line Numbers"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, @@ -314,8 +315,8 @@ RD_VocabInfo rd_vocab_info_table[303] = RD_NameSchemaInfo rd_name_schema_info_table[16] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n 'syntax': dasm_syntax,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n 'syntax': dasm_syntax,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e9f13273..51b9bce9 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -637,7 +637,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[303]; +extern RD_VocabInfo rd_vocab_info_table[304]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 436b155e..3b8c593d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -106,6 +106,7 @@ RD_VocabTable: {show_code_bytes "" "Show Code Bytes" "" Null } {show_source_lines "" "Show Source Lines" "" Null } {show_symbol_names "" "Show Symbol Names" "" Null } + {show_line_numbers "" "Show Line Numbers" "" Null } {syntax syntaxes "Syntax" "Syntaxes" Null } } @@ -166,6 +167,7 @@ RD_VocabTable: { 'lang':lang, 'size':code_string, + @default(1) 'show_line_numbers':bool, } ``` } @@ -180,6 +182,7 @@ RD_VocabTable: @default(0) 'show_code_bytes': bool, @default(1) 'show_source_lines': bool, @default(1) 'show_symbol_names': bool, + @default(1) 'show_line_numbers': bool, 'syntax': dasm_syntax, } ``` diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 98dca750..7629e110 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5363,7 +5363,7 @@ rd_view_ui(Rng2F32 rect) RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| RD_LineEditFlag_KeyboardClickable| RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderSpace*(row_depth==0 && cell == row_info->cells.first && !is_button)| + RD_LineEditFlag_ExpanderSpace*(row_depth==!implicit_root && cell == row_info->cells.first && !is_button)| RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; @@ -7290,6 +7290,492 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: @window_ui_part gather all tasks to build floating views + // + typedef struct FloatingViewTask FloatingViewTask; + struct FloatingViewTask + { + FloatingViewTask *next; + RD_Cfg *view; + F32 row_height_px; + Rng2F32 rect; + String8 view_name; + String8 expr; + B32 is_focused; + B32 is_anchored; + UI_Signal signal; // NOTE(rjf): output, from build + B32 pressed; + B32 pressed_outside; + }; + FloatingViewTask *hover_eval_floating_view_task = 0; + FloatingViewTask *query_floating_view_task = 0; + FloatingViewTask *first_floating_view_task = 0; + FloatingViewTask *last_floating_view_task = 0; + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + { + //- rjf: try to add hover eval first + { + B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); + + // rjf: disable hover eval if hovered view is actively scrolling + if(hover_eval_is_open) + { + for(RD_PanelNode *panel = panel_tree.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) + { + if(panel->first != &rd_nil_panel_node) { continue; } + RD_Cfg *tab = panel->selected_tab; + if(tab != &rd_nil_cfg) + { + RD_ViewState *vs = rd_view_state_from_cfg(tab); + Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); + if(contains_2f32(panel_rect, ui_mouse()) && + (abs_f32(vs->scroll_pos.x.off) > 0.01f || + abs_f32(vs->scroll_pos.y.off) > 0.01f)) + { + build_hover_eval = 0; + ws->hover_eval_firstt_us = rd_state->time_in_us; + } + } + } + } + + // rjf: choose hover evaluation expression + String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + + // rjf: evaluate hover evaluation expression, & determine if it evaluates + // such that we want to build a hover eval. + E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + { + if(hover_eval.msgs.max_kind > E_MsgKind_Null) + { + build_hover_eval = 0; + } + else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) + { + build_hover_eval = 0; + } + else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) + { + build_hover_eval = 0; + } + } + + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + + // rjf: determine view name + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } + + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + + // rjf: request frames if we're waiting to open + if(ws->hover_eval_string.size != 0 && + !hover_eval_is_open && + ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && + rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) + { + rd_request_frame(); + } + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id) + { + predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + } + F32 row_height_px = ui_top_px_height(); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 width_px = floor_f32(70.f*ui_top_font_size()); + F32 height_px = needed_row_count*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = floor_f32(40.f*ui_top_font_size()); + } + + // rjf: determine hover eval top-level rect + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + + // rjf: push hover eval task + if(build_hover_eval) + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + hover_eval_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = view_name; + t->expr = hover_eval_expr; + t->is_focused = ws->hover_eval_focused; + t->is_anchored = 1; + } + + // rjf: reset focus state if hover eval is not being built + if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) + { + ws->hover_eval_focused = 0; + } + } + + //- rjf: force-close query, if it's anchored, but box is gone + if(query_is_open) + { + UI_Box *box = ui_box_from_key(ws->query_regs->ui_key); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key) && ui_box_is_nil(box)) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + } + + //- rjf: force-close query, if it has an expression, but that expression does not evaluate + if(query_is_open) + { + String8 expr = ws->query_regs->expr; + E_Eval eval = e_eval_from_string(scratch.arena, expr); + if(eval.msgs.max_kind > E_MsgKind_Null) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + else if(eval.space.kind == RD_EvalSpaceKind_MetaCfg && + rd_cfg_from_eval_space(eval.space) == &rd_nil_cfg) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + else if((eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && + rd_ctrl_entity_from_eval_space(eval.space) == &ctrl_entity_nil) + { + query_is_open = 0; + rd_cmd(RD_CmdKind_CancelQuery); + } + } + + //- rjf: try to add opened query + if(query_is_open) + { + // rjf: unpack query info + String8 cmd_name = ws->query_regs->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + String8 query_expr = ws->query_regs->expr; + if(cmd_name.size != 0) + { + query_expr = cmd_kind_info->query.expr; + } + B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); + B32 query_is_lister = (cmd_name.size != 0); + B32 size_query_by_expr_eval = (query_is_anchored || query_expr.size == 0); + + // rjf: build view for query + RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + rd_cfg_new_replace(cmd, cmd_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(query_is_lister) + { + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + vs->query_is_selected = 1; + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); + } + + // rjf: compute query expression + if(query_expr.size == 0) + { + query_expr = str8(vs->query_buffer, vs->query_string_size); + } + else + { + U64 input_insertion_pos = str8_find_needle(query_expr, 0, str8_lit("$input"), 0); + if(input_insertion_pos < query_expr.size) + { + String8 pre_insertion = str8_prefix(query_expr, input_insertion_pos); + String8 post_insertion = str8_skip(query_expr, input_insertion_pos + 6); + query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + } + } + + // rjf: based on query expression, determine if we have an explicit root + if(query_expr.size == 0 || !query_is_lister) + { + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new(explicit_root, str8_lit("1")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + + // rjf: evaluate query expression + E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); + + // rjf: compute query view's top-level rectangle + F32 row_height_px = ui_top_px_height(); + Rng2F32 rect = {0}; + RD_RegsScope(.view = view->id) + { + Vec2F32 content_rect_center = center_2f32(content_rect); + Vec2F32 content_rect_dim = dim_2f32(content_rect); + EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); + F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); + F32 max_query_height_px = content_rect_dim.y*0.8f; + F32 query_height_px = max_query_height_px; + if(size_query_by_expr_eval) + { + query_height_px = row_height_px * predicted_block_tree.total_row_count; + query_height_px = Min(query_height_px, max_query_height_px); + } + rect = r2f32p(content_rect_center.x - query_width_px/2, + content_rect_center.y - max_query_height_px/2.f, + content_rect_center.x + query_width_px/2, + content_rect_center.y - max_query_height_px/2.f + query_height_px); + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + rect.x0 = anchor_box->rect.x0; + rect.y0 = anchor_box->rect.y1; + rect.x1 = rect.x0 + ui_top_font_size()*60.f; + rect.y1 = rect.y0 + query_height_px; + } + } + } + + // rjf: push query task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + query_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = str8_lit("watch"); + t->expr = query_expr; + t->is_focused = 1; + t->is_anchored = query_is_anchored; + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part build all floating views + // + ProfScope("build all floating views") + RD_Font(RD_FontSlot_Code) + UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_TagF("floating") + UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) + { + F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); + F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) + { + // rjf: unpack + RD_Cfg *view = t->view; + F32 row_height_px = t->row_height_px; + Rng2F32 rect = t->rect; + String8 view_name = t->view_name; + String8 expr = t->expr; + B32 is_focused = t->is_focused; + B32 is_anchored = t->is_anchored; + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); + + // rjf: build cfg tree + RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new(view, str8_lit("selected")); + rd_cfg_new_replace(expr_root, expr); + + // rjf: push view regs + rd_push_regs(.view = view->id); + { + String8 view_expr = rd_expr_from_cfg(view); + String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); + // NOTE(rjf): we want to only fill out this view's file path slot if it + // evaluates one - this way, a view can use the slot to know the selected + // file path (if there is one). this is useful when pushing commandas which + // apply to a cursor, for example. + if(view_file_path.size != 0) + { + rd_regs()->file_path = view_file_path; + } + } + + // rjf: build + UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + { + // rjf: build top-level container box + UI_Box *container = &ui_nil_box; + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) + { + container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DrawDropShadow| + (UI_BoxFlag_SquishAnchored*!!is_anchored), + "floating_view_container_%p", view); + } + + // rjf: peek press inside/outside events + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && + evt->key == OS_Key_LeftMouseButton) + { + if(contains_2f32(container->rect, evt->pos)) + { + t->pressed = 1; + } + else + { + t->pressed_outside = 1; + } + } + } + } + + // rjf: build overlay container for loading animation + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(container) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); + } + + // rjf: build contents + UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) + { + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); + UI_Parent(view_contents_container) UI_WidthFill + { + rd_view_ui(rect); + } + } + + // rjf: build loading overlay + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + F32 loading_t = vs->loading_t; + if(loading_t > 0.01f) UI_Parent(loading_overlay_container) + { + rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + + // rjf: interact with container + UI_Signal sig = ui_signal_from_box(container); + t->signal = sig; + } + + // rjf: pop interaction registers; commit if this is focused + RD_Regs *view_regs = rd_pop_regs(); + if(is_focused) + { + MemoryCopyStruct(rd_regs(), view_regs); + } + + // rjf: is not anchored? -> darken rest of screen + if(!is_anchored) + { + UI_TagF("inactive") UI_Transparency(1-open_t) UI_Rect(content_rect) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); + } + } + } + + //////////////////////////// + //- rjf: @window_ui_part do special handling of floating view interactions + // + { + //- rjf: hover eval focus rules + if(hover_eval_floating_view_task) + { + UI_Signal sig = hover_eval_floating_view_task->signal; + if(ui_pressed(sig) || hover_eval_floating_view_task->pressed) + { + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_lastt_us = rd_state->time_in_us; + } + else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) + { + rd_request_frame(); + } + if(hover_eval_floating_view_task->pressed_outside) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + } + } + + //- rjf: query interactions + if(query_floating_view_task) + { + String8 cmd_name = ws->query_regs->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: close queries + if(ui_slot_press(UI_EventActionSlot_Cancel) || query_floating_view_task->pressed_outside) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + + // rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *view = query_floating_view_task->view; + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) + { + String8 path_chopped = str8_chop_last_slash(input->first->string); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } + } + } + } + //////////////////////////// //- rjf: @window_ui_part top bar // @@ -8062,459 +8548,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: @window_ui_part gather all tasks to build floating views - // - typedef struct FloatingViewTask FloatingViewTask; - struct FloatingViewTask - { - FloatingViewTask *next; - RD_Cfg *view; - F32 row_height_px; - Rng2F32 rect; - String8 view_name; - String8 expr; - B32 is_focused; - B32 is_anchored; - UI_Signal signal; // NOTE(rjf): output, from build - }; - FloatingViewTask *hover_eval_floating_view_task = 0; - FloatingViewTask *query_floating_view_task = 0; - FloatingViewTask *first_floating_view_task = 0; - FloatingViewTask *last_floating_view_task = 0; - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - { - //- rjf: try to add hover eval first - { - B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); - - // rjf: disable hover eval if hovered view is actively scrolling - if(hover_eval_is_open) - { - for(RD_PanelNode *panel = panel_tree.root; - panel != &rd_nil_panel_node; - panel = rd_panel_node_rec__depth_first_pre(panel_tree.root, panel).next) - { - if(panel->first != &rd_nil_panel_node) { continue; } - RD_Cfg *tab = panel->selected_tab; - if(tab != &rd_nil_cfg) - { - RD_ViewState *vs = rd_view_state_from_cfg(tab); - Rng2F32 panel_rect = rd_target_rect_from_panel_node(content_rect, panel_tree.root, panel); - if(contains_2f32(panel_rect, ui_mouse()) && - (abs_f32(vs->scroll_pos.x.off) > 0.01f || - abs_f32(vs->scroll_pos.y.off) > 0.01f)) - { - build_hover_eval = 0; - ws->hover_eval_firstt_us = rd_state->time_in_us; - } - } - } - } - - // rjf: choose hover evaluation expression - String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); - - // rjf: evaluate hover evaluation expression, & determine if it evaluates - // such that we want to build a hover eval. - E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); - { - if(hover_eval.msgs.max_kind > E_MsgKind_Null) - { - build_hover_eval = 0; - } - else if(hover_eval.space.kind == RD_EvalSpaceKind_MetaCfg && - rd_cfg_from_eval_space(hover_eval.space) == &rd_nil_cfg) - { - build_hover_eval = 0; - } - else if((hover_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - hover_eval.space.kind == RD_EvalSpaceKind_CtrlEntity) && - rd_ctrl_entity_from_eval_space(hover_eval.space) == &ctrl_entity_nil) - { - build_hover_eval = 0; - } - } - - // rjf: determine if we have a top-level visualizer - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); - - // rjf: determine view name - String8 view_name = str8_lit("watch"); - if(view_ui_rule != &rd_nil_view_ui_rule) - { - view_name = view_ui_rule->name; - } - - // rjf: build view - RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - - // rjf: request frames if we're waiting to open - if(ws->hover_eval_string.size != 0 && - !hover_eval_is_open && - ws->hover_eval_lastt_us < ws->hover_eval_firstt_us+hover_eval_open_delay_us && - rd_state->time_in_us - ws->hover_eval_lastt_us < hover_eval_open_delay_us*2) - { - rd_request_frame(); - } - - // rjf: determine size of hover evaluation container - EV_BlockTree predicted_block_tree = {0}; - RD_RegsScope(.view = view->id) - { - predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); - } - F32 row_height_px = ui_top_px_height(); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); - if(ws->hover_eval_focused) - { - max_row_count *= 3; - } - U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 width_px = floor_f32(70.f*ui_top_font_size()); - F32 height_px = needed_row_count*row_height_px; - - // rjf: if arbitrary visualizer, pick catchall size - if(view_ui_rule != &rd_nil_view_ui_rule) - { - height_px = floor_f32(40.f*ui_top_font_size()); - } - - // rjf: determine hover eval top-level rect - Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, - ws->hover_eval_spawn_pos.y, - ws->hover_eval_spawn_pos.x + width_px, - ws->hover_eval_spawn_pos.y + height_px); - - // rjf: push hover eval task - if(build_hover_eval) - { - FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); - SLLQueuePush(first_floating_view_task, last_floating_view_task, t); - hover_eval_floating_view_task = t; - t->view = view; - t->row_height_px = row_height_px; - t->rect = rect; - t->view_name = view_name; - t->expr = hover_eval_expr; - t->is_focused = ws->hover_eval_focused; - t->is_anchored = 1; - } - - // rjf: reset focus state if hover eval is not being built - if(!build_hover_eval || ws->hover_eval_string.size == 0 || !hover_eval_is_open) - { - ws->hover_eval_focused = 0; - } - } - - //- rjf: try to add opened query - if(query_is_open) - { - // rjf: unpack query info - String8 cmd_name = ws->query_regs->cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - String8 query_expr = ws->query_regs->expr; - if(cmd_name.size != 0) - { - query_expr = cmd_kind_info->query.expr; - } - B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); - B32 query_is_lister = (cmd_name.size != 0); - B32 size_query_by_expr_eval = (query_is_anchored || query_expr.size == 0); - - // rjf: build view for query - RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - rd_cfg_new_replace(cmd, cmd_name); - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(query_is_lister) - { - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - vs->query_is_selected = 1; - } - else - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); - } - - // rjf: compute query expression - if(query_expr.size == 0) - { - query_expr = str8(vs->query_buffer, vs->query_string_size); - } - else - { - U64 input_insertion_pos = str8_find_needle(query_expr, 0, str8_lit("$input"), 0); - if(input_insertion_pos < query_expr.size) - { - String8 pre_insertion = str8_prefix(query_expr, input_insertion_pos); - String8 post_insertion = str8_skip(query_expr, input_insertion_pos + 6); - query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); - } - } - - // rjf: based on query expression, determine if we have an explicit root - if(query_expr.size == 0 || !query_is_lister) - { - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - } - else - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); - } - - // rjf: evaluate query expression - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); - - // rjf: compute query view's top-level rectangle - F32 row_height_px = ui_top_px_height(); - Rng2F32 rect = {0}; - RD_RegsScope(.view = view->id) - { - Vec2F32 content_rect_center = center_2f32(content_rect); - Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); - F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); - F32 max_query_height_px = content_rect_dim.y*0.8f; - F32 query_height_px = max_query_height_px; - if(size_query_by_expr_eval) - { - query_height_px = row_height_px * predicted_block_tree.total_row_count; - query_height_px = Min(query_height_px, max_query_height_px); - } - rect = r2f32p(content_rect_center.x - query_width_px/2, - content_rect_center.y - max_query_height_px/2.f, - content_rect_center.x + query_width_px/2, - content_rect_center.y - max_query_height_px/2.f + query_height_px); - if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) - { - UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); - if(anchor_box != &ui_nil_box) - { - rect.x0 = anchor_box->rect.x0; - rect.y0 = anchor_box->rect.y1; - rect.x1 = rect.x0 + ui_top_font_size()*60.f; - rect.y1 = rect.y0 + query_height_px; - } - } - } - - // rjf: push query task - { - FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); - SLLQueuePush(first_floating_view_task, last_floating_view_task, t); - query_floating_view_task = t; - t->view = view; - t->row_height_px = row_height_px; - t->rect = rect; - t->view_name = str8_lit("watch"); - t->expr = query_expr; - t->is_focused = 1; - t->is_anchored = query_is_anchored; - } - } - } - - //////////////////////////// - //- rjf: @window_ui_part build all floating views - // - ProfScope("build all floating views") - RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - UI_TagF("floating") - UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) - { - F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); - F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); - for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) - { - // rjf: unpack - RD_Cfg *view = t->view; - F32 row_height_px = t->row_height_px; - Rng2F32 rect = t->rect; - String8 view_name = t->view_name; - String8 expr = t->expr; - B32 is_focused = t->is_focused; - B32 is_anchored = t->is_anchored; - F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); - - // rjf: build cfg tree - RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(view, str8_lit("selected")); - rd_cfg_new_replace(expr_root, expr); - - // rjf: push view regs - rd_push_regs(.view = view->id); - { - String8 view_expr = rd_expr_from_cfg(view); - String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); - // NOTE(rjf): we want to only fill out this view's file path slot if it - // evaluates one - this way, a view can use the slot to know the selected - // file path (if there is one). this is useful when pushing commandas which - // apply to a cursor, for example. - if(view_file_path.size != 0) - { - rd_regs()->file_path = view_file_path; - } - } - - // rjf: build - UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) - UI_PrefHeight(ui_px(row_height_px, 1.f)) - { - // rjf: build top-level container box - UI_Box *container = &ui_nil_box; - UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) - { - container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawBackgroundBlur| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawDropShadow| - (UI_BoxFlag_SquishAnchored*!!is_anchored), - "floating_view_container_%p", view); - } - - // rjf: peek press events -> focus hover eval if we have a press - if(!ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - contains_2f32(container->rect, evt->pos)) - { - ws->hover_eval_focused = 1; - break; - } - } - } - - // rjf: build overlay container for loading animation - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(container) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_Floating, ui_key_zero()); - } - - // rjf: build contents - UI_Parent(container) UI_Focus(is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) - { - ui_set_next_pref_width(ui_pct(1, 0)); - ui_set_next_pref_height(ui_pct(1, 0)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *view_contents_container = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clip, "###view_contents_container"); - UI_Parent(view_contents_container) UI_WidthFill - { - rd_view_ui(rect); - } - } - - // rjf: build loading overlay - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - F32 loading_t = vs->loading_t; - if(loading_t > 0.01f) UI_Parent(loading_overlay_container) - { - rd_loading_overlay(rect, loading_t, vs->loading_progress_v, vs->loading_progress_v_target); - } - } - - // rjf: interact with container - UI_Signal sig = ui_signal_from_box(container); - t->signal = sig; - } - - // rjf: pop interaction registers; commit if this is focused - RD_Regs *view_regs = rd_pop_regs(); - if(is_focused) - { - MemoryCopyStruct(rd_regs(), view_regs); - } - - // rjf: is not anchored? -> darken rest of screen - if(!is_anchored) - { - UI_TagF("inactive") UI_Transparency(1-open_t) UI_Rect(content_rect) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); - } - } - } - - //////////////////////////// - //- rjf: @window_ui_part do special handling of floating view interactions - // - { - //- rjf: hover eval focus rules - if(hover_eval_floating_view_task) - { - UI_Signal sig = hover_eval_floating_view_task->signal; - if(ui_pressed(sig)) - { - ws->hover_eval_focused = 1; - } - if(ui_mouse_over(sig) || ws->hover_eval_focused) - { - ws->hover_eval_lastt_us = rd_state->time_in_us; - } - else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) - { - rd_request_frame(); - } - if(ws->hover_eval_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_Press && - evt->key == OS_Key_LeftMouseButton && - !contains_2f32(hover_eval_floating_view_task->rect, evt->pos)) - { - ws->hover_eval_focused = 0; - MemoryZeroStruct(&ws->hover_eval_string); - arena_clear(ws->hover_eval_arena); - rd_request_frame(); - break; - } - } - } - } - - //- rjf: query interactions - if(query_floating_view_task) - { - String8 cmd_name = ws->query_regs->cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - - // rjf: close queries - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - - // rjf: any queries which take a file path mutate the debugger's "current path" - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) - { - RD_Cfg *view = query_floating_view_task->view; - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); - RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); - if(input != &rd_nil_cfg) - { - String8 path_chopped = str8_chop_last_slash(input->first->string); - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); - } - } - } - } - //////////////////////////// //- rjf: @window_ui_part bottom bar // diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3f556bd6..3f24e4cb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -45,6 +45,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1; CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers")); ////////////////////////////// //- rjf: unpack information about the viewed source file, if any @@ -138,7 +139,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 line_num_width_px = floor_f32(big_glyph_advance * (log10(visible_line_num_range.max) + 3)); + F32 line_num_width_px = 0; + if(do_line_numbers) + { + line_num_width_px = floor_f32(big_glyph_advance * (log10(visible_line_num_range.max) + 3)); + } F32 priority_margin_width_px = 0; F32 catchall_margin_width_px = 0; if(flags & RD_CodeViewBuildFlag_Margins) @@ -183,7 +188,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla RD_CodeSliceParams code_slice_params = {0}; { // rjf: fill basics - code_slice_params.flags = RD_CodeSliceFlag_LineNums|RD_CodeSliceFlag_Clickable; + code_slice_params.flags = RD_CodeSliceFlag_Clickable; + if(do_line_numbers) + { + code_slice_params.flags |= RD_CodeSliceFlag_LineNums; + } if(flags & RD_CodeViewBuildFlag_Margins) { code_slice_params.flags |= RD_CodeSliceFlag_PriorityMargin|RD_CodeSliceFlag_CatchallMargin; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 8f4b7570..9e1b131d 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -10,8 +10,8 @@ typedef U32 RD_CodeViewBuildFlags; enum { - RD_CodeViewBuildFlag_Margins = (1<<0), - RD_CodeViewBuildFlag_All = 0xffffffff, + RD_CodeViewBuildFlag_Margins = (1<<0), + RD_CodeViewBuildFlag_All = 0xffffffff, }; typedef struct RD_CodeViewState RD_CodeViewState; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 8c553b87..58ed324e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3294,12 +3294,12 @@ rd_line_edit(RD_LineEditParams *params, String8 string) F32 cursor_off = 0; UI_Parent(scrollable_box) { + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) == 0) + { + ui_spacer(ui_em(0.5f, 1.f)); + } if(!is_focus_active && !is_focus_active_disabled && params->fstrs.total_size != 0) { - if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) == 0) - { - ui_spacer(ui_em(0.5f, 1.f)); - } UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(label, ¶ms->fstrs); if(params->fuzzy_matches != 0) diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 7a5296be..09cf9a42 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -148,16 +148,16 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) Rng2F32 cursor_rect = { text_position.x + cursor_pixel_off - cursor_thickness*0.50f, - box->rect.y0+4.f, + box->rect.y0+ui_top_font_size()*0.5f, text_position.x + cursor_pixel_off + cursor_thickness*0.50f, - box->rect.y1-4.f, + box->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 mark_rect = { text_position.x + mark_pixel_off - cursor_thickness*0.50f, - box->rect.y0+2.f, + box->rect.y0+ui_top_font_size()*0.5f, text_position.x + mark_pixel_off + cursor_thickness*0.50f, - box->rect.y1-2.f, + box->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 select_rect = union_2f32(cursor_rect, mark_rect); dr_rect(select_rect, select_color, font_size/2.f, 0, 1.f); From 6f3c14c423e4b507dc4beda581c290954264a5f1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 20 Mar 2025 16:17:12 -0700 Subject: [PATCH 229/755] fix misusage of disabled schema --- src/raddbg/raddbg_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7629e110..fdfc95d5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -16136,7 +16136,8 @@ Z(getting_started) for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) { RD_Cfg *c = n->v; - rd_cfg_child_from_string_or_alloc(c, str8_lit("disabled")); + RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(c, str8_lit("disabled")); + rd_cfg_new_replace(disabled, str8_lit("1")); } if(!is_selected) { @@ -16414,7 +16415,8 @@ Z(getting_started) String8 file_path = rd_regs()->file_path; RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); - rd_cfg_new(target, str8_lit("disabled")); + RD_Cfg *disabled = rd_cfg_new(target, str8_lit("disabled")); + rd_cfg_new(disabled, str8_lit("1")); RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); rd_cfg_new(exe, file_path); String8 working_directory = str8_chop_last_slash(file_path); From cc4c889a9943032df23dbacb445e849006572326 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Mar 2025 11:39:53 -0700 Subject: [PATCH 230/755] bump format encoding version; add breakpad converter to ci; remove unused code --- .github/workflows/builds.yml | 22 ++++++++++++---------- src/lib_rdi_format/rdi_format.h | 2 +- src/os/core/os_core.h | 1 - src/rdi_format/rdi_format.mdesk | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 74246b0d..29973c03 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -20,13 +20,15 @@ jobs: shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 - call build raddbg msvc debug || exit /b 1 - call build rdi_from_pdb msvc debug || exit /b 1 - call build rdi_from_dwarf msvc debug || exit /b 1 - call build rdi_dump msvc debug || exit /b 1 - call build raddbg clang debug || exit /b 1 - call build rdi_from_pdb clang debug || exit /b 1 - call build rdi_from_dwarf clang debug || exit /b 1 - call build rdi_dump clang debug || exit /b 1 - call build radlink msvc debug || exit /b 1 - call build radlink clang debug || exit /b 1 \ No newline at end of file + call build raddbg msvc debug || exit /b 1 + call build raddbg clang debug || exit /b 1 + call build rdi_from_pdb msvc debug || exit /b 1 + call build rdi_from_pdb clang debug || exit /b 1 + call build rdi_from_dwarf msvc debug || exit /b 1 + call build rdi_from_dwarf clang debug || exit /b 1 + call build rdi_dump msvc debug || exit /b 1 + call build rdi_dump clang debug || exit /b 1 + call build radlink msvc debug || exit /b 1 + call build radlink clang debug || exit /b 1 + call build rdi_breakpad_from_pdb msvc debug || exit /b 1 + call build rdi_breakpad_from_pdb clang debug || exit /b 1 \ No newline at end of file diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index ec01827e..365d1f7d 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -52,7 +52,7 @@ typedef int64_t RDI_S64; // \"raddbg\0\0\" #define RDI_MAGIC_CONSTANT 0x0000676264646172 -#define RDI_ENCODING_VERSION 10 +#define RDI_ENCODING_VERSION 11 //////////////////////////////////////////////////////////////// //~ Format Types & Functions diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 2c07e759..96cf3b52 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -206,7 +206,6 @@ internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); -internal B32 os_rename_file(String8 orig_name, String8 new_name); internal B32 os_file_reserve_size(OS_Handle file, U64 size); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 1842cb38..06d13313 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -62,7 +62,7 @@ ""; "// \"raddbg\0\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; - "#define RDI_ENCODING_VERSION 10"; + "#define RDI_ENCODING_VERSION 11"; ""; "////////////////////////////////////////////////////////////////"; "//~ Format Types & Functions"; From 1cef39d0a300fd0776325e240ea9cd2467f2b9e5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Mar 2025 11:42:02 -0700 Subject: [PATCH 231/755] bump encoding version to match dev --- src/lib_rdi_format/rdi_format.h | 2 +- src/rdi_format/rdi_format.mdesk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index 65f75c1e..ca3f8a18 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -52,7 +52,7 @@ typedef int64_t RDI_S64; // "raddbg\0\0" #define RDI_MAGIC_CONSTANT 0x0000676264646172 -#define RDI_ENCODING_VERSION 10 +#define RDI_ENCODING_VERSION 11 //////////////////////////////////////////////////////////////// //~ Format Types & Functions diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index c0534cdf..c49a3d21 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -62,7 +62,7 @@ ""; "// \"raddbg\\0\\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; - "#define RDI_ENCODING_VERSION 10"; + "#define RDI_ENCODING_VERSION 11"; ""; "////////////////////////////////////////////////////////////////"; "//~ Format Types & Functions"; From c70132cd375d4645feb96eda9a25e38f0e4b8f8d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Mar 2025 11:51:52 -0700 Subject: [PATCH 232/755] never mind --- this conflicts badly with stable version! --- src/lib_rdi_format/rdi_format.h | 2 +- src/rdi_format/rdi_format.mdesk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index ca3f8a18..65f75c1e 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -52,7 +52,7 @@ typedef int64_t RDI_S64; // "raddbg\0\0" #define RDI_MAGIC_CONSTANT 0x0000676264646172 -#define RDI_ENCODING_VERSION 11 +#define RDI_ENCODING_VERSION 10 //////////////////////////////////////////////////////////////// //~ Format Types & Functions diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index c49a3d21..c0534cdf 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -62,7 +62,7 @@ ""; "// \"raddbg\\0\\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; - "#define RDI_ENCODING_VERSION 11"; + "#define RDI_ENCODING_VERSION 10"; ""; "////////////////////////////////////////////////////////////////"; "//~ Format Types & Functions"; From c2bebf2a5308e247d573b90853a13f17ca20cb95 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Mar 2025 14:30:29 -0700 Subject: [PATCH 233/755] snap to thread on stop on all windows, not just focused --- src/raddbg/raddbg_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fdfc95d5..2001fc54 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15397,6 +15397,7 @@ Z(getting_started) //- rjf: thread finding case RD_CmdKind_FindThread: for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + RD_RegsScope(.window = ws->cfg_id) { DI_Scope *scope = di_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -15469,6 +15470,7 @@ Z(getting_started) }break; case RD_CmdKind_FindSelectedThread: for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + RD_RegsScope(.window = ws->cfg_id) { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); rd_cmd(RD_CmdKind_FindThread, From 02322191fe764f99c67a80662433edaeb45da41f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 21 Mar 2025 17:18:16 -0700 Subject: [PATCH 234/755] fix drag/drop of immediate views, fix disallowance of [ or { in mdesk tags, other various convergences/fixes --- src/mdesk/mdesk.c | 5 ++++- src/raddbg/generated/raddbg.meta.c | 3 ++- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 28 +++++++++++++++++++++------- src/raddbg/raddbg_widgets.c | 5 +++-- 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/mdesk/mdesk.c b/src/mdesk/mdesk.c index bc314dd2..a1888673 100644 --- a/src/mdesk/mdesk.c +++ b/src/mdesk/mdesk.c @@ -968,7 +968,10 @@ if(work_top == 0) {work_top = &broken_work;}\ String8 tag_name = md_content_string_from_token_flags_str8(token[1].flags, tag_name_raw); MD_Node *node = md_push_node(arena, MD_NodeKind_Tag, md_node_flags_from_token_flags(token[1].flags), tag_name, tag_name_raw, token[0].range.min); DLLPushBack_NPZ(&md_nil_node, work_top->first_gathered_tag, work_top->last_gathered_tag, node, next, prev); - if(token+2 < tokens_opl && token[2].flags & MD_TokenFlag_Reserved && str8_match(str8_substr(text, token[2].range), str8_lit("("), 0)) + if(token+2 < tokens_opl && token[2].flags & MD_TokenFlag_Reserved && + (str8_match(str8_substr(text, token[2].range), str8_lit("("), 0) || + str8_match(str8_substr(text, token[2].range), str8_lit("["), 0) || + str8_match(str8_substr(text, token[2].range), str8_lit("{"), 0))) { token += 3; MD_ParseWorkPush(MD_ParseWorkKind_Main, node); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e91c85cd..b74a0ff0 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[304] = +RD_VocabInfo rd_vocab_info_table[305] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -95,6 +95,7 @@ RD_VocabInfo rd_vocab_info_table[304] = {str8_lit_comp("show_symbol_names"), str8_lit_comp(""), str8_lit_comp("Show Symbol Names"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("show_line_numbers"), str8_lit_comp(""), str8_lit_comp("Show Line Numbers"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, +{str8_lit_comp("num_columns"), str8_lit_comp(""), str8_lit_comp("Number of Columns"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 51b9bce9..58b08f7a 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -637,7 +637,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[304]; +extern RD_VocabInfo rd_vocab_info_table[305]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 3b8c593d..b6ae2570 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -108,6 +108,7 @@ RD_VocabTable: {show_symbol_names "" "Show Symbol Names" "" Null } {show_line_numbers "" "Show Line Numbers" "" Null } {syntax syntaxes "Syntax" "Syntaxes" Null } + {num_columns "" "Number of Columns" "" Null } } @struct RD_VocabInfo: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2001fc54..149033b0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2240,7 +2240,8 @@ rd_setting_from_name(String8 name) String8 result = {0}; { // rjf: find most-granular config scope to begin looking for the setting - RD_Cfg *start_cfg = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *start_cfg = view_cfg; for(RD_Cfg *p = start_cfg->parent; p != &rd_nil_cfg; p = p->parent) { if(str8_match(p->string, str8_lit("transient"), 0)) @@ -2253,7 +2254,7 @@ rd_setting_from_name(String8 name) if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } // rjf: scan upwards the config tree until we find the setting - RD_Cfg *setting = &rd_nil_cfg; + RD_Cfg *setting = rd_cfg_child_from_string(view_cfg, name); for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) { setting = rd_cfg_child_from_string(cfg, name); @@ -2268,7 +2269,7 @@ rd_setting_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 schema_names[] = { - start_cfg->string, + view_cfg->string, str8_lit("settings"), }; for EachElement(idx, schema_names) @@ -4053,7 +4054,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: use row to complete query - if(row != 0) + if(row->expr != &e_expr_nil) { taken = 1; E_Eval eval = e_eval_from_expr(scratch.arena, row->expr); @@ -4858,9 +4859,9 @@ rd_view_ui(Rng2F32 rect) F32 cell_width_px = cell->px + cell->pct * row_width_px; F32 next_cell_x_px = cell_x_px + cell_width_px; { - Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.2f, + Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.4f, boundary_start_idx*row_height_px, - next_cell_x_px + ui_top_font_size()*0.2f, + next_cell_x_px + ui_top_font_size()*0.4f, idx*row_height_px); UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) { @@ -6741,6 +6742,19 @@ rd_window_frame(void) //- rjf: tab dragging if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg) { + RD_Cfg *immediate_parent = &rd_nil_cfg; + for(RD_Cfg *p = view->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->parent->string, str8_lit("immediate"), 0)) + { + immediate_parent = p->parent; + break; + } + } + if(immediate_parent != &rd_nil_cfg) + { + rd_cfg_new(immediate_parent, str8_lit("hot")); + } UI_Size main_width = ui_top_pref_width(); UI_Size main_height = ui_top_pref_height(); UI_TextAlign main_text_align = ui_top_text_alignment(); @@ -7317,7 +7331,7 @@ rd_window_frame(void) { //- rjf: try to add hover eval first { - B32 build_hover_eval = (hover_eval_is_open && (!rd_drag_is_active() || rd_state->drag_drop_regs_slot == RD_RegSlot_View)); + B32 build_hover_eval = (hover_eval_is_open && !rd_drag_is_active()); // rjf: disable hover eval if hovered view is actively scrolling if(hover_eval_is_open) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 58ed324e..796b499c 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1424,7 +1424,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); - catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); + catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideRight|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; @@ -1436,6 +1436,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_CfgList line_bps = params->line_bps[line_idx]; RD_CfgList line_pins = params->line_pins[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_background_color(v4f32(0, 0, 0, 0)); UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) { @@ -1733,7 +1734,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_fixed_x(floor_f32(params->margin_float_off_px + params->priority_margin_width_px + params->catchall_margin_width_px)); ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); - ui_set_next_flags(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight); + ui_set_next_flags(UI_BoxFlag_DrawSideRight); UI_Column UI_PrefHeight(ui_px(params->line_height_px, 1.f)) RD_Font(RD_FontSlot_Code) From 93584ba2baaba7d97407c05ba232d989fa10e1c0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 24 Mar 2025 13:17:10 -0700 Subject: [PATCH 235/755] convergence, enum member name evaluation fixes, visual fixes/tweaks --- data/icons.ttf | Bin 25260 -> 24648 bytes .../eval_visualization_core.c | 19 +- src/raddbg/generated/raddbg.meta.c | 15 +- src/raddbg/generated/raddbg.meta.h | 774 +++++++++--------- src/raddbg/raddbg.mdesk | 11 +- src/raddbg/raddbg_core.c | 737 +++++++++-------- src/raddbg/raddbg_views.c | 4 + src/ui/ui_core.c | 26 +- 8 files changed, 824 insertions(+), 762 deletions(-) diff --git a/data/icons.ttf b/data/icons.ttf index 86db4361f481b6b04b9c1ebf961d43ab1961321a..c2be53be1e0f11f200cad43684b8ae97d5d19e6b 100644 GIT binary patch delta 5316 zcmZu#3vg7|c|QL+_qp0#X&>5My;fRDyAl$5uOvVqu7tpVq(u@GBMb;3gb+rc2=VX( zB*!Jwbf!FfnT*@o8OKiDx|KaPn|M;sbjEF+nZ$LP4s|mgx6@>tq{B2##^c70lNfEk zbNAxl)PisSz4xBy|NZCt|GO*SrtiE?*Ah!xj#M*7BaE@bQ*)E^&mI1H4X$5iObbq( zTdeX|YX8gF=m9)mcWi!U?nv8jAHnqv#{Axy$usk~Uxe#Du*S^EhmJj&%gi#SzrmRG zt>e>^M;pKTtBZ_ne-zKVj^l>@4@w=bzk%!8<8zA__Nj}xH*w<~OgeD#^wi|y&CB0n zY-c$de0^^6!aUtBEW!2bxUM=iIXC^ir^_pF{UgTs_vTNZS-kw)4cizS#)8Fj^9$4S zKimH1(~M0#bN%B7XoJ0ndO5pj-=LQ9enuFB(MBemZ);&a7^R;nge|ZbHX@k8YFHy{ zW^HUe+sGbZhu9hR2)mfep+$nFSQBey9eC2q4zfvhRz9)Ycr;4rUykSXtbujm-#lAj zUt!PMC-|TGhS)I6uw85fvupNsQFD;EU`$ap-7uM_fO&n)Usx0fhQf>$vq&^nQd(AC z5wEODRM*rdQ+4%g8XDI&HMg|3wRf;|CtTURZvBRyjhlKmTYddo2DWayZ#&zub8u)l zgIO@c1>52Ugb~Q3#9OIFJ-{xd^~^y9mOra}k1F?*gs@4S5v9_PU6` zZgvrcwOqtt``D8FUDlE%QiQN^ASoJkAt@SjAt~DJLQ=HH#ah@ua3Sg1 z3oOYG$=CfZT449Nklc;CklgKe(GL573(4a_7m~(9E+mbUE+madTu2(HT!6+Ub`%#9 zlE-Nm8(@#Q=z*PaA^AP-ViWAF3(55f7n17-U0ARuT}YbeTu7=B-a;QNU9%lA*p^?4)!o0xrUB9kX&DMA-U#^ z<$f(fqJR~$N|v;$Ay=IEltMVo6HJH@%h*5FFLmy*M%TBtqO>S8_IbDvY*It_0D6AMxD(oKjSQ~mhPEbA5-lcWv#c;QtO`zKPB7C9 zn3-(1htm>Ma=F|qN(&ZbI7@0_W7e*UFegz+jQl>Ysc=?a%oVN-Vf6~*%CeMLPHa{u zA+!mmX`x}JDCz`L)qt7_6g4-dYD%I-m4V7oC}`*u@2U%=Q_(E8Xl_|G?f@{61Mse zqym0P-kU^77I$0w{aSniV@lyp0O9DF{q1C0-p+qvBv}@>+4sS5$ST6F*aZB5{d9J4J=U1Sw2uGX8O3dQ z_|3eBG3B`j9S7nQvLJBKb0@^t5Hf=4h~i4CT-Ri5;fmltWJ1SpEK?SjgR9AaTGvEA zxj|jks_T-?)G3KhcC|-U1jR3DdiBq1=}W5*uRbF7hJ&l;3sZ%w=L6x=V*0W-=A$nc zm-hT4O?`3mpIo^@t9zEh)#eXO^9P=)Vp@sT8dp{IssY7CSRyb7_%c{+vzi_Mk1HBy zf`~IvqN;onobXX%fg-=Rz|=KFcZfo|9%-cZa3d9mt2a?ib-IT-)9n?+Q}Ot%qqpP- zUCUcs9JwX;n4gTUVb@hw1$Gao-VeiQ0uN~yF_kl&G?5=0tfo8Ucy~UI$1#}HNy^;; zEfesh*QEs~DSwjR@ip0sf5x}n+S)^kmL$aFkiFz@5+RRQJo3YhhP*%XeFP`Ox^dMf5Mcni_9fK!IiQH37H z8UsqEZ1CkETG!pvS{3Zl?=^3}x4n#;`p<8#EIZ@d@1{CzZ`~g*sZh3Gi*f!21USGF zsAK!s6{|1=ADQqLm66JXyWmzVALJ2R279W3>cC{WX6iH8vO<~yfiMhpA0{vkGeb2- z%B;4}bWxak>9c*7{(q-&%fD$ucTFgj4245M4^%!G)~Zvzkmu;9UpmvNI++BE!;vU* zASFaIK_N693Y1R(o$2mSFX3S%8jA3N(%Nz!tB+iFZJ$@WGmeaS*sJls)IE2`xV?}2 z_0>V$&-qu88^$5t<|#8Br*Bradrp~u6D)PQhFv?Cb@Hk6NkQ`I9*@5IXIYswvi@=! zt4L98eD$UB?A5vgYNBDQfXKs-ba7qdaHkgxbp?q8T~-1RSj5JHU*+86;o~-~3AGiH z$CEE;gp7a?+HcIaXA0s-VaowjCW6i1+pGQedPUG{)93Z#m+tMB{7g4%;PZRf@7Koz z(6R9%GEHN$fDF?Z9nT(E(@EKD4IU98pWLM8Ie?VtY_c5Fud`onDyj03<|Wb6ONb`;0>wMYS#%809Te-rB2Cx#Cm!Y z9K0pTHM50OElQ}nu?Q5srcNq1)fq*Sg8VRxg3g#^h5?7k+S}dvLf`kL;yNn2-%ZL; z?O2f^Rgs3IbcTj8tK+A~`VUvjbwhIVjZ3YlA@vGW$ae0au`L}Xlv_osaSYkYHdx(F zM5>9kBd^bGiORgr`KNpR+bvh^9RrUx_gTI5ajq(nV!uGT8+ztGJD~1{ugC5J+xqk3Ps5GL_4$wz5s<9lchM4{NC;86eW5 z;6W^_GERhY3C;BhlpW}(D6;(30*LwOjwg@{oUO}E$)J~vgG1;2=iW)||JgCwAl)SK zzBzbE5##t7sAy;%7th!`hmPPa6Mx&-kLZu_ zQna7nYZn5l2ri+H<3S zr-5(T+e5aBUk No&28tX!ooB{{#KOV{-ri delta 5973 zcma)AdvH|ebwA(t-RJIVAKKMQtln=S5Rwq${kVWJ2qE4m(%O%s5FW&3JH1x;D-*N$W|{3`yi+C|xV}zgzBl~n z>6+*vYl3Ls>sViTbaHfJsPli$Ko)Fkf5as6#@XY}~FqZ^()R!(HUK(zVN z*vR0Krau~Zim0~%>&wS*!#=0p#q~qDZWx<5efHq5f0Dn28#CCnYy%K0g3grmk!Y&oheB8@5}0H0c{Pzzb0y- z#gOfw{dAPZ=oz|7SN-ksi!j6TA5ry(gjCSVdz)n0TQWM>Q=6AJfDb7}o?0Ow%!3Ffj)H zK+|gQM}}Icx|d zG$b6doNQ58T85OUa5R38 zXx2;T-f^WEM#;QTf_dZ8k?xmp;C57mT2HA(h6l+Bm|F;K<@ z>}C&=ZO8k_Fsvc6tb~PQHvGPz4I^wZdY4$%3zwACH#F8aq#S#?YLVz()@0Y?qq)A$ zvPC->>1%FK6b@~__y|!>-E|Y4Ik=MsC8zd`dV#wc7sL-?#dA`vQB#%hB|#rG4|J7Hmx2WgNDe3r&Pt z3Z{jFNW;D$#(Xs!@$4)9KStYpGj=rf$6jcSFsw$vc@~)+{@GZY73Whd$Jgo%Kx+v( z$|q9&I4T{+7ut>R_}_^A$e)at?)f_}-oHg!j)pn%4v27ph<0+Lj^$3pilh?>L62jN zF^(D2wm=z+M&UWz4i8W`oCxnMFJwoD|D|~S#(P)1Hj28@i{v`)#s5>?yryi{%jA9> zUnt6vxA_;;HC02cw9IpBs?x;Tqo?#AYE)B?a_!ZNtpc>pG%MtH_8^* zRF_06TvKL%L@}JIiaF(GAzYMH(6b*x`&HK4>mMxp`G&2t2sTg~4LOEQ@PC-G%)*tZ zqUs`sn)yYpq%^=%yRxtO`xcyE!>;|U`U)ySiniUK>)+)!t<@lsrzHy+@T0MD!b zFBf>Vyl4Ic`H_5sEUNY@pub0PxuZ*XJ}Gwky_qI-4w?V2{Lj?8s+dZthBozHufUlT zT+=Tq)aU@%DXz_>v-e;-Q$h}{+RH&D|7Qd;c z#V%-V^>@}Z$KwvPcE*Go6^`jTqqtd$nNIX`@1g;8oIp(`ceZ9!>_ z*S>LRl3Wo352gZqS7JR44d@vLJP1QofOB5;D*b2cD^(WQ`eyyJ_s@5m2!=~-YdUE4 zpHOg9vrV6~CfF6x;@&mZaA<%>b9AmgnFq{L(AGdNd8OzOW@S2R!<_IxKunT=bYV7G zUU<@4C{iyBE06De;$VC0Fj+=3U7!S8BwrQG8yF#shf;b^!Iu6jUF?v+(r#NaV6+$xmWSjpRK`x;<8k4!T# zKnWP7lsQx7Ka*+=h@&w6oh zo&U@m2V@=#%3~OB zbR##=-3#GmgV7MBx`g(MCeJY%bx`!k9^mPgQ?Mae2kLQK*fh?PsO?$icmcsf!5c`l zZE>R=YEvnoX@?Z3O>>FG~<$<2+@a@&Pzl_IAcc!_HggLomiHjdz$ zaJl6SlHPk*9g}08xOC*;+&F>8xDLs_xvYJ zrkE-M@V?@wH+A7%L*##lr?W7jgT}p38*{WQr03-=YL_-1wXaTqM%C`+3U_FJQu@pb(?I~b8gJY32 zacndjse(}i6}>Qu)G+$+!p;8FLWl>?!o0Oq!8r2XvQJNQax<0x`nB9ZZ0&~>Q^5}i z|MHchUtxv7-_L)TKW4Nm{+WnTS@^>^umfu#ETBZ&g5z{h< ztYT}e^{{o>dfocSe$gT4ZFjkQ+P&(25Lz8Bj+90ItmvCjE4n!P*;sMxNbJAkb@4|N zk0-7s-YQ;Q{Q2VFB!8MZoBEHEmXi0expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) { - e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + B32 is_inherited = 0; + // TODO(rjf): table-drive this + if(str8_match(src_tag->string, str8_lit("hex"), 0) || + str8_match(src_tag->string, str8_lit("oct"), 0) || + str8_match(src_tag->string, str8_lit("bin"), 0) || + str8_match(src_tag->string, str8_lit("dec"), 0) || + str8_match(src_tag->string, str8_lit("no_addr"), 0) || + str8_match(src_tag->string, str8_lit("digits"), 0) || + str8_match(src_tag->string, str8_lit("no_string"), 0) || + str8_match(src_tag->string, str8_lit("only"), 0) || + str8_match(src_tag->string, str8_lit("omit"), 0)) + { + is_inherited = 1; + } + if(is_inherited) + { + e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); + } } } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b74a0ff0..b57c8947 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[305] = +RD_VocabInfo rd_vocab_info_table[307] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -96,6 +96,8 @@ RD_VocabInfo rd_vocab_info_table[305] = {str8_lit_comp("show_line_numbers"), str8_lit_comp(""), str8_lit_comp("Show Line Numbers"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, {str8_lit_comp("num_columns"), str8_lit_comp(""), str8_lit_comp("Number of Columns"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("bitmap"), str8_lit_comp("bitmaps"), str8_lit_comp("Bitmap"), str8_lit_comp("Bitmaps"), RD_IconKind_Bitmap}, +{str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -317,7 +319,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n 'syntax': dasm_syntax,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, @@ -735,7 +737,7 @@ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("toggle_breakpoint"), }; -String8 rd_icon_kind_text_table[69] = +String8 rd_icon_kind_text_table[74] = { str8_lit_comp(""), str8_lit_comp("b"), @@ -765,6 +767,7 @@ str8_lit_comp("O"), str8_lit_comp("o"), str8_lit_comp("!"), str8_lit_comp("1"), +str8_lit_comp("V"), str8_lit_comp("<"), str8_lit_comp(">"), str8_lit_comp("^"), @@ -805,7 +808,11 @@ str8_lit_comp("A"), str8_lit_comp("?"), str8_lit_comp("4"), str8_lit_comp("5"), -str8_lit_comp("c"), +str8_lit_comp("6"), +str8_lit_comp("&"), +str8_lit_comp("*"), +str8_lit_comp("("), +str8_lit_comp(")"), }; String8 rd_theme_preset_display_string_table[9] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 58b08f7a..384ccb7b 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -303,6 +303,7 @@ RD_IconKind_RadioHollow, RD_IconKind_RadioFilled, RD_IconKind_CheckHollow, RD_IconKind_CheckFilled, +RD_IconKind_Check, RD_IconKind_LeftCaret, RD_IconKind_RightCaret, RD_IconKind_UpCaret, @@ -344,6 +345,10 @@ RD_IconKind_QuestionMark, RD_IconKind_Person, RD_IconKind_Briefcase, RD_IconKind_Dot, +RD_IconKind_Bitmap, +RD_IconKind_Cube, +RD_IconKind_WindowRestore, +RD_IconKind_WindowMinimize, RD_IconKind_COUNT, } RD_IconKind; @@ -637,12 +642,12 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[305]; +extern RD_VocabInfo rd_vocab_info_table[307]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; -extern String8 rd_icon_kind_text_table[69]; +extern String8 rd_icon_kind_text_table[74]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_preset_cfg_string_table[9]; @@ -662,401 +667,392 @@ extern String8 rd_theme_color_display_string_table[145]; extern String8 rd_theme_color_cfg_string_table[145]; read_only global U8 rd_icon_font_bytes__data[] = { -0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, -0x0e,0x5d,0x06,0x6d,0x00,0x00,0x53,0xc0,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x53,0xf8,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x53,0xb8,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x3f,0x82,0x6a,0x1b,0x00,0x00,0x07,0x9c,0x00,0x00,0x43,0x86,0x68,0x65,0x61,0x64, -0x26,0x89,0x5f,0x83,0x00,0x00,0x4b,0x24,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0x79,0x03,0xdb,0x00,0x00,0x4b,0x5c,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0xf3,0xce,0xff,0xc8,0x00,0x00,0x4b,0x80,0x00,0x00,0x01,0x30,0x6c,0x6f,0x63,0x61,0x8c,0xcb,0x7c,0x1e,0x00,0x00,0x4c,0xb0,0x00,0x00,0x00,0x9a,0x6d,0x61,0x78,0x70, -0x01,0xe3,0x0f,0x19,0x00,0x00,0x4d,0x4c,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1a,0x1b,0x00,0x00,0x4d,0x6c,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x95,0xf6,0x72,0x8f,0x00,0x00,0x50,0x3c,0x00,0x00,0x03,0x79,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x62,0x04,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, +0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x22,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, +0x0e,0x1f,0x06,0xf3,0x00,0x00,0x51,0x5c,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x51,0x94,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x51,0x54,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x98,0xff,0x4e,0x69,0x00,0x00,0x07,0xc4,0x00,0x00,0x40,0xb8,0x68,0x65,0x61,0x64, +0x2b,0x9e,0xf7,0x7d,0x00,0x00,0x48,0x7c,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0xc2,0x04,0x27,0x00,0x00,0x48,0xb4,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x05,0x74,0xff,0xca,0x00,0x00,0x48,0xd8,0x00,0x00,0x01,0x44,0x6c,0x6f,0x63,0x61,0x74,0xb2,0x85,0xb8,0x00,0x00,0x4a,0x1c,0x00,0x00,0x00,0xa4,0x6d,0x61,0x78,0x70, +0x01,0xe8,0x0f,0x19,0x00,0x00,0x4a,0xc0,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1c,0x1d,0x00,0x00,0x4a,0xe0,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x85,0xfb,0x3a,0x46,0x00,0x00,0x4d,0xb0,0x00,0x00,0x03,0xa3,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x5f,0xa0,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, 0x00,0x0a,0x00,0x30,0x00,0x3e,0x00,0x02,0x44,0x46,0x4c,0x54,0x00,0x0e,0x6c,0x61,0x74,0x6e,0x00,0x1a,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x6c,0x69,0x67,0x61,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x04, -0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x35,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x66,0x45,0x64,0x00,0xc0,0x00,0x21,0xe8,0x00,0x03,0x52,0xff,0x6a,0x00,0x5a,0x03,0xac,0x00,0x96,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x04, -0x00,0x00,0x02,0x58,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x52,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x2c,0x00,0x03,0x00,0x0a,0x00,0x00,0x02,0x58,0x00,0x04,0x01,0x26,0x00,0x00,0x00,0x20,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2e,0x00,0x31,0x00,0x35,0x00,0x39,0x00,0x3c,0x00,0x50,0x00,0x5b,0x00,0x5e, -0x00,0x73,0x00,0x7b,0x00,0x7d,0xe8,0x00,0xff,0xff,0x00,0x00,0x00,0x21,0x00,0x27,0x00,0x2b,0x00,0x2d,0x00,0x30,0x00,0x33,0x00,0x37,0x00,0x3c,0x00,0x3e,0x00,0x52,0x00,0x5d,0x00,0x61,0x00,0x75,0x00,0x7d,0xe8,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x00,0x24,0x00,0x24,0x00,0x24,0x00,0x26,0x00,0x28,0x00,0x2c,0x00,0x30,0x00,0x30,0x00,0x54,0x00,0x66,0x00,0x68,0x00,0x8c,0x00,0x98,0x00,0x98,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a, -0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a,0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a, -0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a,0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a, -0x00,0x4b,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x06,0x07,0x00,0x08,0x09,0x00,0x0a,0x0b,0x0c,0x00,0x0d, -0x0e,0x0f,0x00,0x00,0x10,0x00,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x00,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x00,0x2e,0x2f,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x00,0x43,0x44,0x45, -0x46,0x47,0x48,0x49,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x3a,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x66,0x45,0x64,0x00,0xc0,0x00,0x21,0x00,0x7d,0x03,0x52,0xff,0x6a,0x00,0x5a,0x03,0xac,0x00,0x96,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x04, +0x00,0x00,0x02,0x42,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x3c,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x2c,0x00,0x03,0x00,0x0a,0x00,0x00,0x02,0x42,0x00,0x04,0x01,0x10,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x03,0x00,0x08,0x00,0x23,0x00,0x2b,0x00,0x2e,0x00,0x31,0x00,0x39,0x00,0x3c,0x00,0x5b,0x00,0x5e,0x00,0x73,0x00,0x7b,0x00,0x7d, +0xff,0xff,0x00,0x00,0x00,0x21,0x00,0x26,0x00,0x2d,0x00,0x30,0x00,0x33,0x00,0x3c,0x00,0x3e,0x00,0x5d,0x00,0x61,0x00,0x75,0x00,0x7d,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x1c,0x00,0x26,0x00,0x28,0x00,0x2a,0x00,0x36, +0x00,0x36,0x00,0x70,0x00,0x72,0x00,0x96,0x00,0xa2,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1a, +0x00,0x1b,0x00,0x1c,0x00,0x1d,0x00,0x1e,0x00,0x1f,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00,0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2a,0x00,0x2b,0x00,0x2c,0x00,0x2d,0x00,0x2e,0x00,0x2f,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3a, +0x00,0x3b,0x00,0x3c,0x00,0x3d,0x00,0x3e,0x00,0x3f,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00,0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x49,0x00,0x4a,0x00,0x4b,0x00,0x4c,0x00,0x4d,0x00,0x4e,0x00,0x4f,0x00,0x50,0x00,0x00,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x00,0x00,0x04,0x05,0x06,0x07,0x08,0x09,0x00,0x0a,0x0b,0x00,0x0c,0x0d,0x00,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x00,0x00,0x15,0x00,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25, +0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x00,0x34,0x35,0x00,0x00,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x00,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x03,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x27, -0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x31, -0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x0e, -0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x41, -0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x46, -0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x1e, -0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x52, -0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x57, -0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x2e, -0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x2f,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x65, -0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x6a, -0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x3a,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x3b,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x3d,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x3e, -0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x76, -0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x7b, -0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x4a,0x00,0x00,0xe8,0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x00,0x4b,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x49,0x4b,0xb0,0x24,0x50,0x58,0x40,0x13,0x00,0x01,0x00,0x02,0x01,0x02,0x63,0x04,0x01,0x00,0x00,0x03,0x5f, -0x00,0x03,0x03,0x10,0x00,0x4e,0x1b,0x40,0x19,0x00,0x03,0x04,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x01,0x02,0x4f,0x59,0x40,0x0f,0x02,0x00,0x1e,0x1b,0x16,0x13,0x0a,0x07,0x00,0x0f,0x02,0x0f,0x05,0x07,0x16,0x2b,0x01,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32, -0x36,0x35,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x71,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x34,0x7c,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x02,0xc3,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x59, -0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x06,0x00,0x00,0xff,0xba,0x02,0x80,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x00,0x42,0x00,0x4b,0x00,0x84,0x40,0x0d,0x39,0x30,0x2f,0x26,0x0d,0x0c,0x03,0x02,0x08,0x02,0x04,0x01,0x4c,0x4b,0xb0,0x16,0x50,0x58,0x40,0x25,0x08,0x0c,0x02,0x04,0x0b,0x01, -0x02,0x03,0x04,0x02,0x69,0x09,0x01,0x05,0x05,0x01,0x61,0x07,0x01,0x01,0x01,0x10,0x4d,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x23,0x07,0x01,0x01,0x09,0x01,0x05,0x04,0x01,0x05,0x69,0x08,0x0c,0x02,0x04,0x0b,0x01,0x02,0x03,0x04,0x02,0x69,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01, -0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x1f,0x44,0x43,0x1e,0x1d,0x48,0x47,0x43,0x4b,0x44,0x4b,0x41,0x40,0x3d,0x3c,0x35,0x34,0x2b,0x2a,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x14,0x19,0x17,0x0e,0x07,0x1a,0x2b,0x13,0x14,0x07,0x11,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x03,0x34,0x26,0x22, -0x06,0x14,0x16,0x32,0x36,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xf0,0x48,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x32, -0x2a,0x38,0x28,0x28,0x38,0x2a,0x46,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x01,0xdc,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x02,0x8a,0x4c,0x22,0xfe,0x86,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0xfd,0x76,0x1e,0x28, -0x28,0x3a,0x28,0x28,0x02,0x30,0x28,0x3a,0x28,0x28,0x3a,0x28,0xfe,0x5c,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f, -0x00,0x37,0x00,0x5b,0x00,0x88,0x40,0x10,0x4b,0x39,0x02,0x08,0x06,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x01,0x00,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x2a,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x00,0x07,0x07,0x0c,0x5f,0x00,0x0c,0x0c,0x10,0x4d,0x05,0x03,0x02,0x01, -0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x28,0x00,0x0c,0x00,0x07,0x06,0x0c,0x07,0x67,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x05,0x03,0x02,0x01,0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x16,0x59,0x58,0x55,0x52,0x4f,0x4d,0x47,0x46,0x43, -0x40,0x26,0x22,0x13,0x26,0x26,0x26,0x26,0x26,0x23,0x0e,0x07,0x1f,0x2b,0x25,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0x33, -0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08, -0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0xfe,0xd1,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x52,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08, -0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x02,0x32,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0, -0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x62,0x40,0x09,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01,0x4c,0x4b,0xb0,0x16,0x50,0x58,0x40,0x1e,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x10,0x4d,0x06,0x01,0x04,0x04,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x1c,0x00,0x01,0x00, -0x03,0x02,0x01,0x03,0x69,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x06,0x01,0x04,0x04,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x0f,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07, -0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c, -0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x00,0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x23,0x00,0x30,0x00,0x6f,0x40,0x0a,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x26,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04, -0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x61,0x00,0x07,0x07,0x10,0x4d,0x00,0x04,0x04,0x06,0x62,0x00,0x06,0x06,0x11,0x06,0x4e,0x1b,0x40,0x24,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x07,0x00,0x01,0x00,0x07,0x01,0x67,0x00,0x04,0x04,0x06,0x62,0x00,0x06,0x06,0x11,0x06,0x4e, -0x59,0x40,0x0b,0x15,0x15,0x23,0x24,0x25,0x23,0x24,0x14,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x37,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02, -0xa7,0x16,0x0e,0x8f,0x16,0x0e,0x47,0x0f,0x14,0x01,0x8f,0x0e,0x16,0x01,0x14,0x0f,0x8f,0x16,0x0e,0x47,0x0f,0x14,0x01,0x8f,0x0e,0x16,0xb2,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x8f,0x0f,0x14,0x01,0x16,0x0e,0x8f,0x14,0x0f,0x48,0x0e,0x16,0x01,0x8f,0x0f,0x14,0x01,0x16,0x0e,0x8f, -0x14,0x33,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0f,0x00,0x1c,0x00,0x3c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x15,0x00,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x00,0x01, -0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x15,0x15,0x35,0x24,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x37,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0xa7,0x16,0x0e,0xfe,0x53,0x0e,0x16,0x01,0x14,0x0f,0x01, -0xad,0x0e,0x16,0xb2,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x33,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x01,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x28,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x01,0x01, -0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0xb4,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4, -0x74,0x74,0xc4,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02, -0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d,0x00,0x42,0x00,0x8b,0x40,0x0a,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x30,0x00, -0x07,0x01,0x02,0x01,0x07,0x02,0x80,0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x10,0x02,0x4e,0x1b,0x40,0x36,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80,0x00,0x06,0x02,0x04,0x02,0x06, -0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x01,0x00,0x02,0x06,0x01,0x02,0x67,0x00,0x03,0x00,0x00,0x03,0x57,0x00,0x03,0x03,0x00,0x60,0x00,0x00,0x03,0x00,0x50,0x59,0x40,0x0b,0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35, -0x11,0x34,0x36,0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30, -0x43,0x5e,0x5e,0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e,0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01, -0xd0,0x42,0x5e,0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01,0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f, -0x00,0x1f,0x00,0x2f,0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0xcf,0x40,0x10,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x4b,0xb0,0x09,0x50,0x58,0x40,0x2f,0x00,0x09,0x0e,0x08,0x06,0x09,0x72,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00, -0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x10,0x4d,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x1b,0x4b,0xb0,0x24,0x50,0x58,0x40,0x30,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x10, -0x4d,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x1b,0x40,0x2d,0x00,0x0e,0x09,0x0e,0x85,0x00,0x09,0x08,0x09,0x85,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x59,0x59,0x40,0x1a, -0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b, -0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01, -0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25, -0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11, -0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a,0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01, -0x4c,0x4b,0xb0,0x17,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01,0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26, -0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02,0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46,0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36, -0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c,0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0xcc,0xb5,0x25,0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30, -0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x10,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x4b,0xb0,0x1f,0x50,0x58,0x40,0x31,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x09, -0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x10,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x2f,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x00,0x02,0x00,0x07,0x01,0x02,0x07,0x67,0x0c,0x01,0x05, -0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23,0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15, -0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17,0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15,0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a, -0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04,0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c,0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00, -0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa, -0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16,0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00,0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b, -0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e,0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14, -0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01,0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b,0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01, -0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05, -0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e,0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, -0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06, -0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03,0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06, -0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04,0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00,0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00, -0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27,0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07, -0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15,0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52, -0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08,0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04, -0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f,0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d,0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x56,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00, -0x02,0x02,0x10,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x4b,0xb0,0x2a,0x50,0x58,0x40,0x0e,0x00,0x02,0x00,0x00,0x01,0x02,0x00,0x69,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x15,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x00,0x02,0x57,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x02,0x00,0x51,0x59,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x03,0xd0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x50,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x05,0x00,0x00, +0x00,0x28,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x2e,0x00,0x00, +0x00,0x2e,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x35,0x00,0x00, +0x00,0x10,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x15,0x00,0x00, +0x00,0x3e,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x16,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x43,0x00,0x00, +0x00,0x43,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x1d,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x48,0x00,0x00, +0x00,0x20,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x25,0x00,0x00, +0x00,0x4e,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x51,0x00,0x00,0x00,0x51,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x52,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x53,0x00,0x00, +0x00,0x53,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x54,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x56,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x2f,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x58,0x00,0x00, +0x00,0x30,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x5b,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x5d,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x5e,0x00,0x00,0x00,0x35,0x00,0x00, +0x00,0x61,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x39,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x65,0x00,0x00,0x00,0x3a,0x00,0x00,0x00,0x66,0x00,0x00, +0x00,0x66,0x00,0x00,0x00,0x3b,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x3d,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x6a,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x6b,0x00,0x00,0x00,0x6b,0x00,0x00, +0x00,0x40,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x45,0x00,0x00, +0x00,0x71,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x77,0x00,0x00, +0x00,0x77,0x00,0x00,0x00,0x4b,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x4d,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x7b,0x00,0x00,0x00,0x4f,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x7d,0x00,0x00, +0x00,0x50,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x25,0x40,0x22,0x00,0x01,0x00,0x02,0x01,0x02,0x63,0x04,0x01,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x00,0x4e,0x02,0x00,0x1e,0x1b,0x16,0x13,0x0a,0x07,0x00,0x0f,0x02,0x0f,0x05,0x07,0x16,0x2b,0x01,0x21,0x22,0x06,0x07,0x11,0x14, +0x16,0x17,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x71,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x34,0x7c,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x02,0xc3,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01, +0xd0,0x25,0x34,0x59,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x06,0x00,0x00,0xff,0xba,0x02,0x80,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x00,0x42,0x00,0x4b,0x00,0x54,0x40,0x51,0x39,0x30,0x2f,0x26,0x0d,0x0c,0x03,0x02,0x08,0x02,0x04,0x01,0x4c,0x08,0x0c,0x02,0x04,0x0b,0x01,0x02,0x03,0x04, +0x02,0x69,0x09,0x01,0x05,0x05,0x01,0x61,0x07,0x01,0x01,0x01,0x13,0x4d,0x0d,0x0a,0x02,0x03,0x03,0x00,0x61,0x06,0x01,0x00,0x00,0x11,0x00,0x4e,0x44,0x43,0x1e,0x1d,0x48,0x47,0x43,0x4b,0x44,0x4b,0x41,0x40,0x3d,0x3c,0x35,0x34,0x2b,0x2a,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x14,0x19,0x17,0x0e,0x07,0x1a,0x2b,0x13,0x14,0x07,0x11, +0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x03,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13, +0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xf0,0x48,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x32,0x2a,0x38,0x28,0x28,0x38,0x2a,0x46,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x01,0xdc,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x02,0x8a,0x4c,0x22,0xfe, +0x86,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0xfd,0x76,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0x30,0x28,0x3a,0x28,0x28,0x3a,0x28,0xfe,0x5c,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28, +0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x37,0x00,0x5b,0x00,0x53,0x40,0x50,0x4b,0x39,0x02,0x08,0x06,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x01,0x00,0x02,0x4c,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x00, +0x07,0x07,0x0c,0x5f,0x00,0x0c,0x0c,0x13,0x4d,0x05,0x03,0x02,0x01,0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x58,0x55,0x52,0x4f,0x4d,0x47,0x46,0x43,0x40,0x26,0x22,0x13,0x26,0x26,0x26,0x26,0x26,0x23,0x0e,0x07,0x1f,0x2b,0x25,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34, +0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01, +0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0xfe,0xd1,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01, +0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x52,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x02,0x32,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08, +0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x04,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x0b,0x00,0x08,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x52,0x40,0x4f,0x1d,0x14,0x02,0x01,0x03,0x0f,0x01,0x00,0x01,0x0e,0x0d,0x0c,0x09,0x04,0x02,0x00,0x1c,0x15, +0x02,0x04,0x02,0x04,0x4c,0x00,0x02,0x00,0x04,0x00,0x02,0x04,0x80,0x00,0x01,0x00,0x00,0x02,0x01,0x00,0x69,0x07,0x01,0x03,0x03,0x06,0x5f,0x00,0x06,0x06,0x13,0x4d,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x11,0x05,0x4e,0x11,0x10,0x2e,0x2b,0x26,0x23,0x19,0x17,0x10,0x1f,0x11,0x1f,0x13,0x13,0x12,0x08,0x07,0x19,0x2b,0x01,0x14, +0x0e,0x01,0x26,0x34,0x36,0x1e,0x01,0x01,0x15,0x21,0x35,0x37,0x17,0x01,0x25,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x37,0x21,0x32,0x36,0x27,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x65,0x3e,0x5a,0x3e,0x3e,0x5a,0x3e,0x02,0x3c,0xfc,0xee,0xb2,0x5a,0x01,0x1d,0x01,0x1e, +0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x01,0x0a,0x51,0x34,0x25,0xfc,0x83,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x02,0x11,0x2d,0x3e,0x02,0x42,0x56,0x42,0x04,0x3a,0xfe,0xfa,0xfa,0x6b,0xb3,0x59,0x01,0x1d,0xa1,0x0a,0x08,0xfd,0x5a,0x07,0x0c,0x01,0x0a,0x08,0x02,0xa6,0x08,0x0a,0x12,0xfd,0x5a,0x25,0x34, +0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x40,0x36,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01,0x4c,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x13,0x4d,0x06,0x01,0x04,0x04,0x00, +0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46, +0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x03,0xff,0xff,0xff,0x6a,0x04,0x78, +0x03,0x52,0x00,0x03,0x00,0x0c,0x00,0x26,0x00,0x38,0x40,0x35,0x00,0x08,0x00,0x03,0x04,0x08,0x03,0x67,0x07,0x01,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x00,0x05,0x00,0x02,0x05,0x67,0x00,0x00,0x06,0x06,0x00,0x57,0x00,0x00,0x00,0x06,0x60,0x00,0x06,0x00,0x06,0x50,0x33,0x25,0x33,0x26,0x21,0x11,0x11,0x11,0x10,0x09,0x07, +0x1f,0x2b,0x17,0x21,0x11,0x29,0x02,0x11,0x21,0x15,0x33,0x32,0x16,0x15,0x01,0x11,0x14,0x06,0x23,0x21,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x8f,0x01,0xac,0xfe,0x54,0x02,0x3b,0x01,0x1e,0xfe,0x53,0x36,0x25,0x34,0x01,0xad,0x34,0x25,0xfe,0xac,0x34,0x25,0xfd,0xe8, +0x24,0x36,0x01,0x34,0x25,0x01,0x54,0x34,0x25,0x02,0x18,0x24,0x36,0x07,0x01,0x1e,0x01,0xac,0x8f,0x34,0x25,0x01,0x1e,0xfd,0xe8,0x25,0x34,0xc5,0x25,0x34,0x34,0x25,0x02,0x18,0x25,0x34,0xc5,0x25,0x34,0x34,0x00,0x01,0xff,0xff,0xff,0xb1,0x03,0xe8,0x00,0xcf,0x00,0x0f,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00, +0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x25,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x76,0x6b,0x25,0x34,0x01,0x36,0x24,0x6b,0x25,0x34,0x34,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0xa1,0x03,0x0b,0x00,0x03, +0x00,0x07,0x00,0x1f,0x00,0x1f,0x40,0x1c,0x07,0x06,0x05,0x03,0x02,0x01,0x00,0x07,0x00,0x01,0x01,0x4c,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x13,0x00,0x4e,0x1b,0x1e,0x02,0x07,0x18,0x2b,0x05,0x25,0x11,0x05,0x27,0x2d,0x01,0x0d,0x01,0x11,0x14,0x06,0x07,0x05,0x06,0x22,0x27,0x25,0x2e,0x01,0x35,0x11,0x34,0x36,0x37,0x25,0x36, +0x32,0x17,0x05,0x1e,0x01,0x01,0xf4,0x01,0x65,0xfe,0x9b,0x24,0x01,0x86,0xfe,0x7a,0xfe,0x7b,0x03,0x56,0x14,0x12,0xfe,0x77,0x0f,0x26,0x0f,0xfe,0x77,0x11,0x14,0x1a,0x15,0x01,0x89,0x0c,0x18,0x0d,0x01,0x89,0x15,0x1a,0x3b,0xc3,0x01,0x63,0x82,0x3f,0x8d,0x8e,0x8e,0x01,0xfe,0x54,0x14,0x22,0x09,0xd6,0x09,0x09,0xd6,0x0a,0x20,0x15, +0x01,0xac,0x17,0x24,0x08,0x8f,0x05,0x05,0x8f,0x08,0x24,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44,0x02,0x80,0x00,0x13,0x00,0x31,0x40,0x2e,0x00,0x05,0x00,0x02,0x05,0x59,0x04,0x06,0x02,0x00,0x03,0x01,0x01,0x02,0x00,0x01,0x67,0x00,0x05,0x05,0x02,0x61,0x00,0x02,0x05,0x02,0x51,0x01,0x00,0x11,0x10,0x0e,0x0c,0x0b,0x09,0x07, +0x06,0x04,0x02,0x00,0x13,0x01,0x13,0x07,0x07,0x16,0x2b,0x01,0x32,0x14,0x2b,0x01,0x15,0x14,0x22,0x3d,0x01,0x23,0x22,0x34,0x3b,0x01,0x35,0x34,0x32,0x1d,0x01,0x02,0x26,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0x01,0x90,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44, +0x01,0x90,0x00,0x07,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x57,0x02,0x01,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x05,0x02,0x00,0x07,0x01,0x06,0x03,0x07,0x16,0x2b,0x01,0x32,0x14,0x23,0x21,0x22,0x34,0x33,0x02,0x26,0x1e,0x1e,0xfd,0xf8,0x1e,0x1e,0x01,0x90,0x64,0x64,0x00,0x00,0x00,0x01,0xff,0xfd, +0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, +0x74,0xc4,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02, +0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d,0x00,0x42,0x00,0x48,0x40,0x45,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80, +0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x13,0x02,0x4e,0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, +0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e, +0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e,0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e, +0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01,0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f, +0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0x5d,0x40,0x5a,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x13,0x4d,0x00, +0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34, +0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b, +0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05, +0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a, +0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11,0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a, +0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x18,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01, +0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26,0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02,0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46, +0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36,0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c,0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0x94,0xb5,0x25, +0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x31,0x0d, +0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23, +0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15,0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17,0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15, +0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a,0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04,0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c, +0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07, +0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e,0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, +0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa,0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16,0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00, +0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b,0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e, +0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14,0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01,0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b, +0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27, +0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05,0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e,0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c, +0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05, +0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06,0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03, +0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04,0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00, +0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00,0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27,0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00, +0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15,0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe, +0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52,0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08,0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee, +0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04,0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f,0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d, +0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x3a,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x29,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x10,0x00,0x01,0x00,0x01,0x86,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x00,0x4e,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07, 0x19,0x2b,0x13,0x34,0x26,0x0e,0x01,0x1e,0x02,0x36,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x2e,0x01,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x17,0x01,0x16,0xfa,0x2a,0x3a,0x2c,0x02,0x28,0x3e,0x26,0x02,0x55,0x14,0xfe,0xee,0x16,0x3b,0x14,0xfe,0x71,0x15,0x1e,0x2a,0x1d,0xe9,0x1d,0x48,0x15,0x01,0x8f,0x14,0x02,0x58,0x1e,0x2a, 0x02,0x26,0x40,0x24,0x06,0x30,0xfe,0xd9,0x1e,0x15,0xfe,0xee,0x15,0x15,0x01,0x8f,0x15,0x48,0x1d,0xe8,0x1d,0x2a,0x01,0x1e,0x15,0xfe,0x71,0x15,0x00,0x0d,0x00,0x00,0xff,0xea,0x03,0xca,0x02,0xd2,0x00,0x03,0x00,0x07,0x00,0x0b,0x00,0x0f,0x00,0x13,0x00,0x17,0x00,0x1b,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2f,0x00,0x33, -0x00,0xfd,0x4b,0xb0,0x32,0x50,0x58,0x40,0x49,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x1a,0x01,0x01,0x02, -0x01,0x63,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x03,0x00,0x60,0x00,0x00,0x00,0x13,0x03,0x4e,0x1b,0x40,0x54,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01, -0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x59,0x40,0x52,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33,0x30,0x33,0x32,0x31, -0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f,0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21,0x07,0x17,0x2b,0x15, -0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0xe1,0x9e, -0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16,0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x00,0x00,0x00, -0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x15,0x00,0x04,0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x10,0x03,0x4e,0x1b,0x40,0x1d,0x00,0x03,0x04,0x03,0x85,0x00,0x04,0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00, -0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x59,0xb7,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f,0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16, -0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29,0xdd,0x03,0x07,0x05,0x02, -0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x35,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0d,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00,0x01,0x01,0x10,0x01,0x4e,0x1b,0x40,0x15,0x00,0x01,0x02,0x01,0x85,0x00,0x02,0x00,0x00,0x02,0x57,0x00,0x02,0x02,0x00,0x60,0x00,0x00,0x02, -0x00,0x50,0x59,0xb5,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12, -0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1f,0x40,0x1c,0x01,0x01,0x00,0x49,0x03,0x02,0x02,0x00,0x01,0x00,0x86,0x00,0x01,0x01,0x13,0x01,0x4e,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78, -0x01,0x6e,0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x00,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x42,0x4b,0xb0,0x1c,0x50,0x58,0x40,0x11,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x00,0x14,0x00,0x4e,0x1b,0x40,0x17,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00, -0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x59,0x40,0x0c,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e,0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59, -0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02,0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a,0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00, -0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11,0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05, -0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08,0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08,0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e, -0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x72,0x40,0x15,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x20,0x00,0x00, -0x00,0x05,0x5f,0x00,0x05,0x05,0x10,0x4d,0x00,0x03,0x03,0x04,0x61,0x06,0x01,0x04,0x04,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x1e,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x69,0x00,0x03,0x03,0x04,0x61,0x06,0x01,0x04,0x04,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59, -0x40,0x0f,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26, -0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27,0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52, -0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b,0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06,0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d, -0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01,0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a, -0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00, -0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x80,0x4b,0xb0,0x26,0x50,0x58,0x40,0x26,0x0f,0x09,0x02,0x03,0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06, -0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x10,0x06,0x4e,0x1b,0x40,0x2e,0x11,0x0d,0x02,0x07,0x10,0x0c,0x02,0x06,0x03,0x07,0x06,0x67,0x0f,0x09,0x02,0x03,0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x00,0x00,0x01,0x57,0x0b,0x05,0x02,0x01,0x01,0x00,0x5f,0x0a,0x04,0x02,0x00,0x01,0x00,0x4f,0x59,0x40,0x1e,0x8e, -0x8b,0x86,0x83,0x7e,0x7b,0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f,0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15, -0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15, -0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17, -0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17, -0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c, -0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01, -0x20,0x01,0x08,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25,0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01, -0x07,0x01,0x08,0x07,0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04,0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10, -0x00,0x0f,0x37,0x0d,0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11,0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32, -0x16,0x01,0x89,0x16,0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f,0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01, -0x1d,0x01,0xe8,0x0c,0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08,0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0xad, -0x40,0x28,0x79,0x78,0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10,0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2a,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01, -0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00,0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x10,0x08,0x4e,0x1b,0x40,0x31,0x0f,0x01,0x09,0x0e,0x01,0x08,0x05,0x09,0x08,0x67,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x00, -0x00,0x01,0x57,0x07,0x01,0x01,0x01,0x00,0x5f,0x06,0x01,0x00,0x01,0x00,0x4f,0x59,0x40,0x1a,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64,0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14, -0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14, -0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01, -0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd, -0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c, -0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83, -0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x14,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61,0x00,0x04,0x04,0x10,0x01,0x4e,0x1b,0x40,0x1c,0x00,0x04,0x00,0x01,0x00,0x04,0x01,0x69,0x05,0x03,0x02,0x00,0x02,0x02,0x00,0x59,0x05,0x03,0x02,0x00,0x00,0x02,0x5f,0x00,0x02,0x00, -0x02,0x4f,0x59,0x40,0x09,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20, -0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01, +0x00,0xa9,0x40,0xa6,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e, +0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33,0x30,0x33,0x32,0x31,0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f, +0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21,0x07,0x17,0x2b,0x15,0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01, +0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0xe1,0x9e,0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16, +0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x20,0x40,0x1d,0x00,0x04, +0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x13,0x03,0x4e,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f,0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16, +0x1d,0x01,0x21,0x32,0x16,0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29, +0xdd,0x03,0x07,0x05,0x02,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x16,0x40,0x13,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00,0x01,0x01,0x13,0x01,0x4e,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, +0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1d,0x40,0x1a,0x01,0x01,0x00,0x49, +0x00,0x01,0x00,0x01,0x85,0x03,0x02,0x02,0x00,0x00,0x76,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78,0x01,0x6e,0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x26, +0x40,0x23,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00,0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e,0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36, +0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59,0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02,0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a, +0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11, +0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05,0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08,0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08, +0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e,0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x45,0x40,0x42,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x06, +0x01,0x04,0x00,0x03,0x02,0x04,0x03,0x69,0x00,0x00,0x00,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17, +0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27,0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b, +0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b,0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06, +0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d,0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01,0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54, +0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c, +0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00,0x00,0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x47,0x40,0x44,0x0f,0x09,0x02,0x03, +0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06,0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x13,0x06,0x4e,0x8e,0x8b,0x86,0x83,0x7e,0x7b,0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f, +0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32, +0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32, +0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20, +0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17, +0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe, +0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0x01,0x08,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25, +0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01,0x07,0x01,0x08,0x07,0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04, +0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10,0x00,0x0f,0x37,0x0d,0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11, +0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x89,0x16,0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f, +0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x01,0xe8,0x0c,0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08, +0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x6f,0x40,0x6c,0x79,0x78,0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10, +0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00,0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x13,0x08,0x4e,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64, +0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b, +0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33, +0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01, +0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b, +0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01, +0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x20,0x40,0x1d,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61, +0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01, +0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01, 0x00,0x4a,0x05,0x01,0x01,0x49,0x00,0x00,0x01,0x01,0x00,0x57,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x11,0x11,0x02,0x07,0x18,0x2b,0x01,0x15,0x21,0x11,0x21,0x15,0x01,0x01,0x7a,0x01,0x60,0xfe,0xa0,0xfe,0x86,0x02,0xda,0xbe,0xfe,0x86,0xc0,0x01,0x7c,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x52,0x00,0x0f, 0x00,0x2f,0x00,0x2e,0x40,0x2b,0x09,0x01,0x02,0x01,0x00,0x20,0x01,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x67,0x00,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x00,0x03,0x03,0x11,0x03,0x4e,0x35,0x26,0x36,0x26,0x26,0x14,0x06,0x07,0x1c,0x2b,0x01,0x11,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x33,0x21, 0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x14,0x1e,0x01,0x17,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x34,0x3e,0x01,0x35,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x0a,0x08,0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x46,0x34,0x25,0xfe,0xd1,0x12,0x10,0x01,0x14,0x0f,0xfe,0xe2,0x0f,0x14,0x01, 0x12,0x12,0xfe,0xd0,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x01,0x28,0x01,0xd1,0x07,0x0a,0x01,0x0c,0x06,0xfe,0x2f,0x07,0x0a,0x0a,0x01,0xd8,0xfd,0xa1,0x25,0x34,0x01,0x14,0x2e,0x22,0x07,0x0e,0x16,0x16,0x0e,0x08,0x22,0x2c,0x15,0x36,0x24,0x02,0x5f,0x25,0x34,0x34,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xe1,0x02,0xf8, -0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x71,0xb6,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x4b,0xb0,0x1a,0x50,0x58,0x40,0x18,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x69,0x00,0x04,0x04,0x02,0x61,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x14,0x01,0x4e,0x1b,0x4b,0xb0,0x1d,0x50,0x58,0x40,0x16,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00, -0x03,0x00,0x00,0x01,0x03,0x00,0x69,0x00,0x01,0x01,0x14,0x01,0x4e,0x1b,0x40,0x1d,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x03,0x00,0x51,0x59,0x59,0xb7,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27, -0x0f,0x01,0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16,0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80, -0x95,0x40,0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f,0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40, -0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x47,0x4b,0xb0,0x26,0x50,0x58,0x40,0x16,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x14,0x00,0x03,0x04,0x01,0x00,0x01,0x03,0x00,0x69,0x00,0x01,0x01,0x02,0x61,0x00,0x02, -0x02,0x11,0x02,0x4e,0x59,0x40,0x0f,0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6, -0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xaa,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16, -0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02,0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x09,0x50,0x58,0x40,0x23,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50, -0x58,0x40,0x22,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80, -0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x40,0x12,0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15,0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01, -0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c,0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b,0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe, -0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13, -0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21,0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f,0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b, -0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00,0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07, -0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37,0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11,0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52, -0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x00,0xf2,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x32,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x03,0x00,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02, -0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x04,0x11,0x02,0x00,0x00,0x13,0x00,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58,0x40,0x36,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a, -0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x00,0x04,0x04,0x13,0x4d,0x11,0x01,0x00,0x00,0x13,0x00,0x4e,0x1b,0x40,0x39,0x12,0x01,0x01,0x03,0x01,0x85,0x11,0x01,0x00,0x04,0x02,0x04,0x00,0x02,0x80,0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06, -0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x00,0x04,0x04,0x13,0x04,0x4e,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a,0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09, -0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01,0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32, -0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58, -0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05,0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02, -0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a,0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57, -0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe, -0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5,0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26, -0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c,0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f,0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5, -0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03,0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c, -0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22,0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07, -0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14,0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10, -0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00,0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01,0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10, -0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f,0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21, -0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d,0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc, -0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06,0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12, -0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35,0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21, -0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe, -0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x62,0x00,0xcc,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x21,0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80, -0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80, -0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60, -0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c,0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14, -0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07, -0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12,0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07, -0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7,0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09, -0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x7b,0x40,0x0f,0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x05,0x01, -0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63,0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x10,0x06,0x4e,0x1b,0x40,0x2a,0x00,0x09,0x00,0x06,0x04,0x09,0x06,0x67,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00, -0x07,0x08,0x08,0x07,0x57,0x00,0x07,0x07,0x08,0x5f,0x00,0x08,0x07,0x08,0x4f,0x59,0x40,0x0e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07,0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16, -0x1d,0x01,0x33,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25, -0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe, -0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x59,0xb6,0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x1a,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05, -0x5f,0x00,0x05,0x05,0x10,0x02,0x4e,0x1b,0x40,0x20,0x00,0x05,0x00,0x02,0x01,0x05,0x02,0x67,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x04,0x04,0x03,0x57,0x00,0x03,0x03,0x04,0x5f,0x00,0x04,0x03,0x04,0x4f,0x59,0x40,0x09,0x35,0x35,0x35,0x36,0x26,0x23,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d, -0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01, -0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58, -0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16,0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06, -0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06,0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42,0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b, -0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01,0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09,0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07, -0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07,0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a,0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d, -0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e,0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16, -0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01,0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35, -0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16,0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c,0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01, -0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15,0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11, -0x00,0x27,0x00,0x45,0x00,0x88,0xb5,0x24,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2b,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00,0x06,0x06,0x10,0x04,0x4e,0x1b, -0x40,0x31,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x00,0x06,0x00,0x04,0x07,0x06,0x04,0x67,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x05,0x05,0x01,0x57,0x00,0x01,0x01,0x05,0x5f,0x00,0x05,0x01,0x05,0x4f,0x59,0x40,0x17,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d, -0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36,0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26, -0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25, -0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e,0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33, -0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07,0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e, -0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d,0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80, -0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1a,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80, -0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02, -0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12,0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59, -0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59,0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d,0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36, -0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34, -0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe,0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7, -0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d,0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3,0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33, -0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43,0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33, -0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05,0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28,0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26, -0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f,0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b,0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8, -0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14,0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf,0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23, -0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01,0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11, -0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e, -0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00,0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14, -0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01,0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c,0x03,0x0f,0x00,0x1d,0x00,0x31,0xb7,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x00,0x00,0x10,0x4d,0x00, -0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x59,0xb4,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36,0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19,0x0a,0x10,0x01,0x0e,0x0b,0x01, -0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x13,0x00,0x29, -0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01,0x66,0x09,0x01,0x02, -0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a,0x01,0x04,0x04,0x01, -0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01,0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35,0x34,0x03,0x32,0x36, -0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a,0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16,0x0c,0x0c,0x24,0x1a, -0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a,0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x6a,0x40,0x0b,0x2a,0x01,0x03,0x05,0x25,0x1d,0x02,0x04, -0x03,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x24,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x22,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e, -0x00,0x05,0x00,0x03,0x04,0x05,0x03,0x69,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x09,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f,0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22, -0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56,0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d,0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e, -0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80, -0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23,0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17, -0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15,0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16,0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01, -0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00,0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41,0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49, -0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00,0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16,0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01, -0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e,0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71,0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda, -0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01,0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13,0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98, -0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03,0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x8d,0x40,0x11,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01,0x08,0x02,0x4b,0x4b,0xb0,0x26,0x50,0x58,0x40,0x2f,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03, -0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x10,0x4d,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x2d,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x0a,0x07,0x01,0x04,0x08,0x0a,0x04,0x67, -0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x10,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b,0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35, -0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe, -0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05,0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36, -0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07,0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x3c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x15,0x00,0x01,0x01,0x03,0x5f, -0x00,0x03,0x03,0x10,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x01,0x00,0x03,0x01,0x67,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x35,0x34,0x11,0x10,0x04,0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36, -0x37,0x21,0x32,0x16,0x8f,0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x59,0x4b,0xb0, -0x26,0x50,0x58,0x40,0x1e,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69,0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x1c,0x00,0x05,0x06,0x01,0x02,0x01,0x05,0x02,0x69,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11, -0x04,0x4e,0x59,0x40,0x11,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56, -0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x00,0x02,0x00,0x00, -0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x65,0xb6,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x1d,0x00,0x03,0x02,0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x10,0x00,0x4e,0x1b,0x40,0x24,0x00,0x03,0x02,0x03,0x86, -0x00,0x07,0x08,0x06,0x02,0x00,0x01,0x07,0x00,0x69,0x09,0x05,0x02,0x01,0x02,0x02,0x01,0x59,0x09,0x05,0x02,0x01,0x01,0x02,0x5f,0x04,0x01,0x02,0x01,0x02,0x4f,0x59,0x40,0x0e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06, -0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22,0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16,0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b, -0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58,0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14,0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x81, -0x40,0x13,0x43,0x25,0x02,0x06,0x09,0x2f,0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x29,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x10,0x4d,0x04,0x01,0x02,0x02,0x01,0x61,0x00,0x01,0x01,0x14,0x4d,0x00,0x03,0x03,0x00,0x61,0x00, -0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x27,0x00,0x08,0x00,0x06,0x05,0x08,0x06,0x69,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01,0x02,0x02,0x01,0x61,0x00,0x01,0x01,0x14,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0x40,0x0e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a,0x07,0x1f, -0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x3e, -0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16,0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07,0x0c,0x01, -0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x00, -0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x39,0x40,0x09,0x18,0x10,0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0d,0x03,0x01,0x01,0x01,0x10,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0d,0x03,0x01,0x01,0x01,0x00,0x5f,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x59, -0xb6,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14, -0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x30,0xb6,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x0b,0x00,0x01,0x01, -0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00,0x11,0x00,0x4e,0x59,0xb4,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc, -0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x69,0x40,0x0a,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x24,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05, -0x61,0x00,0x05,0x05,0x10,0x4d,0x00,0x02,0x02,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x22,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x05,0x00,0x01,0x00,0x05,0x01,0x69,0x00,0x02,0x02,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x40,0x09,0x27,0x27,0x13,0x27,0x24,0x33,0x06, -0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01,0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10,0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c, -0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d,0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05,0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74, -0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01,0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37, -0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06,0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c, -0x00,0x1c,0x00,0x2e,0x00,0x6a,0x40,0x0d,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1e,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x1c,0x06,0x01,0x00, -0x00,0x04,0x05,0x00,0x04,0x67,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x59,0x40,0x13,0x01,0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26, -0x2b,0x01,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06, -0x0a,0x0a,0x09,0x67,0x08,0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07, -0x04,0x00,0x02,0x01,0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14,0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16, -0x14,0x0f,0x01,0x17,0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10, -0x10,0x4c,0x0f,0x2e,0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x5c,0x40,0x0b,0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1d,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x10,0x4d, -0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x1b,0x00,0x05,0x00,0x04,0x03,0x05,0x04,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0x40,0x09,0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17, -0x33,0x32,0x36,0x25,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18,0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14, -0x0f,0xfc,0xa6,0x0e,0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16,0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67, -0x00,0x61,0x40,0x5e,0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08,0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06, -0x06,0x12,0x0b,0x4e,0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b, -0x01,0x22,0x0e,0x01,0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16, -0x32,0x36,0x05,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46,0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a, -0x38,0x28,0x8a,0x2a,0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c, -0x22,0x8c,0x34,0x6c,0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x6f,0x40,0x0a,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c, -0x4b,0xb0,0x24,0x50,0x58,0x40,0x26,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x10,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x1b,0x40,0x24,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04, -0x7e,0x00,0x07,0x00,0x01,0x00,0x07,0x01,0x67,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x59,0x40,0x0b,0x35,0x35,0x23,0x33,0x16,0x23,0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01, -0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01, -0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x3c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x15,0x00, -0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x10,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x1b,0x40,0x13,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x59,0xb6,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x07,0x15,0x14,0x16, -0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd, -0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x51,0x4b,0xb0,0x26,0x50,0x58,0x40,0x1a,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x10,0x01,0x4e,0x1b,0x40,0x20, -0x00,0x04,0x00,0x01,0x05,0x04,0x01,0x67,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x03,0x03,0x02,0x57,0x00,0x02,0x02,0x03,0x5f,0x00,0x03,0x02,0x03,0x4f,0x59,0x40,0x09,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14, -0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe,0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01, -0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x1b,0xf3,0xb7,0xb3,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe1,0xa1,0x0d,0xf0, -0x00,0x00,0x00,0x00,0xe1,0xa1,0x0d,0xf1,0xff,0xf5,0xff,0x6a,0x04,0x2f,0x03,0x53,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x2f,0xff,0xf5,0xff,0xf5,0x04,0x2f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4c, -0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0x11,0x00,0x00,0x00,0xf0,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0xff,0xfd,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x02,0x3b,0xff,0xff, -0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00,0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00,0x02,0xda,0x00,0x00, -0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00, -0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x00,0xdc,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff,0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00, -0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe,0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x01,0x0a,0x01,0xce,0x02,0x3a,0x02,0xb8,0x03,0x06, -0x03,0x34,0x03,0x60,0x04,0x0c,0x05,0x06,0x05,0x62,0x06,0x12,0x06,0x3c,0x06,0x5e,0x06,0x88,0x06,0xc0,0x06,0xf8,0x07,0xa0,0x08,0x00,0x08,0xd2,0x09,0x36,0x09,0x74,0x09,0x98,0x09,0xf2,0x0a,0x3a,0x0b,0x12,0x0c,0x18,0x0c,0xa4,0x0d,0xae,0x0e,0x06,0x0e,0x2c,0x0e,0x8e,0x0f,0x12,0x0f,0x64,0x0f,0xfa,0x10,0x22,0x10,0x76,0x11,0x7a, -0x11,0x98,0x11,0xd0,0x12,0x3a,0x12,0x96,0x12,0xf6,0x13,0xdc,0x14,0x78,0x14,0xee,0x15,0x28,0x15,0xec,0x16,0x96,0x16,0xba,0x17,0xc8,0x18,0x2a,0x18,0x82,0x18,0xa0,0x18,0xea,0x19,0x86,0x1a,0x06,0x1a,0x5a,0x1a,0xd6,0x1b,0x84,0x1b,0xc8,0x1c,0x30,0x1c,0xaa,0x1d,0x52,0x1d,0xa2,0x1d,0xd8,0x1e,0x56,0x1e,0x8c,0x1f,0x08,0x1f,0x56, -0x1f,0xc8,0x20,0x84,0x21,0x06,0x21,0x58,0x21,0xc3,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4c,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00, -0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10,0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e, -0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10,0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03, -0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x33,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66, -0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c,0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76, -0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00, -0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x32,0x00,0x33,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00, -0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00, -0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00, -0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00, -0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12, -0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32, -0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d, -0x70,0x74,0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x05,0x74,0x72,0x61,0x73,0x68,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x69,0x72, -0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68,0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72,0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72, -0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c,0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e, -0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77,0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03,0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65, -0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73,0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74,0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65, -0x6c,0x08,0x73,0x74,0x65,0x70,0x69,0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08, -0x73,0x74,0x65,0x70,0x6f,0x76,0x65,0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66, -0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x03,0x64,0x6f,0x74,0x07,0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65, -0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74,0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x70,0x69, -0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f,0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03,0x62,0x6f, -0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1,0x03,0x38,0x02,0xc8,0xff,0xd0,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x02,0xc8,0xff,0xd0,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58, -0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06,0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20, -0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0,0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1,0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60, -0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e,0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0, -0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50,0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58,0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1, -0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58,0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20,0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21, -0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25,0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50,0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59, -0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16,0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07,0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07, -0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b,0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20,0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0, -0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08,0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09, -0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2,0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00, -0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0, -0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42, -0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20,0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59, -0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12,0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64, -0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d,0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43,0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43, -0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25,0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0, -0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44,0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42, -0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01,0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d, -0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1,0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1,0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d, -0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0, -0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11, -0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1,0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d, -0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1,0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20,0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0, -0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f,0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62, -0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02, -0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0,0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01, -0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00,0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62, -0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43, -0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20,0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59,0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25, -0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58, -0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20, -0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a, -0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06,0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63, -0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0,0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0,0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d, -0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23,0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47, -0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20,0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20, -0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e, -0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25, -0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20, -0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c,0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00, -0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23,0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23, -0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01, -0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20, -0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00,0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49, -0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a, -0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20,0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f,0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c, -0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00,0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c,0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59, -0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3,0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00, -0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d,0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00,0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48, -0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3,0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d, -0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3,0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b, -0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b, -0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e, -0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c, -0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1,0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40, -0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06,0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45, -0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1,0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00, -0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44,0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80, -0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44,0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, +0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x2f,0x40,0x2c,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x03,0x00,0x51,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27,0x0f,0x01, +0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16,0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80,0x95,0x40, +0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f,0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40,0x00,0x00, +0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x28,0x40,0x25,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e, +0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, +0x74,0xc4,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xe3,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16,0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02,0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x26,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80, +0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50,0x58,0x40,0x27,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05, +0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x29,0x50,0x58,0x40,0x28,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23, +0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x59,0x40,0x12,0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15, +0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01,0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c,0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b, +0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe,0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00,0x00,0x05,0xff,0xff,0xff,0xf9,0x03,0x59,0x02,0xc4,0x00,0x08,0x00,0x11,0x00,0x21,0x00,0x2b,0x00,0x41,0x00,0x8e,0x40,0x0f, +0x13,0x01,0x01,0x04,0x09,0x00,0x02,0x00,0x01,0x1b,0x01,0x05,0x00,0x03,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x30,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x08,0x00,0x70,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08, +0x60,0x00,0x08,0x05,0x08,0x50,0x1b,0x40,0x31,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x04,0x00,0x05,0x7e,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08,0x60,0x00,0x08,0x05,0x08,0x50,0x59,0x40,0x0e,0x3d,0x3a,0x37, +0x23,0x13,0x26,0x25,0x13,0x14,0x13,0x12,0x0a,0x07,0x1f,0x2b,0x25,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x35,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x21,0x32,0x36,0x01,0x21,0x03,0x2e,0x01,0x23,0x21,0x22,0x06,0x07,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26, +0x37,0x35,0x34,0x37,0x13,0x3e,0x01,0x17,0x21,0x32,0x16,0x17,0x13,0x16,0x02,0x44,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x91,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x41,0x0c,0x06,0xfd,0x59,0x07,0x0a,0x01,0x0c,0x06,0x02,0xa7,0x07,0x0a,0xfd,0x52,0x02,0x93,0x58,0x02,0x0e,0x07,0xfe,0x4b,0x07,0x0e,0x02,0x02,0x9e,0x34,0x25,0xfd,0x59, +0x24,0x36,0x01,0x09,0x6e,0x09,0x34,0x1e,0x01,0xb5,0x1f,0x32,0x0a,0x6e,0x09,0xab,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x14,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x6d,0xb3,0x07,0x0a,0x01,0x0c,0x06,0xb3,0x07,0x0a,0x01,0x0c,0x01,0x12,0x01,0x0d,0x07,0x0a,0x0a,0x07,0xfe,0x9a,0xb3,0x25,0x34,0x34,0x25,0xb3,0x0e,0x1c,0x01,0x52,0x1d, +0x26,0x01,0x24,0x1e,0xfe,0xae,0x1c,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13,0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21, +0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f,0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b,0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00, +0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07,0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37, +0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11,0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00, +0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x01,0x4d,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x36,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x72,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d, +0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x13,0x50,0x58,0x40,0x3c,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x70,0x0e,0x05,0x02,0x02,0x0a, +0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58,0x40,0x3d,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, +0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x40,0x44,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, +0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a, +0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01, +0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01, +0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58,0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05,0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10, +0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02,0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a,0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54, +0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57,0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01, +0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe,0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5,0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85, +0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c,0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f, +0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5,0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03,0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67, +0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c,0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22, +0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07,0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14,0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a, +0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10,0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00,0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01, +0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10,0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f,0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22, +0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21,0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d,0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12, +0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc,0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06, +0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12,0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35,0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26, +0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21,0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12, +0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe,0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x62,0x01,0x0d,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x1c, +0x50,0x58,0x40,0x38,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x0a,0x4e,0x1b,0x4b,0xb0,0x21, +0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08, +0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10, +0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60,0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c,0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27, +0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01, +0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12,0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16, +0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07,0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7,0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19, +0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x44,0x40,0x41, +0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63,0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x13,0x06,0x4e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07, +0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x33,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11, +0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08, +0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x2d,0x40,0x2a, +0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05,0x5f,0x00,0x05,0x05,0x13,0x02,0x4e,0x35,0x35,0x35,0x36,0x26,0x23,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d,0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23, +0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43, +0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16, +0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06,0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06, +0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42,0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b,0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01, +0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09,0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07,0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07, +0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a,0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d,0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e, +0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21, +0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01,0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35,0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16, +0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c,0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01,0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15, +0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11,0x00,0x27,0x00,0x45,0x00,0x4b,0x40,0x48,0x24,0x01,0x01,0x00, +0x01,0x4c,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00,0x06,0x06,0x13,0x04,0x4e,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d,0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36, +0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d, +0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25,0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a, +0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e,0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00, +0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x26,0x40,0x23,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35, +0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe,0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33, +0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01,0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d, +0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f, +0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1b,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09, +0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12,0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01, +0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59,0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59,0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d, +0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36,0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d, +0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34,0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe, +0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7,0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d,0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3, +0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33,0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43,0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55, +0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33,0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05,0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28, +0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26,0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f,0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b, +0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8,0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14,0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf, +0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23,0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01,0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05, +0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e, +0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e,0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00, +0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14,0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01,0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c, +0x03,0x0f,0x00,0x1d,0x00,0x1b,0x40,0x18,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x00,0x00,0x00,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36,0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19, +0x0a,0x10,0x01,0x0e,0x0b,0x01,0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08, +0x00,0x13,0x00,0x29,0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01, +0x66,0x09,0x01,0x02,0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a, +0x01,0x04,0x04,0x01,0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01,0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35, +0x34,0x03,0x32,0x36,0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a,0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16, +0x0c,0x0c,0x24,0x1a,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a,0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x3b,0x40,0x38,0x2a,0x01,0x03,0x05, +0x25,0x1d,0x02,0x04,0x03,0x02,0x4c,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f, +0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56,0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d, +0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e,0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x01,0x00,0x00, +0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80,0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23, +0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15,0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16, +0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00,0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41, +0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49,0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00,0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16, +0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01,0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e,0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71, +0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda,0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01,0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13, +0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98,0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03,0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x53,0x40,0x50,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01, +0x08,0x02,0x4b,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x13,0x4d,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b, +0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34, +0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05, +0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36,0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07,0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x02,0xff,0xff, +0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x1f,0x40,0x1c,0x00,0x01,0x01,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x34,0x11,0x10,0x04,0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x8f, +0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x32,0x40,0x2f,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69, +0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01, +0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0, +0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x35,0x40,0x32,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x00,0x03,0x02,0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x13, +0x00,0x4e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06,0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22,0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16, +0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b,0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58,0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14, +0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x4b,0x40,0x48,0x43,0x25,0x02,0x06,0x09,0x2f,0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01, +0x02,0x00,0x01,0x00,0x02,0x01,0x69,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x13,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a,0x07,0x1f,0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16, +0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x3e,0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16, +0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07,0x0c,0x01,0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e, +0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x20,0x40,0x1d,0x18,0x10, +0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x03,0x01,0x01,0x01,0x13,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10, +0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f, +0x00,0x1a,0x40,0x17,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e, +0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x3a,0x40,0x37,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x04,0x61, +0x00,0x04,0x04,0x11,0x04,0x4e,0x27,0x27,0x13,0x27,0x24,0x33,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01,0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10, +0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c,0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d,0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05, +0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74,0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01,0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06, +0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06,0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00, +0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2e,0x00,0x41,0x40,0x3e,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x13,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x01, +0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32, +0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06,0x0a,0x0a,0x09,0x67,0x08,0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01, +0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07,0x04,0x00,0x02,0x01,0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14, +0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x14,0x0f,0x01,0x17,0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10, +0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x0f,0x2e,0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x34,0x40,0x31, +0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17,0x33,0x32,0x36,0x25, +0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18,0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14,0x0f,0xfc,0xa6,0x0e, +0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16,0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67,0x00,0x61,0x40,0x5e, +0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08,0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06,0x06,0x12,0x0b,0x4e, +0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b,0x01,0x22,0x0e,0x01, +0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x05,0x32, +0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46,0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a,0x38,0x28,0x8a,0x2a, +0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x8c,0x34,0x6c, +0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x3e,0x40,0x3b,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x02,0x01,0x00,0x01, +0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x13,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x35,0x35,0x23,0x33,0x16,0x23,0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06, +0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43, +0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f, +0x00,0x1f,0x00,0x1f,0x40,0x1c,0x00,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37, +0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00, +0x00,0x01,0x00,0x00,0x98,0xdf,0x81,0x07,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xed,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xee,0xff,0xf5,0xff,0x6a,0x04,0x78,0x03,0x53,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x76, +0xff,0xf5,0xff,0xf5,0x04,0x78,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0x11,0x00,0x00,0x04,0x2f,0xff,0xff,0x00,0xf0,0x00,0x00,0x04,0x76,0xff,0xff,0x03,0xe8,0xff,0xff,0x03,0xe8,0x00,0x00,0x02,0x44,0x00,0x00, +0x02,0x44,0x00,0x00,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0xdc,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x02,0x3b,0xff,0xff,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00, +0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00,0x02,0xda,0x00,0x00,0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xff, +0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0xe8,0x00,0x00, +0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff,0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe, +0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0xe0,0x01,0x8a,0x02,0x04,0x02,0x5a,0x02,0xb2,0x02,0xd8,0x03,0x24,0x03,0x5a,0x03,0x7c,0x03,0xa0,0x03,0xcc,0x04,0x56,0x05,0x18,0x05,0x74,0x06,0x08, +0x06,0x2c,0x06,0x56,0x06,0x78,0x06,0xa2,0x06,0xda,0x07,0x12,0x07,0xba,0x08,0x0c,0x08,0xb4,0x09,0x06,0x09,0x34,0x09,0x56,0x09,0xa2,0x09,0xea,0x0a,0xac,0x0b,0x96,0x0c,0x22,0x0d,0x0e,0x0d,0x52,0x0d,0x78,0x0d,0xda,0x0e,0x3e,0x0e,0x80,0x0f,0x32,0x0f,0xe2,0x10,0x0a,0x10,0x5e,0x11,0x90,0x11,0xae,0x11,0xe6,0x12,0x50,0x12,0xac, +0x13,0x0c,0x14,0x14,0x14,0x94,0x14,0xf4,0x15,0x2e,0x15,0xf2,0x16,0x7e,0x16,0xd4,0x17,0xe2,0x18,0x44,0x18,0x9c,0x18,0xba,0x18,0xf8,0x19,0x94,0x19,0xfc,0x1a,0x50,0x1a,0xcc,0x1b,0x5c,0x1b,0x90,0x1b,0xe4,0x1c,0x46,0x1c,0xd4,0x1d,0x18,0x1d,0x42,0x1d,0xa8,0x1d,0xde,0x1e,0x46,0x1e,0x94,0x1e,0xf2,0x1f,0xae,0x20,0x18,0x20,0x5c, +0x00,0x01,0x00,0x00,0x00,0x51,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01, +0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00, +0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10,0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10, +0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f, +0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x35,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c, +0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76,0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46, +0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00, +0x32,0x00,0x30,0x00,0x32,0x00,0x35,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00, +0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00, +0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00,0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00, +0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00, +0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18, +0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38, +0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x01,0x4e,0x01,0x4f,0x01,0x50,0x01,0x51,0x01,0x52,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d,0x70,0x74, +0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x05,0x74,0x72,0x61,0x73,0x68,0x07,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0e,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x72,0x65,0x73,0x74,0x6f,0x72,0x65,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x69, +0x6e,0x69,0x6d,0x69,0x7a,0x65,0x04,0x63,0x75,0x62,0x65,0x04,0x70,0x6c,0x75,0x73,0x05,0x6d,0x69,0x6e,0x75,0x73,0x06,0x63,0x69,0x72,0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68,0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72, +0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x03,0x64,0x6f,0x74,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72,0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c, +0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77,0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03, +0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65,0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73,0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74, +0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x03,0x68,0x64,0x64,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65,0x6c,0x08,0x73,0x74,0x65,0x70,0x69,0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f, +0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08,0x73,0x74,0x65,0x70,0x6f,0x76,0x65,0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75, +0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x07, +0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74, +0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x70,0x69,0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f, +0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03,0x62,0x6f,0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61, +0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1, +0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58,0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06,0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00, +0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20,0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0,0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1, +0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60,0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e,0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59, +0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50,0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58, +0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58,0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20, +0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21,0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25,0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50, +0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16,0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07, +0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07,0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b,0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20, +0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0,0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08, +0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09,0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2, +0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0, +0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0, +0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42,0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20, +0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59,0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12, +0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64,0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d,0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43, +0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43,0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25, +0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44, +0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01, +0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d,0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1,0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1, +0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d,0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10, +0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58, +0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11,0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1, +0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d,0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1,0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20, +0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0,0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f,0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0, +0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42, +0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0, +0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00, +0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0, +0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43,0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20,0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59, +0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25, +0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0, +0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40, +0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a,0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06, +0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0,0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0, +0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23,0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42, +0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20, +0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0, +0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0, +0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30, +0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c,0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43, +0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23,0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1, +0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59, +0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20, +0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00, +0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00, +0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a,0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20,0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f, +0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c,0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00,0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c, +0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59,0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3,0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43, +0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00,0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d,0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00, +0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48,0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3, +0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d,0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3,0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1, +0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b, +0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b, +0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0, +0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1,0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c, +0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06, +0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1,0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00, +0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44, +0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80,0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44, +0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, }; read_only global String8 rd_icon_font_bytes = {rd_icon_font_bytes__data, sizeof(rd_icon_font_bytes__data)}; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b6ae2570..4812a18e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -109,6 +109,8 @@ RD_VocabTable: {show_line_numbers "" "Show Line Numbers" "" Null } {syntax syntaxes "Syntax" "Syntaxes" Null } {num_columns "" "Number of Columns" "" Null } + {bitmap _ "Bitmap" _ Bitmap } + {geo3d "" "Geometry (3D)" "" Cube } } @struct RD_VocabInfo: @@ -178,13 +180,13 @@ RD_VocabTable: x: { 'arch': arch, + 'syntax': dasm_syntax, 'size': code_string, @default(1) 'show_addresses': bool, @default(0) 'show_code_bytes': bool, @default(1) 'show_source_lines': bool, @default(1) 'show_symbol_names': bool, @default(1) 'show_line_numbers': bool, - 'syntax': dasm_syntax, } ``` } @@ -947,6 +949,7 @@ RD_IconTable: (RadioFilled "o") (CheckHollow "!") (CheckFilled "1") + (Check "V") (LeftCaret "<") (RightCaret ">") (UpCaret "^") @@ -987,7 +990,11 @@ RD_IconTable: (QuestionMark "?") (Person "4") (Briefcase "5") - (Dot "c") + (Dot "6") + (Bitmap "&") + (Cube "*") + (WindowRestore "(") + (WindowMinimize ")") } @enum RD_IconKind: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 149033b0..c8c87233 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7654,11 +7654,13 @@ rd_window_frame(void) // rjf: build top-level container box UI_Box *container = &ui_nil_box; UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) + UI_CornerRadius(ui_top_font_size()*0.25f) { container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_RoundChildrenByParent| UI_BoxFlag_DisableFocusOverlay| UI_BoxFlag_DrawDropShadow| (UI_BoxFlag_SquishAnchored*!!is_anchored), @@ -7809,394 +7811,400 @@ rd_window_frame(void) MemoryZeroArray(ui_top_parent()->parent->corner_radii); //- rjf: left column - ui_set_next_flags(UI_BoxFlag_Clip|UI_BoxFlag_ViewScrollX|UI_BoxFlag_ViewClamp); - UI_WidthFill UI_NamedRow(str8_lit("###menu_bar")) { - //- rjf: icon - UI_Padding(ui_em(0.5f, 1.f)) + ui_set_next_flags(UI_BoxFlag_Clip|UI_BoxFlag_ViewScrollX|UI_BoxFlag_ViewClamp); + UI_WidthFill UI_NamedRow(str8_lit("###menu_bar")) { - UI_PrefWidth(ui_px(dim_2f32(top_bar_rect).y - ui_top_font_size()*0.8f, 1.f)) - UI_Column - UI_Padding(ui_em(0.4f, 1.f)) - UI_HeightFill + //- rjf: icon + UI_Padding(ui_em(0.5f, 1.f)) { - R_Handle texture = rd_state->icon_texture; - Vec2S32 texture_dim = r_size_from_tex2d(texture); - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); - } - } - - //- rjf: menu items - ui_set_next_flags(UI_BoxFlag_DrawBackground); - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(20, 1)) UI_GroupKey(menu_bar_group_key) - { - // rjf: file menu - UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); - UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_Open].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, - rd_cmd_kind_info_table[RD_CmdKind_Exit].string, - }; - U32 codepoints[] = - { - 'o', - 'u', - 'p', - 'r', - 'x', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: window menu - UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); - UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_OpenWindow].string, - rd_cmd_kind_info_table[RD_CmdKind_CloseWindow].string, - rd_cmd_kind_info_table[RD_CmdKind_ToggleFullscreen].string, - }; - U32 codepoints[] = - { - 'w', - 'c', - 'f', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: panel menu - UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); - UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_NewPanelUp].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelDown].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelRight].string, - rd_cmd_kind_info_table[RD_CmdKind_NewPanelLeft].string, - rd_cmd_kind_info_table[RD_CmdKind_ClosePanel].string, - rd_cmd_kind_info_table[RD_CmdKind_RotatePanelColumns].string, - rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string, - rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string, - rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, - rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, - rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, - rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string, - rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, - rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, - rd_cmd_kind_info_table[RD_CmdKind_ResetToCompactPanels].string, - rd_cmd_kind_info_table[RD_CmdKind_ResetToSimplePanels].string, - }; - U32 codepoints[] = - { - 'u', - 'd', - 'r', - 'l', - 'x', - 'c', - 'n', - 'p', - 't', - 'b', - 'v', - 0, - 0, - 0, - 0, - 0, - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: view menu - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_Targets].string, - rd_cmd_kind_info_table[RD_CmdKind_Scheduler].string, - rd_cmd_kind_info_table[RD_CmdKind_CallStack].string, - rd_cmd_kind_info_table[RD_CmdKind_Modules].string, - rd_cmd_kind_info_table[RD_CmdKind_Output].string, - rd_cmd_kind_info_table[RD_CmdKind_Memory].string, - rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, - rd_cmd_kind_info_table[RD_CmdKind_Watch].string, - rd_cmd_kind_info_table[RD_CmdKind_Locals].string, - rd_cmd_kind_info_table[RD_CmdKind_Registers].string, - rd_cmd_kind_info_table[RD_CmdKind_Globals].string, - rd_cmd_kind_info_table[RD_CmdKind_ThreadLocals].string, - rd_cmd_kind_info_table[RD_CmdKind_Types].string, - rd_cmd_kind_info_table[RD_CmdKind_Procedures].string, - rd_cmd_kind_info_table[RD_CmdKind_Breakpoints].string, - rd_cmd_kind_info_table[RD_CmdKind_WatchPins].string, - rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, - rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, - rd_cmd_kind_info_table[RD_CmdKind_Settings].string, - rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, - }; - U32 codepoints[] = - { - 't', - 's', - 'k', - 'd', - 'o', - 'm', - 'y', - 'w', - 'l', - 'r', - 0, - 0, - 0, - 0, - 'b', - 'h', - 'p', - 'v', - 'g', - 0, - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: targets menu - UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); - UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - Temp scratch = scratch_begin(0, 0); - String8 cmds[] = - { - rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string, - rd_cmd_kind_info_table[RD_CmdKind_LaunchAndRun].string, - rd_cmd_kind_info_table[RD_CmdKind_LaunchAndStepInto].string, - }; - U32 codepoints[] = - { - 'a', - 'r', - 's', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - scratch_end(scratch); - } - - // rjf: ctrl menu - UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); - UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - String8 cmds[] = - { - rd_cmd_kind_info_table[D_CmdKind_Run].string, - rd_cmd_kind_info_table[D_CmdKind_KillAll].string, - rd_cmd_kind_info_table[D_CmdKind_Restart].string, - rd_cmd_kind_info_table[D_CmdKind_Halt].string, - rd_cmd_kind_info_table[D_CmdKind_StepInto].string, - rd_cmd_kind_info_table[D_CmdKind_StepOver].string, - rd_cmd_kind_info_table[D_CmdKind_StepOut].string, - rd_cmd_kind_info_table[D_CmdKind_Attach].string, - }; - U32 codepoints[] = - { - 'r', - 'k', - 's', - 'h', - 'i', - 'o', - 't', - 'a', - }; - Assert(ArrayCount(codepoints) == ArrayCount(cmds)); - rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); - } - - // rjf: help menu - UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); - UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") - { - UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_TagF("weak") - ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); - ui_spacer(ui_em(1.f, 1.f)); - UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1, 0)) + UI_PrefWidth(ui_px(dim_2f32(top_bar_rect).y - ui_top_font_size()*0.8f, 1.f)) + UI_Column + UI_Padding(ui_em(0.4f, 1.f)) + UI_HeightFill { R_Handle texture = rd_state->icon_texture; Vec2S32 texture_dim = r_size_from_tex2d(texture); - UI_PrefWidth(ui_px(ui_top_font_size()*10.f, 1.f)) - UI_PrefHeight(ui_px(ui_top_font_size()*10.f, 1.f)) - ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); } - ui_spacer(ui_em(1.f, 1.f)); - UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - UI_Padding(ui_pct(1, 0)) - { - ui_labelf("Search for commands and options by pressing "); - UI_Flags(UI_BoxFlag_DrawBorder) - UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); - } - ui_spacer(ui_em(1.f, 1.f)); - UI_TagF("pop") - UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) - UI_CornerRadius(ui_top_font_size()*0.5f) - { - String8 url = str8_lit("https://github.com/EpicGamesExt/raddebugger/issues"); - UI_Signal sig = ui_button(str8_lit("Submit Request, Issue, or Bug Report")); - if(ui_clicked(sig)) - { - os_open_in_browser(url); - } - } - ui_spacer(ui_em(0.5f, 1.f)); } - // rjf: buttons - UI_TextAlignment(UI_TextAlign_Center) UI_HeightFill + //- rjf: menu items + if(dim_2f32(top_bar_rect).x > ui_top_font_size()*60) { - // rjf: set up table - struct + ui_set_next_flags(UI_BoxFlag_DrawBackground); + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(20, 1)) UI_GroupKey(menu_bar_group_key) { - String8 name; - U32 codepoint; - OS_Key key; - UI_Key menu_key; - } - items[] = - { - {str8_lit("File"), 'f', OS_Key_F, file_menu_key}, - {str8_lit("Window"), 'w', OS_Key_W, window_menu_key}, - {str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key}, - {str8_lit("View"), 'v', OS_Key_V, view_menu_key}, - {str8_lit("Targets"), 't', OS_Key_T, targets_menu_key}, - {str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key}, - {str8_lit("Help"), 'h', OS_Key_H, help_menu_key}, - }; - - // rjf: determine if one of the menus is already open - B32 menu_open = 0; - U64 open_menu_idx = 0; - for(U64 idx = 0; idx < ArrayCount(items); idx += 1) - { - if(ui_ctx_menu_is_open(items[idx].menu_key)) + // rjf: file menu + UI_Key file_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_file_menu_key_")); + UI_CtxMenu(file_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { - menu_open = 1; - open_menu_idx = idx; - break; + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_Open].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, + rd_cmd_kind_info_table[RD_CmdKind_Exit].string, + }; + U32 codepoints[] = + { + 'o', + 'u', + 'p', + 'r', + 'x', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); } - } - - // rjf: navigate between menus - U64 open_menu_idx_prime = open_menu_idx; - if(menu_open && ws->menu_bar_focused && window_is_focused) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) + + // rjf: window menu + UI_Key window_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_window_menu_key_")); + UI_CtxMenu(window_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { - B32 taken = 0; - if(evt->delta_2s32.x > 0) + String8 cmds[] = { - taken = 1; - open_menu_idx_prime += 1; - open_menu_idx_prime = open_menu_idx_prime%ArrayCount(items); + rd_cmd_kind_info_table[RD_CmdKind_OpenWindow].string, + rd_cmd_kind_info_table[RD_CmdKind_CloseWindow].string, + rd_cmd_kind_info_table[RD_CmdKind_ToggleFullscreen].string, + }; + U32 codepoints[] = + { + 'w', + 'c', + 'f', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: panel menu + UI_Key panel_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_panel_menu_key_")); + UI_CtxMenu(panel_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_NewPanelUp].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelDown].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelRight].string, + rd_cmd_kind_info_table[RD_CmdKind_NewPanelLeft].string, + rd_cmd_kind_info_table[RD_CmdKind_ClosePanel].string, + rd_cmd_kind_info_table[RD_CmdKind_RotatePanelColumns].string, + rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string, + rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string, + rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, + rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, + rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, + rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string, + rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToCompactPanels].string, + rd_cmd_kind_info_table[RD_CmdKind_ResetToSimplePanels].string, + }; + U32 codepoints[] = + { + 'u', + 'd', + 'r', + 'l', + 'x', + 'c', + 'n', + 'p', + 't', + 'b', + 'v', + 0, + 0, + 0, + 0, + 0, + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: view menu + UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); + UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_Targets].string, + rd_cmd_kind_info_table[RD_CmdKind_Scheduler].string, + rd_cmd_kind_info_table[RD_CmdKind_CallStack].string, + rd_cmd_kind_info_table[RD_CmdKind_Modules].string, + rd_cmd_kind_info_table[RD_CmdKind_Output].string, + rd_cmd_kind_info_table[RD_CmdKind_Memory].string, + rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, + rd_cmd_kind_info_table[RD_CmdKind_Watch].string, + rd_cmd_kind_info_table[RD_CmdKind_Locals].string, + rd_cmd_kind_info_table[RD_CmdKind_Registers].string, + rd_cmd_kind_info_table[RD_CmdKind_Globals].string, + rd_cmd_kind_info_table[RD_CmdKind_ThreadLocals].string, + rd_cmd_kind_info_table[RD_CmdKind_Types].string, + rd_cmd_kind_info_table[RD_CmdKind_Procedures].string, + rd_cmd_kind_info_table[RD_CmdKind_Breakpoints].string, + rd_cmd_kind_info_table[RD_CmdKind_WatchPins].string, + rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, + rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, + rd_cmd_kind_info_table[RD_CmdKind_Settings].string, + rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, + }; + U32 codepoints[] = + { + 't', + 's', + 'k', + 'd', + 'o', + 'm', + 'y', + 'w', + 'l', + 'r', + 0, + 0, + 0, + 0, + 'b', + 'h', + 'p', + 'v', + 'g', + 0, + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: targets menu + UI_Key targets_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_targets_menu_key_")); + UI_CtxMenu(targets_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + Temp scratch = scratch_begin(0, 0); + String8 cmds[] = + { + rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndRun].string, + rd_cmd_kind_info_table[RD_CmdKind_LaunchAndStepInto].string, + }; + U32 codepoints[] = + { + 'a', + 'r', + 's', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + scratch_end(scratch); + } + + // rjf: ctrl menu + UI_Key ctrl_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_ctrl_menu_key_")); + UI_CtxMenu(ctrl_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + String8 cmds[] = + { + rd_cmd_kind_info_table[D_CmdKind_Run].string, + rd_cmd_kind_info_table[D_CmdKind_KillAll].string, + rd_cmd_kind_info_table[D_CmdKind_Restart].string, + rd_cmd_kind_info_table[D_CmdKind_Halt].string, + rd_cmd_kind_info_table[D_CmdKind_StepInto].string, + rd_cmd_kind_info_table[D_CmdKind_StepOver].string, + rd_cmd_kind_info_table[D_CmdKind_StepOut].string, + rd_cmd_kind_info_table[D_CmdKind_Attach].string, + }; + U32 codepoints[] = + { + 'r', + 'k', + 's', + 'h', + 'i', + 'o', + 't', + 'a', + }; + Assert(ArrayCount(codepoints) == ArrayCount(cmds)); + rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); + } + + // rjf: help menu + UI_Key help_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_help_menu_key_")); + UI_CtxMenu(help_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + { + UI_Row UI_TextAlignment(UI_TextAlign_Center) UI_TagF("weak") + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); + ui_spacer(ui_em(1.f, 1.f)); + UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1, 0)) + { + R_Handle texture = rd_state->icon_texture; + Vec2S32 texture_dim = r_size_from_tex2d(texture); + UI_PrefWidth(ui_px(ui_top_font_size()*10.f, 1.f)) + UI_PrefHeight(ui_px(ui_top_font_size()*10.f, 1.f)) + ui_image(texture, R_Tex2DSampleKind_Linear, r2f32p(0, 0, texture_dim.x, texture_dim.y), v4f32(1, 1, 1, 1), 0, str8_lit("")); } - if(evt->delta_2s32.x < 0) + ui_spacer(ui_em(1.f, 1.f)); + UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + UI_Padding(ui_pct(1, 0)) { - taken = 1; - open_menu_idx_prime = open_menu_idx_prime > 0 ? open_menu_idx_prime-1 : (ArrayCount(items)-1); + ui_labelf("Search for commands and options by pressing "); + UI_Flags(UI_BoxFlag_DrawBorder) + UI_TextAlignment(UI_TextAlign_Center) + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); } - if(taken) + ui_spacer(ui_em(1.f, 1.f)); + UI_TagF("pop") + UI_Row UI_Padding(ui_pct(1, 0)) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_text_dim(10, 1)) + UI_CornerRadius(ui_top_font_size()*0.5f) { - ui_eat_event(evt); + String8 url = str8_lit("https://github.com/EpicGamesExt/raddebugger/issues"); + UI_Signal sig = ui_button(str8_lit("Submit Request, Issue, or Bug Report")); + if(ui_clicked(sig)) + { + os_open_in_browser(url); + } + } + ui_spacer(ui_em(0.5f, 1.f)); + } + + // rjf: buttons + UI_TextAlignment(UI_TextAlign_Center) UI_HeightFill + { + // rjf: set up table + struct + { + String8 name; + U32 codepoint; + OS_Key key; + UI_Key menu_key; + } + items[] = + { + {str8_lit("File"), 'f', OS_Key_F, file_menu_key}, + {str8_lit("Window"), 'w', OS_Key_W, window_menu_key}, + {str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key}, + {str8_lit("View"), 'v', OS_Key_V, view_menu_key}, + {str8_lit("Targets"), 't', OS_Key_T, targets_menu_key}, + {str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key}, + {str8_lit("Help"), 'h', OS_Key_H, help_menu_key}, + }; + + // rjf: determine if one of the menus is already open + B32 menu_open = 0; + U64 open_menu_idx = 0; + for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + { + if(ui_ctx_menu_is_open(items[idx].menu_key)) + { + menu_open = 1; + open_menu_idx = idx; + break; + } + } + + // rjf: navigate between menus + U64 open_menu_idx_prime = open_menu_idx; + if(menu_open && ws->menu_bar_focused && window_is_focused) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + B32 taken = 0; + if(evt->delta_2s32.x > 0) + { + taken = 1; + open_menu_idx_prime += 1; + open_menu_idx_prime = open_menu_idx_prime%ArrayCount(items); + } + if(evt->delta_2s32.x < 0) + { + taken = 1; + open_menu_idx_prime = open_menu_idx_prime > 0 ? open_menu_idx_prime-1 : (ArrayCount(items)-1); + } + if(taken) + { + ui_eat_event(evt); + } + } + } + + // rjf: make ui + for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + { + ui_set_next_fastpath_codepoint(items[idx].codepoint); + B32 alt_fastpath_key = 0; + if(ui_key_press(OS_Modifier_Alt, items[idx].key)) + { + alt_fastpath_key = 1; + } + if((ws->menu_bar_key_held || ws->menu_bar_focused) && !ui_any_ctx_menu_is_open()) + { + ui_set_next_flags(UI_BoxFlag_DrawTextFastpathCodepoint); + } + UI_Signal sig = rd_menu_bar_button(items[idx].name); + os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); + if(menu_open) + { + if((ui_hovering(sig) && !ui_ctx_menu_is_open(items[idx].menu_key)) || (open_menu_idx_prime == idx && open_menu_idx_prime != open_menu_idx)) + { + ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + } + } + else if(ui_pressed(sig) || alt_fastpath_key) + { + if(ui_ctx_menu_is_open(items[idx].menu_key)) + { + ui_ctx_menu_close(); + } + else + { + ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + } + } } } } - // rjf: make ui - for(U64 idx = 0; idx < ArrayCount(items); idx += 1) + ui_spacer(ui_em(0.75f, 1)); + + // rjf: conversion task visualization + UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill UI_TagF("pop") { - ui_set_next_fastpath_codepoint(items[idx].codepoint); - B32 alt_fastpath_key = 0; - if(ui_key_press(OS_Modifier_Alt, items[idx].key)) + Temp scratch = scratch_begin(0, 0); + RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); + for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) { - alt_fastpath_key = 1; - } - if((ws->menu_bar_key_held || ws->menu_bar_focused) && !ui_any_ctx_menu_is_open()) - { - ui_set_next_flags(UI_BoxFlag_DrawTextFastpathCodepoint); - } - UI_Signal sig = rd_menu_bar_button(items[idx].name); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(menu_open) - { - if((ui_hovering(sig) && !ui_ctx_menu_is_open(items[idx].menu_key)) || (open_menu_idx_prime == idx && open_menu_idx_prime != open_menu_idx)) + RD_Cfg *task = n->v; + F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f); + if(task_t > 0.5f) { - ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); - } - } - else if(ui_pressed(sig) || alt_fastpath_key) - { - if(ui_ctx_menu_is_open(items[idx].menu_key)) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(items[idx].menu_key, sig.box->key, v2f32(0, sig.box->rect.y1-sig.box->rect.y0)); + String8 rdi_path = task->first->string; + String8 rdi_name = str8_skip_last_slash(rdi_path); + String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); + UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, key); + os_window_push_custom_title_bar_client_area(ws->os, box->rect); + UI_Signal sig = ui_signal_from_box(box); + if(ui_hovering(sig)) UI_Tooltip + { + ui_label(rdi_path); + } + ui_box_equip_display_string(box, task_text); } } + scratch_end(scratch); } } } - - ui_spacer(ui_em(0.75f, 1)); - - // rjf: conversion task visualization - UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill UI_TagF("pop") - { - Temp scratch = scratch_begin(0, 0); - RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); - for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) - { - RD_Cfg *task = n->v; - F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f); - if(task_t > 0.5f) - { - String8 rdi_path = task->first->string; - String8 rdi_name = str8_skip_last_slash(rdi_path); - String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); - UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, key); - os_window_push_custom_title_bar_client_area(ws->os, box->rect); - UI_Signal sig = ui_signal_from_box(box); - if(ui_hovering(sig)) UI_Tooltip - { - ui_label(rdi_path); - } - ui_box_equip_display_string(box, task_text); - } - } - scratch_end(scratch); - } } //- rjf: center column - UI_PrefWidth(ui_children_sum(1.f)) UI_Row + if(dim_2f32(top_bar_rect).x > ui_top_font_size()*60) + UI_PrefWidth(ui_children_sum(1.f)) UI_Row UI_PrefWidth(ui_em(2.5f, 1)) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.85f) @@ -8525,9 +8533,10 @@ rd_window_frame(void) Vec2F32 bar_dim = dim_2f32(top_bar_rect); F32 button_dim = floor_f32(bar_dim.y); UI_PrefWidth(ui_px(button_dim, 1.f)) + UI_FontSize(ui_top_font_size()*0.75f) { - min_sig = rd_icon_buttonf(RD_IconKind_Minus, 0, "##minimize"); - max_sig = rd_icon_buttonf(RD_IconKind_Window, 0, "##maximize"); + min_sig = rd_icon_buttonf(RD_IconKind_WindowMinimize, 0, "##minimize"); + max_sig = rd_icon_buttonf(os_window_is_maximized(ws->os) ? RD_IconKind_WindowRestore : RD_IconKind_Window, 0, "##maximize"); } UI_PrefWidth(ui_px(button_dim, 1.f)) UI_TagF("bad_pop") @@ -9324,7 +9333,7 @@ rd_window_frame(void) //- rjf: build tab view UI_Parent(view_container_box) if(selected_tab != &rd_nil_cfg) ProfScope("build tab view") { - rd_view_ui(pad_2f32(content_rect, -1.f)); + rd_view_ui(content_rect); } //- rjf: pop interaction registers; commit if this is the selected view @@ -13411,13 +13420,13 @@ rd_frame(void) } schema_type_name_key_map[] = { - { str8_lit("bool"), bool_type_key }, - { str8_lit("u64"), u64_type_key }, + { str8_lit("bool"), bool_type_key }, + { str8_lit("u64"), u64_type_key }, { str8_lit("vaddr_range"), vaddr_range_type_key }, { str8_lit("code_string"), code_string_type_key }, - { str8_lit("path"), path_type_key }, - { str8_lit("string"), string_type_key }, - { str8_lit("path_pt"), path_pt_type_key }, + { str8_lit("path"), path_type_key }, + { str8_lit("string"), string_type_key }, + { str8_lit("path_pt"), path_pt_type_key }, }; E_TypeKey evallable_meta_types[ArrayCount(rd_name_schema_info_table)] = {0}; for EachElement(idx, rd_name_schema_info_table) @@ -16063,9 +16072,9 @@ Z(getting_started) } // rjf: build query state + String8 current_query_cmd_name = cmd->first->string; rd_cfg_new_replace(input, initial_input); rd_cfg_new_replace(cmd, cmd_name); - String8 current_query_cmd_name = cmd->first->string; RD_ViewState *vs = rd_view_state_from_cfg(view); if(cmd_name.size != 0) { @@ -16174,7 +16183,7 @@ Z(getting_started) { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); - rd_cfg_new(disabled, str8_lit("1")); + rd_cfg_new_replace(disabled, str8_lit("1")); }break; case RD_CmdKind_RemoveCfg: { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3f24e4cb..0f7f2557 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1392,6 +1392,10 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla Temp scratch = scratch_begin(&arena, 1); E_Member member = result.eval.irtree.member; String8 member_name = member.name; + if(member_name.size == 0) + { + member_name = notable_expr->last->string; + } if(member.inheritance_key_chain.count != 0) { String8List strings = {0}; diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index a35d5fc8..c21f2430 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1289,9 +1289,31 @@ ui_end_build(void) !ui_box_is_nil(box); box = box->hash_next) { - if(box->flags & UI_BoxFlag_RoundChildrenByParent && - !ui_box_is_nil(box->first) && !ui_box_is_nil(box->last)) + if(box->flags & UI_BoxFlag_RoundChildrenByParent) { + for(UI_Box *b = box; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, box).next) + { + if(floor_f32(b->rect.x0) <= floor_f32(box->rect.x0) && + floor_f32(b->rect.y0) <= floor_f32(box->rect.y0)) + { + b->corner_radii[Corner_00] = box->corner_radii[Corner_00]; + } + if(floor_f32(b->rect.x1) >= floor_f32(box->rect.x1) && + floor_f32(b->rect.y0) <= floor_f32(box->rect.y0)) + { + b->corner_radii[Corner_10] = box->corner_radii[Corner_10]; + } + if(floor_f32(b->rect.x0) <= floor_f32(box->rect.x0) && + floor_f32(b->rect.y1) >= floor_f32(box->rect.y1)) + { + b->corner_radii[Corner_01] = box->corner_radii[Corner_01]; + } + if(floor_f32(b->rect.x1) >= floor_f32(box->rect.x1) && + floor_f32(b->rect.y1) >= floor_f32(box->rect.y1)) + { + b->corner_radii[Corner_11] = box->corner_radii[Corner_11]; + } + } box->first->corner_radii[Corner_00] = box->corner_radii[Corner_00]; box->first->corner_radii[Corner_10] = box->corner_radii[Corner_10]; box->last->corner_radii[Corner_01] = box->corner_radii[Corner_01]; From 4f2eb2ebe2d9d32bf6a421fb9764a2b0a45c93be Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 24 Mar 2025 14:56:41 -0700 Subject: [PATCH 236/755] pass over cell line edit; toggle-switches for editable boolean types --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 135 +++++++++++++++------- src/raddbg/raddbg_views.c | 9 ++ src/raddbg/raddbg_widgets.c | 178 ++++++++++++++++++++++------- src/raddbg/raddbg_widgets.h | 69 +++++++---- src/ui/ui_core.h | 3 + 7 files changed, 290 insertions(+), 108 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b57c8947..d4426e1e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -322,7 +322,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'debug_subprocesses': bool,\n 'environment': query,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4812a18e..8346f2db 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -228,8 +228,8 @@ RD_VocabTable: 'stdout_path': path, 'stderr_path': path, 'stdin_path': path, - 'debug_subprocesses': bool, 'environment': query, + 'debug_subprocesses': bool, } ```, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c8c87233..deca3596 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3449,10 +3449,10 @@ rd_view_ui(Rng2F32 rect) RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) ui_label(rd_display_from_code_name(cmd_name)); ui_spacer(ui_em(0.5f, 1.f)); - RD_LineEditParams params = {0}; + RD_CellParams params = {0}; { - params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_LineEditFlag_CodeContents; - params.flags |= RD_LineEditFlag_Border; + params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_CellFlag_CodeContents; + params.flags |= RD_CellFlag_Border; params.cursor = &vs->query_cursor; params.mark = &vs->query_mark; params.edit_buffer = vs->query_buffer; @@ -3462,7 +3462,7 @@ rd_view_ui(Rng2F32 rect) } UI_Transparency(1-search_row_open_t) { - UI_Signal sig = rd_line_editf(¶ms, "###search"); + UI_Signal sig = rd_cellf(¶ms, "###search"); if(ui_pressed(sig)) { vs->query_is_selected = 1; @@ -4747,12 +4747,14 @@ rd_view_ui(Rng2F32 rect) B32 pressed = 0; ProfScope("build ui") { + Vec2F32 rect_dim = dim_2f32(rect); + F32 contents_width_px = (rect_dim.x - floor_f32(ui_top_font_size()*1.5f)); Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; { scroll_list_params.flags = UI_ScrollListFlag_All; scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = dim_2f32(rect); + scroll_list_params.dim_px = rect_dim; scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; @@ -4843,7 +4845,7 @@ rd_view_ui(Rng2F32 rect) { EV_Row *row = last_row; RD_WatchRowInfo *row_info = last_row_info; - F32 row_width_px = (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); + F32 row_width_px = contents_width_px; if(row_info != 0) { U64 row_hash = ev_hash_from_key(row->key); @@ -5088,7 +5090,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: build row box // ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_width(ui_px(contents_width_px, 1.f)); ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); @@ -5115,7 +5117,7 @@ rd_view_ui(Rng2F32 rect) } } - //////////////////// + ////////////// //- rjf: draw mid-row cache line boundaries in expansions // if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) @@ -5138,14 +5140,16 @@ rd_view_ui(Rng2F32 rect) } } - //////////////////// + ////////////// //- rjf: build all cells // S64 cell_x = 0; F32 cell_x_px = 0; for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) { + //////////// //- rjf: unpack cell info + // U64 cell_id = rd_id_from_watch_cell(cell); RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); @@ -5153,9 +5157,12 @@ rd_view_ui(Rng2F32 rect) RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; + B32 cell_toggled = (e_value_eval_from_eval(cell_info.eval).value.u64 != 0); + B32 next_cell_toggled = cell_toggled; + //////////// //- rjf: determine cell's palette - ProfBegin("determine cell's palette"); + // UI_BoxFlags cell_flags = 0; Vec4F32 cell_background_color_override = {0}; String8 cell_tag = {0}; @@ -5164,16 +5171,13 @@ rd_view_ui(Rng2F32 rect) rd_state->hover_regs_slot == RD_RegSlot_Cfg) { RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = linear_from_srgba(rd_color_from_cfg(cfg)); + Vec4F32 rgba = rd_color_from_cfg(cfg); + rgba.w *= 0.05f; if(rgba.w == 0) { rgba = pop_background_rgba; rgba.w *= 0.5f; } - else - { - rgba.w *= 0.05f; - } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; @@ -5183,23 +5187,21 @@ rd_view_ui(Rng2F32 rect) { CTRL_Entity *entity = cell_info.entity; Vec4F32 rgba = rd_color_from_ctrl_entity(entity); + rgba.w *= 0.05f; if(rgba.w == 0) { rgba = pop_background_rgba; rgba.w *= 0.5f; } - else - { - rgba.w *= 0.05f; - } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; cell_flags |= UI_BoxFlag_DrawBackground; } } - ProfEnd(); - //- rjf: build cell + //////////// + //- rjf: build cell container + // UI_Box *cell_box = &ui_nil_box; UI_PrefWidth(ui_px(cell_width_px, 0.f)) { @@ -5207,7 +5209,9 @@ rd_view_ui(Rng2F32 rect) cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); } + //////////// //- rjf: build cell contents + // UI_Signal sig = {0}; ProfScope("build cell contents") UI_Parent(cell_box) @@ -5217,7 +5221,7 @@ rd_view_ui(Rng2F32 rect) UI_TagF("weak") UI_Tag(cell_tag) { - // rjf: cell has errors? -> build error box + //- rjf: cell has errors? -> build error box if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); @@ -5228,7 +5232,7 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: cell has hook? -> build ui by calling hook + //- rjf: cell has hook? -> build ui by calling hook else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) { Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); @@ -5295,7 +5299,7 @@ rd_view_ui(Rng2F32 rect) sig = ui_signal_from_box(box); } - // rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + //- rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty else if(cell->kind == RD_WatchCellKind_CallStackFrame) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); @@ -5315,11 +5319,12 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: build cell line edit + //- rjf: build general cell else { // rjf: compute visual params B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 is_toggle_switch = (cell_info.eval.irtree.mode == E_Mode_Offset && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; @@ -5355,17 +5360,11 @@ rd_view_ui(Rng2F32 rect) } } - // rjf: build - RD_LineEditParams line_edit_params = {0}; + // rjf: form cell build parameters + RD_CellParams line_edit_params = {0}; { - line_edit_params.flags = (RD_LineEditFlag_CodeContents*!is_non_code| - RD_LineEditFlag_NoBackground*!is_button| - RD_LineEditFlag_Button*is_button| - RD_LineEditFlag_SingleClickActivate*is_activated_on_single_click| - RD_LineEditFlag_KeyboardClickable| - RD_LineEditFlag_Expander*!!(row_is_expandable && cell == row_info->cells.first)| - RD_LineEditFlag_ExpanderSpace*(row_depth==!implicit_root && cell == row_info->cells.first && !is_button)| - RD_LineEditFlag_ExpanderSpace*((row_depth!=0 && cell == row_info->cells.first))); + // rjf: set up base parameters + line_edit_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); line_edit_params.depth = (cell_x == 0 ? row_depth : 0); line_edit_params.cursor = &cell_edit_state->cursor; line_edit_params.mark = &cell_edit_state->mark; @@ -5376,7 +5375,50 @@ rd_view_ui(Rng2F32 rect) line_edit_params.pre_edit_value = cell_info.string; line_edit_params.fstrs = cell_info.fstrs; line_edit_params.fuzzy_matches = &fuzzy_matches; + + // rjf: apply expander (or substitute space) + if(row_is_expandable && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_Expander; + } + else if(row_depth == !implicit_root && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + } + else if(row_depth != 0 && cell == row_info->cells.first) + { + line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + } + + // rjf: apply single-click-activation + if(is_activated_on_single_click) + { + line_edit_params.flags |= RD_CellFlag_SingleClickActivate; + } + + // rjf: apply code styles + if(is_non_code) + { + line_edit_params.flags &= ~RD_CellFlag_CodeContents; + } + + // rjf: apply button styles + if(is_button) + { + line_edit_params.flags |= RD_CellFlag_Button; + line_edit_params.flags &= ~RD_CellFlag_NoBackground; + line_edit_params.flags &= ~RD_CellFlag_ExpanderSpace; + } + + // rjf: apply toggle-switch + if(is_toggle_switch) + { + line_edit_params.flags |= RD_CellFlag_ToggleSwitch; + line_edit_params.toggled_out = &next_cell_toggled; + } } + + // rjf: build if(cell_background_color_override.w != 0) { ui_push_background_color(cell_background_color_override); @@ -5384,7 +5426,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { - sig = rd_line_editf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + sig = rd_cellf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); } if(cell_background_color_override.w != 0) { @@ -5406,7 +5448,9 @@ rd_view_ui(Rng2F32 rect) } } + //////////// //- rjf: handle interactions + // { // rjf: hover -> rich hover cfgs if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) @@ -5589,7 +5633,17 @@ rd_view_ui(Rng2F32 rect) } } + //////////// + //- rjf: commit toggle changes + // + if(next_cell_toggled != cell_toggled) + { + rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0"), 0); + } + + //////////// //- rjf: bump x pixel coordinate + // cell_x_px = next_cell_x_px; } } @@ -7155,7 +7209,7 @@ rd_window_frame(void) MD_Node *param_tree = md_child_from_string(params, key->string, 0); String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); - UI_Signal sig = rd_line_editf(RD_LineEditFlag_Border|RD_LineEditFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); + UI_Signal sig = rd_cellf(RD_CellFlag_Border|RD_CellFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); if(ui_committed(sig)) { String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); @@ -9882,7 +9936,8 @@ rd_window_frame(void) if(box->flags & UI_BoxFlag_DrawDropShadow) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); - dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + R_Rect2DInst *inst = dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); + MemoryCopyArray(inst->corner_radii, box->corner_radii); } // rjf: blur background @@ -10133,9 +10188,9 @@ rd_window_frame(void) } // rjf: debug border rendering - if(0) + if(b->flags & UI_BoxFlag_Debug) { - R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1, 0, 1, 0.25f), 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 1.f); MemoryCopyArray(inst->corner_radii, b->corner_radii); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0f7f2557..96574df5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1248,6 +1248,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } + // rjf: for meta-evaluation space booleans, only do expr + else if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Bool && + (info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || + info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + } + // rjf: for meta-cfg evaluation spaces, only do expr/value else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 796b499c..48a7e518 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3066,17 +3066,23 @@ rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String //~ rjf: UI Widgets: Line Edit internal UI_Signal -rd_line_edit(RD_LineEditParams *params, String8 string) +rd_cell(RD_CellParams *params, String8 string) { ProfBeginFunction(); + ////////////////////////////// //- rjf: unpack visual metrics + // F32 expander_size_px = ui_top_font_size()*2.f; + ////////////////////////////// //- rjf: make key + // UI_Key key = ui_key_from_string(ui_active_seed_key(), string); + ////////////////////////////// //- rjf: calculate & push focus + // B32 is_auto_focus_hot = ui_is_key_auto_focus_hot(key); B32 is_auto_focus_active = ui_is_key_auto_focus_active(key); if(is_auto_focus_hot) { ui_push_focus_hot(UI_FocusKind_On); } @@ -3086,69 +3092,137 @@ rd_line_edit(RD_LineEditParams *params, String8 string) B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); + ////////////////////////////// //- rjf: build top-level box + // if(is_focus_active || is_focus_active_disabled) { ui_set_next_hover_cursor(OS_Cursor_IBar); } - if(params->flags & RD_LineEditFlag_Button) + if(params->flags & RD_CellFlag_Button) { ui_set_next_hover_cursor(OS_Cursor_HandPoint); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| - (!!(params->flags & RD_LineEditFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| + (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| UI_BoxFlag_DrawHotEffects| - (!!(params->flags & RD_LineEditFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| - (!(params->flags & RD_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| - (!!(params->flags & RD_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| + (!!(params->flags & RD_CellFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| + (!(params->flags & RD_CellFlag_NoBackground)*UI_BoxFlag_DrawBackground)| + (!!(params->flags & RD_CellFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip), key); + ////////////////////////////// //- rjf: build indent + // UI_Parent(box) for(S32 idx = 0; idx < params->depth; idx += 1) { ui_set_next_flags(UI_BoxFlag_DrawSideLeft); ui_spacer(ui_em(1.f, 1.f)); } - //- rjf: build expander - if(params->flags & RD_LineEditFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) - UI_Flags(UI_BoxFlag_DrawSideLeft) - UI_Focus(UI_FocusKind_Off) + ////////////////////////////// + //- rjf: build expander (or placeholder, or space) + // { - UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); - if(ui_pressed(expander_sig)) + //- rjf: build expander + if(params->flags & RD_CellFlag_Expander) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Parent(box) + UI_Flags(UI_BoxFlag_DrawSideLeft) + UI_Focus(UI_FocusKind_Off) { - params->expanded_out[0] ^= 1; + UI_Signal expander_sig = ui_expanderf(params->expanded_out[0], "expander"); + if(ui_pressed(expander_sig)) + { + params->expanded_out[0] ^= 1; + } + } + + //- rjf: build expander placeholder + else if(params->flags & RD_CellFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) + { + UI_TagF("weak") + UI_Flags(UI_BoxFlag_DrawSideLeft) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); + } + + //- rjf: build expander space + else if(params->flags & RD_CellFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) + { + UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); } } - //- rjf: build expander placeholder - else if(params->flags & RD_LineEditFlag_ExpanderPlaceholder) UI_Parent(box) UI_PrefWidth(ui_px(expander_size_px, 1.f)) UI_Focus(UI_FocusKind_Off) - { - UI_TagF("weak") - UI_Flags(UI_BoxFlag_DrawSideLeft) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(rd_icon_kind_text_table[RD_IconKind_Dot]); - } - - //- rjf: build expander space - else if(params->flags & RD_LineEditFlag_ExpanderSpace) UI_Parent(box) UI_Focus(UI_FocusKind_Off) - { - UI_Flags(UI_BoxFlag_DrawSideLeft) ui_spacer(ui_px(expander_size_px, 1.f)); - } - + ////////////////////////////// //- rjf: build scrollable container box + // UI_Box *scrollable_box = &ui_nil_box; - UI_Parent(box) UI_PrefWidth(ui_children_sum(0)) + UI_Parent(box) UI_WidthFill { scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); } + ////////////////////////////// + //- rjf: build toggle-switch + // + if(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active) + UI_Parent(box) + { + B32 is_toggled = !!params->toggled_out[0]; + F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); + Vec4F32 untoggled_bg_color = {0}; + Vec4F32 toggled_bg_color = {0}; + UI_TagF("pop") + { + toggled_bg_color = ui_color_from_name(str8_lit("background")); + } + Vec4F32 bg_color = mix_4f32(untoggled_bg_color, toggled_bg_color, toggle_t); + F32 padding_px = floor_f32(ui_top_font_size()*0.4f); + F32 height_px = ui_top_px_height() - padding_px*2.f; + UI_PrefWidth(ui_children_sum(1.f)) + UI_HeightFill + UI_Column UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_PrefWidth(ui_em(4.f, 1.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + { + ui_set_next_background_color(bg_color); + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); + UI_Parent(switch_box) + { + ui_spacer(ui_pct(toggle_t, 0)); + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_PrefWidth(ui_px(toggler_size_px, 1.f)) + UI_PrefHeight(ui_px(toggler_size_px, 1.f)) + UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) + { + UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + ui_spacer(ui_pct(1.f-toggle_t, 0)); + } + UI_Signal switch_sig = ui_signal_from_box(switch_box); + if(ui_pressed(switch_sig)) + { + params->toggled_out[0] ^= 1; + } + } + } + + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) + // B32 commit = 0; if(!is_focus_active && is_focus_hot) { @@ -3166,14 +3240,18 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: get signal + // UI_Signal sig = ui_signal_from_box(box); if(commit) { sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: do start/end editing interaction + // B32 focus_started = 0; if(!is_focus_active) { @@ -3201,7 +3279,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) MemoryCopy(params->edit_buffer, edit_string.str, edit_string.size); params->edit_string_size_out[0] = edit_string.size; ui_set_auto_focus_active_key(key); - if(!(params->flags & RD_LineEditFlag_Button)) + if(!(params->flags & RD_CellFlag_Button)) { ui_kill_action(); } @@ -3216,7 +3294,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) sig.f |= UI_SignalFlag_Commit; } + ////////////////////////////// //- rjf: determine autocompletion string + // String8 autocomplete_hint_string = {0}; { for(UI_Event *evt = 0; ui_next_event(&evt);) @@ -3228,9 +3308,11 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: take navigation actions for editing + // B32 changes_made = 0; - if(!(params->flags & RD_LineEditFlag_DisableEdit) && (is_focus_active || focus_started)) + if(!(params->flags & RD_CellFlag_DisableEdit) && (is_focus_active || focus_started)) { Temp scratch = scratch_begin(0, 0); rd_state->text_edit_mode = 1; @@ -3290,12 +3372,14 @@ rd_line_edit(RD_LineEditParams *params, String8 string) scratch_end(scratch); } + ////////////////////////////// //- rjf: build scrolled contents + // TxtPt mouse_pt = {0}; F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) == 0) + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) { ui_spacer(ui_em(0.5f, 1.f)); } @@ -3308,10 +3392,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(label, params->fuzzy_matches); } } - else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_LineEditFlag_CodeContents) + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { display_string = params->pre_edit_value; UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); @@ -3320,7 +3404,7 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if(params->flags & RD_LineEditFlag_DisplayStringIsCode) + else if(params->flags & RD_CellFlag_DisplayStringIsCode) { UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); if(params->fuzzy_matches != 0) @@ -3337,10 +3421,10 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } } - else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_LineEditFlag_CodeContents)) + else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_CellFlag_CodeContents)) { String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_LineEditFlag_PreferDisplayString) && params->pre_edit_value.size != 0) + if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) { display_string = params->pre_edit_value; } @@ -3354,12 +3438,12 @@ rd_line_edit(RD_LineEditParams *params, String8 string) ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); } } - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_LineEditFlag_CodeContents) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); @@ -3437,11 +3521,11 @@ rd_line_edit(RD_LineEditParams *params, String8 string) cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; scratch_end(scratch); } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_LineEditFlag_CodeContents)) + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_LineEditFlag_Expander|RD_LineEditFlag_ExpanderSpace|RD_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; + F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); @@ -3455,7 +3539,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: click+drag + // if(is_focus_active && ui_dragging(sig)) { if(ui_pressed(sig)) @@ -3469,7 +3555,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) params->cursor[0] = params->mark[0] = mouse_pt; } + ////////////////////////////// //- rjf: focus cursor + // { F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) @@ -3491,7 +3579,9 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } } + ////////////////////////////// //- rjf: pop focus + // if(is_auto_focus_hot) { ui_pop_focus_hot(); } if(is_auto_focus_active) { ui_pop_focus_active(); } @@ -3500,14 +3590,14 @@ rd_line_edit(RD_LineEditParams *params, String8 string) } internal UI_Signal -rd_line_editf(RD_LineEditParams *params, char *fmt, ...) +rd_cellf(RD_CellParams *params, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - UI_Signal sig = rd_line_edit(params, string); + UI_Signal sig = rd_cell(params, string); scratch_end(scratch); return sig; } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index dfd3691c..66d14bf3 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -5,39 +5,64 @@ #define RADDBG_WIDGETS_H //////////////////////////////// -//~ rjf: Line Edit Types +//~ rjf: Cell Types -typedef U32 RD_LineEditFlags; +typedef U32 RD_CellFlags; enum { - RD_LineEditFlag_Expander = (1<<0), - RD_LineEditFlag_ExpanderSpace = (1<<1), - RD_LineEditFlag_ExpanderPlaceholder = (1<<2), - RD_LineEditFlag_DisableEdit = (1<<3), - RD_LineEditFlag_CodeContents = (1<<4), - RD_LineEditFlag_KeyboardClickable = (1<<5), - RD_LineEditFlag_Border = (1<<6), - RD_LineEditFlag_NoBackground = (1<<7), - RD_LineEditFlag_Button = (1<<8), - RD_LineEditFlag_SingleClickActivate = (1<<9), - RD_LineEditFlag_PreferDisplayString = (1<<10), - RD_LineEditFlag_DisplayStringIsCode = (1<<11), + //- rjf: expander + RD_CellFlag_Expander = (1<<0), + RD_CellFlag_ExpanderSpace = (1<<1), + RD_CellFlag_ExpanderPlaceholder = (1<<2), + + //- rjf: toggle switch extension + RD_CellFlag_ToggleSwitch = (1<<3), + + //- rjf: slider extension + RD_CellFlag_Slider = (1<<4), + + //- rjf: behavior + RD_CellFlag_DisableEdit = (1<<5), + RD_CellFlag_KeyboardClickable = (1<<6), + RD_CellFlag_SingleClickActivate = (1<<7), + + //- rjf: contents description + RD_CellFlag_CodeContents = (1<<8), + + //- rjf: appearance + RD_CellFlag_Border = (1<<9), + RD_CellFlag_NoBackground = (1<<10), + RD_CellFlag_Button = (1<<11), + RD_CellFlag_PreferDisplayString = (1<<12), + RD_CellFlag_DisplayStringIsCode = (1<<13), }; -typedef struct RD_LineEditParams RD_LineEditParams; -struct RD_LineEditParams +typedef struct RD_CellParams RD_CellParams; +struct RD_CellParams { - RD_LineEditFlags flags; + //- rjf: catachall parameters + RD_CellFlags flags; S32 depth; FuzzyMatchRangeList *fuzzy_matches; + String8 pre_edit_value; + DR_FStrList fstrs; + + //- rjf: expander r/w info + B32 *expanded_out; + + //- rjf: toggle-switch r/w info + B32 *toggled_out; + + //- rjf: slider info r/w info + Rng1U64 slider_value_range; + U64 *slider_value_out; + + //- rjf: text editing r/w info TxtPt *cursor; TxtPt *mark; U8 *edit_buffer; U64 edit_buffer_size; U64 *edit_string_size_out; - B32 *expanded_out; - String8 pre_edit_value; - DR_FStrList fstrs; }; //////////////////////////////// @@ -140,7 +165,7 @@ internal UI_Box *rd_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 b //////////////////////////////// //~ rjf: UI Widgets: Line Edit -internal UI_Signal rd_line_edit(RD_LineEditParams *params, String8 string); -internal UI_Signal rd_line_editf(RD_LineEditParams *params, char *fmt, ...); +internal UI_Signal rd_cell(RD_CellParams *params, String8 string); +internal UI_Signal rd_cellf(RD_CellParams *params, char *fmt, ...); #endif // RADDBG_WIDGETS_H diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 5968c4fc..579c8051 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -352,6 +352,9 @@ typedef U64 UI_BoxFlags; # define UI_BoxFlag_RoundChildrenByParent (UI_BoxFlags)(1ull<<51) # define UI_BoxFlag_SquishAnchored (UI_BoxFlags)(1ull<<52) +//- rjf: debug +# define UI_BoxFlag_Debug (UI_BoxFlags)(1ull<<53) + //- rjf: bundles # define UI_BoxFlag_Clickable (UI_BoxFlag_MouseClickable|UI_BoxFlag_KeyboardClickable) # define UI_BoxFlag_DefaultFocusNav (UI_BoxFlag_DefaultFocusNavX|UI_BoxFlag_DefaultFocusNavY|UI_BoxFlag_DefaultFocusEdit) From 2d7a8740bf044ce41473a290d74649baf84c101b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 24 Mar 2025 15:04:54 -0700 Subject: [PATCH 237/755] adjust toggle switch rules --- src/raddbg/raddbg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index deca3596..892184c3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5324,7 +5324,7 @@ rd_view_ui(Rng2F32 rect) { // rjf: compute visual params B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); - B32 is_toggle_switch = (cell_info.eval.irtree.mode == E_Mode_Offset && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); + B32 is_toggle_switch = (cell_info.eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; From 87e4b8b3f8c7dc117885a23f759f54be268ec99e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 24 Mar 2025 15:48:44 -0700 Subject: [PATCH 238/755] adjust toggle_switch --- src/raddbg/raddbg_widgets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 48a7e518..0bab14a7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3175,7 +3175,7 @@ rd_cell(RD_CellParams *params, String8 string) F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); Vec4F32 untoggled_bg_color = {0}; Vec4F32 toggled_bg_color = {0}; - UI_TagF("pop") + UI_TagF("good_pop") { toggled_bg_color = ui_color_from_name(str8_lit("background")); } From ef1685adc927844f1db0ca87c7ee5b3c03206c20 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 13:49:59 -0700 Subject: [PATCH 239/755] pass over cfg meta evaluations; instead of forming artificial 'eval blob', just use sets/queries/hooks to do the lookups. eliminate cfg -> eval blob cache. switch to 'enabled' rather than 'disabled' as the cfg default. more convergences/fixes/tweaks. --- src/eval/eval_ir.c | 38 ++- src/eval/eval_parse.c | 2 +- src/eval/eval_types.c | 22 +- src/eval/eval_types.h | 2 +- src/raddbg/generated/raddbg.meta.c | 13 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 12 +- src/raddbg/raddbg_core.c | 523 ++++++++++++++++++----------- src/raddbg/raddbg_core.h | 32 +- src/raddbg/raddbg_views.c | 25 +- src/raddbg/raddbg_views.h | 9 +- src/raddbg/raddbg_widgets.c | 23 +- 12 files changed, 419 insertions(+), 284 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 3113346f..a20e36e9 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -322,7 +322,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(file) E_Space space = e_space_make(E_SpaceKind_File); space.u64_0 = e_id_from_string(accel->file_path); result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size); + result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size, 0); result.irtree_and_type.mode = E_Mode_Offset; } } @@ -2102,7 +2102,6 @@ E_IRGEN_FUNCTION_DEF(default) result = e_irtree_and_type_from_expr(arena, expr->first); }break; case E_ExprKind_Neg: - case E_ExprKind_LogNot: case E_ExprKind_BitNot: { // rjf: unpack operand @@ -2136,6 +2135,39 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = E_Mode_Value; } }break; + case E_ExprKind_LogNot: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); + E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); + RDI_EvalOp op = e_opcode_from_expr_kind(kind); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + break; + } + + // rjf: generate + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); + E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); + result.root = new_tree; + result.type_key = r_type_promoted; + result.mode = E_Mode_Value; + } + }break; //- rjf: binary operations case E_ExprKind_Mul: @@ -2449,7 +2481,7 @@ E_IRGEN_FUNCTION_DEF(default) case E_ExprKind_LeafStringLiteral: { String8 string = expr->string; - E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size); + E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size, 0); E_IRNode *new_tree = e_irtree_string_literal(arena, string); result.root = new_tree; result.type_key = type_key; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index e318b97e..9ab30a5c 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1034,7 +1034,7 @@ e_type_from_expr(E_Expr *expr) { E_Expr *child_expr = expr->first; E_TypeKey direct_type_key = e_type_from_expr(child_expr); - result = e_type_key_cons_array(direct_type_key, expr->value.u64); + result = e_type_key_cons_array(direct_type_key, expr->value.u64, 0); }break; } return result; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ef07ee7f..25527892 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -450,9 +450,9 @@ e_type_key_cons_(E_ConsTypeParams *params) //- rjf: constructed type helpers internal E_TypeKey -e_type_key_cons_array(E_TypeKey element_type_key, U64 count) +e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags) { - E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Array, .direct_key = element_type_key, .count = count); + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Array, .direct_key = element_type_key, .count = count, .flags = flags); return key; } @@ -488,7 +488,7 @@ e_type_key_cons_base(Type *type) case TypeKind_Array: { E_TypeKey direct_type = e_type_key_cons_base(type->direct); - result = e_type_key_cons_array(direct_type, type->count); + result = e_type_key_cons_array(direct_type, type->count, 0); }break; case TypeKind_Struct: { @@ -1065,7 +1065,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u128s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U128), reg_byte_count/16); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U128), reg_byte_count/16, 0); } if(type->byte_size > 8 && type->byte_size%8 == 0) { @@ -1075,7 +1075,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u64s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U64), reg_byte_count/8); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U64), reg_byte_count/8, 0); } if(type->byte_size > 4 && type->byte_size%4 == 0) { @@ -1085,7 +1085,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u32s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U32), reg_byte_count/4); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U32), reg_byte_count/4, 0); } if(type->byte_size > 2 && type->byte_size%2 == 0) { @@ -1095,7 +1095,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u16s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U16), reg_byte_count/2); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U16), reg_byte_count/2, 0); } if(type->byte_size > 1) { @@ -1105,7 +1105,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u8s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count, 0); } if(type->byte_size > 4 && type->byte_size%4 == 0) { @@ -1115,7 +1115,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("f32s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F32), reg_byte_count/4); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F32), reg_byte_count/4, 0); } if(type->byte_size > 8 && type->byte_size%8 == 0) { @@ -1125,7 +1125,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("f64s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F64), reg_byte_count/8); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F64), reg_byte_count/8, 0); } } } @@ -1573,7 +1573,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_Member *padding_member = &new_members.v[n->prev_member_idx+padding_idx+1]; MemoryZeroStruct(padding_member); padding_member->kind = E_MemberKind_Padding; - padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size); + padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, 0); padding_member->off = n->off; padding_member->name = push_str8f(arena, "[padding %I64u]", padding_idx); padding_idx += 1; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 2ca62b9f..38c5c7aa 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -359,7 +359,7 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); #define e_type_key_cons(...) e_type_key_cons_(&(E_ConsTypeParams){.kind = E_TypeKind_Null, __VA_ARGS__}) //- rjf: constructed type construction helpers -internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); +internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_base(Type *type); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d4426e1e..8e601e02 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[307] = +RD_VocabInfo rd_vocab_info_table[308] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -76,6 +76,7 @@ RD_VocabInfo rd_vocab_info_table[307] = {str8_lit_comp("local"), str8_lit_comp("locals"), str8_lit_comp("Local"), str8_lit_comp("Locals"), RD_IconKind_Null}, {str8_lit_comp("memory"), str8_lit_comp("memories"), str8_lit_comp("Memory"), str8_lit_comp("Memories"), RD_IconKind_Grid}, {str8_lit_comp("hit_count"), str8_lit_comp("hit_counts"), str8_lit_comp("Hit Count"), str8_lit_comp("Hit Counts"), RD_IconKind_Null}, +{str8_lit_comp("enabled"), str8_lit_comp(""), str8_lit_comp("Enabled"), str8_lit_comp("Enabled"), RD_IconKind_Null}, {str8_lit_comp("disabled"), str8_lit_comp(""), str8_lit_comp("Disabled"), str8_lit_comp("Disabled"), RD_IconKind_Null}, {str8_lit_comp("debug_subprocesses"), str8_lit_comp(""), str8_lit_comp("Debug Subprocesses"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("environment"), str8_lit_comp("environments"), str8_lit_comp("Environment"), str8_lit_comp("Environments"), RD_IconKind_Null}, @@ -322,17 +323,17 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'disabled': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, -{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, -{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'modules':query, 'threads':query}")}, {str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, -{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'call_stack':query}")}, }; Rng1U64 rd_reg_slot_range_table[41] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 384ccb7b..6beea5d2 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -642,7 +642,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[307]; +extern RD_VocabInfo rd_vocab_info_table[308]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8346f2db..d1435b65 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -89,6 +89,7 @@ RD_VocabTable: {local _ "Local" _ Null } {memory memories "Memory" "Memories" Grid } {hit_count hit_counts "Hit Count" "Hit Counts" Null } + {enabled "" "Enabled" "Enabled" Null } {disabled "" "Disabled" "Disabled" Null } {debug_subprocesses "" "Debug Subprocesses" "" Null } {environment _ "Environment" _ Null } @@ -216,7 +217,7 @@ RD_VocabTable: { target, ``` - @commands(launch_and_run, launch_and_step_into, enable_cfg, remove_cfg) + @commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) @collection_commands(add_target) x: { @@ -230,6 +231,7 @@ RD_VocabTable: 'stdin_path': path, 'environment': query, 'debug_subprocesses': bool, + @no_expand @default(0) 'enabled': bool, } ```, } @@ -247,7 +249,7 @@ RD_VocabTable: 'source_location': path_pt, 'address_location': code_string, 'hit_count': u64, - 'disabled': bool, + @no_expand @default(1) 'enabled': bool, } ```, } @@ -295,11 +297,11 @@ RD_VocabTable: //- rjf: control entities { machine, - ```x:{'label':code_string, 'frozen':bool, 'unattached_processes':query, 'processes':query}```, + ```x:{'label':code_string, @no_expand 'frozen':bool, 'unattached_processes':query, 'processes':query}```, } { process, - ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'modules':query, 'threads':query}```, + ```x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'modules':query, 'threads':query}```, } { module, @@ -307,7 +309,7 @@ RD_VocabTable: } { thread, - ```x:{'label':code_string, 'id':u64, 'frozen':bool, 'call_stack':query}```, + ```x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'call_stack':query}```, } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 892184c3..07dd7348 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -283,10 +283,162 @@ E_LOOKUP_RANGE_FUNCTION_DEF(registers) } //////////////////////////////// -//~ rjf: Config Eval Hooks +//~ rjf: Schema'd Set Eval Hooks -typedef struct RD_CfgLookupAccel RD_CfgLookupAccel; -struct RD_CfgLookupAccel +typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; +struct RD_SchemaLookupAccel +{ + RD_Cfg *cfg; + MD_Node *schema; + MD_Node **children; + U64 children_count; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(schema) +{ + E_LookupInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: unpack + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + RD_Cfg *cfg = rd_cfg_from_eval_space(interpret.space); + E_TypeKey type_key = lhs->type_key; + E_Type *type = e_type_from_key__cached(type_key); + MD_Node *schema = rd_schema_from_name(type->name); + + // rjf: gather expansion children + typedef struct ExpandChildNode ExpandChildNode; + struct ExpandChildNode + { + ExpandChildNode *next; + MD_Node *n; + }; + ExpandChildNode *first_child_node = 0; + ExpandChildNode *last_child_node = 0; + U64 child_count = 0; + for MD_EachNode(child, schema->first) + { + if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } + } + + // rjf: flatten expansion member list + MD_Node **children = push_array(arena, MD_Node *, child_count); + { + U64 idx = 0; + for(ExpandChildNode *n = first_child_node; n != 0; n = n->next, idx += 1) + { + children[idx] = n->n; + } + } + + // rjf: build accelerator for lookups + RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); + accel->cfg = cfg; + accel->schema = schema; + accel->children = children; + accel->children_count = child_count; + + // rjf: fill result + result.user_data = accel; + result.named_expr_count = child_count; + + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(schema) +{ + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + E_IRTreeAndType irtree = {&e_irnode_nil}; + if(kind == E_ExprKind_MemberAccess) + { + MD_Node *child_schema = &md_nil_node; + for MD_EachNode(child, accel->schema->first) + { + if(str8_match(child->string, rhs->string, 0)) + { + child_schema = child; + break; + } + } + if(child_schema != &md_nil_node) + { + RD_Cfg *cfg = accel->cfg; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); + E_TypeKey child_type_key = zero_struct; + if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); + } + else if(str8_match(child_schema->first->string, str8_lit("path"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); + } + else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + String8 string = push_str8f(scratch.arena, "%S:%S%s%S", child->first->string, child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); + scratch_end(scratch); + } + else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); + } + else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_U64); + } + else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_Bool); + } + else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); + } + E_Space child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); + child_eval_space.u64s[0] = cfg->id; + child_eval_space.u64s[1] = e_id_from_string(child_schema->string); + irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); + irtree.type_key = child_type_key; + irtree.mode = E_Mode_Offset; + } + } + E_LookupAccess access = {irtree}; + return access; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(schema) +{ + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + if(0 <= idx && idx < accel->children_count) + { + MD_Node *child_schema = accel->children[idx]; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, child_schema->string); + } + } +} + +//////////////////////////////// +//~ rjf: Config Collection Eval Hooks + +typedef struct RD_CfgCollectionLookupAccel RD_CfgCollectionLookupAccel; +struct RD_CfgCollectionLookupAccel { String8Array cmds; RD_CfgArray cfgs; @@ -294,7 +446,7 @@ struct RD_CfgLookupAccel Rng1U64 cfgs_idx_range; }; -E_LOOKUP_INFO_FUNCTION_DEF(cfg) +E_LOOKUP_INFO_FUNCTION_DEF(cfgs) { E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); @@ -342,7 +494,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfg) String8List cmds_list = {0}; if(filter.size == 0) { - MD_Node *schema = rd_schema_from_name(scratch.arena, cfg_name); + MD_Node *schema = rd_schema_from_name(cfg_name); MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); for MD_EachNode(cmd, collection_cmds_root->first) { @@ -351,7 +503,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfg) } //- rjf: package & fill - RD_CfgLookupAccel *accel = push_array(arena, RD_CfgLookupAccel, 1); + RD_CfgCollectionLookupAccel *accel = push_array(arena, RD_CfgCollectionLookupAccel, 1); accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); accel->cmds = str8_array_from_list(arena, &cmds_list); accel->cmds_idx_range = r1u64(0, accel->cmds.count); @@ -363,7 +515,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfg) return result; } -E_LOOKUP_ACCESS_FUNCTION_DEF(cfg) +E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs) { Temp scratch = scratch_begin(&arena, 1); E_LookupAccess result = {{&e_irnode_nil}}; @@ -386,7 +538,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(cfg) E_Interpretation rhs_interp = e_interpret(rhs_bytecode); E_Value rhs_value = rhs_interp.value; U64 rhs_idx = rhs_value.u64; - RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) { cfg = accel->cfgs.v[rhs_idx]; @@ -405,9 +557,9 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(cfg) return result; } -E_LOOKUP_RANGE_FUNCTION_DEF(cfg) +E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) { - RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; Rng1U64 cmds_idx_range = accel->cmds_idx_range; Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; U64 dst_idx = 0; @@ -438,10 +590,10 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfg) } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfg) +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) { U64 id = 0; - RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; if(num != 0) { U64 idx = num-1; @@ -459,10 +611,10 @@ E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfg) return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfg) +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) { U64 num = 0; - RD_CfgLookupAccel *accel = (RD_CfgLookupAccel *)user_data; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; if(id != 0) { if(id & (1ull<<63)) @@ -2136,8 +2288,20 @@ rd_color_from_cfg(RD_Cfg *cfg) internal B32 rd_disabled_from_cfg(RD_Cfg *cfg) { - String8 disabled_value_string = rd_cfg_child_from_string(cfg, str8_lit("disabled"))->first->string; - B32 is_disabled = (disabled_value_string.size != 0 && !str8_match(disabled_value_string, str8_lit("0"), 0)); + MD_Node *schema = rd_schema_from_name(cfg->string); + MD_Node *enabled_schema = md_child_from_string(schema, str8_lit("enabled"), 0); + MD_Node *default_tag = md_tag_from_string(enabled_schema, str8_lit("default"), 0); + String8 value_string = rd_cfg_child_from_string(cfg, str8_lit("enabled"))->first->string; + if(value_string.size == 0) + { + value_string = default_tag->first->string; + } + B32 is_enabled = (str8_match(value_string, str8_lit("1"), 0)); + B32 is_disabled = !is_enabled; + if(value_string.size == 0) + { + is_disabled = 0; + } return is_disabled; } @@ -2220,7 +2384,7 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) } internal MD_Node * -rd_schema_from_name(Arena *arena, String8 name) +rd_schema_from_name(String8 name) { MD_Node *schema = &md_nil_node; for EachElement(idx, rd_name_schema_info_table) @@ -2274,7 +2438,7 @@ rd_setting_from_name(String8 name) }; for EachElement(idx, schema_names) { - MD_Node *schema = rd_schema_from_name(scratch.arena, schema_names[idx]); + MD_Node *schema = rd_schema_from_name(schema_names[idx]); MD_Node *setting = md_child_from_string(schema, name, 0); MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); if(default_tag != &md_nil_node) @@ -2570,119 +2734,6 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) return space; } -//- rjf: cfg -> eval blob - -internal String8 -rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg) -{ - String8 result = {0}; - String8 name = cfg->string; - 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)) - { - String8List parts = {0}; - U64 offset = 8; - String8Node offset_node = {0, str8_struct(&offset)}; - String8Node string_node = {0, cfg->first->string}; - str8_list_push_node(&parts, &offset_node); - str8_list_push_node(&parts, &string_node); - result = str8_list_join(arena, &parts, 0); - } - else - { - 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__cached(type_key); - if(type->members != 0) for EachIndex(member_idx, type->count) - { - E_Member *member = &type->members[member_idx]; - String8 child_name = member->name; - MD_Node *member_schema = md_child_from_string(schema, child_name, 0); - MD_Node *default_root = md_tag_from_string(member_schema, str8_lit("default"), 0); - String8 member_type_name = member_schema->first->string; - RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); - String8 child_value = child->first->string; - if(child_value.size == 0) - { - child_value = default_root->first->string; - } - if(str8_match(member_type_name, str8_lit("path_pt"), 0)) - { - 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))); - for(RD_Cfg *loc_child = child->first; loc_child != &rd_nil_cfg; loc_child = loc_child->first) - { - if(loc_child != child->first) - { - str8_list_push(scratch.arena, &variable_width_parts, str8_lit(":")); - } - str8_list_push(scratch.arena, &variable_width_parts, loc_child->string); - } - str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); - } - else if(str8_match(member_type_name, str8_lit("code_string"), 0) || - str8_match(member_type_name, str8_lit("path"), 0) || - str8_match(member_type_name, str8_lit("string"), 0)) - { - 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, child_value); - str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); - } - else if(str8_match(member_type_name, str8_lit("u64"), 0)) - { - U64 val = 0; - try_u64_from_str8_c_rules(child_value, &val); - str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&val))); - } - else if(str8_match(member_type_name, str8_lit("bool"), 0)) - { - B32 val = str8_match(child_value, str8_lit("1"), 0); - str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8((U8 *)&val, e_type_byte_size_from_key(member->type_key)))); - } - } - } - 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_cfg__cached(RD_Cfg *cfg) -{ - String8 result = {0}; - { - RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; - RD_CfgID id = cfg->id; - U64 hash = d_hash_from_string(str8_struct(&id)); - U64 slot_idx = hash%map->slots_count; - RD_Cfg2EvalBlobNode *node = 0; - for(RD_Cfg2EvalBlobNode *n = map->slots[slot_idx].first; n != 0; n = n->next) - { - if(n->id == id) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(rd_frame_arena(), RD_Cfg2EvalBlobNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, node); - node->id = id; - node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); - } - result = node->blob; - } - return result; -} - //- rjf: ctrl entity -> eval blob internal String8 @@ -2694,7 +2745,7 @@ rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity) 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); + MD_Node *schema = rd_schema_from_name(name); String8List fixed_width_parts = {0}; String8List variable_width_parts = {0}; { @@ -2884,14 +2935,62 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: meta-config reads case RD_EvalSpaceKind_MetaCfg: { - RD_Cfg *cfg = rd_cfg_from_eval_space(space); - String8 cfg_eval_blob = rd_eval_blob_from_cfg__cached(cfg); - Rng1U64 legal_range = r1u64(0, cfg_eval_blob.size); + // rjf: unpack cfg + RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); + String8 child_key = e_string_from_id(space.u64s[1]); + RD_Cfg *cfg = root_cfg; + if(child_key.size != 0) + { + cfg = rd_cfg_child_from_string(root_cfg, child_key); + } + + // rjf: determine data to read from, depending on child type in schema + String8 read_data = {0}; + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(root_cfg->string); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + String8 child_type_name = child_schema->first->string; + if(str8_match(child_type_name, str8_lit("path_pt"), 0)) + { + read_data = push_str8f(scratch.arena, "%S:%S%s%S", cfg->first->string, cfg->first->first->string, cfg->first->first->first->string.size ? ":" : "", cfg->first->first->first->string); + } + else if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("string"), 0)) + { + read_data = cfg->first->string; + } + else if(str8_match(child_type_name, str8_lit("bool"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + B32 value = str8_match(value_string, str8_lit("1"), 0); + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("u64"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + U64 value = 0; + try_u64_from_str8_c_rules(value_string, &value); + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + } + + // rjf: perform read + Rng1U64 legal_range = r1u64(0, read_data.size); Rng1U64 read_range = intersect_1u64(range, legal_range); if(read_range.min < read_range.max) { result = 1; - MemoryCopy(out, cfg_eval_blob.str + read_range.min, dim_1u64(read_range)); + MemoryCopy(out, read_data.str + read_range.min, dim_1u64(read_range)); } }break; @@ -2953,15 +3052,70 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); - // rjf: unpack - RD_Cfg *cfg = rd_cfg_from_eval_space(space); - String8 eval_blob = rd_eval_blob_from_cfg__cached(cfg); - MD_Node *schema = rd_schema_from_name(scratch.arena, cfg->string); - String8 name = cfg->string; - E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - E_Type *type = e_type_from_key__cached(type_key); + // rjf: unpack write info + String8 write_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); + + // rjf: unpack cfg + RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); + String8 child_key = e_string_from_id(space.u64s[1]); + RD_Cfg *cfg = root_cfg; + if(child_key.size != 0) + { + cfg = rd_cfg_child_from_string(root_cfg, child_key); + } + + // rjf: perform write, based on child type in schema + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(root_cfg->string); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + String8 child_type_name = child_schema->first->string; + if(str8_match(child_type_name, str8_lit("path_pt"), 0)) + { + result = 0; + } + else if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("string"), 0)) + { + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replace(child, write_string); + result = 1; + } + else if(str8_match(child_type_name, str8_lit("bool"), 0)) + { + if(range.max == range.min) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + else + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replacef(child, "%I64u", !!value); + } + result = 1; + } + else if(str8_match(child_type_name, str8_lit("u64"), 0)) + { + if(range.max == range.min) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + else + { + U64 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replacef(child, "%I64u", value); + } + result = 1; + } + } // rjf: find member to which this write applies, reflect back in the cfg tree +#if 0 if(type->members != 0) for EachIndex(member_idx, type->count) { E_Member *member = &type->members[member_idx]; @@ -3029,39 +3183,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) break; } } - - // rjf: if no members? -> treat this as a commit to the cfg's children - if(type->members == 0) - { - String8 new_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); - rd_cfg_new_replace(cfg, new_string); - result = 1; - } - - // rjf: commit to the eval blob cache - { - RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; - RD_CfgID id = cfg->id; - U64 hash = d_hash_from_string(str8_struct(&id)); - 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) - { - if(n->id == id) - { - node = n; - break; - } - } - - // rjf: if node -> commit - if(node) - { - node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); - } - } +#endif scratch_end(scratch); }break; @@ -3264,7 +3386,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } } - if(commit_data.size != 0 && e_type_byte_size_from_key(type_key) != 0) + if(commit_data.size != 0 && !e_type_key_match(e_type_key_zero(), type_key)) { U64 dst_offset = dst_eval.value.u64; if(dst_eval.irtree.mode == E_Mode_Offset && commit_at_ptr_dest) @@ -5324,6 +5446,7 @@ rd_view_ui(Rng2F32 rect) { // rjf: compute visual params B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); B32 is_toggle_switch = (cell_info.eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); @@ -5410,6 +5533,12 @@ rd_view_ui(Rng2F32 rect) line_edit_params.flags &= ~RD_CellFlag_ExpanderSpace; } + // rjf: apply background + if(has_background) + { + line_edit_params.flags &= ~RD_CellFlag_NoBackground; + } + // rjf: apply toggle-switch if(is_toggle_switch) { @@ -12684,9 +12813,6 @@ rd_frame(void) } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; - 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); @@ -13487,7 +13613,7 @@ rd_frame(void) for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; - MD_Node *schema = rd_schema_from_name(scratch.arena, name); + MD_Node *schema = rd_schema_from_name(name); E_MemberList members_list = {0}; U64 off = 0; for MD_EachNode(child, schema->first) @@ -13519,7 +13645,7 @@ rd_frame(void) } E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); evallable_meta_types[idx] = e_type_key_cons(.name = name, - .kind = E_TypeKind_Struct, + .kind = E_TypeKind_Set, .members = members.v, .count = members.count); } @@ -13532,6 +13658,10 @@ rd_frame(void) String8 name = rd_name_schema_info_table[idx].name; E_TypeKey type_key = evallable_meta_types[idx]; e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); + e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, + .info = E_LOOKUP_INFO_FUNCTION_NAME(schema), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(schema), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(schema)); } //- rjf: add macros for evallable top-level config trees @@ -13738,11 +13868,11 @@ rd_frame(void) expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(cfg), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(cfg), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(cfg), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(cfg), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(cfg)); + .info = E_LOOKUP_INFO_FUNCTION_NAME(cfgs), + .access = E_LOOKUP_ACCESS_FUNCTION_NAME(cfgs), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(cfgs), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(cfgs), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(cfgs)); } //- rjf: add macros for all ctrl entity collections @@ -13799,7 +13929,7 @@ rd_frame(void) space.u128 = key; expr->space = space; expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size); + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output"), expr); hs_scope_close(hs_scope); } @@ -16216,20 +16346,18 @@ Z(getting_started) for(RD_CfgNode *n = all_of_the_same_kind.first; n != 0; n = n->next) { RD_Cfg *c = n->v; - RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(c, str8_lit("disabled")); - rd_cfg_new_replace(disabled, str8_lit("1")); - } - if(!is_selected) - { - rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("disabled"))); + rd_cfg_release(rd_cfg_child_from_string(c, str8_lit("enabled"))); } + RD_Cfg *enabled_root = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("enabled")); + rd_cfg_new_replace(enabled_root, str8_lit("1")); }break; case RD_CmdKind_EnableCfg: case RD_CmdKind_EnableBreakpoint: case RD_CmdKind_EnableTarget: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); - rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("disabled"))); + RD_Cfg *enabled_root = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("enabled")); + rd_cfg_new_replacef(enabled_root, "1"); }break; case RD_CmdKind_DisableCfg: case RD_CmdKind_DisableBreakpoint: @@ -16237,8 +16365,7 @@ Z(getting_started) case RD_CmdKind_DeselectCfg: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); - RD_Cfg *disabled = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("disabled")); - rd_cfg_new_replace(disabled, str8_lit("1")); + rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("enabled"))); }break; case RD_CmdKind_RemoveCfg: { @@ -16495,8 +16622,6 @@ Z(getting_started) String8 file_path = rd_regs()->file_path; RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *target = rd_cfg_new(project, str8_lit("target")); - RD_Cfg *disabled = rd_cfg_new(target, str8_lit("disabled")); - rd_cfg_new(disabled, str8_lit("1")); RD_Cfg *exe = rd_cfg_new(target, str8_lit("executable")); rd_cfg_new(exe, file_path); String8 working_directory = str8_chop_last_slash(file_path); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index a00facae..22c75874 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -582,31 +582,6 @@ struct RD_WindowStateSlot RD_WindowState *last; }; -//////////////////////////////// -//~ rjf: Config -> Eval Blob Cache Types - -typedef struct RD_Cfg2EvalBlobNode RD_Cfg2EvalBlobNode; -struct RD_Cfg2EvalBlobNode -{ - RD_Cfg2EvalBlobNode *next; - RD_CfgID id; - String8 blob; -}; - -typedef struct RD_Cfg2EvalBlobSlot RD_Cfg2EvalBlobSlot; -struct RD_Cfg2EvalBlobSlot -{ - RD_Cfg2EvalBlobNode *first; - RD_Cfg2EvalBlobNode *last; -}; - -typedef struct RD_Cfg2EvalBlobMap RD_Cfg2EvalBlobMap; -struct RD_Cfg2EvalBlobMap -{ - U64 slots_count; - RD_Cfg2EvalBlobSlot *slots; -}; - //////////////////////////////// //~ rjf: Control Entity -> Eval Blob Cache Types @@ -721,7 +696,6 @@ struct RD_State E_String2TypeKeyMap *meta_name2type_map; // rjf: eval blob caches (lazily constructed from-scratch each frame) - RD_Cfg2EvalBlobMap *cfg2evalblob_map; RD_Entity2EvalBlobMap *entity2evalblob_map; // rjf: name -> view ui map (constructed from-scratch each frame) @@ -949,7 +923,7 @@ internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); internal String8 rd_path_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); -internal MD_Node *rd_schema_from_name(Arena *arena, String8 name); +internal MD_Node *rd_schema_from_name(String8 name); internal String8 rd_setting_from_name(String8 name); #define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) @@ -980,10 +954,6 @@ internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); 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); -//- rjf: cfg -> eval blob -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); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 96574df5..a05a836c 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1135,7 +1135,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { RD_Cfg *cfg = evalled_cfg; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); - MD_Node *schema = rd_schema_from_name(arena, cfg->string); + MD_Node *schema = rd_schema_from_name(cfg->string); MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); for MD_EachNode(cmd, cmds_root->first) { @@ -1177,7 +1177,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } }break; } - if(cmd_kind != RD_CmdKind_Null) + if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).enabled")); + } + else if(cmd_kind != RD_CmdKind_Null) { String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); @@ -1194,13 +1200,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) { - RD_CmdKind cmd_kind = RD_CmdKind_FreezeEntity; - if(ctrl_entity_tree_is_frozen(entity)) - { - cmd_kind = RD_CmdKind_ThawEntity; - } - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).frozen")); } if(entity->kind == CTRL_EntityKind_Thread) { @@ -1263,6 +1265,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || info.eval.space.kind == E_SpaceKind_File) { + if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Array && + e_type_kind_from_key(e_type_direct_from_key(info.eval.irtree.type_key)) == E_TypeKind_U8) + { + info.can_expand = 0; + } info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 9e1b131d..c67e9ba3 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -55,10 +55,11 @@ typedef U32 RD_WatchCellFlags; enum { RD_WatchCellFlag_Button = (1<<0), - RD_WatchCellFlag_ActivateWithSingleClick = (1<<1), - RD_WatchCellFlag_IsNonCode = (1<<2), - RD_WatchCellFlag_CanEdit = (1<<3), - RD_WatchCellFlag_IsErrored = (1<<4), + RD_WatchCellFlag_Background = (1<<1), + RD_WatchCellFlag_ActivateWithSingleClick = (1<<2), + RD_WatchCellFlag_IsNonCode = (1<<3), + RD_WatchCellFlag_CanEdit = (1<<4), + RD_WatchCellFlag_IsErrored = (1<<5), }; typedef struct RD_WatchCell RD_WatchCell; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0bab14a7..3537a855 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3106,7 +3106,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| - UI_BoxFlag_DrawHotEffects| + (!!(params->flags & RD_CellFlag_Button)*UI_BoxFlag_DrawHotEffects)| (!!(params->flags & RD_CellFlag_SingleClickActivate)*UI_BoxFlag_DrawActiveEffects)| (!(params->flags & RD_CellFlag_NoBackground)*UI_BoxFlag_DrawBackground)| (!!(params->flags & RD_CellFlag_Border)*UI_BoxFlag_DrawBorder)| @@ -3173,29 +3173,26 @@ rd_cell(RD_CellParams *params, String8 string) { B32 is_toggled = !!params->toggled_out[0]; F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); - Vec4F32 untoggled_bg_color = {0}; - Vec4F32 toggled_bg_color = {0}; - UI_TagF("good_pop") - { - toggled_bg_color = ui_color_from_name(str8_lit("background")); - } - Vec4F32 bg_color = mix_4f32(untoggled_bg_color, toggled_bg_color, toggle_t); - F32 padding_px = floor_f32(ui_top_font_size()*0.4f); + F32 padding_px = floor_f32(ui_top_font_size()*0.65f); F32 height_px = ui_top_px_height() - padding_px*2.f; UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) UI_Row UI_Padding(ui_px(padding_px, 1.f)) - UI_PrefWidth(ui_em(4.f, 1.f)) + UI_PrefWidth(ui_em(3.5f, 1.f)) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + UI_TagF(is_toggled ? "good_pop" : "") { - ui_set_next_background_color(bg_color); ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); + UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); UI_Parent(switch_box) { - ui_spacer(ui_pct(toggle_t, 0)); + RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_pct(toggle_t, 0)) UI_Transparency(1.f - toggle_t) + { + ui_build_box_from_stringf(UI_BoxFlag_DisableTextTrunc | (toggle_t > 0.001f ? UI_BoxFlag_DrawText : 0), + "%S", rd_icon_kind_text_table[RD_IconKind_Check]); + } UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) UI_PrefWidth(ui_px(height_px, 1.f)) { From 974ce5fa596ad73583758a7f9ddb6447b9ed085b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 14:13:59 -0700 Subject: [PATCH 240/755] eliminate rule to associate set names with expand rules / visualizers; this is really only a rule we want for the core eval lookup hooks --- .../eval_visualization_core.c | 16 ------------- src/raddbg/generated/raddbg.meta.c | 3 ++- src/raddbg/generated/raddbg.meta.h | 5 +++- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 24 ++++++++++++------- src/raddbg/raddbg_main.c | 3 +++ 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 657660b6..7383b24d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1593,22 +1593,6 @@ ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } } - // rjf: next try implicit set name -> rule mapping - if(result.rule == &ev_nil_expand_rule) - { - E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); - if(type_kind == E_TypeKind_Set) - { - E_Type *type = e_type_from_key__cached(irtree->type_key); - String8 name = type->name; - EV_ExpandRule *candidate = ev_expand_rule_from_string(name); - if(candidate != &ev_nil_expand_rule) - { - result.rule = candidate; - } - } - } - // rjf: next try auto hook map if(result.rule == &ev_nil_expand_rule) { diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8e601e02..6e036066 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -336,7 +336,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[41] = +Rng1U64 rd_reg_slot_range_table[42] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -374,6 +374,7 @@ Rng1U64 rd_reg_slot_range_table[41] = {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, {OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, +{OffsetOf(RD_Regs, do_implicit_root), OffsetOf(RD_Regs, do_implicit_root) + sizeof(B32)}, {OffsetOf(RD_Regs, dir2), OffsetOf(RD_Regs, dir2) + sizeof(Dir2)}, {OffsetOf(RD_Regs, string), OffsetOf(RD_Regs, string) + sizeof(String8)}, {OffsetOf(RD_Regs, cmd_name), OffsetOf(RD_Regs, cmd_name) + sizeof(String8)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6beea5d2..079f6938 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -44,6 +44,7 @@ RD_RegSlot_PID, RD_RegSlot_ForceConfirm, RD_RegSlot_PreferDisasm, RD_RegSlot_NoRichTooltip, +RD_RegSlot_DoImplicitRoot, RD_RegSlot_Dir2, RD_RegSlot_String, RD_RegSlot_CmdName, @@ -571,6 +572,7 @@ U32 pid; B32 force_confirm; B32 prefer_disasm; B32 no_rich_tooltip; +B32 do_implicit_root; Dir2 dir2; String8 string; String8 cmd_name; @@ -635,6 +637,7 @@ RD_Query query; .force_confirm = rd_regs()->force_confirm,\ .prefer_disasm = rd_regs()->prefer_disasm,\ .no_rich_tooltip = rd_regs()->no_rich_tooltip,\ +.do_implicit_root = rd_regs()->do_implicit_root,\ .dir2 = rd_regs()->dir2,\ .string = rd_regs()->string,\ .cmd_name = rd_regs()->cmd_name,\ @@ -644,7 +647,7 @@ RD_Query query; C_LINKAGE_BEGIN extern RD_VocabInfo rd_vocab_info_table[308]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; -extern Rng1U64 rd_reg_slot_range_table[41]; +extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[74]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d1435b65..2abb1a0a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -378,6 +378,7 @@ RD_RegTable: {B32 force_confirm ForceConfirm } {B32 prefer_disasm PreferDisasm } {B32 no_rich_tooltip NoRichTooltip } + {B32 do_implicit_root DoImplicitRoot} {Dir2 dir2 Dir2 } {String8 string String } {String8 cmd_name CmdName } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 07dd7348..d4cf4f81 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -323,10 +323,14 @@ E_LOOKUP_INFO_FUNCTION_DEF(schema) { if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) { - ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); - n->n = child; - SLLQueuePush(first_child_node, last_child_node, n); - child_count += 1; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); + if(matches.count == matches.needle_part_count) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } } } @@ -387,7 +391,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) { Temp scratch = scratch_begin(&arena, 1); - String8 string = push_str8f(scratch.arena, "%S:%S%s%S", child->first->string, child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); + String8 string = push_str8f(scratch.arena, "%S%s%S%s%S", child->first->string, child->first->string.size ? ":" : "", child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); scratch_end(scratch); } @@ -2953,7 +2957,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path_pt"), 0)) { - read_data = push_str8f(scratch.arena, "%S:%S%s%S", cfg->first->string, cfg->first->first->string, cfg->first->first->first->string.size ? ":" : "", cfg->first->first->first->string); + read_data = push_str8f(scratch.arena, "%S%s%S%s%S", cfg->first->string, cfg->first->string.size ? ":" : "", cfg->first->first->string, cfg->first->first->first->string.size ? ":" : "", cfg->first->first->first->string); } else if(str8_match(child_type_name, str8_lit("path"), 0) || str8_match(child_type_name, str8_lit("code_string"), 0) || @@ -7724,8 +7728,9 @@ rd_window_frame(void) } } - // rjf: based on query expression, determine if we have an explicit root - if(query_expr.size == 0 || !query_is_lister) + // rjf: determine if we want an explicit root + B32 do_explicit_root = (!ws->query_regs->do_implicit_root && (query_expr.size == 0 || !query_is_lister)); + if(do_explicit_root) { RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new(explicit_root, str8_lit("1")); @@ -7751,7 +7756,7 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - query_height_px = row_height_px * predicted_block_tree.total_row_count; + query_height_px = row_height_px * (predicted_block_tree.total_row_count - !do_explicit_root); query_height_px = Min(query_height_px, max_query_height_px); } rect = r2f32p(content_rect_center.x - query_width_px/2, @@ -9762,6 +9767,7 @@ rd_window_frame(void) else if(ui_right_clicked(sig)) { rd_cmd(RD_CmdKind_PushQuery, + .do_implicit_root = 1, .ui_key = sig.box->key, .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 14788340..7d61a080 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -75,6 +75,9 @@ // single step over the first instruction of that line, even if the thread // would've stopped at the first instruction due to the step, were that bp not // there. +// +// [ ] if a breakpoint matches the entry point's starting address, its hit count +// is not correctly incremented. //////////////////////////////// //~ rjf: post-0.9.12 TODO notes From aff63db8eb3c7a49623140b86ec213fec27e3a71 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 14:56:21 -0700 Subject: [PATCH 241/755] ctrl entity meta evaluation, hook up reads/writes, get off eval blobs; switch freeze/thaw ui to working on 'active' child, plugs into usual toggle path --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/raddbg.mdesk | 6 +- src/raddbg/raddbg_core.c | 269 ++++++++++++++++------------- src/raddbg/raddbg_views.c | 2 +- 4 files changed, 152 insertions(+), 131 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 6e036066..580643ca 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -330,10 +330,10 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, -{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'frozen':bool, 'unattached_processes':query, 'processes':query}")}, -{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'modules':query, 'threads':query}")}, +{str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, +{str8_lit_comp("process"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':query, 'threads':query}")}, {str8_lit_comp("module"), str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, -{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'call_stack':query}")}, +{str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; Rng1U64 rd_reg_slot_range_table[42] = diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 2abb1a0a..4a74ce1a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -297,11 +297,11 @@ RD_VocabTable: //- rjf: control entities { machine, - ```x:{'label':code_string, @no_expand 'frozen':bool, 'unattached_processes':query, 'processes':query}```, + ```x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}```, } { process, - ```x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'modules':query, 'threads':query}```, + ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':query, 'threads':query}```, } { module, @@ -309,7 +309,7 @@ RD_VocabTable: } { thread, - ```x:{'label':code_string, 'id':u64, @no_expand 'frozen':bool, 'call_stack':query}```, + ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}```, } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d4cf4f81..e1543e59 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -289,6 +289,7 @@ typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; struct RD_SchemaLookupAccel { RD_Cfg *cfg; + CTRL_Entity *entity; MD_Node *schema; MD_Node **children; U64 children_count; @@ -304,7 +305,6 @@ E_LOOKUP_INFO_FUNCTION_DEF(schema) E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); - RD_Cfg *cfg = rd_cfg_from_eval_space(interpret.space); E_TypeKey type_key = lhs->type_key; E_Type *type = e_type_from_key__cached(type_key); MD_Node *schema = rd_schema_from_name(type->name); @@ -346,7 +346,8 @@ E_LOOKUP_INFO_FUNCTION_DEF(schema) // rjf: build accelerator for lookups RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); - accel->cfg = cfg; + accel->cfg = rd_cfg_from_eval_space(interpret.space); + accel->entity = rd_ctrl_entity_from_eval_space(interpret.space); accel->schema = schema; accel->children = children; accel->children_count = child_count; @@ -378,9 +379,28 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) if(child_schema != &md_nil_node) { RD_Cfg *cfg = accel->cfg; + CTRL_Entity *entity = accel->entity; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); E_TypeKey child_type_key = zero_struct; - if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + if(0){} + + //- rjf: ctrl entity members + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("label"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsCodeText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("exe"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsPathText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + CTRL_Entity *dbg = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), dbg->string.size, E_TypeFlag_IsPathText); + } + + //- rjf: cfg members + else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); } @@ -399,6 +419,8 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); } + + //- rjf: catchall cases else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) { child_type_key = e_type_key_basic(E_TypeKind_U64); @@ -407,13 +429,34 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_basic(E_TypeKind_Bool); } + else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + E_MemberList vaddr_range_members_list = {0}; + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); + E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); + child_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); + scratch_end(scratch); + } else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) { child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); } - E_Space child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); - child_eval_space.u64s[0] = cfg->id; - child_eval_space.u64s[1] = e_id_from_string(child_schema->string); + + //- rjf: evaluate + E_Space child_eval_space = zero_struct; + if(cfg != &rd_nil_cfg) + { + child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); + child_eval_space.u64s[0] = cfg->id; + child_eval_space.u64s[1] = e_id_from_string(child_schema->string); + } + else + { + child_eval_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + child_eval_space.u64s[2] = e_id_from_string(child_schema->string); + } irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); irtree.type_key = child_type_key; irtree.mode = E_Mode_Offset; @@ -3001,14 +3044,48 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: meta-entity reads case RD_EvalSpaceKind_MetaCtrlEntity: { + // rjf: unpack cfg CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - String8 entity_eval_blob = rd_eval_blob_from_entity__cached(entity); - Rng1U64 legal_range = r1u64(0, entity_eval_blob.size); + String8 child_key = e_string_from_id(space.u64s[2]); + + // rjf: determine data to read from, depending on child name in schema + String8 read_data = {0}; + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + if(str8_match(child_schema->string, str8_lit("exe"), 0) || + str8_match(child_schema->string, str8_lit("label"), 0)) + { + read_data = entity->string; + } + else if(str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + read_data = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath)->string; + } + else if(str8_match(child_schema->string, str8_lit("vaddr_range"), 0)) + { + read_data = str8_struct(&entity->vaddr_range); + } + else if(str8_match(child_schema->string, str8_lit("id"), 0)) + { + read_data = str8_struct(&entity->id); + } + else if(str8_match(child_schema->string, str8_lit("active"), 0)) + { + B32 is_frozen = ctrl_entity_tree_is_frozen(entity); + B32 is_active = !is_frozen; + read_data = push_str8_copy(scratch.arena, str8_struct(&is_active)); + } + } + + // rjf: perform read + Rng1U64 legal_range = r1u64(0, read_data.size); Rng1U64 read_range = intersect_1u64(range, legal_range); if(read_range.min < read_range.max) { result = 1; - MemoryCopy(out, entity_eval_blob.str + read_range.min, dim_1u64(read_range)); + MemoryCopy(out, read_data.str + read_range.min, dim_1u64(read_range)); } }break; } @@ -3118,108 +3195,49 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } } - // rjf: find member to which this write applies, reflect back in the cfg tree -#if 0 - if(type->members != 0) for EachIndex(member_idx, type->count) - { - E_Member *member = &type->members[member_idx]; - Rng1U64 member_range = r1u64(member->off, member->off + e_type_byte_size_from_key(member->type_key)); - String8 child_name = member->name; - MD_Node *member_schema = md_child_from_string(schema, child_name, 0); - String8 member_type_name = member_schema->first->string; - RD_Cfg *child = rd_cfg_child_from_string(cfg, child_name); - if((str8_match(member_type_name, str8_lit("code_string"), 0) || - str8_match(member_type_name, str8_lit("path"), 0) || - str8_match(member_type_name, str8_lit("string"), 0)) && - member->off+sizeof(U64) <= eval_blob.size) - { - U64 string_off = *(U64 *)(eval_blob.str + member->off); - U64 string_opl = string_off + child->first->string.size + 1; - Rng1U64 string_range = r1u64(string_off, string_opl); - if(contains_1u64(string_range, range.min)) - { - String8 new_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); - if(new_string.size == 0) - { - rd_cfg_release(child); - } - else - { - if(child == &rd_nil_cfg) - { - child = rd_cfg_new(cfg, child_name); - } - rd_cfg_new_replace(child, new_string); - } - result = 1; - break; - } - } - else if(str8_match(member_type_name, str8_lit("u64"), 0) && dim_1u64(range) >= 1 && contains_1u64(member_range, range.min)) - { - U64 value = 0; - MemoryCopy(&value, in, dim_1u64(range)); - if(value == 0) - { - rd_cfg_release(child); - } - else - { - if(child == &rd_nil_cfg) - { - child = rd_cfg_new(cfg, child_name); - } - rd_cfg_new_replacef(child, "%I64u", value); - } - result = 1; - break; - } - else if(str8_match(member_type_name, str8_lit("bool"), 0) && dim_1u64(range) >= 1 && contains_1u64(member_range, range.min)) - { - U64 value = 0; - MemoryCopy(&value, in, dim_1u64(range)); - if(child == &rd_nil_cfg) - { - child = rd_cfg_new(cfg, child_name); - } - rd_cfg_new_replacef(child, "%I64u", value); - result = 1; - break; - } - } -#endif - 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 + // rjf: unpack write info + String8 write_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); + + // rjf: unpack cfg CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, entity); + String8 child_key = e_string_from_id(space.u64s[2]); - // 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: perform write, based on child name in schema + if(child_key.size != 0) + { + MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + if(str8_match(child_schema->string, str8_lit("label"), 0)) + { + rd_cmd(D_CmdKind_SetEntityName, .ctrl_entity = entity->handle, .string = write_string); + } + else if(str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + // TODO(rjf) + } + else if(str8_match(child_schema->string, str8_lit("active"), 0)) + { + B32 new_active = 0; + MemoryCopy(&new_active, in, dim_1u64(range)); + if(!new_active) + { + rd_cmd(D_CmdKind_FreezeEntity, .ctrl_entity = entity->handle); + } + else + { + rd_cmd(D_CmdKind_ThawEntity, .ctrl_entity = entity->handle); + } + } + } - // 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) - StringMemberCase(label) {result = 1; ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, str8_cstring_capped(in, (U8 *)in + 4096));} -#undef FlatMemberCase -#undef StringMemberCase scratch_end(scratch); -#endif }break; } return result; @@ -5488,66 +5506,69 @@ rd_view_ui(Rng2F32 rect) } // rjf: form cell build parameters - RD_CellParams line_edit_params = {0}; + RD_CellParams cell_params = {0}; { // rjf: set up base parameters - line_edit_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); - line_edit_params.depth = (cell_x == 0 ? row_depth : 0); - line_edit_params.cursor = &cell_edit_state->cursor; - line_edit_params.mark = &cell_edit_state->mark; - line_edit_params.edit_buffer = cell_edit_state->input_buffer; - line_edit_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); - line_edit_params.edit_string_size_out = &cell_edit_state->input_size; - line_edit_params.expanded_out = &next_row_expanded; - line_edit_params.pre_edit_value = cell_info.string; - line_edit_params.fstrs = cell_info.fstrs; - line_edit_params.fuzzy_matches = &fuzzy_matches; + cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); + cell_params.depth = (cell_x == 0 ? row_depth : 0); + cell_params.cursor = &cell_edit_state->cursor; + cell_params.mark = &cell_edit_state->mark; + cell_params.edit_buffer = cell_edit_state->input_buffer; + cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); + cell_params.edit_string_size_out = &cell_edit_state->input_size; + cell_params.expanded_out = &next_row_expanded; + cell_params.pre_edit_value = cell_info.string; + cell_params.fstrs = cell_info.fstrs; + cell_params.fuzzy_matches = &fuzzy_matches; // rjf: apply expander (or substitute space) if(row_is_expandable && cell == row_info->cells.first) { - line_edit_params.flags |= RD_CellFlag_Expander; + cell_params.flags |= RD_CellFlag_Expander; } else if(row_depth == !implicit_root && cell == row_info->cells.first) { - line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + cell_params.flags |= RD_CellFlag_ExpanderSpace; } else if(row_depth != 0 && cell == row_info->cells.first) { - line_edit_params.flags |= RD_CellFlag_ExpanderSpace; + cell_params.flags |= RD_CellFlag_ExpanderSpace; } // rjf: apply single-click-activation if(is_activated_on_single_click) { - line_edit_params.flags |= RD_CellFlag_SingleClickActivate; + cell_params.flags |= RD_CellFlag_SingleClickActivate; } // rjf: apply code styles if(is_non_code) { - line_edit_params.flags &= ~RD_CellFlag_CodeContents; + cell_params.flags &= ~RD_CellFlag_CodeContents; } // rjf: apply button styles if(is_button) { - line_edit_params.flags |= RD_CellFlag_Button; - line_edit_params.flags &= ~RD_CellFlag_NoBackground; - line_edit_params.flags &= ~RD_CellFlag_ExpanderSpace; + cell_params.flags |= RD_CellFlag_Button; + cell_params.flags &= ~RD_CellFlag_NoBackground; + if(row_depth == 0) + { + cell_params.flags &= ~RD_CellFlag_ExpanderSpace; + } } // rjf: apply background if(has_background) { - line_edit_params.flags &= ~RD_CellFlag_NoBackground; + cell_params.flags &= ~RD_CellFlag_NoBackground; } // rjf: apply toggle-switch if(is_toggle_switch) { - line_edit_params.flags |= RD_CellFlag_ToggleSwitch; - line_edit_params.toggled_out = &next_cell_toggled; + cell_params.flags |= RD_CellFlag_ToggleSwitch; + cell_params.toggled_out = &next_cell_toggled; } } @@ -5559,7 +5580,7 @@ rd_view_ui(Rng2F32 rect) UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) { - sig = rd_cellf(&line_edit_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + sig = rd_cellf(&cell_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); } if(cell_background_color_override.w != 0) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a05a836c..a8eccd2e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1202,7 +1202,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).frozen")); + .string = str8_lit("($expr).active")); } if(entity->kind == CTRL_EntityKind_Thread) { From af9ddf0a48595655ee08b12d0cac407b44aaf9e3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 14:57:06 -0700 Subject: [PATCH 242/755] eliminate old entity -> eval blob paths / cache --- src/raddbg/raddbg_core.c | 105 --------------------------------------- src/raddbg/raddbg_core.h | 32 ------------ 2 files changed, 137 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e1543e59..a4c2cf7f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2781,108 +2781,6 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) return space; } -//- 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(name); - String8List fixed_width_parts = {0}; - String8List variable_width_parts = {0}; - { - E_Type *type = e_type_from_key__cached(type_key); - if(type->members != 0) for EachIndex(member_idx, type->count) - { - E_Member *member = &type->members[member_idx]; - String8 member_name = member->name; - if(0){} - else if(str8_match(member_name, str8_lit("frozen"), 0)) - { - B32 is_frozen = ctrl_entity_tree_is_frozen(entity); - str8_list_push(scratch.arena, &fixed_width_parts, str8((U8 *)&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")); - } - } - } - 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) - { - 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; -} - //- rjf: eval space reads/writes internal B32 @@ -12840,9 +12738,6 @@ rd_frame(void) } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; - 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: iterate all tabs, touch their view-states diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 22c75874..568cdcb8 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -582,31 +582,6 @@ struct RD_WindowStateSlot RD_WindowState *last; }; -//////////////////////////////// -//~ 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 @@ -695,9 +670,6 @@ struct RD_State // rjf: meta name -> eval type key map (constructed from-scratch each frame) E_String2TypeKeyMap *meta_name2type_map; - // rjf: eval blob caches (lazily constructed from-scratch each frame) - RD_Entity2EvalBlobMap *entity2evalblob_map; - // rjf: name -> view ui map (constructed from-scratch each frame) RD_ViewUIRuleMap *view_ui_rule_map; @@ -954,10 +926,6 @@ internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); 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); -//- 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: eval space reads/writes internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); From 8ba44295c6d6f47798664ceada8d2ed50fa701b2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 15:17:56 -0700 Subject: [PATCH 243/755] more aggressively gc hover eval view state; do not use hotkey intermediate if a command triggered by a watch window is already parameterized --- src/raddbg/raddbg_core.c | 127 +++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a4c2cf7f..10f78a4b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5581,7 +5581,17 @@ rd_view_ui(Rng2F32 rect) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); - rd_cmd(RD_CmdKind_RunCommand, .cfg = cfg->id, .ctrl_entity = entity->handle, .cmd_name = cell_info.cmd_name); + RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) + { + if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) + { + rd_push_cmd(cell_info.cmd_name, rd_regs()); + } + else + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cell_info.cmd_name); + } + } } // rjf: row has callstack info? -> select unwind @@ -7487,23 +7497,6 @@ rd_window_frame(void) } } - // rjf: determine if we have a top-level visualizer - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); - - // rjf: determine view name - String8 view_name = str8_lit("watch"); - if(view_ui_rule != &rd_nil_view_ui_rule) - { - view_name = view_ui_rule->name; - } - - // rjf: build view - RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - // rjf: request frames if we're waiting to open if(ws->hover_eval_string.size != 0 && !hover_eval_is_open && @@ -7513,47 +7506,67 @@ rd_window_frame(void) rd_request_frame(); } - // rjf: determine size of hover evaluation container - EV_BlockTree predicted_block_tree = {0}; - RD_RegsScope(.view = view->id) - { - predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); - } - F32 row_height_px = ui_top_px_height(); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); - if(ws->hover_eval_focused) - { - max_row_count *= 3; - } - U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); - F32 width_px = floor_f32(70.f*ui_top_font_size()); - F32 height_px = needed_row_count*row_height_px; - - // rjf: if arbitrary visualizer, pick catchall size - if(view_ui_rule != &rd_nil_view_ui_rule) - { - height_px = floor_f32(40.f*ui_top_font_size()); - } - - // rjf: determine hover eval top-level rect - Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, - ws->hover_eval_spawn_pos.y, - ws->hover_eval_spawn_pos.x + width_px, - ws->hover_eval_spawn_pos.y + height_px); - - // rjf: push hover eval task + // rjf: build hover eval task if(build_hover_eval) { - FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); - SLLQueuePush(first_floating_view_task, last_floating_view_task, t); - hover_eval_floating_view_task = t; - t->view = view; - t->row_height_px = row_height_px; - t->rect = rect; - t->view_name = view_name; - t->expr = hover_eval_expr; - t->is_focused = ws->hover_eval_focused; - t->is_anchored = 1; + // rjf: determine if we have a top-level visualizer + EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + + // rjf: determine view name + String8 view_name = str8_lit("watch"); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + view_name = view_ui_rule->name; + } + + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); + RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_new_replace(explicit_root, str8_lit("1")); + + // rjf: determine size of hover evaluation container + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id) + { + predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + } + F32 row_height_px = ui_top_px_height(); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); + if(ws->hover_eval_focused) + { + max_row_count *= 3; + } + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); + F32 width_px = floor_f32(70.f*ui_top_font_size()); + F32 height_px = needed_row_count*row_height_px; + + // rjf: if arbitrary visualizer, pick catchall size + if(view_ui_rule != &rd_nil_view_ui_rule) + { + height_px = floor_f32(40.f*ui_top_font_size()); + } + + // rjf: determine hover eval top-level rect + Rng2F32 rect = r2f32p(ws->hover_eval_spawn_pos.x, + ws->hover_eval_spawn_pos.y, + ws->hover_eval_spawn_pos.x + width_px, + ws->hover_eval_spawn_pos.y + height_px); + + // rjf: push hover eval task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + hover_eval_floating_view_task = t; + t->view = view; + t->row_height_px = row_height_px; + t->rect = rect; + t->view_name = view_name; + t->expr = hover_eval_expr; + t->is_focused = ws->hover_eval_focused; + t->is_anchored = 1; + } } // rjf: reset focus state if hover eval is not being built From 4787a183e3ae92d38c80087fbb89beb5b7027d5a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 16:06:13 -0700 Subject: [PATCH 244/755] fix consistency issues --- src/raddbg/raddbg_core.c | 11 +++++++++-- src/ui/ui_core.c | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 10f78a4b..670d1564 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9796,11 +9796,18 @@ rd_window_frame(void) rd_icon_kind_text_table[RD_IconKind_Add], panel->cfg); UI_Signal sig = ui_signal_from_box(add_new_box); - if(ui_clicked(sig)) + if(ui_pressed(sig)) { rd_cmd(RD_CmdKind_FocusPanel); UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + if(ui_ctx_menu_is_open(view_menu_key)) + { + ui_ctx_menu_close(); + } + else + { + ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + } } } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index c21f2430..8bf53e7b 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1959,9 +1959,9 @@ internal void ui_tooltip_begin(void) { ui_tooltip_begin_base(); - ui_set_next_squish(0.25f-ui_state->tooltip_open_t*0.25f); + ui_set_next_squish(0.1f-ui_state->tooltip_open_t*0.1f); ui_set_next_transparency(1-ui_state->tooltip_open_t); - UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow) + UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_SquishAnchored) UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_children_sum(1)) UI_CornerRadius(ui_top_font_size()*0.25f) From a826afd4d67b7c81b2bf46ebf0559339549663e4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 16:30:05 -0700 Subject: [PATCH 245/755] merge part 2 --- src/coff/coff.h | 1 + src/ctrl/ctrl_core.c | 4 +++- src/demon/win32/demon_core_win32.c | 24 ++++++++++++------------ src/raddbg/raddbg_core.c | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/coff/coff.h b/src/coff/coff.h index 97727aef..c109a966 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -47,6 +47,7 @@ enum typedef U16 COFF_MachineType; enum { + // TODO(rjf): COFF_Machine prefix -> COFF_MachineType prefix COFF_Machine_Unknown = 0x0, COFF_Machine_X86 = 0x14c, COFF_Machine_X64 = 0x8664, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 2cb579f4..4ce76eb3 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4639,9 +4639,11 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->reg_space.u64_0 = (U64)thread; ctx->module_base = push_array(arena, U64, 1); ctx->module_base[0]= module->vaddr_range.min; + ctx->frame_base = push_array(arena, U64, 1); + // TODO(rjf): need to compute this out here somehow... ctx->frame_base[0] = ; ctx->tls_base = push_array(arena, U64, 1); } - e_select_interpret_ctx(&scope->interpret_ctx); + e_select_interpret_ctx(&scope->interpret_ctx, eval_modules_primary->rdi, thread_rip_voff); return scope; } diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 0e79ad16..abe2d88d 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -469,9 +469,9 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr) } // rjf: get COFF header - B32 got_file_header = 0; - U64 file_header_off = 0; - COFF_FileHeader file_header = {0}; + B32 got_coff_header = 0; + U64 coff_header_off = 0; + COFF_FileHeader coff_header = {0}; if(pe_offset > 0) { U64 pe_magic_off = base_vaddr + pe_offset; @@ -479,21 +479,21 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr) dmn_w32_process_read_struct(process, pe_magic_off, &pe_magic); if(pe_magic == PE_MAGIC) { - file_header_off = pe_magic_off + sizeof(pe_magic); - if(dmn_w32_process_read_struct(process, file_header_off, &file_header)) + coff_header_off = pe_magic_off + sizeof(pe_magic); + if(dmn_w32_process_read_struct(process, coff_header_off, &coff_header)) { - got_file_header = 1; + got_coff_header = 1; } } } // rjf: get arch and size DMN_W32_ImageInfo result = zero_struct; - if(got_file_header) + if(got_coff_header) { U64 optional_size_off = 0; Arch arch = Arch_Null; - switch(file_header.machine) + switch(coff_header.machine) { case COFF_Machine_X86: { @@ -510,7 +510,7 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr) } if(arch != Arch_Null) { - U64 optional_off = file_header_off + sizeof(COFF_FileHeader); + U64 optional_off = coff_header_off + sizeof(coff_header); U32 size = 0; if(dmn_w32_process_read_struct(process, optional_off+optional_size_off, &size) >= sizeof(size)) { @@ -1251,7 +1251,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) // rjf: get COFF header B32 got_coff_header = 0; U64 coff_header_off = 0; - COFF_Header coff_header = {0}; + COFF_FileHeader coff_header = {0}; if(pe_offset > 0) { U64 pe_magic_off = pe_offset; @@ -1274,13 +1274,13 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) switch(coff_header.machine) { default:{}break; - case COFF_MachineType_X64: + case COFF_Machine_X64: { PE_OptionalHeader32Plus hdr = {0}; os_file_read_struct(file, opt_header_off, &hdr); subsystem = hdr.subsystem; }break; - case COFF_MachineType_X86: + case COFF_Machine_X86: { PE_OptionalHeader32 hdr = {0}; os_file_read_struct(file, opt_header_off, &hdr); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 670d1564..a8c6bae2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13923,7 +13923,7 @@ rd_frame(void) ctx->tls_base = push_array(scratch.arena, U64, 1); ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr); } - e_select_interpret_ctx(interpret_ctx); + e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); //////////////////////////// //- rjf: build eval expand rule table From 213091cf755662b4658aed8c431a235faca60f6b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 16:40:52 -0700 Subject: [PATCH 246/755] add safeguard to not overwrite old config data, for anyone using dev currently... --- src/raddbg/raddbg_core.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a8c6bae2..becfdf4e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14216,15 +14216,34 @@ rd_frame(void) //- rjf: load the new file's data String8 file_path = rd_regs()->file_path; String8 file_data = os_data_from_file_path(scratch.arena, file_path); + FileProperties file_props = os_properties_from_file_path(file_path); //- rjf: determine if the file is good B32 file_is_okay = 0; { - FileProperties file_props = os_properties_from_file_path(file_path); file_is_okay = ((file_props.size == 0 && file_props.created == 0) || str8_match(str8_prefix(file_data, 9), str8_lit("// raddbg"), 0)); } + //- rjf: determine file's version + String8 file_version = {0}; + if(file_is_okay && file_props.size != 0) + { + file_version = str8_skip(file_data, 10); + U64 line_end = str8_find_needle(file_version, 0, str8_lit("\n"), 0); + file_version = str8_prefix(file_version, line_end); + U64 first_space = str8_find_needle(file_version, 0, str8_lit(" "), 0); + file_version = str8_prefix(file_version, first_space); + file_version = str8_skip_chop_whitespace(file_version); + String8 current_version = str8_lit(BUILD_VERSION_STRING_LITERAL); + if(!str8_match(file_version, current_version, 0)) + { + String8 msg = push_str8f(scratch.arena, "You are trying to run a new development version of RADDBG (%S) with old configuration files. This would overwrite your old configuration files, since the code to appropriately handle old configuration files hasn't been written yet. Out of caution, the program will now exit. If you want to use this new version anyway, delete or rename your configuration file at %S, so that the new development version can begin safely saving to it.", current_version, file_path); + os_graphical_message(1, str8_lit("Unsupported Configuration File Version"), msg); + os_abort(1); + } + } + //- rjf: bad file -> alert user if(!file_is_okay) { From ab9885bc7d6ef4e6375cc6f350ef8499379775b5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 16:54:12 -0700 Subject: [PATCH 247/755] fix clang build --- src/eval/eval_types.h | 2 +- .../core/linux/metagen_os_core_linux.c | 166 +++++-- .../core/linux/metagen_os_core_linux.h | 29 +- src/metagen/metagen_os/core/metagen_os_core.c | 97 +++- src/metagen/metagen_os/core/metagen_os_core.h | 63 ++- .../core/win32/metagen_os_core_win32.c | 445 ++++++++++++------ .../core/win32/metagen_os_core_win32.h | 1 - src/metagen/metagen_os/metagen_os_inc.h | 4 - src/os/core/win32/os_core_win32.c | 4 +- src/raddbg/raddbg_core.c | 5 +- 10 files changed, 549 insertions(+), 267 deletions(-) diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 38c5c7aa..df66f01c 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -313,7 +313,7 @@ struct E_TypeState //////////////////////////////// //~ rjf: Globals -global read_only E_Member e_member_nil = {E_MemberKind_Null, zero_struct, {0}, {0}, 0, {0}}; +global read_only E_Member e_member_nil = {E_MemberKind_Null}; global read_only E_Type e_type_nil = {E_TypeKind_Null}; thread_static E_TypeState *e_type_state = 0; diff --git a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c index 2220b63e..5acd5cf8 100644 --- a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c +++ b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c @@ -150,9 +150,27 @@ os_get_current_path(Arena *arena) { char *cwdir = getcwd(0, 0); String8 string = push_str8_copy(arena, str8_cstring(cwdir)); + free(cwdir); return string; } +internal U32 +os_get_process_start_time_unix(void) +{ + Temp scratch = scratch_begin(0,0); + U64 start_time = 0; + pid_t pid = getpid(); + String8 path = push_str8f(scratch.arena, "/proc/%u", pid); + struct stat st; + int err = stat((char*)path.str, &st); + if(err == 0) + { + start_time = st.st_mtime; + } + scratch_end(scratch); + return (U32)start_time; +} + //////////////////////////////// //~ rjf: @os_hooks Memory Allocation (Implemented Per-OS) @@ -162,6 +180,10 @@ internal void * os_reserve(U64 size) { void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if(result == MAP_FAILED) + { + result = 0; + } return result; } @@ -191,6 +213,10 @@ internal void * os_reserve_large(U64 size) { void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0); + if(result == MAP_FAILED) + { + result = 0; + } return result; } @@ -207,12 +233,7 @@ os_commit_large(void *ptr, U64 size) internal U32 os_tid(void) { - U32 result = 0; -#if defined(SYS_gettid) - result = syscall(SYS_gettid); -#else - result = gettid(); -#endif + U32 result = gettid(); return result; } @@ -246,7 +267,7 @@ os_file_open(OS_AccessFlags flags, String8 path) Temp scratch = scratch_begin(0, 0); String8 path_copy = push_str8_copy(scratch.arena, path); int lnx_flags = 0; - if(flags & (OS_AccessFlag_Read|OS_AccessFlag_Write)) + if(flags & OS_AccessFlag_Read && flags & OS_AccessFlag_Write) { lnx_flags = O_RDWR; } @@ -262,7 +283,11 @@ os_file_open(OS_AccessFlags flags, String8 path) { lnx_flags |= O_APPEND; } - int fd = open((char *)path_copy.str, lnx_flags); + if(flags & (OS_AccessFlag_Write|OS_AccessFlag_Append)) + { + lnx_flags |= O_CREAT; + } + int fd = open((char *)path_copy.str, lnx_flags, 0755); OS_Handle handle = {0}; if(fd != -1) { @@ -285,16 +310,12 @@ os_file_read(OS_Handle file, Rng1U64 rng, void *out_data) { if(os_handle_match(file, os_handle_zero())) { return 0; } int fd = (int)file.u64[0]; - if(rng.min != 0) - { - lseek(fd, rng.min, SEEK_SET); - } U64 total_num_bytes_to_read = dim_1u64(rng); U64 total_num_bytes_read = 0; U64 total_num_bytes_left_to_read = total_num_bytes_to_read; for(;total_num_bytes_left_to_read > 0;) { - int read_result = read(fd, (U8 *)out_data + total_num_bytes_read, total_num_bytes_left_to_read); + int read_result = pread(fd, (U8 *)out_data + total_num_bytes_read, total_num_bytes_left_to_read, rng.min + total_num_bytes_read); if(read_result >= 0) { total_num_bytes_read += read_result; @@ -313,16 +334,12 @@ os_file_write(OS_Handle file, Rng1U64 rng, void *data) { if(os_handle_match(file, os_handle_zero())) { return 0; } int fd = (int)file.u64[0]; - if(rng.min != 0) - { - lseek(fd, rng.min, SEEK_SET); - } U64 total_num_bytes_to_write = dim_1u64(rng); U64 total_num_bytes_written = 0; U64 total_num_bytes_left_to_write = total_num_bytes_to_write; for(;total_num_bytes_left_to_write > 0;) { - int write_result = write(fd, (U8 *)data + total_num_bytes_written, total_num_bytes_left_to_write); + int write_result = pwrite(fd, (U8 *)data + total_num_bytes_written, total_num_bytes_left_to_write, rng.min + total_num_bytes_written); if(write_result >= 0) { total_num_bytes_written += write_result; @@ -402,25 +419,23 @@ os_copy_file_path(String8 dst, String8 src) if(!os_handle_match(src_h, os_handle_zero()) && !os_handle_match(dst_h, os_handle_zero())) { + int src_fd = (int)src_h.u64[0]; + int dst_fd = (int)dst_h.u64[0]; FileProperties src_props = os_properties_from_file(src_h); U64 size = src_props.size; U64 total_bytes_copied = 0; U64 bytes_left_to_copy = size; for(;bytes_left_to_copy > 0;) { - Temp scratch = scratch_begin(0, 0); - U64 buffer_size = Min(bytes_left_to_copy, MB(8)); - U8 *buffer = push_array_no_zero(scratch.arena, U8, buffer_size); - U64 bytes_read = os_file_read(src_h, r1u64(total_bytes_copied, total_bytes_copied+buffer_size), buffer); - U64 bytes_written = os_file_write(dst_h, r1u64(total_bytes_copied, total_bytes_copied+bytes_read), buffer); - U64 bytes_copied = Min(bytes_read, bytes_written); - bytes_left_to_copy -= bytes_copied; - total_bytes_copied += bytes_copied; - scratch_end(scratch); - if(bytes_copied == 0) + off_t sendfile_off = total_bytes_copied; + int send_result = sendfile(dst_fd, src_fd, &sendfile_off, bytes_left_to_copy); + if(send_result <= 0) { break; } + U64 bytes_copied = (U64)send_result; + bytes_left_to_copy -= bytes_copied; + total_bytes_copied += bytes_copied; } } os_file_close(src_h); @@ -428,6 +443,12 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + // TODO(rjf) +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { @@ -455,6 +476,22 @@ os_file_path_exists(String8 path) return result; } +internal B32 +os_folder_path_exists(String8 path) +{ + Temp scratch = scratch_begin(0, 0); + B32 exists = 0; + String8 path_copy = push_str8_copy(scratch.arena, path); + DIR *handle = opendir((char*)path_copy.str); + if(handle) + { + closedir(handle); + exists = 1; + } + scratch_end(scratch); + return exists; +} + internal FileProperties os_properties_from_file_path(String8 path) { @@ -497,6 +534,10 @@ os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range) if(flags & OS_AccessFlag_Read) { prot_flags |= PROT_READ; } int map_flags = MAP_PRIVATE; void *base = mmap(0, dim_1u64(range), prot_flags, map_flags, fd, range.min); + if(base == MAP_FAILED) + { + base = 0; + } return base; } @@ -589,7 +630,7 @@ os_make_directory(String8 path) Temp scratch = scratch_begin(0, 0); B32 result = 0; String8 path_copy = push_str8_copy(scratch.arena, path); - if(mkdir((char*)path_copy.str, 0777) != -1) + if(mkdir((char*)path_copy.str, 0755) != -1) { result = 1; } @@ -637,6 +678,10 @@ os_shared_memory_view_open(OS_Handle handle, Rng1U64 range) if(os_handle_match(handle, os_handle_zero())){return 0;} int id = (int)handle.u64[0]; void *base = mmap(0, dim_1u64(range), PROT_READ|PROT_WRITE, MAP_SHARED, id, range.min); + if(base == MAP_FAILED) + { + base = 0; + } return base; } @@ -744,10 +789,7 @@ os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params) entity->thread.func = func; entity->thread.ptr = ptr; { - pthread_attr_t attr; - pthread_attr_init(&attr); - int pthread_result = pthread_create(&entity->thread.handle, &attr, os_lnx_thread_entry_point, entity); - pthread_attr_destroy(&attr); + int pthread_result = pthread_create(&entity->thread.handle, 0, os_lnx_thread_entry_point, entity); if(pthread_result == -1) { os_lnx_entity_release(entity); @@ -1025,13 +1067,26 @@ os_condition_variable_broadcast(OS_Handle cv) internal OS_Handle os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name) { - NotImplemented; + OS_Handle result = {0}; + if (name.size > 0) { + // TODO: we need to allocate shared memory to store sem_t + NotImplemented; + } else { + sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + AssertAlways(s != MAP_FAILED); + int err = sem_init(s, 0, initial_count); + if (err == 0) { + result.u64[0] = (U64)s; + } + } + return result; } internal void os_semaphore_release(OS_Handle semaphore) { - NotImplemented; + int err = munmap((void*)semaphore.u64[0], sizeof(sem_t)); + AssertAlways(err == 0); } internal OS_Handle @@ -1049,13 +1104,37 @@ os_semaphore_close(OS_Handle semaphore) internal B32 os_semaphore_take(OS_Handle semaphore, U64 endt_us) { - NotImplemented; + AssertAlways(endt_us == max_U64); + for (;;) { + int err = sem_wait((sem_t*)semaphore.u64[0]); + if (err == 0) { + break; + } else { + if (errno == EAGAIN) { + continue; + } + } + InvalidPath; + break; + } + return 1; } internal void os_semaphore_drop(OS_Handle semaphore) { - NotImplemented; + for (;;) { + int err = sem_post((sem_t*)semaphore.u64[0]); + if (err == 0) { + break; + } else { + if (errno == EAGAIN) { + continue; + } + } + InvalidPath; + break; + } } //////////////////////////////// @@ -1066,7 +1145,7 @@ os_library_open(String8 path) { Temp scratch = scratch_begin(0, 0); char *path_cstr = (char *)push_str8_copy(scratch.arena, path).str; - void *so = dlopen(path_cstr, RTLD_LAZY); + void *so = dlopen(path_cstr, RTLD_LAZY|RTLD_LOCAL); OS_Handle lib = { (U64)so }; scratch_end(scratch); return lib; @@ -1130,14 +1209,11 @@ os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, v //////////////////////////////// //~ rjf: @os_hooks GUIDs (Implemented Per-OS) -internal OS_Guid +internal Guid os_make_guid(void) { - U8 random_bytes[16] = {0}; - StaticAssert(sizeof(random_bytes) == sizeof(OS_Guid), os_lnx_guid_size_check); - getrandom(random_bytes, sizeof(random_bytes), 0); - OS_Guid guid = {0}; - MemoryCopy(&guid, random_bytes, sizeof(random_bytes)); + Guid guid = {0}; + getrandom(guid.v, sizeof(guid.v), 0); guid.data3 &= 0x0fff; guid.data3 |= (4 << 12); guid.data4[0] &= 0x3f; @@ -1256,5 +1332,5 @@ main(int argc, char **argv) } //- rjf: call into "real" entry point - main_thread_base_entry_point(entry_point, argv, (U64)argc); + main_thread_base_entry_point(argc, argv); } diff --git a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.h b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.h index 531c6af3..e7d2ba5a 100644 --- a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.h +++ b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.h @@ -8,24 +8,27 @@ //~ rjf: Includes #define _GNU_SOURCE +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +pid_t gettid(void); int pthread_setname_np(pthread_t thread, const char *name); int pthread_getname_np(pthread_t thread, char *name, size_t size); diff --git a/src/metagen/metagen_os/core/metagen_os_core.c b/src/metagen/metagen_os/core/metagen_os_core.c index a6718e32..21a0a413 100644 --- a/src/metagen/metagen_os/core/metagen_os_core.c +++ b/src/metagen/metagen_os/core/metagen_os_core.c @@ -152,22 +152,89 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range) } //////////////////////////////// -//~ rjf: GUID Helpers (Helpers, Implemented Once) +//~ rjf: Process Launcher Helpers -internal String8 -os_string_from_guid(Arena *arena, OS_Guid guid) +internal OS_Handle +os_cmd_line_launch(String8 string) { - String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - guid.data1, - guid.data2, - guid.data3, - guid.data4[0], - guid.data4[1], - guid.data4[2], - guid.data4[3], - guid.data4[4], - guid.data4[5], - guid.data4[6], - guid.data4[7]); + Temp scratch = scratch_begin(0, 0); + U8 split_chars[] = {' '}; + String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0); + OS_Handle handle = {0}; + if(parts.node_count != 0) + { + // rjf: unpack exe part + String8 exe = parts.first->string; + String8 exe_folder = str8_chop_last_slash(exe); + if(exe_folder.size == 0) + { + exe_folder = os_get_current_path(scratch.arena); + } + + // rjf: find stdout delimiter + String8Node *stdout_delimiter_n = 0; + for(String8Node *n = parts.first; n != 0; n = n->next) + { + if(str8_match(n->string, str8_lit(">"), 0)) + { + stdout_delimiter_n = n; + break; + } + } + + // rjf: read stdout path + String8 stdout_path = {0}; + if(stdout_delimiter_n && stdout_delimiter_n->next) + { + stdout_path = stdout_delimiter_n->next->string; + } + + // rjf: open stdout handle + OS_Handle stdout_handle = {0}; + if(stdout_path.size != 0) + { + OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path); + os_file_close(file); + stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, stdout_path); + } + + // rjf: form command line + String8List cmdline = {0}; + for(String8Node *n = parts.first; n != stdout_delimiter_n && n != 0; n = n->next) + { + str8_list_push(scratch.arena, &cmdline, n->string); + } + + // rjf: launch + OS_ProcessLaunchParams params = {0}; + params.cmd_line = cmdline; + params.path = exe_folder; + params.inherit_env = 1; + params.stdout_file = stdout_handle; + handle = os_process_launch(¶ms); + + // rjf: close stdout handle + { + if(stdout_path.size != 0) + { + os_file_close(stdout_handle); + } + } + } + scratch_end(scratch); + return handle; +} + +internal OS_Handle +os_cmd_line_launchf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + OS_Handle result = os_cmd_line_launch(string); + va_end(args); + scratch_end(scratch); return result; } + diff --git a/src/metagen/metagen_os/core/metagen_os_core.h b/src/metagen/metagen_os/core/metagen_os_core.h index dcfb900d..e3a02048 100644 --- a/src/metagen/metagen_os/core/metagen_os_core.h +++ b/src/metagen/metagen_os/core/metagen_os_core.h @@ -24,6 +24,7 @@ typedef struct OS_ProcessInfo OS_ProcessInfo; struct OS_ProcessInfo { U32 pid; + B32 large_pages_allowed; String8 binary_path; String8 initial_path; String8 user_program_data_path; @@ -37,12 +38,13 @@ struct OS_ProcessInfo typedef U32 OS_AccessFlags; enum { - OS_AccessFlag_Read = (1<<0), - OS_AccessFlag_Write = (1<<1), - OS_AccessFlag_Execute = (1<<2), - OS_AccessFlag_Append = (1<<3), - OS_AccessFlag_ShareRead = (1<<4), - OS_AccessFlag_ShareWrite = (1<<5), + OS_AccessFlag_Read = (1<<0), + OS_AccessFlag_Write = (1<<1), + OS_AccessFlag_Execute = (1<<2), + OS_AccessFlag_Append = (1<<3), + OS_AccessFlag_ShareRead = (1<<4), + OS_AccessFlag_ShareWrite = (1<<5), + OS_AccessFlag_Inherited = (1<<6), }; //////////////////////////////// @@ -78,19 +80,6 @@ struct OS_FileID U64 v[3]; }; -//////////////////////////////// -//~ rjf: Process Launch Parameters - -typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams; -struct OS_ProcessLaunchParams -{ - String8List cmd_line; - String8 path; - String8List env; - B32 inherit_env; - B32 consoleless; -}; - //////////////////////////////// //~ rjf: Handle Type @@ -123,17 +112,21 @@ struct OS_HandleArray }; //////////////////////////////// -//~ rjf: Globally Unique IDs +//~ rjf: Process Launch Parameters -typedef struct OS_Guid OS_Guid; -struct OS_Guid +typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams; +struct OS_ProcessLaunchParams { - U32 data1; - U16 data2; - U16 data3; - U8 data4[8]; + String8List cmd_line; + String8 path; + String8List env; + B32 inherit_env; + B32 debug_subprocesses; + B32 consoleless; + OS_Handle stdout_file; + OS_Handle stderr_file; + OS_Handle stdin_file; }; -StaticAssert(sizeof(OS_Guid) == 16, os_guid_check); //////////////////////////////// //~ rjf: Thread Types @@ -165,16 +158,18 @@ internal S64 os_file_id_compare(OS_FileID a, OS_FileID b); internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range); //////////////////////////////// -//~ rjf: GUID Helpers (Helpers, Implemented Once) +//~ rjf: Process Launcher Helpers -internal String8 os_string_from_guid(Arena *arena, OS_Guid guid); +internal OS_Handle os_cmd_line_launch(String8 string); +internal OS_Handle os_cmd_line_launchf(char *fmt, ...); //////////////////////////////// //~ rjf: @os_hooks System/Process Info (Implemented Per-OS) -internal OS_SystemInfo *os_get_system_info(void); +internal OS_SystemInfo *os_get_system_info(void); internal OS_ProcessInfo *os_get_process_info(void); -internal String8 os_get_current_path(Arena *arena); +internal String8 os_get_current_path(Arena *arena); +internal U32 os_get_process_start_time_unix(void); //////////////////////////////// //~ rjf: @os_hooks Memory Allocation (Implemented Per-OS) @@ -207,14 +202,18 @@ internal void os_abort(S32 exit_code); internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path); internal void os_file_close(OS_Handle file); internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data); +#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr)) internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data); internal B32 os_file_set_times(OS_Handle file, DateTime time); internal FileProperties os_properties_from_file(OS_Handle file); internal OS_FileID os_id_from_file(OS_Handle file); +internal B32 os_file_reserve_size(OS_Handle file, U64 size); internal B32 os_delete_file_at_path(String8 path); internal B32 os_copy_file_path(String8 dst, String8 src); +internal B32 os_move_file_path(String8 dst, String8 src); internal String8 os_full_path_from_path(Arena *arena, String8 path); internal B32 os_file_path_exists(String8 path); +internal B32 os_folder_path_exists(String8 path); internal FileProperties os_properties_from_file_path(String8 path); //- rjf: file maps @@ -320,7 +319,7 @@ internal void os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *f //////////////////////////////// //~ rjf: @os_hooks GUIDs (Implemented Per-OS) -internal OS_Guid os_make_guid(void); +internal Guid os_make_guid(void); //////////////////////////////// //~ rjf: @os_hooks Entry Points (Implemented Per-OS) diff --git a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c index 876f0d91..6cc494f0 100644 --- a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c +++ b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.c @@ -90,6 +90,18 @@ os_w32_sleep_ms_from_endt_us(U64 endt_us) return sleep_ms; } +internal U32 +os_w32_unix_time_from_file_time(FILETIME file_time) +{ + U64 win32_time = ((U64)file_time.dwHighDateTime << 32) | file_time.dwLowDateTime; + U64 unix_time64 = ((win32_time - 0x19DB1DED53E8000ULL) / 10000000); + + Assert(unix_time64 <= max_U32); + U32 unix_time32 = (U32)unix_time64; + + return unix_time32; +} + //////////////////////////////// //~ rjf: Entity Functions @@ -167,6 +179,21 @@ os_get_current_path(Arena *arena) return name; } +internal U32 +os_get_process_start_time_unix(void) +{ + HANDLE handle = GetCurrentProcess(); + FILETIME start_time = {0}; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + if(GetProcessTimes(handle, &start_time, &exit_time, &kernel_time, &user_time)) + { + return os_w32_unix_time_from_file_time(start_time); + } + return 0; +} + //////////////////////////////// //~ rjf: @os_hooks Memory Allocation (Implemented Per-OS) @@ -293,14 +320,19 @@ os_file_open(OS_AccessFlags flags, String8 path) DWORD access_flags = 0; DWORD share_mode = 0; DWORD creation_disposition = OPEN_EXISTING; - if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;} - if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;} - if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;} - if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;} - if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;} - if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;} - if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS;} - HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, 0, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0); + SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0}; + if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;} + if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;} + if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;} + if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;} + if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;} + if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;} + if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; } + if(flags & OS_AccessFlag_Inherited) + { + security_attributes.bInheritHandle = 1; + } + HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, &security_attributes, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0); if(file != INVALID_HANDLE_VALUE) { result.u64[0] = (U64)file; @@ -361,27 +393,29 @@ os_file_write(OS_Handle file, Rng1U64 rng, void *data) HANDLE win_handle = (HANDLE)file.u64[0]; U64 src_off = 0; U64 dst_off = rng.min; - U64 bytes_to_write_total = rng.max-rng.min; - U64 total_bytes_written = 0; - for(;src_off < bytes_to_write_total;) + U64 total_write_size = dim_1u64(rng); + for(;;) { - void *bytes_src = (void *)((U8 *)data + src_off); - U64 bytes_to_write_64 = (bytes_to_write_total-src_off); - U32 bytes_to_write_32 = u32_from_u64_saturate(bytes_to_write_64); - U32 bytes_written = 0; + void *bytes_src = (U8 *)data + src_off; + U64 bytes_left = total_write_size - src_off; + DWORD write_size = Min(MB(1), bytes_left); + DWORD bytes_written = 0; OVERLAPPED overlapped = {0}; - overlapped.Offset = (dst_off&0x00000000ffffffffull); + overlapped.Offset = (dst_off&0x00000000ffffffffull); overlapped.OffsetHigh = (dst_off&0xffffffff00000000ull) >> 32; - BOOL success = WriteFile(win_handle, bytes_src, bytes_to_write_32, (DWORD *)&bytes_written, &overlapped); + BOOL success = WriteFile(win_handle, bytes_src, write_size, &bytes_written, &overlapped); if(success == 0) { break; } src_off += bytes_written; dst_off += bytes_written; - total_bytes_written += bytes_written; + if(bytes_left == 0) + { + break; + } } - return total_bytes_written; + return src_off; } internal B32 @@ -435,6 +469,19 @@ os_id_from_file(OS_Handle file) return result; } +internal B32 +os_file_reserve_size(OS_Handle file, U64 size) +{ + HANDLE handle = (HANDLE)file.u64[0]; + + FILE_ALLOCATION_INFO alloc_info = {0}; + alloc_info.AllocationSize.LowPart = size & max_U32; + alloc_info.AllocationSize.HighPart = (size >> 32) & max_U32; + + BOOL is_reserved = SetFileInformationByHandle(handle, FileAllocationInfo, &alloc_info, sizeof(alloc_info)); + return is_reserved; +} + internal B32 os_delete_file_at_path(String8 path) { @@ -456,15 +503,33 @@ os_copy_file_path(String8 dst, String8 src) return result; } +internal B32 +os_move_file_path(String8 dst, String8 src) +{ + Temp scratch = scratch_begin(0, 0); + String16 dst16 = str16_from_8(scratch.arena, dst); + String16 src16 = str16_from_8(scratch.arena, src); + B32 result = MoveFileW((WCHAR*)src16.str, (WCHAR*)dst16.str); + scratch_end(scratch); + return result; +} + internal String8 os_full_path_from_path(Arena *arena, String8 path) { Temp scratch = scratch_begin(&arena, 1); - DWORD buffer_size = MAX_PATH + 1; - U16 *buffer = push_array_no_zero(scratch.arena, U16, buffer_size); - String16 path16 = str16_from_8(scratch.arena, path); - DWORD path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, (WCHAR*)buffer, NULL); - String8 full_path = str8_from_16(arena, str16(buffer, path16_size)); + DWORD buffer_size = Max(MAX_PATH, path.size * 2) + 1; + String16 path16 = str16_from_8(scratch.arena, path); + WCHAR *buffer = push_array_no_zero(scratch.arena, WCHAR, buffer_size); + DWORD path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, buffer, NULL); + if(path16_size > buffer_size) + { + arena_pop(scratch.arena, buffer_size); + buffer_size = path16_size + 1; + buffer = push_array_no_zero(scratch.arena, WCHAR, buffer_size); + path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, buffer, NULL); + } + String8 full_path = str8_from_16(arena, str16((U16*)buffer, path16_size)); scratch_end(scratch); return full_path; } @@ -480,6 +545,17 @@ os_file_path_exists(String8 path) return exists; } +internal B32 +os_folder_path_exists(String8 path) +{ + Temp scratch = scratch_begin(0,0); + String16 path16 = str16_from_8(scratch.arena, path); + DWORD attributes = GetFileAttributesW((WCHAR *)path16.str); + B32 exists = (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY); + scratch_end(scratch); + return exists; +} + internal FileProperties os_properties_from_file_path(String8 path) { @@ -495,6 +571,28 @@ os_properties_from_file_path(String8 path) os_w32_dense_time_from_file_time(&props.modified, &find_data.ftLastWriteTime); props.flags = os_w32_file_property_flags_from_dwFileAttributes(find_data.dwFileAttributes); } + else + { + Temp scratch = scratch_begin(0, 0); + WCHAR buffer[512] = {0}; + DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer); + U64 last_slash_pos = 0; + for(;last_slash_pos < path.size; last_slash_pos = str8_find_needle(path, last_slash_pos+1, str8_lit("/"), StringMatchFlag_SlashInsensitive)); + String8 path_trimmed = str8_prefix(path, last_slash_pos); + for(U64 off = 0; off < (U64)length;) + { + String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off); + off += next_drive_string_16.size+1; + String8 next_drive_string = str8_from_16(scratch.arena, next_drive_string_16); + next_drive_string = str8_chop_last_slash(next_drive_string); + if(str8_match(path_trimmed, next_drive_string, StringMatchFlag_CaseInsensitive)) + { + props.flags |= FilePropertyFlag_IsFolder; + break; + } + } + scratch_end(scratch); + } FindClose(handle); scratch_end(scratch); return props; @@ -704,7 +802,12 @@ internal void os_file_iter_end(OS_FileIter *iter) { OS_W32_FileIter *w32_iter = (OS_W32_FileIter*)iter->memory; - FindClose(w32_iter->handle); + HANDLE zero_handle; + MemoryZeroStruct(&zero_handle); + if(!MemoryMatchStruct(&zero_handle, &w32_iter->handle)) + { + FindClose(w32_iter->handle); + } } //- rjf: directory creation @@ -805,10 +908,8 @@ os_now_unix(void) { FILETIME file_time; GetSystemTimeAsFileTime(&file_time); - U64 win32_time = ((U64)file_time.dwHighDateTime << 32) | file_time.dwLowDateTime; - U64 unix_time64 = ((win32_time - 0x19DB1DED53E8000ULL) / 10000000); - U32 unix_time32 = (U32)unix_time64; - return unix_time32; + U32 unix_time = os_w32_unix_time_from_file_time(file_time); + return unix_time; } internal DateTime @@ -926,9 +1027,31 @@ os_process_launch(OS_ProcessLaunchParams *params) } //- rjf: launch + BOOL inherit_handles = 0; STARTUPINFOW startup_info = {sizeof(startup_info)}; + if(!os_handle_match(params->stdout_file, os_handle_zero())) + { + HANDLE stdout_handle = (HANDLE)params->stdout_file.u64[0]; + startup_info.hStdOutput = stdout_handle; + startup_info.dwFlags |= STARTF_USESTDHANDLES; + inherit_handles = 1; + } + if(!os_handle_match(params->stderr_file, os_handle_zero())) + { + HANDLE stderr_handle = (HANDLE)params->stderr_file.u64[0]; + startup_info.hStdError = stderr_handle; + startup_info.dwFlags |= STARTF_USESTDHANDLES; + inherit_handles = 1; + } + if(!os_handle_match(params->stdin_file, os_handle_zero())) + { + HANDLE stdin_handle = (HANDLE)params->stdin_file.u64[0]; + startup_info.hStdInput = stdin_handle; + startup_info.dwFlags |= STARTF_USESTDHANDLES; + inherit_handles = 1; + } PROCESS_INFORMATION process_info = {0}; - if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 0, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) + if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, inherit_handles, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) { result.u64[0] = (U64)process_info.hProcess; CloseHandle(process_info.hThread); @@ -977,8 +1100,9 @@ os_thread_join(OS_Handle handle, U64 endt_us) if(entity != 0) { wait_result = WaitForSingleObject(entity->thread.handle, sleep_ms); + CloseHandle(entity->thread.handle); + os_w32_entity_release(entity); } - os_w32_entity_release(entity); return (wait_result == WAIT_OBJECT_0); } @@ -986,7 +1110,11 @@ internal void os_thread_detach(OS_Handle thread) { OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(thread.u64[0]); - os_w32_entity_release(entity); + if(entity != 0) + { + CloseHandle(entity->thread.handle); + os_w32_entity_release(entity); + } } //////////////////////////////// @@ -1255,10 +1383,10 @@ os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, v //////////////////////////////// //~ rjf: @os_hooks GUIDs (Implemented Per-OS) -internal OS_Guid +internal Guid os_make_guid(void) { - OS_Guid result; MemoryZeroStruct(&result); + Guid result; MemoryZeroStruct(&result); UUID uuid; RPC_STATUS rpc_status = UuidCreate(&uuid); if(rpc_status == RPC_S_OK) @@ -1344,8 +1472,12 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) HANDLE thread = GetCurrentThread(); CONTEXT* context = exception_ptrs->ContextRecord; + WCHAR module_path[MAX_PATH]; + GetModuleFileNameW(NULL, module_path, ArrayCount(module_path)); + PathRemoveFileSpecW(module_path); + dbg_SymSetOptions(SYMOPT_EXACT_SYMBOLS | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); - if(dbg_SymInitializeW(process, L"", TRUE)) + if(dbg_SymInitializeW(process, module_path, TRUE)) { // check that raddbg.pdb file is good B32 raddbg_pdb_valid = 0; @@ -1384,7 +1516,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) frame.AddrStack.Offset = context->Sp; frame.AddrStack.Mode = AddrModeFlat; #else -# error Architecture not supported! +# error Arch not supported! #endif for(U32 idx=0; ;idx++) @@ -1488,129 +1620,60 @@ w32_entry_point_caller(int argc, WCHAR **wargv) { SetUnhandledExceptionFilter(&win32_exception_filter); - //- rjf: do OS layer initialization + //- rjf: dynamically load windows functions which are not guaranteed + // in all SDKs { - // rjf: dynamically load windows functions which are not guaranteed - // in all SDKs + HMODULE module = LoadLibraryA("kernel32.dll"); + w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription"); + FreeLibrary(module); + } + + //- rjf: try to allow large pages if we can + B32 large_pages_allowed = 0; + { + HANDLE token; + if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - HMODULE module = LoadLibraryA("kernel32.dll"); - w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription"); - FreeLibrary(module); - } - - // rjf: try to enable large pages if we can - { - HANDLE token; - if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) + LUID luid; + if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) { - LUID luid; - if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) - { - TOKEN_PRIVILEGES priv; - priv.PrivilegeCount = 1; - priv.Privileges[0].Luid = luid; - priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0); - } - CloseHandle(token); + TOKEN_PRIVILEGES priv; + priv.PrivilegeCount = 1; + priv.Privileges[0].Luid = luid; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + large_pages_allowed = !!AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0); } + CloseHandle(token); } - - // rjf: get system info - SYSTEM_INFO sysinfo = {0}; - GetSystemInfo(&sysinfo); - - // rjf: set up non-dynamically-alloc'd state - // - // (we need to set up some basics before this layer can supply - // memory allocation primitives) + } + + //- rjf: get system info + SYSTEM_INFO sysinfo = {0}; + GetSystemInfo(&sysinfo); + + //- rjf: set up non-dynamically-alloc'd state + // + // (we need to set up some basics before this layer can supply + // memory allocation primitives) + { + os_w32_state.microsecond_resolution = 1; + LARGE_INTEGER large_int_resolution; + if(QueryPerformanceFrequency(&large_int_resolution)) { - os_w32_state.microsecond_resolution = 1; - LARGE_INTEGER large_int_resolution; - if(QueryPerformanceFrequency(&large_int_resolution)) - { - os_w32_state.microsecond_resolution = large_int_resolution.QuadPart; - } + os_w32_state.microsecond_resolution = large_int_resolution.QuadPart; } - { - OS_SystemInfo *info = &os_w32_state.system_info; - info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors; - info->page_size = sysinfo.dwPageSize; - info->large_page_size = GetLargePageMinimum(); - info->allocation_granularity = sysinfo.dwAllocationGranularity; - } - { - OS_ProcessInfo *info = &os_w32_state.process_info; - info->pid = GetCurrentProcessId(); - } - - // rjf: set up thread context - local_persist TCTX tctx; - tctx_init_and_equip(&tctx); - - // rjf: set up dynamically-alloc'd state - Arena *arena = arena_alloc(); - { - os_w32_state.arena = arena; - { - OS_SystemInfo *info = &os_w32_state.system_info; - U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0}; - DWORD size = MAX_COMPUTERNAME_LENGTH + 1; - if(GetComputerNameA((char*)buffer, &size)) - { - info->machine_name = push_str8_copy(arena, str8(buffer, size)); - } - } - } - { - OS_ProcessInfo *info = &os_w32_state.process_info; - { - Temp scratch = scratch_begin(0, 0); - DWORD size = KB(32); - U16 *buffer = push_array_no_zero(scratch.arena, U16, size); - DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size); - String8 name8 = str8_from_16(scratch.arena, str16(buffer, length)); - String8 name_chopped = str8_chop_last_slash(name8); - info->binary_path = push_str8_copy(arena, name_chopped); - scratch_end(scratch); - } - info->initial_path = os_get_current_path(arena); - { - Temp scratch = scratch_begin(0, 0); - U64 size = KB(32); - U16 *buffer = push_array_no_zero(scratch.arena, U16, size); - if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer))) - { - info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer)); - } - scratch_end(scratch); - } - { - WCHAR *this_proc_env = GetEnvironmentStringsW(); - U64 start_idx = 0; - for(U64 idx = 0;; idx += 1) - { - if(this_proc_env[idx] == 0) - { - if(start_idx == idx) - { - break; - } - else - { - String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); - String8 string = str8_from_16(arena, string16); - str8_list_push(arena, &info->environment, string); - start_idx = idx+1; - } - } - } - } - } - - // rjf: set up entity storage - InitializeCriticalSection(&os_w32_state.entity_mutex); - os_w32_state.entity_arena = arena_alloc(); + } + { + OS_SystemInfo *info = &os_w32_state.system_info; + info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors; + info->page_size = sysinfo.dwPageSize; + info->large_page_size = GetLargePageMinimum(); + info->allocation_granularity = sysinfo.dwAllocationGranularity; + } + { + OS_ProcessInfo *info = &os_w32_state.process_info; + info->large_pages_allowed = large_pages_allowed; + info->pid = GetCurrentProcessId(); } //- rjf: extract arguments @@ -1620,13 +1683,89 @@ w32_entry_point_caller(int argc, WCHAR **wargv) { String16 arg16 = str16_cstring((U16 *)wargv[i]); String8 arg8 = str8_from_16(args_arena, arg16); - if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive)) + if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive) || + str8_match(arg8, str8_lit("-quiet"), StringMatchFlag_CaseInsensitive)) { win32_g_is_quiet = 1; } + if(str8_match(arg8, str8_lit("--large_pages"), StringMatchFlag_CaseInsensitive) || + str8_match(arg8, str8_lit("-large_pages"), StringMatchFlag_CaseInsensitive)) + { + arena_default_flags = ArenaFlag_LargePages; + arena_default_reserve_size = Max(MB(64), os_w32_state.system_info.large_page_size); + arena_default_commit_size = arena_default_reserve_size; + } argv[i] = (char *)arg8.str; } + //- rjf: set up thread context + local_persist TCTX tctx; + tctx_init_and_equip(&tctx); + + //- rjf: set up dynamically-alloc'd state + Arena *arena = arena_alloc(); + { + os_w32_state.arena = arena; + { + OS_SystemInfo *info = &os_w32_state.system_info; + U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0}; + DWORD size = MAX_COMPUTERNAME_LENGTH + 1; + if(GetComputerNameA((char*)buffer, &size)) + { + info->machine_name = push_str8_copy(arena, str8(buffer, size)); + } + } + } + { + OS_ProcessInfo *info = &os_w32_state.process_info; + { + Temp scratch = scratch_begin(0, 0); + DWORD size = KB(32); + U16 *buffer = push_array_no_zero(scratch.arena, U16, size); + DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size); + String8 name8 = str8_from_16(scratch.arena, str16(buffer, length)); + String8 name_chopped = str8_chop_last_slash(name8); + info->binary_path = push_str8_copy(arena, name_chopped); + scratch_end(scratch); + } + info->initial_path = os_get_current_path(arena); + { + Temp scratch = scratch_begin(0, 0); + U64 size = KB(32); + U16 *buffer = push_array_no_zero(scratch.arena, U16, size); + if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer))) + { + info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer)); + } + scratch_end(scratch); + } + { + WCHAR *this_proc_env = GetEnvironmentStringsW(); + U64 start_idx = 0; + for(U64 idx = 0;; idx += 1) + { + if(this_proc_env[idx] == 0) + { + if(start_idx == idx) + { + break; + } + else + { + String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); + String8 string = str8_from_16(arena, string16); + str8_list_push(arena, &info->environment, string); + start_idx = idx+1; + } + } + } + } + } + + //- rjf: set up entity storage + InitializeCriticalSection(&os_w32_state.entity_mutex); + os_w32_state.entity_arena = arena_alloc(); + //- rjf: call into "real" entry point main_thread_base_entry_point(argc, argv); } diff --git a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.h b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.h index a8c031fd..9a8f0d12 100644 --- a/src/metagen/metagen_os/core/win32/metagen_os_core_win32.h +++ b/src/metagen/metagen_os/core/win32/metagen_os_core_win32.h @@ -7,7 +7,6 @@ //////////////////////////////// //~ rjf: Includes / Libraries -#define WIN32_LEAN_AND_MEAN #include #include #include diff --git a/src/metagen/metagen_os/metagen_os_inc.h b/src/metagen/metagen_os/metagen_os_inc.h index f8c8e06c..b2d96f02 100644 --- a/src/metagen/metagen_os/metagen_os_inc.h +++ b/src/metagen/metagen_os/metagen_os_inc.h @@ -8,10 +8,6 @@ # define OS_FEATURE_GRAPHICAL 0 #endif -#if !defined(OS_GFX_STUB) -# define OS_GFX_STUB 0 -#endif - #include "metagen/metagen_os/core/metagen_os_core.h" #if OS_WINDOWS diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index bfd12c55..6cc494f0 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -473,11 +473,11 @@ internal B32 os_file_reserve_size(OS_Handle file, U64 size) { HANDLE handle = (HANDLE)file.u64[0]; - + FILE_ALLOCATION_INFO alloc_info = {0}; alloc_info.AllocationSize.LowPart = size & max_U32; alloc_info.AllocationSize.HighPart = (size >> 32) & max_U32; - + BOOL is_reserved = SetFileInformationByHandle(handle, FileAllocationInfo, &alloc_info, sizeof(alloc_info)); return is_reserved; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index becfdf4e..a44b4bfd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4335,6 +4335,9 @@ rd_view_ui(Rng2F32 rect) // rjf: commit edited cell string switch(cell->kind) { + case RD_WatchCellKind_ViewUI: + case RD_WatchCellKind_CallStackFrame: + {}break; case RD_WatchCellKind_Expr: { RD_Cfg *cfg = row_info.group_cfg_child; @@ -10269,7 +10272,7 @@ rd_window_frame(void) } // rjf: draw sides - if(b->flags & UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight) + if(b->flags & (UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight)) { Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 r = b->rect; From 42e888d41eda07d5dda243d2943f9f3a01ffc5f9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 25 Mar 2025 16:57:33 -0700 Subject: [PATCH 248/755] fix breakpad converter build --- src/lib_rdi_format/rdi_format_parse.c | 4 ++-- src/lib_rdi_format/rdi_format_parse.h | 2 +- src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index 7ce26cc4..6f51204d 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -815,7 +815,7 @@ rdi_cstring_length(char *cstr) } RDI_PROC RDI_U64 -rdi_size_from_bytecode_stream(U8 *ptr, U8 *opl) +rdi_size_from_bytecode_stream(RDI_U8 *ptr, RDI_U8 *opl) { RDI_U64 bytecode_size = 0; RDI_U8 *off_first = ptr + sizeof(RDI_LocationKind); @@ -826,7 +826,7 @@ rdi_size_from_bytecode_stream(U8 *ptr, U8 *opl) { break; } - + RDI_U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; RDI_U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); bytecode_size += (1 + p_size); diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 455b7eb2..1e82e501 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -225,6 +225,6 @@ RDI_PROC RDI_U8 *rdi_name_from_file_path_node(RDI_Parsed *rdi, RDI_FilePathNode #define rdi_parse__min(a,b) (((a)<(b))?(a):(b)) RDI_PROC RDI_U64 rdi_cstring_length(char *cstr); -RDI_PROC RDI_U64 rdi_size_from_bytecode_stream(U8 *ptr, U8 *opl); +RDI_PROC RDI_U64 rdi_size_from_bytecode_stream(RDI_U8 *ptr, RDI_U8 *opl); #endif // RDI_FORMAT_PARSE_H diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index f3c72e7e..fb5bdf9c 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -23,6 +23,7 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" #include "coff/coff.h" #include "coff/coff_parse.h" #include "codeview/codeview.h" @@ -40,6 +41,7 @@ #include "os/os_inc.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" #include "coff/coff.c" #include "coff/coff_parse.c" #include "codeview/codeview.c" From 29d430ca6c9cc1321ab426e1fd92ee9d43006de9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 10:00:49 -0700 Subject: [PATCH 249/755] dial back use of hand hover cursor --- src/raddbg/raddbg_core.c | 7 ------- src/raddbg/raddbg_widgets.c | 12 ------------ src/ui/ui_basic_widgets.c | 5 +---- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a44b4bfd..03ff2988 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5302,7 +5302,6 @@ rd_view_ui(Rng2F32 rect) ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) UI_CornerRadius(ui_top_font_size()*1.5f) UI_TextAlignment(UI_TextAlign_Center) - UI_HoverCursor(OS_Cursor_HandPoint) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.8f) { @@ -8572,7 +8571,6 @@ rd_window_frame(void) { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *user_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| @@ -8606,7 +8604,6 @@ rd_window_frame(void) { ui_set_next_pref_width(ui_children_sum(1)); ui_set_next_child_layout_axis(Axis2_X); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *prof_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| @@ -9644,7 +9641,6 @@ rd_window_frame(void) { ui_spacer(ui_px(1.f, 1.f)); } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| @@ -9671,7 +9667,6 @@ rd_window_frame(void) UI_CornerRadius00(0) UI_CornerRadius01(0) { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *close_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| @@ -9745,7 +9740,6 @@ rd_window_frame(void) { ui_spacer(ui_px(1.f, 1.f)); } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_group_key(catchall_drop_site_key); UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawBackground| @@ -9786,7 +9780,6 @@ rd_window_frame(void) UI_FontSize(ui_top_font_size()) UI_TagF("implicit") UI_TagF("weak") - UI_HoverCursor(OS_Cursor_HandPoint) { UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_DrawBorder| diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 3537a855..b88ebf2f 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -729,7 +729,6 @@ rd_cmd_binding_buttons(String8 name) //- rjf: build box ui_set_next_tag(has_conflicts ? str8_lit("bad_pop") : rebinding_active_for_this_binding ? str8_lit("pop") : str8_zero()); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); @@ -803,7 +802,6 @@ rd_cmd_binding_buttons(String8 name) rd_state->bind_change_binding_id == 0); RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); @@ -837,7 +835,6 @@ rd_cmd_binding_buttons(String8 name) internal UI_Signal rd_menu_bar_button(String8 string) { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable|UI_BoxFlag_DrawHotEffects, string); UI_Signal sig = ui_signal_from_box(box); return sig; @@ -847,7 +844,6 @@ internal UI_Signal rd_cmd_spec_button(String8 name) { RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(name); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_child_layout_axis(Axis2_X); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground| @@ -914,7 +910,6 @@ internal UI_Signal rd_icon_button(RD_IconKind kind, FuzzyMatchRangeList *matches, String8 string) { String8 display_string = ui_display_part_from_key_string(string); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_child_layout_axis(Axis2_X); UI_Box *box = ui_build_box_from_string(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBorder| @@ -1609,7 +1604,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font(rd_font_from_slot(RD_FontSlot_Icons)); ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_text_color(bp_rgba); UI_Box *bp_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| @@ -1669,7 +1663,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_set_next_font(rd_font_from_slot(RD_FontSlot_Icons)); ui_set_next_font_size(params->font_size * 1.f); ui_set_next_text_raster_flags(FNT_RasterFlag_Smooth); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_text_color(color); UI_Box *pin_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| @@ -3099,10 +3092,6 @@ rd_cell(RD_CellParams *params, String8 string) { ui_set_next_hover_cursor(OS_Cursor_IBar); } - if(params->flags & RD_CellFlag_Button) - { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| @@ -3184,7 +3173,6 @@ rd_cell(RD_CellParams *params, String8 string) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) UI_TagF(is_toggled ? "good_pop" : "") { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); UI_Parent(switch_box) { diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 09cf9a42..12e86b0f 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -70,7 +70,6 @@ ui_label_multilinef(F32 max, char *fmt, ...) internal UI_Signal ui_button(String8 string) { - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *box = ui_build_box_from_string(UI_BoxFlag_Clickable| UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| @@ -181,7 +180,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); //- rjf: build top-level box - ui_set_next_hover_cursor(is_focus_active ? OS_Cursor_IBar : OS_Cursor_HandPoint); + ui_set_next_hover_cursor(is_focus_active ? OS_Cursor_IBar : OS_Cursor_Pointer); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawBorder| UI_BoxFlag_MouseClickable| @@ -1258,7 +1257,6 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran if(idx_range.max != idx_range.min) { ui_set_next_pref_size(axis, ui_pct((F32)((F64)(pt.idx-idx_range.min)/(F64)idx_range_dim), 0)); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *space_before_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "##scroll_area_before"); space_before_sig = ui_signal_from_box(space_before_box); } @@ -1274,7 +1272,6 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran if(idx_range.max != idx_range.min) { ui_set_next_pref_size(axis, ui_pct(1.f - (F32)((F64)(pt.idx-idx_range.min)/(F64)idx_range_dim), 0)); - ui_set_next_hover_cursor(OS_Cursor_HandPoint); UI_Box *space_after_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "##scroll_area_after"); space_after_sig = ui_signal_from_box(space_after_box); } From bd35ea83fc06509ec85573eb52cb43c780b6a464 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 11:38:32 -0700 Subject: [PATCH 250/755] support for raddbg_pin markup on-the-fly watch pin annotations --- src/mule/mule_main.cpp | 7 +- src/raddbg/generated/raddbg.meta.c | 8 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 3 +- src/raddbg/raddbg_core.c | 22 ++++- src/raddbg/raddbg_widgets.c | 154 ++++++++++++++++++++++------- 6 files changed, 142 insertions(+), 55 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 54c38c44..4742f35f 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -328,6 +328,7 @@ type_coverage_eval_tests(void) raddbg_pin(basics); raddbg_pin(fixed); raddbg_pin(pointer); + raddbg_pin(dynamic, slice); Struct_With_Embedded_Arrays swea = {0}; { @@ -1642,8 +1643,8 @@ fancy_viz_eval_tests(void) "}\n\n"); int x1 = 0; raddbg_pin(long_string, "text"); - raddbg_pin(code_string, "text: (lang:c)"); - raddbg_pin(fancy_viz_eval_tests, "disasm: (arch:x64)"); + raddbg_pin(code_string, "text(lang=c)"); + raddbg_pin(fancy_viz_eval_tests, "disasm"); //- rjf: bitmaps unsigned int background_color = 0x00000000; @@ -1892,7 +1893,7 @@ fancy_viz_eval_tests(void) 136, 137, 138, 138, 139, 136, 140, 141, 142, 142, 143, 140, 144, 145, 146, 146, 147, 144, 148, 149, 150, 150, 151, 148, 152, 153, 154, 154, 155, 152, 156, 157, 158, 158, 159, 156, 160, 161, 162, 162, 163, 160, 164, 165, 166, 166, 167, 164, }; - raddbg_pin(index_data, "geo3d: { count:(sizeof index_data/4), vtx:(vertex_data), vtx_size:(sizeof vertex_data) }"); + raddbg_pin(index_data, "geo3d(count = (sizeof index_data/4), vtx = (vertex_data), vtx_size = (sizeof vertex_data))"); int x3 = 0; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 580643ca..0e0c1425 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[308] = +RD_VocabInfo rd_vocab_info_table[307] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -267,7 +267,6 @@ RD_VocabInfo rd_vocab_info_table[308] = {str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, -{str8_lit_comp("add_function_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, @@ -324,7 +323,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, @@ -382,7 +381,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[216] = +RD_CmdKindInfo rd_cmd_kind_info_table[215] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -553,7 +552,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[216] = { str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 079f6938..1839748b 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -224,7 +224,6 @@ RD_CmdKind_DuplicateCfg, RD_CmdKind_RelocateCfg, RD_CmdKind_AddBreakpoint, RD_CmdKind_AddAddressBreakpoint, -RD_CmdKind_AddFunctionBreakpoint, RD_CmdKind_ToggleBreakpoint, RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, @@ -645,7 +644,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[308]; +extern RD_VocabInfo rd_vocab_info_table[307]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4a74ce1a..e535d07d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -241,7 +241,7 @@ RD_VocabTable: breakpoint, ``` @commands(enable_cfg, remove_cfg) - @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint) + @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint) x: { 'label': code_string, @@ -614,7 +614,6 @@ RD_CmdTable: // | | | | //- rjf: breakpoints {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } {AddAddressBreakpoint 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {AddFunctionBreakpoint 1 0 "query:procedures" Expr symbol_lister Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address(es) of the specified function." "" "$breakpoints," } {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 03ff2988..4100c2df 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10047,12 +10047,17 @@ rd_window_frame(void) // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { + B32 is_hot = ui_key_match(box->key, ui_hot_key()); Vec4F32 hover_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); // rjf: brighten { Vec4F32 color = hover_color; - color.w *= t*0.05f; + color.w *= 0.05f; + if(!is_hot) + { + color.w *= t; + } R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; @@ -10063,7 +10068,11 @@ rd_window_frame(void) if(box->hot_t > 0.01f) DR_ClipScope(box->rect) { Vec4F32 color = hover_color; - color.w *= 0.02f*t; + color.w *= 0.02f; + if(!is_hot) + { + color.w *= t; + } Vec2F32 center = ui_mouse(); Vec2F32 box_dim = dim_2f32(box->rect); F32 max_dim = Max(box_dim.x, box_dim.y); @@ -10249,7 +10258,10 @@ rd_window_frame(void) if(b->flags & UI_BoxFlag_DrawHotEffects) { Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); - color.w *= b->hot_t; + if(!ui_key_match(b->key, ui_hot_key())) + { + color.w *= b->hot_t; + } R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; inst->colors[Corner_11].w *= 0.2f; @@ -16322,7 +16334,8 @@ Z(getting_started) case RD_CmdKind_DeselectCfg: { RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); - rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("enabled"))); + RD_Cfg *enabled_root = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("enabled")); + rd_cfg_new_replacef(enabled_root, "0"); }break; case RD_CmdKind_RemoveCfg: { @@ -16441,7 +16454,6 @@ Z(getting_started) } }break; case RD_CmdKind_AddAddressBreakpoint: - case RD_CmdKind_AddFunctionBreakpoint: { rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero()); }break; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b88ebf2f..b7725900 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1872,57 +1872,135 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num < params->line_num_range.max; line_num += 1, line_idx += 1) { - RD_CfgList pins = params->line_pins[line_idx]; - if(pins.count != 0) UI_Parent(line_extras_boxes[line_idx]) - RD_Font(RD_FontSlot_Code) - UI_FontSize(params->font_size) - UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + RD_CfgList immediate_pins = {0}; + String8 line_text = params->line_text[line_idx]; + for(U64 off = 0, next_off = line_text.size; + off < line_text.size; + off = next_off) { - for(RD_CfgNode *n = pins.first; n != 0; n = n->next) + // rjf: find next opener + String8 markup_opener = str8_lit("raddbg_pin("); + next_off = str8_find_needle(line_text, off, markup_opener, 0); + next_off += markup_opener.size; + + // rjf: extract contents of markup + String8 contents = {0}; + S32 nest = 1; + for(U64 off2 = next_off; off2 < line_text.size; off2 += 1) { - RD_Cfg *pin = n->v; - String8 pin_expr = rd_expr_from_cfg(pin); - String8 pin_view_rule = rd_view_rule_from_cfg(pin); - String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); - E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); - String8 eval_string = {0}; - if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) + if(line_text.str[off2] == '(') { - eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); + nest += 1; } - ui_spacer(ui_em(1.5f, 1.f)); - ui_set_next_pref_width(ui_children_sum(1)); - UI_Key pin_box_key = ui_key_from_stringf(ui_key_zero(), "###pin_%p", pin); - UI_Box *pin_box = ui_build_box_from_key(UI_BoxFlag_AnimatePos| - UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBorder, pin_box_key); - UI_Parent(pin_box) UI_PrefWidth(ui_text_dim(10, 1)) + else if(line_text.str[off2] == ')') { - Vec4F32 pin_color = rd_color_from_cfg(pin); - if(pin_color.w == 0) + nest -= 1; + if(nest == 0) { - pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + contents = str8_substr(line_text, r1u64(next_off, off2)); + break; } - UI_PrefWidth(ui_em(1.5f, 1.f)) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - UI_Flags(UI_BoxFlag_DisableTextTrunc) - UI_TextColor(pin_color) + } + } + + // rjf: gather arguments + String8List args = {0}; + { + S32 nest = 0; + U64 arg_start_off = 0; + for(U64 contents_off = 0; contents_off <= contents.size; contents_off += 1) + { + if(contents_off == contents.size || contents.str[contents_off] == ',') { - UI_Signal sig = ui_buttonf("%S###pin_nub", rd_icon_kind_text_table[RD_IconKind_Pin]); - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + String8 arg = str8_substr(contents, r1u64(arg_start_off, contents_off)); + str8_list_push(scratch.arena, &args, arg); + arg_start_off = contents_off+1; + } + if(contents_off < contents.size) + { + if(contents.str[contents_off] == '(') { - RD_RegsScope(.cfg = pin->id) rd_drag_begin(RD_RegSlot_Cfg); + nest += 1; + } + else if(contents.str[contents_off] == ')') + { + nest -= 1; } } - rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); - rd_code_label(0.6f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), eval_string); } - UI_Signal pin_sig = ui_signal_from_box(pin_box); - if(ui_key_match(pin_box_key, ui_hot_key())) + } + + // rjf: extract fixed arguments + String8 expr_string = {0}; + String8 view_rule_string = {0}; + if(args.first != 0) + { + expr_string = args.first->string; + } + if(args.first->next != 0) + { + view_rule_string = args.first->next->string; + } + + // rjf: build immediate pin for this markup + if(expr_string.size != 0) + { + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("markup_pin_%I64x_%I64x", line_num, off); + RD_Cfg *pin = rd_cfg_child_from_string_or_alloc(immediate_root, str8_lit("watch_pin")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(pin, str8_lit("expression")); + RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(pin, str8_lit("view_rule")); + rd_cfg_new_replace(expr, expr_string); + rd_cfg_new_replace(view_rule, view_rule_string); + rd_cfg_list_push(scratch.arena, &immediate_pins, pin); + } + } + RD_CfgList pin_lists[] = + { + params->line_pins[line_idx], + immediate_pins, + }; + for EachElement(list_idx, pin_lists) + { + RD_CfgList pins = pin_lists[list_idx]; + if(pins.count != 0) UI_Parent(line_extras_boxes[line_idx]) + RD_Font(RD_FontSlot_Code) + UI_FontSize(params->font_size) + UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + { + for(RD_CfgNode *n = pins.first; n != 0; n = n->next) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr, pin_view_rule); + RD_Cfg *pin = n->v; + String8 pin_expr = rd_expr_from_cfg(pin); + String8 pin_view_rule = rd_view_rule_from_cfg(pin); + String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); + E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); + String8 eval_string = {0}; + if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) + { + eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); + } + ui_spacer(ui_em(1.5f, 1.f)); + ui_set_next_pref_width(ui_children_sum(1)); + UI_Key pin_box_key = ui_key_from_stringf(ui_key_zero(), "###pin_%p", pin); + UI_Box *pin_box = ui_build_box_from_key(UI_BoxFlag_AnimatePos| + UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBorder, pin_box_key); + UI_Parent(pin_box) UI_PrefWidth(ui_text_dim(10, 1)) + { + Vec4F32 pin_color = rd_color_from_cfg(pin); + if(pin_color.w == 0) + { + pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + } + rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); + rd_code_label(0.6f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), eval_string); + } + UI_Signal pin_sig = ui_signal_from_box(pin_box); + if(ui_key_match(pin_box_key, ui_hot_key())) + { + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr, pin_view_rule); + } } } } From 48f0702e058a1113ec483a8c74360f91716f69e9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 11:49:15 -0700 Subject: [PATCH 251/755] fix source markup parsing, release notes for source-defined watch annotations --- src/mule/mule_main.cpp | 8 ++++---- src/raddbg/raddbg_main.c | 14 ++++++++++++-- src/raddbg/raddbg_widgets.c | 3 ++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 4742f35f..81eb08df 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1642,9 +1642,9 @@ fancy_viz_eval_tests(void) " return 0;\n" "}\n\n"); int x1 = 0; - raddbg_pin(long_string, "text"); - raddbg_pin(code_string, "text(lang=c)"); - raddbg_pin(fancy_viz_eval_tests, "disasm"); + raddbg_pin(long_string, text); + raddbg_pin(code_string, text(lang=c)); + raddbg_pin(fancy_viz_eval_tests, disasm); //- rjf: bitmaps unsigned int background_color = 0x00000000; @@ -1676,7 +1676,7 @@ fancy_viz_eval_tests(void) bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, }; - raddbg_pin(bitmap, "bitmap:(w:18, h:18)"); + raddbg_pin(bitmap, bitmap(18, 18)); for(int i = 0; i < sizeof(bitmap)/sizeof(bitmap[0]); i += 1) { unsigned int r = bitmap[i]&0x000000ff; diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 28bc4b75..6e1f9ec3 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -35,11 +35,21 @@ // common case is debugging a small number of programs, usually 1, and for // those purposes, the `Threads` view is sufficient if not desirable, and // the extra information provided by `Processes` and `Machines`, while useful -// in other contexts, is not useful in that common case. +// in other contexts, is not useful in that common case. The `Machines` view +// now shows a superset of the information previosuly found in the +// `Scheduler` view. // - The two separate interfaces for editing threads, breakpoints, and watch // pins (the right-click context menu and the dedicated tabs) have been // merged. -// - Added the ability to add per-target environment strings. +// - Added the ability to add a list environment strings to targets. +// - Added support for watch annotations derived from source code markup, +// rather than only from configuration. Instances of +// `raddbg_pin(, )` will be parsed, and used to create watch +// annotations inline with source code, in the same way that watch pins do. +// For instance, `raddbg_pin(dynamic_array, slice)` will visualize +// `dynamic_array` with a `slice` view rule; +// `raddbg_pin(some_function, disasm)` will visualize `some_function` as +// disassembly; and so on. // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b7725900..193f6396 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1910,9 +1910,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 arg_start_off = 0; for(U64 contents_off = 0; contents_off <= contents.size; contents_off += 1) { - if(contents_off == contents.size || contents.str[contents_off] == ',') + if(nest == 0 && (contents_off == contents.size || contents.str[contents_off] == ',')) { String8 arg = str8_substr(contents, r1u64(arg_start_off, contents_off)); + arg = str8_skip_chop_whitespace(arg); str8_list_push(scratch.arena, &args, arg); arg_start_off = contents_off+1; } From 0c3a37af446fd354945a34bf863d505cc9173474 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 20:37:00 -0700 Subject: [PATCH 252/755] helper for extracting GNU debug link info --- src/elf/elf_parse.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ src/elf/elf_parse.h | 7 ++++++ 2 files changed, 60 insertions(+) diff --git a/src/elf/elf_parse.c b/src/elf/elf_parse.c index 22bb47be..ebd58bfd 100644 --- a/src/elf/elf_parse.c +++ b/src/elf/elf_parse.c @@ -88,3 +88,56 @@ elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr) return result; } +internal String8 +elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr) +{ + String8 sh_names = str8_substr(raw_data, sh_name_range); + String8 name = {0}; + str8_deserial_read_cstr(sh_names, shdr->sh_name, &name); + return name; +} + +internal U64 +elf_base_addr_from_bin(ELF_Hdr64 *hdr) +{ + NotImplemented; + return 0; +} + +internal B32 +elf_parse_debug_link(String8 raw_data, ELF_BinInfo *elf, ELF_GnuDebugLink *debug_link_out) +{ + Temp scratch = scratch_begin(0,0); + + B32 is_debug_link_present = 0; + ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_data, &elf->hdr); + for (U64 i = 0; i < sections.count; ++i) { + ELF_Shdr64 *shdr = §ions.v[i]; + String8 name = elf_name_from_shdr64(raw_data, &elf->hdr, elf->sh_name_range, shdr); + + if (str8_match(name, str8_lit(".gnu_debuglink"), 0)) { + Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size); + String8 data = str8_substr(raw_data, raw_data_range); + + String8 path = {0}; + U32 checksum = 0; + { + U64 cursor = 0; + cursor += str8_deserial_read_cstr(data, cursor, &path); + + cursor = AlignPow2(cursor, 4); + cursor += str8_deserial_read_struct(data, cursor, &checksum); + } + + debug_link_out->path = path; + debug_link_out->checksum = checksum; + + is_debug_link_present = 1; + break; + } + } + + scratch_end(scratch); + return is_debug_link_present; +} + diff --git a/src/elf/elf_parse.h b/src/elf/elf_parse.h index fccbc233..1d1d1ba4 100644 --- a/src/elf/elf_parse.h +++ b/src/elf/elf_parse.h @@ -18,6 +18,12 @@ typedef struct ELF_Shdr64Array ELF_Shdr64 *v; } ELF_Shdr64Array; +typedef struct ELF_GnuDebugLink +{ + String8 path; + U32 checksum; +} ELF_GnuDebugLink; + //////////////////////////////// internal B32 elf_check_magic(String8 data); @@ -25,5 +31,6 @@ internal ELF_BinInfo elf_bin_from_data(String8 data); internal ELF_Shdr64Array elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr); internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr); +internal U64 elf_base_addr_from_bin(ELF_Hdr64 *hdr); #endif // ELF_PARSE_H From 1ec1deedee97c03aec0a0e306e9dcda19afdfd81 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 20:37:39 -0700 Subject: [PATCH 253/755] moved MSF magic checkers to msf.c --- src/msf/msf.c | 12 ++++++++++++ src/msf/msf.h | 5 +++++ src/msf/msf_parse.c | 6 ++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/msf/msf.c b/src/msf/msf.c index f78cec82..116918c8 100644 --- a/src/msf/msf.c +++ b/src/msf/msf.c @@ -1,4 +1,16 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +internal B32 +msf_check_magic_20(String8 data) +{ + B32 is_msf = data.size >= sizeof(msf_msf20_magic) && str8_match(data, str8_lit(msf_msf20_magic), StringMatchFlag_RightSideSloppy); + return is_msf; +} +internal B32 +msf_check_magic_70(String8 data) +{ + B32 is_msf = data.size >= sizeof(msf_msf70_magic) && str8_match(data, str8_lit(msf_msf70_magic), StringMatchFlag_RightSideSloppy); + return is_msf; +} diff --git a/src/msf/msf.h b/src/msf/msf.h index f18d8204..34bc9960 100644 --- a/src/msf/msf.h +++ b/src/msf/msf.h @@ -52,4 +52,9 @@ struct MSF_Header70 MSF_PageNumber root_pn; }; +//////////////////////////////// + +internal B32 msf_check_magic_20(String8 data); +internal B32 msf_check_magic_70(String8 data); + #endif // MSF_H diff --git a/src/msf/msf_parse.c b/src/msf/msf_parse.c index 79d00fd1..941f5d40 100644 --- a/src/msf/msf_parse.c +++ b/src/msf/msf_parse.c @@ -13,11 +13,9 @@ msf_raw_stream_table_from_data(Arena *arena, String8 msf_data) //- determine msf type U32 index_size = 0; - if (msf_data.size >= sizeof(msf_msf20_magic) && - str8_match(msf_data, str8_lit(msf_msf20_magic), StringMatchFlag_RightSideSloppy)) { + if (msf_check_magic_20(msf_data)) { index_size = 2; - } else if (msf_data.size >= sizeof(msf_msf70_magic) && - str8_match(msf_data, str8_lit(msf_msf70_magic), StringMatchFlag_RightSideSloppy)) { + } else if (msf_check_magic_70(msf_data)) { index_size = 4; } From 0c61415f72090479ed1de248fbf6d326652fc60e Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 21:32:50 -0700 Subject: [PATCH 254/755] merged path helper code from linker layer into main path layer --- src/linker/hash_table.c | 17 ++++- src/linker/lnk.c | 2 - src/linker/lnk_config.c | 8 +-- src/linker/path_ext/path.c | 67 ------------------- src/linker/path_ext/path.h | 10 --- src/path/path.c | 133 +++++++++++++++++++++++++++---------- src/path/path.h | 25 +++++-- src/raddump/raddump_main.c | 2 - 8 files changed, 138 insertions(+), 126 deletions(-) delete mode 100644 src/linker/path_ext/path.c delete mode 100644 src/linker/path_ext/path.h diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index cbb478ad..eaf0f95c 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -129,17 +129,28 @@ hash_table_push_u64_u64(Arena *arena, HashTable *ht, U64 key, U64 value) return hash_table_push(arena, ht, hash, (KeyValuePair){ .key_u64 = key, .value_u64 = value }); } +internal String8 +hash_table_normalize_path_string(Arena *arena, String8 path) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 result; + result = lower_from_str8(scratch.arena, path); + result = path_convert_slashes(arena, result, PathStyle_UnixAbsolute); + scratch_end(scratch); + return result; +} + internal BucketNode * hash_table_push_path_string(Arena *arena, HashTable *ht, String8 path, String8 value) { - String8 path_canon = path_canon_from_regular_path(arena, path); + String8 path_canon = hash_table_normalize_path_string(arena, path); return hash_table_push_string_string(arena, ht, path_canon, value); } internal BucketNode * hash_table_push_path_u64(Arena *arena, HashTable *ht, String8 path, U64 value) { - String8 path_canon = path_canon_from_regular_path(arena, path); + String8 path_canon = hash_table_normalize_path_string(arena, path); U64 hash = hash_table_hasher(path_canon); return hash_table_push(arena, ht, hash, (KeyValuePair){ .key_string = path_canon, .value_u64 = value }); } @@ -147,7 +158,7 @@ hash_table_push_path_u64(Arena *arena, HashTable *ht, String8 path, U64 value) internal BucketNode * hash_table_push_path_raw(Arena *arena, HashTable *ht, String8 path, void *value) { - String8 path_canon = path_canon_from_regular_path(arena, path); + String8 path_canon = hash_table_normalize_path_string(arena, path); U64 hash = hash_table_hasher(path_canon); return hash_table_push(arena, ht, hash, (KeyValuePair){ .key_string = path_canon, .value_raw = value }); } diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 8e7668d8..2c94f897 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -78,7 +78,6 @@ // Code Base Extensions #include "base_ext/base_inc.h" -#include "path_ext/path.h" #include "hash_table.h" #include "thread_pool/thread_pool.h" #include "codeview_ext/codeview.h" @@ -88,7 +87,6 @@ #include "pdb_ext/pdb_builder.h" #include "base_ext/base_inc.c" -#include "path_ext/path.c" #include "hash_table.c" #include "thread_pool/thread_pool.c" #include "codeview_ext/codeview.c" diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 0f07977f..dd9db42d 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -1976,22 +1976,22 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line) if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Out)) { String8 name = str8_list_first(&config->input_list[LNK_Input_Obj]); String8 ext = (config->file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) ? str8_lit("dll") : str8_lit("exe"); - config->image_name = make_file_name_with_ext(scratch.arena, name, ext); + config->image_name = path_replace_file_extension(scratch.arena, name, ext); } // handle empty /PDB if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Pdb)) { - config->pdb_name = make_file_name_with_ext(scratch.arena, config->image_name, str8_lit("pdb")); + config->pdb_name = path_replace_file_extension(scratch.arena, config->image_name, str8_lit("pdb")); } // handle empty /RAD_DEBUG_NAME if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Rad_DebugName)) { - config->rad_debug_name = make_file_name_with_ext(scratch.arena, config->image_name, str8_lit("rdi")); + config->rad_debug_name = path_replace_file_extension(scratch.arena, config->image_name, str8_lit("rdi")); } // handle empty /IMPLIB if (!lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_ImpLib)) { - config->imp_lib_name = make_file_name_with_ext(scratch.arena, config->image_name, str8_lit("lib")); + config->imp_lib_name = path_replace_file_extension(scratch.arena, config->image_name, str8_lit("lib")); } // handle empty /MANIFESTFILE diff --git a/src/linker/path_ext/path.c b/src/linker/path_ext/path.c deleted file mode 100644 index 8b50bfb4..00000000 --- a/src/linker/path_ext/path.c +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -internal String8 -make_file_name_with_ext(Arena *arena, String8 file_name, String8 ext) -{ - String8 file_name_no_ext = str8_chop_last_dot(file_name); - String8 result = push_str8f(arena, "%S.%S", file_name_no_ext, ext); - return result; -} - -internal String8 -path_char_from_style(PathStyle style) -{ - String8 result = str8_zero(); - switch (style) { - case PathStyle_Null: break; - case PathStyle_Relative: break; - case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break; - case PathStyle_UnixAbsolute: result = str8_lit("/"); break; - } - return result; -} - -internal String8 -path_convert_slashes(Arena *arena, String8 path, PathStyle path_style) -{ - Temp scratch = scratch_begin(&arena, 1); - String8List list = str8_split_path(scratch.arena, path); - StringJoin join = {0}; - join.sep = path_char_from_style(path_style); - String8 result = str8_list_join(arena, &list, &join); - scratch_end(scratch); - return result; -} - -internal String8 -path_canon_from_regular_path(Arena *arena, String8 path) -{ - Temp scratch = scratch_begin(&arena, 1); - String8 result; - result = lower_from_str8(scratch.arena, path); - result = path_convert_slashes(arena, result, PathStyle_UnixAbsolute); - scratch_end(scratch); - return result; -} - -struct { - String8 string; - PathStyle path_style; -} g_path_style_map[] = { - { str8_lit_comp("windows"), PathStyle_WindowsAbsolute }, - { str8_lit_comp("unix"), PathStyle_UnixAbsolute }, - { str8_lit_comp("system"), PathStyle_SystemAbsolute }, -}; - -internal PathStyle -path_style_from_string(String8 string) -{ - for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i) { - if (str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive)) { - return g_path_style_map[i].path_style; - } - } - return PathStyle_Null; -} - diff --git a/src/linker/path_ext/path.h b/src/linker/path_ext/path.h deleted file mode 100644 index ae3e4bb9..00000000 --- a/src/linker/path_ext/path.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#pragma once - -internal String8 make_file_name_with_ext(Arena *arena, String8 file_name, String8 ext); -internal String8 path_convert_slashes(Arena *arena, String8 path, PathStyle path_style); -internal String8 path_canon_from_regular_path(Arena *arena, String8 path); -internal PathStyle path_style_from_string(String8 string); - diff --git a/src/path/path.c b/src/path/path.c index b4817291..fa384748 100644 --- a/src/path/path.c +++ b/src/path/path.c @@ -1,29 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ allen: Path Helper Functions - -internal StringMatchFlags -path_match_flags_from_os(OperatingSystem os) -{ - StringMatchFlags flags = StringMatchFlag_SlashInsensitive; - switch(os) - { - default:{}break; - case OperatingSystem_Windows: - { - flags |= StringMatchFlag_CaseInsensitive; - }break; - case OperatingSystem_Linux: - case OperatingSystem_Mac: - { - // NOTE(rjf): no-op - }break; - } - return flags; -} - internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src) { @@ -122,14 +99,16 @@ path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src) } internal String8List -path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *style_out){ +path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *style_out) +{ // analyze path PathStyle path_style = path_style_from_str8(path_string); String8List path = str8_split_path(arena, path_string); // prepend current path to convert relative -> absolute PathStyle path_style_full = path_style; - if (path.node_count != 0 && path_style == PathStyle_Relative){ + if(path.node_count != 0 && path_style == PathStyle_Relative) + { String8 current_path_string = os_get_current_path(arena); PathStyle current_path_style = path_style_from_str8(current_path_string); @@ -145,10 +124,11 @@ path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *s str8_path_list_resolve_dots_in_place(&path, path_style_full); // return - if (style_out != 0){ + if(style_out != 0) + { *style_out = path_style_full; } - return(path); + return path; } internal String8 @@ -160,19 +140,104 @@ path_normalized_from_string(Arena *arena, String8 path_string){ String8 result = str8_path_list_join_by_style(arena, &path, style); scratch_end(scratch); - return(result); + return result; } internal B32 path_match_normalized(String8 left, String8 right) { - B32 result = 0; + Temp scratch = scratch_begin(0, 0); + String8 left_normalized = path_normalized_from_string(scratch.arena, left); + String8 right_normalized = path_normalized_from_string(scratch.arena, right); + B32 result = str8_match(left_normalized, right_normalized, StringMatchFlag_CaseInsensitive); + scratch_end(scratch); + return result; +} + +internal String8 +path_char_from_style(PathStyle style) +{ + String8 result = str8_zero(); + switch (style) { - Temp scratch = scratch_begin(0, 0); - String8 left_normalized = path_normalized_from_string(scratch.arena, left); - String8 right_normalized = path_normalized_from_string(scratch.arena, right); - result = str8_match(left_normalized, right_normalized, StringMatchFlag_CaseInsensitive); - scratch_end(scratch); + case PathStyle_Null: break; + case PathStyle_Relative: break; + case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break; + case PathStyle_UnixAbsolute: result = str8_lit("/"); break; } return result; } + +internal StringMatchFlags +path_match_flags_from_os(OperatingSystem os) +{ + StringMatchFlags flags = StringMatchFlag_SlashInsensitive; + switch(os) + { + default:{}break; + case OperatingSystem_Windows: + { + flags |= StringMatchFlag_CaseInsensitive; + }break; + case OperatingSystem_Linux: + case OperatingSystem_Mac: + { + // NOTE(rjf): no-op + }break; + } + return flags; +} + +internal String8 +path_convert_slashes(Arena *arena, String8 path, PathStyle path_style) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List list = str8_split_path(scratch.arena, path); + StringJoin join = {0}; + join.sep = path_char_from_style(path_style); + String8 result = str8_list_join(arena, &list, &join); + scratch_end(scratch); + return result; +} + +internal String8 +path_replace_file_extension(Arena *arena, String8 file_name, String8 ext) +{ + String8 file_name_no_ext = str8_chop_last_dot(file_name); + String8 result = push_str8f(arena, "%S.%S", file_name_no_ext, ext); + return result; +} + +global read_only struct +{ + String8 string; + PathStyle path_style; +} g_path_style_map[] = +{ + { str8_lit_comp(""), PathStyle_Null }, + { str8_lit_comp("relative"), PathStyle_Relative }, + { str8_lit_comp("windows"), PathStyle_WindowsAbsolute }, + { str8_lit_comp("unix"), PathStyle_UnixAbsolute }, + { str8_lit_comp("system"), PathStyle_SystemAbsolute }, +}; + +internal PathStyle +path_style_from_string(String8 string) +{ + for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i) + { + if(str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive)) + { + return g_path_style_map[i].path_style; + } + } + return PathStyle_Null; +} + +internal String8 +path_string_from_style(PathStyle style) +{ + Assert(style < ArrayCount(g_path_style_map)); + return g_path_style_map[style].string; +} + diff --git a/src/path/path.h b/src/path/path.h index dd110eb1..c6ae12da 100644 --- a/src/path/path.h +++ b/src/path/path.h @@ -5,13 +5,30 @@ #define PATH_H //////////////////////////////// -//~ allen: Path Helper Functions +// Relative <-> Absolute Path -internal StringMatchFlags path_match_flags_from_os(OperatingSystem os); internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src); internal String8 path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src); + +//////////////////////////////// +// Normal Path Helpers + internal String8List path_normalized_list_from_string(Arena *arena, String8 path, PathStyle *style_out); -internal String8 path_normalized_from_string(Arena *arena, String8 path); -internal B32 path_match_normalized(String8 left, String8 right); +internal String8 path_normalized_from_string(Arena *arena, String8 path); +internal B32 path_match_normalized(String8 left, String8 right); + +//////////////////////////////// +// Misc Helpers + +internal String8 path_char_from_style(PathStyle style); +internal StringMatchFlags path_match_flags_from_os(OperatingSystem os); +internal String8 path_convert_slashes(Arena *arena, String8 path, PathStyle path_style); +internal String8 path_replace_file_extension(Arena *arena, String8 file_name, String8 ext); + +//////////////////////////////// +// Enum <-> String + +internal PathStyle path_style_from_string(String8 string); +internal String8 path_string_from_style(PathStyle style); #endif //PATH_H diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index cd465cfb..f72c53d6 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -30,7 +30,6 @@ #include "rdi_make/rdi_make_local.h" #include "rdi_make/rdi_make_help.h" #include "path/path.h" -#include "linker/path_ext/path.h" #include "linker/hash_table.h" #include "coff/coff.h" #include "coff/coff_enum.h" @@ -65,7 +64,6 @@ #include "rdi_make/rdi_make_local.c" #include "rdi_make/rdi_make_help.c" #include "path/path.c" -#include "linker/path_ext/path.c" #include "linker/hash_table.c" #include "coff/coff.c" #include "coff/coff_enum.c" From 2e6ffbd0c43f541fde50a6bfd56d7d2f61ce205c Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:22:42 -0700 Subject: [PATCH 255/755] fixed typo in attrib class for DW_Form_RngListx --- src/dwarf/dwarf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 860d8ab5..0dce7a84 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -454,7 +454,7 @@ typedef enum DW_AttribClassEnum X(LineStrp, DW_AttribClass_String) \ X(ImplicitConst, DW_AttribClass_Const) \ X(LocListx, DW_AttribClass_LocListPtr) \ - X(RngListx, DW_AttribClass_RngListPtr) \ + X(RngListx, DW_AttribClass_RngList) \ X(RefSup8, DW_AttribClass_Reference) \ X(Strx1, DW_AttribClass_String) \ X(Strx2, DW_AttribClass_String) \ From b9c477478642b4e87880e19cb21b852f4e625552 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:23:19 -0700 Subject: [PATCH 256/755] minor fixes --- src/linker/lnk.c | 2 +- src/linker/lnk_config.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 2c94f897..9d6b5a28 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -5,7 +5,7 @@ // Build Options #define BUILD_CONSOLE_INTERFACE 1 -#define BUILD_TITLE "Epic Games Tools (R) RAD COFF/PE Linker" +#define BUILD_TITLE "Epic Games Tools (R) RAD PE/COFF Linker" //////////////////////////////// diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index dd9db42d..aaae53c9 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -882,7 +882,7 @@ lnk_print_help(void) fprintf(stdout, "--- Help -------------------------------------------------------\n"); fprintf(stdout, " %s\n", BUILD_TITLE_STRING_LITERAL); fprintf(stdout, "\n"); - fprintf(stdout, " Usage: rad-link.exe [Options] [Files] [@rsp]\n"); + fprintf(stdout, " Usage: radlink.exe [Options] [Files] [@rsp]\n"); fprintf(stdout, "\n"); fprintf(stdout, " Options:\n"); From a84028d67a5b645971f93ab361afd2db2486254e Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:29:22 -0700 Subject: [PATCH 257/755] helper for checking if ELF has DWARF debug sections --- src/dwarf/dwarf_coff.c | 65 +++++++++++++++++++++++++++++++++++++++-- src/dwarf/dwarf_coff.h | 42 +++----------------------- src/dwarf/dwarf_elf.c | 50 ++++++++++++++++++++++++------- src/dwarf/dwarf_parse.c | 23 +++++++++++++++ 4 files changed, 129 insertions(+), 51 deletions(-) diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c index d8158251..68caeb0a 100644 --- a/src/dwarf/dwarf_coff.c +++ b/src/dwarf/dwarf_coff.c @@ -1,7 +1,68 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#pragma once +internal B32 +dw_is_dwarf_present_coff_section_table(String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + B32 is_dwarf_present = 0; + + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = §ions[i]; + String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + + DW_SectionKind s = dw_section_kind_from_string(name); + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + } + + is_dwarf_present = s != DW_Section_Null; + if (is_dwarf_present) { + break; + } + } + + return is_dwarf_present; +} + +internal DW_Input +dw_input_from_coff_section_table(Arena *arena, + String8 raw_image, + U64 string_table_off, + U64 section_count, + COFF_SectionHeader *sections) +{ + DW_Input input = {0}; + B32 sect_status[ArrayCount(input.sec)] = {0}; + + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = §ions[i]; + Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); + String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + + DW_SectionKind s = dw_section_kind_from_string(name); + B32 is_dwo = 0; + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + is_dwo = 1; + } + + if (s != DW_Section_Null) { + if (sect_status[s]) { + Assert(!"too many debug sections with identical name, picking first"); + } else { + sect_status[s] = 1; + DW_Section *d = &input.sec[s]; + d->name = push_str8_copy(arena, name); + d->data = str8_substr(raw_image, raw_data_range); + d->is_dwo = is_dwo; + } + } + } + + return input; +} -internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h index 3a772531..768863f2 100644 --- a/src/dwarf/dwarf_coff.h +++ b/src/dwarf/dwarf_coff.h @@ -1,44 +1,10 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal DW_Input -dw_input_from_coff_section_table(Arena *arena, - String8 raw_image, - U64 string_table_off, - U64 section_count, - COFF_SectionHeader *sections) -{ - DW_Input input = {0}; - B32 sect_status[ArrayCount(input.sec)] = {0}; +#ifndef DWARF_COFF_H +#define DWARF_COFF_H - for (U64 i = 0; i < section_count; ++i) { - COFF_SectionHeader *header = §ions[i]; - Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); - String8 name = coff_name_from_section_header(raw_image, header, string_table_off); - - DW_SectionKind s = DW_Section_Null; - B32 is_dwo = 0; - #define X(_K,_L,_M,_W) \ - if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } - DW_SectionKind_XList(X) - #undef X - - if (s != DW_Section_Null) { - if (sect_status[s]) { - Assert(!"too many debug sections with identical name, picking first"); - } else { - sect_status[s] = 1; - DW_Section *d = &input.sec[s]; - d->name = push_str8_copy(arena, name); - d->data = str8_substr(raw_image, raw_data_range); - d->is_dwo = is_dwo; - } - } - } - - return input; -} +internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); +#endif // DWARF_COFF_H diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c index 55d6e4f7..99117b2e 100644 --- a/src/dwarf/dwarf_elf.c +++ b/src/dwarf/dwarf_elf.c @@ -1,6 +1,38 @@ // Copyright (c) 2025 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +internal B32 +dw_is_dwarf_present_elf_section_table(String8 raw_image, ELF_BinInfo *bin) +{ + Temp scratch = scratch_begin(0,0); + + B32 is_dwarf_present = 0; + + ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); + + for (U64 i = 0; i < sections.count; ++i) { + ELF_Shdr64 *shdr = §ions.v[i]; + String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr); + + if (shdr->sh_type != ELF_SectionCode_ProgBits) { + continue; + } + + DW_SectionKind s = dw_section_kind_from_string(name); + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + } + + is_dwarf_present = s != DW_Section_Null; + if (is_dwarf_present) { + break; + } + } + + scratch_end(scratch); + return is_dwarf_present; +} + internal DW_Input dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin) { @@ -10,7 +42,6 @@ dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bi B32 sect_status[ArrayCount(result.sec)] = {0}; ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr); - String8 sh_names = str8_substr(raw_image, bin->sh_name_range); for (U64 sect_idx = 1; sect_idx < sections.count; ++sect_idx) { ELF_Shdr64 *shdr = §ions.v[sect_idx]; @@ -20,17 +51,14 @@ dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bi continue; } - String8 name = {0}; - str8_deserial_read_cstr(sh_names, shdr->sh_name, &name); + String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr); - DW_SectionKind s = DW_Section_Null; - B32 is_dwo = 0; - #define X(_K,_L,_M,_W) \ - if (str8_match_lit(_L, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_M, name, 0)) { s = DW_Section_##_K; } \ - if (str8_match_lit(_W, name, 0)) { s = DW_Section_##_K; is_dwo = 1; } - DW_SectionKind_XList(X) - #undef X + DW_SectionKind s = dw_section_kind_from_string(name); + B32 is_dwo = 0; + if (s == DW_Section_Null) { + s = dw_section_dwo_kind_from_string(name); + is_dwo = 1; + } if (s != DW_Section_Null) { if (sect_status[s]) { diff --git a/src/dwarf/dwarf_parse.c b/src/dwarf/dwarf_parse.c index 0e34a29a..a8722d0e 100644 --- a/src/dwarf/dwarf_parse.c +++ b/src/dwarf/dwarf_parse.c @@ -169,6 +169,29 @@ str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 coun return bytes_read; } +internal DW_SectionKind +dw_section_kind_from_string(String8 string) +{ + DW_SectionKind s = DW_Section_Null; +#define X(_K,_L,_M,_W) \ + if (str8_match_lit(_L, string, 0)) { s = DW_Section_##_K; } \ + if (str8_match_lit(_M, string, 0)) { s = DW_Section_##_K; } + DW_SectionKind_XList(X) +#undef X + return s; +} + +internal DW_SectionKind +dw_section_dwo_kind_from_string(String8 string) +{ + DW_SectionKind s = DW_Section_Null; +#define X(_K,_L,_M,_W) \ + if (str8_match_lit(_W, string, 0)) { s = DW_Section_##_K; } + DW_SectionKind_XList(X) +#undef X + return s; +} + internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data) { From b10b08783a93cbb6ee52e124d1dfd99bac91125f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:40:56 -0700 Subject: [PATCH 258/755] WIP RAD debug info converter --- build.bat | 1 + src/radcon/radcon.c | 454 +++++ src/radcon/radcon.h | 66 + src/radcon/radcon_coff.c | 102 ++ src/radcon/radcon_coff.h | 13 + src/radcon/radcon_cv.c | 252 +++ src/radcon/radcon_cv.h | 10 + src/radcon/radcon_dwarf.c | 1878 +++++++++++++++++++++ src/radcon/radcon_dwarf.h | 43 + src/radcon/radcon_elf.c | 17 + src/radcon/radcon_elf.h | 10 + src/radcon/radcon_main.c | 97 ++ src/radcon/radcon_pdb.c | 3207 ++++++++++++++++++++++++++++++++++++ src/radcon/radcon_pdb.h | 238 +++ src/raddump/raddump.c | 77 +- src/raddump/raddump_main.c | 18 +- 16 files changed, 6411 insertions(+), 72 deletions(-) create mode 100644 src/radcon/radcon.c create mode 100644 src/radcon/radcon.h create mode 100644 src/radcon/radcon_coff.c create mode 100644 src/radcon/radcon_coff.h create mode 100644 src/radcon/radcon_cv.c create mode 100644 src/radcon/radcon_cv.h create mode 100644 src/radcon/radcon_dwarf.c create mode 100644 src/radcon/radcon_dwarf.h create mode 100644 src/radcon/radcon_elf.c create mode 100644 src/radcon/radcon_elf.h create mode 100644 src/radcon/radcon_main.c create mode 100644 src/radcon/radcon_pdb.c create mode 100644 src/radcon/radcon_pdb.h diff --git a/build.bat b/build.bat index 6529d9e5..f77e5df9 100644 --- a/build.bat +++ b/build.bat @@ -107,6 +107,7 @@ if not "%no_meta%"=="1" ( pushd build if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %link_icon% %out%raddbg.exe || exit /b 1 if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 +if "%radcon%"=="1" set didbuild=1 && %compile% ..\src\radcon\radcon_main.c %compile_link% %out%radcon.exe || exit /b 1 if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf_main.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c new file mode 100644 index 00000000..e7c6decf --- /dev/null +++ b/src/radcon/radcon.c @@ -0,0 +1,454 @@ +internal String8 +rc_data_from_file_path(Arena *arena, String8 path) +{ + String8 data = os_data_from_file_path(arena, path); + if (data.size == 0) { + fprintf(stderr, "error: unable to read file %.*s\n", str8_varg(path)); + os_abort(1); + } + return data; +} + +internal RC_Context +rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) +{ + Temp scratch = scratch_begin(&arena, 1); + + if (cmdl->inputs.node_count > 2) { + fprintf(stderr, "error: too many input files on the command line.\n"); + os_abort(1); + } + + B32 is_pe_present = 0; + B32 is_pdb_present = 0; + B32 is_elf_present = 0; + B32 is_elf_debug_present = 0; + String8 pe_name = {0}; + String8 pe_data = {0}; + String8 pdb_name = {0}; + String8 pdb_data = {0}; + String8 elf_name = {0}; + String8 elf_data = {0}; + String8 elf_debug_name = {0}; + String8 elf_debug_data = {0}; + + // + // Set typed inputs + // + if (cmd_line_has_flag(cmdl, str8_lit("pe"))) { + pe_name = cmd_line_string(cmdl, str8_lit("pe")); + pe_data = rc_data_from_file_path(arena, pe_name); + if (!pe_check_magic(pe_data)) { + fprintf(stderr, "error: -pe:%.*s is not of PE format\n", str8_varg(pe_name)); + os_abort(1); + } + is_pe_present = 1; + } + if (cmd_line_has_flag(cmdl, str8_lit("pdb"))) { + pdb_name = cmd_line_string(cmdl, str8_lit("pdb")); + pdb_data = rc_data_from_file_path(arena, pdb_name); + if (!msf_check_magic_20(pdb_data) && !msf_check_magic_70(pdb_data)) { + fprintf(stderr, "error: -pdb:%.*s is not of PDB format\n", str8_varg(pdb_name)); + os_abort(1); + } + is_pdb_present = 1; + } + if (cmd_line_has_flag(cmdl, str8_lit("elf"))) { + elf_name = cmd_line_string(cmdl, str8_lit("elf")); + elf_data = rc_data_from_file_path(arena, elf_name); + if (!elf_check_magic(elf_data)) { + fprintf(stderr, "error: -elf:%.*s is not of ELF format\n", str8_varg(elf_name)); + os_abort(1); + } + is_elf_present = 1; + } + if (cmd_line_has_flag(cmdl, str8_lit("elf_debug"))) { + elf_debug_name = cmd_line_string(cmdl, str8_lit("elf_debug")); + elf_debug_data = rc_data_from_file_path(arena, elf_debug_name); + if (!elf_check_magic(elf_debug_data)) { + fprintf(stderr, "error: -elf_debug:%.*s is not of ELF format\n", str8_varg(elf_debug_name)); + os_abort(1); + } + is_elf_debug_present = 1; + } + + // + // Load inputs + // + for (String8Node *input_n = cmdl->inputs.first; input_n != 0; input_n = input_n->next) { + String8 input_data = os_data_from_file_path(arena, input_n->string); + + if (input_data.size == 0) { + fprintf(stderr, "unable to read input %.*s\n", str8_varg(input_n->string)); + os_abort(1); + } + + if (pe_check_magic(input_data)) { + if (is_pe_present) { + fprintf(stderr, "error: too many PE files are specified on the command line\n"); + fprintf(stderr, " selected: %.*s\n", str8_varg(pe_name)); + fprintf(stderr, " current: %.*s\n", str8_varg(input_n->string)); + os_abort(1); + } + pe_data = input_data; + pe_name = input_n->string; + is_pe_present = 1; + } else if (elf_check_magic(input_data)) { + ELF_BinInfo elf = elf_bin_from_data(input_data); + B32 is_dwarf_present = dw_is_dwarf_present_elf_section_table(input_data, &elf); + if (is_dwarf_present) { + if (is_elf_debug_present) { + fprintf(stderr, "error: ambiguous input, both ELFs have DWARF debug sections, please use --elf: --elf_debug: to clarify inputs.\n"); + os_abort(1); + } + elf_debug_name = input_n->string; + elf_debug_data = input_data; + is_elf_debug_present = 1; + } else { + elf_name = input_n->string; + elf_data = input_data; + is_elf_present = 1; + } + } else if (msf_check_magic_20(input_data) || msf_check_magic_70(input_data)) { + if (is_pdb_present) { + fprintf(stderr, "error: too many PDB files are specified on the command line\n"); + fprintf(stderr, " selected: %.*s\n", str8_varg(pdb_name)); + fprintf(stderr, " current: %.*s\n", str8_varg(input_n->string)); + continue; + } + pdb_name = input_n->string; + pdb_data = input_data; + is_pdb_present = 1; + } else { + fprintf(stderr, "error: unknown file format %.*s\n", str8_varg(input_n->string)); + } + } + + // + // Validate input combos + // + if ((is_pe_present || is_pdb_present) && (is_elf_present || is_elf_debug_present)) { + fprintf(stderr, "error: invalid combination of inputs provided, we convert only (PE|PDB) or (ELF|ELF_DEBUG) at a time.\n"); + if (is_pe_present) { + fprintf(stderr, " PE: %.*s\n", str8_varg(pe_name)); + } + if (is_pdb_present) { + fprintf(stderr, " PDB: %.*s\n", str8_varg(pdb_name)); + } + if (is_elf_present) { + fprintf(stderr, " ELF: %.*s\n", str8_varg(elf_name)); + } + if (is_elf_debug_present) { + fprintf(stderr, " ELF Debug: %.*s\n", str8_varg(elf_debug_name)); + } + os_abort(1); + } + + // + // Pick conversion driver + // + RC_Driver driver = RC_Driver_Null; + if (cmd_line_has_flag(cmdl, str8_lit("driver"))) { + String8 driver_name = cmd_line_string(cmdl, str8_lit("driver")); + if (str8_match(driver_name, str8_lit("dwarf"), StringMatchFlag_CaseInsensitive)) { + driver = RC_Driver_Dwarf; + } else if (str8_match(driver_name, str8_lit("pdb"), StringMatchFlag_CaseInsensitive)) { + driver = RC_Driver_Pdb; + } else { + fprintf(stderr, "error: unknown driver %.*s\n", str8_varg(driver_name)); + os_abort(1); + } + } + + ImageType image = Image_Null; + String8 image_name = {0}; + String8 image_data = {0}; + String8 debug_name = {0}; + String8 debug_data = {0}; + + // + // Input is PE/COFF + // + B32 check_guid = 0; + Guid pe_pdb_guid = {0}; + if (is_pe_present) { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); + + String8 raw_debug_dir = str8_substr(pe_data, pe.data_dir_franges[PE_DataDirectoryIndex_DEBUG]); + PE_DebugInfoList debug_dir = pe_parse_debug_directory(scratch.arena, pe_data, raw_debug_dir); + for (PE_DebugInfoNode *debug_n = debug_dir.first; debug_n != 0; debug_n = debug_n->next) { + PE_DebugInfo *debug = &debug_n->v; + if (debug->header.type == PE_DebugDirectoryType_CODEVIEW) { + if (debug->u.codeview.magic == PE_CODEVIEW_PDB70_MAGIC) { + check_guid = 1; + pe_pdb_guid = debug->u.codeview.pdb70.header.guid; + + if (!is_pdb_present) { + pdb_name = debug->u.codeview.pdb70.path; + pdb_data = rc_data_from_file_path(arena, pdb_name); + is_pdb_present = 1; + } + + break; + } + } + } + + if (driver == RC_Driver_Dwarf || driver == RC_Driver_Null) { + String8 raw_sections = str8_substr(pe_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); + U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); + COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; + if (dw_is_dwarf_present_coff_section_table(pe_data, pe.string_table_off, section_count, section_array)) { + driver = RC_Driver_Dwarf; + image = Image_CoffPe; + image_name = pe_name; + image_data = pe_data; + debug_name = pe_name; + debug_data = pe_data; + goto driver_found; + } else { + if (driver == RC_Driver_Dwarf) { + fprintf(stderr, "error: image doesn't have DWARF debug sections.\n"); + os_abort(1); + } + } + } + } + + + // + // Input is PDB + // + if (driver == RC_Driver_Null && is_pdb_present) { + if (is_pe_present) { + image = Image_CoffPe; + image_name = pe_name; + image_data = pe_data; + } + driver = RC_Driver_Pdb; + debug_name = pdb_name; + debug_data = pdb_data; + goto driver_found; + } + + B32 elf_has_debug_link = 0; + ELF_GnuDebugLink debug_link = {0}; + if (is_elf_present || is_elf_debug_present) { + if (driver != RC_Driver_Null && driver != RC_Driver_Dwarf) { + fprintf(stderr, "ELF inputs are only supported when using DWARF driver.\n"); + os_abort(1); + } + + // + // Load image ELF + // + ELF_BinInfo elf = elf_bin_from_data(elf_data); + B32 has_elf_dwarf = dw_is_dwarf_present_elf_section_table(elf_data, &elf); + + // + // ELF doesn't have debug info and no .debug was specified on command line, + // try to load .debug via debug link + // + if (is_elf_present && !is_elf_debug_present) { + elf_has_debug_link = elf_parse_debug_link(elf_data, &elf, &debug_link); + } + if (elf_has_debug_link) { + elf_debug_data = rc_data_from_file_path(arena, debug_link.path); + is_elf_debug_present = 1; + } + + // + // Load .debug ELF + // + ELF_BinInfo elf_debug = elf_bin_from_data(elf_debug_data); + B32 has_elf_debug_dwarf = dw_is_dwarf_present_elf_section_table(elf_debug_data, &elf_debug); + + // + // Input is image ELF and .debug ELF + // + B32 is_split_elf = is_elf_present && is_elf_debug_present && !has_elf_dwarf && has_elf_debug_dwarf; + if (is_split_elf) { + driver = RC_Driver_Dwarf; + image = ELF_HdrIs64Bit(elf.hdr.e_ident) ? Image_Elf64 : Image_Elf32; + image_name = elf_name; + image_data = elf_data; + debug_name = elf_debug_name; + debug_data = elf_debug_data; + goto driver_found; + } + + // + // Input ELF is image with debug info + // + B32 is_monolithic_elf = is_elf_present && !is_elf_debug_present && has_elf_dwarf; + if (is_monolithic_elf) { + driver = RC_Driver_Dwarf; + image = ELF_HdrIs64Bit(elf.hdr.e_ident) ? Image_Elf64 : Image_Elf32; + image_name = elf_name; + image_data = elf_data; + debug_name = elf_name; + debug_data = elf_data; + goto driver_found; + } + + // + // Input ELF is .debug + // + B32 is_debug_elf = !is_elf_present && is_elf_debug_present && has_elf_debug_dwarf; + if (is_debug_elf) { + driver = RC_Driver_Dwarf; + image = ELF_HdrIs64Bit(elf_debug.hdr.e_ident) ? Image_Elf64 : Image_Elf32; + debug_name = elf_debug_name; + debug_data = elf_debug_data; + goto driver_found; + } + } + + driver_found:; + + // + // Handle -out param + // + String8 out_name = {0}; + if (cmd_line_has_flag(cmdl, str8_lit("out"))) { + out_name = cmd_line_string(cmdl, str8_lit("out")); + if (out_name.size == 0) { + fprintf(stderr, "error: -out parameter doesn't have a value\n"); + os_abort(1); + } + } else { + if (image_name.size) { + out_name = path_replace_file_extension(arena, image_name, str8_lit("rdi")); + } else { + out_name = path_replace_file_extension(arena, debug_name, str8_lit("rdi")); + } + } + + + // + // Validate driver input + // + if (driver == RC_Driver_Pdb && + !is_pdb_present && (is_elf_present || is_elf_debug_present)) { + fprintf(stderr, "error: DWARF is an invalid input for PDB driver\n"); + os_abort(1); + } + + + RC_Context ctx = {0}; + ctx.driver = driver; + ctx.image = image; + ctx.image_name = image_name; + ctx.image_data = image_data; + ctx.debug_name = debug_name; + ctx.debug_data = debug_data; + if (check_guid) { + ctx.flags |= RC_Flag_CheckPdbGuid; + ctx.guid = pe_pdb_guid; + } + if (elf_has_debug_link) { + ctx.flags |= RC_Flag_CheckElfChecksum; + ctx.debug_link = debug_link; + } + ctx.out_name = out_name; + + scratch_end(scratch); + return ctx; +} + +internal String8List +rc_run(Arena *arena, RC_Context *rc) +{ + Temp scratch = scratch_begin(&arena, 1); + + ProfBegin("Convert"); + RDIM_HelpState *help_state = rdim_help_init(); + RDIM_BakeParams *convert2bake = 0; + switch (rc->driver) { + case RC_Driver_Null: break; + case RC_Driver_Dwarf: convert2bake = d2r_convert(scratch.arena, help_state, rc); break; + case RC_Driver_Pdb: convert2bake = p2r_convert(scratch.arena, help_state, rc); break; + } + ProfEnd(); + + if (rc->errors.node_count) { + NotImplemented; + } + + ProfBegin("Bake"); + RDIM_BakeResults bake2srlz = rdim_bake(help_state, convert2bake); + ProfEnd(); + + ProfBegin("Serialize Bake"); + RDIM_SerializedSectionBundle srlz2file = rdim_serialized_section_bundle_from_bake_results(&bake2srlz); + ProfEnd(); + + RDIM_SerializedSectionBundle srlz2file_compressed = srlz2file; + if (rc->flags & RC_Flag_Compress) { + ProfBegin("Compress"); + srlz2file_compressed = rdim_compress(scratch.arena, &srlz2file); + ProfEnd(); + } + + ProfBegin("Serialize"); + String8List raw_rdi = rdim_file_blobs_from_section_bundle(scratch.arena, &srlz2file_compressed); + ProfEnd(); + + scratch_end(scratch); + return raw_rdi; +} + +internal String8 +rc_rdi_from_cmd_line(Arena *arena, CmdLine *cmdl) +{ + Temp scratch = scratch_begin(&arena, 1); + RC_Context rc = rc_context_from_cmd_line(scratch.arena, cmdl); + String8List raw_rdi = rc_run(scratch.arena, &rc); + String8 result = str8_list_join(arena, &raw_rdi, 0); + scratch_end(scratch); + return result; +} + +internal void +rc_main(CmdLine *cmdl) +{ + B32 do_help = (cmd_line_has_flag(cmdl, str8_lit("help")) || + cmd_line_has_flag(cmdl, str8_lit("h")) || + cmd_line_has_flag(cmdl, str8_lit("?")) || + cmdl->argc == 1); + if (do_help) { + fprintf(stderr, "--- Help ---------------------------------------------------------------------\n"); + fprintf(stderr, " %s\n\n", BUILD_TITLE_STRING_LITERAL); + fprintf(stderr, " Usage: radcon [Options] [Files]\n\n"); + fprintf(stderr, " Options:\n"); + fprintf(stderr, " -pe: Path to Win32 executable image\n"); + fprintf(stderr, " -pdb: Path to PDB\n"); + fprintf(stderr, " -elf: Path to ELF\n"); + fprintf(stderr, " -elf_debug: Path to ELF with debug info\n"); + fprintf(stderr, " -out: Path at which the output RDI debug info will be written\n"); + fprintf(stderr, " -driver: Sets converter for debug info\n"); + } else { + Temp scratch = scratch_begin(0,0); + + // make converter context + RC_Context rc = rc_context_from_cmd_line(scratch.arena, cmdl); + + // make RDI from context + String8List raw_rdi = rc_run(scratch.arena, &rc); + + // output RDI + if (rc.errors.node_count == 0) { + if (!os_write_data_list_to_file_path(rc.out_name, raw_rdi)) { + str8_list_pushf(scratch.arena, &rc.errors, "no write access to path %.*s", str8_varg(rc.out_name)); + } + } + + // report any errors + for (String8Node *error_n = rc.errors.first; error_n != 0; error_n = error_n->next) { + fprintf(stderr, "error: %.*s\n", str8_varg(error_n->string)); + } + + scratch_end(scratch); + } +} + diff --git a/src/radcon/radcon.h b/src/radcon/radcon.h new file mode 100644 index 00000000..95631068 --- /dev/null +++ b/src/radcon/radcon.h @@ -0,0 +1,66 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADCON_H +#define RADCON_H + +typedef U32 RC_Flags; +enum +{ + RC_Flag_Strings = (1 << 0), + RC_Flag_IndexRuns = (1 << 1), + RC_Flag_BinarySections = (1 << 2), + RC_Flag_Units = (1 << 3), + RC_Flag_Procedures = (1 << 4), + RC_Flag_GlobalVariables = (1 << 5), + RC_Flag_ThreadVariables = (1 << 6), + RC_Flag_Scopes = (1 << 7), + RC_Flag_Locals = (1 << 8), + RC_Flag_Types = (1 << 9), + RC_Flag_UDTs = (1 << 10), + RC_Flag_LineInfo = (1 << 11), + RC_Flag_GlobalVariableNameMap = (1 << 12), + RC_Flag_ThreadVariableNameMap = (1 << 13), + RC_Flag_ProcedureNameMap = (1 << 14), + RC_Flag_TypeNameMap = (1 << 15), + RC_Flag_LinkNameProcedureNameMap= (1 << 16), + RC_Flag_NormalSourcePathNameMap = (1 << 17), + RC_Flag_Compress = (1 << 18), + RC_Flag_StrictDwarfParse = (1 << 19), + RC_Flag_Deterministic = (1 << 20), + RC_Flag_CheckPdbGuid = (1 << 21), + RC_Flag_CheckElfChecksum = (1 << 22), + RC_Flag_All = 0xffffffff, +}; + +typedef enum +{ + RC_Driver_Null, + RC_Driver_Dwarf, + RC_Driver_Pdb, +} RC_Driver; + +typedef struct RC_Context +{ + ImageType image; + RC_Driver driver; + String8 image_name; + String8 image_data; + String8 debug_name; + String8 debug_data; + String8 out_name; + RC_Flags flags; + Guid guid; + ELF_GnuDebugLink debug_link; + String8List errors; +} RC_Context; + +//////////////////////////////// + +internal RC_Context rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl); +internal String8List rc_run(Arena *arena, RC_Context *rc); +internal String8 rc_rdi_from_cmd_line(Arena *arena, CmdLine *cmdl); +internal void rc_main(CmdLine *cmdl); + +#endif // RADCON_H + diff --git a/src/radcon/radcon_coff.c b/src/radcon/radcon_coff.c new file mode 100644 index 00000000..9f5b6059 --- /dev/null +++ b/src/radcon/radcon_coff.c @@ -0,0 +1,102 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal RDI_Arch +c2r_rdi_arch_from_coff_machine(COFF_MachineType machine) +{ + switch (machine) { + case COFF_Machine_X86: return RDI_Arch_X86; + case COFF_Machine_X64: return RDI_Arch_X64; + + case COFF_Machine_Unknown: + case COFF_Machine_Am33: + case COFF_Machine_Arm: + case COFF_Machine_Arm64: + case COFF_Machine_ArmNt: + case COFF_Machine_Ebc: + case COFF_Machine_Ia64: + case COFF_Machine_M32R: + case COFF_Machine_Mips16: + case COFF_Machine_MipsFpu: + case COFF_Machine_MipsFpu16: + case COFF_Machine_PowerPc: + case COFF_Machine_PowerPcFp: + case COFF_Machine_R4000: + case COFF_Machine_RiscV32: + case COFF_Machine_RiscV64: + case COFF_Machine_Sh3: + case COFF_Machine_Sh3Dsp: + case COFF_Machine_Sh4: + case COFF_Machine_Sh5: + case COFF_Machine_Thumb: + case COFF_Machine_WceMipsV2: + NotImplemented; + default: + return RDI_Arch_NULL; + } +} + +internal RDI_BinarySectionFlags +c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags) +{ + RDI_BinarySectionFlags result = 0; + if(flags & COFF_SectionFlag_MemRead) + { + result |= RDI_BinarySectionFlag_Read; + } + if(flags & COFF_SectionFlag_MemWrite) + { + result |= RDI_BinarySectionFlag_Write; + } + if(flags & COFF_SectionFlag_MemExecute) + { + result |= RDI_BinarySectionFlag_Execute; + } + return(result); +} + +internal RDIM_BinarySectionList +c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 string_table_off, U64 sectab_count, COFF_SectionHeader *sectab) +{ + ProfBeginFunction(); + + RDIM_BinarySectionList binary_sections = {0}; + + for (U64 isec = 0; isec < sectab_count; ++isec) { + COFF_SectionHeader *coff_sec = §ab[isec]; + RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections); + + sec->name = coff_name_from_section_header(image_data, coff_sec, string_table_off); + sec->flags = c2r_rdi_binary_section_flags_from_coff_section_flags(coff_sec->flags); + sec->voff_first = coff_sec->voff; + sec->voff_opl = coff_sec->voff + coff_sec->vsize; + sec->foff_first = coff_sec->foff; + sec->foff_opl = coff_sec->foff + coff_sec->fsize; + } + + ProfEnd(); + return binary_sections; +} + +internal RDIM_TopLevelInfo +c2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, U64 exe_hash, U64 sectab_count, COFF_SectionHeader *sectab) +{ + U64 exe_voff_max = 0; + { + COFF_SectionHeader *coff_sec_ptr = sectab; + COFF_SectionHeader *coff_ptr_opl = sectab + sectab_count; + for (;coff_sec_ptr < coff_ptr_opl; coff_sec_ptr += 1) { + U64 sec_voff_max = coff_sec_ptr->voff + coff_sec_ptr->vsize; + exe_voff_max = Max(exe_voff_max, sec_voff_max); + } + } + + RDIM_TopLevelInfo top_level_info = {0}; + top_level_info.arch = arch; + top_level_info.exe_name = str8_skip_last_slash(image_name); + top_level_info.exe_hash = exe_hash; + top_level_info.voff_max = exe_voff_max; + top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); + + return top_level_info; +} diff --git a/src/radcon/radcon_coff.h b/src/radcon/radcon_coff.h new file mode 100644 index 00000000..abed4aef --- /dev/null +++ b/src/radcon/radcon_coff.h @@ -0,0 +1,13 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADCON_COFF_H +#define RADCON_COFF_H + +internal RDI_Arch c2r_rdi_arch_from_coff_machine(COFF_MachineType machine); +internal RDI_BinarySectionFlags c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags); +internal RDIM_BinarySectionList c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 string_table_off, U64 sectab_count, COFF_SectionHeader *sectab); +internal RDIM_TopLevelInfo c2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, U64 exe_hash, U64 sectab_count, COFF_SectionHeader *sectab); + +#endif // RADCON_COFF_H + diff --git a/src/radcon/radcon_cv.c b/src/radcon/radcon_cv.c new file mode 100644 index 00000000..6b687feb --- /dev/null +++ b/src/radcon/radcon_cv.c @@ -0,0 +1,252 @@ +//////////////////////////////// +//~ rjf: CodeView <-> RDI Canonical Conversions + +internal RDI_Arch +cv2r_rdi_arch_from_cv_arch(CV_Arch cv_arch) +{ + RDI_Arch result = 0; + switch(cv_arch) + { + case CV_Arch_8086: result = RDI_Arch_X86; break; + case CV_Arch_X64: result = RDI_Arch_X64; break; + //case CV_Arch_8080: break; + //case CV_Arch_80286: break; + //case CV_Arch_80386: break; + //case CV_Arch_80486: break; + //case CV_Arch_PENTIUM: break; + //case CV_Arch_PENTIUMII: break; + //case CV_Arch_PENTIUMIII: break; + //case CV_Arch_MIPS: break; + //case CV_Arch_MIPS16: break; + //case CV_Arch_MIPS32: break; + //case CV_Arch_MIPS64: break; + //case CV_Arch_MIPSI: break; + //case CV_Arch_MIPSII: break; + //case CV_Arch_MIPSIII: break; + //case CV_Arch_MIPSIV: break; + //case CV_Arch_MIPSV: break; + //case CV_Arch_M68000: break; + //case CV_Arch_M68010: break; + //case CV_Arch_M68020: break; + //case CV_Arch_M68030: break; + //case CV_Arch_M68040: break; + //case CV_Arch_ALPHA: break; + //case CV_Arch_ALPHA_21164: break; + //case CV_Arch_ALPHA_21164A: break; + //case CV_Arch_ALPHA_21264: break; + //case CV_Arch_ALPHA_21364: break; + //case CV_Arch_PPC601: break; + //case CV_Arch_PPC603: break; + //case CV_Arch_PPC604: break; + //case CV_Arch_PPC620: break; + //case CV_Arch_PPCFP: break; + //case CV_Arch_PPCBE: break; + //case CV_Arch_SH3: break; + //case CV_Arch_SH3E: break; + //case CV_Arch_SH3DSP: break; + //case CV_Arch_SH4: break; + //case CV_Arch_SHMEDIA: break; + //case CV_Arch_ARM3: break; + //case CV_Arch_ARM4: break; + //case CV_Arch_ARM4T: break; + //case CV_Arch_ARM5: break; + //case CV_Arch_ARM5T: break; + //case CV_Arch_ARM6: break; + //case CV_Arch_ARM_XMAC: break; + //case CV_Arch_ARM_WMMX: break; + //case CV_Arch_ARM7: break; + //case CV_Arch_OMNI: break; + //case CV_Arch_IA64_1: break; + //case CV_Arch_IA64_2: break; + //case CV_Arch_CEE: break; + //case CV_Arch_AM33: break; + //case CV_Arch_M32R: break; + //case CV_Arch_TRICORE: break; + //case CV_Arch_EBC: break; + //case CV_Arch_THUMB: break; + //case CV_Arch_ARMNT: break; + //case CV_Arch_ARM64: break; + //case CV_Arch_D3D11_SHADER: break; + } + return(result); +} + +internal RDI_RegCode +cv2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code) +{ + RDI_RegCode result = 0; + switch(arch) + { + case RDI_Arch_X86: + { + switch(reg_code) + { +#define X(CVN,C,RDN,BP,BZ) case C: result = RDI_RegCodeX86_##RDN; break; + CV_Reg_X86_XList(X) +#undef X + } + }break; + case RDI_Arch_X64: + { + switch(reg_code) + { +#define X(CVN,C,RDN,BP,BZ) case C: result = RDI_RegCodeX64_##RDN; break; + CV_Reg_X64_XList(X) +#undef X + } + }break; + } + return(result); +} + +internal RDI_Language +cv2r_rdi_language_from_cv_language(CV_Language cv_language) +{ + RDI_Language result = 0; + switch(cv_language) + { + case CV_Language_C: result = RDI_Language_C; break; + case CV_Language_CXX: result = RDI_Language_CPlusPlus; break; + //case CV_Language_FORTRAN: result = ; break; + //case CV_Language_MASM: result = ; break; + //case CV_Language_PASCAL: result = ; break; + //case CV_Language_BASIC: result = ; break; + //case CV_Language_COBOL: result = ; break; + //case CV_Language_LINK: result = ; break; + //case CV_Language_CVTRES: result = ; break; + //case CV_Language_CVTPGD: result = ; break; + //case CV_Language_CSHARP: result = ; break; + //case CV_Language_VB: result = ; break; + //case CV_Language_ILASM: result = ; break; + //case CV_Language_JAVA: result = ; break; + //case CV_Language_JSCRIPT: result = ; break; + //case CV_Language_MSIL: result = ; break; + //case CV_Language_HLSL: result = ; break; + } + return(result); +} + +internal RDI_RegCode +cv2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg) +{ + RDI_RegCode result = 0; + switch(arch) + { + case RDI_Arch_X86: + { + switch(encoded_reg) + { + case CV_EncodedFramePtrReg_StackPtr: + { + // TODO(allen): support CV_AllReg_VFRAME + // TODO(allen): error + }break; + case CV_EncodedFramePtrReg_FramePtr: + { + result = RDI_RegCodeX86_ebp; + }break; + case CV_EncodedFramePtrReg_BasePtr: + { + result = RDI_RegCodeX86_ebx; + }break; + } + }break; + case RDI_Arch_X64: + { + switch(encoded_reg) + { + case CV_EncodedFramePtrReg_StackPtr: + { + result = RDI_RegCodeX64_rsp; + }break; + case CV_EncodedFramePtrReg_FramePtr: + { + result = RDI_RegCodeX64_rbp; + }break; + case CV_EncodedFramePtrReg_BasePtr: + { + result = RDI_RegCodeX64_r13; + }break; + } + }break; + } + return(result); +} + + +internal RDI_TypeKind +cv2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type) +{ + RDI_TypeKind result = RDI_TypeKind_NULL; + switch(basic_type) + { + case CV_BasicType_VOID: {result = RDI_TypeKind_Void;}break; + case CV_BasicType_HRESULT: {result = RDI_TypeKind_HResult;}break; + + case CV_BasicType_RCHAR: + case CV_BasicType_CHAR: + case CV_BasicType_CHAR8: + {result = RDI_TypeKind_Char8;}break; + + case CV_BasicType_UCHAR: {result = RDI_TypeKind_UChar8;}break; + case CV_BasicType_WCHAR: {result = RDI_TypeKind_UChar16;}break; + case CV_BasicType_CHAR16: {result = RDI_TypeKind_Char16;}break; + case CV_BasicType_CHAR32: {result = RDI_TypeKind_Char32;}break; + + case CV_BasicType_BOOL8: + case CV_BasicType_INT8: + {result = RDI_TypeKind_S8;}break; + + case CV_BasicType_BOOL16: + case CV_BasicType_INT16: + case CV_BasicType_SHORT: + {result = RDI_TypeKind_S16;}break; + + case CV_BasicType_BOOL32: + case CV_BasicType_INT32: + case CV_BasicType_LONG: + {result = RDI_TypeKind_S32;}break; + + case CV_BasicType_BOOL64: + case CV_BasicType_INT64: + case CV_BasicType_QUAD: + {result = RDI_TypeKind_S64;}break; + + case CV_BasicType_INT128: + case CV_BasicType_OCT: + {result = RDI_TypeKind_S128;}break; + + case CV_BasicType_UINT8: {result = RDI_TypeKind_U8;}break; + + case CV_BasicType_UINT16: + case CV_BasicType_USHORT: + {result = RDI_TypeKind_U16;}break; + + case CV_BasicType_UINT32: + case CV_BasicType_ULONG: + {result = RDI_TypeKind_U32;}break; + + case CV_BasicType_UINT64: + case CV_BasicType_UQUAD: + {result = RDI_TypeKind_U64;}break; + + case CV_BasicType_UINT128: + case CV_BasicType_UOCT: + {result = RDI_TypeKind_U128;}break; + + case CV_BasicType_FLOAT16:{result = RDI_TypeKind_F16;}break; + case CV_BasicType_FLOAT32:{result = RDI_TypeKind_F32;}break; + case CV_BasicType_FLOAT32PP:{result = RDI_TypeKind_F32PP;}break; + case CV_BasicType_FLOAT48:{result = RDI_TypeKind_F48;}break; + case CV_BasicType_FLOAT64:{result = RDI_TypeKind_F64;}break; + case CV_BasicType_FLOAT80:{result = RDI_TypeKind_F80;}break; + case CV_BasicType_FLOAT128:{result = RDI_TypeKind_F128;}break; + case CV_BasicType_COMPLEX32:{result = RDI_TypeKind_ComplexF32;}break; + case CV_BasicType_COMPLEX64:{result = RDI_TypeKind_ComplexF64;}break; + case CV_BasicType_COMPLEX80:{result = RDI_TypeKind_ComplexF80;}break; + case CV_BasicType_COMPLEX128:{result = RDI_TypeKind_ComplexF128;}break; + case CV_BasicType_PTR:{result = RDI_TypeKind_Handle;}break; + } + return result; +} + diff --git a/src/radcon/radcon_cv.h b/src/radcon/radcon_cv.h new file mode 100644 index 00000000..014a4c9e --- /dev/null +++ b/src/radcon/radcon_cv.h @@ -0,0 +1,10 @@ +#pragma once + +//////////////////////////////// +//~ rjf: CodeView => RDI Canonical Conversions + +internal RDI_Arch cv2r_rdi_arch_from_cv_arch(CV_Arch arch); +internal RDI_RegCode cv2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code); +internal RDI_Language cv2r_rdi_language_from_cv_language(CV_Language language); +internal RDI_RegCode cv2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg); +internal RDI_TypeKind cv2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type); diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c new file mode 100644 index 00000000..8601cdac --- /dev/null +++ b/src/radcon/radcon_dwarf.c @@ -0,0 +1,1878 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +// TODO: +// +// [ ] Currently converter relies on clang's -gdwarf-aranges to generate compile unit ranges, +// however it is optional and in case it is missing converter has to generate the ranges from scopes. +// [ ] Error handling + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code_x64(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return RDI_RegCodeX64_##reg_name_rdi; + DW_Regs_X64_XList(X) +#undef X + } + InvalidPath; + return 0; +} + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code_x86(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return RDI_RegCodeX86_##reg_name_rdi; + DW_Regs_X86_XList(X) +#undef X + } + InvalidPath; + return 0; +} + +internal RDI_RegCode +d2r_rdi_reg_from_dw_reg_code(RDI_Arch arch, U64 reg_code) +{ + switch (arch) { + case RDI_Arch_NULL: return 0; + case RDI_Arch_X64: return d2r_rdi_reg_from_dw_reg_code_x64(reg_code); + case RDI_Arch_X86: return d2r_rdi_reg_from_dw_reg_code_x86(reg_code); + } + InvalidPath; + return 0; +} + +internal RDIM_Type * +d2r_create_type(Arena *arena, D2R_TypeTable *type_table) +{ + RDIM_Type *type = rdim_type_chunk_list_push(arena, type_table->types, type_table->type_chunk_cap); + return type; +} + +internal RDIM_Type * +d2r_find_or_create_type_from_offset(Arena *arena, D2R_TypeTable *type_table, U64 info_off) +{ + RDIM_Type *type = 0; + KeyValuePair *is_type_present = hash_table_search_u64(type_table->ht, info_off); + if (is_type_present) { + type = is_type_present->value_raw; + } else { + type = d2r_create_type(arena, type_table); + hash_table_push_u64_raw(arena, type_table->ht, info_off, type); + } + return type; +} + +internal RDIM_Type * +d2r_type_from_attrib(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +{ + RDIM_Type *type = 0; + + // find attrib + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + + // does tag have this attribute? + if (attrib->attrib_kind == kind) { + DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); + + if (value_class == DW_AttribClass_Reference) { + // resolve reference + DW_Reference ref = dw_ref_from_attrib_ptr(input, cu, attrib); + + // TODO: support for external compile unit references + AssertAlways(ref.cu == cu); + + // find or create type + type = d2r_find_or_create_type_from_offset(arena, type_table, ref.info_off); + } else { + Assert(!"unexpected attrib class"); + } + } else if (attrib->attrib_kind == DW_Attrib_Null) { + type = type_table->void_type; + } + + return type; +} + +internal Rng1U64List +d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag) +{ + // collect non-contiguous range + Rng1U64List ranges = dw_rnglist_from_attrib(arena, input, cu, tag, DW_Attrib_Ranges); + + // collect contiguous range + DW_Attrib *lo_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_LowPc); + DW_Attrib *hi_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_HighPc); + if (lo_pc_attrib->attrib_kind != DW_Attrib_Null && hi_pc_attrib->attrib_kind != DW_Attrib_Null) { + U64 lo_pc = dw_address_from_attrib_ptr(input, cu, lo_pc_attrib); + + U64 hi_pc; + DW_AttribClass hi_pc_class = dw_value_class_from_attrib(cu, hi_pc_attrib); + if (hi_pc_class == DW_AttribClass_Address) { + hi_pc = dw_address_from_attrib_ptr(input, cu, hi_pc_attrib); + } else if (hi_pc_class == DW_AttribClass_Const) { + hi_pc = dw_const_u64_from_attrib_ptr(input, cu, hi_pc_attrib); + hi_pc += lo_pc; + } else { + AssertAlways(!"undefined attrib encoding"); + } + + // TODO: error handling + AssertAlways(lo_pc >= image_base); + AssertAlways(hi_pc >= image_base); + AssertAlways(lo_pc <= hi_pc); + + U64 lo_voff = lo_pc - image_base; + U64 hi_voff = hi_pc - image_base; + rng1u64_list_push(arena, &ranges, rng_1u64(lo_voff, hi_voff)); + } + + return ranges; +} + +internal RDIM_Type ** +d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out) +{ + Temp scratch = scratch_begin(&arena, 1); + + RDIM_TypeList list = {0}; + B32 has_vargs = 0; + for (DW_TagNode *i = cur_node->first_child; i != 0; i = i->sibling) { + if (i->tag.kind == DW_Tag_FormalParameter) { + RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1); + n->v = d2r_type_from_attrib(arena, type_table, input, cu, i->tag, DW_Attrib_Type); + SLLQueuePush(list.first, list.last, n); + ++list.count; + } else if (i->tag.kind == DW_Tag_UnspecifiedParameters) { + has_vargs = 1; + } + } + + if (has_vargs) { + RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1); + n->v = type_table->varg_type; + SLLQueuePush(list.first, list.last, n); + ++list.count; + } + + // collect params + *param_count_out = list.count; + RDIM_Type **params = rdim_array_from_type_list(arena, list); + + scratch_end(scratch); + return params; +} + + +internal RDIM_EvalBytecode +d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +{ + RDIM_EvalBytecode bc = {0}; + + for (U64 cursor = 0; cursor < expr.size; ) { + U8 op = 0; + cursor += str8_deserial_read_struct(expr, cursor, &op); + + U64 size_param; + switch (op) { + case DW_ExprOp_Lit0: case DW_ExprOp_Lit1: case DW_ExprOp_Lit2: + case DW_ExprOp_Lit3: case DW_ExprOp_Lit4: case DW_ExprOp_Lit5: + case DW_ExprOp_Lit6: case DW_ExprOp_Lit7: case DW_ExprOp_Lit8: + case DW_ExprOp_Lit9: case DW_ExprOp_Lit10: case DW_ExprOp_Lit11: + case DW_ExprOp_Lit12: case DW_ExprOp_Lit13: case DW_ExprOp_Lit14: + case DW_ExprOp_Lit15: case DW_ExprOp_Lit16: case DW_ExprOp_Lit17: + case DW_ExprOp_Lit18: case DW_ExprOp_Lit19: case DW_ExprOp_Lit20: + case DW_ExprOp_Lit21: case DW_ExprOp_Lit22: case DW_ExprOp_Lit23: + case DW_ExprOp_Lit24: case DW_ExprOp_Lit25: case DW_ExprOp_Lit26: + case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29: + case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: { + U64 lit = op - DW_ExprOp_Lit0; + rdim_bytecode_push_uconst(arena, &bc, lit); + } break; + + case DW_ExprOp_Const1U: size_param = 1; goto const_unsigned; + case DW_ExprOp_Const2U: size_param = 2; goto const_unsigned; + case DW_ExprOp_Const4U: size_param = 4; goto const_unsigned; + case DW_ExprOp_Const8U: size_param = 8; goto const_unsigned; + const_unsigned: { + U64 val = 0; + cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); + rdim_bytecode_push_uconst(arena, &bc, val); + } break; + + case DW_ExprOp_Const1S:size_param = 1; goto const_signed; + case DW_ExprOp_Const2S:size_param = 2; goto const_signed; + case DW_ExprOp_Const4S:size_param = 4; goto const_signed; + case DW_ExprOp_Const8S:size_param = 8; goto const_signed; + const_signed: { + S64 val = 0; + cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); + val = extend_sign64(val, size_param); + rdim_bytecode_push_sconst(arena, &bc, val); + } break; + + case DW_ExprOp_ConstU: { + U64 val = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &val); + rdim_bytecode_push_uconst(arena, &bc, val); + } break; + + case DW_ExprOp_ConstS: { + S64 val = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, &val); + rdim_bytecode_push_sconst(arena, &bc, val); + } break; + + case DW_ExprOp_Addr: { + U64 addr = 0; + cursor += str8_deserial_read(expr, cursor, &addr, address_size, address_size); + if (addr >= image_base) { + U64 voff = addr - image_base; + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_ModuleOff, voff); + } else { + // TODO: error handling + AssertAlways(!"unable to relocate address"); + } + } break; + + case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2: + case DW_ExprOp_Reg3: case DW_ExprOp_Reg4: case DW_ExprOp_Reg5: + case DW_ExprOp_Reg6: case DW_ExprOp_Reg7: case DW_ExprOp_Reg8: + case DW_ExprOp_Reg9: case DW_ExprOp_Reg10: case DW_ExprOp_Reg11: + case DW_ExprOp_Reg12: case DW_ExprOp_Reg13: case DW_ExprOp_Reg14: + case DW_ExprOp_Reg15: case DW_ExprOp_Reg16: case DW_ExprOp_Reg17: + case DW_ExprOp_Reg18: case DW_ExprOp_Reg19: case DW_ExprOp_Reg20: + case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23: + case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26: + case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: + case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { + U64 reg_code_dw = op - DW_ExprOp_Reg0; + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + } break; + + case DW_ExprOp_RegX: { + U64 reg_code_dw = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, ®_code_dw); + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + } break; + + case DW_ExprOp_ImplicitValue: { + U64 value_size = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &value_size); + + String8 val = str8_substr(expr, rng_1u64(cursor, cursor + value_size)); + if (val.size <= sizeof(U64)) { + U64 val64 = 0; + MemoryCopy(&val64, val.str, val.size); + rdim_bytecode_push_uconst(arena, &bc, val64); + } else { + // TODO: currenlty no way to encode string in RDIM_EvalBytecodeOp + NotImplemented; + } + } break; + + case DW_ExprOp_Piece: { + NotImplemented; + } break; + + case DW_ExprOp_BitPiece: { + NotImplemented; + } break; + + case DW_ExprOp_Pick: { + U8 stack_idx = 0; + cursor += str8_deserial_read_struct(expr, cursor, &stack_idx); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Pick, stack_idx); + } break; + + case DW_ExprOp_PlusUConst: { + U64 addend = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &addend); + rdim_bytecode_push_uconst(arena, &bc, addend); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_Skip: { + S16 skip = 0; + cursor += str8_deserial_read_struct(expr, cursor, &skip); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Skip, skip); + } break; + + case DW_ExprOp_Bra: { + NotImplemented; + } break; + + case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2: + case DW_ExprOp_BReg3: case DW_ExprOp_BReg4: case DW_ExprOp_BReg5: + case DW_ExprOp_BReg6: case DW_ExprOp_BReg7: case DW_ExprOp_BReg8: + case DW_ExprOp_BReg9: case DW_ExprOp_BReg10: case DW_ExprOp_BReg11: + case DW_ExprOp_BReg12: case DW_ExprOp_BReg13: case DW_ExprOp_BReg14: + case DW_ExprOp_BReg15: case DW_ExprOp_BReg16: case DW_ExprOp_BReg17: + case DW_ExprOp_BReg18: case DW_ExprOp_BReg19: case DW_ExprOp_BReg20: + case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23: + case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26: + case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29: + case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: { + U64 reg_code_dw = op - DW_ExprOp_BReg0; + S64 reg_off = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, ®_off); + + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_BRegX: { + U64 reg_code_dw = 0; + S64 reg_off = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, ®_code_dw); + cursor += str8_deserial_read_sleb128(expr, cursor, ®_off); + + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_FBReg: { + S64 frame_off = 0; + cursor += str8_deserial_read_sleb128(expr, cursor, &frame_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_FrameOff, frame_off); + } break; + + case DW_ExprOp_Deref: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_MemRead, address_size); + } break; + + case DW_ExprOp_DerefSize: { + U8 deref_size_in_bytes = 0; + cursor += str8_deserial_read_struct(expr, cursor, &deref_size_in_bytes); + if (0 < deref_size_in_bytes && deref_size_in_bytes <= address_size) { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_MemRead, deref_size_in_bytes); + } else { + // TODO: error handling + AssertAlways(!"ill formed expression"); + } + } break; + + case DW_ExprOp_XDerefSize: { + // TODO: error handling + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Call2: + case DW_ExprOp_Call4: + case DW_ExprOp_CallRef: { + // TODO: error handling + AssertAlways(!"calls are not supported"); + } break; + + case DW_ExprOp_ImplicitPointer: + case DW_ExprOp_GNU_ImplicitPointer: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Convert: + case DW_ExprOp_GNU_Convert: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_GNU_ParameterRef: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_DerefType: + case DW_ExprOp_GNU_DerefType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_ConstType: + case DW_ExprOp_GNU_ConstType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_RegvalType: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_EntryValue: + case DW_ExprOp_GNU_EntryValue: { + U64 block_size = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &block_size); + + String8 entry_value_expr = {0}; + cursor += str8_deserial_read_block(expr, cursor, block_size, &entry_value_expr); + + RDIM_EvalBytecode entry_value_bc = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, entry_value_expr); + } break; + + case DW_ExprOp_Addrx: { + U64 addr_idx = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &addr_idx); + U64 addr = dw_addr_from_list_unit(addr_lu, addr_idx); + if (addr != max_U64) { + if (addr >= image_base) { + U64 voff = addr - image_base; + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_ModuleOff, voff); + } else { + // TODO: error handling + AssertAlways(!"unable to relocate address"); + } + } else { + // TODO: error handling + AssertAlways(!"out of bounds index"); + } + } break; + + case DW_ExprOp_CallFrameCfa: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_FrameOff, 0); + } break; + + case DW_ExprOp_FormTlsAddress: { + // TODO: + AssertAlways(!"RDI_EvalOp_TLSOff accepts immediate"); + } break; + + case DW_ExprOp_PushObjectAddress: { + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Nop: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Noop, 0); + } break; + + case DW_ExprOp_Eq: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_EqEq, 0); + } break; + + case DW_ExprOp_Ge: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_GrEq, 0); + } break; + + case DW_ExprOp_Gt: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Grtr, 0); + } break; + + case DW_ExprOp_Le: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LsEq, 0); + } break; + + case DW_ExprOp_Lt: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Less, 0); + } break; + + case DW_ExprOp_Ne: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_NtEq, 0); + } break; + + case DW_ExprOp_Shl: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LShift, 0); + } break; + + case DW_ExprOp_Shr: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RShift, 0); + } break; + + case DW_ExprOp_Shra: { + // TODO: + AssertAlways(!"sample"); + } break; + + case DW_ExprOp_Xor: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitXor, 0); + } break; + + case DW_ExprOp_XDeref: { + // TODO: error handling + Assert(!"multiple address spaces are not supported"); + } break; + + case DW_ExprOp_Abs: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Abs, 0); + } break; + + case DW_ExprOp_And: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitAnd, 0); + } break; + + case DW_ExprOp_Div: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Div, 0); + } break; + + case DW_ExprOp_Minus: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Sub, 0); + } break; + + case DW_ExprOp_Mod: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mod, 0); + } break; + + case DW_ExprOp_Mul: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mul, 0); + } break; + + case DW_ExprOp_Neg: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Neg, 0); + } break; + + case DW_ExprOp_Not: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitNot, 0); + } break; + + case DW_ExprOp_Or: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitOr, 0); + } break; + + case DW_ExprOp_Plus: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + } break; + + case DW_ExprOp_Rot: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Swap: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Dup: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Drop: { + AssertAlways(!"no suitable conversion"); + } break; + + case DW_ExprOp_Over: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Pick, 1); + } break; + + case DW_ExprOp_StackValue: { + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Stop, 0); + } break; + + default: InvalidPath; break; + } + } + + return bc; +} + +internal RDIM_Location * +d2r_transpile_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +{ + RDIM_Location *loc = 0; + if (expr.size) { + loc = push_array(arena, RDIM_Location, 1); + loc->kind = RDI_LocationKind_AddrBytecodeStream; + loc->bytecode = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, expr); + } + return loc; +} + +internal RDIM_LocationSet +d2r_convert_loclist(Arena *arena, RDIM_ScopeChunkList *scopes, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, DW_LocList loclist) +{ +} + +internal RDIM_Location * +d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, RDI_Arch arch, DW_Tag tag, DW_AttribKind kind) +{ + String8 expr = dw_exprloc_from_attrib(input, cu, tag, kind); + RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, expr); + return location; +} + +internal RDIM_LocationSet +d2r_locset_from_attrib(Arena *arena, + DW_Input *input, + DW_CompUnit *cu, + RDIM_ScopeChunkList *scopes, + RDIM_Scope *curr_scope, + U64 image_base, + RDI_Arch arch, + DW_Tag tag, + DW_AttribKind kind) +{ + RDIM_LocationSet result = {0}; + + // extract attrib from tag + DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); + DW_AttribClass attrib_class = dw_value_class_from_attrib(cu, attrib); + + if (attrib_class == DW_AttribClass_LocList || attrib_class == DW_AttribClass_LocListPtr) { + Temp scratch = scratch_begin(&arena, 1); + + // extract location list from attrib + DW_LocList loclist = dw_loclist_from_attrib_ptr(scratch.arena, input, cu, attrib); + + // convert location list to RDIM location set + for (DW_LocNode *loc_n = loclist.first; loc_n != 0; loc_n = loc_n->next) { + RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, loc_n->v.expr); + RDIM_Rng1U64 voff_range = { .min = loc_n->v.range.min - image_base, .min = loc_n->v.range.max - image_base }; + rdim_location_set_push_case(arena, scopes, &result, voff_range, location); + } + + scratch_end(scratch); + } else if (attrib_class == DW_AttribClass_ExprLoc) { + // extract expression from attrib + String8 expr = dw_exprloc_from_attrib_ptr(input, cu, attrib); + + // convert expression and inherit life-time ranges from enclosed scope + RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, expr); + for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { + rdim_location_set_push_case(arena, scopes, &result, range_n->v, location); + } + } else if (attrib_class != DW_AttribClass_Null) { + AssertAlways(!"unexpected attrib class"); + } + + return result; +} + +internal D2R_CompUnitContribMap +d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8 aranges_data = input->sec[DW_Section_ARanges].data; + Rng1U64List unit_range_list = dw_unit_ranges_from_data(scratch.arena, aranges_data); + + D2R_CompUnitContribMap cm = {0}; + cm.count = 0; + cm.info_off_arr = push_array(arena, U64, unit_range_list.count); + cm.voff_range_arr = push_array(arena, RDIM_Rng1U64List, unit_range_list.count); + + for (Rng1U64Node *range_n = unit_range_list.first; range_n != 0; range_n = range_n->next) { + String8 unit_data = str8_substr(aranges_data, range_n->v); + U64 unit_cursor = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, unit_cursor, &unit_length); + if (unit_length_size == 0) { + continue; + } + unit_cursor += unit_length_size; + + DW_Version version = 0; + U64 version_size = str8_deserial_read_struct(unit_data, unit_cursor, &version); + if (version_size == 0) { + continue; + } + unit_cursor += version; + + if (version != DW_Version_2) { + AssertAlways(!"unknown .debug_aranges version"); + continue; + } + + DW_Format unit_format = DW_FormatFromSize(unit_length); + U64 cu_info_off = 0; + U64 cu_info_off_size = str8_deserial_read_dwarf_uint(unit_data, unit_cursor, unit_format, &cu_info_off); + if (cu_info_off_size == 0) { + continue; + } + unit_cursor += cu_info_off_size; + + U8 address_size = 0; + U64 address_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &address_size); + if (address_size_size == 0) { + continue; + } + unit_cursor += address_size_size; + + U8 segment_selector_size = 0; + U64 segment_selector_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &segment_selector_size); + if (segment_selector_size_size == 0) { + continue; + } + unit_cursor += segment_selector_size_size; + + U64 tuple_size = address_size * 2 + segment_selector_size; + U64 bytes_too_far_past_boundary = unit_cursor % tuple_size; + if (bytes_too_far_past_boundary > 0) { + unit_cursor += tuple_size - bytes_too_far_past_boundary; + } + + RDIM_Rng1U64List voff_ranges = {0}; + if (segment_selector_size == 0) { + while (unit_cursor + address_size * 2 <= unit_data.size) { + U64 address = 0; + U64 length = 0; + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, address_size, address_size); + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &length, address_size, address_size); + + if (address == 0 && length == 0) { + break; + } + + // TODO: error handling + AssertAlways(address >= image_base); + + U64 min = address - image_base; + U64 max = min + length; + rdim_rng1u64_list_push(arena, &voff_ranges, (RDIM_Rng1U64){.min = min, .max = max}); + } + } else { + // TODO: segment relative addressing + NotImplemented; + } + + U64 map_idx = cm.count++; + cm.info_off_arr[map_idx] = cu_info_off; + cm.voff_range_arr[map_idx] = voff_ranges; + } + + scratch_end(scratch); + return cm; +} + +internal RDIM_Rng1U64List +d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off) +{ + RDIM_Rng1U64List voff_ranges = {0}; + U64 voff_list_idx = u64_array_bsearch(map.info_off_arr, map.count, info_off); + if (voff_list_idx < map.count) { + voff_ranges = map.voff_range_arr[voff_list_idx]; + } + return voff_ranges; +} + +internal RDIM_Scope * +d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D2R_TagNode *tag_stack, Rng1U64List ranges) +{ + // fill out scope + RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, scopes, scope_chunk_cap); + + // push ranges + for (Rng1U64Node *i = ranges.first; i != 0; i = i->next) { + rdim_scope_push_voff_range(arena, scopes, scope, (RDIM_Rng1U64){.min = i->v.min, i->v.max}); + } + + // associate scope with tag + tag_stack->scope = scope; + + // update scope hierarchy + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || parent_tag_kind == DW_Tag_InlinedSubroutine || parent_tag_kind == DW_Tag_LexicalBlock) { + RDIM_Scope *parent = tag_stack->next->scope; + + scope->parent_scope = tag_stack->next->scope; + + if (parent->last_child) { + parent->last_child->next_sibling = scope; + } + + SLLQueuePush_N(parent->first_child, parent->last_child, scope, next_sibling); + } + + // propagate scope symbol + if (tag_stack->cur_node->tag.kind == DW_Tag_LexicalBlock) { + scope->symbol = tag_stack->next->scope->symbol; + } + + return scope; +} + +internal RDIM_BakeParams * +d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +{ + Temp scratch = scratch_begin(&arena, 1); + + //////////////////////////////// + + ProfBegin("compute exe hash"); + U64 exe_hash = rdi_hash(in->image_data.str, in->image_data.size); + ProfEnd(); + + //////////////////////////////// + + RDI_Arch arch = RDI_Arch_NULL; + RDIM_BinarySectionList binary_sections = {0}; + RDIM_TopLevelInfo top_level_info = {0}; + + U64 image_base = 0; + DW_Input input = {0}; + DW_ListUnitInput lui = {0}; + + if (in->image == Image_CoffPe) { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, in->image_data); + + // convert arch + switch (pe.arch) { + case Arch_Null: arch = RDI_Arch_NULL; break; + case Arch_x64: arch = RDI_Arch_X64; break; + case Arch_x86: arch = RDI_Arch_X86; break; + default: NotImplemented; break; + } + + // get image base + image_base = pe.image_base; + + // get COFF sections + String8 raw_sections = str8_substr(in->image_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); + U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); + COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; + + // convert sections & top level info + binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, in->image_data, pe.string_table_off, section_count, section_array); + top_level_info = c2r_make_rdim_top_level_info(in->image_name, arch, exe_hash, section_count, section_array); + + // find DWARF sections + input = dw_input_from_coff_section_table(scratch.arena, in->image_data, pe.string_table_off, section_count, section_array); + } else if (in->image == Image_Elf32 || in->image == Image_Elf64) { + ELF_BinInfo elf = elf_bin_from_data(in->debug_data); + + // get image base + image_base = elf_base_addr_from_bin(&elf.hdr); + + // convert arch + switch (elf.hdr.e_machine) { + case ELF_MachineKind_None: arch = RDI_Arch_NULL; break; + case ELF_MachineKind_X86_64: arch = RDI_Arch_X64; break; + case ELF_MachineKind_386: arch = RDI_Arch_X86; break; + default: NotImplemented; break; + } + + ELF_Shdr64Array shdrs = elf_shdr64_array_from_bin(scratch.arena, in->debug_data, &elf.hdr); + + // convert sections & top level info + binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, shdrs); + top_level_info = e2r_make_rdim_top_level_info(in->debug_data, exe_hash, shdrs); + + // find DWARF sections + input = dw_input_from_elf_section_table(scratch.arena, in->debug_data, &elf); + } else { + InvalidPath; + } + + //////////////////////////////// + + U64 arch_addr_size = rdi_addr_size_from_arch(arch); + + //////////////////////////////// + + static const U64 UNIT_CHUNK_CAP = 256; + static const U64 UDT_CHUNK_CAP = 256; + static const U64 TYPE_CHUNK_CAP = 256; + static const U64 GVAR_CHUNK_CAP = 256; + static const U64 TVAR_CHUNK_CAP = 256; + static const U64 PROC_CHUNK_CAP = 256; + static const U64 SCOPE_CHUNK_CAP = 256; + static const U64 INLINE_SITE_CHUNK_CAP = 256; + static const U64 SRC_FILE_CAP = 256; + static const U64 LINE_TABLE_CAP = 256; + static const U64 CALL_SITE_CHUNK_CAP = 256; + + RDIM_UnitChunkList units = {0}; + RDIM_UDTChunkList udts = {0}; + RDIM_TypeChunkList types = {0}; + RDIM_SymbolChunkList gvars = {0}; + RDIM_SymbolChunkList tvars = {0}; + RDIM_SymbolChunkList procs = {0}; + RDIM_ScopeChunkList scopes = {0}; + RDIM_InlineSiteChunkList inline_sites = {0}; + RDIM_SrcFileChunkList src_files = {0}; + RDIM_LineTableChunkList line_tables = {0}; + + //////////////////////////////// + + RDIM_Scope *global_scope = rdim_scope_chunk_list_push(arena, &scopes, SCOPE_CHUNK_CAP); + + //////////////////////////////// + + ProfBegin("Make Unit Contrib Map"); + D2R_CompUnitContribMap cu_contrib_map = {0}; + if (input.sec[DW_Section_ARanges].data.size > 0) { + cu_contrib_map = d2r_cu_contrib_map_from_aranges(arena, &input, image_base); + } else { + // TODO: synthesize cu ranges from scopes + NotImplemented; + } + ProfEnd(); + + ProfBegin("Parse Comop Unit Ranges"); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &input); + Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input.sec[DW_Section_Info].data); + Rng1U64Array cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list); + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Parse Compile Unit Headers"); + B32 is_parse_relaxed = !(in->flags & RC_Flag_StrictDwarfParse); + DW_CompUnit *cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count); + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, &input, lu_input, cu_ranges.v[cu_idx].min, is_parse_relaxed); + } + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Parse Line Tables"); + DW_LineTableParseResult *cu_line_tables = push_array(scratch.arena, DW_LineTableParseResult, cu_ranges.count); + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + DW_CompUnit *cu = &cu_arr[cu_idx]; + String8 cu_stmt_list = dw_line_ptr_from_attrib(&input, cu, cu->tag, DW_Attrib_StmtList); + String8 cu_dir = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_CompDir); + String8 cu_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Name); + cu_line_tables[cu_idx] = dw_parsed_line_table_from_data(scratch.arena, cu_stmt_list, &input, cu_dir, cu_name, cu->address_size, cu->str_offsets_lu); + } + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Convert Line Tables"); + + HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000); + RDIM_LineTable **cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count); + + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP); + + DW_LineTableParseResult *line_table = &cu_line_tables[cu_idx]; + DW_LineVMFileArray *dir_table = &line_table->vm_header.dir_table; + DW_LineVMFileArray *file_table = &line_table->vm_header.file_table; + RDIM_SrcFile **src_file_map = push_array(scratch.arena, RDIM_SrcFile *, file_table->count); + for (U64 file_idx = 0; file_idx < file_table->count; ++file_idx) { + DW_LineFile *file = &file_table->v[file_idx]; + String8 file_path = dw_path_from_file_idx(scratch.arena, &line_table->vm_header, file_idx); + String8List file_path_split = str8_split_path(scratch.arena, file_path); + str8_path_list_resolve_dots_in_place(&file_path_split, PathStyle_WindowsAbsolute); + String8 file_path_resolved = str8_path_list_join_by_style(scratch.arena, &file_path_split, PathStyle_WindowsAbsolute); + String8 file_path_normalized = lower_from_str8(scratch.arena, file_path_resolved); + RDIM_SrcFile *src_file = hash_table_search_path_raw(source_file_ht, file_path_normalized); + if (src_file == 0) { + src_file = rdim_src_file_chunk_list_push(arena, &src_files, SRC_FILE_CAP); + src_file->normal_full_path = push_str8_copy(arena, file_path_normalized); + hash_table_push_path_raw(scratch.arena, source_file_ht, src_file->normal_full_path, src_file); + } + src_file_map[file_idx] = src_file; + } + + for (DW_LineSeqNode *line_seq = line_table->first_seq; line_seq != 0; line_seq = line_seq->next) { + if (line_seq->count == 0) { + continue; + } + + U64 *voffs = push_array(arena, U64, line_seq->count); + U32 *line_nums = push_array(arena, U32, line_seq->count); + U16 *col_nums = 0; + U64 line_idx = 0; + + DW_LineNode *file_line_n = line_seq->first; + U64 file_line_count = 0; + + for (DW_LineNode *line_n = file_line_n; line_n != 0; line_n = line_n->next) { + if (file_line_n->v.file_index != line_n->v.file_index || line_n->next == 0) { + U64 file_index = file_line_n->v.file_index; + U64 *file_voffs = &voffs[line_idx]; + U32 *file_line_nums = &line_nums[line_idx]; + U16 *file_col_nums = 0; + + U64 lines_written = 0; + U64 prev_ln = max_U64; + DW_LineNode *sentinel = line_n->v.file_index != file_line_n->v.file_index ? line_n : 0; + for (; file_line_n != sentinel; file_line_n = file_line_n->next) { + if (file_line_n->v.line != prev_ln) { + // TODO: error handling + AssertAlways(file_line_n->v.address >= image_base); + + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + + ++lines_written; + ++line_idx; + + prev_ln = file_line_n->v.line; + } + } + + RDIM_SrcFile *src_file = src_file_map[file_index]; + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, lines_written); + rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + + file_line_count = 1; + } else { + ++file_line_count; + } + } + + // handle last line + if (file_line_n) { + U64 file_index = file_line_n->v.file_index; + U64 *file_voffs = &voffs[line_idx]; + U32 *file_line_nums = &line_nums[line_idx]; + U16 *file_col_nums = 0; + + for (; file_line_n != 0; file_line_n = file_line_n->next, ++line_idx) { + // TODO: error handling + AssertAlways(file_line_n->v.address >= image_base); + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + } + + RDIM_SrcFile *src_file = src_file_map[file_index]; + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, file_line_count); + rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + } + + //Assert(line_idx == line_seq->count); + } + } + + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Convert Units"); + + for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { + Temp comp_temp = temp_begin(scratch.arena); + + DW_CompUnit *cu = &cu_arr[cu_idx]; + + // parse and build tag tree + DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu); + + // build tag hash table for abstract origin resolution + cu->tag_ht = dw_make_tag_hash_table(comp_temp.arena, tag_tree); + + String8 dwo_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_DwoName); + String8 gnu_dwo_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_GNU_DwoName); + if (dwo_name.size || gnu_dwo_name.size || cu->dwo_id) { + // TODO: report that we dont support DWO + continue; + } + + // get unit's contribution ranges + RDIM_Rng1U64List cu_voff_ranges = d2r_voff_ranges_from_cu_info_off(cu_contrib_map, cu_ranges.v[cu_idx].min); + + String8 cu_name = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Name); + String8 cu_dir = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_CompDir); + String8 cu_prod = dw_string_from_attrib(&input, cu, cu->tag, DW_Attrib_Producer); + DW_Language cu_lang = dw_const_u64_from_attrib(&input, cu, cu->tag, DW_Attrib_Language); + + RDIM_Unit *unit = rdim_unit_chunk_list_push(arena, &units, UNIT_CHUNK_CAP); + unit->unit_name = cu_name; + unit->compiler_name = cu_prod; + unit->source_file = str8_zero(); + unit->object_file = str8_zero(); + unit->archive_file = str8_zero(); + unit->build_path = cu_dir; + unit->language = rdi_language_from_dw_language(cu_lang); + unit->line_table = cu_line_tables_rdi[cu_idx]; + unit->voff_ranges = cu_voff_ranges; + + D2R_TypeTable *type_table = push_array(comp_temp.arena, D2R_TypeTable, 1); + type_table->ht = hash_table_init(comp_temp.arena, 0x4000); + type_table->types = &types; + type_table->type_chunk_cap = TYPE_CHUNK_CAP; + type_table->void_type = d2r_create_type(arena, type_table); + type_table->void_type->kind = RDI_TypeKind_Void; + type_table->varg_type = d2r_create_type(arena, type_table); + type_table->varg_type->kind = RDI_TypeKind_Variadic; + + D2R_TagNode *free_tags = push_array(comp_temp.arena, D2R_TagNode, 1); + D2R_TagNode *tag_stack = push_array(comp_temp.arena, D2R_TagNode, 1); + tag_stack->cur_node = tag_tree.root; + + while (tag_stack) { + while (tag_stack->cur_node) { + DW_TagNode *cur_node = tag_stack->cur_node; + DW_Tag tag = cur_node->tag; + B32 visit_children = 1; + + switch (tag.kind) { + case DW_Tag_Null: { + InvalidPath; + } break; + case DW_Tag_ClassType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteClass; + + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Class; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + tag_stack->type = type; + } + } break; + case DW_Tag_StructureType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteStruct; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Struct; + type->udt = udt; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + + tag_stack->type = type; + } + } break; + case DW_Tag_UnionType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteUnion; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Union; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + + tag_stack->type = type; + } + } break; + case DW_Tag_EnumerationType: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + + B32 is_decl = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_Declaration); + if (is_decl) { + type->kind = RDI_TypeKind_IncompleteEnum; + + // TODO: error handling + Assert(!cur_node->first_child); + visit_children = 0; + } else { + RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); + udt->self_type = type; + + type->kind = RDI_TypeKind_Enum; + type->byte_size = dw_byte_size_32_from_tag(&input, cu, tag); + type->udt = udt; + + tag_stack->type = type; + } + } break; + case DW_Tag_SubroutineType: { + // collect parameters + RDIM_TypeList param_list = {0}; + for (DW_TagNode *n = cur_node->first_child; n != 0; n = n->sibling) { + if (n->tag.kind == DW_Tag_FormalParameter) { + RDIM_Type *param_type = d2r_type_from_attrib(arena, type_table, &input, cu, n->tag, DW_Attrib_Type); + rdim_type_list_push(comp_temp.arena, ¶m_list, param_type); + } else if (n->tag.kind == DW_Tag_UnspecifiedParameters) { + rdim_type_list_push(comp_temp.arena, ¶m_list, type_table->varg_type); + } else { + // TODO: error handling + AssertAlways(!"unexpected tag"); + } + } + + // init proceudre type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Function; + type->byte_size = arch_addr_size; + type->direct_type = ret_type; + type->count = param_list.count; + type->param_types = rdim_array_from_type_list(arena, param_list); + + visit_children = 0; + } break; + case DW_Tag_Typedef: { + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Alias; + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_BaseType: { + DW_ATE encoding = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_Encoding); + U64 byte_size = dw_byte_size_from_tag(&input, cu, tag); + + // convert base type encoding to RDI version + RDI_TypeKind kind = RDI_TypeKind_NULL; + switch (encoding) { + case DW_ATE_Null: kind = RDI_TypeKind_NULL; break; + case DW_ATE_Address: kind = RDI_TypeKind_Void; break; + case DW_ATE_Boolean: kind = RDI_TypeKind_Bool; break; + case DW_ATE_ComplexFloat: { + switch (byte_size) { + case 4: kind = RDI_TypeKind_ComplexF32; break; + case 8: kind = RDI_TypeKind_ComplexF64; break; + case 10: kind = RDI_TypeKind_ComplexF80; break; + case 16: kind = RDI_TypeKind_ComplexF128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Float: { + switch (byte_size) { + case 2: kind = RDI_TypeKind_F16; break; + case 4: kind = RDI_TypeKind_F32; break; + case 6: kind = RDI_TypeKind_F48; break; + case 8: kind = RDI_TypeKind_F64; break; + case 16: kind = RDI_TypeKind_F128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Signed: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_S8; break; + case 2: kind = RDI_TypeKind_S16; break; + case 4: kind = RDI_TypeKind_S32; break; + case 8: kind = RDI_TypeKind_S64; break; + case 16: kind = RDI_TypeKind_S128; break; + case 32: kind = RDI_TypeKind_S256; break; + case 64: kind = RDI_TypeKind_S512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_SignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_Char8; break; + case 2: kind = RDI_TypeKind_Char16; break; + case 4: kind = RDI_TypeKind_Char32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Unsigned: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_U8; break; + case 2: kind = RDI_TypeKind_U16; break; + case 4: kind = RDI_TypeKind_U32; break; + case 8: kind = RDI_TypeKind_U64; break; + case 16: kind = RDI_TypeKind_U128; break; + case 32: kind = RDI_TypeKind_U256; break; + case 64: kind = RDI_TypeKind_U512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_UnsignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_UChar8; break; + case 2: kind = RDI_TypeKind_UChar16; break; + case 4: kind = RDI_TypeKind_UChar32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_ImaginaryFloat: { + NotImplemented; + } break; + case DW_ATE_PackedDecimal: { + NotImplemented; + } break; + case DW_ATE_NumericString: { + NotImplemented; + } break; + case DW_ATE_Edited: { + NotImplemented; + } break; + case DW_ATE_SignedFixed: { + NotImplemented; + } break; + case DW_ATE_UnsignedFixed: { + NotImplemented; + } break; + case DW_ATE_DecimalFloat: { + NotImplemented; + } break; + case DW_ATE_Utf: { + NotImplemented; + } break; + case DW_ATE_Ucs: { + NotImplemented; + } break; + case DW_ATE_Ascii: { + NotImplemented; + } break; + default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling + } + + RDIM_Type *base_type = d2r_create_type(arena, type_table); + base_type->kind = kind; + base_type->byte_size = byte_size; + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Alias; + type->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + type->direct_type = base_type; + } break; + case DW_Tag_PointerType: { + RDIM_Type *direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Allocated)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Associated)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_AddressClass)); + + U64 byte_size = arch_addr_size; + if (cu->version == DW_Version_5 || cu->relaxed) { + dw_try_byte_size_from_tag(&input, cu, tag, &byte_size); + } + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Ptr; + type->byte_size = byte_size; + type->direct_type = direct_type; + } break; + case DW_Tag_RestrictType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Restrict; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_VolatileType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Volatile; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_ConstType: { + // TODO: + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Name)); + Assert(!dw_tag_has_attrib(&input, cu, tag, DW_Attrib_Alignment)); + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Modifier; + type->byte_size = arch_addr_size; + type->flags = RDI_TypeModifierFlag_Const; + type->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + } break; + case DW_Tag_ArrayType: { + // * DWARF vs RDI Array Type Graph * + // + // For example lets take following decl: + // + // int (*foo[2])[3][4]; + // + // This compiles to in DWARF: + // + // foo -> DW_TAG_ArrayType -> (A0) DW_TAG_Subrange [2] + // \ + // -> (B0) DW_TAG_PointerType -> (A1) DW_TAG_ArrayType -> DW_TAG_Subrange [3] -> DW_Tag_Subrange [4] + // \ + // -> (B1) DW_TAG_BaseType (int) + // + // RDI expects: + // + // foo -> Array (2) -> Pointer -> Array (3) -> Array (4) -> int + // + // Note that DWARF forks the graph on DW_TAG_ArrayType to describe array ranges in branch A and + // in branch B describes array type which might be a struct, pointer, base type, or any other type tag. + // However, in RDI we have a simple list of type nodes and to convert we need to append type nodes from + // B to A. + + RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); + type->kind = RDI_TypeKind_Array; + type->direct_type = 0; + + U64 subrange_count = 0; + RDIM_Type *t = type; + for (DW_TagNode *n = cur_node->first_child; n != 0; n = n->sibling) { + if (n->tag.kind != DW_Tag_SubrangeType) { + // TODO: error handling + AssertAlways(!"unexpected tag"); + continue; + } + + if (subrange_count > 0) { + // init array type node + RDIM_Type *s = d2r_create_type(arena, type_table); + s->kind = RDI_TypeKind_Array; + s->direct_type = 0; + + // append new array type node + t->direct_type = s; + t = s; + } + + // resolve array lower bound + U64 lower_bound = 0; + if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_LowerBound)) { + lower_bound = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_LowerBound); + } else { + lower_bound = dw_pick_default_lower_bound(cu_lang); + } + + // resolve array upper bound + U64 upper_bound = 0; + if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_Count)) { + U64 count = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_Count); + upper_bound = lower_bound + count; + } else if (dw_tag_has_attrib(&input, cu, n->tag, DW_Attrib_UpperBound)) { + upper_bound = dw_u64_from_attrib(&input, cu, n->tag, DW_Attrib_UpperBound); + // turn upper bound into exclusive range + upper_bound += 1; + } else { + // zero size array + } + + t->count = upper_bound - lower_bound; + ++subrange_count; + } + + Assert(t->direct_type == 0); + t->direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + visit_children = 0; + } break; + case DW_Tag_SubrangeType: { + // TODO: error handling + AssertAlways(!"unexpected tag"); + } break; + case DW_Tag_Inheritance: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_StructureType && + parent_node->tag.kind != DW_Tag_ClassType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + RDIM_Type *parent = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, parent->udt); + member->kind = RDI_MemberKind_Base; + member->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + member->off = safe_cast_u32(dw_const_u32_from_attrib(&input, cu, tag, DW_Attrib_DataMemberLocation)); + } break; + case DW_Tag_Enumerator: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_EnumerationType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTEnumVal *member = rdim_udt_push_enum_val(arena, &udts, type->udt); + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + member->val = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_ConstValue); + } break; + case DW_Tag_Member: { + DW_TagNode *parent_node = tag_stack->next->cur_node; + if (parent_node->tag.kind != DW_Tag_StructureType && + parent_node->tag.kind != DW_Tag_ClassType && + parent_node->tag.kind != DW_Tag_UnionType && + parent_node->tag.kind != DW_Tag_EnumerationType) { + // TODO: error handling + AssertAlways(!"unexpected parent tag"); + } + + DW_Attrib *data_member_location = dw_attrib_from_tag(&input, cu, tag, DW_Attrib_DataMemberLocation); + DW_AttribClass data_member_location_class = dw_value_class_from_attrib(cu, data_member_location); + if (data_member_location_class == DW_AttribClass_LocList) { + AssertAlways(!"UDT member with multiple locations are not supported"); + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, type->udt); + member->kind = RDI_MemberKind_DataField; + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + member->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + member->off = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_DataMemberLocation); + } break; + case DW_Tag_SubProgram: { + DW_InlKind inl = dw_u64_from_attrib(&input, cu, tag, DW_Attrib_Inline); + switch (inl) { + case DW_Inl_NotInlined: { + U64 param_count = 0; + RDIM_Type **params = d2r_collect_proc_params(arena, type_table, &input, cu, cur_node, ¶m_count); + + // get return type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // fill out proc type + RDIM_Type *proc_type = d2r_create_type(arena, type_table); + proc_type->kind = RDI_TypeKind_Function; + proc_type->byte_size = arch_addr_size; + proc_type->direct_type = ret_type; + proc_type->count = param_count; + proc_type->param_types = params; + + // get container type + RDIM_Type *container_type = 0; + if (dw_tag_has_attrib(&input, cu, tag, DW_Attrib_ContainingType)) { + container_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_ContainingType); + } + + // get frame base expression + String8 frame_base_expr = dw_exprloc_from_attrib(&input, cu, tag, DW_Attrib_FrameBase); + + // get proc container symbol + RDIM_Symbol *proc = rdim_symbol_chunk_list_push(arena, &procs, PROC_CHUNK_CAP ); + + // make scope + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + RDIM_Scope *root_scope = d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + root_scope->symbol = proc; + + // fill out proc + proc->is_extern = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_External); + proc->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + proc->link_name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_LinkageName); + proc->type = proc_type; + proc->container_symbol = 0; + proc->container_type = container_type; + proc->root_scope = root_scope; + proc->frame_base = d2r_locset_from_attrib(arena, &input, cu, &scopes, root_scope, image_base, arch, tag, DW_Attrib_FrameBase); + + // sub program with user-defined parent tag is a method + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_ClassType || parent_tag_kind == DW_Tag_StructureType) { + RDI_MemberKind member_kind = RDI_MemberKind_NULL; + DW_VirtualityKind virtuality = dw_const_u64_from_attrib(&input, cu, tag, DW_Attrib_Virtuality); + switch (virtuality) { + case DW_VirtualityKind_None: member_kind = RDI_MemberKind_Method; break; + case DW_VirtualityKind_Virtual: member_kind = RDI_MemberKind_VirtualMethod; break; + case DW_VirtualityKind_PureVirtual: member_kind = RDI_MemberKind_VirtualMethod; break; // TODO: create kind for pure virutal + default: InvalidPath; break; + } + + RDIM_Type *type = tag_stack->next->type; + RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, type->udt); + member->kind = member_kind; + member->type = type; + member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + } else if (parent_tag_kind != DW_Tag_CompileUnit) { + AssertAlways(!"unexpected tag"); + } + + tag_stack->scope = root_scope; + } break; + case DW_Inl_DeclaredNotInlined: + case DW_Inl_DeclaredInlined: + case DW_Inl_Inlined: { + visit_children = 0; + } break; + default: InvalidPath; break; + } + } break; + case DW_Tag_InlinedSubroutine: { + U64 param_count = 0; + RDIM_Type **params = d2r_collect_proc_params(arena, type_table, &input, cu, tag_stack->cur_node, ¶m_count); + + // get return type + RDIM_Type *ret_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + // fill out proc type + RDIM_Type *proc_type = d2r_create_type(arena, type_table); + proc_type->kind = RDI_TypeKind_Function; + proc_type->byte_size = arch_addr_size; + proc_type->direct_type = ret_type; + proc_type->count = param_count; + proc_type->param_types = params; + + // get container type + RDIM_Type *owner = 0; + if (dw_tag_has_attrib(&input, cu, tag, DW_Attrib_ContainingType)) { + owner = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_ContainingType); + } + + // fill out inline site + RDIM_InlineSite *inline_site = rdim_inline_site_chunk_list_push(arena, &inline_sites, INLINE_SITE_CHUNK_CAP); + inline_site->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + inline_site->type = proc_type; + inline_site->owner = owner; + inline_site->line_table = 0; + + // make scope + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + RDIM_Scope *root_scope = d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + root_scope->inline_site = inline_site; + } break; + case DW_Tag_Variable: { + String8 name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + RDIM_Type *type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || + parent_tag_kind == DW_Tag_InlinedSubroutine || + parent_tag_kind == DW_Tag_LexicalBlock) { + RDIM_Scope *scope = tag_stack->next->scope; + RDIM_Local *local = rdim_scope_push_local(arena, &scopes, tag_stack->next->scope); + local->kind = RDI_LocalKind_Variable; + local->name = name; + local->type = type; + local->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, arch, tag, DW_Attrib_Location); + } else { + + // NOTE: due to a bug in clang in stb_sprint.h local variables + // are declared in global scope without a name + if (name.size == 0) { + break; + } + + RDIM_Symbol *gvar = rdim_symbol_chunk_list_push(arena, &gvars, GVAR_CHUNK_CAP); + gvar->is_extern = dw_flag_from_attrib(&input, cu, tag, DW_Attrib_External); + gvar->name = name; + gvar->link_name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_LinkageName); + gvar->type = type; + //gvar->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, global_scope, image_base, arch, tag, DW_Attrib_Location); + gvar->container_symbol = 0; + gvar->container_type = 0; // TODO: NotImplemented; + } + } break; + case DW_Tag_FormalParameter: { + DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; + if (parent_tag_kind == DW_Tag_SubProgram || parent_tag_kind == DW_Tag_InlinedSubroutine) { + RDIM_Scope *scope = tag_stack->next->scope; + RDIM_Local *param = rdim_scope_push_local(arena, &scopes, scope); + param->kind = RDI_LocalKind_Parameter; + param->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); + param->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); + param->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, arch, tag, DW_Attrib_Location); + } else { + // TODO: error handling + AssertAlways(!"this is a local variable"); + } + } break; + case DW_Tag_LexicalBlock: { + if (tag_stack->next->cur_node->tag.kind == DW_Tag_SubProgram || + tag_stack->next->cur_node->tag.kind == DW_Tag_InlinedSubroutine || + tag_stack->next->cur_node->tag.kind == DW_Tag_LexicalBlock) { + Rng1U64List ranges = d2r_range_list_from_tag(comp_temp.arena, &input, cu, image_base, tag); + d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); + } + } break; + case DW_Tag_Label: + case DW_Tag_CompileUnit: + case DW_Tag_UnspecifiedParameters: + break; + default: NotImplemented; break; + } + + if (tag_stack->cur_node->first_child && visit_children) { + D2R_TagNode *frame = free_tags; + if (frame) { + SLLStackPop(free_tags); + MemoryZeroStruct(frame); + } else { + frame = push_array(scratch.arena, D2R_TagNode, 1); + } + frame->cur_node = tag_stack->cur_node->first_child; + SLLStackPush(tag_stack, frame); + } else { + tag_stack->cur_node = tag_stack->cur_node->sibling; + } + } + + // recycle free frame + D2R_TagNode *frame = tag_stack; + SLLStackPop(tag_stack); + SLLStackPush(free_tags, frame); + + if (tag_stack) { + tag_stack->cur_node = tag_stack->cur_node->sibling; + } + } + + temp_end(comp_temp); + } + + ProfEnd(); + + { + for (RDIM_TypeChunkNode *chunk_n = types.first; chunk_n != 0; chunk_n = chunk_n->next) { + for (U64 i = 0; i < chunk_n->count; ++i) { + RDIM_Type *type = &chunk_n->v[i]; + if (type->kind == RDI_TypeKind_Alias) { + for (RDIM_Type *t = type->direct_type; t != 0; t = t->direct_type) { + if (t->byte_size != 0) { + type->byte_size = t->byte_size; + break; + } + } + } + } + } + } + + { + RDIM_TypeNode *type_stack = 0; + RDIM_TypeNode *free_types = 0; + + for (RDIM_TypeChunkNode *chunk_n = types.first; chunk_n != 0; chunk_n = chunk_n->next) { + for (U64 i = 0; i < chunk_n->count; ++i) { + RDIM_Type *type = &chunk_n->v[i]; + if (type->kind == RDI_TypeKind_Array) { + if (type->byte_size != 0) + continue; + + RDIM_Type *t; + for (t = type; t != 0 && t->kind == RDI_TypeKind_Array; t = t->direct_type) { + RDIM_TypeNode *f = free_types; + if (f == 0) { + f = push_array(scratch.arena, RDIM_TypeNode, 1); + } else { + SLLStackPop(free_types); + } + f->v = t; + SLLStackPush(type_stack, f); + } + + U64 base_type_size = 0; + if (t) { + base_type_size = t->byte_size; + } + + U64 array_size = base_type_size; + while (type_stack) { + if (type_stack->v->count) { + array_size *= type_stack->v->count; + } else { + array_size += type_stack->v->byte_size; + } + SLLStackPop(type_stack); + } + + type->count = 0; + type->byte_size = array_size; + + // recycle frames + free_types = type_stack; + type_stack = 0; + } + } + } + } + + //////////////////////////////// + + RDIM_BakeParams *bake_params = push_array(arena, RDIM_BakeParams, 1); + bake_params->top_level_info = top_level_info; + bake_params->binary_sections = binary_sections; + bake_params->units = units; + bake_params->types = types; + bake_params->udts = udts; + bake_params->src_files = src_files; + bake_params->line_tables = line_tables; + bake_params->global_variables = gvars; + bake_params->thread_variables = tvars; + bake_params->procedures = procs; + bake_params->scopes = scopes; + bake_params->inline_sites = inline_sites; + + scratch_end(scratch); + return bake_params; +} + +internal RDIM_BakeResults +d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +{ + return rdim_bake(state, in_params); +} + +internal RDIM_SerializedSectionBundle +d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in) +{ + RDIM_SerializedSectionBundle result = {0}; + return result; +} + +internal RDI_Language +rdi_language_from_dw_language(DW_Language v) +{ + RDI_Language result = RDI_Language_NULL; + switch (v) { + case DW_Language_Null: result = RDI_Language_NULL; break; + + case DW_Language_C89: + case DW_Language_C99: + case DW_Language_C11: + case DW_Language_C: + result = RDI_Language_C; + break; + + case DW_Language_CPlusPlus03: + case DW_Language_CPlusPlus11: + case DW_Language_CPlusPlus14: + case DW_Language_CPlusPlus: + result = RDI_Language_CPlusPlus; + break; + + default: NotImplemented; break; + } + return result; +} + +internal RDI_RegCodeX86 +rdi_reg_from_dw_reg_x86(DW_RegX86 v) +{ + RDI_RegCodeX86 result = RDI_RegCode_nil; + switch (v) { +#define X(reg_dw, val_dw, reg_rdi, ...) case DW_RegX86_##reg_dw: result = RDI_RegCodeX86_##reg_rdi; break; + DW_Regs_X86_XList(X) +#undef X + default: NotImplemented; break; + } + return result; +} + +internal B32 +rdi_reg_from_dw_reg_x64(DW_RegX64 v, RDI_RegCodeX64 *code_out, U64 *off_out, U64 *size_out) +{ + RDI_RegCodeX64 result = RDI_RegCode_nil; + switch (v) { +#define X(reg_dw, val_dw, reg_rdi, off, size) case DW_RegX64_##reg_dw: result = RDI_RegCodeX64_##reg_rdi; *off_out = off; *size_out = size; break; + DW_Regs_X64_XList(X) +#undef X + default: NotImplemented; break; + } + return result; +} + +internal B32 +rdi_reg_from_dw_reg(Arch arch, DW_Reg v, RDI_RegCode *code_out, U64 *off_out, U64 *size_out) +{ + RDI_RegCode result = RDI_RegCode_nil; + switch (arch) { + case Arch_Null: break; + case Arch_x86: ; break; + case Arch_x64: return rdi_reg_from_dw_reg_x64(v, code_out, off_out, size_out); + default: NotImplemented; break; + } + return 0; +} + diff --git a/src/radcon/radcon_dwarf.h b/src/radcon/radcon_dwarf.h new file mode 100644 index 00000000..688e90e8 --- /dev/null +++ b/src/radcon/radcon_dwarf.h @@ -0,0 +1,43 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADCON_DWARF_H +#define RADCON_DWARF_H + +typedef struct D2R_TypeTable +{ + HashTable *ht; + RDIM_TypeChunkList *types; + U64 type_chunk_cap; + RDIM_Type *void_type; + RDIM_Type *varg_type; +} D2R_TypeTable; + +typedef struct D2R_TagNode +{ + struct D2R_TagNode *next; + DW_TagNode *cur_node; + RDIM_Type *type; + RDIM_Scope *scope; +} D2R_TagNode; + +typedef struct D2R_CompUnitContribMap +{ + U64 count; + U64 *info_off_arr; + RDIM_Rng1U64List *voff_range_arr; +} D2R_CompUnitContribMap; + +//////////////////////////////// + +internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); + +//////////////////////////////// + +internal RDI_Language rdi_language_from_dw_language(DW_Language v); +internal RDI_RegCodeX86 rdi_reg_from_dw_reg_x86(DW_RegX86 v); +internal B32 rdi_reg_from_dw_reg_x64(DW_RegX64 v, RDI_RegCodeX64 *code_out, U64 *off_out, U64 *size_out); +internal B32 rdi_reg_from_dw_reg(Arch arch, DW_Reg v, RDI_RegCode *code_out, U64 *off_out, U64 *size_out); + +#endif // RADCON_DWARF_H + diff --git a/src/radcon/radcon_elf.c b/src/radcon/radcon_elf.c new file mode 100644 index 00000000..6a262ee2 --- /dev/null +++ b/src/radcon/radcon_elf.c @@ -0,0 +1,17 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal RDIM_BinarySectionList +e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs) +{ + RDIM_BinarySectionList result = {0}; + return result; +} + +internal RDIM_TopLevelInfo +e2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, ELF_Shdr64Array shdrs) +{ + RDIM_TopLevelInfo top_level_info = {0}; + return top_level_info; +} + diff --git a/src/radcon/radcon_elf.h b/src/radcon/radcon_elf.h new file mode 100644 index 00000000..bcf40e08 --- /dev/null +++ b/src/radcon/radcon_elf.h @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADCON_ELF_H +#define RADCON_ELF_H + +internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs); +internal RDIM_TopLevelInfo e2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, ELF_Shdr64Array shdrs); + +#endif // RADCON_ELF_H diff --git a/src/radcon/radcon_main.c b/src/radcon/radcon_main.c new file mode 100644 index 00000000..584877f4 --- /dev/null +++ b/src/radcon/radcon_main.c @@ -0,0 +1,97 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#define BUILD_TITLE "Epic Games Tools (R) RAD Debug Info Converter" +#define BUILD_CONSOLE_INTERFACE 1 + +//////////////////////////////// +// Third Party + +#include "third_party/rad_lzb_simple/rad_lzb_simple.h" +#include "third_party/rad_lzb_simple/rad_lzb_simple.c" +#define XXH_STATIC_LINKING_ONLY +#include "third_party/xxHash/xxhash.c" +#include "third_party/xxHash/xxhash.h" +#define SINFL_IMPLEMENTATION +#include "third_party/sinfl/sinfl.h" + +//////////////////////////////// +// RDI Format Library + +#include "lib_rdi_format/rdi_format.h" +#include "lib_rdi_format/rdi_format.c" + +//////////////////////////////// +// Headers + +#include "base/base_inc.h" +#include "os/os_inc.h" +#include "async/async.h" +#include "path/path.h" +#include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_help.h" +#include "linker/hash_table.h" +#include "coff/coff.h" +#include "coff/coff_parse.h" +#include "pe/pe.h" +#include "elf/elf.h" +#include "elf/elf_parse.h" +#include "codeview/codeview.h" +#include "codeview/codeview_parse.h" +#include "dwarf/dwarf.h" +#include "dwarf/dwarf_parse.h" +#include "dwarf/dwarf_coff.h" +#include "dwarf/dwarf_elf.h" +#include "msf/msf.h" +#include "msf/msf_parse.h" +#include "pdb/pdb.h" +#include "pdb/pdb_parse.h" +#include "pdb/pdb_stringize.h" +#include "radcon.h" +#include "radcon_coff.h" +#include "radcon_elf.h" +#include "radcon_cv.h" +#include "radcon_dwarf.h" +#include "radcon_pdb.h" + +//////////////////////////////// +// Implementations + +#include "base/base_inc.c" +#include "os/os_inc.c" +#include "async/async.c" +#include "path/path.c" +#include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_help.c" +#include "linker/hash_table.c" +#include "coff/coff.c" +#include "coff/coff_parse.c" +#include "pe/pe.c" +#include "elf/elf.c" +#include "elf/elf_parse.c" +#include "codeview/codeview.c" +#include "codeview/codeview_parse.c" +#include "msf/msf.c" +#include "msf/msf_parse.c" +#include "pdb/pdb.c" +#include "pdb/pdb_parse.c" +#include "pdb/pdb_stringize.c" +#include "dwarf/dwarf.c" +#include "dwarf/dwarf_parse.c" +#include "dwarf/dwarf_coff.c" +#include "dwarf/dwarf_elf.c" +#include "radcon.c" +#include "radcon_coff.c" +#include "radcon_elf.c" +#include "radcon_cv.c" +#include "radcon_dwarf.c" +#include "radcon_pdb.c" + +//////////////////////////////// + +internal void +entry_point(CmdLine *cmdl) +{ + rc_main(cmdl); +} + diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c new file mode 100644 index 00000000..226e4405 --- /dev/null +++ b/src/radcon/radcon_pdb.c @@ -0,0 +1,3207 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +// TODO(rjf): eliminate redundant null checks, just always allocate +// empty results, and have nulls gracefully fall through +// +// (search for != 0 instances, inserted to prevent prior crashes) + +global RDIM_HelpState *g_p2r_help_state = 0; + +//////////////////////////////// +//~ rjf: Basic Helpers + +internal U64 +p2r_end_of_cplusplus_container_name(String8 str) +{ + // NOTE: This finds the index one past the last "::" contained in str. + // if no "::" is contained in str, then the returned index is 0. + // The intent is that [0,clamp_bot(0,result - 2)) gives the + // "container name" and [result,str.size) gives the leaf name. + U64 result = 0; + if(str.size >= 2) + { + for(U64 i = str.size; i >= 2; i -= 1) + { + if(str.str[i - 2] == ':' && str.str[i - 1] == ':') + { + result = i; + break; + } + } + } + return(result); +} + +internal U64 +p2r_hash_from_voff(U64 voff) +{ + U64 hash = (voff >> 3) ^ ((7 & voff) << 6); + return hash; +} + +//////////////////////////////// +//~ rjf: Location Info Building Helpers + +internal RDIM_Location * +p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection) +{ + RDIM_Location *result = 0; + if(0 <= offset && offset <= (S64)max_U16) + { + if(extra_indirection) + { + result = rdim_push_location_addr_addr_reg_plus_u16(arena, reg_code, (U16)offset); + } + else + { + result = rdim_push_location_addr_reg_plus_u16(arena, reg_code, (U16)offset); + } + } + else + { + RDIM_EvalBytecode bytecode = {0}; + U32 regread_param = RDI_EncodeRegReadParam(reg_code, reg_byte_size, reg_byte_pos); + rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_RegRead, regread_param); + rdim_bytecode_push_sconst(arena, &bytecode, offset); + rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_Add, 0); + if(extra_indirection) + { + U64 addr_size = rdi_addr_size_from_arch(arch); + rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_MemRead, addr_size); + } + result = rdim_push_location_addr_bytecode_stream(arena, &bytecode); + } + return result; +} + +internal void +p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count) +{ + //- rjf: extract range info + U64 voff_first = 0; + U64 voff_opl = 0; + if(section != 0) + { + voff_first = section->voff + range->off; + voff_opl = voff_first + range->len; + } + + //- rjf: emit ranges + CV_LvarAddrGap *gap_ptr = gaps; + U64 voff_cursor = voff_first; + for(U64 i = 0; i < gap_count; i += 1, gap_ptr += 1) + { + U64 voff_gap_first = voff_first + gap_ptr->off; + U64 voff_gap_opl = voff_gap_first + gap_ptr->len; + if(voff_cursor < voff_gap_first) + { + RDIM_Rng1U64 voff_range = {voff_cursor, voff_gap_first}; + rdim_location_set_push_case(arena, scopes, locset, voff_range, location); + } + voff_cursor = voff_gap_opl; + } + + //- rjf: emit remaining range + if(voff_cursor < voff_opl) + { + RDIM_Rng1U64 voff_range = {voff_cursor, voff_opl}; + rdim_location_set_push_case(arena, scopes, locset, voff_range, location); + } +} + +//////////////////////////////// +//~ rjf: Initial Parsing & Preparation Pass Tasks + +ASYNC_WORK_DEF(p2r_exe_hash_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_EXEHashIn *in = (P2R_EXEHashIn *)input; + U64 *out = push_array(arena, U64, 1); + ProfScope("hash exe") *out = rdi_hash(in->exe_data.str, in->exe_data.size); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_TPIHashParseIn *in = (P2R_TPIHashParseIn *)input; + void *out = 0; + ProfScope("parse tpi hash") out = pdb_tpi_hash_from_data(arena, in->strtbl, in->tpi, in->hash_data, in->aux_data); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_TPILeafParseIn *in = (P2R_TPILeafParseIn *)input; + void *out = 0; + ProfScope("parse tpi leaf") out = cv_leaf_from_data(arena, in->leaf_data, in->itype_first); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_SymbolStreamParseIn *in = (P2R_SymbolStreamParseIn *)input; + void *out = 0; + ProfScope("parse symbol stream") out = cv_sym_from_data(arena, in->data, 4); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_c13_stream_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_C13StreamParseIn *in = (P2R_C13StreamParseIn *)input; + void *out = 0; + ProfScope("parse c13 stream") out = cv_c13_parsed_from_data(arena, in->data, in->strtbl, in->coff_sections); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_comp_unit_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_CompUnitParseIn *in = (P2R_CompUnitParseIn *)input; + void *out = 0; + ProfScope("parse comp units") out = pdb_comp_unit_array_from_data(arena, in->data); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_CompUnitContributionsParseIn *in = (P2R_CompUnitContributionsParseIn *)input; + void *out = 0; + ProfScope("parse comp unit contributions") out = pdb_comp_unit_contribution_array_from_data(arena, in->data, in->coff_sections); + ProfEnd(); + return out; +} + +//////////////////////////////// +//~ rjf: Unit Conversion Tasks + +ASYNC_WORK_DEF(p2r_units_convert_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Temp scratch = scratch_begin(&arena, 1); + P2R_UnitConvertIn *in = (P2R_UnitConvertIn *)input; + P2R_UnitConvertOut *out = push_array(arena, P2R_UnitConvertOut, 1); + ProfScope("build units, initial src file map, & collect unit source files") + if(in->comp_units != 0) + { + U64 units_chunk_cap = in->comp_units->count; + P2R_SrcFileMap src_file_map = {0}; + src_file_map.slots_count = 65536; + src_file_map.slots = push_array(scratch.arena, P2R_SrcFileNode *, src_file_map.slots_count); + + //////////////////////////// + //- rjf: pass 1: build per-unit info & per-unit line tables + // + ProfScope("pass 1: build per-unit info & per-unit line tables") + for(U64 comp_unit_idx = 0; comp_unit_idx < in->comp_units->count; comp_unit_idx += 1) + { + PDB_CompUnit *pdb_unit = in->comp_units->units[comp_unit_idx]; + CV_SymParsed *pdb_unit_sym = in->comp_unit_syms[comp_unit_idx]; + CV_C13Parsed *pdb_unit_c13 = in->comp_unit_c13s[comp_unit_idx]; + + //- rjf: produce unit name + String8 unit_name = pdb_unit->obj_name; + if(unit_name.size != 0) + { + String8 unit_name_past_last_slash = str8_skip_last_slash(unit_name); + if(unit_name_past_last_slash.size != 0) + { + unit_name = unit_name_past_last_slash; + } + } + + //- rjf: produce obj name + String8 obj_name = pdb_unit->obj_name; + if(str8_match(obj_name, str8_lit("* Linker *"), 0) || + str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) + { + MemoryZeroStruct(&obj_name); + } + + //- rjf: build this unit's line table, fill out primary line info (inline info added after) + RDIM_LineTable *line_table = 0; + for(CV_C13SubSectionNode *node = pdb_unit_c13->first_sub_section; + node != 0; + node = node->next) + { + if(node->kind == CV_C13SubSectionKind_Lines) + { + for(CV_C13LinesParsedNode *lines_n = node->lines_first; + lines_n != 0; + lines_n = lines_n->next) + { + CV_C13LinesParsed *lines = &lines_n->v; + + // rjf: file name -> normalized file path + String8 file_path = lines->file_name; + String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); + for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) + { + if(file_path_normalized.str[idx] == '\\') + { + file_path_normalized.str[idx] = '/'; + } + } + + // rjf: normalized file path -> source file node + U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size); + U64 src_file_slot = file_path_normalized_hash%src_file_map.slots_count; + P2R_SrcFileNode *src_file_node = 0; + for(P2R_SrcFileNode *n = src_file_map.slots[src_file_slot]; n != 0; n = n->next) + { + if(str8_match(n->src_file->normal_full_path, file_path_normalized, 0)) + { + src_file_node = n; + break; + } + } + if(src_file_node == 0) + { + src_file_node = push_array(scratch.arena, P2R_SrcFileNode, 1); + SLLStackPush(src_file_map.slots[src_file_slot], src_file_node); + src_file_node->src_file = rdim_src_file_chunk_list_push(arena, &out->src_files, 4096); + src_file_node->src_file->normal_full_path = push_str8_copy(arena, file_path_normalized); + } + + // rjf: push sequence into both line table & source file's line map + if(lines->line_count != 0) + { + if(line_table == 0) + { + line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); + } + RDIM_LineSequence *seq = rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, lines->voffs, lines->line_nums, lines->col_nums, lines->line_count); + rdim_src_file_push_line_sequence(arena, &out->src_files, src_file_node->src_file, seq); + } + } + } + } + + //- rjf: build unit + RDIM_Unit *dst_unit = rdim_unit_chunk_list_push(arena, &out->units, units_chunk_cap); + dst_unit->unit_name = unit_name; + dst_unit->compiler_name = pdb_unit_sym->info.compiler_name; + dst_unit->object_file = obj_name; + dst_unit->archive_file = pdb_unit->group_name; + dst_unit->language = cv2r_rdi_language_from_cv_language(pdb_unit_sym->info.language); + dst_unit->line_table = line_table; + } + + //////////////////////////// + //- rjf: pass 2: build per-unit voff ranges from comp unit contributions table + // + PDB_CompUnitContribution *contrib_ptr = in->comp_unit_contributions->contributions; + PDB_CompUnitContribution *contrib_opl = contrib_ptr + in->comp_unit_contributions->count; + ProfScope("pass 2: build per-unit voff ranges from comp unit contributions table") + for(;contrib_ptr < contrib_opl; contrib_ptr += 1) + { + if(contrib_ptr->mod < in->comp_units->count) + { + RDIM_Unit *unit = &out->units.first->v[contrib_ptr->mod]; + RDIM_Rng1U64 range = {contrib_ptr->voff_first, contrib_ptr->voff_opl}; + rdim_rng1u64_list_push(arena, &unit->voff_ranges, range); + } + } + + //////////////////////////// + //- rjf: pass 3: parse all inlinee line tables + // + out->units_first_inline_site_line_tables = push_array(arena, RDIM_LineTable *, in->comp_units->count); + ProfScope("pass 3: parse all inlinee line tables") + for(U64 comp_unit_idx = 0; comp_unit_idx < in->comp_units->count; comp_unit_idx += 1) + { + CV_SymParsed *unit_sym = in->comp_unit_syms[comp_unit_idx]; + CV_C13Parsed *unit_c13 = in->comp_unit_c13s[comp_unit_idx]; + CV_RecRange *rec_ranges_first = unit_sym->sym_ranges.ranges; + CV_RecRange *rec_ranges_opl = rec_ranges_first+unit_sym->sym_ranges.count; + U64 base_voff = 0; + for(CV_RecRange *rec_range = rec_ranges_first; + rec_range < rec_ranges_opl; + rec_range += 1) + { + //- rjf: rec range -> symbol info range + U64 sym_off_first = rec_range->off + 2; + U64 sym_off_opl = rec_range->off + rec_range->hdr.size; + + //- rjf: skip invalid ranges + if(sym_off_opl > unit_sym->data.size || sym_off_first > unit_sym->data.size || sym_off_first > sym_off_opl) + { + continue; + } + + //- rjf: unpack symbol info + CV_SymKind kind = rec_range->hdr.kind; + U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); + void *sym_header_struct_base = unit_sym->data.str + sym_off_first; + void *sym_data_opl = unit_sym->data.str + sym_off_opl; + + //- rjf: skip bad sizes + if(sym_off_first + sym_header_struct_size > sym_off_opl) + { + continue; + } + + //- rjf: process symbol + switch(kind) + { + default:{}break; + + //- rjf: LPROC32/GPROC32 (gather base address) + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: + { + CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; + COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; + if(section != 0) + { + base_voff = section->voff + proc32->off; + } + }break; + + //- rjf: INLINESITE + case CV_SymKind_INLINESITE: + { + // rjf: unpack sym + CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; + String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); + + // rjf: map inlinee -> parsed cv c13 inlinee line info + CV_C13InlineeLinesParsed *inlinee_lines_parsed = 0; + { + U64 hash = cv_hash_from_item_id(sym->inlinee); + U64 slot_idx = hash%unit_c13->inlinee_lines_parsed_slots_count; + for(CV_C13InlineeLinesParsedNode *n = unit_c13->inlinee_lines_parsed_slots[slot_idx]; n != 0; n = n->hash_next) + { + if(n->v.inlinee == sym->inlinee) + { + inlinee_lines_parsed = &n->v; + break; + } + } + } + + // rjf: build line table, fill with parsed binary annotations + + if(inlinee_lines_parsed != 0) + { + // rjf: grab checksums sub-section + CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; + + // rjf: gathered lines + typedef struct LineChunk LineChunk; + struct LineChunk + { + LineChunk *next; + U64 cap; + U64 count; + U64 *voffs; // [line_count + 1] (sorted) + U32 *line_nums; // [line_count] + U16 *col_nums; // [2*line_count] + }; + LineChunk *first_line_chunk = 0; + LineChunk *last_line_chunk = 0; + U64 total_line_chunk_line_count = 0; + U32 last_file_off = max_U32; + U32 curr_file_off = max_U32; + RDIM_LineTable* line_table = 0; + + CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); + for(;;) + { + CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); + + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) + { + last_file_off = curr_file_off; + curr_file_off = step.file_off; + } + if(step.flags == 0 && total_line_chunk_line_count > 0) + { + last_file_off = curr_file_off; + curr_file_off = max_U32; + } + if((last_file_off != max_U32 && last_file_off != curr_file_off)) + { + String8 seq_file_name = {0}; + + if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) + { + CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off); + U32 name_off = checksum->name_off; + seq_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off); + } + + // rjf: file name -> normalized file path + String8 file_path = seq_file_name; + String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); + for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) + { + if(file_path_normalized.str[idx] == '\\') + { + file_path_normalized.str[idx] = '/'; + } + } + + // rjf: normalized file path -> source file node + U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size); + U64 src_file_slot = file_path_normalized_hash%src_file_map.slots_count; + P2R_SrcFileNode *src_file_node = 0; + for(P2R_SrcFileNode *n = src_file_map.slots[src_file_slot]; n != 0; n = n->next) + { + if(str8_match(n->src_file->normal_full_path, file_path_normalized, 0)) + { + src_file_node = n; + break; + } + } + if(src_file_node == 0) + { + src_file_node = push_array(scratch.arena, P2R_SrcFileNode, 1); + SLLStackPush(src_file_map.slots[src_file_slot], src_file_node); + src_file_node->src_file = rdim_src_file_chunk_list_push(arena, &out->src_files, 4096); + src_file_node->src_file->normal_full_path = push_str8_copy(arena, file_path_normalized); + } + + // rjf: gather all lines + RDI_U64 *voffs = push_array_no_zero(arena, RDI_U64, total_line_chunk_line_count+1); + RDI_U32 *line_nums = push_array_no_zero(arena, RDI_U32, total_line_chunk_line_count); + RDI_U64 line_count = total_line_chunk_line_count; + { + U64 dst_idx = 0; + for(LineChunk *chunk = first_line_chunk; chunk != 0; chunk = chunk->next) + { + MemoryCopy(voffs+dst_idx, chunk->voffs, sizeof(U64)*(chunk->count+1)); + MemoryCopy(line_nums+dst_idx, chunk->line_nums, sizeof(U32)*chunk->count); + dst_idx += chunk->count; + } + } + + // rjf: push + if(line_count != 0) + { + if(line_table == 0) + { + line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); + if(out->units_first_inline_site_line_tables[comp_unit_idx] == 0) + { + out->units_first_inline_site_line_tables[comp_unit_idx] = line_table; + } + } + RDIM_LineSequence *seq = rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, voffs, line_nums, 0, line_count); + rdim_src_file_push_line_sequence(arena, &out->src_files, src_file_node->src_file, seq); + } + + // rjf: clear line chunks for subsequent sequences + first_line_chunk = last_line_chunk = 0; + total_line_chunk_line_count = 0; + } + + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) + { + LineChunk *chunk = last_line_chunk; + if(chunk == 0 || chunk->count+1 >= chunk->cap) + { + chunk = push_array(scratch.arena, LineChunk, 1); + SLLQueuePush(first_line_chunk, last_line_chunk, chunk); + chunk->cap = 256; + chunk->voffs = push_array_no_zero(scratch.arena, U64, chunk->cap); + chunk->line_nums = push_array_no_zero(scratch.arena, U32, chunk->cap); + } + chunk->voffs[chunk->count] = step.line_voff; + chunk->voffs[chunk->count+1] = step.line_voff_end; + chunk->line_nums[chunk->count] = step.ln; + chunk->count += 1; + total_line_chunk_line_count += 1; + } + + if(step.flags == 0) + { + break; + } + } + } + }break; + } + } + } + } + scratch_end(scratch); + ProfEnd(); + return out; +} + +//////////////////////////////// +//~ rjf: Link Name Map Building Tasks + +ASYNC_WORK_DEF(p2r_link_name_map_build_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)input; + CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges; + CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count; + for(CV_RecRange *rec_range = rec_ranges_first; + rec_range < rec_ranges_opl; + rec_range += 1) + { + //- rjf: unpack symbol range info + CV_SymKind kind = rec_range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind); + U8 *sym_first = in->sym->data.str + rec_range->off + 2; + U8 *sym_opl = sym_first + rec_range->hdr.size; + + //- rjf: skip bad ranges + if(sym_opl > in->sym->data.str + in->sym->data.size || sym_first + header_struct_size > in->sym->data.str + in->sym->data.size) + { + continue; + } + + //- rjf: consume symbol + switch(kind) + { + default:{}break; + case CV_SymKind_PUB32: + { + // rjf: unpack sym + CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first; + String8 name = str8_cstring_capped(pub32+1, sym_opl); + COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= in->coff_sections.count) ? &in->coff_sections.v[pub32->sec-1] : 0; + U64 voff = 0; + if(section != 0) + { + voff = section->voff + pub32->off; + } + + // rjf: commit to link name map + U64 hash = p2r_hash_from_voff(voff); + U64 bucket_idx = hash%in->link_name_map->buckets_count; + P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1); + SLLStackPush(in->link_name_map->buckets[bucket_idx], node); + node->voff = voff; + node->name = name; + in->link_name_map->link_name_count += 1; + in->link_name_map->bucket_collision_count += (node->next != 0); + }break; + } + } + ProfEnd(); + return 0; +} + +//////////////////////////////// +//~ rjf: UDT Conversion Tasks + +ASYNC_WORK_DEF(p2r_udt_convert_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) + RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); + RDI_U64 udts_chunk_cap = 1024; + ProfScope("convert UDT info") + { + for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) + { + //- rjf: skip basics + if(itype < in->tpi_leaf->itype_first) { continue; } + + //- rjf: grab type for this itype - skip if empty + RDIM_Type *dst_type = in->itype_type_ptrs[itype]; + if(dst_type == 0) { continue; } + + //- rjf: unpack itype leaf range - skip if out-of-range + CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[itype-in->tpi_leaf->itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + if(range->off+range->hdr.size > in->tpi_leaf->data.size || + range->off+2+header_struct_size > in->tpi_leaf->data.size || + range->hdr.size < 2) + { + continue; + } + + //- rjf: build UDT + CV_TypeId field_itype = 0; + switch(kind) + { + default:{}break; + + //////////////////////// + //- rjf: structs/unions/classes -> equip members + // + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + { + CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; + if(lf->props & CV_TypeProp_FwdRef) + { + break; + } + field_itype = lf->field_itype; + }goto equip_members; + case CV_LeafKind_UNION: + { + CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; + if(lf->props & CV_TypeProp_FwdRef) + { + break; + } + field_itype = lf->field_itype; + }goto equip_members; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; + if(lf->props & CV_TypeProp_FwdRef) + { + break; + } + field_itype = lf->field_itype; + }goto equip_members; + equip_members: + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: grab UDT info + RDIM_UDT *dst_udt = dst_type->udt; + if(dst_udt == 0) + { + dst_udt = dst_type->udt = rdim_udt_chunk_list_push(arena, udts, udts_chunk_cap); + dst_udt->self_type = dst_type; + } + + //- rjf: gather all fields + typedef struct FieldListTask FieldListTask; + struct FieldListTask + { + FieldListTask *next; + CV_TypeId itype; + }; + FieldListTask start_fl_task = {0, field_itype}; + FieldListTask *fl_todo_stack = &start_fl_task; + FieldListTask *fl_done_stack = 0; + for(;fl_todo_stack != 0;) + { + //- rjf: take & unpack task + FieldListTask *fl_task = fl_todo_stack; + SLLStackPop(fl_todo_stack); + SLLStackPush(fl_done_stack, fl_task); + CV_TypeId field_list_itype = fl_task->itype; + + //- rjf: skip bad itypes + if(field_list_itype < in->tpi_leaf->itype_first || in->tpi_leaf->itype_opl <= field_list_itype) + { + continue; + } + + //- rjf: field list itype -> range + CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[field_list_itype-in->tpi_leaf->itype_first]; + + //- rjf: skip bad headers + if(range->off+range->hdr.size > in->tpi_leaf->data.size || + range->hdr.size < 2 || + range->hdr.kind != CV_LeafKind_FIELDLIST) + { + continue; + } + + //- rjf: loop over all fields + { + U8 *field_list_first = in->tpi_leaf->data.str+range->off+2; + U8 *field_list_opl = field_list_first+range->hdr.size-2; + for(U8 *read_ptr = field_list_first, *next_read_ptr = field_list_opl; + read_ptr < field_list_opl; + read_ptr = next_read_ptr) + { + // rjf: unpack field + CV_LeafKind field_kind = *(CV_LeafKind *)read_ptr; + U64 field_leaf_header_size = cv_header_struct_size_from_leaf_kind(field_kind); + U8 *field_leaf_first = read_ptr+2; + U8 *field_leaf_opl = field_list_opl; + next_read_ptr = field_leaf_opl; + + // rjf: skip out-of-bounds fields + if(field_leaf_first+field_leaf_header_size > field_list_opl) + { + continue; + } + + // rjf: process field + switch(field_kind) + { + //- rjf: unhandled/invalid cases + default: + { + // TODO(rjf): log + }break; + + //- rjf: INDEX + case CV_LeafKind_INDEX: + { + // rjf: unpack leaf + CV_LeafIndex *lf = (CV_LeafIndex *)field_leaf_first; + CV_TypeId new_itype = lf->itype; + + // rjf: bump next read pointer past header + next_read_ptr = (U8 *)(lf+1); + + // rjf: determine if index itype is new + B32 is_new = 1; + for(FieldListTask *t = fl_done_stack; t != 0; t = t->next) + { + if(t->itype == new_itype) + { + is_new = 0; + break; + } + } + + // rjf: if new -> push task to follow new itype + if(is_new) + { + FieldListTask *new_task = push_array(scratch.arena, FieldListTask, 1); + SLLStackPush(fl_todo_stack, new_task); + new_task->itype = new_itype; + } + }break; + + //- rjf: MEMBER + case CV_LeafKind_MEMBER: + { + // TODO(rjf): log on bad offset + + // rjf: unpack leaf + CV_LeafMember *lf = (CV_LeafMember *)field_leaf_first; + U8 *offset_ptr = (U8 *)(lf+1); + CV_NumericParsed offset = cv_numeric_from_data_range(offset_ptr, field_leaf_opl); + U64 offset64 = cv_u64_from_numeric(&offset); + U8 *name_ptr = offset_ptr + offset.encoded_size; + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_DataField; + mem->name = name; + mem->type = p2r_type_ptr_from_itype(lf->itype); + mem->off = (U32)offset64; + }break; + + //- rjf: STMEMBER + case CV_LeafKind_STMEMBER: + { + // TODO(rjf): handle attribs + + // rjf: unpack leaf + CV_LeafStMember *lf = (CV_LeafStMember *)field_leaf_first; + U8 *name_ptr = (U8 *)(lf+1); + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_StaticData; + mem->name = name; + mem->type = p2r_type_ptr_from_itype(lf->itype); + }break; + + //- rjf: METHOD + case CV_LeafKind_METHOD: + { + // rjf: unpack leaf + CV_LeafMethod *lf = (CV_LeafMethod *)field_leaf_first; + U8 *name_ptr = (U8 *)(lf+1); + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + //- rjf: method list itype -> range + CV_RecRange *method_list_range = &in->tpi_leaf->leaf_ranges.ranges[lf->list_itype-in->tpi_leaf->itype_first]; + + //- rjf: skip bad method lists + if(method_list_range->off+method_list_range->hdr.size > in->tpi_leaf->data.size || + method_list_range->hdr.size < 2 || + method_list_range->hdr.kind != CV_LeafKind_METHODLIST) + { + break; + } + + //- rjf: loop through all methods & emit members + U8 *method_list_first = in->tpi_leaf->data.str + method_list_range->off + 2; + U8 *method_list_opl = method_list_first + method_list_range->hdr.size-2; + for(U8 *method_read_ptr = method_list_first, *next_method_read_ptr = method_list_opl; + method_read_ptr < method_list_opl; + method_read_ptr = next_method_read_ptr) + { + CV_LeafMethodListMember *method = (CV_LeafMethodListMember*)method_read_ptr; + CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(method->attribs); + RDIM_Type *method_type = p2r_type_ptr_from_itype(method->itype); + next_method_read_ptr = (U8 *)(method+1); + + // TODO(allen): PROBLEM + // We only get offsets for virtual functions (the "vbaseoff") from + // "Intro" and "PureIntro". In C++ inheritance, when we have a chain + // of inheritance (let's just talk single inheritance for now) the + // first class in the chain that introduces a new virtual function + // has this "Intro" method. If a later class in the chain redefines + // the virtual function it only has a "Virtual" method which does + // not update the offset. There is a "Virtual" and "PureVirtual" + // variant of "Virtual". The "Pure" in either case means there + // is no concrete procedure. When there is no "Pure" the method + // should have a corresponding procedure symbol id. + // + // The issue is we will want to mark all of our virtual methods as + // virtual and give them an offset, but that means we have to do + // some extra figuring to propogate offsets from "Intro" methods + // to "Virtual" methods in inheritance trees. That is - IF we want + // to start preserving the offsets of virtuals. There is room in + // the method struct to make this work, but for now I've just + // decided to drop this information. It is not urgently useful to + // us and greatly complicates matters. + + // rjf: read vbaseoff + U32 vbaseoff = 0; + if(prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) + { + if(next_method_read_ptr+4 <= method_list_opl) + { + vbaseoff = *(U32 *)next_method_read_ptr; + } + next_method_read_ptr += 4; + } + + // rjf: emit method + switch(prop) + { + default: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_Method; + mem->name = name; + mem->type = method_type; + }break; + case CV_MethodProp_Static: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_StaticMethod; + mem->name = name; + mem->type = method_type; + }break; + case CV_MethodProp_Virtual: + case CV_MethodProp_PureVirtual: + case CV_MethodProp_Intro: + case CV_MethodProp_PureIntro: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_VirtualMethod; + mem->name = name; + mem->type = method_type; + }break; + } + } + + }break; + + //- rjf: ONEMETHOD + case CV_LeafKind_ONEMETHOD: + { + // TODO(rjf): handle attribs + + // rjf: unpack leaf + CV_LeafOneMethod *lf = (CV_LeafOneMethod *)field_leaf_first; + CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(lf->attribs); + U8 *vbaseoff_ptr = (U8 *)(lf+1); + U8 *vbaseoff_opl_ptr = vbaseoff_ptr; + U32 vbaseoff = 0; + if(prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) + { + vbaseoff = *(U32 *)(vbaseoff_ptr); + vbaseoff_opl_ptr += sizeof(U32); + } + U8 *name_ptr = vbaseoff_opl_ptr; + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + RDIM_Type *method_type = p2r_type_ptr_from_itype(lf->itype); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit method + switch(prop) + { + default: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_Method; + mem->name = name; + mem->type = method_type; + }break; + + case CV_MethodProp_Static: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_StaticMethod; + mem->name = name; + mem->type = method_type; + }break; + + case CV_MethodProp_Virtual: + case CV_MethodProp_PureVirtual: + case CV_MethodProp_Intro: + case CV_MethodProp_PureIntro: + { + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_VirtualMethod; + mem->name = name; + mem->type = method_type; + }break; + } + }break; + + //- rjf: NESTTYPE + case CV_LeafKind_NESTTYPE: + { + // rjf: unpack leaf + CV_LeafNestType *lf = (CV_LeafNestType *)field_leaf_first; + U8 *name_ptr = (U8 *)(lf+1); + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_NestedType; + mem->name = name; + mem->type = p2r_type_ptr_from_itype(lf->itype); + }break; + + //- rjf: NESTTYPEEX + case CV_LeafKind_NESTTYPEEX: + { + // TODO(rjf): handle attribs + + // rjf: unpack leaf + CV_LeafNestTypeEx *lf = (CV_LeafNestTypeEx *)field_leaf_first; + U8 *name_ptr = (U8 *)(lf+1); + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_NestedType; + mem->name = name; + mem->type = p2r_type_ptr_from_itype(lf->itype); + }break; + + //- rjf: BCLASS + case CV_LeafKind_BCLASS: + { + // TODO(rjf): log on bad offset + + // rjf: unpack leaf + CV_LeafBClass *lf = (CV_LeafBClass *)field_leaf_first; + U8 *offset_ptr = (U8 *)(lf+1); + CV_NumericParsed offset = cv_numeric_from_data_range(offset_ptr, field_leaf_opl); + U64 offset64 = cv_u64_from_numeric(&offset); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = offset_ptr+offset.encoded_size; + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_Base; + mem->type = p2r_type_ptr_from_itype(lf->itype); + mem->off = (U32)offset64; + }break; + + //- rjf: VBCLASS/IVBCLASS + case CV_LeafKind_VBCLASS: + case CV_LeafKind_IVBCLASS: + { + // TODO(rjf): log on bad offsets + // TODO(rjf): handle attribs + // TODO(rjf): offsets? + + // rjf: unpack leaf + CV_LeafVBClass *lf = (CV_LeafVBClass *)field_leaf_first; + U8 *num1_ptr = (U8 *)(lf+1); + CV_NumericParsed num1 = cv_numeric_from_data_range(num1_ptr, field_leaf_opl); + U8 *num2_ptr = num1_ptr + num1.encoded_size; + CV_NumericParsed num2 = cv_numeric_from_data_range(num2_ptr, field_leaf_opl); + + // rjf: bump next read pointer past header + next_read_ptr = (U8 *)(lf+1); + + // rjf: emit member + RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); + mem->kind = RDI_MemberKind_VirtualBase; + mem->type = p2r_type_ptr_from_itype(lf->itype); + }break; + + //- rjf: VFUNCTAB + case CV_LeafKind_VFUNCTAB: + { + CV_LeafVFuncTab *lf = (CV_LeafVFuncTab *)field_leaf_first; + + // rjf: bump next read pointer past header + next_read_ptr = (U8 *)(lf+1); + + // NOTE(rjf): currently no-op this case + (void)lf; + }break; + } + + // rjf: align-up next field + next_read_ptr = (U8 *)AlignPow2((U64)next_read_ptr, 4); + } + } + } + + scratch_end(scratch); + }break; + + //////////////////////// + //- rjf: enums -> equip enumerates + // + case CV_LeafKind_ENUM: + { + CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; + if(lf->props & CV_TypeProp_FwdRef) + { + break; + } + field_itype = lf->field_itype; + }goto equip_enum_vals; + equip_enum_vals:; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: grab UDT info + RDIM_UDT *dst_udt = dst_type->udt; + if(dst_udt == 0) + { + dst_udt = dst_type->udt = rdim_udt_chunk_list_push(arena, udts, udts_chunk_cap); + dst_udt->self_type = dst_type; + } + + //- rjf: gather all fields + typedef struct FieldListTask FieldListTask; + struct FieldListTask + { + FieldListTask *next; + CV_TypeId itype; + }; + FieldListTask start_fl_task = {0, field_itype}; + FieldListTask *fl_todo_stack = &start_fl_task; + FieldListTask *fl_done_stack = 0; + for(;fl_todo_stack != 0;) + { + //- rjf: take & unpack task + FieldListTask *fl_task = fl_todo_stack; + SLLStackPop(fl_todo_stack); + SLLStackPush(fl_done_stack, fl_task); + CV_TypeId field_list_itype = fl_task->itype; + + //- rjf: skip bad itypes + if(field_list_itype < in->tpi_leaf->itype_first || in->tpi_leaf->itype_opl <= field_list_itype) + { + continue; + } + + //- rjf: field list itype -> range + CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[field_list_itype-in->tpi_leaf->itype_first]; + + //- rjf: skip bad headers + if(range->off+range->hdr.size > in->tpi_leaf->data.size || + range->hdr.size < 2 || + range->hdr.kind != CV_LeafKind_FIELDLIST) + { + continue; + } + + //- rjf: loop over all fields + { + U8 *field_list_first = in->tpi_leaf->data.str+range->off+2; + U8 *field_list_opl = field_list_first+range->hdr.size-2; + for(U8 *read_ptr = field_list_first, *next_read_ptr = field_list_opl; + read_ptr < field_list_opl; + read_ptr = next_read_ptr) + { + // rjf: unpack field + CV_LeafKind field_kind = *(CV_LeafKind *)read_ptr; + U64 field_leaf_header_size = cv_header_struct_size_from_leaf_kind(field_kind); + U8 *field_leaf_first = read_ptr+2; + U8 *field_leaf_opl = field_leaf_first+range->hdr.size-2; + next_read_ptr = field_leaf_opl; + + // rjf: skip out-of-bounds fields + if(field_leaf_first+field_leaf_header_size > field_list_opl) + { + continue; + } + + // rjf: process field + switch(field_kind) + { + //- rjf: unhandled/invalid cases + default: + { + // TODO(rjf): log + }break; + + //- rjf: INDEX + case CV_LeafKind_INDEX: + { + // rjf: unpack leaf + CV_LeafIndex *lf = (CV_LeafIndex *)field_leaf_first; + CV_TypeId new_itype = lf->itype; + + // rjf: determine if index itype is new + B32 is_new = 1; + for(FieldListTask *t = fl_done_stack; t != 0; t = t->next) + { + if(t->itype == new_itype) + { + is_new = 0; + break; + } + } + + // rjf: if new -> push task to follow new itype + if(is_new) + { + FieldListTask *new_task = push_array(scratch.arena, FieldListTask, 1); + SLLStackPush(fl_todo_stack, new_task); + new_task->itype = new_itype; + } + }break; + + //- rjf: ENUMERATE + case CV_LeafKind_ENUMERATE: + { + // TODO(rjf): attribs + + // rjf: unpack leaf + CV_LeafEnumerate *lf = (CV_LeafEnumerate *)field_leaf_first; + U8 *val_ptr = (U8 *)(lf+1); + CV_NumericParsed val = cv_numeric_from_data_range(val_ptr, field_leaf_opl); + U64 val64 = cv_u64_from_numeric(&val); + U8 *name_ptr = val_ptr + val.encoded_size; + String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); + + // rjf: bump next read pointer past variable length parts + next_read_ptr = name.str+name.size+1; + + // rjf: emit member + RDIM_UDTEnumVal *enum_val = rdim_udt_push_enum_val(arena, udts, dst_udt); + enum_val->name = name; + enum_val->val = val64; + }break; + } + + // rjf: align-up next field + next_read_ptr = (U8 *)AlignPow2((U64)next_read_ptr, 4); + } + } + } + + scratch_end(scratch); + }break; + } + } + } +#undef p2r_type_ptr_from_itype + ProfEnd(); + return udts; +} + +//////////////////////////////// +//~ rjf: Symbol Stream Conversion Path & Thread + +ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) +{ + ProfBeginFunction(); + Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Temp scratch = scratch_begin(&arena, 1); + P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) + + ////////////////////////// + //- rjf: set up outputs for this sym stream + // + U64 sym_procedures_chunk_cap = 1024; + U64 sym_global_variables_chunk_cap = 1024; + U64 sym_thread_variables_chunk_cap = 1024; + U64 sym_scopes_chunk_cap = 1024; + U64 sym_inline_sites_chunk_cap = 1024; + RDIM_SymbolChunkList sym_procedures = {0}; + RDIM_SymbolChunkList sym_global_variables = {0}; + RDIM_SymbolChunkList sym_thread_variables = {0}; + RDIM_ScopeChunkList sym_scopes = {0}; + RDIM_InlineSiteChunkList sym_inline_sites = {0}; + + ////////////////////////// + //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) + // + U64 procedure_frameprocs_count = 0; + U64 procedure_frameprocs_cap = (in->sym_ranges_opl - in->sym_ranges_first); + CV_SymFrameproc **procedure_frameprocs = push_array_no_zero(scratch.arena, CV_SymFrameproc *, procedure_frameprocs_cap); + ProfScope("symbols pass 1: produce procedure frame info map (procedure -> frame info)") + { + U64 procedure_num = 0; + CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges + in->sym_ranges_first; + CV_RecRange *rec_ranges_opl = in->sym->sym_ranges.ranges + in->sym_ranges_opl; + for(CV_RecRange *rec_range = rec_ranges_first; + rec_range < rec_ranges_opl; + rec_range += 1) + { + //- rjf: rec range -> symbol info range + U64 sym_off_first = rec_range->off + 2; + U64 sym_off_opl = rec_range->off + rec_range->hdr.size; + + //- rjf: skip invalid ranges + if(sym_off_opl > in->sym->data.size || sym_off_first > in->sym->data.size || sym_off_first > sym_off_opl) + { + continue; + } + + //- rjf: unpack symbol info + CV_SymKind kind = rec_range->hdr.kind; + U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); + void *sym_header_struct_base = in->sym->data.str + sym_off_first; + + //- rjf: skip bad sizes + if(sym_off_first + sym_header_struct_size > sym_off_opl) + { + continue; + } + + //- rjf: consume symbol based on kind + switch(kind) + { + default:{}break; + + //- rjf: FRAMEPROC + case CV_SymKind_FRAMEPROC: + { + if(procedure_num == 0) { break; } + if(procedure_num > procedure_frameprocs_cap) { break; } + CV_SymFrameproc *frameproc = (CV_SymFrameproc*)sym_header_struct_base; + procedure_frameprocs[procedure_num-1] = frameproc; + procedure_frameprocs_count = Max(procedure_frameprocs_count, procedure_num); + }break; + + //- rjf: LPROC32/GPROC32 + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: + { + procedure_num += 1; + }break; + } + } + U64 scratch_overkill = sizeof(procedure_frameprocs[0])*(procedure_frameprocs_cap-procedure_frameprocs_count); + arena_pop(scratch.arena, scratch_overkill); + } + + ////////////////////////// + //- rjf: symbols pass 2: construct all symbols, given procedure frame info map + // + ProfScope("symbols pass 2: construct all symbols, given procedure frame info map") + { + RDIM_LocationSet *defrange_target = 0; + B32 defrange_target_is_param = 0; + U64 procedure_num = 0; + U64 procedure_base_voff = 0; + CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges + in->sym_ranges_first; + CV_RecRange *rec_ranges_opl = in->sym->sym_ranges.ranges + in->sym_ranges_opl; + typedef struct P2R_ScopeNode P2R_ScopeNode; + struct P2R_ScopeNode + { + P2R_ScopeNode *next; + RDIM_Scope *scope; + }; + P2R_ScopeNode *top_scope_node = 0; + P2R_ScopeNode *free_scope_node = 0; + RDIM_LineTable *inline_site_line_table = in->first_inline_site_line_table; + for(CV_RecRange *rec_range = rec_ranges_first; + rec_range < rec_ranges_opl; + rec_range += 1) + { + //- rjf: rec range -> symbol info range + U64 sym_off_first = rec_range->off + 2; + U64 sym_off_opl = rec_range->off + rec_range->hdr.size; + + //- rjf: skip invalid ranges + if(sym_off_opl > in->sym->data.size || sym_off_first > in->sym->data.size || sym_off_first > sym_off_opl) + { + continue; + } + + //- rjf: unpack symbol info + CV_SymKind kind = rec_range->hdr.kind; + U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); + void *sym_header_struct_base = in->sym->data.str + sym_off_first; + void *sym_data_opl = in->sym->data.str + sym_off_opl; + + //- rjf: skip bad sizes + if(sym_off_first + sym_header_struct_size > sym_off_opl) + { + continue; + } + + //- rjf: consume symbol based on kind + switch(kind) + { + default:{}break; + + //- rjf: END + case CV_SymKind_END: + { + P2R_ScopeNode *n = top_scope_node; + if(n != 0) + { + SLLStackPop(top_scope_node); + SLLStackPush(free_scope_node, n); + } + defrange_target = 0; + defrange_target_is_param = 0; + }break; + + //- rjf: BLOCK32 + case CV_SymKind_BLOCK32: + { + // rjf: unpack sym + CV_SymBlock32 *block32 = (CV_SymBlock32 *)sym_header_struct_base; + + // rjf: build scope, insert into current parent scope + RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); + { + if(top_scope_node == 0) + { + // TODO(rjf): log + } + if(top_scope_node != 0) + { + RDIM_Scope *top_scope = top_scope_node->scope; + SLLQueuePush_N(top_scope->first_child, top_scope->last_child, scope, next_sibling); + scope->parent_scope = top_scope; + scope->symbol = top_scope->symbol; + } + COFF_SectionHeader *section = (0 < block32->sec && block32->sec <= in->coff_sections.count) ? &in->coff_sections.v[block32->sec-1] : 0; + if(section != 0) + { + U64 voff_first = section->voff + block32->off; + U64 voff_last = voff_first + block32->len; + RDIM_Rng1U64 voff_range = {voff_first, voff_last}; + rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); + } + } + + // rjf: push this scope to scope stack + { + P2R_ScopeNode *node = free_scope_node; + if(node != 0) { SLLStackPop(free_scope_node); } + else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } + node->scope = scope; + SLLStackPush(top_scope_node, node); + } + }break; + + //- rjf: LDATA32/GDATA32 + case CV_SymKind_LDATA32: + case CV_SymKind_GDATA32: + { + // rjf: unpack sym + CV_SymData32 *data32 = (CV_SymData32 *)sym_header_struct_base; + String8 name = str8_cstring_capped(data32+1, sym_data_opl); + COFF_SectionHeader *section = (0 < data32->sec && data32->sec <= in->coff_sections.count) ? &in->coff_sections.v[data32->sec-1] : 0; + U64 voff = (section ? section->voff : 0) + data32->off; + + // rjf: determine if this is an exact duplicate global + // + // PDB likes to have duplicates of these spread across different + // symbol streams so we deduplicate across the entire translation + // context. + // + B32 is_duplicate = 0; + { + // TODO(rjf): @important global symbol dedup + } + + // rjf: is not duplicate -> push new global + if(!is_duplicate) + { + // rjf: unpack global variable's type + RDIM_Type *type = p2r_type_ptr_from_itype(data32->itype); + + // rjf: unpack global's container type + RDIM_Type *container_type = 0; + U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); + if(container_name_opl > 2) + { + String8 container_name = str8(name.str, container_name_opl - 2); + CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); + container_type = p2r_type_ptr_from_itype(cv_type_id); + } + + // rjf: unpack global's container symbol + RDIM_Symbol *container_symbol = 0; + if(container_type == 0 && top_scope_node != 0) + { + container_symbol = top_scope_node->scope->symbol; + } + + // form a VOFF location +#if 0 + RDIM_LocationSet locset = {0}; + RDIM_Location *voff_loc = rdim_push_location_voff(arena, voff); + rdim_location_set_push_case(arena, &locset, (RDIM_Rng1U64){0,max_U64}, voff_loc); +#endif + + // rjf: build symbol + RDIM_Symbol *symbol = rdim_symbol_chunk_list_push(arena, &sym_global_variables, sym_global_variables_chunk_cap); + symbol->is_extern = (kind == CV_SymKind_GDATA32); + symbol->name = name; + symbol->type = type; + //symbol->locset = locset; + symbol->container_symbol = container_symbol; + symbol->container_type = container_type; + } + }break; + + //- rjf: LPROC32/GPROC32 + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: + { + // rjf: unpack sym + CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; + String8 name = str8_cstring_capped(proc32+1, sym_data_opl); + RDIM_Type *type = p2r_type_ptr_from_itype(proc32->itype); + + // rjf: unpack proc's container type + RDIM_Type *container_type = 0; + U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); + if(container_name_opl > 2 && in->tpi_hash != 0 && in->tpi_leaf != 0) + { + String8 container_name = str8(name.str, container_name_opl - 2); + CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); + container_type = p2r_type_ptr_from_itype(cv_type_id); + } + + // rjf: unpack proc's container symbol + RDIM_Symbol *container_symbol = 0; + if(container_type == 0 && top_scope_node != 0) + { + container_symbol = top_scope_node->scope->symbol; + } + + // rjf: build procedure's root scope + // + // NOTE: even if there could be a containing scope at this point (which should be + // illegal in C/C++ but not necessarily in another language) we would not use + // it here because these scopes refer to the ranges of code that make up a + // procedure *not* the namespaces, so a procedure's root scope always has + // no parent. + RDIM_Scope *procedure_root_scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); + { + COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; + if(section != 0) + { + U64 voff_first = section->voff + proc32->off; + U64 voff_last = voff_first + proc32->len; + RDIM_Rng1U64 voff_range = {voff_first, voff_last}; + rdim_scope_push_voff_range(arena, &sym_scopes, procedure_root_scope, voff_range); + procedure_base_voff = voff_first; + } + } + + // rjf: root scope voff minimum range -> link name + String8 link_name = {0}; + if(procedure_root_scope->voff_ranges.min != 0) + { + U64 voff = procedure_root_scope->voff_ranges.min; + U64 hash = p2r_hash_from_voff(voff); + U64 bucket_idx = hash%in->link_name_map->buckets_count; + P2R_LinkNameNode *node = 0; + for(P2R_LinkNameNode *n = in->link_name_map->buckets[bucket_idx]; n != 0; n = n->next) + { + if(n->voff == voff) + { + link_name = n->name; + break; + } + } + } + + // rjf: build procedure symbol + RDIM_Symbol *procedure_symbol = rdim_symbol_chunk_list_push(arena, &sym_procedures, sym_procedures_chunk_cap); + procedure_symbol->is_extern = (kind == CV_SymKind_GPROC32); + procedure_symbol->name = name; + procedure_symbol->link_name = link_name; + procedure_symbol->type = type; + procedure_symbol->container_symbol = container_symbol; + procedure_symbol->container_type = container_type; + procedure_symbol->root_scope = procedure_root_scope; + + // rjf: fill root scope's symbol + procedure_root_scope->symbol = procedure_symbol; + + // rjf: push scope to scope stack + { + P2R_ScopeNode *node = free_scope_node; + if(node != 0) { SLLStackPop(free_scope_node); } + else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } + node->scope = procedure_root_scope; + SLLStackPush(top_scope_node, node); + } + + // rjf: increment procedure counter + procedure_num += 1; + }break; + + //- rjf: REGREL32 + case CV_SymKind_REGREL32: + { + // TODO(rjf): apparently some of the information here may end up being + // redundant with "better" information from CV_SymKind_LOCAL record. + // we don't currently handle this, but if those cases arise then it + // will obviously be better to prefer the better information from both + // records. + + // rjf: no containing scope? -> malformed data; locals cannot be produced + // outside of a containing scope + if(top_scope_node == 0) + { + break; + } + + // rjf: unpack sym + CV_SymRegrel32 *regrel32 = (CV_SymRegrel32 *)sym_header_struct_base; + String8 name = str8_cstring_capped(regrel32+1, sym_data_opl); + RDIM_Type *type = p2r_type_ptr_from_itype(regrel32->itype); + CV_Reg cv_reg = regrel32->reg; + U32 var_off = regrel32->reg_off; + + // rjf: determine if this is a parameter + RDI_LocalKind local_kind = RDI_LocalKind_Variable; + { + B32 is_stack_reg = 0; + switch(in->arch) + { + default:{}break; + case RDI_Arch_X86:{is_stack_reg = (cv_reg == CV_Regx86_ESP);}break; + case RDI_Arch_X64:{is_stack_reg = (cv_reg == CV_Regx64_RSP);}break; + } + if(is_stack_reg) + { + U32 frame_size = 0xFFFFFFFF; + if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num < procedure_frameprocs_count) + { + CV_SymFrameproc *frameproc = procedure_frameprocs[procedure_num-1]; + frame_size = frameproc->frame_size; + } + if(var_off > frame_size) + { + local_kind = RDI_LocalKind_Parameter; + } + } + } + + // TODO(rjf): is this correct? + // rjf: redirect type, if 0, and if outside frame, to the return type of the + // containing procedure + if(local_kind == RDI_LocalKind_Parameter && regrel32->itype == 0 && + top_scope_node->scope->symbol != 0 && + top_scope_node->scope->symbol->type != 0) + { + type = top_scope_node->scope->symbol->type->direct_type; + } + + // rjf: build local + RDIM_Scope *scope = top_scope_node->scope; + RDIM_Local *local = rdim_scope_push_local(arena, &sym_scopes, scope); + local->kind = local_kind; + local->name = name; + local->type = type; + + // rjf: add location info to local + if(type != 0) + { + // rjf: determine if we need an extra indirection to the value + B32 extra_indirection_to_value = 0; + switch(in->arch) + { + case RDI_Arch_X86: + { + extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 4 || !IsPow2OrZero(type->byte_size))); + }break; + case RDI_Arch_X64: + { + extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 8 || !IsPow2OrZero(type->byte_size))); + }break; + } + + // rjf: get raddbg register code + RDI_RegCode reg_code = cv2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); + // TODO(rjf): real byte_size & byte_pos from cv_reg goes here + U32 byte_size = 8; + U32 byte_pos = 0; + + // rjf: set location case + RDIM_Location *loc = p2r_location_from_addr_reg_off(arena, in->arch, reg_code, byte_size, byte_pos, (S64)(S32)var_off, extra_indirection_to_value); + RDIM_Rng1U64 voff_range = {0, max_U64}; + rdim_location_set_push_case(arena, &sym_scopes, &local->locset, voff_range, loc); + } + }break; + + //- rjf: LTHREAD32/GTHREAD32 + case CV_SymKind_LTHREAD32: + case CV_SymKind_GTHREAD32: + { + // rjf: unpack sym + CV_SymThread32 *thread32 = (CV_SymThread32 *)sym_header_struct_base; + String8 name = str8_cstring_capped(thread32+1, sym_data_opl); + U32 tls_off = thread32->tls_off; + RDIM_Type *type = p2r_type_ptr_from_itype(thread32->itype); + + // rjf: unpack thread variable's container type + RDIM_Type *container_type = 0; + U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); + if(container_name_opl > 2) + { + String8 container_name = str8(name.str, container_name_opl - 2); + CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); + container_type = p2r_type_ptr_from_itype(cv_type_id); + } + + // rjf: unpack thread variable's container symbol + RDIM_Symbol *container_symbol = 0; + if(container_type == 0 && top_scope_node != 0) + { + container_symbol = top_scope_node->scope->symbol; + } + + // form TLS OFF location +#if 0 + RDIM_LocationSet locset = {0}; + RDIM_Location *tls_off_loc = rdim_push_location_tls_off(arena, tls_off); + rdim_location_set_push_case(arena, &locset, (RDIM_Rng1U64){0,max_U64}, tls_off_loc); +#endif + + // rjf: build symbol + RDIM_Symbol *tvar = rdim_symbol_chunk_list_push(arena, &sym_thread_variables, sym_thread_variables_chunk_cap); + tvar->name = name; + tvar->type = type; + tvar->is_extern = (kind == CV_SymKind_GTHREAD32); + //tvar->locset = locset; + tvar->container_type = container_type; + tvar->container_symbol = container_symbol; + }break; + + //- rjf: LOCAL + case CV_SymKind_LOCAL: + { + // rjf: no containing scope? -> malformed data; locals cannot be produced + // outside of a containing scope + if(top_scope_node == 0) + { + break; + } + + // rjf: unpack sym + CV_SymLocal *slocal = (CV_SymLocal *)sym_header_struct_base; + String8 name = str8_cstring_capped(slocal+1, sym_data_opl); + RDIM_Type *type = p2r_type_ptr_from_itype(slocal->itype); + + // rjf: determine if this symbol encodes the beginning of a global modification + B32 is_global_modification = 0; + if((slocal->flags & CV_LocalFlag_Global) || + (slocal->flags & CV_LocalFlag_Static)) + { + is_global_modification = 1; + } + + // rjf: is global modification -> emit global modification symbol + if(is_global_modification) + { + // TODO(rjf): add global modification symbols + defrange_target = 0; + defrange_target_is_param = 0; + } + + // rjf: is not a global modification -> emit a local variable + if(!is_global_modification) + { + // rjf: determine local kind + RDI_LocalKind local_kind = RDI_LocalKind_Variable; + if(slocal->flags & CV_LocalFlag_Param) + { + local_kind = RDI_LocalKind_Parameter; + } + + // rjf: build local + RDIM_Scope *scope = top_scope_node->scope; + RDIM_Local *local = rdim_scope_push_local(arena, &sym_scopes, scope); + local->kind = local_kind; + local->name = name; + local->type = type; + + // rjf: save defrange target, for subsequent defrange symbols + defrange_target = &local->locset; + defrange_target_is_param = (local_kind == RDI_LocalKind_Parameter); + } + }break; + + //- rjf: DEFRANGE_REGISTESR + case CV_SymKind_DEFRANGE_REGISTER: + { + // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing + // a local - break immediately + if(defrange_target == 0) + { + break; + } + + // rjf: unpack sym + CV_SymDefrangeRegister *defrange_register = (CV_SymDefrangeRegister*)sym_header_struct_base; + CV_Reg cv_reg = defrange_register->reg; + CV_LvarAddrRange *range = &defrange_register->range; + COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register+1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + RDI_RegCode reg_code = cv2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); + + // rjf: build location + RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); + + // rjf: emit locations over ranges + p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + }break; + + //- rjf: DEFRANGE_FRAMEPOINTER_REL + case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL: + { + // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing + // a local - break immediately + if(defrange_target == 0) + { + break; + } + + // rjf: find current procedure's frameproc + CV_SymFrameproc *frameproc = 0; + if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0) + { + frameproc = procedure_frameprocs[procedure_num-1]; + } + + // rjf: no current valid frameproc? -> somehow we got a to a framepointer-relative defrange + // without having an actually active procedure - break + if(frameproc == 0) + { + break; + } + + // rjf: unpack sym + CV_SymDefrangeFramepointerRel *defrange_fprel = (CV_SymDefrangeFramepointerRel*)sym_header_struct_base; + CV_LvarAddrRange *range = &defrange_fprel->range; + COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_fprel + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // rjf: select frame pointer register + CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); + RDI_RegCode fp_register_code = cv2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); + + // rjf: build location + B32 extra_indirection = 0; + U32 byte_size = rdi_addr_size_from_arch(in->arch); + U32 byte_pos = 0; + S64 var_off = (S64)defrange_fprel->off; + RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); + + // rjf: emit locations over ranges + p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + }break; + + //- rjf: DEFRANGE_SUBFIELD_REGISTER + case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER: + { + // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing + // a local - break immediately + if(defrange_target == 0) + { + break; + } + + // rjf: unpack sym + CV_SymDefrangeSubfieldRegister *defrange_subfield_register = (CV_SymDefrangeSubfieldRegister*)sym_header_struct_base; + CV_Reg cv_reg = defrange_subfield_register->reg; + CV_LvarAddrRange *range = &defrange_subfield_register->range; + COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_subfield_register + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + RDI_RegCode reg_code = cv2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); + + // rjf: skip "subfield" location info - currently not supported + if(defrange_subfield_register->field_offset != 0) + { + break; + } + + // rjf: build location + RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); + + // rjf: emit locations over ranges + p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + }break; + + //- rjf: DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE + case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: + { + // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing + // a local - break immediately + if(defrange_target == 0) + { + break; + } + + // rjf: find current procedure's frameproc + CV_SymFrameproc *frameproc = 0; + if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0) + { + frameproc = procedure_frameprocs[procedure_num-1]; + } + + // rjf: no current valid frameproc? -> somehow we got a to a framepointer-relative defrange + // without having an actually active procedure - break + if(frameproc == 0) + { + break; + } + + // rjf: unpack sym + CV_SymDefrangeFramepointerRelFullScope *defrange_fprel_full_scope = (CV_SymDefrangeFramepointerRelFullScope*)sym_header_struct_base; + CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); + RDI_RegCode fp_register_code = cv2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); + + // rjf: build location + B32 extra_indirection = 0; + U32 byte_size = rdi_addr_size_from_arch(in->arch); + U32 byte_pos = 0; + S64 var_off = (S64)defrange_fprel_full_scope->off; + RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); + + // rjf: emit location over ranges + RDIM_Rng1U64 voff_range = {0, max_U64}; + rdim_location_set_push_case(arena, &sym_scopes, defrange_target, voff_range, location); + }break; + + //- rjf: DEFRANGE_REGISTER_REL + case CV_SymKind_DEFRANGE_REGISTER_REL: + { + // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing + // a local - break immediately + if(defrange_target == 0) + { + break; + } + + // rjf: unpack sym + CV_SymDefrangeRegisterRel *defrange_register_rel = (CV_SymDefrangeRegisterRel*)sym_header_struct_base; + CV_Reg cv_reg = defrange_register_rel->reg; + RDI_RegCode reg_code = cv2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); + CV_LvarAddrRange *range = &defrange_register_rel->range; + COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register_rel + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // rjf: build location + // TODO(rjf): offset & size from cv_reg code + U32 byte_size = rdi_addr_size_from_arch(in->arch); + U32 byte_pos = 0; + B32 extra_indirection_to_value = 0; + S64 var_off = defrange_register_rel->reg_off; + RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, reg_code, byte_size, byte_pos, var_off, extra_indirection_to_value); + + // rjf: emit locations over ranges + p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + }break; + + //- rjf: FILESTATIC + case CV_SymKind_FILESTATIC: + { + CV_SymFileStatic *file_static = (CV_SymFileStatic*)sym_header_struct_base; + String8 name = str8_cstring_capped(file_static+1, sym_data_opl); + RDIM_Type *type = p2r_type_ptr_from_itype(file_static->itype); + // TODO(rjf): emit a global modifier symbol + defrange_target = 0; + defrange_target_is_param = 0; + }break; + + //- rjf: INLINESITE + case CV_SymKind_INLINESITE: + { + // rjf: unpack sym + CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; + String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); + + // rjf: extract external info about inline site + String8 name = str8_zero(); + RDIM_Type *type = 0; + RDIM_Type *owner = 0; + if(in->ipi_leaf != 0 && in->ipi_leaf->itype_first <= sym->inlinee && sym->inlinee < in->ipi_leaf->itype_opl) + { + CV_RecRange rec_range = in->ipi_leaf->leaf_ranges.ranges[sym->inlinee - in->ipi_leaf->itype_first]; + String8 rec_data = str8_substr(in->ipi_leaf->data, rng_1u64(rec_range.off, rec_range.off + rec_range.hdr.size)); + void *raw_leaf = rec_data.str + sizeof(U16); + + // rjf: extract method inline info + if(rec_range.hdr.kind == CV_LeafKind_MFUNC_ID && + rec_range.hdr.size >= sizeof(CV_LeafMFuncId)) + { + CV_LeafMFuncId *mfunc_id = (CV_LeafMFuncId*)raw_leaf; + name = str8_cstring_capped(mfunc_id + 1, rec_data.str + rec_data.size); + type = p2r_type_ptr_from_itype(mfunc_id->itype); + owner = mfunc_id->owner_itype != 0 ? p2r_type_ptr_from_itype(mfunc_id->owner_itype) : 0; + } + + // rjf: extract non-method function inline info + else if(rec_range.hdr.kind == CV_LeafKind_FUNC_ID && + rec_range.hdr.size >= sizeof(CV_LeafFuncId)) + { + CV_LeafFuncId *func_id = (CV_LeafFuncId*)raw_leaf; + name = str8_cstring_capped(func_id + 1, rec_data.str + rec_data.size); + type = p2r_type_ptr_from_itype(func_id->itype); + owner = func_id->scope_string_id != 0 ? p2r_type_ptr_from_itype(func_id->scope_string_id) : 0; + } + } + + // rjf: build inline site + RDIM_InlineSite *inline_site = rdim_inline_site_chunk_list_push(arena, &sym_inline_sites, sym_inline_sites_chunk_cap); + inline_site->name = name; + inline_site->type = type; + inline_site->owner = owner; + inline_site->line_table = inline_site_line_table; + + // rjf: increment to next inline site line table in this unit + if(inline_site_line_table != 0 && inline_site_line_table->chunk != 0) + { + RDIM_LineTableChunkNode *chunk = inline_site_line_table->chunk; + U64 current_idx = (U64)(inline_site_line_table - chunk->v); + if(current_idx+1 < chunk->count) + { + inline_site_line_table += 1; + } + else + { + chunk = chunk->next; + inline_site_line_table = 0; + if(chunk != 0) + { + inline_site_line_table = chunk->v; + } + } + } + + // rjf: build scope + RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); + scope->inline_site = inline_site; + if(top_scope_node == 0) + { + // TODO(rjf): log + } + if(top_scope_node != 0) + { + RDIM_Scope *top_scope = top_scope_node->scope; + SLLQueuePush_N(top_scope->first_child, top_scope->last_child, scope, next_sibling); + scope->parent_scope = top_scope; + scope->symbol = top_scope->symbol; + } + + // rjf: push this scope to scope stack + { + P2R_ScopeNode *node = free_scope_node; + if(node != 0) { SLLStackPop(free_scope_node); } + else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } + node->scope = scope; + SLLStackPush(top_scope_node, node); + } + + // rjf: parse offset ranges of this inline site - attach to scope + { + CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(0, 0, procedure_base_voff); + for(;;) + { + CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); + + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) + { + // rjf: build new range & add to scope + RDIM_Rng1U64 voff_range = { step.range.min, step.range.max }; + rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); + } + + if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) + { + if(scope->voff_ranges.last != 0) + { + scope->voff_ranges.last->v.max = step.range.max; + } + } + + if(step.flags == 0) + { + break; + } + } + } + }break; + + //- rjf: INLINESITE_END + case CV_SymKind_INLINESITE_END: + { + P2R_ScopeNode *n = top_scope_node; + if(n != 0) + { + SLLStackPop(top_scope_node); + SLLStackPush(free_scope_node, n); + } + defrange_target = 0; + defrange_target_is_param = 0; + }break; + } + } + } + + ////////////////////////// + //- rjf: allocate & fill output + // + P2R_SymbolStreamConvertOut *out = push_array(arena, P2R_SymbolStreamConvertOut, 1); + { + out->procedures = sym_procedures; + out->global_variables = sym_global_variables; + out->thread_variables = sym_thread_variables; + out->scopes = sym_scopes; + out->inline_sites = sym_inline_sites; + } + +#undef p2r_type_ptr_from_itype + scratch_end(scratch); + ProfEnd(); + return out; +} + +//////////////////////////////// +//~ rjf: Top-Level Conversion Entry Point + +internal RDIM_BakeParams * +p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +{ + Temp scratch = scratch_begin(&arena, 1); + + g_p2r_help_state = help_state; + + ////////////////////////////////////////////////////////////// + //- rjf: parse MSF structure + // + MSF_Parsed *msf = 0; + if(in->debug_data.size != 0) ProfScope("parse MSF structure") + { + msf = msf_parsed_from_data(arena, in->debug_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse PDB auth_guid & named streams table + // + PDB_NamedStreamTable *named_streams = 0; + Guid auth_guid = {0}; + if(msf != 0) ProfScope("parse PDB auth_guid & named streams table") + { + Temp scratch = scratch_begin(&arena, 1); + String8 info_data = msf_data_from_stream(msf, PDB_FixedStream_Info); + PDB_Info *info = pdb_info_from_data(scratch.arena, info_data); + named_streams = pdb_named_stream_table_from_info(arena, info); + MemoryCopyStruct(&auth_guid, &info->auth_guid); + scratch_end(scratch); + + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { + fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); + os_abort(1); + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse PDB strtbl + // + PDB_Strtbl *strtbl = 0; + String8 raw_strtbl = str8_zero(); + if(named_streams != 0) ProfScope("parse PDB strtbl") + { + MSF_StreamNumber strtbl_sn = named_streams->sn[PDB_NamedStream_StringTable]; + String8 strtbl_data = msf_data_from_stream(msf, strtbl_sn); + strtbl = pdb_strtbl_from_data(arena, strtbl_data); + raw_strtbl = str8_substr(strtbl_data, rng_1u64(strtbl->strblock_min, strtbl->strblock_max)); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse dbi + // + PDB_DbiParsed *dbi = 0; + if(msf != 0) ProfScope("parse dbi") + { + String8 dbi_data = msf_data_from_stream(msf, PDB_FixedStream_Dbi); + dbi = pdb_dbi_from_data(arena, dbi_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse tpi + // + PDB_TpiParsed *tpi = 0; + if(msf != 0) ProfScope("parse tpi") + { + String8 tpi_data = msf_data_from_stream(msf, PDB_FixedStream_Tpi); + tpi = pdb_tpi_from_data(arena, tpi_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse ipi + // + PDB_TpiParsed *ipi = 0; + if(msf != 0) ProfScope("parse ipi") + { + String8 ipi_data = msf_data_from_stream(msf, PDB_FixedStream_Ipi); + ipi = pdb_tpi_from_data(arena, ipi_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse coff sections + // + COFF_SectionHeaderArray coff_sections = {0}; + if(dbi != 0) ProfScope("parse coff sections") + { + MSF_StreamNumber section_stream = dbi->dbg_streams[PDB_DbiStream_SECTION_HEADER]; + String8 section_data = msf_data_from_stream(msf, section_stream); + coff_sections = pdb_coff_section_array_from_data(arena, section_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse gsi + // + PDB_GsiParsed *gsi = 0; + if(dbi != 0) ProfScope("parse gsi") + { + String8 gsi_data = msf_data_from_stream(msf, dbi->gsi_sn); + gsi = pdb_gsi_from_data(arena, gsi_data); + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse psi + // + PDB_GsiParsed *psi_gsi_part = 0; + if(dbi != 0) ProfScope("parse psi") + { + String8 psi_data = msf_data_from_stream(msf, dbi->psi_sn); + String8 psi_data_gsi_part = str8_range(psi_data.str + sizeof(PDB_PsiHeader), psi_data.str + psi_data.size); + psi_gsi_part = pdb_gsi_from_data(arena, psi_data_gsi_part); + } + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff EXE hash + // + P2R_EXEHashIn exe_hash_in = {in->image_data}; + ASYNC_Task *exe_hash_task = async_task_launch(scratch.arena, p2r_exe_hash_work, .input = &exe_hash_in); + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff TPI hash parse + // + P2R_TPIHashParseIn tpi_hash_in = {0}; + ASYNC_Task *tpi_hash_task = 0; + if(tpi != 0) + { + tpi_hash_in.strtbl = strtbl; + tpi_hash_in.tpi = tpi; + tpi_hash_in.hash_data = msf_data_from_stream(msf, tpi->hash_sn); + tpi_hash_in.aux_data = msf_data_from_stream(msf, tpi->hash_sn_aux); + tpi_hash_task = async_task_launch(scratch.arena, p2r_tpi_hash_parse_work, .input = &tpi_hash_in); + } + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff TPI leaf parse + // + P2R_TPILeafParseIn tpi_leaf_in = {0}; + ASYNC_Task *tpi_leaf_task = 0; + if(tpi != 0) + { + tpi_leaf_in.leaf_data = pdb_leaf_data_from_tpi(tpi); + tpi_leaf_in.itype_first = tpi->itype_first; + tpi_leaf_task = async_task_launch(scratch.arena, p2r_tpi_leaf_parse_work, .input = &tpi_leaf_in); + } + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff IPI hash parse + // + P2R_TPIHashParseIn ipi_hash_in = {0}; + ASYNC_Task *ipi_hash_task = 0; + if(ipi != 0) + { + ipi_hash_in.strtbl = strtbl; + ipi_hash_in.tpi = ipi; + ipi_hash_in.hash_data = msf_data_from_stream(msf, ipi->hash_sn); + ipi_hash_in.aux_data = msf_data_from_stream(msf, ipi->hash_sn_aux); + ipi_hash_task = async_task_launch(scratch.arena, p2r_tpi_hash_parse_work, .input = &ipi_hash_in); + } + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff IPI leaf parse + // + P2R_TPILeafParseIn ipi_leaf_in = {0}; + ASYNC_Task *ipi_leaf_task = 0; + if(ipi != 0) + { + ipi_leaf_in.leaf_data = pdb_leaf_data_from_tpi(ipi); + ipi_leaf_in.itype_first = ipi->itype_first; + ipi_leaf_task = async_task_launch(scratch.arena, p2r_tpi_leaf_parse_work, .input = &ipi_leaf_in); + } + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff top-level global symbol stream parse + // + P2R_SymbolStreamParseIn sym_parse_in = {dbi ? msf_data_from_stream(msf, dbi->sym_sn) : str8_zero()}; + ASYNC_Task *sym_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_symbol_stream_parse_work, .input = &sym_parse_in); + + ////////////////////////////////////////////////////////////// + //- rjf: kickoff compilation unit parses + // + P2R_CompUnitParseIn comp_unit_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_ModuleInfo) : str8_zero()}; + P2R_CompUnitContributionsParseIn comp_unit_contributions_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_SecCon) : str8_zero(), coff_sections}; + ASYNC_Task *comp_unit_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_parse_work, .input = &comp_unit_parse_in); + ASYNC_Task *comp_unit_contributions_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_contributions_parse_work, .input = &comp_unit_contributions_parse_in); + + ////////////////////////////////////////////////////////////// + //- rjf: join compilation unit parses + // + PDB_CompUnitArray *comp_units = 0; + U64 comp_unit_count = 0; + PDB_CompUnitContributionArray *comp_unit_contributions = 0; + U64 comp_unit_contribution_count = 0; + { + comp_units = async_task_join_struct(comp_unit_parse_task, PDB_CompUnitArray); + comp_unit_contributions = async_task_join_struct(comp_unit_contributions_parse_task, PDB_CompUnitContributionArray); + comp_unit_count = comp_units ? comp_units->count : 0; + comp_unit_contribution_count = comp_unit_contributions ? comp_unit_contributions->count : 0; + } + + ////////////////////////////////////////////////////////////// + //- rjf: parse syms & line info for each compilation unit + // + CV_SymParsed **sym_for_unit = push_array(arena, CV_SymParsed *, comp_unit_count); + CV_C13Parsed **c13_for_unit = push_array(arena, CV_C13Parsed *, comp_unit_count); + if(comp_units != 0) ProfScope("parse syms & line info for each compilation unit") + { + //- rjf: kick off tasks + P2R_SymbolStreamParseIn *sym_tasks_inputs = push_array(scratch.arena, P2R_SymbolStreamParseIn, comp_unit_count); + ASYNC_Task **sym_tasks = push_array(scratch.arena, ASYNC_Task *, comp_unit_count); + P2R_C13StreamParseIn *c13_tasks_inputs = push_array(scratch.arena, P2R_C13StreamParseIn, comp_unit_count); + ASYNC_Task **c13_tasks = push_array(scratch.arena, ASYNC_Task *, comp_unit_count); + for(U64 idx = 0; idx < comp_unit_count; idx += 1) + { + PDB_CompUnit *unit = comp_units->units[idx]; + sym_tasks_inputs[idx].data = pdb_data_from_unit_range(msf, unit, PDB_DbiCompUnitRange_Symbols); + sym_tasks[idx] = async_task_launch(scratch.arena, p2r_symbol_stream_parse_work, .input = &sym_tasks_inputs[idx]); + c13_tasks_inputs[idx].data = pdb_data_from_unit_range(msf, unit, PDB_DbiCompUnitRange_C13); + c13_tasks_inputs[idx].strtbl = raw_strtbl; + c13_tasks_inputs[idx].coff_sections = coff_sections; + c13_tasks[idx] = async_task_launch(scratch.arena, p2r_c13_stream_parse_work, .input = &c13_tasks_inputs[idx]); + } + + //- rjf: join tasks + for(U64 idx = 0; idx < comp_unit_count; idx += 1) + { + sym_for_unit[idx] = async_task_join_struct(sym_tasks[idx], CV_SymParsed); + c13_for_unit[idx] = async_task_join_struct(c13_tasks[idx], CV_C13Parsed); + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: determine architecture + // + RDI_Arch arch = cv2r_rdi_arch_from_cv_arch(dbi->machine_type); + U64 arch_addr_size = rdi_addr_size_from_arch(arch); + + ////////////////////////////////////////////////////////////// + //- rjf: join EXE hash + // + U64 exe_hash = *async_task_join_struct(exe_hash_task, U64); + + ////////////////////////////////////////////////////////////// + //- rjf: produce top-level-info + // + RDIM_TopLevelInfo top_level_info = c2r_make_rdim_top_level_info(in->image_name, arch, exe_hash, coff_sections.count, coff_sections.v); + + ////////////////////////////////////////////////////////////// + //- rjf: build binary sections list + // + RDIM_BinarySectionList binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, str8_zero(), 0, coff_sections.count, coff_sections.v); + + ////////////////////////////////////////////////////////////// + //- rjf: kick off unit conversion & source file collection + // + P2R_UnitConvertIn unit_convert_in = {strtbl, coff_sections, comp_units, comp_unit_contributions, sym_for_unit, c13_for_unit}; + ASYNC_Task *unit_convert_task = async_task_launch(scratch.arena, p2r_units_convert_work, .input = &unit_convert_in); + + ////////////////////////////////////////////////////////////// + //- rjf: join global sym stream parse + // + CV_SymParsed *sym = async_task_join_struct(sym_parse_task, CV_SymParsed); + + ////////////////////////////// + //- rjf: predict symbol count + // + U64 symbol_count_prediction = 0; + ProfScope("predict symbol count") + { + U64 rec_range_count = 0; + if(sym != 0) + { + rec_range_count += sym->sym_ranges.count; + } + for(U64 comp_unit_idx = 0; comp_unit_idx < comp_unit_count; comp_unit_idx += 1) + { + CV_SymParsed *unit_sym = sym_for_unit[comp_unit_idx]; + rec_range_count += unit_sym->sym_ranges.count; + } + symbol_count_prediction = rec_range_count/8; + if(symbol_count_prediction < 256) + { + symbol_count_prediction = 256; + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: kick off link name map production + // + P2R_LinkNameMap link_name_map__in_progress = {0}; + P2R_LinkNameMapBuildIn link_name_map_build_in = {0}; + ASYNC_Task *link_name_map_task = 0; + if(sym != 0) ProfScope("kick off link name map build task") + { + link_name_map__in_progress.buckets_count = symbol_count_prediction; + link_name_map__in_progress.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map__in_progress.buckets_count); + link_name_map_build_in.sym = sym; + link_name_map_build_in.coff_sections = coff_sections; + link_name_map_build_in.link_name_map = &link_name_map__in_progress; + link_name_map_task = async_task_launch(scratch.arena, p2r_link_name_map_build_work, .input = &link_name_map_build_in); + } + + ////////////////////////////////////////////////////////////// + //- rjf: join ipi/tpi hash/leaf parses + // + PDB_TpiHashParsed *tpi_hash = 0; + CV_LeafParsed *tpi_leaf = 0; + PDB_TpiHashParsed *ipi_hash = 0; + CV_LeafParsed *ipi_leaf = 0; + { + tpi_hash = async_task_join_struct(tpi_hash_task, PDB_TpiHashParsed); + tpi_leaf = async_task_join_struct(tpi_leaf_task, CV_LeafParsed); + ipi_hash = async_task_join_struct(ipi_hash_task, PDB_TpiHashParsed); + ipi_leaf = async_task_join_struct(ipi_leaf_task, CV_LeafParsed); + } + + ////////////////////////////////////////////////////////////// + //- rjf: types pass 1: construct all types from TPI + // + // this doesn't gather struct/class/union/enum members, which is done by + // subsequent passes, to build RDI "UDT" information, which is distinct + // from regular type info. + // + RDIM_Type **itype_type_ptrs = 0; + RDIM_TypeChunkList all_types = {0}; +#define p2r_type_ptr_from_itype(itype) (((itype) < tpi_leaf->itype_opl) ? itype_type_ptrs[itype] : 0) + if(in->flags & RC_Flag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") + { + itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); + + ////////////////////////// + //- build basic type + // + { + RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); + + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); + RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); + RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); + RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); + RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); + RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); + RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); + RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); + RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); + + struct + { + char * name; + RDI_TypeKind kind_rdi; + CV_LeafKind kind_cv; + B32 make_pointer_near; + B32 make_pointer_32; + B32 make_pointer_64; + } + table[] = + { + { "" , RDI_TypeKind_NULL , CV_BasicType_NOTYPE , 0, 0, 0 }, + { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, + { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, + { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, + { "short" , short_type , CV_BasicType_SHORT , 1, 1, 1 }, + { "long" , long_type , CV_BasicType_LONG , 1, 1, 1 }, + { "long long" , long_long_type , CV_BasicType_QUAD , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT , 1, 1, 1 }, // Clang type + { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR , 1, 1, 1 }, + { "unsigned short" , ushort_type , CV_BasicType_USHORT , 1, 1, 1 }, + { "unsigned long" , ulong_type , CV_BasicType_ULONG , 1, 1, 1 }, + { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT , 1, 1, 1 }, // Clang type + { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 , 1, 1, 1 }, + { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 , 1, 1, 1 }, // not real C type + { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 , 1, 1, 1 }, // not real C type + { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 , 1, 1, 1 }, + { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 , 1, 1, 1 }, + { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 , 1, 1, 1 }, + { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 , 1, 1, 1 }, // Clang type + { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 , 1, 1, 1 }, // not real C type + { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP , 1, 1, 1 }, // not real C type + { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 , 0, 0, 0 }, + { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 , 0, 0, 0 }, + { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 , 0, 0, 0 }, + { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 , 0, 0, 0 }, + { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 , 1, 1, 1 }, + { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, + { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, + { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, + { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, + { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, + { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, + { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 , 1, 1, 1 }, + { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR , 1, 1, 1 }, // always ASCII + { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR , 1, 1, 1 }, // on windows always UTF-16 + { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 , 1, 1, 1 }, // always UTF-8 + { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 , 1, 1, 1 }, // always UTF-16 + { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 + { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } + }; + + for(U64 i = 0; i < ArrayCount(table); i += 1) + { + U64 builtin_size; + if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) + { + builtin_size = arch_addr_size; + } + else + { + builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); + } + + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + builtin->kind = table[i].kind_rdi; + builtin->name = str8_cstring(table[i].name); + builtin->byte_size = builtin_size; + + itype_type_ptrs[table[i].kind_cv] = builtin; + + if(table[i].make_pointer_near) + { + CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; + RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_near->kind = RDI_TypeKind_Ptr; + ptr_near->byte_size = 2; + ptr_near->direct_type = builtin; + + itype_type_ptrs[near_ptr_itype] = ptr_near; + } + if(table[i].make_pointer_32) + { + CV_TypeIndex ptr_32_itype = table[i].kind_cv | 0x400; + RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_32->kind = RDI_TypeKind_Ptr; + ptr_32->byte_size = 4; + ptr_32->direct_type = builtin; + + itype_type_ptrs[ptr_32_itype] = ptr_32; + } + if(table[i].make_pointer_64) + { + CV_TypeIndex ptr_64_itype = table[i].kind_cv | 0x600; + RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_64->kind = RDI_TypeKind_Ptr; + ptr_64->byte_size = 8; + ptr_64->direct_type = builtin; + + itype_type_ptrs[ptr_64_itype] = ptr_64; + } + } + } + + ////////////////////////// + //- rjf: build non-basic type + // + for(CV_TypeId itype = tpi_leaf->itype_first; itype < tpi_leaf->itype_opl; itype += 1) + { + RDIM_Type *dst_type = 0; + CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + + if(range->off+range->hdr.size <= tpi_leaf->data.size && + range->off+2+header_struct_size <= tpi_leaf->data.size && + range->hdr.size >= 2) + { + U8 *itype_leaf_first = tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + switch(kind) + { + //- rjf: MODIFIER + case CV_LeafKind_MODIFIER: + { + // rjf: unpack leaf + CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; + + // rjf: cv -> rdi flags + RDI_TypeModifierFlags flags = 0; + if(lf->flags & CV_ModifierFlag_Const) {flags |= RDI_TypeModifierFlag_Const;} + if(lf->flags & CV_ModifierFlag_Volatile) {flags |= RDI_TypeModifierFlag_Volatile;} + + // rjf: fill type + if(flags == 0) + { + dst_type = p2r_type_ptr_from_itype(lf->itype); + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = flags; + dst_type->direct_type = p2r_type_ptr_from_itype(lf->itype); + dst_type->byte_size = dst_type->direct_type ? dst_type->direct_type->byte_size : 0; + } + }break; + + //- rjf: POINTER + case CV_LeafKind_POINTER: + { + // TODO(rjf): if ptr_mode in {PtrMem, PtrMethod} then output a member pointer instead + + // rjf: unpack leaf + CV_LeafPointer *lf = (CV_LeafPointer *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(lf->attribs); + CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(lf->attribs); + U32 ptr_size = CV_PointerAttribs_Extract_Size(lf->attribs); + + // rjf: cv -> rdi modifier flags + RDI_TypeModifierFlags modifier_flags = 0; + if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} + if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} + if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} + + // rjf: cv info -> rdi pointer type kind + RDI_TypeKind type_kind = RDI_TypeKind_Ptr; + { + if(lf->attribs & CV_PointerAttrib_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(lf->attribs & CV_PointerAttrib_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + if(ptr_mode == CV_PointerMode_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(ptr_mode == CV_PointerMode_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + } + + // rjf: fill type + if(modifier_flags != 0) + { + RDIM_Type *pointer_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = modifier_flags; + dst_type->direct_type = pointer_type; + dst_type->byte_size = arch_addr_size; + pointer_type->kind = type_kind; + pointer_type->byte_size = arch_addr_size; + pointer_type->direct_type = direct_type; + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = type_kind; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = direct_type; + } + }break; + + //- rjf: PROCEDURE + case CV_LeafKind_PROCEDURE: + { + // TODO(rjf): handle call_kind & attribs + + // rjf: unpack leaf + CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type's basics + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count; + dst_type->param_types = params; + }break; + + //- rjf: MFUNCTION + case CV_LeafKind_MFUNCTION: + { + // TODO(rjf): handle call_kind & attribs + // TODO(rjf): preserve "this_adjust" + + // rjf: unpack leaf + CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = (lf->this_itype != 0) ? RDI_TypeKind_Method : RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + U64 num_this_extras = 1; + if(lf->this_itype == 0) + { + num_this_extras = 0; + } + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count+num_this_extras); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx+num_this_extras] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + if(lf->this_itype != 0) + { + params[0] = p2r_type_ptr_from_itype(lf->this_itype); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count+num_this_extras; + dst_type->param_types = params; + }break; + + //- rjf: BITFIELD + case CV_LeafKind_BITFIELD: + { + // rjf: unpack leaf + CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Bitfield; + dst_type->off = lf->pos; + dst_type->count = lf->len; + dst_type->byte_size = direct_type?direct_type->byte_size:0; + dst_type->direct_type = direct_type; + }break; + + //- rjf: ARRAY + case CV_LeafKind_ARRAY: + { + // rjf: unpack leaf + CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->entry_itype); + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed array_count = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 full_size = cv_u64_from_numeric(&array_count); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + dst_type->kind = RDI_TypeKind_Array; + dst_type->direct_type = direct_type; + dst_type->byte_size = full_size; + }break; + + //- rjf: CLASS/STRUCTURE + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + + dst_type->name = name; + dst_type->byte_size = safe_cast_u32(size_u64); + }break; + + //- rjf: CLASS2/STRUCT2 + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + dst_type->name = name; + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + + //- rjf: UNION + case CV_LeafKind_UNION: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteUnion; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Union; + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + + //- rjf: ENUM + case CV_LeafKind_ENUM: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->base_itype); + U8 *name_ptr = (U8 *)(lf + 1); + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteEnum; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Enum; + dst_type->direct_type = direct_type; + dst_type->byte_size = direct_type ? direct_type->byte_size : 0; + dst_type->name = name; + } + + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && + ((lf->props & CV_TypeProp_HasUniqueName) != 0)); + if(do_unique_name_lookup) + { + U8 *unique_name_ptr = name_ptr + name.size + 1; + dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + } + }break; + } + } + + //- rjf: store finalized type to this itype's slot + itype_type_ptrs[itype] = dst_type; + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: types pass 2: kick off UDT build + // + U64 udt_task_size_itypes = 4096; + U64 udt_tasks_count = (tpi_leaf->itype_opl+(udt_task_size_itypes-1))/udt_task_size_itypes; + P2R_UDTConvertIn *udt_tasks_inputs = push_array(scratch.arena, P2R_UDTConvertIn, udt_tasks_count); + ASYNC_Task **udt_tasks = push_array(scratch.arena, ASYNC_Task *, udt_tasks_count); + if(in->flags & RC_Flag_UDTs) ProfScope("types pass 2: kick off UDT build") + { + for(U64 idx = 0; idx < udt_tasks_count; idx += 1) + { + udt_tasks_inputs[idx].tpi_leaf = tpi_leaf; + udt_tasks_inputs[idx].itype_first = idx*udt_task_size_itypes; + udt_tasks_inputs[idx].itype_opl = udt_tasks_inputs[idx].itype_first + udt_task_size_itypes; + udt_tasks_inputs[idx].itype_opl = ClampTop(udt_tasks_inputs[idx].itype_opl, tpi_leaf->itype_opl); + udt_tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; + udt_tasks[idx] = async_task_launch(scratch.arena, p2r_udt_convert_work, .input = &udt_tasks_inputs[idx]); + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: join link name map building task + // + P2R_LinkNameMap *link_name_map = 0; + ProfScope("join link name map building task") + { + async_task_join(link_name_map_task); + link_name_map = &link_name_map__in_progress; + } + + ////////////////////////////////////////////////////////////// + //- rjf: join unit conversion & src file & line table tasks + // + RDIM_UnitChunkList all_units = {0}; + RDIM_SrcFileChunkList all_src_files = {0}; + RDIM_LineTableChunkList all_line_tables = {0}; + RDIM_LineTable **units_first_inline_site_line_tables = 0; + ProfScope("join unit conversion & src file tasks") + { + P2R_UnitConvertOut *out = async_task_join_struct(unit_convert_task, P2R_UnitConvertOut); + all_units = out->units; + all_src_files = out->src_files; + all_line_tables = out->line_tables; + units_first_inline_site_line_tables = out->units_first_inline_site_line_tables; + } + + ////////////////////////////////////////////////////////////// + //- rjf: produce symbols from all streams + // + RDIM_SymbolChunkList all_procedures = {0}; + RDIM_SymbolChunkList all_global_variables = {0}; + RDIM_SymbolChunkList all_thread_variables = {0}; + RDIM_ScopeChunkList all_scopes = {0}; + RDIM_InlineSiteChunkList all_inline_sites = {0}; + ProfScope("produce symbols from all streams") + { + //////////////////////////// + //- rjf: kick off all symbol conversion tasks + // + U64 global_stream_subdivision_tasks_count = sym ? (sym->sym_ranges.count+16383)/16384 : 0; + U64 global_stream_syms_per_task = sym ? sym->sym_ranges.count/global_stream_subdivision_tasks_count : 0; + U64 tasks_count = comp_unit_count + global_stream_subdivision_tasks_count; + P2R_SymbolStreamConvertIn *tasks_inputs = push_array(scratch.arena, P2R_SymbolStreamConvertIn, tasks_count); + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, tasks_count); + ProfScope("kick off all symbol conversion tasks") + { + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + tasks_inputs[idx].arch = arch; + tasks_inputs[idx].coff_sections = coff_sections; + tasks_inputs[idx].tpi_hash = tpi_hash; + tasks_inputs[idx].tpi_leaf = tpi_leaf; + tasks_inputs[idx].ipi_leaf = ipi_leaf; + tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; + tasks_inputs[idx].link_name_map = link_name_map; + if(idx < global_stream_subdivision_tasks_count) + { + tasks_inputs[idx].sym = sym; + tasks_inputs[idx].sym_ranges_first= idx*global_stream_syms_per_task; + tasks_inputs[idx].sym_ranges_opl = tasks_inputs[idx].sym_ranges_first + global_stream_syms_per_task; + tasks_inputs[idx].sym_ranges_opl = ClampTop(tasks_inputs[idx].sym_ranges_opl, sym->sym_ranges.count); + } + else + { + tasks_inputs[idx].sym = sym_for_unit[idx-global_stream_subdivision_tasks_count]; + tasks_inputs[idx].sym_ranges_first= 0; + tasks_inputs[idx].sym_ranges_opl = sym_for_unit[idx-global_stream_subdivision_tasks_count]->sym_ranges.count; + tasks_inputs[idx].first_inline_site_line_table = units_first_inline_site_line_tables[idx-global_stream_subdivision_tasks_count]; + } + tasks[idx] = async_task_launch(scratch.arena, p2r_symbol_stream_convert_work, .input = &tasks_inputs[idx]); + } + } + + //////////////////////////// + //- rjf: join tasks, merge with top-level collections + // + ProfScope("join tasks, merge with top-level collections") + { + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + P2R_SymbolStreamConvertOut *out = async_task_join_struct(tasks[idx], P2R_SymbolStreamConvertOut); + rdim_symbol_chunk_list_concat_in_place(&all_procedures, &out->procedures); + rdim_symbol_chunk_list_concat_in_place(&all_global_variables, &out->global_variables); + rdim_symbol_chunk_list_concat_in_place(&all_thread_variables, &out->thread_variables); + rdim_scope_chunk_list_concat_in_place(&all_scopes, &out->scopes); + rdim_inline_site_chunk_list_concat_in_place(&all_inline_sites,&out->inline_sites); + } + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: types pass 5: join UDT build tasks + // + RDIM_UDTChunkList all_udts = {0}; + for(U64 idx = 0; idx < udt_tasks_count; idx += 1) + { + RDIM_UDTChunkList *udts = async_task_join_struct(udt_tasks[idx], RDIM_UDTChunkList); + rdim_udt_chunk_list_concat_in_place(&all_udts, udts); + } + + ////////////////////////////////////////////////////////////// + //- rjf: fill output + // + RDIM_BakeParams *out = push_array(arena, RDIM_BakeParams, 1); + { + out->top_level_info = top_level_info; + out->binary_sections = binary_sections; + out->units = all_units; + out->types = all_types; + out->udts = all_udts; + out->src_files = all_src_files; + out->line_tables = all_line_tables; + out->global_variables = all_global_variables; + out->thread_variables = all_thread_variables; + out->procedures = all_procedures; + out->scopes = all_scopes; + out->inline_sites = all_inline_sites; + } + + scratch_end(scratch); + return out; +} + +//////////////////////////////// + +internal B32 +p2r_has_symbol_ref(String8 msf_data, String8List symbol_list, MSF_RawStreamTable *st) +{ + Temp scratch = scratch_begin(0,0); + + B32 has_ref = 0; + + String8 dbi_data = msf_data_from_stream_number(scratch.arena, msf_data, st, PDB_FixedStream_Dbi); + PDB_DbiParsed *dbi = pdb_dbi_from_data(scratch.arena, dbi_data); + if(dbi) + { + String8 gsi_data = msf_data_from_stream_number(scratch.arena, msf_data, st, dbi->gsi_sn); + PDB_GsiParsed *gsi_parsed = pdb_gsi_from_data(scratch.arena, gsi_data); + if(gsi_parsed) + { + String8 symbol_data = msf_data_from_stream_number(scratch.arena, msf_data, st, dbi->sym_sn); + + for(String8Node *symbol_n = symbol_list.first; symbol_n != 0; symbol_n = symbol_n->next) + { + U64 symbol_off = pdb_gsi_symbol_from_string(gsi_parsed, symbol_data, symbol_n->string); + if(symbol_off < symbol_data.size) + { + has_ref = 1; + break; + } + } + } + } + + scratch_end(scratch); + return has_ref; +} + +internal B32 +p2r_has_file_ref(String8 msf_data, String8List file_list, MSF_RawStreamTable *st) +{ + Temp scratch = scratch_begin(0,0); + + B32 has_ref = 0; + + String8 info_data = msf_data_from_stream_number(scratch.arena, msf_data, st, PDB_FixedStream_Info); + PDB_Info *info = pdb_info_from_data(scratch.arena, info_data); + if(info) + { + PDB_NamedStreamTable *named_streams = pdb_named_stream_table_from_info(scratch.arena, info); + if(named_streams) + { + MSF_StreamNumber strtbl_sn = named_streams->sn[PDB_NamedStream_StringTable]; + String8 strtbl_data = msf_data_from_stream_number(scratch.arena, msf_data, st, strtbl_sn); + PDB_Strtbl *strtbl = pdb_strtbl_from_data(scratch.arena, strtbl_data); + if(strtbl) + { + for(String8Node *file_n = file_list.first; file_n != 0; file_n = file_n->next) + { + U32 off = pdb_strtbl_off_from_string(strtbl, file_n->string); + if(off != max_U32) + { + has_ref = 1; + break; + } + } + } + } + } + + scratch_end(scratch); + return has_ref; +} + +internal B32 +p2r_has_symbol_or_file_ref(String8 msf_data, String8List symbol_list, String8List file_list) +{ + Temp scratch = scratch_begin(0,0); + + B32 has_ref = 0; + + MSF_RawStreamTable *st = msf_raw_stream_table_from_data(scratch.arena, msf_data); + + if(!has_ref && symbol_list.node_count) + { + has_ref = p2r_has_symbol_ref(msf_data, symbol_list, st); + } + + if(!has_ref && file_list.node_count) + { + has_ref = p2r_has_file_ref(msf_data, file_list, st); + } + + scratch_end(scratch); + return has_ref; +} + diff --git a/src/radcon/radcon_pdb.h b/src/radcon/radcon_pdb.h new file mode 100644 index 00000000..e4574a32 --- /dev/null +++ b/src/radcon/radcon_pdb.h @@ -0,0 +1,238 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADCON_PDB_H +#define RADCON_PDB_H + +//////////////////////////////// +//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types + +//- rjf: tpi hash parsing + +typedef struct P2R_TPIHashParseIn P2R_TPIHashParseIn; +struct P2R_TPIHashParseIn +{ + PDB_Strtbl *strtbl; + PDB_TpiParsed *tpi; + String8 hash_data; + String8 aux_data; +}; + +//- rjf: tpi leaves parsing + +typedef struct P2R_TPILeafParseIn P2R_TPILeafParseIn; +struct P2R_TPILeafParseIn +{ + String8 leaf_data; + CV_TypeId itype_first; +}; + +//- rjf: exe hashing + +typedef struct P2R_EXEHashIn P2R_EXEHashIn; +struct P2R_EXEHashIn +{ + String8 exe_data; +}; + +//- rjf: symbol stream parsing + +typedef struct P2R_SymbolStreamParseIn P2R_SymbolStreamParseIn; +struct P2R_SymbolStreamParseIn +{ + String8 data; +}; + +//- rjf: c13 line info stream parsing + +typedef struct P2R_C13StreamParseIn P2R_C13StreamParseIn; +struct P2R_C13StreamParseIn +{ + String8 data; + String8 strtbl; + COFF_SectionHeaderArray coff_sections; +}; + +//- rjf: comp unit parsing + +typedef struct P2R_CompUnitParseIn P2R_CompUnitParseIn; +struct P2R_CompUnitParseIn +{ + String8 data; +}; + +//- rjf: comp unit contribution table parsing + +typedef struct P2R_CompUnitContributionsParseIn P2R_CompUnitContributionsParseIn; +struct P2R_CompUnitContributionsParseIn +{ + String8 data; + COFF_SectionHeaderArray coff_sections; +}; + +//////////////////////////////// +//~ rjf: Conversion Data Structure & Task Types + +//- rjf: link name map (voff -> string) + +typedef struct P2R_LinkNameNode P2R_LinkNameNode; +struct P2R_LinkNameNode +{ + P2R_LinkNameNode *next; + U64 voff; + String8 name; +}; + +typedef struct P2R_LinkNameMap P2R_LinkNameMap; +struct P2R_LinkNameMap +{ + P2R_LinkNameNode **buckets; + U64 buckets_count; + U64 bucket_collision_count; + U64 link_name_count; +}; + +//- rjf: normalized file path -> source file map + +typedef struct P2R_SrcFileNode P2R_SrcFileNode; +struct P2R_SrcFileNode +{ + P2R_SrcFileNode *next; + RDIM_SrcFile *src_file; +}; + +typedef struct P2R_SrcFileMap P2R_SrcFileMap; +struct P2R_SrcFileMap +{ + P2R_SrcFileNode **slots; + U64 slots_count; +}; + +//- rjf: unit conversion tasks + +typedef struct P2R_UnitConvertIn P2R_UnitConvertIn; +struct P2R_UnitConvertIn +{ + PDB_Strtbl *pdb_strtbl; + COFF_SectionHeaderArray coff_sections; + PDB_CompUnitArray *comp_units; + PDB_CompUnitContributionArray *comp_unit_contributions; + CV_SymParsed **comp_unit_syms; + CV_C13Parsed **comp_unit_c13s; +}; + +typedef struct P2R_UnitConvertOut P2R_UnitConvertOut; +struct P2R_UnitConvertOut +{ + RDIM_UnitChunkList units; + RDIM_SrcFileChunkList src_files; + RDIM_LineTableChunkList line_tables; + RDIM_LineTable **units_first_inline_site_line_tables; +}; + +//- rjf: link name map building tasks + +typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn; +struct P2R_LinkNameMapBuildIn +{ + CV_SymParsed *sym; + COFF_SectionHeaderArray coff_sections; + P2R_LinkNameMap *link_name_map; +}; + +//- rjf: udt conversion + +typedef struct P2R_UDTConvertIn P2R_UDTConvertIn; +struct P2R_UDTConvertIn +{ + CV_LeafParsed *tpi_leaf; + CV_TypeId itype_first; + CV_TypeId itype_opl; + RDIM_Type **itype_type_ptrs; +}; + +//- rjf: symbol stream conversion + +typedef struct P2R_SymbolStreamConvertIn P2R_SymbolStreamConvertIn; +struct P2R_SymbolStreamConvertIn +{ + RDI_Arch arch; + COFF_SectionHeaderArray coff_sections; + PDB_TpiHashParsed *tpi_hash; + CV_LeafParsed *tpi_leaf; + CV_LeafParsed *ipi_leaf; + CV_SymParsed *sym; + U64 sym_ranges_first; + U64 sym_ranges_opl; + RDIM_Type **itype_type_ptrs; + P2R_LinkNameMap *link_name_map; + RDIM_LineTable *first_inline_site_line_table; +}; + +typedef struct P2R_SymbolStreamConvertOut P2R_SymbolStreamConvertOut; +struct P2R_SymbolStreamConvertOut +{ + RDIM_SymbolChunkList procedures; + RDIM_SymbolChunkList global_variables; + RDIM_SymbolChunkList thread_variables; + RDIM_ScopeChunkList scopes; + RDIM_InlineSiteChunkList inline_sites; +}; + +//////////////////////////////// +//~ rjf: Basic Helpers + +internal U64 p2r_end_of_cplusplus_container_name(String8 str); +internal U64 p2r_hash_from_voff(U64 voff); + +//////////////////////////////// +//~ rjf: Location Info Building Helpers + +internal RDIM_Location *p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection); +internal RDI_RegCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg); +internal void p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count); + +//////////////////////////////// +//~ rjf: Initial Parsing & Preparation Pass Tasks + +ASYNC_WORK_DEF(p2r_exe_hash_work); +ASYNC_WORK_DEF(p2r_tpi_hash_parse_work); +ASYNC_WORK_DEF(p2r_tpi_leaf_work); +ASYNC_WORK_DEF(p2r_symbol_stream_parse_work); +ASYNC_WORK_DEF(p2r_c13_stream_parse_work); +ASYNC_WORK_DEF(p2r_comp_unit_parse_work); +ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work); + +//////////////////////////////// +//~ rjf: Unit Conversion Tasks + +ASYNC_WORK_DEF(p2r_units_convert_work); + +//////////////////////////////// +//~ rjf: Link Name Map Building Tasks + +ASYNC_WORK_DEF(p2r_link_name_map_build_work); + +//////////////////////////////// +//~ rjf: UDT Conversion Tasks + +ASYNC_WORK_DEF(p2r_udt_convert_work); + +//////////////////////////////// +//~ rjf: Symbol Stream Conversion Tasks + +ASYNC_WORK_DEF(p2r_symbol_stream_convert_work); + +//////////////////////////////// +//~ rjf: Top-Level Conversion Entry Point + +internal RDIM_BakeParams *p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); + +//////////////////////////////// + +internal B32 p2r_has_symbol_ref(String8 msf_data, String8List symbol_list, MSF_RawStreamTable *st); +internal B32 p2r_has_file_ref(String8 msf_data, String8List file_list, MSF_RawStreamTable *st); +internal B32 p2r_has_symbol_or_file_ref(String8 msf_data, String8List symbol_list, String8List file_list); + +#endif // RADCON_PDB_H + diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 531f5d74..d369ff54 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -42,78 +42,21 @@ rd_stderr(char *fmt, ...) scratch_end(scratch); } -internal String8 -rd_invoke_rdi_converter(Arena *arena, String8 exe_name, String8 exe_data, String8 pdb_path) -{ - Temp scratch = scratch_begin(0,0); - - P2R_User2Convert user2convert = {0}; - user2convert.input_pdb_name = pdb_path; - user2convert.input_pdb_data = os_data_from_file_path(scratch.arena, pdb_path); - user2convert.input_exe_name = exe_name; - user2convert.input_exe_data = exe_data; - user2convert.output_name = str8_zero(); - user2convert.flags = P2R_ConvertFlag_All; - - P2R_Convert2Bake *convert2bake = p2r_convert(scratch.arena, &user2convert); - P2R_Bake2Serialize *bake2srlz = p2r_bake(scratch.arena, convert2bake); - RDIM_SerializedSectionBundle bundle = rdim_serialized_section_bundle_from_bake_results(&bake2srlz->bake_results); - String8List rdi_blobs = rdim_file_blobs_from_section_bundle(scratch.arena, &bundle); - String8 raw_rdi = str8_list_join(arena, &rdi_blobs, 0); - - scratch_end(scratch); - return raw_rdi; -} - internal RDI_Parsed * -rd_rdi_from_pe(Arena *arena, String8 data_path, String8 raw_data) +rd_rdi_from_pe(Arena *arena, String8 pe_path) { Temp scratch = scratch_begin(&arena, 1); + // make command line for converter + String8List cmdl_string = {0}; + str8_list_pushf(scratch.arena, &cmdl_string, "-pe:%S", pe_path); + CmdLine cmdl = cmd_line_from_string_list(scratch.arena, cmdl_string); + + // run converter + String8 raw_rdi = rc_rdi_from_cmd_line(scratch.arena, &cmdl); + + // load RDI RDI_Parsed *rdi = 0; - - PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, raw_data); - String8 raw_debug_dir = str8_substr(raw_data, pe.data_dir_franges[PE_DataDirectoryIndex_DEBUG]); - PE_DebugInfoList dbg_list = pe_parse_debug_directory(scratch.arena, raw_data, raw_debug_dir); - - String8 raw_rdi = {0}; - Guid rdi_guid = {0}; - for (PE_DebugInfoNode *n = dbg_list.first; n != 0; n = n->next) { - PE_DebugInfo *v = &n->v; - if (v->header.type == PE_DebugDirectoryType_CODEVIEW) { - if (v->u.codeview.magic == PE_CODEVIEW_RDI_MAGIC) { - if (raw_rdi.size) { - rd_warningf("multiple RDI paths defined in %S"); - } else { - raw_rdi = os_data_from_file_path(arena, v->u.codeview.rdi.path); - rdi_guid = v->u.codeview.rdi.header.guid; - if (raw_rdi.size == 0) { - rd_errorf("unable to open RDI: %S", v->u.codeview.rdi.path); - } - } - } - } - } - - if (!raw_rdi.size) { - String8 pdb_path = str8_zero(); - Guid pdb_guid = {0}; - B32 convert_pdb = 0; - for (PE_DebugInfoNode *n = dbg_list.first; n != 0; n = n->next) { - PE_DebugInfo *v = &n->v; - if (v->header.type == PE_DebugDirectoryType_CODEVIEW) { - pdb_path = v->u.codeview.pdb70.path; - pdb_guid = v->u.codeview.pdb70.header.guid; - convert_pdb = 1; - break; - } - } - - if (convert_pdb) { - raw_rdi = rd_invoke_rdi_converter(scratch.arena, data_path, raw_data, pdb_path); - } - } - if (raw_rdi.size) { rdi = push_array(arena, RDI_Parsed, 1); diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index f72c53d6..c8225dba 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -53,8 +53,12 @@ #include "dwarf/dwarf_coff.h" #include "dwarf/dwarf_elf.h" #include "dwarf/dwarf_enum.h" -#include "rdi_from_pdb/rdi_from_pdb.h" -#include "rdi_from_dwarf/rdi_from_dwarf.h" +#include "radcon/radcon.h" +#include "radcon/radcon_coff.h" +#include "radcon/radcon_cv.h" +#include "radcon/radcon_elf.h" +#include "radcon/radcon_pdb.h" +#include "radcon/radcon_dwarf.h" #include "base/base_inc.c" #include "linker/base_ext/base_inc.c" @@ -87,8 +91,12 @@ #include "dwarf/dwarf_coff.c" #include "dwarf/dwarf_elf.c" #include "dwarf/dwarf_enum.c" -#include "rdi_from_pdb/rdi_from_pdb.c" -#include "rdi_from_dwarf/rdi_from_dwarf.c" +#include "radcon/radcon_coff.c" +#include "radcon/radcon_cv.c" +#include "radcon/radcon_elf.c" +#include "radcon/radcon_pdb.c" +#include "radcon/radcon_dwarf.c" +#include "radcon/radcon.c" #include "linker/thread_pool/thread_pool.h" #include "linker/thread_pool/thread_pool.c" @@ -288,7 +296,7 @@ entry_point(CmdLine *cmdline) } else if (pe_check_magic(raw_data)) { RDI_Parsed *rdi = 0; if (!(opts & RD_Option_NoRdi)) { - rdi = rd_rdi_from_pe(arena, file_path, raw_data); + rdi = rd_rdi_from_pe(arena, file_path); } pe_print(arena, out, indent, raw_data, opts, rdi); } else if (pe_is_res(raw_data)) { From 7d5110e7521ee8f8b9f26a86985dc8e9be1be8ad Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 22 Mar 2025 23:56:22 -0700 Subject: [PATCH 259/755] take into account null type slot --- src/rdi_make/rdi_make_help.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c index f85d38a1..93576760 100644 --- a/src/rdi_make/rdi_make_help.c +++ b/src/rdi_make/rdi_make_help.c @@ -436,7 +436,7 @@ rdim_help_resolve_incomplete_types(RDIM_TypeChunkList *types) Temp scratch = scratch_begin(0,0); ProfBegin("Build Hash Table"); - RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count); + RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) { for(RDI_U64 i = 0; i < chunk->count; i += 1) @@ -485,7 +485,7 @@ rdim_help_resolve_incomplete_types(RDIM_TypeChunkList *types) ProfEnd(); ProfBegin("Make Fwd Map"); - RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count); + RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) { for(RDI_U64 i = 0; i < chunk->count; i += 1) From a63254b70da3b6c916ae6226eec5d5a01eb1bc21 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 24 Mar 2025 11:40:59 -0700 Subject: [PATCH 260/755] merged rdim_help.c into rdim_local.c --- src/radcon/radcon.c | 8 +- src/radcon/radcon_dwarf.c | 4 +- src/radcon/radcon_dwarf.h | 2 +- src/radcon/radcon_main.c | 2 - src/radcon/radcon_pdb.c | 28 +- src/radcon/radcon_pdb.h | 2 +- src/raddbg/raddbg_main.c | 2 - src/raddump/raddump_main.c | 2 - src/rdi_from_dwarf/rdi_from_dwarf.c | 2 +- src/rdi_from_dwarf/rdi_from_dwarf.h | 2 +- src/rdi_from_dwarf/rdi_from_dwarf_main.c | 6 +- src/rdi_from_pdb/rdi_from_pdb.c | 67 +- src/rdi_from_pdb/rdi_from_pdb_main.c | 2 - src/rdi_make/rdi_make_help.c | 1118 ---------------------- src/rdi_make/rdi_make_help.h | 346 ------- src/rdi_make/rdi_make_local.c | 1117 +++++++++++++++++++++ src/rdi_make/rdi_make_local.h | 361 ++++++- 17 files changed, 1528 insertions(+), 1543 deletions(-) delete mode 100644 src/rdi_make/rdi_make_help.c delete mode 100644 src/rdi_make/rdi_make_help.h diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index e7c6decf..9688340c 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -362,12 +362,12 @@ rc_run(Arena *arena, RC_Context *rc) Temp scratch = scratch_begin(&arena, 1); ProfBegin("Convert"); - RDIM_HelpState *help_state = rdim_help_init(); + RDIM_LocalState *local_state = rdim_local_init(); RDIM_BakeParams *convert2bake = 0; switch (rc->driver) { case RC_Driver_Null: break; - case RC_Driver_Dwarf: convert2bake = d2r_convert(scratch.arena, help_state, rc); break; - case RC_Driver_Pdb: convert2bake = p2r_convert(scratch.arena, help_state, rc); break; + case RC_Driver_Dwarf: convert2bake = d2r_convert(scratch.arena, local_state, rc); break; + case RC_Driver_Pdb: convert2bake = p2r_convert(scratch.arena, local_state, rc); break; } ProfEnd(); @@ -376,7 +376,7 @@ rc_run(Arena *arena, RC_Context *rc) } ProfBegin("Bake"); - RDIM_BakeResults bake2srlz = rdim_bake(help_state, convert2bake); + RDIM_BakeResults bake2srlz = rdim_bake(local_state, convert2bake); ProfEnd(); ProfBegin("Serialize Bake"); diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 8601cdac..b336e67b 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -787,7 +787,7 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D } internal RDIM_BakeParams * -d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) { Temp scratch = scratch_begin(&arena, 1); @@ -1799,7 +1799,7 @@ d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) } internal RDIM_BakeResults -d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { return rdim_bake(state, in_params); } diff --git a/src/radcon/radcon_dwarf.h b/src/radcon/radcon_dwarf.h index 688e90e8..b9a3912c 100644 --- a/src/radcon/radcon_dwarf.h +++ b/src/radcon/radcon_dwarf.h @@ -30,7 +30,7 @@ typedef struct D2R_CompUnitContribMap //////////////////////////////// -internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); +internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in); //////////////////////////////// diff --git a/src/radcon/radcon_main.c b/src/radcon/radcon_main.c index 584877f4..05f4ab99 100644 --- a/src/radcon/radcon_main.c +++ b/src/radcon/radcon_main.c @@ -29,7 +29,6 @@ #include "async/async.h" #include "path/path.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "linker/hash_table.h" #include "coff/coff.h" #include "coff/coff_parse.h" @@ -62,7 +61,6 @@ #include "async/async.c" #include "path/path.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "linker/hash_table.c" #include "coff/coff.c" #include "coff/coff_parse.c" diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index 226e4405..ca7cdf33 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -6,7 +6,7 @@ // // (search for != 0 instances, inserted to prevent prior crashes) -global RDIM_HelpState *g_p2r_help_state = 0; +global RDIM_LocalState *g_p2r_local_state = 0; //////////////////////////////// //~ rjf: Basic Helpers @@ -116,7 +116,7 @@ p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDI ASYNC_WORK_DEF(p2r_exe_hash_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_EXEHashIn *in = (P2R_EXEHashIn *)input; U64 *out = push_array(arena, U64, 1); ProfScope("hash exe") *out = rdi_hash(in->exe_data.str, in->exe_data.size); @@ -127,7 +127,7 @@ ASYNC_WORK_DEF(p2r_exe_hash_work) ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_TPIHashParseIn *in = (P2R_TPIHashParseIn *)input; void *out = 0; ProfScope("parse tpi hash") out = pdb_tpi_hash_from_data(arena, in->strtbl, in->tpi, in->hash_data, in->aux_data); @@ -138,7 +138,7 @@ ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_TPILeafParseIn *in = (P2R_TPILeafParseIn *)input; void *out = 0; ProfScope("parse tpi leaf") out = cv_leaf_from_data(arena, in->leaf_data, in->itype_first); @@ -149,7 +149,7 @@ ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_SymbolStreamParseIn *in = (P2R_SymbolStreamParseIn *)input; void *out = 0; ProfScope("parse symbol stream") out = cv_sym_from_data(arena, in->data, 4); @@ -160,7 +160,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) ASYNC_WORK_DEF(p2r_c13_stream_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_C13StreamParseIn *in = (P2R_C13StreamParseIn *)input; void *out = 0; ProfScope("parse c13 stream") out = cv_c13_parsed_from_data(arena, in->data, in->strtbl, in->coff_sections); @@ -171,7 +171,7 @@ ASYNC_WORK_DEF(p2r_c13_stream_parse_work) ASYNC_WORK_DEF(p2r_comp_unit_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_CompUnitParseIn *in = (P2R_CompUnitParseIn *)input; void *out = 0; ProfScope("parse comp units") out = pdb_comp_unit_array_from_data(arena, in->data); @@ -182,7 +182,7 @@ ASYNC_WORK_DEF(p2r_comp_unit_parse_work) ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_CompUnitContributionsParseIn *in = (P2R_CompUnitContributionsParseIn *)input; void *out = 0; ProfScope("parse comp unit contributions") out = pdb_comp_unit_contribution_array_from_data(arena, in->data, in->coff_sections); @@ -196,7 +196,7 @@ ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) ASYNC_WORK_DEF(p2r_units_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_UnitConvertIn *in = (P2R_UnitConvertIn *)input; P2R_UnitConvertOut *out = push_array(arena, P2R_UnitConvertOut, 1); @@ -555,7 +555,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) ASYNC_WORK_DEF(p2r_link_name_map_build_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)input; CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges; CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count; @@ -613,7 +613,7 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) ASYNC_WORK_DEF(p2r_udt_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; #define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); @@ -1250,7 +1250,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; #define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) @@ -2125,11 +2125,11 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) //~ rjf: Top-Level Conversion Entry Point internal RDIM_BakeParams * -p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) { Temp scratch = scratch_begin(&arena, 1); - g_p2r_help_state = help_state; + g_p2r_local_state = local_state; ////////////////////////////////////////////////////////////// //- rjf: parse MSF structure diff --git a/src/radcon/radcon_pdb.h b/src/radcon/radcon_pdb.h index e4574a32..7f7aaf72 100644 --- a/src/radcon/radcon_pdb.h +++ b/src/radcon/radcon_pdb.h @@ -226,7 +226,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work); //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point -internal RDIM_BakeParams *p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); +internal RDIM_BakeParams *p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in); //////////////////////////////// diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 6e1f9ec3..9e6738ef 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -396,7 +396,6 @@ #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" #include "file_stream/file_stream.h" @@ -439,7 +438,6 @@ #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" #include "file_stream/file_stream.c" diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index c8225dba..4f62d683 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -28,7 +28,6 @@ #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "path/path.h" #include "linker/hash_table.h" #include "coff/coff.h" @@ -66,7 +65,6 @@ #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "path/path.c" #include "linker/hash_table.c" #include "coff/coff.c" diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index 3d4dcba8..91a5b73b 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -1838,7 +1838,7 @@ d2r_convert(Arena *arena, D2R_User2Convert *in) } internal RDIM_BakeResults -d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { return rdim_bake(state, in_params); } diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.h b/src/rdi_from_dwarf/rdi_from_dwarf.h index 63d27b32..4f59fb27 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.h +++ b/src/rdi_from_dwarf/rdi_from_dwarf.h @@ -56,7 +56,7 @@ internal D2R_User2Convert * d2r_user2convert_from_cmdln(Arena *arena, CmdLine *c // Top-Level Conversion Entry Point internal RDIM_BakeParams * d2r_convert (Arena *arena, D2R_User2Convert *in); -internal RDIM_BakeResults d2r_bake (RDIM_HelpState *state, RDIM_BakeParams *in); +internal RDIM_BakeResults d2r_bake (RDIM_LocalState *state, RDIM_BakeParams *in); internal RDIM_SerializedSectionBundle d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in); //////////////////////////////// diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_main.c b/src/rdi_from_dwarf/rdi_from_dwarf_main.c index 07c2410f..a74e3b15 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf_main.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf_main.c @@ -25,7 +25,6 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "linker/path_ext/path.h" #include "linker/hash_table.h" #include "coff/coff.h" @@ -44,7 +43,6 @@ #include "coff/coff_parse.c" #include "pe/pe.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "linker/rdi/rdi_coff.c" #include "linker/path_ext/path.c" #include "linker/hash_table.c" @@ -89,14 +87,14 @@ entry_point(CmdLine *cmdline) os_abort(0); } - RDIM_HelpState *rdim_help_state = rdim_help_init(); + RDIM_LocalState *rdim_local_state = rdim_local_init(); ProfBegin("convert"); RDIM_BakeParams *convert2bake = d2r_convert(arena, user2convert); ProfEnd(); ProfBegin("bake"); - RDIM_BakeResults bake2srlz = d2r_bake(rdim_help_state, convert2bake); + RDIM_BakeResults bake2srlz = d2r_bake(rdim_local_state, convert2bake); ProfEnd(); ProfBegin("serialize bake"); diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 0b8e911a..e84bb0eb 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -787,11 +787,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } // rjf: build line table, fill with parsed binary annotations + if(inlinee_lines_parsed != 0) { // rjf: grab checksums sub-section CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; - + // rjf: gathered lines typedef struct LineChunk LineChunk; struct LineChunk @@ -809,12 +810,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) U32 last_file_off = max_U32; U32 curr_file_off = max_U32; RDIM_LineTable* line_table = 0; - + CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) { last_file_off = curr_file_off; @@ -828,7 +829,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) if((last_file_off != max_U32 && last_file_off != curr_file_off)) { String8 seq_file_name = {0}; - + if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off); @@ -900,7 +901,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) first_line_chunk = last_line_chunk = 0; total_line_chunk_line_count = 0; } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) { LineChunk *chunk = last_line_chunk; @@ -918,7 +919,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) chunk->count += 1; total_line_chunk_line_count += 1; } - + if(step.flags == 0) { break; @@ -2435,14 +2436,14 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) { // rjf: build new range & add to scope RDIM_Rng1U64 voff_range = { step.range.min, step.range.max }; rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) { if(scope->voff_ranges.last != 0) @@ -2450,7 +2451,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) scope->voff_ranges.last->v.max = step.range.max; } } - + if(step.flags == 0) { break; @@ -2523,7 +2524,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) named_streams = pdb_named_stream_table_from_info(arena, info); MemoryCopyStruct(&auth_guid, &info->auth_guid); scratch_end(scratch); - + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); os_abort(1); @@ -2887,13 +2888,13 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); - + ////////////////////////// //- build basic type // { RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); @@ -2903,7 +2904,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); - + struct { char * name; @@ -2958,7 +2959,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } }; - + for(U64 i = 0; i < ArrayCount(table); i += 1) { U64 builtin_size; @@ -2970,14 +2971,14 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); } - + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); builtin->kind = table[i].kind_rdi; builtin->name = str8_cstring(table[i].name); builtin->byte_size = builtin_size; - + itype_type_ptrs[table[i].kind_cv] = builtin; - + if(table[i].make_pointer_near) { CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; @@ -2985,7 +2986,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_near->kind = RDI_TypeKind_Ptr; ptr_near->byte_size = 2; ptr_near->direct_type = builtin; - + itype_type_ptrs[near_ptr_itype] = ptr_near; } if(table[i].make_pointer_32) @@ -2995,7 +2996,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_32->kind = RDI_TypeKind_Ptr; ptr_32->byte_size = 4; ptr_32->direct_type = builtin; - + itype_type_ptrs[ptr_32_itype] = ptr_32; } if(table[i].make_pointer_64) @@ -3005,12 +3006,12 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_64->kind = RDI_TypeKind_Ptr; ptr_64->byte_size = 8; ptr_64->direct_type = builtin; - + itype_type_ptrs[ptr_64_itype] = ptr_64; } } } - + ////////////////////////// //- rjf: build non-basic type // @@ -3020,7 +3021,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; CV_LeafKind kind = range->hdr.kind; U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - + if(range->off+range->hdr.size <= tpi_leaf->data.size && range->off+2+header_struct_size <= tpi_leaf->data.size && range->hdr.size >= 2) @@ -3277,7 +3278,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3285,7 +3286,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) U8 *unique_name_ptr = name_ptr + name.size + 1; dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); } - + dst_type->name = name; dst_type->byte_size = safe_cast_u32(size_u64); }break; @@ -3317,7 +3318,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3353,7 +3354,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3388,7 +3389,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = direct_type ? direct_type->byte_size : 0; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3571,13 +3572,13 @@ p2r_init(void) internal P2R_Bake2Serialize * p2r_bake(Arena *arena, P2R_Convert2Bake *in) { - RDIM_HelpState help_state = {0}; - help_state.arena = p2r_state->arena; - help_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; - help_state.work_thread_arenas = p2r_state->work_thread_arenas; - + RDIM_LocalState local_state = {0}; + local_state.arena = p2r_state->arena; + local_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; + local_state.work_thread_arenas = p2r_state->work_thread_arenas; + P2R_Bake2Serialize *result = push_array(arena, P2R_Bake2Serialize, 1); - result->bake_results = rdim_bake(&help_state, &in->bake_params); + result->bake_results = rdim_bake(&local_state, &in->bake_params); return result; } diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index d2fc8707..6ab7a29b 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -24,7 +24,6 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "coff/coff.h" #include "coff/coff_parse.h" #include "codeview/codeview.h" @@ -41,7 +40,6 @@ #include "os/os_inc.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "coff/coff.c" #include "coff/coff_parse.c" #include "codeview/codeview.c" diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c deleted file mode 100644 index 93576760..00000000 --- a/src/rdi_make/rdi_make_help.c +++ /dev/null @@ -1,1118 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// - -internal RDIM_DataModel -rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) -{ - RDIM_DataModel data_model = RDIM_DataModel_Null; - switch (os) { - case OperatingSystem_Null: break; - case OperatingSystem_Windows: { - switch (arch) { - case RDI_Arch_X86: - case RDI_Arch_X64: - data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Linux: { - switch (arch) { - case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Mac: { - switch (arch) { - case RDI_Arch_X86: NotImplemented; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; - } - } break; - default: InvalidPath; - } - return data_model; -} - -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: bake string map building - -#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) - -ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_units_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_types_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake type strings") - { - for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_udts_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake udt strings") - { - for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake symbol strings") - { - for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeInlineSiteStringsIn *in = input; - rdim_make_string_map_if_needed(); - ProfScope("bake inline site strings") - { - for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake scope strings") - { - for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_line_tables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; - RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); - ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); - ProfEnd(); - return out; -} - -#undef rdim_make_string_map_if_needed - -//- rjf: bake string map joining - -ASYNC_WORK_DEF(rdim_bake_string_map_join_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; - ProfScope("join bake string maps") - { - for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) - { - for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) - { - B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); - B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); - if(src_slots_good && dst_slot_is_zero) - { - in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; - } - else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) - { - rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: bake string map sorting - -ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; - ProfScope("sort bake string chunk list map range") - { - for(U64 slot_idx = in->slot_idx; - slot_idx < in->slot_idx+in->slot_count; - slot_idx += 1) - { - if(in->src_map->slots[slot_idx] != 0) - { - if(in->src_map->slots[slot_idx]->total_count > 1) - { - in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); - *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); - } - else - { - in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: pass 1: interner/deduper map builds - -ASYNC_WORK_DEF(rdim_build_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; - RDIM_BakeNameMap *name_map = 0; - ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); - ProfEnd(); - return name_map; -} - -//- rjf: pass 2: string-map-dependent debug info stream builds - -ASYNC_WORK_DEF(rdim_bake_units_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; - RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); - ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; - RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); - ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_src_files_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; - RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); - ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_udts_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; - RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); - ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_variables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; - RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); - ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; - RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); - ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_thread_variables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; - RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); - ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_procedures_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; - RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); - ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scopes_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; - RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); - ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; - RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); - ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_inline_sites_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; - RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); - ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_file_paths_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; - RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); - ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; - RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); - ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); - ProfEnd(); - return out; -} - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds - -ASYNC_WORK_DEF(rdim_bake_type_nodes_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; - RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); - ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; - RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); - ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_idx_runs_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; - RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); - ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); - ProfEnd(); - return out; -} - -internal U64 -rdim_help_hash(RDIM_String8 string) -{ - U64 hash = 5381; - U8 *ptr = string.str; - U8 *opl = string.str + string.size; - for (;ptr < opl; ++ptr) { - hash = ((hash << 5) + hash) + (*ptr); - } - return hash; -} - -internal void -rdim_help_resolve_incomplete_types(RDIM_TypeChunkList *types) -{ - ProfBeginFunction(); - - Temp scratch = scratch_begin(0,0); - - ProfBegin("Build Hash Table"); - RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; i += 1) - { - RDIM_Type *type = &chunk->v[i]; - if(RDI_TypeKind_FirstUserDefined <= type->kind && type->kind <= RDI_TypeKind_LastRecord) - { - RDIM_String8 name = type->link_name.size ? type->link_name : type->name; - RDI_U64 hash = rdim_help_hash(name); - - RDI_U64 best_slot = hash % types->total_count; - RDI_U64 slot = best_slot; - do - { - RDIM_Type *s = name_ht[slot]; - if(s == 0) - { - break; - } - - if(s->link_name.size) - { - if(str8_match(s->link_name, name, 0)) - { - break; - } - } - else if(s->name.size) - { - if(str8_match(s->name, type->name, 0)) - { - break; - } - } - - slot = (slot + 1) % types->total_count; - } while (slot != best_slot); - - if(name_ht[slot] == 0) - { - name_ht[slot] = type; - } - } - } - } - ProfEnd(); - - ProfBegin("Make Fwd Map"); - RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; i += 1) - { - RDIM_Type *type = &chunk->v[i]; - - if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) - { - RDIM_String8 name = type->link_name.size ? type->link_name : type->name; - RDI_U64 hash = rdim_help_hash(name); - RDI_U64 best_slot = hash % types->total_count; - RDI_U64 slot = best_slot; - - RDIM_Type *match = 0; - do - { - if(name_ht[slot] == 0) - { - break; - } - RDIM_Type *s = name_ht[slot]; - if(s->link_name.size) - { - if(str8_match(s->link_name, type->link_name, 0)) - { - match = s; - break; - } - } - else - { - if(str8_match(s->name, type->name, 0)) - { - match = s; - break; - } - } - } while(slot != best_slot); - - if(match) - { - type->kind = RDI_TypeKind_NULL; - - RDI_U64 type_idx = rdim_idx_from_type(type); - fwd_map[type_idx] = match; - } - } - } - } - ProfEnd(); - - ProfBegin("Resolve Types"); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; ++i) - { - RDIM_Type *t = &chunk->v[i]; - if(t->direct_type) - { - RDI_U64 direct_idx = rdim_idx_from_type(t->direct_type); - if(fwd_map[direct_idx]) - { - t->direct_type = fwd_map[direct_idx]; - } - } - if(t->param_types) - { - for(RDI_U64 param_idx = 0; param_idx < t->count; param_idx += 1) - { - RDI_U64 type_idx = rdim_idx_from_type(t->param_types[param_idx]); - if(fwd_map[type_idx]) - { - t->param_types[param_idx] = fwd_map[type_idx]; - } - } - } - } - } - ProfEnd(); - - scratch_end(scratch); - ProfEnd(); -} - -internal RDIM_HelpState * -rdim_help_init(void) -{ - Arena *arena = arena_alloc(); - RDIM_HelpState *state = push_array(arena, RDIM_HelpState, 1); - state->arena = arena; - state->work_thread_arenas_count = async_thread_count(); - state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); - for EachIndex(idx, state->work_thread_arenas_count) - { - state->work_thread_arenas[idx] = arena_alloc(); - } - return state; -} - -internal RDIM_BakeResults -rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) -{ - Temp scratch = scratch_begin(0,0); - RDIM_BakeResults out = {0}; - - rdim_help_state = state; - - //////////////////////////////// - // resolve incomplete types - - rdim_help_resolve_incomplete_types(&in_params->types); - - //////////////////////////////// - // compute type indices - - RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); - - ////////////////////////////// - //- rjf: kick off line tables baking - // - ASYNC_Task *bake_line_tables_task = 0; - { - RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); - in->line_tables = &in_params->line_tables; - bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); - } - - ////////////////////////////// - //- rjf: build interned path tree - // - RDIM_BakePathTree *path_tree = 0; - ProfScope("build interned path tree") - { - path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); - } - - ////////////////////////////// - //- rjf: kick off string map building tasks - // - RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + - in_params->procedures.total_count*1 + - in_params->global_variables.total_count*1 + - in_params->thread_variables.total_count*1 + - in_params->types.total_count/2)}; - RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); - ASYNC_TaskList bake_string_map_build_tasks = {0}; - { - // rjf: src files - ProfScope("kick off src files string map build task") - { - RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->src_files; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); - } - - // rjf: units - ProfScope("kick off units string map build task") - { - RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->units; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); - } - - // rjf: types - ProfScope("kick off types string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; - RDIM_TypeChunkNode *chunk = in_params->types.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); - } - } - - // rjf: UDTs - ProfScope("kick off udts string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; - RDIM_UDTChunkNode *chunk = in_params->udts.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); - } - } - - // rjf: symbols - ProfScope("kick off symbols string map build tasks") - { - RDIM_SymbolChunkList *symbol_lists[] = - { - &in_params->global_variables, - &in_params->thread_variables, - &in_params->procedures, - }; - for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) - { - U64 items_per_task = 4096; - U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; - RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); - } - } - } - - ProfScope("kick off inline site string map build task") - { - U64 items_per_task = 4096; - U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); - RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); - } - } - - // rjf: scope chunks - ProfScope("kick off scope chunks string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; - RDIM_ScopeChunkNode *chunk = in_params->scopes.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); - } - } - } - - ////////////////////////////// - //- rjf: kick off name map building tasks - // - RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; - ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - build_bake_name_map_in[k].k = k; - build_bake_name_map_in[k].type_indices = type_indices; - build_bake_name_map_in[k].params = in_params; - build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); - } - - ////////////////////////////// - //- rjf: join string map building tasks - // - ProfScope("join string map building tasks") - { - for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - - ////////////////////////////// - //- rjf: produce joined string map - // - RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); - ProfScope("produce joined string map") - { - U64 slots_per_task = 16384; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); - - // rjf: kickoff tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); - in->top = &bake_string_map_topology; - in->src_maps = bake_string_maps__in_progress; - in->src_maps_count = async_thread_count(); - in->dst_map = unsorted_bake_string_map; - in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); - in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); - tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); - } - - // rjf: join tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - async_task_join(tasks[task_idx]); - } - - // rjf: insert small top-level stuff - rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); - } - - ////////////////////////////// - //- rjf: kick off string map sorting tasks - // - ASYNC_TaskList sort_bake_string_map_tasks = {0}; - RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); - { - U64 slots_per_task = 4096; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); - { - in->top = &bake_string_map_topology; - in->src_map = unsorted_bake_string_map; - in->dst_map = sorted_bake_string_map__in_progress; - in->slot_idx = task_idx*slots_per_task; - in->slot_count = slots_per_task; - if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) - { - in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; - } - } - async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); - } - } - - ////////////////////////////// - //- rjf: join string map sorting tasks - // - ProfScope("join string map sorting tasks") - { - for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; - - ////////////////////////////// - //- rjf: build finalized string map - // - ProfBegin("build finalized string map base indices"); - RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); - ProfEnd(); - ProfBegin("build finalized string map"); - RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); - ProfEnd(); - - ////////////////////////////// - //- rjf: kick off pass 2 tasks - // - RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; - ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); - RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; - ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); - RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; - ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); - RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; - ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); - RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; - ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); - RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; - ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); - RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; - ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); - RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; - ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); - RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; - ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); - - RDIM_String8List location_blocks = {0}; - RDIM_String8List location_data_blobs = {0}; - - // reserve null location block for opl - rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); - - // TODO: export location instead of VOFF - RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; - ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); - ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - - // TODO: export location instead of VOFF - RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; - ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); - ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - - RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; - ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); - ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - - RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; - ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); - ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - - ////////////////////////////// - //- rjf: join name map building tasks - // - RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; - ProfScope("join name map building tasks") - { - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); - } - } - - ////////////////////////////// - //- rjf: build interned idx run map - // - RDIM_BakeIdxRunMap *idx_runs = 0; - ProfScope("build interned idx run map") - { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); - } - - ////////////////////////////// - //- rjf: do small top-level bakes - // - ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); - - ////////////////////////////// - //- rjf: kick off pass 3 tasks - // - RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; - ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); - ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - if(name_maps[k] == 0 || name_maps[k]->name_count == 0) - { - continue; - } - RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); - in->strings = &bake_strings; - in->idx_runs = idx_runs; - in->map = name_maps[k]; - in->kind = k; - bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); - } - } - RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; - ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); - - ////////////////////////////// - //- rjf: join remaining completed bakes - // - ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); - ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); - ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); - ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); - ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); - ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); - ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); - ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); - ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); - ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); - ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); - ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); - - ////////////////////////////// - //- rjf: join individual name map bakes - // - RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; - ProfScope("name maps") - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); - if(bake != 0) - { - name_map_bakes[k] = *bake; - } - } - } - - ////////////////////////////// - //- rjf: join all individual name map bakes - // - ProfScope("join all name map bakes into final name map bake") - { - out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); - } - - - //////////////////////////////// - - out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); - out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); - - rdim_help_state = 0; - - scratch_end(scratch); - return out; -} - -internal RDIM_SerializedSectionBundle -rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) -{ - RDIM_SerializedSectionBundle out = {0}; - - //- rjf: set up compression context - rr_lzb_simple_context ctx = {0}; - ctx.m_tableSizeBits = 14; - ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; - RDIM_SerializedSection *dst = &out.sections[k]; - MemoryCopyStruct(dst, src); - - // rjf: determine if this section should be compressed - B32 should_compress = 1; - - // rjf: compress if needed - if(should_compress) - { - MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); - dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); - dst->unpacked_size = src->encoded_size; - dst->encoding = RDI_SectionEncoding_LZB; - } - } - - return out; -} diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h deleted file mode 100644 index d8b28160..00000000 --- a/src/rdi_make/rdi_make_help.h +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDIM_MAKE_HELP -#define RDIM_MAKE_HELP - -//- rjf: line table baking task types - -typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; -struct RDIM_BakeLineTablesIn -{ - RDIM_LineTableChunkList *line_tables; -}; - -//- rjf: string map baking task types - -typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; -struct RDIM_BakeSrcFilesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_SrcFileChunkList *list; -}; - -typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; -struct RDIM_BakeUnitsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_UnitChunkList *list; -}; - -typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; -struct RDIM_BakeUDTsStringsInNode -{ - RDIM_BakeUDTsStringsInNode *next; - RDIM_UDT *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; -struct RDIM_BakeTypesStringsInNode -{ - RDIM_BakeTypesStringsInNode *next; - RDIM_Type *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; -struct RDIM_BakeTypesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeTypesStringsInNode *first; - RDIM_BakeTypesStringsInNode *last; -}; - -typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; -struct RDIM_BakeUDTsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeUDTsStringsInNode *first; - RDIM_BakeUDTsStringsInNode *last; -}; - -typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; -struct RDIM_BakeSymbolsStringsInNode -{ - RDIM_BakeSymbolsStringsInNode *next; - RDIM_Symbol *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; -struct RDIM_BakeSymbolsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeSymbolsStringsInNode *first; - RDIM_BakeSymbolsStringsInNode *last; -}; - -typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; -struct RDIM_BakeInlineSiteStringsInNode -{ - RDIM_BakeInlineSiteStringsInNode *next; - RDIM_InlineSite *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; -struct RDIM_BakeInlineSiteStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeInlineSiteStringsInNode *first; - RDIM_BakeInlineSiteStringsInNode *last; -}; - -typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; -struct RDIM_BakeScopesStringsInNode -{ - RDIM_BakeScopesStringsInNode *next; - RDIM_Scope *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; -struct RDIM_BakeScopesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeScopesStringsInNode *first; - RDIM_BakeScopesStringsInNode *last; -}; - -//- rjf: OLD string map baking types - -typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; -struct RDIM_BuildBakeStringMapIn -{ - RDIM_BakePathTree *path_tree; - RDIM_BakeParams *params; -}; - -typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; -struct RDIM_BuildBakeNameMapIn -{ - RDI_NameMapKind k; - RDI_U64 *type_indices; - RDIM_BakeParams *params; -}; - -//- rjf: string map joining task types - -typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; -struct RDIM_JoinBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **src_maps; - U64 src_maps_count; - RDIM_BakeStringMapLoose *dst_map; - Rng1U64 slot_idx_range; -}; - -//- rjf: string map sorting task types - -typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; -struct RDIM_SortBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose *src_map; - RDIM_BakeStringMapLoose *dst_map; - U64 slot_idx; - U64 slot_count; -}; - -//- rjf: debug info baking task types - -typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; -struct RDIM_BakeUnitsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_UnitChunkList *units; -}; - -typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; -struct RDIM_BakeUnitVMapIn -{ - RDIM_UnitChunkList *units; -}; - -typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; -struct RDIM_BakeSrcFilesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_SrcFileChunkList *src_files; -}; - -typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; -struct RDIM_BakeUDTsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_UDTChunkList *udts; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; -struct RDIM_BakeGlobalVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *global_variables; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; -struct RDIM_BakeGlobalVMapIn -{ - RDIM_SymbolChunkList *global_variables; -}; - -typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; -struct RDIM_BakeThreadVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *thread_variables; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; -struct RDIM_BakeProceduresIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *procedures; - RDI_U64 *type_indices; - RDIM_String8List *location_blocks; - RDIM_String8List *location_data_blobs; -}; - -typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; -struct RDIM_BakeScopesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_ScopeChunkList *scopes; - RDI_U64 *type_indices; - RDIM_String8List *location_blocks; - RDIM_String8List *location_data_blobs; -}; - -typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; -struct RDIM_BakeScopeVMapIn -{ - RDIM_ScopeChunkList *scopes; -}; - -typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; -struct RDIM_BakeInlineSitesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_InlineSiteChunkList *inline_sites; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; -struct RDIM_BakeFilePathsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; -}; - -typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; -struct RDIM_BakeStringsIn -{ - RDIM_BakeStringMapTight *strings; -}; - -typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; -struct RDIM_BakeTypeNodesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_TypeChunkList *types; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; -struct RDIM_BakeNameMapIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_BakeNameMap *map; - RDI_NameMapKind kind; -}; - -typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; -struct RDIM_BakeIdxRunsIn -{ - RDIM_BakeIdxRunMap *idx_runs; -}; - -//////////////////////////////// - -internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); - -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: unsorted bake string map building -ASYNC_WORK_DEF(p2r_bake_src_files_strings_work); -ASYNC_WORK_DEF(p2r_bake_units_strings_work); -ASYNC_WORK_DEF(p2r_bake_types_strings_work); -ASYNC_WORK_DEF(p2r_bake_udts_strings_work); -ASYNC_WORK_DEF(p2r_bake_symbols_strings_work); -ASYNC_WORK_DEF(p2r_bake_scopes_strings_work); -ASYNC_WORK_DEF(p2r_bake_line_tables_work); - -//- rjf: bake string map joining -ASYNC_WORK_DEF(p2r_bake_string_map_join_work); - -//- rjf: bake string map sorting -ASYNC_WORK_DEF(p2r_bake_string_map_sort_work); - -//- rjf: pass 1: interner/deduper map builds -ASYNC_WORK_DEF(p2r_build_bake_name_map_work); - -//- rjf: pass 2: string-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_units_work); -ASYNC_WORK_DEF(p2r_bake_unit_vmap_work); -ASYNC_WORK_DEF(p2r_bake_src_files_work); -ASYNC_WORK_DEF(p2r_bake_udts_work); -ASYNC_WORK_DEF(p2r_bake_global_variables_work); -ASYNC_WORK_DEF(p2r_bake_global_vmap_work); -ASYNC_WORK_DEF(p2r_bake_thread_variables_work); -ASYNC_WORK_DEF(p2r_bake_procedures_work); -ASYNC_WORK_DEF(p2r_bake_scopes_work); -ASYNC_WORK_DEF(p2r_bake_scope_vmap_work); -ASYNC_WORK_DEF(p2r_bake_file_paths_work); -ASYNC_WORK_DEF(p2r_bake_strings_work); - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_type_nodes_work); -ASYNC_WORK_DEF(p2r_bake_name_map_work); -ASYNC_WORK_DEF(p2r_bake_idx_runs_work); - -typedef struct RDIM_HelpState RDIM_HelpState; -struct RDIM_HelpState -{ - Arena *arena; - U64 work_thread_arenas_count; - Arena **work_thread_arenas; -}; - -//////////////////////////////// - -global RDIM_HelpState *rdim_help_state = 0; - -//////////////////////////////// - -internal RDIM_HelpState * rdim_help_init(void); -internal RDIM_BakeResults rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in); -internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); - -#endif // RDIM_MAKE_HELP diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index c1b5436c..79aedf13 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -2,3 +2,1120 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) #include "lib_rdi_make/rdi_make.c" + +//////////////////////////////// + +internal RDIM_DataModel +rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) +{ + RDIM_DataModel data_model = RDIM_DataModel_Null; + switch (os) { + case OperatingSystem_Null: break; + case OperatingSystem_Windows: { + switch (arch) { + case RDI_Arch_X86: + case RDI_Arch_X64: + data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Linux: { + switch (arch) { + case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Mac: { + switch (arch) { + case RDI_Arch_X86: NotImplemented; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; + } + } break; + default: InvalidPath; + } + return data_model; +} + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: bake string map building + +#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) + +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_units_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_types_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake type strings") + { + for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_udts_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake udt strings") + { + for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake symbol strings") + { + for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSiteStringsIn *in = input; + rdim_make_string_map_if_needed(); + ProfScope("bake inline site strings") + { + for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake scope strings") + { + for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_line_tables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; + RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); + ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); + return out; +} + +#undef rdim_make_string_map_if_needed + +//- rjf: bake string map joining + +ASYNC_WORK_DEF(rdim_bake_string_map_join_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; + ProfScope("join bake string maps") + { + for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) + { + for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) + { + B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); + B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); + if(src_slots_good && dst_slot_is_zero) + { + in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; + } + else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) + { + rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: bake string map sorting + +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; + ProfScope("sort bake string chunk list map range") + { + for(U64 slot_idx = in->slot_idx; + slot_idx < in->slot_idx+in->slot_count; + slot_idx += 1) + { + if(in->src_map->slots[slot_idx] != 0) + { + if(in->src_map->slots[slot_idx]->total_count > 1) + { + in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); + *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); + } + else + { + in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: pass 1: interner/deduper map builds + +ASYNC_WORK_DEF(rdim_build_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; + RDIM_BakeNameMap *name_map = 0; + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); + ProfEnd(); + return name_map; +} + +//- rjf: pass 2: string-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_units_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; + RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); + ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; + RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); + ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_src_files_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; + RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); + ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_udts_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; + RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; + RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; + RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); + ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_thread_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; + RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_procedures_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; + RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; + RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; + RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); + ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_inline_sites_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; + RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_file_paths_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; + RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); + ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; + RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); + ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); + ProfEnd(); + return out; +} + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_type_nodes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; + RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; + RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); + ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_idx_runs_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; + RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); + ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); + ProfEnd(); + return out; +} + +internal U64 +rdim_local_hash(RDIM_String8 string) +{ + U64 hash = 5381; + U8 *ptr = string.str; + U8 *opl = string.str + string.size; + for (;ptr < opl; ++ptr) { + hash = ((hash << 5) + hash) + (*ptr); + } + return hash; +} + +internal void +rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) +{ + ProfBeginFunction(); + + Temp scratch = scratch_begin(0,0); + + ProfBegin("Build Hash Table"); + RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + if(RDI_TypeKind_FirstUserDefined <= type->kind && type->kind <= RDI_TypeKind_LastRecord) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_local_hash(name); + + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + do + { + RDIM_Type *s = name_ht[slot]; + if(s == 0) + { + break; + } + + if(s->link_name.size) + { + if(str8_match(s->link_name, name, 0)) + { + break; + } + } + else if(s->name.size) + { + if(str8_match(s->name, type->name, 0)) + { + break; + } + } + + slot = (slot + 1) % types->total_count; + } while (slot != best_slot); + + if(name_ht[slot] == 0) + { + name_ht[slot] = type; + } + } + } + } + ProfEnd(); + + ProfBegin("Make Fwd Map"); + RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + + if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_local_hash(name); + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + + RDIM_Type *match = 0; + do + { + if(name_ht[slot] == 0) + { + break; + } + RDIM_Type *s = name_ht[slot]; + if(s->link_name.size) + { + if(str8_match(s->link_name, type->link_name, 0)) + { + match = s; + break; + } + } + else + { + if(str8_match(s->name, type->name, 0)) + { + match = s; + break; + } + } + } while(slot != best_slot); + + if(match) + { + type->kind = RDI_TypeKind_NULL; + + RDI_U64 type_idx = rdim_idx_from_type(type); + fwd_map[type_idx] = match; + } + } + } + } + ProfEnd(); + + ProfBegin("Resolve Types"); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; ++i) + { + RDIM_Type *t = &chunk->v[i]; + if(t->direct_type) + { + RDI_U64 direct_idx = rdim_idx_from_type(t->direct_type); + if(fwd_map[direct_idx]) + { + t->direct_type = fwd_map[direct_idx]; + } + } + if(t->param_types) + { + for(RDI_U64 param_idx = 0; param_idx < t->count; param_idx += 1) + { + RDI_U64 type_idx = rdim_idx_from_type(t->param_types[param_idx]); + if(fwd_map[type_idx]) + { + t->param_types[param_idx] = fwd_map[type_idx]; + } + } + } + } + } + ProfEnd(); + + scratch_end(scratch); + ProfEnd(); +} + +internal RDIM_LocalState * +rdim_local_init(void) +{ + Arena *arena = arena_alloc(); + RDIM_LocalState *state = push_array(arena, RDIM_LocalState, 1); + state->arena = arena; + state->work_thread_arenas_count = async_thread_count(); + state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); + for EachIndex(idx, state->work_thread_arenas_count) + { + state->work_thread_arenas[idx] = arena_alloc(); + } + return state; +} + +internal RDIM_BakeResults +rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) +{ + Temp scratch = scratch_begin(0,0); + RDIM_BakeResults out = {0}; + + rdim_local_state = state; + + //////////////////////////////// + // resolve incomplete types + + rdim_local_resolve_incomplete_types(&in_params->types); + + //////////////////////////////// + // compute type indices + + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); + + ////////////////////////////// + //- rjf: kick off line tables baking + // + ASYNC_Task *bake_line_tables_task = 0; + { + RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); + in->line_tables = &in_params->line_tables; + bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); + } + + ////////////////////////////// + //- rjf: build interned path tree + // + RDIM_BakePathTree *path_tree = 0; + ProfScope("build interned path tree") + { + path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + } + + ////////////////////////////// + //- rjf: kick off string map building tasks + // + RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + + in_params->procedures.total_count*1 + + in_params->global_variables.total_count*1 + + in_params->thread_variables.total_count*1 + + in_params->types.total_count/2)}; + RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); + ASYNC_TaskList bake_string_map_build_tasks = {0}; + { + // rjf: src files + ProfScope("kick off src files string map build task") + { + RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->src_files; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); + } + + // rjf: units + ProfScope("kick off units string map build task") + { + RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->units; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); + } + + // rjf: types + ProfScope("kick off types string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; + RDIM_TypeChunkNode *chunk = in_params->types.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); + } + } + + // rjf: UDTs + ProfScope("kick off udts string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; + RDIM_UDTChunkNode *chunk = in_params->udts.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); + } + } + + // rjf: symbols + ProfScope("kick off symbols string map build tasks") + { + RDIM_SymbolChunkList *symbol_lists[] = + { + &in_params->global_variables, + &in_params->thread_variables, + &in_params->procedures, + }; + for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) + { + U64 items_per_task = 4096; + U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; + RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); + } + } + } + + ProfScope("kick off inline site string map build task") + { + U64 items_per_task = 4096; + U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); + RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); + } + } + + // rjf: scope chunks + ProfScope("kick off scope chunks string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; + RDIM_ScopeChunkNode *chunk = in_params->scopes.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); + } + } + } + + ////////////////////////////// + //- rjf: kick off name map building tasks + // + RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; + ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + build_bake_name_map_in[k].k = k; + build_bake_name_map_in[k].type_indices = type_indices; + build_bake_name_map_in[k].params = in_params; + build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); + } + + ////////////////////////////// + //- rjf: join string map building tasks + // + ProfScope("join string map building tasks") + { + for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + + ////////////////////////////// + //- rjf: produce joined string map + // + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + ProfScope("produce joined string map") + { + U64 slots_per_task = 16384; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); + + // rjf: kickoff tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); + in->top = &bake_string_map_topology; + in->src_maps = bake_string_maps__in_progress; + in->src_maps_count = async_thread_count(); + in->dst_map = unsorted_bake_string_map; + in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); + in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); + tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); + } + + // rjf: join tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + async_task_join(tasks[task_idx]); + } + + // rjf: insert small top-level stuff + rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + } + + ////////////////////////////// + //- rjf: kick off string map sorting tasks + // + ASYNC_TaskList sort_bake_string_map_tasks = {0}; + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + { + U64 slots_per_task = 4096; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); + { + in->top = &bake_string_map_topology; + in->src_map = unsorted_bake_string_map; + in->dst_map = sorted_bake_string_map__in_progress; + in->slot_idx = task_idx*slots_per_task; + in->slot_count = slots_per_task; + if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) + { + in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; + } + } + async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); + } + } + + ////////////////////////////// + //- rjf: join string map sorting tasks + // + ProfScope("join string map sorting tasks") + { + for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; + + ////////////////////////////// + //- rjf: build finalized string map + // + ProfBegin("build finalized string map base indices"); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + ProfEnd(); + ProfBegin("build finalized string map"); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + ProfEnd(); + + ////////////////////////////// + //- rjf: kick off pass 2 tasks + // + RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; + ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); + RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; + ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); + RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; + ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; + ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); + RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; + ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); + RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; + ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; + ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); + RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; + ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); + RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; + ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); + + RDIM_String8List location_blocks = {0}; + RDIM_String8List location_data_blobs = {0}; + + // reserve null location block for opl + rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); + + // TODO: export location instead of VOFF + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; + ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); + ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); + + // TODO: export location instead of VOFF + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; + ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); + ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); + + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); + ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); + + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); + ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); + + ////////////////////////////// + //- rjf: join name map building tasks + // + RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; + ProfScope("join name map building tasks") + { + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); + } + } + + ////////////////////////////// + //- rjf: build interned idx run map + // + RDIM_BakeIdxRunMap *idx_runs = 0; + ProfScope("build interned idx run map") + { + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); + } + + ////////////////////////////// + //- rjf: do small top-level bakes + // + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + + ////////////////////////////// + //- rjf: kick off pass 3 tasks + // + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; + ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); + ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + if(name_maps[k] == 0 || name_maps[k]->name_count == 0) + { + continue; + } + RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); + in->strings = &bake_strings; + in->idx_runs = idx_runs; + in->map = name_maps[k]; + in->kind = k; + bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); + } + } + RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; + ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); + + ////////////////////////////// + //- rjf: join remaining completed bakes + // + ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); + ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); + ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); + ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); + ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); + ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); + ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); + ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); + ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); + ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); + ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); + ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); + + ////////////////////////////// + //- rjf: join individual name map bakes + // + RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; + ProfScope("name maps") + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); + if(bake != 0) + { + name_map_bakes[k] = *bake; + } + } + } + + ////////////////////////////// + //- rjf: join all individual name map bakes + // + ProfScope("join all name map bakes into final name map bake") + { + out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + } + + + //////////////////////////////// + + out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); + + rdim_local_state = 0; + + scratch_end(scratch); + return out; +} + +internal RDIM_SerializedSectionBundle +rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) +{ + RDIM_SerializedSectionBundle out = {0}; + + //- rjf: set up compression context + rr_lzb_simple_context ctx = {0}; + ctx.m_tableSizeBits = 14; + ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; + RDIM_SerializedSection *dst = &out.sections[k]; + MemoryCopyStruct(dst, src); + + // rjf: determine if this section should be compressed + B32 should_compress = 1; + + // rjf: compress if needed + if(should_compress) + { + MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); + dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); + dst->unpacked_size = src->encoded_size; + dst->encoding = RDI_SectionEncoding_LZB; + } + } + + return out; +} + diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index 46a11b16..f8bffbfa 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef RDI_CONS_LOCAL_H -#define RDI_CONS_LOCAL_H +#ifndef RDI_MAKE_LOCAL_H +#define RDI_MAKE_LOCAL_H // rjf: base layer memory ops #define RDIM_MEMSET_OVERRIDE @@ -12,16 +12,16 @@ // rjf: base layer string overrides #define RDI_STRING8_OVERRIDE -#define RDIM_String8 String8 +#define RDIM_String8 String8 #define RDIM_String8_BaseMember str #define RDIM_String8_SizeMember size #define RDI_STRING8LIST_OVERRIDE -#define RDIM_String8Node String8Node -#define RDIM_String8Node_NextPtrMember next -#define RDIM_String8Node_StringMember string -#define RDIM_String8List String8List -#define RDIM_String8List_FirstMember first -#define RDIM_String8List_LastMember last +#define RDIM_String8Node String8Node +#define RDIM_String8Node_NextPtrMember next +#define RDIM_String8Node_StringMember string +#define RDIM_String8List String8List +#define RDIM_String8List_FirstMember first +#define RDIM_String8List_LastMember last #define RDIM_String8List_NodeCountMember node_count #define RDIM_String8List_TotalSizeMember total_size @@ -47,4 +47,345 @@ #include "lib_rdi_make/rdi_make.h" -#endif // RDI_CONS_LOCAL_H +//////////////////////////////// + +//- rjf: line table baking task types + +typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; +struct RDIM_BakeLineTablesIn +{ + RDIM_LineTableChunkList *line_tables; +}; + +//- rjf: string map baking task types + +typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; +struct RDIM_BakeSrcFilesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_SrcFileChunkList *list; +}; + +typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; +struct RDIM_BakeUnitsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_UnitChunkList *list; +}; + +typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; +struct RDIM_BakeUDTsStringsInNode +{ + RDIM_BakeUDTsStringsInNode *next; + RDIM_UDT *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; +struct RDIM_BakeTypesStringsInNode +{ + RDIM_BakeTypesStringsInNode *next; + RDIM_Type *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; +struct RDIM_BakeTypesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeTypesStringsInNode *first; + RDIM_BakeTypesStringsInNode *last; +}; + +typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; +struct RDIM_BakeUDTsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeUDTsStringsInNode *first; + RDIM_BakeUDTsStringsInNode *last; +}; + +typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; +struct RDIM_BakeSymbolsStringsInNode +{ + RDIM_BakeSymbolsStringsInNode *next; + RDIM_Symbol *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; +struct RDIM_BakeSymbolsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeSymbolsStringsInNode *first; + RDIM_BakeSymbolsStringsInNode *last; +}; + +typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; +struct RDIM_BakeInlineSiteStringsInNode +{ + RDIM_BakeInlineSiteStringsInNode *next; + RDIM_InlineSite *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; +struct RDIM_BakeInlineSiteStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeInlineSiteStringsInNode *first; + RDIM_BakeInlineSiteStringsInNode *last; +}; + +typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; +struct RDIM_BakeScopesStringsInNode +{ + RDIM_BakeScopesStringsInNode *next; + RDIM_Scope *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; +struct RDIM_BakeScopesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeScopesStringsInNode *first; + RDIM_BakeScopesStringsInNode *last; +}; + +//- rjf: OLD string map baking types + +typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; +struct RDIM_BuildBakeStringMapIn +{ + RDIM_BakePathTree *path_tree; + RDIM_BakeParams *params; +}; + +typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; +struct RDIM_BuildBakeNameMapIn +{ + RDI_NameMapKind k; + RDI_U64 *type_indices; + RDIM_BakeParams *params; +}; + +//- rjf: string map joining task types + +typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; +struct RDIM_JoinBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **src_maps; + U64 src_maps_count; + RDIM_BakeStringMapLoose *dst_map; + Rng1U64 slot_idx_range; +}; + +//- rjf: string map sorting task types + +typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; +struct RDIM_SortBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose *src_map; + RDIM_BakeStringMapLoose *dst_map; + U64 slot_idx; + U64 slot_count; +}; + +//- rjf: debug info baking task types + +typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; +struct RDIM_BakeUnitsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; +struct RDIM_BakeUnitVMapIn +{ + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; +struct RDIM_BakeSrcFilesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_SrcFileChunkList *src_files; +}; + +typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; +struct RDIM_BakeUDTsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_UDTChunkList *udts; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; +struct RDIM_BakeGlobalVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *global_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; +struct RDIM_BakeGlobalVMapIn +{ + RDIM_SymbolChunkList *global_variables; +}; + +typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; +struct RDIM_BakeThreadVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *thread_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; +struct RDIM_BakeProceduresIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *procedures; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; +struct RDIM_BakeScopesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_ScopeChunkList *scopes; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; +struct RDIM_BakeScopeVMapIn +{ + RDIM_ScopeChunkList *scopes; +}; + +typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; +struct RDIM_BakeInlineSitesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_InlineSiteChunkList *inline_sites; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; +struct RDIM_BakeFilePathsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; +}; + +typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; +struct RDIM_BakeStringsIn +{ + RDIM_BakeStringMapTight *strings; +}; + +typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; +struct RDIM_BakeTypeNodesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_TypeChunkList *types; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; +struct RDIM_BakeNameMapIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_BakeNameMap *map; + RDI_NameMapKind kind; +}; + +typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; +struct RDIM_BakeIdxRunsIn +{ + RDIM_BakeIdxRunMap *idx_runs; +}; + +//////////////////////////////// + +internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: unsorted bake string map building +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work); +ASYNC_WORK_DEF(rdim_bake_units_strings_work); +ASYNC_WORK_DEF(rdim_bake_types_strings_work); +ASYNC_WORK_DEF(rdim_bake_udts_strings_work); +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work); +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work); +ASYNC_WORK_DEF(rdim_bake_line_tables_work); + +//- rjf: bake string map joining +ASYNC_WORK_DEF(rdim_bake_string_map_join_work); + +//- rjf: bake string map sorting +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work); + +//- rjf: pass 1: interner/deduper map builds +ASYNC_WORK_DEF(rdim_build_bake_name_map_work); + +//- rjf: pass 2: string-map-dependent debug info stream builds +ASYNC_WORK_DEF(rdim_bake_units_work); +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work); +ASYNC_WORK_DEF(rdim_bake_src_files_work); +ASYNC_WORK_DEF(rdim_bake_udts_work); +ASYNC_WORK_DEF(rdim_bake_global_variables_work); +ASYNC_WORK_DEF(rdim_bake_global_vmap_work); +ASYNC_WORK_DEF(rdim_bake_thread_variables_work); +ASYNC_WORK_DEF(rdim_bake_procedures_work); +ASYNC_WORK_DEF(rdim_bake_scopes_work); +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work); +ASYNC_WORK_DEF(rdim_bake_file_paths_work); +ASYNC_WORK_DEF(rdim_bake_strings_work); + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds +ASYNC_WORK_DEF(rdim_bake_type_nodes_work); +ASYNC_WORK_DEF(rdim_bake_name_map_work); +ASYNC_WORK_DEF(rdim_bake_idx_runs_work); + +typedef struct RDIM_LocalState RDIM_LocalState; +struct RDIM_LocalState +{ + Arena *arena; + U64 work_thread_arenas_count; + Arena **work_thread_arenas; +}; + +//////////////////////////////// + +global RDIM_LocalState *rdim_local_state = 0; + +//////////////////////////////// + +internal RDIM_LocalState * rdim_local_init(void); +internal RDIM_BakeResults rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in); +internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); + +#endif // RDI_MAKE_LOCAL_H From 801b18a82dd59a55cf47234a3c1a0a6bf9971547 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 24 Mar 2025 11:23:25 -0700 Subject: [PATCH 261/755] bugfix machine conversion in PDB and improved inference of conversion drivers --- src/radcon/radcon.c | 109 ++++++++++++++++++++++++---------------- src/radcon/radcon_pdb.c | 2 +- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index 9688340c..ac6335dc 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -72,6 +72,22 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) is_elf_debug_present = 1; } + // + // Pick conversion driver + // + RC_Driver driver = RC_Driver_Null; + if (cmd_line_has_flag(cmdl, str8_lit("driver"))) { + String8 driver_name = cmd_line_string(cmdl, str8_lit("driver")); + if (str8_match(driver_name, str8_lit("dwarf"), StringMatchFlag_CaseInsensitive)) { + driver = RC_Driver_Dwarf; + } else if (str8_match(driver_name, str8_lit("pdb"), StringMatchFlag_CaseInsensitive)) { + driver = RC_Driver_Pdb; + } else { + fprintf(stderr, "error: unknown driver \"%.*s\"\n", str8_varg(driver_name)); + os_abort(1); + } + } + // // Load inputs // @@ -144,36 +160,30 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) os_abort(1); } - // - // Pick conversion driver - // - RC_Driver driver = RC_Driver_Null; - if (cmd_line_has_flag(cmdl, str8_lit("driver"))) { - String8 driver_name = cmd_line_string(cmdl, str8_lit("driver")); - if (str8_match(driver_name, str8_lit("dwarf"), StringMatchFlag_CaseInsensitive)) { - driver = RC_Driver_Dwarf; - } else if (str8_match(driver_name, str8_lit("pdb"), StringMatchFlag_CaseInsensitive)) { - driver = RC_Driver_Pdb; - } else { - fprintf(stderr, "error: unknown driver %.*s\n", str8_varg(driver_name)); - os_abort(1); - } + if (is_pe_present && (is_elf_present || is_elf_debug_present)) { + fprintf(stderr, "error: command line has too many image types specified.\n"); + os_abort(1); } + ImageType image = Image_Null; String8 image_name = {0}; String8 image_data = {0}; String8 debug_name = {0}; String8 debug_data = {0}; + // - // Input is PE/COFF + // Input has PE/COFF // B32 check_guid = 0; Guid pe_pdb_guid = {0}; if (is_pe_present) { - PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); + image = Image_CoffPe; + image_name = pe_name; + image_data = pe_data; + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); String8 raw_debug_dir = str8_substr(pe_data, pe.data_dir_franges[PE_DataDirectoryIndex_DEBUG]); PE_DebugInfoList debug_dir = pe_parse_debug_directory(scratch.arena, pe_data, raw_debug_dir); for (PE_DebugInfoNode *debug_n = debug_dir.first; debug_n != 0; debug_n = debug_n->next) { @@ -194,48 +204,28 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) } } - if (driver == RC_Driver_Dwarf || driver == RC_Driver_Null) { + if (driver == RC_Driver_Null || driver == RC_Driver_Dwarf) { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); String8 raw_sections = str8_substr(pe_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; if (dw_is_dwarf_present_coff_section_table(pe_data, pe.string_table_off, section_count, section_array)) { driver = RC_Driver_Dwarf; - image = Image_CoffPe; - image_name = pe_name; - image_data = pe_data; debug_name = pe_name; debug_data = pe_data; goto driver_found; - } else { - if (driver == RC_Driver_Dwarf) { - fprintf(stderr, "error: image doesn't have DWARF debug sections.\n"); - os_abort(1); - } + } else if (driver == RC_Driver_Dwarf) { + fprintf(stderr, "error: image doesn't have DWARF debug sections.\n"); + os_abort(1); } } } - - // - // Input is PDB - // - if (driver == RC_Driver_Null && is_pdb_present) { - if (is_pe_present) { - image = Image_CoffPe; - image_name = pe_name; - image_data = pe_data; - } - driver = RC_Driver_Pdb; - debug_name = pdb_name; - debug_data = pdb_data; - goto driver_found; - } - B32 elf_has_debug_link = 0; ELF_GnuDebugLink debug_link = {0}; if (is_elf_present || is_elf_debug_present) { if (driver != RC_Driver_Null && driver != RC_Driver_Dwarf) { - fprintf(stderr, "ELF inputs are only supported when using DWARF driver.\n"); + fprintf(stderr, "error: ELF inputs are only supported when using DWARF driver.\n"); os_abort(1); } @@ -304,6 +294,23 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) } } + // + // Input is PDB + // + if (is_pdb_present) { + if (driver == RC_Driver_Null || driver == RC_Driver_Pdb) { + driver = RC_Driver_Pdb; + debug_name = pdb_name; + debug_data = pdb_data; + goto driver_found; + } else if (driver == RC_Driver_Dwarf) { + fprintf(stderr, "error: unable to select DWARF conversion driver because convert doesn't support PDB as input format.\n"); + os_abort(1); + } else { + InvalidPath; + } + } + driver_found:; // @@ -342,6 +349,24 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) ctx.image_data = image_data; ctx.debug_name = debug_name; ctx.debug_data = debug_data; + ctx.flags = RC_Flag_Strings| + RC_Flag_IndexRuns| + RC_Flag_BinarySections| + RC_Flag_Units| + RC_Flag_Procedures| + RC_Flag_GlobalVariables| + RC_Flag_ThreadVariables| + RC_Flag_Scopes| + RC_Flag_Locals| + RC_Flag_Types| + RC_Flag_UDTs| + RC_Flag_LineInfo| + RC_Flag_GlobalVariableNameMap| + RC_Flag_ThreadVariableNameMap| + RC_Flag_ProcedureNameMap| + RC_Flag_TypeNameMap| + RC_Flag_LinkNameProcedureNameMap| + RC_Flag_NormalSourcePathNameMap; if (check_guid) { ctx.flags |= RC_Flag_CheckPdbGuid; ctx.guid = pe_pdb_guid; diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index ca7cdf33..4b395510 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -2355,7 +2355,7 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) ////////////////////////////////////////////////////////////// //- rjf: determine architecture // - RDI_Arch arch = cv2r_rdi_arch_from_cv_arch(dbi->machine_type); + RDI_Arch arch = c2r_rdi_arch_from_coff_machine(dbi->machine_type); U64 arch_addr_size = rdi_addr_size_from_arch(arch); ////////////////////////////////////////////////////////////// From 8551e8c3ecb6f71ead41e1d992afc315d2289112 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 24 Mar 2025 11:42:57 -0700 Subject: [PATCH 262/755] remove unused funcs --- src/radcon/radcon_dwarf.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index b336e67b..82f66097 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -582,11 +582,6 @@ d2r_transpile_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arc return loc; } -internal RDIM_LocationSet -d2r_convert_loclist(Arena *arena, RDIM_ScopeChunkList *scopes, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, DW_LocList loclist) -{ -} - internal RDIM_Location * d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, RDI_Arch arch, DW_Tag tag, DW_AttribKind kind) { @@ -1798,19 +1793,6 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) return bake_params; } -internal RDIM_BakeResults -d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) -{ - return rdim_bake(state, in_params); -} - -internal RDIM_SerializedSectionBundle -d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in) -{ - RDIM_SerializedSectionBundle result = {0}; - return result; -} - internal RDI_Language rdi_language_from_dw_language(DW_Language v) { From d137d928c92482016768bd8ec8ecdb89eae1bdd3 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 24 Mar 2025 13:03:09 -0700 Subject: [PATCH 263/755] added call site value opcode to RDI format --- src/lib_rdi_format/rdi_format.c | 3 +- src/lib_rdi_format/rdi_format.h | 6 +- src/radcon/radcon_dwarf.c | 18 ++++-- src/rdi_format/rdi_format.mdesk | 99 +++++++++++++++++---------------- 4 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index d2143de0..0427a302 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -92,7 +92,7 @@ RDI_U8 rdi_section_is_required_table[37] = 0, }; -RDI_U16 rdi_eval_op_ctrlbits_table[49] = +RDI_U16 rdi_eval_op_ctrlbits_table[50] = { RDI_EVAL_CTRLBITS(0, 0, 0), RDI_EVAL_CTRLBITS(0, 0, 0), @@ -142,6 +142,7 @@ RDI_EVAL_CTRLBITS(0, 1, 0), RDI_EVAL_CTRLBITS(1, 0, 0), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 1, 1), +RDI_EVAL_CTRLBITS(4, 0, 0), RDI_EVAL_CTRLBITS(0, 0, 0), }; diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index 5237ad55..d16d7924 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -488,7 +488,8 @@ RDI_EvalOp_Pop = 44, RDI_EvalOp_Insert = 45, RDI_EvalOp_ValueRead = 46, RDI_EvalOp_ByteSwap = 47, -RDI_EvalOp_COUNT = 48, +RDI_EvalOp_CallSiteValue = 48, +RDI_EvalOp_COUNT = 49, } RDI_EvalOpEnum; typedef RDI_U8 RDI_EvalTypeGroup; @@ -1066,6 +1067,7 @@ X(Pop)\ X(Insert)\ X(ValueRead)\ X(ByteSwap)\ +X(CallSiteValue)\ #define RDI_EvalTypeGroup_XList \ X(Other)\ @@ -1537,6 +1539,6 @@ RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConver extern RDI_U16 rdi_section_element_size_table[37]; extern RDI_U8 rdi_section_is_required_table[37]; -extern RDI_U16 rdi_eval_op_ctrlbits_table[49]; +extern RDI_U16 rdi_eval_op_ctrlbits_table[50]; #endif // RDI_FORMAT_H diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 82f66097..1703e184 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -166,9 +166,10 @@ d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input internal RDIM_EvalBytecode -d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr, B32 *is_addr_out) { RDIM_EvalBytecode bc = {0}; + *is_addr_out = 1; for (U64 cursor = 0; cursor < expr.size; ) { U8 op = 0; @@ -415,7 +416,13 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI String8 entry_value_expr = {0}; cursor += str8_deserial_read_block(expr, cursor, block_size, &entry_value_expr); - RDIM_EvalBytecode entry_value_bc = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, entry_value_expr); + B32 dummy = 0; + RDIM_EvalBytecode call_site_bc = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, entry_value_expr, &dummy); + + U32 encoded_size32 = safe_cast_u32(call_site_bc.encoded_size); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_CallSiteValue, encoded_size32); + + rdim_bytecode_concat_in_place(&bc, &call_site_bc); } break; case DW_ExprOp_Addrx: { @@ -575,9 +582,12 @@ d2r_transpile_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arc { RDIM_Location *loc = 0; if (expr.size) { + B32 is_addr = 0; + RDIM_EvalBytecode bytecode = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, expr, &is_addr); + loc = push_array(arena, RDIM_Location, 1); - loc->kind = RDI_LocationKind_AddrBytecodeStream; - loc->bytecode = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, expr); + loc->kind = is_addr ? RDI_LocationKind_AddrBytecodeStream : RDI_LocationKind_ValBytecodeStream; + loc->bytecode = bytecode; } return loc; } diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 51e48649..9816f254 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1245,55 +1245,56 @@ RDI_LocationRegMemberTable: @table(name value num_decodes num_pops num_pushes) RDI_EvalOpTable: { - {Stop 0 0 0 0} - {Noop 1 0 0 0} - {Cond 2 1 1 0} - {Skip 3 2 0 0} - {MemRead 4 1 1 1} - {RegRead 5 4 0 1} - {RegReadDyn 6 0 1 1} - {FrameOff 7 8 0 1} - {ModuleOff 8 4 0 1} - {TLSOff 9 4 0 1} - {ObjectOff 10 0 0 0} - {CFA 11 0 0 0} - {ConstU8 12 1 0 1} - {ConstU16 13 2 0 1} - {ConstU32 14 4 0 1} - {ConstU64 15 8 0 1} - {ConstU128 16 16 0 1} - {ConstString 17 1 0 1} - {Abs 18 1 1 1} - {Neg 19 1 1 1} - {Add 20 1 2 1} - {Sub 21 1 2 1} - {Mul 22 1 2 1} - {Div 23 1 2 1} - {Mod 24 1 2 1} - {LShift 25 1 2 1} - {RShift 26 1 2 1} - {BitAnd 27 1 2 1} - {BitOr 28 1 2 1} - {BitXor 29 1 2 1} - {BitNot 30 1 1 1} - {LogAnd 31 1 2 1} - {LogOr 32 1 2 1} - {LogNot 33 1 1 1} - {EqEq 34 1 2 1} - {NtEq 35 1 2 1} - {LsEq 36 1 2 1} - {GrEq 37 1 2 1} - {Less 38 1 2 1} - {Grtr 39 1 2 1} - {Trunc 40 1 1 1} - {TruncSigned 41 1 1 1} - {Convert 42 2 1 1} - {Pick 43 1 0 1} - {Pop 44 0 1 0} - {Insert 45 1 0 0} - {ValueRead 46 1 2 1} - {ByteSwap 47 1 1 1} - {COUNT 48 0 0 0} + {Stop 0 0 0 0} + {Noop 1 0 0 0} + {Cond 2 1 1 0} + {Skip 3 2 0 0} + {MemRead 4 1 1 1} + {RegRead 5 4 0 1} + {RegReadDyn 6 0 1 1} + {FrameOff 7 8 0 1} + {ModuleOff 8 4 0 1} + {TLSOff 9 4 0 1} + {ObjectOff 10 0 0 0} + {CFA 11 0 0 0} + {ConstU8 12 1 0 1} + {ConstU16 13 2 0 1} + {ConstU32 14 4 0 1} + {ConstU64 15 8 0 1} + {ConstU128 16 16 0 1} + {ConstString 17 1 0 1} + {Abs 18 1 1 1} + {Neg 19 1 1 1} + {Add 20 1 2 1} + {Sub 21 1 2 1} + {Mul 22 1 2 1} + {Div 23 1 2 1} + {Mod 24 1 2 1} + {LShift 25 1 2 1} + {RShift 26 1 2 1} + {BitAnd 27 1 2 1} + {BitOr 28 1 2 1} + {BitXor 29 1 2 1} + {BitNot 30 1 1 1} + {LogAnd 31 1 2 1} + {LogOr 32 1 2 1} + {LogNot 33 1 1 1} + {EqEq 34 1 2 1} + {NtEq 35 1 2 1} + {LsEq 36 1 2 1} + {GrEq 37 1 2 1} + {Less 38 1 2 1} + {Grtr 39 1 2 1} + {Trunc 40 1 1 1} + {TruncSigned 41 1 1 1} + {Convert 42 2 1 1} + {Pick 43 1 0 1} + {Pop 44 0 1 0} + {Insert 45 1 0 0} + {ValueRead 46 1 2 1} + {ByteSwap 47 1 1 1} + {CallSiteValue 48 4 0 0} + {COUNT 49 0 0 0} } // NOTE(rjf): "ck" -> "conversion kind, when converted to type group", used in square matrix form From 64b8f762cb718c8dd4b639779444f0b062e104ac Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 25 Mar 2025 12:52:13 -0700 Subject: [PATCH 264/755] fix bytecode list concat --- src/lib_rdi_make/rdi_make.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 484845cc..8e4ee557 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -1207,9 +1207,10 @@ rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *ri } else { - left_dst->last_op = right_destroyed->last_op; - left_dst->op_count += right_destroyed->op_count; - left_dst->encoded_size += right_destroyed->encoded_size; + left_dst->last_op->next = right_destroyed->first_op; + left_dst->last_op = right_destroyed->last_op; + left_dst->op_count += right_destroyed->op_count; + left_dst->encoded_size += right_destroyed->encoded_size; } rdim_memzero_struct(right_destroyed); } From 63086b802c9215581d995d36f43c9dec5428a2a7 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 12:11:25 -0700 Subject: [PATCH 265/755] opcodes for encoding partial values --- src/lib_rdi_format/rdi_format.c | 4 +- src/lib_rdi_format/rdi_format.h | 8 ++- src/rdi_format/rdi_format.mdesk | 102 ++++++++++++++++---------------- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 0427a302..563e4b42 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -92,7 +92,7 @@ RDI_U8 rdi_section_is_required_table[37] = 0, }; -RDI_U16 rdi_eval_op_ctrlbits_table[50] = +RDI_U16 rdi_eval_op_ctrlbits_table[52] = { RDI_EVAL_CTRLBITS(0, 0, 0), RDI_EVAL_CTRLBITS(0, 0, 0), @@ -143,6 +143,8 @@ RDI_EVAL_CTRLBITS(1, 0, 0), RDI_EVAL_CTRLBITS(1, 2, 1), RDI_EVAL_CTRLBITS(1, 1, 1), RDI_EVAL_CTRLBITS(4, 0, 0), +RDI_EVAL_CTRLBITS(4, 0, 0), +RDI_EVAL_CTRLBITS(8, 0, 0), RDI_EVAL_CTRLBITS(0, 0, 0), }; diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index d16d7924..e985b125 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -489,7 +489,9 @@ RDI_EvalOp_Insert = 45, RDI_EvalOp_ValueRead = 46, RDI_EvalOp_ByteSwap = 47, RDI_EvalOp_CallSiteValue = 48, -RDI_EvalOp_COUNT = 49, +RDI_EvalOp_PartialValue = 49, +RDI_EvalOp_PartialValueBit = 50, +RDI_EvalOp_COUNT = 51, } RDI_EvalOpEnum; typedef RDI_U8 RDI_EvalTypeGroup; @@ -1068,6 +1070,8 @@ X(Insert)\ X(ValueRead)\ X(ByteSwap)\ X(CallSiteValue)\ +X(PartialValue)\ +X(PartialValueBit)\ #define RDI_EvalTypeGroup_XList \ X(Other)\ @@ -1539,6 +1543,6 @@ RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConver extern RDI_U16 rdi_section_element_size_table[37]; extern RDI_U8 rdi_section_is_required_table[37]; -extern RDI_U16 rdi_eval_op_ctrlbits_table[50]; +extern RDI_U16 rdi_eval_op_ctrlbits_table[52]; #endif // RDI_FORMAT_H diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 9816f254..4fadfabd 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1245,56 +1245,58 @@ RDI_LocationRegMemberTable: @table(name value num_decodes num_pops num_pushes) RDI_EvalOpTable: { - {Stop 0 0 0 0} - {Noop 1 0 0 0} - {Cond 2 1 1 0} - {Skip 3 2 0 0} - {MemRead 4 1 1 1} - {RegRead 5 4 0 1} - {RegReadDyn 6 0 1 1} - {FrameOff 7 8 0 1} - {ModuleOff 8 4 0 1} - {TLSOff 9 4 0 1} - {ObjectOff 10 0 0 0} - {CFA 11 0 0 0} - {ConstU8 12 1 0 1} - {ConstU16 13 2 0 1} - {ConstU32 14 4 0 1} - {ConstU64 15 8 0 1} - {ConstU128 16 16 0 1} - {ConstString 17 1 0 1} - {Abs 18 1 1 1} - {Neg 19 1 1 1} - {Add 20 1 2 1} - {Sub 21 1 2 1} - {Mul 22 1 2 1} - {Div 23 1 2 1} - {Mod 24 1 2 1} - {LShift 25 1 2 1} - {RShift 26 1 2 1} - {BitAnd 27 1 2 1} - {BitOr 28 1 2 1} - {BitXor 29 1 2 1} - {BitNot 30 1 1 1} - {LogAnd 31 1 2 1} - {LogOr 32 1 2 1} - {LogNot 33 1 1 1} - {EqEq 34 1 2 1} - {NtEq 35 1 2 1} - {LsEq 36 1 2 1} - {GrEq 37 1 2 1} - {Less 38 1 2 1} - {Grtr 39 1 2 1} - {Trunc 40 1 1 1} - {TruncSigned 41 1 1 1} - {Convert 42 2 1 1} - {Pick 43 1 0 1} - {Pop 44 0 1 0} - {Insert 45 1 0 0} - {ValueRead 46 1 2 1} - {ByteSwap 47 1 1 1} - {CallSiteValue 48 4 0 0} - {COUNT 49 0 0 0} + {Stop 0 0 0 0} + {Noop 1 0 0 0} + {Cond 2 1 1 0} + {Skip 3 2 0 0} + {MemRead 4 1 1 1} + {RegRead 5 4 0 1} + {RegReadDyn 6 0 1 1} + {FrameOff 7 8 0 1} + {ModuleOff 8 4 0 1} + {TLSOff 9 4 0 1} + {ObjectOff 10 0 0 0} + {CFA 11 0 0 0} + {ConstU8 12 1 0 1} + {ConstU16 13 2 0 1} + {ConstU32 14 4 0 1} + {ConstU64 15 8 0 1} + {ConstU128 16 16 0 1} + {ConstString 17 1 0 1} + {Abs 18 1 1 1} + {Neg 19 1 1 1} + {Add 20 1 2 1} + {Sub 21 1 2 1} + {Mul 22 1 2 1} + {Div 23 1 2 1} + {Mod 24 1 2 1} + {LShift 25 1 2 1} + {RShift 26 1 2 1} + {BitAnd 27 1 2 1} + {BitOr 28 1 2 1} + {BitXor 29 1 2 1} + {BitNot 30 1 1 1} + {LogAnd 31 1 2 1} + {LogOr 32 1 2 1} + {LogNot 33 1 1 1} + {EqEq 34 1 2 1} + {NtEq 35 1 2 1} + {LsEq 36 1 2 1} + {GrEq 37 1 2 1} + {Less 38 1 2 1} + {Grtr 39 1 2 1} + {Trunc 40 1 1 1} + {TruncSigned 41 1 1 1} + {Convert 42 2 1 1} + {Pick 43 1 0 1} + {Pop 44 0 1 0} + {Insert 45 1 0 0} + {ValueRead 46 1 2 1} + {ByteSwap 47 1 1 1} + {CallSiteValue 48 4 0 0} + {PartialValue 49 4 0 0} + {PartialValueBit 50 8 0 0} + {COUNT 51 0 0 0} } // NOTE(rjf): "ck" -> "conversion kind, when converted to type group", used in square matrix form From ff61ad4cf87d4fe9b912ffa159e3330331c25a68 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 12:13:06 -0700 Subject: [PATCH 266/755] improved formatting of bytecode locations, and added inline site name display next to inline site index --- src/raddump/raddump.c | 293 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 271 insertions(+), 22 deletions(-) diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index d369ff54..967ee7a6 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -725,6 +725,78 @@ rdi_string_from_reg_code(Arena *arena, RDI_Arch arch, U64 reg_code) return push_str8f(arena, "??? (%llu)", reg_code); } +internal String8 +rdi_string_from_eval_op(Arena *arena, RDI_EvalOp op) +{ + switch (op) { + case RDI_EvalOp_Stop: return str8_lit("Stop"); + case RDI_EvalOp_Noop: return str8_lit("Noop"); + case RDI_EvalOp_Cond: return str8_lit("Cond"); + case RDI_EvalOp_Skip: return str8_lit("Skip"); + case RDI_EvalOp_MemRead: return str8_lit("MemRead"); + case RDI_EvalOp_RegRead: return str8_lit("RegRead"); + case RDI_EvalOp_RegReadDyn: return str8_lit("RegReadDyn"); + case RDI_EvalOp_FrameOff: return str8_lit("FrameOff"); + case RDI_EvalOp_ModuleOff: return str8_lit("ModuleOff"); + case RDI_EvalOp_TLSOff: return str8_lit("TLSOff"); + case RDI_EvalOp_ObjectOff: return str8_lit("ObjectOff"); + case RDI_EvalOp_CFA: return str8_lit("CFA"); + case RDI_EvalOp_ConstU8: return str8_lit("ConstU8"); + case RDI_EvalOp_ConstU16: return str8_lit("ConstU16"); + case RDI_EvalOp_ConstU32: return str8_lit("ConstU32"); + case RDI_EvalOp_ConstU64: return str8_lit("ConstU64"); + case RDI_EvalOp_ConstU128: return str8_lit("ConstU128"); + case RDI_EvalOp_ConstString: return str8_lit("ConstString"); + case RDI_EvalOp_Abs: return str8_lit("Abs"); + case RDI_EvalOp_Neg: return str8_lit("Neg"); + case RDI_EvalOp_Add: return str8_lit("Add"); + case RDI_EvalOp_Sub: return str8_lit("Sub"); + case RDI_EvalOp_Mul: return str8_lit("Mul"); + case RDI_EvalOp_Div: return str8_lit("Div"); + case RDI_EvalOp_Mod: return str8_lit("Mod"); + case RDI_EvalOp_LShift: return str8_lit("LShift"); + case RDI_EvalOp_RShift: return str8_lit("RShift"); + case RDI_EvalOp_BitAnd: return str8_lit("BitAnd"); + case RDI_EvalOp_BitOr: return str8_lit("BitOr"); + case RDI_EvalOp_BitXor: return str8_lit("BitXor"); + case RDI_EvalOp_BitNot: return str8_lit("BitNot"); + case RDI_EvalOp_LogAnd: return str8_lit("LogAnd"); + case RDI_EvalOp_LogOr: return str8_lit("LogOr"); + case RDI_EvalOp_LogNot: return str8_lit("LogNot"); + case RDI_EvalOp_EqEq: return str8_lit("EqEq"); + case RDI_EvalOp_NtEq: return str8_lit("NtEq"); + case RDI_EvalOp_LsEq: return str8_lit("LsEq"); + case RDI_EvalOp_GrEq: return str8_lit("GrEq"); + case RDI_EvalOp_Less: return str8_lit("Less"); + case RDI_EvalOp_Grtr: return str8_lit("Grtr"); + case RDI_EvalOp_Trunc: return str8_lit("Trunc"); + case RDI_EvalOp_TruncSigned: return str8_lit("TruncSigned"); + case RDI_EvalOp_Convert: return str8_lit("Convert"); + case RDI_EvalOp_Pick: return str8_lit("Pick"); + case RDI_EvalOp_Pop: return str8_lit("Pop"); + case RDI_EvalOp_Insert: return str8_lit("Insert"); + case RDI_EvalOp_ValueRead: return str8_lit("ValueRead"); + case RDI_EvalOp_ByteSwap: return str8_lit("ByteSwap"); + case RDI_EvalOp_CallSiteValue: return str8_lit("CallSiteValue"); + case RDI_EvalOp_PartialValue: return str8_lit("PartialValue"); + case RDI_EvalOp_PartialValueBit: return str8_lit("PartialValueBit"); + } + return push_str8f(arena, "%#x", op); +} + +internal String8 +rdi_string_from_eval_type_group(Arena *arena, RDI_EvalTypeGroup x) +{ + switch (x) { + case RDI_EvalTypeGroup_Other: return str8_lit("Other"); + case RDI_EvalTypeGroup_U: return str8_lit("U"); + case RDI_EvalTypeGroup_S: return str8_lit("S"); + case RDI_EvalTypeGroup_F32: return str8_lit("F32"); + case RDI_EvalTypeGroup_F64: return str8_lit("F64"); + } + return push_str8f(arena, "%#x", x); +} + internal String8 rdi_string_from_binary_section_flags(Arena *arena, RDI_BinarySectionFlags flags) { @@ -1030,8 +1102,169 @@ rdi_print_udt(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, R scratch_end(scratch); } +internal String8 +rdi_string_from_bytecode(Arena *arena, RDI_Arch arch, String8 bc) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8List fmt = {0}; + for (U64 cursor = 0; cursor < bc.size; ) { + RDI_EvalOp op = RDI_EvalOp_Stop; + cursor += str8_deserial_read_struct(bc, cursor, &op); + + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 imm_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + + String8 imm = {0}; + cursor += str8_deserial_read_block(bc, cursor, imm_size, &imm); + if (imm.size != imm_size) { + str8_list_pushf(scratch.arena, &fmt, "(ERROR: not enough bytes to read immediate)"); + break; + } + + String8 imm_fmt = {0}; + switch (op) { + case RDI_EvalOp_Stop: goto exit; + case RDI_EvalOp_Noop: break; + case RDI_EvalOp_Cond: break; + case RDI_EvalOp_Skip: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U16 *)imm.str); + } break; + case RDI_EvalOp_MemRead: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U8 *)imm.str); + } break; + case RDI_EvalOp_RegRead: { + U32 regread = *(U32 *)imm.str; + RDI_RegCode reg_code = Extract8(regread, 0); + U8 byte_size = Extract8(regread, 1); + U8 byte_off = Extract8(regread, 2); + String8 reg_str = rdi_string_from_reg_code(scratch.arena, arch, reg_code); + imm_fmt = push_str8f(scratch.arena, "%S, Size: %u", rd_string_from_reg_off(scratch.arena, reg_str, byte_off), byte_size); + } break; + case RDI_EvalOp_RegReadDyn: break; + case RDI_EvalOp_FrameOff: { + imm_fmt = push_str8f(scratch.arena, "%+lld", *(S64 *)imm.str); + } break; + case RDI_EvalOp_ModuleOff: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U32 *)imm.str); + } break; + case RDI_EvalOp_TLSOff: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U32 *)imm.str); + } break; + case RDI_EvalOp_ConstU8: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U8 *)imm.str); + } break; + case RDI_EvalOp_ConstU16: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U16 *)imm.str); + } break; + case RDI_EvalOp_ConstU32: { + imm_fmt = push_str8f(scratch.arena, "%u", *(U32 *)imm.str); + } break; + case RDI_EvalOp_ConstU64: { + imm_fmt = push_str8f(scratch.arena, "%llu", *(U64 *)imm.str); + } break; + case RDI_EvalOp_ConstU128: { + imm_fmt = push_str8f(scratch.arena, "Lo: %llu, Hi: %llu", *(U64 *)imm.str, *((U64 *)imm.str + 1)); + } break; + case RDI_EvalOp_ConstString: { + U8 size = *(U8 *)imm.str; + String8 string = {0}; + cursor += str8_deserial_read_block(bc, cursor, size, &string); + + imm_fmt = push_str8f(scratch.arena, "(%u) \"%S\"", size, string); + } break; + case RDI_EvalOp_Abs: + case RDI_EvalOp_Neg: + case RDI_EvalOp_Add: + case RDI_EvalOp_Sub: + case RDI_EvalOp_Mul: + case RDI_EvalOp_Div: + case RDI_EvalOp_Mod: + case RDI_EvalOp_LShift: + case RDI_EvalOp_RShift: + case RDI_EvalOp_BitAnd: + case RDI_EvalOp_BitOr: + case RDI_EvalOp_BitXor: + case RDI_EvalOp_BitNot: + case RDI_EvalOp_LogAnd: + case RDI_EvalOp_LogOr: + case RDI_EvalOp_LogNot: + case RDI_EvalOp_EqEq: + case RDI_EvalOp_NtEq: + case RDI_EvalOp_LsEq: + case RDI_EvalOp_GrEq: + case RDI_EvalOp_Less: + case RDI_EvalOp_Grtr: { + U8 eval_type_group = *(U8 *)imm.str; + imm_fmt = rdi_string_from_eval_type_group(scratch.arena, eval_type_group); + } break; + case RDI_EvalOp_Trunc: + case RDI_EvalOp_TruncSigned: { + U8 trunc = *(U8 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", trunc); + } break; + case RDI_EvalOp_Convert: { + U16 convert = *(U16 *)imm.str; + U8 in = Extract8(convert, 0); + U8 out = Extract8(convert, 1); + String8 in_str = rdi_string_from_eval_type_group(scratch.arena, in); + String8 out_str = rdi_string_from_eval_type_group(scratch.arena, out); + imm_fmt = push_str8f(scratch.arena, "in: %S out: %S", in_str, out_str); + } break; + case RDI_EvalOp_Pick: { + U8 pick = *(U8 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", pick); + } break; + case RDI_EvalOp_Pop: break; + case RDI_EvalOp_Insert: { + U8 insert = *(U8 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", insert); + } break; + case RDI_EvalOp_ValueRead: { + U8 bytes_to_read = *(U8 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", bytes_to_read); + } break; + case RDI_EvalOp_ByteSwap: { + U8 byte_size = *(U8 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", byte_size); + } break; + case RDI_EvalOp_CallSiteValue: { + U32 call_site_bc_size = *(U32 *)imm.str; + String8 call_site_bc = {0}; + cursor += str8_deserial_read_block(bc, cursor, call_site_bc_size, &call_site_bc); + + String8 call_site_str = rdi_string_from_bytecode(scratch.arena, arch, call_site_bc); + imm_fmt = push_str8f(scratch.arena, "%S", call_site_str); + } break; + case RDI_EvalOp_PartialValue: { + U32 partial_value_size = *(U32 *)imm.str; + imm_fmt = push_str8f(scratch.arena, "%u", partial_value_size); + } break; + case RDI_EvalOp_PartialValueBit: { + U64 partial_value = *(U64 *)imm.str; + U32 bit_size = Extract32(partial_value, 0); + U32 bit_off = Extract32(partial_value, 1); + imm_fmt = push_str8f(scratch.arena, "Off: %u, Size: %u", bit_size, bit_off); + } break; + } + + String8 op_str = rdi_string_from_eval_op(scratch.arena, op); + if (imm_fmt.size) { + str8_list_pushf(scratch.arena, &fmt, "RDI_EvalOp_%S(%S)", op_str, imm_fmt); + } else { + str8_list_pushf(scratch.arena, &fmt, "RDI_EvalOp_%S", op_str); + } + } + exit:; + + String8 result = str8_list_join(arena, &fmt, &(StringJoin){.sep = str8_lit(", ")}); + + scratch_end(scratch); + return result; +} + internal void -rdi_print_locations(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, Arch arch, U64 block_lo, U64 block_hi) +rdi_print_locations(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Arch arch, U64 block_lo, U64 block_hi) { Temp scratch = scratch_begin(&arena, 1); @@ -1046,65 +1279,68 @@ rdi_print_locations(Arena *arena, String8List *out, String8 indent, RDI_Parsed * for (U32 block_idx = block_lo; block_idx < block_hi; ++block_idx) { RDI_LocationBlock *block_ptr = &location_block_array[block_idx]; + String8List fmt = {0}; + if (block_ptr->scope_off_first == 0 && block_ptr->scope_off_opl == max_U32) { - rd_printf("case *always*:"); + str8_list_pushf(scratch.arena, &fmt, "*always*:"); } else { - rd_printf("case [%#08x, %#08x):", block_ptr->scope_off_first, block_ptr->scope_off_opl); + str8_list_pushf(scratch.arena, &fmt, "[%#08x, %#08x):", block_ptr->scope_off_first, block_ptr->scope_off_opl); } if (block_ptr->location_data_off >= location_data_size) { - rd_printf("", block_ptr->location_data_off); + str8_list_pushf(scratch.arena, &fmt, "", block_ptr->location_data_off); } else { U8 *loc_data_opl = location_data + location_data_size; U8 *loc_base_ptr = location_data + block_ptr->location_data_off; RDI_LocationKind kind = *(RDI_LocationKind*)loc_base_ptr; switch (kind) { default: { - rd_printf("\?\?\?: %u", kind); + str8_list_pushf(scratch.arena, &fmt, "\?\?\?: %u", kind); } break; case RDI_LocationKind_AddrBytecodeStream: { - Temp temp = temp_begin(scratch.arena); - String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); - rd_printf("AddrBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); - temp_end(temp); + String8 bc = str8_range(loc_base_ptr + 1, loc_data_opl); + String8 bc_str = rdi_string_from_bytecode(scratch.arena, arch, bc); + str8_list_pushf(scratch.arena, &fmt, "AddrBytecodeStream(%S)", bc_str); } break; case RDI_LocationKind_ValBytecodeStream: { - Temp temp = temp_begin(scratch.arena); - String8 raw_bytes = str8_cstring_capped(loc_base_ptr + 1, loc_data_opl); - rd_printf("ValBytecodeStream: %S", rd_format_hex_array(temp.arena, raw_bytes.str, raw_bytes.size)); - temp_end(temp); + String8 bc = str8_range(loc_base_ptr + 1, loc_data_opl); + String8 bc_str = rdi_string_from_bytecode(scratch.arena, arch, bc); + str8_list_pushf(scratch.arena, &fmt, "ValBytecodeStream(%S)", bc_str); } break; case RDI_LocationKind_AddrRegPlusU16: { if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl) { - rd_printf("AddrRegPlusU16(\?\?\?)"); + str8_list_pushf(scratch.arena, &fmt, "AddrRegPlusU16(\?\?\?)"); } else { RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr; - rd_printf("AddrRegPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); + str8_list_pushf(scratch.arena, &fmt, "AddrRegPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); } } break; case RDI_LocationKind_AddrAddrRegPlusU16: { if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){ - rd_printf("AddrAddrRegPlusU16(\?\?\?)"); + str8_list_pushf(scratch.arena, &fmt, "AddrAddrRegPlusU16(\?\?\?)"); } else { RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16 *)loc_base_ptr; - rd_printf("AddrAddrRegisterPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); + str8_list_pushf(scratch.arena, &fmt, "AddrAddrRegisterPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); } } break; case RDI_LocationKind_ValReg: { if (loc_base_ptr + sizeof(RDI_LocationReg) > loc_data_opl) { - rd_printf("ValReg(\?\?\?)"); + str8_list_pushf(scratch.arena, &fmt, "ValReg(\?\?\?)"); } else { RDI_LocationReg *loc = (RDI_LocationReg*)loc_base_ptr; - rd_printf("ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code)); + str8_list_pushf(scratch.arena, &fmt, "ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code)); } } break; } } + + String8 print_string = str8_list_join(scratch.arena, &fmt, &(StringJoin){.sep=str8_lit(" ")}); + rd_printf("%S", print_string); } scratch_end(scratch); @@ -1161,10 +1397,12 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, U64 scope_voff_count = 0; U64 local_count = 0; U64 proc_count = 0; + U64 inline_site_count = 0; RDI_Scope *scope_array = rdi_table_from_name(rdi, Scopes, &scope_count); U64 *scope_voff_array = rdi_table_from_name(rdi, ScopeVOffData, &scope_voff_count); RDI_Local *local_array = rdi_table_from_name(rdi, Locals, &local_count); - RDI_Procedure *proc_array = rdi_table_from_name(rdi, Procedures, &proc_count); + RDI_Procedure *proc_array = rdi_table_from_name(rdi, Procedures, &proc_count); + RDI_InlineSite *inline_site_array = rdi_table_from_name(rdi, InlineSites, &inline_site_count); U32 voff_range_lo = ClampTop(scope->voff_range_first, scope_voff_count); U32 voff_range_hi = ClampTop(scope->voff_range_opl, scope_voff_count); @@ -1173,7 +1411,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, String8 voff_str = rd_string_from_range_array_u64_hex(scratch.arena, voff_ptr, voff_range_count); U64 scope_idx = (U64)(scope - scope_array); - rd_printf("[%llu]", scope_idx); + rd_printf("scope[%llu]", scope_idx); rd_indent(); String8 proc_name = str8_lit("???"); @@ -1182,10 +1420,21 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx); } + String8 inline_site_name = str8_lit(""); + if (scope->inline_site_idx != 0) { + if (scope->inline_site_idx < inline_site_count) { + RDI_InlineSite *inline_site = &inline_site_array[scope->inline_site_idx]; + inline_site_name = str8_from_rdi_string_idx(rdi, inline_site->name_string_idx); + } else { + inline_site_name = str8_lit("???"); + } + inline_site_name = push_str8f(scratch.arena, " '%S'", inline_site_name); + } + rd_printf("proc_idx =%u '%S'", scope->proc_idx, proc_name); rd_printf("first_child_scope_idx =%u", scope->first_child_scope_idx); rd_printf("next_sibling_scope_idx=%u", scope->next_sibling_scope_idx); - rd_printf("inline_site_idx =%u", scope->inline_site_idx); + rd_printf("inline_site_idx =%u%S", scope->inline_site_idx, inline_site_name); rd_printf("voff_ranges =%S", voff_str); // local_array From e7cee3b83cee262a7e46031f04545a198ab4120a Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 12:13:22 -0700 Subject: [PATCH 267/755] helper for extract bits --- src/base/base_core.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/base/base_core.h b/src/base/base_core.h index 9e2d686a..441fec7f 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -348,6 +348,9 @@ C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t s #define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0) #define ExtractBit(word, idx) (((word) >> (idx)) & 1) +#define Extract8(word, pos) (((word) >> ((pos)*8)) & max_U8) +#define Extract16(word, pos) (((word) >> ((pos)*16)) & max_U16) +#define Extract32(word, pos) (((word) >> ((pos)*32)) & max_U32) #if LANG_CPP # define zero_struct {} From c80661449c8ca797694e57aeccb069c6306c32b3 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 12:15:11 -0700 Subject: [PATCH 268/755] added rest of XMM registers, more progress on converting expressions front --- src/dwarf/dwarf.c | 64 ++++++ src/dwarf/dwarf.h | 23 ++ src/radcon/radcon_dwarf.c | 460 +++++++++++++++++++++++++++++++------- 3 files changed, 463 insertions(+), 84 deletions(-) diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index ea440ee3..77d334a1 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -1,6 +1,70 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +internal U64 +dw_reg_size_from_code_x86(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_size; + DW_Regs_X86_XList(X) +#undef X + } + return 0; +} + +internal U64 +dw_reg_pos_from_code_x86(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_pos; + DW_Regs_X86_XList(X) +#undef X + } + return max_U64; +} + +internal U64 +dw_reg_size_from_code_x64(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size; + DW_Regs_X64_XList(X) +#undef X + } + return 0; +} + +internal U64 +dw_reg_pos_from_code_x64(U64 reg_code) +{ + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos; + DW_Regs_X64_XList(X) +#undef X + } + return max_U64; +} + +internal U64 +dw_reg_size_from_code(RDI_Arch arch, U64 reg_code) +{ + switch (arch) { + case RDI_Arch_X86: return dw_reg_size_from_code_x86(reg_code); + case RDI_Arch_X64: return dw_reg_size_from_code_x64(reg_code); + } + return 0; +} + +internal U64 +dw_reg_pos_from_code(RDI_Arch arch, U64 reg_code) +{ + switch (arch) { + case RDI_Arch_X86: return dw_reg_pos_from_code_x86(reg_code); + case RDI_Arch_X64: return dw_reg_pos_from_code_x64(reg_code); + } + return max_U64; +} + internal DW_AttribClass dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k) { diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 0dce7a84..e6a246af 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -1670,6 +1670,22 @@ typedef enum DW_ExprOpEnum X(Xmm13, 30, zmm13, 0, 16) \ X(Xmm14, 31, zmm14, 0, 16) \ X(Xmm15, 32, zmm15, 0, 16) \ + X(Xmm16, 67, zmm16, 0, 16) \ + X(Xmm17, 68, zmm17, 0, 16) \ + X(Xmm18, 69, zmm18, 0, 16) \ + X(Xmm19, 70, zmm19, 0, 16) \ + X(Xmm20, 71, zmm20, 0, 16) \ + X(Xmm21, 72, zmm21, 0, 16) \ + X(Xmm22, 73, zmm22, 0, 16) \ + X(Xmm23, 74, zmm23, 0, 16) \ + X(Xmm24, 75, zmm24, 0, 16) \ + X(Xmm25, 76, zmm25, 0, 16) \ + X(Xmm26, 77, zmm26, 0, 16) \ + X(Xmm27, 78, zmm27, 0, 16) \ + X(Xmm28, 79, zmm28, 0, 16) \ + X(Xmm29, 80, zmm29, 0, 16) \ + X(Xmm30, 81, zmm30, 0, 16) \ + X(Xmm31, 82, zmm31, 0, 16) \ X(St0, 33, st0, 0, 10) \ X(St1, 34, st1, 0, 10) \ X(St2, 35, st2, 0, 10) \ @@ -1718,6 +1734,13 @@ typedef enum DW_RegX64Enum //////////////////////////////// +internal U64 dw_reg_size_from_code_x86(U64 reg_code); +internal U64 dw_reg_pos_from_code_x86(U64 reg_code); +internal U64 dw_reg_size_from_code_x64(U64 reg_code); +internal U64 dw_reg_pos_from_code_x64(U64 reg_code); +internal U64 dw_reg_size_from_code(Arch arch, U64 reg_code); +internal U64 dw_reg_pos_from_code(Arch arch, U64 reg_code); + //- Attrib Class Encodings // Speced Encodings diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 1703e184..02f95aa7 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -101,6 +101,15 @@ d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 imag // collect non-contiguous range Rng1U64List ranges = dw_rnglist_from_attrib(arena, input, cu, tag, DW_Attrib_Ranges); + // debase ranges + for (Rng1U64Node *range_n = ranges.first; range_n != 0; range_n = range_n->next) { + // TODO: error handling + AssertAlways(range_n->v.min >= image_base); + AssertAlways(range_n->v.max >= image_base); + range_n->v.min -= image_base; + range_n->v.max -= image_base; + } + // collect contiguous range DW_Attrib *lo_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_LowPc); DW_Attrib *hi_pc_attrib = dw_attrib_from_tag(input, cu, tag, DW_Attrib_HighPc); @@ -164,12 +173,109 @@ d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input return params; } +internal RDI_TypeKind +d2r_unsigned_type_kind_from_size(U64 byte_size) +{ + RDI_TypeKind result = RDI_TypeKind_NULL; + switch (byte_size) { + case 1: result = RDI_TypeKind_U8; break; + case 2: result = RDI_TypeKind_U16; break; + case 4: result = RDI_TypeKind_U32; break; + case 8: result = RDI_TypeKind_U64; break; + } + return result; +} + +internal RDI_TypeKind +d2r_signed_type_kind_from_size(U64 byte_size) +{ + RDI_TypeKind result = RDI_TypeKind_NULL; + switch (byte_size) { + case 1: result = RDI_TypeKind_S8; break; + case 2: result = RDI_TypeKind_S16; break; + case 4: result = RDI_TypeKind_S32; break; + case 8: result = RDI_TypeKind_S64; break; + } + return result; +} + +internal RDI_EvalTypeGroup +d2r_type_group_from_type_kind(RDI_TypeKind x) +{ + switch (x) { + case RDI_TypeKind_NULL: + case RDI_TypeKind_Void: + case RDI_TypeKind_Handle: + break; + case RDI_TypeKind_UChar8: + case RDI_TypeKind_UChar16: + case RDI_TypeKind_UChar32: + case RDI_TypeKind_U8: + case RDI_TypeKind_U16: + case RDI_TypeKind_U32: + case RDI_TypeKind_U64: + case RDI_TypeKind_U128: + case RDI_TypeKind_U256: + case RDI_TypeKind_U512: + return RDI_EvalTypeGroup_U; + case RDI_TypeKind_Char8: + case RDI_TypeKind_Char16: + case RDI_TypeKind_Char32: + case RDI_TypeKind_S8: + case RDI_TypeKind_S16: + case RDI_TypeKind_S32: + case RDI_TypeKind_S64: + case RDI_TypeKind_S128: + case RDI_TypeKind_S256: + case RDI_TypeKind_S512: + return RDI_EvalTypeGroup_S; + case RDI_TypeKind_F32: + return RDI_EvalTypeGroup_F32; + case RDI_TypeKind_F64: + return RDI_EvalTypeGroup_F64; + default: InvalidPath; + } + return RDI_EvalTypeGroup_Other; +} internal RDIM_EvalBytecode -d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr, B32 *is_addr_out) +d2r_bytecode_from_expression(Arena *arena, + DW_Input *input, + U64 image_base, + U64 address_size, + RDI_Arch arch, + DW_ListUnit *addr_lu, + String8 expr, + DW_CompUnit *cu, + B32 *is_addr_out) { + Temp scratch = scratch_begin(&arena, 1); + RDIM_EvalBytecode bc = {0}; - *is_addr_out = 1; + + *is_addr_out = 0; + + struct Frame { + struct Frame *next; + RDI_EvalTypeGroup value_type; + }; + struct Frame *stack = 0; +#define push_of_type(type) do { \ + struct Frame *f = push_array(scratch.arena, struct Frame, 1); \ + f->value_type = d2r_type_group_from_type_kind(type); \ + SLLStackPush(stack, f); \ +} while (0) +#define pop_type() stack->value_type; SLLStackPop(stack) +#define peek_type() stack->value_type + + + RDI_TypeKind addr_type_kind = RDI_TypeKind_NULL; + if (address_size == 4) { + addr_type_kind = RDI_TypeKind_U32; + } else if (address_size == 8) { + addr_type_kind = RDI_TypeKind_U64; + } + for (U64 cursor = 0; cursor < expr.size; ) { U8 op = 0; @@ -189,40 +295,83 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29: case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: { U64 lit = op - DW_ExprOp_Lit0; + rdim_bytecode_push_uconst(arena, &bc, lit); + push_of_type(RDI_TypeKind_U64); } break; - case DW_ExprOp_Const1U: size_param = 1; goto const_unsigned; - case DW_ExprOp_Const2U: size_param = 2; goto const_unsigned; - case DW_ExprOp_Const4U: size_param = 4; goto const_unsigned; - case DW_ExprOp_Const8U: size_param = 8; goto const_unsigned; - const_unsigned: { - U64 val = 0; - cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); + case DW_ExprOp_Const1U: { + U8 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + rdim_bytecode_push_uconst(arena, &bc, val); + push_of_type(RDI_TypeKind_U8); + } break; + case DW_ExprOp_Const2U: { + U16 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_uconst(arena, &bc, val); + push_of_type(RDI_TypeKind_U16); + } break; + case DW_ExprOp_Const4U: { + U32 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_uconst(arena, &bc, val); + push_of_type(RDI_TypeKind_U32); + } break; + case DW_ExprOp_Const8U: { + U64 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_uconst(arena, &bc, val); + push_of_type(RDI_TypeKind_U64); } break; - case DW_ExprOp_Const1S:size_param = 1; goto const_signed; - case DW_ExprOp_Const2S:size_param = 2; goto const_signed; - case DW_ExprOp_Const4S:size_param = 4; goto const_signed; - case DW_ExprOp_Const8S:size_param = 8; goto const_signed; - const_signed: { - S64 val = 0; - cursor += str8_deserial_read(expr, cursor, &val, size_param, size_param); - val = extend_sign64(val, size_param); + case DW_ExprOp_Const1S: { + S8 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + rdim_bytecode_push_sconst(arena, &bc, val); + push_of_type(RDI_TypeKind_S8); + } break; + case DW_ExprOp_Const2S: { + S16 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_sconst(arena, &bc, val); + push_of_type(RDI_TypeKind_S16); + } break; + case DW_ExprOp_Const4S: { + S32 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_sconst(arena, &bc, val); + push_of_type(RDI_TypeKind_S32); + } break; + case DW_ExprOp_Const8S: { + S64 val = 0; + cursor += str8_deserial_read_struct(expr, cursor, &val); + + rdim_bytecode_push_sconst(arena, &bc, val); + push_of_type(RDI_TypeKind_S64); } break; case DW_ExprOp_ConstU: { U64 val = 0; cursor += str8_deserial_read_uleb128(expr, cursor, &val); + rdim_bytecode_push_uconst(arena, &bc, val); + push_of_type(RDI_TypeKind_U64); } break; case DW_ExprOp_ConstS: { S64 val = 0; cursor += str8_deserial_read_sleb128(expr, cursor, &val); + rdim_bytecode_push_sconst(arena, &bc, val); + push_of_type(RDI_TypeKind_S64); } break; case DW_ExprOp_Addr: { @@ -231,10 +380,13 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI if (addr >= image_base) { U64 voff = addr - image_base; rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_ModuleOff, voff); + push_of_type(addr_type_kind); } else { // TODO: error handling AssertAlways(!"unable to relocate address"); } + + *is_addr_out = 1; } break; case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2: @@ -248,29 +400,42 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26: case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { - U64 reg_code_dw = op - DW_ExprOp_Reg0; - RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); - U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + U64 reg_code_dw = op - DW_ExprOp_Reg0; + U64 reg_size = dw_reg_size_from_code(arch, reg_code_dw); + U64 reg_pos = dw_reg_pos_from_code(arch, reg_code_dw); + + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, reg_size, reg_pos); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + push_of_type(d2r_unsigned_type_kind_from_size(reg_size)); } break; case DW_ExprOp_RegX: { U64 reg_code_dw = 0; cursor += str8_deserial_read_uleb128(expr, cursor, ®_code_dw); + + U64 reg_size = dw_reg_size_from_code(arch, reg_code_dw); + U64 reg_pos = dw_reg_pos_from_code(arch, reg_code_dw); + RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); - U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, 8, 0); + U32 regread_param = RDI_EncodeRegReadParam(reg_code_rdi, reg_size, reg_pos); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegRead, regread_param); + push_of_type(d2r_unsigned_type_kind_from_size(reg_size)); + + *is_addr_out = 1; } break; case DW_ExprOp_ImplicitValue: { - U64 value_size = 0; - cursor += str8_deserial_read_uleb128(expr, cursor, &value_size); - - String8 val = str8_substr(expr, rng_1u64(cursor, cursor + value_size)); + U64 val_size = 0; + String8 val = {0}; + cursor += str8_deserial_read_uleb128(expr, cursor, &val_size); + cursor += str8_deserial_read_block(expr, cursor, val_size, &val); if (val.size <= sizeof(U64)) { U64 val64 = 0; MemoryCopy(&val64, val.str, val.size); + rdim_bytecode_push_uconst(arena, &bc, val64); + push_of_type(d2r_unsigned_type_kind_from_size(val_size)); } else { // TODO: currenlty no way to encode string in RDIM_EvalBytecodeOp NotImplemented; @@ -278,11 +443,24 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI } break; case DW_ExprOp_Piece: { - NotImplemented; + U64 piece_byte_size = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &piece_byte_size); + + U64 partial_value_size32 = safe_cast_u32(piece_byte_size); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_PartialValue, partial_value_size32); } break; case DW_ExprOp_BitPiece: { - NotImplemented; + U64 piece_bit_size = 0; + U64 piece_bit_off = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &piece_bit_size); + cursor += str8_deserial_read_uleb128(expr, cursor, &piece_bit_off); + + U32 piece_bit_size32 = safe_cast_u32(piece_bit_size); + U32 piece_bit_off32 = safe_cast_u32(piece_bit_off); + + U64 partial_value = ((U64)piece_bit_size32 << 32) | (U64)piece_bit_off32; + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_PartialValueBit, partial_value); } break; case DW_ExprOp_Pick: { @@ -295,7 +473,7 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI U64 addend = 0; cursor += str8_deserial_read_uleb128(expr, cursor, &addend); rdim_bytecode_push_uconst(arena, &bc, addend); - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, RDI_EvalTypeGroup_U); } break; case DW_ExprOp_Skip: { @@ -325,8 +503,13 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); - rdim_bytecode_push_sconst(arena, &bc, reg_off); - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + if (reg_off > 0) { + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, RDI_EvalTypeGroup_S); + } + push_of_type(RDI_TypeKind_S64); + + *is_addr_out = 1; } break; case DW_ExprOp_BRegX: { @@ -337,14 +520,21 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI RDI_RegCode reg_code_rdi = d2r_rdi_reg_from_dw_reg_code(arch, reg_code_dw); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RegReadDyn, reg_code_rdi); - rdim_bytecode_push_sconst(arena, &bc, reg_off); - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + if (reg_off > 0) { + rdim_bytecode_push_sconst(arena, &bc, reg_off); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, RDI_EvalTypeGroup_S); + } + push_of_type(RDI_TypeKind_S64); + + *is_addr_out = 1; } break; case DW_ExprOp_FBReg: { S64 frame_off = 0; cursor += str8_deserial_read_sleb128(expr, cursor, &frame_off); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_FrameOff, frame_off); + + *is_addr_out = 1; } break; case DW_ExprOp_Deref: { @@ -382,8 +572,60 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI case DW_ExprOp_Convert: case DW_ExprOp_GNU_Convert: { - // TODO: - AssertAlways(!"sample"); + U64 type_info_off = 0; + cursor += str8_deserial_read_uleb128(expr, cursor, &type_info_off); + + RDI_EvalTypeGroup in = stack ? d2r_type_group_from_type_kind(stack->value_type) : RDI_EvalTypeGroup_Other; + RDI_EvalTypeGroup out = RDI_EvalTypeGroup_Other; + + if (type_info_off == 0) { + // + // 2.5.1 + // Instead of a base type, elements can have a generic type, + // which is an integral type that has the size of an address + // on the target machine and unspecified signedness. + // + out = d2r_type_group_from_type_kind(addr_type_kind); + } else { + // find ref tag + DW_TagNode *tag_node = dw_tag_node_from_info_off(cu, type_info_off); + DW_Tag tag = tag_node->tag; + if (tag.kind == DW_Tag_BaseType) { + // extract encoding attribute + DW_ATE encoding = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_Encoding); + + // DW_ATE -> RDI_EvalTypeGroup + switch (encoding) { + case DW_ATE_SignedChar: + case DW_ATE_Signed: out = RDI_EvalTypeGroup_S; break; + case DW_ATE_UnsignedChar: + case DW_ATE_Unsigned: out = RDI_EvalTypeGroup_U; break; + case DW_ATE_Float: { + U64 byte_size = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_ByteSize); + switch (byte_size) { + case 4: out = RDI_EvalTypeGroup_F32; break; + case 8: out = RDI_EvalTypeGroup_F64; break; + default: InvalidPath; + } + } break; + default: InvalidPath; + } + } else { + AssertAlways(!"unexpected tag"); // TODO: error handling + } + } + + if (in == RDI_EvalTypeGroup_Other) { + push_of_type(out); + break; + } + + // TODO: error handling + AssertAlways(in != RDI_EvalTypeGroup_Other); + AssertAlways(out != RDI_EvalTypeGroup_Other); + + U16 operand = (U16)in | ((U16)out << 8); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Convert, operand); } break; case DW_ExprOp_GNU_ParameterRef: { @@ -410,18 +652,16 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI case DW_ExprOp_EntryValue: case DW_ExprOp_GNU_EntryValue: { - U64 block_size = 0; - cursor += str8_deserial_read_uleb128(expr, cursor, &block_size); - - String8 entry_value_expr = {0}; - cursor += str8_deserial_read_block(expr, cursor, block_size, &entry_value_expr); + U64 entry_value_expr_size = 0; + String8 entry_value_expr = {0}; + cursor += str8_deserial_read_uleb128(expr, cursor, &entry_value_expr_size); + cursor += str8_deserial_read_block(expr, cursor, entry_value_expr_size, &entry_value_expr); B32 dummy = 0; - RDIM_EvalBytecode call_site_bc = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, entry_value_expr, &dummy); + RDIM_EvalBytecode call_site_bc = d2r_bytecode_from_expression(arena, input, image_base, address_size, arch, addr_lu, entry_value_expr, cu, &dummy); U32 encoded_size32 = safe_cast_u32(call_site_bc.encoded_size); rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_CallSiteValue, encoded_size32); - rdim_bytecode_concat_in_place(&bc, &call_site_bc); } break; @@ -461,44 +701,43 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI } break; case DW_ExprOp_Eq: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_EqEq, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_EqEq, peek_type()); } break; case DW_ExprOp_Ge: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_GrEq, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_GrEq, peek_type()); } break; case DW_ExprOp_Gt: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Grtr, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Grtr, peek_type()); } break; case DW_ExprOp_Le: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LsEq, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LsEq, peek_type()); } break; case DW_ExprOp_Lt: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Less, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Less, peek_type()); } break; case DW_ExprOp_Ne: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_NtEq, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_NtEq, peek_type()); } break; case DW_ExprOp_Shl: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LShift, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_LShift, peek_type()); } break; case DW_ExprOp_Shr: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RShift, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RShift, RDI_EvalTypeGroup_U); } break; case DW_ExprOp_Shra: { - // TODO: - AssertAlways(!"sample"); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_RShift, RDI_EvalTypeGroup_S); } break; case DW_ExprOp_Xor: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitXor, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitXor, peek_type()); } break; case DW_ExprOp_XDeref: { @@ -507,43 +746,43 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI } break; case DW_ExprOp_Abs: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Abs, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Abs, peek_type()); } break; case DW_ExprOp_And: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitAnd, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitAnd, peek_type()); } break; case DW_ExprOp_Div: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Div, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Div, peek_type()); } break; case DW_ExprOp_Minus: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Sub, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Sub, peek_type()); } break; case DW_ExprOp_Mod: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mod, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mod, peek_type()); } break; case DW_ExprOp_Mul: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mul, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Mul, peek_type()); } break; case DW_ExprOp_Neg: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Neg, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Neg, peek_type()); } break; case DW_ExprOp_Not: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitNot, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitNot, peek_type()); } break; case DW_ExprOp_Or: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitOr, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_BitOr, peek_type()); } break; case DW_ExprOp_Plus: { - rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, 0); + rdim_bytecode_push_op(arena, &bc, RDI_EvalOp_Add, peek_type()); } break; case DW_ExprOp_Rot: { @@ -574,16 +813,20 @@ d2r_bytecode_from_expression(Arena *arena, U64 image_base, U64 address_size, RDI } } +#undef peek_type +#undef pop_type +#undef push_of_type + scratch_end(scratch); return bc; } internal RDIM_Location * -d2r_transpile_expression(Arena *arena, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, String8 expr) +d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr) { RDIM_Location *loc = 0; if (expr.size) { B32 is_addr = 0; - RDIM_EvalBytecode bytecode = d2r_bytecode_from_expression(arena, image_base, address_size, arch, addr_lu, expr, &is_addr); + RDIM_EvalBytecode bytecode = d2r_bytecode_from_expression(arena, input, image_base, address_size, arch, addr_lu, expr, cu, &is_addr); loc = push_array(arena, RDIM_Location, 1); loc->kind = is_addr ? RDI_LocationKind_AddrBytecodeStream : RDI_LocationKind_ValBytecodeStream; @@ -596,7 +839,7 @@ internal RDIM_Location * d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, RDI_Arch arch, DW_Tag tag, DW_AttribKind kind) { String8 expr = dw_exprloc_from_attrib(input, cu, tag, kind); - RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, expr); + RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, expr); return location; } @@ -611,7 +854,7 @@ d2r_locset_from_attrib(Arena *arena, DW_Tag tag, DW_AttribKind kind) { - RDIM_LocationSet result = {0}; + RDIM_LocationSet locset = {0}; // extract attrib from tag DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); @@ -625,9 +868,9 @@ d2r_locset_from_attrib(Arena *arena, // convert location list to RDIM location set for (DW_LocNode *loc_n = loclist.first; loc_n != 0; loc_n = loc_n->next) { - RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, loc_n->v.expr); - RDIM_Rng1U64 voff_range = { .min = loc_n->v.range.min - image_base, .min = loc_n->v.range.max - image_base }; - rdim_location_set_push_case(arena, scopes, &result, voff_range, location); + RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, loc_n->v.expr); + RDIM_Rng1U64 voff_range = { .min = loc_n->v.range.min - image_base, .max = loc_n->v.range.max - image_base }; + rdim_location_set_push_case(arena, scopes, &locset, voff_range, location); } scratch_end(scratch); @@ -636,15 +879,59 @@ d2r_locset_from_attrib(Arena *arena, String8 expr = dw_exprloc_from_attrib_ptr(input, cu, attrib); // convert expression and inherit life-time ranges from enclosed scope - RDIM_Location *location = d2r_transpile_expression(arena, image_base, cu->address_size, arch, cu->addr_lu, expr); + RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, expr); for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { - rdim_location_set_push_case(arena, scopes, &result, range_n->v, location); + rdim_location_set_push_case(arena, scopes, &locset, range_n->v, location); } } else if (attrib_class != DW_AttribClass_Null) { AssertAlways(!"unexpected attrib class"); } - return result; + return locset; +} + +internal RDIM_LocationSet +d2r_var_locset_from_tag(Arena *arena, + DW_Input *input, + DW_CompUnit *cu, + RDIM_ScopeChunkList *scopes, + RDIM_Scope *curr_scope, + U64 image_base, + RDI_Arch arch, + DW_Tag tag) +{ + RDIM_LocationSet locset = {0}; + + B32 has_const_value = dw_tag_has_attrib(input, cu, tag, DW_Attrib_ConstValue); + B32 has_location = dw_tag_has_attrib(input, cu, tag, DW_Attrib_Location); + + if (has_const_value && has_location) { + // TODO: error handling + AssertAlways(!"unexpected variable encoding"); + } + + if (has_const_value) { + // extract const value + U64 const_value = dw_u64_from_attrib(input, cu, tag, DW_Attrib_ConstValue); + + // make value byte code + RDIM_EvalBytecode bc = {0}; + rdim_bytecode_push_uconst(arena, &bc, const_value); + + // fill out location + RDIM_Location *loc = push_array(arena, RDIM_Location, 1); + loc->kind = RDI_LocationKind_ValBytecodeStream; + loc->bytecode = bc; + + // push location cases + for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { + rdim_location_set_push_case(arena, scopes, &locset, range_n->v, loc); + } + } else if (has_location) { + locset = d2r_locset_from_attrib(arena, input, cu, scopes, curr_scope, image_base, arch, tag, DW_Attrib_Location); + } + + return locset; } internal D2R_CompUnitContribMap @@ -774,20 +1061,15 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D if (parent_tag_kind == DW_Tag_SubProgram || parent_tag_kind == DW_Tag_InlinedSubroutine || parent_tag_kind == DW_Tag_LexicalBlock) { RDIM_Scope *parent = tag_stack->next->scope; - scope->parent_scope = tag_stack->next->scope; + scope->parent_scope = parent; + scope->symbol = parent->symbol; if (parent->last_child) { parent->last_child->next_sibling = scope; } - SLLQueuePush_N(parent->first_child, parent->last_child, scope, next_sibling); } - // propagate scope symbol - if (tag_stack->cur_node->tag.kind == DW_Tag_LexicalBlock) { - scope->symbol = tag_stack->next->scope->symbol; - } - return scope; } @@ -879,7 +1161,6 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) static const U64 INLINE_SITE_CHUNK_CAP = 256; static const U64 SRC_FILE_CAP = 256; static const U64 LINE_TABLE_CAP = 256; - static const U64 CALL_SITE_CHUNK_CAP = 256; RDIM_UnitChunkList units = {0}; RDIM_UDTChunkList udts = {0}; @@ -1572,7 +1853,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) case DW_VirtualityKind_None: member_kind = RDI_MemberKind_Method; break; case DW_VirtualityKind_Virtual: member_kind = RDI_MemberKind_VirtualMethod; break; case DW_VirtualityKind_PureVirtual: member_kind = RDI_MemberKind_VirtualMethod; break; // TODO: create kind for pure virutal - default: InvalidPath; break; + //default: InvalidPath; break; } RDIM_Type *type = tag_stack->next->type; @@ -1581,7 +1862,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) member->type = type; member->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); } else if (parent_tag_kind != DW_Tag_CompileUnit) { - AssertAlways(!"unexpected tag"); + //AssertAlways(!"unexpected tag"); } tag_stack->scope = root_scope; @@ -1640,7 +1921,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) local->kind = RDI_LocalKind_Variable; local->name = name; local->type = type; - local->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, arch, tag, DW_Attrib_Location); + local->locset = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); } else { // NOTE: due to a bug in clang in stb_sprint.h local variables @@ -1667,7 +1948,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) param->kind = RDI_LocalKind_Parameter; param->name = dw_string_from_attrib(&input, cu, tag, DW_Attrib_Name); param->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_Attrib_Type); - param->locset = d2r_locset_from_attrib(arena, &input, cu, &scopes, scope, image_base, arch, tag, DW_Attrib_Location); + param->locset = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); } else { // TODO: error handling AssertAlways(!"this is a local variable"); @@ -1681,10 +1962,21 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, tag_stack, ranges); } } break; + case DW_Tag_CallSite: { + // TODO + } break; + case DW_Tag_CallSiteParameter: { + // TODO + } break; case DW_Tag_Label: case DW_Tag_CompileUnit: case DW_Tag_UnspecifiedParameters: break; + case DW_Tag_Namespace: break; + case DW_Tag_ImportedDeclaration: break; + case DW_Tag_PtrToMemberType: break; + case DW_Tag_TemplateTypeParameter: break; + case DW_Tag_ReferenceType: break; default: NotImplemented; break; } From 8f7ca178c228deefd1b25c44614797ac225a6c1b Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 12:21:55 -0700 Subject: [PATCH 269/755] bugfix incomplete type resolution hash table lookup --- src/rdi_make/rdi_make_local.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index 79aedf13..df463138 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -437,8 +437,10 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) Temp scratch = scratch_begin(0,0); + U64 total_type_count = types->total_count + 1; + ProfBegin("Build Hash Table"); - RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, total_type_count); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) { for(RDI_U64 i = 0; i < chunk->count; i += 1) @@ -474,7 +476,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) } } - slot = (slot + 1) % types->total_count; + slot = (slot + 1) % total_type_count; } while (slot != best_slot); if(name_ht[slot] == 0) @@ -487,7 +489,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) ProfEnd(); ProfBegin("Make Fwd Map"); - RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, total_type_count); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) { for(RDI_U64 i = 0; i < chunk->count; i += 1) @@ -525,6 +527,8 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) break; } } + + slot = (slot + 1) % total_type_count; } while(slot != best_slot); if(match) From 03cbbac6d732f1a032b6756a9ebe3df1cbff55f7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 13:45:26 -0700 Subject: [PATCH 270/755] source-markup-defined auto-view-rules --- src/ctrl/ctrl_core.c | 46 +++++ src/ctrl/ctrl_core.h | 2 + src/lib_raddbg_markup/raddbg_markup.c | 245 ------------------------- src/lib_raddbg_markup/raddbg_markup.h | 250 ++++++++++++++++++++++++++ src/mule/mule_main.cpp | 2 + src/raddbg/raddbg_core.c | 34 +++- src/raddbg/raddbg_main.c | 1 - 7 files changed, 329 insertions(+), 251 deletions(-) delete mode 100644 src/lib_raddbg_markup/raddbg_markup.c diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 4ce76eb3..1f05114c 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -2077,6 +2077,26 @@ ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle return result; } +internal String8 +ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle) +{ + String8 result = {0}; + U64 hash = ctrl_hash_from_handle(module_handle); + U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count; + U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; + CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; + CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->module, module_handle)) + { + result = push_str8_copy(arena, n->raddbg_data); + break; + } + } + return result; +} + //////////////////////////////// //~ rjf: Unwinding Functions @@ -3582,6 +3602,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ U32 rdi_dbg_time = 0; Guid rdi_dbg_guid = {0}; String8 rdi_dbg_path = str8_zero(); + String8 raddbg_data = str8_zero(); ProfScope("unpack relevant PE info") { B32 is_valid = 1; @@ -3775,6 +3796,30 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ } } } + + // rjf: extract copy of module's raddbg data + { + Temp scratch = scratch_begin(0, 0); + U64 sec_array_off = opt_ext_off_range.max; + U64 sec_count = file_header.section_count; + COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count); + dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec); + Rng1U64 raddbg_section_voff_range = r1u64(0, 0); + for EachIndex(idx, sec_count) + { + String8 section_name = str8_cstring(sec[idx].name); + if(str8_match(section_name, str8_lit(".raddbg"), 0)) + { + raddbg_section_voff_range.min = sec[idx].voff; + raddbg_section_voff_range.max = sec[idx].voff + sec[idx].vsize; + } + } + raddbg_data.size = dim_1u64(raddbg_section_voff_range); + raddbg_data.str = push_array(arena, U8, raddbg_data.size); + dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + raddbg_section_voff_range.min, + vaddr_range.min + raddbg_section_voff_range.max), raddbg_data.str); + scratch_end(scratch); + } } } @@ -3853,6 +3898,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ node->pdatas_count = pdatas_count; node->entry_point_voff = entry_point_voff; node->initial_debug_info_path = initial_debug_info_path; + node->raddbg_data = raddbg_data; } } } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 92541b1c..eb74a594 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -593,6 +593,7 @@ struct CTRL_ModuleImageInfoCacheNode U64 entry_point_voff; Rng1U64 tls_vaddr_range; String8 initial_debug_info_path; + String8 raddbg_data; }; typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot; @@ -891,6 +892,7 @@ internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Han internal U64 ctrl_entry_point_voff_from_module(CTRL_Handle module_handle); internal Rng1U64 ctrl_tls_vaddr_range_from_module(CTRL_Handle module_handle); internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle); +internal String8 ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle); //////////////////////////////// //~ rjf: Unwinding Functions diff --git a/src/lib_raddbg_markup/raddbg_markup.c b/src/lib_raddbg_markup/raddbg_markup.c deleted file mode 100644 index 7e220eca..00000000 --- a/src/lib_raddbg_markup/raddbg_markup.c +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ Win32 Implementations - -#if defined(_WIN32) - -//- types - -typedef int BOOL; -typedef long LONG; -typedef unsigned long ULONG; -typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; -typedef unsigned long DWORD; -typedef wchar_t WCHAR; -typedef char const *LPCSTR; -typedef const WCHAR *LPCWSTR, *PCWSTR; -typedef LONG HRESULT; -typedef void *HANDLE; -struct HINSTANCE__; -typedef struct HINSTANCE__ *HMODULE; -typedef __int64 INT_PTR; -typedef INT_PTR (*FARPROC)(); - -//- prototypes - -#include - -#if defined(__cplusplus) -extern "C" -{ -#endif - __declspec(dllimport) HMODULE LoadLibraryA(LPCSTR name); - __declspec(dllimport) FARPROC GetProcAddress(HMODULE module, LPCSTR name); - __declspec(dllimport) BOOL FreeLibrary(HMODULE mod); - __declspec(dllimport) HANDLE GetCurrentThread(void); - __declspec(dllimport) DWORD GetCurrentThreadId(void); - __declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments); - long long _InterlockedCompareExchange64(long long volatile*, long long, long long); - long long _InterlockedExchangeAdd64(long long volatile*, long long); -#pragma intrinsic(_InterlockedCompareExchange64) -#pragma intrinsic(_InterlockedExchangeAdd64) - int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list); -#if defined(__cplusplus) -} -#endif - -//- helpers - -typedef struct RADDBG_MARKUP_UnicodeDecode RADDBG_MARKUP_UnicodeDecode; -struct RADDBG_MARKUP_UnicodeDecode -{ - unsigned __int32 inc; - unsigned __int32 codepoint; -}; -static __int8 raddbg_utf8_class[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5}; - -static inline RADDBG_MARKUP_UnicodeDecode -raddbg_decode_utf8(char *str, unsigned __int64 max) -{ - RADDBG_MARKUP_UnicodeDecode result = {1, 0xffffffff}; - unsigned __int8 byte = str[0]; - unsigned __int8 byte_class = raddbg_utf8_class[byte >> 3]; - switch(byte_class) - { - case 1: - { - result.codepoint = byte; - }break; - case 2: - if(2 < max) - { - char cont_byte = str[1]; - if(raddbg_utf8_class[cont_byte >> 3] == 0) - { - result.codepoint = (byte & 0x0000001f) << 6; - result.codepoint |= (cont_byte & 0x0000003f); - result.inc = 2; - } - }break; - case 3: - if(2 < max) - { - char cont_byte[2] = {str[1], str[2]}; - if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && - raddbg_utf8_class[cont_byte[1] >> 3] == 0) - { - result.codepoint = (byte & 0x0000000f) << 12; - result.codepoint |= ((cont_byte[0] & 0x0000003f) << 6); - result.codepoint |= (cont_byte[1] & 0x0000003f); - result.inc = 3; - } - }break; - case 4: - if(3 < max) - { - char cont_byte[3] = {str[1], str[2], str[3]}; - if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && - raddbg_utf8_class[cont_byte[1] >> 3] == 0 && - raddbg_utf8_class[cont_byte[2] >> 3] == 0) - { - result.codepoint = (byte & 0x00000007) << 18; - result.codepoint |= ((cont_byte[0] & 0x0000003f) << 12); - result.codepoint |= ((cont_byte[1] & 0x0000003f) << 6); - result.codepoint |= (cont_byte[2] & 0x0000003f); - result.inc = 4; - } - } - } - return result; -} - -static inline unsigned __int32 -raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint) -{ - unsigned __int32 inc = 1; - if(codepoint == 0xffffffff) - { - str[0] = (wchar_t)'?'; - } - else if(codepoint < 0x10000) - { - str[0] = (wchar_t)codepoint; - } - else - { - U32 v = codepoint - 0x10000; - str[0] = (wchar_t)(0xD800 + (v >> 10)); - str[1] = (wchar_t)(0xDC00 + (v & 0x000003ff)); - inc = 2; - } - return inc; -} - -//- implementations - -static inline int -raddbg_is_attached__impl(void) -{ - // TODO(rjf) - return 0; -} - -static inline void -raddbg_thread_name__impl(char *fmt, ...) -{ - // rjf: resolve variadic arguments - char buffer[512] = {0}; - char *name = buffer; - { - va_list args; - va_start(args, fmt); - raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - } - - // rjf: get windows 10 style procedure - HRESULT (*SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription) = 0; - { - static HRESULT (*global_SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription); - static volatile __int64 global_SetThreadDescription_init_started; - static volatile __int64 global_SetThreadDescription_init_done; - __int64 do_init = !_InterlockedCompareExchange64(&global_SetThreadDescription_init_started, 1, 0); - if(do_init) - { - HMODULE module = LoadLibraryA("kernel32.dll"); - global_SetThreadDescription_function = (HRESULT (*)(HANDLE, PCWSTR))GetProcAddress(module, "SetThreadDescription"); - FreeLibrary(module); - _InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 1); - } - for(;_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 0) == 0;) - { - // NOTE(rjf): busy-loop, until init is done - } - SetThreadDescription_function = global_SetThreadDescription_function; - } - - // rjf: set thread name, windows 10 style - if(SetThreadDescription_function) - { - WCHAR buffer16[1024] = {0}; - int name_length = 0; - for(;name[name_length]; name_length += 1); - int write_offset = 0; - for(int idx = 0; idx < name_length;) - { - RADDBG_MARKUP_UnicodeDecode decode = raddbg_decode_utf8(name+idx, name_length-idx); - write_offset += raddbg_encode_utf16(buffer16 + write_offset, decode.codepoint); - idx += decode.inc; - } - SetThreadDescription_function(GetCurrentThread(), buffer16); - } - - // rjf: set thread name, raise-exception style - { -#pragma pack(push, 8) - typedef struct THREADNAME_INFO THREADNAME_INFO; - struct THREADNAME_INFO - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - }; -#pragma pack(pop) - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; -#pragma warning(push) -#pragma warning(disable: 6320 6322) - __try - { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); - } - __except(1) - { - } -#pragma warning(pop) - } -} - -static inline void -raddbg_thread_color__impl(unsigned int hexcode) -{ - // TODO(rjf) -} - -#define raddbg_break__impl() (__debugbreak()) - -static inline void -raddbg_watch__impl(char *fmt, ...) -{ - // TODO(rjf) -} - -static inline void -raddbg_log__impl(char *fmt, ...) -{ - // TODO(rjf) -} - -#endif // defined(_WIN32) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 390f50d9..be865bfc 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -23,5 +23,255 @@ #define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) #define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ #define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) +#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_auto_view_rule_data__##__COUNTER__[] = ("auto_view_rule: {type:" #type ", view_rule: " #__VA_ARGS__ "}") + +//////////////////////////////// +//~ Win32 Implementations + +#if defined(RADDBG_MARKUP_IMPLEMENTATION) +#if defined(_WIN32) + +//- section allocating +#pragma section(".raddbg", read) +#define raddbg_exe_data __declspec(allocate(".raddbg")) + +//- types + +typedef int BOOL; +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; +typedef unsigned long DWORD; +typedef wchar_t WCHAR; +typedef char const *LPCSTR; +typedef const WCHAR *LPCWSTR, *PCWSTR; +typedef LONG HRESULT; +typedef void *HANDLE; +struct HINSTANCE__; +typedef struct HINSTANCE__ *HMODULE; +typedef __int64 INT_PTR; +typedef INT_PTR (*FARPROC)(); + +//- prototypes + +#include + +#if defined(__cplusplus) +extern "C" +{ +#endif + __declspec(dllimport) HMODULE LoadLibraryA(LPCSTR name); + __declspec(dllimport) FARPROC GetProcAddress(HMODULE module, LPCSTR name); + __declspec(dllimport) BOOL FreeLibrary(HMODULE mod); + __declspec(dllimport) HANDLE GetCurrentThread(void); + __declspec(dllimport) DWORD GetCurrentThreadId(void); + __declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments); + long long _InterlockedCompareExchange64(long long volatile*, long long, long long); + long long _InterlockedExchangeAdd64(long long volatile*, long long); +#pragma intrinsic(_InterlockedCompareExchange64) +#pragma intrinsic(_InterlockedExchangeAdd64) + int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list); +#if defined(__cplusplus) +} +#endif + +//- helpers + +typedef struct RADDBG_MARKUP_UnicodeDecode RADDBG_MARKUP_UnicodeDecode; +struct RADDBG_MARKUP_UnicodeDecode +{ + unsigned __int32 inc; + unsigned __int32 codepoint; +}; +static __int8 raddbg_utf8_class[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5}; + +static inline RADDBG_MARKUP_UnicodeDecode +raddbg_decode_utf8(char *str, unsigned __int64 max) +{ + RADDBG_MARKUP_UnicodeDecode result = {1, 0xffffffff}; + unsigned __int8 byte = str[0]; + unsigned __int8 byte_class = raddbg_utf8_class[byte >> 3]; + switch(byte_class) + { + case 1: + { + result.codepoint = byte; + }break; + case 2: + if(2 < max) + { + char cont_byte = str[1]; + if(raddbg_utf8_class[cont_byte >> 3] == 0) + { + result.codepoint = (byte & 0x0000001f) << 6; + result.codepoint |= (cont_byte & 0x0000003f); + result.inc = 2; + } + }break; + case 3: + if(2 < max) + { + char cont_byte[2] = {str[1], str[2]}; + if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && + raddbg_utf8_class[cont_byte[1] >> 3] == 0) + { + result.codepoint = (byte & 0x0000000f) << 12; + result.codepoint |= ((cont_byte[0] & 0x0000003f) << 6); + result.codepoint |= (cont_byte[1] & 0x0000003f); + result.inc = 3; + } + }break; + case 4: + if(3 < max) + { + char cont_byte[3] = {str[1], str[2], str[3]}; + if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 && + raddbg_utf8_class[cont_byte[1] >> 3] == 0 && + raddbg_utf8_class[cont_byte[2] >> 3] == 0) + { + result.codepoint = (byte & 0x00000007) << 18; + result.codepoint |= ((cont_byte[0] & 0x0000003f) << 12); + result.codepoint |= ((cont_byte[1] & 0x0000003f) << 6); + result.codepoint |= (cont_byte[2] & 0x0000003f); + result.inc = 4; + } + } + } + return result; +} + +static inline unsigned __int32 +raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint) +{ + unsigned __int32 inc = 1; + if(codepoint == 0xffffffff) + { + str[0] = (wchar_t)'?'; + } + else if(codepoint < 0x10000) + { + str[0] = (wchar_t)codepoint; + } + else + { + unsigned __int32 v = codepoint - 0x10000; + str[0] = (wchar_t)(0xD800 + (v >> 10)); + str[1] = (wchar_t)(0xDC00 + (v & 0x000003ff)); + inc = 2; + } + return inc; +} + +//- implementations + +static inline int +raddbg_is_attached__impl(void) +{ + // TODO(rjf) + return 0; +} + +static inline void +raddbg_thread_name__impl(char *fmt, ...) +{ + // rjf: resolve variadic arguments + char buffer[512] = {0}; + char *name = buffer; + { + va_list args; + va_start(args, fmt); + raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + } + + // rjf: get windows 10 style procedure + HRESULT (*SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription) = 0; + { + static HRESULT (*global_SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription); + static volatile __int64 global_SetThreadDescription_init_started; + static volatile __int64 global_SetThreadDescription_init_done; + __int64 do_init = !_InterlockedCompareExchange64(&global_SetThreadDescription_init_started, 1, 0); + if(do_init) + { + HMODULE module = LoadLibraryA("kernel32.dll"); + global_SetThreadDescription_function = (HRESULT (*)(HANDLE, PCWSTR))GetProcAddress(module, "SetThreadDescription"); + FreeLibrary(module); + _InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 1); + } + for(;_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 0) == 0;) + { + // NOTE(rjf): busy-loop, until init is done + } + SetThreadDescription_function = global_SetThreadDescription_function; + } + + // rjf: set thread name, windows 10 style + if(SetThreadDescription_function) + { + WCHAR buffer16[1024] = {0}; + int name_length = 0; + for(;name[name_length]; name_length += 1); + int write_offset = 0; + for(int idx = 0; idx < name_length;) + { + RADDBG_MARKUP_UnicodeDecode decode = raddbg_decode_utf8(name+idx, name_length-idx); + write_offset += raddbg_encode_utf16(buffer16 + write_offset, decode.codepoint); + idx += decode.inc; + } + SetThreadDescription_function(GetCurrentThread(), buffer16); + } + + // rjf: set thread name, raise-exception style + { +#pragma pack(push, 8) + typedef struct THREADNAME_INFO THREADNAME_INFO; + struct THREADNAME_INFO + { + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; + }; +#pragma pack(pop) + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } +#pragma warning(pop) + } +} + +static inline void +raddbg_thread_color__impl(unsigned int hexcode) +{ + // TODO(rjf) +} + +#define raddbg_break__impl() (__debugbreak()) + +static inline void +raddbg_watch__impl(char *fmt, ...) +{ + // TODO(rjf) +} + +static inline void +raddbg_log__impl(char *fmt, ...) +{ + // TODO(rjf) +} + +#endif // defined(_WIN32) +#endif // defined(RADDBG_MARKUP_IMPLEMENTATION) #endif // RADDBG_MARKUP_H diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 81eb08df..9a028864 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -6,6 +6,7 @@ ** stepping, breakpoints, evaluation, cross-module calls. */ +#define RADDBG_MARKUP_IMPLEMENTATION #include "lib_raddbg_markup/raddbg_markup.h" //////////////////////////////// @@ -142,6 +143,7 @@ struct Fixed_Array{ int count; }; +raddbg_auto_view_rule(Dynamic?, slice); struct Dynamic_Array{ Pair *pairs; int count; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4100c2df..c77162f6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13900,15 +13900,39 @@ rd_frame(void) } } + //- rjf: gather auto-view-rules from loaded modules + RD_CfgList immediate_auto_view_rules = {0}; + CTRL_EntityList modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next) + { + String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, n->v->handle); + RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, raddbg_data); + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, n->v->handle)); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); + rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); + } + } + //- rjf: add auto-hook rules for auto-view-rules { RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); - for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next) + RD_CfgList rules_lists[] = { - RD_Cfg *rule = n->v; - String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; - String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + auto_view_rules, + immediate_auto_view_rules, + }; + for EachElement(list_idx, rules_lists) + { + RD_CfgList list = rules_lists[list_idx]; + for(RD_CfgNode *n = list.first; n != 0; n = n->next) + { + RD_Cfg *rule = n->v; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; + e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + } } } } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 9e6738ef..2b018fb4 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -388,7 +388,6 @@ #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" #include "lib_raddbg_markup/raddbg_markup.h" -#include "lib_raddbg_markup/raddbg_markup.c" //- rjf: [h] #include "base/base_inc.h" From 14966d932e9be5757add62bceb8243ffdfe34ba5 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 26 Mar 2025 14:52:28 -0700 Subject: [PATCH 271/755] don't bake discarded type --- src/lib_rdi_make/rdi_make.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 8e4ee557..340d0883 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -2342,6 +2342,7 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI for(RDI_U64 idx = 0; idx < n->count; idx += 1) { RDI_U32 type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, &n->v[idx]); // TODO(rjf): @u64_to_u32 + if(type_idx == 0) {continue;} rdim_bake_name_map_push(arena, map, n->v[idx].name, type_idx); } } From b154c5a120c82df61f5b0f0a176eaf2182a673a5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 14:57:54 -0700 Subject: [PATCH 272/755] use slightly looser mapping for auto-view-rules, to not generate false negatives when looking up --- src/eval/eval_ir.c | 10 +++---- src/eval/eval_ir.h | 2 +- .../eval_visualization_core.h | 28 ------------------- 3 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index a20e36e9..06dd5356 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1326,13 +1326,13 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * type_key = irtree.type_key; } E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); - node->type_key = type_key; + 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->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; if(!e_type_key_match(e_type_key_zero(), type_key)) { - U64 hash = e_hash_from_string(5381, str8_struct(&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); } @@ -1352,15 +1352,16 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { Temp scratch = scratch_begin(&arena, 1); E_AutoHookMap *map = e_ir_state->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, str8_struct(&type_key)); + 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(e_type_key_match(n->type_key, type_key)) + if(str8_match(n->type_string, type_string, 0)) { for(E_Expr *e = n->tag_exprs.first; e != &e_expr_nil; e = e->next) { @@ -1373,7 +1374,6 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) //- rjf: gather fuzzy matches from all patterns in the map if(map != 0 && 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) diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d06cb232..93210498 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -188,7 +188,7 @@ struct E_AutoHookNode { E_AutoHookNode *hash_next; E_AutoHookNode *pattern_order_next; - E_TypeKey type_key; + String8 type_string; String8List type_pattern_parts; E_ExprChain tag_exprs; }; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 57e24759..e247c273 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -224,33 +224,6 @@ struct EV_WindowedRowList U64 count_before_semantic; }; -//////////////////////////////// -//~ rjf: Automatic Type -> View Rule Map Types - -typedef struct EV_AutoViewRuleNode EV_AutoViewRuleNode; -struct EV_AutoViewRuleNode -{ - EV_AutoViewRuleNode *next; - E_TypeKey key; - String8 view_rule; - B32 is_required; -}; - -typedef struct EV_AutoViewRuleSlot EV_AutoViewRuleSlot; -struct EV_AutoViewRuleSlot -{ - EV_AutoViewRuleNode *first; - EV_AutoViewRuleNode *last; - U64 count; -}; - -typedef struct EV_AutoViewRuleTable EV_AutoViewRuleTable; -struct EV_AutoViewRuleTable -{ - EV_AutoViewRuleSlot *slots; - U64 slots_count; -}; - //////////////////////////////// //~ rjf: Generated Code @@ -280,7 +253,6 @@ global read_only EV_ExpandRule ev_nil_expand_rule = EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; -thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0; global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_expand_rule}; //////////////////////////////// From dc967f52743eb77dd080090c271027868c66babb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Mar 2025 16:28:13 -0700 Subject: [PATCH 273/755] fix treatment of 0-terminator in raddbg data section, fix encoding of auto view rules in raddbg data section --- src/lib_raddbg_markup/raddbg_markup.h | 8 ++++++- src/mule/mule_main.cpp | 31 +++++++++++++++++++-------- src/raddbg/raddbg_core.c | 16 +++++++++----- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index be865bfc..c59d7ade 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -23,7 +23,13 @@ #define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) #define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ #define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_auto_view_rule_data__##__COUNTER__[] = ("auto_view_rule: {type:" #type ", view_rule: " #__VA_ARGS__ "}") +#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") + +//////////////////////////////// +//~ Helpers + +#define raddbg_glue_(a, b) a##b +#define raddbg_glue(a, b) raddbg_glue_(a, b) //////////////////////////////// //~ Win32 Implementations diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 9a028864..23b47f5e 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1602,6 +1602,15 @@ basic_inline_tests(void) //////////////////////////////// //~ rjf: Fancy Visualization Eval Tests +struct Bitmap +{ + unsigned char *base; + int width; + int height; +}; +// raddbg_auto_view_rule(Bitmap, wrap(base) bitmap(width, height)); +raddbg_auto_view_rule(Bitmap, wrap($expr.base)); + static unsigned int mule_bswap_u32(unsigned int x) { @@ -1708,6 +1717,10 @@ fancy_viz_eval_tests(void) } int x2 = 0; + //- rjf: auto-view-rule'd bitmaps + Bitmap foo = {(unsigned char *)&bitmap[0], 18, 18}; + raddbg_pin(foo); + //- rjf: 3D geometry float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ... { @@ -2365,12 +2378,12 @@ debug_string_tests(void) OutputDebugStringA("Hello, World!\n"); } char message[65409+1]; - memset(&message[0], '=', sizeof(message)); - for(int i = 1; i < sizeof(message); i += 128) - { - message[i] = '\n'; - } - message[sizeof(message) - 1] = 0; + memset(&message[0], '=', sizeof(message)); + for(int i = 1; i < sizeof(message); i += 128) + { + message[i] = '\n'; + } + message[sizeof(message) - 1] = 0; OutputDebugStringA(message); #endif } @@ -2643,13 +2656,13 @@ static void dynamic_step_test(void){ #if _WIN32 #if defined(_x86_64) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( _M_AMD64 ) - void *page = VirtualAlloc(0, 4096, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); + void *page = VirtualAlloc(0, 4096, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); char *ptr = (char*)page; *ptr++ = 0x51; // push rcx *ptr++ = 0x59; // pop rcx *ptr++ = 0xC3; // ret - callback_t cb = (callback_t)page; - cb(1); + callback_t cb = (callback_t)page; + cb(1); #endif #endif } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c77162f6..66e29a76 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13906,12 +13906,18 @@ rd_frame(void) for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next) { String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, n->v->handle); - RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, raddbg_data); - RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, n->v->handle)); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + U8 split_char = 0; + String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); + for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) { - rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); - rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); + String8 text = text_n->string; + RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, n->v->handle)); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); + rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); + } } } From 53c889e5d3dde1de0f788cf7520ad35da4967fe5 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 11:12:48 -0700 Subject: [PATCH 274/755] switched to using base Arch enum for converting DWARF registers, simplified top level building path --- src/dwarf/dwarf.c | 20 +++++------ src/dwarf/dwarf.h | 12 +++---- src/radcon/radcon_coff.c | 22 ------------ src/radcon/radcon_coff.h | 1 - src/radcon/radcon_dwarf.c | 66 +++++++++++++++-------------------- src/radcon/radcon_elf.c | 7 ---- src/radcon/radcon_elf.h | 1 - src/radcon/radcon_pdb.c | 10 +++--- src/rdi_make/rdi_make_local.c | 33 ++++++++++++++++++ src/rdi_make/rdi_make_local.h | 5 +++ 10 files changed, 87 insertions(+), 90 deletions(-) diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index 77d334a1..0c552663 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -2,7 +2,7 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) internal U64 -dw_reg_size_from_code_x86(U64 reg_code) +dw_reg_size_from_code_x86(DW_Reg reg_code) { switch (reg_code) { #define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_size; @@ -13,7 +13,7 @@ dw_reg_size_from_code_x86(U64 reg_code) } internal U64 -dw_reg_pos_from_code_x86(U64 reg_code) +dw_reg_pos_from_code_x86(DW_Reg reg_code) { switch (reg_code) { #define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_pos; @@ -24,7 +24,7 @@ dw_reg_pos_from_code_x86(U64 reg_code) } internal U64 -dw_reg_size_from_code_x64(U64 reg_code) +dw_reg_size_from_code_x64(DW_Reg reg_code) { switch (reg_code) { #define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size; @@ -35,7 +35,7 @@ dw_reg_size_from_code_x64(U64 reg_code) } internal U64 -dw_reg_pos_from_code_x64(U64 reg_code) +dw_reg_pos_from_code_x64(DW_Reg reg_code) { switch (reg_code) { #define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos; @@ -46,21 +46,21 @@ dw_reg_pos_from_code_x64(U64 reg_code) } internal U64 -dw_reg_size_from_code(RDI_Arch arch, U64 reg_code) +dw_reg_size_from_code(RDI_Arch arch, DW_Reg reg_code) { switch (arch) { - case RDI_Arch_X86: return dw_reg_size_from_code_x86(reg_code); - case RDI_Arch_X64: return dw_reg_size_from_code_x64(reg_code); + case Arch_x86: return dw_reg_size_from_code_x86(reg_code); + case Arch_x64: return dw_reg_size_from_code_x64(reg_code); } return 0; } internal U64 -dw_reg_pos_from_code(RDI_Arch arch, U64 reg_code) +dw_reg_pos_from_code(RDI_Arch arch, DW_Reg reg_code) { switch (arch) { - case RDI_Arch_X86: return dw_reg_pos_from_code_x86(reg_code); - case RDI_Arch_X64: return dw_reg_pos_from_code_x64(reg_code); + case Arch_x86: return dw_reg_pos_from_code_x86(reg_code); + case Arch_x64: return dw_reg_pos_from_code_x64(reg_code); } return max_U64; } diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index e6a246af..4c7132a4 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -1734,12 +1734,12 @@ typedef enum DW_RegX64Enum //////////////////////////////// -internal U64 dw_reg_size_from_code_x86(U64 reg_code); -internal U64 dw_reg_pos_from_code_x86(U64 reg_code); -internal U64 dw_reg_size_from_code_x64(U64 reg_code); -internal U64 dw_reg_pos_from_code_x64(U64 reg_code); -internal U64 dw_reg_size_from_code(Arch arch, U64 reg_code); -internal U64 dw_reg_pos_from_code(Arch arch, U64 reg_code); +internal U64 dw_reg_size_from_code_x86(DW_Reg reg_code); +internal U64 dw_reg_pos_from_code_x86(DW_Reg reg_code); +internal U64 dw_reg_size_from_code_x64(DW_Reg reg_code); +internal U64 dw_reg_pos_from_code_x64(DW_Reg reg_code); +internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code); +internal U64 dw_reg_pos_from_code(Arch arch, DW_Reg reg_code); //- Attrib Class Encodings diff --git a/src/radcon/radcon_coff.c b/src/radcon/radcon_coff.c index 9f5b6059..56306141 100644 --- a/src/radcon/radcon_coff.c +++ b/src/radcon/radcon_coff.c @@ -78,25 +78,3 @@ c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 return binary_sections; } -internal RDIM_TopLevelInfo -c2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, U64 exe_hash, U64 sectab_count, COFF_SectionHeader *sectab) -{ - U64 exe_voff_max = 0; - { - COFF_SectionHeader *coff_sec_ptr = sectab; - COFF_SectionHeader *coff_ptr_opl = sectab + sectab_count; - for (;coff_sec_ptr < coff_ptr_opl; coff_sec_ptr += 1) { - U64 sec_voff_max = coff_sec_ptr->voff + coff_sec_ptr->vsize; - exe_voff_max = Max(exe_voff_max, sec_voff_max); - } - } - - RDIM_TopLevelInfo top_level_info = {0}; - top_level_info.arch = arch; - top_level_info.exe_name = str8_skip_last_slash(image_name); - top_level_info.exe_hash = exe_hash; - top_level_info.voff_max = exe_voff_max; - top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); - - return top_level_info; -} diff --git a/src/radcon/radcon_coff.h b/src/radcon/radcon_coff.h index abed4aef..57cf7a47 100644 --- a/src/radcon/radcon_coff.h +++ b/src/radcon/radcon_coff.h @@ -7,7 +7,6 @@ internal RDI_Arch c2r_rdi_arch_from_coff_machine(COFF_MachineType machine); internal RDI_BinarySectionFlags c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags); internal RDIM_BinarySectionList c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 string_table_off, U64 sectab_count, COFF_SectionHeader *sectab); -internal RDIM_TopLevelInfo c2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, U64 exe_hash, U64 sectab_count, COFF_SectionHeader *sectab); #endif // RADCON_COFF_H diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 02f95aa7..98ad228c 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -32,12 +32,12 @@ d2r_rdi_reg_from_dw_reg_code_x86(U64 reg_code) } internal RDI_RegCode -d2r_rdi_reg_from_dw_reg_code(RDI_Arch arch, U64 reg_code) +d2r_rdi_reg_from_dw_reg_code(Arch arch, U64 reg_code) { switch (arch) { - case RDI_Arch_NULL: return 0; - case RDI_Arch_X64: return d2r_rdi_reg_from_dw_reg_code_x64(reg_code); - case RDI_Arch_X86: return d2r_rdi_reg_from_dw_reg_code_x86(reg_code); + case Arch_Null: return 0; + case Arch_x64: return d2r_rdi_reg_from_dw_reg_code_x64(reg_code); + case Arch_x86: return d2r_rdi_reg_from_dw_reg_code_x86(reg_code); } InvalidPath; return 0; @@ -243,7 +243,7 @@ d2r_bytecode_from_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, - RDI_Arch arch, + Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, @@ -821,7 +821,7 @@ d2r_bytecode_from_expression(Arena *arena, } internal RDIM_Location * -d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, RDI_Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr) +d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr) { RDIM_Location *loc = 0; if (expr.size) { @@ -836,7 +836,7 @@ d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 addr } internal RDIM_Location * -d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, RDI_Arch arch, DW_Tag tag, DW_AttribKind kind) +d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind) { String8 expr = dw_exprloc_from_attrib(input, cu, tag, kind); RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, expr); @@ -850,7 +850,7 @@ d2r_locset_from_attrib(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, U64 image_base, - RDI_Arch arch, + Arch arch, DW_Tag tag, DW_AttribKind kind) { @@ -897,7 +897,7 @@ d2r_var_locset_from_tag(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, U64 image_base, - RDI_Arch arch, + Arch arch, DW_Tag tag) { RDIM_LocationSet locset = {0}; @@ -1086,60 +1086,46 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) //////////////////////////////// - RDI_Arch arch = RDI_Arch_NULL; + Arch arch = Arch_Null; + U64 image_base = 0; RDIM_BinarySectionList binary_sections = {0}; - RDIM_TopLevelInfo top_level_info = {0}; - - U64 image_base = 0; - DW_Input input = {0}; - DW_ListUnitInput lui = {0}; + DW_Input input = {0}; if (in->image == Image_CoffPe) { PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, in->image_data); - // convert arch - switch (pe.arch) { - case Arch_Null: arch = RDI_Arch_NULL; break; - case Arch_x64: arch = RDI_Arch_X64; break; - case Arch_x86: arch = RDI_Arch_X86; break; - default: NotImplemented; break; - } + // get image arch + arch = pe.arch; // get image base image_base = pe.image_base; - // get COFF sections + // get image sections String8 raw_sections = str8_substr(in->image_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; - // convert sections & top level info + // convert sections binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, in->image_data, pe.string_table_off, section_count, section_array); - top_level_info = c2r_make_rdim_top_level_info(in->image_name, arch, exe_hash, section_count, section_array); - // find DWARF sections + // make DWARF input input = dw_input_from_coff_section_table(scratch.arena, in->image_data, pe.string_table_off, section_count, section_array); } else if (in->image == Image_Elf32 || in->image == Image_Elf64) { ELF_BinInfo elf = elf_bin_from_data(in->debug_data); + // get image arch + arch = arch_from_elf_machine(elf.hdr.e_machine); + // get image base image_base = elf_base_addr_from_bin(&elf.hdr); - // convert arch - switch (elf.hdr.e_machine) { - case ELF_MachineKind_None: arch = RDI_Arch_NULL; break; - case ELF_MachineKind_X86_64: arch = RDI_Arch_X64; break; - case ELF_MachineKind_386: arch = RDI_Arch_X86; break; - default: NotImplemented; break; - } - + // get image sections ELF_Shdr64Array shdrs = elf_shdr64_array_from_bin(scratch.arena, in->debug_data, &elf.hdr); - // convert sections & top level info - binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, shdrs); - top_level_info = e2r_make_rdim_top_level_info(in->debug_data, exe_hash, shdrs); + // convert sections + binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, shdrs); - // find DWARF sections + // make DWARF input input = dw_input_from_elf_section_table(scratch.arena, in->debug_data, &elf); } else { InvalidPath; @@ -1147,6 +1133,10 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) //////////////////////////////// + RDIM_TopLevelInfo top_level_info = rdim_make_top_level_info(in->image_name, arch, exe_hash, binary_sections); + + //////////////////////////////// + U64 arch_addr_size = rdi_addr_size_from_arch(arch); //////////////////////////////// diff --git a/src/radcon/radcon_elf.c b/src/radcon/radcon_elf.c index 6a262ee2..d5ab8333 100644 --- a/src/radcon/radcon_elf.c +++ b/src/radcon/radcon_elf.c @@ -8,10 +8,3 @@ e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shd return result; } -internal RDIM_TopLevelInfo -e2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, ELF_Shdr64Array shdrs) -{ - RDIM_TopLevelInfo top_level_info = {0}; - return top_level_info; -} - diff --git a/src/radcon/radcon_elf.h b/src/radcon/radcon_elf.h index bcf40e08..dadb2ae2 100644 --- a/src/radcon/radcon_elf.h +++ b/src/radcon/radcon_elf.h @@ -5,6 +5,5 @@ #define RADCON_ELF_H internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs); -internal RDIM_TopLevelInfo e2r_make_rdim_top_level_info(String8 image_name, RDI_Arch arch, ELF_Shdr64Array shdrs); #endif // RADCON_ELF_H diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index 4b395510..4a24ed43 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -2363,15 +2363,15 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) // U64 exe_hash = *async_task_join_struct(exe_hash_task, U64); - ////////////////////////////////////////////////////////////// - //- rjf: produce top-level-info - // - RDIM_TopLevelInfo top_level_info = c2r_make_rdim_top_level_info(in->image_name, arch, exe_hash, coff_sections.count, coff_sections.v); - ////////////////////////////////////////////////////////////// //- rjf: build binary sections list // RDIM_BinarySectionList binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, str8_zero(), 0, coff_sections.count, coff_sections.v); + + ////////////////////////////////////////////////////////////// + //- rjf: produce top-level-info + // + RDIM_TopLevelInfo top_level_info = rdim_make_top_level_info(in->image_name, arch_from_coff_machine(dbi->machine_type), exe_hash, binary_sections); ////////////////////////////////////////////////////////////// //- rjf: kick off unit conversion & source file collection diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index df463138..3de6d4af 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -37,6 +37,39 @@ rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) return data_model; } +//////////////////////////////// + +internal RDIM_TopLevelInfo +rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections) +{ + // convert arch + RDI_Arch arch_rdi; + switch (arch) { + case Arch_Null: arch_rdi = RDI_Arch_NULL; break; + case Arch_x64: arch_rdi = RDI_Arch_X64; break; + case Arch_x86: arch_rdi = RDI_Arch_X86; break; + default: NotImplemented; break; + } + + + // find max VOFF + U64 exe_voff_max = 0; + for (RDIM_BinarySectionNode *sect_n = sections.first; sect_n != 0 ; sect_n = sect_n->next) { + exe_voff_max = Max(exe_voff_max, sect_n->v.voff_opl); + } + + + // fill out top level info + RDIM_TopLevelInfo top_level_info = {0}; + top_level_info.arch = arch_rdi; + top_level_info.exe_hash = exe_hash; + top_level_info.voff_max = exe_voff_max; + top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); + + + return top_level_info; +} + //////////////////////////////// //~ rjf: Baking Stage Tasks diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index f8bffbfa..290265b8 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -384,6 +384,11 @@ global RDIM_LocalState *rdim_local_state = 0; //////////////////////////////// +internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); +internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections); + +//////////////////////////////// + internal RDIM_LocalState * rdim_local_init(void); internal RDIM_BakeResults rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in); internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); From 49ba163077d954299a51608a838ecf144b812356 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 13:42:50 -0700 Subject: [PATCH 275/755] export CodeView types as aliases to its builtin counter-parts, --- src/lib_rdi_format/rdi_format.c | 68 ++++++++++++++++++++++++++++++++ src/lib_rdi_make/rdi_make.c | 69 ++++++++++++++++++++++++++++----- src/lib_rdi_make/rdi_make.h | 5 +++ src/radcon/radcon_dwarf.c | 10 ++--- src/radcon/radcon_dwarf.h | 1 - src/radcon/radcon_pdb.c | 59 ++++++++++------------------ src/rdi_format/rdi_format.mdesk | 17 ++++++++ 7 files changed, 175 insertions(+), 54 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 563e4b42..74fc9ed3 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -180,6 +180,74 @@ rdi_hash(RDI_U8 *ptr, RDI_U64 size) return result; } +RDI_PROC RDI_U8 * +rdi_string_from_type_kind(RDI_TypeKind kind, RDI_U64 *size_out) +{ +RDI_U8 *result = 0; +*size_out = 0; +switch (kind) +{ +default:{}break; +case RDI_TypeKind_NULL: {result = "NULL"; *size_out = sizeof("NULL")-1;}break; +case RDI_TypeKind_Void: {result = "Void"; *size_out = sizeof("Void")-1;}break; +case RDI_TypeKind_Handle: {result = "Handle"; *size_out = sizeof("Handle")-1;}break; +case RDI_TypeKind_HResult: {result = "HResult"; *size_out = sizeof("HResult")-1;}break; +case RDI_TypeKind_Char8: {result = "Char8"; *size_out = sizeof("Char8")-1;}break; +case RDI_TypeKind_Char16: {result = "Char16"; *size_out = sizeof("Char16")-1;}break; +case RDI_TypeKind_Char32: {result = "Char32"; *size_out = sizeof("Char32")-1;}break; +case RDI_TypeKind_UChar8: {result = "UChar8"; *size_out = sizeof("UChar8")-1;}break; +case RDI_TypeKind_UChar16: {result = "UChar16"; *size_out = sizeof("UChar16")-1;}break; +case RDI_TypeKind_UChar32: {result = "UChar32"; *size_out = sizeof("UChar32")-1;}break; +case RDI_TypeKind_U8: {result = "U8"; *size_out = sizeof("U8")-1;}break; +case RDI_TypeKind_U16: {result = "U16"; *size_out = sizeof("U16")-1;}break; +case RDI_TypeKind_U32: {result = "U32"; *size_out = sizeof("U32")-1;}break; +case RDI_TypeKind_U64: {result = "U64"; *size_out = sizeof("U64")-1;}break; +case RDI_TypeKind_U128: {result = "U128"; *size_out = sizeof("U128")-1;}break; +case RDI_TypeKind_U256: {result = "U256"; *size_out = sizeof("U256")-1;}break; +case RDI_TypeKind_U512: {result = "U512"; *size_out = sizeof("U512")-1;}break; +case RDI_TypeKind_S8: {result = "S8"; *size_out = sizeof("S8")-1;}break; +case RDI_TypeKind_S16: {result = "S16"; *size_out = sizeof("S16")-1;}break; +case RDI_TypeKind_S32: {result = "S32"; *size_out = sizeof("S32")-1;}break; +case RDI_TypeKind_S64: {result = "S64"; *size_out = sizeof("S64")-1;}break; +case RDI_TypeKind_S128: {result = "S128"; *size_out = sizeof("S128")-1;}break; +case RDI_TypeKind_S256: {result = "S256"; *size_out = sizeof("S256")-1;}break; +case RDI_TypeKind_S512: {result = "S512"; *size_out = sizeof("S512")-1;}break; +case RDI_TypeKind_Bool: {result = "Bool"; *size_out = sizeof("Bool")-1;}break; +case RDI_TypeKind_F16: {result = "F16"; *size_out = sizeof("F16")-1;}break; +case RDI_TypeKind_F32: {result = "F32"; *size_out = sizeof("F32")-1;}break; +case RDI_TypeKind_F32PP: {result = "F32PP"; *size_out = sizeof("F32PP")-1;}break; +case RDI_TypeKind_F48: {result = "F48"; *size_out = sizeof("F48")-1;}break; +case RDI_TypeKind_F64: {result = "F64"; *size_out = sizeof("F64")-1;}break; +case RDI_TypeKind_F80: {result = "F80"; *size_out = sizeof("F80")-1;}break; +case RDI_TypeKind_F128: {result = "F128"; *size_out = sizeof("F128")-1;}break; +case RDI_TypeKind_ComplexF32: {result = "ComplexF32"; *size_out = sizeof("ComplexF32")-1;}break; +case RDI_TypeKind_ComplexF64: {result = "ComplexF64"; *size_out = sizeof("ComplexF64")-1;}break; +case RDI_TypeKind_ComplexF80: {result = "ComplexF80"; *size_out = sizeof("ComplexF80")-1;}break; +case RDI_TypeKind_ComplexF128: {result = "ComplexF128"; *size_out = sizeof("ComplexF128")-1;}break; +case RDI_TypeKind_Modifier: {result = "Modifier"; *size_out = sizeof("Modifier")-1;}break; +case RDI_TypeKind_Ptr: {result = "Ptr"; *size_out = sizeof("Ptr")-1;}break; +case RDI_TypeKind_LRef: {result = "LRef"; *size_out = sizeof("LRef")-1;}break; +case RDI_TypeKind_RRef: {result = "RRef"; *size_out = sizeof("RRef")-1;}break; +case RDI_TypeKind_Array: {result = "Array"; *size_out = sizeof("Array")-1;}break; +case RDI_TypeKind_Function: {result = "Function"; *size_out = sizeof("Function")-1;}break; +case RDI_TypeKind_Method: {result = "Method"; *size_out = sizeof("Method")-1;}break; +case RDI_TypeKind_MemberPtr: {result = "MemberPtr"; *size_out = sizeof("MemberPtr")-1;}break; +case RDI_TypeKind_Struct: {result = "Struct"; *size_out = sizeof("Struct")-1;}break; +case RDI_TypeKind_Class: {result = "Class"; *size_out = sizeof("Class")-1;}break; +case RDI_TypeKind_Union: {result = "Union"; *size_out = sizeof("Union")-1;}break; +case RDI_TypeKind_Enum: {result = "Enum"; *size_out = sizeof("Enum")-1;}break; +case RDI_TypeKind_Alias: {result = "Alias"; *size_out = sizeof("Alias")-1;}break; +case RDI_TypeKind_IncompleteStruct: {result = "IncompleteStruct"; *size_out = sizeof("IncompleteStruct")-1;}break; +case RDI_TypeKind_IncompleteUnion: {result = "IncompleteUnion"; *size_out = sizeof("IncompleteUnion")-1;}break; +case RDI_TypeKind_IncompleteClass: {result = "IncompleteClass"; *size_out = sizeof("IncompleteClass")-1;}break; +case RDI_TypeKind_IncompleteEnum: {result = "IncompleteEnum"; *size_out = sizeof("IncompleteEnum")-1;}break; +case RDI_TypeKind_Bitfield: {result = "Bitfield"; *size_out = sizeof("Bitfield")-1;}break; +case RDI_TypeKind_Variadic: {result = "Variadic"; *size_out = sizeof("Variadic")-1;}break; +case RDI_TypeKind_Count: {result = "Count"; *size_out = sizeof("Count")-1;}break; +} +return result; +} + RDI_PROC RDI_U32 rdi_size_from_basic_type_kind(RDI_TypeKind kind) { diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 340d0883..40a1bf0f 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -444,7 +444,8 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r RDI_PROC RDI_TypeKind rdim_short_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; @@ -459,7 +460,8 @@ rdim_short_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; @@ -474,7 +476,8 @@ rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_int_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; @@ -489,7 +492,8 @@ rdim_int_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; @@ -504,7 +508,8 @@ rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_long_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; @@ -519,7 +524,8 @@ rdim_long_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; @@ -534,7 +540,8 @@ rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_long_long_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; @@ -549,7 +556,8 @@ rdim_long_long_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; @@ -564,7 +572,8 @@ rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) RDI_PROC RDI_TypeKind rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model) { - switch (data_model) { + switch(data_model) + { case RDIM_DataModel_Null : break; case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; @@ -1298,6 +1307,48 @@ rdim_count_from_location_block_chunk_list(RDIM_String8List *list) //////////////////////////////// +RDI_PROC RDIM_Type * +rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind) +{ + RDI_U64 type_idx = 0; + if (type_kind != RDI_TypeKind_NULL) { + type_idx = (type_kind - RDI_TypeKind_FirstBuiltIn) + 1; + } + RDIM_Type *builtin = &list.first->v[type_idx]; + return builtin; +} + +RDI_PROC RDIM_TypeChunkList +rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) +{ + RDIM_TypeChunkList list = {0}; + + RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; + + RDIM_Type *null_type = rdim_type_chunk_list_push(arena, &list, type_cap); + + for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) + { + RDIM_String8 name = {0}; + name.str = rdi_string_from_type_kind(type_kind, &name.size); + + RDIM_Type *type = rdim_type_chunk_list_push(arena, &list, type_cap); + type->name = name; + type->kind = type_kind; + type->byte_size = rdi_size_from_basic_type_kind(type_kind); + } + + RDIM_Type *void_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Void); + void_type->byte_size = rdi_addr_size_from_arch(arch); + + RDIM_Type *handle_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Handle); + handle_type->byte_size = rdi_addr_size_from_arch(arch); + + return list; +} + +//////////////////////////////// + RDI_PROC void rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) { diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 943b373f..43afb3c9 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -1459,6 +1459,11 @@ RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList RDI_PROC RDI_LocationBlock * rdim_location_block_chunk_list_push_array(RDIM_Arena *arena, RDIM_String8List *list, RDI_U32 count); RDI_PROC RDI_U32 rdim_count_from_location_block_chunk_list(RDIM_String8List *list); +//////////////////////////////// + +RDI_PROC RDIM_TypeChunkList rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch); +RDI_PROC RDIM_Type * rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind); + //////////////////////////////// // Type Index diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 98ad228c..4cfd0ca6 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -38,8 +38,8 @@ d2r_rdi_reg_from_dw_reg_code(Arch arch, U64 reg_code) case Arch_Null: return 0; case Arch_x64: return d2r_rdi_reg_from_dw_reg_code_x64(reg_code); case Arch_x86: return d2r_rdi_reg_from_dw_reg_code_x86(reg_code); + default: InvalidPath; } - InvalidPath; return 0; } @@ -89,7 +89,7 @@ d2r_type_from_attrib(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, D Assert(!"unexpected attrib class"); } } else if (attrib->attrib_kind == DW_Attrib_Null) { - type = type_table->void_type; + type = rdim_builtin_type_from_kind(*type_table->types, RDI_TypeKind_NULL); } return type; @@ -1154,7 +1154,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) RDIM_UnitChunkList units = {0}; RDIM_UDTChunkList udts = {0}; - RDIM_TypeChunkList types = {0}; + RDIM_TypeChunkList types = rdim_init_type_chunk_list(arena, arch); RDIM_SymbolChunkList gvars = {0}; RDIM_SymbolChunkList tvars = {0}; RDIM_SymbolChunkList procs = {0}; @@ -1356,8 +1356,6 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) type_table->ht = hash_table_init(comp_temp.arena, 0x4000); type_table->types = &types; type_table->type_chunk_cap = TYPE_CHUNK_CAP; - type_table->void_type = d2r_create_type(arena, type_table); - type_table->void_type->kind = RDI_TypeKind_Void; type_table->varg_type = d2r_create_type(arena, type_table); type_table->varg_type->kind = RDI_TypeKind_Variadic; @@ -1597,7 +1595,7 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling } - RDIM_Type *base_type = d2r_create_type(arena, type_table); + RDIM_Type *base_type = rdim_builtin_type_from_kind(types, kind); base_type->kind = kind; base_type->byte_size = byte_size; diff --git a/src/radcon/radcon_dwarf.h b/src/radcon/radcon_dwarf.h index b9a3912c..3029b314 100644 --- a/src/radcon/radcon_dwarf.h +++ b/src/radcon/radcon_dwarf.h @@ -9,7 +9,6 @@ typedef struct D2R_TypeTable HashTable *ht; RDIM_TypeChunkList *types; U64 type_chunk_cap; - RDIM_Type *void_type; RDIM_Type *varg_type; } D2R_TypeTable; diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index 4a24ed43..ca9a4f7d 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -2445,27 +2445,24 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) // from regular type info. // RDIM_Type **itype_type_ptrs = 0; - RDIM_TypeChunkList all_types = {0}; + RDIM_TypeChunkList all_types = rdim_init_type_chunk_list(arena, arch); #define p2r_type_ptr_from_itype(itype) (((itype) < tpi_leaf->itype_opl) ? itype_type_ptrs[itype] : 0) if(in->flags & RC_Flag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); ////////////////////////// - //- build basic type + //- build basic types // { - RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - - RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); - RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); - RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); - RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); - RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); - RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); - RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); - RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); - RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); + RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); + RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); + RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); + RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); + RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); + RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); + RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); struct { @@ -2508,8 +2505,8 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, - { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, - { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, + { "int" , RDI_TypeKind_S32 , CV_BasicType_INT32 , 1, 1, 1 }, + { "unsigned int" , RDI_TypeKind_U32 , CV_BasicType_UINT32 , 1, 1, 1 }, { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, @@ -2524,22 +2521,11 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) for(U64 i = 0; i < ArrayCount(table); i += 1) { - U64 builtin_size; - if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) - { - builtin_size = arch_addr_size; - } - else - { - builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); - } - - RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - builtin->kind = table[i].kind_rdi; - builtin->name = str8_cstring(table[i].name); - builtin->byte_size = builtin_size; - - itype_type_ptrs[table[i].kind_cv] = builtin; + RDIM_Type *type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + type->kind = RDI_TypeKind_Alias; + type->name = str8_cstring(table[i].name); + type->direct_type = rdim_builtin_type_from_kind(all_types, table[i].kind_rdi); + itype_type_ptrs[table[i].kind_cv] = type; if(table[i].make_pointer_near) { @@ -2547,8 +2533,7 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_near->kind = RDI_TypeKind_Ptr; ptr_near->byte_size = 2; - ptr_near->direct_type = builtin; - + ptr_near->direct_type = type; itype_type_ptrs[near_ptr_itype] = ptr_near; } if(table[i].make_pointer_32) @@ -2557,8 +2542,7 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_32->kind = RDI_TypeKind_Ptr; ptr_32->byte_size = 4; - ptr_32->direct_type = builtin; - + ptr_32->direct_type = type; itype_type_ptrs[ptr_32_itype] = ptr_32; } if(table[i].make_pointer_64) @@ -2567,15 +2551,14 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_64->kind = RDI_TypeKind_Ptr; ptr_64->byte_size = 8; - ptr_64->direct_type = builtin; - + ptr_64->direct_type = type; itype_type_ptrs[ptr_64_itype] = ptr_64; } } } ////////////////////////// - //- rjf: build non-basic type + //- rjf: build complex type // for(CV_TypeId itype = tpi_leaf->itype_first; itype < tpi_leaf->itype_opl; itype += 1) { diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 4fadfabd..1a32964f 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1489,6 +1489,23 @@ rdi_hash(RDI_U8 *ptr, RDI_U64 size) } ``` +@gen(functions) @c_file +{ + `RDI_PROC RDI_U8 *`; + `rdi_string_from_type_kind(RDI_TypeKind kind, RDI_U64 *size_out)`; + `{`; + `RDI_U8 *result = 0;`; + `*size_out = 0;`; + `switch (kind)`; + `{`; + `default:{}break;`; + @expand(RDI_TypeKindTable a) ` case RDI_TypeKind_$(a.name): {result = "$(a.name)"; *size_out = sizeof("$(a.name)")-1;}break;`, + `}`; + `return result;`; + `}`; + ``; +} + @gen(functions) @c_file { `RDI_PROC RDI_U32`; From 3c7c2918f67e424c8e0d4909158f1c89d51725d4 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 13:47:40 -0700 Subject: [PATCH 276/755] replace pointers to incomplete types in UDT members --- src/rdi_make/rdi_make_local.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index 3de6d4af..302126fe 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -464,7 +464,7 @@ rdim_local_hash(RDIM_String8 string) } internal void -rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) +rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList *udts) { ProfBeginFunction(); @@ -603,6 +603,27 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) } } } + for(RDIM_UDTChunkNode *chunk = udts->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; ++i) + { + RDIM_UDT *udt = &chunk->v[i]; + RDI_U64 self_idx = rdim_idx_from_type(udt->self_type); + if(fwd_map[self_idx]) + { + udt->self_type = fwd_map[self_idx]; + } + + for(RDIM_UDTMember *member = udt->first_member; member != 0; member = member->next) + { + RDI_U64 member_idx = rdim_idx_from_type(member->type); + if(fwd_map[member_idx]) + { + member->type = fwd_map[member_idx]; + } + } + } + } ProfEnd(); scratch_end(scratch); @@ -635,7 +656,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) //////////////////////////////// // resolve incomplete types - rdim_local_resolve_incomplete_types(&in_params->types); + rdim_local_resolve_incomplete_types(&in_params->types, &in_params->udts); //////////////////////////////// // compute type indices From 5ba981357db0b103c094f3573aeb85cd92ec1396 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 15:01:16 -0700 Subject: [PATCH 277/755] fix string cast warning --- src/lib_rdi_format/rdi_format.c | 112 ++++++++++++++++---------------- src/lib_rdi_format/rdi_format.h | 1 + src/raddump/raddump.c | 18 ++--- src/raddump/raddump.h | 2 +- src/rdi_format/rdi_format.mdesk | 3 +- 5 files changed, 64 insertions(+), 72 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 74fc9ed3..3765d03e 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -188,62 +188,62 @@ RDI_U8 *result = 0; switch (kind) { default:{}break; -case RDI_TypeKind_NULL: {result = "NULL"; *size_out = sizeof("NULL")-1;}break; -case RDI_TypeKind_Void: {result = "Void"; *size_out = sizeof("Void")-1;}break; -case RDI_TypeKind_Handle: {result = "Handle"; *size_out = sizeof("Handle")-1;}break; -case RDI_TypeKind_HResult: {result = "HResult"; *size_out = sizeof("HResult")-1;}break; -case RDI_TypeKind_Char8: {result = "Char8"; *size_out = sizeof("Char8")-1;}break; -case RDI_TypeKind_Char16: {result = "Char16"; *size_out = sizeof("Char16")-1;}break; -case RDI_TypeKind_Char32: {result = "Char32"; *size_out = sizeof("Char32")-1;}break; -case RDI_TypeKind_UChar8: {result = "UChar8"; *size_out = sizeof("UChar8")-1;}break; -case RDI_TypeKind_UChar16: {result = "UChar16"; *size_out = sizeof("UChar16")-1;}break; -case RDI_TypeKind_UChar32: {result = "UChar32"; *size_out = sizeof("UChar32")-1;}break; -case RDI_TypeKind_U8: {result = "U8"; *size_out = sizeof("U8")-1;}break; -case RDI_TypeKind_U16: {result = "U16"; *size_out = sizeof("U16")-1;}break; -case RDI_TypeKind_U32: {result = "U32"; *size_out = sizeof("U32")-1;}break; -case RDI_TypeKind_U64: {result = "U64"; *size_out = sizeof("U64")-1;}break; -case RDI_TypeKind_U128: {result = "U128"; *size_out = sizeof("U128")-1;}break; -case RDI_TypeKind_U256: {result = "U256"; *size_out = sizeof("U256")-1;}break; -case RDI_TypeKind_U512: {result = "U512"; *size_out = sizeof("U512")-1;}break; -case RDI_TypeKind_S8: {result = "S8"; *size_out = sizeof("S8")-1;}break; -case RDI_TypeKind_S16: {result = "S16"; *size_out = sizeof("S16")-1;}break; -case RDI_TypeKind_S32: {result = "S32"; *size_out = sizeof("S32")-1;}break; -case RDI_TypeKind_S64: {result = "S64"; *size_out = sizeof("S64")-1;}break; -case RDI_TypeKind_S128: {result = "S128"; *size_out = sizeof("S128")-1;}break; -case RDI_TypeKind_S256: {result = "S256"; *size_out = sizeof("S256")-1;}break; -case RDI_TypeKind_S512: {result = "S512"; *size_out = sizeof("S512")-1;}break; -case RDI_TypeKind_Bool: {result = "Bool"; *size_out = sizeof("Bool")-1;}break; -case RDI_TypeKind_F16: {result = "F16"; *size_out = sizeof("F16")-1;}break; -case RDI_TypeKind_F32: {result = "F32"; *size_out = sizeof("F32")-1;}break; -case RDI_TypeKind_F32PP: {result = "F32PP"; *size_out = sizeof("F32PP")-1;}break; -case RDI_TypeKind_F48: {result = "F48"; *size_out = sizeof("F48")-1;}break; -case RDI_TypeKind_F64: {result = "F64"; *size_out = sizeof("F64")-1;}break; -case RDI_TypeKind_F80: {result = "F80"; *size_out = sizeof("F80")-1;}break; -case RDI_TypeKind_F128: {result = "F128"; *size_out = sizeof("F128")-1;}break; -case RDI_TypeKind_ComplexF32: {result = "ComplexF32"; *size_out = sizeof("ComplexF32")-1;}break; -case RDI_TypeKind_ComplexF64: {result = "ComplexF64"; *size_out = sizeof("ComplexF64")-1;}break; -case RDI_TypeKind_ComplexF80: {result = "ComplexF80"; *size_out = sizeof("ComplexF80")-1;}break; -case RDI_TypeKind_ComplexF128: {result = "ComplexF128"; *size_out = sizeof("ComplexF128")-1;}break; -case RDI_TypeKind_Modifier: {result = "Modifier"; *size_out = sizeof("Modifier")-1;}break; -case RDI_TypeKind_Ptr: {result = "Ptr"; *size_out = sizeof("Ptr")-1;}break; -case RDI_TypeKind_LRef: {result = "LRef"; *size_out = sizeof("LRef")-1;}break; -case RDI_TypeKind_RRef: {result = "RRef"; *size_out = sizeof("RRef")-1;}break; -case RDI_TypeKind_Array: {result = "Array"; *size_out = sizeof("Array")-1;}break; -case RDI_TypeKind_Function: {result = "Function"; *size_out = sizeof("Function")-1;}break; -case RDI_TypeKind_Method: {result = "Method"; *size_out = sizeof("Method")-1;}break; -case RDI_TypeKind_MemberPtr: {result = "MemberPtr"; *size_out = sizeof("MemberPtr")-1;}break; -case RDI_TypeKind_Struct: {result = "Struct"; *size_out = sizeof("Struct")-1;}break; -case RDI_TypeKind_Class: {result = "Class"; *size_out = sizeof("Class")-1;}break; -case RDI_TypeKind_Union: {result = "Union"; *size_out = sizeof("Union")-1;}break; -case RDI_TypeKind_Enum: {result = "Enum"; *size_out = sizeof("Enum")-1;}break; -case RDI_TypeKind_Alias: {result = "Alias"; *size_out = sizeof("Alias")-1;}break; -case RDI_TypeKind_IncompleteStruct: {result = "IncompleteStruct"; *size_out = sizeof("IncompleteStruct")-1;}break; -case RDI_TypeKind_IncompleteUnion: {result = "IncompleteUnion"; *size_out = sizeof("IncompleteUnion")-1;}break; -case RDI_TypeKind_IncompleteClass: {result = "IncompleteClass"; *size_out = sizeof("IncompleteClass")-1;}break; -case RDI_TypeKind_IncompleteEnum: {result = "IncompleteEnum"; *size_out = sizeof("IncompleteEnum")-1;}break; -case RDI_TypeKind_Bitfield: {result = "Bitfield"; *size_out = sizeof("Bitfield")-1;}break; -case RDI_TypeKind_Variadic: {result = "Variadic"; *size_out = sizeof("Variadic")-1;}break; -case RDI_TypeKind_Count: {result = "Count"; *size_out = sizeof("Count")-1;}break; +case RDI_TypeKind_NULL: {result = (RDI_U8*)"NULL"; *size_out = sizeof("NULL")-1;}break; +case RDI_TypeKind_Void: {result = (RDI_U8*)"Void"; *size_out = sizeof("Void")-1;}break; +case RDI_TypeKind_Handle: {result = (RDI_U8*)"Handle"; *size_out = sizeof("Handle")-1;}break; +case RDI_TypeKind_HResult: {result = (RDI_U8*)"HResult"; *size_out = sizeof("HResult")-1;}break; +case RDI_TypeKind_Char8: {result = (RDI_U8*)"Char8"; *size_out = sizeof("Char8")-1;}break; +case RDI_TypeKind_Char16: {result = (RDI_U8*)"Char16"; *size_out = sizeof("Char16")-1;}break; +case RDI_TypeKind_Char32: {result = (RDI_U8*)"Char32"; *size_out = sizeof("Char32")-1;}break; +case RDI_TypeKind_UChar8: {result = (RDI_U8*)"UChar8"; *size_out = sizeof("UChar8")-1;}break; +case RDI_TypeKind_UChar16: {result = (RDI_U8*)"UChar16"; *size_out = sizeof("UChar16")-1;}break; +case RDI_TypeKind_UChar32: {result = (RDI_U8*)"UChar32"; *size_out = sizeof("UChar32")-1;}break; +case RDI_TypeKind_U8: {result = (RDI_U8*)"U8"; *size_out = sizeof("U8")-1;}break; +case RDI_TypeKind_U16: {result = (RDI_U8*)"U16"; *size_out = sizeof("U16")-1;}break; +case RDI_TypeKind_U32: {result = (RDI_U8*)"U32"; *size_out = sizeof("U32")-1;}break; +case RDI_TypeKind_U64: {result = (RDI_U8*)"U64"; *size_out = sizeof("U64")-1;}break; +case RDI_TypeKind_U128: {result = (RDI_U8*)"U128"; *size_out = sizeof("U128")-1;}break; +case RDI_TypeKind_U256: {result = (RDI_U8*)"U256"; *size_out = sizeof("U256")-1;}break; +case RDI_TypeKind_U512: {result = (RDI_U8*)"U512"; *size_out = sizeof("U512")-1;}break; +case RDI_TypeKind_S8: {result = (RDI_U8*)"S8"; *size_out = sizeof("S8")-1;}break; +case RDI_TypeKind_S16: {result = (RDI_U8*)"S16"; *size_out = sizeof("S16")-1;}break; +case RDI_TypeKind_S32: {result = (RDI_U8*)"S32"; *size_out = sizeof("S32")-1;}break; +case RDI_TypeKind_S64: {result = (RDI_U8*)"S64"; *size_out = sizeof("S64")-1;}break; +case RDI_TypeKind_S128: {result = (RDI_U8*)"S128"; *size_out = sizeof("S128")-1;}break; +case RDI_TypeKind_S256: {result = (RDI_U8*)"S256"; *size_out = sizeof("S256")-1;}break; +case RDI_TypeKind_S512: {result = (RDI_U8*)"S512"; *size_out = sizeof("S512")-1;}break; +case RDI_TypeKind_Bool: {result = (RDI_U8*)"Bool"; *size_out = sizeof("Bool")-1;}break; +case RDI_TypeKind_F16: {result = (RDI_U8*)"F16"; *size_out = sizeof("F16")-1;}break; +case RDI_TypeKind_F32: {result = (RDI_U8*)"F32"; *size_out = sizeof("F32")-1;}break; +case RDI_TypeKind_F32PP: {result = (RDI_U8*)"F32PP"; *size_out = sizeof("F32PP")-1;}break; +case RDI_TypeKind_F48: {result = (RDI_U8*)"F48"; *size_out = sizeof("F48")-1;}break; +case RDI_TypeKind_F64: {result = (RDI_U8*)"F64"; *size_out = sizeof("F64")-1;}break; +case RDI_TypeKind_F80: {result = (RDI_U8*)"F80"; *size_out = sizeof("F80")-1;}break; +case RDI_TypeKind_F128: {result = (RDI_U8*)"F128"; *size_out = sizeof("F128")-1;}break; +case RDI_TypeKind_ComplexF32: {result = (RDI_U8*)"ComplexF32"; *size_out = sizeof("ComplexF32")-1;}break; +case RDI_TypeKind_ComplexF64: {result = (RDI_U8*)"ComplexF64"; *size_out = sizeof("ComplexF64")-1;}break; +case RDI_TypeKind_ComplexF80: {result = (RDI_U8*)"ComplexF80"; *size_out = sizeof("ComplexF80")-1;}break; +case RDI_TypeKind_ComplexF128: {result = (RDI_U8*)"ComplexF128"; *size_out = sizeof("ComplexF128")-1;}break; +case RDI_TypeKind_Modifier: {result = (RDI_U8*)"Modifier"; *size_out = sizeof("Modifier")-1;}break; +case RDI_TypeKind_Ptr: {result = (RDI_U8*)"Ptr"; *size_out = sizeof("Ptr")-1;}break; +case RDI_TypeKind_LRef: {result = (RDI_U8*)"LRef"; *size_out = sizeof("LRef")-1;}break; +case RDI_TypeKind_RRef: {result = (RDI_U8*)"RRef"; *size_out = sizeof("RRef")-1;}break; +case RDI_TypeKind_Array: {result = (RDI_U8*)"Array"; *size_out = sizeof("Array")-1;}break; +case RDI_TypeKind_Function: {result = (RDI_U8*)"Function"; *size_out = sizeof("Function")-1;}break; +case RDI_TypeKind_Method: {result = (RDI_U8*)"Method"; *size_out = sizeof("Method")-1;}break; +case RDI_TypeKind_MemberPtr: {result = (RDI_U8*)"MemberPtr"; *size_out = sizeof("MemberPtr")-1;}break; +case RDI_TypeKind_Struct: {result = (RDI_U8*)"Struct"; *size_out = sizeof("Struct")-1;}break; +case RDI_TypeKind_Class: {result = (RDI_U8*)"Class"; *size_out = sizeof("Class")-1;}break; +case RDI_TypeKind_Union: {result = (RDI_U8*)"Union"; *size_out = sizeof("Union")-1;}break; +case RDI_TypeKind_Enum: {result = (RDI_U8*)"Enum"; *size_out = sizeof("Enum")-1;}break; +case RDI_TypeKind_Alias: {result = (RDI_U8*)"Alias"; *size_out = sizeof("Alias")-1;}break; +case RDI_TypeKind_IncompleteStruct: {result = (RDI_U8*)"IncompleteStruct"; *size_out = sizeof("IncompleteStruct")-1;}break; +case RDI_TypeKind_IncompleteUnion: {result = (RDI_U8*)"IncompleteUnion"; *size_out = sizeof("IncompleteUnion")-1;}break; +case RDI_TypeKind_IncompleteClass: {result = (RDI_U8*)"IncompleteClass"; *size_out = sizeof("IncompleteClass")-1;}break; +case RDI_TypeKind_IncompleteEnum: {result = (RDI_U8*)"IncompleteEnum"; *size_out = sizeof("IncompleteEnum")-1;}break; +case RDI_TypeKind_Bitfield: {result = (RDI_U8*)"Bitfield"; *size_out = sizeof("Bitfield")-1;}break; +case RDI_TypeKind_Variadic: {result = (RDI_U8*)"Variadic"; *size_out = sizeof("Variadic")-1;}break; +case RDI_TypeKind_Count: {result = (RDI_U8*)"Count"; *size_out = sizeof("Count")-1;}break; } return result; } diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index e985b125..23149735 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -1540,6 +1540,7 @@ RDI_PROC RDI_U32 rdi_addr_size_from_arch(RDI_Arch arch); RDI_PROC RDI_EvalConversionKind rdi_eval_conversion_kind_from_typegroups(RDI_EvalTypeGroup in, RDI_EvalTypeGroup out); RDI_PROC RDI_S32 rdi_eval_op_typegroup_are_compatible(RDI_EvalOp op, RDI_EvalTypeGroup group); RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConversionKind kind, RDI_U64 *size_out); +RDI_PROC RDI_U8 *rdi_string_from_type_kind(RDI_TypeKind kind, RDI_U64 *size_out); extern RDI_U16 rdi_section_element_size_table[37]; extern RDI_U8 rdi_section_is_required_table[37]; diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 967ee7a6..b89c057a 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -665,19 +665,6 @@ rdi_string_from_local_kind(Arena *arena, RDI_LocalKind v) return result; } -internal String8 -rdi_string_from_type_kind(Arena *arena, RDI_TypeKind v) -{ - String8 result; - switch (v) { - default: { result = push_str8f(arena, "%u", v); } break; -#define X(name) case RDI_TypeKind_##name: { result = str8_lit(#name); } break; - RDI_TypeKind_XList -#undef X - } - return result; -} - internal String8 rdi_string_from_member_kind(Arena *arena, RDI_MemberKind v) { @@ -1001,7 +988,10 @@ rdi_print_type_node(Arena *arena, String8List *out, String8 indent, RDI_Parsed * { Temp scratch = scratch_begin(&arena, 1); - rd_printf("kind =%S", rdi_string_from_type_kind(scratch.arena, type->kind)); + String8 type_kind_str = {0}; + type_kind_str.str = rdi_string_from_type_kind(type->kind, &type_kind_str.size); + + rd_printf("kind =%S", type_kind_str); if (type->kind == RDI_TypeKind_Modifier) { rd_printf("flags =%S", rdi_string_from_type_modifier_flags(scratch.arena, type->flags)); } else { diff --git a/src/raddump/raddump.h b/src/raddump/raddump.h index 684d154f..910c5ccc 100644 --- a/src/raddump/raddump.h +++ b/src/raddump/raddump.h @@ -191,7 +191,7 @@ internal String8 rdi_string_from_data_section_kind(Arena *arena, RDI_SectionKind internal String8 rdi_string_from_arch (Arena *arena, RDI_Arch v); internal String8 rdi_string_from_language (Arena *arena, RDI_Language v); internal String8 rdi_string_from_local_kind (Arena *arena, RDI_LocalKind v); -internal String8 rdi_string_from_type_kind (Arena *arena, RDI_TypeKind v); +//internal String8 rdi_string_from_type_kind (Arena *arena, RDI_TypeKind v); internal String8 rdi_string_from_member_kind (Arena *arena, RDI_MemberKind v); internal String8 rdi_string_from_binary_section_flags(Arena *arena, RDI_BinarySectionFlags flags); diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 1a32964f..5639d5df 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1472,6 +1472,7 @@ RDI_PROC RDI_U32 rdi_addr_size_from_arch(RDI_Arch arch); RDI_PROC RDI_EvalConversionKind rdi_eval_conversion_kind_from_typegroups(RDI_EvalTypeGroup in, RDI_EvalTypeGroup out); RDI_PROC RDI_S32 rdi_eval_op_typegroup_are_compatible(RDI_EvalOp op, RDI_EvalTypeGroup group); RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConversionKind kind, RDI_U64 *size_out); +RDI_PROC RDI_U8 *rdi_string_from_type_kind(RDI_TypeKind kind, RDI_U64 *size_out); ``` @gen(functions) @c_file @@ -1499,7 +1500,7 @@ rdi_hash(RDI_U8 *ptr, RDI_U64 size) `switch (kind)`; `{`; `default:{}break;`; - @expand(RDI_TypeKindTable a) ` case RDI_TypeKind_$(a.name): {result = "$(a.name)"; *size_out = sizeof("$(a.name)")-1;}break;`, + @expand(RDI_TypeKindTable a) ` case RDI_TypeKind_$(a.name): {result = (RDI_U8*)"$(a.name)"; *size_out = sizeof("$(a.name)")-1;}break;`, `}`; `return result;`; `}`; From 12628c679cc294c02cf9203a01a50026f5848d87 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 27 Mar 2025 15:10:57 -0700 Subject: [PATCH 278/755] Update builds.yml remove rdi_from_dwarf --- .github/workflows/builds.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 29973c03..423c43d1 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -24,11 +24,9 @@ jobs: call build raddbg clang debug || exit /b 1 call build rdi_from_pdb msvc debug || exit /b 1 call build rdi_from_pdb clang debug || exit /b 1 - call build rdi_from_dwarf msvc debug || exit /b 1 - call build rdi_from_dwarf clang debug || exit /b 1 call build rdi_dump msvc debug || exit /b 1 call build rdi_dump clang debug || exit /b 1 call build radlink msvc debug || exit /b 1 call build radlink clang debug || exit /b 1 call build rdi_breakpad_from_pdb msvc debug || exit /b 1 - call build rdi_breakpad_from_pdb clang debug || exit /b 1 \ No newline at end of file + call build rdi_breakpad_from_pdb clang debug || exit /b 1 From 350c17a6063098ffe6dd2c30a75c03ae402a2255 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 27 Mar 2025 15:17:50 -0700 Subject: [PATCH 279/755] Update builds.yml replaced rdi_dump with raddump --- .github/workflows/builds.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 423c43d1..e38219f2 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -24,8 +24,8 @@ jobs: call build raddbg clang debug || exit /b 1 call build rdi_from_pdb msvc debug || exit /b 1 call build rdi_from_pdb clang debug || exit /b 1 - call build rdi_dump msvc debug || exit /b 1 - call build rdi_dump clang debug || exit /b 1 + call build raddump msvc debug || exit /b 1 + call build raddump clang debug || exit /b 1 call build radlink msvc debug || exit /b 1 call build radlink clang debug || exit /b 1 call build rdi_breakpad_from_pdb msvc debug || exit /b 1 From dab65d65235a8e6ad6ef489cb0c7f830fc9a1066 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 15:16:53 -0700 Subject: [PATCH 280/755] deleted rdi_dump, all features of this dumper are now part of raddump --- build.bat | 1 - src/rdi_dump/rdi_dump.c | 843 ----------------------------------- src/rdi_dump/rdi_dump.h | 85 ---- src/rdi_dump/rdi_dump_main.c | 515 --------------------- 4 files changed, 1444 deletions(-) delete mode 100644 src/rdi_dump/rdi_dump.c delete mode 100644 src/rdi_dump/rdi_dump.h delete mode 100644 src/rdi_dump/rdi_dump_main.c diff --git a/build.bat b/build.bat index f77e5df9..0c9fc09f 100644 --- a/build.bat +++ b/build.bat @@ -111,7 +111,6 @@ if "%radcon%"=="1" set didbuild=1 && %compile% ..\src\radcon if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf_main.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 -if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1 if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1 if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1 if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 diff --git a/src/rdi_dump/rdi_dump.c b/src/rdi_dump/rdi_dump.c deleted file mode 100644 index 8cfd3d59..00000000 --- a/src/rdi_dump/rdi_dump.c +++ /dev/null @@ -1,843 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: RDI Enum -> String Functions - -internal String8 -rdi_string_from_reg_code_x86(U64 reg_code) -{ -#define X(name, value) case RDI_RegCodeX86_##name: return str8_lit(#name); - switch (reg_code) { - RDI_RegCodeX86_XList - } -#undef X - return str8_lit(""); -} - -internal String8 -rdi_string_from_reg_code_x64(U64 reg_code) -{ -#define X(name, value) case RDI_RegCodeX64_##name: return str8_lit(#name); - switch (reg_code) { - RDI_RegCodeX64_XList - } -#undef X - return str8_lit(""); -} - -internal String8 -rdi_string_from_reg_code(RDI_Arch arch, U64 reg_code) -{ - switch (arch) { - case RDI_Arch_NULL: break; - case RDI_Arch_X86: return rdi_string_from_reg_code_x86(reg_code); - case RDI_Arch_X64: return rdi_string_from_reg_code_x64(reg_code); - default: InvalidPath; - } - return str8_lit(""); -} - -internal String8 -rdi_string_from_data_section_kind(RDI_SectionKind v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name, lower, type) case RDI_SectionKind_##name:{result = str8_lit(#name);}break; - RDI_SectionKind_XList -#undef X - } - return result; -} - -internal String8 -rdi_string_from_arch(RDI_Arch v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name) case RDI_Arch_##name:{result = str8_lit(#name);}break; - RDI_Arch_XList -#undef X - } - return result; -} - -internal String8 -rdi_string_from_language(RDI_Language v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name) case RDI_Language_##name:{result = str8_lit(#name);}break; - RDI_Language_XList -#undef X - } - return result; -} - -internal String8 -rdi_string_from_type_kind(RDI_TypeKind v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name) case RDI_TypeKind_##name:{result = str8_lit(#name);}break; - RDI_TypeKind_XList -#undef X - } - return result; -} - -internal String8 -rdi_string_from_member_kind(RDI_MemberKind v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name) case RDI_MemberKind_##name:{result = str8_lit(#name);}break; - RDI_MemberKind_XList -#undef X - } - return result; -} - -internal String8 -rdi_string_from_local_kind(RDI_LocalKind v) -{ - String8 result = str8_lit(""); - switch(v) - { - default:{}break; -#define X(name) case RDI_LocalKind_##name:{result = str8_lit(#name);}break; - RDI_LocalKind_XList -#undef X - } - return result; -} - -//////////////////////////////// -//~ rjf: RDI Flags -> String Functions - -internal void -rdi_stringize_binary_section_flags(Arena *arena, String8List *out, RDI_BinarySectionFlags flags) -{ - if(flags == 0) { str8_list_push(arena, out, str8_lit("0")); } -#define X(name) if(flags & RDI_BinarySectionFlag_##name) { str8_list_push(arena, out, str8_lit(#name " ")); } - RDI_BinarySectionFlags_XList; -#undef X -} - -internal void -rdi_stringize_type_modifier_flags(Arena *arena, String8List *out, - RDI_TypeModifierFlags flags) -{ - if(flags == 0) { str8_list_push(arena, out, str8_lit("0")); } -#define X(name) if(flags & RDI_TypeModifierFlag_##name) { str8_list_push(arena, out, str8_lit(#name " ")); } - RDI_TypeModifierFlags_XList; -#undef X -} - -internal void -rdi_stringize_udt_flags(Arena *arena, String8List *out, RDI_UDTFlags flags) -{ - if(flags == 0) { str8_list_push(arena, out, str8_lit("0")); } -#define X(name) if(flags & RDI_UDTFlag_##name) { str8_list_push(arena, out, str8_lit(#name " ")); } - RDI_UDTFlags_XList; -#undef X -} - -internal void -rdi_stringize_link_flags(Arena *arena, String8List *out, RDI_LinkFlags flags) -{ - if(flags == 0) { str8_list_push(arena, out, str8_lit("0")); } -#define X(name) if(flags & RDI_LinkFlag_##name) { str8_list_push(arena, out, str8_lit(#name " ")); } - RDI_LinkFlags_XList; -#undef X -} - -//////////////////////////////// - -internal String8 -rdi_format_reg_code(Arena *arena, RDI_Arch arch, U64 reg_code) -{ - String8 result = {0}; - String8 reg_name = rdi_string_from_reg_code(arch, reg_code); - if (reg_name.size) { - result = push_str8f(arena, "%S", reg_name, reg_code); - } else { - result = push_str8f(arena, "??? (%llu)", reg_code); - } - return result; -} - -//////////////////////////////// -//~ rjf: RADDBG Compound Stringize Functions - -global char rdi_stringize_spaces[] = " "; - -internal void -rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *rdi, U32 indent_level) -{ - for(U64 idx = 0; idx < rdi->sections_count; idx += 1) - { - RDI_SectionKind kind = (RDI_SectionKind)idx; - RDI_Section *section = &rdi->sections[idx]; - String8 kind_str = rdi_string_from_data_section_kind(kind); - str8_list_pushf(arena, out, "%.*sdata_section[%5I64u] = {0x%08llx, %7u, %7u} %S\n", - indent_level, rdi_stringize_spaces, - idx, section->off, section->encoded_size, section->unpacked_size, kind_str); - } -} - -internal void -rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_TopLevelInfo *tli, U32 indent_level) -{ - String8 arch_str = rdi_string_from_arch(tli->arch); - String8 exe_name = {0}; - exe_name.str = rdi_string_from_idx(rdi, tli->exe_name_string_idx, &exe_name.size); - String8 producer_name = {0}; - producer_name.str = rdi_string_from_idx(rdi, tli->producer_name_string_idx, &producer_name.size); - str8_list_pushf(arena, out, "%.*sarch=%S\n", indent_level, rdi_stringize_spaces, arch_str); - str8_list_pushf(arena, out, "%.*sexe_name='%S'\n", indent_level, rdi_stringize_spaces, exe_name); - str8_list_pushf(arena, out, "%.*svoff_max=0x%08llx\n", indent_level, rdi_stringize_spaces, tli->voff_max); - str8_list_pushf(arena, out, "%.*sproducer_name='%S'\n", indent_level, rdi_stringize_spaces, producer_name); -} - -internal void -rdi_stringize_binary_section(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_BinarySection *bin_section, U32 indent_level) -{ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, bin_section->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sname='%.*s'\n", indent_level, rdi_stringize_spaces, str8_varg(name)); - - str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces); - rdi_stringize_binary_section_flags(arena, out, bin_section->flags); - str8_list_pushf(arena, out, "\n"); - - str8_list_pushf(arena, out, "%.*svoff_first=0x%08x\n", indent_level, rdi_stringize_spaces, bin_section->voff_first); - str8_list_pushf(arena, out, "%.*svoff_opl =0x%08x\n", indent_level, rdi_stringize_spaces, bin_section->voff_opl); - str8_list_pushf(arena, out, "%.*sfoff_first=0x%08x\n", indent_level, rdi_stringize_spaces, bin_section->foff_first); - str8_list_pushf(arena, out, "%.*sfoff_opl =0x%08x\n", indent_level, rdi_stringize_spaces, bin_section->foff_opl); -} - -internal void -rdi_stringize_file_path(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_FilePathBundle *bundle, RDI_FilePathNode *file_path, U32 indent_level) -{ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, file_path->name_string_idx, &name.size); - U32 this_idx = (U32)(file_path - bundle->file_paths); - if(file_path->source_file_idx == 0) - { - str8_list_pushf(arena, out, "%.*s[%u] '%.*s'\n", - indent_level, rdi_stringize_spaces, - this_idx, str8_varg(name)); - } - else - { - str8_list_pushf(arena, out, "%.*s[%u] '%.*s'; source_file=%u\n", - indent_level, rdi_stringize_spaces, - this_idx, str8_varg(name), file_path->source_file_idx); - } - - for(U32 child = file_path->first_child; child != 0;) - { - // get node for child - RDI_FilePathNode *child_node = 0; - if (child < bundle->file_path_count){ - child_node = bundle->file_paths + child; - } - if (child_node == 0){ - break; - } - - // stringize child - rdi_stringize_file_path(arena, out, rdi, bundle, child_node, indent_level + 1); - - // increment iterator - child = child_node->next_sibling; - } -} - -internal void -rdi_stringize_source_file(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_SourceFile *source_file, U32 indent_level) -{ - // file path node idx - str8_list_pushf(arena, out, "%.*sfile_path_node_idx: %u\n", indent_level, rdi_stringize_spaces, source_file->file_path_node_idx); - - // normal source path - String8 path = {0}; - path.str = rdi_string_from_idx(rdi, source_file->normal_full_path_string_idx, &path.size); - str8_list_pushf(arena, out, "%.*spath: \"%S\"\n", indent_level, rdi_stringize_spaces, path); - - // rjf: source line map idx - str8_list_pushf(arena, out, "%.*ssource_line_map: %u\n", indent_level, rdi_stringize_spaces, source_file->source_line_map_idx); -} - -internal void -rdi_stringize_line_table(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_LineTable *line_table, U32 indent_level) -{ - // rjf: parse line table - RDI_ParsedLineTable parsed_line_table = {0}; - rdi_parsed_from_line_table(rdi, line_table, &parsed_line_table); - - // rjf: stringize lines - str8_list_pushf(arena, out, "%.*slines:\n", indent_level, rdi_stringize_spaces); - for(U32 i = 0; i < parsed_line_table.count; i += 1) - { - U64 first = parsed_line_table.voffs[i]; - U64 opl = parsed_line_table.voffs[i + 1]; - RDI_Line *line = parsed_line_table.lines + i; - RDI_Column *col = 0; - if(i < parsed_line_table.col_count) - { - col = parsed_line_table.cols + i; - } - if(col == 0) - { - str8_list_pushf(arena, out, "%.*s [0x%08llx,0x%08llx) file=%u; line=%u\n", - indent_level, rdi_stringize_spaces, - first, opl, line->file_idx, line->line_num); - } - else - { - str8_list_pushf(arena, out, "%.*s [0x%08llx,0x%08llx) file=%u; line=%u; columns=[%u,%u)\n", - indent_level, rdi_stringize_spaces, - first, opl, line->file_idx, line->line_num, - col->col_first, col->col_opl); - } - } -} - -internal void -rdi_stringize_source_line_map(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_SourceLineMap *map, U32 indent_level) -{ - RDI_ParsedSourceLineMap line_map = {0}; - rdi_parsed_from_source_line_map(rdi, map, &line_map); - str8_list_pushf(arena, out, "%.*slines:\n", indent_level, rdi_stringize_spaces); - - for(U32 i = 0; i < line_map.count; i += 1) - { - U32 line_num = line_map.nums[i]; - U32 digit_count = 1; - if(line_num > 0) - { - U32 x = line_num; - for(;;) - { - x /= 10; - if(x == 0) - { - break; - } - digit_count += 1; - } - } - - str8_list_pushf(arena, out, "%.*s %u: ", indent_level, rdi_stringize_spaces, line_num); - - U32 first = line_map.ranges[i]; - U32 opl_raw = line_map.ranges[i + 1]; - U32 opl = ClampTop(opl_raw, line_map.voff_count); - for(U32 j = first; j < opl; j += 1) - { - if(j == first) - { - str8_list_pushf(arena, out, "0x%08x\n", line_map.voffs[j]); - } - else - { - str8_list_pushf(arena, out, "%.*s0x%08x\n", - indent_level + digit_count + 3, rdi_stringize_spaces, - line_map.voffs[j]); - } - } - } -} - -internal void -rdi_stringize_unit(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Unit *unit, U32 indent_level) -{ - String8 unit_name = {0}; - unit_name.str = rdi_string_from_idx(rdi, unit->unit_name_string_idx, &unit_name.size); - String8 compiler_name = {0}; - compiler_name.str = rdi_string_from_idx(rdi, unit->compiler_name_string_idx, &compiler_name.size); - - str8_list_pushf(arena, out, "%.*sunit_name='%.*s'\n", indent_level, rdi_stringize_spaces, str8_varg(unit_name)); - str8_list_pushf(arena, out, "%.*scompiler_name='%.*s'\n", indent_level, rdi_stringize_spaces, str8_varg(compiler_name)); - - str8_list_pushf(arena, out, "%.*ssource_file_path=%u\n", indent_level, rdi_stringize_spaces, unit->source_file_path_node); - str8_list_pushf(arena, out, "%.*sobject_file_path=%u\n", indent_level, rdi_stringize_spaces, unit->object_file_path_node); - str8_list_pushf(arena, out, "%.*sarchive_file_path=%u\n", indent_level, rdi_stringize_spaces, unit->archive_file_path_node); - str8_list_pushf(arena, out, "%.*sbuild_path=%u\n", indent_level, rdi_stringize_spaces, unit->build_path_node); - - String8 language_str = rdi_string_from_language(unit->language); - str8_list_pushf(arena, out, "%.*slanguage=%.*s\n", indent_level, rdi_stringize_spaces, str8_varg(language_str)); - - str8_list_pushf(arena, out, "%.*sline_table_idx=%u\n", indent_level, rdi_stringize_spaces, unit->line_table_idx); -} - -internal void -rdi_stringize_type_node(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_TypeNode *type, U32 indent_level){ - RDI_TypeKind kind = type->kind; - String8 type_kind_str = rdi_string_from_type_kind(kind); - - str8_list_pushf(arena, out, "%.*skind=%.*s\n", - indent_level, rdi_stringize_spaces, str8_varg(type_kind_str)); - - switch (type->kind){ - case RDI_TypeKind_Modifier: - { - str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces); - rdi_stringize_type_modifier_flags(arena, out, type->flags); - str8_list_push(arena, out, str8_lit("\n")); - }break; - - default: - { - if (type->flags != 0){ - str8_list_pushf(arena, out, "%.*sflags=%x (missing stringizer path)", - indent_level, rdi_stringize_spaces, type->flags); - } - }break; - } - - str8_list_pushf(arena, out, "%.*sbyte_size=%u\n", - indent_level, rdi_stringize_spaces, type->byte_size); - - if (RDI_TypeKind_FirstBuiltIn <= kind && - kind <= RDI_TypeKind_LastBuiltIn){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, type->built_in.name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sbuilt_in.name='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - } - - else if (RDI_TypeKind_FirstConstructed <= kind && - kind <= RDI_TypeKind_LastConstructed){ - str8_list_pushf(arena, out, "%.*sconstructed.direct_type=%u\n", - indent_level, rdi_stringize_spaces, type->constructed.direct_type_idx); - - if (type->kind == RDI_TypeKind_Array){ - str8_list_pushf(arena, out, "%.*sconstructed.array_count=%u\n", - indent_level, rdi_stringize_spaces, type->constructed.count); - } - - if (type->kind == RDI_TypeKind_Function || - type->kind == RDI_TypeKind_Method){ - U32 run_first = type->constructed.param_idx_run_first; - U32 run_count_raw = type->constructed.count; - - U32 run_count = 0; - U32 *run = rdi_idx_run_from_first_count(rdi, run_first, run_count_raw, &run_count); - - U32 this_type_idx = 0; - if (run_count > 0 && type->kind == RDI_TypeKind_Method){ - this_type_idx = run[0]; - run += 1; - run_count -= 1; - } - - if (this_type_idx != 0){ - str8_list_pushf(arena, out, "%.*sconstructed.this_type=%u\n", - indent_level, rdi_stringize_spaces, this_type_idx); - } - - str8_list_pushf(arena, out, "%.*sconstructed.params={", - indent_level, rdi_stringize_spaces); - - if (run_count > 0){ - U32 last = run_count - 1; - for (U32 j = 0; j < last; j += 1){ - str8_list_pushf(arena, out, " %u,", run[j]); - } - str8_list_pushf(arena, out, " %u ", run[last]); - } - - str8_list_push(arena, out, str8_lit("}\n")); - } - } - - else if (RDI_TypeKind_FirstUserDefined <= kind && - kind <= RDI_TypeKind_LastUserDefined){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, type->user_defined.name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*suser_defined.name='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - str8_list_pushf(arena, out, "%.*suser_defined.direct_type=%u\n", - indent_level, rdi_stringize_spaces, - type->user_defined.direct_type_idx); - str8_list_pushf(arena, out, "%.*suser_defined.udt=%u\n", - indent_level, rdi_stringize_spaces, - type->user_defined.udt_idx); - } - - else if (kind == RDI_TypeKind_Bitfield){ - str8_list_pushf(arena, out, "%.*sbitfield.off=%u\n", - indent_level, rdi_stringize_spaces, type->bitfield.off); - str8_list_pushf(arena, out, "%.*sbitfield.size=%u\n", - indent_level, rdi_stringize_spaces, type->bitfield.size); - } -} - -internal void -rdi_stringize_udt(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_UDTMemberBundle *member_bundle, RDI_UDT *udt, - U32 indent_level){ - str8_list_pushf(arena, out, "%.*sself_type=%u\n", - indent_level, rdi_stringize_spaces, udt->self_type_idx); - - str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces); - rdi_stringize_udt_flags(arena, out, udt->flags); - str8_list_push(arena, out, str8_lit("\n")); - - if (udt->file_idx != 0){ - str8_list_pushf(arena, out, "%.*sloc={file=%u; line=%u; col=%u}\n", - indent_level, rdi_stringize_spaces, - udt->file_idx, udt->line, udt->col); - } - - // enum members - if (udt->flags & RDI_UDTFlag_EnumMembers){ - U32 first_raw = udt->member_first; - U32 opl_raw = first_raw + udt->member_count; - U32 opl = ClampTop(opl_raw, member_bundle->enum_member_count); - U32 first = ClampTop(first_raw, opl); - - if (first < opl){ - str8_list_pushf(arena, out, "%.*smembers={\n", indent_level, rdi_stringize_spaces); - RDI_EnumMember *enum_member = member_bundle->enum_members + first; - for (U32 i = first; i < opl; i += 1, enum_member += 1){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, enum_member->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*s '%.*s' %llu\n", - indent_level, rdi_stringize_spaces, - str8_varg(name), enum_member->val); - } - str8_list_pushf(arena, out, "%.*s}\n", indent_level, rdi_stringize_spaces); - } - } - - // field members - else{ - U32 first_raw = udt->member_first; - U32 opl_raw = first_raw + udt->member_count; - U32 opl = ClampTop(opl_raw, member_bundle->member_count); - U32 first = ClampTop(first_raw, opl); - - if (first < opl){ - str8_list_pushf(arena, out, "%.*smembers={\n", indent_level, rdi_stringize_spaces); - RDI_Member *member = member_bundle->members + first; - for (U32 i = first; i < opl; i += 1, member += 1){ - str8_list_pushf(arena, out, "%.*s {\n", indent_level, rdi_stringize_spaces); - - String8 kind_str = rdi_string_from_member_kind(member->kind); - str8_list_pushf(arena, out, "%.*s kind=%.*s\n", - indent_level, rdi_stringize_spaces, str8_varg(kind_str)); - - if (member->name_string_idx != 0){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, member->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*s name='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - } - - str8_list_pushf(arena, out, "%.*s type=%u\n", - indent_level, rdi_stringize_spaces, member->type_idx); - str8_list_pushf(arena, out, "%.*s off=%u\n", - indent_level, rdi_stringize_spaces, member->off); - - str8_list_pushf(arena, out, "%.*s }\n", indent_level, rdi_stringize_spaces); - } - str8_list_pushf(arena, out, "%.*s}\n", indent_level, rdi_stringize_spaces); - } - } -} - -internal void -rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_GlobalVariable *global_variable, U32 indent_level){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, global_variable->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sname='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - - str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces); - rdi_stringize_link_flags(arena, out, global_variable->link_flags); - str8_list_push(arena, out, str8_lit("\n")); - - str8_list_pushf(arena, out, "%.*svoff=0x%08llx\n", - indent_level, rdi_stringize_spaces, global_variable->voff); - - str8_list_pushf(arena, out, "%.*stype_idx=%u\n", - indent_level, rdi_stringize_spaces, global_variable->type_idx); - - str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n", - indent_level, rdi_stringize_spaces, global_variable->container_idx); -} - -internal void -rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_ThreadVariable *thread_var, - U32 indent_level){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, thread_var->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sname='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - - str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces); - rdi_stringize_link_flags(arena, out, thread_var->link_flags); - str8_list_push(arena, out, str8_lit("\n")); - - str8_list_pushf(arena, out, "%.*stls_off=0x%08x\n", - indent_level, rdi_stringize_spaces, thread_var->tls_off); - - str8_list_pushf(arena, out, "%.*stype_idx=%u\n", - indent_level, rdi_stringize_spaces, thread_var->type_idx); - - str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n", - indent_level, rdi_stringize_spaces, thread_var->container_idx); -} - -internal void -rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_Procedure *proc, U32 indent_level){ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, proc->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sname='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - - String8 link_name = {0}; - link_name.str = rdi_string_from_idx(rdi, proc->link_name_string_idx, &link_name.size); - str8_list_pushf(arena, out, "%.*slink_name='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(link_name)); - - str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces); - rdi_stringize_link_flags(arena, out, proc->link_flags); - str8_list_push(arena, out, str8_lit("\n")); - - str8_list_pushf(arena, out, "%.*stype_idx=%u\n", - indent_level, rdi_stringize_spaces, proc->type_idx); - - str8_list_pushf(arena, out, "%.*sroot_scope_idx=%u\n", - indent_level, rdi_stringize_spaces, proc->root_scope_idx); - - str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n", - indent_level, rdi_stringize_spaces, proc->container_idx); -} - -internal void -rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Arch arch, - RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level) -{ - Temp scratch = scratch_begin(&arena, 1); - - U32 this_idx = (U32)(scope - bundle->scopes); - - str8_list_pushf(arena, out, "%.*s[%u]\n", - indent_level, rdi_stringize_spaces, this_idx); - - str8_list_pushf(arena, out, "%.*s proc_idx=%u\n", - indent_level, rdi_stringize_spaces, scope->proc_idx); - - if(scope->inline_site_idx != 0) - { - str8_list_pushf(arena, out, "%.*s inline_site_idx=%u\n", - indent_level, rdi_stringize_spaces, scope->inline_site_idx); - } - - // voff ranges - { - U32 voff_range_first_raw = scope->voff_range_first; - U32 voff_range_opl_raw = scope->voff_range_opl; - U32 voff_range_opl_clamped = ClampTop(voff_range_opl_raw, bundle->scope_voff_count); - U32 voff_range_first = ClampTop(voff_range_first_raw, voff_range_opl_clamped); - U32 voff_range_opl = voff_range_opl_clamped; - if ((voff_range_opl - voff_range_first) % 2 == 1){ - voff_range_opl -= 1; - } - - U64 *voff_ptr = bundle->scope_voffs + voff_range_first; - - if (voff_range_opl - voff_range_first > 2){ - str8_list_pushf(arena, out, "%.*s voff_ranges={\n", - indent_level, rdi_stringize_spaces); - for (U32 i = voff_range_first; i < voff_range_opl; i += 2, voff_ptr += 2){ - str8_list_pushf(arena, out, "%.*s [0x%08llx, 0x%08llx)\n", - indent_level, rdi_stringize_spaces, - voff_ptr[0], voff_ptr[1]); - } - str8_list_pushf(arena, out, "%.*s }\n", - indent_level, rdi_stringize_spaces); - } - else if (voff_range_opl - voff_range_first == 2){ - str8_list_pushf(arena, out, "%.*s voff_range=[0x%08llx, 0x%08llx)\n", - indent_level, rdi_stringize_spaces, - voff_ptr[0], voff_ptr[1]); - } - } - - // locals - { - U32 local_first = scope->local_first; - U32 local_opl_raw = local_first + scope->local_count; - U32 local_opl = ClampTop(local_opl_raw, bundle->local_count); - - if (local_first < local_opl){ - RDI_Local *local_ptr = bundle->locals + local_first; - for (U32 i = local_first; i < local_opl; i += 1, local_ptr += 1){ - str8_list_pushf(arena, out, "%.*s local[%u]\n", - indent_level, rdi_stringize_spaces, i); - - String8 local_kind_str = rdi_string_from_local_kind(local_ptr->kind); - str8_list_pushf(arena, out, "%.*s kind=%.*s\n", - indent_level, rdi_stringize_spaces, str8_varg(local_kind_str)); - - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, local_ptr->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*s name='%.*s'\n", - indent_level, rdi_stringize_spaces, str8_varg(name)); - - str8_list_pushf(arena, out, "%.*s type_idx=%u\n", - indent_level, rdi_stringize_spaces, local_ptr->type_idx); - - U32 location_first = local_ptr->location_first; - U32 location_opl_raw = local_ptr->location_opl; - U32 location_opl = ClampTop(location_opl_raw, bundle->location_block_count); - - if (location_first < location_opl){ - str8_list_pushf(arena, out, "%.*s locations:\n", indent_level, rdi_stringize_spaces); - RDI_LocationBlock *block_ptr = bundle->location_blocks + location_first; - for (U32 j = location_first; j < location_opl; j += 1, block_ptr += 1){ - if (block_ptr->scope_off_first == 0 && block_ptr->scope_off_opl == max_U32){ - str8_list_pushf(arena, out, "%.*s case *always*:\n", indent_level, rdi_stringize_spaces); - } - else{ - str8_list_pushf(arena, out, "%.*s case [0x%08x, 0x%08x):\n", - indent_level, rdi_stringize_spaces, - block_ptr->scope_off_first, block_ptr->scope_off_opl); - } - - if (block_ptr->location_data_off >= bundle->location_data_size){ - str8_list_pushf(arena, out, "%.*s \n", - indent_level, rdi_stringize_spaces); - } - else{ - str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces); - - U8 *loc_data_opl = bundle->location_data + bundle->location_data_size; - U8 *loc_base_ptr = bundle->location_data + block_ptr->location_data_off; - RDI_LocationKind kind = (RDI_LocationKind)*loc_base_ptr; - switch (kind){ - default: - { - str8_list_pushf(arena, out, "\n"); - }break; - - case RDI_LocationKind_AddrBytecodeStream: - { - str8_list_pushf(arena, out, "AddrBytecodeStream\n"); - str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces); - U8 *bytecode_ptr = loc_base_ptr + 1; - for (;bytecode_ptr < loc_data_opl && *bytecode_ptr != 0; bytecode_ptr += 1){ - str8_list_pushf(arena, out, "%02x ", *bytecode_ptr); - } - str8_list_pushf(arena, out, "\n"); - }break; - - case RDI_LocationKind_ValBytecodeStream: - { - str8_list_pushf(arena, out, "ValBytecodeStream\n"); - str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces); - U8 *bytecode_ptr = loc_base_ptr + 1; - for (;bytecode_ptr < loc_data_opl && *bytecode_ptr != 0; bytecode_ptr += 1){ - str8_list_pushf(arena, out, "%02x ", *bytecode_ptr); - } - str8_list_pushf(arena, out, "\n"); - }break; - - case RDI_LocationKind_AddrRegPlusU16: - { - if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){ - str8_list_pushf(arena, out, "AddrRegPlusU16( )\n"); - } - else{ - RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr; - str8_list_pushf(arena, out, "AddrRegPlusU16(reg: %S, off: %u)\n", - rdi_format_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); - } - }break; - - case RDI_LocationKind_AddrAddrRegPlusU16: - { - if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){ - str8_list_pushf(arena, out, "AddrAddrRegPlusU16( )\n"); - } - else{ - RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr; - str8_list_pushf(arena, out, "AddrAddrRegisterPlusU16(reg: %S, off: %u)\n", - rdi_format_reg_code(scratch.arena, arch, loc->reg_code), loc->offset); - } - }break; - - case RDI_LocationKind_ValReg: - { - if (loc_base_ptr + sizeof(RDI_LocationReg) > loc_data_opl){ - str8_list_pushf(arena, out, "ValReg( )\n"); - } - else{ - RDI_LocationReg *loc = (RDI_LocationReg*)loc_base_ptr; - str8_list_pushf(arena, out, "ValReg(reg: %S)\n", rdi_format_reg_code(scratch.arena, arch, loc->reg_code)); - } - }break; - } - } - } - } - } - } - } - - // TODO(allen): static locals - - for (U32 child = scope->first_child_scope_idx; - child != 0;){ - // get scope for child - RDI_Scope *child_scope = 0; - if (child < bundle->scope_count){ - child_scope = bundle->scopes + child; - } - if (child_scope == 0){ - break; - } - - // stringize child - rdi_stringize_scope(arena, out, rdi, arch, bundle, child_scope, indent_level + 1); - - // increment iterator - child = child_scope->next_sibling_scope_idx; - } - - str8_list_pushf(arena, out, "%.*s[/%u]\n", - indent_level, rdi_stringize_spaces, this_idx); - - scratch_end(scratch); -} - -internal void -rdi_stringize_inline_site(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_InlineSite *inline_site, U32 indent_level) -{ - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - str8_list_pushf(arena, out, "%.*sname='%S'\n", indent_level, rdi_stringize_spaces, name); - str8_list_pushf(arena, out, "%.*stype_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->type_idx); - str8_list_pushf(arena, out, "%.*sowner_type_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->owner_type_idx); - str8_list_pushf(arena, out, "%.*sline_table_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->line_table_idx); -} diff --git a/src/rdi_dump/rdi_dump.h b/src/rdi_dump/rdi_dump.h deleted file mode 100644 index 1c99092c..00000000 --- a/src/rdi_dump/rdi_dump.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_DUMP_H -#define RDI_DUMP_H - -//////////////////////////////// -//~ rjf: RADDBG Stringize Helper Types - -typedef struct RDI_FilePathBundle RDI_FilePathBundle; -struct RDI_FilePathBundle -{ - RDI_FilePathNode *file_paths; - U64 file_path_count; -}; - -typedef struct RDI_UDTMemberBundle RDI_UDTMemberBundle; -struct RDI_UDTMemberBundle -{ - RDI_Member *members; - RDI_EnumMember *enum_members; - U32 member_count; - U32 enum_member_count; -}; - -typedef struct RDI_ScopeBundle RDI_ScopeBundle; -struct RDI_ScopeBundle -{ - RDI_Scope *scopes; - U64 *scope_voffs; - RDI_Local *locals; - RDI_LocationBlock *location_blocks; - U8 *location_data; - U32 scope_count; - U32 scope_voff_count; - U32 local_count; - U32 location_block_count; - U32 location_data_size; -}; - -//////////////////////////////// -//~ rjf: RDI Enum -> String Functions - -internal String8 rdi_string_from_reg_code_x86(U64 reg_code); -internal String8 rdi_string_from_reg_code_x64(U64 reg_code); -internal String8 rdi_string_from_reg_code(RDI_Arch arch, U64 reg_code); -internal String8 rdi_string_from_data_section_kind(RDI_SectionKind v); -internal String8 rdi_string_from_arch(RDI_Arch v); -internal String8 rdi_string_from_language(RDI_Language v); -internal String8 rdi_string_from_type_kind(RDI_TypeKind v); -internal String8 rdi_string_from_member_kind(RDI_MemberKind v); -internal String8 rdi_string_from_local_kind(RDI_LocalKind v); - -//////////////////////////////// -//~ rjf: RDI Flags -> String Functions - -internal void rdi_stringize_binary_section_flags(Arena *arena, String8List *out, RDI_BinarySectionFlags flags); -internal void rdi_stringize_type_modifier_flags(Arena *arena, String8List *out, RDI_TypeModifierFlags flags); -internal void rdi_stringize_udt_flags(Arena *arena, String8List *out, RDI_UDTFlags flags); -internal void rdi_stringize_link_flags(Arena *arena, String8List *out, RDI_LinkFlags flags); - -//////////////////////////////// - -internal String8 rdi_format_reg_code(Arena *arena, RDI_Arch arch, U64 reg_code); - -//////////////////////////////// -//~ rjf: RDI Compound Stringize Functions - -internal void rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *rdi, U32 indent_level); -internal void rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_TopLevelInfo *tli, U32 indent_level); -internal void rdi_stringize_binary_section(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_BinarySection *bin_section, U32 indent_level); -internal void rdi_stringize_file_path(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_FilePathBundle *bundle, RDI_FilePathNode *file_path, U32 indent_level); -internal void rdi_stringize_source_file(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_SourceFile *source_file, U32 indent_level); -internal void rdi_stringize_line_table(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_LineTable *line_table, U32 indent_level); -internal void rdi_stringize_source_line_map(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_SourceLineMap *map, U32 indent_level); -internal void rdi_stringize_unit(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Unit *unit, U32 indent_level); -internal void rdi_stringize_type_node(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_TypeNode *type, U32 indent_level); -internal void rdi_stringize_udt(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_UDTMemberBundle *bundle, RDI_UDT *udt, U32 indent_level); -internal void rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_GlobalVariable *global_variable, U32 indent_level); -internal void rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_ThreadVariable *thread_var, U32 indent_level); -internal void rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Procedure *proc, U32 indent_level); -internal void rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Arch arch, RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level); -internal void rdi_stringize_inline_site(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_InlineSite *inline_site, U32 indent_level); - -#endif // RDI_DUMP_H diff --git a/src/rdi_dump/rdi_dump_main.c b/src/rdi_dump/rdi_dump_main.c deleted file mode 100644 index 34ebf27a..00000000 --- a/src/rdi_dump/rdi_dump_main.c +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Build Options - -#define BUILD_TITLE "rdi_dump" -#define BUILD_CONSOLE_INTERFACE 1 - -//////////////////////////////// -//~ rjf: Includes - -//- rjf: [lib] -#include "third_party/rad_lzb_simple/rad_lzb_simple.h" -#include "third_party/rad_lzb_simple/rad_lzb_simple.c" - -//- rjf: [h] -#include "base/base_inc.h" -#include "os/os_inc.h" -#include "rdi_format/rdi_format_local.h" -#include "rdi_dump.h" - -//- rjf: [c] -#include "base/base_inc.c" -#include "os/os_inc.c" -#include "rdi_format/rdi_format_local.c" -#include "rdi_dump.c" - -//////////////////////////////// -//~ rjf: Entry Point - -internal void -entry_point(CmdLine *cmd_line) -{ - ////////////////////////////// - //- rjf: set up - // - Arena *arena = arena_alloc(); - String8List errors = {0}; - - ////////////////////////////// - //- rjf: extract command line parameters - // - typedef U32 DumpFlags; - enum - { - DumpFlag_DataSections = (1<<0), - DumpFlag_TopLevelInfo = (1<<1), - DumpFlag_BinarySections = (1<<2), - DumpFlag_FilePaths = (1<<3), - DumpFlag_SourceFiles = (1<<4), - DumpFlag_LineTables = (1<<5), - DumpFlag_SourceLineMaps = (1<<6), - DumpFlag_Units = (1<<7), - DumpFlag_UnitVMap = (1<<8), - DumpFlag_TypeNodes = (1<<9), - DumpFlag_UDTs = (1<<10), - DumpFlag_GlobalVariables = (1<<11), - DumpFlag_GlobalVMap = (1<<12), - DumpFlag_ThreadVariables = (1<<13), - DumpFlag_Procedures = (1<<14), - DumpFlag_Scopes = (1<<15), - DumpFlag_ScopeVMap = (1<<16), - DumpFlag_InlineSites = (1<<17), - DumpFlag_NameMaps = (1<<18), - DumpFlag_Strings = (1<<19), - }; - String8 input_name = {0}; - DumpFlags dump_flags = (U32)0xffffffff; - { - // rjf: extract input file path - input_name = str8_list_first(&cmd_line->inputs); - - // rjf: extract "only" options - { - String8List dump_options = cmd_line_strings(cmd_line, str8_lit("only")); - if(dump_options.first != 0) - { - dump_flags = 0; - for(String8Node *n = dump_options.first; n != 0; n = n->next) - { - if(0){} - else if(str8_match(n->string, str8_lit("data_sections"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_DataSections; } - else if(str8_match(n->string, str8_lit("top_level_info"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_TopLevelInfo; } - else if(str8_match(n->string, str8_lit("binary_sections"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_BinarySections; } - else if(str8_match(n->string, str8_lit("file_paths"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_FilePaths; } - else if(str8_match(n->string, str8_lit("source_files"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_SourceFiles; } - else if(str8_match(n->string, str8_lit("line_tables"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_LineTables; } - else if(str8_match(n->string, str8_lit("source_line_maps"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_SourceLineMaps; } - else if(str8_match(n->string, str8_lit("units"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Units; } - else if(str8_match(n->string, str8_lit("unit_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_UnitVMap; } - else if(str8_match(n->string, str8_lit("type_nodes"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_TypeNodes; } - else if(str8_match(n->string, str8_lit("udt_data"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_UDTs; } - else if(str8_match(n->string, str8_lit("global_variables"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_GlobalVariables; } - else if(str8_match(n->string, str8_lit("global_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_GlobalVMap; } - else if(str8_match(n->string, str8_lit("thread_variables"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_ThreadVariables; } - else if(str8_match(n->string, str8_lit("procedures"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Procedures; } - else if(str8_match(n->string, str8_lit("scopes"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Scopes; } - else if(str8_match(n->string, str8_lit("scope_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_ScopeVMap; } - else if(str8_match(n->string, str8_lit("inline_sites"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_InlineSites; } - else if(str8_match(n->string, str8_lit("name_maps"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_NameMaps; } - else if(str8_match(n->string, str8_lit("strings"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Strings; } - } - } - } - } - - ////////////////////////////// - //- rjf: load file - // - String8 input_data = os_data_from_file_path(arena, input_name); - if(input_name.size == 0) - { - str8_list_pushf(arena, &errors, "error (input): No input RDI file specified."); - } - else if(input_data.size == 0) - { - str8_list_pushf(arena, &errors, "error (input): No input RDI file successfully loaded; either the path or file contents are invalid."); - } - - ////////////////////////////// - //- rjf: obtain initial rdi parse - // - RDI_Parsed rdi_ = {0}; - RDI_Parsed *rdi = &rdi_; - RDI_ParseStatus status = rdi_parse(input_data.str, input_data.size, rdi); - - ////////////////////////////// - //- rjf: decompress rdi if necessary - // - { - U64 decompressed_size = rdi_decompressed_size_from_parsed(rdi); - if(decompressed_size > input_data.size) - { - U8 *decompressed_data = push_array_no_zero(arena, U8, decompressed_size); - rdi_decompress_parsed(decompressed_data, decompressed_size, rdi); - status = rdi_parse(decompressed_data, decompressed_size, rdi); - } - } - - ////////////////////////////// - //- rjf: error on bad parse status - // - if(status != RDI_ParseStatus_Good) - { - str8_list_pushf(arena, &errors, "error (input): RDI file could not be successfully decoded."); - } - - ////////////////////////////// - //- rjf: output error strings to stderr - // - for(String8Node *n = errors.first; n != 0; n = n->next) - { - fwrite(n->string.str, 1, n->string.size, stderr); - fprintf(stderr, "\n"); - } - - ////////////////////////////// - //- rjf: build dump strings - // - String8List dump = {0}; - if(errors.node_count == 0) - { - //- rjf: DATA SECTIONS - if(dump_flags & DumpFlag_DataSections) - { - str8_list_pushf(arena, &dump, "# DATA SECTIONS:\n"); - rdi_stringize_data_sections(arena, &dump, rdi, 1); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: TOP LEVEL INFO - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - if(dump_flags & DumpFlag_TopLevelInfo) - { - str8_list_pushf(arena, &dump, "# TOP LEVEL INFO:\n"); - rdi_stringize_top_level_info(arena, &dump, rdi, tli, 1); - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: BINARY SECTIONS - if(dump_flags & DumpFlag_BinarySections) - { - str8_list_pushf(arena, &dump, "# BINARY SECTIONS:\n"); - U64 count = 0; - RDI_BinarySection *v = rdi_table_from_name(rdi, BinarySections, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " section[%I64u]:\n", idx); - rdi_stringize_binary_section(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: FILE PATHS - if(dump_flags & DumpFlag_FilePaths) - { - RDI_FilePathBundle file_path_bundle = {0}; - file_path_bundle.file_paths = rdi_table_from_name(rdi, FilePathNodes, &file_path_bundle.file_path_count); - str8_list_pushf(arena, &dump, "# FILE PATHS\n"); - RDI_FilePathNode *ptr = file_path_bundle.file_paths; - for(U32 i = 0; i < file_path_bundle.file_path_count; i += 1, ptr += 1) - { - if(ptr->parent_path_node == 0) - { - rdi_stringize_file_path(arena, &dump, rdi, &file_path_bundle, ptr, 1); - } - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: SOURCE FILES - if(dump_flags & DumpFlag_SourceFiles) - { - str8_list_pushf(arena, &dump, "# SOURCE FILES\n"); - U64 count = 0; - RDI_SourceFile *v = rdi_table_from_name(rdi, SourceFiles, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " source_file[%I64u]:\n", idx); - rdi_stringize_source_file(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: LINE TABLES - if(dump_flags & DumpFlag_LineTables) - { - str8_list_pushf(arena, &dump, "# LINE TABLES\n"); - U64 count = 0; - RDI_LineTable *v = rdi_table_from_name(rdi, LineTables, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " line_table[%I64u]:\n", idx); - rdi_stringize_line_table(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: SOURCE LINE MAPS - if(dump_flags & DumpFlag_SourceLineMaps) - { - str8_list_pushf(arena, &dump, "# SOURCE LINE MAPS\n"); - U64 count = 0; - RDI_SourceLineMap *v = rdi_table_from_name(rdi, SourceLineMaps, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " source_line_map[%I64u]:\n", idx); - rdi_stringize_source_line_map(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: UNITS - if(dump_flags & DumpFlag_Units) - { - str8_list_pushf(arena, &dump, "# UNITS\n"); - U64 count = 0; - RDI_Unit *v = rdi_table_from_name(rdi, Units, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " unit[%I64u]:\n", idx); - rdi_stringize_unit(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: UNIT VMAP - if(dump_flags & DumpFlag_UnitVMap) - { - str8_list_pushf(arena, &dump, "# UNIT VMAP\n"); - U64 count = 0; - RDI_VMapEntry *v = rdi_table_from_name(rdi, UnitVMap, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", v[idx].voff, v[idx].idx); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: TYPE NODES - if(dump_flags & DumpFlag_TypeNodes) - { - str8_list_pushf(arena, &dump, "# TYPE NODES:\n"); - U64 count = 0; - RDI_TypeNode *v = rdi_table_from_name(rdi, TypeNodes, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " type[%I64u]:\n", idx); - rdi_stringize_type_node(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: UDT DATA - if(dump_flags & DumpFlag_UDTs) - { - U64 all_members_count = 0; - RDI_Member *all_members = rdi_table_from_name(rdi, Members, &all_members_count); - U64 all_enum_members_count = 0; - RDI_EnumMember *all_enum_members = rdi_table_from_name(rdi, EnumMembers, &all_enum_members_count); - U64 all_udts_count = 0; - RDI_UDT *all_udts = rdi_table_from_name(rdi, UDTs, &all_udts_count); - RDI_UDTMemberBundle member_bundle = {0}; - { - member_bundle.members = all_members; - member_bundle.enum_members = all_enum_members; - member_bundle.member_count = (RDI_U32)all_members_count; - member_bundle.enum_member_count = (RDI_U32)all_enum_members_count; - } - str8_list_pushf(arena, &dump, "# UDTS:\n"); - for(U64 idx = 0; idx < all_udts_count; idx += 1) - { - str8_list_pushf(arena, &dump, " udt[%I64u]:\n", idx); - rdi_stringize_udt(arena, &dump, rdi, &member_bundle, &all_udts[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: GLOBAL VARIABLES - if(dump_flags & DumpFlag_GlobalVariables) - { - str8_list_pushf(arena, &dump, "# GLOBAL VARIABLES:\n"); - RDI_U64 count = 0; - RDI_GlobalVariable *v = rdi_table_from_name(rdi, GlobalVariables, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " global_variable[%I64u]:\n", idx); - rdi_stringize_global_variable(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: GLOBAL VMAP - if(dump_flags & DumpFlag_GlobalVMap) - { - str8_list_pushf(arena, &dump, "# GLOBAL VMAP:\n"); - U64 count = 0; - RDI_VMapEntry *v = rdi_table_from_name(rdi, GlobalVMap, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", v[idx].voff, v[idx].idx); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: THREAD LOCAL VARIABLES - if(dump_flags & DumpFlag_ThreadVariables) - { - str8_list_pushf(arena, &dump, "# THREAD VARIABLES:\n"); - U64 count = 0; - RDI_ThreadVariable *v = rdi_table_from_name(rdi, ThreadVariables, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " thread_variable[%I64u]:\n", idx); - rdi_stringize_thread_variable(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: PROCEDURES - if(dump_flags & DumpFlag_Procedures) - { - str8_list_pushf(arena, &dump, "# PROCEDURES:\n"); - U64 count = 0; - RDI_Procedure *v = rdi_table_from_name(rdi, Procedures, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " procedure[%I64u]:\n", idx); - rdi_stringize_procedure(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: SCOPES - if(dump_flags & DumpFlag_Scopes) - { - U64 scopes_count = 0; - RDI_Scope *scopes = rdi_table_from_name(rdi, Scopes, &scopes_count); - U64 scopes_voffs_count = 0; - U64 *scopes_voffs = rdi_table_from_name(rdi, ScopeVOffData, &scopes_voffs_count); - U64 locals_count = 0; - RDI_Local *locals = rdi_table_from_name(rdi, Locals, &locals_count); - U64 location_block_count = 0; - RDI_LocationBlock *location_blocks = rdi_table_from_name(rdi, LocationBlocks, &location_block_count); - U64 location_data_size = 0; - RDI_U8 *location_data = rdi_table_from_name(rdi, LocationData, &location_data_size); - RDI_ScopeBundle scope_bundle = {0}; - { - scope_bundle.scopes = scopes; - scope_bundle.scope_count = scopes_count; - scope_bundle.scope_voffs = scopes_voffs; - scope_bundle.scope_voff_count = scopes_voffs_count; - scope_bundle.locals = locals; - scope_bundle.local_count = locals_count; - scope_bundle.location_blocks = location_blocks; - scope_bundle.location_block_count = location_block_count; - scope_bundle.location_data = location_data; - scope_bundle.location_data_size = location_data_size; - } - str8_list_pushf(arena, &dump, "# SCOPES:\n"); - for(U64 idx = 0; idx < scopes_count; idx += 1) - { - if(scopes[idx].parent_scope_idx == 0) - { - rdi_stringize_scope(arena, &dump, rdi, tli->arch, &scope_bundle, &scopes[idx], 1); - } - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: SCOPE VMAP - if(dump_flags & DumpFlag_ScopeVMap) - { - str8_list_pushf(arena, &dump, "# SCOPE VMAP:\n"); - U64 count = 0; - RDI_VMapEntry *v = rdi_table_from_name(rdi, ScopeVMap, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", v[idx].voff, v[idx].idx); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: INLINE SITES - if(dump_flags & DumpFlag_InlineSites) - { - str8_list_pushf(arena, &dump, "# INLINE SITES:\n"); - U64 count = 0; - RDI_InlineSite *v = rdi_table_from_name(rdi, InlineSites, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - str8_list_pushf(arena, &dump, " inline_site[%I64u]:\n", idx); - rdi_stringize_inline_site(arena, &dump, rdi, &v[idx], 2); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: NAME MAPS - if(dump_flags & DumpFlag_NameMaps) - { - str8_list_pushf(arena, &dump, "# NAME MAP:\n"); - U64 count = 0; - RDI_NameMap *v = rdi_table_from_name(rdi, NameMaps, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - RDI_ParsedNameMap name_map = {0}; - rdi_parsed_from_name_map(rdi, &v[idx], &name_map); - str8_list_pushf(arena, &dump, " name_map[%I64u]:\n", idx); - RDI_NameMapBucket *bucket = name_map.buckets; - for(U32 j = 0; j < name_map.bucket_count; j += 1, bucket += 1) - { - if(bucket->node_count > 0) - { - str8_list_pushf(arena, &dump, " bucket[%u]:\n", j); - RDI_NameMapNode *node = name_map.nodes + bucket->first_node; - RDI_NameMapNode *node_opl = node + bucket->node_count; - for(;node < node_opl; node += 1) - { - String8 string = {0}; - string.str = rdi_string_from_idx(rdi, node->string_idx, &string.size); - str8_list_pushf(arena, &dump, " match \"%.*s\": ", str8_varg(string)); - if(node->match_count == 1) - { - str8_list_pushf(arena, &dump, "%u", node->match_idx_or_idx_run_first); - } - else - { - RDI_U32 idx_count = 0; - RDI_U32 *idx_run = - rdi_idx_run_from_first_count(rdi, node->match_idx_or_idx_run_first, - node->match_count, &idx_count); - if(idx_count > 0) - { - RDI_U32 last = idx_count - 1; - for(U32 k = 0; k < last; k += 1) - { - str8_list_pushf(arena, &dump, "%u, ", idx_run[k]); - } - str8_list_pushf(arena, &dump, "%u", idx_run[last]); - } - } - str8_list_pushf(arena, &dump, "\n"); - } - } - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - - //- rjf: STRINGS - if(dump_flags & DumpFlag_Strings) - { - str8_list_pushf(arena, &dump, "# STRINGS:\n"); - U64 count = 0; - U32 *v = rdi_table_from_name(rdi, StringTable, &count); - for(U64 idx = 0; idx < count; idx += 1) - { - String8 string = {0}; - string.str = rdi_string_from_idx(rdi, (RDI_U32)idx, &string.size); - str8_list_pushf(arena, &dump, " string[%I64u]: \"%S\"\n", idx, string); - } - str8_list_push(arena, &dump, str8_lit("\n")); - } - } - - ////////////////////////////// - //- rjf: write dump to stdout - // - for(String8Node *n = dump.first; n != 0; n = n->next) - { - fwrite(n->string.str, 1, n->string.size, stdout); - } -} From c57b5fcd6d8beaaca03e5fc2de5b7fd3132bde93 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 15:37:27 -0700 Subject: [PATCH 281/755] appease clang --- src/dwarf/dwarf.c | 8 ++++++-- src/dwarf/dwarf_expr.c | 11 ++++++++++- src/dwarf/dwarf_unwind.c | 5 +++++ src/elf/elf.c | 12 ++++++------ src/radcon/radcon.c | 9 +++++---- src/radcon/radcon_main.c | 1 + 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index 0c552663..05f72bc0 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -46,21 +46,25 @@ dw_reg_pos_from_code_x64(DW_Reg reg_code) } internal U64 -dw_reg_size_from_code(RDI_Arch arch, DW_Reg reg_code) +dw_reg_size_from_code(Arch arch, DW_Reg reg_code) { switch (arch) { + case Arch_Null: break; case Arch_x86: return dw_reg_size_from_code_x86(reg_code); case Arch_x64: return dw_reg_size_from_code_x64(reg_code); + default: NotImplemented; break; } return 0; } internal U64 -dw_reg_pos_from_code(RDI_Arch arch, DW_Reg reg_code) +dw_reg_pos_from_code(Arch arch, DW_Reg reg_code) { switch (arch) { + case Arch_Null: break; case Arch_x86: return dw_reg_pos_from_code_x86(reg_code); case Arch_x64: return dw_reg_pos_from_code_x64(reg_code); + default: NotImplemented; break; } return max_U64; } diff --git a/src/dwarf/dwarf_expr.c b/src/dwarf/dwarf_expr.c index fe4fd9a1..98309b97 100644 --- a/src/dwarf/dwarf_expr.c +++ b/src/dwarf/dwarf_expr.c @@ -3,13 +3,16 @@ //- analyzers +#if 0 internal DW_SimpleLoc dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base) { DW_SimpleLoc result = {DW_SimpleLocKind_Empty}; + String8 expr_data = str8((U8*)data+range.min, (U8*)data+range.max); + U8 op = 0; - if (dw_based_range_read(base, range, 0, 1, &op)) { + if (str8_deserial_read_struct(expr_data, 0, &op)) { // step params U64 size_param = 0; B32 is_signed = 0; @@ -548,12 +551,14 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf scratch_end(scratch); return result; } +#endif //- full eval internal DW_Location dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_ExprMachineConfig *config) { +#if 0 Temp scratch = scratch_begin(&arena_optional, 1); DW_Location result = {0}; @@ -1322,8 +1327,12 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp // clear stack scratch_end(scratch); return result; +#endif + DW_Location result = {0}; + return result; } + //- dw expr val stack internal DW_ExprStack diff --git a/src/dwarf/dwarf_unwind.c b/src/dwarf/dwarf_unwind.c index 84931716..81cc93de 100644 --- a/src/dwarf/dwarf_unwind.c +++ b/src/dwarf/dwarf_unwind.c @@ -1,6 +1,11 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 off, U64 size, void *out) { return 0; } +internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 off, U64 *out) { return 0; } +internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 off, S64 *out) { return 0; } +internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 off, U64 *out) { return 0; } + //////////////////////////////// // x64 Unwind Function diff --git a/src/elf/elf.c b/src/elf/elf.c index 1a094baa..ac3473cb 100644 --- a/src/elf/elf.c +++ b/src/elf/elf.c @@ -82,10 +82,10 @@ elf_sym64_from_sym32(ELF_Sym32 sym32) internal ELF_Rel64 elf_rel64_from_rel32(ELF_Rel32 rel32) { - U32 sym = SYMS_ELF32_R_SYM(rel32.r_info); - U32 type = SYMS_ELF32_R_TYPE(rel32.r_info); + U32 sym = ELF32_R_SYM(rel32.r_info); + U32 type = ELF32_R_TYPE(rel32.r_info); ELF_Rel64 rel64 = {0}; - rel64.r_info = SYMS_ELF64_R_INFO(sym, type); + rel64.r_info = ELF64_R_INFO(sym, type); rel64.r_offset = rel32.r_offset; return rel64; } @@ -93,11 +93,11 @@ elf_rel64_from_rel32(ELF_Rel32 rel32) internal ELF_Rela64 elf_rela64_from_rela32(ELF_Rela32 rela32) { - U32 sym = SYMS_ELF32_R_SYM(rela32.r_info); - U32 type = SYMS_ELF32_R_TYPE(rela32.r_info); + U32 sym = ELF32_R_SYM(rela32.r_info); + U32 type = ELF32_R_TYPE(rela32.r_info); ELF_Rela64 rela64 = {0}; rela64.r_offset = rela32.r_info; - rela64.r_info = SYMS_ELF64_R_INFO(sym, type); + rela64.r_info = ELF64_R_INFO(sym, type); rela64.r_addend = rela32.r_addend; return rela64; } diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index ac6335dc..9d6101f1 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -172,12 +172,15 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) String8 debug_name = {0}; String8 debug_data = {0}; + B32 check_guid = 0; + Guid pe_pdb_guid = {0}; + + B32 elf_has_debug_link = 0; + ELF_GnuDebugLink debug_link = {0}; // // Input has PE/COFF // - B32 check_guid = 0; - Guid pe_pdb_guid = {0}; if (is_pe_present) { image = Image_CoffPe; image_name = pe_name; @@ -221,8 +224,6 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) } } - B32 elf_has_debug_link = 0; - ELF_GnuDebugLink debug_link = {0}; if (is_elf_present || is_elf_debug_present) { if (driver != RC_Driver_Null && driver != RC_Driver_Dwarf) { fprintf(stderr, "error: ELF inputs are only supported when using DWARF driver.\n"); diff --git a/src/radcon/radcon_main.c b/src/radcon/radcon_main.c index 05f4ab99..9f3c2b0a 100644 --- a/src/radcon/radcon_main.c +++ b/src/radcon/radcon_main.c @@ -14,6 +14,7 @@ #include "third_party/xxHash/xxhash.h" #define SINFL_IMPLEMENTATION #include "third_party/sinfl/sinfl.h" +#include "third_party/radsort/radsort.h" //////////////////////////////// // RDI Format Library From da3c15c7ed290ba89e96e9fdb16a2fdbe238278a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 27 Mar 2025 15:41:32 -0700 Subject: [PATCH 282/755] short-circuit rule lookups if explicit default is found --- src/eval/eval_ir.c | 19 +++++++++++++++++-- src/raddbg/raddbg_views.c | 8 ++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 06dd5356..9722f37d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2641,12 +2641,18 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } //- rjf: pick the ir-generation rule from explicitly-stored expressions + B32 default_is_forced = 0; 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->string; E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); + if(str8_match(name, e_irgen_rule__default.name, 0)) + { + default_is_forced = 1; + break; + } if(irgen_rule_candidate != &e_irgen_rule__default) { B32 tag_is_poisoned = e_tag_is_poisoned(tag); @@ -2685,6 +2691,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } // rjf: find any auto hooks according to this generation's type + if(!default_is_forced) { E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -3028,11 +3035,19 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) E_LookupRuleTagPair result = {&e_lookup_rule__default, &e_expr_nil}; { // rjf: first try explicitly-stored tags + B32 default_is_forced = 0; if(result.rule == &e_lookup_rule__default) { for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) { if(e_tag_is_poisoned(tag)) { continue; } + if(str8_match(tag->string, e_lookup_rule__default.name, 0)) + { + result.rule = &e_lookup_rule__default; + result.tag = &e_expr_nil; + default_is_forced = 1; + break; + } E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); if(candidate != &e_lookup_rule__nil) { @@ -3043,7 +3058,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } // rjf: next try implicit set name -> rule mapping - if(result.rule == &e_lookup_rule__default) + if(!default_is_forced && result.rule == &e_lookup_rule__default) { E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); if(type_kind == E_TypeKind_Set) @@ -3059,7 +3074,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } // rjf: next try auto hook map - if(result.rule == &e_lookup_rule__default) + if(!default_is_forced && result.rule == &e_lookup_rule__default) { E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 31b07abb..16929f96 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1329,10 +1329,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr => default)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } } From 4cc883a353371514f5e9a5d6edac601ea192ac9d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 15:49:15 -0700 Subject: [PATCH 283/755] update includes in rdi_breakpad_from_pdb --- src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index fb5bdf9c..f3c72e7e 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -23,7 +23,6 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "coff/coff.h" #include "coff/coff_parse.h" #include "codeview/codeview.h" @@ -41,7 +40,6 @@ #include "os/os_inc.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "coff/coff.c" #include "coff/coff_parse.c" #include "codeview/codeview.c" From 3911a66b303472112154e20c3294477c62aa2361 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 28 Mar 2025 10:56:41 -0700 Subject: [PATCH 284/755] fill out first pass implementations of raddbg_markup features; thread names, thread colors, format-string output-debug-string helper, attachment-checking --- src/ctrl/ctrl_core.c | 39 +++++++++-- src/ctrl/ctrl_core.h | 3 +- src/demon/demon_core.mdesk | 1 + src/demon/generated/demon.meta.c | 3 +- src/demon/generated/demon.meta.h | 3 +- src/demon/win32/demon_core_win32.c | 7 ++ src/demon/win32/demon_core_win32.h | 1 + src/lib_raddbg_markup/raddbg_markup.h | 97 +++++++++++++++++++++------ src/mule/mule_main.cpp | 12 +++- src/raddbg/raddbg_core.c | 2 + 10 files changed, 137 insertions(+), 31 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1f05114c..ab1c1614 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -606,8 +606,8 @@ ctrl_event_from_serialized_string(Arena *arena, String8 string) read_off += str8_deserial_read_struct(string, read_off, &event.stack_base); read_off += str8_deserial_read_struct(string, read_off, &event.tls_root); read_off += str8_deserial_read_struct(string, read_off, &event.timestamp); - read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); read_off += str8_deserial_read_struct(string, read_off, &event.rgba); + read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); read_off += str8_deserial_read_struct(string, read_off, &event.string.size); event.string.str = push_array_no_zero(arena, U8, event.string.size); read_off += str8_deserial_read(string, read_off, event.string.str, event.string.size, 1); @@ -3603,6 +3603,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ Guid rdi_dbg_guid = {0}; String8 rdi_dbg_path = str8_zero(); String8 raddbg_data = str8_zero(); + Rng1U64 raddbg_section_voff_range = r1u64(0, 0); ProfScope("unpack relevant PE info") { B32 is_valid = 1; @@ -3804,7 +3805,6 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ U64 sec_count = file_header.section_count; COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count); dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec); - Rng1U64 raddbg_section_voff_range = r1u64(0, 0); for EachIndex(idx, sec_count) { String8 section_name = str8_cstring(sec[idx].name); @@ -3820,6 +3820,13 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ vaddr_range.min + raddbg_section_voff_range.max), raddbg_data.str); scratch_end(scratch); } + + // rjf: if we have a raddbg section, mark the first byte as 1, to signify attachment + if(raddbg_section_voff_range.max != raddbg_section_voff_range.min) + { + U8 new_value = 1; + dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_section_voff_range.min, &new_value); + } } } @@ -3898,6 +3905,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ node->pdatas_count = pdatas_count; node->entry_point_voff = entry_point_voff; node->initial_debug_info_path = initial_debug_info_path; + node->raddbg_section_voff_range = raddbg_section_voff_range; node->raddbg_data = raddbg_data; } } @@ -3905,11 +3913,12 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ } internal void -ctrl_thread__module_close(CTRL_Handle module) +ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range) { ////////////////////////////// //- rjf: evict module image info from cache // + Rng1U64 raddbg_section_voff_range = {0}; { U64 hash = ctrl_hash_from_handle(module); U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count; @@ -3929,11 +3938,21 @@ ctrl_thread__module_close(CTRL_Handle module) } if(node) { + raddbg_section_voff_range = node->raddbg_section_voff_range; DLLRemove(slot->first, slot->last, node); arena_release(node->arena); } } } + + ////////////////////////////// + //- rjf: write 0 into first byte of raddbg data section, to signify detachment + // + if(raddbg_section_voff_range.max != raddbg_section_voff_range.min) + { + U8 new_value = 0; + dmn_process_write_struct(process.dmn_handle, vaddr_range.min + raddbg_section_voff_range.min, &new_value); + } } //- rjf: attached process running/event gathering @@ -4265,13 +4284,14 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); CTRL_Handle module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); + CTRL_Entity *module_ent = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module_handle); + CTRL_Entity *process_ent = ctrl_process_from_entity(module_ent); String8 module_path = event->string; - ctrl_thread__module_close(module_handle); + ctrl_thread__module_close(process_ent->handle, module_handle, module_ent->vaddr_range); out_evt->kind = CTRL_EventKind_EndModule; out_evt->msg_id = msg->msg_id; out_evt->entity = module_handle; out_evt->string = module_path; - CTRL_Entity *module_ent = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module_handle); CTRL_Entity *debug_info_path_ent = ctrl_entity_child_from_kind(module_ent, CTRL_EntityKind_DebugInfoPath); if(debug_info_path_ent != &ctrl_entity_nil) { @@ -4302,6 +4322,15 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->string = event->string; out_evt->entity_id = event->code; }break; + case DMN_EventKind_SetThreadColor: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_ThreadColor; + out_evt->msg_id = msg->msg_id; + out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); + out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); + out_evt->rgba = event->code; + }break; } ctrl_c2u_push_events(&evts); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index eb74a594..114834fd 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -593,6 +593,7 @@ struct CTRL_ModuleImageInfoCacheNode U64 entry_point_voff; Rng1U64 tls_vaddr_range; String8 initial_debug_info_path; + Rng1U64 raddbg_section_voff_range; String8 raddbg_data; }; @@ -953,7 +954,7 @@ internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, C //- rjf: module lifetime open/close work internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); -internal void ctrl_thread__module_close(CTRL_Handle module); +internal void ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range); //- rjf: attached process running/event gathering internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof); diff --git a/src/demon/demon_core.mdesk b/src/demon/demon_core.mdesk index 1ccc3c14..ea3139f6 100644 --- a/src/demon/demon_core.mdesk +++ b/src/demon/demon_core.mdesk @@ -21,6 +21,7 @@ DMN_EventKindTable: {Memory} {DebugString} {SetThreadName} + {SetThreadColor} } @table(name) diff --git a/src/demon/generated/demon.meta.c b/src/demon/generated/demon.meta.c index 69511785..3aa15e72 100644 --- a/src/demon/generated/demon.meta.c +++ b/src/demon/generated/demon.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 dmn_event_kind_string_table[17] = +String8 dmn_event_kind_string_table[18] = { str8_lit_comp("Null"), str8_lit_comp("Error"), @@ -23,6 +23,7 @@ str8_lit_comp("Halt"), str8_lit_comp("Memory"), str8_lit_comp("DebugString"), str8_lit_comp("SetThreadName"), +str8_lit_comp("SetThreadColor"), }; String8 dmn_exception_kind_string_table[5] = diff --git a/src/demon/generated/demon.meta.h b/src/demon/generated/demon.meta.h index 3b73d40b..f5fdae4c 100644 --- a/src/demon/generated/demon.meta.h +++ b/src/demon/generated/demon.meta.h @@ -25,6 +25,7 @@ DMN_EventKind_Halt, DMN_EventKind_Memory, DMN_EventKind_DebugString, DMN_EventKind_SetThreadName, +DMN_EventKind_SetThreadColor, DMN_EventKind_COUNT, } DMN_EventKind; @@ -58,7 +59,7 @@ DMN_ExceptionKind_COUNT, } DMN_ExceptionKind; C_LINKAGE_BEGIN -extern String8 dmn_event_kind_string_table[17]; +extern String8 dmn_event_kind_string_table[18]; extern String8 dmn_exception_kind_string_table[5]; C_LINKAGE_END diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index abe2d88d..60573d5b 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2378,6 +2378,13 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } }break; + //- rjf: fill set-thread-color info + case DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR: + { + e->kind = DMN_EventKind_SetThreadColor; + e->code = exception->ExceptionInformation[1]; + }break; + //- rjf: unhandled exception case default: { diff --git a/src/demon/win32/demon_core_win32.h b/src/demon/win32/demon_core_win32.h index c7234571..24f527f2 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -56,6 +56,7 @@ #define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u #define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u #define DMN_w32_EXCEPTION_CLR 0xE0434352u +#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u //////////////////////////////// //~ rjf: Win32 Register Codes diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index c59d7ade..89ea688c 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -7,23 +7,37 @@ //////////////////////////////// //~ Implementation Overrides -#if !defined(raddbg_markup_vsnprintf) -# define raddbg_markup_vsnprintf vsnprintf +#if !defined(RADDBG_MARKUP_VSNPRINTF) +# define RADDBG_MARKUP_DEFAULT_VSNPRINTF 1 +# define RADDBG_MARKUP_VSNPRINTF vsnprintf #endif //////////////////////////////// //~ Usage Macros -#define raddbg_is_attached(...) raddbg_is_attached__impl() -#define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -#define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -#define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl((unsigned int)(((r)*255) << 24) | (unsigned int)(((g)*255) << 16) | (unsigned int)(((b)*255) << 8) | (unsigned int)((a)*255)) -#define raddbg_break(...) raddbg_break__impl() -#define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) -#define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) -#define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ -#define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +#if defined(RADDBG_MARKUP_STUBS) +# define raddbg_is_attached(...) (0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_color_hex(hexcode) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)0) +# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_pin(expr, ...) +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_auto_view_rule(type, ...) struct raddbg_glue(raddbg_auto_view_rule_stub__, __COUNTER__){int __unused__} +#else +# define raddbg_is_attached(...) raddbg_is_attached__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) +# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl((unsigned int)(((r)*255) << 24) | (unsigned int)(((g)*255) << 16) | (unsigned int)(((b)*255) << 8) | (unsigned int)((a)*255)) +# define raddbg_break(...) raddbg_break__impl() +# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) +# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) +# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ +# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +#endif //////////////////////////////// //~ Helpers @@ -34,13 +48,21 @@ //////////////////////////////// //~ Win32 Implementations -#if defined(RADDBG_MARKUP_IMPLEMENTATION) +#if defined(RADDBG_MARKUP_IMPLEMENTATION) && !defined(RADDBG_MARKUP_STUBS) #if defined(_WIN32) +//- default includes +#if RADDBG_MARKUP_DEFAULT_VSNPRINTF +#include +#endif + //- section allocating -#pragma section(".raddbg", read) +#pragma section(".raddbg", read, write) #define raddbg_exe_data __declspec(allocate(".raddbg")) +//- first byte of exe data section -> is attached +raddbg_exe_data unsigned char raddbg_is_attached_byte_marker = 0; + //- types typedef int BOOL; @@ -72,11 +94,12 @@ extern "C" __declspec(dllimport) HANDLE GetCurrentThread(void); __declspec(dllimport) DWORD GetCurrentThreadId(void); __declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments); + __declspec(dllimport) void OutputDebugStringA(LPCSTR buffer); long long _InterlockedCompareExchange64(long long volatile*, long long, long long); long long _InterlockedExchangeAdd64(long long volatile*, long long); #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) - int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list); + int RADDBG_MARKUP_VSNPRINTF(char * const, unsigned long long const, const char * const, va_list); #if defined(__cplusplus) } #endif @@ -173,8 +196,7 @@ raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint) static inline int raddbg_is_attached__impl(void) { - // TODO(rjf) - return 0; + return !!raddbg_is_attached_byte_marker; } static inline void @@ -186,7 +208,7 @@ raddbg_thread_name__impl(char *fmt, ...) { va_list args; va_start(args, fmt); - raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args); + RADDBG_MARKUP_VSNPRINTF(buffer, sizeof(buffer), fmt, args); va_end(args); } @@ -260,7 +282,32 @@ raddbg_thread_name__impl(char *fmt, ...) static inline void raddbg_thread_color__impl(unsigned int hexcode) { - // TODO(rjf) + if(raddbg_is_attached()) + { +#pragma pack(push, 8) + typedef struct RADDBG_ThreadColorInfo RADDBG_ThreadColorInfo; + struct RADDBG_ThreadColorInfo + { + DWORD dwThreadID; + DWORD _pad0_; + DWORD rgba; + DWORD _pad1_; + }; +#pragma pack(pop) + RADDBG_ThreadColorInfo info; + info.dwThreadID = GetCurrentThreadId(); + info.rgba = hexcode; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x00524144u, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } +#pragma warning(pop) + } } #define raddbg_break__impl() (__debugbreak()) @@ -274,7 +321,17 @@ raddbg_watch__impl(char *fmt, ...) static inline void raddbg_log__impl(char *fmt, ...) { - // TODO(rjf) + // rjf: resolve variadic arguments + char buffer[4096]; + { + va_list args; + va_start(args, fmt); + RADDBG_MARKUP_VSNPRINTF(buffer, sizeof(buffer), fmt, args); + va_end(args); + } + + // rjf: output debug string + OutputDebugStringA(buffer); } #endif // defined(_WIN32) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 23b47f5e..cef09d86 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2670,7 +2670,15 @@ dynamic_step_test(void){ //////////////////////////////// int -mule_main(int argc, char** argv){ +mule_main(int argc, char** argv) +{ + raddbg_thread_name("mule_main_thread"); + raddbg_thread_color_rgba(1, 0, 0, 1); + if(raddbg_is_attached()) + { + raddbg_log("raddbg is attached!\n"); + } + mule_init(); // NOTE(allen): Eval Tests @@ -2735,5 +2743,3 @@ mule_main(int argc, char** argv){ return(0); } - - diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 66e29a76..540d3574 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3114,6 +3114,8 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); if(str8_match(child_schema->string, str8_lit("label"), 0)) { + result = 1; + ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, write_string); rd_cmd(D_CmdKind_SetEntityName, .ctrl_entity = entity->handle, .string = write_string); } else if(str8_match(child_schema->string, str8_lit("dbg"), 0)) From 269efba455cd3b533270fc844c0962833c5adb16 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 28 Mar 2025 11:04:37 -0700 Subject: [PATCH 285/755] fix treatment of floats in thread color rgba macro in raddbg_markup --- build.bat | 2 +- src/lib_raddbg_markup/raddbg_markup.h | 2 +- src/mule/mule_main.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.bat b/build.bat index 0c9fc09f..0c9e0463 100644 --- a/build.bat +++ b/build.bat @@ -106,7 +106,7 @@ if not "%no_meta%"=="1" ( :: --- Build Everything (@build_targets) -------------------------------------- pushd build if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %link_icon% %out%raddbg.exe || exit /b 1 -if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 +if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 if "%radcon%"=="1" set didbuild=1 && %compile% ..\src\radcon\radcon_main.c %compile_link% %out%radcon.exe || exit /b 1 if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 89ea688c..f6a17078 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -30,7 +30,7 @@ # define raddbg_is_attached(...) raddbg_is_attached__impl() # define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) # define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl((unsigned int)(((r)*255) << 24) | (unsigned int)(((g)*255) << 16) | (unsigned int)(((b)*255) << 8) | (unsigned int)((a)*255)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) # define raddbg_break(...) raddbg_break__impl() # define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index cef09d86..5b5ad81f 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2673,7 +2673,7 @@ int mule_main(int argc, char** argv) { raddbg_thread_name("mule_main_thread"); - raddbg_thread_color_rgba(1, 0, 0, 1); + raddbg_thread_color_rgba(0.4f, 0.9f, 0.2f, 1); if(raddbg_is_attached()) { raddbg_log("raddbg is attached!\n"); From 160083835a464aee402acfd7fad564610d30f6f1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 28 Mar 2025 11:38:56 -0700 Subject: [PATCH 286/755] add std::vector / auto-view-rule test to mule --- src/lib_raddbg_markup/raddbg_markup.h | 2 +- src/mule/mule_main.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index f6a17078..5eeab741 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -61,7 +61,7 @@ #define raddbg_exe_data __declspec(allocate(".raddbg")) //- first byte of exe data section -> is attached -raddbg_exe_data unsigned char raddbg_is_attached_byte_marker = 0; +raddbg_exe_data unsigned char raddbg_is_attached_byte_marker[1]; //- types diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 5b5ad81f..aecc5293 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -103,8 +103,11 @@ void optimized_struct_parameters_eval_tests(void); //////////////////////////////// // NOTE(allen): Type Coverage Eval +#include #include +raddbg_auto_view_rule(std::vector, wrap($expr._Mypair._Myval2), slice); + struct Basics{ char a; unsigned char b; @@ -439,6 +442,15 @@ type_coverage_eval_tests(void) const int32_t y1 = -10; const int32_t z1 = x1 + y1; + std::vector int_vector; + int_vector.push_back(1); + int_vector.push_back(2); + int_vector.push_back(3); + int_vector.push_back(4); + int_vector.push_back(5); + int_vector.push_back(6); + int_vector.push_back(7); + int x = (int)(Anonymous_D); } From 5eb9f2f886624f3f4e4c3e0facd4706625a836ef Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 28 Mar 2025 12:21:18 -0700 Subject: [PATCH 287/755] big notes/todos/release-notes pass --- src/lib_raddbg_markup/raddbg_markup.h | 2 +- src/raddbg/raddbg_main.c | 175 +++++++++++++------------- 2 files changed, 89 insertions(+), 88 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 5eeab741..2eb8a77e 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -21,7 +21,7 @@ # define raddbg_thread_color_hex(hexcode) ((void)0) # define raddbg_thread_color_rgba(r, g, b, a) ((void)0) # define raddbg_break(...) ((void)0) -# define raddbg_break_if(expr, ...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)expr) # define raddbg_watch(fmt, ...) ((void)0) # define raddbg_pin(expr, ...) # define raddbg_log(fmt, ...) ((void)0) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 2b018fb4..e6f78215 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -2,14 +2,18 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) //////////////////////////////// -//~ rjf: 0.9.16 changes +//~ rjf: 0.9.16 release notes // // - Auto view rules have been upgraded to support type pattern-matching. This -// makes them usable for generic types in various languages. +// makes them usable for generic types in various languages. This +// pattern-matching is done by using `?` characters in a pattern, to specify +// placeholders for various parts of a type name. For example, the pattern +// `DynamicArray` would match `DynamicArray`, `DynamicArray`, +// and so on. // - The `slice` view rule has been streamlined and simplified. When an // expression with a `slice` view rule is expanded, it will simply expand to // the slice's contents, which matches the behavior with static arrays. -// - The `slice` view rule now supports `first, one-past-last` pointer pairs, +// - The `slice` view rule now supports `first, one_past_last` pointer pairs, // as well as `base_pointer, length` pairs. // - The syntax for view rules has changed to improve its familiarity, // usability, and to improve its consistency with the rest of the evaluation @@ -17,7 +21,9 @@ // need to be explicitly named. For example, instead of // `bitmap:{w:1024, h:1024}`, the new view rule syntax would be // `bitmap(1024, 1024)`. Commas can still be omitted. Named arguments are -// still possible (and required in some cases): `disasm(size=1024, arch=x64)` +// still possible (and required in some cases): +// `disasm(size=1024, arch=x64)`. If there are no arguments required for a +// view rule, like `hex`, then no parentheses are needed. // - The hover evaluation feature has been majorly upgraded to support all // features normally available in the `Watch` view. Hover evaluations now // explicitly show type information, and contain a view rule column, which @@ -42,37 +48,49 @@ // pins (the right-click context menu and the dedicated tabs) have been // merged. // - Added the ability to add a list environment strings to targets. -// - Added support for watch annotations derived from source code markup, -// rather than only from configuration. Instances of -// `raddbg_pin(, )` will be parsed, and used to create watch -// annotations inline with source code, in the same way that watch pins do. -// For instance, `raddbg_pin(dynamic_array, slice)` will visualize -// `dynamic_array` with a `slice` view rule; -// `raddbg_pin(some_function, disasm)` will visualize `some_function` as -// disassembly; and so on. +// - The debugger releases are now packaged with a `raddbg_markup.h` +// single-header library which contains a number of source code markup tools +// which can be used in your programs. Some of these features are for direct +// interaction with the RAD Debugger. Others are simply helpers (often +// abstracting over platform functionality) for very commonly needed +// debugger-related features, like setting thread names. This second set of +// features will work with any debugger. Here is a list of this library's +// initial features (proper documentation will be written once the library +// matures): +// - `raddbg_is_attached()`: Returns 1 if the RAD Debugger is attached, +// otherwise returns 0. +// - `raddbg_break()`: Generates a trap instruction at the usage site. +// - `raddbg_break_if(expr)`: Generates a trap instruction guarded by a +// conditional, evaluating `expr`. +// - `raddbg_thread_name(format, ...)`, e.g. +// `raddbg_thread_name("worker_thread_%i", index)`: Sets the calling +// thread's name. +// - `raddbg_log(format, ...)`, e.g. +// `raddbg_log("This is a number: %i", 123)`: Writes a debug string for a +// debugger to read and display in its UI. +// - `raddbg_thread_color_hex(hexcode)`, e.g. +// `raddbg_thread_color_hex(0xff0000ff)`: Sets the calling thread's color. +// - Also can be done with individual `[0, 1]` color components: +// `raddbg_thread_color_rgba(1.f, 0.f, 0.f, 1.f)` +// - `raddbg_pin(, )`, e.g. +// `raddbg_pin(dynamic_array, slice)`: Like watch pins, but defined in source +// code. This is used by the debugger UI, but does not show up anywhere +// other than the source code, so it can either be used as a macro (which +// expands to nothing), or in comments too. +// - `raddbg_auto_view_rule(, )`, e.g. +// `raddbg_auto_view_rule(DynamicArray, slice)`: declares an +// auto-view-rule from source code, rather than from debugger +// configuration. // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. +// - Made several visual improvements. //////////////////////////////// //~ rjf: feature cleanup, code dedup, code elimination pass: // -// [ ] frontend config entities, serialization/deserialization, remove hacks, -// etc. - the entity structure should be dramatically simplified & made -// to reflect a more flexible string-tree data structure which can be -// more trivially derived from config, and more flexibly rearranged. -// drag/drop watch rows -> tabs, tabs -> watch rows, etc. -// [ ] frontend entities need to be the "upstream state" for windows, panels, -// tabs, etc. - entities can be mapped to caches of window/panel/view state -// in purely immediate-mode fashion, so the only *state* part of the -// equation only has to do with the string tree. -// [ ] config hot-reloading using the wins from the previous points -// [ ] undo/redo, using the wins from the previous points -// [ ] watch table UI - hidden table boundaries, special-cased control hacks -// [ ] hash store -> need to somehow hold on to hash blobs which are still -// depended upon by usage layers, e.g. extra dependency refcount, e.g. -// text cache can explicitly correllate nodes in its cache to hashes, -// bump their refcount - this would keep the hash correllated to its key -// and it would prevent it from being evicted (output debug string perf) +// [ ] config hot-reloading, using cfg wins +// [ ] undo/redo, using cfg wins +// [ ] back/forward, using cfg wins // [ ] autocompletion lister, file lister, function lister, command lister, // etc., all need to be merged, and optionally contextualized/filtered. // right-clicking a tab should be equivalent to spawning a command lister, @@ -97,44 +115,21 @@ // [ ] Mohit-reported breakpoint not hitting - may be similar thing to @bpmiss // // [ ] CLI argument over-mangling? -// -// [ ] OutputDebugString spam, keeping way too much around! -// // [ ] fix light themes // [ ] make `array` view rule work with actual array types, to change their // size dynamically -// -// -// [ ] auto view rule templates (?) // [ ] single-line visualization busted with auto-view-rules applied, it seems... // not showing member variables, just commas, check w/ mohit -// [ ] auto-view-rules likely should apply at each level in the expression -// tree -// [ ] `slice` view rule - extend to support begin/end style as well // [ ] disasm starting address - need to use debug info for more correct // results... -// // [ ] linked list view rule -// -// [ ] investigate false exceptions, being reported while stepping through init code // [ ] output: add option for scroll-to-bottom - ensure this shows up in universal ctx menu -// // [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need // to prioritize the primary rdi -// // [ ] (reported by forrest) 'set-next-statement' -> prioritize current // module/symbol, in cases where one line maps to many voffs -// -// [ ] collapse upstream state for theme/bindings/settings into entities; use cache accelerators if needed to make up difference -// [ ] collapse upstream state for windows/panels/tabs into entities; use downstream window/view resource cache to make up the difference -// [ ] entity <-> mdesk paths -// // [ ] universal ctx menu address/watch options; e.g. watch -> memory; watch -> add watch // [ ] rich hover coverage; bitmap <-> geo <-> memory <-> disassembly <-> text; etc. -// -// [ ] save view column pcts; generalize to being a first-class thing in -// RD_View, e.g. by just having a string -> f32 store -// // [ ] visualize all breakpoints everywhere - source view should show up in // disasm, disasm should show up in source view, function should show up in // both, etc. @@ -146,7 +141,6 @@ //////////////////////////////// //~ rjf: Frontend/UI Pass Tasks // -// [ ] transient view timeout releasing // [ ] theme lister -> fonts & font sizes // [ ] "Browse..." buttons should adopt a more relevant starting search path, // if possible @@ -182,15 +176,11 @@ // [ ] max view rule // [ ] min view rule // -// [ ] double-click vs. single-click for folder navigation, see if we can infer // [ ] use backslashes on windows by default, forward slashes elsewhere (?) // // [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not // support it? // -// -// [ ] visualize conversion failures -// // [ ] I was a little confused about what a profile file was. I understood // what the user file was, but the profile file sounded like it should // perhaps be per-project, yet it sounded like it was meant to be somewhat @@ -203,16 +193,6 @@ // the files myself in the shell, but it seemed weird that there was no // "save" option in the menus. // -// [ ] Right-clicking on a thread in the Scheduler window pops up a context -// menu, but you can't actually see it because the tooltip for the thread -// draws on top of it, so you can't see the menu. -// -// [ ] In a "hover watch" (where you hover over a variable and it shows a pop- -// up watch window), if you expand an item near the bottom of the listing, -// it will be clipped to the bottom of the listing instead of showing the -// actual items (ie., it doesn't resize the listing based on what's -// actually visible) -// // [ ] ** One very nice feature of RemedyBG that I use all the time is the // ability to put "$err, hr" into the watch window, which will just show // the value of GetLastError() as a string. This is super useful for @@ -267,29 +247,13 @@ //////////////////////////////// //~ rjf: Hot, Feature Tasks (Not really "low priority" but less urgent than fixes) // -// [ ] @eval_upgrade -// [ ] new eval system; support strings, many address spaces, many debug -// infos, wide/async transforms (e.g. diff(blob1, blob2)) -// -// [ ] Fancy View Rules -// [ ] table column boundaries should be checked against *AFTER* table -// contents, not before -// [ ] `array:(x, y)` - multidimensional array -// +// [ ] eval wide/async transforms (e.g. diff(blob1, blob2)) // [ ] search-in-all-files -// // [ ] Memory View // [ ] memory view mutation controls // [ ] memory view user-made annotations -// -// [ ] undo/redo -// [ ] proper "go back" + "go forward" history navigations -// [ ] undo close tab would be nice. If not for everything, then at least -// just for source files -// // [ ] globally disable/configure default view rule-like things (string // viz for u8s in particular) -// // [ ] @feature processor/data breakpoints // [ ] @feature automatically snap to search matches when searching source files // [ ] automatically start search query with selected text @@ -314,8 +278,8 @@ // // [ ] @feature eval ui improvement features // [ ] serializing eval view maps -// [ ] view rule editors in hover-eval // [ ] view rule hook coverage +// [ ] `array:(x, y)` - multidimensional array // [ ] `each:(expr addition)` - apply some additional expression to all // elements in an array/linked list would be useful to look at only a // subset of an array of complex structs @@ -348,8 +312,6 @@ // [ ] font cache eviction (both for font tags, closing fp handles, and // rasterizations) // [ ] frontend speedup opportunities -// [ ] tables in UI -> currently building per-row, could probably cut down on -// # of boxes and # of draws by doing per-column in some cases? // [ ] font cache layer -> can probably cache (string*font*size) -> (run) too // (not just rasterization)... would save a *lot*, there is a ton of work // just in looking up & stitching stuff repeatedly @@ -366,6 +328,45 @@ // values for "unknown identifier". But also yellow arrow in call stack // disappears if font size gets too large. // [x] @cleanup central worker thread pool - eliminate per-layer thread pools +// [x] frontend config entities, serialization/deserialization, remove hacks, +// etc. - the entity structure should be dramatically simplified & made +// to reflect a more flexible string-tree data structure which can be +// more trivially derived from config, and more flexibly rearranged. +// drag/drop watch rows -> tabs, tabs -> watch rows, etc. +// [x] frontend entities need to be the "upstream state" for windows, panels, +// tabs, etc. - entities can be mapped to caches of window/panel/view state +// in purely immediate-mode fashion, so the only *state* part of the +// equation only has to do with the string tree. +// [x] watch table UI - hidden table boundaries, special-cased control hacks +// [x] hash store -> need to somehow hold on to hash blobs which are still +// depended upon by usage layers, e.g. extra dependency refcount, e.g. +// text cache can explicitly correllate nodes in its cache to hashes, +// bump their refcount - this would keep the hash correllated to its key +// and it would prevent it from being evicted (output debug string perf) +// [x] OutputDebugString spam, keeping way too much around! +// [x] auto view rule templates (?) +// [x] auto-view-rules likely should apply at each level in the expression +// tree +// [x] `slice` view rule - extend to support begin/end style as well +// [x] investigate false exceptions, being reported while stepping through init code +// [x] collapse upstream state for theme/bindings/settings into entities; use cache accelerators if needed to make up difference +// [x] collapse upstream state for windows/panels/tabs into entities; use downstream window/view resource cache to make up the difference +// [x] entity <-> mdesk paths +// [x] save view column pcts; generalize to being a first-class thing in +// RD_View, e.g. by just having a string -> f32 store +// [x] transient view timeout releasing +// [x] view rule editors in hover-eval +// [x] table column boundaries should be checked against *AFTER* table +// contents, not before +// [x] In a "hover watch" (where you hover over a variable and it shows a pop- +// up watch window), if you expand an item near the bottom of the listing, +// it will be clipped to the bottom of the listing instead of showing the +// actual items (ie., it doesn't resize the listing based on what's +// actually visible) +// [x] Right-clicking on a thread in the Scheduler window pops up a context +// menu, but you can't actually see it because the tooltip for the thread +// draws on top of it, so you can't see the menu. +// [x] double-click vs. single-click for folder navigation, see if we can infer //////////////////////////////// //~ rjf: Build Options From 833bee35e31c4c18e8e51b142d9cdeaeb93860ba Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 28 Mar 2025 15:50:19 -0700 Subject: [PATCH 288/755] sketch out new auto view rules for new expression language idea --- src/mule/mule_main.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index aecc5293..0e9073ac 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -106,7 +106,7 @@ void optimized_struct_parameters_eval_tests(void); #include #include -raddbg_auto_view_rule(std::vector, wrap($expr._Mypair._Myval2), slice); +raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); struct Basics{ char a; @@ -146,11 +146,11 @@ struct Fixed_Array{ int count; }; -raddbg_auto_view_rule(Dynamic?, slice); struct Dynamic_Array{ Pair *pairs; int count; }; +raddbg_auto_view_rule(Dynamic_Array, slice); struct Struct_With_Embedded_Arrays{ int x; @@ -1620,8 +1620,7 @@ struct Bitmap int width; int height; }; -// raddbg_auto_view_rule(Bitmap, wrap(base) bitmap(width, height)); -raddbg_auto_view_rule(Bitmap, wrap($expr.base)); +raddbg_auto_view_rule(Bitmap, bitmap(base, width, height)); static unsigned int mule_bswap_u32(unsigned int x) From 1adf280354c957c96c5bb3eb010133384d0a34b3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 11:02:17 -0700 Subject: [PATCH 289/755] delete dead code in eval --- src/eval/eval_ir.c | 35 ----------------------------------- src/eval/eval_ir.h | 22 ---------------------- src/eval/eval_parse.c | 34 ---------------------------------- src/eval/eval_parse.h | 20 -------------------- src/eval/eval_types.h | 2 +- src/raddbg/raddbg_core.c | 2 +- 6 files changed, 2 insertions(+), 113 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9722f37d..0ebd975e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -82,8 +82,6 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); e_ir_state->type_auto_hook_cache_map->slots_count = 256; e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); - e_ir_state->irtree_and_type_cache_slots_count = 1024; - e_ir_state->irtree_and_type_cache_slots = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheSlot, e_ir_state->irtree_and_type_cache_slots_count); e_ir_state->string_id_gen = 0; e_ir_state->string_id_map = push_array(e_ir_state->arena, E_StringIDMap, 1); e_ir_state->string_id_map->id_slots_count = 1024; @@ -2993,39 +2991,6 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type return root; } -//////////////////////////////// -//~ rjf: IRified Expression Cache - -internal E_IRTreeAndType -e_irtree_and_type_from_expr__cached(E_Expr *expr) -{ - E_IRTreeAndType result = {&e_irnode_nil}; - { - U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->irtree_and_type_cache_slots_count; - E_IRTreeAndTypeCacheNode *node = 0; - for(E_IRTreeAndTypeCacheNode *n = e_ir_state->irtree_and_type_cache_slots[slot_idx].first; n != 0; n = n->next) - { - if(n->expr == expr) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheNode, 1); - SLLQueuePush(e_ir_state->irtree_and_type_cache_slots[slot_idx].first, e_ir_state->irtree_and_type_cache_slots[slot_idx].last, node); - node->irtree_and_type = e_irtree_and_type_from_expr(e_ir_state->arena, expr); - } - if(node != 0) - { - result = node->irtree_and_type; - } - } - return result; -} - //////////////////////////////// //~ rjf: Expression & IR-Tree => Lookup Rule diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 93210498..a11f7e87 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -310,21 +310,6 @@ struct E_IRCtx //////////////////////////////// //~ rjf: IR State -typedef struct E_IRTreeAndTypeCacheNode E_IRTreeAndTypeCacheNode; -struct E_IRTreeAndTypeCacheNode -{ - E_IRTreeAndTypeCacheNode *next; - E_Expr *expr; - E_IRTreeAndType irtree_and_type; -}; - -typedef struct E_IRTreeAndTypeCacheSlot E_IRTreeAndTypeCacheSlot; -struct E_IRTreeAndTypeCacheSlot -{ - E_IRTreeAndTypeCacheNode *first; - E_IRTreeAndTypeCacheNode *last; -}; - typedef struct E_IRState E_IRState; struct E_IRState { @@ -337,8 +322,6 @@ struct E_IRState // rjf: caches E_UsedTagMap *used_tag_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; - U64 irtree_and_type_cache_slots_count; - E_IRTreeAndTypeCacheSlot *irtree_and_type_cache_slots; U64 string_id_gen; E_StringIDMap *string_id_map; }; @@ -468,11 +451,6 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); -//////////////////////////////// -//~ rjf: IRified Expression Cache - -internal E_IRTreeAndType e_irtree_and_type_from_expr__cached(E_Expr *expr); - //////////////////////////////// //~ rjf: Expression & IR-Tree => Lookup Rule diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 9ab30a5c..6ecd95eb 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -634,8 +634,6 @@ e_select_parse_ctx(E_ParseCtx *ctx) } arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); e_parse_state->ctx = ctx; - e_parse_state->parse_cache_slots_count = 1024; - e_parse_state->parse_cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->parse_cache_slots_count); } internal U32 @@ -2306,35 +2304,3 @@ e_parse_expr_from_text(Arena *arena, String8 text) scratch_end(scratch); return parse; } - -internal E_Parse -e_parse_expr_from_text__cached(String8 text) -{ - E_Parse parse = {0, &e_expr_nil}; - U64 hash = e_hash_from_string(5381, str8_struct(&text)); - U64 slot_idx = hash%e_parse_state->parse_cache_slots_count; - E_ParseCacheNode *node = 0; - for(E_ParseCacheNode *n = e_parse_state->parse_cache_slots[slot_idx].first; n != 0; n = n->next) - { - if(str8_match(n->string, text, 0)) - { - node = n; - break; - } - } - if(node == 0) - { - Temp scratch = scratch_begin(0, 0); - node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); - SLLQueuePush(e_parse_state->parse_cache_slots[slot_idx].first, e_parse_state->parse_cache_slots[slot_idx].last, node); - node->string = push_str8_copy(e_parse_state->arena, text); - E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); - node->parse = e_parse_expr_from_text_tokens(e_parse_state->arena, node->string, &tokens); - scratch_end(scratch); - } - if(node != 0) - { - parse = node->parse; - } - return parse; -} diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 37343f2e..39e9c716 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -190,31 +190,12 @@ struct E_ParseCtx //////////////////////////////// //~ rjf: Parse State (stateful thread-local caching mechanisms, not provided by user) -typedef struct E_ParseCacheNode E_ParseCacheNode; -struct E_ParseCacheNode -{ - E_ParseCacheNode *next; - String8 string; - E_Parse parse; -}; - -typedef struct E_ParseCacheSlot E_ParseCacheSlot; -struct E_ParseCacheSlot -{ - E_ParseCacheNode *first; - E_ParseCacheNode *last; -}; - typedef struct E_ParseState E_ParseState; struct E_ParseState { Arena *arena; U64 arena_eval_start_pos; E_ParseCtx *ctx; - - // rjf: string -> parse cache - E_ParseCacheSlot *parse_cache_slots; - U64 parse_cache_slots_count; }; //////////////////////////////// @@ -296,6 +277,5 @@ internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_Tok internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); -internal E_Parse e_parse_expr_from_text__cached(String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index df66f01c..e106fd52 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -184,7 +184,7 @@ struct E_ConsTypeParams E_EnumVal *enum_vals; }; -typedef struct E_ConsTypeNode E_ConsTypeNode; +typedef struct E_ConsTypeNode E_ConsTypeNode; struct E_ConsTypeNode { E_ConsTypeNode *key_next; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 540d3574..7c43a1f7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13892,7 +13892,7 @@ rd_frame(void) { RD_Cfg *watch = n->v; String8 expr = rd_expr_from_cfg(watch); - E_Parse parse = e_parse_expr_from_text__cached(expr); + E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); if(parse.msgs.max_kind == E_MsgKind_Null) { for(E_Expr *expr = parse.exprs.first; expr != &e_expr_nil; expr = expr->next) From fbe0d3bc2e9181fa6d3582c750841d89017d579d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 11:41:14 -0700 Subject: [PATCH 290/755] set up eval scratch; promote raddbg_markup to base layer, plug in custom codebase vsnprintf --- build.bat | 1 + project.4coder | 13 ++- src/base/base_markup.h | 4 + src/eval/eval_interpret.c | 7 +- src/lib_raddbg_markup/raddbg_markup.h | 2 + src/raddbg/raddbg_main.c | 10 +- src/scratch/eval_scratch.c | 151 ++++++++++++++++++++++++++ 7 files changed, 175 insertions(+), 13 deletions(-) create mode 100644 src/scratch/eval_scratch.c diff --git a/build.bat b/build.bat index 0c9e0463..343f3f37 100644 --- a/build.bat +++ b/build.bat @@ -114,6 +114,7 @@ if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_fr if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1 if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1 if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 +if "%eval_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\eval_scratch.c %compile_link% %out%eval_scratch.exe || exit /b 1 if "%textperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\textperf.c %compile_link% %out%textperf.exe || exit /b 1 if "%convertperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\convertperf.c %compile_link% %out%convertperf.exe || exit /b 1 if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1 diff --git a/project.4coder b/project.4coder index 6e727228..585fdf9b 100644 --- a/project.4coder +++ b/project.4coder @@ -46,12 +46,15 @@ load_paths = commands = { //- rjf: fkey command slots (change locally but do not commit) - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + + //- rjf: [raddbg] + // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + + //- rjf: [eval_scratch] + .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + + //- rjf: running target .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - // .f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - // .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - // .f3 = { .win = "pushd build && textperf.exe --capture && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_markup.h b/src/base/base_markup.h index fd291375..8a1c6578 100644 --- a/src/base/base_markup.h +++ b/src/base/base_markup.h @@ -4,6 +4,10 @@ #ifndef BASE_MARKUP_H #define BASE_MARKUP_H +#define RADDBG_MARKUP_IMPLEMENTATION +#define RADDBG_MARKUP_VSNPRINTF raddbg_vsnprintf +#include "lib_raddbg_markup/raddbg_markup.h" + internal void set_thread_name(String8 string); internal void set_thread_namef(char *fmt, ...); #define ThreadNameF(...) (set_thread_namef(__VA_ARGS__)) diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 0ebd1ed1..5f994405 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -14,11 +14,12 @@ internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff) { e_interpret_ctx = ctx; - + // compute and apply frame base + if(primary_rdi != 0) { E_Interpretation frame_base = { .code = ~0 }; - + RDI_Procedure *proc = rdi_procedure_from_voff(primary_rdi, ip_voff); for(U64 loc_block_idx = proc->frame_base_location_first; loc_block_idx < proc->frame_base_location_opl; loc_block_idx += 1) { @@ -45,7 +46,7 @@ e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff break; } } - + if(frame_base.code == E_InterpretationCode_Good) { *ctx->frame_base = frame_base.value.u64; diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 2eb8a77e..84bddf4e 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -99,7 +99,9 @@ extern "C" long long _InterlockedExchangeAdd64(long long volatile*, long long); #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) +#if RADDBG_MARKUP_DEFAULT_VSNPRINTF int RADDBG_MARKUP_VSNPRINTF(char * const, unsigned long long const, const char * const, va_list); +#endif #if defined(__cplusplus) } #endif diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index e6f78215..a127444a 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -27,7 +27,7 @@ // - The hover evaluation feature has been majorly upgraded to support all // features normally available in the `Watch` view. Hover evaluations now // explicitly show type information, and contain a view rule column, which -// can be edited in an identical way as the `Watch` view. +// can be edited in a way identical to the `Watch` view. // - Added "auto tabs", which are colored differently than normal tabs. These // tabs are automatically opened by the debugger when snapping to source code // which is not already opened. They are automatically replaced and recycled @@ -42,12 +42,13 @@ // those purposes, the `Threads` view is sufficient if not desirable, and // the extra information provided by `Processes` and `Machines`, while useful // in other contexts, is not useful in that common case. The `Machines` view -// now shows a superset of the information previosuly found in the +// now shows a superset of the information previously found in the // `Scheduler` view. // - The two separate interfaces for editing threads, breakpoints, and watch // pins (the right-click context menu and the dedicated tabs) have been -// merged. -// - Added the ability to add a list environment strings to targets. +// merged. Both interfaces support exactly the same features in exactly the +// same way. +// - Added the ability to add a list of environment strings to targets. // - The debugger releases are now packaged with a `raddbg_markup.h` // single-header library which contains a number of source code markup tools // which can be used in your programs. Some of these features are for direct @@ -388,7 +389,6 @@ //- rjf: [lib] #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" -#include "lib_raddbg_markup/raddbg_markup.h" //- rjf: [h] #include "base/base_inc.h" diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c new file mode 100644 index 00000000..3b43e616 --- /dev/null +++ b/src/scratch/eval_scratch.c @@ -0,0 +1,151 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Includes + +//- rjf: [h] +#include "base/base_inc.h" +#include "os/os_inc.h" +#include "rdi_format/rdi_format_local.h" +#include "regs/regs.h" +#include "regs/rdi/regs_rdi.h" +#include "eval/eval_inc.h" + +//- rjf: [c] +#include "base/base_inc.c" +#include "os/os_inc.c" +#include "rdi_format/rdi_format_local.c" +#include "regs/regs.c" +#include "regs/rdi/regs_rdi.c" +#include "eval/eval_inc.c" + +//////////////////////////////// +//~ rjf: Entry Point + +internal void +entry_point(CmdLine *cmdline) +{ + Arena *arena = arena_alloc(); + char *indent_spaces = " "; + E_TypeCtx *type_ctx = push_array(arena, E_TypeCtx, 1); + e_select_type_ctx(type_ctx); + E_ParseCtx *parse_ctx = push_array(arena, E_ParseCtx, 1); + e_select_parse_ctx(parse_ctx); + E_IRCtx *ir_ctx = push_array(arena, E_IRCtx, 1); + e_select_ir_ctx(ir_ctx); + E_InterpretCtx *interpret_ctx = push_array(arena, E_InterpretCtx, 1); + e_select_interpret_ctx(interpret_ctx, 0, 0); + String8 exprs[] = + { + str8_lit("123"), + }; + for EachElement(idx, exprs) + { + //- rjf: begin expression + String8 expr_text = exprs[idx]; + raddbg_log("`%S`\n", expr_text); + + //- rjf: tokenize + E_TokenArray tokens = e_token_array_from_text(arena, expr_text); + raddbg_log(" tokens:\n"); + for EachIndex(idx, tokens.count) + { + E_Token token = tokens.v[idx]; + String8 token_string = str8_substr(expr_text, token.range); + raddbg_log(" %S: `%S`\n", e_token_kind_strings[token.kind], token_string); + } + + //- rjf: parse + E_Parse parse = e_parse_expr_from_text_tokens(arena, expr_text, &tokens); + { + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *expr; + S32 indent; + }; + raddbg_log(" expr:\n"); + Task start_task = {0, parse.exprs.first, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_Expr *expr = t->expr; + raddbg_log("%.*s%S", (int)t->indent*2, indent_spaces, e_expr_kind_strings[expr->kind]); + switch(expr->kind) + { + default:{}break; + case E_ExprKind_LeafU64: + { + raddbg_log(" (%I64u)", expr->value.u64); + }break; + } + raddbg_log("\n"); + for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(arena, Task, 1); + task->next = t->next; + t->next = task; + task->expr = child; + task->indent = t->indent+1; + } + } + } + + //- rjf: type + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, parse.exprs.first); + { + raddbg_log(" type:\n"); + S32 indent = 2; + for(E_TypeKey type_key = irtree.type_key; + !e_type_key_match(e_type_key_zero(), type_key); + type_key = e_type_direct_from_key(type_key), + indent += 1) + { + E_Type *type = e_type_from_key(arena, type_key); + raddbg_log("%.*s%S\n", (int)indent*2, indent_spaces, e_kind_basic_string_table[type->kind]); + } + } + + //- rjf: irtree + { + typedef struct Task Task; + struct Task + { + Task *next; + E_IRNode *irnode; + S32 indent; + }; + raddbg_log(" ir_tree:\n"); + Task start_task = {0, irtree.root, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_IRNode *irnode = t->irnode; + raddbg_log("%.*s", (int)t->indent*2, indent_spaces); + switch(irnode->op) + { + default:{}break; +#define X(name) case RDI_EvalOp_##name:{raddbg_log(" " #name);}break; + RDI_EvalOp_XList +#undef X + } + if(irnode->value.u64 != 0) + { + raddbg_log(" (%I64u)", irnode->value.u64); + } + raddbg_log("\n"); + for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(arena, Task, 1); + task->next = t->next; + t->next = task; + task->irnode = child; + task->indent = t->indent+1; + } + } + } + + } +} From 17ff4da9bffdf9d3c3b645e6592c19893678da53 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 13:09:30 -0700 Subject: [PATCH 291/755] more eval scratch work --- src/base/base_core.h | 26 +++++++++- src/eval/eval_core.h | 4 +- src/eval/eval_interpret.c | 6 +-- src/eval/eval_parse.c | 71 +++++++++++++++------------ src/lib_rdi_format/rdi_format_parse.c | 1 - src/scratch/eval_scratch.c | 34 +++++++------ 6 files changed, 88 insertions(+), 54 deletions(-) diff --git a/src/base/base_core.h b/src/base/base_core.h index 441fec7f..cc0a6545 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -382,11 +382,33 @@ typedef S64 B64; typedef float F32; typedef double F64; typedef void VoidProc(void); -typedef struct U128 U128; -struct U128 +typedef union U128 U128; +union U128 { + U8 u8[16]; + U16 u16[8]; + U32 u32[4]; U64 u64[2]; }; +typedef union U256 U256; +union U256 +{ + U8 u8[32]; + U16 u16[16]; + U32 u32[8]; + U64 u64[4]; + U128 u128[2]; +}; +typedef union U512 U512; +union U512 +{ + U8 u8[64]; + U16 u16[32]; + U32 u32[16]; + U64 u64[8]; + U128 u128[4]; + U256 u256[2]; +}; //////////////////////////////// //~ rjf: Basic Types & Spaces diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 650597b8..a9d1fd4a 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -42,8 +42,8 @@ struct E_MsgList typedef union E_Value E_Value; union E_Value { - U64 u512[8]; - U64 u256[4]; + U512 u512; + U256 u256; U128 u128; U64 u64; U32 u32; diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 5f994405..ee5c96f3 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -572,13 +572,13 @@ e_interpret(String8 bytecode) case RDI_EvalOp_EqEq: { - B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512); + B32 result = MemoryMatchArray(svals[0].u512.u64, svals[1].u512.u64); nval.u64 = !!result; }break; case RDI_EvalOp_NtEq: { - B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512); + B32 result = MemoryMatchArray(svals[0].u512.u64, svals[1].u512.u64); nval.u64 = !result; }break; @@ -813,7 +813,7 @@ e_interpret(String8 bytecode) if(offset + bytes_to_read <= sizeof(E_Value)) { E_Value src_val = svals[1]; - MemoryCopy(&nval.u512[0], (U8 *)(&src_val.u512[0]) + offset, bytes_to_read); + MemoryCopy(&nval.u512.u64[0], (U8 *)(&src_val.u512.u64[0]) + offset, bytes_to_read); } }break; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 6ecd95eb..6076f906 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -633,6 +633,10 @@ e_select_parse_ctx(E_ParseCtx *ctx) e_parse_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); + 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; } e_parse_state->ctx = ctx; } @@ -1498,43 +1502,46 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to arch = module->arch; U64 all_location_data_size = 0; U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; + loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) + default:{mapped_identifier = 0;}break; + case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; + bytecode_stream:; { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) { - break; + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; + loc_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); + }break; + case RDI_LocationKind_ValReg: + { + MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); + }break; + } } } } diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index 6f51204d..f099ec6c 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -834,4 +834,3 @@ rdi_size_from_bytecode_stream(RDI_U8 *ptr, RDI_U8 *opl) } return bytecode_size; } - diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c index 3b43e616..8b4de5b0 100644 --- a/src/scratch/eval_scratch.c +++ b/src/scratch/eval_scratch.c @@ -27,7 +27,7 @@ internal void entry_point(CmdLine *cmdline) { Arena *arena = arena_alloc(); - char *indent_spaces = " "; + char *indent_spaces = " "; E_TypeCtx *type_ctx = push_array(arena, E_TypeCtx, 1); e_select_type_ctx(type_ctx); E_ParseCtx *parse_ctx = push_array(arena, E_ParseCtx, 1); @@ -39,6 +39,8 @@ entry_point(CmdLine *cmdline) String8 exprs[] = { str8_lit("123"), + str8_lit("1 + 2"), + str8_lit("foo"), }; for EachElement(idx, exprs) { @@ -48,12 +50,12 @@ entry_point(CmdLine *cmdline) //- rjf: tokenize E_TokenArray tokens = e_token_array_from_text(arena, expr_text); - raddbg_log(" tokens:\n"); + raddbg_log(" tokens:\n"); for EachIndex(idx, tokens.count) { E_Token token = tokens.v[idx]; String8 token_string = str8_substr(expr_text, token.range); - raddbg_log(" %S: `%S`\n", e_token_kind_strings[token.kind], token_string); + raddbg_log(" %S: `%S`\n", e_token_kind_strings[token.kind], token_string); } //- rjf: parse @@ -66,13 +68,13 @@ entry_point(CmdLine *cmdline) E_Expr *expr; S32 indent; }; - raddbg_log(" expr:\n"); + raddbg_log(" expr:\n"); Task start_task = {0, parse.exprs.first, 2}; Task *first_task = &start_task; for(Task *t = first_task; t != 0; t = t->next) { E_Expr *expr = t->expr; - raddbg_log("%.*s%S", (int)t->indent*2, indent_spaces, e_expr_kind_strings[expr->kind]); + raddbg_log("%.*s%S", (int)t->indent*4, indent_spaces, e_expr_kind_strings[expr->kind]); switch(expr->kind) { default:{}break; @@ -82,13 +84,15 @@ entry_point(CmdLine *cmdline) }break; } raddbg_log("\n"); + Task *last_task = t; for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) { Task *task = push_array(arena, Task, 1); - task->next = t->next; - t->next = task; + task->next = last_task->next; + last_task->next = task; task->expr = child; task->indent = t->indent+1; + last_task = task; } } } @@ -96,7 +100,7 @@ entry_point(CmdLine *cmdline) //- rjf: type E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, parse.exprs.first); { - raddbg_log(" type:\n"); + raddbg_log(" type:\n"); S32 indent = 2; for(E_TypeKey type_key = irtree.type_key; !e_type_key_match(e_type_key_zero(), type_key); @@ -104,7 +108,7 @@ entry_point(CmdLine *cmdline) indent += 1) { E_Type *type = e_type_from_key(arena, type_key); - raddbg_log("%.*s%S\n", (int)indent*2, indent_spaces, e_kind_basic_string_table[type->kind]); + raddbg_log("%.*s%S\n", (int)indent*4, indent_spaces, e_kind_basic_string_table[type->kind]); } } @@ -117,17 +121,17 @@ entry_point(CmdLine *cmdline) E_IRNode *irnode; S32 indent; }; - raddbg_log(" ir_tree:\n"); + raddbg_log(" ir_tree:\n"); Task start_task = {0, irtree.root, 2}; Task *first_task = &start_task; for(Task *t = first_task; t != 0; t = t->next) { E_IRNode *irnode = t->irnode; - raddbg_log("%.*s", (int)t->indent*2, indent_spaces); + raddbg_log("%.*s", (int)t->indent*4, indent_spaces); switch(irnode->op) { default:{}break; -#define X(name) case RDI_EvalOp_##name:{raddbg_log(" " #name);}break; +#define X(name) case RDI_EvalOp_##name:{raddbg_log(#name);}break; RDI_EvalOp_XList #undef X } @@ -136,13 +140,15 @@ entry_point(CmdLine *cmdline) raddbg_log(" (%I64u)", irnode->value.u64); } raddbg_log("\n"); + Task *last_task = t; for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) { Task *task = push_array(arena, Task, 1); - task->next = t->next; - t->next = task; + task->next = last_task->next; + last_task->next = task; task->irnode = child; task->indent = t->indent+1; + last_task = task; } } } From a5d6e8a33587aaa1641c3322eea5811e68ecf57b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 13:48:19 -0700 Subject: [PATCH 292/755] make eval ctxs more robust to missing info, e.g. in the test harness case --- src/ctrl/ctrl_core.c | 2 +- src/dasm_cache/dasm_cache.c | 10 +++++----- src/dbg_engine/dbg_engine_core.c | 6 +++--- src/dbgi/dbgi.c | 4 ++-- src/dbgi/dbgi.h | 1 - src/eval/eval.mdesk | 2 +- src/eval/eval_core.h | 5 +++++ src/eval/eval_ir.c | 7 ++++--- src/eval/eval_parse.c | 7 ++++--- src/eval/eval_types.c | 1 + src/eval/generated/eval.meta.c | 2 +- src/eval/generated/eval.meta.h | 2 +- src/lib_rdi_format/rdi_format_parse.h | 1 + src/raddbg/raddbg_core.c | 12 ++++++------ src/raddbg/raddbg_views.c | 2 +- src/raddbg/raddbg_widgets.c | 2 +- src/scratch/eval_scratch.c | 6 ++++++ 17 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ab1c1614..360d5d3e 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4624,7 +4624,7 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; - eval_modules_primary->rdi = &di_rdi_parsed_nil; + eval_modules_primary->rdi = &rdi_parsed_nil; eval_modules_primary->vaddr_range = r1u64(0, max_U64); { U64 eval_module_idx = 0; diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index a8aa6776..d3360793 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -532,7 +532,7 @@ ASYNC_WORK_DEF(dasm_parse_work) } //- rjf: get dbg info - RDI_Parsed *rdi = &di_rdi_parsed_nil; + RDI_Parsed *rdi = &rdi_parsed_nil; if(got_task && params.dbgi_key.path.size != 0) { rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, max_U64); @@ -573,7 +573,7 @@ ASYNC_WORK_DEF(dasm_parse_work) // rjf: push strings derived from voff -> line info if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines)) { - if(rdi != &di_rdi_parsed_nil) + if(rdi != &rdi_parsed_nil) { U64 voff = (params.vaddr+off) - params.base_vaddr; U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff); @@ -655,7 +655,7 @@ ASYNC_WORK_DEF(dasm_parse_work) String8 addr_part = {0}; if(params.style_flags & DASM_StyleFlag_Addresses) { - addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off); + addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off); } String8 code_bytes_part = {0}; if(params.style_flags & DASM_StyleFlag_CodeBytes) @@ -677,7 +677,7 @@ ASYNC_WORK_DEF(dasm_parse_work) code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0); } String8 symbol_part = {0}; - if(inst.jump_dest_vaddr != 0 && rdi != &di_rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames) + if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames) { RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr); if(scope_idx != 0) @@ -752,7 +752,7 @@ ASYNC_WORK_DEF(dasm_parse_work) { n->info_arena = info_arena; MemoryCopyStruct(&n->info, &info); - if(rdi != &di_rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames)) + if(rdi != &rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames)) { n->change_gen = change_gen; } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index b61e3c6d..ee357f51 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -811,7 +811,7 @@ d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name) RDI_NameMapKind_GlobalVariables, RDI_NameMapKind_Procedures, }; - if(rdi != &di_rdi_parsed_nil) + if(rdi != &rdi_parsed_nil) { for(U64 name_map_kind_idx = 0; name_map_kind_idx < ArrayCount(name_map_kinds); @@ -1038,7 +1038,7 @@ d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key, // rjf: file_path_normalized * rdi -> src_id B32 good_src_id = 0; U32 src_id = 0; - if(rdi != &di_rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") + if(rdi != &rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") { RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths); RDI_ParsedNameMap map = {0}; @@ -1136,7 +1136,7 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64 // rjf: file_path_normalized * rdi -> src_id B32 good_src_id = 0; U32 src_id = 0; - if(rdi != &di_rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") + if(rdi != &rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") { RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths); RDI_ParsedNameMap map = {0}; diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index a3fbccaf..15ccb4b3 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -582,7 +582,7 @@ internal RDI_Parsed * di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) { ProfBeginFunction(); - RDI_Parsed *result = &di_rdi_parsed_nil; + RDI_Parsed *result = &rdi_parsed_nil; if(key->path.size != 0) { Temp scratch = scratch_begin(0, 0); @@ -1086,7 +1086,7 @@ ASYNC_WORK_DEF(di_parse_work) //////////////////////////// //- rjf: do initial parse of rdi // - RDI_Parsed rdi_parsed_maybe_compressed = di_rdi_parsed_nil; + RDI_Parsed rdi_parsed_maybe_compressed = rdi_parsed_nil; { RDI_ParseStatus parse_status = rdi_parse((U8 *)file_base, file_props.size, &rdi_parsed_maybe_compressed); (void)parse_status; diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index 76754bd4..ecf29632 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -379,7 +379,6 @@ struct DI_Shared global DI_Shared *di_shared = 0; thread_static DI_TCTX *di_tctx = 0; -global RDI_Parsed di_rdi_parsed_nil = {0}; //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 4f281812..82bc175a 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -125,7 +125,7 @@ E_ExprKindTable: { LeafU64 Null 0 "U64" "" "" "" } { LeafF64 Null 0 "F64" "" "" "" } { LeafF32 Null 0 "F32" "" "" "" } - { LeafIdent Null 0 "leaf_ident" "" "" "" } + { LeafIdentifier Null 0 "leaf_identifier" "" "" "" } { LeafOffset Null 0 "leaf_offset" "" "" "" } { LeafValue Null 0 "leaf_value" "" "" "" } { LeafFilePath Null 0 "leaf_filepath" "" "" "" } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index a9d1fd4a..df697586 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -142,6 +142,11 @@ struct E_Module #include "eval/generated/eval.meta.h" +//////////////////////////////// +//~ rjf: Globals + +global read_only E_Module e_module_nil = {&rdi_parsed_nil}; + //////////////////////////////// //~ rjf: Basic Helper Functions diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0ebd975e..24d2a320 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -75,6 +75,7 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); + if(ctx->macro_map == 0) {ctx->macro_map = &e_string2expr_map_nil;} e_ir_state->ctx = ctx; e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); e_ir_state->used_tag_map->slots_count = 64; @@ -1230,7 +1231,7 @@ E_IRGEN_FUNCTION_DEF(wrap) Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) { - if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + if(t->expr->kind == E_ExprKind_LeafIdentifier && str8_match(t->expr->string, str8_lit("$expr"), 0)) { E_Expr *original_expr_ref = e_expr_ref(arena, expr); if(t->parent != &e_expr_nil) @@ -2530,7 +2531,7 @@ E_IRGEN_FUNCTION_DEF(default) }break; //- rjf: leaf identifiers - case E_ExprKind_LeafIdent: + case E_ExprKind_LeafIdentifier: { E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); if(macro_expr == &e_expr_nil) @@ -2618,7 +2619,7 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; result = e_irtree_and_type_from_expr(arena, rhs); - if(lhs->kind != E_ExprKind_LeafIdent) + if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); } diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 6076f906..2a4b1b66 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -637,6 +637,7 @@ e_select_parse_ctx(E_ParseCtx *ctx) 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->primary_module == 0){ ctx->primary_module = &e_module_nil; } e_parse_state->ctx = ctx; } @@ -855,7 +856,7 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) }break; case E_ExprKind_LeafBytecode: case E_ExprKind_LeafMember: - case E_ExprKind_LeafIdent: + case E_ExprKind_LeafIdentifier: { str8_list_push(arena, out, expr->string); }break; @@ -1058,7 +1059,7 @@ e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, { E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; - if(exprl->kind == E_ExprKind_LeafIdent) + if(exprl->kind == E_ExprKind_LeafIdentifier) { e_string2expr_map_insert(arena, map, exprl->string, exprr); } @@ -1869,7 +1870,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to //- rjf: map failure -> attach as leaf identifier, to be resolved later if(!mapped_identifier) { - atom = e_push_expr(arena, E_ExprKind_LeafIdent, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); atom->string = token_string; it += 1; } diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 25527892..c2822449 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -241,6 +241,7 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->arena = arena; e_type_state->arena_eval_start_pos = arena_pos(e_type_state->arena); } + if(ctx->primary_module == 0) {ctx->primary_module = &e_module_nil;} arena_pop_to(e_type_state->arena, e_type_state->arena_eval_start_pos); e_type_state->ctx = ctx; e_type_state->cons_id_gen = 0; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 770eb9c2..48dd90f6 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -57,7 +57,7 @@ str8_lit_comp("LeafBool"), str8_lit_comp("LeafU64"), str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), -str8_lit_comp("LeafIdent"), +str8_lit_comp("LeafIdentifier"), str8_lit_comp("LeafOffset"), str8_lit_comp("LeafValue"), str8_lit_comp("LeafFilePath"), diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 3288fa6c..2bbf680a 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -132,7 +132,7 @@ E_ExprKind_LeafBool, E_ExprKind_LeafU64, E_ExprKind_LeafF64, E_ExprKind_LeafF32, -E_ExprKind_LeafIdent, +E_ExprKind_LeafIdentifier, E_ExprKind_LeafOffset, E_ExprKind_LeafValue, E_ExprKind_LeafFilePath, diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 1e82e501..59cedfa5 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -132,6 +132,7 @@ static union RDI_Local local; } rdi_nil_element_union = {0}; +static RDI_Parsed rdi_parsed_nil = {0}; //////////////////////////////// //~ Top-Level Parsing API diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7c43a1f7..e8be644f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3376,7 +3376,7 @@ rd_query_from_eval_string(Arena *arena, String8 string) { Temp scratch = scratch_begin(&arena, 1); E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; - if(expr->kind == E_ExprKind_LeafIdent && + if(expr->kind == E_ExprKind_LeafIdentifier && str8_match(expr->qualifier, str8_lit("query"), 0)) { result = expr->string; @@ -6036,7 +6036,7 @@ rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) // rjf: try implicit non-define arguments for(E_Expr *param = tag->first->next; param != &e_expr_nil && !got_fmt; param = param->next) { - if(param->kind == E_ExprKind_LeafIdent) + if(param->kind == E_ExprKind_LeafIdentifier) { for EachEnumVal(R_Tex2DFormat, f) { @@ -10747,7 +10747,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f }break; case E_Mode_Value: { - MemoryCopy(string_buffer, &eval.value.u512[0], Min(string_buffer_size, sizeof(eval.value))); + MemoryCopy(string_buffer, &eval.value.u512.u64[0], Min(string_buffer_size, sizeof(eval.value))); }break; } String8 string = {0}; @@ -13449,7 +13449,7 @@ rd_frame(void) U64 eval_modules_count = Max(1, all_modules.count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; - eval_modules_primary->rdi = &di_rdi_parsed_nil; + eval_modules_primary->rdi = &rdi_parsed_nil; eval_modules_primary->vaddr_range = r1u64(0, max_U64); DI_Key primary_dbgi_key = {0}; ProfScope("produce all eval modules") @@ -15640,7 +15640,7 @@ Z(getting_started) // rjf: snap to resolved line B32 missing_rip = (rip_vaddr == 0); B32 dbgi_missing = (dbgi_key.min_timestamp == 0 || dbgi_key.path.size == 0); - B32 dbgi_pending = !dbgi_missing && rdi == &di_rdi_parsed_nil; + B32 dbgi_pending = !dbgi_missing && rdi == &rdi_parsed_nil; B32 has_line_info = (line.voff_range.max != 0); B32 has_module = (module != &ctrl_entity_nil); B32 has_dbg_info = has_module && !dbgi_missing; @@ -17312,7 +17312,7 @@ Z(getting_started) ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) { - if(t->expr->kind == E_ExprKind_LeafIdent) + if(t->expr->kind == E_ExprKind_LeafIdentifier) { E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, t->expr->string); if(macro_expr != &e_expr_nil) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 16929f96..8cdfb900 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1468,7 +1468,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) { - if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0)) + if(t->expr->kind == E_ExprKind_LeafIdentifier && str8_match(t->expr->string, str8_lit("$expr"), 0)) { E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->expr); if(t->parent != &e_expr_nil) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 193f6396..2d472577 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -501,7 +501,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0); - if(rdi != &di_rdi_parsed_nil) + if(rdi != &rdi_parsed_nil) { RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff); String8 name = {0}; diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c index 8b4de5b0..a0b8895e 100644 --- a/src/scratch/eval_scratch.c +++ b/src/scratch/eval_scratch.c @@ -41,6 +41,7 @@ entry_point(CmdLine *cmdline) str8_lit("123"), str8_lit("1 + 2"), str8_lit("foo"), + str8_lit("foo(bar)"), }; for EachElement(idx, exprs) { @@ -82,6 +83,10 @@ entry_point(CmdLine *cmdline) { raddbg_log(" (%I64u)", expr->value.u64); }break; + case E_ExprKind_LeafIdentifier: + { + raddbg_log(" (`%S`)", expr->string); + }break; } raddbg_log("\n"); Task *last_task = t; @@ -153,5 +158,6 @@ entry_point(CmdLine *cmdline) } } + raddbg_log("\n"); } } From 999eca5e29cac852873ecdc401d35d8a632afd32 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 15:41:10 -0700 Subject: [PATCH 293/755] more old eval trimming --- src/eval/eval.mdesk | 146 +++++----- src/eval/eval_core.h | 474 +++++++++++++++++++++++++++++++++ src/eval/eval_interpret.h | 2 - src/eval/eval_ir.h | 185 ------------- src/eval/eval_parse.h | 149 ----------- src/eval/eval_types.c | 12 +- src/eval/eval_types.h | 137 ---------- src/eval/generated/eval.meta.c | 372 +++++++++++++------------- src/eval/generated/eval.meta.h | 6 +- src/scratch/eval_scratch.c | 2 +- 10 files changed, 740 insertions(+), 745 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 82bc175a..ec41dfa9 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -74,70 +74,70 @@ E_TypeKindTable: {Set "set" 0 } } -@table(name op_kind precedence string op_pre op_sep op_pos) +@table(name op_kind precedence op_pre op_sep op_pos) E_ExprKindTable: { - { Nil Null 0 "" "" "" "" } - { Ref Null 0 "" "" "" "" } + { Nil Null 0 "" "" "" } + { Ref Null 0 "" "" "" } - { ArrayIndex Null 0 "[]" "" "[" "]"} - { MemberAccess Null 0 "." "" "." "" } - { Deref UnaryPrefix 2 "*" "*" "" "" } - { Address UnaryPrefix 2 "&" "&" "" "" } + { ArrayIndex Null 0 "" "[" "]"} + { MemberAccess Null 0 "" "." "" } + { Deref UnaryPrefix 2 "*" "" "" } + { Address UnaryPrefix 2 "&" "" "" } - { Cast Null 1 "cast" "(" ")" "" } - { Sizeof UnaryPrefix 1 "sizeof" "sizeof" "(" ")"} - { Typeof UnaryPrefix 1 "typeof" "typeof" "(" ")"} - { ByteSwap UnaryPrefix 1 "bswap" "bswap" "(" ")"} + { Cast Null 1 "(" ")" "" } + { Sizeof UnaryPrefix 1 "sizeof" "(" ")"} + { Typeof UnaryPrefix 1 "typeof" "(" ")"} + { ByteSwap UnaryPrefix 1 "bswap" "(" ")"} - { Pos UnaryPrefix 2 "+" "+" "" "" } - { Neg UnaryPrefix 2 "-" "-" "" "" } - { LogNot UnaryPrefix 2 "!" "!" "" "" } - { BitNot UnaryPrefix 2 "~" "~" "" "" } - { Mul Binary 3 "*" "" "*" "" } - { Div Binary 3 "/" "" "/" "" } - { Mod Binary 3 "%" "" "%" "" } - { Add Binary 4 "+" "" "+" "" } - { Sub Binary 4 "-" "" "-" "" } - { LShift Binary 5 "<<" "" "<<" "" } - { RShift Binary 5 ">>" "" ">>" "" } - { Less Binary 6 "<" "" "<" "" } - { LsEq Binary 6 "<=" "" "<=" "" } - { Grtr Binary 6 ">" "" ">" "" } - { GrEq Binary 6 ">=" "" ">=" "" } - { EqEq Binary 7 "==" "" "==" "" } - { NtEq Binary 7 "!=" "" "!=" "" } + { Pos UnaryPrefix 2 "+" "" "" } + { Neg UnaryPrefix 2 "-" "" "" } + { LogNot UnaryPrefix 2 "!" "" "" } + { BitNot UnaryPrefix 2 "~" "" "" } + { Mul Binary 3 "" "*" "" } + { Div Binary 3 "" "/" "" } + { Mod Binary 3 "" "%" "" } + { Add Binary 4 "" "+" "" } + { Sub Binary 4 "" "-" "" } + { LShift Binary 5 "" "<<" "" } + { RShift Binary 5 "" ">>" "" } + { Less Binary 6 "" "<" "" } + { LsEq Binary 6 "" "<=" "" } + { Grtr Binary 6 "" ">" "" } + { GrEq Binary 6 "" ">=" "" } + { EqEq Binary 7 "" "==" "" } + { NtEq Binary 7 "" "!=" "" } - { BitAnd Binary 8 "&" "" "&" "" } - { BitXor Binary 9 "^" "" "^" "" } - { BitOr Binary 10 "|" "" "|" "" } - { LogAnd Binary 11 "&&" "" "&&" "" } - { LogOr Binary 12 "||" "" "||" "" } + { BitAnd Binary 8 "" "&" "" } + { BitXor Binary 9 "" "^" "" } + { BitOr Binary 10 "" "|" "" } + { LogAnd Binary 11 "" "&&" "" } + { LogOr Binary 12 "" "||" "" } - { Ternary Null 0 "? " "" "?" ":"} + { Ternary Null 0 "" "?" ":"} - { Call Null 0 "()" "(" "," ")"} + { Call Null 0 "(" "," ")"} - { LeafBytecode Null 0 "bytecode" "" "" "" } - { LeafMember Null 0 "member" "" "" "" } - { LeafStringLiteral Null 0 "string_literal" "" "" "" } - { LeafBool Null 0 "B32" "" "" "" } - { LeafU64 Null 0 "U64" "" "" "" } - { LeafF64 Null 0 "F64" "" "" "" } - { LeafF32 Null 0 "F32" "" "" "" } - { LeafIdentifier Null 0 "leaf_identifier" "" "" "" } - { LeafOffset Null 0 "leaf_offset" "" "" "" } - { LeafValue Null 0 "leaf_value" "" "" "" } - { LeafFilePath Null 0 "leaf_filepath" "" "" "" } + { LeafBytecode Null 0 "" "" "" } + { LeafMember Null 0 "" "" "" } + { LeafStringLiteral Null 0 "" "" "" } + { LeafBool Null 0 "" "" "" } + { LeafU64 Null 0 "" "" "" } + { LeafF64 Null 0 "" "" "" } + { LeafF32 Null 0 "" "" "" } + { LeafIdentifier Null 0 "" "" "" } + { LeafOffset Null 0 "" "" "" } + { LeafValue Null 0 "" "" "" } + { LeafFilePath Null 0 "" "" "" } - { TypeIdent Null 0 "type_ident" "" "" "" } - { Ptr Null 0 "ptr" "" "" "" } - { Array Null 0 "array" "" "" "" } - { Func Null 0 "function" "" "" "" } + { TypeIdent Null 0 "" "" "" } + { Ptr Null 0 "" "" "" } + { Array Null 0 "" "" "" } + { Func Null 0 "" "" "" } - { Define Binary 13 "=" "" "=" "" } + { Define Binary 13 "" "=" "" } - { Tag Null 0 "=>" "=>" "," "" } + { Tag Null 0 "=>" "," "" } } @table(name display_string) @@ -162,6 +162,12 @@ E_InterpretationCodeTable: COUNT, } +@data(String8) +e_token_kind_strings: +{ + @expand(E_TokenKindTable a) `str8_lit_comp("$(a.name)")` +} + @enum E_TypeKind: { @expand(E_TypeKindTable a) `$(a.name)`, @@ -178,46 +184,40 @@ E_InterpretationCodeTable: `LastIncomplete = E_TypeKind_IncompleteEnum`, } +@data(String8) e_type_kind_basic_string_table: +{ + @expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`; +} + +@data(U8) e_type_kind_basic_byte_size_table: +{ + @expand(E_TypeKindTable a) `$(a.basic_byte_size)`; +} + @enum(U32) E_ExprKind: { @expand(E_ExprKindTable a) `$(a.name)`, COUNT, } -@enum E_InterpretationCode: -{ - @expand(E_InterpretationCodeTable a) `$(a.name)`, - COUNT, -} - -@data(String8) -e_token_kind_strings: -{ - @expand(E_TokenKindTable a) `str8_lit_comp("$(a.name)")` -} - @data(String8) e_expr_kind_strings: { @expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")` } -@data(String8) e_interpretation_code_display_strings: -{ - @expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")` -} - @data(E_OpInfo) e_expr_kind_op_info_table: { @expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_pos)") }` } -@data(U8) e_kind_basic_byte_size_table: +@enum E_InterpretationCode: { - @expand(E_TypeKindTable a) `$(a.basic_byte_size)`; + @expand(E_InterpretationCodeTable a) `$(a.name)`, + COUNT, } -@data(String8) e_kind_basic_string_table: +@data(String8) e_interpretation_code_display_strings: { - @expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`; + @expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")` } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index df697586..7bcd86a1 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -114,6 +114,147 @@ struct E_Space }; }; +//////////////////////////////// +//~ rjf: Implicit Type Graph Key Types + +typedef enum E_TypeKeyKind +{ + E_TypeKeyKind_Null, + E_TypeKeyKind_Basic, + E_TypeKeyKind_Ext, + E_TypeKeyKind_Cons, + E_TypeKeyKind_Reg, + E_TypeKeyKind_RegAlias, +} +E_TypeKeyKind; + +typedef struct E_TypeKey E_TypeKey; +struct E_TypeKey +{ + E_TypeKeyKind kind; + U32 u32[3]; + // [0] -> E_TypeKind (Basic, Cons, Ext); Arch (Reg, RegAlias) + // [1] -> Type Index In RDI (Ext); Code (Reg, RegAlias); Type Index In Constructed (Cons) + // [2] -> RDI Index (Ext) +}; + +typedef struct E_TypeKeyNode E_TypeKeyNode; +struct E_TypeKeyNode +{ + E_TypeKeyNode *next; + E_TypeKey v; +}; + +typedef struct E_TypeKeyList E_TypeKeyList; +struct E_TypeKeyList +{ + E_TypeKeyNode *first; + E_TypeKeyNode *last; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Generated Code + +#include "generated/eval.meta.h" + +//////////////////////////////// +//~ rjf: Full Extracted Type Information Types + +typedef enum E_MemberKind +{ + E_MemberKind_Null, + E_MemberKind_DataField, + E_MemberKind_StaticData, + E_MemberKind_Method, + E_MemberKind_StaticMethod, + E_MemberKind_VirtualMethod, + E_MemberKind_VTablePtr, + E_MemberKind_Base, + E_MemberKind_VirtualBase, + E_MemberKind_NestedType, + E_MemberKind_Padding, + E_MemberKind_Query, + E_MemberKind_COUNT +} +E_MemberKind; + +typedef U32 E_TypeFlags; +enum +{ + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_External = (1<<2), + E_TypeFlag_IsPlainText = (1<<3), + E_TypeFlag_IsCodeText = (1<<4), + E_TypeFlag_IsPathText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), +}; + +typedef struct E_Member E_Member; +struct E_Member +{ + E_MemberKind kind; + E_TypeKey type_key; + String8 name; + U64 off; + E_TypeKeyList inheritance_key_chain; +}; + +typedef struct E_MemberNode E_MemberNode; +struct E_MemberNode +{ + E_MemberNode *next; + E_Member v; +}; + +typedef struct E_MemberList E_MemberList; +struct E_MemberList +{ + E_MemberNode *first; + E_MemberNode *last; + U64 count; +}; + +typedef struct E_MemberArray E_MemberArray; +struct E_MemberArray +{ + E_Member *v; + U64 count; +}; + +typedef struct E_EnumVal E_EnumVal; +struct E_EnumVal +{ + String8 name; + U64 val; +}; + +typedef struct E_EnumValArray E_EnumValArray; +struct E_EnumValArray +{ + E_EnumVal *v; + U64 count; +}; + +typedef struct E_Type E_Type; +struct E_Type +{ + E_TypeKind kind; + E_TypeFlags flags; + String8 name; + U64 byte_size; + U64 count; + U64 depth; + U32 off; + Arch arch; + E_TypeKey direct_type_key; + E_TypeKey owner_type_key; + E_TypeKey *param_type_keys; + E_Member *members; + E_EnumVal *enum_vals; +}; + //////////////////////////////// //~ rjf: Evaluation Modes @@ -137,6 +278,339 @@ struct E_Module E_Space space; }; +//////////////////////////////// +//~ rjf: Token Types + +typedef struct E_Token E_Token; +struct E_Token +{ + E_TokenKind kind; + Rng1U64 range; +}; + +typedef struct E_TokenChunkNode E_TokenChunkNode; +struct E_TokenChunkNode +{ + E_TokenChunkNode *next; + E_Token *v; + U64 count; + U64 cap; +}; + +typedef struct E_TokenChunkList E_TokenChunkList; +struct E_TokenChunkList +{ + E_TokenChunkNode *first; + E_TokenChunkNode *last; + U64 node_count; + U64 total_count; +}; + +typedef struct E_TokenArray E_TokenArray; +struct E_TokenArray +{ + E_Token *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Expression Tree Types + +typedef struct E_Expr E_Expr; +struct E_Expr +{ + E_Expr *first; + E_Expr *last; + E_Expr *first_tag; + E_Expr *last_tag; + E_Expr *next; + E_Expr *prev; + E_Expr *ref; + void *location; + E_ExprKind kind; + E_Mode mode; + E_Space space; + E_TypeKey type_key; + E_Value value; + String8 string; + String8 qualifier; + String8 bytecode; +}; + +typedef struct E_ExprChain E_ExprChain; +struct E_ExprChain +{ + E_Expr *first; + E_Expr *last; +}; + +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: IR Tree Types + +typedef struct E_IRNode E_IRNode; +struct E_IRNode +{ + E_IRNode *first; + E_IRNode *last; + E_IRNode *next; + RDI_EvalOp op; + E_Space space; + String8 string; + E_Value value; +}; + +typedef struct E_IRTreeAndType E_IRTreeAndType; +struct E_IRTreeAndType +{ + E_IRNode *root; + E_TypeKey type_key; + E_Member member; + E_Mode mode; + E_MsgList msgs; +}; + +//////////////////////////////// +//~ rjf: String -> Num + +typedef struct E_String2NumMapNode E_String2NumMapNode; +struct E_String2NumMapNode +{ + E_String2NumMapNode *order_next; + E_String2NumMapNode *hash_next; + String8 string; + U64 num; +}; + +typedef struct E_String2NumMapNodeArray E_String2NumMapNodeArray; +struct E_String2NumMapNodeArray +{ + E_String2NumMapNode **v; + U64 count; +}; + +typedef struct E_String2NumMapSlot E_String2NumMapSlot; +struct E_String2NumMapSlot +{ + E_String2NumMapNode *first; + E_String2NumMapNode *last; +}; + +typedef struct E_String2NumMap E_String2NumMap; +struct E_String2NumMap +{ + U64 slots_count; + U64 node_count; + E_String2NumMapSlot *slots; + E_String2NumMapNode *first; + E_String2NumMapNode *last; +}; + +//////////////////////////////// +//~ rjf: String -> Expr + +typedef struct E_String2ExprMapNode E_String2ExprMapNode; +struct E_String2ExprMapNode +{ + E_String2ExprMapNode *hash_next; + String8 string; + E_Expr *expr; + U64 poison_count; +}; + +typedef struct E_String2ExprMapSlot E_String2ExprMapSlot; +struct E_String2ExprMapSlot +{ + E_String2ExprMapNode *first; + E_String2ExprMapNode *last; +}; + +typedef struct E_String2ExprMap E_String2ExprMap; +struct E_String2ExprMap +{ + U64 slots_count; + E_String2ExprMapSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Member/Index Lookup Hooks + +typedef struct E_LookupInfo E_LookupInfo; +struct E_LookupInfo +{ + void *user_data; + U64 named_expr_count; + U64 idxed_expr_count; +}; + +typedef struct E_LookupAccess E_LookupAccess; +struct E_LookupAccess +{ + E_IRTreeAndType irtree_and_type; +}; + +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter) +#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name +#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) +typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); +E_LOOKUP_INFO_FUNCTION_DEF(default); + +#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data) +#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name +#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) +typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); +E_LOOKUP_ACCESS_FUNCTION_DEF(default); + +#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) +#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name +#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) +typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); +E_LOOKUP_RANGE_FUNCTION_DEF(default); + +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name +#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) +typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); + +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name +#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) +typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); + +typedef struct E_LookupRule E_LookupRule; +struct E_LookupRule +{ + String8 name; + E_LookupInfoFunctionType *info; + E_LookupAccessFunctionType *access; + E_LookupRangeFunctionType *range; + E_LookupIDFromNumFunctionType *id_from_num; + E_LookupNumFromIDFunctionType *num_from_id; +}; + +typedef struct E_LookupRuleNode E_LookupRuleNode; +struct E_LookupRuleNode +{ + E_LookupRuleNode *next; + E_LookupRule v; +}; + +typedef struct E_LookupRuleSlot E_LookupRuleSlot; +struct E_LookupRuleSlot +{ + E_LookupRuleNode *first; + E_LookupRuleNode *last; +}; + +typedef struct E_LookupRuleMap E_LookupRuleMap; +struct E_LookupRuleMap +{ + E_LookupRuleSlot *slots; + U64 slots_count; +}; + +typedef struct E_LookupRuleTagPair E_LookupRuleTagPair; +struct E_LookupRuleTagPair +{ + E_LookupRule *rule; + E_Expr *tag; +}; + +//////////////////////////////// +//~ rjf: IR Generation Hooks + +#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag) +#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name +#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) +typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); +E_IRGEN_FUNCTION_DEF(default); + +typedef struct E_IRGenRule E_IRGenRule; +struct E_IRGenRule +{ + String8 name; + E_IRGenFunctionType *irgen; +}; + +typedef struct E_IRGenRuleNode E_IRGenRuleNode; +struct E_IRGenRuleNode +{ + E_IRGenRuleNode *next; + E_IRGenRule v; +}; + +typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; +struct E_IRGenRuleSlot +{ + E_IRGenRuleNode *first; + E_IRGenRuleNode *last; +}; + +typedef struct E_IRGenRuleMap E_IRGenRuleMap; +struct E_IRGenRuleMap +{ + U64 slots_count; + 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; + String8 type_string; + String8List type_pattern_parts; + E_ExprChain tag_exprs; +}; + +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; +}; + +typedef struct E_AutoHookParams E_AutoHookParams; +struct E_AutoHookParams +{ + E_TypeKey type_key; + String8 type_pattern; + String8 tag_expr_string; +}; + +//////////////////////////////// +//~ rjf: Contextual & Implicit Evaluation Parameters + +typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); + //////////////////////////////// //~ rjf: Generated Code diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 8d1c1449..cfebe221 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -18,8 +18,6 @@ struct E_Interpretation //////////////////////////////// //~ rjf: Interpretation Context -typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); - typedef struct E_InterpretCtx E_InterpretCtx; struct E_InterpretCtx { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index a11f7e87..b23023bc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -32,191 +32,6 @@ struct E_OpList U64 encoded_size; }; -//////////////////////////////// -//~ rjf: IR Tree Types - -typedef struct E_IRNode E_IRNode; -struct E_IRNode -{ - E_IRNode *first; - E_IRNode *last; - E_IRNode *next; - RDI_EvalOp op; - E_Space space; - String8 string; - E_Value value; -}; - -typedef struct E_IRTreeAndType E_IRTreeAndType; -struct E_IRTreeAndType -{ - E_IRNode *root; - E_TypeKey type_key; - E_Member member; - E_Mode mode; - E_MsgList msgs; -}; - -//////////////////////////////// -//~ rjf: Member/Index Lookup Hooks - -typedef struct E_LookupInfo E_LookupInfo; -struct E_LookupInfo -{ - void *user_data; - U64 named_expr_count; - U64 idxed_expr_count; -}; - -typedef struct E_LookupAccess E_LookupAccess; -struct E_LookupAccess -{ - E_IRTreeAndType irtree_and_type; -}; - -#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter) -#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name -#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) -typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); -E_LOOKUP_INFO_FUNCTION_DEF(default); - -#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data) -#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name -#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) -typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); -E_LOOKUP_ACCESS_FUNCTION_DEF(default); - -#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) -#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name -#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) -typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); -E_LOOKUP_RANGE_FUNCTION_DEF(default); - -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) -typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); - -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) -typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); - -typedef struct E_LookupRule E_LookupRule; -struct E_LookupRule -{ - String8 name; - E_LookupInfoFunctionType *info; - E_LookupAccessFunctionType *access; - E_LookupRangeFunctionType *range; - E_LookupIDFromNumFunctionType *id_from_num; - E_LookupNumFromIDFunctionType *num_from_id; -}; - -typedef struct E_LookupRuleNode E_LookupRuleNode; -struct E_LookupRuleNode -{ - E_LookupRuleNode *next; - E_LookupRule v; -}; - -typedef struct E_LookupRuleSlot E_LookupRuleSlot; -struct E_LookupRuleSlot -{ - E_LookupRuleNode *first; - E_LookupRuleNode *last; -}; - -typedef struct E_LookupRuleMap E_LookupRuleMap; -struct E_LookupRuleMap -{ - E_LookupRuleSlot *slots; - U64 slots_count; -}; - -typedef struct E_LookupRuleTagPair E_LookupRuleTagPair; -struct E_LookupRuleTagPair -{ - E_LookupRule *rule; - E_Expr *tag; -}; - -//////////////////////////////// -//~ rjf: IR Generation Hooks - -#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag) -#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name -#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) -typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); -E_IRGEN_FUNCTION_DEF(default); - -typedef struct E_IRGenRule E_IRGenRule; -struct E_IRGenRule -{ - String8 name; - E_IRGenFunctionType *irgen; -}; - -typedef struct E_IRGenRuleNode E_IRGenRuleNode; -struct E_IRGenRuleNode -{ - E_IRGenRuleNode *next; - E_IRGenRule v; -}; - -typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; -struct E_IRGenRuleSlot -{ - E_IRGenRuleNode *first; - E_IRGenRuleNode *last; -}; - -typedef struct E_IRGenRuleMap E_IRGenRuleMap; -struct E_IRGenRuleMap -{ - U64 slots_count; - 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; - String8 type_string; - String8List type_pattern_parts; - E_ExprChain tag_exprs; -}; - -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; -}; - -typedef struct E_AutoHookParams E_AutoHookParams; -struct E_AutoHookParams -{ - E_TypeKey type_key; - String8 type_pattern; - String8 tag_expr_string; -}; - //////////////////////////////// //~ rjf: Used Tag Map Data Structure diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 39e9c716..cd34d618 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -4,155 +4,6 @@ #ifndef EVAL_PARSE_H #define EVAL_PARSE_H -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/eval.meta.h" - -//////////////////////////////// -//~ rjf: Token Types - -typedef struct E_Token E_Token; -struct E_Token -{ - E_TokenKind kind; - Rng1U64 range; -}; - -typedef struct E_TokenChunkNode E_TokenChunkNode; -struct E_TokenChunkNode -{ - E_TokenChunkNode *next; - E_Token *v; - U64 count; - U64 cap; -}; - -typedef struct E_TokenChunkList E_TokenChunkList; -struct E_TokenChunkList -{ - E_TokenChunkNode *first; - E_TokenChunkNode *last; - U64 node_count; - U64 total_count; -}; - -typedef struct E_TokenArray E_TokenArray; -struct E_TokenArray -{ - E_Token *v; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Expression Tree Types - -typedef struct E_Expr E_Expr; -struct E_Expr -{ - E_Expr *first; - E_Expr *last; - E_Expr *first_tag; - E_Expr *last_tag; - E_Expr *next; - E_Expr *prev; - E_Expr *ref; - void *location; - E_ExprKind kind; - E_Mode mode; - E_Space space; - E_TypeKey type_key; - E_Value value; - String8 string; - String8 qualifier; - String8 bytecode; -}; - -typedef struct E_ExprChain E_ExprChain; -struct E_ExprChain -{ - E_Expr *first; - E_Expr *last; -}; - -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 - -//- rjf: string -> num - -typedef struct E_String2NumMapNode E_String2NumMapNode; -struct E_String2NumMapNode -{ - E_String2NumMapNode *order_next; - E_String2NumMapNode *hash_next; - String8 string; - U64 num; -}; - -typedef struct E_String2NumMapNodeArray E_String2NumMapNodeArray; -struct E_String2NumMapNodeArray -{ - E_String2NumMapNode **v; - U64 count; -}; - -typedef struct E_String2NumMapSlot E_String2NumMapSlot; -struct E_String2NumMapSlot -{ - E_String2NumMapNode *first; - E_String2NumMapNode *last; -}; - -typedef struct E_String2NumMap E_String2NumMap; -struct E_String2NumMap -{ - U64 slots_count; - U64 node_count; - E_String2NumMapSlot *slots; - E_String2NumMapNode *first; - E_String2NumMapNode *last; -}; - -//- rjf: string -> expr - -typedef struct E_String2ExprMapNode E_String2ExprMapNode; -struct E_String2ExprMapNode -{ - E_String2ExprMapNode *hash_next; - String8 string; - E_Expr *expr; - U64 poison_count; -}; - -typedef struct E_String2ExprMapSlot E_String2ExprMapSlot; -struct E_String2ExprMapSlot -{ - E_String2ExprMapNode *first; - E_String2ExprMapNode *last; -}; - -typedef struct E_String2ExprMap E_String2ExprMap; -struct E_String2ExprMap -{ - U64 slots_count; - E_String2ExprMapSlot *slots; -}; - //////////////////////////////// //~ rjf: Parse Results diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index c2822449..0565f4c7 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -225,12 +225,6 @@ e_member_array_from_list(Arena *arena, E_MemberList *list) //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_TypeCtx * -e_selected_type_ctx(void) -{ - return e_type_state->ctx; -} - internal void e_select_type_ctx(E_TypeCtx *ctx) { @@ -605,8 +599,8 @@ e_type_from_key(Arena *arena, E_TypeKey key) { type = push_array(arena, E_Type, 1); type->kind = kind; - type->name = e_kind_basic_string_table[kind]; - type->byte_size = e_kind_basic_byte_size_table[kind]; + type->name = e_type_kind_basic_string_table[kind]; + type->byte_size = e_type_kind_basic_byte_size_table[kind]; } }break; @@ -1159,7 +1153,7 @@ e_type_byte_size_from_key(E_TypeKey key) case E_TypeKeyKind_Basic: { E_TypeKind kind = (E_TypeKind)key.u32[0]; - result = e_kind_basic_byte_size_table[kind]; + result = e_type_kind_basic_byte_size_table[kind]; }break; case E_TypeKeyKind_Ext: { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index e106fd52..1801164b 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -4,142 +4,6 @@ #ifndef EVAL_TYPES_H #define EVAL_TYPES_H -//////////////////////////////// -//~ rjf: Implicit Type Graph Key Types - -typedef enum E_TypeKeyKind -{ - E_TypeKeyKind_Null, - E_TypeKeyKind_Basic, - E_TypeKeyKind_Ext, - E_TypeKeyKind_Cons, - E_TypeKeyKind_Reg, - E_TypeKeyKind_RegAlias, -} -E_TypeKeyKind; - -typedef struct E_TypeKey E_TypeKey; -struct E_TypeKey -{ - E_TypeKeyKind kind; - U32 u32[3]; - // [0] -> E_TypeKind (Basic, Cons, Ext); Arch (Reg, RegAlias) - // [1] -> Type Index In RDI (Ext); Code (Reg, RegAlias); Type Index In Constructed (Cons) - // [2] -> RDI Index (Ext) -}; - -typedef struct E_TypeKeyNode E_TypeKeyNode; -struct E_TypeKeyNode -{ - E_TypeKeyNode *next; - E_TypeKey v; -}; - -typedef struct E_TypeKeyList E_TypeKeyList; -struct E_TypeKeyList -{ - E_TypeKeyNode *first; - E_TypeKeyNode *last; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Full Extracted Type Information Types - -typedef enum E_MemberKind -{ - E_MemberKind_Null, - E_MemberKind_DataField, - E_MemberKind_StaticData, - E_MemberKind_Method, - E_MemberKind_StaticMethod, - E_MemberKind_VirtualMethod, - E_MemberKind_VTablePtr, - E_MemberKind_Base, - E_MemberKind_VirtualBase, - E_MemberKind_NestedType, - E_MemberKind_Padding, - E_MemberKind_Query, - E_MemberKind_COUNT -} -E_MemberKind; - -typedef U32 E_TypeFlags; -enum -{ - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_External = (1<<2), - E_TypeFlag_IsPlainText = (1<<3), - E_TypeFlag_IsCodeText = (1<<4), - E_TypeFlag_IsPathText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), -}; - -typedef struct E_Member E_Member; -struct E_Member -{ - E_MemberKind kind; - E_TypeKey type_key; - String8 name; - U64 off; - E_TypeKeyList inheritance_key_chain; -}; - -typedef struct E_MemberNode E_MemberNode; -struct E_MemberNode -{ - E_MemberNode *next; - E_Member v; -}; - -typedef struct E_MemberList E_MemberList; -struct E_MemberList -{ - E_MemberNode *first; - E_MemberNode *last; - U64 count; -}; - -typedef struct E_MemberArray E_MemberArray; -struct E_MemberArray -{ - E_Member *v; - U64 count; -}; - -typedef struct E_EnumVal E_EnumVal; -struct E_EnumVal -{ - String8 name; - U64 val; -}; - -typedef struct E_EnumValArray E_EnumValArray; -struct E_EnumValArray -{ - E_EnumVal *v; - U64 count; -}; - -typedef struct E_Type E_Type; -struct E_Type -{ - E_TypeKind kind; - E_TypeFlags flags; - String8 name; - U64 byte_size; - U64 count; - U64 depth; - U32 off; - Arch arch; - E_TypeKey direct_type_key; - E_TypeKey owner_type_key; - E_TypeKey *param_type_keys; - E_Member *members; - E_EnumVal *enum_vals; -}; - //////////////////////////////// //~ rjf: String -> Type Key Map Data Structure @@ -339,7 +203,6 @@ internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_TypeCtx *e_selected_type_ctx(void); internal void e_select_type_ctx(E_TypeCtx *ctx); //////////////////////////////// diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 48dd90f6..50b115ba 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,192 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_expr_kind_strings[51] = -{ -str8_lit_comp("Nil"), -str8_lit_comp("Ref"), -str8_lit_comp("ArrayIndex"), -str8_lit_comp("MemberAccess"), -str8_lit_comp("Deref"), -str8_lit_comp("Address"), -str8_lit_comp("Cast"), -str8_lit_comp("Sizeof"), -str8_lit_comp("Typeof"), -str8_lit_comp("ByteSwap"), -str8_lit_comp("Pos"), -str8_lit_comp("Neg"), -str8_lit_comp("LogNot"), -str8_lit_comp("BitNot"), -str8_lit_comp("Mul"), -str8_lit_comp("Div"), -str8_lit_comp("Mod"), -str8_lit_comp("Add"), -str8_lit_comp("Sub"), -str8_lit_comp("LShift"), -str8_lit_comp("RShift"), -str8_lit_comp("Less"), -str8_lit_comp("LsEq"), -str8_lit_comp("Grtr"), -str8_lit_comp("GrEq"), -str8_lit_comp("EqEq"), -str8_lit_comp("NtEq"), -str8_lit_comp("BitAnd"), -str8_lit_comp("BitXor"), -str8_lit_comp("BitOr"), -str8_lit_comp("LogAnd"), -str8_lit_comp("LogOr"), -str8_lit_comp("Ternary"), -str8_lit_comp("Call"), -str8_lit_comp("LeafBytecode"), -str8_lit_comp("LeafMember"), -str8_lit_comp("LeafStringLiteral"), -str8_lit_comp("LeafBool"), -str8_lit_comp("LeafU64"), -str8_lit_comp("LeafF64"), -str8_lit_comp("LeafF32"), -str8_lit_comp("LeafIdentifier"), -str8_lit_comp("LeafOffset"), -str8_lit_comp("LeafValue"), -str8_lit_comp("LeafFilePath"), -str8_lit_comp("TypeIdent"), -str8_lit_comp("Ptr"), -str8_lit_comp("Array"), -str8_lit_comp("Func"), -str8_lit_comp("Define"), -str8_lit_comp("Tag"), -}; - -String8 e_interpretation_code_display_strings[11] = -{ -str8_lit_comp(""), -str8_lit_comp("Cannot divide by zero."), -str8_lit_comp("Invalid operation."), -str8_lit_comp("Invalid operation types."), -str8_lit_comp("Failed memory read."), -str8_lit_comp("Failed register read."), -str8_lit_comp("Invalid frame base address."), -str8_lit_comp("Invalid module base address."), -str8_lit_comp("Invalid thread-local storage base address."), -str8_lit_comp("Insufficient evaluation machine stack space."), -str8_lit_comp("Malformed bytecode."), -}; - -E_OpInfo e_expr_kind_op_info_table[51] = -{ -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp("") }, -{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp("") }, -{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp("") }, -{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp("") }, -{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp("") }, -{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp("") }, -{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp("") }, -{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp("") }, -{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp("") }, -{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp("") }, -{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") }, -{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") }, -{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, -}; - -U8 e_kind_basic_byte_size_table[56] = -{ -0, -0, -0xFF, -4, -1, -2, -4, -1, -2, -4, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -4, -6, -8, -10, -16, -8, -16, -20, -32, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -}; - -String8 e_kind_basic_string_table[56] = +String8 e_type_kind_basic_string_table[56] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -259,5 +74,190 @@ str8_lit_comp("variadic"), str8_lit_comp("set"), }; +U8 e_type_kind_basic_byte_size_table[56] = +{ +0, +0, +0xFF, +4, +1, +2, +4, +1, +2, +4, +1, +2, +4, +8, +16, +32, +64, +1, +2, +4, +8, +16, +32, +64, +1, +2, +4, +4, +6, +8, +10, +16, +8, +16, +20, +32, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +}; + +String8 e_expr_kind_strings[51] = +{ +str8_lit_comp("Nil"), +str8_lit_comp("Ref"), +str8_lit_comp("ArrayIndex"), +str8_lit_comp("MemberAccess"), +str8_lit_comp("Deref"), +str8_lit_comp("Address"), +str8_lit_comp("Cast"), +str8_lit_comp("Sizeof"), +str8_lit_comp("Typeof"), +str8_lit_comp("ByteSwap"), +str8_lit_comp("Pos"), +str8_lit_comp("Neg"), +str8_lit_comp("LogNot"), +str8_lit_comp("BitNot"), +str8_lit_comp("Mul"), +str8_lit_comp("Div"), +str8_lit_comp("Mod"), +str8_lit_comp("Add"), +str8_lit_comp("Sub"), +str8_lit_comp("LShift"), +str8_lit_comp("RShift"), +str8_lit_comp("Less"), +str8_lit_comp("LsEq"), +str8_lit_comp("Grtr"), +str8_lit_comp("GrEq"), +str8_lit_comp("EqEq"), +str8_lit_comp("NtEq"), +str8_lit_comp("BitAnd"), +str8_lit_comp("BitXor"), +str8_lit_comp("BitOr"), +str8_lit_comp("LogAnd"), +str8_lit_comp("LogOr"), +str8_lit_comp("Ternary"), +str8_lit_comp("Call"), +str8_lit_comp("LeafBytecode"), +str8_lit_comp("LeafMember"), +str8_lit_comp("LeafStringLiteral"), +str8_lit_comp("LeafBool"), +str8_lit_comp("LeafU64"), +str8_lit_comp("LeafF64"), +str8_lit_comp("LeafF32"), +str8_lit_comp("LeafIdentifier"), +str8_lit_comp("LeafOffset"), +str8_lit_comp("LeafValue"), +str8_lit_comp("LeafFilePath"), +str8_lit_comp("TypeIdent"), +str8_lit_comp("Ptr"), +str8_lit_comp("Array"), +str8_lit_comp("Func"), +str8_lit_comp("Define"), +str8_lit_comp("Tag"), +}; + +E_OpInfo e_expr_kind_op_info_table[51] = +{ +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp("") }, +{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp("") }, +{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp("") }, +{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp("") }, +{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp("") }, +{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp("") }, +{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp("") }, +{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp("") }, +{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp("") }, +{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp("") }, +{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") }, +{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") }, +{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, +}; + +String8 e_interpretation_code_display_strings[11] = +{ +str8_lit_comp(""), +str8_lit_comp("Cannot divide by zero."), +str8_lit_comp("Invalid operation."), +str8_lit_comp("Invalid operation types."), +str8_lit_comp("Failed memory read."), +str8_lit_comp("Failed register read."), +str8_lit_comp("Invalid frame base address."), +str8_lit_comp("Invalid module base address."), +str8_lit_comp("Invalid thread-local storage base address."), +str8_lit_comp("Insufficient evaluation machine stack space."), +str8_lit_comp("Malformed bytecode."), +}; + C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 2bbf680a..5bb4994c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -163,11 +163,11 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; +extern String8 e_type_kind_basic_string_table[56]; +extern U8 e_type_kind_basic_byte_size_table[56]; extern String8 e_expr_kind_strings[51]; -extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[51]; -extern U8 e_kind_basic_byte_size_table[56]; -extern String8 e_kind_basic_string_table[56]; +extern String8 e_interpretation_code_display_strings[11]; C_LINKAGE_END diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c index a0b8895e..b83d0d1c 100644 --- a/src/scratch/eval_scratch.c +++ b/src/scratch/eval_scratch.c @@ -113,7 +113,7 @@ entry_point(CmdLine *cmdline) indent += 1) { E_Type *type = e_type_from_key(arena, type_key); - raddbg_log("%.*s%S\n", (int)indent*4, indent_spaces, e_kind_basic_string_table[type->kind]); + raddbg_log("%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); } } From bca5169447d57860ab5e067b3b3ad8c8962ed1be Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 31 Mar 2025 16:38:18 -0700 Subject: [PATCH 294/755] eliminate manual console creation & needs-console detection; use user-error mechanism for process creation failure --- project.4coder | 9 ++-- src/demon/win32/demon_core_win32.c | 86 +----------------------------- src/mule/mule_main.cpp | 5 ++ 3 files changed, 10 insertions(+), 90 deletions(-) diff --git a/project.4coder b/project.4coder index 585fdf9b..f08ca89e 100644 --- a/project.4coder +++ b/project.4coder @@ -45,16 +45,15 @@ load_paths = commands = { - //- rjf: fkey command slots (change locally but do not commit) - //- rjf: [raddbg] - // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [eval_scratch] - .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target - .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 60573d5b..b4715f5b 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1229,75 +1229,6 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) cmd = str8_list_join(scratch.arena, &args, &join_params); } - //- rjf: determine if process needs a console - B32 needs_console = 1; - { - String8 exe_path = params->cmd_line.first->string; - OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, exe_path); - - // rjf: find PE offset - U32 pe_offset = 0; - { - U64 dos_magic_off = 0; - U16 dos_magic = 0; - os_file_read_struct(file, dos_magic_off, &dos_magic); - if(dos_magic == PE_DOS_MAGIC) - { - U64 pe_offset_off = OffsetOf(PE_DosHeader, coff_file_offset); - os_file_read_struct(file, pe_offset_off, &pe_offset); - } - } - - // rjf: get COFF header - B32 got_coff_header = 0; - U64 coff_header_off = 0; - COFF_FileHeader coff_header = {0}; - if(pe_offset > 0) - { - U64 pe_magic_off = pe_offset; - U32 pe_magic = 0; - os_file_read_struct(file, pe_magic_off, &pe_magic); - if(pe_magic == PE_MAGIC) - { - coff_header_off = pe_magic_off + sizeof(pe_magic); - if(os_file_read_struct(file, coff_header_off, &coff_header)) - { - got_coff_header = 1; - } - } - } - - // rjf: get subsystem from PE header following COFF header - PE_WindowsSubsystem subsystem = 0; - { - U64 opt_header_off = coff_header_off + sizeof(coff_header); - switch(coff_header.machine) - { - default:{}break; - case COFF_Machine_X64: - { - PE_OptionalHeader32Plus hdr = {0}; - os_file_read_struct(file, opt_header_off, &hdr); - subsystem = hdr.subsystem; - }break; - case COFF_Machine_X86: - { - PE_OptionalHeader32 hdr = {0}; - os_file_read_struct(file, opt_header_off, &hdr); - subsystem = hdr.subsystem; - }break; - } - } - - // rjf: determine if we need a console depending on the subsystem - if(subsystem == PE_WindowsSubsystem_WINDOWS_GUI) - { - needs_console = 0; - } - - os_file_close(file); - } - //- rjf: produce environment strings String8 env = {0}; { @@ -1360,10 +1291,6 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) inherit_handles = 1; } PROCESS_INFORMATION process_info = {0}; - if(needs_console) - { - AllocConsole(); - } if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, creation_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) { // check if we are 32-bit app, and just close it immediately @@ -1385,18 +1312,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) } else { - MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP); - } - if(needs_console) - { - FreeConsole(); - } - - //- rjf: eliminate all handles which have stuck around from the AllocConsole - { - SetStdHandle(STD_INPUT_HANDLE, 0); - SetStdHandle(STD_OUTPUT_HANDLE, 0); - SetStdHandle(STD_ERROR_HANDLE, 0); + log_user_errorf("There was an error starting %S.", params->cmd_line.first->string); } } scratch_end(scratch); diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 0e9073ac..b7514dc4 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2383,6 +2383,11 @@ recursion_stepping_tests(void){ static void debug_string_tests(void) { + for(int i = 0; i < 100; i += 1) + { + printf("here is a number: %i\n", i); + fflush(stdout); + } #if _WIN32 for(int i = 0; i < 100; i += 1) { From 03a87fd4eed08806daa8838508821dd481cbe07d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 31 Mar 2025 22:47:50 -0700 Subject: [PATCH 295/755] cleaned up a bit symbol replacement logic --- src/linker/lnk_error.h | 2 +- src/linker/lnk_symbol_table.c | 261 +++++++++++++++++----------------- src/linker/lnk_symbol_table.h | 2 +- 3 files changed, 131 insertions(+), 134 deletions(-) diff --git a/src/linker/lnk_error.h b/src/linker/lnk_error.h index 2f3cd415..ad6dd4ba 100644 --- a/src/linker/lnk_error.h +++ b/src/linker/lnk_error.h @@ -31,10 +31,10 @@ typedef enum LNK_Error_LoadRes, LNK_Error_IO, LNK_Error_LargeAddrAwareRequired, + LNK_Error_InvalidPath, LNK_Error_StopLast, LNK_Error_First, - LNK_Error_InvalidPath, LNK_Error_AlreadyDefinedSymbol, LNK_Error_AlternateNameConflict, LNK_Error_CvPrecomp, diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index 127a6f1d..79f6a3fe 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -221,133 +221,128 @@ lnk_symbol_hash_trie_chunk_list_push(Arena *arena, LNK_SymbolHashTrieChunkList * } internal B32 -lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src) +lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) { - B32 can_replace = 0; - + Assert(src->type != LNK_Symbol_Undefined); Assert(dst != src); Assert(str8_match(dst->name, src->name, 0)); - Assert(src->type != LNK_Symbol_Undefined); + B32 can_replace = 0; + + // lazy vs lazy if (dst->type == LNK_Symbol_Lazy && src->type == LNK_Symbol_Lazy) { // link.exe picks symbol from lib that is discovered first LNK_Lib *dst_lib = dst->u.lazy.lib; LNK_Lib *src_lib = src->u.lazy.lib; - - //if (dst_lib->input_idx == src_lib->input_idx) { - //Assert(!"TODO: report duplicate symbols in lib"); - //} - can_replace = dst_lib->input_idx > src_lib->input_idx; - } else if (dst->type == LNK_Symbol_Lazy && (LNK_Symbol_IsDefined(src->type) || src->type == LNK_Symbol_Weak)) { + } + // lazy vs weak + else if (dst->type == LNK_Symbol_Lazy && (LNK_Symbol_IsDefined(src->type) || src->type == LNK_Symbol_Weak)) { can_replace = 1; - } else if (dst->type == LNK_Symbol_Weak && LNK_Symbol_IsDefined(src->type)) { - // strong definition found, replace weak symbol + } + // weak vs strong + else if (dst->type == LNK_Symbol_Weak && LNK_Symbol_IsDefined(src->type)) { can_replace = 1; - } else if (dst->type == LNK_Symbol_Weak && src->type == LNK_Symbol_Weak) { + } + // weak vs weak + else if (dst->type == LNK_Symbol_Weak && src->type == LNK_Symbol_Weak) { B32 is_fallback_same = str8_match(dst->u.weak.fallback_symbol->name, src->u.weak.fallback_symbol->name, 0); - if (!is_fallback_same) { + if (is_fallback_same) { + if (src->obj && !dst->obj) { + can_replace = 1; + } else if (src->obj && dst->obj) { + can_replace = src->obj->input_idx < dst->obj->input_idx; + } + } else { lnk_error(LNK_Error_MultiplyDefinedSymbol, "multiply defined weak symbol %S, symbol defined in:", src->name); lnk_supplement_error("%S", dst->obj->path); lnk_supplement_error("%S", src->obj->path); } + } + // defined VA vs defined chunk + else if (LNK_Symbol_IsDefined(dst->type) && dst->u.defined.value_type == LNK_DefinedSymbolValue_VA && + LNK_Symbol_IsDefined(src->type)) { + can_replace = 1; + } + // defined chunk vs defined chunk + else if (LNK_Symbol_IsDefined(dst->type) && dst->u.defined.value_type == LNK_DefinedSymbolValue_Chunk && + LNK_Symbol_IsDefined(src->type) && src->u.defined.value_type == LNK_DefinedSymbolValue_Chunk) { + LNK_DefinedSymbol *dst_defn = &dst->u.defined; + LNK_DefinedSymbol *src_defn = &src->u.defined; - if (src->obj && !dst->obj) { - can_replace = 1; - } else if (src->obj && dst->obj) { - can_replace = src->obj->input_idx < dst->obj->input_idx; + Assert(dst_defn->u.chunk->is_discarded == 0); + Assert(dst_defn->u.chunk->type == LNK_Chunk_Leaf); + Assert(src_defn->u.chunk->type == LNK_Chunk_Leaf); + + COFF_ComdatSelectType dst_select = dst_defn->u.selection; + COFF_ComdatSelectType src_select = src_defn->u.selection; + + // handle objs compiled with /GR- and /GR + if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest) || + (src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any)) { + dst_select = COFF_ComdatSelect_Largest; + src_select = COFF_ComdatSelect_Largest; } - } else if (LNK_Symbol_IsDefined(dst->type) && LNK_Symbol_IsDefined(src->type)) { - const LNK_DefinedSymbol *dst_defn = &dst->u.defined; - const LNK_DefinedSymbol *src_defn = &src->u.defined; - if (dst_defn->value_type == LNK_DefinedSymbolValue_Chunk && - src_defn->value_type == LNK_DefinedSymbolValue_Chunk) { - Assert(dst_defn->u.chunk->is_discarded == 0); - Assert(dst_defn->u.chunk->type == LNK_Chunk_Leaf); - Assert(src_defn->u.chunk->type == LNK_Chunk_Leaf); + if (src_select == dst_select) { + LNK_Chunk *dst_chunk = dst_defn->u.chunk; + LNK_Chunk *src_chunk = src_defn->u.chunk; + U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk); + U64 src_chunk_size = lnk_chunk_get_size(src_chunk); - COFF_ComdatSelectType dst_select = dst_defn->u.selection; - COFF_ComdatSelectType src_select = src_defn->u.selection; - - // handle objs compiled with /GR- and /GR - if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest) || - (src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any)) { - dst_select = COFF_ComdatSelect_Largest; - src_select = COFF_ComdatSelect_Largest; - } - - if (src_select == dst_select) { - switch (src_select) { - default: InvalidPath; - case COFF_ComdatSelect_Null: - case COFF_ComdatSelect_Any: { - LNK_Chunk *dst_chunk = dst_defn->u.chunk; - LNK_Chunk *src_chunk = src_defn->u.chunk; - U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk); - U64 src_chunk_size = lnk_chunk_get_size(src_chunk); - if (src_chunk_size == dst_chunk_size) { - can_replace = src_chunk->input_idx < dst_chunk->input_idx; - } else { - // both COMDATs are valid but to get smaller exe pick smallest - can_replace = src_chunk_size < dst_chunk_size; - } - } break; - case COFF_ComdatSelect_NoDuplicates: { - lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); - } break; - case COFF_ComdatSelect_SameSize: { - LNK_Chunk *dst_chunk = dst_defn->u.chunk; - LNK_Chunk *src_chunk = src_defn->u.chunk; - U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk); - U64 src_chunk_size = lnk_chunk_get_size(src_chunk); - B32 is_same_size = (dst_chunk_size == src_chunk_size); - if (!is_same_size) { - lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); - } - } break; - case COFF_ComdatSelect_ExactMatch: { - B32 is_exact_match = (dst_defn->u.check_sum == src_defn->u.check_sum); - if (!is_exact_match) { - lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); - } - } break; - case COFF_ComdatSelect_Largest: { - LNK_Chunk *dst_chunk = dst_defn->u.chunk; - LNK_Chunk *src_chunk = src_defn->u.chunk; - U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk); - U64 src_chunk_size = lnk_chunk_get_size(src_chunk); - if (dst_chunk_size == src_chunk_size) { - if (dst_defn->u.chunk->u.leaf.str == 0 && src_defn->u.chunk->u.leaf.size > 0) { - // handle communal variable - // - // MSVC CRT relies on this behaviour (e.g. __scrt_ucrt_dll_is_in_use in ucrt_detection.c) - can_replace = 1; - } else { - can_replace = src_chunk->input_idx < dst_chunk->input_idx; - } - } else { - can_replace = dst_chunk_size < src_chunk_size; - } - } break; - case COFF_ComdatSelect_Associative: { - // ignore - } break; + switch (src_select) { + case COFF_ComdatSelect_Null: + case COFF_ComdatSelect_Any: { + if (src_chunk_size == dst_chunk_size) { + can_replace = src_chunk->input_idx < dst_chunk->input_idx; + } else { + // both COMDATs are valid but to get smaller exe pick smallest + can_replace = src_chunk_size < dst_chunk_size; } - } else { - String8 src_select_str = coff_string_from_comdat_select_type(src_defn->u.selection); - String8 dst_select_str = coff_string_from_comdat_select_type(dst_defn->u.selection); - lnk_error_obj(LNK_Warning_UnresolvedComdat, src->obj, - "%S: COMDAT selection conflict detected, current selection %S, leader selection %S from %S", - src->name, src_select_str, dst_select_str, dst->obj->path); + } break; + case COFF_ComdatSelect_NoDuplicates: { + lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); + } break; + case COFF_ComdatSelect_SameSize: { + if (dst_chunk_size != src_chunk_size) { + lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); + } + } break; + case COFF_ComdatSelect_ExactMatch: { + if (dst_defn->u.check_sum != src_defn->u.check_sum) { + lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path); + } + } break; + case COFF_ComdatSelect_Largest: { + if (dst_chunk_size == src_chunk_size) { + if (dst_defn->u.chunk->u.leaf.str == 0 && src_defn->u.chunk->u.leaf.size > 0) { + // handle communal variable + // + // MSVC CRT relies on this behaviour (e.g. __scrt_ucrt_dll_is_in_use in ucrt_detection.c) + can_replace = 1; + } else { + can_replace = src_chunk->input_idx < dst_chunk->input_idx; + } + } else { + can_replace = dst_chunk_size < src_chunk_size; + } + } break; + case COFF_ComdatSelect_Associative: { + // ignore + } break; + default: { + lnk_error_obj(LNK_Error_InvalidPath, src->obj, "unknown COMDAT selection %#x", src->obj, src_select); + } break; } - } else if (dst_defn->value_type == LNK_DefinedSymbolValue_VA && src_defn->value_type == LNK_DefinedSymbolValue_Chunk) { - can_replace = 1; } else { - InvalidPath; + String8 src_select_str = coff_string_from_comdat_select_type(src_defn->u.selection); + String8 dst_select_str = coff_string_from_comdat_select_type(dst_defn->u.selection); + lnk_error_obj(LNK_Warning_UnresolvedComdat, src->obj, + "%S: COMDAT selection conflict detected, current selection %S, leader selection %S from %S", + src->name, src_select_str, dst_select_str, dst->obj->path); } } else { - InvalidPath; + lnk_error(LNK_Error_InvalidPath, "unable to find a suitable replacement logic for symbol combination"); } return can_replace; @@ -388,19 +383,22 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src) } internal void -lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunk_list, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *new_symbol) +lnk_symbol_hash_trie_insert_or_replace(Arena *arena, + LNK_SymbolHashTrieChunkList *chunks, + LNK_SymbolHashTrie **trie, + U64 hash, + LNK_Symbol *symbol) { LNK_SymbolHashTrie **curr_trie_ptr = trie; - for (U64 h = hash; ; h <<= 2) { // load current pointer LNK_SymbolHashTrie *curr_trie = ins_atomic_ptr_eval(curr_trie_ptr); if (curr_trie == 0) { // init node - LNK_SymbolHashTrie *new_trie = lnk_symbol_hash_trie_chunk_list_push(arena, chunk_list, 512); - new_trie->name = &new_symbol->name; - new_trie->symbol = new_symbol; + LNK_SymbolHashTrie *new_trie = lnk_symbol_hash_trie_chunk_list_push(arena, chunks, 512); + new_trie->name = &symbol->name; + new_trie->symbol = symbol; MemoryZeroArray(new_trie->child); // try to insert new node @@ -412,7 +410,7 @@ lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList } // rollback chunk list push - chunk_list->last->count -= 1; + --chunks->last->count; // retry insert with trie node from another thread curr_trie = cmp; @@ -421,39 +419,38 @@ lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList // load current symbol String8 *curr_name = ins_atomic_ptr_eval(&curr_trie->name); - if (curr_name) { - if (str8_match(*curr_name, new_symbol->name, 0)) { - for (LNK_Symbol *src = new_symbol, *dst;;) { - LNK_Symbol *dst = ins_atomic_ptr_eval_assign(&curr_trie->symbol, 0); + if (curr_name && str8_match(*curr_name, symbol->name, 0)) { + for (LNK_Symbol *src = symbol;;) { + // try replacing current symbol with zero, otherwise loop back and retry + LNK_Symbol *dst = ins_atomic_ptr_eval_assign(&curr_trie->symbol, 0); - if (dst) { - if (lnk_can_replace_symbol(dst, src)) { - // HACK: patch dst because relocations might point to it - lnk_on_symbol_replace(dst, src); - - // swap - dst = src; - } else { - // discard source - lnk_on_symbol_replace(src, dst); - } - } - - // try insert back symbol - dst = ins_atomic_ptr_eval_cond_assign(&curr_trie->symbol, src, 0); - - if (dst == 0) { - break; + // apply replacement logic + LNK_Symbol *current_symbol = dst; + if (dst) { + if (lnk_can_replace_symbol(dst, src)) { + // HACK: patch dst because relocations might point to it + lnk_on_symbol_replace(dst, src); + current_symbol = src; + } else { + // discard source + lnk_on_symbol_replace(src, dst); } } - break; + // try replacing symbol, if another thread has already taken the slot, rerun the whole loop + dst = ins_atomic_ptr_eval_cond_assign(&curr_trie->symbol, current_symbol, 0); + + // symbol replaced, exit + if (dst == 0) { + goto exit; + } } } - // descend + // pick child and descend curr_trie_ptr = curr_trie->child + (h >> 62); } + exit:; } internal LNK_SymbolHashTrie * diff --git a/src/linker/lnk_symbol_table.h b/src/linker/lnk_symbol_table.h index 3426a17a..29326d6d 100644 --- a/src/linker/lnk_symbol_table.h +++ b/src/linker/lnk_symbol_table.h @@ -201,7 +201,7 @@ internal LNK_SymbolArray lnk_symbol_array_from_list(Arena *arena, LNK_Symbol //////////////////////////////// -internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunk_list, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *new_symbol); +internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunks, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *symbol); internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name); internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie); From 1c1a8b84ec03a7199635bf3ec077cb30b2e92cce Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 31 Mar 2025 22:49:17 -0700 Subject: [PATCH 296/755] pass over raddump - made inline sites section more compact - consistent indentation for PE/COFF printers --- src/raddump/raddump.c | 692 +++++++++++++++++++------------------ src/raddump/raddump.h | 2 +- src/raddump/raddump_main.c | 12 +- 3 files changed, 359 insertions(+), 347 deletions(-) diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index b89c057a..5eebeb56 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -1474,12 +1474,25 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, } internal void -rdi_print_inline_site(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_InlineSite *inline_site) +rdi_print_inline_site(Arena *arena, + String8List *out, + String8 indent, + RDI_Parsed *rdi, + U64 idx, + RDI_InlineSite *inline_site) { - rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, inline_site->name_string_idx)); - rd_printf("type_idx =%u", inline_site->type_idx); - rd_printf("owner_type_idx=%u", inline_site->owner_type_idx); - rd_printf("line_table_idx=%u", inline_site->line_table_idx); + Temp scratch = scratch_begin(&arena, 1); + String8 inline_site_idx = push_str8f(scratch.arena, "inline_site[%u]", idx); + String8 type_idx = push_str8f(scratch.arena, "type_idx = %u,", inline_site->type_idx); + String8 owner_type_idx = push_str8f(scratch.arena, "owner_type_idx = %u,", inline_site->owner_type_idx); + String8 line_table_idx = push_str8f(scratch.arena, "line_table_idx = %u,", inline_site->line_table_idx); + rd_printf("%-20S = { %-25S %-25S %-25S name = '%-20S' }", + inline_site_idx, + type_idx, + owner_type_idx, + line_table_idx, + str8_from_rdi_string_idx(rdi, inline_site->name_string_idx)); + scratch_end(scratch); } internal void @@ -1712,10 +1725,7 @@ rdi_print(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RD_Op rd_printf("# INLINE SITES"); rd_indent(); for (U64 i = 0; i < inline_site_count; ++i) { - rd_printf("inline_site[%llu]:", i); - rd_indent(); - rdi_print_inline_site(arena, out, indent, rdi, &inline_site_array[i]); - rd_unindent(); + rdi_print_inline_site(arena, out, indent, rdi, i, &inline_site_array[i]); } rd_unindent(); rd_newline(); @@ -4070,26 +4080,26 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV switch (type) { case CV_SymKind_THUNK32_ST: case CV_SymKind_THUNK32: { - CV_SymThunk32 sym = {0}; + CV_SymThunk32 sym = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Parent: %x", sym.parent); - rd_printf("End: %x", sym.end); - rd_printf("Next: %x", sym.next); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); - rd_printf("Length: %u", sym.len); - rd_printf("Ordinal: %S", cv_string_from_thunk_ordinal(sym.ord)); + rd_printf("Name : %S", name); + rd_printf("Parent : %#x", sym.parent); + rd_printf("End : %#x", sym.end); + rd_printf("Next : %#x", sym.next); + rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); + rd_printf("Length : %u", sym.len); + rd_printf("Ordinal: %S", cv_string_from_thunk_ordinal(sym.ord)); } break; case CV_SymKind_FILESTATIC: { CV_SymFileStatic sym = {0}; String8 name = str8_zero(); cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); rd_printf("Flags: %S", cv_string_from_local_flags(scratch.arena, sym.flags)); } break; case CV_SymKind_CALLERS: @@ -4106,7 +4116,7 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV rd_indent(); for (U32 i = 0; i < sym.count; ++i) { U32 invoks = i < invocation_count ? invocations[i] : 0; - rd_printf("%08x (%u)", funcs[i], invoks); + rd_printf("%#08x (%u)", funcs[i], invoks); } rd_unindent(); } break; @@ -4129,20 +4139,20 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += raw_annots.size; - rd_printf("Parent: %#x", sym.parent); - rd_printf("End: %#x", sym.end); + rd_printf("Parent : %#x", sym.parent); + rd_printf("End : %#x", sym.end); rd_printf("Inlinee: %S", cv_string_from_itemid(arena, sym.inlinee)); cv_print_binary_annots(arena, out, indent, arch, raw_annots); } break; case CV_SymKind_INLINESITE2: { - CV_SymInlineSite2 sym = {0}; + CV_SymInlineSite2 sym = {0}; String8 raw_annots = str8_skip(raw_symbol, sizeof(CV_SymInlineSite2)); cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += raw_annots.size; - rd_printf("Parent: %#x", sym.parent_off); - rd_printf("End: %#x", sym.end_off); - rd_printf("Inlinee: %S", cv_string_from_itemid(arena, sym.inlinee)); + rd_printf("Parent : %#x", sym.parent_off); + rd_printf("End : %#x", sym.end_off); + rd_printf("Inlinee : %S", cv_string_from_itemid(arena, sym.inlinee)); rd_printf("Invocations: %u", sym.invocations); cv_print_binary_annots(arena, out, indent, arch, raw_annots); } break; @@ -4153,37 +4163,37 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV case CV_SymKind_GTHREAD32_ST: case CV_SymKind_LTHREAD32: case CV_SymKind_GTHREAD32: { - CV_SymThread32 sym = {0}; + CV_SymThread32 sym = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("TSL Address: %S", cv_string_sec_off(scratch.arena, sym.tls_seg, sym.tls_off)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); } break; case CV_SymKind_OBJNAME: { - CV_SymObjName sym = {0}; + CV_SymObjName sym = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Signature: %#x", sym.sig); } break; case CV_SymKind_BLOCK32_ST: case CV_SymKind_BLOCK32: { - CV_SymBlock32 sym = {0}; + CV_SymBlock32 sym = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Parent: %x", sym.parent); - rd_printf("End: %x", sym.end); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); - rd_printf("Length: %u", sym.len); + rd_printf("Parent : %#x", sym.parent); + rd_printf("End : %#x", sym.end); + rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); + rd_printf("Length : %u", sym.len); + rd_printf("Name : %S", name); if (name.size) { - rd_printf("Name: %S", name); } } break; case CV_SymKind_LABEL32_ST: @@ -4207,13 +4217,13 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV U32 float_pkg = CV_CompileFlags_Extract_FloatPkg(sym.flags); U32 ambient_data = CV_CompileFlags_Extract_AmbientData(sym.flags); U32 mode = CV_CompileFlags_Extract_Mode(sym.flags); - rd_printf("Arch: %S", cv_string_from_arch(sym.machine)); - rd_printf("Language: %S", cv_string_from_language(language)); - rd_printf("FloatPrec: %x", float_prec); - rd_printf("FloatPkg: %x", float_pkg); - rd_printf("Ambient Data: %x", ambient_data); - rd_printf("Mode: %x", mode); - rd_printf("Version String: %S", version_string); + rd_printf("Arch : %#x (%S)", sym.machine, cv_string_from_arch(sym.machine)); + rd_printf("Language : %#x (%S)", language, cv_string_from_language(language)); + rd_printf("FloatPrec : %#x", float_prec); + rd_printf("FloatPkg : %#x", float_pkg); + rd_printf("Ambient Data : %#x", ambient_data); + rd_printf("Mode : %#x", mode); + rd_printf("Version String: %S", version_string); } break; case CV_SymKind_COMPILE2_ST: case CV_SymKind_COMPILE2: { @@ -4224,14 +4234,14 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_cstr(raw_symbol, cursor, &version_string); U32 language = CV_Compile2Flags_Extract_Language(sym.flags); - rd_printf("Machine: %S", cv_string_from_arch(sym.machine)); - rd_printf("Flags: %x", sym.flags); - rd_printf("Language: %S", cv_string_from_language(language)); - rd_printf("Frontend Version: %u.%u", sym.ver_fe_major, sym.ver_fe_minor); - rd_printf("Frontend Build: %u", sym.ver_fe_build); - rd_printf("Backend Version: %u.%u", sym.ver_major, sym.ver_minor); - rd_printf("Backend Build: %u", sym.ver_build); - rd_printf("Version String: %S", version_string); + rd_printf("Machine : %#x (%S)", sym.machine, cv_string_from_arch(sym.machine)); + rd_printf("Flags : %#x", sym.flags); + rd_printf("Language : %#x (%S)", language, cv_string_from_language(language)); + rd_printf("Frontend Version: %u.%u", sym.ver_fe_major, sym.ver_fe_minor); + rd_printf("Frontend Build : %u", sym.ver_fe_build); + rd_printf("Backend Version : %u.%u", sym.ver_major, sym.ver_minor); + rd_printf("Backend Build : %u", sym.ver_build); + rd_printf("Version String : %S", version_string); } break; case CV_SymKind_COMPILE3: { CV_SymCompile3 sym = {0}; @@ -4240,16 +4250,16 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_cstr(raw_symbol, cursor, &version_string); U32 language = CV_Compile3Flags_Extract_Language(sym.flags); - rd_printf("Machine: %S", cv_string_from_arch(sym.machine)); - rd_printf("Flags: %x", sym.flags); - rd_printf("Language: %S", cv_string_from_language(language)); - rd_printf("Frontend Version: %u.%u", sym.ver_fe_major, sym.ver_fe_minor); - rd_printf("Frontend Build: %u", sym.ver_fe_build); - rd_printf("Fontend QFE: %u", sym.ver_feqfe); - rd_printf("Backend Version: %u.%u", sym.ver_major, sym.ver_minor); - rd_printf("Backend Build: %u", sym.ver_build); - rd_printf("Backend QFE: %u", sym.ver_qfe); - rd_printf("Version String: %S", version_string); + rd_printf("Machine : %#x (%S)", sym.machine, cv_string_from_arch(sym.machine)); + rd_printf("Flags : %#x", sym.flags); + rd_printf("Language : %#x (%S)", language, cv_string_from_language(language)); + rd_printf("Frontend Version: %u.%u", sym.ver_fe_major, sym.ver_fe_minor); + rd_printf("Frontend Build : %u", sym.ver_fe_build); + rd_printf("Fontend QFE : %u", sym.ver_feqfe); + rd_printf("Backend Version : %u.%u", sym.ver_major, sym.ver_minor); + rd_printf("Backend Build : %u", sym.ver_build); + rd_printf("Backend QFE : %u", sym.ver_qfe); + rd_printf("Version String : %S", version_string); } break; case CV_SymKind_GPROC32_ST: case CV_SymKind_LPROC32_ST: @@ -4262,16 +4272,16 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV String8 name = str8_zero(); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Parent: %#x", sym.parent); - rd_printf("End: %#x", sym.end); - rd_printf("Next: %#x", sym.next); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); - rd_printf("Length: %u", sym.len); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); - rd_printf("Flags: %S", cv_string_from_proc_flags(scratch.arena, sym.flags)); - rd_printf("Debug Start: %#x", sym.dbg_start); - rd_printf("Debug End: %#x", sym.dbg_end); + rd_printf("Name : %S", name); + rd_printf("Parent : %#x", sym.parent); + rd_printf("End : %#x", sym.end); + rd_printf("Next : %#x", sym.next); + rd_printf("Address : %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); + rd_printf("Length : %u", sym.len); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Flags : %#x (%S)", sym.flags, cv_string_from_proc_flags(scratch.arena, sym.flags)); + rd_printf("Debug Start: %#x", sym.dbg_start); + rd_printf("Debug End : %#x", sym.dbg_end); } break; case CV_SymKind_LDATA32_ST: case CV_SymKind_GDATA32_ST: @@ -4282,8 +4292,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); } break; case CV_SymKind_CONSTANT_ST: @@ -4306,14 +4316,14 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV String8 flags = cv_string_from_frame_proc_flags(scratch.arena, sym.flags); U32 local_ptr = CV_FrameprocFlags_Extract_LocalBasePointer(sym.flags); U32 param_ptr = CV_FrameprocFlags_Extract_ParamBasePointer(sym.flags); - rd_printf("Frame Size: %x", sym.frame_size); - rd_printf("Pad Size: %x", sym.pad_size); - rd_printf("Pad Offset: %x", sym.pad_off); - rd_printf("Save Registers Area: %u", sym.save_reg_size); - rd_printf("Exception Handler: %S", cv_string_sec_off(arena, sym.eh_sec, sym.eh_off)); - rd_printf("Flags: %S", flags); - rd_printf("Local pointer: %S", cv_string_from_reg_id(scratch.arena, arch, cv_map_encoded_base_pointer(arch, local_ptr))); - rd_printf("Param pointer: %S", cv_string_from_reg_id(scratch.arena, arch, cv_map_encoded_base_pointer(arch, param_ptr))); + rd_printf("Frame Size : %#x", sym.frame_size); + rd_printf("Pad Size : %#x", sym.pad_size); + rd_printf("Pad Offset : %#x", sym.pad_off); + rd_printf("Save Registers Area: %u", sym.save_reg_size); + rd_printf("Exception Handler : %S", cv_string_sec_off(arena, sym.eh_sec, sym.eh_off)); + rd_printf("Flags : %S", flags); + rd_printf("Local pointer : %S", cv_string_from_reg_id(scratch.arena, arch, cv_map_encoded_base_pointer(arch, local_ptr))); + rd_printf("Param pointer : %S", cv_string_from_reg_id(scratch.arena, arch, cv_map_encoded_base_pointer(arch, param_ptr))); } break; case CV_SymKind_LOCAL: { CV_SymLocal sym = {0}; @@ -4321,8 +4331,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); rd_printf("Flags: %S", cv_string_from_local_flags(scratch.arena, sym.flags)); } break; case CV_SymKind_DEFRANGE: { @@ -4341,7 +4351,7 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += raw_gaps.size; - rd_printf("Register: %S", cv_string_from_reg_id(scratch.arena, arch, sym.reg)); + rd_printf("Register : %S", cv_string_from_reg_id(scratch.arena, arch, sym.reg)); rd_printf("Attributes: %S", cv_string_from_range_attribs(scratch.arena, sym.attribs)); cv_print_lvar_addr_range(arena, out, indent, sym.range); cv_print_lvar_addr_gap(arena, out, indent, raw_gaps); @@ -4361,9 +4371,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += raw_gaps.size; - rd_printf("Register: %S", cv_string_from_reg_id(scratch.arena, arch, sym.reg)); - rd_printf("Attributes: %S", cv_string_from_range_attribs(scratch.arena, sym.attribs)); - rd_printf("Parent Offset: %#x", sym.field_offset); + rd_printf("Register : %#x (%S)", sym.reg, cv_string_from_reg_id(scratch.arena, arch, sym.reg)); + rd_printf("Attributes : %#x (%S)", sym.attribs, cv_string_from_range_attribs(scratch.arena, sym.attribs)); + rd_printf("Parent Offset: %#x", sym.field_offset); cv_print_lvar_addr_range(arena, out, indent, sym.range); cv_print_lvar_addr_gap(arena, out, indent, raw_gaps); } break; @@ -4378,8 +4388,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += raw_gaps.size; - rd_printf("Flags: %S", cv_string_from_defrange_register_rel_flags(scratch.arena, sym.flags)); - rd_printf("Address: %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.reg_off)); + rd_printf("Flags : %#x (%S)", sym.flags, cv_string_from_defrange_register_rel_flags(scratch.arena, sym.flags)); + rd_printf("Address: %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.reg_off)); cv_print_lvar_addr_gap(arena, out, indent, raw_gaps); } break; case CV_SymKind_END: @@ -4425,16 +4435,16 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); - rd_printf("Pad: %u", sym.pad); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Pad : %u", sym.pad); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); } break; case CV_SymKind_FRAMECOOKIE: { CV_SymFrameCookie sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Address: %S", cv_string_sec_off(arena, sym.reg, sym.off)); - rd_printf("Kind: %S", cv_string_from_frame_cookie_kind(sym.kind)); - rd_printf("Flags: %#x", sym.flags); // TODO: llvm and cvinfo.h don't define these flags... + rd_printf("Address: %S", cv_string_sec_off(arena, sym.reg, sym.off)); + rd_printf("Kind : %#x (%S)", sym.kind, cv_string_from_frame_cookie_kind(sym.kind)); + rd_printf("Flags : %#x", sym.flags); // TODO: llvm and cvinfo.h don't define these flags... } break; case CV_SymKind_HEAPALLOCSITE: { CV_SymHeapAllocSite sym = {0}; @@ -4442,8 +4452,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV String8 addr = cv_string_sec_off(arena, sym.sec, sym.off); String8 itype = cv_string_from_itype(arena, min_itype, sym.itype); - rd_printf("Address: %S", addr); - rd_printf("Type: %S", itype); + rd_printf("Address : %S", addr); + rd_printf("Type : %S", itype); rd_printf("Call instruction length: %x", sym.call_inst_len); } break; case CV_SymKind_ALIGN: { @@ -4476,7 +4486,7 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); rd_printf("Start Symbol: %#x", sym.start_symbol); - rd_printf("Segment: %#x", sym.segment); + rd_printf("Segment : %#x", sym.segment); } break; case CV_SymKind_RETURN: { Assert(!"TODO: test"); @@ -4484,15 +4494,15 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymReturn sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Flags: %S", cv_string_from_generic_flags(scratch.arena, sym.flags)); - rd_printf("Style: %S", cv_string_from_generic_style(sym.style)); + rd_printf("Flags : %#x (%S)", sym.flags, cv_string_from_generic_flags(scratch.arena, sym.flags)); + rd_printf("Style : %#x (%S)", sym.style, cv_string_from_generic_style(sym.style)); if (sym.style == CV_GenericStyle_REG) { U8 count = 0; cursor += str8_deserial_read_struct(raw_symbol, cursor, &count); String8 data = rd_format_hex_array(scratch.arena, raw_symbol.str, raw_symbol.size); rd_printf("Byte Count: %u", count); - rd_printf("Data: %S", data); + rd_printf("Data : %S", data); } } break; case CV_SymKind_ENTRYTHIS: { @@ -4506,13 +4516,13 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cv_print_symbol(arena, out, indent, arch, min_itype, type, raw_subsym); } break; case CV_SymKind_SLINK32: { - Assert(!"ret"); + Assert(!"TODO: test"); CV_SymSLink32 sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); rd_printf("Frame Size: %x", sym.frame_size); - rd_printf("Address: %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.offset)); + rd_printf("Address : %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.offset)); } break; case CV_SymKind_OEM: { Assert(!"TODO: test"); @@ -4525,7 +4535,7 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV // // CV-spec doesn't even mention S_OEM just LF_OEM and cvdump.exe prints out type with guid... rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); - rd_printf("ID: %S", string_from_guid(scratch.arena, sym.id)); + rd_printf("ID : %S", string_from_guid(scratch.arena, sym.id)); } break; case CV_SymKind_VFTABLE32:{ Assert(!"TODO: test"); @@ -4533,8 +4543,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymVPath32 sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Root: %S", cv_string_from_itype(scratch.arena, min_itype, sym.root)); - rd_printf("Path: %S", cv_string_from_itype(scratch.arena, min_itype, sym.path)); + rd_printf("Root : %S", cv_string_from_itype(scratch.arena, min_itype, sym.root)); + rd_printf("Path : %S", cv_string_from_itype(scratch.arena, min_itype, sym.path)); rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.seg, sym.off)); } break; case CV_SymKind_PUB32_ST: @@ -4544,8 +4554,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Flags: %S", cv_string_from_pub32_flags(scratch.arena, sym.flags)); + rd_printf("Name : %S", name); + rd_printf("Flags : %S", cv_string_from_pub32_flags(scratch.arena, sym.flags)); rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); } break; case CV_SymKind_BPREL32_ST: @@ -4557,9 +4567,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Offset: %#x", sym.off); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); } break; case CV_SymKind_REGISTER: { Assert(!"TODO: test"); @@ -4569,9 +4579,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Register: %S", cv_string_from_reg_id(scratch.arena, arch, sym.reg)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); } break; case CV_SymKind_PROCREF_ST: case CV_SymKind_DATAREF_ST: @@ -4587,9 +4597,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("SUC: %#x", sym.suc_name); - rd_printf("IMod: %#x", sym.imod); + rd_printf("Name : %S", name); + rd_printf("SUC : %#x", sym.suc_name); + rd_printf("IMod : %#x", sym.imod); rd_printf("Symbol Stream Offset: %#x", sym.sym_off); } break; case CV_SymKind_SEPCODE: { @@ -4598,12 +4608,12 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymSepcode sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Parent: %#x", sym.parent); - rd_printf("End: %#x", sym.end); - rd_printf("Length: %u", sym.len); - rd_printf("Flags: %S", cv_string_from_sepcode(scratch.arena, sym.flags)); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.sec_off)); - rd_printf("Parent Address: %S", cv_string_sec_off(scratch.arena, sym.sec_parent, sym.sec_parent_off)); + rd_printf("Parent : %#x", sym.parent); + rd_printf("End : %#x", sym.end); + rd_printf("Length : %u", sym.len); + rd_printf("Flags : %#x (%S)", sym.flags, cv_string_from_sepcode(scratch.arena, sym.flags)); + rd_printf("Address : %S", cv_string_sec_off(scratch.arena, sym.sec, sym.sec_off)); + rd_printf("Parent Address: %S", cv_string_sec_off(scratch.arena, sym.sec_parent, sym.sec_parent_off)); } break; case CV_SymKind_PARAMSLOT_ST: case CV_SymKind_LOCALSLOT_ST: @@ -4625,10 +4635,10 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymTrampoline sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Type: %S", cv_string_from_trampoline_kind(sym.kind)); - rd_printf("Thunk Size: %u", sym.thunk_size); - rd_printf("Thunk: %.*s", cv_string_sec_off(scratch.arena, sym.thunk_sec, sym.thunk_sec_off)); - rd_printf("Target: %.*s", cv_string_sec_off(scratch.arena, sym.target_sec, sym.target_sec_off)); + rd_printf("Type : %S", cv_string_from_trampoline_kind(sym.kind)); + rd_printf("Thunk Size: %u", sym.thunk_size); + rd_printf("Thunk : %S", cv_string_sec_off(scratch.arena, sym.thunk_sec, sym.thunk_sec_off)); + rd_printf("Target : %S", cv_string_sec_off(scratch.arena, sym.target_sec, sym.target_sec_off)); } break; case CV_SymKind_POGODATA: { Assert(!"TODO: test"); @@ -4636,9 +4646,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymPogoInfo sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Invocations: %u", sym.invocations); - rd_printf("Dynamic instruction count: %u", sym.dynamic_inst_count); - rd_printf("Static instruction count: %u", sym.static_inst_count); + rd_printf("Invocations : %u", sym.invocations); + rd_printf("Dynamic instruction count : %u", sym.dynamic_inst_count); + rd_printf("Static instruction count : %u", sym.static_inst_count); rd_printf("Post inline static instruction count: %u", sym.post_inline_static_inst_count); } break; case CV_SymKind_MANYREG: { @@ -4647,9 +4657,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymManyreg sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Type: %S", cv_string_from_itype(arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(arena, min_itype, sym.itype)); rd_printf("Reg Count: %u", sym.count); - rd_printf("Regs:"); + rd_printf("Regs :"); rd_indent(); for (U8 i = 0; i < sym.count; ++i) { U8 v = 0; @@ -4665,9 +4675,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymManyreg sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Type: %S", cv_string_from_itype(arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(arena, min_itype, sym.itype)); rd_printf("Reg Count: %u", sym.count); - rd_printf("Regs:"); + rd_printf("Regs :"); rd_indent(); for (U16 i = 0; i < sym.count; ++i) { U16 v = 0; @@ -4684,11 +4694,11 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Index: %u", sym.sec_index); - rd_printf("Align: %u", sym.align); - rd_printf("Virtual Offset: %#x", sym.rva); - rd_printf("Size: %u", sym.size); + rd_printf("Name : %S", name); + rd_printf("Index : %u", sym.sec_index); + rd_printf("Align : %u", sym.align); + rd_printf("Virtual Offset : %#x", sym.rva); + rd_printf("Size : %u", sym.size); rd_printf("Characteristics: %S", coff_string_from_section_flags(scratch.arena, sym.characteristics)); } break; case CV_SymKind_ENVBLOCK: { @@ -4714,10 +4724,10 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Size: %u", sym.size); - rd_printf("Characteristics: %S", coff_string_from_section_flags(scratch.arena, sym.characteristics)); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); + rd_printf("Name : %S", name); + rd_printf("Size : %u", sym.size); + rd_printf("Characteristics: %#x (%S)", sym.characteristics, coff_string_from_section_flags(scratch.arena, sym.characteristics)); + rd_printf("Address : %S", cv_string_sec_off(scratch.arena, sym.sec, sym.off)); } break; case CV_SymKind_EXPORT: { Assert(!"TODO: test"); @@ -4727,9 +4737,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Ordinal: %#x", sym.ordinal); - rd_printf("Flags: %S", cv_string_from_export_flags(scratch.arena, sym.flags)); + rd_printf("Flags : %S", cv_string_from_export_flags(scratch.arena, sym.flags)); } break; case CV_SymKind_ANNOTATION: { Assert(!"TODO: test"); @@ -4737,8 +4747,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymAnnotation sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Address: %S", cv_string_sec_off(scratch.arena, sym.seg, sym.off)); - rd_printf("Count: %u", sym.count); + rd_printf("Address : %S", cv_string_sec_off(scratch.arena, sym.seg, sym.off)); + rd_printf("Count : %u", sym.count); rd_printf("Annotations:"); rd_indent(); for (U16 i = 0; i < sym.count; ++i) { @@ -4757,9 +4767,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Offset: %#x", sym.off); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); cv_print_lvar_attr(arena, out, indent, sym.attr); } break; case CV_SymKind_MANREGISTER: @@ -4771,8 +4781,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); rd_printf("Register: %S", cv_string_from_reg_id(scratch.arena, arch, sym.reg)); cv_print_lvar_attr(arena, out, indent, sym.attr); } break; @@ -4784,9 +4794,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); - rd_printf("Address: %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.off)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Address: %S", cv_string_from_reg_off(scratch.arena, arch, sym.reg, sym.off)); cv_print_lvar_attr(arena, out, indent, sym.attr); } break; case CV_SymKind_MANYREG_ST: @@ -4801,11 +4811,11 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV String8 name = str8_zero(); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, sym.itype)); cv_print_lvar_attr(arena, out, indent, sym.attr); rd_printf("Reg Count: %u", sym.count); - rd_printf("Regs:"); + rd_printf("Regs :"); rd_indent(); for (U8 i = 0; i < sym.count; ++i) { rd_printf("%S", cv_string_from_reg_id(scratch.arena, arch, regs[i])); @@ -4852,8 +4862,8 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &symbol_type); String8 raw_subsym = str8_skip(raw_symbol, cursor); - rd_printf("Kind: %x", sym.kind); - rd_printf("File ID: %x", sym.file_id); + rd_printf("Kind : %x", sym.kind); + rd_printf("File ID : %x", sym.file_id); rd_printf("File Line Number: %u", sym.file_ln); rd_printf("# Discarded Symbol"); cv_print_symbol(arena, out, indent, arch, min_itype, symbol_type, raw_subsym); @@ -4867,7 +4877,7 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_cstr(raw_symbol, cursor, &to); rd_printf("From: %S", from); - rd_printf("To: %S", to); + rd_printf("To : %S", to); } break; case CV_SymKind_FASTLINK: { Assert(!"TODO: test"); @@ -4877,9 +4887,9 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Flags: %x", sym.flags); - rd_printf("Type: %S", cv_string_from_itype(arena, min_itype, sym.itype)); + rd_printf("Name : %S", name); + rd_printf("Flags: %#x", sym.flags); + rd_printf("Type : %S", cv_string_from_itype(arena, min_itype, sym.itype)); } break; case CV_SymKind_ARMSWITCHTABLE: { Assert(!"TODO: test"); @@ -4887,11 +4897,11 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV CV_SymArmSwitchTable sym = {0}; cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); - rd_printf("Base Address: %S", cv_string_sec_off(scratch.arena, sym.sec_base, sym.off_base)); + rd_printf("Base Address : %S", cv_string_sec_off(scratch.arena, sym.sec_base, sym.off_base)); rd_printf("Branch Address: %S", cv_string_sec_off(scratch.arena, sym.sec_branch, sym.off_branch)); - rd_printf("Table Address: %S", cv_string_sec_off(scratch.arena, sym.sec_table, sym.off_table)); - rd_printf("Entry count: %u", sym.entry_count); - rd_printf("Switch Type: %x", sym.kind); + rd_printf("Table Address : %S", cv_string_sec_off(scratch.arena, sym.sec_table, sym.off_table)); + rd_printf("Entry count : %u", sym.entry_count); + rd_printf("Switch Type : %x", sym.kind); } break; case CV_SymKind_REF_MINIPDB: { Assert(!"TODO: test"); @@ -4901,11 +4911,11 @@ cv_print_symbol(Arena *arena, String8List *out, String8 indent, CV_Arch arch, CV cursor += str8_deserial_read_struct(raw_symbol, cursor, &sym); cursor += str8_deserial_read_cstr(raw_symbol, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Flags: %x", sym.flags); - rd_printf("IMod: %04x", sym.imod); + rd_printf("Name : %S", name); + rd_printf("Flags : %x", sym.flags); + rd_printf("IMod : %04x", sym.imod); if (sym.flags & CV_RefMiniPdbFlag_UDT) { - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, (CV_TypeIndex)sym.data)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, (CV_TypeIndex)sym.data)); } else { rd_printf("Coff ISect: %#x", sym.data); } @@ -5022,8 +5032,8 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i CV_LeafBitField lf = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); - rd_printf("Length: %u", lf.len); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Length : %u", lf.len); rd_printf("Position: %u", lf.pos); } break; case CV_LeafKind_CLASS2: @@ -5035,12 +5045,12 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += cv_read_numeric(raw_leaf, cursor, &size); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Fields: %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); - rd_printf("Properties: %S", cv_string_from_type_props(scratch.arena, lf.props)); - rd_printf("Derived: %S", cv_string_from_itype(scratch.arena, min_itype, lf.derived_itype)); - rd_printf("VShape: %S", cv_string_from_itype(scratch.arena, min_itype, lf.vshape_itype)); - rd_printf("Unknown: %x", lf.unknown); + rd_printf("Name : %S", name); + rd_printf("Fields : %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); + rd_printf("Properties : %#x (%S)", lf.props, cv_string_from_type_props(scratch.arena, lf.props)); + rd_printf("Derived : %S", cv_string_from_itype(scratch.arena, min_itype, lf.derived_itype)); + rd_printf("VShape : %S", cv_string_from_itype(scratch.arena, min_itype, lf.vshape_itype)); + rd_printf("Unknown : %#x", lf.unknown); if (lf.props & CV_TypeProp_HasUniqueName) { String8 unique_name = str8_zero(); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &unique_name); @@ -5049,25 +5059,25 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i } break; case CV_LeafKind_PRECOMP_ST: case CV_LeafKind_PRECOMP: { - CV_LeafPreComp lf = {0}; + CV_LeafPreComp lf = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Start Index: %x", lf.start_index); - rd_printf("Count: %u", lf.count); - rd_printf("Signature: %x", lf.sig); + rd_printf("Count : %u", lf.count); + rd_printf("Signature : %x", lf.sig); } break; case CV_LeafKind_TYPESERVER2: { - CV_LeafTypeServer2 lf = {0}; + CV_LeafTypeServer2 lf = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Sig70: %S", string_from_guid(arena, lf.sig70)); - rd_printf("Age: %u", lf.age); + rd_printf("Age : %u", lf.age); } break; case CV_LeafKind_BUILDINFO: { CV_LeafBuildInfo lf = {0}; @@ -5083,13 +5093,13 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i rd_unindent(); } break; case CV_LeafKind_MFUNC_ID: { - CV_LeafMFuncId lf = {0}; + CV_LeafMFuncId lf = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Owner Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.owner_itype)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); } break; case CV_LeafKind_VFUNCTAB: { CV_LeafVFuncTab lf = {0}; @@ -5107,8 +5117,8 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i if (has_vbase) { cursor += str8_deserial_read_struct(raw_leaf, cursor, &vbase); } - rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, ml.attribs)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, ml.itype)); + rd_printf("Attribs : %#x (%S)", ml.attribs, cv_string_from_field_attribs(scratch.arena, ml.attribs)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, ml.itype)); if (has_vbase) { rd_printf("Virtual Base: %x", vbase); } @@ -5126,48 +5136,48 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i } String8 name = {0}; cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Field Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Name : %S", name); + rd_printf("Field Attribs: %#x (%S)", lf.attribs, cv_string_from_field_attribs(scratch.arena, lf.attribs)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); if (has_vbase) { rd_printf("Virtual Base: %#x", vbase); } } break; case CV_LeafKind_METHOD_ST: case CV_LeafKind_METHOD: { - CV_LeafMethod lf = {0}; + CV_LeafMethod lf = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Count: %u", lf.count); + rd_printf("Name : %S", name); + rd_printf("Count : %u", lf.count); rd_printf("Type List: %S", cv_string_from_itype(scratch.arena, min_itype, lf.list_itype)); } break; case CV_LeafKind_VBCLASS: case CV_LeafKind_IVBCLASS: { - CV_LeafVBClass lf = {0}; + CV_LeafVBClass lf = {0}; CV_NumericParsed vbptr_off = {0}; CV_NumericParsed vbtable_off = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += cv_read_numeric(raw_leaf, cursor, &vbptr_off); cursor += cv_read_numeric(raw_leaf, cursor, &vbtable_off); - rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); + rd_printf("Attribs : %#x (%S)", lf.attribs, cv_string_from_field_attribs(scratch.arena, lf.attribs)); rd_printf("Direct Base Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); rd_printf("Virtual Base Ptr: %S", cv_string_from_itype(scratch.arena, min_itype, lf.vbptr_itype)); - rd_printf("vbpoff: %S", cv_string_from_numeric(scratch.arena, vbptr_off)); - rd_printf("vbind: %S", cv_string_from_numeric(scratch.arena, vbtable_off)); + rd_printf("vbpoff : %S", cv_string_from_numeric(scratch.arena, vbptr_off)); + rd_printf("vbind : %S", cv_string_from_numeric(scratch.arena, vbtable_off)); } break; case CV_LeafKind_BCLASS: { - CV_LeafBClass lf = {0}; + CV_LeafBClass lf = {0}; CV_NumericParsed offset = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += cv_read_numeric(raw_leaf, cursor, &offset); - rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); - rd_printf("Offset: %S", cv_string_from_numeric(scratch.arena, offset)); + rd_printf("Attribs: %#x (%S)", lf.attribs, cv_string_from_field_attribs(scratch.arena, lf.attribs)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Offset : %S", cv_string_from_numeric(scratch.arena, offset)); } break; case CV_LeafKind_VTSHAPE: { CV_LeafVTShape lf = {0}; @@ -5186,26 +5196,26 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i } break; case CV_LeafKind_STMEMBER_ST: case CV_LeafKind_STMEMBER: { - CV_LeafStMember lf = {0}; + CV_LeafStMember lf = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Name : %S", name); + rd_printf("Attribs: %#x (%S)", lf.attribs, cv_string_from_field_attribs(scratch.arena, lf.attribs)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); } break; case CV_LeafKind_MFUNCTION: { CV_LeafMFunction lf = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); - rd_printf("Return Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.ret_itype)); - rd_printf("Class Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.class_itype)); - rd_printf("This Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.this_itype)); - rd_printf("Call Kind: %S", cv_string_from_call_kind(lf.call_kind)); - rd_printf("Function Attribs: %S", cv_string_from_function_attribs(scratch.arena, lf.attribs)); - rd_printf("Argument Count: %u", lf.arg_count); - rd_printf("Argument Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.arg_itype)); + rd_printf("Return Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.ret_itype)); + rd_printf("Class Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.class_itype)); + rd_printf("This Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.this_itype)); + rd_printf("Call Kind : %#x (%S)", lf.call_kind, cv_string_from_call_kind(lf.call_kind)); + rd_printf("Function Attribs: %#x (%S)", lf.attribs, cv_string_from_function_attribs(scratch.arena, lf.attribs)); + rd_printf("Argument Count : %u", lf.arg_count); + rd_printf("Argument Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.arg_itype)); } break; #if 0 case CV_LeafKind_SKIP_16t: { @@ -5229,11 +5239,11 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Field Count: %u", lf.count); - rd_printf("Properties: %S", cv_string_from_type_props(scratch.arena, lf.props)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.base_itype)); - rd_printf("Field: %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); + rd_printf("Name : %S", name); + rd_printf("Field Count: %u", lf.count); + rd_printf("Properties : %#x (%S)", lf.props, cv_string_from_type_props(scratch.arena, lf.props)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.base_itype)); + rd_printf("Field : %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); if (lf.props & CV_TypeProp_HasUniqueName) { String8 unique_name = {0}; cursor += str8_deserial_read_cstr(raw_leaf, cursor, &unique_name); @@ -5248,9 +5258,9 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += cv_read_numeric(raw_leaf, cursor, &value); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); - rd_printf("Value: %S", cv_string_from_numeric(scratch.arena, value)); + rd_printf("Value : %S", cv_string_from_numeric(scratch.arena, value)); } break; case CV_LeafKind_NESTTYPE_ST: case CV_LeafKind_NESTTYPE: { @@ -5258,7 +5268,7 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); rd_printf("Index: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); } break; case CV_LeafKind_NOTTRAN: { @@ -5277,7 +5287,7 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &string); - rd_printf("string: %S", string); + rd_printf("string : %S", string); rd_printf("Substrings: %S", cv_string_from_itemid(arena, lf.substr_list_id)); // TODO: print actual strings instead } break; case CV_LeafKind_POINTER: { @@ -5287,7 +5297,7 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i CV_PointerKind kind = CV_PointerAttribs_Extract_Kind(lf.attribs); CV_PointerMode mode = CV_PointerAttribs_Extract_Mode(lf.attribs); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); rd_printf("Attribs: %S", cv_string_from_pointer_attribs(arena, lf.attribs)); rd_indent(); if (mode == CV_PointerMode_PtrMem) { @@ -5297,7 +5307,7 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += str8_deserial_read_struct(raw_leaf, cursor, &pm); rd_printf("Class Type: %S", cv_string_from_itype(scratch.arena, min_itype, itype)); - rd_printf("Format: %S", cv_string_from_member_pointer_kind(pm)); + rd_printf("Format : %S", cv_string_from_member_pointer_kind(pm)); } else { if (kind == CV_PointerKind_BaseSeg) { U16 seg; @@ -5311,25 +5321,25 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); rd_printf("Base Type: %S", cv_string_from_itype(scratch.arena, min_itype, base_itype)); - rd_printf("Name: %S", name); + rd_printf("Name : %S", name); } } rd_unindent(); } break; case CV_LeafKind_UNION_ST: case CV_LeafKind_UNION: { - CV_LeafUnion lf = {0}; + CV_LeafUnion lf = {0}; CV_NumericParsed num = {0}; String8 name = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += cv_read_numeric(raw_leaf, cursor, &num); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Field Count: %u", lf.count); - rd_printf("Properties: %S", cv_string_from_type_props(scratch.arena, lf.props)); - rd_printf("Field: %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); - rd_printf("Size: %S", cv_string_from_numeric(scratch.arena, num)); + rd_printf("Name : %S", name); + rd_printf("Field Count: %u", lf.count); + rd_printf("Properties : %#x (%S)", lf.props, cv_string_from_type_props(scratch.arena, lf.props)); + rd_printf("Field : %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); + rd_printf("Size : %S", cv_string_from_numeric(scratch.arena, num)); if (lf.props & CV_TypeProp_HasUniqueName) { String8 unique_name = {0}; cursor += str8_deserial_read_cstr(raw_leaf, cursor, &unique_name); @@ -5347,13 +5357,13 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += cv_read_numeric(raw_leaf, cursor, &num); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Field Count: %u", lf.count); - rd_printf("Properties: %S", cv_string_from_type_props(scratch.arena, lf.props)); - rd_printf("Field List Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); - rd_printf("Derived Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.derived_itype)); - rd_printf("VShape: %S", cv_string_from_itype(scratch.arena, min_itype, lf.vshape_itype)); - rd_printf("Size: %S", cv_string_from_numeric(scratch.arena, num)); + rd_printf("Name : %S", name); + rd_printf("Field Count : %u", lf.count); + rd_printf("Properties : %#x (%S)", lf.props, cv_string_from_type_props(scratch.arena, lf.props)); + rd_printf("Field List Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.field_itype)); + rd_printf("Derived Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.derived_itype)); + rd_printf("VShape : %S", cv_string_from_itype(scratch.arena, min_itype, lf.vshape_itype)); + rd_printf("Size : %S", cv_string_from_numeric(scratch.arena, num)); if (lf.props & CV_TypeProp_HasUniqueName) { String8 unique_name = {0}; cursor += str8_deserial_read_cstr(raw_leaf, cursor, &unique_name); @@ -5381,11 +5391,11 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i String8 call_kind = cv_string_from_call_kind(lf.call_kind); String8 func_attribs = cv_string_from_function_attribs(scratch.arena, lf.attribs); - rd_printf("Return type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.ret_itype)); - rd_printf("Call Convention: %S", call_kind); - rd_printf("Function Attribs: %S", func_attribs); - rd_printf("Argumnet Count: %u", lf.arg_count); - rd_printf("Argument List Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.arg_itype)); + rd_printf("Return type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.ret_itype)); + rd_printf("Call Convention : %#x (%S)", lf.call_kind, call_kind); + rd_printf("Function Attribs : %#x (%S)", lf.attribs, func_attribs); + rd_printf("Argumnet Count : %u", lf.arg_count); + rd_printf("Argument List Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.arg_itype)); } break; case CV_LeafKind_FUNC_ID: { CV_LeafFuncId lf = {0}; @@ -5393,16 +5403,16 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Scope Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.scope_string_id)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Name : %S", name); + rd_printf("Scope Type: %#x (%S)", lf.scope_string_id, cv_string_from_itype(scratch.arena, min_itype, lf.scope_string_id)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); } break; case CV_LeafKind_MODIFIER: { CV_LeafModifier lf = {0}; cursor += str8_deserial_read_struct(raw_leaf, cursor, &lf); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); - rd_printf("Flags: %S", cv_string_from_modifier_flags(scratch.arena, lf.flags)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Flags: %#x (%S)", lf.flags, cv_string_from_modifier_flags(scratch.arena, lf.flags)); } break; case CV_LeafKind_ARRAY_ST: case CV_LeafKind_ARRAY: { @@ -5413,7 +5423,7 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i rd_printf("Entry type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.entry_itype)); rd_printf("Index type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.index_itype)); - rd_printf("Length: %S", cv_string_from_numeric(scratch.arena, num)); + rd_printf("Length : %S", cv_string_from_numeric(scratch.arena, num)); } break; case CV_LeafKind_FIELDLIST: { for (U64 idx = 0; cursor < raw_leaf.size;) { @@ -5437,10 +5447,10 @@ cv_print_leaf(Arena *arena, String8List *out, String8 indent, CV_TypeIndex min_i cursor += cv_read_numeric(raw_leaf, cursor, &num); cursor += str8_deserial_read_cstr(raw_leaf, cursor, &name); - rd_printf("Name: %S", name); - rd_printf("Attribs: %S", cv_string_from_field_attribs(scratch.arena, lf.attribs)); - rd_printf("Type: %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); - rd_printf("Offset: %S", cv_string_from_numeric(scratch.arena, num)); + rd_printf("Name : %S", name); + rd_printf("Attribs: %#x (%S)", lf.attribs, cv_string_from_field_attribs(scratch.arena, lf.attribs)); + rd_printf("Type : %S", cv_string_from_itype(scratch.arena, min_itype, lf.itype)); + rd_printf("Offset : %S", cv_string_from_numeric(scratch.arena, num)); } break; case CV_LeafKind_LABEL: { CV_LeafLabel lf = {0}; @@ -5936,12 +5946,12 @@ coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, Temp scratch = scratch_begin(&arena, 1); String8 time_stamp = coff_string_from_time_stamp(scratch.arena, header.time_stamp); - rd_printf("Name: %S" , header.name ); - rd_printf("Time Stamp: %S" , time_stamp ); - rd_printf("User ID: %u" , header.user_id ); - rd_printf("Group ID: %u" , header.group_id); - rd_printf("Mode: %S" , header.mode ); - rd_printf("Data: [%#llx-%#llx)", header.data_range.min, header.data_range.max); + rd_printf("Name : %S" , header.name ); + rd_printf("Time Stamp: (%#x) %S" , header.time_stamp, time_stamp ); + rd_printf("User ID : %u" , header.user_id ); + rd_printf("Group ID : %u" , header.group_id); + rd_printf("Mode : %S" , header.mode ); + rd_printf("Data : [%#llx-%#llx)", header.data_range.min, header.data_range.max); scratch_end(scratch); } @@ -6388,11 +6398,11 @@ coff_print_big_obj_header(Arena *arena, String8List *out, String8 indent, COFF_B rd_printf("# Big Obj"); rd_indent(); - rd_printf("Time Stamp: %S", time_stamp ); - rd_printf("Machine: %S", machine ); + rd_printf("Time Stamp : %#x (%S)", header->time_stamp, time_stamp); + rd_printf("Machine : %#x (%S)", header->machine, machine ); rd_printf("Section Count: %u", header->section_count ); - rd_printf("Symbol Table: %#x", header->symbol_table_foff); - rd_printf("Symbol Count: %u", header->symbol_count ); + rd_printf("Symbol Table : %#x", header->symbol_table_foff); + rd_printf("Symbol Count : %u", header->symbol_count ); rd_unindent(); scratch_end(scratch); @@ -6409,13 +6419,13 @@ coff_print_file_header(Arena *arena, String8List *out, String8 indent, COFF_File rd_printf("# COFF File Header"); rd_indent(); - rd_printf("Time Stamp: %S", time_stamp ); - rd_printf("Machine: %S", machine ); - rd_printf("Section Count: %u", header->section_count ); - rd_printf("Symbol Table: %#x", header->symbol_table_foff ); - rd_printf("Symbol Count: %u", header->symbol_count ); - rd_printf("Optional Header Size: %m", header->optional_header_size); - rd_printf("Flags: %S", flags ); + rd_printf("Time Stamp : %#x (%S)", header->time_stamp, time_stamp ); + rd_printf("Machine : %#x %S", header->machine, machine ); + rd_printf("Section Count : %u", header->section_count ); + rd_printf("Symbol Table : %#x", header->symbol_table_foff ); + rd_printf("Symbol Count : %u", header->symbol_count ); + rd_printf("Optional Header Size: %#x (%m)", header->optional_header_size, header->optional_header_size); + rd_printf("Flags : %#x (%S)", header->flags, flags ); rd_unindent(); scratch_end(scratch); @@ -6431,15 +6441,15 @@ coff_print_import(Arena *arena, String8List *out, String8 indent, COFF_ParsedArc rd_printf("# Import"); rd_indent(); - rd_printf("Version: %u", header->version ); - rd_printf("Machine: %S", machine ); - rd_printf("Time Stamp: %S", time_stamp ); - rd_printf("Data Size: %m", header->data_size ); - rd_printf("Hint: %u", header->hint_or_ordinal); - rd_printf("Type: %u", header->type ); - rd_printf("Import By: %u", header->import_by ); - rd_printf("Function: %S", header->func_name ); - rd_printf("DLL: %S", header->dll_name ); + rd_printf("Version : %u", header->version ); + rd_printf("Machine : %S", machine ); + rd_printf("Time Stamp: %#x (%S)", header->time_stamp, time_stamp ); + rd_printf("Data Size : %#x (%m)", header->data_size, header->data_size); + rd_printf("Hint : %u", header->hint_or_ordinal); + rd_printf("Type : %u", header->type ); + rd_printf("Import By : %u", header->import_by ); + rd_printf("Function : %S", header->func_name ); + rd_printf("DLL : %S", header->dll_name ); rd_unindent(); scratch_end(scratch); @@ -6592,8 +6602,8 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a rd_printf("# First Header"); rd_indent(); - rd_printf("Symbol Count: %u", first_member.symbol_count); - rd_printf("String Table Size: %M", first_member.string_table.size); + rd_printf("Symbol Count : %u", first_member.symbol_count); + rd_printf("String Table Size: %#llx (%M)", first_member.string_table.size, first_member.string_table.size); rd_printf("Members:"); rd_indent(); @@ -6622,9 +6632,9 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a rd_printf("# Second Header"); rd_indent(); - rd_printf("Member Count: %u", second_member.member_count); - rd_printf("Symbol Count: %u", second_member.symbol_count); - rd_printf("String Table Size: %M", second_member.string_table.size); + rd_printf("Member Count : %u", second_member.member_count); + rd_printf("Symbol Count : %u", second_member.symbol_count); + rd_printf("String Table Size: %#llx (%M)", second_member.string_table.size, second_member.string_table.size); String8List string_table = str8_split_by_string_chars(scratch.arena, second_member.string_table, str8_lit("\0"), 0); @@ -6744,11 +6754,11 @@ mscrt_print_eh_handler_type32(Arena *arena, String8List *out, String8 indent, RD Temp scratch = scratch_begin(&arena, 1); String8 catch_line = rd_format_line_from_voff(scratch.arena, rdi, handler->catch_handler_voff, PathStyle_WindowsAbsolute); String8 adjectives_str = mscrt_string_from_eh_adjectives(scratch.arena, handler->adjectives); - rd_printf("Adjectives: %S", adjectives_str, handler->adjectives); - rd_printf("Descriptor: %#x", handler->descriptor_voff); - rd_printf("Catch Object Frame Offset: %#x", handler->catch_obj_frame_offset); - rd_printf("Catch Handler: %#x%s%S", handler->catch_handler_voff, catch_line.size ? " " : "", catch_line); - rd_printf("Delta to FP Handler: %#x", handler->fp_distance); + rd_printf("Adjectives : %#x (%S)", handler->adjectives, adjectives_str); + rd_printf("Descriptor : %#x", handler->descriptor_voff); + rd_printf("Catch Object Frame Offset: %#x", handler->catch_obj_frame_offset); + rd_printf("Catch Handler : %#x%s%S", handler->catch_handler_voff, catch_line.size ? " " : "", catch_line); + rd_printf("Delta to FP Handler : %#x", handler->fp_distance); scratch_end(scratch); } @@ -6783,32 +6793,32 @@ pe_print_optional_header32(Arena *arena, String8List *out, String8 indent, PE_Op rd_printf("# PE Optional Header 32"); rd_indent(); - rd_printf("Magic: %#x", opt_header->magic); - rd_printf("Linker version: %u.%u", opt_header->major_linker_version, opt_header->minor_linker_version); - rd_printf("Size of code: %m", opt_header->sizeof_code); - rd_printf("Size of inited data: %m", opt_header->sizeof_inited_data); - rd_printf("Size of uninited data: %m", opt_header->sizeof_uninited_data); - rd_printf("Entry point: %#x", opt_header->entry_point_va); - rd_printf("Code base: %#x", opt_header->code_base); - rd_printf("Data base: %#x", opt_header->data_base); - rd_printf("Image base: %#x", opt_header->image_base); - rd_printf("Section align: %#x", opt_header->section_alignment); - rd_printf("File align: %#x", opt_header->file_alignment); - rd_printf("OS version: %u.%u", opt_header->major_os_ver, opt_header->minor_os_ver); - rd_printf("Image Version: %u.%u", opt_header->major_img_ver, opt_header->minor_img_ver); - rd_printf("Subsystem version: %u.%u", opt_header->major_subsystem_ver, opt_header->minor_subsystem_ver); - rd_printf("Win32 version: %u", opt_header->win32_version_value); - rd_printf("Size of image: %m", opt_header->sizeof_image); - rd_printf("Size of headers: %m", opt_header->sizeof_headers); - rd_printf("Checksum: %#x", opt_header->check_sum); - rd_printf("Subsystem: %S", subsystem); - rd_printf("DLL Characteristics: %S", dll_chars); - rd_printf("Stack reserve: %m", opt_header->sizeof_stack_reserve); - rd_printf("Stack commit: %m", opt_header->sizeof_stack_commit); - rd_printf("Heap reserve: %m", opt_header->sizeof_heap_reserve); - rd_printf("Heap commit: %m", opt_header->sizeof_heap_commit); - rd_printf("Loader flags: %#x", opt_header->loader_flags); - rd_printf("RVA and offset count: %u", opt_header->data_dir_count); + rd_printf("Magic : %#x", opt_header->magic); + rd_printf("Linker version : %u.%u", opt_header->major_linker_version, opt_header->minor_linker_version); + rd_printf("Size of code : %#-8x (%m)", opt_header->sizeof_code, opt_header->sizeof_code); + rd_printf("Size of inited data : %#-8x (%m)", opt_header->sizeof_inited_data, opt_header->sizeof_inited_data); + rd_printf("Size of uninited data: %#-8x (%m)", opt_header->sizeof_uninited_data, opt_header->sizeof_uninited_data); + rd_printf("Entry point : %#x", opt_header->entry_point_va); + rd_printf("Code base : %#x", opt_header->code_base); + rd_printf("Data base : %#x", opt_header->data_base); + rd_printf("Image base : %#x", opt_header->image_base); + rd_printf("Section align : %#x", opt_header->section_alignment); + rd_printf("File align : %#x", opt_header->file_alignment); + rd_printf("OS version : %u.%u", opt_header->major_os_ver, opt_header->minor_os_ver); + rd_printf("Image Version : %u.%u", opt_header->major_img_ver, opt_header->minor_img_ver); + rd_printf("Subsystem version : %u.%u", opt_header->major_subsystem_ver, opt_header->minor_subsystem_ver); + rd_printf("Win32 version : %u", opt_header->win32_version_value); + rd_printf("Size of image : %#x (%m)", opt_header->sizeof_image, opt_header->sizeof_image); + rd_printf("Size of headers : %#x (%m)", opt_header->sizeof_headers, opt_header->sizeof_headers); + rd_printf("Checksum : %#x", opt_header->check_sum); + rd_printf("Subsystem : %#x (%S)", opt_header->subsystem, subsystem); + rd_printf("DLL Characteristics : %#x (%S)", opt_header->dll_characteristics, dll_chars); + rd_printf("Stack reserve : %#-8x (%m)", opt_header->sizeof_stack_reserve, opt_header->sizeof_stack_reserve); + rd_printf("Stack commit : %#-8x (%m)", opt_header->sizeof_stack_commit, opt_header->sizeof_stack_commit); + rd_printf("Heap reserve : %#-8x (%m)", opt_header->sizeof_heap_reserve, opt_header->sizeof_heap_reserve); + rd_printf("Heap commit : %#-8x (%m)", opt_header->sizeof_heap_commit, opt_header->sizeof_heap_commit); + rd_printf("Loader flags : %#x", opt_header->loader_flags); + rd_printf("RVA and offset count : %u", opt_header->data_dir_count); rd_newline(); pe_print_data_directory_ranges(arena, out, indent, opt_header->data_dir_count, dirs); @@ -6827,31 +6837,31 @@ pe_print_optional_header32plus(Arena *arena, String8List *out, String8 indent, P rd_printf("# PE Optional Header 32+"); rd_indent(); - rd_printf("Magic: %#x", opt_header->magic); - rd_printf("Linker version: %u.%u", opt_header->major_linker_version, opt_header->minor_linker_version); - rd_printf("Size of code: %m", opt_header->sizeof_code); - rd_printf("Size of inited data: %m", opt_header->sizeof_inited_data); - rd_printf("Size of uninited data: %m", opt_header->sizeof_uninited_data); - rd_printf("Entry point: %#x", opt_header->entry_point_va); - rd_printf("Code base: %#x", opt_header->code_base); - rd_printf("Image base: %#llx", opt_header->image_base); - rd_printf("Section align: %#x", opt_header->section_alignment); - rd_printf("File align: %#x", opt_header->file_alignment); - rd_printf("OS version: %u.%u", opt_header->major_os_ver, opt_header->minor_os_ver); - rd_printf("Image Version: %u.%u", opt_header->major_img_ver, opt_header->minor_img_ver); - rd_printf("Subsystem version: %u.%u", opt_header->major_subsystem_ver, opt_header->minor_subsystem_ver); - rd_printf("Win32 version: %u", opt_header->win32_version_value); - rd_printf("Size of image: %m", opt_header->sizeof_image); - rd_printf("Size of headers: %m", opt_header->sizeof_headers); - rd_printf("Checksum: %#x", opt_header->check_sum); - rd_printf("Subsystem: %S", subsystem); - rd_printf("DLL Characteristics: %S", dll_chars); - rd_printf("Stack reserve: %M", opt_header->sizeof_stack_reserve); - rd_printf("Stack commit: %M", opt_header->sizeof_stack_commit); - rd_printf("Heap reserve: %M", opt_header->sizeof_heap_reserve); - rd_printf("Heap commit: %M", opt_header->sizeof_heap_commit); - rd_printf("Loader flags: %#x", opt_header->loader_flags); - rd_printf("RVA and offset count: %u", opt_header->data_dir_count); + rd_printf("Magic : %#x", opt_header->magic); + rd_printf("Linker version : %u.%u", opt_header->major_linker_version, opt_header->minor_linker_version); + rd_printf("Size of code : %#-8x (%m)", opt_header->sizeof_code, opt_header->sizeof_code); + rd_printf("Size of inited data : %#-8x (%m)", opt_header->sizeof_inited_data, opt_header->sizeof_inited_data); + rd_printf("Size of uninited data: %#-8x (%m)", opt_header->sizeof_uninited_data, opt_header->sizeof_uninited_data); + rd_printf("Entry point : %#x", opt_header->entry_point_va); + rd_printf("Code base : %#x", opt_header->code_base); + rd_printf("Image base : %#llx", opt_header->image_base); + rd_printf("Section align : %#x", opt_header->section_alignment); + rd_printf("File align : %#x", opt_header->file_alignment); + rd_printf("OS version : %u.%u", opt_header->major_os_ver, opt_header->minor_os_ver); + rd_printf("Image Version : %u.%u", opt_header->major_img_ver, opt_header->minor_img_ver); + rd_printf("Subsystem version : %u.%u", opt_header->major_subsystem_ver, opt_header->minor_subsystem_ver); + rd_printf("Win32 version : %u", opt_header->win32_version_value); + rd_printf("Size of image : %#x (%m)", opt_header->sizeof_image, opt_header->sizeof_image); + rd_printf("Size of headers : %#x (%m)", opt_header->sizeof_headers, opt_header->sizeof_headers); + rd_printf("Checksum : %#x", opt_header->check_sum); + rd_printf("Subsystem : %#llx (%S)", opt_header->subsystem, subsystem); + rd_printf("DLL Characteristics : %#llx (%S)", opt_header->dll_characteristics, dll_chars); + rd_printf("Stack reserve : %#-8llx (%M)", opt_header->sizeof_stack_reserve, opt_header->sizeof_stack_reserve); + rd_printf("Stack commit : %#-8llx (%M)", opt_header->sizeof_stack_commit, opt_header->sizeof_stack_commit); + rd_printf("Heap reserve : %#-8llx (%M)", opt_header->sizeof_heap_reserve, opt_header->sizeof_heap_reserve); + rd_printf("Heap commit : %#-8llx (%M)", opt_header->sizeof_heap_commit, opt_header->sizeof_heap_commit); + rd_printf("Loader flags : %#x", opt_header->loader_flags); + rd_printf("RVA and offset count : %u", opt_header->data_dir_count); rd_newline(); pe_print_data_directory_ranges(arena, out, indent, opt_header->data_dir_count, dirs); diff --git a/src/raddump/raddump.h b/src/raddump/raddump.h index 910c5ccc..36d0017b 100644 --- a/src/raddump/raddump.h +++ b/src/raddump/raddump.h @@ -213,7 +213,7 @@ internal void rdi_print_global_variable(Arena *arena, String8List *out, String8 internal void rdi_print_thread_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_ThreadVariable *tvar); internal void rdi_print_procedure (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc, RDI_Arch arch); internal void rdi_print_scope (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Scope *scope, RDI_Arch arch); -internal void rdi_print_inline_site (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_InlineSite *inline_site); +internal void rdi_print_inline_site (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, U64 idx, RDI_InlineSite *inline_site); internal void rdi_print_vmap_entry (Arena *arena, String8List *out, String8 indent, RDI_VMapEntry *v); // DWARF diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index 4f62d683..d6fee2b4 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -274,17 +274,19 @@ entry_point(CmdLine *cmdline) RDI_Parsed rdi = {0}; RDI_ParseStatus parse_status = rdi_parse(raw_data.str, raw_data.size, &rdi); switch (parse_status) { - case RDI_ParseStatus_Good: rdi_print(arena, out, indent, &rdi, opts); break; + case RDI_ParseStatus_Good: { + RD_Option rdi_print_opts = opts; + if ((rdi_print_opts & RD_Option_RdiAll) == 0) { + rdi_print_opts |= RD_Option_RdiAll; + } + rdi_print(arena, out, indent, &rdi, rdi_print_opts); + } break; case RDI_ParseStatus_HeaderDoesNotMatch: rd_errorf("RDI Parse: header does not match"); break; case RDI_ParseStatus_UnsupportedVersionNumber: rd_errorf("RDI Parse: unsupported version"); break; case RDI_ParseStatus_InvalidDataSecionLayout: rd_errorf("RDI Parse: invalid data section layout"); break; case RDI_ParseStatus_MissingRequiredSection: rd_errorf("RDI Parse: missing required section"); break; default: rd_errorf("RDI Parse: unknown parse status %u", parse_status); break; } - if ((opts & RD_Option_RdiAll) == 0) { - opts = RD_Option_RdiAll; - } - rdi_print(arena, out, indent, &rdi, opts); } else if (coff_is_regular_archive(raw_data) || coff_is_thin_archive(raw_data)) { coff_print_archive(arena, out, indent, raw_data, opts); } else if (coff_is_big_obj(raw_data)) { From 1c518bfa075c3ca681c147c4862fd6be5112d688 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 31 Mar 2025 22:53:10 -0700 Subject: [PATCH 297/755] prefix COFF machine enums with "Type" --- src/codeview/codeview.c | 48 ++++++++++++------------ src/coff/coff.c | 22 +++++------ src/coff/coff.h | 55 ++++++++++++++------------- src/coff/coff_enum.c | 60 +++++++++++++++--------------- src/coff/coff_parse.c | 30 +++++++-------- src/ctrl/ctrl_core.c | 4 +- src/demon/win32/demon_core_win32.c | 4 +- src/linker/lnk.c | 34 ++++++++--------- src/linker/lnk_config.c | 48 ++++++++++++------------ src/linker/lnk_import_table.c | 10 ++--- src/linker/lnk_lib.c | 2 +- src/linker/lnk_reloc.c | 6 +-- src/linker/lnk_section_table.c | 4 +- src/linker/rdi/rdi_coff.c | 48 ++++++++++++------------ src/pe/pe.c | 14 +++---- src/radcon/radcon_coff.c | 48 ++++++++++++------------ src/raddump/raddump.c | 24 ++++++------ 17 files changed, 230 insertions(+), 231 deletions(-) diff --git a/src/codeview/codeview.c b/src/codeview/codeview.c index 4836c249..fbae1c89 100644 --- a/src/codeview/codeview.c +++ b/src/codeview/codeview.c @@ -14,30 +14,30 @@ cv_arch_from_coff_machine(COFF_MachineType machine) CV_Arch arch = 0; switch(machine) { - case COFF_Machine_X64: arch = CV_Arch_X64; break; - case COFF_Machine_X86: arch = CV_Arch_8086; break; - case COFF_Machine_Am33: arch = CV_Arch_AM33; break; - case COFF_Machine_Arm: NotImplemented; break; - case COFF_Machine_Arm64: arch = CV_Arch_ARM64; break; - case COFF_Machine_ArmNt: arch = CV_Arch_ARMNT; break; - case COFF_Machine_Ebc: arch = CV_Arch_EBC; break; - case COFF_Machine_Ia64: arch = CV_Arch_IA64; break; - case COFF_Machine_M32R: arch = CV_Arch_M32R; break; - case COFF_Machine_Mips16: arch = CV_Arch_MIPS16; break; - case COFF_Machine_MipsFpu: NotImplemented; break; - case COFF_Machine_MipsFpu16: NotImplemented; break; - case COFF_Machine_PowerPc: NotImplemented; break; - case COFF_Machine_PowerPcFp: arch = CV_Arch_PPCFP; break; - case COFF_Machine_R4000: NotImplemented; break; - case COFF_Machine_RiscV32: NotImplemented; break; - case COFF_Machine_RiscV64: NotImplemented; break; - case COFF_Machine_RiscV128: NotImplemented; break; - case COFF_Machine_Sh3: arch = CV_Arch_SH3; break; - case COFF_Machine_Sh3Dsp: arch = CV_Arch_SH3DSP; break; - case COFF_Machine_Sh4: arch = CV_Arch_SH4; break; - case COFF_Machine_Sh5: NotImplemented; break; - case COFF_Machine_Thumb: arch = CV_Arch_THUMB; break; - case COFF_Machine_WceMipsV2: NotImplemented; break; + case COFF_MachineType_X64: arch = CV_Arch_X64; break; + case COFF_MachineType_X86: arch = CV_Arch_8086; break; + case COFF_MachineType_Am33: arch = CV_Arch_AM33; break; + case COFF_MachineType_Arm: NotImplemented; break; + case COFF_MachineType_Arm64: arch = CV_Arch_ARM64; break; + case COFF_MachineType_ArmNt: arch = CV_Arch_ARMNT; break; + case COFF_MachineType_Ebc: arch = CV_Arch_EBC; break; + case COFF_MachineType_Ia64: arch = CV_Arch_IA64; break; + case COFF_MachineType_M32R: arch = CV_Arch_M32R; break; + case COFF_MachineType_Mips16: arch = CV_Arch_MIPS16; break; + case COFF_MachineType_MipsFpu: NotImplemented; break; + case COFF_MachineType_MipsFpu16: NotImplemented; break; + case COFF_MachineType_PowerPc: NotImplemented; break; + case COFF_MachineType_PowerPcFp: arch = CV_Arch_PPCFP; break; + case COFF_MachineType_R4000: NotImplemented; break; + case COFF_MachineType_RiscV32: NotImplemented; break; + case COFF_MachineType_RiscV64: NotImplemented; break; + case COFF_MachineType_RiscV128: NotImplemented; break; + case COFF_MachineType_Sh3: arch = CV_Arch_SH3; break; + case COFF_MachineType_Sh3Dsp: arch = CV_Arch_SH3DSP; break; + case COFF_MachineType_Sh4: arch = CV_Arch_SH4; break; + case COFF_MachineType_Sh5: NotImplemented; break; + case COFF_MachineType_Thumb: arch = CV_Arch_THUMB; break; + case COFF_MachineType_WceMipsV2: NotImplemented; break; } return arch; } diff --git a/src/coff/coff.c b/src/coff/coff.c index 0f2ba099..cc3cdd4e 100644 --- a/src/coff/coff.c +++ b/src/coff/coff.c @@ -174,8 +174,8 @@ internal U64 coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x) { switch (machine) { - case COFF_Machine_X64: return coff_apply_size_from_reloc_x64(x); - case COFF_Machine_X86: return coff_apply_size_from_reloc_x86(x); + case COFF_MachineType_X64: return coff_apply_size_from_reloc_x64(x); + case COFF_MachineType_X86: return coff_apply_size_from_reloc_x86(x); default: NotImplemented; } return 0; @@ -221,7 +221,7 @@ coff_make_import_header_by_name(Arena *arena, flags |= COFF_ImportBy_Name << COFF_ImportHeader_ImportByShift; COFF_ImportHeader header = {0}; - header.sig1 = COFF_Machine_Unknown; + header.sig1 = COFF_MachineType_Unknown; header.sig2 = max_U16; header.version = 0; header.machine = machine; @@ -264,7 +264,7 @@ coff_make_import_header_by_ordinal(Arena *arena, flags |= COFF_ImportBy_Ordinal << COFF_ImportHeader_ImportByShift; COFF_ImportHeader header = {0}; - header.sig1 = COFF_Machine_Unknown; + header.sig1 = COFF_MachineType_Unknown; header.sig2 = max_U16; header.version = 0; header.machine = machine; @@ -298,8 +298,8 @@ coff_word_size_from_machine(COFF_MachineType machine) { U64 result = 0; switch (machine) { - case COFF_Machine_X64: result = 8; break; - case COFF_Machine_X86: result = 4; break; + case COFF_MachineType_X64: result = 8; break; + case COFF_MachineType_X86: result = 4; break; } return result; } @@ -332,11 +332,11 @@ arch_from_coff_machine(COFF_MachineType machine) { Arch result = Arch_Null; switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: result = Arch_x86; break; - case COFF_Machine_X64: result = Arch_x64; break; - case COFF_Machine_Arm: result = Arch_arm32; break; - case COFF_Machine_Arm64: result = Arch_arm64; break; + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: result = Arch_x86; break; + case COFF_MachineType_X64: result = Arch_x64; break; + case COFF_MachineType_Arm: result = Arch_arm32; break; + case COFF_MachineType_Arm64: result = Arch_arm64; break; } return result; } diff --git a/src/coff/coff.h b/src/coff/coff.h index c109a966..6ff6c1af 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -47,32 +47,31 @@ enum typedef U16 COFF_MachineType; enum { - // TODO(rjf): COFF_Machine prefix -> COFF_MachineType prefix - COFF_Machine_Unknown = 0x0, - COFF_Machine_X86 = 0x14c, - COFF_Machine_X64 = 0x8664, - COFF_Machine_Am33 = 0x1d3, - COFF_Machine_Arm = 0x1c0, - COFF_Machine_Arm64 = 0xaa64, - COFF_Machine_ArmNt = 0x1c4, - COFF_Machine_Ebc = 0xebc, - COFF_Machine_Ia64 = 0x200, - COFF_Machine_M32R = 0x9041, - COFF_Machine_Mips16 = 0x266, - COFF_Machine_MipsFpu = 0x366, - COFF_Machine_MipsFpu16 = 0x466, - COFF_Machine_PowerPc = 0x1f0, - COFF_Machine_PowerPcFp = 0x1f1, - COFF_Machine_R4000 = 0x166, - COFF_Machine_RiscV32 = 0x5032, - COFF_Machine_RiscV64 = 0x5064, - COFF_Machine_RiscV128 = 0x5128, - COFF_Machine_Sh3 = 0x1a2, - COFF_Machine_Sh3Dsp = 0x1a3, - COFF_Machine_Sh4 = 0x1a6, - COFF_Machine_Sh5 = 0x1a8, - COFF_Machine_Thumb = 0x1c2, - COFF_Machine_WceMipsV2 = 0x169 + COFF_MachineType_Unknown = 0x0, + COFF_MachineType_X86 = 0x14c, + COFF_MachineType_X64 = 0x8664, + COFF_MachineType_Am33 = 0x1d3, + COFF_MachineType_Arm = 0x1c0, + COFF_MachineType_Arm64 = 0xaa64, + COFF_MachineType_ArmNt = 0x1c4, + COFF_MachineType_Ebc = 0xebc, + COFF_MachineType_Ia64 = 0x200, + COFF_MachineType_M32R = 0x9041, + COFF_MachineType_Mips16 = 0x266, + COFF_MachineType_MipsFpu = 0x366, + COFF_MachineType_MipsFpu16 = 0x466, + COFF_MachineType_PowerPc = 0x1f0, + COFF_MachineType_PowerPcFp = 0x1f1, + COFF_MachineType_R4000 = 0x166, + COFF_MachineType_RiscV32 = 0x5032, + COFF_MachineType_RiscV64 = 0x5064, + COFF_MachineType_RiscV128 = 0x5128, + COFF_MachineType_Sh3 = 0x1a2, + COFF_MachineType_Sh3Dsp = 0x1a3, + COFF_MachineType_Sh4 = 0x1a6, + COFF_MachineType_Sh5 = 0x1a8, + COFF_MachineType_Thumb = 0x1c2, + COFF_MachineType_WceMipsV2 = 0x169 }; typedef struct COFF_FileHeader @@ -88,7 +87,7 @@ typedef struct COFF_FileHeader typedef struct COFF_BigObjHeader { - U16 sig1; // COFF_Machine_Unknown + U16 sig1; // COFF_MachineType_Unknown U16 sig2; // max_U16 U16 version; // 2 COFF_MachineType machine; @@ -548,7 +547,7 @@ enum typedef struct COFF_ImportHeader { - U16 sig1; // COFF_Machine_Unknown + U16 sig1; // COFF_MachineType_Unknown U16 sig2; // max_U16 U16 version; // 0 COFF_MachineType machine; diff --git a/src/coff/coff_enum.c b/src/coff/coff_enum.c index 7636a78b..ccd96eeb 100644 --- a/src/coff/coff_enum.c +++ b/src/coff/coff_enum.c @@ -21,31 +21,31 @@ read_only struct String8 string; COFF_MachineType machine; } g_coff_machine_map[] = { - { str8_lit_comp(""), COFF_Machine_Unknown }, - { str8_lit_comp("X86"), COFF_Machine_X86 }, - { str8_lit_comp("Amd64"), COFF_Machine_X64 }, - { str8_lit_comp("X64"), COFF_Machine_X64 }, - { str8_lit_comp("Am33"), COFF_Machine_Am33 }, - { str8_lit_comp("Arm"), COFF_Machine_Arm }, - { str8_lit_comp("Arm64"), COFF_Machine_Arm64 }, - { str8_lit_comp("ArmNt"), COFF_Machine_ArmNt }, - { str8_lit_comp("Ebc"), COFF_Machine_Ebc }, - { str8_lit_comp("Ia64"), COFF_Machine_Ia64 }, - { str8_lit_comp("M32r"), COFF_Machine_M32R }, - { str8_lit_comp("Mips16"), COFF_Machine_Mips16 }, - { str8_lit_comp("MipsFpu"), COFF_Machine_MipsFpu }, - { str8_lit_comp("MipsFpu16"), COFF_Machine_MipsFpu16 }, - { str8_lit_comp("PowerPc"), COFF_Machine_PowerPc }, - { str8_lit_comp("PowerPcFp"), COFF_Machine_PowerPcFp }, - { str8_lit_comp("R4000"), COFF_Machine_R4000 }, - { str8_lit_comp("RiscV32"), COFF_Machine_RiscV32 }, - { str8_lit_comp("RiscV64"), COFF_Machine_RiscV64 }, - { str8_lit_comp("Sh3"), COFF_Machine_Sh3 }, - { str8_lit_comp("Sh3Dsp"), COFF_Machine_Sh3Dsp }, - { str8_lit_comp("Sh4"), COFF_Machine_Sh4 }, - { str8_lit_comp("Sh5"), COFF_Machine_Sh5 }, - { str8_lit_comp("Thumb"), COFF_Machine_Thumb }, - { str8_lit_comp("WceMipsV2"), COFF_Machine_WceMipsV2 }, + { str8_lit_comp(""), COFF_MachineType_Unknown }, + { str8_lit_comp("X86"), COFF_MachineType_X86 }, + { str8_lit_comp("Amd64"), COFF_MachineType_X64 }, + { str8_lit_comp("X64"), COFF_MachineType_X64 }, + { str8_lit_comp("Am33"), COFF_MachineType_Am33 }, + { str8_lit_comp("Arm"), COFF_MachineType_Arm }, + { str8_lit_comp("Arm64"), COFF_MachineType_Arm64 }, + { str8_lit_comp("ArmNt"), COFF_MachineType_ArmNt }, + { str8_lit_comp("Ebc"), COFF_MachineType_Ebc }, + { str8_lit_comp("Ia64"), COFF_MachineType_Ia64 }, + { str8_lit_comp("M32r"), COFF_MachineType_M32R }, + { str8_lit_comp("Mips16"), COFF_MachineType_Mips16 }, + { str8_lit_comp("MipsFpu"), COFF_MachineType_MipsFpu }, + { str8_lit_comp("MipsFpu16"), COFF_MachineType_MipsFpu16 }, + { str8_lit_comp("PowerPc"), COFF_MachineType_PowerPc }, + { str8_lit_comp("PowerPcFp"), COFF_MachineType_PowerPcFp }, + { str8_lit_comp("R4000"), COFF_MachineType_R4000 }, + { str8_lit_comp("RiscV32"), COFF_MachineType_RiscV32 }, + { str8_lit_comp("RiscV64"), COFF_MachineType_RiscV64 }, + { str8_lit_comp("Sh3"), COFF_MachineType_Sh3 }, + { str8_lit_comp("Sh3Dsp"), COFF_MachineType_Sh3Dsp }, + { str8_lit_comp("Sh4"), COFF_MachineType_Sh4 }, + { str8_lit_comp("Sh5"), COFF_MachineType_Sh5 }, + { str8_lit_comp("Thumb"), COFF_MachineType_Thumb }, + { str8_lit_comp("WceMipsV2"), COFF_MachineType_WceMipsV2 }, }; read_only static struct { @@ -446,10 +446,10 @@ internal String8 coff_string_from_reloc(COFF_MachineType machine, COFF_RelocType x) { switch (machine) { - case COFF_Machine_X86: return coff_string_from_reloc_x86(x); - case COFF_Machine_X64: return coff_string_from_reloc_x64(x); - case COFF_Machine_Arm: return coff_string_from_reloc_arm(x); - case COFF_Machine_Arm64: return coff_string_from_reloc_arm64(x); + case COFF_MachineType_X86: return coff_string_from_reloc_x86(x); + case COFF_MachineType_X64: return coff_string_from_reloc_x64(x); + case COFF_MachineType_Arm: return coff_string_from_reloc_arm(x); + case COFF_MachineType_Arm64: return coff_string_from_reloc_arm64(x); } return str8_zero(); } @@ -462,7 +462,7 @@ coff_machine_from_string(String8 string) return g_coff_machine_map[i].machine; } } - return COFF_Machine_Unknown; + return COFF_MachineType_Unknown; } internal COFF_ImportType diff --git a/src/coff/coff_parse.c b/src/coff/coff_parse.c index 3e0aaee4..166be2ae 100644 --- a/src/coff/coff_parse.c +++ b/src/coff/coff_parse.c @@ -7,7 +7,7 @@ coff_is_big_obj(String8 raw_coff) B32 is_big_obj = 0; if (raw_coff.size >= sizeof(COFF_BigObjHeader)) { COFF_BigObjHeader *file_header32 = (COFF_BigObjHeader*)(raw_coff.str); - is_big_obj = file_header32->sig1 == COFF_Machine_Unknown && + is_big_obj = file_header32->sig1 == COFF_MachineType_Unknown && file_header32->sig2 == max_U16 && file_header32->version >= 2 && MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0; @@ -26,19 +26,19 @@ coff_is_obj(String8 raw_coff) // validate machine B32 is_machine_type_valid = 0; switch (header->machine) { - case COFF_Machine_Unknown: - case COFF_Machine_X86: case COFF_Machine_X64: - case COFF_Machine_Am33: case COFF_Machine_Arm: - case COFF_Machine_Arm64: case COFF_Machine_ArmNt: - case COFF_Machine_Ebc: case COFF_Machine_Ia64: - case COFF_Machine_M32R: case COFF_Machine_Mips16: - case COFF_Machine_MipsFpu:case COFF_Machine_MipsFpu16: - case COFF_Machine_PowerPc:case COFF_Machine_PowerPcFp: - case COFF_Machine_R4000: case COFF_Machine_RiscV32: - case COFF_Machine_RiscV64:case COFF_Machine_RiscV128: - case COFF_Machine_Sh3: case COFF_Machine_Sh3Dsp: - case COFF_Machine_Sh4: case COFF_Machine_Sh5: - case COFF_Machine_Thumb: case COFF_Machine_WceMipsV2: + case COFF_MachineType_Unknown: + case COFF_MachineType_X86: case COFF_MachineType_X64: + case COFF_MachineType_Am33: case COFF_MachineType_Arm: + case COFF_MachineType_Arm64: case COFF_MachineType_ArmNt: + case COFF_MachineType_Ebc: case COFF_MachineType_Ia64: + case COFF_MachineType_M32R: case COFF_MachineType_Mips16: + case COFF_MachineType_MipsFpu:case COFF_MachineType_MipsFpu16: + case COFF_MachineType_PowerPc:case COFF_MachineType_PowerPcFp: + case COFF_MachineType_R4000: case COFF_MachineType_RiscV32: + case COFF_MachineType_RiscV64:case COFF_MachineType_RiscV128: + case COFF_MachineType_Sh3: case COFF_MachineType_Sh3Dsp: + case COFF_MachineType_Sh4: case COFF_MachineType_Sh5: + case COFF_MachineType_Thumb: case COFF_MachineType_WceMipsV2: { is_machine_type_valid = 1; }break; @@ -499,7 +499,7 @@ coff_is_import(String8 raw_archive_member) if (raw_archive_member.size >= sizeof(U16)*2) { U16 *sig1 = (U16*)raw_archive_member.str; U16 *sig2 = sig1 + 1; - is_import = *sig1 == COFF_Machine_Unknown && *sig2 == 0xffff; + is_import = *sig1 == COFF_MachineType_Unknown && *sig2 == 0xffff; } return is_import; } diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 360d5d3e..0c2316bf 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3714,7 +3714,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ switch(file_header.machine) { default:{}break; - case COFF_Machine_X86: + case COFF_MachineType_X86: { PE_TLSHeader32 tls_header32 = {0}; dmn_process_read_struct(process.dmn_handle, vaddr_range.min + tls_voff_range.min, &tls_header32); @@ -3725,7 +3725,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ tls_header.zero_fill_size = (U64)tls_header32.zero_fill_size; tls_header.characteristics = (U64)tls_header32.characteristics; }break; - case COFF_Machine_X64: + case COFF_MachineType_X64: { dmn_process_read_struct(process.dmn_handle, vaddr_range.min + tls_voff_range.min, &tls_header); }break; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index b4715f5b..5ed5e044 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -495,12 +495,12 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr) Arch arch = Arch_Null; switch(coff_header.machine) { - case COFF_Machine_X86: + case COFF_MachineType_X86: { arch = Arch_x86; optional_size_off = OffsetOf(PE_OptionalHeader32, sizeof_image); }break; - case COFF_Machine_X64: + case COFF_MachineType_X64: { arch = Arch_x64; optional_size_off = OffsetOf(PE_OptionalHeader32Plus, sizeof_image); diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 9d6b5a28..2283b570 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1283,7 +1283,7 @@ lnk_push_linker_symbols(LNK_SymbolTable *symtab, COFF_MachineType machine) LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_Any, 0); { // load config symbols - if (machine == COFF_Machine_X86) { + if (machine == COFF_MachineType_X86) { lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0); } @@ -1604,7 +1604,7 @@ lnk_build_guard_tables(TP_Context *tp, } // TODO: emit table for SEH on X86 - if (machine == COFF_Machine_X86) { + if (machine == COFF_MachineType_X86) { lnk_not_implemented("__safe_se_handler_table"); lnk_not_implemented("__safe_se_handler_count"); } @@ -2372,7 +2372,7 @@ lnk_build_win32_image_header(LNK_SymbolTable *symtab, lnk_build_pe_magic(symtab, header_sect, pe_magic_chunk); lnk_build_coff_file_header(symtab, header_sect, coff_file_header_chunk, config->machine, config->time_stamp, config->file_characteristics); switch (config->machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { lnk_build_pe_optional_header_x64(symtab, header_sect, pe_optional_chunk, @@ -3404,8 +3404,8 @@ lnk_run(int argc, char **argv) String8 delay_helper_name = str8_zero(); switch (config->machine) { - case COFF_Machine_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break; - case COFF_Machine_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break; + case COFF_MachineType_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break; + case COFF_MachineType_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break; default: NotImplemented; } @@ -3464,7 +3464,7 @@ lnk_run(int argc, char **argv) if (is_delayed) { if (!imptab_delayed) { - Assert(config->machine != COFF_Machine_Unknown); + Assert(config->machine != COFF_MachineType_Unknown); B32 is_unloadable = !!(config->flags & LNK_ConfigFlag_DelayUnload); B32 is_bindable = !!(config->flags & LNK_ConfigFlag_DelayBind); imptab_delayed = lnk_import_table_alloc_delayed(st, symtab, config->machine, is_unloadable, is_bindable); @@ -3479,7 +3479,7 @@ lnk_run(int argc, char **argv) } } else { if (!imptab_static) { - Assert(config->machine != COFF_Machine_Unknown); + Assert(config->machine != COFF_MachineType_Unknown); imptab_static = lnk_import_table_alloc_static(st, symtab, config->machine); } LNK_ImportDLL *dll = lnk_import_table_search_dll(imptab_static, import_header->dll_name); @@ -3561,14 +3561,14 @@ lnk_run(int argc, char **argv) LNK_Obj *obj = &obj_node_arr.v[obj_idx].data; // derive machine from obj - if (config->machine == COFF_Machine_Unknown) { + if (config->machine == COFF_MachineType_Unknown) { config->machine = obj->machine; - } else if (config->machine != COFF_Machine_X64) { + } else if (config->machine != COFF_MachineType_X64) { lnk_error_with_loc(LNK_Error_UnsupportedMachine, obj->path, obj->lib_path, "%S machine is supported", coff_string_from_machine_type(obj->machine)); } else { // is obj machine compatible? if (config->machine != obj->machine && - obj->machine != COFF_Machine_Unknown) { // obj with unknown machine type is compatible with any other machine type + obj->machine != COFF_MachineType_Unknown) { // obj with unknown machine type is compatible with any other machine type lnk_error_obj(LNK_Error_IncompatibleObj, obj, "conflicting machine types expected %S but got %S", coff_string_from_machine_type(config->machine), @@ -3990,18 +3990,18 @@ lnk_run(int argc, char **argv) if (pdata_symbol) { String8 pdata = lnk_data_from_chunk_ref_no_pad(sect_id_map, image_data, pdata_symbol->u.defined.u.chunk->ref); switch (config->machine) { - case COFF_Machine_X86: - case COFF_Machine_X64: { + case COFF_MachineType_X86: + case COFF_MachineType_X64: { U64 count = pdata.size / sizeof(PE_IntelPdata); radsort((PE_IntelPdata *)pdata.str, count, lnk_pdata_is_before_x8664); } break; - case COFF_Machine_Arm64: - case COFF_Machine_Arm: { + case COFF_MachineType_Arm64: + case COFF_MachineType_Arm: { AssertAlways(!"TOOD: ARM"); } break; - case COFF_Machine_MipsFpu: - case COFF_Machine_Mips16: - case COFF_Machine_MipsFpu16: { + case COFF_MachineType_MipsFpu: + case COFF_MachineType_Mips16: + case COFF_MachineType_MipsFpu16: { AssertAlways(!"TODO: MIPS"); } break; } diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index aaae53c9..72b3dd12 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -355,11 +355,11 @@ lnk_get_default_function_pad_min(COFF_MachineType machine) { U64 function_pad_min = 0; switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: { + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: { function_pad_min = 5; } break; - case COFF_Machine_X64: { + case COFF_MachineType_X64: { function_pad_min = 6; } break; default: { @@ -399,12 +399,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp case PE_WindowsSubsystem_WINDOWS_CUI: { switch (machine) { - case COFF_Machine_X64: - case COFF_Machine_X86: ver = make_version(6,0); break; + case COFF_MachineType_X64: + case COFF_MachineType_X86: ver = make_version(6,0); break; - case COFF_Machine_ArmNt: - case COFF_Machine_Arm64: - case COFF_Machine_Arm: ver = make_version(6,2); break; + case COFF_MachineType_ArmNt: + case COFF_MachineType_Arm64: + case COFF_MachineType_Arm: ver = make_version(6,2); break; default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break; } @@ -412,12 +412,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp case PE_WindowsSubsystem_WINDOWS_GUI: { switch (machine) { - case COFF_Machine_X64: - case COFF_Machine_X86: ver = make_version(6,0); break; + case COFF_MachineType_X64: + case COFF_MachineType_X86: ver = make_version(6,0); break; - case COFF_Machine_ArmNt: - case COFF_Machine_Arm64: - case COFF_Machine_Arm: ver = make_version(6,2); break; + case COFF_MachineType_ArmNt: + case COFF_MachineType_Arm64: + case COFF_MachineType_Arm: ver = make_version(6,2); break; default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break; } @@ -447,13 +447,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma case PE_WindowsSubsystem_WINDOWS_CUI: { switch (machine) { - case COFF_Machine_X86: ver = make_version(5,1); break; + case COFF_MachineType_X86: ver = make_version(5,1); break; - case COFF_Machine_X64: ver = make_version(5,2); break; + case COFF_MachineType_X64: ver = make_version(5,2); break; - case COFF_Machine_ArmNt: - case COFF_Machine_Arm64: - case COFF_Machine_Arm: ver = make_version(6,2); break; + case COFF_MachineType_ArmNt: + case COFF_MachineType_Arm64: + case COFF_MachineType_Arm: ver = make_version(6,2); break; default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break; } @@ -461,13 +461,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma case PE_WindowsSubsystem_WINDOWS_GUI: { switch (machine) { - case COFF_Machine_X86: ver = make_version(5,1); break; + case COFF_MachineType_X86: ver = make_version(5,1); break; - case COFF_Machine_X64: ver = make_version(5,2); break; + case COFF_MachineType_X64: ver = make_version(5,2); break; - case COFF_Machine_ArmNt: - case COFF_Machine_Arm64: - case COFF_Machine_Arm: ver = make_version(6,2); break; + case COFF_MachineType_ArmNt: + case COFF_MachineType_Arm64: + case COFF_MachineType_Arm: ver = make_version(6,2); break; default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break; } @@ -1213,7 +1213,7 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam case LNK_CmdSwitch_Machine: { if (value_strings.node_count == 1) { COFF_MachineType machine = coff_machine_from_string(value_strings.first->string); - if (machine != COFF_Machine_Unknown) { + if (machine != COFF_MachineType_Unknown) { config->machine = machine; } else { lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "unknown parameter \"%S\"", value_strings.first->string); diff --git a/src/linker/lnk_import_table.c b/src/linker/lnk_import_table.c index 34f44e52..81b7d648 100644 --- a/src/linker/lnk_import_table.c +++ b/src/linker/lnk_import_table.c @@ -345,7 +345,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt // emit tail merge LNK_Chunk *tail_merge_chunk = 0; switch (machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main); tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol); } break; @@ -446,7 +446,7 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr; if (header->type == COFF_ImportHeader_Code) { switch (dll->machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { // generate jump thunk LNK_Chunk *jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol); lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk); @@ -507,7 +507,7 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym LNK_Chunk *load_thunk_chunk = 0; if (header->type == COFF_ImportHeader_Code) { switch (dll->machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name); LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], iat_symbol_name, LNK_SymbolScopeFlag_Main); @@ -624,12 +624,12 @@ lnk_ordinal_data_from_hint(Arena *arena, COFF_MachineType machine, U16 hint) { String8 ordinal_data = str8_zero(); switch (machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { U64 *ordinal = push_array(arena, U64, 1); *ordinal = coff_make_ordinal64(hint); ordinal_data = str8_struct(ordinal); } break; - case COFF_Machine_X86: { + case COFF_MachineType_X86: { U32 *ordinal = push_array(arena, U32, 1); *ordinal = coff_make_ordinal32(hint); ordinal_data = str8_struct(ordinal); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index b200b1db..fc4e54d0 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -541,7 +541,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach { ProfBeginFunction(); - Assert(machine == COFF_Machine_X64); + Assert(machine == COFF_MachineType_X64); Assert(str8_match_lit("dll", str8_skip_last_dot(dll_name), StringMatchFlag_CaseInsensitive|StringMatchFlag_RightSideSloppy)); String8List list = {0}; diff --git a/src/linker/lnk_reloc.c b/src/linker/lnk_reloc.c index b37120bd..f78df7e6 100644 --- a/src/linker/lnk_reloc.c +++ b/src/linker/lnk_reloc.c @@ -117,8 +117,8 @@ lnk_ext_reloc_type_from_coff(COFF_MachineType machine, U32 type) { LNK_RelocType result = LNK_Reloc_NULL; switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X64: { + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X64: { switch (type) { case COFF_Reloc_X64_Abs: result = LNK_Reloc_NULL; break; case COFF_Reloc_X64_Addr64: result = LNK_Reloc_ADDR_64; break; @@ -150,7 +150,7 @@ lnk_ext_reloc_type_to_coff(COFF_MachineType machine, LNK_RelocType type) { U32 result = 0; switch (machine) { - case COFF_Machine_X64: { + case COFF_MachineType_X64: { switch (type) { case LNK_Reloc_NULL: result = COFF_Reloc_X64_Abs; break; case LNK_Reloc_ADDR_64: result = COFF_Reloc_X64_Addr64; break; diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index 4ac8cb25..084538db 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -236,8 +236,8 @@ lnk_code_align_byte_from_machine(COFF_MachineType machine) { U8 align_byte = 0; switch (machine) { - case COFF_Machine_X64: - case COFF_Machine_X86: { + case COFF_MachineType_X64: + case COFF_MachineType_X86: { align_byte = 0xCC; } break; default: { diff --git a/src/linker/rdi/rdi_coff.c b/src/linker/rdi/rdi_coff.c index 32b93862..2646860c 100644 --- a/src/linker/rdi/rdi_coff.c +++ b/src/linker/rdi/rdi_coff.c @@ -5,31 +5,31 @@ internal RDI_Arch rdi_arch_from_coff_machine(COFF_MachineType machine) { switch (machine) { - case COFF_Machine_X86: return RDI_Arch_X86; - case COFF_Machine_X64: return RDI_Arch_X64; + case COFF_MachineType_X86: return RDI_Arch_X86; + case COFF_MachineType_X64: return RDI_Arch_X64; - case COFF_Machine_Unknown: - case COFF_Machine_Am33: - case COFF_Machine_Arm: - case COFF_Machine_Arm64: - case COFF_Machine_ArmNt: - case COFF_Machine_Ebc: - case COFF_Machine_Ia64: - case COFF_Machine_M32R: - case COFF_Machine_Mips16: - case COFF_Machine_MipsFpu: - case COFF_Machine_MipsFpu16: - case COFF_Machine_PowerPc: - case COFF_Machine_PowerPcFp: - case COFF_Machine_R4000: - case COFF_Machine_RiscV32: - case COFF_Machine_RiscV64: - case COFF_Machine_Sh3: - case COFF_Machine_Sh3Dsp: - case COFF_Machine_Sh4: - case COFF_Machine_Sh5: - case COFF_Machine_Thumb: - case COFF_Machine_WceMipsV2: + case COFF_MachineType_Unknown: + case COFF_MachineType_Am33: + case COFF_MachineType_Arm: + case COFF_MachineType_Arm64: + case COFF_MachineType_ArmNt: + case COFF_MachineType_Ebc: + case COFF_MachineType_Ia64: + case COFF_MachineType_M32R: + case COFF_MachineType_Mips16: + case COFF_MachineType_MipsFpu: + case COFF_MachineType_MipsFpu16: + case COFF_MachineType_PowerPc: + case COFF_MachineType_PowerPcFp: + case COFF_MachineType_R4000: + case COFF_MachineType_RiscV32: + case COFF_MachineType_RiscV64: + case COFF_MachineType_Sh3: + case COFF_MachineType_Sh3Dsp: + case COFF_MachineType_Sh4: + case COFF_MachineType_Sh5: + case COFF_MachineType_Thumb: + case COFF_MachineType_WceMipsV2: NotImplemented; default: return RDI_Arch_NULL; diff --git a/src/pe/pe.c b/src/pe/pe.c index f6dc53b5..b631386f 100644 --- a/src/pe/pe.c +++ b/src/pe/pe.c @@ -568,8 +568,8 @@ pe_bin_info_from_data(Arena *arena, String8 data) switch(file_header.machine) { default:{ NotImplemented; }break; - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: { PE_TLSHeader32 tls_header32 = {0}; if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header32) == sizeof(tls_header32)) @@ -586,7 +586,7 @@ pe_bin_info_from_data(Arena *arena, String8 data) Assert(!"unable to read TLS Header 32"); } }break; - case COFF_Machine_X64: + case COFF_MachineType_X64: { if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header) != sizeof(tls_header)) { @@ -981,7 +981,7 @@ pe_get_entry_point_names(COFF_MachineType machine, String8Array entry_point_names = {0}; if (file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) { - if (machine == COFF_Machine_X86) { + if (machine == COFF_MachineType_X86) { read_only static String8 dll_entry_point_arr[] = { str8_lit_comp("__DllMainCRTStartup@12"), }; @@ -1432,8 +1432,8 @@ pe_tls_from_data(Arena *arena, U64 *callback_addrs = 0; switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: { + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: { PE_TLSHeader32 header32 = {0}; str8_deserial_read_struct(raw_tls, 0, &header32); @@ -1458,7 +1458,7 @@ pe_tls_from_data(Arena *arena, callback_addrs[i] = (U64)src[i]; } } break; - case COFF_Machine_X64: { + case COFF_MachineType_X64: { str8_deserial_read_struct(raw_tls, 0, &header64); U64 callbacks_voff = header64.callbacks_address - image_base; diff --git a/src/radcon/radcon_coff.c b/src/radcon/radcon_coff.c index 56306141..35c6a23d 100644 --- a/src/radcon/radcon_coff.c +++ b/src/radcon/radcon_coff.c @@ -5,31 +5,31 @@ internal RDI_Arch c2r_rdi_arch_from_coff_machine(COFF_MachineType machine) { switch (machine) { - case COFF_Machine_X86: return RDI_Arch_X86; - case COFF_Machine_X64: return RDI_Arch_X64; + case COFF_MachineType_X86: return RDI_Arch_X86; + case COFF_MachineType_X64: return RDI_Arch_X64; - case COFF_Machine_Unknown: - case COFF_Machine_Am33: - case COFF_Machine_Arm: - case COFF_Machine_Arm64: - case COFF_Machine_ArmNt: - case COFF_Machine_Ebc: - case COFF_Machine_Ia64: - case COFF_Machine_M32R: - case COFF_Machine_Mips16: - case COFF_Machine_MipsFpu: - case COFF_Machine_MipsFpu16: - case COFF_Machine_PowerPc: - case COFF_Machine_PowerPcFp: - case COFF_Machine_R4000: - case COFF_Machine_RiscV32: - case COFF_Machine_RiscV64: - case COFF_Machine_Sh3: - case COFF_Machine_Sh3Dsp: - case COFF_Machine_Sh4: - case COFF_Machine_Sh5: - case COFF_Machine_Thumb: - case COFF_Machine_WceMipsV2: + case COFF_MachineType_Unknown: + case COFF_MachineType_Am33: + case COFF_MachineType_Arm: + case COFF_MachineType_Arm64: + case COFF_MachineType_ArmNt: + case COFF_MachineType_Ebc: + case COFF_MachineType_Ia64: + case COFF_MachineType_M32R: + case COFF_MachineType_Mips16: + case COFF_MachineType_MipsFpu: + case COFF_MachineType_MipsFpu16: + case COFF_MachineType_PowerPc: + case COFF_MachineType_PowerPcFp: + case COFF_MachineType_R4000: + case COFF_MachineType_RiscV32: + case COFF_MachineType_RiscV64: + case COFF_MachineType_Sh3: + case COFF_MachineType_Sh3Dsp: + case COFF_MachineType_Sh4: + case COFF_MachineType_Sh5: + case COFF_MachineType_Thumb: + case COFF_MachineType_WceMipsV2: NotImplemented; default: return RDI_Arch_NULL; diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 5eebeb56..52f76b9c 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -7959,9 +7959,9 @@ pe_print_exceptions(Arena *arena, rd_indent(); rd_printf("%-8s %-8s %-8s %-8s", "Offset", "Begin", "End", "Unwind Info"); switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X64: - case COFF_Machine_X86: { + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X64: + case COFF_MachineType_X86: { pe_print_exceptions_x8664(arena, out, indent, section_count, sections, raw_data, except_frange, rdi); } break; default: NotImplemented; break; @@ -7994,9 +7994,9 @@ pe_print_base_relocs(Arena *arena, U32 addr_size = 0; switch (machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: addr_size = 4; break; - case COFF_Machine_X64: addr_size = 8; break; + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: addr_size = 4; break; + case COFF_MachineType_X64: addr_size = 8; break; default: NotImplemented; } @@ -8026,9 +8026,9 @@ pe_print_base_relocs(Arena *arena, case PE_BaseRelocKind_DIR64: type_str = "DIR64"; break; default: { switch (machine) { - case COFF_Machine_Arm: - case COFF_Machine_Arm64: - case COFF_Machine_ArmNt: { + case COFF_MachineType_Arm: + case COFF_MachineType_Arm64: + case COFF_MachineType_ArmNt: { switch (type) { case PE_BaseRelocKind_ARM_MOV32: type_str = "ARM_MOV32"; break; case PE_BaseRelocKind_THUMB_MOV32: type_str = "THUMB_MOV32"; break; @@ -8226,8 +8226,8 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op String8 raw_lc = str8_substr(raw_data, dirs_file_ranges[PE_DataDirectoryIndex_LOAD_CONFIG]); if (raw_lc.size) { switch (file_header->machine) { - case COFF_Machine_Unknown: break; - case COFF_Machine_X86: { + case COFF_MachineType_Unknown: break; + case COFF_MachineType_X86: { PE_LoadConfig32 *lc = str8_deserial_get_raw_ptr(raw_lc, 0, sizeof(*lc)); if (lc) { pe_print_load_config32(arena, out, indent, lc); @@ -8235,7 +8235,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op rd_errorf("not enough bytes to parse 32bit load config"); } } break; - case COFF_Machine_X64: { + case COFF_MachineType_X64: { PE_LoadConfig64 *lc = str8_deserial_get_raw_ptr(raw_lc, 0, sizeof(*lc)); if (lc) { pe_print_load_config64(arena, out, indent, lc); From 190b74f411c15dbbdbe5f8b70f1acd80b3fccf1e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 1 Apr 2025 16:04:38 -0700 Subject: [PATCH 298/755] shift first-class basic type names to more widely-used names (int32 instead of S32, etc.); force match of any debugger-known basic type name -> key, do not settle for bogus aliases from debug info --- project.4coder | 4 +-- src/eval/eval.mdesk | 50 ++++++++++++++-------------- src/eval/eval_parse.c | 61 +++++++++++++++++++++++----------- src/eval/generated/eval.meta.c | 50 ++++++++++++++-------------- 4 files changed, 93 insertions(+), 72 deletions(-) diff --git a/project.4coder b/project.4coder index f08ca89e..0b003cbf 100644 --- a/project.4coder +++ b/project.4coder @@ -52,8 +52,8 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target - // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index ec41dfa9..b9a1d33c 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -26,32 +26,32 @@ E_TypeKindTable: {UChar8 "uchar8" 1 } {UChar16 "uchar16" 2 } {UChar32 "uchar32" 4 } - {U8 "U8" 1 } - {U16 "U16" 2 } - {U32 "U32" 4 } - {U64 "U64" 8 } - {U128 "U128" 16 } - {U256 "U256" 32 } - {U512 "U512" 64 } - {S8 "S8" 1 } - {S16 "S16" 2 } - {S32 "S32" 4 } - {S64 "S64" 8 } - {S128 "S128" 16 } - {S256 "S256" 32 } - {S512 "S512" 64 } + {U8 "uint8" 1 } + {U16 "uint16" 2 } + {U32 "uint32" 4 } + {U64 "uint64" 8 } + {U128 "uint128" 16 } + {U256 "uint256" 32 } + {U512 "uint512" 64 } + {S8 "int8" 1 } + {S16 "int16" 2 } + {S32 "int32" 4 } + {S64 "int64" 8 } + {S128 "int128" 16 } + {S256 "int256" 32 } + {S512 "int512" 64 } {Bool "bool" 1 } - {F16 "F16" 2 } - {F32 "F32" 4 } - {F32PP "F32PP" 4 } - {F48 "F48" 6 } - {F64 "F64" 8 } - {F80 "F80" 10 } - {F128 "F128" 16 } - {ComplexF32 "ComplexF32" 8 } - {ComplexF64 "ComplexF64" 16 } - {ComplexF80 "ComplexF80" 20 } - {ComplexF128 "ComplexF128" 32 } + {F16 "float16" 2 } + {F32 "float32" 4 } + {F32PP "float32PP" 4 } + {F48 "float48" 6 } + {F64 "float64" 8 } + {F80 "float80" 10 } + {F128 "float128" 16 } + {ComplexF32 "complex_float32" 8 } + {ComplexF64 "complex_float64" 16 } + {ComplexF80 "complex_float80" 20 } + {ComplexF128 "complex_float128" 32 } {Modifier "modifier" 0 } {Ptr "ptr" 0 } {LRef "lref" 0 } diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 2a4b1b66..7b48f62d 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -914,104 +914,125 @@ e_leaf_type_from_name(String8 name) { E_TypeKey key = zero_struct; B32 found = 0; - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, name.str, name.size); - if(node != 0) - { - U32 match_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &match_count); - if(match_count != 0) - { - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, matches[0]); - found = (type_node->kind != RDI_TypeKind_NULL); - key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), matches[0], module_idx); - break; - } - } - } if(!found) { #define Case(str) (str8_match(name, str8_lit(str), 0)) if(0){} else if(Case("u8") || Case("uint8") || Case("uint8_t") || Case("U8")) { + found = 1; key = e_type_key_basic(E_TypeKind_U8); } else if(Case("uchar8") || Case("uchar")) { + found = 1; key = e_type_key_basic(E_TypeKind_UChar8); } else if(Case("u16") || Case("uint16") || Case("uint16_t") || Case("U16")) { + found = 1; key = e_type_key_basic(E_TypeKind_U16); } else if(Case("uchar16")) { + found = 1; key = e_type_key_basic(E_TypeKind_UChar16); } else if(Case("u32") || Case("uint32") || Case("uint32_t") || Case("U32") || Case("uint")) { + found = 1; key = e_type_key_basic(E_TypeKind_U32); } else if(Case("uchar32")) { + found = 1; key = e_type_key_basic(E_TypeKind_UChar32); } else if(Case("u64") || Case("uint64") || Case("uint64_t") || Case("U64") || Case("size_t")) { + found = 1; key = e_type_key_basic(E_TypeKind_U64); } else if(Case("s8") || Case("b8") || Case("B8") || Case("i8") || Case("int8") || Case("int8_t") || Case("S8")) { + found = 1; key = e_type_key_basic(E_TypeKind_S8); } else if(Case("char8") || Case("char")) { + found = 1; key = e_type_key_basic(E_TypeKind_Char8); } else if(Case("s16") || Case("b16") || Case("B16") || Case("i16") || Case("int16") || Case("int16_t") || Case("S16")) { + found = 1; key = e_type_key_basic(E_TypeKind_S16); } else if(Case("char16")) { + found = 1; key = e_type_key_basic(E_TypeKind_Char16); } else if(Case("s32") || Case("b32") || Case("B32") || Case("i32") || Case("int32") || Case("int32_t") || Case("char32") || Case("S32") || Case("int")) { + found = 1; key = e_type_key_basic(E_TypeKind_S32); } else if(Case("char32")) { + found = 1; key = e_type_key_basic(E_TypeKind_Char32); } else if(Case("s64") || Case("b64") || Case("B64") || Case("i64") || Case("int64") || Case("int64_t") || Case("S64") || Case("ssize_t")) { + found = 1; key = e_type_key_basic(E_TypeKind_S64); } else if(Case("void")) { + found = 1; key = e_type_key_basic(E_TypeKind_Void); } else if(Case("bool")) { + found = 1; key = e_type_key_basic(E_TypeKind_Bool); } else if(Case("float") || Case("f32") || Case("F32") || Case("r32") || Case("R32")) { + found = 1; key = e_type_key_basic(E_TypeKind_F32); } else if(Case("double") || Case("f64") || Case("F64") || Case("r64") || Case("R64")) { + found = 1; key = e_type_key_basic(E_TypeKind_F64); } #undef Case } + if(!found) + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, name.str, name.size); + if(node != 0) + { + U32 match_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &match_count); + if(match_count != 0) + { + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, matches[0]); + found = (type_node->kind != RDI_TypeKind_NULL); + key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), matches[0], module_idx); + break; + } + } + } + } return key; } diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 50b115ba..cb7cdfea 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -26,32 +26,32 @@ str8_lit_comp("char32"), str8_lit_comp("uchar8"), str8_lit_comp("uchar16"), str8_lit_comp("uchar32"), -str8_lit_comp("U8"), -str8_lit_comp("U16"), -str8_lit_comp("U32"), -str8_lit_comp("U64"), -str8_lit_comp("U128"), -str8_lit_comp("U256"), -str8_lit_comp("U512"), -str8_lit_comp("S8"), -str8_lit_comp("S16"), -str8_lit_comp("S32"), -str8_lit_comp("S64"), -str8_lit_comp("S128"), -str8_lit_comp("S256"), -str8_lit_comp("S512"), +str8_lit_comp("uint8"), +str8_lit_comp("uint16"), +str8_lit_comp("uint32"), +str8_lit_comp("uint64"), +str8_lit_comp("uint128"), +str8_lit_comp("uint256"), +str8_lit_comp("uint512"), +str8_lit_comp("int8"), +str8_lit_comp("int16"), +str8_lit_comp("int32"), +str8_lit_comp("int64"), +str8_lit_comp("int128"), +str8_lit_comp("int256"), +str8_lit_comp("int512"), str8_lit_comp("bool"), -str8_lit_comp("F16"), -str8_lit_comp("F32"), -str8_lit_comp("F32PP"), -str8_lit_comp("F48"), -str8_lit_comp("F64"), -str8_lit_comp("F80"), -str8_lit_comp("F128"), -str8_lit_comp("ComplexF32"), -str8_lit_comp("ComplexF64"), -str8_lit_comp("ComplexF80"), -str8_lit_comp("ComplexF128"), +str8_lit_comp("float16"), +str8_lit_comp("float32"), +str8_lit_comp("float32PP"), +str8_lit_comp("float48"), +str8_lit_comp("float64"), +str8_lit_comp("float80"), +str8_lit_comp("float128"), +str8_lit_comp("complex_float32"), +str8_lit_comp("complex_float64"), +str8_lit_comp("complex_float80"), +str8_lit_comp("complex_float128"), str8_lit_comp("modifier"), str8_lit_comp("ptr"), str8_lit_comp("lref"), From b2ae4d89d7bf0634aa579904d9995bc1c666b67e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 11:08:27 -0700 Subject: [PATCH 299/755] eval: re-slice helper map data structures -> core --- src/eval/eval_core.c | 318 ++++++++++++++++++++++++++++++++++++++++++ src/eval/eval_core.h | 24 ++++ src/eval/eval_parse.c | 318 ------------------------------------------ src/eval/eval_parse.h | 24 ---- 4 files changed, 342 insertions(+), 342 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index ada7177d..bc53ed0e 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -74,3 +74,321 @@ e_space_make(E_SpaceKind kind) space.kind = kind; return space; } + +//////////////////////////////// +//~ rjf: Basic Map Functions + +//- rjf: string -> num + +internal E_String2NumMap +e_string2num_map_make(Arena *arena, U64 slot_count) +{ + E_String2NumMap map = {0}; + map.slots_count = slot_count; + map.slots = push_array(arena, E_String2NumMapSlot, map.slots_count); + return map; +} + +internal void +e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num) +{ + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + E_String2NumMapNode *existing_node = 0; + for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0) && node->num == num) + { + existing_node = node; + break; + } + } + if(existing_node == 0) + { + E_String2NumMapNode *node = push_array(arena, E_String2NumMapNode, 1); + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + SLLQueuePush_N(map->first, map->last, node, order_next); + node->string = push_str8_copy(arena, string); + node->num = num; + map->node_count += 1; + } +} + +internal U64 +e_num_from_string(E_String2NumMap *map, String8 string) +{ + U64 num = 0; + if(map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + E_String2NumMapNode *existing_node = 0; + for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + existing_node = node; + break; + } + } + if(existing_node != 0) + { + num = existing_node->num; + } + } + return num; +} + +internal E_String2NumMapNodeArray +e_string2num_map_node_array_from_map(Arena *arena, E_String2NumMap *map) +{ + E_String2NumMapNodeArray result = {0}; + result.count = map->node_count; + result.v = push_array(arena, E_String2NumMapNode *, result.count); + U64 idx = 0; + for(E_String2NumMapNode *n = map->first; n != 0; n = n->order_next, idx += 1) + { + result.v[idx] = n; + } + return result; +} + +internal int +e_string2num_map_node_qsort_compare__num_ascending(E_String2NumMapNode **a, E_String2NumMapNode **b) +{ + int result = 0; + if(a[0]->num < b[0]->num) + { + result = -1; + } + else if(a[0]->num > b[0]->num) + { + result = +1; + } + return result; +} + +internal void +e_string2num_map_node_array_sort__in_place(E_String2NumMapNodeArray *array) +{ + quick_sort(array->v, array->count, sizeof(array->v[0]), e_string2num_map_node_qsort_compare__num_ascending); +} + +//- rjf: string -> expr + +internal E_String2ExprMap +e_string2expr_map_make(Arena *arena, U64 slot_count) +{ + E_String2ExprMap map = {0}; + map.slots_count = slot_count; + map.slots = push_array(arena, E_String2ExprMapSlot, map.slots_count); + return map; +} + +internal void +e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr) +{ + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + E_String2ExprMapNode *existing_node = 0; + for(E_String2ExprMapNode *node = map->slots[slot_idx].first; + node != 0; + node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + existing_node = node; + break; + } + } + if(existing_node == 0) + { + E_String2ExprMapNode *node = push_array(arena, E_String2ExprMapNode, 1); + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + node->string = push_str8_copy(arena, string); + existing_node = node; + existing_node->expr = expr; + } +} + +internal void +e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_String2ExprMapNode *node = map->slots[slot_idx].first; + node != 0; + node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + node->poison_count += 1; + break; + } + } +} + +internal void +e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_String2ExprMapNode *node = map->slots[slot_idx].first; + node != 0; + node = node->hash_next) + { + if(str8_match(node->string, string, 0) && node->poison_count > 0) + { + node->poison_count -= 1; + break; + } + } +} + +internal E_Expr * +e_string2expr_lookup(E_String2ExprMap *map, String8 string) +{ + E_Expr *expr = &e_expr_nil; + if(map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + E_String2ExprMapNode *existing_node = 0; + for(E_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0) && node->poison_count == 0) + { + existing_node = node; + break; + } + } + if(existing_node != 0) + { + expr = existing_node->expr; + } + } + return expr; +} + +//////////////////////////////// +//~ rjf: Debug-Info-Driven Map Building Functions + +internal E_String2NumMap * +e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) +{ + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: gather scopes to walk + typedef struct Task Task; + struct Task + { + Task *next; + RDI_Scope *scope; + }; + Task *first_task = 0; + Task *last_task = 0; + + //- rjf: voff -> tightest scope + RDI_Scope *tightest_scope = 0; + { + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + Task *task = push_array(scratch.arena, Task, 1); + task->scope = scope; + SLLQueuePush(first_task, last_task, task); + tightest_scope = scope; + } + + //- rjf: voff-1 -> scope + if(voff > 0) + { + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff-1); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + if(scope != tightest_scope) + { + Task *task = push_array(scratch.arena, Task, 1); + task->scope = scope; + SLLQueuePush(first_task, last_task, task); + } + } + + //- rjf: tightest scope -> walk up the tree & build tasks for each parent scope + if(tightest_scope != 0) + { + RDI_Scope *nil_scope = rdi_element_from_name_idx(rdi, Scopes, 0); + for(RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, tightest_scope->parent_scope_idx); + scope != 0 && scope != nil_scope; + scope = rdi_element_from_name_idx(rdi, Scopes, scope->parent_scope_idx)) + { + Task *task = push_array(scratch.arena, Task, 1); + task->scope = scope; + SLLQueuePush(first_task, last_task, task); + } + } + + //- rjf: build blank map + E_String2NumMap *map = push_array(arena, E_String2NumMap, 1); + *map = e_string2num_map_make(arena, 1024); + + //- rjf: accumulate locals for all tasks + for(Task *task = first_task; task != 0; task = task->next) + { + RDI_Scope *scope = task->scope; + if(scope != 0) + { + U32 local_opl_idx = scope->local_first + scope->local_count; + for(U32 local_idx = scope->local_first; local_idx < local_opl_idx; local_idx += 1) + { + RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_idx); + U64 local_name_size = 0; + U8 *local_name_str = rdi_string_from_idx(rdi, local_var->name_string_idx, &local_name_size); + String8 name = push_str8_copy(arena, str8(local_name_str, local_name_size)); + e_string2num_map_insert(arena, map, name, (U64)local_idx+1); + } + } + } + + scratch_end(scratch); + return map; +} + +internal E_String2NumMap * +e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) +{ + //- rjf: voff -> tightest scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + RDI_Scope *tightest_scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + + //- rjf: tightest scope -> procedure + U32 proc_idx = tightest_scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + + //- rjf: procedure -> udt + U32 udt_idx = procedure->container_idx; + RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, udt_idx); + + //- rjf: build blank map + E_String2NumMap *map = push_array(arena, E_String2NumMap, 1); + *map = e_string2num_map_make(arena, 64); + + //- rjf: udt -> fill member map + if(!(udt->flags & RDI_UDTFlag_EnumMembers)) + { + U64 data_member_num = 1; + for(U32 member_idx = udt->member_first; + member_idx < udt->member_first+udt->member_count; + member_idx += 1) + { + RDI_Member *m = rdi_element_from_name_idx(rdi, Members, member_idx); + if(m->kind == RDI_MemberKind_DataField) + { + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, m->name_string_idx, &name.size); + e_string2num_map_insert(arena, map, name, data_member_num); + data_member_num += 1; + } + } + } + + return map; +} diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 7bcd86a1..edbb5702 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -639,4 +639,28 @@ internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push); internal E_Space e_space_make(E_SpaceKind kind); +//////////////////////////////// +//~ rjf: Basic Map Functions + +//- rjf: string -> num +internal E_String2NumMap e_string2num_map_make(Arena *arena, U64 slot_count); +internal void e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num); +internal U64 e_num_from_string(E_String2NumMap *map, String8 string); +internal E_String2NumMapNodeArray e_string2num_map_node_array_from_map(Arena *arena, E_String2NumMap *map); +internal int e_string2num_map_node_qsort_compare__num_ascending(E_String2NumMapNode **a, E_String2NumMapNode **b); +internal void e_string2num_map_node_array_sort__in_place(E_String2NumMapNodeArray *array); + +//- rjf: string -> expr +internal E_String2ExprMap e_string2expr_map_make(Arena *arena, U64 slot_count); +internal void e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr); +internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string); +internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string); +internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string); + +//////////////////////////////// +//~ rjf: Debug-Info-Driven Map Building Functions + +internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); +internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); + #endif // EVAL_CORE_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 7b48f62d..352067e2 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -20,324 +20,6 @@ global read_only String8 e_multichar_symbol_strings[] = global read_only S64 e_max_precedence = 15; -//////////////////////////////// -//~ rjf: Basic Map Functions - -//- rjf: string -> num - -internal E_String2NumMap -e_string2num_map_make(Arena *arena, U64 slot_count) -{ - E_String2NumMap map = {0}; - map.slots_count = slot_count; - map.slots = push_array(arena, E_String2NumMapSlot, map.slots_count); - return map; -} - -internal void -e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - E_String2NumMapNode *existing_node = 0; - for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->num == num) - { - existing_node = node; - break; - } - } - if(existing_node == 0) - { - E_String2NumMapNode *node = push_array(arena, E_String2NumMapNode, 1); - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - SLLQueuePush_N(map->first, map->last, node, order_next); - node->string = push_str8_copy(arena, string); - node->num = num; - map->node_count += 1; - } -} - -internal U64 -e_num_from_string(E_String2NumMap *map, String8 string) -{ - U64 num = 0; - if(map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - E_String2NumMapNode *existing_node = 0; - for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - existing_node = node; - break; - } - } - if(existing_node != 0) - { - num = existing_node->num; - } - } - return num; -} - -internal E_String2NumMapNodeArray -e_string2num_map_node_array_from_map(Arena *arena, E_String2NumMap *map) -{ - E_String2NumMapNodeArray result = {0}; - result.count = map->node_count; - result.v = push_array(arena, E_String2NumMapNode *, result.count); - U64 idx = 0; - for(E_String2NumMapNode *n = map->first; n != 0; n = n->order_next, idx += 1) - { - result.v[idx] = n; - } - return result; -} - -internal int -e_string2num_map_node_qsort_compare__num_ascending(E_String2NumMapNode **a, E_String2NumMapNode **b) -{ - int result = 0; - if(a[0]->num < b[0]->num) - { - result = -1; - } - else if(a[0]->num > b[0]->num) - { - result = +1; - } - return result; -} - -internal void -e_string2num_map_node_array_sort__in_place(E_String2NumMapNodeArray *array) -{ - quick_sort(array->v, array->count, sizeof(array->v[0]), e_string2num_map_node_qsort_compare__num_ascending); -} - -//- rjf: string -> expr - -internal E_String2ExprMap -e_string2expr_map_make(Arena *arena, U64 slot_count) -{ - E_String2ExprMap map = {0}; - map.slots_count = slot_count; - map.slots = push_array(arena, E_String2ExprMapSlot, map.slots_count); - return map; -} - -internal void -e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - E_String2ExprMapNode *existing_node = 0; - for(E_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - existing_node = node; - break; - } - } - if(existing_node == 0) - { - E_String2ExprMapNode *node = push_array(arena, E_String2ExprMapNode, 1); - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - node->string = push_str8_copy(arena, string); - existing_node = node; - existing_node->expr = expr; - } -} - -internal void -e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - for(E_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - node->poison_count += 1; - break; - } - } -} - -internal void -e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - for(E_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->poison_count > 0) - { - node->poison_count -= 1; - break; - } - } -} - -internal E_Expr * -e_string2expr_lookup(E_String2ExprMap *map, String8 string) -{ - E_Expr *expr = &e_expr_nil; - if(map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - E_String2ExprMapNode *existing_node = 0; - for(E_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->poison_count == 0) - { - existing_node = node; - break; - } - } - if(existing_node != 0) - { - expr = existing_node->expr; - } - } - return expr; -} - -//////////////////////////////// -//~ rjf: Debug-Info-Driven Map Building Functions - -internal E_String2NumMap * -e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) -{ - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: gather scopes to walk - typedef struct Task Task; - struct Task - { - Task *next; - RDI_Scope *scope; - }; - Task *first_task = 0; - Task *last_task = 0; - - //- rjf: voff -> tightest scope - RDI_Scope *tightest_scope = 0; - { - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - tightest_scope = scope; - } - - //- rjf: voff-1 -> scope - if(voff > 0) - { - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff-1); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - if(scope != tightest_scope) - { - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - } - } - - //- rjf: tightest scope -> walk up the tree & build tasks for each parent scope - if(tightest_scope != 0) - { - RDI_Scope *nil_scope = rdi_element_from_name_idx(rdi, Scopes, 0); - for(RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, tightest_scope->parent_scope_idx); - scope != 0 && scope != nil_scope; - scope = rdi_element_from_name_idx(rdi, Scopes, scope->parent_scope_idx)) - { - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - } - } - - //- rjf: build blank map - E_String2NumMap *map = push_array(arena, E_String2NumMap, 1); - *map = e_string2num_map_make(arena, 1024); - - //- rjf: accumulate locals for all tasks - for(Task *task = first_task; task != 0; task = task->next) - { - RDI_Scope *scope = task->scope; - if(scope != 0) - { - U32 local_opl_idx = scope->local_first + scope->local_count; - for(U32 local_idx = scope->local_first; local_idx < local_opl_idx; local_idx += 1) - { - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_idx); - U64 local_name_size = 0; - U8 *local_name_str = rdi_string_from_idx(rdi, local_var->name_string_idx, &local_name_size); - String8 name = push_str8_copy(arena, str8(local_name_str, local_name_size)); - e_string2num_map_insert(arena, map, name, (U64)local_idx+1); - } - } - } - - scratch_end(scratch); - return map; -} - -internal E_String2NumMap * -e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) -{ - //- rjf: voff -> tightest scope - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *tightest_scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - - //- rjf: tightest scope -> procedure - U32 proc_idx = tightest_scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - - //- rjf: procedure -> udt - U32 udt_idx = procedure->container_idx; - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, udt_idx); - - //- rjf: build blank map - E_String2NumMap *map = push_array(arena, E_String2NumMap, 1); - *map = e_string2num_map_make(arena, 64); - - //- rjf: udt -> fill member map - if(!(udt->flags & RDI_UDTFlag_EnumMembers)) - { - U64 data_member_num = 1; - for(U32 member_idx = udt->member_first; - member_idx < udt->member_first+udt->member_count; - member_idx += 1) - { - RDI_Member *m = rdi_element_from_name_idx(rdi, Members, member_idx); - if(m->kind == RDI_MemberKind_DataField) - { - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, m->name_string_idx, &name.size); - e_string2num_map_insert(arena, map, name, data_member_num); - data_member_num += 1; - } - } - } - - return map; -} - //////////////////////////////// //~ rjf: Tokenization Functions diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index cd34d618..a251ec3c 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -57,30 +57,6 @@ global read_only E_String2ExprMap e_string2expr_map_nil = {0}; global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; thread_static E_ParseState *e_parse_state = 0; -//////////////////////////////// -//~ rjf: Basic Map Functions - -//- rjf: string -> num -internal E_String2NumMap e_string2num_map_make(Arena *arena, U64 slot_count); -internal void e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num); -internal U64 e_num_from_string(E_String2NumMap *map, String8 string); -internal E_String2NumMapNodeArray e_string2num_map_node_array_from_map(Arena *arena, E_String2NumMap *map); -internal int e_string2num_map_node_qsort_compare__num_ascending(E_String2NumMapNode **a, E_String2NumMapNode **b); -internal void e_string2num_map_node_array_sort__in_place(E_String2NumMapNodeArray *array); - -//- rjf: string -> expr -internal E_String2ExprMap e_string2expr_map_make(Arena *arena, U64 slot_count); -internal void e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr); -internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string); -internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string); -internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string); - -//////////////////////////////// -//~ rjf: Debug-Info-Driven Map Building Functions - -internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); -internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); - //////////////////////////////// //~ rjf: Tokenization Functions From 6113a2e3db186d7537c544bb1dd0d7dc5ecf44fb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 14:30:12 -0700 Subject: [PATCH 300/755] eval: do simplification pass over identifier resolution, shift from parsing stage -> ir generation / typechecking stage; do simplifications over expr tree, eliminate redundant kinds --- src/ctrl/ctrl_core.c | 21 +- src/eval/eval.mdesk | 2 - src/eval/eval_bundles.c | 2 +- src/eval/eval_ir.c | 717 +++++++++++++++- src/eval/eval_ir.h | 21 +- src/eval/eval_parse.c | 802 ++++-------------- src/eval/eval_parse.h | 20 +- src/eval/eval_types.h | 5 - src/eval/generated/eval.meta.c | 8 +- src/eval/generated/eval.meta.h | 6 +- .../eval_visualization_core.c | 2 +- src/lib_rdi_format/rdi_format_parse.c | 24 + src/lib_rdi_format/rdi_format_parse.h | 2 + src/raddbg/raddbg_core.c | 26 +- src/raddbg/raddbg_views.c | 2 +- 15 files changed, 942 insertions(+), 718 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 0c2316bf..e66e8af6 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4663,8 +4663,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) // rjf: build eval type context { E_TypeCtx *ctx = &scope->type_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -4675,10 +4673,15 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ProfScope("build eval parse context") { E_ParseCtx *ctx = &scope->parse_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->ip_thread_space.u64_0 = (U64)thread; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + } + e_select_parse_ctx(&scope->parse_ctx); + + // rjf: build eval IR context + { + E_IRCtx *ctx = &scope->ir_ctx; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -4686,12 +4689,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); - } - e_select_parse_ctx(&scope->parse_ctx); - - // rjf: build eval IR context - { - E_IRCtx *ctx = &scope->ir_ctx; ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(arena, 512); ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index b9a1d33c..976f691b 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -119,9 +119,7 @@ E_ExprKindTable: { Call Null 0 "(" "," ")"} { LeafBytecode Null 0 "" "" "" } - { LeafMember Null 0 "" "" "" } { LeafStringLiteral Null 0 "" "" "" } - { LeafBool Null 0 "" "" "" } { LeafU64 Null 0 "" "" "" } { LeafF64 Null 0 "" "" "" } { LeafF32 Null 0 "" "" "" } diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 11c8e68a..e14531e9 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -43,7 +43,7 @@ internal E_Eval e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); + E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); E_Eval eval = e_eval_from_exprs(arena, parse.exprs); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 24d2a320..3bdd069e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -58,12 +58,6 @@ e_expr_kind_is_comparison(E_ExprKind kind) //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_IRCtx * -e_selected_ir_ctx(void) -{ - return e_ir_state->ctx; -} - internal void e_select_ir_ctx(E_IRCtx *ctx) { @@ -75,9 +69,14 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - if(ctx->macro_map == 0) {ctx->macro_map = &e_string2expr_map_nil;} + 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 = &e_string2expr_map_nil;} e_ir_state->ctx = ctx; - e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); + e_ir_state->ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->ip_voff); + e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); e_ir_state->used_tag_map->slots_count = 64; e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); @@ -340,7 +339,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file) { String8 name = accel->fields.v[idx]; expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); rhs->string = push_str8_copy(arena, name); e_expr_push_child(expr, e_expr_ref(arena, lhs)); e_expr_push_child(expr, rhs); @@ -659,7 +658,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) { break; } - else if(exprr->kind != E_ExprKind_LeafMember) + else if(exprr->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); break; @@ -1320,7 +1319,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * if(params->type_pattern.size != 0) { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); - E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); + E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, tokens); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); type_key = irtree.type_key; } @@ -2470,12 +2469,6 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = expr->mode; }break; - //- rjf: (unexpected) leaf member - case E_ExprKind_LeafMember: - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "(internal) Leaf member not expected here."); - }break; - //- rjf: leaf string literal case E_ExprKind_LeafStringLiteral: { @@ -2487,14 +2480,6 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = E_Mode_Value; }break; - //- rjf: leaf bools - case E_ExprKind_LeafBool: - { - result.root = e_irtree_const_u(arena, expr->value.u64); - result.type_key = expr->type_key; - result.mode = E_Mode_Value; - }break; - //- rjf: leaf U64s case E_ExprKind_LeafU64: { @@ -2533,6 +2518,683 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf identifiers case E_ExprKind_LeafIdentifier: { + Temp scratch = scratch_begin(&arena, 1); + String8 qualifier = expr->qualifier; + String8 string = expr->string; + String8 string__redirected = string; + B32 string_mapped = 0; + E_TypeKey mapped_type_key = zero_struct; + E_Module *mapped_location_block_module = &e_module_nil; + RDI_LocationBlock *mapped_location_block = 0; + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_strings = {0}; + { + E_Module *module = e_ir_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->ip_procedure; + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); + str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try to map name as member - if found, string__redirected := "this", and turn + // on later implicit-member-lookup generation + B32 string_is_implicit_member_name = 0; + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) + { + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->ip_procedure; + RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); + E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); + E_Member member = e_type_member_from_key_name__cached(container_type_key, string); + if(member.kind != E_MemberKind_Null) + { + string_is_implicit_member_name = 1; + string__redirected = str8_lit("this"); + } + } + + //- rjf: try locals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) + { + U64 ip_voff = e_ir_state->ctx->ip_voff; + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); + if(local_num != 0) + { + RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); + + // rjf: extract local's type key + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); + + // rjf: extract local's location block + for(U32 loc_block_idx = local->location_first; + loc_block_idx < local->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) + { + mapped_location_block_module = module; + mapped_location_block = block; + } + } + } + } + + //- rjf: mapped to location block -> extract or produce bytecode for this mapping + E_Mode mapped_bytecode_mode = E_Mode_Offset; + E_Space mapped_bytecode_space = zero_struct; + String8 mapped_bytecode = {0}; + if(mapped_location_block != 0) + { + E_Module *module = mapped_location_block_module; + E_Space space = module->space; + Arch arch = module->arch; + RDI_Parsed *rdi = module->rdi; + RDI_LocationBlock *block = mapped_location_block; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{}break; + case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; + bytecode_stream:; + { + string_mapped = 1; + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + mapped_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_ValReg: + if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); + + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = space; + }break; + } + } + } + + //- rjf: generate IR trees for bytecode + B32 generated = 0; + if(!generated && mapped_bytecode.size != 0) + { + generated = 1; + E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); + root->space = mapped_bytecode_space; + result.root = root; + result.type_key = mapped_type_key; + result.mode = mapped_bytecode_mode; + } + + //- rjf: generate IR trees for macros + if(!generated) + { + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); + if(macro_expr != &e_expr_nil) + { + generated = 1; + e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); + result = e_irtree_and_type_from_expr(arena, macro_expr); + e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); + } + } + + //- rjf: error on failure-to-generate + if(!generated) + { + e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); + } + + //- TODO(rjf): +#if 0 + B32 mapped_identifier = 0; + B32 identifier_is_constant_value = 0; + B32 identifier_looks_like_type_expr = 0; + RDI_LocationKind loc_kind = RDI_LocationKind_NULL; + RDI_LocationReg loc_reg = {0}; + RDI_LocationRegPlusU16 loc_reg_u16 = {0}; + String8 loc_bytecode = {0}; + U64 constant_value = 0; + REGS_RegCode reg_code = 0; + REGS_AliasCode alias_code = 0; + E_TypeKey type_key = zero_struct; + String8 local_lookup_string = token_string; + E_Space space = {0}; + Arch arch = Arch_Null; + + + //- rjf: identifiers surrounded by ``s should have those `s stripped + if(local_lookup_string.size >= 2 && + local_lookup_string.str[0] == '`' && + local_lookup_string.str[local_lookup_string.size-1] == '`') + { + token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); + } + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_token_strings = {0}; + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); + str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try members + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") + { + U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); + if(data_member_num != 0) + { + atom_implicit_member_name = token_string; + local_lookup_string = str8_lit("this"); + } + } + + //- rjf: try locals + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); + if(local_num != 0) + { + RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); + + // rjf: grab location info + for(U32 loc_block_idx = local_var->location_first; + loc_block_idx < local_var->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) + { + mapped_identifier = 1; + space = module->space; + arch = module->arch; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{mapped_identifier = 0;}break; + case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; + bytecode_stream:; + { + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + loc_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); + }break; + case RDI_LocationKind_ValReg: + { + MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); + }break; + } + } + } + } + } + } + + //- rjf: try registers + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") + { + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); + if(reg_num != 0) + { + reg_code = reg_num; + type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try register aliases + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") + { + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); + if(alias_num != 0) + { + alias_code = (REGS_AliasCode)alias_num; + type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try global variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + // NOTE(rjf): apparently, PDBs can be produced such that they + // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I + // don't know of a magic hash table fixup path in PDBs, so + // in this case, I'm going to prefer the latest-added global. + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try thread variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try procedures + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + loc_kind = RDI_LocationKind_ValBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try types + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") + { + type_key = e_leaf_type_from_name(token_string); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + mapped_identifier = 1; + identifier_looks_like_type_expr = 1; + MemoryZeroStruct(&space); + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try basic constants + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 1; + } + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 0; + } + + //- rjf: attach on map + if(mapped_identifier != 0) ProfScope("attach on map") + { + it += 1; + + // rjf: build atom + switch(loc_kind) + { + default: + { + if(identifier_is_constant_value) + { + atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); + atom->value.u64 = constant_value; + atom->type_key = type_key; + } + else if(identifier_looks_like_type_expr) + { + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it-1, it_opl)); + E_Expr *type = type_parse.exprs.last; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + atom = type; + } + else if(reg_code != 0) + { + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else if(alias_code != 0) + { + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); + } + }break; + case RDI_LocationKind_AddrBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_ValBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_AddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + case RDI_LocationKind_ValReg: + { + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + } + + // rjf: implicit local lookup -> attach member access node + if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) + { + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); + member_expr->string = atom_implicit_member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); + atom->space = space; + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } + } + + //- rjf: map failure -> attach as leaf identifier, to be resolved later + if(!mapped_identifier) + { + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); + atom->string = token_string; + it += 1; + } + + + + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); if(macro_expr == &e_expr_nil) { @@ -2544,6 +3206,9 @@ E_IRGEN_FUNCTION_DEF(default) result = e_irtree_and_type_from_expr(arena, macro_expr); e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, expr->string); } +#endif + + scratch_end(scratch); }break; //- rjf: leaf offsets @@ -2933,7 +3598,7 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); rhs->string = push_str8_copy(arena, member_name); e_expr_push_child(root, lhs_bytecode); e_expr_push_child(root, rhs); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index b23023bc..adb12aa8 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -116,7 +116,24 @@ struct E_StringIDMap typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { + // rjf: instruction pointer info + U64 ip_vaddr; + U64 ip_voff; + E_Space ip_thread_space; + + // rjf: modules + E_Module *modules; + U64 modules_count; + E_Module *primary_module; + + // rjf: identifier-resolution maps + E_String2NumMap *regs_map; + E_String2NumMap *reg_alias_map; + E_String2NumMap *locals_map; // (within `primary_module`) + E_String2NumMap *member_map; // (within `primary_module`) E_String2ExprMap *macro_map; + + // rjf: hook maps E_LookupRuleMap *lookup_rule_map; E_IRGenRuleMap *irgen_rule_map; E_AutoHookMap *auto_hook_map; @@ -134,6 +151,9 @@ struct E_IRState // rjf: ir context E_IRCtx *ctx; + // rjf: unpacked ctx + RDI_Procedure *ip_procedure; + // rjf: caches E_UsedTagMap *used_tag_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; @@ -179,7 +199,6 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_IRCtx *e_selected_ir_ctx(void); internal void e_select_ir_ctx(E_IRCtx *ctx); //////////////////////////////// diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 352067e2..38386ed2 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -315,10 +315,6 @@ e_select_parse_ctx(E_ParseCtx *ctx) e_parse_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - 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->primary_module == 0){ ctx->primary_module = &e_module_nil; } e_parse_state->ctx = ctx; } @@ -537,7 +533,6 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) } }break; case E_ExprKind_LeafBytecode: - case E_ExprKind_LeafMember: case E_ExprKind_LeafIdentifier: { str8_list_push(arena, out, expr->string); @@ -547,7 +542,6 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) str8_list_pushf(arena, out, "\"%S\"", expr->string); }break; case E_ExprKind_LeafU64: - case E_ExprKind_LeafBool: { str8_list_pushf(arena, out, "%I64u", expr->value.u64); }break; @@ -771,15 +765,15 @@ e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, } internal E_Parse -e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) +e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) { E_Parse parse = {0, &e_expr_nil, &e_expr_nil}; - E_Token *token_it = tokens->v; + E_Token *token_it = tokens.v; //- rjf: parse unsigned marker B32 unsigned_marker = 0; { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind == E_TokenKind_Identifier) { String8 token_string = str8_substr(text, token.range); @@ -793,7 +787,7 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) //- rjf: parse base type { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind == E_TokenKind_Identifier) { String8 token_string = str8_substr(text, token.range); @@ -836,7 +830,7 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { for(;;) { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind != E_TokenKind_Symbol) { break; @@ -862,20 +856,24 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } internal E_Parse -e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count) +e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); - E_Token *it = tokens->v; - E_Token *it_opl = tokens->v + tokens->count; + E_Token *it = tokens.v; + E_Token *it_opl = tokens.v + tokens.count; E_Parse result = {0, &e_expr_nil, &e_expr_nil}; + ////////////////////////////// //- rjf: parse chain of expressions + // for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { + //////////////////////////// //- rjf: exit on symbols callers may be waiting on + // { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); if(token.kind == E_TokenKind_Symbol && (str8_match(token_string, str8_lit(")"), 0) || @@ -887,10 +885,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: skip commas, semicolons, etc. + // for(;it < it_opl;) { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); if(token.kind == E_TokenKind_Symbol && (str8_match(token_string, str8_lit(","), 0) || @@ -904,22 +904,24 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: parse prefix unaries - typedef struct PrefixUnaryNode PrefixUnaryNode; - struct PrefixUnaryNode + // + typedef struct PrefixUnaryTask PrefixUnaryTask; + struct PrefixUnaryTask { - PrefixUnaryNode *next; + PrefixUnaryTask *next; E_ExprKind kind; E_Expr *cast_expr; void *location; }; - PrefixUnaryNode *first_prefix_unary = 0; - PrefixUnaryNode *last_prefix_unary = 0; + PrefixUnaryTask *first_prefix_unary = 0; + PrefixUnaryTask *last_prefix_unary = 0; { for(;it < it_opl;) { E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; E_ExprKind prefix_unary_kind = 0; @@ -948,7 +950,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: try casting expression if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) { - E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); + E_Token some_type_identifier_maybe = e_token_at_it(it+1, &tokens); String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) { @@ -959,15 +961,14 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse type expr - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); E_Expr *type = type_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1002,7 +1003,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: push prefix unary if we got one { - PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); + PrefixUnaryTask *op_n = push_array(scratch.arena, PrefixUnaryTask, 1); op_n->kind = prefix_unary_kind; op_n->cast_expr = cast_expr; op_n->location = location; @@ -1011,44 +1012,49 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: parse atom + // E_Expr *atom = &e_expr_nil; String8 atom_implicit_member_name = {0}; if(it < it_opl) { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); - //- rjf: gather resolution qualifier + ////////////////////////// + //- rjf: consume resolution qualifiers + // String8 resolution_qualifier = {0}; if(token.kind == E_TokenKind_Identifier) { - E_Token next_token = e_token_at_it(it+1, tokens); + E_Token next_token = e_token_at_it(it+1, &tokens); String8 next_token_string = str8_substr(text, next_token.range); if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) { it += 2; resolution_qualifier = token_string; - token = e_token_at_it(it, tokens); + token = e_token_at_it(it, &tokens); token_string = str8_substr(text, token.range); } } - //- rjf: descent to nested expression + ////////////////////////// + //- rjf: descent to nested expression (...) + // if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { // rjf: skip ( it += 1; // rjf: parse () contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.exprs.last; it = nested_parse.last_token; // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1062,15 +1068,16 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: descent to assembly-style dereference sub-expression + ////////////////////////// + //- rjf: descent to assembly-style dereference sub-expression [...] + // else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) { // rjf: skip [ it += 1; // rjf: parse [] contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.exprs.last; it = nested_parse.last_token; @@ -1093,7 +1100,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } // rjf: expect ] - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) { @@ -1107,569 +1114,115 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: leaf (identifier, literal) - else if(token.kind != E_TokenKind_Symbol) + ////////////////////////// + //- rjf: leaf identifier + // + else if(token.kind == E_TokenKind_Identifier) { - switch(token.kind) + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); + atom->string = token_string; + it += 1; + } + + ////////////////////////// + //- rjf: leaf numeric + // + else if(token.kind == E_TokenKind_Numeric) + { + U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); + it += 1; + + // rjf: no . => integral + if(dot_pos == token_string.size) { - //- rjf: identifier => name resolution - default: - case E_TokenKind_Identifier: - { - B32 mapped_identifier = 0; - B32 identifier_is_constant_value = 0; - B32 identifier_type_is_possibly_dynamically_overridden = 0; - B32 identifier_looks_like_type_expr = 0; - RDI_LocationKind loc_kind = RDI_LocationKind_NULL; - RDI_LocationReg loc_reg = {0}; - RDI_LocationRegPlusU16 loc_reg_u16 = {0}; - String8 loc_bytecode = {0}; - U64 constant_value = 0; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - E_TypeKey type_key = zero_struct; - String8 local_lookup_string = token_string; - E_Space space = {0}; - Arch arch = Arch_Null; - - //- rjf: identifiers surrounded by ``s should have those `s stripped - if(local_lookup_string.size >= 2 && - local_lookup_string.str[0] == '`' && - local_lookup_string.str[local_lookup_string.size-1] == '`') - { - token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); - str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try members - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") - { - U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); - if(data_member_num != 0) - { - atom_implicit_member_name = token_string; - local_lookup_string = str8_lit("this"); - } - } - - //- rjf: try locals - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - identifier_type_is_possibly_dynamically_overridden = 1; - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); - - // rjf: grab location info - for(U32 loc_block_idx = local_var->location_first; - loc_block_idx < local_var->location_opl; - loc_block_idx += 1) - { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) - { - mapped_identifier = 1; - space = module->space; - arch = module->arch; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) - { - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) - { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; - { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) - { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) - { - break; - } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; - } - } - } - } - } - } - - //- rjf: try registers - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") - { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") - { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - // NOTE(rjf): apparently, PDBs can be produced such that they - // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I - // don't know of a magic hash table fixup path in PDBs, so - // in this case, I'm going to prefer the latest-added global. - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try procedures - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try types - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") - { - type_key = e_leaf_type_from_name(token_string); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - MemoryZeroStruct(&space); - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try basic constants - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 1; - } - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 0; - } - - //- rjf: attach on map - if(mapped_identifier != 0) ProfScope("attach on map") - { - it += 1; - - // rjf: build atom - switch(loc_kind) - { - default: - { - if(identifier_is_constant_value) - { - atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); - atom->value.u64 = constant_value; - atom->type_key = type_key; - } - else if(identifier_looks_like_type_expr) - { - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.exprs.last; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else if(alias_code != 0) - { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - } - - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) - { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); - member_expr->string = atom_implicit_member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); - atom->space = space; - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - } - - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) - { - atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); - atom->string = token_string; - it += 1; - } - }break; - - //- rjf: numeric => directly extract value - case E_TokenKind_Numeric: - { - U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); - it += 1; - - // rjf: no . => integral - if(dot_pos == token_string.size) - { - U64 val = 0; - try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = val; - break; - } - - // rjf: presence of . => double or float - if(dot_pos < token_string.size) - { - F64 val = f64_from_str8(token_string); - U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); - - // rjf: presence of f after . => f32 - if(f_pos < token_string.size) - { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); - atom->value.f32 = val; - } - - // rjf: no f => f64 - else - { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); - atom->value.f64 = val; - } - } - }break; - - //- rjf: char => extract char value - case E_TokenKind_CharLiteral: - { - it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') - { - String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); - String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); - U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = (U64)char_val; - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); - } - }break; - - //- rjf: string => leaf string literal, or file path - case E_TokenKind_StringLiteral: - { - if(str8_match(resolution_qualifier, str8_lit("file"), 0) || - str8_match(resolution_qualifier, str8_lit("folder"), 0)) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); - atom->string = string_value_raw; - it += 1; - } - else - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); - atom->string = string_value_raw; - it += 1; - } - }break; + U64 val = 0; + try_u64_from_str8_c_rules(token_string, &val); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = val; + break; } - //- rjf: upgrade atom w/ qualifier - if(atom != &e_expr_nil && resolution_qualifier.size != 0) + // rjf: presence of . => double or float + if(dot_pos < token_string.size) { - atom->qualifier = resolution_qualifier; + F64 val = f64_from_str8(token_string); + U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); + + // rjf: presence of f after . => f32 + if(f_pos < token_string.size) + { + atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); + atom->value.f32 = val; + } + + // rjf: no f => f64 + else + { + atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); + atom->value.f64 = val; + } } } + + ////////////////////////// + //- rjf: leaf char literal + // + else if(token.kind == E_TokenKind_CharLiteral) + { + it += 1; + if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + { + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = (U64)char_val; + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); + } + } + + ////////////////////////// + //- rjf: filesystem-qualified leaf string literal + // + else if(token.kind == E_TokenKind_StringLiteral && + (str8_match(resolution_qualifier, str8_lit("file"), 0) || + str8_match(resolution_qualifier, str8_lit("folder"), 0))) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); + atom->string = string_value_raw; + it += 1; + } + + ////////////////////////// + //- rjf: leaf string literal + // + else if(token.kind == E_TokenKind_StringLiteral) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); + atom->string = string_value_raw; + it += 1; + } + + //- rjf: upgrade atom w/ qualifier + if(atom != &e_expr_nil && resolution_qualifier.size != 0) + { + atom->qualifier = resolution_qualifier; + } } + //////////////////////////// //- rjf: upgrade atom w/ postfix unaries + // if(atom != &e_expr_nil) for(;it < it_opl;) { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); B32 is_postfix_unary = 0; @@ -1687,7 +1240,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to String8 member_name = {0}; B32 good_member_name = 0; { - E_Token member_name_maybe = e_token_at_it(it, tokens); + E_Token member_name_maybe = e_token_at_it(it, &tokens); String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); if(member_name_maybe.kind != E_TokenKind_Identifier) { @@ -1704,7 +1257,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(good_member_name) { E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name.str); member_expr->string = member_name; atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); e_expr_push_child(atom, member_container); @@ -1728,8 +1281,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse indexing expression - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence, 1); + E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); it = idx_expr_parse.last_token; @@ -1745,7 +1297,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: expect ] { - E_Token close_brace_maybe = e_token_at_it(it, tokens); + E_Token close_brace_maybe = e_token_at_it(it, &tokens); String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) { @@ -1770,8 +1322,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); call_expr->string = callee_expr->string; e_expr_push_child(call_expr, callee_expr); - E_TokenArray args_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); + E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; if(args_parse.exprs.first != &e_expr_nil) @@ -1784,7 +1335,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: expect ) { - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1804,11 +1355,21 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: upgrade atom w/ previously parsed prefix unaries + //////////////////////////// + //- rjf: no `atom`, but we have a cast expression? -> just evaluate the type as the atom + // if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) { atom = first_prefix_unary->cast_expr; - for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; + first_prefix_unary = first_prefix_unary->next; + } + + //////////////////////////// + //- rjf: upgrade `atom` w/ previously parsed prefix unaries + // + if(atom != &e_expr_nil) + { + for(PrefixUnaryTask *prefix_unary = first_prefix_unary; prefix_unary != 0; prefix_unary = prefix_unary->next) { @@ -1821,31 +1382,18 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to e_expr_push_child(atom, rhs); } } - else if(atom == &e_expr_nil && first_prefix_unary != 0) + else if(first_prefix_unary != 0) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); } - else - { - for(PrefixUnaryNode *prefix_unary = first_prefix_unary; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - //- rjf: parse complex operators + //////////////////////////// + //- rjf: parse complex operators to further extend `atom` + // if(atom != &e_expr_nil) for(;it < it_opl;) { E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); //- rjf: parse binaries @@ -1869,8 +1417,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // precedence if(binary_precedence != 0 && binary_precedence <= max_precedence) { - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1, 1); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.exprs.last; it = rhs_expr_parse.last_token; @@ -1895,8 +1442,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse middle expression - E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence, 1); + E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); it = middle_expr_parse.last_token; E_Expr *middle_expr = middle_expr_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); @@ -1910,7 +1456,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Token colon_token = zero_struct; String8 colon_token_string = {0}; { - E_Token colon_token_maybe = e_token_at_it(it, tokens); + E_Token colon_token_maybe = e_token_at_it(it, &tokens); String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) { @@ -1926,8 +1472,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } // rjf: parse rhs - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence, 1); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); if(got_colon) { it = rhs_expr_parse.last_token; @@ -1959,8 +1504,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) { it += 1; - E_TokenArray tags_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, &tags_tokens, e_max_precedence, max_U64); + E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); it = tags_parse.last_token; for(E_Expr *tag = tags_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) @@ -1998,7 +1542,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } internal E_Parse -e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) +e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) { ProfBegin("parse '%.*s'", str8_varg(text)); E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); @@ -2011,7 +1555,7 @@ e_parse_expr_from_text(Arena *arena, String8 text) { Temp scratch = scratch_begin(&arena, 1); E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); - E_Parse parse = e_parse_expr_from_text_tokens(arena, text, &tokens); + E_Parse parse = e_parse_expr_from_text_tokens(arena, text, tokens); scratch_end(scratch); return parse; } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index a251ec3c..a414f01b 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -21,21 +21,9 @@ struct E_Parse typedef struct E_ParseCtx E_ParseCtx; struct E_ParseCtx { - // rjf: instruction pointer info - U64 ip_vaddr; - U64 ip_voff; - E_Space ip_thread_space; - - // rjf: modules E_Module *modules; U64 modules_count; E_Module *primary_module; - - // rjf: local identifier resolution maps - E_String2NumMap *regs_map; - E_String2NumMap *reg_alias_map; - E_String2NumMap *locals_map; // (within `rdis[rdis_primary_idx]`) - E_String2NumMap *member_map; // (within `rdis[rdis_primary_idx]`) }; //////////////////////////////// @@ -60,7 +48,7 @@ thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// //~ rjf: Tokenization Functions -#define e_token_at_it(it, arr) (((it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero()) +#define e_token_at_it(it, arr) (((arr)->v <= (it) && (it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero()) internal E_Token e_token_zero(void); internal void e_token_chunk_list_push(Arena *arena, E_TokenChunkList *list, U64 chunk_size, E_Token *token); internal E_TokenArray e_token_array_from_chunk_list(Arena *arena, E_TokenChunkList *list); @@ -100,9 +88,9 @@ internal String8 e_string_from_expr(Arena *arena, E_Expr *expr); internal E_TypeKey e_leaf_type_from_name(String8 name); internal E_TypeKey e_type_from_expr(E_Expr *expr); internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); -internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); -internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); +internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); +internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); +internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 1801164b..045dd158 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -137,11 +137,6 @@ struct E_MemberCacheSlot typedef struct E_TypeCtx E_TypeCtx; struct E_TypeCtx { - // rjf: instruction pointer info - U64 ip_vaddr; - U64 ip_voff; // (within `primary_module`) - - // rjf: debug info E_Module *modules; U64 modules_count; E_Module *primary_module; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index cb7cdfea..14af0ad1 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -134,7 +134,7 @@ U8 e_type_kind_basic_byte_size_table[56] = 0, }; -String8 e_expr_kind_strings[51] = +String8 e_expr_kind_strings[49] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -171,9 +171,7 @@ str8_lit_comp("LogOr"), str8_lit_comp("Ternary"), str8_lit_comp("Call"), str8_lit_comp("LeafBytecode"), -str8_lit_comp("LeafMember"), str8_lit_comp("LeafStringLiteral"), -str8_lit_comp("LeafBool"), str8_lit_comp("LeafU64"), str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), @@ -189,7 +187,7 @@ str8_lit_comp("Define"), str8_lit_comp("Tag"), }; -E_OpInfo e_expr_kind_op_info_table[51] = +E_OpInfo e_expr_kind_op_info_table[49] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -238,8 +236,6 @@ E_OpInfo e_expr_kind_op_info_table[51] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 5bb4994c..5ccfe7e1 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -126,9 +126,7 @@ E_ExprKind_LogOr, E_ExprKind_Ternary, E_ExprKind_Call, E_ExprKind_LeafBytecode, -E_ExprKind_LeafMember, E_ExprKind_LeafStringLiteral, -E_ExprKind_LeafBool, E_ExprKind_LeafU64, E_ExprKind_LeafF64, E_ExprKind_LeafF32, @@ -165,8 +163,8 @@ C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; extern String8 e_type_kind_basic_string_table[56]; extern U8 e_type_kind_basic_byte_size_table[56]; -extern String8 e_expr_kind_strings[51]; -extern E_OpInfo e_expr_kind_op_info_table[51]; +extern String8 e_expr_kind_strings[49]; +extern E_OpInfo e_expr_kind_op_info_table[49]; extern String8 e_interpretation_code_display_strings[11]; C_LINKAGE_END diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 7383b24d..7ceb35c3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -519,7 +519,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key // rjf: push explicitly-attached tags (via key) next String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, tag_expr_tokens); for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { next = tag->next; diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index f099ec6c..3439589e 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -586,6 +586,30 @@ rdi_root_scope_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) return scope; } +RDI_PROC RDI_UDT * +rdi_container_udt_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) +{ + RDI_U64 idx = 0; + if(procedure->link_flags & RDI_LinkFlag_TypeScoped) + { + idx = procedure->container_idx; + } + RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, idx); + return udt; +} + +RDI_PROC RDI_Procedure * +rdi_container_procedure_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) +{ + RDI_U64 idx = 0; + if(procedure->link_flags & RDI_LinkFlag_ProcScoped) + { + idx = procedure->container_idx; + } + RDI_Procedure *container_procedure = rdi_element_from_name_idx(rdi, Procedures, idx); + return container_procedure; +} + RDI_PROC RDI_U64 rdi_first_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) { diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 59cedfa5..4d3e40b4 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -182,6 +182,8 @@ RDI_PROC RDI_Procedure *rdi_procedure_from_name(RDI_Parsed *rdi, RDI_U8 *name, R RDI_PROC RDI_Procedure *rdi_procedure_from_name_cstr(RDI_Parsed *rdi, char *cstr); RDI_PROC RDI_U8 *rdi_name_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure, RDI_U64 *len_out); RDI_PROC RDI_Scope *rdi_root_scope_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); +RDI_PROC RDI_UDT *rdi_container_udt_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); +RDI_PROC RDI_Procedure *rdi_container_procedure_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_U64 rdi_first_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_U64 rdi_opl_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_Procedure *rdi_procedure_from_voff(RDI_Parsed *rdi, RDI_U64 voff); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e8be644f..eb543367 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -196,7 +196,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(locals) E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); e_string2num_map_node_array_sort__in_place(&nodes); String8List exprs_filtered = {0}; for EachIndex(idx, nodes.count) @@ -11873,7 +11873,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, string); + U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -11884,7 +11884,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_parse_state->ctx->member_map, string); + U64 member_num = e_num_from_string(e_ir_state->ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -11895,7 +11895,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -11906,7 +11906,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -13479,8 +13479,6 @@ rd_frame(void) ProfScope("build eval type context") { E_TypeCtx *ctx = type_ctx; - ctx->ip_vaddr = rip_vaddr; - ctx->ip_voff = rip_voff; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -13494,16 +13492,9 @@ rd_frame(void) ProfScope("build eval parse context") { E_ParseCtx *ctx = parse_ctx; - ctx->ip_vaddr = rip_vaddr; - ctx->ip_voff = rip_voff; - ctx->ip_thread_space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_CtrlEntity); ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; - ctx->regs_map = ctrl_string2reg_from_arch(ctx->primary_module->arch); - ctx->reg_alias_map = ctrl_string2alias_from_arch(ctx->primary_module->arch); - ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); - ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); } e_select_parse_ctx(parse_ctx); @@ -13514,6 +13505,13 @@ rd_frame(void) if(e_ir_state != 0) { e_ir_state->ctx = 0; } { E_IRCtx *ctx = ir_ctx; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + ctx->regs_map = ctrl_string2reg_from_arch(ctx->primary_module->arch); + ctx->reg_alias_map = ctrl_string2alias_from_arch(ctx->primary_module->arch); + ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); + ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8cdfb900..0b33bad5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2501,7 +2501,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_parse_state->ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_ir_state->ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); From 9146594ff986e69eceb850aafffc466d0218c31d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 14:39:38 -0700 Subject: [PATCH 301/755] eval: global name resolution in new ir-stage name resolution path --- src/eval/eval_ir.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 3bdd069e..ac7d4334 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2699,6 +2699,45 @@ E_IRGEN_FUNCTION_DEF(default) } } + //- rjf: try globals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + //- rjf: generate IR trees for bytecode B32 generated = 0; if(!generated && mapped_bytecode.size != 0) From 33de6253739c88a788403887c49b80aad1cb55a5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 14:56:53 -0700 Subject: [PATCH 302/755] eval: register, register alias name mapping in new name resolution pass --- src/ctrl/ctrl_core.c | 4 ++++ src/eval/eval_ir.c | 43 ++++++++++++++++++++++++++++++++++++---- src/eval/eval_ir.h | 8 ++++---- src/raddbg/raddbg_core.c | 3 +++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e66e8af6..846e1720 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4682,6 +4682,10 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) // rjf: build eval IR context { E_IRCtx *ctx = &scope->ir_ctx; + ctx->thread_ip_vaddr = thread_rip_vaddr; + ctx->thread_ip_voff = thread_rip_voff; + ctx->thread_reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); + ctx->thread_reg_space.u64_0 = (U64)thread; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ac7d4334..d9b26413 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -75,7 +75,7 @@ e_select_ir_ctx(E_IRCtx *ctx) if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; } if(ctx->macro_map == 0) {ctx->macro_map = &e_string2expr_map_nil;} e_ir_state->ctx = ctx; - e_ir_state->ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->ip_voff); + e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->thread_ip_voff); e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); e_ir_state->used_tag_map->slots_count = 64; e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); @@ -2532,7 +2532,7 @@ E_IRGEN_FUNCTION_DEF(default) { E_Module *module = e_ir_state->ctx->primary_module; RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->ip_procedure; + RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; U64 name_size = 0; U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); String8 containing_procedure_name = str8(name_ptr, name_size); @@ -2561,7 +2561,7 @@ E_IRGEN_FUNCTION_DEF(default) E_Module *module = e_ir_state->ctx->primary_module; U32 module_idx = (U32)(module - e_ir_state->ctx->modules); RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->ip_procedure; + RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); @@ -2576,7 +2576,6 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: try locals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) { - U64 ip_voff = e_ir_state->ctx->ip_voff; E_Module *module = e_ir_state->ctx->primary_module; U32 module_idx = (U32)(module - e_ir_state->ctx->modules); RDI_Parsed *rdi = module->rdi; @@ -2590,6 +2589,7 @@ E_IRGEN_FUNCTION_DEF(default) mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); // rjf: extract local's location block + U64 ip_voff = e_ir_state->ctx->thread_ip_voff; for(U32 loc_block_idx = local->location_first; loc_block_idx < local->location_opl; loc_block_idx += 1) @@ -2738,6 +2738,41 @@ E_IRGEN_FUNCTION_DEF(default) } } + //- rjf: try registers + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + if(reg_num != 0) + { + string_mapped = 1; + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_num]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; + mapped_type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_num); + } + } + + //- rjf: try register aliases + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + if(alias_num != 0) + { + string_mapped = 1; + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_num]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; + mapped_type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_num); + } + } + //- rjf: generate IR trees for bytecode B32 generated = 0; if(!generated && mapped_bytecode.size != 0) diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index adb12aa8..8f4b6df3 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -117,9 +117,9 @@ typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { // rjf: instruction pointer info - U64 ip_vaddr; - U64 ip_voff; - E_Space ip_thread_space; + U64 thread_ip_vaddr; + U64 thread_ip_voff; + E_Space thread_reg_space; // rjf: modules E_Module *modules; @@ -152,7 +152,7 @@ struct E_IRState E_IRCtx *ctx; // rjf: unpacked ctx - RDI_Procedure *ip_procedure; + RDI_Procedure *thread_ip_procedure; // rjf: caches E_UsedTagMap *used_tag_map; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index eb543367..c9b0870c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13505,6 +13505,9 @@ rd_frame(void) if(e_ir_state != 0) { e_ir_state->ctx = 0; } { E_IRCtx *ctx = ir_ctx; + ctx->thread_ip_voff = rip_voff; + ctx->thread_ip_vaddr = rip_vaddr; + ctx->thread_reg_space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_CtrlEntity); ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; From 9bf69afd0bb200455a1790aa580e0315fde731fd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 15:07:35 -0700 Subject: [PATCH 303/755] eval: procedure, type, thread-variable name mapping; sketch out implicit member access path --- src/eval/eval_ir.c | 609 ++++++++++----------------------------------- 1 file changed, 131 insertions(+), 478 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index d9b26413..e8e16562 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2738,6 +2738,96 @@ E_IRGEN_FUNCTION_DEF(default) } } + //- rjf: try thread-locals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try procedures + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try types + if(!string_mapped == 0 && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) + { + mapped_type_key = e_leaf_type_from_name(string); + if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) + { + string_mapped = 1; + } + } + //- rjf: try registers if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) { @@ -2773,6 +2863,26 @@ E_IRGEN_FUNCTION_DEF(default) } } + //- rjf: try basic constants + if(!string_mapped && str8_match(string, str8_lit("true"), 0)) + { + string_mapped = 1; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, 1); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + } + if(!string_mapped && str8_match(string, str8_lit("false"), 0)) + { + string_mapped = 1; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, 0); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + } + //- rjf: generate IR trees for bytecode B32 generated = 0; if(!generated && mapped_bytecode.size != 0) @@ -2785,6 +2895,14 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = mapped_bytecode_mode; } + //- rjf: generate nil-IR trees w/ type for types + if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) + { + generated = 1; + result.type_key = mapped_type_key; + result.mode = E_Mode_Null; + } + //- rjf: generate IR trees for macros if(!generated) { @@ -2798,490 +2916,25 @@ E_IRGEN_FUNCTION_DEF(default) } } + //- rjf: extend generation with member access, if original string was an + // implicit member access + if(generated && string_is_implicit_member_name) + { + // TODO(rjf): @cfg +#if 0 + E_LookupRule *lookup_rule = &e_lookup_rule__default; + E_LookupInfo lookup_info = lookup_rule->info(arena, &result, &e_expr_nil, str8_zero()); + E_LookupAccess lookup_access = lookup_rule->access(arena, E_ExprKind_MemberAccess, lhs, rhs, &e_expr_nil, lookup_info.user_data); + result = lookup_access.irtree_and_type; +#endif + } + //- rjf: error on failure-to-generate if(!generated) { e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); } - //- TODO(rjf): -#if 0 - B32 mapped_identifier = 0; - B32 identifier_is_constant_value = 0; - B32 identifier_looks_like_type_expr = 0; - RDI_LocationKind loc_kind = RDI_LocationKind_NULL; - RDI_LocationReg loc_reg = {0}; - RDI_LocationRegPlusU16 loc_reg_u16 = {0}; - String8 loc_bytecode = {0}; - U64 constant_value = 0; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - E_TypeKey type_key = zero_struct; - String8 local_lookup_string = token_string; - E_Space space = {0}; - Arch arch = Arch_Null; - - - //- rjf: identifiers surrounded by ``s should have those `s stripped - if(local_lookup_string.size >= 2 && - local_lookup_string.str[0] == '`' && - local_lookup_string.str[local_lookup_string.size-1] == '`') - { - token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); - str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try members - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") - { - U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); - if(data_member_num != 0) - { - atom_implicit_member_name = token_string; - local_lookup_string = str8_lit("this"); - } - } - - //- rjf: try locals - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); - - // rjf: grab location info - for(U32 loc_block_idx = local_var->location_first; - loc_block_idx < local_var->location_opl; - loc_block_idx += 1) - { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) - { - mapped_identifier = 1; - space = module->space; - arch = module->arch; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) - { - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) - { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; - { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) - { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) - { - break; - } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; - } - } - } - } - } - } - - //- rjf: try registers - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") - { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") - { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - // NOTE(rjf): apparently, PDBs can be produced such that they - // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I - // don't know of a magic hash table fixup path in PDBs, so - // in this case, I'm going to prefer the latest-added global. - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try procedures - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try types - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") - { - type_key = e_leaf_type_from_name(token_string); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - MemoryZeroStruct(&space); - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try basic constants - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 1; - } - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 0; - } - - //- rjf: attach on map - if(mapped_identifier != 0) ProfScope("attach on map") - { - it += 1; - - // rjf: build atom - switch(loc_kind) - { - default: - { - if(identifier_is_constant_value) - { - atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); - atom->value.u64 = constant_value; - atom->type_key = type_key; - } - else if(identifier_looks_like_type_expr) - { - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it-1, it_opl)); - E_Expr *type = type_parse.exprs.last; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else if(alias_code != 0) - { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - } - - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) - { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); - member_expr->string = atom_implicit_member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); - atom->space = space; - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - } - - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) - { - atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); - atom->string = token_string; - it += 1; - } - - - - - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); - if(macro_expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", expr->string); - } - else - { - e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, expr->string); - result = e_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, expr->string); - } -#endif - scratch_end(scratch); }break; From c6add5f8f068855827feb32e46bf2fd562b432ef Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 15:12:32 -0700 Subject: [PATCH 304/755] fix incorrect type name short-circuit check --- src/eval/eval_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e8e16562..7f34255a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2819,7 +2819,7 @@ E_IRGEN_FUNCTION_DEF(default) } //- rjf: try types - if(!string_mapped == 0 && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) { mapped_type_key = e_leaf_type_from_name(string); if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) From 95df14bc20d57f633cc46f063888fc064f30ef72 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 15:25:14 -0700 Subject: [PATCH 305/755] eliminate old short-circuit from leaf-numeric expr tree generation path --- src/eval/eval_parse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 38386ed2..691f3f39 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1139,7 +1139,6 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok try_u64_from_str8_c_rules(token_string, &val); atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); atom->value.u64 = val; - break; } // rjf: presence of . => double or float From ca7f20e3945bf378ff486923da231339b63a4849 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 2 Apr 2025 15:55:50 -0700 Subject: [PATCH 306/755] detect window resizes as a layout-reset correctly --- src/raddbg/raddbg_core.c | 7 +++++-- src/raddbg/raddbg_core.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c9b0870c..158d288d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9094,6 +9094,8 @@ rd_window_frame(void) //- rjf: @window_ui_part animate panels // { + B32 window_is_resizing = (ws->last_window_rect.x1 != window_rect.x1 || + ws->last_window_rect.y1 != window_rect.y1); Vec2F32 content_rect_dim = dim_2f32(content_rect); if(content_rect_dim.x > 0 && content_rect_dim.y > 0) { @@ -9106,7 +9108,7 @@ rd_window_frame(void) target_rect_px.y0/content_rect_dim.y, target_rect_px.x1/content_rect_dim.x, target_rect_px.y1/content_rect_dim.y); - B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); + B32 reset = (window_is_resizing || ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset); ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset); @@ -10387,9 +10389,10 @@ rd_window_frame(void) } ////////////////////////////// - //- rjf: @window_frame_part increment per-window frame counter + //- rjf: @window_frame_part update per-window frame counters/info // ws->frames_alive += 1; + ws->last_window_rect = os_client_rect_from_window(ws->os); ProfEnd(); scratch_end(scratch); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 568cdcb8..855445f8 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -527,6 +527,7 @@ struct RD_WindowState F32 last_dpi; B32 window_temporarily_focused_ipc; B32 window_layout_reset; + Rng2F32 last_window_rect; // rjf: theme (recomputed each frame) UI_Theme *theme; From 02885b0b86ab67dccffb3f31ad9d2b93a10fbfe5 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 2 Apr 2025 22:48:32 -0700 Subject: [PATCH 307/755] dedup manifest inputs --- src/linker/hash_table.c | 20 ++++++++++++++++++++ src/linker/hash_table.h | 3 ++- src/linker/lnk.c | 17 +++++++++++------ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index eaf0f95c..1f1ed5ec 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -356,3 +356,23 @@ remove_duplicates_u64_array(Arena *arena, U64Array arr) scratch_end(scratch); return result; } + +internal String8List +remove_duplicates_str8_list(Arena *arena, String8List list) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8List result = {0}; + HashTable *ht = hash_table_init(scratch.arena, list.node_count); + + for (String8Node *node = list.first; node != 0; node = node->next) { + KeyValuePair *is_present = hash_table_search_string(ht, node->string); + if (!is_present) { + hash_table_push_string_raw(scratch.arena, ht, node->string, 0); + str8_list_push(arena, &result, node->string); + } + } + + scratch_end(scratch); + return result; +} diff --git a/src/linker/hash_table.h b/src/linker/hash_table.h index 20163a17..b35c9fcf 100644 --- a/src/linker/hash_table.h +++ b/src/linker/hash_table.h @@ -86,5 +86,6 @@ internal void sort_key_value_pairs_as_u64(KeyValuePair *pairs, U64 count); //////////////////////////////// -internal U64Array remove_duplicates_u64_array(Arena *arena, U64Array arr); +internal U64Array remove_duplicates_u64_array(Arena *arena, U64Array arr); +internal String8List remove_duplicates_str8_list(Arena *arena, String8List list); diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 2283b570..461a28a5 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -346,24 +346,29 @@ lnk_manifest_from_inputs(Arena *arena, String8List input_manifest_path_list, String8List deps_list) { + Temp scratch = scratch_begin(&arena, 1); + + String8List unique_deps = remove_duplicates_str8_list(scratch.arena, deps_list); + String8 manifest_data; if (input_manifest_path_list.node_count > 0) { ProfBegin("Merge Manifests"); - Temp scratch = scratch_begin(&arena, 1); - String8 linker_manifest = lnk_make_linker_manifest(scratch.arena, manifest_uac, manifest_level, manifest_ui_access, deps_list); + String8 linker_manifest = lnk_make_linker_manifest(scratch.arena, manifest_uac, manifest_level, manifest_ui_access, unique_deps); // write linker manifest to temp file String8 linker_manifest_path = push_str8f(scratch.arena, "%S.manifest.temp", manifest_name); lnk_write_data_to_file_path(linker_manifest_path, str8_zero(), linker_manifest); + String8List unique_input_manifest_paths = remove_duplicates_str8_list(scratch.arena, input_manifest_path_list); + // push linker manifest - str8_list_push(scratch.arena, &input_manifest_path_list, linker_manifest_path); + str8_list_push(scratch.arena, &unique_input_manifest_paths, linker_manifest_path); // launch mt.exe to merge input manifests String8 merged_manifest_path = push_str8f(scratch.arena, "%S.manifest.merged", manifest_name); - lnk_merge_manifest_files(mt_path, merged_manifest_path, input_manifest_path_list); + lnk_merge_manifest_files(mt_path, merged_manifest_path, unique_input_manifest_paths); // read mt.exe output from disk manifest_data = lnk_read_data_from_file_path(arena, merged_manifest_path); @@ -375,12 +380,12 @@ lnk_manifest_from_inputs(Arena *arena, os_delete_file_at_path(linker_manifest_path); os_delete_file_at_path(merged_manifest_path); - scratch_end(scratch); ProfEnd(); } else { - manifest_data = lnk_make_linker_manifest(arena, manifest_uac, manifest_level, manifest_ui_access, deps_list); + manifest_data = lnk_make_linker_manifest(arena, manifest_uac, manifest_level, manifest_ui_access, unique_deps); } + scratch_end(scratch); return manifest_data; } From c6ba47542714aea6adc58f6d51ea4429c06a0d0c Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 2 Apr 2025 11:14:33 -0700 Subject: [PATCH 308/755] produce image layout map --- src/linker/lnk.c | 178 +++++++++++++++++++++++++++++++++++++++- src/linker/lnk_chunk.h | 3 +- src/linker/lnk_config.c | 13 ++- src/linker/lnk_config.h | 4 + src/linker/lnk_obj.c | 5 ++ 5 files changed, 198 insertions(+), 5 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 461a28a5..6c2bc7ec 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -3139,6 +3139,169 @@ LNK_CHUNK_VISITOR_SIG(lnk_max_tls_align) return 0; } +global LNK_Section **g_rad_sort_sect_id_map = 0; + +typedef struct +{ + U64 off; + LNK_Chunk *chunk; +} LNK_ChunkOffPair; + +internal int +lnk_map_sort_on_chunk_file_off(void *raw_a, void *raw_b) +{ + LNK_Chunk **a = raw_a; + LNK_Chunk **b = raw_b; + + U64 a_file_off = lnk_virt_off_from_chunk_ref(g_rad_sort_sect_id_map, (*a)->ref); + U64 b_file_off = lnk_virt_off_from_chunk_ref(g_rad_sort_sect_id_map, (*b)->ref); + + int is_before = a_file_off < b_file_off; + return is_before; +} + +internal int +lnk_map_sort_on_chunk_off(void *raw_a, void *raw_b) +{ + LNK_ChunkOffPair *a = raw_a; + LNK_ChunkOffPair *b = raw_b; + + int is_before = a->off < b->off; + return is_before; +} + +internal U64 +lnk_chunk_off_pair_array_bsearch(LNK_ChunkOffPair *arr, U64 count, U64 value) +{ + if(count > 1 && arr[0].off <= value && value < arr[count-1].off) + { + U64 l = 0; + U64 r = count - 1; + for(; l <= r; ) + { + U64 m = l + (r - l) / 2; + if(arr[m].off == value) + { + return m; + } + else if(arr[m].off < value) + { + l = m + 1; + } + else + { + r = m - 1; + } + } + } + else if (count == 1 && arr[0].off == value) + { + return 0; + } + return max_U64; +} + +internal String8List +lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ObjList objs, LNK_SectionTable *st, LNK_SymbolTable *symtab) +{ + Temp scratch = scratch_begin(&arena, 1); + + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + + String8List map = {0}; + + str8_list_pushf(arena, &map, "# CHUNKS\n"); + for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) { + LNK_Section *sect = §_n->data; + if (sect->has_layout) { + LNK_Chunk **chunks = push_array_no_zero(scratch.arena, LNK_Chunk *, sect->layout.total_count); + MemoryCopyTyped(chunks, sect->layout.chunk_ptr_array, sect->layout.total_count); + + g_rad_sort_sect_id_map = sect_id_map; + radsort(chunks, sect->layout.total_count, lnk_map_sort_on_chunk_file_off); + + str8_list_pushf(arena, &map, "%S\n", sect->name); + str8_list_pushf(arena, &map, "%-16s %-8s %-8s %-16s %-8s %s\n", "Sect:Offset", "VirtSize", "FileSize", "Blake3", "ChunkRef", "Source"); + for (U64 chunk_idx = 0; chunk_idx < sect->layout.total_count; ++chunk_idx) { + LNK_Chunk *chunk = chunks[chunk_idx]; + if (chunk->type == LNK_Chunk_Leaf && chunk != g_null_chunk_ptr) { + Temp temp = temp_begin(scratch.arena); + + ISectOff sc = lnk_sc_from_chunk_ref(sect_id_map, chunk->ref); + U64 virt_size = lnk_virt_size_from_chunk_ref(sect_id_map, chunk->ref); + U64 file_size = lnk_file_size_from_chunk_ref(sect_id_map, chunk->ref); + String8 chunk_data = lnk_data_from_chunk_ref(sect_id_map, image_data, chunk->ref); + + U128 chunk_hash = {0}; + if (~sect->flags & COFF_SectionFlag_CntUninitializedData) { + blake3_hasher hasher; blake3_hasher_init(&hasher); + blake3_hasher_update(&hasher, chunk_data.str, chunk_data.size); + blake3_hasher_finalize(&hasher, (U8 *)&chunk_hash, sizeof(chunk_hash)); + } + + String8 address_str = push_str8f(temp.arena, "%04x:%08x", sc.isect, sc.off); + String8 virt_size_str = push_str8f(temp.arena, "%08x", virt_size); + String8 file_size_str = push_str8f(temp.arena, "%08x", file_size); + String8 chunk_hash_str = push_str8f(temp.arena, "%08x%08x", chunk_hash.u64[0], chunk_hash.u64[1]); + String8 chunk_ref_str = push_str8f(temp.arena, "{%llx,%llx}", chunk->ref.sect_id, chunk->ref.chunk_id); + String8 source_str = str8_lit("\?\?\?"); + if (chunk->obj) { + if (chunk->obj->lib_path.size) { + String8 lib_name = chunk->obj->lib_path; + lib_name = str8_skip_last_slash(lib_name); + lib_name = str8_chop_last_dot(lib_name); + + String8 obj_name = chunk->obj->path; + obj_name = str8_skip_last_slash(obj_name); + + source_str = push_str8f(temp.arena, "%S:%S", lib_name, obj_name); + } else { + source_str = push_str8f(temp.arena, "%S", chunk->obj->path); + } + } + + str8_list_pushf(arena, &map, "%-16S %-8S %-8S %-16S %-8S %S\n", address_str, virt_size_str, file_size_str, chunk_hash_str, chunk_ref_str, source_str); + + temp_end(temp); + } + } + str8_list_pushf(arena, &map, "\n"); + } + } + + str8_list_pushf(arena, &map, "# SYMBOLS\n"); + str8_list_pushf(arena, &map, "%-8s %s\n", "ChunkRef", "Symbol"); + for (LNK_ObjNode *obj_n = objs.first; obj_n != 0; obj_n = obj_n->next) { + LNK_Obj *obj = &obj_n->data; + for (LNK_SymbolNode *symbol_n = obj->symbol_list.first; symbol_n != 0; symbol_n = symbol_n->next) { + LNK_Symbol *symbol = symbol_n->data; + if (LNK_Symbol_IsDefined(symbol->type)) { + if (symbol->u.defined.value_type == LNK_DefinedSymbolValue_Chunk) { + LNK_Chunk *chunk = symbol->u.defined.u.chunk; + String8 chunk_ref_str = push_str8f(scratch.arena, "{%llx,%llx}", chunk->ref.sect_id, chunk->ref.chunk_id); + + String8 lib_name = obj->lib_path; + lib_name = str8_skip_last_slash(lib_name); + lib_name = str8_chop_last_dot(lib_name); + + String8 obj_name = obj->path; + obj_name = str8_skip_last_slash(obj_name); + + str8_list_pushf(arena, &map, "%-8S (%S%s%S) %S\n", + chunk_ref_str, + lib_name, lib_name.size ? ":" : "", obj_name, + symbol->name); + } + } + } + } + + //str8_list_pushf(arena, &map, "%16s %30s %23s %10s\n\n", "Address", "Publics by Value", "Rva+Base", "Lib:Object"); + + scratch_end(scratch); + return map; +} + internal void lnk_run(int argc, char **argv) { @@ -3167,6 +3330,7 @@ lnk_run(int argc, char **argv) State_BuildBaseRelocs, State_FinalizeImage, State_BuildImpLib, + State_BuildRadChunkMap, State_BuildDebugInfo, }; struct StateNode { @@ -3254,10 +3418,11 @@ lnk_run(int argc, char **argv) B32 report_unresolved_symbols = 1; B32 check_unused_delay_loads = !!(config->flags & LNK_ConfigFlag_CheckUnusedDelayLoadDll); B32 build_imp_lib = config->build_imp_lib; + B32 build_rad_chunk_map = (config->rad_chunk_map == LNK_SwitchState_Yes); LNK_ObjList obj_list = {0}; LNK_LibList lib_index[LNK_InputSource_Count] = {0}; String8 image_data = str8_zero(); - OS_Handle image_write_thread = {0}; + OS_Handle image_write_thread = {0}; // init state machine struct StateList state_list = {0}; @@ -4121,6 +4286,12 @@ lnk_run(int argc, char **argv) lnk_timer_end(LNK_Timer_Lib); ProfEnd(); } break; + case State_BuildRadChunkMap: { + ProfBegin("RAD Chunk Map"); + String8List map = lnk_build_rad_chunk_map(scratch.arena, image_data, config->worker_count, obj_list, st, symtab); + lnk_write_data_list_to_file_path(config->rad_chunk_map_name, config->temp_rad_chunk_map_name, map); + ProfEnd(); + } break; case State_BuildDebugInfo: { ProfBegin("Debug Info"); lnk_timer_begin(LNK_Timer_Debug); @@ -4319,6 +4490,11 @@ lnk_run(int argc, char **argv) continue; } } + if (build_rad_chunk_map) { + build_rad_chunk_map = 0; + state_list_push(scratch.arena, state_list, State_BuildRadChunkMap); + continue; + } if (build_debug_info) { build_debug_info = 0; state_list_push(scratch.arena, state_list, State_BuildDebugInfo); diff --git a/src/linker/lnk_chunk.h b/src/linker/lnk_chunk.h index 0b64d968..e2c54174 100644 --- a/src/linker/lnk_chunk.h +++ b/src/linker/lnk_chunk.h @@ -40,6 +40,7 @@ typedef struct LNK_Chunk struct LNK_ChunkList *list; struct LNK_ChunkArray *arr; } u; + struct LNK_Obj *obj; #if LNK_DEBUG_CHUNKS String8 debug; #endif @@ -115,7 +116,7 @@ typedef struct LNK_ChunkPadArrayNode } LNK_ChunkPadArrayNode; typedef struct LNK_ChunkPadArrayList { - U64 count; + U64 count; LNK_ChunkPadArrayNode *first; LNK_ChunkPadArrayNode *last; } LNK_ChunkPadArrayList; diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 72b3dd12..e1f20096 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -132,6 +132,7 @@ global read_only struct { LNK_CmdSwitch_Rad_Age, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." }, { LNK_CmdSwitch_Rad_BuildInfo, "RAD_BUILD_INFO", "", "Print build info and exit." }, { LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "RAD_CHECK_UNUSED_DELAY_LOAD_DLL", "[:NO]", "" }, + { LNK_CmdSwitch_Rad_ChunkMap, "RAD_CHUNK_MAP", ":FILENAME", "Emit file with the output image's layout description." }, { LNK_CmdSwitch_Rad_Debug, "RAD_DEBUG", "[:NO]", "Emit RAD debug info file." }, { LNK_CmdSwitch_Rad_DebugAltPath, "RAD_DEBUGALTPATH", "", "" }, { LNK_CmdSwitch_Rad_DebugName, "RAD_DEBUG_NAME", ":FILENAME", "Sets file name for RAD debug info file." }, @@ -1522,6 +1523,11 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam lnk_cmd_switch_set_flag_64(obj_path, lib_path, cmd_switch, value_strings, &config->flags, LNK_ConfigFlag_CheckUnusedDelayLoadDll); } break; + case LNK_CmdSwitch_Rad_ChunkMap: { + lnk_cmd_switch_parse_string_copy(arena, obj_path, lib_path, cmd_switch, value_strings, &config->rad_chunk_map_name); + config->rad_chunk_map = LNK_SwitchState_Yes; + } break; + case LNK_CmdSwitch_Rad_Debug: { lnk_cmd_switch_parse_flag(obj_path, lib_path, cmd_switch, value_strings, &config->rad_debug); } break; @@ -2060,9 +2066,10 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line) // create temporary files names if (config->write_temp_files == LNK_SwitchState_Yes) { - config->temp_image_name = push_str8f(arena, "%S.tmp%x", config->image_name, config->time_stamp); - config->temp_pdb_name = push_str8f(arena, "%S.tmp%x", config->pdb_name, config->time_stamp); - config->temp_rad_debug_name = push_str8f(arena, "%S.tmp%x", config->rad_debug_name, config->time_stamp); + config->temp_rad_chunk_map_name = push_str8f(arena, "%S.tmp%x", config->rad_chunk_map_name, config->time_stamp); + config->temp_image_name = push_str8f(arena, "%S.tmp%x", config->image_name, config->time_stamp); + config->temp_pdb_name = push_str8f(arena, "%S.tmp%x", config->pdb_name, config->time_stamp); + config->temp_rad_debug_name = push_str8f(arena, "%S.tmp%x", config->rad_debug_name, config->time_stamp); } if (lnk_get_log_status(LNK_Log_Debug)) { diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index ea9d3edc..81f64066 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -128,6 +128,7 @@ typedef enum LNK_CmdSwitch_Rad_Age, LNK_CmdSwitch_Rad_BuildInfo, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, + LNK_CmdSwitch_Rad_ChunkMap, LNK_CmdSwitch_Rad_Debug, LNK_CmdSwitch_Rad_DebugName, LNK_CmdSwitch_Rad_DebugAltPath, @@ -355,6 +356,8 @@ typedef struct LNK_Config String8 manifest_ui_access; String8List manifest_dependency_list; LNK_SwitchState rad_debug; + LNK_SwitchState rad_chunk_map; + String8 rad_chunk_map_name; String8 rad_debug_name; String8 rad_debug_alt_path; String8List include_symbol_list; @@ -369,6 +372,7 @@ typedef struct LNK_Config String8 temp_image_name; String8 temp_pdb_name; String8 temp_rad_debug_name; + String8 temp_rad_chunk_map_name; } LNK_Config; typedef enum diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index d53802d2..1c3f7705 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -410,6 +410,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) chunk->input_idx = LNK_MakeChunkInputIdx(obj_idx, sect_idx); chunk->flags = coff_sect->flags; chunk->u.leaf = data; + chunk->obj = obj; lnk_chunk_set_debugf(arena, chunk, "%S: name: %S, obj_idx: 0x%llX isect: 0x%llX", cached_path, sect_name_arr[sect_idx], obj_idx, sect_idx); } @@ -425,6 +426,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) master_common_block->flags = LNK_BSS_SECTION_FLAGS; master_common_block->associate = 0; master_common_block->u.list = push_array(arena, LNK_ChunkList, 1); + master_common_block->obj = obj; lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", cached_path); LNK_ChunkPtr *chunk_ptr_arr = push_array_no_zero(arena, LNK_ChunkPtr, chunk_count); @@ -787,6 +789,7 @@ lnk_symbol_array_from_coff(Arena *arena, chunk_list->input_idx = chunk->input_idx; chunk_list->flags = chunk->flags; chunk_list->u.list = push_array(arena, LNK_ChunkList, 1); + chunk_list->obj = obj; lnk_chunk_set_debugf(arena, chunk_list, "%S: function chunk list for %S", obj_path, symbol.name); // update properties on first chunk @@ -834,6 +837,7 @@ lnk_symbol_array_from_coff(Arena *arena, split_chunk->is_discarded = current->data->is_discarded; split_chunk->flags = current->data->flags; split_chunk->u.leaf = right_data; + split_chunk->obj = obj; lnk_chunk_set_debugf(arena, split_chunk, "%S: chunk split on function %S SECT%x SPLIT_POS %#llx", obj_path, symbol.name, symbol.section_number, split_pos); LNK_ChunkNode *split_node = push_array(arena, LNK_ChunkNode, 1); @@ -985,6 +989,7 @@ lnk_symbol_array_from_coff(Arena *arena, chunk->type = LNK_Chunk_Leaf; chunk->flags = master_common_block->flags; chunk->u.leaf = str8(0, parsed_symbol.value); + chunk->obj = obj; lnk_chunk_set_debugf(arena, chunk, "%S: common block %S", obj_path, parsed_symbol.name); lnk_chunk_list_push(arena, master_common_block->u.list, chunk); From bb3d01ffe68c177e2714455ed7cbf24a6c1cd469 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 2 Apr 2025 14:37:36 -0700 Subject: [PATCH 309/755] output lib index and chunk debug comments --- src/linker/lnk.c | 47 +++++++++++++++++++++++++++++++++++------- src/linker/lnk_chunk.h | 14 ++++++------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 6c2bc7ec..463802f0 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -3202,15 +3202,17 @@ lnk_chunk_off_pair_array_bsearch(LNK_ChunkOffPair *arr, U64 count, U64 value) } internal String8List -lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ObjList objs, LNK_SectionTable *st, LNK_SymbolTable *symtab) +lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ObjList objs, LNK_LibList lib_index[LNK_InputSource_Count], LNK_SectionTable *st, LNK_SymbolTable *symtab) { + ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); + String8List map = {0}; + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); - String8List map = {0}; - - str8_list_pushf(arena, &map, "# CHUNKS\n"); + ProfBegin("SECTIONS"); + str8_list_pushf(arena, &map, "# SECTIONS\n"); for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) { LNK_Section *sect = §_n->data; if (sect->has_layout) { @@ -3244,7 +3246,7 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ String8 file_size_str = push_str8f(temp.arena, "%08x", file_size); String8 chunk_hash_str = push_str8f(temp.arena, "%08x%08x", chunk_hash.u64[0], chunk_hash.u64[1]); String8 chunk_ref_str = push_str8f(temp.arena, "{%llx,%llx}", chunk->ref.sect_id, chunk->ref.chunk_id); - String8 source_str = str8_lit("\?\?\?"); + String8 source_str = {0}; if (chunk->obj) { if (chunk->obj->lib_path.size) { String8 lib_name = chunk->obj->lib_path; @@ -3259,6 +3261,18 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ source_str = push_str8f(temp.arena, "%S", chunk->obj->path); } } +#if LNK_DEBUG_CHUNKS + if (chunk->debug.size) { + if (source_str.size) { + source_str = push_str8f(temp.arena, "%S (%S)", source_str, chunk->debug); + } else if (chunk->debug.size) { + source_str = push_str8f(temp.arena, "%S", chunk->debug); + } + } +#endif + if (source_str.size == 0) { + source_str = str8_lit("\?\?\?"); + } str8_list_pushf(arena, &map, "%-16S %-8S %-8S %-16S %-8S %S\n", address_str, virt_size_str, file_size_str, chunk_hash_str, chunk_ref_str, source_str); @@ -3268,7 +3282,10 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ str8_list_pushf(arena, &map, "\n"); } } + ProfEnd(); + + ProfBegin("SYMBOLS"); str8_list_pushf(arena, &map, "# SYMBOLS\n"); str8_list_pushf(arena, &map, "%-8s %s\n", "ChunkRef", "Symbol"); for (LNK_ObjNode *obj_n = objs.first; obj_n != 0; obj_n = obj_n->next) { @@ -3295,10 +3312,24 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ } } } - - //str8_list_pushf(arena, &map, "%16s %30s %23s %10s\n\n", "Address", "Publics by Value", "Rva+Base", "Lib:Object"); + str8_list_pushf(arena, &map, "\n"); + ProfEnd(); + + ProfBegin("LIBS"); + for (U64 input_source = 0; input_source < LNK_InputSource_Count; ++input_source) { + if (lib_index[input_source].count) { + str8_list_pushf(arena, &map, "# LIBS (%S)\n", lnk_string_from_input_source(input_source)); + for (LNK_LibNode *lib_n = lib_index[input_source].first; lib_n != 0; lib_n = lib_n->next) { + str8_list_pushf(arena, &map, "%S\n", lib_n->data.path); + } + } + } + ProfEnd(); + + scratch_end(scratch); + ProfEnd(); return map; } @@ -4288,7 +4319,7 @@ lnk_run(int argc, char **argv) } break; case State_BuildRadChunkMap: { ProfBegin("RAD Chunk Map"); - String8List map = lnk_build_rad_chunk_map(scratch.arena, image_data, config->worker_count, obj_list, st, symtab); + String8List map = lnk_build_rad_chunk_map(scratch.arena, image_data, config->worker_count, obj_list, lib_index, st, symtab); lnk_write_data_list_to_file_path(config->rad_chunk_map_name, config->temp_rad_chunk_map_name, map); ProfEnd(); } break; diff --git a/src/linker/lnk_chunk.h b/src/linker/lnk_chunk.h index e2c54174..cb68e56d 100644 --- a/src/linker/lnk_chunk.h +++ b/src/linker/lnk_chunk.h @@ -5,7 +5,13 @@ //////////////////////////////// -#define LNK_DEBUG_CHUNKS 0 +#define LNK_DEBUG_CHUNKS 1 + +#if LNK_DEBUG_CHUNKS +# define lnk_chunk_set_debugf(a, c, f, ...) do { (c)->debug = push_str8f((a), f, __VA_ARGS__); } while(0) +#else +# define lnk_chunk_set_debugf(a, c, f, ...) (void)(c) +#endif //////////////////////////////// @@ -200,9 +206,3 @@ internal LNK_ChunkNode * lnk_chunk_ptr_list_reserve(Arena *arena, LNK_ChunkList internal String8Array lnk_data_arr_from_chunk_ptr_list(Arena *arena, LNK_ChunkList list); internal String8Array * lnk_data_arr_from_chunk_ptr_list_arr(Arena *arena, LNK_ChunkList *list_arr, U64 count); -#if LNK_DEBUG_CHUNKS -#define lnk_chunk_set_debugf(a, c, f, ...) do { (c)->debug = push_str8f((a), f, __VA_ARGS__); } while(0) -#else -#define lnk_chunk_set_debugf(a, c, f, ...) (void)(c) -#endif - From c090bee2f3d5d5d4a14c0b3de68646b73ebd4c44 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 2 Apr 2025 16:06:23 -0700 Subject: [PATCH 310/755] added missing debug comments for chunks --- src/linker/lnk.c | 112 ++++++++++++++++++--------------- src/linker/lnk_chunk.c | 12 ++++ src/linker/lnk_chunk.h | 2 + src/linker/lnk_import_table.c | 34 +++++++--- src/linker/lnk_obj.c | 10 +-- src/linker/lnk_section_table.c | 1 + 6 files changed, 110 insertions(+), 61 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 463802f0..4e8cb79c 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -2013,7 +2013,8 @@ lnk_build_base_relocs(TP_Context *tp, Assert(*block_size_ptr <= buf_size); // push page chunk - lnk_section_push_chunk_raw(base_reloc_sect, base_reloc_sect->root, buf, block_size, str8_zero()); + LNK_Chunk *page_chunk = lnk_section_push_chunk_raw(base_reloc_sect, base_reloc_sect->root, buf, block_size, str8_zero()); + lnk_chunk_set_debugf(base_reloc_sect->arena, page_chunk, "Base Reloc Page (VirtOff: %#x Size: %#x, Pads: %#x)", page->voff, block_size, pad_reloc_count); // purge voffs for next run hash_table_purge(voff_ht); @@ -2278,11 +2279,11 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect, } // push COFF header array chunk - LNK_Chunk *COFF_FileHeader_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero()); - lnk_chunk_set_debugf(header_sect->arena, COFF_FileHeader_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME); + LNK_Chunk *coff_section_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero()); + lnk_chunk_set_debugf(header_sect->arena, coff_section_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME); // define symbol for COFF header array - lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, COFF_FileHeader_array_chunk, 0, 0, 0); + lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_section_array_chunk, 0, 0, 0); // push headers for (LNK_Section *sect = §_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) { @@ -2292,38 +2293,39 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect, if (!sect->has_layout) { continue; } - COFF_SectionHeader *COFF_FileHeader = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1); + COFF_SectionHeader *coff_section = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1); // TODO: for objs we can store long name in string table and write here /offset - if (sect->name.size > sizeof(COFF_FileHeader->name)) { + if (sect->name.size > sizeof(coff_section->name)) { lnk_error(LNK_Warning_LongSectionName, "not enough space in COFF section header to store entire name \"%S\"", sect->name); } - MemorySet(&COFF_FileHeader->name[0], 0, sizeof(COFF_FileHeader->name)); - MemoryCopy(&COFF_FileHeader->name[0], sect->name.str, Min(sect->name.size, sizeof(COFF_FileHeader->name))); - COFF_FileHeader->vsize = 0; // :vsize - COFF_FileHeader->voff = 0; // :voff - COFF_FileHeader->fsize = 0; // :fsize - COFF_FileHeader->foff = 0; // :foff - COFF_FileHeader->relocs_foff = 0; // :relocs_foff - COFF_FileHeader->lines_foff = 0; // obsolete - COFF_FileHeader->reloc_count = 0; // :reloc_count - COFF_FileHeader->line_count = 0; // obsolete - COFF_FileHeader->flags = sect->flags; + MemorySet(&coff_section->name[0], 0, sizeof(coff_section->name)); + MemoryCopy(&coff_section->name[0], sect->name.str, Min(sect->name.size, sizeof(coff_section->name))); + coff_section->vsize = 0; // :vsize + coff_section->voff = 0; // :voff + coff_section->fsize = 0; // :fsize + coff_section->foff = 0; // :foff + coff_section->relocs_foff = 0; // :relocs_foff + coff_section->lines_foff = 0; // obsolete + coff_section->reloc_count = 0; // :reloc_count + coff_section->line_count = 0; // obsolete + coff_section->flags = sect->flags; // push chunk - LNK_Chunk *COFF_FileHeader_chunk = lnk_section_push_chunk_raw(header_sect, COFF_FileHeader_array_chunk, COFF_FileHeader, sizeof(*COFF_FileHeader), str8_zero()); + LNK_Chunk *coff_section_chunk = lnk_section_push_chunk_raw(header_sect, coff_section_array_chunk, coff_section, sizeof(*coff_section), str8_zero()); + lnk_chunk_set_debugf(header_sect->arena, coff_section_chunk, "COFF_SECTION_HEADER %S", sect->name); // :vsize - lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal); + lnk_section_push_reloc_undefined(header_sect, coff_section_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal); // :voff - lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal); + lnk_section_push_reloc_undefined(header_sect, coff_section_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal); if (~sect->flags & COFF_SectionFlag_CntUninitializedData) { // :fsize - lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal); + lnk_section_push_reloc_undefined(header_sect, coff_section_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal); // :foff - lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal); + lnk_section_push_reloc_undefined(header_sect, coff_section_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal); } // TODO: :reloc_off @@ -2331,10 +2333,10 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect, } // push symbol for section header count - U64 header_count = COFF_FileHeader_array_chunk->u.list->count; + U64 header_count = coff_section_array_chunk->u.list->count; lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, header_count); - return COFF_FileHeader_array_chunk; + return coff_section_array_chunk; } internal LNK_Chunk * @@ -3223,13 +3225,14 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ radsort(chunks, sect->layout.total_count, lnk_map_sort_on_chunk_file_off); str8_list_pushf(arena, &map, "%S\n", sect->name); - str8_list_pushf(arena, &map, "%-16s %-8s %-8s %-16s %-8s %s\n", "Sect:Offset", "VirtSize", "FileSize", "Blake3", "ChunkRef", "Source"); + str8_list_pushf(arena, &map, "%-8s %-8s %-8s %-8s %-16s %-8s %s\n", "FileOff", "VirtOff", "VirtSize", "FileSize", "Blake3", "ChunkRef", "Source"); for (U64 chunk_idx = 0; chunk_idx < sect->layout.total_count; ++chunk_idx) { LNK_Chunk *chunk = chunks[chunk_idx]; - if (chunk->type == LNK_Chunk_Leaf && chunk != g_null_chunk_ptr) { + if (chunk != g_null_chunk_ptr) { Temp temp = temp_begin(scratch.arena); - ISectOff sc = lnk_sc_from_chunk_ref(sect_id_map, chunk->ref); + U64 file_off = lnk_file_off_from_chunk_ref(sect_id_map, chunk->ref); + U64 virt_off = lnk_virt_off_from_chunk_ref(sect_id_map, chunk->ref); U64 virt_size = lnk_virt_size_from_chunk_ref(sect_id_map, chunk->ref); U64 file_size = lnk_file_size_from_chunk_ref(sect_id_map, chunk->ref); String8 chunk_data = lnk_data_from_chunk_ref(sect_id_map, image_data, chunk->ref); @@ -3241,40 +3244,51 @@ lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ blake3_hasher_finalize(&hasher, (U8 *)&chunk_hash, sizeof(chunk_hash)); } - String8 address_str = push_str8f(temp.arena, "%04x:%08x", sc.isect, sc.off); + String8 file_off_str = push_str8f(temp.arena, "%08x", file_off); + String8 virt_off_str = push_str8f(temp.arena, "%08x", virt_off); String8 virt_size_str = push_str8f(temp.arena, "%08x", virt_size); String8 file_size_str = push_str8f(temp.arena, "%08x", file_size); String8 chunk_hash_str = push_str8f(temp.arena, "%08x%08x", chunk_hash.u64[0], chunk_hash.u64[1]); String8 chunk_ref_str = push_str8f(temp.arena, "{%llx,%llx}", chunk->ref.sect_id, chunk->ref.chunk_id); - String8 source_str = {0}; - if (chunk->obj) { - if (chunk->obj->lib_path.size) { - String8 lib_name = chunk->obj->lib_path; - lib_name = str8_skip_last_slash(lib_name); - lib_name = str8_chop_last_dot(lib_name); + String8 source_str; + { + String8List source_list = {0}; - String8 obj_name = chunk->obj->path; - obj_name = str8_skip_last_slash(obj_name); + // chunk type + str8_list_pushf(temp.arena, &source_list, "[%S]", lnk_string_from_chunk_type(chunk->type)); - source_str = push_str8f(temp.arena, "%S:%S", lib_name, obj_name); - } else { - source_str = push_str8f(temp.arena, "%S", chunk->obj->path); + // location + if (chunk->obj) { + if (chunk->obj->lib_path.size) { + String8 lib_name = chunk->obj->lib_path; + lib_name = str8_skip_last_slash(lib_name); + lib_name = str8_chop_last_dot(lib_name); + + String8 obj_name = chunk->obj->path; + obj_name = str8_skip_last_slash(obj_name); + + str8_list_pushf(temp.arena, &source_list, "%S:%S", lib_name, obj_name); + } else { + str8_list_push(temp.arena, &source_list, chunk->obj->path); + } } - } + + // debug comment #if LNK_DEBUG_CHUNKS - if (chunk->debug.size) { - if (source_str.size) { - source_str = push_str8f(temp.arena, "%S (%S)", source_str, chunk->debug); - } else if (chunk->debug.size) { - source_str = push_str8f(temp.arena, "%S", chunk->debug); + if (chunk->debug.size) { + if (source_str.size) { + str8_list_pushf(temp.arena, &source_list, "(%S)", chunk->debug); + } else if (chunk->debug.size) { + str8_list_push(temp.arena, &source_list, chunk->debug); + } } - } #endif - if (source_str.size == 0) { - source_str = str8_lit("\?\?\?"); + + // string join + source_str = str8_list_join(temp.arena, &source_list, &(StringJoin){.sep=str8_lit(" ")}); } - str8_list_pushf(arena, &map, "%-16S %-8S %-8S %-16S %-8S %S\n", address_str, virt_size_str, file_size_str, chunk_hash_str, chunk_ref_str, source_str); + str8_list_pushf(arena, &map, "%-8S %-8S %-8S %-8S %-16S %-8S %S\n", file_off_str, virt_off_str, virt_size_str, file_size_str, chunk_hash_str, chunk_ref_str, source_str); temp_end(temp); } diff --git a/src/linker/lnk_chunk.c b/src/linker/lnk_chunk.c index c35e4b73..be7b7211 100644 --- a/src/linker/lnk_chunk.c +++ b/src/linker/lnk_chunk.c @@ -790,3 +790,15 @@ lnk_data_arr_from_chunk_ptr_list_arr(Arena *arena, LNK_ChunkList *list_arr, U64 return result; } +internal String8 +lnk_string_from_chunk_type(LNK_ChunkType type) +{ + switch (type) { + case LNK_Chunk_Null: return str8_lit("Null"); + case LNK_Chunk_Leaf: return str8_lit("Leaf"); + case LNK_Chunk_LeafArray: return str8_lit("LeafArray"); + case LNK_Chunk_List: return str8_lit("List"); + default: InvalidPath; + } + return str8_zero(); +} diff --git a/src/linker/lnk_chunk.h b/src/linker/lnk_chunk.h index cb68e56d..ed53cf36 100644 --- a/src/linker/lnk_chunk.h +++ b/src/linker/lnk_chunk.h @@ -206,3 +206,5 @@ internal LNK_ChunkNode * lnk_chunk_ptr_list_reserve(Arena *arena, LNK_ChunkList internal String8Array lnk_data_arr_from_chunk_ptr_list(Arena *arena, LNK_ChunkList list); internal String8Array * lnk_data_arr_from_chunk_ptr_list_arr(Arena *arena, LNK_ChunkList *list_arr, U64 count); +internal String8 lnk_string_from_chunk_type(LNK_ChunkType type); + diff --git a/src/linker/lnk_import_table.c b/src/linker/lnk_import_table.c index 81b7d648..677ae6ba 100644 --- a/src/linker/lnk_import_table.c +++ b/src/linker/lnk_import_table.c @@ -14,7 +14,12 @@ lnk_import_table_alloc_static(LNK_SectionTable *st, LNK_SymbolTable *symtab, COF LNK_Chunk *iat_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); LNK_Chunk *ilt_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); LNK_Chunk *code_chunk = lnk_section_push_chunk_list(code_sect, code_sect->root, str8_zero()); - + lnk_chunk_set_debugf(data_sect->arena, dll_table_chunk, "DLL_TABLE" ); + lnk_chunk_set_debugf(data_sect->arena, int_chunk, "IMPORT_NAME_TABLE" ); + lnk_chunk_set_debugf(data_sect->arena, iat_chunk, "IMPORT_ADDRESS_TABLE"); + lnk_chunk_set_debugf(data_sect->arena, ilt_chunk, "IMPORT_LOOKUP_TABLE" ); + lnk_chunk_set_debugf(data_sect->arena, code_chunk, "IMPORT_TABLE_CODE" ); + LNK_Chunk *null_dll_import = lnk_section_push_chunk_data(data_sect, dll_table_chunk, str8(0, sizeof(PE_ImportEntry)), str8_lit("zzzzz")); lnk_chunk_set_debugf(data_sect->arena, null_dll_import, "DLL_DIRECTORY_TERMINATOR"); @@ -177,6 +182,10 @@ lnk_import_table_push_dll_static(LNK_ImportTable *imptab, LNK_SymbolTable *symta LNK_Chunk *ilt_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->ilt_chunk, str8_zero()); LNK_Chunk *iat_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->iat_chunk, str8_zero()); LNK_Chunk *code_table_chunk = lnk_section_push_chunk_list(code_sect, imptab->code_chunk, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, int_table_chunk, "%S.INT", dll_name); + lnk_chunk_set_debugf(data_sect->arena, ilt_table_chunk, "%S.ILT", dll_name); + lnk_chunk_set_debugf(data_sect->arena, iat_table_chunk, "%S.IAT", dll_name); + lnk_chunk_set_debugf(data_sect->arena, code_table_chunk, "%S.CODE", dll_name); String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "%S.lookup_table_voff", dll_name); LNK_Symbol *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_table_chunk, 0, 0, 0); @@ -256,24 +265,26 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt // emit entry chunk String8 imp_desc_data = str8_struct(imp_desc); LNK_Chunk *imp_desc_chunk = lnk_section_push_chunk_data(data_sect, imptab->dll_table_chunk, imp_desc_data, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, imp_desc_chunk, "%S.IMP_DESC", dll_name); // emit entry symbol String8 imp_desc_name = push_str8f(symtab->arena->v[0], "__DELAY_IMPORT_DESCRIPTOR_%S", dll_name); LNK_Symbol *imp_desc_symbol = lnk_symbol_table_push_defined_chunk(symtab, imp_desc_name, LNK_DefinedSymbolVisibility_Extern, 0, imp_desc_chunk, 0, 0, 0); // emit string table chunk - String8 int_table_chunk_debug = push_str8f(data_sect->arena, "delayed.%S.int", dll_name); - LNK_Chunk *int_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->int_chunk, int_table_chunk_debug); + LNK_Chunk *int_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->int_chunk, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, int_table_chunk, "%S.DELAY_INT", dll_name); String8 int_table_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.int", dll_name); LNK_Symbol *int_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_table_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_table_chunk, 0, 0, 0); LNK_Chunk *null_string_chunk = lnk_section_push_chunk_list(data_sect, int_table_chunk, str8_lit("zzzzz")); - lnk_chunk_set_debugf(data_sect->arena, null_string_chunk, "string table null"); + lnk_chunk_set_debugf(data_sect->arena, null_string_chunk, "%S.STRING_TABLE_NULL", dll_name); // emit DLL name chunk String8 name_chunk_data = push_cstr(data_sect->arena, dll_name); LNK_Chunk *name_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, name_chunk_data, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, name_chunk, "%S.DELAY_NAME", dll_name); String8 name_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.name", dll_name); LNK_Symbol *name_symbol = lnk_symbol_table_push_defined_chunk(symtab, name_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0); @@ -283,6 +294,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt // emit DLL handle chunk LNK_Chunk *handle_chunk = lnk_section_push_chunk_bss(data_sect, imptab->handle_table_chunk, handle_size, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, handle_chunk, "%S.DELAY_HANDLE", dll_name); String8 handle_name = push_str8f(symtab->arena->v[0], "delayed.%S.handle", dll_name); LNK_Symbol *handle_symbol = lnk_symbol_table_push_defined_chunk(symtab, handle_name, LNK_DefinedSymbolVisibility_Internal, 0, handle_chunk, 0, 0, 0); @@ -292,18 +304,19 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt // emit IAT chunk LNK_Chunk *iat_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->iat_chunk, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, iat_table_chunk, "%S.DELAY_IAT", dll_name); String8 iat_table_name = push_str8f(symtab->arena->v[0], "delayed.%S.iat", dll_name); LNK_Symbol *iat_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_table_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0); LNK_Chunk *null_iat_chunk = lnk_section_push_chunk_bss(data_sect, iat_table_chunk, import_size, str8_lit("zzzzzz")); - lnk_chunk_set_debugf(data_sect->arena, null_iat_chunk, "%S: IAT terminator", dll_name); + lnk_chunk_set_debugf(data_sect->arena, null_iat_chunk, "%S.DELAY_IAT_TERMINATOR", dll_name); // emit ILT chunk LNK_Chunk *ilt_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->ilt_chunk, str8_zero()); LNK_Chunk *null_ilt_chunk = lnk_section_push_chunk_bss(data_sect, ilt_table_chunk, import_size, str8_lit("zzzzzz")); - lnk_chunk_set_debugf(data_sect->arena, null_ilt_chunk, "%S: ILT terminator", dll_name); + lnk_chunk_set_debugf(data_sect->arena, null_ilt_chunk, "%S.DELAY_ILT_TERMINATOR", dll_name); String8 ilt_table_name = push_str8f(symtab->arena->v[0], "delayed.%S.ilt", dll_name); LNK_Symbol *ilt_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_table_name, LNK_DefinedSymbolVisibility_Extern, 0, ilt_table_chunk, 0, 0, 0); @@ -318,6 +331,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt LNK_Chunk *biat_chunk = 0; if (imptab->flags & LNK_ImportTableFlag_EmitBiat) { biat_chunk = lnk_section_push_chunk_list(data_sect, imptab->biat_chunk, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, biat_chunk, "%S.DELAY_BIAT", dll_name); String8 biat_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.BIAT", dll_name); LNK_Symbol *biat_symbol = lnk_symbol_table_push_defined_chunk(symtab, biat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk, 0, 0, 0); @@ -330,6 +344,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt LNK_Chunk *uiat_chunk = NULL; if (imptab->flags & LNK_ImportTableFlag_EmitUiat) { uiat_chunk = lnk_section_push_chunk_list(data_sect, imptab->uiat_chunk, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, uiat_chunk, "%S.DELAY_UIAT", dll_name); String8 uiat_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.UIAT", dll_name); LNK_Symbol *uiat_symbol = lnk_symbol_table_push_defined_chunk(symtab, uiat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk, 0, 0, 0); @@ -340,7 +355,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt // emit chunk for DLL thunk/load code LNK_Chunk *code_chunk = lnk_section_push_chunk_list(code_sect, imptab->code_chunk, str8_zero()); - lnk_chunk_set_debugf(code_sect->arena, code_chunk, "code for %S", dll_name); + lnk_chunk_set_debugf(code_sect->arena, code_chunk, "%S.DLAY_CODE", dll_name); // emit tail merge LNK_Chunk *tail_merge_chunk = 0; @@ -348,6 +363,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt case COFF_MachineType_X64: { LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main); tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol); + lnk_chunk_set_debugf(code_sect->arena, code_chunk, "%S.X64_TAIL_MERGE", dll_name); } break; default: { lnk_not_implemented("TODO: __tailMerge for %S", coff_string_from_machine_type(machine)); @@ -402,6 +418,8 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint_or_ordinal); ilt_chunk = lnk_section_push_chunk_data(data_sect, ilt_table_chunk, ordinal_data, sort_index); iat_chunk = lnk_section_push_chunk_data(data_sect, iat_table_chunk, ordinal_data, sort_index); + lnk_chunk_set_debugf(data_sect->arena, ilt_chunk, "ILT entry for %S.%u", dll->name, header->hint_or_ordinal); + lnk_chunk_set_debugf(data_sect->arena, iat_chunk, "IAT entry for %S.%u", dll->name, header->hint_or_ordinal); // associate chunks lnk_section_associate_chunks(data_sect, iat_chunk, ilt_chunk); @@ -410,6 +428,7 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt // put together name look up entry String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint_or_ordinal, header->func_name); LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero()); + lnk_chunk_set_debugf(data_sect->arena, int_chunk, "INT entry for %S.%S (Hint: %u)", dll->name, header->func_name, header->hint_or_ordinal); // create symbol for lookup chunk String8 int_symbol_name = push_str8f(symtab->arena->v[0], "static.%S.%S.name", dll->name, header->func_name); @@ -450,6 +469,7 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt // generate jump thunk LNK_Chunk *jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol); lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk); + lnk_chunk_set_debugf(data_sect->arena, jmp_thunk_chunk, "Jump thunk to %S.%S", dll->name, iat_symbol->name); // push jump thunk symbol String8 jmp_thunk_symbol_name = push_str8_copy(symtab->arena->v[0], header->func_name); diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index 1c3f7705..2c93341f 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -411,7 +411,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) chunk->flags = coff_sect->flags; chunk->u.leaf = data; chunk->obj = obj; - lnk_chunk_set_debugf(arena, chunk, "%S: name: %S, obj_idx: 0x%llX isect: 0x%llX", cached_path, sect_name_arr[sect_idx], obj_idx, sect_idx); + lnk_chunk_set_debugf(arena, chunk, "obj_idx %llx isect %llx", obj_idx, sect_idx); } // :common_block @@ -427,7 +427,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) master_common_block->associate = 0; master_common_block->u.list = push_array(arena, LNK_ChunkList, 1); master_common_block->obj = obj; - lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", cached_path); + lnk_chunk_set_debugf(arena, master_common_block, "master common block"); LNK_ChunkPtr *chunk_ptr_arr = push_array_no_zero(arena, LNK_ChunkPtr, chunk_count); for (U64 i = 0; i < chunk_count; ++i) { @@ -790,7 +790,7 @@ lnk_symbol_array_from_coff(Arena *arena, chunk_list->flags = chunk->flags; chunk_list->u.list = push_array(arena, LNK_ChunkList, 1); chunk_list->obj = obj; - lnk_chunk_set_debugf(arena, chunk_list, "%S: function chunk list for %S", obj_path, symbol.name); + lnk_chunk_set_debugf(arena, chunk_list, "function chunk list for %S", symbol.name); // update properties on first chunk chunk->min_size = function_pad_min; @@ -838,7 +838,7 @@ lnk_symbol_array_from_coff(Arena *arena, split_chunk->flags = current->data->flags; split_chunk->u.leaf = right_data; split_chunk->obj = obj; - lnk_chunk_set_debugf(arena, split_chunk, "%S: chunk split on function %S SECT%x SPLIT_POS %#llx", obj_path, symbol.name, symbol.section_number, split_pos); + lnk_chunk_set_debugf(arena, split_chunk, "chunk split on function %S sect %x split pos %#llx", symbol.name, symbol.section_number, split_pos); LNK_ChunkNode *split_node = push_array(arena, LNK_ChunkNode, 1); split_node->data = split_chunk; @@ -990,7 +990,7 @@ lnk_symbol_array_from_coff(Arena *arena, chunk->flags = master_common_block->flags; chunk->u.leaf = str8(0, parsed_symbol.value); chunk->obj = obj; - lnk_chunk_set_debugf(arena, chunk, "%S: common block %S", obj_path, parsed_symbol.name); + lnk_chunk_set_debugf(arena, chunk, "common block %S", parsed_symbol.name); lnk_chunk_list_push(arena, master_common_block->u.list, chunk); LNK_DefinedSymbolFlags flags = 0; diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index 084538db..a38ec9a7 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -338,6 +338,7 @@ lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags fla sect->is_loose = 1; lnk_chunk_set_debugf(sect->arena, sect->root, "root chunk for %S", name); + lnk_chunk_set_debugf(sect->arena, sect->nosort_chunk, "nosort chunk for %S", name); ProfEnd(); return sect; From 8beb168905d7bfaa2bedc6cd549af5c34aa9127f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 4 Apr 2025 15:05:29 -0700 Subject: [PATCH 311/755] went over COFF string table and changed the parser code accept to String8 --- src/coff/coff.c | 14 +- src/coff/coff.h | 4 +- src/coff/coff_parse.c | 28 +-- src/coff/coff_parse.h | 11 +- src/dwarf/dwarf_coff.c | 16 +- src/dwarf/dwarf_coff.h | 2 +- src/linker/lnk_obj.c | 363 ++++++++++++++++++++------------------ src/linker/lnk_obj.h | 9 +- src/pe/pe.c | 103 ++--------- src/pe/pe.h | 11 +- src/radcon/radcon.c | 11 +- src/radcon/radcon_coff.c | 4 +- src/radcon/radcon_coff.h | 2 +- src/radcon/radcon_dwarf.c | 9 +- src/radcon/radcon_pdb.c | 2 +- src/raddump/raddump.c | 118 +++++++------ src/raddump/raddump.h | 8 +- 17 files changed, 335 insertions(+), 380 deletions(-) diff --git a/src/coff/coff.c b/src/coff/coff.c index cc3cdd4e..11e5d92a 100644 --- a/src/coff/coff.c +++ b/src/coff/coff.c @@ -52,14 +52,13 @@ coff_section_flag_from_align_size(U64 align) } internal String8 -coff_name_from_section_header(String8 raw_coff, COFF_SectionHeader *header, U64 string_table_off) +coff_name_from_section_header(String8 string_table, COFF_SectionHeader *header) { String8 name = str8_cstring_capped(header->name, header->name + sizeof(header->name)); if (name.str[0] == '/') { - String8 ascii_off = str8_skip(name, 1); - U64 name_rel_off = u64_from_str8(ascii_off, 10); - U64 name_off = name_rel_off + string_table_off; - name = str8_cstring_capped(raw_coff.str + name_off, raw_coff.str + raw_coff.size); + String8 name_off_str = str8_skip(name, 1); + U64 name_off = u64_from_str8(name_off_str, 10); + name = str8_cstring_capped(string_table.str + name_off, string_table.str+string_table.size); } return name; } @@ -94,12 +93,11 @@ coff_parse_section_name(String8 full_name, String8 *name_out, String8 *postfix_o } internal String8 -coff_read_symbol_name(String8 raw_coff, U64 string_table_off, COFF_SymbolName *name) +coff_read_symbol_name(String8 string_table, COFF_SymbolName *name) { String8 name_str = str8_lit(""); if (name->long_name.zeroes == 0) { - U64 name_string_off = string_table_off + name->long_name.string_table_offset; - str8_deserial_read_cstr(raw_coff, name_string_off, &name_str); + str8_deserial_read_cstr(string_table, name->long_name.string_table_offset, &name_str); } else { U32 i; for (i = 0; i < sizeof(name->short_name); ++i) { diff --git a/src/coff/coff.h b/src/coff/coff.h index 6ff6c1af..33cec229 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -567,13 +567,13 @@ typedef struct COFF_ImportHeader internal U64 coff_align_size_from_section_flags(COFF_SectionFlags flags); internal COFF_SectionFlags coff_section_flag_from_align_size (U64 align); -internal String8 coff_name_from_section_header(String8 raw_coff, COFF_SectionHeader *header, U64 string_table_off); +internal String8 coff_name_from_section_header(String8 string_table, COFF_SectionHeader *header); internal void coff_parse_section_name (String8 full_name, String8 *name_out, String8 *postfix_out); //////////////////////////////// // Symbol -internal String8 coff_read_symbol_name(String8 raw_coff, U64 string_table_off, COFF_SymbolName *name); +internal String8 coff_read_symbol_name(String8 string_table, COFF_SymbolName *name); //////////////////////////////// // Reloc diff --git a/src/coff/coff_parse.c b/src/coff/coff_parse.c index 166be2ae..15a918a5 100644 --- a/src/coff/coff_parse.c +++ b/src/coff/coff_parse.c @@ -99,33 +99,33 @@ coff_file_header_info_from_data(String8 raw_coff) COFF_BigObjHeader *header32 = (COFF_BigObjHeader*)raw_coff.str; info.is_big_obj = 1; info.machine = header32->machine; - info.header_size = sizeof(COFF_BigObjHeader); - info.section_array_off = sizeof(COFF_BigObjHeader); info.section_count_no_null = header32->section_count; - info.string_table_off = header32->symbol_table_foff + sizeof(COFF_Symbol32) * header32->symbol_count; - info.symbol_size = sizeof(COFF_Symbol32); - info.symbol_off = header32->symbol_table_foff; info.symbol_count = header32->symbol_count; + info.symbol_size = sizeof(COFF_Symbol32); + info.header_range = rng_1u64(0, sizeof(COFF_BigObjHeader)); + info.section_table_range = rng_1u64(info.header_range.max, info.header_range.max + sizeof(COFF_SectionHeader) * header32->section_count); + info.symbol_table_range = rng_1u64(header32->symbol_table_foff, header32->symbol_table_foff + sizeof(COFF_Symbol32) * header32->symbol_count); + info.string_table_range = rng_1u64(info.symbol_table_range.max, raw_coff.size); } else if (coff_is_obj(raw_coff)) { COFF_FileHeader *header16 = (COFF_FileHeader*)raw_coff.str; info.is_big_obj = 0; info.machine = header16->machine; - info.header_size = sizeof(COFF_FileHeader); - info.section_array_off = sizeof(COFF_FileHeader); info.section_count_no_null = header16->section_count; - info.string_table_off = header16->symbol_table_foff + sizeof(COFF_Symbol16) * header16->symbol_count; - info.symbol_size = sizeof(COFF_Symbol16); - info.symbol_off = header16->symbol_table_foff; info.symbol_count = header16->symbol_count; + info.symbol_size = sizeof(COFF_Symbol16); + info.header_range = rng_1u64(0, sizeof(COFF_FileHeader)); + info.section_table_range = rng_1u64(info.header_range.max, info.header_range.max + sizeof(COFF_SectionHeader) * header16->section_count); + info.symbol_table_range = rng_1u64(header16->symbol_table_foff, header16->symbol_table_foff + sizeof(COFF_Symbol16) * header16->symbol_count); + info.string_table_range = rng_1u64(info.symbol_table_range.max, raw_coff.size); } return info; } internal COFF_ParsedSymbol -coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32) +coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32) { COFF_ParsedSymbol result = {0}; - result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym32->name); + result.name = coff_read_symbol_name(string_table, &sym32->name); result.value = sym32->value; result.section_number = sym32->section_number; result.type = sym32->type; @@ -135,10 +135,10 @@ coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32 } internal COFF_ParsedSymbol -coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16) +coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16) { COFF_ParsedSymbol result = {0}; - result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym16->name); + result.name = coff_read_symbol_name(string_table, &sym16->name); result.value = sym16->value; if (sym16->section_number == COFF_Symbol_DebugSection16) { result.section_number = COFF_Symbol_DebugSection32; diff --git a/src/coff/coff_parse.h b/src/coff/coff_parse.h index 2ed92e92..7e237646 100644 --- a/src/coff/coff_parse.h +++ b/src/coff/coff_parse.h @@ -9,12 +9,13 @@ typedef struct COFF_FileHeaderInfo B32 is_big_obj; COFF_MachineType machine; U64 header_size; - U64 section_array_off; U64 section_count_no_null; - U64 string_table_off; U64 symbol_size; - U64 symbol_off; U64 symbol_count; + Rng1U64 header_range; + Rng1U64 section_table_range; + Rng1U64 symbol_table_range; + Rng1U64 string_table_range; } COFF_FileHeaderInfo; //////////////////////////////// @@ -249,8 +250,8 @@ internal COFF_FileHeaderInfo coff_file_header_info_from_data(String8 raw_coff); //////////////////////////////// // Symbol -internal COFF_ParsedSymbol coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32); -internal COFF_ParsedSymbol coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16); +internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32); +internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16); internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c index 68caeb0a..423761bc 100644 --- a/src/dwarf/dwarf_coff.c +++ b/src/dwarf/dwarf_coff.c @@ -3,15 +3,15 @@ internal B32 dw_is_dwarf_present_coff_section_table(String8 raw_image, - U64 string_table_off, + String8 string_table, U64 section_count, - COFF_SectionHeader *sections) + COFF_SectionHeader *section_table) { B32 is_dwarf_present = 0; for (U64 i = 0; i < section_count; ++i) { - COFF_SectionHeader *header = §ions[i]; - String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + COFF_SectionHeader *header = §ion_table[i]; + String8 name = coff_name_from_section_header(string_table, header); DW_SectionKind s = dw_section_kind_from_string(name); if (s == DW_Section_Null) { @@ -30,17 +30,17 @@ dw_is_dwarf_present_coff_section_table(String8 raw_image, internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, - U64 string_table_off, + String8 string_table, U64 section_count, - COFF_SectionHeader *sections) + COFF_SectionHeader *section_table) { DW_Input input = {0}; B32 sect_status[ArrayCount(input.sec)] = {0}; for (U64 i = 0; i < section_count; ++i) { - COFF_SectionHeader *header = §ions[i]; + COFF_SectionHeader *header = §ion_table[i]; Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize); - String8 name = coff_name_from_section_header(raw_image, header, string_table_off); + String8 name = coff_name_from_section_header(string_table, header); DW_SectionKind s = dw_section_kind_from_string(name); B32 is_dwo = 0; diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h index 768863f2..e612897a 100644 --- a/src/dwarf/dwarf_coff.h +++ b/src/dwarf/dwarf_coff.h @@ -4,7 +4,7 @@ #ifndef DWARF_COFF_H #define DWARF_COFF_H -internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections); +internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table); #endif // DWARF_COFF_H diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index 2c93341f..b03d9fa8 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -315,106 +315,50 @@ lnk_sect_defn_list_concat_in_place_arr(LNK_SectDefnList *list, LNK_SectDefnList internal THREAD_POOL_TASK_FUNC(lnk_obj_initer) { - Temp scratch = scratch_begin(&arena, 1); - - LNK_ObjIniter *task = raw_task; - LNK_InputObj *input = task->inputs[task_id]; - U64 obj_idx = task->obj_id_base + task_id; - LNK_ObjNode *obj_node = task->obj_node_arr + task_id; - LNK_Obj *obj = &obj_node->data; + LNK_ObjIniter *task = raw_task; + LNK_InputObj *input = task->inputs[task_id]; + LNK_Obj *obj = &task->obj_node_arr[task_id].data; + U64 obj_idx = task->obj_id_base + task_id; - String8 cached_path = push_str8_copy(arena, input->path); - String8 cached_lib_path = push_str8_copy(arena, input->lib_path); - - // parse coff obj + // + // parse obj header + // COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(input->data); - Rng1U64 coff_file_header_range = rng_1u64(0, coff_info.header_size); - Rng1U64 coff_sect_arr_range = rng_1u64(coff_info.section_array_off, coff_info.section_array_off + coff_info.section_count_no_null * sizeof(COFF_SectionHeader)); - Rng1U64 coff_symbols_range = rng_1u64(coff_info.symbol_off, coff_info.symbol_off + coff_info.symbol_count * coff_info.symbol_size); - String8 raw_coff_sect_arr = str8_substr(input->data, coff_sect_arr_range); - String8 raw_coff_symbols = str8_substr(input->data, coff_symbols_range); + String8 raw_coff_section_table = str8_substr(input->data, coff_info.section_table_range); + String8 raw_coff_symbol_table = str8_substr(input->data, coff_info.symbol_table_range); + String8 raw_coff_string_table = str8_substr(input->data, coff_info.string_table_range); - if (raw_coff_sect_arr.size != dim_1u64(coff_sect_arr_range)) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "corrupted file, unable to read section header table"); + // + // error check: section table / symbol table / string table + // + if (raw_coff_section_table.size != dim_1u64(coff_info.section_table_range)) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read section header table"); } - if (raw_coff_symbols.size != dim_1u64(coff_symbols_range)) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "corrupted file, unable to read symbol table"); + if (raw_coff_symbol_table.size != dim_1u64(coff_info.symbol_table_range)) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read symbol table"); + } + if (raw_coff_string_table.size != dim_1u64(coff_info.string_table_range)) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read string table"); } - COFF_SectionHeader *coff_sect_arr = (COFF_SectionHeader *)raw_coff_sect_arr.str; - void *coff_symbols = raw_coff_symbols.str; + U64 chunk_count = coff_info.section_count_no_null + /* :common_block */ 1; + String8 *sect_name_arr = push_array_no_zero(arena, String8, chunk_count); + String8 *sect_sort_arr = push_array_no_zero(arena, String8, chunk_count); + LNK_Chunk *chunk_arr = push_array(arena, LNK_Chunk, chunk_count); + LNK_ChunkPtr *chunk_ptr_arr = push_array_no_zero(arena, LNK_ChunkPtr, chunk_count); - // :function_pad_min - U64 function_pad_min; - if (task->function_pad_min) { - function_pad_min = *task->function_pad_min; - } else { - function_pad_min = lnk_get_default_function_pad_min(coff_info.machine); + for (U64 chunk_idx = 0; chunk_idx < chunk_count; chunk_idx += 1) { + chunk_ptr_arr[chunk_idx] = &chunk_arr[chunk_idx]; } - U64 chunk_count = 1; // :common_block - chunk_count += coff_info.section_count_no_null; + // + // setup :common_block + // - String8 *sect_name_arr = push_array_no_zero(arena, String8, chunk_count); - String8 *sect_sort_arr = push_array_no_zero(arena, String8, chunk_count); - LNK_Chunk *chunk_arr = push_array(arena, LNK_Chunk, chunk_count); - - // :common_block U64 common_block_idx = chunk_count - 1; sect_name_arr[common_block_idx] = str8_lit(".bss"); sect_sort_arr[common_block_idx] = str8_lit("~"); - for (U64 sect_idx = 0; sect_idx < coff_info.section_count_no_null; sect_idx += 1) { - COFF_SectionHeader *coff_sect = &coff_sect_arr[sect_idx]; - - // read name - String8 sect_name = coff_name_from_section_header(input->data, coff_sect, coff_info.string_table_off); - - // parse section name - coff_parse_section_name(sect_name, §_name_arr[sect_idx], §_sort_arr[sect_idx]); - - String8 data; - if (coff_sect->flags & COFF_SectionFlag_CntUninitializedData) { - data = str8(0, coff_sect->fsize); - } else { - if (coff_sect->fsize > 0) { - Rng1U64 range = rng_1u64(coff_sect->foff, coff_sect->foff + coff_sect->fsize); - data = str8_substr(input->data, range); - - if (contains_1u64(coff_file_header_range, coff_sect->foff) || - (coff_sect->fsize > 0 && contains_1u64(coff_file_header_range, coff_sect->foff + coff_sect->fsize-1))) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into file header)", sect_name, sect_idx+1); - } - if (contains_1u64(coff_sect_arr_range, coff_sect->foff) || - (coff_sect->fsize > 0 && contains_1u64(coff_sect_arr_range, coff_sect->foff + coff_sect->fsize-1))) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into section header table)", sect_name, sect_idx+1); - } - if (contains_1u64(coff_symbols_range, coff_sect->foff) || - (coff_sect->fsize > 0 && contains_1u64(coff_symbols_range, coff_sect->foff + coff_sect->fsize-1))) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into symbol table)", sect_name, sect_idx+1); - } - if (dim_1u64(range) != coff_sect->fsize) { - lnk_error_with_loc(LNK_Error_IllData, cached_path, cached_lib_path, "header (%S No. %#llx) defines out of bounds section data", sect_name, sect_idx+1); - } - } else { - data = str8_zero(); - } - } - - LNK_Chunk *chunk = &chunk_arr[sect_idx]; - chunk->align = coff_align_size_from_section_flags(coff_sect->flags); - chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LnkRemove); - chunk->sort_chunk = 1; - chunk->type = LNK_Chunk_Leaf; - chunk->sort_idx = sect_sort_arr[sect_idx]; - chunk->input_idx = LNK_MakeChunkInputIdx(obj_idx, sect_idx); - chunk->flags = coff_sect->flags; - chunk->u.leaf = data; - chunk->obj = obj; - lnk_chunk_set_debugf(arena, chunk, "obj_idx %llx isect %llx", obj_idx, sect_idx); - } - - // :common_block LNK_Chunk *master_common_block = &chunk_arr[common_block_idx]; master_common_block->ref = lnk_chunk_ref(0,0); // :chunk_ref_assign master_common_block->align = 1; @@ -427,23 +371,119 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) master_common_block->associate = 0; master_common_block->u.list = push_array(arena, LNK_ChunkList, 1); master_common_block->obj = obj; - lnk_chunk_set_debugf(arena, master_common_block, "master common block"); + lnk_chunk_set_debugf(arena, master_common_block, "obj[%llx] master common block", obj_idx); - LNK_ChunkPtr *chunk_ptr_arr = push_array_no_zero(arena, LNK_ChunkPtr, chunk_count); - for (U64 i = 0; i < chunk_count; ++i) { - chunk_ptr_arr[i] = &chunk_arr[i]; + // + // parse section table + // + COFF_SectionHeader *coff_section_table = (COFF_SectionHeader *)raw_coff_section_table.str; + for (U64 sect_idx = 0; sect_idx < coff_info.section_count_no_null; sect_idx += 1) { + COFF_SectionHeader *coff_sect_header = &coff_section_table[sect_idx]; + + // read name + String8 sect_name = coff_name_from_section_header(raw_coff_string_table, coff_sect_header); + + // parse name + coff_parse_section_name(sect_name, §_name_arr[sect_idx], §_sort_arr[sect_idx]); + + // find contents + String8 sect_data; + if (coff_sect_header->flags & COFF_SectionFlag_CntUninitializedData) { + sect_data = str8(0, coff_sect_header->fsize); + } else { + if (coff_sect_header->fsize > 0) { + Rng1U64 sect_range = rng_1u64(coff_sect_header->foff, coff_sect_header->foff + coff_sect_header->fsize); + sect_data = str8_substr(input->data, sect_range); + + if (contains_1u64(coff_info.header_range, coff_sect_header->foff) || + (coff_sect_header->fsize > 0 && contains_1u64(coff_info.header_range, sect_range.max-1))) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into file header)", sect_name, sect_idx+1); + } + if (contains_1u64(coff_info.section_table_range, coff_sect_header->foff) || + (coff_sect_header->fsize > 0 && contains_1u64(coff_info.section_table_range, sect_range.max-1))) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into section header table)", sect_name, sect_idx+1); + } + if (contains_1u64(coff_info.symbol_table_range, coff_sect_header->foff) || + (coff_sect_header->fsize > 0 && contains_1u64(coff_info.symbol_table_range, sect_range.max-1))) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into symbol table)", sect_name, sect_idx+1); + } + if (dim_1u64(sect_range) != coff_sect_header->fsize) { + lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data", sect_name, sect_idx+1); + } + } else { + sect_data = str8_zero(); + } + } + + // fill out chunk + LNK_Chunk *chunk = &chunk_arr[sect_idx]; + chunk->align = coff_align_size_from_section_flags(coff_sect_header->flags); + chunk->is_discarded = !!(coff_sect_header->flags & COFF_SectionFlag_LnkRemove); + chunk->sort_chunk = 1; + chunk->type = LNK_Chunk_Leaf; + chunk->sort_idx = sect_sort_arr[sect_idx]; + chunk->input_idx = LNK_MakeChunkInputIdx(obj_idx, sect_idx); + chunk->flags = coff_sect_header->flags; + chunk->u.leaf = sect_data; + chunk->obj = obj; + lnk_chunk_set_debugf(arena, chunk, "obj[%llx] sect[%llx]", obj_idx, sect_idx); + } + + // + // :function_pad_min + // + U64 function_pad_min; + if (task->function_pad_min) { + function_pad_min = *task->function_pad_min; + } else { + function_pad_min = lnk_get_default_function_pad_min(coff_info.machine); + } + + // + // convert from COFF + // + void *coff_symbol_table = raw_coff_symbol_table.str; + LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, obj, input->path, input->lib_path, coff_info.is_big_obj, function_pad_min, coff_info.section_count_no_null, coff_section_table, coff_info.symbol_count, coff_symbol_table, raw_coff_string_table, chunk_ptr_arr, master_common_block); + LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr); + LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_section_table, chunk_ptr_arr, symbol_arr); + + // + // parse directives + // + LNK_DirectiveInfo directive_info = lnk_directive_info_from_sections(arena, input->path, input->lib_path, coff_info.section_count_no_null, reloc_list_arr, sect_name_arr, chunk_arr); + + // parse exports + LNK_ExportParseList export_parse = {0}; + for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Export].first; dir != 0; dir = dir->next) { + lnk_parse_export_directive(arena, &export_parse, dir->value_list, input->path, input->lib_path); + } + + // push /export symbols + for (LNK_ExportParse *exp = export_parse.first; exp != 0; exp = exp->next) { + LNK_Symbol *symbol = lnk_make_undefined_symbol(arena, exp->name, LNK_SymbolScopeFlag_Main); + lnk_symbol_list_push(arena, &symbol_list, symbol); + } + + // push /include symbols + String8List include_symbol_list = {0}; + for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Include].first; dir != 0; dir = dir->next) { + str8_list_concat_in_place(&include_symbol_list, &dir->value_list); + } + + // parse /alternatename + LNK_AltNameList alt_name_list = {0}; + for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_AlternateName].first; dir != 0; dir = dir->next) { + String8 *invalid_string = lnk_parse_alt_name_directive_list(arena, dir->value_list, &alt_name_list); + if (invalid_string != 0) { + lnk_error_with_loc(LNK_Error_Cmdl, input->path, input->lib_path, "invalid syntax \"%S\", expected format \"FROM=TO\"", *invalid_string); + } } - // convert from coff - LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, cached_lib_path, coff_info.is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block); - LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr); - LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_ptr_arr, symbol_arr); - LNK_DirectiveInfo directive_info = lnk_directive_info_from_sections(arena, cached_path, cached_lib_path, coff_info.section_count_no_null, reloc_list_arr, sect_name_arr, chunk_arr); // fill out obj obj->data = input->data; - obj->path = cached_path; - obj->lib_path = cached_lib_path; + obj->path = push_str8_copy(arena, input->path); + obj->lib_path = push_str8_copy(arena, input->lib_path); obj->input_idx = obj_idx; obj->machine = coff_info.machine; obj->chunk_count = chunk_count; @@ -454,33 +494,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) obj->symbol_list = symbol_list; obj->sect_reloc_list_arr = reloc_list_arr; obj->directive_info = directive_info; - - // parse exports - LNK_ExportParseList export_parse = {0}; - for (LNK_Directive *dir = obj->directive_info.v[LNK_CmdSwitch_Export].first; dir != 0; dir = dir->next) { - lnk_parse_export_directive(arena, &obj->export_parse, dir->value_list, obj->path, obj->lib_path); - } - - // push /export symbols - for (LNK_ExportParse *exp = export_parse.first; exp != 0; exp = exp->next) { - LNK_Symbol *symbol = lnk_make_undefined_symbol(arena, exp->name, LNK_SymbolScopeFlag_Main); - lnk_symbol_list_push(arena, &obj->symbol_list, symbol); - } - - // push /include symbols - for (LNK_Directive *dir = obj->directive_info.v[LNK_CmdSwitch_Include].first; dir != 0; dir = dir->next) { - str8_list_concat_in_place(&obj->include_symbol_list, &dir->value_list); - } - - // parse /alternatename - for (LNK_Directive *dir = obj->directive_info.v[LNK_CmdSwitch_AlternateName].first; dir != 0; dir = dir->next) { - String8 *invalid_string = lnk_parse_alt_name_directive_list(arena, dir->value_list, &obj->alt_name_list); - if (invalid_string != 0) { - lnk_error_obj(LNK_Error_Cmdl, obj, "invalid syntax \"%S\", expected format \"FROM=TO\"", *invalid_string); - } - } - - scratch_end(scratch); + obj->export_parse = export_parse; + obj->include_symbol_list = include_symbol_list; + obj->alt_name_list = alt_name_list; } internal @@ -528,14 +544,14 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_counter) LNK_ChunkCounter *task = raw_task; LNK_Obj *obj = &task->obj_arr[obj_idx].data; for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) { - String8 name = obj->sect_name_arr[chunk_idx]; + String8 name = obj->sect_name_arr[chunk_idx]; LNK_Chunk *chunk = obj->chunk_arr[chunk_idx]; LNK_Section *sect = lnk_section_table_search(task->st, name); U64 count = 0; lnk_visit_chunks(0, chunk, lnk_chunk_get_count_cb, &count); - task->chunk_count_arr_arr[sect->id][obj_idx] += count; + task->chunk_counts[sect->id][obj_idx] += count; } } @@ -545,8 +561,8 @@ LNK_CHUNK_VISITOR_SIG(lnk_chunk_ref_assign) LNK_ChunkRefAssign *ctx = ud; // alloc chunk id - U64 chunk_id = ctx->chunk_id_arr_arr[sect_id][ctx->obj_idx]; - ctx->chunk_id_arr_arr[sect_id][ctx->obj_idx] += 1; + U64 chunk_id = *ctx->chunk_id; + *ctx->chunk_id += 1; // set chunk ref chunk->ref = lnk_chunk_ref(sect_id, chunk_id); @@ -571,13 +587,11 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_ref_assigner) // :find_chunk_section LNK_Section *sect = lnk_section_table_search(task->st, name); - Assert(sect); // :chunk_ref_assign - LNK_ChunkRefAssign ctx; - ctx.cman = sect->cman; - ctx.chunk_id_arr_arr = task->chunk_id_arr_arr; - ctx.obj_idx = obj_idx; + LNK_ChunkRefAssign ctx = {0}; + ctx.cman = sect->cman; + ctx.chunk_id = &task->chunk_ids[sect->id][obj_idx]; lnk_visit_chunks(sect->id, chunk, lnk_chunk_ref_assign, &ctx); // push to section chunk list @@ -684,27 +698,27 @@ lnk_obj_list_push_parallel(TP_Context *tp, ProfEnd(); ProfBegin("Count Chunks Per Section"); - U64 **chunk_id_arr_arr; + U64 **chunk_ids; { - U64 **chunk_count_arr_arr = push_array_no_zero(scratch.arena, U64 *, st->id_max); + U64 **chunk_counts = push_array_no_zero(scratch.arena, U64 *, st->id_max); for (U64 sect_idx = 0; sect_idx < st->id_max; sect_idx += 1) { - chunk_count_arr_arr[sect_idx] = push_array(scratch.arena, U64, obj_arr.count); + chunk_counts[sect_idx] = push_array(scratch.arena, U64, obj_arr.count); } - LNK_ChunkCounter task; - task.st = st; - task.obj_arr = obj_arr.v; - task.chunk_count_arr_arr = chunk_count_arr_arr; + LNK_ChunkCounter task = {0}; + task.st = st; + task.obj_arr = obj_arr.v; + task.chunk_counts = chunk_counts; tp_for_parallel(tp, 0, obj_arr.count, lnk_chunk_counter, &task); - chunk_id_arr_arr = chunk_count_arr_arr; + chunk_ids = chunk_counts; for (U64 sect_idx = 1; sect_idx < st->id_max; sect_idx += 1) { LNK_Section *sect = lnk_section_table_search_id(st, sect_idx); if (!sect) continue; for (U64 obj_idx = 0; obj_idx < obj_arr.count; obj_idx += 1) { U64 chunk_id_base = sect->cman->total_chunk_count; - sect->cman->total_chunk_count += chunk_count_arr_arr[sect_idx][obj_idx]; - chunk_id_arr_arr[sect_idx][obj_idx] = chunk_id_base; + sect->cman->total_chunk_count += chunk_counts[sect_idx][obj_idx]; + chunk_ids[sect_idx][obj_idx] = chunk_id_base; } } } @@ -715,7 +729,7 @@ lnk_obj_list_push_parallel(TP_Context *tp, LNK_ChunkRefAssigner task; task.st = st; task.range_arr = tp_divide_work(scratch.arena, obj_arr.count, tp->worker_count); - task.chunk_id_arr_arr = chunk_id_arr_arr; + task.chunk_ids = chunk_ids; task.obj_arr = obj_arr.v; task.nosort_chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, st->id_max, tp->worker_count); task.chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, st->id_max, tp->worker_count); @@ -738,28 +752,27 @@ lnk_obj_list_push_parallel(TP_Context *tp, internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, - String8 raw_coff, LNK_Obj *obj, String8 obj_path, String8 lib_path, B32 is_big_obj, U64 function_pad_min, - U64 string_table_off, U64 sect_count, - COFF_SectionHeader *coff_sect_arr, - U64 coff_symbol_count, - void *coff_symbols, - LNK_ChunkPtr *chunk_ptr_arr, + COFF_SectionHeader *section_table, + U64 symbol_count, + void *symbol_table, + String8 string_table, + LNK_ChunkPtr *chunk_table, LNK_Chunk *master_common_block) { if (function_pad_min) { COFF_ParsedSymbol symbol; - for (U64 symbol_idx = 0; symbol_idx < coff_symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { + for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { // read symbol if (is_big_obj) { - symbol = coff_parse_symbol32(raw_coff, string_table_off, &((COFF_Symbol32 *)coff_symbols)[symbol_idx]); + symbol = coff_parse_symbol32(string_table, &((COFF_Symbol32 *)symbol_table)[symbol_idx]); } else { - symbol = coff_parse_symbol16(raw_coff, string_table_off, &((COFF_Symbol16 *)coff_symbols)[symbol_idx]); + symbol = coff_parse_symbol16(string_table, &((COFF_Symbol16 *)symbol_table)[symbol_idx]); } // is this a function symbol? @@ -768,11 +781,11 @@ lnk_symbol_array_from_coff(Arena *arena, if (symbol.section_number == 0 || symbol.section_number > sect_count) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "out ouf bounds section index in symbol \"%S (%u)\"", symbol.name, symbol.section_number); } - if (symbol.value > coff_sect_arr[symbol.section_number-1].fsize) { + if (symbol.value > section_table[symbol.section_number-1].fsize) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "out of bounds section offset in symbol \"%S (%u)\"", symbol.name, symbol.value); } - LNK_Chunk *chunk = chunk_ptr_arr[symbol.section_number-1]; + LNK_Chunk *chunk = chunk_table[symbol.section_number-1]; if (symbol.value > 0) { // convert leaf to list // @@ -805,7 +818,7 @@ lnk_symbol_array_from_coff(Arena *arena, chunk = chunk_list; // set list chunk to be head of this section - chunk_ptr_arr[symbol.section_number-1] = chunk_list; + chunk_table[symbol.section_number-1] = chunk_list; } // find chunk that is near symbol @@ -860,23 +873,23 @@ lnk_symbol_array_from_coff(Arena *arena, } LNK_SymbolArray symbol_array = {0}; - symbol_array.count = coff_symbol_count; + symbol_array.count = symbol_count; symbol_array.v = push_array(arena, LNK_Symbol, symbol_array.count); COFF_ParsedSymbol parsed_symbol; - for (U64 symbol_idx = 0; symbol_idx < coff_symbol_count; symbol_idx += (1 + parsed_symbol.aux_symbol_count)) { + for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += (1 + parsed_symbol.aux_symbol_count)) { void *aux_symbols; if (is_big_obj) { - COFF_Symbol32 *ptr = &((COFF_Symbol32 *)coff_symbols)[symbol_idx]; - parsed_symbol = coff_parse_symbol32(raw_coff, string_table_off, ptr); - aux_symbols = parsed_symbol.aux_symbol_count ? ptr+1 : 0; + COFF_Symbol32 *ptr = &((COFF_Symbol32 *)symbol_table)[symbol_idx]; + parsed_symbol = coff_parse_symbol32(string_table, ptr); + aux_symbols = parsed_symbol.aux_symbol_count ? ptr+1 : 0; } else { - COFF_Symbol16 *ptr = (COFF_Symbol16 *)coff_symbols + symbol_idx; - parsed_symbol = coff_parse_symbol16(raw_coff, string_table_off, ptr); - aux_symbols = parsed_symbol.aux_symbol_count ? ptr+1 : 0; + COFF_Symbol16 *ptr = (COFF_Symbol16 *)symbol_table + symbol_idx; + parsed_symbol = coff_parse_symbol16(string_table, ptr); + aux_symbols = parsed_symbol.aux_symbol_count ? ptr+1 : 0; } - if (symbol_idx + parsed_symbol.aux_symbol_count + 1 > coff_symbol_count) { + if (symbol_idx + parsed_symbol.aux_symbol_count + 1 > symbol_count) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out of bounds aux symbol count %llu", parsed_symbol.name, symbol_idx, parsed_symbol.aux_symbol_count); } @@ -886,7 +899,7 @@ lnk_symbol_array_from_coff(Arena *arena, if (parsed_symbol.section_number == 0 || parsed_symbol.section_number > sect_count) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out ouf bounds section index %x", parsed_symbol.name, symbol_idx, parsed_symbol.section_number); } - if (parsed_symbol.value > coff_sect_arr[parsed_symbol.section_number-1].fsize) { + if (parsed_symbol.value > section_table[parsed_symbol.section_number-1].fsize) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out of bounds section offset %x into section %x", parsed_symbol.name, symbol_idx, parsed_symbol.value, parsed_symbol.section_number); } @@ -901,13 +914,13 @@ lnk_symbol_array_from_coff(Arena *arena, } - LNK_Chunk *chunk = chunk_ptr_arr[parsed_symbol.section_number-1]; + LNK_Chunk *chunk = chunk_table[parsed_symbol.section_number-1]; U64 offset = parsed_symbol.value; COFF_ComdatSelectType selection = COFF_ComdatSelect_Any; U64 check_sum = 0; - B32 is_comdat = (coff_sect_arr[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LnkCOMDAT) && + B32 is_comdat = (section_table[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LnkCOMDAT) && parsed_symbol.value == 0 && parsed_symbol.aux_symbol_count > 0 && parsed_symbol.type.u.lsb == COFF_SymType_Null && @@ -929,8 +942,8 @@ lnk_symbol_array_from_coff(Arena *arena, // associate chunks if (secdef_number > 0 && secdef_number <= sect_count) { - LNK_Chunk *head_chunk = chunk_ptr_arr[secdef_number-1]; - LNK_Chunk *associate_chunk = chunk_ptr_arr[parsed_symbol.section_number-1]; + LNK_Chunk *head_chunk = chunk_table[secdef_number-1]; + LNK_Chunk *associate_chunk = chunk_table[parsed_symbol.section_number-1]; lnk_chunk_associate(head_chunk, associate_chunk); } else { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out of bounds section definition number %u", parsed_symbol.name, symbol_idx, secdef_number); @@ -964,7 +977,7 @@ lnk_symbol_array_from_coff(Arena *arena, } COFF_SymbolWeakExt *weak_ext = aux_symbols; - if (weak_ext->tag_index >= coff_symbol_count) { + if (weak_ext->tag_index >= symbol_count) { lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "weak symbol \"%S (%u)\" points to out of bounds symbol", parsed_symbol.name, symbol_idx); } @@ -1029,10 +1042,10 @@ lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 c { LNK_RelocList *reloc_list_arr = push_array_no_zero(arena, LNK_RelocList, sect_count); for (U64 sect_idx = 0; sect_idx < sect_count; ++sect_idx) { - COFF_SectionHeader *COFF_FileHeader = &coff_sect_arr[sect_idx]; - COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, COFF_FileHeader); - COFF_Reloc *coff_reloc_v = (COFF_Reloc *)(coff_data.str + coff_reloc_info.array_off); - LNK_Chunk *sect_chunk = chunk_ptr_arr[sect_idx]; + COFF_SectionHeader *coff_sect_header = &coff_sect_arr[sect_idx]; + COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, coff_sect_header); + COFF_Reloc *coff_reloc_v = (COFF_Reloc *)(coff_data.str + coff_reloc_info.array_off); + LNK_Chunk *sect_chunk = chunk_ptr_arr[sect_idx]; reloc_list_arr[sect_idx] = lnk_reloc_list_from_coff_reloc_array(arena, machine, sect_chunk, symbol_array, coff_reloc_v, coff_reloc_info.count); } return reloc_list_arr; diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index fa821460..876557ea 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -128,21 +128,20 @@ typedef struct { LNK_SectionTable *st; LNK_ObjNode *obj_arr; - U64 **chunk_count_arr_arr; + U64 **chunk_counts; } LNK_ChunkCounter; typedef struct { LNK_ChunkManager *cman; - U64 **chunk_id_arr_arr; - U64 obj_idx; + U64 *chunk_id; } LNK_ChunkRefAssign; typedef struct { LNK_SectionTable *st; Rng1U64 *range_arr; - U64 **chunk_id_arr_arr; + U64 **chunk_ids; LNK_ObjNode *obj_arr; LNK_ChunkList **nosort_chunk_list_arr_arr; LNK_ChunkList **chunk_list_arr_arr; @@ -202,7 +201,7 @@ internal LNK_ChunkList * lnk_collect_obj_chunks(TP_Context *tp, TP_Arena *arena internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 *function_pad_min, U64 input_count, LNK_InputObj **inputs); internal LNK_Chunk * lnk_sect_chunk_array_from_coff(Arena *arena, U64 obj_id, String8 obj_path, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, String8 *sect_name_arr, String8 *sect_postfix_arr); -internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, LNK_Obj *obj, String8 obj_path, String8 lib_path, B32 is_big_obj, U64 function_pad_min, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, U64 coff_symbol_count, void *coff_symbols, LNK_ChunkPtr *chunk_ptr_arr, LNK_Chunk *master_common_block); +internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, LNK_Obj *obj, String8 obj_path, String8 lib_path, B32 is_big_obj, U64 function_pad_min, U64 sect_count, COFF_SectionHeader *section_table, U64 symbol_count, void *symbol_table, String8 string_table, LNK_ChunkPtr *chunk_table, LNK_Chunk *master_common_block); internal LNK_RelocList lnk_reloc_list_from_coff_reloc_array(Arena *arena, COFF_MachineType machine, LNK_Chunk *chunk, LNK_SymbolArray symbol_array, COFF_Reloc *reloc_v, U64 reloc_count); internal LNK_RelocList * lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_ChunkPtr *chunk_ptr_arr, LNK_SymbolArray symbol_array); internal LNK_DirectiveInfo lnk_directive_info_from_sections(Arena *arena, String8 obj_path, String8 lib_path, U64 chunk_count, LNK_RelocList *reloc_list_arr, String8 *sect_name_arr, LNK_Chunk *chunk_arr); diff --git a/src/pe/pe.c b/src/pe/pe.c index b631386f..36c9e423 100644 --- a/src/pe/pe.c +++ b/src/pe/pe.c @@ -600,20 +600,20 @@ pe_bin_info_from_data(Arena *arena, String8 data) // rjf: fill info if(valid) { - info.image_base = image_base; - info.entry_point = entry_point; - info.is_pe32 = (optional_magic == PE_PE32_MAGIC); - info.virt_section_align = virt_section_align; - info.file_section_align = file_section_align; - info.section_array_off = sec_array_off; - info.section_count = clamped_sec_count; - info.symbol_array_off = symbol_array_off; - info.symbol_count = symbol_count; - info.string_table_off = string_table_off; - info.data_dir_franges = data_dir_franges; - info.data_dir_count = data_dir_count; - info.arch = arch_from_coff_machine(file_header.machine); - info.tls_header = tls_header; + info.arch = arch_from_coff_machine(file_header.machine); + info.image_base = image_base; + info.entry_point = entry_point; + info.is_pe32 = (optional_magic == PE_PE32_MAGIC); + info.virt_section_align = virt_section_align; + info.file_section_align = file_section_align; + info.section_count = clamped_sec_count; + info.symbol_count = symbol_count; + info.section_table_range = rng_1u64(sec_array_off, sec_array_off + sizeof(COFF_SectionHeader) * clamped_sec_count); + info.symbol_table_range = rng_1u64(symbol_array_off, symbol_array_off + sizeof(COFF_Symbol16) * symbol_count); + info.string_table_range = rng_1u64(string_table_off, data.size); + info.data_dir_franges = data_dir_franges; + info.data_dir_count = data_dir_count; + info.tls_header = tls_header; } return info; @@ -762,80 +762,15 @@ pe_pdata_off_from_voff__binary_search_x8664(String8 raw_pdata, U64 voff) return result; } -internal void * -pe_ptr_from_voff(String8 data, PE_BinInfo *bin, U64 voff) -{ - // rjf: get the section for this voff - U64 sec_count = bin->section_count; - COFF_SectionHeader *sec_array = (COFF_SectionHeader*)((U8*)data.str + bin->section_array_off); - COFF_SectionHeader *sec_ptr = sec_array; - COFF_SectionHeader *sec = 0; - for(U64 i = 1; i <= sec_count; i += 1, sec_ptr += 1) - { - if(sec_ptr->voff <= voff && voff < sec_ptr->voff + sec_ptr->vsize) - { - sec = sec_ptr; - break; - } - } - - // rjf: adjust to file pointer - void *result = 0; - if(sec != 0 && sec_ptr->fsize > 0) - { - U64 off = voff - sec->voff + sec->foff; - if(off < data.size) - { - result = data.str + off; - } - } - return result; -} - -internal U64 -pe_section_num_from_voff(String8 data, PE_BinInfo *bin, U64 voff) -{ - U64 sec_count = bin->section_count; - COFF_SectionHeader *sec_array = (COFF_SectionHeader*)((U8*)data.str + bin->section_array_off); - COFF_SectionHeader *sec_ptr = sec_array; - U64 result = 0; - for(U64 i = 1; i <= sec_count; i += 1, sec_ptr += 1) - { - if(sec_ptr->voff <= voff && voff < sec_ptr->voff + sec_ptr->vsize) - { - result = i; - break; - } - } - return result; -} - -internal void * -pe_ptr_from_section_num(String8 data, PE_BinInfo *bin, U64 n) -{ - void *result = 0; - U64 sec_count = bin->section_count; - if(1 <= n && n <= sec_count) - { - COFF_SectionHeader *sec_array = (COFF_SectionHeader*)((U8*)data.str + bin->section_array_off); - COFF_SectionHeader *sec = sec_array + n - 1; - if(sec->fsize > 0) - { - result = data.str + sec->foff; - } - } - return(result); -} - internal U64 pe_foff_from_voff(String8 data, PE_BinInfo *bin, U64 voff) { - U64 foff = 0; - COFF_SectionHeader *sections = (COFF_SectionHeader*)(data.str+bin->section_array_off); - U64 section_count = bin->section_count; - for(U64 sect_idx = 0; sect_idx < section_count; sect_idx += 1) + U64 foff = 0; + String8 raw_section_table = str8_substr(data, bin->section_table_range); + COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_section_table.str; + for(U64 sect_idx = 0; sect_idx < bin->section_count; sect_idx += 1) { - COFF_SectionHeader *sect = §ions[sect_idx]; + COFF_SectionHeader *sect = §ion_table[sect_idx]; if(sect->voff <= voff && voff < sect->voff + sect->vsize) { if(!(sect->flags & COFF_SectionFlag_CntUninitializedData)) diff --git a/src/pe/pe.h b/src/pe/pe.h index 8ff6a741..7dadd496 100644 --- a/src/pe/pe.h +++ b/src/pe/pe.h @@ -993,17 +993,17 @@ struct PE_HandlerScope typedef struct PE_BinInfo PE_BinInfo; struct PE_BinInfo { + Arch arch; U64 image_base; U64 entry_point; B32 is_pe32; U64 virt_section_align; U64 file_section_align; - U64 section_array_off; U64 section_count; - U64 symbol_array_off; U64 symbol_count; - U64 string_table_off; - Arch arch; + Rng1U64 section_table_range; + Rng1U64 symbol_table_range; + Rng1U64 string_table_range; Rng1U64 *data_dir_franges; U32 data_dir_count; PE_TLSHeader64 tls_header; @@ -1085,9 +1085,6 @@ internal PE_ParsedTLS pe_tls_from_data(Arena *arena, COFF_MachineT //~ rjf: Helpers internal U64 pe_pdata_off_from_voff__binary_search_x8664(String8 raw_data, U64 voff); -internal void * pe_ptr_from_voff(String8 data, PE_BinInfo *bin, U64 voff); -internal U64 pe_section_num_from_voff(String8 data, PE_BinInfo *bin, U64 voff); -internal void * pe_ptr_from_section_num(String8 data, PE_BinInfo *bin, U64 n); internal U64 pe_foff_from_voff(String8 data, PE_BinInfo *bin, U64 voff); internal PE_BaseRelocBlockList pe_base_reloc_block_list_from_data(Arena *arena, String8 raw_relocs); internal Rng1U64 pe_tls_rng_from_bin_base_vaddr(String8 data, PE_BinInfo *bin, U64 base_vaddr); diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index 9d6101f1..c66e40ea 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -208,11 +208,12 @@ rc_context_from_cmd_line(Arena *arena, CmdLine *cmdl) } if (driver == RC_Driver_Null || driver == RC_Driver_Dwarf) { - PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); - String8 raw_sections = str8_substr(pe_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); - U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); - COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; - if (dw_is_dwarf_present_coff_section_table(pe_data, pe.string_table_off, section_count, section_array)) { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, pe_data); + String8 raw_section_table = str8_substr(pe_data, pe.section_table_range); + String8 string_table = str8_substr(pe_data, pe.string_table_range); + U64 section_count = raw_section_table.size / sizeof(COFF_SectionHeader); + COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_section_table.str; + if (dw_is_dwarf_present_coff_section_table(pe_data, string_table, section_count, section_table)) { driver = RC_Driver_Dwarf; debug_name = pe_name; debug_data = pe_data; diff --git a/src/radcon/radcon_coff.c b/src/radcon/radcon_coff.c index 35c6a23d..08f40a4a 100644 --- a/src/radcon/radcon_coff.c +++ b/src/radcon/radcon_coff.c @@ -56,7 +56,7 @@ c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags) } internal RDIM_BinarySectionList -c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 string_table_off, U64 sectab_count, COFF_SectionHeader *sectab) +c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, String8 string_table, U64 sectab_count, COFF_SectionHeader *sectab) { ProfBeginFunction(); @@ -66,7 +66,7 @@ c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 COFF_SectionHeader *coff_sec = §ab[isec]; RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections); - sec->name = coff_name_from_section_header(image_data, coff_sec, string_table_off); + sec->name = coff_name_from_section_header(string_table, coff_sec); sec->flags = c2r_rdi_binary_section_flags_from_coff_section_flags(coff_sec->flags); sec->voff_first = coff_sec->voff; sec->voff_opl = coff_sec->voff + coff_sec->vsize; diff --git a/src/radcon/radcon_coff.h b/src/radcon/radcon_coff.h index 57cf7a47..252874fd 100644 --- a/src/radcon/radcon_coff.h +++ b/src/radcon/radcon_coff.h @@ -6,7 +6,7 @@ internal RDI_Arch c2r_rdi_arch_from_coff_machine(COFF_MachineType machine); internal RDI_BinarySectionFlags c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags); -internal RDIM_BinarySectionList c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, U64 string_table_off, U64 sectab_count, COFF_SectionHeader *sectab); +internal RDIM_BinarySectionList c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, String8 string_table, U64 sectab_count, COFF_SectionHeader *sectab); #endif // RADCON_COFF_H diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 4cfd0ca6..e2b6af54 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -1101,15 +1101,16 @@ d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) image_base = pe.image_base; // get image sections - String8 raw_sections = str8_substr(in->image_data, rng_1u64(pe.section_array_off, pe.section_array_off+sizeof(COFF_SectionHeader)*pe.section_count)); + String8 raw_sections = str8_substr(in->image_data, pe.section_table_range); U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); - COFF_SectionHeader *section_array = (COFF_SectionHeader *)raw_sections.str; + COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_sections.str; // convert sections - binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, in->image_data, pe.string_table_off, section_count, section_array); + String8 string_table = str8_substr(in->image_data, pe.string_table_range); + binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, in->image_data, string_table, section_count, section_table); // make DWARF input - input = dw_input_from_coff_section_table(scratch.arena, in->image_data, pe.string_table_off, section_count, section_array); + input = dw_input_from_coff_section_table(scratch.arena, in->image_data, string_table, section_count, section_table); } else if (in->image == Image_Elf32 || in->image == Image_Elf64) { ELF_BinInfo elf = elf_bin_from_data(in->debug_data); diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index ca9a4f7d..453c5b75 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -2366,7 +2366,7 @@ p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) ////////////////////////////////////////////////////////////// //- rjf: build binary sections list // - RDIM_BinarySectionList binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, str8_zero(), 0, coff_sections.count, coff_sections.v); + RDIM_BinarySectionList binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, str8_zero(), str8_zero(), coff_sections.count, coff_sections.v); ////////////////////////////////////////////////////////////// //- rjf: produce top-level-info diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 52f76b9c..b3ecb678 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -396,7 +396,7 @@ rd_section_markers_from_rdi(Arena *arena, RDI_Parsed *rdi) } internal RD_MarkerArray * -rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 string_table_off, U64 section_count, COFF_Symbol32Array symbols) +rd_section_markers_from_coff_symbol_table(Arena *arena, String8 string_table, U64 section_count, COFF_Symbol32Array symbols) { Temp scratch = scratch_begin(&arena, 1); @@ -411,7 +411,7 @@ rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 st (symbol->storage_class == COFF_SymStorageClass_External || symbol->storage_class == COFF_SymStorageClass_Static); if (is_marker) { - String8 name = coff_read_symbol_name(raw_data, string_table_off, &symbol->name); + String8 name = coff_read_symbol_name(string_table, &symbol->name); RD_MarkerNode *n = push_array(scratch.arena, RD_MarkerNode, 1); n->v.off = symbol->value; @@ -5853,14 +5853,14 @@ cv_print_symbols_section(Arena *arena, } internal void -cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8 raw_image, U64 string_table_off, U64 section_count, COFF_SectionHeader *sections) +cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *sections) { CV_Arch arch = ~0; { B32 keep_parsing = 1; for (U64 i = 0; i < section_count && keep_parsing; ++i) { COFF_SectionHeader *header = §ions[i]; - String8 sect_name = coff_name_from_section_header(raw_image, header, string_table_off); + String8 sect_name = coff_name_from_section_header(string_table, header); Rng1U64 sect_frange = rng_1u64(header->foff, header->foff+header->fsize); String8 raw_sect = str8_substr(raw_image, sect_frange); if (str8_match_lit(".debug$S", sect_name, 0)) { @@ -5908,7 +5908,7 @@ cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8 for (U64 i = 0; i < section_count; ++i) { COFF_SectionHeader *header = §ions[i]; - String8 sect_name = coff_name_from_section_header(raw_image, header, string_table_off); + String8 sect_name = coff_name_from_section_header(string_table, header); Rng1U64 sect_frange = rng_1u64(header->foff, header->foff+header->fsize); String8 raw_sect = str8_substr(raw_image, sect_frange); if (str8_match_lit(".debug$S", sect_name, 0)) { @@ -5957,35 +5957,34 @@ coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, } internal void -coff_print_seciton_table(Arena *arena, +coff_print_section_table(Arena *arena, String8List *out, String8 indent, - String8 raw_data, - U64 string_table_off, - COFF_Symbol32Array symbols, - U64 sect_count, - COFF_SectionHeader *sect_headers) + String8 string_table, + COFF_Symbol32Array symbol_table, + U64 section_count, + COFF_SectionHeader *section_table) { Temp scratch = scratch_begin(&arena, 1); - String8 *symlinks = push_array(scratch.arena, String8, sect_count); - for (U64 i = 0; i < symbols.count; ++i) { - COFF_Symbol32 *symbol = symbols.v+i; + String8 *symlinks = push_array(scratch.arena, String8, section_count); + for (U64 i = 0; i < symbol_table.count; ++i) { + COFF_Symbol32 *symbol = symbol_table.v+i; COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol->section_number, symbol->value, symbol->storage_class); if (interp == COFF_SymbolValueInterp_Regular && symbol->aux_symbol_count == 0 && (symbol->storage_class == COFF_SymStorageClass_External || symbol->storage_class == COFF_SymStorageClass_Static)) { - if (symbol->section_number > 0 && symbol->section_number <= symbols.count) { - COFF_SectionHeader *header = sect_headers+(symbol->section_number-1); + if (symbol->section_number > 0 && symbol->section_number <= symbol_table.count) { + COFF_SectionHeader *header = section_table+(symbol->section_number-1); if (header->flags & COFF_SectionFlag_LnkCOMDAT) { - symlinks[symbol->section_number-1] = coff_read_symbol_name(raw_data, string_table_off, &symbol->name); + symlinks[symbol->section_number-1] = coff_read_symbol_name(string_table, &symbol->name); } } } i += symbol->aux_symbol_count; } - if (sect_count) { + if (section_count) { rd_printf("# Section Table"); rd_indent(); @@ -6004,11 +6003,11 @@ coff_print_seciton_table(Arena *arena, "Flags", "Symlink"); - for (U64 i = 0; i < sect_count; ++i) { - COFF_SectionHeader *header = sect_headers+i; + for (U64 i = 0; i < section_count; ++i) { + COFF_SectionHeader *header = section_table+i; String8 name = str8_cstring_capped(header->name, header->name+sizeof(header->name)); - String8 full_name = coff_name_from_section_header(raw_data, header, string_table_off); + String8 full_name = coff_name_from_section_header(string_table, header); String8 align; { @@ -6188,13 +6187,13 @@ coff_raw_data_sections(Arena *arena, String8 indent, String8 raw_data, B32 is_obj, - RD_MarkerArray *section_markers, + RD_MarkerArray *section_markers, U64 section_count, - COFF_SectionHeader *sections) + COFF_SectionHeader *section_table) { if (section_count) { for (U64 sect_idx = 0; sect_idx < section_count; ++sect_idx) { - COFF_SectionHeader *sect = sections+sect_idx; + COFF_SectionHeader *sect = section_table+sect_idx; if (sect->fsize > 0) { U64 sect_size = is_obj ? sect->fsize : sect->vsize; String8 raw_sect = str8_substr(raw_data, rng_1u64(sect->foff, sect->foff+sect_size)); @@ -6215,7 +6214,7 @@ coff_print_relocs(Arena *arena, String8List *out, String8 indent, String8 raw_data, - U64 string_table_off, + String8 string_table, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, @@ -6263,7 +6262,7 @@ coff_print_relocs(Arena *arena, } COFF_Symbol32 *symbol = symbols.v+reloc->isymbol; - String8 symbol_name = coff_read_symbol_name(raw_data, string_table_off, &symbol->name); + String8 symbol_name = coff_read_symbol_name(string_table, &symbol->name); String8List line = {0}; str8_list_pushf(scratch.arena, &line, "%-4x", reloc_idx ); @@ -6294,7 +6293,7 @@ coff_print_symbol_table(Arena *arena, String8 indent, String8 raw_data, B32 is_big_obj, - U64 string_table_off, + String8 string_table, COFF_Symbol32Array symbols) { Temp scratch = scratch_begin(&arena, 1); @@ -6308,7 +6307,7 @@ coff_print_symbol_table(Arena *arena, for (U64 i = 0; i < symbols.count; ++i) { COFF_Symbol32 *symbol = &symbols.v[i]; - String8 name = coff_read_symbol_name(raw_data, string_table_off, &symbol->name); + String8 name = coff_read_symbol_name(string_table, &symbol->name); String8 msb = coff_string_from_sym_dtype(symbol->type.u.msb); String8 lsb = coff_string_from_sym_type(symbol->type.u.lsb); String8 storage_class = coff_string_from_sym_storage_class(symbol->storage_class); @@ -6460,10 +6459,15 @@ coff_print_big_obj(Arena *arena, String8List *out, String8 indent, String8 raw_d { Temp scratch = scratch_begin(&arena, 1); - COFF_BigObjHeader *big_obj = str8_deserial_get_raw_ptr(raw_data, 0, sizeof(COFF_BigObjHeader)); - COFF_SectionHeader *sections = str8_deserial_get_raw_ptr(raw_data, sizeof(COFF_BigObjHeader), sizeof(COFF_SectionHeader)*big_obj->section_count); - U64 string_table_off = big_obj->symbol_table_foff + sizeof(COFF_Symbol32)*big_obj->symbol_count; - COFF_Symbol32Array symbols = coff_symbol_array_from_data_32(scratch.arena, raw_data, big_obj->symbol_table_foff, big_obj->symbol_count); + COFF_FileHeaderInfo header_info = coff_file_header_info_from_data(raw_data); + + String8 raw_header = str8_substr(raw_data, header_info.header_range); + String8 raw_section_table = str8_substr(raw_data, header_info.section_table_range); + String8 raw_string_table = str8_substr(raw_data, header_info.string_table_range); + + COFF_BigObjHeader *big_obj = (COFF_BigObjHeader *)raw_header.str; + COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_section_table.str; + COFF_Symbol32Array symbol_table = coff_symbol_array_from_data_32(scratch.arena, raw_data, header_info.symbol_table_range.min, big_obj->symbol_count); if (opts & RD_Option_Headers) { coff_print_big_obj_header(arena, out, indent, big_obj); @@ -6490,17 +6494,17 @@ coff_print_big_obj(Arena *arena, String8List *out, String8 indent, String8 raw_d } } - coff_print_seciton_table(arena, out, indent, raw_data, string_table_off, symbols, big_obj->section_count, sections); + coff_print_section_table(arena, out, indent, raw_string_table, symbol_table, big_obj->section_count, section_table); rd_newline(); } if (opts & RD_Option_Relocs) { - coff_print_relocs(arena, out, indent, raw_data, string_table_off, big_obj->machine, big_obj->section_count, sections, symbols); + coff_print_relocs(arena, out, indent, raw_data, raw_string_table, big_obj->machine, big_obj->section_count, section_table, symbol_table); rd_newline(); } if (opts & RD_Option_Symbols) { - coff_print_symbol_table(arena, out, indent, raw_data, 1, string_table_off, symbols); + coff_print_symbol_table(arena, out, indent, raw_data, 1, raw_string_table, symbol_table); rd_newline(); } @@ -6513,11 +6517,16 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, { Temp scratch = scratch_begin(&arena, 1); - COFF_FileHeader *header = (COFF_FileHeader *)raw_data.str; - COFF_SectionHeader *sections = (COFF_SectionHeader *)(header+1); - U64 string_table_off = header->symbol_table_foff + sizeof(COFF_Symbol16)*header->symbol_count; - COFF_Symbol32Array symbols = coff_symbol_array_from_data_16(scratch.arena, raw_data, header->symbol_table_foff, header->symbol_count); - Arch arch = arch_from_coff_machine(header->machine); + COFF_FileHeaderInfo header_info = coff_file_header_info_from_data(raw_data); + + String8 raw_header = str8_substr(raw_data, header_info.header_range); + String8 raw_section_table = str8_substr(raw_data, header_info.section_table_range); + String8 raw_string_table = str8_substr(raw_data, header_info.string_table_range); + + COFF_FileHeader *header = (COFF_FileHeader *)raw_header.str; + COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_section_table.str; + COFF_Symbol32Array symbol_table = coff_symbol_array_from_data_16(scratch.arena, raw_data, header_info.symbol_table_range.min, header->symbol_count); + Arch arch = arch_from_coff_machine(header->machine); if (opts & RD_Option_Headers) { coff_print_file_header(arena, out, indent, header); @@ -6544,40 +6553,40 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data, } } - coff_print_seciton_table(arena, out, indent, raw_data, string_table_off, symbols, header->section_count, sections); + coff_print_section_table(arena, out, indent, raw_string_table, symbol_table, header->section_count, section_table); rd_newline(); } if (opts & RD_Option_Relocs) { - coff_print_relocs(arena, out, indent, raw_data, string_table_off, header->machine, header->section_count, sections, symbols); + coff_print_relocs(arena, out, indent, raw_data, raw_string_table, header->machine, header->section_count, section_table, symbol_table); rd_newline(); } if (opts & RD_Option_Symbols) { - coff_print_symbol_table(arena, out, indent, raw_data, 0, string_table_off, symbols); + coff_print_symbol_table(arena, out, indent, raw_data, 0, raw_string_table, symbol_table); rd_newline(); } RD_MarkerArray *section_markers = 0; if (opts & (RD_Option_Disasm|RD_Option_Rawdata)) { - section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, header->section_count, symbols); + section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_string_table, header->section_count, symbol_table); } if (opts & RD_Option_Rawdata) { - coff_raw_data_sections(arena, out, indent, raw_data, 1, section_markers, header->section_count, sections); + coff_raw_data_sections(arena, out, indent, raw_data, 1, section_markers, header->section_count, section_table); } if (opts & RD_Option_Disasm) { - coff_disasm_sections(arena, out, indent, raw_data, header->machine, 0, 1, section_markers, header->section_count, sections); + coff_disasm_sections(arena, out, indent, raw_data, header->machine, 0, 1, section_markers, header->section_count, section_table); rd_newline(); } if (opts & RD_Option_Codeview) { - cv_format_debug_sections(arena, out, indent, raw_data, string_table_off, header->section_count, sections); + cv_format_debug_sections(arena, out, indent, raw_data, raw_string_table, header->section_count, section_table); } if (opts & RD_Option_Dwarf) { - DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, string_table_off, header->section_count, sections); + DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, raw_string_table, header->section_count, section_table); dw_format(arena, out, indent, opts, &dwarf_input, arch, Image_CoffPe); } @@ -8109,7 +8118,8 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op goto exit; } - U64 string_table_off = file_header->symbol_table_foff + sizeof(COFF_Symbol16) * file_header->symbol_count; + U64 string_table_off = file_header->symbol_table_foff + sizeof(COFF_Symbol16) * file_header->symbol_count; + String8 raw_string_table = str8_substr(raw_data, rng_1u64(string_table_off, raw_data.size)); COFF_Symbol32Array symbols = coff_symbol_array_from_data_16(scratch.arena, raw_data, file_header->symbol_table_foff, file_header->symbol_count); @@ -8165,15 +8175,15 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op } if (opts & RD_Option_Sections) { - coff_print_seciton_table(arena, out, indent, raw_data, string_table_off, symbols, file_header->section_count, sections); + coff_print_section_table(arena, out, indent, raw_string_table, symbols, file_header->section_count, sections); } if (opts & RD_Option_Relocs) { - coff_print_relocs(arena, out, indent, raw_data, string_table_off, file_header->machine, file_header->section_count, sections, symbols); + coff_print_relocs(arena, out, indent, raw_data, raw_string_table, file_header->machine, file_header->section_count, sections, symbols); } if (opts & RD_Option_Symbols) { - coff_print_symbol_table(arena, out, indent, raw_data, 0, string_table_off, symbols); + coff_print_symbol_table(arena, out, indent, raw_data, 0, raw_string_table, symbols); } if (opts & RD_Option_Exports) { @@ -8253,7 +8263,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op if (rdi) { section_markers = rd_section_markers_from_rdi(scratch.arena, rdi); } else { - section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, file_header->section_count, symbols); + section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_string_table, file_header->section_count, symbols); } } @@ -8266,7 +8276,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op } if (opts & RD_Option_Dwarf) { - DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections); + DW_Input dwarf_input = dw_input_from_coff_section_table(scratch.arena, raw_data, raw_string_table, file_header->section_count, sections); dw_format(arena, out, indent, opts, &dwarf_input, arch, Image_CoffPe); } diff --git a/src/raddump/raddump.h b/src/raddump/raddump.h index 36d0017b..0daad497 100644 --- a/src/raddump/raddump.h +++ b/src/raddump/raddump.h @@ -169,7 +169,7 @@ internal void rd_format_preamble(Arena *arena, String8List *out, String8 indent, // Markers -internal RD_MarkerArray * rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 string_table_off, U64 section_count, COFF_Symbol32Array symbols); +internal RD_MarkerArray * rd_section_markers_from_coff_symbol_table(Arena *arena, String8 string_table, U64 section_count, COFF_Symbol32Array symbols); // Sections @@ -258,11 +258,11 @@ internal void cv_print_symbols_section(Arena *arena, String8List *out, String8 i // COFF internal void coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveMemberHeader header, String8 long_names); -internal void coff_print_seciton_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_Symbol32Array symbols, U64 sect_count, COFF_SectionHeader *sect_headers); +internal void coff_print_section_table (Arena *arena, String8List *out, String8 indent, String8 string_table, COFF_Symbol32Array symbols, U64 sect_count, COFF_SectionHeader *sect_headers); internal void coff_disasm_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, COFF_MachineType machine, U64 image_base, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections); internal void coff_raw_data_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections); -internal void coff_print_relocs (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, COFF_Symbol32Array symbols); -internal void coff_print_symbol_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_big_obj, U64 string_table_off, COFF_Symbol32Array symbols); +internal void coff_print_relocs (Arena *arena, String8List *out, String8 indent, String8 raw_data, String8 string_table, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, COFF_Symbol32Array symbols); +internal void coff_print_symbol_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_big_obj, String8 string_table, COFF_Symbol32Array symbols); internal void coff_print_big_obj_header (Arena *arena, String8List *out, String8 indent, COFF_BigObjHeader *header); internal void coff_print_file_header (Arena *arena, String8List *out, String8 indent, COFF_FileHeader *header); internal void coff_print_import (Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveImportHeader *header); From ab05133f8ac062018df727fd8a447328c2674f74 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 4 Apr 2025 15:47:37 -0700 Subject: [PATCH 312/755] picked better name convention for the section table --- src/linker/lnk.c | 242 +++++++++++++++---------------- src/linker/lnk.h | 26 ++-- src/linker/lnk_export_table.c | 4 +- src/linker/lnk_export_table.h | 2 +- src/linker/lnk_import_table.c | 12 +- src/linker/lnk_import_table.h | 4 +- src/linker/lnk_lib.c | 6 +- src/linker/lnk_obj.c | 30 ++-- src/linker/lnk_obj.h | 8 +- src/linker/lnk_section_table.c | 140 +++++++++--------- src/linker/lnk_section_table.h | 30 ++-- src/linker/pdb_ext/msf_builder.c | 18 +-- src/linker/pdb_ext/msf_builder.h | 2 +- 13 files changed, 262 insertions(+), 262 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 4e8cb79c..b5fa1ea7 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -414,13 +414,13 @@ lnk_res_number_id_is_before(void *raw_a, void *raw_b) } internal void -lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE_ResourceDir *root_dir) +lnk_serialize_pe_resource_tree(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, PE_ResourceDir *root_dir) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - LNK_Section *dir_sect = lnk_section_table_push(st, str8_lit(".rsrc$01"), LNK_RSRC_SECTION_FLAGS); - LNK_Section *data_sect = lnk_section_table_push(st, str8_lit(".rsrc$02"), LNK_RSRC_SECTION_FLAGS); + LNK_Section *dir_sect = lnk_section_table_push(sectab, str8_lit(".rsrc$01"), LNK_RSRC_SECTION_FLAGS); + LNK_Section *data_sect = lnk_section_table_push(sectab, str8_lit(".rsrc$02"), LNK_RSRC_SECTION_FLAGS); LNK_Chunk *dir_tree_chunk = lnk_section_push_chunk_list(dir_sect, dir_sect->root, str8_zero()); LNK_Chunk *dir_data_chunk = lnk_section_push_chunk_list(dir_sect, dir_sect->root, str8_zero()); @@ -580,7 +580,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE } internal void -lnk_add_resource_debug_s(LNK_SectionTable *st, +lnk_add_resource_debug_s(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 obj_path, String8 cwd_path, @@ -674,7 +674,7 @@ lnk_add_resource_debug_s(LNK_SectionTable *st, str8_serial_push_data_list(scratch.arena, &sub_sect_srl, symbol_srl.first); str8_serial_push_align(scratch.arena, &sub_sect_srl, CV_C13SubSectionAlign); - LNK_Section *debug_s = lnk_section_table_push(st, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS); + LNK_Section *debug_s = lnk_section_table_push(sectab, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS); String8 sub_sect_data = str8_serial_end(debug_s->arena, &sub_sect_srl); lnk_section_push_chunk_data(debug_s, debug_s->root, sub_sect_data, str8_zero()); @@ -706,24 +706,24 @@ lnk_make_res_obj(TP_Context *tp, temp_tp_arena->v[0] = arena_alloc(); LNK_SymbolTable *symtab = lnk_symbol_table_init(temp_tp_arena); - LNK_SectionTable *st = lnk_section_table_alloc(0, sect_virt_align, sect_file_align); - LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".null"), 0); + LNK_SectionTable *sectab = lnk_section_table_alloc(0, sect_virt_align, sect_file_align); + LNK_Section *header_sect = lnk_section_table_push(sectab, str8_lit(".null"), 0); - lnk_serialize_pe_resource_tree(st, symtab, root_dir); + lnk_serialize_pe_resource_tree(sectab, symtab, root_dir); CV_Arch cv_arch = cv_arch_from_coff_machine(machine); - lnk_add_resource_debug_s(st, symtab, path, cwd_path, exe_path, cv_arch, res_file_list, res_hash_array); + lnk_add_resource_debug_s(sectab, symtab, path, cwd_path, exe_path, cv_arch, res_file_list, res_hash_array); // register section symbols (after this point don't push new sections) - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; lnk_symbol_table_push_defined_chunk(symtab, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); } - st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null")); - lnk_section_table_build_data(tp, st, machine); - lnk_section_table_push_null(st); - lnk_section_table_assign_indices(st); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + sectab->null_sect = lnk_section_list_remove(§ab->list, str8_lit(".null")); + lnk_section_table_build_data(tp, sectab, machine); + lnk_section_table_push_null(sectab); + lnk_section_table_assign_indices(sectab); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); COFF_Symbol16List coff_symbol_list = {0}; @@ -735,7 +735,7 @@ lnk_make_res_obj(TP_Context *tp, coff_symbol16_list_push(scratch.arena, &coff_symbol_list, coff_feat00); // emit coff symbols for section definitions - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; if (sect == header_sect) continue; if (!sect->emit_header) continue; @@ -768,7 +768,7 @@ lnk_make_res_obj(TP_Context *tp, // convert relocations and symbols to coff format { - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; // filter out resource relocations @@ -827,8 +827,8 @@ lnk_make_res_obj(TP_Context *tp, if (coff_reloc_list.count == 0) continue; // push section for relocation data - String8 sect_name = push_str8f(st->arena, "%S.relocs", sect->name); - LNK_Section *reloc_sect = lnk_section_table_push(st, sect_name, 0); + String8 sect_name = push_str8f(sectab->arena, "%S.relocs", sect->name); + LNK_Section *reloc_sect = lnk_section_table_push(sectab, sect_name, 0); reloc_sect->emit_header = 0; // push chunk layout for relocations @@ -848,7 +848,7 @@ lnk_make_res_obj(TP_Context *tp, } } - LNK_Section *misc_sect = lnk_section_table_push(st, str8_lit(".misc"), COFF_SectionFlag_LnkInfo|COFF_SectionFlag_LnkRemove); + LNK_Section *misc_sect = lnk_section_table_push(sectab, str8_lit(".misc"), COFF_SectionFlag_LnkInfo|COFF_SectionFlag_LnkRemove); misc_sect->emit_header = 0; // serialize coff symbol list @@ -894,9 +894,9 @@ lnk_make_res_obj(TP_Context *tp, // build section headers { LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero()); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { - if (sect_node == st->null_sect) continue; - if (!sect_node->data.emit_header) continue; + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { + if (sect_node == sectab->null_sect) continue; + if (!sect_node->data.emit_header) continue; LNK_Section *sect = §_node->data; // init section header @@ -941,13 +941,13 @@ lnk_make_res_obj(TP_Context *tp, lnk_symbol_table_push(symtab, coff_section_header_count_symbol); } - lnk_section_table_assign_indices(st); - lnk_section_table_build_data(tp, st, machine); - lnk_section_table_assign_file_offsets(st); - String8 res_obj = lnk_section_table_serialize(tp, arena, st, machine); - sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); - lnk_patch_relocs_linker(tp, symtab, st, sect_id_map, res_obj, 0); - lnk_section_table_release(&st); + lnk_section_table_assign_indices(sectab); + lnk_section_table_build_data(tp, sectab, machine); + lnk_section_table_assign_file_offsets(sectab); + String8 res_obj = lnk_section_table_serialize(tp, arena, sectab, machine); + sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); + lnk_patch_relocs_linker(tp, symtab, sectab, sect_id_map, res_obj, 0); + lnk_section_table_release(§ab); arena_release(temp_tp_arena->v[0]); scratch_end(scratch); @@ -958,7 +958,7 @@ lnk_make_res_obj(TP_Context *tp, internal String8 lnk_obj_from_res_file_list(TP_Context *tp, Arena *arena, - LNK_SectionTable *st, + LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8List res_data_list, String8List res_path_list, @@ -1030,10 +1030,10 @@ lnk_make_linker_coff_obj(TP_Context *tp, temp_tp_arena->count = 1; LNK_SymbolTable *symtab = lnk_symbol_table_init(temp_tp_arena); - LNK_SectionTable *st = lnk_section_table_alloc(0, 1, 1); + LNK_SectionTable *sectab = lnk_section_table_alloc(0, 1, 1); - LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".coffhdr"), 0); - LNK_Section *debug_s_sect = lnk_section_table_push(st, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS); + LNK_Section *header_sect = lnk_section_table_push(sectab, str8_lit(".coffhdr"), 0); + LNK_Section *debug_s_sect = lnk_section_table_push(sectab, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS); // TODO: remove! hack! header_sect->emit_header = 0; @@ -1105,15 +1105,15 @@ lnk_make_linker_coff_obj(TP_Context *tp, { // register section symbols (after this point don't push new sections) - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; lnk_symbol_table_push_defined_chunk(symtab, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); } LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero()); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { - if (sect_node == st->null_sect) continue; - if (!sect_node->data.emit_header) continue; + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { + if (sect_node == sectab->null_sect) continue; + if (!sect_node->data.emit_header) continue; LNK_Section *sect = §_node->data; // init section header @@ -1157,14 +1157,14 @@ lnk_make_linker_coff_obj(TP_Context *tp, lnk_symbol_table_push(symtab, coff_section_header_count_symbol); } - lnk_section_table_assign_indices(st); - lnk_section_table_build_data(tp, st, machine); - lnk_section_table_assign_file_offsets(st); - String8 coff_data = lnk_section_table_serialize(tp, arena, st, machine); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); - lnk_patch_relocs_linker(tp, symtab, st, sect_id_map, coff_data, 0); + lnk_section_table_assign_indices(sectab); + lnk_section_table_build_data(tp, sectab, machine); + lnk_section_table_assign_file_offsets(sectab); + String8 coff_data = lnk_section_table_serialize(tp, arena, sectab, machine); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); + lnk_patch_relocs_linker(tp, symtab, sectab, sect_id_map, coff_data, 0); - lnk_section_table_release(&st); + lnk_section_table_release(§ab); scratch_end(scratch); return coff_data; @@ -1378,7 +1378,7 @@ lnk_push_pe_debug_data_directory(LNK_Section *sect, } internal void -lnk_build_debug_pdb(LNK_SectionTable *st, +lnk_build_debug_pdb(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_Section *sect, LNK_Chunk *dir_array_chunk, @@ -1405,7 +1405,7 @@ lnk_build_debug_pdb(LNK_SectionTable *st, } internal void -lnk_build_debug_rdi(LNK_SectionTable *st, +lnk_build_debug_rdi(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_Section *debug_sect, LNK_Chunk *debug_dir_array_chunk, @@ -1415,7 +1415,7 @@ lnk_build_debug_rdi(LNK_SectionTable *st, { ProfBeginFunction(); - LNK_Section *rdi_sect = lnk_section_table_push(st, str8_lit(".raddbg"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead); + LNK_Section *rdi_sect = lnk_section_table_push(sectab, str8_lit(".raddbg"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead); // push chunks String8 debug_rdi = pe_make_debug_header_rdi(rdi_sect->arena, guid, rdi_path); @@ -1434,7 +1434,7 @@ lnk_build_debug_rdi(LNK_SectionTable *st, internal void lnk_build_guard_tables(TP_Context *tp, - LNK_SectionTable *st, + LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_ExportTable *exptab, LNK_ObjList obj_list, @@ -1446,7 +1446,7 @@ lnk_build_guard_tables(TP_Context *tp, ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); enum { GUARD_FIDS, GUARD_IATS, GUARD_LJMP, GUARD_EHCONT, GUARD_COUNT }; LNK_SymbolList guard_symbol_list_table[GUARD_COUNT]; MemoryZeroStruct(&guard_symbol_list_table[0]); @@ -1561,8 +1561,8 @@ lnk_build_guard_tables(TP_Context *tp, #endif // build section data - lnk_section_table_build_data(tp, st, machine); - lnk_section_table_assign_virtual_offsets(st); + lnk_section_table_build_data(tp, sectab, machine); + lnk_section_table_assign_virtual_offsets(sectab); // compute symbols virtual offsets U64Array guard_voff_arr_table[GUARD_COUNT]; @@ -1604,7 +1604,7 @@ lnk_build_guard_tables(TP_Context *tp, { ".gehcont", LNK_GEHCONT_SYMBOL_NAME, LNK_GEHCONT_SECTION_FLAGS }, }; for (U64 i = 0; i < ArrayCount(sect_layout); ++i) { - LNK_Section *sect = lnk_section_table_push(st, str8_cstring(sect_layout[i].name), sect_layout[i].flags); + LNK_Section *sect = lnk_section_table_push(sectab, str8_cstring(sect_layout[i].name), sect_layout[i].flags); lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(sect_layout[i].symbol), LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); } @@ -1619,10 +1619,10 @@ lnk_build_guard_tables(TP_Context *tp, LNK_Symbol *gljmp_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_GLJMP_SYMBOL_NAME)); LNK_Symbol *gehcont_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_GEHCONT_SYMBOL_NAME)); - LNK_Section *gfids_sect = lnk_section_table_search_id(st, gfids_symbol->u.defined.u.chunk->ref.sect_id); - LNK_Section *giats_sect = lnk_section_table_search_id(st, giats_symbol->u.defined.u.chunk->ref.sect_id); - LNK_Section *gljmp_sect = lnk_section_table_search_id(st, gljmp_symbol->u.defined.u.chunk->ref.sect_id); - LNK_Section *gehcont_sect = lnk_section_table_search_id(st, gehcont_symbol->u.defined.u.chunk->ref.sect_id); + LNK_Section *gfids_sect = lnk_section_table_search_id(sectab, gfids_symbol->u.defined.u.chunk->ref.sect_id); + LNK_Section *giats_sect = lnk_section_table_search_id(sectab, giats_symbol->u.defined.u.chunk->ref.sect_id); + LNK_Section *gljmp_sect = lnk_section_table_search_id(sectab, gljmp_symbol->u.defined.u.chunk->ref.sect_id); + LNK_Section *gehcont_sect = lnk_section_table_search_id(sectab, gehcont_symbol->u.defined.u.chunk->ref.sect_id); LNK_Chunk *gfids_array_chunk = gfids_sect->root; LNK_Chunk *giats_array_chunk = giats_sect->root; @@ -1683,7 +1683,7 @@ lnk_build_guard_tables(TP_Context *tp, gflags_def->u.va |= PE_LoadConfigGuardFlags_EH_CONTINUATION_TABLE_PRESENT; } { - LNK_Section *didat_sect = lnk_section_table_search(st, str8_lit(".didat")); + LNK_Section *didat_sect = lnk_section_table_search(sectab, str8_lit(".didat")); if (didat_sect) { gflags_def->u.va |= PE_LoadConfigGuardFlags_DELAYLOAD_IAT_IN_ITS_OWN_SECTION; } @@ -1852,7 +1852,7 @@ lnk_base_reloc_page_array_sort(LNK_BaseRelocPageArray arr) internal void lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, - LNK_SectionTable *st, + LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine, U64 page_size, @@ -1863,10 +1863,10 @@ lnk_build_base_relocs(TP_Context *tp, TP_Temp temp = tp_temp_begin(tp_arena); - lnk_section_table_build_data(tp, st, machine); - lnk_section_table_assign_virtual_offsets(st); + lnk_section_table_build_data(tp, sectab, machine); + lnk_section_table_assign_virtual_offsets(sectab); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(tp_arena->v[0], st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(tp_arena->v[0], sectab); LNK_BaseRelocPageList *page_list_arr = push_array(tp_arena->v[0], LNK_BaseRelocPageList, tp->worker_count); HashTable **page_ht_arr = push_array_no_zero(tp_arena->v[0], HashTable *, tp->worker_count); @@ -1876,7 +1876,7 @@ lnk_build_base_relocs(TP_Context *tp, // emit pages from relocs defined in section table ProfBegin("Emit Relocs From Section Table"); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_BaseRelocTask task = {0}; task.page_size = page_size; task.sect_id_map = sect_id_map; @@ -1938,7 +1938,7 @@ lnk_build_base_relocs(TP_Context *tp, ProfEnd(); if (main_page_list->count > 0) { - LNK_Section *base_reloc_sect = lnk_section_table_push(st, str8_lit(".reloc"), LNK_RELOC_SECTION_FLAGS); + LNK_Section *base_reloc_sect = lnk_section_table_push(sectab, str8_lit(".reloc"), LNK_RELOC_SECTION_FLAGS); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_BASE_RELOC_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, base_reloc_sect->root, 0, 0, 0); ProfBegin("Page List -> Array"); @@ -2772,7 +2772,7 @@ THREAD_POOL_TASK_FUNC(lnk_section_reloc_patcher) String8 image_data = task->image_data; LNK_SymbolTable *symtab = task->symtab; - LNK_SectionTable *st = task->st; + LNK_SectionTable *sectab = task->sectab; LNK_Section **sect_id_map = task->sect_id_map; U64 base_addr = task->base_addr; Rng1U64 range = task->range_arr[task_id]; @@ -2786,24 +2786,24 @@ THREAD_POOL_TASK_FUNC(lnk_section_reloc_patcher) continue; } String8 chunk_data = lnk_data_from_chunk_ref(sect_id_map, image_data, chunk->ref); - lnk_apply_reloc(base_addr, st->sect_align, st->file_align, sect_id_map, symtab, chunk_data, reloc); + lnk_apply_reloc(base_addr, sectab->sect_align, sectab->file_align, sect_id_map, symtab, chunk_data, reloc); int bad_vs = 0; (void)bad_vs; } } } internal void -lnk_patch_relocs_linker(TP_Context *tp, LNK_SymbolTable *symtab, LNK_SectionTable *st, LNK_Section **sect_id_map, String8 image_data, U64 base_addr) +lnk_patch_relocs_linker(TP_Context *tp, LNK_SymbolTable *symtab, LNK_SectionTable *sectab, LNK_Section **sect_id_map, String8 image_data, U64 base_addr) { ProfBeginFunction(); Temp scratch = scratch_begin(0,0); - LNK_SectionPtrArray sect_arr = lnk_section_ptr_array_from_list(scratch.arena, st->list); + LNK_SectionPtrArray sect_arr = lnk_section_ptr_array_from_list(scratch.arena, sectab->list); LNK_SectionRelocPatcher task = {0}; task.image_data = image_data; task.symtab = symtab; - task.st = st; + task.sectab = sectab; task.sect_id_map = sect_id_map; task.sect_arr = sect_arr.v; task.base_addr = base_addr; @@ -2829,14 +2829,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) continue; } String8 chunk_data = lnk_data_from_chunk_ref(sect_id_map, image_data, reloc->chunk->ref); - lnk_apply_reloc(task->base_addr, task->st->sect_align, task->st->file_align, task->sect_id_map, task->symtab, chunk_data, reloc); + lnk_apply_reloc(task->base_addr, task->sectab->sect_align, task->sectab->file_align, task->sect_id_map, task->symtab, chunk_data, reloc); int bad_vs = 0; (void)bad_vs; } } } internal void -lnk_patch_relocs_obj(TP_Context *tp, LNK_ObjList obj_list, LNK_SymbolTable *symtab, LNK_SectionTable *st, LNK_Section **sect_id_map, String8 image_data, U64 base_addr) +lnk_patch_relocs_obj(TP_Context *tp, LNK_ObjList obj_list, LNK_SymbolTable *symtab, LNK_SectionTable *sectab, LNK_Section **sect_id_map, String8 image_data, U64 base_addr) { ProfBeginFunction(); Temp scratch = scratch_begin(0,0); @@ -2844,7 +2844,7 @@ lnk_patch_relocs_obj(TP_Context *tp, LNK_ObjList obj_list, LNK_SymbolTable *symt LNK_ObjRelocPatcher task; task.image_data = image_data; task.symtab = symtab; - task.st = st; + task.sectab = sectab; task.sect_id_map = sect_id_map; task.base_addr = base_addr; task.obj_arr = lnk_obj_arr_from_list(scratch.arena, obj_list); @@ -2879,24 +2879,24 @@ lnk_init_section_table(LNK_SymbolTable *symtab, U64 section_virt_off, U64 sect_a { ".tls", LNK_TLS_SYMBOL_NAME, LNK_DATA_SECTION_FLAGS }, }; - LNK_SectionTable *st = lnk_section_table_alloc(section_virt_off, sect_align, file_align); + LNK_SectionTable *sectab = lnk_section_table_alloc(section_virt_off, sect_align, file_align); for (U64 i = 0; i < ArrayCount(sect_layout); ++i) { - LNK_Section *sect = lnk_section_table_push(st, str8_cstring(sect_layout[i].name), sect_layout[i].flags); + LNK_Section *sect = lnk_section_table_push(sectab, str8_cstring(sect_layout[i].name), sect_layout[i].flags); sect->symbol_name = str8_cstring(sect_layout[i].symbol); sect->symbol_name = push_str8_copy(sect->arena, sect->symbol_name); lnk_symbol_table_push_defined_chunk(symtab, sect->symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); } - st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null")); + sectab->null_sect = lnk_section_list_remove(§ab->list, str8_lit(".null")); // dont build layout because we discard debug from image and move it to pdb - LNK_Section *debug_sect = lnk_section_table_search(st, str8_lit(".debug")); + LNK_Section *debug_sect = lnk_section_table_search(sectab, str8_lit(".debug")); debug_sect->emit_header = 0; debug_sect->has_layout = 0; ProfEnd(); - return st; + return sectab; } internal LNK_MergeDirectiveList @@ -2928,7 +2928,7 @@ lnk_init_merge_directive_list(Arena *arena, LNK_ObjList obj_list) } internal void -lnk_discard_meta_data_sections(LNK_SectionTable *st) +lnk_discard_meta_data_sections(LNK_SectionTable *sectab) { static char * meta_data_sect_arr[] = { ".gfids", @@ -2938,7 +2938,7 @@ lnk_discard_meta_data_sections(LNK_SectionTable *st) }; for (U64 meta_idx = 0; meta_idx < ArrayCount(meta_data_sect_arr); meta_idx += 1) { String8 name = str8_cstring(meta_data_sect_arr[meta_idx]); - LNK_Section *sect = lnk_section_table_search(st, name); + LNK_Section *sect = lnk_section_table_search(sectab, name); if (sect) { lnk_visit_chunks(sect->id, sect->root, lnk_chunk_mark_discarded, NULL); sect->root->is_discarded = 0; @@ -2960,15 +2960,15 @@ lnk_pdata_is_before_x8664(void *raw_a, void *raw_b) //////////////////////////////// internal void -lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab) +lnk_log_size_breakdown(LNK_SectionTable *sectab, LNK_SymbolTable *symtab) { Temp scratch = scratch_begin(0, 0); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); U64 code_size = 0; U64 data_size = 0; - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; if (sect->has_layout) { U64 sect_size = lnk_file_size_from_chunk_ref(sect_id_map, sect->root->ref); @@ -2982,21 +2982,21 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab) LNK_Symbol *dos_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_HEADER_SYMBOL_NAME)); LNK_Symbol *dos_program_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_PROGRAM_SYMBOL_NAME)); - LNK_Symbol *COFF_FileHeader_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME)); + LNK_Symbol *coff_file_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME)); LNK_Symbol *coff_section_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME)); LNK_Symbol *pe_opt_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME)); LNK_Symbol *pe_directories_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME)); LNK_Chunk *dos_header_chunk = dos_header_symbol->u.defined.u.chunk; LNK_Chunk *dos_program_chunk = dos_program_symbol->u.defined.u.chunk; - LNK_Chunk *COFF_FileHeader_chunk = COFF_FileHeader_symbol->u.defined.u.chunk; + LNK_Chunk *coff_file_header_chunk = coff_file_header_symbol->u.defined.u.chunk; LNK_Chunk *coff_section_header_chunk = coff_section_header_symbol->u.defined.u.chunk; LNK_Chunk *pe_opt_header_chunk = pe_opt_header_symbol->u.defined.u.chunk; LNK_Chunk *pe_directories_chunk = pe_directories_symbol->u.defined.u.chunk; U64 dos_header_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_header_chunk->ref); U64 dos_program_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_program_chunk->ref); - U64 COFF_FileHeader_size = lnk_file_size_from_chunk_ref(sect_id_map, COFF_FileHeader_chunk->ref); + U64 coff_file_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_file_header_chunk->ref); U64 coff_section_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_section_header_chunk->ref); U64 pe_opt_header_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_opt_header_chunk->ref); U64 pe_directories_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_directories_chunk->ref); @@ -3005,7 +3005,7 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab) str8_list_pushf(scratch.arena, &output_list, "--- Image Size Breakdown -------------------------------------------------------"); str8_list_pushf(scratch.arena, &output_list, " DOS Header: %M", dos_header_size); str8_list_pushf(scratch.arena, &output_list, " DOS Program Stub: %M", dos_program_size); - str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", COFF_FileHeader_size); + str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", coff_file_header_size); str8_list_pushf(scratch.arena, &output_list, " COFF Section Headers: %M", coff_section_header_size); str8_list_pushf(scratch.arena, &output_list, " PE Header: %M", pe_opt_header_size); str8_list_pushf(scratch.arena, &output_list, " Directories: %M", pe_directories_size); @@ -3020,7 +3020,7 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab) } internal void -lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *st) +lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *sectab) { Temp scratch = scratch_begin(0, 0); @@ -3029,7 +3029,7 @@ lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTabl lib_count += lib_index[i].count; } U32 reloc_count = 0; - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { reloc_count += sect_node->data.reloc_list.count; } @@ -3204,18 +3204,18 @@ lnk_chunk_off_pair_array_bsearch(LNK_ChunkOffPair *arr, U64 count, U64 value) } internal String8List -lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ObjList objs, LNK_LibList lib_index[LNK_InputSource_Count], LNK_SectionTable *st, LNK_SymbolTable *symtab) +lnk_build_rad_chunk_map(Arena *arena, String8 image_data, U64 thread_count, LNK_ObjList objs, LNK_LibList lib_index[LNK_InputSource_Count], LNK_SectionTable *sectab, LNK_SymbolTable *symtab) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); String8List map = {0}; - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); ProfBegin("SECTIONS"); str8_list_pushf(arena, &map, "# SECTIONS\n"); - for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) { + for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) { LNK_Section *sect = §_n->data; if (sect->has_layout) { LNK_Chunk **chunks = push_array_no_zero(scratch.arena, LNK_Chunk *, sect->layout.total_count); @@ -3436,7 +3436,7 @@ lnk_run(int argc, char **argv) // state LNK_SymbolTable *symtab = lnk_symbol_table_init(tp_arena); - LNK_SectionTable *st = lnk_init_section_table(symtab, config->section_virt_off, config->sect_align, config->file_align); + LNK_SectionTable *sectab = lnk_init_section_table(symtab, config->section_virt_off, config->sect_align, config->file_align); LNK_ImportTable *imptab_static = 0; LNK_ImportTable *imptab_delayed = 0; LNK_ExportTable *exptab = lnk_export_table_alloc(); @@ -3682,7 +3682,7 @@ lnk_run(int argc, char **argv) Assert(config->machine != COFF_MachineType_Unknown); B32 is_unloadable = !!(config->flags & LNK_ConfigFlag_DelayUnload); B32 is_bindable = !!(config->flags & LNK_ConfigFlag_DelayBind); - imptab_delayed = lnk_import_table_alloc_delayed(st, symtab, config->machine, is_unloadable, is_bindable); + imptab_delayed = lnk_import_table_alloc_delayed(sectab, symtab, config->machine, is_unloadable, is_bindable); } LNK_ImportDLL *dll = lnk_import_table_search_dll(imptab_delayed, import_header->dll_name); if (!dll) { @@ -3695,7 +3695,7 @@ lnk_run(int argc, char **argv) } else { if (!imptab_static) { Assert(config->machine != COFF_MachineType_Unknown); - imptab_static = lnk_import_table_alloc_static(st, symtab, config->machine); + imptab_static = lnk_import_table_alloc_static(sectab, symtab, config->machine); } LNK_ImportDLL *dll = lnk_import_table_search_dll(imptab_static, import_header->dll_name); if (!dll) { @@ -3769,7 +3769,7 @@ lnk_run(int argc, char **argv) } ProfEnd(); - LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, st, config->function_pad_min, unique_obj_input_list.count, input_obj_arr); + LNK_ObjNodeArray obj_node_arr = lnk_obj_list_push_parallel(tp, tp_arena, &obj_list, sectab, config->function_pad_min, unique_obj_input_list.count, input_obj_arr); ProfBegin("Machine Compat Check"); for (U64 obj_idx = 0; obj_idx < obj_node_arr.count; ++obj_idx) { @@ -4012,7 +4012,7 @@ lnk_run(int argc, char **argv) String8 obj_name = str8_lit("* Resources *"); String8 obj_data = lnk_obj_from_res_file_list(tp, tp_arena->v[0], - st, + sectab, symtab, res_data_list, res_path_list, @@ -4101,14 +4101,14 @@ lnk_run(int argc, char **argv) case State_DiscardMetaDataSections: { ProfBegin("Discard Meta Data Sections"); - lnk_discard_meta_data_sections(st); + lnk_discard_meta_data_sections(sectab); ProfEnd(); } break; case State_BuildDebugDirectory: { ProfBegin("Build Debug Directory"); // push debug directory layout chunks - LNK_Section *debug_sect = lnk_section_table_search(st, str8_lit(".rdata")); + LNK_Section *debug_sect = lnk_section_table_search(sectab, str8_lit(".rdata")); LNK_Chunk *debug_chunk = lnk_section_push_chunk_list(debug_sect, debug_sect->root, str8_zero()); LNK_Chunk *debug_dir_array_chunk = lnk_section_push_chunk_list(debug_sect, debug_chunk, str8_zero()); @@ -4117,12 +4117,12 @@ lnk_run(int argc, char **argv) // debug entry for PDB if (config->debug_mode != LNK_DebugMode_None && config->debug_mode != LNK_DebugMode_Null) { - lnk_build_debug_pdb(st, symtab, debug_sect, debug_dir_array_chunk, config->time_stamp, config->guid, config->age, config->pdb_alt_path); + lnk_build_debug_pdb(sectab, symtab, debug_sect, debug_dir_array_chunk, config->time_stamp, config->guid, config->age, config->pdb_alt_path); } // debug entry for RDI if (config->rad_debug == LNK_SwitchState_Yes) { - lnk_build_debug_rdi(st, symtab, debug_sect, debug_dir_array_chunk, config->time_stamp, config->guid, config->rad_debug_alt_path); + lnk_build_debug_rdi(sectab, symtab, debug_sect, debug_dir_array_chunk, config->time_stamp, config->guid, config->rad_debug_alt_path); } ProfEnd(); @@ -4139,38 +4139,38 @@ lnk_run(int argc, char **argv) lnk_collect_exports_from_obj_directives(exptab, obj_list, symtab); // build export table section - lnk_build_edata(exptab, st, symtab, config->image_name, config->machine); + lnk_build_edata(exptab, sectab, symtab, config->image_name, config->machine); ProfEnd(); } break; case State_MergeSections: { ProfBegin("Merge Sections"); LNK_MergeDirectiveList merge_list = lnk_init_merge_directive_list(scratch.arena, obj_list); - lnk_section_table_merge(st, merge_list); + lnk_section_table_merge(sectab, merge_list); ProfEnd(); } break; case State_BuildCFGuards: { ProfBegin("Build CF Guards"); B32 emit_suppress_flag = 1; // MSVC emits this flag but every entry has zero set. - lnk_build_guard_tables(tp, st, symtab, exptab, obj_list, config->machine, config->entry_point_name, config->guard_flags, emit_suppress_flag); + lnk_build_guard_tables(tp, sectab, symtab, exptab, obj_list, config->machine, config->entry_point_name, config->guard_flags, emit_suppress_flag); ProfEnd(); } break; case State_BuildBaseRelocs: { ProfBegin("Base Relocs"); - lnk_build_base_relocs(tp, tp_arena, st, symtab, config->machine, config->page_size, config->file_characteristics, obj_list); + lnk_build_base_relocs(tp, tp_arena, sectab, symtab, config->machine, config->page_size, config->file_characteristics, obj_list); ProfEnd(); } break; case State_FinalizeImage: { ProfBegin("Build Win32 Header"); // remove empty section headers from output image - lnk_section_table_remove_empties(st, symtab); + lnk_section_table_remove_empties(sectab, symtab); // collect output sections - LNK_SectionArray out_sect_arr = lnk_section_table_get_output_sections(scratch.arena, st); + LNK_SectionArray out_sect_arr = lnk_section_table_get_output_sections(scratch.arena, sectab); // push back null section where we store image header - LNK_Section *header_sect = lnk_section_table_push_null(st); + LNK_Section *header_sect = lnk_section_table_push_null(sectab); // fill out header section with win32 image header data lnk_build_win32_image_header(symtab, header_sect, header_sect->root, config, out_sect_arr); @@ -4178,24 +4178,24 @@ lnk_run(int argc, char **argv) ProfEnd(); // finalize sections - lnk_section_table_build_data(tp, st, config->machine); - lnk_section_table_assign_indices(st); - lnk_section_table_assign_virtual_offsets(st); - lnk_section_table_assign_file_offsets(st); + lnk_section_table_build_data(tp, sectab, config->machine); + lnk_section_table_assign_indices(sectab); + lnk_section_table_assign_virtual_offsets(sectab); + lnk_section_table_assign_file_offsets(sectab); ProfBegin("Image Serialize"); - image_data = lnk_section_table_serialize(tp, scratch.arena, st, config->machine); + image_data = lnk_section_table_serialize(tp, scratch.arena, sectab, config->machine); Assert(image_data.size > 0); ProfEnd(); // image layout is finalized, section id map is stable after this point - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); ProfBegin("Patch Relocs"); U64 base_addr = lnk_get_base_addr(config); - lnk_patch_relocs_obj(tp, obj_list, symtab, st, sect_id_map, image_data, base_addr); - lnk_patch_relocs_linker(tp, symtab, st, sect_id_map, image_data, base_addr); + lnk_patch_relocs_obj(tp, obj_list, symtab, sectab, sect_id_map, image_data, base_addr); + lnk_patch_relocs_linker(tp, symtab, sectab, sect_id_map, image_data, base_addr); ProfEnd(); @@ -4333,7 +4333,7 @@ lnk_run(int argc, char **argv) } break; case State_BuildRadChunkMap: { ProfBegin("RAD Chunk Map"); - String8List map = lnk_build_rad_chunk_map(scratch.arena, image_data, config->worker_count, obj_list, lib_index, st, symtab); + String8List map = lnk_build_rad_chunk_map(scratch.arena, image_data, config->worker_count, obj_list, lib_index, sectab, symtab); lnk_write_data_list_to_file_path(config->rad_chunk_map_name, config->temp_rad_chunk_map_name, map); ProfEnd(); } break; @@ -4343,12 +4343,12 @@ lnk_run(int argc, char **argv) LNK_CodeViewInput input = lnk_make_code_view_input(tp, tp_arena, config->lib_dir_list, obj_list); CV_DebugT *types = lnk_import_types(tp, tp_arena, &input); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); if (config->rad_debug == LNK_SwitchState_Yes) { lnk_timer_begin(LNK_Timer_Rdi); RDI_Arch arch = rdi_arch_from_coff_machine(config->machine); - LNK_SectionArray image_sects = lnk_section_table_get_output_sections(scratch.arena, st); + LNK_SectionArray image_sects = lnk_section_table_get_output_sections(scratch.arena, sectab); String8List rdi_data = lnk_build_rad_debug_info(tp, tp_arena, @@ -4553,10 +4553,10 @@ lnk_run(int argc, char **argv) } if (lnk_get_log_status(LNK_Log_SizeBreakdown)) { - lnk_log_size_breakdown(st, symtab); + lnk_log_size_breakdown(sectab, symtab); } if (lnk_get_log_status(LNK_Log_LinkStats)) { - lnk_log_link_stats(obj_list, lib_index, st); + lnk_log_link_stats(obj_list, lib_index, sectab); } if (lnk_get_log_status(LNK_Log_Timers)) { lnk_log_timers(); @@ -4566,7 +4566,7 @@ lnk_run(int argc, char **argv) // linker is done, punt memory release to OS //arena_release(ht_arena); - //lnk_section_table_release(&st); + //lnk_section_table_release(§ab); //lnk_export_table_release(&export_table); //lnk_import_table_release(&imptab_static); //lnk_import_table_release(&imptab_delayed); diff --git a/src/linker/lnk.h b/src/linker/lnk.h index d6732174..2790fa60 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -204,7 +204,7 @@ typedef struct { String8 image_data; LNK_SymbolTable *symtab; - LNK_SectionTable *st; + LNK_SectionTable *sectab; LNK_Section **sect_id_map; U64 base_addr; LNK_Section **sect_arr; @@ -215,7 +215,7 @@ typedef struct { String8 image_data; LNK_SymbolTable *symtab; - LNK_SectionTable *st; + LNK_SectionTable *sectab; LNK_Section **sect_id_map; U64 base_addr; LNK_Obj **obj_arr; @@ -262,10 +262,10 @@ internal void lnk_merge_manifest_files(String8 mt_path, String8 out_name, Str //////////////////////////////// // Resources -internal void lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE_ResourceDir *root_dir); -internal void lnk_add_resource_debug_s(LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 obj_path, String8 cwd_path, String8 exe_path, CV_Arch arch, String8List res_file_list, MD5Hash *res_hash_array); +internal void lnk_serialize_pe_resource_tree(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, PE_ResourceDir *root_dir); +internal void lnk_add_resource_debug_s(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 obj_path, String8 cwd_path, String8 exe_path, CV_Arch arch, String8List res_file_list, MD5Hash *res_hash_array); internal String8 lnk_make_res_obj(TP_Context *tp, Arena *arena, PE_ResourceDir *root_dir, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 path, String8 cwd_path, String8 exe_path, String8List res_file_list, MD5Hash *res_hash_array); -internal String8 lnk_obj_from_res_file_list(TP_Context *tp, Arena *arena, LNK_SectionTable *st, LNK_SymbolTable *symtab, String8List res_file_list, String8List res_path_list, COFF_MachineType machine, U32 time_stamp, String8 work_dir, PathStyle system_path_style, String8 obj_name); +internal String8 lnk_obj_from_res_file_list(TP_Context *tp, Arena *arena, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8List res_file_list, String8List res_path_list, COFF_MachineType machine, U32 time_stamp, String8 work_dir, PathStyle system_path_style, String8 obj_name); //////////////////////////////// // Debug @@ -275,10 +275,10 @@ internal String8 lnk_make_linker_coff_obj(TP_Context *tp, Arena *arena, COFF_Tim //////////////////////////////// // Win32 Image Helpers -internal void lnk_build_debug_pdb(LNK_SectionTable *st, LNK_SymbolTable *symtab, LNK_Section *debug_sect, LNK_Chunk *debug_dir_array_chunk, COFF_TimeStamp time_stamp, Guid guid, U32 age, String8 pdb_path); -internal void lnk_build_debug_rdi(LNK_SectionTable *st, LNK_SymbolTable *symtab, LNK_Section *debug_sect, LNK_Chunk *debug_dir_array_chunk, COFF_TimeStamp time_stamp, Guid guid, String8 rdi_path); -internal void lnk_build_guard_tables(TP_Context *tp, LNK_SectionTable *st, LNK_SymbolTable *symtab, LNK_ExportTable *exptab, LNK_ObjList obj_list, COFF_MachineType machine, String8 entry_point_name, LNK_GuardFlags guard_flags, B32 emit_suppress_flag); -internal void lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_SectionTable *st, LNK_SymbolTable *symtab, COFF_MachineType machine, U64 page_size, PE_ImageFileCharacteristics file_chars, LNK_ObjList obj_list); +internal void lnk_build_debug_pdb(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_Section *debug_sect, LNK_Chunk *debug_dir_array_chunk, COFF_TimeStamp time_stamp, Guid guid, U32 age, String8 pdb_path); +internal void lnk_build_debug_rdi(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_Section *debug_sect, LNK_Chunk *debug_dir_array_chunk, COFF_TimeStamp time_stamp, Guid guid, String8 rdi_path); +internal void lnk_build_guard_tables(TP_Context *tp, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, LNK_ExportTable *exptab, LNK_ObjList obj_list, COFF_MachineType machine, String8 entry_point_name, LNK_GuardFlags guard_flags, B32 emit_suppress_flag); +internal void lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine, U64 page_size, PE_ImageFileCharacteristics file_chars, LNK_ObjList obj_list); internal LNK_Chunk * lnk_build_dos_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent_chunk); internal LNK_Chunk * lnk_build_pe_magic(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent); internal LNK_Chunk * lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent, COFF_MachineType machine, COFF_TimeStamp time_stamp, PE_ImageFileCharacteristics file_characteristics); @@ -290,15 +290,15 @@ internal LNK_Chunk * lnk_build_win32_image_header(LNK_SymbolTable *symtab, LNK_S //////////////////////////////// // Relocs -internal void lnk_patch_relocs_linker(TP_Context *tp, LNK_SymbolTable *symtab, LNK_SectionTable *st, LNK_Section **sect_id_map, String8 image_data, U64 base_addr); -internal void lnk_patch_relocs_obj(TP_Context *tp, LNK_ObjList obj_list, LNK_SymbolTable *symtab, LNK_SectionTable *st, LNK_Section **sect_id_map, String8 image_data, U64 base_addr); +internal void lnk_patch_relocs_linker(TP_Context *tp, LNK_SymbolTable *symtab, LNK_SectionTable *sectab, LNK_Section **sect_id_map, String8 image_data, U64 base_addr); +internal void lnk_patch_relocs_obj(TP_Context *tp, LNK_ObjList obj_list, LNK_SymbolTable *symtab, LNK_SectionTable *sectab, LNK_Section **sect_id_map, String8 image_data, U64 base_addr); internal void lnk_apply_reloc(U64 base_addr, U64 virt_align, U64 file_align, LNK_Section **sect_id_map, LNK_SymbolTable *symtab, String8 chunk_data, LNK_Reloc *reloc); //////////////////////////////// -internal void lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab); -internal void lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *st); +internal void lnk_log_size_breakdown(LNK_SectionTable *sectab, LNK_SymbolTable *symtab); +internal void lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *sectab); internal void lnk_log_timers(void); //////////////////////////////// diff --git a/src/linker/lnk_export_table.c b/src/linker/lnk_export_table.c index ff36c649..d2beb95e 100644 --- a/src/linker/lnk_export_table.c +++ b/src/linker/lnk_export_table.c @@ -171,7 +171,7 @@ lnk_export_array_from_list(Arena *arena, LNK_ExportList list) } internal void -lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 image_name, COFF_MachineType machine) +lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 image_name, COFF_MachineType machine) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -195,7 +195,7 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable * } } - LNK_Section *edata = lnk_section_table_search(st, str8_lit(".edata")); + LNK_Section *edata = lnk_section_table_search(sectab, str8_lit(".edata")); // push header PE_ExportTableHeader *header = push_array(edata->arena, PE_ExportTableHeader, 1); diff --git a/src/linker/lnk_export_table.h b/src/linker/lnk_export_table.h index 25cc31ca..08be801f 100644 --- a/src/linker/lnk_export_table.h +++ b/src/linker/lnk_export_table.h @@ -41,6 +41,6 @@ internal LNK_ExportTable * lnk_export_table_alloc(void); internal void lnk_export_table_release(LNK_ExportTable **exptab_ptr); internal LNK_Export * lnk_export_table_search(LNK_ExportTable *exptab, String8 name); internal void lnk_collect_exports_from_def_files(LNK_ExportTable *exptab, String8List path_list); -internal void lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 image_name, COFF_MachineType machine); +internal void lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 image_name, COFF_MachineType machine); internal void lnk_collect_exports_from_obj_directives(LNK_ExportTable *exptab, LNK_ObjList obj_list, LNK_SymbolTable *symtab); diff --git a/src/linker/lnk_import_table.c b/src/linker/lnk_import_table.c index 677ae6ba..c1973f30 100644 --- a/src/linker/lnk_import_table.c +++ b/src/linker/lnk_import_table.c @@ -2,12 +2,12 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) internal LNK_ImportTable * -lnk_import_table_alloc_static(LNK_SectionTable *st, LNK_SymbolTable *symtab, COFF_MachineType machine) +lnk_import_table_alloc_static(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine) { ProfBeginFunction(); - LNK_Section *data_sect = lnk_section_table_push(st, str8_lit(".idata"), LNK_IDATA_SECTION_FLAGS); - LNK_Section *code_sect = lnk_section_table_search(st, str8_lit(".text")); + LNK_Section *data_sect = lnk_section_table_push(sectab, str8_lit(".idata"), LNK_IDATA_SECTION_FLAGS); + LNK_Section *code_sect = lnk_section_table_search(sectab, str8_lit(".text")); LNK_Chunk *dll_table_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); LNK_Chunk *int_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); @@ -47,12 +47,12 @@ lnk_import_table_alloc_static(LNK_SectionTable *st, LNK_SymbolTable *symtab, COF } internal LNK_ImportTable * -lnk_import_table_alloc_delayed(LNK_SectionTable *st, LNK_SymbolTable *symtab, COFF_MachineType machine, B32 is_unloadable, B32 is_bindable) +lnk_import_table_alloc_delayed(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine, B32 is_unloadable, B32 is_bindable) { ProfBeginFunction(); - LNK_Section *data_sect = lnk_section_table_push(st, str8_lit(".didat"), LNK_DEBUG_DIR_SECTION_FLAGS); - LNK_Section *code_sect = lnk_section_table_search(st, str8_lit(".text")); + LNK_Section *data_sect = lnk_section_table_push(sectab, str8_lit(".didat"), LNK_DEBUG_DIR_SECTION_FLAGS); + LNK_Section *code_sect = lnk_section_table_search(sectab, str8_lit(".text")); LNK_Chunk *dll_table_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); LNK_Chunk *int_chunk = lnk_section_push_chunk_list(data_sect, data_sect->root, str8_zero()); diff --git a/src/linker/lnk_import_table.h b/src/linker/lnk_import_table.h index 6005b622..3bb9eb2f 100644 --- a/src/linker/lnk_import_table.h +++ b/src/linker/lnk_import_table.h @@ -59,8 +59,8 @@ typedef struct LNK_ImportTable HashTable *dll_ht; } LNK_ImportTable; -internal LNK_ImportTable * lnk_import_table_alloc_static(LNK_SectionTable *st, LNK_SymbolTable *symtab, COFF_MachineType machine); -internal LNK_ImportTable * lnk_import_table_alloc_delayed(LNK_SectionTable *st, LNK_SymbolTable *symtab, COFF_MachineType machine, B32 is_unloadable, B32 is_bindable); +internal LNK_ImportTable * lnk_import_table_alloc_static(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine); +internal LNK_ImportTable * lnk_import_table_alloc_delayed(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, COFF_MachineType machine, B32 is_unloadable, B32 is_bindable); internal void lnk_import_table_release(LNK_ImportTable **imptab); internal LNK_ImportDLL * lnk_import_table_push_dll_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine); internal LNK_ImportDLL * lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index fc4e54d0..d02f4fac 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -939,16 +939,16 @@ lnk_build_import_lib(TP_Context *tp, TP_Arena *arena, COFF_MachineType machine, } LNK_InputObj **inputs = lnk_array_from_input_obj_list(scratch.arena, input_obj_list); - LNK_SectionTable *st = lnk_section_table_alloc(0,0,0); + LNK_SectionTable *sectab = lnk_section_table_alloc(0,0,0); LNK_ObjList obj_list = {0}; - lnk_obj_list_push_parallel(tp, arena, &obj_list, st, 0, input_obj_list.count, inputs); + lnk_obj_list_push_parallel(tp, arena, &obj_list, sectab, 0, input_obj_list.count, inputs); LNK_LibBuild import_lib = lnk_build_lib(scratch.arena, machine, time_stamp, dll_name, obj_list, exptab); B32 emit_second_member = 0; // MSVC linker refuses to link with lib that has the second member. String8List coff_archive_data = lnk_coff_archive_from_lib_build(arena->v[0], &import_lib, emit_second_member, time_stamp, /* -rw-r--r-- */ 644); // cleanup memory - lnk_section_table_release(&st); + lnk_section_table_release(§ab); scratch_end(scratch); ProfEnd(); diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index b03d9fa8..af16561c 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -546,7 +546,7 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_counter) for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) { String8 name = obj->sect_name_arr[chunk_idx]; LNK_Chunk *chunk = obj->chunk_arr[chunk_idx]; - LNK_Section *sect = lnk_section_table_search(task->st, name); + LNK_Section *sect = lnk_section_table_search(task->sectab, name); U64 count = 0; lnk_visit_chunks(0, chunk, lnk_chunk_get_count_cb, &count); @@ -586,7 +586,7 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_ref_assigner) LNK_Chunk *chunk = obj->chunk_arr[chunk_idx]; // :find_chunk_section - LNK_Section *sect = lnk_section_table_search(task->st, name); + LNK_Section *sect = lnk_section_table_search(task->sectab, name); // :chunk_ref_assign LNK_ChunkRefAssign ctx = {0}; @@ -605,7 +605,7 @@ internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_list, - LNK_SectionTable *st, + LNK_SectionTable *sectab, U64 *function_pad_min, U64 input_count, LNK_InputObj **inputs) @@ -627,7 +627,7 @@ lnk_obj_list_push_parallel(TP_Context *tp, } ProfEnd(); - if (st) { + if (sectab) { ProfBegin("Section Table Update"); { TP_Temp temp = tp_temp_begin(arena); @@ -647,7 +647,7 @@ lnk_obj_list_push_parallel(TP_Context *tp, HashTable *ht = hash_table_init(arena->v[0], 128); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; hash_table_push_string_u64(arena->v[0], ht, sect->name, sect->flags); } @@ -690,7 +690,7 @@ lnk_obj_list_push_parallel(TP_Context *tp, // push new sections for :find_chunk_section for (LNK_SectDefn *curr = new_list.first; curr != 0; curr = curr->next) { - lnk_section_table_push(st, curr->name, curr->flags & ~COFF_SectionFlags_LnkFlags); + lnk_section_table_push(sectab, curr->name, curr->flags & ~COFF_SectionFlags_LnkFlags); } tp_temp_end(temp); @@ -700,20 +700,20 @@ lnk_obj_list_push_parallel(TP_Context *tp, ProfBegin("Count Chunks Per Section"); U64 **chunk_ids; { - U64 **chunk_counts = push_array_no_zero(scratch.arena, U64 *, st->id_max); - for (U64 sect_idx = 0; sect_idx < st->id_max; sect_idx += 1) { + U64 **chunk_counts = push_array_no_zero(scratch.arena, U64 *, sectab->id_max); + for (U64 sect_idx = 0; sect_idx < sectab->id_max; sect_idx += 1) { chunk_counts[sect_idx] = push_array(scratch.arena, U64, obj_arr.count); } LNK_ChunkCounter task = {0}; - task.st = st; + task.sectab = sectab; task.obj_arr = obj_arr.v; task.chunk_counts = chunk_counts; tp_for_parallel(tp, 0, obj_arr.count, lnk_chunk_counter, &task); chunk_ids = chunk_counts; - for (U64 sect_idx = 1; sect_idx < st->id_max; sect_idx += 1) { - LNK_Section *sect = lnk_section_table_search_id(st, sect_idx); + for (U64 sect_idx = 1; sect_idx < sectab->id_max; sect_idx += 1) { + LNK_Section *sect = lnk_section_table_search_id(sectab, sect_idx); if (!sect) continue; for (U64 obj_idx = 0; obj_idx < obj_arr.count; obj_idx += 1) { U64 chunk_id_base = sect->cman->total_chunk_count; @@ -727,16 +727,16 @@ lnk_obj_list_push_parallel(TP_Context *tp, ProfBegin("Assign Chunk Refs"); { LNK_ChunkRefAssigner task; - task.st = st; + task.sectab = sectab; task.range_arr = tp_divide_work(scratch.arena, obj_arr.count, tp->worker_count); task.chunk_ids = chunk_ids; task.obj_arr = obj_arr.v; - task.nosort_chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, st->id_max, tp->worker_count); - task.chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, st->id_max, tp->worker_count); + task.nosort_chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, sectab->id_max, tp->worker_count); + task.chunk_list_arr_arr = lnk_make_chunk_list_arr_arr(scratch.arena, sectab->id_max, tp->worker_count); tp_for_parallel(tp, arena, tp->worker_count, lnk_chunk_ref_assigner, &task); // merge chunks - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; lnk_chunk_list_concat_in_place_arr(sect->nosort_chunk->u.list, task.nosort_chunk_list_arr_arr[sect->id], tp->worker_count); lnk_chunk_list_concat_in_place_arr(sect->root->u.list, task.chunk_list_arr_arr[sect->id], tp->worker_count); diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 876557ea..ec07d32e 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -112,7 +112,7 @@ typedef struct LNK_ObjNode *obj_node_arr; U64 obj_id_base; LNK_SectDefnList *defn_arr; - LNK_SectionTable *st; + LNK_SectionTable *sectab; U64 *function_pad_min; } LNK_ObjIniter; @@ -126,7 +126,7 @@ typedef struct typedef struct { - LNK_SectionTable *st; + LNK_SectionTable *sectab; LNK_ObjNode *obj_arr; U64 **chunk_counts; } LNK_ChunkCounter; @@ -139,7 +139,7 @@ typedef struct typedef struct { - LNK_SectionTable *st; + LNK_SectionTable *sectab; Rng1U64 *range_arr; U64 **chunk_ids; LNK_ObjNode *obj_arr; @@ -198,7 +198,7 @@ internal LNK_InputObjList lnk_input_obj_list_from_string_list(Arena *arena, Stri internal LNK_Obj ** lnk_obj_arr_from_list(Arena *arena, LNK_ObjList list); internal LNK_ObjNodeArray lnk_obj_list_reserve(Arena *arena, LNK_ObjList *list, U64 count); internal LNK_ChunkList * lnk_collect_obj_chunks(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded); -internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 *function_pad_min, U64 input_count, LNK_InputObj **inputs); +internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *sectab, U64 *function_pad_min, U64 input_count, LNK_InputObj **inputs); internal LNK_Chunk * lnk_sect_chunk_array_from_coff(Arena *arena, U64 obj_id, String8 obj_path, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, String8 *sect_name_arr, String8 *sect_postfix_arr); internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, LNK_Obj *obj, String8 obj_path, String8 lib_path, B32 is_big_obj, U64 function_pad_min, U64 sect_count, COFF_SectionHeader *section_table, U64 symbol_count, void *symbol_table, String8 string_table, LNK_ChunkPtr *chunk_table, LNK_Chunk *master_common_block); diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index a38ec9a7..4da0b857 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -271,33 +271,33 @@ lnk_section_table_alloc(U64 section_virt_off, U64 sect_align, U64 file_align) { ProfBeginFunction(); Arena *arena = arena_alloc(); - LNK_SectionTable *st = push_array(arena, LNK_SectionTable, 1); - st->arena = arena; - st->section_virt_off = section_virt_off; - st->sect_align = sect_align; - st->file_align = file_align; + LNK_SectionTable *sectab = push_array(arena, LNK_SectionTable, 1); + sectab->arena = arena; + sectab->section_virt_off = section_virt_off; + sectab->sect_align = sect_align; + sectab->file_align = file_align; ProfEnd(); - return st; + return sectab; } internal void lnk_section_table_release(LNK_SectionTable **st_ptr) { ProfBeginFunction(); - LNK_SectionTable *st = *st_ptr; - arena_release(st->arena); + LNK_SectionTable *sectab = *st_ptr; + arena_release(sectab->arena); *st_ptr = NULL; ProfEnd(); } internal LNK_Section * -lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags flags) +lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags) { ProfBeginFunction(); - LNK_SectionList *sect_list = &st->list; + LNK_SectionList *sect_list = §ab->list; - LNK_SectionNode *sect_node = push_array(st->arena, LNK_SectionNode, 1); - String8 sort_index = lnk_make_section_sort_index(st->arena, name, flags, st->id_max); + LNK_SectionNode *sect_node = push_array(sectab->arena, LNK_SectionNode, 1); + String8 sort_index = lnk_make_section_sort_index(sectab->arena, name, flags, sectab->id_max); B32 found = 0; for (LNK_SectionNode *curr = sect_list->first, *prev = NULL; curr != NULL; prev = curr, curr = curr->next) { @@ -320,8 +320,8 @@ lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags fla } sect_list->count += 1; - U64 sect_id = st->id_max; - st->id_max += 1; + U64 sect_id = sectab->id_max; + sectab->id_max += 1; LNK_Section *sect = §_node->data; sect->arena = arena_alloc(); @@ -329,7 +329,7 @@ lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags fla sect->name = push_str8_copy(sect->arena, name); sect->sort_index = sort_index; sect->flags = flags; - sect->cman = lnk_chunk_manager_alloc(sect->arena, sect_id, st->file_align); + sect->cman = lnk_chunk_manager_alloc(sect->arena, sect_id, sectab->file_align); sect->root = sect->cman->root; sect->nosort_chunk = lnk_chunk_push_list(sect->arena, sect->cman, sect->root, str8(0,0)); sect->nosort_chunk->sort_chunk = 0; @@ -345,12 +345,12 @@ lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags fla } internal LNK_Section * -lnk_section_table_push_null(LNK_SectionTable *st) +lnk_section_table_push_null(LNK_SectionTable *sectab) { - LNK_SectionList *list = &st->list; - SLLQueuePushFront(list->first, list->last, st->null_sect); + LNK_SectionList *list = §ab->list; + SLLQueuePushFront(list->first, list->last, sectab->null_sect); list->count += 1; - return &st->null_sect->data; + return §ab->null_sect->data; } LNK_CHUNK_VISITOR_SIG(lnk_chunk_has_leaf) @@ -375,12 +375,12 @@ LNK_CHUNK_VISITOR_SIG(lnk_chunk_mark_discarded) } internal void -lnk_section_table_remove(LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 name) +lnk_section_table_remove(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 name) { ProfBeginFunction(); // remove node from list - LNK_SectionNode *sect_node = lnk_section_list_remove(&st->list, name); + LNK_SectionNode *sect_node = lnk_section_list_remove(§ab->list, name); LNK_Section *sect = §_node->data; // remove symbol for section root chunk @@ -390,22 +390,22 @@ lnk_section_table_remove(LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 lnk_visit_chunks(sect->id, sect->root, lnk_chunk_mark_discarded, NULL); // push to empties - SLLQueuePush(st->empties_list.first, st->empties_list.last, sect_node); - st->empties_list.count += 1; + SLLQueuePush(sectab->empties_list.first, sectab->empties_list.last, sect_node); + sectab->empties_list.count += 1; ProfEnd(); } internal LNK_Section * -lnk_section_table_search(LNK_SectionTable *st, String8 name) +lnk_section_table_search(LNK_SectionTable *sectab, String8 name) { - return lnk_section_list_search(&st->list, name); + return lnk_section_list_search(§ab->list, name); } internal LNK_Section * -lnk_section_table_search_id(LNK_SectionTable *st, U64 id) +lnk_section_table_search_id(LNK_SectionTable *sectab, U64 id) { - for (LNK_SectionNode *node = st->list.first; node != NULL; node = node->next) { + for (LNK_SectionNode *node = sectab->list.first; node != NULL; node = node->next) { if (node->data.id == id) { return &node->data; } @@ -414,16 +414,16 @@ lnk_section_table_search_id(LNK_SectionTable *st, U64 id) } internal void -lnk_section_table_merge(LNK_SectionTable *st, LNK_MergeDirectiveList merge_list) +lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - LNK_Section **src_dst = push_array(scratch.arena, LNK_Section *, st->id_max); + LNK_Section **src_dst = push_array(scratch.arena, LNK_Section *, sectab->id_max); for (LNK_MergeDirectiveNode *merge_node = merge_list.first; merge_node != NULL; merge_node = merge_node->next) { LNK_MergeDirective *merge = &merge_node->data; // are we trying to merge section that was already merged? - LNK_Section *merge_sect = lnk_section_list_search(&st->merge_list, merge->src); + LNK_Section *merge_sect = lnk_section_list_search(§ab->merge_list, merge->src); if (merge_sect) { LNK_Section *dst = src_dst[merge_sect->id]; B32 is_ambiguous_merge = !str8_match(dst->name, merge->dst, 0); @@ -436,7 +436,7 @@ lnk_section_table_merge(LNK_SectionTable *st, LNK_MergeDirectiveList merge_list) } // find source seciton - LNK_Section *src = lnk_section_table_search(st, merge->src); + LNK_Section *src = lnk_section_table_search(sectab, merge->src); if (src == NULL) { lnk_error(LNK_Warning_IllData, "Can't find section \"%S\" to merge with \"%S\"", merge->src, merge->dst); // TODO: supplement obj path if applicable @@ -444,7 +444,7 @@ lnk_section_table_merge(LNK_SectionTable *st, LNK_MergeDirectiveList merge_list) } // handle case where destination section doesn't exist - LNK_Section *dst = lnk_section_table_search(st, merge->dst); + LNK_Section *dst = lnk_section_table_search(sectab, merge->dst); if (dst == NULL) { src->name = push_str8_copy(src->arena, merge->dst); src_dst[src->id] = src; @@ -458,24 +458,24 @@ lnk_section_table_merge(LNK_SectionTable *st, LNK_MergeDirectiveList merge_list) lnk_section_merge(dst, src); // remove from output section list - LNK_SectionNode *src_node = lnk_section_list_remove(&st->list, src->name); + LNK_SectionNode *src_node = lnk_section_list_remove(§ab->list, src->name); // push section to merged list - SLLQueuePush(st->merge_list.first, st->merge_list.last, src_node); - st->merge_list.count += 1; + SLLQueuePush(sectab->merge_list.first, sectab->merge_list.last, src_node); + sectab->merge_list.count += 1; } scratch_end(scratch); ProfEnd(); } internal void -lnk_section_table_remove_empties(LNK_SectionTable *st, LNK_SymbolTable *symtab) +lnk_section_table_remove_empties(LNK_SectionTable *sectab, LNK_SymbolTable *symtab) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); String8List name_list = {0}; - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; B32 no_data = 1; @@ -488,28 +488,28 @@ lnk_section_table_remove_empties(LNK_SectionTable *st, LNK_SymbolTable *symtab) } for (String8Node *name = name_list.first; name != NULL; name = name->next) { - lnk_section_table_remove(st, symtab, name->string); + lnk_section_table_remove(sectab, symtab, name->string); } scratch_end(scratch); ProfEnd(); } internal LNK_SectionArray -lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *st) +lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *sectab) { LNK_SectionArray result = {0}; result.count = 0; - result.v = push_array(arena, LNK_Section, st->list.count); + result.v = push_array(arena, LNK_Section, sectab->list.count); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) { if (sect_node->data.emit_header && sect_node->data.has_layout) { - Assert(result.count < st->list.count); + Assert(result.count < sectab->list.count); result.v[result.count] = sect_node->data; result.count += 1; } } - U64 unused_entry_count = st->list.count - result.count; + U64 unused_entry_count = sectab->list.count - result.count; arena_pop(arena, unused_entry_count * sizeof(result.v[0])); return result; @@ -526,12 +526,12 @@ THREAD_POOL_TASK_FUNC(lnk_section_data_builder) } internal void -lnk_section_table_build_data(TP_Context *tp, LNK_SectionTable *st, COFF_MachineType machine) +lnk_section_table_build_data(TP_Context *tp, LNK_SectionTable *sectab, COFF_MachineType machine) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - LNK_SectionPtrArray sect_arr = lnk_section_ptr_array_from_list(scratch.arena, st->list); + LNK_SectionPtrArray sect_arr = lnk_section_ptr_array_from_list(scratch.arena, sectab->list); LNK_SectionDataBuilder task = {0}; task.machine = machine; @@ -544,32 +544,32 @@ lnk_section_table_build_data(TP_Context *tp, LNK_SectionTable *st, COFF_MachineT } internal void -lnk_section_table_assign_virtual_offsets(LNK_SectionTable *st) +lnk_section_table_assign_virtual_offsets(LNK_SectionTable *sectab) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); - U64 cursor = st->section_virt_off; + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); + U64 cursor = sectab->section_virt_off; Assert(cursor >= 0x1000); - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { - if (sect_node == st->null_sect) continue; + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { + if (sect_node == sectab->null_sect) continue; LNK_Section *sect = §_node->data; if (!sect->has_layout) continue; sect->virt_off = cursor; U64 sect_size = lnk_virt_size_from_chunk_ref(sect_id_map, sect->root->ref); cursor += sect_size; - cursor = AlignPow2(cursor, st->sect_align); + cursor = AlignPow2(cursor, sectab->sect_align); } scratch_end(scratch); ProfEnd(); } internal void -lnk_section_table_assign_file_offsets(LNK_SectionTable *st) +lnk_section_table_assign_file_offsets(LNK_SectionTable *sectab) { ProfBeginFunction(); U64 cursor = 0; - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; if (sect->flags & COFF_SectionFlag_CntUninitializedData) { continue; @@ -583,11 +583,11 @@ lnk_section_table_assign_file_offsets(LNK_SectionTable *st) } internal void -lnk_section_table_assign_indices(LNK_SectionTable *st) +lnk_section_table_assign_indices(LNK_SectionTable *sectab) { ProfBeginFunction(); U64 isect = 0; - for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { + for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; if (sect->emit_header) { sect->isect = isect++; @@ -597,13 +597,13 @@ lnk_section_table_assign_indices(LNK_SectionTable *st) } internal String8 -lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st, COFF_MachineType machine) +lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *sectab, COFF_MachineType machine) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); U64 image_size = 0; - for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) { + for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) { LNK_Section *sect = §_n->data; if (sect->has_layout) { U64 root_size = sect->layout.chunk_file_size_array[sect->root->ref.chunk_id]; @@ -615,7 +615,7 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st, String8 image = str8(image_buffer, image_size); U64 image_cursor = 0; - for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) { + for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) { LNK_Section *sect = §_n->data; if (sect->has_layout) { if (sect->flags & COFF_SectionFlag_CntUninitializedData) { @@ -642,15 +642,15 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st, } internal LNK_ChunkPtr ** -lnk_chunk_id_map_from_section_table(Arena *arena, LNK_SectionTable *st) +lnk_chunk_id_map_from_section_table(Arena *arena, LNK_SectionTable *sectab) { ProfBeginFunction(); - LNK_ChunkPtr **chunk_id_map = push_array(arena, LNK_ChunkPtr *, st->id_max); - for (LNK_SectionNode *node = st->list.first; node != 0; node = node->next) { + LNK_ChunkPtr **chunk_id_map = push_array(arena, LNK_ChunkPtr *, sectab->id_max); + for (LNK_SectionNode *node = sectab->list.first; node != 0; node = node->next) { LNK_Section *sect = &node->data; chunk_id_map[sect->id] = lnk_make_chunk_id_map(arena, sect->cman); } - if (st->list.first->data.id != 0) { + if (sectab->list.first->data.id != 0) { chunk_id_map[0] = push_array(arena, LNK_ChunkPtr, 1); chunk_id_map[0][0] = g_null_chunk_ptr; } @@ -659,15 +659,15 @@ lnk_chunk_id_map_from_section_table(Arena *arena, LNK_SectionTable *st) } internal LNK_Section ** -lnk_sect_id_map_from_section_table(Arena *arena, LNK_SectionTable *st) +lnk_sect_id_map_from_section_table(Arena *arena, LNK_SectionTable *sectab) { ProfBeginFunction(); - LNK_Section **map = push_array(arena, LNK_Section *, st->id_max); - LNK_SectionList *list_arr[] = { &st->list, &st->merge_list, &st->empties_list }; + LNK_Section **map = push_array(arena, LNK_Section *, sectab->id_max); + LNK_SectionList *list_arr[] = { §ab->list, §ab->merge_list, §ab->empties_list }; for (U64 list_idx = 0; list_idx < ArrayCount(list_arr); ++list_idx) { for (LNK_SectionNode *sect_node = list_arr[list_idx]->first; sect_node != NULL; sect_node = sect_node->next) { LNK_Section *sect = §_node->data; - Assert(sect->id < st->id_max); + Assert(sect->id < sectab->id_max); Assert(map[sect->id] == NULL); map[sect->id] = sect; } @@ -880,12 +880,12 @@ lnk_file_size_from_symbol(LNK_Section **sect_id_map, LNK_Symbol *symbol) #if LNK_DEBUG_CHUNKS internal void -lnk_dump_chunks(LNK_SectionTable *st) +lnk_dump_chunks(LNK_SectionTable *sectab) { Temp scratch = scratch_begin(0, 0); - LNK_ChunkPtr **chunk_id_map = lnk_chunk_id_map_from_section_table(scratch.arena, st); - LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); - for (U64 sect_id = 0; sect_id < st->id_max; ++sect_id) { + LNK_ChunkPtr **chunk_id_map = lnk_chunk_id_map_from_section_table(scratch.arena, sectab); + LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, sectab); + for (U64 sect_id = 0; sect_id < sectab->id_max; ++sect_id) { LNK_Section *sect = sect_id_map[sect_id]; if (!sect) continue; if (sect->is_merged) continue; diff --git a/src/linker/lnk_section_table.h b/src/linker/lnk_section_table.h index 4aa6f2c3..770b934b 100644 --- a/src/linker/lnk_section_table.h +++ b/src/linker/lnk_section_table.h @@ -110,21 +110,21 @@ internal LNK_Chunk * lnk_section_push_chunk_list(LNK_Section *sect, LNK_Chunk internal LNK_SectionTable * lnk_section_table_alloc(U64 section_virt_off, U64 sect_align, U64 file_align); internal void lnk_section_table_release(LNK_SectionTable **st_ptr); -internal LNK_Section * lnk_section_table_push(LNK_SectionTable *st, String8 name, COFF_SectionFlags flags); -internal LNK_Section * lnk_section_table_push_null(LNK_SectionTable *st); -internal void lnk_section_table_remove(LNK_SectionTable *st, LNK_SymbolTable *symtab, String8 name); -internal LNK_Section * lnk_section_table_search(LNK_SectionTable *st, String8 name); -internal LNK_Section * lnk_section_table_search_id(LNK_SectionTable *st, U64 id); -internal void lnk_section_table_merge(LNK_SectionTable *st, LNK_MergeDirectiveList merge_list); -internal void lnk_section_table_remove_empties(LNK_SectionTable *st, LNK_SymbolTable *symtab); -internal void lnk_section_table_build_data(TP_Context *tp, LNK_SectionTable *st, COFF_MachineType machine); -internal void lnk_section_table_assign_virtual_offsets(LNK_SectionTable *st); -internal void lnk_section_table_assign_file_offsets(LNK_SectionTable *st); -internal void lnk_section_table_assign_indices(LNK_SectionTable *st); -internal String8 lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st, COFF_MachineType machine); +internal LNK_Section * lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags); +internal LNK_Section * lnk_section_table_push_null(LNK_SectionTable *sectab); +internal void lnk_section_table_remove(LNK_SectionTable *sectab, LNK_SymbolTable *symtab, String8 name); +internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name); +internal LNK_Section * lnk_section_table_search_id(LNK_SectionTable *sectab, U64 id); +internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list); +internal void lnk_section_table_remove_empties(LNK_SectionTable *sectab, LNK_SymbolTable *symtab); +internal void lnk_section_table_build_data(TP_Context *tp, LNK_SectionTable *sectab, COFF_MachineType machine); +internal void lnk_section_table_assign_virtual_offsets(LNK_SectionTable *sectab); +internal void lnk_section_table_assign_file_offsets(LNK_SectionTable *sectab); +internal void lnk_section_table_assign_indices(LNK_SectionTable *sectab); +internal String8 lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *sectab, COFF_MachineType machine); -internal LNK_ChunkPtr ** lnk_chunk_id_map_from_section_table(Arena *arena, LNK_SectionTable *st); -internal LNK_Section ** lnk_sect_id_map_from_section_table(Arena *arena, LNK_SectionTable *st); +internal LNK_ChunkPtr ** lnk_chunk_id_map_from_section_table(Arena *arena, LNK_SectionTable *sectab); +internal LNK_Section ** lnk_sect_id_map_from_section_table(Arena *arena, LNK_SectionTable *sectab); internal LNK_ChunkRef lnk_get_final_chunk_ref(LNK_Section **sect_id_map, LNK_ChunkRef chunk_ref); internal LNK_Section * lnk_sect_from_chunk_ref(LNK_Section **sect_id_map, LNK_ChunkRef chunk_ref); internal LNK_Chunk * lnk_chunk_from_chunk_ref(LNK_Section **sect_id_map, LNK_ChunkPtr **chunk_id_map, LNK_ChunkRef chunk_ref); @@ -146,6 +146,6 @@ internal U64 lnk_virt_size_from_symbol(LNK_Section **sect_id_map, LN internal U64 lnk_file_size_from_symbol(LNK_Section **sect_id_map, LNK_Symbol *symbol); #if LNK_DEBUG_CHUNKS -internal void lnk_dump_chunks(LNK_SectionTable *st); +internal void lnk_dump_chunks(LNK_SectionTable *sectab); #endif diff --git a/src/linker/pdb_ext/msf_builder.c b/src/linker/pdb_ext/msf_builder.c index 9905147f..5ae0036d 100644 --- a/src/linker/pdb_ext/msf_builder.c +++ b/src/linker/pdb_ext/msf_builder.c @@ -798,7 +798,7 @@ msf_stream_alloc_(Arena *arena, MSF_StreamList *list) internal MSF_StreamNumber msf_stream_alloc_ex(MSF_Context *msf, MSF_UInt size) { - MSF_StreamNode *node = msf_stream_alloc_(msf->arena, &msf->st); + MSF_StreamNode *node = msf_stream_alloc_(msf->arena, &msf->sectab); MSF_Stream *stream = &node->data; msf_stream_resize_ex(msf, stream, size); return stream->sn; @@ -854,7 +854,7 @@ msf_stream_free(MSF_Context *msf, MSF_StreamNumber sn) B32 is_free_ok = 0; MSF_StreamNode *stream_node = msf_find_stream_node(msf, sn); if (stream_node) { - msf_stream_list_remove(&msf->st, stream_node); + msf_stream_list_remove(&msf->sectab, stream_node); msf_stream_resize_ex(msf, &stream_node->data, 0); stream_node->data.size = MSF_DELETED_STREAM_STAMP; is_free_ok = 1; @@ -1382,7 +1382,7 @@ internal MSF_StreamNode * msf_find_stream_node(MSF_Context *msf, MSF_StreamNumber sn) { MSF_StreamNode *node; - for (node = msf->st.first; node != 0; node = node->next) { + for (node = msf->sectab.first; node != 0; node = node->next) { if (node->data.sn == sn) { break; } @@ -1645,7 +1645,7 @@ msf_open(String8 data, MSF_Context **msf_out) msf->header_page_list = header_page_list; msf->root_page_list = root_page_list; msf->st_page_list = st_page_list; - msf->st = stream_list; + msf->sectab = stream_list; *msf_out = msf; @@ -1678,19 +1678,19 @@ msf_release(MSF_Context **msf_ptr) } internal String8List -msf_build_stream_table_data(Arena *arena, MSF_StreamList *st, MSF_UInt page_size, MSF_UInt page_count) +msf_build_stream_table_data(Arena *arena, MSF_StreamList *sectab, MSF_UInt page_size, MSF_UInt page_count) { ProfBeginFunction(); MSF_UInt *stream_count_ptr = push_array(arena, MSF_UInt, 1); - *stream_count_ptr = st->count; + *stream_count_ptr = sectab->count; - MSF_UInt *stream_size_arr = push_array(arena, MSF_UInt, st->count); + MSF_UInt *stream_size_arr = push_array(arena, MSF_UInt, sectab->count); MSF_UInt stream_page_count = 0; MSF_PageNumber *stream_pages_arr = push_array(arena, MSF_PageNumber, page_count); - for (MSF_StreamNode *stream_node = st->first; stream_node != 0; stream_node = stream_node->next) { + for (MSF_StreamNode *stream_node = sectab->first; stream_node != 0; stream_node = stream_node->next) { MSF_Stream *stream = &stream_node->data; // is page list correct? @@ -1747,7 +1747,7 @@ msf_build_stream_table(MSF_Context *msf, MSF_UInt *stream_table_size_out) MSF_Error error = MSF_Error_OK; - String8List st_data_list = msf_build_stream_table_data(scratch.arena, &msf->st, msf->page_size, msf->page_count); + String8List st_data_list = msf_build_stream_table_data(scratch.arena, &msf->sectab, msf->page_size, msf->page_count); MSF_UInt st_page_count = msf_count_pages(msf->page_size, st_data_list.total_size); msf_free_pages(msf, &msf->st_page_list); // TODO: page reuse diff --git a/src/linker/pdb_ext/msf_builder.h b/src/linker/pdb_ext/msf_builder.h index 40aba132..c9bda071 100644 --- a/src/linker/pdb_ext/msf_builder.h +++ b/src/linker/pdb_ext/msf_builder.h @@ -82,7 +82,7 @@ typedef struct MSF_Context MSF_PageList root_page_list; MSF_PageList st_page_list; MSF_PageList page_pool; - MSF_StreamList st; + MSF_StreamList sectab; } MSF_Context; typedef enum MSF_Error From ea5aab3f7e75ccb41d861428b05d244e9b5a009a Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Fri, 4 Apr 2025 15:50:23 -0700 Subject: [PATCH 313/755] remove assert for empty switch --- src/linker/lnk_config.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index e1f20096..53ad9cda 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -954,8 +954,6 @@ lnk_expand_env_vars_windows(Arena *arena, HashTable *env_vars, String8 string) internal void lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_name, String8List value_strings, String8 obj_path, String8 lib_path) { - Assert(cmd_name.size); // switch must have a defined name in the table - Temp scratch = scratch_begin(&arena,1); LNK_CmdSwitchType cmd_switch = lnk_cmd_switch_type_from_string(cmd_name); From d060cb58b7769cbd5eb83cf0ddad9923431f2b23 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sat, 5 Apr 2025 11:59:02 -0700 Subject: [PATCH 314/755] disable import library for radlink build --- build.bat | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.bat b/build.bat index 343f3f37..e2cc8eef 100644 --- a/build.bat +++ b/build.bat @@ -52,14 +52,14 @@ set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /pdbaltpath:%%%%_PDB%%% set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /pdbaltpath:%%%%_PDB%%%% -Xlinker /NATVIS:"%~dp0\src\natvis\base.natvis" set cl_out= /out: set clang_out= -o -set cl_natvis= /NATVIS: -set clang_natvis= -Xlinker /NATVIS: +set cl_linker= +set clang_linker= -Xlinker :: --- Per-Build Settings ----------------------------------------------------- set link_dll=-DLL set link_icon=logo.res -if "%msvc%"=="1" set link_natvis=%cl_natvis% -if "%clang%"=="1" set link_natvis=%clang_natvis% +if "%msvc%"=="1" set linker=%cl_linker% +if "%clang%"=="1" set linker=%clang_linker% if "%msvc%"=="1" set only_compile=/c if "%clang%"=="1" set only_compile=-c if "%msvc%"=="1" set EHsc=/EHsc @@ -106,7 +106,7 @@ if not "%no_meta%"=="1" ( :: --- Build Everything (@build_targets) -------------------------------------- pushd build if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %link_icon% %out%raddbg.exe || exit /b 1 -if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 +if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %linker% /NOIMPLIB %linker% /NATVIS:"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 if "%radcon%"=="1" set didbuild=1 && %compile% ..\src\radcon\radcon_main.c %compile_link% %out%radcon.exe || exit /b 1 if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 From 0705ba0a961ed210eab42d9b8839beef235b99eb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 3 Apr 2025 16:36:59 -0700 Subject: [PATCH 315/755] begin plugging in view rules as formal call part of expression language --- src/eval/eval.mdesk | 4 +- src/eval/eval_bundles.c | 1 + src/eval/eval_bundles.h | 1 + src/eval/eval_core.h | 2 +- src/eval/eval_ir.c | 143 +++++++------ src/eval/generated/eval.meta.c | 8 +- src/eval/generated/eval.meta.h | 7 +- .../eval_visualization_core.c | 2 +- src/mule/mule_main.cpp | 6 +- src/raddbg/raddbg_core.c | 188 ++++++------------ src/raddbg/raddbg_main.c | 6 + src/raddbg/raddbg_views.c | 20 +- src/scratch/eval_scratch.c | 2 +- 13 files changed, 158 insertions(+), 232 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 976f691b..ce6ce9a0 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,7 +71,7 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } - {Set "set" 0 } + {Stub "stub" 0 } } @table(name op_kind precedence op_pre op_sep op_pos) @@ -134,8 +134,6 @@ E_ExprKindTable: { Func Null 0 "" "" "" } { Define Binary 13 "" "=" "" } - - { Tag Null 0 "=>" "," "" } } @table(name display_string) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index e14531e9..945a1b89 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -27,6 +27,7 @@ e_eval_from_exprs(Arena *arena, E_ExprChain exprs) .space = interp.space, .exprs = exprs, .irtree = irtree, + .bytecode = bytecode, .lookup_rule_tag = lookup, .code = interp.code, }; diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index 311a752e..f2ad6c85 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -14,6 +14,7 @@ struct E_Eval E_Space space; E_ExprChain exprs; E_IRTreeAndType irtree; + String8 bytecode; E_LookupRuleTagPair lookup_rule_tag; E_InterpretationCode code; E_MsgList msgs; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index edbb5702..083b0435 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -535,7 +535,7 @@ struct E_LookupRuleTagPair //////////////////////////////// //~ rjf: IR Generation Hooks -#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag) +#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr) #define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name #define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 7f34255a..f93e27ad 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -69,11 +69,12 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - 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 = &e_string2expr_map_nil;} + if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } + 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_ir_state->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_ir_state->arena, 512); } e_ir_state->ctx = ctx; e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->thread_ip_voff); e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); @@ -88,6 +89,18 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); e_ir_state->string_id_map->hash_slots_count = 1024; e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); + String8 builtin_view_rule_names[] = + { + str8_lit_comp("bswap"), + str8_lit_comp("array"), + }; + for EachElement(idx, builtin_view_rule_names) + { + E_Expr *expr = e_push_expr(e_ir_state->arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("view_rule")); + expr->value.u64 = e_id_from_string(builtin_view_rule_names[idx]); + e_string2expr_map_insert(e_ir_state->arena, ctx->macro_map, builtin_view_rule_names[idx], expr); + } } //////////////////////////////// @@ -179,7 +192,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("folder")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(folder_path); expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); @@ -189,7 +202,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) String8 file_name = accel->files.v[idx - accel->folders.count]; String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("file")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(file_path); expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); @@ -866,7 +879,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) enum_type_key = lhs_type_key; do_enum_range = 1; } - else if(lhs_type_kind == E_TypeKind_Set) + else if(lhs_type_kind == E_TypeKind_Stub) { do_index_range = 1; } @@ -1177,15 +1190,6 @@ e_lookup_rule_from_string(String8 string) //////////////////////////////// //~ rjf: IR Gen Rules -E_IRGEN_FUNCTION_DEF(cast) -{ - E_Expr *type_expr = tag->first->next; - E_TypeKey type_key = e_type_from_expr(type_expr); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_IRTreeAndType result = {irtree.root, type_key, irtree.member, irtree.mode, irtree.msgs}; - return result; -} - E_IRGEN_FUNCTION_DEF(bswap) { E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); @@ -1197,60 +1201,20 @@ E_IRGEN_FUNCTION_DEF(bswap) E_IRGEN_FUNCTION_DEF(array) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_TypeKey type_key = irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind)) - { - E_Value count_value = e_value_from_expr(tag->first->next); - E_TypeKey element_type_key = e_type_ptee_from_key(type_key); - E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); - irtree.type_key = ptr_type_key; - } - return irtree; + E_Expr *ptr_expr = expr->first->next; + E_Expr *count_expr = ptr_expr->next; + E_IRTreeAndType result = e_irtree_and_type_from_expr(arena, ptr_expr); + E_TypeKey element_type_key = e_type_ptee_from_key(result.type_key); + E_Value count_value = e_value_from_expr(count_expr); + result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); + return result; } -E_IRGEN_FUNCTION_DEF(wrap) +E_IRGEN_FUNCTION_DEF(view_rule_noop) { - Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr_to_irify = expr; - E_Expr *wrap_expr_src = tag->first->next; - if(wrap_expr_src != &e_expr_nil) - { - expr_to_irify = e_expr_copy(scratch.arena, wrap_expr_src); - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *parent; - E_Expr *expr; - }; - Task start_task = {0, &e_expr_nil, expr_to_irify}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - if(t->expr->kind == E_ExprKind_LeafIdentifier && str8_match(t->expr->string, str8_lit("$expr"), 0)) - { - E_Expr *original_expr_ref = e_expr_ref(arena, expr); - if(t->parent != &e_expr_nil) - { - e_expr_insert_child(t->parent, t->expr, original_expr_ref); - e_expr_remove_child(t->parent, t->expr); - } - } - else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = t->expr; - task->expr = child; - } - } - } - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr_to_irify); - scratch_end(scratch); - return irtree; + E_Expr *expr_arg = expr->first->next; + E_IRTreeAndType result = e_irtree_and_type_from_expr(arena, expr_arg); + return result; } internal E_IRGenRuleMap @@ -1260,10 +1224,8 @@ e_irgen_rule_map_make(Arena *arena, U64 slots_count) map.slots_count = slots_count; map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); e_irgen_rule_map_insert_new(arena, &map, str8_lit("default"), .irgen = E_IRGEN_FUNCTION_NAME(default)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("cast"), .irgen = E_IRGEN_FUNCTION_NAME(cast)); e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("wrap"), .irgen = E_IRGEN_FUNCTION_NAME(wrap)); return map; } @@ -2458,6 +2420,37 @@ E_IRGEN_FUNCTION_DEF(default) } }break; + //- rjf: call + case E_ExprKind_Call: + { + E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(lhs_type->kind == E_TypeKind_Stub) + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + String8 name = e_string_from_id(interp.value.u64); + E_IRGenRule *irgen_rule = e_irgen_rule_from_string(name); + if(irgen_rule != &e_irgen_rule__default) + { + result = irgen_rule->irgen(arena, expr); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "There is no rule named `%S`.", name); + } + scratch_end(scratch); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not currently supported."); + } + }break; + //- rjf: leaf bytecode case E_ExprKind_LeafBytecode: { @@ -2970,7 +2963,7 @@ E_IRGEN_FUNCTION_DEF(default) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("file")); result.mode = E_Mode_Value; } else @@ -2981,7 +2974,7 @@ E_IRGEN_FUNCTION_DEF(default) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("folder")); result.mode = E_Mode_Value; } } @@ -3074,10 +3067,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: do this rule's generation ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) { - result = t->rule->irgen(arena, expr, t->tag); + result = t->rule->irgen(arena, expr); if(result.root == &e_irnode_nil && t->rule != &e_irgen_rule__default) { - result = e_irgen_rule__default.irgen(arena, expr, &e_expr_nil); + result = e_irgen_rule__default.irgen(arena, expr); } } @@ -3419,7 +3412,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) if(!default_is_forced && result.rule == &e_lookup_rule__default) { E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); - if(type_kind == E_TypeKind_Set) + if(type_kind == E_TypeKind_Stub) { E_Type *type = e_type_from_key__cached(irtree->type_key); String8 name = type->name; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 14af0ad1..851d9687 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -71,7 +71,7 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), -str8_lit_comp("set"), +str8_lit_comp("stub"), }; U8 e_type_kind_basic_byte_size_table[56] = @@ -134,7 +134,7 @@ U8 e_type_kind_basic_byte_size_table[56] = 0, }; -String8 e_expr_kind_strings[49] = +String8 e_expr_kind_strings[48] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -184,10 +184,9 @@ str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), str8_lit_comp("Define"), -str8_lit_comp("Tag"), }; -E_OpInfo e_expr_kind_op_info_table[49] = +E_OpInfo e_expr_kind_op_info_table[48] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -237,7 +236,6 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; String8 e_interpretation_code_display_strings[11] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 5ccfe7e1..fb48f62d 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,7 +74,7 @@ E_TypeKind_IncompleteClass, E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, -E_TypeKind_Set, +E_TypeKind_Stub, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -139,7 +139,6 @@ E_ExprKind_Ptr, E_ExprKind_Array, E_ExprKind_Func, E_ExprKind_Define, -E_ExprKind_Tag, E_ExprKind_COUNT, } E_ExprKindEnum; @@ -163,8 +162,8 @@ C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; extern String8 e_type_kind_basic_string_table[56]; extern U8 e_type_kind_basic_byte_size_table[56]; -extern String8 e_expr_kind_strings[49]; -extern E_OpInfo e_expr_kind_op_info_table[49]; +extern String8 e_expr_kind_strings[48]; +extern E_OpInfo e_expr_kind_op_info_table[48]; extern String8 e_interpretation_code_display_strings[11]; C_LINKAGE_END diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 7ceb35c3..ae77d8de 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -94,7 +94,7 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) kind == E_TypeKind_Union || kind == E_TypeKind_Class || kind == E_TypeKind_Array || - kind == E_TypeKind_Set || + kind == E_TypeKind_Stub || (kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index b7514dc4..3962a8db 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -106,7 +106,7 @@ void optimized_struct_parameters_eval_tests(void); #include #include -raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); +// raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); struct Basics{ char a; @@ -150,7 +150,7 @@ struct Dynamic_Array{ Pair *pairs; int count; }; -raddbg_auto_view_rule(Dynamic_Array, slice); +// raddbg_auto_view_rule(Dynamic_Array, slice); struct Struct_With_Embedded_Arrays{ int x; @@ -1620,7 +1620,7 @@ struct Bitmap int width; int height; }; -raddbg_auto_view_rule(Bitmap, bitmap(base, width, height)); +// raddbg_auto_view_rule(Bitmap, bitmap(base, width, height)); static unsigned int mule_bswap_u32(unsigned int x) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 158d288d..c84984e7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -107,7 +107,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) { E_Eval eval = e_eval_from_string(scratch.arena, expr); E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind != E_TypeKind_Set) + if(type->kind != E_TypeKind_Stub) { passes_filter = 0; FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); @@ -441,7 +441,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) } else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) { - child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); + child_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = child_schema->string); } //- rjf: evaluate @@ -4706,7 +4706,7 @@ rd_view_ui(Rng2F32 rect) E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); E_TypeKey block_type_key = block_irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Set) + if(block_type_kind == E_TypeKind_Stub) { E_Type *block_type = e_type_from_key__cached(block_type_key); group_cfg_name = rd_singular_from_code_name_plural(block_type->name); @@ -10788,7 +10788,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f case E_TypeKind_IncompleteStruct: case E_TypeKind_IncompleteUnion: case E_TypeKind_IncompleteClass: - case E_TypeKind_Set: + case E_TypeKind_Stub: arrays_and_sets_and_structs: { // rjf: unpack @@ -13527,92 +13527,13 @@ rd_frame(void) 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: build special member types for evallable meta types - E_TypeKey bool_type_key = {0}; - E_TypeKey u64_type_key = {0}; - E_TypeKey vaddr_range_type_key = {0}; - E_TypeKey code_string_type_key = {0}; - E_TypeKey path_type_key = {0}; - E_TypeKey string_type_key = {0}; - E_TypeKey path_pt_type_key = {0}; - { - E_MemberList vaddr_range_members_list = {0}; - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); - E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); - bool_type_key = e_type_key_basic(E_TypeKind_Bool); - u64_type_key = e_type_key_basic(E_TypeKind_U64); - vaddr_range_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); - code_string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - path_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); - string_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPlainText); - path_pt_type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsPathText); - } - - //- rjf: build types for each evallable meta name - struct - { - String8 schema_type_name; - E_TypeKey type_key; - } - schema_type_name_key_map[] = - { - { str8_lit("bool"), bool_type_key }, - { str8_lit("u64"), u64_type_key }, - { str8_lit("vaddr_range"), vaddr_range_type_key }, - { str8_lit("code_string"), code_string_type_key }, - { str8_lit("path"), path_type_key }, - { str8_lit("string"), string_type_key }, - { str8_lit("path_pt"), path_pt_type_key }, - }; - E_TypeKey evallable_meta_types[ArrayCount(rd_name_schema_info_table)] = {0}; - for EachElement(idx, rd_name_schema_info_table) - { - String8 name = rd_name_schema_info_table[idx].name; - MD_Node *schema = rd_schema_from_name(name); - E_MemberList members_list = {0}; - U64 off = 0; - for MD_EachNode(child, schema->first) - { - if(str8_match(child->first->string, str8_lit("query"), 0)) - { - e_member_list_push_new(scratch.arena, &members_list, - .type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child->string), - .name = child->string); - } - else - { - String8 member_name = child->string; - E_TypeKey member_type_key = zero_struct; - for EachElement(schema_type_name_idx, schema_type_name_key_map) - { - if(str8_match(child->first->string, schema_type_name_key_map[schema_type_name_idx].schema_type_name, 0)) - { - member_type_key = schema_type_name_key_map[schema_type_name_idx].type_key; - break; - } - } - e_member_list_push_new(scratch.arena, &members_list, - .type_key = member_type_key, - .name = member_name, - .off = off); - off += e_type_byte_size_from_key(member_type_key); - } - } - E_MemberArray members = e_member_array_from_list(scratch.arena, &members_list); - evallable_meta_types[idx] = e_type_key_cons(.name = name, - .kind = E_TypeKind_Set, - .members = members.v, - .count = members.count); - } - //- rjf: cache meta name -> type key correllation rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; - E_TypeKey type_key = evallable_meta_types[idx]; + E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Stub); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(schema), @@ -13741,7 +13662,7 @@ rd_frame(void) { String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name, .flags = E_TypeFlag_EditableChildren); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, @@ -13783,7 +13704,7 @@ rd_frame(void) { String8 collection_name = collection_infos[idx].name; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = collection_infos[idx].lookup_info, @@ -13803,7 +13724,7 @@ rd_frame(void) { String8 name = debug_info_table_collection_names[idx]; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = name); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, @@ -13818,7 +13739,7 @@ rd_frame(void) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13836,7 +13757,7 @@ rd_frame(void) { String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; String8 collection_name = rd_plural_from_code_name(kind_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13850,7 +13771,7 @@ rd_frame(void) //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); @@ -13863,7 +13784,7 @@ rd_frame(void) //- rjf: add macro for commands { String8 name = str8_lit("commands"); - E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13950,6 +13871,53 @@ rd_frame(void) } e_select_ir_ctx(ir_ctx); + //////////////////////////// + //- rjf: generate macros for all view ui rules + // + { + //- rjf: choose set of view ui rules + // TODO(rjf): generate via metaprogram + struct + { + String8 name; + RD_ViewUIFunctionType *ui; + EV_ExpandRuleInfoHookFunctionType *expand; + } + view_ui_rule_table[] = + { + {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + }; + + //- rjf: fill view ui rules in expand rule map, view ui rule map + EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); + ev_select_expand_rule_table(expand_rule_table); + rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); + { + for EachElement(idx, view_ui_rule_table) + { + e_irgen_rule_map_insert_new(scratch.arena, e_ir_state->ctx->irgen_rule_map, view_ui_rule_table[idx].name, E_IRGEN_FUNCTION_NAME(view_rule_noop)); + rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, view_ui_rule_table[idx].name, view_ui_rule_table[idx].ui); + if(view_ui_rule_table[idx].expand != 0) + { + ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, view_ui_rule_table[idx].name, view_ui_rule_table[idx].expand); + } + } + } + for EachElement(idx, view_ui_rule_table) + { + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("view_rule")); + expr->value.u64 = e_id_from_string(view_ui_rule_table[idx].name); + e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); + } + } + //////////////////////////// //- rjf: build eval interpretation context // @@ -13969,44 +13937,6 @@ rd_frame(void) } e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); - //////////////////////////// - //- rjf: build eval expand rule table - // - EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); - ev_select_expand_rule_table(expand_rule_table); - - //////////////////////////// - //- rjf: build view ui rule map - // - rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); - { - // TODO(rjf): generate via metaprogram - struct - { - String8 name; - RD_ViewUIFunctionType *ui; - EV_ExpandRuleInfoHookFunctionType *expand; - } - table[] = - { - {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, - {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, - {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, - {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, - }; - for EachElement(idx, table) - { - rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, table[idx].name, table[idx].ui); - if(table[idx].expand != 0) - { - ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, table[idx].name, table[idx].expand); - } - } - } - //////////////////////////// //- rjf: autosave if needed // diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index a127444a..48865106 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -89,6 +89,12 @@ //////////////////////////////// //~ rjf: feature cleanup, code dedup, code elimination pass: // +// [ ] 'view rules' need to be rephrased as "function" calls in the expression language +// [ ] need a formalization which takes unknown identifiers which are called, and tries +// to use that to apply a IR-generation rule, which is keyed by that unknown +// identifier +// [ ] *ALL* expressions in watch windows need to be editable. +// // [ ] config hot-reloading, using cfg wins // [ ] undo/redo, using cfg wins // [ ] back/forward, using cfg wins diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0b33bad5..1c2b2803 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1002,21 +1002,21 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine ctrl entity - if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || - block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + if(block_type_kind == E_TypeKind_Stub && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); } // rjf: determine cfg group name / parent - if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || - block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) + if(block_type_kind == E_TypeKind_Stub && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) { info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); } // rjf: determine group cfg name - if(block_type_kind == E_TypeKind_Set) + if(block_type_kind == E_TypeKind_Stub) { String8 singular_name = rd_singular_from_code_name_plural(block_type->name); if(singular_name.size != 0) @@ -1070,7 +1070,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) + if(type->kind == E_TypeKind_Stub) { String8 file_path = e_string_from_id(info.eval.value.u64); DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); @@ -1226,7 +1226,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) + if(type->kind == E_TypeKind_Stub) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); } @@ -1282,7 +1282,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: procedures collections get only expr/value/view-rule - else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) + else if(block_type->kind == E_TypeKind_Stub && str8_match(block_type->name, str8_lit("procedures"), 0)) { info.cell_style_key = str8_lit("expr_value_viewrule"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1565,7 +1565,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla else if(result.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) + if(type->kind == E_TypeKind_Stub) { String8 file_path = e_string_from_id(result.eval.value.u64); result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); @@ -1633,7 +1633,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla else if(result.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) + if(type->kind == E_TypeKind_Stub) { String8 file_path = e_string_from_id(result.eval.value.u64); result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c index b83d0d1c..24246e6f 100644 --- a/src/scratch/eval_scratch.c +++ b/src/scratch/eval_scratch.c @@ -60,7 +60,7 @@ entry_point(CmdLine *cmdline) } //- rjf: parse - E_Parse parse = e_parse_expr_from_text_tokens(arena, expr_text, &tokens); + E_Parse parse = e_parse_expr_from_text_tokens(arena, expr_text, tokens); { typedef struct Task Task; struct Task From 0c999d70dc6ac90cf754e282814733288daebc3b Mon Sep 17 00:00:00 2001 From: Martins Mozeiko Date: Sun, 6 Apr 2025 20:58:35 -0700 Subject: [PATCH 316/755] better error message if CreateProcess fails --- src/demon/win32/demon_core_win32.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 5ed5e044..5c40854e 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1312,7 +1312,13 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) } else { - log_user_errorf("There was an error starting %S.", params->cmd_line.first->string); + DWORD error = GetLastError(); + LPWSTR message = 0; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL), (LPWSTR)&message, 0, 0); + String8 message8 = message ? str8_from_16(scratch.arena, str16_cstring(message)) : str8_lit("unknown error"); + LocalFree(message); + + log_user_errorf("There was an error starting %S: %S", params->cmd_line.first->string, message8); } } scratch_end(scratch); From 710828c67df7ecd93b2eccf0a933c01389283723 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 08:02:11 -0700 Subject: [PATCH 317/755] checkpoint in switching to new call-style of view rules for everything --- src/eval/eval_core.h | 2 - src/eval/eval_ir.c | 182 +++++++++--------- src/eval/eval_ir.h | 41 ++-- src/eval/eval_parse.c | 16 +- src/eval/eval_parse.h | 1 - .../eval_visualization_core.c | 4 +- src/raddbg/raddbg_main.c | 5 + 7 files changed, 115 insertions(+), 136 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 083b0435..1a5792b9 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -321,8 +321,6 @@ struct E_Expr { E_Expr *first; E_Expr *last; - E_Expr *first_tag; - E_Expr *last_tag; E_Expr *next; E_Expr *prev; E_Expr *ref; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index f93e27ad..cc0691b1 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -77,9 +77,9 @@ e_select_ir_ctx(E_IRCtx *ctx) if(ctx->macro_map == 0) { ctx->macro_map = push_array(e_ir_state->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_ir_state->arena, 512); } e_ir_state->ctx = ctx; e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->thread_ip_voff); - e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); - e_ir_state->used_tag_map->slots_count = 64; - e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); + e_ir_state->used_expr_map = push_array(e_ir_state->arena, E_UsedExprMap, 1); + e_ir_state->used_expr_map->slots_count = 64; + e_ir_state->used_expr_map->slots = push_array(e_ir_state->arena, E_UsedExprSlot, e_ir_state->used_expr_map->slots_count); e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); e_ir_state->type_auto_hook_cache_map->slots_count = 256; e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); @@ -1304,7 +1304,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * } internal E_ExprList -e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) +e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { ProfBeginFunction(); E_ExprList exprs = {0}; @@ -1371,7 +1371,7 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } internal E_ExprList -e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) +e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key) { E_ExprList exprs = {0}; if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->type_auto_hook_cache_map != 0 && e_ir_state->type_auto_hook_cache_map->slots_count != 0) @@ -1393,7 +1393,7 @@ e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key) node = push_array(e_ir_state->arena, E_TypeAutoHookCacheNode, 1); SLLQueuePush(e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_state->type_auto_hook_cache_map->slots[slot_idx].last, node); node->key = type_key; - node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key); + node->exprs = e_auto_hook_exprs_from_type_key(e_type_state->arena, type_key); } exprs = node->exprs; } @@ -1759,14 +1759,14 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type //- rjf: rule tag poison checking internal B32 -e_tag_is_poisoned(E_Expr *tag) +e_expr_is_poisoned(E_Expr *expr) { B32 tag_is_poisoned = 0; - U64 hash = e_hash_from_string(5381, str8_struct(&tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + U64 hash = e_hash_from_string(5381, str8_struct(&expr)); + U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { - if(n->tag == tag) + if(n->expr == expr) { tag_is_poisoned = 1; break; @@ -1776,25 +1776,25 @@ e_tag_is_poisoned(E_Expr *tag) } internal void -e_tag_poison(E_Expr *tag) +e_expr_poison(E_Expr *expr) { - U64 hash = e_hash_from_string(5381, str8_struct(&tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - E_UsedTagNode *n = push_array(e_ir_state->arena, E_UsedTagNode, 1); - n->tag = tag; - DLLPushBack(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); + U64 hash = e_hash_from_string(5381, str8_struct(&expr)); + U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; + E_UsedExprNode *n = push_array(e_ir_state->arena, E_UsedExprNode, 1); + n->expr = expr; + DLLPushBack(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); } internal void -e_tag_unpoison(E_Expr *tag) +e_expr_unpoison(E_Expr *expr) { - U64 hash = e_hash_from_string(5381, str8_struct(&tag)); - U64 slot_idx = hash%e_ir_state->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_state->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + U64 hash = e_hash_from_string(5381, str8_struct(&expr)); + U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { - if(n->tag == tag) + if(n->expr == expr) { - DLLRemove(e_ir_state->used_tag_map->slots[slot_idx].first, e_ir_state->used_tag_map->slots[slot_idx].last, n); + DLLRemove(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); break; } } @@ -1818,14 +1818,14 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_LookupRuleTagPair lhs_lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(lhs, &lhs_irtree); - ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule_and_tag.rule->name)) + E_LookupRule *lookup_rule = e_lookup_rule_from_irtree(&lhs_irtree); + ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule->name)) { - e_tag_poison(lhs_lookup_rule_and_tag.tag); + e_expr_poison(lhs_lookup_rule_and_tag.tag); E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, lhs_lookup_rule_and_tag.tag, str8_zero()); E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule_and_tag.tag, lookup_info.user_data); result = lookup_access.irtree_and_type; - e_tag_unpoison(lhs_lookup_rule_and_tag.tag); + e_expr_unpoison(lhs_lookup_rule_and_tag.tag); } scratch_end(scratch); }break; @@ -2425,26 +2425,30 @@ E_IRGEN_FUNCTION_DEF(default) { E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if(lhs_type->kind == E_TypeKind_Stub) + + // rjf: map callee -> ir-generation rule + E_IRGenRule *irgen_rule = &e_irgen_rule__default; { Temp scratch = scratch_begin(&arena, 1); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - String8 name = e_string_from_id(interp.value.u64); - E_IRGenRule *irgen_rule = e_irgen_rule_from_string(name); - if(irgen_rule != &e_irgen_rule__default) + E_TypeKey type_key = lhs_irtree.type_key; + E_Type *type = e_type_from_key__cached(type_key); + if(type->kind == E_TypeKind_Stub) { - result = irgen_rule->irgen(arena, expr); - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "There is no rule named `%S`.", name); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + String8 name = e_string_from_id(interp.value.u64); + irgen_rule = e_irgen_rule_from_string(name); } scratch_end(scratch); } + + // rjf: if we have a non-default ir-generation rule, then we can use that + // to generate the resultant IR tree + if(irgen_rule != &e_irgen_rule__default) + { + result = irgen_rule->irgen(arena, expr); + } else { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not currently supported."); @@ -3024,76 +3028,38 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) expr = expr->ref; } - //- rjf: pick the ir-generation rule from explicitly-stored expressions - B32 default_is_forced = 0; - 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->string; - E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name); - if(str8_match(name, e_irgen_rule__default.name, 0)) - { - default_is_forced = 1; - break; - } - if(irgen_rule_candidate != &e_irgen_rule__default) - { - B32 tag_is_poisoned = e_tag_is_poisoned(tag); - if(!tag_is_poisoned) - { - explicit_irgen_rule = irgen_rule_candidate; - explicit_irgen_rule_tag = tag; - } - } - } - //- rjf: apply all ir-generation steps typedef struct Task Task; struct Task { Task *next; - E_IRGenRule *rule; - E_Expr *tag; + E_Expr *expr; }; - Task start_task = {0, explicit_irgen_rule, explicit_irgen_rule_tag}; + Task start_task = {0, expr}; 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 - e_tag_poison(t->tag); + e_expr_poison(t->expr); // rjf: do this rule's generation - ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name)) - { - result = t->rule->irgen(arena, expr); - if(result.root == &e_irnode_nil && t->rule != &e_irgen_rule__default) - { - result = e_irgen_rule__default.irgen(arena, expr); - } - } + result = e_irgen_rule__default.irgen(arena, t->expr); // rjf: find any auto hooks according to this generation's type - if(!default_is_forced) { - E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key); + E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) { - for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next) + for(E_Expr *e = n->v; e != &e_expr_nil; e = e->next) { - B32 tag_is_poisoned = e_tag_is_poisoned(tag); - if(!tag_is_poisoned) + B32 e_is_poisoned = e_expr_is_poisoned(e); + if(!e_is_poisoned) { - E_IRGenRule *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; - } + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->expr = e; + break; } } } @@ -3103,7 +3069,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) //- rjf: unpoison the tags we used for(Task *t = first_task; t != 0; t = t->next) { - e_tag_unpoison(t->tag); + e_expr_unpoison(t->expr); } scratch_end(scratch); @@ -3378,7 +3344,31 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type } //////////////////////////////// -//~ rjf: Expression & IR-Tree => Lookup Rule +//~ rjf: Expression & IR-Tree => Rules + +internal E_LookupRule * +e_lookup_rule_from_irtree(E_IRTreeAndType *irtree) +{ + E_LookupRule *rule = &e_lookup_rule__default; + E_TypeKey type_key = irtree->type_key; + E_Type *type = e_type_from_key__cached(type_key); + + // rjf: first try implicit stub name -> rule mapping + if(rule == &e_lookup_rule__default && type->kind == E_TypeKind_Stub) + { + String8 name = type->name; + rule = e_lookup_rule_from_string(name); + } + + // rjf: try auto hook map + if(rule == &e_lookup_rule__default) + { + E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); + + } + + return rule; +} internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) @@ -3391,7 +3381,7 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) { - if(e_tag_is_poisoned(tag)) { continue; } + if(e_expr_is_poisoned(tag)) { continue; } if(str8_match(tag->string, e_lookup_rule__default.name, 0)) { result.rule = &e_lookup_rule__default; @@ -3427,10 +3417,10 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) // rjf: next try auto hook map if(!default_is_forced && result.rule == &e_lookup_rule__default) { - E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) { - if(e_tag_is_poisoned(n->v)) { continue; } + if(e_expr_is_poisoned(n->v)) { continue; } E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); if(candidate != &e_lookup_rule__nil) { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 8f4b6df3..961eba20 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -35,26 +35,26 @@ struct E_OpList //////////////////////////////// //~ rjf: Used Tag Map Data Structure -typedef struct E_UsedTagNode E_UsedTagNode; -struct E_UsedTagNode +typedef struct E_UsedExprNode E_UsedExprNode; +struct E_UsedExprNode { - E_UsedTagNode *next; - E_UsedTagNode *prev; - E_Expr *tag; + E_UsedExprNode *next; + E_UsedExprNode *prev; + E_Expr *expr; }; -typedef struct E_UsedTagSlot E_UsedTagSlot; -struct E_UsedTagSlot +typedef struct E_UsedExprSlot E_UsedExprSlot; +struct E_UsedExprSlot { - E_UsedTagNode *first; - E_UsedTagNode *last; + E_UsedExprNode *first; + E_UsedExprNode *last; }; -typedef struct E_UsedTagMap E_UsedTagMap; -struct E_UsedTagMap +typedef struct E_UsedExprMap E_UsedExprMap; +struct E_UsedExprMap { U64 slots_count; - E_UsedTagSlot *slots; + E_UsedExprSlot *slots; }; //////////////////////////////// @@ -155,7 +155,7 @@ struct E_IRState RDI_Procedure *thread_ip_procedure; // rjf: caches - E_UsedTagMap *used_tag_map; + E_UsedExprMap *used_expr_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; U64 string_id_gen; E_StringIDMap *string_id_map; @@ -225,8 +225,8 @@ internal E_IRGenRule *e_irgen_rule_from_string(String8 string); 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, E_AutoHookParams *params); #define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) -internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key); -internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key); +internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); +internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); //////////////////////////////// //~ rjf: Evaluated String IDs @@ -266,10 +266,10 @@ internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key) internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in); internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); -//- rjf: rule tag poison checking -internal B32 e_tag_is_poisoned(E_Expr *tag); -internal void e_tag_poison(E_Expr *tag); -internal void e_tag_unpoison(E_Expr *tag); +//- rjf: expression poison checking +internal B32 e_expr_is_poisoned(E_Expr *expr); +internal void e_expr_poison(E_Expr *expr); +internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); @@ -286,8 +286,9 @@ internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType * internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); //////////////////////////////// -//~ rjf: Expression & IR-Tree => Lookup Rule +//~ rjf: Expression & IR-Tree => Rules +internal E_LookupRule *e_lookup_rule_from_irtree(E_IRTreeAndType *irtree); internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 691f3f39..ec9e3537 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -341,7 +341,7 @@ internal E_Expr * e_push_expr(Arena *arena, E_ExprKind kind, void *location) { E_Expr *e = push_array(arena, E_Expr, 1); - e->first = e->last = e->next = e->prev = e->ref = e->first_tag = e->last_tag = &e_expr_nil; + e->first = e->last = e->next = e->prev = e->ref = &e_expr_nil; e->location = location; e->kind = kind; return e; @@ -365,12 +365,6 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child) DLLRemove_NPZ(&e_expr_nil, parent->first, parent->last, child, next, prev); } -internal void -e_expr_push_tag(E_Expr *parent, E_Expr *child) -{ - DLLPushBack_NPZ(&e_expr_nil, parent->first_tag, parent->last_tag, child, next, prev); -} - internal E_Expr * e_expr_ref(Arena *arena, E_Expr *ref) { @@ -460,14 +454,6 @@ e_expr_copy(Arena *arena, E_Expr *src) task->src = src_child; SLLQueuePush(first_task, last_task, task); } - for(E_Expr *src_child = t->src->first_tag; src_child != &e_expr_nil; src_child = src_child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->dst_parent = dst; - task->src = src_child; - task->is_tag = 1; - SLLQueuePush(first_task, last_task, task); - } } } scratch_end(scratch); diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index a414f01b..493dbad7 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -69,7 +69,6 @@ internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location); internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); -internal void e_expr_push_tag(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); 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); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ae77d8de..696c9603 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -509,7 +509,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key // rjf: push tags inferred from the type { E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree.type_key); + E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree.type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) { e_expr_push_tag(expr, e_expr_copy(arena, n->v)); @@ -1596,7 +1596,7 @@ ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) // rjf: next try auto hook map if(result.rule == &ev_nil_expand_rule) { - E_ExprList tags = e_auto_hook_tag_exprs_from_type_key__cached(irtree->type_key); + E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); for(E_ExprNode *n = tags.first; n != 0; n = n->next) { EV_ExpandRule *candidate = ev_expand_rule_from_string(n->v->string); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 48865106..7f7971a5 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -93,6 +93,11 @@ // [ ] need a formalization which takes unknown identifiers which are called, and tries // to use that to apply a IR-generation rule, which is keyed by that unknown // identifier +// [ ] we need to select expressions as "parents" when possible, so that when using an +// auto-view-rule (or similar context), leaf identifiers referring to e.g. members +// of an expression's type resolve correctly (e.g. bitmap(base, width, height) being +// used as a shorthand for bitmap(foo.base, foo.width, foo.height) when evaluating +// foo). // [ ] *ALL* expressions in watch windows need to be editable. // // [ ] config hot-reloading, using cfg wins From ecb3992b93fd401c553559537a5ec9c1b8d5ee01 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 12:01:41 -0700 Subject: [PATCH 318/755] eval stability tests in tester; tear out last pass' view rule extensions --- project.4coder | 3 + src/eval/eval.mdesk | 3 +- src/eval/eval_bundles.c | 134 +++++++++++++++++- src/eval/eval_bundles.h | 6 +- src/eval/eval_ir.c | 61 +++----- src/eval/eval_ir.h | 3 +- src/eval/eval_parse.c | 24 +--- src/eval/eval_types.c | 3 +- src/eval/generated/eval.meta.c | 8 +- src/eval/generated/eval.meta.h | 7 +- .../eval_visualization_core.c | 28 ++-- .../eval_visualization_core.h | 4 + src/raddbg/raddbg_core.c | 41 ++++-- src/raddbg/raddbg_views.c | 20 +-- src/scratch/eval_scratch.c | 118 +-------------- src/tester/tester_main.c | 102 +++++++++++-- 16 files changed, 324 insertions(+), 241 deletions(-) diff --git a/project.4coder b/project.4coder index 0b003cbf..1b92e539 100644 --- a/project.4coder +++ b/project.4coder @@ -51,6 +51,9 @@ commands = //- rjf: [eval_scratch] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: [tester] + // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: running target .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index ce6ce9a0..4d73fadf 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -71,7 +71,8 @@ E_TypeKindTable: {IncompleteEnum "enum" 0 } {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } - {Stub "stub" 0 } + {Set "set" 0 } + {Lens "lens" 0 } } @table(name op_kind precedence op_pre op_sep op_pos) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 945a1b89..87c45e0c 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -17,7 +17,6 @@ e_eval_from_exprs(Arena *arena, E_ExprChain exprs) { ProfBeginFunction(); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); - E_LookupRuleTagPair lookup = e_lookup_rule_tag_pair_from_expr_irtree(exprs.last, &irtree); E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); E_Interpretation interp = e_interpret(bytecode); @@ -28,7 +27,6 @@ e_eval_from_exprs(Arena *arena, E_ExprChain exprs) .exprs = exprs, .irtree = irtree, .bytecode = bytecode, - .lookup_rule_tag = lookup, .code = interp.code, }; e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); @@ -254,4 +252,134 @@ e_value_from_expr(E_Expr *expr) E_Value result = value_eval.value; scratch_end(scratch); return result; -} \ No newline at end of file +} + +//////////////////////////////// +//~ rjf: Debug Logging Functions + +internal String8 +e_debug_log_from_expr_string(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + char *indent_spaces = " "; + String8List strings = {0}; + + //- rjf: begin expression + String8 expr_text = string; + str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text); + + //- rjf: tokenize + E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr_text); + str8_list_pushf(scratch.arena, &strings, " tokens:\n"); + for EachIndex(idx, tokens.count) + { + E_Token token = tokens.v[idx]; + String8 token_string = str8_substr(expr_text, token.range); + str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); + } + + //- rjf: parse + E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr_text, tokens); + { + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *expr; + S32 indent; + }; + str8_list_pushf(scratch.arena, &strings, " expr:\n"); + Task start_task = {0, parse.exprs.first, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_Expr *expr = t->expr; + str8_list_pushf(scratch.arena, &strings, "%.*s%S", (int)t->indent*4, indent_spaces, e_expr_kind_strings[expr->kind]); + switch(expr->kind) + { + default:{}break; + case E_ExprKind_LeafU64: + { + str8_list_pushf(scratch.arena, &strings, " (%I64u)", expr->value.u64); + }break; + case E_ExprKind_LeafIdentifier: + { + str8_list_pushf(scratch.arena, &strings, " (`%S`)", expr->string); + }break; + } + str8_list_pushf(scratch.arena, &strings, "\n"); + Task *last_task = t; + for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->next = last_task->next; + last_task->next = task; + task->expr = child; + task->indent = t->indent+1; + last_task = task; + } + } + } + + //- rjf: type + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.first); + { + str8_list_pushf(scratch.arena, &strings, " type:\n"); + S32 indent = 2; + for(E_TypeKey type_key = irtree.type_key; + !e_type_key_match(e_type_key_zero(), type_key); + type_key = e_type_direct_from_key(type_key), + indent += 1) + { + E_Type *type = e_type_from_key(scratch.arena, type_key); + str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); + } + } + + //- rjf: irtree + { + typedef struct Task Task; + struct Task + { + Task *next; + E_IRNode *irnode; + S32 indent; + }; + str8_list_pushf(scratch.arena, &strings, " ir_tree:\n"); + Task start_task = {0, irtree.root, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_IRNode *irnode = t->irnode; + str8_list_pushf(scratch.arena, &strings, "%.*s", (int)t->indent*4, indent_spaces); + switch(irnode->op) + { + default:{}break; +#define X(name) case RDI_EvalOp_##name:{str8_list_pushf(scratch.arena, &strings, #name);}break; + RDI_EvalOp_XList +#undef X + } + if(irnode->value.u64 != 0) + { + str8_list_pushf(scratch.arena, &strings, " (%I64u)", irnode->value.u64); + } + str8_list_pushf(scratch.arena, &strings, "\n"); + Task *last_task = t; + for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->next = last_task->next; + last_task->next = task; + task->irnode = child; + task->indent = t->indent+1; + last_task = task; + } + } + } + + str8_list_pushf(scratch.arena, &strings, "\n"); + + String8 result = str8_list_join(arena, &strings, 0); + scratch_end(scratch); + return result; +} diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index f2ad6c85..c5028e08 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -15,7 +15,6 @@ struct E_Eval E_ExprChain exprs; E_IRTreeAndType irtree; String8 bytecode; - E_LookupRuleTagPair lookup_rule_tag; E_InterpretationCode code; E_MsgList msgs; }; @@ -34,4 +33,9 @@ internal E_Value e_value_from_string(String8 string); internal E_Value e_value_from_stringf(char *fmt, ...); internal E_Value e_value_from_expr(E_Expr *expr); +//////////////////////////////// +//~ rjf: Debug Logging Functions + +internal String8 e_debug_log_from_expr_string(Arena *arena, String8 string); + #endif // EVAL_BUNDLES_H diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index cc0691b1..70937c02 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -69,6 +69,7 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); + if(ctx->modules == 0) { ctx->modules = &e_module_nil; } if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } 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; } @@ -97,8 +98,7 @@ e_select_ir_ctx(E_IRCtx *ctx) for EachElement(idx, builtin_view_rule_names) { E_Expr *expr = e_push_expr(e_ir_state->arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("view_rule")); - expr->value.u64 = e_id_from_string(builtin_view_rule_names[idx]); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .name = builtin_view_rule_names[idx]); e_string2expr_map_insert(e_ir_state->arena, ctx->macro_map, builtin_view_rule_names[idx], expr); } } @@ -192,7 +192,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("folder")); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(folder_path); expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); @@ -202,7 +202,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(folder) String8 file_name = accel->files.v[idx - accel->folders.count]; String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("file")); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); expr->space = e_space_make(E_SpaceKind_FileSystem); expr->value.u64 = e_id_from_string(file_path); expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); @@ -879,7 +879,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default) enum_type_key = lhs_type_key; do_enum_range = 1; } - else if(lhs_type_kind == E_TypeKind_Stub) + else if(lhs_type_kind == E_TypeKind_Set) { do_index_range = 1; } @@ -1818,14 +1818,12 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_LookupRule *lookup_rule = e_lookup_rule_from_irtree(&lhs_irtree); - ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule->name)) + E_LookupRule *lookup_rule = &e_lookup_rule__default; + ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name)) { - e_expr_poison(lhs_lookup_rule_and_tag.tag); - E_LookupInfo lookup_info = lhs_lookup_rule_and_tag.rule->info(arena, &lhs_irtree, lhs_lookup_rule_and_tag.tag, str8_zero()); - E_LookupAccess lookup_access = lhs_lookup_rule_and_tag.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule_and_tag.tag, lookup_info.user_data); + E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, &e_expr_nil, str8_zero()); + E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, &e_expr_nil, lookup_info.user_data); result = lookup_access.irtree_and_type; - e_expr_unpoison(lhs_lookup_rule_and_tag.tag); } scratch_end(scratch); }break; @@ -2429,18 +2427,13 @@ E_IRGEN_FUNCTION_DEF(default) // rjf: map callee -> ir-generation rule E_IRGenRule *irgen_rule = &e_irgen_rule__default; { - Temp scratch = scratch_begin(&arena, 1); E_TypeKey type_key = lhs_irtree.type_key; E_Type *type = e_type_from_key__cached(type_key); - if(type->kind == E_TypeKind_Stub) + if(type->kind == E_TypeKind_Lens) { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree.root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - String8 name = e_string_from_id(interp.value.u64); + String8 name = type->name; irgen_rule = e_irgen_rule_from_string(name); } - scratch_end(scratch); } // rjf: if we have a non-default ir-generation rule, then we can use that @@ -2451,7 +2444,7 @@ E_IRGEN_FUNCTION_DEF(default) } else { - e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not currently supported."); + e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); } }break; @@ -2967,7 +2960,7 @@ E_IRGEN_FUNCTION_DEF(default) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("file")); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); result.mode = E_Mode_Value; } else @@ -2978,7 +2971,7 @@ E_IRGEN_FUNCTION_DEF(default) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("folder")); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); result.mode = E_Mode_Value; } } @@ -3346,30 +3339,7 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules -internal E_LookupRule * -e_lookup_rule_from_irtree(E_IRTreeAndType *irtree) -{ - E_LookupRule *rule = &e_lookup_rule__default; - E_TypeKey type_key = irtree->type_key; - E_Type *type = e_type_from_key__cached(type_key); - - // rjf: first try implicit stub name -> rule mapping - if(rule == &e_lookup_rule__default && type->kind == E_TypeKind_Stub) - { - String8 name = type->name; - rule = e_lookup_rule_from_string(name); - } - - // rjf: try auto hook map - if(rule == &e_lookup_rule__default) - { - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); - - } - - return rule; -} - +#if 0 // TODO(rjf): @eval internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { @@ -3432,3 +3402,4 @@ e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } return result; } +#endif diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 961eba20..18be9eee 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -288,7 +288,8 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules -internal E_LookupRule *e_lookup_rule_from_irtree(E_IRTreeAndType *irtree); +#if 0 // TODO(rjf): @eval internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); +#endif #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index ec9e3537..34cb115c 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -315,7 +315,8 @@ e_select_parse_ctx(E_ParseCtx *ctx) e_parse_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - if(ctx->primary_module == 0){ ctx->primary_module = &e_module_nil; } + if(ctx->modules == 0) { ctx->modules = &e_module_nil; } + if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } e_parse_state->ctx = ctx; } @@ -408,7 +409,6 @@ e_expr_copy(Arena *arena, E_Expr *src) E_Expr *dst_parent; E_Expr *src; B32 is_ref; - B32 is_tag; }; Task start_task = {0, &e_expr_nil, src}; Task *first_task = &start_task; @@ -431,10 +431,6 @@ e_expr_copy(Arena *arena, E_Expr *src) { t->dst_parent->ref = dst; } - else if(t->is_tag) - { - e_expr_push_tag(t->dst_parent, dst); - } else { e_expr_push_child(t->dst_parent, dst); @@ -1484,22 +1480,6 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } } - //- rjf: parse tags - { - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) - { - it += 1; - E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); - e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); - it = tags_parse.last_token; - for(E_Expr *tag = tags_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) - { - next = tag->next; - e_expr_push_tag(atom, tag); - } - } - } - // rjf: if we parsed nothing successfully, we're done if(it == start_it) { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 0565f4c7..e98d7ed1 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -235,7 +235,8 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->arena = arena; e_type_state->arena_eval_start_pos = arena_pos(e_type_state->arena); } - if(ctx->primary_module == 0) {ctx->primary_module = &e_module_nil;} + if(ctx->modules == 0) { ctx->modules = &e_module_nil; } + if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } arena_pop_to(e_type_state->arena, e_type_state->arena_eval_start_pos); e_type_state->ctx = ctx; e_type_state->cons_id_gen = 0; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 851d9687..bd097d05 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_type_kind_basic_string_table[56] = +String8 e_type_kind_basic_string_table[57] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -71,10 +71,11 @@ str8_lit_comp("class"), str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), -str8_lit_comp("stub"), +str8_lit_comp("set"), +str8_lit_comp("lens"), }; -U8 e_type_kind_basic_byte_size_table[56] = +U8 e_type_kind_basic_byte_size_table[57] = { 0, 0, @@ -132,6 +133,7 @@ U8 e_type_kind_basic_byte_size_table[56] = 0, 0, 0, +0, }; String8 e_expr_kind_strings[48] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index fb48f62d..30cd7f64 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -74,7 +74,8 @@ E_TypeKind_IncompleteClass, E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, -E_TypeKind_Stub, +E_TypeKind_Set, +E_TypeKind_Lens, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -160,8 +161,8 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_type_kind_basic_string_table[56]; -extern U8 e_type_kind_basic_byte_size_table[56]; +extern String8 e_type_kind_basic_string_table[57]; +extern U8 e_type_kind_basic_byte_size_table[57]; extern String8 e_expr_kind_strings[48]; extern E_OpInfo e_expr_kind_op_info_table[48]; extern String8 e_interpretation_code_display_strings[11]; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 696c9603..a292c43f 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -94,7 +94,7 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) kind == E_TypeKind_Union || kind == E_TypeKind_Class || kind == E_TypeKind_Array || - kind == E_TypeKind_Stub || + kind == E_TypeKind_Set || (kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; @@ -474,6 +474,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) //////////////////////////////// //~ rjf: Upgrading Expressions w/ Tags From All Sources +#if 0 // TODO(rjf): @eval internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) { @@ -528,6 +529,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key } scratch_end(scratch); } +#endif //////////////////////////////// //~ rjf: Block Building @@ -544,7 +546,9 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); E_Expr *root_expr = e_expr_copy(arena, exprs.last); +#if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); +#endif //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); @@ -593,9 +597,9 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); // rjf: get expr's expansion rule - EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ExpandRule *expand_rule = expand_rule_and_tag.rule; - E_Expr *expand_rule_tag = expand_rule_and_tag.tag; + // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + EV_ExpandRule *expand_rule = &ev_nil_expand_rule; + E_Expr *expand_rule_tag = &e_expr_nil; // rjf: skip if no expansion rule, & type info disallows expansion if(expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) @@ -604,12 +608,12 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai } // rjf: get expr's lookup rule - E_LookupRuleTagPair lookup_rule_and_tag = e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.tag; + // TODO(rjf): @eval E_LookupRuleTagPair lookup_rule_and_tag = &e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + E_LookupRule *lookup_rule = &e_lookup_rule__default; + E_Expr *lookup_rule_tag = &e_expr_nil; // rjf: get top-level lookup/expansion info - E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_and_tag.tag, filter); + E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_tag, filter); EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); // rjf: determine expansion info @@ -733,7 +737,9 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai if(child_expr != &e_expr_nil) { EV_Key child_key = child_keys[idx]; +#if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); +#endif Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; @@ -1046,7 +1052,9 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 U64 child_id = n->v.block->lookup_rule->id_from_num(child_num, n->v.block->lookup_rule_user_data); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; +#if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); +#endif EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1142,11 +1150,13 @@ ev_row_is_expandable(EV_Row *row) // rjf: determine if view rules force expandability if(!result) { +#if 0 // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(row->expr, &irtree); if(expand_rule_and_tag.rule != &ev_nil_expand_rule) { result = 1; } +#endif } // rjf: determine if type info force expandability @@ -1573,6 +1583,7 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) //////////////////////////////// //~ rjf: Expression & IR-Tree => Expand Rule +#if 0 // TODO(rjf): @eval internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { @@ -1611,3 +1622,4 @@ ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) } return result; } +#endif diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index e247c273..bb699ecf 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -304,7 +304,9 @@ internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); //////////////////////////////// //~ rjf: Upgrading Expressions w/ Tags From All Sources +#if 0 // TODO(rjf): @eval internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr); +#endif //////////////////////////////// //~ rjf: Block Building @@ -345,6 +347,8 @@ internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); //////////////////////////////// //~ rjf: Expression & IR-Tree => Expand Rule +#if 0 // TODO(rjf): @eval internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); +#endif #endif // EVAL_VISUALIZATION_CORE_H diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c84984e7..5704bb8f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -107,7 +107,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(watches) { E_Eval eval = e_eval_from_string(scratch.arena, expr); E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind != E_TypeKind_Stub) + if(type->kind != E_TypeKind_Set) { passes_filter = 0; FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); @@ -441,7 +441,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(schema) } else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) { - child_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = child_schema->string); + child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); } //- rjf: evaluate @@ -4706,7 +4706,7 @@ rd_view_ui(Rng2F32 rect) E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); E_TypeKey block_type_key = block_irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Stub) + if(block_type_kind == E_TypeKind_Set) { E_Type *block_type = e_type_from_key__cached(block_type_key); group_cfg_name = rd_singular_from_code_name_plural(block_type->name); @@ -7514,8 +7514,10 @@ rd_window_frame(void) if(build_hover_eval) { // rjf: determine if we have a top-level visualizer +#if 0 // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); - RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule_tag.rule->string); +#endif + RD_ViewUIRule *view_ui_rule = &rd_nil_view_ui_rule; // TODO(rjf): @eval rd_view_ui_rule_from_string(expand_rule_tag.rule->string); // rjf: determine view name String8 view_name = str8_lit("watch"); @@ -10418,6 +10420,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f B32 no_addr = 0; B32 no_string = 0; B32 has_array = 0; +#if 0 // TODO(rjf): @eval for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} @@ -10436,6 +10439,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f min_digits = (U32)num_value_eval.value.u64; } } +#endif if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || eval.space.kind == RD_EvalSpaceKind_MetaCfg) { @@ -10655,6 +10659,9 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { // rjf: unpack E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = &e_lookup_rule__default; + E_Expr *lookup_rule_tag = &e_expr_nil; +#if 0 // TODO(rjf): @eval E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; if(lookup_rule == &e_lookup_rule__default) @@ -10662,6 +10669,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f lookup_rule = root_eval.lookup_rule_tag.rule; lookup_rule_tag = root_eval.lookup_rule_tag.tag; } +#endif E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("["); @@ -10788,11 +10796,14 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f case E_TypeKind_IncompleteStruct: case E_TypeKind_IncompleteUnion: case E_TypeKind_IncompleteClass: - case E_TypeKind_Stub: + case E_TypeKind_Set: arrays_and_sets_and_structs: { // rjf: unpack E_IRTreeAndType irtree = eval.irtree; + E_LookupRule *lookup_rule = &e_lookup_rule__default; + E_Expr *lookup_rule_tag = &e_expr_nil; +#if 0 // TODO(rjf): @eval E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; if(lookup_rule == &e_lookup_rule__default) @@ -10800,6 +10811,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f lookup_rule = root_eval.lookup_rule_tag.rule; lookup_rule_tag = root_eval.lookup_rule_tag.tag; } +#endif E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("{"); @@ -13533,7 +13545,7 @@ rd_frame(void) for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; - E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Stub); + E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, .info = E_LOOKUP_INFO_FUNCTION_NAME(schema), @@ -13662,7 +13674,7 @@ rd_frame(void) { String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name, .flags = E_TypeFlag_EditableChildren); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, @@ -13704,7 +13716,7 @@ rd_frame(void) { String8 collection_name = collection_infos[idx].name; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = collection_infos[idx].lookup_info, @@ -13724,7 +13736,7 @@ rd_frame(void) { String8 name = debug_info_table_collection_names[idx]; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, @@ -13739,7 +13751,7 @@ rd_frame(void) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13757,7 +13769,7 @@ rd_frame(void) { String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; String8 collection_name = rd_plural_from_code_name(kind_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13771,7 +13783,7 @@ rd_frame(void) //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); @@ -13784,7 +13796,7 @@ rd_frame(void) //- rjf: add macro for commands { String8 name = str8_lit("commands"); - E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = name); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); @@ -13912,8 +13924,7 @@ rd_frame(void) for EachElement(idx, view_ui_rule_table) { E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Stub, .name = str8_lit("view_rule")); - expr->value.u64 = e_id_from_string(view_ui_rule_table[idx].name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .name = view_ui_rule_table[idx].name); e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 1c2b2803..0b33bad5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1002,21 +1002,21 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine ctrl entity - if(block_type_kind == E_TypeKind_Stub && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || - block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); } // rjf: determine cfg group name / parent - if(block_type_kind == E_TypeKind_Stub && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || - block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) + if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || + block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) { info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); } // rjf: determine group cfg name - if(block_type_kind == E_TypeKind_Stub) + if(block_type_kind == E_TypeKind_Set) { String8 singular_name = rd_singular_from_code_name_plural(block_type->name); if(singular_name.size != 0) @@ -1070,7 +1070,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(type->kind == E_TypeKind_Stub) + if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(info.eval.value.u64); DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); @@ -1226,7 +1226,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) { E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); - if(type->kind == E_TypeKind_Stub) + if(type->kind == E_TypeKind_Set) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); } @@ -1282,7 +1282,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: procedures collections get only expr/value/view-rule - else if(block_type->kind == E_TypeKind_Stub && str8_match(block_type->name, str8_lit("procedures"), 0)) + else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) { info.cell_style_key = str8_lit("expr_value_viewrule"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1565,7 +1565,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla else if(result.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Stub) + if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(result.eval.value.u64); result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); @@ -1633,7 +1633,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla else if(result.eval.space.kind == E_SpaceKind_FileSystem) { E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Stub) + if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(result.eval.value.u64); result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); diff --git a/src/scratch/eval_scratch.c b/src/scratch/eval_scratch.c index 24246e6f..233a773b 100644 --- a/src/scratch/eval_scratch.c +++ b/src/scratch/eval_scratch.c @@ -27,7 +27,6 @@ internal void entry_point(CmdLine *cmdline) { Arena *arena = arena_alloc(); - char *indent_spaces = " "; E_TypeCtx *type_ctx = push_array(arena, E_TypeCtx, 1); e_select_type_ctx(type_ctx); E_ParseCtx *parse_ctx = push_array(arena, E_ParseCtx, 1); @@ -42,122 +41,11 @@ entry_point(CmdLine *cmdline) str8_lit("1 + 2"), str8_lit("foo"), str8_lit("foo(bar)"), + str8_lit("foo(bar(baz))"), }; for EachElement(idx, exprs) { - //- rjf: begin expression - String8 expr_text = exprs[idx]; - raddbg_log("`%S`\n", expr_text); - - //- rjf: tokenize - E_TokenArray tokens = e_token_array_from_text(arena, expr_text); - raddbg_log(" tokens:\n"); - for EachIndex(idx, tokens.count) - { - E_Token token = tokens.v[idx]; - String8 token_string = str8_substr(expr_text, token.range); - raddbg_log(" %S: `%S`\n", e_token_kind_strings[token.kind], token_string); - } - - //- rjf: parse - E_Parse parse = e_parse_expr_from_text_tokens(arena, expr_text, tokens); - { - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *expr; - S32 indent; - }; - raddbg_log(" expr:\n"); - Task start_task = {0, parse.exprs.first, 2}; - Task *first_task = &start_task; - for(Task *t = first_task; t != 0; t = t->next) - { - E_Expr *expr = t->expr; - raddbg_log("%.*s%S", (int)t->indent*4, indent_spaces, e_expr_kind_strings[expr->kind]); - switch(expr->kind) - { - default:{}break; - case E_ExprKind_LeafU64: - { - raddbg_log(" (%I64u)", expr->value.u64); - }break; - case E_ExprKind_LeafIdentifier: - { - raddbg_log(" (`%S`)", expr->string); - }break; - } - raddbg_log("\n"); - Task *last_task = t; - for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(arena, Task, 1); - task->next = last_task->next; - last_task->next = task; - task->expr = child; - task->indent = t->indent+1; - last_task = task; - } - } - } - - //- rjf: type - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, parse.exprs.first); - { - raddbg_log(" type:\n"); - S32 indent = 2; - for(E_TypeKey type_key = irtree.type_key; - !e_type_key_match(e_type_key_zero(), type_key); - type_key = e_type_direct_from_key(type_key), - indent += 1) - { - E_Type *type = e_type_from_key(arena, type_key); - raddbg_log("%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); - } - } - - //- rjf: irtree - { - typedef struct Task Task; - struct Task - { - Task *next; - E_IRNode *irnode; - S32 indent; - }; - raddbg_log(" ir_tree:\n"); - Task start_task = {0, irtree.root, 2}; - Task *first_task = &start_task; - for(Task *t = first_task; t != 0; t = t->next) - { - E_IRNode *irnode = t->irnode; - raddbg_log("%.*s", (int)t->indent*4, indent_spaces); - switch(irnode->op) - { - default:{}break; -#define X(name) case RDI_EvalOp_##name:{raddbg_log(#name);}break; - RDI_EvalOp_XList -#undef X - } - if(irnode->value.u64 != 0) - { - raddbg_log(" (%I64u)", irnode->value.u64); - } - raddbg_log("\n"); - Task *last_task = t; - for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(arena, Task, 1); - task->next = last_task->next; - last_task->next = task; - task->irnode = child; - task->indent = t->indent+1; - last_task = task; - } - } - } - - raddbg_log("\n"); + String8 debug_string = e_debug_log_from_expr_string(arena, exprs[idx]); + raddbg_log("%S", debug_string); } } diff --git a/src/tester/tester_main.c b/src/tester/tester_main.c index c62ea4f1..45b3e61f 100644 --- a/src/tester/tester_main.c +++ b/src/tester/tester_main.c @@ -16,12 +16,20 @@ #include "os/os_inc.h" #include "path/path.h" #include "hash_store/hash_store.h" +#include "rdi_format/rdi_format_local.h" +#include "regs/regs.h" +#include "regs/rdi/regs_rdi.h" +#include "eval/eval_inc.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" #include "path/path.c" #include "hash_store/hash_store.c" +#include "rdi_format/rdi_format_local.c" +#include "regs/regs.c" +#include "regs/rdi/regs_rdi.c" +#include "eval/eval_inc.c" //////////////////////////////// //~ rjf: Entry Points @@ -32,6 +40,14 @@ internal void entry_point(CmdLine *cmdline) { Arena *arena = arena_alloc(); + E_TypeCtx *type_ctx = push_array(arena, E_TypeCtx, 1); + e_select_type_ctx(type_ctx); + E_ParseCtx *parse_ctx = push_array(arena, E_ParseCtx, 1); + e_select_parse_ctx(parse_ctx); + E_IRCtx *ir_ctx = push_array(arena, E_IRCtx, 1); + e_select_ir_ctx(ir_ctx); + E_InterpretCtx *interpret_ctx = push_array(arena, E_InterpretCtx, 1); + e_select_interpret_ctx(interpret_ctx, 0, 0); ////////////////////////////// //- rjf: unpack command line @@ -49,14 +65,31 @@ entry_point(CmdLine *cmdline) String8 artifacts_path = path_normalized_from_string(arena, str8_lit("./tester_artifacts")); os_make_directory(artifacts_path); + ////////////////////////////// + //- rjf: set up list of test artifacts + // + typedef struct Test Test; + struct Test + { + Test *next; + String8 name; + String8List out; + B32 good; + }; + Test *first_test = 0; + Test *last_test = 0; +#define Test(name_identifier) \ +Test *test_##name_identifier = push_array(arena, Test, 1);\ +test_##name_identifier->name = str8_lit(#name_identifier);\ +test_##name_identifier->good = 1;\ +SLLQueuePush(first_test, last_test, test_##name_identifier);\ +for(Test *test = test_##name_identifier; test != 0; test = 0) + ////////////////////////////// //- rjf: PDB -> RDI determinism // - String8 name = {0}; - B32 good = 1; - String8List out = {0}; + Test(pdb2rdi_determinism) { - name = str8_lit("pdb2rdi_determinism"); U64 num_repeats_per_pdb = 32; String8 pdb_paths[] = { @@ -67,7 +100,7 @@ entry_point(CmdLine *cmdline) { // rjf: unpack paths, make output directory String8 pdb_path = path_normalized_from_string(arena, pdb_paths[pdb_idx]); - String8 repeat_folder = push_str8f(arena, "%S/%S", artifacts_path, name); + String8 repeat_folder = push_str8f(arena, "%S/%S", artifacts_path, test->name); os_make_directory(repeat_folder); // rjf: generate all RDIs @@ -157,29 +190,72 @@ entry_point(CmdLine *cmdline) // rjf: output bad case info if(!matches) { - good = 0; - str8_list_pushf(arena, &out, " pdb[%I64u] \"%S\"\n", pdb_idx, pdb_path); + test->good = 0; + str8_list_pushf(arena, &test->out, " pdb[%I64u] \"%S\"\n", pdb_idx, pdb_path); for EachIndex(idx, rdi_hashes_count) { - str8_list_pushf(arena, &out, " rdi[%I64u] \"%S\": 0x%I64x:%I64x\n", idx, rdi_paths_array[idx], rdi_hashes[idx].u64[0], rdi_hashes[idx].u64[1]); + str8_list_pushf(arena, &test->out, " rdi[%I64u] \"%S\": 0x%I64x:%I64x\n", idx, rdi_paths_array[idx], rdi_hashes[idx].u64[0], rdi_hashes[idx].u64[1]); } for EachIndex(idx, dump_hashes_count) { - str8_list_pushf(arena, &out, " dump[%I64u] \"%S\": 0x%I64x:%I64x\n", idx, dump_paths_array[idx], dump_hashes[idx].u64[0], dump_hashes[idx].u64[1]); + str8_list_pushf(arena, &test->out, " dump[%I64u] \"%S\": 0x%I64x:%I64x\n", idx, dump_paths_array[idx], dump_hashes[idx].u64[0], dump_hashes[idx].u64[1]); } } } } + ////////////////////////////// + //- rjf: eval compiler basics + // + Test(eval_compiler_basics) + { + String8 exprs[] = + { + str8_lit("123"), + str8_lit("1 + 2"), + str8_lit("foo"), + str8_lit("foo(bar)"), + str8_lit("foo(bar(baz))"), + }; + String8List logs = {0}; + for EachElement(idx, exprs) + { + String8 log = e_debug_log_from_expr_string(arena, exprs[idx]); + str8_list_push(arena, &logs, log); + } + String8 log = str8_list_join(arena, &logs, 0); + String8 test_artifacts_path = push_str8f(arena, "%S/%S", artifacts_path, test->name); + os_make_directory(test_artifacts_path); + String8 current_file_path = push_str8f(arena, "%S/current.txt", test_artifacts_path); + String8 correct_file_path = push_str8f(arena, "%S/%S/correct.txt", test_data_folder_path, test->name); + os_write_data_to_file_path(current_file_path, log); + String8 current_file_data = log; + String8 correct_file_data = os_data_from_file_path(arena, correct_file_path); + test->good = str8_match(correct_file_data, current_file_data, 0); + } + ////////////////////////////// //- rjf: dump results // - fprintf(stderr, "[%s] \"%.*s\"\n", good ? "." : "X", str8_varg(name)); - if(!good) + B32 all_good = 1; + for(Test *t = first_test; t != 0; t = t->next) { - for(String8Node *n = out.first; n != 0; n = n->next) + if(!t->good) { - fprintf(stderr, "%.*s", str8_varg(n->string)); + all_good = 0; + break; + } + } + fprintf(stderr, "[%s]\n", all_good ? "." : "X"); + for(Test *t = first_test; t != 0; t = t->next) + { + fprintf(stderr, " [%s] \"%.*s\"\n", t->good ? "." : "X", str8_varg(t->name)); + if(!t->good) + { + for(String8Node *n = t->out.first; n != 0; n = n->next) + { + fprintf(stderr, " %.*s", str8_varg(n->string)); + } } } From da69d9e91c6668b3445bb8ff7dcb70ce66b1354b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 13:43:35 -0700 Subject: [PATCH 319/755] more progress on new eval/view-rule integration; raddbg_entry_point markup feature --- src/ctrl/ctrl_core.c | 45 +++++++++++++++---- src/eval/eval_core.h | 6 +-- src/eval/eval_ir.c | 32 ++++++++++--- src/eval/eval_ir.h | 4 +- .../eval_visualization_core.c | 7 +-- src/lib_raddbg_markup/raddbg_markup.h | 7 ++- src/mule/mule_main.cpp | 2 + src/raddbg/raddbg_core.c | 4 +- src/raddbg/raddbg_main.c | 3 ++ 9 files changed, 84 insertions(+), 26 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 846e1720..ffa258d2 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -5403,15 +5403,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: unpack process/module info CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); - CTRL_Entity *module = &ctrl_entity_nil; - for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == CTRL_EntityKind_Module) - { - module = child; - break; - } - } + CTRL_Entity *module = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Module); U64 module_base_vaddr = module->vaddr_range.min; CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp}; @@ -5448,6 +5440,41 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } } + //- rjf: add traps for module-baked entry points, if specified + if(!entries_found) + { + String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, module->handle); + U8 split_char = 0; + String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); + for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) + { + String8 text = text_n->string; + MD_Node *root = md_tree_from_string(scratch.arena, text); + if(str8_match(root->first->string, str8_lit("entry_point"), 0)) + { + String8 name = root->first->first->string; + U32 procedure_id = 0; + { + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, name.str, name.size); + U32 id_count = 0; + U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count); + if(id_count > 0) + { + procedure_id = ids[0]; + } + } + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_id); + U64 voff = rdi_first_voff_from_procedure(rdi, procedure); + if(voff != 0) + { + entries_found = 1; + DMN_Trap trap = {process->handle.dmn_handle, module_base_vaddr + voff}; + dmn_trap_chunk_list_push(scratch.arena, &entry_traps, 256, &trap); + } + } + } + } + //- rjf: add traps for PID-correllated entry points if(!entries_found) { diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 1a5792b9..e887e1c2 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -523,11 +523,11 @@ struct E_LookupRuleMap U64 slots_count; }; -typedef struct E_LookupRuleTagPair E_LookupRuleTagPair; -struct E_LookupRuleTagPair +typedef struct E_LookupRuleExprPair E_LookupRuleExprPair; +struct E_LookupRuleExprPair { E_LookupRule *rule; - E_Expr *tag; + E_Expr *expr; }; //////////////////////////////// diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 70937c02..ccb15550 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1818,11 +1818,11 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_LookupRule *lookup_rule = &e_lookup_rule__default; - ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name)) + E_LookupRuleExprPair lhs_lookup_rule = e_lookup_rule_expr_pair_from_expr_irtree(lhs, &lhs_irtree); + ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule.rule->name)) { - E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, &e_expr_nil, str8_zero()); - E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, &e_expr_nil, lookup_info.user_data); + E_LookupInfo lookup_info = lhs_lookup_rule.rule->info(arena, &lhs_irtree, lhs_lookup_rule.expr, str8_zero()); + E_LookupAccess lookup_access = lhs_lookup_rule.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule.expr, lookup_info.user_data); result = lookup_access.irtree_and_type; } scratch_end(scratch); @@ -3339,11 +3339,31 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +internal E_LookupRuleExprPair +e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) +{ + E_LookupRuleExprPair result = {&e_lookup_rule__default, &e_expr_nil}; + + // rjf: first, try set name -> rule mapping + if(result.rule == &e_lookup_rule__default && e_type_kind_from_key(irtree->type_key) == E_TypeKind_Set) + { + E_Type *type = e_type_from_key__cached(irtree->type_key); + String8 name = type->name; + E_LookupRule *candidate = e_lookup_rule_from_string(name); + if(candidate != &e_lookup_rule__nil) + { + result.rule = candidate; + } + } + + return result; +} + #if 0 // TODO(rjf): @eval -internal E_LookupRuleTagPair +internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { - E_LookupRuleTagPair result = {&e_lookup_rule__default, &e_expr_nil}; + E_LookupRuleExprPair result = {&e_lookup_rule__default, &e_expr_nil}; { // rjf: first try explicitly-stored tags B32 default_is_forced = 0; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 18be9eee..105765a9 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -288,8 +288,10 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +internal E_LookupRuleExprPair e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); + #if 0 // TODO(rjf): @eval -internal E_LookupRuleTagPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); +internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); #endif #endif // EVAL_IR_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index a292c43f..9332bf9c 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -608,9 +608,10 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai } // rjf: get expr's lookup rule - // TODO(rjf): @eval E_LookupRuleTagPair lookup_rule_and_tag = &e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - E_LookupRule *lookup_rule = &e_lookup_rule__default; - E_Expr *lookup_rule_tag = &e_expr_nil; + // TODO(rjf): @eval E_LookupRuleExprPair lookup_rule_and_tag = &e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); + E_LookupRuleExprPair lookup_rule_and_tag = e_lookup_rule_expr_pair_from_expr_irtree(t->expr, &expr_irtree); + E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; + E_Expr *lookup_rule_tag = lookup_rule_and_tag.expr; // rjf: get top-level lookup/expansion info E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_tag, filter); diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 84bddf4e..a141fa53 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -25,7 +25,8 @@ # define raddbg_watch(fmt, ...) ((void)0) # define raddbg_pin(expr, ...) # define raddbg_log(fmt, ...) ((void)0) -# define raddbg_auto_view_rule(type, ...) struct raddbg_glue(raddbg_auto_view_rule_stub__, __COUNTER__){int __unused__} +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_auto_view_rule(type, ...) struct raddbg_gen_data_id(){int __unused__} #else # define raddbg_is_attached(...) raddbg_is_attached__impl() # define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) @@ -36,7 +37,8 @@ # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) # define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ # define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_glue(raddbg_auto_view_rule_data__, __COUNTER__)[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: " #__VA_ARGS__) +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") #endif //////////////////////////////// @@ -44,6 +46,7 @@ #define raddbg_glue_(a, b) a##b #define raddbg_glue(a, b) raddbg_glue_(a, b) +#define raddbg_gen_data_id() raddbg_glue(raddbg_data__, __COUNTER__) //////////////////////////////// //~ Win32 Implementations diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 3962a8db..f1799a40 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2685,6 +2685,8 @@ dynamic_step_test(void){ //////////////////////////////// +raddbg_entry_point(mule_main); + int mule_main(int argc, char** argv) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5704bb8f..155e490a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10053,7 +10053,7 @@ rd_window_frame(void) // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) { - B32 is_hot = ui_key_match(box->key, ui_hot_key()); + B32 is_hot = !ui_key_match(box->key, ui_key_zero()) && ui_key_match(box->key, ui_hot_key()); Vec4F32 hover_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); // rjf: brighten @@ -10264,7 +10264,7 @@ rd_window_frame(void) if(b->flags & UI_BoxFlag_DrawHotEffects) { Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("hover")); - if(!ui_key_match(b->key, ui_hot_key())) + if(ui_key_match(b->key, ui_key_zero()) || !ui_key_match(b->key, ui_hot_key())) { color.w *= b->hot_t; } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 7f7971a5..6c271264 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -78,6 +78,9 @@ // code. This is used by the debugger UI, but does not show up anywhere // other than the source code, so it can either be used as a macro (which // expands to nothing), or in comments too. +// - `raddbg_entry_point(name)`, e.g. `raddbg_entry_point(entry_point)`: +// declares the entry point for an executable, which the debugger will use +// when stepping into a program, rather than the defaults (e.g. `main`). // - `raddbg_auto_view_rule(, )`, e.g. // `raddbg_auto_view_rule(DynamicArray, slice)`: declares an // auto-view-rule from source code, rather than from debugger From 84e16b81ff68db5e617fb4b577ce097e6b61fc60 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 13:45:06 -0700 Subject: [PATCH 320/755] automatically mark up entry_point as exe entry points, for codebase builds --- src/os/core/os_core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index e3a02048..369070e1 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -329,6 +329,7 @@ internal Guid os_make_guid(void); // into the standard codebase program entry points, named "entry_point". #if BUILD_ENTRY_DEFINING_UNIT +raddbg_entry_point(entry_point); internal void entry_point(CmdLine *cmdline); #endif From 97a1003d85b6bc25fc43daf79ef90657201a726b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 14:02:23 -0700 Subject: [PATCH 321/755] eliminate old incorrect auto-hook of ctrl entity type keys; was busting visualization of ctrl entities --- src/raddbg/raddbg_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 155e490a..8be41e57 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13661,7 +13661,6 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); } } - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_key = type_key, .tag_expr_string = name); } //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' From b1f17b217ce4608965a6d18ffc4b24a20191b77c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 14:57:56 -0700 Subject: [PATCH 322/755] checkpoint - extend constructed types w/ expression arguments, new 'lens' type operator, which can wrap evaluations of other types, + provide a name/args. e.g., bitmap(256, 256) <- (uint8 *), as a well-formed type. this also is the first step to collapsing all 'expression introspection' paths, and making sure they all compose properly. --- src/eval/eval_core.h | 181 ++++++++++++++++++++------------------- src/eval/eval_ir.c | 50 ++++++----- src/eval/eval_types.c | 36 ++++++++ src/eval/eval_types.h | 1 + src/raddbg/raddbg_core.c | 1 - 5 files changed, 157 insertions(+), 112 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index e887e1c2..e43002c3 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -158,6 +158,96 @@ struct E_TypeKeyList #include "generated/eval.meta.h" +//////////////////////////////// +//~ rjf: Token Types + +typedef struct E_Token E_Token; +struct E_Token +{ + E_TokenKind kind; + Rng1U64 range; +}; + +typedef struct E_TokenChunkNode E_TokenChunkNode; +struct E_TokenChunkNode +{ + E_TokenChunkNode *next; + E_Token *v; + U64 count; + U64 cap; +}; + +typedef struct E_TokenChunkList E_TokenChunkList; +struct E_TokenChunkList +{ + E_TokenChunkNode *first; + E_TokenChunkNode *last; + U64 node_count; + U64 total_count; +}; + +typedef struct E_TokenArray E_TokenArray; +struct E_TokenArray +{ + E_Token *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Evaluation Modes + +typedef enum E_Mode +{ + E_Mode_Null, + E_Mode_Value, + E_Mode_Offset, +} +E_Mode; + +//////////////////////////////// +//~ rjf: Expression Tree Types + +typedef struct E_Expr E_Expr; +struct E_Expr +{ + E_Expr *first; + E_Expr *last; + E_Expr *next; + E_Expr *prev; + E_Expr *ref; + void *location; + E_ExprKind kind; + E_Mode mode; + E_Space space; + E_TypeKey type_key; + E_Value value; + String8 string; + String8 qualifier; + String8 bytecode; +}; + +typedef struct E_ExprChain E_ExprChain; +struct E_ExprChain +{ + E_Expr *first; + E_Expr *last; +}; + +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: Full Extracted Type Information Types @@ -253,19 +343,9 @@ struct E_Type E_TypeKey *param_type_keys; E_Member *members; E_EnumVal *enum_vals; + E_Expr **args; }; -//////////////////////////////// -//~ rjf: Evaluation Modes - -typedef enum E_Mode -{ - E_Mode_Null, - E_Mode_Value, - E_Mode_Offset, -} -E_Mode; - //////////////////////////////// //~ rjf: Modules @@ -278,85 +358,6 @@ struct E_Module E_Space space; }; -//////////////////////////////// -//~ rjf: Token Types - -typedef struct E_Token E_Token; -struct E_Token -{ - E_TokenKind kind; - Rng1U64 range; -}; - -typedef struct E_TokenChunkNode E_TokenChunkNode; -struct E_TokenChunkNode -{ - E_TokenChunkNode *next; - E_Token *v; - U64 count; - U64 cap; -}; - -typedef struct E_TokenChunkList E_TokenChunkList; -struct E_TokenChunkList -{ - E_TokenChunkNode *first; - E_TokenChunkNode *last; - U64 node_count; - U64 total_count; -}; - -typedef struct E_TokenArray E_TokenArray; -struct E_TokenArray -{ - E_Token *v; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Expression Tree Types - -typedef struct E_Expr E_Expr; -struct E_Expr -{ - E_Expr *first; - E_Expr *last; - E_Expr *next; - E_Expr *prev; - E_Expr *ref; - void *location; - E_ExprKind kind; - E_Mode mode; - E_Space space; - E_TypeKey type_key; - E_Value value; - String8 string; - String8 qualifier; - String8 bytecode; -}; - -typedef struct E_ExprChain E_ExprChain; -struct E_ExprChain -{ - E_Expr *first; - E_Expr *last; -}; - -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: IR Tree Types diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ccb15550..a4da10ff 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1210,13 +1210,6 @@ E_IRGEN_FUNCTION_DEF(array) return result; } -E_IRGEN_FUNCTION_DEF(view_rule_noop) -{ - E_Expr *expr_arg = expr->first->next; - E_IRTreeAndType result = e_irtree_and_type_from_expr(arena, expr_arg); - return result; -} - internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count) { @@ -2423,24 +2416,39 @@ E_IRGEN_FUNCTION_DEF(default) { E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - // rjf: map callee -> ir-generation rule - E_IRGenRule *irgen_rule = &e_irgen_rule__default; + // rjf: calling a lens? -> generate IR for the first argument; wrap the type in + // a lens type, which preserves the name & arguments of the lens call expression + if(lhs_type->kind == E_TypeKind_Lens) { - E_TypeKey type_key = lhs_irtree.type_key; - E_Type *type = e_type_from_key__cached(type_key); - if(type->kind == E_TypeKind_Lens) + Temp scratch = scratch_begin(&arena, 1); + + // rjf: generate result via first argument to lens + result = e_irtree_and_type_from_expr(arena, lhs->next); + + // rjf: count extra arguments + U64 arg_count = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next) { - String8 name = type->name; - irgen_rule = e_irgen_rule_from_string(name); + arg_count += 1; } - } - - // rjf: if we have a non-default ir-generation rule, then we can use that - // to generate the resultant IR tree - if(irgen_rule != &e_irgen_rule__default) - { - result = irgen_rule->irgen(arena, expr); + + // rjf: flatten extra arguments + E_Expr **args = push_array(scratch.arena, E_Expr *, arg_count); + { + U64 idx = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next, idx += 1) + { + args[idx] = arg; + } + } + + // rjf: patch resultant type with a lens w/ args, pointing to the original type + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .count = arg_count, .args = args, .direct_key = result.type_key, .name = lhs_type->name); + + scratch_end(scratch); } else { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index e98d7ed1..ee2f0cfb 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -418,6 +418,14 @@ e_type_key_cons_(E_ConsTypeParams *params) } node->byte_size = e_type_byte_size_from_key(node->params.direct_key); } + else if(params->args != 0) + { + node->params.args = push_array(e_type_state->arena, E_Expr *, params->count); + for EachIndex(idx, params->count) + { + node->params.args[idx] = e_expr_copy(e_type_state->arena, params->args[idx]); + } + } else switch(params->kind) { default: @@ -629,6 +637,15 @@ e_type_from_key(Arena *arena, E_TypeKey key) switch(type->kind) { default:{}break; + case E_TypeKind_Lens: + { + type->args = push_array(arena, E_Expr *, type->count); + MemoryCopy(type->args, node->params.args, sizeof(E_Expr *)*type->count); + for EachIndex(idx, type->count) + { + type->args[idx] = e_expr_copy(arena, type->args[idx]); + } + }break; case E_TypeKind_Struct: case E_TypeKind_Union: case E_TypeKind_Class: @@ -1686,6 +1703,25 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } }break; + case E_TypeKind_Lens: + { + E_Type *type = e_type_from_key__cached(key); + str8_list_pushf(arena, out, "%S(", type->name); + for EachIndex(idx, type->count) + { + String8 string = e_string_from_expr(arena, type->args[idx]); + str8_list_push(arena, out, string); + if(idx+1 < type->count) + { + str8_list_pushf(arena, out, ", "); + } + } + str8_list_pushf(arena, out, ") <- ("); + E_TypeKey direct = e_type_direct_from_key(key); + e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); + str8_list_pushf(arena, out, ")"); + }break; + case E_TypeKind_Ptr: { E_TypeKey direct = e_type_direct_from_key(key); diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 045dd158..0ff334ed 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -46,6 +46,7 @@ struct E_ConsTypeParams U64 depth; E_Member *members; E_EnumVal *enum_vals; + E_Expr **args; }; typedef struct E_ConsTypeNode E_ConsTypeNode; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8be41e57..82665e80 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13912,7 +13912,6 @@ rd_frame(void) { for EachElement(idx, view_ui_rule_table) { - e_irgen_rule_map_insert_new(scratch.arena, e_ir_state->ctx->irgen_rule_map, view_ui_rule_table[idx].name, E_IRGEN_FUNCTION_NAME(view_rule_noop)); rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, view_ui_rule_table[idx].name, view_ui_rule_table[idx].ui); if(view_ui_rule_table[idx].expand != 0) { From 9bfa4f87e3e6da9e59c172b70b7f54270e93f607 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 16:11:27 -0700 Subject: [PATCH 323/755] work on new eval-viz layer stringification which factors out measurement/limiting/etc., but just walks an eval tree and stringifies each part; start working on new types <-> lookup-rule stuff --- src/base/base_meta.c | 31 ++- src/base/base_meta.h | 7 +- src/eval/eval.mdesk | 1 + src/eval/eval_core.h | 9 +- src/eval/eval_ir.c | 15 +- src/eval/eval_ir.h | 1 + src/eval/eval_types.c | 1 - src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- .../eval_visualization_core.c | 189 ++++++++++++++++-- .../eval_visualization_core.h | 32 ++- src/raddbg/raddbg_core.c | 46 +++-- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 3 +- src/raddbg/raddbg_widgets.c | 3 +- 15 files changed, 278 insertions(+), 72 deletions(-) diff --git a/src/base/base_meta.c b/src/base/base_meta.c index c60dc237..2bf14eb6 100644 --- a/src/base/base_meta.c +++ b/src/base/base_meta.c @@ -44,8 +44,7 @@ typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr) switch(t->type->kind) { default:{}break; - case TypeKind_Ptr: - if(!(t->type->flags & TypeFlag_IsExternal)) + case TypeKind_Ptr: { *(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr)); }break; @@ -173,13 +172,13 @@ serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerialize task->containing_type = t->containing_type; task->containing_ptr = t->containing_ptr; SLLQueuePush(first_task, last_task, task); - } - - // rjf: catch-all: write pointer value - else - { - str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); - } + } + + // rjf: catch-all: write pointer value + else + { + str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count)); + } }break; //- rjf: arrays -> descend to underlying type, + count @@ -345,14 +344,14 @@ deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSeriali task->containing_type = t->containing_type; task->containing_ptr = t->containing_ptr; SLLQueuePush(first_task, last_task, task); - } - - // rjf: catch-all: read pointer value - else - { + } + + // rjf: catch-all: read pointer value + else + { MemoryCopy(t->dst, t_src, t->type->size*t->count); - read_off += t->type->size*t->count; - } + read_off += t->type->size*t->count; + } }break; //- rjf: arrays -> descend to underlying type, + count diff --git a/src/base/base_meta.h b/src/base/base_meta.h index 45d01e72..62faafeb 100644 --- a/src/base/base_meta.h +++ b/src/base/base_meta.h @@ -100,10 +100,9 @@ TypeKind; typedef U32 TypeFlags; enum { - TypeFlag_IsExternal = (1<<0), - TypeFlag_IsPlainText = (1<<1), - TypeFlag_IsCodeText = (1<<2), - TypeFlag_IsPathText = (1<<3), + TypeFlag_IsPlainText = (1<<0), + TypeFlag_IsCodeText = (1<<1), + TypeFlag_IsPathText = (1<<2), }; typedef U32 MemberFlags; diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 4d73fadf..36fc7a34 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -73,6 +73,7 @@ E_TypeKindTable: {Variadic "variadic" 0 } {Set "set" 0 } {Lens "lens" 0 } + {LensSpec "lens_spec" 0 } } @table(name op_kind precedence op_pre op_sep op_pos) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index e43002c3..c34d7992 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -274,11 +274,10 @@ enum { E_TypeFlag_Const = (1<<0), E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_External = (1<<2), - E_TypeFlag_IsPlainText = (1<<3), - E_TypeFlag_IsCodeText = (1<<4), - E_TypeFlag_IsPathText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_EditableChildren = (1<<5), }; typedef struct E_Member E_Member; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index a4da10ff..9deae36e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -98,7 +98,7 @@ e_select_ir_ctx(E_IRCtx *ctx) for EachElement(idx, builtin_view_rule_names) { E_Expr *expr = e_push_expr(e_ir_state->arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .name = builtin_view_rule_names[idx]); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = builtin_view_rule_names[idx]); e_string2expr_map_insert(e_ir_state->arena, ctx->macro_map, builtin_view_rule_names[idx], expr); } } @@ -2421,7 +2421,7 @@ E_IRGEN_FUNCTION_DEF(default) // rjf: calling a lens? -> generate IR for the first argument; wrap the type in // a lens type, which preserves the name & arguments of the lens call expression - if(lhs_type->kind == E_TypeKind_Lens) + if(lhs_type->kind == E_TypeKind_LensSpec) { Temp scratch = scratch_begin(&arena, 1); @@ -3347,6 +3347,17 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +internal E_LookupRule * +e_lookup_rule_from_type_key(E_TypeKey type_key) +{ + E_LookupRule *rule = &e_lookup_rule__default; + + // rjf: unpack type + E_Type *type = e_type_from_key__cached(type_key); + + return rule; +} + internal E_LookupRuleExprPair e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 105765a9..d6d2a6fe 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -288,6 +288,7 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key); internal E_LookupRuleExprPair e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); #if 0 // TODO(rjf): @eval diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ee2f0cfb..25900532 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -483,7 +483,6 @@ e_type_key_cons_base(Type *type) { E_TypeKey direct_type = e_type_key_cons_base(type->direct); E_TypeFlags flags = 0; - if(type->flags & TypeFlag_IsExternal) { flags |= E_TypeFlag_External; } if(type->flags & TypeFlag_IsPlainText){ flags |= E_TypeFlag_IsPlainText; } if(type->flags & TypeFlag_IsCodeText) { flags |= E_TypeFlag_IsCodeText; } if(type->flags & TypeFlag_IsPathText) { flags |= E_TypeFlag_IsPathText; } diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index bd097d05..1973dbf0 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_type_kind_basic_string_table[57] = +String8 e_type_kind_basic_string_table[58] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -73,9 +73,10 @@ str8_lit_comp("bitfield"), str8_lit_comp("variadic"), str8_lit_comp("set"), str8_lit_comp("lens"), +str8_lit_comp("lens_spec"), }; -U8 e_type_kind_basic_byte_size_table[57] = +U8 e_type_kind_basic_byte_size_table[58] = { 0, 0, @@ -134,6 +135,7 @@ U8 e_type_kind_basic_byte_size_table[57] = 0, 0, 0, +0, }; String8 e_expr_kind_strings[48] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 30cd7f64..d9212232 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -76,6 +76,7 @@ E_TypeKind_Bitfield, E_TypeKind_Variadic, E_TypeKind_Set, E_TypeKind_Lens, +E_TypeKind_LensSpec, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -161,8 +162,8 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_type_kind_basic_string_table[57]; -extern U8 e_type_kind_basic_byte_size_table[57]; +extern String8 e_type_kind_basic_string_table[58]; +extern U8 e_type_kind_basic_byte_size_table[58]; extern String8 e_expr_kind_strings[48]; extern E_OpInfo e_expr_kind_op_info_table[48]; extern String8 e_interpretation_code_display_strings[11]; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 9332bf9c..56b6af70 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1367,14 +1367,14 @@ ev_string_from_hresult_code(U32 code) } internal String8 -ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval) +ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval eval) { String8 result = {0}; E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_byte_size = e_type_byte_size_from_key(type_key); U8 digit_group_separator = 0; - if(!(flags & EV_StringFlag_ReadOnlyDisplayRules)) + if(!(params->flags & EV_StringFlag_ReadOnlyDisplayRules)) { digit_group_separator = 0; } @@ -1385,19 +1385,19 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_Handle: { - result = str8_from_s64(arena, eval.value.s64, radix, min_digits, digit_group_separator); + result = str8_from_s64(arena, eval.value.s64, params->radix, params->min_digits, digit_group_separator); }break; case E_TypeKind_HResult: { - if(flags & EV_StringFlag_ReadOnlyDisplayRules) + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { Temp scratch = scratch_begin(&arena, 1); U32 hresult_value = (U32)eval.value.u64; U32 is_error = !!(hresult_value & (1ull<<31)); U32 error_code = (hresult_value); U32 facility = (hresult_value & 0x7ff0000) >> 16; - String8 value_string = str8_from_s64(scratch.arena, eval.value.u64, radix, min_digits, digit_group_separator); + String8 value_string = str8_from_s64(scratch.arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator); String8 facility_string = ev_string_from_hresult_facility_code(facility); String8 error_string = ev_string_from_hresult_code(error_code); result = push_str8f(arena, "%S%s%s%S%s%s%S%s", @@ -1413,7 +1413,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, } else { - result = str8_from_s64(arena, eval.value.u64, radix, min_digits, digit_group_separator); + result = str8_from_s64(arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator); } }break; @@ -1428,11 +1428,11 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, String8 char_str = ev_string_from_ascii_value(arena, eval.value.s64); if(char_str.size != 0) { - if(flags & EV_StringFlag_ReadOnlyDisplayRules) + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { String8 imm_string = (type_is_unsigned - ? str8_from_u64(arena, eval.value.u64, radix, min_digits, digit_group_separator) - : str8_from_s64(arena, eval.value.s64, radix, min_digits, digit_group_separator)); + ? str8_from_u64(arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator) + : str8_from_s64(arena, eval.value.s64, params->radix, params->min_digits, digit_group_separator)); result = push_str8f(arena, "'%S' (%S)", char_str, imm_string); } else @@ -1443,8 +1443,8 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, else { result = (type_is_unsigned - ? str8_from_u64(arena, eval.value.u64, radix, min_digits, digit_group_separator) - : str8_from_s64(arena, eval.value.s64, radix, min_digits, digit_group_separator)); + ? str8_from_u64(arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator) + : str8_from_s64(arena, eval.value.s64, params->radix, params->min_digits, digit_group_separator)); } }break; @@ -1453,7 +1453,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_S32: case E_TypeKind_S64: { - result = str8_from_s64(arena, eval.value.s64, radix, min_digits, digit_group_separator); + result = str8_from_s64(arena, eval.value.s64, params->radix, params->min_digits, digit_group_separator); }break; case E_TypeKind_U8: @@ -1461,14 +1461,14 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_U32: case E_TypeKind_U64: { - result = str8_from_u64(arena, eval.value.u64, radix, min_digits, digit_group_separator); + result = str8_from_u64(arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator); }break; case E_TypeKind_U128: { Temp scratch = scratch_begin(&arena, 1); - String8 upper64 = str8_from_u64(scratch.arena, eval.value.u128.u64[0], radix, min_digits, digit_group_separator); - String8 lower64 = str8_from_u64(scratch.arena, eval.value.u128.u64[1], radix, min_digits, digit_group_separator); + String8 upper64 = str8_from_u64(scratch.arena, eval.value.u128.u64[0], params->radix, params->min_digits, digit_group_separator); + String8 lower64 = str8_from_u64(scratch.arena, eval.value.u128.u64[1], params->radix, params->min_digits, digit_group_separator); result = push_str8f(arena, "%S:%S", upper64, lower64); scratch_end(scratch); }break; @@ -1477,7 +1477,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_F64:{f64 = eval.value.f64;}goto f64_path; f64_path:; { - result = push_str8f(arena, "%.*f", min_digits ? min_digits : 16, f64); + result = push_str8f(arena, "%.*f", params->min_digits ? params->min_digits : 16, f64); U64 num_to_chop = 0; for(U64 num_trimmed = 0; num_trimmed < result.size; num_trimmed += 1) { @@ -1512,8 +1512,8 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, break; } } - String8 numeric_value_string = str8_from_u64(scratch.arena, eval.value.u64, radix, min_digits, digit_group_separator); - if(flags & EV_StringFlag_ReadOnlyDisplayRules) + String8 numeric_value_string = str8_from_u64(scratch.arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator); + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { if(constant_name.size != 0) { @@ -1581,6 +1581,159 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) return result; } +//- rjf: tree stringification iterator + +internal EV_StringIter * +ev_string_iter_begin(Arena *arena, E_Eval eval, EV_StringParams *params) +{ + EV_StringIter *it = push_array(arena, EV_StringIter, 1); + it->top_task = push_array(arena, EV_StringIterTask, 1); + it->top_task->eval = eval; + MemoryCopyStruct(&it->top_task->params, params); + return it; +} + +internal B32 +ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) +{ + B32 result = 0; + + //- rjf: make progress on top task + MemoryZeroStruct(out_string); + B32 need_pop = 1; + B32 need_new_task = 0; + EV_StringIterTask new_task = {0}; + if(it->top_task != 0) + { + result = 1; + + //- rjf: unpack task + U64 task_idx = it->top_task->idx; + EV_StringParams *params = &it->top_task->params; + E_Eval eval = it->top_task->eval; + E_TypeKey type_key = eval.irtree.type_key; + E_TypeKind type_kind = e_type_kind_from_key(type_key); + + //- rjf: type evaluations -> display type string + if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) + { + *out_string = e_type_string_from_key(arena, type_key); + } + + //- rjf: non-type evaluations + else switch(type_kind) + { + //- rjf: default - leaf cases + default: + { + E_Eval value_eval = e_value_eval_from_eval(eval); + *out_string = ev_string_from_simple_typed_eval(arena, params, value_eval); + }break; + + //- rjf: lenses + case E_TypeKind_Lens: + switch(task_idx) + { + default:{}break; + + // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type + case 0: + { + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; + { + E_Type *type = e_type_from_key__cached(type_key); + str8_list_pushf(scratch.arena, &strings, "%S(", type->name); + for EachIndex(idx, type->count) + { + String8 string = e_string_from_expr(scratch.arena, type->args[idx]); + str8_list_push(scratch.arena, &strings, string); + if(idx+1 < type->count) + { + str8_list_pushf(scratch.arena, &strings, ", "); + } + } + str8_list_pushf(scratch.arena, &strings, ") <- ("); + } + *out_string = str8_list_join(arena, &strings, 0); + need_new_task = 1; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + scratch_end(scratch); + }break; + + // rjf: step 1 -> close + case 1: + { + *out_string = str8_lit(")"); + }break; + }break; + + //- rjf: pointers + case E_TypeKind_Function: + case E_TypeKind_Ptr: + case E_TypeKind_LRef: + case E_TypeKind_RRef: + { + + }break; + + //- rjf: arrays + case E_TypeKind_Array: + { + + }break; + + //- rjf: non-string-arrays/structs/sets + case E_TypeKind_Struct: + case E_TypeKind_Union: + case E_TypeKind_Class: + case E_TypeKind_IncompleteStruct: + case E_TypeKind_IncompleteUnion: + case E_TypeKind_IncompleteClass: + case E_TypeKind_Set: + arrays_and_sets_and_structs: + { + + }break; + } + } + + //- rjf: bump task counter + if(it->top_task != 0) + { + it->top_task->idx += 1; + } + + //- rjf: if result is good, and we have a new task? -> push + if(result && need_new_task) + { + EV_StringIterTask *new_t = it->free_task; + if(new_t != 0) + { + SLLStackPop(it->free_task); + } + else + { + new_t = push_array(arena, EV_StringIterTask, 1); + } + MemoryCopyStruct(new_t, &new_task); + SLLStackPush(it->top_task, new_t); + new_t->idx = 0; + } + + //- rjf: if result is good, but we don't have a new task? -> pop + else if(result && need_pop) + { + EV_StringIterTask *task = it->top_task; + SLLStackPop(it->top_task); + SLLStackPush(it->free_task, task); + } + + return result; +} + //////////////////////////////// //~ rjf: Expression & IR-Tree => Expand Rule diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index bb699ecf..adbf9ff7 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -237,6 +237,32 @@ enum { EV_StringFlag_ReadOnlyDisplayRules = (1<<0), EV_StringFlag_PrettyNames = (1<<1), + EV_StringFlag_DisableAddresses = (1<<2), + EV_StringFlag_DisableStrings = (1<<3), +}; + +typedef struct EV_StringParams EV_StringParams; +struct EV_StringParams +{ + EV_StringFlags flags; + U32 radix; + U32 min_digits; +}; + +typedef struct EV_StringIterTask EV_StringIterTask; +struct EV_StringIterTask +{ + EV_StringIterTask *next; + EV_StringParams params; + E_Eval eval; + U64 idx; +}; + +typedef struct EV_StringIter EV_StringIter; +struct EV_StringIter +{ + EV_StringIterTask *top_task; + EV_StringIterTask *free_task; }; //////////////////////////////// @@ -341,9 +367,13 @@ internal B32 ev_row_is_editable(EV_Row *row); internal String8 ev_string_from_ascii_value(Arena *arena, U8 val); internal String8 ev_string_from_hresult_facility_code(U32 code); internal String8 ev_string_from_hresult_code(U32 code); -internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval); +internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval eval); internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); +//- rjf: tree stringification iterator +internal EV_StringIter *ev_string_iter_begin(Arena *arena, E_Eval eval, EV_StringParams *params); +internal B32 ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string); + //////////////////////////////// //~ rjf: Expression & IR-Tree => Expand Rule diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 82665e80..af904043 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6839,7 +6839,8 @@ rd_window_frame(void) E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); if(eval.irtree.mode != E_Mode_Null) { - String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); + EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; + String8 value_string = rd_value_string_from_eval_NEW(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); } } @@ -10419,7 +10420,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f U32 min_digits = 0; B32 no_addr = 0; B32 no_string = 0; - B32 has_array = 0; #if 0 // TODO(rjf): @eval for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) { @@ -10430,7 +10430,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f else if(str8_match(tag->string, str8_lit("oct"), 0)) {radix = 8; } else if(str8_match(tag->string, str8_lit("no_addr"), 0)) {no_addr = 1;} else if(str8_match(tag->string, str8_lit("no_string"), 0)) {no_string = 1;} - else if(str8_match(tag->string, str8_lit("array"), 0)) {has_array = 1;} else if(str8_match(tag->string, str8_lit("digits"), 0)) { E_Expr *num_expr = tag->first->next; @@ -10440,22 +10439,12 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } } #endif + + //- rjf: force no_addr in non-address-spaces if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - E_TypeKind kind = e_type_kind_from_key(eval.irtree.type_key); - if(kind != E_TypeKind_Ptr) - { - no_addr = 1; - } - else - { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(!(type->flags & E_TypeFlag_External)) - { - no_addr = 1; - } - } + no_addr = 1; } //- rjf: force no_string, if we are looking at padding members @@ -10507,7 +10496,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f default: { E_Eval value_eval = e_value_eval_from_eval(eval); - String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); + String8 string = {0}; // ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, out, string); }break; @@ -10624,7 +10613,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; str8_list_push(arena, out, left_paren); } - String8 string = ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); + String8 string = {0}; // ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, out, string); if(did_content) @@ -10889,6 +10878,25 @@ rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U3 return result; } +internal String8 +rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strs = {0}; + { + EV_StringIter *iter = ev_string_iter_begin(scratch.arena, eval, params); + F32 space_taken_px = 0; + for(String8 string = {0}; ev_string_iter_next(scratch.arena, iter, &string) && space_taken_px < max_size;) + { + str8_list_push(scratch.arena, &strs, string); + space_taken_px += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + } + } + String8 result = str8_list_join(arena, &strs, 0); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Hover Eval @@ -13922,7 +13930,7 @@ rd_frame(void) for EachElement(idx, view_ui_rule_table) { E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .name = view_ui_rule_table[idx].name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = view_ui_rule_table[idx].name); e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 855445f8..d61f709e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1007,6 +1007,7 @@ internal void rd_window_frame(void); internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out); internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); +internal String8 rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// //~ rjf: Hover Eval diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0b33bad5..9985339d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1503,7 +1503,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: generate strings/flags based on that expression & fill - result.string = rd_value_string_from_eval(arena, rd_view_query_input(), string_flags, default_radix, font, font_size, max_size_px, result.eval); + EV_StringParams string_params = {.flags = string_flags, .radix = default_radix}; + result.string = rd_value_string_from_eval_NEW(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2d472577..51c99ac5 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1978,7 +1978,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { - eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), EV_StringFlag_ReadOnlyDisplayRules, 10, params->font, params->font_size, params->font_size*60.f, eval); + EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; + eval_string = rd_value_string_from_eval_NEW(scratch.arena, str8_zero(), &string_params, params->font, params->font_size, params->font_size*60.f, eval); } ui_spacer(ui_em(1.5f, 1.f)); ui_set_next_pref_width(ui_children_sum(1)); From 7c0a37fef3e9f213cac7edb787ef9a3d333e4ade Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 7 Apr 2025 17:46:21 -0700 Subject: [PATCH 324/755] boil down expr/irtree/type -> lookup_rule mapping more - since lens arguments are now stored in type info, we no longer need other ways of smuggling through expression trees. also fill out new path of pointer eval single-line string generation. --- src/eval/eval_ir.c | 28 +-- src/eval/eval_ir.h | 1 - src/eval/eval_parse.c | 8 +- src/eval/eval_types.c | 7 +- .../eval_visualization_core.c | 187 +++++++++++++++++- .../eval_visualization_core.h | 3 + 6 files changed, 202 insertions(+), 32 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9deae36e..a5427b61 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1811,11 +1811,11 @@ E_IRGEN_FUNCTION_DEF(default) E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_LookupRuleExprPair lhs_lookup_rule = e_lookup_rule_expr_pair_from_expr_irtree(lhs, &lhs_irtree); - ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule.rule->name)) + E_LookupRule *lhs_lookup_rule = e_lookup_rule_from_type_key(lhs_irtree.type_key); + ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule->name)) { - E_LookupInfo lookup_info = lhs_lookup_rule.rule->info(arena, &lhs_irtree, lhs_lookup_rule.expr, str8_zero()); - E_LookupAccess lookup_access = lhs_lookup_rule.rule->access(arena, expr->kind, lhs, rhs, lhs_lookup_rule.expr, lookup_info.user_data); + E_LookupInfo lookup_info = lhs_lookup_rule->info(arena, &lhs_irtree, &e_expr_nil, str8_zero()); + E_LookupAccess lookup_access = lhs_lookup_rule->access(arena, expr->kind, lhs, rhs, &e_expr_nil, lookup_info.user_data); result = lookup_access.irtree_and_type; } scratch_end(scratch); @@ -3355,27 +3355,17 @@ e_lookup_rule_from_type_key(E_TypeKey type_key) // rjf: unpack type E_Type *type = e_type_from_key__cached(type_key); - return rule; -} - -internal E_LookupRuleExprPair -e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) -{ - E_LookupRuleExprPair result = {&e_lookup_rule__default, &e_expr_nil}; - - // rjf: first, try set name -> rule mapping - if(result.rule == &e_lookup_rule__default && e_type_kind_from_key(irtree->type_key) == E_TypeKind_Set) + // rjf: sets / lenses -> try to implicitly map to a rule based on name + if(type->kind == E_TypeKind_Set || type->kind == E_TypeKind_Lens) { - E_Type *type = e_type_from_key__cached(irtree->type_key); - String8 name = type->name; - E_LookupRule *candidate = e_lookup_rule_from_string(name); + E_LookupRule *candidate = e_lookup_rule_from_string(type->name); if(candidate != &e_lookup_rule__nil) { - result.rule = candidate; + rule = candidate; } } - return result; + return rule; } #if 0 // TODO(rjf): @eval diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d6d2a6fe..bb197c22 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -289,7 +289,6 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r //~ rjf: Expression & IR-Tree => Rules internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key); -internal E_LookupRuleExprPair e_lookup_rule_expr_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); #if 0 // TODO(rjf): @eval internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 34cb115c..f93e91dd 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -492,10 +492,10 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) sep_idx += 1; } str8_list_push(arena, out, seps[sep_idx]); - if(sep_idx == 0) - { - sep_idx += 1; - } + } + if(sep_idx == 0) + { + sep_idx += 1; } if(child == &e_expr_nil) { diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 25900532..b8acbc35 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1625,7 +1625,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); }break; case E_TypeKind_Bitfield: @@ -1663,7 +1662,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); }break; case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; @@ -1676,7 +1674,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); }break; case E_TypeKind_Array: @@ -1725,6 +1722,10 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { E_TypeKey direct = e_type_direct_from_key(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); + if(!e_type_kind_is_pointer_or_ref(e_type_kind_from_key(direct))) + { + str8_list_push(arena, out, str8_lit(" ")); + } str8_list_push(arena, out, str8_lit("*")); E_Type *type = e_type_from_key__cached(key); if(type->count != 1) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 56b6af70..41c957ba 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -609,9 +609,8 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai // rjf: get expr's lookup rule // TODO(rjf): @eval E_LookupRuleExprPair lookup_rule_and_tag = &e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - E_LookupRuleExprPair lookup_rule_and_tag = e_lookup_rule_expr_pair_from_expr_irtree(t->expr, &expr_irtree); - E_LookupRule *lookup_rule = lookup_rule_and_tag.rule; - E_Expr *lookup_rule_tag = lookup_rule_and_tag.expr; + E_LookupRule *lookup_rule = e_lookup_rule_from_type_key(expr_irtree.type_key); + E_Expr *lookup_rule_tag = &e_expr_nil; // rjf: get top-level lookup/expansion info E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_tag, filter); @@ -1609,6 +1608,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: unpack task U64 task_idx = it->top_task->idx; + S32 depth = it->top_task->depth; EV_StringParams *params = &it->top_task->params; E_Eval eval = it->top_task->eval; E_TypeKey type_key = eval.irtree.type_key; @@ -1623,14 +1623,18 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: non-type evaluations else switch(type_kind) { + ////////////////////////// //- rjf: default - leaf cases + // default: { E_Eval value_eval = e_value_eval_from_eval(eval); *out_string = ev_string_from_simple_typed_eval(arena, params, value_eval); }break; + ////////////////////////// //- rjf: lenses + // case E_TypeKind_Lens: switch(task_idx) { @@ -1670,22 +1674,194 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) }break; }break; + ////////////////////////// //- rjf: pointers + // case E_TypeKind_Function: case E_TypeKind_Ptr: case E_TypeKind_LRef: case E_TypeKind_RRef: { - + typedef struct EV_StringPtrData EV_StringPtrData; + struct EV_StringPtrData + { + E_Eval value_eval; + E_Type *type; + E_Type *direct_type; + B32 ptee_has_content; + B32 ptee_has_string; + B32 did_prefix_content; + }; + EV_StringPtrData *ptr_data = it->top_task->user_data; + if(ptr_data == 0) + { + ptr_data = it->top_task->user_data = push_array(arena, EV_StringPtrData, 1); + ptr_data->value_eval = e_value_eval_from_eval(eval); + ptr_data->type = e_type_from_key__cached(type_key); + ptr_data->direct_type = e_type_from_key__cached(e_type_direct_from_key(type_key)); + ptr_data->ptee_has_content = (ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); + ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || + ptr_data->direct_type->kind == E_TypeKind_S8 || + ptr_data->direct_type->kind == E_TypeKind_U8); + } + switch(task_idx) + { + default:{}break; + + //- rjf: step 0 -> try "prefix content", which we want to print before the pointer value, + // like strings or symbol names + case 0: + { + // rjf: try strings + if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && !(params->flags & EV_StringFlag_DisableStrings)) + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: read string data + U64 string_memory_addr = ptr_data->value_eval.value.u64; + U64 string_buffer_size = 256; + U8 *string_buffer = push_array(scratch.arena, U8, string_buffer_size); + for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) + { + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); + if(read_good) + { + break; + } + } + string_buffer[string_buffer_size-1] = 0; + + // rjf: check element size - if non-U8, assume UTF-16 or UTF-32 based on type, and convert + U64 element_size = ptr_data->direct_type->byte_size; + String8 string = {0}; + switch(element_size) + { + default:{string = str8_cstring((char *)string_buffer);}break; + case 2: {string = str8_from_16(scratch.arena, str16_cstring((U16 *)string_buffer));}break; + case 4: {string = str8_from_32(scratch.arena, str32_cstring((U32 *)string_buffer));}break; + } + + // rjf: escape and quote + B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableAddresses) || depth > 0); + String8 string__escaped_and_quoted = string; + if(string__is_escaped_and_quoted) + { + String8 string_escaped = ev_escaped_from_raw_string(scratch.arena, string); + string__escaped_and_quoted = push_str8f(scratch.arena, "\"%S\"", string_escaped); + } + + // rjf: report + *out_string = push_str8_copy(arena, string__escaped_and_quoted); + ptr_data->did_prefix_content = 1; + + scratch_end(scratch); + } + + // rjf: try symbols + if(!ptr_data->did_prefix_content) + { + U64 vaddr = ptr_data->value_eval.value.u64; + E_Module *module = &e_module_nil; + U32 module_idx = 0; + for EachIndex(idx, e_type_state->ctx->modules_count) + { + if(contains_1u64(e_type_state->ctx->modules[idx].vaddr_range, vaddr)) + { + module = &e_type_state->ctx->modules[idx]; + module_idx = (U32)idx; + break; + } + } + if(module != &e_module_nil) + { + U64 voff = vaddr - module->vaddr_range.min; + RDI_Procedure *procedure = rdi_procedure_from_voff(module->rdi, voff); + String8 procedure_name = {0}; + procedure_name.str = rdi_name_from_procedure(module->rdi, procedure, &procedure_name.size); + if(procedure_name.size != 0) + { + // NOTE(rjf): read-only -> generate non-parseable things, like type-info + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + { + // TODO(rjf) + *out_string = procedure_name; + } + + // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + else + { + *out_string = procedure_name; + } + + ptr_data->did_prefix_content = 1; + } + } + } + + need_pop = 0; + }break; + + //- rjf: step 1 -> do pointer value + descend if needed + case 1: + { + Temp scratch = scratch_begin(&arena, 1); + String8 ptr_value_string = str8_from_u64(scratch.arena, ptr_data->value_eval.value.u64, 16, 0, 0); + // + // NOTE(rjf): currently, we are not using the string-generation radix parameter when + // generating a pointer value - it is weird to want to change pointer value visualization + // to anything other than hex, so it is just not supported right now... + // + + // rjf: [read only] if we did prefix content, do a parenthesized pointer value + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules && ptr_data->did_prefix_content) + { + *out_string = push_str8f(arena, " (%S)", ptr_value_string); + } + + // rjf: [read only] if we did *not* do any prefix content, do " -> " then descend + else if(params->flags & EV_StringFlag_ReadOnlyDisplayRules && !ptr_data->did_prefix_content && ptr_data->ptee_has_content) + { + *out_string = push_str8f(arena, "%S -> ", ptr_value_string); + + // rjf: single-length pointers -> just gen new task for deref'd expr + if(ptr_data->type->count == 1) + { + E_Expr *deref_expr = e_expr_irext_deref(arena, eval.exprs.first, &eval.irtree); + E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); + need_new_task = 1; + new_task.params = *params; + new_task.eval = deref_eval; + } + + // rjf: multi-length pointers -> expand like an array (try to dedup with array case) + else + { + // TODO(rjf) + } + } + + // rjf: [writeable, catchall] if we did *not* do any prefix content, do "" + else + { + *out_string = push_str8_copy(arena, ptr_value_string); + } + + scratch_end(scratch); + }break; + } }break; + ////////////////////////// //- rjf: arrays + // case E_TypeKind_Array: { - + // TODO(rjf) }break; + ////////////////////////// //- rjf: non-string-arrays/structs/sets + // case E_TypeKind_Struct: case E_TypeKind_Union: case E_TypeKind_Class: @@ -1719,6 +1895,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_t = push_array(arena, EV_StringIterTask, 1); } MemoryCopyStruct(new_t, &new_task); + new_t->depth = it->top_task->depth+1; SLLStackPush(it->top_task, new_t); new_t->idx = 0; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index adbf9ff7..214fe7a5 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -247,6 +247,7 @@ struct EV_StringParams EV_StringFlags flags; U32 radix; U32 min_digits; + U8 digit_group_separator; }; typedef struct EV_StringIterTask EV_StringIterTask; @@ -256,6 +257,8 @@ struct EV_StringIterTask EV_StringParams params; E_Eval eval; U64 idx; + S32 depth; + void *user_data; }; typedef struct EV_StringIter EV_StringIter; From fbd78525d2bf72e0cad8cbfce2a0bbb80a4f4ff4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 8 Apr 2025 11:14:58 -0700 Subject: [PATCH 325/755] sketch out new eval type-system-defined hooks for all eval-layer view rules; accesses (., [] operators), expansion ranges, id <-> num mapping --- src/eval/eval_core.h | 86 +++++++++---- src/eval/eval_ir.c | 263 ++++++++++++++++++++++++++++++++++++-- src/eval/eval_types.c | 21 +-- src/eval/eval_types.h | 5 + src/raddbg/raddbg_views.c | 2 +- 5 files changed, 332 insertions(+), 45 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index c34d7992..90d45c52 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -248,6 +248,30 @@ struct E_ExprList U64 count; }; +//////////////////////////////// +//~ rjf: IR Tree Types + +typedef struct E_IRNode E_IRNode; +struct E_IRNode +{ + E_IRNode *first; + E_IRNode *last; + E_IRNode *next; + RDI_EvalOp op; + E_Space space; + String8 string; + E_Value value; +}; + +typedef struct E_IRTreeAndType E_IRTreeAndType; +struct E_IRTreeAndType +{ + E_IRNode *root; + E_TypeKey type_key; + E_Mode mode; + E_MsgList msgs; +}; + //////////////////////////////// //~ rjf: Full Extracted Type Information Types @@ -326,6 +350,38 @@ struct E_EnumValArray U64 count; }; +typedef struct E_TypeExpandInfo E_TypeExpandInfo; +struct E_TypeExpandInfo +{ + void *user_data; + U64 expr_count; +}; + +#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree) +#define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name +#define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) +typedef E_TYPE_ACCESS_FUNCTION_SIG(E_TypeAccessFunctionType); + +#define E_TYPE_EXPAND_INFO_FUNCTION_SIG(name) E_TypeExpandInfo name(Arena *arena, E_IRTreeAndType *irtree, String8 filter) +#define E_TYPE_EXPAND_INFO_FUNCTION_NAME(name) e_type_expand_info__##name +#define E_TYPE_EXPAND_INFO_FUNCTION_DEF(name) internal E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TYPE_EXPAND_INFO_FUNCTION_NAME(name)) +typedef E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TypeExpandInfoFunctionType); + +#define E_TYPE_EXPAND_RANGE_FUNCTION_SIG(name) void name(Arena *arena, void *user_data, E_Expr *expr, String8 filter, Rng1U64 idx_range, E_Expr **exprs_out, String8 *exprs_strings_out) +#define E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name) e_type_expand_range__##name +#define E_TYPE_EXPAND_RANGE_FUNCTION_DEF(name) internal E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)) +typedef E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TypeExpandRangeFunctionType); + +#define E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(void *user_data, U64 num) +#define E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name) e_type_expand_id_from_num__##name +#define E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(name) internal E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_SIG(E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name)) +typedef E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_SIG(E_TypeExpandIDFromNumFunctionType); + +#define E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(void *user_data, U64 id) +#define E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) e_type_expand_num_from_id__##name +#define E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name)) +typedef E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TypeExpandNumFromIDFunctionType); + typedef struct E_Type E_Type; struct E_Type { @@ -343,6 +399,11 @@ struct E_Type E_Member *members; E_EnumVal *enum_vals; E_Expr **args; + E_TypeAccessFunctionType *access; + E_TypeExpandInfoFunctionType *expand_info; + E_TypeExpandRangeFunctionType *expand_range; + E_TypeExpandIDFromNumFunctionType *expand_id_from_num; + E_TypeExpandNumFromIDFunctionType *expand_num_from_id; }; //////////////////////////////// @@ -357,31 +418,6 @@ struct E_Module E_Space space; }; -//////////////////////////////// -//~ rjf: IR Tree Types - -typedef struct E_IRNode E_IRNode; -struct E_IRNode -{ - E_IRNode *first; - E_IRNode *last; - E_IRNode *next; - RDI_EvalOp op; - E_Space space; - String8 string; - E_Value value; -}; - -typedef struct E_IRTreeAndType E_IRTreeAndType; -struct E_IRTreeAndType -{ - E_IRNode *root; - E_TypeKey type_key; - E_Member member; - E_Mode mode; - E_MsgList msgs; -}; - //////////////////////////////// //~ rjf: String -> Num diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index a5427b61..8d67064b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -717,7 +717,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) // rjf: fill result.irtree_and_type.root = new_tree; result.irtree_and_type.type_key = r_type; - result.irtree_and_type.member = member; result.irtree_and_type.mode = mode; } }break; @@ -1195,7 +1194,7 @@ E_IRGEN_FUNCTION_DEF(bswap) E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); e_irnode_push_child(root, irtree.root); - E_IRTreeAndType result = {root, irtree.type_key, irtree.member, irtree.mode, irtree.msgs}; + E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs}; return result; } @@ -1793,6 +1792,246 @@ e_expr_unpoison(E_Expr *expr) } } +//- rjf: default type access hook + +E_TYPE_ACCESS_FUNCTION_DEF(default) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + switch(expr->kind) + { + default:{}break; + + //- rjf: member accessing (. operator) + case E_ExprKind_MemberAccess: + { + // rjf: unpack left/right expressions + E_Expr *exprl = expr->first; + E_Expr *exprr = exprl->next; + E_IRTreeAndType l = *lhs_irtree; + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKey check_type_key = l_restype; + E_TypeKind check_type_kind = l_restype_kind; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); + check_type_kind = e_type_kind_from_key(check_type_key); + } + e_msg_list_concat_in_place(&result.msgs, &l.msgs); + + // rjf: look up member + E_Member member = zero_struct; + B32 r_found = 0; + E_TypeKey r_type = zero_struct; + U64 r_value = 0; + String8 r_query_name = {0}; + B32 r_is_constant_value = 0; + { + Temp scratch = scratch_begin(&arena, 1); + E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); + member = match; + if(match.kind != E_MemberKind_Null) + { + r_found = 1; + r_type = match.type_key; + r_value = match.off; + } + if(match.kind == E_MemberKind_Query) + { + r_query_name = exprr->string; + } + if(match.kind == E_MemberKind_Null) + { + E_Type *type = e_type_from_key__cached(check_type_key); + if(type->enum_vals != 0) + { + String8 lookup_string = exprr->string; + String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); + String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); + E_EnumVal *enum_val_match = 0; + for EachIndex(idx, type->count) + { + if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) + { + enum_val_match = &type->enum_vals[idx]; + break; + } + } + if(enum_val_match != 0) + { + r_found = 1; + r_type = check_type_key; + r_value = enum_val_match->val; + r_is_constant_value = 1; + } + } + } + scratch_end(scratch); + } + + // rjf: bad conditions? -> error if applicable, exit + if(e_type_key_match(e_type_key_zero(), check_type_key)) + { + break; + } + else if(exprr->kind != E_ExprKind_LeafIdentifier) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + break; + } + else if(!r_found) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + break; + } + else if(check_type_kind != E_TypeKind_Struct && + check_type_kind != E_TypeKind_Class && + check_type_kind != E_TypeKind_Union && + check_type_kind != E_TypeKind_Enum) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + break; + } + + // rjf: generate + { + // rjf: build tree + E_IRNode *new_tree = l.root; + E_TypeKey new_tree_type = r_type; + E_Mode mode = l.mode; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); + mode = E_Mode_Offset; + } + if(r_value != 0 && !r_is_constant_value) + { + E_IRNode *const_tree = e_irtree_const_u(arena, r_value); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); + } + else if(r_is_constant_value) + { + new_tree = e_irtree_const_u(arena, r_value); + mode = E_Mode_Value; + } + + // rjf: fill + result.root = new_tree; + result.type_key = r_type; + result.mode = mode; + } + }break; + + //- rjf: indexing ([] operator) + case E_ExprKind_ArrayIndex: + { + // rjf: unpack left/right expressions + E_Expr *exprl = expr->first; + E_Expr *exprr = exprl->next; + E_IRTreeAndType l = *lhs_irtree; + E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKey r_restype = e_type_unwrap(r.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); + if(e_type_kind_is_basic_or_enum(r_restype_kind)) + { + r_restype = e_type_unwrap_enum(r_restype); + r_restype_kind = e_type_kind_from_key(r_restype); + } + E_TypeKey direct_type = e_type_unwrap(l_restype); + direct_type = e_type_direct_from_key(direct_type); + direct_type = e_type_unwrap(direct_type); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + e_msg_list_concat_in_place(&result.msgs, &l.msgs); + e_msg_list_concat_in_place(&result.msgs, &r.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r.root->op == 0) + { + break; + } + else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + break; + } + else if(!e_type_kind_is_integer(r_restype_kind)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + break; + } + else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + break; + } + else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + break; + } + + // rjf: generate + E_IRNode *new_tree = &e_irnode_nil; + E_Mode mode = l.mode; + { + // rjf: reading from an array value -> read from stack value + if(l.mode == E_Mode_Value && l_restype_kind == E_TypeKind_Array) + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to push stack value, push offset, + read from stack value + new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); + new_tree->value.u64 = direct_type_size; + e_irnode_push_child(new_tree, offset_tree); + e_irnode_push_child(new_tree, l.root); + } + + // rjf: all other cases -> read from base offset + else + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) + E_IRNode *base_tree = l.root; + if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) + { + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); + } + + // rjf: ops to compute the final address + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + } + } + + // rjf: fill + result.root = new_tree; + result.type_key = direct_type; + result.mode = mode; + }break; + } + return result; +} + //- rjf: top-level irtree/type extraction E_IRGEN_FUNCTION_DEF(default) @@ -1807,18 +2046,20 @@ E_IRGEN_FUNCTION_DEF(default) case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - Temp scratch = scratch_begin(&arena, 1); + // rjf: unpack left-hand-size E_Expr *lhs = expr->first; - E_Expr *rhs = lhs->next; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_LookupRule *lhs_lookup_rule = e_lookup_rule_from_type_key(lhs_irtree.type_key); - ProfScope("lookup via rule '%.*s'", str8_varg(lhs_lookup_rule->name)) + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: pick access hook based on type + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + E_TypeAccessFunctionType *lhs_access = lhs_type->access; + if(lhs_access == 0) { - E_LookupInfo lookup_info = lhs_lookup_rule->info(arena, &lhs_irtree, &e_expr_nil, str8_zero()); - E_LookupAccess lookup_access = lhs_lookup_rule->access(arena, expr->kind, lhs, rhs, &e_expr_nil, lookup_info.user_data); - result = lookup_access.irtree_and_type; + lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); } - scratch_end(scratch); + + // rjf: call into hook to do access + result = lhs_access(arena, expr, &lhs_irtree); }break; //- rjf: dereference diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index b8acbc35..ee2944e9 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -625,14 +625,19 @@ e_type_from_key(Arena *arena, E_TypeKey key) if(e_type_key_match(node->key, key)) { type = push_array(arena, E_Type, 1); - type->kind = e_type_kind_from_key(node->key); - type->flags = node->params.flags; - type->name = push_str8_copy(arena, node->params.name); - type->direct_type_key = node->params.direct_key; - type->count = node->params.count; - type->depth = node->params.depth; - type->arch = node->params.arch; - type->byte_size = node->byte_size; + type->kind = e_type_kind_from_key(node->key); + type->flags = node->params.flags; + type->name = push_str8_copy(arena, node->params.name); + type->direct_type_key = node->params.direct_key; + type->count = node->params.count; + type->depth = node->params.depth; + type->arch = node->params.arch; + type->access = node->params.access; + type->expand_info = node->params.expand_info; + type->expand_range = node->params.expand_range; + type->expand_id_from_num = node->params.expand_id_from_num; + type->expand_num_from_id = node->params.expand_num_from_id; + type->byte_size = node->byte_size; switch(type->kind) { default:{}break; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 0ff334ed..9c94c2e8 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -47,6 +47,11 @@ struct E_ConsTypeParams E_Member *members; E_EnumVal *enum_vals; E_Expr **args; + E_TypeAccessFunctionType *access; + E_TypeExpandInfoFunctionType *expand_info; + E_TypeExpandRangeFunctionType *expand_range; + E_TypeExpandIDFromNumFunctionType *expand_id_from_num; + E_TypeExpandNumFromIDFunctionType *expand_num_from_id; }; typedef struct E_ConsTypeNode E_ConsTypeNode; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9985339d..634fc015 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1406,7 +1406,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla case E_ExprKind_MemberAccess: { Temp scratch = scratch_begin(&arena, 1); - E_Member member = result.eval.irtree.member; + E_Member member = e_type_member_from_key_name__cached(result.eval.irtree.type_key, notable_expr->last->string); String8 member_name = member.name; if(member_name.size == 0) { From d3f0a9a6728be286ed02855bb3a8925b5cf79a4a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 8 Apr 2025 14:39:28 -0700 Subject: [PATCH 326/755] checkpoint in moving from old lookup hooks -> new type hooks; elimination of unnecessary recomputation of ir-trees/evals, just use information in already-computed evals --- src/ctrl/ctrl_core.c | 2 + src/eval/eval_bundles.c | 54 +- src/eval/eval_bundles.h | 8 +- src/eval/eval_core.h | 27 +- src/eval/eval_ir.c | 2915 +++++++---------- src/eval/eval_ir.h | 11 + src/eval/eval_types.c | 455 ++- src/eval/eval_types.h | 17 +- .../eval_visualization_core.c | 170 +- .../eval_visualization_core.h | 29 +- src/lib_raddbg_markup/raddbg_markup.h | 4 +- src/raddbg/raddbg_core.c | 1418 +------- src/raddbg/raddbg_core.h | 2 + src/raddbg/raddbg_eval.c | 1274 +++++++ src/raddbg/raddbg_eval.h | 88 + src/raddbg/raddbg_inc.c | 1 + src/raddbg/raddbg_inc.h | 1 + src/raddbg/raddbg_views.c | 92 +- src/raddbg/raddbg_views.h | 1 - 19 files changed, 3369 insertions(+), 3200 deletions(-) create mode 100644 src/raddbg/raddbg_eval.c create mode 100644 src/raddbg/raddbg_eval.h diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ffa258d2..f33b082d 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4695,10 +4695,12 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(arena, 512); +#if 0 // TODO(rjf): @eval ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); ctx->lookup_rule_map[0] = e_lookup_rule_map_make(arena, 512); ctx->irgen_rule_map = push_array(arena, E_IRGenRuleMap, 1); ctx->irgen_rule_map[0] = e_irgen_rule_map_make(arena, 512); +#endif ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); ctx->auto_hook_map[0] = e_auto_hook_map_make(arena, 512); } diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 87c45e0c..263159d5 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -6,17 +6,9 @@ internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) -{ - E_ExprChain exprs = {expr, expr}; - E_Eval result = e_eval_from_exprs(arena, exprs); - return result; -} - -internal E_Eval -e_eval_from_exprs(Arena *arena, E_ExprChain exprs) { ProfBeginFunction(); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); E_Interpretation interp = e_interpret(bytecode); @@ -24,7 +16,7 @@ e_eval_from_exprs(Arena *arena, E_ExprChain exprs) { .value = interp.value, .space = interp.space, - .exprs = exprs, + .expr = expr, .irtree = irtree, .bytecode = bytecode, .code = interp.code, @@ -43,7 +35,7 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); - E_Eval eval = e_eval_from_exprs(arena, parse.exprs); + E_Eval eval = e_eval_from_expr(arena, parse.exprs.first); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } @@ -252,22 +244,22 @@ e_value_from_expr(E_Expr *expr) E_Value result = value_eval.value; scratch_end(scratch); return result; -} - +} + //////////////////////////////// //~ rjf: Debug Logging Functions -internal String8 -e_debug_log_from_expr_string(Arena *arena, String8 string) -{ - Temp scratch = scratch_begin(&arena, 1); - char *indent_spaces = " "; - String8List strings = {0}; - +internal String8 +e_debug_log_from_expr_string(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + char *indent_spaces = " "; + String8List strings = {0}; + //- rjf: begin expression String8 expr_text = string; str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text); - + //- rjf: tokenize E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr_text); str8_list_pushf(scratch.arena, &strings, " tokens:\n"); @@ -277,7 +269,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) String8 token_string = str8_substr(expr_text, token.range); str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); } - + //- rjf: parse E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr_text, tokens); { @@ -320,7 +312,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } } } - + //- rjf: type E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.first); { @@ -335,7 +327,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); } } - + //- rjf: irtree { typedef struct Task Task; @@ -376,10 +368,10 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } } } - - str8_list_pushf(scratch.arena, &strings, "\n"); - - String8 result = str8_list_join(arena, &strings, 0); - scratch_end(scratch); - return result; -} + + str8_list_pushf(scratch.arena, &strings, "\n"); + + String8 result = str8_list_join(arena, &strings, 0); + scratch_end(scratch); + return result; +} diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index c5028e08..9801fbf8 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -12,18 +12,22 @@ struct E_Eval { E_Value value; E_Space space; - E_ExprChain exprs; + E_Expr *expr; E_IRTreeAndType irtree; String8 bytecode; E_InterpretationCode code; E_MsgList msgs; }; +//////////////////////////////// +//~ rjf: Globals + +read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e_irnode_nil}}; + //////////////////////////////// //~ rjf: Bundled Evaluation Functions internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); -internal E_Eval e_eval_from_exprs(Arena *arena, E_ExprChain exprs); internal E_Eval e_eval_from_string(Arena *arena, String8 string); internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 90d45c52..ea79a619 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -268,6 +268,7 @@ struct E_IRTreeAndType { E_IRNode *root; E_TypeKey type_key; + void *user_data; E_Mode mode; E_MsgList msgs; }; @@ -288,7 +289,6 @@ typedef enum E_MemberKind E_MemberKind_VirtualBase, E_MemberKind_NestedType, E_MemberKind_Padding, - E_MemberKind_Query, E_MemberKind_COUNT } E_MemberKind; @@ -357,6 +357,11 @@ struct E_TypeExpandInfo U64 expr_count; }; +#define E_TYPE_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_IRTreeAndType *irtree) +#define E_TYPE_IRGEN_FUNCTION_NAME(name) e_type_irgen__##name +#define E_TYPE_IRGEN_FUNCTION_DEF(name) internal E_TYPE_IRGEN_FUNCTION_SIG(E_TYPE_IRGEN_FUNCTION_NAME(name)) +typedef E_TYPE_IRGEN_FUNCTION_SIG(E_TypeIRGenFunctionType); + #define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree) #define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name #define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) @@ -382,6 +387,15 @@ typedef E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_SIG(E_TypeExpandIDFromNumFunctionType #define E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name)) typedef E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TypeExpandNumFromIDFunctionType); +typedef struct E_TypeExpandRule E_TypeExpandRule; +struct E_TypeExpandRule +{ + E_TypeExpandInfoFunctionType *info; + E_TypeExpandRangeFunctionType *range; + E_TypeExpandIDFromNumFunctionType *id_from_num; + E_TypeExpandNumFromIDFunctionType *num_from_id; +}; + typedef struct E_Type E_Type; struct E_Type { @@ -399,11 +413,9 @@ struct E_Type E_Member *members; E_EnumVal *enum_vals; E_Expr **args; + E_TypeIRGenFunctionType *irgen; E_TypeAccessFunctionType *access; - E_TypeExpandInfoFunctionType *expand_info; - E_TypeExpandRangeFunctionType *expand_range; - E_TypeExpandIDFromNumFunctionType *expand_id_from_num; - E_TypeExpandNumFromIDFunctionType *expand_num_from_id; + E_TypeExpandRule expand; }; //////////////////////////////// @@ -483,6 +495,8 @@ struct E_String2ExprMap //////////////////////////////// //~ rjf: Member/Index Lookup Hooks +#if 0 // TODO(rjf): @eval + typedef struct E_LookupInfo E_LookupInfo; struct E_LookupInfo { @@ -565,10 +579,12 @@ struct E_LookupRuleExprPair E_LookupRule *rule; E_Expr *expr; }; +#endif //////////////////////////////// //~ rjf: IR Generation Hooks +#if 0 // TODO(rjf): @eval #define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr) #define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name #define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) @@ -602,6 +618,7 @@ struct E_IRGenRuleMap U64 slots_count; E_IRGenRuleSlot *slots; }; +#endif //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 8d67064b..03cb1a7f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -103,268 +103,10 @@ e_select_ir_ctx(E_IRCtx *ctx) } } -//////////////////////////////// -//~ rjf: File System Lookup Rules - -typedef struct E_FolderAccel E_FolderAccel; -struct E_FolderAccel -{ - String8 folder_path; - String8Array folders; - String8Array files; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(folder) -{ - E_LookupInfo info = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: evaluate lhs file path ID - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - E_Value lhs_value = lhs_interp.value; - U64 lhs_string_id = lhs_value.u64; - String8 folder_path = e_string_from_id(lhs_string_id); - - //- rjf: compute filter - omit common prefixes (common parent paths) - String8 local_filter = filter; - { - U64 folder_pos_in_filter = str8_find_needle(filter, 0, folder_path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive); - if(folder_pos_in_filter < filter.size) - { - local_filter = str8_skip(local_filter, folder_pos_in_filter+folder_path.size); - local_filter = str8_skip_chop_slashes(local_filter); - } - else - { - MemoryZeroStruct(&local_filter); - } - } - - //- rjf: gather & filter files in this folder - String8List folder_paths = {0}; - String8List file_paths = {0}; - { - OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name); - if(matches.count == matches.needle_part_count) - { - if(info.props.flags & FilePropertyFlag_IsFolder) - { - str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); - } - else - { - str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); - } - } - } - os_file_iter_end(iter); - } - - //- rjf: build accelerator - E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1); - accel->folder_path = push_str8_copy(arena, folder_path); - accel->folders = str8_array_from_list(arena, &folder_paths); - accel->files = str8_array_from_list(arena, &file_paths); - info.user_data = accel; - info.idxed_expr_count = accel->folders.count + accel->files.count; - scratch_end(scratch); - } - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(folder) -{ - E_FolderAccel *accel = (E_FolderAccel *)user_data; - U64 out_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = &e_expr_nil; - String8 expr_string = {0}; - if(0 <= idx && idx < accel->folders.count) - { - String8 folder_name = accel->folders.v[idx - 0]; - String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); - expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); - expr->space = e_space_make(E_SpaceKind_FileSystem); - expr->value.u64 = e_id_from_string(folder_path); - expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); - } - else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) - { - String8 file_name = accel->files.v[idx - accel->folders.count]; - String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); - expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); - expr->space = e_space_make(E_SpaceKind_FileSystem); - expr->value.u64 = e_id_from_string(file_path); - expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); - } - exprs[out_idx] = expr; - exprs_strings[out_idx] = expr_string; - scratch_end(scratch); - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(folder) -{ - U64 id = 0; - E_FolderAccel *accel = (E_FolderAccel *)user_data; - String8 name = {0}; - if(0 < num && num <= accel->folders.count) - { - name = accel->folders.v[num-1]; - } - else if(accel->folders.count < num && num <= accel->folders.count+accel->files.count) - { - name = accel->files.v[num-accel->folders.count-1]; - } - id = e_hash_from_string(5381, name); - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(folder) -{ - U64 num = 0; - E_FolderAccel *accel = (E_FolderAccel *)user_data; - for(U64 idx = 0; idx < accel->folders.count+accel->files.count; idx += 1) - { - String8 name = {0}; - if(0 <= idx && idx < accel->folders.count) - { - name = accel->folders.v[idx]; - } - else if(accel->folders.count <= idx && idx < accel->folders.count+accel->files.count) - { - name = accel->files.v[idx-accel->folders.count]; - } - U64 hash = e_hash_from_string(5381, name); - if(hash == id) - { - num = idx+1; - break; - } - } - return num; -} - -typedef struct E_FileAccel E_FileAccel; -struct E_FileAccel -{ - String8 file_path; - FileProperties props; - String8Array fields; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(file) -{ - E_FileAccel *accel = push_array(arena, E_FileAccel, 1); - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: evaluate lhs file path ID - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - E_Value lhs_value = lhs_interp.value; - U64 lhs_string_id = lhs_value.u64; - - //- rjf: get file path - String8 file_path = e_string_from_id(lhs_string_id); - - //- rjf: build field list - String8List fields = {0}; - str8_list_pushf(arena, &fields, "size"); - str8_list_pushf(arena, &fields, "last_modified_time"); - str8_list_pushf(arena, &fields, "creation_time"); - str8_list_pushf(arena, &fields, "data"); - - //- rjf: fill accel - accel->file_path = push_str8_copy(arena, file_path); - accel->props = os_properties_from_file_path(file_path); - accel->fields = str8_array_from_list(arena, &fields); - - scratch_end(scratch); - } - E_LookupInfo info = {accel, accel->fields.count}; - return info; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(file) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_MemberAccess) - { - E_FileAccel *accel = (E_FileAccel *)user_data; - String8 member_name = rhs->string; - if(str8_match(member_name, str8_lit("size"), 0)) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - space.u64_0 = e_id_from_string(accel->file_path); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.size)); - result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); - result.irtree_and_type.mode = E_Mode_Value; - } - else if(str8_match(member_name, str8_lit("last_modified_time"), 0)) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - space.u64_0 = e_id_from_string(accel->file_path); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.modified)); - result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); - result.irtree_and_type.mode = E_Mode_Value; - } - else if(str8_match(member_name, str8_lit("creation_time"), 0)) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - space.u64_0 = e_id_from_string(accel->file_path); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.created)); - result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64); - result.irtree_and_type.mode = E_Mode_Value; - } - else if(str8_match(member_name, str8_lit("data"), 0)) - { - E_Space space = e_space_make(E_SpaceKind_File); - space.u64_0 = e_id_from_string(accel->file_path); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size, 0); - result.irtree_and_type.mode = E_Mode_Offset; - } - } - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(file) -{ - E_FileAccel *accel = (E_FileAccel *)user_data; - U64 out_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - E_Expr *expr = &e_expr_nil; - String8 string = {0}; - if(0 <= idx && idx < accel->fields.count) - { - String8 name = accel->fields.v[idx]; - expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); - rhs->string = push_str8_copy(arena, name); - e_expr_push_child(expr, e_expr_ref(arena, lhs)); - e_expr_push_child(expr, rhs); - } - exprs[out_idx] = expr; - exprs_strings[out_idx] = string; - } -} - //////////////////////////////// //~ rjf: Slice Lookup Rules +#if 0 // TODO(rjf): @eval typedef struct E_SliceAccel E_SliceAccel; struct E_SliceAccel { @@ -529,55 +271,6 @@ E_LOOKUP_RANGE_FUNCTION_DEF(slice) } } -E_LOOKUP_INFO_FUNCTION_DEF(default) -{ - E_LookupInfo lookup_info = {0}; - { - E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) - { - E_Type *type = e_type_from_key__cached(lhs_type_key); - lookup_info.idxed_expr_count = type->count; - if(type->count == 1) - { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); - lookup_info.named_expr_count = data_members.count; - } - else if(direct_type_kind == E_TypeKind_Enum) - { - E_Type *direct_type = e_type_from_key__cached(direct_type_key); - lookup_info.named_expr_count = direct_type->count; - } - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Union) - { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(lhs_type_key, filter); - lookup_info.named_expr_count = data_members.count; - } - else if(lhs_type_kind == E_TypeKind_Enum) - { - E_Type *direct_type = e_type_from_key__cached(lhs_type_key); - lookup_info.named_expr_count = direct_type->count; - } - else if(lhs_type_kind == E_TypeKind_Array) - { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - lookup_info.idxed_expr_count = lhs_type->count; - } - } - return lookup_info; -} - E_LOOKUP_ACCESS_FUNCTION_DEF(default) { // @@ -619,7 +312,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) B32 r_found = 0; E_TypeKey r_type = zero_struct; U64 r_value = 0; - String8 r_query_name = {0}; B32 r_is_constant_value = 0; { Temp scratch = scratch_begin(&arena, 1); @@ -631,10 +323,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) r_type = match.type_key; r_value = match.off; } - if(match.kind == E_MemberKind_Query) - { - r_query_name = exprr->string; - } if(match.kind == E_MemberKind_Null) { E_Type *type = e_type_from_key__cached(check_type_key); @@ -825,111 +513,6 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) return result; } -E_LOOKUP_RANGE_FUNCTION_DEF(default) -{ - Temp scratch = scratch_begin(&arena, 1); - { - //- rjf: unpack type of expression - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - //- rjf: pull out specific kinds of types - B32 do_struct_range = 0; - B32 do_enum_range = 0; - B32 do_index_range = 0; - E_TypeKey enum_type_key = zero_struct; - E_TypeKey struct_type_key = zero_struct; - E_TypeKind struct_type_kind = E_TypeKind_Null; - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) - { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if(lhs_type->count == 1 && - (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class)) - { - struct_type_key = direct_type_key; - struct_type_kind = direct_type_kind; - do_struct_range = 1; - } - else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) - { - do_enum_range = 1; - enum_type_key = direct_type_key; - } - else - { - do_index_range = 1; - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Class) - { - struct_type_key = lhs_type_key; - struct_type_kind = lhs_type_kind; - do_struct_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Enum) - { - enum_type_key = lhs_type_key; - do_enum_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Set) - { - do_index_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Array) - { - do_index_range = 1; - } - - //- rjf: struct case -> the lookup-range will return a range of members - if(do_struct_range) - { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); - Rng1U64 legal_idx_range = r1u64(0, data_members.count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 member_idx = idx + read_range.min; - String8 member_name = data_members.v[member_idx].name; - exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); - } - } - - //- rjf: enum case -> the lookup-range will return a range of enum constants - else if(do_enum_range) - { - E_Type *type = e_type_from_key__cached(enum_type_key); - Rng1U64 legal_idx_range = r1u64(0, type->count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 member_idx = idx + read_range.min; - String8 member_name = type->enum_vals[member_idx].name; - exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); - } - } - - //- rjf: ptr case -> the lookup-range will return a range of dereferences - else if(do_index_range) - { - U64 read_range_count = dim_1u64(idx_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, idx_range.min + idx); - } - } - } - scratch_end(scratch); -} - E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default) { return num; @@ -939,10 +522,12 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) { return id; } +#endif //////////////////////////////// //~ rjf: Member Filtering Lookup Rules +#if 0 // TODO(rjf): @eval typedef struct E_MemberFilterAccel E_MemberFilterAccel; struct E_MemberFilterAccel { @@ -1112,10 +697,12 @@ E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) scratch_end(scratch); } } +#endif //////////////////////////////// //~ rjf: Lookups +#if 0 // TODO(rjf): @eval internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count) { @@ -1185,10 +772,12 @@ e_lookup_rule_from_string(String8 string) } return result; } +#endif //////////////////////////////// //~ rjf: IR Gen Rules +#if 0 // TODO(rjf): @eval E_IRGEN_FUNCTION_DEF(bswap) { E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); @@ -1252,6 +841,7 @@ e_irgen_rule_from_string(String8 string) } return rule; } +#endif //////////////////////////////// //~ rjf: Auto Hooks @@ -1838,10 +1428,6 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) r_type = match.type_key; r_value = match.off; } - if(match.kind == E_MemberKind_Query) - { - r_query_name = exprr->string; - } if(match.kind == E_MemberKind_Null) { E_Type *type = e_type_from_key__cached(check_type_key); @@ -2034,1261 +1620,1268 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction -E_IRGEN_FUNCTION_DEF(default) -{ - E_IRTreeAndType result = {&e_irnode_nil}; - E_ExprKind kind = expr->kind; - switch(kind) - { - default:{}break; - - //- rjf: accesses - case E_ExprKind_MemberAccess: - case E_ExprKind_ArrayIndex: - { - // rjf: unpack left-hand-size - E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - - // rjf: pick access hook based on type - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - E_TypeAccessFunctionType *lhs_access = lhs_type->access; - if(lhs_access == 0) - { - lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); - } - - // rjf: call into hook to do access - result = lhs_access(arena, expr, &lhs_irtree); - }break; - - //- rjf: dereference - case E_ExprKind_Deref: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey r_type_direct = e_type_direct_from_key(r_type); - U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r_tree.root->op == 0) - { - break; - } - else if(r_type_direct_size == 0 && - (r_type_kind == E_TypeKind_Ptr || - r_type_kind == E_TypeKind_LRef || - r_type_kind == E_TypeKind_RRef)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference pointers of zero-sized types."); - break; - } - else if(r_type_direct_size == 0 && r_type_kind == E_TypeKind_Array) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference arrays of zero-sized types."); - break; - } - else if(r_type_kind != E_TypeKind_Array && - r_type_kind != E_TypeKind_Ptr && - r_type_kind != E_TypeKind_LRef && - r_type_kind != E_TypeKind_RRef) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference this type."); - break; - } - - // rjf: generate - { - E_IRNode *new_tree = r_tree.root; - if(r_tree.mode != E_Mode_Value && - (r_type_kind == E_TypeKind_Ptr || - r_type_kind == E_TypeKind_LRef || - r_type_kind == E_TypeKind_RRef)) - { - new_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - } - result.root = new_tree; - result.type_key = r_type_direct; - result.mode = E_Mode_Offset; - } - }break; - - //- rjf: address-of - case E_ExprKind_Address: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = r_tree.type_key; - E_TypeKey r_type_unwrapped = e_type_unwrap(r_type); - E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r_tree.root->op == 0) - { - break; - } - else if(e_type_key_match(e_type_key_zero(), r_type_unwrapped)) - { - break; - } - - // rjf: generate - result.root = r_tree.root; - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 1, 0); - result.mode = E_Mode_Value; - }break; - - //- rjf: cast - case E_ExprKind_Cast: - { - // rjf: unpack operands - E_Expr *cast_type_expr = expr->first; - E_Expr *casted_expr = cast_type_expr->next; - E_TypeKey cast_type = e_type_from_expr(cast_type_expr); - E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); - U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); - e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); - E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key); - E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); - U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); - U8 in_group = e_type_group_from_kind(casted_type_kind); - U8 out_group = e_type_group_from_kind(cast_type_kind); - RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); - - // rjf: bad conditions? -> error if applicable, exit - if(casted_tree.root->op == 0) - { - break; - } - else if(cast_type_kind == E_TypeKind_Null) - { - break; - } - else if(conversion_rule != RDI_EvalConversionKind_Noop && - conversion_rule != RDI_EvalConversionKind_Legal) - { - String8 text = str8_lit("Unknown cast conversion rule."); - if(conversion_rule < RDI_EvalConversionKind_COUNT) - { - text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); - } - e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); - break; - } - - // rjf: generate - { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); - E_IRNode *new_tree = in_tree; - if(conversion_rule == RDI_EvalConversionKind_Legal) - { - new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group); - } - if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind)) - { - new_tree = e_irtree_trunc(arena, in_tree, cast_type); - } - result.root = new_tree; - result.type_key = cast_type; - result.mode = E_Mode_Value; - } - }break; - - //- rjf: sizeof - case E_ExprKind_Sizeof: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_TypeKey r_type = zero_struct; - E_Space space = r_expr->space; - switch(r_expr->kind) - { - case E_ExprKind_TypeIdent: - case E_ExprKind_Ptr: - case E_ExprKind_Array: - case E_ExprKind_Func: - { - r_type = e_type_from_expr(r_expr); - }break; - default: - { - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - r_type = r_tree.type_key; - }break; - } - - // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(r_type, e_type_key_zero())) - { - break; - } - else if(e_type_kind_from_key(r_type) == E_TypeKind_Null) - { - break; - } - - // rjf: generate - { - U64 r_type_byte_size = e_type_byte_size_from_key(r_type); - result.root = e_irtree_const_u(arena, r_type_byte_size); - result.type_key = e_type_key_basic(E_TypeKind_U64); - result.mode = E_Mode_Value; - } - }break; - - //- rjf: typeof - case E_ExprKind_Typeof: - { - // rjf: evaluate operand tree - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - - // rjf: fill output - result.root = e_irtree_const_u(arena, 0); - result.type_key = r_tree.type_key; - result.mode = E_Mode_Null; - }break; - - //- rjf: byteswap - case E_ExprKind_ByteSwap: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - U64 r_type_size = e_type_byte_size_from_key(r_type); - - // rjf: bad conditions? -> error if applicable, exit - if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Byteswapping this type is not supported."); - break; - } - - // rjf: generate - { - E_IRNode *node = e_push_irnode(arena, RDI_EvalOp_ByteSwap); - E_IRNode *rhs = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - e_irnode_push_child(node, rhs); - node->value.u64 = r_type_size; - result.root = node; - result.mode = E_Mode_Value; - result.type_key = r_type; - } - }break; - - //- rjf: unary operations - case E_ExprKind_Pos: - { - result = e_irtree_and_type_from_expr(arena, expr->first); - }break; - case E_ExprKind_Neg: - case E_ExprKind_BitNot: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); - E_TypeKey r_type_promoted = e_type_promote(r_type); - RDI_EvalOp op = e_opcode_from_expr_kind(kind); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r_tree.root->op == 0) - { - break; - } - else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); - break; - } - - // rjf: generate - { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); - E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); - result.root = new_tree; - result.type_key = r_type_promoted; - result.mode = E_Mode_Value; - } - }break; - case E_ExprKind_LogNot: - { - // rjf: unpack operand - E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); - E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); - RDI_EvalOp op = e_opcode_from_expr_kind(kind); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r_tree.root->op == 0) - { - break; - } - else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); - break; - } - - // rjf: generate - { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); - E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); - result.root = new_tree; - result.type_key = r_type_promoted; - result.mode = E_Mode_Value; - } - }break; - - //- rjf: binary operations - case E_ExprKind_Mul: - case E_ExprKind_Div: - case E_ExprKind_Mod: - case E_ExprKind_Add: - case E_ExprKind_Sub: - case E_ExprKind_LShift: - case E_ExprKind_RShift: - case E_ExprKind_Less: - case E_ExprKind_LsEq: - case E_ExprKind_Grtr: - case E_ExprKind_GrEq: - case E_ExprKind_EqEq: - case E_ExprKind_NtEq: - case E_ExprKind_BitAnd: - case E_ExprKind_BitXor: - case E_ExprKind_BitOr: - case E_ExprKind_LogAnd: - case E_ExprKind_LogOr: - { - // rjf: unpack operands - RDI_EvalOp op = e_opcode_from_expr_kind(kind); - B32 is_comparison = e_expr_kind_is_comparison(kind); - E_Expr *l_expr = expr->first; - E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key)); - E_TypeKey r_type = e_type_unwrap_enum(e_type_unwrap(r_tree.type_key)); - E_TypeKind l_type_kind = e_type_kind_from_key(l_type); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - if(l_type.kind == E_TypeKeyKind_Reg) - { - l_type_kind = E_TypeKind_U64; - l_type = e_type_key_basic(l_type_kind); - } - if(r_type.kind == E_TypeKeyKind_Reg) - { - r_type_kind = E_TypeKind_U64; - r_type = e_type_key_basic(r_type_kind); - } - B32 l_is_pointer = (l_type_kind == E_TypeKind_Ptr); - B32 l_is_decay = (l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Offset); - B32 l_is_pointer_like = (l_is_pointer || l_is_decay); - B32 r_is_pointer = (r_type_kind == E_TypeKind_Ptr); - B32 r_is_decay = (r_type_kind == E_TypeKind_Array && r_tree.mode == E_Mode_Offset); - B32 r_is_pointer_like = (r_is_pointer || r_is_decay); - RDI_EvalTypeGroup l_type_group = e_type_group_from_kind(l_type_kind); - RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); - - // rjf: bad conditions? -> error if applicable, exit - if(l_tree.root->op == 0 || r_tree.root->op == 0) - { - break; - } - - // rjf: determine arithmetic path -#define E_ArithPath_Normal 0 -#define E_ArithPath_PtrAdd 1 -#define E_ArithPath_PtrSub 2 -#define E_ArithPath_PtrArrayCompare 3 - B32 ptr_arithmetic_mul_rptr = 0; - U32 arith_path = E_ArithPath_Normal; - if(kind == E_ExprKind_Add) - { - if(l_is_pointer_like && e_type_kind_is_integer(r_type_kind)) - { - arith_path = E_ArithPath_PtrAdd; - } - if(l_is_pointer_like && e_type_kind_is_integer(l_type_kind)) - { - arith_path = E_ArithPath_PtrAdd; - ptr_arithmetic_mul_rptr = 1; - } - } - else if(kind == E_ExprKind_Sub) - { - if(l_is_pointer_like && e_type_kind_is_integer(r_type_kind)) - { - arith_path = E_ArithPath_PtrAdd; - } - if(l_is_pointer_like && r_is_pointer_like) - { - E_TypeKey l_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); - E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(r_type))); - U64 l_type_direct_byte_size = e_type_byte_size_from_key(l_type_direct); - U64 r_type_direct_byte_size = e_type_byte_size_from_key(r_type_direct); - if(l_type_direct_byte_size == r_type_direct_byte_size) - { - arith_path = E_ArithPath_PtrSub; - } - } - } - else if(kind == E_ExprKind_EqEq) - { - if(l_type_kind == E_TypeKind_Array && (r_type_kind == E_TypeKind_Ptr || r_is_decay)) - { - arith_path = E_ArithPath_PtrArrayCompare; - } - if(r_type_kind == E_TypeKind_Array && (l_type_kind == E_TypeKind_Ptr || l_is_decay)) - { - arith_path = E_ArithPath_PtrArrayCompare; - } - } - - // rjf: generate according to arithmetic path - switch(arith_path) - { - //- rjf: normal arithmetic - case E_ArithPath_Normal: - { - // rjf: bad conditions? -> error if applicable, exit - if(!rdi_eval_op_typegroup_are_compatible(op, l_type_group) || - !rdi_eval_op_typegroup_are_compatible(op, r_type_group)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); - break; - } - - // rjf: generate - { - E_TypeKey final_type_key = is_comparison ? e_type_key_basic(E_TypeKind_Bool) : l_type; - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - l_value_tree = e_irtree_convert_hi(arena, l_value_tree, l_type, l_type); - r_value_tree = e_irtree_convert_hi(arena, r_value_tree, l_type, r_type); - E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, l_value_tree, r_value_tree); - result.root = new_tree; - result.type_key = final_type_key; - result.mode = E_Mode_Value; - } - }break; - - //- rjf: pointer addition - case E_ArithPath_PtrAdd: - { - // rjf: map l/r to ptr/int - E_IRTreeAndType *ptr_tree = &l_tree; - E_IRTreeAndType *int_tree = &r_tree; - B32 ptr_is_decay = l_is_decay; - if(ptr_arithmetic_mul_rptr) - { - ptr_tree = &r_tree; - int_tree = &l_tree; - ptr_is_decay = r_is_decay; - } - - // rjf: unpack type - E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(ptr_tree->type_key))); - U64 direct_type_size = e_type_byte_size_from_key(direct_type); - - // rjf: generate - { - E_IRNode *ptr_root = ptr_tree->root; - if(!ptr_is_decay) - { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_root, ptr_tree->type_key); - } - E_IRNode *int_root = int_tree->root; - int_root = e_irtree_resolve_to_value(arena, int_tree->mode, int_root, int_tree->type_key); - if(direct_type_size > 1) - { - E_IRNode *const_root = e_irtree_const_u(arena, direct_type_size); - int_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, int_root, const_root); - } - E_TypeKey ptr_type = ptr_tree->type_key; - if(ptr_is_decay) - { - ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 1, 0); - } - E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); - result.root = new_root; - result.type_key = ptr_type; - result.mode = E_Mode_Value; - } - }break; - - //- rjf: pointer subtraction - case E_ArithPath_PtrSub: - { - // rjf: unpack type - E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); - U64 direct_type_size = e_type_byte_size_from_key(direct_type); - - // rjf: generate - E_IRNode *l_root = l_tree.root; - E_IRNode *r_root = r_tree.root; - if(!l_is_decay) - { - l_root = e_irtree_resolve_to_value(arena, l_tree.mode, l_root, l_type); - } - if(!r_is_decay) - { - r_root = e_irtree_resolve_to_value(arena, r_tree.mode, r_root, r_type); - } - E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_root, r_root); - E_IRNode *new_tree = op_tree; - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Div, new_tree, const_tree); - } - result.root = new_tree; - result.type_key = e_type_key_basic(E_TypeKind_U64); - result.mode = E_Mode_Value; - }break; - - //- rjf: pointer array comparison - case E_ArithPath_PtrArrayCompare: - { - // rjf: map l/r to pointer/array - B32 ptr_is_decay = l_is_decay; - E_IRTreeAndType *ptr_tree = &l_tree; - E_IRTreeAndType *arr_tree = &r_tree; - if(l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Value) - { - ptr_is_decay = r_is_decay; - ptr_tree = &r_tree; - arr_tree = &l_tree; - } - - // rjf: resolve pointer to value, sized same as array - E_IRNode *ptr_root = ptr_tree->root; - E_IRNode *arr_root = arr_tree->root; - if(!ptr_is_decay) - { - ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); - } - - // rjf: read from pointer into value, to compare with array - E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_root, arr_tree->type_key); - - // rjf: generate - result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, mem_root, arr_root); - result.type_key = e_type_key_basic(E_TypeKind_Bool); - result.mode = E_Mode_Value; - }break; - } - }break; - - //- rjf: ternary operators - case E_ExprKind_Ternary: - { - // rjf: unpack operands - E_Expr *c_expr = expr->first; - E_Expr *l_expr = c_expr->next; - E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr); - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); - e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey c_type = e_type_unwrap(c_tree.type_key); - E_TypeKey l_type = e_type_unwrap(l_tree.type_key); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); - E_TypeKind c_type_kind = e_type_kind_from_key(c_type); - E_TypeKind l_type_kind = e_type_kind_from_key(l_type); - E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey result_type = l_type; - - // rjf: bad conditions? -> error if applicable, exit - if(c_tree.root->op == 0 || l_tree.root->op == 0 || r_tree.root->op == 0) - { - break; - } - else if(!e_type_kind_is_integer(c_type_kind) && c_type_kind != E_TypeKind_Bool) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Conditional term must be an integer or boolean type."); - } - else if(!e_type_match(l_type, r_type)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left and right terms must have matching types."); - } - - // rjf: generate - { - E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); - E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); - E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); - l_value_tree = e_irtree_convert_hi(arena, l_value_tree, result_type, l_type); - r_value_tree = e_irtree_convert_hi(arena, r_value_tree, result_type, r_type); - E_IRNode *new_tree = e_irtree_conditional(arena, c_value_tree, l_value_tree, r_value_tree); - result.root = new_tree; - result.type_key = result_type; - result.mode = E_Mode_Value; - } - }break; - - //- rjf: call - case E_ExprKind_Call: - { - E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - - // rjf: calling a lens? -> generate IR for the first argument; wrap the type in - // a lens type, which preserves the name & arguments of the lens call expression - if(lhs_type->kind == E_TypeKind_LensSpec) - { - Temp scratch = scratch_begin(&arena, 1); - - // rjf: generate result via first argument to lens - result = e_irtree_and_type_from_expr(arena, lhs->next); - - // rjf: count extra arguments - U64 arg_count = 0; - for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next) - { - arg_count += 1; - } - - // rjf: flatten extra arguments - E_Expr **args = push_array(scratch.arena, E_Expr *, arg_count); - { - U64 idx = 0; - for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next, idx += 1) - { - args[idx] = arg; - } - } - - // rjf: patch resultant type with a lens w/ args, pointing to the original type - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .count = arg_count, .args = args, .direct_key = result.type_key, .name = lhs_type->name); - - scratch_end(scratch); - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); - } - }break; - - //- rjf: leaf bytecode - case E_ExprKind_LeafBytecode: - { - E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode); - new_tree->space = expr->space; - E_TypeKey final_type_key = expr->type_key; - result.root = new_tree; - result.type_key = final_type_key; - result.mode = expr->mode; - }break; - - //- rjf: leaf string literal - case E_ExprKind_LeafStringLiteral: - { - String8 string = expr->string; - E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size, 0); - E_IRNode *new_tree = e_irtree_string_literal(arena, string); - result.root = new_tree; - result.type_key = type_key; - result.mode = E_Mode_Value; - }break; - - //- rjf: leaf U64s - case E_ExprKind_LeafU64: - { - U64 val = expr->value.u64; - E_IRNode *new_tree = e_irtree_const_u(arena, val); - E_TypeKey type_key = zero_struct; - if(0){} - else if(val <= max_S32){type_key = e_type_key_basic(E_TypeKind_S32);} - else if(val <= max_S64){type_key = e_type_key_basic(E_TypeKind_S64);} - else {type_key = e_type_key_basic(E_TypeKind_U64);} - result.root = new_tree; - result.type_key = type_key; - result.mode = E_Mode_Value; - }break; - - //- rjf: leaf F64s - case E_ExprKind_LeafF64: - { - U64 val = expr->value.u64; - E_IRNode *new_tree = e_irtree_const_u(arena, val); - result.root = new_tree; - result.type_key = e_type_key_basic(E_TypeKind_F64); - result.mode = E_Mode_Value; - }break; - - //- rjf: leaf F32s - case E_ExprKind_LeafF32: - { - U32 val = expr->value.u32; - E_IRNode *new_tree = e_irtree_const_u(arena, val); - result.root = new_tree; - result.type_key = e_type_key_basic(E_TypeKind_F32); - result.mode = E_Mode_Value; - }break; - - //- rjf: leaf identifiers - case E_ExprKind_LeafIdentifier: - { - Temp scratch = scratch_begin(&arena, 1); - String8 qualifier = expr->qualifier; - String8 string = expr->string; - String8 string__redirected = string; - B32 string_mapped = 0; - E_TypeKey mapped_type_key = zero_struct; - E_Module *mapped_location_block_module = &e_module_nil; - RDI_LocationBlock *mapped_location_block = 0; - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_strings = {0}; - { - E_Module *module = e_ir_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); - str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try to map name as member - if found, string__redirected := "this", and turn - // on later implicit-member-lookup generation - B32 string_is_implicit_member_name = 0; - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) - { - E_Module *module = e_ir_state->ctx->primary_module; - U32 module_idx = (U32)(module - e_ir_state->ctx->modules); - RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; - RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); - E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); - E_Member member = e_type_member_from_key_name__cached(container_type_key, string); - if(member.kind != E_MemberKind_Null) - { - string_is_implicit_member_name = 1; - string__redirected = str8_lit("this"); - } - } - - //- rjf: try locals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) - { - E_Module *module = e_ir_state->ctx->primary_module; - U32 module_idx = (U32)(module - e_ir_state->ctx->modules); - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); - if(local_num != 0) - { - RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); - - // rjf: extract local's type key - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); - - // rjf: extract local's location block - U64 ip_voff = e_ir_state->ctx->thread_ip_voff; - for(U32 loc_block_idx = local->location_first; - loc_block_idx < local->location_opl; - loc_block_idx += 1) - { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) - { - mapped_location_block_module = module; - mapped_location_block = block; - } - } - } - } - - //- rjf: mapped to location block -> extract or produce bytecode for this mapping - E_Mode mapped_bytecode_mode = E_Mode_Offset; - E_Space mapped_bytecode_space = zero_struct; - String8 mapped_bytecode = {0}; - if(mapped_location_block != 0) - { - E_Module *module = mapped_location_block_module; - E_Space space = module->space; - Arch arch = module->arch; - RDI_Parsed *rdi = module->rdi; - RDI_LocationBlock *block = mapped_location_block; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) - { - RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) - { - default:{}break; - case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; - bytecode_stream:; - { - string_mapped = 1; - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) - { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) - { - break; - } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - mapped_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) - { - string_mapped = 1; - RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = space; - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - string_mapped = 1; - RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = space; - }break; - case RDI_LocationKind_ValReg: - if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) - { - string_mapped = 1; - RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); - - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - mapped_bytecode_space = space; - }break; - } - } - } - - //- rjf: try globals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) - { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = module->space; - break; - } - } - } - - //- rjf: try thread-locals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) - { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = module->space; - break; - } - } - } - - //- rjf: try procedures - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) - { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - mapped_bytecode_space = module->space; - break; - } - } - } - - //- rjf: try types - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) - { - mapped_type_key = e_leaf_type_from_name(string); - if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) - { - string_mapped = 1; - } - } - - //- rjf: try registers - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) - { - U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); - if(reg_num != 0) - { - string_mapped = 1; - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_num]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; - mapped_type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_num); - } - } - - //- rjf: try register aliases - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) - { - U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); - if(alias_num != 0) - { - string_mapped = 1; - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_num]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_slice.code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; - mapped_type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_num); - } - } - - //- rjf: try basic constants - if(!string_mapped && str8_match(string, str8_lit("true"), 0)) - { - string_mapped = 1; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, 1); - mapped_type_key = e_type_key_basic(E_TypeKind_Bool); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - } - if(!string_mapped && str8_match(string, str8_lit("false"), 0)) - { - string_mapped = 1; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, 0); - mapped_type_key = e_type_key_basic(E_TypeKind_Bool); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - } - - //- rjf: generate IR trees for bytecode - B32 generated = 0; - if(!generated && mapped_bytecode.size != 0) - { - generated = 1; - E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); - root->space = mapped_bytecode_space; - result.root = root; - result.type_key = mapped_type_key; - result.mode = mapped_bytecode_mode; - } - - //- rjf: generate nil-IR trees w/ type for types - if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) - { - generated = 1; - result.type_key = mapped_type_key; - result.mode = E_Mode_Null; - } - - //- rjf: generate IR trees for macros - if(!generated) - { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); - if(macro_expr != &e_expr_nil) - { - generated = 1; - e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); - result = e_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); - } - } - - //- rjf: extend generation with member access, if original string was an - // implicit member access - if(generated && string_is_implicit_member_name) - { - // TODO(rjf): @cfg -#if 0 - E_LookupRule *lookup_rule = &e_lookup_rule__default; - E_LookupInfo lookup_info = lookup_rule->info(arena, &result, &e_expr_nil, str8_zero()); - E_LookupAccess lookup_access = lookup_rule->access(arena, E_ExprKind_MemberAccess, lhs, rhs, &e_expr_nil, lookup_info.user_data); - result = lookup_access.irtree_and_type; -#endif - } - - //- rjf: error on failure-to-generate - if(!generated) - { - e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); - } - - scratch_end(scratch); - }break; - - //- rjf: leaf offsets - case E_ExprKind_LeafOffset: - { - E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); - new_tree->value = expr->value; - new_tree->space = expr->space; - result.root = new_tree; - result.type_key = expr->type_key; - result.mode = E_Mode_Offset; - }break; - - //- rjf: leaf values - case E_ExprKind_LeafValue: - { - E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU128); - new_tree->value = expr->value; - new_tree->space = expr->space; - result.root = new_tree; - result.type_key = expr->type_key; - result.mode = E_Mode_Value; - }break; - - //- rjf: leaf file paths - case E_ExprKind_LeafFilePath: - { - Temp scratch = scratch_begin(&arena, 1); - String8 file_path = expr->string; - FileProperties props = os_properties_from_file_path(file_path); - if(!str8_match(expr->qualifier, str8_lit("folder"), 0) && !(props.flags & FilePropertyFlag_IsFolder) && file_path.size != 0) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); - result.mode = E_Mode_Value; - } - else - { - String8 folder_path = str8_chop_last_slash(file_path); - props = os_properties_from_file_path(folder_path); - if(props.flags & FilePropertyFlag_IsFolder || folder_path.size == 0 || str8_match(folder_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - E_Space space = e_space_make(E_SpaceKind_FileSystem); - result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); - result.mode = E_Mode_Value; - } - } - scratch_end(scratch); - }break; - - //- rjf: types - case E_ExprKind_TypeIdent: - { - result.root = e_irtree_const_u(arena, 0); - result.root->space = expr->space; - result.type_key = expr->type_key; - result.mode = E_Mode_Null; - }break; - - //- rjf: (unexpected) type expressions - case E_ExprKind_Ptr: - case E_ExprKind_Array: - case E_ExprKind_Func: - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Type expression not expected."); - }break; - - //- rjf: definitions - case E_ExprKind_Define: - { - E_Expr *lhs = expr->first; - E_Expr *rhs = lhs->next; - result = e_irtree_and_type_from_expr(arena, rhs); - if(lhs->kind != E_ExprKind_LeafIdentifier) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); - } - }break; - } - return result; -} - internal E_IRTreeAndType -e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) +e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); E_IRTreeAndType result = {&e_irnode_nil}; - if(expr->kind == E_ExprKind_Ref) - { - expr = expr->ref; - } + ////////////////////////////// //- rjf: apply all ir-generation steps + // typedef struct Task Task; struct Task { Task *next; E_Expr *expr; + E_Expr *parent_expr; + E_IRTreeAndType parent_irtree_and_type; }; - Task start_task = {0, expr}; + Task start_task = {0, root_expr, &e_expr_nil, {&e_irnode_nil}}; 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 - e_expr_poison(t->expr); + E_Expr *expr = t->expr; - // rjf: do this rule's generation - result = e_irgen_rule__default.irgen(arena, t->expr); + //- rjf: poison the expression we are about to use, so we don't recursively use it + e_expr_poison(expr); - // rjf: find any auto hooks according to this generation's type + //- rjf: do expr -> irtree generation for this expression + if(expr->kind == E_ExprKind_Ref) + { + expr = expr->ref; + } + E_ExprKind kind = expr->kind; + switch(kind) + { + default:{}break; + + //- rjf: accesses + case E_ExprKind_MemberAccess: + case E_ExprKind_ArrayIndex: + { + // rjf: unpack left-hand-size + E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: pick access hook based on type + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + E_TypeAccessFunctionType *lhs_access = lhs_type->access; + if(lhs_access == 0) + { + lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); + } + + // rjf: call into hook to do access + result = lhs_access(arena, expr, &lhs_irtree); + }break; + + //- rjf: dereference + case E_ExprKind_Deref: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + E_TypeKey r_type_direct = e_type_direct_from_key(r_type); + U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(r_type_direct_size == 0 && + (r_type_kind == E_TypeKind_Ptr || + r_type_kind == E_TypeKind_LRef || + r_type_kind == E_TypeKind_RRef)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference pointers of zero-sized types."); + break; + } + else if(r_type_direct_size == 0 && r_type_kind == E_TypeKind_Array) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference arrays of zero-sized types."); + break; + } + else if(r_type_kind != E_TypeKind_Array && + r_type_kind != E_TypeKind_Ptr && + r_type_kind != E_TypeKind_LRef && + r_type_kind != E_TypeKind_RRef) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference this type."); + break; + } + + // rjf: generate + { + E_IRNode *new_tree = r_tree.root; + if(r_tree.mode != E_Mode_Value && + (r_type_kind == E_TypeKind_Ptr || + r_type_kind == E_TypeKind_LRef || + r_type_kind == E_TypeKind_RRef)) + { + new_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + } + result.root = new_tree; + result.type_key = r_type_direct; + result.mode = E_Mode_Offset; + } + }break; + + //- rjf: address-of + case E_ExprKind_Address: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = r_tree.type_key; + E_TypeKey r_type_unwrapped = e_type_unwrap(r_type); + E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(e_type_key_match(e_type_key_zero(), r_type_unwrapped)) + { + break; + } + + // rjf: generate + result.root = r_tree.root; + result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 1, 0); + result.mode = E_Mode_Value; + }break; + + //- rjf: cast + case E_ExprKind_Cast: + { + // rjf: unpack operands + E_Expr *cast_type_expr = expr->first; + E_Expr *casted_expr = cast_type_expr->next; + E_TypeKey cast_type = e_type_from_expr(cast_type_expr); + E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); + U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); + E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); + e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); + E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key); + E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); + U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); + U8 in_group = e_type_group_from_kind(casted_type_kind); + U8 out_group = e_type_group_from_kind(cast_type_kind); + RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); + + // rjf: bad conditions? -> error if applicable, exit + if(casted_tree.root->op == 0) + { + break; + } + else if(cast_type_kind == E_TypeKind_Null) + { + break; + } + else if(conversion_rule != RDI_EvalConversionKind_Noop && + conversion_rule != RDI_EvalConversionKind_Legal) + { + String8 text = str8_lit("Unknown cast conversion rule."); + if(conversion_rule < RDI_EvalConversionKind_COUNT) + { + text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); + } + e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); + break; + } + + // rjf: generate + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); + E_IRNode *new_tree = in_tree; + if(conversion_rule == RDI_EvalConversionKind_Legal) + { + new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group); + } + if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind)) + { + new_tree = e_irtree_trunc(arena, in_tree, cast_type); + } + result.root = new_tree; + result.type_key = cast_type; + result.mode = E_Mode_Value; + } + }break; + + //- rjf: sizeof + case E_ExprKind_Sizeof: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_TypeKey r_type = zero_struct; + E_Space space = r_expr->space; + switch(r_expr->kind) + { + case E_ExprKind_TypeIdent: + case E_ExprKind_Ptr: + case E_ExprKind_Array: + case E_ExprKind_Func: + { + r_type = e_type_from_expr(r_expr); + }break; + default: + { + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + r_type = r_tree.type_key; + }break; + } + + // rjf: bad conditions? -> error if applicable, exit + if(e_type_key_match(r_type, e_type_key_zero())) + { + break; + } + else if(e_type_kind_from_key(r_type) == E_TypeKind_Null) + { + break; + } + + // rjf: generate + { + U64 r_type_byte_size = e_type_byte_size_from_key(r_type); + result.root = e_irtree_const_u(arena, r_type_byte_size); + result.type_key = e_type_key_basic(E_TypeKind_U64); + result.mode = E_Mode_Value; + } + }break; + + //- rjf: typeof + case E_ExprKind_Typeof: + { + // rjf: evaluate operand tree + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: fill output + result.root = e_irtree_const_u(arena, 0); + result.type_key = r_tree.type_key; + result.mode = E_Mode_Null; + }break; + + //- rjf: byteswap + case E_ExprKind_ByteSwap: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + U64 r_type_size = e_type_byte_size_from_key(r_type); + + // rjf: bad conditions? -> error if applicable, exit + if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Byteswapping this type is not supported."); + break; + } + + // rjf: generate + { + E_IRNode *node = e_push_irnode(arena, RDI_EvalOp_ByteSwap); + E_IRNode *rhs = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + e_irnode_push_child(node, rhs); + node->value.u64 = r_type_size; + result.root = node; + result.mode = E_Mode_Value; + result.type_key = r_type; + } + }break; + + //- rjf: unary operations + case E_ExprKind_Pos: + { + result = e_irtree_and_type_from_expr(arena, expr->first); + }break; + case E_ExprKind_Neg: + case E_ExprKind_BitNot: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); + E_TypeKey r_type_promoted = e_type_promote(r_type); + RDI_EvalOp op = e_opcode_from_expr_kind(kind); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + break; + } + + // rjf: generate + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); + E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); + result.root = new_tree; + result.type_key = r_type_promoted; + result.mode = E_Mode_Value; + } + }break; + case E_ExprKind_LogNot: + { + // rjf: unpack operand + E_Expr *r_expr = expr->first; + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); + E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); + RDI_EvalOp op = e_opcode_from_expr_kind(kind); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r_tree.root->op == 0) + { + break; + } + else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + break; + } + + // rjf: generate + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + in_tree = e_irtree_convert_hi(arena, in_tree, r_type_promoted, r_type); + E_IRNode *new_tree = e_irtree_unary_op(arena, op, r_type_group, in_tree); + result.root = new_tree; + result.type_key = r_type_promoted; + result.mode = E_Mode_Value; + } + }break; + + //- rjf: binary operations + case E_ExprKind_Mul: + case E_ExprKind_Div: + case E_ExprKind_Mod: + case E_ExprKind_Add: + case E_ExprKind_Sub: + case E_ExprKind_LShift: + case E_ExprKind_RShift: + case E_ExprKind_Less: + case E_ExprKind_LsEq: + case E_ExprKind_Grtr: + case E_ExprKind_GrEq: + case E_ExprKind_EqEq: + case E_ExprKind_NtEq: + case E_ExprKind_BitAnd: + case E_ExprKind_BitXor: + case E_ExprKind_BitOr: + case E_ExprKind_LogAnd: + case E_ExprKind_LogOr: + { + // rjf: unpack operands + RDI_EvalOp op = e_opcode_from_expr_kind(kind); + B32 is_comparison = e_expr_kind_is_comparison(kind); + E_Expr *l_expr = expr->first; + E_Expr *r_expr = l_expr->next; + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key)); + E_TypeKey r_type = e_type_unwrap_enum(e_type_unwrap(r_tree.type_key)); + E_TypeKind l_type_kind = e_type_kind_from_key(l_type); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + if(l_type.kind == E_TypeKeyKind_Reg) + { + l_type_kind = E_TypeKind_U64; + l_type = e_type_key_basic(l_type_kind); + } + if(r_type.kind == E_TypeKeyKind_Reg) + { + r_type_kind = E_TypeKind_U64; + r_type = e_type_key_basic(r_type_kind); + } + B32 l_is_pointer = (l_type_kind == E_TypeKind_Ptr); + B32 l_is_decay = (l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Offset); + B32 l_is_pointer_like = (l_is_pointer || l_is_decay); + B32 r_is_pointer = (r_type_kind == E_TypeKind_Ptr); + B32 r_is_decay = (r_type_kind == E_TypeKind_Array && r_tree.mode == E_Mode_Offset); + B32 r_is_pointer_like = (r_is_pointer || r_is_decay); + RDI_EvalTypeGroup l_type_group = e_type_group_from_kind(l_type_kind); + RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); + + // rjf: bad conditions? -> error if applicable, exit + if(l_tree.root->op == 0 || r_tree.root->op == 0) + { + break; + } + + // rjf: determine arithmetic path +#define E_ArithPath_Normal 0 +#define E_ArithPath_PtrAdd 1 +#define E_ArithPath_PtrSub 2 +#define E_ArithPath_PtrArrayCompare 3 + B32 ptr_arithmetic_mul_rptr = 0; + U32 arith_path = E_ArithPath_Normal; + if(kind == E_ExprKind_Add) + { + if(l_is_pointer_like && e_type_kind_is_integer(r_type_kind)) + { + arith_path = E_ArithPath_PtrAdd; + } + if(l_is_pointer_like && e_type_kind_is_integer(l_type_kind)) + { + arith_path = E_ArithPath_PtrAdd; + ptr_arithmetic_mul_rptr = 1; + } + } + else if(kind == E_ExprKind_Sub) + { + if(l_is_pointer_like && e_type_kind_is_integer(r_type_kind)) + { + arith_path = E_ArithPath_PtrAdd; + } + if(l_is_pointer_like && r_is_pointer_like) + { + E_TypeKey l_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); + E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(r_type))); + U64 l_type_direct_byte_size = e_type_byte_size_from_key(l_type_direct); + U64 r_type_direct_byte_size = e_type_byte_size_from_key(r_type_direct); + if(l_type_direct_byte_size == r_type_direct_byte_size) + { + arith_path = E_ArithPath_PtrSub; + } + } + } + else if(kind == E_ExprKind_EqEq) + { + if(l_type_kind == E_TypeKind_Array && (r_type_kind == E_TypeKind_Ptr || r_is_decay)) + { + arith_path = E_ArithPath_PtrArrayCompare; + } + if(r_type_kind == E_TypeKind_Array && (l_type_kind == E_TypeKind_Ptr || l_is_decay)) + { + arith_path = E_ArithPath_PtrArrayCompare; + } + } + + // rjf: generate according to arithmetic path + switch(arith_path) + { + //- rjf: normal arithmetic + case E_ArithPath_Normal: + { + // rjf: bad conditions? -> error if applicable, exit + if(!rdi_eval_op_typegroup_are_compatible(op, l_type_group) || + !rdi_eval_op_typegroup_are_compatible(op, r_type_group)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + break; + } + + // rjf: generate + { + E_TypeKey final_type_key = is_comparison ? e_type_key_basic(E_TypeKind_Bool) : l_type; + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + l_value_tree = e_irtree_convert_hi(arena, l_value_tree, l_type, l_type); + r_value_tree = e_irtree_convert_hi(arena, r_value_tree, l_type, r_type); + E_IRNode *new_tree = e_irtree_binary_op(arena, op, l_type_group, l_value_tree, r_value_tree); + result.root = new_tree; + result.type_key = final_type_key; + result.mode = E_Mode_Value; + } + }break; + + //- rjf: pointer addition + case E_ArithPath_PtrAdd: + { + // rjf: map l/r to ptr/int + E_IRTreeAndType *ptr_tree = &l_tree; + E_IRTreeAndType *int_tree = &r_tree; + B32 ptr_is_decay = l_is_decay; + if(ptr_arithmetic_mul_rptr) + { + ptr_tree = &r_tree; + int_tree = &l_tree; + ptr_is_decay = r_is_decay; + } + + // rjf: unpack type + E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(ptr_tree->type_key))); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + + // rjf: generate + { + E_IRNode *ptr_root = ptr_tree->root; + if(!ptr_is_decay) + { + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_root, ptr_tree->type_key); + } + E_IRNode *int_root = int_tree->root; + int_root = e_irtree_resolve_to_value(arena, int_tree->mode, int_root, int_tree->type_key); + if(direct_type_size > 1) + { + E_IRNode *const_root = e_irtree_const_u(arena, direct_type_size); + int_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, int_root, const_root); + } + E_TypeKey ptr_type = ptr_tree->type_key; + if(ptr_is_decay) + { + ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 1, 0); + } + E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); + result.root = new_root; + result.type_key = ptr_type; + result.mode = E_Mode_Value; + } + }break; + + //- rjf: pointer subtraction + case E_ArithPath_PtrSub: + { + // rjf: unpack type + E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + + // rjf: generate + E_IRNode *l_root = l_tree.root; + E_IRNode *r_root = r_tree.root; + if(!l_is_decay) + { + l_root = e_irtree_resolve_to_value(arena, l_tree.mode, l_root, l_type); + } + if(!r_is_decay) + { + r_root = e_irtree_resolve_to_value(arena, r_tree.mode, r_root, r_type); + } + E_IRNode *op_tree = e_irtree_binary_op_u(arena, op, l_root, r_root); + E_IRNode *new_tree = op_tree; + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Div, new_tree, const_tree); + } + result.root = new_tree; + result.type_key = e_type_key_basic(E_TypeKind_U64); + result.mode = E_Mode_Value; + }break; + + //- rjf: pointer array comparison + case E_ArithPath_PtrArrayCompare: + { + // rjf: map l/r to pointer/array + B32 ptr_is_decay = l_is_decay; + E_IRTreeAndType *ptr_tree = &l_tree; + E_IRTreeAndType *arr_tree = &r_tree; + if(l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Value) + { + ptr_is_decay = r_is_decay; + ptr_tree = &r_tree; + arr_tree = &l_tree; + } + + // rjf: resolve pointer to value, sized same as array + E_IRNode *ptr_root = ptr_tree->root; + E_IRNode *arr_root = arr_tree->root; + if(!ptr_is_decay) + { + ptr_root = e_irtree_resolve_to_value(arena, ptr_tree->mode, ptr_tree->root, ptr_tree->type_key); + } + + // rjf: read from pointer into value, to compare with array + E_IRNode *mem_root = e_irtree_mem_read_type(arena, ptr_root, arr_tree->type_key); + + // rjf: generate + result.root = e_irtree_binary_op(arena, op, RDI_EvalTypeGroup_Other, mem_root, arr_root); + result.type_key = e_type_key_basic(E_TypeKind_Bool); + result.mode = E_Mode_Value; + }break; + } + }break; + + //- rjf: ternary operators + case E_ExprKind_Ternary: + { + // rjf: unpack operands + E_Expr *c_expr = expr->first; + E_Expr *l_expr = c_expr->next; + E_Expr *r_expr = l_expr->next; + E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr); + E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); + e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + E_TypeKey c_type = e_type_unwrap(c_tree.type_key); + E_TypeKey l_type = e_type_unwrap(l_tree.type_key); + E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKind c_type_kind = e_type_kind_from_key(c_type); + E_TypeKind l_type_kind = e_type_kind_from_key(l_type); + E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + E_TypeKey result_type = l_type; + + // rjf: bad conditions? -> error if applicable, exit + if(c_tree.root->op == 0 || l_tree.root->op == 0 || r_tree.root->op == 0) + { + break; + } + else if(!e_type_kind_is_integer(c_type_kind) && c_type_kind != E_TypeKind_Bool) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Conditional term must be an integer or boolean type."); + } + else if(!e_type_match(l_type, r_type)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left and right terms must have matching types."); + } + + // rjf: generate + { + E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); + E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); + E_IRNode *r_value_tree = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_type); + l_value_tree = e_irtree_convert_hi(arena, l_value_tree, result_type, l_type); + r_value_tree = e_irtree_convert_hi(arena, r_value_tree, result_type, r_type); + E_IRNode *new_tree = e_irtree_conditional(arena, c_value_tree, l_value_tree, r_value_tree); + result.root = new_tree; + result.type_key = result_type; + result.mode = E_Mode_Value; + } + }break; + + //- rjf: call + case E_ExprKind_Call: + { + E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + + // rjf: calling a lens? -> generate IR for the first argument; wrap the type in + // a lens type, which preserves the name & arguments of the lens call expression + if(lhs_type->kind == E_TypeKind_LensSpec) + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: generate result via first argument to lens + result = e_irtree_and_type_from_expr(arena, lhs->next); + + // rjf: count extra arguments + U64 arg_count = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next) + { + arg_count += 1; + } + + // rjf: flatten extra arguments + E_Expr **args = push_array(scratch.arena, E_Expr *, arg_count); + { + U64 idx = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next, idx += 1) + { + args[idx] = arg; + } + } + + // rjf: patch resultant type with a lens w/ args, pointing to the original type + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .count = arg_count, .args = args, .direct_key = result.type_key, .name = lhs_type->name); + + scratch_end(scratch); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); + } + }break; + + //- rjf: leaf bytecode + case E_ExprKind_LeafBytecode: + { + E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode); + new_tree->space = expr->space; + E_TypeKey final_type_key = expr->type_key; + result.root = new_tree; + result.type_key = final_type_key; + result.mode = expr->mode; + }break; + + //- rjf: leaf string literal + case E_ExprKind_LeafStringLiteral: + { + String8 string = expr->string; + E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size, 0); + E_IRNode *new_tree = e_irtree_string_literal(arena, string); + result.root = new_tree; + result.type_key = type_key; + result.mode = E_Mode_Value; + }break; + + //- rjf: leaf U64s + case E_ExprKind_LeafU64: + { + U64 val = expr->value.u64; + E_IRNode *new_tree = e_irtree_const_u(arena, val); + E_TypeKey type_key = zero_struct; + if(0){} + else if(val <= max_S32){type_key = e_type_key_basic(E_TypeKind_S32);} + else if(val <= max_S64){type_key = e_type_key_basic(E_TypeKind_S64);} + else {type_key = e_type_key_basic(E_TypeKind_U64);} + result.root = new_tree; + result.type_key = type_key; + result.mode = E_Mode_Value; + }break; + + //- rjf: leaf F64s + case E_ExprKind_LeafF64: + { + U64 val = expr->value.u64; + E_IRNode *new_tree = e_irtree_const_u(arena, val); + result.root = new_tree; + result.type_key = e_type_key_basic(E_TypeKind_F64); + result.mode = E_Mode_Value; + }break; + + //- rjf: leaf F32s + case E_ExprKind_LeafF32: + { + U32 val = expr->value.u32; + E_IRNode *new_tree = e_irtree_const_u(arena, val); + result.root = new_tree; + result.type_key = e_type_key_basic(E_TypeKind_F32); + result.mode = E_Mode_Value; + }break; + + //- rjf: leaf identifiers + case E_ExprKind_LeafIdentifier: + { + Temp scratch = scratch_begin(&arena, 1); + String8 qualifier = expr->qualifier; + String8 string = expr->string; + String8 string__redirected = string; + B32 string_mapped = 0; + E_TypeKey mapped_type_key = zero_struct; + E_Module *mapped_location_block_module = &e_module_nil; + RDI_LocationBlock *mapped_location_block = 0; + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_strings = {0}; + { + E_Module *module = e_ir_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); + str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try to map name as member - if found, string__redirected := "this", and turn + // on later implicit-member-lookup generation + B32 string_is_implicit_member_name = 0; + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) + { + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); + E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); + E_Member member = e_type_member_from_key_name__cached(container_type_key, string); + if(member.kind != E_MemberKind_Null) + { + string_is_implicit_member_name = 1; + string__redirected = str8_lit("this"); + } + } + + //- rjf: try locals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) + { + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); + if(local_num != 0) + { + RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); + + // rjf: extract local's type key + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); + + // rjf: extract local's location block + U64 ip_voff = e_ir_state->ctx->thread_ip_voff; + for(U32 loc_block_idx = local->location_first; + loc_block_idx < local->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) + { + mapped_location_block_module = module; + mapped_location_block = block; + } + } + } + } + + //- rjf: mapped to location block -> extract or produce bytecode for this mapping + E_Mode mapped_bytecode_mode = E_Mode_Offset; + E_Space mapped_bytecode_space = zero_struct; + String8 mapped_bytecode = {0}; + if(mapped_location_block != 0) + { + E_Module *module = mapped_location_block_module; + E_Space space = module->space; + Arch arch = module->arch; + RDI_Parsed *rdi = module->rdi; + RDI_LocationBlock *block = mapped_location_block; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{}break; + case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; + bytecode_stream:; + { + string_mapped = 1; + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + mapped_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_ValReg: + if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); + + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = space; + }break; + } + } + } + + //- rjf: try globals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try thread-locals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try procedures + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) + { + for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_ir_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try types + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) + { + mapped_type_key = e_leaf_type_from_name(string); + if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) + { + string_mapped = 1; + } + } + + //- rjf: try registers + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + if(reg_num != 0) + { + string_mapped = 1; + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_num]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; + mapped_type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_num); + } + } + + //- rjf: try register aliases + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + if(alias_num != 0) + { + string_mapped = 1; + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_num]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; + mapped_type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_num); + } + } + + //- rjf: try basic constants + if(!string_mapped && str8_match(string, str8_lit("true"), 0)) + { + string_mapped = 1; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, 1); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + } + if(!string_mapped && str8_match(string, str8_lit("false"), 0)) + { + string_mapped = 1; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, 0); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + } + + //- rjf: generate IR trees for bytecode + B32 generated = 0; + if(!generated && mapped_bytecode.size != 0) + { + generated = 1; + E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); + root->space = mapped_bytecode_space; + result.root = root; + result.type_key = mapped_type_key; + result.mode = mapped_bytecode_mode; + } + + //- rjf: generate nil-IR trees w/ type for types + if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) + { + generated = 1; + result.type_key = mapped_type_key; + result.mode = E_Mode_Null; + } + + //- rjf: generate IR trees for macros + if(!generated) + { + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); + if(macro_expr != &e_expr_nil) + { + generated = 1; + e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); + result = e_irtree_and_type_from_expr(arena, macro_expr); + e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); + } + } + + //- rjf: extend generation with member access, if original string was an + // implicit member access + if(generated && string_is_implicit_member_name) + { + // TODO(rjf): @cfg +#if 0 + E_LookupRule *lookup_rule = &e_lookup_rule__default; + E_LookupInfo lookup_info = lookup_rule->info(arena, &result, &e_expr_nil, str8_zero()); + E_LookupAccess lookup_access = lookup_rule->access(arena, E_ExprKind_MemberAccess, lhs, rhs, &e_expr_nil, lookup_info.user_data); + result = lookup_access.irtree_and_type; +#endif + } + + //- rjf: error on failure-to-generate + if(!generated) + { + e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); + } + + scratch_end(scratch); + }break; + + //- rjf: leaf offsets + case E_ExprKind_LeafOffset: + { + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64); + new_tree->value = expr->value; + new_tree->space = expr->space; + result.root = new_tree; + result.type_key = expr->type_key; + result.mode = E_Mode_Offset; + }break; + + //- rjf: leaf values + case E_ExprKind_LeafValue: + { + E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU128); + new_tree->value = expr->value; + new_tree->space = expr->space; + result.root = new_tree; + result.type_key = expr->type_key; + result.mode = E_Mode_Value; + }break; + + //- rjf: leaf file paths + case E_ExprKind_LeafFilePath: + { + Temp scratch = scratch_begin(&arena, 1); + String8 file_path = expr->string; + FileProperties props = os_properties_from_file_path(file_path); + if(!str8_match(expr->qualifier, str8_lit("folder"), 0) && !(props.flags & FilePropertyFlag_IsFolder) && file_path.size != 0) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.mode = E_Mode_Value; + } + else + { + String8 folder_path = str8_chop_last_slash(file_path); + props = os_properties_from_file_path(folder_path); + if(props.flags & FilePropertyFlag_IsFolder || folder_path.size == 0 || str8_match(folder_path, str8_lit("/"), StringMatchFlag_SlashInsensitive)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.mode = E_Mode_Value; + } + } + scratch_end(scratch); + }break; + + //- rjf: types + case E_ExprKind_TypeIdent: + { + result.root = e_irtree_const_u(arena, 0); + result.root->space = expr->space; + result.type_key = expr->type_key; + result.mode = E_Mode_Null; + }break; + + //- rjf: (unexpected) type expressions + case E_ExprKind_Ptr: + case E_ExprKind_Array: + case E_ExprKind_Func: + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Type expression not expected."); + }break; + + //- rjf: definitions + case E_ExprKind_Define: + { + E_Expr *lhs = expr->first; + E_Expr *rhs = lhs->next; + result = e_irtree_and_type_from_expr(arena, rhs); + if(lhs->kind != E_ExprKind_LeafIdentifier) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); + } + }break; + } + + //- rjf: if the evaluated type has a hook for an extra layer of ir generation, + // call into it + E_Type *type = e_type_from_key__cached(result.type_key); + if(type->irgen != 0) + { + result = type->irgen(arena, &result); + } + + //- rjf: find any auto hooks according to this generation's type { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -3301,6 +2894,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; + task->parent_expr = expr; + task->parent_irtree_and_type = result; break; } } @@ -3308,7 +2903,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } } + ////////////////////////////// //- rjf: unpoison the tags we used + // for(Task *t = first_task; t != 0; t = t->next) { e_expr_unpoison(t->expr); @@ -3588,6 +3185,7 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +#if 0 // TODO(rjf): @eval internal E_LookupRule * e_lookup_rule_from_type_key(E_TypeKey type_key) { @@ -3608,6 +3206,7 @@ e_lookup_rule_from_type_key(E_TypeKey type_key) return rule; } +#endif #if 0 // TODO(rjf): @eval internal E_LookupRuleExprPair diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index bb197c22..871527e2 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -134,8 +134,10 @@ struct E_IRCtx E_String2ExprMap *macro_map; // rjf: hook maps +#if 0 // TODO(rjf): @eval E_LookupRuleMap *lookup_rule_map; E_IRGenRuleMap *irgen_rule_map; +#endif E_AutoHookMap *auto_hook_map; }; @@ -164,6 +166,7 @@ struct E_IRState //////////////////////////////// //~ rjf: Globals +#if 0 // TODO(rjf): @eval local_persist read_only E_LookupRule e_lookup_rule__nil = { str8_lit_comp("nil"), @@ -187,6 +190,8 @@ local_persist read_only E_IRGenRule e_irgen_rule__default = str8_lit_comp("default"), E_IRGEN_FUNCTION_NAME(default), }; +#endif + global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRState *e_ir_state = 0; @@ -204,20 +209,24 @@ internal void e_select_ir_ctx(E_IRCtx *ctx); //////////////////////////////// //~ rjf: Lookups +#if 0 // TODO(rjf): @eval internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); #define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__}) internal E_LookupRule *e_lookup_rule_from_string(String8 string); +#endif //////////////////////////////// //~ rjf: IR Gen Rules +#if 0 // TODO(rjf): @eval internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count); internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule); #define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__}) internal E_IRGenRule *e_irgen_rule_from_string(String8 string); +#endif //////////////////////////////// //~ rjf: Auto Hooks @@ -288,7 +297,9 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r //////////////////////////////// //~ rjf: Expression & IR-Tree => Rules +#if 0 // TODO(rjf): @eval internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key); +#endif #if 0 // TODO(rjf): @eval internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ee2944e9..69d66116 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -396,6 +396,11 @@ e_type_key_cons_(E_ConsTypeParams *params) node->key = key; MemoryCopyStruct(&node->params, params); node->params.name = push_str8_copy(e_type_state->arena, params->name); + if(node->params.expand.info != 0) + { + if(node->params.expand.id_from_num == 0) {node->params.expand.id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity);} + if(node->params.expand.num_from_id == 0) {node->params.expand.num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity);} + } if(params->members != 0) { node->params.members = push_array(e_type_state->arena, E_Member, params->count); @@ -632,11 +637,9 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->count = node->params.count; type->depth = node->params.depth; type->arch = node->params.arch; + type->irgen = node->params.irgen; type->access = node->params.access; - type->expand_info = node->params.expand_info; - type->expand_range = node->params.expand_range; - type->expand_id_from_num = node->params.expand_id_from_num; - type->expand_num_from_id = node->params.expand_num_from_id; + type->expand = node->params.expand; type->byte_size = node->byte_size; switch(type->kind) { @@ -2067,3 +2070,447 @@ e_type_member_from_key_name__cached(E_TypeKey key, String8 name) } return result; } + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) Default Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) +{ + E_TypeExpandInfo result = {0}; + { + E_TypeKey type_key = e_type_unwrap(irtree->type_key); + E_TypeKind type_kind = e_type_kind_from_key(type_key); + if(e_type_kind_is_pointer_or_ref(type_kind)) + { + E_Type *type = e_type_from_key__cached(type_key); + result.expr_count = type->count; + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); + result.expr_count = data_members.count; + } + else if(direct_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(direct_type_key); + result.expr_count = direct_type->count; + } + } + } + else if(type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Union) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(type_key, filter); + result.expr_count = data_members.count; + } + else if(type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key__cached(type_key); + result.expr_count = direct_type->count; + } + else if(type_kind == E_TypeKind_Array) + { + E_Type *type = e_type_from_key__cached(type_key); + result.expr_count = type->count; + } + } + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) +{ + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: unpack type of expression + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, expr); + E_TypeKey lhs_type_key = lhs_irtree.type_key; + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + + //- rjf: pull out specific kinds of types + B32 do_struct_range = 0; + B32 do_enum_range = 0; + B32 do_index_range = 0; + E_TypeKey enum_type_key = zero_struct; + E_TypeKey struct_type_key = zero_struct; + E_TypeKind struct_type_kind = E_TypeKind_Null; + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(lhs_type->count == 1 && + (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class)) + { + struct_type_key = direct_type_key; + struct_type_kind = direct_type_kind; + do_struct_range = 1; + } + else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) + { + do_enum_range = 1; + enum_type_key = direct_type_key; + } + else + { + do_index_range = 1; + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Class) + { + struct_type_key = lhs_type_key; + struct_type_kind = lhs_type_kind; + do_struct_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Enum) + { + enum_type_key = lhs_type_key; + do_enum_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Set) + { + do_index_range = 1; + } + else if(lhs_type_kind == E_TypeKind_Array) + { + do_index_range = 1; + } + + //- rjf: struct case -> the lookup-range will return a range of members + if(do_struct_range) + { + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); + Rng1U64 legal_idx_range = r1u64(0, data_members.count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = data_members.v[member_idx].name; + exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + } + } + + //- rjf: enum case -> the lookup-range will return a range of enum constants + else if(do_enum_range) + { + E_Type *type = e_type_from_key__cached(enum_type_key); + Rng1U64 legal_idx_range = r1u64(0, type->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = type->enum_vals[member_idx].name; + exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + } + } + + //- rjf: ptr case -> the lookup-range will return a range of dereferences + else if(do_index_range) + { + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + exprs_out[idx] = e_expr_irext_array_index(arena, expr, &lhs_irtree, idx_range.min + idx); + } + } + } + scratch_end(scratch); +} + +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity) +{ + return num; +} + +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) +{ + return id; +} + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `folder` type + +typedef struct E_FolderAccel E_FolderAccel; +struct E_FolderAccel +{ + String8 folder_path; + String8Array folders; + String8Array files; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder) +{ + E_TypeExpandInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + String8 folder_path = e_string_from_id(lhs_string_id); + + //- rjf: compute filter - omit common prefixes (common parent paths) + String8 local_filter = filter; + { + U64 folder_pos_in_filter = str8_find_needle(filter, 0, folder_path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive); + if(folder_pos_in_filter < filter.size) + { + local_filter = str8_skip(local_filter, folder_pos_in_filter+folder_path.size); + local_filter = str8_skip_chop_slashes(local_filter); + } + else + { + MemoryZeroStruct(&local_filter); + } + } + + //- rjf: gather & filter files in this folder + String8List folder_paths = {0}; + String8List file_paths = {0}; + { + OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name); + if(matches.count == matches.needle_part_count) + { + if(info.props.flags & FilePropertyFlag_IsFolder) + { + str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name)); + } + else + { + str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name)); + } + } + } + os_file_iter_end(iter); + } + + //- rjf: build accelerator + E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1); + accel->folder_path = push_str8_copy(arena, folder_path); + accel->folders = str8_array_from_list(arena, &folder_paths); + accel->files = str8_array_from_list(arena, &file_paths); + info.user_data = accel; + info.expr_count = accel->folders.count + accel->files.count; + scratch_end(scratch); + } + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder) +{ + E_FolderAccel *accel = (E_FolderAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr = &e_expr_nil; + String8 expr_string = {0}; + if(0 <= idx && idx < accel->folders.count) + { + String8 folder_name = accel->folders.v[idx - 0]; + String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(folder_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); + } + else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) + { + String8 file_name = accel->files.v[idx - accel->folders.count]; + String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); + expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + expr->space = e_space_make(E_SpaceKind_FileSystem); + expr->value.u64 = e_id_from_string(file_path); + expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); + } + exprs_out[out_idx] = expr; + exprs_strings_out[out_idx] = expr_string; + scratch_end(scratch); + } +} + +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(folder) +{ + U64 id = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + String8 name = {0}; + if(0 < num && num <= accel->folders.count) + { + name = accel->folders.v[num-1]; + } + else if(accel->folders.count < num && num <= accel->folders.count+accel->files.count) + { + name = accel->files.v[num-accel->folders.count-1]; + } + id = e_hash_from_string(5381, name); + return id; +} + +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(folder) +{ + U64 num = 0; + E_FolderAccel *accel = (E_FolderAccel *)user_data; + for(U64 idx = 0; idx < accel->folders.count+accel->files.count; idx += 1) + { + String8 name = {0}; + if(0 <= idx && idx < accel->folders.count) + { + name = accel->folders.v[idx]; + } + else if(accel->folders.count <= idx && idx < accel->folders.count+accel->files.count) + { + name = accel->files.v[idx-accel->folders.count]; + } + U64 hash = e_hash_from_string(5381, name); + if(hash == id) + { + num = idx+1; + break; + } + } + return num; +} + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `file` type + +typedef struct E_FileAccel E_FileAccel; +struct E_FileAccel +{ + String8 file_path; + FileProperties props; + String8Array fields; +}; + +E_TYPE_IRGEN_FUNCTION_DEF(file) +{ + E_IRTreeAndType result = *irtree; + E_FileAccel *accel = push_array(arena, E_FileAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs file path ID + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + E_Value lhs_value = lhs_interp.value; + U64 lhs_string_id = lhs_value.u64; + + //- rjf: get file path + String8 file_path = e_string_from_id(lhs_string_id); + + //- rjf: build field list + String8List fields = {0}; + str8_list_pushf(arena, &fields, "size"); + str8_list_pushf(arena, &fields, "last_modified_time"); + str8_list_pushf(arena, &fields, "creation_time"); + str8_list_pushf(arena, &fields, "data"); + + //- rjf: fill accel + accel->file_path = push_str8_copy(arena, file_path); + accel->props = os_properties_from_file_path(file_path); + accel->fields = str8_array_from_list(arena, &fields); + + scratch_end(scratch); + } + result.user_data = accel; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(file) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + E_FileAccel *accel = (E_FileAccel *)lhs_irtree->user_data; + if(expr->kind == E_ExprKind_MemberAccess) + { + E_Expr *rhs = expr->first->next; + String8 member_name = rhs->string; + if(str8_match(member_name, str8_lit("size"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.size)); + result.type_key = e_type_key_basic(E_TypeKind_U64); + result.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("last_modified_time"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.modified)); + result.type_key = e_type_key_basic(E_TypeKind_U64); + result.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("creation_time"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_FileSystem); + space.u64_0 = e_id_from_string(accel->file_path); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.created)); + result.type_key = e_type_key_basic(E_TypeKind_U64); + result.mode = E_Mode_Value; + } + else if(str8_match(member_name, str8_lit("data"), 0)) + { + E_Space space = e_space_make(E_SpaceKind_File); + space.u64_0 = e_id_from_string(accel->file_path); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size, 0); + result.mode = E_Mode_Offset; + } + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(file) +{ + E_FileAccel *accel = push_array(arena, E_FileAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + + scratch_end(scratch); + } + E_TypeExpandInfo info = {accel, accel->fields.count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file) +{ + E_FileAccel *accel = (E_FileAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = &e_expr_nil; + String8 string = {0}; + if(0 <= idx && idx < accel->fields.count) + { + String8 name = accel->fields.v[idx]; + expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); + E_Expr *lhs = e_expr_ref(arena, expr); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); + rhs->string = push_str8_copy(arena, name); + e_expr_push_child(expr, lhs); + e_expr_push_child(expr, rhs); + } + exprs_out[out_idx] = expr; + exprs_strings_out[out_idx] = string; + } +} diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 9c94c2e8..d57d3e37 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -47,11 +47,9 @@ struct E_ConsTypeParams E_Member *members; E_EnumVal *enum_vals; E_Expr **args; + E_TypeIRGenFunctionType *irgen; E_TypeAccessFunctionType *access; - E_TypeExpandInfoFunctionType *expand_info; - E_TypeExpandRangeFunctionType *expand_range; - E_TypeExpandIDFromNumFunctionType *expand_id_from_num; - E_TypeExpandNumFromIDFunctionType *expand_num_from_id; + E_TypeExpandRule expand; }; typedef struct E_ConsTypeNode E_ConsTypeNode; @@ -180,6 +178,17 @@ struct E_TypeState global read_only E_Member e_member_nil = {E_MemberKind_Null}; global read_only E_Type e_type_nil = {E_TypeKind_Null}; +E_TYPE_EXPAND_INFO_FUNCTION_DEF(default); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +global read_only E_TypeExpandRule e_type_expand_rule__default = +{ + E_TYPE_EXPAND_INFO_FUNCTION_NAME(default), + E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default), + E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), + E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), +}; thread_static E_TypeState *e_type_state = 0; //////////////////////////////// diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 41c957ba..d94cd5cb 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -535,7 +535,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs) +ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *expr) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -545,7 +545,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai //- rjf: generate root expression EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); - E_Expr *root_expr = e_expr_copy(arena, exprs.last); + E_Expr *root_expr = e_expr_copy(arena, expr); #if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); #endif @@ -555,7 +555,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = root_key; tree.root->string = str8_zero(); - tree.root->expr = root_expr; + tree.root->eval = e_eval_from_expr(arena, root_expr); tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -566,12 +566,12 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai { Task *next; EV_Block *parent_block; - E_Expr *expr; + E_Eval eval; U64 child_id; U64 split_relative_idx; B32 default_expanded; }; - Task start_task = {0, tree.root, tree.root->expr, 1, 0}; + Task start_task = {0, tree.root, tree.root->eval, 1, 0}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -593,39 +593,41 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai continue; } - // rjf: unpack expr - E_IRTreeAndType expr_irtree = e_irtree_and_type_from_expr(scratch.arena, t->expr); + // rjf: unpack eval + E_Mode mode = t->eval.irtree.mode; + E_TypeKey type_key = t->eval.irtree.type_key; + E_Type *type = e_type_from_key__cached(type_key); + E_TypeExpandRule *type_expand_rule = &e_type_expand_rule__default; + if(type->expand.info != 0) + { + type_expand_rule = &type->expand; + } - // rjf: get expr's expansion rule + // rjf: get eval's visualization expansion rule // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ExpandRule *expand_rule = &ev_nil_expand_rule; - E_Expr *expand_rule_tag = &e_expr_nil; + EV_ExpandRule *viz_expand_rule = &ev_nil_expand_rule; + E_Expr *viz_expand_rule_tag = &e_expr_nil; // rjf: skip if no expansion rule, & type info disallows expansion - if(expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(expr_irtree.type_key, expr_irtree.mode)) + if(viz_expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(type_key, mode)) { continue; } - // rjf: get expr's lookup rule - // TODO(rjf): @eval E_LookupRuleExprPair lookup_rule_and_tag = &e_lookup_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - E_LookupRule *lookup_rule = e_lookup_rule_from_type_key(expr_irtree.type_key); - E_Expr *lookup_rule_tag = &e_expr_nil; - // rjf: get top-level lookup/expansion info - E_LookupInfo lookup_info = lookup_rule->info(arena, &expr_irtree, lookup_rule_tag, filter); - EV_ExpandInfo expand_info = expand_rule->info(arena, view, filter, t->expr, expand_rule_tag); + E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, &t->eval.irtree, filter); + EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr, viz_expand_rule_tag); // rjf: determine expansion info - U64 expansion_row_count = lookup_info.named_expr_count ? lookup_info.named_expr_count : lookup_info.idxed_expr_count; - if(expand_rule != &ev_nil_expand_rule) + U64 expansion_row_count = type_expand_info.expr_count; + if(viz_expand_rule != &ev_nil_expand_rule) { - expansion_row_count = expand_info.row_count; + expansion_row_count = viz_expand_info.row_count; } // rjf: determine if this expansion supports child expansions B32 allow_child_expansions = 1; - if(expand_info.single_item) + if(viz_expand_info.single_item) { // NOTE(rjf): for now, just plugging in the heuristic of "is this a single row (a.k.a. visualizer)?" allow_child_expansions = 0; @@ -641,25 +643,21 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai expansion_block->parent = t->parent_block; expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; - expansion_block->expr = t->expr; - expansion_block->lookup_tag = lookup_rule_tag; - expansion_block->expand_tag = expand_rule_tag; - expansion_block->lookup_rule = lookup_rule; - expansion_block->expand_rule = expand_rule; - expansion_block->lookup_rule_user_data = lookup_info.user_data; - expansion_block->expand_rule_user_data = expand_info.user_data; + expansion_block->eval = t->eval; + expansion_block->type_expand_info = type_expand_info; + expansion_block->type_expand_rule = type_expand_rule; + expansion_block->viz_expand_info = viz_expand_info; + expansion_block->viz_expand_rule = viz_expand_rule; expansion_block->row_count = expansion_row_count; - expansion_block->single_item = expand_info.single_item; - expansion_block->rows_default_expanded = expand_info.rows_default_expanded; tree.total_row_count += expansion_row_count; - tree.total_item_count += expand_info.single_item ? 1 : expansion_row_count; + tree.total_item_count += viz_expand_info.single_item ? 1 : expansion_row_count; } // rjf: gather children expansions from expansion state U64 child_count = 0; EV_Key *child_keys = 0; U64 *child_nums = 0; - if(allow_child_expansions && !child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) + if(allow_child_expansions && !child_count && !viz_expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) { // rjf: count children for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} @@ -673,7 +671,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, idx += 1) { child_keys[idx] = child->key; - child_nums[idx] = lookup_rule->num_from_id(child->key.child_id, lookup_info.user_data); + child_nums[idx] = type_expand_rule->num_from_id(type_expand_info.user_data, child->key.child_id); if(child_nums[idx] != child_keys[idx].child_id) { needs_sort = 1; @@ -706,14 +704,14 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai } // rjf: gather children expansions from inverse of expansion state - if(allow_child_expansions && !child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) + if(allow_child_expansions && !child_count && (viz_expand_info.rows_default_expanded || (expand_node == 0 && !viz_expand_info.rows_default_expanded))) { - child_count = expand_info.row_count; + child_count = viz_expand_info.row_count; child_keys = push_array(scratch.arena, EV_Key, child_count); child_nums = push_array(scratch.arena, U64, child_count); for(U64 idx = 0; idx < child_count; idx += 1) { - U64 child_id = lookup_rule->id_from_num(idx+1, lookup_info.user_data); + U64 child_id = type_expand_rule->id_from_num(type_expand_info.user_data, idx+1); child_keys[idx] = ev_key_make(ev_hash_from_key(key), child_id); child_nums[idx] = idx+1; } @@ -728,14 +726,15 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai { continue; } - if(expand_info.rows_default_expanded || ev_expansion_from_key(view, child_keys[idx])) + if(viz_expand_info.rows_default_expanded || ev_expansion_from_key(view, child_keys[idx])) { Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Expr *child_expr = &e_expr_nil; String8 child_string = {0}; - lookup_rule->range(arena, t->expr, lookup_rule_tag, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string, lookup_info.user_data); + type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); if(child_expr != &e_expr_nil) { + E_Eval child_eval = e_eval_from_expr(arena, child_expr); EV_Key child_key = child_keys[idx]; #if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); @@ -743,10 +742,10 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; - task->expr = child_expr; + task->eval = child_eval; task->child_id = child_key.child_id; task->split_relative_idx = split_relative_idx; - task->default_expanded = expand_info.rows_default_expanded; + task->default_expanded = viz_expand_info.rows_default_expanded; } } } @@ -771,6 +770,20 @@ ev_depth_from_block(EV_Block *block) //////////////////////////////// //~ rjf: Block Coordinate Spaces +internal U64 +ev_block_id_from_num(EV_Block *block, U64 num) +{ + U64 result = block->type_expand_rule->id_from_num(block->type_expand_info.user_data, num); + return result; +} + +internal U64 +ev_block_num_from_id(EV_Block *block, U64 id) +{ + U64 result = block->type_expand_rule->num_from_id(block->type_expand_info.user_data, id); + return result; +} + internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree) { @@ -870,7 +883,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) if(contains_1u64(global_range, num)) { U64 relative_num = (num - base_num) + n->v.range.min + 1; - U64 child_id = n->v.block->lookup_rule->id_from_num(relative_num, n->v.block->lookup_rule_user_data); + U64 child_id = ev_block_id_from_num(n->v.block, relative_num); EV_Key block_key = n->v.block->key; key = ev_key_make(ev_hash_from_key(block_key), child_id); break; @@ -890,7 +903,7 @@ ev_num_from_key(EV_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->lookup_rule->num_from_id(key.child_id, n->v.block->lookup_rule_user_data); + U64 relative_num = ev_block_num_from_id(n->v.block, key.child_id); Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->single_item ? (n->v.range.min+1) : n->v.range.max); if(contains_1u64(num_range, relative_num-1)) { @@ -1011,7 +1024,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 if(block_relative_range__windowed.max > block_relative_range__windowed.min) { // rjf: get info about expansion range - B32 is_root = 0; + B32 is_standalone_row = 0; U64 range_exprs_count = dim_1u64(block_relative_range__windowed); E_Expr **range_exprs = push_array(arena, E_Expr *, range_exprs_count); String8 *range_exprs_strings = push_array(arena, String8 ,range_exprs_count); @@ -1019,18 +1032,17 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - if(n->v.block->lookup_rule == &e_lookup_rule__nil || - n->v.block->single_item) + if(n->v.block->single_item) { - is_root = 1; + is_standalone_row = 1; } else { - n->v.block->lookup_rule->range(arena, n->v.block->expr, n->v.block->lookup_tag, filter, block_relative_range__windowed, range_exprs, range_exprs_strings, n->v.block->lookup_rule_user_data); + n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval.expr, filter, block_relative_range__windowed, range_exprs, range_exprs_strings); } // rjf: no expansion operator applied -> push row for block expression; pass through block info - if(is_root) + if(is_standalone_row) { EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); @@ -1042,16 +1054,17 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; row->string = n->v.block->string; - row->expr = n->v.block->expr; + row->eval = n->v.block->eval; } // rjf: expansion operator applied -> call, and add rows for all expressions in the viewable range else for EachIndex(idx, range_exprs_count) { U64 child_num = block_relative_range.min + num_skipped + idx + 1; - U64 child_id = n->v.block->lookup_rule->id_from_num(child_num, n->v.block->lookup_rule_user_data); + U64 child_id = ev_block_id_from_num(n->v.block, child_num); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; + E_Eval row_eval = e_eval_from_expr(arena, row_expr); #if 0 // TODO(rjf): @eval ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); #endif @@ -1063,7 +1076,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->key = row_key; row->visual_size = 1; row->string = range_exprs_strings[idx]; - row->expr = row_expr; + row->eval = row_eval; } } } @@ -1085,7 +1098,7 @@ ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList * { result = push_array(arena, EV_Row, 1); result->block = &ev_nil_block; - result->expr = &e_expr_nil; + result->eval = e_eval_nil; } return result; } @@ -1098,54 +1111,13 @@ ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRang return rows; } -internal String8 -ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags) -{ - String8 result = row->string; - E_Expr *notable_expr = row->expr; - for(B32 good = 0; !good;) - { - switch(notable_expr->kind) - { - default:{good = 1;}break; - case E_ExprKind_Address: - case E_ExprKind_Deref: - case E_ExprKind_Cast: - { - notable_expr = notable_expr->last; - }break; - case E_ExprKind_Ref: - { - notable_expr = notable_expr->ref; - }break; - } - } - if(result.size == 0) switch(notable_expr->kind) - { - default: - { - result = e_string_from_expr(arena, notable_expr); - }break; - case E_ExprKind_ArrayIndex: - { - result = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); - }break; - case E_ExprKind_MemberAccess: - { - result = push_str8f(arena, ".%S", e_string_from_expr(arena, notable_expr->last)); - }break; - } - return result; -} - internal B32 ev_row_is_expandable(EV_Row *row) { B32 result = 0; if(!ev_key_match(ev_key_root(), row->block->key)) { - Temp scratch = scratch_begin(0, 0); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); + E_IRTreeAndType irtree = row->eval.irtree; // rjf: determine if view rules force expandability if(!result) @@ -1162,10 +1134,8 @@ ev_row_is_expandable(EV_Row *row) // rjf: determine if type info force expandability if(!result) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); } - scratch_end(scratch); } return result; } @@ -1174,10 +1144,8 @@ internal B32 ev_row_is_editable(EV_Row *row) { B32 result = 0; - Temp scratch = scratch_begin(0, 0); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); + E_IRTreeAndType irtree = row->eval.irtree; result = ev_type_key_is_editable(irtree.type_key); - scratch_end(scratch); return result; } @@ -1826,7 +1794,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // rjf: single-length pointers -> just gen new task for deref'd expr if(ptr_data->type->count == 1) { - E_Expr *deref_expr = e_expr_irext_deref(arena, eval.exprs.first, &eval.irtree); + E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); need_new_task = 1; new_task.params = *params; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 214fe7a5..7f5115d0 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -146,15 +146,13 @@ struct EV_Block // rjf: split index, relative to parent's space U64 split_relative_idx; - // rjf: expression / visualization info - String8 string; - E_Expr *expr; - E_Expr *lookup_tag; - E_Expr *expand_tag; - E_LookupRule *lookup_rule; - EV_ExpandRule *expand_rule; - void *lookup_rule_user_data; - void *expand_rule_user_data; + // rjf: evaluation info + String8 string; + E_Eval eval; + E_TypeExpandInfo type_expand_info; + E_TypeExpandRule *type_expand_rule; + EV_ExpandInfo viz_expand_info; + EV_ExpandRule *viz_expand_rule; // rjf: expansion info U64 row_count; @@ -201,8 +199,8 @@ struct EV_Row EV_Block *block; EV_Key key; U64 visual_size; - String8 string; - E_Expr *expr; + String8 string; + E_Eval eval; }; typedef struct EV_WindowedRowNode EV_WindowedRowNode; @@ -282,7 +280,7 @@ global read_only EV_ExpandRule ev_nil_expand_rule = EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_lookup_rule__nil, &ev_nil_expand_rule}; +global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}}; //////////////////////////////// //~ rjf: Key Functions @@ -340,12 +338,14 @@ internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *blo //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChain exprs); +internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *expr); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// //~ rjf: Block Coordinate Spaces - + +internal U64 ev_block_id_from_num(EV_Block *block, U64 num); +internal U64 ev_block_num_from_id(EV_Block *block, U64 id); internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree); internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num); @@ -359,7 +359,6 @@ internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx); internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); -internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags); internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row); diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index a141fa53..e153ab4d 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -37,8 +37,8 @@ # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) # define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ # define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: " #__VA_ARGS__) -# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") #endif //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index af904043..ed46e37b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9,1275 +9,6 @@ #include "generated/raddbg.meta.c" -//////////////////////////////// -//~ rjf: Commands Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(commands) -{ - E_LookupInfo result = {0}; - if(filter.size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8List cmd_names = {0}; - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - String8 name = info->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &cmd_names, name); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &cmd_names); - result.user_data = accel; - result.idxed_expr_count = accel->count; - scratch_end(scratch); - } - else - { - result.idxed_expr_count = RD_CmdKind_COUNT; - } - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(commands) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_MemberAccess) - { - String8 cmd_name = rhs->string; - result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - result.irtree_and_type.mode = E_Mode_Value; - result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, e_id_from_string(cmd_name))); - } - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(commands) -{ - U64 out_idx = 0; - if(user_data != 0) - { - String8Array *accel = (String8Array *)user_data; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - String8 cmd_name = accel->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs[out_idx] = expr; - } - } - else - { - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - RD_CmdKind cmd_kind = (RD_CmdKind)idx; - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs[out_idx] = expr; - } - } -} - -//////////////////////////////// -//~ rjf: Watches Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(watches) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - RD_CfgList cfgs_list__filtered = cfgs_list; - if(filter.size != 0) - { - MemoryZeroStruct(&cfgs_list__filtered); - for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) - { - String8 expr = rd_expr_from_cfg(n->v); - B32 passes_filter = 1; - if(filter.size != 0) - { - E_Eval eval = e_eval_from_string(scratch.arena, expr); - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind != E_TypeKind_Set) - { - passes_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); - if(matches.count == matches.needle_part_count) - { - passes_filter = 1; - } - } - } - if(passes_filter) - { - rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); - } - } - } - RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); - cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); - result.user_data = cfgs; - result.idxed_expr_count = cfgs->count + 1; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(watches) -{ - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) - { - String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; - exprs_strings[idx] = push_str8_copy(arena, expr_string); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(watches) -{ - U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) - { - U64 idx = (num-1); - id = cfgs->v[idx]->id; - } - else if(num == cfgs->count+1) - { - id = max_U64; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(watches) -{ - U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(id != 0 && id != max_U64) - { - for EachIndex(idx, cfgs->count) - { - if(cfgs->v[idx]->id == id) - { - num = idx+1; - break; - } - } - } - else if(id == max_U64) - { - num = cfgs->count + 1; - } - return num; -} - -//////////////////////////////// -//~ rjf: Locals Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(locals) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); - e_string2num_map_node_array_sort__in_place(&nodes); - String8List exprs_filtered = {0}; - for EachIndex(idx, nodes.count) - { - String8 local_expr_string = nodes.v[idx]->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_filtered); - result.user_data = accel; - result.idxed_expr_count = accel->count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(locals) -{ - String8Array *accel = (String8Array *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - String8 expr_string = accel->v[read_range.min + idx]; - exprs[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; - exprs_strings[idx] = push_str8_copy(arena, expr_string); - } -} - -//////////////////////////////// -//~ rjf: Registers Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(registers) -{ - 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); - U64 alias_count = regs_alias_code_count_from_arch(arch); - String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); - String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); - String8List exprs_list = {0}; - for(U64 idx = 1; idx < reg_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); - } - } - for(U64 idx = 1; idx < alias_count; idx += 1) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &exprs_list); - E_LookupInfo info = {accel, 0, accel->count}; - scratch_end(scratch); - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(registers) -{ - String8Array *accel = (String8Array *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - String8 register_name = accel->v[read_range.min + idx]; - String8 register_expr = push_str8f(arena, "reg:%S", register_name); - exprs_strings[idx] = register_name; - exprs[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; - } -} - -//////////////////////////////// -//~ rjf: Schema'd Set Eval Hooks - -typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; -struct RD_SchemaLookupAccel -{ - RD_Cfg *cfg; - CTRL_Entity *entity; - MD_Node *schema; - MD_Node **children; - U64 children_count; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(schema) -{ - E_LookupInfo result = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - // rjf: unpack - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interpret = e_interpret(bytecode); - E_TypeKey type_key = lhs->type_key; - E_Type *type = e_type_from_key__cached(type_key); - MD_Node *schema = rd_schema_from_name(type->name); - - // rjf: gather expansion children - typedef struct ExpandChildNode ExpandChildNode; - struct ExpandChildNode - { - ExpandChildNode *next; - MD_Node *n; - }; - ExpandChildNode *first_child_node = 0; - ExpandChildNode *last_child_node = 0; - U64 child_count = 0; - for MD_EachNode(child, schema->first) - { - if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) - { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) - { - ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); - n->n = child; - SLLQueuePush(first_child_node, last_child_node, n); - child_count += 1; - } - } - } - - // rjf: flatten expansion member list - MD_Node **children = push_array(arena, MD_Node *, child_count); - { - U64 idx = 0; - for(ExpandChildNode *n = first_child_node; n != 0; n = n->next, idx += 1) - { - children[idx] = n->n; - } - } - - // rjf: build accelerator for lookups - RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); - accel->cfg = rd_cfg_from_eval_space(interpret.space); - accel->entity = rd_ctrl_entity_from_eval_space(interpret.space); - accel->schema = schema; - accel->children = children; - accel->children_count = child_count; - - // rjf: fill result - result.user_data = accel; - result.named_expr_count = child_count; - - scratch_end(scratch); - } - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(schema) -{ - RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; - E_IRTreeAndType irtree = {&e_irnode_nil}; - if(kind == E_ExprKind_MemberAccess) - { - MD_Node *child_schema = &md_nil_node; - for MD_EachNode(child, accel->schema->first) - { - if(str8_match(child->string, rhs->string, 0)) - { - child_schema = child; - break; - } - } - if(child_schema != &md_nil_node) - { - RD_Cfg *cfg = accel->cfg; - CTRL_Entity *entity = accel->entity; - RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); - E_TypeKey child_type_key = zero_struct; - if(0){} - - //- rjf: ctrl entity members - else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("label"), 0)) - { - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsCodeText); - } - else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("exe"), 0)) - { - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsPathText); - } - else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("dbg"), 0)) - { - CTRL_Entity *dbg = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath); - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), dbg->string.size, E_TypeFlag_IsPathText); - } - - //- rjf: cfg members - else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) - { - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); - } - else if(str8_match(child_schema->first->string, str8_lit("path"), 0)) - { - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); - } - else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - String8 string = push_str8f(scratch.arena, "%S%s%S%s%S", child->first->string, child->first->string.size ? ":" : "", child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); - scratch_end(scratch); - } - else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) - { - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); - } - - //- rjf: catchall cases - else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) - { - child_type_key = e_type_key_basic(E_TypeKind_U64); - } - else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) - { - child_type_key = e_type_key_basic(E_TypeKind_Bool); - } - else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - E_MemberList vaddr_range_members_list = {0}; - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); - e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); - E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); - child_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); - scratch_end(scratch); - } - else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) - { - child_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = child_schema->string); - } - - //- rjf: evaluate - E_Space child_eval_space = zero_struct; - if(cfg != &rd_nil_cfg) - { - child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); - child_eval_space.u64s[0] = cfg->id; - child_eval_space.u64s[1] = e_id_from_string(child_schema->string); - } - else - { - child_eval_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - child_eval_space.u64s[2] = e_id_from_string(child_schema->string); - } - irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); - irtree.type_key = child_type_key; - irtree.mode = E_Mode_Offset; - } - } - E_LookupAccess access = {irtree}; - return access; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(schema) -{ - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; - U64 out_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - if(0 <= idx && idx < accel->children_count) - { - MD_Node *child_schema = accel->children[idx]; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, child_schema->string); - } - } -} - -//////////////////////////////// -//~ rjf: Config Collection Eval Hooks - -typedef struct RD_CfgCollectionLookupAccel RD_CfgCollectionLookupAccel; -struct RD_CfgCollectionLookupAccel -{ - String8Array cmds; - RD_CfgArray cfgs; - Rng1U64 cmds_idx_range; - Rng1U64 cfgs_idx_range; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(cfgs) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - //- rjf: determine which cfg we'll use to scope the lookups - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - RD_Cfg *scoping_cfg = rd_cfg_from_eval_space(lhs_interp.space); - - //- rjf: determine which kind of child we'll be gathering - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); - - //- rjf: gather cfgs - RD_CfgList cfgs_list = {0}; - if(scoping_cfg == &rd_nil_cfg) - { - cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); - } - else - { - cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); - } - - //- rjf: filter cfgs - RD_CfgList cfgs_list__filtered = cfgs_list; - if(filter.size != 0) - { - MemoryZeroStruct(&cfgs_list__filtered); - for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) - { - DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); - String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); - if(fuzzy_matches.count == fuzzy_matches.needle_part_count) - { - rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); - } - } - } - - //- rjf: gather commands - String8List cmds_list = {0}; - if(filter.size == 0) - { - MD_Node *schema = rd_schema_from_name(cfg_name); - MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); - for MD_EachNode(cmd, collection_cmds_root->first) - { - str8_list_push(arena, &cmds_list, cmd->string); - } - } - - //- rjf: package & fill - RD_CfgCollectionLookupAccel *accel = push_array(arena, RD_CfgCollectionLookupAccel, 1); - accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); - accel->cmds = str8_array_from_list(arena, &cmds_list); - accel->cmds_idx_range = r1u64(0, accel->cmds.count); - accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); - result.user_data = accel; - result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = {{&e_irnode_nil}}; - RD_Cfg *cfg = &rd_nil_cfg; - if(kind == E_ExprKind_MemberAccess) - { - String8 rhs_name = rhs->string; - RD_CfgID id = 0; - if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && - try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) - { - cfg = rd_cfg_from_id(id); - } - } - else if(kind == E_ExprKind_ArrayIndex) - { - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - U64 rhs_idx = rhs_value.u64; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; - if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) - { - cfg = accel->cfgs.v[rhs_idx]; - } - } - if(cfg != &rd_nil_cfg) - { - E_Space cfg_space = rd_eval_space_from_cfg(cfg); - String8 cfg_name = cfg->string; - E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); - result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = cfg_type_key; - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) -{ - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; - Rng1U64 cmds_idx_range = accel->cmds_idx_range; - Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; - U64 dst_idx = 0; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - - // rjf: fill commands - { - Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); - U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; - E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); - for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) - { - String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - exprs[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); - } - } - - // rjf: fill cfgs - { - Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); - U64 read_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) - { - RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - exprs[dst_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, push_str8f(arena, "$%I64d", cfg->id)); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) -{ - U64 id = 0; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; - if(num != 0) - { - U64 idx = num-1; - if(contains_1u64(accel->cfgs_idx_range, idx)) - { - RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; - id = cfg->id; - } - else if(contains_1u64(accel->cmds_idx_range, idx)) - { - id = num; - id |= (1ull<<63); - } - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) -{ - U64 num = 0; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; - if(id != 0) - { - if(id & (1ull<<63)) - { - num = id; - num &= ~(1ull<<63); - } - else for EachIndex(idx, accel->cfgs.count) - { - if(accel->cfgs.v[idx]->id == id) - { - num = idx + accel->cfgs_idx_range.min + 1; - break; - } - } - } - return num; -} - -//////////////////////////////// -//~ rjf: Call Stack Eval Hooks - -typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; -struct RD_CallStackLookupAccel -{ - Arch arch; - CTRL_Handle process; - CTRL_CallStack call_stack; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(call_stack) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); - if(entity->kind == CTRL_EntityKind_Thread) - { - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); - accel->arch = entity->arch; - accel->process = process->handle; - accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); - result.idxed_expr_count = accel->call_stack.count; - } - result.user_data = accel; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; - CTRL_CallStack *call_stack = &accel->call_stack; - if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) - { - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); - CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); - result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); - result.irtree_and_type.mode = E_Mode_Value; - } - scratch_end(scratch); - } - return result; -} - -//////////////////////////////// -//~ rjf: Target / Environment Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(environment) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interpret = e_interpret(bytecode); - RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); - RD_CfgList env_strings = {0}; - for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) - { - if(str8_match(child->string, str8_lit("environment"), 0)) - { - rd_cfg_list_push(scratch.arena, &env_strings, child); - } - } - RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); - *accel = rd_cfg_array_from_list(arena, &env_strings); - result.user_data = accel; - result.idxed_expr_count = accel->count + 1; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(environment) -{ - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) - { - Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) - { - RD_Cfg *cfg = cfgs->v[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(environment) -{ - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) - { - exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); - } - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) -{ - U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) - { - U64 idx = (num-1); - id = cfgs->v[idx]->id; - } - else if(num == cfgs->count+1) - { - id = max_U64; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) -{ - U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(id != 0 && id != max_U64) - { - for EachIndex(idx, cfgs->count) - { - if(cfgs->v[idx]->id == id) - { - num = idx+1; - break; - } - } - } - else if(id == max_U64) - { - num = cfgs->count + 1; - } - return num; -} - -//////////////////////////////// -//~ rjf: Unattached System Process List Eval Hooks - -typedef struct RD_UnattachedProcessesAccel RD_UnattachedProcessesAccel; -struct RD_UnattachedProcessesAccel -{ - DMN_ProcessInfo *infos; - CTRL_Entity **machines; - U64 infos_count; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(unattached_processes) -{ - E_LookupInfo info = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: evaluate lhs machine, if we have one - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); - - //- rjf: gather all machines we're searching through - CTRL_EntityList machines = {0}; - if(lhs_entity->kind == CTRL_EntityKind_Machine) - { - ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); - } - else - { - machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); - } - - //- rjf: gather system processes from this machine - typedef struct Node Node; - struct Node - { - Node *next; - CTRL_Entity *machine; - DMN_ProcessInfo info; - }; - Node *first = 0; - Node *last = 0; - U64 count = 0; - for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) - { - CTRL_Entity *machine = n->v; - DMN_ProcessIter iter = {0}; - dmn_process_iter_begin(&iter); - for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) - { - B32 passes_filter = 1; - if(filter.size != 0) - { - passes_filter = 0; - FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, info.name); - FuzzyMatchRangeList pid_matches = fuzzy_match_find(scratch.arena, filter, push_str8f(scratch.arena, "%I64u", info.pid)); - if(name_matches.count == name_matches.needle_part_count || pid_matches.count == pid_matches.needle_part_count) - { - passes_filter = 1; - } - } - if(passes_filter) - { - Node *node = push_array(scratch.arena, Node, 1); - SLLQueuePush(first, last, node); - node->machine = machine; - node->info = info; - count += 1; - } - } - dmn_process_iter_end(&iter); - } - - //- rjf: list -> array - U64 infos_count = count; - DMN_ProcessInfo *infos = push_array(arena, DMN_ProcessInfo, infos_count); - CTRL_Entity **infos_machines = push_array(arena, CTRL_Entity *, infos_count); - { - U64 idx = 0; - for(Node *n = first; n != 0; n = n->next, idx += 1) - { - infos[idx] = n->info; - infos[idx].name = push_str8_copy(arena, infos[idx].name); - infos_machines[idx] = n->machine; - } - } - - //- rjf: build accelerator - RD_UnattachedProcessesAccel *accel = push_array(arena, RD_UnattachedProcessesAccel, 1); - accel->infos = infos; - accel->infos_count = infos_count; - accel->machines = infos_machines; - info.user_data = accel; - info.idxed_expr_count = infos_count; - scratch_end(scratch); - } - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(unattached_processes) -{ - RD_UnattachedProcessesAccel *accel = (RD_UnattachedProcessesAccel *)user_data; - U64 out_idx = 0; - E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = unattached_process_type; - expr->value.u128.u64[0] = accel->infos[idx].pid; - expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); - expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); - exprs[out_idx] = expr; - } -} - -//////////////////////////////// -//~ rjf: Control Entity Eval Hooks - -E_LOOKUP_INFO_FUNCTION_DEF(ctrl_entities) -{ - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - //- rjf: determine which entity we're looking under - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - CTRL_Entity *scoping_entity = &ctrl_entity_nil; - if(lhs_interp.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - scoping_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); - } - - //- rjf: determine which type of child we're gathering - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - String8 name = rd_singular_from_code_name_plural(lhs_type->name); - CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; - for EachNonZeroEnumVal(CTRL_EntityKind, k) - { - if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) - { - entity_kind = k; - break; - } - } - - //- rjf: gather list of all entities which fit the bill - CTRL_EntityList list = {0}; - if(scoping_entity == &ctrl_entity_nil) - { - list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); - } - else - { - for(CTRL_Entity *child = scoping_entity->first; child != &ctrl_entity_nil; child = child->next) - { - if(child->kind == entity_kind) - { - ctrl_entity_list_push(scratch.arena, &list, child); - } - } - } - - //- rjf: filter the list - CTRL_EntityList list__filtered = list; - if(filter.size != 0) - { - MemoryZeroStruct(&list__filtered); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) - { - CTRL_Entity *entity = n->v; - DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, 1); - String8 title_string = dr_string_from_fstrs(scratch.arena, &fstrs); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, title_string); - if(matches.count == matches.needle_part_count) - { - ctrl_entity_list_push(scratch.arena, &list__filtered, entity); - } - } - } - - //- rjf: list -> array & fill - CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); - *array = ctrl_entity_array_from_list(arena, &list__filtered); - result.user_data = array; - result.idxed_expr_count = array->count; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = {{&e_irnode_nil}}; - CTRL_Entity *entity = &ctrl_entity_nil; - if(kind == E_ExprKind_MemberAccess) - { - String8 rhs_name = rhs->string; - CTRL_Handle handle = ctrl_handle_from_string(rhs_name); - entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); - } - else if(kind == E_ExprKind_ArrayIndex) - { - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - U64 rhs_idx = rhs_value.u64; - CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; - if(0 <= rhs_idx && rhs_idx < entities->count) - { - entity = entities->v[rhs_idx]; - } - } - if(entity != &ctrl_entity_nil) - { - E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - String8 name = ctrl_entity_kind_code_name_table[entity->kind]; - E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = type_key; - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) -{ - CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - Rng1U64 legal_range = r1u64(0, entities->count); - Rng1U64 read_range = intersect_1u64(legal_range, idx_range); - U64 read_count = dim_1u64(read_range); - for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) - { - CTRL_Entity *entity = entities->v[out_idx + read_range.min]; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, ctrl_string_from_handle(arena, entity->handle)); - } -} - -//////////////////////////////// -//~ rjf: Debug Info Tables Eval Hooks - -typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; -struct RD_DebugInfoTableLookupAccel -{ - RDI_SectionKind section; - U64 rdis_count; - RDI_Parsed **rdis; - DI_SearchItemArray items; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) -{ - Temp scratch = scratch_begin(&arena, 1); - - // rjf: determine which debug info section we're dealing with - RDI_SectionKind section = RDI_SectionKind_NULL; - { - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if(0){} - else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} - else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} - else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} - else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} - } - - // rjf: gather debug info table items - RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); - if(section != RDI_SectionKind_NULL) - { - U64 endt_us = rd_state->frame_eval_memread_endt_us; - - //- 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(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: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; - B32 items_stale = 0; - DI_SearchParams params = {section, dbgi_keys}; - accel->section = section; - accel->rdis_count = rdis_count; - accel->rdis = rdis; - accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - } - E_LookupInfo info = {accel, 0, accel->items.count}; - scratch_end(scratch); - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 needed_row_count = dim_1u64(idx_range); - for EachIndex(idx, needed_row_count) - { - // rjf: unpack row - DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; - - // rjf: skip bad elements - if(item->dbgi_idx >= accel->rdis_count) - { - continue; - } - - // rjf: unpack row info - RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; - - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; - { - U64 element_idx = item->idx; - switch(accel->section) - { - default:{}break; - case RDI_SectionKind_Procedures: - { - Temp scratch = scratch_begin(&arena, 1); - RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); - RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - String8 symbol_name = {0}; - symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); - String8List strings = {0}; - e_type_lhs_string_from_key(scratch.arena, type_key, &strings, 0, 0); - str8_list_push(scratch.arena, &strings, symbol_name); - e_type_rhs_string_from_key(scratch.arena, type_key, &strings, 0); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string = str8_list_join(arena, &strings, 0); - scratch_end(scratch); - }break; - case RDI_SectionKind_GlobalVariables: - { - RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_ThreadVariables: - { - RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); - }break; - case RDI_SectionKind_UDTs: - { - RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; - }break; - } - } - - // rjf: fill - exprs[idx] = item_expr; - } -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 id = 0; - if(0 < num && num <= accel->items.count) - { - id = accel->items.v[num-1].idx+1; - } - return id; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) -{ - RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; - U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); - return num; -} - //////////////////////////////// //~ rjf: Config ID Type Functions @@ -3901,7 +2632,7 @@ rd_view_ui(Rng2F32 rect) { ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); } - block_tree = ev_block_tree_from_exprs(scratch.arena, eval_view, filter, eval.exprs); + block_tree = ev_block_tree_from_expr(scratch.arena, eval_view, filter, eval.expr); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); if(implicit_root && block_ranges.first != 0) { @@ -4098,10 +2829,10 @@ rd_view_ui(Rng2F32 rect) } // rjf: use row to complete query - if(row->expr != &e_expr_nil) + if(row->eval.expr != &e_expr_nil) { taken = 1; - E_Eval eval = e_eval_from_expr(scratch.arena, row->expr); + E_Eval eval = row->eval; switch(eval.space.kind) { default: @@ -4500,13 +3231,13 @@ rd_view_ui(Rng2F32 rect) if(cfg != &rd_nil_cfg) { rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); - U64 deleted_num = row->block->lookup_rule->num_from_id(row->key.child_id, row->block->lookup_rule_user_data); + U64 deleted_num = ev_block_num_from_id(row->block, row->key.child_id); if(deleted_num != 0) { EV_Key parent_key = row->block->parent->key; EV_Key key = row->block->key; - U64 fallback_id_prev = row->block->lookup_rule->id_from_num(deleted_num-1, row->block->lookup_rule_user_data); - U64 fallback_id_next = row->block->lookup_rule->id_from_num(deleted_num+1, row->block->lookup_rule_user_data); + U64 fallback_id_prev = ev_block_id_from_num(row->block, deleted_num-1); + U64 fallback_id_next = ev_block_id_from_num(row->block, deleted_num+1); if(fallback_id_next != 0) { parent_key = row->block->key; @@ -4703,7 +3434,7 @@ rd_view_ui(Rng2F32 rect) // rjf: determine collection info for the block String8 group_cfg_name = {0}; { - E_IRTreeAndType block_irtree = e_irtree_and_type_from_expr(scratch.arena, selection_block->expr); + E_IRTreeAndType block_irtree = selection_block->eval.irtree; E_TypeKey block_type_key = block_irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); if(block_type_kind == E_TypeKind_Set) @@ -5083,17 +3814,17 @@ rd_view_ui(Rng2F32 rect) ProfBegin("determine if row's data is fresh and/or bad"); B32 row_is_fresh = 0; B32 row_is_bad = 0; - switch(row_info->eval.irtree.mode) + switch(row->eval.irtree.mode) { default:{}break; case E_Mode_Offset: { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) { - U64 size = e_type_byte_size_from_key(row_info->eval.irtree.type_key); + U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key); size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row_info->eval.value.u64, row_info->eval.value.u64+size); + Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size); CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { @@ -5150,32 +3881,38 @@ rd_view_ui(Rng2F32 rect) //////////////////// //- rjf: draw start of cache lines in expansions // - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - U64 row_offset = row_info->eval.value.u64; - if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(space_entity->kind == CTRL_EntityKind_Process) { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_tag(str8_lit("pop")); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + U64 row_offset = row->eval.value.u64; + if((row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_tag(str8_lit("pop")); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } } } ////////////// //- rjf: draw mid-row cache line boundaries in expansions // - if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - if((row_info->eval.irtree.mode == E_Mode_Offset || row_info->eval.irtree.mode == E_Mode_Null) && - row_info->eval.value.u64%64 != 0 && + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(space_entity->kind == CTRL_EntityKind_Process && + (row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && + row->eval.value.u64%64 != 0 && row_depth > 0 && !row_expanded) { - U64 next_off = (row_info->eval.value.u64 + e_type_byte_size_from_key(row_info->eval.irtree.type_key)); - if(next_off%64 != 0 && row_info->eval.value.u64/64 < next_off/64) + U64 next_off = (row->eval.value.u64 + e_type_byte_size_from_key(row->eval.irtree.type_key)); + if(next_off%64 != 0 && row->eval.value.u64/64 < next_off/64) { ui_set_next_fixed_x(0); ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); @@ -5291,7 +4028,7 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); + rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.expr)); rd_cfg_new(view, str8_lit("selected")); RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) @@ -5543,12 +4280,12 @@ rd_view_ui(Rng2F32 rect) case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; } } - else if(row_info->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || - row_info->eval.space.kind == E_SpaceKind_FileSystem || - row_info->eval.space.kind == E_SpaceKind_File || - row_info->eval.space.kind == E_SpaceKind_Null) + else if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || + row->eval.space.kind == E_SpaceKind_FileSystem || + row->eval.space.kind == E_SpaceKind_File || + row->eval.space.kind == E_SpaceKind_Null) { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row_info->eval.exprs.last), + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row->eval.expr), .view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key)) rd_drag_begin(RD_RegSlot_Expr); } @@ -5583,8 +4320,8 @@ rd_view_ui(Rng2F32 rect) // rjf: has a command name? -> push command else if(cell_info.cmd_name.size != 0) { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row_info->eval.space); - RD_Cfg *cfg = rd_cfg_from_eval_space(row_info->eval.space); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row->eval.space); + RD_Cfg *cfg = rd_cfg_from_eval_space(row->eval.space); RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) { if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) @@ -7537,7 +6274,7 @@ rd_window_frame(void) EV_BlockTree predicted_block_tree = {0}; RD_RegsScope(.view = view->id) { - predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.exprs); + predicted_block_tree = ev_block_tree_from_expr(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.expr); } F32 row_height_px = ui_top_px_height(); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); @@ -7689,7 +6426,7 @@ rd_window_frame(void) { Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_exprs(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.exprs); + EV_BlockTree predicted_block_tree = ev_block_tree_from_expr(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.expr); F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); F32 max_query_height_px = content_rect_dim.y*0.8f; F32 query_height_px = max_query_height_px; @@ -10408,6 +9145,7 @@ rd_window_frame(void) //////////////////////////////// //~ rjf: Eval Visualization +#if 0 // TODO(rjf): @eval internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out) { @@ -10448,9 +9186,9 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f } //- rjf: force no_string, if we are looking at padding members - if(eval.exprs.last->kind == E_ExprKind_MemberAccess) + if(eval.expr->kind == E_ExprKind_MemberAccess) { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.exprs.last->first); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr->first); E_TypeKey struct_type = irtree.type_key; for(B32 done = 0; !done;) { @@ -10471,7 +9209,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f break; } } - E_Member member = e_type_member_from_key_name__cached(struct_type, eval.exprs.last->last->string); + E_Member member = e_type_member_from_key_name__cached(struct_type, eval.expr->first->next->string); if(member.kind == E_MemberKind_Padding) { no_string = 1; @@ -10640,7 +9378,7 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f { if(type->count == 1) { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.exprs.last); + E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, deref_eval, out); } @@ -10877,6 +9615,7 @@ rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U3 scratch_end(scratch); return result; } +#endif internal String8 rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) @@ -13540,26 +12279,33 @@ rd_frame(void) ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); +#if 0 // TODO(rjf): @eval 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->irgen_rule_map = push_array(scratch.arena, E_IRGenRuleMap, 1); ctx->irgen_rule_map[0] = e_irgen_rule_map_make(scratch.arena, 512); +#endif 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: cache meta name -> type key correllation rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); +#if 0 // TODO(rjf): @eval for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; - E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set); + E_TypeKey type_key = e_type_key_cons(.name = name, + .kind = E_TypeKind_Set, + .access = E_TYPE_ACCESS_FUNCTION_NAME(schema), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(schema), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(schema), + }); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(schema), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(schema), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(schema)); } +#endif //- rjf: add macros for evallable top-level config trees String8 evallable_cfg_names[] = @@ -13681,30 +12427,39 @@ rd_frame(void) { String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(watches), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(watches), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), + }); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(watches), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(watches), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(watches)); } - //- rjf: add lookup rules for queries + //- rjf: add types for queries { - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment)); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(call_stack), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(call_stack)); +#if 0 // TODO(rjf): @eval + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("environment"), + e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("environment"), + .flags = E_TypeFlag_EditableChildren, + .expand = + { + .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), + .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), + .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), + .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment), + })); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), + e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack"))); +#endif } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) +#if 0 // TODO(rjf): @eval { struct { @@ -13730,8 +12485,10 @@ rd_frame(void) .range = collection_infos[idx].lookup_range); } } +#endif //- rjf: add macros for debug info table collections +#if 0 // TODO(rjf): @eval String8 debug_info_table_collection_names[] = { str8_lit_comp("procedures"), @@ -13813,6 +12570,7 @@ rd_frame(void) .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands), .range = E_LOOKUP_RANGE_FUNCTION_NAME(commands)); } +#endif //- rjf: add macro for output log { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index d61f709e..32780f50 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1005,8 +1005,10 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization +#if 0 // TODO(rjf): @eval internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out); internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); +#endif internal String8 rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c new file mode 100644 index 00000000..275b7cd2 --- /dev/null +++ b/src/raddbg/raddbg_eval.c @@ -0,0 +1,1274 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: `commands` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) +{ + E_TypeExpandInfo result = {0}; + if(filter.size != 0) + { + Temp scratch = scratch_begin(&arena, 1); + String8List cmd_names = {0}; + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + String8 name = info->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &cmd_names, name); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &cmd_names); + result.user_data = accel; + result.expr_count = accel->count; + scratch_end(scratch); + } + else + { + result.expr_count = RD_CmdKind_COUNT; + } + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(commands) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_MemberAccess) + { + String8 cmd_name = expr->first->next->string; + result.type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + result.mode = E_Mode_Value; + result.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, e_id_from_string(cmd_name))); + } + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) +{ + U64 out_idx = 0; + if(user_data != 0) + { + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 cmd_name = accel->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs_out[out_idx] = expr; + } + } + else + { + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + RD_CmdKind cmd_kind = (RD_CmdKind)idx; + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs_out[out_idx] = expr; + } + } +} + +//////////////////////////////// +//~ rjf: `watches` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) +{ + E_TypeExpandInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + String8 expr = rd_expr_from_cfg(n->v); + B32 passes_filter = 1; + if(filter.size != 0) + { + E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind != E_TypeKind_Set) + { + passes_filter = 0; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); + if(matches.count == matches.needle_part_count) + { + passes_filter = 1; + } + } + } + if(passes_filter) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); + cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + result.user_data = cfgs; + result.expr_count = cfgs->count + 1; + } + scratch_end(scratch); + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; + exprs_strings_out[idx] = push_str8_copy(arena, expr_string); + } + } +} + +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: `locals` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(locals) +{ + E_TypeExpandInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); + e_string2num_map_node_array_sort__in_place(&nodes); + String8List exprs_filtered = {0}; + for EachIndex(idx, nodes.count) + { + String8 local_expr_string = nodes.v[idx]->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, local_expr_string); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_filtered, local_expr_string); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_filtered); + result.user_data = accel; + result.expr_count = accel->count; + } + scratch_end(scratch); + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 expr_string = accel->v[read_range.min + idx]; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; + exprs_strings_out[idx] = push_str8_copy(arena, expr_string); + } +} + +//////////////////////////////// +//~ rjf: `registers` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers) +{ + 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); + U64 alias_count = regs_alias_code_count_from_arch(arch); + String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); + String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); + String8List exprs_list = {0}; + for(U64 idx = 1; idx < reg_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, reg_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, reg_strings[idx]); + } + } + for(U64 idx = 1; idx < alias_count; idx += 1) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, alias_strings[idx]); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &exprs_list, alias_strings[idx]); + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &exprs_list); + E_TypeExpandInfo info = {accel, accel->count}; + scratch_end(scratch); + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) +{ + String8Array *accel = (String8Array *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + String8 register_name = accel->v[read_range.min + idx]; + String8 register_expr = push_str8f(arena, "reg:%S", register_name); + exprs_strings_out[idx] = register_name; + exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; + } +} + +//////////////////////////////// +//~ rjf: Schema Type Hooks + +#if 0 // TODO(rjf): @eval + +E_TYPE_ACCESS_FUNCTION_DEF(schema) +{ + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + E_IRTreeAndType irtree = {&e_irnode_nil}; + if(kind == E_ExprKind_MemberAccess) + { + MD_Node *child_schema = &md_nil_node; + for MD_EachNode(child, accel->schema->first) + { + if(str8_match(child->string, rhs->string, 0)) + { + child_schema = child; + break; + } + } + if(child_schema != &md_nil_node) + { + RD_Cfg *cfg = accel->cfg; + CTRL_Entity *entity = accel->entity; + RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); + E_TypeKey child_type_key = zero_struct; + if(0){} + + //- rjf: ctrl entity members + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("label"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsCodeText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("exe"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), entity->string.size, E_TypeFlag_IsPathText); + } + else if(entity != &ctrl_entity_nil && str8_match(child_schema->string, str8_lit("dbg"), 0)) + { + CTRL_Entity *dbg = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), dbg->string.size, E_TypeFlag_IsPathText); + } + + //- rjf: cfg members + else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); + } + else if(str8_match(child_schema->first->string, str8_lit("path"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); + } + else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + String8 string = push_str8f(scratch.arena, "%S%s%S%s%S", child->first->string, child->first->string.size ? ":" : "", child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); + scratch_end(scratch); + } + else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) + { + child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); + } + + //- rjf: catchall cases + else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_U64); + } + else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_Bool); + } + else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + E_MemberList vaddr_range_members_list = {0}; + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("min"), .off = 0); + e_member_list_push_new(scratch.arena, &vaddr_range_members_list, .type_key = e_type_key_basic(E_TypeKind_U64), .name = str8_lit("max"), .off = 8); + E_MemberArray vaddr_range_members = e_member_array_from_list(scratch.arena, &vaddr_range_members_list); + child_type_key = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("vaddr_range"), .count = vaddr_range_members.count, .members = vaddr_range_members.v); + scratch_end(scratch); + } + else if(str8_match(child_schema->first->string, str8_lit("query"), 0)) + { + child_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, child_schema->string); + } + + //- rjf: evaluate + E_Space child_eval_space = zero_struct; + if(cfg != &rd_nil_cfg) + { + child_eval_space = e_space_make(RD_EvalSpaceKind_MetaCfg); + child_eval_space.u64s[0] = cfg->id; + child_eval_space.u64s[1] = e_id_from_string(child_schema->string); + } + else + { + child_eval_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + child_eval_space.u64s[2] = e_id_from_string(child_schema->string); + } + irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); + irtree.type_key = child_type_key; + irtree.mode = E_Mode_Offset; + } + } + E_LookupAccess access = {irtree}; + return access; +} + +typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; +struct RD_SchemaLookupAccel +{ + RD_Cfg *cfg; + CTRL_Entity *entity; + MD_Node *schema; + MD_Node **children; + U64 children_count; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) +{ + E_TypeExpandInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: unpack + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + E_TypeKey type_key = lhs->type_key; + E_Type *type = e_type_from_key__cached(type_key); + MD_Node *schema = rd_schema_from_name(type->name); + + // rjf: gather expansion children + typedef struct ExpandChildNode ExpandChildNode; + struct ExpandChildNode + { + ExpandChildNode *next; + MD_Node *n; + }; + ExpandChildNode *first_child_node = 0; + ExpandChildNode *last_child_node = 0; + U64 child_count = 0; + for MD_EachNode(child, schema->first) + { + if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) + { + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); + if(matches.count == matches.needle_part_count) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } + } + } + + // rjf: flatten expansion member list + MD_Node **children = push_array(arena, MD_Node *, child_count); + { + U64 idx = 0; + for(ExpandChildNode *n = first_child_node; n != 0; n = n->next, idx += 1) + { + children[idx] = n->n; + } + } + + // rjf: build accelerator for lookups + RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); + accel->cfg = rd_cfg_from_eval_space(interpret.space); + accel->entity = rd_ctrl_entity_from_eval_space(interpret.space); + accel->schema = schema; + accel->children = children; + accel->children_count = child_count; + + // rjf: fill result + result.user_data = accel; + result.expr_count = child_count; + + scratch_end(scratch); + } + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(schema) +{ + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + if(0 <= idx && idx < accel->children_count) + { + MD_Node *child_schema = accel->children[idx]; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, child_schema->string); + } + } +} + +//////////////////////////////// +//~ rjf: Config Collection Type Hooks + +typedef struct RD_CfgCollectionLookupAccel RD_CfgCollectionLookupAccel; +struct RD_CfgCollectionLookupAccel +{ + String8Array cmds; + RD_CfgArray cfgs; + Rng1U64 cmds_idx_range; + Rng1U64 cfgs_idx_range; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(cfgs) +{ + E_LookupInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: determine which cfg we'll use to scope the lookups + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + RD_Cfg *scoping_cfg = rd_cfg_from_eval_space(lhs_interp.space); + + //- rjf: determine which kind of child we'll be gathering + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); + + //- rjf: gather cfgs + RD_CfgList cfgs_list = {0}; + if(scoping_cfg == &rd_nil_cfg) + { + cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); + } + else + { + cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); + } + + //- rjf: filter cfgs + RD_CfgList cfgs_list__filtered = cfgs_list; + if(filter.size != 0) + { + MemoryZeroStruct(&cfgs_list__filtered); + for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) + { + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); + String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); + if(fuzzy_matches.count == fuzzy_matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); + } + } + } + + //- rjf: gather commands + String8List cmds_list = {0}; + if(filter.size == 0) + { + MD_Node *schema = rd_schema_from_name(cfg_name); + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(arena, &cmds_list, cmd->string); + } + } + + //- rjf: package & fill + RD_CfgCollectionLookupAccel *accel = push_array(arena, RD_CfgCollectionLookupAccel, 1); + accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + accel->cmds = str8_array_from_list(arena, &cmds_list); + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); + result.user_data = accel; + result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = {{&e_irnode_nil}}; + RD_Cfg *cfg = &rd_nil_cfg; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + RD_CfgID id = 0; + if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && + try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + { + cfg = rd_cfg_from_id(id); + } + } + else if(kind == E_ExprKind_ArrayIndex) + { + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + U64 rhs_idx = rhs_value.u64; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) + { + cfg = accel->cfgs.v[rhs_idx]; + } + } + if(cfg != &rd_nil_cfg) + { + E_Space cfg_space = rd_eval_space_from_cfg(cfg); + String8 cfg_name = cfg->string; + E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); + result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = cfg_type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) +{ + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + Rng1U64 cmds_idx_range = accel->cmds_idx_range; + Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; + U64 dst_idx = 0; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: fill commands + { + Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; + E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; + exprs[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); + } + } + + // rjf: fill cfgs + { + Rng1U64 read_range = intersect_1u64(cfgs_idx_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) + { + RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; + exprs[dst_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, push_str8f(arena, "$%I64d", cfg->id)); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) +{ + U64 id = 0; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(num != 0) + { + U64 idx = num-1; + if(contains_1u64(accel->cfgs_idx_range, idx)) + { + RD_Cfg *cfg = accel->cfgs.v[idx - accel->cfgs_idx_range.min]; + id = cfg->id; + } + else if(contains_1u64(accel->cmds_idx_range, idx)) + { + id = num; + id |= (1ull<<63); + } + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) +{ + U64 num = 0; + RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + if(id != 0) + { + if(id & (1ull<<63)) + { + num = id; + num &= ~(1ull<<63); + } + else for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx + accel->cfgs_idx_range.min + 1; + break; + } + } + } + return num; +} + +//////////////////////////////// +//~ rjf: `call_stack` Type Hooks + +typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; +struct RD_CallStackLookupAccel +{ + Arch arch; + CTRL_Handle process; + CTRL_CallStack call_stack; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) +{ + E_TypeExpandInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); + if(entity->kind == CTRL_EntityKind_Thread) + { + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); + accel->arch = entity->arch; + accel->process = process->handle; + accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); + result.expr_count = accel->call_stack.count; + } + result.user_data = accel; + } + scratch_end(scratch); + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(call_stack) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; + CTRL_CallStack *call_stack = &accel->call_stack; + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) + { + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); + CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); + result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + result.irtree_and_type.mode = E_Mode_Value; + } + scratch_end(scratch); + } + return result; +} + +//////////////////////////////// +//~ rjf: `environment` Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(environment) +{ + E_LookupAccess result = {{&e_irnode_nil}}; + if(kind == E_ExprKind_ArrayIndex) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) +{ + E_TypeExpandInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); + RD_CfgList env_strings = {0}; + for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("environment"), 0)) + { + rd_cfg_list_push(scratch.arena, &env_strings, child); + } + } + RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); + *accel = rd_cfg_array_from_list(arena, &env_strings); + result.user_data = accel; + result.idxed_expr_count = accel->count + 1; + } + scratch_end(scratch); + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment) +{ + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < cfgs->count) + { + exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); + } + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) +{ + U64 id = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(1 <= num && num <= cfgs->count) + { + U64 idx = (num-1); + id = cfgs->v[idx]->id; + } + else if(num == cfgs->count+1) + { + id = max_U64; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +{ + U64 num = 0; + RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, cfgs->count) + { + if(cfgs->v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = cfgs->count + 1; + } + return num; +} + +//////////////////////////////// +//~ rjf: `unattached_processes` Type Hooks + +typedef struct RD_UnattachedProcessesAccel RD_UnattachedProcessesAccel; +struct RD_UnattachedProcessesAccel +{ + DMN_ProcessInfo *infos; + CTRL_Entity **machines; + U64 infos_count; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) +{ + E_TypeExpandInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: evaluate lhs machine, if we have one + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + + //- rjf: gather all machines we're searching through + CTRL_EntityList machines = {0}; + if(lhs_entity->kind == CTRL_EntityKind_Machine) + { + ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); + } + else + { + machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + } + + //- rjf: gather system processes from this machine + typedef struct Node Node; + struct Node + { + Node *next; + CTRL_Entity *machine; + DMN_ProcessInfo info; + }; + Node *first = 0; + Node *last = 0; + U64 count = 0; + for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) + { + CTRL_Entity *machine = n->v; + DMN_ProcessIter iter = {0}; + dmn_process_iter_begin(&iter); + for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) + { + B32 passes_filter = 1; + if(filter.size != 0) + { + passes_filter = 0; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, info.name); + FuzzyMatchRangeList pid_matches = fuzzy_match_find(scratch.arena, filter, push_str8f(scratch.arena, "%I64u", info.pid)); + if(name_matches.count == name_matches.needle_part_count || pid_matches.count == pid_matches.needle_part_count) + { + passes_filter = 1; + } + } + if(passes_filter) + { + Node *node = push_array(scratch.arena, Node, 1); + SLLQueuePush(first, last, node); + node->machine = machine; + node->info = info; + count += 1; + } + } + dmn_process_iter_end(&iter); + } + + //- rjf: list -> array + U64 infos_count = count; + DMN_ProcessInfo *infos = push_array(arena, DMN_ProcessInfo, infos_count); + CTRL_Entity **infos_machines = push_array(arena, CTRL_Entity *, infos_count); + { + U64 idx = 0; + for(Node *n = first; n != 0; n = n->next, idx += 1) + { + infos[idx] = n->info; + infos[idx].name = push_str8_copy(arena, infos[idx].name); + infos_machines[idx] = n->machine; + } + } + + //- rjf: build accelerator + RD_UnattachedProcessesAccel *accel = push_array(arena, RD_UnattachedProcessesAccel, 1); + accel->infos = infos; + accel->infos_count = infos_count; + accel->machines = infos_machines; + info.user_data = accel; + info.idxed_expr_count = infos_count; + scratch_end(scratch); + } + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) +{ + RD_UnattachedProcessesAccel *accel = (RD_UnattachedProcessesAccel *)user_data; + U64 out_idx = 0; + E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = unattached_process_type; + expr->value.u128.u64[0] = accel->infos[idx].pid; + expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); + expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); + exprs_out[out_idx] = expr; + } +} + +//////////////////////////////// +//~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) +{ + E_TypeExpandInfo result = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: determine which entity we're looking under + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); + E_Interpretation lhs_interp = e_interpret(lhs_bytecode); + CTRL_Entity *scoping_entity = &ctrl_entity_nil; + if(lhs_interp.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + scoping_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + } + + //- rjf: determine which type of child we're gathering + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + String8 name = rd_singular_from_code_name_plural(lhs_type->name); + CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; + for EachNonZeroEnumVal(CTRL_EntityKind, k) + { + if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) + { + entity_kind = k; + break; + } + } + + //- rjf: gather list of all entities which fit the bill + CTRL_EntityList list = {0}; + if(scoping_entity == &ctrl_entity_nil) + { + list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + } + else + { + for(CTRL_Entity *child = scoping_entity->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == entity_kind) + { + ctrl_entity_list_push(scratch.arena, &list, child); + } + } + } + + //- rjf: filter the list + CTRL_EntityList list__filtered = list; + if(filter.size != 0) + { + MemoryZeroStruct(&list__filtered); + for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, 1); + String8 title_string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, title_string); + if(matches.count == matches.needle_part_count) + { + ctrl_entity_list_push(scratch.arena, &list__filtered, entity); + } + } + } + + //- rjf: list -> array & fill + CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); + *array = ctrl_entity_array_from_list(arena, &list__filtered); + result.user_data = array; + result.idxed_expr_count = array->count; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) +{ + Temp scratch = scratch_begin(&arena, 1); + E_LookupAccess result = {{&e_irnode_nil}}; + CTRL_Entity *entity = &ctrl_entity_nil; + if(kind == E_ExprKind_MemberAccess) + { + String8 rhs_name = rhs->string; + CTRL_Handle handle = ctrl_handle_from_string(rhs_name); + entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + } + else if(kind == E_ExprKind_ArrayIndex) + { + E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); + E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); + String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); + E_Interpretation rhs_interp = e_interpret(rhs_bytecode); + E_Value rhs_value = rhs_interp.value; + U64 rhs_idx = rhs_value.u64; + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + if(0 <= rhs_idx && rhs_idx < entities->count) + { + entity = entities->v[rhs_idx]; + } + } + if(entity != &ctrl_entity_nil) + { + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.irtree_and_type.type_key = type_key; + result.irtree_and_type.mode = E_Mode_Offset; + } + scratch_end(scratch); + return result; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) +{ + CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + Rng1U64 legal_range = r1u64(0, entities->count); + Rng1U64 read_range = intersect_1u64(legal_range, idx_range); + U64 read_count = dim_1u64(read_range); + for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) + { + CTRL_Entity *entity = entities->v[out_idx + read_range.min]; + exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, ctrl_string_from_handle(arena, entity->handle)); + } +} + +//////////////////////////////// +//~ rjf: Debug Info Tables Eval Hooks + +typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel; +struct RD_DebugInfoTableLookupAccel +{ + RDI_SectionKind section; + U64 rdis_count; + RDI_Parsed **rdis; + DI_SearchItemArray items; +}; + +E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) +{ + Temp scratch = scratch_begin(&arena, 1); + + // rjf: determine which debug info section we're dealing with + RDI_SectionKind section = RDI_SectionKind_NULL; + { + E_TypeKey lhs_type_key = lhs->type_key; + E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + if(0){} + else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} + else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} + else if(str8_match(lhs_type->name, str8_lit("thread_locals"), 0)) {section = RDI_SectionKind_ThreadVariables;} + else if(str8_match(lhs_type->name, str8_lit("types"), 0)) {section = RDI_SectionKind_UDTs;} + } + + // rjf: gather debug info table items + RD_DebugInfoTableLookupAccel *accel = push_array(arena, RD_DebugInfoTableLookupAccel, 1); + if(section != RDI_SectionKind_NULL) + { + U64 endt_us = rd_state->frame_eval_memread_endt_us; + + //- 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(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: query all filtered items from dbgi searching system + U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section}; + B32 items_stale = 0; + DI_SearchParams params = {section, dbgi_keys}; + accel->section = section; + accel->rdis_count = rdis_count; + accel->rdis = rdis; + accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + if(items_stale) + { + rd_request_frame(); + } + } + E_LookupInfo info = {accel, 0, accel->items.count}; + scratch_end(scratch); + return info; +} + +E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 needed_row_count = dim_1u64(idx_range); + for EachIndex(idx, needed_row_count) + { + // rjf: unpack row + DI_SearchItem *item = &accel->items.v[idx_range.min + idx]; + + // rjf: skip bad elements + if(item->dbgi_idx >= accel->rdis_count) + { + continue; + } + + // rjf: unpack row info + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; + + // rjf: build expr + E_Expr *item_expr = &e_expr_nil; + { + U64 element_idx = item->idx; + switch(accel->section) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + Temp scratch = scratch_begin(&arena, 1); + RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); + RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + String8 symbol_name = {0}; + symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); + String8List strings = {0}; + e_type_lhs_string_from_key(scratch.arena, type_key, &strings, 0, 0); + str8_list_push(scratch.arena, &strings, symbol_name); + e_type_rhs_string_from_key(scratch.arena, type_key, &strings, 0); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Value; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string = str8_list_join(arena, &strings, 0); + scratch_end(scratch); + }break; + case RDI_SectionKind_GlobalVariables: + { + RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); + U64 voff = gvar->voff; + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = gvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_ThreadVariables: + { + RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = tvar->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); + item_expr->mode = E_Mode_Offset; + item_expr->space = module->space; + item_expr->type_key = type_key; + item_expr->bytecode = bytecode; + item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + }break; + case RDI_SectionKind_UDTs: + { + RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); + RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); + item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); + item_expr->type_key = type_key; + }break; + } + } + + // rjf: fill + exprs[idx] = item_expr; + } +} + +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 id = 0; + if(0 < num && num <= accel->items.count) + { + id = accel->items.v[num-1].idx+1; + } + return id; +} + +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) +{ + RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; + U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); + return num; +} +#endif diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h new file mode 100644 index 00000000..d8c6af28 --- /dev/null +++ b/src/raddbg/raddbg_eval.h @@ -0,0 +1,88 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADDBG_EVAL_H +#define RADDBG_EVAL_H + +//////////////////////////////// +//~ rjf: `commands` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands); +E_TYPE_ACCESS_FUNCTION_DEF(commands); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands); + +//////////////////////////////// +//~ rjf: `watches` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); + +//////////////////////////////// +//~ rjf: `locals` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(locals); +E_LOOKUP_RANGE_FUNCTION_DEF(locals); + +//////////////////////////////// +//~ rjf: `registers` Type Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(registers); +E_LOOKUP_RANGE_FUNCTION_DEF(registers); + +//////////////////////////////// +//~ rjf: Schema Type Hooks + +#if 0 // TODO(rjf): @eval +E_TYPE_ACCESS_FUNCTION_DEF(schema); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); + +//////////////////////////////// +//~ rjf: Config Collection Type Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(cfgs); +E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs); +E_LOOKUP_RANGE_FUNCTION_DEF(cfgs); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs); + +//////////////////////////////// +//~ rjf: `call_stack` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); +E_TYPE_ACCESS_FUNCTION_DEF(call_stack); + +//////////////////////////////// +//~ rjf: `environment` Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(environment); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment); + +//////////////////////////////// +//~ rjf: `unattached_processes` Type Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes); + +//////////////////////////////// +//~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities); +E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities); +E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities); + +//////////////////////////////// +//~ rjf: Debug Info Tables Eval Hooks + +E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table); +E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table); +E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table); +E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table); +#endif + +#endif // RADDBG_EVAL_H diff --git a/src/raddbg/raddbg_inc.c b/src/raddbg/raddbg_inc.c index 07842d04..e3fef691 100644 --- a/src/raddbg/raddbg_inc.c +++ b/src/raddbg/raddbg_inc.c @@ -2,5 +2,6 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) #include "raddbg_core.c" +#include "raddbg_eval.c" #include "raddbg_widgets.c" #include "raddbg_views.c" diff --git a/src/raddbg/raddbg_inc.h b/src/raddbg/raddbg_inc.h index 46cb0ece..2e131faf 100644 --- a/src/raddbg/raddbg_inc.h +++ b/src/raddbg/raddbg_inc.h @@ -5,6 +5,7 @@ #define RADDBG_INC_H #include "raddbg_core.h" +#include "raddbg_eval.h" #include "raddbg_widgets.h" #include "raddbg_views.h" diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 634fc015..b67927c5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -943,37 +943,32 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: unpack key & block EV_Block *block = row->block; EV_Key key = row->key; - E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); - E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); - E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); + E_Eval block_eval = row->block->eval; E_TypeKey block_type_key = block_eval.irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); E_Type *block_type = e_type_from_key__cached(block_type_key); - // rjf: fill row's eval - info.eval = e_eval_from_expr(arena, row->expr); - // rjf: determine if row's expression is editable - if(block_type->flags & E_TypeFlag_EditableChildren || row->expr == &e_expr_nil) + if(block_type->flags & E_TypeFlag_EditableChildren || row->eval.expr == &e_expr_nil) { info.expr_is_editable = 1; } // rjf: determine row's module - CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(row->eval.space); CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); - if(info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity) { switch(row_ctrl_entity->kind) { default: case CTRL_EntityKind_Process: - if(info.eval.irtree.mode == E_Mode_Offset) + if(row->eval.irtree.mode == E_Mode_Offset) { - info.module = ctrl_module_from_process_vaddr(row_ctrl_entity, info.eval.value.u64); + info.module = ctrl_module_from_process_vaddr(row_ctrl_entity, row->eval.value.u64); }break; case CTRL_EntityKind_Thread: - if(info.eval.irtree.mode == E_Mode_Value) + if(row->eval.irtree.mode == E_Mode_Value) { CTRL_Entity *process = ctrl_process_from_entity(row_ctrl_entity); info.module = ctrl_module_from_process_vaddr(process, d_query_cached_rip_from_thread(row_ctrl_entity)); @@ -988,7 +983,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(entity->kind == CTRL_EntityKind_Thread) { info.callstack_thread = entity; - U64 frame_num = block->lookup_rule->num_from_id(key.child_id, block->lookup_rule_user_data); + U64 frame_num = ev_block_num_from_id(block, key.child_id); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_process_from_entity(entity), &unwind); if(1 <= frame_num && frame_num <= call_stack.count) @@ -1005,7 +1000,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { - info.group_entity = rd_ctrl_entity_from_eval_space(info.eval.space); + info.group_entity = rd_ctrl_entity_from_eval_space(row->eval.space); } // rjf: determine cfg group name / parent @@ -1037,8 +1032,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine cfgs/entities that this row is evaluating - RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(info.eval.space); - CTRL_Entity *evalled_entity = (info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(info.eval.space) : &ctrl_entity_nil); + RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(row->eval.space); + CTRL_Entity *evalled_entity = (row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(row->eval.space) : &ctrl_entity_nil); // rjf: determine if this cfg/entity evaluation is top-level - e.g. if we // are evaluating a cfg tree, or some descendant of it @@ -1046,33 +1041,36 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(evalled_cfg != &rd_nil_cfg) { E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); - is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); + is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); } if(evalled_entity != &ctrl_entity_nil) { String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); - is_top_level = (info.eval.value.u64 == 0 && e_type_key_match(top_level_type_key, info.eval.irtree.type_key)); + is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); } // rjf: determine view ui rule - info.view_ui_rule = rd_view_ui_rule_from_string(row->block->expand_rule->string); + // TODO(rjf): @eval + info.view_ui_rule = &rd_nil_view_ui_rule; // rd_view_ui_rule_from_string(row->block->expand_rule->string); +#if 0 // TODO(rjf): @eval if(info.view_ui_rule != &rd_nil_view_ui_rule) { info.view_ui_tag = row->block->expand_tag; } +#endif // rjf: fill row's cells { if(0){} // rjf: folder / file rows - else if(info.eval.space.kind == E_SpaceKind_FileSystem) + else if(row->eval.space.kind == E_SpaceKind_FileSystem) { - E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { - String8 file_path = e_string_from_id(info.eval.value.u64); + String8 file_path = e_string_from_id(row->eval.value.u64); DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, @@ -1098,13 +1096,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: singular button for unattached processes - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { - E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(str8_match(type->name, str8_lit("unattached_process"), 0)) { - U64 pid = info.eval.value.u128.u64[0]; - String8 name = e_string_from_id(info.eval.value.u128.u64[1]); + U64 pid = row->eval.value.u128.u64[0]; + String8 name = e_string_from_id(row->eval.value.u128.u64[1]); DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; DR_FStrList fstrs = {0}; UI_TagF("weak") @@ -1217,22 +1215,22 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: singular row for queries - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaQuery) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } // rjf: singular button for commands - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCmd) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - E_Type *type = e_type_from_key__cached(info.eval.irtree.type_key); + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); } else { - String8 cmd_name = e_string_from_id(e_value_eval_from_eval(info.eval).value.u64); + String8 cmd_name = e_string_from_id(e_value_eval_from_eval(row->eval).value.u64); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); } @@ -1245,28 +1243,28 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr - else if(info.eval.exprs.last == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) + else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } // rjf: for meta-evaluation space booleans, only do expr - else if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Bool && - (info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || - info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + else if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Bool && + (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || + row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); } // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - info.eval.space.kind == RD_EvalSpaceKind_MetaCmd || - info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - info.eval.space.kind == E_SpaceKind_File) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || + row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + row->eval.space.kind == E_SpaceKind_File) { - if(e_type_kind_from_key(info.eval.irtree.type_key) == E_TypeKind_Array && - e_type_kind_from_key(e_type_direct_from_key(info.eval.irtree.type_key)) == E_TypeKind_U8) + if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Array && + e_type_kind_from_key(e_type_direct_from_key(row->eval.irtree.type_key)) == E_TypeKind_U8) { info.can_expand = 0; } @@ -1371,11 +1369,11 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.flags |= RD_WatchCellFlag_CanEdit; } - result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); result.string = row->string; if(result.string.size == 0) { - E_Expr *notable_expr = row->expr; + E_Expr *notable_expr = row->eval.expr; for(B32 good = 0; !good;) { switch(notable_expr->kind) @@ -1451,7 +1449,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: use cell's wrap string to wrap row's expression String8 wrap_string = cell->string; - E_Expr *root_expr = row->expr; + E_Expr *root_expr = row->eval.expr; if(wrap_string.size != 0) { E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).exprs.last; @@ -1470,7 +1468,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { if(t->expr->kind == E_ExprKind_LeafIdentifier && str8_match(t->expr->string, str8_lit("$expr"), 0)) { - E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->expr); + E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->eval.expr); if(t->parent != &e_expr_nil) { e_expr_insert_child(t->parent, t->expr, original_expr_ref); @@ -1526,7 +1524,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: view ui cells case RD_WatchCellKind_ViewUI: { - result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, row->expr)); + result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); result.view_ui_rule = row_info->view_ui_rule; result.view_ui_tag = row_info->view_ui_tag; }break; @@ -1948,7 +1946,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) // B32 auto_selected = 0; E_Space auto_space = {0}; - if(eval.exprs.last == &e_expr_nil) + if(eval.expr == &e_expr_nil) { if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index c67e9ba3..a4961eda 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -88,7 +88,6 @@ struct RD_WatchCellList typedef struct RD_WatchRowInfo RD_WatchRowInfo; struct RD_WatchRowInfo { - E_Eval eval; CTRL_Entity *module; B32 can_expand; B32 expr_is_editable; From c938a6fcfa15801b13d32e213ebdfcd824c8ff4c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 8 Apr 2025 19:37:38 -0700 Subject: [PATCH 327/755] next checkpoint; eval/type-hooks for registers, locals, files/folders, cfgs --- src/eval/eval_core.h | 4 +- src/eval/eval_types.c | 41 ++- src/eval/eval_types.h | 30 ++ .../eval_visualization_core.c | 14 +- src/raddbg/raddbg_core.c | 45 +-- src/raddbg/raddbg_eval.c | 259 ++++++++++-------- src/raddbg/raddbg_eval.h | 19 +- 7 files changed, 250 insertions(+), 162 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index ea79a619..78a7021c 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -367,12 +367,12 @@ typedef E_TYPE_IRGEN_FUNCTION_SIG(E_TypeIRGenFunctionType); #define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) typedef E_TYPE_ACCESS_FUNCTION_SIG(E_TypeAccessFunctionType); -#define E_TYPE_EXPAND_INFO_FUNCTION_SIG(name) E_TypeExpandInfo name(Arena *arena, E_IRTreeAndType *irtree, String8 filter) +#define E_TYPE_EXPAND_INFO_FUNCTION_SIG(name) E_TypeExpandInfo name(Arena *arena, E_Expr *expr, E_IRTreeAndType *irtree, String8 filter) #define E_TYPE_EXPAND_INFO_FUNCTION_NAME(name) e_type_expand_info__##name #define E_TYPE_EXPAND_INFO_FUNCTION_DEF(name) internal E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TYPE_EXPAND_INFO_FUNCTION_NAME(name)) typedef E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TypeExpandInfoFunctionType); -#define E_TYPE_EXPAND_RANGE_FUNCTION_SIG(name) void name(Arena *arena, void *user_data, E_Expr *expr, String8 filter, Rng1U64 idx_range, E_Expr **exprs_out, String8 *exprs_strings_out) +#define E_TYPE_EXPAND_RANGE_FUNCTION_SIG(name) void name(Arena *arena, void *user_data, E_Expr *expr, E_IRTreeAndType *irtree, String8 filter, Rng1U64 idx_range, E_Expr **exprs_out, String8 *exprs_strings_out) #define E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name) e_type_expand_range__##name #define E_TYPE_EXPAND_RANGE_FUNCTION_DEF(name) internal E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)) typedef E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TypeExpandRangeFunctionType); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 69d66116..b393266b 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -248,6 +248,24 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count); e_type_state->type_cache_slots_count = 1024; e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); + e_type_state->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("file"), + .irgen = E_TYPE_IRGEN_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_type_state->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), + }); } //////////////////////////////// @@ -519,6 +537,20 @@ e_type_key_cons_base(Type *type) return result; } +internal E_TypeKey +e_type_key_file(void) +{ + E_TypeKey key = e_type_state->file_type_key; + return key; +} + +internal E_TypeKey +e_type_key_folder(void) +{ + E_TypeKey key = e_type_state->folder_type_key; + return key; +} + //- rjf: basic type key functions internal B32 @@ -2128,7 +2160,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) Temp scratch = scratch_begin(&arena, 1); { //- rjf: unpack type of expression - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, expr); + E_IRTreeAndType lhs_irtree = *irtree; E_TypeKey lhs_type_key = lhs_irtree.type_key; E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); @@ -2482,12 +2514,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(file) E_TYPE_EXPAND_INFO_FUNCTION_DEF(file) { - E_FileAccel *accel = push_array(arena, E_FileAccel, 1); - { - Temp scratch = scratch_begin(&arena, 1); - - scratch_end(scratch); - } + E_FileAccel *accel = (E_FileAccel *)irtree->user_data; E_TypeExpandInfo info = {accel, accel->fields.count}; return info; } diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index d57d3e37..8217065c 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -164,6 +164,10 @@ struct E_TypeState E_ConsTypeSlot *cons_content_slots; E_ConsTypeSlot *cons_key_slots; + // rjf: build-in constructed type keys + E_TypeKey file_type_key; + E_TypeKey folder_type_key; + // rjf: member cache table U64 member_cache_slots_count; E_MemberCacheSlot *member_cache_slots; @@ -235,6 +239,8 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_base(Type *type); +internal E_TypeKey e_type_key_file(void); +internal E_TypeKey e_type_key_folder(void); //- rjf: basic type key functions internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); @@ -275,4 +281,28 @@ internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) Default Hooks + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(default); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `folder` type + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(folder); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(folder); + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `file` type + +E_TYPE_IRGEN_FUNCTION_DEF(file); +E_TYPE_ACCESS_FUNCTION_DEF(file); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(file); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file); + #endif // EVAL_TYPES_H diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index d94cd5cb..f4dc6cc8 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -553,9 +553,11 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); - tree.root->key = root_key; - tree.root->string = str8_zero(); - tree.root->eval = e_eval_from_expr(arena, root_expr); + tree.root->key = root_key; + tree.root->string = str8_zero(); + tree.root->eval = e_eval_from_expr(arena, root_expr); + tree.root->type_expand_rule = &e_type_expand_rule__default; + tree.root->viz_expand_rule = &ev_nil_expand_rule; tree.root->row_count = 1; tree.total_row_count += 1; tree.total_item_count += 1; @@ -615,7 +617,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp } // rjf: get top-level lookup/expansion info - E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, &t->eval.irtree, filter); + E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr, viz_expand_rule_tag); // rjf: determine expansion info @@ -731,7 +733,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Expr *child_expr = &e_expr_nil; String8 child_string = {0}; - type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); + type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, &t->eval.irtree, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); if(child_expr != &e_expr_nil) { E_Eval child_eval = e_eval_from_expr(arena, child_expr); @@ -1038,7 +1040,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } else { - n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval.expr, filter, block_relative_range__windowed, range_exprs, range_exprs_strings); + n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval.expr, &n->v.block->eval.irtree, filter, block_relative_range__windowed, range_exprs, range_exprs_strings); } // rjf: no expansion operator applied -> push row for block expression; pass through block info diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ed46e37b..a923f1a1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9158,7 +9158,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f U32 min_digits = 0; B32 no_addr = 0; B32 no_string = 0; -#if 0 // TODO(rjf): @eval for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) { if(0){} @@ -9176,7 +9175,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f min_digits = (U32)num_value_eval.value.u64; } } -#endif //- rjf: force no_addr in non-address-spaces if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || @@ -9388,7 +9386,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f E_IRTreeAndType irtree = eval.irtree; E_LookupRule *lookup_rule = &e_lookup_rule__default; E_Expr *lookup_rule_tag = &e_expr_nil; -#if 0 // TODO(rjf): @eval E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; if(lookup_rule == &e_lookup_rule__default) @@ -9396,7 +9393,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f lookup_rule = root_eval.lookup_rule_tag.rule; lookup_rule_tag = root_eval.lookup_rule_tag.tag; } -#endif E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("["); @@ -9530,7 +9526,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f E_IRTreeAndType irtree = eval.irtree; E_LookupRule *lookup_rule = &e_lookup_rule__default; E_Expr *lookup_rule_tag = &e_expr_nil; -#if 0 // TODO(rjf): @eval E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; if(lookup_rule == &e_lookup_rule__default) @@ -9538,7 +9533,6 @@ rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags f lookup_rule = root_eval.lookup_rule_tag.rule; lookup_rule_tag = root_eval.lookup_rule_tag.tag; } -#endif E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); String8 opener_string = str8_lit("{"); @@ -12459,17 +12453,16 @@ rd_frame(void) } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) -#if 0 // TODO(rjf): @eval { struct { String8 name; - E_LookupInfoFunctionType *lookup_info; - E_LookupRangeFunctionType *lookup_range; + E_TypeExpandInfoFunctionType *info; + E_TypeExpandRangeFunctionType *range; } collection_infos[] = { -#define Collection(name) {str8_lit_comp(#name), E_LOOKUP_INFO_FUNCTION_NAME(name), E_LOOKUP_RANGE_FUNCTION_NAME(name)} +#define Collection(name) {str8_lit_comp(#name), E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)} Collection(locals), Collection(registers), #undef Collection @@ -12478,14 +12471,17 @@ rd_frame(void) { String8 collection_name = collection_infos[idx].name; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = collection_name, + .expand = + { + .info = collection_infos[idx].info, + .range = collection_infos[idx].range, + }); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = collection_infos[idx].lookup_info, - .range = collection_infos[idx].lookup_range); } } -#endif //- rjf: add macros for debug info table collections #if 0 // TODO(rjf): @eval @@ -12509,25 +12505,30 @@ rd_frame(void) .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(debug_info_table)); } +#endif //- rjf: add macros for all config collections for EachElement(cfg_name_idx, evallable_cfg_names) { String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .irgen = E_TYPE_IRGEN_FUNCTION_NAME(cfgs), + .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs), + .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs), + }); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(cfgs), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(cfgs), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(cfgs), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(cfgs), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(cfgs)); } +#if 0 // TODO(rjf): @eval //- rjf: add macros for all ctrl entity collections for EachElement(ctrl_name_idx, evallable_ctrl_names) { diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 275b7cd2..80ae6ae1 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -277,18 +277,45 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) //////////////////////////////// //~ rjf: Schema Type Hooks -#if 0 // TODO(rjf): @eval +typedef struct RD_SchemaIRExt RD_SchemaIRExt; +struct RD_SchemaIRExt +{ + RD_Cfg *cfg; + CTRL_Entity *entity; + MD_Node *schema; +}; + +E_TYPE_IRGEN_FUNCTION_DEF(schema) +{ + E_IRTreeAndType result = *irtree; + RD_SchemaIRExt *ext = push_array(arena, RD_SchemaIRExt, 1); + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + E_TypeKey type_key = irtree->type_key; + E_Type *type = e_type_from_key__cached(type_key); + MD_Node *schema = rd_schema_from_name(type->name); + ext->cfg = rd_cfg_from_eval_space(interpret.space); + ext->entity = rd_ctrl_entity_from_eval_space(interpret.space); + ext->schema = schema; + scratch_end(scratch); + } + result.user_data = ext; + return result; +} E_TYPE_ACCESS_FUNCTION_DEF(schema) { - RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + RD_SchemaIRExt *ext = (RD_SchemaIRExt *)lhs_irtree->user_data; E_IRTreeAndType irtree = {&e_irnode_nil}; - if(kind == E_ExprKind_MemberAccess) + if(expr->kind == E_ExprKind_MemberAccess) { MD_Node *child_schema = &md_nil_node; - for MD_EachNode(child, accel->schema->first) + for MD_EachNode(child, ext->schema->first) { - if(str8_match(child->string, rhs->string, 0)) + if(str8_match(child->string, expr->first->next->string, 0)) { child_schema = child; break; @@ -296,8 +323,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) } if(child_schema != &md_nil_node) { - RD_Cfg *cfg = accel->cfg; - CTRL_Entity *entity = accel->entity; + RD_Cfg *cfg = ext->cfg; + CTRL_Entity *entity = ext->entity; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); E_TypeKey child_type_key = zero_struct; if(0){} @@ -380,16 +407,12 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) irtree.mode = E_Mode_Offset; } } - E_LookupAccess access = {irtree}; - return access; + return irtree; } -typedef struct RD_SchemaLookupAccel RD_SchemaLookupAccel; -struct RD_SchemaLookupAccel +typedef struct RD_SchemaExpandAccel RD_SchemaExpandAccel; +struct RD_SchemaExpandAccel { - RD_Cfg *cfg; - CTRL_Entity *entity; - MD_Node *schema; MD_Node **children; U64 children_count; }; @@ -401,12 +424,8 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) Temp scratch = scratch_begin(&arena, 1); // rjf: unpack - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); - E_Interpretation interpret = e_interpret(bytecode); - E_TypeKey type_key = lhs->type_key; - E_Type *type = e_type_from_key__cached(type_key); - MD_Node *schema = rd_schema_from_name(type->name); + RD_SchemaIRExt *ext = (RD_SchemaIRExt *)irtree->user_data; + MD_Node *schema = ext->schema; // rjf: gather expansion children typedef struct ExpandChildNode ExpandChildNode; @@ -444,10 +463,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) } // rjf: build accelerator for lookups - RD_SchemaLookupAccel *accel = push_array(arena, RD_SchemaLookupAccel, 1); - accel->cfg = rd_cfg_from_eval_space(interpret.space); - accel->entity = rd_ctrl_entity_from_eval_space(interpret.space); - accel->schema = schema; + RD_SchemaExpandAccel *accel = push_array(arena, RD_SchemaExpandAccel, 1); accel->children = children; accel->children_count = child_count; @@ -460,17 +476,16 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) return result; } -E_LOOKUP_RANGE_FUNCTION_DEF(schema) +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) { - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - RD_SchemaLookupAccel *accel = (RD_SchemaLookupAccel *)user_data; + RD_SchemaExpandAccel *accel = (RD_SchemaExpandAccel *)user_data; U64 out_idx = 0; for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { if(0 <= idx && idx < accel->children_count) { MD_Node *child_schema = accel->children[idx]; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, child_schema->string); + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, child_schema->string); } } } @@ -478,62 +493,33 @@ E_LOOKUP_RANGE_FUNCTION_DEF(schema) //////////////////////////////// //~ rjf: Config Collection Type Hooks -typedef struct RD_CfgCollectionLookupAccel RD_CfgCollectionLookupAccel; -struct RD_CfgCollectionLookupAccel +typedef struct RD_CfgsIRExt RD_CfgsIRExt; +struct RD_CfgsIRExt { + String8 cfg_name; String8Array cmds; RD_CfgArray cfgs; Rng1U64 cmds_idx_range; Rng1U64 cfgs_idx_range; }; -E_LOOKUP_INFO_FUNCTION_DEF(cfgs) +E_TYPE_IRGEN_FUNCTION_DEF(cfgs) { - E_LookupInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType result = *irtree; + RD_CfgsIRExt *ext = push_array(arena, RD_CfgsIRExt, 1); { - //- rjf: determine which cfg we'll use to scope the lookups - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - RD_Cfg *scoping_cfg = rd_cfg_from_eval_space(lhs_interp.space); + Temp scratch = scratch_begin(&arena, 1); - //- rjf: determine which kind of child we'll be gathering - E_TypeKey lhs_type_key = lhs->type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - String8 cfg_name = rd_singular_from_code_name_plural(lhs_type->name); + //- rjf: determine which key we'll be gathering + E_TypeKey type_key = irtree->type_key; + E_Type *type = e_type_from_key__cached(type_key); + String8 cfg_name = rd_singular_from_code_name_plural(type->name); //- rjf: gather cfgs - RD_CfgList cfgs_list = {0}; - if(scoping_cfg == &rd_nil_cfg) - { - cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); - } - else - { - cfgs_list = rd_cfg_child_list_from_string(scratch.arena, scoping_cfg, cfg_name); - } - - //- rjf: filter cfgs - RD_CfgList cfgs_list__filtered = cfgs_list; - if(filter.size != 0) - { - MemoryZeroStruct(&cfgs_list__filtered); - for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) - { - DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); - String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); - if(fuzzy_matches.count == fuzzy_matches.needle_part_count) - { - rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); - } - } - } + RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, cfg_name); //- rjf: gather commands String8List cmds_list = {0}; - if(filter.size == 0) { MD_Node *schema = rd_schema_from_name(cfg_name); MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); @@ -544,67 +530,107 @@ E_LOOKUP_INFO_FUNCTION_DEF(cfgs) } //- rjf: package & fill - RD_CfgCollectionLookupAccel *accel = push_array(arena, RD_CfgCollectionLookupAccel, 1); - accel->cfgs = rd_cfg_array_from_list(arena, &cfgs_list__filtered); - accel->cmds = str8_array_from_list(arena, &cmds_list); - accel->cmds_idx_range = r1u64(0, accel->cmds.count); - accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); - result.user_data = accel; - result.idxed_expr_count = accel->cfgs.count + accel->cmds.count; + ext->cfg_name = cfg_name; + ext->cfgs = rd_cfg_array_from_list(arena, &cfgs_list); + ext->cmds = str8_array_from_list(arena, &cmds_list); + + scratch_end(scratch); } - scratch_end(scratch); + result.user_data = ext; return result; } -E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs) +E_TYPE_ACCESS_FUNCTION_DEF(cfgs) { - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = {{&e_irnode_nil}}; + E_IRTreeAndType result = {&e_irnode_nil}; RD_Cfg *cfg = &rd_nil_cfg; - if(kind == E_ExprKind_MemberAccess) + RD_CfgsIRExt *ext = (RD_CfgsIRExt *)lhs_irtree->user_data; + switch(expr->kind) { - String8 rhs_name = rhs->string; - RD_CfgID id = 0; - if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && - try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + default:{}break; + case E_ExprKind_ArrayIndex: { - cfg = rd_cfg_from_id(id); - } - } - else if(kind == E_ExprKind_ArrayIndex) - { - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - U64 rhs_idx = rhs_value.u64; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; - if(0 <= rhs_idx && rhs_idx < accel->cfgs.count) + E_Value rhs_value = e_value_from_expr(expr->first->next); + U64 rhs_idx = rhs_value.u64; + if(0 <= rhs_idx && rhs_idx < ext->cfgs.count) + { + cfg = ext->cfgs.v[rhs_idx]; + } + }break; + case E_ExprKind_MemberAccess: { - cfg = accel->cfgs.v[rhs_idx]; - } + String8 rhs_name = expr->first->next->string; + RD_CfgID id = 0; + if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && + try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + { + cfg = rd_cfg_from_id(id); + } + }break; } if(cfg != &rd_nil_cfg) { - E_Space cfg_space = rd_eval_space_from_cfg(cfg); - String8 cfg_name = cfg->string; - E_TypeKey cfg_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg_name); - result.irtree_and_type.root = e_irtree_set_space(arena, cfg_space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = cfg_type_key; - result.irtree_and_type.mode = E_Mode_Offset; + result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.mode = E_Mode_Offset; + result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ext->cfg_name); } - scratch_end(scratch); return result; } -E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) +typedef struct RD_CfgsExpandAccel RD_CfgsExpandAccel; +struct RD_CfgsExpandAccel { - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + String8Array cmds; + RD_CfgArray cfgs; + Rng1U64 cmds_idx_range; + Rng1U64 cfgs_idx_range; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs) +{ + RD_CfgsExpandAccel *accel = push_array(arena, RD_CfgsExpandAccel, 1); + E_TypeExpandInfo info = {accel}; + Temp scratch = scratch_begin(&arena, 1); + { + //- rjf: unpack + RD_CfgsIRExt *ext = (RD_CfgsIRExt *)irtree->user_data; + + //- rjf: filter cfgs + RD_CfgArray cfgs__filtered = ext->cfgs; + if(filter.size != 0) + { + RD_CfgList cfgs_list__filtered = {0}; + for EachIndex(idx, ext->cfgs.count) + { + RD_Cfg *cfg = ext->cfgs.v[idx]; + DR_FStrList fstrs = rd_title_fstrs_from_cfg(scratch.arena, cfg); + String8 string = dr_string_from_fstrs(scratch.arena, &fstrs); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, filter, string); + if(fuzzy_matches.count == fuzzy_matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, cfg); + } + } + cfgs__filtered = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + } + + //- rjf: fill + accel->cmds = ext->cmds; + accel->cfgs = cfgs__filtered; + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); + info.expr_count = (accel->cmds.count + accel->cfgs.count); + } + scratch_end(scratch); + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) +{ + RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; Rng1U64 cmds_idx_range = accel->cmds_idx_range; Rng1U64 cfgs_idx_range = accel->cfgs_idx_range; U64 dst_idx = 0; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); // rjf: fill commands { @@ -615,7 +641,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - exprs[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); + exprs_out[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); } } @@ -626,15 +652,15 @@ E_LOOKUP_RANGE_FUNCTION_DEF(cfgs) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - exprs[dst_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, push_str8f(arena, "$%I64d", cfg->id)); + exprs_out[dst_idx] = e_expr_irext_member_access(arena, expr, irtree, push_str8f(arena, "$%I64d", cfg->id)); } } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs) { U64 id = 0; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; if(num != 0) { U64 idx = num-1; @@ -652,10 +678,10 @@ E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs) return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs) { U64 num = 0; - RD_CfgCollectionLookupAccel *accel = (RD_CfgCollectionLookupAccel *)user_data; + RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; if(id != 0) { if(id & (1ull<<63)) @@ -675,6 +701,7 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs) return num; } +#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `call_stack` Type Hooks diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index d8c6af28..d53d6b9a 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -23,18 +23,17 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); //~ rjf: `locals` Type Hooks E_TYPE_EXPAND_INFO_FUNCTION_DEF(locals); -E_LOOKUP_RANGE_FUNCTION_DEF(locals); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals); //////////////////////////////// //~ rjf: `registers` Type Hooks -E_LOOKUP_INFO_FUNCTION_DEF(registers); -E_LOOKUP_RANGE_FUNCTION_DEF(registers); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers); //////////////////////////////// //~ rjf: Schema Type Hooks -#if 0 // TODO(rjf): @eval E_TYPE_ACCESS_FUNCTION_DEF(schema); E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); @@ -42,12 +41,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); //////////////////////////////// //~ rjf: Config Collection Type Hooks -E_LOOKUP_INFO_FUNCTION_DEF(cfgs); -E_LOOKUP_ACCESS_FUNCTION_DEF(cfgs); -E_LOOKUP_RANGE_FUNCTION_DEF(cfgs); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(cfgs); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(cfgs); +E_TYPE_IRGEN_FUNCTION_DEF(cfgs); +E_TYPE_ACCESS_FUNCTION_DEF(cfgs); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs); +#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `call_stack` Type Hooks From ac65d7fc348f269e1e0cc63a93447e51587cd3bb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 8 Apr 2025 19:46:48 -0700 Subject: [PATCH 328/755] fix incorrect type info generation of schema'd evaluations --- src/raddbg/raddbg_core.c | 3 +-- src/raddbg/raddbg_eval.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a923f1a1..cd21c54e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12285,12 +12285,12 @@ rd_frame(void) //- rjf: cache meta name -> type key correllation rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); -#if 0 // TODO(rjf): @eval for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set, + .irgen = E_TYPE_IRGEN_FUNCTION_NAME(schema), .access = E_TYPE_ACCESS_FUNCTION_NAME(schema), .expand = { @@ -12299,7 +12299,6 @@ rd_frame(void) }); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); } -#endif //- rjf: add macros for evallable top-level config trees String8 evallable_cfg_names[] = diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index d53d6b9a..2ea93701 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -34,6 +34,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers); //////////////////////////////// //~ rjf: Schema Type Hooks +E_TYPE_IRGEN_FUNCTION_DEF(schema); E_TYPE_ACCESS_FUNCTION_DEF(schema); E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); From cde079a14d3f65f56f1dd6b6329339e9af606732 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 9 Apr 2025 13:05:29 -0700 Subject: [PATCH 329/755] checkpoint in moving to new type-based view rule / synthetic structure hooks --- src/ctrl/ctrl_core.c | 47 ++++---- src/ctrl/ctrl_core.h | 9 +- src/dbg_engine/dbg_engine_core.c | 27 ++--- src/eval/eval_types.c | 1 + src/raddbg/raddbg_core.c | 100 +++++++++------- src/raddbg/raddbg_eval.c | 190 +++++++++++++++---------------- src/raddbg/raddbg_eval.h | 19 ++-- src/raddbg/raddbg_views.c | 12 +- src/raddbg/raddbg_widgets.c | 2 +- 9 files changed, 215 insertions(+), 192 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index f33b082d..c9d16e95 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -669,7 +669,7 @@ ctrl_entity_store_alloc(void) store->hash_slots = push_array(arena, CTRL_EntityHashSlot, store->hash_slots_count); for EachEnumVal(CTRL_EntityKind, k) { - store->entity_kind_lists_arenas[k] = arena_alloc(); + store->entity_kind_arrays_arenas[k] = arena_alloc(); } CTRL_Entity *root = store->root = ctrl_entity_alloc(store, &ctrl_entity_nil, CTRL_EntityKind_Root, Arch_Null, ctrl_handle_zero(), 0); CTRL_Entity *local_machine = ctrl_entity_alloc(store, root, CTRL_EntityKind_Machine, arch_from_context(), ctrl_handle_make(CTRL_MachineID_Local, dmn_handle_zero()), 0); @@ -1029,10 +1029,10 @@ internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key) { CTRL_EntityList list = {0}; - CTRL_EntityList all_modules = ctrl_entity_list_from_kind(store, CTRL_EntityKind_Module); - for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next) + CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Module); + for EachIndex(idx, all_modules.count) { - CTRL_Entity *module = n->v; + CTRL_Entity *module = all_modules.v[idx]; DI_Key module_dbgi_key = ctrl_dbgi_key_from_module(module); if(di_key_match(&module_dbgi_key, dbgi_key)) { @@ -1065,25 +1065,28 @@ ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, return module; } -internal CTRL_EntityList -ctrl_entity_list_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind) +internal CTRL_EntityArray +ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind) { - if(store->entity_kind_lists_gens[kind] != store->entity_kind_alloc_gens[kind]) + if(store->entity_kind_arrays_gens[kind] != store->entity_kind_alloc_gens[kind]) { - arena_clear(store->entity_kind_lists_arenas[kind]); - MemoryZeroStruct(&store->entity_kind_lists[kind]); + Temp scratch = scratch_begin(0, 0); + CTRL_EntityList entities = {0}; for(CTRL_Entity *e = store->root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, store->root).next) { if(e->kind == kind) { - ctrl_entity_list_push(store->entity_kind_lists_arenas[kind], &store->entity_kind_lists[kind], e); + ctrl_entity_list_push(scratch.arena, &entities, e); } } - store->entity_kind_lists_gens[kind] = store->entity_kind_alloc_gens[kind]; + store->entity_kind_arrays_gens[kind] = store->entity_kind_alloc_gens[kind]; + arena_clear(store->entity_kind_arrays_arenas[kind]); + store->entity_kind_arrays[kind] = ctrl_entity_array_from_list(store->entity_kind_arrays_arenas[kind], &entities); + scratch_end(scratch); } - return store->entity_kind_lists[kind]; + return store->entity_kind_arrays[kind]; } internal U64 @@ -1202,13 +1205,14 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) { ctrl_entity_equip_string(store, thread, str8_lit("main_thread")); } - CTRL_EntityList pending_thread_names = ctrl_entity_list_from_kind(store, CTRL_EntityKind_PendingThreadName); - for(CTRL_EntityNode *n = pending_thread_names.first; n != 0; n = n->next) + CTRL_EntityArray pending_thread_names = ctrl_entity_array_from_kind(store, CTRL_EntityKind_PendingThreadName); + for EachIndex(idx, pending_thread_names.count) { - if(n->v->id == event->entity_id) + CTRL_Entity *entity = pending_thread_names.v[idx]; + if(entity->id == event->entity_id) { - ctrl_entity_equip_string(store, thread, n->v->string); - ctrl_entity_release(store, n->v); + ctrl_entity_equip_string(store, thread, entity->string); + ctrl_entity_release(store, entity); break; } } @@ -4920,7 +4924,7 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) U32 exit_code = msg->exit_code; //- rjf: gather all currently existing processes - CTRL_EntityList initial_processes = ctrl_entity_list_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray initial_processes = ctrl_entity_array_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); typedef struct Task Task; struct Task { @@ -4930,10 +4934,11 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) }; Task *first_task = 0; Task *last_task = 0; - for(CTRL_EntityNode *n = initial_processes.first; n != 0; n = n->next) + for EachIndex(idx, initial_processes.count) { + CTRL_Entity *entity = initial_processes.v[idx]; Task *t = push_array(scratch.arena, Task, 1); - t->process = n->v; + t->process = entity; DLLPushBack(first_task, last_task, t); } @@ -4974,7 +4979,7 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } // rjf: end if all processes are gone - CTRL_EntityList processes = ctrl_entity_list_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); if(processes.count == 0) { done = 1; diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 114834fd..5d5642f8 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -140,10 +140,10 @@ struct CTRL_EntityStore U64 hash_slots_count; CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)]; U64 entity_kind_counts[CTRL_EntityKind_COUNT]; - Arena *entity_kind_lists_arenas[CTRL_EntityKind_COUNT]; - U64 entity_kind_lists_gens[CTRL_EntityKind_COUNT]; + Arena *entity_kind_arrays_arenas[CTRL_EntityKind_COUNT]; + U64 entity_kind_arrays_gens[CTRL_EntityKind_COUNT]; U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT]; - CTRL_EntityList entity_kind_lists[CTRL_EntityKind_COUNT]; + CTRL_EntityArray entity_kind_arrays[CTRL_EntityKind_COUNT]; }; //////////////////////////////// @@ -803,6 +803,7 @@ internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_En //- rjf: entity array data structure internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list); +#define ctrl_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &ctrl_entity_nil) //- rjf: cache creation/destruction internal CTRL_EntityStore *ctrl_entity_store_alloc(void); @@ -829,7 +830,7 @@ internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 v internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates); -internal CTRL_EntityList ctrl_entity_list_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind); +internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind); internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff); internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr); internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range); diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index ee357f51..dec0cf0d 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1369,10 +1369,10 @@ internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena) { DI_KeyList dbgis = {0}; - CTRL_EntityList modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); - for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next) + CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + for EachIndex(idx, modules.count) { - CTRL_Entity *module = n->v; + CTRL_Entity *module = modules.v[idx]; DI_Key key = ctrl_dbgi_key_from_module(module); di_key_list_push(arena, &dbgis, &key); } @@ -1803,7 +1803,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case CTRL_EventKind_NewProc: { // rjf: the first process? -> clear session output - CTRL_EntityList existing_processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray existing_processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(existing_processes.count == 1) { MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; @@ -1886,10 +1886,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: build data strings of all param data String8List strings = {0}; { - CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); - for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) + CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) { - CTRL_Entity *thread = n->v; + CTRL_Entity *thread = threads.v[idx]; if(thread->is_frozen) { str8_list_push(scratch.arena, &strings, str8_struct(&thread->id)); @@ -2097,12 +2097,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_Continue: { B32 good_to_run = 0; - CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); if(threads.count > 0) { - for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) + for EachIndex(idx, threads.count) { - if(!n->v->is_frozen) + CTRL_Entity *thread = threads.v[idx]; + if(!thread->is_frozen) { good_to_run = 1; break; @@ -2252,7 +2253,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Run: { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count != 0) { d_cmd(D_CmdKind_Continue); @@ -2264,7 +2265,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Restart: { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count != 0) { d_cmd(D_CmdKind_KillAll); @@ -2274,7 +2275,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepInto: case D_CmdKind_StepOver: { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count != 0) { D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index b393266b..96773dc3 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -416,6 +416,7 @@ e_type_key_cons_(E_ConsTypeParams *params) node->params.name = push_str8_copy(e_type_state->arena, params->name); if(node->params.expand.info != 0) { + if(node->params.expand.range == 0) {node->params.expand.range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default);} if(node->params.expand.id_from_num == 0) {node->params.expand.id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity);} if(node->params.expand.num_from_id == 0) {node->params.expand.num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity);} } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cd21c54e..2f63d32b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2280,7 +2280,7 @@ rd_view_ui(Rng2F32 rect) UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) { RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); //- rjf: icon & info UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") @@ -6072,7 +6072,7 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_AddTarget, .file_path = n->string); } - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count != 0) { rd_cmd(RD_CmdKind_KillAll); @@ -6091,7 +6091,7 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_AddTarget, .file_path = n->string); } - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count != 0) { rd_cmd(RD_CmdKind_KillAll); @@ -7075,7 +7075,7 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); B32 have_targets = (targets.count != 0); B32 can_send_signal = !d_ctrl_targets_running(); B32 can_play = (have_targets && (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())); @@ -12201,7 +12201,7 @@ rd_frame(void) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); U64 tls_root_vaddr = ctrl_query_cached_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle); - CTRL_EntityList all_modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); U64 eval_modules_count = Max(1, all_modules.count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; @@ -12210,10 +12210,9 @@ rd_frame(void) DI_Key primary_dbgi_key = {0}; ProfScope("produce all eval modules") { - U64 eval_module_idx = 0; - for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, eval_module_idx += 1) + for EachIndex(eval_module_idx, all_modules.count) { - CTRL_Entity *m = n->v; + CTRL_Entity *m = all_modules.v[eval_module_idx]; 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(rd_state->frame_di_scope, &dbgi_key, 0); @@ -12376,11 +12375,11 @@ rd_frame(void) { String8 name = evallable_ctrl_names[idx]; CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); - CTRL_EntityList list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, kind); + CTRL_EntityArray array = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, kind); E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + for EachIndex(idx, array.count) { - CTRL_Entity *entity = n->v; + CTRL_Entity *entity = array.v[idx]; E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = space; @@ -12446,9 +12445,18 @@ rd_frame(void) .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment), })); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), - e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack"))); #endif + e_string2typekey_map_insert(rd_frame_arena(), + rd_state->meta_name2type_map, + str8_lit("call_stack"), + e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("call_stack"), + .irgen = E_TYPE_IRGEN_FUNCTION_NAME(call_stack), + .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(call_stack), + })); } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) @@ -12483,7 +12491,6 @@ rd_frame(void) } //- rjf: add macros for debug info table collections -#if 0 // TODO(rjf): @eval String8 debug_info_table_collection_names[] = { str8_lit_comp("procedures"), @@ -12495,16 +12502,18 @@ rd_frame(void) { String8 name = debug_info_table_collection_names[idx]; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = name, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(debug_info_table), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(debug_info_table), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(debug_info_table) + }); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(debug_info_table), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(debug_info_table), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(debug_info_table)); } -#endif //- rjf: add macros for all config collections for EachElement(cfg_name_idx, evallable_cfg_names) @@ -12527,23 +12536,26 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); } -#if 0 // TODO(rjf): @eval //- rjf: add macros for all ctrl entity collections for EachElement(ctrl_name_idx, evallable_ctrl_names) { String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; String8 collection_name = rd_plural_from_code_name(kind_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = collection_name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(ctrl_entities), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(ctrl_entities), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(ctrl_entities) + }); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(ctrl_entities), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(ctrl_entities), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(ctrl_entities)); } +#if 0 // TODO(rjf): @eval //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); @@ -12556,21 +12568,24 @@ rd_frame(void) .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); } +#endif //- rjf: add macro for commands { String8 name = str8_lit("commands"); - E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = name); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), + }); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, name, - .info = E_LOOKUP_INFO_FUNCTION_NAME(commands), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(commands), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(commands)); } -#endif //- rjf: add macro for output log { @@ -12606,17 +12621,18 @@ rd_frame(void) //- rjf: gather auto-view-rules from loaded modules RD_CfgList immediate_auto_view_rules = {0}; - CTRL_EntityList modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); - for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next) + CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + for EachIndex(idx, modules.count) { - String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, n->v->handle); + CTRL_Entity *module = modules.v[idx]; + String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, module->handle); U8 split_char = 0; String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) { String8 text = text_n->string; RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); - RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, n->v->handle)); + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, module->handle)); for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); @@ -12757,7 +12773,7 @@ rd_frame(void) case RD_CmdKind_StepOver: case RD_CmdKind_Restart: { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count == 0 || kind == RD_CmdKind_Restart) { RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); @@ -12837,7 +12853,7 @@ rd_frame(void) { // rjf: if control processes are live, but this is not force-confirmed, then // get confirmation from user - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation")); if(processes.count != 0 && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key)) { @@ -16167,7 +16183,7 @@ Z(getting_started) case D_EventKind_ProcessEnd: if(rd_state->quit_after_success) { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(evt->code == 0 && processes.count == 0) { rd_cmd(RD_CmdKind_Exit); @@ -16204,8 +16220,8 @@ Z(getting_started) // rjf: no stop-causing thread, but don't have selected thread? -> snap to first available thread if(need_refocus && thread == &ctrl_entity_nil && selected_thread == &ctrl_entity_nil) { - CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); - CTRL_Entity *first_available_thread = ctrl_entity_list_first(&threads); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_Entity *first_available_thread = ctrl_entity_array_first(&threads); rd_cmd(RD_CmdKind_SelectThread, .thread = first_available_thread->handle); } diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 80ae6ae1..98eb4a48 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -701,25 +701,24 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs) return num; } -#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `call_stack` Type Hooks -typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel; -struct RD_CallStackLookupAccel +typedef struct RD_CallStackAccel RD_CallStackAccel; +struct RD_CallStackAccel { Arch arch; CTRL_Handle process; CTRL_CallStack call_stack; }; -E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) +E_TYPE_IRGEN_FUNCTION_DEF(call_stack) { - E_TypeExpandInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType result = *irtree; + RD_CallStackAccel *accel = push_array(arena, RD_CallStackAccel, 1); { - RD_CallStackLookupAccel *accel = push_array(arena, RD_CallStackLookupAccel, 1); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interp = e_interpret(bytecode); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); @@ -730,40 +729,44 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) accel->arch = entity->arch; accel->process = process->handle; accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); - result.expr_count = accel->call_stack.count; } - result.user_data = accel; + scratch_end(scratch); } - scratch_end(scratch); + result.user_data = accel; return result; } E_TYPE_ACCESS_FUNCTION_DEF(call_stack) { - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex) { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data; + RD_CallStackAccel *accel = (RD_CallStackAccel *)lhs_irtree->user_data; + E_Value rhs_value = e_value_from_expr(expr->first->next); CTRL_CallStack *call_stack = &accel->call_stack; if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) { CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); - result.irtree_and_type.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); - result.irtree_and_type.mode = E_Mode_Value; + result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); + result.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + result.mode = E_Mode_Value; } - scratch_end(scratch); } return result; } +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) +{ + RD_CallStackAccel *accel = (RD_CallStackAccel *)irtree->user_data; + E_TypeExpandInfo result = {0}; + result.user_data = accel; + result.expr_count = accel->call_stack.count; + return result; +} + +#if 0 // TODO(rjf): @eval + //////////////////////////////// //~ rjf: `environment` Type Hooks @@ -988,17 +991,57 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) exprs_out[out_idx] = expr; } } +#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) +E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + { + CTRL_Entity *entity = &ctrl_entity_nil; + switch(expr->kind) + { + case E_ExprKind_MemberAccess: + { + String8 rhs_name = expr->first->next->string; + CTRL_Handle handle = ctrl_handle_from_string(rhs_name); + entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + }break; + case E_ExprKind_ArrayIndex: + { + E_Type *type = e_type_from_key__cached(lhs_irtree->type_key); + CTRL_EntityKind kind = ctrl_entity_kind_from_string(rd_singular_from_code_name_plural(type->name)); + E_Value rhs_value = e_value_from_expr(expr->first->next); + U64 rhs_idx = rhs_value.u64; + CTRL_EntityArray entities = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, kind); + if(0 <= rhs_idx && rhs_idx < entities.count) + { + entity = entities.v[rhs_idx]; + } + }break; + } + if(entity != &ctrl_entity_nil) + { + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + String8 name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.type_key = type_key; + result.mode = E_Mode_Offset; + } + } + return result; +} + E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) { E_TypeExpandInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { //- rjf: determine which entity we're looking under - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); E_Interpretation lhs_interp = e_interpret(lhs_bytecode); CTRL_Entity *scoping_entity = &ctrl_entity_nil; @@ -1008,27 +1051,20 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) } //- rjf: determine which type of child we're gathering - E_TypeKey lhs_type_key = lhs->type_key; + E_TypeKey lhs_type_key = irtree->type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 name = rd_singular_from_code_name_plural(lhs_type->name); - CTRL_EntityKind entity_kind = CTRL_EntityKind_Null; - for EachNonZeroEnumVal(CTRL_EntityKind, k) - { - if(str8_match(name, ctrl_entity_kind_code_name_table[k], 0)) - { - entity_kind = k; - break; - } - } + CTRL_EntityKind entity_kind = ctrl_entity_kind_from_string(name); - //- rjf: gather list of all entities which fit the bill - CTRL_EntityList list = {0}; + //- rjf: gather array of all entities which fit the bill + CTRL_EntityArray array = {0}; if(scoping_entity == &ctrl_entity_nil) { - list = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, entity_kind); + array = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, entity_kind); } else { + CTRL_EntityList list = {0}; for(CTRL_Entity *child = scoping_entity->first; child != &ctrl_entity_nil; child = child->next) { if(child->kind == entity_kind) @@ -1036,16 +1072,17 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) ctrl_entity_list_push(scratch.arena, &list, child); } } + array = ctrl_entity_array_from_list(arena, &list); } - //- rjf: filter the list - CTRL_EntityList list__filtered = list; + //- rjf: filter the array + CTRL_EntityArray array__filtered = array; if(filter.size != 0) { - MemoryZeroStruct(&list__filtered); - for(CTRL_EntityNode *n = list.first; n != 0; n = n->next) + CTRL_EntityList list__filtered = {0}; + for EachIndex(idx, array.count) { - CTRL_Entity *entity = n->v; + CTRL_Entity *entity = array.v[idx]; DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, entity, 1); String8 title_string = dr_string_from_fstrs(scratch.arena, &fstrs); FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, title_string); @@ -1054,67 +1091,29 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) ctrl_entity_list_push(scratch.arena, &list__filtered, entity); } } + array__filtered = ctrl_entity_array_from_list(arena, &list__filtered); } //- rjf: list -> array & fill - CTRL_EntityArray *array = push_array(arena, CTRL_EntityArray, 1); - *array = ctrl_entity_array_from_list(arena, &list__filtered); - result.user_data = array; - result.idxed_expr_count = array->count; + CTRL_EntityArray *accel = push_array(arena, CTRL_EntityArray, 1); + *accel = array__filtered; + result.user_data = accel; + result.expr_count = accel->count; } scratch_end(scratch); return result; } -E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupAccess result = {{&e_irnode_nil}}; - CTRL_Entity *entity = &ctrl_entity_nil; - if(kind == E_ExprKind_MemberAccess) - { - String8 rhs_name = rhs->string; - CTRL_Handle handle = ctrl_handle_from_string(rhs_name); - entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); - } - else if(kind == E_ExprKind_ArrayIndex) - { - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - U64 rhs_idx = rhs_value.u64; - CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; - if(0 <= rhs_idx && rhs_idx < entities->count) - { - entity = entities->v[rhs_idx]; - } - } - if(entity != &ctrl_entity_nil) - { - E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - String8 name = ctrl_entity_kind_code_name_table[entity->kind]; - E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = type_key; - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - return result; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities) +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(ctrl_entities) { CTRL_EntityArray *entities = (CTRL_EntityArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); Rng1U64 legal_range = r1u64(0, entities->count); Rng1U64 read_range = intersect_1u64(legal_range, idx_range); U64 read_count = dim_1u64(read_range); for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) { CTRL_Entity *entity = entities->v[out_idx + read_range.min]; - exprs[out_idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, ctrl_string_from_handle(arena, entity->handle)); + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, ctrl_string_from_handle(arena, entity->handle)); } } @@ -1130,14 +1129,14 @@ struct RD_DebugInfoTableLookupAccel DI_SearchItemArray items; }; -E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) +E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table) { Temp scratch = scratch_begin(&arena, 1); // rjf: determine which debug info section we're dealing with RDI_SectionKind section = RDI_SectionKind_NULL; { - E_TypeKey lhs_type_key = lhs->type_key; + E_TypeKey lhs_type_key = irtree->type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); if(0){} else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} @@ -1175,12 +1174,12 @@ E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table) rd_request_frame(); } } - E_LookupInfo info = {accel, 0, accel->items.count}; + E_TypeExpandInfo info = {accel, accel->items.count}; scratch_end(scratch); return info; } -E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) { RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; U64 needed_row_count = dim_1u64(idx_range); @@ -1277,11 +1276,11 @@ E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table) } // rjf: fill - exprs[idx] = item_expr; + exprs_out[idx] = item_expr; } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) { RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; U64 id = 0; @@ -1292,10 +1291,9 @@ E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(debug_info_table) { RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); return num; } -#endif diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 2ea93701..03e6c830 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -49,13 +49,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs); -#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `call_stack` Type Hooks -E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); +E_TYPE_IRGEN_FUNCTION_DEF(call_stack); E_TYPE_ACCESS_FUNCTION_DEF(call_stack); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); +#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `environment` Type Hooks @@ -70,21 +71,21 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment); E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes); +#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) +E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities); E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities); -E_LOOKUP_ACCESS_FUNCTION_DEF(ctrl_entities); -E_LOOKUP_RANGE_FUNCTION_DEF(ctrl_entities); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(ctrl_entities); //////////////////////////////// //~ rjf: Debug Info Tables Eval Hooks -E_LOOKUP_INFO_FUNCTION_DEF(debug_info_table); -E_LOOKUP_RANGE_FUNCTION_DEF(debug_info_table); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(debug_info_table); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(debug_info_table); -#endif +E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(debug_info_table); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(debug_info_table); #endif // RADDBG_EVAL_H diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b67927c5..8a8ba428 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -260,10 +260,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(!dasm_lines) ProfScope("find live threads mapping to this file") { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); - for(CTRL_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next) + CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) { - CTRL_Entity *thread = thread_n->v; + CTRL_Entity *thread = threads.v[idx]; CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); U64 unwind_count = (thread == selected_thread) ? rd_regs()->unwind_count : 0; U64 inline_depth = (thread == selected_thread) ? rd_regs()->inline_depth : 0; @@ -336,10 +336,10 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(dasm_lines) ProfScope("find live threads mapping to this disassembly") { CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); - for(CTRL_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next) + CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) { - CTRL_Entity *thread = thread_n->v; + CTRL_Entity *thread = threads.v[idx]; U64 unwind_count = (thread == selected_thread) ? rd_regs()->unwind_count : 0; U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count); if(ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process) == process && contains_1u64(dasm_vaddr_range, rip_vaddr)) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 51c99ac5..1ec9c77a 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -451,7 +451,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e if(entity->kind == CTRL_EntityKind_Thread || entity->kind == CTRL_EntityKind_Module) { - CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count > 1) { CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); From fbe747a8b444e381b33b0439d63376f9a786a8dd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 9 Apr 2025 16:44:02 -0700 Subject: [PATCH 330/755] further work on convergence, dead code elimination, and lens (view rule) calls --- src/ctrl/ctrl_core.c | 6 - src/eval/eval_core.h | 39 -- src/eval/eval_ir.c | 278 ++---------- src/eval/eval_ir.h | 63 --- src/eval/eval_parse.c | 54 +-- src/eval/eval_types.c | 24 +- .../eval_visualization_core.c | 394 +++++++++++++----- .../eval_visualization_core.h | 29 +- src/mule/mule_main.cpp | 4 + src/raddbg/raddbg_core.c | 54 ++- src/raddbg/raddbg_eval.c | 121 +++--- src/raddbg/raddbg_eval.h | 7 +- src/raddbg/raddbg_views.c | 4 +- 13 files changed, 476 insertions(+), 601 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index c9d16e95..0e3ec2a7 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4699,12 +4699,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(arena, 512); -#if 0 // TODO(rjf): @eval - ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); - ctx->lookup_rule_map[0] = e_lookup_rule_map_make(arena, 512); - ctx->irgen_rule_map = push_array(arena, E_IRGenRuleMap, 1); - ctx->irgen_rule_map[0] = e_irgen_rule_map_make(arena, 512); -#endif ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); ctx->auto_hook_map[0] = e_auto_hook_map_make(arena, 512); } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 78a7021c..62bf70a7 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -581,45 +581,6 @@ struct E_LookupRuleExprPair }; #endif -//////////////////////////////// -//~ rjf: IR Generation Hooks - -#if 0 // TODO(rjf): @eval -#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr) -#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name -#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) -typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); -E_IRGEN_FUNCTION_DEF(default); - -typedef struct E_IRGenRule E_IRGenRule; -struct E_IRGenRule -{ - String8 name; - E_IRGenFunctionType *irgen; -}; - -typedef struct E_IRGenRuleNode E_IRGenRuleNode; -struct E_IRGenRuleNode -{ - E_IRGenRuleNode *next; - E_IRGenRule v; -}; - -typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; -struct E_IRGenRuleSlot -{ - E_IRGenRuleNode *first; - E_IRGenRuleNode *last; -}; - -typedef struct E_IRGenRuleMap E_IRGenRuleMap; -struct E_IRGenRuleMap -{ - U64 slots_count; - E_IRGenRuleSlot *slots; -}; -#endif - //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 03cb1a7f..56e83ce2 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -699,150 +699,6 @@ E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) } #endif -//////////////////////////////// -//~ rjf: Lookups - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleMap -e_lookup_rule_map_make(Arena *arena, U64 slots_count) -{ - E_LookupRuleMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(default), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(file), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("only"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(only), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("omit"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(omit), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); - return map; -} - -internal void -e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) -{ - U64 hash = e_hash_from_string(5381, rule->name); - U64 slot_idx = hash%map->slots_count; - E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); - MemoryCopyStruct(&n->v, rule); - if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } - if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } - if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } - if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } - if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } - n->v.name = push_str8_copy(arena, n->v.name); -} - -internal E_LookupRule * -e_lookup_rule_from_string(String8 string) -{ - E_LookupRule *result = &e_lookup_rule__nil; - if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; - for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->v.name, string, 0)) - { - result = &n->v; - break; - } - } - } - return result; -} -#endif - -//////////////////////////////// -//~ rjf: IR Gen Rules - -#if 0 // TODO(rjf): @eval -E_IRGEN_FUNCTION_DEF(bswap) -{ - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); - e_irnode_push_child(root, irtree.root); - E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs}; - return result; -} - -E_IRGEN_FUNCTION_DEF(array) -{ - E_Expr *ptr_expr = expr->first->next; - E_Expr *count_expr = ptr_expr->next; - E_IRTreeAndType result = e_irtree_and_type_from_expr(arena, ptr_expr); - E_TypeKey element_type_key = e_type_ptee_from_key(result.type_key); - E_Value count_value = e_value_from_expr(count_expr); - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); - return result; -} - -internal E_IRGenRuleMap -e_irgen_rule_map_make(Arena *arena, U64 slots_count) -{ - E_IRGenRuleMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("default"), .irgen = E_IRGEN_FUNCTION_NAME(default)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); - return map; -} - -internal void -e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule) -{ - U64 hash = e_hash_from_string(5381, rule->name); - U64 slot_idx = hash%map->slots_count; - E_IRGenRuleNode *n = push_array(arena, E_IRGenRuleNode, 1); - MemoryCopyStruct(&n->v, rule); - n->v.name = push_str8_copy(arena, n->v.name); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); -} - -internal E_IRGenRule * -e_irgen_rule_from_string(String8 string) -{ - E_IRGenRule *rule = &e_irgen_rule__default; - if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->ctx->irgen_rule_map != 0 && e_ir_state->ctx->irgen_rule_map->slots_count != 0) - { - E_IRGenRuleMap *map = e_ir_state->ctx->irgen_rule_map; - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) - { - if(str8_match(string, n->v.name, 0)) - { - rule = &n->v; - break; - } - } - } - return rule; -} -#endif - //////////////////////////////// //~ rjf: Auto Hooks @@ -1658,8 +1514,47 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { default:{}break; - //- rjf: accesses + //- rjf: member accesses case E_ExprKind_MemberAccess: + { + // rjf: unpack left-hand-size + E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: if the right-hand-side is a call, then this is short-hand for + // the right-hand-side call, with the left-hand-side as the first argument. + E_Expr *rhs = lhs->next; + if(rhs->kind == E_ExprKind_Call) + { + E_Expr *rhs_copy = e_expr_copy(arena, rhs); + e_expr_insert_child(rhs_copy, rhs_copy->first, e_expr_ref(arena, lhs)); + result = e_irtree_and_type_from_expr(arena, rhs_copy); + } + + // rjf: if the right-hand-side is a leaf identifier, then this is an + // "access" to the left-hand-side. + else if(rhs->kind == E_ExprKind_LeafIdentifier) + { + // rjf: pick access hook based on type + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + E_TypeAccessFunctionType *lhs_access = lhs_type->access; + if(lhs_access == 0) + { + lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); + } + + // rjf: call into hook to do access + result = lhs_access(arena, expr, &lhs_irtree); + } + + // rjf: if the right-hand-side is anything else, this is an invalid formation. + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Expected identifier or call after `.`."); + } + }break; + + //- rjf: array indices case E_ExprKind_ArrayIndex: { // rjf: unpack left-hand-size @@ -1686,7 +1581,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey r_type_direct = e_type_direct_from_key(r_type); + E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(r_type)); U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -3181,94 +3076,3 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type e_expr_push_child(root, rhs_bytecode); return root; } - -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Rules - -#if 0 // TODO(rjf): @eval -internal E_LookupRule * -e_lookup_rule_from_type_key(E_TypeKey type_key) -{ - E_LookupRule *rule = &e_lookup_rule__default; - - // rjf: unpack type - E_Type *type = e_type_from_key__cached(type_key); - - // rjf: sets / lenses -> try to implicitly map to a rule based on name - if(type->kind == E_TypeKind_Set || type->kind == E_TypeKind_Lens) - { - E_LookupRule *candidate = e_lookup_rule_from_string(type->name); - if(candidate != &e_lookup_rule__nil) - { - rule = candidate; - } - } - - return rule; -} -#endif - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleExprPair -e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) -{ - E_LookupRuleExprPair result = {&e_lookup_rule__default, &e_expr_nil}; - { - // rjf: first try explicitly-stored tags - B32 default_is_forced = 0; - if(result.rule == &e_lookup_rule__default) - { - for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) - { - if(e_expr_is_poisoned(tag)) { continue; } - if(str8_match(tag->string, e_lookup_rule__default.name, 0)) - { - result.rule = &e_lookup_rule__default; - result.tag = &e_expr_nil; - default_is_forced = 1; - break; - } - E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - result.tag = tag; - } - } - } - - // rjf: next try implicit set name -> rule mapping - if(!default_is_forced && result.rule == &e_lookup_rule__default) - { - E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); - if(type_kind == E_TypeKind_Stub) - { - E_Type *type = e_type_from_key__cached(irtree->type_key); - String8 name = type->name; - E_LookupRule *candidate = e_lookup_rule_from_string(name); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - } - } - } - - // rjf: next try auto hook map - if(!default_is_forced && result.rule == &e_lookup_rule__default) - { - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); - for(E_ExprNode *n = tags.first; n != 0; n = n->next) - { - if(e_expr_is_poisoned(n->v)) { continue; } - E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - result.tag = n->v; - } - } - } - } - return result; -} -#endif diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 871527e2..dc266067 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -134,10 +134,6 @@ struct E_IRCtx E_String2ExprMap *macro_map; // rjf: hook maps -#if 0 // TODO(rjf): @eval - E_LookupRuleMap *lookup_rule_map; - E_IRGenRuleMap *irgen_rule_map; -#endif E_AutoHookMap *auto_hook_map; }; @@ -166,32 +162,6 @@ struct E_IRState //////////////////////////////// //~ rjf: Globals -#if 0 // TODO(rjf): @eval -local_persist read_only E_LookupRule e_lookup_rule__nil = -{ - str8_lit_comp("nil"), - E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_ACCESS_FUNCTION_NAME(default), - E_LOOKUP_RANGE_FUNCTION_NAME(default), - E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), -}; -local_persist read_only E_LookupRule e_lookup_rule__default = -{ - str8_lit_comp("default"), - E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_ACCESS_FUNCTION_NAME(default), - E_LOOKUP_RANGE_FUNCTION_NAME(default), - E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), -}; -local_persist read_only E_IRGenRule e_irgen_rule__default = -{ - str8_lit_comp("default"), - E_IRGEN_FUNCTION_NAME(default), -}; -#endif - global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRState *e_ir_state = 0; @@ -206,28 +176,6 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); internal void e_select_ir_ctx(E_IRCtx *ctx); -//////////////////////////////// -//~ rjf: Lookups - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); -internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); -#define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__}) - -internal E_LookupRule *e_lookup_rule_from_string(String8 string); -#endif - -//////////////////////////////// -//~ rjf: IR Gen Rules - -#if 0 // TODO(rjf): @eval -internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count); -internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule); -#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__}) - -internal E_IRGenRule *e_irgen_rule_from_string(String8 string); -#endif - //////////////////////////////// //~ rjf: Auto Hooks @@ -294,15 +242,4 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Rules - -#if 0 // TODO(rjf): @eval -internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key); -#endif - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); -#endif - #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index f93e91dd..9c46201f 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1208,7 +1208,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok B32 is_postfix_unary = 0; // rjf: dot/arrow operator - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 1 && + token.kind == E_TokenKind_Symbol && (str8_match(token_string, str8_lit("."), 0) || str8_match(token_string, str8_lit("->"), 0))) { @@ -1217,43 +1218,29 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: advance past operator it += 1; - // rjf: expect member name - String8 member_name = {0}; - B32 good_member_name = 0; - { - E_Token member_name_maybe = e_token_at_it(it, &tokens); - String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - if(member_name_maybe.kind != E_TokenKind_Identifier) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); - } - else - { - member_name = member_name_maybe_string; - good_member_name = 1; - } - } + // rjf: parse right-hand-side + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), 0, 1); + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + E_Expr *rhs = rhs_expr_parse.exprs.last; + it = rhs_expr_parse.last_token; - // rjf: produce lookup member expr - if(good_member_name) + // rjf: produce member access expr + if(rhs == &e_expr_nil) { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name.str); - member_expr->string = member_name; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `.`."); + } + else + { + E_Expr *lhs = atom; atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - - // rjf: increment past good member names - if(good_member_name) - { - it += 1; + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, rhs); } } // rjf: array index - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 1 && + token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) { is_postfix_unary = 1; @@ -1292,9 +1279,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } // rjf: calls - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 0 && + token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { + is_postfix_unary = 1; + // rjf: skip ( it += 1; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 96773dc3..936c7d9e 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -348,7 +348,8 @@ e_hash_from_cons_type_params(E_ConsTypeParams *params) internal B32 e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r) { - B32 result = (l->kind == r->kind && + B32 result = (l->kind != E_TypeKind_Lens && + l->kind == r->kind && l->flags == r->flags && str8_match(l->name, r->name, 0) && e_type_key_match(l->direct_key, r->direct_key) && @@ -1665,7 +1666,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr default: { E_Type *type = e_type_from_key__cached(key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_Bitfield: @@ -1702,7 +1703,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Alias: { E_Type *type = e_type_from_key__cached(key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; @@ -1714,7 +1715,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_Array: @@ -1753,20 +1754,15 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_pushf(arena, out, ", "); } } - str8_list_pushf(arena, out, ") <- ("); + str8_list_pushf(arena, out, ") <- "); E_TypeKey direct = e_type_direct_from_key(key); - e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - str8_list_pushf(arena, out, ")"); + e_type_lhs_string_from_key(arena, direct, out, 2, skip_return); }break; case E_TypeKind_Ptr: { E_TypeKey direct = e_type_direct_from_key(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - if(!e_type_kind_is_pointer_or_ref(e_type_kind_from_key(direct))) - { - str8_list_push(arena, out, str8_lit(" ")); - } str8_list_push(arena, out, str8_lit("*")); E_Type *type = e_type_from_key__cached(key); if(type->count != 1) @@ -1879,6 +1875,12 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; + + case E_TypeKind_Lens: + if(prec == 1) + { + str8_list_push(arena, out, str8_lit(")")); + }break; } } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index f4dc6cc8..ca2886b6 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1572,17 +1572,20 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) B32 need_pop = 1; B32 need_new_task = 0; EV_StringIterTask new_task = {0}; + S32 top_task_depth = 0; if(it->top_task != 0) { result = 1; //- rjf: unpack task U64 task_idx = it->top_task->idx; - S32 depth = it->top_task->depth; + S32 depth = top_task_depth = it->top_task->depth; EV_StringParams *params = &it->top_task->params; E_Eval eval = it->top_task->eval; E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); + String8 expansion_opener_symbol = str8_lit("{"); + String8 expansion_closer_symbol = str8_lit("}"); //- rjf: type evaluations -> display type string if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) @@ -1606,42 +1609,81 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: lenses // case E_TypeKind_Lens: - switch(task_idx) { - default:{}break; - - // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type - case 0: + E_Type *type = e_type_from_key__cached(type_key); + B32 lens_applied = 1; + EV_StringParams lens_params = *params; + if(0){} + else if(str8_match(type->name, str8_lit("bin"), 0)) { lens_params.radix = 2; } + else if(str8_match(type->name, str8_lit("oct"), 0)) { lens_params.radix = 8; } + else if(str8_match(type->name, str8_lit("dec"), 0)) { lens_params.radix = 10; } + else if(str8_match(type->name, str8_lit("hex"), 0)) { lens_params.radix = 16; } + else if(str8_match(type->name, str8_lit("digits"), 0) && type->count >= 1) + { + E_Value value = e_value_from_expr(type->args[0]); + lens_params.min_digits = value.u64; + } + else + { + lens_applied = 0; + } + if(lens_applied) { - Temp scratch = scratch_begin(&arena, 1); - String8List strings = {0}; - { - E_Type *type = e_type_from_key__cached(type_key); - str8_list_pushf(scratch.arena, &strings, "%S(", type->name); - for EachIndex(idx, type->count) - { - String8 string = e_string_from_expr(scratch.arena, type->args[idx]); - str8_list_push(scratch.arena, &strings, string); - if(idx+1 < type->count) - { - str8_list_pushf(scratch.arena, &strings, ", "); - } - } - str8_list_pushf(scratch.arena, &strings, ") <- ("); - } - *out_string = str8_list_join(arena, &strings, 0); need_new_task = 1; - new_task.params = *params; + need_pop = 1; + new_task.params = lens_params; new_task.eval = eval; new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); - scratch_end(scratch); - }break; - - // rjf: step 1 -> close - case 1: + } + else switch(task_idx) { - *out_string = str8_lit(")"); - }break; + default:{}break; + + // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type + case 0: + { + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; + { + str8_list_pushf(scratch.arena, &strings, "%S(", type->name); + for EachIndex(idx, type->count) + { + String8 string = e_string_from_expr(scratch.arena, type->args[idx]); + str8_list_push(scratch.arena, &strings, string); + if(idx+1 < type->count) + { + str8_list_pushf(scratch.arena, &strings, ", "); + } + } + str8_list_pushf(scratch.arena, &strings, ") <- ("); + } + *out_string = str8_list_join(arena, &strings, 0); + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + scratch_end(scratch); + }break; + + // rjf: step 1 -> close + case 1: + { + *out_string = str8_lit(")"); + }break; + } + }break; + + ////////////////////////// + //- rjf: modifiers + // + case E_TypeKind_Modifier: + { + need_pop = 1; + need_new_task = 1; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); }break; ////////////////////////// @@ -1651,7 +1693,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_Ptr: case E_TypeKind_LRef: case E_TypeKind_RRef: + case E_TypeKind_Array: { + if(type_kind == E_TypeKind_Array && it->top_task->redirect_array_to_sets_and_structs) + { + expansion_opener_symbol = str8_lit("["); + expansion_closer_symbol = str8_lit("]"); + goto arrays_and_sets_and_structs; + } typedef struct EV_StringPtrData EV_StringPtrData; struct EV_StringPtrData { @@ -1661,6 +1710,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) B32 ptee_has_content; B32 ptee_has_string; B32 did_prefix_content; + B32 did_redirect; }; EV_StringPtrData *ptr_data = it->top_task->user_data; if(ptr_data == 0) @@ -1668,13 +1718,17 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) ptr_data = it->top_task->user_data = push_array(arena, EV_StringPtrData, 1); ptr_data->value_eval = e_value_eval_from_eval(eval); ptr_data->type = e_type_from_key__cached(type_key); - ptr_data->direct_type = e_type_from_key__cached(e_type_direct_from_key(type_key)); + ptr_data->direct_type = e_type_from_key__cached(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key)))); ptr_data->ptee_has_content = (ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || ptr_data->direct_type->kind == E_TypeKind_S8 || ptr_data->direct_type->kind == E_TypeKind_U8); } - switch(task_idx) + if(ptr_data->did_redirect) + { + need_pop = 1; + } + else switch(task_idx) { default:{}break; @@ -1744,31 +1798,147 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } if(module != &e_module_nil) { + RDI_Parsed *rdi = module->rdi; U64 voff = vaddr - module->vaddr_range.min; - RDI_Procedure *procedure = rdi_procedure_from_voff(module->rdi, voff); - String8 procedure_name = {0}; - procedure_name.str = rdi_name_from_procedure(module->rdi, procedure, &procedure_name.size); - if(procedure_name.size != 0) + B32 good_symbol_match = 0; + + // NOTE(rjf): read-only -> generate non-parseable things, like type-info / inlines + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { - // NOTE(rjf): read-only -> generate non-parseable things, like type-info - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + + // rjf: scope -> # of max possible inline depth + U64 inline_site_count = 0; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { - // TODO(rjf) - *out_string = procedure_name; + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s->inline_site_idx != 0) + { + inline_site_count += 1; + } + else + { + break; + } } - // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + // rjf: depth in [1, max]? -> form name from inline site + if(0 < ptr_data->type->depth && ptr_data->type->depth <= inline_site_count) + { + RDI_InlineSite *inline_site = 0; + U64 s_inline_depth = inline_site_count; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) + { + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s_inline_depth == ptr_data->type->depth) + { + inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + break; + } + s_inline_depth -= 1; + if(s_inline_depth == 0) + { + break; + } + } + if(inline_site != 0) + { + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, module_idx); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + if(inline_site->type_idx != 0) + { + Temp scratch = scratch_begin(&arena, 1); + String8List list = {0}; + str8_list_pushf(scratch.arena, &list, "[inlined] "); + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + *out_string = str8_list_join(arena, &list, 0); + scratch_end(scratch); + } + else + { + *out_string = push_str8_copy(arena, name); + } + good_symbol_match = (name.size != 0); + } + } + + // rjf: depth == 0 or depth >= max? -> form name from scope procedure else { - *out_string = procedure_name; + Temp scratch = scratch_begin(&arena, 1); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, module_idx); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + if(procedure->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + *out_string = str8_list_join(arena, &list, 0); + } + else + { + *out_string = push_str8_copy(arena, name); + } + good_symbol_match = (out_string->size != 0); + scratch_end(scratch); } - - ptr_data->did_prefix_content = 1; } + + // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + else + { + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); + + // rjf: scope -> procedure / string + RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); + String8 procedure_name = {0}; + procedure_name.str = rdi_name_from_procedure(rdi, procedure, &procedure_name.size); + + *out_string = procedure_name; + good_symbol_match = (procedure_name.size != 0); + } + + ptr_data->did_prefix_content = good_symbol_match; } } - need_pop = 0; + // rjf: if this is an array, and we do not have a prefix, then we need to + // generate a new task which redirects array types -> sets and structs. + if(type_kind == E_TypeKind_Array && !ptr_data->did_prefix_content) + { + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.redirect_array_to_sets_and_structs = 1; + ptr_data->did_redirect = 1; + } + + // rjf: if this is an array, and we *did* prefix content, then we are + // just done. + else if(type_kind == E_TypeKind_Array && ptr_data->did_prefix_content) + { + // NOTE(rjf): no-op, task is done. + } + + // rjf: otherwise, keep going on this task + else + { + need_pop = 0; + } }break; //- rjf: step 1 -> do pointer value + descend if needed @@ -1799,6 +1969,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); need_new_task = 1; + need_pop = 0; new_task.params = *params; new_task.eval = deref_eval; } @@ -1822,15 +1993,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) }break; ////////////////////////// - //- rjf: arrays - // - case E_TypeKind_Array: - { - // TODO(rjf) - }break; - - ////////////////////////// - //- rjf: non-string-arrays/structs/sets + //- rjf: non-string-arrays/structs, sets // case E_TypeKind_Struct: case E_TypeKind_Union: @@ -1841,7 +2004,64 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_Set: arrays_and_sets_and_structs: { - + typedef struct EV_ExpandedTypeData EV_ExpandedTypeData; + struct EV_ExpandedTypeData + { + E_Type *type; + E_TypeExpandRule *expand_rule; + E_TypeExpandInfo expand_info; + }; + EV_ExpandedTypeData *expand_data = (EV_ExpandedTypeData *)it->top_task->user_data; + if(expand_data == 0) + { + expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); + expand_data->type = e_type_from_key__cached(type_key); + expand_data->expand_rule = &e_type_expand_rule__default; + if(expand_data->type->expand.info != 0) + { + expand_data->expand_rule = &expand_data->type->expand; + } + expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); + } + switch(task_idx) + { + //- rjf: step 0 -> generate opener symbol + case 0: + { + need_pop = 0; + *out_string = expansion_opener_symbol; + }break; + + default: + //- rjf: last step -> generate closer symbol + if(task_idx == expand_data->expand_info.expr_count+1) + { + *out_string = expansion_closer_symbol; + } + + //- rjf: middle step -> generate new task for next thing in expansion + else + { + E_Expr *next_expr = &e_expr_nil; + String8 next_string = {0}; + expand_data->expand_rule->range(arena, expand_data->expand_info.user_data, eval.expr, &eval.irtree, params->filter, r1u64(task_idx-1, task_idx), &next_expr, &next_string); + if(next_expr != &e_expr_nil) + { + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = e_eval_from_expr(arena, next_expr); + if(task_idx > 1) + { + *out_string = str8_lit(", "); + } + } + else + { + need_pop = 0; + } + }break; + } }break; } } @@ -1852,6 +2072,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) it->top_task->idx += 1; } + //- rjf: if result is good, and we want to pop? -> pop + if(result && need_pop) + { + EV_StringIterTask *task = it->top_task; + SLLStackPop(it->top_task); + SLLStackPush(it->free_task, task); + } + //- rjf: if result is good, and we have a new task? -> push if(result && need_new_task) { @@ -1865,62 +2093,10 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_t = push_array(arena, EV_StringIterTask, 1); } MemoryCopyStruct(new_t, &new_task); - new_t->depth = it->top_task->depth+1; + new_t->depth = top_task_depth+1; SLLStackPush(it->top_task, new_t); new_t->idx = 0; } - //- rjf: if result is good, but we don't have a new task? -> pop - else if(result && need_pop) - { - EV_StringIterTask *task = it->top_task; - SLLStackPop(it->top_task); - SLLStackPush(it->free_task, task); - } - return result; } - -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Expand Rule - -#if 0 // TODO(rjf): @eval -internal EV_ExpandRuleTagPair -ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) -{ - EV_ExpandRuleTagPair result = {&ev_nil_expand_rule, &e_expr_nil}; - { - // rjf: first try explicitly-stored tags - if(result.rule == &ev_nil_expand_rule) - { - for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) - { - EV_ExpandRule *candidate = ev_expand_rule_from_string(tag->string); - if(candidate != &ev_nil_expand_rule) - { - result.rule = candidate; - result.tag = tag; - break; - } - } - } - - // rjf: next try auto hook map - if(result.rule == &ev_nil_expand_rule) - { - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); - for(E_ExprNode *n = tags.first; n != 0; n = n->next) - { - EV_ExpandRule *candidate = ev_expand_rule_from_string(n->v->string); - if(candidate != &ev_nil_expand_rule) - { - result.rule = candidate; - result.tag = n->v; - break; - } - } - } - } - return result; -} -#endif diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 7f5115d0..86325d44 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -147,12 +147,12 @@ struct EV_Block U64 split_relative_idx; // rjf: evaluation info - String8 string; - E_Eval eval; - E_TypeExpandInfo type_expand_info; - E_TypeExpandRule *type_expand_rule; - EV_ExpandInfo viz_expand_info; - EV_ExpandRule *viz_expand_rule; + String8 string; + E_Eval eval; + E_TypeExpandInfo type_expand_info; + E_TypeExpandRule *type_expand_rule; + EV_ExpandInfo viz_expand_info; + EV_ExpandRule *viz_expand_rule; // rjf: expansion info U64 row_count; @@ -199,8 +199,8 @@ struct EV_Row EV_Block *block; EV_Key key; U64 visual_size; - String8 string; - E_Eval eval; + String8 string; + E_Eval eval; }; typedef struct EV_WindowedRowNode EV_WindowedRowNode; @@ -246,6 +246,7 @@ struct EV_StringParams U32 radix; U32 min_digits; U8 digit_group_separator; + String8 filter; }; typedef struct EV_StringIterTask EV_StringIterTask; @@ -256,6 +257,7 @@ struct EV_StringIterTask E_Eval eval; U64 idx; S32 depth; + B32 redirect_array_to_sets_and_structs; void *user_data; }; @@ -343,8 +345,8 @@ internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// //~ rjf: Block Coordinate Spaces - -internal U64 ev_block_id_from_num(EV_Block *block, U64 num); + +internal U64 ev_block_id_from_num(EV_Block *block, U64 num); internal U64 ev_block_num_from_id(EV_Block *block, U64 id); internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree); internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); @@ -376,11 +378,4 @@ internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); internal EV_StringIter *ev_string_iter_begin(Arena *arena, E_Eval eval, EV_StringParams *params); internal B32 ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string); -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Expand Rule - -#if 0 // TODO(rjf): @eval -internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); -#endif - #endif // EVAL_VISUALIZATION_CORE_H diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f1799a40..7b8b03dc 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -299,6 +299,10 @@ type_coverage_eval_tests(void) L"This is a string, but instead of being encoded in a stream of bytes,\n" L"it is encoded in a stream of 2-byte packages!\n"; + const char *const_string = "Hello, World!"; + const char const_string_array[] = "Hello, World!"; + const char *const const_ptr_const_string = "Hello, World!"; + void *pointer = &basics; Basics *pointer_to_basics = &basics; Basics **pointer_to_pointer_to_basics = &pointer_to_basics; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2f63d32b..ad581ca8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9619,10 +9619,18 @@ rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *par { EV_StringIter *iter = ev_string_iter_begin(scratch.arena, eval, params); F32 space_taken_px = 0; - for(String8 string = {0}; ev_string_iter_next(scratch.arena, iter, &string) && space_taken_px < max_size;) + for(String8 string = {0}; ev_string_iter_next(scratch.arena, iter, &string);) { - str8_list_push(scratch.arena, &strs, string); - space_taken_px += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + if(space_taken_px > max_size) + { + str8_list_push(scratch.arena, &strs, str8_lit("...")); + break; + } + else + { + str8_list_push(scratch.arena, &strs, string); + space_taken_px += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + } } } String8 result = str8_list_join(arena, &strs, 0); @@ -12272,12 +12280,6 @@ rd_frame(void) ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); -#if 0 // TODO(rjf): @eval - 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->irgen_rule_map = push_array(scratch.arena, E_IRGenRuleMap, 1); - ctx->irgen_rule_map[0] = e_irgen_rule_map_make(scratch.arena, 512); -#endif ctx->auto_hook_map = push_array(scratch.arena, E_AutoHookMap, 1); ctx->auto_hook_map[0] = e_auto_hook_map_make(scratch.arena, 512); @@ -12433,19 +12435,19 @@ rd_frame(void) //- rjf: add types for queries { -#if 0 // TODO(rjf): @eval e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("environment"), e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment"), .flags = E_TypeFlag_EditableChildren, + .irgen = E_TYPE_IRGEN_FUNCTION_NAME(environment), + .access = E_TYPE_ACCESS_FUNCTION_NAME(environment), .expand = { - .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment), + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(environment), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(environment), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(environment), })); -#endif e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), @@ -12555,20 +12557,21 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); } -#if 0 // TODO(rjf): @eval //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(unattached_processes) + }); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("unattached_processes"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); } -#endif //- rjf: add macro for commands { @@ -12665,10 +12668,10 @@ rd_frame(void) e_select_ir_ctx(ir_ctx); //////////////////////////// - //- rjf: generate macros for all view ui rules + //- rjf: generate macros for all view rules // { - //- rjf: choose set of view ui rules + //- rjf: choose set of view rules // TODO(rjf): generate via metaprogram struct { @@ -12678,6 +12681,11 @@ rd_frame(void) } view_ui_rule_table[] = { + {str8_lit("bin")}, + {str8_lit("oct")}, + {str8_lit("dec")}, + {str8_lit("hex")}, + {str8_lit("digits")}, {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 98eb4a48..defd8482 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -765,44 +765,26 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) return result; } -#if 0 // TODO(rjf): @eval - //////////////////////////////// //~ rjf: `environment` Type Hooks -E_TYPE_ACCESS_FUNCTION_DEF(environment) +typedef struct RD_EnvironmentAccel RD_EnvironmentAccel; +struct RD_EnvironmentAccel { - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + RD_CfgArray cfgs; +}; + +E_TYPE_IRGEN_FUNCTION_DEF(environment) +{ + E_IRTreeAndType result = *irtree; + RD_EnvironmentAccel *accel = push_array(arena, RD_EnvironmentAccel, 1); { Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) - { - RD_Cfg *cfg = cfgs->v[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) -{ - E_TypeExpandInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); - RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); + E_Space space = interpret.space; + RD_Cfg *target = rd_cfg_from_eval_space(space); RD_CfgList env_strings = {0}; for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) { @@ -811,57 +793,80 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) rd_cfg_list_push(scratch.arena, &env_strings, child); } } - RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); - *accel = rd_cfg_array_from_list(arena, &env_strings); - result.user_data = accel; - result.idxed_expr_count = accel->count + 1; + accel->cfgs = rd_cfg_array_from_list(arena, &env_strings); + scratch_end(scratch); } - scratch_end(scratch); + result.user_data = accel; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(environment) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex) + { + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)lhs_irtree->user_data; + RD_CfgArray *cfgs = &accel->cfgs; + E_Value rhs_value = e_value_from_expr(expr->first->next); + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.mode = E_Mode_Offset; + } + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) +{ + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)irtree->user_data; + E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; return result; } E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment) { - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->cfgs.count); Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); U64 read_range_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) + if(cfg_idx < accel->cfgs.count) { - exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, cfg_idx); } } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(environment) { U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; + if(1 <= num && num <= accel->cfgs.count) { U64 idx = (num-1); - id = cfgs->v[idx]->id; + id = accel->cfgs.v[idx]->id; } - else if(num == cfgs->count+1) + else if(num == accel->cfgs.count+1) { id = max_U64; } return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment) { U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; if(id != 0 && id != max_U64) { - for EachIndex(idx, cfgs->count) + for EachIndex(idx, accel->cfgs.count) { - if(cfgs->v[idx]->id == id) + if(accel->cfgs.v[idx]->id == id) { num = idx+1; break; @@ -870,7 +875,7 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) } else if(id == max_U64) { - num = cfgs->count + 1; + num = accel->cfgs.count + 1; } return num; } @@ -893,20 +898,21 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) Temp scratch = scratch_begin(&arena, 1); //- rjf: evaluate lhs machine, if we have one - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); E_Interpretation lhs_interp = e_interpret(lhs_bytecode); CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); //- rjf: gather all machines we're searching through - CTRL_EntityList machines = {0}; + CTRL_EntityArray machines = {0}; if(lhs_entity->kind == CTRL_EntityKind_Machine) { - ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); + machines.v = &lhs_entity; + machines.count = 1; } else { - machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + machines = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); } //- rjf: gather system processes from this machine @@ -920,9 +926,9 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) Node *first = 0; Node *last = 0; U64 count = 0; - for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) + for EachIndex(idx, machines.count) { - CTRL_Entity *machine = n->v; + CTRL_Entity *machine = machines.v[idx]; DMN_ProcessIter iter = {0}; dmn_process_iter_begin(&iter); for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) @@ -970,7 +976,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) accel->infos_count = infos_count; accel->machines = infos_machines; info.user_data = accel; - info.idxed_expr_count = infos_count; + info.expr_count = infos_count; scratch_end(scratch); } return info; @@ -991,7 +997,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) exprs_out[out_idx] = expr; } } -#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 03e6c830..5c1627cb 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -56,22 +56,21 @@ E_TYPE_IRGEN_FUNCTION_DEF(call_stack); E_TYPE_ACCESS_FUNCTION_DEF(call_stack); E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); -#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `environment` Type Hooks +E_TYPE_IRGEN_FUNCTION_DEF(environment); E_TYPE_ACCESS_FUNCTION_DEF(environment); E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(environment); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment); //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes); -#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8a8ba428..270b02dd 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1289,7 +1289,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); #undef take_pct } @@ -1313,7 +1313,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = module_eval, .default_pct = 0.20f, .pct = take_pct()); #undef take_pct } From c7a3a73b63d235a6adb2a6513d9d7bcfafb8e86b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 9 Apr 2025 17:29:59 -0700 Subject: [PATCH 331/755] fix incorrect story for chained lens calls; fix possibly-overridden usage of lens calls in ui build --- src/base/base_strings.c | 1 - src/eval/eval_ir.c | 65 +++---- src/eval/eval_parse.c | 31 ++-- .../eval_visualization_core.c | 170 +++++++++--------- src/raddbg/raddbg_views.c | 11 +- 5 files changed, 134 insertions(+), 144 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index e8b620dc..47b94f74 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1970,7 +1970,6 @@ escaped_from_raw_str8(Arena *arena, String8 string) case '\v': {separator_replace = str8_lit("\\v");}break; case '\\': {separator_replace = str8_lit("\\\\");}break; case '"': {separator_replace = str8_lit("\\\"");}break; - case '?': {separator_replace = str8_lit("\\?");}break; } if(split) { diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 56e83ce2..7cbf0dfc 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1514,47 +1514,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { default:{}break; - //- rjf: member accesses + //- rjf: member accesses & array indexing expressions case E_ExprKind_MemberAccess: - { - // rjf: unpack left-hand-size - E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - - // rjf: if the right-hand-side is a call, then this is short-hand for - // the right-hand-side call, with the left-hand-side as the first argument. - E_Expr *rhs = lhs->next; - if(rhs->kind == E_ExprKind_Call) - { - E_Expr *rhs_copy = e_expr_copy(arena, rhs); - e_expr_insert_child(rhs_copy, rhs_copy->first, e_expr_ref(arena, lhs)); - result = e_irtree_and_type_from_expr(arena, rhs_copy); - } - - // rjf: if the right-hand-side is a leaf identifier, then this is an - // "access" to the left-hand-side. - else if(rhs->kind == E_ExprKind_LeafIdentifier) - { - // rjf: pick access hook based on type - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - E_TypeAccessFunctionType *lhs_access = lhs_type->access; - if(lhs_access == 0) - { - lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); - } - - // rjf: call into hook to do access - result = lhs_access(arena, expr, &lhs_irtree); - } - - // rjf: if the right-hand-side is anything else, this is an invalid formation. - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Expected identifier or call after `.`."); - } - }break; - - //- rjf: array indices case E_ExprKind_ArrayIndex: { // rjf: unpack left-hand-size @@ -2171,9 +2132,29 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + // rjf: calling an unresolved leaf-identifier member access, and we can determine + // that that identifer maps to a type? -> generate a call expression with the + // left-hand-side of the dot operator as the first argument. this is a fast path + // which prevents paren nesting in simple cases, to easily chain multiple + // calls - for example, bin(2).digits(4) + if(lhs_type == &e_type_nil && + lhs->kind == E_ExprKind_MemberAccess) + { + E_Expr *callee = lhs->first->next; + E_Expr *first_arg = e_expr_ref(arena, lhs->first); + E_Expr *call = e_push_expr(arena, E_ExprKind_Call, 0); + e_expr_push_child(call, callee); + e_expr_push_child(call, first_arg); + for(E_Expr *arg = lhs->next; arg != &e_expr_nil; arg = arg->next) + { + e_expr_push_child(call, e_expr_ref(arena, arg)); + } + result = e_irtree_and_type_from_expr(arena, call); + } + // rjf: calling a lens? -> generate IR for the first argument; wrap the type in // a lens type, which preserves the name & arguments of the lens call expression - if(lhs_type->kind == E_TypeKind_LensSpec) + else if(lhs_type->kind == E_TypeKind_LensSpec) { Temp scratch = scratch_begin(&arena, 1); @@ -2202,6 +2183,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) scratch_end(scratch); } + + // rjf: calling any other type? -> not valid else { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 9c46201f..9296befb 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1218,29 +1218,31 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: advance past operator it += 1; - // rjf: parse right-hand-side - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), 0, 1); - e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.exprs.last; - it = rhs_expr_parse.last_token; + // rjf: look for member name + E_Token member_name_maybe = e_token_at_it(it, &tokens); + String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - // rjf: produce member access expr - if(rhs == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `.`."); - } - else + // rjf: if we have a member name, build dot-operator tree + if(member_name_maybe.kind == E_TokenKind_Identifier) { + it += 1; E_Expr *lhs = atom; + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name_maybe_string.str); + rhs->string = member_name_maybe_string; atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); e_expr_push_child(atom, lhs); e_expr_push_child(atom, rhs); } + + // rjf: no identifier after `.`? -> error + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing identifier after `.`."); + } } // rjf: array index - if(max_precedence >= 1 && - token.kind == E_TokenKind_Symbol && + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) { is_postfix_unary = 1; @@ -1279,8 +1281,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } // rjf: calls - if(max_precedence >= 0 && - token.kind == E_TokenKind_Symbol && + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { is_postfix_unary = 1; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ca2886b6..a03768bd 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1531,7 +1531,6 @@ ev_escaped_from_raw_string(Arena *arena, String8 raw) case '\v': {separator_replace = str8_lit("\\v");}break; case '\\': {separator_replace = str8_lit("\\\\");}break; case '"': {separator_replace = str8_lit("\\\"");}break; - case '?': {separator_replace = str8_lit("\\?");}break; } if(split) { @@ -1796,123 +1795,128 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) break; } } - if(module != &e_module_nil) + RDI_Parsed *rdi = module->rdi; + U64 voff = vaddr - module->vaddr_range.min; + B32 good_symbol_match = 0; + + // NOTE(rjf): read-only -> generate non-parseable things, like type-info / inlines + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { - RDI_Parsed *rdi = module->rdi; - U64 voff = vaddr - module->vaddr_range.min; - B32 good_symbol_match = 0; + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - // NOTE(rjf): read-only -> generate non-parseable things, like type-info / inlines - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + // rjf: scope -> # of max possible inline depth + U64 inline_site_count = 0; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { - // rjf: voff -> scope - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - - // rjf: scope -> # of max possible inline depth - U64 inline_site_count = 0; + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s->inline_site_idx != 0) + { + inline_site_count += 1; + } + else + { + break; + } + } + + // rjf: depth in [1, max]? -> form name from inline site + if(0 < ptr_data->type->depth && ptr_data->type->depth <= inline_site_count) + { + RDI_InlineSite *inline_site = 0; + U64 s_inline_depth = inline_site_count; for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); s_idx_next = s->parent_scope_idx; - if(s->inline_site_idx != 0) + if(s_inline_depth == ptr_data->type->depth) { - inline_site_count += 1; + inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + break; } - else + s_inline_depth -= 1; + if(s_inline_depth == 0) { break; } } - - // rjf: depth in [1, max]? -> form name from inline site - if(0 < ptr_data->type->depth && ptr_data->type->depth <= inline_site_count) + if(inline_site != 0) { - RDI_InlineSite *inline_site = 0; - U64 s_inline_depth = inline_site_count; - for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) - { - RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); - s_idx_next = s->parent_scope_idx; - if(s_inline_depth == ptr_data->type->depth) - { - inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); - break; - } - s_inline_depth -= 1; - if(s_inline_depth == 0) - { - break; - } - } - if(inline_site != 0) - { - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, module_idx); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - if(inline_site->type_idx != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8List list = {0}; - str8_list_pushf(scratch.arena, &list, "[inlined] "); - e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); - str8_list_push(scratch.arena, &list, name); - e_type_rhs_string_from_key(scratch.arena, type, &list, 0); - *out_string = str8_list_join(arena, &list, 0); - scratch_end(scratch); - } - else - { - *out_string = push_str8_copy(arena, name); - } - good_symbol_match = (name.size != 0); - } - } - - // rjf: depth == 0 or depth >= max? -> form name from scope procedure - else - { - Temp scratch = scratch_begin(&arena, 1); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, module_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, module_idx); String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - if(procedure->type_idx != 0) + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + if(inline_site->type_idx != 0) { + Temp scratch = scratch_begin(&arena, 1); String8List list = {0}; + str8_list_pushf(scratch.arena, &list, "[inlined] "); e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); str8_list_push(scratch.arena, &list, name); e_type_rhs_string_from_key(scratch.arena, type, &list, 0); *out_string = str8_list_join(arena, &list, 0); + scratch_end(scratch); } else { *out_string = push_str8_copy(arena, name); } - good_symbol_match = (out_string->size != 0); - scratch_end(scratch); + good_symbol_match = (name.size != 0); } } - // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + // rjf: depth == 0 or depth >= max? -> form name from scope procedure else { - // rjf: voff -> scope - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); + Temp scratch = scratch_begin(&arena, 1); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, module_idx); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + if(procedure->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + *out_string = str8_list_join(arena, &list, 0); + } + else + { + *out_string = push_str8_copy(arena, name); + } - // rjf: scope -> procedure / string - RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); - String8 procedure_name = {0}; - procedure_name.str = rdi_name_from_procedure(rdi, procedure, &procedure_name.size); - - *out_string = procedure_name; - good_symbol_match = (procedure_name.size != 0); + good_symbol_match = (out_string->size != 0); + scratch_end(scratch); } - ptr_data->did_prefix_content = good_symbol_match; + // rjf: if we have a function type, but we did not generate any name, then just put a ??? + if(out_string->size == 0 && e_type_kind_from_key(ptr_data->type->direct_type_key) == E_TypeKind_Function) + { + *out_string = str8_lit("???"); + good_symbol_match = 1; + } } + + // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + else + { + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); + + // rjf: scope -> procedure / string + RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); + String8 procedure_name = {0}; + procedure_name.str = rdi_name_from_procedure(rdi, procedure, &procedure_name.size); + + *out_string = procedure_name; + good_symbol_match = (procedure_name.size != 0); + } + + ptr_data->did_prefix_content = good_symbol_match; } // rjf: if this is an array, and we do not have a prefix, then we need to diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 270b02dd..21d64a88 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -824,7 +824,7 @@ rd_id_from_watch_cell(RD_WatchCell *cell) result = e_hash_from_string(result, str8_struct(&cell->kind)); if(cell->kind != RD_WatchCellKind_Expr) { - result = e_hash_from_string(result, str8_struct(&cell->eval.irtree.mode)); + // result = e_hash_from_string(result, str8_struct(&cell->eval.irtree.mode)); result = e_hash_from_string(result, str8_struct(&cell->index)); result = e_hash_from_string(result, str8_struct(&cell->default_pct)); } @@ -1289,7 +1289,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); #undef take_pct } @@ -1313,8 +1313,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = module_eval, .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), + .string = str8_lit(" "), + .default_pct = 0.20f, .pct = take_pct()); #undef take_pct } From c9e55cacf5286a485a74be652464376149da6641 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 9 Apr 2025 19:04:03 -0700 Subject: [PATCH 332/755] fix root-level block -> row expansion --- src/eval_visualization/eval_visualization_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index a03768bd..b7eea0cb 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1034,7 +1034,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - if(n->v.block->single_item) + if(n->v.block->single_item || n->v.block->parent == &ev_nil_block) { is_standalone_row = 1; } From 8dd8eaa507fc0681aefbac5c9d5a0abf6534e7d2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 9 Apr 2025 19:32:45 -0700 Subject: [PATCH 333/755] more work on lens-wrapped expressions composability w/ default expansions, operators, etc. --- src/eval/eval_ir.c | 3 ++- src/eval/eval_types.c | 29 ++++++++++++----------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 7cbf0dfc..60f1969a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1260,7 +1260,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_TypeKind check_type_kind = l_restype_kind; if(l_restype_kind == E_TypeKind_Ptr || l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) + l_restype_kind == E_TypeKind_RRef || + l_restype_kind == E_TypeKind_Lens) { check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); check_type_kind = e_type_kind_from_key(check_type_key); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 936c7d9e..acf3c6c1 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1745,18 +1745,16 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { E_Type *type = e_type_from_key__cached(key); str8_list_pushf(arena, out, "%S(", type->name); + E_TypeKey direct = e_type_direct_from_key(key); + String8 direct_string = e_type_string_from_key(arena, direct); + str8_list_push(arena, out, direct_string); for EachIndex(idx, type->count) { String8 string = e_string_from_expr(arena, type->args[idx]); + str8_list_pushf(arena, out, ", "); str8_list_push(arena, out, string); - if(idx+1 < type->count) - { - str8_list_pushf(arena, out, ", "); - } } - str8_list_pushf(arena, out, ") <- "); - E_TypeKey direct = e_type_direct_from_key(key); - e_type_lhs_string_from_key(arena, direct, out, 2, skip_return); + str8_list_pushf(arena, out, ")"); }break; case E_TypeKind_Ptr: @@ -1875,12 +1873,6 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; - - case E_TypeKind_Lens: - if(prec == 1) - { - str8_list_push(arena, out, str8_lit(")")); - }break; } } @@ -2115,11 +2107,12 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) { E_TypeKey type_key = e_type_unwrap(irtree->type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind)) + if(e_type_kind_is_pointer_or_ref(type_kind) || + type_kind == E_TypeKind_Lens) { E_Type *type = e_type_from_key__cached(type_key); result.expr_count = type->count; - if(type->count == 1) + if(type->count == 1 || type_kind == E_TypeKind_Lens) { E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); @@ -2176,10 +2169,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) E_TypeKey enum_type_key = zero_struct; E_TypeKey struct_type_key = zero_struct; E_TypeKind struct_type_kind = E_TypeKind_Null; - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + if(e_type_kind_is_pointer_or_ref(lhs_type_kind) || + lhs_type_kind == E_TypeKind_Lens) { E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if(lhs_type->count == 1 && + if((lhs_type->count == 1 || + lhs_type_kind == E_TypeKind_Lens) && (direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Union || direct_type_kind == E_TypeKind_Class)) From d15f9af4b72df1c14112054a086400731d8bbb92 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 09:37:55 -0700 Subject: [PATCH 334/755] fix incorrect signal of error on meta-ctrl-entity eval space write --- src/raddbg/raddbg_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ad581ca8..e36800f6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1855,6 +1855,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } else if(str8_match(child_schema->string, str8_lit("active"), 0)) { + result = 1; B32 new_active = 0; MemoryCopy(&new_active, in, dim_1u64(range)); if(!new_active) From c05c21cfa49ee8910f4cfc796b7379b09ffd8338 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 14:18:57 -0700 Subject: [PATCH 335/755] lens inheritance-on-expansion, composability with lens types & accesses (dot operator, array index operator), plugging in visualizers, killing dead code, etc. --- src/eval/eval_core.h | 13 +- src/eval/eval_ir.c | 53 +++- src/eval/eval_types.c | 249 +++++++++++------- src/eval/eval_types.h | 2 + .../eval_visualization_core.c | 164 ++++-------- .../eval_visualization_core.h | 30 ++- src/raddbg/raddbg_core.c | 246 +++++++++-------- src/raddbg/raddbg_core.h | 18 +- src/raddbg/raddbg_views.c | 59 ++--- src/raddbg/raddbg_views.h | 1 - 10 files changed, 450 insertions(+), 385 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 62bf70a7..3a4a1f6a 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -296,12 +296,13 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_EditableChildren = (1<<5), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_EditableChildren = (1<<5), + E_TypeFlag_InheritedOnAccess = (1<<6), }; typedef struct E_Member E_Member; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 60f1969a..182a469c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1242,6 +1242,7 @@ e_expr_unpoison(E_Expr *expr) E_TYPE_ACCESS_FUNCTION_DEF(default) { + Temp scratch = scratch_begin(&arena, 1); E_IRTreeAndType result = {&e_irnode_nil}; switch(expr->kind) { @@ -1260,8 +1261,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_TypeKind check_type_kind = l_restype_kind; if(l_restype_kind == E_TypeKind_Ptr || l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef || - l_restype_kind == E_TypeKind_Lens) + l_restype_kind == E_TypeKind_RRef) { check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); check_type_kind = e_type_kind_from_key(check_type_key); @@ -1472,6 +1472,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) result.mode = mode; }break; } + scratch_end(scratch); return result; } @@ -1482,6 +1483,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); + E_TypeKeyList inherited_lenses = {0}; E_IRTreeAndType result = {&e_irnode_nil}; ////////////////////////////// @@ -1519,10 +1521,26 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - // rjf: unpack left-hand-size + // rjf: unpack left-hand-side E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + // rjf: gather inherited lenses from the left-hand-side + { + E_TypeKey k = lhs_irtree.type_key; + E_TypeKind kind = e_type_kind_from_key(k); + for(;kind == E_TypeKind_Lens;) + { + E_Type *lens_type = e_type_from_key__cached(k); + if(lens_type->flags & E_TypeFlag_InheritedOnAccess) + { + e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); + } + k = e_type_direct_from_key(k); + kind = e_type_kind_from_key(k); + } + } + // rjf: pick access hook based on type E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); E_TypeAccessFunctionType *lhs_access = lhs_type->access; @@ -2180,7 +2198,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } // rjf: patch resultant type with a lens w/ args, pointing to the original type - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .count = arg_count, .args = args, .direct_key = result.type_key, .name = lhs_type->name); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lhs_type->flags, + .count = arg_count, + .args = args, + .direct_key = result.type_key, + .name = lhs_type->name); scratch_end(scratch); } @@ -2790,6 +2813,28 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_expr_unpoison(t->expr); } + ////////////////////////////// + //- rjf: apply inherited lenses to the resultant type + // + if(inherited_lenses.count != 0) + { + E_Type *result_type = e_type_from_key__cached(result.type_key); + for(E_TypeKeyNode *n = inherited_lenses.first; n != 0; n = n->next) + { + E_Type *src_type = e_type_from_key__cached(n->v); + E_TypeKey dst_type_key = e_type_key_cons(.kind = src_type->kind, + .flags = src_type->flags, + .name = src_type->name, + .count = src_type->count, + .args = src_type->args, + .irgen = src_type->irgen, + .access = src_type->access, + .expand = src_type->expand, + .direct_key = result.type_key); + result.type_key = dst_type_key; + } + } + scratch_end(scratch); ProfEnd(); return result; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index acf3c6c1..e4c8b899 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1337,7 +1337,8 @@ e_type_unwrap(E_TypeKey key) E_TypeKind kind = e_type_kind_from_key(result); if((E_TypeKind_FirstIncomplete <= kind && kind <= E_TypeKind_LastIncomplete) || kind == E_TypeKind_Modifier || - kind == E_TypeKind_Alias) + kind == E_TypeKind_Alias || + kind == E_TypeKind_Lens) { result = e_type_direct_from_key(result); } @@ -1889,6 +1890,91 @@ e_type_string_from_key(Arena *arena, E_TypeKey key) return result; } +internal E_TypeKey +e_default_expansion_type_from_key(E_TypeKey root_key) +{ + E_TypeKey type_key = zero_struct; + for(E_TypeKey key = root_key; + !e_type_key_match(e_type_key_zero(), key); + key = e_type_direct_from_key(key)) + { + B32 done = 1; + E_TypeKind kind = e_type_kind_from_key(key); + + //- rjf: if we have pointers which point to a single thing (count = 1), + // or we have a lens, or we have a modifier node, then we will defer to + // the next type in the chain. + // + // if this pointer points to N things (count > 1), then we can use it for + // array-like expansion. + // + if(e_type_kind_is_pointer_or_ref(kind)) + { + E_Type *type = e_type_from_key__cached(key); + if(!e_type_key_match(e_type_key_basic(E_TypeKind_Void), type->direct_type_key)) + { + if(type->count == 1) + { + done = 0; + } + else if(type->count > 1) + { + type_key = key; + } + } + } + + //- rjf: if we have lenses or modifiers in the type chain, then we will + // defer to the next type in the chain. + // + // NOTE(rjf): while it may seem like a lens type needs to do something + // different, because lenses sometimes want to define their own expansion + // rules, they would've redirected to an entirely different expansion + // hook. if we are in the default expansion hook, then the lenses do not + // impact the expansion at all (e.g. they are for other cosmetic things, + // like visualizers or integer radix changes), and so in that case we + // want to ignore them. + // + else if(kind == E_TypeKind_Lens || + kind == E_TypeKind_Modifier) + { + done = 0; + } + + //- rjf: if we've reached a struct-like, then we can use that for + // struct-like expansion. + else if(kind == E_TypeKind_Struct || + kind == E_TypeKind_Union || + kind == E_TypeKind_Class || + kind == E_TypeKind_Set) + { + type_key = key; + } + + //- rjf: if we've reached an enum-like, then we can use that for + // enum-like expansion. + else if(kind == E_TypeKind_Enum) + { + type_key = key; + } + + //- rjf: if we've reached an array, then we can use that for array-like + // expansion. + else if(kind == E_TypeKind_Array) + { + type_key = key; + } + + //- rjf: if we're done, then just break. + if(done) + { + break; + } + } + + return type_key; +} + //- rjf: type key data structures internal void @@ -1900,6 +1986,15 @@ e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key) list->count += 1; } +internal void +e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key) +{ + E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); + n->v = key; + SLLQueuePushFront(list->first, list->last, n); + list->count += 1; +} + internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) { @@ -2105,47 +2200,48 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) { E_TypeExpandInfo result = {0}; { - E_TypeKey type_key = e_type_unwrap(irtree->type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind) || - type_kind == E_TypeKind_Lens) + //- rjf: try to extract a struct-like type key, enum-like, or array-like + // type key, for expansion + E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + + //- rjf: struct type? -> use the struct type for expansion + B32 did_expansion = 0; + if(!did_expansion) { - E_Type *type = e_type_from_key__cached(type_key); - result.expr_count = type->count; - if(type->count == 1 || type_kind == E_TypeKind_Lens) + E_TypeKind struct_type_kind = e_type_kind_from_key(expand_type_key); + if(struct_type_kind == E_TypeKind_Struct || + struct_type_kind == E_TypeKind_Class || + struct_type_kind == E_TypeKind_Union) { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); - result.expr_count = data_members.count; - } - else if(direct_type_kind == E_TypeKind_Enum) - { - E_Type *direct_type = e_type_from_key__cached(direct_type_key); - result.expr_count = direct_type->count; - } + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(expand_type_key, filter); + result.expr_count = data_members.count; + did_expansion = 1; } } - else if(type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Union) + + //- rjf: array-like type? -> use the array-like for expansion + if(!did_expansion) { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(type_key, filter); - result.expr_count = data_members.count; + E_TypeKind array_type_kind = e_type_kind_from_key(expand_type_key); + if(array_type_kind == E_TypeKind_Array || + array_type_kind == E_TypeKind_Ptr) + { + E_Type *array_type = e_type_from_key__cached(expand_type_key); + result.expr_count = array_type->count; + did_expansion = 1; + } } - else if(type_kind == E_TypeKind_Enum) + + //- rjf: enum-like type? -> use the enum-like for expansion + if(!did_expansion) { - E_Type *direct_type = e_type_from_key__cached(type_key); - result.expr_count = direct_type->count; - } - else if(type_kind == E_TypeKind_Array) - { - E_Type *type = e_type_from_key__cached(type_key); - result.expr_count = type->count; + E_TypeKind enum_type_kind = e_type_kind_from_key(expand_type_key); + if(enum_type_kind == E_TypeKind_Enum) + { + E_Type *enum_type = e_type_from_key__cached(expand_type_key); + result.expr_count = enum_type->count; + did_expansion = 1; + } } } return result; @@ -2155,70 +2251,17 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { Temp scratch = scratch_begin(&arena, 1); { - //- rjf: unpack type of expression - E_IRTreeAndType lhs_irtree = *irtree; - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - //- rjf: pull out specific kinds of types - B32 do_struct_range = 0; - B32 do_enum_range = 0; - B32 do_index_range = 0; - E_TypeKey enum_type_key = zero_struct; - E_TypeKey struct_type_key = zero_struct; - E_TypeKind struct_type_kind = E_TypeKind_Null; - if(e_type_kind_is_pointer_or_ref(lhs_type_kind) || - lhs_type_kind == E_TypeKind_Lens) - { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if((lhs_type->count == 1 || - lhs_type_kind == E_TypeKind_Lens) && - (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class)) - { - struct_type_key = direct_type_key; - struct_type_kind = direct_type_kind; - do_struct_range = 1; - } - else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) - { - do_enum_range = 1; - enum_type_key = direct_type_key; - } - else - { - do_index_range = 1; - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Class) - { - struct_type_key = lhs_type_key; - struct_type_kind = lhs_type_kind; - do_struct_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Enum) - { - enum_type_key = lhs_type_key; - do_enum_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Set) - { - do_index_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Array) - { - do_index_range = 1; - } + //- rjf: try to extract a struct-like type key, enum-like, or array-like + // type key, for expansion + E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); //- rjf: struct case -> the lookup-range will return a range of members - if(do_struct_range) + if(expand_type_kind == E_TypeKind_Struct || + expand_type_kind == E_TypeKind_Class || + expand_type_kind == E_TypeKind_Union) { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(expand_type_key, filter); Rng1U64 legal_idx_range = r1u64(0, data_members.count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -2226,14 +2269,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = data_members.v[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); } } //- rjf: enum case -> the lookup-range will return a range of enum constants - else if(do_enum_range) + else if(expand_type_kind == E_TypeKind_Enum) { - E_Type *type = e_type_from_key__cached(enum_type_key); + E_Type *type = e_type_from_key__cached(expand_type_key); Rng1U64 legal_idx_range = r1u64(0, type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -2241,17 +2284,19 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = type->enum_vals[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); } } //- rjf: ptr case -> the lookup-range will return a range of dereferences - else if(do_index_range) + else if(expand_type_kind == E_TypeKind_Ptr || + expand_type_kind == E_TypeKind_Array || + expand_type_kind == E_TypeKind_Set) { U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, &lhs_irtree, idx_range.min + idx); + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); } } } diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 8217065c..cb5e06f7 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -264,9 +264,11 @@ internal E_Member *e_type_member_from_array_name(E_MemberArray *members, String8 internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return); internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec); internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); +internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key); //- rjf: type key data structures internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); +internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index b7eea0cb..4c7ae9dd 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -83,30 +83,19 @@ internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; - for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) { - E_TypeKind kind = e_type_kind_from_key(t); - if(kind == E_TypeKind_Null || kind == E_TypeKind_Function) - { - break; - } - if(kind == E_TypeKind_Struct || - kind == E_TypeKind_Union || - kind == E_TypeKind_Class || - kind == E_TypeKind_Array || - kind == E_TypeKind_Set || - (kind == E_TypeKind_Enum && mode == E_Mode_Null)) + E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); + E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); + if(expand_type_kind == E_TypeKind_Struct || + expand_type_kind == E_TypeKind_Union || + expand_type_kind == E_TypeKind_Class || + expand_type_kind == E_TypeKind_Array || + expand_type_kind == E_TypeKind_Set || + e_type_kind_is_pointer_or_ref(expand_type_kind) || + (expand_type_kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; } - if(kind == E_TypeKind_Ptr) - { - E_Type *type = e_type_from_key__cached(t); - if(type->count > 1) - { - result = 1; - } - } } return result; } @@ -396,6 +385,27 @@ ev_expand_rule_from_string(String8 string) return info; } +internal EV_ExpandRule * +ev_expand_rule_from_type_key(E_TypeKey type_key) +{ + EV_ExpandRule *rule = &ev_nil_expand_rule; + { + E_TypeKey k = type_key; + E_TypeKind kind = e_type_kind_from_key(k); + for(;kind == E_TypeKind_Lens; k = e_type_direct_from_key(k), kind = e_type_kind_from_key(k)) + { + E_Type *type = e_type_from_key__cached(k); + EV_ExpandRule *candidate = ev_expand_rule_from_string(type->name); + if(candidate != &ev_nil_expand_rule) + { + rule = candidate; + break; + } + } + } + return rule; +} + //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) @@ -471,66 +481,6 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) } #endif -//////////////////////////////// -//~ rjf: Upgrading Expressions w/ Tags From All Sources - -#if 0 // TODO(rjf): @eval -internal void -ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) -{ - Temp scratch = scratch_begin(&arena, 1); - if(expr != &e_expr_nil) - { - // rjf: push inherited tags first (we want these to be found first, since tags are applied - // in order, and explicit ones should always be strongest) - { - for(E_Expr *src_tag = block->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) - { - B32 is_inherited = 0; - // TODO(rjf): table-drive this - if(str8_match(src_tag->string, str8_lit("hex"), 0) || - str8_match(src_tag->string, str8_lit("oct"), 0) || - str8_match(src_tag->string, str8_lit("bin"), 0) || - str8_match(src_tag->string, str8_lit("dec"), 0) || - str8_match(src_tag->string, str8_lit("no_addr"), 0) || - str8_match(src_tag->string, str8_lit("digits"), 0) || - str8_match(src_tag->string, str8_lit("no_string"), 0) || - str8_match(src_tag->string, str8_lit("only"), 0) || - str8_match(src_tag->string, str8_lit("omit"), 0)) - { - is_inherited = 1; - } - if(is_inherited) - { - e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); - } - } - } - - // rjf: push tags inferred from the type - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree.type_key); - for(E_ExprNode *n = tags.first; n != 0; n = n->next) - { - e_expr_push_tag(expr, e_expr_copy(arena, n->v)); - } - } - - // rjf: push explicitly-attached tags (via key) next - String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); - E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) - { - next = tag->next; - e_expr_push_tag(expr, tag); - } - } - scratch_end(scratch); -} -#endif - //////////////////////////////// //~ rjf: Block Building @@ -546,9 +496,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); E_Expr *root_expr = e_expr_copy(arena, expr); -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); -#endif //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); @@ -606,9 +553,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp } // rjf: get eval's visualization expansion rule - // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ExpandRule *viz_expand_rule = &ev_nil_expand_rule; - E_Expr *viz_expand_rule_tag = &e_expr_nil; + EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(type_key); // rjf: skip if no expansion rule, & type info disallows expansion if(viz_expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(type_key, mode)) @@ -618,7 +563,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp // rjf: get top-level lookup/expansion info E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); - EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr, viz_expand_rule_tag); + EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); // rjf: determine expansion info U64 expansion_row_count = type_expand_info.expr_count; @@ -738,9 +683,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp { E_Eval child_eval = e_eval_from_expr(arena, child_expr); EV_Key child_key = child_keys[idx]; -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); -#endif Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; @@ -857,7 +799,7 @@ ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + U64 range_size = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); Rng1U64 global_range = r1u64(base_num, base_num + range_size); if(contains_1u64(global_range, num)) { @@ -880,7 +822,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + U64 range_size = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); Rng1U64 global_range = r1u64(base_num, base_num + range_size); if(contains_1u64(global_range, num)) { @@ -906,14 +848,14 @@ ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) if(hash == key.parent_hash) { U64 relative_num = ev_block_num_from_id(n->v.block, key.child_id); - Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->single_item ? (n->v.range.min+1) : n->v.range.max); + Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->viz_expand_info.single_item ? (n->v.range.min+1) : n->v.range.max); if(contains_1u64(num_range, relative_num-1)) { result = base_num + (relative_num - 1 - n->v.range.min); break; } } - base_num += n->v.block->single_item ? 1 : dim_1u64(n->v.range); + base_num += n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); } return result; } @@ -927,10 +869,10 @@ ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 next_base_num = base_num + (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + U64 next_base_num = base_num + (n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range)); if(base_num <= num && num < next_base_num) { - U64 relative_vnum = (n->v.block->single_item ? 0 : (num - base_num)); + U64 relative_vnum = (n->v.block->viz_expand_info.single_item ? 0 : (num - base_num)); vnum = base_vnum + relative_vnum; break; } @@ -957,12 +899,12 @@ ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vnum) U64 next_base_vnum = base_vnum + dim_1u64(n->v.range); if(base_vnum <= vnum && vnum < next_base_vnum) { - U64 relative_num = (n->v.block->single_item ? 0 : (vnum - base_vnum)); + U64 relative_num = (n->v.block->viz_expand_info.single_item ? 0 : (vnum - base_vnum)); num = base_num + relative_num; break; } base_vnum = next_base_vnum; - base_num += (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + base_num += (n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range)); } } return num; @@ -1009,7 +951,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 rows.count_before_visual += num_skipped; if(block_num_visual_rows != 0 && num_skipped != 0) { - if(n->v.block->single_item) + if(n->v.block->viz_expand_info.single_item) { if(num_skipped >= block_num_visual_rows) { @@ -1034,7 +976,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - if(n->v.block->single_item || n->v.block->parent == &ev_nil_block) + if(n->v.block->viz_expand_info.single_item || n->v.block->parent == &ev_nil_block) { is_standalone_row = 1; } @@ -1054,7 +996,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 EV_Row *row = &row_node->row; row->block = n->v.block; row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); - row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; + row->visual_size = n->v.block->viz_expand_info.single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; row->string = n->v.block->string; row->eval = n->v.block->eval; } @@ -1067,9 +1009,6 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; E_Eval row_eval = e_eval_from_expr(arena, row_expr); -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); -#endif EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1121,16 +1060,14 @@ ev_row_is_expandable(EV_Row *row) { E_IRTreeAndType irtree = row->eval.irtree; - // rjf: determine if view rules force expandability + // rjf: determine if lenses force expandability if(!result) { -#if 0 // TODO(rjf): @eval - EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(row->expr, &irtree); - if(expand_rule_and_tag.rule != &ev_nil_expand_rule) + EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(irtree.type_key); + if(expand_rule != &ev_nil_expand_rule) { result = 1; } -#endif } // rjf: determine if type info force expandability @@ -1736,13 +1673,16 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case 0: { // rjf: try strings - if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && !(params->flags & EV_StringFlag_DisableStrings)) + if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && + !(params->flags & EV_StringFlag_DisableStrings) && + (type_kind == E_TypeKind_Array || + params->flags & EV_StringFlag_ReadOnlyDisplayRules)) { Temp scratch = scratch_begin(&arena, 1); // rjf: read string data U64 string_memory_addr = ptr_data->value_eval.value.u64; - U64 string_buffer_size = 256; + U64 string_buffer_size = 4096; U8 *string_buffer = push_array(scratch.arena, U8, string_buffer_size); for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) { @@ -1765,7 +1705,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } // rjf: escape and quote - B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableAddresses) || depth > 0); + B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableStringQuotes) || depth > 0); String8 string__escaped_and_quoted = string; if(string__is_escaped_and_quoted) { diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 86325d44..35a20c57 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -87,7 +87,7 @@ struct EV_ExpandInfo B32 rows_default_expanded; }; -#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) +#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr) #define EV_EXPAND_RULE_INFO_FUNCTION_NAME(name) ev_expand_rule_info__##name #define EV_EXPAND_RULE_INFO_FUNCTION_DEF(name) internal EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_EXPAND_RULE_INFO_FUNCTION_NAME(name)) typedef EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_ExpandRuleInfoHookFunctionType); @@ -156,8 +156,6 @@ struct EV_Block // rjf: expansion info U64 row_count; - B32 single_item; - B32 rows_default_expanded; }; typedef struct EV_BlockTree EV_BlockTree; @@ -237,6 +235,7 @@ enum EV_StringFlag_PrettyNames = (1<<1), EV_StringFlag_DisableAddresses = (1<<2), EV_StringFlag_DisableStrings = (1<<3), + EV_StringFlag_DisableStringQuotes = (1<<4), }; typedef struct EV_StringParams EV_StringParams; @@ -282,7 +281,22 @@ global read_only EV_ExpandRule ev_nil_expand_rule = EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}}; +global read_only EV_Block ev_nil_block = +{ + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + {0}, + 0, + {0}, + {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}, + {0}, + &e_type_expand_rule__default, + {0}, + &ev_nil_expand_rule, +}; //////////////////////////////// //~ rjf: Key Functions @@ -322,6 +336,7 @@ internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, #define ev_expand_rule_table_push_new(arena, table, ...) ev_expand_rule_table_push((arena), (table), &(EV_ExpandRule){__VA_ARGS__}) internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); +internal EV_ExpandRule *ev_expand_rule_from_type_key(E_TypeKey type_key); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) @@ -330,13 +345,6 @@ internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); #endif -//////////////////////////////// -//~ rjf: Upgrading Expressions w/ Tags From All Sources - -#if 0 // TODO(rjf): @eval -internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr); -#endif - //////////////////////////////// //~ rjf: Block Building diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e36800f6..cc4ce525 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1404,16 +1404,6 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) return result; } -internal E_Expr * -rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) -{ - E_Expr *expr = &e_expr_nil; - { - // TODO(rjf): @cfg - } - return expr; -} - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -1949,7 +1939,7 @@ rd_whole_range_from_eval_space(E_Space space) //- rjf: writing values back to child processes internal B32 -rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping) +rd_commit_eval_value_string(E_Eval dst_eval, String8 string) { B32 result = 0; if(dst_eval.irtree.mode == E_Mode_Offset) @@ -1984,17 +1974,14 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un e_type_kind_is_integer(direct_type_kind)) { B32 is_quoted = 0; - if(string_needs_unescaping) + if(string.size >= 1 && string.str[0] == '"') { - if(string.size >= 1 && string.str[0] == '"') - { - string = str8_skip(string, 1); - is_quoted = 1; - } - if(string.size >= 1 && string.str[string.size-1] == '"') - { - string = str8_chop(string, 1); - } + string = str8_skip(string, 1); + is_quoted = 1; + } + if(string.size >= 1 && string.str[string.size-1] == '"') + { + string = str8_chop(string, 1); } if(is_quoted) { @@ -2652,7 +2639,7 @@ rd_view_ui(Rng2F32 rect) { UI_ScrollListRowBlock block = {0}; block.row_count = dim_1u64(n->v.range); - block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + block.item_count = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); } row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); @@ -3134,7 +3121,7 @@ rd_view_ui(Rng2F32 rect) if(should_commit_asap) { B32 success = 0; - success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); + success = rd_commit_eval_value_string(cell_info.eval, new_string); if(!success) { log_user_error(str8_lit("Could not commit value successfully.")); @@ -3268,7 +3255,7 @@ rd_view_ui(Rng2F32 rect) case RD_WatchCellKind_Eval: { RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); + rd_commit_eval_value_string(cell_info.eval, str8_zero()); }break; } } @@ -4069,7 +4056,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); + cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4442,7 +4429,7 @@ rd_view_ui(Rng2F32 rect) // if(next_cell_toggled != cell_toggled) { - rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0"), 0); + rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); } //////////// @@ -4488,8 +4475,7 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); - view_ui_rule->ui(expr_eval, tag, rect); + view_ui_rule->ui(expr_eval, rect); scratch_end(scratch); } } @@ -4595,7 +4581,7 @@ rd_view_cfg_value_from_string(String8 string) internal U64 rd_base_offset_from_eval(E_Eval eval) { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.irtree.type_key))) + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)))) { eval = e_value_eval_from_eval(eval); } @@ -4603,15 +4589,20 @@ rd_base_offset_from_eval(E_Eval eval) } internal Rng1U64 -rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_range_from_eval(E_Eval eval) { U64 size = 0; - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("size"), 0)) + for EachIndex(idx, type->count) { - size = e_value_from_expr(param->first->next).u64; - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) + { + size = e_value_from_expr(arg->first->next).u64; + break; + } } } E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); @@ -4643,7 +4634,7 @@ rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) } internal TXT_LangKind -rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_lang_kind_from_eval(E_Eval eval) { TXT_LangKind lang_kind = TXT_LangKind_Null; Temp scratch = scratch_begin(0, 0); @@ -4654,12 +4645,17 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) } if(lang_kind == TXT_LangKind_Null) { - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + for EachIndex(idx, type->count) { - lang_kind = txt_lang_kind_from_extension(param->first->next->string); - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(arg->first->next->string); + break; + } } } } @@ -4668,7 +4664,7 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) } internal Arch -rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_arch_from_eval(E_Eval eval) { // rjf: try implicitly from either `eval` itself, or from context CTRL_Entity *ctrl_entity = rd_ctrl_entity_from_eval_space(eval.space); @@ -4683,18 +4679,25 @@ rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) arch = arch_from_context(); } - // rjf: try arch parameters - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + // rjf: try arch arguments + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - String8 param_arch_string = param->string; - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("arch"), 0)) + for EachIndex(idx, type->count) { - param_arch_string = param->first->next->string; - } - if(str8_match(param->first->next->string, str8_lit("x64"), 0)) - { - arch = Arch_x64; - break; + E_Expr *arg = type->args[idx]; + { + String8 arg_arch_string = arg->string; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("arch"), 0)) + { + arg_arch_string = arg->first->next->string; + } + if(str8_match(arg->first->next->string, str8_lit("x64"), 0)) + { + arch = Arch_x64; + break; + } + } } } @@ -4702,45 +4705,54 @@ rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) } internal Vec2S32 -rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_dim2s32_from_eval(E_Eval eval) { Vec2S32 dim = v2s32(1, 1); B32 got_x = 0; B32 got_y = 0; // rjf: try explicitly passed dimensions - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define) + for EachIndex(idx, type->count) { - if(str8_match(param->first->string, str8_lit("w"), 0)) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define) { - got_x = 1; - dim.x = e_value_from_expr(param->first->next).s64; - } - if(str8_match(param->first->string, str8_lit("h"), 0)) - { - got_y = 1; - dim.y = e_value_from_expr(param->first->next).s64; + if(str8_match(arg->first->string, str8_lit("w"), 0)) + { + got_x = 1; + dim.x = e_value_from_expr(arg->first->next).s64; + } + if(str8_match(arg->first->string, str8_lit("h"), 0)) + { + got_y = 1; + dim.y = e_value_from_expr(arg->first->next).s64; + } } } } // rjf: try ordered non-define arguments - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + if(type->kind == E_TypeKind_Lens) { - if(param->kind != E_ExprKind_Define) + for EachIndex(idx, type->count) { - if(!got_x) + E_Expr *arg = type->args[idx]; + if(arg->kind != E_ExprKind_Define) { - got_x = 1; - dim.x = e_value_from_expr(param).s64; - } - else if(!got_y) - { - got_y = 1; - dim.y = e_value_from_expr(param).s64; - break; + if(!got_x) + { + got_x = 1; + dim.x = e_value_from_expr(arg).s64; + } + else if(!got_y) + { + got_y = 1; + dim.y = e_value_from_expr(arg).s64; + break; + } } } } @@ -4749,39 +4761,48 @@ rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) } internal R_Tex2DFormat -rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_tex2dformat_from_eval(E_Eval eval) { R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; B32 got_fmt = 0; // rjf: try explicitly passed formats - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("fmt"), 0)) + for EachIndex(idx, type->count) { - got_fmt = 1; - for EachEnumVal(R_Tex2DFormat, f) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("fmt"), 0)) { - if(str8_match(param->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + got_fmt = 1; + for EachEnumVal(R_Tex2DFormat, f) { - fmt = f; - break; + if(str8_match(arg->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } } } } } // rjf: try implicit non-define arguments - for(E_Expr *param = tag->first->next; param != &e_expr_nil && !got_fmt; param = param->next) + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_LeafIdentifier) + for EachIndex(idx, type->count) { - for EachEnumVal(R_Tex2DFormat, f) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_LeafIdentifier) { - if(str8_match(param->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + for EachEnumVal(R_Tex2DFormat, f) { - fmt = f; - break; + if(str8_match(arg->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } } } } @@ -4791,15 +4812,20 @@ rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) } internal E_Value -rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key) +rd_value_from_eval_key(E_Eval eval, String8 key) { E_Value value = zero_struct; - for(E_Expr *arg = tag->first->next; arg != &e_expr_nil; arg = arg->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + for EachIndex(idx, type->count) { - value = e_value_from_expr(arg->first->next); - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + { + value = e_value_from_expr(arg->first->next); + break; + } } } return value; @@ -6253,10 +6279,8 @@ rd_window_frame(void) if(build_hover_eval) { // rjf: determine if we have a top-level visualizer -#if 0 // TODO(rjf): @eval - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); -#endif - RD_ViewUIRule *view_ui_rule = &rd_nil_view_ui_rule; // TODO(rjf): @eval rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(hover_eval.irtree.type_key); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule->string); // rjf: determine view name String8 view_name = str8_lit("watch"); @@ -12677,23 +12701,24 @@ rd_frame(void) struct { String8 name; + B32 inherited; RD_ViewUIFunctionType *ui; EV_ExpandRuleInfoHookFunctionType *expand; } view_ui_rule_table[] = { - {str8_lit("bin")}, - {str8_lit("oct")}, - {str8_lit("dec")}, - {str8_lit("hex")}, - {str8_lit("digits")}, - {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, - {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, - {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, - {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + {str8_lit("bin"), 1}, + {str8_lit("oct"), 1}, + {str8_lit("dec"), 1}, + {str8_lit("hex"), 1}, + {str8_lit("digits"), 1}, + {str8_lit("text"), 0, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), 0, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), 0, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), 0, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), 0, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), 0, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), 0, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; //- rjf: fill view ui rules in expand rule map, view ui rule map @@ -12712,8 +12737,13 @@ rd_frame(void) } for EachElement(idx, view_ui_rule_table) { + E_TypeFlags type_flags = 0; + if(view_ui_rule_table[idx].inherited) + { + type_flags |= E_TypeFlag_InheritedOnAccess; + } E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = view_ui_rule_table[idx].name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .flags = type_flags, .name = view_ui_rule_table[idx].name); e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 32780f50..83a604ee 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -92,7 +92,7 @@ enum //////////////////////////////// //~ rjf: View UI Hook Types -#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, E_Expr *tag, Rng2F32 rect) +#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, Rng2F32 rect) #define RD_VIEW_UI_FUNCTION_NAME(name) rd_view_ui__##name #define RD_VIEW_UI_FUNCTION_DEF(name) internal RD_VIEW_UI_FUNCTION_SIG(RD_VIEW_UI_FUNCTION_NAME(name)) typedef RD_VIEW_UI_FUNCTION_SIG(RD_ViewUIFunctionType); @@ -908,8 +908,6 @@ internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path); internal String8List rd_possible_overrides_from_file_path(Arena *arena, String8 file_path); -internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -941,7 +939,7 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); //~ rjf: Evaluation Visualization //- rjf: writing values back to child processes -internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); +internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string); //- rjf: eval <-> file path internal String8 rd_file_path_from_eval(Arena *arena, E_Eval eval); @@ -971,12 +969,12 @@ internal E_Value rd_view_cfg_value_from_string(String8 string); //- rjf: evaluation & tag (a view's 'call') parameter extraction internal U64 rd_base_offset_from_eval(E_Eval eval); -internal Rng1U64 rd_range_from_eval_tag(E_Eval eval, E_Expr *tag); -internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag); -internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag); -internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag); -internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag); -internal E_Value rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key); +internal Rng1U64 rd_range_from_eval(E_Eval eval); +internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval); +internal Arch rd_arch_from_eval(E_Eval eval); +internal Vec2S32 rd_dim2s32_from_eval(E_Eval eval); +internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval); +internal E_Value rd_value_from_eval_key(E_Eval eval, String8 key); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 21d64a88..09afb46b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1051,14 +1051,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine view ui rule - // TODO(rjf): @eval - info.view_ui_rule = &rd_nil_view_ui_rule; // rd_view_ui_rule_from_string(row->block->expand_rule->string); -#if 0 // TODO(rjf): @eval - if(info.view_ui_rule != &rd_nil_view_ui_rule) - { - info.view_ui_tag = row->block->expand_tag; - } -#endif + info.view_ui_rule = rd_view_ui_rule_from_string(row->block->viz_expand_rule->string); // rjf: fill row's cells { @@ -1311,9 +1304,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((uint64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .string = str8_lit(" "), @@ -1332,7 +1325,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr => default)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1353,7 +1346,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: fill basics/defaults result.view_ui_rule = &rd_nil_view_ui_rule; - result.view_ui_tag = &e_expr_nil; result.fstrs = cell->fstrs; result.flags = cell->flags; result.cfg = &rd_nil_cfg; @@ -1495,16 +1487,22 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: evaluate wrapped expression result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); - //- rjf: determine default radix - U32 default_radix = 10; - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + //- rjf: determine string generation parameters based on evaluation + EV_StringParams string_params = {string_flags, 10}; { - default_radix = 16; + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + string_params.flags |= EV_StringFlag_DisableStringQuotes; + } + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + { + string_params.radix = 16; + } } //- rjf: generate strings/flags based on that expression & fill - EV_StringParams string_params = {.flags = string_flags, .radix = default_radix}; result.string = rd_value_string_from_eval_NEW(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); @@ -1529,7 +1527,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); result.view_ui_rule = row_info->view_ui_rule; - result.view_ui_tag = row_info->view_ui_tag; }break; } @@ -1743,9 +1740,9 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - Rng1U64 range = rd_range_from_eval_tag(eval, tag); + Rng1U64 range = rd_range_from_eval(eval); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval_tag(eval, tag); + rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); @@ -2002,8 +1999,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = rd_range_from_eval_tag(eval, tag); - Arch arch = rd_arch_from_eval_tag(eval, tag); + Rng1U64 range = rd_range_from_eval(eval); + Arch arch = rd_arch_from_eval(eval); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; DI_Key dbgi_key = {0}; @@ -2170,7 +2167,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - Rng1U64 space_range = rd_range_from_eval_tag(eval, tag); + Rng1U64 space_range = rd_range_from_eval(eval); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -3085,8 +3082,8 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - Vec2S32 dim = rd_dim2s32_from_eval_tag(eval, tag); - R_Tex2DFormat fmt = rd_tex2dformat_from_eval_tag(eval, tag); + Vec2S32 dim = rd_dim2s32_from_eval(eval); + R_Tex2DFormat fmt = rd_tex2dformat_from_eval(eval); U64 base_offset = rd_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -3283,7 +3280,7 @@ RD_VIEW_UI_FUNCTION_DEF(checkbox) E_Eval value_eval = e_value_eval_from_eval(eval); if(ui_clicked(rd_icon_buttonf(value_eval.value.u64 == 0 ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled, 0, "###check"))) { - rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0"), 0); + rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0")); } } @@ -3484,9 +3481,9 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_value_from_eval_tag_key(eval, tag, str8_lit("count")).u64; - U64 vtx_base_off = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx")).u64; - U64 vtx_size = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx_size")).u64; + U64 count = rd_value_from_eval_key(eval, str8_lit("count")).u64; + U64 vtx_base_off = rd_value_from_eval_key(eval, str8_lit("vtx")).u64; + U64 vtx_size = rd_value_from_eval_key(eval, str8_lit("vtx_size")).u64; F32 yaw_target = rd_view_cfg_value_from_string(str8_lit("yaw")).f32; F32 pitch_target = rd_view_cfg_value_from_string(str8_lit("pitch")).f32; F32 zoom_target = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index a4961eda..099929d0 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -118,7 +118,6 @@ struct RD_WatchRowCellInfo String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; - E_Expr *view_ui_tag; }; typedef enum RD_WatchViewColumnKind From 4a69b8e57a4603bac2416db86a7da95f716a285c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 14:28:45 -0700 Subject: [PATCH 336/755] type decoration to explicitly disable string visualization; use in registers & padding members; eliminate dead code --- src/eval/eval_core.h | 94 +--- src/eval/eval_types.c | 4 +- .../eval_visualization_core.c | 23 +- src/raddbg/raddbg_core.c | 472 +----------------- src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_views.c | 7 +- src/raddbg/raddbg_widgets.c | 2 +- 7 files changed, 35 insertions(+), 573 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 3a4a1f6a..99fd2ea5 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -301,8 +301,9 @@ enum E_TypeFlag_IsPlainText = (1<<2), E_TypeFlag_IsCodeText = (1<<3), E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_EditableChildren = (1<<5), - E_TypeFlag_InheritedOnAccess = (1<<6), + E_TypeFlag_IsNotText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_InheritedOnAccess = (1<<7), }; typedef struct E_Member E_Member; @@ -493,95 +494,6 @@ struct E_String2ExprMap E_String2ExprMapSlot *slots; }; -//////////////////////////////// -//~ rjf: Member/Index Lookup Hooks - -#if 0 // TODO(rjf): @eval - -typedef struct E_LookupInfo E_LookupInfo; -struct E_LookupInfo -{ - void *user_data; - U64 named_expr_count; - U64 idxed_expr_count; -}; - -typedef struct E_LookupAccess E_LookupAccess; -struct E_LookupAccess -{ - E_IRTreeAndType irtree_and_type; -}; - -#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter) -#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name -#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name)) -typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType); -E_LOOKUP_INFO_FUNCTION_DEF(default); - -#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data) -#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name -#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name)) -typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType); -E_LOOKUP_ACCESS_FUNCTION_DEF(default); - -#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data) -#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name -#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name)) -typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType); -E_LOOKUP_RANGE_FUNCTION_DEF(default); - -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data) -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name -#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name)) -typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default); - -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data) -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name -#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name)) -typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default); - -typedef struct E_LookupRule E_LookupRule; -struct E_LookupRule -{ - String8 name; - E_LookupInfoFunctionType *info; - E_LookupAccessFunctionType *access; - E_LookupRangeFunctionType *range; - E_LookupIDFromNumFunctionType *id_from_num; - E_LookupNumFromIDFunctionType *num_from_id; -}; - -typedef struct E_LookupRuleNode E_LookupRuleNode; -struct E_LookupRuleNode -{ - E_LookupRuleNode *next; - E_LookupRule v; -}; - -typedef struct E_LookupRuleSlot E_LookupRuleSlot; -struct E_LookupRuleSlot -{ - E_LookupRuleNode *first; - E_LookupRuleNode *last; -}; - -typedef struct E_LookupRuleMap E_LookupRuleMap; -struct E_LookupRuleMap -{ - E_LookupRuleSlot *slots; - U64 slots_count; -}; - -typedef struct E_LookupRuleExprPair E_LookupRuleExprPair; -struct E_LookupRuleExprPair -{ - E_LookupRule *rule; - E_Expr *expr; -}; -#endif - //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index e4c8b899..003e05dd 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1159,7 +1159,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) E_Member *mem = &n->v; mem->kind = E_MemberKind_DataField; mem->name = str8_lit("u8s"); - mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count, 0); + mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count, E_TypeFlag_IsNotText); } if(type->byte_size > 4 && type->byte_size%4 == 0) { @@ -1628,7 +1628,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_Member *padding_member = &new_members.v[n->prev_member_idx+padding_idx+1]; MemoryZeroStruct(padding_member); padding_member->kind = E_MemberKind_Padding; - padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, 0); + padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, E_TypeFlag_IsNotText); padding_member->off = n->off; padding_member->name = push_str8f(arena, "[padding %I64u]", padding_idx); padding_idx += 1; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 4c7ae9dd..f887100e 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1559,6 +1559,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) E_Value value = e_value_from_expr(type->args[0]); lens_params.min_digits = value.u64; } + else if(str8_match(type->name, str8_lit("no_string"), 0)) + { + lens_params.flags |= EV_StringFlag_DisableStrings; + } + else if(str8_match(type->name, str8_lit("no_addr"), 0)) + { + lens_params.flags |= EV_StringFlag_DisableAddresses; + } else { lens_applied = 0; @@ -1673,7 +1681,8 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case 0: { // rjf: try strings - if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && + if(!(ptr_data->type->flags & E_TypeFlag_IsNotText) && + !ptr_data->did_prefix_content && ptr_data->ptee_has_string && !(params->flags & EV_StringFlag_DisableStrings) && (type_kind == E_TypeKind_Array || params->flags & EV_StringFlag_ReadOnlyDisplayRules)) @@ -1897,15 +1906,19 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // // rjf: [read only] if we did prefix content, do a parenthesized pointer value - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules && ptr_data->did_prefix_content) + if(!(params->flags & EV_StringFlag_DisableAddresses) && params->flags & EV_StringFlag_ReadOnlyDisplayRules && ptr_data->did_prefix_content) { *out_string = push_str8f(arena, " (%S)", ptr_value_string); } - // rjf: [read only] if we did *not* do any prefix content, do " -> " then descend + // rjf: [read only] if we did *not* do any prefix content, but we have content, + // do " -> " then descend else if(params->flags & EV_StringFlag_ReadOnlyDisplayRules && !ptr_data->did_prefix_content && ptr_data->ptee_has_content) { - *out_string = push_str8f(arena, "%S -> ", ptr_value_string); + if(!(params->flags & EV_StringFlag_DisableAddresses)) + { + *out_string = push_str8f(arena, "%S -> ", ptr_value_string); + } // rjf: single-length pointers -> just gen new task for deref'd expr if(ptr_data->type->count == 1) @@ -1926,7 +1939,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } // rjf: [writeable, catchall] if we did *not* do any prefix content, do "" - else + else if(!ptr_data->did_prefix_content) { *out_string = push_str8_copy(arena, ptr_value_string); } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cc4ce525..56e566f5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5604,7 +5604,7 @@ rd_window_frame(void) if(eval.irtree.mode != E_Mode_Null) { EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; - String8 value_string = rd_value_string_from_eval_NEW(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); + String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); } } @@ -9170,474 +9170,8 @@ rd_window_frame(void) //////////////////////////////// //~ rjf: Eval Visualization -#if 0 // TODO(rjf): @eval -internal F32 -rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - F32 space_taken = 0; - - //- rjf: unpack view rules - U32 radix = default_radix; - U32 min_digits = 0; - B32 no_addr = 0; - B32 no_string = 0; - for(E_Expr *tag = root_eval.exprs.last->first_tag; tag != &e_expr_nil; tag = tag->next) - { - if(0){} - else if(str8_match(tag->string, str8_lit("dec"), 0)) {radix = 10;} - else if(str8_match(tag->string, str8_lit("hex"), 0)) {radix = 16;} - else if(str8_match(tag->string, str8_lit("bin"), 0)) {radix = 2; } - else if(str8_match(tag->string, str8_lit("oct"), 0)) {radix = 8; } - else if(str8_match(tag->string, str8_lit("no_addr"), 0)) {no_addr = 1;} - else if(str8_match(tag->string, str8_lit("no_string"), 0)) {no_string = 1;} - else if(str8_match(tag->string, str8_lit("digits"), 0)) - { - E_Expr *num_expr = tag->first->next; - E_Eval num_eval = e_eval_from_expr(scratch.arena, num_expr); - E_Eval num_value_eval = e_value_eval_from_eval(num_eval); - min_digits = (U32)num_value_eval.value.u64; - } - } - - //- rjf: force no_addr in non-address-spaces - if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - eval.space.kind == RD_EvalSpaceKind_MetaCfg) - { - no_addr = 1; - } - - //- rjf: force no_string, if we are looking at padding members - if(eval.expr->kind == E_ExprKind_MemberAccess) - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, eval.expr->first); - E_TypeKey struct_type = irtree.type_key; - for(B32 done = 0; !done;) - { - E_TypeKind kind = e_type_kind_from_key(struct_type); - if(kind == E_TypeKind_Null || - kind == E_TypeKind_Struct || - kind == E_TypeKind_Union || - kind == E_TypeKind_Class) - { - done = 1; - } - else if(e_type_kind_is_pointer_or_ref(kind)) - { - struct_type = e_type_direct_from_key(struct_type); - } - else - { - break; - } - } - E_Member member = e_type_member_from_key_name__cached(struct_type, eval.expr->first->next->string); - if(member.kind == E_MemberKind_Padding) - { - no_string = 1; - } - } - - //- rjf: type evaluations -> display type string - if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) - { - String8 string = e_type_string_from_key(arena, eval.irtree.type_key); - str8_list_push(arena, out, string); - } - - //- rjf: value/offset evaluations - else if(max_size > 0) - { - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); - E_TypeKind kind = e_type_kind_from_key(type_key); - switch(kind) - { - //- rjf: default - leaf cases - default: - { - E_Eval value_eval = e_value_eval_from_eval(eval); - String8 string = {0}; // ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - str8_list_push(arena, out, string); - }break; - - //- rjf: pointers - case E_TypeKind_Function: - case E_TypeKind_Ptr: - case E_TypeKind_LRef: - case E_TypeKind_RRef: - { - // rjf: unpack type info - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); - E_Type *type = e_type_from_key__cached(type_key); - E_TypeKind type_kind = type->kind; - E_TypeKey direct_type_key = e_type_unwrap(e_type_ptee_from_key(type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - // rjf: unpack info about pointer destination - E_Eval value_eval = e_value_eval_from_eval(eval); - B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void); - B32 ptee_has_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - E_Space space = value_eval.space; - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process == &ctrl_entity_nil) - { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - process = ctrl_process_from_entity(thread); - } - String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, type->depth, 1); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - B32 did_string = 0; - if(!did_content && ptee_has_string && !no_string) - { - did_content = 1; - did_string = 1; - U64 string_memory_addr = value_eval.value.u64; - U64 element_size = e_type_byte_size_from_key(direct_type_key); - U64 string_buffer_size = 1024; - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) - { - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); - if(read_good) - { - break; - } - } - string_buffer[string_buffer_size-1] = 0; - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring((char *)string_buffer);}break; - case 2: {string = str8_from_16(arena, str16_cstring((U16 *)string_buffer));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = string; - if(!no_addr || depth > 0) - { - string_escaped = ev_escaped_from_raw_string(arena, string); - } - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - str8_list_push(arena, out, string_escaped); - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - } - - // rjf: special case: push strings for symbols - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size != 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Void) || - (type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function))) - { - did_content = 1; - str8_list_push(arena, out, symbol_name); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; - } - - // rjf: special case: need symbol name, don't have one - if(value_eval.value.u64 != 0 && - !did_content && symbol_name.size == 0 && - flags & EV_StringFlag_ReadOnlyDisplayRules && - ((type_kind == E_TypeKind_Ptr && direct_type_kind == E_TypeKind_Function) || - (type_kind == E_TypeKind_Function)) && - (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - did_content = 1; - String8 string = str8_lit("???"); - str8_list_push(arena, out, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - } - - // rjf: push pointer value - B32 did_ptr_value = 0; - if(!no_addr || value_eval.value.u64 == 0) - { - did_ptr_value = 1; - if(did_content) - { - String8 left_paren = str8_lit(" ("); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, left_paren).x; - str8_list_push(arena, out, left_paren); - } - String8 string = {0}; // ev_string_from_simple_typed_eval(arena, flags, radix, min_digits, value_eval); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; - str8_list_push(arena, out, string); - if(did_content) - { - String8 right_paren = str8_lit(")"); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, right_paren).x; - str8_list_push(arena, out, right_paren); - } - } - - // rjf: descend for all other cases - B32 did_arrow = 0; - if(value_eval.value.u64 != 0 && !did_content && ptee_has_content && (flags & EV_StringFlag_ReadOnlyDisplayRules)) - { - if(did_ptr_value && !did_arrow) - { - did_arrow = 1; - String8 arrow = str8_lit(" -> "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; - str8_list_push(arena, out, arrow); - } - did_content = 1; - if(depth < 4) - { - if(type->count == 1) - { - E_Expr *deref_expr = e_expr_ref_deref(scratch.arena, eval.expr); - E_Eval deref_eval = e_eval_from_expr(scratch.arena, deref_expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, deref_eval, out); - } - else - { - // rjf: unpack - E_IRTreeAndType irtree = eval.irtree; - E_LookupRule *lookup_rule = &e_lookup_rule__default; - E_Expr *lookup_rule_tag = &e_expr_nil; - E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; - E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; - if(lookup_rule == &e_lookup_rule__default) - { - lookup_rule = root_eval.lookup_rule_tag.rule; - lookup_rule_tag = root_eval.lookup_rule_tag.tag; - } - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); - U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); - String8 opener_string = str8_lit("["); - String8 closer_string = str8_lit("]"); - - // rjf: opener ({, [) - { - str8_list_push(arena, out, opener_string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; - } - - // rjf: contents - { - B32 is_first = 1; - for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) - { - E_Expr *expr = &e_expr_nil; - String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); - if(expr != &e_expr_nil) - { - if(!is_first) - { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - is_first = 0; - E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); - if(space_taken > max_size && idx+1 < total_possible_child_count) - { - String8 ellipses = str8_lit(", ..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); - } - } - } - } - - // rjf: closer (}, ]) - { - str8_list_push(arena, out, closer_string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; - } - } - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - } - }break; - - //- rjf: arrays - case E_TypeKind_Array: - { - // rjf: unpack type info - E_Type *eval_type = e_type_from_key__cached(e_type_unwrap(eval.irtree.type_key)); - E_TypeKey direct_type_key = e_type_unwrap(eval_type->direct_type_key); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - U64 array_count = eval_type->count; - - // rjf: get pointed-at type - B32 array_is_string = ((E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32) || - direct_type_kind == E_TypeKind_S8 || - direct_type_kind == E_TypeKind_U8); - - // rjf: special case: push strings for textual string content - B32 did_content = 0; - if(!did_content && array_is_string && !no_string) - { - U64 element_size = e_type_byte_size_from_key(direct_type_key); - did_content = 1; - U64 string_buffer_size = Clamp(1, array_count, 1024); - U8 *string_buffer = push_array(arena, U8, string_buffer_size); - switch(eval.irtree.mode) - { - default:{}break; - case E_Mode_Offset: - { - U64 string_memory_addr = eval.value.u64; - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+string_buffer_size)); - }break; - case E_Mode_Value: - { - MemoryCopy(string_buffer, &eval.value.u512.u64[0], Min(string_buffer_size, sizeof(eval.value))); - }break; - } - String8 string = {0}; - switch(element_size) - { - default:{string = str8_cstring_capped(string_buffer, string_buffer + string_buffer_size);}break; - case 2: {string = str8_from_16(arena, str16_cstring_capped(string_buffer, string_buffer + string_buffer_size));}break; - case 4: {string = str8_from_32(arena, str32_cstring((U32 *)string_buffer));}break; - } - String8 string_escaped = ev_escaped_from_raw_string(arena, string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string_escaped).x; - space_taken += 2*fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - str8_list_push(arena, out, string_escaped); - if(!no_addr || depth > 0) - { - str8_list_push(arena, out, str8_lit("\"")); - } - } - - // rjf: if we did not do any special content, then go to the regular arrays/structs/sets case - if(!did_content) - { - goto arrays_and_sets_and_structs; - } - }break; - - //- rjf: non-string-arrays/structs/sets - case E_TypeKind_Struct: - case E_TypeKind_Union: - case E_TypeKind_Class: - case E_TypeKind_IncompleteStruct: - case E_TypeKind_IncompleteUnion: - case E_TypeKind_IncompleteClass: - case E_TypeKind_Set: - arrays_and_sets_and_structs: - { - // rjf: unpack - E_IRTreeAndType irtree = eval.irtree; - E_LookupRule *lookup_rule = &e_lookup_rule__default; - E_Expr *lookup_rule_tag = &e_expr_nil; - E_LookupRule *lookup_rule = eval.lookup_rule_tag.rule; - E_Expr *lookup_rule_tag = eval.lookup_rule_tag.tag; - if(lookup_rule == &e_lookup_rule__default) - { - lookup_rule = root_eval.lookup_rule_tag.rule; - lookup_rule_tag = root_eval.lookup_rule_tag.tag; - } - E_LookupInfo lookup_info = lookup_rule->info(arena, &irtree, lookup_rule_tag, filter); - U64 total_possible_child_count = Max(lookup_info.idxed_expr_count, lookup_info.named_expr_count); - String8 opener_string = str8_lit("{"); - String8 closer_string = str8_lit("}"); - if(lookup_info.idxed_expr_count > lookup_info.named_expr_count) - { - opener_string = str8_lit("["); - closer_string = str8_lit("]"); - } - - // rjf: opener ({, [) - { - str8_list_push(arena, out, opener_string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, opener_string).x; - } - - // rjf: build contents - if(depth < 4) - { - B32 is_first = 1; - for(U64 idx = 0; idx < total_possible_child_count && max_size > space_taken; idx += 1) - { - E_Expr *expr = &e_expr_nil; - String8 expr_string = {0}; - lookup_rule->range(scratch.arena, eval.exprs.last, lookup_rule_tag, filter, r1u64(idx, idx+1), &expr, &expr_string, lookup_info.user_data); - if(expr != &e_expr_nil) - { - if(!is_first) - { - String8 comma = str8_lit(", "); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; - str8_list_push(arena, out, comma); - } - is_first = 0; - E_Eval child_eval = e_eval_from_expr(scratch.arena, expr); - space_taken += rd_append_value_strings_from_eval(arena, filter, flags, radix, font, font_size, max_size-space_taken, depth+1, root_eval, child_eval, out); - if(space_taken > max_size && idx+1 < total_possible_child_count) - { - String8 ellipses = str8_lit(", ..."); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - str8_list_push(arena, out, ellipses); - } - } - } - } - else - { - String8 ellipses = str8_lit("..."); - str8_list_push(arena, out, ellipses); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; - } - - // rjf: closer (}, ]) - { - str8_list_push(arena, out, closer_string); - space_taken += fnt_dim_from_tag_size_string(font, font_size, 0, 0, closer_string).x; - } - }break; - } - } - - scratch_end(scratch); - ProfEnd(); - return space_taken; -} - internal String8 -rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) -{ - Temp scratch = scratch_begin(&arena, 1); - String8List strs = {0}; - rd_append_value_strings_from_eval(scratch.arena, filter, flags, default_radix, font, font_size, max_size, 0, eval, eval, &strs); - String8 result = str8_list_join(arena, &strs, 0); - scratch_end(scratch); - return result; -} -#endif - -internal String8 -rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) +rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval) { Temp scratch = scratch_begin(&arena, 1); String8List strs = {0}; @@ -12712,6 +12246,8 @@ rd_frame(void) {str8_lit("dec"), 1}, {str8_lit("hex"), 1}, {str8_lit("digits"), 1}, + {str8_lit("no_string"), 1}, + {str8_lit("no_addr"), 1}, {str8_lit("text"), 0, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), 0, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 83a604ee..514feb8d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1003,11 +1003,7 @@ internal void rd_window_frame(void); //////////////////////////////// //~ rjf: Eval Visualization -#if 0 // TODO(rjf): @eval -internal F32 rd_append_value_strings_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval root_eval, E_Eval eval, String8List *out); -internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); -#endif -internal String8 rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); +internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringParams *params, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval); //////////////////////////////// //~ rjf: Hover Eval diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 09afb46b..95766c6e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1500,10 +1500,15 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { string_params.radix = 16; } + if(result.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && + rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Thread) + { + string_params.radix = 16; + } } //- rjf: generate strings/flags based on that expression & fill - result.string = rd_value_string_from_eval_NEW(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); + result.string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1ec9c77a..13867ed7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1979,7 +1979,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; - eval_string = rd_value_string_from_eval_NEW(scratch.arena, str8_zero(), &string_params, params->font, params->font_size, params->font_size*60.f, eval); + eval_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, params->font, params->font_size, params->font_size*60.f, eval); } ui_spacer(ui_em(1.5f, 1.f)); ui_set_next_pref_width(ui_children_sum(1)); From 0dd0f1b8bcfe7188c97613cb4729aacea49a2bad Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 15:19:29 -0700 Subject: [PATCH 337/755] rephrase type irgen hook -> irext, to eliminate cases where it'd be very easy to accidentally cause infinite recursion of ir generation (e.g. slice(x) requiring evaluation of 'lhs.count', where lhs == slice(x)). also bring back slice hooks --- src/eval/eval_core.h | 16 +- src/eval/eval_ir.c | 21 +- src/eval/eval_ir.h | 1 + src/eval/eval_types.c | 192 +++++++++++++++++- src/eval/eval_types.h | 11 +- .../eval_visualization_core.c | 18 +- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 76 ++++--- src/raddbg/raddbg_eval.c | 20 +- src/raddbg/raddbg_eval.h | 8 +- 10 files changed, 297 insertions(+), 68 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 99fd2ea5..a3b7f9de 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -352,6 +352,12 @@ struct E_EnumValArray U64 count; }; +typedef struct E_IRExt E_IRExt; +struct E_IRExt +{ + void *user_data; +}; + typedef struct E_TypeExpandInfo E_TypeExpandInfo; struct E_TypeExpandInfo { @@ -359,10 +365,10 @@ struct E_TypeExpandInfo U64 expr_count; }; -#define E_TYPE_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_IRTreeAndType *irtree) -#define E_TYPE_IRGEN_FUNCTION_NAME(name) e_type_irgen__##name -#define E_TYPE_IRGEN_FUNCTION_DEF(name) internal E_TYPE_IRGEN_FUNCTION_SIG(E_TYPE_IRGEN_FUNCTION_NAME(name)) -typedef E_TYPE_IRGEN_FUNCTION_SIG(E_TypeIRGenFunctionType); +#define E_TYPE_IREXT_FUNCTION_SIG(name) E_IRExt name(Arena *arena, E_Expr *expr, E_IRTreeAndType *irtree) +#define E_TYPE_IREXT_FUNCTION_NAME(name) e_type_irext__##name +#define E_TYPE_IREXT_FUNCTION_DEF(name) internal E_TYPE_IREXT_FUNCTION_SIG(E_TYPE_IREXT_FUNCTION_NAME(name)) +typedef E_TYPE_IREXT_FUNCTION_SIG(E_TypeIRExtFunctionType); #define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree) #define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name @@ -415,7 +421,7 @@ struct E_Type E_Member *members; E_EnumVal *enum_vals; E_Expr **args; - E_TypeIRGenFunctionType *irgen; + E_TypeIRExtFunctionType *irext; E_TypeAccessFunctionType *access; E_TypeExpandRule expand; }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 182a469c..fe1b3f28 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2203,7 +2203,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) .count = arg_count, .args = args, .direct_key = result.type_key, - .name = lhs_type->name); + .name = lhs_type->name, + .irext = lhs_type->irext, + .access = lhs_type->access, + .expand = lhs_type->expand); scratch_end(scratch); } @@ -2727,7 +2730,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); + result.type_key = e_type_state->file_type_key; result.mode = E_Mode_Value; } else @@ -2738,7 +2741,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); + result.type_key = e_type_state->folder_type_key; result.mode = E_Mode_Value; } } @@ -2778,9 +2781,15 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: if the evaluated type has a hook for an extra layer of ir generation, // call into it E_Type *type = e_type_from_key__cached(result.type_key); - if(type->irgen != 0) + if(type->kind != E_TypeKind_LensSpec && type->irext != 0) { - result = type->irgen(arena, &result); + E_IRTreeAndType irtree_stripped = result; + if(type->kind == E_TypeKind_Lens) + { + irtree_stripped.type_key = e_type_direct_from_key(irtree_stripped.type_key); + } + E_IRExt ext = type->irext(arena, expr, &irtree_stripped); + result.user_data = ext.user_data; } //- rjf: find any auto hooks according to this generation's type @@ -2827,7 +2836,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) .name = src_type->name, .count = src_type->count, .args = src_type->args, - .irgen = src_type->irgen, + .irext = src_type->irext, .access = src_type->access, .expand = src_type->expand, .direct_key = result.type_key); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index dc266067..134f26dc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -229,6 +229,7 @@ internal void e_expr_poison(E_Expr *expr); internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction +E_TYPE_ACCESS_FUNCTION_DEF(default); internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); //- rjf: irtree -> linear ops/bytecode diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 003e05dd..57a3c53e 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -250,7 +250,7 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); e_type_state->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file"), - .irgen = E_TYPE_IRGEN_FUNCTION_NAME(file), + .irext = E_TYPE_IREXT_FUNCTION_NAME(file), .access = E_TYPE_ACCESS_FUNCTION_NAME(file), .expand = { @@ -671,7 +671,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->count = node->params.count; type->depth = node->params.depth; type->arch = node->params.arch; - type->irgen = node->params.irgen; + type->irext = node->params.irext; type->access = node->params.access; type->expand = node->params.expand; type->byte_size = node->byte_size; @@ -2313,6 +2313,188 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) return id; } +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `slice` lens + +typedef struct E_SliceAccel E_SliceAccel; +struct E_SliceAccel +{ + Arch arch; + U64 count; + U64 base_ptr_vaddr; + E_TypeKey element_type_key; +}; + +E_TYPE_IREXT_FUNCTION_DEF(slice) +{ + E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: unpack struct type + E_TypeKey struct_type_key = e_type_unwrap(irtree->type_key); + for(;;) + { + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key))) + { + struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key)); + } + else + { + break; + } + } + + // rjf: build info from struct type + E_TypeKind type_kind = e_type_kind_from_key(struct_type_key); + if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) + { + // rjf: unpack members + E_MemberArray members = e_type_data_members_from_key__cached(struct_type_key); + + // rjf: choose base pointer & count members + E_Member *base_ptr_member = 0; + E_Member *opl_ptr_member = 0; + E_Member *count_member = 0; + for(U64 idx = 0; idx < members.count; idx += 1) + { + E_Member *member = &members.v[idx]; + E_TypeKey member_type = e_type_unwrap(member->type_key); + E_TypeKind member_type_kind = e_type_kind_from_key(member_type); + if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) + { + count_member = member; + } + if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + base_ptr_member = &members.v[idx]; + } + else if(base_ptr_member != 0 && opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) + { + opl_ptr_member = &members.v[idx]; + } + if(count_member != 0 && base_ptr_member != 0) + { + break; + } + else if(base_ptr_member != 0 && opl_ptr_member != 0) + { + break; + } + } + + // rjf: determine architecture + Arch arch = e_type_state->ctx->primary_module->arch; + if(base_ptr_member != 0) + { + E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); + arch = type->arch; + } + + // rjf: evaluate count member, determine count + U64 count = 0; + if(count_member != 0) + { + E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, irtree, count_member->name); + E_Value count_member_value = e_value_from_expr(count_member_expr); + count = count_member_value.u64; + } + + // rjf: evaluate base ptr member, determine base address + U64 base_ptr_vaddr = 0; + if(base_ptr_member != 0) + { + E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, base_ptr_member->name); + E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr); + base_ptr_vaddr = base_ptr_member_value.u64; + } + + // rjf: evaluate opl ptr member, determine opl address + U64 opl_ptr_vaddr = 0; + if(count_member == 0 && opl_ptr_member != 0) + { + E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, opl_ptr_member->name); + E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr); + opl_ptr_vaddr = opl_ptr_member_value.u64; + } + + // rjf: determine element type + E_TypeKey element_type_key = zero_struct; + if(base_ptr_member != 0) + { + element_type_key = e_type_direct_from_key(base_ptr_member->type_key); + } + + // rjf: if no count, but base/opl, swap base/opl if needed, and measure count + if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0) + { + U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr); + U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr); + base_ptr_vaddr = min_vaddr; + opl_ptr_vaddr = max_vaddr; + count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key); + } + + // rjf: fill + if((count_member || opl_ptr_member) && base_ptr_member) + { + accel->arch = arch; + accel->count = count; + accel->base_ptr_vaddr = base_ptr_vaddr; + accel->element_type_key = element_type_key; + } + } + scratch_end(scratch); + } + E_IRExt result = {accel}; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(slice) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + E_SliceAccel *accel = (E_SliceAccel *)lhs_irtree->user_data; + switch(expr->kind) + { + default: + case E_ExprKind_MemberAccess: + { + result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, expr, lhs_irtree); + }break; + case E_ExprKind_ArrayIndex: + { + E_Value rhs_value = e_value_from_expr(expr->first->next); + U64 rhs_idx = rhs_value.u64; + if(0 <= rhs_idx && rhs_idx < accel->count) + { + E_Type *element_type = e_type_from_key__cached(accel->element_type_key); + U64 offset = element_type->byte_size*rhs_idx; + U64 vaddr = accel->base_ptr_vaddr + offset; + result.root = e_irtree_const_u(arena, vaddr); + result.type_key = accel->element_type_key; + result.mode = E_Mode_Offset; + } + }break; + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice) +{ + E_SliceAccel *accel = (E_SliceAccel *)irtree->user_data; + E_TypeExpandInfo info = {accel, accel->count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice) +{ + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); + } +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `folder` type @@ -2476,7 +2658,7 @@ struct E_FileAccel String8Array fields; }; -E_TYPE_IRGEN_FUNCTION_DEF(file) +E_TYPE_IREXT_FUNCTION_DEF(file) { E_IRTreeAndType result = *irtree; E_FileAccel *accel = push_array(arena, E_FileAccel, 1); @@ -2507,8 +2689,8 @@ E_TYPE_IRGEN_FUNCTION_DEF(file) scratch_end(scratch); } - result.user_data = accel; - return result; + E_IRExt ext = {accel}; + return ext; } E_TYPE_ACCESS_FUNCTION_DEF(file) diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index cb5e06f7..5103fa3c 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -47,7 +47,7 @@ struct E_ConsTypeParams E_Member *members; E_EnumVal *enum_vals; E_Expr **args; - E_TypeIRGenFunctionType *irgen; + E_TypeIRExtFunctionType *irext; E_TypeAccessFunctionType *access; E_TypeExpandRule expand; }; @@ -291,6 +291,13 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `slice` lens + +E_TYPE_IREXT_FUNCTION_DEF(slice); +E_TYPE_ACCESS_FUNCTION_DEF(slice); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `folder` type @@ -302,7 +309,7 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(folder); //////////////////////////////// //~ rjf: (Built-In Type Hooks) `file` type -E_TYPE_IRGEN_FUNCTION_DEF(file); +E_TYPE_IREXT_FUNCTION_DEF(file); E_TYPE_ACCESS_FUNCTION_DEF(file); E_TYPE_EXPAND_INFO_FUNCTION_DEF(file); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index f887100e..bf8aee74 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1546,6 +1546,12 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // case E_TypeKind_Lens: { + if(it->top_task->redirect_to_sets_and_structs) + { + expansion_opener_symbol = str8_lit("["); + expansion_closer_symbol = str8_lit("]"); + goto arrays_and_sets_and_structs; + } E_Type *type = e_type_from_key__cached(type_key); B32 lens_applied = 1; EV_StringParams lens_params = *params; @@ -1579,6 +1585,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_task.eval = eval; new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); } + else if(type->expand.info != 0) + { + need_new_task = 1; + need_pop = 1; + new_task.params = *params; + new_task.eval = eval; + new_task.redirect_to_sets_and_structs = 1; + } else switch(task_idx) { default:{}break; @@ -1639,7 +1653,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_RRef: case E_TypeKind_Array: { - if(type_kind == E_TypeKind_Array && it->top_task->redirect_array_to_sets_and_structs) + if(type_kind == E_TypeKind_Array && it->top_task->redirect_to_sets_and_structs) { expansion_opener_symbol = str8_lit("["); expansion_closer_symbol = str8_lit("]"); @@ -1876,7 +1890,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_pop = 0; new_task.params = *params; new_task.eval = eval; - new_task.redirect_array_to_sets_and_structs = 1; + new_task.redirect_to_sets_and_structs = 1; ptr_data->did_redirect = 1; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 35a20c57..3967e505 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -256,7 +256,7 @@ struct EV_StringIterTask E_Eval eval; U64 idx; S32 depth; - B32 redirect_array_to_sets_and_structs; + B32 redirect_to_sets_and_structs; void *user_data; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 56e566f5..9ba31be5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11850,7 +11850,7 @@ rd_frame(void) String8 name = rd_name_schema_info_table[idx].name; E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set, - .irgen = E_TYPE_IRGEN_FUNCTION_NAME(schema), + .irext = E_TYPE_IREXT_FUNCTION_NAME(schema), .access = E_TYPE_ACCESS_FUNCTION_NAME(schema), .expand = { @@ -11998,7 +11998,7 @@ rd_frame(void) e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment"), .flags = E_TypeFlag_EditableChildren, - .irgen = E_TYPE_IRGEN_FUNCTION_NAME(environment), + .irext = E_TYPE_IREXT_FUNCTION_NAME(environment), .access = E_TYPE_ACCESS_FUNCTION_NAME(environment), .expand = { @@ -12012,7 +12012,7 @@ rd_frame(void) str8_lit("call_stack"), e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack"), - .irgen = E_TYPE_IRGEN_FUNCTION_NAME(call_stack), + .irext = E_TYPE_IREXT_FUNCTION_NAME(call_stack), .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack), .expand = { @@ -12082,7 +12082,7 @@ rd_frame(void) String8 cfg_name = evallable_cfg_names[cfg_name_idx]; String8 collection_name = rd_plural_from_code_name(cfg_name); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, - .irgen = E_TYPE_IRGEN_FUNCTION_NAME(cfgs), + .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs), .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs), .expand = { @@ -12227,60 +12227,74 @@ rd_frame(void) e_select_ir_ctx(ir_ctx); //////////////////////////// - //- rjf: generate macros for all view rules + //- rjf: generate macros for all lenses // { - //- rjf: choose set of view rules + //- rjf: choose set of lenses // TODO(rjf): generate via metaprogram struct { String8 name; B32 inherited; + E_TypeIRExtFunctionType *irext; + E_TypeAccessFunctionType *access; + E_TypeExpandRule expand; RD_ViewUIFunctionType *ui; - EV_ExpandRuleInfoHookFunctionType *expand; + EV_ExpandRuleInfoHookFunctionType *ev_expand; } - view_ui_rule_table[] = + lens_table[] = { - {str8_lit("bin"), 1}, - {str8_lit("oct"), 1}, - {str8_lit("dec"), 1}, - {str8_lit("hex"), 1}, - {str8_lit("digits"), 1}, - {str8_lit("no_string"), 1}, - {str8_lit("no_addr"), 1}, - {str8_lit("text"), 0, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, - {str8_lit("disasm"), 0, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, - {str8_lit("memory"), 0, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, - {str8_lit("bitmap"), 0, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), 0, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), 0, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), 0, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + {str8_lit("bin"), 1, 0, 0, {0}}, + {str8_lit("oct"), 1, 0, 0, {0}}, + {str8_lit("dec"), 1, 0, 0, {0}}, + {str8_lit("hex"), 1, 0, 0, {0}}, + {str8_lit("digits"), 1, 0, 0, {0}}, + {str8_lit("no_string"), 1, 0, 0, {0}}, + {str8_lit("no_addr"), 1, 0, 0, {0}}, + {str8_lit("slice"), 0, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, + {str8_lit("text"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; - //- rjf: fill view ui rules in expand rule map, view ui rule map + //- rjf: fill lenses in ev expand rule map, rd view ui rule map EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); ev_select_expand_rule_table(expand_rule_table); rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); { - for EachElement(idx, view_ui_rule_table) + for EachElement(idx, lens_table) { - rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, view_ui_rule_table[idx].name, view_ui_rule_table[idx].ui); - if(view_ui_rule_table[idx].expand != 0) + if(lens_table[idx].ui != 0) { - ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, view_ui_rule_table[idx].name, view_ui_rule_table[idx].expand); + rd_view_ui_rule_map_insert(scratch.arena, rd_state->view_ui_rule_map, lens_table[idx].name, lens_table[idx].ui); + } + if(lens_table[idx].ev_expand != 0) + { + ev_expand_rule_table_push_new(scratch.arena, expand_rule_table, lens_table[idx].name, lens_table[idx].ev_expand); } } } - for EachElement(idx, view_ui_rule_table) + + //- rjf: fill macros w/ types for lenses + for EachElement(idx, lens_table) { E_TypeFlags type_flags = 0; - if(view_ui_rule_table[idx].inherited) + if(lens_table[idx].inherited) { type_flags |= E_TypeFlag_InheritedOnAccess; } E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .flags = type_flags, .name = view_ui_rule_table[idx].name); - e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, + .flags = type_flags, + .name = lens_table[idx].name, + .irext = lens_table[idx].irext, + .access = lens_table[idx].access, + .expand = lens_table[idx].expand); + e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, lens_table[idx].name, expr); } } diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index defd8482..9cfcc3cb 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -285,9 +285,8 @@ struct RD_SchemaIRExt MD_Node *schema; }; -E_TYPE_IRGEN_FUNCTION_DEF(schema) +E_TYPE_IREXT_FUNCTION_DEF(schema) { - E_IRTreeAndType result = *irtree; RD_SchemaIRExt *ext = push_array(arena, RD_SchemaIRExt, 1); { Temp scratch = scratch_begin(&arena, 1); @@ -302,7 +301,7 @@ E_TYPE_IRGEN_FUNCTION_DEF(schema) ext->schema = schema; scratch_end(scratch); } - result.user_data = ext; + E_IRExt result = {ext}; return result; } @@ -503,9 +502,8 @@ struct RD_CfgsIRExt Rng1U64 cfgs_idx_range; }; -E_TYPE_IRGEN_FUNCTION_DEF(cfgs) +E_TYPE_IREXT_FUNCTION_DEF(cfgs) { - E_IRTreeAndType result = *irtree; RD_CfgsIRExt *ext = push_array(arena, RD_CfgsIRExt, 1); { Temp scratch = scratch_begin(&arena, 1); @@ -536,7 +534,7 @@ E_TYPE_IRGEN_FUNCTION_DEF(cfgs) scratch_end(scratch); } - result.user_data = ext; + E_IRExt result = {ext}; return result; } @@ -712,9 +710,8 @@ struct RD_CallStackAccel CTRL_CallStack call_stack; }; -E_TYPE_IRGEN_FUNCTION_DEF(call_stack) +E_TYPE_IREXT_FUNCTION_DEF(call_stack) { - E_IRTreeAndType result = *irtree; RD_CallStackAccel *accel = push_array(arena, RD_CallStackAccel, 1); { Temp scratch = scratch_begin(&arena, 1); @@ -732,7 +729,7 @@ E_TYPE_IRGEN_FUNCTION_DEF(call_stack) } scratch_end(scratch); } - result.user_data = accel; + E_IRExt result = {accel}; return result; } @@ -774,9 +771,8 @@ struct RD_EnvironmentAccel RD_CfgArray cfgs; }; -E_TYPE_IRGEN_FUNCTION_DEF(environment) +E_TYPE_IREXT_FUNCTION_DEF(environment) { - E_IRTreeAndType result = *irtree; RD_EnvironmentAccel *accel = push_array(arena, RD_EnvironmentAccel, 1); { Temp scratch = scratch_begin(&arena, 1); @@ -796,7 +792,7 @@ E_TYPE_IRGEN_FUNCTION_DEF(environment) accel->cfgs = rd_cfg_array_from_list(arena, &env_strings); scratch_end(scratch); } - result.user_data = accel; + E_IRExt result = {accel}; return result; } diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 5c1627cb..2c01a48e 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -34,7 +34,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers); //////////////////////////////// //~ rjf: Schema Type Hooks -E_TYPE_IRGEN_FUNCTION_DEF(schema); +E_TYPE_IREXT_FUNCTION_DEF(schema); E_TYPE_ACCESS_FUNCTION_DEF(schema); E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); @@ -42,7 +42,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); //////////////////////////////// //~ rjf: Config Collection Type Hooks -E_TYPE_IRGEN_FUNCTION_DEF(cfgs); +E_TYPE_IREXT_FUNCTION_DEF(cfgs); E_TYPE_ACCESS_FUNCTION_DEF(cfgs); E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs); @@ -52,14 +52,14 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs); //////////////////////////////// //~ rjf: `call_stack` Type Hooks -E_TYPE_IRGEN_FUNCTION_DEF(call_stack); +E_TYPE_IREXT_FUNCTION_DEF(call_stack); E_TYPE_ACCESS_FUNCTION_DEF(call_stack); E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); //////////////////////////////// //~ rjf: `environment` Type Hooks -E_TYPE_IRGEN_FUNCTION_DEF(environment); +E_TYPE_IREXT_FUNCTION_DEF(environment); E_TYPE_ACCESS_FUNCTION_DEF(environment); E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment); From b7e12f900c0f2d899a00ab30552a2f6fca90165b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 15:19:58 -0700 Subject: [PATCH 338/755] eliminate dead code --- src/eval/eval_ir.c | 421 --------------------------------------------- 1 file changed, 421 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index fe1b3f28..5701988f 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -103,427 +103,6 @@ e_select_ir_ctx(E_IRCtx *ctx) } } -//////////////////////////////// -//~ rjf: Slice Lookup Rules - -#if 0 // TODO(rjf): @eval -typedef struct E_SliceAccel E_SliceAccel; -struct E_SliceAccel -{ - Arch arch; - U64 count; - U64 base_ptr_vaddr; - E_TypeKey element_type_key; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(slice) -{ - E_LookupInfo info = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - // rjf: unpack struct type - E_TypeKey struct_type_key = e_type_unwrap(lhs->type_key); - for(;;) - { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key))) - { - struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key)); - } - else - { - break; - } - } - - // rjf: build info from struct type - E_TypeKind type_kind = e_type_kind_from_key(struct_type_key); - if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) - { - // rjf: unpack members - E_MemberArray members = e_type_data_members_from_key__cached(struct_type_key); - - // rjf: choose base pointer & count members - E_Member *base_ptr_member = 0; - E_Member *opl_ptr_member = 0; - E_Member *count_member = 0; - for(U64 idx = 0; idx < members.count; idx += 1) - { - E_Member *member = &members.v[idx]; - E_TypeKey member_type = e_type_unwrap(member->type_key); - E_TypeKind member_type_kind = e_type_kind_from_key(member_type); - if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) - { - count_member = member; - } - if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) - { - base_ptr_member = &members.v[idx]; - } - else if(base_ptr_member != 0 && opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind)) - { - opl_ptr_member = &members.v[idx]; - } - if(count_member != 0 && base_ptr_member != 0) - { - break; - } - else if(base_ptr_member != 0 && opl_ptr_member != 0) - { - break; - } - } - - // rjf: determine architecture - Arch arch = e_type_state->ctx->primary_module->arch; - if(base_ptr_member != 0) - { - E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); - arch = type->arch; - } - - // rjf: evaluate count member, determine count - U64 count = 0; - if(count_member != 0) - { - E_Expr *count_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, count_member->name); - E_Value count_member_value = e_value_from_expr(count_member_expr); - count = count_member_value.u64; - } - - // rjf: evaluate base ptr member, determine base address - U64 base_ptr_vaddr = 0; - if(base_ptr_member != 0) - { - E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, base_ptr_member->name); - E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr); - base_ptr_vaddr = base_ptr_member_value.u64; - } - - // rjf: evaluate opl ptr member, determine opl address - U64 opl_ptr_vaddr = 0; - if(count_member == 0 && opl_ptr_member != 0) - { - E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, opl_ptr_member->name); - E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr); - opl_ptr_vaddr = opl_ptr_member_value.u64; - } - - // rjf: determine element type - E_TypeKey element_type_key = zero_struct; - if(base_ptr_member != 0) - { - element_type_key = e_type_direct_from_key(base_ptr_member->type_key); - } - - // rjf: if no count, but base/opl, swap base/opl if needed, and measure count - if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0) - { - U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr); - U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr); - base_ptr_vaddr = min_vaddr; - opl_ptr_vaddr = max_vaddr; - count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key); - } - - // rjf: fill - if((count_member || opl_ptr_member) && base_ptr_member) - { - E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); - accel->arch = arch; - accel->count = count; - accel->base_ptr_vaddr = base_ptr_vaddr; - accel->element_type_key = element_type_key; - info.user_data = accel; - info.idxed_expr_count = accel->count; - } - - // rjf: fall back to default - else - { - info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); - } - } - scratch_end(scratch); - } - return info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(slice) -{ - if(user_data == 0) - { - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); - } - else - { - E_SliceAccel *accel = (E_SliceAccel *)user_data; - U64 out_idx = 0; - U64 element_type_size = e_type_byte_size_from_key(accel->element_type_key); - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->value.u64 = accel->base_ptr_vaddr + idx*element_type_size; - expr->type_key = accel->element_type_key; - exprs[out_idx] = expr; - exprs_strings[out_idx] = push_str8f(arena, "[%I64u]", idx); - } - } -} - -E_LOOKUP_ACCESS_FUNCTION_DEF(default) -{ - // - // TODO(rjf): need to define what it means to access a set expression - // whose type *does not* define its IR generation rules, BUT it does - // define specific child expressions. so e.g. `watches`, does not - // define `watches[0]`, because it has defined that `watches[0]` - // maps to another expression, which is whatever the first watch - // expression is (e.g. `basics`). so, in that case, we can just use - // the lookup-range rule, grab the Nth expression, and IR-ify *that*. - // - E_LookupAccess result = {{&e_irnode_nil}}; - switch(kind) - { - default:{}break; - - //- rjf: member accessing - case E_ExprKind_MemberAccess: - { - // rjf: unpack left/right expressions - E_Expr *exprl = lhs; - E_Expr *exprr = rhs; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKey check_type_key = l_restype; - E_TypeKind check_type_kind = l_restype_kind; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); - check_type_kind = e_type_kind_from_key(check_type_key); - } - e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); - - // rjf: look up member - E_Member member = zero_struct; - B32 r_found = 0; - E_TypeKey r_type = zero_struct; - U64 r_value = 0; - B32 r_is_constant_value = 0; - { - Temp scratch = scratch_begin(&arena, 1); - E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); - member = match; - if(match.kind != E_MemberKind_Null) - { - r_found = 1; - r_type = match.type_key; - r_value = match.off; - } - if(match.kind == E_MemberKind_Null) - { - E_Type *type = e_type_from_key__cached(check_type_key); - if(type->enum_vals != 0) - { - String8 lookup_string = exprr->string; - String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); - String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); - E_EnumVal *enum_val_match = 0; - for EachIndex(idx, type->count) - { - if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) - { - enum_val_match = &type->enum_vals[idx]; - break; - } - } - if(enum_val_match != 0) - { - r_found = 1; - r_type = check_type_key; - r_value = enum_val_match->val; - r_is_constant_value = 1; - } - } - } - scratch_end(scratch); - } - - // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(e_type_key_zero(), check_type_key)) - { - break; - } - else if(exprr->kind != E_ExprKind_LeafIdentifier) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); - break; - } - else if(!r_found) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); - break; - } - else if(check_type_kind != E_TypeKind_Struct && - check_type_kind != E_TypeKind_Class && - check_type_kind != E_TypeKind_Union && - check_type_kind != E_TypeKind_Enum) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); - break; - } - - // rjf: generate - { - // rjf: build tree - E_IRNode *new_tree = l.root; - E_TypeKey new_tree_type = r_type; - E_Mode mode = l.mode; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); - mode = E_Mode_Offset; - } - if(r_value != 0 && !r_is_constant_value) - { - E_IRNode *const_tree = e_irtree_const_u(arena, r_value); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); - } - else if(r_is_constant_value) - { - new_tree = e_irtree_const_u(arena, r_value); - mode = E_Mode_Value; - } - - // rjf: fill - result.irtree_and_type.root = new_tree; - result.irtree_and_type.type_key = r_type; - result.irtree_and_type.mode = mode; - } - }break; - - //- rjf: array indexing - case E_ExprKind_ArrayIndex: - { - // rjf: unpack left/right expressions - E_Expr *exprl = lhs; - E_Expr *exprr = rhs; - E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); - E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKey r_restype = e_type_unwrap(r.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); - if(e_type_kind_is_basic_or_enum(r_restype_kind)) - { - r_restype = e_type_unwrap_enum(r_restype); - r_restype_kind = e_type_kind_from_key(r_restype); - } - E_TypeKey direct_type = e_type_unwrap(l_restype); - direct_type = e_type_direct_from_key(direct_type); - direct_type = e_type_unwrap(direct_type); - U64 direct_type_size = e_type_byte_size_from_key(direct_type); - e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs); - e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &r.msgs); - - // rjf: bad conditions? -> error if applicable, exit - if(r.root->op == 0) - { - break; - } - else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); - break; - } - else if(!e_type_kind_is_integer(r_restype_kind)) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); - break; - } - else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); - break; - } - else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) - { - e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); - break; - } - - // rjf: generate - E_IRNode *new_tree = &e_irnode_nil; - E_Mode mode = l.mode; - { - // rjf: reading from an array value -> read from stack value - if(l.mode == E_Mode_Value && l_restype_kind == E_TypeKind_Array) - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to push stack value, push offset, + read from stack value - new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); - new_tree->value.u64 = direct_type_size; - e_irnode_push_child(new_tree, offset_tree); - e_irnode_push_child(new_tree, l.root); - } - - // rjf: all other cases -> read from base offset - else - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) - E_IRNode *base_tree = l.root; - if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) - { - base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); - } - - // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - } - } - - // rjf: fill - result.irtree_and_type.root = new_tree; - result.irtree_and_type.type_key = direct_type; - result.irtree_and_type.mode = mode; - }break; - } - return result; -} - -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default) -{ - return num; -} - -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default) -{ - return id; -} -#endif - //////////////////////////////// //~ rjf: Member Filtering Lookup Rules From 297c57662355022f4d0333955d3ed487e3229197 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 16:20:52 -0700 Subject: [PATCH 339/755] irtree parent experiment (failed) --- src/eval/eval_ir.c | 55 ++++++++++++++++++++++++++++++++++++---- src/eval/eval_ir.h | 16 ++++++++++++ src/raddbg/raddbg_core.c | 10 ++++++-- 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5701988f..3f5836e4 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -90,6 +90,8 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); e_ir_state->string_id_map->hash_slots_count = 1024; e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); + e_ir_state->top_parent = 0; + e_ir_state->free_parent = 0; String8 builtin_view_rule_names[] = { str8_lit_comp("bswap"), @@ -817,6 +819,32 @@ e_expr_unpoison(E_Expr *expr) } } +//- rjf: irtree parent selection + +internal void +e_push_irtree_parent(E_IRTreeAndType parent) +{ + E_IRParentNode *parent_n = e_ir_state->free_parent; + if(parent_n != 0) + { + SLLStackPop(e_ir_state->free_parent); + } + else + { + parent_n = push_array(e_ir_state->arena, E_IRParentNode, 1); + } + parent_n->v = parent; + SLLStackPush(e_ir_state->top_parent, parent_n); +} + +internal void +e_pop_irtree_parent(void) +{ + E_IRParentNode *popped = e_ir_state->top_parent; + SLLStackPop(e_ir_state->top_parent); + SLLStackPush(e_ir_state->free_parent, popped); +} + //- rjf: default type access hook E_TYPE_ACCESS_FUNCTION_DEF(default) @@ -1073,12 +1101,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { Task *next; E_Expr *expr; - E_Expr *parent_expr; - E_IRTreeAndType parent_irtree_and_type; }; - Task start_task = {0, root_expr, &e_expr_nil, {&e_irnode_nil}}; + Task start_task = {0, root_expr}; Task *first_task = &start_task; Task *last_task = first_task; + U64 num_parents = 0; for(Task *t = first_task; t != 0; t = t->next) { E_Expr *expr = t->expr; @@ -2038,6 +2065,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } + //- rjf: try to map name as parent expression signifier ('$') + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->top_parent != 0) + { + E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->top_parent->v.root); + string_mapped = 1; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = e_ir_state->top_parent->v.mode; + mapped_type_key = e_ir_state->top_parent->v.type_key; + } + //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) { @@ -2384,8 +2421,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; - task->parent_expr = expr; - task->parent_irtree_and_type = result; + e_push_irtree_parent(result); + num_parents += 1; break; } } @@ -2401,6 +2438,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_expr_unpoison(t->expr); } + ////////////////////////////// + //- rjf: pop all the parents that we used + // + for EachIndex(idx, num_parents) + { + e_pop_irtree_parent(); + } + ////////////////////////////// //- rjf: apply inherited lenses to the resultant type // diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 134f26dc..4f6fefb4 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -140,6 +140,13 @@ struct E_IRCtx //////////////////////////////// //~ rjf: IR State +typedef struct E_IRParentNode E_IRParentNode; +struct E_IRParentNode +{ + E_IRParentNode *next; + E_IRTreeAndType v; +}; + typedef struct E_IRState E_IRState; struct E_IRState { @@ -152,6 +159,10 @@ struct E_IRState // rjf: unpacked ctx RDI_Procedure *thread_ip_procedure; + // rjf: parent stack + E_IRParentNode *top_parent; + E_IRParentNode *free_parent; + // rjf: caches E_UsedExprMap *used_expr_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; @@ -228,6 +239,11 @@ internal B32 e_expr_is_poisoned(E_Expr *expr); internal void e_expr_poison(E_Expr *expr); internal void e_expr_unpoison(E_Expr *expr); +//- rjf: irtree parent selection +internal void e_push_irtree_parent(E_IRTreeAndType parent); +internal void e_pop_irtree_parent(void); +#define E_IRTreeParentScope(p) DeferLoop(e_push_irtree_parent(p), e_pop_irtree_parent()) + //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9ba31be5..14d4d1b2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4056,7 +4056,10 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); + E_IRTreeParentScope(cell_info.eval.irtree) + { + cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); + } // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4475,7 +4478,10 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - view_ui_rule->ui(expr_eval, rect); + E_IRTreeParentScope(expr_eval.irtree) + { + view_ui_rule->ui(expr_eval, rect); + } scratch_end(scratch); } } From 59df09b39b5601fbc4080a4d0f40ce90a80dfd35 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 10 Apr 2025 16:53:36 -0700 Subject: [PATCH 340/755] re-enable auto view rules in mule --- src/eval/eval_ir.c | 3 ++- src/mule/mule_main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 3f5836e4..4f94a918 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -924,7 +924,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(e_type_key_zero(), check_type_key)) + if(l.root == &e_irnode_nil || + e_type_key_match(e_type_key_zero(), check_type_key)) { break; } diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 7b8b03dc..b3da6013 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -106,7 +106,7 @@ void optimized_struct_parameters_eval_tests(void); #include #include -// raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); +raddbg_auto_view_rule(std::vector, slice($._Mypair._Myval2)); struct Basics{ char a; @@ -150,7 +150,7 @@ struct Dynamic_Array{ Pair *pairs; int count; }; -// raddbg_auto_view_rule(Dynamic_Array, slice); +raddbg_auto_view_rule(Dynamic_Array, slice($)); struct Struct_With_Embedded_Arrays{ int x; From b60329c817065d8352adc8cacd446b459c2ceb79 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 11:25:16 -0700 Subject: [PATCH 341/755] eliminate view rule column; eliminate 'parent irtree' experiment, need to do something else --- src/eval/eval_ir.c | 30 ++---------------------------- src/eval/eval_ir.h | 16 ---------------- src/raddbg/raddbg_core.c | 10 ++-------- src/raddbg/raddbg_views.c | 12 +++++------- 4 files changed, 9 insertions(+), 59 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4f94a918..ebf8f28c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -90,8 +90,6 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); e_ir_state->string_id_map->hash_slots_count = 1024; e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); - e_ir_state->top_parent = 0; - e_ir_state->free_parent = 0; String8 builtin_view_rule_names[] = { str8_lit_comp("bswap"), @@ -819,32 +817,6 @@ e_expr_unpoison(E_Expr *expr) } } -//- rjf: irtree parent selection - -internal void -e_push_irtree_parent(E_IRTreeAndType parent) -{ - E_IRParentNode *parent_n = e_ir_state->free_parent; - if(parent_n != 0) - { - SLLStackPop(e_ir_state->free_parent); - } - else - { - parent_n = push_array(e_ir_state->arena, E_IRParentNode, 1); - } - parent_n->v = parent; - SLLStackPush(e_ir_state->top_parent, parent_n); -} - -internal void -e_pop_irtree_parent(void) -{ - E_IRParentNode *popped = e_ir_state->top_parent; - SLLStackPop(e_ir_state->top_parent); - SLLStackPush(e_ir_state->free_parent, popped); -} - //- rjf: default type access hook E_TYPE_ACCESS_FUNCTION_DEF(default) @@ -2067,6 +2039,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: try to map name as parent expression signifier ('$') +#if 0 if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->top_parent != 0) { E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->top_parent->v.root); @@ -2075,6 +2048,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) mapped_bytecode_mode = e_ir_state->top_parent->v.mode; mapped_type_key = e_ir_state->top_parent->v.type_key; } +#endif //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 4f6fefb4..134f26dc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -140,13 +140,6 @@ struct E_IRCtx //////////////////////////////// //~ rjf: IR State -typedef struct E_IRParentNode E_IRParentNode; -struct E_IRParentNode -{ - E_IRParentNode *next; - E_IRTreeAndType v; -}; - typedef struct E_IRState E_IRState; struct E_IRState { @@ -159,10 +152,6 @@ struct E_IRState // rjf: unpacked ctx RDI_Procedure *thread_ip_procedure; - // rjf: parent stack - E_IRParentNode *top_parent; - E_IRParentNode *free_parent; - // rjf: caches E_UsedExprMap *used_expr_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; @@ -239,11 +228,6 @@ internal B32 e_expr_is_poisoned(E_Expr *expr); internal void e_expr_poison(E_Expr *expr); internal void e_expr_unpoison(E_Expr *expr); -//- rjf: irtree parent selection -internal void e_push_irtree_parent(E_IRTreeAndType parent); -internal void e_pop_irtree_parent(void); -#define E_IRTreeParentScope(p) DeferLoop(e_push_irtree_parent(p), e_pop_irtree_parent()) - //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 14d4d1b2..9ba31be5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4056,10 +4056,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - E_IRTreeParentScope(cell_info.eval.irtree) - { - cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); - } + cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4478,10 +4475,7 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_IRTreeParentScope(expr_eval.irtree) - { - view_ui_rule->ui(expr_eval, rect); - } + view_ui_rule->ui(expr_eval, rect); scratch_end(scratch); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 95766c6e..b16227e4 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1281,9 +1281,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1323,10 +1322,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.25f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } } From 9622bc880802a870a1f69e30938d440f18ab59fa Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 11:26:01 -0700 Subject: [PATCH 342/755] fix calls to parent tree experiment --- src/eval/eval_ir.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ebf8f28c..c3e9efcc 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1078,7 +1078,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Task start_task = {0, root_expr}; Task *first_task = &start_task; Task *last_task = first_task; - U64 num_parents = 0; for(Task *t = first_task; t != 0; t = t->next) { E_Expr *expr = t->expr; @@ -2396,8 +2395,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; - e_push_irtree_parent(result); - num_parents += 1; break; } } @@ -2413,14 +2410,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_expr_unpoison(t->expr); } - ////////////////////////////// - //- rjf: pop all the parents that we used - // - for EachIndex(idx, num_parents) - { - e_pop_irtree_parent(); - } - ////////////////////////////// //- rjf: apply inherited lenses to the resultant type // From abd33f7160b3bd0342eeb144c44d6edf00dd66ea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 11:58:43 -0700 Subject: [PATCH 343/755] new (and successful :) ) story for 'parent/overridden irtrees'. basically, if we have a rule which maps some eval X's type from A -> B, we preserve the original ir-tree compilation of A in the 'history' when we inevitably produce the ir-tree compilation of B. this can be used for accesses on overridden evaluations, and it allows us to implement $ in auto view rules. --- src/eval/eval_core.h | 1 + src/eval/eval_ir.c | 102 +++++++++++++++++++++++++-------------- src/eval/eval_ir.h | 3 ++ src/mule/mule_main.cpp | 2 +- src/raddbg/raddbg_core.c | 6 +++ 5 files changed, 78 insertions(+), 36 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index a3b7f9de..5aea7d7e 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -271,6 +271,7 @@ struct E_IRTreeAndType void *user_data; E_Mode mode; E_MsgList msgs; + E_IRTreeAndType *prev; }; //////////////////////////////// diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index c3e9efcc..7ce01ff4 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -896,12 +896,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } // rjf: bad conditions? -> error if applicable, exit - if(l.root == &e_irnode_nil || - e_type_key_match(e_type_key_zero(), check_type_key)) - { - break; - } - else if(exprr->kind != E_ExprKind_LeafIdentifier) + if(exprr->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); break; @@ -911,6 +906,11 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); break; } + else if(l.root == &e_irnode_nil || + e_type_key_match(e_type_key_zero(), check_type_key)) + { + break; + } else if(check_type_kind != E_TypeKind_Struct && check_type_kind != E_TypeKind_Class && check_type_kind != E_TypeKind_Union && @@ -1074,8 +1074,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { Task *next; E_Expr *expr; + E_IRTreeAndType *prev; }; - Task start_task = {0, root_expr}; + E_IRTreeAndType *start_prev = e_ir_state->overridden_irtree; + Task start_task = {0, root_expr, e_ir_state->overridden_irtree}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -1085,11 +1087,18 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: poison the expression we are about to use, so we don't recursively use it e_expr_poison(expr); + //- rjf: select the task's previous ir-tree-and-type as the overridden tree + if(t->prev != 0) + { + e_ir_state->overridden_irtree = t->prev; + } + //- rjf: do expr -> irtree generation for this expression if(expr->kind == E_ExprKind_Ref) { expr = expr->ref; } + B32 allow_autohooks = 1; E_ExprKind kind = expr->kind; switch(kind) { @@ -1103,32 +1112,42 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - // rjf: gather inherited lenses from the left-hand-side + // rjf: try all IR trees in chain + for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev) { - E_TypeKey k = lhs_irtree.type_key; - E_TypeKind kind = e_type_kind_from_key(k); - for(;kind == E_TypeKind_Lens;) + // rjf: gather inherited lenses from the left-hand-side { - E_Type *lens_type = e_type_from_key__cached(k); - if(lens_type->flags & E_TypeFlag_InheritedOnAccess) + E_TypeKey k = lhs_irtree_try->type_key; + E_TypeKind kind = e_type_kind_from_key(k); + for(;kind == E_TypeKind_Lens;) { - e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); + E_Type *lens_type = e_type_from_key__cached(k); + if(lens_type->flags & E_TypeFlag_InheritedOnAccess) + { + e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); + } + k = e_type_direct_from_key(k); + kind = e_type_kind_from_key(k); } - k = e_type_direct_from_key(k); - kind = e_type_kind_from_key(k); + } + + // rjf: pick access hook based on type + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree_try->type_key); + E_TypeAccessFunctionType *lhs_access = lhs_type->access; + if(lhs_access == 0) + { + lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); + } + + // rjf: call into hook to do access + result = lhs_access(arena, expr, lhs_irtree_try); + + // rjf: end chain if we found a result + if(result.root != &e_irnode_nil) + { + break; } } - - // rjf: pick access hook based on type - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); - E_TypeAccessFunctionType *lhs_access = lhs_type->access; - if(lhs_access == 0) - { - lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); - } - - // rjf: call into hook to do access - result = lhs_access(arena, expr, &lhs_irtree); }break; //- rjf: dereference @@ -2037,17 +2056,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - //- rjf: try to map name as parent expression signifier ('$') -#if 0 - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->top_parent != 0) + //- rjf: try to map name as overridden expression signifier ('$') + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->overridden_irtree != 0) { - E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->top_parent->v.root); + E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->overridden_irtree->root); string_mapped = 1; mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = e_ir_state->top_parent->v.mode; - mapped_type_key = e_ir_state->top_parent->v.type_key; + mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; + mapped_type_key = e_ir_state->overridden_irtree->type_key; + allow_autohooks = 0; } -#endif //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) @@ -2368,7 +2386,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; } - //- rjf: if the evaluated type has a hook for an extra layer of ir generation, + //- rjf: if the evaluated type has a hook for an extra layer of ir extension, // call into it E_Type *type = e_type_from_key__cached(result.type_key); if(type->kind != E_TypeKind_LensSpec && type->irext != 0) @@ -2382,7 +2400,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) result.user_data = ext.user_data; } + //- rjf: equip previous task's irtree + if(t->prev != 0) + { + result.prev = t->prev; + } + //- rjf: find any auto hooks according to this generation's type + if(allow_autohooks) { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -2395,6 +2420,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; + task->prev = push_array(arena, E_IRTreeAndType, 1); + task->prev[0] = result; break; } } @@ -2402,6 +2429,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } + ////////////////////////////// + //- rjf: reset the overridden irtree to whatever it was before this task list + // + e_ir_state->overridden_irtree = start_prev; + ////////////////////////////// //- rjf: unpoison the tags we used // diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 134f26dc..ea560063 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -152,6 +152,9 @@ struct E_IRState // rjf: unpacked ctx RDI_Procedure *thread_ip_procedure; + // rjf: overridden irtree + E_IRTreeAndType *overridden_irtree; + // rjf: caches E_UsedExprMap *used_expr_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index b3da6013..fde022df 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1624,7 +1624,7 @@ struct Bitmap int width; int height; }; -// raddbg_auto_view_rule(Bitmap, bitmap(base, width, height)); +raddbg_auto_view_rule(Bitmap, lens:bitmap($.base, $.width, $.height)); static unsigned int mule_bswap_u32(unsigned int x) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9ba31be5..347d2168 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4056,7 +4056,10 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = cell_info.eval.irtree.prev; cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); + e_ir_state->overridden_irtree = prev_overridden_irtree; // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4475,7 +4478,10 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = expr_eval.irtree.prev; view_ui_rule->ui(expr_eval, rect); + e_ir_state->overridden_irtree = prev_overridden_irtree; scratch_end(scratch); } } From 83a31a52291e7e8690f7b027bd1ab7b2fa294861 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 13:21:25 -0700 Subject: [PATCH 344/755] take out view rules from pins, since that is just in the expr itself now --- src/mule/mule_main.cpp | 61 +++++++++++++++++++------------------ src/raddbg/raddbg_main.c | 10 +++--- src/raddbg/raddbg_widgets.c | 7 ----- 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index fde022df..86632973 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -337,7 +337,7 @@ type_coverage_eval_tests(void) raddbg_pin(basics); raddbg_pin(fixed); raddbg_pin(pointer); - raddbg_pin(dynamic, slice); + raddbg_pin(dynamic); Struct_With_Embedded_Arrays swea = {0}; { @@ -1668,9 +1668,9 @@ fancy_viz_eval_tests(void) " return 0;\n" "}\n\n"); int x1 = 0; - raddbg_pin(long_string, text); - raddbg_pin(code_string, text(lang=c)); - raddbg_pin(fancy_viz_eval_tests, disasm); + raddbg_pin(text(long_string)); + raddbg_pin(text(code_string, lang=c)); + raddbg_pin(disasm(fancy_viz_eval_tests)); //- rjf: bitmaps unsigned int background_color = 0x00000000; @@ -1681,7 +1681,7 @@ fancy_viz_eval_tests(void) unsigned int cl = mule_bswap_u32(main_color); unsigned int sn = mule_bswap_u32(shine_color); unsigned int sh = mule_bswap_u32(shadow_color); - unsigned int bitmap[] = + unsigned int pixels[] = { bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, @@ -1702,38 +1702,38 @@ fancy_viz_eval_tests(void) bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, }; - raddbg_pin(bitmap, bitmap(18, 18)); - for(int i = 0; i < sizeof(bitmap)/sizeof(bitmap[0]); i += 1) + raddbg_pin(bitmap(pixels, 18, 18)); + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) { - unsigned int r = bitmap[i]&0x000000ff; - unsigned int a = bitmap[i]&0xff000000; - bitmap[i] = bitmap[i]>>8; - bitmap[i] &= ~0xffff0000; - bitmap[i] |= (r<<16); - bitmap[i] |= (a); + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); } - for(int i = 0; i < sizeof(bitmap)/sizeof(bitmap[0]); i += 1) + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) { - unsigned int r = bitmap[i]&0x000000ff; - unsigned int a = bitmap[i]&0xff000000; - bitmap[i] = bitmap[i]>>8; - bitmap[i] &= ~0xffff0000; - bitmap[i] |= (r<<16); - bitmap[i] |= (a); + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); } - for(int i = 0; i < sizeof(bitmap)/sizeof(bitmap[0]); i += 1) + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) { - unsigned int r = bitmap[i]&0x000000ff; - unsigned int a = bitmap[i]&0xff000000; - bitmap[i] = bitmap[i]>>8; - bitmap[i] &= ~0xffff0000; - bitmap[i] |= (r<<16); - bitmap[i] |= (a); + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); } int x2 = 0; //- rjf: auto-view-rule'd bitmaps - Bitmap foo = {(unsigned char *)&bitmap[0], 18, 18}; + Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; raddbg_pin(foo); //- rjf: 3D geometry @@ -1923,7 +1923,10 @@ fancy_viz_eval_tests(void) 136, 137, 138, 138, 139, 136, 140, 141, 142, 142, 143, 140, 144, 145, 146, 146, 147, 144, 148, 149, 150, 150, 151, 148, 152, 153, 154, 154, 155, 152, 156, 157, 158, 158, 159, 156, 160, 161, 162, 162, 163, 160, 164, 165, 166, 166, 167, 164, }; - raddbg_pin(index_data, "geo3d(count = (sizeof index_data/4), vtx = (vertex_data), vtx_size = (sizeof vertex_data))"); + int count = (sizeof index_data/4); + float *vtx = vertex_data; + int vtx_size = sizeof vertex_data; + raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size)); int x3 = 0; } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 6c271264..5e4fa97e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -73,11 +73,11 @@ // `raddbg_thread_color_hex(0xff0000ff)`: Sets the calling thread's color. // - Also can be done with individual `[0, 1]` color components: // `raddbg_thread_color_rgba(1.f, 0.f, 0.f, 1.f)` -// - `raddbg_pin(, )`, e.g. -// `raddbg_pin(dynamic_array, slice)`: Like watch pins, but defined in source -// code. This is used by the debugger UI, but does not show up anywhere -// other than the source code, so it can either be used as a macro (which -// expands to nothing), or in comments too. +// - `raddbg_pin()`, e.g. +// `raddbg_pin(slice(dynamic_array))`: Like watch pins, but defined in +// source code. This is used by the debugger UI, but does not show up +// anywhere other than the source code, so it can either be used as a macro +// (which expands to nothing), or in comments too. // - `raddbg_entry_point(name)`, e.g. `raddbg_entry_point(entry_point)`: // declares the entry point for an executable, which the debugger will use // when stepping into a program, rather than the defaults (e.g. `main`). diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 13867ed7..faa44ddb 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1933,15 +1933,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: extract fixed arguments String8 expr_string = {0}; - String8 view_rule_string = {0}; if(args.first != 0) { expr_string = args.first->string; } - if(args.first->next != 0) - { - view_rule_string = args.first->next->string; - } // rjf: build immediate pin for this markup if(expr_string.size != 0) @@ -1949,9 +1944,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("markup_pin_%I64x_%I64x", line_num, off); RD_Cfg *pin = rd_cfg_child_from_string_or_alloc(immediate_root, str8_lit("watch_pin")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(pin, str8_lit("expression")); - RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(pin, str8_lit("view_rule")); rd_cfg_new_replace(expr, expr_string); - rd_cfg_new_replace(view_rule, view_rule_string); rd_cfg_list_push(scratch.arena, &immediate_pins, pin); } } From 3e49e92e981955b2e64c3a970cfa3c5d6ea4cfba Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 14:16:48 -0700 Subject: [PATCH 345/755] only and omit; notes & dead code deletion --- project.4coder | 4 +- src/eval/eval_core.h | 18 +- src/eval/eval_ir.c | 180 +----------------- src/eval/eval_types.c | 109 +++++++++++ src/eval/eval_types.h | 6 + .../eval_visualization_core.c | 10 +- src/raddbg/raddbg_core.c | 48 +++-- src/raddbg/raddbg_main.c | 25 +-- src/scratch/textperf.c | 4 +- 9 files changed, 182 insertions(+), 222 deletions(-) diff --git a/project.4coder b/project.4coder index 1b92e539..a725e0d6 100644 --- a/project.4coder +++ b/project.4coder @@ -48,8 +48,8 @@ commands = //- rjf: [raddbg] .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - //- rjf: [eval_scratch] - // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta eval_scratch && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: [textperf] + // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [tester] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 5aea7d7e..12aafc78 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -297,14 +297,16 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_IsNotText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), - E_TypeFlag_InheritedOnAccess = (1<<7), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_IsNotText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_InheritedByMembers = (1<<7), + E_TypeFlag_InheritedByElements = (1<<8), + E_TypeFlag_ArrayLikeExpansion = (1<<9), }; typedef struct E_Member E_Member; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 7ce01ff4..ca8d438a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -103,181 +103,6 @@ e_select_ir_ctx(E_IRCtx *ctx) } } -//////////////////////////////// -//~ rjf: Member Filtering Lookup Rules - -#if 0 // TODO(rjf): @eval -typedef struct E_MemberFilterAccel E_MemberFilterAccel; -struct E_MemberFilterAccel -{ - E_MemberArray members; -}; - -E_LOOKUP_INFO_FUNCTION_DEF(only) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupInfo lookup_info = {0}; - { - //- rjf: extract struct type - E_TypeKey struct_type_key = zero_struct; - { - E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) - { - E_Type *type = e_type_from_key__cached(lhs_type_key); - if(type->count == 1) - { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - struct_type_key = direct_type_key; - } - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Union) - { - struct_type_key = lhs_type_key; - } - } - - //- rjf: not struct -> fall back on default - if(e_type_key_match(struct_type_key, e_type_key_zero())) - { - lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); - } - - //- struct -> filter - else - { - E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList data_members_list__filtered = {0}; - for EachIndex(idx, data_members.count) - { - B32 fits_filter = 0; - for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) - { - if(str8_match(name->string, data_members.v[idx].name, 0)) - { - fits_filter = 1; - break; - } - } - if(fits_filter) - { - e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); - } - } - E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); - accel->members = e_member_array_from_list(arena, &data_members_list__filtered); - lookup_info.user_data = accel; - lookup_info.named_expr_count = accel->members.count; - } - } - scratch_end(scratch); - return lookup_info; -} - -E_LOOKUP_INFO_FUNCTION_DEF(omit) -{ - Temp scratch = scratch_begin(&arena, 1); - E_LookupInfo lookup_info = {0}; - { - //- rjf: extract struct type - E_TypeKey struct_type_key = zero_struct; - { - E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key); - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) - { - E_Type *type = e_type_from_key__cached(lhs_type_key); - if(type->count == 1) - { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - struct_type_key = direct_type_key; - } - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Union) - { - struct_type_key = lhs_type_key; - } - } - - //- rjf: not struct -> fall back on default - if(e_type_key_match(struct_type_key, e_type_key_zero())) - { - lookup_info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter); - } - - //- struct -> filter - else - { - E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList data_members_list__filtered = {0}; - for EachIndex(idx, data_members.count) - { - B32 fits_filter = 1; - for(E_Expr *name = tag->first->next; name != &e_expr_nil; name = name->next) - { - if(str8_match(name->string, data_members.v[idx].name, 0)) - { - fits_filter = 0; - break; - } - } - if(fits_filter) - { - e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); - } - } - E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); - accel->members = e_member_array_from_list(arena, &data_members_list__filtered); - lookup_info.user_data = accel; - lookup_info.named_expr_count = accel->members.count; - } - } - scratch_end(scratch); - return lookup_info; -} - -E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) -{ - if(user_data == 0) - { - E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data); - } - else - { - Temp scratch = scratch_begin(&arena, 1); - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); - E_MemberFilterAccel *accel = (E_MemberFilterAccel *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->members.count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 member_idx = idx + read_range.min; - String8 member_name = accel->members.v[member_idx].name; - exprs[idx] = e_expr_irext_member_access(arena, lhs, &lhs_irtree, member_name); - } - scratch_end(scratch); - } -} -#endif - //////////////////////////////// //~ rjf: Auto Hooks @@ -1122,7 +947,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) for(;kind == E_TypeKind_Lens;) { E_Type *lens_type = e_type_from_key__cached(k); - if(lens_type->flags & E_TypeFlag_InheritedOnAccess) + if((lens_type->flags & E_TypeFlag_InheritedByMembers && expr->kind == E_ExprKind_MemberAccess) || + (lens_type->flags & E_TypeFlag_InheritedByElements && expr->kind == E_ExprKind_ArrayIndex)) { e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); } @@ -2407,7 +2233,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: find any auto hooks according to this generation's type - if(allow_autohooks) + if(allow_autohooks && result.mode != E_Mode_Null) { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 57a3c53e..6ca89074 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2495,6 +2495,115 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice) } } + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `only`, `omit` lenses + +typedef struct E_MemberFilterAccel E_MemberFilterAccel; +struct E_MemberFilterAccel +{ + E_MemberArray members; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(only_and_omit) +{ + Temp scratch = scratch_begin(&arena, 1); + E_TypeExpandInfo info = {0}; + { + //- rjf: extract struct type + E_TypeKey struct_type_key = zero_struct; + { + E_TypeKey lhs_type_key = e_type_unwrap(irtree->type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + E_Type *type = e_type_from_key__cached(lhs_type_key); + if(type->count == 1) + { + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(irtree->type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union) + { + struct_type_key = direct_type_key; + } + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union) + { + struct_type_key = lhs_type_key; + } + } + + //- rjf: not struct -> fall back on default + if(e_type_key_match(struct_type_key, e_type_key_zero())) + { + info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(default)(arena, expr, irtree, filter); + } + + //- struct -> filter + else + { + E_Type *type = e_type_from_key__cached(irtree->type_key); + E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); + E_MemberList data_members_list__filtered = {0}; + if(type->args != 0) + { + B32 default_fits_filter = (str8_match(type->name, str8_lit("only"), 0) ? 0 : 1); + for EachIndex(idx, data_members.count) + { + B32 fits_filter = default_fits_filter; + for EachIndex(arg_idx, type->count) + { + E_Expr *arg = type->args[arg_idx]; + if(str8_match(arg->string, data_members.v[idx].name, 0)) + { + fits_filter = !default_fits_filter; + break; + } + } + if(fits_filter) + { + e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); + } + } + } + E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); + accel->members = e_member_array_from_list(arena, &data_members_list__filtered); + info.user_data = accel; + info.expr_count = accel->members.count; + } + } + scratch_end(scratch); + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only_and_omit) +{ + if(user_data == 0) + { + E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default)(arena, user_data, expr, irtree, filter, idx_range, exprs_out, exprs_strings_out); + } + else + { + Temp scratch = scratch_begin(&arena, 1); + E_MemberFilterAccel *accel = (E_MemberFilterAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->members.count); + Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 member_idx = idx + read_range.min; + String8 member_name = accel->members.v[member_idx].name; + exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); + } + scratch_end(scratch); + } +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `folder` type diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 5103fa3c..171634d1 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -298,6 +298,12 @@ E_TYPE_IREXT_FUNCTION_DEF(slice); E_TYPE_ACCESS_FUNCTION_DEF(slice); E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `only`, `omit` lenses + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(only_and_omit); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only_and_omit); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `folder` type diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index bf8aee74..5277f70a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1548,8 +1548,12 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { if(it->top_task->redirect_to_sets_and_structs) { - expansion_opener_symbol = str8_lit("["); - expansion_closer_symbol = str8_lit("]"); + E_Type *type = e_type_from_key__cached(type_key); + if(type->flags & E_TypeFlag_ArrayLikeExpansion) + { + expansion_opener_symbol = str8_lit("["); + expansion_closer_symbol = str8_lit("]"); + } goto arrays_and_sets_and_structs; } E_Type *type = e_type_from_key__cached(type_key); @@ -1677,7 +1681,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) ptr_data->value_eval = e_value_eval_from_eval(eval); ptr_data->type = e_type_from_key__cached(type_key); ptr_data->direct_type = e_type_from_key__cached(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key)))); - ptr_data->ptee_has_content = (ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); + ptr_data->ptee_has_content = (ptr_data->value_eval.value.u64 != 0 && ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || ptr_data->direct_type->kind == E_TypeKind_S8 || ptr_data->direct_type->kind == E_TypeKind_U8); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 347d2168..61dc4f3a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12241,7 +12241,9 @@ rd_frame(void) struct { String8 name; - B32 inherited; + B32 inherited_by_members; + B32 inherited_by_elements; + B32 array_like; E_TypeIRExtFunctionType *irext; E_TypeAccessFunctionType *access; E_TypeExpandRule expand; @@ -12250,21 +12252,23 @@ rd_frame(void) } lens_table[] = { - {str8_lit("bin"), 1, 0, 0, {0}}, - {str8_lit("oct"), 1, 0, 0, {0}}, - {str8_lit("dec"), 1, 0, 0, {0}}, - {str8_lit("hex"), 1, 0, 0, {0}}, - {str8_lit("digits"), 1, 0, 0, {0}}, - {str8_lit("no_string"), 1, 0, 0, {0}}, - {str8_lit("no_addr"), 1, 0, 0, {0}}, - {str8_lit("slice"), 0, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, - {str8_lit("text"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, - {str8_lit("disasm"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, - {str8_lit("memory"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, - {str8_lit("bitmap"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + {str8_lit("bin"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("oct"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("dec"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("hex"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("digits"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, + {str8_lit("only"), 0, 1, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only_and_omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only_and_omit)}}, + {str8_lit("omit"), 0, 1, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only_and_omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only_and_omit)}}, + {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; //- rjf: fill lenses in ev expand rule map, rd view ui rule map @@ -12289,9 +12293,17 @@ rd_frame(void) for EachElement(idx, lens_table) { E_TypeFlags type_flags = 0; - if(lens_table[idx].inherited) + if(lens_table[idx].inherited_by_members) { - type_flags |= E_TypeFlag_InheritedOnAccess; + type_flags |= E_TypeFlag_InheritedByMembers; + } + if(lens_table[idx].inherited_by_elements) + { + type_flags |= E_TypeFlag_InheritedByElements; + } + if(lens_table[idx].array_like) + { + type_flags |= E_TypeFlag_ArrayLikeExpansion; } E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 5e4fa97e..547da72b 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -92,15 +92,6 @@ //////////////////////////////// //~ rjf: feature cleanup, code dedup, code elimination pass: // -// [ ] 'view rules' need to be rephrased as "function" calls in the expression language -// [ ] need a formalization which takes unknown identifiers which are called, and tries -// to use that to apply a IR-generation rule, which is keyed by that unknown -// identifier -// [ ] we need to select expressions as "parents" when possible, so that when using an -// auto-view-rule (or similar context), leaf identifiers referring to e.g. members -// of an expression's type resolve correctly (e.g. bitmap(base, width, height) being -// used as a shorthand for bitmap(foo.base, foo.width, foo.height) when evaluating -// foo). // [ ] *ALL* expressions in watch windows need to be editable. // // [ ] config hot-reloading, using cfg wins @@ -111,7 +102,6 @@ // right-clicking a tab should be equivalent to spawning a command lister, // but only with commands that are directly // -// [ ] r8 bitmap view rule seems incorrect? // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // // [ ] stepping-onto a line with a conditional breakpoint, which fails, causes a @@ -121,6 +111,7 @@ // // [ ] if a breakpoint matches the entry point's starting address, its hit count // is not correctly incremented. +// [ ] odin's demo is busted - need to revert PDB conversion type index changes. //////////////////////////////// //~ rjf: post-0.9.12 TODO notes @@ -133,8 +124,6 @@ // [ ] fix light themes // [ ] make `array` view rule work with actual array types, to change their // size dynamically -// [ ] single-line visualization busted with auto-view-rules applied, it seems... -// not showing member variables, just commas, check w/ mohit // [ ] disasm starting address - need to use debug info for more correct // results... // [ ] linked list view rule @@ -382,6 +371,18 @@ // menu, but you can't actually see it because the tooltip for the thread // draws on top of it, so you can't see the menu. // [x] double-click vs. single-click for folder navigation, see if we can infer +// [x] 'view rules' need to be rephrased as "function" calls in the expression language +// [x] need a formalization which takes unknown identifiers which are called, and tries +// to use that to apply a IR-generation rule, which is keyed by that unknown +// identifier +// [x] we need to select expressions as "parents" when possible, so that when using an +// auto-view-rule (or similar context), leaf identifiers referring to e.g. members +// of an expression's type resolve correctly (e.g. bitmap(base, width, height) being +// used as a shorthand for bitmap(foo.base, foo.width, foo.height) when evaluating +// foo). +// [x] single-line visualization busted with auto-view-rules applied, it seems... +// not showing member variables, just commas, check w/ mohit +// [x] r8 bitmap view rule seems incorrect? //////////////////////////////// //~ rjf: Build Options diff --git a/src/scratch/textperf.c b/src/scratch/textperf.c index c9e3792e..b252b9e1 100644 --- a/src/scratch/textperf.c +++ b/src/scratch/textperf.c @@ -51,7 +51,7 @@ frame(void) } } r_begin_frame(); - dr_begin_frame(); + dr_begin_frame(fnt_tag_zero()); r_window_begin_frame(os_window, r_window); DR_Bucket *bucket = dr_bucket_make(); DR_BucketScope(bucket) ProfScope("draw") @@ -77,7 +77,7 @@ frame(void) internal void entry_point(CmdLine *cmdline) { - os_window = os_window_open(v2f32(1600, 900), 0, str8_lit("textperf")); + os_window = os_window_open(r2f32p(0, 0, 1600, 900), OS_WindowFlag_UseDefaultPosition, str8_lit("textperf")); r_window = r_window_equip(os_window); os_window_first_paint(os_window); for(;!update();); From 2e8bca21f613a4cd5db5b42e9f4e7606bedf991f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 14:41:15 -0700 Subject: [PATCH 346/755] strip out only/omit - i think they are insufficient for long-term filtering stuff... --- src/eval/eval_ir.c | 38 ++++++++++---- src/eval/eval_types.c | 109 --------------------------------------- src/raddbg/raddbg_core.c | 3 +- 3 files changed, 29 insertions(+), 121 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ca8d438a..98af225d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1592,6 +1592,13 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_expr_push_child(call, e_expr_ref(arena, arg)); } result = e_irtree_and_type_from_expr(arena, call); + + // rjf: is "raw"? -> strip all lens types from result; disallow auto-hooks + if(str8_match(callee->string, str8_lit("raw"), 0)) + { + result.type_key = e_type_unwrap(result.type_key); + allow_autohooks = 0; + } } // rjf: calling a lens? -> generate IR for the first argument; wrap the type in @@ -1620,16 +1627,27 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - // rjf: patch resultant type with a lens w/ args, pointing to the original type - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, - .flags = lhs_type->flags, - .count = arg_count, - .args = args, - .direct_key = result.type_key, - .name = lhs_type->name, - .irext = lhs_type->irext, - .access = lhs_type->access, - .expand = lhs_type->expand); + // rjf: is "raw"? -> strip all lens types from result; disallow auto-hooks + if(str8_match(lhs_type->name, str8_lit("raw"), 0)) + { + result = e_irtree_and_type_from_expr(arena, lhs->next); + result.type_key = e_type_unwrap(result.type_key); + allow_autohooks = 0; + } + + // rjf: is non-raw -> patch resultant type with a lens w/ args, pointing to the original type + else + { + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lhs_type->flags, + .count = arg_count, + .args = args, + .direct_key = result.type_key, + .name = lhs_type->name, + .irext = lhs_type->irext, + .access = lhs_type->access, + .expand = lhs_type->expand); + } scratch_end(scratch); } diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6ca89074..57a3c53e 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2495,115 +2495,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice) } } - -//////////////////////////////// -//~ rjf: (Built-In Type Hooks) `only`, `omit` lenses - -typedef struct E_MemberFilterAccel E_MemberFilterAccel; -struct E_MemberFilterAccel -{ - E_MemberArray members; -}; - -E_TYPE_EXPAND_INFO_FUNCTION_DEF(only_and_omit) -{ - Temp scratch = scratch_begin(&arena, 1); - E_TypeExpandInfo info = {0}; - { - //- rjf: extract struct type - E_TypeKey struct_type_key = zero_struct; - { - E_TypeKey lhs_type_key = e_type_unwrap(irtree->type_key); - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) - { - E_Type *type = e_type_from_key__cached(lhs_type_key); - if(type->count == 1) - { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(irtree->type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - struct_type_key = direct_type_key; - } - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Class || - lhs_type_kind == E_TypeKind_Union) - { - struct_type_key = lhs_type_key; - } - } - - //- rjf: not struct -> fall back on default - if(e_type_key_match(struct_type_key, e_type_key_zero())) - { - info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(default)(arena, expr, irtree, filter); - } - - //- struct -> filter - else - { - E_Type *type = e_type_from_key__cached(irtree->type_key); - E_MemberArray data_members = e_type_data_members_from_key__cached(struct_type_key); - E_MemberList data_members_list__filtered = {0}; - if(type->args != 0) - { - B32 default_fits_filter = (str8_match(type->name, str8_lit("only"), 0) ? 0 : 1); - for EachIndex(idx, data_members.count) - { - B32 fits_filter = default_fits_filter; - for EachIndex(arg_idx, type->count) - { - E_Expr *arg = type->args[arg_idx]; - if(str8_match(arg->string, data_members.v[idx].name, 0)) - { - fits_filter = !default_fits_filter; - break; - } - } - if(fits_filter) - { - e_member_list_push(scratch.arena, &data_members_list__filtered, &data_members.v[idx]); - } - } - } - E_MemberFilterAccel *accel = push_array(arena, E_MemberFilterAccel, 1); - accel->members = e_member_array_from_list(arena, &data_members_list__filtered); - info.user_data = accel; - info.expr_count = accel->members.count; - } - } - scratch_end(scratch); - return info; -} - -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only_and_omit) -{ - if(user_data == 0) - { - E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default)(arena, user_data, expr, irtree, filter, idx_range, exprs_out, exprs_strings_out); - } - else - { - Temp scratch = scratch_begin(&arena, 1); - E_MemberFilterAccel *accel = (E_MemberFilterAccel *)user_data; - Rng1U64 legal_idx_range = r1u64(0, accel->members.count); - Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 member_idx = idx + read_range.min; - String8 member_name = accel->members.v[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); - } - scratch_end(scratch); - } -} - //////////////////////////////// //~ rjf: (Built-In Type Hooks) `folder` type diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 61dc4f3a..ca78fedd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12252,6 +12252,7 @@ rd_frame(void) } lens_table[] = { + {str8_lit("raw"), 0, 0, 0, 0, 0, {0}}, {str8_lit("bin"), 1, 1, 0, 0, 0, {0}}, {str8_lit("oct"), 1, 1, 0, 0, 0, {0}}, {str8_lit("dec"), 1, 1, 0, 0, 0, {0}}, @@ -12260,8 +12261,6 @@ rd_frame(void) {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, - {str8_lit("only"), 0, 1, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only_and_omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only_and_omit)}}, - {str8_lit("omit"), 0, 1, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only_and_omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only_and_omit)}}, {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, From e754380caa42a60ef3ef05f8fdbe07f3bb49ad96 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 15:02:54 -0700 Subject: [PATCH 347/755] eval identifier resolution: allow implicitly mapping leaf identifiers to member accesses of overridden irtree --- src/eval/eval_ir.c | 43 +++++++++++++++++++++++++++------------- src/mule/mule_main.cpp | 10 ++++++++++ src/raddbg/raddbg_core.c | 1 + 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 98af225d..df177443 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1727,6 +1727,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_TypeKey mapped_type_key = zero_struct; E_Module *mapped_location_block_module = &e_module_nil; RDI_LocationBlock *mapped_location_block = 0; + E_Mode mapped_bytecode_mode = E_Mode_Offset; + E_Space mapped_bytecode_space = zero_struct; + String8 mapped_bytecode = {0}; //- rjf: form namespaceified fallback versions of this lookup string String8List namespaceified_strings = {0}; @@ -1754,6 +1757,32 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } + //- rjf: try to map name as overridden expression signifier ('$') + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->overridden_irtree != 0) + { + E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->overridden_irtree->root); + string_mapped = 1; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; + mapped_type_key = e_ir_state->overridden_irtree->type_key; + allow_autohooks = 0; + } + + //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) + if(!string_mapped && e_ir_state->overridden_irtree != 0) + { + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, e_ir_state->overridden_irtree, string); + E_IRTreeAndType access_irtree = e_irtree_and_type_from_expr(scratch.arena, access); + if(access_irtree.root != &e_irnode_nil) + { + string_mapped = 1; + E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); + mapped_type_key = access_irtree.type_key; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = access_irtree.mode; + } + } + //- rjf: try to map name as member - if found, string__redirected := "this", and turn // on later implicit-member-lookup generation B32 string_is_implicit_member_name = 0; @@ -1806,9 +1835,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: mapped to location block -> extract or produce bytecode for this mapping - E_Mode mapped_bytecode_mode = E_Mode_Offset; - E_Space mapped_bytecode_space = zero_struct; - String8 mapped_bytecode = {0}; if(mapped_location_block != 0) { E_Module *module = mapped_location_block_module; @@ -1900,17 +1926,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - //- rjf: try to map name as overridden expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->overridden_irtree != 0) - { - E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->overridden_irtree->root); - string_mapped = 1; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; - mapped_type_key = e_ir_state->overridden_irtree->type_key; - allow_autohooks = 0; - } - //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) { diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 86632973..c501a9de 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1649,6 +1649,16 @@ fancy_viz_eval_tests(void) (void)error_code; #endif + //- rjf: booleans (checkboxes) + bool bool1 = 0; raddbg_pin(bool1); + bool bool2 = 1; raddbg_pin(bool2); + bool bool3 = 0; raddbg_pin(bool3); + + //- rjf: sliders + float slide1 = 500.f; raddbg_pin(range1(slide1, 0, 1000)); + double slide2 = 0.75; raddbg_pin(range1(slide2, 0, 1.0)); + int slide3 = 25; raddbg_pin(range1(slide3, 0, 100)); + //- rjf: colors float example_color_4f32[4] = {1.00f, 0.85f, 0.25f, 1.00f}; unsigned int example_color_u32 = 0xff6f30ff; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ca78fedd..bf9c0745 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12260,6 +12260,7 @@ rd_frame(void) {str8_lit("digits"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, From 72aa47972472e9d3d67a84dc19f654614cae7d8e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 15:04:32 -0700 Subject: [PATCH 348/755] eliminate unnecessary usage of $. in mule auto view rules --- src/mule/mule_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index c501a9de..430d352d 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -106,7 +106,7 @@ void optimized_struct_parameters_eval_tests(void); #include #include -raddbg_auto_view_rule(std::vector, slice($._Mypair._Myval2)); +raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); struct Basics{ char a; @@ -1624,7 +1624,7 @@ struct Bitmap int width; int height; }; -raddbg_auto_view_rule(Bitmap, lens:bitmap($.base, $.width, $.height)); +raddbg_auto_view_rule(Bitmap, lens:bitmap(base, width, height)); static unsigned int mule_bswap_u32(unsigned int x) From 64187e75eb67c2b12ccf0f503109976db3230e2e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 16:21:47 -0700 Subject: [PATCH 349/755] slider extension to built-in cell controls (similar to toggle-switch) --- src/eval/eval_core.h | 20 ++--- .../eval_visualization_core.c | 68 ++++++++------ src/raddbg/raddbg_core.c | 88 ++++++++++++++++++- src/raddbg/raddbg_widgets.c | 56 ++++++++++++ src/raddbg/raddbg_widgets.h | 3 +- 5 files changed, 192 insertions(+), 43 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 12aafc78..869f02c7 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -297,16 +297,16 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_IsNotText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), - E_TypeFlag_InheritedByMembers = (1<<7), - E_TypeFlag_InheritedByElements = (1<<8), - E_TypeFlag_ArrayLikeExpansion = (1<<9), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_IsNotText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_InheritedByMembers = (1<<7), + E_TypeFlag_InheritedByElements = (1<<8), + E_TypeFlag_ArrayLikeExpansion = (1<<9), }; typedef struct E_Member E_Member; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5277f70a..35e6a7f3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1597,42 +1597,52 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_task.eval = eval; new_task.redirect_to_sets_and_structs = 1; } - else switch(task_idx) + else { - default:{}break; - - // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type - case 0: + need_new_task = 1; + need_pop = 1; + new_task.params = lens_params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); +#if 0 // NOTE(rjf): will explicitly visualize lenses in value strings. does not seem useful for now? + switch(task_idx) { - Temp scratch = scratch_begin(&arena, 1); - String8List strings = {0}; + default:{}break; + + // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type + case 0: { - str8_list_pushf(scratch.arena, &strings, "%S(", type->name); - for EachIndex(idx, type->count) + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; { - String8 string = e_string_from_expr(scratch.arena, type->args[idx]); - str8_list_push(scratch.arena, &strings, string); - if(idx+1 < type->count) + str8_list_pushf(scratch.arena, &strings, "%S(", type->name); + for EachIndex(idx, type->count) { - str8_list_pushf(scratch.arena, &strings, ", "); + String8 string = e_string_from_expr(scratch.arena, type->args[idx]); + str8_list_push(scratch.arena, &strings, string); + if(idx+1 < type->count) + { + str8_list_pushf(scratch.arena, &strings, ", "); + } } + str8_list_pushf(scratch.arena, &strings, ") <- ("); } - str8_list_pushf(scratch.arena, &strings, ") <- ("); - } - *out_string = str8_list_join(arena, &strings, 0); - need_new_task = 1; - need_pop = 0; - new_task.params = *params; - new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); - scratch_end(scratch); - }break; - - // rjf: step 1 -> close - case 1: - { - *out_string = str8_lit(")"); - }break; + *out_string = str8_list_join(arena, &strings, 0); + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + scratch_end(scratch); + }break; + + // rjf: step 1 -> close + case 1: + { + *out_string = str8_lit(")"); + }break; + } +#endif } }break; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bf9c0745..b1a3d113 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3927,11 +3927,54 @@ rd_view_ui(Rng2F32 rect) RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + E_Type *cell_type = e_type_from_key__cached(cell_info.eval.irtree.type_key); + E_Eval cell_value_eval = e_value_eval_from_eval(cell_info.eval); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; - B32 cell_toggled = (e_value_eval_from_eval(cell_info.eval).value.u64 != 0); + B32 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; + //////////// + //- rjf: compute slider parameters + // + E_Value cell_slider_min = zero_struct; + E_Value cell_slider_max = zero_struct; + E_TypeKind slider_value_type_kind = E_TypeKind_Null; + F32 cell_slider_value = 0.f; + if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2) + { + E_Expr *min_expr = cell_type->args[0]; + E_Expr *max_expr = cell_type->args[1]; + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &cell_info.eval.irtree; + { + E_TypeKey slider_value_type = e_type_unwrap(cell_type->direct_type_key); + slider_value_type_kind = e_type_kind_from_key(slider_value_type); + E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); + E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); + cell_slider_min = e_value_from_expr(min_casted); + cell_slider_max = e_value_from_expr(max_casted); + } + e_ir_state->overridden_irtree = prev_overridden_irtree; + } + switch(slider_value_type_kind) + { + default: + if(e_type_kind_is_integer(slider_value_type_kind)) + { + cell_slider_value = ((F32)(cell_value_eval.value.s64 - cell_slider_min.s64)) / (cell_slider_max.s64 - cell_slider_min.s64); + }break; + case E_TypeKind_F32: + { + cell_slider_value = (cell_value_eval.value.f32 - cell_slider_min.f32) / (cell_slider_max.f32 - cell_slider_min.f32); + }break; + case E_TypeKind_F64: + { + cell_slider_value = (F32)((cell_value_eval.value.f64 - cell_slider_min.f64) / (cell_slider_max.f64 - cell_slider_min.f64)); + }break; + } + F32 next_cell_slider_value = cell_slider_value; + //////////// //- rjf: determine cell's palette // @@ -4097,9 +4140,12 @@ rd_view_ui(Rng2F32 rect) else { // rjf: compute visual params + B32 fancy_editors_in_expr = (row_info->cells.count == 1); + B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); - B32 is_toggle_switch = (cell_info.eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(cell_info.eval.irtree.type_key) == E_TypeKind_Bool); + B32 is_toggle_switch = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Bool); + B32 is_slider = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Lens && str8_match(cell_type->name, str8_lit("range1"), 0)); B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; @@ -4200,6 +4246,13 @@ rd_view_ui(Rng2F32 rect) cell_params.flags |= RD_CellFlag_ToggleSwitch; cell_params.toggled_out = &next_cell_toggled; } + + // rjf: apply slider + if(is_slider) + { + cell_params.flags |= RD_CellFlag_Slider; + cell_params.slider_value_out = &next_cell_slider_value; + } } // rjf: build @@ -4435,6 +4488,37 @@ rd_view_ui(Rng2F32 rect) rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); } + //////////// + //- rjf: commit slider changes + // + if(next_cell_slider_value != cell_slider_value) + { + String8 new_value_string = {0}; + switch(slider_value_type_kind) + { + default: + if(e_type_kind_is_integer(slider_value_type_kind)) + { + S64 new_value = (S64)((next_cell_slider_value * (cell_slider_max.s64 - cell_slider_min.s64)) + cell_slider_min.s64); + new_value = Clamp(cell_slider_min.s64, new_value, cell_slider_max.s64); + new_value_string = push_str8f(scratch.arena, "%I64d", new_value); + }break; + case E_TypeKind_F32: + { + F32 new_value = (next_cell_slider_value * (cell_slider_max.f32 - cell_slider_min.f32)) + cell_slider_min.f32; + new_value = Clamp(cell_slider_min.f32, new_value, cell_slider_max.f32); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + case E_TypeKind_F64: + { + F64 new_value = (F64)((next_cell_slider_value * (cell_slider_max.f64 - cell_slider_min.f64)) + cell_slider_min.f64); + new_value = Clamp(cell_slider_min.f64, new_value, cell_slider_max.f64); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + } + rd_commit_eval_value_string(cell_info.eval, new_value_string); + } + //////////// //- rjf: bump x pixel coordinate // diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index faa44ddb..ba89a4d7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3278,6 +3278,62 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build slider + // + if(params->flags & RD_CellFlag_Slider && !is_focus_active) + UI_Parent(box) + { + F32 padding_px = floor_f32(ui_top_font_size()*0.65f); + F32 height_px = ui_top_px_height() - padding_px*2.f; + UI_PrefWidth(ui_children_sum(1.f)) + UI_HeightFill + UI_Column UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_PrefWidth(ui_pct(0.5f, 0.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + { + ui_set_next_hover_cursor(OS_Cursor_LeftRight); + UI_Box *slider_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "slider"); + UI_Parent(slider_box) UI_TagF("good_pop") + { + UI_Signal sig = ui_signal_from_box(slider_box); + if(ui_dragging(sig)) + { + if(ui_pressed(sig)) + { + ui_store_drag_struct(params->slider_value_out); + } + F32 initial_pct = *ui_get_drag_struct(F32); + F32 current_pct = initial_pct + (ui_drag_delta().x / dim_2f32(slider_box->rect).x); + params->slider_value_out[0] = current_pct; + } + UI_Box *fill_box = &ui_nil_box; + UI_PrefWidth(ui_pct(Clamp(0, params->slider_value_out[0], 1), 0.f)) + fill_box = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + UI_Parent(fill_box) + { + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + ui_spacer(ui_pct(1.f, 0.f)); + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_PrefWidth(ui_px(toggler_size_px, 1.f)) + UI_PrefHeight(ui_px(toggler_size_px, 1.f)) + UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) + { + UI_Box *nub = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + } + } + } + } + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) // diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 66d14bf3..f4004990 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -54,8 +54,7 @@ struct RD_CellParams B32 *toggled_out; //- rjf: slider info r/w info - Rng1U64 slider_value_range; - U64 *slider_value_out; + F32 *slider_value_out; //- rjf: text editing r/w info TxtPt *cursor; From e621d1366965670c6c9628baa55dd579ab557a9a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 17:03:36 -0700 Subject: [PATCH 350/755] frontend ui/editor & data funnelling for hardware data breakpoints --- src/ctrl/ctrl_core.c | 2 ++ src/ctrl/ctrl_core.h | 9 +++++++++ src/dbg_engine/dbg_engine_core.c | 8 ++++++++ src/dbg_engine/dbg_engine_core.h | 9 +++++++++ src/raddbg/generated/raddbg.meta.c | 8 ++++++-- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 8 ++++++++ src/raddbg/raddbg_core.c | 16 ++++++++++++++++ 8 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 0e3ec2a7..96cff2ec 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -385,6 +385,7 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs) { CTRL_UserBreakpoint *bp = &n->v; str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->kind); + str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->flags); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->string.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->string.str, bp->string.size); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->pt); @@ -506,6 +507,7 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string) msg->user_bps.count += 1; CTRL_UserBreakpoint *bp = &n->v; read_off += str8_deserial_read_struct(string, read_off, &bp->kind); + read_off += str8_deserial_read_struct(string, read_off, &bp->flags); read_off += str8_deserial_read_struct(string, read_off, &bp->string.size); bp->string.str = push_array_no_zero(arena, U8, bp->string.size); read_off += str8_deserial_read(string, read_off, bp->string.str, bp->string.size, 1); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 5d5642f8..a3fab44e 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -259,6 +259,14 @@ struct CTRL_Spoof //////////////////////////////// //~ rjf: User Breakpoint Types +typedef U32 CTRL_UserBreakpointFlags; +enum +{ + CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0), + CTRL_UserBreakpointFlag_BreakOnRead = (1<<1), + CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2), +}; + typedef enum CTRL_UserBreakpointKind { CTRL_UserBreakpointKind_Null, @@ -272,6 +280,7 @@ typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint; struct CTRL_UserBreakpoint { CTRL_UserBreakpointKind kind; + CTRL_UserBreakpointFlags flags; String8 string; TxtPt pt; U64 u64; diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index dec0cf0d..884e1c53 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -2403,6 +2403,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: unpack user breakpoint entity D_Breakpoint *bp = &batch_breakpoints->v[idx]; + // rjf: d -> ctrl flags + CTRL_UserBreakpointFlags ctrl_bp_flags = 0; + if(bp->flags & D_BreakpointFlag_BreakOnWrite) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnWrite; } + if(bp->flags & D_BreakpointFlag_BreakOnRead) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnRead; } + if(bp->flags & D_BreakpointFlag_BreakOnExecute) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnExecute; } + // rjf: textual location -> add breakpoints for all possible override locations if(bp->file_path.size != 0 && bp->pt.line != 0) { @@ -2410,6 +2416,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P for(String8Node *n = overrides.first; n != 0; n = n->next) { CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber}; + ctrl_user_bp.flags = ctrl_bp_flags; ctrl_user_bp.string = n->string; ctrl_user_bp.pt = bp->pt; ctrl_user_bp.condition = bp->condition; @@ -2421,6 +2428,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P else if(bp->vaddr_expr.size != 0) { CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression}; + ctrl_user_bp.flags = ctrl_bp_flags; ctrl_user_bp.string = bp->vaddr_expr; ctrl_user_bp.condition = bp->condition; ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index cabaca1d..68c977a7 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -28,9 +28,18 @@ struct D_TargetArray U64 count; }; +typedef U32 D_BreakpointFlags; +enum +{ + D_BreakpointFlag_BreakOnWrite = (1<<0), + D_BreakpointFlag_BreakOnRead = (1<<1), + D_BreakpointFlag_BreakOnExecute = (1<<2), +}; + typedef struct D_Breakpoint D_Breakpoint; struct D_Breakpoint { + D_BreakpointFlags flags; String8 file_path; TxtPt pt; String8 vaddr_expr; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0e0c1425..c343c535 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[307] = +RD_VocabInfo rd_vocab_info_table[311] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -99,6 +99,10 @@ RD_VocabInfo rd_vocab_info_table[307] = {str8_lit_comp("num_columns"), str8_lit_comp(""), str8_lit_comp("Number of Columns"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("bitmap"), str8_lit_comp("bitmaps"), str8_lit_comp("Bitmap"), str8_lit_comp("Bitmaps"), RD_IconKind_Bitmap}, {str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, +{str8_lit_comp("address_range_size"), str8_lit_comp("address_range_sizes"), str8_lit_comp("Address Range Size"), str8_lit_comp("Address Range Sizes"), RD_IconKind_Null}, +{str8_lit_comp("break_on_read"), str8_lit_comp(""), str8_lit_comp("Break On Read"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("break_on_write"), str8_lit_comp(""), str8_lit_comp("Break On Write"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("break_on_execute"), str8_lit_comp(""), str8_lit_comp("Break On Execution"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -323,7 +327,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[16] = {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 1839748b..4bf58a22 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -644,7 +644,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[307]; +extern RD_VocabInfo rd_vocab_info_table[311]; extern RD_NameSchemaInfo rd_name_schema_info_table[16]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e535d07d..1bf5a8b1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -112,6 +112,10 @@ RD_VocabTable: {num_columns "" "Number of Columns" "" Null } {bitmap _ "Bitmap" _ Bitmap } {geo3d "" "Geometry (3D)" "" Cube } + {address_range_size _ "Address Range Size" _ Null } + {break_on_read "" "Break On Read" "" Null } + {break_on_write "" "Break On Write" "" Null } + {break_on_execute "" "Break On Execution" "" Null } } @struct RD_VocabInfo: @@ -249,6 +253,10 @@ RD_VocabTable: 'source_location': path_pt, 'address_location': code_string, 'hit_count': u64, + 'address_range_size': @or(1, 2, 4, 8) u64, + 'break_on_write': bool, + 'break_on_read': bool, + 'break_on_execute': bool, @no_expand @default(1) 'enabled': bool, } ```, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b1a3d113..e6c2da65 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15778,8 +15778,24 @@ Z(getting_started) continue; } + //- rjf: compute breakpoint flags + D_BreakpointFlags flags = 0; + if(str8_match(rd_cfg_child_from_string(src_bp, str8_lit("break_on_write"))->first->string, str8_lit("1"), 0)) + { + flags |= D_BreakpointFlag_BreakOnWrite; + } + if(str8_match(rd_cfg_child_from_string(src_bp, str8_lit("break_on_read"))->first->string, str8_lit("1"), 0)) + { + flags |= D_BreakpointFlag_BreakOnRead; + } + if(str8_match(rd_cfg_child_from_string(src_bp, str8_lit("break_on_execute"))->first->string, str8_lit("1"), 0)) + { + flags |= D_BreakpointFlag_BreakOnExecute; + } + //- rjf: fill breakpoint D_Breakpoint *dst_bp = &breakpoints.v[idx]; + dst_bp->flags = flags; dst_bp->file_path = src_bp_loc.file_path; dst_bp->pt = src_bp_loc.pt; dst_bp->vaddr_expr = src_bp_loc.expr; From 929e68d074f83561e6c9cab91f686d1aeec15d8d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 17:49:16 -0700 Subject: [PATCH 351/755] first pass at setting up x64 debug registers for data breakpoints --- src/demon/demon_core.h | 10 ++ src/demon/win32/demon_core_win32.c | 173 +++++++++++++++++++++++++---- src/regs/generated/regs.meta.c | 16 +-- src/regs/generated/regs.meta.h | 16 +-- src/regs/regs.mdesk | 16 +-- 5 files changed, 187 insertions(+), 44 deletions(-) diff --git a/src/demon/demon_core.h b/src/demon/demon_core.h index 32ef28a0..ef29a045 100644 --- a/src/demon/demon_core.h +++ b/src/demon/demon_core.h @@ -100,12 +100,22 @@ struct DMN_EventList //////////////////////////////// //~ rjf: Run Control Types +typedef U32 DMN_TrapFlags; +enum +{ + DMN_TrapFlag_BreakOnWrite = (1<<0), + DMN_TrapFlag_BreakOnRead = (1<<1), + DMN_TrapFlag_BreakOnExecute = (1<<2), +}; + typedef struct DMN_Trap DMN_Trap; struct DMN_Trap { DMN_Handle process; U64 vaddr; U64 id; + DMN_TrapFlags flags; + U32 length; }; typedef struct DMN_TrapChunkNode DMN_TrapChunkNode; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 5c40854e..4d454c5d 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -749,12 +749,12 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block) dst->fs.u16 = ctx->SegFs; dst->gs.u16 = ctx->SegGs; dst->ss.u16 = ctx->SegSs; - dst->dr0.u32 = ctx->Dr0; - dst->dr1.u32 = ctx->Dr1; - dst->dr2.u32 = ctx->Dr2; - dst->dr3.u32 = ctx->Dr3; - dst->dr6.u32 = ctx->Dr6; - dst->dr7.u32 = ctx->Dr7; + dst->dr0.u64 = ctx->Dr0; + dst->dr1.u64 = ctx->Dr1; + dst->dr2.u64 = ctx->Dr2; + dst->dr3.u64 = ctx->Dr3; + dst->dr6.u64 = ctx->Dr6; + dst->dr7.u64 = ctx->Dr7; // NOTE(rjf): this bit is "supposed to always be 1", according to old info. // may need to be investigated. dst->rflags.u64 = ctx->EFlags | 0x2; @@ -1020,12 +1020,12 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block) ctx->SegFs = src->fs.u16; ctx->SegGs = src->gs.u16; ctx->SegSs = src->ss.u16; - ctx->Dr0 = src->dr0.u32; - ctx->Dr1 = src->dr1.u32; - ctx->Dr2 = src->dr2.u32; - ctx->Dr3 = src->dr3.u32; - ctx->Dr6 = src->dr6.u32; - ctx->Dr7 = src->dr7.u32; + ctx->Dr0 = src->dr0.u64; + ctx->Dr1 = src->dr1.u64; + ctx->Dr2 = src->dr2.u64; + ctx->Dr3 = src->dr3.u64; + ctx->Dr6 = src->dr6.u64; + ctx->Dr7 = src->dr7.u64; ctx->EFlags = src->rflags.u64; fxsave->ControlWord = src->fcw.u16; fxsave->StatusWord = src->fsw.u16; @@ -1317,7 +1317,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL), (LPWSTR)&message, 0, 0); String8 message8 = message ? str8_from_16(scratch.arena, str16_cstring(message)) : str8_lit("unknown error"); LocalFree(message); - + log_user_errorf("There was an error starting %S: %S", params->cmd_line.first->string, message8); } } @@ -1557,10 +1557,140 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1) { DMN_Trap *trap = n->v+n_idx; - trap_swap_bytes[trap_idx] = 0xCC; - dmn_process_read(trap->process, r1u64(trap->vaddr, trap->vaddr+1), trap_swap_bytes+trap_idx); - U8 int3 = 0xCC; - dmn_process_write(trap->process, r1u64(trap->vaddr, trap->vaddr+1), &int3); + if(trap->flags == 0) + { + trap_swap_bytes[trap_idx] = 0xCC; + dmn_process_read(trap->process, r1u64(trap->vaddr, trap->vaddr+1), trap_swap_bytes+trap_idx); + U8 int3 = 0xCC; + dmn_process_write(trap->process, r1u64(trap->vaddr, trap->vaddr+1), &int3); + } + } + } + } + + ////////////////////////// + //- rjf: write all debug register states, for flagged-traps + // + ProfScope("write all debug register states, for flagged-traps") + { + //- rjf: gather all flagged traps, bucketed by process + typedef struct DMN_FlaggedTrapTask DMN_FlaggedTrapTask; + struct DMN_FlaggedTrapTask + { + DMN_FlaggedTrapTask *next; + DMN_Handle process; + DMN_TrapChunkList traps; + }; + DMN_FlaggedTrapTask *first_task = 0; + DMN_FlaggedTrapTask *last_task = 0; + for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) + { + for(U64 n_idx = 0; n_idx < n->count; n_idx += 1) + { + DMN_Trap *trap = n->v+n_idx; + if(trap->flags != 0) + { + DMN_FlaggedTrapTask *task = 0; + for(DMN_FlaggedTrapTask *t = first_task; t != 0; t = t->next) + { + if(dmn_handle_match(t->process, trap->process)) + { + task = t; + break; + } + } + if(task == 0) + { + task = push_array(scratch.arena, DMN_FlaggedTrapTask, 1); + SLLQueuePush(first_task, last_task, task); + task->process = trap->process; + } + dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap); + } + } + } + + //- rjf: for each flagged trap task, iterate all threads in the + // associated process, and prepare debug registers accordingly + for(DMN_FlaggedTrapTask *t = first_task; t != 0; t = t->next) + { + DMN_Handle process = t->process; + DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process); + for(DMN_W32_Entity *child = process_entity->first; + child != &dmn_w32_entity_nil; + child = child->next) + { + if(child->kind == DMN_W32_EntityKind_Thread) + { + switch(child->arch) + { + default:{}break; + + //- rjf: x64 + case Arch_x64: + { + REGS_RegBlockX64 regs = {0}; + dmn_thread_read_reg_block(ctrls->single_step_thread, ®s); + { + U64 trap_idx = 0; + for(DMN_TrapChunkNode *n = t->traps.first; n != 0; n = n->next) + { + for(U64 n_idx = 0; n_idx < n->count && trap_idx < 4; n_idx += 1, trap_idx += 1) + { + DMN_Trap *trap = &n->v[n_idx]; + REGS_Reg64 *addr_reg = ®s.dr0; + switch(trap_idx) + { + default:{}break; + case 0:{addr_reg = ®s.dr0;}break; + case 1:{addr_reg = ®s.dr1;}break; + case 2:{addr_reg = ®s.dr2;}break; + case 3:{addr_reg = ®s.dr3;}break; + } + addr_reg->u64 = trap->vaddr; + regs.dr7.u64 |= (1ull << (trap_idx*4)); + regs.dr7.u64 &= ~((U64)(bit16|bit17|bit18|bit19) << (trap_idx*4)); + switch(trap->flags) + { + case DMN_TrapFlag_BreakOnExecute: + default:{}break; + case DMN_TrapFlag_BreakOnWrite: + case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute: + { + regs.dr7.u64 |= ((U64)bit16) << (trap_idx*4); + }break; + case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute: + case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite: + { + regs.dr7.u64 |= (((U64)bit16) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit17) << (trap_idx*4)); + }break; + } + switch(trap->length) + { + case 1: + default:{}break; + case 2: + { + regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4)); + }break; + case 4: + { + regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4)); + }break; + case 8: + { + regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4)); + }break; + } + } + } + } + dmn_thread_write_reg_block(ctrls->single_step_thread, ®s); + }break; + } + } } } } @@ -2485,10 +2615,13 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1) { DMN_Trap *trap = n->v+n_idx; - U8 og_byte = trap_swap_bytes[trap_idx]; - if(og_byte != 0xCC) + if(trap->flags == 0) { - dmn_process_write(trap->process, r1u64(trap->vaddr, trap->vaddr+1), &og_byte); + U8 og_byte = trap_swap_bytes[trap_idx]; + if(og_byte != 0xCC) + { + dmn_process_write(trap->process, r1u64(trap->vaddr, trap->vaddr+1), &og_byte); + } } } } diff --git a/src/regs/generated/regs.meta.c b/src/regs/generated/regs.meta.c index c7f9f538..1f9f4b10 100644 --- a/src/regs/generated/regs.meta.c +++ b/src/regs/generated/regs.meta.c @@ -536,14 +536,14 @@ REGS_Rng regs_g_reg_code_x64_rng_table[101] = {(U16)OffsetOf(REGS_RegBlockX64, gsbase), 8}, {(U16)OffsetOf(REGS_RegBlockX64, rip), 8}, {(U16)OffsetOf(REGS_RegBlockX64, rflags), 8}, -{(U16)OffsetOf(REGS_RegBlockX64, dr0), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr1), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr2), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr3), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr4), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr5), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr6), 4}, -{(U16)OffsetOf(REGS_RegBlockX64, dr7), 4}, +{(U16)OffsetOf(REGS_RegBlockX64, dr0), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr1), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr2), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr3), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr4), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr5), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr6), 8}, +{(U16)OffsetOf(REGS_RegBlockX64, dr7), 8}, {(U16)OffsetOf(REGS_RegBlockX64, fpr0), 10}, {(U16)OffsetOf(REGS_RegBlockX64, fpr1), 10}, {(U16)OffsetOf(REGS_RegBlockX64, fpr2), 10}, diff --git a/src/regs/generated/regs.meta.h b/src/regs/generated/regs.meta.h index c2abaac9..f3cdf807 100644 --- a/src/regs/generated/regs.meta.h +++ b/src/regs/generated/regs.meta.h @@ -343,14 +343,14 @@ REGS_Reg64 fsbase; REGS_Reg64 gsbase; REGS_Reg64 rip; REGS_Reg64 rflags; -REGS_Reg32 dr0; -REGS_Reg32 dr1; -REGS_Reg32 dr2; -REGS_Reg32 dr3; -REGS_Reg32 dr4; -REGS_Reg32 dr5; -REGS_Reg32 dr6; -REGS_Reg32 dr7; +REGS_Reg64 dr0; +REGS_Reg64 dr1; +REGS_Reg64 dr2; +REGS_Reg64 dr3; +REGS_Reg64 dr4; +REGS_Reg64 dr5; +REGS_Reg64 dr6; +REGS_Reg64 dr7; REGS_Reg80 fpr0; REGS_Reg80 fpr1; REGS_Reg80 fpr2; diff --git a/src/regs/regs.mdesk b/src/regs/regs.mdesk index 2f68c43e..5e4ae872 100644 --- a/src/regs/regs.mdesk +++ b/src/regs/regs.mdesk @@ -27,14 +27,14 @@ REGS_RegTableX64: {gsbase 64 Normal} {rip 64 Normal} {rflags 64 Normal} - {dr0 32 Normal} - {dr1 32 Normal} - {dr2 32 Normal} - {dr3 32 Normal} - {dr4 32 Normal} - {dr5 32 Normal} - {dr6 32 Normal} - {dr7 32 Normal} + {dr0 64 Normal} + {dr1 64 Normal} + {dr2 64 Normal} + {dr3 64 Normal} + {dr4 64 Normal} + {dr5 64 Normal} + {dr6 64 Normal} + {dr7 64 Normal} {fpr0 80 Normal} {fpr1 80 Normal} {fpr2 80 Normal} From ecad70ca19b0fece5d0f4dd02dafe5cb2aa253fa Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 11 Apr 2025 18:07:00 -0700 Subject: [PATCH 352/755] pass through data breakpoint length, more progress on fixes/correctness in first pass --- src/ctrl/ctrl_core.c | 18 ++++++++++++++++-- src/ctrl/ctrl_core.h | 3 ++- src/dbg_engine/dbg_engine_core.c | 2 ++ src/dbg_engine/dbg_engine_core.h | 1 + src/demon/demon_core.h | 2 +- src/demon/win32/demon_core_win32.c | 21 +++++++++++---------- src/raddbg/raddbg_core.c | 8 ++++++++ 7 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 96cff2ec..027f6429 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -121,6 +121,16 @@ ctrl_entity_kind_from_string(String8 string) return result; } +internal DMN_TrapFlags +ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags) +{ + DMN_TrapFlags result = 0; + if(flags & CTRL_UserBreakpointFlag_BreakOnWrite) { result |= DMN_TrapFlag_BreakOnWrite; } + if(flags & CTRL_UserBreakpointFlag_BreakOnRead) { result |= DMN_TrapFlag_BreakOnRead; } + if(flags & CTRL_UserBreakpointFlag_BreakOnExecute) { result |= DMN_TrapFlag_BreakOnExecute; } + return result; +} + //////////////////////////////// //~ rjf: Machine/Handle Pair Type Functions @@ -389,7 +399,7 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs) str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->string.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->string.str, bp->string.size); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->pt); - str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->u64); + str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->size); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->condition.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->condition.str, bp->condition.size); } @@ -512,7 +522,7 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string) bp->string.str = push_array_no_zero(arena, U8, bp->string.size); read_off += str8_deserial_read(string, read_off, bp->string.str, bp->string.size, 1); read_off += str8_deserial_read_struct(string, read_off, &bp->pt); - read_off += str8_deserial_read_struct(string, read_off, &bp->u64); + read_off += str8_deserial_read_struct(string, read_off, &bp->size); read_off += str8_deserial_read_struct(string, read_off, &bp->condition.size); bp->condition.str = push_array_no_zero(arena, U8, bp->condition.size); read_off += str8_deserial_read(string, read_off, bp->condition.str, bp->condition.size, 1); @@ -3561,6 +3571,8 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope * if(value.u64 != 0) { DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + trap.flags = ctrl_dmn_trap_flags_from_user_breakpoint_flags(bp->flags); + trap.size = bp->size; dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); } }break; @@ -3582,6 +3594,8 @@ ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope if(value.u64 != 0) { DMN_Trap trap = {process.dmn_handle, value.u64, (U64)bp}; + trap.flags = ctrl_dmn_trap_flags_from_user_breakpoint_flags(bp->flags); + trap.size = bp->size; dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); } } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index a3fab44e..aae980a7 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -283,7 +283,7 @@ struct CTRL_UserBreakpoint CTRL_UserBreakpointFlags flags; String8 string; TxtPt pt; - U64 u64; + U64 size; String8 condition; }; @@ -753,6 +753,7 @@ internal CTRL_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind) internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); +internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags); //////////////////////////////// //~ rjf: Handle Type Functions diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 884e1c53..058221da 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -2420,6 +2420,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P ctrl_user_bp.string = n->string; ctrl_user_bp.pt = bp->pt; ctrl_user_bp.condition = bp->condition; + ctrl_user_bp.size = bp->size; ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); } } @@ -2431,6 +2432,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P ctrl_user_bp.flags = ctrl_bp_flags; ctrl_user_bp.string = bp->vaddr_expr; ctrl_user_bp.condition = bp->condition; + ctrl_user_bp.size = bp->size; ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); } } diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 68c977a7..10d237cd 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -44,6 +44,7 @@ struct D_Breakpoint TxtPt pt; String8 vaddr_expr; String8 condition; + U64 size; }; typedef struct D_BreakpointArray D_BreakpointArray; diff --git a/src/demon/demon_core.h b/src/demon/demon_core.h index ef29a045..522988a1 100644 --- a/src/demon/demon_core.h +++ b/src/demon/demon_core.h @@ -115,7 +115,7 @@ struct DMN_Trap U64 vaddr; U64 id; DMN_TrapFlags flags; - U32 length; + U32 size; }; typedef struct DMN_TrapChunkNode DMN_TrapChunkNode; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 4d454c5d..d9a7618b 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1630,7 +1630,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case Arch_x64: { REGS_RegBlockX64 regs = {0}; - dmn_thread_read_reg_block(ctrls->single_step_thread, ®s); + dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s); { U64 trap_idx = 0; for(DMN_TrapChunkNode *n = t->traps.first; n != 0; n = n->next) @@ -1648,8 +1648,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case 3:{addr_reg = ®s.dr3;}break; } addr_reg->u64 = trap->vaddr; - regs.dr7.u64 |= (1ull << (trap_idx*4)); - regs.dr7.u64 &= ~((U64)(bit16|bit17|bit18|bit19) << (trap_idx*4)); + regs.dr7.u64 |= (1ull << (trap_idx*2)); + regs.dr7.u64 |= (1ull << (trap_idx*2+1)); + regs.dr7.u64 &= ~((U64)(bit17|bit18|bit19|bit20) << (trap_idx*4)); switch(trap->flags) { case DMN_TrapFlag_BreakOnExecute: @@ -1657,37 +1658,37 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case DMN_TrapFlag_BreakOnWrite: case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute: { - regs.dr7.u64 |= ((U64)bit16) << (trap_idx*4); + regs.dr7.u64 |= ((U64)bit17) << (trap_idx*4); }break; case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute: case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite: { - regs.dr7.u64 |= (((U64)bit16) << (trap_idx*4)); regs.dr7.u64 |= (((U64)bit17) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4)); }break; } - switch(trap->length) + switch(trap->size) { case 1: default:{}break; case 2: { - regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4)); }break; case 4: { - regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4)); regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4)); }break; case 8: { - regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4)); + regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4)); }break; } } } } - dmn_thread_write_reg_block(ctrls->single_step_thread, ®s); + dmn_w32_thread_write_reg_block(child->arch, child->handle, ®s); }break; } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e6c2da65..992a034e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15793,6 +15793,13 @@ Z(getting_started) flags |= D_BreakpointFlag_BreakOnExecute; } + //- rjf: compute address range size + U64 addr_range_size = 0; + { + RD_Cfg *address_range_size_cfg = rd_cfg_child_from_string(src_bp, str8_lit("address_range_size")); + try_u64_from_str8_c_rules(address_range_size_cfg->first->string, &addr_range_size); + } + //- rjf: fill breakpoint D_Breakpoint *dst_bp = &breakpoints.v[idx]; dst_bp->flags = flags; @@ -15800,6 +15807,7 @@ Z(getting_started) dst_bp->pt = src_bp_loc.pt; dst_bp->vaddr_expr = src_bp_loc.expr; dst_bp->condition = non_ctrl_thread_static_condition; + dst_bp->size = addr_range_size; idx += 1; } } From 3f69b028e48ea4242149226b7c652b43c70d7b68 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 07:34:27 -0700 Subject: [PATCH 353/755] fix ptr-to-ptr expansions --- src/eval/eval_types.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 57a3c53e..34b0f507 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1894,6 +1894,7 @@ internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey root_key) { E_TypeKey type_key = zero_struct; + B32 hit_1ptr = 0; for(E_TypeKey key = root_key; !e_type_key_match(e_type_key_zero(), key); key = e_type_direct_from_key(key)) @@ -1913,8 +1914,13 @@ e_default_expansion_type_from_key(E_TypeKey root_key) E_Type *type = e_type_from_key__cached(key); if(!e_type_key_match(e_type_key_basic(E_TypeKind_Void), type->direct_type_key)) { - if(type->count == 1) + if(type->count == 1 && hit_1ptr) { + type_key = key; + } + else if(type->count == 1 && !hit_1ptr) + { + hit_1ptr = 1; done = 0; } else if(type->count > 1) From d894f7112f3a4374acefc96251e59fb759b4066b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 07:55:19 -0700 Subject: [PATCH 354/755] array view rule --- src/eval/eval_ir.c | 5 ++--- src/eval/eval_types.c | 31 +++++++++++++++++++++++++++++++ src/eval/eval_types.h | 7 +++++++ src/raddbg/raddbg_core.c | 1 + 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index df177443..b47d4559 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -93,7 +93,6 @@ e_select_ir_ctx(E_IRCtx *ctx) String8 builtin_view_rule_names[] = { str8_lit_comp("bswap"), - str8_lit_comp("array"), }; for EachElement(idx, builtin_view_rule_names) { @@ -2255,8 +2254,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { irtree_stripped.type_key = e_type_direct_from_key(irtree_stripped.type_key); } - E_IRExt ext = type->irext(arena, expr, &irtree_stripped); - result.user_data = ext.user_data; + E_IRExt ext = type->irext(arena, expr, &irtree_stripped); + result.user_data = ext.user_data; } //- rjf: equip previous task's irtree diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 34b0f507..b6194826 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2319,6 +2319,37 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) return id; } +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `array` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) +{ + E_Type *type = e_type_from_key__cached(irtree->type_key); + U64 count = 1; + if(type->args != 0 && type->count > 0) + { + E_Expr *count_expr = type->args[0]; + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = irtree; + { + E_Value count_value = e_value_from_expr(count_expr); + count = count_value.u64; + } + e_ir_state->overridden_irtree = prev_overridden_irtree; + } + E_TypeExpandInfo info = {0, count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array) +{ + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); + } +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `slice` lens diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 171634d1..c606c1be 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -291,12 +291,19 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `array` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(array); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `slice` lens E_TYPE_IREXT_FUNCTION_DEF(slice); E_TYPE_ACCESS_FUNCTION_DEF(slice); E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice); //////////////////////////////// //~ rjf: (Built-In Type Hooks) `only`, `omit` lenses diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 992a034e..08616cbb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12345,6 +12345,7 @@ rd_frame(void) {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, + {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, From 0f380e9228acc00b87d3a9e5567793961c64b76c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 14:28:38 -0700 Subject: [PATCH 355/755] transmit user breakpoints hit from demon -> ctrl using ctrl-defined IDs, correllate those IDs to rd-defined IDs, use rd-defined IDs in stop events to count bp hits, rather than re-resolving breakpoints. further fixes & work on first pass of data breakpoints --- src/ctrl/ctrl_core.c | 36 ++++-- src/ctrl/ctrl_core.h | 1 + src/dbg_engine/dbg_engine_core.c | 3 + src/dbg_engine/dbg_engine_core.h | 2 + src/demon/win32/demon_core_win32.c | 185 +++++++++++++++++++++++------ src/raddbg/raddbg_core.c | 25 +--- 6 files changed, 181 insertions(+), 71 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 027f6429..a2a231bf 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -396,6 +396,7 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs) CTRL_UserBreakpoint *bp = &n->v; str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->kind); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->flags); + str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->id); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->string.size); str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->string.str, bp->string.size); str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->pt); @@ -518,6 +519,7 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string) CTRL_UserBreakpoint *bp = &n->v; read_off += str8_deserial_read_struct(string, read_off, &bp->kind); read_off += str8_deserial_read_struct(string, read_off, &bp->flags); + read_off += str8_deserial_read_struct(string, read_off, &bp->id); read_off += str8_deserial_read_struct(string, read_off, &bp->string.size); bp->string.str = push_array_no_zero(arena, U8, bp->string.size); read_off += str8_deserial_read(string, read_off, bp->string.str, bp->string.size, 1); @@ -5731,21 +5733,28 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } // rjf: user breakpoints - for(DMN_TrapChunkNode *n = user_traps.first; n != 0; n = n->next) { - DMN_Trap *trap = n->v; - DMN_Trap *opl = n->v + n->count; - for(;trap < opl; trap += 1) + if(event->user_data != 0) { - if(dmn_handle_match(trap->process, event->process) && - trap->vaddr == event->instruction_pointer && - (!dmn_handle_match(event->thread, target_thread.dmn_handle) || !target_thread_is_on_user_bp_and_trap_net_trap)) + CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)event->user_data; + hit_user_bp = 1; + } + for(DMN_TrapChunkNode *n = user_traps.first; n != 0; n = n->next) + { + DMN_Trap *trap = n->v; + DMN_Trap *opl = n->v + n->count; + for(;trap < opl; trap += 1) { - CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)trap->id; - hit_user_bp = 1; - if(user_bp != 0 && user_bp->condition.size != 0) + if(dmn_handle_match(trap->process, event->process) && + trap->vaddr == event->instruction_pointer && + (!dmn_handle_match(event->thread, target_thread.dmn_handle) || !target_thread_is_on_user_bp_and_trap_net_trap)) { - str8_list_push(temp.arena, &conditions, user_bp->condition); + CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)trap->id; + hit_user_bp = 1; + if(user_bp != 0 && user_bp->condition.size != 0) + { + str8_list_push(temp.arena, &conditions, user_bp->condition); + } } } } @@ -6090,6 +6099,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->exception_kind = ctrl_exception_kind_from_dmn(stop_event->exception_kind); event->vaddr_rng = r1u64(stop_event->address, stop_event->address); event->rip_vaddr = stop_event->instruction_pointer; + if(stop_cause == CTRL_EventCause_UserBreakpoint && stop_event->user_data != 0) + { + CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)stop_event->user_data; + event->u64_code = user_bp->id; + } ctrl_c2u_push_events(&evts); } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index aae980a7..e8481f95 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -281,6 +281,7 @@ struct CTRL_UserBreakpoint { CTRL_UserBreakpointKind kind; CTRL_UserBreakpointFlags flags; + U64 id; String8 string; TxtPt pt; U64 size; diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 058221da..dea8294e 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1795,6 +1795,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P evt->cause = cause; evt->thread = thread->kind == CTRL_EntityKind_Thread ? thread->handle : ctrl_handle_zero(); evt->vaddr = event->rip_vaddr; + evt->id = event->u64_code; } }break; @@ -2417,6 +2418,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber}; ctrl_user_bp.flags = ctrl_bp_flags; + ctrl_user_bp.id = bp->id; ctrl_user_bp.string = n->string; ctrl_user_bp.pt = bp->pt; ctrl_user_bp.condition = bp->condition; @@ -2430,6 +2432,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression}; ctrl_user_bp.flags = ctrl_bp_flags; + ctrl_user_bp.id = bp->id; ctrl_user_bp.string = bp->vaddr_expr; ctrl_user_bp.condition = bp->condition; ctrl_user_bp.size = bp->size; diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 10d237cd..4efc7234 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -40,6 +40,7 @@ typedef struct D_Breakpoint D_Breakpoint; struct D_Breakpoint { D_BreakpointFlags flags; + U64 id; String8 file_path; TxtPt pt; String8 vaddr_expr; @@ -98,6 +99,7 @@ struct D_Event CTRL_Handle thread; U64 vaddr; U64 code; + U64 id; }; typedef struct D_EventNode D_EventNode; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index d9a7618b..5ec06fe0 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1568,51 +1568,53 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } } + ////////////////////////// + //- rjf: gather all flagged traps, bucketed by process + // + typedef struct DMN_FlaggedTrapTask DMN_FlaggedTrapTask; + struct DMN_FlaggedTrapTask + { + DMN_FlaggedTrapTask *next; + DMN_Handle process; + DMN_TrapChunkList traps; + }; + DMN_FlaggedTrapTask *first_flagged_trap_task = 0; + DMN_FlaggedTrapTask *last_flagged_trap_task= 0; + for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) + { + for(U64 n_idx = 0; n_idx < n->count; n_idx += 1) + { + DMN_Trap *trap = n->v+n_idx; + if(trap->flags != 0) + { + DMN_FlaggedTrapTask *task = 0; + for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next) + { + if(dmn_handle_match(t->process, trap->process)) + { + task = t; + break; + } + } + if(task == 0) + { + task = push_array(scratch.arena, DMN_FlaggedTrapTask, 1); + SLLQueuePush(first_flagged_trap_task, last_flagged_trap_task, task); + task->process = trap->process; + } + dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap); + } + } + } + ////////////////////////// //- rjf: write all debug register states, for flagged-traps // ProfScope("write all debug register states, for flagged-traps") { - //- rjf: gather all flagged traps, bucketed by process - typedef struct DMN_FlaggedTrapTask DMN_FlaggedTrapTask; - struct DMN_FlaggedTrapTask - { - DMN_FlaggedTrapTask *next; - DMN_Handle process; - DMN_TrapChunkList traps; - }; - DMN_FlaggedTrapTask *first_task = 0; - DMN_FlaggedTrapTask *last_task = 0; - for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) - { - for(U64 n_idx = 0; n_idx < n->count; n_idx += 1) - { - DMN_Trap *trap = n->v+n_idx; - if(trap->flags != 0) - { - DMN_FlaggedTrapTask *task = 0; - for(DMN_FlaggedTrapTask *t = first_task; t != 0; t = t->next) - { - if(dmn_handle_match(t->process, trap->process)) - { - task = t; - break; - } - } - if(task == 0) - { - task = push_array(scratch.arena, DMN_FlaggedTrapTask, 1); - SLLQueuePush(first_task, last_task, task); - task->process = trap->process; - } - dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap); - } - } - } - //- rjf: for each flagged trap task, iterate all threads in the // associated process, and prepare debug registers accordingly - for(DMN_FlaggedTrapTask *t = first_task; t != 0; t = t->next) + for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next) { DMN_Handle process = t->process; DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process); @@ -1648,9 +1650,11 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case 3:{addr_reg = ®s.dr3;}break; } addr_reg->u64 = trap->vaddr; + regs.dr7.u64 |= bit9|bit10|bit11; regs.dr7.u64 |= (1ull << (trap_idx*2)); - regs.dr7.u64 |= (1ull << (trap_idx*2+1)); + // NOTE(rjf): global-enable regs.dr7.u64 |= (1ull << (trap_idx*2+1)); regs.dr7.u64 &= ~((U64)(bit17|bit18|bit19|bit20) << (trap_idx*4)); + regs.dr7.u64 &= ~((U64)(bit15|bit16)); switch(trap->flags) { case DMN_TrapFlag_BreakOnExecute: @@ -2217,6 +2221,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) //- rjf: check if this trap is a usage-code-specified trap or something else B32 hit_user_trap = 0; + U64 user_trap_id = 0; if(is_trap) { for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) @@ -2226,6 +2231,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) if(dmn_handle_match(n->v[idx].process, dmn_w32_handle_from_entity(process)) && n->v[idx].vaddr == instruction_pointer) { hit_user_trap = 1; + user_trap_id = n->v[idx].id; break; } } @@ -2314,6 +2320,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) e->code = exception->ExceptionCode; e->flags = exception->ExceptionFlags; e->instruction_pointer = (U64)exception->ExceptionAddress; + e->user_data = user_trap_id; //- rjf: fill according to exception code switch(exception->ExceptionCode) @@ -2343,6 +2350,71 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case DMN_W32_EXCEPTION_SINGLE_STEP: { e->kind = DMN_EventKind_SingleStep; + + // NOTE(rjf): data breakpoints are reported via single-steps + // over the instructions which caused the breakpoint to be + // hit - so if we have data breakpoints set, we need to + // check this thread's debug registers, to determine if this + // is a regular single-step or a data breakpoint hit. + if(first_flagged_trap_task != 0) + { + // rjf: first determine the flagged trap index + U64 flagged_trap_idx = 0; + switch(thread->arch) + { + default:{NotImplemented;}break; + case Arch_x64: + { + REGS_RegBlockX64 regs = {0}; + dmn_w32_thread_read_reg_block(thread->arch, thread->handle, ®s); + if(regs.dr6.u64 & 0xF) + { + e->kind = DMN_EventKind_Breakpoint; + if(0){} + else if(regs.dr7.u64 & (1ull<<0) && regs.dr6.u64 & (1ull<<0)) { flagged_trap_idx = 1; } + else if(regs.dr7.u64 & (1ull<<1) && regs.dr6.u64 & (1ull<<1)) { flagged_trap_idx = 2; } + else if(regs.dr7.u64 & (1ull<<2) && regs.dr6.u64 & (1ull<<2)) { flagged_trap_idx = 3; } + else if(regs.dr7.u64 & (1ull<<3) && regs.dr6.u64 & (1ull<<3)) { flagged_trap_idx = 3; } + } + }break; + } + + // rjf: find the flagged trap task for this thread's process + DMN_W32_Entity *process = thread->parent; + DMN_FlaggedTrapTask *task = 0; + for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next) + { + if(dmn_handle_match(t->process, dmn_w32_handle_from_entity(process))) + { + task = t; + break; + } + } + + // rjf: find the trap + DMN_Trap *trap = 0; + if(task != 0) + { + U64 trap_idx = 0; + for(DMN_TrapChunkNode *n = task->traps.first; n != 0; n = n->next) + { + for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1) + { + if(trap_idx == flagged_trap_idx) + { + trap = &n->v[n_idx]; + break; + } + } + } + } + + // rjf: fill event based on trap + if(trap != 0) + { + e->user_data = trap->id; + } + } }break; //- rjf: fill throw info @@ -2563,7 +2635,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } } + //////////////////////// //- rjf: gather new thread-names + // ProfScope("gather new thread names") if(dmn_w32_GetThreadDescription != 0) { for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first; @@ -2628,6 +2702,39 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } } + ////////////////////////// + //- rjf: clear all debug register states, for flagged-traps + // + ProfScope("clear all debug register states, for flagged-traps") + { + for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next) + { + DMN_Handle process = t->process; + DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process); + for(DMN_W32_Entity *child = process_entity->first; + child != &dmn_w32_entity_nil; + child = child->next) + { + if(child->kind == DMN_W32_EntityKind_Thread) + { + switch(child->arch) + { + default:{}break; + + //- rjf: x64 + case Arch_x64: + { + REGS_RegBlockX64 regs = {0}; + dmn_w32_thread_read_reg_block(child->arch, child->handle, ®s); + regs.dr7.u64 = 0; + dmn_w32_thread_write_reg_block(child->arch, child->handle, ®s); + }break; + } + } + } + } + } + ////////////////////////// //- rjf: unset single step bit // diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 08616cbb..08b445c4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15804,6 +15804,7 @@ Z(getting_started) //- rjf: fill breakpoint D_Breakpoint *dst_bp = &breakpoints.v[idx]; dst_bp->flags = flags; + dst_bp->id = src_bp->id; dst_bp->file_path = src_bp_loc.file_path; dst_bp->pt = src_bp_loc.pt; dst_bp->vaddr_expr = src_bp_loc.expr; @@ -15944,31 +15945,13 @@ Z(getting_started) // rjf: increment breakpoint hit counts if(evt->cause == D_EventCause_UserBreakpoint) { - RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); - for(RD_CfgNode *n = bps.first; n != 0; n = n->next) + RD_Cfg *bp = rd_cfg_from_id(evt->id); + if(bp != &rd_nil_cfg) { - RD_Cfg *bp = n->v; RD_Cfg *hit_count_root = rd_cfg_child_from_string_or_alloc(bp, str8_lit("hit_count")); U64 hit_count = 0; try_u64_from_str8_c_rules(hit_count_root->first->string, &hit_count); - RD_Location loc = rd_location_from_cfg(bp); - D_LineList loc_lines = d_lines_from_file_path_line_num(scratch.arena, loc.file_path, loc.pt.line); - E_Value loc_value = e_value_from_string(loc.expr); - if(loc_lines.first != 0) - { - for(D_LineNode *n = loc_lines.first; n != 0; n = n->next) - { - if(contains_1u64(n->v.voff_range, voff)) - { - hit_count += 1; - break; - } - } - } - else if(loc_value.u64 != 0 && vaddr == loc_value.u64) - { - hit_count += 1; - } + hit_count += 1; rd_cfg_new_replacef(hit_count_root, "%I64u", hit_count); } } From 97e3c73086dcdf4002c9b45b2b045e05831e0fb9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 14:39:38 -0700 Subject: [PATCH 356/755] fix flagged-trap-search --- src/demon/win32/demon_core_win32.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 5ec06fe0..4853fb23 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2371,10 +2371,10 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { e->kind = DMN_EventKind_Breakpoint; if(0){} - else if(regs.dr7.u64 & (1ull<<0) && regs.dr6.u64 & (1ull<<0)) { flagged_trap_idx = 1; } - else if(regs.dr7.u64 & (1ull<<1) && regs.dr6.u64 & (1ull<<1)) { flagged_trap_idx = 2; } - else if(regs.dr7.u64 & (1ull<<2) && regs.dr6.u64 & (1ull<<2)) { flagged_trap_idx = 3; } - else if(regs.dr7.u64 & (1ull<<3) && regs.dr6.u64 & (1ull<<3)) { flagged_trap_idx = 3; } + else if(regs.dr7.u64 & (1ull<<0) && regs.dr6.u64 & (1ull<<0)) { flagged_trap_idx = 0; } + else if(regs.dr7.u64 & (1ull<<2) && regs.dr6.u64 & (1ull<<1)) { flagged_trap_idx = 1; } + else if(regs.dr7.u64 & (1ull<<4) && regs.dr6.u64 & (1ull<<2)) { flagged_trap_idx = 2; } + else if(regs.dr7.u64 & (1ull<<8) && regs.dr6.u64 & (1ull<<3)) { flagged_trap_idx = 3; } } }break; } @@ -2403,10 +2403,11 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) if(trap_idx == flagged_trap_idx) { trap = &n->v[n_idx]; - break; + goto break_search_for_flagged_trap; } } } + break_search_for_flagged_trap:; } // rjf: fill event based on trap From 6a5fa58d8a9853be8aea16ca9cb94c3710d4fdd1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 14:47:29 -0700 Subject: [PATCH 357/755] dedup flagged traps, so we don't write the same data breakpoint into the registers multiple times --- src/demon/win32/demon_core_win32.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 4853fb23..bca362dd 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1602,7 +1602,23 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) SLLQueuePush(first_flagged_trap_task, last_flagged_trap_task, task); task->process = trap->process; } - dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap); + B32 already_in_task = 0; + for(DMN_TrapChunkNode *n = task->traps.first; n != 0; n = n->next) + { + for(U64 n_idx = 0; n_idx < n->count; n_idx += 1) + { + if(n->v[n_idx].id == trap->id) + { + already_in_task = 1; + goto end_look_for_existing_trap_in_task; + } + } + } + end_look_for_existing_trap_in_task:; + if(!already_in_task) + { + dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap); + } } } } From 7ba027e84183f5c1cdbbe83f0eb55b4866379f20 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 15:21:48 -0700 Subject: [PATCH 358/755] sketch out new markup API for programmatic address/data breakpoints --- src/ctrl/ctrl_core.c | 30 +++++++++- src/ctrl/ctrl_core.h | 6 +- src/demon/demon_core.h | 2 +- src/demon/demon_core.mdesk | 2 + src/demon/generated/demon.meta.c | 4 +- src/demon/generated/demon.meta.h | 4 +- src/demon/win32/demon_core_win32.c | 17 ++++++ src/demon/win32/demon_core_win32.h | 85 ++++++++++++++------------- src/lib_raddbg_markup/raddbg_markup.h | 83 +++++++++++++++++++------- src/mule/mule_main.cpp | 21 ++++++- 10 files changed, 184 insertions(+), 70 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index a2a231bf..5ae8b19f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -131,6 +131,16 @@ ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags) return result; } +internal CTRL_UserBreakpointFlags +ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags) +{ + CTRL_UserBreakpointFlags result = 0; + if(flags & DMN_TrapFlag_BreakOnWrite) { result |= CTRL_UserBreakpointFlag_BreakOnWrite; } + if(flags & DMN_TrapFlag_BreakOnRead) { result |= CTRL_UserBreakpointFlag_BreakOnRead; } + if(flags & DMN_TrapFlag_BreakOnExecute) { result |= CTRL_UserBreakpointFlag_BreakOnExecute; } + return result; +} + //////////////////////////////// //~ rjf: Machine/Handle Pair Type Functions @@ -588,8 +598,9 @@ ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *event, U64 max) str8_serial_push_struct(scratch.arena, &srl, &event->stack_base); str8_serial_push_struct(scratch.arena, &srl, &event->tls_root); str8_serial_push_struct(scratch.arena, &srl, &event->timestamp); - str8_serial_push_struct(scratch.arena, &srl, &event->rgba); str8_serial_push_struct(scratch.arena, &srl, &event->exception_code); + str8_serial_push_struct(scratch.arena, &srl, &event->rgba); + str8_serial_push_struct(scratch.arena, &srl, &event->bp_flags); String8 string = event->string; string.size = Min(string.size, max-srl.total_size); str8_serial_push_struct(scratch.arena, &srl, &string.size); @@ -620,8 +631,9 @@ ctrl_event_from_serialized_string(Arena *arena, String8 string) read_off += str8_deserial_read_struct(string, read_off, &event.stack_base); read_off += str8_deserial_read_struct(string, read_off, &event.tls_root); read_off += str8_deserial_read_struct(string, read_off, &event.timestamp); - read_off += str8_deserial_read_struct(string, read_off, &event.rgba); read_off += str8_deserial_read_struct(string, read_off, &event.exception_code); + read_off += str8_deserial_read_struct(string, read_off, &event.rgba); + read_off += str8_deserial_read_struct(string, read_off, &event.bp_flags); read_off += str8_deserial_read_struct(string, read_off, &event.string.size); event.string.str = push_array_no_zero(arena, U8, event.string.size); read_off += str8_deserial_read(string, read_off, event.string.str, event.string.size, 1); @@ -4353,6 +4365,20 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); out_evt->rgba = event->code; }break; + case DMN_EventKind_SetBreakpoint: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_SetBreakpoint; + out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); + out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); + }break; + case DMN_EventKind_UnsetBreakpoint: + { + CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); + out_evt->kind = CTRL_EventKind_UnsetBreakpoint; + out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); + out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); + }break; } ctrl_c2u_push_events(&evts); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index e8481f95..3ded38c1 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -406,10 +406,12 @@ typedef enum CTRL_EventKind //- rjf: debug info changes CTRL_EventKind_ModuleDebugInfoPathChange, - //- rjf: debug strings / decorations + //- rjf: debug strings / decorations / markup CTRL_EventKind_DebugString, CTRL_EventKind_ThreadName, CTRL_EventKind_ThreadColor, + CTRL_EventKind_SetBreakpoint, + CTRL_EventKind_UnsetBreakpoint, //- rjf: memory CTRL_EventKind_MemReserve, @@ -465,6 +467,7 @@ struct CTRL_Event U64 timestamp; U32 exception_code; U32 rgba; + CTRL_UserBreakpointFlags bp_flags; String8 string; }; @@ -755,6 +758,7 @@ internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string); internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags); +internal CTRL_UserBreakpointFlags ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags); //////////////////////////////// //~ rjf: Handle Type Functions diff --git a/src/demon/demon_core.h b/src/demon/demon_core.h index 522988a1..94f8d8c3 100644 --- a/src/demon/demon_core.h +++ b/src/demon/demon_core.h @@ -73,7 +73,7 @@ struct DMN_Event U64 size; String8 string; U32 code; // code gives pid & tid on CreateProcess and CreateThread (respectfully) - U32 flags; + U32 flags; // DMN_TrapFlags, if `DMN_EventKind_SetBreakpoint` S32 signo; S32 sigcode; U64 instruction_pointer; diff --git a/src/demon/demon_core.mdesk b/src/demon/demon_core.mdesk index ea3139f6..3c9a367e 100644 --- a/src/demon/demon_core.mdesk +++ b/src/demon/demon_core.mdesk @@ -22,6 +22,8 @@ DMN_EventKindTable: {DebugString} {SetThreadName} {SetThreadColor} + {SetBreakpoint} + {UnsetBreakpoint} } @table(name) diff --git a/src/demon/generated/demon.meta.c b/src/demon/generated/demon.meta.c index 3aa15e72..47406944 100644 --- a/src/demon/generated/demon.meta.c +++ b/src/demon/generated/demon.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 dmn_event_kind_string_table[18] = +String8 dmn_event_kind_string_table[20] = { str8_lit_comp("Null"), str8_lit_comp("Error"), @@ -24,6 +24,8 @@ str8_lit_comp("Memory"), str8_lit_comp("DebugString"), str8_lit_comp("SetThreadName"), str8_lit_comp("SetThreadColor"), +str8_lit_comp("SetBreakpoint"), +str8_lit_comp("UnsetBreakpoint"), }; String8 dmn_exception_kind_string_table[5] = diff --git a/src/demon/generated/demon.meta.h b/src/demon/generated/demon.meta.h index f5fdae4c..4a8b5b80 100644 --- a/src/demon/generated/demon.meta.h +++ b/src/demon/generated/demon.meta.h @@ -26,6 +26,8 @@ DMN_EventKind_Memory, DMN_EventKind_DebugString, DMN_EventKind_SetThreadName, DMN_EventKind_SetThreadColor, +DMN_EventKind_SetBreakpoint, +DMN_EventKind_UnsetBreakpoint, DMN_EventKind_COUNT, } DMN_EventKind; @@ -59,7 +61,7 @@ DMN_ExceptionKind_COUNT, } DMN_ExceptionKind; C_LINKAGE_BEGIN -extern String8 dmn_event_kind_string_table[18]; +extern String8 dmn_event_kind_string_table[20]; extern String8 dmn_exception_kind_string_table[5]; C_LINKAGE_END diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index bca362dd..6480d200 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2527,6 +2527,23 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) e->code = exception->ExceptionInformation[1]; }break; + //- rjf: fill set-data-breakpoint info + case DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT: + { + U64 vaddr = exception->ExceptionInformation[0]; + U64 size = exception->ExceptionInformation[1]; + U64 read = exception->ExceptionInformation[2]; + U64 write = exception->ExceptionInformation[3]; + U64 exec = exception->ExceptionInformation[4]; + U64 set = exception->ExceptionInformation[5]; + e->kind = set ? DMN_EventKind_SetBreakpoint : DMN_EventKind_UnsetBreakpoint; + e->address = vaddr; + e->size = size; + if(read) { e->flags |= DMN_TrapFlag_BreakOnRead; } + if(write) { e->flags |= DMN_TrapFlag_BreakOnWrite; } + if(exec) { e->flags |= DMN_TrapFlag_BreakOnExecute; } + }break; + //- rjf: unhandled exception case default: { diff --git a/src/demon/win32/demon_core_win32.h b/src/demon/win32/demon_core_win32.h index 24f527f2..05483e26 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -15,48 +15,49 @@ //////////////////////////////// //~ rjf: Win32 Exception Codes -#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u -#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u -#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u -#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u -#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu -#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u -#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u -#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du -#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu -#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu -#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u -#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u -#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u -#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u -#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u -#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u -#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u -#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du -#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u -#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u -#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u -#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu -#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u -#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u -#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u -#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u -#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u -#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u -#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au -#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u -#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u -#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u -#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u -#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u -#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u -#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u -#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u -#define DMN_W32_EXCEPTION_THROW 0xE06D7363u -#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u -#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u -#define DMN_w32_EXCEPTION_CLR 0xE0434352u -#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u +#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u +#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u +#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u +#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u +#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu +#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u +#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u +#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du +#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu +#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu +#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u +#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u +#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u +#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u +#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u +#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u +#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u +#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du +#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u +#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u +#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u +#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu +#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u +#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u +#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u +#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u +#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u +#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u +#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au +#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u +#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u +#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u +#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u +#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u +#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u +#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u +#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u +#define DMN_W32_EXCEPTION_THROW 0xE06D7363u +#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u +#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u +#define DMN_w32_EXCEPTION_CLR 0xE0434352u +#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u +#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u //////////////////////////////// //~ rjf: Win32 Register Codes diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index e153ab4d..09de9b30 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -16,29 +16,33 @@ //~ Usage Macros #if defined(RADDBG_MARKUP_STUBS) -# define raddbg_is_attached(...) (0) -# define raddbg_thread_name(fmt, ...) ((void)0) -# define raddbg_thread_color_hex(hexcode) ((void)0) -# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) -# define raddbg_break(...) ((void)0) -# define raddbg_break_if(expr, ...) ((void)expr) -# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_is_attached(...) (0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_color_hex(hexcode) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)expr) +# define raddbg_watch(fmt, ...) ((void)0) # define raddbg_pin(expr, ...) -# define raddbg_log(fmt, ...) ((void)0) -# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_auto_view_rule(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_auto_view_rule(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) +# define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) #else -# define raddbg_is_attached(...) raddbg_is_attached__impl() -# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) -# define raddbg_break(...) raddbg_break__impl() -# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) -# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) -# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ -# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") -# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_is_attached(...) raddbg_is_attached__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) +# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_break(...) raddbg_break__impl() +# define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) +# define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) +# define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ +# define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) +# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") +# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) +# define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) #endif //////////////////////////////// @@ -339,6 +343,43 @@ raddbg_log__impl(char *fmt, ...) OutputDebugStringA(buffer); } +static inline void +raddbg_add_or_remove_breakpoint__impl(void *ptr, int set, int size, int r, int w, int x) +{ + if(raddbg_is_attached()) + { +#pragma pack(push, 8) + typedef struct RADDBG_AddBreakpointInfo RADDBG_AddBreakpointInfo; + struct RADDBG_AddBreakpointInfo + { + unsigned __int64 vaddr; + unsigned __int64 size; + unsigned __int64 r; + unsigned __int64 w; + unsigned __int64 x; + unsigned __int64 add; + }; +#pragma pack(pop) + RADDBG_AddBreakpointInfo info; + info.vaddr = (unsigned __int64)ptr; + info.size = size; + info.r = r; + info.w = w; + info.x = x; + info.add = set; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(0x00524145u, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } +#pragma warning(pop) + } +} + #endif // defined(_WIN32) #endif // defined(RADDBG_MARKUP_IMPLEMENTATION) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 430d352d..21a07187 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1941,7 +1941,24 @@ fancy_viz_eval_tests(void) } //////////////////////////////// -// NOTE(allen): Function Overload Resolution +//~ rjf: Markup Tests + +static void +markup_tests(void) +{ + int x = 0; + raddbg_add_breakpoint(&x, sizeof(x), 0, 1, 0); + for(int i = 0; i < 10000; i += 1) + { + if(i == 5000) + { + x += 1; + } + } +} + +//////////////////////////////// +//~ NOTE(allen): Function Overload Resolution static int overloaded_function(float y){ @@ -2747,6 +2764,8 @@ mule_main(int argc, char** argv) fancy_viz_eval_tests(); + markup_tests(); + // NOTE(allen): Stepping Tests control_flow_stepping_tests(); From 8a857b2154871b711e9e4f646619d8b4f698877e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 15:32:27 -0700 Subject: [PATCH 359/755] use set/unset breakpoint events to build bp entities in ctrl entity tree --- src/ctrl/ctrl.mdesk | 3 +- src/ctrl/ctrl_core.c | 28 ++++++++++ src/ctrl/ctrl_core.h | 95 +++++++++++++++++----------------- src/ctrl/generated/ctrl.meta.c | 6 ++- src/ctrl/generated/ctrl.meta.h | 5 +- 5 files changed, 85 insertions(+), 52 deletions(-) diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index 98a97412..5665654d 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -14,7 +14,8 @@ CTRL_EntityKindTable: {Module module "Module" } {EntryPoint entry_point "Entry Point" } {DebugInfoPath debug_info_path "Debug Info Path" } - {PendingThreadName pending_thread_name "Pending Thread Name" } + {PendingThreadName pending_thread_name "Pending Thread Name" } + {Breakpoint breakpoint "Breakpoint" } } @enum CTRL_EntityKind: diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 5ae8b19f..7738a9ad 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1312,6 +1312,30 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) ctrl_entity_equip_string(store, debug_info_path, event->string); debug_info_path->timestamp = event->timestamp; }break; + + //- rjf: dynamic, program-created breakpoints + case CTRL_EventKind_SetBreakpoint: + { + CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *bp = ctrl_entity_alloc(store, process, CTRL_EntityKind_Breakpoint, Arch_Null, ctrl_handle_zero(), 0); + bp->vaddr_range = event->vaddr_rng; + bp->bp_flags = event->bp_flags; + }break; + case CTRL_EventKind_UnsetBreakpoint: + { + CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == CTRL_EntityKind_Breakpoint && + child->vaddr_range.min == event->vaddr_rng.min && + child->vaddr_range.max == event->vaddr_rng.max && + child->bp_flags == event->bp_flags) + { + ctrl_entity_release(store, child); + break; + } + } + }break; } } } @@ -4369,6 +4393,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); out_evt->kind = CTRL_EventKind_SetBreakpoint; + out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); + out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); }break; @@ -4376,6 +4402,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); out_evt->kind = CTRL_EventKind_UnsetBreakpoint; + out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); + out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); out_evt->vaddr_rng = r1u64(event->address, event->address+event->size); out_evt->bp_flags = ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags); }break; diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 3ded38c1..7edda053 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -12,6 +12,53 @@ typedef U64 CTRL_MachineID; #define CTRL_MachineID_Local (1) +//////////////////////////////// +//~ rjf: User Breakpoint Types + +typedef U32 CTRL_UserBreakpointFlags; +enum +{ + CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0), + CTRL_UserBreakpointFlag_BreakOnRead = (1<<1), + CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2), +}; + +typedef enum CTRL_UserBreakpointKind +{ + CTRL_UserBreakpointKind_Null, + CTRL_UserBreakpointKind_FileNameAndLineColNumber, + CTRL_UserBreakpointKind_Expression, + CTRL_UserBreakpointKind_COUNT +} +CTRL_UserBreakpointKind; + +typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint; +struct CTRL_UserBreakpoint +{ + CTRL_UserBreakpointKind kind; + CTRL_UserBreakpointFlags flags; + U64 id; + String8 string; + TxtPt pt; + U64 size; + String8 condition; +}; + +typedef struct CTRL_UserBreakpointNode CTRL_UserBreakpointNode; +struct CTRL_UserBreakpointNode +{ + CTRL_UserBreakpointNode *next; + CTRL_UserBreakpoint v; +}; + +typedef struct CTRL_UserBreakpointList CTRL_UserBreakpointList; +struct CTRL_UserBreakpointList +{ + CTRL_UserBreakpointNode *first; + CTRL_UserBreakpointNode *last; + U64 count; +}; + //////////////////////////////// //~ rjf: Entity Handle Types @@ -62,6 +109,7 @@ struct CTRL_Entity Rng1U64 vaddr_range; U64 stack_base; U64 timestamp; + CTRL_UserBreakpointFlags bp_flags; String8 string; }; @@ -256,53 +304,6 @@ struct CTRL_Spoof U64 new_ip_value; }; -//////////////////////////////// -//~ rjf: User Breakpoint Types - -typedef U32 CTRL_UserBreakpointFlags; -enum -{ - CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0), - CTRL_UserBreakpointFlag_BreakOnRead = (1<<1), - CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2), -}; - -typedef enum CTRL_UserBreakpointKind -{ - CTRL_UserBreakpointKind_Null, - CTRL_UserBreakpointKind_FileNameAndLineColNumber, - CTRL_UserBreakpointKind_Expression, - CTRL_UserBreakpointKind_COUNT -} -CTRL_UserBreakpointKind; - -typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint; -struct CTRL_UserBreakpoint -{ - CTRL_UserBreakpointKind kind; - CTRL_UserBreakpointFlags flags; - U64 id; - String8 string; - TxtPt pt; - U64 size; - String8 condition; -}; - -typedef struct CTRL_UserBreakpointNode CTRL_UserBreakpointNode; -struct CTRL_UserBreakpointNode -{ - CTRL_UserBreakpointNode *next; - CTRL_UserBreakpoint v; -}; - -typedef struct CTRL_UserBreakpointList CTRL_UserBreakpointList; -struct CTRL_UserBreakpointList -{ - CTRL_UserBreakpointNode *first; - CTRL_UserBreakpointNode *last; - U64 count; -}; - //////////////////////////////// //~ rjf: Evaluation Spaces diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 4b45ed27..87ed9c81 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 ctrl_entity_kind_code_name_table[9] = +String8 ctrl_entity_kind_code_name_table[10] = { {0}, str8_lit_comp("root"), @@ -15,9 +15,10 @@ str8_lit_comp("module"), str8_lit_comp("entry_point"), str8_lit_comp("debug_info_path"), str8_lit_comp("pending_thread_name"), +str8_lit_comp("breakpoint"), }; -String8 ctrl_entity_kind_display_string_table[9] = +String8 ctrl_entity_kind_display_string_table[10] = { {0}, str8_lit_comp("Root"), @@ -28,6 +29,7 @@ str8_lit_comp("Module"), str8_lit_comp("EntryPoint"), str8_lit_comp("DebugInfoPath"), str8_lit_comp("PendingThreadName"), +str8_lit_comp("Breakpoint"), }; U32 ctrl_exception_code_kind_code_table[38] = diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 8c5e9a3a..14dfc6a8 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -17,6 +17,7 @@ CTRL_EntityKind_Module, CTRL_EntityKind_EntryPoint, CTRL_EntityKind_DebugInfoPath, CTRL_EntityKind_PendingThreadName, +CTRL_EntityKind_Breakpoint, CTRL_EntityKind_COUNT, } CTRL_EntityKind; @@ -64,8 +65,8 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN -extern String8 ctrl_entity_kind_code_name_table[9]; -extern String8 ctrl_entity_kind_display_string_table[9]; +extern String8 ctrl_entity_kind_code_name_table[10]; +extern String8 ctrl_entity_kind_display_string_table[10]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38]; From 7c668388ebd47ab76af7bb943bb3044f47382535 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 12 Apr 2025 19:38:07 -0700 Subject: [PATCH 360/755] hook up programmatic breakpoint state to trap list --- src/ctrl/ctrl_core.c | 57 +++++++++++++++++++++++++++++++++++++++--- src/ctrl/ctrl_core.h | 1 + src/mule/mule_main.cpp | 1 + 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 7738a9ad..117d86de 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3640,6 +3640,21 @@ ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope } } +internal void +ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_TrapChunkList *traps_out) +{ + CTRL_Entity *process = bp->parent; + DMN_Trap trap = + { + .process = process->handle.dmn_handle, + .vaddr = bp->vaddr_range.min, + .id = ((U64)bp|bit64), + .flags = ctrl_dmn_trap_flags_from_user_breakpoint_flags(bp->bp_flags), + .size = (U32)dim_1u64(bp->vaddr_range), + }; + dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); +} + //- rjf: module lifetime open/close work internal void @@ -5153,6 +5168,13 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, process->handle, module->handle, &msg->user_bps, &user_traps); } + // rjf: push process-declared breakpoins + for(CTRL_Entity *bp = process->first; bp != &ctrl_entity_nil; bp = bp->next) + { + if(bp->kind != CTRL_EntityKind_Breakpoint) { continue; } + ctrl_thread__append_program_defined_bp_traps(scratch.arena, bp, &user_traps); + } + // rjf: push virtual-address user breakpoints per-process ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, process->handle, &msg->user_bps, &user_traps); } @@ -5464,6 +5486,31 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } ctrl_thread__eval_scope_end(eval_scope); }break; + case DMN_EventKind_SetBreakpoint: + { + CTRL_Entity *bp = &ctrl_entity_nil; + { + CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) + { + if(child->kind == CTRL_EntityKind_Breakpoint && + child->vaddr_range.min == event->address && + child->vaddr_range.max == event->address + event->size && + child->bp_flags == ctrl_user_breakpoint_flags_from_dmn_trap_flags(event->flags)) + { + bp = child; + break; + } + } + } + if(bp != &ctrl_entity_nil) + { + DMN_TrapChunkList new_traps = {0}; + ctrl_thread__append_program_defined_bp_traps(scratch.arena, bp, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps); + dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps); + } + }break; } ////////////////////////// @@ -5790,7 +5837,6 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { if(event->user_data != 0) { - CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)event->user_data; hit_user_bp = 1; } for(DMN_TrapChunkNode *n = user_traps.first; n != 0; n = n->next) @@ -5805,7 +5851,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)trap->id; hit_user_bp = 1; - if(user_bp != 0 && user_bp->condition.size != 0) + if(user_bp != 0 && !(trap->id & bit64) && user_bp->condition.size != 0) { str8_list_push(temp.arena, &conditions, user_bp->condition); } @@ -6155,8 +6201,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) event->rip_vaddr = stop_event->instruction_pointer; if(stop_cause == CTRL_EventCause_UserBreakpoint && stop_event->user_data != 0) { - CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)stop_event->user_data; - event->u64_code = user_bp->id; + if(!(stop_event->user_data & bit64)) + { + CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)stop_event->user_data; + event->u64_code = user_bp->id; + } } ctrl_c2u_push_events(&evts); } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 7edda053..85d80ac3 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -968,6 +968,7 @@ internal void ctrl_thread__entry_point(void *p); //- rjf: breakpoint resolution internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_TrapChunkList *traps_out); //- rjf: module lifetime open/close work internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 21a07187..cf532a54 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1955,6 +1955,7 @@ markup_tests(void) x += 1; } } + raddbg_remove_breakpoint(&x, sizeof(x), 0, 1, 0); } //////////////////////////////// From b98f2b153ed31d513d02b472e60e067ab99239ee Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 13 Apr 2025 16:45:27 -0700 Subject: [PATCH 361/755] fix call expr stringification --- src/eval/eval.mdesk | 100 ++++++++++++++++----------------- src/eval/eval_core.h | 1 + src/eval/eval_parse.c | 15 ++--- src/eval/generated/eval.meta.c | 96 +++++++++++++++---------------- 4 files changed, 105 insertions(+), 107 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 36fc7a34..e943b21d 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -76,66 +76,66 @@ E_TypeKindTable: {LensSpec "lens_spec" 0 } } -@table(name op_kind precedence op_pre op_sep op_pos) +@table(name op_kind precedence op_pre op_sep op_pos op_chain) E_ExprKindTable: { - { Nil Null 0 "" "" "" } - { Ref Null 0 "" "" "" } + { Nil Null 0 "" "" "" "" } + { Ref Null 0 "" "" "" "" } - { ArrayIndex Null 0 "" "[" "]"} - { MemberAccess Null 0 "" "." "" } - { Deref UnaryPrefix 2 "*" "" "" } - { Address UnaryPrefix 2 "&" "" "" } + { ArrayIndex Null 0 "" "[" "]" "" } + { MemberAccess Null 0 "" "." "" "" } + { Deref UnaryPrefix 2 "*" "" "" "" } + { Address UnaryPrefix 2 "&" "" "" "" } - { Cast Null 1 "(" ")" "" } - { Sizeof UnaryPrefix 1 "sizeof" "(" ")"} - { Typeof UnaryPrefix 1 "typeof" "(" ")"} - { ByteSwap UnaryPrefix 1 "bswap" "(" ")"} + { Cast Null 1 "(" ")" "" "" } + { Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" } + { Typeof UnaryPrefix 1 "typeof" "(" ")" "" } + { ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" } - { Pos UnaryPrefix 2 "+" "" "" } - { Neg UnaryPrefix 2 "-" "" "" } - { LogNot UnaryPrefix 2 "!" "" "" } - { BitNot UnaryPrefix 2 "~" "" "" } - { Mul Binary 3 "" "*" "" } - { Div Binary 3 "" "/" "" } - { Mod Binary 3 "" "%" "" } - { Add Binary 4 "" "+" "" } - { Sub Binary 4 "" "-" "" } - { LShift Binary 5 "" "<<" "" } - { RShift Binary 5 "" ">>" "" } - { Less Binary 6 "" "<" "" } - { LsEq Binary 6 "" "<=" "" } - { Grtr Binary 6 "" ">" "" } - { GrEq Binary 6 "" ">=" "" } - { EqEq Binary 7 "" "==" "" } - { NtEq Binary 7 "" "!=" "" } + { Pos UnaryPrefix 2 "+" "" "" "" } + { Neg UnaryPrefix 2 "-" "" "" "" } + { LogNot UnaryPrefix 2 "!" "" "" "" } + { BitNot UnaryPrefix 2 "~" "" "" "" } + { Mul Binary 3 "" " * " "" "" } + { Div Binary 3 "" " / " "" "" } + { Mod Binary 3 "" " % " "" "" } + { Add Binary 4 "" " + " "" "" } + { Sub Binary 4 "" " - " "" "" } + { LShift Binary 5 "" " << " "" "" } + { RShift Binary 5 "" " >> " "" "" } + { Less Binary 6 "" " < " "" "" } + { LsEq Binary 6 "" " <= " "" "" } + { Grtr Binary 6 "" " > " "" "" } + { GrEq Binary 6 "" " >= " "" "" } + { EqEq Binary 7 "" " == " "" "" } + { NtEq Binary 7 "" " != " "" "" } - { BitAnd Binary 8 "" "&" "" } - { BitXor Binary 9 "" "^" "" } - { BitOr Binary 10 "" "|" "" } - { LogAnd Binary 11 "" "&&" "" } - { LogOr Binary 12 "" "||" "" } + { BitAnd Binary 8 "" " & " "" "" } + { BitXor Binary 9 "" " ^ " "" "" } + { BitOr Binary 10 "" " | " "" "" } + { LogAnd Binary 11 "" " && " "" "" } + { LogOr Binary 12 "" " || " "" "" } - { Ternary Null 0 "" "?" ":"} + { Ternary Null 0 "" " ? " " : " "" } - { Call Null 0 "(" "," ")"} + { Call Null 15 "" "(" ")" ", "} - { LeafBytecode Null 0 "" "" "" } - { LeafStringLiteral Null 0 "" "" "" } - { LeafU64 Null 0 "" "" "" } - { LeafF64 Null 0 "" "" "" } - { LeafF32 Null 0 "" "" "" } - { LeafIdentifier Null 0 "" "" "" } - { LeafOffset Null 0 "" "" "" } - { LeafValue Null 0 "" "" "" } - { LeafFilePath Null 0 "" "" "" } + { LeafBytecode Null 0 "" "" "" "" } + { LeafStringLiteral Null 0 "" "" "" "" } + { LeafU64 Null 0 "" "" "" "" } + { LeafF64 Null 0 "" "" "" "" } + { LeafF32 Null 0 "" "" "" "" } + { LeafIdentifier Null 0 "" "" "" "" } + { LeafOffset Null 0 "" "" "" "" } + { LeafValue Null 0 "" "" "" "" } + { LeafFilePath Null 0 "" "" "" "" } - { TypeIdent Null 0 "" "" "" } - { Ptr Null 0 "" "" "" } - { Array Null 0 "" "" "" } - { Func Null 0 "" "" "" } + { TypeIdent Null 0 "" "" "" "" } + { Ptr Null 0 "" "" "" "" } + { Array Null 0 "" "" "" "" } + { Func Null 0 "" "" "" "" } - { Define Binary 13 "" "=" "" } + { Define Binary 13 "" " = " "" "" } } @table(name display_string) @@ -206,7 +206,7 @@ e_expr_kind_strings: @data(E_OpInfo) e_expr_kind_op_info_table: { - @expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_pos)") }` + @expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_pos)"), str8_lit_comp("$(a.op_chain)") }` } @enum E_InterpretationCode: diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 869f02c7..483a9409 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -74,6 +74,7 @@ struct E_OpInfo String8 pre; String8 sep; String8 post; + String8 chain; }; //////////////////////////////// diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 9296befb..675c5cbe 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -485,16 +485,13 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) U64 sep_idx = 0; for(E_Expr *child = expr->first;; child = child->next) { - if(seps[sep_idx].size != 0) + if(sep_idx == ArrayCount(seps)-1 && child != &e_expr_nil) { - if(sep_idx == 1 && child == &e_expr_nil) - { - sep_idx += 1; - } - str8_list_push(arena, out, seps[sep_idx]); + str8_list_push(arena, out, op_info->chain); } - if(sep_idx == 0) + else { + str8_list_push(arena, out, seps[sep_idx]); sep_idx += 1; } if(child == &e_expr_nil) @@ -914,7 +911,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok for EachNonZeroEnumVal(E_ExprKind, k) { E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0)) + if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(str8_skip_chop_whitespace(op_info->pre), token_string, 0)) { prefix_unary_precedence = op_info->precedence; prefix_unary_kind = k; @@ -1376,7 +1373,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok for EachNonZeroEnumVal(E_ExprKind, k) { E_OpInfo *op_info = &e_expr_kind_op_info_table[k]; - if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0)) + if(op_info->kind == E_OpKind_Binary && str8_match(str8_skip_chop_whitespace(op_info->sep), token_string, 0)) { binary_precedence = op_info->precedence; binary_kind = k; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 1973dbf0..6febd96e 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -192,54 +192,54 @@ str8_lit_comp("Define"), E_OpInfo e_expr_kind_op_info_table[48] = { -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp("") }, -{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp("") }, -{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp("") }, -{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp("") }, -{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp("") }, -{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp("") }, -{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp("") }, -{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp("") }, -{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp("") }, -{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp("") }, -{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp("") }, -{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp("") }, -{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") }, -{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") }, -{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]"), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" * "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" / "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" % "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp(" + "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp(" - "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(" << "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(" >> "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" < "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" <= "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" > "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" >= "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp(" == "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp(" != "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp(" & "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp(" ^ "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp(" | "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp(" && "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp(" || "), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(" ? "), str8_lit_comp(" : "), str8_lit_comp("") }, +{ E_OpKind_Null, 15, str8_lit_comp(""), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(", ") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp(" = "), str8_lit_comp(""), str8_lit_comp("") }, }; String8 e_interpretation_code_display_strings[11] = From 550950ed461cf66054caf4a2d160aa11981f83ce Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 10:49:36 -0700 Subject: [PATCH 362/755] ui min sizes, fixes to slider viz --- src/raddbg/raddbg_widgets.c | 12 +++++++----- src/ui/generated/ui.meta.c | 12 ++++++++++++ src/ui/generated/ui.meta.h | 22 ++++++++++++++++++++++ src/ui/ui.mdesk | 2 ++ src/ui/ui_core.c | 9 ++++++++- src/ui/ui_core.h | 3 +++ 6 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ba89a4d7..4015fe06 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3294,6 +3294,8 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) { + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; ui_set_next_hover_cursor(OS_Cursor_LeftRight); UI_Box *slider_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "slider"); UI_Parent(slider_box) UI_TagF("good_pop") @@ -3305,28 +3307,28 @@ rd_cell(RD_CellParams *params, String8 string) { ui_store_drag_struct(params->slider_value_out); } + F32 draggable_region_size_px = dim_2f32(slider_box->rect).x; F32 initial_pct = *ui_get_drag_struct(F32); - F32 current_pct = initial_pct + (ui_drag_delta().x / dim_2f32(slider_box->rect).x); + F32 current_pct = initial_pct + (ui_drag_delta().x / draggable_region_size_px); params->slider_value_out[0] = current_pct; } UI_Box *fill_box = &ui_nil_box; UI_PrefWidth(ui_pct(Clamp(0, params->slider_value_out[0], 1), 0.f)) + UI_MinWidth(toggler_size_px + extratoggler_padding_px*2) fill_box = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); UI_Parent(fill_box) { + ui_spacer(ui_pct(1, 0)); UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) UI_PrefWidth(ui_px(height_px, 1.f)) { - ui_spacer(ui_pct(1.f, 0.f)); - F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); - F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) UI_PrefWidth(ui_px(toggler_size_px, 1.f)) UI_PrefHeight(ui_px(toggler_size_px, 1.f)) UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) { - UI_Box *nub = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); } } } diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index 4748e2a6..f66c6b76 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -12,6 +12,8 @@ #define UI_FixedHeight(v) DeferLoop(ui_push_fixed_height(v), ui_pop_fixed_height()) #define UI_PrefWidth(v) DeferLoop(ui_push_pref_width(v), ui_pop_pref_width()) #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) +#define UI_MinWidth(v) DeferLoop(ui_push_min_width(v), ui_pop_min_width()) +#define UI_MinHeight(v) DeferLoop(ui_push_min_height(v), ui_pop_min_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) #define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) @@ -45,6 +47,8 @@ internal F32 ui_top_fixed_width(void) { UI_StackTopImpl(ui_state, FixedWidth, fi internal F32 ui_top_fixed_height(void) { UI_StackTopImpl(ui_state, FixedHeight, fixed_height) } internal UI_Size ui_top_pref_width(void) { UI_StackTopImpl(ui_state, PrefWidth, pref_width) } internal UI_Size ui_top_pref_height(void) { UI_StackTopImpl(ui_state, PrefHeight, pref_height) } +internal F32 ui_top_min_width(void) { UI_StackTopImpl(ui_state, MinWidth, min_width) } +internal F32 ui_top_min_height(void) { UI_StackTopImpl(ui_state, MinHeight, min_height) } internal UI_PermissionFlags ui_top_permission_flags(void) { UI_StackTopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_top_flags(void) { UI_StackTopImpl(ui_state, Flags, flags) } internal UI_BoxFlags ui_top_omit_flags(void) { UI_StackTopImpl(ui_state, OmitFlags, omit_flags) } @@ -76,6 +80,8 @@ internal F32 ui_bottom_fixed_width(void) { UI_StackBottomImpl(ui_state, FixedWid internal F32 ui_bottom_fixed_height(void) { UI_StackBottomImpl(ui_state, FixedHeight, fixed_height) } internal UI_Size ui_bottom_pref_width(void) { UI_StackBottomImpl(ui_state, PrefWidth, pref_width) } internal UI_Size ui_bottom_pref_height(void) { UI_StackBottomImpl(ui_state, PrefHeight, pref_height) } +internal F32 ui_bottom_min_width(void) { UI_StackBottomImpl(ui_state, MinWidth, min_width) } +internal F32 ui_bottom_min_height(void) { UI_StackBottomImpl(ui_state, MinHeight, min_height) } internal UI_PermissionFlags ui_bottom_permission_flags(void) { UI_StackBottomImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_bottom_flags(void) { UI_StackBottomImpl(ui_state, Flags, flags) } internal UI_BoxFlags ui_bottom_omit_flags(void) { UI_StackBottomImpl(ui_state, OmitFlags, omit_flags) } @@ -107,6 +113,8 @@ internal F32 ui_push_fixed_width(F32 v) { UI_StackPushImpl(ui_state, FixedWidth, internal F32 ui_push_fixed_height(F32 v) { UI_StackPushImpl(ui_state, FixedHeight, fixed_height, F32, v) } internal UI_Size ui_push_pref_width(UI_Size v) { UI_StackPushImpl(ui_state, PrefWidth, pref_width, UI_Size, v) } internal UI_Size ui_push_pref_height(UI_Size v) { UI_StackPushImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } +internal F32 ui_push_min_width(F32 v) { UI_StackPushImpl(ui_state, MinWidth, min_width, F32, v) } +internal F32 ui_push_min_height(F32 v) { UI_StackPushImpl(ui_state, MinHeight, min_height, F32, v) } internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v) { UI_StackPushImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_push_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, Flags, flags, UI_BoxFlags, v) } internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v) { UI_StackPushImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } @@ -138,6 +146,8 @@ internal F32 ui_pop_fixed_width(void) { UI_StackPopImpl(ui_state, FixedWidth, fi internal F32 ui_pop_fixed_height(void) { UI_StackPopImpl(ui_state, FixedHeight, fixed_height) } internal UI_Size ui_pop_pref_width(void) { UI_StackPopImpl(ui_state, PrefWidth, pref_width) } internal UI_Size ui_pop_pref_height(void) { UI_StackPopImpl(ui_state, PrefHeight, pref_height) } +internal F32 ui_pop_min_width(void) { UI_StackPopImpl(ui_state, MinWidth, min_width) } +internal F32 ui_pop_min_height(void) { UI_StackPopImpl(ui_state, MinHeight, min_height) } internal UI_PermissionFlags ui_pop_permission_flags(void) { UI_StackPopImpl(ui_state, PermissionFlags, permission_flags) } internal UI_BoxFlags ui_pop_flags(void) { UI_StackPopImpl(ui_state, Flags, flags) } internal UI_BoxFlags ui_pop_omit_flags(void) { UI_StackPopImpl(ui_state, OmitFlags, omit_flags) } @@ -169,6 +179,8 @@ internal F32 ui_set_next_fixed_width(F32 v) { UI_StackSetNextImpl(ui_state, Fixe internal F32 ui_set_next_fixed_height(F32 v) { UI_StackSetNextImpl(ui_state, FixedHeight, fixed_height, F32, v) } internal UI_Size ui_set_next_pref_width(UI_Size v) { UI_StackSetNextImpl(ui_state, PrefWidth, pref_width, UI_Size, v) } internal UI_Size ui_set_next_pref_height(UI_Size v) { UI_StackSetNextImpl(ui_state, PrefHeight, pref_height, UI_Size, v) } +internal F32 ui_set_next_min_width(F32 v) { UI_StackSetNextImpl(ui_state, MinWidth, min_width, F32, v) } +internal F32 ui_set_next_min_height(F32 v) { UI_StackSetNextImpl(ui_state, MinHeight, min_height, F32, v) } internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v) { UI_StackSetNextImpl(ui_state, PermissionFlags, permission_flags, UI_PermissionFlags, v) } internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, Flags, flags, UI_BoxFlags, v) } internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v) { UI_StackSetNextImpl(ui_state, OmitFlags, omit_flags, UI_BoxFlags, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index 3148b82e..2b666b2a 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -14,6 +14,8 @@ typedef struct UI_FixedWidthNode UI_FixedWidthNode; struct UI_FixedWidthNode{UI_ typedef struct UI_FixedHeightNode UI_FixedHeightNode; struct UI_FixedHeightNode{UI_FixedHeightNode *next; F32 v;}; typedef struct UI_PrefWidthNode UI_PrefWidthNode; struct UI_PrefWidthNode{UI_PrefWidthNode *next; UI_Size v;}; typedef struct UI_PrefHeightNode UI_PrefHeightNode; struct UI_PrefHeightNode{UI_PrefHeightNode *next; UI_Size v;}; +typedef struct UI_MinWidthNode UI_MinWidthNode; struct UI_MinWidthNode{UI_MinWidthNode *next; F32 v;}; +typedef struct UI_MinHeightNode UI_MinHeightNode; struct UI_MinHeightNode{UI_MinHeightNode *next; F32 v;}; typedef struct UI_PermissionFlagsNode UI_PermissionFlagsNode; struct UI_PermissionFlagsNode{UI_PermissionFlagsNode *next; UI_PermissionFlags v;}; typedef struct UI_FlagsNode UI_FlagsNode; struct UI_FlagsNode{UI_FlagsNode *next; UI_BoxFlags v;}; typedef struct UI_OmitFlagsNode UI_OmitFlagsNode; struct UI_OmitFlagsNode{UI_OmitFlagsNode *next; UI_BoxFlags v;}; @@ -49,6 +51,8 @@ UI_FixedWidthNode fixed_width_nil_stack_top;\ UI_FixedHeightNode fixed_height_nil_stack_top;\ UI_PrefWidthNode pref_width_nil_stack_top;\ UI_PrefHeightNode pref_height_nil_stack_top;\ +UI_MinWidthNode min_width_nil_stack_top;\ +UI_MinHeightNode min_height_nil_stack_top;\ UI_PermissionFlagsNode permission_flags_nil_stack_top;\ UI_FlagsNode flags_nil_stack_top;\ UI_OmitFlagsNode omit_flags_nil_stack_top;\ @@ -83,6 +87,8 @@ state->fixed_width_nil_stack_top.v = 0;\ state->fixed_height_nil_stack_top.v = 0;\ state->pref_width_nil_stack_top.v = ui_px(250.f, 1.f);\ state->pref_height_nil_stack_top.v = ui_px(30.f, 1.f);\ +state->min_width_nil_stack_top.v = 0;\ +state->min_height_nil_stack_top.v = 0;\ state->permission_flags_nil_stack_top.v = UI_PermissionFlag_All;\ state->flags_nil_stack_top.v = 0;\ state->omit_flags_nil_stack_top.v = 0;\ @@ -119,6 +125,8 @@ struct { UI_FixedWidthNode *top; F32 bottom_val; UI_FixedWidthNode *free; U64 ge struct { UI_FixedHeightNode *top; F32 bottom_val; UI_FixedHeightNode *free; U64 gen; B32 auto_pop; } fixed_height_stack;\ struct { UI_PrefWidthNode *top; UI_Size bottom_val; UI_PrefWidthNode *free; U64 gen; B32 auto_pop; } pref_width_stack;\ struct { UI_PrefHeightNode *top; UI_Size bottom_val; UI_PrefHeightNode *free; U64 gen; B32 auto_pop; } pref_height_stack;\ +struct { UI_MinWidthNode *top; F32 bottom_val; UI_MinWidthNode *free; U64 gen; B32 auto_pop; } min_width_stack;\ +struct { UI_MinHeightNode *top; F32 bottom_val; UI_MinHeightNode *free; U64 gen; B32 auto_pop; } min_height_stack;\ struct { UI_PermissionFlagsNode *top; UI_PermissionFlags bottom_val; UI_PermissionFlagsNode *free; U64 gen; B32 auto_pop; } permission_flags_stack;\ struct { UI_FlagsNode *top; UI_BoxFlags bottom_val; UI_FlagsNode *free; U64 gen; B32 auto_pop; } flags_stack;\ struct { UI_OmitFlagsNode *top; UI_BoxFlags bottom_val; UI_OmitFlagsNode *free; U64 gen; B32 auto_pop; } omit_flags_stack;\ @@ -153,6 +161,8 @@ state->fixed_width_stack.top = &state->fixed_width_nil_stack_top; state->fixed_w state->fixed_height_stack.top = &state->fixed_height_nil_stack_top; state->fixed_height_stack.bottom_val = 0; state->fixed_height_stack.free = 0; state->fixed_height_stack.auto_pop = 0;\ state->pref_width_stack.top = &state->pref_width_nil_stack_top; state->pref_width_stack.bottom_val = ui_px(250.f, 1.f); state->pref_width_stack.free = 0; state->pref_width_stack.auto_pop = 0;\ state->pref_height_stack.top = &state->pref_height_nil_stack_top; state->pref_height_stack.bottom_val = ui_px(30.f, 1.f); state->pref_height_stack.free = 0; state->pref_height_stack.auto_pop = 0;\ +state->min_width_stack.top = &state->min_width_nil_stack_top; state->min_width_stack.bottom_val = 0; state->min_width_stack.free = 0; state->min_width_stack.auto_pop = 0;\ +state->min_height_stack.top = &state->min_height_nil_stack_top; state->min_height_stack.bottom_val = 0; state->min_height_stack.free = 0; state->min_height_stack.auto_pop = 0;\ state->permission_flags_stack.top = &state->permission_flags_nil_stack_top; state->permission_flags_stack.bottom_val = UI_PermissionFlag_All; state->permission_flags_stack.free = 0; state->permission_flags_stack.auto_pop = 0;\ state->flags_stack.top = &state->flags_nil_stack_top; state->flags_stack.bottom_val = 0; state->flags_stack.free = 0; state->flags_stack.auto_pop = 0;\ state->omit_flags_stack.top = &state->omit_flags_nil_stack_top; state->omit_flags_stack.bottom_val = 0; state->omit_flags_stack.free = 0; state->omit_flags_stack.auto_pop = 0;\ @@ -187,6 +197,8 @@ if(state->fixed_width_stack.auto_pop) { ui_pop_fixed_width(); state->fixed_width if(state->fixed_height_stack.auto_pop) { ui_pop_fixed_height(); state->fixed_height_stack.auto_pop = 0; }\ if(state->pref_width_stack.auto_pop) { ui_pop_pref_width(); state->pref_width_stack.auto_pop = 0; }\ if(state->pref_height_stack.auto_pop) { ui_pop_pref_height(); state->pref_height_stack.auto_pop = 0; }\ +if(state->min_width_stack.auto_pop) { ui_pop_min_width(); state->min_width_stack.auto_pop = 0; }\ +if(state->min_height_stack.auto_pop) { ui_pop_min_height(); state->min_height_stack.auto_pop = 0; }\ if(state->permission_flags_stack.auto_pop) { ui_pop_permission_flags(); state->permission_flags_stack.auto_pop = 0; }\ if(state->flags_stack.auto_pop) { ui_pop_flags(); state->flags_stack.auto_pop = 0; }\ if(state->omit_flags_stack.auto_pop) { ui_pop_omit_flags(); state->omit_flags_stack.auto_pop = 0; }\ @@ -220,6 +232,8 @@ internal F32 ui_top_fixed_width(void); internal F32 ui_top_fixed_height(void); internal UI_Size ui_top_pref_width(void); internal UI_Size ui_top_pref_height(void); +internal F32 ui_top_min_width(void); +internal F32 ui_top_min_height(void); internal UI_PermissionFlags ui_top_permission_flags(void); internal UI_BoxFlags ui_top_flags(void); internal UI_BoxFlags ui_top_omit_flags(void); @@ -252,6 +266,8 @@ internal F32 ui_bottom_fixed_width(void); internal F32 ui_bottom_fixed_height(void); internal UI_Size ui_bottom_pref_width(void); internal UI_Size ui_bottom_pref_height(void); +internal F32 ui_bottom_min_width(void); +internal F32 ui_bottom_min_height(void); internal UI_PermissionFlags ui_bottom_permission_flags(void); internal UI_BoxFlags ui_bottom_flags(void); internal UI_BoxFlags ui_bottom_omit_flags(void); @@ -284,6 +300,8 @@ internal F32 ui_push_fixed_width(F32 v); internal F32 ui_push_fixed_height(F32 v); internal UI_Size ui_push_pref_width(UI_Size v); internal UI_Size ui_push_pref_height(UI_Size v); +internal F32 ui_push_min_width(F32 v); +internal F32 ui_push_min_height(F32 v); internal UI_PermissionFlags ui_push_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_push_flags(UI_BoxFlags v); internal UI_BoxFlags ui_push_omit_flags(UI_BoxFlags v); @@ -316,6 +334,8 @@ internal F32 ui_pop_fixed_width(void); internal F32 ui_pop_fixed_height(void); internal UI_Size ui_pop_pref_width(void); internal UI_Size ui_pop_pref_height(void); +internal F32 ui_pop_min_width(void); +internal F32 ui_pop_min_height(void); internal UI_PermissionFlags ui_pop_permission_flags(void); internal UI_BoxFlags ui_pop_flags(void); internal UI_BoxFlags ui_pop_omit_flags(void); @@ -348,6 +368,8 @@ internal F32 ui_set_next_fixed_width(F32 v); internal F32 ui_set_next_fixed_height(F32 v); internal UI_Size ui_set_next_pref_width(UI_Size v); internal UI_Size ui_set_next_pref_height(UI_Size v); +internal F32 ui_set_next_min_width(F32 v); +internal F32 ui_set_next_min_height(F32 v); internal UI_PermissionFlags ui_set_next_permission_flags(UI_PermissionFlags v); internal UI_BoxFlags ui_set_next_flags(UI_BoxFlags v); internal UI_BoxFlags ui_set_next_omit_flags(UI_BoxFlags v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index b5945493..cbe35c8a 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -19,6 +19,8 @@ UI_StackTable: { FixedHeight fixed_height F32 0 } { PrefWidth pref_width UI_Size `ui_px(250.f, 1.f)` } { PrefHeight pref_height UI_Size `ui_px(30.f, 1.f)` } + { MinWidth min_width F32 0 } + { MinHeight min_height F32 0 } //- rjf: flags { PermissionFlags permission_flags UI_PermissionFlags UI_PermissionFlag_All } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 8bf53e7b..a4f1df81 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1757,7 +1757,6 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis) } } } - } //- rjf: fixup children sizes (in the direction of the layout axis) @@ -1825,6 +1824,12 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis) } } + //- rjf: enforce clamps + for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + { + child->fixed_size.v[axis] = Max(child->fixed_size.v[axis], child->min_size.v[axis]); + } + //- rjf: recurse for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) { @@ -2424,6 +2429,8 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) { box->pref_size[Axis2_Y] = ui_state->pref_height_stack.top->v; } + box->min_size.v[Axis2_X] = ui_state->min_width_stack.top->v; + box->min_size.v[Axis2_Y] = ui_state->min_height_stack.top->v; B32 is_auto_focus_active = ui_is_key_auto_focus_active(key); B32 is_auto_focus_hot = ui_is_key_auto_focus_hot(key); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 579c8051..49c14597 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -390,6 +390,7 @@ struct UI_Box UI_TextAlign text_align; Vec2F32 fixed_position; Vec2F32 fixed_size; + Vec2F32 min_size; UI_Size pref_size[Axis2_COUNT]; Axis2 child_layout_axis; OS_Cursor hover_cursor; @@ -1129,6 +1130,8 @@ internal F32 ui_top_px_height(void); #define UI_FixedHeight(v) DeferLoop(ui_push_fixed_height(v), ui_pop_fixed_height()) #define UI_PrefWidth(v) DeferLoop(ui_push_pref_width(v), ui_pop_pref_width()) #define UI_PrefHeight(v) DeferLoop(ui_push_pref_height(v), ui_pop_pref_height()) +#define UI_MinWidth(v) DeferLoop(ui_push_min_width(v), ui_pop_min_width()) +#define UI_MinHeight(v) DeferLoop(ui_push_min_height(v), ui_pop_min_height()) #define UI_PermissionFlags(v) DeferLoop(ui_push_permission_flags(v), ui_pop_permission_flags()) #define UI_Flags(v) DeferLoop(ui_push_flags(v), ui_pop_flags()) #define UI_OmitFlags(v) DeferLoop(ui_push_omit_flags(v), ui_pop_omit_flags()) From 70c003607d80bf3645ab114ed52f52aaacfaa156 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 10:55:33 -0700 Subject: [PATCH 363/755] further fixes to slider viz --- src/raddbg/raddbg_widgets.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 4015fe06..e849459d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3298,7 +3298,7 @@ rd_cell(RD_CellParams *params, String8 string) F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; ui_set_next_hover_cursor(OS_Cursor_LeftRight); UI_Box *slider_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "slider"); - UI_Parent(slider_box) UI_TagF("good_pop") + UI_Parent(slider_box) UI_TagF("pop") { UI_Signal sig = ui_signal_from_box(slider_box); if(ui_dragging(sig)) @@ -3307,18 +3307,19 @@ rd_cell(RD_CellParams *params, String8 string) { ui_store_drag_struct(params->slider_value_out); } - F32 draggable_region_size_px = dim_2f32(slider_box->rect).x; + F32 draggable_region_size_px = dim_2f32(slider_box->rect).x - (extratoggler_padding_px*2 + toggler_size_px); F32 initial_pct = *ui_get_drag_struct(F32); F32 current_pct = initial_pct + (ui_drag_delta().x / draggable_region_size_px); params->slider_value_out[0] = current_pct; } + UI_Box *fill_box = &ui_nil_box; - UI_PrefWidth(ui_pct(Clamp(0, params->slider_value_out[0], 1), 0.f)) + UI_PrefWidth(ui_children_sum(0)) UI_MinWidth(toggler_size_px + extratoggler_padding_px*2) fill_box = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); UI_Parent(fill_box) { - ui_spacer(ui_pct(1, 0)); + ui_spacer(ui_pct(Clamp(0, params->slider_value_out[0], 1), 0.f)); UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) UI_PrefWidth(ui_px(height_px, 1.f)) { @@ -3332,6 +3333,7 @@ rd_cell(RD_CellParams *params, String8 string) } } } + ui_spacer(ui_pct(1-Clamp(0, params->slider_value_out[0], 1), 0.f)); } } } From ee0c1b25c3b57df317b8219d144862fc05f646a1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 11:07:18 -0700 Subject: [PATCH 364/755] eval ir generation: adjust autohook-allowance to be a stack, and correctly disable it for all sub-evaluations when using a `raw` lens, such that autohooks do not apply for evaluation of the parameter (e.g. raw(foo) -> foo, without allowing mapping of `foo` to something else) --- src/eval/eval_ir.c | 43 ++++++++++++++++++++++++++++++------------- src/eval/eval_ir.h | 1 + 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index b47d4559..4eca77d5 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -901,6 +901,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_IRTreeAndType *prev; }; E_IRTreeAndType *start_prev = e_ir_state->overridden_irtree; + B32 start_disallow_autohooks = e_ir_state->disallow_autohooks; Task start_task = {0, root_expr, e_ir_state->overridden_irtree}; Task *first_task = &start_task; Task *last_task = first_task; @@ -922,7 +923,6 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { expr = expr->ref; } - B32 allow_autohooks = 1; E_ExprKind kind = expr->kind; switch(kind) { @@ -1592,11 +1592,19 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } result = e_irtree_and_type_from_expr(arena, call); - // rjf: is "raw"? -> strip all lens types from result; disallow auto-hooks + // rjf: is "raw"? -> try to return overridden tree, otherwise strip all + // lens types from result; disallow auto-hooks if(str8_match(callee->string, str8_lit("raw"), 0)) { - result.type_key = e_type_unwrap(result.type_key); - allow_autohooks = 0; + e_ir_state->disallow_autohooks = 1; + if(e_ir_state->overridden_irtree != 0) + { + result = *e_ir_state->overridden_irtree; + } + else + { + result.type_key = e_type_unwrap(result.type_key); + } } } @@ -1626,12 +1634,20 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - // rjf: is "raw"? -> strip all lens types from result; disallow auto-hooks + // rjf: is "raw"? -> try to return overridden tree, otherwise strip all + // lens types from result; disallow auto-hooks if(str8_match(lhs_type->name, str8_lit("raw"), 0)) { - result = e_irtree_and_type_from_expr(arena, lhs->next); - result.type_key = e_type_unwrap(result.type_key); - allow_autohooks = 0; + e_ir_state->disallow_autohooks = 1; + if(e_ir_state->overridden_irtree != 0) + { + result = *e_ir_state->overridden_irtree; + } + else + { + result = e_irtree_and_type_from_expr(arena, lhs->next); + result.type_key = e_type_unwrap(result.type_key); + } } // rjf: is non-raw -> patch resultant type with a lens w/ args, pointing to the original type @@ -1764,7 +1780,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; mapped_type_key = e_ir_state->overridden_irtree->type_key; - allow_autohooks = 0; + e_ir_state->disallow_autohooks = 1; } //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) @@ -2254,8 +2270,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { irtree_stripped.type_key = e_type_direct_from_key(irtree_stripped.type_key); } - E_IRExt ext = type->irext(arena, expr, &irtree_stripped); - result.user_data = ext.user_data; + E_IRExt ext = type->irext(arena, expr, &irtree_stripped); + result.user_data = ext.user_data; } //- rjf: equip previous task's irtree @@ -2265,7 +2281,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: find any auto hooks according to this generation's type - if(allow_autohooks && result.mode != E_Mode_Null) + if(!e_ir_state->disallow_autohooks && result.mode != E_Mode_Null) { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -2288,9 +2304,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } ////////////////////////////// - //- rjf: reset the overridden irtree to whatever it was before this task list + //- rjf: reset the overridden settings to whatever they were before this task list // e_ir_state->overridden_irtree = start_prev; + e_ir_state->disallow_autohooks = start_disallow_autohooks; ////////////////////////////// //- rjf: unpoison the tags we used diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index ea560063..67b8f51a 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -154,6 +154,7 @@ struct E_IRState // rjf: overridden irtree E_IRTreeAndType *overridden_irtree; + B32 disallow_autohooks; // rjf: caches E_UsedExprMap *used_expr_map; From b34c70a2478a18137dfd8a3558ce7943f8c9375b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 12:49:47 -0700 Subject: [PATCH 365/755] begin merging view state / view parameterizations - unify code for introspecting on each, thus allowing explicit parameterizations of view state via a lens call. also build out the path from an eval -> cfg tree --- src/eval/eval_bundles.c | 56 ++++++ src/eval/eval_bundles.h | 3 + src/eval/eval_parse.c | 4 +- src/raddbg/generated/raddbg.meta.c | 12 +- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 23 ++- src/raddbg/raddbg_core.c | 285 +++++++++++++---------------- src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_views.c | 24 +-- 9 files changed, 230 insertions(+), 187 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 263159d5..5a35ef78 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -246,6 +246,62 @@ e_value_from_expr(E_Expr *expr) return result; } +internal U64 +e_base_offset_from_eval(E_Eval eval) +{ + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)))) + { + eval = e_value_eval_from_eval(eval); + } + return eval.value.u64; +} + +internal Rng1U64 +e_range_from_eval(E_Eval eval) +{ + U64 size = 0; + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) + { + for EachIndex(idx, type->count) + { + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) + { + size = e_value_from_expr(arg->first->next).u64; + break; + } + } + } + E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + E_TypeKind type_kind = e_type_kind_from_key(type_key); + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.irtree.type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.irtree.type_key))); + } + if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Union || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(e_type_unwrap(eval.irtree.type_key)); + } + if(size == 0) + { + size = KB(16); + } + Rng1U64 result = {0}; + result.min = e_base_offset_from_eval(eval); + result.max = result.min + size; + return result; +} + + //////////////////////////////// //~ rjf: Debug Logging Functions diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index 9801fbf8..e56d4fd3 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -37,6 +37,9 @@ internal E_Value e_value_from_string(String8 string); internal E_Value e_value_from_stringf(char *fmt, ...); internal E_Value e_value_from_expr(E_Expr *expr); +internal U64 e_base_offset_from_eval(E_Eval eval); +internal Rng1U64 e_range_from_eval(E_Eval eval); + //////////////////////////////// //~ rjf: Debug Logging Functions diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 675c5cbe..fbbae582 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -653,12 +653,12 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_Bool); } - else if(Case("float") || Case("f32") || Case("F32") || Case("r32") || Case("R32")) + else if(Case("float") || Case("float32") || Case("f32") || Case("F32") || Case("r32") || Case("R32")) { found = 1; key = e_type_key_basic(E_TypeKind_F32); } - else if(Case("double") || Case("f64") || Case("F64") || Case("r64") || Case("R64")) + else if(Case("double") || Case("float64") || Case("f64") || Case("F64") || Case("r64") || Case("R64")) { found = 1; key = e_type_key_basic(E_TypeKind_F64); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c343c535..66f40040 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[311] = +RD_VocabInfo rd_vocab_info_table[314] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -103,6 +103,9 @@ RD_VocabInfo rd_vocab_info_table[311] = {str8_lit_comp("break_on_read"), str8_lit_comp(""), str8_lit_comp("Break On Read"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("break_on_write"), str8_lit_comp(""), str8_lit_comp("Break On Write"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("break_on_execute"), str8_lit_comp(""), str8_lit_comp("Break On Execution"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("yaw"), str8_lit_comp(""), str8_lit_comp("Yaw"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("pitch"), str8_lit_comp(""), str8_lit_comp("Pitch"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("zoom"), str8_lit_comp(""), str8_lit_comp("Zoom"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -319,15 +322,16 @@ RD_VocabInfo rd_vocab_info_table[311] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[16] = +RD_NameSchemaInfo rd_name_schema_info_table[17] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n 'w': code_string,\n 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': code_string,\n @order(1) 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': code_string,\n 'pitch': code_string,\n 'zoom': code_string,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 4bf58a22..d5cd7f86 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -644,8 +644,8 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[311]; -extern RD_NameSchemaInfo rd_name_schema_info_table[16]; +extern RD_VocabInfo rd_vocab_info_table[314]; +extern RD_NameSchemaInfo rd_name_schema_info_table[17]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1bf5a8b1..73cf294b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -116,6 +116,9 @@ RD_VocabTable: {break_on_read "" "Break On Read" "" Null } {break_on_write "" "Break On Write" "" Null } {break_on_execute "" "Break On Execution" "" Null } + {yaw "" "Yaw" "" Null } + {pitch "" "Pitch" "" Null } + {zoom "" "Zoom" "" Null } } @struct RD_VocabInfo: @@ -210,12 +213,26 @@ RD_VocabTable: ``` x: { - 'w': code_string, - 'h': code_string, + @order(0) 'w': code_string, + @order(1) 'h': code_string, 'fmt': tex2dformat, } ``` } + { + geo3d, + ``` + x: + { + 'count': code_string, + 'vtx': code_string, + 'vtx_size': code_string, + 'yaw': code_string, + 'pitch': code_string, + 'zoom': code_string, + } + ``` + } //- rjf: targets { @@ -253,7 +270,7 @@ RD_VocabTable: 'source_location': path_pt, 'address_location': code_string, 'hit_count': u64, - 'address_range_size': @or(1, 2, 4, 8) u64, + 'address_range_size': @or(0, 1, 2, 4, 8) u64, 'break_on_write': bool, 'break_on_read': bool, 'break_on_execute': bool, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 08b445c4..f22c5c9e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2108,6 +2108,63 @@ rd_query_from_eval_string(Arena *arena, String8 string) //////////////////////////////// //~ rjf: View Functions +internal RD_Cfg * +rd_view_from_eval(RD_Cfg *parent, E_Eval eval) +{ + Temp scratch = scratch_begin(0, 0); + String8 schema_name = eval.expr->first->string; + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); + rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); + { + MD_Node *schema = rd_schema_from_name(schema_name); + E_Expr *primary_expr = eval.expr; + E_Expr *first_arg = &e_expr_nil; + if(eval.expr->kind == E_ExprKind_Call) + { + primary_expr = eval.expr->first->next; + first_arg = primary_expr->next; + } + RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new_replace(expr_root, e_string_from_expr(scratch.arena, primary_expr)); + { + U64 unnamed_order_idx = 0; + for(E_Expr *arg = first_arg; arg != &e_expr_nil; arg = arg->next) + { + String8 param_name = {0}; + E_Expr *arg_expr = arg; + if(arg->kind == E_ExprKind_Define) + { + param_name = arg->first->string; + arg_expr = arg->first->next; + } + else + { + for MD_EachNode(schema_child, schema->first) + { + MD_Node *order_tag = md_tag_from_string(schema_child, str8_lit("order"), 0); + if(order_tag != &md_nil_node) + { + U64 schema_child_order_idx = 0; + try_u64_from_str8_c_rules(order_tag->first->string, &schema_child_order_idx); + if(schema_child_order_idx == unnamed_order_idx) + { + param_name = schema_child->string; + arg_expr = arg; + break; + } + } + } + unnamed_order_idx += 1; + } + RD_Cfg *arg_root = rd_cfg_child_from_string_or_alloc(view, param_name); + rd_cfg_new_replace(arg_root, e_string_from_expr(scratch.arena, arg_expr)); + } + } + } + scratch_end(scratch); + return view; +} + internal RD_ViewState * rd_view_state_from_cfg(RD_Cfg *cfg) { @@ -2421,7 +2478,6 @@ rd_view_ui(Rng2F32 rect) } // rjf: unpack view's target expression & hash - String8 expr_string = rd_expr_from_cfg(view); E_Eval eval = e_eval_from_string(scratch.arena, expr_string); Rng1U64 range = r1u64(0, 1024); U128 key = rd_key_from_eval_space_range(eval.space, range, 0); @@ -4050,68 +4106,62 @@ rd_view_ui(Rng2F32 rect) //- rjf: cell has hook? -> build ui by calling hook else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) { + RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *view = rd_view_from_eval(root, cell_info.eval); Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); UI_Parent(box) - { - RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, cell_info.view_ui_rule->name); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.expr)); - rd_cfg_new(view, str8_lit("selected")); RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - UI_Flags(0) + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + UI_Flags(0) + { + // rjf: 'pull out' button + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) + UI_CornerRadius(ui_top_font_size()*1.5f) + UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()*0.8f) { - // rjf: 'pull out' button - UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) - UI_CornerRadius(ui_top_font_size()*1.5f) - UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()*0.8f) + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Floating| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects, + "%S###pull_out", + rd_icon_kind_text_table[RD_IconKind_Window]); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_Floating| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_DrawHotEffects, - "%S###pull_out", - rd_icon_kind_text_table[RD_IconKind_Window]); - UI_Signal sig = ui_signal_from_box(box); - if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) - { - rd_drag_begin(RD_RegSlot_View); - } - } - - // rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - // rjf: view ui contents - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = cell_info.eval.irtree.prev; - cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; - - // rjf: loading fill - UI_Parent(loading_overlay_container) - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + rd_drag_begin(RD_RegSlot_View); } } + // rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + // rjf: view ui contents + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = cell_info.eval.irtree.prev; + cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); + e_ir_state->overridden_irtree = prev_overridden_irtree; + + // rjf: loading fill + UI_Parent(loading_overlay_container) + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } } sig = ui_signal_from_box(box); } @@ -4666,63 +4716,32 @@ rd_view_cfg_value_from_string(String8 string) return result; } -//- rjf: evaluation & tag (a view's 'call') parameter extraction - internal U64 -rd_base_offset_from_eval(E_Eval eval) +rd_view_cfg_u64_from_string(String8 string) { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - -internal Rng1U64 -rd_range_from_eval(E_Eval eval) -{ - U64 size = 0; - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) - { - size = e_value_from_expr(arg->first->next).u64; - break; - } - } - } - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.irtree.type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.irtree.type_key))); - } - if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(e_type_unwrap(eval.irtree.type_key)); - } - if(size == 0) - { - size = KB(16); - } - Rng1U64 result = {0}; - result.min = rd_base_offset_from_eval(eval); - result.max = result.min + size; + Temp scratch = scratch_begin(0, 0); + RD_Cfg *root = rd_view_cfg_from_string(string); + String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", root->first->string); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + U64 result = e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); return result; } +internal F32 +rd_view_cfg_f32_from_string(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + RD_Cfg *root = rd_view_cfg_from_string(string); + String8 expr = push_str8f(scratch.arena, "(float32)(%S)", root->first->string); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + F32 result = e_value_eval_from_eval(eval).value.f32; + scratch_end(scratch); + return result; +} + +//- rjf: evaluation & tag (a view's 'call') parameter extraction + internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval) { @@ -4794,62 +4813,6 @@ rd_arch_from_eval(E_Eval eval) return arch; } -internal Vec2S32 -rd_dim2s32_from_eval(E_Eval eval) -{ - Vec2S32 dim = v2s32(1, 1); - B32 got_x = 0; - B32 got_y = 0; - - // rjf: try explicitly passed dimensions - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define) - { - if(str8_match(arg->first->string, str8_lit("w"), 0)) - { - got_x = 1; - dim.x = e_value_from_expr(arg->first->next).s64; - } - if(str8_match(arg->first->string, str8_lit("h"), 0)) - { - got_y = 1; - dim.y = e_value_from_expr(arg->first->next).s64; - } - } - } - } - - // rjf: try ordered non-define arguments - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind != E_ExprKind_Define) - { - if(!got_x) - { - got_x = 1; - dim.x = e_value_from_expr(arg).s64; - } - else if(!got_y) - { - got_y = 1; - dim.y = e_value_from_expr(arg).s64; - break; - } - } - } - } - - return dim; -} - internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval) { @@ -6381,7 +6344,7 @@ rd_window_frame(void) // rjf: build view RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, view_name); + RD_Cfg *view = rd_view_from_eval(root, hover_eval); RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); rd_cfg_new_replace(explicit_root, str8_lit("1")); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 514feb8d..d00a9154 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -952,6 +952,7 @@ internal String8 rd_query_from_eval_string(Arena *arena, String8 string); //////////////////////////////// //~ rjf: View Functions +internal RD_Cfg *rd_view_from_eval(RD_Cfg *parent, E_Eval eval); internal RD_ViewState *rd_view_state_from_cfg(RD_Cfg *cfg); internal void rd_view_ui(Rng2F32 rect); @@ -966,13 +967,12 @@ internal String8 rd_view_query_cmd(void); internal String8 rd_view_query_input(void); internal RD_Cfg *rd_view_cfg_from_string(String8 string); internal E_Value rd_view_cfg_value_from_string(String8 string); +internal U64 rd_view_cfg_u64_from_string(String8 string); +internal F32 rd_view_cfg_f32_from_string(String8 string); //- rjf: evaluation & tag (a view's 'call') parameter extraction -internal U64 rd_base_offset_from_eval(E_Eval eval); -internal Rng1U64 rd_range_from_eval(E_Eval eval); internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval); internal Arch rd_arch_from_eval(E_Eval eval); -internal Vec2S32 rd_dim2s32_from_eval(E_Eval eval); internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval); internal E_Value rd_value_from_eval_key(E_Eval eval, String8 key); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b16227e4..4cfe1f7b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1743,7 +1743,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - Rng1U64 range = rd_range_from_eval(eval); + Rng1U64 range = e_range_from_eval(eval); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); U128 hash = {0}; @@ -2002,7 +2002,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = rd_range_from_eval(eval); + Rng1U64 range = e_range_from_eval(eval); Arch arch = rd_arch_from_eval(eval); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; @@ -2170,7 +2170,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - Rng1U64 space_range = rd_range_from_eval(eval); + Rng1U64 space_range = e_range_from_eval(eval); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -3085,9 +3085,9 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - Vec2S32 dim = rd_dim2s32_from_eval(eval); + Vec2S32 dim = v2s32((S32)rd_view_cfg_u64_from_string(str8_lit("w")), (S32)rd_view_cfg_u64_from_string(str8_lit("h"))); R_Tex2DFormat fmt = rd_tex2dformat_from_eval(eval); - U64 base_offset = rd_base_offset_from_eval(eval); + U64 base_offset = e_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -3484,17 +3484,17 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_value_from_eval_key(eval, str8_lit("count")).u64; - U64 vtx_base_off = rd_value_from_eval_key(eval, str8_lit("vtx")).u64; - U64 vtx_size = rd_value_from_eval_key(eval, str8_lit("vtx_size")).u64; - F32 yaw_target = rd_view_cfg_value_from_string(str8_lit("yaw")).f32; - F32 pitch_target = rd_view_cfg_value_from_string(str8_lit("pitch")).f32; - F32 zoom_target = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; + U64 count = rd_view_cfg_u64_from_string(str8_lit("count")); + U64 vtx_base_off = rd_view_cfg_u64_from_string(str8_lit("vtx")); + U64 vtx_size = rd_view_cfg_u64_from_string(str8_lit("vtx_size")); + F32 yaw_target = rd_view_cfg_f32_from_string(str8_lit("yaw")); + F32 pitch_target = rd_view_cfg_f32_from_string(str8_lit("pitch")); + F32 zoom_target = rd_view_cfg_f32_from_string(str8_lit("zoom")); ////////////////////////////// //- rjf: evaluate & unpack expression // - U64 base_offset = rd_base_offset_from_eval(eval); + U64 base_offset = e_base_offset_from_eval(eval); Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32)); Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size); U128 idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0); From 7d48e9915d89cdd2e7912030fee65de07436e1b6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 12:58:26 -0700 Subject: [PATCH 366/755] adjust lens'd eval -> view cfg to being based on type info, not expression tree --- src/raddbg/raddbg_core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f22c5c9e..217d83e0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2112,24 +2112,32 @@ internal RD_Cfg * rd_view_from_eval(RD_Cfg *parent, E_Eval eval) { Temp scratch = scratch_begin(0, 0); - String8 schema_name = eval.expr->first->string; + E_TypeKey type_key = eval.irtree.type_key; + E_Type *type = e_type_from_key__cached(type_key); + String8 schema_name = type->name; RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { MD_Node *schema = rd_schema_from_name(schema_name); E_Expr *primary_expr = eval.expr; - E_Expr *first_arg = &e_expr_nil; + E_Expr **args = 0; + U64 args_count = 0; if(eval.expr->kind == E_ExprKind_Call) { primary_expr = eval.expr->first->next; - first_arg = primary_expr->next; + } + if(type->args != 0) + { + args = type->args; + args_count = type->count; } RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); rd_cfg_new_replace(expr_root, e_string_from_expr(scratch.arena, primary_expr)); { U64 unnamed_order_idx = 0; - for(E_Expr *arg = first_arg; arg != &e_expr_nil; arg = arg->next) + for EachIndex(arg_idx, args_count) { + E_Expr *arg = args[arg_idx]; String8 param_name = {0}; E_Expr *arg_expr = arg; if(arg->kind == E_ExprKind_Define) From 51623013169e53b343fa69dfc6d13ac325f031cd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 13:18:01 -0700 Subject: [PATCH 367/755] f32 path for meta evaluations --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 6 +++--- src/raddbg/raddbg_core.c | 25 +++++++++++++++++++++++++ src/raddbg/raddbg_eval.c | 4 ++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 66f40040..617c766f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -329,7 +329,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': code_string,\n @order(1) 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': code_string,\n 'pitch': code_string,\n 'zoom': code_string,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': f32,\n 'pitch': f32,\n 'zoom': f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 73cf294b..10d2e7d0 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -227,9 +227,9 @@ RD_VocabTable: 'count': code_string, 'vtx': code_string, 'vtx_size': code_string, - 'yaw': code_string, - 'pitch': code_string, - 'zoom': code_string, + 'yaw': f32, + 'pitch': f32, + 'zoom': f32, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 217d83e0..5f2828d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1648,6 +1648,16 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) try_u64_from_str8_c_rules(value_string, &value); read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } + else if(str8_match(child_type_name, str8_lit("f32"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + F32 value = (F32)f64_from_str8(value_string); + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } } // rjf: perform read @@ -1812,6 +1822,21 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) } result = 1; } + else if(str8_match(child_type_name, str8_lit("f32"), 0)) + { + if(range.max == range.min) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + else + { + F32 value = 0; + MemoryCopy(&value, in, dim_1u64(range)); + RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replacef(child, "%f", value); + } + result = 1; + } } scratch_end(scratch); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 9cfcc3cb..2f50af59 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -369,6 +369,10 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_basic(E_TypeKind_U64); } + else if(str8_match(child_schema->first->string, str8_lit("f32"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_F32); + } else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) { child_type_key = e_type_key_basic(E_TypeKind_Bool); From a021e6f68fbad2b575bfa1bc2f5f6eaf1ed7f238 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 13:51:43 -0700 Subject: [PATCH 368/755] extend rangification of meta evaluations to all child evaluations; further mark up schema expansion types --- src/raddbg/generated/raddbg.meta.c | 6 +++--- src/raddbg/raddbg.mdesk | 12 ++++++------ src/raddbg/raddbg_eval.c | 20 ++++++++++++++++++++ src/raddbg/raddbg_views.c | 8 ++++---- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 617c766f..1cbb3cf2 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -327,9 +327,9 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': code_string,\n @order(1) 'h': code_string,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': f32,\n 'pitch': f32,\n 'zoom': f32,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 256] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 10d2e7d0..fa3cfc3f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -204,7 +204,7 @@ RD_VocabTable: x: { 'size': code_string, - @default(16) 'num_columns': @range[1, 64] u64, + @default(16) 'num_columns': @range[1, 256] u64, } ``` } @@ -213,8 +213,8 @@ RD_VocabTable: ``` x: { - @order(0) 'w': code_string, - @order(1) 'h': code_string, + @order(0) 'w': u64, + @order(1) 'h': u64, 'fmt': tex2dformat, } ``` @@ -227,9 +227,9 @@ RD_VocabTable: 'count': code_string, 'vtx': code_string, 'vtx_size': code_string, - 'yaw': f32, - 'pitch': f32, - 'zoom': f32, + 'yaw': @range[0, 1] f32, + 'pitch': @range[-0.5, 0] f32, + 'zoom': @range[0, 100] f32, } ``` } diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 2f50af59..521f35fc 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -392,6 +392,26 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) child_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, child_schema->string); } + //- rjf: extend child type with ranges + MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); + if(!md_node_is_nil(range)) + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).exprs.first; + E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).exprs.first; + E_Expr *args[] = + { + min_bound, + max_bound, + }; + child_type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .name = str8_lit("range1"), + .direct_key = child_type_key, + .count = 2, + .args = args); + scratch_end(scratch); + } + //- rjf: evaluate E_Space child_eval_space = zero_struct; if(cfg != &rd_nil_cfg) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4cfe1f7b..aa56aa14 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2180,10 +2180,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { space_range = r1u64(0, 0x7FFFFFFFFFFFull); } - U64 cursor = rd_view_cfg_value_from_string(str8_lit("cursor_vaddr")).u64; - U64 mark = rd_view_cfg_value_from_string(str8_lit("mark_vaddr")).u64; - U64 bytes_per_cell = rd_view_cfg_value_from_string(str8_lit("bytes_per_cell")).u64; - U64 num_columns = rd_view_cfg_value_from_string(str8_lit("num_columns")).u64; + U64 cursor = rd_view_cfg_u64_from_string(str8_lit("cursor_vaddr")); + U64 mark = rd_view_cfg_u64_from_string(str8_lit("mark_vaddr")); + U64 bytes_per_cell = rd_view_cfg_u64_from_string(str8_lit("bytes_per_cell")); + U64 num_columns = rd_view_cfg_u64_from_string(str8_lit("num_columns")); if(num_columns == 0) { num_columns = 16; From a34e39751f45329494f5d1ee44285de2e98215ff Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 14:12:23 -0700 Subject: [PATCH 369/755] eliminate type-determined cfg tree eval writes - just always use textual data, and only use type info if committing to an actual ctrl entity space --- src/raddbg/raddbg_core.c | 180 +++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 102 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5f2828d8..4f7cb691 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1760,7 +1760,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) //- rjf: meta-config writes case RD_EvalSpaceKind_MetaCfg: { - Temp scratch = scratch_begin(0, 0); + result = 1; // rjf: unpack write info String8 write_string = str8_cstring_capped(in, (U8 *)in + dim_1u64(range)); @@ -1768,78 +1768,19 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) // rjf: unpack cfg RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); String8 child_key = e_string_from_id(space.u64s[1]); - RD_Cfg *cfg = root_cfg; - if(child_key.size != 0) + + // rjf: zero-range? delete child + if(range.min == range.max) { - cfg = rd_cfg_child_from_string(root_cfg, child_key); + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); } - // rjf: perform write, based on child type in schema - if(child_key.size != 0) + // rjf: non-zero-range? create child if needed & write value + else { - MD_Node *root_schema = rd_schema_from_name(root_cfg->string); - MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); - String8 child_type_name = child_schema->first->string; - if(str8_match(child_type_name, str8_lit("path_pt"), 0)) - { - result = 0; - } - else if(str8_match(child_type_name, str8_lit("path"), 0) || - str8_match(child_type_name, str8_lit("code_string"), 0) || - str8_match(child_type_name, str8_lit("string"), 0)) - { - RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); - rd_cfg_new_replace(child, write_string); - result = 1; - } - else if(str8_match(child_type_name, str8_lit("bool"), 0)) - { - if(range.max == range.min) - { - rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); - } - else - { - U64 value = 0; - MemoryCopy(&value, in, dim_1u64(range)); - RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); - rd_cfg_new_replacef(child, "%I64u", !!value); - } - result = 1; - } - else if(str8_match(child_type_name, str8_lit("u64"), 0)) - { - if(range.max == range.min) - { - rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); - } - else - { - U64 value = 0; - MemoryCopy(&value, in, dim_1u64(range)); - RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); - rd_cfg_new_replacef(child, "%I64u", value); - } - result = 1; - } - else if(str8_match(child_type_name, str8_lit("f32"), 0)) - { - if(range.max == range.min) - { - rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); - } - else - { - F32 value = 0; - MemoryCopy(&value, in, dim_1u64(range)); - RD_Cfg *child = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); - rd_cfg_new_replacef(child, "%f", value); - } - result = 1; - } + RD_Cfg *child_cfg = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replace(child_cfg, write_string); } - - scratch_end(scratch); }break; case RD_EvalSpaceKind_MetaCtrlEntity: @@ -1970,34 +1911,56 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) if(dst_eval.irtree.mode == E_Mode_Offset) { Temp scratch = scratch_begin(0, 0); + + //- rjf: unpack type of destination E_TypeKey type_key = e_type_unwrap(dst_eval.irtree.type_key); E_TypeKind type_kind = e_type_kind_from_key(type_key); E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.irtree.type_key))); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + + //- rjf: determine data we'll write + B32 got_commit_data = 0; String8 commit_data = {0}; B32 commit_at_ptr_dest = 0; - if((E_TypeKind_FirstBasic <= type_kind && type_kind <= E_TypeKind_LastBasic) || - type_kind == E_TypeKind_Enum) + if(!e_type_key_match(e_type_key_zero(), type_key)) { - E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; - E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); - E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); - commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); - commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); - } - else if(type_kind == E_TypeKind_Ptr || type_kind == E_TypeKind_Array) - { - E_Eval src_eval = e_eval_from_string(scratch.arena, string); - E_Eval src_eval_value = e_value_eval_from_eval(src_eval); - E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); - if(direct_type_kind == E_TypeKind_Char8 || - direct_type_kind == E_TypeKind_Char16 || - direct_type_kind == E_TypeKind_Char32 || - direct_type_kind == E_TypeKind_UChar8 || - direct_type_kind == E_TypeKind_UChar16 || - direct_type_kind == E_TypeKind_UChar32 || - e_type_kind_is_integer(direct_type_kind)) + + //- rjf: meta evaluations? -> always treat string as textual content, as-is, + // and commit that. + if(!got_commit_data && dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg) { + got_commit_data = 1; + commit_data = string; + } + + //- rjf: basic types or enums? treat string as an expression, cast to the + // destination type, and compute commit data as being the binary representation + // of the new value. + if(!got_commit_data && + ((E_TypeKind_FirstBasic <= type_kind && type_kind <= E_TypeKind_LastBasic) || + type_kind == E_TypeKind_Enum)) + { + got_commit_data = 1; + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); + E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); + commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); + commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); + } + + //- rjf: pointer or array to characters/integers? -> try to treat + // new value string as textual data + if(!got_commit_data && + ((type_kind == E_TypeKind_Ptr || type_kind == E_TypeKind_Array) && + direct_type_kind == E_TypeKind_Char8 || + direct_type_kind == E_TypeKind_Char16 || + direct_type_kind == E_TypeKind_Char32 || + direct_type_kind == E_TypeKind_UChar8 || + direct_type_kind == E_TypeKind_UChar16 || + direct_type_kind == E_TypeKind_UChar32 || + e_type_kind_is_integer(direct_type_kind))) + { + got_commit_data = 1; B32 is_quoted = 0; if(string.size >= 1 && string.str[0] == '"') { @@ -2042,26 +2005,39 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) }break; } } - else if(type_kind == E_TypeKind_Ptr && - (e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || - e_type_kind_is_integer(src_eval_value_type_kind)) && - src_eval_value.irtree.mode == E_Mode_Value) + + //- rjf: pointer? -> try to treat new value as numeric value + if(!got_commit_data && type_kind == E_TypeKind_Ptr) { - commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); - commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.irtree.type_key)); - commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); + E_Eval src_eval = e_eval_from_string(scratch.arena, string); + E_Eval src_eval_value = e_value_eval_from_eval(src_eval); + E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); + if((e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || + e_type_kind_is_integer(src_eval_value_type_kind)) && + src_eval_value.irtree.mode == E_Mode_Value) + { + got_commit_data = 1; + commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); + commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(src_eval.irtree.type_key)); + commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); + } } } - if(commit_data.size != 0 && !e_type_key_match(e_type_key_zero(), type_key)) + + //- rjf: determine destination offset we'll write the new data to + U64 dst_offset = dst_eval.value.u64; + if(got_commit_data && commit_at_ptr_dest) + { + E_Eval dst_value_eval = e_value_eval_from_eval(dst_eval); + dst_offset = dst_value_eval.value.u64; + } + + //- rjf: if we have commit data, then write that data to the destination offset + if(got_commit_data) { - U64 dst_offset = dst_eval.value.u64; - if(dst_eval.irtree.mode == E_Mode_Offset && commit_at_ptr_dest) - { - E_Eval dst_value_eval = e_value_eval_from_eval(dst_eval); - dst_offset = dst_value_eval.value.u64; - } result = e_space_write(dst_eval.space, commit_data.str, r1u64(dst_offset, dst_offset + commit_data.size)); } + scratch_end(scratch); } return result; From cbc44cd9e43124bf1db4199b54b0b9a1b5401c31 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 14:31:38 -0700 Subject: [PATCH 370/755] fix hover eval view cfg build; fix editability-from-type-key path to respect lenses --- .../eval_visualization_core.c | 65 +++++++++++-------- src/raddbg/raddbg_core.c | 11 +++- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 35e6a7f3..8f06f230 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -104,39 +104,50 @@ internal B32 ev_type_key_is_editable(E_TypeKey type_key) { B32 result = 0; - for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) + B32 done = 0; + for(E_TypeKey t = type_key; !result && !done; t = e_type_direct_from_key(t)) { E_TypeKind kind = e_type_kind_from_key(t); - if(kind == E_TypeKind_Array) + switch(kind) { - E_TypeKind element_kind = e_type_kind_from_key(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))); - if(element_kind != E_TypeKind_U8 && - element_kind != E_TypeKind_U16 && - element_kind != E_TypeKind_U32 && - element_kind != E_TypeKind_S8 && - element_kind != E_TypeKind_S16 && - element_kind != E_TypeKind_S32 && - element_kind != E_TypeKind_UChar8 && - element_kind != E_TypeKind_UChar16 && - element_kind != E_TypeKind_UChar32 && - element_kind != E_TypeKind_Char8 && - element_kind != E_TypeKind_Char16 && - element_kind != E_TypeKind_Char32) + case E_TypeKind_Null: + case E_TypeKind_Function: { - break; - } - else + result = 0; + done = 1; + }break; + default: + if((E_TypeKind_FirstBasic <= kind && kind <= E_TypeKind_LastBasic) || e_type_kind_is_pointer_or_ref(kind)) { result = 1; - } - } - if(kind == E_TypeKind_Null || kind == E_TypeKind_Function) - { - break; - } - if((E_TypeKind_FirstBasic <= kind && kind <= E_TypeKind_LastBasic) || e_type_kind_is_pointer_or_ref(kind)) - { - result = 1; + done = 1; + }break; + case E_TypeKind_Array: + { + E_Type *type = e_type_from_key__cached(t); + if(type->flags & E_TypeFlag_IsNotText) + { + result = 0; + done = 1; + } + else + { + E_TypeKind element_kind = e_type_kind_from_key(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))); + result = (element_kind == E_TypeKind_U8 || + element_kind == E_TypeKind_U16 || + element_kind == E_TypeKind_U32 || + element_kind == E_TypeKind_S8 || + element_kind == E_TypeKind_S16 || + element_kind == E_TypeKind_S32 || + element_kind == E_TypeKind_UChar8 || + element_kind == E_TypeKind_UChar16 || + element_kind == E_TypeKind_UChar32 || + element_kind == E_TypeKind_Char8 || + element_kind == E_TypeKind_Char16 || + element_kind == E_TypeKind_Char32); + done = 1; + } + }break; } } return result; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4f7cb691..58346a55 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1924,7 +1924,6 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) B32 commit_at_ptr_dest = 0; if(!e_type_key_match(e_type_key_zero(), type_key)) { - //- rjf: meta evaluations? -> always treat string as textual content, as-is, // and commit that. if(!got_commit_data && dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg) @@ -2115,7 +2114,15 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) Temp scratch = scratch_begin(0, 0); E_TypeKey type_key = eval.irtree.type_key; E_Type *type = e_type_from_key__cached(type_key); - String8 schema_name = type->name; + String8 schema_name = str8_lit("watch"); + if(type->kind == E_TypeKind_Lens) + { + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(type->name); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + schema_name = type->name; + } + } RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { From 8e13f8162aaea69f08126e9348a9ae61fecde8c0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 14:52:46 -0700 Subject: [PATCH 371/755] adjust memory reads from cfg spaces to evaluating the cfg strings, rather than directly interpreting them as leaves --- src/raddbg/generated/raddbg.meta.c | 5 +++-- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 4 +++- src/raddbg/raddbg_core.c | 13 ++++++++----- src/raddbg/raddbg_views.c | 2 -- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 1cbb3cf2..1c8e1e17 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[314] = +RD_VocabInfo rd_vocab_info_table[315] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -97,6 +97,7 @@ RD_VocabInfo rd_vocab_info_table[314] = {str8_lit_comp("show_line_numbers"), str8_lit_comp(""), str8_lit_comp("Show Line Numbers"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("syntax"), str8_lit_comp("syntaxes"), str8_lit_comp("Syntax"), str8_lit_comp("Syntaxes"), RD_IconKind_Null}, {str8_lit_comp("num_columns"), str8_lit_comp(""), str8_lit_comp("Number of Columns"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("bytes_per_cell"), str8_lit_comp(""), str8_lit_comp("Bytes Per Cell"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("bitmap"), str8_lit_comp("bitmaps"), str8_lit_comp("Bitmap"), str8_lit_comp("Bitmaps"), RD_IconKind_Bitmap}, {str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, {str8_lit_comp("address_range_size"), str8_lit_comp("address_range_sizes"), str8_lit_comp("Address Range Size"), str8_lit_comp("Address Range Sizes"), RD_IconKind_Null}, @@ -327,7 +328,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 256] u64,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 256] u64,\n @default(1) 'bytes_per_cell': @range[1, 16] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d5cd7f86..c3feb1ad 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -644,7 +644,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[314]; +extern RD_VocabInfo rd_vocab_info_table[315]; extern RD_NameSchemaInfo rd_name_schema_info_table[17]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index fa3cfc3f..3820156f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -110,6 +110,7 @@ RD_VocabTable: {show_line_numbers "" "Show Line Numbers" "" Null } {syntax syntaxes "Syntax" "Syntaxes" Null } {num_columns "" "Number of Columns" "" Null } + {bytes_per_cell "" "Bytes Per Cell" "" Null } {bitmap _ "Bitmap" _ Bitmap } {geo3d "" "Geometry (3D)" "" Cube } {address_range_size _ "Address Range Size" _ Null } @@ -203,8 +204,9 @@ RD_VocabTable: ``` x: { - 'size': code_string, + 'size': code_string, @default(16) 'num_columns': @range[1, 256] u64, + @default(1) 'bytes_per_cell': @range[1, 16] u64, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 58346a55..e54c48c1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1634,7 +1634,8 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; } - B32 value = str8_match(value_string, str8_lit("1"), 0); + String8 value_string_casted = push_str8f(scratch.arena, "(bool)(%S)", value_string); + B32 value = !!e_value_from_string(value_string_casted).u64; read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } else if(str8_match(child_type_name, str8_lit("u64"), 0)) @@ -1644,8 +1645,8 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; } - U64 value = 0; - try_u64_from_str8_c_rules(value_string, &value); + String8 value_string_casted = push_str8f(scratch.arena, "(uint64)(%S)", value_string); + U64 value = e_value_from_string(value_string_casted).u64; read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } else if(str8_match(child_type_name, str8_lit("f32"), 0)) @@ -1655,7 +1656,8 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; } - F32 value = (F32)f64_from_str8(value_string); + String8 value_string_casted = push_str8f(scratch.arena, "(float32)(%S)", value_string); + F32 value = e_value_from_string(value_string_casted).f32; read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } } @@ -4368,7 +4370,8 @@ rd_view_ui(Rng2F32 rect) } // rjf: dragging -> drag/drop - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse())) + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse()) && + (!cell_selected || !ewv->text_editing)) { if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index aa56aa14..d39c9a4d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2960,8 +2960,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // rd_store_view_param_u64(str8_lit("cursor_vaddr"), cursor); rd_store_view_param_u64(str8_lit("mark_vaddr"), mark); - rd_store_view_param_u64(str8_lit("bytes_per_cell"), bytes_per_cell); - rd_store_view_param_u64(str8_lit("num_columns"), num_columns); rd_store_view_scroll_pos(scroll_pos); hs_scope_close(hs_scope); From db381db85d9aa0bf940822a8bc286ab9cdf55b56 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 14 Apr 2025 15:21:46 -0700 Subject: [PATCH 372/755] meta-expr type operators, for meta-evaluations, to annotate source expression strings of evaluations --- src/eval/eval.mdesk | 1 + src/eval/eval_types.c | 22 ++++++++++++- src/eval/generated/eval.meta.c | 6 ++-- src/eval/generated/eval.meta.h | 5 +-- .../eval_visualization_core.c | 32 +++++++++++++++++++ src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +-- src/raddbg/raddbg_eval.c | 21 ++++++++++++ 8 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index e943b21d..b70e3fbb 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -74,6 +74,7 @@ E_TypeKindTable: {Set "set" 0 } {Lens "lens" 0 } {LensSpec "lens_spec" 0 } + {MetaExpr "meta_expr" 0 } } @table(name op_kind precedence op_pre op_sep op_pos op_chain) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index b6194826..a84bf0ef 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1338,7 +1338,8 @@ e_type_unwrap(E_TypeKey key) if((E_TypeKind_FirstIncomplete <= kind && kind <= E_TypeKind_LastIncomplete) || kind == E_TypeKind_Modifier || kind == E_TypeKind_Alias || - kind == E_TypeKind_Lens) + kind == E_TypeKind_Lens || + kind == E_TypeKind_MetaExpr) { result = e_type_direct_from_key(result); } @@ -1800,6 +1801,12 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } str8_list_push(arena, out, str8_lit("::*")); }break; + + case E_TypeKind_MetaExpr: + { + E_TypeKey direct = e_type_direct_from_key(key); + e_type_lhs_string_from_key(arena, direct, out, prec, skip_return); + }break; } } @@ -1874,6 +1881,12 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; + + case E_TypeKind_MetaExpr: + { + E_TypeKey direct = e_type_direct_from_key(key); + e_type_rhs_string_from_key(arena, direct, out, prec); + }break; } } @@ -1947,6 +1960,13 @@ e_default_expansion_type_from_key(E_TypeKey root_key) done = 0; } + //- rjf: if we have meta-expression tags in the type chain, defer + // to the next type in the chain. + else if(kind == E_TypeKind_MetaExpr) + { + done = 0; + } + //- rjf: if we've reached a struct-like, then we can use that for // struct-like expansion. else if(kind == E_TypeKind_Struct || diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 6febd96e..cf45b3a3 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_type_kind_basic_string_table[58] = +String8 e_type_kind_basic_string_table[59] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -74,9 +74,10 @@ str8_lit_comp("variadic"), str8_lit_comp("set"), str8_lit_comp("lens"), str8_lit_comp("lens_spec"), +str8_lit_comp("meta_expr"), }; -U8 e_type_kind_basic_byte_size_table[58] = +U8 e_type_kind_basic_byte_size_table[59] = { 0, 0, @@ -136,6 +137,7 @@ U8 e_type_kind_basic_byte_size_table[58] = 0, 0, 0, +0, }; String8 e_expr_kind_strings[48] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index d9212232..6ba7a85e 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -77,6 +77,7 @@ E_TypeKind_Variadic, E_TypeKind_Set, E_TypeKind_Lens, E_TypeKind_LensSpec, +E_TypeKind_MetaExpr, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -162,8 +163,8 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_type_kind_basic_string_table[58]; -extern U8 e_type_kind_basic_byte_size_table[58]; +extern String8 e_type_kind_basic_string_table[59]; +extern U8 e_type_kind_basic_byte_size_table[59]; extern String8 e_expr_kind_strings[48]; extern E_OpInfo e_expr_kind_op_info_table[48]; extern String8 e_interpretation_code_display_strings[11]; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 8f06f230..d22ca1a3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1657,6 +1657,38 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } }break; + ////////////////////////// + //- rjf: meta-expression tags + // + case E_TypeKind_MetaExpr: + { + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + { + switch(task_idx) + { + default:{}break; + case 0: + { + need_pop = 0; + need_new_task = 1; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + }break; + case 1: + { + E_Type *type = e_type_from_key__cached(type_key); + *out_string = push_str8f(arena, " (%S)", type->name); + }break; + } + } + else + { + E_Type *type = e_type_from_key__cached(type_key); + *out_string = type->name; + } + }break; + ////////////////////////// //- rjf: modifiers // diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 1c8e1e17..c8476d82 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -328,7 +328,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 256] u64,\n @default(1) 'bytes_per_cell': @range[1, 16] u64,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 3820156f..966e7bb7 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -205,8 +205,8 @@ RD_VocabTable: x: { 'size': code_string, - @default(16) 'num_columns': @range[1, 256] u64, - @default(1) 'bytes_per_cell': @range[1, 16] u64, + @default(16) 'num_columns': @range[1, 64] u64, + @default(1) 'bytes_per_cell': @range[1, 8] u64, } ``` } diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 521f35fc..bc90f40d 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -367,15 +367,36 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) //- rjf: catchall cases else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) { + Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_U64); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + if(expr->kind != E_ExprKind_LeafU64) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); + } + scratch_end(scratch); } else if(str8_match(child_schema->first->string, str8_lit("f32"), 0)) { + Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_F32); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + if(expr->kind != E_ExprKind_LeafF32 && expr->kind != E_ExprKind_LeafF64) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); + } + scratch_end(scratch); } else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) { + Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_Bool); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + if(expr->kind != E_ExprKind_LeafU64) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); + } + scratch_end(scratch); } else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) { From e27f31cfa4f6640fdd2110c646d1778785fdc05c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 11:35:49 -0700 Subject: [PATCH 373/755] adjust meta-expr type visualization; unify 'type unwrapping' paths, instead of nest of various 'scanners', we just have one path which we parameterize via bits to skip what each path needs --- src/eval/eval_bundles.c | 18 +- src/eval/eval_ir.c | 59 +- src/eval/eval_types.c | 569 ++++++++---------- src/eval/eval_types.h | 38 +- .../eval_visualization_core.c | 27 +- src/raddbg/raddbg_core.c | 11 +- src/raddbg/raddbg_eval.c | 6 +- src/raddbg/raddbg_views.c | 2 +- 8 files changed, 336 insertions(+), 394 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 5a35ef78..4e056cb1 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -94,7 +94,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) type_kind == E_TypeKind_Ptr) { Temp scratch = scratch_begin(0, 0); - E_TypeKey ptee_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key))); + E_TypeKey ptee_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { @@ -111,7 +111,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) if(has_vtable) { U64 ptr_vaddr = eval.value.u64; - U64 addr_size = e_type_byte_size_from_key(e_type_unwrap(type_key)); + U64 addr_size = e_type_byte_size_from_key(e_type_key_unwrap(type_key, E_TypeUnwrapFlag_AllDecorative)); U64 class_base_vaddr = 0; U64 vtable_vaddr = 0; if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && @@ -160,7 +160,7 @@ e_value_eval_from_eval(E_Eval eval) ProfBeginFunction(); if(eval.irtree.mode == E_Mode_Offset) { - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + 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) { @@ -249,7 +249,7 @@ e_value_from_expr(E_Expr *expr) internal U64 e_base_offset_from_eval(E_Eval eval) { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)))) + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)))) { eval = e_value_eval_from_eval(eval); } @@ -273,23 +273,23 @@ e_range_from_eval(E_Eval eval) } } } - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + 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); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.irtree.type_key)); + E_TypeKey direct_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || direct_type_kind == E_TypeKind_Union || direct_type_kind == E_TypeKind_Class || direct_type_kind == E_TypeKind_Array)) { - size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.irtree.type_key))); + size = e_type_byte_size_from_key(direct_type_key); } if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Union || type_kind == E_TypeKind_Class || type_kind == E_TypeKind_Array)) { - size = e_type_byte_size_from_key(e_type_unwrap(eval.irtree.type_key)); + size = e_type_byte_size_from_key(type_key); } if(size == 0) { @@ -376,7 +376,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) S32 indent = 2; for(E_TypeKey type_key = irtree.type_key; !e_type_key_match(e_type_key_zero(), type_key); - type_key = e_type_direct_from_key(type_key), + type_key = e_type_key_direct(type_key), indent += 1) { E_Type *type = e_type_from_key(scratch.arena, type_key); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4eca77d5..9838c363 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -658,7 +658,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); E_TypeKey check_type_key = l_restype; E_TypeKind check_type_kind = l_restype_kind; @@ -666,7 +666,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) l_restype_kind == E_TypeKind_LRef || l_restype_kind == E_TypeKind_RRef) { - check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); + check_type_key = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_All); check_type_kind = e_type_kind_from_key(check_type_key); } e_msg_list_concat_in_place(&result.msgs, &l.msgs); @@ -783,18 +783,11 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKey r_restype = e_type_unwrap(r.type_key); + E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); - if(e_type_kind_is_basic_or_enum(r_restype_kind)) - { - r_restype = e_type_unwrap_enum(r_restype); - r_restype_kind = e_type_kind_from_key(r_restype); - } - E_TypeKey direct_type = e_type_unwrap(l_restype); - direct_type = e_type_direct_from_key(direct_type); - direct_type = e_type_unwrap(direct_type); + E_TypeKey direct_type = e_type_key_unwrap(l_restype, E_TypeUnwrapFlag_All); U64 direct_type_size = e_type_byte_size_from_key(direct_type); e_msg_list_concat_in_place(&result.msgs, &l.msgs); e_msg_list_concat_in_place(&result.msgs, &r.msgs); @@ -951,7 +944,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); } - k = e_type_direct_from_key(k); + k = e_type_key_direct(k); kind = e_type_kind_from_key(k); } } @@ -981,9 +974,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(r_type)); + E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1037,7 +1030,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = r_tree.type_key; - E_TypeKey r_type_unwrapped = e_type_unwrap(r_type); + E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1068,7 +1061,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); - E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key); + E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); U8 in_group = e_type_group_from_kind(casted_type_kind); @@ -1178,7 +1171,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); U64 r_type_size = e_type_byte_size_from_key(r_type); @@ -1212,10 +1205,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); - E_TypeKey r_type_promoted = e_type_promote(r_type); + E_TypeKey r_type_promoted = e_type_key_promote(r_type); RDI_EvalOp op = e_opcode_from_expr_kind(kind); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1245,7 +1238,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); @@ -1303,8 +1296,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key)); - E_TypeKey r_type = e_type_unwrap_enum(e_type_unwrap(r_tree.type_key)); + E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); if(l_type.kind == E_TypeKeyKind_Reg) @@ -1359,8 +1352,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } if(l_is_pointer_like && r_is_pointer_like) { - E_TypeKey l_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); - E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(r_type))); + E_TypeKey l_type_direct = e_type_key_unwrap(l_type, E_TypeUnwrapFlag_All); + E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); U64 l_type_direct_byte_size = e_type_byte_size_from_key(l_type_direct); U64 r_type_direct_byte_size = e_type_byte_size_from_key(r_type_direct); if(l_type_direct_byte_size == r_type_direct_byte_size) @@ -1424,7 +1417,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } // rjf: unpack type - E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(ptr_tree->type_key))); + E_TypeKey direct_type = e_type_key_unwrap(ptr_tree->type_key, E_TypeUnwrapFlag_All); U64 direct_type_size = e_type_byte_size_from_key(direct_type); // rjf: generate @@ -1457,7 +1450,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) case E_ArithPath_PtrSub: { // rjf: unpack type - E_TypeKey direct_type = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_type))); + E_TypeKey direct_type = e_type_key_unwrap(l_type, E_TypeUnwrapFlag_All); U64 direct_type_size = e_type_byte_size_from_key(direct_type); // rjf: generate @@ -1529,9 +1522,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - E_TypeKey c_type = e_type_unwrap(c_tree.type_key); - E_TypeKey l_type = e_type_unwrap(l_tree.type_key); - E_TypeKey r_type = e_type_unwrap(r_tree.type_key); + E_TypeKey c_type = e_type_key_unwrap(c_tree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind c_type_kind = e_type_kind_from_key(c_type); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1603,7 +1596,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } else { - result.type_key = e_type_unwrap(result.type_key); + result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } } @@ -1646,7 +1639,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) else { result = e_irtree_and_type_from_expr(arena, lhs->next); - result.type_key = e_type_unwrap(result.type_key); + result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -2268,7 +2261,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_IRTreeAndType irtree_stripped = result; if(type->kind == E_TypeKind_Lens) { - irtree_stripped.type_key = e_type_direct_from_key(irtree_stripped.type_key); + irtree_stripped.type_key = e_type_key_direct(irtree_stripped.type_key); } E_IRExt ext = type->irext(arena, expr, &irtree_stripped); result.user_data = ext.user_data; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index a84bf0ef..4db7e20d 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -562,7 +562,7 @@ e_type_key_match(E_TypeKey l, E_TypeKey r) return result; } -//- rjf: key -> info extraction +//- rjf: type key -> info extraction internal U64 e_hash_from_type(E_Type *type) @@ -627,6 +627,48 @@ e_type_kind_from_key(E_TypeKey key) return kind; } +internal U64 +e_type_byte_size_from_key(E_TypeKey key) +{ + ProfBeginFunction(); + U64 result = 0; + switch(key.kind) + { + default:{}break; + case E_TypeKeyKind_Basic: + { + E_TypeKind kind = (E_TypeKind)key.u32[0]; + result = e_type_kind_basic_byte_size_table[kind]; + }break; + case E_TypeKeyKind_Ext: + { + U64 type_node_idx = key.u32[1]; + U32 rdi_idx = key.u32[2]; + RDI_Parsed *rdi = e_type_state->ctx->modules[rdi_idx].rdi; + RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); + result = rdi_type->byte_size; + }break; + case E_TypeKeyKind_Cons: + { + U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); + U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx]; + for(E_ConsTypeNode *node = key_slot->first; + node != 0; + node = node->key_next) + { + if(e_type_key_match(node->key, key)) + { + result = node->byte_size; + break; + } + } + }break; + } + ProfEnd(); + return result; +} + internal E_Type * e_type_from_key(Arena *arena, E_TypeKey key) { @@ -1201,287 +1243,6 @@ e_type_from_key(Arena *arena, E_TypeKey key) return type; } -internal U64 -e_type_byte_size_from_key(E_TypeKey key) -{ - ProfBeginFunction(); - U64 result = 0; - switch(key.kind) - { - default:{}break; - case E_TypeKeyKind_Basic: - { - E_TypeKind kind = (E_TypeKind)key.u32[0]; - result = e_type_kind_basic_byte_size_table[kind]; - }break; - case E_TypeKeyKind_Ext: - { - U64 type_node_idx = key.u32[1]; - U32 rdi_idx = key.u32[2]; - RDI_Parsed *rdi = e_type_state->ctx->modules[rdi_idx].rdi; - RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); - result = rdi_type->byte_size; - }break; - case E_TypeKeyKind_Cons: - { - U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count; - E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx]; - for(E_ConsTypeNode *node = key_slot->first; - node != 0; - node = node->key_next) - { - if(e_type_key_match(node->key, key)) - { - result = node->byte_size; - break; - } - } - }break; - } - ProfEnd(); - return result; -} - -internal E_TypeKey -e_type_direct_from_key(E_TypeKey key) -{ - E_TypeKey result = zero_struct; - switch(key.kind) - { - default:{}break; - case E_TypeKeyKind_Ext: - case E_TypeKeyKind_Cons: - { - E_Type *type = e_type_from_key__cached(key); - result = type->direct_type_key; - }break; - } - return result; -} - -internal E_TypeKey -e_type_owner_from_key(E_TypeKey key) -{ - E_TypeKey result = zero_struct; - switch(key.kind) - { - default:{}break; - case E_TypeKeyKind_Ext: - case E_TypeKeyKind_Cons: - { - E_Type *type = e_type_from_key__cached(key); - result = type->owner_type_key; - }break; - } - return result; -} - -internal E_TypeKey -e_type_ptee_from_key(E_TypeKey key) -{ - E_TypeKey result = key; - B32 passed_ptr = 0; - for(;;) - { - E_TypeKind kind = e_type_kind_from_key(result); - result = e_type_direct_from_key(result); - if(kind == E_TypeKind_Ptr || kind == E_TypeKind_LRef || kind == E_TypeKind_RRef) - { - passed_ptr = 1; - } - E_TypeKind next_kind = e_type_kind_from_key(result); - if(passed_ptr && - next_kind != E_TypeKind_IncompleteStruct && - next_kind != E_TypeKind_IncompleteUnion && - next_kind != E_TypeKind_IncompleteEnum && - next_kind != E_TypeKind_IncompleteClass && - next_kind != E_TypeKind_Alias && - next_kind != E_TypeKind_Modifier) - { - break; - } - if(kind == E_TypeKind_Null) - { - break; - } - } - return result; -} - -internal E_TypeKey -e_type_unwrap_enum(E_TypeKey key) -{ - E_TypeKey result = key; - for(B32 good = 1; good;) - { - E_TypeKind kind = e_type_kind_from_key(result); - if(kind == E_TypeKind_Enum) - { - result = e_type_direct_from_key(result); - } - else - { - good = 0; - } - } - return result; -} - -internal E_TypeKey -e_type_unwrap(E_TypeKey key) -{ - E_TypeKey result = key; - for(B32 good = 1; good;) - { - E_TypeKind kind = e_type_kind_from_key(result); - if((E_TypeKind_FirstIncomplete <= kind && kind <= E_TypeKind_LastIncomplete) || - kind == E_TypeKind_Modifier || - kind == E_TypeKind_Alias || - kind == E_TypeKind_Lens || - kind == E_TypeKind_MetaExpr) - { - result = e_type_direct_from_key(result); - } - else - { - good = 0; - } - } - return result; -} - -internal E_TypeKey -e_type_promote(E_TypeKey key) -{ - E_TypeKey result = key; - E_TypeKind kind = e_type_kind_from_key(key); - if(kind == E_TypeKind_Bool || - kind == E_TypeKind_S8 || - kind == E_TypeKind_S16 || - kind == E_TypeKind_U8 || - kind == E_TypeKind_U16) - { - result = e_type_key_basic(E_TypeKind_S32); - } - return result; -} - -internal B32 -e_type_match(E_TypeKey l, E_TypeKey r) -{ - // rjf: unpack parameters - E_TypeKey lu = e_type_unwrap(l); - E_TypeKey ru = e_type_unwrap(r); - - // rjf: exact key matches -> match - B32 result = e_type_key_match(lu, ru); - - // rjf: if keys don't match, type *contents* could still match, - // so we need to unpack the type info & compare - if(!result) - { - E_TypeKind luk = e_type_kind_from_key(lu); - E_TypeKind ruk = e_type_kind_from_key(ru); - if(luk == ruk) - { - switch(luk) - { - default: - { - result = 1; - }break; - - case E_TypeKind_Ptr: - case E_TypeKind_LRef: - case E_TypeKind_RRef: - { - E_TypeKey lud = e_type_direct_from_key(lu); - E_TypeKey rud = e_type_direct_from_key(ru); - result = e_type_match(lud, rud); - }break; - - case E_TypeKind_MemberPtr: - { - E_TypeKey lud = e_type_direct_from_key(lu); - E_TypeKey rud = e_type_direct_from_key(ru); - E_TypeKey luo = e_type_owner_from_key(lu); - E_TypeKey ruo = e_type_owner_from_key(ru); - result = (e_type_match(lud, rud) && e_type_match(luo, ruo)); - }break; - - case E_TypeKind_Array: - { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); - if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) - { - result = 1; - } - }break; - - case E_TypeKind_Function: - { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); - if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) - { - B32 params_match = 1; - E_TypeKey *lp = lt->param_type_keys; - E_TypeKey *rp = rt->param_type_keys; - U64 count = lt->count; - for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) - { - if(!e_type_match(*lp, *rp)) - { - params_match = 0; - break; - } - } - result = params_match; - } - }break; - - case E_TypeKind_Method: - { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); - if(lt->count == rt->count && - e_type_match(lt->direct_type_key, rt->direct_type_key) && - e_type_match(lt->owner_type_key, rt->owner_type_key)) - { - B32 params_match = 1; - E_TypeKey *lp = lt->param_type_keys; - E_TypeKey *rp = rt->param_type_keys; - U64 count = lt->count; - for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) - { - if(!e_type_match(*lp, *rp)) - { - params_match = 0; - break; - } - } - result = params_match; - } - }break; - } - } - } - - return result; -} - -internal E_Member * -e_type_member_copy(Arena *arena, E_Member *src) -{ - E_Member *dst = push_array(arena, E_Member, 1); - MemoryCopyStruct(dst, src); - dst->name = push_str8_copy(arena, src->name); - dst->inheritance_key_chain = e_type_key_list_copy(arena, &src->inheritance_key_chain); - return dst; -} - internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b) { @@ -1641,23 +1402,204 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) return members; } -internal E_Member * -e_type_member_from_array_name(E_MemberArray *members, String8 name) +//- rjf: type key traversal + +internal E_TypeKey +e_type_key_direct(E_TypeKey key) { - E_Member *member = 0; - for(U64 idx = 0; idx < members->count; idx += 1) + E_TypeKey result = zero_struct; + switch(key.kind) { - if((members->v[idx].kind == E_MemberKind_DataField || - members->v[idx].kind == E_MemberKind_Padding) && - str8_match(members->v[idx].name, name, 0)) + default:{}break; + case E_TypeKeyKind_Ext: + case E_TypeKeyKind_Cons: + { + E_Type *type = e_type_from_key__cached(key); + result = type->direct_type_key; + }break; + } + return result; +} + +internal E_TypeKey +e_type_key_owner(E_TypeKey key) +{ + E_TypeKey result = zero_struct; + switch(key.kind) + { + default:{}break; + case E_TypeKeyKind_Ext: + case E_TypeKeyKind_Cons: + { + E_Type *type = e_type_from_key__cached(key); + result = type->owner_type_key; + }break; + } + return result; +} + +internal E_TypeKey +e_type_key_promote(E_TypeKey key) +{ + E_TypeKey result = key; + E_TypeKind kind = e_type_kind_from_key(key); + if(kind == E_TypeKind_Bool || + kind == E_TypeKind_S8 || + kind == E_TypeKind_S16 || + kind == E_TypeKind_U8 || + kind == E_TypeKind_U16) + { + result = e_type_key_basic(E_TypeKind_S32); + } + return result; +} + +internal E_TypeKey +e_type_key_unwrap(E_TypeKey key, E_TypeUnwrapFlags flags) +{ + E_TypeKey result = key; + E_TypeKind kind = e_type_kind_from_key(result); + B32 did_ptr = 0; + for(;;) + { + B32 done = 0; + switch(kind) + { + default:{done = 1;}break; + case E_TypeKind_Modifier: {done = !(flags & E_TypeUnwrapFlag_Modifiers);}break; + case E_TypeKind_Lens: {done = !(flags & E_TypeUnwrapFlag_Lenses);}break; + case E_TypeKind_MetaExpr: {done = !(flags & E_TypeUnwrapFlag_Meta);}break; + case E_TypeKind_Enum: {done = !(flags & E_TypeUnwrapFlag_Enums);}break; + case E_TypeKind_Alias: {done = !(flags & E_TypeUnwrapFlag_Aliases);}break; + case E_TypeKind_Array: + case E_TypeKind_Ptr: + case E_TypeKind_RRef: + case E_TypeKind_LRef: + case E_TypeKind_MemberPtr: + { + done = (did_ptr || !(flags & E_TypeUnwrapFlag_Pointers)); + did_ptr = 1; + }break; + } + if(done) { - member = &members->v[idx]; break; } + result = e_type_key_direct(result); + kind = e_type_kind_from_key(result); } - return member; + return result; } +//- rjf: type comparisons + +internal B32 +e_type_match(E_TypeKey l, E_TypeKey r) +{ + // rjf: unpack parameters + E_TypeKey lu = e_type_key_unwrap(l, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey ru = e_type_key_unwrap(r, E_TypeUnwrapFlag_AllDecorative); + + // rjf: exact key matches -> match + B32 result = e_type_key_match(lu, ru); + + // rjf: if keys don't match, type *contents* could still match, + // so we need to unpack the type info & compare + if(!result) + { + E_TypeKind luk = e_type_kind_from_key(lu); + E_TypeKind ruk = e_type_kind_from_key(ru); + if(luk == ruk) + { + switch(luk) + { + default: + { + result = 1; + }break; + + case E_TypeKind_Ptr: + case E_TypeKind_LRef: + case E_TypeKind_RRef: + { + E_TypeKey lud = e_type_key_direct(lu); + E_TypeKey rud = e_type_key_direct(ru); + result = e_type_match(lud, rud); + }break; + + case E_TypeKind_MemberPtr: + { + E_TypeKey lud = e_type_key_direct(lu); + E_TypeKey rud = e_type_key_direct(ru); + E_TypeKey luo = e_type_key_owner(lu); + E_TypeKey ruo = e_type_key_owner(ru); + result = (e_type_match(lud, rud) && e_type_match(luo, ruo)); + }break; + + case E_TypeKind_Array: + { + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); + if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) + { + result = 1; + } + }break; + + case E_TypeKind_Function: + { + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); + if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) + { + B32 params_match = 1; + E_TypeKey *lp = lt->param_type_keys; + E_TypeKey *rp = rt->param_type_keys; + U64 count = lt->count; + for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) + { + if(!e_type_match(*lp, *rp)) + { + params_match = 0; + break; + } + } + result = params_match; + } + }break; + + case E_TypeKind_Method: + { + E_Type *lt = e_type_from_key__cached(l); + E_Type *rt = e_type_from_key__cached(r); + if(lt->count == rt->count && + e_type_match(lt->direct_type_key, rt->direct_type_key) && + e_type_match(lt->owner_type_key, rt->owner_type_key)) + { + B32 params_match = 1; + E_TypeKey *lp = lt->param_type_keys; + E_TypeKey *rp = rt->param_type_keys; + U64 count = lt->count; + for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) + { + if(!e_type_match(*lp, *rp)) + { + params_match = 0; + break; + } + } + result = params_match; + } + }break; + } + } + } + + return result; +} + +//- rjf: key -> string + internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return) { @@ -1722,7 +1664,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Array: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 2, skip_return); if(prec == 1) { @@ -1734,7 +1676,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { if(!skip_return) { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 2, 0); } if(prec == 1) @@ -1747,7 +1689,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { E_Type *type = e_type_from_key__cached(key); str8_list_pushf(arena, out, "%S(", type->name); - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); String8 direct_string = e_type_string_from_key(arena, direct); str8_list_push(arena, out, direct_string); for EachIndex(idx, type->count) @@ -1761,7 +1703,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Ptr: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("*")); E_Type *type = e_type_from_key__cached(key); @@ -1773,14 +1715,14 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_LRef: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("&")); }break; case E_TypeKind_RRef: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("&&")); }break; @@ -1804,7 +1746,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_MetaExpr: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, prec, skip_return); }break; } @@ -1820,7 +1762,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Bitfield: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_rhs_string_from_key(arena, direct, out, prec); }break; @@ -1830,7 +1772,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_RRef: case E_TypeKind_MemberPtr: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_rhs_string_from_key(arena, direct, out, 1); }break; @@ -1845,7 +1787,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, str8_lit("[")); str8_list_push(arena, out, count_str); str8_list_push(arena, out, str8_lit("]")); - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; @@ -1878,13 +1820,13 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr } str8_list_push(arena, out, str8_lit(")")); } - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; case E_TypeKind_MetaExpr: { - E_TypeKey direct = e_type_direct_from_key(key); + E_TypeKey direct = e_type_key_direct(key); e_type_rhs_string_from_key(arena, direct, out, prec); }break; } @@ -1910,7 +1852,7 @@ e_default_expansion_type_from_key(E_TypeKey root_key) B32 hit_1ptr = 0; for(E_TypeKey key = root_key; !e_type_key_match(e_type_key_zero(), key); - key = e_type_direct_from_key(key)) + key = e_type_key_direct(key)) { B32 done = 1; E_TypeKind kind = e_type_kind_from_key(key); @@ -2388,21 +2330,8 @@ E_TYPE_IREXT_FUNCTION_DEF(slice) { Temp scratch = scratch_begin(&arena, 1); - // rjf: unpack struct type - E_TypeKey struct_type_key = e_type_unwrap(irtree->type_key); - for(;;) - { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key))) - { - struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key)); - } - else - { - break; - } - } - // rjf: build info from struct type + E_TypeKey struct_type_key = e_type_key_unwrap(irtree->type_key, E_TypeUnwrapFlag_All); E_TypeKind type_kind = e_type_kind_from_key(struct_type_key); if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class) { @@ -2416,7 +2345,7 @@ E_TYPE_IREXT_FUNCTION_DEF(slice) for(U64 idx = 0; idx < members.count; idx += 1) { E_Member *member = &members.v[idx]; - E_TypeKey member_type = e_type_unwrap(member->type_key); + E_TypeKey member_type = e_type_key_unwrap(member->type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind member_type_kind = e_type_kind_from_key(member_type); if(count_member == 0 && e_type_kind_is_integer(member_type_kind)) { @@ -2479,7 +2408,7 @@ E_TYPE_IREXT_FUNCTION_DEF(slice) E_TypeKey element_type_key = zero_struct; if(base_ptr_member != 0) { - element_type_key = e_type_direct_from_key(base_ptr_member->type_key); + element_type_key = e_type_key_direct(base_ptr_member->type_key); } // rjf: if no count, but base/opl, swap base/opl if needed, and measure count diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index c606c1be..bdc52766 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -29,6 +29,22 @@ struct E_String2TypeKeyMap E_String2TypeKeySlot *slots; }; +//////////////////////////////// +//~ rjf: Type Unwrapping + +typedef U32 E_TypeUnwrapFlags; +enum +{ + E_TypeUnwrapFlag_Modifiers = (1<<0), + E_TypeUnwrapFlag_Pointers = (1<<1), + E_TypeUnwrapFlag_Lenses = (1<<2), + E_TypeUnwrapFlag_Meta = (1<<3), + E_TypeUnwrapFlag_Enums = (1<<4), + E_TypeUnwrapFlag_Aliases = (1<<5), + E_TypeUnwrapFlag_All = 0xffffffff, + E_TypeUnwrapFlag_AllDecorative = (E_TypeUnwrapFlag_All & ~E_TypeUnwrapFlag_Pointers) +}; + //////////////////////////////// //~ rjf: Evaluation Context @@ -245,22 +261,24 @@ internal E_TypeKey e_type_key_folder(void); //- rjf: basic type key functions internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); -//- rjf: key -> info extraction +//- rjf: type key -> info extraction internal U64 e_hash_from_type(E_Type *type); internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key); internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); -internal E_TypeKey e_type_direct_from_key(E_TypeKey key); -internal E_TypeKey e_type_owner_from_key(E_TypeKey key); -internal E_TypeKey e_type_ptee_from_key(E_TypeKey key); -internal E_TypeKey e_type_unwrap_enum(E_TypeKey key); -internal E_TypeKey e_type_unwrap(E_TypeKey key); -internal E_TypeKey e_type_promote(E_TypeKey key); -internal B32 e_type_match(E_TypeKey l, E_TypeKey r); -internal E_Member *e_type_member_copy(Arena *arena, E_Member *src); internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b); internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key); -internal E_Member *e_type_member_from_array_name(E_MemberArray *members, String8 name); + +//- rjf: type key traversal +internal E_TypeKey e_type_key_direct(E_TypeKey key); +internal E_TypeKey e_type_key_owner(E_TypeKey key); +internal E_TypeKey e_type_key_promote(E_TypeKey key); +internal E_TypeKey e_type_key_unwrap(E_TypeKey key, E_TypeUnwrapFlags flags); + +//- rjf: type comparisons +internal B32 e_type_match(E_TypeKey l, E_TypeKey r); + +//- rjf: type key -> string internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return); internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec); internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index d22ca1a3..ee581c25 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -105,7 +105,7 @@ ev_type_key_is_editable(E_TypeKey type_key) { B32 result = 0; B32 done = 0; - for(E_TypeKey t = type_key; !result && !done; t = e_type_direct_from_key(t)) + for(E_TypeKey t = type_key; !result && !done; t = e_type_key_direct(t)) { E_TypeKind kind = e_type_kind_from_key(t); switch(kind) @@ -132,7 +132,7 @@ ev_type_key_is_editable(E_TypeKey type_key) } else { - E_TypeKind element_kind = e_type_kind_from_key(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))); + E_TypeKind element_kind = e_type_kind_from_key(e_type_key_unwrap(t, E_TypeUnwrapFlag_All)); result = (element_kind == E_TypeKind_U8 || element_kind == E_TypeKind_U16 || element_kind == E_TypeKind_U32 || @@ -403,7 +403,7 @@ ev_expand_rule_from_type_key(E_TypeKey type_key) { E_TypeKey k = type_key; E_TypeKind kind = e_type_kind_from_key(k); - for(;kind == E_TypeKind_Lens; k = e_type_direct_from_key(k), kind = e_type_kind_from_key(k)) + for(;kind == E_TypeKind_Lens; k = e_type_key_direct(k), kind = e_type_kind_from_key(k)) { E_Type *type = e_type_from_key__cached(k); EV_ExpandRule *candidate = ev_expand_rule_from_string(type->name); @@ -430,7 +430,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) E_Eval eval = e_eval_from_expr(scratch.arena, expr); E_TypeKey type_key = eval.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey ptee_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key))); + E_TypeKey ptee_type_key = e_type_unwrap(e_type_key_direct(e_type_unwrap(type_key))); E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) { @@ -1287,7 +1287,7 @@ internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval eval) { String8 result = {0}; - E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); + E_TypeKey type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); E_TypeKind type_kind = e_type_kind_from_key(type_key); U64 type_byte_size = e_type_byte_size_from_key(type_key); U8 digit_group_separator = 0; @@ -1598,7 +1598,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_pop = 1; new_task.params = lens_params; new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); } else if(type->expand.info != 0) { @@ -1614,7 +1614,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_pop = 1; new_task.params = lens_params; new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); #if 0 // NOTE(rjf): will explicitly visualize lenses in value strings. does not seem useful for now? switch(task_idx) { @@ -1643,7 +1643,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_pop = 0; new_task.params = *params; new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); scratch_end(scratch); }break; @@ -1669,16 +1669,17 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) default:{}break; case 0: { + E_Type *type = e_type_from_key__cached(type_key); + *out_string = push_str8f(arena, "%S (", type->name); need_pop = 0; need_new_task = 1; new_task.params = *params; new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); }break; case 1: { - E_Type *type = e_type_from_key__cached(type_key); - *out_string = push_str8f(arena, " (%S)", type->name); + *out_string = str8_lit(")"); }break; } } @@ -1698,7 +1699,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_new_task = 1; new_task.params = *params; new_task.eval = eval; - new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); }break; ////////////////////////// @@ -1733,7 +1734,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) ptr_data = it->top_task->user_data = push_array(arena, EV_StringPtrData, 1); ptr_data->value_eval = e_value_eval_from_eval(eval); ptr_data->type = e_type_from_key__cached(type_key); - ptr_data->direct_type = e_type_from_key__cached(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key)))); + ptr_data->direct_type = e_type_from_key__cached(e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All)); ptr_data->ptee_has_content = (ptr_data->value_eval.value.u64 != 0 && ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || ptr_data->direct_type->kind == E_TypeKind_S8 || diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e54c48c1..3be74495 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1915,9 +1915,9 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) Temp scratch = scratch_begin(0, 0); //- rjf: unpack type of destination - E_TypeKey type_key = e_type_unwrap(dst_eval.irtree.type_key); + E_TypeKey type_key = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(dst_eval.irtree.type_key))); + E_TypeKey direct_type_key = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_All); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); //- rjf: determine data we'll write @@ -4001,7 +4001,8 @@ rd_view_ui(Rng2F32 rect) RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - E_Type *cell_type = e_type_from_key__cached(cell_info.eval.irtree.type_key); + E_TypeKey cell_type_key = cell_info.eval.irtree.type_key; + E_Type *cell_type = e_type_from_key__cached(cell_type_key); E_Eval cell_value_eval = e_value_eval_from_eval(cell_info.eval); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; @@ -4022,7 +4023,7 @@ rd_view_ui(Rng2F32 rect) E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; e_ir_state->overridden_irtree = &cell_info.eval.irtree; { - E_TypeKey slider_value_type = e_type_unwrap(cell_type->direct_type_key); + E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); slider_value_type_kind = e_type_kind_from_key(slider_value_type); E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); @@ -10774,7 +10775,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) E_Eval eval = e_eval_from_string(scratch.arena, string); if(eval.msgs.max_kind == E_MsgKind_Null) { - E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)); + E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); if(eval_type_kind == E_TypeKind_Ptr || eval_type_kind == E_TypeKind_LRef || eval_type_kind == E_TypeKind_RRef) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index bc90f40d..325e00db 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -370,7 +370,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_U64); E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafU64) + if(expr->kind != E_ExprKind_LeafU64 && expr != &e_expr_nil) { child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); } @@ -381,7 +381,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_F32); E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafF32 && expr->kind != E_ExprKind_LeafF64) + if(expr->kind != E_ExprKind_LeafF32 && expr->kind != E_ExprKind_LeafF64 && expr != &e_expr_nil) { child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); } @@ -392,7 +392,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_Bool); E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafU64) + if(expr->kind != E_ExprKind_LeafU64 && expr != &e_expr_nil) { child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d39c9a4d..5c6220ee 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1257,7 +1257,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == E_SpaceKind_File) { if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Array && - e_type_kind_from_key(e_type_direct_from_key(row->eval.irtree.type_key)) == E_TypeKind_U8) + e_type_kind_from_key(e_type_key_direct(row->eval.irtree.type_key)) == E_TypeKind_U8) { info.can_expand = 0; } From 1679aa6f646f670f905648958fdc69e22b8c4114 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 11:50:36 -0700 Subject: [PATCH 374/755] fix up / simplify decision path to wrap cfg evaluations with meta-expr type --- src/raddbg/raddbg_eval.c | 52 ++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 325e00db..51095516 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -326,6 +326,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) CTRL_Entity *entity = ext->entity; RD_Cfg *child = rd_cfg_child_from_string(cfg, child_schema->string); E_TypeKey child_type_key = zero_struct; + B32 wrap_child_w_meta_expr = 0; if(0){} //- rjf: ctrl entity members @@ -367,36 +368,18 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) //- rjf: catchall cases else if(str8_match(child_schema->first->string, str8_lit("u64"), 0)) { - Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_U64); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafU64 && expr != &e_expr_nil) - { - child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); - } - scratch_end(scratch); + wrap_child_w_meta_expr = 1; } else if(str8_match(child_schema->first->string, str8_lit("f32"), 0)) { - Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_F32); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafF32 && expr->kind != E_ExprKind_LeafF64 && expr != &e_expr_nil) - { - child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); - } - scratch_end(scratch); + wrap_child_w_meta_expr = 1; } else if(str8_match(child_schema->first->string, str8_lit("bool"), 0)) { - Temp scratch = scratch_begin(&arena, 1); child_type_key = e_type_key_basic(E_TypeKind_Bool); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; - if(expr->kind != E_ExprKind_LeafU64 && expr != &e_expr_nil) - { - child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); - } - scratch_end(scratch); + wrap_child_w_meta_expr = 1; } else if(str8_match(child_schema->first->string, str8_lit("vaddr_range"), 0)) { @@ -413,6 +396,33 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) child_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, child_schema->string); } + //- rjf: extend child type with meta-expression information + if(wrap_child_w_meta_expr) + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + B32 expr_is_simple = 0; + if(expr->kind == E_ExprKind_LeafU64 || + expr->kind == E_ExprKind_LeafF64 || + expr->kind == E_ExprKind_LeafF32) + { + expr_is_simple = 1; + } + if((expr->kind == E_ExprKind_Pos || expr->kind == E_ExprKind_Neg) && + expr->first == expr->last && + (expr->first->kind == E_ExprKind_LeafU64 || + expr->first->kind == E_ExprKind_LeafF64 || + expr->first->kind == E_ExprKind_LeafF32)) + { + expr_is_simple = 1; + } + if(!expr_is_simple && expr != &e_expr_nil) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); + } + scratch_end(scratch); + } + //- rjf: extend child type with ranges MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); if(!md_node_is_nil(range)) From 85f715f2ba92b0d08f085dfe52ef03c88c37f8ab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 13:07:59 -0700 Subject: [PATCH 375/755] revert to single expression from parse, but keep chains as implicit extension to expressions; use chained expressions to look up shorthands for hex, dec, bin, array counts, etc. --- src/eval/eval_bundles.c | 6 ++-- src/eval/eval_core.h | 2 +- src/eval/eval_ir.c | 66 +++++++++++++++++++++++++++++++++------ src/eval/eval_parse.c | 53 ++++++++++++++++--------------- src/eval/eval_parse.h | 3 +- src/raddbg/raddbg_core.c | 10 +++--- src/raddbg/raddbg_eval.c | 14 ++++----- src/raddbg/raddbg_views.c | 2 +- 8 files changed, 103 insertions(+), 53 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 4e056cb1..3acca27f 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -35,7 +35,7 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); - E_Eval eval = e_eval_from_expr(arena, parse.exprs.first); + E_Eval eval = e_eval_from_expr(arena, parse.expr); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } @@ -337,7 +337,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) S32 indent; }; str8_list_pushf(scratch.arena, &strings, " expr:\n"); - Task start_task = {0, parse.exprs.first, 2}; + Task start_task = {0, parse.expr, 2}; Task *first_task = &start_task; for(Task *t = first_task; t != 0; t = t->next) { @@ -370,7 +370,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.first); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 483a9409..a1078495 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -514,7 +514,7 @@ struct E_AutoHookNode E_AutoHookNode *pattern_order_next; String8 type_string; String8List type_pattern_parts; - E_ExprChain tag_exprs; + E_Expr *expr; }; typedef struct E_AutoHookSlot E_AutoHookSlot; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9838c363..902a90f0 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -123,14 +123,14 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); type_key = irtree.type_key; } 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->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; + node->expr = e_parse_expr_from_text(arena, push_str8_copy(arena, 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); @@ -164,10 +164,7 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { if(str8_match(n->type_string, type_string, 0)) { - for(E_Expr *e = n->tag_exprs.first; e != &e_expr_nil; e = e->next) - { - e_expr_list_push(arena, &exprs, e); - } + e_expr_list_push(arena, &exprs, n->expr); } } } @@ -197,10 +194,7 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } if(fits_this_type_string) { - for(E_Expr *e = auto_hook_node->tag_exprs.first; e != &e_expr_nil; e = e->next) - { - e_expr_list_push(arena, &exprs, e); - } + e_expr_list_push(arena, &exprs, auto_hook_node->expr); } } } @@ -2253,6 +2247,58 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; } + //- rjf: check chained expressions for simple wrappers + { + struct + { + String8 shorthand; + String8 full_name; + } + shorthand_lens_pair_table[] = + { + {str8_lit("x"), str8_lit("hex")}, + {str8_lit("b"), str8_lit("bin")}, + {str8_lit("o"), str8_lit("oct")}, + {str8_lit("d"), str8_lit("dec")}, + }; + for(E_Expr *chained_expr = expr->next; + chained_expr != &e_expr_nil; + chained_expr = chained_expr->next) + { + B32 matches_shorthand = 0; + if(chained_expr->kind == E_ExprKind_LeafIdentifier) + { + for EachElement(shorthand_idx, shorthand_lens_pair_table) + { + if(str8_match(chained_expr->string, shorthand_lens_pair_table[shorthand_idx].shorthand, 0)) + { + String8 full_name = shorthand_lens_pair_table[shorthand_idx].full_name; + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .direct_key = result.type_key, + .name = full_name); + matches_shorthand = 1; + break; + } + } + } + if(!matches_shorthand && e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative)))) + { + E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); + E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; + E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lens_spec_type->flags, + .count = 1, + .args = &chained_expr, + .direct_key = result.type_key, + .name = lens_spec_type->name, + .irext = lens_spec_type->irext, + .access = lens_spec_type->access, + .expand = lens_spec_type->expand); + } + } + } + //- rjf: if the evaluated type has a hook for an extra layer of ir extension, // call into it E_Type *type = e_type_from_key__cached(result.type_key); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index fbbae582..7c9bf0cc 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -798,14 +798,14 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) } // rjf: construct leaf type - parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - parse.exprs.first->type_key = type_key; + parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.expr->type_key = type_key; } } } //- rjf: parse extensions - if(parse.exprs.first != &e_expr_nil) + if(parse.expr != &e_expr_nil) { for(;;) { @@ -818,9 +818,9 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) if(str8_match(token_string, str8_lit("*"), 0)) { token_it += 1; - E_Expr *ptee = parse.exprs.first; - parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); - e_expr_push_child(parse.exprs.first, ptee); + E_Expr *ptee = parse.expr; + parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(parse.expr, ptee); } else { @@ -941,7 +941,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse type expr E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); - E_Expr *type = type_parse.exprs.last; + E_Expr *type = type_parse.expr; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; @@ -1029,7 +1029,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse () contents E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.exprs.last; + atom = nested_parse.expr; it = nested_parse.last_token; // rjf: expect ) @@ -1058,11 +1058,11 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse [] contents E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.exprs.last; + atom = nested_parse.expr; it = nested_parse.last_token; // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.exprs.last == &e_expr_nil) + if(nested_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); } @@ -1253,10 +1253,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it = idx_expr_parse.last_token; // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.exprs.last != &e_expr_nil) + if(idx_expr_parse.expr != &e_expr_nil) { E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.exprs.last; + E_Expr *index_expr = idx_expr_parse.expr; atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); e_expr_push_child(atom, array_expr); e_expr_push_child(atom, index_expr); @@ -1294,11 +1294,14 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; - if(args_parse.exprs.first != &e_expr_nil) + if(args_parse.expr != &e_expr_nil) { - call_expr->last->next = args_parse.exprs.first; - args_parse.exprs.first->prev = call_expr->last; - call_expr->last = args_parse.exprs.last; + call_expr->last->next = args_parse.expr; + args_parse.expr->prev = call_expr->last; + for(E_Expr *arg = args_parse.expr; arg != &e_expr_nil; arg = arg->next) + { + call_expr->last = arg; + } } atom = call_expr; @@ -1388,7 +1391,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok { E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.exprs.last; + E_Expr *rhs = rhs_expr_parse.expr; it = rhs_expr_parse.last_token; if(rhs == &e_expr_nil) { @@ -1413,9 +1416,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse middle expression E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.exprs.last; + E_Expr *middle_expr = middle_expr_parse.expr; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.exprs.last == &e_expr_nil) + if(middle_expr_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); } @@ -1446,7 +1449,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok { it = rhs_expr_parse.last_token; e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.exprs.last == &e_expr_nil) + if(rhs_expr_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); } @@ -1454,12 +1457,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: build ternary if(atom != &e_expr_nil && - middle_expr_parse.exprs.last != &e_expr_nil && - rhs_expr_parse.exprs.last != &e_expr_nil) + middle_expr_parse.expr != &e_expr_nil && + rhs_expr_parse.expr != &e_expr_nil) { E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.exprs.last; - E_Expr *rhs = rhs_expr_parse.exprs.last; + E_Expr *mhs = middle_expr_parse.expr; + E_Expr *rhs = rhs_expr_parse.expr; atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); e_expr_push_child(atom, lhs); e_expr_push_child(atom, mhs); @@ -1478,7 +1481,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok //- rjf: store parsed atom to expression chain - if we didn't get an expression, break if(atom != &e_expr_nil) { - DLLPushBack_NPZ(&e_expr_nil, result.exprs.first, result.exprs.last, atom, next, prev); + DLLPushBack_NPZ(&e_expr_nil, result.expr, result.last_expr, atom, next, prev); chain_count += 1; } else diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 493dbad7..84f26343 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -11,7 +11,8 @@ typedef struct E_Parse E_Parse; struct E_Parse { E_Token *last_token; - E_ExprChain exprs; + E_Expr *expr; + E_Expr *last_expr; E_MsgList msgs; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3be74495..7c211371 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1942,7 +1942,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) type_kind == E_TypeKind_Enum)) { got_commit_data = 1; - E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).expr; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); @@ -2096,7 +2096,7 @@ rd_query_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).expr; if(expr->kind == E_ExprKind_LeafIdentifier && str8_match(expr->qualifier, str8_lit("query"), 0)) { @@ -12045,7 +12045,7 @@ rd_frame(void) //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' { - E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).exprs.first; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).expr; e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } @@ -12247,7 +12247,7 @@ rd_frame(void) E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); if(parse.msgs.max_kind == E_MsgKind_Null) { - for(E_Expr *expr = parse.exprs.first; expr != &e_expr_nil; expr = expr->next) + for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) { e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); } @@ -15707,7 +15707,7 @@ Z(getting_started) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).exprs.last; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).expr; ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 51095516..5c61ffa4 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -136,7 +136,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) if(cfg_idx < cfgs->count) { String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -218,7 +218,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) for(U64 idx = 0; idx < read_range_count; idx += 1) { String8 expr_string = accel->v[read_range.min + idx]; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -270,7 +270,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) String8 register_name = accel->v[read_range.min + idx]; String8 register_expr = push_str8f(arena, "reg:%S", register_name); exprs_strings_out[idx] = register_name; - exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; + exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).expr; } } @@ -400,7 +400,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(wrap_child_w_meta_expr) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).expr; B32 expr_is_simple = 0; if(expr->kind == E_ExprKind_LeafU64 || expr->kind == E_ExprKind_LeafF64 || @@ -428,8 +428,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(!md_node_is_nil(range)) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).exprs.first; - E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).exprs.first; + E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).expr; + E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).expr; E_Expr *args[] = { min_bound, @@ -689,7 +689,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).expr; E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5c6220ee..90bfa3fa 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1445,7 +1445,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla E_Expr *root_expr = row->eval.expr; if(wrap_string.size != 0) { - E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).exprs.last; + E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).expr; root_expr = wrap_expr; typedef struct Task Task; struct Task From 82ec25ad19f906174cd7f03336ab1f5b5dc4b421 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 13:31:11 -0700 Subject: [PATCH 376/755] table lens --- .../eval_visualization_core.c | 42 +++++++++++-------- .../eval_visualization_core.h | 1 + src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_views.c | 42 +++++++++++++++++++ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ee581c25..c2c14195 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1063,29 +1063,37 @@ ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRang return rows; } +internal B32 +ev_eval_is_expandable(E_Eval eval) +{ + B32 result = 0; + E_IRTreeAndType irtree = eval.irtree; + + // rjf: determine if lenses force expandability + if(!result) + { + EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(irtree.type_key); + if(expand_rule != &ev_nil_expand_rule) + { + result = 1; + } + } + + // rjf: determine if type info force expandability + if(!result) + { + result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); + } + return result; +} + internal B32 ev_row_is_expandable(EV_Row *row) { B32 result = 0; if(!ev_key_match(ev_key_root(), row->block->key)) { - E_IRTreeAndType irtree = row->eval.irtree; - - // rjf: determine if lenses force expandability - if(!result) - { - EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(irtree.type_key); - if(expand_rule != &ev_nil_expand_rule) - { - result = 1; - } - } - - // rjf: determine if type info force expandability - if(!result) - { - result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); - } + result = ev_eval_is_expandable(row->eval); } return result; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 3967e505..2def910b 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -369,6 +369,7 @@ internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx); internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); +internal B32 ev_eval_is_expandable(E_Eval eval); internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7c211371..40365af8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12330,6 +12330,7 @@ rd_frame(void) {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, + {str8_lit("table"), 0, 0, 0, 0, 0, {0}}, {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 90bfa3fa..33951338 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1053,10 +1053,52 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: determine view ui rule info.view_ui_rule = rd_view_ui_rule_from_string(row->block->viz_expand_rule->string); + // rjf: find possible table type + E_Type *maybe_table_type = block_type; + for(;;) + { + if(maybe_table_type->kind == E_TypeKind_Lens && + str8_match(maybe_table_type->name, str8_lit("table"), 0)) + { + break; + } + else if(maybe_table_type->kind == E_TypeKind_Lens) + { + maybe_table_type = e_type_from_key__cached(maybe_table_type->direct_type_key); + continue; + } + else + { + break; + } + } + // rjf: fill row's cells { if(0){} + // rjf: table rows + else if(maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) + { + U64 column_count = maybe_table_type->count; + info.cell_style_key = push_str8f(arena, "table_%I64u_cols", column_count); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &row->eval.irtree; + for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + { + E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + } + e_ir_state->overridden_irtree = prev_overridden_irtree; + info.can_expand = 0; +#undef take_pct + } + // rjf: folder / file rows else if(row->eval.space.kind == E_SpaceKind_FileSystem) { From 923f55fb2b61c8f647d516b2cfa8d7e383b163b9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 14:18:21 -0700 Subject: [PATCH 377/755] correctly treat chains of lenses when looking up type hooks; allow type-evaluations when producing per-cell evaluations --- src/eval/eval_ir.c | 33 +++++++++++++++---- .../eval_visualization_core.c | 10 ++++++ src/raddbg/raddbg_views.c | 4 +-- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 902a90f0..5ede2ff9 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -946,6 +946,16 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: pick access hook based on type E_Type *lhs_type = e_type_from_key__cached(lhs_irtree_try->type_key); E_TypeAccessFunctionType *lhs_access = lhs_type->access; + for(E_Type *lens_type = lhs_type; + lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; + lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + { + if(lens_type->access != 0) + { + lhs_access = lens_type->access; + break; + } + } if(lhs_access == 0) { lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); @@ -2302,15 +2312,26 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: if the evaluated type has a hook for an extra layer of ir extension, // call into it E_Type *type = e_type_from_key__cached(result.type_key); - if(type->kind != E_TypeKind_LensSpec && type->irext != 0) { - E_IRTreeAndType irtree_stripped = result; - if(type->kind == E_TypeKind_Lens) + E_TypeIRExtFunctionType *irext = type->irext; + for(E_Type *t = type; t->kind == E_TypeKind_Lens || t->kind == E_TypeKind_Set; t = e_type_from_key__cached(t->direct_type_key)) { - irtree_stripped.type_key = e_type_key_direct(irtree_stripped.type_key); + if(t->irext != 0) + { + irext = t->irext; + break; + } + } + if(irext != 0) + { + E_IRTreeAndType irtree_stripped = result; + if(type->kind == E_TypeKind_Lens) + { + irtree_stripped.type_key = e_type_key_direct(irtree_stripped.type_key); + } + E_IRExt ext = irext(arena, expr, &irtree_stripped); + result.user_data = ext.user_data; } - E_IRExt ext = type->irext(arena, expr, &irtree_stripped); - result.user_data = ext.user_data; } //- rjf: equip previous task's irtree diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index c2c14195..c9e80938 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -562,6 +562,16 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp { type_expand_rule = &type->expand; } + for(E_Type *lens_type = type; + lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; + lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + { + if(lens_type->expand.info != 0) + { + type_expand_rule = &lens_type->expand; + break; + } + } // rjf: get eval's visualization expansion rule EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(type_key); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 33951338..fe4ecc58 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1404,7 +1404,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.flags |= RD_WatchCellFlag_CanEdit; } - result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); + result.eval = (!e_type_key_match(cell->eval.irtree.type_key, e_type_key_zero()) ? cell->eval : row->eval); result.string = row->string; if(result.string.size == 0) { @@ -1525,7 +1525,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } //- rjf: evaluate wrapped expression - result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); + result.eval = (!e_type_key_match(cell->eval.irtree.type_key, e_type_key_zero()) ? cell->eval : e_eval_from_expr(arena, root_expr)); //- rjf: determine string generation parameters based on evaluation EV_StringParams string_params = {string_flags, 10}; From b9ef453a14c0e2a669cdfeac2f1cb66f3379975c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 15 Apr 2025 16:27:44 -0700 Subject: [PATCH 378/755] eval visualization - allow chained expressions to cause multiple child expansion blocks; begin work on unified lister watch window --- src/eval/eval_parse.c | 14 ++++++++++++++ .../eval_visualization_core.c | 19 +++++++++++++++++-- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 13 +++---------- src/raddbg/raddbg_eval.c | 4 ++-- src/raddbg/raddbg_widgets.c | 4 ++-- 7 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 7c9bf0cc..9c353772 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -409,6 +409,7 @@ e_expr_copy(Arena *arena, E_Expr *src) E_Expr *dst_parent; E_Expr *src; B32 is_ref; + B32 is_sib; }; Task start_task = {0, &e_expr_nil, src}; Task *first_task = &start_task; @@ -431,10 +432,23 @@ e_expr_copy(Arena *arena, E_Expr *src) { t->dst_parent->ref = dst; } + else if(t->is_sib) + { + t->dst_parent->next = dst; + dst->prev = t->dst_parent; + } else { e_expr_push_child(t->dst_parent, dst); } + if(t->src->next != &e_expr_nil) + { + Task *task = push_array(scratch.arena, Task, 1); + task->dst_parent = dst; + task->src = t->src->next; + task->is_sib = 1; + SLLQueuePush(first_task, last_task, task); + } if(t->src->ref != &e_expr_nil) { Task *task = push_array(scratch.arena, Task, 1); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index c9e80938..5a095cbf 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -520,7 +520,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp tree.total_row_count += 1; tree.total_item_count += 1; - //- rjf: iterate all expansions & generate blocks for each + //- rjf: generate initial task, for root's evaluation typedef struct Task Task; struct Task { @@ -534,6 +534,8 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp Task start_task = {0, tree.root, tree.root->eval, 1, 0}; Task *first_task = &start_task; Task *last_task = first_task; + + //- rjf: iterate all expansions & generate blocks for each for(Task *t = first_task; t != 0; t = t->next) { // rjf: get task key @@ -714,6 +716,19 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp } } } + + // rjf: if this expr has a sibling, push another task to continue the chain + if(t->eval.expr->next != &e_expr_nil) + { + Task *task = push_array(scratch.arena, Task, 1); + task->next = t->next; + t->next = task; + task->parent_block = t->parent_block; + task->eval = e_eval_from_expr(arena, t->eval.expr->next); + task->child_id = t->child_id; + task->split_relative_idx = 0; + task->default_expanded = t->default_expanded; + } } scratch_end(scratch); } @@ -797,7 +812,7 @@ ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree) // rjf: generate task for post-child rows, if any, after children Rng1U64 remainder_range = r1u64(t->next_child->split_relative_idx+1, t->block_relative_range.max); - if(remainder_range.max > remainder_range.min) + if(remainder_range.max >= remainder_range.min) { BlockTask *remainder_task = push_array(scratch.arena, BlockTask, 1); remainder_task->next = child_task->next; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c8476d82..f033bd3a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -426,7 +426,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[215] = { str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:lister"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 966e7bb7..826a785b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -450,7 +450,7 @@ RD_CmdTable: // | | | | {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } //- rjf: top-level lister - {OpenLister 1 1 "query:lister" Null null Nil Null 0 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } + {OpenLister 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } //- rjf: command runner {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 40365af8..22c8ca4a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12492,18 +12492,11 @@ rd_frame(void) #endif }break; - //- rjf: top-level lister + //- rjf: open lister case RD_CmdKind_OpenLister: { - RD_ListerFlags lister_flags = (RD_ListerFlag_LineEdit| - RD_ListerFlag_Descriptions| - RD_ListerFlag_KindLabel| - RD_ListerFlag_Procedures| - RD_ListerFlag_Files| - RD_ListerFlag_Commands| - RD_ListerFlag_Settings| - RD_ListerFlag_SystemProcesses); - rd_cmd(RD_CmdKind_PushQuery, .lister_flags = lister_flags); + String8 expr = push_str8f(scratch.arena, "query:commands, query:recent_files, query:recent_projects, query:procedures, query:$%I64x", rd_regs()->view); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1); }break; //- rjf: command fast path diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 5c61ffa4..e87c0ac8 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -29,7 +29,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) } else { - result.expr_count = RD_CmdKind_COUNT; + result.expr_count = RD_CmdKind_COUNT - 1; } return result; } @@ -67,7 +67,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) { for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { - RD_CmdKind cmd_kind = (RD_CmdKind)idx; + RD_CmdKind cmd_kind = (RD_CmdKind)(idx+1); String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index e849459d..536ad443 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3235,8 +3235,8 @@ rd_cell(RD_CellParams *params, String8 string) { B32 is_toggled = !!params->toggled_out[0]; F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); - F32 padding_px = floor_f32(ui_top_font_size()*0.65f); - F32 height_px = ui_top_px_height() - padding_px*2.f; + F32 height_px = ui_top_font_size() * 1.75f; + F32 padding_px = (ui_top_px_height() - height_px) / 2.f; UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) From 2a456962949e5b843f7e2bd77155a0218844a951 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 16 Apr 2025 11:02:04 -0700 Subject: [PATCH 379/755] matrix table visualization test --- src/mule/mule_main.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index cf532a54..2f3cd9de 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -181,6 +181,13 @@ union Vector_R2{ float v[2]; }; +typedef union Matrix4x4F32 Matrix4x4F32; +union Matrix4x4F32 +{ + float elements[4][4]; +}; +raddbg_auto_view_rule(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); + enum Kind{ Kind_None, Kind_First, @@ -366,6 +373,16 @@ type_coverage_eval_tests(void) Function_Few_Params_Type **ptr_ptr_few_params = &ptr_few_params; Callback callback = {few_params1, no_params1, {1, 2.f}}; + Matrix4x4F32 matrix = + { + { + {1.f, 0.f, 0.f, 0.f}, + {0.f, 1.f, 0.f, 0.f}, + {0.f, 0.f, 1.f, 0.f}, + {0.f, 0.f, 0.f, 1.f}, + } + }; + Vector_R2 vector = {1.f, 2.f}; Has_Enums has_enums = {(Kind)4, (Flag)7}; From 51f46cb5b83e6c7d30de5fcaa2f4c97da91a871c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 16 Apr 2025 11:13:30 -0700 Subject: [PATCH 380/755] eliminate extra view rule channel in rd_regs/hover-eval/watch-pins/etc. --- src/raddbg/generated/raddbg.meta.c | 3 +- src/raddbg/generated/raddbg.meta.h | 5 +-- src/raddbg/raddbg.mdesk | 57 +++++++++++++++--------------- src/raddbg/raddbg_core.c | 23 +++--------- src/raddbg/raddbg_core.h | 4 +-- src/raddbg/raddbg_widgets.c | 9 ++--- 6 files changed, 38 insertions(+), 63 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f033bd3a..be65f051 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -344,7 +344,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[42] = +Rng1U64 rd_reg_slot_range_table[41] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -373,7 +373,6 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)}, {OffsetOf(RD_Regs, voff_range), OffsetOf(RD_Regs, voff_range) + sizeof(Rng1U64)}, {OffsetOf(RD_Regs, expr), OffsetOf(RD_Regs, expr) + sizeof(String8)}, -{OffsetOf(RD_Regs, view_rule), OffsetOf(RD_Regs, view_rule) + sizeof(String8)}, {OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)}, {OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)}, {OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index c3feb1ad..4829e52f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -35,7 +35,6 @@ RD_RegSlot_Voff, RD_RegSlot_VaddrRange, RD_RegSlot_VoffRange, RD_RegSlot_Expr, -RD_RegSlot_ViewRule, RD_RegSlot_UIKey, RD_RegSlot_OffPx, RD_RegSlot_ListerFlags, @@ -562,7 +561,6 @@ U64 voff; Rng1U64 vaddr_range; Rng1U64 voff_range; String8 expr; -String8 view_rule; UI_Key ui_key; Vec2F32 off_px; RD_ListerFlags lister_flags; @@ -627,7 +625,6 @@ RD_Query query; .vaddr_range = rd_regs()->vaddr_range,\ .voff_range = rd_regs()->voff_range,\ .expr = rd_regs()->expr,\ -.view_rule = rd_regs()->view_rule,\ .ui_key = rd_regs()->ui_key,\ .off_px = rd_regs()->off_px,\ .lister_flags = rd_regs()->lister_flags,\ @@ -646,7 +643,7 @@ RD_Query query; C_LINKAGE_BEGIN extern RD_VocabInfo rd_vocab_info_table[315]; extern RD_NameSchemaInfo rd_name_schema_info_table[17]; -extern Rng1U64 rd_reg_slot_range_table[42]; +extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[74]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 826a785b..94345a6a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -374,43 +374,42 @@ RD_RegTable: {RD_CfgIDList cfg_list CfgList } // rjf: frame selection - {U64 unwind_count UnwindCount } - {U64 inline_depth InlineDepth } + {U64 unwind_count UnwindCount } + {U64 inline_depth InlineDepth } // rjf: code / address location info - {String8 file_path FilePath } - {TxtPt cursor Cursor } - {TxtPt mark Mark } - {U128 text_key TextKey } - {TXT_LangKind lang_kind LangKind } - {D_LineList lines Lines } - {DI_Key dbgi_key DbgiKey } - {U64 vaddr Vaddr } - {U64 voff Voff } - {Rng1U64 vaddr_range VaddrRange } - {Rng1U64 voff_range VoffRange } + {String8 file_path FilePath } + {TxtPt cursor Cursor } + {TxtPt mark Mark } + {U128 text_key TextKey } + {TXT_LangKind lang_kind LangKind } + {D_LineList lines Lines } + {DI_Key dbgi_key DbgiKey } + {U64 vaddr Vaddr } + {U64 voff Voff } + {Rng1U64 vaddr_range VaddrRange } + {Rng1U64 voff_range VoffRange } // rjf: evaluation - {String8 expr Expr } - {String8 view_rule ViewRule } + {String8 expr Expr } // rjf: ui context - {UI_Key ui_key UIKey } - {Vec2F32 off_px OffPx } - {RD_ListerFlags lister_flags ListerFlags } - {RD_RegSlot reg_slot RegSlot } + {UI_Key ui_key UIKey } + {Vec2F32 off_px OffPx } + {RD_ListerFlags lister_flags ListerFlags } + {RD_RegSlot reg_slot RegSlot } // rjf: general parameters - {U32 pid PID } - {B32 force_confirm ForceConfirm } - {B32 prefer_disasm PreferDisasm } - {B32 no_rich_tooltip NoRichTooltip } - {B32 do_implicit_root DoImplicitRoot} - {Dir2 dir2 Dir2 } - {String8 string String } - {String8 cmd_name CmdName } - {`MD_Node *` params_tree ParamsTree } - {`OS_Event *` os_event OSEvent } + {U32 pid PID } + {B32 force_confirm ForceConfirm } + {B32 prefer_disasm PreferDisasm } + {B32 no_rich_tooltip NoRichTooltip } + {B32 do_implicit_root DoImplicitRoot} + {Dir2 dir2 Dir2 } + {String8 string String } + {String8 cmd_name CmdName } + {`MD_Node *` params_tree ParamsTree } + {`OS_Event *` os_event OSEvent } } @enum RD_RegSlot: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 22c8ca4a..ae51f4ea 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -44,7 +44,6 @@ rd_regs_copy_contents(Arena *arena, RD_Regs *dst, RD_Regs *src) dst->lines = d_line_list_copy(arena, &src->lines); dst->dbgi_key = di_key_copy(arena, &src->dbgi_key); dst->expr = push_str8_copy(arena, src->expr); - dst->view_rule = push_str8_copy(arena, src->view_rule); dst->string = push_str8_copy(arena, src->string); dst->cmd_name = push_str8_copy(arena, src->cmd_name); dst->params_tree = md_tree_copy(arena, src->params_tree); @@ -1123,14 +1122,6 @@ rd_expr_from_cfg(RD_Cfg *cfg) return result; } -internal String8 -rd_view_rule_from_cfg(RD_Cfg *cfg) -{ - RD_Cfg *view_rule = rd_cfg_child_from_string(cfg, str8_lit("view_rule")); - String8 result = view_rule->first->string; - return result; -} - internal String8 rd_path_from_cfg(RD_Cfg *cfg) { @@ -4399,8 +4390,7 @@ rd_view_ui(Rng2F32 rect) row->eval.space.kind == E_SpaceKind_File || row->eval.space.kind == E_SpaceKind_Null) { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row->eval.expr), - .view_rule = ev_view_rule_from_key(rd_view_eval_view(), row->key)) + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row->eval.expr)) rd_drag_begin(RD_RegSlot_Expr); } } @@ -6316,7 +6306,7 @@ rd_window_frame(void) } // rjf: choose hover evaluation expression - String8 hover_eval_expr = push_str8f(scratch.arena, "%S%s%S", ws->hover_eval_string, ws->hover_eval_view_rules.size != 0 ? " => " : "", ws->hover_eval_view_rules); + String8 hover_eval_expr = ws->hover_eval_string; // rjf: evaluate hover evaluation expression, & determine if it evaluates // such that we want to build a hover eval. @@ -9274,7 +9264,7 @@ rd_value_string_from_eval(Arena *arena, String8 filter, EV_StringParams *params, //~ rjf: Hover Eval internal void -rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules) +rd_set_hover_eval(Vec2F32 pos, String8 string) { RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); @@ -9283,14 +9273,12 @@ rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules) ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero()) && ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero())) { - B32 is_new_string = (!str8_match(ws->hover_eval_string, string, 0) || - !str8_match(ws->hover_eval_view_rules, view_rules, 0)); + B32 is_new_string = (!str8_match(ws->hover_eval_string, string, 0)); if(is_new_string) { ws->hover_eval_firstt_us = ws->hover_eval_lastt_us = rd_state->time_in_us; arena_clear(ws->hover_eval_arena); ws->hover_eval_string = push_str8_copy(ws->hover_eval_arena, string); - ws->hover_eval_view_rules = push_str8_copy(ws->hover_eval_arena, view_rules); ws->hover_eval_focused = 0; } ws->hover_eval_spawn_pos = pos; @@ -14891,7 +14879,6 @@ Z(getting_started) String8 file_path = rd_regs()->file_path; TxtPt pt = rd_regs()->cursor; String8 expr_string = rd_regs()->expr; - String8 view_rule_string = rd_regs()->view_rule; U64 vaddr = rd_regs()->vaddr; B32 removed_already_existing = 0; if(kind == RD_CmdKind_ToggleWatchPin) @@ -14916,9 +14903,7 @@ Z(getting_started) RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *wp = rd_cfg_new(project, str8_lit("watch_pin")); RD_Cfg *expr = rd_cfg_new(wp, str8_lit("expression")); - RD_Cfg *view_rule = rd_cfg_new(wp, str8_lit("view_rule")); rd_cfg_new(expr, expr_string); - rd_cfg_new(view_rule, view_rule_string); rd_cmd(RD_CmdKind_RelocateCfg, .cfg = wp->id, .expr = str8_zero()); } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index d00a9154..c586be8d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -560,7 +560,6 @@ struct RD_WindowState Arena *hover_eval_arena; Vec2F32 hover_eval_spawn_pos; String8 hover_eval_string; - String8 hover_eval_view_rules; U64 hover_eval_firstt_us; U64 hover_eval_lastt_us; @@ -892,7 +891,6 @@ internal B32 rd_disabled_from_cfg(RD_Cfg *cfg); internal RD_Location rd_location_from_cfg(RD_Cfg *cfg); internal String8 rd_label_from_cfg(RD_Cfg *cfg); internal String8 rd_expr_from_cfg(RD_Cfg *cfg); -internal String8 rd_view_rule_from_cfg(RD_Cfg *cfg); internal String8 rd_path_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); @@ -1008,7 +1006,7 @@ internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_Stri //////////////////////////////// //~ rjf: Hover Eval -internal void rd_set_hover_eval(Vec2F32 pos, String8 string, String8 view_rules); +internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //////////////////////////////// //~ rjf: Lister Functions diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 536ad443..b4bad7ed 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1965,9 +1965,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_Cfg *pin = n->v; String8 pin_expr = rd_expr_from_cfg(pin); - String8 pin_view_rule = rd_view_rule_from_cfg(pin); - String8 full_pin_expr = push_str8f(scratch.arena, "%S => %S", pin_expr, pin_view_rule); - E_Eval eval = e_eval_from_string(scratch.arena, full_pin_expr); + E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { @@ -1994,7 +1992,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal pin_sig = ui_signal_from_box(pin_box); if(ui_key_match(pin_box_key, ui_hot_key())) { - rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr, pin_view_rule); + rd_set_hover_eval(v2f32(pin_box->rect.x0, pin_box->rect.y1-2.f), pin_expr); } } } @@ -2198,7 +2196,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_vaddr = params->line_vaddrs[line_idx]; rd_cmd(RD_CmdKind_AddWatchPin, .expr = rd_state->drag_drop_regs->expr, - .view_rule = rd_state->drag_drop_regs->view_rule, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); @@ -2320,7 +2317,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe U64 line_idx = mouse_pt.line-params->line_num_range.min; line_vaddr = params->line_vaddrs[line_idx]; } - rd_set_hover_eval(mouse_expr_baseline_pos, mouse_expr, str8_zero()); + rd_set_hover_eval(mouse_expr_baseline_pos, mouse_expr); } } From 950199026b7f0633cc84a83296cf017c3bcba809 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 16 Apr 2025 12:10:56 -0700 Subject: [PATCH 381/755] begin folding font size parameters into main cfg tree settings path; allow per-tab font sizes, eliminate all redundant font size lookups/applications --- src/raddbg/generated/raddbg.meta.c | 36 ++++---- src/raddbg/generated/raddbg.meta.h | 15 ++-- src/raddbg/raddbg.mdesk | 77 ++++++++++------- src/raddbg/raddbg_core.c | 133 +++++++++-------------------- src/raddbg/raddbg_core.h | 32 +------ src/raddbg/raddbg_eval.c | 55 ++++++++---- src/raddbg/raddbg_views.c | 12 +-- src/raddbg/raddbg_widgets.h | 1 - src/ui/ui_core.c | 2 + 9 files changed, 160 insertions(+), 203 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index be65f051..45e11be1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[315] = +RD_VocabInfo rd_vocab_info_table[314] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -107,6 +107,7 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("yaw"), str8_lit_comp(""), str8_lit_comp("Yaw"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("pitch"), str8_lit_comp(""), str8_lit_comp("Pitch"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("zoom"), str8_lit_comp(""), str8_lit_comp("Zoom"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("font_size"), str8_lit_comp(""), str8_lit_comp("Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -149,10 +150,8 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, {str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select Entity"), str8_lit_comp(""), RD_IconKind_RadioHollow}, {str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect Entity"), str8_lit_comp(""), RD_IconKind_RadioFilled}, -{str8_lit_comp("inc_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("dec_ui_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("inc_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("dec_code_font_scale"), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("inc_font_size"), str8_lit_comp(""), str8_lit_comp("Increase Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("open_window"), str8_lit_comp(""), str8_lit_comp("Open New Window"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("close_window"), str8_lit_comp(""), str8_lit_comp("Close Window"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("toggle_fullscreen"), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), str8_lit_comp(""), RD_IconKind_Window}, @@ -323,14 +322,16 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[17] = +RD_NameSchemaInfo rd_name_schema_info_table[19] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @can_be_per_window 'main_font_size': @range[6, 72] u64,\n @can_be_per_window 'code_font_size': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, @@ -344,7 +345,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[17] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[41] = +Rng1U64 rd_reg_slot_range_table[40] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -375,7 +376,6 @@ Rng1U64 rd_reg_slot_range_table[41] = {OffsetOf(RD_Regs, expr), OffsetOf(RD_Regs, expr) + sizeof(String8)}, {OffsetOf(RD_Regs, ui_key), OffsetOf(RD_Regs, ui_key) + sizeof(UI_Key)}, {OffsetOf(RD_Regs, off_px), OffsetOf(RD_Regs, off_px) + sizeof(Vec2F32)}, -{OffsetOf(RD_Regs, lister_flags), OffsetOf(RD_Regs, lister_flags) + sizeof(RD_ListerFlags)}, {OffsetOf(RD_Regs, reg_slot), OffsetOf(RD_Regs, reg_slot) + sizeof(RD_RegSlot)}, {OffsetOf(RD_Regs, pid), OffsetOf(RD_Regs, pid) + sizeof(U32)}, {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, @@ -389,7 +389,7 @@ Rng1U64 rd_reg_slot_range_table[41] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[215] = +RD_CmdKindInfo rd_cmd_kind_info_table[213] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -434,10 +434,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[215] = { str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_font_size"), str8_lit_comp("Increases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_font_size"), str8_lit_comp("Decreases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 4829e52f..7948062f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -37,7 +37,6 @@ RD_RegSlot_VoffRange, RD_RegSlot_Expr, RD_RegSlot_UIKey, RD_RegSlot_OffPx, -RD_RegSlot_ListerFlags, RD_RegSlot_RegSlot, RD_RegSlot_PID, RD_RegSlot_ForceConfirm, @@ -97,10 +96,8 @@ RD_CmdKind_UpOneFrame, RD_CmdKind_DownOneFrame, RD_CmdKind_SelectEntity, RD_CmdKind_DeselectEntity, -RD_CmdKind_IncUIFontScale, -RD_CmdKind_DecUIFontScale, -RD_CmdKind_IncCodeFontScale, -RD_CmdKind_DecCodeFontScale, +RD_CmdKind_IncFontSize, +RD_CmdKind_DecFontSize, RD_CmdKind_OpenWindow, RD_CmdKind_CloseWindow, RD_CmdKind_ToggleFullscreen, @@ -563,7 +560,6 @@ Rng1U64 voff_range; String8 expr; UI_Key ui_key; Vec2F32 off_px; -RD_ListerFlags lister_flags; RD_RegSlot reg_slot; U32 pid; B32 force_confirm; @@ -627,7 +623,6 @@ RD_Query query; .expr = rd_regs()->expr,\ .ui_key = rd_regs()->ui_key,\ .off_px = rd_regs()->off_px,\ -.lister_flags = rd_regs()->lister_flags,\ .reg_slot = rd_regs()->reg_slot,\ .pid = rd_regs()->pid,\ .force_confirm = rd_regs()->force_confirm,\ @@ -641,9 +636,9 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[315]; -extern RD_NameSchemaInfo rd_name_schema_info_table[17]; -extern Rng1U64 rd_reg_slot_range_table[41]; +extern RD_VocabInfo rd_vocab_info_table[314]; +extern RD_NameSchemaInfo rd_name_schema_info_table[19]; +extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[74]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 94345a6a..65c0bb90 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -120,6 +120,7 @@ RD_VocabTable: {yaw "" "Yaw" "" Null } {pitch "" "Pitch" "" Null } {zoom "" "Zoom" "" Null } + {font_size "" "Font Size" "" Null } } @struct RD_VocabInfo: @@ -148,25 +149,46 @@ RD_VocabTable: settings, ```x: { - @default(1) 'hover_animations': bool, - @default(1) 'press_animations': bool, - @default(0) 'focus_animations': bool, - @default(1) 'tooltip_animations': bool, - @default(1) 'menu_animations': bool, - @default(1) 'scrolling_animations': bool, - @default(1) 'background_blur': bool, - @default(1) 'thread_lines': bool, - @default(1) 'breakpoint_lines': bool, - @default(1) 'thread_glow': bool, - @default(1) 'breakpoint_glow': bool, - @default(0) 'opaque_backgrounds': bool, - @default(1) 'smooth_main_text': bool, - @default(0) 'smooth_code_text': bool, - @default(1) 'hint_main_text': bool, - @default(1) 'hint_code_text': bool, - @default(2) 'tab_width': @range[1, 32] u64, - @can_be_per_window 'main_font_size': @range[6, 72] u64, - @can_be_per_window 'code_font_size': @range[1, 32] u64, + @default(1) 'hover_animations': bool, + @default(1) 'press_animations': bool, + @default(0) 'focus_animations': bool, + @default(1) 'tooltip_animations': bool, + @default(1) 'menu_animations': bool, + @default(1) 'scrolling_animations': bool, + @default(1) 'background_blur': bool, + @default(1) 'thread_lines': bool, + @default(1) 'breakpoint_lines': bool, + @default(1) 'thread_glow': bool, + @default(1) 'breakpoint_glow': bool, + @default(0) 'opaque_backgrounds': bool, + @default(1) 'smooth_main_text': bool, + @default(0) 'smooth_code_text': bool, + @default(1) 'hint_main_text': bool, + @default(1) 'hint_code_text': bool, + @default(2) 'tab_width': @range[1, 32] u64, + @default(11) 'font_size': @range[6, 72] u64, + } + ``` + } + + //- rjf: windows + { + window, + ``` + x: + { + @default(11) 'font_size': @range[6, 72] u64, + } + ``` + } + + //- rjf: tabs + { + tab, + ``` + x: + { + @default(11) 'font_size': @range[6, 72] u64, } ``` } @@ -175,7 +197,7 @@ RD_VocabTable: { text, ``` - x: + @inherit(tab) x: { 'lang':lang, 'size':code_string, @@ -186,7 +208,7 @@ RD_VocabTable: { disasm, ``` - x: + @inherit(tab) x: { 'arch': arch, 'syntax': dasm_syntax, @@ -202,7 +224,7 @@ RD_VocabTable: { memory, ``` - x: + @inherit(tab) x: { 'size': code_string, @default(16) 'num_columns': @range[1, 64] u64, @@ -213,7 +235,7 @@ RD_VocabTable: { bitmap, ``` - x: + @inherit(tab) x: { @order(0) 'w': u64, @order(1) 'h': u64, @@ -224,7 +246,7 @@ RD_VocabTable: { geo3d, ``` - x: + @inherit(tab) x: { 'count': code_string, 'vtx': code_string, @@ -396,7 +418,6 @@ RD_RegTable: // rjf: ui context {UI_Key ui_key UIKey } {Vec2F32 off_px OffPx } - {RD_ListerFlags lister_flags ListerFlags } {RD_RegSlot reg_slot RegSlot } // rjf: general parameters @@ -466,10 +487,8 @@ RD_CmdTable: // | | | | {DeselectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } //- rjf: font sizes - {IncUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_ui_font_scale" "Increase UI Font Scale" "Increases the font size used for UI." "" "" } - {DecUIFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_ui_font_scale" "Decrease UI Font Scale" "Decreases the font size used for UI." "" "" } - {IncCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_code_font_scale" "Increase Code Font Scale" "Increases the font size used for code." "" "" } - {DecCodeFontScale 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_code_font_scale" "Decrease Code Font Scale" "Decreases the font size used for code." "" "" } + {IncFontSize 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_font_size" "Increase Font Size" "Increases the font size by one point." "" "" } + {DecFontSize 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_font_size" "Decrease Font Size" "Decreases the font size by one point." "" "" } //- rjf: windows {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ae51f4ea..6c4b8952 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2320,7 +2320,7 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: fill view container // - UI_Parent(view_container) + UI_Parent(view_container) UI_FontSize(rd_setting_f32_from_name(str8_lit("font_size"))) { //////////////////////////// //- rjf: special-case view: "getting started" @@ -5280,6 +5280,7 @@ rd_window_frame(void) // if(rd_state->first_window_state == ws && rd_state->last_window_state == ws && ws->frames_alive == 0) { + F32 font_size = rd_setting_f32_from_name(str8_lit("font_size")); RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; RD_FontSlot icon_font_slot = RD_FontSlot_Icons; for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) @@ -5289,12 +5290,12 @@ rd_window_frame(void) String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); fnt_push_run_from_string(scratch.arena, rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Code), + font_size, 0, 0, 0, sample_text); fnt_push_run_from_string(scratch.arena, rd_font_from_slot(slot), - rd_font_size_from_slot(RD_FontSlot_Main), + font_size, 0, 0, 0, sample_text); scratch_end(scratch); @@ -5304,17 +5305,17 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); fnt_push_run_from_string(scratch.arena, rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(icon_font_slot), + font_size, 0, 0, FNT_RasterFlag_Smooth, rd_icon_kind_text_table[icon_kind]); fnt_push_run_from_string(scratch.arena, rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Main), + font_size, 0, 0, FNT_RasterFlag_Smooth, rd_icon_kind_text_table[icon_kind]); fnt_push_run_from_string(scratch.arena, rd_font_from_slot(icon_font_slot), - rd_font_size_from_slot(RD_FontSlot_Code), + font_size, 0, 0, FNT_RasterFlag_Smooth, rd_icon_kind_text_table[icon_kind]); scratch_end(scratch); @@ -5425,15 +5426,14 @@ rd_window_frame(void) //- rjf: @window_ui_part set up // { - // rjf: gather font info - FNT_Tag main_font = rd_font_from_slot(RD_FontSlot_Main); - F32 main_font_size = rd_font_size_from_slot(RD_FontSlot_Main); - FNT_Tag icon_font = rd_font_from_slot(RD_FontSlot_Icons); + // rjf: get top-level font size info + F32 top_level_font_size = 0; + RD_RegsScope(.view = 0) top_level_font_size = rd_setting_f32_from_name(str8_lit("font_size")); // rjf: build icon info UI_IconInfo icon_info = {0}; { - icon_info.icon_font = icon_font; + icon_info.icon_font = rd_font_from_slot(RD_FontSlot_Icons); icon_info.icon_kind_text_map[UI_IconKind_RightArrow] = rd_icon_kind_text_table[RD_IconKind_RightScroll]; icon_info.icon_kind_text_map[UI_IconKind_DownArrow] = rd_icon_kind_text_table[RD_IconKind_DownScroll]; icon_info.icon_kind_text_map[UI_IconKind_LeftArrow] = rd_icon_kind_text_table[RD_IconKind_LeftScroll]; @@ -5459,9 +5459,9 @@ rd_window_frame(void) // rjf: begin & push initial stack values ui_begin_build(ws->os, &ws->ui_events, &icon_info, ws->theme, &animation_info, rd_state->frame_dt, rd_state->frame_dt); - ui_push_font(main_font); - ui_push_font_size(main_font_size); - ui_push_text_padding(main_font_size*0.3f); + ui_push_font(rd_font_from_slot(RD_FontSlot_Main)); + ui_push_font_size(top_level_font_size); + ui_push_text_padding(floor_f32(ui_top_font_size()*0.3f)); ui_push_pref_width(ui_px(floor_f32(ui_top_font_size()*20.f), 1.f)); ui_push_pref_height(ui_px(floor_f32(ui_top_font_size()*3.f), 1.f)); ui_push_blur_size(10.f); @@ -6275,7 +6275,6 @@ rd_window_frame(void) FloatingViewTask *first_floating_view_task = 0; FloatingViewTask *last_floating_view_task = 0; RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) { //- rjf: try to add hover eval first { @@ -6561,7 +6560,6 @@ rd_window_frame(void) // ProfScope("build all floating views") RD_Font(RD_FontSlot_Code) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) { @@ -7181,16 +7179,12 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); if(ui_hovering(sig) && !can_play) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); } if(ui_hovering(sig) && can_play) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) { if(can_stop) { @@ -7227,9 +7221,7 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); if(ui_hovering(sig)) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) { ui_labelf("Restart"); } @@ -7248,16 +7240,12 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); if(ui_hovering(sig) && !can_pause) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: Already halted"); } if(ui_hovering(sig) && can_pause) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Halt all attached processes"); } if(ui_clicked(sig)) @@ -7277,16 +7265,11 @@ rd_window_frame(void) } if(ui_hovering(sig) && !can_stop) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - ui_labelf("Disabled: No processes are running"); + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: No processes are running"); } if(ui_hovering(sig) && can_stop) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Kill all attached processes"); } if(ui_clicked(sig)) @@ -7305,16 +7288,11 @@ rd_window_frame(void) { if(can_play) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) - ui_labelf("Step Over"); + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Step Over"); } else { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); } } @@ -7334,16 +7312,12 @@ rd_window_frame(void) { if(can_play) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Step Into"); } else { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); } } @@ -7361,23 +7335,17 @@ rd_window_frame(void) os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); if(ui_hovering(sig) && !can_step && can_pause) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: Running"); } if(ui_hovering(sig) && !can_step && !can_stop) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: No processes are running"); } if(ui_hovering(sig) && can_step) { - UI_Tooltip - RD_Font(RD_FontSlot_Main) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) + UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Step Out"); } if(ui_clicked(sig)) @@ -7608,9 +7576,7 @@ rd_window_frame(void) UI_PrefWidth(ui_text_dim(10, 1)) UI_TextAlignment(UI_TextAlign_Center) { - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); + RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); rd_label(error_string); } } @@ -8494,7 +8460,7 @@ rd_window_frame(void) } UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f) + UI_FontSize(ui_top_font_size()*0.75f) UI_TagF(".") UI_TagF("weak") UI_TagF("implicit") UI_CornerRadius00(0) UI_CornerRadius01(0) @@ -8529,7 +8495,6 @@ rd_window_frame(void) else if(ui_right_clicked(sig)) { rd_cmd(RD_CmdKind_PushQuery, - .do_implicit_root = 1, .ui_key = sig.box->key, .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); @@ -8714,11 +8679,11 @@ rd_window_frame(void) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncUIFontScale); + rd_cmd(RD_CmdKind_IncFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecUIFontScale); + rd_cmd(RD_CmdKind_DecFontSize); } } } @@ -9383,7 +9348,6 @@ rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, St { Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = di_scope_open(); - RD_ListerFlags flags = regs->lister_flags; String8 needle_path = rd_lister_query_path_from_input_string_off(needle, cursor_off); RD_ListerItemChunkList item_list = {0}; DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); @@ -10402,6 +10366,9 @@ rd_font_from_slot(RD_FontSlot slot) internal F32 rd_font_size_from_slot(RD_FontSlot slot) { + F32 result = (F32)rd_setting_u64_from_name(str8_lit("font_size")); + return result; +#if 0 F32 result = 11.f; // rjf: determine config key based on slot @@ -10430,8 +10397,8 @@ rd_font_size_from_slot(RD_FontSlot slot) F32 dpi = os_dpi_from_window(ws->os); result = 11.f * (dpi / 96.f); } - return result; +#endif } internal FNT_RasterFlags @@ -12501,7 +12468,7 @@ rd_frame(void) // rjf: command has required query -> prep query else { - rd_cmd(RD_CmdKind_PushQuery, .lister_flags = rd_regs()->lister_flags|RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Descriptions); + rd_cmd(RD_CmdKind_PushQuery); } }break; @@ -12822,42 +12789,24 @@ rd_frame(void) }break; //- rjf: font sizes - case RD_CmdKind_IncUIFontScale: + case RD_CmdKind_IncFontSize: { fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("font_size")); rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; - case RD_CmdKind_DecUIFontScale: + case RD_CmdKind_DecFontSize: { fnt_reset(); F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("main_font_size")); + RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("font_size")); rd_cfg_new_replacef(main_font_size, "%f", new_font_size); }break; - case RD_CmdKind_IncCodeFontScale: - { - fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); - F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - rd_cfg_new_replacef(code_font_size, "%f", new_font_size); - }break; - case RD_CmdKind_DecCodeFontScale: - { - fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Code); - F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *code_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("code_font_size")); - rd_cfg_new_replacef(code_font_size, "%f", new_font_size); - }break; //- rjf: panel creation case RD_CmdKind_NewPanelLeft: {split_dir = Dir2_Left;}goto split; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index c586be8d..f8efc425 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -159,37 +159,6 @@ enum RD_CmdKindFlag_ListInIPCDocs = (1<<1), }; -//////////////////////////////// -//~ rjf: Lister Flags - -typedef U32 RD_ListerFlags; -enum -{ - //- rjf: lister visual settings - RD_ListerFlag_LineEdit = (1<<0), // determines whether or not the lister has its own line edit, or if the filtering string is sourced by a user - RD_ListerFlag_Descriptions = (1<<1), // determines whether or not the lister items have descriptions (taller & bigger buttons) - RD_ListerFlag_KindLabel = (1<<2), // determines whether or not the lister items have labels for each item's kind - RD_ListerFlag_SizeByAnchor = (1<<3), // determines whether or not the lister is sized by the anchor box - - //- rjf: lister item sources - RD_ListerFlag_Locals = (1<<4), - RD_ListerFlag_Registers = (1<<5), - RD_ListerFlag_ViewRules = (1<<6), - RD_ListerFlag_ViewRuleParams = (1<<7), - RD_ListerFlag_Members = (1<<8), - RD_ListerFlag_Globals = (1<<9), - RD_ListerFlag_ThreadLocals = (1<<10), - RD_ListerFlag_Procedures = (1<<11), - RD_ListerFlag_Types = (1<<12), - RD_ListerFlag_Languages = (1<<13), - RD_ListerFlag_Architectures = (1<<14), - RD_ListerFlag_Tex2DFormats = (1<<15), - RD_ListerFlag_Files = (1<<16), - RD_ListerFlag_Commands = (1<<17), - RD_ListerFlag_Settings = (1<<18), - RD_ListerFlag_SystemProcesses= (1<<19), -}; - //////////////////////////////// //~ rjf: Generated Code @@ -899,6 +868,7 @@ internal MD_Node *rd_schema_from_name(String8 name); internal String8 rd_setting_from_name(String8 name); #define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) #define rd_setting_u64_from_name(name) (u64_from_str8(rd_setting_from_name(name), 10)) +#define rd_setting_f32_from_name(name) ((F32)f64_from_str8(rd_setting_from_name(name))) internal RD_Cfg *rd_immediate_cfg_from_key(String8 string); internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index e87c0ac8..e43baa2c 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -277,12 +277,20 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) //////////////////////////////// //~ rjf: Schema Type Hooks +typedef struct RD_SchemaNode RD_SchemaNode; +struct RD_SchemaNode +{ + RD_SchemaNode *next; + MD_Node *schema; +}; + typedef struct RD_SchemaIRExt RD_SchemaIRExt; struct RD_SchemaIRExt { RD_Cfg *cfg; CTRL_Entity *entity; - MD_Node *schema; + RD_SchemaNode *first_schema; + RD_SchemaNode *last_schema; }; E_TYPE_IREXT_FUNCTION_DEF(schema) @@ -298,7 +306,18 @@ E_TYPE_IREXT_FUNCTION_DEF(schema) MD_Node *schema = rd_schema_from_name(type->name); ext->cfg = rd_cfg_from_eval_space(interpret.space); ext->entity = rd_ctrl_entity_from_eval_space(interpret.space); - ext->schema = schema; + for MD_EachNode(tag, schema->first_tag) + { + if(str8_match(tag->string, str8_lit("inherit"), 0)) + { + RD_SchemaNode *n = push_array(arena, RD_SchemaNode, 1); + n->schema = rd_schema_from_name(tag->first->string); + SLLQueuePush(ext->first_schema, ext->last_schema, n); + } + } + RD_SchemaNode *n = push_array(arena, RD_SchemaNode, 1); + n->schema = schema; + SLLQueuePush(ext->first_schema, ext->last_schema, n); scratch_end(scratch); } E_IRExt result = {ext}; @@ -312,12 +331,15 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(expr->kind == E_ExprKind_MemberAccess) { MD_Node *child_schema = &md_nil_node; - for MD_EachNode(child, ext->schema->first) + for(RD_SchemaNode *n = ext->first_schema; n != 0; n = n->next) { - if(str8_match(child->string, expr->first->next->string, 0)) + for MD_EachNode(child, n->schema->first) { - child_schema = child; - break; + if(str8_match(child->string, expr->first->next->string, 0)) + { + child_schema = child; + break; + } } } if(child_schema != &md_nil_node) @@ -479,7 +501,6 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) // rjf: unpack RD_SchemaIRExt *ext = (RD_SchemaIRExt *)irtree->user_data; - MD_Node *schema = ext->schema; // rjf: gather expansion children typedef struct ExpandChildNode ExpandChildNode; @@ -491,17 +512,21 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) ExpandChildNode *first_child_node = 0; ExpandChildNode *last_child_node = 0; U64 child_count = 0; - for MD_EachNode(child, schema->first) + for(RD_SchemaNode *n = ext->first_schema; n != 0; n = n->next) { - if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) + MD_Node *schema = n->schema; + for MD_EachNode(child, schema->first) { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) + if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) { - ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); - n->n = child; - SLLQueuePush(first_child_node, last_child_node, n); - child_count += 1; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); + if(matches.count == matches.needle_part_count) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } } } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index fe4ecc58..bdd69348 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -34,7 +34,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: extract invariants // FNT_Tag code_font = rd_font_from_slot(RD_FontSlot_Code); - F32 code_font_size = rd_font_size_from_slot(RD_FontSlot_Code); + F32 code_font_size = ui_top_font_size(); F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_name(str8_lit("tab_width")); FNT_Metrics code_font_metrics = fnt_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(fnt_line_height_from_metrics(&code_font_metrics) * 1.5f); @@ -779,11 +779,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncCodeFontScale); + rd_cmd(RD_CmdKind_IncFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecCodeFontScale); + rd_cmd(RD_CmdKind_DecFontSize); } } } @@ -2270,7 +2270,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); FNT_RasterFlags font_raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); - F32 font_size = rd_font_size_from_slot(RD_FontSlot_Code); + F32 font_size = ui_top_font_size(); F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; F32 row_height_px = floor_f32(font_size*2.f); F32 cell_width_px = floor_f32(font_size*2.f * bytes_per_cell); @@ -2735,11 +2735,11 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncCodeFontScale); + rd_cmd(RD_CmdKind_IncFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecCodeFontScale); + rd_cmd(RD_CmdKind_DecFontSize); } } } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index f4004990..173bb3ff 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -116,7 +116,6 @@ struct RD_CodeSliceSignal //////////////////////////////// //~ rjf: UI Building Helpers -#define RD_Palette(code) UI_Palette(rd_palette_from_code(code)) #define RD_Font(slot) UI_Font(rd_font_from_slot(slot)) UI_TextRasterFlags(rd_raster_flags_from_slot((slot))) //////////////////////////////// diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index a4f1df81..faf68764 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1945,6 +1945,7 @@ ui_tooltip_begin_base(void) ui_push_parent(ui_state->tooltip_root); ui_push_flags(0); ui_push_text_raster_flags(ui_bottom_text_raster_flags()); + ui_push_font_size(ui_bottom_font_size()); ui_push_tag(str8_lit(".")); ui_push_tag(str8_lit("floating")); } @@ -1954,6 +1955,7 @@ ui_tooltip_end_base(void) { ui_pop_tag(); ui_pop_tag(); + ui_pop_font_size(); ui_pop_text_raster_flags(); ui_pop_flags(); ui_pop_parent(); From f29c017268b35af155bfd5ba77f676edec392b7f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 16 Apr 2025 12:16:36 -0700 Subject: [PATCH 382/755] adjust text/disasm views to apply top-level font size to scroll bars / metadata, but use the per-view font size for main contents --- src/raddbg/raddbg_views.c | 13 ++++++++----- src/ui/ui_basic_widgets.c | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index bdd69348..8daf5b21 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -33,6 +33,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ////////////////////////////// //- rjf: extract invariants // + F32 main_font_size = ui_bottom_font_size(); FNT_Tag code_font = rd_font_from_slot(RD_FontSlot_Code); F32 code_font_size = ui_top_font_size(); F32 code_tab_size = fnt_column_size_from_tag_size(code_font, code_font_size)*rd_setting_u64_from_name(str8_lit("tab_width")); @@ -40,7 +41,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla F32 code_line_height = ceil_f32(fnt_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = fnt_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; Vec2F32 panel_box_dim = dim_2f32(rect); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); + F32 scroll_bar_dim = floor_f32(main_font_size*1.5f); Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim); S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1; CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); @@ -1739,7 +1740,8 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: set up invariants // - F32 bottom_bar_height = ui_top_font_size()*2.f; + F32 main_font_size = ui_bottom_font_size(); + F32 bottom_bar_height = main_font_size*2.f; Rng2F32 code_area_rect = r2f32p(rect.x0, rect.y0, rect.x1, rect.y1 - bottom_bar_height); Rng2F32 bottom_bar_rect = r2f32p(rect.x0, rect.y1 - bottom_bar_height, rect.x1, rect.y1); @@ -1885,7 +1887,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: build bottom bar // - if(!file_is_missing && key_has_data) + if(!file_is_missing && key_has_data) UI_FontSize(main_font_size) { ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); ui_set_next_flags(UI_BoxFlag_DrawBackground); @@ -2010,7 +2012,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) ////////////////////////////// //- rjf: set up invariants // - F32 bottom_bar_height = ui_top_font_size()*2.f; + F32 main_font_size = ui_bottom_font_size(); + F32 bottom_bar_height = main_font_size*2.f; Rng2F32 code_area_rect = r2f32p(rect.x0, rect.y0, rect.x1, rect.y1 - bottom_bar_height); Rng2F32 bottom_bar_rect = r2f32p(rect.x0, rect.y1 - bottom_bar_height, rect.x1, rect.y1); rd_regs()->file_path = str8_zero(); @@ -2149,7 +2152,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) ////////////////////////////// //- rjf: build bottom bar // - if(!is_loading && has_disasm) + if(!is_loading && has_disasm) UI_FontSize(main_font_size) { ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); ui_set_next_flags(UI_BoxFlag_DrawBackground); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 12e86b0f..27361e8f 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -1212,6 +1212,7 @@ internal UI_ScrollPt ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_range, S64 view_num_indices) { ui_push_tag(str8_lit("scroll_bar")); + ui_push_font_size(ui_bottom_font_size()*0.65f); //- rjf: unpack S64 idx_range_dim = Max(dim_1s64(idx_range), 1); @@ -1329,6 +1330,7 @@ ui_scroll_bar(Axis2 axis, UI_Size off_axis_size, UI_ScrollPt pt, Rng1S64 idx_ran } } + ui_pop_font_size(); ui_pop_tag(); return new_pt; } From f1549f6b53db5fe9d98c23a943f82272abdc54b7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 10:53:11 -0700 Subject: [PATCH 383/755] correctly use all schemas (including inherited ones) when doing lookups/evaluations; shift enabled to using evaluation path rather than just checking the value string; fix visualization of inherited schema values (e.g. font sizes in tabs) --- src/mdesk/mdesk.c | 22 ++++++ src/mdesk/mdesk.h | 21 ++++++ src/raddbg/generated/raddbg.meta.c | 8 +-- src/raddbg/raddbg.mdesk | 6 +- src/raddbg/raddbg_core.c | 108 +++++++++++++++++++++-------- src/raddbg/raddbg_core.h | 4 +- src/raddbg/raddbg_eval.c | 44 ++++-------- src/raddbg/raddbg_views.c | 96 +++++++++++++------------ src/ui/ui_core.c | 2 +- 9 files changed, 195 insertions(+), 116 deletions(-) diff --git a/src/mdesk/mdesk.c b/src/mdesk/mdesk.c index a1888673..1b6e2f51 100644 --- a/src/mdesk/mdesk.c +++ b/src/mdesk/mdesk.c @@ -1204,3 +1204,25 @@ md_debug_string_list_from_tree(Arena *arena, MD_Node *root) } return strings; } + +//////////////////////////////// +//~ rjf: Node Pointer List Functions + +internal void +md_node_ptr_list_push(Arena *arena, MD_NodePtrList *list, MD_Node *node) +{ + MD_NodePtrNode *n = push_array(arena, MD_NodePtrNode, 1); + n->v = node; + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal void +md_node_ptr_list_push_front(Arena *arena, MD_NodePtrList *list, MD_Node *node) +{ + MD_NodePtrNode *n = push_array(arena, MD_NodePtrNode, 1); + n->v = node; + SLLQueuePushFront(list->first, list->last, n); + list->count += 1; +} + diff --git a/src/mdesk/mdesk.h b/src/mdesk/mdesk.h index afe6fc32..455cb268 100644 --- a/src/mdesk/mdesk.h +++ b/src/mdesk/mdesk.h @@ -202,6 +202,21 @@ struct MD_NodeRec S32 pop_count; }; +typedef struct MD_NodePtrNode MD_NodePtrNode; +struct MD_NodePtrNode +{ + MD_NodePtrNode *next; + MD_Node *v; +}; + +typedef struct MD_NodePtrList MD_NodePtrList; +struct MD_NodePtrList +{ + MD_NodePtrNode *first; + MD_NodePtrNode *last; + U64 count; +}; + //////////////////////////////// //~ rjf: Text -> Tokens Types @@ -322,4 +337,10 @@ internal MD_ParseResult md_parse_from_text(Arena *arena, String8 filename, Strin internal String8List md_debug_string_list_from_tree(Arena *arena, MD_Node *root); +//////////////////////////////// +//~ rjf: Node Pointer List Functions + +internal void md_node_ptr_list_push(Arena *arena, MD_NodePtrList *list, MD_Node *node); +internal void md_node_ptr_list_push_front(Arena *arena, MD_NodePtrList *list, MD_Node *node); + #endif // MDESK_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 45e11be1..a8c5cbb4 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -606,7 +606,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[107] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -620,10 +620,8 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = {str8_lit_comp("step_over"), {OS_Key_F10, 0 }}, {str8_lit_comp("run_to_line"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, -{str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, -{str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, -{str8_lit_comp("inc_code_font_scale"), {OS_Key_Equal, 0 |OS_Modifier_Shift |OS_Modifier_Alt}}, -{str8_lit_comp("dec_code_font_scale"), {OS_Key_Minus, 0 |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("inc_font_size"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, +{str8_lit_comp("dec_font_size"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, {str8_lit_comp("window"), {OS_Key_N, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("toggle_fullscreen"), {OS_Key_Return, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("new_panel_right"), {OS_Key_P, 0 |OS_Modifier_Ctrl }}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 65c0bb90..f88de859 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -788,10 +788,8 @@ RD_DefaultBindingTable: { "set_next_statement" F10 ctrl shift 0 } //- rjf: font sizes - { "inc_ui_font_scale" Equal 0 0 alt } - { "dec_ui_font_scale" Minus 0 0 alt } - { "inc_code_font_scale" Equal 0 shift alt } - { "dec_code_font_scale" Minus 0 shift alt } + { "inc_font_size" Equal 0 0 alt } + { "dec_font_size" Minus 0 0 alt } //- rjf: windows { "window" N ctrl shift 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6c4b8952..44fa5e79 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1065,15 +1065,19 @@ rd_color_from_cfg(RD_Cfg *cfg) internal B32 rd_disabled_from_cfg(RD_Cfg *cfg) { - MD_Node *schema = rd_schema_from_name(cfg->string); - MD_Node *enabled_schema = md_child_from_string(schema, str8_lit("enabled"), 0); - MD_Node *default_tag = md_tag_from_string(enabled_schema, str8_lit("default"), 0); + MD_Node *child_schema = &md_nil_node; + MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); + for(MD_NodePtrNode *n = schemas.first; n != 0 && child_schema == &md_nil_node; n = n->next) + { + child_schema = md_child_from_string(n->v, str8_lit("enabled"), 0); + } + MD_Node *default_tag = md_tag_from_string(child_schema, str8_lit("default"), 0); String8 value_string = rd_cfg_child_from_string(cfg, str8_lit("enabled"))->first->string; if(value_string.size == 0) { value_string = default_tag->first->string; } - B32 is_enabled = (str8_match(value_string, str8_lit("1"), 0)); + B32 is_enabled = !!e_value_from_string(value_string).u64; B32 is_disabled = !is_enabled; if(value_string.size == 0) { @@ -1152,19 +1156,19 @@ rd_target_from_cfg(Arena *arena, RD_Cfg *cfg) return target; } -internal MD_Node * -rd_schema_from_name(String8 name) +internal MD_NodePtrList +rd_schemas_from_name(String8 name) { - MD_Node *schema = &md_nil_node; + MD_NodePtrList schemas = {0}; for EachElement(idx, rd_name_schema_info_table) { if(str8_match(name, rd_name_schema_info_table[idx].name, 0)) { - schema = rd_state->schemas[idx]; + schemas = rd_state->schemas[idx]; break; } } - return schema; + return schemas; } internal String8 @@ -1207,15 +1211,20 @@ rd_setting_from_name(String8 name) }; for EachElement(idx, schema_names) { - MD_Node *schema = rd_schema_from_name(schema_names[idx]); - MD_Node *setting = md_child_from_string(schema, name, 0); - MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); - if(default_tag != &md_nil_node) + MD_NodePtrList schemas = rd_schemas_from_name(schema_names[idx]); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { - result = default_tag->first->string; - break; + MD_Node *schema = n->v; + MD_Node *setting = md_child_from_string(schema, name, 0); + MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + if(default_tag != &md_nil_node) + { + result = default_tag->first->string; + goto end_default_search; + } } } + end_default_search:; scratch_end(scratch); } } @@ -1605,8 +1614,12 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) String8 read_data = {0}; if(child_key.size != 0) { - MD_Node *root_schema = rd_schema_from_name(root_cfg->string); - MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + MD_NodePtrList schemas = rd_schemas_from_name(root_cfg->string); + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && child_schema == &md_nil_node; n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path_pt"), 0)) { @@ -1674,8 +1687,12 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) String8 read_data = {0}; if(child_key.size != 0) { - MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); - MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + MD_NodePtrList schemas = rd_schemas_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && child_schema == &md_nil_node; n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } if(str8_match(child_schema->string, str8_lit("exe"), 0) || str8_match(child_schema->string, str8_lit("label"), 0)) { @@ -1790,8 +1807,12 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) // rjf: perform write, based on child name in schema if(child_key.size != 0) { - MD_Node *root_schema = rd_schema_from_name(ctrl_entity_kind_code_name_table[entity->kind]); - MD_Node *child_schema = md_child_from_string(root_schema, child_key, 0); + MD_NodePtrList schemas = rd_schemas_from_name(ctrl_entity_kind_code_name_table[entity->kind]); + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && child_schema == &md_nil_node; n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } if(str8_match(child_schema->string, str8_lit("label"), 0)) { result = 1; @@ -2119,7 +2140,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { - MD_Node *schema = rd_schema_from_name(schema_name); + MD_NodePtrList schemas = rd_schemas_from_name(schema_name); E_Expr *primary_expr = eval.expr; E_Expr **args = 0; U64 args_count = 0; @@ -2146,9 +2167,9 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) param_name = arg->first->string; arg_expr = arg->first->next; } - else + else if(schemas.last != 0) { - for MD_EachNode(schema_child, schema->first) + for MD_EachNode(schema_child, schemas.last->v->first) { MD_Node *order_tag = md_tag_from_string(schema_child, str8_lit("order"), 0); if(order_tag != &md_nil_node) @@ -8679,11 +8700,11 @@ rd_window_frame(void) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncFontSize); + rd_cmd(RD_CmdKind_IncFontSize, .view = 0); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecFontSize); + rd_cmd(RD_CmdKind_DecFontSize, .view = 0); } } } @@ -10903,10 +10924,41 @@ rd_init(CmdLine *cmdln) // rjf: set up schemas { U64 schemas_count = ArrayCount(rd_name_schema_info_table); - rd_state->schemas = push_array(rd_state->arena, MD_Node *, schemas_count); + rd_state->schemas = push_array(rd_state->arena, MD_NodePtrList, schemas_count); for EachIndex(idx, schemas_count) { - rd_state->schemas[idx] = md_tree_from_string(rd_state->arena, rd_name_schema_info_table[idx].schema)->first; + Temp scratch = scratch_begin(0, 0); + typedef struct SchemaParseTask SchemaParseTask; + struct SchemaParseTask + { + SchemaParseTask *next; + String8 schema_text; + }; + SchemaParseTask start_task = {0, rd_name_schema_info_table[idx].schema}; + SchemaParseTask *first_task = &start_task; + SchemaParseTask *last_task = first_task; + for(SchemaParseTask *t = first_task; t != 0; t = t->next) + { + MD_Node *schema = md_tree_from_string(rd_state->arena, t->schema_text)->first; + md_node_ptr_list_push_front(rd_state->arena, &rd_state->schemas[idx], schema); + for MD_EachNode(tag, schema->first_tag) + { + if(str8_match(tag->string, str8_lit("inherit"), 0)) + { + for EachIndex(idx2, schemas_count) + { + if(str8_match(rd_name_schema_info_table[idx2].name, tag->first->string, 0)) + { + SchemaParseTask *new_task = push_array(scratch.arena, SchemaParseTask, 1); + SLLQueuePush(first_task, last_task, new_task); + new_task->schema_text = rd_name_schema_info_table[idx2].schema; + break; + } + } + } + } + } + scratch_end(scratch); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index f8efc425..67506ca0 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -598,7 +598,7 @@ struct RD_State String8 project_path; // rjf: schema table - MD_Node **schemas; + MD_NodePtrList *schemas; // rjf: default theme table MD_Node *theme_preset_trees[RD_ThemePreset_COUNT]; @@ -863,7 +863,7 @@ internal String8 rd_expr_from_cfg(RD_Cfg *cfg); internal String8 rd_path_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); -internal MD_Node *rd_schema_from_name(String8 name); +internal MD_NodePtrList rd_schemas_from_name(String8 name); internal String8 rd_setting_from_name(String8 name); #define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index e43baa2c..7611a0a2 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -277,20 +277,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) //////////////////////////////// //~ rjf: Schema Type Hooks -typedef struct RD_SchemaNode RD_SchemaNode; -struct RD_SchemaNode -{ - RD_SchemaNode *next; - MD_Node *schema; -}; - typedef struct RD_SchemaIRExt RD_SchemaIRExt; struct RD_SchemaIRExt { RD_Cfg *cfg; CTRL_Entity *entity; - RD_SchemaNode *first_schema; - RD_SchemaNode *last_schema; + MD_NodePtrList schemas; }; E_TYPE_IREXT_FUNCTION_DEF(schema) @@ -303,21 +295,9 @@ E_TYPE_IREXT_FUNCTION_DEF(schema) E_Interpretation interpret = e_interpret(bytecode); E_TypeKey type_key = irtree->type_key; E_Type *type = e_type_from_key__cached(type_key); - MD_Node *schema = rd_schema_from_name(type->name); ext->cfg = rd_cfg_from_eval_space(interpret.space); ext->entity = rd_ctrl_entity_from_eval_space(interpret.space); - for MD_EachNode(tag, schema->first_tag) - { - if(str8_match(tag->string, str8_lit("inherit"), 0)) - { - RD_SchemaNode *n = push_array(arena, RD_SchemaNode, 1); - n->schema = rd_schema_from_name(tag->first->string); - SLLQueuePush(ext->first_schema, ext->last_schema, n); - } - } - RD_SchemaNode *n = push_array(arena, RD_SchemaNode, 1); - n->schema = schema; - SLLQueuePush(ext->first_schema, ext->last_schema, n); + ext->schemas = rd_schemas_from_name(type->name); scratch_end(scratch); } E_IRExt result = {ext}; @@ -331,9 +311,9 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(expr->kind == E_ExprKind_MemberAccess) { MD_Node *child_schema = &md_nil_node; - for(RD_SchemaNode *n = ext->first_schema; n != 0; n = n->next) + for(MD_NodePtrNode *n = ext->schemas.first; n != 0; n = n->next) { - for MD_EachNode(child, n->schema->first) + for MD_EachNode(child, n->v->first) { if(str8_match(child->string, expr->first->next->string, 0)) { @@ -512,9 +492,9 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) ExpandChildNode *first_child_node = 0; ExpandChildNode *last_child_node = 0; U64 child_count = 0; - for(RD_SchemaNode *n = ext->first_schema; n != 0; n = n->next) + for(MD_NodePtrNode *n = ext->schemas.first; n != 0; n = n->next) { - MD_Node *schema = n->schema; + MD_Node *schema = n->v; for MD_EachNode(child, schema->first) { if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) @@ -599,11 +579,15 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs) //- rjf: gather commands String8List cmds_list = {0}; { - MD_Node *schema = rd_schema_from_name(cfg_name); - MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); - for MD_EachNode(cmd, collection_cmds_root->first) + MD_NodePtrList schemas = rd_schemas_from_name(cfg_name); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { - str8_list_push(arena, &cmds_list, cmd->string); + MD_Node *schema = n->v; + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(arena, &cmds_list, cmd->string); + } } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8daf5b21..01f9afe0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1169,58 +1169,62 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { RD_Cfg *cfg = evalled_cfg; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); - MD_Node *schema = rd_schema_from_name(cfg->string); - MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); - for MD_EachNode(cmd, cmds_root->first) + MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { - String8 cmd_name = cmd->string; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - switch(cmd_kind) + MD_Node *schema = n->v; + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); + for MD_EachNode(cmd, cmds_root->first) { - default:{}break; - case RD_CmdKind_EnableCfg: + String8 cmd_name = cmd->string; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + switch(cmd_kind) { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(!is_disabled) + default:{}break; + case RD_CmdKind_EnableCfg: { - cmd_kind = RD_CmdKind_DisableCfg; - } - }break; - case RD_CmdKind_DisableCfg: + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DisableCfg; + } + }break; + case RD_CmdKind_DisableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_EnableCfg; + } + }break; + case RD_CmdKind_SelectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DeselectCfg; + } + }break; + case RD_CmdKind_DeselectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_SelectCfg; + } + }break; + } + if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(is_disabled) - { - cmd_kind = RD_CmdKind_EnableCfg; - } - }break; - case RD_CmdKind_SelectCfg: + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).enabled")); + } + else if(cmd_kind != RD_CmdKind_Null) { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(!is_disabled) - { - cmd_kind = RD_CmdKind_DeselectCfg; - } - }break; - case RD_CmdKind_DeselectCfg: - { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(is_disabled) - { - cmd_kind = RD_CmdKind_SelectCfg; - } - }break; - } - if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, - .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).enabled")); - } - else if(cmd_kind != RD_CmdKind_Null) - { - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } } } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index faf68764..eaa812da 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1777,7 +1777,7 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis) // rjf: if we have a violation, we need to subtract some amount from all children F32 violation = total_size - total_allowed_size; - if(violation > 0) + if(violation > 0 && total_weighted_size > 0) { // rjf: figure out how much we can take in totality F32 child_fixup_sum = 0; From b20ff61e50e2d40c756d8e974bac5c34e6e645de Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 11:22:51 -0700 Subject: [PATCH 384/755] fix inc/dec font size commands for new font size cfg setup --- src/raddbg/raddbg_core.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 44fa5e79..4c1e8d7b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12843,21 +12843,33 @@ rd_frame(void) //- rjf: font sizes case RD_CmdKind_IncFontSize: { - fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); - F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size+1); - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("font_size")); - rd_cfg_new_replacef(main_font_size, "%f", new_font_size); + RD_Cfg *cfg = &rd_nil_cfg; + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->view); } + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } + if(cfg != &rd_nil_cfg) + { + fnt_reset(); + F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 new_font_size = current_font_size+1; + new_font_size = ClampBot(1, new_font_size); + RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); + rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); + } }break; case RD_CmdKind_DecFontSize: { - fnt_reset(); - F32 current_font_size = rd_font_size_from_slot(RD_FontSlot_Main); - F32 new_font_size = clamp_1f32(r1f32(6, 72), current_font_size-1); - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_Cfg *main_font_size = rd_cfg_child_from_string_or_alloc(window, str8_lit("font_size")); - rd_cfg_new_replacef(main_font_size, "%f", new_font_size); + RD_Cfg *cfg = &rd_nil_cfg; + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->view); } + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } + if(cfg != &rd_nil_cfg) + { + fnt_reset(); + F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 new_font_size = current_font_size-1; + new_font_size = ClampBot(1, new_font_size); + RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); + rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); + } }break; //- rjf: panel creation From 9bc8641db162d91e9a1c4ca1da4de9829c40f49c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 12:52:47 -0700 Subject: [PATCH 385/755] distinguish row commands vs. expansion commands in cfg evals --- src/raddbg/generated/raddbg.meta.c | 10 ++++---- src/raddbg/raddbg.mdesk | 10 ++++---- src/raddbg/raddbg_core.c | 20 +++++++++++++++ src/raddbg/raddbg_eval.c | 39 +++++++++++++++++++++++++++--- src/raddbg/raddbg_views.c | 2 +- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a8c5cbb4..3adf1153 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -332,11 +332,11 @@ RD_NameSchemaInfo rd_name_schema_info_table[19] = {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f88de859..5af0805d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -262,7 +262,7 @@ RD_VocabTable: { target, ``` - @commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) + @row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) @collection_commands(add_target) x: { @@ -285,7 +285,7 @@ RD_VocabTable: { breakpoint, ``` - @commands(enable_cfg, remove_cfg) + @row_commands(enable_cfg, remove_cfg) @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint) x: { @@ -307,7 +307,7 @@ RD_VocabTable: { watch_pin, ``` - @commands(remove_cfg) + @row_commands(remove_cfg) @collection_commands(add_watch_pin) x: { @@ -322,13 +322,13 @@ RD_VocabTable: //- rjf: file path maps { file_path_map, - ```@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}```, + ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}```, } //- rjf: auto view rules { auto_view_rule, - ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, + ```@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, } //- rjf: recent projects diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4c1e8d7b..46baaa77 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2236,6 +2236,23 @@ rd_view_state_from_cfg(RD_Cfg *cfg) return view_state; } +typedef struct RD_WatchRowExtrasDrawData RD_WatchRowExtrasDrawData; +struct RD_WatchRowExtrasDrawData +{ + B32 breaks_from_prev; +}; + +internal UI_BOX_CUSTOM_DRAW(rd_watch_row_extras_custom_draw) +{ + RD_WatchRowExtrasDrawData *draw_data = (RD_WatchRowExtrasDrawData *)user_data; + if(draw_data->breaks_from_prev) DR_ClipScope(intersect_2f32(dr_top_clip(), box->rect)) + { + Vec4F32 shadow_color = ui_color_from_name(str8_lit("drop_shadow")); + R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y0, box->rect.x1, (box->rect.y0+box->rect.y1)/2), shadow_color, 0, 0, 0); + inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(0, 0, 0, 0); + } +} + internal void rd_view_ui(Rng2F32 rect) { @@ -3946,6 +3963,9 @@ rd_view_ui(Rng2F32 rect) ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + RD_WatchRowExtrasDrawData *row_draw_data = push_array(ui_build_arena(), RD_WatchRowExtrasDrawData, 1); + row_draw_data->breaks_from_prev = !row_matches_last_row_topology; + ui_box_equip_custom_draw(row_box, rd_watch_row_extras_custom_draw, row_draw_data); ////////////////////// //- rjf: build row contents diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7611a0a2..68201878 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -469,6 +469,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) typedef struct RD_SchemaExpandAccel RD_SchemaExpandAccel; struct RD_SchemaExpandAccel { + String8Array commands; MD_Node **children; U64 children_count; }; @@ -482,6 +483,22 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) // rjf: unpack RD_SchemaIRExt *ext = (RD_SchemaIRExt *)irtree->user_data; + // rjf: gather expansion commands + String8Array commands = {0}; + { + String8List commands_list = {0}; + for(MD_NodePtrNode *n = ext->schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + MD_Node *tag = md_tag_from_string(schema, str8_lit("expand_commands"), 0); + for MD_EachNode(arg, tag->first) + { + str8_list_push(scratch.arena, &commands_list, arg->string); + } + } + commands = str8_array_from_list(arena, &commands_list); + } + // rjf: gather expansion children typedef struct ExpandChildNode ExpandChildNode; struct ExpandChildNode @@ -523,12 +540,13 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) // rjf: build accelerator for lookups RD_SchemaExpandAccel *accel = push_array(arena, RD_SchemaExpandAccel, 1); + accel->commands = commands; accel->children = children; accel->children_count = child_count; // rjf: fill result result.user_data = accel; - result.expr_count = child_count; + result.expr_count = child_count + commands.count; scratch_end(scratch); } @@ -538,12 +556,25 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) { RD_SchemaExpandAccel *accel = (RD_SchemaExpandAccel *)user_data; + Rng1U64 cmds_idx_range = r1u64(0, accel->commands.count); + Rng1U64 chld_idx_range = r1u64(cmds_idx_range.max, cmds_idx_range.max + accel->children_count); U64 out_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + + // rjf: read commands { - if(0 <= idx && idx < accel->children_count) + Rng1U64 read_range = intersect_1u64(idx_range, cmds_idx_range); + for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) { - MD_Node *child_schema = accel->children[idx]; + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, accel->commands.v[idx - cmds_idx_range.min]); + } + } + + // rjf: read children + { + Rng1U64 read_range = intersect_1u64(idx_range, chld_idx_range); + for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) + { + MD_Node *child_schema = accel->children[idx - chld_idx_range.min]; exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, child_schema->string); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 01f9afe0..d6fd181d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1173,7 +1173,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { MD_Node *schema = n->v; - MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("row_commands"), 0); for MD_EachNode(cmd, cmds_root->first) { String8 cmd_name = cmd->string; From a2047619c4e018c83590238621174f3913b2ce97 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 13:14:08 -0700 Subject: [PATCH 386/755] window evaluation, provide path to get to per-window settings --- src/raddbg/generated/raddbg.meta.c | 6 ++++-- src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 22 +++++++++++++++++++--- src/raddbg/raddbg_core.h | 1 - src/ui/ui_core.c | 2 +- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 3adf1153..93ad9d9b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[314] = +RD_VocabInfo rd_vocab_info_table[315] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -153,6 +153,7 @@ RD_VocabInfo rd_vocab_info_table[314] = {str8_lit_comp("inc_font_size"), str8_lit_comp(""), str8_lit_comp("Increase Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("dec_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("open_window"), str8_lit_comp(""), str8_lit_comp("Open New Window"), str8_lit_comp(""), RD_IconKind_Window}, +{str8_lit_comp("window_settings"), str8_lit_comp(""), str8_lit_comp("Window Settings"), str8_lit_comp(""), RD_IconKind_Gear}, {str8_lit_comp("close_window"), str8_lit_comp(""), str8_lit_comp("Close Window"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("toggle_fullscreen"), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("bring_to_front"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), str8_lit_comp(""), RD_IconKind_Window}, @@ -389,7 +390,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[213] = +RD_CmdKindInfo rd_cmd_kind_info_table[214] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -437,6 +438,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[213] = { str8_lit_comp("inc_font_size"), str8_lit_comp("Increases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("dec_font_size"), str8_lit_comp("Decreases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("window_settings"), str8_lit_comp("Opens settings for a window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 7948062f..2808a8dd 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -99,6 +99,7 @@ RD_CmdKind_DeselectEntity, RD_CmdKind_IncFontSize, RD_CmdKind_DecFontSize, RD_CmdKind_OpenWindow, +RD_CmdKind_WindowSettings, RD_CmdKind_CloseWindow, RD_CmdKind_ToggleFullscreen, RD_CmdKind_BringToFront, @@ -636,7 +637,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[314]; +extern RD_VocabInfo rd_vocab_info_table[315]; extern RD_NameSchemaInfo rd_name_schema_info_table[19]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5af0805d..9de8ff23 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -492,6 +492,7 @@ RD_CmdTable: // | | | | //- rjf: windows {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {WindowSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "window_settings" "Window Settings" "Opens settings for a window." "" "" } {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 46baaa77..55492ef2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1861,7 +1861,7 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) { U64 file_path_string_id = space.u64_0; String8 file_path = e_string_from_id(file_path_string_id); - result = fs_key_from_path_range(file_path, range); + result = fs_key_from_path_range(file_path, range); }break; case RD_EvalSpaceKind_CtrlEntity: { @@ -2270,7 +2270,7 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); String8 current_input = input_root->first->string; B32 search_row_is_open = (vs->query_is_selected); - F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open, .epsilon = 0.01f); if(search_row_open_t > 0.001f) { String8 cmd_name = cmd_root->first->string; @@ -6859,12 +6859,14 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenWindow].string, rd_cmd_kind_info_table[RD_CmdKind_CloseWindow].string, rd_cmd_kind_info_table[RD_CmdKind_ToggleFullscreen].string, + rd_cmd_kind_info_table[RD_CmdKind_WindowSettings].string, }; U32 codepoints[] = { 'w', 'c', 'f', + 's', }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); @@ -12004,6 +12006,15 @@ rd_frame(void) for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { RD_Cfg *window = n->v; + { + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, window->string); + E_Space space = rd_eval_space_from_cfg(window); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", window->id), expr); + } RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); for(RD_PanelNode *p = panel_tree.root; p != &rd_nil_panel_node; @@ -12522,7 +12533,7 @@ rd_frame(void) //- rjf: open lister case RD_CmdKind_OpenLister: { - String8 expr = push_str8f(scratch.arena, "query:commands, query:recent_files, query:recent_projects, query:procedures, query:$%I64x", rd_regs()->view); + String8 expr = push_str8f(scratch.arena, "query:commands, query:recent_files, query:recent_projects, query:procedures, query:$%I64x, query:$%I64x", rd_regs()->view, rd_regs()->window); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1); }break; @@ -12604,6 +12615,11 @@ rd_frame(void) RD_Cfg *panels = rd_cfg_new(new_window, str8_lit("panels")); rd_cfg_new(panels, str8_lit("selected")); }break; + case RD_CmdKind_WindowSettings: + { + String8 expr = push_str8f(scratch.arena, "query:$%I64x", rd_regs()->window); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1); + }break; case RD_CmdKind_CloseWindow: { RD_CfgList all_windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 67506ca0..68dfb763 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -849,7 +849,6 @@ internal Rng2F32 rd_target_rect_from_panel_node_child(Rng2F32 parent_rect, RD_Pa internal Rng2F32 rd_target_rect_from_panel_node(Rng2F32 root_rect, RD_PanelNode *root, RD_PanelNode *panel); internal B32 rd_cfg_is_project_filtered(RD_Cfg *cfg); - internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_name(Arena *arena, String8 string); internal RD_KeyMapNodePtrList rd_key_map_node_ptr_list_from_binding(Arena *arena, RD_Binding binding); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index eaa812da..1f4f5df3 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -3172,7 +3172,7 @@ ui_anim_(UI_Key key, UI_AnimParams *params) { node->params.epsilon = 0.005f; } - if(node->params.rate == 1) + if(node->params.rate == 1 || abs_f32(node->current - node->params.target) < abs_f32(node->params.epsilon)) { node->current = node->params.target; } From 751f3708e74ce90be636f8e0e5bb0e2dced7f228 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 13:46:06 -0700 Subject: [PATCH 387/755] interval lens, to generate an expansion of N things, to use w/ tables --- src/eval/eval_types.c | 31 ++++++++++++++++ src/eval/eval_types.h | 6 ++++ .../eval_visualization_core.c | 36 +++++++++++++------ src/raddbg/raddbg_core.c | 1 + 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 4db7e20d..44d8c57a 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2281,6 +2281,37 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) return id; } +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `sequence` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(sequence) +{ + E_Type *type = e_type_from_key__cached(irtree->type_key); + U64 count = 0; + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList count_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 count_bytecode = e_bytecode_from_oplist(scratch.arena, &count_oplist); + E_Interpretation count_interpret = e_interpret(count_bytecode); + E_Value count_value = count_interpret.value; + count = count_value.u64; + scratch_end(scratch); + } + E_TypeExpandInfo info = {0, count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence) +{ + U64 read_range_count = dim_1u64(idx_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); + expr->value.u64 = idx_range.min + idx; + exprs_out[idx] = expr; + } +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `array` lens diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index bdc52766..ae1c3dd5 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -309,6 +309,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `sequence` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(sequence); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `array` lens diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5a095cbf..e4ae439a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -84,17 +84,33 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; { - E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); - E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); - if(expand_type_kind == E_TypeKind_Struct || - expand_type_kind == E_TypeKind_Union || - expand_type_kind == E_TypeKind_Class || - expand_type_kind == E_TypeKind_Array || - expand_type_kind == E_TypeKind_Set || - e_type_kind_is_pointer_or_ref(expand_type_kind) || - (expand_type_kind == E_TypeKind_Enum && mode == E_Mode_Null)) + if(e_type_kind_from_key(type_key) == E_TypeKind_Lens) { - result = 1; + for(E_Type *lens_type = e_type_from_key__cached(type_key); + lens_type->kind == E_TypeKind_Lens; + lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + { + if(lens_type->expand.info != 0) + { + result = 1; + break; + } + } + } + else + { + E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); + E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); + if(expand_type_kind == E_TypeKind_Struct || + expand_type_kind == E_TypeKind_Union || + expand_type_kind == E_TypeKind_Class || + expand_type_kind == E_TypeKind_Array || + expand_type_kind == E_TypeKind_Set || + e_type_kind_is_pointer_or_ref(expand_type_kind) || + (expand_type_kind == E_TypeKind_Enum && mode == E_Mode_Null)) + { + result = 1; + } } } return result; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 55492ef2..ca291bd4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12365,6 +12365,7 @@ rd_frame(void) {str8_lit("digits"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("sequence"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(sequence), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(sequence)}}, {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, From f3974b2af7a1cff8c36eeefb9c738a2c04d40994 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 15:36:43 -0700 Subject: [PATCH 388/755] only/omit; disallow chained fastpaths (vs-style ,x ; ,b; ,count) in nested irtree generations --- src/eval/eval_ir.c | 5 + src/eval/eval_ir.h | 1 + src/eval/eval_types.c | 122 ++++++++++++++++++ src/eval/eval_types.h | 7 + .../eval_visualization_core.c | 29 +---- src/raddbg/raddbg_core.c | 2 + src/raddbg/raddbg_views.c | 4 +- 7 files changed, 144 insertions(+), 26 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5ede2ff9..49b61863 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1565,6 +1565,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: call case E_ExprKind_Call: { + B32 start_disallow_chained_fastpaths = e_ir_state->disallow_chained_fastpaths; + e_ir_state->disallow_chained_fastpaths = 1; E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; @@ -1669,6 +1671,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); } + + e_ir_state->disallow_chained_fastpaths = start_disallow_chained_fastpaths; }break; //- rjf: leaf bytecode @@ -2258,6 +2262,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: check chained expressions for simple wrappers + if(!e_ir_state->disallow_chained_fastpaths) { struct { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 67b8f51a..60c0226b 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -155,6 +155,7 @@ struct E_IRState // rjf: overridden irtree E_IRTreeAndType *overridden_irtree; B32 disallow_autohooks; + B32 disallow_chained_fastpaths; // rjf: caches E_UsedExprMap *used_expr_map; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 44d8c57a..d25fb04c 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1402,6 +1402,30 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) return members; } +internal E_TypeExpandRule * +e_expand_rule_from_type_key(E_TypeKey key) +{ + E_TypeExpandRule *rule = &e_type_expand_rule__default; + { + E_Type *type = e_type_from_key__cached(key); + if(type->expand.info != 0) + { + rule = &type->expand; + } + for(E_Type *lens_type = type; + lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; + lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + { + if(lens_type->expand.info != 0) + { + rule = &lens_type->expand; + break; + } + } + } + return rule; +} + //- rjf: type key traversal internal E_TypeKey @@ -2281,6 +2305,104 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) return id; } +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `only` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(only) +{ + E_Type *type = e_type_from_key__cached(irtree->type_key); + E_TypeExpandInfo info = {0, type->count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) +{ + E_Type *type = e_type_from_key__cached(irtree->type_key); + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + E_Expr *arg = type->args[idx]; + if(arg->string.size != 0) + { + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, arg->string); + } + } +} + +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `omit` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) +{ + E_Type *type = e_type_from_key__cached(irtree->type_key); + String8Array allowed_children_array = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + String8List allowed_children = {0}; + { + E_Type *stripped_type = e_type_from_key__cached(type->direct_type_key); + // TODO(rjf): this is kind of ugly due to the need to call irext, + // i wish it was possible to have an easier way to "strip" the current + // lens & evaluate the wrapped expression? + E_IRTreeAndType irtree_stripped = *irtree; + irtree_stripped.type_key = type->direct_type_key; + irtree_stripped.user_data = stripped_type->irext ? stripped_type->irext(scratch.arena, expr, &irtree_stripped).user_data : 0; + E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(irtree_stripped.type_key); + E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, expr, &irtree_stripped, filter); + if(expand_info.expr_count < 4096) + { + E_Expr **exprs = push_array(scratch.arena, E_Expr *, expand_info.expr_count); + String8 *exprs_strings = push_array(scratch.arena, String8, expand_info.expr_count); + for EachIndex(idx, expand_info.expr_count) + { + exprs[idx] = &e_expr_nil; + } + expand_rule->range(scratch.arena, expand_info.user_data, expr, &irtree_stripped, filter, r1u64(0, expand_info.expr_count), exprs, exprs_strings); + for EachIndex(idx, expand_info.expr_count) + { + if(exprs[idx]->kind == E_ExprKind_MemberAccess) + { + String8 name = exprs[idx]->first->next->string; + B32 name_is_allowed = 1; + for EachIndex(arg_idx, type->count) + { + if(str8_match(type->args[arg_idx]->string, name, 0)) + { + name_is_allowed = 0; + break; + } + } + if(name_is_allowed) + { + str8_list_push(scratch.arena, &allowed_children, push_str8_copy(arena, name)); + } + } + } + } + } + allowed_children_array = str8_array_from_list(arena, &allowed_children); + scratch_end(scratch); + } + String8Array *ext = push_array(arena, String8Array, 1); + *ext = allowed_children_array; + E_TypeExpandInfo info = {ext, ext->count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(omit) +{ + String8Array *ext = (String8Array *)user_data; + U64 out_idx = 0; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 name = ext->v[idx]; + if(name.size != 0) + { + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, name); + } + } +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `sequence` lens diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index ae1c3dd5..20636b29 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -268,6 +268,7 @@ internal U64 e_type_byte_size_from_key(E_TypeKey key); internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b); internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key); +internal E_TypeExpandRule *e_expand_rule_from_type_key(E_TypeKey key); //- rjf: type key traversal internal E_TypeKey e_type_key_direct(E_TypeKey key); @@ -309,6 +310,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); +//////////////////////////////// +//~ rjf: (Built-In Type Hooks) `only` lens + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(only); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) `sequence` lens diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index e4ae439a..61526059 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -84,7 +84,7 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; { - if(e_type_kind_from_key(type_key) == E_TypeKind_Lens) + if(!result && e_type_kind_from_key(type_key) == E_TypeKind_Lens) { for(E_Type *lens_type = e_type_from_key__cached(type_key); lens_type->kind == E_TypeKind_Lens; @@ -97,7 +97,7 @@ ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) } } } - else + if(!result) { E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); @@ -574,24 +574,9 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp // rjf: unpack eval E_Mode mode = t->eval.irtree.mode; E_TypeKey type_key = t->eval.irtree.type_key; - E_Type *type = e_type_from_key__cached(type_key); - E_TypeExpandRule *type_expand_rule = &e_type_expand_rule__default; - if(type->expand.info != 0) - { - type_expand_rule = &type->expand; - } - for(E_Type *lens_type = type; - lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; - lens_type = e_type_from_key__cached(lens_type->direct_type_key)) - { - if(lens_type->expand.info != 0) - { - type_expand_rule = &lens_type->expand; - break; - } - } - // rjf: get eval's visualization expansion rule + // rjf: get expansion rules from type + E_TypeExpandRule *type_expand_rule = e_expand_rule_from_type_key(type_key); EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(type_key); // rjf: skip if no expansion rule, & type info disallows expansion @@ -2094,11 +2079,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); expand_data->type = e_type_from_key__cached(type_key); - expand_data->expand_rule = &e_type_expand_rule__default; - if(expand_data->type->expand.info != 0) - { - expand_data->expand_rule = &expand_data->type->expand; - } + expand_data->expand_rule = e_expand_rule_from_type_key(type_key); expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); } switch(task_idx) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ca291bd4..2d3fed09 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12366,6 +12366,8 @@ rd_frame(void) {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, {str8_lit("sequence"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(sequence), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(sequence)}}, + {str8_lit("only"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only)}}, + {str8_lit("omit"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(omit)}}, {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d6fd181d..4c4ef5ff 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1079,7 +1079,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(0){} // rjf: table rows - else if(maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) + else if(block->parent != &ev_nil_block && maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) { U64 column_count = maybe_table_type->count; info.cell_style_key = push_str8f(arena, "table_%I64u_cols", column_count); @@ -1371,7 +1371,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof(raw($expr))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } } From 559f1baae1aaa1b74171b96dfc1ac9baeac2ca6e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 16:05:31 -0700 Subject: [PATCH 389/755] begin fitting settings into window evaluation --- src/mule/mule_main.cpp | 50 ++++++++++++++++++++---------- src/raddbg/generated/raddbg.meta.c | 10 ++++-- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 31 ++++++++++++++++-- src/raddbg/raddbg_core.c | 6 ++-- 5 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 2f3cd9de..cac984ce 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -108,7 +108,8 @@ void optimized_struct_parameters_eval_tests(void); raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); -struct Basics{ +struct Basics +{ char a; unsigned char b; short c; @@ -119,11 +120,11 @@ struct Basics{ unsigned long long h; float i; double j; - int z; }; -struct Basics_Stdint{ +struct Basics_Stdint +{ int8_t a; uint8_t b; int16_t c; @@ -136,23 +137,27 @@ struct Basics_Stdint{ double j; }; -struct Pair{ +struct Pair +{ int x; float y; }; -struct Fixed_Array{ +struct Fixed_Array +{ Pair pairs[10]; int count; }; -struct Dynamic_Array{ +struct Dynamic_Array +{ Pair *pairs; int count; }; raddbg_auto_view_rule(Dynamic_Array, slice($)); -struct Struct_With_Embedded_Arrays{ +struct Struct_With_Embedded_Arrays +{ int x; float y; Pair pairs[10]; @@ -173,13 +178,16 @@ struct Callback{ Pair pair; }; -union Vector_R2{ - struct{ +union Vector_R2 +{ + struct + { float x; float y; }; float v[2]; }; +raddbg_auto_view_rule(Vector_R2, only($, x, y)); typedef union Matrix4x4F32 Matrix4x4F32; union Matrix4x4F32 @@ -188,7 +196,8 @@ union Matrix4x4F32 }; raddbg_auto_view_rule(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); -enum Kind{ +enum Kind +{ Kind_None, Kind_First, Kind_Second, @@ -197,7 +206,8 @@ enum Kind{ Kind_COUNT, }; -enum Flag{ +enum Flag +{ Flag_None = 0, Flag_First = 1, Flag_Second = 2, @@ -208,25 +218,31 @@ enum Flag{ Flag_All = 0xFFFFFFFF, }; -struct Has_Enums{ +struct Has_Enums +{ Kind kind; Flag flags; }; -struct Discriminated_Union{ +struct Discriminated_Union +{ Kind kind; - union{ - struct{ + union + { + struct + { int x; int y; Vector_R2 vector; } first; Pair second; - struct{ + struct + { Function_Few_Params_Type *few_params; Pair pairs[4]; } third; - struct{ + struct + { Kind sub_kind; Flag flags; } fourth; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 93ad9d9b..747d9a37 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[315] = +RD_VocabInfo rd_vocab_info_table[319] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -108,6 +108,10 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("pitch"), str8_lit_comp(""), str8_lit_comp("Pitch"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("zoom"), str8_lit_comp(""), str8_lit_comp("Zoom"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("font_size"), str8_lit_comp(""), str8_lit_comp("Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("smooth_ui_text"), str8_lit_comp(""), str8_lit_comp("Smooth UI Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("smooth_code_text"), str8_lit_comp(""), str8_lit_comp("Smooth Code Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("hint_ui_text"), str8_lit_comp(""), str8_lit_comp("Hint UI Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("hint_code_text"), str8_lit_comp(""), str8_lit_comp("Hint Code Text"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -325,8 +329,8 @@ RD_VocabInfo rd_vocab_info_table[315] = RD_NameSchemaInfo rd_name_schema_info_table[19] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_main_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_main_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 2808a8dd..2e0fdf95 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -637,7 +637,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[315]; +extern RD_VocabInfo rd_vocab_info_table[319]; extern RD_NameSchemaInfo rd_name_schema_info_table[19]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9de8ff23..06140c07 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -121,6 +121,10 @@ RD_VocabTable: {pitch "" "Pitch" "" Null } {zoom "" "Zoom" "" Null } {font_size "" "Font Size" "" Null } + {smooth_ui_text "" "Smooth UI Text" "" Null } + {smooth_code_text "" "Smooth Code Text" "" Null } + {hint_ui_text "" "Hint UI Text" "" Null } + {hint_code_text "" "Hint Code Text" "" Null } } @struct RD_VocabInfo: @@ -161,9 +165,9 @@ RD_VocabTable: @default(1) 'thread_glow': bool, @default(1) 'breakpoint_glow': bool, @default(0) 'opaque_backgrounds': bool, - @default(1) 'smooth_main_text': bool, + @default(1) 'smooth_ui_text': bool, @default(0) 'smooth_code_text': bool, - @default(1) 'hint_main_text': bool, + @default(1) 'hint_ui_text': bool, @default(1) 'hint_code_text': bool, @default(2) 'tab_width': @range[1, 32] u64, @default(11) 'font_size': @range[6, 72] u64, @@ -177,6 +181,29 @@ RD_VocabTable: ``` x: { + //- rjf: animations + @default(1) 'hover_animations': bool, + @default(1) 'press_animations': bool, + @default(0) 'focus_animations': bool, + @default(1) 'tooltip_animations': bool, + @default(1) 'menu_animations': bool, + @default(1) 'scrolling_animations': bool, + + //- rjf: thread & breakpoint decorations + @default(1) 'thread_lines': bool, + @default(1) 'thread_glow': bool, + @default(1) 'breakpoint_lines': bool, + @default(1) 'breakpoint_glow': bool, + + //- rjf: occluding background settings + @default(0) 'opaque_backgrounds': bool, + @default(1) 'background_blur': bool, + + //- rjf: text rasterization settings + @default(1) 'smooth_ui_text': bool, + @default(1) 'hint_ui_text': bool, + @default(0) 'smooth_code_text': bool, + @default(1) 'hint_code_text': bool, @default(11) 'font_size': @range[6, 72] u64, } ``` diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2d3fed09..41d14efb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5507,8 +5507,8 @@ rd_window_frame(void) ui_push_pref_height(ui_px(floor_f32(ui_top_font_size()*3.f), 1.f)); ui_push_blur_size(10.f); FNT_RasterFlags text_raster_flags = 0; - if(rd_setting_b32_from_name(str8_lit("smooth_main_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} - if(rd_setting_b32_from_name(str8_lit("hint_main_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} + if(rd_setting_b32_from_name(str8_lit("smooth_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Smooth;} + if(rd_setting_b32_from_name(str8_lit("hint_ui_text"))) {text_raster_flags |= FNT_RasterFlag_Hinted;} ui_push_text_raster_flags(text_raster_flags); } @@ -10452,7 +10452,7 @@ rd_raster_flags_from_slot(RD_FontSlot slot) { default:{}break; case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break; - case RD_FontSlot_Main: {flags = (rd_setting_b32_from_name(str8_lit("smooth_main_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_main_text"))*FNT_RasterFlag_Hinted);}break; + case RD_FontSlot_Main: {flags = (rd_setting_b32_from_name(str8_lit("smooth_ui_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_ui_text"))*FNT_RasterFlag_Hinted);}break; case RD_FontSlot_Code: {flags = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; } return flags; From 79b6ee49594a430ff83d2ed7ab8deb3155bc6fdf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 16:26:13 -0700 Subject: [PATCH 390/755] fix permanent growth of transient cfg trees, ensure correct recycling as old cfg trees for module-defined auto view rules etc. --- src/raddbg/raddbg_core.c | 87 ++++++++++++++++++++++++++++++++++++---- src/raddbg/raddbg_core.h | 6 +++ 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 41d14efb..6c91aa09 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1254,7 +1254,7 @@ rd_immediate_cfg_from_key(String8 string) immediate = rd_cfg_new(transient, str8_lit("immediate")); cfg = rd_cfg_new(immediate, string); } - rd_cfg_new(immediate, str8_lit("hot")); + rd_cfg_child_from_string_or_alloc(immediate, str8_lit("hot")); return cfg; } @@ -5742,7 +5742,7 @@ rd_window_frame(void) } if(immediate_parent != &rd_nil_cfg) { - rd_cfg_new(immediate_parent, str8_lit("hot")); + rd_cfg_child_from_string_or_alloc(immediate_parent, str8_lit("hot")); } UI_Size main_width = ui_top_pref_width(); UI_Size main_height = ui_top_pref_height(); @@ -6620,7 +6620,7 @@ rd_window_frame(void) // rjf: build cfg tree RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new(view, str8_lit("selected")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); rd_cfg_new_replace(expr_root, expr); // rjf: push view regs @@ -10913,6 +10913,10 @@ rd_init(CmdLine *cmdln) cmd_line_has_flag(cmdln, str8_lit("q"))); rd_state->user_path_arena = arena_alloc(); rd_state->project_path_arena = arena_alloc(); + rd_state->user_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_user_data_string_key")); + rd_state->project_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_project_data_string_key")); + rd_state->cmdln_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_cmdln_data_string_key")); + rd_state->transient_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_transient_data_string_key")); for(U64 idx = 0; idx < ArrayCount(rd_state->frame_arenas); idx += 1) { rd_state->frame_arenas[idx] = arena_alloc(); @@ -11174,6 +11178,32 @@ rd_frame(void) Temp scratch = scratch_begin(0, 0); log_scope_begin(); + ////////////////////////////// + //- rjf: (DEBUG) take top-level cfg roots, stringize them, and store them to hash store + // +#if 0 + { + struct + { + U128 key; + String8 name; + } + table[] = + { + {rd_state->user_cfg_string_key, str8_lit("user")}, + {rd_state->project_cfg_string_key, str8_lit("project")}, + {rd_state->cmdln_cfg_string_key, str8_lit("command_line")}, + {rd_state->transient_cfg_string_key, str8_lit("transient")}, + }; + for EachElement(idx, table) + { + Arena *arena = arena_alloc(); + String8 data = rd_string_from_cfg_tree(arena, rd_cfg_child_from_string(rd_state->root_cfg, table[idx].name)); + hs_submit_data(table[idx].key, &arena, data); + } + } +#endif + ////////////////////////////// //- rjf: do per-frame resets // @@ -11242,7 +11272,14 @@ rd_frame(void) { if(str8_match(tln->string, str8_lit("immediate"), 0)) { - rd_cfg_release(rd_cfg_child_from_string(tln, str8_lit("hot"))); + for(RD_Cfg *child = tln->first, *next = &rd_nil_cfg; child != &rd_nil_cfg; child = next) + { + next = child->next; + if(str8_match(child->string, str8_lit("hot"), 0)) + { + rd_cfg_release(child); + } + } } } } @@ -12276,6 +12313,39 @@ rd_frame(void) hs_scope_close(hs_scope); } + //- rjf: (DEBUG) add macro for cfg strings +#if 0 + { + struct + { + U128 key; + String8 name; + } + table[] = + { + {rd_state->user_cfg_string_key, str8_lit("raddbg_user_data")}, + {rd_state->project_cfg_string_key, str8_lit("raddbg_project_data")}, + {rd_state->cmdln_cfg_string_key, str8_lit("raddbg_command_line_data")}, + {rd_state->transient_cfg_string_key, str8_lit("raddbg_transient_data")}, + }; + for EachElement(idx, table) + { + HS_Scope *hs_scope = hs_scope_open(); + U128 key = table[idx].key; + U128 hash = hs_hash_from_key(key, 0); + String8 data = hs_data_from_hash(hs_scope, hash); + E_Space space = e_space_make(E_SpaceKind_HashStoreKey); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + space.u128 = key; + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); + e_string2expr_map_insert(scratch.arena, ctx->macro_map, table[idx].name, expr); + hs_scope_close(hs_scope); + } + } +#endif + //- rjf: add macros for all watches which define identifiers RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); for(RD_CfgNode *n = watches.first; n != 0; n = n->next) @@ -12301,13 +12371,16 @@ rd_frame(void) String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, module->handle); U8 split_char = 0; String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); + U64 cfg_idx = 0; for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) { String8 text = text_n->string; RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); - RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, module->handle)); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + String8 module_name = ctrl_string_from_handle(scratch.arena, module->handle); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next, cfg_idx += 1) { + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfg_%I64x", module_name, cfg_idx); + rd_cfg_release_all_children(immediate_root); rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); } @@ -12616,7 +12689,7 @@ rd_frame(void) } } RD_Cfg *panels = rd_cfg_new(new_window, str8_lit("panels")); - rd_cfg_new(panels, str8_lit("selected")); + rd_cfg_child_from_string_or_alloc(panels, str8_lit("selected")); }break; case RD_CmdKind_WindowSettings: { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 68dfb763..30ec872a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -597,6 +597,12 @@ struct RD_State Arena *project_path_arena; String8 project_path; + // rjf: serialized config debug string keys + U128 user_cfg_string_key; + U128 project_cfg_string_key; + U128 cmdln_cfg_string_key; + U128 transient_cfg_string_key; + // rjf: schema table MD_NodePtrList *schemas; From 2925161c3ac92d2246d76b1d362a39a984a20738 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 16:29:38 -0700 Subject: [PATCH 391/755] sequence/table visualization test in mule --- src/mule/mule_main.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index cac984ce..3e1d6cfe 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -330,7 +330,8 @@ type_coverage_eval_tests(void) Basics *pointer_to_basics = &basics; Basics **pointer_to_pointer_to_basics = &pointer_to_basics; - Fixed_Array fixed = { + Fixed_Array fixed = + { { { 3, 4.f}, { 5, 6.f}, @@ -344,7 +345,8 @@ type_coverage_eval_tests(void) }, 9 }; - Pair memory_[] = { + Pair memory_[] = + { {100, 1.f}, {101, 2.f}, {102, 4.f}, @@ -352,11 +354,13 @@ type_coverage_eval_tests(void) {104, 16.f}, {105, 32.f}, }; - Dynamic_Array dynamic = { + Dynamic_Array dynamic = + { memory_, 6 }; + raddbg_pin(table(sequence(6), fixed.pairs[$], memory_[$])); raddbg_pin(basics); raddbg_pin(fixed); raddbg_pin(pointer); From 2fd5e743b94b8260081aaa6ced8d85f494373ec4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 17 Apr 2025 16:35:01 -0700 Subject: [PATCH 392/755] eliminate old font size code --- src/raddbg/raddbg_core.c | 38 -------------------------------------- src/raddbg/raddbg_core.h | 3 +-- 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6c91aa09..61b8225d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10406,44 +10406,6 @@ rd_font_from_slot(RD_FontSlot slot) return result; } -internal F32 -rd_font_size_from_slot(RD_FontSlot slot) -{ - F32 result = (F32)rd_setting_u64_from_name(str8_lit("font_size")); - return result; -#if 0 - F32 result = 11.f; - - // rjf: determine config key based on slot - String8 key = {0}; - switch(slot) - { - default:{}break; - case RD_FontSlot_Icons: - case RD_FontSlot_Main:{key = str8_lit("main_font_size");}break; - case RD_FontSlot_Code:{key = str8_lit("code_font_size");}break; - } - - // rjf: given key, find setting string - String8 setting_string = rd_setting_from_name(key); - - // rjf: if found, map setting string -> f64; otherwise use the window's monitor's DPI - // based on some default size. - if(setting_string.size) - { - result = (F32)f64_from_str8(setting_string); - } - else - { - RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - F32 dpi = os_dpi_from_window(ws->os); - result = 11.f * (dpi / 96.f); - } - return result; -#endif -} - internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 30ec872a..9bf7145f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1012,9 +1012,8 @@ internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); -//- rjf: fonts/sizes +//- rjf: fonts internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); -internal F32 rd_font_size_from_slot(RD_FontSlot slot); internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); //////////////////////////////// From ddf0703b02da136c4c2fb6d81c279afae1dda960 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 11:03:40 -0700 Subject: [PATCH 393/755] fix scroll bar size in watch views with changed font size, fix type evaluations --- src/eval/eval_ir.c | 1 + src/raddbg/generated/raddbg.meta.c | 9 ++++++--- src/raddbg/generated/raddbg.meta.h | 4 ++-- src/raddbg/raddbg.mdesk | 10 +++++++++- src/raddbg/raddbg_core.c | 14 +++++++------- src/raddbg/raddbg_widgets.c | 6 +++--- src/ui/ui_basic_widgets.c | 2 +- 7 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 49b61863..e19d243d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2142,6 +2142,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) { generated = 1; + result.root = e_irtree_const_u(arena, 0); result.type_key = mapped_type_key; result.mode = E_Mode_Null; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 747d9a37..758afa21 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[319] = +RD_VocabInfo rd_vocab_info_table[321] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -112,6 +112,8 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("smooth_code_text"), str8_lit_comp(""), str8_lit_comp("Smooth Code Text"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("hint_ui_text"), str8_lit_comp(""), str8_lit_comp("Hint UI Text"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("hint_code_text"), str8_lit_comp(""), str8_lit_comp("Hint Code Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("opaque_backgrounds"), str8_lit_comp(""), str8_lit_comp("Opaque Backgrounds"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("background_blur"), str8_lit_comp(""), str8_lit_comp("Background Blur"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -327,11 +329,12 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[19] = +RD_NameSchemaInfo rd_name_schema_info_table[20] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, @@ -339,7 +342,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[19] = {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 2e0fdf95..8f9c5748 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -637,8 +637,8 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[319]; -extern RD_NameSchemaInfo rd_name_schema_info_table[19]; +extern RD_VocabInfo rd_vocab_info_table[321]; +extern RD_NameSchemaInfo rd_name_schema_info_table[20]; extern Rng1U64 rd_reg_slot_range_table[40]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 06140c07..b4f20af2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -125,6 +125,8 @@ RD_VocabTable: {smooth_code_text "" "Smooth Code Text" "" Null } {hint_ui_text "" "Hint UI Text" "" Null } {hint_code_text "" "Hint Code Text" "" Null } + {opaque_backgrounds "" "Opaque Backgrounds" "" Null } + {background_blur "" "Background Blur" "" Null } } @struct RD_VocabInfo: @@ -221,6 +223,13 @@ RD_VocabTable: } //- rjf: views + { + watch, + ``` + @inherit(tab) x: + {} + ``` + } { text, ``` @@ -339,7 +348,6 @@ RD_VocabTable: x: { 'expression': code_string, - 'view_rule': code_string, 'source_location': path_pt, 'address_location': code_string, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 61b8225d..4a009300 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3617,7 +3617,7 @@ rd_view_ui(Rng2F32 rect) ProfScope("build ui") { Vec2F32 rect_dim = dim_2f32(rect); - F32 contents_width_px = (rect_dim.x - floor_f32(ui_top_font_size()*1.5f)); + F32 contents_width_px = (rect_dim.x - floor_f32(ui_bottom_font_size()*1.5f)); Rng1S64 visible_row_rng = {0}; UI_ScrollListParams scroll_list_params = {0}; { @@ -4426,12 +4426,12 @@ rd_view_ui(Rng2F32 rect) case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; } } - else if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || - row->eval.space.kind == E_SpaceKind_FileSystem || - row->eval.space.kind == E_SpaceKind_File || - row->eval.space.kind == E_SpaceKind_Null) + else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity || + cell_info.eval.space.kind == E_SpaceKind_FileSystem || + cell_info.eval.space.kind == E_SpaceKind_File || + cell_info.eval.space.kind == E_SpaceKind_Null) { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, row->eval.expr)) + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell_info.eval.expr)) rd_drag_begin(RD_RegSlot_Expr); } } @@ -6548,7 +6548,7 @@ rd_window_frame(void) E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); // rjf: compute query view's top-level rectangle - F32 row_height_px = ui_top_px_height(); + F32 row_height_px = floor_f32(ui_top_px_height()); Rng2F32 rect = {0}; RD_RegsScope(.view = view->id) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b4bad7ed..e496ac44 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3136,7 +3136,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: unpack visual metrics // - F32 expander_size_px = ui_top_font_size()*2.f; + F32 expander_size_px = floor_f32(ui_top_font_size()*2.f); ////////////////////////////// //- rjf: make key @@ -3281,8 +3281,8 @@ rd_cell(RD_CellParams *params, String8 string) if(params->flags & RD_CellFlag_Slider && !is_focus_active) UI_Parent(box) { - F32 padding_px = floor_f32(ui_top_font_size()*0.65f); - F32 height_px = ui_top_px_height() - padding_px*2.f; + F32 height_px = ui_top_font_size() * 1.75f; + F32 padding_px = (ui_top_px_height() - height_px) / 2.f; UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 27361e8f..8e06f4a0 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -1457,7 +1457,7 @@ ui_scroll_list_begin(UI_ScrollListParams *params, UI_ScrollPt *scroll_pt, Vec2S6 *visible_row_range_out = visible_row_range; //- rjf: store thread-locals - ui_scroll_list_scroll_bar_dim_px = ui_top_font_size()*1.5f; + ui_scroll_list_scroll_bar_dim_px = ui_bottom_font_size()*1.5f; ui_scroll_list_scroll_pt_ptr = scroll_pt; ui_scroll_list_dim_px = params->dim_px; ui_scroll_list_scroll_idx_rng = scroll_row_idx_range; From ff35db0e16373833bf8c42bdfc55c039ea109008 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 13:48:31 -0700 Subject: [PATCH 394/755] more eval type operators for metadata decorations; fix target environment string list evaluation / edits --- src/eval/eval.mdesk | 2 + src/eval/eval_types.c | 23 +++++ src/eval/eval_types.h | 3 + src/eval/generated/eval.meta.c | 8 +- src/eval/generated/eval.meta.h | 6 +- src/raddbg/generated/raddbg.meta.c | 7 +- src/raddbg/generated/raddbg.meta.h | 5 +- src/raddbg/raddbg.mdesk | 5 +- src/raddbg/raddbg_core.c | 129 ++++++++++++++++++----------- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_eval.c | 52 ++++++++---- src/raddbg/raddbg_views.c | 37 +++++---- src/raddbg/raddbg_views.h | 3 +- src/raddbg/raddbg_widgets.c | 12 +-- 14 files changed, 192 insertions(+), 101 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index b70e3fbb..e4d88531 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -75,6 +75,8 @@ E_TypeKindTable: {Lens "lens" 0 } {LensSpec "lens_spec" 0 } {MetaExpr "meta_expr" 0 } + {MetaDisplayName "meta_display_name" 0 } + {MetaDescription "meta_description" 0 } } @table(name op_kind precedence op_pre op_sep op_pos op_chain) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d25fb04c..3135aea8 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -492,6 +492,27 @@ e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlag return key; } +internal E_TypeKey +e_type_key_cons_meta_expr(E_TypeKey type_key, String8 expr) +{ + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .direct_key = type_key, .name = expr); + return key; +} + +internal E_TypeKey +e_type_key_cons_meta_display_name(E_TypeKey type_key, String8 name) +{ + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_MetaDisplayName, .direct_key = type_key, .name = name); + return key; +} + +internal E_TypeKey +e_type_key_cons_meta_description(E_TypeKey type_key, String8 desc) +{ + E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_MetaDescription, .direct_key = type_key, .name = desc); + return key; +} + internal E_TypeKey e_type_key_cons_base(Type *type) { @@ -1492,6 +1513,8 @@ e_type_key_unwrap(E_TypeKey key, E_TypeUnwrapFlags flags) default:{done = 1;}break; case E_TypeKind_Modifier: {done = !(flags & E_TypeUnwrapFlag_Modifiers);}break; case E_TypeKind_Lens: {done = !(flags & E_TypeUnwrapFlag_Lenses);}break; + case E_TypeKind_MetaDisplayName: + case E_TypeKind_MetaDescription: case E_TypeKind_MetaExpr: {done = !(flags & E_TypeUnwrapFlag_Meta);}break; case E_TypeKind_Enum: {done = !(flags & E_TypeUnwrapFlag_Enums);}break; case E_TypeKind_Alias: {done = !(flags & E_TypeUnwrapFlag_Aliases);}break; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 20636b29..4efa66ad 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -254,6 +254,9 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); //- rjf: constructed type construction helpers internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags); +internal E_TypeKey e_type_key_cons_meta_expr(E_TypeKey type_key, String8 expr); +internal E_TypeKey e_type_key_cons_meta_display_name(E_TypeKey type_key, String8 name); +internal E_TypeKey e_type_key_cons_meta_description(E_TypeKey type_key, String8 desc); internal E_TypeKey e_type_key_cons_base(Type *type); internal E_TypeKey e_type_key_file(void); internal E_TypeKey e_type_key_folder(void); diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index cf45b3a3..86a8ea6e 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"), str8_lit_comp("Symbol"), }; -String8 e_type_kind_basic_string_table[59] = +String8 e_type_kind_basic_string_table[61] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -75,9 +75,11 @@ str8_lit_comp("set"), str8_lit_comp("lens"), str8_lit_comp("lens_spec"), str8_lit_comp("meta_expr"), +str8_lit_comp("meta_display_name"), +str8_lit_comp("meta_description"), }; -U8 e_type_kind_basic_byte_size_table[59] = +U8 e_type_kind_basic_byte_size_table[61] = { 0, 0, @@ -138,6 +140,8 @@ U8 e_type_kind_basic_byte_size_table[59] = 0, 0, 0, +0, +0, }; String8 e_expr_kind_strings[48] = diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 6ba7a85e..5bd73d8d 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -78,6 +78,8 @@ E_TypeKind_Set, E_TypeKind_Lens, E_TypeKind_LensSpec, E_TypeKind_MetaExpr, +E_TypeKind_MetaDisplayName, +E_TypeKind_MetaDescription, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -163,8 +165,8 @@ E_InterpretationCode_COUNT, C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; -extern String8 e_type_kind_basic_string_table[59]; -extern U8 e_type_kind_basic_byte_size_table[59]; +extern String8 e_type_kind_basic_string_table[61]; +extern U8 e_type_kind_basic_byte_size_table[61]; extern String8 e_expr_kind_strings[48]; extern E_OpInfo e_expr_kind_op_info_table[48]; extern String8 e_interpretation_code_display_strings[11]; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 758afa21..8d4ad735 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -332,8 +332,8 @@ RD_VocabInfo rd_vocab_info_table[321] = RD_NameSchemaInfo rd_name_schema_info_table[20] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, @@ -353,7 +353,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[20] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[40] = +Rng1U64 rd_reg_slot_range_table[41] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -390,6 +390,7 @@ Rng1U64 rd_reg_slot_range_table[40] = {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, {OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, {OffsetOf(RD_Regs, do_implicit_root), OffsetOf(RD_Regs, do_implicit_root) + sizeof(B32)}, +{OffsetOf(RD_Regs, do_lister), OffsetOf(RD_Regs, do_lister) + sizeof(B32)}, {OffsetOf(RD_Regs, dir2), OffsetOf(RD_Regs, dir2) + sizeof(Dir2)}, {OffsetOf(RD_Regs, string), OffsetOf(RD_Regs, string) + sizeof(String8)}, {OffsetOf(RD_Regs, cmd_name), OffsetOf(RD_Regs, cmd_name) + sizeof(String8)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 8f9c5748..d268dc5c 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -43,6 +43,7 @@ RD_RegSlot_ForceConfirm, RD_RegSlot_PreferDisasm, RD_RegSlot_NoRichTooltip, RD_RegSlot_DoImplicitRoot, +RD_RegSlot_DoLister, RD_RegSlot_Dir2, RD_RegSlot_String, RD_RegSlot_CmdName, @@ -567,6 +568,7 @@ B32 force_confirm; B32 prefer_disasm; B32 no_rich_tooltip; B32 do_implicit_root; +B32 do_lister; Dir2 dir2; String8 string; String8 cmd_name; @@ -630,6 +632,7 @@ RD_Query query; .prefer_disasm = rd_regs()->prefer_disasm,\ .no_rich_tooltip = rd_regs()->no_rich_tooltip,\ .do_implicit_root = rd_regs()->do_implicit_root,\ +.do_lister = rd_regs()->do_lister,\ .dir2 = rd_regs()->dir2,\ .string = rd_regs()->string,\ .cmd_name = rd_regs()->cmd_name,\ @@ -639,7 +642,7 @@ RD_Query query; C_LINKAGE_BEGIN extern RD_VocabInfo rd_vocab_info_table[321]; extern RD_NameSchemaInfo rd_name_schema_info_table[20]; -extern Rng1U64 rd_reg_slot_range_table[40]; +extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[74]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b4f20af2..284aeb92 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -206,7 +206,7 @@ RD_VocabTable: @default(1) 'hint_ui_text': bool, @default(0) 'smooth_code_text': bool, @default(1) 'hint_code_text': bool, - @default(11) 'font_size': @range[6, 72] u64, + @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64, } ``` } @@ -217,7 +217,7 @@ RD_VocabTable: ``` x: { - @default(11) 'font_size': @range[6, 72] u64, + @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64, } ``` } @@ -461,6 +461,7 @@ RD_RegTable: {B32 prefer_disasm PreferDisasm } {B32 no_rich_tooltip NoRichTooltip } {B32 do_implicit_root DoImplicitRoot} + {B32 do_lister DoLister } {Dir2 dir2 Dir2 } {String8 string String } {String8 cmd_name CmdName } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4a009300..c9621233 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1666,6 +1666,12 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } } + // rjf: if no child key? -> just read from this cfg's child string - first 8 bytes -> offset of string (just 8), then string's content + if(child_key.size == 0) + { + read_data = cfg->first->string; + } + // rjf: perform read Rng1U64 legal_range = r1u64(0, read_data.size); Rng1U64 read_range = intersect_1u64(range, legal_range); @@ -1779,17 +1785,27 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) RD_Cfg *root_cfg = rd_cfg_from_eval_space(space); String8 child_key = e_string_from_id(space.u64s[1]); - // rjf: zero-range? delete child - if(range.min == range.max) + // rjf: no child key? -> overwrite child string + if(child_key.size == 0) { - rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + rd_cfg_new_replace(root_cfg, write_string); } - // rjf: non-zero-range? create child if needed & write value + // rjf: child key -> look up & edit child else { - RD_Cfg *child_cfg = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); - rd_cfg_new_replace(child_cfg, write_string); + // rjf: zero-range? delete child + if(range.min == range.max) + { + rd_cfg_release(rd_cfg_child_from_string(root_cfg, child_key)); + } + + // rjf: non-zero-range? create child if needed & write value + else + { + RD_Cfg *child_cfg = rd_cfg_child_from_string_or_alloc(root_cfg, child_key); + rd_cfg_new_replace(child_cfg, write_string); + } } }break; @@ -2661,7 +2677,7 @@ rd_view_ui(Rng2F32 rect) // the "collection of all watches", to build a watch window. but this behavior is not // as desirable if we are just using some other expression as the root. // - B32 implicit_root = !rd_view_cfg_value_from_string(str8_lit("explicit_root")).u64; + B32 implicit_root = (rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("explicit_root")) == &rd_nil_cfg); ////////////////////////////// //- rjf: determine autocompletion string @@ -4287,7 +4303,7 @@ rd_view_ui(Rng2F32 rect) { // rjf: set up base parameters cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); - cell_params.depth = (cell_x == 0 ? row_depth : 0); + cell_params.depth = (cell->flags & RD_WatchCellFlag_Indented ? row_depth : 0); cell_params.cursor = &cell_edit_state->cursor; cell_params.mark = &cell_edit_state->mark; cell_params.edit_buffer = cell_edit_state->input_buffer; @@ -4454,7 +4470,7 @@ rd_view_ui(Rng2F32 rect) ui_kill_action(); } - // rjf: this watch window is being queried? -> move curosr & accept + // rjf: this watch window is a lister? -> move cursor & accept RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); if(lister != &rd_nil_cfg) { @@ -4676,7 +4692,7 @@ rd_view_ui(Rng2F32 rect) // if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) { - if(ui_is_focus_active() && rd_cfg_child_from_string(view, str8_lit("lister")) == &rd_nil_cfg && ui_slot_press(UI_EventActionSlot_Cancel)) + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { vs->query_is_selected = 0; vs->query_string_size = 0; @@ -6307,6 +6323,7 @@ rd_window_frame(void) String8 expr; B32 is_focused; B32 is_anchored; + B32 reset_open; UI_Signal signal; // NOTE(rjf): output, from build B32 pressed; B32 pressed_outside; @@ -6487,8 +6504,25 @@ rd_window_frame(void) //- rjf: try to add opened query if(query_is_open) { + // rjf: unpack view for query + RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); + B32 root_is_explicit = (rd_cfg_child_from_string(view, str8_lit("explicit_root")) != &rd_nil_cfg); + RD_ViewState *vs = rd_view_state_from_cfg(view); + + // rjf: did this view ID change? -> reset open animation + B32 reset_open = 0; + if(view->id != ws->query_last_view_id) + { + ws->query_last_view_id = view->id; + reset_open = 1; + } + // rjf: unpack query info - String8 cmd_name = ws->query_regs->cmd_name; + String8 cmd_name = cmd->first->string; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); String8 query_expr = ws->query_regs->expr; if(cmd_name.size != 0) @@ -6496,26 +6530,8 @@ rd_window_frame(void) query_expr = cmd_kind_info->query.expr; } B32 query_is_anchored = (!ui_box_is_nil(ui_box_from_key(ws->query_regs->ui_key))); - B32 query_is_lister = (cmd_name.size != 0); B32 size_query_by_expr_eval = (query_is_anchored || query_expr.size == 0); - // rjf: build view for query - RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); - RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - rd_cfg_new_replace(cmd, cmd_name); - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(query_is_lister) - { - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - vs->query_is_selected = 1; - } - else - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); - } - // rjf: compute query expression if(query_expr.size == 0) { @@ -6532,18 +6548,6 @@ rd_window_frame(void) } } - // rjf: determine if we want an explicit root - B32 do_explicit_root = (!ws->query_regs->do_implicit_root && (query_expr.size == 0 || !query_is_lister)); - if(do_explicit_root) - { - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new(explicit_root, str8_lit("1")); - } - else - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); - } - // rjf: evaluate query expression E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); @@ -6560,7 +6564,7 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - query_height_px = row_height_px * (predicted_block_tree.total_row_count - !do_explicit_root); + query_height_px = row_height_px * (predicted_block_tree.total_row_count - !root_is_explicit); query_height_px = Min(query_height_px, max_query_height_px); } rect = r2f32p(content_rect_center.x - query_width_px/2, @@ -6580,7 +6584,14 @@ rd_window_frame(void) } } + // rjf: close queries via 'cancel' + if(ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + // rjf: push query task + else { FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); SLLQueuePush(first_floating_view_task, last_floating_view_task, t); @@ -6592,6 +6603,7 @@ rd_window_frame(void) t->expr = query_expr; t->is_focused = 1; t->is_anchored = query_is_anchored; + t->reset_open = reset_open; } } } @@ -6616,7 +6628,7 @@ rd_window_frame(void) String8 expr = t->expr; B32 is_focused = t->is_focused; B32 is_anchored = t->is_anchored; - F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate); + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate, .reset = t->reset_open, .initial = 0.f); // rjf: build cfg tree RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); @@ -6763,7 +6775,7 @@ rd_window_frame(void) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: close queries - if(ui_slot_press(UI_EventActionSlot_Cancel) || query_floating_view_task->pressed_outside) + if(query_floating_view_task->pressed_outside) { rd_cmd(RD_CmdKind_CancelQuery); } @@ -12571,8 +12583,8 @@ rd_frame(void) //- rjf: open lister case RD_CmdKind_OpenLister: { - String8 expr = push_str8f(scratch.arena, "query:commands, query:recent_files, query:recent_projects, query:procedures, query:$%I64x, query:$%I64x", rd_regs()->view, rd_regs()->window); - rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1); + String8 expr = push_str8f(scratch.arena, "query:commands, query:$%I64x, query:$%I64x, query:recent_files, query:recent_projects, query:procedures", rd_regs()->view, rd_regs()->window); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1); }break; //- rjf: command fast path @@ -12589,7 +12601,7 @@ rd_frame(void) // rjf: command has required query -> prep query else { - rd_cmd(RD_CmdKind_PushQuery); + rd_cmd(RD_CmdKind_PushQuery, .do_implicit_root = 1, .do_lister = 1); } }break; @@ -14675,7 +14687,8 @@ Z(getting_started) // rjf: floating queries -> set up window to build immediate-mode top-level query RD_Cfg *view = &rd_nil_cfg; - if(cmd_name.size == 0 || cmd_kind_info->query.flags & RD_QueryFlag_Floating) + B32 is_floating = (cmd_name.size == 0 || cmd_kind_info->query.flags & RD_QueryFlag_Floating); + if(is_floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); @@ -14686,6 +14699,7 @@ Z(getting_started) ws->query_regs = rd_regs_copy(ws->query_arena, rd_regs()); } RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); + rd_cfg_release_all_children(window_query); view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); } @@ -14699,6 +14713,25 @@ Z(getting_started) RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + if(is_floating) + { + if(rd_regs()->do_implicit_root) + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); + } + else + { + rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + } + if(!rd_regs()->do_lister) + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); + } + else + { + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); + } + } // rjf: choose initial input string String8 initial_input = {0}; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 9bf7145f..ff27f9a4 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -523,6 +523,7 @@ struct RD_WindowState B32 query_is_active; Arena *query_arena; RD_Regs *query_regs; + RD_CfgID query_last_view_id; // rjf: hover eval state B32 hover_eval_focused; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 68201878..f941e0f8 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -420,29 +420,45 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) } if(!expr_is_simple && expr != &e_expr_nil) { - child_type_key = e_type_key_cons(.kind = E_TypeKind_MetaExpr, .name = child->first->string, .direct_key = child_type_key); + child_type_key = e_type_key_cons_meta_expr(child_type_key, child->first->string); } scratch_end(scratch); } - //- rjf: extend child type with ranges - MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); - if(!md_node_is_nil(range)) + //- rjf: extend child type with decorative meta info { - Temp scratch = scratch_begin(&arena, 1); - E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).expr; - E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).expr; - E_Expr *args[] = + MD_Node *display_name = md_tag_from_string(child_schema, str8_lit("display_name"), 0); + MD_Node *description = md_tag_from_string(child_schema, str8_lit("description"), 0); + if(!md_node_is_nil(display_name)) { - min_bound, - max_bound, - }; - child_type_key = e_type_key_cons(.kind = E_TypeKind_Lens, - .name = str8_lit("range1"), - .direct_key = child_type_key, - .count = 2, - .args = args); - scratch_end(scratch); + child_type_key = e_type_key_cons_meta_display_name(child_type_key, display_name->first->string); + } + if(!md_node_is_nil(description)) + { + child_type_key = e_type_key_cons_meta_description(child_type_key, description->first->string); + } + } + + //- rjf: extend child type with ranges + { + MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); + if(!md_node_is_nil(range)) + { + Temp scratch = scratch_begin(&arena, 1); + E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).expr; + E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).expr; + E_Expr *args[] = + { + min_bound, + max_bound, + }; + child_type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .name = str8_lit("range1"), + .direct_key = child_type_key, + .count = 2, + .args = args); + scratch_end(scratch); + } } //- rjf: evaluate @@ -903,7 +919,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(environment) { RD_Cfg *cfg = cfgs->v[rhs_value.u64]; result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); - result.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), cfg->first->string.size, E_TypeFlag_IsCodeText); result.mode = E_Mode_Offset; } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4c4ef5ff..599c6ac4 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -825,7 +825,6 @@ rd_id_from_watch_cell(RD_WatchCell *cell) result = e_hash_from_string(result, str8_struct(&cell->kind)); if(cell->kind != RD_WatchCellKind_Expr) { - // result = e_hash_from_string(result, str8_struct(&cell->eval.irtree.mode)); result = e_hash_from_string(result, str8_struct(&cell->index)); result = e_hash_from_string(result, str8_struct(&cell->default_pct)); } @@ -1026,7 +1025,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine row's group cfg - if(info.group_cfg_name.size != 0) + if(info.group_cfg_name.size != 0 && (block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs) || + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) || + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment))) { RD_CfgID id = row->key.child_id; info.group_cfg_child = rd_cfg_from_id(id); @@ -1125,7 +1126,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1153,7 +1154,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &fstrs, ¶ms, name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = fstrs); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = fstrs); } } @@ -1161,14 +1162,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } // rjf: top-level cfg rows else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1233,7 +1234,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); if(entity->kind == CTRL_EntityKind_Machine || entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) @@ -1257,7 +1258,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular row for queries else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellFlag_Indented|RD_WatchCellKind_Expr, .pct = 1.f); } // rjf: singular button for commands @@ -1266,13 +1267,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = 0, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } else { String8 cmd_name = e_string_from_id(e_value_eval_from_eval(row->eval).value.u64); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); } } @@ -1285,7 +1286,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } // rjf: for meta-evaluation space booleans, only do expr @@ -1294,7 +1295,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } // rjf: for meta-cfg evaluation spaces, only do expr/value @@ -1314,21 +1315,21 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } - // rjf: procedures collections get only expr/value/view-rule + // rjf: procedures collections get only expr/value else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) { - info.cell_style_key = str8_lit("expr_value_viewrule"); + info.cell_style_key = str8_lit("procedure_expr_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1369,7 +1370,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof(raw($expr))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct @@ -1538,7 +1539,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { - string_params.flags |= EV_StringFlag_DisableStringQuotes; + string_params.flags |= EV_StringFlag_DisableStringQuotes|EV_StringFlag_DisableAddresses; } if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 099929d0..73be483b 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -60,6 +60,7 @@ enum RD_WatchCellFlag_IsNonCode = (1<<3), RD_WatchCellFlag_CanEdit = (1<<4), RD_WatchCellFlag_IsErrored = (1<<5), + RD_WatchCellFlag_Indented = (1<<6), }; typedef struct RD_WatchCell RD_WatchCell; @@ -67,11 +68,11 @@ struct RD_WatchCell { RD_WatchCell *next; RD_WatchCellKind kind; + RD_WatchCellFlags flags; U64 index; String8 string; E_Eval eval; DR_FStrList fstrs; - RD_WatchCellFlags flags; F32 default_pct; F32 pct; F32 px; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index e496ac44..d9300d71 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3232,8 +3232,8 @@ rd_cell(RD_CellParams *params, String8 string) { B32 is_toggled = !!params->toggled_out[0]; F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); - F32 height_px = ui_top_font_size() * 1.75f; - F32 padding_px = (ui_top_px_height() - height_px) / 2.f; + F32 height_px = ceil_f32(ui_top_font_size() * 1.75f); + F32 padding_px = ceil_f32((ui_top_px_height() - height_px) / 2.f); UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) @@ -3255,7 +3255,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefWidth(ui_px(height_px, 1.f)) { F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); - F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + F32 toggler_size_px = ceil_f32(height_px - extratoggler_padding_px*2.f) - 1.f; UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) UI_PrefWidth(ui_px(toggler_size_px, 1.f)) @@ -3281,8 +3281,8 @@ rd_cell(RD_CellParams *params, String8 string) if(params->flags & RD_CellFlag_Slider && !is_focus_active) UI_Parent(box) { - F32 height_px = ui_top_font_size() * 1.75f; - F32 padding_px = (ui_top_px_height() - height_px) / 2.f; + F32 height_px = ceil_f32(ui_top_font_size() * 1.75f); + F32 padding_px = ceil_f32((ui_top_px_height() - height_px) / 2.f); UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) @@ -3292,7 +3292,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) { F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); - F32 toggler_size_px = height_px - extratoggler_padding_px*2.f; + F32 toggler_size_px = ceil_f32(height_px - extratoggler_padding_px*2.f) - 1.f; ui_set_next_hover_cursor(OS_Cursor_LeftRight); UI_Box *slider_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "slider"); UI_Parent(slider_box) UI_TagF("pop") From d053edab3f585060820ca7c4aaf3905c2b33ebdd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 13:58:38 -0700 Subject: [PATCH 395/755] correctly register types for cfg/ctrl-entity queries --- src/raddbg/raddbg_core.c | 2 ++ src/raddbg/raddbg_views.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c9621233..0ba9172f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12217,6 +12217,7 @@ rd_frame(void) expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); } //- rjf: add macros for all ctrl entity collections @@ -12236,6 +12237,7 @@ rd_frame(void) expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); } //- rjf: add macro / lookup rules for unattached processes diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 599c6ac4..b1b274c4 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1258,7 +1258,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // rjf: singular row for queries else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellFlag_Indented|RD_WatchCellKind_Expr, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } // rjf: singular button for commands From c5402faa259bae17f0428d688dcd3066806fda6b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 14:49:59 -0700 Subject: [PATCH 396/755] work on floating view state machines / characteristics - lister, query views, what happens on escape, is there a filter by default or not, etc. --- src/raddbg/generated/raddbg.meta.c | 10 ++-- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 9 ++++ src/raddbg/raddbg_core.c | 83 ++++++++++++++++++------------ 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8d4ad735..642916bd 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[321] = +RD_VocabInfo rd_vocab_info_table[323] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -114,6 +114,8 @@ RD_VocabInfo rd_vocab_info_table[321] = {str8_lit_comp("hint_code_text"), str8_lit_comp(""), str8_lit_comp("Hint Code Text"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("opaque_backgrounds"), str8_lit_comp(""), str8_lit_comp("Opaque Backgrounds"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("background_blur"), str8_lit_comp(""), str8_lit_comp("Background Blur"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("row_height"), str8_lit_comp(""), str8_lit_comp("Row Height"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("tab_height"), str8_lit_comp(""), str8_lit_comp("Tab Height"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -331,9 +333,9 @@ RD_VocabInfo rd_vocab_info_table[321] = RD_NameSchemaInfo rd_name_schema_info_table[20] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n @default(3.f) 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d268dc5c..580f4eca 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -640,7 +640,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[321]; +extern RD_VocabInfo rd_vocab_info_table[323]; extern RD_NameSchemaInfo rd_name_schema_info_table[20]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 284aeb92..50848c42 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -127,6 +127,8 @@ RD_VocabTable: {hint_code_text "" "Hint Code Text" "" Null } {opaque_backgrounds "" "Opaque Backgrounds" "" Null } {background_blur "" "Background Blur" "" Null } + {row_height "" "Row Height" "" Null } + {tab_height "" "Tab Height" "" Null } } @struct RD_VocabInfo: @@ -173,6 +175,8 @@ RD_VocabTable: @default(1) 'hint_code_text': bool, @default(2) 'tab_width': @range[1, 32] u64, @default(11) 'font_size': @range[6, 72] u64, + @default(3.f) 'row_height': @range[1.75f, 5.f] f32, + @default(3.f) 'tab_height': @range[1.75f, 5.f] f32, } ``` } @@ -207,6 +211,10 @@ RD_VocabTable: @default(0) 'smooth_code_text': bool, @default(1) 'hint_code_text': bool, @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64, + + //- rjf: size settings + @default(3.f) @display_name('Window Row Height') 'row_height': @range[1.75f, 5.f] f32, + @default(3.f) 'tab_height': @range[1.75f, 5.f] f32, } ``` } @@ -218,6 +226,7 @@ RD_VocabTable: x: { @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64, + @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0ba9172f..9cd8d88e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2322,16 +2322,19 @@ rd_view_ui(Rng2F32 rect) UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) { - UI_TextAlignment(UI_TextAlign_Center) + if(cmd_name.size != 0) + { + UI_TextAlignment(UI_TextAlign_Center) + UI_Transparency(1-search_row_open_t) + UI_PrefWidth(ui_em(2.5f, 1.f)) + UI_TagF("weak") + RD_Font(RD_FontSlot_Icons) + ui_label(rd_icon_kind_text_table[icon == RD_IconKind_Null ? RD_IconKind_Find : icon]); UI_Transparency(1-search_row_open_t) - UI_PrefWidth(ui_em(2.5f, 1.f)) - UI_TagF("weak") - RD_Font(RD_FontSlot_Icons) - ui_label(rd_icon_kind_text_table[icon == RD_IconKind_Null ? RD_IconKind_Find : icon]); - UI_Transparency(1-search_row_open_t) - RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) - ui_label(rd_display_from_code_name(cmd_name)); - ui_spacer(ui_em(0.5f, 1.f)); + RD_Font(RD_FontSlot_Main) UI_PrefWidth(ui_text_dim(1, 1)) + ui_label(rd_display_from_code_name(cmd_name)); + ui_spacer(ui_em(0.5f, 1.f)); + } RD_CellParams params = {0}; { params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_CellFlag_CodeContents; @@ -2374,7 +2377,9 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: fill view container // - UI_Parent(view_container) UI_FontSize(rd_setting_f32_from_name(str8_lit("font_size"))) + UI_Parent(view_container) + UI_FontSize(rd_setting_f32_from_name(str8_lit("font_size"))) + UI_PrefHeight(ui_px(floor_f32(ui_top_font_size()*rd_setting_f32_from_name(str8_lit("row_height"))), 1.f)) { //////////////////////////// //- rjf: special-case view: "getting started" @@ -4688,16 +4693,16 @@ rd_view_ui(Rng2F32 rect) } //////////////////////////// - //- rjf: catchall query completion controls + //- rjf: catchall completion controls // - if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) + UI_Focus(UI_FocusKind_On) { - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + if(rd_cfg_child_from_string(view, str8_lit("close_on_cancel")) == &rd_nil_cfg && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { vs->query_is_selected = 0; vs->query_string_size = 0; } - if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + if(vs->query_is_selected && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { String8 cmd_name = rd_view_query_cmd(); String8 input = rd_view_query_input(); @@ -5533,8 +5538,9 @@ rd_window_frame(void) // Rng2F32 window_rect = os_client_rect_from_window(ws->os); Vec2F32 window_rect_dim = dim_2f32(window_rect); - Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_px_height()); - Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_px_height(), window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); + F32 top_bar_dim_px = floor_f32(ui_top_font_size()*3.f); + Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+top_bar_dim_px); + Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - top_bar_dim_px, window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y); Rng2F32 content_rect = r2f32p(window_rect.x0, top_bar_rect.y1, window_rect.x0+window_rect_dim.x, bottom_bar_rect.y0); F32 window_edge_px = os_dpi_from_window(ws->os)*0.035f; content_rect = pad_2f32(content_rect, -window_edge_px); @@ -6412,8 +6418,8 @@ rd_window_frame(void) // rjf: build view RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); RD_Cfg *view = rd_view_from_eval(root, hover_eval); - RD_Cfg *explicit_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_new_replace(explicit_root, str8_lit("1")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("close_on_cancel")); // rjf: determine size of hover evaluation container EV_BlockTree predicted_block_tree = {0}; @@ -6508,7 +6514,6 @@ rd_window_frame(void) RD_Cfg *root = rd_immediate_cfg_from_keyf("window_query_%p", window); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); B32 root_is_explicit = (rd_cfg_child_from_string(view, str8_lit("explicit_root")) != &rd_nil_cfg); RD_ViewState *vs = rd_view_state_from_cfg(view); @@ -6522,10 +6527,10 @@ rd_window_frame(void) } // rjf: unpack query info - String8 cmd_name = cmd->first->string; + String8 cmd_name = ws->query_regs->cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); String8 query_expr = ws->query_regs->expr; - if(cmd_name.size != 0) + if(query_expr.size == 0 && cmd_name.size != 0) { query_expr = cmd_kind_info->query.expr; } @@ -6584,14 +6589,7 @@ rd_window_frame(void) } } - // rjf: close queries via 'cancel' - if(ui_slot_press(UI_EventActionSlot_Cancel)) - { - rd_cmd(RD_CmdKind_CancelQuery); - } - // rjf: push query task - else { FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); SLLQueuePush(first_floating_view_task, last_floating_view_task, t); @@ -6759,7 +6757,7 @@ rd_window_frame(void) { rd_request_frame(); } - if(hover_eval_floating_view_task->pressed_outside) + if(hover_eval_floating_view_task->pressed_outside || ui_slot_press(UI_EventActionSlot_Cancel)) { ws->hover_eval_focused = 0; MemoryZeroStruct(&ws->hover_eval_string); @@ -6775,7 +6773,7 @@ rd_window_frame(void) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: close queries - if(query_floating_view_task->pressed_outside) + if(query_floating_view_task->pressed_outside || ui_slot_press(UI_EventActionSlot_Cancel)) { rd_cmd(RD_CmdKind_CancelQuery); } @@ -8008,7 +8006,7 @@ rd_window_frame(void) panel_rect_pct.y1*content_rect_dim.y); panel_rect = pad_2f32(panel_rect, floor_f32(-ui_top_font_size()*0.15f)); F32 tab_bar_rheight = floor_f32(ui_top_font_size()*3.5f); - F32 tab_bar_vheight = floor_f32(ui_top_font_size()*3.f); + F32 tab_bar_vheight = floor_f32(ui_top_font_size()*rd_setting_f32_from_name(str8_lit("tab_height"))); F32 tab_bar_rv_diff = tab_bar_rheight - tab_bar_vheight; F32 tab_spacing = floor_f32(ui_top_font_size()*0.4f); Rng2F32 tab_bar_rect = r2f32p(panel_rect.x0, panel_rect.y0, panel_rect.x1, panel_rect.y0 + tab_bar_vheight); @@ -14703,6 +14701,7 @@ Z(getting_started) RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); rd_cfg_release_all_children(window_query); view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); + rd_cfg_new(view, str8_lit("close_on_cancel")); } // rjf: non-floating -> embed in tab parameter @@ -14787,16 +14786,34 @@ Z(getting_started) vs->query_is_selected ^= 1; } } + if(rd_regs()->do_lister) + { + vs->query_is_selected = 1; + } }break; case RD_CmdKind_CompleteQuery: { + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); String8 cmd_name = rd_view_query_cmd(); RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - RD_RegsScope() + if(cmd_name.size != 0) RD_RegsScope() { rd_push_cmd(cmd_name, rd_regs()); } - if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) + + // rjf: find out if this view is floating + B32 is_floating = 0; + for(RD_Cfg *p = view; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("transient"), 0)) + { + is_floating = 1; + break; + } + } + + // rjf: complete query + if(is_floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); From f99d560b40c476c9259b14f0b06775868a4ed75c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 15:02:24 -0700 Subject: [PATCH 397/755] more tweaks of the previous --- src/raddbg/raddbg_core.c | 160 +++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 81 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9cd8d88e..5632fefb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4695,14 +4695,14 @@ rd_view_ui(Rng2F32 rect) //////////////////////////// //- rjf: catchall completion controls // - UI_Focus(UI_FocusKind_On) + if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) { - if(rd_cfg_child_from_string(view, str8_lit("close_on_cancel")) == &rd_nil_cfg && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { vs->query_is_selected = 0; vs->query_string_size = 0; } - if(vs->query_is_selected && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) + if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) { String8 cmd_name = rd_view_query_cmd(); String8 input = rd_view_query_input(); @@ -6419,7 +6419,6 @@ rd_window_frame(void) RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); RD_Cfg *view = rd_view_from_eval(root, hover_eval); rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - rd_cfg_child_from_string_or_alloc(view, str8_lit("close_on_cancel")); // rjf: determine size of hover evaluation container EV_BlockTree predicted_block_tree = {0}; @@ -6769,11 +6768,13 @@ rd_window_frame(void) //- rjf: query interactions if(query_floating_view_task) { + RD_Cfg *view = query_floating_view_task->view; + RD_ViewState *vs = rd_view_state_from_cfg(query_floating_view_task->view); String8 cmd_name = ws->query_regs->cmd_name; RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: close queries - if(query_floating_view_task->pressed_outside || ui_slot_press(UI_EventActionSlot_Cancel)) + if(query_floating_view_task->pressed_outside || (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_selected) || ui_slot_press(UI_EventActionSlot_Cancel)) { rd_cmd(RD_CmdKind_CancelQuery); } @@ -6781,7 +6782,6 @@ rd_window_frame(void) // rjf: any queries which take a file path mutate the debugger's "current path" if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) { - RD_Cfg *view = query_floating_view_task->view; RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); if(input != &rd_nil_cfg) @@ -14701,7 +14701,6 @@ Z(getting_started) RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); rd_cfg_release_all_children(window_query); view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); - rd_cfg_new(view, str8_lit("close_on_cancel")); } // rjf: non-floating -> embed in tab parameter @@ -14710,85 +14709,92 @@ Z(getting_started) view = rd_cfg_from_id(rd_regs()->view); } - // rjf: unpack view's query info - RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); - RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); - if(is_floating) - { - if(rd_regs()->do_implicit_root) - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); - } - else - { - rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); - } - if(!rd_regs()->do_lister) - { - rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); - } - else - { - rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); - } - } + // rjf: determine if the target view is a lister (and thus already has a command) + B32 view_is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); - // rjf: choose initial input string - String8 initial_input = {0}; - if(cmd_name.size != 0) + // rjf: target view is a lister -> do not do anything - cannot replace the command + if(!view_is_lister) { - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + // rjf: unpack view's query info + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string_or_alloc(query, str8_lit("cmd")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + if(is_floating) { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); - String8 current_path_string = current_path->first->string; - if(current_path_string.size == 0) + if(rd_regs()->do_implicit_root) { - current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("explicit_root"))); } else { - current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); + } + if(!rd_regs()->do_lister) + { + rd_cfg_release(rd_cfg_child_from_string(view, str8_lit("lister"))); + } + else + { + rd_cfg_child_from_string_or_alloc(view, str8_lit("lister")); } - initial_input = path_normalized_from_string(scratch.arena, current_path_string); - initial_input = push_str8f(scratch.arena, "%S/", initial_input); } - else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + + // rjf: choose initial input string + String8 initial_input = {0}; + if(cmd_name.size != 0) { - initial_input = input->first->string; + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); + String8 current_path_string = current_path->first->string; + if(current_path_string.size == 0) + { + current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + } + else + { + current_path_string = path_normalized_from_string(scratch.arena, current_path_string); + } + initial_input = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = push_str8f(scratch.arena, "%S/", initial_input); + } + else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) + { + initial_input = input->first->string; + } } - } - - // rjf: build query state - String8 current_query_cmd_name = cmd->first->string; - rd_cfg_new_replace(input, initial_input); - rd_cfg_new_replace(cmd, cmd_name); - RD_ViewState *vs = rd_view_state_from_cfg(view); - if(cmd_name.size != 0) - { - if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + + // rjf: build query state + String8 current_query_cmd_name = cmd->first->string; + rd_cfg_new_replace(input, initial_input); + rd_cfg_new_replace(cmd, cmd_name); + RD_ViewState *vs = rd_view_state_from_cfg(view); + if(cmd_name.size != 0) { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = txt_pt(1, 1); + if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = txt_pt(1, 1); + } + else + { + vs->query_cursor = txt_pt(1, 1+input->first->string.size); + vs->query_mark = vs->query_cursor; + } + if(!str8_match(current_query_cmd_name, cmd_name, 0)) + { + vs->query_is_selected = 1; + } + else + { + vs->query_is_selected ^= 1; + } } - else - { - vs->query_cursor = txt_pt(1, 1+input->first->string.size); - vs->query_mark = vs->query_cursor; - } - if(!str8_match(current_query_cmd_name, cmd_name, 0)) + if(rd_regs()->do_lister) { vs->query_is_selected = 1; } - else - { - vs->query_is_selected ^= 1; - } - } - if(rd_regs()->do_lister) - { - vs->query_is_selected = 1; } }break; case RD_CmdKind_CompleteQuery: @@ -14801,19 +14807,11 @@ Z(getting_started) rd_push_cmd(cmd_name, rd_regs()); } - // rjf: find out if this view is floating - B32 is_floating = 0; - for(RD_Cfg *p = view; p != &rd_nil_cfg; p = p->parent) - { - if(str8_match(p->string, str8_lit("transient"), 0)) - { - is_floating = 1; - break; - } - } + // rjf: find out if this view is a lister + B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); // rjf: complete query - if(is_floating) + if(is_lister) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); From 225ac267f09cd420be209cbc764e5ce2b664eb10 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 15:51:27 -0700 Subject: [PATCH 398/755] pass over row info building --- src/raddbg/raddbg_views.c | 677 ++++++++++++++++++++------------------ src/raddbg/raddbg_views.h | 1 - 2 files changed, 361 insertions(+), 317 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b1b274c4..0af75efc 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -934,31 +934,54 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .group_entity = &ctrl_entity_nil, .callstack_thread = &ctrl_entity_nil, .view_ui_rule = &rd_nil_view_ui_rule, - .view_ui_tag = &e_expr_nil, }; { Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); - // rjf: unpack key & block - EV_Block *block = row->block; + //////////////////////////// + //- rjf: unpack row's evaluation, key, & block info + // + E_Type *row_type = e_type_from_key__cached(row->eval.irtree.type_key); EV_Key key = row->key; + EV_Block *block = row->block; E_Eval block_eval = row->block->eval; E_TypeKey block_type_key = block_eval.irtree.type_key; E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); E_Type *block_type = e_type_from_key__cached(block_type_key); + RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(row->eval.space); + CTRL_Entity *evalled_entity = (row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(row->eval.space) : &ctrl_entity_nil); - // rjf: determine if row's expression is editable + //////////////////////////// + //- rjf: determine if this cfg/entity evaluation is top-level - e.g. if we + // are evaluating a cfg tree, or some descendant of it + // + B32 is_top_level = 0; + if(evalled_cfg != &rd_nil_cfg) + { + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); + is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); + } + if(evalled_entity != &ctrl_entity_nil) + { + String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; + E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); + is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); + } + + //////////////////////////// + //- rjf: fill if row's expression is editable + // if(block_type->flags & E_TypeFlag_EditableChildren || row->eval.expr == &e_expr_nil) { info.expr_is_editable = 1; } - // rjf: determine row's module - CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(row->eval.space); - CTRL_Entity *row_module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + //////////////////////////// + //- rjf: fill row's module + // if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity) { + CTRL_Entity *row_ctrl_entity = rd_ctrl_entity_from_eval_space(row->eval.space); switch(row_ctrl_entity->kind) { default: @@ -976,12 +999,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine call stack info + //////////////////////////// + //- rjf: fill row's call stack info + // if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && str8_match(str8_lit("call_stack"), block_type->name, 0)) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); if(entity->kind == CTRL_EntityKind_Thread) { + DI_Scope *di_scope = di_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); @@ -993,24 +1019,31 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.callstack_inline_depth = f->inline_depth; info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); } + di_scope_close(di_scope); } } - // rjf: determine ctrl entity + //////////////////////////// + //- rjf: fill row's ctrl entity + // if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { info.group_entity = rd_ctrl_entity_from_eval_space(row->eval.space); } - // rjf: determine cfg group name / parent + //////////////////////////// + //- rjf: fill row's cfg group name / parent + // if(block_type_kind == E_TypeKind_Set && (block_eval.space.kind == RD_EvalSpaceKind_MetaQuery || block_eval.space.kind == RD_EvalSpaceKind_MetaCfg)) { info.group_cfg_parent = rd_cfg_from_eval_space(block_eval.space); } - // rjf: determine group cfg name + //////////////////////////// + //- rjf: fill row's group cfg name + // if(block_type_kind == E_TypeKind_Set) { String8 singular_name = rd_singular_from_code_name_plural(block_type->name); @@ -1024,7 +1057,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine row's group cfg + //////////////////////////// + //- rjf: fill row's group cfg + // if(info.group_cfg_name.size != 0 && (block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs) || block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) || block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment))) @@ -1033,29 +1068,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.group_cfg_child = rd_cfg_from_id(id); } - // rjf: determine cfgs/entities that this row is evaluating - RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(row->eval.space); - CTRL_Entity *evalled_entity = (row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(row->eval.space) : &ctrl_entity_nil); - - // rjf: determine if this cfg/entity evaluation is top-level - e.g. if we - // are evaluating a cfg tree, or some descendant of it - B32 is_top_level = 0; - if(evalled_cfg != &rd_nil_cfg) - { - E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, evalled_cfg->string); - is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); - } - if(evalled_entity != &ctrl_entity_nil) - { - String8 top_level_name = ctrl_entity_kind_code_name_table[evalled_entity->kind]; - E_TypeKey top_level_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, top_level_name); - is_top_level = (row->eval.value.u64 == 0 && e_type_key_match(top_level_type_key, row->eval.irtree.type_key)); - } - - // rjf: determine view ui rule + //////////////////////////// + //- rjf: fill row's view ui rule + // info.view_ui_rule = rd_view_ui_rule_from_string(row->block->viz_expand_rule->string); - // rjf: find possible table type + //////////////////////////// + //- rjf: find possible table type + // E_Type *maybe_table_type = block_type; for(;;) { @@ -1075,240 +1095,52 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: fill row's cells + //////////////////////////// + //- rjf: @watch_row_build_cells table rows + // + if(0){} + else if(block->parent != &ev_nil_block && maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) { - if(0){} - - // rjf: table rows - else if(block->parent != &ev_nil_block && maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) - { - U64 column_count = maybe_table_type->count; - info.cell_style_key = push_str8f(arena, "table_%I64u_cols", column_count); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; + U64 column_count = maybe_table_type->count; + info.cell_style_key = push_str8f(arena, "table_%I64u_cols", column_count); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &row->eval.irtree; - for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) - { - E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); - } - e_ir_state->overridden_irtree = prev_overridden_irtree; - info.can_expand = 0; + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &row->eval.irtree; + for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + { + E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + } + e_ir_state->overridden_irtree = prev_overridden_irtree; + info.can_expand = 0; #undef take_pct - } - - // rjf: folder / file rows - else if(row->eval.space.kind == E_SpaceKind_FileSystem) + } + + //////////////////////////// + //- rjf: @watch_row_build_cells files / folders + // + else if(row->eval.space.kind == E_SpaceKind_FileSystem) + { + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) - { - String8 file_path = e_string_from_id(row->eval.value.u64); - DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, - .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, - .pct = 1.f, - .fstrs = fstrs); - if(str8_match(type->name, str8_lit("file"), 0)) - { - info.can_expand = 0; - } - } - else - { - info.cell_style_key = str8_lit("expr_and_eval"); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); -#undef take_pct - } - } - - // rjf: singular button for unattached processes - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) - { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); - if(str8_match(type->name, str8_lit("unattached_process"), 0)) - { - U64 pid = row->eval.value.u128.u64[0]; - String8 name = e_string_from_id(row->eval.value.u128.u64[1]); - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - DR_FStrList fstrs = {0}; - UI_TagF("weak") - { - dr_fstrs_push_new(arena, &fstrs, ¶ms, - rd_icon_kind_text_table[RD_IconKind_Scheduler], - .font = rd_font_from_slot(RD_FontSlot_Icons), - .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), - .color = ui_color_from_name(str8_lit("text"))); - } - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = fstrs); - } - } - - // rjf: lister rows - else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) - { - info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); - } - - // rjf: top-level cfg rows - else if(is_top_level && evalled_cfg != &rd_nil_cfg) - { - RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); - MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); - for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) - { - MD_Node *schema = n->v; - MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("row_commands"), 0); - for MD_EachNode(cmd, cmds_root->first) - { - String8 cmd_name = cmd->string; - RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); - switch(cmd_kind) - { - default:{}break; - case RD_CmdKind_EnableCfg: - { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(!is_disabled) - { - cmd_kind = RD_CmdKind_DisableCfg; - } - }break; - case RD_CmdKind_DisableCfg: - { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(is_disabled) - { - cmd_kind = RD_CmdKind_EnableCfg; - } - }break; - case RD_CmdKind_SelectCfg: - { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(!is_disabled) - { - cmd_kind = RD_CmdKind_DeselectCfg; - } - }break; - case RD_CmdKind_DeselectCfg: - { - B32 is_disabled = rd_disabled_from_cfg(cfg); - if(is_disabled) - { - cmd_kind = RD_CmdKind_SelectCfg; - } - }break; - } - if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, - .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).enabled")); - } - else if(cmd_kind != RD_CmdKind_Null) - { - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); - } - } - } - } - - // rjf: top-level entity rows - else if(is_top_level && evalled_entity != &ctrl_entity_nil) - { - CTRL_Entity *entity = evalled_entity; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); - if(entity->kind == CTRL_EntityKind_Machine || - entity->kind == CTRL_EntityKind_Process || - entity->kind == CTRL_EntityKind_Thread) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).active")); - } - if(entity->kind == CTRL_EntityKind_Thread) - { - RD_CmdKind cmd_kind = RD_CmdKind_SelectEntity; - if(ctrl_handle_match(entity->handle, rd_base_regs()->thread)) - { - cmd_kind = RD_CmdKind_DeselectEntity; - } - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); - } - } - - // rjf: singular row for queries - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); - } - - // rjf: singular button for commands - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCmd) - { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); - } - else - { - String8 cmd_name = e_string_from_id(e_value_eval_from_eval(row->eval).value.u64); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); - } - } - - // rjf: singular cell for view ui - else if(info.view_ui_rule != &rd_nil_view_ui_rule) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); - } - - // rjf: for 'add-new' rows in meta-cfg evaluation spaces, only do expr - else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); - } - - // rjf: for meta-evaluation space booleans, only do expr - else if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Bool && - (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || - row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) - { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); - } - - // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || - row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - row->eval.space.kind == E_SpaceKind_File) - { - if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Array && - e_type_kind_from_key(e_type_key_direct(row->eval.irtree.type_key)) == E_TypeKind_U8) + String8 file_path = e_string_from_id(row->eval.value.u64); + DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, + .pct = 1.f, + .fstrs = fstrs); + if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; } + } + else + { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); @@ -1319,65 +1151,278 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } - - // rjf: procedures collections get only expr/value - else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) + } + + //////////////////////////// + //- rjf: @watch_row_build_cells unattached processes + // + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + { + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); + if(str8_match(type->name, str8_lit("unattached_process"), 0)) { - info.cell_style_key = str8_lit("procedure_expr_eval"); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.25f, .pct = take_pct()); -#undef take_pct - } - - // rjf: callstack frames - else if(info.callstack_thread != &ctrl_entity_nil) - { - info.cell_style_key = str8_lit("call_stack_frame"); - CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); - E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); - E_Eval module_eval = e_eval_from_expr(arena, expr); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((uint64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), - .string = str8_lit(" "), - .default_pct = 0.20f, .pct = take_pct()); -#undef take_pct - } - - // rjf: default cells - else - { - info.cell_style_key = str8_lit("normal"); - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); - RD_Cfg *w_cfg = style->first; - F32 next_pct = 0; -#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof(raw($expr))"), .default_pct = 0.25f, .pct = take_pct()); -#undef take_pct + U64 pid = row->eval.value.u128.u64[0]; + String8 name = e_string_from_id(row->eval.value.u128.u64[1]); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Scheduler], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = fstrs); } } - di_scope_close(di_scope); + //////////////////////////// + //- rjf: @watch_row_build_cells lister rows + // + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) + { + info.can_expand = 0; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + } + + //////////////////////////// + //- rjf: @watch_row_build_cells top-level cfg evaluations + // + else if(is_top_level && evalled_cfg != &rd_nil_cfg) + { + RD_Cfg *cfg = evalled_cfg; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); + MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("row_commands"), 0); + for MD_EachNode(cmd, cmds_root->first) + { + String8 cmd_name = cmd->string; + RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); + switch(cmd_kind) + { + default:{}break; + case RD_CmdKind_EnableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DisableCfg; + } + }break; + case RD_CmdKind_DisableCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_EnableCfg; + } + }break; + case RD_CmdKind_SelectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(!is_disabled) + { + cmd_kind = RD_CmdKind_DeselectCfg; + } + }break; + case RD_CmdKind_DeselectCfg: + { + B32 is_disabled = rd_disabled_from_cfg(cfg); + if(is_disabled) + { + cmd_kind = RD_CmdKind_SelectCfg; + } + }break; + } + if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).enabled")); + } + else if(cmd_kind != RD_CmdKind_Null) + { + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } + } + } + } + + //////////////////////////// + //- rjf: @watch_row_build_cells ctrl entity evaluations + // + else if(is_top_level && evalled_entity != &ctrl_entity_nil) + { + CTRL_Entity *entity = evalled_entity; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); + if(entity->kind == CTRL_EntityKind_Machine || + entity->kind == CTRL_EntityKind_Process || + entity->kind == CTRL_EntityKind_Thread) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + .px = floor_f32(ui_top_font_size()*6.f), + .string = str8_lit("($expr).active")); + } + if(entity->kind == CTRL_EntityKind_Thread) + { + RD_CmdKind cmd_kind = RD_CmdKind_SelectEntity; + if(ctrl_handle_match(entity->handle, rd_base_regs()->thread)) + { + cmd_kind = RD_CmdKind_DeselectEntity; + } + String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + } + } + + //////////////////////////// + //- rjf: @watch_row_build_cells queries + // + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + } + + //////////////////////////// + //- rjf: @watch_row_build_cells commands + // + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); + if(type->kind == E_TypeKind_Set) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + } + else + { + String8 cmd_name = e_string_from_id(e_value_eval_from_eval(row->eval).value.u64); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + } + } + + //////////////////////////// + //- rjf: @watch_row_build_cells view UI escape hatch + // + else if(info.view_ui_rule != &rd_nil_view_ui_rule) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); + } + + //////////////////////////// + //- rjf: @watch_row_build_cells "add new" expression rows + // + else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + } + + //////////////////////////// + //- rjf: @watch_row_build_cells meta-evaluation booleans + // + else if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Bool && + (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || + row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) + { + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + } + + //////////////////////////// + //- rjf: @watch_row_build_cells meta-evaluation catch-all: expression / value + // + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || + row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + row->eval.space.kind == E_SpaceKind_File) + { + if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Array && + e_type_kind_from_key(e_type_key_direct(row->eval.irtree.type_key)) == E_TypeKind_U8) + { + info.can_expand = 0; + } + info.cell_style_key = str8_lit("expr_and_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); +#undef take_pct + } + + //////////////////////////// + //- rjf: @watch_row_build_cells procedures (expr & eval, mostly expr) + // + else if(block_type->kind == E_TypeKind_Set && str8_match(block_type->name, str8_lit("procedures"), 0)) + { + info.cell_style_key = str8_lit("procedure_expr_eval"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.25f, .pct = take_pct()); +#undef take_pct + } + + //////////////////////////// + //- rjf: @watch_row_build_cells call stack frames + // + else if(info.callstack_thread != &ctrl_entity_nil) + { + info.cell_style_key = str8_lit("call_stack_frame"); + CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); + E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); + E_Eval module_eval = e_eval_from_expr(arena, expr); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((uint64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), + .string = str8_lit(" "), + .default_pct = 0.20f, .pct = take_pct()); +#undef take_pct + } + + //////////////////////////// + //- rjf: @watch_row_build_cells catchall (normal rows) + // + else + { + info.cell_style_key = str8_lit("normal"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof(raw($expr))"), .default_pct = 0.25f, .pct = take_pct()); +#undef take_pct + } + scratch_end(scratch); } return info; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 73be483b..e4070b6f 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -103,7 +103,6 @@ struct RD_WatchRowInfo String8 cell_style_key; RD_WatchCellList cells; RD_ViewUIRule *view_ui_rule; - E_Expr *view_ui_tag; }; typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; From e30df5122aa311f83c29efb2c87b4c7f8ef5b7bd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 17:15:57 -0700 Subject: [PATCH 399/755] first half of cell rendering pass --- src/eval/eval_bundles.c | 23 + src/eval/eval_bundles.h | 2 + src/eval/eval_ir.c | 5 +- src/raddbg/raddbg_core.c | 3811 ++++++++++++++++++------------------- src/raddbg/raddbg_core.h | 4 + src/raddbg/raddbg_views.c | 354 +++- src/raddbg/raddbg_views.h | 7 +- 7 files changed, 2217 insertions(+), 1989 deletions(-) diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 3acca27f..859b708e 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -246,6 +246,29 @@ e_value_from_expr(E_Expr *expr) return result; } +internal E_Eval +e_eval_wrap(Arena *arena, E_Eval eval, String8 string) +{ + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &eval.irtree; + E_Eval wrapped_eval = e_eval_from_string(arena, string); + e_ir_state->overridden_irtree = prev_overridden_irtree; + return wrapped_eval; +} + +internal E_Eval +e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...) +{ + Temp scratch = scratch_begin(&arena, 1); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Eval result = e_eval_wrap(arena, eval, string); + va_end(args); + scratch_end(scratch); + return result; +} + internal U64 e_base_offset_from_eval(E_Eval eval) { diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index e56d4fd3..d3be65cf 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -36,6 +36,8 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval); internal E_Value e_value_from_string(String8 string); internal E_Value e_value_from_stringf(char *fmt, ...); internal E_Value e_value_from_expr(E_Expr *expr); +internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string); +internal E_Eval e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...);; internal U64 e_base_offset_from_eval(E_Eval eval); internal Rng1U64 e_range_from_eval(E_Eval eval); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e19d243d..666ae0ee 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2343,7 +2343,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: equip previous task's irtree if(t->prev != 0) { - result.prev = t->prev; + result.prev = push_array(arena, E_IRTreeAndType, 1); + result.prev[0] = *t->prev; } //- rjf: find any auto hooks according to this generation's type @@ -2360,7 +2361,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; - task->prev = push_array(arena, E_IRTreeAndType, 1); + task->prev = push_array(scratch.arena, E_IRTreeAndType, 1); task->prev[0] = result; break; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5632fefb..4ec0d08d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1502,6 +1502,27 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) return space; } +//- rjf: command name <-> eval space + +internal String8 +rd_cmd_name_from_eval_space(E_Space space) +{ + String8 result = {0}; + if(space.kind == RD_EvalSpaceKind_MetaCmd) + { + result = e_string_from_id(space.u64s[0]); + } + return result; +} + +internal E_Space +rd_eval_space_from_cmd_name(String8 cmd_name) +{ + E_Space space = e_space_make(RD_EvalSpaceKind_MetaCmd); + space.u64s[0] = e_id_from_string(cmd_name); + return space; +} + //- rjf: eval space reads/writes internal B32 @@ -2636,488 +2657,676 @@ rd_view_ui(Rng2F32 rect) else if(str8_match(view_name, str8_lit("watch"), 0)) { Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); - RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); - UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); - F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; - B32 is_first_frame = 0; - if(ewv->initialized == 0) + RD_Font(RD_FontSlot_Code) { - is_first_frame = 1; - ewv->initialized = 1; - ewv->filter_arena = rd_push_view_arena(); - ewv->text_edit_arena = rd_push_view_arena(); - } - - ////////////////////////////// - //- rjf: unpack arguments - // - EV_View *eval_view = rd_view_eval_view(); - F32 row_height_px = ui_top_px_height(); - S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); - F32 row_string_max_size_px = dim_2f32(rect).x; - EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; - String8 filter = rd_view_query_input(); - Vec4F32 pop_background_rgba = {0}; - UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); - - ////////////////////////////// - //- rjf: whenever the filter changes, we want to reset the cursor/mark state - // - if(!str8_match(filter, ewv->last_filter, 0)) - { - MemoryZeroStruct(&ewv->cursor); - MemoryZeroStruct(&ewv->mark); - MemoryZeroStruct(&ewv->next_cursor); - MemoryZeroStruct(&ewv->next_mark); - arena_clear(ewv->filter_arena); - ewv->last_filter = push_str8_copy(ewv->filter_arena, filter); - } - - ////////////////////////////// - //- rjf: decide if root should be implicit - // - // "implicit" means -> root is automatically expanded, row depth is 1 less than the - // block tree structure would suggest. this would be used if the root is, for instance, - // the "collection of all watches", to build a watch window. but this behavior is not - // as desirable if we are just using some other expression as the root. - // - B32 implicit_root = (rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("explicit_root")) == &rd_nil_cfg); - - ////////////////////////////// - //- rjf: determine autocompletion string - // - String8 autocomplete_hint_string = {0}; - { - for(UI_Event *evt = 0; ui_next_event(&evt);) + E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); + UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); + F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + B32 is_first_frame = 0; + if(ewv->initialized == 0) { - if(evt->kind == UI_EventKind_AutocompleteHint) + is_first_frame = 1; + ewv->initialized = 1; + ewv->filter_arena = rd_push_view_arena(); + ewv->text_edit_arena = rd_push_view_arena(); + } + + ////////////////////////////// + //- rjf: unpack arguments + // + EV_View *eval_view = rd_view_eval_view(); + F32 row_height_px = ui_top_px_height(); + S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); + F32 row_string_max_size_px = dim_2f32(rect).x; + EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules; + String8 filter = rd_view_query_input(); + Vec4F32 pop_background_rgba = {0}; + UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); + + ////////////////////////////// + //- rjf: whenever the filter changes, we want to reset the cursor/mark state + // + if(!str8_match(filter, ewv->last_filter, 0)) + { + MemoryZeroStruct(&ewv->cursor); + MemoryZeroStruct(&ewv->mark); + MemoryZeroStruct(&ewv->next_cursor); + MemoryZeroStruct(&ewv->next_mark); + arena_clear(ewv->filter_arena); + ewv->last_filter = push_str8_copy(ewv->filter_arena, filter); + } + + ////////////////////////////// + //- rjf: decide if root should be implicit + // + // "implicit" means -> root is automatically expanded, row depth is 1 less than the + // block tree structure would suggest. this would be used if the root is, for instance, + // the "collection of all watches", to build a watch window. but this behavior is not + // as desirable if we are just using some other expression as the root. + // + B32 implicit_root = (rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("explicit_root")) == &rd_nil_cfg); + + ////////////////////////////// + //- rjf: determine autocompletion string + // + String8 autocomplete_hint_string = {0}; + { + for(UI_Event *evt = 0; ui_next_event(&evt);) { - autocomplete_hint_string = evt->string; - break; + if(evt->kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = evt->string; + break; + } } } - } - - ////////////////////////////// - //- rjf: process commands - // - for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) - { - RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); - switch(kind) + + ////////////////////////////// + //- rjf: process commands + // + for(RD_Cmd *cmd = 0; rd_next_view_cmd(&cmd);) { - default:{}break; - case RD_CmdKind_Search: - case RD_CmdKind_SearchBackwards: + RD_CmdKind kind = rd_cmd_kind_from_string(cmd->name); + switch(kind) { - vs->query_is_selected = 0; - }break; + default:{}break; + case RD_CmdKind_Search: + case RD_CmdKind_SearchBackwards: + { + vs->query_is_selected = 0; + }break; + } } - } - - ////////////////////////////// - //- rjf: consume events & perform navigations/edits - calculate state - // - EV_BlockTree block_tree = {0}; - EV_BlockRangeList block_ranges = {0}; - UI_ScrollListRowBlockArray row_blocks = {0}; - Vec2S64 cursor_tbl = {0}; - Vec2S64 mark_tbl = {0}; - Rng2S64 selection_tbl = {0}; - ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) - { - B32 state_dirty = 1; - B32 snap_to_cursor = 0; - B32 cursor_dirty__tbl = 0; - B32 take_autocomplete = 0; - for(UI_Event *event = 0;;) + + ////////////////////////////// + //- rjf: consume events & perform navigations/edits - calculate state + // + EV_BlockTree block_tree = {0}; + EV_BlockRangeList block_ranges = {0}; + UI_ScrollListRowBlockArray row_blocks = {0}; + Vec2S64 cursor_tbl = {0}; + Vec2S64 mark_tbl = {0}; + Rng2S64 selection_tbl = {0}; + ProfScope("consume events & perform navigations/edits - calculate state") UI_Focus(UI_FocusKind_On) { - ////////////////////////// - //- rjf: state -> viz blocks - // - if(state_dirty) ProfScope("state -> viz blocks") + B32 state_dirty = 1; + B32 snap_to_cursor = 0; + B32 cursor_dirty__tbl = 0; + B32 take_autocomplete = 0; + for(UI_Event *event = 0;;) { - MemoryZeroStruct(&block_tree); - MemoryZeroStruct(&block_ranges); - if(implicit_root || is_first_frame) + ////////////////////////// + //- rjf: state -> viz blocks + // + if(state_dirty) ProfScope("state -> viz blocks") { - ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); - } - block_tree = ev_block_tree_from_expr(scratch.arena, eval_view, filter, eval.expr); - block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); - if(implicit_root && block_ranges.first != 0) - { - block_ranges.count -= 1; - block_ranges.first = block_ranges.first->next; - } - } - - ////////////////////////// - //- rjf: block ranges -> ui row blocks - // - ProfScope("block ranges -> ui row blocks") - { - UI_ScrollListRowBlockChunkList row_block_chunks = {0}; - for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) - { - UI_ScrollListRowBlock block = {0}; - block.row_count = dim_1u64(n->v.range); - block.item_count = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); - ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); - } - row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); - } - - ////////////////////////// - //- rjf: conclude state update - // - if(state_dirty) - { - state_dirty = 0; - } - - ////////////////////////////// - //- rjf: 2D table coordinates * blocks -> stable cursor state - // - if(cursor_dirty__tbl) - { - cursor_dirty__tbl = 0; - struct - { - RD_WatchPt *pt_state; - Vec2S64 pt_tbl; - } - points[] = - { - {&ewv->cursor, cursor_tbl}, - {&ewv->mark, mark_tbl}, - }; - for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) - { - EV_Key last_key = points[point_idx].pt_state->key; - EV_Key last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); - if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) + MemoryZeroStruct(&block_tree); + MemoryZeroStruct(&block_ranges); + if(implicit_root || is_first_frame) { - points[point_idx].pt_state->key = last_parent_key; - EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); - for(EV_ExpandNode *n = node; n != 0; n = n->parent) + ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); + } + block_tree = ev_block_tree_from_expr(scratch.arena, eval_view, filter, eval.expr); + block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); + if(implicit_root && block_ranges.first != 0) + { + block_ranges.count -= 1; + block_ranges.first = block_ranges.first->next; + } + } + + ////////////////////////// + //- rjf: block ranges -> ui row blocks + // + ProfScope("block ranges -> ui row blocks") + { + UI_ScrollListRowBlockChunkList row_block_chunks = {0}; + for(EV_BlockRangeNode *n = block_ranges.first; n != 0; n = n->next) + { + UI_ScrollListRowBlock block = {0}; + block.row_count = dim_1u64(n->v.range); + block.item_count = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); + ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); + } + row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); + } + + ////////////////////////// + //- rjf: conclude state update + // + if(state_dirty) + { + state_dirty = 0; + } + + ////////////////////////////// + //- rjf: 2D table coordinates * blocks -> stable cursor state + // + if(cursor_dirty__tbl) + { + cursor_dirty__tbl = 0; + struct + { + RD_WatchPt *pt_state; + Vec2S64 pt_tbl; + } + points[] = + { + {&ewv->cursor, cursor_tbl}, + {&ewv->mark, mark_tbl}, + }; + for(U64 point_idx = 0; point_idx < ArrayCount(points); point_idx += 1) + { + EV_Key last_key = points[point_idx].pt_state->key; + EV_Key last_parent_key = points[point_idx].pt_state->parent_key; + points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); + if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key) && points[point_idx].pt_tbl.y != 0) { - points[point_idx].pt_state->key = n->key; - if(n->expanded == 0) + points[point_idx].pt_state->key = last_parent_key; + EV_ExpandNode *node = ev_expand_node_from_key(eval_view, last_parent_key); + for(EV_ExpandNode *n = node; n != 0; n = n->parent) { - break; + points[point_idx].pt_state->key = n->key; + if(n->expanded == 0) + { + break; + } + } + } + if(point_idx == 0 && + (!ev_key_match(ewv->cursor.key, last_key) || + !ev_key_match(ewv->cursor.parent_key, last_parent_key))) + { + ewv->text_editing = 0; + } + } + ewv->next_cursor = ewv->cursor; + ewv->next_mark = ewv->mark; + } + + ////////////////////////// + //- rjf: stable cursor state * blocks -> 2D table coordinates + // + EV_WindowedRowList mark_rows = {0}; + Rng2S64 cursor_tbl_range = {0}; + { + // rjf: compute 2d table coordinates + cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); + mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); + + // rjf: compute legal coordinate range, given selection-defining row + Rng1S64 cursor_x_range = {0}; + { + EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); + } + cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); + + // rjf: clamp x positions of cursor/mark tbl + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); + } + + // rjf: form selection range table coordinates + selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), + Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); + } + + ////////////////////////// + //- rjf: [table] snap to cursor + // + if(snap_to_cursor) + { + Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); + if(contains_1s64(global_vnum_range, cursor_tbl.y)) + { + UI_ScrollPt *scroll_pt = &scroll_pos.y; + + //- rjf: compute visible row range + Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), + scroll_pt->idx + 1 + num_possible_visible_rows); + + //- rjf: compute cursor row range from cursor item + Rng1S64 cursor_visibility_row_num_range = {0}; + cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; + cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; + + //- rjf: compute deltas & apply + S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); + S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); + S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; + new_num = clamp_1s64(global_vnum_range, new_num); + if(new_num > 0) + { + U64 new_idx = (U64)(new_num - 1); + ui_scroll_pt_target_idx(scroll_pt, new_idx); + } + } + } + + ////////////////////////////// + //- rjf: apply cursor/mark rugpull change + // + B32 cursor_rugpull = 0; + if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) + { + cursor_rugpull = 1; + ewv->cursor = ewv->next_cursor; + ewv->mark = ewv->next_mark; + } + + ////////////////////////// + //- rjf: grab next event, if any - otherwise exit the loop, as we now have + // the most up-to-date state + // + B32 next_event_good = ui_next_event(&event); + if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) + { + break; + } + UI_Event dummy_evt = zero_struct; + UI_Event *evt = &dummy_evt; + if(next_event_good) + { + evt = event; + } + B32 taken = 0; + + ////////////////////////////// + //- rjf: consume query-completion events, if this view is being used as a query + // + { + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg && + evt->kind == UI_EventKind_Press && + evt->slot == UI_EventActionSlot_Accept && + selection_tbl.min.y == selection_tbl.max.y) + { + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); + String8 cmd_name = cmd->first->string; + + // rjf: if we have no selection, just pick the first row + EV_Row *row = 0; + if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); + } + + // rjf: if we do have a selection, compute that row + else + { + row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); + } + + // rjf: use row to complete query + if(row->eval.expr != &e_expr_nil) + { + taken = 1; + E_Eval eval = row->eval; + switch(eval.space.kind) + { + default: + { + String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); + rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); + }break; + case E_SpaceKind_File: + case E_SpaceKind_FileSystem: + { + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + String8 file = rd_file_path_from_eval(scratch.arena, eval); + if(str8_match(type->name, str8_lit("folder"), 0)) + { + String8 new_input_string = push_str8f(scratch.arena, "%S/", file); + rd_cmd(RD_CmdKind_UpdateQuery, .string = new_input_string); + } + else + { + rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file); + } + }break; + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); + }break; + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = eval.value.u128.u64[0]; + rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); + }break; } } } - if(point_idx == 0 && - (!ev_key_match(ewv->cursor.key, last_key) || - !ev_key_match(ewv->cursor.parent_key, last_parent_key))) + } + + ////////////////////////// + //- rjf: begin editing on some operations + // + if(!ewv->text_editing && + (evt->kind == UI_EventKind_Text || + evt->flags & UI_EventFlag_Paste || + (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && + selection_tbl.min.x == selection_tbl.max.x && + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0)) + { + Vec2S64 selection_dim = dim_2s64(selection_tbl); + arena_clear(ewv->text_edit_arena); + ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); + ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); + ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + B32 any_edits_started = 0; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + if(cell_info.flags & RD_WatchCellFlag_CanEdit) + { + any_edits_started = 1; + String8 string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + U64 hash = ev_hash_from_key(pt.key); + U64 slot_idx = hash%ewv->text_edit_state_slots_count; + RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); + SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); + edit_state->pt = pt; + edit_state->cursor = txt_pt(1, string.size+1); + edit_state->mark = txt_pt(1, 1); + edit_state->input_size = string.size; + MemoryCopy(edit_state->input_buffer, string.str, string.size); + edit_state->initial_size = string.size; + MemoryCopy(edit_state->initial_buffer, string.str, string.size); + } + } + } + ewv->text_editing = any_edits_started; + } + + ////////////////////////// + //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if + // cannot apply to multi-cursor, then just don't take the event + // + if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && + (selection_tbl.min.y != 0 || selection_tbl.max.y != 0) && + (selection_tbl.max.y - selection_tbl.min.y > 0)) + { + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + if(row_node != 0) + { + taken = 1; + for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) + { + // rjf: unpack row info + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + + // rjf: loop through X selections and perform operations for each + for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + { +#if 0 // TODO(rjf): @cfg (multicursor watch window press operations) + //- rjf: determine operation for this cell + typedef enum OpKind + { + OpKind_Null, + OpKind_DoExpand, + } + OpKind; + OpKind kind = OpKind_Null; + switch(row_kind) + { + default:{}break; + case RD_WatchViewRowKind_Normal: + { + RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); + switch(col->kind) + { + default:{}break; + case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; + } + }break; + case RD_WatchViewRowKind_PrettyEntityControls: + if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) + { + kind = OpKind_DoExpand; + }break; + } + + //- rjf: perform operation + switch(kind) + { + default:{taken = 0;}break; + case OpKind_DoExpand: + if(ev_row_is_expandable(row)) + { + B32 is_expanded = ev_expansion_from_key(eval_view, row->key); + ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); + }break; + } +#endif + } + } + } + } + + ////////////////////////// + //- rjf: [text] apply textual edits + // + if(ewv->text_editing) + { + B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || + (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || + cursor_rugpull); + rd_state->text_edit_mode = 1; + if(editing_complete || + ((evt->kind == UI_EventKind_Edit || + evt->kind == UI_EventKind_Navigate || + evt->kind == UI_EventKind_Text) && + evt->delta_2s32.y == 0)) + { + taken = 1; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; + for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) + { + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) + { + continue; + } + RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; + RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); + String8 string = str8(edit_state->input_buffer, edit_state->input_size); + UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + + // rjf: copy + if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) + { + os_set_clipboard_text(op.copy); + } + + // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(autocomplete_hint_string.size != 0) + { + take_autocomplete = 1; + String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); + U64 word_off = (U64)(word_query.str - string.str); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + string = str8(edit_state->input_buffer, edit_state->input_size); + op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); + } + + // rjf: cancel? -> revert to initial string + if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) + { + string = str8(edit_state->initial_buffer, edit_state->initial_size); + } + + // rjf: obtain edited string + String8 new_string = string; + if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) + { + new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); + } + + // rjf: commit to edit state + new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); + MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); + edit_state->input_size = new_string.size; + edit_state->cursor = op.cursor; + edit_state->mark = op.mark; + + // rjf: commit edited cell string + switch(cell->kind) + { + case RD_WatchCellKind_ViewUI: + case RD_WatchCellKind_CallStackFrame: + {}break; + case RD_WatchCellKind_Expr: + { + RD_Cfg *cfg = row_info.group_cfg_child; + String8 child_key = str8_lit("expression"); + if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) + { + RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; + if(new_cfg_parent != &rd_nil_cfg) + { + child_key = str8_zero(); + } + if(new_cfg_parent == &rd_nil_cfg) + { + RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); + new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; + } + if(new_cfg_parent == &rd_nil_cfg) + { + new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + } + cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); + state_dirty = 1; + snap_to_cursor = 1; + } + if(cfg != &rd_nil_cfg) + { + RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; + rd_cfg_new_replace(expr, new_string); + } + }break; + case RD_WatchCellKind_Eval: + { + if(cell->eval.irtree.mode == E_Mode_Offset) + { + B32 should_commit_asap = editing_complete; + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + should_commit_asap = 1; + } + else if(evt->slot != UI_EventActionSlot_Cancel) + { + should_commit_asap = editing_complete; + } + if(should_commit_asap) + { + B32 success = 0; + success = rd_commit_eval_value_string(cell->eval, new_string); + if(!success) + { + log_user_error(str8_lit("Could not commit value successfully.")); + } + } + } + }break; + } + } + } + } + if(editing_complete) { ewv->text_editing = 0; } } - ewv->next_cursor = ewv->cursor; - ewv->next_mark = ewv->mark; - } - - ////////////////////////// - //- rjf: stable cursor state * blocks -> 2D table coordinates - // - EV_WindowedRowList mark_rows = {0}; - Rng2S64 cursor_tbl_range = {0}; - { - // rjf: compute 2d table coordinates - cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); - mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); - // rjf: compute legal coordinate range, given selection-defining row - Rng1S64 cursor_x_range = {0}; - { - EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); - } - cursor_tbl_range = r2s64(v2s64(cursor_x_range.min, 0), v2s64(cursor_x_range.max, block_tree.total_item_count - implicit_root)); - - // rjf: clamp x positions of cursor/mark tbl - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - mark_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), mark_tbl.v[axis]); - } - - // rjf: form selection range table coordinates - selection_tbl = r2s64p(Min(cursor_tbl.x, mark_tbl.x), Min(cursor_tbl.y, mark_tbl.y), - Max(cursor_tbl.x, mark_tbl.x), Max(cursor_tbl.y, mark_tbl.y)); - } - - ////////////////////////// - //- rjf: [table] snap to cursor - // - if(snap_to_cursor) - { - Rng1S64 global_vnum_range = r1s64(1, block_tree.total_row_count+1); - if(contains_1s64(global_vnum_range, cursor_tbl.y)) - { - UI_ScrollPt *scroll_pt = &scroll_pos.y; - - //- rjf: compute visible row range - Rng1S64 visible_row_num_range = r1s64(scroll_pt->idx + 1 - !!(scroll_pt->off < 0), - scroll_pt->idx + 1 + num_possible_visible_rows); - - //- rjf: compute cursor row range from cursor item - Rng1S64 cursor_visibility_row_num_range = {0}; - cursor_visibility_row_num_range.min = ev_vnum_from_num(&block_ranges, cursor_tbl.y) - 1; - cursor_visibility_row_num_range.max = cursor_visibility_row_num_range.min + 3; - - //- rjf: compute deltas & apply - S64 min_delta = Min(0, cursor_visibility_row_num_range.min-visible_row_num_range.min); - S64 max_delta = Max(0, cursor_visibility_row_num_range.max-visible_row_num_range.max); - S64 new_num = (S64)scroll_pt->idx + 1 + min_delta + max_delta; - new_num = clamp_1s64(global_vnum_range, new_num); - if(new_num > 0) - { - U64 new_idx = (U64)(new_num - 1); - ui_scroll_pt_target_idx(scroll_pt, new_idx); - } - } - } - - ////////////////////////////// - //- rjf: apply cursor/mark rugpull change - // - B32 cursor_rugpull = 0; - if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) - { - cursor_rugpull = 1; - ewv->cursor = ewv->next_cursor; - ewv->mark = ewv->next_mark; - } - - ////////////////////////// - //- rjf: grab next event, if any - otherwise exit the loop, as we now have - // the most up-to-date state - // - B32 next_event_good = ui_next_event(&event); - if(!cursor_rugpull && (!next_event_good || !ui_is_focus_active())) - { - break; - } - UI_Event dummy_evt = zero_struct; - UI_Event *evt = &dummy_evt; - if(next_event_good) - { - evt = event; - } - B32 taken = 0; - - ////////////////////////////// - //- rjf: consume query-completion events, if this view is being used as a query - // - { - RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); - if(lister != &rd_nil_cfg && - evt->kind == UI_EventKind_Press && - evt->slot == UI_EventActionSlot_Accept && - selection_tbl.min.y == selection_tbl.max.y) - { - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); - RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); - String8 cmd_name = cmd->first->string; - - // rjf: if we have no selection, just pick the first row - EV_Row *row = 0; - if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) - { - row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); - } - - // rjf: if we do have a selection, compute that row - else - { - row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); - } - - // rjf: use row to complete query - if(row->eval.expr != &e_expr_nil) - { - taken = 1; - E_Eval eval = row->eval; - switch(eval.space.kind) - { - default: - { - String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); - rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); - }break; - case E_SpaceKind_File: - case E_SpaceKind_FileSystem: - { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - String8 file = rd_file_path_from_eval(scratch.arena, eval); - if(str8_match(type->name, str8_lit("folder"), 0)) - { - String8 new_input_string = push_str8f(scratch.arena, "%S/", file); - rd_cmd(RD_CmdKind_UpdateQuery, .string = new_input_string); - } - else - { - rd_cmd(RD_CmdKind_CompleteQuery, .file_path = file); - } - }break; - case RD_EvalSpaceKind_MetaCfg: - { - RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); - }break; - case RD_EvalSpaceKind_MetaUnattachedProcess: - { - U64 pid = eval.value.u128.u64[0]; - rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); - }break; - } - } - } - } - - ////////////////////////// - //- rjf: begin editing on some operations - // - if(!ewv->text_editing && - (evt->kind == UI_EventKind_Text || - evt->flags & UI_EventFlag_Paste || - (evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Edit)) && - selection_tbl.min.x == selection_tbl.max.x && - (selection_tbl.min.y != 0 || selection_tbl.max.y != 0)) - { - Vec2S64 selection_dim = dim_2s64(selection_tbl); - arena_clear(ewv->text_edit_arena); - ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); - ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); - ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - B32 any_edits_started = 0; - for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags & (~EV_StringFlag_ReadOnlyDisplayRules), &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.flags & RD_WatchCellFlag_CanEdit) - { - any_edits_started = 1; - String8 string = cell_info.string; - string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - U64 hash = ev_hash_from_key(pt.key); - U64 slot_idx = hash%ewv->text_edit_state_slots_count; - RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); - SLLStackPush_N(ewv->text_edit_state_slots[slot_idx], edit_state, pt_hash_next); - edit_state->pt = pt; - edit_state->cursor = txt_pt(1, string.size+1); - edit_state->mark = txt_pt(1, 1); - edit_state->input_size = string.size; - MemoryCopy(edit_state->input_buffer, string.str, string.size); - edit_state->initial_size = string.size; - MemoryCopy(edit_state->initial_buffer, string.str, string.size); - } - } - } - ewv->text_editing = any_edits_started; - } - - ////////////////////////// - //- rjf: [table] do cell-granularity multi-cursor 'accept' operations (expansions / etc.); if - // cannot apply to multi-cursor, then just don't take the event - // - if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && - (selection_tbl.min.y != 0 || selection_tbl.max.y != 0) && - (selection_tbl.max.y - selection_tbl.min.y > 0)) - { - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - if(row_node != 0) + ////////////////////////// + //- rjf: [table] do cell-granularity copies + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) { taken = 1; + String8List strs = {0}; + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowNode *row_node = rows.first; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { - // rjf: unpack row info EV_Row *row = &row_node->row; RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - - // rjf: loop through X selections and perform operations for each - for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) + S64 cell_x = 0; + for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) { -#if 0 // TODO(rjf): @cfg (multicursor watch window press operations) - //- rjf: determine operation for this cell - typedef enum OpKind + if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) { - OpKind_Null, - OpKind_DoExpand, + continue; } - OpKind; - OpKind kind = OpKind_Null; - switch(row_kind) + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + String8 cell_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + cell_string = str8_skip_chop_whitespace(cell_string); + U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); + if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) { - default:{}break; - case RD_WatchViewRowKind_Normal: - { - RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); - switch(col->kind) - { - default:{}break; - case RD_WatchViewColumnKind_Expr: {kind = OpKind_DoExpand;}break; - } - }break; - case RD_WatchViewRowKind_PrettyEntityControls: - if((!rd_entity_is_nil(row_info.collection_entity) || row_info.collection_ctrl_entity != &ctrl_entity_nil) && selection_tbl.min.x == 1 && selection_tbl.max.x == 1) - { - kind = OpKind_DoExpand; - }break; + str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", + comma_pos < cell_string.size ? "\"" : "", + cell_string, + comma_pos < cell_string.size ? "\"" : "", + cell_x+1 <= selection_tbl.max.x ? "," : ""); } - - //- rjf: perform operation - switch(kind) + else { - default:{taken = 0;}break; - case OpKind_DoExpand: - if(ev_row_is_expandable(row)) - { - B32 is_expanded = ev_expansion_from_key(eval_view, row->key); - ev_key_set_expansion(eval_view, row->block->key, row->key, !is_expanded); - }break; + str8_list_push(scratch.arena, &strs, cell_string); } -#endif + } + if(y+1 <= selection_tbl.max.y) + { + str8_list_push(scratch.arena, &strs, str8_lit("\n")); } } + String8 string = str8_list_join(scratch.arena, &strs, 0); + os_set_clipboard_text(string); } - } - - ////////////////////////// - //- rjf: [text] apply textual edits - // - if(ewv->text_editing) - { - B32 editing_complete = ((evt->kind == UI_EventKind_Press && (evt->slot == UI_EventActionSlot_Cancel || evt->slot == UI_EventActionSlot_Accept)) || - (evt->kind == UI_EventKind_Navigate && evt->delta_2s32.y != 0) || - cursor_rugpull); - rd_state->text_edit_mode = 1; - if(editing_complete || - ((evt->kind == UI_EventKind_Edit || - evt->kind == UI_EventKind_Navigate || - evt->kind == UI_EventKind_Text) && - evt->delta_2s32.y == 0)) + + ////////////////////////// + //- rjf: [table] do cell-granularity deletions + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) { taken = 1; + state_dirty = 1; + snap_to_cursor = 1; + RD_CfgList cfgs_to_remove = {0}; + RD_WatchPt next_cursor_pt = {0}; + B32 next_cursor_set = 0; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) @@ -3132,1547 +3341,1307 @@ rd_view_ui(Rng2F32 rect) continue; } RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); - String8 string = str8(edit_state->input_buffer, edit_state->input_size); - UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - - // rjf: copy - if(op.flags & UI_TxtOpFlag_Copy && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y) - { - os_set_clipboard_text(op.copy); - } - - // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op - if(autocomplete_hint_string.size != 0) - { - take_autocomplete = 1; - String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); - U64 word_off = (U64)(word_query.str - string.str); - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); - new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); - string = str8(edit_state->input_buffer, edit_state->input_size); - op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); - } - - // rjf: cancel? -> revert to initial string - if(editing_complete && evt->slot == UI_EventActionSlot_Cancel) - { - string = str8(edit_state->initial_buffer, edit_state->initial_size); - } - - // rjf: obtain edited string - String8 new_string = string; - if(!txt_pt_match(op.range.min, op.range.max) || op.replace.size != 0) - { - new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(op.range.min.column, op.range.max.column), op.replace); - } - - // rjf: commit to edit state - new_string.size = Min(new_string.size, sizeof(edit_state->input_buffer)); - MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); - edit_state->input_size = new_string.size; - edit_state->cursor = op.cursor; - edit_state->mark = op.mark; - - // rjf: commit edited cell string switch(cell->kind) { - case RD_WatchCellKind_ViewUI: - case RD_WatchCellKind_CallStackFrame: - {}break; + default:{}break; case RD_WatchCellKind_Expr: { RD_Cfg *cfg = row_info.group_cfg_child; - String8 child_key = str8_lit("expression"); - if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) - { - RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; - if(new_cfg_parent != &rd_nil_cfg) - { - child_key = str8_zero(); - } - if(new_cfg_parent == &rd_nil_cfg) - { - RD_CfgList all_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, row_info.group_cfg_name); - new_cfg_parent = rd_cfg_list_last(&all_cfgs)->parent; - } - if(new_cfg_parent == &rd_nil_cfg) - { - new_cfg_parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - } - cfg = rd_cfg_new(new_cfg_parent, row_info.group_cfg_name); - state_dirty = 1; - snap_to_cursor = 1; - } if(cfg != &rd_nil_cfg) { - RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; - rd_cfg_new_replace(expr, new_string); - } - }break; - case RD_WatchCellKind_Tag: - if(editing_complete) - { - ev_key_set_view_rule(eval_view, pt.key, new_string); - RD_Cfg *cfg = row_info.group_cfg_child; - if(cfg != &rd_nil_cfg && new_string.size != 0) - { - RD_Cfg *view_rule = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("view_rule")); - rd_cfg_new(view_rule, new_string); - } - else if(cfg != &rd_nil_cfg && new_string.size == 0) - { - rd_cfg_release(rd_cfg_child_from_string(cfg, str8_lit("view_rule"))); + rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); + U64 deleted_num = ev_block_num_from_id(row->block, row->key.child_id); + if(deleted_num != 0) + { + EV_Key parent_key = row->block->parent->key; + EV_Key key = row->block->key; + U64 fallback_id_prev = ev_block_id_from_num(row->block, deleted_num-1); + U64 fallback_id_next = ev_block_id_from_num(row->block, deleted_num+1); + if(fallback_id_next != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_next); + } + else if(fallback_id_prev != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_prev); + } + RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; + next_cursor_pt = new_pt; + next_cursor_set = 1; + state_dirty = 1; + } } }break; case RD_WatchCellKind_Eval: { - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - if(cell_info.eval.irtree.mode == E_Mode_Offset) + rd_commit_eval_value_string(cell->eval, str8_zero()); + }break; + } + } + } + for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + if(next_cursor_set) + { + ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; + } + } + + ////////////////////////// + //- rjf: [table] apply deltas to cursor & mark + // + if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) + { + B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; + Vec2S32 delta = evt->delta_2s32; + if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + if(delta.x > 0 || delta.y > 0) + { + cursor_tbl.x = selection_tbl.max.x; + cursor_tbl.y = selection_tbl.max.y; + } + else if(delta.x < 0 || delta.y < 0) + { + cursor_tbl.x = selection_tbl.min.x; + cursor_tbl.y = selection_tbl.min.y; + } + } + if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) + { + MemoryZeroStruct(&delta); + } + B32 moved = 1; + switch(evt->delta_unit) + { + default:{moved = 0;}break; + case UI_EventDeltaUnit_Char: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] += delta.v[axis]; + if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; + } + if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) + { + cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; + } + cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); + } + }break; + case UI_EventDeltaUnit_Word: + case UI_EventDeltaUnit_Line: + case UI_EventDeltaUnit_Page: + { + cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : + delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : + cursor_tbl.x); + cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : + delta.y<0 ? -(num_possible_visible_rows-3) : + 0)); + cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], + cursor_tbl_range.max.y), + cursor_tbl.y); + }break; + case UI_EventDeltaUnit_Whole: + { + for EachEnumVal(Axis2, axis) + { + cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); + } + }break; + } + if(moved) + { + taken = 1; + cursor_dirty__tbl = 1; + snap_to_cursor = 1; + } + } + + ////////////////////////// + //- rjf: [table] stick table mark to cursor if needed + // + if(!ewv->text_editing) + { + if(taken && !(evt->flags & UI_EventFlag_KeepMark)) + { + mark_tbl = cursor_tbl; + } + } + + ////////////////////////// + //- rjf: [table] do cell-granularity reorders + // + if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) + { + taken = 1; + if(filter.size == 0) + { + // rjf: determine blocks of each endpoint of the table selection + EV_Block *selection_endpoint_blocks[2] = + { + ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, + ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, + }; + + // rjf: pick shallowest block within which we can do reordering + U64 selection_depths[2] = + { + ev_depth_from_block(selection_endpoint_blocks[0]), + ev_depth_from_block(selection_endpoint_blocks[1]), + }; + EV_Block *selection_block = (selection_depths[1] < selection_depths[0] + ? selection_endpoint_blocks[1] + : selection_endpoint_blocks[0]); + + // rjf: find selection keys within the block in which we are doing reordering + EV_Key selection_keys_in_block[2] = {0}; + { + for EachElement(idx, selection_endpoint_blocks) + { + EV_Block *endpoint_block = selection_endpoint_blocks[idx]; + if(endpoint_block == selection_block) + { + selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); + } + else + { + for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) { - B32 should_commit_asap = editing_complete; - if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + endpoint_block = endpoint_block->parent; + } + if(endpoint_block->parent == selection_block) + { + selection_keys_in_block[idx] = endpoint_block->key; + } + } + } + EV_Key fallback_key = {0}; + for EachElement(idx, selection_endpoint_blocks) + { + if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + fallback_key = selection_keys_in_block[idx]; + } + } + for EachElement(idx, selection_endpoint_blocks) + { + if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) + { + selection_keys_in_block[idx] = fallback_key; + } + } + } + + // rjf: determine collection info for the block + String8 group_cfg_name = {0}; + { + E_IRTreeAndType block_irtree = selection_block->eval.irtree; + E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + if(block_type_kind == E_TypeKind_Set) + { + E_Type *block_type = e_type_from_key__cached(block_type_key); + group_cfg_name = rd_singular_from_code_name_plural(block_type->name); + if(group_cfg_name.size == 0) + { + group_cfg_name = block_type->name; + } + } + } + + // rjf: map selection endpoints to cfgs + RD_Cfg *first_cfg = &rd_nil_cfg; + RD_Cfg *last_cfg = &rd_nil_cfg; + if(group_cfg_name.size != 0) + { + first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); + last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); + } + + // rjf: reorder + if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) + { + RD_Cfg *first_cfg_prev = &rd_nil_cfg; + RD_Cfg *last_cfg_next = &rd_nil_cfg; + for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) + { + if(str8_match(prev->string, first_cfg->string, 0)) + { + first_cfg_prev = prev; + break; + } + } + for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) + { + if(str8_match(next->string, last_cfg->string, 0)) + { + last_cfg_next = next; + break; + } + } + if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = first_cfg_prev->parent; + rd_cfg_unhook(parent, first_cfg_prev); + rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); + } + if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) + { + state_dirty = 1; + snap_to_cursor = 1; + RD_Cfg *parent = last_cfg_next->parent; + rd_cfg_unhook(parent, last_cfg_next); + rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); + } + } + } + } + + ////////////////////////// + //- rjf: consume event, if taken + // + if(taken && evt != &dummy_evt) + { + ui_eat_event(evt); + } + } + if(take_autocomplete) + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + ui_eat_event(evt); + break; + } + } + } + } + + ////////////////////////////// + //- rjf: build ui + // + B32 pressed = 0; + ProfScope("build ui") + { + Vec2F32 rect_dim = dim_2f32(rect); + F32 contents_width_px = (rect_dim.x - floor_f32(ui_bottom_font_size()*1.5f)); + Rng1S64 visible_row_rng = {0}; + UI_ScrollListParams scroll_list_params = {0}; + { + scroll_list_params.flags = UI_ScrollListFlag_All; + scroll_list_params.row_height_px = row_height_px; + scroll_list_params.dim_px = rect_dim; + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); + scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); + scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; + scroll_list_params.row_blocks = row_blocks; + } + UI_BoxFlags disabled_flags = ui_top_flags(); + if(d_ctrl_targets_running()) + { + disabled_flags |= UI_BoxFlag_Disabled; + } + UI_ScrollListSignal scroll_list_sig = {0}; + UI_Focus(UI_FocusKind_On) + UI_ScrollList(&scroll_list_params, &scroll_pos.y, + 0, + 0, + &visible_row_rng, + &scroll_list_sig) + UI_Focus(UI_FocusKind_Null) + { + ui_set_next_pref_height(ui_children_sum(1)); + ui_set_next_child_layout_axis(Axis2_Y); + UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); + UI_Parent(table) + { + Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; + + //////////////////////// + //- rjf: viz blocks -> rows + // + EV_WindowedRowList rows = {0}; + { + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); + } + + //////////////////////// + //- rjf: rows -> row infos + // + RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build boundaries + // + B32 cell_pcts_are_dirty = 0; + ProfScope("build boundaries") + { + U64 idx = 0; + U64 boundary_start_idx = 0; + EV_Row *last_row = 0; + RD_WatchRowInfo *last_row_info = 0; + for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) + { + //- rjf: determine if this row breaks the topology + B32 is_new_topology = (row_node == 0); + if(row_node != 0 && last_row_info != 0) + { + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[idx]; + for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + is_new_topology = 1; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + is_new_topology = 1; + break; + } + } + } + + //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations + if(is_new_topology) + { + EV_Row *row = last_row; + RD_WatchRowInfo *row_info = last_row_info; + F32 row_width_px = contents_width_px; + if(row_info != 0) + { + U64 row_hash = ev_hash_from_key(row->key); + F32 cell_x_px = 0; + U64 cell_idx = 0; + for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) + { + if(cell->pct == 0 || cell->next->pct == 0) { - should_commit_asap = 1; + continue; } - else if(evt->slot != UI_EventActionSlot_Cancel) + U64 cell_id = rd_id_from_watch_cell(cell); + F32 cell_width_px = cell->px + cell->pct * row_width_px; + F32 next_cell_x_px = cell_x_px + cell_width_px; { - should_commit_asap = editing_complete; - } - if(should_commit_asap) - { - B32 success = 0; - success = rd_commit_eval_value_string(cell_info.eval, new_string); - if(!success) + Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.4f, + boundary_start_idx*row_height_px, + next_cell_x_px + ui_top_font_size()*0.4f, + idx*row_height_px); + UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) { - log_user_error(str8_lit("Could not commit value successfully.")); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig)) + { + typedef struct DragData DragData; + struct DragData + { + F32 min_pct; + F32 max_pct; + }; + if(ui_pressed(sig)) + { + DragData drag_data = {cell->pct, cell->next->pct}; + ui_store_drag_struct(&drag_data); + } + DragData *drag_data = ui_get_drag_struct(DragData); + F32 min_pct__pre = drag_data->min_pct; + F32 max_pct__pre = drag_data->max_pct; + F32 min_px__pre = min_pct__pre*row_width_px; + F32 max_px__pre = max_pct__pre*row_width_px; + F32 min_px__post = min_px__pre + ui_drag_delta().x; + F32 max_px__post = max_px__pre - ui_drag_delta().x; + F32 min_pct__post = min_px__post/row_width_px; + F32 max_pct__post = max_px__post/row_width_px; + if(min_pct__post < 0.05f) + { + min_pct__post = 0.05f; + max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; + } + if(max_pct__post < 0.05f) + { + max_pct__post = 0.05f; + min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; + } + if(ui_double_clicked(sig)) + { + F32 default_sum = cell->default_pct + cell->next->default_pct; + F32 current_sum = min_pct__pre + max_pct__pre;; + min_pct__post = current_sum * (cell->default_pct / default_sum); + max_pct__post = current_sum * (cell->next->default_pct / default_sum); + ui_kill_action(); + } + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); + RD_Cfg *min_cfg = &rd_nil_cfg; + RD_Cfg *max_cfg = &rd_nil_cfg; + { + RD_Cfg *pct_child = style->first; + U64 c_idx = 0; + for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) + { + if(pct_child == &rd_nil_cfg) + { + pct_child = rd_cfg_newf(style, "%f", c->pct); + } + if(c_idx == cell_idx) + { + min_cfg = pct_child; + } + if(c_idx == cell_idx+1) + { + max_cfg = pct_child; + } + pct_child = pct_child->next; + } + rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); + rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); + cell_pcts_are_dirty = 1; + } + } + } + } + cell_x_px = next_cell_x_px; + } + } + boundary_start_idx = idx; + } + + //- rjf: advance + if(row_node == 0) + { + break; + } + else + { + last_row = &row_node->row; + last_row_info = &row_infos[idx]; + } + } + } + + //////////////////////// + //- rjf: if cell widths are dirty -> recompute row infos + // + if(cell_pcts_are_dirty) + { + U64 idx = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) + { + EV_Row *row = &row_node->row; + row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); + } + } + + //////////////////////// + //- rjf: build table + // + ProfScope("build table") + { + U64 local_row_idx = 0; + U64 global_row_idx = rows.count_before_semantic; + RD_WatchRowInfo last_row_info = {0}; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) + { + //////////////////////// + //- rjf: unpack row info + // + ProfBegin("unpack row info"); + EV_Row *row = &row_node->row; + RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; + U64 row_hash = ev_hash_from_key(row->key); + U64 row_depth = ev_depth_from_block(row->block); + B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); + B32 row_expanded = ev_expansion_from_key(eval_view, row->key); + B32 next_row_expanded = row_expanded; + B32 row_is_expandable = row_info->can_expand; + if(implicit_root && row_depth > 0) + { + row_depth -= 1; + } + ProfEnd(); + + //////////////////////// + //- rjf: determine if this row fits the last row's topology + // + B32 row_matches_last_row_topology = 1; + if(row_node != rows.first) + { + for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; + last_cell = last_cell->next, this_cell = this_cell->next) + { + if(last_cell == 0 && this_cell == 0) + { + break; + } + if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) + { + row_matches_last_row_topology = 0; + break; + } + if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) + { + row_matches_last_row_topology = 0; + break; + } + } + } + + //////////////////////// + //- rjf: store last row's info, for next iteration + // + last_row_info = *row_info; + + //////////////////////// + //- rjf: determine if row's data is fresh and/or bad + // + ProfBegin("determine if row's data is fresh and/or bad"); + B32 row_is_fresh = 0; + B32 row_is_bad = 0; + switch(row->eval.irtree.mode) + { + default:{}break; + case E_Mode_Offset: + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + { + U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size); + CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + row_is_fresh = 1; + } + if(slice.byte_bad_flags[idx] != 0) + {row_is_bad = 1; } } } }break; } - } - } - } - if(editing_complete) - { - ewv->text_editing = 0; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity copies - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Copy) - { - taken = 1; - String8List strs = {0}; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - String8 cell_string = cell_info.string; - cell_string = str8_skip_chop_whitespace(cell_string); - U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); - if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) - { - str8_list_pushf(scratch.arena, &strs, "%s%S%s%s", - comma_pos < cell_string.size ? "\"" : "", - cell_string, - comma_pos < cell_string.size ? "\"" : "", - cell_x+1 <= selection_tbl.max.x ? "," : ""); - } - else - { - str8_list_push(scratch.arena, &strs, cell_string); - } - } - if(y+1 <= selection_tbl.max.y) - { - str8_list_push(scratch.arena, &strs, str8_lit("\n")); - } - } - String8 string = str8_list_join(scratch.arena, &strs, 0); - os_set_clipboard_text(string); - } - - ////////////////////////// - //- rjf: [table] do cell-granularity deletions - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Delete) - { - taken = 1; - state_dirty = 1; - snap_to_cursor = 1; - RD_CfgList cfgs_to_remove = {0}; - RD_WatchPt next_cursor_pt = {0}; - B32 next_cursor_set = 0; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); - EV_WindowedRowNode *row_node = rows.first; - for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); - S64 cell_x = 0; - for(RD_WatchCell *cell = row_info.cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - if(cell_x < selection_tbl.min.x || selection_tbl.max.x < cell_x) - { - continue; - } - RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - switch(cell->kind) - { - default:{}break; - case RD_WatchCellKind_Expr: + ProfEnd(); + + //////////////////////// + //- rjf: determine row's flags & color palette + // + ProfBegin("determine row's flags & color palette"); + UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; { - RD_Cfg *cfg = row_info.group_cfg_child; - if(cfg != &rd_nil_cfg) + if(row_is_fresh) { - rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); - U64 deleted_num = ev_block_num_from_id(row->block, row->key.child_id); - if(deleted_num != 0) + ui_set_next_tag(str8_lit("fresh")); + row_flags |= UI_BoxFlag_DrawBackground; + } + else if(global_row_idx & 1) + { + ui_set_next_tag(str8_lit("alt")); + row_flags |= UI_BoxFlag_DrawBackground; + } + if(!row_matches_last_row_topology) + { + row_flags |= UI_BoxFlag_DrawSideTop; + } + } + ProfEnd(); + + //////////////////////// + //- rjf: build row box + // + ui_set_next_flags(disabled_flags); + ui_set_next_pref_width(ui_px(contents_width_px, 1.f)); + ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); + ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); + UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + RD_WatchRowExtrasDrawData *row_draw_data = push_array(ui_build_arena(), RD_WatchRowExtrasDrawData, 1); + row_draw_data->breaks_from_prev = !row_matches_last_row_topology; + ui_box_equip_custom_draw(row_box, rd_watch_row_extras_custom_draw, row_draw_data); + + ////////////////////// + //- rjf: build row contents + // + RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) + { + //////////////////// + //- rjf: draw start of cache lines in expansions + // + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(space_entity->kind == CTRL_EntityKind_Process) { - EV_Key parent_key = row->block->parent->key; - EV_Key key = row->block->key; - U64 fallback_id_prev = ev_block_id_from_num(row->block, deleted_num-1); - U64 fallback_id_next = ev_block_id_from_num(row->block, deleted_num+1); - if(fallback_id_next != 0) + U64 row_offset = row->eval.value.u64; + if((row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && + row_offset%64 == 0 && row_depth > 0) { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_next); + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(0); + ui_set_next_fixed_height(ui_top_font_size()*0.2f); + ui_set_next_tag(str8_lit("pop")); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); } - else if(fallback_id_prev != 0) - { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_prev); - } - RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; - next_cursor_pt = new_pt; - next_cursor_set = 1; - state_dirty = 1; } } - }break; - case RD_WatchCellKind_Tag: - { - if(row_info.group_cfg_child != &rd_nil_cfg) + + ////////////// + //- rjf: draw mid-row cache line boundaries in expansions + // + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) { - rd_cfg_release(rd_cfg_child_from_string(row_info.group_cfg_child, str8_lit("view_rule"))); + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); + if(space_entity->kind == CTRL_EntityKind_Process && + (row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && + row->eval.value.u64%64 != 0 && + row_depth > 0 && + !row_expanded) + { + U64 next_off = (row->eval.value.u64 + e_type_byte_size_from_key(row->eval.irtree.type_key)); + if(next_off%64 != 0 && row->eval.value.u64/64 < next_off/64) + { + ui_set_next_fixed_x(0); + ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); + ui_set_next_fixed_height(ui_top_font_size()*1.f); + ui_set_next_tag(str8_lit("pop")); + ui_set_next_transparency(0.5f); + ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); + } + } } - ev_key_set_view_rule(eval_view, row->key, str8_zero()); - state_dirty = 1; - }break; - case RD_WatchCellKind_Eval: - { - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - rd_commit_eval_value_string(cell_info.eval, str8_zero()); - }break; - } - } - } - for(RD_CfgNode *n = cfgs_to_remove.first; n != 0; n = n->next) - { - rd_cfg_release(n->v); - } - if(next_cursor_set) - { - ewv->cursor = ewv->mark = ewv->next_cursor = ewv->next_mark = next_cursor_pt; - } - } - - ////////////////////////// - //- rjf: [table] apply deltas to cursor & mark - // - if(!ewv->text_editing && !(evt->flags & UI_EventFlag_Delete) && !(evt->flags & UI_EventFlag_Reorder)) - { - B32 cursor_tbl_min_is_empty_selection[Axis2_COUNT] = {0, 1}; - Vec2S32 delta = evt->delta_2s32; - if(evt->flags & UI_EventFlag_PickSelectSide && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - if(delta.x > 0 || delta.y > 0) - { - cursor_tbl.x = selection_tbl.max.x; - cursor_tbl.y = selection_tbl.max.y; - } - else if(delta.x < 0 || delta.y < 0) - { - cursor_tbl.x = selection_tbl.min.x; - cursor_tbl.y = selection_tbl.min.y; - } - } - if(evt->flags & UI_EventFlag_ZeroDeltaOnSelect && !MemoryMatchStruct(&selection_tbl.min, &selection_tbl.max)) - { - MemoryZeroStruct(&delta); - } - B32 moved = 1; - switch(evt->delta_unit) - { - default:{moved = 0;}break; - case UI_EventDeltaUnit_Char: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] += delta.v[axis]; - if(cursor_tbl.v[axis] < cursor_tbl_range.min.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.max.v[axis]; - } - if(cursor_tbl.v[axis] > cursor_tbl_range.max.v[axis]) - { - cursor_tbl.v[axis] = cursor_tbl_range.min.v[axis]; - } - cursor_tbl.v[axis] = clamp_1s64(r1s64(cursor_tbl_range.min.v[axis], cursor_tbl_range.max.v[axis]), cursor_tbl.v[axis]); - } - }break; - case UI_EventDeltaUnit_Word: - case UI_EventDeltaUnit_Line: - case UI_EventDeltaUnit_Page: - { - cursor_tbl.x = (delta.x>0 ? (cursor_tbl_range.max.x) : - delta.x<0 ? (cursor_tbl_range.min.x + !!cursor_tbl_min_is_empty_selection[Axis2_X]) : - cursor_tbl.x); - cursor_tbl.y += ((delta.y>0 ? +(num_possible_visible_rows-3) : - delta.y<0 ? -(num_possible_visible_rows-3) : - 0)); - cursor_tbl.y = clamp_1s64(r1s64(cursor_tbl_range.min.y + !!cursor_tbl_min_is_empty_selection[Axis2_Y], - cursor_tbl_range.max.y), - cursor_tbl.y); - }break; - case UI_EventDeltaUnit_Whole: - { - for EachEnumVal(Axis2, axis) - { - cursor_tbl.v[axis] = (delta.v[axis]>0 ? cursor_tbl_range.max.v[axis] : delta.v[axis]<0 ? cursor_tbl_range.min.v[axis] + !!cursor_tbl_min_is_empty_selection[axis] : cursor_tbl.v[axis]); - } - }break; - } - if(moved) - { - taken = 1; - cursor_dirty__tbl = 1; - snap_to_cursor = 1; - } - } - - ////////////////////////// - //- rjf: [table] stick table mark to cursor if needed - // - if(!ewv->text_editing) - { - if(taken && !(evt->flags & UI_EventFlag_KeepMark)) - { - mark_tbl = cursor_tbl; - } - } - - ////////////////////////// - //- rjf: [table] do cell-granularity reorders - // - if(!ewv->text_editing && evt->flags & UI_EventFlag_Reorder) - { - taken = 1; - if(filter.size == 0) - { - // rjf: determine blocks of each endpoint of the table selection - EV_Block *selection_endpoint_blocks[2] = - { - ev_block_range_from_num(&block_ranges, selection_tbl.min.y).block, - ev_block_range_from_num(&block_ranges, selection_tbl.max.y).block, - }; - - // rjf: pick shallowest block within which we can do reordering - U64 selection_depths[2] = - { - ev_depth_from_block(selection_endpoint_blocks[0]), - ev_depth_from_block(selection_endpoint_blocks[1]), - }; - EV_Block *selection_block = (selection_depths[1] < selection_depths[0] - ? selection_endpoint_blocks[1] - : selection_endpoint_blocks[0]); - - // rjf: find selection keys within the block in which we are doing reordering - EV_Key selection_keys_in_block[2] = {0}; - { - for EachElement(idx, selection_endpoint_blocks) - { - EV_Block *endpoint_block = selection_endpoint_blocks[idx]; - if(endpoint_block == selection_block) - { - selection_keys_in_block[idx] = ev_key_from_num(&block_ranges, selection_tbl.v[idx].y); - } - else - { - for(;endpoint_block->parent != selection_block && endpoint_block != &ev_nil_block;) - { - endpoint_block = endpoint_block->parent; - } - if(endpoint_block->parent == selection_block) - { - selection_keys_in_block[idx] = endpoint_block->key; - } - } - } - EV_Key fallback_key = {0}; - for EachElement(idx, selection_endpoint_blocks) - { - if(!ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - fallback_key = selection_keys_in_block[idx]; - } - } - for EachElement(idx, selection_endpoint_blocks) - { - if(ev_key_match(selection_keys_in_block[idx], ev_key_zero())) - { - selection_keys_in_block[idx] = fallback_key; - } - } - } - - // rjf: determine collection info for the block - String8 group_cfg_name = {0}; - { - E_IRTreeAndType block_irtree = selection_block->eval.irtree; - E_TypeKey block_type_key = block_irtree.type_key; - E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Set) - { - E_Type *block_type = e_type_from_key__cached(block_type_key); - group_cfg_name = rd_singular_from_code_name_plural(block_type->name); - if(group_cfg_name.size == 0) - { - group_cfg_name = block_type->name; - } - } - } - - // rjf: map selection endpoints to cfgs - RD_Cfg *first_cfg = &rd_nil_cfg; - RD_Cfg *last_cfg = &rd_nil_cfg; - if(group_cfg_name.size != 0) - { - first_cfg = rd_cfg_from_id(selection_keys_in_block[0].child_id); - last_cfg = rd_cfg_from_id(selection_keys_in_block[1].child_id); - } - - // rjf: reorder - if(first_cfg != &rd_nil_cfg && last_cfg != &rd_nil_cfg) - { - RD_Cfg *first_cfg_prev = &rd_nil_cfg; - RD_Cfg *last_cfg_next = &rd_nil_cfg; - for(RD_Cfg *prev = first_cfg->prev; prev != &rd_nil_cfg; prev = prev->prev) - { - if(str8_match(prev->string, first_cfg->string, 0)) - { - first_cfg_prev = prev; - break; - } - } - for(RD_Cfg *next = last_cfg->next; next != &rd_nil_cfg; next = next->next) - { - if(str8_match(next->string, last_cfg->string, 0)) - { - last_cfg_next = next; - break; - } - } - if(evt->delta_2s32.y < 0 && first_cfg != &rd_nil_cfg && first_cfg_prev != &rd_nil_cfg) - { - state_dirty = 1; - snap_to_cursor = 1; - RD_Cfg *parent = first_cfg_prev->parent; - rd_cfg_unhook(parent, first_cfg_prev); - rd_cfg_insert_child(parent, last_cfg, first_cfg_prev); - } - if(evt->delta_2s32.y > 0 && last_cfg != &rd_nil_cfg && last_cfg_next != &rd_nil_cfg) - { - state_dirty = 1; - snap_to_cursor = 1; - RD_Cfg *parent = last_cfg_next->parent; - rd_cfg_unhook(parent, last_cfg_next); - rd_cfg_insert_child(parent, first_cfg_prev, last_cfg_next); - } - } - } - } - - ////////////////////////// - //- rjf: consume event, if taken - // - if(taken && evt != &dummy_evt) - { - ui_eat_event(evt); - } - } - if(take_autocomplete) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - ui_eat_event(evt); - break; - } - } - } - } - - ////////////////////////////// - //- rjf: build ui - // - B32 pressed = 0; - ProfScope("build ui") - { - Vec2F32 rect_dim = dim_2f32(rect); - F32 contents_width_px = (rect_dim.x - floor_f32(ui_bottom_font_size()*1.5f)); - Rng1S64 visible_row_rng = {0}; - UI_ScrollListParams scroll_list_params = {0}; - { - scroll_list_params.flags = UI_ScrollListFlag_All; - scroll_list_params.row_height_px = row_height_px; - scroll_list_params.dim_px = rect_dim; - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, 0)); - scroll_list_params.item_range = r1s64(0, block_tree.total_row_count - !!implicit_root); - scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; - scroll_list_params.row_blocks = row_blocks; - } - UI_BoxFlags disabled_flags = ui_top_flags(); - if(d_ctrl_targets_running()) - { - disabled_flags |= UI_BoxFlag_Disabled; - } - UI_ScrollListSignal scroll_list_sig = {0}; - UI_Focus(UI_FocusKind_On) - UI_ScrollList(&scroll_list_params, &scroll_pos.y, - 0, - 0, - &visible_row_rng, - &scroll_list_sig) - UI_Focus(UI_FocusKind_Null) - { - ui_set_next_pref_height(ui_children_sum(1)); - ui_set_next_child_layout_axis(Axis2_Y); - UI_Box *table = ui_build_box_from_string(0, str8_lit("table")); - UI_Parent(table) - { - Vec2F32 scroll_list_view_off_px = ui_top_parent()->parent->view_off; - - //////////////////////// - //- rjf: viz blocks -> rows - // - EV_WindowedRowList rows = {0}; - { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); - } - - //////////////////////// - //- rjf: rows -> row infos - // - RD_WatchRowInfo *row_infos = push_array(scratch.arena, RD_WatchRowInfo, rows.count); - { - U64 idx = 0; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) - { - EV_Row *row = &row_node->row; - row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); - } - } - - //////////////////////// - //- rjf: build boundaries - // - B32 cell_pcts_are_dirty = 0; - ProfScope("build boundaries") - { - U64 idx = 0; - U64 boundary_start_idx = 0; - EV_Row *last_row = 0; - RD_WatchRowInfo *last_row_info = 0; - for(EV_WindowedRowNode *row_node = rows.first;; row_node = row_node->next, idx += 1) - { - //- rjf: determine if this row breaks the topology - B32 is_new_topology = (row_node == 0); - if(row_node != 0 && last_row_info != 0) - { - EV_Row *row = &row_node->row; - RD_WatchRowInfo *row_info = &row_infos[idx]; - for(RD_WatchCell *last_cell = last_row_info->cells.first, *this_cell = row_info->cells.first;; - last_cell = last_cell->next, this_cell = this_cell->next) - { - if(last_cell == 0 && this_cell == 0) - { - break; - } - if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) - { - is_new_topology = 1; - break; - } - if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) - { - is_new_topology = 1; - break; - } - } - } - - //- rjf: if we reached a new topology, or the end -> build boundaries for all cell separations - if(is_new_topology) - { - EV_Row *row = last_row; - RD_WatchRowInfo *row_info = last_row_info; - F32 row_width_px = contents_width_px; - if(row_info != 0) - { - U64 row_hash = ev_hash_from_key(row->key); + + ////////////// + //- rjf: build all cells + // + S64 cell_x = 0; F32 cell_x_px = 0; - U64 cell_idx = 0; - for(RD_WatchCell *cell = row_info->cells.first; cell != 0 && cell->next != 0; cell = cell->next, cell_idx += 1) + for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) { - if(cell->pct == 0 || cell->next->pct == 0) - { - continue; - } + //////////// + //- rjf: unpack cell info + // U64 cell_id = rd_id_from_watch_cell(cell); - F32 cell_width_px = cell->px + cell->pct * row_width_px; + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); + E_TypeKey cell_type_key = cell->eval.irtree.type_key; + E_Type *cell_type = e_type_from_key__cached(cell_type_key); + E_Eval cell_value_eval = e_value_eval_from_eval(cell->eval); + F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; - { - Rng2F32 rect = r2f32p(next_cell_x_px - ui_top_font_size()*0.4f, - boundary_start_idx*row_height_px, - next_cell_x_px + ui_top_font_size()*0.4f, - idx*row_height_px); - UI_Rect(rect) UI_HoverCursor(OS_Cursor_LeftRight) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Floating, "boundary_%I64x_%I64x", row_hash, cell_id); - UI_Signal sig = ui_signal_from_box(box); - if(ui_dragging(sig)) - { - typedef struct DragData DragData; - struct DragData - { - F32 min_pct; - F32 max_pct; - }; - if(ui_pressed(sig)) - { - DragData drag_data = {cell->pct, cell->next->pct}; - ui_store_drag_struct(&drag_data); - } - DragData *drag_data = ui_get_drag_struct(DragData); - F32 min_pct__pre = drag_data->min_pct; - F32 max_pct__pre = drag_data->max_pct; - F32 min_px__pre = min_pct__pre*row_width_px; - F32 max_px__pre = max_pct__pre*row_width_px; - F32 min_px__post = min_px__pre + ui_drag_delta().x; - F32 max_px__post = max_px__pre - ui_drag_delta().x; - F32 min_pct__post = min_px__post/row_width_px; - F32 max_pct__post = max_px__post/row_width_px; - if(min_pct__post < 0.05f) - { - min_pct__post = 0.05f; - max_pct__post = (min_pct__pre + max_pct__pre) - min_pct__post; - } - if(max_pct__post < 0.05f) - { - max_pct__post = 0.05f; - min_pct__post = (min_pct__pre + max_pct__pre) - max_pct__post; - } - if(ui_double_clicked(sig)) - { - F32 default_sum = cell->default_pct + cell->next->default_pct; - F32 current_sum = min_pct__pre + max_pct__pre;; - min_pct__post = current_sum * (cell->default_pct / default_sum); - max_pct__post = current_sum * (cell->next->default_pct / default_sum); - ui_kill_action(); - } - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *style = rd_cfg_child_from_string_or_alloc(view, row_info->cell_style_key); - RD_Cfg *min_cfg = &rd_nil_cfg; - RD_Cfg *max_cfg = &rd_nil_cfg; - { - RD_Cfg *pct_child = style->first; - U64 c_idx = 0; - for(RD_WatchCell *c = row_info->cells.first; c != 0; c = c->next, c_idx += 1) - { - if(pct_child == &rd_nil_cfg) - { - pct_child = rd_cfg_newf(style, "%f", c->pct); - } - if(c_idx == cell_idx) - { - min_cfg = pct_child; - } - if(c_idx == cell_idx+1) - { - max_cfg = pct_child; - } - pct_child = pct_child->next; - } - rd_cfg_equip_stringf(min_cfg, "%f", min_pct__post); - rd_cfg_equip_stringf(max_cfg, "%f", max_pct__post); - cell_pcts_are_dirty = 1; - } - } - } - } - cell_x_px = next_cell_x_px; - } - } - boundary_start_idx = idx; - } - - //- rjf: advance - if(row_node == 0) - { - break; - } - else - { - last_row = &row_node->row; - last_row_info = &row_infos[idx]; - } - } - } - - //////////////////////// - //- rjf: if cell widths are dirty -> recompute row infos - // - if(cell_pcts_are_dirty) - { - U64 idx = 0; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, idx += 1) - { - EV_Row *row = &row_node->row; - row_infos[idx] = rd_watch_row_info_from_row(scratch.arena, row); - } - } - - //////////////////////// - //- rjf: build table - // - ProfScope("build table") - { - U64 local_row_idx = 0; - U64 global_row_idx = rows.count_before_semantic; - RD_WatchRowInfo last_row_info = {0}; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) - { - //////////////////////// - //- rjf: unpack row info - // - ProfBegin("unpack row info"); - EV_Row *row = &row_node->row; - RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; - U64 row_hash = ev_hash_from_key(row->key); - U64 row_depth = ev_depth_from_block(row->block); - B32 row_selected = (selection_tbl.min.y <= global_row_idx+1 && global_row_idx+1 <= selection_tbl.max.y); - B32 row_expanded = ev_expansion_from_key(eval_view, row->key); - B32 next_row_expanded = row_expanded; - B32 row_is_expandable = row_info->can_expand; - if(implicit_root && row_depth > 0) - { - row_depth -= 1; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine if this row fits the last row's topology - // - B32 row_matches_last_row_topology = 1; - if(row_node != rows.first) - { - for(RD_WatchCell *last_cell = last_row_info.cells.first, *this_cell = row_info->cells.first;; - last_cell = last_cell->next, this_cell = this_cell->next) - { - if(last_cell == 0 && this_cell == 0) - { - break; - } - if((last_cell == 0 && this_cell != 0) || (last_cell != 0 && this_cell == 0)) - { - row_matches_last_row_topology = 0; - break; - } - if(rd_id_from_watch_cell(last_cell) != rd_id_from_watch_cell(this_cell)) - { - row_matches_last_row_topology = 0; - break; - } - } - } - - //////////////////////// - //- rjf: store last row's info, for next iteration - // - last_row_info = *row_info; - - //////////////////////// - //- rjf: determine if row's data is fresh and/or bad - // - ProfBegin("determine if row's data is fresh and/or bad"); - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row->eval.irtree.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); - if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - {row_is_bad = 1; - } - } - } - }break; - } - ProfEnd(); - - //////////////////////// - //- rjf: determine row's flags & color palette - // - ProfBegin("determine row's flags & color palette"); - UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; - { - if(row_is_fresh) - { - ui_set_next_tag(str8_lit("fresh")); - row_flags |= UI_BoxFlag_DrawBackground; - } - else if(global_row_idx & 1) - { - ui_set_next_tag(str8_lit("alt")); - row_flags |= UI_BoxFlag_DrawBackground; - } - if(!row_matches_last_row_topology) - { - row_flags |= UI_BoxFlag_DrawSideTop; - } - } - ProfEnd(); - - //////////////////////// - //- rjf: build row box - // - ui_set_next_flags(disabled_flags); - ui_set_next_pref_width(ui_px(contents_width_px, 1.f)); - ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); - ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); - UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); - RD_WatchRowExtrasDrawData *row_draw_data = push_array(ui_build_arena(), RD_WatchRowExtrasDrawData, 1); - row_draw_data->breaks_from_prev = !row_matches_last_row_topology; - ui_box_equip_custom_draw(row_box, rd_watch_row_extras_custom_draw, row_draw_data); - - ////////////////////// - //- rjf: build row contents - // - RD_RegsScope(.module = row_info->module->handle) UI_Parent(row_box) - { - //////////////////// - //- rjf: draw start of cache lines in expansions - // - if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); - if(space_entity->kind == CTRL_EntityKind_Process) - { - U64 row_offset = row->eval.value.u64; - if((row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && - row_offset%64 == 0 && row_depth > 0) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(0); - ui_set_next_fixed_height(ui_top_font_size()*0.2f); - ui_set_next_tag(str8_lit("pop")); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - - ////////////// - //- rjf: draw mid-row cache line boundaries in expansions - // - if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->view_ui_rule == &rd_nil_view_ui_rule) - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); - if(space_entity->kind == CTRL_EntityKind_Process && - (row->eval.irtree.mode == E_Mode_Offset || row->eval.irtree.mode == E_Mode_Null) && - row->eval.value.u64%64 != 0 && - row_depth > 0 && - !row_expanded) - { - U64 next_off = (row->eval.value.u64 + e_type_byte_size_from_key(row->eval.irtree.type_key)); - if(next_off%64 != 0 && row->eval.value.u64/64 < next_off/64) - { - ui_set_next_fixed_x(0); - ui_set_next_fixed_y(row_height_px - ui_top_font_size()*0.5f); - ui_set_next_fixed_height(ui_top_font_size()*1.f); - ui_set_next_tag(str8_lit("pop")); - ui_set_next_transparency(0.5f); - ui_build_box_from_key(UI_BoxFlag_Floating|UI_BoxFlag_DrawBackground, ui_key_zero()); - } - } - } - - ////////////// - //- rjf: build all cells - // - S64 cell_x = 0; - F32 cell_x_px = 0; - for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) - { - //////////// - //- rjf: unpack cell info - // - U64 cell_id = rd_id_from_watch_cell(cell); - RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - E_TypeKey cell_type_key = cell_info.eval.irtree.type_key; - E_Type *cell_type = e_type_from_key__cached(cell_type_key); - E_Eval cell_value_eval = e_value_eval_from_eval(cell_info.eval); - F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); - F32 next_cell_x_px = cell_x_px + cell_width_px; - B32 cell_toggled = (cell_value_eval.value.u64 != 0); - B32 next_cell_toggled = cell_toggled; - - //////////// - //- rjf: compute slider parameters - // - E_Value cell_slider_min = zero_struct; - E_Value cell_slider_max = zero_struct; - E_TypeKind slider_value_type_kind = E_TypeKind_Null; - F32 cell_slider_value = 0.f; - if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2) - { - E_Expr *min_expr = cell_type->args[0]; - E_Expr *max_expr = cell_type->args[1]; - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &cell_info.eval.irtree; - { - E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); - slider_value_type_kind = e_type_kind_from_key(slider_value_type); - E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); - E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); - cell_slider_min = e_value_from_expr(min_casted); - cell_slider_max = e_value_from_expr(max_casted); - } - e_ir_state->overridden_irtree = prev_overridden_irtree; - } - switch(slider_value_type_kind) - { - default: - if(e_type_kind_is_integer(slider_value_type_kind)) - { - cell_slider_value = ((F32)(cell_value_eval.value.s64 - cell_slider_min.s64)) / (cell_slider_max.s64 - cell_slider_min.s64); - }break; - case E_TypeKind_F32: - { - cell_slider_value = (cell_value_eval.value.f32 - cell_slider_min.f32) / (cell_slider_max.f32 - cell_slider_min.f32); - }break; - case E_TypeKind_F64: - { - cell_slider_value = (F32)((cell_value_eval.value.f64 - cell_slider_min.f64) / (cell_slider_max.f64 - cell_slider_min.f64)); - }break; - } - F32 next_cell_slider_value = cell_slider_value; - - //////////// - //- rjf: determine cell's palette - // - UI_BoxFlags cell_flags = 0; - Vec4F32 cell_background_color_override = {0}; - String8 cell_tag = {0}; - { - if(cell_info.cfg->id == rd_get_hover_regs()->cfg && - rd_state->hover_regs_slot == RD_RegSlot_Cfg) - { - RD_Cfg *cfg = cell_info.cfg; - Vec4F32 rgba = rd_color_from_cfg(cfg); - rgba.w *= 0.05f; - if(rgba.w == 0) - { - rgba = pop_background_rgba; - rgba.w *= 0.5f; - } - rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); - cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; - } - else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && - rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) - { - CTRL_Entity *entity = cell_info.entity; - Vec4F32 rgba = rd_color_from_ctrl_entity(entity); - rgba.w *= 0.05f; - if(rgba.w == 0) - { - rgba = pop_background_rgba; - rgba.w *= 0.5f; - } - rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); - cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; - } - } - - //////////// - //- rjf: build cell container - // - UI_Box *cell_box = &ui_nil_box; - UI_PrefWidth(ui_px(cell_width_px, 0.f)) - { - ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); - cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); - } - - //////////// - //- rjf: build cell contents - // - UI_Signal sig = {0}; - ProfScope("build cell contents") - UI_Parent(cell_box) - UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) - UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) - RD_Font(RD_FontSlot_Code) - UI_TagF("weak") - UI_Tag(cell_tag) - { - //- rjf: cell has errors? -> build error box - if(cell_info.flags & RD_WatchCellFlag_IsErrored) RD_Font(RD_FontSlot_Main) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); - sig = ui_signal_from_box(box); - UI_Parent(box) UI_Flags(0) - { - rd_error_label(cell_info.string); - } - } + B32 cell_toggled = (cell_value_eval.value.u64 != 0); + B32 next_cell_toggled = cell_toggled; - //- rjf: cell has hook? -> build ui by calling hook - else if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + //////////// + //- rjf: compute slider parameters + // + E_Value cell_slider_min = zero_struct; + E_Value cell_slider_max = zero_struct; + E_TypeKind slider_value_type_kind = E_TypeKind_Null; + F32 cell_slider_value = 0.f; + if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2) { - RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); - RD_Cfg *view = rd_view_from_eval(root, cell_info.eval); - Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); - ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); - ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); - UI_Parent(box) - RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval)) - UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) - UI_Flags(0) + E_Expr *min_expr = cell_type->args[0]; + E_Expr *max_expr = cell_type->args[1]; + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &cell->eval.irtree; { - // rjf: 'pull out' button - UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) - UI_CornerRadius(ui_top_font_size()*1.5f) - UI_TextAlignment(UI_TextAlign_Center) - RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()*0.8f) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| - UI_BoxFlag_Floating| - UI_BoxFlag_DrawText| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_DrawHotEffects, - "%S###pull_out", - rd_icon_kind_text_table[RD_IconKind_Window]); - UI_Signal sig = ui_signal_from_box(box); - if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) - { - rd_drag_begin(RD_RegSlot_View); - } - } - - // rjf: loading animation container - UI_Box *loading_overlay_container = &ui_nil_box; - UI_Parent(box) UI_WidthFill UI_HeightFill - { - loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); - } - - // rjf: view ui contents - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = cell_info.eval.irtree.prev; - cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; - - // rjf: loading fill - UI_Parent(loading_overlay_container) - { - RD_ViewState *vs = rd_view_state_from_cfg(view); - rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); - } + E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); + slider_value_type_kind = e_type_kind_from_key(slider_value_type); + E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); + E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); + cell_slider_min = e_value_from_expr(min_casted); + cell_slider_max = e_value_from_expr(max_casted); } - sig = ui_signal_from_box(box); + e_ir_state->overridden_irtree = prev_overridden_irtree; } - - //- rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty - else if(cell->kind == RD_WatchCellKind_CallStackFrame) - { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); - sig = ui_signal_from_box(box); - if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && - row_info->callstack_unwind_index == rd_base_regs()->unwind_count && - row_info->callstack_inline_depth == rd_base_regs()->inline_depth) - { - UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) - { - Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); - RD_Font(RD_FontSlot_Icons) - UI_Flags(UI_BoxFlag_DisableTextTrunc) - UI_TextColor(color) - ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); - } - } - } - - //- rjf: build general cell - else - { - // rjf: compute visual params - B32 fancy_editors_in_expr = (row_info->cells.count == 1); - B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); - B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); - B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); - B32 is_toggle_switch = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Bool); - B32 is_slider = (cell_has_fancy_editors && cell_info.eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Lens && str8_match(cell_type->name, str8_lit("range1"), 0)); - B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); - B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); - String8 ghost_text = {0}; - if(cell->kind == RD_WatchCellKind_Expr && cell_info.string.size == 0) - { - ghost_text = str8_lit("Expression"); - is_non_code = !cell_selected || !ewv->text_editing; - } - else if(cell->kind == RD_WatchCellKind_Tag && cell_info.string.size == 0 && global_row_idx == 0) - { - ghost_text = str8_lit("View Rules"); - is_non_code = !cell_selected || !ewv->text_editing; - } - if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) - { - is_non_code = 0; - is_button = 0; - is_activated_on_single_click = 0; - } - String8 searched_string = cell_info.string; - if(cell_info.fstrs.node_count != 0) - { - searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); - } - String8 search_query = rd_view_query_input(); - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); - if(fuzzy_matches.count == 0) - { - String8 path_needle = str8_skip_last_slash(search_query); - if(0 < path_needle.size && path_needle.size < search_query.size) - { - fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); - } - } - - // rjf: form cell build parameters - RD_CellParams cell_params = {0}; - { - // rjf: set up base parameters - cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); - cell_params.depth = (cell->flags & RD_WatchCellFlag_Indented ? row_depth : 0); - cell_params.cursor = &cell_edit_state->cursor; - cell_params.mark = &cell_edit_state->mark; - cell_params.edit_buffer = cell_edit_state->input_buffer; - cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); - cell_params.edit_string_size_out = &cell_edit_state->input_size; - cell_params.expanded_out = &next_row_expanded; - cell_params.pre_edit_value = cell_info.string; - cell_params.fstrs = cell_info.fstrs; - cell_params.fuzzy_matches = &fuzzy_matches; - - // rjf: apply expander (or substitute space) - if(row_is_expandable && cell == row_info->cells.first) - { - cell_params.flags |= RD_CellFlag_Expander; - } - else if(row_depth == !implicit_root && cell == row_info->cells.first) - { - cell_params.flags |= RD_CellFlag_ExpanderSpace; - } - else if(row_depth != 0 && cell == row_info->cells.first) - { - cell_params.flags |= RD_CellFlag_ExpanderSpace; - } - - // rjf: apply single-click-activation - if(is_activated_on_single_click) - { - cell_params.flags |= RD_CellFlag_SingleClickActivate; - } - - // rjf: apply code styles - if(is_non_code) - { - cell_params.flags &= ~RD_CellFlag_CodeContents; - } - - // rjf: apply button styles - if(is_button) - { - cell_params.flags |= RD_CellFlag_Button; - cell_params.flags &= ~RD_CellFlag_NoBackground; - if(row_depth == 0) - { - cell_params.flags &= ~RD_CellFlag_ExpanderSpace; - } - } - - // rjf: apply background - if(has_background) - { - cell_params.flags &= ~RD_CellFlag_NoBackground; - } - - // rjf: apply toggle-switch - if(is_toggle_switch) - { - cell_params.flags |= RD_CellFlag_ToggleSwitch; - cell_params.toggled_out = &next_cell_toggled; - } - - // rjf: apply slider - if(is_slider) - { - cell_params.flags |= RD_CellFlag_Slider; - cell_params.slider_value_out = &next_cell_slider_value; - } - } - - // rjf: build - if(cell_background_color_override.w != 0) - { - ui_push_background_color(cell_background_color_override); - } - UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) - RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) - { - sig = rd_cellf(&cell_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); - } - if(cell_background_color_override.w != 0) - { - ui_pop_background_color(); - } -#if 0 // TODO(rjf): @cfg (autocompletion) - if(ui_is_focus_active() && - selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && - txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) - { - String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); - } -#endif - } - } - - //////////// - //- rjf: handle interactions - // - { - // rjf: hover -> rich hover cfgs - if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) - { - RD_RegsScope(.cfg = cell_info.cfg->id, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_Cfg); - } - - // rjf: hover -> rich hover entities - if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) - { - RD_RegsScope(.ctrl_entity = cell_info.entity->handle, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_CtrlEntity); - } - - // rjf: dragging -> drag/drop - if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse()) && - (!cell_selected || !ewv->text_editing)) - { - if(cell_info.eval.space.kind == E_SpaceKind_FileSystem) - { - String8 file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval); - RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); - } - else if(cell_info.cfg != &rd_nil_cfg) - { - RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); - } - else if(cell_info.entity != &ctrl_entity_nil) - { - RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) - { - default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; - case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; - case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; - case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; - case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; - } - } - else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity || - cell_info.eval.space.kind == E_SpaceKind_FileSystem || - cell_info.eval.space.kind == E_SpaceKind_File || - cell_info.eval.space.kind == E_SpaceKind_Null) - { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell_info.eval.expr)) - rd_drag_begin(RD_RegSlot_Expr); - } - } - - // rjf: (normally) single-click -> move selection here - if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - pressed = 1; - } - - // rjf: activation (double-click normally, or single-clicks with special buttons) - if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || - ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig)) || - sig.f & UI_SignalFlag_KeyboardPressed) - { - // rjf: kill if a double-clickable cell - if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) - { - ui_kill_action(); - } - - // rjf: this watch window is a lister? -> move cursor & accept - RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); - if(lister != &rd_nil_cfg) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - rd_cmd(RD_CmdKind_Accept); - } - - // rjf: has a command name? -> push command - else if(cell_info.cmd_name.size != 0) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row->eval.space); - RD_Cfg *cfg = rd_cfg_from_eval_space(row->eval.space); - RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) - { - if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) - { - rd_push_cmd(cell_info.cmd_name, rd_regs()); - } - else - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cell_info.cmd_name); - } - } - } - - // rjf: row has callstack info? -> select unwind - else if(row_info->callstack_thread != &ctrl_entity_nil) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); - rd_cmd(RD_CmdKind_SelectUnwind, - .unwind_count = row_info->callstack_unwind_index, - .inline_depth = row_info->callstack_inline_depth); - } - - // rjf: can edit? -> begin editing - else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) - { - ewv->next_cursor = ewv->next_mark = cell_pt; - rd_cmd(RD_CmdKind_Edit); - } - - // rjf: can expand? -> expand - else if(sig.f & UI_SignalFlag_KeyboardPressed && row_is_expandable) - { - next_row_expanded = !row_expanded; - } - - // rjf: can't edit, but has address info? -> go to address - else if(cell_info.eval.space.kind == RD_EvalSpaceKind_CtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); - CTRL_Entity *process = ctrl_process_from_entity(entity); - if(process != &ctrl_entity_nil) - { - U64 vaddr = cell_info.eval.value.u64; - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } - } - } - - // rjf: can't edit, but has cfg? -> find or select - else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) - { - RD_Cfg *cfg = rd_cfg_from_eval_space(cell_info.eval.space); - RD_Location loc = rd_location_from_cfg(cfg); - if(loc.file_path.size != 0) - { - rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = 0, .file_path = loc.file_path, .cursor = loc.pt); - } - else if(loc.expr.size != 0) - { - U64 value = e_value_from_string(loc.expr).u64; - rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); - } - else if(str8_match(cfg->string, str8_lit("target"), 0) && sig.event_flags & OS_Modifier_Ctrl) - { - rd_cmd(RD_CmdKind_EnableCfg, .cfg = cfg->id); - } - else if(str8_match(cfg->string, str8_lit("target"), 0)) - { - rd_cmd(RD_CmdKind_SelectCfg, .cfg = cfg->id); - } - } - - // rjf: can't edit, but has thread? -> select - else if(cell_info.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell_info.eval.space); - if(entity->kind == CTRL_EntityKind_Thread) - { - rd_cmd(RD_CmdKind_SelectThread, .thread = entity->handle); - } - } - } - - // rjf: hovering with inheritance string -> show tooltip - if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) - { - ui_labelf("Inherited from "); - RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); - } - } - - // rjf: hovering with error tooltip -> show tooltip - if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip - { - UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); - } - } - - //////////// - //- rjf: commit toggle changes - // - if(next_cell_toggled != cell_toggled) - { - rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); - } - - //////////// - //- rjf: commit slider changes - // - if(next_cell_slider_value != cell_slider_value) - { - String8 new_value_string = {0}; switch(slider_value_type_kind) { default: if(e_type_kind_is_integer(slider_value_type_kind)) { - S64 new_value = (S64)((next_cell_slider_value * (cell_slider_max.s64 - cell_slider_min.s64)) + cell_slider_min.s64); - new_value = Clamp(cell_slider_min.s64, new_value, cell_slider_max.s64); - new_value_string = push_str8f(scratch.arena, "%I64d", new_value); + cell_slider_value = ((F32)(cell_value_eval.value.s64 - cell_slider_min.s64)) / (cell_slider_max.s64 - cell_slider_min.s64); }break; case E_TypeKind_F32: { - F32 new_value = (next_cell_slider_value * (cell_slider_max.f32 - cell_slider_min.f32)) + cell_slider_min.f32; - new_value = Clamp(cell_slider_min.f32, new_value, cell_slider_max.f32); - new_value_string = push_str8f(scratch.arena, "%f", new_value); + cell_slider_value = (cell_value_eval.value.f32 - cell_slider_min.f32) / (cell_slider_max.f32 - cell_slider_min.f32); }break; case E_TypeKind_F64: { - F64 new_value = (F64)((next_cell_slider_value * (cell_slider_max.f64 - cell_slider_min.f64)) + cell_slider_min.f64); - new_value = Clamp(cell_slider_min.f64, new_value, cell_slider_max.f64); - new_value_string = push_str8f(scratch.arena, "%f", new_value); + cell_slider_value = (F32)((cell_value_eval.value.f64 - cell_slider_min.f64) / (cell_slider_max.f64 - cell_slider_min.f64)); }break; } - rd_commit_eval_value_string(cell_info.eval, new_value_string); + F32 next_cell_slider_value = cell_slider_value; + + //////////// + //- rjf: determine cell's palette + // + UI_BoxFlags cell_flags = 0; + Vec4F32 cell_background_color_override = {0}; + String8 cell_tag = {0}; + { + if(cell_info.cfg->id == rd_get_hover_regs()->cfg && + rd_state->hover_regs_slot == RD_RegSlot_Cfg) + { + RD_Cfg *cfg = cell_info.cfg; + Vec4F32 rgba = rd_color_from_cfg(cfg); + rgba.w *= 0.05f; + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && + rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) + { + CTRL_Entity *entity = cell_info.entity; + Vec4F32 rgba = rd_color_from_ctrl_entity(entity); + rgba.w *= 0.05f; + if(rgba.w == 0) + { + rgba = pop_background_rgba; + rgba.w *= 0.5f; + } + rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); + cell_background_color_override = rgba; + cell_flags |= UI_BoxFlag_DrawBackground; + } + } + + //////////// + //- rjf: build cell container + // + UI_Box *cell_box = &ui_nil_box; + UI_PrefWidth(ui_px(cell_width_px, 0.f)) + { + ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); + } + + //////////// + //- rjf: build cell contents + // + UI_Signal sig = {0}; + ProfScope("build cell contents") + UI_Parent(cell_box) + UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) + RD_Font(RD_FontSlot_Code) + UI_TagF("weak") + UI_Tag(cell_tag) + { + //- rjf: cell has hook? -> build ui by calling hook + if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + { + RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *view = rd_view_from_eval(root, cell->eval); + Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); + ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); + UI_Parent(box) + RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell->eval)) + UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) + UI_Flags(0) + { + // rjf: 'pull out' button + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f, + ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) + UI_CornerRadius(ui_top_font_size()*1.5f) + UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(ui_top_font_size()*0.8f) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Floating| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects, + "%S###pull_out", + rd_icon_kind_text_table[RD_IconKind_Window]); + UI_Signal sig = ui_signal_from_box(box); + if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) + { + rd_drag_begin(RD_RegSlot_View); + } + } + + // rjf: loading animation container + UI_Box *loading_overlay_container = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_HeightFill + { + loading_overlay_container = ui_build_box_from_key(UI_BoxFlag_FloatingX|UI_BoxFlag_FloatingY, ui_key_zero()); + } + + // rjf: view ui contents + E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = cell->eval.irtree.prev; + cell_info.view_ui_rule->ui(cell->eval, cell_rect); + e_ir_state->overridden_irtree = prev_overridden_irtree; + + // rjf: loading fill + UI_Parent(loading_overlay_container) + { + RD_ViewState *vs = rd_view_state_from_cfg(view); + rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); + } + } + sig = ui_signal_from_box(box); + } + + //- rjf: cell is call stack frame? -> build arrow if this is the selected frame, otherwise leave empty + else if(cell->kind == RD_WatchCellKind_CallStackFrame) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "###%I64x_%I64x", cell_id, row_hash); + sig = ui_signal_from_box(box); + if(ctrl_handle_match(row_info->callstack_thread->handle, rd_base_regs()->thread) && + row_info->callstack_unwind_index == rd_base_regs()->unwind_count && + row_info->callstack_inline_depth == rd_base_regs()->inline_depth) + { + UI_Parent(box) UI_Flags(0) UI_TextAlignment(UI_TextAlign_Center) + { + Vec4F32 color = rd_color_from_ctrl_entity(row_info->callstack_thread); + RD_Font(RD_FontSlot_Icons) + UI_Flags(UI_BoxFlag_DisableTextTrunc) + UI_TextColor(color) + ui_label(rd_icon_kind_text_table[RD_IconKind_RightArrow]); + } + } + } + + //- rjf: build general cell + else + { + // rjf: compute visual params + B32 fancy_editors_in_expr = (row_info->cells.count == 1); + B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); + B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); + B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); + B32 is_toggle_switch = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Bool); + B32 is_slider = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Lens && str8_match(cell_type->name, str8_lit("range1"), 0)); + B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); + B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); + String8 ghost_text = {0}; + if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + { + is_non_code = 0; + is_button = 0; + is_activated_on_single_click = 0; + } + String8 searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + String8 search_query = rd_view_query_input(); + FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); + if(fuzzy_matches.count == 0) + { + String8 path_needle = str8_skip_last_slash(search_query); + if(0 < path_needle.size && path_needle.size < search_query.size) + { + fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); + } + } + + // rjf: form cell build parameters + RD_CellParams cell_params = {0}; + { + // rjf: set up base parameters + cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); + cell_params.depth = (cell->flags & RD_WatchCellFlag_Indented ? row_depth : 0); + cell_params.cursor = &cell_edit_state->cursor; + cell_params.mark = &cell_edit_state->mark; + cell_params.edit_buffer = cell_edit_state->input_buffer; + cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); + cell_params.edit_string_size_out = &cell_edit_state->input_size; + cell_params.expanded_out = &next_row_expanded; + cell_params.pre_edit_value = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + cell_params.fstrs = cell_info.fstrs; + cell_params.fuzzy_matches = &fuzzy_matches; + + // rjf: apply expander (or substitute space) + if(row_is_expandable && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_Expander; + } + else if(row_depth == !implicit_root && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderSpace; + } + else if(row_depth != 0 && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderSpace; + } + + // rjf: apply single-click-activation + if(is_activated_on_single_click) + { + cell_params.flags |= RD_CellFlag_SingleClickActivate; + } + + // rjf: apply code styles + if(is_non_code) + { + cell_params.flags &= ~RD_CellFlag_CodeContents; + } + + // rjf: apply button styles + if(is_button) + { + cell_params.flags |= RD_CellFlag_Button; + cell_params.flags &= ~RD_CellFlag_NoBackground; + if(row_depth == 0) + { + cell_params.flags &= ~RD_CellFlag_ExpanderSpace; + } + } + + // rjf: apply background + if(has_background) + { + cell_params.flags &= ~RD_CellFlag_NoBackground; + } + + // rjf: apply toggle-switch + if(is_toggle_switch) + { + cell_params.flags |= RD_CellFlag_ToggleSwitch; + cell_params.toggled_out = &next_cell_toggled; + } + + // rjf: apply slider + if(is_slider) + { + cell_params.flags |= RD_CellFlag_Slider; + cell_params.slider_value_out = &next_cell_slider_value; + } + } + + // rjf: build + if(cell_background_color_override.w != 0) + { + ui_push_background_color(cell_background_color_override); + } + UI_TextAlignment(cell->px != 0 ? UI_TextAlign_Center : UI_TextAlign_Left) + RD_Font(is_non_code ? RD_FontSlot_Main : RD_FontSlot_Code) + { + sig = rd_cellf(&cell_params, "%S###%I64x_row_%I64x", ghost_text, cell_x, row_hash); + } + if(cell_background_color_override.w != 0) + { + ui_pop_background_color(); + } +#if 0 // TODO(rjf): @cfg (autocompletion) + if(ui_is_focus_active() && + selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && + txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) + { + String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_lister_query(.ui_key = sig.box->key, + .off_px = v2f32(0, dim_2f32(sig.box->rect).y), + .string = input, + .cursor = cell_edit_state->cursor, + .lister_flags = cell_autocomp_flags); + } +#endif + } + } + + //////////// + //- rjf: handle interactions + // + { + // rjf: hover -> rich hover cfgs + if(ui_hovering(sig) && cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_Cfg); + } + + // rjf: hover -> rich hover entities + if(ui_hovering(sig) && cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_CtrlEntity); + } + + // rjf: dragging -> drag/drop + if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse()) && + (!cell_selected || !ewv->text_editing)) + { + if(cell->eval.space.kind == E_SpaceKind_FileSystem) + { + String8 file_path = rd_file_path_from_eval(scratch.arena, cell->eval); + RD_RegsScope(.file_path = file_path) rd_drag_begin(RD_RegSlot_FilePath); + } + else if(cell_info.cfg != &rd_nil_cfg) + { + RD_RegsScope(.cfg = cell_info.cfg->id) rd_drag_begin(RD_RegSlot_Cfg); + } + else if(cell_info.entity != &ctrl_entity_nil) + { + RD_RegsScope(.ctrl_entity = cell_info.entity->handle) switch(cell_info.entity->kind) + { + default:{rd_drag_begin(RD_RegSlot_CtrlEntity);}break; + case CTRL_EntityKind_Machine:{RD_RegsScope(.machine = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Machine);}break; + case CTRL_EntityKind_Process:{RD_RegsScope(.process = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Process);}break; + case CTRL_EntityKind_Module:{RD_RegsScope(.module = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Module);}break; + case CTRL_EntityKind_Thread:{RD_RegsScope(.thread = cell_info.entity->handle) rd_drag_begin(RD_RegSlot_Thread);}break; + } + } + else if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity || + cell->eval.space.kind == E_SpaceKind_FileSystem || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_Null) + { + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell->eval.expr)) + rd_drag_begin(RD_RegSlot_Expr); + } + } + + // rjf: (normally) single-click -> move selection here + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_pressed(sig)) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + + // rjf: activation (double-click normally, or single-clicks with special buttons) + if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || + ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig)) || + sig.f & UI_SignalFlag_KeyboardPressed) + { + // rjf: kill if a double-clickable cell + if(!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick)) + { + ui_kill_action(); + } + + // rjf: this watch window is a lister? -> move cursor & accept + RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); + if(lister != &rd_nil_cfg) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); + } + + // rjf: has a command name? -> push command + else if(cell_info.cmd_name.size != 0) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row->eval.space); + RD_Cfg *cfg = rd_cfg_from_eval_space(row->eval.space); + RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) + { + if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) + { + rd_push_cmd(cell_info.cmd_name, rd_regs()); + } + else + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cell_info.cmd_name); + } + } + } + + // rjf: row has callstack info? -> select unwind + else if(row_info->callstack_thread != &ctrl_entity_nil) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = row_info->callstack_thread->handle); + rd_cmd(RD_CmdKind_SelectUnwind, + .unwind_count = row_info->callstack_unwind_index, + .inline_depth = row_info->callstack_inline_depth); + } + + // rjf: can edit? -> begin editing + else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Edit); + } + + // rjf: can expand? -> expand + else if(sig.f & UI_SignalFlag_KeyboardPressed && row_is_expandable) + { + next_row_expanded = !row_expanded; + } + + // rjf: can't edit, but has address info? -> go to address + else if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(cell->eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + if(process != &ctrl_entity_nil) + { + U64 vaddr = cell->eval.value.u64; + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff); + String8 file_path = {0}; + TxtPt pt = {0}; + if(lines.first != 0) + { + file_path = lines.first->v.file_path; + pt = lines.first->v.pt; + rd_cmd(RD_CmdKind_FindCodeLocation, + .process = process->handle, + .vaddr = vaddr, + .file_path = file_path, + .cursor = pt); + } + } + } + + // rjf: can't edit, but has cfg? -> find or select + else if(cell_info.cfg != &rd_nil_cfg) + { + RD_Cfg *cfg = cell_info.cfg; + RD_Location loc = rd_location_from_cfg(cfg); + if(loc.file_path.size != 0) + { + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = 0, .file_path = loc.file_path, .cursor = loc.pt); + } + else if(loc.expr.size != 0) + { + U64 value = e_value_from_string(loc.expr).u64; + rd_cmd(RD_CmdKind_FindCodeLocation, .vaddr = value); + } + else if(str8_match(cfg->string, str8_lit("target"), 0) && sig.event_flags & OS_Modifier_Ctrl) + { + rd_cmd(RD_CmdKind_EnableCfg, .cfg = cfg->id); + } + else if(str8_match(cfg->string, str8_lit("target"), 0)) + { + rd_cmd(RD_CmdKind_SelectCfg, .cfg = cfg->id); + } + } + + // rjf: can't edit, but has thread? -> select + else if(cell_info.entity->kind == CTRL_EntityKind_Thread) + { + rd_cmd(RD_CmdKind_SelectThread, .thread = cell_info.entity->handle); + } + } + + // rjf: hovering with inheritance string -> show tooltip + if(ui_hovering(sig) && cell_info.inheritance_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) + { + ui_labelf("Inherited from "); + RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, ui_color_from_name(str8_lit("code_default")), cell_info.inheritance_tooltip); + } + } + + // rjf: hovering with error tooltip -> show tooltip + if(ui_hovering(sig) && cell_info.error_tooltip.size != 0) UI_Tooltip + { + UI_PrefWidth(ui_children_sum(1)) rd_error_label(cell_info.error_tooltip); + } + } + + //////////// + //- rjf: commit toggle changes + // + if(next_cell_toggled != cell_toggled) + { + rd_commit_eval_value_string(cell->eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); + } + + //////////// + //- rjf: commit slider changes + // + if(next_cell_slider_value != cell_slider_value) + { + String8 new_value_string = {0}; + switch(slider_value_type_kind) + { + default: + if(e_type_kind_is_integer(slider_value_type_kind)) + { + S64 new_value = (S64)((next_cell_slider_value * (cell_slider_max.s64 - cell_slider_min.s64)) + cell_slider_min.s64); + new_value = Clamp(cell_slider_min.s64, new_value, cell_slider_max.s64); + new_value_string = push_str8f(scratch.arena, "%I64d", new_value); + }break; + case E_TypeKind_F32: + { + F32 new_value = (next_cell_slider_value * (cell_slider_max.f32 - cell_slider_min.f32)) + cell_slider_min.f32; + new_value = Clamp(cell_slider_min.f32, new_value, cell_slider_max.f32); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + case E_TypeKind_F64: + { + F64 new_value = (F64)((next_cell_slider_value * (cell_slider_max.f64 - cell_slider_min.f64)) + cell_slider_min.f64); + new_value = Clamp(cell_slider_min.f64, new_value, cell_slider_max.f64); + new_value_string = push_str8f(scratch.arena, "%f", new_value); + }break; + } + rd_commit_eval_value_string(cell->eval, new_value_string); + } + + //////////// + //- rjf: bump x pixel coordinate + // + cell_x_px = next_cell_x_px; } - - //////////// - //- rjf: bump x pixel coordinate - // - cell_x_px = next_cell_x_px; } - } - - ////////////////////// - //- rjf: commit expansion state changes - // - if(next_row_expanded != row_expanded) - { - if(!ev_key_match(ev_key_root(), row->key)) + + ////////////////////// + //- rjf: commit expansion state changes + // + if(next_row_expanded != row_expanded) { - ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + if(!ev_key_match(ev_key_root(), row->key)) + { + ev_key_set_expansion(eval_view, row->block->key, row->key, next_row_expanded); + } } } } } } } + + ////////////////////////////// + //- rjf: general table-wide press logic + // + if(pressed) + { + rd_cmd(RD_CmdKind_FocusPanel); + } + + rd_store_view_scroll_pos(scroll_pos); } - - ////////////////////////////// - //- rjf: general table-wide press logic - // - if(pressed) - { - rd_cmd(RD_CmdKind_FocusPanel); - } - - rd_store_view_scroll_pos(scroll_pos); scratch_end(scratch); } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index ff27f9a4..13dcd009 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -899,6 +899,10 @@ internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); 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); +//- rjf: command name <-> eval space +internal String8 rd_cmd_name_from_eval_space(E_Space space); +internal E_Space rd_eval_space_from_cmd_name(String8 cmd_name); + //- rjf: eval space reads/writes internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0af75efc..20a57007 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1113,7 +1113,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) { E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); } e_ir_state->overridden_irtree = prev_overridden_irtree; info.can_expand = 0; @@ -1129,11 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - DR_FStrList fstrs = rd_title_fstrs_from_file_path(arena, file_path); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, - .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, - .pct = 1.f, - .fstrs = fstrs); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1147,8 +1143,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } } @@ -1156,29 +1152,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: @watch_row_build_cells unattached processes // - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess && + str8_match(row_type->name, str8_lit("unattached_process"), 0)) { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); - if(str8_match(type->name, str8_lit("unattached_process"), 0)) - { - U64 pid = row->eval.value.u128.u64[0]; - String8 name = e_string_from_id(row->eval.value.u128.u64[1]); - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - DR_FStrList fstrs = {0}; - UI_TagF("weak") - { - dr_fstrs_push_new(arena, &fstrs, ¶ms, - rd_icon_kind_text_table[RD_IconKind_Scheduler], - .font = rd_font_from_slot(RD_FontSlot_Icons), - .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), - .color = ui_color_from_name(str8_lit("text"))); - } - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); - dr_fstrs_push_new(arena, &fstrs, ¶ms, name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = fstrs); - } + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1187,7 +1164,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1196,7 +1173,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f, .fstrs = rd_title_fstrs_from_cfg(arena, cfg)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1244,14 +1221,18 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_Background, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .flags = RD_WatchCellFlag_Background, .px = floor_f32(ui_top_font_size()*6.f), .string = str8_lit("($expr).enabled")); } else if(cmd_kind != RD_CmdKind_Null) { String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, + .px = floor_f32(ui_top_font_size()*4.f), + .string = push_str8f(arena, "query:commands.%S", cmd_name)); } } } @@ -1263,14 +1244,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f, .fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, + .pct = 1.f); if(entity->kind == CTRL_EntityKind_Machine || entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).active")); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "active"), + .px = floor_f32(ui_top_font_size()*6.f)); } if(entity->kind == CTRL_EntityKind_Thread) { @@ -1280,7 +1262,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) cmd_kind = RD_CmdKind_DeselectEntity; } String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f), .string = push_str8f(arena, "query:commands.%S", cmd_name)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, + .px = floor_f32(ui_top_font_size()*4.f)); } } @@ -1289,7 +1273,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1300,13 +1284,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } else { - String8 cmd_name = e_string_from_id(e_value_eval_from_eval(row->eval).value.u64); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f, .fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string)); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, + .pct = 1.f); } } @@ -1315,7 +1299,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(info.view_ui_rule != &rd_nil_view_ui_rule) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewUI, row->eval, .pct = 1.f); } //////////////////////////// @@ -1323,7 +1307,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1334,7 +1318,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1356,8 +1340,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1372,8 +1356,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((U64)($expr))"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1396,11 +1380,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("lens:hex((uint64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .string = str8_lit(" "), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct @@ -1417,9 +1400,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof(raw($expr))"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1433,11 +1416,259 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { - RD_WatchRowCellInfo result = {0}; + RD_WatchRowCellInfo result = + { + .flags = cell->flags, + .view_ui_rule = &rd_nil_view_ui_rule, + .cfg = &rd_nil_cfg, + .entity = &ctrl_entity_nil, + }; + ////////////////////////////// + //- rjf: unpack evaluation + // + E_Type *cell_type = e_type_from_key__cached(cell->eval.irtree.type_key); + if(cell->eval.space.u64s[1] == 0) + { + result.cfg = rd_cfg_from_eval_space(cell->eval.space); + } + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && cell->eval.space.u64s[2] == 0) + { + result.entity = rd_ctrl_entity_from_eval_space(cell->eval.space); + } + result.cmd_name = rd_cmd_name_from_eval_space(cell->eval.space); + if(cell->eval.space.kind == E_SpaceKind_FileSystem) + { + result.file_path = e_string_from_id(cell->eval.space.u64_0); + } + for(E_Type *type = cell_type; + type->kind == E_TypeKind_Lens; + type = e_type_from_key__cached(type->direct_type_key)) + { + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(type->name); + if(view_ui_rule != &rd_nil_view_ui_rule) + { + result.view_ui_rule = view_ui_rule; + break; + } + } + + ////////////////////////////// + //- rjf: build cell's visual appearance info + // + switch(cell->eval.space.kind) + { + //- rjf: default case: depending on cell info, generate string + default: + { + //- rjf: cfg evaluation -> button for cfg + if(result.cfg != &rd_nil_cfg) + { + result.fstrs = rd_title_fstrs_from_cfg(arena, result.cfg); + result.flags |= RD_WatchCellFlag_Button; + } + + //- rjf: entity evaluation -> button for entity + else if(result.entity != &ctrl_entity_nil) + { + result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, result.entity, 1); + result.flags |= RD_WatchCellFlag_Button; + } + + //- rjf: buttons -> button for command + else if(result.cmd_name.size != 0) + { + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(result.cmd_name); + result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string); + result.flags |= RD_WatchCellFlag_Button; + } + + //- rjf: files -> button for file + else if(result.file_path.size != 0) + { + String8 file_path = e_string_from_id(cell->eval.value.u64); + result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.flags |= RD_WatchCellFlag_Button; + } + + //- rjf: expression cell -> need to form "left-hand-side", or "meta" string, for some evaluation + else if(cell->kind == RD_WatchCellKind_Expr) + { + // rjf: funnel-through this cell's string, if it has one + B32 is_non_code = 0; + String8 expr_string = cell->string; + + // rjf: if this cell has no string specified, then we need to synthesize one from the evaluation + if(expr_string.size == 0) + { + // rjf: first, locate a notable expression - we special-case things like member accesses + // or array indices, so we should grab those if possible + E_Expr *notable_expr = cell->eval.expr; + for(B32 good = 0; !good;) + { + switch(notable_expr->kind) + { + default:{good = 1;}break; + case E_ExprKind_Address: + case E_ExprKind_Deref: + case E_ExprKind_Cast: + { + notable_expr = notable_expr->last; + }break; + case E_ExprKind_Ref: + { + notable_expr = notable_expr->ref; + }break; + } + } + + // rjf: generate expression string based on our notable expression + switch(notable_expr->kind) + { + // rjf: default case -> just walk the expression tree & generate a string + default: + { + expr_string = e_string_from_expr(arena, notable_expr); + }break; + + // rjf: array indices -> fast path to [index] + case E_ExprKind_ArrayIndex: + { + expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); + }break; + + // rjf: member accesses -> fast-path to .name + case E_ExprKind_MemberAccess: + { + Temp scratch = scratch_begin(&arena, 1); + + // TODO(rjf): @cfg need to build inheritance tooltips +#if 0 + if(member.inheritance_key_chain.count != 0) + { + String8List strings = {0}; + for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) + { + String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); + str8_list_push(scratch.arena, &strings, base_class_name); + } + result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); + } +#endif + + // rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map + // to see if we have a fancy display string for this member. otherwise, we will just + // do a code-string of ".member_name" + String8 member_name = notable_expr->first->next->string; + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem) + { + String8 fancy_name = rd_display_from_code_name(member_name); + if(fancy_name.size != 0) + { + expr_string = fancy_name; + is_non_code = 1; + } + } + if(expr_string.size == 0) + { + expr_string = push_str8f(arena, ".%S", member_name); + } + scratch_end(scratch); + }break; + } + } + + // rjf: use expression string / params to generate fancy strings + if(is_non_code) + { + UI_TagF("weak") + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, expr_string); + } + } + else + { + result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); + } + } + + //- rjf: evaluation -> need to form value string + else if(cell->kind == RD_WatchCellKind_Eval) + { + // rjf: determine string generation parameters based on evaluation + EV_StringParams string_params = {string_flags, 10}; + { + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + string_params.flags |= EV_StringFlag_DisableStringQuotes|EV_StringFlag_DisableAddresses; + } + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Module) + { + string_params.radix = 16; + } + if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && + rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Thread) + { + string_params.radix = 16; + } + } + + // rjf: determine if code + B32 is_code = 1; + { + E_Type *type = e_type_from_key__cached(cell->eval.irtree.type_key); + if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) + { + is_code = 0; + } + } + + // rjf: generate string based on that expression & fill + String8 string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, cell->eval); + if(is_code) + { + result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); + } + else UI_TagF("weak") + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, string); + } + } + }break; + + //- rjf: unattached processes + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = cell->eval.value.u128.u64[0]; + String8 name = e_string_from_id(cell->eval.value.u128.u64[1]); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Scheduler], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + result.fstrs = fstrs; + }break; + } + +#if 0 //- rjf: fill basics/defaults result.view_ui_rule = &rd_nil_view_ui_rule; - result.fstrs = cell->fstrs; result.flags = cell->flags; result.cfg = &rd_nil_cfg; result.entity = &ctrl_entity_nil; @@ -1737,6 +1968,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } }break; } +#endif return result; } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index e4070b6f..c08d2dcb 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -44,7 +44,6 @@ struct RD_CodeViewBuildResult typedef enum RD_WatchCellKind { RD_WatchCellKind_Expr, // strings to represent expression itself - RD_WatchCellKind_Tag, // strings to represent attached tags at row-granularity RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook RD_WatchCellKind_CallStackFrame, // a slot for a yellow arrow, to show call stack frame selection @@ -72,7 +71,6 @@ struct RD_WatchCell U64 index; String8 string; E_Eval eval; - DR_FStrList fstrs; F32 default_pct; F32 pct; F32 px; @@ -109,11 +107,10 @@ typedef struct RD_WatchRowCellInfo RD_WatchRowCellInfo; struct RD_WatchRowCellInfo { RD_WatchCellFlags flags; - E_Eval eval; RD_Cfg *cfg; CTRL_Entity *entity; String8 cmd_name; - String8 string; + String8 file_path; DR_FStrList fstrs; String8 error_tooltip; String8 inheritance_tooltip; @@ -220,7 +217,7 @@ internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewStat internal U64 rd_id_from_watch_cell(RD_WatchCell *cell); internal RD_WatchCell *rd_watch_cell_list_push(Arena *arena, RD_WatchCellList *list); internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellList *list, RD_WatchCell *params); -#define rd_watch_cell_list_push_new(arena, list, kind_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), __VA_ARGS__}) +#define rd_watch_cell_list_push_new(arena, list, kind_, eval_, ...) rd_watch_cell_list_push_new_((arena), (list), &(RD_WatchCell){.kind = (kind_), .eval = (eval_), __VA_ARGS__}) //- rjf: watch view points <-> table coordinates internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b); From dc151609ad0bce02639c67350c3ebf9ad49677bc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 18 Apr 2025 21:21:46 -0700 Subject: [PATCH 400/755] fix files/cmds fancy string list build --- src/raddbg/raddbg_core.c | 14 +++----------- src/raddbg/raddbg_core.h | 3 +-- src/raddbg/raddbg_views.c | 15 ++++++--------- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4ec0d08d..7e0b511b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1505,24 +1505,16 @@ rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind) //- rjf: command name <-> eval space internal String8 -rd_cmd_name_from_eval_space(E_Space space) +rd_cmd_name_from_eval(E_Eval eval) { String8 result = {0}; - if(space.kind == RD_EvalSpaceKind_MetaCmd) + if(eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - result = e_string_from_id(space.u64s[0]); + result = e_string_from_id(eval.value.u64); } return result; } -internal E_Space -rd_eval_space_from_cmd_name(String8 cmd_name) -{ - E_Space space = e_space_make(RD_EvalSpaceKind_MetaCmd); - space.u64s[0] = e_id_from_string(cmd_name); - return space; -} - //- rjf: eval space reads/writes internal B32 diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 13dcd009..984c5673 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -900,8 +900,7 @@ 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); //- rjf: command name <-> eval space -internal String8 rd_cmd_name_from_eval_space(E_Space space); -internal E_Space rd_eval_space_from_cmd_name(String8 cmd_name); +internal String8 rd_cmd_name_from_eval(E_Eval eval); //- rjf: eval space reads/writes internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 20a57007..a19cca41 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1416,6 +1416,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) internal RD_WatchRowCellInfo rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_flags, RD_WatchRowInfo *row_info, RD_WatchCell *cell, FNT_Tag font, F32 font_size, F32 max_size_px) { + Temp scratch = scratch_begin(&arena ,1); RD_WatchRowCellInfo result = { .flags = cell->flags, @@ -1436,11 +1437,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.entity = rd_ctrl_entity_from_eval_space(cell->eval.space); } - result.cmd_name = rd_cmd_name_from_eval_space(cell->eval.space); - if(cell->eval.space.kind == E_SpaceKind_FileSystem) - { - result.file_path = e_string_from_id(cell->eval.space.u64_0); - } + result.cmd_name = rd_cmd_name_from_eval(cell->eval); + result.file_path = rd_file_path_from_eval(arena, cell->eval); for(E_Type *type = cell_type; type->kind == E_TypeKind_Lens; type = e_type_from_key__cached(type->direct_type_key)) @@ -1478,16 +1476,14 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: buttons -> button for command else if(result.cmd_name.size != 0) { - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(result.cmd_name); - result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_kind_info->string); + result.fstrs = rd_title_fstrs_from_code_name(arena, result.cmd_name); result.flags |= RD_WatchCellFlag_Button; } //- rjf: files -> button for file else if(result.file_path.size != 0) { - String8 file_path = e_string_from_id(cell->eval.value.u64); - result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); + result.fstrs = rd_title_fstrs_from_file_path(arena, result.file_path); result.flags |= RD_WatchCellFlag_Button; } @@ -1970,6 +1966,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } #endif + scratch_end(scratch); return result; } From 92f3ea922d933d73fa6d446de61541f42c02716d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 19 Apr 2025 09:44:43 -0700 Subject: [PATCH 401/755] fix row command evaluations in row building --- src/raddbg/raddbg_views.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a19cca41..ed4d723b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1221,18 +1221,17 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "enabled"), .flags = RD_WatchCellFlag_Background, - .px = floor_f32(ui_top_font_size()*6.f), - .string = str8_lit("($expr).enabled")); + .px = floor_f32(ui_top_font_size()*6.f)); } else if(cmd_kind != RD_CmdKind_Null) { String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, + e_eval_from_stringf(arena, "query:commands.%S", cmd_name), .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, - .px = floor_f32(ui_top_font_size()*4.f), - .string = push_str8f(arena, "query:commands.%S", cmd_name)); + .px = floor_f32(ui_top_font_size()*4.f)); } } } @@ -1459,8 +1458,10 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: default case: depending on cell info, generate string default: { + if(0){} + //- rjf: cfg evaluation -> button for cfg - if(result.cfg != &rd_nil_cfg) + else if(result.cfg != &rd_nil_cfg) { result.fstrs = rd_title_fstrs_from_cfg(arena, result.cfg); result.flags |= RD_WatchCellFlag_Button; From 657f5edb31c4f1ffb09acade4243e0454cdaaa70 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 19 Apr 2025 19:12:55 -0700 Subject: [PATCH 402/755] compute cell editability --- src/raddbg/raddbg_views.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index ed4d723b..52130617 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1450,6 +1450,28 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } } + ////////////////////////////// + //- rjf: determine cell editability + // + switch(cell->kind) + { + default:{}break; + case RD_WatchCellKind_Expr: + { + if(row_info->expr_is_editable) + { + result.flags |= RD_WatchCellFlag_CanEdit; + } + }break; + case RD_WatchCellKind_Eval: + { + if(ev_type_key_is_editable(cell->eval.irtree.type_key) && cell->eval.irtree.mode == E_Mode_Offset) + { + result.flags |= RD_WatchCellFlag_CanEdit; + } + }break; + } + ////////////////////////////// //- rjf: build cell's visual appearance info // From c45bd364eb60f223d41988a6b491e47dca64219c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 19 Apr 2025 21:23:48 -0700 Subject: [PATCH 403/755] use meta-display-names in cell rendering, fix small command buttons --- src/raddbg/generated/raddbg.meta.c | 14 +++-------- src/raddbg/generated/raddbg.meta.h | 5 +--- src/raddbg/raddbg.mdesk | 12 +++------ src/raddbg/raddbg_views.c | 39 ++++++++++++++++++++++++++---- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 642916bd..fcbb559a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[323] = +RD_VocabInfo rd_vocab_info_table[320] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -269,9 +269,6 @@ RD_VocabInfo rd_vocab_info_table[323] = {str8_lit_comp("toggle_watch_expr"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("set_columns"), str8_lit_comp(""), str8_lit_comp("Set Columns"), str8_lit_comp(""), RD_IconKind_Thumbnails}, -{str8_lit_comp("toggle_address_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, -{str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), str8_lit_comp(""), RD_IconKind_Thumbnails}, {str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_RadioHollow}, @@ -335,8 +332,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[20] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n @default(3.f) 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, @@ -400,7 +397,7 @@ Rng1U64 rd_reg_slot_range_table[41] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[214] = +RD_CmdKindInfo rd_cmd_kind_info_table[211] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -556,9 +553,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("$disasm,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 580f4eca..6184904a 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -208,9 +208,6 @@ RD_CmdKind_GoToNameAtCursor, RD_CmdKind_ToggleWatchExpression, RD_CmdKind_ToggleWatchExpressionAtCursor, RD_CmdKind_ToggleWatchExpressionAtMouse, -RD_CmdKind_SetColumns, -RD_CmdKind_ToggleAddressVisibility, -RD_CmdKind_ToggleCodeBytesVisibility, RD_CmdKind_EnableCfg, RD_CmdKind_DisableCfg, RD_CmdKind_SelectCfg, @@ -640,7 +637,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[323]; +extern RD_VocabInfo rd_vocab_info_table[320]; extern RD_NameSchemaInfo rd_name_schema_info_table[20]; extern Rng1U64 rd_reg_slot_range_table[41]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 50848c42..9731f69c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -226,7 +226,6 @@ RD_VocabTable: x: { @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64, - @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32, } ``` } @@ -236,7 +235,9 @@ RD_VocabTable: watch, ``` @inherit(tab) x: - {} + { + @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32, + } ``` } { @@ -684,13 +685,6 @@ RD_CmdTable: // | | | | {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } - //- rjf: memory view parameterization - {SetColumns 1 1 "" Null null Nil Null 0 0 0 0 1 1 1 Thumbnails "set_columns" "Set Columns" "Sets the number of columns for a memory view." "" "" } - - //- rjf: disassembly view parameterization - {ToggleAddressVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_address_visibility" "Toggle Address Visibility" "Toggles the visibility of addresses in a disassembly view." "" "$disasm," } - {ToggleCodeBytesVisibility 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thumbnails "toggle_code_bytes_visibility""Toggle Code Bytes Visibility" "Toggles the visibility of machine code bytes in a disassembly view." "" "$disasm," } - //- rjf: general config operations {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 52130617..36f9f43b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1499,7 +1499,24 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: buttons -> button for command else if(result.cmd_name.size != 0) { - result.fstrs = rd_title_fstrs_from_code_name(arena, result.cmd_name); + if(cell->px != 0) + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[rd_icon_kind_from_code_name(result.cmd_name)], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + result.fstrs = fstrs; + } + else + { + result.fstrs = rd_title_fstrs_from_code_name(arena, result.cmd_name); + } result.flags |= RD_WatchCellFlag_Button; } @@ -1517,6 +1534,22 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla B32 is_non_code = 0; String8 expr_string = cell->string; + // rjf: if this cell has a meta-display-name, then use that + if(expr_string.size == 0) + { + for(E_Type *t = e_type_from_key__cached(cell->eval.irtree.type_key); + t != &e_type_nil; + t = e_type_from_key__cached(t->direct_type_key)) + { + if(t->kind == E_TypeKind_MetaDisplayName) + { + is_non_code = 1; + expr_string = t->name; + break; + } + } + } + // rjf: if this cell has no string specified, then we need to synthesize one from the evaluation if(expr_string.size == 0) { @@ -2563,10 +2596,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) cursor = mark = cmd->regs->vaddr; mv->center_cursor = 1; }break; - case RD_CmdKind_SetColumns: - { - // TODO(rjf) - }break; } } From 19a56b88a01b40be19964abf08553be92befe943 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 20 Apr 2025 19:09:11 -0700 Subject: [PATCH 404/755] correct cell expression edit string formation --- .../eval_visualization_core.c | 4 +- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 2 +- src/raddbg/raddbg_views.c | 51 +++++++++++++------ src/raddbg/raddbg_views.h | 2 +- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 61526059..688cbe80 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1034,7 +1034,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->block = n->v.block; row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); row->visual_size = n->v.block->viz_expand_info.single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; - row->string = n->v.block->string; + row->edit_string = n->v.block->string; row->eval = n->v.block->eval; } @@ -1053,7 +1053,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->block = n->v.block; row->key = row_key; row->visual_size = 1; - row->string = range_exprs_strings[idx]; + row->edit_string = range_exprs_strings[idx]; row->eval = row_eval; } } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 2def910b..a23a2fcf 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -197,7 +197,7 @@ struct EV_Row EV_Block *block; EV_Key key; U64 visual_size; - String8 string; + String8 edit_string; E_Eval eval; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7e0b511b..ac74d496 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3030,7 +3030,7 @@ rd_view_ui(Rng2F32 rect) if(cell_info.flags & RD_WatchCellFlag_CanEdit) { any_edits_started = 1; - String8 string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + String8 string = cell->edit_string; string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; U64 hash = ev_hash_from_key(pt.key); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 36f9f43b..e9906a66 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1129,7 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1143,7 +1143,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1155,7 +1155,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess && str8_match(row_type->name, str8_lit("unattached_process"), 0)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1164,7 +1164,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1173,7 +1173,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1244,6 +1244,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f); if(entity->kind == CTRL_EntityKind_Machine || @@ -1251,6 +1252,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Thread) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "active"), + .edit_string = row->edit_string, .px = floor_f32(ui_top_font_size()*6.f)); } if(entity->kind == CTRL_EntityKind_Thread) @@ -1262,6 +1264,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + .edit_string = row->edit_string, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*4.f)); } @@ -1272,7 +1275,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string,.flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1283,11 +1286,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } else { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f); } @@ -1306,7 +1312,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1317,7 +1325,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1339,8 +1349,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .edit_string = row->edit_string, + .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1355,7 +1369,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, + .default_pct = 0.75f, + .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1383,7 +1401,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), - .string = str8_lit(" "), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct } @@ -1399,7 +1416,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Indented, + .default_pct = 0.35f, + .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct @@ -1532,7 +1553,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { // rjf: funnel-through this cell's string, if it has one B32 is_non_code = 0; - String8 expr_string = cell->string; + String8 expr_string = cell->edit_string; // rjf: if this cell has a meta-display-name, then use that if(expr_string.size == 0) diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index c08d2dcb..38b4f927 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -69,7 +69,7 @@ struct RD_WatchCell RD_WatchCellKind kind; RD_WatchCellFlags flags; U64 index; - String8 string; + String8 edit_string; E_Eval eval; F32 default_pct; F32 pct; From ffb81cd814a7d7f7448e24eb426bc9042e23b8ea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 20 Apr 2025 19:30:22 -0700 Subject: [PATCH 405/755] f1 lister completion; improve command listing --- src/raddbg/raddbg_core.c | 74 +++++++++++++++++++++++++++++++-- src/raddbg/raddbg_eval.c | 90 ++++++++++++++++------------------------ 2 files changed, 107 insertions(+), 57 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ac74d496..eafcfe11 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2960,7 +2960,10 @@ rd_view_ui(Rng2F32 rect) { taken = 1; E_Eval eval = row->eval; - switch(eval.space.kind) + + // rjf: if we have a specific command we are trying to complete, then + // fill registers based on this row's evaluation. + if(cmd_name.size != 0) switch(eval.space.kind) { default: { @@ -2993,6 +2996,67 @@ rd_view_ui(Rng2F32 rect) rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); }break; } + + // rjf: if we do not have a specific command, then we can just + // pick a sensible default based on what was selected. + if(cmd_name.size == 0) + { + B32 did_cmd = 1; + switch(eval.space.kind) + { + default: + { + String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); + if(symbol_name.size != 0) + { + rd_cmd(RD_CmdKind_GoToName, .string = symbol_name); + } + else + { + did_cmd = 0; + } + }break; + case E_SpaceKind_File: + case E_SpaceKind_FileSystem: + { + String8 file = rd_file_path_from_eval(scratch.arena, eval); + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = file, .vaddr = 0); + }break; + case RD_EvalSpaceKind_MetaCfg: + { + RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); + if(str8_match(cfg->string, str8_lit("recent_file"), 0)) + { + rd_cmd(RD_CmdKind_Switch, .cfg = cfg->id); + } + else if(str8_match(cfg->string, str8_lit("recent_project"), 0)) + { + rd_cmd(RD_CmdKind_OpenRecentProject, .cfg = cfg->id); + } + else + { + did_cmd = 0; + } + }break; + case RD_EvalSpaceKind_MetaUnattachedProcess: + { + U64 pid = eval.value.u128.u64[0]; + }break; + case RD_EvalSpaceKind_MetaCmd: + { + String8 cmd_name = rd_cmd_name_from_eval(eval); + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_name); + }break; + } + if(did_cmd) + { + rd_cmd(RD_CmdKind_CompleteQuery); + } + else + { + taken = 0; + } + } } } } @@ -14760,9 +14824,11 @@ Z(getting_started) }break; case RD_CmdKind_CompleteQuery: { + // rjf: unpack params RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); String8 cmd_name = rd_view_query_cmd(); - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: push command if(cmd_name.size != 0) RD_RegsScope() { rd_push_cmd(cmd_name, rd_regs()); @@ -14771,7 +14837,9 @@ Z(getting_started) // rjf: find out if this view is a lister B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); - // rjf: complete query + // rjf: complete query, either by closing the query popup, or closing the + // tab-embedded query edit + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); if(is_lister) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index f941e0f8..1accfe81 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -4,36 +4,6 @@ //////////////////////////////// //~ rjf: `commands` Type Hooks -E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) -{ - E_TypeExpandInfo result = {0}; - if(filter.size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - String8List cmd_names = {0}; - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - String8 name = info->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) - { - str8_list_push(scratch.arena, &cmd_names, name); - } - } - String8Array *accel = push_array(arena, String8Array, 1); - *accel = str8_array_from_list(arena, &cmd_names); - result.user_data = accel; - result.expr_count = accel->count; - scratch_end(scratch); - } - else - { - result.expr_count = RD_CmdKind_COUNT - 1; - } - return result; -} - E_TYPE_ACCESS_FUNCTION_DEF(commands) { E_IRTreeAndType result = {&e_irnode_nil}; @@ -47,34 +17,46 @@ E_TYPE_ACCESS_FUNCTION_DEF(commands) return result; } +E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) +{ + E_TypeExpandInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + String8List cmd_names = {0}; + for EachNonZeroEnumVal(RD_CmdKind, k) + { + RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; + if(info->flags & RD_CmdKindFlag_ListInUI) + { + String8 name = info->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); + if(matches.count == matches.needle_part_count) + { + str8_list_push(scratch.arena, &cmd_names, name); + } + } + } + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &cmd_names); + result.user_data = accel; + result.expr_count = accel->count; + scratch_end(scratch); + } + return result; +} + E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) { U64 out_idx = 0; - if(user_data != 0) + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { - String8Array *accel = (String8Array *)user_data; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - String8 cmd_name = accel->v[idx]; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs_out[out_idx] = expr; - } - } - else - { - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) - { - RD_CmdKind cmd_kind = (RD_CmdKind)(idx+1); - String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs_out[out_idx] = expr; - } + String8 cmd_name = accel->v[idx]; + E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); + expr->value.u64 = e_id_from_string(cmd_name); + exprs_out[out_idx] = expr; } } From 9453f62cf4cfc9412a45b34afb1889ace236f3c6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 20 Apr 2025 19:35:37 -0700 Subject: [PATCH 406/755] cmd filter -> filter on display names, descriptions, and search tags --- src/raddbg/raddbg_eval.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 1accfe81..c997994a 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -28,11 +28,18 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; if(info->flags & RD_CmdKindFlag_ListInUI) { - String8 name = info->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, name); - if(matches.count == matches.needle_part_count) + String8 code_name = info->string; + String8 description = info->description; + String8 search_tags = info->search_tags; + String8 display_name = rd_display_from_code_name(code_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, description); + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, display_name); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, filter, search_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == desc_matches.needle_part_count || + tags_matches.count == tags_matches.needle_part_count) { - str8_list_push(scratch.arena, &cmd_names, name); + str8_list_push(scratch.arena, &cmd_names, code_name); } } } From cbe1365244aa79da59a6460c87f3a2ae11c754e8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 20 Apr 2025 20:21:54 -0700 Subject: [PATCH 407/755] cell description rendering --- src/raddbg/raddbg_core.c | 22 ++++++++++++++++------ src/raddbg/raddbg_eval.c | 10 ++++++++-- src/raddbg/raddbg_views.c | 14 ++++++++++++++ src/raddbg/raddbg_views.h | 1 + src/raddbg/raddbg_widgets.c | 31 ++++++++++++++++++++++++++++++- src/raddbg/raddbg_widgets.h | 3 ++- src/ui/ui_basic_widgets.c | 8 ++++---- 7 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index eafcfe11..247b9f28 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4347,6 +4347,12 @@ rd_view_ui(Rng2F32 rect) cell_params.fstrs = cell_info.fstrs; cell_params.fuzzy_matches = &fuzzy_matches; + // rjf: apply description + if(row_height_px > ui_top_font_size()*3.5f) + { + cell_params.description = cell_info.description; + } + // rjf: apply expander (or substitute space) if(row_is_expandable && cell == row_info->cells.first) { @@ -6348,7 +6354,6 @@ rd_window_frame(void) { FloatingViewTask *next; RD_Cfg *view; - F32 row_height_px; Rng2F32 rect; String8 view_name; String8 expr; @@ -6479,7 +6484,6 @@ rd_window_frame(void) SLLQueuePush(first_floating_view_task, last_floating_view_task, t); hover_eval_floating_view_task = t; t->view = view; - t->row_height_px = row_height_px; t->rect = rect; t->view_name = view_name; t->expr = hover_eval_expr; @@ -6580,11 +6584,20 @@ rd_window_frame(void) // rjf: evaluate query expression E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); + // rjf: determine & store row-height setting + if(!query_is_anchored && cmd_name.size == 0) + { + F32 row_height = 5.f; + F32 row_height_px = row_height * ui_top_font_size(); + RD_Cfg *row_height_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("row_height")); + rd_cfg_new_replacef(row_height_root, "%f", row_height); + } + // rjf: compute query view's top-level rectangle - F32 row_height_px = floor_f32(ui_top_px_height()); Rng2F32 rect = {0}; RD_RegsScope(.view = view->id) { + F32 row_height_px = ui_top_px_height(); Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); EV_BlockTree predicted_block_tree = ev_block_tree_from_expr(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.expr); @@ -6619,7 +6632,6 @@ rd_window_frame(void) SLLQueuePush(first_floating_view_task, last_floating_view_task, t); query_floating_view_task = t; t->view = view; - t->row_height_px = row_height_px; t->rect = rect; t->view_name = str8_lit("watch"); t->expr = query_expr; @@ -6644,7 +6656,6 @@ rd_window_frame(void) { // rjf: unpack RD_Cfg *view = t->view; - F32 row_height_px = t->row_height_px; Rng2F32 rect = t->rect; String8 view_name = t->view_name; String8 expr = t->expr; @@ -6674,7 +6685,6 @@ rd_window_frame(void) // rjf: build UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) - UI_PrefHeight(ui_px(row_height_px, 1.f)) { // rjf: build top-level container box UI_Box *container = &ui_nil_box; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index c997994a..4a2d9e82 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -10,7 +10,10 @@ E_TYPE_ACCESS_FUNCTION_DEF(commands) if(expr->kind == E_ExprKind_MemberAccess) { String8 cmd_name = expr->first->next->string; - result.type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + RD_CmdKindInfo *cmd_info = rd_cmd_kind_info_from_string(cmd_name); + E_TypeKey cmd_type = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + cmd_type = e_type_key_cons_meta_description(cmd_type, cmd_info->description); + result.type_key = cmd_type; result.mode = E_Mode_Value; result.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCmd), e_irtree_const_u(arena, e_id_from_string(cmd_name))); } @@ -59,8 +62,11 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { String8 cmd_name = accel->v[idx]; + RD_CmdKindInfo *cmd_info = rd_cmd_kind_info_from_string(cmd_name); + E_TypeKey cmd_type = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + cmd_type = e_type_key_cons_meta_description(cmd_type, cmd_info->description); E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); + expr->type_key = cmd_type; expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); expr->value.u64 = e_id_from_string(cmd_name); exprs_out[out_idx] = expr; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index e9906a66..2d0a284a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1471,6 +1471,20 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } } + ////////////////////////////// + //- rjf: determine cell description + // + for(E_Type *type = cell_type; + type->kind != E_TypeKind_Null; + type = e_type_from_key__cached(type->direct_type_key)) + { + if(type->kind == E_TypeKind_MetaDescription) + { + result.description = type->name; + break; + } + } + ////////////////////////////// //- rjf: determine cell editability // diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 38b4f927..fa974618 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -112,6 +112,7 @@ struct RD_WatchRowCellInfo String8 cmd_name; String8 file_path; DR_FStrList fstrs; + String8 description; String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index d9300d71..38ded76d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3215,11 +3215,24 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build left-hand-side container box + // + UI_Box *lhs_box = &ui_nil_box; + UI_Parent(box) UI_WidthFill UI_ChildLayoutAxis(Axis2_Y) + { + lhs_box = ui_build_box_from_stringf(0, "lhs_box"); + UI_Parent(lhs_box) + { + ui_spacer(ui_em(3.f, 0.f)); + } + } + ////////////////////////////// //- rjf: build scrollable container box // UI_Box *scrollable_box = &ui_nil_box; - UI_Parent(box) UI_WidthFill + UI_Parent(lhs_box) UI_WidthFill UI_HeightFill { scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); } @@ -3654,6 +3667,22 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build description + // + if(params->description.size != 0) UI_Parent(lhs_box) UI_HeightFill RD_Font(RD_FontSlot_Main) UI_FontSize(ui_top_font_size()*0.85f) + { + UI_Row + { + ui_spacer(ui_em(0.5f, 1.f)); + ui_label(params->description); + } + } + UI_Parent(lhs_box) + { + ui_spacer(ui_em(3.f, 0.f)); + } + ////////////////////////////// //- rjf: click+drag // diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 173bb3ff..e817b8c4 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -40,12 +40,13 @@ enum typedef struct RD_CellParams RD_CellParams; struct RD_CellParams { - //- rjf: catachall parameters + //- rjf: catchall parameters RD_CellFlags flags; S32 depth; FuzzyMatchRangeList *fuzzy_matches; String8 pre_edit_value; DR_FStrList fstrs; + String8 description; //- rjf: expander r/w info B32 *expanded_out; diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 8e06f4a0..c216d7b1 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -147,16 +147,16 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) Rng2F32 cursor_rect = { text_position.x + cursor_pixel_off - cursor_thickness*0.50f, - box->rect.y0+ui_top_font_size()*0.5f, + box->parent->parent->rect.y0+ui_top_font_size()*0.5f, text_position.x + cursor_pixel_off + cursor_thickness*0.50f, - box->rect.y1-ui_top_font_size()*0.5f, + box->parent->parent->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 mark_rect = { text_position.x + mark_pixel_off - cursor_thickness*0.50f, - box->rect.y0+ui_top_font_size()*0.5f, + box->parent->parent->rect.y0+ui_top_font_size()*0.5f, text_position.x + mark_pixel_off + cursor_thickness*0.50f, - box->rect.y1-ui_top_font_size()*0.5f, + box->parent->parent->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 select_rect = union_2f32(cursor_rect, mark_rect); dr_rect(select_rect, select_color, font_size/2.f, 0, 1.f); From d98ea1cf6f5970d62624cc9676c650c49d5ac1ab Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 27 Mar 2025 16:08:26 -0700 Subject: [PATCH 408/755] parallel build targets --- .github/workflows/builds.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index e38219f2..b2de41ba 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -13,6 +13,19 @@ jobs: runs-on: windows-2022 strategy: fail-fast: false + matrix: + target: + - raddbg + - radlink + - rdi_from_pdb + - raddump + - rdi_breakpad_from_pdb + compiler: + - msvc + - clang + mode: + - debug + - release steps: - name: checkout uses: actions/checkout@v2 @@ -20,13 +33,4 @@ jobs: shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 - call build raddbg msvc debug || exit /b 1 - call build raddbg clang debug || exit /b 1 - call build rdi_from_pdb msvc debug || exit /b 1 - call build rdi_from_pdb clang debug || exit /b 1 - call build raddump msvc debug || exit /b 1 - call build raddump clang debug || exit /b 1 - call build radlink msvc debug || exit /b 1 - call build radlink clang debug || exit /b 1 - call build rdi_breakpad_from_pdb msvc debug || exit /b 1 - call build rdi_breakpad_from_pdb clang debug || exit /b 1 + call build ${{ matrix.target }} ${{ matrix.compiler }} ${{ matrix.mode }} || exit /b 1 From 02dc501547c8982f46c64d80d9fcfbc3491f123e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:02:27 -0700 Subject: [PATCH 409/755] transient tab editing, more work on descriptions/schemas for settings/etc --- src/raddbg/generated/raddbg.meta.c | 17 ++++------- src/raddbg/generated/raddbg.meta.h | 7 +++-- src/raddbg/raddbg.mdesk | 49 ++++++++++++++++++------------ src/raddbg/raddbg_core.c | 43 +++++++++++++++++++------- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 4 +-- 6 files changed, 75 insertions(+), 46 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index fcbb559a..0a98e475 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[320] = +RD_VocabInfo rd_vocab_info_table[314] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -108,12 +108,6 @@ RD_VocabInfo rd_vocab_info_table[320] = {str8_lit_comp("pitch"), str8_lit_comp(""), str8_lit_comp("Pitch"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("zoom"), str8_lit_comp(""), str8_lit_comp("Zoom"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("font_size"), str8_lit_comp(""), str8_lit_comp("Font Size"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("smooth_ui_text"), str8_lit_comp(""), str8_lit_comp("Smooth UI Text"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("smooth_code_text"), str8_lit_comp(""), str8_lit_comp("Smooth Code Text"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("hint_ui_text"), str8_lit_comp(""), str8_lit_comp("Hint UI Text"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("hint_code_text"), str8_lit_comp(""), str8_lit_comp("Hint Code Text"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("opaque_backgrounds"), str8_lit_comp(""), str8_lit_comp("Opaque Backgrounds"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("background_blur"), str8_lit_comp(""), str8_lit_comp("Background Blur"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("row_height"), str8_lit_comp(""), str8_lit_comp("Row Height"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_height"), str8_lit_comp(""), str8_lit_comp("Tab Height"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, @@ -331,10 +325,10 @@ RD_VocabInfo rd_vocab_info_table[320] = RD_NameSchemaInfo rd_name_schema_info_table[20] = { {str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n @default(3.f) 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) 'thread_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) 'smooth_ui_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n @default(0) @display_name('Transient') 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, @@ -352,7 +346,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[20] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[41] = +Rng1U64 rd_reg_slot_range_table[42] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -390,6 +384,7 @@ Rng1U64 rd_reg_slot_range_table[41] = {OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, {OffsetOf(RD_Regs, do_implicit_root), OffsetOf(RD_Regs, do_implicit_root) + sizeof(B32)}, {OffsetOf(RD_Regs, do_lister), OffsetOf(RD_Regs, do_lister) + sizeof(B32)}, +{OffsetOf(RD_Regs, do_big_rows), OffsetOf(RD_Regs, do_big_rows) + sizeof(B32)}, {OffsetOf(RD_Regs, dir2), OffsetOf(RD_Regs, dir2) + sizeof(Dir2)}, {OffsetOf(RD_Regs, string), OffsetOf(RD_Regs, string) + sizeof(String8)}, {OffsetOf(RD_Regs, cmd_name), OffsetOf(RD_Regs, cmd_name) + sizeof(String8)}, @@ -487,7 +482,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6184904a..aad7975e 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -44,6 +44,7 @@ RD_RegSlot_PreferDisasm, RD_RegSlot_NoRichTooltip, RD_RegSlot_DoImplicitRoot, RD_RegSlot_DoLister, +RD_RegSlot_DoBigRows, RD_RegSlot_Dir2, RD_RegSlot_String, RD_RegSlot_CmdName, @@ -566,6 +567,7 @@ B32 prefer_disasm; B32 no_rich_tooltip; B32 do_implicit_root; B32 do_lister; +B32 do_big_rows; Dir2 dir2; String8 string; String8 cmd_name; @@ -630,6 +632,7 @@ RD_Query query; .no_rich_tooltip = rd_regs()->no_rich_tooltip,\ .do_implicit_root = rd_regs()->do_implicit_root,\ .do_lister = rd_regs()->do_lister,\ +.do_big_rows = rd_regs()->do_big_rows,\ .dir2 = rd_regs()->dir2,\ .string = rd_regs()->string,\ .cmd_name = rd_regs()->cmd_name,\ @@ -637,9 +640,9 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[320]; +extern RD_VocabInfo rd_vocab_info_table[314]; extern RD_NameSchemaInfo rd_name_schema_info_table[20]; -extern Rng1U64 rd_reg_slot_range_table[41]; +extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[74]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9731f69c..6563e48c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -121,12 +121,6 @@ RD_VocabTable: {pitch "" "Pitch" "" Null } {zoom "" "Zoom" "" Null } {font_size "" "Font Size" "" Null } - {smooth_ui_text "" "Smooth UI Text" "" Null } - {smooth_code_text "" "Smooth Code Text" "" Null } - {hint_ui_text "" "Hint UI Text" "" Null } - {hint_code_text "" "Hint Code Text" "" Null } - {opaque_backgrounds "" "Opaque Backgrounds" "" Null } - {background_blur "" "Background Blur" "" Null } {row_height "" "Row Height" "" Null } {tab_height "" "Tab Height" "" Null } } @@ -196,25 +190,38 @@ RD_VocabTable: @default(1) 'scrolling_animations': bool, //- rjf: thread & breakpoint decorations - @default(1) 'thread_lines': bool, - @default(1) 'thread_glow': bool, - @default(1) 'breakpoint_lines': bool, - @default(1) 'breakpoint_glow': bool, + @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") + 'thread_lines': bool, + @default(1) @display_name('Thread Glow') @description("Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.") + 'thread_glow': bool, + @default(1) @display_name('Breakpoint Lines') @description("Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.") + 'breakpoint_lines': bool, + @default(1) @display_name('Breakpoint Glow') @description("Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.") + 'breakpoint_glow': bool, //- rjf: occluding background settings - @default(0) 'opaque_backgrounds': bool, - @default(1) 'background_blur': bool, + @default(0) @display_name('Opaque Backgrounds') @description("Controls whether or not all floating background colors are forced to be fully opaque.") + 'opaque_backgrounds': bool, + @default(1) @display_name('Background Blur') @description("Controls whether or not occluded regions behind floating elements are blurred.") + 'background_blur': bool, //- rjf: text rasterization settings - @default(1) 'smooth_ui_text': bool, - @default(1) 'hint_ui_text': bool, - @default(0) 'smooth_code_text': bool, - @default(1) 'hint_code_text': bool, - @default(11) @display_name('Window Font Size') 'font_size': @range[6, 72] u64, + @default(1) @display_name('Smooth UI Text') @description("Controls whether or not UI text is fully anti-aliased, for a smoother appearance.") + 'smooth_ui_text': bool, + @default(1) @display_name('Hint UI Text') @description("Controls whether or not UI text is hinted, for better text readability at small sizes.") + 'hint_ui_text': bool, + @default(0) @display_name('Smooth Code Text') @description("Controls whether or not code text is fully anti-aliased, for a smoother appearance.") + 'smooth_code_text': bool, + @default(1) @display_name('Hint Code Text') @description("Controls whether or not code text is hinted, for better text readability at small sizes.") + 'hint_code_text': bool, + @default(11) @display_name('Window Font Size') @description("Controls the window's default font size. Does not apply to tabs with their own font size set.") + 'font_size': @range[6, 72] u64, //- rjf: size settings - @default(3.f) @display_name('Window Row Height') 'row_height': @range[1.75f, 5.f] f32, - @default(3.f) 'tab_height': @range[1.75f, 5.f] f32, + @default(3.f) @display_name('Window Row Height') @description("Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.") + 'row_height': @range[1.75f, 5.f] f32, + @default(3.f) @description("Controls the height of tabs, in multiples of the font size.") + 'tab_height': @range[1.75f, 5.f] f32, } ``` } @@ -248,6 +255,7 @@ RD_VocabTable: 'lang':lang, 'size':code_string, @default(1) 'show_line_numbers':bool, + @default(0) @display_name('Transient') 'auto': bool, } ``` } @@ -472,6 +480,7 @@ RD_RegTable: {B32 no_rich_tooltip NoRichTooltip } {B32 do_implicit_root DoImplicitRoot} {B32 do_lister DoLister } + {B32 do_big_rows DoBigRows } {Dir2 dir2 Dir2 } {String8 string String } {String8 cmd_name CmdName } @@ -598,7 +607,7 @@ RD_CmdTable: // | | | | {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } - {ShowFileInExplorer 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } + {ShowFileInExplorer 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 247b9f28..def514cc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3047,6 +3047,11 @@ rd_view_ui(Rng2F32 rect) String8 cmd_name = rd_cmd_name_from_eval(eval); rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_name); }break; + case RD_EvalSpaceKind_MetaCtrlEntity: + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + rd_cmd(RD_CmdKind_PushQuery, .expr = ctrl_string_from_handle(scratch.arena, entity->handle)); + }break; } if(did_cmd) { @@ -4308,7 +4313,7 @@ rd_view_ui(Rng2F32 rect) B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); - B32 is_toggle_switch = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Bool); + B32 is_toggle_switch = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Bool); B32 is_slider = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && cell_type->kind == E_TypeKind_Lens && str8_match(cell_type->name, str8_lit("range1"), 0)); B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); @@ -4819,6 +4824,18 @@ rd_view_cfg_value_from_string(String8 string) return result; } +internal B32 +rd_view_cfg_b32_from_string(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + RD_Cfg *root = rd_view_cfg_from_string(string); + String8 expr = push_str8f(scratch.arena, "(bool)(%S)", root->first->string); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + B32 result = !!e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); + return result; +} + internal U64 rd_view_cfg_u64_from_string(String8 string) { @@ -6585,7 +6602,7 @@ rd_window_frame(void) E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); // rjf: determine & store row-height setting - if(!query_is_anchored && cmd_name.size == 0) + if(ws->query_regs->do_big_rows) { F32 row_height = 5.f; F32 row_height_px = row_height * ui_top_font_size(); @@ -8498,7 +8515,7 @@ rd_window_frame(void) { // rjf: gather info for this tab B32 tab_is_selected = (tab == panel->selected_tab); - B32 tab_is_auto = (rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg); + B32 tab_is_auto = rd_view_cfg_b32_from_string(str8_lit("auto")); // rjf: begin vertical region for this tab ui_set_next_child_layout_axis(Axis2_Y); @@ -12618,8 +12635,8 @@ rd_frame(void) //- rjf: open lister case RD_CmdKind_OpenLister: { - String8 expr = push_str8f(scratch.arena, "query:commands, query:$%I64x, query:$%I64x, query:recent_files, query:recent_projects, query:procedures", rd_regs()->view, rd_regs()->window); - rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1); + String8 expr = push_str8f(scratch.arena, "query:commands, query:$%I64x, query:$%I64x, query:recent_files, query:recent_projects, query:procedures, query:processes, query:threads, query:modules", rd_regs()->view, rd_regs()->window); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1); }break; //- rjf: command fast path @@ -12703,7 +12720,7 @@ rd_frame(void) case RD_CmdKind_WindowSettings: { String8 expr = push_str8f(scratch.arena, "query:$%I64x", rd_regs()->window); - rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); }break; case RD_CmdKind_CloseWindow: { @@ -14443,11 +14460,14 @@ Z(getting_started) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - if(str8_match(tab->string, str8_lit("text"), 0) && - rd_cfg_child_from_string(tab, str8_lit("auto")) != &rd_nil_cfg) + RD_RegsScope(.view = tab->id) { - panel_w_auto = panel; - view_w_auto = tab; + if(str8_match(tab->string, str8_lit("text"), 0) && + rd_view_cfg_b32_from_string(str8_lit("auto"))) + { + panel_w_auto = panel; + view_w_auto = tab; + } } } } @@ -14658,7 +14678,8 @@ Z(getting_started) dst_tab = rd_cfg_new(dst_panel->cfg, str8_lit("text")); RD_Cfg *expr = rd_cfg_new(dst_tab, str8_lit("expression")); rd_cfg_new(expr, rd_eval_string_from_file_path(scratch.arena, file_path)); - rd_cfg_new(dst_tab, str8_lit("auto")); + RD_Cfg *auto_root = rd_cfg_new(dst_tab, str8_lit("auto")); + rd_cfg_new(auto_root, str8_lit("1")); } // rjf: determine if we need a contain or center diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 984c5673..64a35c7c 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -944,6 +944,7 @@ internal String8 rd_view_query_cmd(void); internal String8 rd_view_query_input(void); internal RD_Cfg *rd_view_cfg_from_string(String8 string); internal E_Value rd_view_cfg_value_from_string(String8 string); +internal B32 rd_view_cfg_b32_from_string(String8 string); internal U64 rd_view_cfg_u64_from_string(String8 string); internal F32 rd_view_cfg_f32_from_string(String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2d0a284a..771710c7 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1129,7 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1320,7 +1320,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: @watch_row_build_cells meta-evaluation booleans // - else if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Bool && + else if(e_type_kind_from_key(e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Bool && (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) From c4a18f7bff936d8d7ebe1d30ae1f9cd1cb3f4cda Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:05:14 -0700 Subject: [PATCH 410/755] list select thread command in ui again --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0a98e475..26e9411e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -431,7 +431,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, { str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6563e48c..53625ffa 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -534,7 +534,7 @@ RD_CmdTable: // | | | | {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 0 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } {SelectUnwind 0 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } From 21a7126a574e6d99dd990e04ac19d68d23b62319 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:12:42 -0700 Subject: [PATCH 411/755] kill old row/cell building code, fix incorrect use of view ui rule hooks in all cells --- src/raddbg/raddbg_core.c | 2 +- src/raddbg/raddbg_views.c | 305 -------------------------------------- 2 files changed, 1 insertion(+), 306 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index def514cc..940ce350 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4223,7 +4223,7 @@ rd_view_ui(Rng2F32 rect) UI_Tag(cell_tag) { //- rjf: cell has hook? -> build ui by calling hook - if(cell_info.view_ui_rule != &rd_nil_view_ui_rule) + if(cell->kind == RD_WatchCellKind_ViewUI && cell_info.view_ui_rule != &rd_nil_view_ui_rule) { RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); RD_Cfg *view = rd_view_from_eval(root, cell->eval); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 771710c7..28cc000d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1752,311 +1752,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.fstrs = fstrs; }break; } - -#if 0 - //- rjf: fill basics/defaults - result.view_ui_rule = &rd_nil_view_ui_rule; - result.flags = cell->flags; - result.cfg = &rd_nil_cfg; - result.entity = &ctrl_entity_nil; - - //- rjf: do per-kind fills - switch(cell->kind) - { - default:{}break; - - //- rjf: expression cells -> if no string attached to row itself, form one from the - // expression tree. - case RD_WatchCellKind_Expr: - { - if(row_info->expr_is_editable) - { - result.flags |= RD_WatchCellFlag_CanEdit; - } - result.eval = (!e_type_key_match(cell->eval.irtree.type_key, e_type_key_zero()) ? cell->eval : row->eval); - result.string = row->string; - if(result.string.size == 0) - { - E_Expr *notable_expr = row->eval.expr; - for(B32 good = 0; !good;) - { - switch(notable_expr->kind) - { - default:{good = 1;}break; - case E_ExprKind_Address: - case E_ExprKind_Deref: - case E_ExprKind_Cast: - { - notable_expr = notable_expr->last; - }break; - case E_ExprKind_Ref: - { - notable_expr = notable_expr->ref; - }break; - } - } - switch(notable_expr->kind) - { - default: - { - result.string = e_string_from_expr(arena, notable_expr); - }break; - case E_ExprKind_ArrayIndex: - { - result.string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); - }break; - case E_ExprKind_MemberAccess: - { - Temp scratch = scratch_begin(&arena, 1); - E_Member member = e_type_member_from_key_name__cached(result.eval.irtree.type_key, notable_expr->last->string); - String8 member_name = member.name; - if(member_name.size == 0) - { - member_name = notable_expr->last->string; - } - if(member.inheritance_key_chain.count != 0) - { - String8List strings = {0}; - for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) - { - String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); - str8_list_push(scratch.arena, &strings, base_class_name); - } - result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); - } - B32 is_non_code = 0; - String8 string = push_str8f(arena, ".%S", member_name); - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - result.eval.space.kind == E_SpaceKind_File || - result.eval.space.kind == E_SpaceKind_FileSystem) - { - String8 fancy_name = rd_display_from_code_name(member_name); - if(fancy_name.size != 0) - { - string = fancy_name; - is_non_code = 1; - } - } - result.flags |= (!!is_non_code * RD_WatchCellFlag_IsNonCode); - result.string = string; - scratch_end(scratch); - }break; - } - } - }break; - - //- rjf: evaluation cells -> wrap expression if needed, evaluate, & stringize - case RD_WatchCellKind_Eval: - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: use cell's wrap string to wrap row's expression - String8 wrap_string = cell->string; - E_Expr *root_expr = row->eval.expr; - if(wrap_string.size != 0) - { - E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).expr; - root_expr = wrap_expr; - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *parent; - E_Expr *expr; - }; - Task start_task = {0, &e_expr_nil, wrap_expr}; - Task *first_task = &start_task; - Task *last_task = first_task; - for(Task *t = first_task; t != 0; t = t->next) - { - if(t->expr->kind == E_ExprKind_LeafIdentifier && str8_match(t->expr->string, str8_lit("$expr"), 0)) - { - E_Expr *original_expr_ref = e_expr_ref(scratch.arena, row->eval.expr); - if(t->parent != &e_expr_nil) - { - e_expr_insert_child(t->parent, t->expr, original_expr_ref); - e_expr_remove_child(t->parent, t->expr); - } - else - { - root_expr = original_expr_ref; - } - } - else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = t->expr; - task->expr = child; - } - } - } - - //- rjf: evaluate wrapped expression - result.eval = (!e_type_key_match(cell->eval.irtree.type_key, e_type_key_zero()) ? cell->eval : e_eval_from_expr(arena, root_expr)); - - //- rjf: determine string generation parameters based on evaluation - EV_StringParams string_params = {string_flags, 10}; - { - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || - result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - string_params.flags |= EV_StringFlag_DisableStringQuotes|EV_StringFlag_DisableAddresses; - } - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) - { - string_params.radix = 16; - } - if(result.eval.space.kind == RD_EvalSpaceKind_CtrlEntity && - rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Thread) - { - string_params.radix = 16; - } - } - - //- rjf: generate strings/flags based on that expression & fill - result.string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); - result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; - E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) - { - result.flags |= RD_WatchCellFlag_IsNonCode; - } - - scratch_end(scratch); - }break; - - //- rjf: tag cells -> look up attached tag - case RD_WatchCellKind_Tag: - { - EV_View *ev_view = rd_view_eval_view(); - result.string = ev_view_rule_from_key(ev_view, row->key); - result.flags |= RD_WatchCellFlag_CanEdit; - }break; - - //- rjf: view ui cells - case RD_WatchCellKind_ViewUI: - { - result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); - result.view_ui_rule = row_info->view_ui_rule; - }break; - } - - //- rjf: adjust style based on evaluation - switch(cell->kind) - { - default:{}break; - case RD_WatchCellKind_Expr: - { - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - result.eval.value.u64 == 0) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); - E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); - if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) - { - result.entity = entity; - } - } - else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && - result.eval.value.u64 == 0) - { - RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); - E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); - if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) - { - result.cfg = cfg; - result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); - } - } - else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) - { - result.cmd_name = e_string_from_id(result.eval.value.u64); - } - else if(result.eval.space.kind == E_SpaceKind_FileSystem) - { - E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) - { - String8 file_path = e_string_from_id(result.eval.value.u64); - result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); - result.flags |= RD_WatchCellFlag_Button; - } - } - }break; - case RD_WatchCellKind_Eval: - { - if(result.eval.msgs.max_kind != E_MsgKind_Null) - { - Temp scratch = scratch_begin(&arena, 1); - result.flags |= RD_WatchCellFlag_IsErrored|RD_WatchCellFlag_IsNonCode; - String8List error_strings = {0}; - for(E_Msg *msg = result.eval.msgs.first; msg != 0; msg = msg->next) - { - str8_list_push(scratch.arena, &error_strings, msg->text); - if(msg->next) - { - str8_list_pushf(scratch.arena, &error_strings, " "); - } - } - result.string = str8_list_join(arena, &error_strings, 0); - scratch_end(scratch); - } - else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - result.eval.value.u64 == 0) - { - CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(result.eval.space); - E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); - if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) - { - result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, entity, 1); - result.flags |= RD_WatchCellFlag_Button; - result.entity = entity; - } - } - else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg && - result.eval.value.u64 == 0) - { - RD_Cfg *cfg = rd_cfg_from_eval_space(result.eval.space); - E_TypeKey cfg_type = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); - if(e_type_key_match(cfg_type, result.eval.irtree.type_key)) - { - result.fstrs = rd_title_fstrs_from_cfg(arena, cfg); - result.flags |= RD_WatchCellFlag_Button; - result.cfg = cfg; - } - } - else if(result.eval.space.kind == RD_EvalSpaceKind_MetaCmd) - { - String8 cmd_name = e_string_from_id(result.eval.value.u64); - if(cell->px != 0) UI_TagF("weak") - { - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(arena, &result.fstrs, ¶ms, rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); - } - else - { - result.fstrs = rd_title_fstrs_from_code_name(arena, cmd_name); - } - result.flags |= RD_WatchCellFlag_Button; - result.cmd_name = cmd_name; - } - else if(result.eval.space.kind == E_SpaceKind_FileSystem) - { - E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); - if(type->kind == E_TypeKind_Set) - { - String8 file_path = e_string_from_id(result.eval.value.u64); - result.fstrs = rd_title_fstrs_from_file_path(arena, file_path); - result.flags |= RD_WatchCellFlag_Button; - } - } - }break; - } -#endif - scratch_end(scratch); return result; } From 8dd334d75426c6465fc90102442e23a4c3316f44 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:37:10 -0700 Subject: [PATCH 412/755] fix row key uniqueness of chained expansions, fix initial edit strings for value editing --- src/eval_visualization/eval_visualization_core.c | 6 ++++-- src/raddbg/raddbg_core.c | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 688cbe80..e68be0fd 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -546,6 +546,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp U64 child_id; U64 split_relative_idx; B32 default_expanded; + B32 force_expanded; }; Task start_task = {0, tree.root, tree.root->eval, 1, 0}; Task *first_task = &start_task; @@ -560,7 +561,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp // rjf: obtain expansion node & expansion state EV_ExpandNode *expand_node = ev_expand_node_from_key(view, key); B32 is_expanded = (expand_node != 0 && expand_node->expanded); - if(t->default_expanded) + if(t->default_expanded || t->force_expanded) { is_expanded ^= 1; } @@ -726,9 +727,10 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp t->next = task; task->parent_block = t->parent_block; task->eval = e_eval_from_expr(arena, t->eval.expr->next); - task->child_id = t->child_id; + task->child_id = t->child_id + 1; task->split_relative_idx = 0; task->default_expanded = t->default_expanded; + task->force_expanded = 1; } } scratch_end(scratch); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 940ce350..f6998517 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3100,6 +3100,10 @@ rd_view_ui(Rng2F32 rect) { any_edits_started = 1; String8 string = cell->edit_string; + if(string.size == 0) + { + string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + } string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; U64 hash = ev_hash_from_key(pt.key); From 7946e938c0b8a3f8833ea8e68302313e4b1c309e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:46:03 -0700 Subject: [PATCH 413/755] raw -> walk chain of overridden irtrees, since we want to strip 100% of all overrides/hooks/etc. --- src/eval/eval_ir.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 666ae0ee..e485a923 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1599,6 +1599,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(e_ir_state->overridden_irtree != 0) { result = *e_ir_state->overridden_irtree; + for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + { + result = *prev; + } } else { @@ -1641,6 +1645,10 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(e_ir_state->overridden_irtree != 0) { result = *e_ir_state->overridden_irtree; + for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + { + result = *prev; + } } else { From 0ce9925ba6e6dbb0fbae545cca8ee0bd43e39c4e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 11:54:55 -0700 Subject: [PATCH 414/755] pipe through parent expression string info through expr -> string generation path, so we can correctly generate standalone expression strings in the presence of $ (parent shortcuts) --- src/eval/eval_ir.c | 8 ++++---- src/eval/eval_parse.c | 19 +++++++++++++------ src/eval/eval_parse.h | 4 ++-- src/eval/eval_types.c | 2 +- src/raddbg/raddbg_core.c | 6 +++--- src/raddbg/raddbg_views.c | 4 ++-- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e485a923..48387207 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2620,7 +2620,7 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); - lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->string = e_string_from_expr(arena, lhs, str8_zero()); lhs_bytecode->qualifier = lhs->qualifier; lhs_bytecode->space = lhs->space; lhs_bytecode->mode = lhs_irtree->mode; @@ -2639,7 +2639,7 @@ e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); - lhs_bytecode->string = e_string_from_expr(arena, lhs); + lhs_bytecode->string = e_string_from_expr(arena, lhs, str8_zero()); lhs_bytecode->qualifier = lhs->qualifier; lhs_bytecode->space = lhs->space; lhs_bytecode->mode = lhs_irtree->mode; @@ -2658,7 +2658,7 @@ e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree) E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0); E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); - rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->string = e_string_from_expr(arena, rhs, str8_zero()); rhs_bytecode->space = rhs->space; rhs_bytecode->mode = rhs_irtree->mode; rhs_bytecode->type_key = rhs_irtree->type_key; @@ -2673,7 +2673,7 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type E_Expr *root = e_push_expr(arena, E_ExprKind_Cast, 0); E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); - rhs_bytecode->string = e_string_from_expr(arena, rhs); + rhs_bytecode->string = e_string_from_expr(arena, rhs, str8_zero()); rhs_bytecode->space = rhs->space; rhs_bytecode->mode = rhs_irtree->mode; rhs_bytecode->type_key = rhs_irtree->type_key; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 9c353772..77ce10ff 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -483,7 +483,7 @@ e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr) //~ rjf: Expression Tree -> String Conversions internal void -e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) +e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string, String8List *out) { switch(expr->kind) { @@ -518,7 +518,7 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) { str8_list_pushf(arena, out, "("); } - e_append_strings_from_expr(arena, child, out); + e_append_strings_from_expr(arena, child, parent_expr_string, out); if(need_parens) { str8_list_pushf(arena, out, ")"); @@ -528,7 +528,14 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) case E_ExprKind_LeafBytecode: case E_ExprKind_LeafIdentifier: { - str8_list_push(arena, out, expr->string); + if(str8_match(expr->string, str8_lit("$"), 0) && parent_expr_string.size != 0) + { + str8_list_push(arena, out, parent_expr_string); + } + else + { + str8_list_push(arena, out, expr->string); + } }break; case E_ExprKind_LeafStringLiteral: { @@ -561,16 +568,16 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) }break; case E_ExprKind_Ref: { - e_append_strings_from_expr(arena, expr->ref, out); + e_append_strings_from_expr(arena, expr->ref, parent_expr_string, out); }break; } } internal String8 -e_string_from_expr(Arena *arena, E_Expr *expr) +e_string_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string) { String8List strings = {0}; - e_append_strings_from_expr(arena, expr, &strings); + e_append_strings_from_expr(arena, expr, parent_expr_string, &strings); String8 result = str8_list_join(arena, &strings, 0); return result; } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 84f26343..3a11affb 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -79,8 +79,8 @@ internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr); //////////////////////////////// //~ rjf: Expression Tree -> String Conversions -internal void e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out); -internal String8 e_string_from_expr(Arena *arena, E_Expr *expr); +internal void e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string, String8List *out); +internal String8 e_string_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string); //////////////////////////////// //~ rjf: Parsing Functions diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 3135aea8..cb603c39 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1741,7 +1741,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_push(arena, out, direct_string); for EachIndex(idx, type->count) { - String8 string = e_string_from_expr(arena, type->args[idx]); + String8 string = e_string_from_expr(arena, type->args[idx], str8_zero()); str8_list_pushf(arena, out, ", "); str8_list_push(arena, out, string); } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f6998517..2b2a8367 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2183,7 +2183,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) args_count = type->count; } RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replace(expr_root, e_string_from_expr(scratch.arena, primary_expr)); + rd_cfg_new_replace(expr_root, e_string_from_expr(scratch.arena, primary_expr, str8_zero())); { U64 unnamed_order_idx = 0; for EachIndex(arg_idx, args_count) @@ -2216,7 +2216,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) unnamed_order_idx += 1; } RD_Cfg *arg_root = rd_cfg_child_from_string_or_alloc(view, param_name); - rd_cfg_new_replace(arg_root, e_string_from_expr(scratch.arena, arg_expr)); + rd_cfg_new_replace(arg_root, e_string_from_expr(scratch.arena, arg_expr, str8_zero())); } } } @@ -4495,7 +4495,7 @@ rd_view_ui(Rng2F32 rect) cell->eval.space.kind == E_SpaceKind_File || cell->eval.space.kind == E_SpaceKind_Null) { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell->eval.expr)) + RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell->eval.expr, e_string_from_expr(scratch.arena, row->eval.expr, str8_zero()))) rd_drag_begin(RD_RegSlot_Expr); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 28cc000d..6fa29632 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1615,13 +1615,13 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: default case -> just walk the expression tree & generate a string default: { - expr_string = e_string_from_expr(arena, notable_expr); + expr_string = e_string_from_expr(arena, notable_expr, str8_zero()); }break; // rjf: array indices -> fast path to [index] case E_ExprKind_ArrayIndex: { - expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last)); + expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero())); }break; // rjf: member accesses -> fast-path to .name From 20ba4a6af9e1b561f6de70ddcc227bd5339aa32c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 14:57:31 -0700 Subject: [PATCH 415/755] dead code elimination, user/project setting evaluation, work on color view ui --- src/dbg_engine/dbg_engine.mdesk | 43 +--- src/dbg_engine/dbg_engine_core.c | 61 ------ src/dbg_engine/dbg_engine_core.h | 47 ----- src/dbg_engine/generated/dbg_engine.meta.c | 28 --- src/dbg_engine/generated/dbg_engine.meta.h | 26 --- src/mule/mule_main.cpp | 3 + src/raddbg/generated/raddbg.meta.c | 10 +- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 99 ++------- src/raddbg/raddbg_core.c | 99 ++++++--- src/raddbg/raddbg_views.c | 224 +++++++++++++++------ src/raddbg/raddbg_views.h | 5 +- src/raddbg/raddbg_widgets.c | 17 ++ src/ui/ui_basic_widgets.c | 4 +- 14 files changed, 283 insertions(+), 387 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index cef6e19f..2871eca7 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -26,7 +26,7 @@ D_CmdTable: // | | | {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {RunToLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } @@ -59,47 +59,6 @@ D_CmdTable: // | | | COUNT, } -//////////////////////////////// -//~ rjf: Built-In VieNull w Rules - -@table(coverage_check name name_lower string ih ex xp vb display_name docs schema description) -D_ViewRuleTable: -{ - {x Default default "default" - - - x "Default" - "" "" } - {x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } - {x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." } - {- List list "list" - - - x "List" - "x:{member}" "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." } - {x ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed." } - {x Cast cast "cast" - - x - "Cast" x "x:{type}" "Specifies that the expression to which the view rule is applied should be casted to the provided type." } - {- BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "" "Specifies that all integral evaluations should appear in base-10 form." } - {- BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "" "Specifies that all integral evaluations should appear in base-2 form." } - {- BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "" "Specifies that all integral evaluations should appear in base-8 form." } - {- BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "" "Specifies that all integral evaluations should appear in base-16 form." } - {- Only only "only" x - - x "Only Specified Members" x "x:{member}" "Specifies that only the specified members should appear in struct, union, or class evaluations." } - {- Omit omit "omit" x - - x "Omit Specified Members" x "x:{member}" "Omits a list of member names from appearing in struct, union, or class evaluations." } - {- NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "" "Displays only what pointers point to, if possible, without the pointer's address value." } - {x Checkbox checkbox "checkbox" - - - - "Checkbox" x "" "Displays simple integer values as checkboxes, encoding zero or nonzero values." } - {- ColorRGBA color_rgba "color_rgba" - x - x "Color (RGBA)" x "" "Displays as a color, interpreting the data as encoding R, G, B, and A values." } - {x Text text "text" - x - x "Text" x "x:{'lang':lang, 'size':expr}" "Displays as text." } - {x Disasm disasm "disasm" - x - x "Disassembly" x "x:{'arch':arch, 'size':expr}" "Displays as disassembled instructions, interpreting the data as raw machine code." } - {x Memory memory "memory" - x - x "Memory" x "x:{'size':expr}" "Displays as a raw memory grid." } - {- Graph graph "graph" - x - x "Graph" x "" "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." } - {x Bitmap bitmap "bitmap" - x - x "Bitmap" x "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" "Displays as a bitmap, interpreting the data as raw pixel data." } - {- Geo3D geo3d "geo3d" - x - x "Geometry (3D)" x "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" "Displays as geometry, interpreting the data as index or vertex data." } -} - -@enum D_ViewRuleKind: -{ - @expand(D_ViewRuleTable a) `$(a.name)`, - COUNT, -} - -@data(D_ViewRuleSpecInfo) @c_file d_core_view_rule_spec_info_table: -{ - @expand(D_ViewRuleTable a) - ```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.description)"), (D_ViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(D_ViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(D_ViewRuleSpecInfoFlag_ExprResolution*$(a.xp == "x"))|(D_ViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), }```; -} - //////////////////////////////// //~ rjf: Developer Toggles diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index dea8294e..2915cbc1 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -196,59 +196,6 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams * cmds->count += 1; } -//////////////////////////////// -//~ rjf: View Rule Spec Stateful Functions - -internal void -d_register_view_rule_specs(D_ViewRuleSpecInfoArray specs) -{ - for(U64 idx = 0; idx < specs.count; idx += 1) - { - // rjf: extract info from array slot - D_ViewRuleSpecInfo *info = &specs.v[idx]; - - // rjf: skip empties - if(info->string.size == 0) - { - continue; - } - - // rjf: determine hash/slot - U64 hash = d_hash_from_string(info->string); - U64 slot_idx = hash%d_state->view_rule_spec_table_size; - - // rjf: allocate node & push - D_ViewRuleSpec *spec = push_array(d_state->arena, D_ViewRuleSpec, 1); - SLLStackPush_N(d_state->view_rule_spec_table[slot_idx], spec, hash_next); - - // rjf: fill node - D_ViewRuleSpecInfo *info_copy = &spec->info; - MemoryCopyStruct(info_copy, info); - info_copy->string = push_str8_copy(d_state->arena, info->string); - info_copy->display_string = push_str8_copy(d_state->arena, info->display_string); - info_copy->description = push_str8_copy(d_state->arena, info->description); - } -} - -internal D_ViewRuleSpec * -d_view_rule_spec_from_string(String8 string) -{ - D_ViewRuleSpec *spec = &d_nil_core_view_rule_spec; - { - U64 hash = d_hash_from_string(string); - U64 slot_idx = hash%d_state->view_rule_spec_table_size; - for(D_ViewRuleSpec *s = d_state->view_rule_spec_table[slot_idx]; s != 0; s = s->hash_next) - { - if(str8_match(string, s->info.string, 0)) - { - spec = s; - break; - } - } - } - return spec; -} - //////////////////////////////// //~ rjf: Stepping "Trap Net" Builders @@ -1668,16 +1615,8 @@ d_init(void) hs_submit_data(d_state->output_log_key, 0, str8_zero()); d_state->ctrl_entity_store = ctrl_entity_store_alloc(); d_state->ctrl_stop_arena = arena_alloc(); - d_state->view_rule_spec_table_size = 1024; - d_state->view_rule_spec_table = push_array(arena, D_ViewRuleSpec *, d_state->view_rule_spec_table_size); d_state->ctrl_msg_arena = arena_alloc(); - // rjf: register core view rules - { - D_ViewRuleSpecInfoArray array = {d_core_view_rule_spec_info_table, ArrayCount(d_core_view_rule_spec_info_table)}; - d_register_view_rule_specs(array); - } - // rjf: set up caches d_state->unwind_cache.slots_count = 1024; d_state->unwind_cache.slots = push_array(arena, D_UnwindCacheSlot, d_state->unwind_cache.slots_count); diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 4efc7234..ff4b0fc3 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -169,42 +169,6 @@ D_RunKind; #include "dbg_engine/generated/dbg_engine.meta.h" -//////////////////////////////// -//~ rjf: View Rules - -typedef U32 D_ViewRuleSpecInfoFlags; // NOTE(rjf): see @view_rule_info -enum -{ - D_ViewRuleSpecInfoFlag_Inherited = (1<<0), - D_ViewRuleSpecInfoFlag_Expandable = (1<<1), - D_ViewRuleSpecInfoFlag_ExprResolution = (1<<2), - D_ViewRuleSpecInfoFlag_VizBlockProd = (1<<3), -}; - -typedef struct D_ViewRuleSpecInfo D_ViewRuleSpecInfo; -struct D_ViewRuleSpecInfo -{ - String8 string; - String8 display_string; - String8 schema; - String8 description; - D_ViewRuleSpecInfoFlags flags; -}; - -typedef struct D_ViewRuleSpecInfoArray D_ViewRuleSpecInfoArray; -struct D_ViewRuleSpecInfoArray -{ - D_ViewRuleSpecInfo *v; - U64 count; -}; - -typedef struct D_ViewRuleSpec D_ViewRuleSpec; -struct D_ViewRuleSpec -{ - D_ViewRuleSpec *hash_next; - D_ViewRuleSpecInfo info; -}; - //////////////////////////////// //~ rjf: Command Types @@ -363,10 +327,6 @@ struct D_State D_RunLocalsCache member_caches[2]; U64 member_cache_gen; - // rjf: view rule specification table - U64 view_rule_spec_table_size; - D_ViewRuleSpec **view_rule_spec_table; - // rjf: user -> ctrl driving state Arena *ctrl_last_run_arena; D_RunKind ctrl_last_run_kind; @@ -391,7 +351,6 @@ struct D_State //////////////////////////////// //~ rjf: Globals -read_only global D_ViewRuleSpec d_nil_core_view_rule_spec = {0}; global D_State *d_state = 0; //////////////////////////////// @@ -426,12 +385,6 @@ internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src); //- rjf: command lists internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params); -//////////////////////////////// -//~ rjf: View Rule Spec Stateful Functions - -internal void d_register_view_rule_specs(D_ViewRuleSpecInfoArray specs); -internal D_ViewRuleSpec *d_view_rule_spec_from_string(String8 string); - //////////////////////////////// //~ rjf: Stepping "Trap Net" Builders diff --git a/src/dbg_engine/generated/dbg_engine.meta.c b/src/dbg_engine/generated/dbg_engine.meta.c index 6d096e0b..3d32a4c2 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.c +++ b/src/dbg_engine/generated/dbg_engine.meta.c @@ -3,31 +3,3 @@ //- GENERATED CODE -C_LINKAGE_BEGIN -D_ViewRuleSpecInfo d_core_view_rule_spec_info_table[21] = -{ -{str8_lit_comp("default"), str8_lit_comp("Default"), str8_lit_comp(""), str8_lit_comp(""), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("x:{expr}"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("slice"), str8_lit_comp("Slice"), str8_lit_comp(""), str8_lit_comp("Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("cast"), str8_lit_comp("Cast"), str8_lit_comp("x:{type}"), str8_lit_comp("Specifies that the expression to which the view rule is applied should be casted to the provided type."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("bin"), str8_lit_comp("Binary Base (Base 2)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-2 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("oct"), str8_lit_comp("Octal Base (Base 8)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-8 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("hex"), str8_lit_comp("Hexadecimal Base (Base 16)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-16 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("only"), str8_lit_comp("Only Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that only the specified members should appear in struct, union, or class evaluations."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("omit"), str8_lit_comp("Omit Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Omits a list of member names from appearing in struct, union, or class evaluations."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("no_addr"), str8_lit_comp("Disable Address Values"), str8_lit_comp(""), str8_lit_comp("Displays only what pointers point to, if possible, without the pointer's address value."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("checkbox"), str8_lit_comp("Checkbox"), str8_lit_comp(""), str8_lit_comp("Displays simple integer values as checkboxes, encoding zero or nonzero values."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), }, -{str8_lit_comp("color_rgba"), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), str8_lit_comp("Displays as a color, interpreting the data as encoding R, G, B, and A values."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("text"), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), str8_lit_comp("Displays as text."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr}"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("memory"), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), str8_lit_comp("Displays as a raw memory grid."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("graph"), str8_lit_comp("Graph"), str8_lit_comp(""), str8_lit_comp("Displays as a pointer graph, visualizing nodes and edges formed by pointers directly."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -{str8_lit_comp("geo3d"), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), str8_lit_comp("Displays as geometry, interpreting the data as index or vertex data."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), }, -}; - -C_LINKAGE_END - diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index 9efa15b8..8451a246 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -44,32 +44,6 @@ D_CmdKind_Attach, D_CmdKind_COUNT, } D_CmdKind; -typedef enum D_ViewRuleKind -{ -D_ViewRuleKind_Default, -D_ViewRuleKind_Array, -D_ViewRuleKind_Slice, -D_ViewRuleKind_List, -D_ViewRuleKind_ByteSwap, -D_ViewRuleKind_Cast, -D_ViewRuleKind_BaseDec, -D_ViewRuleKind_BaseBin, -D_ViewRuleKind_BaseOct, -D_ViewRuleKind_BaseHex, -D_ViewRuleKind_Only, -D_ViewRuleKind_Omit, -D_ViewRuleKind_NoAddr, -D_ViewRuleKind_Checkbox, -D_ViewRuleKind_ColorRGBA, -D_ViewRuleKind_Text, -D_ViewRuleKind_Disasm, -D_ViewRuleKind_Memory, -D_ViewRuleKind_Graph, -D_ViewRuleKind_Bitmap, -D_ViewRuleKind_Geo3D, -D_ViewRuleKind_COUNT, -} D_ViewRuleKind; - global B32 DEV_simulate_lag = 0; global B32 DEV_draw_ui_text_pos = 0; global B32 DEV_draw_ui_focus_debug = 0; diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 3e1d6cfe..c13ff6e3 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1701,6 +1701,9 @@ fancy_viz_eval_tests(void) unsigned int example_color_u32 = 0xff6f30ff; struct {float r, g, b, a;} example_color_struct = {0.50f, 0.95f, 0.75f, 1.00f}; int x0 = 0; + raddbg_pin(color(example_color_4f32)); + raddbg_pin(color(example_color_u32)); + raddbg_pin(color(example_color_struct)); //- rjf: multiline text char *long_string = ("This is an example of some very long text with line breaks\n" diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 26e9411e..b1098360 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[314] = +RD_VocabInfo rd_vocab_info_table[315] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -110,6 +110,7 @@ RD_VocabInfo rd_vocab_info_table[314] = {str8_lit_comp("font_size"), str8_lit_comp(""), str8_lit_comp("Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("row_height"), str8_lit_comp(""), str8_lit_comp("Row Height"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_height"), str8_lit_comp(""), str8_lit_comp("Tab Height"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("rgba"), str8_lit_comp(""), str8_lit_comp("RGBA"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -322,9 +323,10 @@ RD_VocabInfo rd_vocab_info_table[314] = {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; -RD_NameSchemaInfo rd_name_schema_info_table[20] = +RD_NameSchemaInfo rd_name_schema_info_table[21] = { -{str8_lit_comp("settings"), str8_lit_comp("x:\n{\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n @default(1) 'background_blur': bool,\n @default(1) 'thread_lines': bool,\n @default(1) 'breakpoint_lines': bool,\n @default(1) 'thread_glow': bool,\n @default(1) 'breakpoint_glow': bool,\n @default(0) 'opaque_backgrounds': bool,\n @default(1) 'smooth_ui_text': bool,\n @default(0) 'smooth_code_text': bool,\n @default(1) 'hint_ui_text': bool,\n @default(1) 'hint_code_text': bool,\n @default(2) 'tab_width': @range[1, 32] u64,\n @default(11) 'font_size': @range[6, 72] u64,\n @default(3.f) 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, @@ -409,7 +411,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index aad7975e..c0be4d39 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -640,8 +640,8 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[314]; -extern RD_NameSchemaInfo rd_name_schema_info_table[20]; +extern RD_VocabInfo rd_vocab_info_table[315]; +extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 53625ffa..66467e5c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -123,6 +123,7 @@ RD_VocabTable: {font_size "" "Font Size" "" Null } {row_height "" "Row Height" "" Null } {tab_height "" "Tab Height" "" Null } + {rgba "" "RGBA" "" Palette } } @struct RD_VocabInfo: @@ -146,31 +147,22 @@ RD_VocabTable: @table(name schema) RD_SchemaTable: { - //- rjf: settings + //- rjf: users / projects { - settings, - ```x: + user + ``` + x: { - @default(1) 'hover_animations': bool, - @default(1) 'press_animations': bool, - @default(0) 'focus_animations': bool, - @default(1) 'tooltip_animations': bool, - @default(1) 'menu_animations': bool, - @default(1) 'scrolling_animations': bool, - @default(1) 'background_blur': bool, - @default(1) 'thread_lines': bool, - @default(1) 'breakpoint_lines': bool, - @default(1) 'thread_glow': bool, - @default(1) 'breakpoint_glow': bool, - @default(0) 'opaque_backgrounds': bool, - @default(1) 'smooth_ui_text': bool, - @default(0) 'smooth_code_text': bool, - @default(1) 'hint_ui_text': bool, - @default(1) 'hint_code_text': bool, - @default(2) 'tab_width': @range[1, 32] u64, - @default(11) 'font_size': @range[6, 72] u64, - @default(3.f) 'row_height': @range[1.75f, 5.f] f32, - @default(3.f) 'tab_height': @range[1.75f, 5.f] f32, + @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64, + } + ``` + } + { + project + ``` + x: + { + @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, } ``` } @@ -1102,67 +1094,6 @@ RD_IconTable: @expand(RD_IconTable a) `str8_lit_comp("$(a.text)")`; } -//////////////////////////////// -//~ rjf: View Rules - -@table(name name_lower display_name params_schema icon can_filter filter_is_code typing_automatically_filters can_use_in_watch_table can_fill_value_cell can_expand show_in_docs description) -RD_ViewRuleTable: -{ - //- rjf: basics - { Empty empty "" "" Null 0 0 0 0 0 0 0 "" } - { GettingStarted getting_started "Getting Started" "" QuestionMark 0 0 0 0 0 0 0 "" } - - //- rjf: meta (settings) - { Settings settings "Settings" "" Gear 0 0 0 0 0 0 1 "An interface to modify general settings for the debugger's appearance and behavior." } - - //- rjf: temporary view for loading files - must analyze file before picking viewer - { PendingFile pending_file "Pending File" "" FileOutline 0 0 0 0 0 0 0 "" } - - //- rjf: visualizers - { Watch watch "Watch" "" Binoculars 1 1 1 0 0 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } - { Text text "Text" "x:{'lang':lang, 'size':expr}" FileOutline 0 0 0 1 0 1 0 "" } - { Disasm disasm "Disassembly" "x:{'arch':arch, 'size':expr, 'addresses':bool, 'code_bytes':bool}" Glasses 0 0 0 1 0 1 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } - { Memory memory "Memory" "x:{'size':expr}" Grid 0 0 0 1 0 1 1 "A hex-editor-like grid interface for viewing memory." } - { Bitmap bitmap "Bitmap" "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as a bitmap." } - { Checkbox checkbox "Checkbox" "" CheckFilled 0 0 0 1 1 0 1 "Visualizes memory as an RGBA color." } - { ColorRGBA color_rgba "Color (RGBA)" "" Palette 0 0 0 1 1 1 1 "Visualizes memory as an RGBA color." } - { Geo3D geo3d "Geometry (3D)" "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" Binoculars 0 0 0 1 0 1 1 "Visualizes memory as 3D geometry." } -} - -/* -@enum RD_ViewRuleKind: -{ - Null, - @expand(RD_ViewRuleTable a) `$(a.name)`, - COUNT -} - -@struct RD_ViewRuleInfo: -{ - `String8 string`; - `String8 description`; - `String8 display_name`; - `String8 params_schema`; - `RD_IconKind icon_kind`; - `RD_ViewRuleInfoFlags flags`; - `EV_ExpandRuleInfoHookFunctionType *expr_expand_info`; - `RD_ViewRuleUIFunctionType *ui`; -} - -@gen -{ - `RD_VIEW_RULE_UI_FUNCTION_DEF(null);`, - @expand(RD_ViewRuleTable a) `$(a.can_use_in_watch_table != 0 && a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`, - @expand(RD_ViewRuleTable a) `RD_VIEW_RULE_UI_FUNCTION_DEF($(a.name_lower));`, -} - -@data(RD_ViewRuleInfo) rd_view_rule_kind_info_table: -{ - `{{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), RD_VIEW_RULE_UI_FUNCTION_NAME(null)}`, - @expand(RD_ViewRuleTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.description)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.params_schema)"), RD_IconKind_$(a.icon), (RD_ViewRuleInfoFlag_ShowInDocs*$(a.show_in_docs)|RD_ViewRuleInfoFlag_CanFilter*$(a.can_filter)|RD_ViewRuleInfoFlag_FilterIsCode*$(a.filter_is_code)|RD_ViewRuleInfoFlag_TypingAutomaticallyFilters*$(a.typing_automatically_filters)|RD_ViewRuleInfoFlag_CanUseInWatchTable*$(a.can_use_in_watch_table)|RD_ViewRuleInfoFlag_CanFillValueCell*$(a.can_fill_value_cell)|RD_ViewRuleInfoFlag_CanExpand*$(a.can_expand)), $(a.can_expand != 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(" .. a.name_lower .. ")") $(a.can_expand == 0 -> "EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil)"), RD_VIEW_RULE_UI_FUNCTION_NAME($(a.name_lower))}`, -} -*/ - //////////////////////////////// //~ rjf: Theme Tables diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2b2a8367..9f8d4d0b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1176,17 +1176,9 @@ rd_setting_from_name(String8 name) { String8 result = {0}; { - // rjf: find most-granular config scope to begin looking for the setting + // rjf: find most-granular config scopes to begin looking for the setting RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *start_cfg = view_cfg; - for(RD_Cfg *p = start_cfg->parent; p != &rd_nil_cfg; p = p->parent) - { - if(str8_match(p->string, str8_lit("transient"), 0)) - { - start_cfg = &rd_nil_cfg; - break; - } - } + RD_Cfg *start_cfg = &rd_nil_cfg; if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->panel); } if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } @@ -1200,23 +1192,27 @@ rd_setting_from_name(String8 name) // rjf: return resultant child string stored under this key result = setting->first->string; - // rjf: no result -> look for default in settings + // rjf: no result -> look for default in schemas if(result.size == 0) ProfScope("default setting schema lookup") { - Temp scratch = scratch_begin(0, 0); - String8 schema_names[] = + MD_Node *schema = &md_nil_node; { - view_cfg->string, - str8_lit("settings"), - }; - for EachElement(idx, schema_names) - { - MD_NodePtrList schemas = rd_schemas_from_name(schema_names[idx]); - for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) + MD_NodePtrList schemas = rd_schemas_from_name(view_cfg->string); + for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next) { - MD_Node *schema = n->v; - MD_Node *setting = md_child_from_string(schema, name, 0); - MD_Node *default_tag = md_tag_from_string(setting, str8_lit("default"), 0); + schema = md_child_from_string(n->v, name, 0); + } + for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && schema == &md_nil_node; cfg = cfg->parent) + { + MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); + for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next) + { + schema = md_child_from_string(n->v, name, 0); + } + } + if(schema != &md_nil_node) + { + MD_Node *default_tag = md_tag_from_string(schema, str8_lit("default"), 0); if(default_tag != &md_nil_node) { result = default_tag->first->string; @@ -1225,7 +1221,6 @@ rd_setting_from_name(String8 name) } } end_default_search:; - scratch_end(scratch); } } return result; @@ -2990,6 +2985,19 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); rd_cmd(RD_CmdKind_CompleteQuery, .cfg = cfg->id); }break; + case RD_EvalSpaceKind_MetaCtrlEntity: + { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + RD_RegsScope(.ctrl_entity = entity->handle) + { + if(0){} + else if(entity->kind == CTRL_EntityKind_Thread) { rd_regs()->thread = entity->handle; } + else if(entity->kind == CTRL_EntityKind_Module) { rd_regs()->module = entity->handle; } + else if(entity->kind == CTRL_EntityKind_Process) { rd_regs()->process = entity->handle; } + else if(entity->kind == CTRL_EntityKind_Machine) { rd_regs()->machine = entity->handle; } + rd_cmd(RD_CmdKind_CompleteQuery); + } + }break; case RD_EvalSpaceKind_MetaUnattachedProcess: { U64 pid = eval.value.u128.u64[0]; @@ -4725,7 +4733,11 @@ rd_view_ui(Rng2F32 rect) RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = expr_eval.irtree.prev; + e_ir_state->overridden_irtree = &expr_eval.irtree; + for(E_IRTreeAndType *prev = expr_eval.irtree.prev; prev != 0; prev = prev->prev) + { + e_ir_state->overridden_irtree = prev; + } view_ui_rule->ui(expr_eval, rect); e_ir_state->overridden_irtree = prev_overridden_irtree; scratch_end(scratch); @@ -12100,6 +12112,26 @@ rd_frame(void) } } + //- rjf: add macros for user/project + { + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("user")); + E_Space space = rd_eval_space_from_cfg(rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("user_settings"), expr); + } + { + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("project")); + E_Space space = rd_eval_space_from_cfg(rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project"))); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("project_settings"), expr); + } + //- rjf: add macros for evallable control entities String8 evallable_ctrl_names[] = { @@ -12479,8 +12511,7 @@ rd_frame(void) {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, {str8_lit("bitmap"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("color"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(color), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color)}, {str8_lit("geo3d"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; @@ -12639,7 +12670,19 @@ rd_frame(void) //- rjf: open lister case RD_CmdKind_OpenLister: { - String8 expr = push_str8f(scratch.arena, "query:commands, query:$%I64x, query:$%I64x, query:recent_files, query:recent_projects, query:procedures, query:processes, query:threads, query:modules", rd_regs()->view, rd_regs()->window); + String8 expr = push_str8f(scratch.arena, + "query:commands, " + "query:$%I64x, " + "query:$%I64x, " + "query:recent_files, " + "query:recent_projects, " + "query:procedures, " + "query:processes, " + "query:threads, " + "query:modules, " + "query:user_settings, " + "query:project_settings, ", + rd_regs()->view, rd_regs()->window); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1); }break; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 6fa29632..5df1ee41 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3307,7 +3307,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) //- rjf: image-region canvas interaction // Vec2S32 mouse_bmp = {-1, -1}; - if(ui_hovering(canvas_sig) && !ui_dragging(canvas_sig)) + if(ui_hovering(canvas_sig) && !ui_dragging(canvas_sig)) RD_Font(RD_FontSlot_Code) { Vec2F32 mouse_scr = sub_2f32(ui_mouse(), rect.p0); Vec2F32 mouse_cvs = rd_bitmap_canvas_from_screen_pos(view_center_pos, zoom, canvas_rect, mouse_scr); @@ -3380,43 +3380,118 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) } //////////////////////////////// -//~ rjf: "checkbox" +//~ rjf: rgba @view_hook_impl -RD_VIEW_UI_FUNCTION_DEF(checkbox) +typedef struct RD_EvalColor RD_EvalColor; +struct RD_EvalColor { - E_Eval value_eval = e_value_eval_from_eval(eval); - if(ui_clicked(rd_icon_buttonf(value_eval.value.u64 == 0 ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled, 0, "###check"))) - { - rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0")); - } -} + Vec4F32 rgba; + E_Eval rgba_evals[4]; +}; -//////////////////////////////// -//~ rjf: color_rgba @view_hook_impl - -internal Vec4F32 -rd_rgba_from_eval_params(E_Eval eval, MD_Node *params) +internal RD_EvalColor +rd_eval_color_from_eval(E_Eval eval) { - Vec4F32 rgba = {0}; + Temp scratch = scratch_begin(0, 0); + + //- rjf: walk eval's type tree, find all four component evaluations + E_Eval component_evals[4] = {0}; { - E_Eval value_eval = e_value_eval_from_eval(eval); - E_TypeKey type_key = eval.irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - U64 type_size = e_type_byte_size_from_key(type_key); - if(16 <= type_size) + typedef struct LeafTask LeafTask; + struct LeafTask { - e_space_read(eval.space, &rgba, r1u64(eval.value.u64, eval.value.u64 + 16)); - } - else if(4 <= type_size) + LeafTask *next; + E_Eval eval; + }; + U64 num_components_left = 4; + LeafTask start_task = {0, eval}; + LeafTask *first_task = &start_task; + LeafTask *last_task = first_task; + for(LeafTask *t = first_task; t != 0 && num_components_left > 0; t = t->next) { - U32 hex_val = value_eval.value.u32; - rgba = rgba_from_u32(hex_val); + E_Type *type = e_type_from_key__cached(e_type_key_unwrap(t->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + switch(type->kind) + { + default:{}break; + + // rjf: leaf u32 -> take all 4 components + case E_TypeKind_U32: + { + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x0000ff00) >> 8) / 255.f")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x000000ff) >> 0) / 255.f")); + num_components_left -= 4; + }break; + + //- rjf: array -> generate tasks for first four elements + case E_TypeKind_Array: + { + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[0])")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[1])")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[2])")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[3])")); + num_components_left -= 4; + }break; + } } } - return rgba; + + //- rjf: swizzle / extract the component values from the evals, depending on this lens + // (the lens implicitly tells us the format) + RD_EvalColor result = {0}; + { + E_Type *lens_type = e_type_from_key__cached(eval.irtree.type_key); + for(E_Type *t = lens_type; t->kind == E_TypeKind_Lens; t = e_type_from_key__cached(t->direct_type_key)) + { + if(str8_match(t->name, str8_lit("color"), 0)) + { + lens_type = t; + break; + } + } + if(lens_type->kind == E_TypeKind_Lens) + { + if(lens_type->count < 1 || str8_match(lens_type->args[0]->string, str8_lit("rgba"), 0)) + { + result.rgba_evals[0] = component_evals[0]; + result.rgba_evals[1] = component_evals[1]; + result.rgba_evals[2] = component_evals[2]; + result.rgba_evals[3] = component_evals[3]; + } + else if(str8_match(lens_type->args[0]->string, str8_lit("argb"), 0)) + { + result.rgba_evals[0] = component_evals[1]; + result.rgba_evals[1] = component_evals[2]; + result.rgba_evals[2] = component_evals[3]; + result.rgba_evals[3] = component_evals[0]; + } + else if(str8_match(lens_type->args[0]->string, str8_lit("bgra"), 0)) + { + result.rgba_evals[0] = component_evals[2]; + result.rgba_evals[1] = component_evals[1]; + result.rgba_evals[2] = component_evals[0]; + result.rgba_evals[3] = component_evals[3]; + } + else if(str8_match(lens_type->args[0]->string, str8_lit("abgr"), 0)) + { + result.rgba_evals[0] = component_evals[3]; + result.rgba_evals[1] = component_evals[2]; + result.rgba_evals[2] = component_evals[1]; + result.rgba_evals[3] = component_evals[0]; + } + for EachIndex(idx, 4) + { + result.rgba.v[idx] = e_value_eval_from_eval(result.rgba_evals[idx]).value.f32; + } + } + } + + scratch_end(scratch); + return result; } -EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba) +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color) { EV_ExpandInfo info = {0}; info.row_count = 8; @@ -3424,16 +3499,26 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba) return info; } -RD_VIEW_UI_FUNCTION_DEF(color_rgba) +RD_VIEW_UI_FUNCTION_DEF(color) { Temp scratch = scratch_begin(0, 0); Vec2F32 dim = dim_2f32(rect); F32 padding = ui_top_font_size()*3.f; - Vec4F32 rgba = {0}; // TODO(rjf): @cfg rd_rgba_from_eval_params(eval, params); + F32 sv_dim_px = Min(dim.x, dim.y); + if(sv_dim_px == dim.x) + { + padding = ui_top_font_size()*30.f; + } + sv_dim_px -= padding*2.f; + sv_dim_px = Min(sv_dim_px, ui_top_font_size()*70.f); + RD_EvalColor eval_color = rd_eval_color_from_eval(eval); + Vec4F32 rgba = eval_color.rgba; Vec4F32 hsva = hsva_from_rgba(rgba); + ////////////////////////////// //- rjf: too small -> just show components - if(dim.y <= ui_top_font_size()*8.f) + // + if(dim.y <= ui_top_font_size()*12.f) { //- rjf: build text box UI_Box *text_box = &ui_nil_box; @@ -3444,11 +3529,11 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) { DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("(")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = v4f32(1.f, 0.25f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = linear_from_srgba(v4f32(1.f, 0.25f, 0.25f, 1.f)), .underline_thickness = 4.f); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.y), .color = v4f32(0.25f, 1.f, 0.25f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.y), .color = linear_from_srgba(v4f32(0.25f, 1.f, 0.25f, 1.f)), .underline_thickness = 4.f); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.z), .color = v4f32(0.25f, 0.25f, 1.f, 1.f), .underline_thickness = 4.f); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.z), .color = linear_from_srgba(v4f32(0.25f, 0.25f, 1.f, 1.f)), .underline_thickness = 4.f); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.w), .color = v4f32(1.f, 1.f, 1.f, 1.f), .underline_thickness = 4.f); dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")")); @@ -3479,45 +3564,64 @@ RD_VIEW_UI_FUNCTION_DEF(color_rgba) } } + ////////////////////////////// //- rjf: large enough -> full color picker + // else { - UI_WidthFill UI_HeightFill UI_Column UI_Padding(ui_px(padding, 1.f)) UI_Row UI_Padding(ui_pct(1.f, 0.f)) UI_HeightFill + UI_WidthFill UI_HeightFill + UI_PrefHeight(ui_children_sum(1)) UI_Column UI_Padding(ui_pct(1.f, 0.f)) + UI_PrefHeight(ui_children_sum(1)) UI_Row UI_Padding(ui_pct(1.f, 0.f)) + UI_PrefWidth(ui_px(sv_dim_px, 1.f)) + UI_PrefHeight(ui_px(sv_dim_px, 1.f)) + RD_Font(RD_FontSlot_Code) { - UI_PrefWidth(ui_px(dim.y - padding*2, 1.f)) - { - UI_Signal sv_sig = ui_sat_val_pickerf(hsva.x, &hsva.y, &hsva.z, "sat_val_picker"); - } + UI_Signal sv_sig = ui_sat_val_pickerf(hsva.x, &hsva.y, &hsva.z, "sat_val_picker"); + ui_spacer(ui_em(1.f, 1.f)); UI_PrefWidth(ui_em(3.f, 1.f)) { UI_Signal h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); } - UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) - UI_TagF("weak") + ui_spacer(ui_em(1.f, 1.f)); + UI_PrefWidth(ui_children_sum(1)) UI_Column { - ui_labelf("Hex"); - ui_labelf("R"); - ui_labelf("G"); - ui_labelf("B"); - ui_labelf("H"); - ui_labelf("S"); - ui_labelf("V"); - ui_labelf("A"); - } - UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) - { - String8 hex_string = hex_string_from_rgba_4f32(scratch.arena, rgba); - ui_label(hex_string); - ui_labelf("%.2f", rgba.x); - ui_labelf("%.2f", rgba.y); - ui_labelf("%.2f", rgba.z); - ui_labelf("%.2f", hsva.x); - ui_labelf("%.2f", hsva.y); - ui_labelf("%.2f", hsva.z); - ui_labelf("%.2f", rgba.w); + UI_PrefWidth(ui_em(6.f, 0.f)) UI_PrefHeight(ui_em(6.f, 0.f)) + UI_BackgroundColor(linear_from_srgba(v4f32(rgba.x, rgba.y, rgba.z, 1.f))) + UI_CornerRadius(4.f) + UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) + ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); + ui_spacer(ui_em(2.f, 1.f)); + UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_children_sum(1)) UI_Row + { + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) + UI_TagF("weak") + { + ui_labelf("Hex"); + ui_labelf("R"); + ui_labelf("G"); + ui_labelf("B"); + ui_labelf("H"); + ui_labelf("S"); + ui_labelf("V"); + ui_labelf("A"); + } + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_PrefHeight(ui_em(2.f, 0.f)) RD_Font(RD_FontSlot_Code) + { + String8 hex_string = hex_string_from_rgba_4f32(scratch.arena, rgba); + ui_label(hex_string); + ui_labelf("%.2f", rgba.x); + ui_labelf("%.2f", rgba.y); + ui_labelf("%.2f", rgba.z); + ui_labelf("%.2f", hsva.x); + ui_labelf("%.2f", hsva.y); + ui_labelf("%.2f", hsva.z); + ui_labelf("%.2f", rgba.w); + } + } } } } + scratch_end(scratch); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index fa974618..b0971bfb 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -245,15 +245,14 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(text); EV_EXPAND_RULE_INFO_FUNCTION_DEF(disasm); EV_EXPAND_RULE_INFO_FUNCTION_DEF(memory); EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap); -EV_EXPAND_RULE_INFO_FUNCTION_DEF(color_rgba); +EV_EXPAND_RULE_INFO_FUNCTION_DEF(color); EV_EXPAND_RULE_INFO_FUNCTION_DEF(geo3d); RD_VIEW_UI_FUNCTION_DEF(text); RD_VIEW_UI_FUNCTION_DEF(disasm); RD_VIEW_UI_FUNCTION_DEF(memory); RD_VIEW_UI_FUNCTION_DEF(bitmap); -RD_VIEW_UI_FUNCTION_DEF(checkbox); -RD_VIEW_UI_FUNCTION_DEF(color_rgba); +RD_VIEW_UI_FUNCTION_DEF(color); RD_VIEW_UI_FUNCTION_DEF(geo3d); #endif // RADDBG_VIEWS_H diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 38ded76d..cf646c23 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -129,6 +129,23 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } } + //- rjf: push bucket name + if(cfg->parent == rd_state->root_cfg) + { + if(str8_match(cfg->string, str8_lit("user"), 0)) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("User"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + else if(str8_match(cfg->string, str8_lit("project"), 0)) + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("Project"), .font = rd_font_from_slot(RD_FontSlot_Main), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Main)); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + start_secondary(); + } + } + //- rjf: push label if(label_string.size != 0) { diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index c216d7b1..c2e8c2e7 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -479,7 +479,7 @@ ui_do_color_tooltip_hsv(Vec3F32 hsv) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_BackgroundColor(v4f32(rgb.x, rgb.y, rgb.z, 1.f)) + UI_BackgroundColor(linear_from_srgba(v4f32(rgb.x, rgb.y, rgb.z, 1.f))) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); @@ -518,7 +518,7 @@ ui_do_color_tooltip_hsva(Vec4F32 hsva) { UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) UI_Row UI_Padding(ui_pct(1, 0)) { - UI_BackgroundColor(rgba) + UI_BackgroundColor(linear_from_srgba(rgba)) UI_CornerRadius(4.f) UI_PrefWidth(ui_em(6.f, 1.f)) UI_PrefHeight(ui_em(6.f, 1.f)) ui_build_box_from_string(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, str8_lit("")); From a5c68412fcb349e78db6f3c11233bc0c441cfcd9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 15:23:49 -0700 Subject: [PATCH 416/755] further work/convergence on cell rendering / listers --- src/raddbg/generated/raddbg.meta.c | 8 ++--- src/raddbg/raddbg.mdesk | 48 +++++++++++++++++------------- src/raddbg/raddbg_eval.c | 1 + src/raddbg/raddbg_views.c | 1 + 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b1098360..897f7a32 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -325,13 +325,13 @@ RD_VocabInfo rd_vocab_info_table[315] = RD_NameSchemaInfo rd_name_schema_info_table[21] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n @default(0) @display_name('Transient') 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) 'show_addresses': bool,\n @default(0) 'show_code_bytes': bool,\n @default(1) 'show_source_lines': bool,\n @default(1) 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 66467e5c..928c37ce 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -153,6 +153,23 @@ RD_VocabTable: ``` x: { + //- rjf: thread & breakpoint decorations + @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") + 'thread_lines': bool, + @default(1) @display_name('Thread Glow') @description("Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.") + 'thread_glow': bool, + @default(1) @display_name('Breakpoint Lines') @description("Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.") + 'breakpoint_lines': bool, + @default(1) @display_name('Breakpoint Glow') @description("Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.") + 'breakpoint_glow': bool, + + //- rjf: occluding background settings + @default(0) @display_name('Opaque Backgrounds') @description("Controls whether or not all floating background colors are forced to be fully opaque.") + 'opaque_backgrounds': bool, + @default(1) @display_name('Background Blur') @description("Controls whether or not occluded regions behind floating elements are blurred.") + 'background_blur': bool, + + //- rjf: code formatting settings @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64, } ``` @@ -181,22 +198,6 @@ RD_VocabTable: @default(1) 'menu_animations': bool, @default(1) 'scrolling_animations': bool, - //- rjf: thread & breakpoint decorations - @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") - 'thread_lines': bool, - @default(1) @display_name('Thread Glow') @description("Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.") - 'thread_glow': bool, - @default(1) @display_name('Breakpoint Lines') @description("Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.") - 'breakpoint_lines': bool, - @default(1) @display_name('Breakpoint Glow') @description("Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.") - 'breakpoint_glow': bool, - - //- rjf: occluding background settings - @default(0) @display_name('Opaque Backgrounds') @description("Controls whether or not all floating background colors are forced to be fully opaque.") - 'opaque_backgrounds': bool, - @default(1) @display_name('Background Blur') @description("Controls whether or not occluded regions behind floating elements are blurred.") - 'background_blur': bool, - //- rjf: text rasterization settings @default(1) @display_name('Smooth UI Text') @description("Controls whether or not UI text is fully anti-aliased, for a smoother appearance.") 'smooth_ui_text': bool, @@ -247,7 +248,8 @@ RD_VocabTable: 'lang':lang, 'size':code_string, @default(1) 'show_line_numbers':bool, - @default(0) @display_name('Transient') 'auto': bool, + @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") + 'auto': bool, } ``` } @@ -259,10 +261,14 @@ RD_VocabTable: 'arch': arch, 'syntax': dasm_syntax, 'size': code_string, - @default(1) 'show_addresses': bool, - @default(0) 'show_code_bytes': bool, - @default(1) 'show_source_lines': bool, - @default(1) 'show_symbol_names': bool, + @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") + 'show_addresses': bool, + @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") + 'show_code_bytes': bool, + @default(1) @description("Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.") + 'show_source_lines': bool, + @default(1) @description("Controls whether or not disassembly text is decorated with symbol names.") + 'show_symbol_names': bool, @default(1) 'show_line_numbers': bool, } ``` diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 4a2d9e82..4fb4523f 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -620,6 +620,7 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs) //- rjf: gather commands String8List cmds_list = {0}; + if(rd_view_query_cmd().size == 0) { MD_NodePtrList schemas = rd_schemas_from_name(cfg_name); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5df1ee41..a912abaa 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1726,6 +1726,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; dr_fstrs_push_new(arena, &result.fstrs, ¶ms, string); + result.flags |= RD_WatchCellFlag_IsNonCode; } } }break; From 93b8aef49c0be1212818b8b7baf20a167969c966 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 15:45:39 -0700 Subject: [PATCH 417/755] fix target environment string list evaluation cell building; extend lister completion with further push-queries for catchall; extend f1 lister to include targets, types, globals, thread-locals --- src/raddbg/raddbg_core.c | 14 +++++++++----- src/raddbg/raddbg_eval.c | 2 +- src/raddbg/raddbg_views.c | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9f8d4d0b..7d6f4c37 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3021,7 +3021,7 @@ rd_view_ui(Rng2F32 rect) } else { - did_cmd = 0; + rd_cmd(RD_CmdKind_PushQuery, .expr = e_string_from_expr(scratch.arena, eval.expr, str8_zero())); } }break; case E_SpaceKind_File: @@ -3043,7 +3043,7 @@ rd_view_ui(Rng2F32 rect) } else { - did_cmd = 0; + rd_cmd(RD_CmdKind_PushQuery, .expr = e_string_from_expr(scratch.arena, eval.expr, str8_zero())); } }break; case RD_EvalSpaceKind_MetaUnattachedProcess: @@ -12205,7 +12205,6 @@ rd_frame(void) e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("environment"), e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment"), - .flags = E_TypeFlag_EditableChildren, .irext = E_TYPE_IREXT_FUNCTION_NAME(environment), .access = E_TYPE_ACCESS_FUNCTION_NAME(environment), .expand = @@ -12674,14 +12673,19 @@ rd_frame(void) "query:commands, " "query:$%I64x, " "query:$%I64x, " + "query:targets, " "query:recent_files, " "query:recent_projects, " - "query:procedures, " "query:processes, " "query:threads, " "query:modules, " "query:user_settings, " - "query:project_settings, ", + "query:project_settings, " + "query:procedures, " + "query:types, " + "query:globals, " + "query:thread_locals, " + , rd_regs()->view, rd_regs()->window); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1); }break; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 4fb4523f..79067747 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -620,7 +620,7 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs) //- rjf: gather commands String8List cmds_list = {0}; - if(rd_view_query_cmd().size == 0) + if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) == &rd_nil_cfg) { MD_NodePtrList schemas = rd_schemas_from_name(cfg_name); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a912abaa..18ae3d0d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1449,7 +1449,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: unpack evaluation // E_Type *cell_type = e_type_from_key__cached(cell->eval.irtree.type_key); - if(cell->eval.space.u64s[1] == 0) + MD_NodePtrList cell_schemas = rd_schemas_from_name(cell_type->name); + if(cell->eval.space.u64s[1] == 0 && cell_schemas.count != 0) { result.cfg = rd_cfg_from_eval_space(cell->eval.space); } From 4fe602521ac224a7111ba0ce71c3f8642ec526d2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 16:49:02 -0700 Subject: [PATCH 418/755] fix pointer dereference path in type-mode evaluation; carve out exception for lens visualization with string-pointers - in that case, we just want to apply a string size limitation & go to the regular string path; begin getting off old color slots --- src/eval/eval_ir.c | 11 +++++++++-- src/eval_visualization/eval_visualization_core.c | 16 ++++++++++++++++ src/eval_visualization/eval_visualization_core.h | 2 ++ src/raddbg/raddbg_core.c | 8 ++++++-- src/raddbg/raddbg_widgets.c | 13 ++++++------- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 48387207..1ae73bcb 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -749,7 +749,10 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) l_restype_kind == E_TypeKind_RRef) { new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); - mode = E_Mode_Offset; + if(l.mode != E_Mode_Null) + { + mode = E_Mode_Offset; + } } if(r_value != 0 && !r_is_constant_value) { @@ -1023,7 +1026,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } result.root = new_tree; result.type_key = r_type_direct; - result.mode = E_Mode_Offset; + result.mode = E_Mode_Null; + if(r_tree.mode == E_Mode_Value) + { + result.mode = E_Mode_Offset; + } } }break; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index e68be0fd..b11f9183 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1604,6 +1604,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) goto arrays_and_sets_and_structs; } E_Type *type = e_type_from_key__cached(type_key); + E_TypeKind element_type_kind = e_type_kind_from_key(e_type_key_unwrap(type->direct_type_key, E_TypeUnwrapFlag_All)); B32 lens_applied = 1; EV_StringParams lens_params = *params; if(0){} @@ -1624,6 +1625,15 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { lens_params.flags |= EV_StringFlag_DisableAddresses; } + else if(str8_match(type->name, str8_lit("array"), 0) && + type->count >= 1 && + (((E_TypeKind_Char8 <= element_type_kind && element_type_kind <= E_TypeKind_UChar32) || + element_type_kind == E_TypeKind_S8 || + element_type_kind == E_TypeKind_U8))) + { + lens_params.limit_strings = 1; + lens_params.limit_strings_size = e_value_from_expr(type->args[0]).u64; + } else { lens_applied = 0; @@ -1821,6 +1831,12 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case 4: {string = str8_from_32(scratch.arena, str32_cstring((U32 *)string_buffer));}break; } + // rjf: apply string size limitation + if(params->limit_strings) + { + string = str8_prefix(string, params->limit_strings_size); + } + // rjf: escape and quote B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableStringQuotes) || depth > 0); String8 string__escaped_and_quoted = string; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index a23a2fcf..f8d4c626 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -246,6 +246,8 @@ struct EV_StringParams U32 min_digits; U8 digit_group_separator; String8 filter; + B32 limit_strings; + U64 limit_strings_size; }; typedef struct EV_StringIterTask EV_StringIterTask; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7d6f4c37..fc34441f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3041,11 +3041,15 @@ rd_view_ui(Rng2F32 rect) { rd_cmd(RD_CmdKind_OpenRecentProject, .cfg = cfg->id); } - else + else if(e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Set) { rd_cmd(RD_CmdKind_PushQuery, .expr = e_string_from_expr(scratch.arena, eval.expr, str8_zero())); } - }break; + else + { + did_cmd = 0; + } + }break; case RD_EvalSpaceKind_MetaUnattachedProcess: { U64 pid = eval.value.u128.u64[0]; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index cf646c23..c44044c5 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1739,8 +1739,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_TagF("floating") { TxtRng select_rng = txt_rng(*cursor, *mark); - Vec4F32 active_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeLineNumbersSelected); - Vec4F32 inactive_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeLineNumbers); ui_set_next_fixed_x(floor_f32(params->margin_float_off_px + params->priority_margin_width_px + params->catchall_margin_width_px)); ui_set_next_pref_width(ui_px(params->line_num_width_px, 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); @@ -1756,7 +1754,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num <= params->line_num_range.max; line_num += 1, line_idx += 1) { - Vec4F32 text_color = (select_rng.min.line <= line_num && line_num <= select_rng.max.line) ? active_color : inactive_color; + B32 line_is_selected = (select_rng.min.line <= line_num && line_num <= select_rng.max.line); Vec4F32 bg_color = v4f32(0, 0, 0, 0); // rjf: line info on this line -> adjust bg color to visualize @@ -1785,7 +1783,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: build line num box - UI_TextColor(text_color) UI_BackgroundColor(bg_color) + UI_TagF(line_is_selected ? "" : "weak") UI_BackgroundColor(bg_color) ui_build_box_from_stringf(UI_BoxFlag_DrawText|(UI_BoxFlag_DrawBackground*!!has_line_info), "%I64u##line_num", line_num); } } @@ -2001,10 +1999,11 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Vec4F32 pin_color = rd_color_from_cfg(pin); if(pin_color.w == 0) { - pin_color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + pin_color = ui_color_from_name(str8_lit("text")); } - rd_code_label(0.8f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), pin_expr); - rd_code_label(0.6f, 1, rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), eval_string); + Vec4F32 default_code_color = ui_color_from_name(str8_lit("code_default")); + rd_code_label(0.8f, 1, default_code_color, pin_expr); + rd_code_label(0.6f, 1, default_code_color, eval_string); } UI_Signal pin_sig = ui_signal_from_box(pin_box); if(ui_key_match(pin_box_key, ui_hot_key())) From 1c71b89387b6b1daf89b6ed7fc8defc461c467d6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 16:55:46 -0700 Subject: [PATCH 419/755] eval irgen: allow ,length fastpath for array types as well --- src/eval/eval_ir.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 1ae73bcb..1e184bf0 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2312,20 +2312,25 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } } - if(!matches_shorthand && e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative)))) + if(!matches_shorthand) { - E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); - E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; - E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, - .flags = lens_spec_type->flags, - .count = 1, - .args = &chained_expr, - .direct_key = result.type_key, - .name = lens_spec_type->name, - .irext = lens_spec_type->irext, - .access = lens_spec_type->access, - .expand = lens_spec_type->expand); + E_TypeKind type_kind = e_type_kind_from_key(e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative)); + if(e_type_kind_is_pointer_or_ref(type_kind) || + type_kind == E_TypeKind_Array) + { + E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); + E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; + E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lens_spec_type->flags, + .count = 1, + .args = &chained_expr, + .direct_key = result.type_key, + .name = lens_spec_type->name, + .irext = lens_spec_type->irext, + .access = lens_spec_type->access, + .expand = lens_spec_type->expand); + } } } } From 83e59bb0c0ddbbbcc4891f8b0f6d8fff2715569a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 16:57:27 -0700 Subject: [PATCH 420/755] fix incorrect resolution to type-mode evaluation with dereference ops --- src/eval/eval_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 1e184bf0..0790cf4b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1027,7 +1027,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) result.root = new_tree; result.type_key = r_type_direct; result.mode = E_Mode_Null; - if(r_tree.mode == E_Mode_Value) + if(r_tree.mode != E_Mode_Null) { result.mode = E_Mode_Offset; } From c9227b71e2c1475d999fbe0ada372190c8e6433e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 17:17:52 -0700 Subject: [PATCH 421/755] corner radii editing --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +++ src/raddbg/raddbg_core.c | 47 +++++++++++++++++++++--------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 897f7a32..a970abc7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -325,7 +325,7 @@ RD_VocabInfo rd_vocab_info_table[315] = RD_NameSchemaInfo rd_name_schema_info_table[21] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 928c37ce..1bfade9a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -169,6 +169,10 @@ RD_VocabTable: @default(1) @display_name('Background Blur') @description("Controls whether or not occluded regions behind floating elements are blurred.") 'background_blur': bool, + //- rjf: appearance settings + @default(1.f) @display_name('Rounded Corner Amount') @description("Controls the degree to which UI corners are rounded.") + 'rounded_corner_amount': @range[0, 1] f32, + //- rjf: code formatting settings @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fc34441f..67cafaeb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8847,6 +8847,7 @@ rd_window_frame(void) Rng2F32 window_rect = os_client_rect_from_window(ws->os); //- rjf: unpack settings + F32 rounded_corner_amount = rd_setting_f32_from_name(str8_lit("rounded_corner_amount")); B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); Vec4F32 base_background_color = ui_color_from_name(str8_lit("background")); Vec4F32 base_border_color = ui_color_from_name(str8_lit("border")); @@ -8881,6 +8882,15 @@ rd_window_frame(void) U64 total_heatmap_sum_count = 0; for(UI_Box *box = ui_root_from_state(ws->ui); !ui_box_is_nil(box);) { + // rjf: get corner radii + F32 box_corner_radii[Corner_COUNT] = + { + box->corner_radii[Corner_00]*rounded_corner_amount, + box->corner_radii[Corner_01]*rounded_corner_amount, + box->corner_radii[Corner_10]*rounded_corner_amount, + box->corner_radii[Corner_11]*rounded_corner_amount, + }; + // rjf: get recursion UI_BoxRec rec = ui_box_rec_df_post(box, &ui_nil_box); @@ -8929,14 +8939,14 @@ rd_window_frame(void) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); R_Rect2DInst *inst = dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } // rjf: blur background if(box->flags & UI_BoxFlag_DrawBackgroundBlur && do_background_blur) { R_PassParams_Blur *params = dr_blur(pad_2f32(box->rect, 1.f), box->blur_size*(1-box->transparency), 0); - MemoryCopyArray(params->corner_radii, box->corner_radii); + MemoryCopyArray(params->corner_radii, box_corner_radii); } // rjf: compute effective active t @@ -8964,7 +8974,7 @@ rd_window_frame(void) // rjf: draw background R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box_background_color, 0, 0, 1.f); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); // rjf: hot effect extension if(box->flags & UI_BoxFlag_DrawHotEffects) @@ -8983,7 +8993,7 @@ rd_window_frame(void) R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } // rjf: soft circle around mouse @@ -9022,7 +9032,7 @@ rd_window_frame(void) R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y0, box->rect.x1, box->rect.y0 + shadow_size.y), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = inst->colors[Corner_10] = shadow_color; inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(0.f, 0.f, 0.f, 0.0f); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } // rjf: bottom -> top light effect @@ -9030,7 +9040,7 @@ rd_window_frame(void) R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y1 - shadow_size.y, box->rect.x1, box->rect.y1), v4f32(0, 0, 0, 0), 0, 0, 1.f); inst->colors[Corner_00] = inst->colors[Corner_10] = v4f32(0, 0, 0, 0); inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(1.0f, 1.0f, 1.0f, 0.08f*box->active_t); - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } // rjf: left -> right dark effect @@ -9039,7 +9049,7 @@ rd_window_frame(void) inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(0.f, 0.f, 0.f, 0.f); inst->colors[Corner_00] = shadow_color; inst->colors[Corner_01] = shadow_color; - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } // rjf: right -> left dark effect @@ -9048,7 +9058,7 @@ rd_window_frame(void) inst->colors[Corner_00] = inst->colors[Corner_01] = v4f32(0.f, 0.f, 0.f, 0.f); inst->colors[Corner_10] = shadow_color; inst->colors[Corner_11] = shadow_color; - MemoryCopyArray(inst->corner_radii, box->corner_radii); + MemoryCopyArray(inst->corner_radii, box_corner_radii); } } } @@ -9168,13 +9178,22 @@ rd_window_frame(void) dr_pop_clip(); } + // rjf: get corner radii + F32 b_corner_radii[Corner_COUNT] = + { + b->corner_radii[Corner_00]*rounded_corner_amount, + b->corner_radii[Corner_01]*rounded_corner_amount, + b->corner_radii[Corner_10]*rounded_corner_amount, + b->corner_radii[Corner_11]*rounded_corner_amount, + }; + // rjf: draw border if(b->flags & UI_BoxFlag_DrawBorder) { Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); // rjf: hover effect if(b->flags & UI_BoxFlag_DrawHotEffects) @@ -9187,7 +9206,7 @@ rd_window_frame(void) R_Rect2DInst *inst = dr_rect(b_border_rect, color, 0, 1.f, 1.f); inst->colors[Corner_01].w *= 0.2f; inst->colors[Corner_11].w *= 0.2f; - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); } } @@ -9195,7 +9214,7 @@ rd_window_frame(void) if(b->flags & UI_BoxFlag_Debug) { R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 1.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); } // rjf: draw sides @@ -9229,7 +9248,7 @@ rd_window_frame(void) Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= 0.09f*b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); } // rjf: draw focus border @@ -9244,7 +9263,7 @@ rd_window_frame(void) Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); } // rjf: disabled overlay @@ -9252,7 +9271,7 @@ rd_window_frame(void) { Vec4F32 disabled_overlay_color = v4f32(base_background_color.x, base_background_color.y, base_background_color.z, b->disabled_t*0.3f); R_Rect2DInst *inst = dr_rect(b->rect, disabled_overlay_color, 0, 0, 1); - MemoryCopyArray(inst->corner_radii, b->corner_radii); + MemoryCopyArray(inst->corner_radii, b_corner_radii); } // rjf: pop squish From 3d1f764741c64dba9ede1d60b842c184dfe18ae1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 21 Apr 2025 17:23:38 -0700 Subject: [PATCH 422/755] control to disable windows style menu bar alt behavior --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 ++++ src/raddbg/raddbg_core.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a970abc7..a6e368d0 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -325,7 +325,7 @@ RD_VocabInfo rd_vocab_info_table[315] = RD_NameSchemaInfo rd_name_schema_info_table[21] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1bfade9a..eadc49c2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -175,6 +175,10 @@ RD_VocabTable: //- rjf: code formatting settings @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64, + + //- rjf: windows style menu bar + @default(1) @display_name('Focus Menu Bar With Alt') @description("Mimics standard Windows behavior of focusing the menu bar using the Alt key.") + 'focus_menu_bar_with_alt': bool, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 67cafaeb..6c9a0109 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7212,7 +7212,7 @@ rd_window_frame(void) { ui_set_next_fastpath_codepoint(items[idx].codepoint); B32 alt_fastpath_key = 0; - if(ui_key_press(OS_Modifier_Alt, items[idx].key)) + if(rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt")) && ui_key_press(OS_Modifier_Alt, items[idx].key)) { alt_fastpath_key = 1; } @@ -11855,6 +11855,7 @@ rd_frame(void) } //- rjf: try menu bar operations + if(rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt"))) { if(!take && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { From c7a9e174fafcd5b516793580d7f79ed6345c2a99 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 10:17:16 -0700 Subject: [PATCH 423/755] eliminate mutual exclusion of expression/evaluation cells; allow both paths to be turned on in a single cell --- src/raddbg/raddbg_core.c | 110 ++++++------- src/raddbg/raddbg_views.c | 338 +++++++++++++++++++------------------- src/raddbg/raddbg_views.h | 21 +-- 3 files changed, 233 insertions(+), 236 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6c9a0109..8008764c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3277,13 +3277,11 @@ rd_view_ui(Rng2F32 rect) edit_state->cursor = op.cursor; edit_state->mark = op.mark; - // rjf: commit edited cell string - switch(cell->kind) + // rjf: commit edited cell string - first try to commit eval value, if that path is + // enabled on this cell, next try to commit expression string, if that path is enabled + if(cell->kind == RD_WatchCellKind_Eval) { - case RD_WatchCellKind_ViewUI: - case RD_WatchCellKind_CallStackFrame: - {}break; - case RD_WatchCellKind_Expr: + if(cell->flags & RD_WatchCellFlag_Expr && cell->flags & RD_WatchCellFlag_NoEval) { RD_Cfg *cfg = row_info.group_cfg_child; String8 child_key = str8_lit("expression"); @@ -3312,31 +3310,28 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *expr = child_key.size != 0 ? rd_cfg_child_from_string_or_alloc(cfg, child_key) : cfg; rd_cfg_new_replace(expr, new_string); } - }break; - case RD_WatchCellKind_Eval: + } + else { - if(cell->eval.irtree.mode == E_Mode_Offset) + B32 should_commit_asap = editing_complete; + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - B32 should_commit_asap = editing_complete; - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg) + should_commit_asap = 1; + } + else if(evt->slot != UI_EventActionSlot_Cancel) + { + should_commit_asap = editing_complete; + } + if(should_commit_asap) + { + B32 success = 0; + success = rd_commit_eval_value_string(cell->eval, new_string); + if(!success) { - should_commit_asap = 1; - } - else if(evt->slot != UI_EventActionSlot_Cancel) - { - should_commit_asap = editing_complete; - } - if(should_commit_asap) - { - B32 success = 0; - success = rd_commit_eval_value_string(cell->eval, new_string); - if(!success) - { - log_user_error(str8_lit("Could not commit value successfully.")); - } + log_user_error(str8_lit("Could not commit value successfully.")); } } - }break; + } } } } @@ -3418,43 +3413,39 @@ rd_view_ui(Rng2F32 rect) continue; } RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; - switch(cell->kind) + if(cell->flags & RD_WatchCellFlag_Expr && cell->flags & RD_WatchCellFlag_NoEval) { - default:{}break; - case RD_WatchCellKind_Expr: + RD_Cfg *cfg = row_info.group_cfg_child; + if(cfg != &rd_nil_cfg) { - RD_Cfg *cfg = row_info.group_cfg_child; - if(cfg != &rd_nil_cfg) + rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); + U64 deleted_num = ev_block_num_from_id(row->block, row->key.child_id); + if(deleted_num != 0) { - rd_cfg_list_push(scratch.arena, &cfgs_to_remove, cfg); - U64 deleted_num = ev_block_num_from_id(row->block, row->key.child_id); - if(deleted_num != 0) + EV_Key parent_key = row->block->parent->key; + EV_Key key = row->block->key; + U64 fallback_id_prev = ev_block_id_from_num(row->block, deleted_num-1); + U64 fallback_id_next = ev_block_id_from_num(row->block, deleted_num+1); + if(fallback_id_next != 0) { - EV_Key parent_key = row->block->parent->key; - EV_Key key = row->block->key; - U64 fallback_id_prev = ev_block_id_from_num(row->block, deleted_num-1); - U64 fallback_id_next = ev_block_id_from_num(row->block, deleted_num+1); - if(fallback_id_next != 0) - { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_next); - } - else if(fallback_id_prev != 0) - { - parent_key = row->block->key; - key = ev_key_make(row->key.parent_hash, fallback_id_prev); - } - RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; - next_cursor_pt = new_pt; - next_cursor_set = 1; - state_dirty = 1; + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_next); } + else if(fallback_id_prev != 0) + { + parent_key = row->block->key; + key = ev_key_make(row->key.parent_hash, fallback_id_prev); + } + RD_WatchPt new_pt = {parent_key, key, pt.cell_id}; + next_cursor_pt = new_pt; + next_cursor_set = 1; + state_dirty = 1; } - }break; - case RD_WatchCellKind_Eval: - { - rd_commit_eval_value_string(cell->eval, str8_zero()); - }break; + } + } + else + { + rd_commit_eval_value_string(cell->eval, str8_zero()); } } } @@ -4325,8 +4316,7 @@ rd_view_ui(Rng2F32 rect) else { // rjf: compute visual params - B32 fancy_editors_in_expr = (row_info->cells.count == 1); - B32 cell_has_fancy_editors = (cell->kind != RD_WatchCellKind_Expr || fancy_editors_in_expr); + B32 cell_has_fancy_editors = (!(cell->flags & RD_WatchCellFlag_NoEval)); B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); B32 is_toggle_switch = (cell_has_fancy_editors && cell->eval.irtree.mode != E_Mode_Null && e_type_kind_from_key(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Bool); @@ -4334,7 +4324,7 @@ rd_view_ui(Rng2F32 rect) B32 is_activated_on_single_click = !!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick); B32 is_non_code = !!(cell_info.flags & RD_WatchCellFlag_IsNonCode); String8 ghost_text = {0}; - if(cell_selected && ewv->text_editing && cell->kind == RD_WatchCellKind_Expr) + if(cell_selected && ewv->text_editing && cell->flags & RD_WatchCellFlag_Expr && cell->flags & RD_WatchCellFlag_NoEval) { is_non_code = 0; is_button = 0; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 18ae3d0d..72240ccb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -823,7 +823,7 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); - if(cell->kind != RD_WatchCellKind_Expr) + if(!(cell->flags & RD_WatchCellFlag_Expr)) { result = e_hash_from_string(result, str8_struct(&cell->index)); result = e_hash_from_string(result, str8_struct(&cell->default_pct)); @@ -1129,7 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1143,7 +1143,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1155,7 +1155,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(row->eval.space.kind == RD_EvalSpaceKind_MetaUnattachedProcess && str8_match(row_type->name, str8_lit("unattached_process"), 0)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .edit_string = row->edit_string, + .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, + .pct = 1.f); } //////////////////////////// @@ -1164,7 +1167,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1173,7 +1176,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1243,7 +1246,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_entity != &ctrl_entity_nil) { CTRL_Entity *entity = evalled_entity; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f); @@ -1275,7 +1278,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, .edit_string = row->edit_string,.flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string,.flags = RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1286,13 +1289,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented, .pct = 1.f); } else { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f); @@ -1312,9 +1315,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1325,9 +1328,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1349,9 +1352,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .default_pct = 0.65f, .pct = take_pct()); @@ -1369,9 +1372,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); @@ -1416,9 +1419,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, row->eval, + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); @@ -1489,23 +1492,22 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla ////////////////////////////// //- rjf: determine cell editability // - switch(cell->kind) + if(cell->kind == RD_WatchCellKind_Eval) { - default:{}break; - case RD_WatchCellKind_Expr: + if(cell->flags & RD_WatchCellFlag_Expr && cell->flags & RD_WatchCellFlag_NoEval) { if(row_info->expr_is_editable) { result.flags |= RD_WatchCellFlag_CanEdit; } - }break; - case RD_WatchCellKind_Eval: + } + else { if(ev_type_key_is_editable(cell->eval.irtree.type_key) && cell->eval.irtree.mode == E_Mode_Offset) { result.flags |= RD_WatchCellFlag_CanEdit; } - }break; + } } ////////////////////////////// @@ -1563,172 +1565,176 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.flags |= RD_WatchCellFlag_Button; } - //- rjf: expression cell -> need to form "left-hand-side", or "meta" string, for some evaluation - else if(cell->kind == RD_WatchCellKind_Expr) + //- rjf: catchall cell -> need to form "left-hand-side", or "meta" string, for expression, and/or value string + else { - // rjf: funnel-through this cell's string, if it has one - B32 is_non_code = 0; - String8 expr_string = cell->edit_string; - - // rjf: if this cell has a meta-display-name, then use that - if(expr_string.size == 0) + //- rjf: build left-hand-side strings + if(cell->flags & RD_WatchCellFlag_Expr) { - for(E_Type *t = e_type_from_key__cached(cell->eval.irtree.type_key); - t != &e_type_nil; - t = e_type_from_key__cached(t->direct_type_key)) + // rjf: funnel-through this cell's string, if it has one + B32 is_non_code = 0; + String8 expr_string = cell->edit_string; + + // rjf: if this cell has a meta-display-name, then use that + if(expr_string.size == 0) { - if(t->kind == E_TypeKind_MetaDisplayName) + for(E_Type *t = e_type_from_key__cached(cell->eval.irtree.type_key); + t != &e_type_nil; + t = e_type_from_key__cached(t->direct_type_key)) { - is_non_code = 1; - expr_string = t->name; - break; + if(t->kind == E_TypeKind_MetaDisplayName) + { + is_non_code = 1; + expr_string = t->name; + break; + } } } - } - - // rjf: if this cell has no string specified, then we need to synthesize one from the evaluation - if(expr_string.size == 0) - { - // rjf: first, locate a notable expression - we special-case things like member accesses - // or array indices, so we should grab those if possible - E_Expr *notable_expr = cell->eval.expr; - for(B32 good = 0; !good;) + + // rjf: if this cell has no string specified, then we need to synthesize one from the evaluation + if(expr_string.size == 0) { + // rjf: first, locate a notable expression - we special-case things like member accesses + // or array indices, so we should grab those if possible + E_Expr *notable_expr = cell->eval.expr; + for(B32 good = 0; !good;) + { + switch(notable_expr->kind) + { + default:{good = 1;}break; + case E_ExprKind_Address: + case E_ExprKind_Deref: + case E_ExprKind_Cast: + { + notable_expr = notable_expr->last; + }break; + case E_ExprKind_Ref: + { + notable_expr = notable_expr->ref; + }break; + } + } + + // rjf: generate expression string based on our notable expression switch(notable_expr->kind) { - default:{good = 1;}break; - case E_ExprKind_Address: - case E_ExprKind_Deref: - case E_ExprKind_Cast: + // rjf: default case -> just walk the expression tree & generate a string + default: { - notable_expr = notable_expr->last; + expr_string = e_string_from_expr(arena, notable_expr, str8_zero()); }break; - case E_ExprKind_Ref: + + // rjf: array indices -> fast path to [index] + case E_ExprKind_ArrayIndex: { - notable_expr = notable_expr->ref; + expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero())); + }break; + + // rjf: member accesses -> fast-path to .name + case E_ExprKind_MemberAccess: + { + Temp scratch = scratch_begin(&arena, 1); + + // TODO(rjf): @cfg need to build inheritance tooltips +#if 0 + if(member.inheritance_key_chain.count != 0) + { + String8List strings = {0}; + for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) + { + String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); + str8_list_push(scratch.arena, &strings, base_class_name); + } + result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); + } +#endif + + // rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map + // to see if we have a fancy display string for this member. otherwise, we will just + // do a code-string of ".member_name" + String8 member_name = notable_expr->first->next->string; + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem) + { + String8 fancy_name = rd_display_from_code_name(member_name); + if(fancy_name.size != 0) + { + expr_string = fancy_name; + is_non_code = 1; + } + } + if(expr_string.size == 0) + { + expr_string = push_str8f(arena, ".%S", member_name); + } + scratch_end(scratch); }break; } } - // rjf: generate expression string based on our notable expression - switch(notable_expr->kind) + // rjf: use expression string / params to generate fancy strings + if(is_non_code) { - // rjf: default case -> just walk the expression tree & generate a string - default: + UI_TagF("weak") { - expr_string = e_string_from_expr(arena, notable_expr, str8_zero()); - }break; - - // rjf: array indices -> fast path to [index] - case E_ExprKind_ArrayIndex: - { - expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero())); - }break; - - // rjf: member accesses -> fast-path to .name - case E_ExprKind_MemberAccess: - { - Temp scratch = scratch_begin(&arena, 1); - - // TODO(rjf): @cfg need to build inheritance tooltips -#if 0 - if(member.inheritance_key_chain.count != 0) - { - String8List strings = {0}; - for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) - { - String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); - str8_list_push(scratch.arena, &strings, base_class_name); - } - result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); - } -#endif - - // rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map - // to see if we have a fancy display string for this member. otherwise, we will just - // do a code-string of ".member_name" - String8 member_name = notable_expr->first->next->string; - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - cell->eval.space.kind == E_SpaceKind_File || - cell->eval.space.kind == E_SpaceKind_FileSystem) - { - String8 fancy_name = rd_display_from_code_name(member_name); - if(fancy_name.size != 0) - { - expr_string = fancy_name; - is_non_code = 1; - } - } - if(expr_string.size == 0) - { - expr_string = push_str8f(arena, ".%S", member_name); - } - scratch_end(scratch); - }break; + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, expr_string); + } + } + else + { + result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); } } - // rjf: use expression string / params to generate fancy strings - if(is_non_code) + //- rjf: evaluation -> need to form value string + if(!(cell->flags & RD_WatchCellFlag_NoEval)) { - UI_TagF("weak") + // rjf: determine string generation parameters based on evaluation + EV_StringParams string_params = {string_flags, 10}; + { + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + string_params.flags |= EV_StringFlag_DisableStringQuotes|EV_StringFlag_DisableAddresses; + } + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Module) + { + string_params.radix = 16; + } + if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && + rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Thread) + { + string_params.radix = 16; + } + } + + // rjf: determine if code + B32 is_code = 1; + { + E_Type *type = e_type_from_key__cached(cell->eval.irtree.type_key); + if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) + { + is_code = 0; + } + } + + // rjf: generate string based on that expression & fill + String8 string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, cell->eval); + if(is_code) + { + result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); + } + else UI_TagF("weak") { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.fstrs, ¶ms, expr_string); + dr_fstrs_push_new(arena, &result.fstrs, ¶ms, string); + result.flags |= RD_WatchCellFlag_IsNonCode; } } - else - { - result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); - } - } - - //- rjf: evaluation -> need to form value string - else if(cell->kind == RD_WatchCellKind_Eval) - { - // rjf: determine string generation parameters based on evaluation - EV_StringParams string_params = {string_flags, 10}; - { - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) - { - string_params.flags |= EV_StringFlag_DisableStringQuotes|EV_StringFlag_DisableAddresses; - } - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Module) - { - string_params.radix = 16; - } - if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && - rd_ctrl_entity_from_eval_space(cell->eval.space)->kind == CTRL_EntityKind_Thread) - { - string_params.radix = 16; - } - } - - // rjf: determine if code - B32 is_code = 1; - { - E_Type *type = e_type_from_key__cached(cell->eval.irtree.type_key); - if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) - { - is_code = 0; - } - } - - // rjf: generate string based on that expression & fill - String8 string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, cell->eval); - if(is_code) - { - result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); - } - else UI_TagF("weak") - { - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.fstrs, ¶ms, string); - result.flags |= RD_WatchCellFlag_IsNonCode; - } } }break; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index b0971bfb..d3b2b37e 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -43,9 +43,8 @@ struct RD_CodeViewBuildResult typedef enum RD_WatchCellKind { - RD_WatchCellKind_Expr, // strings to represent expression itself - RD_WatchCellKind_Eval, // an evaluation of the expression, with some optional modification - e.g. `$expr.some_member`, or `typeof($expr)` - RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook + RD_WatchCellKind_Eval, // an evaluation cell + RD_WatchCellKind_ViewUI, // an arbitrary user interface, supplied by a hook RD_WatchCellKind_CallStackFrame, // a slot for a yellow arrow, to show call stack frame selection } RD_WatchCellKind; @@ -53,13 +52,15 @@ RD_WatchCellKind; typedef U32 RD_WatchCellFlags; enum { - RD_WatchCellFlag_Button = (1<<0), - RD_WatchCellFlag_Background = (1<<1), - RD_WatchCellFlag_ActivateWithSingleClick = (1<<2), - RD_WatchCellFlag_IsNonCode = (1<<3), - RD_WatchCellFlag_CanEdit = (1<<4), - RD_WatchCellFlag_IsErrored = (1<<5), - RD_WatchCellFlag_Indented = (1<<6), + RD_WatchCellFlag_Expr = (1<<0), + RD_WatchCellFlag_NoEval = (1<<1), + RD_WatchCellFlag_Button = (1<<2), + RD_WatchCellFlag_Background = (1<<3), + RD_WatchCellFlag_ActivateWithSingleClick = (1<<4), + RD_WatchCellFlag_IsNonCode = (1<<5), + RD_WatchCellFlag_CanEdit = (1<<6), + RD_WatchCellFlag_IsErrored = (1<<7), + RD_WatchCellFlag_Indented = (1<<8), }; typedef struct RD_WatchCell RD_WatchCell; From 78b5582e956fec60b529b8cdf8421f742f87dc68 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 11:24:41 -0700 Subject: [PATCH 424/755] dead code elimination, do cleanup pass over cell text rendering story, prep for expr/eval in same cell --- src/draw/draw.c | 10 ++ src/draw/draw.h | 1 + src/raddbg/raddbg_core.c | 293 ++---------------------------------- src/raddbg/raddbg_views.c | 28 ++-- src/raddbg/raddbg_views.h | 3 +- src/raddbg/raddbg_widgets.c | 285 +++++++++++++++++------------------ src/raddbg/raddbg_widgets.h | 7 +- 7 files changed, 183 insertions(+), 444 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index 24b39995..d77f41af 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -133,6 +133,16 @@ dr_string_from_fstrs(Arena *arena, DR_FStrList *list) return result; } +internal FuzzyMatchRangeList +dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle) +{ + Temp scratch = scratch_begin(&arena, 1); + String8 fstrs_string = dr_string_from_fstrs(scratch.arena, fstrs); + FuzzyMatchRangeList ranges = fuzzy_match_find(arena, needle, fstrs_string); + scratch_end(scratch); + return ranges; +} + internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) { diff --git a/src/draw/draw.h b/src/draw/draw.h index d905818f..d98f1081 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -123,6 +123,7 @@ internal void dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push); internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src); internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list); +internal FuzzyMatchRangeList dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle); internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs); internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8008764c..c5fefee4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3114,7 +3114,11 @@ rd_view_ui(Rng2F32 rect) String8 string = cell->edit_string; if(string.size == 0) { - string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + string = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); + } + if(string.size == 0) + { + string = dr_string_from_fstrs(scratch.arena, &cell_info.eval_fstrs); } string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; @@ -3363,7 +3367,10 @@ rd_view_ui(Rng2F32 rect) continue; } RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - String8 cell_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); + String8List cell_strings = {0}; + str8_list_push(scratch.arena, &cell_strings, dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs)); + str8_list_push(scratch.arena, &cell_strings, dr_string_from_fstrs(scratch.arena, &cell_info.eval_fstrs)); + String8 cell_string = str8_list_join(scratch.arena, &cell_strings, &(StringJoin){.sep = str8_lit(" ")}); cell_string = str8_skip_chop_whitespace(cell_string); U64 comma_pos = str8_find_needle(cell_string, 0, str8_lit(","), 0); if(selection_tbl.min.x != selection_tbl.max.x || selection_tbl.min.y != selection_tbl.max.y) @@ -4330,17 +4337,6 @@ rd_view_ui(Rng2F32 rect) is_button = 0; is_activated_on_single_click = 0; } - String8 searched_string = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); - String8 search_query = rd_view_query_input(); - FuzzyMatchRangeList fuzzy_matches = fuzzy_match_find(scratch.arena, search_query, searched_string); - if(fuzzy_matches.count == 0) - { - String8 path_needle = str8_skip_last_slash(search_query); - if(0 < path_needle.size && path_needle.size < search_query.size) - { - fuzzy_matches = fuzzy_match_find(scratch.arena, path_needle, searched_string); - } - } // rjf: form cell build parameters RD_CellParams cell_params = {0}; @@ -4354,9 +4350,10 @@ rd_view_ui(Rng2F32 rect) cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); cell_params.edit_string_size_out = &cell_edit_state->input_size; cell_params.expanded_out = &next_row_expanded; - cell_params.pre_edit_value = dr_string_from_fstrs(scratch.arena, &cell_info.fstrs); - cell_params.fstrs = cell_info.fstrs; - cell_params.fuzzy_matches = &fuzzy_matches; + cell_params.pre_edit_value = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); + cell_params.expr_fstrs = cell_info.expr_fstrs; + cell_params.eval_fstrs = cell_info.eval_fstrs; + cell_params.search_needle = rd_view_query_input(); // rjf: apply description if(row_height_px > ui_top_font_size()*3.5f) @@ -5982,270 +5979,6 @@ rd_window_frame(void) } } - //////////////////////////// - //- rjf: @window_ui_part top-level registers context menu - // -#if 0 - UI_CtxMenu(rd_state->ctx_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) - { - Temp scratch = scratch_begin(0, 0); - RD_Regs *regs = ws->ctx_menu_regs; - RD_RegSlot slot = ws->ctx_menu_regs_slot; - CTRL_Entity *ctrl_entity = &ctrl_entity_nil; - { - switch(slot) - { - default:{}break; - - ////////////////////// - //- rjf: source code locations - // - case RD_RegSlot_Cursor: - { - // TODO(rjf): with new registers-based commands, all of this can be deduplicated with the - // command-based path, but I am holding off on that until post 0.9.12 - these should be - // able to just all push commands for their corresponding actions - // - TXT_Scope *txt_scope = txt_scope_open(); - HS_Scope *hs_scope = hs_scope_open(); - TxtRng range = txt_rng(regs->cursor, regs->mark); - D_LineList lines = regs->lines; - if(!txt_pt_match(range.min, range.max) && ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Copy].string))) - { - U128 hash = {0}; - TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, regs->text_key, regs->lang_kind, &hash); - String8 data = hs_data_from_hash(hs_scope, hash); - String8 copy_data = txt_string_from_info_data_txt_rng(&info, data, range); - os_set_clipboard_text(copy_data); - ui_ctx_menu_close(); - } - if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_RightArrow, 0, "Set Next Statement"))) - { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - U64 new_rip_vaddr = regs->vaddr; - if(regs->file_path.size != 0) - { - for(D_LineNode *n = lines.first; n != 0; n = n->next) - { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); - CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules); - if(module != &ctrl_entity_nil) - { - new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); - break; - } - } - } - rd_cmd(RD_CmdKind_SetThreadIP, .vaddr = new_rip_vaddr); - ui_ctx_menu_close(); - } - if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Play, 0, "Run To Line"))) - { - if(regs->file_path.size != 0) - { - rd_cmd(RD_CmdKind_RunToLine, .file_path = regs->file_path, .cursor = range.min); - } - else - { - rd_cmd(RD_CmdKind_RunToLine, .vaddr = regs->vaddr); - } - ui_ctx_menu_close(); - } - if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Null, 0, "Go To Name"))) - { - U128 hash = {0}; - TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, regs->text_key, regs->lang_kind, &hash); - String8 data = hs_data_from_hash(hs_scope, hash); - Rng1U64 expr_off_range = {0}; - if(range.min.column != range.max.column) - { - expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max)); - } - else - { - expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min); - } - String8 expr = str8_substr(data, expr_off_range); - rd_cmd(RD_CmdKind_GoToName, .string = expr); - ui_ctx_menu_close(); - } - if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_CircleFilled, 0, "Toggle Breakpoint"))) - { - rd_cmd(RD_CmdKind_ToggleBreakpoint, - .file_path = regs->file_path, - .cursor = range.min, - .vaddr = regs->vaddr); - ui_ctx_menu_close(); - } - if(range.min.line == range.max.line && ui_clicked(rd_icon_buttonf(RD_IconKind_Binoculars, 0, "Toggle Watch Expression"))) - { - U128 hash = {0}; - TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, regs->text_key, regs->lang_kind, &hash); - String8 data = hs_data_from_hash(hs_scope, hash); - Rng1U64 expr_off_range = {0}; - if(range.min.column != range.max.column) - { - expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max)); - } - else - { - expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min); - } - String8 expr = str8_substr(data, expr_off_range); - rd_cmd(RD_CmdKind_ToggleWatchExpression, .string = expr); - ui_ctx_menu_close(); - } - if(regs->file_path.size == 0 && range.min.line == range.max.line && ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_GoToSource].string))) - { - rd_cmd(RD_CmdKind_GoToSource, .lines = lines); - ui_ctx_menu_close(); - } - if(regs->file_path.size != 0 && range.min.line == range.max.line && ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_GoToDisassembly].string))) - { - rd_cmd(RD_CmdKind_GoToDisassembly, .lines = lines); - ui_ctx_menu_close(); - } - hs_scope_close(hs_scope); - txt_scope_close(txt_scope); - }break; - - ////////////////////// - //- rjf: tabs - // - case RD_RegSlot_View: - { -#if 0 // TODO(rjf): @cfg (context menus) - RD_Cfg *tab = rd_cfg_from_id(regs->view); - RD_RegsScope(.view = regs->view) - { - String8 expr = rd_view_expr_string(); - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(tab->string); - RD_IconKind view_icon = view_rule_info->icon_kind; - DR_FStrList fstrs = rd_title_fstrs_from_view(scratch.arena, view_rule_info->display_name, expr, ui_top_palette()->text, ui_top_palette()->text_weak, ui_top_font_size()); - String8 file_path = rd_file_path_from_eval_string(scratch.arena, expr); - - // rjf: title - UI_Row - { - ui_spacer(ui_em(1.f, 1.f)); - RD_Font(RD_FontSlot_Icons) - UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)) - UI_PrefWidth(ui_em(2.f, 1.f)) - UI_PrefHeight(ui_pct(1, 0)) - UI_TextAlignment(UI_TextAlign_Center) - UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_label(rd_icon_kind_text_table[view_icon]); - UI_PrefWidth(ui_text_dim(10, 1)) - { - UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(name_box, &fstrs); - } - } - - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - - // rjf: copy name - if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Name"))) - { - os_set_clipboard_text(dr_string_from_fstrs(scratch.arena, &fstrs)); - ui_ctx_menu_close(); - } - - // rjf: copy full path - if(file_path.size != 0) - { - UI_Signal copy_full_path_sig = rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Full Path"); - String8 full_path = path_normalized_from_string(scratch.arena, file_path); - if(ui_clicked(copy_full_path_sig)) - { - os_set_clipboard_text(full_path); - ui_ctx_menu_close(); - } - if(ui_hovering(copy_full_path_sig)) UI_Tooltip - { - ui_label(full_path); - } - } - - // rjf: show in explorer - if(file_path.size != 0) - { - UI_Signal sig = rd_icon_buttonf(RD_IconKind_FolderClosedFilled, 0, "Show In Explorer"); - if(ui_clicked(sig)) - { - String8 full_path = path_normalized_from_string(scratch.arena, file_path); - os_show_in_filesystem_ui(full_path); - ui_ctx_menu_close(); - } - } - - // rjf: filter controls - if(view_rule_info->flags & RD_ViewRuleInfoFlag_CanFilter) - { - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_Filter].string))) - { - rd_cmd(RD_CmdKind_Filter); - ui_ctx_menu_close(); - } - if(ui_clicked(rd_cmd_spec_button(rd_cmd_kind_info_table[RD_CmdKind_ClearFilter].string))) - { - rd_cmd(RD_CmdKind_ClearFilter); - ui_ctx_menu_close(); - } - } - - // rjf: close tab - if(ui_clicked(rd_icon_buttonf(RD_IconKind_X, 0, "Close Tab"))) - { - rd_cmd(RD_CmdKind_CloseTab); - ui_ctx_menu_close(); - } - - // rjf: param tree editing -#if 0 - UI_TextPadding(ui_top_font_size()*1.5f) RD_Font(RD_FontSlot_Code) - { - Temp scratch = scratch_begin(0, 0); - String8 schema_string = view->spec->params_schema; - MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, schema_string); - MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), schema_string, schema_tokenize.tokens); - MD_Node *schema_root = schema_parse.root->first; - if(!md_node_is_nil(schema_root)) - { - if(!md_node_is_nil(schema_root->first)) - { - RD_Palette(RD_PaletteCode_Floating) ui_divider(ui_em(1.f, 1.f)); - } - for MD_EachNode(key, schema_root->first) - { - UI_Row - { - MD_Node *params = view->params_roots[view->params_write_gen%ArrayCount(view->params_roots)]; - MD_Node *param_tree = md_child_from_string(params, key->string, 0); - String8 pre_edit_value = md_string_from_children(scratch.arena, param_tree); - UI_PrefWidth(ui_em(10.f, 1.f)) ui_label(key->string); - UI_Signal sig = rd_cellf(RD_CellFlag_Border|RD_CellFlag_CodeContents, 0, 0, &ws->ctx_menu_input_cursor, &ws->ctx_menu_input_mark, ws->ctx_menu_input_buffer, ws->ctx_menu_input_buffer_size, &ws->ctx_menu_input_string_size, 0, pre_edit_value, "%S##view_param", key->string); - if(ui_committed(sig)) - { - String8 new_string = str8(ws->ctx_menu_input_buffer, ws->ctx_menu_input_string_size); - rd_view_store_param(view, key->string, new_string); - } - } - } - } - scratch_end(scratch); - } -#endif - } -#endif - }break; - } - } - - scratch_end(scratch); - } -#endif - //////////////////////////// //- rjf: @window_ui_part drop-completion context menu // diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 72240ccb..e3a5a61a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1176,7 +1176,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1248,7 +1248,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f); if(entity->kind == CTRL_EntityKind_Machine || entity->kind == CTRL_EntityKind_Process || @@ -1291,13 +1291,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented, .pct = 1.f); + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented, .pct = 1.f); } else { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f); } } @@ -1523,14 +1523,14 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: cfg evaluation -> button for cfg else if(result.cfg != &rd_nil_cfg) { - result.fstrs = rd_title_fstrs_from_cfg(arena, result.cfg); + result.expr_fstrs = rd_title_fstrs_from_cfg(arena, result.cfg); result.flags |= RD_WatchCellFlag_Button; } //- rjf: entity evaluation -> button for entity else if(result.entity != &ctrl_entity_nil) { - result.fstrs = rd_title_fstrs_from_ctrl_entity(arena, result.entity, 1); + result.expr_fstrs = rd_title_fstrs_from_ctrl_entity(arena, result.entity, 1); result.flags |= RD_WatchCellFlag_Button; } @@ -1549,11 +1549,11 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = ui_color_from_name(str8_lit("text"))); } - result.fstrs = fstrs; + result.expr_fstrs = fstrs; } else { - result.fstrs = rd_title_fstrs_from_code_name(arena, result.cmd_name); + result.expr_fstrs = rd_title_fstrs_from_code_name(arena, result.cmd_name); } result.flags |= RD_WatchCellFlag_Button; } @@ -1561,7 +1561,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: files -> button for file else if(result.file_path.size != 0) { - result.fstrs = rd_title_fstrs_from_file_path(arena, result.file_path); + result.expr_fstrs = rd_title_fstrs_from_file_path(arena, result.file_path); result.flags |= RD_WatchCellFlag_Button; } @@ -1680,12 +1680,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla UI_TagF("weak") { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.fstrs, ¶ms, expr_string); + dr_fstrs_push_new(arena, &result.expr_fstrs, ¶ms, expr_string); } } else { - result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); + result.expr_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); } } @@ -1726,12 +1726,12 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla String8 string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, cell->eval); if(is_code) { - result.fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); + result.eval_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); } else UI_TagF("weak") { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.fstrs, ¶ms, string); + dr_fstrs_push_new(arena, &result.eval_fstrs, ¶ms, string); result.flags |= RD_WatchCellFlag_IsNonCode; } } @@ -1757,7 +1757,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla dr_fstrs_push_new(arena, &fstrs, ¶ms, push_str8f(arena, "(PID: %I64u)", pid)); dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &fstrs, ¶ms, name); - result.fstrs = fstrs; + result.expr_fstrs = fstrs; }break; } scratch_end(scratch); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index d3b2b37e..03f8bbb0 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -112,7 +112,8 @@ struct RD_WatchRowCellInfo CTRL_Entity *entity; String8 cmd_name; String8 file_path; - DR_FStrList fstrs; + DR_FStrList expr_fstrs; + DR_FStrList eval_fstrs; String8 description; String8 error_tooltip; String8 inheritance_tooltip; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c44044c5..e208376d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3523,164 +3523,159 @@ rd_cell(RD_CellParams *params, String8 string) F32 cursor_off = 0; UI_Parent(scrollable_box) { + Temp scratch = scratch_begin(0, 0); + + //- rjf: compute fancy strings + DR_FStrList fstrs = {0}; + { + //- rjf: (not editing) + if(!is_focus_active && !is_focus_active_disabled && params->expr_fstrs.total_size != 0) + { + fstrs = params->expr_fstrs; + } + else if(!is_focus_active && !is_focus_active_disabled && params->eval_fstrs.total_size != 0) + { + fstrs = params->eval_fstrs; + } + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents && params->pre_edit_value.size != 0) + { + String8 display_string = params->pre_edit_value; + fstrs = rd_fstrs_from_code_string(scratch.arena, 1, 0, ui_color_from_name(str8_lit("text")), display_string); + } + else if(!is_focus_active && !is_focus_active_disabled) + { + String8 display_string = params->pre_edit_value; + if(params->pre_edit_value.size == 0) + { + display_string = ui_display_part_from_key_string(string); + } + UI_TagF("weak") + { + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, display_string); + } + } + + //- rjf: (editing) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); + if(autocomplete_hint_string.size != 0) + { + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); + U64 off = 0; + U64 cursor_off = params->cursor->column-1; + DR_FStrNode *prev_n = 0; + for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) + { + if(off <= cursor_off && cursor_off <= off+n->v.string.size) + { + prev_n = n; + break; + } + off += n->v.string.size; + } + { + DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *fstr = &autocomp_fstr_n->v; + fstr->string = autocomplete_append_string; + fstr->params.font = ui_top_font(); + fstr->params.color = ui_color_from_name(str8_lit("text")); + fstr->params.color.w *= 0.5f; + fstr->params.size = ui_top_font_size(); + autocomp_fstr_n->next = prev_n ? prev_n->next : 0; + if(prev_n != 0) + { + prev_n->next = autocomp_fstr_n; + } + if(prev_n == 0) + { + code_fstrs.first = code_fstrs.last = autocomp_fstr_n; + } + if(prev_n != 0 && prev_n->next == 0) + { + code_fstrs.last = autocomp_fstr_n; + } + code_fstrs.node_count += 1; + code_fstrs.total_size += autocomplete_hint_string.size; + if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) + { + String8 full_string = prev_n->v.string; + U64 chop_amt = full_string.size - (cursor_off - off); + prev_n->v.string = str8_chop(full_string, chop_amt); + code_fstrs.total_size -= chop_amt; + if(chop_amt != 0) + { + String8 post_cursor = str8_skip(full_string, cursor_off - off); + DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *post_fstr = &post_fstr_n->v; + MemoryCopyStruct(post_fstr, &prev_n->v); + post_fstr->string = post_cursor; + if(autocomp_fstr_n->next == 0) + { + code_fstrs.last = post_fstr_n; + } + post_fstr_n->next = autocomp_fstr_n->next; + autocomp_fstr_n->next = post_fstr_n; + code_fstrs.node_count += 1; + code_fstrs.total_size += post_cursor.size; + } + } + } + } + fstrs = code_fstrs; + } + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); + } + } + + //- rjf: compute fuzzy match ranges + FuzzyMatchRangeList fuzzy_matches = {0}; + if(params->search_needle.size != 0) + { + fuzzy_matches = dr_fuzzy_match_find_from_fstrs(scratch.arena, &fstrs, params->search_needle); + } + + //- rjf: build textual content if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) { ui_spacer(ui_em(0.5f, 1.f)); } - if(!is_focus_active && !is_focus_active_disabled && params->fstrs.total_size != 0) + if(is_focus_active) { - UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(label, ¶ms->fstrs); - if(params->fuzzy_matches != 0) - { - ui_box_equip_fuzzy_match_ranges(label, params->fuzzy_matches); - } + ui_set_next_pref_width(ui_text_dim(1, 1)); + ui_set_next_flags(UI_BoxFlag_DisableTextTrunc); } - else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents) - { - String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) - { - display_string = params->pre_edit_value; - UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); - if(params->fuzzy_matches != 0) - { - ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); - } - } - else if(params->flags & RD_CellFlag_DisplayStringIsCode) - { - UI_Box *box = rd_code_label(1.f, 1, ui_color_from_name(str8_lit("text")), display_string); - if(params->fuzzy_matches != 0) - { - ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); - } - } - else UI_TagF("weak") - { - UI_Box *box = ui_label(display_string).box; - if(params->fuzzy_matches != 0) - { - ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); - } - } - } - else if(!is_focus_active && !is_focus_active_disabled && !(params->flags & RD_CellFlag_CodeContents)) - { - String8 display_string = ui_display_part_from_key_string(string); - if(!(params->flags & RD_CellFlag_PreferDisplayString) && params->pre_edit_value.size != 0) - { - display_string = params->pre_edit_value; - } - else - { - ui_set_next_tag(str8_lit("weak")); - } - UI_Box *box = ui_label(display_string).box; - if(params->fuzzy_matches != 0) - { - ui_box_equip_fuzzy_match_ranges(box, params->fuzzy_matches); - } - } - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) + UI_Box *text_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###text_box"); + ui_box_equip_display_fstrs(text_box, &fstrs); + ui_box_equip_fuzzy_match_ranges(text_box, &fuzzy_matches); + if(is_focus_active || is_focus_active_disabled) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - Temp scratch = scratch_begin(0, 0); - F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; - ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); - UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); - DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); - if(autocomplete_hint_string.size != 0) - { - String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); - U64 off = 0; - U64 cursor_off = params->cursor->column-1; - DR_FStrNode *prev_n = 0; - for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) - { - if(off <= cursor_off && cursor_off <= off+n->v.string.size) - { - prev_n = n; - break; - } - off += n->v.string.size; - } - { - DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *fstr = &autocomp_fstr_n->v; - fstr->string = autocomplete_append_string; - fstr->params.font = ui_top_font(); - fstr->params.color = ui_color_from_name(str8_lit("text")); - fstr->params.color.w *= 0.5f; - fstr->params.size = ui_top_font_size(); - autocomp_fstr_n->next = prev_n ? prev_n->next : 0; - if(prev_n != 0) - { - prev_n->next = autocomp_fstr_n; - } - if(prev_n == 0) - { - code_fstrs.first = code_fstrs.last = autocomp_fstr_n; - } - if(prev_n != 0 && prev_n->next == 0) - { - code_fstrs.last = autocomp_fstr_n; - } - code_fstrs.node_count += 1; - code_fstrs.total_size += autocomplete_hint_string.size; - if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) - { - String8 full_string = prev_n->v.string; - U64 chop_amt = full_string.size - (cursor_off - off); - prev_n->v.string = str8_chop(full_string, chop_amt); - code_fstrs.total_size -= chop_amt; - if(chop_amt != 0) - { - String8 post_cursor = str8_skip(full_string, cursor_off - off); - DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *post_fstr = &post_fstr_n->v; - MemoryCopyStruct(post_fstr, &prev_n->v); - post_fstr->string = post_cursor; - if(autocomp_fstr_n->next == 0) - { - code_fstrs.last = post_fstr_n; - } - post_fstr_n->next = autocomp_fstr_n->next; - autocomp_fstr_n->next = post_fstr_n; - code_fstrs.node_count += 1; - code_fstrs.total_size += post_cursor.size; - } - } - } - } - ui_box_equip_display_fstrs(editstr_box, &code_fstrs); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = params->cursor[0]; draw_data->mark = params->mark[0]; - ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); - mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; - scratch_end(scratch); - } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - F32 total_text_width = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; - F32 total_editstr_width = total_text_width - !!(params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) * expander_size_px; - ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); - UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); - UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); - draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); - draw_data->cursor = params->cursor[0]; - draw_data->mark = params->mark[0]; - ui_box_equip_display_string(editstr_box, edit_string); - ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); - mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); + ui_box_equip_custom_draw(text_box, ui_line_edit_draw, draw_data); + Vec2F32 text2mouse = sub_2f32(ui_mouse(), ui_box_text_position(text_box)); + FNT_Tag font = ui_top_font(); + F32 font_size = ui_top_font_size(); + if(params->flags & RD_CellFlag_CodeContents) + { + font = rd_font_from_slot(RD_FontSlot_Code); + } + U64 mouse_pt_off = fnt_char_pos_from_tag_size_string_p(font, font_size, 0, ui_top_tab_size(), edit_string, text2mouse.x); + mouse_pt = txt_pt(1, 1+mouse_pt_off); cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; } + + scratch_end(scratch); } ////////////////////////////// @@ -3722,7 +3717,7 @@ rd_cell(RD_CellParams *params, String8 string) F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) { - Rng1F32 cursor_range_px = r1f32(cursor_off-ui_top_font_size()*2.f, cursor_off+ui_top_font_size()*2.f); + Rng1F32 cursor_range_px = r1f32(cursor_off-ui_top_font_size()*2.f, cursor_off+ui_top_font_size()*1.f); Rng1F32 visible_range_px = r1f32(scrollable_box->view_off_target.x, scrollable_box->view_off_target.x + visible_dim_px); cursor_range_px.min = ClampBot(0, cursor_range_px.min); cursor_range_px.max = ClampBot(0, cursor_range_px.max); diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index e817b8c4..c657689c 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -33,8 +33,6 @@ enum RD_CellFlag_Border = (1<<9), RD_CellFlag_NoBackground = (1<<10), RD_CellFlag_Button = (1<<11), - RD_CellFlag_PreferDisplayString = (1<<12), - RD_CellFlag_DisplayStringIsCode = (1<<13), }; typedef struct RD_CellParams RD_CellParams; @@ -43,9 +41,10 @@ struct RD_CellParams //- rjf: catchall parameters RD_CellFlags flags; S32 depth; - FuzzyMatchRangeList *fuzzy_matches; String8 pre_edit_value; - DR_FStrList fstrs; + DR_FStrList expr_fstrs; + DR_FStrList eval_fstrs; + String8 search_needle; String8 description; //- rjf: expander r/w info From d9d102cb565fd103b00eb42e60f7e9203170934e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 13:53:52 -0700 Subject: [PATCH 425/755] expand cell capabilities to have meta data (expr name/description/etc.), as well as value editor, as well as fancy value editing widgets, all in one cell --- src/draw/draw.c | 35 ++- src/raddbg/generated/raddbg.meta.c | 8 +- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 2 - src/raddbg/raddbg_core.c | 51 ++++- src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_eval.c | 6 + src/raddbg/raddbg_views.c | 45 ++-- src/raddbg/raddbg_widgets.c | 353 ++++++++++++++++------------- src/raddbg/raddbg_widgets.h | 4 +- src/ui/ui_core.h | 3 + 11 files changed, 313 insertions(+), 204 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index d77f41af..39c12fa4 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -119,16 +119,19 @@ internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list) { String8 result = {0}; - result.size = list->total_size; - result.str = push_array_no_zero(arena, U8, result.size); - U64 idx = 0; - for(DR_FStrNode *n = list->first; n != 0; n = n->next) { - if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)) + Temp scratch = scratch_begin(&arena, 1); + String8List parts = {0}; + for(DR_FStrNode *n = list->first; n != 0; n = n->next) { - MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); - idx += n->v.string.size; + if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)) + { + str8_list_push(scratch.arena, &parts, n->v.string); + } } + result = str8_list_join(arena, &parts, 0); + result = str8_skip_chop_whitespace(result); + scratch_end(scratch); } return result; } @@ -137,7 +140,23 @@ internal FuzzyMatchRangeList dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle) { Temp scratch = scratch_begin(&arena, 1); - String8 fstrs_string = dr_string_from_fstrs(scratch.arena, fstrs); + String8 fstrs_string = {0}; + fstrs_string.size = fstrs->total_size; + fstrs_string.str = push_array(arena, U8, fstrs_string.size); + { + // TODO(rjf): the fact that we only increment on non-icon portions is super weird? + // we are only doing that because of the rendering of the fuzzy matches, so maybe + // once that is straightened out, we can fix the code here too... + U64 off = 0; + for(DR_FStrNode *n = fstrs->first; n != 0; n = n->next) + { + if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font)) + { + MemoryCopy(fstrs_string.str + off, n->v.string.str, n->v.string.size); + off += n->v.string.size; + } + } + } FuzzyMatchRangeList ranges = fuzzy_match_find(arena, needle, fstrs_string); scratch_end(scratch); return ranges; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a6e368d0..2f074e43 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[315] = +RD_VocabInfo rd_vocab_info_table[313] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -253,8 +253,6 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("goto_address"), str8_lit_comp(""), str8_lit_comp("Go To Address"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("center_cursor"), str8_lit_comp(""), str8_lit_comp("Center Cursor"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("contain_cursor"), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("find_text_forward"), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), str8_lit_comp(""), RD_IconKind_Find}, -{str8_lit_comp("find_text_backward"), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("find_next"), str8_lit_comp(""), str8_lit_comp("Find Next"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("find_prev"), str8_lit_comp(""), str8_lit_comp("Find Previous"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("find_thread"), str8_lit_comp(""), str8_lit_comp("Find Thread"), str8_lit_comp(""), RD_IconKind_Find}, @@ -394,7 +392,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[211] = +RD_CmdKindInfo rd_cmd_kind_info_table[209] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -539,8 +537,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index c0be4d39..25631e29 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -198,8 +198,6 @@ RD_CmdKind_GoToLine, RD_CmdKind_GoToAddress, RD_CmdKind_CenterCursor, RD_CmdKind_ContainCursor, -RD_CmdKind_FindTextForward, -RD_CmdKind_FindTextBackward, RD_CmdKind_FindNext, RD_CmdKind_FindPrev, RD_CmdKind_FindThread, @@ -640,7 +638,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[315]; +extern RD_VocabInfo rd_vocab_info_table[313]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index eadc49c2..d617ff7a 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -682,8 +682,6 @@ RD_CmdTable: // | | | | {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } - {FindTextForward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_forward" "Find Text (Forward)" "Searches the current code file forward (from the cursor) for a string." "" "" } - {FindTextBackward 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "find_text_backward" "Find Text (Backwards)" "Searches the current code file backwards (from the cursor) for a string." "" "" } {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c5fefee4..ce3deb35 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1226,6 +1226,42 @@ rd_setting_from_name(String8 name) return result; } +internal B32 +rd_setting_b32_from_name(String8 name) +{ + Temp scratch = scratch_begin(0, 0); + String8 value = rd_setting_from_name(name); + String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + B32 result = !!e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); + return result; +} + +internal U64 +rd_setting_u64_from_name(String8 name) +{ + Temp scratch = scratch_begin(0, 0); + String8 value = rd_setting_from_name(name); + String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + U64 result = e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); + return result; +} + +internal F32 +rd_setting_f32_from_name(String8 name) +{ + Temp scratch = scratch_begin(0, 0); + String8 value = rd_setting_from_name(name); + String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); + E_Eval eval = e_eval_from_string(scratch.arena, expr); + F32 result = e_value_eval_from_eval(eval).value.f32; + scratch_end(scratch); + return result; +} + internal RD_Cfg * rd_immediate_cfg_from_key(String8 string) { @@ -3114,11 +3150,11 @@ rd_view_ui(Rng2F32 rect) String8 string = cell->edit_string; if(string.size == 0) { - string = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); + string = dr_string_from_fstrs(scratch.arena, &cell_info.eval_fstrs); } if(string.size == 0) { - string = dr_string_from_fstrs(scratch.arena, &cell_info.eval_fstrs); + string = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); } string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; @@ -4118,6 +4154,8 @@ rd_view_ui(Rng2F32 rect) F32 cell_x_px = 0; for(RD_WatchCell *cell = row_info->cells.first; cell != 0; cell = cell->next, cell_x += 1) { + if(row_depth > 0) { ui_push_tagf("weak"); } + //////////// //- rjf: unpack cell info // @@ -4350,12 +4388,9 @@ rd_view_ui(Rng2F32 rect) cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); cell_params.edit_string_size_out = &cell_edit_state->input_size; cell_params.expanded_out = &next_row_expanded; - cell_params.pre_edit_value = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); - cell_params.expr_fstrs = cell_info.expr_fstrs; - cell_params.eval_fstrs = cell_info.eval_fstrs; cell_params.search_needle = rd_view_query_input(); - - // rjf: apply description + cell_params.meta_fstrs = cell_info.expr_fstrs; + cell_params.value_fstrs = cell_info.eval_fstrs; if(row_height_px > ui_top_font_size()*3.5f) { cell_params.description = cell_info.description; @@ -4683,6 +4718,8 @@ rd_view_ui(Rng2F32 rect) //- rjf: bump x pixel coordinate // cell_x_px = next_cell_x_px; + + if(row_depth > 0) { ui_pop_tag(); } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 64a35c7c..168f9ab3 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -872,9 +872,9 @@ internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal MD_NodePtrList rd_schemas_from_name(String8 name); internal String8 rd_setting_from_name(String8 name); -#define rd_setting_b32_from_name(name) (str8_match(rd_setting_from_name(name), str8_lit("1"), 0)) -#define rd_setting_u64_from_name(name) (u64_from_str8(rd_setting_from_name(name), 10)) -#define rd_setting_f32_from_name(name) ((F32)f64_from_str8(rd_setting_from_name(name))) +internal B32 rd_setting_b32_from_name(String8 name); +internal U64 rd_setting_u64_from_name(String8 name); +internal F32 rd_setting_f32_from_name(String8 name); internal RD_Cfg *rd_immediate_cfg_from_key(String8 string); internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 79067747..c27c17b2 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -413,6 +413,12 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { expr_is_simple = 1; } + if(expr->kind == E_ExprKind_LeafIdentifier && + (str8_match(expr->string, str8_lit("true"), 0) || + str8_match(expr->string, str8_lit("false"), 0))) + { + expr_is_simple = 1; + } if(!expr_is_simple && expr != &e_expr_nil) { child_type_key = e_type_key_cons_meta_expr(child_type_key, child->first->string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index e3a5a61a..292a3232 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1129,7 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1167,7 +1167,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + RD_WatchCellFlags extra_flags = 0; + if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + { + extra_flags |= RD_WatchCellFlag_NoEval; + } + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = extra_flags|RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1176,7 +1181,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1248,7 +1253,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f); if(entity->kind == CTRL_EntityKind_Machine || entity->kind == CTRL_EntityKind_Process || @@ -1278,7 +1283,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string,.flags = RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1291,13 +1296,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented, .pct = 1.f); + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } else { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, - .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f); } } @@ -1569,6 +1574,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla else { //- rjf: build left-hand-side strings + DR_FStrList expr_fstrs = {0}; if(cell->flags & RD_WatchCellFlag_Expr) { // rjf: funnel-through this cell's string, if it has one @@ -1677,19 +1683,17 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: use expression string / params to generate fancy strings if(is_non_code) { - UI_TagF("weak") - { - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.expr_fstrs, ¶ms, expr_string); - } + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; + dr_fstrs_push_new(arena, &expr_fstrs, ¶ms, expr_string); } else { - result.expr_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); + expr_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), expr_string); } } //- rjf: evaluation -> need to form value string + DR_FStrList eval_fstrs = {0}; if(!(cell->flags & RD_WatchCellFlag_NoEval)) { // rjf: determine string generation parameters based on evaluation @@ -1726,15 +1730,26 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla String8 string = rd_value_string_from_eval(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, cell->eval); if(is_code) { - result.eval_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); + eval_fstrs = rd_fstrs_from_code_string(arena, 1, 0, ui_color_from_name(str8_lit("text")), string); } else UI_TagF("weak") { DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), font_size, 0, 0}; - dr_fstrs_push_new(arena, &result.eval_fstrs, ¶ms, string); + dr_fstrs_push_new(arena, &eval_fstrs, ¶ms, string); result.flags |= RD_WatchCellFlag_IsNonCode; } } + + //- rjf: if we have only the expression, then use the expression as the value + if(cell->flags & RD_WatchCellFlag_NoEval) + { + result.eval_fstrs = expr_fstrs; + } + else + { + result.expr_fstrs = expr_fstrs; + result.eval_fstrs = eval_fstrs; + } } }break; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index e208376d..f916f247 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3148,6 +3148,7 @@ internal UI_Signal rd_cell(RD_CellParams *params, String8 string) { ProfBeginFunction(); + Temp scratch = scratch_begin(0, 0); ////////////////////////////// //- rjf: unpack visual metrics @@ -3171,6 +3172,140 @@ rd_cell(RD_CellParams *params, String8 string) B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); + ////////////////////////////// + //- rjf: determine which sub-cell components we'll build + // + // (the base line edit textual label / editor is always built, but this can be enriched + // with extra widgets & metadata) + // + B32 build_toggle_switch = !!(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active); + B32 build_slider = !!(params->flags & RD_CellFlag_Slider && !is_focus_active); + B32 build_lhs_name_desc = (params->meta_fstrs.node_count != 0 || params->description.size != 0); + DR_FStrList lhs_name_fstrs = params->meta_fstrs; + DR_FStrList value_name_fstrs = params->value_fstrs; + + ////////////////////////////// + //- rjf: determine autocompletion string + // + String8 autocomplete_hint_string = {0}; + { + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + autocomplete_hint_string = evt->string; + } + } + } + + ////////////////////////////// + //- rjf: compute editable fancy strings + // + DR_FStrList fstrs = {0}; + { + //- rjf: (not editing) + if(!is_focus_active && !is_focus_active_disabled && value_name_fstrs.total_size != 0) + { + fstrs = value_name_fstrs; + } + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents && params->pre_edit_value.size != 0) + { + String8 display_string = params->pre_edit_value; + fstrs = rd_fstrs_from_code_string(scratch.arena, 1, 0, ui_color_from_name(str8_lit("text")), display_string); + } + else if(!is_focus_active && !is_focus_active_disabled) + { + String8 display_string = params->pre_edit_value; + if(params->pre_edit_value.size == 0) + { + display_string = ui_display_part_from_key_string(string); + } + UI_TagF("weak") + { + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, display_string); + } + } + + //- rjf: (editing) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); + if(autocomplete_hint_string.size != 0) + { + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); + U64 off = 0; + U64 cursor_off = params->cursor->column-1; + DR_FStrNode *prev_n = 0; + for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) + { + if(off <= cursor_off && cursor_off <= off+n->v.string.size) + { + prev_n = n; + break; + } + off += n->v.string.size; + } + { + DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *fstr = &autocomp_fstr_n->v; + fstr->string = autocomplete_append_string; + fstr->params.font = ui_top_font(); + fstr->params.color = ui_color_from_name(str8_lit("text")); + fstr->params.color.w *= 0.5f; + fstr->params.size = ui_top_font_size(); + autocomp_fstr_n->next = prev_n ? prev_n->next : 0; + if(prev_n != 0) + { + prev_n->next = autocomp_fstr_n; + } + if(prev_n == 0) + { + code_fstrs.first = code_fstrs.last = autocomp_fstr_n; + } + if(prev_n != 0 && prev_n->next == 0) + { + code_fstrs.last = autocomp_fstr_n; + } + code_fstrs.node_count += 1; + code_fstrs.total_size += autocomplete_hint_string.size; + if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) + { + String8 full_string = prev_n->v.string; + U64 chop_amt = full_string.size - (cursor_off - off); + prev_n->v.string = str8_chop(full_string, chop_amt); + code_fstrs.total_size -= chop_amt; + if(chop_amt != 0) + { + String8 post_cursor = str8_skip(full_string, cursor_off - off); + DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *post_fstr = &post_fstr_n->v; + MemoryCopyStruct(post_fstr, &prev_n->v); + post_fstr->string = post_cursor; + if(autocomp_fstr_n->next == 0) + { + code_fstrs.last = post_fstr_n; + } + post_fstr_n->next = autocomp_fstr_n->next; + autocomp_fstr_n->next = post_fstr_n; + code_fstrs.node_count += 1; + code_fstrs.total_size += post_cursor.size; + } + } + } + } + fstrs = code_fstrs; + } + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); + } + } + ////////////////////////////// //- rjf: build top-level box // @@ -3235,29 +3370,78 @@ rd_cell(RD_CellParams *params, String8 string) //- rjf: build left-hand-side container box // UI_Box *lhs_box = &ui_nil_box; - UI_Parent(box) UI_WidthFill UI_ChildLayoutAxis(Axis2_Y) + if(build_lhs_name_desc) { - lhs_box = ui_build_box_from_stringf(0, "lhs_box"); - UI_Parent(lhs_box) + UI_Parent(box) UI_WidthFill UI_ChildLayoutAxis(Axis2_Y) { - ui_spacer(ui_em(3.f, 0.f)); + lhs_box = ui_build_box_from_stringf(0, "lhs_box"); } } + ////////////////////////////// + //- rjf: build line edit container box + // + UI_Box *edit_box = &ui_nil_box; + UI_Parent(box) if(fstrs.node_count != 0 || (!is_focus_active && !is_focus_active_disabled)) + { + UI_Size edit_box_size = ui_pct(1, 0); + if(build_lhs_name_desc) + { + edit_box_size = ui_px(dr_dim_from_fstrs(&fstrs).x + 10, 1.f); + ui_set_next_text_alignment(UI_TextAlign_Center); + } + UI_PrefWidth(edit_box_size) + edit_box = ui_build_box_from_stringf(0, "edit_box"); + } + ////////////////////////////// //- rjf: build scrollable container box // UI_Box *scrollable_box = &ui_nil_box; - UI_Parent(lhs_box) UI_WidthFill UI_HeightFill + if(edit_box != &ui_nil_box) { - scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); + UI_Parent(edit_box) UI_WidthFill UI_HeightFill + { + scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); + } + } + + ////////////////////////////// + //- rjf: build left-hand-side name/desc box + // + if(build_lhs_name_desc) UI_Parent(lhs_box) UI_Padding(ui_em(3.f, 0.f)) UI_WidthFill UI_HeightFill + { + FuzzyMatchRangeList fuzzy_matches = {0}; + if(params->search_needle.size != 0) + { + fuzzy_matches = dr_fuzzy_match_find_from_fstrs(scratch.arena, &lhs_name_fstrs, params->search_needle); + } + UI_Row + { + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) + { + ui_spacer(ui_em(0.5f, 1.f)); + } + UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(name_box, &lhs_name_fstrs); + ui_box_equip_fuzzy_match_ranges(name_box, &fuzzy_matches); + } + if(params->description.size != 0) RD_Font(RD_FontSlot_Main) UI_FontSize(ui_top_font_size()*0.85f) + { + UI_Row + { + ui_spacer(ui_em(0.5f, 1.f)); + UI_Box *desc_box = ui_label(params->description).box; + FuzzyMatchRangeList desc_fuzzy_matches = fuzzy_match_find(scratch.arena, params->search_needle, params->description); + ui_box_equip_fuzzy_match_ranges(desc_box, &desc_fuzzy_matches); + } + } } ////////////////////////////// //- rjf: build toggle-switch // - if(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active) - UI_Parent(box) + if(build_toggle_switch) UI_Parent(box) { B32 is_toggled = !!params->toggled_out[0]; F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); @@ -3307,8 +3491,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: build slider // - if(params->flags & RD_CellFlag_Slider && !is_focus_active) - UI_Parent(box) + if(build_slider) UI_Parent(box) { F32 height_px = ceil_f32(ui_top_font_size() * 1.75f); F32 padding_px = ceil_f32((ui_top_px_height() - height_px) / 2.f); @@ -3438,20 +3621,6 @@ rd_cell(RD_CellParams *params, String8 string) sig.f |= UI_SignalFlag_Commit; } - ////////////////////////////// - //- rjf: determine autocompletion string - // - String8 autocomplete_hint_string = {0}; - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - autocomplete_hint_string = evt->string; - } - } - } - ////////////////////////////// //- rjf: take navigation actions for editing // @@ -3521,128 +3690,13 @@ rd_cell(RD_CellParams *params, String8 string) // TxtPt mouse_pt = {0}; F32 cursor_off = 0; - UI_Parent(scrollable_box) + if(scrollable_box != &ui_nil_box) UI_Parent(scrollable_box) { - Temp scratch = scratch_begin(0, 0); - - //- rjf: compute fancy strings - DR_FStrList fstrs = {0}; - { - //- rjf: (not editing) - if(!is_focus_active && !is_focus_active_disabled && params->expr_fstrs.total_size != 0) - { - fstrs = params->expr_fstrs; - } - else if(!is_focus_active && !is_focus_active_disabled && params->eval_fstrs.total_size != 0) - { - fstrs = params->eval_fstrs; - } - else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents && params->pre_edit_value.size != 0) - { - String8 display_string = params->pre_edit_value; - fstrs = rd_fstrs_from_code_string(scratch.arena, 1, 0, ui_color_from_name(str8_lit("text")), display_string); - } - else if(!is_focus_active && !is_focus_active_disabled) - { - String8 display_string = params->pre_edit_value; - if(params->pre_edit_value.size == 0) - { - display_string = ui_display_part_from_key_string(string); - } - UI_TagF("weak") - { - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, display_string); - } - } - - //- rjf: (editing) - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); - if(autocomplete_hint_string.size != 0) - { - String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); - U64 off = 0; - U64 cursor_off = params->cursor->column-1; - DR_FStrNode *prev_n = 0; - for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) - { - if(off <= cursor_off && cursor_off <= off+n->v.string.size) - { - prev_n = n; - break; - } - off += n->v.string.size; - } - { - DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *fstr = &autocomp_fstr_n->v; - fstr->string = autocomplete_append_string; - fstr->params.font = ui_top_font(); - fstr->params.color = ui_color_from_name(str8_lit("text")); - fstr->params.color.w *= 0.5f; - fstr->params.size = ui_top_font_size(); - autocomp_fstr_n->next = prev_n ? prev_n->next : 0; - if(prev_n != 0) - { - prev_n->next = autocomp_fstr_n; - } - if(prev_n == 0) - { - code_fstrs.first = code_fstrs.last = autocomp_fstr_n; - } - if(prev_n != 0 && prev_n->next == 0) - { - code_fstrs.last = autocomp_fstr_n; - } - code_fstrs.node_count += 1; - code_fstrs.total_size += autocomplete_hint_string.size; - if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) - { - String8 full_string = prev_n->v.string; - U64 chop_amt = full_string.size - (cursor_off - off); - prev_n->v.string = str8_chop(full_string, chop_amt); - code_fstrs.total_size -= chop_amt; - if(chop_amt != 0) - { - String8 post_cursor = str8_skip(full_string, cursor_off - off); - DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *post_fstr = &post_fstr_n->v; - MemoryCopyStruct(post_fstr, &prev_n->v); - post_fstr->string = post_cursor; - if(autocomp_fstr_n->next == 0) - { - code_fstrs.last = post_fstr_n; - } - post_fstr_n->next = autocomp_fstr_n->next; - autocomp_fstr_n->next = post_fstr_n; - code_fstrs.node_count += 1; - code_fstrs.total_size += post_cursor.size; - } - } - } - } - fstrs = code_fstrs; - } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); - } - } - - //- rjf: compute fuzzy match ranges FuzzyMatchRangeList fuzzy_matches = {0}; if(params->search_needle.size != 0) { fuzzy_matches = dr_fuzzy_match_find_from_fstrs(scratch.arena, &fstrs, params->search_needle); } - - //- rjf: build textual content if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) { ui_spacer(ui_em(0.5f, 1.f)); @@ -3674,24 +3728,6 @@ rd_cell(RD_CellParams *params, String8 string) mouse_pt = txt_pt(1, 1+mouse_pt_off); cursor_off = fnt_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, params->cursor->column-1)).x; } - - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: build description - // - if(params->description.size != 0) UI_Parent(lhs_box) UI_HeightFill RD_Font(RD_FontSlot_Main) UI_FontSize(ui_top_font_size()*0.85f) - { - UI_Row - { - ui_spacer(ui_em(0.5f, 1.f)); - ui_label(params->description); - } - } - UI_Parent(lhs_box) - { - ui_spacer(ui_em(3.f, 0.f)); } ////////////////////////////// @@ -3741,6 +3777,7 @@ rd_cell(RD_CellParams *params, String8 string) if(is_auto_focus_active) { ui_pop_focus_active(); } ProfEnd(); + scratch_end(scratch); return sig; } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index c657689c..293f115e 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -42,8 +42,8 @@ struct RD_CellParams RD_CellFlags flags; S32 depth; String8 pre_edit_value; - DR_FStrList expr_fstrs; - DR_FStrList eval_fstrs; + DR_FStrList meta_fstrs; + DR_FStrList value_fstrs; String8 search_needle; String8 description; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 49c14597..33edb2e6 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -944,6 +944,9 @@ internal F32 ui_anim_(UI_Key key, UI_AnimParams *params); //////////////////////////////// //~ rjf: Stacks +internal void ui__push_tags_key_from_appended_string(String8 string); +internal void ui__pop_tags_key(void); + //- rjf: base internal UI_Box * ui_top_parent(void); internal Axis2 ui_top_child_layout_axis(void); From 5aae5cc4bb1c7fe16c3b9c35e1c4de63f1ee10a8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 15:29:58 -0700 Subject: [PATCH 426/755] more work on combined cell path, debugging, fixes --- data/icons.ttf | Bin 24648 -> 24608 bytes src/raddbg/generated/raddbg.meta.c | 27 +- src/raddbg/generated/raddbg.meta.h | 712 +++++++++++++++-------------- src/raddbg/raddbg.mdesk | 35 +- src/raddbg/raddbg_core.c | 57 ++- src/raddbg/raddbg_views.c | 8 +- src/raddbg/raddbg_widgets.c | 280 ++++++------ src/ui/ui_core.h | 3 + 8 files changed, 586 insertions(+), 536 deletions(-) diff --git a/data/icons.ttf b/data/icons.ttf index c2be53be1e0f11f200cad43684b8ae97d5d19e6b..f9d82393f926fa3675552a4eedf756649d0a0778 100644 GIT binary patch delta 722 zcmXYtUr1AN6vxl+-n)Bu_wVk?b~opCy>sd;&1`>eh4T+mww4)&5Y&S$ryH{6Oi3eS zVlO_3DHVvKj0pEqB<&#|hlq%v{R4#p=|N&chzJWQTK$Y(&i8!2-*e8xS<9eg22DCp z*;J_`;Q@eC-SKej#))5d0otMfI!!p(AIH8Pa}`!)IC`hM??cNP0J8$nI2q{*hAQ{o zzX0&J<6MqlgIT7Wn8z`fMq&d)^o2j`m=^)inP_ikuy0}X8Nm5{oIi~PhvF#96#}>d z)7X%124h_tb5-RF`f?US*<( z%#xR(7)qcF+~9+FW6Xhowjmar62U0Q79fEJk`8MS0IL8t3<_W<1rr7eR7y$}1|<+` zB@xylHA3nuSk$NkFkJF@5O{nZU+rnxTXVd+>PSUdX^Gup(rH*4ijk;e5<(?%2`1h^ zGxm~lr}wb%9=QS4quRs3D7!i2MvU8Z((5qdDF<)&dSt{Og44m1FHItngx@(V`M0qyH=OFzG*wvgyzM z29&ssz7oyEJh4LR$!0P_j+0ANlY&xQSM1Yfx`__a6Z9&bXBLth%g7%b8X(sPpxe^)aw1WsXK;NwY8EG__w3jp~cK$;^x zr!sBEf4@uy2KFNi3=TUoQWI0O=Y6kbVDP8`%9~{X1=tU#2`lK-cG z{2L4mj4nC($%!SKT6Zuoc*y|em*gf^6fnNvmtQnO+7nTMi!{x0Rscm z*@FDylGfi=ZVU{*8yFav7Z((z7QFU2HJ5=Qe!;{a(TrA`Ll{jt>NheAF>^EUGsrXO zGng|(GXy&Xcv~`YuxTnv3UV^CF)}dua4~W)uyI84ax<~9FflPOvN2>bu(R{TGw|>T z`?4}KF*0(-GjMVWa{5I^ga-Nhy1O|$s3{4nfq*g}yS%olpoy9`qY|5_poo|?qmh|8 zf-j0L0On8rDd5NS@8aYTK~=RN#!e0{E{=cYAQA_g$!PLwLB-7*xmMfC%(&mk9?x&{ zm4To61u$F~p0G#0h0^aPS9rKG3U1!#Vb56K#l*rC#k7g(2D1ut6mt#p0_HO;VXP9Y zC2SmQI&5KV6>N*xZm|oo@8aO$*uu%iX~G%Cxrp->*Bb6=JW9NLyg|Gbytnx5_!{_) z_#X*y3B(Cb5L_qtOejETjWCahh{zO?FQR&)pTz3Ku82R9aFLiJu}k8Ios_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[313]; +extern RD_VocabInfo rd_vocab_info_table[315]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; -extern String8 rd_icon_kind_text_table[74]; +extern String8 rd_icon_kind_text_table[75]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_preset_cfg_string_table[9]; @@ -663,12 +666,12 @@ extern String8 rd_theme_color_display_string_table[145]; extern String8 rd_theme_color_cfg_string_table[145]; read_only global U8 rd_icon_font_bytes__data[] = { -0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x22,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, -0x0e,0x1f,0x06,0xf3,0x00,0x00,0x51,0x5c,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x51,0x94,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x51,0x54,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x98,0xff,0x4e,0x69,0x00,0x00,0x07,0xc4,0x00,0x00,0x40,0xb8,0x68,0x65,0x61,0x64, -0x2b,0x9e,0xf7,0x7d,0x00,0x00,0x48,0x7c,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0xc2,0x04,0x27,0x00,0x00,0x48,0xb4,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x05,0x74,0xff,0xca,0x00,0x00,0x48,0xd8,0x00,0x00,0x01,0x44,0x6c,0x6f,0x63,0x61,0x74,0xb2,0x85,0xb8,0x00,0x00,0x4a,0x1c,0x00,0x00,0x00,0xa4,0x6d,0x61,0x78,0x70, -0x01,0xe8,0x0f,0x19,0x00,0x00,0x4a,0xc0,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1c,0x1d,0x00,0x00,0x4a,0xe0,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x85,0xfb,0x3a,0x46,0x00,0x00,0x4d,0xb0,0x00,0x00,0x03,0xa3,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x5f,0xa0,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, +0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, +0x0e,0x1f,0x06,0xf3,0x00,0x00,0x51,0x34,0x00,0x00,0x00,0x38,0x66,0x70,0x67,0x6d,0x62,0x31,0xfb,0x7b,0x00,0x00,0x51,0x6c,0x00,0x00,0x0e,0x0c,0x67,0x61,0x73,0x70,0x00,0x00,0x00,0x10,0x00,0x00,0x51,0x2c,0x00,0x00,0x00,0x08,0x67,0x6c,0x79,0x66,0x71,0xda,0x4c,0xc8,0x00,0x00,0x07,0xc4,0x00,0x00,0x40,0x90,0x68,0x65,0x61,0x64, +0x2b,0xeb,0xd3,0xaf,0x00,0x00,0x48,0x54,0x00,0x00,0x00,0x36,0x68,0x68,0x65,0x61,0x07,0xc2,0x04,0x27,0x00,0x00,0x48,0x8c,0x00,0x00,0x00,0x24,0x68,0x6d,0x74,0x78,0x06,0x4b,0xff,0xca,0x00,0x00,0x48,0xb0,0x00,0x00,0x01,0x44,0x6c,0x6f,0x63,0x61,0x71,0xa6,0x82,0xac,0x00,0x00,0x49,0xf4,0x00,0x00,0x00,0xa4,0x6d,0x61,0x78,0x70, +0x01,0xe8,0x0f,0x19,0x00,0x00,0x4a,0x98,0x00,0x00,0x00,0x20,0x6e,0x61,0x6d,0x65,0xcd,0x9d,0x1c,0x1d,0x00,0x00,0x4a,0xb8,0x00,0x00,0x02,0xcd,0x70,0x6f,0x73,0x74,0x77,0x9e,0x36,0x3b,0x00,0x00,0x4d,0x88,0x00,0x00,0x03,0xa2,0x70,0x72,0x65,0x70,0xeb,0x48,0xca,0x9d,0x00,0x00,0x5f,0x78,0x00,0x00,0x00,0xa7,0x00,0x01,0x00,0x00, 0x00,0x0a,0x00,0x30,0x00,0x3e,0x00,0x02,0x44,0x46,0x4c,0x54,0x00,0x0e,0x6c,0x61,0x74,0x6e,0x00,0x1a,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x6c,0x69,0x67,0x61,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x04, -0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x3a,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x03,0x3d,0x01,0x90,0x00,0x05,0x00,0x00,0x02,0x7a,0x02,0xbc,0x00,0x00,0x00,0x8c,0x02,0x7a,0x02,0xbc,0x00,0x00,0x01,0xe0,0x00,0x31,0x01,0x02,0x00,0x00,0x02,0x00,0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x66,0x45,0x64,0x00,0xc0,0x00,0x21,0x00,0x7d,0x03,0x52,0xff,0x6a,0x00,0x5a,0x03,0xac,0x00,0x96,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x04, 0x00,0x00,0x02,0x42,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x3c,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x2c,0x00,0x03,0x00,0x0a,0x00,0x00,0x02,0x42,0x00,0x04,0x01,0x10,0x00,0x00,0x00,0x18,0x00,0x10,0x00,0x03,0x00,0x08,0x00,0x23,0x00,0x2b,0x00,0x2e,0x00,0x31,0x00,0x39,0x00,0x3c,0x00,0x5b,0x00,0x5e,0x00,0x73,0x00,0x7b,0x00,0x7d, 0xff,0xff,0x00,0x00,0x00,0x21,0x00,0x26,0x00,0x2d,0x00,0x30,0x00,0x33,0x00,0x3c,0x00,0x3e,0x00,0x5d,0x00,0x61,0x00,0x75,0x00,0x7d,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x1c,0x00,0x26,0x00,0x28,0x00,0x2a,0x00,0x36, @@ -701,354 +704,353 @@ read_only global U8 rd_icon_font_bytes__data[] = 0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x03,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13, 0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xf0,0x48,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x32,0x2a,0x38,0x28,0x28,0x38,0x2a,0x46,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x01,0xdc,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x02,0x8a,0x4c,0x22,0xfe, 0x86,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0xfd,0x76,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0x30,0x28,0x3a,0x28,0x28,0x3a,0x28,0xfe,0x5c,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28, -0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x37,0x00,0x5b,0x00,0x53,0x40,0x50,0x4b,0x39,0x02,0x08,0x06,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x01,0x00,0x02,0x4c,0x0a,0x01,0x08,0x00,0x06,0x08,0x59,0x0d,0x0b,0x02,0x06,0x04,0x02,0x02,0x00,0x01,0x06,0x00,0x69,0x00, -0x07,0x07,0x0c,0x5f,0x00,0x0c,0x0c,0x13,0x4d,0x05,0x03,0x02,0x01,0x01,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x58,0x55,0x52,0x4f,0x4d,0x47,0x46,0x43,0x40,0x26,0x22,0x13,0x26,0x26,0x26,0x26,0x26,0x23,0x0e,0x07,0x1f,0x2b,0x25,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34, -0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x11,0x34,0x26,0x2b,0x01,0x22,0x06,0x15,0x11,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01, -0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0xfe,0xd1,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01, -0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x52,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x08,0x01,0x89,0x08,0x0a,0x0a,0x08,0xfe,0x77,0x08,0x0a,0x0a,0x02,0x32,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08, -0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x04,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x0b,0x00,0x08,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x52,0x40,0x4f,0x1d,0x14,0x02,0x01,0x03,0x0f,0x01,0x00,0x01,0x0e,0x0d,0x0c,0x09,0x04,0x02,0x00,0x1c,0x15, -0x02,0x04,0x02,0x04,0x4c,0x00,0x02,0x00,0x04,0x00,0x02,0x04,0x80,0x00,0x01,0x00,0x00,0x02,0x01,0x00,0x69,0x07,0x01,0x03,0x03,0x06,0x5f,0x00,0x06,0x06,0x13,0x4d,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x11,0x05,0x4e,0x11,0x10,0x2e,0x2b,0x26,0x23,0x19,0x17,0x10,0x1f,0x11,0x1f,0x13,0x13,0x12,0x08,0x07,0x19,0x2b,0x01,0x14, -0x0e,0x01,0x26,0x34,0x36,0x1e,0x01,0x01,0x15,0x21,0x35,0x37,0x17,0x01,0x25,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x37,0x21,0x32,0x36,0x27,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x65,0x3e,0x5a,0x3e,0x3e,0x5a,0x3e,0x02,0x3c,0xfc,0xee,0xb2,0x5a,0x01,0x1d,0x01,0x1e, -0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x01,0x0a,0x51,0x34,0x25,0xfc,0x83,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x02,0x11,0x2d,0x3e,0x02,0x42,0x56,0x42,0x04,0x3a,0xfe,0xfa,0xfa,0x6b,0xb3,0x59,0x01,0x1d,0xa1,0x0a,0x08,0xfd,0x5a,0x07,0x0c,0x01,0x0a,0x08,0x02,0xa6,0x08,0x0a,0x12,0xfd,0x5a,0x25,0x34, -0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x40,0x36,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01,0x4c,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x13,0x4d,0x06,0x01,0x04,0x04,0x00, -0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46, -0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x03,0xff,0xff,0xff,0x6a,0x04,0x78, -0x03,0x52,0x00,0x03,0x00,0x0c,0x00,0x26,0x00,0x38,0x40,0x35,0x00,0x08,0x00,0x03,0x04,0x08,0x03,0x67,0x07,0x01,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x00,0x05,0x00,0x02,0x05,0x67,0x00,0x00,0x06,0x06,0x00,0x57,0x00,0x00,0x00,0x06,0x60,0x00,0x06,0x00,0x06,0x50,0x33,0x25,0x33,0x26,0x21,0x11,0x11,0x11,0x10,0x09,0x07, -0x1f,0x2b,0x17,0x21,0x11,0x29,0x02,0x11,0x21,0x15,0x33,0x32,0x16,0x15,0x01,0x11,0x14,0x06,0x23,0x21,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x8f,0x01,0xac,0xfe,0x54,0x02,0x3b,0x01,0x1e,0xfe,0x53,0x36,0x25,0x34,0x01,0xad,0x34,0x25,0xfe,0xac,0x34,0x25,0xfd,0xe8, -0x24,0x36,0x01,0x34,0x25,0x01,0x54,0x34,0x25,0x02,0x18,0x24,0x36,0x07,0x01,0x1e,0x01,0xac,0x8f,0x34,0x25,0x01,0x1e,0xfd,0xe8,0x25,0x34,0xc5,0x25,0x34,0x34,0x25,0x02,0x18,0x25,0x34,0xc5,0x25,0x34,0x34,0x00,0x01,0xff,0xff,0xff,0xb1,0x03,0xe8,0x00,0xcf,0x00,0x0f,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00, -0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x25,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x76,0x6b,0x25,0x34,0x01,0x36,0x24,0x6b,0x25,0x34,0x34,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0xa1,0x03,0x0b,0x00,0x03, -0x00,0x07,0x00,0x1f,0x00,0x1f,0x40,0x1c,0x07,0x06,0x05,0x03,0x02,0x01,0x00,0x07,0x00,0x01,0x01,0x4c,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x13,0x00,0x4e,0x1b,0x1e,0x02,0x07,0x18,0x2b,0x05,0x25,0x11,0x05,0x27,0x2d,0x01,0x0d,0x01,0x11,0x14,0x06,0x07,0x05,0x06,0x22,0x27,0x25,0x2e,0x01,0x35,0x11,0x34,0x36,0x37,0x25,0x36, -0x32,0x17,0x05,0x1e,0x01,0x01,0xf4,0x01,0x65,0xfe,0x9b,0x24,0x01,0x86,0xfe,0x7a,0xfe,0x7b,0x03,0x56,0x14,0x12,0xfe,0x77,0x0f,0x26,0x0f,0xfe,0x77,0x11,0x14,0x1a,0x15,0x01,0x89,0x0c,0x18,0x0d,0x01,0x89,0x15,0x1a,0x3b,0xc3,0x01,0x63,0x82,0x3f,0x8d,0x8e,0x8e,0x01,0xfe,0x54,0x14,0x22,0x09,0xd6,0x09,0x09,0xd6,0x0a,0x20,0x15, -0x01,0xac,0x17,0x24,0x08,0x8f,0x05,0x05,0x8f,0x08,0x24,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44,0x02,0x80,0x00,0x13,0x00,0x31,0x40,0x2e,0x00,0x05,0x00,0x02,0x05,0x59,0x04,0x06,0x02,0x00,0x03,0x01,0x01,0x02,0x00,0x01,0x67,0x00,0x05,0x05,0x02,0x61,0x00,0x02,0x05,0x02,0x51,0x01,0x00,0x11,0x10,0x0e,0x0c,0x0b,0x09,0x07, -0x06,0x04,0x02,0x00,0x13,0x01,0x13,0x07,0x07,0x16,0x2b,0x01,0x32,0x14,0x2b,0x01,0x15,0x14,0x22,0x3d,0x01,0x23,0x22,0x34,0x3b,0x01,0x35,0x34,0x32,0x1d,0x01,0x02,0x26,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0x01,0x90,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44, -0x01,0x90,0x00,0x07,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x57,0x02,0x01,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x05,0x02,0x00,0x07,0x01,0x06,0x03,0x07,0x16,0x2b,0x01,0x32,0x14,0x23,0x21,0x22,0x34,0x33,0x02,0x26,0x1e,0x1e,0xfd,0xf8,0x1e,0x1e,0x01,0x90,0x64,0x64,0x00,0x00,0x00,0x01,0xff,0xfd, -0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, -0x74,0xc4,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02, -0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d,0x00,0x42,0x00,0x48,0x40,0x45,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80, -0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x13,0x02,0x4e,0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, -0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e, -0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e,0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e, -0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01,0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f, -0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0x5d,0x40,0x5a,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a,0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x13,0x4d,0x00, -0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34, -0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06,0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b, -0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05, -0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a, -0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11,0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08,0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a, -0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x18,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01, -0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26,0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02,0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46, -0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36,0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c,0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0x94,0xb5,0x25, -0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x31,0x0d, -0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23, -0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15,0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17,0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15, -0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a,0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04,0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c, -0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07, -0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e,0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, -0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa,0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16,0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00, -0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b,0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e, -0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14,0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01,0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b, -0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27, -0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05,0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e,0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c, -0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05, -0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06,0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03, -0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04,0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00, -0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00,0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27,0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00, -0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15,0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe, -0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52,0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08,0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee, -0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04,0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f,0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d, -0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x3a,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x29,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40,0x10,0x00,0x01,0x00,0x01,0x86,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x00,0x4e,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07, -0x19,0x2b,0x13,0x34,0x26,0x0e,0x01,0x1e,0x02,0x36,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x2e,0x01,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x17,0x01,0x16,0xfa,0x2a,0x3a,0x2c,0x02,0x28,0x3e,0x26,0x02,0x55,0x14,0xfe,0xee,0x16,0x3b,0x14,0xfe,0x71,0x15,0x1e,0x2a,0x1d,0xe9,0x1d,0x48,0x15,0x01,0x8f,0x14,0x02,0x58,0x1e,0x2a, -0x02,0x26,0x40,0x24,0x06,0x30,0xfe,0xd9,0x1e,0x15,0xfe,0xee,0x15,0x15,0x01,0x8f,0x15,0x48,0x1d,0xe8,0x1d,0x2a,0x01,0x1e,0x15,0xfe,0x71,0x15,0x00,0x0d,0x00,0x00,0xff,0xea,0x03,0xca,0x02,0xd2,0x00,0x03,0x00,0x07,0x00,0x0b,0x00,0x0f,0x00,0x13,0x00,0x17,0x00,0x1b,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2f,0x00,0x33, -0x00,0xa9,0x40,0xa6,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10,0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e, -0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33,0x30,0x33,0x32,0x31,0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f, -0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21,0x07,0x17,0x2b,0x15,0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01, -0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0xe1,0x9e,0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16, -0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x20,0x40,0x1d,0x00,0x04, -0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x13,0x03,0x4e,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f,0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16, -0x1d,0x01,0x21,0x32,0x16,0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29, -0xdd,0x03,0x07,0x05,0x02,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x16,0x40,0x13,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00,0x01,0x01,0x13,0x01,0x4e,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36, -0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1d,0x40,0x1a,0x01,0x01,0x00,0x49, -0x00,0x01,0x00,0x01,0x85,0x03,0x02,0x02,0x00,0x00,0x76,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78,0x01,0x6e,0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x26, -0x40,0x23,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00,0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e,0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36, -0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59,0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02,0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a, -0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11, -0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05,0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08,0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08, -0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e,0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x45,0x40,0x42,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x06, -0x01,0x04,0x00,0x03,0x02,0x04,0x03,0x69,0x00,0x00,0x00,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17, -0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27,0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b, -0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b,0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06, -0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d,0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01,0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54, -0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c, -0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00,0x00,0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x47,0x40,0x44,0x0f,0x09,0x02,0x03, -0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06,0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x13,0x06,0x4e,0x8e,0x8b,0x86,0x83,0x7e,0x7b,0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f, -0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32, -0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32, -0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20, -0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17, -0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe, -0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0x01,0x08,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25, -0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01,0x07,0x01,0x08,0x07,0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04, -0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10,0x00,0x0f,0x37,0x0d,0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11, -0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x89,0x16,0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f, -0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x01,0xe8,0x0c,0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08, -0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x6f,0x40,0x6c,0x79,0x78,0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10, -0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00,0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x13,0x08,0x4e,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64, -0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b, -0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33, -0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01, -0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b, -0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01, -0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x20,0x40,0x1d,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61, -0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01, -0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01, -0x00,0x4a,0x05,0x01,0x01,0x49,0x00,0x00,0x01,0x01,0x00,0x57,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x11,0x11,0x02,0x07,0x18,0x2b,0x01,0x15,0x21,0x11,0x21,0x15,0x01,0x01,0x7a,0x01,0x60,0xfe,0xa0,0xfe,0x86,0x02,0xda,0xbe,0xfe,0x86,0xc0,0x01,0x7c,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x52,0x00,0x0f, -0x00,0x2f,0x00,0x2e,0x40,0x2b,0x09,0x01,0x02,0x01,0x00,0x20,0x01,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x67,0x00,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x00,0x03,0x03,0x11,0x03,0x4e,0x35,0x26,0x36,0x26,0x26,0x14,0x06,0x07,0x1c,0x2b,0x01,0x11,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x33,0x21, -0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x14,0x1e,0x01,0x17,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x34,0x3e,0x01,0x35,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x0a,0x08,0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x46,0x34,0x25,0xfe,0xd1,0x12,0x10,0x01,0x14,0x0f,0xfe,0xe2,0x0f,0x14,0x01, -0x12,0x12,0xfe,0xd0,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x01,0x28,0x01,0xd1,0x07,0x0a,0x01,0x0c,0x06,0xfe,0x2f,0x07,0x0a,0x0a,0x01,0xd8,0xfd,0xa1,0x25,0x34,0x01,0x14,0x2e,0x22,0x07,0x0e,0x16,0x16,0x0e,0x08,0x22,0x2c,0x15,0x36,0x24,0x02,0x5f,0x25,0x34,0x34,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xe1,0x02,0xf8, -0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x2f,0x40,0x2c,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x03,0x00,0x51,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27,0x0f,0x01, -0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16,0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80,0x95,0x40, -0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f,0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40,0x00,0x00, -0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x28,0x40,0x25,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e,0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e, -0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74, -0x74,0xc4,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xe3,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16,0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02,0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x26,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80, -0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50,0x58,0x40,0x27,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05, -0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x29,0x50,0x58,0x40,0x28,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23, -0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x59,0x40,0x12,0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15, -0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01,0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c,0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b, -0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe,0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00,0x00,0x05,0xff,0xff,0xff,0xf9,0x03,0x59,0x02,0xc4,0x00,0x08,0x00,0x11,0x00,0x21,0x00,0x2b,0x00,0x41,0x00,0x8e,0x40,0x0f, -0x13,0x01,0x01,0x04,0x09,0x00,0x02,0x00,0x01,0x1b,0x01,0x05,0x00,0x03,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x30,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x08,0x00,0x70,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08, -0x60,0x00,0x08,0x05,0x08,0x50,0x1b,0x40,0x31,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x04,0x00,0x05,0x7e,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08,0x60,0x00,0x08,0x05,0x08,0x50,0x59,0x40,0x0e,0x3d,0x3a,0x37, -0x23,0x13,0x26,0x25,0x13,0x14,0x13,0x12,0x0a,0x07,0x1f,0x2b,0x25,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x35,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x21,0x32,0x36,0x01,0x21,0x03,0x2e,0x01,0x23,0x21,0x22,0x06,0x07,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26, -0x37,0x35,0x34,0x37,0x13,0x3e,0x01,0x17,0x21,0x32,0x16,0x17,0x13,0x16,0x02,0x44,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x91,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x41,0x0c,0x06,0xfd,0x59,0x07,0x0a,0x01,0x0c,0x06,0x02,0xa7,0x07,0x0a,0xfd,0x52,0x02,0x93,0x58,0x02,0x0e,0x07,0xfe,0x4b,0x07,0x0e,0x02,0x02,0x9e,0x34,0x25,0xfd,0x59, -0x24,0x36,0x01,0x09,0x6e,0x09,0x34,0x1e,0x01,0xb5,0x1f,0x32,0x0a,0x6e,0x09,0xab,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x14,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x6d,0xb3,0x07,0x0a,0x01,0x0c,0x06,0xb3,0x07,0x0a,0x01,0x0c,0x01,0x12,0x01,0x0d,0x07,0x0a,0x0a,0x07,0xfe,0x9a,0xb3,0x25,0x34,0x34,0x25,0xb3,0x0e,0x1c,0x01,0x52,0x1d, -0x26,0x01,0x24,0x1e,0xfe,0xae,0x1c,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13,0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21, -0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f,0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b,0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00, -0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07,0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37, -0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11,0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00, -0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x01,0x4d,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x36,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x72,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d, -0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x13,0x50,0x58,0x40,0x3c,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x70,0x0e,0x05,0x02,0x02,0x0a, -0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58,0x40,0x3d,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, -0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x40,0x44,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e, -0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a, -0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01, -0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01, -0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58,0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05,0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10, -0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02,0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a,0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54, -0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57,0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01, -0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe,0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5,0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85, -0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c,0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f, -0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5,0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03,0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67, -0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c,0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22, -0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07,0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14,0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a, -0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10,0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00,0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01, -0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10,0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f,0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22, -0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21,0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d,0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12, -0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc,0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06, -0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12,0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35,0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26, -0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21,0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12, -0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe,0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x62,0x01,0x0d,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x1c, -0x50,0x58,0x40,0x38,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x0a,0x4e,0x1b,0x4b,0xb0,0x21, -0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08, -0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10, -0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60,0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c,0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27, -0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01, -0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12,0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16, -0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07,0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7,0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19, -0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x44,0x40,0x41, -0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63,0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x13,0x06,0x4e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07, -0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x33,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11, -0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08, -0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x2d,0x40,0x2a, -0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05,0x5f,0x00,0x05,0x05,0x13,0x02,0x4e,0x35,0x35,0x35,0x36,0x26,0x23,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d,0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23, -0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43, -0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16, -0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06,0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06, -0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42,0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b,0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01, -0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09,0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07,0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07, -0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a,0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d,0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e, -0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21, -0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01,0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35,0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16, -0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c,0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01,0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15, -0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11,0x00,0x27,0x00,0x45,0x00,0x4b,0x40,0x48,0x24,0x01,0x01,0x00, -0x01,0x4c,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00,0x06,0x06,0x13,0x04,0x4e,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d,0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36, -0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d, -0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25,0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a, -0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e,0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00, -0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x26,0x40,0x23,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35, -0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe,0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33, -0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01,0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d, -0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f, -0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1b,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09, -0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12,0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01, -0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59,0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59,0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d, -0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36,0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d, -0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34,0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe, -0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7,0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d,0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3, -0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33,0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43,0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55, -0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33,0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05,0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28, -0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26,0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f,0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b, -0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8,0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14,0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf, -0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23,0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01,0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05, -0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e, -0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e,0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00, -0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14,0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01,0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c, -0x03,0x0f,0x00,0x1d,0x00,0x1b,0x40,0x18,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x00,0x00,0x00,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36,0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19, -0x0a,0x10,0x01,0x0e,0x0b,0x01,0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08, -0x00,0x13,0x00,0x29,0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01, -0x66,0x09,0x01,0x02,0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a, -0x01,0x04,0x04,0x01,0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01,0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35, -0x34,0x03,0x32,0x36,0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a,0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16, -0x0c,0x0c,0x24,0x1a,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a,0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x3b,0x40,0x38,0x2a,0x01,0x03,0x05, -0x25,0x1d,0x02,0x04,0x03,0x02,0x4c,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f, -0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56,0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d, -0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e,0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x01,0x00,0x00, -0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80,0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23, -0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15,0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16, -0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00,0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41, -0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49,0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00,0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16, -0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01,0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e,0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71, -0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda,0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01,0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13, -0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98,0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03,0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x53,0x40,0x50,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01, -0x08,0x02,0x4b,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x13,0x4d,0x05,0x02,0x02,0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b, -0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34, -0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05, -0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36,0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07,0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x02,0xff,0xff, -0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x1f,0x40,0x1c,0x00,0x01,0x01,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x34,0x11,0x10,0x04,0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x8f, -0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x32,0x40,0x2f,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69, -0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b,0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01, -0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0, -0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x35,0x40,0x32,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x00,0x03,0x02,0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x13, -0x00,0x4e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06,0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22,0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16, -0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b,0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58,0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14, -0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x4b,0x40,0x48,0x43,0x25,0x02,0x06,0x09,0x2f,0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01, -0x02,0x00,0x01,0x00,0x02,0x01,0x69,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x13,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a,0x07,0x1f,0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16, -0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x3e,0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16, -0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07,0x0c,0x01,0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e, -0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x20,0x40,0x1d,0x18,0x10, -0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x03,0x01,0x01,0x01,0x13,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10, -0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f, -0x00,0x1a,0x40,0x17,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e, -0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x3a,0x40,0x37,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x00,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x04,0x61, -0x00,0x04,0x04,0x11,0x04,0x4e,0x27,0x27,0x13,0x27,0x24,0x33,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01,0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10, -0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c,0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d,0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05, -0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74,0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01,0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06, -0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06,0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00, -0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2e,0x00,0x41,0x40,0x3e,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x13,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x01, -0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x07,0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32, -0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06,0x0a,0x0a,0x09,0x67,0x08,0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01, -0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07,0x04,0x00,0x02,0x01,0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14, -0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x14,0x0f,0x01,0x17,0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10, -0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x0f,0x2e,0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x34,0x40,0x31, -0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17,0x33,0x32,0x36,0x25, -0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18,0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14,0x0f,0xfc,0xa6,0x0e, -0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16,0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67,0x00,0x61,0x40,0x5e, -0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08,0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06,0x06,0x12,0x0b,0x4e, -0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b,0x01,0x22,0x0e,0x01, -0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x05,0x32, -0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46,0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a,0x38,0x28,0x8a,0x2a, -0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x8c,0x34,0x6c, -0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x3e,0x40,0x3b,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x02,0x01,0x00,0x01, -0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x13,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x35,0x35,0x23,0x33,0x16,0x23,0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06, -0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43, -0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f, -0x00,0x1f,0x00,0x1f,0x40,0x1c,0x00,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07,0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37, -0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00, -0x00,0x01,0x00,0x00,0x98,0xdf,0x81,0x07,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xed,0x00,0x00,0x00,0x00,0xe4,0x07,0x59,0xee,0xff,0xf5,0xff,0x6a,0x04,0x78,0x03,0x53,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x76, -0xff,0xf5,0xff,0xf5,0x04,0x78,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0x11,0x00,0x00,0x04,0x2f,0xff,0xff,0x00,0xf0,0x00,0x00,0x04,0x76,0xff,0xff,0x03,0xe8,0xff,0xff,0x03,0xe8,0x00,0x00,0x02,0x44,0x00,0x00, -0x02,0x44,0x00,0x00,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0xdc,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x02,0x3b,0xff,0xff,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00, -0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00,0x02,0xda,0x00,0x00,0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xff, -0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0xe8,0x00,0x00, -0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff,0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe, -0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0xe0,0x01,0x8a,0x02,0x04,0x02,0x5a,0x02,0xb2,0x02,0xd8,0x03,0x24,0x03,0x5a,0x03,0x7c,0x03,0xa0,0x03,0xcc,0x04,0x56,0x05,0x18,0x05,0x74,0x06,0x08, -0x06,0x2c,0x06,0x56,0x06,0x78,0x06,0xa2,0x06,0xda,0x07,0x12,0x07,0xba,0x08,0x0c,0x08,0xb4,0x09,0x06,0x09,0x34,0x09,0x56,0x09,0xa2,0x09,0xea,0x0a,0xac,0x0b,0x96,0x0c,0x22,0x0d,0x0e,0x0d,0x52,0x0d,0x78,0x0d,0xda,0x0e,0x3e,0x0e,0x80,0x0f,0x32,0x0f,0xe2,0x10,0x0a,0x10,0x5e,0x11,0x90,0x11,0xae,0x11,0xe6,0x12,0x50,0x12,0xac, -0x13,0x0c,0x14,0x14,0x14,0x94,0x14,0xf4,0x15,0x2e,0x15,0xf2,0x16,0x7e,0x16,0xd4,0x17,0xe2,0x18,0x44,0x18,0x9c,0x18,0xba,0x18,0xf8,0x19,0x94,0x19,0xfc,0x1a,0x50,0x1a,0xcc,0x1b,0x5c,0x1b,0x90,0x1b,0xe4,0x1c,0x46,0x1c,0xd4,0x1d,0x18,0x1d,0x42,0x1d,0xa8,0x1d,0xde,0x1e,0x46,0x1e,0x94,0x1e,0xf2,0x1f,0xae,0x20,0x18,0x20,0x5c, -0x00,0x01,0x00,0x00,0x00,0x51,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00, -0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10,0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10, -0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f, -0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x35,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c, -0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76,0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46, -0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00, -0x32,0x00,0x30,0x00,0x32,0x00,0x35,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00, -0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00,0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00, -0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00,0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00, -0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00, -0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18, -0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38, -0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x01,0x4e,0x01,0x4f,0x01,0x50,0x01,0x51,0x01,0x52,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d,0x70,0x74, -0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x05,0x74,0x72,0x61,0x73,0x68,0x07,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0e,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x72,0x65,0x73,0x74,0x6f,0x72,0x65,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x69, -0x6e,0x69,0x6d,0x69,0x7a,0x65,0x04,0x63,0x75,0x62,0x65,0x04,0x70,0x6c,0x75,0x73,0x05,0x6d,0x69,0x6e,0x75,0x73,0x06,0x63,0x69,0x72,0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68,0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72, -0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x03,0x64,0x6f,0x74,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72,0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c, -0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77,0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03, -0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65,0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73,0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74, -0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x03,0x68,0x64,0x64,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65,0x6c,0x08,0x73,0x74,0x65,0x70,0x69,0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f, -0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08,0x73,0x74,0x65,0x70,0x6f,0x76,0x65,0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75, -0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x07, -0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74, -0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x70,0x69,0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f, -0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03,0x62,0x6f,0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61, -0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1, -0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58,0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06,0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00, -0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20,0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0,0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1, -0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60,0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e,0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59, -0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50,0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58, -0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58,0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20, -0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21,0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25,0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50, -0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16,0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07, -0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07,0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b,0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20, -0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0,0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08, -0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09,0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2, -0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0, -0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0, -0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42,0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20, -0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59,0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12, -0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64,0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d,0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43, -0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43,0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25, -0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44, -0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01, -0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d,0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1,0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1, -0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d,0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10, -0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58, -0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11,0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1, -0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d,0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1,0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20, -0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0,0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f,0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0, -0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42, -0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0, -0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00, -0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0, -0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43,0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20,0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59, -0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25, -0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0, -0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40, -0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a,0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06, -0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0,0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0, -0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23,0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42, -0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20, -0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0, -0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0, -0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30, -0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c,0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43, -0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23,0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1, -0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59, -0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20, -0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00, -0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00, -0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a,0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20,0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f, -0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c,0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00,0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c, -0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59,0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3,0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43, -0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00,0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d,0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00, -0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48,0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3, -0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d,0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3,0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1, -0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b, -0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b, -0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0, -0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1,0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c, -0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06, -0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1,0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00, -0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44, -0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80,0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44, -0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, +0x28,0x3a,0x28,0x00,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x1f,0x00,0x22,0x00,0x25,0x00,0x33,0x00,0x3c,0x00,0x70,0x40,0x6d,0x23,0x01,0x00,0x06,0x1d,0x01,0x09,0x00,0x27,0x20,0x02,0x07,0x05,0x03,0x4c,0x00,0x03,0x00,0x06,0x00,0x03,0x06,0x67,0x0c,0x01,0x00,0x00,0x09,0x05,0x00,0x09,0x67,0x00,0x05,0x00,0x07, +0x04,0x05,0x07,0x67,0x00,0x04,0x00,0x0a,0x08,0x04,0x0a,0x67,0x00,0x08,0x00,0x02,0x0b,0x08,0x02,0x67,0x0d,0x01,0x0b,0x01,0x01,0x0b,0x57,0x0d,0x01,0x0b,0x0b,0x01,0x5f,0x00,0x01,0x0b,0x01,0x4f,0x34,0x34,0x01,0x00,0x34,0x3c,0x34,0x3c,0x3b,0x39,0x36,0x35,0x30,0x2f,0x2e,0x2c,0x29,0x28,0x25,0x24,0x22,0x21,0x1a,0x17,0x0e,0x0c, +0x09,0x06,0x00,0x1f,0x01,0x1e,0x0e,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x15,0x36,0x33,0x0f,0x01,0x33,0x01,0x07,0x33,0x17,0x37,0x35,0x23,0x15,0x14,0x06,0x07,0x23,0x11,0x21,0x35,0x34,0x36,0x01,0x11, +0x23,0x15,0x14,0x06,0x27,0x23,0x11,0x03,0xb2,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0xfe,0xd1,0x17,0x1e,0x01,0x16,0x10,0xe4,0x0f,0x36,0x16,0xe8,0x17,0x1e,0x01,0x26,0x21,0x47,0xa7,0xa7,0xfe,0x9b,0xa7,0xa7,0x6d,0xb0,0xd6,0x1e,0x17,0xe9,0x01,0x1e,0x16,0x02,0x26,0xd7,0x1e,0x17,0xe8,0x02,0x7c,0x20,0x16,0xfd,0x5a, +0x17,0x1e,0x01,0x20,0x16,0xa0,0x20,0x16,0x01,0x77,0x16,0x36,0x0f,0xe4,0x10,0x16,0x20,0x16,0xb7,0x17,0x77,0xa7,0x01,0x7d,0xa7,0xc2,0xb0,0xe9,0xe9,0x16,0x1e,0x01,0xfe,0x9b,0x8f,0x16,0x36,0xfe,0x4e,0x02,0x83,0xe8,0x16,0x20,0x01,0xfe,0x9a,0x00,0x00,0x04,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x0b,0x00,0x08,0x00,0x0f,0x00,0x1f, +0x00,0x2f,0x00,0x52,0x40,0x4f,0x1d,0x14,0x02,0x01,0x03,0x0f,0x01,0x00,0x01,0x0e,0x0d,0x0c,0x09,0x04,0x02,0x00,0x1c,0x15,0x02,0x04,0x02,0x04,0x4c,0x00,0x02,0x00,0x04,0x00,0x02,0x04,0x80,0x00,0x01,0x00,0x00,0x02,0x01,0x00,0x69,0x07,0x01,0x03,0x03,0x06,0x5f,0x00,0x06,0x06,0x13,0x4d,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05, +0x11,0x05,0x4e,0x11,0x10,0x2e,0x2b,0x26,0x23,0x19,0x17,0x10,0x1f,0x11,0x1f,0x13,0x13,0x12,0x08,0x07,0x19,0x2b,0x01,0x14,0x0e,0x01,0x26,0x34,0x36,0x1e,0x01,0x01,0x15,0x21,0x35,0x37,0x17,0x01,0x25,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x37,0x21,0x32,0x36,0x27,0x11,0x34,0x26,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11, +0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x65,0x3e,0x5a,0x3e,0x3e,0x5a,0x3e,0x02,0x3c,0xfc,0xee,0xb2,0x5a,0x01,0x1d,0x01,0x1e,0xfc,0x83,0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x01,0x0a,0x51,0x34,0x25,0xfc,0x83,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x02,0x11,0x2d,0x3e,0x02,0x42,0x56,0x42,0x04,0x3a,0xfe,0xfa,0xfa, +0x6b,0xb3,0x59,0x01,0x1d,0xa1,0x0a,0x08,0xfd,0x5a,0x07,0x0c,0x01,0x0a,0x08,0x02,0xa6,0x08,0x0a,0x12,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xba,0x00,0xf0,0x03,0x02,0x00,0x13,0x00,0x1c,0x00,0x25,0x00,0x39,0x40,0x36,0x13,0x0a,0x09,0x00,0x04,0x05,0x02,0x01, +0x4c,0x00,0x02,0x00,0x05,0x04,0x02,0x05,0x69,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x13,0x4d,0x06,0x01,0x04,0x04,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x1e,0x1d,0x22,0x21,0x1d,0x25,0x1e,0x25,0x13,0x17,0x19,0x14,0x07,0x07,0x1a,0x2b,0x37,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x11,0x26,0x35,0x34,0x36,0x32,0x16, +0x15,0x14,0x07,0x27,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0xa8,0x48,0x46,0x64,0x46,0x48,0x48,0x46,0x64,0x46,0x48,0x74,0x28,0x38,0x2a,0x2a,0x38,0x28,0x44,0x1c,0x2a,0x2a,0x38,0x28,0x28,0xa2,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x01,0x7a,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c, +0x22,0x6e,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x46,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x03,0xff,0xff,0xff,0x6a,0x04,0x78,0x03,0x52,0x00,0x03,0x00,0x0c,0x00,0x26,0x00,0x38,0x40,0x35,0x00,0x08,0x00,0x03,0x04,0x08,0x03,0x67,0x07,0x01,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x00,0x05,0x00,0x02,0x05,0x67,0x00,0x00,0x06, +0x06,0x00,0x57,0x00,0x00,0x00,0x06,0x60,0x00,0x06,0x00,0x06,0x50,0x33,0x25,0x33,0x26,0x21,0x11,0x11,0x11,0x10,0x09,0x07,0x1f,0x2b,0x17,0x21,0x11,0x29,0x02,0x11,0x21,0x15,0x33,0x32,0x16,0x15,0x01,0x11,0x14,0x06,0x23,0x21,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x35,0x34,0x36,0x33,0x21,0x32,0x16, +0x8f,0x01,0xac,0xfe,0x54,0x02,0x3b,0x01,0x1e,0xfe,0x53,0x36,0x25,0x34,0x01,0xad,0x34,0x25,0xfe,0xac,0x34,0x25,0xfd,0xe8,0x24,0x36,0x01,0x34,0x25,0x01,0x54,0x34,0x25,0x02,0x18,0x24,0x36,0x07,0x01,0x1e,0x01,0xac,0x8f,0x34,0x25,0x01,0x1e,0xfd,0xe8,0x25,0x34,0xc5,0x25,0x34,0x34,0x25,0x02,0x18,0x25,0x34,0xc5,0x25,0x34,0x34, +0x00,0x01,0xff,0xff,0xff,0xb1,0x03,0xe8,0x00,0xcf,0x00,0x0f,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x00,0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x25,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34, +0x76,0x6b,0x25,0x34,0x01,0x36,0x24,0x6b,0x25,0x34,0x34,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0xa1,0x03,0x0b,0x00,0x03,0x00,0x07,0x00,0x1f,0x00,0x1f,0x40,0x1c,0x07,0x06,0x05,0x03,0x02,0x01,0x00,0x07,0x00,0x01,0x01,0x4c,0x00,0x00,0x00,0x01,0x61,0x00,0x01,0x01,0x13,0x00,0x4e,0x1b,0x1e,0x02,0x07,0x18,0x2b,0x05,0x25,0x11, +0x05,0x27,0x2d,0x01,0x0d,0x01,0x11,0x14,0x06,0x07,0x05,0x06,0x22,0x27,0x25,0x2e,0x01,0x35,0x11,0x34,0x36,0x37,0x25,0x36,0x32,0x17,0x05,0x1e,0x01,0x01,0xf4,0x01,0x65,0xfe,0x9b,0x24,0x01,0x86,0xfe,0x7a,0xfe,0x7b,0x03,0x56,0x14,0x12,0xfe,0x77,0x0f,0x26,0x0f,0xfe,0x77,0x11,0x14,0x1a,0x15,0x01,0x89,0x0c,0x18,0x0d,0x01,0x89, +0x15,0x1a,0x3b,0xc3,0x01,0x63,0x82,0x3f,0x8d,0x8e,0x8e,0x01,0xfe,0x54,0x14,0x22,0x09,0xd6,0x09,0x09,0xd6,0x0a,0x20,0x15,0x01,0xac,0x17,0x24,0x08,0x8f,0x05,0x05,0x8f,0x08,0x24,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44,0x02,0x80,0x00,0x13,0x00,0x31,0x40,0x2e,0x00,0x05,0x00,0x02,0x05,0x59,0x04,0x06,0x02,0x00,0x03,0x01, +0x01,0x02,0x00,0x01,0x67,0x00,0x05,0x05,0x02,0x61,0x00,0x02,0x05,0x02,0x51,0x01,0x00,0x11,0x10,0x0e,0x0c,0x0b,0x09,0x07,0x06,0x04,0x02,0x00,0x13,0x01,0x13,0x07,0x07,0x16,0x2b,0x01,0x32,0x14,0x2b,0x01,0x15,0x14,0x22,0x3d,0x01,0x23,0x22,0x34,0x3b,0x01,0x35,0x34,0x32,0x1d,0x01,0x02,0x26,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e, +0xd2,0x64,0x01,0x90,0x64,0xd2,0x1e,0x1e,0xd2,0x64,0xd2,0x1e,0x1e,0xd2,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x44,0x01,0x90,0x00,0x07,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01,0x01,0x00,0x57,0x02,0x01,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x05,0x02,0x00,0x07,0x01,0x06,0x03,0x07,0x16,0x2b,0x01,0x32, +0x14,0x23,0x21,0x22,0x34,0x33,0x02,0x26,0x1e,0x1e,0xfd,0xf8,0x1e,0x1e,0x01,0x90,0x64,0x64,0x00,0x00,0x00,0x01,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x13,0x40,0x10,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x15,0x13,0x02,0x07,0x18,0x2b,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e, +0x01,0x03,0x59,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4,0xba,0x7e,0x01,0x5e,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x3c,0x01,0xed,0x00,0x0e,0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01, +0x00,0x51,0x35,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x26,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x3b,0x0a,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x01,0xc9,0x0e,0x0b,0xfa,0x0b,0x0b,0xfa,0x0b,0x1c,0x16,0x16,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa0,0x03,0x0b,0x00,0x2d, +0x00,0x42,0x00,0x48,0x40,0x45,0x3b,0x01,0x04,0x06,0x25,0x01,0x05,0x04,0x02,0x4c,0x00,0x07,0x01,0x02,0x01,0x07,0x02,0x80,0x00,0x06,0x02,0x04,0x02,0x06,0x04,0x80,0x00,0x04,0x05,0x02,0x04,0x05,0x7e,0x00,0x05,0x03,0x02,0x05,0x03,0x7e,0x00,0x03,0x00,0x00,0x03,0x00,0x64,0x00,0x02,0x02,0x01,0x5f,0x00,0x01,0x01,0x13,0x02,0x4e, +0x14,0x17,0x15,0x27,0x35,0x39,0x35,0x33,0x08,0x07,0x1e,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x17,0x1e,0x01,0x0f,0x01,0x06,0x23,0x27,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x3d,0x01,0x34,0x3f,0x01,0x36,0x33,0x32,0x17,0x16,0x13,0x01,0x06,0x22,0x2f,0x01, +0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x14,0x03,0x12,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x23,0x1e,0x09,0x03,0x07,0x1b,0x06,0x07,0x05,0x0d,0x0c,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x05,0x24,0x06,0x07,0x03,0x04,0x0b,0x81,0xfe,0x39,0x0d,0x24,0x0e,0xf0,0x0e, +0x0e,0x3d,0x0e,0x24,0x0e,0x93,0x01,0x69,0x0d,0x24,0x0e,0x3e,0x0d,0x01,0x4b,0xb1,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x5e,0x01,0x0e,0x04,0x13,0x06,0x1c,0x05,0x01,0x03,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x8d,0x08,0x05,0x23,0x06,0x02,0x04,0x01,0x05,0xfe,0x3a,0x0e,0x0e,0xf0,0x0d,0x24,0x0e,0x3e,0x0d,0x0d,0x93,0x01, +0x69,0x0d,0x0d,0x3d,0x0e,0x24,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0xb1,0x03,0x12,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3b,0x00,0x43,0x00,0x67,0x00,0x5d,0x40,0x5a,0x57,0x45,0x02,0x06,0x08,0x29,0x21,0x19,0x11,0x09,0x01,0x06,0x00,0x01,0x02,0x4c,0x00,0x09,0x0e,0x08,0x0e,0x09,0x08,0x80,0x0f,0x0d,0x02,0x08,0x0c,0x0a, +0x02,0x06,0x01,0x08,0x06,0x68,0x05,0x03,0x02,0x01,0x04,0x02,0x02,0x00,0x07,0x01,0x00,0x69,0x00,0x0e,0x0e,0x13,0x4d,0x00,0x07,0x07,0x0b,0x5f,0x00,0x0b,0x0b,0x11,0x0b,0x4e,0x65,0x64,0x61,0x5e,0x5b,0x59,0x53,0x52,0x4f,0x4c,0x49,0x47,0x41,0x3f,0x14,0x24,0x14,0x26,0x26,0x26,0x26,0x26,0x23,0x10,0x07,0x1f,0x2b,0x01,0x11,0x14, +0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x13,0x11,0x21,0x11,0x14,0x1e,0x01,0x33,0x21,0x32,0x3e,0x01,0x01,0x33,0x27,0x26,0x27,0x23,0x06, +0x07,0x05,0x15,0x14,0x06,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x37,0x3e,0x01,0x37,0x33,0x32,0x16,0x1f,0x01,0x33,0x32,0x16,0x01,0x1e,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8f,0x0a,0x08,0x24,0x08,0x0a,0x0a,0x08,0x24,0x08,0x0a,0x8e,0x0a,0x07,0x24, +0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x48,0xfe,0x0c,0x08,0x08,0x02,0x01,0xd0,0x02,0x08,0x08,0xfe,0x89,0xfa,0x1b,0x04,0x05,0xb1,0x06,0x04,0x01,0xeb,0x0a,0x08,0x36,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x35,0x08,0x0a,0x0a,0x08,0xac,0x27,0x09,0x2c,0x16,0xb2,0x17,0x2a,0x09,0x27,0xad,0x08,0x0a,0x01,0xb7,0xfe,0xbf,0x08,0x0a,0x0a, +0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0x08,0xfe,0xbf,0x08,0x0a,0x0a,0x08,0x01,0x41,0x08,0x0a,0x0a,0xfe,0x64,0x02,0x11,0xfd,0xef,0x0c,0x14,0x0a,0x0a,0x14,0x02,0x65,0x41,0x05,0x01,0x01,0x05,0x53,0x24,0x08,0x0a,0xfd,0xef,0x2e,0x44,0x42,0x2e,0x02,0x13,0x0a,0x08,0x24,0x08, +0x0a,0x5d,0x15,0x1c,0x01,0x1e,0x14,0x5d,0x0a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x9c,0x03,0xac,0x03,0x20,0x00,0x2a,0x00,0x34,0x40,0x09,0x20,0x1e,0x16,0x12,0x04,0x00,0x01,0x01,0x4c,0x4b,0xb0,0x18,0x50,0x58,0x40,0x0b,0x00,0x01,0x01,0x10,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x1b,0x40,0x0b,0x00,0x00,0x00,0x01,0x61,0x00, +0x01,0x01,0x10,0x00,0x4e,0x59,0xb5,0x1b,0x1a,0x13,0x02,0x07,0x17,0x2b,0x25,0x16,0x1d,0x01,0x21,0x35,0x34,0x37,0x3e,0x01,0x35,0x34,0x26,0x27,0x2e,0x03,0x27,0x34,0x36,0x3f,0x01,0x26,0x27,0x26,0x36,0x32,0x16,0x0f,0x01,0x16,0x15,0x0e,0x03,0x07,0x0e,0x01,0x15,0x14,0x16,0x02,0xe0,0xcc,0xfc,0x54,0xcc,0x5e,0x44,0x2c,0x0a,0x02, +0x0e,0x0e,0x0e,0x02,0x0a,0x04,0x04,0x08,0x04,0x04,0x5a,0xe0,0x5c,0x06,0x0c,0x12,0x02,0x0e,0x0e,0x0e,0x02,0x08,0x2e,0x46,0x80,0x48,0x32,0x6a,0x6a,0x32,0x48,0x22,0x46,0x3c,0x16,0x36,0x2e,0x0c,0x0c,0x04,0x1e,0x1c,0x10,0x14,0x02,0x04,0x32,0x26,0x36,0x74,0x74,0x36,0x58,0x08,0x22,0x1c,0x1e,0x04,0x0c,0x0c,0x30,0x34,0x16,0x3c, +0x46,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xb6,0x03,0xe8,0x03,0x08,0x00,0x18,0x00,0x20,0x00,0x2d,0x00,0x94,0xb5,0x25,0x01,0x09,0x0b,0x01,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x30,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x72,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07, +0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x1b,0x40,0x31,0x0d,0x01,0x0b,0x08,0x09,0x08,0x0b,0x09,0x80,0x0c,0x01,0x05,0x00,0x01,0x05,0x57,0x06,0x03,0x02,0x01,0x04,0x01,0x00,0x08,0x01,0x00,0x67,0x00,0x07,0x07,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x0a,0x01,0x08,0x08, +0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x59,0x40,0x1e,0x21,0x21,0x00,0x00,0x21,0x2d,0x21,0x2d,0x2c,0x2b,0x29,0x26,0x23,0x22,0x20,0x1d,0x1b,0x1a,0x00,0x18,0x00,0x18,0x12,0x24,0x35,0x22,0x11,0x0e,0x07,0x1b,0x2b,0x01,0x15,0x21,0x13,0x36,0x3b,0x01,0x36,0x3f,0x01,0x3e,0x01,0x3b,0x01,0x32,0x16,0x17,0x16,0x17,0x33,0x32,0x17, +0x13,0x21,0x35,0x03,0x07,0x21,0x27,0x26,0x2b,0x01,0x22,0x13,0x35,0x21,0x06,0x07,0x06,0x23,0x21,0x22,0x35,0x27,0x21,0x15,0x01,0xc8,0xfe,0x38,0x0a,0x04,0x60,0xa0,0x10,0x15,0x17,0x0e,0x12,0x1c,0xde,0x1a,0x14,0x0c,0x12,0x2a,0xa0,0x60,0x04,0x0a,0xfe,0x3a,0xa4,0x1c,0x01,0x24,0x1c,0x0e,0x1c,0x98,0x1c,0x96,0x01,0xae,0x06,0x04, +0x06,0x54,0xfd,0x12,0x5a,0x0a,0x01,0xae,0x01,0x46,0x64,0x01,0x24,0x6c,0x1a,0x29,0x2d,0x1a,0x0c,0x0e,0x18,0x20,0x50,0x6c,0xfe,0xdc,0x64,0x01,0x62,0x36,0x36,0x1a,0xfd,0x8a,0x64,0x58,0x4e,0x54,0x54,0xa6,0x64,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xdc,0x01,0xcc,0x00,0x08,0x00,0x20,0x40,0x1d,0x02,0x01,0x00,0x01, +0x01,0x00,0x59,0x02,0x01,0x00,0x00,0x01,0x61,0x00,0x01,0x00,0x01,0x51,0x01,0x00,0x05,0x04,0x00,0x08,0x01,0x08,0x03,0x07,0x16,0x2b,0x13,0x32,0x16,0x14,0x06,0x22,0x26,0x34,0x36,0x6e,0x2e,0x40,0x40,0x5c,0x40,0x40,0x01,0xcc,0x40,0x5a,0x42,0x42,0x5a,0x40,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x67,0x02,0x7c,0x00,0x0d, +0x00,0x1e,0x40,0x1b,0x00,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x13,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x16,0x01,0x65,0x14,0x20,0x09,0xfa,0x0a,0x0a,0xfa,0x0b,0x1c,0x18,0x02,0x58,0xfe,0x0c,0x0e,0x16, +0x0b,0xfa,0x0b,0x1c,0x0b,0xfa,0x0b,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x41,0x02,0x7d,0x00,0x0e,0x00,0x0a,0xb7,0x00,0x00,0x00,0x76,0x14,0x01,0x07,0x17,0x2b,0x01,0x14,0x0f,0x01,0x06,0x22,0x26,0x35,0x11,0x34,0x3e,0x01,0x1f,0x01,0x16,0x01,0x41,0x0a,0xfa,0x0b,0x1c,0x16,0x16,0x1c,0x0b,0xfa,0x0a,0x01,0x5e,0x0e,0x0b,0xfa, +0x0b,0x16,0x0e,0x01,0xf4,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x02,0x3b,0x01,0xc9,0x00,0x0e,0x00,0x18,0x40,0x15,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x15,0x32,0x02,0x07,0x18,0x2b,0x25,0x14,0x06,0x27,0x21,0x22,0x2e,0x01,0x3f,0x01,0x36,0x32,0x1f,0x01, +0x16,0x02,0x3b,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x02,0x0c,0xfa,0x0a,0x1e,0x0a,0xfa,0x0a,0xab,0x0e,0x16,0x01,0x14,0x1e,0x0b,0xfa,0x0a,0x0a,0xfa,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x5e,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x03,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00, +0x61,0x00,0x00,0x01,0x00,0x51,0x17,0x19,0x02,0x07,0x18,0x2b,0x01,0x14,0x0f,0x01,0x17,0x16,0x14,0x0f,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x37,0x01,0x36,0x32,0x1f,0x01,0x16,0x01,0x5e,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0xfe,0xfc,0x06,0x06,0x01,0x04,0x05,0x10,0x04,0x1c,0x06,0x02,0x22,0x07,0x05,0xdc,0xdb,0x06,0x0e, +0x06,0x1c,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0x1c,0x05,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x4c,0x02,0x51,0x00,0x15,0x00,0x1e,0x40,0x1b,0x0b,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x01,0x59,0x00,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x1c,0x14,0x02,0x07,0x18,0x2b,0x01,0x14,0x07,0x01, +0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x17,0x01,0x16,0x01,0x4c,0x05,0xfe,0xfb,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x10,0x04,0x01,0x05,0x05,0x01,0x3a,0x07,0x05,0xfe,0xfb,0x05,0x05,0x1c,0x06,0x0e,0x06,0xdb,0xdc,0x05,0x0e,0x06,0x1c,0x06,0x06,0xfe,0xfc,0x05,0x00, +0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x16,0x00,0x3f,0x00,0x83,0x40,0x0b,0x38,0x36,0x02,0x03,0x05,0x13,0x01,0x02,0x03,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x24,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x00,0x01,0x02,0x01,0x66,0x00,0x04, +0x04,0x00,0x61,0x07,0x01,0x00,0x00,0x12,0x04,0x4e,0x1b,0x40,0x2b,0x00,0x05,0x06,0x03,0x06,0x05,0x03,0x80,0x07,0x01,0x00,0x00,0x04,0x06,0x00,0x04,0x69,0x00,0x06,0x00,0x03,0x02,0x06,0x03,0x69,0x08,0x01,0x02,0x01,0x01,0x02,0x59,0x08,0x01,0x02,0x02,0x01,0x62,0x00,0x01,0x02,0x01,0x52,0x59,0x40,0x19,0x0a,0x09,0x01,0x00,0x27, +0x26,0x22,0x20,0x1d,0x1b,0x11,0x0e,0x09,0x16,0x0a,0x16,0x05,0x04,0x00,0x08,0x01,0x08,0x09,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x13,0x32,0x36,0x35,0x36,0x26,0x2b,0x01,0x22,0x06,0x07,0x14,0x16,0x17,0x13,0x36,0x35,0x34,0x26,0x23,0x22,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x32,0x17,0x16,0x15, +0x14,0x07,0x06,0x0f,0x01,0x06,0x0f,0x01,0x06,0x07,0x06,0x07,0x15,0x33,0x35,0x34,0x37,0x36,0x3f,0x01,0x36,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xbc,0x1e,0x26,0x02,0x26,0x1e,0x02,0x1c,0x26,0x02,0x26,0x1c,0xa8,0x1a,0x6a,0x52,0x40,0x28,0x44,0x04,0x6e,0x10,0x10,0x4e,0x0c,0x10,0x10,0x08, +0x0c,0x16,0x0a,0x0a,0x15,0x0b,0x06,0x0e,0x04,0x6c,0x04,0x06,0x16,0x1c,0x2e,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0xfd,0x1e,0x26,0x1c,0x1e,0x26,0x24,0x1c,0x1e,0x26,0x02,0x01,0x48,0x22,0x2c,0x4e,0x4c,0x1a,0x2a,0x68,0x04,0x04,0x1a,0x1c,0x18,0x14,0x14,0x18,0x12,0x16,0x0c,0x08,0x0f, +0x07,0x08,0x11,0x09,0x08,0x14,0x3a,0x08,0x04,0x0c,0x10,0x14,0x10,0x12,0x22,0x00,0x00,0x02,0x00,0x00,0xff,0xbd,0x03,0x4d,0x03,0x0b,0x00,0x08,0x00,0x1d,0x00,0x3a,0xb5,0x00,0x01,0x01,0x00,0x01,0x4c,0x4b,0xb0,0x29,0x50,0x58,0x40,0x10,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x1b,0x40, +0x10,0x00,0x01,0x00,0x01,0x86,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x13,0x00,0x4e,0x59,0xb5,0x38,0x1a,0x12,0x03,0x07,0x19,0x2b,0x13,0x34,0x26,0x0e,0x01,0x1e,0x02,0x36,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x2e,0x01,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x17,0x01,0x16,0xfa,0x2a,0x3a,0x2c,0x02,0x28,0x3e,0x26,0x02, +0x55,0x14,0xfe,0xee,0x16,0x3b,0x14,0xfe,0x71,0x15,0x1e,0x2a,0x1d,0xe9,0x1d,0x48,0x15,0x01,0x8f,0x14,0x02,0x58,0x1e,0x2a,0x02,0x26,0x40,0x24,0x06,0x30,0xfe,0xd9,0x1e,0x15,0xfe,0xee,0x15,0x15,0x01,0x8f,0x15,0x48,0x1d,0xe8,0x1d,0x2a,0x01,0x1e,0x15,0xfe,0x71,0x15,0x00,0x0d,0x00,0x00,0xff,0xea,0x03,0xca,0x02,0xd2,0x00,0x03, +0x00,0x07,0x00,0x0b,0x00,0x0f,0x00,0x13,0x00,0x17,0x00,0x1b,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x2b,0x00,0x2f,0x00,0x33,0x00,0xa9,0x40,0xa6,0x18,0x12,0x0c,0x03,0x06,0x00,0x07,0x00,0x06,0x07,0x80,0x20,0x19,0x13,0x1d,0x0d,0x05,0x07,0x03,0x00,0x07,0x03,0x7e,0x17,0x11,0x0b,0x03,0x05,0x02,0x04,0x02,0x05,0x04,0x80,0x16,0x10, +0x0a,0x03,0x04,0x01,0x02,0x04,0x01,0x7e,0x00,0x00,0x14,0x1e,0x0f,0x08,0x1b,0x05,0x03,0x02,0x00,0x03,0x67,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x05,0x01,0x02,0x58,0x1f,0x15,0x0e,0x1c,0x09,0x05,0x02,0x02,0x01,0x5f,0x1a,0x01,0x01,0x02,0x01,0x4f,0x30,0x30,0x28,0x28,0x1c,0x1c,0x18,0x18,0x10,0x10,0x04,0x04,0x00,0x00,0x30,0x33, +0x30,0x33,0x32,0x31,0x2f,0x2e,0x2d,0x2c,0x28,0x2b,0x28,0x2b,0x2a,0x29,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1c,0x1f,0x1c,0x1f,0x1e,0x1d,0x18,0x1b,0x18,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14,0x10,0x13,0x10,0x13,0x12,0x11,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x04,0x07,0x04,0x07,0x06,0x05,0x00,0x03,0x00,0x03,0x11,0x21, +0x07,0x17,0x2b,0x15,0x11,0x21,0x11,0x01,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x05,0x15,0x33,0x35,0x03,0x33,0x35,0x23,0x13,0x23,0x15,0x33,0x17,0x35,0x23,0x1d,0x01,0x33,0x35,0x23,0x13,0x35,0x23,0x15,0x03,0xca,0xfe,0x3d,0x9f,0x9f,0x9f,0x9f,0x9f, +0x9f,0x9f,0xe1,0x9e,0x9e,0x9e,0x9e,0x9e,0xfd,0x5b,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0xe1,0x9d,0x9d,0x9d,0x9d,0x9d,0x16,0x02,0xe8,0xfd,0x18,0x01,0xc4,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e,0x9e,0x43,0x9f,0x9f,0xfe,0x80,0x9d,0x01,0xc4,0x9e,0xe2,0x9f,0x9f,0xe1,0x9d,0x01,0x26,0x9e, +0x9e,0x00,0x00,0x00,0x00,0x02,0xff,0xff,0xff,0xf9,0x04,0x19,0x03,0x0b,0x00,0x12,0x00,0x29,0x00,0x20,0x40,0x1d,0x00,0x04,0x00,0x02,0x01,0x04,0x02,0x68,0x00,0x01,0x00,0x00,0x01,0x00,0x63,0x00,0x03,0x03,0x13,0x03,0x4e,0x23,0x3a,0x23,0x36,0x35,0x05,0x07,0x1b,0x2b,0x01,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x2e,0x01,0x3f, +0x01,0x3e,0x01,0x33,0x21,0x32,0x16,0x27,0x15,0x21,0x22,0x06,0x0f,0x02,0x27,0x26,0x37,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x04,0x19,0x12,0xbb,0x18,0x56,0x26,0xfd,0xa1,0x13,0x1c,0x01,0x11,0xbc,0x18,0x56,0x25,0x02,0x5f,0x13,0x1e,0xc0,0xfe,0x30,0x35,0x72,0x23,0xbc,0x02,0x01,0x01,0x01,0x4a,0x33,0xb3, +0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x3f,0x11,0x14,0xdd,0x1c,0x28,0x0e,0x22,0x14,0xdd,0x1c,0x28,0x0e,0xaf,0x5a,0x34,0x29,0xdd,0x03,0x07,0x05,0x02,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x14,0x00,0x16,0x40,0x13,0x00,0x02,0x00,0x00,0x02,0x00,0x64,0x00, +0x01,0x01,0x13,0x01,0x4e,0x23,0x35,0x33,0x03,0x07,0x19,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0xa1,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x01,0xff,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33, +0x12,0x4a,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x1d,0x40,0x1a,0x01,0x01,0x00,0x49,0x00,0x01,0x00,0x01,0x85,0x03,0x02,0x02,0x00,0x00,0x76,0x00,0x00,0x00,0x06,0x00,0x06,0x11,0x12,0x04,0x07,0x18,0x2b,0x09,0x02,0x33,0x11,0x21,0x11,0x02,0xf8,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x78,0x01,0x6e, +0xfe,0x84,0x01,0x7c,0x01,0x5e,0xfe,0xa2,0x00,0x02,0xff,0xf7,0xff,0xe2,0x03,0xdb,0x03,0x12,0x00,0x17,0x00,0x20,0x00,0x26,0x40,0x23,0x00,0x02,0x01,0x02,0x85,0x03,0x01,0x01,0x00,0x00,0x01,0x59,0x03,0x01,0x01,0x01,0x00,0x61,0x00,0x00,0x01,0x00,0x51,0x19,0x18,0x1d,0x1c,0x18,0x20,0x19,0x20,0x2f,0x04,0x07,0x17,0x2b,0x01,0x1e, +0x01,0x06,0x07,0x06,0x26,0x06,0x07,0x06,0x1e,0x01,0x07,0x0e,0x02,0x23,0x22,0x26,0x37,0x3e,0x01,0x37,0x24,0x03,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x59,0x48,0x3a,0x12,0x1a,0x10,0x4c,0x54,0x26,0x1e,0x12,0x32,0x02,0x02,0x44,0xb8,0x7c,0xba,0xd2,0x0a,0x08,0xc0,0x78,0x01,0x22,0x48,0x1e,0x2c,0x2c,0x3e,0x2c,0x2c,0x02, +0x6e,0x30,0x7c,0x54,0x06,0x04,0x1c,0x08,0x2a,0x2e,0x3a,0x48,0x0e,0x1a,0x4a,0x4a,0xca,0x90,0x76,0xea,0x22,0x54,0xfd,0x8a,0x2c,0x40,0x2a,0x2a,0x40,0x2c,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x06,0x00,0x18,0x00,0x33,0x40,0x30,0x01,0x01,0x00,0x03,0x01,0x4c,0x00,0x03,0x00,0x03,0x85,0x04,0x01,0x00, +0x01,0x00,0x85,0x00,0x01,0x02,0x02,0x01,0x57,0x00,0x01,0x01,0x02,0x60,0x00,0x02,0x01,0x02,0x50,0x00,0x00,0x18,0x16,0x11,0x0e,0x0b,0x09,0x00,0x06,0x00,0x06,0x05,0x07,0x16,0x2b,0x01,0x11,0x16,0x1f,0x01,0x16,0x17,0x05,0x14,0x16,0x17,0x21,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21,0x02,0x3b,0x0d,0x08, +0xe3,0x08,0x08,0xfe,0xb1,0x20,0x16,0x01,0x2f,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xbe,0x02,0x34,0x01,0x08,0x08,0x08,0xe4,0x07,0x0d,0x12,0x16,0x1e,0x01,0xfd,0xb3,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c,0x17,0x1e,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x08,0x00,0x6a,0x00,0x45, +0x40,0x42,0x65,0x59,0x4c,0x41,0x04,0x00,0x04,0x3b,0x0a,0x02,0x01,0x00,0x34,0x28,0x1b,0x10,0x04,0x03,0x01,0x03,0x4c,0x06,0x01,0x04,0x00,0x03,0x02,0x04,0x03,0x69,0x00,0x00,0x00,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x5c,0x5b,0x53,0x51,0x49,0x48,0x2b,0x2a,0x22,0x20,0x13, +0x12,0x07,0x07,0x18,0x2b,0x01,0x34,0x26,0x22,0x0e,0x01,0x16,0x32,0x36,0x25,0x15,0x14,0x06,0x0f,0x01,0x06,0x07,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x27,0x22,0x2f,0x01,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x35,0x27,0x26,0x27,0x07,0x06,0x22,0x27,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x37,0x26,0x2f,0x01,0x2e,0x01,0x27, +0x35,0x34,0x36,0x3f,0x01,0x36,0x37,0x26,0x27,0x26,0x34,0x37,0x3e,0x01,0x33,0x32,0x1f,0x01,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x1f,0x01,0x16,0x17,0x37,0x36,0x32,0x17,0x16,0x17,0x16,0x14,0x07,0x0e,0x01,0x07,0x16,0x1f,0x01,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x01,0x1c,0x08,0x07,0x68,0x0a,0x0b, +0x13,0x28,0x06,0x05,0x0f,0x50,0x0d,0x07,0x07,0x4d,0x19,0x1a,0x09,0x07,0x04,0x10,0x7c,0x08,0x0c,0x10,0x1b,0x17,0x4f,0x06,0x10,0x06,0x46,0x16,0x04,0x05,0x08,0x28,0x0a,0x0f,0x08,0x66,0x07,0x08,0x01,0x0a,0x05,0x68,0x08,0x0e,0x17,0x25,0x06,0x05,0x0f,0x50,0x0d,0x07,0x08,0x4d,0x18,0x1a,0x09,0x08,0x03,0x11,0x7c,0x07,0x0c,0x01, +0x0f,0x1c,0x17,0x4f,0x05,0x0f,0x07,0x48,0x14,0x04,0x04,0x09,0x28,0x0a,0x0f,0x08,0x66,0x07,0x0a,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0x78,0x7c,0x07,0x0c,0x01,0x10,0x1e,0x15,0x1b,0x32,0x06,0x0e,0x06,0x15,0x50,0x01,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0c,0x3c,0x05,0x06,0x40,0x1e,0x05,0x0e,0x06,0x0c, +0x32,0x0f,0x1c,0x1b,0x0f,0x01,0x0c,0x07,0x7c,0x07,0x0c,0x01,0x10,0x19,0x1a,0x20,0x2d,0x07,0x0c,0x07,0x14,0x50,0x05,0x3c,0x0d,0x08,0x4c,0x1c,0x10,0x0a,0x07,0x67,0x09,0x0b,0x3b,0x05,0x05,0x43,0x1c,0x05,0x0e,0x06,0x0c,0x32,0x0f,0x1c,0x1a,0x10,0x01,0x0c,0x00,0x00,0x00,0x09,0x00,0x00,0xff,0xf9,0x03,0xe8,0x03,0x0b,0x00,0x0f, +0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x8f,0x00,0x47,0x40,0x44,0x0f,0x09,0x02,0x03,0x0e,0x08,0x02,0x02,0x01,0x03,0x02,0x67,0x0b,0x05,0x02,0x01,0x0a,0x04,0x02,0x00,0x01,0x00,0x63,0x10,0x0c,0x02,0x06,0x06,0x07,0x5f,0x11,0x0d,0x02,0x07,0x07,0x13,0x06,0x4e,0x8e,0x8b,0x86,0x83,0x7e,0x7b, +0x76,0x73,0x6e,0x6b,0x66,0x63,0x5e,0x5b,0x56,0x53,0x4e,0x4b,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x12,0x07,0x1f,0x2b,0x25,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22, +0x26,0x27,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x17,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22, +0x26,0x27,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x37,0x33,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x1e,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2, +0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0xfe,0x9c,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2, +0x17,0x1e,0x01,0x66,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x01,0x20,0x16,0xb2,0x16,0x20,0x20,0x16,0xb2,0x17,0x1e,0x9a,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x01,0x06,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02, +0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0xfe,0xcd,0x6c,0x16,0x1e,0x01,0x20,0x15,0x6c,0x16,0x20,0x01,0x1e,0x02,0x24,0x6b,0x16,0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0xfe,0xcc,0x6b,0x16,0x20,0x01,0x1e,0x17,0x6b,0x17,0x1e,0x01,0x20,0x01,0x08,0x6b,0x16, +0x20,0x20,0x16,0x6b,0x16,0x20,0x20,0x00,0x00,0x05,0x00,0x00,0xff,0x6a,0x03,0xe8,0x03,0x52,0x00,0x10,0x00,0x14,0x00,0x25,0x00,0x2f,0x00,0x39,0x00,0x65,0x40,0x62,0x33,0x29,0x02,0x07,0x08,0x21,0x01,0x05,0x02,0x1d,0x15,0x0d,0x0c,0x04,0x00,0x05,0x03,0x4c,0x04,0x01,0x05,0x01,0x4b,0x0a,0x01,0x08,0x09,0x01,0x07,0x01,0x08,0x07, +0x67,0x00,0x02,0x05,0x01,0x02,0x57,0x06,0x0c,0x03,0x0b,0x04,0x01,0x00,0x05,0x00,0x01,0x05,0x69,0x06,0x0c,0x03,0x0b,0x04,0x01,0x01,0x00,0x5f,0x04,0x01,0x00,0x01,0x00,0x4f,0x11,0x11,0x00,0x00,0x37,0x35,0x32,0x31,0x2d,0x2b,0x28,0x27,0x24,0x22,0x1f,0x1e,0x1b,0x19,0x11,0x14,0x11,0x14,0x13,0x12,0x00,0x10,0x00,0x0f,0x37,0x0d, +0x07,0x17,0x2b,0x01,0x11,0x14,0x06,0x07,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x13,0x36,0x33,0x21,0x11,0x23,0x11,0x01,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x22,0x26,0x27,0x11,0x33,0x32,0x17,0x25,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x05,0x15,0x23,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x89,0x16, +0x0e,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x8b,0x04,0x0d,0x01,0x9f,0x8e,0x02,0x3b,0x16,0x0e,0xfe,0xe3,0x0f,0x14,0x01,0x0f,0x14,0x01,0xed,0x0d,0x04,0xfe,0x3e,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x01,0x77,0xc5,0x0a,0x08,0xa1,0x08,0x0a,0x02,0x9f,0xfe,0x54,0x0f,0x14,0x01,0xfe,0xbf,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x01,0xe8,0x0c, +0xfe,0x78,0x01,0x88,0xfe,0x0c,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x41,0x16,0x0e,0x01,0xac,0x0c,0xad,0x7d,0x7d,0x08,0x0a,0x0a,0x08,0x7d,0x7d,0x08,0x0a,0x0a,0x00,0x08,0xff,0xff,0xff,0xf8,0x03,0xe9,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x3f,0x00,0x4f,0x00,0x5f,0x00,0x6f,0x00,0x7f,0x00,0x6f,0x40,0x6c,0x79,0x78, +0x71,0x49,0x48,0x41,0x06,0x08,0x09,0x69,0x61,0x60,0x29,0x21,0x20,0x06,0x04,0x05,0x59,0x58,0x51,0x50,0x19,0x18,0x11,0x10,0x08,0x02,0x03,0x39,0x38,0x31,0x09,0x08,0x01,0x06,0x00,0x01,0x04,0x4c,0x0d,0x01,0x05,0x0c,0x01,0x04,0x03,0x05,0x04,0x67,0x0b,0x01,0x03,0x0a,0x01,0x02,0x01,0x03,0x02,0x67,0x07,0x01,0x01,0x06,0x01,0x00, +0x01,0x00,0x63,0x0e,0x01,0x08,0x08,0x09,0x5f,0x0f,0x01,0x09,0x09,0x13,0x08,0x4e,0x7d,0x7b,0x75,0x73,0x6d,0x6b,0x65,0x64,0x5d,0x5b,0x55,0x54,0x4d,0x4c,0x26,0x26,0x17,0x26,0x17,0x17,0x17,0x17,0x14,0x10,0x07,0x1f,0x2b,0x37,0x15,0x14,0x06,0x27,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x27, +0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x17,0x33,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x23,0x22,0x26,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x01,0x15,0x14,0x06,0x27,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x35,0x34,0x36,0x37,0x33,0x32,0x16,0x01,0x15,0x14,0x06,0x27, +0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x27,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08, +0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0xfc,0xa6,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x03,0x58,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07, +0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x01,0x0a,0x08,0xfd,0x12,0x07,0x0a,0x01,0x0c,0x06,0x02,0xee,0x07,0x0c,0x76,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xd0,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xfe,0x4c,0x6b,0x07,0x0c,0x01,0x0a, +0x08,0x6b,0x07,0x0a,0x01,0x0c,0x02,0x7d,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0xfe,0x4d,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0xce,0x6b,0x07,0x0a,0x01,0x0c,0x06,0x6b,0x08,0x0a,0x0a,0xcf,0x6b,0x08,0x0a,0x0a,0x08,0x6b,0x07,0x0a,0x01,0x0c,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x02,0x83, +0x03,0x0b,0x00,0x07,0x00,0x1f,0x00,0x20,0x40,0x1d,0x05,0x03,0x02,0x00,0x00,0x02,0x00,0x02,0x63,0x00,0x01,0x01,0x04,0x61,0x00,0x04,0x04,0x13,0x01,0x4e,0x23,0x13,0x25,0x36,0x13,0x10,0x06,0x07,0x1c,0x2b,0x13,0x21,0x35,0x34,0x26,0x0e,0x01,0x17,0x05,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34, +0x36,0x32,0x16,0x07,0x15,0x33,0x32,0x16,0xb3,0x01,0x1d,0x54,0x76,0x54,0x01,0x01,0xd0,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x12,0x17,0x1e,0x01,0xa5,0x6c,0x3b,0x54,0x02,0x50,0x3d,0xa1,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0x6c,0x66,0x94,0x94,0x66,0x6c,0x1e,0x00,0x00, +0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x06,0x01,0x01,0x00,0x01,0x4c,0x00,0x01,0x00,0x4a,0x05,0x01,0x01,0x49,0x00,0x00,0x01,0x01,0x00,0x57,0x00,0x00,0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x11,0x11,0x02,0x07,0x18,0x2b,0x01,0x15,0x21,0x11,0x21,0x15,0x01,0x01,0x7a,0x01,0x60,0xfe, +0xa0,0xfe,0x86,0x02,0xda,0xbe,0xfe,0x86,0xc0,0x01,0x7c,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x04,0x2f,0x03,0x52,0x00,0x0f,0x00,0x2f,0x00,0x2e,0x40,0x2b,0x09,0x01,0x02,0x01,0x00,0x20,0x01,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x00,0x01,0x05,0x00,0x67,0x00,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x00,0x03,0x03,0x11,0x03,0x4e, +0x35,0x26,0x36,0x26,0x26,0x14,0x06,0x07,0x1c,0x2b,0x01,0x11,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x14,0x1e,0x01,0x17,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x34,0x3e,0x01,0x35,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0xe8,0x0a,0x08,0xfc,0x83, +0x07,0x0a,0x01,0x0c,0x06,0x03,0x7d,0x07,0x0c,0x46,0x34,0x25,0xfe,0xd1,0x12,0x10,0x01,0x14,0x0f,0xfe,0xe2,0x0f,0x14,0x01,0x12,0x12,0xfe,0xd0,0x24,0x36,0x01,0x34,0x25,0x03,0x7d,0x25,0x34,0x01,0x28,0x01,0xd1,0x07,0x0a,0x01,0x0c,0x06,0xfe,0x2f,0x07,0x0a,0x0a,0x01,0xd8,0xfd,0xa1,0x25,0x34,0x01,0x14,0x2e,0x22,0x07,0x0e,0x16, +0x16,0x0e,0x08,0x22,0x2c,0x15,0x36,0x24,0x02,0x5f,0x25,0x34,0x34,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xe1,0x02,0xf8,0x02,0xdb,0x00,0x21,0x00,0x31,0x00,0x2f,0x40,0x2c,0x11,0x06,0x02,0x00,0x03,0x01,0x4c,0x00,0x01,0x00,0x01,0x86,0x00,0x02,0x00,0x04,0x03,0x02,0x04,0x69,0x00,0x03,0x00,0x00,0x03,0x59,0x00,0x03,0x03,0x00, +0x61,0x00,0x00,0x03,0x00,0x51,0x15,0x2b,0x1d,0x25,0x22,0x05,0x07,0x1b,0x2b,0x01,0x0e,0x01,0x23,0x22,0x26,0x27,0x0f,0x01,0x06,0x23,0x22,0x26,0x35,0x34,0x3f,0x02,0x2e,0x01,0x35,0x34,0x37,0x3e,0x01,0x32,0x17,0x16,0x17,0x16,0x15,0x14,0x07,0x06,0x25,0x1e,0x01,0x33,0x32,0x3e,0x01,0x34,0x2e,0x01,0x22,0x0e,0x01,0x15,0x14,0x16, +0x02,0xa8,0x29,0x66,0x36,0x31,0x5d,0x28,0x33,0x82,0x15,0x18,0x1e,0x2d,0x0f,0x81,0x7e,0x20,0x22,0x27,0x25,0x80,0x95,0x40,0x3f,0x26,0x26,0x14,0x14,0xfe,0x99,0x19,0x40,0x21,0x2d,0x4f,0x2e,0x2f,0x4e,0x5b,0x4f,0x2f,0x1a,0x01,0x00,0x29,0x2a,0x22,0x20,0x7d,0x82,0x0f,0x2f,0x1e,0x1a,0x13,0x82,0x33,0x26,0x5e,0x32,0x4b,0x40,0x3f, +0x4b,0x27,0x25,0x3f,0x41,0x4a,0x38,0x32,0x34,0x24,0x18,0x1a,0x2e,0x4f,0x5d,0x4e,0x2e,0x2f,0x4e,0x2d,0x22,0x40,0x00,0x00,0x00,0x02,0xff,0xfd,0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x0c,0x00,0x19,0x00,0x28,0x40,0x25,0x04,0x01,0x00,0x00,0x03,0x61,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x61,0x00,0x02,0x02,0x11,0x02,0x4e, +0x01,0x00,0x17,0x16,0x11,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x05,0x07,0x16,0x2b,0x01,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x01,0xad,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xf4, +0xba,0x7e,0x02,0x8e,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x4d,0x02,0xff,0x00,0x06,0x00,0x14,0x00,0x19,0x00,0x24,0x00,0xe3,0x40,0x17,0x1e,0x01,0x02,0x05,0x1d,0x16,0x0e,0x07,0x04,0x03,0x02,0x19,0x03,0x02, +0x03,0x00,0x03,0x01,0x01,0x01,0x00,0x04,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x26,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x00,0x03,0x70,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x12,0x50,0x58,0x40,0x27,0x00,0x02, +0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x72,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x4b,0xb0,0x29,0x50,0x58,0x40,0x28,0x00,0x02,0x05,0x03,0x05,0x02,0x03,0x80,0x00,0x03,0x00,0x05,0x03,0x00,0x7e,0x06,0x01,0x01,0x00, +0x04,0x00,0x01,0x04,0x80,0x00,0x05,0x05,0x13,0x4d,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x1b,0x40,0x23,0x00,0x05,0x02,0x05,0x85,0x00,0x02,0x03,0x02,0x85,0x00,0x03,0x00,0x03,0x85,0x06,0x01,0x01,0x00,0x04,0x00,0x01,0x04,0x80,0x00,0x00,0x00,0x04,0x60,0x00,0x04,0x04,0x11,0x04,0x4e,0x59,0x59,0x59,0x40,0x12, +0x00,0x00,0x21,0x20,0x18,0x17,0x10,0x0f,0x09,0x08,0x00,0x06,0x00,0x06,0x14,0x07,0x07,0x17,0x2b,0x17,0x37,0x27,0x07,0x15,0x33,0x15,0x01,0x34,0x23,0x22,0x07,0x01,0x06,0x15,0x14,0x33,0x32,0x37,0x01,0x36,0x27,0x17,0x01,0x23,0x35,0x01,0x14,0x0f,0x01,0x27,0x37,0x36,0x32,0x1f,0x01,0x16,0xcb,0x32,0x83,0x33,0x48,0x01,0x5f,0x0c, +0x05,0x04,0xfe,0xd1,0x04,0x0d,0x05,0x04,0x01,0x2f,0x03,0x1e,0xe8,0xfe,0x30,0xe8,0x03,0x4d,0x14,0x5d,0xe8,0x5d,0x14,0x3b,0x16,0x83,0x14,0x07,0x33,0x83,0x33,0x3c,0x47,0x02,0x06,0x0c,0x04,0xfe,0xd2,0x04,0x06,0x0c,0x04,0x01,0x2e,0x04,0x71,0xe8,0xfe,0x2f,0xe9,0x01,0x9a,0x1d,0x15,0x5d,0xe9,0x5c,0x15,0x15,0x83,0x16,0x00,0x00, +0x00,0x05,0xff,0xff,0xff,0xf9,0x03,0x59,0x02,0xc4,0x00,0x08,0x00,0x11,0x00,0x21,0x00,0x2b,0x00,0x41,0x00,0x8e,0x40,0x0f,0x13,0x01,0x01,0x04,0x09,0x00,0x02,0x00,0x01,0x1b,0x01,0x05,0x00,0x03,0x4c,0x4b,0xb0,0x0a,0x50,0x58,0x40,0x30,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x08,0x00,0x70,0x00,0x09, +0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06,0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08,0x60,0x00,0x08,0x05,0x08,0x50,0x1b,0x40,0x31,0x03,0x01,0x01,0x04,0x00,0x04,0x01,0x00,0x80,0x02,0x01,0x00,0x05,0x04,0x00,0x05,0x7e,0x00,0x09,0x00,0x07,0x06,0x09,0x07,0x67,0x00,0x06,0x00,0x04,0x01,0x06, +0x04,0x67,0x00,0x05,0x08,0x08,0x05,0x58,0x00,0x05,0x05,0x08,0x60,0x00,0x08,0x05,0x08,0x50,0x59,0x40,0x0e,0x3d,0x3a,0x37,0x23,0x13,0x26,0x25,0x13,0x14,0x13,0x12,0x0a,0x07,0x1f,0x2b,0x25,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x14,0x06,0x22,0x26,0x3e,0x01,0x1e,0x01,0x17,0x35,0x34,0x26,0x27,0x21,0x22,0x06,0x07,0x15, +0x14,0x16,0x17,0x21,0x32,0x36,0x01,0x21,0x03,0x2e,0x01,0x23,0x21,0x22,0x06,0x07,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x37,0x13,0x3e,0x01,0x17,0x21,0x32,0x16,0x17,0x13,0x16,0x02,0x44,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x91,0x1a,0x24,0x1c,0x02,0x18,0x28,0x16,0x41,0x0c,0x06,0xfd,0x59,0x07,0x0a,0x01,0x0c, +0x06,0x02,0xa7,0x07,0x0a,0xfd,0x52,0x02,0x93,0x58,0x02,0x0e,0x07,0xfe,0x4b,0x07,0x0e,0x02,0x02,0x9e,0x34,0x25,0xfd,0x59,0x24,0x36,0x01,0x09,0x6e,0x09,0x34,0x1e,0x01,0xb5,0x1f,0x32,0x0a,0x6e,0x09,0xab,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x14,0x12,0x1a,0x1a,0x24,0x1c,0x02,0x18,0x6d,0xb3,0x07,0x0a,0x01,0x0c,0x06,0xb3,0x07, +0x0a,0x01,0x0c,0x01,0x12,0x01,0x0d,0x07,0x0a,0x0a,0x07,0xfe,0x9a,0xb3,0x25,0x34,0x34,0x25,0xb3,0x0e,0x1c,0x01,0x52,0x1d,0x26,0x01,0x24,0x1e,0xfe,0xae,0x1c,0x00,0x00,0x01,0x00,0x00,0xff,0xe2,0x02,0xda,0x02,0xda,0x00,0x06,0x00,0x26,0x40,0x23,0x01,0x01,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x4a,0x02,0x01,0x00,0x49,0x00,0x01, +0x00,0x00,0x01,0x57,0x00,0x01,0x01,0x00,0x5f,0x00,0x00,0x01,0x00,0x4f,0x11,0x13,0x02,0x07,0x18,0x2b,0x09,0x02,0x35,0x21,0x11,0x21,0x01,0x5e,0x01,0x7c,0xfe,0x84,0xfe,0xa2,0x01,0x5e,0x02,0xda,0xfe,0x84,0xfe,0x84,0xc0,0x01,0x7a,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xab,0x03,0x6b,0x03,0x20,0x00,0x0f,0x00,0x13,0x00,0x1f, +0x00,0x38,0x40,0x35,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x0b,0x03,0x02,0x01,0x4c,0x00,0x02,0x02,0x00,0x5f,0x04,0x01,0x00,0x00,0x10,0x4d,0x00,0x03,0x03,0x01,0x5f,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x13,0x12,0x11,0x10,0x09,0x06,0x00,0x0f,0x01,0x0e,0x05,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14, +0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x07,0x17,0x07,0x17,0x37,0x17,0x37,0x27,0x37,0x27,0x07,0x87,0x0c,0x11,0x11,0x0c,0x02,0xc6,0x0c,0x11,0x11,0x0c,0xfd,0x58,0x02,0x8b,0xfd,0x75,0x01,0x87,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x53,0x53,0x2e,0x52,0x03,0x1f,0x12,0x0c,0xfc,0xc8,0x0c,0x11, +0x11,0x0c,0x03,0x38,0x0c,0x12,0x3b,0xfd,0x02,0x02,0xcb,0x2e,0x52,0x53,0x2d,0x52,0x52,0x2d,0x53,0x52,0x2e,0x52,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x84,0x03,0x8f,0x03,0x33,0x00,0x02,0x00,0x10,0x00,0x3c,0x00,0x68,0x01,0x4d,0x40,0x0b,0x01,0x01,0x0a,0x02,0x62,0x36,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x0c,0x50,0x58,0x40,0x36, +0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x72,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x13,0x50,0x58,0x40,0x3c,0x12,0x01, +0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x70,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b,0x4b,0xb0,0x16,0x50,0x58, +0x40,0x3d,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x0a,0x02,0x59,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x03,0x4e,0x1b, +0x40,0x44,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x00,0x03,0x04,0x0a,0x03,0x57,0x0e,0x05,0x02,0x02,0x0f,0x01,0x0a,0x06,0x02,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x69,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61, +0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x68,0x66,0x5e,0x5c,0x5b,0x59,0x4d,0x4b,0x4a,0x48,0x3f,0x3d,0x3c,0x3a,0x32,0x30,0x2f,0x2d,0x21,0x1f,0x1e,0x1c,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d, +0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x13,0x33,0x32,0x16,0x1d,0x01,0x14,0x16,0x17,0x16,0x17,0x16,0x3b,0x01,0x15,0x23,0x22,0x07,0x06,0x07,0x06,0x07,0x06,0x1d,0x01,0x14,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e, +0x01,0x2b,0x01,0x35,0x33,0x32,0x36,0x37,0x36,0x37,0x36,0x3d,0x01,0x34,0x37,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0x90,0x63,0x64,0xfe,0xcd,0x0d,0x13,0x3f,0x01,0x58,0x3f,0x12,0x0d,0x55,0x1b,0x47,0x45,0x07,0x0b,0x09,0x12,0x0e,0x1c,0x0f,0x0f,0x1a,0x12,0x0f,0x0c,0x08,0x05, +0x03,0x0f,0x22,0x34,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x20,0x0a,0x08,0x05,0x04,0x07,0x07,0x23,0x33,0x27,0x1b,0x15,0x55,0x4e,0x4e,0x55,0x15,0x02,0xb1,0xac,0xac,0x82,0x12,0x0d,0xe7,0xc7,0x2e,0x4e,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x09,0x0a, +0x05,0x05,0x33,0x05,0x03,0x0a,0x08,0x0f,0x0d,0x14,0x80,0x1d,0x33,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x09,0x08,0x0f,0x14,0x0d,0x57,0x21,0x16,0x19,0x24,0x12,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x00,0x01,0x00,0x00, +0xff,0xf2,0x02,0xf8,0x02,0xcc,0x00,0x06,0x00,0x17,0x40,0x14,0x06,0x01,0x00,0x4a,0x02,0x01,0x00,0x01,0x00,0x85,0x00,0x01,0x01,0x76,0x11,0x11,0x10,0x03,0x07,0x19,0x2b,0x01,0x23,0x11,0x21,0x11,0x23,0x01,0x02,0xf8,0xc0,0xfe,0x88,0xc0,0x01,0x7c,0x01,0x50,0xfe,0xa2,0x01,0x5e,0x01,0x7c,0x00,0x01,0x00,0x00,0x00,0x00,0x03,0xa5, +0x02,0x98,0x00,0x15,0x00,0x1d,0x40,0x1a,0x0f,0x01,0x00,0x01,0x01,0x4c,0x00,0x02,0x01,0x02,0x85,0x00,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x01,0x36,0x32,0x1f,0x01,0x16,0x03,0xa5,0x10,0xfe,0x20,0x10,0x2c, +0x10,0xfe,0xea,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0x01,0x6e,0x10,0x2c,0x10,0x4c,0x10,0x02,0x16,0x16,0x10,0xfe,0x20,0x0f,0x0f,0x01,0x16,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa5,0x01,0x6f,0x10,0x10,0x4c,0x0f,0x00,0x03,0xff,0xf5,0xff,0xb1,0x03,0xf3,0x03,0x52,0x00,0x0f,0x00,0x21,0x00,0x33,0x00,0x33,0x40,0x30,0x1b,0x11,0x02,0x03, +0x02,0x09,0x01,0x02,0x01,0x00,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02,0x67,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x01,0x01,0x04,0x5f,0x00,0x04,0x04,0x11,0x04,0x4e,0x17,0x38,0x27,0x27,0x26,0x23,0x06,0x07,0x1c,0x2b,0x25,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x1d,0x01,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34, +0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x17,0x14,0x16,0x37,0x33,0x32,0x36,0x03,0x01,0x16,0x07,0x0e,0x01,0x07,0x21,0x22,0x26,0x27,0x26,0x37,0x01,0x3e,0x01,0x32,0x16,0x02,0x3b,0x0a,0x07,0x6c,0x07,0x0a,0x0a,0x07,0x6c,0x07,0x0a,0x01,0x0a,0x05,0x07,0x07,0x7a,0x06,0x08,0x05,0x09,0x0c,0x07,0x67,0x08,0x0c,0x08,0x01,0xac,0x14, +0x15,0x09,0x22,0x12,0xfc,0xa6,0x12,0x22,0x09,0x15,0x14,0x01,0xad,0x09,0x22,0x26,0x22,0x53,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xd7,0x01,0x01,0x06,0x04,0x06,0x06,0x04,0x08,0xff,0x05,0x08,0x01,0x06,0x02,0x10,0xfc,0xee,0x23,0x23,0x11,0x12,0x01,0x14,0x10,0x23,0x23,0x03,0x12,0x11,0x14,0x14,0x00,0x04,0x00,0x00, +0xff,0x79,0x03,0xd1,0x03,0x3c,0x00,0x0f,0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x36,0x40,0x33,0x07,0x01,0x05,0x03,0x01,0x01,0x05,0x01,0x63,0x06,0x01,0x04,0x04,0x00,0x5f,0x09,0x02,0x08,0x03,0x00,0x00,0x12,0x04,0x4e,0x11,0x10,0x01,0x00,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x19,0x16,0x10,0x1f,0x11,0x1e,0x09,0x06,0x00,0x0f, +0x01,0x0e,0x0a,0x07,0x16,0x2b,0x13,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x33,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x11,0x34,0x26,0x23,0x05,0x21,0x11,0x21,0x01,0x21,0x11,0x21,0x38,0x0d,0x13,0x13,0x0d,0x01,0x7c,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0x01,0x7d, +0x0d,0x12,0x12,0x0d,0xfc,0xa6,0x01,0x3e,0xfe,0xc2,0x01,0xfc,0x01,0x3e,0xfe,0xc2,0x03,0x3b,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d,0x12,0x12,0x0d,0x03,0x83,0x0d,0x12,0x3e,0xfc,0xbb,0x03,0x45,0xfc,0xbb,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x7e,0x03,0xd6,0x03,0x37,0x00,0x0f, +0x00,0x1f,0x00,0x23,0x00,0x27,0x00,0x3d,0x40,0x3a,0x00,0x04,0x00,0x01,0x02,0x04,0x01,0x67,0x00,0x02,0x09,0x01,0x07,0x06,0x02,0x07,0x67,0x00,0x06,0x00,0x03,0x06,0x03,0x63,0x08,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x00,0x12,0x05,0x4e,0x24,0x24,0x20,0x20,0x24,0x27,0x24,0x27,0x26,0x25,0x20,0x23,0x20,0x23,0x14,0x35,0x35,0x35, +0x32,0x0a,0x07,0x1b,0x2b,0x01,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x15,0x34,0x26,0x23,0x21,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x35,0x03,0x11,0x21,0x11,0x01,0x11,0x21,0x11,0x03,0xd5,0x12,0x0d,0xfc,0x7d,0x0d,0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x12,0x0d,0xfc,0x7d,0x0d, +0x13,0x13,0x0d,0x03,0x83,0x0d,0x12,0x3f,0xfc,0xbc,0x03,0x44,0xfc,0xbc,0x03,0x17,0x0d,0x12,0x12,0x0d,0xfe,0x84,0x0d,0x12,0x12,0x0d,0x80,0x0d,0x12,0x12,0x0d,0xfe,0x83,0x0d,0x12,0x12,0x0d,0x03,0x5a,0xfe,0xc2,0x01,0x3e,0xfe,0x04,0xfe,0xc1,0x01,0x3f,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0x89,0x03,0xdc,0x03,0x38,0x00,0x02, +0x00,0x10,0x00,0x39,0x00,0x62,0x01,0x0d,0x40,0x0b,0x01,0x01,0x06,0x0a,0x5c,0x33,0x02,0x07,0x06,0x02,0x4c,0x4b,0xb0,0x1c,0x50,0x58,0x40,0x38,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10, +0x01,0x09,0x0b,0x01,0x08,0x09,0x08,0x65,0x0f,0x01,0x0a,0x0a,0x03,0x5f,0x00,0x03,0x03,0x13,0x0a,0x4e,0x1b,0x4b,0xb0,0x21,0x50,0x58,0x40,0x3f,0x12,0x01,0x01,0x03,0x01,0x85,0x04,0x11,0x02,0x00,0x03,0x02,0x03,0x00,0x02,0x80,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f,0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01, +0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x1b,0x40,0x45,0x12,0x01,0x01,0x03,0x01,0x85,0x00,0x04,0x03,0x00,0x03,0x04,0x00,0x80,0x11,0x01,0x00,0x02,0x03,0x00,0x02,0x7e,0x0e,0x05,0x02,0x02,0x0a,0x03,0x02,0x0a,0x7e,0x00,0x03,0x0f, +0x01,0x0a,0x06,0x03,0x0a,0x69,0x0d,0x01,0x06,0x0c,0x01,0x07,0x09,0x06,0x07,0x6a,0x10,0x01,0x09,0x08,0x08,0x09,0x59,0x10,0x01,0x09,0x09,0x08,0x61,0x0b,0x01,0x08,0x09,0x08,0x51,0x59,0x59,0x40,0x2d,0x04,0x03,0x00,0x00,0x62,0x60,0x58,0x56,0x55,0x53,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x1f,0x1d,0x1c, +0x1a,0x13,0x11,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x03,0x10,0x04,0x0f,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x01,0x07,0x27,0x25,0x22,0x06,0x1d,0x01,0x33,0x35,0x21,0x15,0x33,0x35,0x34,0x26,0x23,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x1e,0x02,0x3b,0x01,0x15,0x23,0x22,0x07,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35, +0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x02,0x3d,0x01,0x34,0x3e,0x02,0x3b,0x01,0x15,0x23,0x22,0x1d,0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x03,0xdc,0x63,0x64,0xfd,0x31,0x0d,0x13,0x3f,0x02,0xf4,0x3f,0x12, +0x0d,0xfe,0xb9,0x1b,0x47,0x45,0x07,0x16,0x22,0x18,0x10,0x10,0x16,0x16,0x10,0x14,0x07,0x08,0x06,0x21,0x38,0x25,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa8,0x1b,0x47,0x44,0x04,0x04,0x0b,0x09,0x23,0x18,0x10,0x10,0x1c,0x1f,0x15,0x07,0x0f,0x21,0x34,0x27,0x1b,0x15,0x55,0x4d,0x4e,0x54,0x15,0x02,0x85,0xad,0xad,0xb3,0x12,0x0d,0xe7, +0xc7,0x6d,0x8d,0x0d,0x12,0xfe,0xfa,0x42,0x44,0x54,0x14,0x1b,0x13,0x0a,0x33,0x04,0x04,0x12,0x1c,0x14,0x80,0x1d,0x1a,0x19,0x23,0x13,0x34,0x52,0x7f,0x5a,0x0a,0x09,0x5c,0x54,0x54,0xfd,0x8a,0x43,0x43,0x7e,0x0e,0x12,0x0e,0x0a,0x09,0x0b,0x33,0x08,0x13,0x1a,0x14,0x57,0x20,0x30,0x23,0x13,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d, +0x54,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x43,0x00,0x44,0x40,0x41,0x18,0x01,0x03,0x04,0x13,0x01,0x02,0x00,0x03,0x06,0x01,0x01,0x00,0x03,0x4c,0x05,0x01,0x03,0x02,0x01,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x00,0x01,0x07,0x04,0x01,0x69,0x00,0x07,0x00,0x08,0x07,0x08,0x63, +0x00,0x06,0x06,0x09,0x5f,0x00,0x09,0x09,0x13,0x06,0x4e,0x42,0x3f,0x35,0x35,0x36,0x14,0x23,0x26,0x14,0x23,0x23,0x0a,0x07,0x1f,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3d,0x01,0x23,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x35,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x33,0x32,0x16,0x13,0x11, +0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24, +0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0xc4,0x08,0x0a,0x0a,0x08,0xc4,0x0a,0x08,0x24,0x07,0x0a,0xc5,0x08,0x0a,0x0a,0x08,0xc5,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0, +0x42,0x5e,0x01,0x60,0x00,0x03,0x00,0x00,0xff,0xf9,0x03,0x13,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x2f,0x00,0x2d,0x40,0x2a,0x09,0x01,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x67,0x00,0x03,0x00,0x04,0x03,0x04,0x63,0x00,0x02,0x02,0x05,0x5f,0x00,0x05,0x05,0x13,0x02,0x4e,0x35,0x35,0x35,0x36,0x26,0x23,0x06, +0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x3d,0x01,0x34,0x36,0x33,0x21,0x32,0x16,0x13,0x11,0x34,0x26,0x23,0x21,0x22,0x06,0x07,0x11,0x14,0x16,0x17,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0x83,0x0a,0x08,0xfe,0x30,0x08,0x0a,0x0a,0x08,0x01,0xd0,0x08, +0x0a,0x47,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x24,0x01,0xd0,0x25,0x34,0x48,0x5e,0x43,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42,0x60,0x01,0x94,0x24,0x08,0x0a,0x0a,0x08,0x24,0x07,0x0a,0x0a,0xfe,0xff,0x01,0xd0,0x25,0x34,0x34,0x25,0xfe,0x30,0x25,0x34,0x01,0x36,0x01,0xf4,0xfe,0x30,0x43,0x5e,0x5e,0x43,0x01,0xd0,0x42, +0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xd4,0x00,0x15,0x00,0x21,0xb1,0x06,0x64,0x44,0x40,0x16,0x07,0x01,0x00,0x02,0x01,0x4c,0x00,0x02,0x00,0x02,0x85,0x01,0x01,0x00,0x00,0x76,0x17,0x14,0x14,0x03,0x07,0x19,0x2b,0xb1,0x06,0x00,0x44,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01, +0x26,0x34,0x37,0x01,0x36,0x32,0x17,0x01,0x16,0x02,0x58,0x06,0x1c,0x05,0x0e,0x06,0xdc,0xdb,0x05,0x10,0x04,0x1c,0x06,0x06,0x01,0x04,0x05,0x0e,0x06,0x01,0x04,0x06,0xbd,0x07,0x05,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x0e,0x06,0x01,0x04,0x06,0x06,0xfe,0xfc,0x05,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xff,0x89,0x03,0x42, +0x03,0x33,0x00,0x0f,0x00,0x19,0x00,0x33,0x00,0x3f,0x00,0x4b,0x00,0x57,0x00,0x8c,0x40,0x89,0x56,0x01,0x0c,0x0d,0x44,0x01,0x0a,0x0b,0x3e,0x01,0x08,0x09,0x03,0x4c,0x00,0x02,0x03,0x05,0x03,0x02,0x05,0x80,0x00,0x05,0x0d,0x03,0x05,0x0d,0x7e,0x00,0x0b,0x0c,0x0a,0x0c,0x0b,0x0a,0x80,0x00,0x0a,0x09,0x0c,0x0a,0x09,0x7e,0x00,0x09, +0x08,0x0c,0x09,0x08,0x7e,0x10,0x01,0x08,0x07,0x0c,0x08,0x07,0x7e,0x00,0x0d,0x11,0x01,0x0c,0x0b,0x0d,0x0c,0x67,0x00,0x07,0x00,0x01,0x07,0x01,0x64,0x06,0x04,0x0f,0x03,0x03,0x03,0x00,0x5f,0x0e,0x01,0x00,0x00,0x12,0x03,0x4e,0x4e,0x4c,0x36,0x34,0x10,0x10,0x01,0x00,0x54,0x52,0x4c,0x57,0x4e,0x57,0x48,0x45,0x42,0x40,0x3c,0x3a, +0x34,0x3f,0x36,0x3f,0x32,0x2f,0x2a,0x28,0x25,0x22,0x1f,0x1d,0x10,0x19,0x10,0x19,0x16,0x13,0x09,0x06,0x00,0x0f,0x01,0x0e,0x12,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x17,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x3d,0x01,0x13,0x11,0x34,0x26,0x07,0x23,0x15,0x14,0x06,0x07, +0x23,0x22,0x26,0x37,0x35,0x23,0x22,0x06,0x17,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x27,0x21,0x22,0x35,0x34,0x36,0x37,0x21,0x32,0x16,0x07,0x14,0x27,0x21,0x22,0x26,0x37,0x34,0x33,0x21,0x32,0x15,0x14,0x06,0x27,0x21,0x22,0x35,0x34,0x36,0x17,0x21,0x32,0x16,0x07,0x14,0x02,0xa6,0x41,0x5a,0x01,0x5c,0x40,0xfd,0xf6,0x41,0x5a,0x01, +0x5c,0x40,0x68,0x20,0x15,0xd0,0x16,0x1e,0x9c,0x1e,0x15,0x35,0x3c,0x2c,0xd0,0x2b,0x3e,0x01,0x35,0x15,0x20,0x01,0x1e,0x16,0x02,0x0a,0x15,0x1e,0x68,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x1a,0xfe,0x60,0x0b,0x10,0x01,0x1a,0x01,0xa0,0x1a,0x0e,0x0c,0xfe,0x60,0x1a,0x0e,0x0c,0x01,0xa0,0x0b,0x10,0x01,0x03,0x33,0x5c, +0x40,0xfd,0x8f,0x41,0x5c,0x5c,0x41,0x02,0x71,0x41,0x5a,0x01,0x68,0x34,0x15,0x20,0x20,0x15,0x34,0xfd,0x5b,0x02,0x71,0x15,0x20,0x01,0x34,0x2b,0x3c,0x01,0x3e,0x2a,0x34,0x1e,0x16,0xfd,0x8f,0x15,0x20,0x20,0x49,0x19,0x0c,0x0e,0x01,0x10,0x0b,0x19,0x9d,0x0e,0x0c,0x19,0x19,0x0b,0x10,0x9d,0x19,0x0b,0x10,0x01,0x0e,0x0c,0x19,0x00, +0x00,0x03,0x00,0x00,0xff,0xf9,0x04,0x29,0x03,0x0b,0x00,0x11,0x00,0x27,0x00,0x45,0x00,0x4b,0x40,0x48,0x24,0x01,0x01,0x00,0x01,0x4c,0x00,0x07,0x04,0x03,0x04,0x07,0x03,0x80,0x00,0x03,0x02,0x04,0x03,0x02,0x7e,0x08,0x09,0x02,0x02,0x00,0x00,0x01,0x02,0x00,0x68,0x00,0x01,0x00,0x05,0x01,0x05,0x63,0x00,0x04,0x04,0x06,0x5f,0x00, +0x06,0x06,0x13,0x04,0x4e,0x13,0x12,0x42,0x40,0x3d,0x3b,0x38,0x35,0x30,0x2d,0x21,0x1e,0x19,0x16,0x12,0x27,0x13,0x27,0x36,0x31,0x0a,0x07,0x18,0x2b,0x01,0x34,0x23,0x21,0x22,0x06,0x0f,0x01,0x06,0x15,0x14,0x33,0x21,0x32,0x36,0x3f,0x01,0x36,0x25,0x21,0x35,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06, +0x15,0x11,0x37,0x3e,0x01,0x05,0x14,0x0f,0x01,0x0e,0x01,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x17,0x15,0x33,0x32,0x16,0x17,0x16,0x03,0xe2,0x1e,0xfd,0xa1,0x16,0x34,0x0d,0xa4,0x0b,0x1e,0x02,0x5f,0x17,0x32,0x0f,0xa4,0x0a,0xfd,0x83,0x01,0xad,0x20,0x16,0xfe,0xbf,0x17,0x1e,0x01, +0x1e,0x17,0xb3,0x16,0x20,0x8f,0x19,0x50,0x02,0xea,0x19,0xa5,0x18,0x52,0x25,0xfd,0xa1,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x2f,0x34,0x48,0x01,0x6b,0x1e,0x34,0x0b,0x08,0x01,0x4b,0x13,0x18,0x11,0xcb,0x0d,0x09,0x14,0x1a,0x10,0xcb,0x0c,0x64,0x5a,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfe,0x24,0xaf,0x1e, +0x26,0x5a,0x23,0x20,0xcb,0x1e,0x26,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33,0x12,0x4a,0x33,0x5a,0x1a,0x1b,0x11,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xf9,0x03,0xa1,0x03,0x0b,0x00,0x17,0x00,0x2c,0x00,0x26,0x40,0x23,0x00,0x05,0x00,0x00,0x02,0x05,0x00,0x67,0x00,0x02,0x00,0x03,0x02,0x03,0x63,0x00,0x01,0x01,0x04,0x5f,0x00,0x04, +0x04,0x13,0x01,0x4e,0x23,0x35,0x35,0x35,0x35,0x33,0x06,0x07,0x1c,0x2b,0x25,0x11,0x34,0x26,0x07,0x21,0x22,0x26,0x27,0x35,0x34,0x26,0x07,0x23,0x22,0x06,0x15,0x11,0x14,0x16,0x33,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x1d,0x01,0x21,0x32,0x16,0x03,0x59,0x1e,0x17,0xfe, +0x77,0x17,0x1e,0x01,0x1e,0x17,0xb3,0x16,0x20,0x20,0x16,0x02,0xa7,0x16,0x20,0x47,0x4a,0x33,0xfd,0x59,0x33,0x4a,0x4a,0x33,0xb3,0x33,0x4a,0x01,0x77,0x33,0x4a,0x76,0x01,0x89,0x16,0x20,0x01,0x20,0x16,0x24,0x16,0x20,0x01,0x1e,0x17,0xfd,0xe8,0x16,0x20,0x20,0x01,0x9f,0xfe,0x77,0x33,0x4a,0x4a,0x33,0x02,0x18,0x33,0x4a,0x4a,0x33, +0x12,0x4a,0x00,0x00,0x00,0x04,0x00,0x00,0xff,0xb8,0x03,0x94,0x03,0x1f,0x00,0x02,0x00,0x10,0x00,0x39,0x00,0x66,0x01,0x0d,0x40,0x0b,0x60,0x33,0x02,0x07,0x06,0x01,0x01,0x02,0x07,0x02,0x4c,0x4b,0xb0,0x13,0x50,0x58,0x40,0x38,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02, +0x06,0x07,0x69,0x0b,0x08,0x12,0x04,0x11,0x05,0x00,0x01,0x09,0x00,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x4b,0xb0,0x1b,0x50,0x58,0x40,0x3f,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x12,0x04,0x11,0x03,0x00,0x08,0x01,0x08,0x00,0x01,0x80,0x00, +0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x1b,0x40,0x45,0x00,0x02,0x07,0x09,0x07,0x02,0x09,0x80,0x11,0x01,0x00,0x08,0x04,0x08,0x00,0x04,0x80,0x12, +0x01,0x04,0x01,0x08,0x04,0x01,0x7e,0x00,0x03,0x01,0x03,0x86,0x0d,0x01,0x06,0x0c,0x01,0x07,0x02,0x06,0x07,0x69,0x0b,0x01,0x08,0x00,0x09,0x08,0x59,0x10,0x01,0x09,0x00,0x01,0x03,0x09,0x01,0x67,0x0f,0x01,0x0a,0x0a,0x05,0x61,0x0e,0x01,0x05,0x05,0x10,0x0a,0x4e,0x59,0x59,0x40,0x2d,0x03,0x03,0x00,0x00,0x66,0x64,0x5c,0x5a,0x59, +0x57,0x4a,0x48,0x47,0x45,0x3c,0x3a,0x39,0x37,0x2f,0x2d,0x2c,0x2a,0x20,0x1e,0x1d,0x1b,0x13,0x11,0x03,0x10,0x03,0x10,0x0d,0x0a,0x07,0x06,0x05,0x04,0x00,0x02,0x00,0x02,0x13,0x07,0x16,0x2b,0x25,0x37,0x17,0x07,0x15,0x21,0x35,0x23,0x15,0x14,0x16,0x33,0x21,0x32,0x36,0x3d,0x01,0x01,0x33,0x32,0x16,0x1d,0x01,0x14,0x17,0x1e,0x02, +0x3b,0x01,0x15,0x23,0x22,0x0e,0x02,0x1d,0x01,0x14,0x07,0x0e,0x02,0x2b,0x01,0x35,0x33,0x32,0x3d,0x01,0x34,0x37,0x26,0x3d,0x01,0x34,0x2b,0x01,0x03,0x23,0x22,0x26,0x3d,0x01,0x34,0x27,0x26,0x27,0x2e,0x01,0x2b,0x01,0x35,0x33,0x32,0x3e,0x01,0x37,0x36,0x3d,0x01,0x34,0x37,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x15,0x23,0x22,0x1d, +0x01,0x14,0x07,0x16,0x1d,0x01,0x14,0x3b,0x01,0x02,0xcd,0x64,0x63,0x82,0xfe,0xa7,0x3e,0x12,0x0d,0x01,0x97,0x0d,0x13,0xfe,0xa0,0x1c,0x47,0x44,0x04,0x05,0x11,0x25,0x18,0x10,0x10,0x1c,0x20,0x14,0x07,0x07,0x07,0x22,0x35,0x26,0x1c,0x16,0x55,0x4d,0x4e,0x54,0x16,0xa7,0x1b,0x48,0x44,0x04,0x05,0x09,0x0a,0x23,0x18,0x0f,0x0f,0x1d, +0x20,0x13,0x03,0x04,0x07,0x08,0x10,0x10,0x1b,0x1b,0x27,0x1b,0x16,0x55,0x4d,0x4e,0x54,0x16,0x6a,0xac,0xac,0x09,0x6a,0xb3,0xd3,0x0d,0x12,0x12,0x0d,0x8a,0x02,0xbe,0x42,0x44,0x54,0x14,0x0c,0x10,0x10,0x0c,0x33,0x08,0x14,0x19,0x15,0x80,0x21,0x16,0x19,0x23,0x12,0x33,0x52,0x7f,0x59,0x0b,0x09,0x5c,0x54,0x54,0xfd,0x8b,0x42,0x43, +0x7e,0x14,0x0c,0x10,0x08,0x0b,0x09,0x33,0x09,0x12,0x0e,0x0c,0x15,0x56,0x1a,0x1e,0x18,0x12,0x10,0x0b,0x09,0x33,0x53,0x55,0x59,0x0c,0x07,0x5d,0x7d,0x54,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x03,0xe8,0x02,0x60,0x00,0x20,0x00,0x24,0x00,0x28,0x00,0x36,0x40,0x33,0x00,0x00,0x08,0x06,0x07,0x03,0x04,0x03,0x00,0x04,0x67,0x05, +0x01,0x03,0x01,0x01,0x03,0x57,0x05,0x01,0x03,0x03,0x01,0x5f,0x02,0x01,0x01,0x03,0x01,0x4f,0x25,0x25,0x21,0x21,0x25,0x28,0x25,0x28,0x27,0x26,0x21,0x24,0x21,0x24,0x14,0x27,0x2a,0x18,0x09,0x07,0x1a,0x2b,0x11,0x26,0x37,0x25,0x36,0x17,0x16,0x0f,0x01,0x21,0x27,0x26,0x37,0x36,0x17,0x05,0x16,0x07,0x03,0x06,0x23,0x21,0x26,0x2f, +0x01,0x26,0x0f,0x01,0x06,0x23,0x21,0x26,0x27,0x37,0x17,0x21,0x37,0x33,0x17,0x21,0x37,0x02,0x0a,0x01,0x68,0x1d,0x0c,0x0b,0x19,0xe3,0x02,0x92,0xe4,0x19,0x0b,0x0e,0x1d,0x01,0x6a,0x0b,0x02,0x1b,0x08,0x19,0xfe,0xc7,0x19,0x06,0x31,0x27,0x35,0x32,0x06,0x1a,0xfe,0xc8,0x1b,0x04,0x27,0x13,0x01,0x04,0x2b,0xdd,0x29,0x01,0x03,0x14, +0x01,0x82,0x0d,0x0c,0xba,0x0b,0x1b,0x21,0x0c,0x68,0x68,0x10,0x1d,0x1b,0x0b,0xba,0x0c,0x0d,0xff,0x00,0x1e,0x02,0x18,0xdf,0x19,0x18,0xe0,0x1a,0x02,0x1c,0xe2,0xbd,0xbd,0xbd,0xbd,0x00,0x00,0x03,0x00,0x00,0xff,0x6a,0x03,0x59,0x03,0x52,0x00,0x13,0x00,0x1a,0x00,0x23,0x00,0x39,0x40,0x36,0x14,0x01,0x02,0x04,0x01,0x4c,0x00,0x01, +0x00,0x04,0x02,0x01,0x04,0x67,0x00,0x02,0x00,0x03,0x05,0x02,0x03,0x67,0x06,0x01,0x05,0x00,0x00,0x05,0x57,0x06,0x01,0x05,0x05,0x00,0x5f,0x00,0x00,0x05,0x00,0x4f,0x1b,0x1b,0x1b,0x23,0x1b,0x23,0x13,0x26,0x14,0x35,0x36,0x07,0x07,0x1b,0x2b,0x01,0x1e,0x01,0x15,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x37,0x21, +0x32,0x16,0x17,0x07,0x15,0x33,0x26,0x2f,0x01,0x26,0x13,0x11,0x23,0x22,0x26,0x27,0x35,0x21,0x11,0x03,0x33,0x10,0x16,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x01,0xf4,0x16,0x36,0x0f,0x4a,0xd2,0x05,0x07,0xaf,0x06,0xc6,0xe8,0x17,0x1e,0x01,0xfe,0x53,0x02,0x7e,0x10,0x34,0x18,0xfd,0x7e,0x17,0x1e,0x01,0x20,0x16,0x03,0x7c, +0x17,0x1e,0x01,0x16,0x10,0x26,0xd2,0x11,0x06,0xaf,0x07,0xfc,0xb0,0x02,0x3c,0x20,0x15,0xe9,0xfc,0xa6,0x00,0x01,0x00,0x00,0xff,0xaa,0x03,0x11,0x03,0x13,0x00,0x0b,0x00,0x06,0xb3,0x07,0x02,0x01,0x32,0x2b,0x09,0x01,0x06,0x26,0x35,0x11,0x34,0x36,0x17,0x01,0x16,0x14,0x03,0x04,0xfd,0x1b,0x0d,0x12,0x12,0x0d,0x02,0xe5,0x0d,0x01, +0x4d,0xfe,0x64,0x07,0x0a,0x0f,0x03,0x36,0x0e,0x0c,0x08,0xfe,0x64,0x07,0x14,0x00,0x00,0x01,0xff,0xff,0xff,0xae,0x02,0x3c,0x03,0x0f,0x00,0x1d,0x00,0x1b,0x40,0x18,0x1b,0x1a,0x12,0x03,0x01,0x00,0x01,0x4c,0x00,0x00,0x00,0x13,0x4d,0x00,0x01,0x01,0x11,0x01,0x4e,0x35,0x3d,0x02,0x07,0x18,0x2b,0x17,0x06,0x26,0x37,0x11,0x34,0x36, +0x17,0x01,0x16,0x17,0x11,0x34,0x36,0x3b,0x01,0x32,0x16,0x07,0x11,0x14,0x06,0x2b,0x01,0x22,0x26,0x37,0x11,0x06,0x07,0x19,0x0a,0x10,0x01,0x0e,0x0b,0x01,0x8c,0x05,0x03,0x14,0x0f,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48,0x0e,0x16,0x01,0x03,0x05,0x47,0x0b,0x06,0x0f,0x03,0x36,0x0e,0x08,0x0c,0xfe,0x74,0x05,0x05,0x01,0x7a,0x0e,0x16, +0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x01,0x7b,0x06,0x05,0x00,0x03,0xff,0xfc,0xff,0x90,0x03,0x9a,0x03,0x2c,0x00,0x08,0x00,0x13,0x00,0x29,0x00,0xa7,0x40,0x0d,0x0c,0x01,0x03,0x02,0x23,0x22,0x18,0x17,0x04,0x05,0x07,0x02,0x4c,0x4b,0xb0,0x24,0x50,0x58,0x40,0x32,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02, +0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00,0x05,0x04,0x02,0x05,0x04,0x7e,0x0a,0x01,0x04,0x00,0x01,0x04,0x01,0x66,0x09,0x01,0x02,0x02,0x00,0x61,0x08,0x01,0x00,0x00,0x12,0x02,0x4e,0x1b,0x40,0x39,0x00,0x03,0x02,0x06,0x02,0x03,0x06,0x80,0x00,0x06,0x07,0x02,0x06,0x07,0x7e,0x00,0x07,0x05,0x02,0x07,0x05,0x7e,0x00, +0x05,0x04,0x02,0x05,0x04,0x7e,0x08,0x01,0x00,0x09,0x01,0x02,0x03,0x00,0x02,0x69,0x0a,0x01,0x04,0x01,0x01,0x04,0x59,0x0a,0x01,0x04,0x04,0x01,0x62,0x00,0x01,0x04,0x01,0x52,0x59,0x40,0x1f,0x15,0x14,0x0a,0x09,0x01,0x00,0x26,0x24,0x20,0x1e,0x1b,0x19,0x14,0x29,0x15,0x29,0x10,0x0e,0x09,0x13,0x0a,0x13,0x05,0x04,0x00,0x08,0x01, +0x08,0x0b,0x07,0x16,0x2b,0x01,0x36,0x00,0x12,0x00,0x04,0x00,0x02,0x00,0x17,0x22,0x06,0x15,0x06,0x16,0x33,0x32,0x36,0x35,0x34,0x03,0x32,0x36,0x37,0x27,0x06,0x23,0x22,0x3f,0x01,0x36,0x23,0x22,0x06,0x07,0x17,0x36,0x33,0x32,0x0f,0x01,0x06,0x01,0xc6,0xbe,0x01,0x10,0x06,0xfe,0xf6,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0c,0xf2,0x2a, +0x2e,0x02,0x22,0x20,0x26,0x2e,0xb4,0x1e,0x6c,0x34,0x12,0x30,0x18,0x0e,0x0a,0x2a,0x1a,0x30,0x1e,0x76,0x38,0x10,0x34,0x16,0x0c,0x0c,0x24,0x1a,0x03,0x2a,0x02,0xfe,0xf8,0xfe,0x84,0xfe,0xee,0x06,0x01,0x0a,0x01,0x7c,0x01,0x12,0x96,0x30,0x1a,0x1c,0x20,0x2c,0x20,0x3a,0xfd,0xae,0x34,0x34,0x18,0x24,0x26,0xa0,0x60,0x3a,0x2e,0x1a, +0x22,0x22,0x98,0x68,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x31,0x00,0x3b,0x40,0x38,0x2a,0x01,0x03,0x05,0x25,0x1d,0x02,0x04,0x03,0x02,0x4c,0x00,0x04,0x03,0x01,0x03,0x04,0x01,0x80,0x00,0x01,0x02,0x03,0x01,0x02,0x7e,0x00,0x03,0x03,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x00,0x61,0x00,0x00,0x00, +0x11,0x00,0x4e,0x29,0x35,0x17,0x23,0x17,0x24,0x06,0x07,0x1c,0x2b,0x01,0x14,0x0e,0x02,0x23,0x22,0x26,0x27,0x26,0x34,0x3f,0x01,0x36,0x16,0x17,0x1e,0x01,0x33,0x32,0x3e,0x03,0x2e,0x02,0x22,0x06,0x07,0x17,0x16,0x06,0x2b,0x01,0x22,0x26,0x27,0x35,0x34,0x36,0x1f,0x01,0x3e,0x01,0x33,0x32,0x1e,0x02,0x03,0x59,0x44,0x72,0xa0,0x56, +0x60,0xae,0x3c,0x04,0x05,0x4c,0x06,0x11,0x04,0x29,0x76,0x43,0x3a,0x68,0x50,0x2a,0x02,0x2e,0x4c,0x6c,0x6f,0x64,0x28,0x4d,0x11,0x13,0x17,0xfa,0x0f,0x14,0x01,0x2c,0x11,0x48,0x3c,0x9a,0x52,0x57,0x9e,0x74,0x42,0x01,0x5e,0x57,0x9e,0x74,0x44,0x52,0x49,0x06,0x0e,0x04,0x4d,0x05,0x01,0x06,0x35,0x3a,0x2e,0x4c,0x6a,0x74,0x6a,0x4c, +0x2e,0x28,0x25,0x4d,0x10,0x2d,0x16,0x0e,0xfa,0x18,0x13,0x12,0x48,0x39,0x3e,0x44,0x74,0x9e,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0xf9,0x02,0x83,0x03,0x53,0x00,0x23,0x00,0x3a,0x40,0x37,0x00,0x04,0x05,0x00,0x05,0x04,0x00,0x80,0x00,0x03,0x00,0x05,0x04,0x03,0x05,0x69,0x02,0x06,0x02,0x00,0x01,0x01,0x00,0x59,0x02,0x06,0x02,0x00, +0x00,0x01,0x5f,0x00,0x01,0x00,0x01,0x4f,0x01,0x00,0x20,0x1f,0x1b,0x18,0x14,0x13,0x10,0x0e,0x09,0x06,0x00,0x23,0x01,0x23,0x07,0x07,0x16,0x2b,0x01,0x32,0x16,0x17,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x17,0x33,0x35,0x34,0x36,0x1e,0x01,0x07,0x14,0x06,0x2b,0x01,0x22,0x26,0x35,0x34,0x26,0x22,0x06,0x17,0x15, +0x02,0x4d,0x17,0x1e,0x01,0x20,0x16,0xfd,0xe9,0x17,0x1e,0x01,0x20,0x16,0x11,0x94,0xcc,0x96,0x02,0x14,0x0f,0x24,0x0e,0x16,0x54,0x76,0x54,0x01,0x01,0xa5,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x20,0x15,0x01,0x42,0x16,0x20,0x01,0xb3,0x67,0x94,0x02,0x90,0x69,0x0e,0x16,0x16,0x0e,0x3b,0x54,0x54,0x3b,0xb3,0x00,0x00,0x08,0x00,0x00, +0xff,0x9f,0x03,0x8f,0x03,0x1d,0x00,0x04,0x00,0x09,0x00,0x0e,0x00,0x13,0x00,0x1b,0x00,0x23,0x00,0x2b,0x00,0x33,0x00,0x41,0x40,0x3e,0x21,0x20,0x15,0x14,0x0e,0x01,0x06,0x00,0x4a,0x31,0x30,0x25,0x24,0x10,0x09,0x06,0x01,0x49,0x05,0x04,0x02,0x08,0x04,0x00,0x01,0x00,0x85,0x07,0x06,0x09,0x03,0x04,0x01,0x01,0x76,0x0f,0x0f,0x00, +0x00,0x2d,0x2c,0x29,0x28,0x1d,0x1c,0x19,0x18,0x0f,0x13,0x0f,0x13,0x0b,0x0a,0x06,0x05,0x00,0x04,0x00,0x04,0x0a,0x07,0x16,0x2b,0x01,0x35,0x1e,0x01,0x17,0x07,0x33,0x0e,0x01,0x07,0x03,0x23,0x3e,0x01,0x37,0x11,0x15,0x2e,0x01,0x27,0x01,0x35,0x1e,0x01,0x17,0x23,0x2e,0x01,0x01,0x23,0x3e,0x01,0x37,0x15,0x0e,0x01,0x01,0x15,0x2e, +0x01,0x27,0x33,0x1e,0x01,0x01,0x33,0x0e,0x01,0x07,0x35,0x3e,0x01,0x02,0x09,0x3c,0x56,0x10,0xa2,0xa2,0x10,0x56,0x3c,0x71,0xa2,0x10,0x56,0x3c,0x3c,0x56,0x10,0x01,0x13,0x98,0xda,0x14,0x71,0x12,0x9a,0xfe,0x11,0x71,0x13,0xda,0x99,0x6a,0x98,0x01,0x02,0x9a,0xd8,0x14,0x71,0x12,0x9a,0x01,0xef,0x71,0x15,0xd8,0x99,0x69,0x9a,0x01, +0x97,0xa2,0x10,0x58,0x3a,0x71,0x3b,0x58,0x0f,0x01,0x13,0x3b,0x56,0x11,0xfe,0xed,0xa2,0x10,0x56,0x3c,0x01,0x86,0x71,0x13,0xda,0x99,0x6b,0x98,0xfe,0xfd,0x98,0xda,0x14,0x71,0x12,0x98,0xfe,0x0f,0x72,0x13,0xdc,0x98,0x6b,0x98,0x01,0x03,0x99,0xda,0x14,0x72,0x12,0x98,0x00,0x04,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x03, +0x00,0x21,0x00,0x31,0x00,0x45,0x00,0x53,0x40,0x50,0x2b,0x2a,0x23,0x22,0x04,0x08,0x04,0x01,0x4c,0x0d,0x01,0x04,0x06,0x01,0x08,0x02,0x4b,0x00,0x08,0x04,0x03,0x04,0x08,0x03,0x80,0x00,0x03,0x06,0x04,0x03,0x06,0x7e,0x00,0x06,0x00,0x01,0x00,0x06,0x01,0x68,0x07,0x01,0x04,0x04,0x0a,0x5f,0x00,0x0a,0x0a,0x13,0x4d,0x05,0x02,0x02, +0x00,0x00,0x09,0x5f,0x00,0x09,0x09,0x11,0x09,0x4e,0x40,0x3d,0x38,0x35,0x17,0x26,0x33,0x11,0x13,0x3b,0x11,0x11,0x10,0x0b,0x07,0x1f,0x2b,0x17,0x21,0x35,0x21,0x05,0x33,0x11,0x34,0x26,0x2f,0x01,0x2e,0x01,0x07,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x35,0x23,0x11,0x33,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x07,0x03,0x35,0x34, +0x26,0x2b,0x01,0x22,0x06,0x17,0x15,0x14,0x16,0x37,0x33,0x32,0x36,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x1f,0x01,0x1e,0x01,0xd6,0x01,0xad,0xfe,0x53,0x01,0xf4,0x48,0x0c,0x05,0x9d,0x05,0x1c,0x08,0x1e,0x17,0xfe,0xbe,0x16,0x1e,0x01,0x48,0x48,0x20,0x15,0x01,0xd1,0x16,0x20,0x01,0xd6, +0x0a,0x08,0x6b,0x07,0x0c,0x01,0x0a,0x08,0x6b,0x07,0x0c,0x01,0x64,0x1e,0x17,0xfd,0x12,0x17,0x1e,0x01,0x20,0x16,0x02,0x05,0x17,0x36,0x0f,0x9c,0x10,0x16,0x07,0xd6,0xd6,0x01,0xf4,0x08,0x1a,0x07,0x9c,0x06,0x0c,0x01,0xe8,0x16,0x20,0x20,0x16,0xe8,0xfd,0x36,0xe8,0x16,0x20,0x20,0x16,0x01,0x1e,0xb2,0x08,0x0a,0x0a,0x08,0xb2,0x07, +0x0c,0x01,0x0a,0x0a,0xfd,0xfa,0x16,0x20,0x20,0x16,0x02,0xee,0x16,0x20,0x18,0x0e,0x9d,0x0f,0x36,0x00,0x00,0x02,0xff,0xff,0xff,0xb1,0x03,0xe8,0x03,0x0b,0x00,0x03,0x00,0x13,0x00,0x1f,0x40,0x1c,0x00,0x01,0x01,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x00,0x00,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x34,0x11,0x10,0x04, +0x07,0x1a,0x2b,0x37,0x21,0x11,0x21,0x25,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x37,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x8f,0x02,0xca,0xfd,0x36,0x03,0x59,0x34,0x25,0xfc,0xca,0x24,0x36,0x01,0x34,0x25,0x03,0x36,0x25,0x34,0x40,0x01,0xad,0xc4,0xfd,0x5a,0x25,0x34,0x01,0x36,0x24,0x02,0xa6,0x25,0x34,0x01,0x36,0x00,0x03,0xff,0xfd, +0xff,0xb1,0x03,0x5f,0x03,0x0b,0x00,0x08,0x00,0x15,0x00,0x22,0x00,0x32,0x40,0x2f,0x00,0x01,0x00,0x00,0x03,0x01,0x00,0x69,0x06,0x01,0x02,0x02,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x03,0x03,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x0a,0x09,0x20,0x1f,0x1a,0x19,0x10,0x0f,0x09,0x15,0x0a,0x15,0x13,0x12,0x07,0x07,0x18,0x2b, +0x01,0x14,0x06,0x22,0x2e,0x01,0x36,0x32,0x16,0x27,0x22,0x0e,0x02,0x1e,0x01,0x32,0x3e,0x01,0x2e,0x02,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x32,0x1e,0x01,0x02,0x3b,0x52,0x78,0x52,0x02,0x56,0x74,0x56,0x90,0x53,0x8c,0x50,0x02,0x54,0x88,0xaa,0x86,0x56,0x04,0x4e,0x8e,0x01,0x5b,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc, +0xf4,0xba,0x7e,0x01,0x5e,0x3b,0x54,0x54,0x76,0x54,0x54,0xf5,0x52,0x8c,0xa4,0x8c,0x52,0x52,0x8c,0xa4,0x8c,0x52,0xfe,0xd0,0x75,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0x6a,0x02,0x83,0x03,0x0b,0x00,0x0b,0x00,0x2e,0x00,0x35,0x40,0x32,0x07,0x01,0x02,0x01,0x00,0x01,0x4c,0x00,0x03,0x02, +0x03,0x86,0x09,0x05,0x02,0x01,0x04,0x01,0x02,0x03,0x01,0x02,0x67,0x08,0x06,0x02,0x00,0x00,0x07,0x5f,0x00,0x07,0x07,0x13,0x00,0x4e,0x2d,0x2c,0x13,0x33,0x11,0x14,0x22,0x33,0x15,0x15,0x13,0x0a,0x07,0x1f,0x2b,0x01,0x35,0x34,0x26,0x22,0x06,0x1d,0x01,0x14,0x16,0x32,0x36,0x05,0x14,0x06,0x27,0x23,0x03,0x0e,0x01,0x07,0x23,0x22, +0x27,0x03,0x23,0x22,0x26,0x27,0x34,0x36,0x33,0x11,0x22,0x2e,0x01,0x36,0x37,0x21,0x32,0x16,0x14,0x06,0x27,0x11,0x32,0x16,0x01,0x0c,0x0a,0x10,0x0a,0x0a,0x10,0x0a,0x01,0x77,0x16,0x0e,0xef,0x1d,0x01,0x0a,0x06,0x01,0x0f,0x02,0x2b,0xe1,0x0f,0x14,0x01,0x58,0x37,0x1d,0x2a,0x02,0x2e,0x1b,0x01,0x65,0x1d,0x2a,0x2a,0x1d,0x37,0x58, +0x01,0x70,0xfa,0x08,0x0a,0x0a,0x08,0xfa,0x08,0x0a,0x0a,0xbd,0x0e,0x16,0x01,0xfe,0xf2,0x07,0x08,0x01,0x0f,0x01,0x0f,0x14,0x0f,0x45,0x6e,0x01,0x1e,0x2a,0x3a,0x2a,0x01,0x2c,0x38,0x2c,0x01,0xfe,0xe2,0x6e,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5b,0x03,0x0b,0x00,0x24,0x00,0x47,0x00,0x4b,0x40,0x48,0x43,0x25,0x02,0x06,0x09,0x2f, +0x01,0x05,0x06,0x17,0x01,0x03,0x02,0x08,0x01,0x01,0x03,0x04,0x4c,0x00,0x09,0x07,0x01,0x05,0x02,0x09,0x05,0x67,0x04,0x01,0x02,0x00,0x01,0x00,0x02,0x01,0x69,0x00,0x06,0x06,0x08,0x61,0x00,0x08,0x08,0x13,0x4d,0x00,0x03,0x03,0x00,0x61,0x00,0x00,0x00,0x11,0x00,0x4e,0x46,0x45,0x26,0x25,0x25,0x36,0x25,0x26,0x35,0x14,0x24,0x0a, +0x07,0x1f,0x2b,0x01,0x14,0x15,0x0e,0x01,0x23,0x22,0x26,0x27,0x07,0x06,0x22,0x26,0x3d,0x01,0x34,0x36,0x3b,0x01,0x32,0x16,0x06,0x0f,0x01,0x1e,0x01,0x37,0x32,0x36,0x37,0x36,0x37,0x36,0x3b,0x01,0x32,0x16,0x13,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x36,0x3f,0x01,0x26,0x23,0x22,0x06,0x07,0x06,0x07,0x06,0x2b,0x01,0x22,0x26,0x37, +0x35,0x3e,0x01,0x33,0x32,0x16,0x17,0x37,0x36,0x32,0x16,0x03,0x4b,0x24,0xe4,0x99,0x51,0x98,0x3c,0x48,0x0b,0x1c,0x16,0x16,0x0e,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x28,0x64,0x37,0x4a,0x82,0x27,0x06,0x18,0x04,0x0c,0x6b,0x08,0x0a,0x0e,0x14,0x10,0xfa,0x0e,0x16,0x02,0x09,0x4d,0x52,0x70,0x4b,0x82,0x27,0x06,0x17,0x05,0x0c,0x6f,0x07, +0x0c,0x01,0x24,0xe6,0x99,0x51,0x9a,0x3c,0x48,0x0b,0x1c,0x18,0x01,0x05,0x03,0x01,0x96,0xba,0x3e,0x39,0x48,0x0b,0x16,0x0e,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x24,0x2a,0x01,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x01,0xb8,0xfa,0x0e,0x16,0x16,0x1c,0x0b,0x4d,0x4d,0x4a,0x3e,0x0a,0x38,0x0d,0x0c,0x06,0x04,0x96,0xba,0x3e,0x39,0x48,0x0b, +0x16,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x20,0x40,0x1d,0x18,0x10,0x08,0x00,0x04,0x00,0x01,0x01,0x4c,0x03,0x01,0x01,0x01,0x13,0x4d,0x02,0x01,0x00,0x00,0x11,0x00,0x4e,0x35,0x35,0x35,0x33,0x04,0x07,0x1a,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36, +0x33,0x21,0x32,0x16,0x05,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0xfe,0x0b,0x14,0x10,0xfe,0xe3,0x0f,0x14,0x01,0x16,0x0e,0x01,0x1d,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x0e, +0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x00,0x01,0x00,0x00,0xff,0xb1,0x03,0x5a,0x03,0x0b,0x00,0x0f,0x00,0x1a,0x40,0x17,0x08,0x00,0x02,0x00,0x01,0x01,0x4c,0x00,0x01,0x01,0x13,0x4d,0x00,0x00,0x00,0x11,0x00,0x4e,0x35,0x33,0x02,0x07,0x18,0x2b,0x01,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x27,0x11,0x34,0x36, +0x33,0x21,0x32,0x16,0x03,0x59,0x14,0x10,0xfc,0xef,0x0f,0x14,0x01,0x16,0x0e,0x03,0x11,0x0f,0x16,0x02,0xe7,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x16,0x00,0x01,0xff,0xfe,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x30,0x00,0x3a,0x40,0x37,0x2d,0x01,0x01,0x05,0x09,0x01,0x00,0x01,0x02,0x4c,0x00,0x00,0x01,0x03,0x01,0x00, +0x03,0x80,0x00,0x03,0x02,0x01,0x03,0x02,0x7e,0x00,0x01,0x01,0x05,0x61,0x00,0x05,0x05,0x13,0x4d,0x00,0x02,0x02,0x04,0x61,0x00,0x04,0x04,0x11,0x04,0x4e,0x27,0x27,0x13,0x27,0x24,0x33,0x06,0x07,0x1c,0x2b,0x01,0x15,0x14,0x06,0x2b,0x01,0x22,0x26,0x3f,0x01,0x26,0x23,0x22,0x0e,0x02,0x14,0x1e,0x02,0x33,0x32,0x36,0x37,0x3e,0x01, +0x1f,0x01,0x1e,0x01,0x07,0x0e,0x01,0x07,0x22,0x2e,0x02,0x3e,0x03,0x33,0x32,0x16,0x17,0x37,0x36,0x16,0x03,0x59,0x14,0x10,0xfa,0x17,0x13,0x11,0x4d,0x52,0x70,0x3a,0x6a,0x4c,0x2e,0x2e,0x4c,0x6a,0x3a,0x42,0x76,0x29,0x04,0x11,0x06,0x4c,0x05,0x02,0x06,0x3c,0xae,0x5f,0x57,0xa0,0x70,0x48,0x04,0x40,0x78,0x98,0x5b,0x52,0x98,0x3d, +0x48,0x11,0x2c,0x02,0xc3,0xfa,0x0e,0x16,0x2d,0x10,0x4d,0x4d,0x2e,0x4c,0x6a,0x74,0x6a,0x4c,0x2e,0x3a,0x35,0x06,0x01,0x05,0x4d,0x04,0x0e,0x06,0x4a,0x50,0x01,0x44,0x74,0x9e,0xae,0x9e,0x74,0x44,0x3e,0x39,0x48,0x12,0x13,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x58,0x01,0xe6,0x00,0x15,0x00,0x19,0x40,0x16,0x0f,0x01,0x00,0x01, +0x01,0x4c,0x02,0x01,0x01,0x00,0x01,0x85,0x00,0x00,0x00,0x76,0x14,0x17,0x14,0x03,0x07,0x19,0x2b,0x01,0x14,0x07,0x01,0x06,0x22,0x27,0x01,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x02,0x58,0x06,0xfe,0xfc,0x05,0x10,0x04,0xfe,0xfc,0x06,0x06,0x1c,0x05,0x0e,0x06,0xdb,0xdc,0x05,0x10,0x04,0x1c,0x06, +0x01,0xb7,0x07,0x05,0xfe,0xfb,0x05,0x05,0x01,0x05,0x05,0x0e,0x06,0x1c,0x06,0x06,0xdb,0xdb,0x06,0x06,0x1c,0x05,0x00,0x00,0x00,0x03,0xff,0xfd,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2e,0x00,0x41,0x40,0x3e,0x28,0x1e,0x02,0x05,0x04,0x16,0x15,0x0e,0x03,0x03,0x02,0x02,0x4c,0x00,0x05,0x00,0x02,0x03,0x05,0x02, +0x67,0x00,0x04,0x04,0x00,0x61,0x06,0x01,0x00,0x00,0x13,0x4d,0x00,0x03,0x03,0x01,0x61,0x00,0x01,0x01,0x11,0x01,0x4e,0x01,0x00,0x2c,0x2a,0x23,0x21,0x1a,0x18,0x12,0x10,0x07,0x06,0x00,0x0c,0x01,0x0c,0x07,0x07,0x16,0x2b,0x01,0x32,0x1e,0x01,0x14,0x0e,0x01,0x22,0x2e,0x02,0x3e,0x01,0x13,0x35,0x34,0x26,0x2b,0x01,0x22,0x06,0x07, +0x15,0x14,0x16,0x17,0x33,0x32,0x36,0x27,0x13,0x34,0x27,0x26,0x2b,0x01,0x22,0x07,0x06,0x15,0x13,0x14,0x16,0x3b,0x01,0x32,0x36,0x01,0xad,0x74,0xc6,0x72,0x72,0xc6,0xe8,0xc8,0x6e,0x06,0x7a,0xbc,0xc1,0x0a,0x07,0x6b,0x08,0x0a,0x01,0x0c,0x07,0x6b,0x07,0x0a,0x01,0x0a,0x06,0x05,0x08,0x7b,0x08,0x05,0x06,0x0a,0x0a,0x09,0x67,0x08, +0x0a,0x03,0x0b,0x74,0xc4,0xea,0xc4,0x74,0x74,0xc4,0xea,0xc4,0x74,0xfd,0x48,0x6a,0x08,0x0a,0x0a,0x08,0x6a,0x08,0x0a,0x01,0x0c,0xc7,0x01,0x5a,0x07,0x03,0x05,0x05,0x03,0x07,0xfe,0xa6,0x06,0x08,0x08,0x00,0x00,0x01,0x00,0x00,0xff,0xef,0x02,0xd4,0x02,0x86,0x00,0x24,0x00,0x26,0x40,0x23,0x22,0x19,0x10,0x07,0x04,0x00,0x02,0x01, +0x4c,0x03,0x01,0x02,0x00,0x00,0x02,0x59,0x03,0x01,0x02,0x02,0x00,0x61,0x01,0x01,0x00,0x02,0x00,0x51,0x14,0x1c,0x14,0x14,0x04,0x07,0x1a,0x2b,0x25,0x14,0x0f,0x01,0x06,0x22,0x2f,0x01,0x07,0x06,0x22,0x2f,0x01,0x26,0x34,0x3f,0x01,0x27,0x26,0x34,0x3f,0x01,0x36,0x32,0x1f,0x01,0x37,0x36,0x32,0x1f,0x01,0x16,0x14,0x0f,0x01,0x17, +0x16,0x02,0xd4,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x0f,0x0f,0xa4,0xa4,0x0f,0x70,0x16,0x10,0x4c,0x0f,0x0f,0xa5,0xa5,0x0f,0x0f,0x4c,0x10,0x2c,0x10,0xa4,0xa4,0x10,0x2c,0x10,0x4c,0x10,0x10,0xa4,0xa4,0x10,0x10,0x4c,0x0f,0x2e, +0x0f,0xa4,0xa4,0x0f,0x00,0x03,0x00,0x00,0xff,0xb1,0x03,0xc5,0x03,0x0b,0x00,0x0c,0x00,0x1c,0x00,0x2c,0x00,0x34,0x40,0x31,0x25,0x1d,0x02,0x04,0x05,0x00,0x01,0x01,0x00,0x02,0x4c,0x00,0x03,0x00,0x00,0x01,0x03,0x00,0x67,0x00,0x04,0x04,0x05,0x5f,0x00,0x05,0x05,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e, +0x35,0x35,0x35,0x35,0x24,0x32,0x06,0x07,0x1c,0x2b,0x01,0x34,0x26,0x07,0x23,0x22,0x0e,0x01,0x16,0x17,0x33,0x32,0x36,0x25,0x11,0x14,0x06,0x23,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x33,0x21,0x32,0x16,0x37,0x15,0x14,0x06,0x23,0x21,0x22,0x26,0x37,0x35,0x34,0x36,0x33,0x21,0x32,0x16,0x02,0x5f,0x14,0x10,0x8e,0x0f,0x14,0x02,0x18, +0x0d,0x8e,0x0f,0x16,0x01,0x41,0x16,0x0e,0xfc,0xee,0x0e,0x16,0x16,0x0e,0x03,0x12,0x0e,0x16,0x23,0x14,0x0f,0xfc,0xa6,0x0e,0x16,0x01,0x14,0x0f,0x03,0x5a,0x0e,0x16,0x01,0x82,0x0e,0x16,0x01,0x14,0x1e,0x14,0x01,0x16,0x79,0xfd,0xe8,0x0e,0x16,0x16,0x0e,0x02,0x18,0x0e,0x16,0x16,0xec,0x8f,0x0e,0x16,0x16,0x0e,0x8f,0x0e,0x16,0x16, +0x00,0x05,0x00,0x00,0xff,0x88,0x03,0xac,0x03,0x34,0x00,0x43,0x00,0x4c,0x00,0x55,0x00,0x5e,0x00,0x67,0x00,0x61,0x40,0x5e,0x3c,0x33,0x02,0x05,0x0a,0x1a,0x0f,0x02,0x01,0x05,0x2b,0x22,0x19,0x10,0x09,0x00,0x06,0x08,0x01,0x03,0x4c,0x07,0x01,0x05,0x03,0x01,0x01,0x08,0x05,0x01,0x67,0x00,0x0a,0x0f,0x0c,0x02,0x08,0x09,0x0a,0x08, +0x69,0x10,0x0e,0x0d,0x03,0x09,0x04,0x02,0x02,0x00,0x09,0x00,0x65,0x00,0x0b,0x0b,0x06,0x61,0x00,0x06,0x06,0x12,0x0b,0x4e,0x60,0x5f,0x64,0x63,0x5f,0x67,0x60,0x67,0x5d,0x5c,0x59,0x58,0x54,0x53,0x50,0x4f,0x4b,0x4a,0x15,0x36,0x16,0x37,0x18,0x36,0x16,0x36,0x14,0x11,0x07,0x1f,0x2b,0x25,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34, +0x37,0x35,0x34,0x2b,0x01,0x22,0x27,0x15,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x06,0x2b,0x01,0x22,0x0e,0x01,0x1d,0x01,0x16,0x15,0x14,0x06,0x22,0x26,0x35,0x34,0x37,0x35,0x34,0x36,0x3b,0x01,0x32,0x3d,0x01,0x26,0x35,0x34,0x36,0x32,0x16,0x15,0x14,0x07,0x15,0x14,0x3b,0x01,0x32,0x16,0x15,0x05,0x34,0x26,0x22,0x06, +0x14,0x16,0x32,0x36,0x13,0x14,0x16,0x32,0x36,0x34,0x26,0x22,0x06,0x13,0x34,0x26,0x22,0x06,0x14,0x16,0x32,0x36,0x05,0x32,0x36,0x34,0x26,0x22,0x06,0x14,0x16,0x03,0x64,0x48,0x46,0x64,0x46,0x48,0x4c,0x64,0x2c,0x22,0x48,0x46,0x64,0x46,0x48,0x1e,0x2e,0x64,0x22,0x26,0x06,0x48,0x46,0x64,0x46,0x48,0x56,0x58,0x64,0x4c,0x48,0x46, +0x64,0x46,0x48,0x4e,0x64,0x56,0x56,0xfd,0x5a,0x2a,0x38,0x28,0x28,0x38,0x2a,0xd4,0x28,0x38,0x2a,0x2a,0x38,0x28,0x8a,0x2a,0x38,0x28,0x28,0x38,0x2a,0x01,0x18,0x1c,0x2a,0x2a,0x38,0x28,0x28,0x70,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x4e,0x0c,0xcc,0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0xcc,0x0c,0x26,0x1c,0x0c,0x72, +0x22,0x4e,0x32,0x46,0x46,0x32,0x4e,0x22,0x72,0x40,0x6c,0x34,0x8c,0x22,0x4c,0x32,0x46,0x46,0x32,0x4c,0x22,0x8c,0x34,0x6c,0x40,0xe2,0x1e,0x28,0x28,0x3a,0x28,0x28,0x02,0xd8,0x1c,0x28,0x28,0x3a,0x28,0x28,0xfd,0x26,0x1e,0x28,0x28,0x3a,0x28,0x28,0x28,0x28,0x3a,0x28,0x28,0x3a,0x28,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59, +0x03,0x0b,0x00,0x23,0x00,0x33,0x00,0x3e,0x40,0x3b,0x0d,0x01,0x00,0x01,0x1f,0x01,0x04,0x03,0x02,0x4c,0x02,0x01,0x00,0x01,0x03,0x01,0x00,0x03,0x80,0x05,0x01,0x03,0x04,0x01,0x03,0x04,0x7e,0x00,0x01,0x01,0x07,0x5f,0x00,0x07,0x07,0x13,0x4d,0x00,0x04,0x04,0x06,0x60,0x00,0x06,0x06,0x11,0x06,0x4e,0x35,0x35,0x23,0x33,0x16,0x23, +0x24,0x23,0x08,0x07,0x1e,0x2b,0x01,0x35,0x34,0x26,0x07,0x23,0x35,0x34,0x26,0x27,0x23,0x22,0x06,0x07,0x15,0x23,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x33,0x15,0x14,0x16,0x3b,0x01,0x32,0x36,0x37,0x35,0x33,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xb3,0x16, +0x0e,0x47,0x0f,0x14,0x01,0xb2,0x0f,0x14,0x01,0x16,0x0e,0xb2,0x16,0x0e,0x47,0x0f,0x14,0x01,0xb3,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0xb3,0x0f,0x14,0x01,0x16,0x0e,0xb3,0x14,0x0f,0x48,0x0e,0x16,0x01,0xb3,0x0e,0x16,0x16,0x0e,0xb3,0x14,0x01,0x3f,0xfd,0xe8, +0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x02,0x00,0x00,0xff,0xb1,0x03,0x59,0x03,0x0b,0x00,0x0f,0x00,0x1f,0x00,0x1f,0x40,0x1c,0x00,0x00,0x00,0x03,0x5f,0x00,0x03,0x03,0x13,0x4d,0x00,0x01,0x01,0x02,0x5f,0x00,0x02,0x02,0x11,0x02,0x4e,0x35,0x35,0x26,0x33,0x04,0x07,0x1a,0x2b,0x01,0x35,0x34,0x26,0x07, +0x21,0x22,0x06,0x07,0x15,0x14,0x16,0x37,0x21,0x32,0x36,0x13,0x11,0x14,0x06,0x07,0x21,0x22,0x26,0x35,0x11,0x34,0x36,0x37,0x21,0x32,0x16,0x02,0xca,0x14,0x0f,0xfe,0x0c,0x0f,0x14,0x01,0x16,0x0e,0x01,0xf4,0x0e,0x16,0x8e,0x5e,0x43,0xfd,0xe9,0x43,0x5e,0x5e,0x43,0x02,0x17,0x43,0x5e,0x01,0x3a,0x48,0x0e,0x16,0x01,0x14,0x0f,0x48, +0x0e,0x16,0x01,0x14,0x01,0x3f,0xfd,0xe8,0x42,0x5e,0x01,0x60,0x41,0x02,0x18,0x42,0x5e,0x01,0x60,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x07,0xb3,0xdb,0xee,0x5f,0x0f,0x3c,0xf5,0x00,0x0f,0x03,0xe8,0x00,0x00,0x00,0x00,0xe4,0x2d,0xc8,0x06,0x00,0x00,0x00,0x00,0xe4,0x2d,0xc8,0x07,0xff,0xf5,0xff,0x6a,0x04,0x78,0x03,0x53, +0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x52,0xff,0x6a,0x00,0x00,0x04,0x76,0xff,0xf5,0xff,0xf5,0x04,0x78,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x80,0x00,0x00,0x03,0xe8,0x00,0x00, +0x04,0x2f,0xff,0xff,0x00,0xf0,0x00,0x00,0x04,0x76,0xff,0xff,0x03,0xe8,0xff,0xff,0x03,0xe8,0x00,0x00,0x02,0x44,0x00,0x00,0x02,0x44,0x00,0x00,0x03,0x59,0xff,0xfd,0x02,0x3b,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x11,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0xdc,0x00,0x00,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00, +0x02,0x3b,0xff,0xff,0x01,0x65,0x00,0x00,0x01,0x65,0x00,0x00,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x03,0xca,0x00,0x00,0x04,0x2f,0xff,0xff,0x03,0xa0,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xd4,0xff,0xf7,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xff,0x02,0x82,0x00,0x00, +0x02,0xda,0x00,0x00,0x04,0x2f,0xff,0xff,0x02,0xf8,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xff,0x02,0xda,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x02,0xf8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0xff,0xf5,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0x11,0x00,0x00, +0x03,0x11,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0x42,0x00,0x00,0x04,0x2f,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xe7,0xff,0xfe,0x03,0x59,0x00,0x00,0x03,0x11,0x00,0x00,0x02,0x3b,0xff,0xff,0x03,0x98,0xff,0xfc,0x03,0x59,0x00,0x00,0x02,0x82,0x00,0x00,0x03,0xa0,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0xe8,0xff,0xff, +0x03,0x59,0xff,0xfd,0x02,0x82,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0xff,0xfe,0x02,0x82,0x00,0x00,0x03,0x59,0xff,0xfd,0x03,0x11,0x00,0x00,0x03,0xe8,0x00,0x00,0x03,0xac,0x00,0x00,0x03,0x59,0x00,0x00,0x03,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0xe0,0x01,0x76,0x01,0xf0, +0x02,0x46,0x02,0x9e,0x02,0xc4,0x03,0x10,0x03,0x46,0x03,0x68,0x03,0x8c,0x03,0xb8,0x04,0x42,0x05,0x04,0x05,0x60,0x05,0xf4,0x06,0x18,0x06,0x42,0x06,0x64,0x06,0x8e,0x06,0xc6,0x06,0xfe,0x07,0xa6,0x07,0xf8,0x08,0xa0,0x08,0xf2,0x09,0x20,0x09,0x42,0x09,0x8e,0x09,0xd6,0x0a,0x98,0x0b,0x82,0x0c,0x0e,0x0c,0xfa,0x0d,0x3e,0x0d,0x64, +0x0d,0xc6,0x0e,0x2a,0x0e,0x6c,0x0f,0x1e,0x0f,0xce,0x0f,0xf6,0x10,0x4a,0x11,0x7c,0x11,0x9a,0x11,0xd2,0x12,0x3c,0x12,0x98,0x12,0xf8,0x14,0x00,0x14,0x80,0x14,0xe0,0x15,0x1a,0x15,0xde,0x16,0x6a,0x16,0xc0,0x17,0xce,0x18,0x30,0x18,0x88,0x18,0xa6,0x18,0xe4,0x19,0x80,0x19,0xe8,0x1a,0x3c,0x1a,0xb8,0x1b,0x48,0x1b,0x7c,0x1b,0xd0, +0x1c,0x32,0x1c,0xc0,0x1d,0x04,0x1d,0x2e,0x1d,0x94,0x1d,0xca,0x1e,0x32,0x1e,0x80,0x1e,0xde,0x1f,0x9a,0x20,0x04,0x20,0x48,0x00,0x01,0x00,0x00,0x00,0x51,0x00,0x90,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x00,0x7b,0x00,0x8d,0x00,0x00,0x00,0xba,0x0e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xde,0x00,0x01, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x35,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x44,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x4c,0x00,0x01,0x00,0x00,0x00,0x00, +0x00,0x05,0x00,0x0b,0x00,0x54,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x5f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x2b,0x00,0x67,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x13,0x00,0x92,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x00,0x00,0x6a,0x00,0xa5,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x01,0x00,0x10, +0x01,0x0f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x02,0x00,0x0e,0x01,0x1f,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x03,0x00,0x10,0x01,0x2d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x04,0x00,0x10,0x01,0x3d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x05,0x00,0x16,0x01,0x4d,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x06,0x00,0x10,0x01,0x63,0x00,0x03, +0x00,0x01,0x04,0x09,0x00,0x0a,0x00,0x56,0x01,0x73,0x00,0x03,0x00,0x01,0x04,0x09,0x00,0x0b,0x00,0x26,0x01,0xc9,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x32,0x30,0x32,0x35,0x20,0x62,0x79,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x20,0x40,0x20,0x66, +0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x52,0x65,0x67,0x75,0x6c,0x61,0x72,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x47,0x65,0x6e, +0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x73,0x76,0x67,0x32,0x74,0x74,0x66,0x20,0x66,0x72,0x6f,0x6d,0x20,0x46,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x20,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x2e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x66,0x6f,0x6e,0x74,0x65,0x6c,0x6c,0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x43,0x00,0x6f,0x00, +0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x20,0x00,0x28,0x00,0x43,0x00,0x29,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x32,0x00,0x35,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x6f,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6e,0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x61,0x00,0x75,0x00,0x74,0x00, +0x68,0x00,0x6f,0x00,0x72,0x00,0x73,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x52,0x00,0x65,0x00,0x67,0x00,0x75,0x00,0x6c,0x00, +0x61,0x00,0x72,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x31,0x00,0x2e,0x00,0x30,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00, +0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x47,0x00,0x65,0x00,0x6e,0x00,0x65,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x62,0x00,0x79,0x00,0x20,0x00,0x73,0x00,0x76,0x00,0x67,0x00,0x32,0x00,0x74,0x00,0x74,0x00,0x66,0x00,0x20,0x00,0x66,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x20,0x00,0x46,0x00, +0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,0x00,0x6a,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x2e,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x00,0x66,0x00,0x6f,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x6f,0x00,0x2e,0x00, +0x63,0x00,0x6f,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c, +0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01,0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2c, +0x01,0x2d,0x01,0x2e,0x01,0x2f,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01,0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01,0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4c, +0x01,0x4d,0x01,0x4e,0x01,0x4f,0x01,0x50,0x01,0x51,0x01,0x52,0x00,0x0b,0x63,0x68,0x65,0x63,0x6b,0x2d,0x65,0x6d,0x70,0x74,0x79,0x0d,0x66,0x6c,0x6f,0x77,0x2d,0x70,0x61,0x72,0x61,0x6c,0x6c,0x65,0x6c,0x04,0x64,0x6f,0x63,0x73,0x07,0x70,0x69,0x63,0x74,0x75,0x72,0x65,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x6c,0x69,0x6e,0x65,0x0e,0x77, +0x69,0x6e,0x64,0x6f,0x77,0x2d,0x72,0x65,0x73,0x74,0x6f,0x72,0x65,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x69,0x6e,0x69,0x6d,0x69,0x7a,0x65,0x04,0x63,0x75,0x62,0x65,0x04,0x70,0x6c,0x75,0x73,0x05,0x6d,0x69,0x6e,0x75,0x73,0x06,0x63,0x69,0x72,0x63,0x6c,0x65,0x08,0x64,0x6f,0x77,0x6e,0x2d,0x64,0x69,0x72,0x05,0x63,0x68, +0x65,0x63,0x6b,0x0b,0x74,0x72,0x61,0x73,0x68,0x2d,0x65,0x6d,0x70,0x74,0x79,0x04,0x75,0x73,0x65,0x72,0x09,0x62,0x72,0x69,0x65,0x66,0x63,0x61,0x73,0x65,0x03,0x64,0x6f,0x74,0x08,0x6c,0x65,0x66,0x74,0x2d,0x64,0x69,0x72,0x09,0x72,0x69,0x67,0x68,0x74,0x2d,0x64,0x69,0x72,0x06,0x75,0x70,0x2d,0x64,0x69,0x72,0x0a,0x61,0x6e,0x67, +0x6c,0x65,0x2d,0x6c,0x65,0x66,0x74,0x0b,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x72,0x69,0x67,0x68,0x74,0x0c,0x68,0x65,0x6c,0x70,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03,0x74,0x61,0x67,0x04,0x67,0x72,0x69,0x64,0x0b,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f,0x70,0x65,0x6e,0x06,0x66,0x6f,0x6c,0x64,0x65,0x72,0x09,0x64,0x6f,0x77, +0x6e,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x70,0x61,0x6c,0x65,0x74,0x74,0x65,0x07,0x64,0x6f,0x63,0x2d,0x69,0x6e,0x76,0x03,0x63,0x6f,0x67,0x02,0x74,0x68,0x0a,0x62,0x69,0x6e,0x6f,0x63,0x75,0x6c,0x61,0x72,0x73,0x04,0x6c,0x69,0x73,0x74,0x04,0x6c,0x6f,0x63,0x6b,0x09,0x6c,0x65,0x66,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x07,0x64,0x65,0x73, +0x6b,0x74,0x6f,0x70,0x06,0x73,0x65,0x61,0x72,0x63,0x68,0x0c,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x65,0x6d,0x70,0x74,0x79,0x06,0x70,0x65,0x6e,0x63,0x69,0x6c,0x03,0x68,0x64,0x64,0x0a,0x72,0x69,0x67,0x68,0x74,0x2d,0x62,0x6f,0x6c,0x64,0x0b,0x63,0x6c,0x6f,0x73,0x65,0x5f,0x70,0x61,0x6e,0x65,0x6c,0x08,0x73,0x74,0x65,0x70,0x69, +0x6e,0x74,0x6f,0x07,0x75,0x70,0x2d,0x62,0x6f,0x6c,0x64,0x02,0x6f,0x6b,0x09,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x10,0x68,0x6f,0x72,0x69,0x7a,0x6f,0x6e,0x74,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x0e,0x76,0x65,0x72,0x74,0x69,0x63,0x61,0x6c,0x5f,0x73,0x70,0x6c,0x69,0x74,0x08,0x73,0x74,0x65,0x70,0x6f,0x76,0x65, +0x72,0x10,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x11,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x2d,0x61,0x6c,0x74,0x08,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x75,0x70,0x09,0x63,0x6c,0x69,0x70,0x62,0x6f,0x61,0x72,0x64,0x11,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x6f, +0x70,0x65,0x6e,0x2d,0x65,0x6d,0x70,0x74,0x79,0x0c,0x66,0x6f,0x6c,0x64,0x65,0x72,0x2d,0x65,0x6d,0x70,0x74,0x79,0x07,0x73,0x74,0x65,0x70,0x6f,0x75,0x74,0x07,0x67,0x6c,0x61,0x73,0x73,0x65,0x73,0x03,0x64,0x6f,0x63,0x04,0x70,0x6c,0x61,0x79,0x06,0x74,0x6f,0x2d,0x65,0x6e,0x64,0x0c,0x69,0x6e,0x66,0x6f,0x2d,0x63,0x69,0x72,0x63, +0x6c,0x65,0x64,0x03,0x63,0x63,0x77,0x0d,0x6c,0x6f,0x63,0x6b,0x2d,0x6f,0x70,0x65,0x6e,0x2d,0x61,0x6c,0x74,0x06,0x74,0x61,0x72,0x67,0x65,0x74,0x06,0x66,0x6c,0x6f,0x70,0x70,0x79,0x0f,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x6d,0x61,0x78,0x69,0x6d,0x69,0x7a,0x65,0x0b,0x64,0x6f,0x74,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x03, +0x70,0x69,0x6e,0x09,0x61,0x72,0x72,0x6f,0x77,0x73,0x2d,0x63,0x77,0x05,0x70,0x61,0x75,0x73,0x65,0x04,0x73,0x74,0x6f,0x70,0x02,0x63,0x77,0x0a,0x61,0x6e,0x67,0x6c,0x65,0x2d,0x64,0x6f,0x77,0x6e,0x11,0x61,0x74,0x74,0x65,0x6e,0x74,0x69,0x6f,0x6e,0x2d,0x63,0x69,0x72,0x63,0x6c,0x65,0x64,0x06,0x63,0x61,0x6e,0x63,0x65,0x6c,0x03, +0x62,0x6f,0x78,0x09,0x66,0x6c,0x6f,0x77,0x2d,0x74,0x72,0x65,0x65,0x0c,0x70,0x6c,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x0d,0x6d,0x69,0x6e,0x75,0x73,0x2d,0x73,0x71,0x75,0x61,0x72,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xff,0xff,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x01,0x1e,0x00,0x7d,0x00,0x7d,0x01,0x1e,0x03,0x18,0xff,0xb1,0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0x03,0x18,0xff,0xb1,0x03,0x38,0x03,0x0b,0xff,0xb1,0xff,0xb1,0xb0,0x00,0x2c,0x20,0xb0,0x00,0x55,0x58,0x45,0x59,0x20,0x20,0x4b,0xb8,0x00,0x0e,0x51,0x4b,0xb0,0x06, +0x53,0x5a,0x58,0xb0,0x34,0x1b,0xb0,0x28,0x59,0x60,0x66,0x20,0x8a,0x55,0x58,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x62,0x1b,0x21,0x21,0xb0,0x00,0x59,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x01,0x2c,0xb0,0x20,0x60,0x66,0x2d,0xb0,0x02,0x2c,0x23,0x21,0x23,0x21,0x2d,0xb0, +0x03,0x2c,0x20,0x64,0xb3,0x03,0x14,0x15,0x00,0x42,0x43,0xb0,0x13,0x43,0x20,0x60,0x60,0x42,0xb1,0x02,0x14,0x43,0x42,0xb1,0x25,0x03,0x43,0xb0,0x02,0x43,0x54,0x78,0x20,0xb0,0x0c,0x23,0xb0,0x02,0x43,0x43,0x61,0x64,0xb0,0x04,0x50,0x78,0xb2,0x02,0x02,0x02,0x43,0x60,0x42,0xb0,0x21,0x65,0x1c,0x21,0xb0,0x02,0x43,0x43,0xb2,0x0e, +0x15,0x01,0x42,0x1c,0x20,0xb0,0x02,0x43,0x23,0x42,0xb2,0x13,0x01,0x13,0x43,0x60,0x42,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb2,0x16,0x01,0x02,0x43,0x60,0x42,0x2d,0xb0,0x04,0x2c,0xb0,0x03,0x2b,0xb0,0x15,0x43,0x58,0x23,0x21,0x23,0x21,0xb0,0x16,0x43,0x43,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x1b,0x20,0x64,0x20,0xb0,0xc0,0x50, +0xb0,0x04,0x26,0x5a,0xb2,0x28,0x01,0x0d,0x43,0x45,0x63,0x45,0xb0,0x06,0x45,0x58,0x21,0xb0,0x03,0x25,0x59,0x52,0x5b,0x58,0x21,0x23,0x21,0x1b,0x8a,0x58,0x20,0xb0,0x50,0x50,0x58,0x21,0xb0,0x40,0x59,0x1b,0x20,0xb0,0x38,0x50,0x58,0x21,0xb0,0x38,0x59,0x59,0x20,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x61,0x64,0xb0,0x28,0x50,0x58, +0x21,0xb1,0x01,0x0d,0x43,0x45,0x63,0x45,0x20,0xb0,0x30,0x50,0x58,0x21,0xb0,0x30,0x59,0x1b,0x20,0xb0,0xc0,0x50,0x58,0x20,0x66,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x0a,0x50,0x58,0x60,0x1b,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x0a,0x60,0x1b,0x20,0xb0,0x36,0x50,0x58,0x21,0xb0,0x36,0x60,0x1b,0x60,0x59,0x59,0x59,0x1b,0xb0,0x02,0x25, +0xb0,0x0c,0x43,0x63,0xb0,0x00,0x52,0x58,0xb0,0x00,0x4b,0xb0,0x0a,0x50,0x58,0x21,0xb0,0x0c,0x43,0x1b,0x4b,0xb0,0x1e,0x50,0x58,0x21,0xb0,0x1e,0x4b,0x61,0xb8,0x10,0x00,0x63,0xb0,0x0c,0x43,0x63,0xb8,0x05,0x00,0x62,0x59,0x59,0x64,0x61,0x59,0xb0,0x01,0x2b,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0x59,0x20,0x64,0xb0,0x16, +0x43,0x23,0x42,0x59,0x2d,0xb0,0x05,0x2c,0x20,0x45,0x20,0xb0,0x04,0x25,0x61,0x64,0x20,0xb0,0x07,0x43,0x50,0x58,0xb0,0x07,0x23,0x42,0xb0,0x08,0x23,0x42,0x1b,0x21,0x21,0x59,0xb0,0x01,0x60,0x2d,0xb0,0x06,0x2c,0x23,0x21,0x23,0x21,0xb0,0x03,0x2b,0x20,0x64,0xb1,0x07,0x62,0x42,0x20,0xb0,0x08,0x23,0x42,0xb0,0x06,0x45,0x58,0x1b, +0xb1,0x01,0x0d,0x43,0x45,0x63,0xb1,0x01,0x0d,0x43,0xb0,0x01,0x60,0x45,0x63,0xb0,0x05,0x2a,0x21,0x20,0xb0,0x08,0x43,0x20,0x8a,0x20,0x8a,0xb0,0x01,0x2b,0xb1,0x30,0x05,0x25,0xb0,0x04,0x26,0x51,0x58,0x60,0x50,0x1b,0x61,0x52,0x59,0x58,0x23,0x59,0x21,0x59,0x20,0xb0,0x40,0x53,0x58,0xb0,0x01,0x2b,0x1b,0x21,0xb0,0x40,0x59,0x23, +0xb0,0x00,0x50,0x58,0x65,0x59,0x2d,0xb0,0x07,0x2c,0xb0,0x09,0x43,0x2b,0xb2,0x00,0x02,0x00,0x43,0x60,0x42,0x2d,0xb0,0x08,0x2c,0xb0,0x09,0x23,0x42,0x23,0x20,0xb0,0x00,0x23,0x42,0x61,0xb0,0x02,0x62,0x66,0xb0,0x01,0x63,0xb0,0x01,0x60,0xb0,0x07,0x2a,0x2d,0xb0,0x09,0x2c,0x20,0x20,0x45,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00, +0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0a,0x2c,0xb2,0x09,0x0e,0x00,0x43,0x45,0x42,0x2a,0x21,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0b,0x2c,0xb0,0x00,0x43,0x23,0x44,0xb2,0x00,0x01,0x00,0x43,0x60,0x42,0x2d,0xb0,0x0c,0x2c,0x20,0x20,0x45,0x20,0xb0, +0x01,0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0x20,0xb0,0x20,0x50,0x58,0x21,0xb0,0x00,0x1b,0xb0,0x30,0x50,0x58,0xb0,0x20,0x1b,0xb0,0x40,0x59,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0d,0x2c,0x20,0x20,0x45,0x20,0xb0,0x01, +0x2b,0x23,0xb0,0x00,0x43,0xb0,0x04,0x25,0x60,0x20,0x45,0x8a,0x23,0x61,0x20,0x64,0xb0,0x24,0x50,0x58,0xb0,0x00,0x1b,0xb0,0x40,0x59,0x23,0xb0,0x00,0x50,0x58,0x65,0x59,0xb0,0x03,0x25,0x23,0x61,0x44,0x44,0xb0,0x01,0x60,0x2d,0xb0,0x0e,0x2c,0x20,0xb0,0x00,0x23,0x42,0xb3,0x0d,0x0c,0x00,0x03,0x45,0x50,0x58,0x21,0x1b,0x23,0x21, +0x59,0x2a,0x21,0x2d,0xb0,0x0f,0x2c,0xb1,0x02,0x02,0x45,0xb0,0x64,0x61,0x44,0x2d,0xb0,0x10,0x2c,0xb0,0x01,0x60,0x20,0x20,0xb0,0x0f,0x43,0x4a,0xb0,0x00,0x50,0x58,0x20,0xb0,0x0f,0x23,0x42,0x59,0xb0,0x10,0x43,0x4a,0xb0,0x00,0x52,0x58,0x20,0xb0,0x10,0x23,0x42,0x59,0x2d,0xb0,0x11,0x2c,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63, +0x20,0xb8,0x04,0x00,0x63,0x8a,0x23,0x61,0xb0,0x11,0x43,0x60,0x20,0x8a,0x60,0x20,0xb0,0x11,0x23,0x42,0x23,0x2d,0xb0,0x12,0x2c,0x4b,0x54,0x58,0xb1,0x04,0x64,0x44,0x59,0x24,0xb0,0x0d,0x65,0x23,0x78,0x2d,0xb0,0x13,0x2c,0x4b,0x51,0x58,0x4b,0x53,0x58,0xb1,0x04,0x64,0x44,0x59,0x1b,0x21,0x59,0x24,0xb0,0x13,0x65,0x23,0x78,0x2d, +0xb0,0x14,0x2c,0xb1,0x00,0x12,0x43,0x55,0x58,0xb1,0x12,0x12,0x43,0xb0,0x01,0x61,0x42,0xb0,0x11,0x2b,0x59,0xb0,0x00,0x43,0xb0,0x02,0x25,0x42,0xb1,0x0f,0x02,0x25,0x42,0xb1,0x10,0x02,0x25,0x42,0xb0,0x01,0x16,0x23,0x20,0xb0,0x03,0x25,0x50,0x58,0xb1,0x01,0x00,0x43,0x60,0xb0,0x04,0x25,0x42,0x8a,0x8a,0x20,0x8a,0x23,0x61,0xb0, +0x10,0x2a,0x21,0x23,0xb0,0x01,0x61,0x20,0x8a,0x23,0x61,0xb0,0x10,0x2a,0x21,0x1b,0xb1,0x01,0x00,0x43,0x60,0xb0,0x02,0x25,0x42,0xb0,0x02,0x25,0x61,0xb0,0x10,0x2a,0x21,0x59,0xb0,0x0f,0x43,0x47,0xb0,0x10,0x43,0x47,0x60,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x20,0xb0,0x0e,0x43,0x63, +0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb1,0x00,0x00,0x13,0x23,0x44,0xb0,0x01,0x43,0xb0,0x00,0x3e,0xb2,0x01,0x01,0x01,0x43,0x60,0x42,0x2d,0xb0,0x15,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60, +0x42,0x20,0x60,0xb7,0x18,0x18,0x01,0x00,0x11,0x00,0x13,0x00,0x42,0x42,0x42,0x8a,0x60,0x20,0xb0,0x14,0x23,0x42,0xb0,0x01,0x61,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b,0x1b,0x22,0x59,0x2d,0xb0,0x16,0x2c,0xb1,0x00,0x15,0x2b,0x2d,0xb0,0x17,0x2c,0xb1,0x01,0x15,0x2b,0x2d,0xb0,0x18,0x2c,0xb1,0x02,0x15,0x2b,0x2d,0xb0,0x19,0x2c,0xb1, +0x03,0x15,0x2b,0x2d,0xb0,0x1a,0x2c,0xb1,0x04,0x15,0x2b,0x2d,0xb0,0x1b,0x2c,0xb1,0x05,0x15,0x2b,0x2d,0xb0,0x1c,0x2c,0xb1,0x06,0x15,0x2b,0x2d,0xb0,0x1d,0x2c,0xb1,0x07,0x15,0x2b,0x2d,0xb0,0x1e,0x2c,0xb1,0x08,0x15,0x2b,0x2d,0xb0,0x1f,0x2c,0xb1,0x09,0x15,0x2b,0x2d,0xb0,0x2b,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63, +0xb0,0x06,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x5d,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2c,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x16,0x60,0x4b,0x54,0x58,0x23,0x20,0x2e,0xb0,0x01,0x71,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x2d,0x2c,0x23,0x20,0xb0,0x10,0x62,0x66,0xb0,0x01,0x63,0xb0,0x26,0x60,0x4b,0x54,0x58, +0x23,0x20,0x2e,0xb0,0x01,0x72,0x1b,0x21,0x21,0x59,0x2d,0xb0,0x20,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb0,0x12,0x23,0x42,0x20,0x45,0xb0,0x0e,0x23,0x42,0xb0,0x0d,0x23,0xb0,0x01,0x60,0x42,0x20,0x60,0xb0,0x01,0x61,0xb5,0x18,0x18,0x01,0x00,0x11,0x00,0x42,0x42,0x8a,0x60,0xb1,0x14,0x08,0x2b,0xb0,0x8b,0x2b, +0x1b,0x22,0x59,0x2d,0xb0,0x21,0x2c,0xb1,0x00,0x20,0x2b,0x2d,0xb0,0x22,0x2c,0xb1,0x01,0x20,0x2b,0x2d,0xb0,0x23,0x2c,0xb1,0x02,0x20,0x2b,0x2d,0xb0,0x24,0x2c,0xb1,0x03,0x20,0x2b,0x2d,0xb0,0x25,0x2c,0xb1,0x04,0x20,0x2b,0x2d,0xb0,0x26,0x2c,0xb1,0x05,0x20,0x2b,0x2d,0xb0,0x27,0x2c,0xb1,0x06,0x20,0x2b,0x2d,0xb0,0x28,0x2c,0xb1, +0x07,0x20,0x2b,0x2d,0xb0,0x29,0x2c,0xb1,0x08,0x20,0x2b,0x2d,0xb0,0x2a,0x2c,0xb1,0x09,0x20,0x2b,0x2d,0xb0,0x2e,0x2c,0x20,0x3c,0xb0,0x01,0x60,0x2d,0xb0,0x2f,0x2c,0x20,0x60,0xb0,0x18,0x60,0x20,0x43,0x23,0xb0,0x01,0x60,0x43,0xb0,0x02,0x25,0x61,0xb0,0x01,0x60,0xb0,0x2e,0x2a,0x21,0x2d,0xb0,0x30,0x2c,0xb0,0x2f,0x2b,0xb0,0x2f, +0x2a,0x2d,0xb0,0x31,0x2c,0x20,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x61,0x38,0x23,0x20,0x8a,0x55,0x58,0x20,0x47,0x20,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01, +0x63,0x60,0x23,0x61,0x38,0x1b,0x21,0x59,0x2d,0xb0,0x32,0x2c,0x00,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0,0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x33,0x2c,0x00,0xb0,0x0f,0x2b,0xb1,0x00,0x02,0x45,0x54,0x58,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x16,0xb0, +0x31,0x2a,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x1b,0x22,0x59,0x2d,0xb0,0x34,0x2c,0x20,0x35,0xb0,0x01,0x60,0x2d,0xb0,0x35,0x2c,0x00,0xb1,0x0e,0x07,0x45,0x42,0xb0,0x01,0x45,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62, +0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x01,0x2b,0xb0,0x00,0x16,0xb4,0x00,0x00,0x00,0x00,0x00,0x44,0x3e,0x23,0x38,0xb1,0x34,0x01,0x15,0x2a,0x21,0x2d,0xb0,0x36,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01, +0x63,0x60,0xb0,0x00,0x43,0x61,0x38,0x2d,0xb0,0x37,0x2c,0x2e,0x17,0x3c,0x2d,0xb0,0x38,0x2c,0x20,0x3c,0x20,0x47,0x20,0xb0,0x0e,0x43,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0xb0,0x00,0x43,0x61,0xb0,0x01,0x43,0x63,0x38,0x2d,0xb0,0x39,0x2c,0xb1,0x02,0x00,0x16,0x25,0x20, +0x2e,0x20,0x47,0xb0,0x00,0x23,0x42,0xb0,0x02,0x25,0x49,0x8a,0x8a,0x47,0x23,0x47,0x23,0x61,0x20,0x58,0x62,0x1b,0x21,0x59,0xb0,0x01,0x23,0x42,0xb2,0x38,0x01,0x01,0x15,0x14,0x2a,0x2d,0xb0,0x3a,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x47,0x23,0x47,0x23,0x61,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43, +0x2b,0x65,0x8a,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x3b,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b,0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3, +0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0xb0,0x0a,0x43,0x20,0x8a,0x23,0x47,0x23,0x47,0x23,0x61,0x23,0x46,0x60,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23,0xb0,0x05,0x43,0x61,0x64,0x50, +0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x1b,0x23,0xb0,0x0a,0x43,0x46,0xb0,0x02,0x25,0xb0,0x0a,0x43,0x47,0x23,0x47,0x23,0x61,0x60,0x20,0xb0,0x06,0x43,0xb0, +0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x20,0xb0,0x01,0x2b,0x23,0xb0,0x06,0x43,0x60,0xb0,0x01,0x2b,0xb0,0x05,0x25,0x61,0xb0,0x05,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0xb0,0x04,0x26,0x61,0x20,0xb0,0x04,0x25,0x60,0x64,0x23,0xb0, +0x03,0x25,0x60,0x64,0x50,0x58,0x21,0x1b,0x23,0x21,0x59,0x23,0x20,0x20,0xb0,0x04,0x26,0x23,0x46,0x61,0x38,0x59,0x2d,0xb0,0x3c,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0x20,0x20,0xb0,0x05,0x26,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x23,0x3c,0x38,0x2d,0xb0,0x3d,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x23, +0x42,0x20,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x2d,0xb0,0x3e,0x2c,0xb0,0x00,0x16,0xb0,0x17,0x23,0x42,0xb0,0x03,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0xb0,0x00,0x54,0x58,0x2e,0x20,0x3c,0x23,0x21,0x1b,0xb0,0x02,0x25,0xb0,0x02,0x25,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x05,0x25,0xb0,0x04,0x25,0x47, +0x23,0x47,0x23,0x61,0xb0,0x06,0x25,0xb0,0x05,0x25,0x49,0xb0,0x02,0x25,0x61,0xb9,0x08,0x00,0x08,0x00,0x63,0x63,0x23,0x20,0x58,0x62,0x1b,0x21,0x59,0x63,0xb8,0x04,0x00,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x23,0x2e,0x23,0x20,0x20,0x3c,0x8a,0x38,0x23,0x21,0x59,0x2d,0xb0,0x3f,0x2c,0xb0, +0x00,0x16,0xb0,0x17,0x23,0x42,0x20,0xb0,0x0a,0x43,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0x60,0xb0,0x20,0x60,0x66,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x23,0x20,0x20,0x3c,0x8a,0x38,0x2d,0xb0,0x40,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52, +0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x41,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x42,0x2c,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c, +0x59,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x52,0x1b,0x50,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x43,0x2c,0xb0,0x3a,0x2b,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x44,0x2c, +0xb0,0x3b,0x2b,0x8a,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x8a,0x38,0x23,0x20,0x2e,0x46,0xb0,0x02,0x25,0x46,0xb0,0x17,0x43,0x58,0x50,0x1b,0x52,0x59,0x58,0x20,0x3c,0x59,0x2e,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x45,0x2c,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x26,0x20,0x20,0x20,0x46,0x23, +0x47,0x61,0xb0,0x0c,0x23,0x42,0x2e,0x47,0x23,0x47,0x23,0x61,0xb0,0x0b,0x43,0x2b,0x23,0x20,0x3c,0x20,0x2e,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x46,0x2c,0xb1,0x0a,0x04,0x25,0x42,0xb0,0x00,0x16,0xb0,0x04,0x25,0xb0,0x04,0x25,0x20,0x2e,0x47,0x23,0x47,0x23,0x61,0x20,0xb0,0x06,0x23,0x42,0xb1,0x0c,0x00,0x42,0xb0,0x0b, +0x43,0x2b,0x20,0xb0,0x60,0x50,0x58,0x20,0xb0,0x40,0x51,0x58,0xb3,0x04,0x20,0x05,0x20,0x1b,0xb3,0x04,0x26,0x05,0x1a,0x59,0x42,0x42,0x23,0x20,0x47,0xb0,0x06,0x43,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x60,0x20,0xb0,0x01,0x2b,0x20,0x8a,0x8a,0x61,0x20,0xb0,0x04,0x43,0x60,0x64,0x23, +0xb0,0x05,0x43,0x61,0x64,0x50,0x58,0xb0,0x04,0x43,0x61,0x1b,0xb0,0x05,0x43,0x60,0x59,0xb0,0x03,0x25,0xb0,0x02,0x62,0x20,0xb0,0x00,0x50,0x58,0xb0,0x40,0x60,0x59,0x66,0xb0,0x01,0x63,0x61,0xb0,0x02,0x25,0x46,0x61,0x38,0x23,0x20,0x3c,0x23,0x38,0x1b,0x21,0x20,0x20,0x46,0x23,0x47,0xb0,0x01,0x2b,0x23,0x61,0x38,0x21,0x59,0xb1, +0x30,0x01,0x14,0x2b,0x2d,0xb0,0x47,0x2c,0xb1,0x00,0x3a,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x48,0x2c,0xb1,0x00,0x3b,0x2b,0x21,0x23,0x20,0x20,0x3c,0xb0,0x06,0x23,0x42,0x23,0x38,0xb1,0x30,0x01,0x14,0x2b,0xb0,0x06,0x43,0x2e,0xb0,0x30,0x2b,0x2d,0xb0,0x49,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00, +0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4a,0x2c,0xb0,0x00,0x15,0x20,0x47,0xb0,0x00,0x23,0x42,0xb2,0x00,0x01,0x01,0x15,0x14,0x13,0x2e,0xb0,0x36,0x2a,0x2d,0xb0,0x4b,0x2c,0xb1,0x00,0x01,0x14,0x13,0xb0,0x37,0x2a,0x2d,0xb0,0x4c,0x2c,0xb0,0x39,0x2a,0x2d,0xb0,0x4d,0x2c,0xb0,0x00,0x16,0x45,0x23,0x20,0x2e,0x20, +0x46,0x8a,0x23,0x61,0x38,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x4e,0x2c,0xb0,0x0a,0x23,0x42,0xb0,0x4d,0x2b,0x2d,0xb0,0x4f,0x2c,0xb2,0x00,0x00,0x46,0x2b,0x2d,0xb0,0x50,0x2c,0xb2,0x00,0x01,0x46,0x2b,0x2d,0xb0,0x51,0x2c,0xb2,0x01,0x00,0x46,0x2b,0x2d,0xb0,0x52,0x2c,0xb2,0x01,0x01,0x46,0x2b,0x2d,0xb0,0x53,0x2c,0xb2,0x00,0x00, +0x47,0x2b,0x2d,0xb0,0x54,0x2c,0xb2,0x00,0x01,0x47,0x2b,0x2d,0xb0,0x55,0x2c,0xb2,0x01,0x00,0x47,0x2b,0x2d,0xb0,0x56,0x2c,0xb2,0x01,0x01,0x47,0x2b,0x2d,0xb0,0x57,0x2c,0xb3,0x00,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x58,0x2c,0xb3,0x00,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x59,0x2c,0xb3,0x01,0x00,0x00,0x43,0x2b,0x2d,0xb0,0x5a,0x2c,0xb3, +0x01,0x01,0x00,0x43,0x2b,0x2d,0xb0,0x5b,0x2c,0xb3,0x00,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5c,0x2c,0xb3,0x00,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5d,0x2c,0xb3,0x01,0x00,0x01,0x43,0x2b,0x2d,0xb0,0x5e,0x2c,0xb3,0x01,0x01,0x01,0x43,0x2b,0x2d,0xb0,0x5f,0x2c,0xb2,0x00,0x00,0x45,0x2b,0x2d,0xb0,0x60,0x2c,0xb2,0x00,0x01,0x45,0x2b,0x2d, +0xb0,0x61,0x2c,0xb2,0x01,0x00,0x45,0x2b,0x2d,0xb0,0x62,0x2c,0xb2,0x01,0x01,0x45,0x2b,0x2d,0xb0,0x63,0x2c,0xb2,0x00,0x00,0x48,0x2b,0x2d,0xb0,0x64,0x2c,0xb2,0x00,0x01,0x48,0x2b,0x2d,0xb0,0x65,0x2c,0xb2,0x01,0x00,0x48,0x2b,0x2d,0xb0,0x66,0x2c,0xb2,0x01,0x01,0x48,0x2b,0x2d,0xb0,0x67,0x2c,0xb3,0x00,0x00,0x00,0x44,0x2b,0x2d, +0xb0,0x68,0x2c,0xb3,0x00,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x69,0x2c,0xb3,0x01,0x00,0x00,0x44,0x2b,0x2d,0xb0,0x6a,0x2c,0xb3,0x01,0x01,0x00,0x44,0x2b,0x2d,0xb0,0x6b,0x2c,0xb3,0x00,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6c,0x2c,0xb3,0x00,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6d,0x2c,0xb3,0x01,0x00,0x01,0x44,0x2b,0x2d,0xb0,0x6e,0x2c,0xb3, +0x01,0x01,0x01,0x44,0x2b,0x2d,0xb0,0x6f,0x2c,0xb1,0x00,0x3c,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x70,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x71,0x2c,0xb1,0x00,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x72,0x2c,0xb0,0x00,0x16,0xb1,0x00,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x73,0x2c,0xb1,0x01,0x3c,0x2b,0xb0, +0x40,0x2b,0x2d,0xb0,0x74,0x2c,0xb1,0x01,0x3c,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x75,0x2c,0xb0,0x00,0x16,0xb1,0x01,0x3c,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x76,0x2c,0xb1,0x00,0x3d,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x77,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x78,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x41,0x2b,0x2d, +0xb0,0x79,0x2c,0xb1,0x00,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7a,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7b,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x7c,0x2c,0xb1,0x01,0x3d,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x7d,0x2c,0xb1,0x00,0x3e,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x7e,0x2c,0xb1,0x00,0x3e, +0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x7f,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x80,0x2c,0xb1,0x00,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x81,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x82,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x83,0x2c,0xb1,0x01,0x3e,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x84,0x2c,0xb1, +0x00,0x3f,0x2b,0x2e,0xb1,0x30,0x01,0x14,0x2b,0x2d,0xb0,0x85,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x86,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x41,0x2b,0x2d,0xb0,0x87,0x2c,0xb1,0x00,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x88,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x40,0x2b,0x2d,0xb0,0x89,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x41,0x2b, +0x2d,0xb0,0x8a,0x2c,0xb1,0x01,0x3f,0x2b,0xb0,0x42,0x2b,0x2d,0xb0,0x8b,0x2c,0xb2,0x0b,0x00,0x03,0x45,0x50,0x58,0xb0,0x06,0x1b,0xb2,0x04,0x02,0x03,0x45,0x58,0x23,0x21,0x1b,0x21,0x59,0x59,0x42,0x2b,0xb0,0x08,0x65,0xb0,0x03,0x24,0x50,0x78,0xb1,0x05,0x01,0x15,0x45,0x58,0x30,0x59,0x2d,0x00,0x4b,0xb8,0x00,0xc8,0x52,0x58,0xb1, +0x01,0x01,0x8e,0x59,0xb0,0x01,0xb9,0x08,0x00,0x08,0x00,0x63,0x70,0xb1,0x00,0x07,0x42,0xb2,0x19,0x01,0x00,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x0d,0x09,0x01,0x0a,0x2a,0xb1,0x00,0x07,0x42,0xb3,0x16,0x06,0x01,0x0a,0x2a,0xb1,0x00,0x08,0x42,0xba,0x03,0x80,0x00,0x01,0x00,0x0b,0x2a,0xb1,0x00,0x09,0x42,0xba,0x00,0x80,0x00,0x01,0x00, +0x0b,0x2a,0xb9,0x00,0x03,0x00,0x00,0x44,0xb1,0x24,0x01,0x88,0x51,0x58,0xb0,0x40,0x88,0x58,0xb9,0x00,0x03,0x00,0x64,0x44,0xb1,0x28,0x01,0x88,0x51,0x58,0xb8,0x08,0x00,0x88,0x58,0xb9,0x00,0x03,0x00,0x00,0x44,0x59,0x1b,0xb1,0x27,0x01,0x88,0x51,0x58,0xba,0x08,0x80,0x00,0x01,0x04,0x40,0x88,0x63,0x54,0x58,0xb9,0x00,0x03,0x00, +0x00,0x44,0x59,0x59,0x59,0x59,0x59,0xb3,0x10,0x06,0x01,0x0e,0x2a,0xb8,0x01,0xff,0x85,0xb0,0x04,0x8d,0xb1,0x02,0x00,0x44,0xb3,0x05,0x64,0x06,0x00,0x44,0x44,0x00, }; read_only global String8 rd_icon_font_bytes = {rd_icon_font_bytes__data, sizeof(rd_icon_font_bytes__data)}; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d617ff7a..1cfdd85e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -153,6 +153,14 @@ RD_VocabTable: ``` x: { + //- rjf: animations + @default(1) 'hover_animations': bool, + @default(1) 'press_animations': bool, + @default(0) 'focus_animations': bool, + @default(1) 'tooltip_animations': bool, + @default(1) 'menu_animations': bool, + @default(1) 'scrolling_animations': bool, + //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") 'thread_lines': bool, @@ -170,6 +178,8 @@ RD_VocabTable: 'background_blur': bool, //- rjf: appearance settings + @default(1) @display_name('Drop Shadows') @description("Controls whether or not drop shadows are drawn.") + 'drop_shadows': bool, @default(1.f) @display_name('Rounded Corner Amount') @description("Controls the degree to which UI corners are rounded.") 'rounded_corner_amount': @range[0, 1] f32, @@ -198,14 +208,6 @@ RD_VocabTable: ``` x: { - //- rjf: animations - @default(1) 'hover_animations': bool, - @default(1) 'press_animations': bool, - @default(0) 'focus_animations': bool, - @default(1) 'tooltip_animations': bool, - @default(1) 'menu_animations': bool, - @default(1) 'scrolling_animations': bool, - //- rjf: text rasterization settings @default(1) @display_name('Smooth UI Text') @description("Controls whether or not UI text is fully anti-aliased, for a smoother appearance.") 'smooth_ui_text': bool, @@ -322,7 +324,7 @@ RD_VocabTable: { target, ``` - @row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) + @row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg) @collection_commands(add_target) x: { @@ -345,7 +347,7 @@ RD_VocabTable: { breakpoint, ``` - @row_commands(enable_cfg, remove_cfg) + @row_commands(enable_cfg, duplicate_cfg, remove_cfg) @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint) x: { @@ -367,7 +369,7 @@ RD_VocabTable: { watch_pin, ``` - @row_commands(remove_cfg) + @row_commands(duplicate_cfg, remove_cfg) @collection_commands(add_watch_pin) x: { @@ -631,6 +633,10 @@ RD_CmdTable: // | | | | {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } + //- rjf: opening user/project settings + {UserSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "user_settings" "User Settings" "Opens user settings." "" "" } + {ProjectSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "project_settings" "Project Settings" "Opens project settings." "" "" } + //- rjf: meta controls {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } @@ -706,15 +712,15 @@ RD_CmdTable: // | | | | {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } - {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } {AddAddressBreakpoint 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } - {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } - {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 0 0 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins {AddWatchPin 1 1 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } @@ -1093,6 +1099,7 @@ RD_IconTable: (Cube "*") (WindowRestore "(") (WindowMinimize ")") + (Duplicate "#") } @enum RD_IconKind: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ce3deb35..3c6c89c0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4169,6 +4169,11 @@ rd_view_ui(Rng2F32 rect) E_Eval cell_value_eval = e_value_eval_from_eval(cell->eval); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; + F32 cell_width_strictness = 0.f; + if(cell->px != 0) + { + cell_width_strictness = 1.f; + } B32 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; @@ -4256,7 +4261,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: build cell container // UI_Box *cell_box = &ui_nil_box; - UI_PrefWidth(ui_px(cell_width_px, 0.f)) + UI_PrefWidth(ui_px(cell_width_px, cell_width_strictness)) { ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); @@ -4376,6 +4381,13 @@ rd_view_ui(Rng2F32 rect) is_activated_on_single_click = 0; } + // rjf: determine query needle + String8 needle = rd_view_query_input(); + if(cell->eval.space.kind == E_SpaceKind_FileSystem) + { + needle = str8_skip_last_slash(needle); + } + // rjf: form cell build parameters RD_CellParams cell_params = {0}; { @@ -4388,7 +4400,7 @@ rd_view_ui(Rng2F32 rect) cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); cell_params.edit_string_size_out = &cell_edit_state->input_size; cell_params.expanded_out = &next_row_expanded; - cell_params.search_needle = rd_view_query_input(); + cell_params.search_needle = needle; cell_params.meta_fstrs = cell_info.expr_fstrs; cell_params.value_fstrs = cell_info.eval_fstrs; if(row_height_px > ui_top_font_size()*3.5f) @@ -6678,6 +6690,8 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, + rd_cmd_kind_info_table[RD_CmdKind_UserSettings].string, + rd_cmd_kind_info_table[RD_CmdKind_ProjectSettings].string, rd_cmd_kind_info_table[RD_CmdKind_Exit].string, }; U32 codepoints[] = @@ -6686,6 +6700,8 @@ rd_window_frame(void) 'u', 'p', 'r', + 'e', + 't', 'x', }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); @@ -8608,7 +8624,10 @@ rd_window_frame(void) //- rjf: unpack settings F32 rounded_corner_amount = rd_setting_f32_from_name(str8_lit("rounded_corner_amount")); + F32 border_softness = 1.f; B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); + B32 do_drop_shadows = + rd_setting_b32_from_name(str8_lit("drop_shadows")); Vec4F32 base_background_color = ui_color_from_name(str8_lit("background")); Vec4F32 base_border_color = ui_color_from_name(str8_lit("border")); Vec4F32 drop_shadow_color = ui_color_from_name(str8_lit("drop_shadow")); @@ -8635,7 +8654,7 @@ rd_window_frame(void) //- rjf: draw window border { - dr_rect(os_client_rect_from_window(ws->os), base_border_color, 0, 1.f, 0.5f); + dr_rect(os_client_rect_from_window(ws->os), base_border_color, 0, 1.f, border_softness*0.5f); } //- rjf: recurse & draw @@ -8695,7 +8714,7 @@ rd_window_frame(void) } // rjf: draw drop shadow - if(box->flags & UI_BoxFlag_DrawDropShadow) + if(do_drop_shadows && box->flags & UI_BoxFlag_DrawDropShadow) { Rng2F32 drop_shadow_rect = shift_2f32(pad_2f32(box->rect, 8), v2f32(4, 4)); R_Rect2DInst *inst = dr_rect(drop_shadow_rect, drop_shadow_color, 0.8f, 0, 8.f); @@ -8703,7 +8722,7 @@ rd_window_frame(void) } // rjf: blur background - if(box->flags & UI_BoxFlag_DrawBackgroundBlur && do_background_blur) + if(do_background_blur && box->flags & UI_BoxFlag_DrawBackgroundBlur) { R_PassParams_Blur *params = dr_blur(pad_2f32(box->rect, 1.f), box->blur_size*(1-box->transparency), 0); MemoryCopyArray(params->corner_radii, box_corner_radii); @@ -8733,7 +8752,7 @@ rd_window_frame(void) } // rjf: draw background - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box_background_color, 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), box_background_color, 0, 0, border_softness*1.f); MemoryCopyArray(inst->corner_radii, box_corner_radii); // rjf: hot effect extension @@ -8750,7 +8769,7 @@ rd_window_frame(void) { color.w *= t; } - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, 1.f); + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, 1.f), v4f32(0, 0, 0, 0), 0, 0, border_softness*1.f); inst->colors[Corner_00] = color; inst->colors[Corner_10] = color; MemoryCopyArray(inst->corner_radii, box_corner_radii); @@ -8952,7 +8971,7 @@ rd_window_frame(void) { Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border")); Rng2F32 b_border_rect = pad_2f32(b->rect, 1.f); - R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b_border_rect, border_color, 0, 1.f, border_softness*1.f); MemoryCopyArray(inst->corner_radii, b_corner_radii); // rjf: hover effect @@ -8973,7 +8992,7 @@ rd_window_frame(void) // rjf: debug border rendering if(b->flags & UI_BoxFlag_Debug) { - R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(b->rect, v4f32(1*box->pref_size[Axis2_X].strictness, 0, 1, 0.25f), 0, 1.f, 0); MemoryCopyArray(inst->corner_radii, b_corner_radii); } @@ -9022,7 +9041,7 @@ rd_window_frame(void) } Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); color.w *= b->focus_active_t; - R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, 1.f); + R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, border_softness*1.f); MemoryCopyArray(inst->corner_radii, b_corner_radii); } @@ -12453,11 +12472,15 @@ rd_frame(void) //- rjf: open lister case RD_CmdKind_OpenLister: { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); + RD_Cfg *tab = panel_tree.focused->selected_tab; String8 expr = push_str8f(scratch.arena, "query:commands, " "query:$%I64x, " "query:$%I64x, " "query:targets, " + "query:breakpoints, " "query:recent_files, " "query:recent_projects, " "query:processes, " @@ -12470,8 +12493,8 @@ rd_frame(void) "query:globals, " "query:thread_locals, " , - rd_regs()->view, rd_regs()->window); - rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1); + tab->id, window->id); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1, .view = tab->id); }break; //- rjf: command fast path @@ -12813,6 +12836,16 @@ rd_frame(void) } }break; + //- rjf: opening user/project settings + case RD_CmdKind_UserSettings: + { + rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:user_settings"), .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); + }break; + case RD_CmdKind_ProjectSettings: + { + rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:project_settings"), .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); + }break; + //- rjf: font sizes case RD_CmdKind_IncFontSize: { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 292a3232..e05f7d41 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1231,7 +1231,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "enabled"), .flags = RD_WatchCellFlag_Background, - .px = floor_f32(ui_top_font_size()*6.f)); + .px = floor_f32(ui_top_font_size()*5.f)); } else if(cmd_kind != RD_CmdKind_Null) { @@ -1239,7 +1239,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, - .px = floor_f32(ui_top_font_size()*4.f)); + .px = floor_f32(ui_top_font_size()*3.f)); } } } @@ -1261,7 +1261,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "active"), .edit_string = row->edit_string, - .px = floor_f32(ui_top_font_size()*6.f)); + .px = floor_f32(ui_top_font_size()*5.f)); } if(entity->kind == CTRL_EntityKind_Thread) { @@ -1274,7 +1274,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), .edit_string = row->edit_string, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, - .px = floor_f32(ui_top_font_size()*4.f)); + .px = floor_f32(ui_top_font_size()*3.f)); } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index f916f247..2b7ea1d2 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3178,8 +3178,8 @@ rd_cell(RD_CellParams *params, String8 string) // (the base line edit textual label / editor is always built, but this can be enriched // with extra widgets & metadata) // - B32 build_toggle_switch = !!(params->flags & RD_CellFlag_ToggleSwitch && !is_focus_active); - B32 build_slider = !!(params->flags & RD_CellFlag_Slider && !is_focus_active); + B32 build_toggle_switch = !!(params->flags & RD_CellFlag_ToggleSwitch) && !is_focus_active; + B32 build_slider = !!(params->flags & RD_CellFlag_Slider) && !is_focus_active; B32 build_lhs_name_desc = (params->meta_fstrs.node_count != 0 || params->description.size != 0); DR_FStrList lhs_name_fstrs = params->meta_fstrs; DR_FStrList value_name_fstrs = params->value_fstrs; @@ -3198,114 +3198,6 @@ rd_cell(RD_CellParams *params, String8 string) } } - ////////////////////////////// - //- rjf: compute editable fancy strings - // - DR_FStrList fstrs = {0}; - { - //- rjf: (not editing) - if(!is_focus_active && !is_focus_active_disabled && value_name_fstrs.total_size != 0) - { - fstrs = value_name_fstrs; - } - else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents && params->pre_edit_value.size != 0) - { - String8 display_string = params->pre_edit_value; - fstrs = rd_fstrs_from_code_string(scratch.arena, 1, 0, ui_color_from_name(str8_lit("text")), display_string); - } - else if(!is_focus_active && !is_focus_active_disabled) - { - String8 display_string = params->pre_edit_value; - if(params->pre_edit_value.size == 0) - { - display_string = ui_display_part_from_key_string(string); - } - UI_TagF("weak") - { - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, display_string); - } - } - - //- rjf: (editing) - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); - if(autocomplete_hint_string.size != 0) - { - String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); - U64 off = 0; - U64 cursor_off = params->cursor->column-1; - DR_FStrNode *prev_n = 0; - for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) - { - if(off <= cursor_off && cursor_off <= off+n->v.string.size) - { - prev_n = n; - break; - } - off += n->v.string.size; - } - { - DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *fstr = &autocomp_fstr_n->v; - fstr->string = autocomplete_append_string; - fstr->params.font = ui_top_font(); - fstr->params.color = ui_color_from_name(str8_lit("text")); - fstr->params.color.w *= 0.5f; - fstr->params.size = ui_top_font_size(); - autocomp_fstr_n->next = prev_n ? prev_n->next : 0; - if(prev_n != 0) - { - prev_n->next = autocomp_fstr_n; - } - if(prev_n == 0) - { - code_fstrs.first = code_fstrs.last = autocomp_fstr_n; - } - if(prev_n != 0 && prev_n->next == 0) - { - code_fstrs.last = autocomp_fstr_n; - } - code_fstrs.node_count += 1; - code_fstrs.total_size += autocomplete_hint_string.size; - if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) - { - String8 full_string = prev_n->v.string; - U64 chop_amt = full_string.size - (cursor_off - off); - prev_n->v.string = str8_chop(full_string, chop_amt); - code_fstrs.total_size -= chop_amt; - if(chop_amt != 0) - { - String8 post_cursor = str8_skip(full_string, cursor_off - off); - DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); - DR_FStr *post_fstr = &post_fstr_n->v; - MemoryCopyStruct(post_fstr, &prev_n->v); - post_fstr->string = post_cursor; - if(autocomp_fstr_n->next == 0) - { - code_fstrs.last = post_fstr_n; - } - post_fstr_n->next = autocomp_fstr_n->next; - autocomp_fstr_n->next = post_fstr_n; - code_fstrs.node_count += 1; - code_fstrs.total_size += post_cursor.size; - } - } - } - } - fstrs = code_fstrs; - } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); - } - } - ////////////////////////////// //- rjf: build top-level box // @@ -3378,34 +3270,6 @@ rd_cell(RD_CellParams *params, String8 string) } } - ////////////////////////////// - //- rjf: build line edit container box - // - UI_Box *edit_box = &ui_nil_box; - UI_Parent(box) if(fstrs.node_count != 0 || (!is_focus_active && !is_focus_active_disabled)) - { - UI_Size edit_box_size = ui_pct(1, 0); - if(build_lhs_name_desc) - { - edit_box_size = ui_px(dr_dim_from_fstrs(&fstrs).x + 10, 1.f); - ui_set_next_text_alignment(UI_TextAlign_Center); - } - UI_PrefWidth(edit_box_size) - edit_box = ui_build_box_from_stringf(0, "edit_box"); - } - - ////////////////////////////// - //- rjf: build scrollable container box - // - UI_Box *scrollable_box = &ui_nil_box; - if(edit_box != &ui_nil_box) - { - UI_Parent(edit_box) UI_WidthFill UI_HeightFill - { - scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); - } - } - ////////////////////////////// //- rjf: build left-hand-side name/desc box // @@ -3438,6 +3302,33 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build line edit container box + // + UI_Box *edit_box = &ui_nil_box; + UI_Parent(box) if((is_focus_active || is_focus_active_disabled) || params->pre_edit_value.size != 0 || params->value_fstrs.node_count != 0 || (params->edit_string_size_out && params->edit_string_size_out[0] != 0)) + { + UI_Size edit_box_size = ui_pct(1, 0); + if(build_lhs_name_desc) + { + edit_box_size = ui_children_sum(1); + } + UI_PrefWidth(edit_box_size) + edit_box = ui_build_box_from_stringf(0, "edit_box"); + } + + ////////////////////////////// + //- rjf: build scrollable container box + // + UI_Box *scrollable_box = &ui_nil_box; + if(edit_box != &ui_nil_box) + { + UI_Parent(edit_box) UI_PrefWidth(ui_children_sum(0)) + { + scrollable_box = ui_build_box_from_stringf(is_focus_active*(UI_BoxFlag_AllowOverflowX), "scroll_box_%p", params->edit_buffer); + } + } + ////////////////////////////// //- rjf: build toggle-switch // @@ -3499,7 +3390,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) UI_Row UI_Padding(ui_px(padding_px, 1.f)) - UI_PrefWidth(ui_pct(0.5f, 0.f)) + UI_PrefWidth(ui_pct(0.5f - 0.2f*(!!build_lhs_name_desc), 0.f)) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) { @@ -3685,6 +3576,114 @@ rd_cell(RD_CellParams *params, String8 string) scratch_end(scratch); } + ////////////////////////////// + //- rjf: compute editable fancy strings + // + DR_FStrList fstrs = {0}; + { + //- rjf: (not editing) + if(!is_focus_active && !is_focus_active_disabled && value_name_fstrs.total_size != 0) + { + fstrs = value_name_fstrs; + } + else if(!is_focus_active && !is_focus_active_disabled && params->flags & RD_CellFlag_CodeContents && params->pre_edit_value.size != 0) + { + String8 display_string = params->pre_edit_value; + fstrs = rd_fstrs_from_code_string(scratch.arena, 1, 0, ui_color_from_name(str8_lit("text")), display_string); + } + else if(!is_focus_active && !is_focus_active_disabled) + { + String8 display_string = params->pre_edit_value; + if(params->pre_edit_value.size == 0) + { + display_string = ui_display_part_from_key_string(string); + } + UI_TagF("weak") + { + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, display_string); + } + } + + //- rjf: (editing) + else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); + if(autocomplete_hint_string.size != 0) + { + String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); + U64 off = 0; + U64 cursor_off = params->cursor->column-1; + DR_FStrNode *prev_n = 0; + for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) + { + if(off <= cursor_off && cursor_off <= off+n->v.string.size) + { + prev_n = n; + break; + } + off += n->v.string.size; + } + { + DR_FStrNode *autocomp_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *fstr = &autocomp_fstr_n->v; + fstr->string = autocomplete_append_string; + fstr->params.font = ui_top_font(); + fstr->params.color = ui_color_from_name(str8_lit("text")); + fstr->params.color.w *= 0.5f; + fstr->params.size = ui_top_font_size(); + autocomp_fstr_n->next = prev_n ? prev_n->next : 0; + if(prev_n != 0) + { + prev_n->next = autocomp_fstr_n; + } + if(prev_n == 0) + { + code_fstrs.first = code_fstrs.last = autocomp_fstr_n; + } + if(prev_n != 0 && prev_n->next == 0) + { + code_fstrs.last = autocomp_fstr_n; + } + code_fstrs.node_count += 1; + code_fstrs.total_size += autocomplete_hint_string.size; + if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) + { + String8 full_string = prev_n->v.string; + U64 chop_amt = full_string.size - (cursor_off - off); + prev_n->v.string = str8_chop(full_string, chop_amt); + code_fstrs.total_size -= chop_amt; + if(chop_amt != 0) + { + String8 post_cursor = str8_skip(full_string, cursor_off - off); + DR_FStrNode *post_fstr_n = push_array(scratch.arena, DR_FStrNode, 1); + DR_FStr *post_fstr = &post_fstr_n->v; + MemoryCopyStruct(post_fstr, &prev_n->v); + post_fstr->string = post_cursor; + if(autocomp_fstr_n->next == 0) + { + code_fstrs.last = post_fstr_n; + } + post_fstr_n->next = autocomp_fstr_n->next; + autocomp_fstr_n->next = post_fstr_n; + code_fstrs.node_count += 1; + code_fstrs.total_size += post_cursor.size; + } + } + } + } + fstrs = code_fstrs; + } + else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); + } + } + ////////////////////////////// //- rjf: build scrolled contents // @@ -3703,9 +3702,9 @@ rd_cell(RD_CellParams *params, String8 string) } if(is_focus_active) { - ui_set_next_pref_width(ui_text_dim(1, 1)); ui_set_next_flags(UI_BoxFlag_DisableTextTrunc); } + ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*0.5f, 0)); UI_Box *text_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "###text_box"); ui_box_equip_display_fstrs(text_box, &fstrs); ui_box_equip_fuzzy_match_ranges(text_box, &fuzzy_matches); @@ -3749,6 +3748,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: focus cursor // + if(scrollable_box != &ui_nil_box) { F32 visible_dim_px = dim_2f32(box->rect).x - expander_size_px - ui_top_font_size()*params->depth; if(visible_dim_px > 0) diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 33edb2e6..f2546163 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -1179,4 +1179,7 @@ internal F32 ui_top_px_height(void); //- rjf: context menu #define UI_CtxMenu(key) DeferLoopChecked(ui_begin_ctx_menu(key), ui_end_ctx_menu()) +//- rjf: debug +#define UI_Debug UI_FlagsAdd(UI_BoxFlag_Debug) + #endif // UI_H From 42ee4b9776144d10d09b761c6d383c0bdae9e608 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 15:36:45 -0700 Subject: [PATCH 427/755] lister -> palette --- src/raddbg/generated/raddbg.meta.c | 22 +++++++++++----------- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 15 +++++++-------- src/raddbg/raddbg_core.c | 10 ++++++---- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2a16d8e9..613549e4 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -144,7 +144,7 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("set_entity_name"), str8_lit_comp(""), str8_lit_comp("Set Entity Name"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("attach"), str8_lit_comp(""), str8_lit_comp("Attach"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("exit"), str8_lit_comp(""), str8_lit_comp("Exit"), str8_lit_comp(""), RD_IconKind_X}, -{str8_lit_comp("open_lister"), str8_lit_comp(""), str8_lit_comp("Open Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_palette"), str8_lit_comp(""), str8_lit_comp("Open Palette"), str8_lit_comp(""), RD_IconKind_List}, {str8_lit_comp("run_command"), str8_lit_comp(""), str8_lit_comp("Run Command"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp("OS Event"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Thread}, @@ -315,10 +315,10 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("pick_file"), str8_lit_comp(""), str8_lit_comp("Pick File"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("pick_folder"), str8_lit_comp(""), str8_lit_comp("Pick Folder"), str8_lit_comp(""), RD_IconKind_FolderOpenFilled}, {str8_lit_comp("pick_file_or_folder"), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("push_lister"), str8_lit_comp(""), str8_lit_comp("Push Lister"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("complete_lister"), str8_lit_comp(""), str8_lit_comp("Complete Lister"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("cancel_lister"), str8_lit_comp(""), str8_lit_comp("Cancel Lister"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("update_lister"), str8_lit_comp(""), str8_lit_comp("Update Lister"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("push_query"), str8_lit_comp(""), str8_lit_comp("Push Query"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("complete_query"), str8_lit_comp(""), str8_lit_comp("Complete Query"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("cancel_query"), str8_lit_comp(""), str8_lit_comp("Cancel Query"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("update_query"), str8_lit_comp(""), str8_lit_comp("Update Query"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, }; @@ -430,7 +430,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_lister"), str8_lit_comp("Opens the lister."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, @@ -601,10 +601,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_lister"), str8_lit_comp("Pushes a new lister onto the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_lister"), str8_lit_comp("Completes a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_lister"), str8_lit_comp("Cancels a lister, and pops it off the lister stack."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("update_lister"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_query"), str8_lit_comp("Opens a new temporary query interface."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_query"), str8_lit_comp("Completes and closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_query"), str8_lit_comp("Closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("update_query"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; @@ -715,7 +715,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[107] = {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, {str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, -{str8_lit_comp("open_lister"), {OS_Key_F1, 0 }}, +{str8_lit_comp("open_palette"), {OS_Key_F1, 0 }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("toggle_dev_menu"), {OS_Key_D, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 0a16873f..980bb613 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -89,7 +89,7 @@ RD_CmdKind_SetEntityColor, RD_CmdKind_SetEntityName, RD_CmdKind_Attach, RD_CmdKind_Exit, -RD_CmdKind_OpenLister, +RD_CmdKind_OpenPalette, RD_CmdKind_RunCommand, RD_CmdKind_OSEvent, RD_CmdKind_SelectThread, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1cfdd85e..acae8241 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -532,8 +532,8 @@ RD_CmdTable: // | | | | //- rjf: exiting {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } - //- rjf: top-level lister - {OpenLister 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_lister" "Open Lister" "Opens the lister." "help,cmd" "" } + //- rjf: palette + {OpenPalette 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 List "open_palette" "Open Palette" "Opens the palette." "help,cmd,lister" "" } //- rjf: command runner {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } @@ -778,10 +778,10 @@ RD_CmdTable: // | | | | {PickFileOrFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack - {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_lister" "Push Lister" "Pushes a new lister onto the lister stack." "" "" } - {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_lister" "Complete Lister" "Completes a lister, and pops it off the lister stack." "" "" } - {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_lister" "Cancel Lister" "Cancels a lister, and pops it off the lister stack." "" "" } - {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_lister" "Update Lister" "Updates a query input." "" "" } + {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_query" "Push Query" "Opens a new temporary query interface." "" "" } + {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_query" "Complete Query" "Completes and closes a query." "" "" } + {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_query" "Cancel Query" "Closes a query." "" "" } + {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_query" "Update Query" "Updates a query input." "" "" } //- rjf: developer commands {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } @@ -979,8 +979,7 @@ RD_DefaultBindingTable: { "attach" F6 0 shift 0 } //- rjf: command lister - // { "run_command" F1 0 0 0 } - { "open_lister" F1 0 0 0 } + { "open_palette" F1 0 0 0 } //- rjf: developer commands { "log_marker" M ctrl shift alt } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3c6c89c0..eea6e0d9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2546,7 +2546,7 @@ rd_view_ui(Rng2F32 rect) UI_Padding(ui_pct(1, 0)) { ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string); ui_labelf("to search for commands and options"); } } @@ -6690,6 +6690,7 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, rd_cmd_kind_info_table[RD_CmdKind_UserSettings].string, rd_cmd_kind_info_table[RD_CmdKind_ProjectSettings].string, rd_cmd_kind_info_table[RD_CmdKind_Exit].string, @@ -6700,6 +6701,7 @@ rd_window_frame(void) 'u', 'p', 'r', + 'n', 'e', 't', 'x', @@ -6906,7 +6908,7 @@ rd_window_frame(void) ui_labelf("Search for commands and options by pressing "); UI_Flags(UI_BoxFlag_DrawBorder) UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenLister].string); + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string); } ui_spacer(ui_em(1.f, 1.f)); UI_TagF("pop") @@ -12469,8 +12471,8 @@ rd_frame(void) #endif }break; - //- rjf: open lister - case RD_CmdKind_OpenLister: + //- rjf: open palette + case RD_CmdKind_OpenPalette: { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); From 5bfb5b578a87f55ae0ebb99c3e2970c9f9ac4c71 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 15:47:37 -0700 Subject: [PATCH 428/755] do not do mixed eval/expr booleans in watch groups --- src/raddbg/raddbg_views.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index e05f7d41..2ef83523 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1328,7 +1328,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: @watch_row_build_cells meta-evaluation booleans // - else if(e_type_kind_from_key(e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Bool && + else if(info.group_cfg_child == &rd_nil_cfg && + e_type_kind_from_key(e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Bool && (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg || row->eval.space.kind == RD_EvalSpaceKind_MetaCmd || row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) From fc728ea4e965b2af317b11e649c592d00fcff4eb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 16:13:29 -0700 Subject: [PATCH 429/755] description coverage, char visualization disabling --- .../eval_visualization_core.c | 10 ++++++- .../eval_visualization_core.h | 3 +- src/raddbg/generated/raddbg.meta.c | 15 +++++----- src/raddbg/raddbg.mdesk | 29 ++++++++++++------- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_eval.c | 14 +++++++-- 6 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index b11f9183..c2ed317f 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1378,7 +1378,11 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval e case E_TypeKind_UChar32: { B32 type_is_unsigned = (E_TypeKind_UChar8 <= type_kind && type_kind <= E_TypeKind_UChar32); - String8 char_str = ev_string_from_ascii_value(arena, eval.value.s64); + String8 char_str = {0}; + if(!(params->flags & EV_StringFlag_DisableChars)) + { + char_str = ev_string_from_ascii_value(arena, eval.value.s64); + } if(char_str.size != 0) { if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) @@ -1621,6 +1625,10 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { lens_params.flags |= EV_StringFlag_DisableStrings; } + else if(str8_match(type->name, str8_lit("no_char"), 0)) + { + lens_params.flags |= EV_StringFlag_DisableChars; + } else if(str8_match(type->name, str8_lit("no_addr"), 0)) { lens_params.flags |= EV_StringFlag_DisableAddresses; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index f8d4c626..54d7cd36 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -235,7 +235,8 @@ enum EV_StringFlag_PrettyNames = (1<<1), EV_StringFlag_DisableAddresses = (1<<2), EV_StringFlag_DisableStrings = (1<<3), - EV_StringFlag_DisableStringQuotes = (1<<4), + EV_StringFlag_DisableChars = (1<<4), + EV_StringFlag_DisableStringQuotes = (1<<5), }; typedef struct EV_StringParams EV_StringParams; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 613549e4..81e97f52 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -328,12 +328,12 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n 'lang':lang,\n 'size':code_string,\n @default(1) 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, @@ -609,7 +609,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[107] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -716,6 +716,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[107] = {str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, {str8_lit_comp("open_palette"), {OS_Key_F1, 0 }}, +{str8_lit_comp("open_palette"), {OS_Key_P, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("toggle_dev_menu"), {OS_Key_D, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index acae8241..6f7e2167 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -235,7 +235,8 @@ RD_VocabTable: ``` x: { - @default(11) @display_name('Tab Font Size') 'font_size': @range[6, 72] u64, + @default(11) @display_name('Tab Font Size') @description("Controls the tab's font size.") + 'font_size': @range[6, 72] u64, } ``` } @@ -246,7 +247,8 @@ RD_VocabTable: ``` @inherit(tab) x: { - @default(3.f) @display_name('Tab Row Height') 'row_height': @range[1.75f, 5.f] f32, + @default(3.f) @display_name('Tab Row Height') @description("Controls the tab's row height, in multiples of the font size.") + 'row_height': @range[1.75f, 5.f] f32, } ``` } @@ -255,9 +257,10 @@ RD_VocabTable: ``` @inherit(tab) x: { - 'lang':lang, - 'size':code_string, - @default(1) 'show_line_numbers':bool, + @description("The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.") + 'lang': lang, + @default(1) @description("Controls whether or not line numbers are shown.") + 'show_line_numbers':bool, @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, } @@ -279,7 +282,8 @@ RD_VocabTable: 'show_source_lines': bool, @default(1) @description("Controls whether or not disassembly text is decorated with symbol names.") 'show_symbol_names': bool, - @default(1) 'show_line_numbers': bool, + @default(1) @description("Controls whether or not line numbers are shown.") + 'show_line_numbers': bool, } ``` } @@ -288,9 +292,12 @@ RD_VocabTable: ``` @inherit(tab) x: { - 'size': code_string, - @default(16) 'num_columns': @range[1, 64] u64, - @default(1) 'bytes_per_cell': @range[1, 8] u64, + @description("The number of bytes of the viewed memory range.") + 'size': code_string, + @default(16) @description("The number of columns to build before building new rows.") + 'num_columns': @range[1, 64] u64, + @default(1) @description("The number of bytes that each cell should represent.") + 'bytes_per_cell': @range[1, 8] u64, } ``` } @@ -301,7 +308,8 @@ RD_VocabTable: { @order(0) 'w': u64, @order(1) 'h': u64, - 'fmt': tex2dformat, + @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") + 'fmt': tex2dformat, } ``` } @@ -980,6 +988,7 @@ RD_DefaultBindingTable: //- rjf: command lister { "open_palette" F1 0 0 0 } + { "open_palette" P ctrl shift 0 } //- rjf: developer commands { "log_marker" M ctrl shift alt } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index eea6e0d9..9245ca2a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12303,6 +12303,7 @@ rd_frame(void) {str8_lit("hex"), 1, 1, 0, 0, 0, {0}}, {str8_lit("digits"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_string"), 1, 1, 0, 0, 0, {0}}, + {str8_lit("no_char"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, {str8_lit("sequence"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(sequence), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(sequence)}}, {str8_lit("only"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only)}}, diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index c27c17b2..9c6113a1 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -533,8 +533,18 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) { if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) { - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, child->string); - if(matches.count == matches.needle_part_count) + String8 display_name = md_tag_from_string(child, str8_lit("display_name"), 0)->first->string; + if(display_name.size == 0) + { + display_name = rd_display_from_code_name(child->string); + } + String8 desc = md_tag_from_string(child, str8_lit("description"), 0)->first->string; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, child->string); + FuzzyMatchRangeList display_name_matches = fuzzy_match_find(scratch.arena, filter, display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, desc); + if(name_matches.count == name_matches.needle_part_count || + display_name_matches.count == display_name_matches.needle_part_count || + desc_matches.count == desc_matches.needle_part_count) { ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); n->n = child; From 4cbb03fbfe8e61050c131c8a0f1f7bf22dfcf79d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 16:40:45 -0700 Subject: [PATCH 430/755] ctrl + scroll -> adjust global font size by default, ctrl + shift + scroll -> adjust text view font size --- src/os/gfx/os_gfx.c | 18 ++++++++++++++++++ src/os/gfx/os_gfx.h | 1 + src/raddbg/raddbg_core.c | 11 +++++++++-- src/raddbg/raddbg_eval.c | 15 ++++++++++++++- src/raddbg/raddbg_views.c | 2 +- src/raddbg/raddbg_widgets.c | 34 ++++++++++++++++++++++++++-------- src/raddbg/raddbg_widgets.h | 22 ++++++++++++++-------- src/ui/ui_core.c | 8 ++++---- 8 files changed, 87 insertions(+), 24 deletions(-) diff --git a/src/os/gfx/os_gfx.c b/src/os/gfx/os_gfx.c index 30d09d74..c5800b57 100644 --- a/src/os/gfx/os_gfx.c +++ b/src/os/gfx/os_gfx.c @@ -45,6 +45,24 @@ os_string_list_from_modifiers(Arena *arena, OS_Modifiers modifiers) return result; } +internal String8 +os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key) +{ + String8 result = {0}; + if(key != OS_Key_Null) + { + Temp scratch = scratch_begin(&arena, 1); + String8List mods = os_string_list_from_modifiers(scratch.arena, modifiers); + String8 key_string = os_g_key_display_string_table[key]; + str8_list_push(scratch.arena, &mods, key_string); + StringJoin join = {0}; + join.sep = str8_lit(" + "); + result = str8_list_join(arena, &mods, &join); + scratch_end(scratch); + } + return result; +} + internal U32 os_codepoint_from_modifiers_and_key(OS_Modifiers modifiers, OS_Key key) { diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index 9c50c5d3..edb4217b 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -112,6 +112,7 @@ internal B32 frame(void); internal String8 os_string_from_event_kind(OS_EventKind kind); internal String8List os_string_list_from_modifiers(Arena *arena, OS_Modifiers flags); +internal String8 os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key); internal U32 os_codepoint_from_modifiers_and_key(OS_Modifiers flags, OS_Key key); internal void os_eat_event(OS_EventList *events, OS_Event *event); internal B32 os_key_press(OS_EventList *events, OS_Handle window, OS_Modifiers modifiers, OS_Key key); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9245ca2a..26bed2db 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2546,7 +2546,7 @@ rd_view_ui(Rng2F32 rect) UI_Padding(ui_pct(1, 0)) { ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero()); ui_labelf("to search for commands and options"); } } @@ -4464,6 +4464,13 @@ rd_view_ui(Rng2F32 rect) cell_params.flags |= RD_CellFlag_Slider; cell_params.slider_value_out = &next_cell_slider_value; } + + // rjf: apply bindings + if(cell->px == 0 && cell->eval.space.kind == RD_EvalSpaceKind_MetaCmd) + { + cell_params.flags |= RD_CellFlag_Bindings; + cell_params.bindings_name = rd_cmd_name_from_eval(cell->eval); + } } // rjf: build @@ -6908,7 +6915,7 @@ rd_window_frame(void) ui_labelf("Search for commands and options by pressing "); UI_Flags(UI_BoxFlag_DrawBorder) UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string); + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero()); } ui_spacer(ui_em(1.f, 1.f)); UI_TagF("pop") diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 9c6113a1..0d796539 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -38,9 +38,22 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, description); FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, display_name); FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, filter, search_tags); + B32 binding_matches_good = 0; + RD_KeyMapNodePtrList bindings = rd_key_map_node_ptr_list_from_name(scratch.arena, code_name); + for(RD_KeyMapNodePtr *n = bindings.first; n != 0; n = n->next) + { + String8 binding_text = os_string_from_modifiers_key(scratch.arena, n->v->binding.modifiers, n->v->binding.key); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, binding_text); + if(matches.count == matches.needle_part_count) + { + binding_matches_good = 1; + break; + } + } if(name_matches.count == name_matches.needle_part_count || desc_matches.count == desc_matches.needle_part_count || - tags_matches.count == tags_matches.needle_part_count) + tags_matches.count == tags_matches.needle_part_count || + binding_matches_good) { str8_list_push(scratch.arena, &cmd_names, code_name); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2ef83523..6f0b6bd8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -775,7 +775,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { for(UI_Event *evt = 0; ui_next_event(&evt);) { - if(evt->kind == UI_EventKind_Scroll && evt->modifiers & OS_Modifier_Ctrl) + if(evt->kind == UI_EventKind_Scroll && evt->modifiers & OS_Modifier_Ctrl && evt->modifiers & OS_Modifier_Shift) { ui_eat_event(evt); if(evt->delta_2f32.y < 0) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2b7ea1d2..90e79d52 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -699,7 +699,7 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t //~ rjf: UI Widgets: Fancy Buttons internal void -rd_cmd_binding_buttons(String8 name) +rd_cmd_binding_buttons(String8 name, String8 filter) { Temp scratch = scratch_begin(0, 0); RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name); @@ -731,12 +731,7 @@ rd_cmd_binding_buttons(String8 name) { if(binding.key != OS_Key_Null) { - String8List mods = os_string_list_from_modifiers(scratch.arena, binding.modifiers); - String8 key = os_g_key_display_string_table[binding.key]; - str8_list_push(scratch.arena, &mods, key); - StringJoin join = {0}; - join.sep = str8_lit(" + "); - keybinding_str = str8_list_join(scratch.arena, &mods, &join); + keybinding_str = os_string_from_modifiers_key(scratch.arena, binding.modifiers, binding.key); } else { @@ -744,6 +739,13 @@ rd_cmd_binding_buttons(String8 name) } } + //- rjf: compute fuzzy matches + FuzzyMatchRangeList matches = {0}; + if(filter.size != 0) + { + matches = fuzzy_match_find(scratch.arena, filter, keybinding_str); + } + //- rjf: build box ui_set_next_tag(has_conflicts ? str8_lit("bad_pop") : rebinding_active_for_this_binding ? str8_lit("pop") : str8_zero()); ui_set_next_text_alignment(UI_TextAlign_Center); @@ -756,6 +758,7 @@ rd_cmd_binding_buttons(String8 name) UI_BoxFlag_DrawBorder| UI_BoxFlag_DrawBackground, "%S###bind_btn_%S_%x_%x", keybinding_str, name, binding.key, binding.modifiers); + ui_box_equip_fuzzy_match_ranges(box, &matches); //- rjf: interaction UI_Signal sig = ui_signal_from_box(box); @@ -895,7 +898,7 @@ rd_cmd_spec_button(String8 name) UI_TagF("weak") UI_FastpathCodepoint(0) { - rd_cmd_binding_buttons(name); + rd_cmd_binding_buttons(name, str8_zero()); } } } @@ -3180,6 +3183,7 @@ rd_cell(RD_CellParams *params, String8 string) // B32 build_toggle_switch = !!(params->flags & RD_CellFlag_ToggleSwitch) && !is_focus_active; B32 build_slider = !!(params->flags & RD_CellFlag_Slider) && !is_focus_active; + B32 build_bindings = !!(params->flags & RD_CellFlag_Bindings) && !is_focus_active; B32 build_lhs_name_desc = (params->meta_fstrs.node_count != 0 || params->description.size != 0); DR_FStrList lhs_name_fstrs = params->meta_fstrs; DR_FStrList value_name_fstrs = params->value_fstrs; @@ -3438,6 +3442,20 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build bindings + // + if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main) + { + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_Padding(ui_em(1.f, 1.f)) UI_HeightFill + { + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_Padding(ui_em(1.f, 1.f)) + { + rd_cmd_binding_buttons(params->bindings_name, params->search_needle); + } + } + } + ////////////////////////////// //- rjf: do non-textual edits (delete, copy, cut) // diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 293f115e..d0622470 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -21,18 +21,21 @@ enum //- rjf: slider extension RD_CellFlag_Slider = (1<<4), + //- rjf: bindings extension + RD_CellFlag_Bindings = (1<<5), + //- rjf: behavior - RD_CellFlag_DisableEdit = (1<<5), - RD_CellFlag_KeyboardClickable = (1<<6), - RD_CellFlag_SingleClickActivate = (1<<7), + RD_CellFlag_DisableEdit = (1<<6), + RD_CellFlag_KeyboardClickable = (1<<7), + RD_CellFlag_SingleClickActivate = (1<<8), //- rjf: contents description - RD_CellFlag_CodeContents = (1<<8), + RD_CellFlag_CodeContents = (1<<9), //- rjf: appearance - RD_CellFlag_Border = (1<<9), - RD_CellFlag_NoBackground = (1<<10), - RD_CellFlag_Button = (1<<11), + RD_CellFlag_Border = (1<<10), + RD_CellFlag_NoBackground = (1<<11), + RD_CellFlag_Button = (1<<12), }; typedef struct RD_CellParams RD_CellParams; @@ -56,6 +59,9 @@ struct RD_CellParams //- rjf: slider info r/w info F32 *slider_value_out; + //- rjf: bindings name w info + String8 bindings_name; + //- rjf: text editing r/w info TxtPt *cursor; TxtPt *mark; @@ -134,7 +140,7 @@ internal void rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U6 //////////////////////////////// //~ rjf: UI Widgets: Fancy Buttons -internal void rd_cmd_binding_buttons(String8 name); +internal void rd_cmd_binding_buttons(String8 name, String8 filter); internal UI_Signal rd_menu_bar_button(String8 string); internal UI_Signal rd_cmd_spec_button(String8 name); internal void rd_cmd_list_menu_buttons(U64 count, String8 *cmd_names, U32 *fastpath_codepoints); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 1f4f5df3..53e68765 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -557,11 +557,11 @@ ui_next_event(UI_Event **ev) { good = 0; } - if(!(perms & UI_PermissionFlag_ScrollX) && (n->v.kind == UI_EventKind_Scroll) && (n->v.delta_2f32.x != 0 || n->v.modifiers & OS_Modifier_Shift)) + if(!(perms & UI_PermissionFlag_ScrollX) && (n->v.kind == UI_EventKind_Scroll) && (n->v.delta_2f32.x != 0 || n->v.modifiers == OS_Modifier_Shift)) { good = 0; } - if(!(perms & UI_PermissionFlag_ScrollY) && (n->v.kind == UI_EventKind_Scroll) && n->v.delta_2f32.y != 0 && !(n->v.modifiers & OS_Modifier_Shift)) + if(!(perms & UI_PermissionFlag_ScrollY) && (n->v.kind == UI_EventKind_Scroll) && n->v.delta_2f32.y != 0 && n->v.modifiers == 0) { good = 0; } @@ -2878,7 +2878,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: scrolling if(box->flags & UI_BoxFlag_Scroll && evt->kind == UI_EventKind_Scroll && - evt->modifiers != OS_Modifier_Ctrl && + (evt->modifiers == 0 || evt->modifiers == OS_Modifier_Shift) && evt_mouse_in_bounds) { Vec2F32 delta = evt->delta_2f32; @@ -2899,7 +2899,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: view scrolling if(box->flags & UI_BoxFlag_ViewScroll && box->first_touched_build_index != box->last_touched_build_index && evt->kind == UI_EventKind_Scroll && - evt->modifiers != OS_Modifier_Ctrl && + (evt->modifiers == 0 || evt->modifiers == OS_Modifier_Shift) && evt_mouse_in_bounds) { Vec2F32 delta = evt->delta_2f32; From afed771adb10319c2f14bc45bc438a193983ff98 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 16:43:17 -0700 Subject: [PATCH 431/755] adjust cmd binding editor buttons style --- src/raddbg/raddbg_widgets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 90e79d52..a13ab216 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -705,7 +705,7 @@ rd_cmd_binding_buttons(String8 name, String8 filter) RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name); //- rjf: build buttons for each binding - for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next) + UI_CornerRadius(ui_top_font_size()*0.5f) for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next) { RD_Binding binding = n->v->binding; B32 rebinding_active_for_this_binding = (rd_state->bind_change_active && @@ -820,7 +820,7 @@ rd_cmd_binding_buttons(String8 name, String8 filter) B32 adding_new_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && rd_state->bind_change_binding_id == 0); - RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") + RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") UI_CornerRadius(ui_top_font_size()*0.5f) { ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); From a9dcc7a08ea5335a3f77e4dd8ddbb46beef6aa36 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 17:05:28 -0700 Subject: [PATCH 432/755] more tweaks --- src/raddbg/raddbg_core.c | 2 +- src/raddbg/raddbg_widgets.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 26bed2db..c897b9b8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7065,7 +7065,7 @@ rd_window_frame(void) //- rjf: center column if(dim_2f32(top_bar_rect).x > ui_top_font_size()*60) UI_PrefWidth(ui_children_sum(1.f)) UI_Row - UI_PrefWidth(ui_em(2.5f, 1)) + UI_PrefWidth(ui_px(dim_2f32(top_bar_rect).y, 1)) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.85f) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index a13ab216..27ca3d96 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -824,7 +824,7 @@ rd_cmd_binding_buttons(String8 name, String8 filter) { ui_set_next_text_alignment(UI_TextAlign_Center); ui_set_next_group_key(ui_key_zero()); - ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.f, 1)); + ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.5f, 1)); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| UI_BoxFlag_Clickable| UI_BoxFlag_DrawActiveEffects| @@ -3447,7 +3447,7 @@ rd_cell(RD_CellParams *params, String8 string) // if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main) { - UI_PrefWidth(ui_children_sum(1)) UI_Column UI_Padding(ui_em(1.f, 1.f)) UI_HeightFill + UI_PrefWidth(ui_children_sum(1)) UI_Column UI_Padding(ui_px(ui_top_px_height()*0.2f, 1.f)) UI_HeightFill { UI_PrefWidth(ui_children_sum(1)) UI_Row UI_Padding(ui_em(1.f, 1.f)) { From 0ce85082ec451dea63095f1ba4bac9e11bdcca9d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 22 Apr 2025 17:16:29 -0700 Subject: [PATCH 433/755] include font in user settings schema --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 ++++ src/raddbg/raddbg_core.c | 18 +----------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 81e97f52..720907f7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -325,7 +325,7 @@ RD_VocabInfo rd_vocab_info_table[315] = RD_NameSchemaInfo rd_name_schema_info_table[21] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6f7e2167..6c9bbb40 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -161,6 +161,10 @@ RD_VocabTable: @default(1) 'menu_animations': bool, @default(1) 'scrolling_animations': bool, + //- rjf: fonts + 'main_font': string, + 'code_font': string, + //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") 'thread_lines': bool, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c897b9b8..a3e0a0d4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10257,23 +10257,7 @@ rd_font_from_slot(RD_FontSlot slot) } // rjf: determine font name - String8 font_name = {0}; - if(key.size != 0) - { - RD_Cfg *seed_cfg = &rd_nil_cfg; - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->view); } - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->panel); } - if(seed_cfg == &rd_nil_cfg) { seed_cfg = rd_cfg_from_id(rd_regs()->window); } - for(RD_Cfg *cfg = seed_cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) - { - RD_Cfg *font_root = rd_cfg_child_from_string(cfg, key); - if(font_root != &rd_nil_cfg) - { - font_name = font_root->first->string; - break; - } - } - } + String8 font_name = rd_setting_from_name(key); // rjf: map name -> tag FNT_Tag result = {0}; From 264dbc81995876118e4c0953d577a4d68cff3dde Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 11:49:44 -0700 Subject: [PATCH 434/755] deduplication from evaluation ctxs - just have base ctx with deduplicated info, then separate type-state, ir-ctx, and interpretation-ctx --- src/ctrl/ctrl_core.c | 69 +-- src/ctrl/ctrl_core.h | 3 +- src/dbg_engine/dbg_engine_core.c | 129 ----- src/dbg_engine/dbg_engine_core.h | 4 - src/eval/eval_bundles.c | 41 +- src/eval/eval_bundles.h | 1 - src/eval/eval_core.c | 82 ++++ src/eval/eval_core.h | 93 +++- src/eval/eval_ir.c | 46 +- src/eval/eval_ir.h | 41 -- src/eval/eval_parse.c | 48 +- src/eval/eval_parse.h | 21 +- src/eval/eval_types.c | 111 +---- src/eval/eval_types.h | 54 +-- .../eval_visualization_core.c | 18 +- src/raddbg/raddbg_core.c | 448 +++++++++--------- src/raddbg/raddbg_eval.c | 10 +- src/raddbg/raddbg_views.c | 24 +- 18 files changed, 546 insertions(+), 697 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 117d86de..4db53c17 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4704,14 +4704,18 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) CTRL_EvalScope *scope = push_array(arena, CTRL_EvalScope, 1); scope->di_scope = di_scope_open(); - // rjf: unpack thread + ////////////////////////////// + //- rjf: unpack thread + // Arch arch = thread->arch; U64 thread_rip_vaddr = dmn_rip_from_thread(thread->handle.dmn_handle); CTRL_Entity *process = ctrl_process_from_entity(thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - // rjf: gather evaluation modules + ////////////////////////////// + //- rjf: gather evaluation modules + // U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; @@ -4751,35 +4755,40 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } } - // rjf: build eval type context + ////////////////////////////// + //- rjf: build base evaluation context + // { - E_TypeCtx *ctx = &scope->type_ctx; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_type_ctx(&scope->type_ctx); - - // rjf: build eval parse context - ProfScope("build eval parse context") - { - E_ParseCtx *ctx = &scope->parse_ctx; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_parse_ctx(&scope->parse_ctx); - - // rjf: build eval IR context - { - E_IRCtx *ctx = &scope->ir_ctx; - ctx->thread_ip_vaddr = thread_rip_vaddr; - ctx->thread_ip_voff = thread_rip_voff; + E_BaseCtx *ctx = &scope->base_ctx; + + //- rjf: fill instruction pointer info + ctx->thread_ip_vaddr = thread_rip_vaddr; + ctx->thread_ip_voff = thread_rip_voff; + ctx->thread_arch = thread->arch; ctx->thread_reg_space = e_space_make(CTRL_EvalSpaceKind_Entity); ctx->thread_reg_space.u64_0 = (U64)thread; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; + + //- rjf: fill modules + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + + //- rjf: fill space hooks + ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; + ctx->space_read = ctrl_eval_space_read; + } + e_select_base_ctx(&scope->base_ctx); + + ////////////////////////////// + //- rjf: begin type evaluation + // + e_type_eval_begin(); + + ////////////////////////////// + //- rjf: build IR evaluation context + // + { + E_IRCtx *ctx = &scope->ir_ctx; ctx->regs_map = ctrl_string2reg_from_arch(arch); ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); @@ -4791,7 +4800,9 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_ir_ctx(&scope->ir_ctx); - // rjf: build eval interpretation context + ////////////////////////////// + //- rjf: build eval interpretation context + // { E_InterpretCtx *ctx = &scope->interpret_ctx; ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 85d80ac3..f5127226 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -658,8 +658,7 @@ typedef struct CTRL_EvalScope CTRL_EvalScope; struct CTRL_EvalScope { DI_Scope *di_scope; - E_TypeCtx type_ctx; - E_ParseCtx parse_ctx; + E_BaseCtx base_ctx; E_IRCtx ir_ctx; E_InterpretCtx interpret_ctx; }; diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 2915cbc1..05263a35 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -613,135 +613,6 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) //////////////////////////////// //~ rjf: Debug Info Lookups -//- rjf: symbol lookups - -internal String8 -d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated) -{ - String8 result = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - DI_Scope *scope = di_scope_open(); - RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0); - - //- rjf: try scopes - if(result.size == 0) - { - // rjf: voff -> scope - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - - // rjf: scope -> # of max possible inline depth - U64 inline_site_count = 0; - for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) - { - RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); - s_idx_next = s->parent_scope_idx; - if(s->inline_site_idx != 0) - { - inline_site_count += 1; - } - else - { - break; - } - } - - // rjf: depth in [1, max]? -> form name from inline site - if(0 < depth && depth <= inline_site_count) - { - RDI_InlineSite *inline_site = 0; - U64 s_inline_depth = inline_site_count; - for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) - { - RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); - s_idx_next = s->parent_scope_idx; - if(s_inline_depth == depth) - { - inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); - break; - } - s_inline_depth -= 1; - if(s_inline_depth == 0) - { - break; - } - } - if(inline_site != 0) - { - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); - if(decorated && inline_site->type_idx != 0) - { - String8List list = {0}; - str8_list_pushf(scratch.arena, &list, "[inlined] "); - e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); - str8_list_push(scratch.arena, &list, name); - e_type_rhs_string_from_key(scratch.arena, type, &list, 0); - result = str8_list_join(arena, &list, 0); - } - else - { - result = push_str8_copy(arena, name); - } - } - } - - // rjf: depth == 0 or depth >= max? -> form name from scope procedure - else - { - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); - if(decorated && procedure->type_idx != 0) - { - String8List list = {0}; - e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); - str8_list_push(scratch.arena, &list, name); - e_type_rhs_string_from_key(scratch.arena, type, &list, 0); - result = str8_list_join(arena, &list, 0); - } - else - { - result = push_str8_copy(arena, name); - } - } - } - - //- rjf: try global variables - if(result.size == 0) - { - U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, voff); - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, global_var->name_string_idx, &name_size); - result = push_str8_copy(arena, str8(name_ptr, name_size)); - } - - di_scope_close(scope); - scratch_end(scratch); - } - return result; -} - -internal String8 -d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated) -{ - ProfBeginFunction(); - String8 result = {0}; - { - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - U64 voff = ctrl_voff_from_vaddr(module, vaddr); - result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, depth, decorated); - } - ProfEnd(); - return result; -} - //- rjf: symbol -> voff lookups internal U64 diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index ff4b0fc3..536f852b 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -395,10 +395,6 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL //////////////////////////////// //~ rjf: Debug Info Lookups -//- rjf: voff|vaddr -> symbol lookups -internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, U64 depth, B32 decorated); -internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, U64 depth, B32 decorated); - //- rjf: symbol -> voff lookups internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name); internal U64 d_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name); diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 859b708e..1cc3ced0 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -53,35 +53,6 @@ e_eval_from_stringf(Arena *arena, char *fmt, ...) return eval; } -internal E_Eval -e_autoresolved_eval_from_eval(E_Eval eval) -{ - if(e_parse_state && - e_interpret_ctx && - e_parse_state->ctx->modules_count > 0 && - e_interpret_ctx->module_base != 0 && - (e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S64)) || - e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U64)) || - e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_S32)) || - e_type_key_match(eval.irtree.type_key, e_type_key_basic(E_TypeKind_U32)))) - { - U64 vaddr = eval.value.u64; - U64 voff = vaddr - e_interpret_ctx->module_base[0]; - RDI_Parsed *rdi = e_parse_state->ctx->primary_module->rdi; - RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); - RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); - RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); - U32 string_idx = 0; - if(string_idx == 0) { string_idx = procedure->name_string_idx; } - if(string_idx == 0) { string_idx = gvar->name_string_idx; } - if(string_idx != 0) - { - eval.irtree.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 1, 0); - } - } - return eval; -} - internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval) { @@ -117,18 +88,18 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && e_space_read(eval.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) { - Arch arch = e_type_state->ctx->primary_module->arch; + Arch arch = e_base_ctx->primary_module->arch; U32 rdi_idx = 0; RDI_Parsed *rdi = 0; U64 module_base = 0; - for(U64 idx = 0; idx < e_type_state->ctx->modules_count; idx += 1) + for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) { - if(contains_1u64(e_type_state->ctx->modules[idx].vaddr_range, vtable_vaddr)) + if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) { - arch = e_type_state->ctx->modules[idx].arch; + arch = e_base_ctx->modules[idx].arch; rdi_idx = (U32)idx; - rdi = e_type_state->ctx->modules[idx].rdi; - module_base = e_type_state->ctx->modules[idx].vaddr_range.min; + rdi = e_base_ctx->modules[idx].rdi; + module_base = e_base_ctx->modules[idx].vaddr_range.min; break; } } diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index d3be65cf..f6430dea 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -30,7 +30,6 @@ read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); internal E_Eval e_eval_from_string(Arena *arena, String8 string); internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); -internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval); internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); internal E_Eval e_value_eval_from_eval(E_Eval eval); internal E_Value e_value_from_string(String8 string); diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index bc53ed0e..78892efa 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -22,6 +22,37 @@ e_hash_from_string(U64 seed, String8 string) return result; } +//- rjf: type key data structures + +internal void +e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key) +{ + E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); + n->v = key; + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal void +e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key) +{ + E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); + n->v = key; + SLLQueuePushFront(list->first, list->last, n); + list->count += 1; +} + +internal E_TypeKeyList +e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) +{ + E_TypeKeyList dst = {0}; + for(E_TypeKeyNode *n = src->first; n != 0; n = n->next) + { + e_type_key_list_push(arena, &dst, n->v); + } + return dst; +} + //////////////////////////////// //~ rjf: Message Functions @@ -270,6 +301,45 @@ e_string2expr_lookup(E_String2ExprMap *map, String8 string) return expr; } +//- rjf: string -> type-key + +internal E_String2TypeKeyMap +e_string2typekey_map_make(Arena *arena, U64 slots_count) +{ + E_String2TypeKeyMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_String2TypeKeySlot, map.slots_count); + return map; +} + +internal void +e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key) +{ + E_String2TypeKeyNode *n = push_array(arena, E_String2TypeKeyNode, 1); + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); + n->string = push_str8_copy(arena, string); + n->key = key; +} + +internal E_TypeKey +e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) +{ + E_TypeKey key = zero_struct; + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%map->slots_count; + for(E_String2TypeKeyNode *n = map->slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(n->string, string, 0)) + { + key = n->key; + break; + } + } + return key; +} + //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Functions @@ -392,3 +462,15 @@ e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) return map; } + +//////////////////////////////// +//~ rjf: Base Evaluation Context Selection + +internal void +e_select_base_ctx(E_BaseCtx *ctx) +{ + 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; +} diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index a1078495..a047efe8 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -55,6 +55,34 @@ union E_Value F32 f32; }; +//////////////////////////////// +//~ rjf: Bytecode Operation Types + +enum +{ + E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, + E_IRExtKind_SetSpace, + E_IRExtKind_COUNT +}; + +typedef struct E_Op E_Op; +struct E_Op +{ + E_Op *next; + RDI_EvalOp opcode; + E_Value value; + String8 string; +}; + +typedef struct E_OpList E_OpList; +struct E_OpList +{ + E_Op *first; + E_Op *last; + U64 op_count; + U64 encoded_size; +}; + //////////////////////////////// //~ rjf: Operator Info @@ -504,6 +532,31 @@ struct E_String2ExprMap E_String2ExprMapSlot *slots; }; +//////////////////////////////// +//~ rjf: String -> Type Key Map Data Structure + +typedef struct E_String2TypeKeyNode E_String2TypeKeyNode; +struct E_String2TypeKeyNode +{ + E_String2TypeKeyNode *next; + String8 string; + E_TypeKey key; +}; + +typedef struct E_String2TypeKeySlot E_String2TypeKeySlot; +struct E_String2TypeKeySlot +{ + E_String2TypeKeyNode *first; + E_String2TypeKeyNode *last; +}; + +typedef struct E_String2TypeKeyMap E_String2TypeKeyMap; +struct E_String2TypeKeyMap +{ + U64 slots_count; + E_String2TypeKeySlot *slots; +}; + //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) @@ -542,10 +595,31 @@ struct E_AutoHookParams }; //////////////////////////////// -//~ rjf: Contextual & Implicit Evaluation Parameters +//~ rjf: Evaluation Context typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); +typedef struct E_BaseCtx E_BaseCtx; +struct E_BaseCtx +{ + // rjf: instruction pointer info + U64 thread_ip_vaddr; + U64 thread_ip_voff; + E_Space thread_reg_space; + Arch thread_arch; + U64 thread_unwind_count; + + // rjf: modules + E_Module *modules; + U64 modules_count; + E_Module *primary_module; + + // rjf: space hooks + void *space_rw_user_data; + E_SpaceRWFunction *space_read; + E_SpaceRWFunction *space_write; +}; + //////////////////////////////// //~ rjf: Generated Code @@ -555,6 +629,8 @@ typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 //~ rjf: Globals global read_only E_Module e_module_nil = {&rdi_parsed_nil}; +thread_static E_BaseCtx *e_base_ctx = 0; +thread_static U64 e_base_ctx_gen = 0; //////////////////////////////// //~ rjf: Basic Helper Functions @@ -562,6 +638,11 @@ global read_only E_Module e_module_nil = {&rdi_parsed_nil}; internal U64 e_hash_from_string(U64 seed, String8 string); #define e_value_u64(v) (E_Value){.u64 = (v)} +//- rjf: type key data structures +internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); +internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); +internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); + //////////////////////////////// //~ rjf: Message Functions @@ -592,10 +673,20 @@ internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string); internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string); +//- rjf: string -> type-key +internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); +internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); +internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string); + //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Functions internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); +//////////////////////////////// +//~ rjf: Base Evaluation Context Selection + +internal void e_select_base_ctx(E_BaseCtx *ctx); + #endif // EVAL_CORE_H diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0790cf4b..9cd4ff86 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -69,15 +69,13 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - if(ctx->modules == 0) { ctx->modules = &e_module_nil; } - if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } 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_ir_state->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_ir_state->arena, 512); } e_ir_state->ctx = ctx; - e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->thread_ip_voff); + e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff); e_ir_state->used_expr_map = push_array(e_ir_state->arena, E_UsedExprMap, 1); e_ir_state->used_expr_map->slots_count = 64; e_ir_state->used_expr_map->slots = push_array(e_ir_state->arena, E_UsedExprSlot, e_ir_state->used_expr_map->slots_count); @@ -1057,7 +1055,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: generate result.root = r_tree.root; - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, r_type_unwrapped, 1, 0); + result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, r_type_unwrapped, 1, 0); result.mode = E_Mode_Value; }break; @@ -1448,7 +1446,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_TypeKey ptr_type = ptr_tree->type_key; if(ptr_is_decay) { - ptr_type = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, direct_type, 1, 0); + ptr_type = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type, 1, 0); } E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root); result.root = new_root; @@ -1765,7 +1763,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: form namespaceified fallback versions of this lookup string String8List namespaceified_strings = {0}; { - E_Module *module = e_ir_state->ctx->primary_module; + E_Module *module = e_base_ctx->primary_module; RDI_Parsed *rdi = module->rdi; RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; U64 name_size = 0; @@ -1819,8 +1817,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) B32 string_is_implicit_member_name = 0; if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) { - E_Module *module = e_ir_state->ctx->primary_module; - U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + E_Module *module = e_base_ctx->primary_module; + U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); @@ -1837,8 +1835,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try locals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) { - E_Module *module = e_ir_state->ctx->primary_module; - U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + E_Module *module = e_base_ctx->primary_module; + U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); if(local_num != 0) @@ -1850,7 +1848,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); // rjf: extract local's location block - U64 ip_voff = e_ir_state->ctx->thread_ip_voff; + U64 ip_voff = e_base_ctx->thread_ip_voff; for(U32 loc_block_idx = local->location_first; loc_block_idx < local->location_opl; loc_block_idx += 1) @@ -1960,9 +1958,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; + E_Module *module = &e_base_ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); RDI_ParsedNameMap parsed_name_map = {0}; @@ -1999,9 +1997,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try thread-locals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; + E_Module *module = &e_base_ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); RDI_ParsedNameMap parsed_name_map = {0}; @@ -2038,9 +2036,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try procedures if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) { - for(U64 module_idx = 0; module_idx < e_ir_state->ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) { - E_Module *module = &e_ir_state->ctx->modules[module_idx]; + E_Module *module = &e_base_ctx->modules[module_idx]; RDI_Parsed *rdi = module->rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); RDI_ParsedNameMap parsed_name_map = {0}; @@ -2093,13 +2091,13 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(reg_num != 0) { string_mapped = 1; - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_num]; + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num]; E_OpList oplist = {0}; e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; - mapped_type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_num); + mapped_bytecode_space = e_base_ctx->thread_reg_space; + mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num); } } @@ -2110,14 +2108,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(alias_num != 0) { string_mapped = 1; - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_num]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_ir_state->ctx->primary_module->arch)[alias_slice.code]; + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code]; E_OpList oplist = {0}; e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_ir_state->ctx->thread_reg_space; - mapped_type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_num); + mapped_bytecode_space = e_base_ctx->thread_reg_space; + mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num); } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 60c0226b..0709a2c6 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -4,34 +4,6 @@ #ifndef EVAL_IR_H #define EVAL_IR_H -//////////////////////////////// -//~ rjf: Bytecode Operation Types - -enum -{ - E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, - E_IRExtKind_SetSpace, - E_IRExtKind_COUNT -}; - -typedef struct E_Op E_Op; -struct E_Op -{ - E_Op *next; - RDI_EvalOp opcode; - E_Value value; - String8 string; -}; - -typedef struct E_OpList E_OpList; -struct E_OpList -{ - E_Op *first; - E_Op *last; - U64 op_count; - U64 encoded_size; -}; - //////////////////////////////// //~ rjf: Used Tag Map Data Structure @@ -116,24 +88,11 @@ struct E_StringIDMap typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { - // rjf: instruction pointer info - U64 thread_ip_vaddr; - U64 thread_ip_voff; - E_Space thread_reg_space; - - // rjf: modules - E_Module *modules; - U64 modules_count; - E_Module *primary_module; - - // rjf: identifier-resolution maps E_String2NumMap *regs_map; E_String2NumMap *reg_alias_map; E_String2NumMap *locals_map; // (within `primary_module`) E_String2NumMap *member_map; // (within `primary_module`) E_String2ExprMap *macro_map; - - // rjf: hook maps E_AutoHookMap *auto_hook_map; }; diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 77ce10ff..a7c0ae6b 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -295,46 +295,6 @@ e_token_array_make_first_opl(E_Token *first, E_Token *opl) return array; } -//////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal E_ParseCtx * -e_selected_parse_ctx(void) -{ - return e_parse_state->ctx; -} - -internal void -e_select_parse_ctx(E_ParseCtx *ctx) -{ - if(e_parse_state == 0) - { - Arena *arena = arena_alloc(); - e_parse_state = push_array(arena, E_ParseState, 1); - e_parse_state->arena = arena; - e_parse_state->arena_eval_start_pos = arena_pos(arena); - } - arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - if(ctx->modules == 0) { ctx->modules = &e_module_nil; } - if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } - e_parse_state->ctx = ctx; -} - -internal U32 -e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi) -{ - U32 result = 0; - for(U64 idx = 0; idx < e_parse_state->ctx->modules_count; idx += 1) - { - if(e_parse_state->ctx->modules[idx].rdi == rdi) - { - result = (U32)idx; - break; - } - } - return result; -} - //////////////////////////////// //~ rjf: Expression Tree Building Functions @@ -688,9 +648,9 @@ e_leaf_type_from_name(String8 name) } if(!found) { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) { - RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi; + RDI_Parsed *rdi = e_base_ctx->modules[module_idx].rdi; RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); RDI_ParsedNameMap parsed_name_map = {0}; rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); @@ -728,7 +688,7 @@ e_type_from_expr(E_Expr *expr) case E_ExprKind_Ptr: { E_TypeKey direct_type_key = e_type_from_expr(expr->first); - result = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, direct_type_key, 1, 0); + result = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type_key, 1, 0); }break; case E_ExprKind_Array: { @@ -1090,7 +1050,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok else { E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); + type->type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); E_Expr *casted = atom; E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); e_expr_push_child(cast, type); diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 3a11affb..c46ceb5b 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -17,25 +17,13 @@ struct E_Parse }; //////////////////////////////// -//~ rjf: Parse Context - -typedef struct E_ParseCtx E_ParseCtx; -struct E_ParseCtx -{ - E_Module *modules; - U64 modules_count; - E_Module *primary_module; -}; - -//////////////////////////////// -//~ rjf: Parse State (stateful thread-local caching mechanisms, not provided by user) +//~ rjf: Parse Evaluation State typedef struct E_ParseState E_ParseState; struct E_ParseState { Arena *arena; U64 arena_eval_start_pos; - E_ParseCtx *ctx; }; //////////////////////////////// @@ -56,13 +44,6 @@ internal E_TokenArray e_token_array_from_chunk_list(Arena *arena, E_TokenChunkLi internal E_TokenArray e_token_array_from_text(Arena *arena, String8 text); internal E_TokenArray e_token_array_make_first_opl(E_Token *first, E_Token *opl); -//////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal E_ParseCtx *e_selected_parse_ctx(void); -internal void e_select_parse_ctx(E_ParseCtx *ctx); -internal U32 e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi); - //////////////////////////////// //~ rjf: Expression Tree Building Functions diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index cb603c39..ff7af653 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -223,10 +223,10 @@ e_member_array_from_list(Arena *arena, E_MemberList *list) } //////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) +//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) internal void -e_select_type_ctx(E_TypeCtx *ctx) +e_type_eval_begin(void) { if(e_type_state == 0) { @@ -235,10 +235,7 @@ e_select_type_ctx(E_TypeCtx *ctx) e_type_state->arena = arena; e_type_state->arena_eval_start_pos = arena_pos(e_type_state->arena); } - if(ctx->modules == 0) { ctx->modules = &e_module_nil; } - if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } arena_pop_to(e_type_state->arena, e_type_state->arena_eval_start_pos); - e_type_state->ctx = ctx; e_type_state->cons_id_gen = 0; e_type_state->cons_content_slots_count = 256; e_type_state->cons_key_slots_count = 256; @@ -665,7 +662,7 @@ e_type_byte_size_from_key(E_TypeKey key) { U64 type_node_idx = key.u32[1]; U32 rdi_idx = key.u32[2]; - RDI_Parsed *rdi = e_type_state->ctx->modules[rdi_idx].rdi; + RDI_Parsed *rdi = e_base_ctx->modules[rdi_idx].rdi; RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); result = rdi_type->byte_size; }break; @@ -777,7 +774,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) { U64 type_node_idx = key.u32[1]; U32 rdi_idx = key.u32[2]; - RDI_Parsed *rdi = e_type_state->ctx->modules[rdi_idx].rdi; + RDI_Parsed *rdi = e_base_ctx->modules[rdi_idx].rdi; RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); if(rdi_type->kind != RDI_TypeKind_NULL) { @@ -824,7 +821,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = members_count; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; type->members = members; } @@ -869,7 +866,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = (U64)rdi_type->byte_size; type->count = enum_vals_count; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; type->enum_vals = enum_vals; type->direct_type_key = direct_type_key; } @@ -909,7 +906,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->byte_size = direct_type_byte_size; type->flags = flags; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Ptr: case RDI_TypeKind_LRef: @@ -918,9 +915,9 @@ e_type_from_key(Arena *arena, E_TypeKey key) type = push_array(arena, E_Type, 1); type->kind = kind; type->direct_type_key = direct_type_key; - type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->count = 1; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Array: @@ -930,7 +927,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->count = rdi_type->constructed.count; type->byte_size = direct_type_byte_size * type->count; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; }break; case RDI_TypeKind_Function: { @@ -942,11 +939,11 @@ e_type_from_key(Arena *arena, E_TypeKey key) { type = push_array(arena, E_Type, 1); type->kind = kind; - type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->direct_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -976,11 +973,11 @@ e_type_from_key(Arena *arena, E_TypeKey key) { type = push_array(arena, E_Type, 1); type->kind = kind; - type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->owner_type_key = direct_type_key; type->count = count; type->param_type_keys = push_array_no_zero(arena, E_TypeKey, type->count); - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; for(U32 idx = 0; idx < type->count; idx += 1) { U32 param_type_idx = idx_run[idx]; @@ -1015,10 +1012,10 @@ e_type_from_key(Arena *arena, E_TypeKey key) } type = push_array(arena, E_Type, 1); type->kind = kind; - type->byte_size = bit_size_from_arch(e_type_state->ctx->modules[rdi_idx].arch)/8; + type->byte_size = bit_size_from_arch(e_base_ctx->modules[rdi_idx].arch)/8; type->owner_type_key = owner_type_key; type->direct_type_key = direct_type_key; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; }break; } } @@ -1047,7 +1044,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->name = push_str8_copy(arena, name); type->byte_size = direct_type_byte_size; type->direct_type_key = direct_type_key; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; } //- rjf: bitfields @@ -1071,7 +1068,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type->direct_type_key = direct_type_key; type->off = (U32)rdi_type->bitfield.off; type->count = (U64)rdi_type->bitfield.size; - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; } //- rjf: incomplete types @@ -1085,7 +1082,7 @@ e_type_from_key(Arena *arena, E_TypeKey key) type = push_array(arena, E_Type, 1); type->kind = kind; type->name = push_str8_copy(arena, name); - type->arch = e_type_state->ctx->modules[rdi_idx].arch; + type->arch = e_base_ctx->modules[rdi_idx].arch; } } @@ -1990,74 +1987,6 @@ e_default_expansion_type_from_key(E_TypeKey root_key) return type_key; } -//- rjf: type key data structures - -internal void -e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key) -{ - E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); - n->v = key; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal void -e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key) -{ - E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); - n->v = key; - SLLQueuePushFront(list->first, list->last, n); - list->count += 1; -} - -internal E_TypeKeyList -e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) -{ - E_TypeKeyList dst = {0}; - for(E_TypeKeyNode *n = src->first; n != 0; n = n->next) - { - e_type_key_list_push(arena, &dst, n->v); - } - return dst; -} - -internal E_String2TypeKeyMap -e_string2typekey_map_make(Arena *arena, U64 slots_count) -{ - E_String2TypeKeyMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_String2TypeKeySlot, map.slots_count); - return map; -} - -internal void -e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key) -{ - E_String2TypeKeyNode *n = push_array(arena, E_String2TypeKeyNode, 1); - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); - n->string = push_str8_copy(arena, string); - n->key = key; -} - -internal E_TypeKey -e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) -{ - E_TypeKey key = zero_struct; - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - for(E_String2TypeKeyNode *n = map->slots[slot_idx].first; n != 0; n = n->next) - { - if(str8_match(n->string, string, 0)) - { - key = n->key; - break; - } - } - return key; -} - //////////////////////////////// //~ rjf: Cache Lookups @@ -2546,7 +2475,7 @@ E_TYPE_IREXT_FUNCTION_DEF(slice) } // rjf: determine architecture - Arch arch = e_type_state->ctx->primary_module->arch; + Arch arch = e_base_ctx->primary_module->arch; if(base_ptr_member != 0) { E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 4efa66ad..fdbcb08b 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -4,31 +4,6 @@ #ifndef EVAL_TYPES_H #define EVAL_TYPES_H -//////////////////////////////// -//~ rjf: String -> Type Key Map Data Structure - -typedef struct E_String2TypeKeyNode E_String2TypeKeyNode; -struct E_String2TypeKeyNode -{ - E_String2TypeKeyNode *next; - String8 string; - E_TypeKey key; -}; - -typedef struct E_String2TypeKeySlot E_String2TypeKeySlot; -struct E_String2TypeKeySlot -{ - E_String2TypeKeyNode *first; - E_String2TypeKeyNode *last; -}; - -typedef struct E_String2TypeKeyMap E_String2TypeKeyMap; -struct E_String2TypeKeyMap -{ - U64 slots_count; - E_String2TypeKeySlot *slots; -}; - //////////////////////////////// //~ rjf: Type Unwrapping @@ -46,7 +21,7 @@ enum }; //////////////////////////////// -//~ rjf: Evaluation Context +//~ rjf: Type Evaluation State //- rjf: constructed type cache types @@ -152,17 +127,7 @@ struct E_MemberCacheSlot E_MemberCacheNode *last; }; -//- rjf: context parameterization - -typedef struct E_TypeCtx E_TypeCtx; -struct E_TypeCtx -{ - E_Module *modules; - U64 modules_count; - E_Module *primary_module; -}; - -//- rjf: stateful machine part of context (not provided by user) +//- rjf: bundle typedef struct E_TypeState E_TypeState; struct E_TypeState @@ -170,9 +135,6 @@ struct E_TypeState Arena *arena; U64 arena_eval_start_pos; - // rjf: evaluation context - E_TypeCtx *ctx; - // rjf: JIT-constructed types tables U64 cons_id_gen; U64 cons_content_slots_count; @@ -231,9 +193,9 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list); //////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) +//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) -internal void e_select_type_ctx(E_TypeCtx *ctx); +internal void e_type_eval_begin(void); //////////////////////////////// //~ rjf: Type Operation Functions @@ -288,14 +250,6 @@ internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8Lis internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key); -//- rjf: type key data structures -internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); -internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); -internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); -internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); -internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); -internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string); - //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index c2ed317f..cef40c56 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -469,18 +469,18 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && e_space_read(eval.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) { - Arch arch = e_type_state->ctx->primary_module->arch; + Arch arch = e_base_ctx->primary_module->arch; U32 rdi_idx = 0; RDI_Parsed *rdi = 0; U64 module_base = 0; - for(U64 idx = 0; idx < e_type_state->ctx->modules_count; idx += 1) + for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) { - if(contains_1u64(e_type_state->ctx->modules[idx].vaddr_range, vtable_vaddr)) + if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) { - arch = e_type_state->ctx->modules[idx].arch; + arch = e_base_ctx->modules[idx].arch; rdi_idx = (U32)idx; - rdi = e_type_state->ctx->modules[idx].rdi; - module_base = e_type_state->ctx->modules[idx].vaddr_range.min; + rdi = e_base_ctx->modules[idx].rdi; + module_base = e_base_ctx->modules[idx].vaddr_range.min; break; } } @@ -1867,11 +1867,11 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) U64 vaddr = ptr_data->value_eval.value.u64; E_Module *module = &e_module_nil; U32 module_idx = 0; - for EachIndex(idx, e_type_state->ctx->modules_count) + for EachIndex(idx, e_base_ctx->modules_count) { - if(contains_1u64(e_type_state->ctx->modules[idx].vaddr_range, vaddr)) + if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vaddr)) { - module = &e_type_state->ctx->modules[idx]; + module = &e_base_ctx->modules[idx]; module_idx = (U32)idx; break; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a3e0a0d4..13ae1c1e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2998,8 +2998,31 @@ rd_view_ui(Rng2F32 rect) { default: { - String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); - rd_cmd(RD_CmdKind_CompleteQuery, .string = symbol_name); + U64 vaddr = eval.value.u64; + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + { + DI_Scope *scope = di_scope_open(); + RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0); + String8 name = {0}; + if(name.size == 0) + { + RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); + name.str = rdi_name_from_procedure(rdi, procedure, &name.size); + } + if(name.size == 0) + { + RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); + name.str = rdi_string_from_idx(rdi, gvar->name_string_idx, &name.size); + } + if(name.size != 0) + { + rd_cmd(RD_CmdKind_CompleteQuery, .string = name); + } + di_scope_close(scope); + } }break; case E_SpaceKind_File: case E_SpaceKind_FileSystem: @@ -3050,10 +3073,32 @@ rd_view_ui(Rng2F32 rect) { default: { - String8 symbol_name = d_symbol_name_from_process_vaddr(scratch.arena, ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), eval.value.u64, 0, 0); - if(symbol_name.size != 0) + String8 name = {0}; { - rd_cmd(RD_CmdKind_GoToName, .string = symbol_name); + U64 vaddr = eval.value.u64; + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + { + DI_Scope *scope = di_scope_open(); + RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0); + if(name.size == 0) + { + RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); + name.str = rdi_name_from_procedure(rdi, procedure, &name.size); + } + if(name.size == 0) + { + RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); + name.str = rdi_string_from_idx(rdi, gvar->name_string_idx, &name.size); + } + di_scope_close(scope); + } + } + if(name.size != 0) + { + rd_cmd(RD_CmdKind_GoToName, .string = name); } else { @@ -10214,30 +10259,6 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str }break; } } - -#if 0 - // rjf: try to map as symbol - if(!mapped && kind == TXT_TokenKind_Identifier) - { - U64 voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, string); - if(voff != 0) - { - mapped = 1; - color = RD_ThemeColor_CodeSymbol; - } - } - - // rjf: try to map as type - if(!mapped && kind == TXT_TokenKind_Identifier) - { - U64 type_num = d_type_num_from_dbgi_key_name(&dbgi_key, string); - if(type_num != 0) - { - mapped = 1; - color = RD_ThemeColor_CodeType; - } - } -#endif } return color; } @@ -11769,57 +11790,70 @@ rd_frame(void) } ProfEnd(); - //////////////////////////// - //- rjf: build eval type context - // - E_TypeCtx *type_ctx = push_array(scratch.arena, E_TypeCtx, 1); - ProfScope("build eval type context") - { - E_TypeCtx *ctx = type_ctx; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_type_ctx(type_ctx); + //~ + //~ NOTE(rjf): NEW VVVVV + //~ //////////////////////////// - //- rjf: build eval parse context + //- rjf: build base evaluation context // - E_ParseCtx *parse_ctx = push_array(scratch.arena, E_ParseCtx, 1); - ProfScope("build eval parse context") + E_BaseCtx *eval_base_ctx = push_array(scratch.arena, E_BaseCtx, 1); { - E_ParseCtx *ctx = parse_ctx; - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - } - e_select_parse_ctx(parse_ctx); - - //////////////////////////// - //- rjf: build eval IR context - // - E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); - if(e_ir_state != 0) { e_ir_state->ctx = 0; } - { - E_IRCtx *ctx = ir_ctx; - ctx->thread_ip_voff = rip_voff; - ctx->thread_ip_vaddr = rip_vaddr; - ctx->thread_reg_space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_CtrlEntity); - ctx->modules = eval_modules; - ctx->modules_count = eval_modules_count; - ctx->primary_module = eval_modules_primary; - ctx->regs_map = ctrl_string2reg_from_arch(ctx->primary_module->arch); - ctx->reg_alias_map = ctrl_string2alias_from_arch(ctx->primary_module->arch); - ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); - ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); - ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); - ctx->macro_map[0] = e_string2expr_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); + E_BaseCtx *ctx = eval_base_ctx; - //- rjf: cache meta name -> type key correllation - rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); - rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); + //- rjf: fill instruction pointer info + ctx->thread_ip_vaddr = rip_vaddr; + ctx->thread_ip_voff = rip_voff; + ctx->thread_reg_space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_CtrlEntity); + ctx->thread_arch = thread->arch; + ctx->thread_unwind_count = unwind_count; + + //- rjf: fill modules + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + + //- rjf: fill space hooks + ctx->space_read = rd_eval_space_read; + ctx->space_write = rd_eval_space_write; + } + e_select_base_ctx(eval_base_ctx); + + //////////////////////////// + //- rjf: begin type evaluation + // + e_type_eval_begin(); + + //////////////////////////// + //- rjf: build extra types & maps + // + E_String2ExprMap *macro_map = push_array(scratch.arena, E_String2ExprMap, 1); + macro_map[0] = e_string2expr_map_make(scratch.arena, 512); + E_AutoHookMap *auto_hook_map = push_array(scratch.arena, E_AutoHookMap, 1); + auto_hook_map[0] = e_auto_hook_map_make(scratch.arena, 512); + rd_state->meta_name2type_map = push_array(rd_frame_arena(), E_String2TypeKeyMap, 1); + rd_state->meta_name2type_map[0] = e_string2typekey_map_make(rd_frame_arena(), 256); + EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); + rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); + { + //- rjf: add macro for commands + { + String8 name = str8_lit("commands"); + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + } + + //- rjf: build schema types & cache (name -> type) mapping for EachElement(idx, rd_name_schema_info_table) { String8 name = rd_name_schema_info_table[idx].name; @@ -11861,18 +11895,72 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", cfg->id), expr); + e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", cfg->id), expr); if(exe.size != 0) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_skip_last_slash(exe), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_skip_last_slash(exe), expr); } if(label.size != 0) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, label, expr); + e_string2expr_map_insert(scratch.arena, macro_map, label, expr); } } } + //- rjf: add macro for watches group + { + String8 collection_name = str8_lit("watches"); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(watches), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(watches), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), + }); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); + } + + //- rjf: add macros for all watches which define identifiers + RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); + for(RD_CfgNode *n = watches.first; n != 0; n = n->next) + { + RD_Cfg *watch = n->v; + String8 expr = rd_expr_from_cfg(watch); + E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); + if(parse.msgs.max_kind == E_MsgKind_Null) + { + for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) + { + e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, macro_map, expr); + } + } + } + + //- rjf: add macros for all config collections + for EachElement(cfg_name_idx, evallable_cfg_names) + { + String8 cfg_name = evallable_cfg_names[cfg_name_idx]; + String8 collection_name = rd_plural_from_code_name(cfg_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs), + .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs), + .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs), + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); + } + //- rjf: add macros for windows/tabs { RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); @@ -11886,7 +11974,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", window->id), expr); + e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", window->id), expr); } RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); for(RD_PanelNode *p = panel_tree.root; @@ -11902,12 +11990,13 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$%I64x", tab->id), expr); + e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", tab->id), expr); } } } } + //- rjf: add macros for user/project { E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("user")); @@ -11916,7 +12005,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("user_settings"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("user_settings"), expr); } { E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("project")); @@ -11925,7 +12014,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("project_settings"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("project_settings"), expr); } //- rjf: add macros for evallable control entities @@ -11950,51 +12039,72 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, ctrl_string_from_handle(scratch.arena, entity->handle), expr); + e_string2expr_map_insert(scratch.arena, macro_map, ctrl_string_from_handle(scratch.arena, entity->handle), expr); if(entity->string.size != 0) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); + e_string2expr_map_insert(scratch.arena, macro_map, entity->string, expr); } if(kind == CTRL_EntityKind_Machine && entity->handle.machine_id == CTRL_MachineID_Local) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("local_machine"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("local_machine"), expr); } if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("current_thread"), expr); } if(kind == CTRL_EntityKind_Process && ctrl_handle_match(rd_base_regs()->process, entity->handle)) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_process"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("current_process"), expr); } if(kind == CTRL_EntityKind_Module && ctrl_handle_match(rd_base_regs()->module, entity->handle)) { - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_module"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("current_module"), expr); } } } + //- rjf: add macros for all ctrl entity collections + for EachElement(ctrl_name_idx, evallable_ctrl_names) + { + String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; + String8 collection_name = rd_plural_from_code_name(kind_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = collection_name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(ctrl_entities), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(ctrl_entities), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(ctrl_entities) + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); + } + + //- rjf: add macro / lookup rules for unattached processes + { + String8 collection_name = str8_lit("unattached_processes"); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(unattached_processes) + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); + } + //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' { E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).expr; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("call_stack"), expr); } - //- rjf: add macro for watches group - { - String8 collection_name = str8_lit("watches"); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren, - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(watches), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(watches), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), - }); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - } //- rjf: add types for queries { @@ -12050,7 +12160,7 @@ rd_frame(void) .range = collection_infos[idx].range, }); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); } } @@ -12076,82 +12186,7 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(debug_info_table), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(debug_info_table) }); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); - } - - //- rjf: add macros for all config collections - for EachElement(cfg_name_idx, evallable_cfg_names) - { - String8 cfg_name = evallable_cfg_names[cfg_name_idx]; - String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, - .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs), - .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs), - .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs), - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); - } - - //- rjf: add macros for all ctrl entity collections - for EachElement(ctrl_name_idx, evallable_ctrl_names) - { - String8 kind_name = evallable_ctrl_names[ctrl_name_idx]; - String8 collection_name = rd_plural_from_code_name(kind_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, - .name = collection_name, - .access = E_TYPE_ACCESS_FUNCTION_NAME(ctrl_entities), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(ctrl_entities), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(ctrl_entities) - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); - } - - //- rjf: add macro / lookup rules for unattached processes - { - String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(unattached_processes) - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); - } - - //- rjf: add macro for commands - { - String8 name = str8_lit("commands"); - E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, - .name = name, - .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, name, expr); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); } //- rjf: add macro for output log @@ -12166,7 +12201,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("output"), expr); + e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("output"), expr); hs_scope_close(hs_scope); } @@ -12197,28 +12232,12 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); - e_string2expr_map_insert(scratch.arena, ctx->macro_map, table[idx].name, expr); + e_string2expr_map_insert(scratch.arena, macro_map, table[idx].name, expr); hs_scope_close(hs_scope); } } #endif - //- rjf: add macros for all watches which define identifiers - RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - for(RD_CfgNode *n = watches.first; n != 0; n = n->next) - { - RD_Cfg *watch = n->v; - String8 expr = rd_expr_from_cfg(watch); - E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); - if(parse.msgs.max_kind == E_MsgKind_Null) - { - for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) - { - e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); - } - } - } - //- rjf: gather auto-view-rules from loaded modules RD_CfgList immediate_auto_view_rules = {0}; CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); @@ -12260,17 +12279,11 @@ rd_frame(void) RD_Cfg *rule = n->v; String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; - e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + e_auto_hook_map_insert_new(scratch.arena, auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); } } } - } - e_select_ir_ctx(ir_ctx); - - //////////////////////////// - //- rjf: generate macros for all lenses - // - { + //- rjf: choose set of lenses // TODO(rjf): generate via metaprogram struct @@ -12312,9 +12325,6 @@ rd_frame(void) }; //- rjf: fill lenses in ev expand rule map, rd view ui rule map - EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); - ev_select_expand_rule_table(expand_rule_table); - rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); { for EachElement(idx, lens_table) { @@ -12352,9 +12362,25 @@ rd_frame(void) .irext = lens_table[idx].irext, .access = lens_table[idx].access, .expand = lens_table[idx].expand); - e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, lens_table[idx].name, expr); + e_string2expr_map_insert(scratch.arena, macro_map, lens_table[idx].name, expr); } } + ev_select_expand_rule_table(expand_rule_table); + + //////////////////////////// + //- rjf: build IR evaluation context + // + E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); + { + E_IRCtx *ctx = ir_ctx; + ctx->regs_map = ctrl_string2reg_from_arch(eval_base_ctx->primary_module->arch); + ctx->reg_alias_map = ctrl_string2alias_from_arch(eval_base_ctx->primary_module->arch); + ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); + ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); + ctx->macro_map = macro_map; + ctx->auto_hook_map = auto_hook_map; + } + e_select_ir_ctx(ir_ctx); //////////////////////////// //- rjf: build eval interpretation context diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 0d796539..84e86383 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1333,7 +1333,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) // rjf: unpack row info RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; - E_Module *module = &e_parse_state->ctx->modules[item->dbgi_idx]; + E_Module *module = &e_base_ctx->modules[item->dbgi_idx]; // rjf: build expr E_Expr *item_expr = &e_expr_nil; @@ -1353,7 +1353,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = procedure->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); String8 symbol_name = {0}; symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); String8List strings = {0}; @@ -1377,7 +1377,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = gvar->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Offset; item_expr->space = module->space; @@ -1393,7 +1393,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) String8 bytecode = e_bytecode_from_oplist(arena, &oplist); U32 type_idx = tvar->type_idx; RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_state->ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); item_expr->mode = E_Mode_Offset; item_expr->space = module->space; @@ -1405,7 +1405,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) { RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_state->ctx->modules)); + E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_base_ctx->modules)); item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); item_expr->type_key = type_key; }break; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 6f0b6bd8..72dfa6a5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2588,7 +2588,29 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, f_rip); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 rip_voff = ctrl_voff_from_vaddr(module, f_rip); - String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 0, 1); + String8 symbol_name = {0}; + { + U64 vaddr = eval.value.u64; + CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + { + DI_Scope *scope = di_scope_open(); + RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0); + if(symbol_name.size == 0) + { + RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff); + symbol_name.str = rdi_name_from_procedure(rdi, procedure, &symbol_name.size); + } + if(symbol_name.size == 0) + { + RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff); + symbol_name.str = rdi_string_from_idx(rdi, gvar->name_string_idx, &symbol_name.size); + } + di_scope_close(scope); + } + } Annotation *annotation = push_array(scratch.arena, Annotation, 1); annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]"); annotation->kind_string = str8_lit("Call Stack Frame"); From c766ffe0a3b142d4c5179e82fd2127c885d7ab6c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 11:55:58 -0700 Subject: [PATCH 435/755] kill old code --- src/eval/eval_interpret.c | 6 ------ src/eval/eval_interpret.h | 1 - src/eval/eval_parse.c | 9 --------- src/eval/eval_parse.h | 1 - 4 files changed, 17 deletions(-) diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index ee5c96f3..670118df 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -4,12 +4,6 @@ //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_InterpretCtx * -e_selected_interpret_ctx(void) -{ - return e_interpret_ctx; -} - internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff) { diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index cfebe221..0c900a5a 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -41,7 +41,6 @@ thread_static E_InterpretCtx *e_interpret_ctx = 0; //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_InterpretCtx *e_selected_interpret_ctx(void); internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff); //////////////////////////////// diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index a7c0ae6b..247e85c6 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -334,15 +334,6 @@ e_expr_ref(Arena *arena, E_Expr *ref) return expr; } -internal E_Expr * -e_expr_ref_deref(Arena *arena, E_Expr *rhs) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0); - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(root, rhs_ref); - return root; -} - internal E_Expr * e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs) { diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index c46ceb5b..657320b9 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -52,7 +52,6 @@ internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); -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_copy(Arena *arena, E_Expr *src); internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr); From a27b90a3f93eafeb7264ca9c6323e30e2970ce66 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 12:04:50 -0700 Subject: [PATCH 436/755] eliminate separate expr -> type path (this is just done via ir tree generation now), eliminate helper for locating defines & pushing to macro maps --- src/eval/eval_ir.c | 36 +++++++++++++--------------- src/eval/eval_parse.c | 52 ---------------------------------------- src/eval/eval_parse.h | 2 -- src/raddbg/raddbg_core.c | 35 ++++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 75 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9cd4ff86..73d0d69c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1065,7 +1065,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_TypeKey cast_type = e_type_from_expr(cast_type_expr); + E_IRTreeAndType cast_irtree = e_irtree_and_type_from_expr(arena, cast_type_expr); + E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); @@ -1123,22 +1124,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - switch(r_expr->kind) - { - case E_ExprKind_TypeIdent: - case E_ExprKind_Ptr: - case E_ExprKind_Array: - case E_ExprKind_Func: - { - r_type = e_type_from_expr(r_expr); - }break; - default: - { - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); - r_type = r_tree.type_key; - }break; - } + E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + r_type = r_tree.type_key; // rjf: bad conditions? -> error if applicable, exit if(e_type_key_match(r_type, e_type_key_zero())) @@ -2253,13 +2241,21 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) result.type_key = expr->type_key; result.mode = E_Mode_Null; }break; - - //- rjf: (unexpected) type expressions case E_ExprKind_Ptr: + { + E_IRTreeAndType ptee_irtree = e_irtree_and_type_from_expr(arena, expr->first); + result = ptee_irtree; + result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); + }break; case E_ExprKind_Array: + { + E_IRTreeAndType element_irtree = e_irtree_and_type_from_expr(arena, expr->first); + result = element_irtree; + result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); + }break; case E_ExprKind_Func: { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Type expression not expected."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Function type expressions are currently not supported."); }break; //- rjf: definitions diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 247e85c6..ddafb9b7 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -663,58 +663,6 @@ e_leaf_type_from_name(String8 name) return key; } -internal E_TypeKey -e_type_from_expr(E_Expr *expr) -{ - E_TypeKey result = zero_struct; - E_ExprKind kind = expr->kind; - switch(kind) - { - // TODO(rjf): do we support E_ExprKind_Func here? - default:{}break; - case E_ExprKind_TypeIdent: - { - result = expr->type_key; - }break; - case E_ExprKind_Ptr: - { - E_TypeKey direct_type_key = e_type_from_expr(expr->first); - result = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type_key, 1, 0); - }break; - case E_ExprKind_Array: - { - E_Expr *child_expr = expr->first; - E_TypeKey direct_type_key = e_type_from_expr(child_expr); - result = e_type_key_cons_array(direct_type_key, expr->value.u64, 0); - }break; - } - return result; -} - -internal void -e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr) -{ - switch(expr->kind) - { - default: - { - for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) - { - e_push_leaf_ident_exprs_from_expr__in_place(arena, map, child); - } - }break; - case E_ExprKind_Define: - { - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - if(exprl->kind == E_ExprKind_LeafIdentifier) - { - e_string2expr_map_insert(arena, map, exprl->string, exprr); - } - }break; - } -} - internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) { diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 657320b9..2c7554c4 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -66,8 +66,6 @@ internal String8 e_string_from_expr(Arena *arena, E_Expr *expr, String8 parent_e //~ rjf: Parsing Functions internal E_TypeKey e_leaf_type_from_name(String8 name); -internal E_TypeKey e_type_from_expr(E_Expr *expr); -internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 13ae1c1e..81caf7b4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11934,7 +11934,40 @@ rd_frame(void) { for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) { - e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, macro_map, expr); + typedef struct ExprWalkTask ExprWalkTask; + struct ExprWalkTask + { + ExprWalkTask *next; + E_Expr *expr; + }; + ExprWalkTask start_task = {0, expr}; + ExprWalkTask *first_task = &start_task; + ExprWalkTask *last_task = first_task; + for(ExprWalkTask *t = first_task; t != 0; t = t->next) + { + switch(t->expr->kind) + { + case E_ExprKind_Call:{}break; + case E_ExprKind_Define: + { + E_Expr *lhs = t->expr->first; + E_Expr *rhs = lhs->next; + if(lhs->kind == E_ExprKind_LeafIdentifier) + { + e_string2expr_map_insert(scratch.arena, macro_map, lhs->string, rhs); + } + }break; + default: + { + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->expr = child; + } + }break; + } + } } } } From c9a05bc76fe78ddc1a8129b3aacf15402102b994 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 14:45:15 -0700 Subject: [PATCH 437/755] adjust block tree building from being on expr -> being on eval --- src/ctrl/ctrl_core.c | 16 +++++++------- src/eval/eval_bundles.c | 12 ++++++++++ src/eval/eval_bundles.h | 21 +----------------- src/eval/eval_core.h | 22 ++++++++++++++++++- src/eval/eval_ir.h | 1 - src/eval/eval_parse.h | 4 +--- .../eval_visualization_core.c | 5 ++--- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 6 ++--- 9 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 4db53c17..eb7f3476 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1466,16 +1466,15 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 U128 result = {0}; U64 size = dim_1u64(range); U64 pre_mem_gen = dmn_mem_gen(); + CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; + U64 range_hash = ctrl_hash_from_string(str8_struct(&range)); + U64 process_hash = ctrl_hash_from_string(str8_struct(&process)); + U64 process_slot_idx = process_hash%cache->slots_count; + U64 process_stripe_idx = process_slot_idx%cache->stripes_count; + CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx]; + CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx]; if(size != 0) for(;;) { - CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; - U64 process_hash = ctrl_hash_from_string(str8_struct(&process)); - U64 process_slot_idx = process_hash%cache->slots_count; - U64 process_stripe_idx = process_slot_idx%cache->stripes_count; - CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx]; - CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx]; - U64 range_hash = ctrl_hash_from_string(str8_struct(&range)); - //- rjf: try to read from cache B32 is_good = 0; B32 process_node_exists = 0; @@ -6353,6 +6352,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) { ProfBeginFunction(); CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; + //- rjf: unpack next request CTRL_Handle process = {0}; Rng1U64 vaddr_range = {0}; diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 1cc3ced0..fcfca2b7 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -33,10 +33,14 @@ e_eval_from_expr(Arena *arena, E_Expr *expr) internal E_Eval e_eval_from_string(Arena *arena, String8 string) { + ProfBeginFunction(); + ProfBegin("e_eval_from_string (%.*s)", str8_varg(string)); E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); E_Eval eval = e_eval_from_expr(arena, parse.expr); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); + ProfEnd(); + ProfEnd(); return eval; } @@ -217,6 +221,14 @@ e_value_from_expr(E_Expr *expr) return result; } +internal E_Value +e_value_from_eval(E_Eval eval) +{ + E_Eval value_eval = e_value_eval_from_eval(eval); + E_Value result = value_eval.value; + return result; +} + internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string) { diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index f6430dea..f56457b1 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -4,26 +4,6 @@ #ifndef EVAL_BUNDLES_H #define EVAL_BUNDLES_H -//////////////////////////////// -//~ rjf: Bundled Evaluation Path Types - -typedef struct E_Eval E_Eval; -struct E_Eval -{ - E_Value value; - E_Space space; - E_Expr *expr; - E_IRTreeAndType irtree; - String8 bytecode; - E_InterpretationCode code; - E_MsgList msgs; -}; - -//////////////////////////////// -//~ rjf: Globals - -read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e_irnode_nil}}; - //////////////////////////////// //~ rjf: Bundled Evaluation Functions @@ -35,6 +15,7 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval); internal E_Value e_value_from_string(String8 string); internal E_Value e_value_from_stringf(char *fmt, ...); internal E_Value e_value_from_expr(E_Expr *expr); +internal E_Value e_value_from_eval(E_Eval eval); internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string); internal E_Eval e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...);; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index a047efe8..7e361fe9 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -303,6 +303,21 @@ struct E_IRTreeAndType E_IRTreeAndType *prev; }; +//////////////////////////////// +//~ rjf: Evaluation Artifact Bundle + +typedef struct E_Eval E_Eval; +struct E_Eval +{ + E_Value value; + E_Space space; + E_Expr *expr; + E_IRTreeAndType irtree; + String8 bytecode; + E_InterpretationCode code; + E_MsgList msgs; +}; + //////////////////////////////// //~ rjf: Full Extracted Type Information Types @@ -628,7 +643,12 @@ struct E_BaseCtx //////////////////////////////// //~ rjf: Globals -global read_only E_Module e_module_nil = {&rdi_parsed_nil}; +read_only global E_String2NumMap e_string2num_map_nil = {0}; +read_only global E_String2ExprMap e_string2expr_map_nil = {0}; +read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; +read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; +read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e_irnode_nil}}; +read_only global E_Module e_module_nil = {&rdi_parsed_nil}; thread_static E_BaseCtx *e_base_ctx = 0; thread_static U64 e_base_ctx_gen = 0; diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 0709a2c6..5f49f0bc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -126,7 +126,6 @@ struct E_IRState //////////////////////////////// //~ rjf: Globals -global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRState *e_ir_state = 0; //////////////////////////////// diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 2c7554c4..9ef478ad 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -29,9 +29,7 @@ struct E_ParseState //////////////////////////////// //~ rjf: Globals -global read_only E_String2NumMap e_string2num_map_nil = {0}; -global read_only E_String2ExprMap e_string2expr_map_nil = {0}; -global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; + thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index cef40c56..5fac14f3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -512,7 +512,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *expr) +ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -522,14 +522,13 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp //- rjf: generate root expression EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); - E_Expr *root_expr = e_expr_copy(arena, expr); //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = root_key; tree.root->string = str8_zero(); - tree.root->eval = e_eval_from_expr(arena, root_expr); + tree.root->eval = eval; tree.root->type_expand_rule = &e_type_expand_rule__default; tree.root->viz_expand_rule = &ev_nil_expand_rule; tree.root->row_count = 1; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 54d7cd36..6d2155a1 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -351,7 +351,7 @@ internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *expr); +internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 81caf7b4..e2a76458 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2790,7 +2790,7 @@ rd_view_ui(Rng2F32 rect) { ev_key_set_expansion(eval_view, ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); } - block_tree = ev_block_tree_from_expr(scratch.arena, eval_view, filter, eval.expr); + block_tree = ev_block_tree_from_eval(scratch.arena, eval_view, filter, eval); block_ranges = ev_block_range_list_from_tree(scratch.arena, &block_tree); if(implicit_root && block_ranges.first != 0) { @@ -6315,7 +6315,7 @@ rd_window_frame(void) EV_BlockTree predicted_block_tree = {0}; RD_RegsScope(.view = view->id) { - predicted_block_tree = ev_block_tree_from_expr(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval.expr); + predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); } F32 row_height_px = ui_top_px_height(); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); @@ -6461,7 +6461,7 @@ rd_window_frame(void) F32 row_height_px = ui_top_px_height(); Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); - EV_BlockTree predicted_block_tree = ev_block_tree_from_expr(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval.expr); + EV_BlockTree predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval); F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); F32 max_query_height_px = content_rect_dim.y*0.8f; F32 query_height_px = max_query_height_px; From ba293509398b82a7c9de8ff261c40926fc71f9c0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 16:00:23 -0700 Subject: [PATCH 438/755] parse cache, ir-tree cache --- src/ctrl/ctrl_core.c | 1 + src/eval/eval_bundles.c | 47 ++++--- src/eval/eval_core.h | 6 +- src/eval/eval_ir.c | 103 +++++++++----- src/eval/eval_ir.h | 25 +++- src/eval/eval_parse.c | 111 +++++++++++---- src/eval/eval_parse.h | 33 ++++- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 131 ++++++++---------- src/raddbg/raddbg_core.h | 1 - src/raddbg/raddbg_eval.c | 18 ++- 11 files changed, 307 insertions(+), 171 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index eb7f3476..189ebae4 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4781,6 +4781,7 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ////////////////////////////// //- rjf: begin type evaluation // + e_parse_eval_begin(); e_type_eval_begin(); ////////////////////////////// diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index fcfca2b7..98ca8c89 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -8,7 +8,7 @@ internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) { ProfBeginFunction(); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(arena, expr); E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); String8 bytecode = e_bytecode_from_oplist(arena, &oplist); E_Interpretation interp = e_interpret(bytecode); @@ -35,10 +35,25 @@ e_eval_from_string(Arena *arena, String8 string) { ProfBeginFunction(); ProfBegin("e_eval_from_string (%.*s)", str8_varg(string)); - E_TokenArray tokens = e_token_array_from_text(arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); - E_Eval eval = e_eval_from_expr(arena, parse.expr); - e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); + E_Parse parse = e_parse_from_string(string); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(parse.expr); + E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); + String8 bytecode = e_bytecode_from_oplist(arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + E_Eval eval = + { + .value = interp.value, + .space = interp.space, + .expr = parse.expr, + .irtree = irtree, + .bytecode = bytecode, + .code = interp.code, + }; + e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); + if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT) + { + e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]); + } ProfEnd(); ProfEnd(); return eval; @@ -322,18 +337,8 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) String8 expr_text = string; str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text); - //- rjf: tokenize - E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr_text); - str8_list_pushf(scratch.arena, &strings, " tokens:\n"); - for EachIndex(idx, tokens.count) - { - E_Token token = tokens.v[idx]; - String8 token_string = str8_substr(expr_text, token.range); - str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); - } - //- rjf: parse - E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr_text, tokens); + E_Parse parse = e_push_parse_from_string(scratch.arena, expr_text); { typedef struct Task Task; struct Task @@ -342,6 +347,14 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) E_Expr *expr; S32 indent; }; + E_TokenArray tokens = parse.tokens; + str8_list_pushf(scratch.arena, &strings, " tokens:\n"); + for EachIndex(idx, tokens.count) + { + E_Token token = tokens.v[idx]; + String8 token_string = str8_substr(expr_text, token.range); + str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); + } str8_list_pushf(scratch.arena, &strings, " expr:\n"); Task start_task = {0, parse.expr, 2}; Task *first_task = &start_task; @@ -376,7 +389,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 7e361fe9..c6a8c504 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -309,12 +309,12 @@ struct E_IRTreeAndType typedef struct E_Eval E_Eval; struct E_Eval { - E_Value value; - E_Space space; E_Expr *expr; E_IRTreeAndType irtree; String8 bytecode; E_InterpretationCode code; + E_Value value; + E_Space space; E_MsgList msgs; }; @@ -647,7 +647,7 @@ read_only global E_String2NumMap e_string2num_map_nil = {0}; read_only global E_String2ExprMap e_string2expr_map_nil = {0}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e_irnode_nil}}; +read_only global E_Eval e_eval_nil = {&e_expr_nil, {&e_irnode_nil}}; read_only global E_Module e_module_nil = {&rdi_parsed_nil}; thread_static E_BaseCtx *e_base_ctx = 0; thread_static U64 e_base_ctx_gen = 0; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 73d0d69c..e355f78c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -88,6 +88,8 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); e_ir_state->string_id_map->hash_slots_count = 1024; e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); + e_ir_state->ir_cache_slots_count = 4096; + e_ir_state->ir_cache_slots = push_array(e_ir_state->arena, E_IRCacheSlot, e_ir_state->ir_cache_slots_count); String8 builtin_view_rule_names[] = { str8_lit_comp("bswap"), @@ -115,20 +117,17 @@ e_auto_hook_map_make(Arena *arena, U64 slots_count) internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) { - Temp scratch = scratch_begin(&arena, 1); E_TypeKey type_key = params->type_key; if(params->type_pattern.size != 0) { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); - E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); - type_key = irtree.type_key; + E_Parse parse = e_parse_from_string(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_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).expr; + 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); @@ -139,7 +138,6 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * { SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next); } - scratch_end(scratch); } internal E_ExprList @@ -777,7 +775,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, exprr); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); @@ -871,7 +869,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -922,7 +920,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); // rjf: try all IR trees in chain for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev) @@ -978,7 +976,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); @@ -1037,7 +1035,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); @@ -1065,11 +1063,11 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_irtree_and_type_from_expr(arena, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, cast_type_expr); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -1124,7 +1122,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -1152,7 +1150,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -1166,7 +1164,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1194,14 +1192,14 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: unary operations case E_ExprKind_Pos: { - result = e_irtree_and_type_from_expr(arena, expr->first); + result = e_push_irtree_and_type_from_expr(arena, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1234,7 +1232,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1289,8 +1287,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1513,9 +1511,9 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr); - E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1561,7 +1559,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) B32 start_disallow_chained_fastpaths = e_ir_state->disallow_chained_fastpaths; e_ir_state->disallow_chained_fastpaths = 1; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1582,7 +1580,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_expr_push_child(call, e_expr_ref(arena, arg)); } - result = e_irtree_and_type_from_expr(arena, call); + result = e_push_irtree_and_type_from_expr(arena, call); // rjf: is "raw"? -> try to return overridden tree, otherwise strip all // lens types from result; disallow auto-hooks @@ -1611,7 +1609,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Temp scratch = scratch_begin(&arena, 1); // rjf: generate result via first argument to lens - result = e_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, lhs->next); // rjf: count extra arguments U64 arg_count = 0; @@ -1645,7 +1643,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } else { - result = e_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, lhs->next); result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -1789,7 +1787,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(!string_mapped && e_ir_state->overridden_irtree != 0) { E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, e_ir_state->overridden_irtree, string); - E_IRTreeAndType access_irtree = e_irtree_and_type_from_expr(scratch.arena, access); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -2156,7 +2154,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { generated = 1; e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); - result = e_irtree_and_type_from_expr(arena, macro_expr); + result = e_push_irtree_and_type_from_expr(arena, macro_expr); e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); } } @@ -2243,13 +2241,13 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2263,7 +2261,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_irtree_and_type_from_expr(arena, rhs); + result = e_push_irtree_and_type_from_expr(arena, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); @@ -2690,3 +2688,40 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type e_expr_push_child(root, rhs_bytecode); return root; } + +//////////////////////////////// +//~ rjf: IR Cache Functions + +internal E_IRTreeAndType +e_irtree_and_type_from_expr(E_Expr *expr) +{ + U64 hash_parts[] = + { + (U64)expr, + (U64)(e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0), + }; + U64 hash = e_hash_from_string(5381, str8((U8 *)hash_parts, sizeof(hash_parts))); + U64 slot_idx = hash%e_ir_state->ir_cache_slots_count; + E_IRCacheSlot *slot = &e_ir_state->ir_cache_slots[slot_idx]; + E_IRCacheNode *node = 0; + for(E_IRCacheNode *n = slot->first; n != 0; n = n->next) + { + if(expr == n->expr && + ((e_ir_state->overridden_irtree == 0 && n->overridden_node == 0) || + (e_ir_state->overridden_irtree != 0 && n->overridden_node == e_ir_state->overridden_irtree->root))) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_ir_state->arena, E_IRCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->expr = expr; + node->overridden_node = (e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0); + node->irtree = e_push_irtree_and_type_from_expr(e_ir_state->arena, expr); + } + E_IRTreeAndType result = node->irtree; + return result; +} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 5f49f0bc..d996d710 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -99,6 +99,22 @@ struct E_IRCtx //////////////////////////////// //~ rjf: IR State +typedef struct E_IRCacheNode E_IRCacheNode; +struct E_IRCacheNode +{ + E_IRCacheNode *next; + E_Expr *expr; + E_IRNode *overridden_node; + E_IRTreeAndType irtree; +}; + +typedef struct E_IRCacheSlot E_IRCacheSlot; +struct E_IRCacheSlot +{ + E_IRCacheNode *first; + E_IRCacheNode *last; +}; + typedef struct E_IRState E_IRState; struct E_IRState { @@ -121,6 +137,8 @@ struct E_IRState E_TypeAutoHookCacheMap *type_auto_hook_cache_map; U64 string_id_gen; E_StringIDMap *string_id_map; + U64 ir_cache_slots_count; + E_IRCacheSlot *ir_cache_slots; }; //////////////////////////////// @@ -193,7 +211,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); @@ -206,4 +224,9 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); +//////////////////////////////// +//~ rjf: IR Cache Functions + +internal E_IRTreeAndType e_irtree_and_type_from_expr(E_Expr *expr); + #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index ddafb9b7..abf9e728 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -663,10 +663,38 @@ e_leaf_type_from_name(String8 name) return key; } -internal E_Parse -e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) +internal E_TypeKey +e_type_key_from_expr(E_Expr *expr) { - E_Parse parse = {0, &e_expr_nil, &e_expr_nil}; + E_TypeKey result = zero_struct; + E_ExprKind kind = expr->kind; + switch(kind) + { + // TODO(rjf): do we support E_ExprKind_Func here? + default:{}break; + case E_ExprKind_TypeIdent: + { + result = expr->type_key; + }break; + case E_ExprKind_Ptr: + { + E_TypeKey direct_type_key = e_type_key_from_expr(expr->first); + result = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type_key, 1, 0); + }break; + case E_ExprKind_Array: + { + E_Expr *child_expr = expr->first; + E_TypeKey direct_type_key = e_type_key_from_expr(child_expr); + result = e_type_key_cons_array(direct_type_key, expr->value.u64, 0); + }break; + } + return result; +} + +internal E_Parse +e_push_type_parse_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) +{ + E_Parse parse = {tokens, 0, &e_expr_nil, &e_expr_nil}; E_Token *token_it = tokens.v; //- rjf: parse unsigned marker @@ -755,13 +783,13 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) } internal E_Parse -e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count) +e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); E_Token *it = tokens.v; E_Token *it_opl = tokens.v + tokens.count; - E_Parse result = {0, &e_expr_nil, &e_expr_nil}; + E_Parse result = {tokens, 0, &e_expr_nil, &e_expr_nil}; ////////////////////////////// //- rjf: parse chain of expressions @@ -860,7 +888,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it += 1; // rjf: parse type expr - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); + E_Parse type_parse = e_push_type_parse_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); E_Expr *type = type_parse.expr; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; @@ -947,7 +975,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it += 1; // rjf: parse () contents - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.expr; it = nested_parse.last_token; @@ -976,7 +1004,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it += 1; // rjf: parse [] contents - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.expr; it = nested_parse.last_token; @@ -1168,7 +1196,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it += 1; // rjf: parse indexing expression - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + E_Parse idx_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); it = idx_expr_parse.last_token; @@ -1211,7 +1239,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); call_expr->string = callee_expr->string; e_expr_push_child(call_expr, callee_expr); - E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); + E_Parse args_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; if(args_parse.expr != &e_expr_nil) @@ -1309,7 +1337,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // precedence if(binary_precedence != 0 && binary_precedence <= max_precedence) { - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); + E_Parse rhs_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.expr; it = rhs_expr_parse.last_token; @@ -1334,7 +1362,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it += 1; // rjf: parse middle expression - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + E_Parse middle_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); it = middle_expr_parse.last_token; E_Expr *middle_expr = middle_expr_parse.expr; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); @@ -1364,7 +1392,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } // rjf: parse rhs - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + E_Parse rhs_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); if(got_colon) { it = rhs_expr_parse.last_token; @@ -1418,20 +1446,55 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } internal E_Parse -e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) -{ - ProfBegin("parse '%.*s'", str8_varg(text)); - E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); - ProfEnd(); - return parse; -} - -internal E_Parse -e_parse_expr_from_text(Arena *arena, String8 text) +e_push_parse_from_string(Arena *arena, String8 text) { Temp scratch = scratch_begin(&arena, 1); E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); - E_Parse parse = e_parse_expr_from_text_tokens(arena, text, tokens); + E_Parse parse = e_push_parse_from_string_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); scratch_end(scratch); return parse; } + +//////////////////////////////// +//~ rjf: Parse Cache Functions + +internal void +e_parse_eval_begin(void) +{ + if(e_parse_state == 0) + { + Arena *arena = arena_alloc(); + e_parse_state = push_array(arena, E_ParseState, 1); + e_parse_state->arena = arena; + e_parse_state->arena_eval_start_pos = arena_pos(e_parse_state->arena); + } + arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); + e_parse_state->cache_slots_count = 4096; + e_parse_state->cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->cache_slots_count); +} + +internal E_Parse +e_parse_from_string(String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%e_parse_state->cache_slots_count; + E_ParseCacheSlot *slot = &e_parse_state->cache_slots[slot_idx]; + E_ParseCacheNode *node = 0; + for(E_ParseCacheNode *n = slot->first; n != 0; n = n->next) + { + if(str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->string = push_str8_copy(e_parse_state->arena, string); + node->parse = e_push_parse_from_string(e_parse_state->arena, node->string); + } + E_Parse result = node->parse; + return result; +} diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 9ef478ad..418451a9 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -10,6 +10,7 @@ typedef struct E_Parse E_Parse; struct E_Parse { + E_TokenArray tokens; E_Token *last_token; E_Expr *expr; E_Expr *last_expr; @@ -19,17 +20,33 @@ struct E_Parse //////////////////////////////// //~ rjf: Parse Evaluation State +typedef struct E_ParseCacheNode E_ParseCacheNode; +struct E_ParseCacheNode +{ + E_ParseCacheNode *next; + String8 string; + E_Parse parse; +}; + +typedef struct E_ParseCacheSlot E_ParseCacheSlot; +struct E_ParseCacheSlot +{ + E_ParseCacheNode *first; + E_ParseCacheNode *last; +}; + typedef struct E_ParseState E_ParseState; struct E_ParseState { Arena *arena; U64 arena_eval_start_pos; + U64 cache_slots_count; + E_ParseCacheSlot *cache_slots; }; //////////////////////////////// //~ rjf: Globals - thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// @@ -64,9 +81,15 @@ internal String8 e_string_from_expr(Arena *arena, E_Expr *expr, String8 parent_e //~ rjf: Parsing Functions internal E_TypeKey e_leaf_type_from_name(String8 name); -internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); -internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); -internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); -internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); +internal E_TypeKey e_type_key_from_expr(E_Expr *expr); +internal E_Parse e_push_type_parse_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); +internal E_Parse e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); +internal E_Parse e_push_parse_from_string(Arena *arena, String8 text); + +//////////////////////////////// +//~ rjf: Parse Cache Functions + +internal void e_parse_eval_begin(void); +internal E_Parse e_parse_from_string(String8 string); #endif // EVAL_PARSE_H diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 6d2155a1..de41c742 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -294,7 +294,7 @@ global read_only EV_Block ev_nil_block = {0}, 0, {0}, - {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}, + {&e_expr_nil, &e_irnode_nil}, {0}, &e_type_expand_rule__default, {0}, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e2a76458..76f2a3c6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2014,7 +2014,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) type_kind == E_TypeKind_Enum)) { got_commit_data = 1; - E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).expr; + E_Expr *src_expr = e_parse_from_string(string).expr; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); @@ -2168,7 +2168,7 @@ rd_query_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).expr; + E_Expr *expr = e_parse_from_string(string).expr; if(expr->kind == E_ExprKind_LeafIdentifier && str8_match(expr->qualifier, str8_lit("query"), 0)) { @@ -5092,26 +5092,6 @@ rd_tex2dformat_from_eval(E_Eval eval) return fmt; } -internal E_Value -rd_value_from_eval_key(E_Eval eval, String8 key) -{ - E_Value value = zero_struct; - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) - { - value = e_value_from_expr(arg->first->next); - break; - } - } - } - return value; -} - //- rjf: pushing/attaching view resources internal void * @@ -11790,10 +11770,6 @@ rd_frame(void) } ProfEnd(); - //~ - //~ NOTE(rjf): NEW VVVVV - //~ - //////////////////////////// //- rjf: build base evaluation context // @@ -11822,6 +11798,7 @@ rd_frame(void) //////////////////////////// //- rjf: begin type evaluation // + e_parse_eval_begin(); e_type_eval_begin(); //////////////////////////// @@ -11929,7 +11906,7 @@ rd_frame(void) { RD_Cfg *watch = n->v; String8 expr = rd_expr_from_cfg(watch); - E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); + E_Parse parse = e_parse_from_string(expr); if(parse.msgs.max_kind == E_MsgKind_Null) { for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) @@ -12134,7 +12111,7 @@ rd_frame(void) //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' { - E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).expr; + E_Expr *expr = e_parse_from_string(str8_lit("query:current_thread.call_stack")).expr; e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("call_stack"), expr); } @@ -12271,52 +12248,6 @@ rd_frame(void) } #endif - //- rjf: gather auto-view-rules from loaded modules - RD_CfgList immediate_auto_view_rules = {0}; - CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); - for EachIndex(idx, modules.count) - { - CTRL_Entity *module = modules.v[idx]; - String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, module->handle); - U8 split_char = 0; - String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); - U64 cfg_idx = 0; - for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) - { - String8 text = text_n->string; - RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); - String8 module_name = ctrl_string_from_handle(scratch.arena, module->handle); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next, cfg_idx += 1) - { - RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfg_%I64x", module_name, cfg_idx); - rd_cfg_release_all_children(immediate_root); - rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); - rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); - } - } - } - - //- rjf: add auto-hook rules for auto-view-rules - { - RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); - RD_CfgList rules_lists[] = - { - auto_view_rules, - immediate_auto_view_rules, - }; - for EachElement(list_idx, rules_lists) - { - RD_CfgList list = rules_lists[list_idx]; - for(RD_CfgNode *n = list.first; n != 0; n = n->next) - { - RD_Cfg *rule = n->v; - String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; - String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; - e_auto_hook_map_insert_new(scratch.arena, auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); - } - } - } - //- rjf: choose set of lenses // TODO(rjf): generate via metaprogram struct @@ -12400,6 +12331,56 @@ rd_frame(void) } ev_select_expand_rule_table(expand_rule_table); + //////////////////////////// + //- rjf: gather auto-view-rules from loaded modules + // + RD_CfgList immediate_auto_view_rules = {0}; + CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + for EachIndex(idx, modules.count) + { + CTRL_Entity *module = modules.v[idx]; + String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, module->handle); + U8 split_char = 0; + String8List raddbg_data_text_parts = str8_split(scratch.arena, raddbg_data, &split_char, 1, 0); + U64 cfg_idx = 0; + for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) + { + String8 text = text_n->string; + RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); + String8 module_name = ctrl_string_from_handle(scratch.arena, module->handle); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next, cfg_idx += 1) + { + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfg_%I64x", module_name, cfg_idx); + rd_cfg_release_all_children(immediate_root); + rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); + rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); + } + } + } + + //////////////////////////// + //- rjf: add auto-hook rules for auto-view-rules + // + { + RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); + RD_CfgList rules_lists[] = + { + auto_view_rules, + immediate_auto_view_rules, + }; + for EachElement(list_idx, rules_lists) + { + RD_CfgList list = rules_lists[list_idx]; + for(RD_CfgNode *n = list.first; n != 0; n = n->next) + { + RD_Cfg *rule = n->v; + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; + String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; + e_auto_hook_map_insert_new(scratch.arena, auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + } + } + } + //////////////////////////// //- rjf: build IR evaluation context // @@ -15804,7 +15785,7 @@ Z(getting_started) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).expr; + E_Expr *expr = e_parse_from_string(src_bp_cnd).expr; ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 168f9ab3..9875452f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -952,7 +952,6 @@ internal F32 rd_view_cfg_f32_from_string(String8 string); internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval); internal Arch rd_arch_from_eval(E_Eval eval); internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval); -internal E_Value rd_value_from_eval_key(E_Eval eval, String8 key); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 84e86383..a3bd9650 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -144,7 +144,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) if(cfg_idx < cfgs->count) { String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; + exprs_out[idx] = e_parse_from_string(expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -226,7 +226,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) for(U64 idx = 0; idx < read_range_count; idx += 1) { String8 expr_string = accel->v[read_range.min + idx]; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; + exprs_out[idx] = e_parse_from_string(expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -278,7 +278,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) String8 register_name = accel->v[read_range.min + idx]; String8 register_expr = push_str8f(arena, "reg:%S", register_name); exprs_strings_out[idx] = register_name; - exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).expr; + exprs_out[idx] = e_parse_from_string(register_expr).expr; } } @@ -410,7 +410,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(wrap_child_w_meta_expr) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).expr; + E_Expr *expr = e_parse_from_string(child->first->string).expr; B32 expr_is_simple = 0; if(expr->kind == E_ExprKind_LeafU64 || expr->kind == E_ExprKind_LeafF64 || @@ -458,9 +458,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); if(!md_node_is_nil(range)) { - Temp scratch = scratch_begin(&arena, 1); - E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).expr; - E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).expr; + E_Expr *min_bound = e_parse_from_string(range->first->string).expr; + E_Expr *max_bound = e_parse_from_string(range->first->next->string).expr; E_Expr *args[] = { min_bound, @@ -471,7 +470,6 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) .direct_key = child_type_key, .count = 2, .args = args); - scratch_end(scratch); } } @@ -770,8 +768,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).expr; - E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); + E_Expr *commands = e_parse_from_string(str8_lit("query:commands")).expr; + E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(commands); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; From 23125dd3128babccd9c4659ab2db95f9aeb0d34c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 16:21:10 -0700 Subject: [PATCH 439/755] cache font raster flag settings, add additional acceleration to very common repeated cfg lookups - e.g. same window/view -> state structure N times, or same ID -> cfg N times --- src/raddbg/raddbg_core.c | 153 +++++++++++++++++++++++++-------------- src/raddbg/raddbg_core.h | 10 +++ 2 files changed, 109 insertions(+), 54 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 76f2a3c6..a80acc9a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -366,16 +366,27 @@ internal RD_Cfg * rd_cfg_from_id(RD_CfgID id) { RD_Cfg *result = &rd_nil_cfg; - U64 hash = d_hash_from_string(str8_struct(&id)); - U64 slot_idx = hash%rd_state->cfg_id_slots_count; - for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) + if(id != 0 && + id == rd_state->cfg_last_accessed_id && + id == rd_state->cfg_last_accessed->id) { - if(n->v->id == id) + result = rd_state->cfg_last_accessed; + } + else + { + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->cfg_id_slots_count; + for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) { - result = n->v; - break; + if(n->v->id == id) + { + result = n->v; + break; + } } } + rd_state->cfg_last_accessed_id = id; + rd_state->cfg_last_accessed = result; return result; } @@ -1171,6 +1182,29 @@ rd_schemas_from_name(String8 name) return schemas; } +internal String8 +rd_default_setting_from_names(String8 schema_name, String8 setting_name) +{ + String8 result = {0}; + { + MD_Node *setting_schema = &md_nil_node; + MD_NodePtrList schemas = rd_schemas_from_name(schema_name); + for(MD_NodePtrNode *n = schemas.first; n != 0 && setting_schema == &md_nil_node; n = n->next) + { + setting_schema = md_child_from_string(n->v, setting_name, 0); + } + if(setting_schema != &md_nil_node) + { + MD_Node *default_tag = md_tag_from_string(setting_schema, str8_lit("default"), 0); + if(default_tag != &md_nil_node) + { + result = default_tag->first->string; + } + } + } + return result; +} + internal String8 rd_setting_from_name(String8 name) { @@ -1193,34 +1227,13 @@ rd_setting_from_name(String8 name) result = setting->first->string; // rjf: no result -> look for default in schemas - if(result.size == 0) ProfScope("default setting schema lookup") + if(result.size == 0) { - MD_Node *schema = &md_nil_node; + result = rd_default_setting_from_names(view_cfg->string, name); + for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && result.size == 0; cfg = cfg->parent) { - MD_NodePtrList schemas = rd_schemas_from_name(view_cfg->string); - for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next) - { - schema = md_child_from_string(n->v, name, 0); - } - for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && schema == &md_nil_node; cfg = cfg->parent) - { - MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); - for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next) - { - schema = md_child_from_string(n->v, name, 0); - } - } - if(schema != &md_nil_node) - { - MD_Node *default_tag = md_tag_from_string(schema, str8_lit("default"), 0); - if(default_tag != &md_nil_node) - { - result = default_tag->first->string; - goto end_default_search; - } - } + result = rd_default_setting_from_names(cfg->string, name); } - end_default_search:; } } return result; @@ -2258,17 +2271,26 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) internal RD_ViewState * rd_view_state_from_cfg(RD_Cfg *cfg) { - RD_CfgID id = cfg->id; - U64 hash = d_hash_from_string(str8_struct(&id)); - U64 slot_idx = hash%rd_state->view_state_slots_count; - RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; RD_ViewState *view_state = &rd_nil_view_state; - for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) + RD_CfgID id = cfg->id; + if(id != 0 && + id == rd_state->view_state_last_accessed_id && + id == rd_state->view_state_last_accessed->cfg_id) { - if(v->cfg_id == id) + view_state = rd_state->view_state_last_accessed; + } + else + { + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->view_state_slots_count; + RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; + for(RD_ViewState *v = slot->first; v != 0; v = v->hash_next) { - view_state = v; - break; + if(v->cfg_id == id) + { + view_state = v; + break; + } } } if(view_state == &rd_nil_view_state) @@ -2283,6 +2305,9 @@ rd_view_state_from_cfg(RD_Cfg *cfg) view_state = push_array(rd_state->arena, RD_ViewState, 1); } MemoryCopyStruct(view_state, &rd_nil_view_state); + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->view_state_slots_count; + RD_ViewStateSlot *slot = &rd_state->view_state_slots[slot_idx]; DLLPushBack_NP(slot->first, slot->last, view_state, hash_next, hash_prev); view_state->cfg_id = id; view_state->arena = arena_alloc(); @@ -2293,6 +2318,8 @@ rd_view_state_from_cfg(RD_Cfg *cfg) { view_state->last_frame_index_touched = rd_state->frame_index; } + rd_state->view_state_last_accessed = view_state; + rd_state->view_state_last_accessed_id = id; return view_state; } @@ -5201,18 +5228,27 @@ rd_window_state_from_cfg(RD_Cfg *cfg) //- rjf: unpack RD_Cfg *window_cfg = rd_window_from_cfg(cfg); RD_CfgID id = window_cfg->id; - U64 hash = d_hash_from_string(str8_struct(&id)); - U64 slot_idx = hash%rd_state->window_state_slots_count; - RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; //- rjf: scan for existing window RD_WindowState *ws = &rd_nil_window_state; - for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) + if(id != 0 && + id == rd_state->window_state_last_accessed_id && + id == rd_state->window_state_last_accessed->cfg_id) { - if(w->cfg_id == id) + ws = rd_state->window_state_last_accessed; + } + else + { + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->window_state_slots_count; + RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; + for(RD_WindowState *w = slot->first; w != 0; w = w->hash_next) { - ws = w; - break; + if(w->cfg_id == id) + { + ws = w; + break; + } } } @@ -5288,6 +5324,9 @@ rd_window_state_from_cfg(RD_Cfg *cfg) } // rjf: hook up window links + U64 hash = d_hash_from_string(str8_struct(&id)); + U64 slot_idx = hash%rd_state->window_state_slots_count; + RD_WindowStateSlot *slot = &rd_state->window_state_slots[slot_idx]; DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); @@ -5301,6 +5340,8 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->last_frame_index_touched = rd_state->frame_index; } + rd_state->window_state_last_accessed_id = ws->cfg_id; + rd_state->window_state_last_accessed = ws; return ws; } @@ -5473,6 +5514,15 @@ rd_window_frame(void) } } + ////////////////////////////// + //- rjf: @window_frame_part compute window's font raster flags + // + { + ws->font_slot_raster_flags[RD_FontSlot_Icons] = FNT_RasterFlag_Smooth; + ws->font_slot_raster_flags[RD_FontSlot_Main] = (rd_setting_b32_from_name(str8_lit("smooth_ui_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_ui_text"))*FNT_RasterFlag_Hinted); + ws->font_slot_raster_flags[RD_FontSlot_Code] = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted); + } + ////////////////////////////// //- rjf: @window_frame_part pre-emptively rasterize common glyphs on the first frame // @@ -10283,14 +10333,9 @@ rd_font_from_slot(RD_FontSlot slot) internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot) { - FNT_RasterFlags flags = FNT_RasterFlag_Smooth|FNT_RasterFlag_Hinted; - switch(slot) - { - default:{}break; - case RD_FontSlot_Icons:{flags = FNT_RasterFlag_Smooth;}break; - case RD_FontSlot_Main: {flags = (rd_setting_b32_from_name(str8_lit("smooth_ui_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_ui_text"))*FNT_RasterFlag_Hinted);}break; - case RD_FontSlot_Code: {flags = (rd_setting_b32_from_name(str8_lit("smooth_code_text"))*FNT_RasterFlag_Smooth)|(rd_setting_b32_from_name(str8_lit("hint_code_text"))*FNT_RasterFlag_Hinted);}break; - } + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + FNT_RasterFlags flags = ws->font_slot_raster_flags[slot]; return flags; } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 9875452f..936afa92 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -501,6 +501,9 @@ struct RD_WindowState // rjf: theme (recomputed each frame) UI_Theme *theme; + // rjf: font raster flags (recomputed each frame) + FNT_RasterFlags font_slot_raster_flags[RD_FontSlot_COUNT]; + // rjf: dev interface state B32 dev_menu_is_open; @@ -700,6 +703,8 @@ struct RD_State RD_CfgSlot *cfg_id_slots; RD_CfgNode *free_cfg_id_node; U64 cfg_id_gen; + RD_CfgID cfg_last_accessed_id; + RD_Cfg *cfg_last_accessed; // rjf: window state cache U64 window_state_slots_count; @@ -708,11 +713,15 @@ struct RD_State RD_CfgID last_focused_window; RD_WindowState *first_window_state; RD_WindowState *last_window_state; + RD_CfgID window_state_last_accessed_id; + RD_WindowState *window_state_last_accessed; // rjf: view state cache U64 view_state_slots_count; RD_ViewStateSlot *view_state_slots; RD_ViewState *free_view_state; + RD_CfgID view_state_last_accessed_id; + RD_ViewState *view_state_last_accessed; // rjf: bind change Arena *bind_change_arena; @@ -870,6 +879,7 @@ internal String8 rd_path_from_cfg(RD_Cfg *cfg); internal D_Target rd_target_from_cfg(Arena *arena, RD_Cfg *cfg); internal MD_NodePtrList rd_schemas_from_name(String8 name); +internal String8 rd_default_setting_from_names(String8 schema_name, String8 setting_name); internal String8 rd_setting_from_name(String8 name); internal B32 rd_setting_b32_from_name(String8 name); From 2f7e48e5cf624e4b4cabc3c27c8ae6a61ebada22 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 17:29:31 -0700 Subject: [PATCH 440/755] first pass at unified evaluation cache --- src/ctrl/ctrl_core.c | 5 + src/eval/eval_cache.c | 256 +++++++++++++++++++++++++++++++++++++++ src/eval/eval_cache.h | 158 ++++++++++++++++++++++++ src/eval/eval_inc.c | 1 + src/eval/eval_inc.h | 1 + src/raddbg/raddbg_core.c | 5 + 6 files changed, 426 insertions(+) create mode 100644 src/eval/eval_cache.c create mode 100644 src/eval/eval_cache.h diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 189ebae4..914d1ea6 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4819,6 +4819,11 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_interpret_ctx(&scope->interpret_ctx, eval_modules_primary->rdi, thread_rip_voff); + //////////////////////////// + //- rjf: begin cached evaluations + // + e_cache_eval_begin(); + return scope; } diff --git a/src/eval/eval_cache.c b/src/eval/eval_cache.c new file mode 100644 index 00000000..c171c647 --- /dev/null +++ b/src/eval/eval_cache.c @@ -0,0 +1,256 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Basic Key Helpers + +internal B32 +e_key_match(E_Key a, E_Key b) +{ + B32 result = (a.u64 == b.u64); + return result; +} + +//////////////////////////////// +//~ rjf: Cache Initialization (Required For All Subsequent APIs) + +internal void +e_cache_eval_begin(void) +{ + if(e_cache == 0) + { + Arena *arena = arena_alloc(); + e_cache = push_array(arena, E_Cache, 1); + e_cache->arena = arena; + e_cache->arena_eval_start_pos = arena_pos(arena); + } + 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; +} + +//////////////////////////////// +//~ 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); + node->key = key; + SLLQueuePush_N(slot->first, slot->last, node, string_next); + SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next); + node->bundle.parent_key = parent_key; + node->bundle.string = push_str8_copy(e_cache->arena, string); + } + return node->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; +} + +//- 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->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_IRTreeAndType *prev_overridden = e_ir_state->overridden_irtree; + e_ir_state->overridden_irtree = &overridden; + E_Parse parse = e_parse_from_bundle(bundle); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, parse.expr); + e_ir_state->overridden_irtree = prev_overridden; + } + 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 = + { + .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; +} + +//- rjf: string-based helpers +// TODO(rjf): (replace the old bundle APIs here) + +//////////////////////////////// +//~ 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; +} diff --git a/src/eval/eval_cache.h b/src/eval/eval_cache.h new file mode 100644 index 00000000..8d27b4e4 --- /dev/null +++ b/src/eval/eval_cache.h @@ -0,0 +1,158 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef EVAL_CACHE_H +#define EVAL_CACHE_H + +//////////////////////////////// +//~ rjf: Cache Key Type + +typedef struct E_Key E_Key; +struct E_Key +{ + U64 u64; +}; + +//////////////////////////////// +//~ rjf: Cache Types + +typedef U32 E_CacheBundleFlags; +enum +{ + E_CacheBundleFlag_Parse = (1<<0), + E_CacheBundleFlag_IRTree = (1<<1), + E_CacheBundleFlag_Bytecode = (1<<2), + E_CacheBundleFlag_Interpret = (1<<3), +}; + +typedef struct E_CacheBundle E_CacheBundle; +struct E_CacheBundle +{ + E_CacheBundleFlags flags; + E_Key parent_key; + String8 string; + E_Parse parse; + E_IRTreeAndType irtree; + String8 bytecode; + E_Interpretation interpretation; +}; + +typedef struct E_CacheNode E_CacheNode; +struct E_CacheNode +{ + E_CacheNode *string_next; + E_CacheNode *key_next; + E_Key key; + E_CacheBundle bundle; +}; + +typedef struct E_CacheLookup E_CacheLookup; +struct E_CacheLookup +{ + E_CacheNode *node; + U64 hash; +}; + +typedef struct E_CacheSlot E_CacheSlot; +struct E_CacheSlot +{ + E_CacheNode *first; + E_CacheNode *last; +}; + +typedef struct E_CacheParentNode E_CacheParentNode; +struct E_CacheParentNode +{ + E_CacheParentNode *next; + E_Key key; +}; + +typedef struct E_Cache E_Cache; +struct E_Cache +{ + Arena *arena; + U64 arena_eval_start_pos; + U64 key_id_gen; + U64 key_slots_count; + E_CacheSlot *key_slots; + U64 string_slots_count; + E_CacheSlot *string_slots; + E_CacheParentNode *top_parent_node; + E_CacheParentNode *free_parent_node; +}; + +//////////////////////////////// +//~ rjf: Globals + +thread_static E_Cache *e_cache = 0; +read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; + +//////////////////////////////// +//~ rjf: Basic Key Helpers + +internal B32 e_key_match(E_Key a, E_Key b); + +//////////////////////////////// +//~ rjf: Cache Initialization (Required For All Subsequent APIs) + +internal void e_cache_eval_begin(void); + +//////////////////////////////// +//~ rjf: Cache Accessing Functions +// +// The cache uses a unique keying mechanism to refer to some evaluation at +// many layers of analysis. +// +// key +// ________________________________________________ +// / / | \ +// text -> expression -> ir tree and type -> interpretation result +// +// Each one of these calls refers to one stage in this pipeline. The cache will +// only compute what is needed on-demand. If you ask for the full evaluation, +// which is a bundle of artifacts at all layers of analysis, then all stages +// will be computed. +// +// One wrinkle here is that the IR tree generation stage is implicitly +// parameterized by the "overridden" IR tree - this is to enable "parent +// expressions", e.g. `$.x`, or simply `x` assuming `foo` has such a member, +// in the context of some struct `foo` evaluates to the same thing as `foo.x`. +// So even though the primary API shape is based around singular keys, the +// "parent key stack" also implicitly parameterizes all of these (partly +// because it is not relevant in 99% of cases). + +//- rjf: parent key stack +internal E_Key e_parent_key_push(E_Key key); +internal E_Key e_parent_key_pop(void); + +//- rjf: key construction +internal E_Key e_key_from_string(String8 string); +internal E_Key e_key_from_stringf(char *fmt, ...); + +//- rjf: base key -> bundle helper +internal E_CacheBundle *e_cache_bundle_from_key(E_Key key); + +//- rjf: bundle -> pipeline stage outputs +internal E_Parse e_parse_from_bundle(E_CacheBundle *bundle); +internal E_IRTreeAndType e_irtree_from_bundle(E_CacheBundle *bundle); +internal String8 e_bytecode_from_bundle(E_CacheBundle *bundle); +internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); +#define e_parse_from_key(key) e_parse_from_bundle(e_cache_bundle_from_key(key)) +#define e_irtree_from_key(key) e_irtree_from_bundle(e_cache_bundle_from_key(key)) +#define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) +#define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) + +//- rjf: comprehensive bundle +internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); +#define e_eval_from_key(key) e_eval_from_bundle(e_cache_bundle_from_key(key)) + +//- rjf: string-based helpers +// TODO(rjf): (replace the old bundle APIs here) + +//////////////////////////////// +//~ rjf: Key Extension Functions + +internal E_Key e_key_wrap(E_Key key, String8 string); +internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); + +#endif // EVAL_CACHE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c index c4d2222c..2a74cc6b 100644 --- a/src/eval/eval_inc.c +++ b/src/eval/eval_inc.c @@ -7,3 +7,4 @@ #include "eval/eval_ir.c" #include "eval/eval_interpret.c" #include "eval/eval_bundles.c" +#include "eval/eval_cache.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h index 2c46335b..882fff88 100644 --- a/src/eval/eval_inc.h +++ b/src/eval/eval_inc.h @@ -10,5 +10,6 @@ #include "eval/eval_ir.h" #include "eval/eval_interpret.h" #include "eval/eval_bundles.h" +#include "eval/eval_cache.h" #endif // EVAL_INC_H diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a80acc9a..0a4e3185 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12460,6 +12460,11 @@ rd_frame(void) } e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); + //////////////////////////// + //- rjf: begin cached evaluations + // + e_cache_eval_begin(); + //////////////////////////// //- rjf: autosave if needed // From c341fb6c002408d01ffa69ab36b6981a567a2645 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 23 Apr 2025 21:26:32 -0700 Subject: [PATCH 441/755] work on next release notes --- src/raddbg/raddbg_main.c | 112 +++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 35 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 547da72b..dca81f18 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -4,50 +4,92 @@ //////////////////////////////// //~ rjf: 0.9.16 release notes // -// - Auto view rules have been upgraded to support type pattern-matching. This -// makes them usable for generic types in various languages. This -// pattern-matching is done by using `?` characters in a pattern, to specify -// placeholders for various parts of a type name. For example, the pattern -// `DynamicArray` would match `DynamicArray`, `DynamicArray`, -// and so on. -// - The `slice` view rule has been streamlined and simplified. When an -// expression with a `slice` view rule is expanded, it will simply expand to -// the slice's contents, which matches the behavior with static arrays. -// - The `slice` view rule now supports `first, one_past_last` pointer pairs, -// as well as `base_pointer, length` pairs. -// - The syntax for view rules has changed to improve its familiarity, -// usability, and to improve its consistency with the rest of the evaluation -// language. It now appears like function calls, and many arguments no longer -// need to be explicitly named. For example, instead of -// `bitmap:{w:1024, h:1024}`, the new view rule syntax would be -// `bitmap(1024, 1024)`. Commas can still be omitted. Named arguments are -// still possible (and required in some cases): -// `disasm(size=1024, arch=x64)`. If there are no arguments required for a -// view rule, like `hex`, then no parentheses are needed. +// - "View rules", now simply called "views", have been formally integrated +// into the debugger evaluation language. They now appear similar to function +// calls, and are expressed directly within an expression. For example, an +// expression `dynamic_array` with a view rule `slice` from prior versions +// would now be expressed as `slice(dynamic_array)`. Alternatively, views +// can be expressed with similar syntax to method calls: +// `dynamic_array.slice()`. Many views can still be attached to a single +// expression, like `dynamic_array.slice().hex()` (equivalent to +// `hex(slice(dynamic_array))`. The first argument to a view is the +// expression to which the view should apply. Some views take additional +// parameters, like `bitmap(base_pointer, width, height)`. Named parameters, +// required in some cases (e.g. the `fmt`/format parameter for `bitmap`), are +// expressed using `name = value` syntax: +// `bitmap(base, width, height, fmt=bgra8)`. +// - "Auto view rules", now simply called "type views", have been upgraded +// to support type pattern-matching. This makes them usable for generic types +// in various languages. This pattern-matching is done by using `?` characters +// in a pattern, to specify placeholders for various parts of a type name. +// For example, the pattern `DynamicArray` would match +// `DynamicArray`, `DynamicArray`, and so on. +// - Type views have been upgraded to support a larger number of possibilities. +// Instead of mapping to a set of views which are applied to some other +// expression, type views can remap the expression itself, and apply +// additional views. These expressions can refer to the originating +// expression either explicitly using the `$` character, or implicitly in +// some cases. For instance, a type like +// `struct Bitmap {U8 *base; U32 width; U32 height;};` can be used in a type +// view which maps `Bitmap` to `bitmap(base, width, height)`. In this case, +// `base`, `width`, and `height` are recognized as being member names of +// `Bitmap`. This is equivalent to `bitmap($.base, $.width, $.height)`. +// - The F1 command palette has been replaced by a substantially more powerful +// "everything palette" (referred to in the UI simply as "palette"), opened +// with the `Open Palette` command. This palette lists commands and allows +// the editing of bindings, just like the old command palette (although it +// now also supports searching for command bindings themselves, in addition +// to the original searching support for command names and descriptions). +// However, this palette now also lists: targets, breakpoints, recent files, +// recent projects, settings (including tab settings, window settings, user +// settings, project settings), attached processes, threads, modules, +// functions, types, and global variables. This can be used to quickly search +// for a large set of possible things, and either jump to them or edit them. +// - The tab right-click menu has been upgraded to show all tab-related +// settings, including ones specially-defined for specific visualizers (like +// the width and height parameters to the bitmap visualizer). +// - The debugger UI now more flexibly supports a larger set of possible +// combinations of font sizes. Each tab can have a specific font size set, +// which can be edited within the palette or a tab's right-click menu. If a +// tab has no per-tab font size set, then it inherits the setting from the +// window's font size. +// - Debugger settings have been upgraded to be stored as expressions, rather +// than being locked to a specific value. These expressions are evaluated, +// like any other expression, and their evaluated value is used when the +// setting value is actually needed. +// - The `slice` view has been streamlined and simplified. When an expression +// with a `slice` view is expanded, it will simply expand to the slice's +// contents, which matches the behavior with static arrays. +// - The `slice` view now supports `first, one_past_last` pointer pairs, as +// well as `base_pointer, length` pairs. +// - The debugger now displays toggle switches as an additional visualization +// and editor for all boolean evaluations. +// - A new `range1` view has been added, which expresses bounds for some scalar +// value. When this view is used in an evaluation, the debugger will +// visualize the evaluation value with a slider, which can be used to edit +// the value as well. // - The hover evaluation feature has been majorly upgraded to support all -// features normally available in the `Watch` view. Hover evaluations now -// explicitly show type information, and contain a view rule column, which -// can be edited in a way identical to the `Watch` view. -// - Added "auto tabs", which are colored differently than normal tabs. These -// tabs are automatically opened by the debugger when snapping to source code -// which is not already opened. They are automatically replaced and recycled -// when the debugger needs to snap to new locations. This will greatly reduce -// the number of unused source code tabs accumulated throughout a debugging -// session. These tabs can still be promoted to permanent tabs, in which case -// they'll stay around until manually closed. -// - The `Scheduler` view has been removed, in favor of three separate views, +// features normally available in the `Watch` view. +// - Added "transient tabs", which are colored differently than normal tabs. +// These tabs are automatically opened by the debugger when snapping to +// source code which is not already opened. They are automatically replaced +// and recycled when the debugger needs to snap to new locations. This will +// greatly reduce the number of unused source code tabs accumulated +// throughout a debugging session. These tabs can still be promoted to +// permanent tabs, in which case they'll stay around until manually closed. +// - The `Scheduler` tab has been removed, in favor of three separate tabs, // which present various versions of the same information: `Threads`, // `Processes`, and `Machines`. The justification for this is that the // common case is debugging a small number of programs, usually 1, and for -// those purposes, the `Threads` view is sufficient if not desirable, and +// those purposes, the `Threads` tab is sufficient if not desirable, and // the extra information provided by `Processes` and `Machines`, while useful -// in other contexts, is not useful in that common case. The `Machines` view +// in other contexts, is not useful in that common case. The `Machines` tab // now shows a superset of the information previously found in the -// `Scheduler` view. +// `Scheduler` tab. // - The two separate interfaces for editing threads, breakpoints, and watch // pins (the right-click context menu and the dedicated tabs) have been // merged. Both interfaces support exactly the same features in exactly the -// same way. +// same way. The same interface is also accessible through the palette. // - Added the ability to add a list of environment strings to targets. // - The debugger releases are now packaged with a `raddbg_markup.h` // single-header library which contains a number of source code markup tools From 9bb592786a5356f9f29ee2c6c1163359456f21b4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 09:07:29 -0700 Subject: [PATCH 442/755] eliminate all old evaluation bundled helpers, eliminate old fragmented eval caches; move all to unified evaluation cache --- src/ctrl/ctrl_core.c | 29 +- src/ctrl/ctrl_core.h | 3 + src/eval/eval_bundles.c | 62 +- src/eval/eval_bundles.h | 2 + src/eval/eval_cache.c | 256 ------- src/eval/eval_cache.h | 158 ----- src/eval/eval_core.c | 630 +++++++++++++++++- src/eval/eval_core.h | 474 ++++++++++++- src/eval/eval_inc.c | 1 - src/eval/eval_inc.h | 1 - src/eval/eval_interpret.h | 11 - src/eval/eval_ir.c | 464 ++----------- src/eval/eval_ir.h | 130 +--- src/eval/eval_parse.c | 44 -- src/eval/eval_parse.h | 51 -- src/eval/eval_types.c | 129 ++-- src/eval/eval_types.h | 141 ---- .../eval_visualization_core.c | 12 +- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_core.c | 118 ++-- src/raddbg/raddbg_core.h | 3 + src/raddbg/raddbg_eval.c | 20 +- src/raddbg/raddbg_views.c | 59 +- src/raddbg/raddbg_widgets.c | 4 +- 24 files changed, 1315 insertions(+), 1489 deletions(-) delete mode 100644 src/eval/eval_cache.c delete mode 100644 src/eval/eval_cache.h diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 914d1ea6..a8bb074b 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -217,6 +217,16 @@ ctrl_handle_from_string(String8 string) return handle; } +internal E_Eval +ctrl_eval_from_handle(CTRL_Handle handle) +{ + Temp scratch = scratch_begin(0, 0); + String8 string = ctrl_string_from_handle(scratch.arena, handle); + E_Eval eval = e_eval_from_string(string); + scratch_end(scratch); + return eval; +} + //////////////////////////////// //~ rjf: Trap Type Functions @@ -1412,6 +1422,7 @@ ctrl_init(void) scratch_end(scratch); } ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); + ctrl_state->ctrl_thread_eval_cache = e_cache_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); ctrl_state->user_entry_point_arena = arena_alloc(); ctrl_state->dbg_dir_arena = arena_alloc(); @@ -4754,6 +4765,11 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } } + ////////////////////////////// + //- rjf: select evaluation cache + // + e_select_cache(ctrl_state->ctrl_thread_eval_cache); + ////////////////////////////// //- rjf: build base evaluation context // @@ -4778,12 +4794,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_base_ctx(&scope->base_ctx); - ////////////////////////////// - //- rjf: begin type evaluation - // - e_parse_eval_begin(); - e_type_eval_begin(); - ////////////////////////////// //- rjf: build IR evaluation context // @@ -4819,11 +4829,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_interpret_ctx(&scope->interpret_ctx, eval_modules_primary->rdi, thread_rip_voff); - //////////////////////////// - //- rjf: begin cached evaluations - // - e_cache_eval_begin(); - return scope; } @@ -5886,7 +5891,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) E_Eval eval = zero_struct; ProfScope("evaluate expression") { - eval = e_eval_from_string(temp.arena, condition_n->string); + eval = e_eval_from_string(condition_n->string); } // rjf: interpret evaluation diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index f5127226..84af61bb 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -709,6 +709,7 @@ struct CTRL_State OS_Handle ctrl_thread; Log *ctrl_thread_log; CTRL_EntityStore *ctrl_thread_entity_store; + E_Cache *ctrl_thread_eval_cache; Arena *dmn_event_arena; DMN_EventNode *first_dmn_event_node; DMN_EventNode *last_dmn_event_node; @@ -769,6 +770,8 @@ internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b); internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair); internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle); +internal CTRL_Handle ctrl_handle_from_string(String8 string); +internal E_Eval ctrl_eval_from_handle(CTRL_Handle handle); //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 98ca8c89..b05ea40c 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -4,6 +4,7 @@ //////////////////////////////// //~ rjf: Bundled Evaluation Functions +#if 0 internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) { @@ -144,63 +145,6 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) 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<> 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; -} - internal E_Value e_value_from_string(String8 string) { @@ -267,6 +211,8 @@ e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...) return result; } +#endif + internal U64 e_base_offset_from_eval(E_Eval eval) { @@ -389,7 +335,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index f56457b1..3d271963 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -7,6 +7,7 @@ //////////////////////////////// //~ rjf: Bundled Evaluation Functions +#if 0 internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); internal E_Eval e_eval_from_string(Arena *arena, String8 string); internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); @@ -18,6 +19,7 @@ internal E_Value e_value_from_expr(E_Expr *expr); internal E_Value e_value_from_eval(E_Eval eval); internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string); internal E_Eval e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...);; +#endif internal U64 e_base_offset_from_eval(E_Eval eval); internal Rng1U64 e_range_from_eval(E_Eval eval); diff --git a/src/eval/eval_cache.c b/src/eval/eval_cache.c deleted file mode 100644 index c171c647..00000000 --- a/src/eval/eval_cache.c +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Basic Key Helpers - -internal B32 -e_key_match(E_Key a, E_Key b) -{ - B32 result = (a.u64 == b.u64); - return result; -} - -//////////////////////////////// -//~ rjf: Cache Initialization (Required For All Subsequent APIs) - -internal void -e_cache_eval_begin(void) -{ - if(e_cache == 0) - { - Arena *arena = arena_alloc(); - e_cache = push_array(arena, E_Cache, 1); - e_cache->arena = arena; - e_cache->arena_eval_start_pos = arena_pos(arena); - } - 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; -} - -//////////////////////////////// -//~ 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); - node->key = key; - SLLQueuePush_N(slot->first, slot->last, node, string_next); - SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next); - node->bundle.parent_key = parent_key; - node->bundle.string = push_str8_copy(e_cache->arena, string); - } - return node->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; -} - -//- 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->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_IRTreeAndType *prev_overridden = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &overridden; - E_Parse parse = e_parse_from_bundle(bundle); - bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, parse.expr); - e_ir_state->overridden_irtree = prev_overridden; - } - 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 = - { - .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; -} - -//- rjf: string-based helpers -// TODO(rjf): (replace the old bundle APIs here) - -//////////////////////////////// -//~ 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; -} diff --git a/src/eval/eval_cache.h b/src/eval/eval_cache.h deleted file mode 100644 index 8d27b4e4..00000000 --- a/src/eval/eval_cache.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_CACHE_H -#define EVAL_CACHE_H - -//////////////////////////////// -//~ rjf: Cache Key Type - -typedef struct E_Key E_Key; -struct E_Key -{ - U64 u64; -}; - -//////////////////////////////// -//~ rjf: Cache Types - -typedef U32 E_CacheBundleFlags; -enum -{ - E_CacheBundleFlag_Parse = (1<<0), - E_CacheBundleFlag_IRTree = (1<<1), - E_CacheBundleFlag_Bytecode = (1<<2), - E_CacheBundleFlag_Interpret = (1<<3), -}; - -typedef struct E_CacheBundle E_CacheBundle; -struct E_CacheBundle -{ - E_CacheBundleFlags flags; - E_Key parent_key; - String8 string; - E_Parse parse; - E_IRTreeAndType irtree; - String8 bytecode; - E_Interpretation interpretation; -}; - -typedef struct E_CacheNode E_CacheNode; -struct E_CacheNode -{ - E_CacheNode *string_next; - E_CacheNode *key_next; - E_Key key; - E_CacheBundle bundle; -}; - -typedef struct E_CacheLookup E_CacheLookup; -struct E_CacheLookup -{ - E_CacheNode *node; - U64 hash; -}; - -typedef struct E_CacheSlot E_CacheSlot; -struct E_CacheSlot -{ - E_CacheNode *first; - E_CacheNode *last; -}; - -typedef struct E_CacheParentNode E_CacheParentNode; -struct E_CacheParentNode -{ - E_CacheParentNode *next; - E_Key key; -}; - -typedef struct E_Cache E_Cache; -struct E_Cache -{ - Arena *arena; - U64 arena_eval_start_pos; - U64 key_id_gen; - U64 key_slots_count; - E_CacheSlot *key_slots; - U64 string_slots_count; - E_CacheSlot *string_slots; - E_CacheParentNode *top_parent_node; - E_CacheParentNode *free_parent_node; -}; - -//////////////////////////////// -//~ rjf: Globals - -thread_static E_Cache *e_cache = 0; -read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; - -//////////////////////////////// -//~ rjf: Basic Key Helpers - -internal B32 e_key_match(E_Key a, E_Key b); - -//////////////////////////////// -//~ rjf: Cache Initialization (Required For All Subsequent APIs) - -internal void e_cache_eval_begin(void); - -//////////////////////////////// -//~ rjf: Cache Accessing Functions -// -// The cache uses a unique keying mechanism to refer to some evaluation at -// many layers of analysis. -// -// key -// ________________________________________________ -// / / | \ -// text -> expression -> ir tree and type -> interpretation result -// -// Each one of these calls refers to one stage in this pipeline. The cache will -// only compute what is needed on-demand. If you ask for the full evaluation, -// which is a bundle of artifacts at all layers of analysis, then all stages -// will be computed. -// -// One wrinkle here is that the IR tree generation stage is implicitly -// parameterized by the "overridden" IR tree - this is to enable "parent -// expressions", e.g. `$.x`, or simply `x` assuming `foo` has such a member, -// in the context of some struct `foo` evaluates to the same thing as `foo.x`. -// So even though the primary API shape is based around singular keys, the -// "parent key stack" also implicitly parameterizes all of these (partly -// because it is not relevant in 99% of cases). - -//- rjf: parent key stack -internal E_Key e_parent_key_push(E_Key key); -internal E_Key e_parent_key_pop(void); - -//- rjf: key construction -internal E_Key e_key_from_string(String8 string); -internal E_Key e_key_from_stringf(char *fmt, ...); - -//- rjf: base key -> bundle helper -internal E_CacheBundle *e_cache_bundle_from_key(E_Key key); - -//- rjf: bundle -> pipeline stage outputs -internal E_Parse e_parse_from_bundle(E_CacheBundle *bundle); -internal E_IRTreeAndType e_irtree_from_bundle(E_CacheBundle *bundle); -internal String8 e_bytecode_from_bundle(E_CacheBundle *bundle); -internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); -#define e_parse_from_key(key) e_parse_from_bundle(e_cache_bundle_from_key(key)) -#define e_irtree_from_key(key) e_irtree_from_bundle(e_cache_bundle_from_key(key)) -#define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) -#define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) - -//- rjf: comprehensive bundle -internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); -#define e_eval_from_key(key) e_eval_from_bundle(e_cache_bundle_from_key(key)) - -//- rjf: string-based helpers -// TODO(rjf): (replace the old bundle APIs here) - -//////////////////////////////// -//~ rjf: Key Extension Functions - -internal E_Key e_key_wrap(E_Key key, String8 string); -internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); - -#endif // EVAL_CACHE_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 78892efa..7e8d5757 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -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<> 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; } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index c6a8c504..3893e0ec 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -4,6 +4,15 @@ #ifndef EVAL_CORE_H #define EVAL_CORE_H +//////////////////////////////// +//~ rjf: Evaluation Key Type + +typedef struct E_Key E_Key; +struct E_Key +{ + U64 u64; +}; + //////////////////////////////// //~ rjf: Messages @@ -309,6 +318,7 @@ struct E_IRTreeAndType typedef struct E_Eval E_Eval; struct E_Eval { + E_Key key; E_Expr *expr; E_IRTreeAndType irtree; String8 bytecode; @@ -417,7 +427,7 @@ struct E_TypeExpandInfo #define E_TYPE_IREXT_FUNCTION_DEF(name) internal E_TYPE_IREXT_FUNCTION_SIG(E_TYPE_IREXT_FUNCTION_NAME(name)) typedef E_TYPE_IREXT_FUNCTION_SIG(E_TypeIRExtFunctionType); -#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree) +#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_IRTreeAndType *overridden, E_Expr *expr, E_IRTreeAndType *lhs_irtree) #define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name #define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) typedef E_TYPE_ACCESS_FUNCTION_SIG(E_TypeAccessFunctionType); @@ -473,6 +483,44 @@ struct E_Type E_TypeExpandRule expand; }; +//////////////////////////////// +//~ rjf: Constructed Type Types + +typedef struct E_ConsTypeParams E_ConsTypeParams; +struct E_ConsTypeParams +{ + Arch arch; + E_TypeKind kind; + E_TypeFlags flags; + String8 name; + E_TypeKey direct_key; + U64 count; + U64 depth; + E_Member *members; + E_EnumVal *enum_vals; + E_Expr **args; + E_TypeIRExtFunctionType *irext; + E_TypeAccessFunctionType *access; + E_TypeExpandRule expand; +}; + +typedef struct E_ConsTypeNode E_ConsTypeNode; +struct E_ConsTypeNode +{ + E_ConsTypeNode *key_next; + E_ConsTypeNode *content_next; + E_TypeKey key; + E_ConsTypeParams params; + U64 byte_size; +}; + +typedef struct E_ConsTypeSlot E_ConsTypeSlot; +struct E_ConsTypeSlot +{ + E_ConsTypeNode *first; + E_ConsTypeNode *last; +}; + //////////////////////////////// //~ rjf: Modules @@ -614,6 +662,8 @@ struct E_AutoHookParams typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); +//- rjf: base context + typedef struct E_BaseCtx E_BaseCtx; struct E_BaseCtx { @@ -635,6 +685,300 @@ struct E_BaseCtx E_SpaceRWFunction *space_write; }; +//- rjf: ir generation context + +typedef struct E_IRCtx E_IRCtx; +struct E_IRCtx +{ + E_String2NumMap *regs_map; + E_String2NumMap *reg_alias_map; + E_String2NumMap *locals_map; // (within `primary_module`) + E_String2NumMap *member_map; // (within `primary_module`) + E_String2ExprMap *macro_map; + E_AutoHookMap *auto_hook_map; +}; + +//////////////////////////////// +//~ rjf: Parse Results + +typedef struct E_Parse E_Parse; +struct E_Parse +{ + E_TokenArray tokens; + E_Token *last_token; + E_Expr *expr; + E_Expr *last_expr; + E_MsgList msgs; +}; + +//////////////////////////////// +//~ rjf: Bytecode Interpretation Types + +typedef struct E_Interpretation E_Interpretation; +struct E_Interpretation +{ + E_Value value; + E_Space space; + E_InterpretationCode code; +}; + +//////////////////////////////// +//~ rjf: Core Evaluation Cache Types + +//- rjf: unpacked type cache + +typedef struct E_TypeCacheNode E_TypeCacheNode; +struct E_TypeCacheNode +{ + E_TypeCacheNode *next; + E_TypeKey key; + E_Type *type; +}; + +typedef struct E_TypeCacheSlot E_TypeCacheSlot; +struct E_TypeCacheSlot +{ + E_TypeCacheNode *first; + E_TypeCacheNode *last; +}; + +//- rjf: member lookup cache types + +typedef struct E_MemberHashNode E_MemberHashNode; +struct E_MemberHashNode +{ + E_MemberHashNode *next; + U64 member_idx; +}; + +typedef struct E_MemberHashSlot E_MemberHashSlot; +struct E_MemberHashSlot +{ + E_MemberHashNode *first; + E_MemberHashNode *last; +}; + +typedef struct E_MemberFilterNode E_MemberFilterNode; +struct E_MemberFilterNode +{ + E_MemberFilterNode *next; + String8 filter; + E_MemberArray members_filtered; +}; + +typedef struct E_MemberFilterSlot E_MemberFilterSlot; +struct E_MemberFilterSlot +{ + E_MemberFilterNode *first; + E_MemberFilterNode *last; +}; + +typedef struct E_MemberCacheNode E_MemberCacheNode; +struct E_MemberCacheNode +{ + E_MemberCacheNode *next; + E_TypeKey key; + E_MemberArray members; + U64 member_hash_slots_count; + E_MemberHashSlot *member_hash_slots; + U64 member_filter_slots_count; + E_MemberFilterSlot *member_filter_slots; +}; + +typedef struct E_MemberCacheSlot E_MemberCacheSlot; +struct E_MemberCacheSlot +{ + E_MemberCacheNode *first; + E_MemberCacheNode *last; +}; + +//- rjf: used expression map + +typedef struct E_UsedExprNode E_UsedExprNode; +struct E_UsedExprNode +{ + E_UsedExprNode *next; + E_UsedExprNode *prev; + E_Expr *expr; +}; + +typedef struct E_UsedExprSlot E_UsedExprSlot; +struct E_UsedExprSlot +{ + E_UsedExprNode *first; + E_UsedExprNode *last; +}; + +typedef struct E_UsedExprMap E_UsedExprMap; +struct E_UsedExprMap +{ + U64 slots_count; + E_UsedExprSlot *slots; +}; + +//- rjf: type key -> auto hook expression list cache + +typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; +struct E_TypeAutoHookCacheNode +{ + E_TypeAutoHookCacheNode *next; + E_TypeKey key; + E_ExprList exprs; +}; + +typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; +struct E_TypeAutoHookCacheSlot +{ + E_TypeAutoHookCacheNode *first; + E_TypeAutoHookCacheNode *last; +}; + +typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; +struct E_TypeAutoHookCacheMap +{ + U64 slots_count; + E_TypeAutoHookCacheSlot *slots; +}; + +//- rjf: string ID cache + +typedef struct E_StringIDNode E_StringIDNode; +struct E_StringIDNode +{ + E_StringIDNode *hash_next; + E_StringIDNode *id_next; + U64 id; + String8 string; +}; + +typedef struct E_StringIDSlot E_StringIDSlot; +struct E_StringIDSlot +{ + E_StringIDNode *first; + E_StringIDNode *last; +}; + +typedef struct E_StringIDMap E_StringIDMap; +struct E_StringIDMap +{ + U64 id_slots_count; + E_StringIDSlot *id_slots; + U64 hash_slots_count; + E_StringIDSlot *hash_slots; +}; + +//- rjf: cache evaluation bundles + +typedef U32 E_CacheBundleFlags; +enum +{ + E_CacheBundleFlag_Parse = (1<<0), + E_CacheBundleFlag_IRTree = (1<<1), + E_CacheBundleFlag_Bytecode = (1<<2), + E_CacheBundleFlag_Interpret = (1<<3), +}; + +typedef struct E_CacheBundle E_CacheBundle; +struct E_CacheBundle +{ + E_CacheBundleFlags flags; + E_Key key; + E_Key parent_key; + String8 string; + E_Parse parse; + E_IRTreeAndType irtree; + String8 bytecode; + E_Interpretation interpretation; +}; + +typedef struct E_CacheNode E_CacheNode; +struct E_CacheNode +{ + E_CacheNode *string_next; + E_CacheNode *key_next; + E_CacheBundle bundle; +}; + +typedef struct E_CacheLookup E_CacheLookup; +struct E_CacheLookup +{ + E_CacheNode *node; + U64 hash; +}; + +typedef struct E_CacheSlot E_CacheSlot; +struct E_CacheSlot +{ + E_CacheNode *first; + E_CacheNode *last; +}; + +//- rjf: parent stack + +typedef struct E_CacheParentNode E_CacheParentNode; +struct E_CacheParentNode +{ + E_CacheParentNode *next; + E_Key key; +}; + +//- rjf: main cache state type + +typedef struct E_Cache E_Cache; +struct E_Cache +{ + //- rjf: root arena + Arena *arena; + U64 arena_eval_start_pos; + + //- rjf: key ID generation counter + U64 key_id_gen; + + //- rjf: key -> bundle, string -> bundle tables + U64 key_slots_count; + E_CacheSlot *key_slots; + U64 string_slots_count; + E_CacheSlot *string_slots; + + //- rjf: parent stack + E_CacheParentNode *top_parent_node; + E_CacheParentNode *free_parent_node; + + //- rjf: unpacked context + RDI_Procedure *thread_ip_procedure; + + //- rjf: [types] JIT-constructed types tables + U64 cons_id_gen; + U64 cons_content_slots_count; + U64 cons_key_slots_count; + E_ConsTypeSlot *cons_content_slots; + E_ConsTypeSlot *cons_key_slots; + + //- rjf: [types] build-in constructed type keys + E_TypeKey file_type_key; + E_TypeKey folder_type_key; + + //- rjf: [types] member cache table + U64 member_cache_slots_count; + E_MemberCacheSlot *member_cache_slots; + + //- rjf: [types] unpacked type cache + U64 type_cache_slots_count; + E_TypeCacheSlot *type_cache_slots; + + //- rjf: [ir] ir gen options + B32 disallow_autohooks; + B32 disallow_chained_fastpaths; + + //- rjf: [ir] ir caches + E_UsedExprMap *used_expr_map; + E_TypeAutoHookCacheMap *type_auto_hook_cache_map; + + //- rjf: [ir] string ID cache + U64 string_id_gen; + E_StringIDMap *string_id_map; +}; + //////////////////////////////// //~ rjf: Generated Code @@ -647,18 +991,33 @@ read_only global E_String2NumMap e_string2num_map_nil = {0}; read_only global E_String2ExprMap e_string2expr_map_nil = {0}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -read_only global E_Eval e_eval_nil = {&e_expr_nil, {&e_irnode_nil}}; +read_only global E_Eval e_eval_nil = {{0}, &e_expr_nil, {&e_irnode_nil}}; read_only global E_Module e_module_nil = {&rdi_parsed_nil}; +read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; thread_static E_BaseCtx *e_base_ctx = 0; -thread_static U64 e_base_ctx_gen = 0; +thread_static E_IRCtx *e_ir_ctx = 0; +thread_static E_Cache *e_cache = 0; //////////////////////////////// -//~ rjf: Basic Helper Functions +//~ rjf: Basic Helpers internal U64 e_hash_from_string(U64 seed, String8 string); #define e_value_u64(v) (E_Value){.u64 = (v)} -//- rjf: type key data structures +//////////////////////////////// +//~ rjf: Expr Kind Enum Functions + +internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind); +internal B32 e_expr_kind_is_comparison(E_ExprKind kind); + +//////////////////////////////// +//~ rjf: Key Type Functions + +internal B32 e_key_match(E_Key a, E_Key b); + +//////////////////////////////// +//~ rjf: Type Key Type Functions + internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); @@ -676,7 +1035,7 @@ internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push); internal E_Space e_space_make(E_SpaceKind kind); //////////////////////////////// -//~ rjf: Basic Map Functions +//~ rjf: Map Functions //- rjf: string -> num internal E_String2NumMap e_string2num_map_make(Arena *arena, U64 slot_count); @@ -691,13 +1050,18 @@ internal E_String2ExprMap e_string2expr_map_make(Arena *arena, U64 slot_count); internal void e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr); internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string); internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string); -internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string); +internal E_Expr *e_string2expr_map_lookup(E_String2ExprMap *map, String8 string); //- rjf: string -> type-key internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, 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, E_AutoHookParams *params); +#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) + //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Functions @@ -705,8 +1069,102 @@ internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Pars internal E_String2NumMap *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); +internal void e_cache_release(E_Cache *cache); +internal void e_select_cache(E_Cache *cache); + +//////////////////////////////// +//~ rjf: Evaluation Phase Markers internal void e_select_base_ctx(E_BaseCtx *ctx); +internal void e_select_ir_ctx(E_IRCtx *ctx); + +//////////////////////////////// +//~ rjf: Base Cache Accessing Functions +// +// The cache uses a unique keying mechanism to refer to some evaluation at +// many layers of analysis. +// +// key +// ________________________________________________ +// / / | \ +// text -> expression -> ir tree and type -> interpretation result +// +// Each one of these calls refers to one stage in this pipeline. The cache will +// only compute what is needed on-demand. If you ask for the full evaluation, +// which is a bundle of artifacts at all layers of analysis, then all stages +// will be computed. +// +// One wrinkle here is that the IR tree generation stage is implicitly +// parameterized by the "overridden" IR tree - this is to enable "parent +// expressions", e.g. `$.x`, or simply `x` assuming `foo` has such a member, +// in the context of some struct `foo` evaluates to the same thing as `foo.x`. +// So even though the primary API shape is based around singular keys, the +// "parent key stack" also implicitly parameterizes all of these (partly +// because it is not relevant in 99% of cases). + +//- rjf: parent key stack +internal E_Key e_parent_key_push(E_Key key); +internal E_Key e_parent_key_pop(void); +#define E_ParentKey(key) DeferLoop(e_parent_key_push(key), e_parent_key_pop()) + +//- rjf: key construction +internal E_Key e_key_from_string(String8 string); +internal E_Key e_key_from_stringf(char *fmt, ...); +internal E_Key e_key_from_expr(E_Expr *expr); + +//- rjf: base key -> bundle helper +internal E_CacheBundle *e_cache_bundle_from_key(E_Key key); + +//- rjf: bundle -> pipeline stage outputs +internal E_Parse e_parse_from_bundle(E_CacheBundle *bundle); +internal E_IRTreeAndType e_irtree_from_bundle(E_CacheBundle *bundle); +internal String8 e_bytecode_from_bundle(E_CacheBundle *bundle); +internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); +#define e_parse_from_key(key) e_parse_from_bundle(e_cache_bundle_from_key(key)) +#define e_irtree_from_key(key) e_irtree_from_bundle(e_cache_bundle_from_key(key)) +#define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) +#define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) + +//- rjf: comprehensive bundle +internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); +internal E_Eval e_value_eval_from_eval(E_Eval eval); +#define e_eval_from_key(key) e_eval_from_bundle(e_cache_bundle_from_key(key)) +#define e_value_from_key(key) (e_value_eval_from_eval(e_eval_from_key(key)).value) + +//- rjf: string-based helpers +#define e_parse_from_string(string) e_parse_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_irtree_from_string(string) e_irtree_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_bytecode_from_string(string) e_bytecode_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_interpretation_from_string(string) e_interpretation_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_eval_from_string(string) e_eval_from_key(e_key_from_string(string)) +#define e_eval_from_stringf(...) e_eval_from_key(e_key_from_stringf(__VA_ARGS__)) +#define e_value_from_string(string) e_value_eval_from_eval(e_eval_from_string(string)).value +#define e_value_from_stringf(...) e_value_eval_from_eval(e_eval_from_stringf(__VA_ARGS__)).value +// TODO(rjf): (replace the old bundle APIs here) + +//- rjf: expr-based helpers +#define e_eval_from_expr(expr) e_eval_from_key(e_key_from_expr(expr)) +#define e_value_from_expr(expr) e_value_eval_from_eval(e_eval_from_expr(expr)).value + +//- rjf: type key -> auto hooks +internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); +internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); + +//- rjf: string IDs +internal U64 e_id_from_string(String8 string); +internal String8 e_string_from_id(U64 id); + +//////////////////////////////// +//~ rjf: Key Extension Functions + +internal E_Key e_key_wrap(E_Key key, String8 string); +internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); + +//- rjf: eval-based helpers +#define e_eval_wrap(eval, string) e_eval_from_key(e_key_wrap((eval).key, (string))) +#define e_eval_wrapf(eval, ...) e_eval_from_key(e_key_wrapf((eval).key, __VA_ARGS__)) #endif // EVAL_CORE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c index 2a74cc6b..c4d2222c 100644 --- a/src/eval/eval_inc.c +++ b/src/eval/eval_inc.c @@ -7,4 +7,3 @@ #include "eval/eval_ir.c" #include "eval/eval_interpret.c" #include "eval/eval_bundles.c" -#include "eval/eval_cache.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h index 882fff88..2c46335b 100644 --- a/src/eval/eval_inc.h +++ b/src/eval/eval_inc.h @@ -10,6 +10,5 @@ #include "eval/eval_ir.h" #include "eval/eval_interpret.h" #include "eval/eval_bundles.h" -#include "eval/eval_cache.h" #endif // EVAL_INC_H diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 0c900a5a..0b4f37af 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -4,17 +4,6 @@ #ifndef EVAL_INTERPRET_H #define EVAL_INTERPRET_H -//////////////////////////////// -//~ rjf: Bytecode Interpretation Types - -typedef struct E_Interpretation E_Interpretation; -struct E_Interpretation -{ - E_Value value; - E_Space space; - E_InterpretationCode code; -}; - //////////////////////////////// //~ rjf: Interpretation Context diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e355f78c..ce077dc8 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1,289 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ 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: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal void -e_select_ir_ctx(E_IRCtx *ctx) -{ - if(e_ir_state == 0) - { - Arena *arena = arena_alloc(); - e_ir_state = push_array(arena, E_IRState, 1); - e_ir_state->arena = arena; - e_ir_state->arena_eval_start_pos = arena_pos(arena); - } - arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - 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_ir_state->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_ir_state->arena, 512); } - e_ir_state->ctx = ctx; - e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff); - e_ir_state->used_expr_map = push_array(e_ir_state->arena, E_UsedExprMap, 1); - e_ir_state->used_expr_map->slots_count = 64; - e_ir_state->used_expr_map->slots = push_array(e_ir_state->arena, E_UsedExprSlot, e_ir_state->used_expr_map->slots_count); - e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); - e_ir_state->type_auto_hook_cache_map->slots_count = 256; - e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); - e_ir_state->string_id_gen = 0; - e_ir_state->string_id_map = push_array(e_ir_state->arena, E_StringIDMap, 1); - e_ir_state->string_id_map->id_slots_count = 1024; - e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); - e_ir_state->string_id_map->hash_slots_count = 1024; - e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); - e_ir_state->ir_cache_slots_count = 4096; - e_ir_state->ir_cache_slots = push_array(e_ir_state->arena, E_IRCacheSlot, e_ir_state->ir_cache_slots_count); - String8 builtin_view_rule_names[] = - { - str8_lit_comp("bswap"), - }; - for EachElement(idx, builtin_view_rule_names) - { - E_Expr *expr = e_push_expr(e_ir_state->arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = builtin_view_rule_names[idx]); - e_string2expr_map_insert(e_ir_state->arena, ctx->macro_map, builtin_view_rule_names[idx], expr); - } -} - -//////////////////////////////// -//~ 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_parse_from_string(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); - } -} - -internal E_ExprList -e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) -{ - ProfBeginFunction(); - E_ExprList exprs = {0}; - if(e_ir_state != 0 && e_ir_state->ctx != 0) - { - Temp scratch = scratch_begin(&arena, 1); - E_AutoHookMap *map = e_ir_state->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}; - if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->type_auto_hook_cache_map != 0 && e_ir_state->type_auto_hook_cache_map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); - U64 slot_idx = hash%e_ir_state->type_auto_hook_cache_map->slots_count; - E_TypeAutoHookCacheNode *node = 0; - for(E_TypeAutoHookCacheNode *n = e_ir_state->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_ir_state->arena, E_TypeAutoHookCacheNode, 1); - SLLQueuePush(e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_state->type_auto_hook_cache_map->slots[slot_idx].last, node); - node->key = type_key; - node->exprs = e_auto_hook_exprs_from_type_key(e_type_state->arena, type_key); - } - exprs = node->exprs; - } - return exprs; -} - -//////////////////////////////// -//~ rjf: Evaluated String IDs - -internal U64 -e_id_from_string(String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 hash_slot_idx = hash%e_ir_state->string_id_map->hash_slots_count; - E_StringIDNode *node = 0; - for(E_StringIDNode *n = e_ir_state->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_ir_state->string_id_gen += 1; - U64 id = e_ir_state->string_id_gen; - U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; - node = push_array(e_ir_state->arena, E_StringIDNode, 1); - SLLQueuePush_N(e_ir_state->string_id_map->hash_slots[hash_slot_idx].first, e_ir_state->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next); - SLLQueuePush_N(e_ir_state->string_id_map->id_slots[id_slot_idx].first, e_ir_state->string_id_map->hash_slots[id_slot_idx].last, node, id_next); - node->id = id; - node->string = push_str8_copy(e_ir_state->arena, string); - } - U64 result = node->id; - return result; -} - -internal String8 -e_string_from_id(U64 id) -{ - U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; - E_StringIDNode *node = 0; - for(E_StringIDNode *n = e_ir_state->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: IR-ization Functions @@ -594,8 +311,8 @@ e_expr_is_poisoned(E_Expr *expr) { B32 tag_is_poisoned = 0; U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_cache->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->expr == expr) { @@ -610,22 +327,22 @@ internal void e_expr_poison(E_Expr *expr) { U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - E_UsedExprNode *n = push_array(e_ir_state->arena, E_UsedExprNode, 1); + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + E_UsedExprNode *n = push_array(e_cache->arena, E_UsedExprNode, 1); n->expr = expr; - DLLPushBack(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); + DLLPushBack(e_cache->used_expr_map->slots[slot_idx].first, e_cache->used_expr_map->slots[slot_idx].last, n); } internal void e_expr_unpoison(E_Expr *expr) { U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_cache->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->expr == expr) { - DLLRemove(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); + DLLRemove(e_cache->used_expr_map->slots[slot_idx].first, e_cache->used_expr_map->slots[slot_idx].last, n); break; } } @@ -775,7 +492,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); @@ -869,7 +586,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -886,9 +603,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *expr; E_IRTreeAndType *prev; }; - E_IRTreeAndType *start_prev = e_ir_state->overridden_irtree; - B32 start_disallow_autohooks = e_ir_state->disallow_autohooks; - Task start_task = {0, root_expr, e_ir_state->overridden_irtree}; + Task start_task = {0, root_expr, overridden}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -901,7 +616,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: select the task's previous ir-tree-and-type as the overridden tree if(t->prev != 0) { - e_ir_state->overridden_irtree = t->prev; + overridden = t->prev; } //- rjf: do expr -> irtree generation for this expression @@ -920,7 +635,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs); // rjf: try all IR trees in chain for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev) @@ -961,7 +676,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } // rjf: call into hook to do access - result = lhs_access(arena, expr, lhs_irtree_try); + result = lhs_access(arena, overridden, expr, lhs_irtree_try); // rjf: end chain if we found a result if(result.root != &e_irnode_nil) @@ -976,7 +691,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); @@ -1035,7 +750,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); @@ -1063,11 +778,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -1122,7 +837,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -1150,7 +865,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -1164,7 +879,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1192,14 +907,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, expr->first); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1232,7 +947,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1287,8 +1002,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1511,9 +1226,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1556,10 +1271,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: call case E_ExprKind_Call: { - B32 start_disallow_chained_fastpaths = e_ir_state->disallow_chained_fastpaths; - e_ir_state->disallow_chained_fastpaths = 1; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1580,17 +1293,17 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_expr_push_child(call, e_expr_ref(arena, arg)); } - result = e_push_irtree_and_type_from_expr(arena, call); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call); // rjf: is "raw"? -> try to return overridden tree, otherwise strip all // lens types from result; disallow auto-hooks if(str8_match(callee->string, str8_lit("raw"), 0)) { - e_ir_state->disallow_autohooks = 1; - if(e_ir_state->overridden_irtree != 0) + disallow_autohooks = 1; + if(overridden != 0) { - result = *e_ir_state->overridden_irtree; - for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + result = *overridden; + for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) { result = *prev; } @@ -1609,7 +1322,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Temp scratch = scratch_begin(&arena, 1); // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); // rjf: count extra arguments U64 arg_count = 0; @@ -1632,18 +1345,18 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // lens types from result; disallow auto-hooks if(str8_match(lhs_type->name, str8_lit("raw"), 0)) { - e_ir_state->disallow_autohooks = 1; - if(e_ir_state->overridden_irtree != 0) + disallow_autohooks = 1; + if(overridden != 0) { - result = *e_ir_state->overridden_irtree; - for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + result = *overridden; + for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) { result = *prev; } } else { - result = e_push_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -1670,8 +1383,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); } - - e_ir_state->disallow_chained_fastpaths = start_disallow_chained_fastpaths; }break; //- rjf: leaf bytecode @@ -1751,7 +1462,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Module *module = e_base_ctx->primary_module; RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; U64 name_size = 0; U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); String8 containing_procedure_name = str8(name_ptr, name_size); @@ -1773,21 +1484,21 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: try to map name as overridden expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->overridden_irtree != 0) + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && overridden != 0) { - E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->overridden_irtree->root); + E_OpList oplist = e_oplist_from_irtree(arena, overridden->root); string_mapped = 1; mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; - mapped_type_key = e_ir_state->overridden_irtree->type_key; - e_ir_state->disallow_autohooks = 1; + mapped_bytecode_mode = overridden->mode; + mapped_type_key = overridden->type_key; + disallow_autohooks = 1; } //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(!string_mapped && e_ir_state->overridden_irtree != 0) + if(!string_mapped && overridden != 0) { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, e_ir_state->overridden_irtree, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, access); + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -1806,7 +1517,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Module *module = e_base_ctx->primary_module; U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); @@ -1824,7 +1535,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Module *module = e_base_ctx->primary_module; U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); + U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected); if(local_num != 0) { RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); @@ -2073,7 +1784,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try registers if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) { - U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); if(reg_num != 0) { string_mapped = 1; @@ -2090,7 +1801,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try register aliases if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) { - U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); if(alias_num != 0) { string_mapped = 1; @@ -2149,13 +1860,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: generate IR trees for macros if(!generated) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); + E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, string); if(macro_expr != &e_expr_nil) { generated = 1; - e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); + e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, macro_expr); + e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); } } @@ -2213,7 +1924,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_state->file_type_key; + result.type_key = e_cache->file_type_key; result.mode = E_Mode_Value; } else @@ -2224,7 +1935,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_state->folder_type_key; + result.type_key = e_cache->folder_type_key; result.mode = E_Mode_Value; } } @@ -2241,13 +1952,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2261,7 +1972,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, rhs); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); @@ -2270,7 +1981,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: check chained expressions for simple wrappers - if(!e_ir_state->disallow_chained_fastpaths) + if(!disallow_chained_fastpaths) { struct { @@ -2310,7 +2021,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(e_type_kind_is_pointer_or_ref(type_kind) || type_kind == E_TypeKind_Array) { - E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); + E_Expr *lens_spec_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, str8_lit("array")); E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, @@ -2360,7 +2071,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: find any auto hooks according to this generation's type - if(!e_ir_state->disallow_autohooks && result.mode != E_Mode_Null) + if(!disallow_autohooks && result.mode != E_Mode_Null) { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -2382,12 +2093,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - ////////////////////////////// - //- rjf: reset the overridden settings to whatever they were before this task list - // - e_ir_state->overridden_irtree = start_prev; - e_ir_state->disallow_autohooks = start_disallow_autohooks; - ////////////////////////////// //- rjf: unpoison the tags we used // @@ -2688,40 +2393,3 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type e_expr_push_child(root, rhs_bytecode); return root; } - -//////////////////////////////// -//~ rjf: IR Cache Functions - -internal E_IRTreeAndType -e_irtree_and_type_from_expr(E_Expr *expr) -{ - U64 hash_parts[] = - { - (U64)expr, - (U64)(e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0), - }; - U64 hash = e_hash_from_string(5381, str8((U8 *)hash_parts, sizeof(hash_parts))); - U64 slot_idx = hash%e_ir_state->ir_cache_slots_count; - E_IRCacheSlot *slot = &e_ir_state->ir_cache_slots[slot_idx]; - E_IRCacheNode *node = 0; - for(E_IRCacheNode *n = slot->first; n != 0; n = n->next) - { - if(expr == n->expr && - ((e_ir_state->overridden_irtree == 0 && n->overridden_node == 0) || - (e_ir_state->overridden_irtree != 0 && n->overridden_node == e_ir_state->overridden_irtree->root))) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_ir_state->arena, E_IRCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->expr = expr; - node->overridden_node = (e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0); - node->irtree = e_push_irtree_and_type_from_expr(e_ir_state->arena, expr); - } - E_IRTreeAndType result = node->irtree; - return result; -} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d996d710..2bc467dd 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -4,98 +4,6 @@ #ifndef EVAL_IR_H #define EVAL_IR_H -//////////////////////////////// -//~ rjf: Used Tag Map Data Structure - -typedef struct E_UsedExprNode E_UsedExprNode; -struct E_UsedExprNode -{ - E_UsedExprNode *next; - E_UsedExprNode *prev; - E_Expr *expr; -}; - -typedef struct E_UsedExprSlot E_UsedExprSlot; -struct E_UsedExprSlot -{ - E_UsedExprNode *first; - E_UsedExprNode *last; -}; - -typedef struct E_UsedExprMap E_UsedExprMap; -struct E_UsedExprMap -{ - U64 slots_count; - E_UsedExprSlot *slots; -}; - -//////////////////////////////// -//~ rjf: Type Key -> Auto Hook Expr List Cache - -typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; -struct E_TypeAutoHookCacheNode -{ - E_TypeAutoHookCacheNode *next; - E_TypeKey key; - E_ExprList exprs; -}; - -typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; -struct E_TypeAutoHookCacheSlot -{ - E_TypeAutoHookCacheNode *first; - E_TypeAutoHookCacheNode *last; -}; - -typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; -struct E_TypeAutoHookCacheMap -{ - U64 slots_count; - E_TypeAutoHookCacheSlot *slots; -}; - -//////////////////////////////// -//~ rjf: Evaluated String ID Map - -typedef struct E_StringIDNode E_StringIDNode; -struct E_StringIDNode -{ - E_StringIDNode *hash_next; - E_StringIDNode *id_next; - U64 id; - String8 string; -}; - -typedef struct E_StringIDSlot E_StringIDSlot; -struct E_StringIDSlot -{ - E_StringIDNode *first; - E_StringIDNode *last; -}; - -typedef struct E_StringIDMap E_StringIDMap; -struct E_StringIDMap -{ - U64 id_slots_count; - E_StringIDSlot *id_slots; - U64 hash_slots_count; - E_StringIDSlot *hash_slots; -}; - -//////////////////////////////// -//~ rjf: IR Context - -typedef struct E_IRCtx E_IRCtx; -struct E_IRCtx -{ - E_String2NumMap *regs_map; - E_String2NumMap *reg_alias_map; - E_String2NumMap *locals_map; // (within `primary_module`) - E_String2NumMap *member_map; // (within `primary_module`) - E_String2ExprMap *macro_map; - E_AutoHookMap *auto_hook_map; -}; - //////////////////////////////// //~ rjf: IR State @@ -141,37 +49,6 @@ struct E_IRState E_IRCacheSlot *ir_cache_slots; }; -//////////////////////////////// -//~ rjf: Globals - -thread_static E_IRState *e_ir_state = 0; - -//////////////////////////////// -//~ rjf: Expr Kind Enum Functions - -internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind); -internal B32 e_expr_kind_is_comparison(E_ExprKind kind); - -//////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal void e_select_ir_ctx(E_IRCtx *ctx); - -//////////////////////////////// -//~ 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, E_AutoHookParams *params); -#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) -internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); -internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); - -//////////////////////////////// -//~ rjf: Evaluated String IDs - -internal U64 e_id_from_string(String8 string); -internal String8 e_string_from_id(U64 id); - //////////////////////////////// //~ rjf: IR-ization Functions @@ -211,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); @@ -224,9 +101,4 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); -//////////////////////////////// -//~ rjf: IR Cache Functions - -internal E_IRTreeAndType e_irtree_and_type_from_expr(E_Expr *expr); - #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index abf9e728..116ddda1 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1454,47 +1454,3 @@ e_push_parse_from_string(Arena *arena, String8 text) scratch_end(scratch); return parse; } - -//////////////////////////////// -//~ rjf: Parse Cache Functions - -internal void -e_parse_eval_begin(void) -{ - if(e_parse_state == 0) - { - Arena *arena = arena_alloc(); - e_parse_state = push_array(arena, E_ParseState, 1); - e_parse_state->arena = arena; - e_parse_state->arena_eval_start_pos = arena_pos(e_parse_state->arena); - } - arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - e_parse_state->cache_slots_count = 4096; - e_parse_state->cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->cache_slots_count); -} - -internal E_Parse -e_parse_from_string(String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_parse_state->cache_slots_count; - E_ParseCacheSlot *slot = &e_parse_state->cache_slots[slot_idx]; - E_ParseCacheNode *node = 0; - for(E_ParseCacheNode *n = slot->first; n != 0; n = n->next) - { - if(str8_match(n->string, string, 0)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->string = push_str8_copy(e_parse_state->arena, string); - node->parse = e_push_parse_from_string(e_parse_state->arena, node->string); - } - E_Parse result = node->parse; - return result; -} diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 418451a9..54af1689 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -4,51 +4,6 @@ #ifndef EVAL_PARSE_H #define EVAL_PARSE_H -//////////////////////////////// -//~ rjf: Parse Results - -typedef struct E_Parse E_Parse; -struct E_Parse -{ - E_TokenArray tokens; - E_Token *last_token; - E_Expr *expr; - E_Expr *last_expr; - E_MsgList msgs; -}; - -//////////////////////////////// -//~ rjf: Parse Evaluation State - -typedef struct E_ParseCacheNode E_ParseCacheNode; -struct E_ParseCacheNode -{ - E_ParseCacheNode *next; - String8 string; - E_Parse parse; -}; - -typedef struct E_ParseCacheSlot E_ParseCacheSlot; -struct E_ParseCacheSlot -{ - E_ParseCacheNode *first; - E_ParseCacheNode *last; -}; - -typedef struct E_ParseState E_ParseState; -struct E_ParseState -{ - Arena *arena; - U64 arena_eval_start_pos; - U64 cache_slots_count; - E_ParseCacheSlot *cache_slots; -}; - -//////////////////////////////// -//~ rjf: Globals - -thread_static E_ParseState *e_parse_state = 0; - //////////////////////////////// //~ rjf: Tokenization Functions @@ -86,10 +41,4 @@ internal E_Parse e_push_type_parse_from_text_tokens(Arena *arena, String8 text, internal E_Parse e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_push_parse_from_string(Arena *arena, String8 text); -//////////////////////////////// -//~ rjf: Parse Cache Functions - -internal void e_parse_eval_begin(void); -internal E_Parse e_parse_from_string(String8 string); - #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ff7af653..6b4156b0 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -222,49 +222,6 @@ e_member_array_from_list(Arena *arena, E_MemberList *list) return array; } -//////////////////////////////// -//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) - -internal void -e_type_eval_begin(void) -{ - if(e_type_state == 0) - { - Arena *arena = arena_alloc(); - e_type_state = push_array(arena, E_TypeState, 1); - e_type_state->arena = arena; - e_type_state->arena_eval_start_pos = arena_pos(e_type_state->arena); - } - arena_pop_to(e_type_state->arena, e_type_state->arena_eval_start_pos); - e_type_state->cons_id_gen = 0; - e_type_state->cons_content_slots_count = 256; - e_type_state->cons_key_slots_count = 256; - e_type_state->cons_content_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_content_slots_count); - e_type_state->cons_key_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_key_slots_count); - e_type_state->member_cache_slots_count = 256; - e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count); - e_type_state->type_cache_slots_count = 1024; - e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); - e_type_state->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_type_state->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), - }); -} - //////////////////////////////// //~ rjf: Type Operation Functions @@ -385,8 +342,8 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params) { U64 content_hash = e_hash_from_cons_type_params(params); - U64 content_slot_idx = content_hash%e_type_state->cons_content_slots_count; - E_ConsTypeSlot *content_slot = &e_type_state->cons_content_slots[content_slot_idx]; + U64 content_slot_idx = content_hash%e_cache->cons_content_slots_count; + E_ConsTypeSlot *content_slot = &e_cache->cons_content_slots[content_slot_idx]; E_ConsTypeNode *node = 0; for(E_ConsTypeNode *n = content_slot->first; n != 0; n = n->content_next) { @@ -401,17 +358,17 @@ e_type_key_cons_(E_ConsTypeParams *params) { E_TypeKey key = {E_TypeKeyKind_Cons}; key.u32[0] = (U32)params->kind; - key.u32[1] = (U32)e_type_state->cons_id_gen; - e_type_state->cons_id_gen += 1; + key.u32[1] = (U32)e_cache->cons_id_gen; + e_cache->cons_id_gen += 1; U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count; - E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx]; - E_ConsTypeNode *node = push_array(e_type_state->arena, E_ConsTypeNode, 1); + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; + E_ConsTypeNode *node = push_array(e_cache->arena, E_ConsTypeNode, 1); SLLQueuePush_N(content_slot->first, content_slot->last, node, content_next); SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next); node->key = key; MemoryCopyStruct(&node->params, params); - node->params.name = push_str8_copy(e_type_state->arena, params->name); + node->params.name = push_str8_copy(e_cache->arena, params->name); if(node->params.expand.info != 0) { if(node->params.expand.range == 0) {node->params.expand.range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default);} @@ -420,32 +377,32 @@ e_type_key_cons_(E_ConsTypeParams *params) } if(params->members != 0) { - node->params.members = push_array(e_type_state->arena, E_Member, params->count); + node->params.members = push_array(e_cache->arena, E_Member, params->count); MemoryCopy(node->params.members, params->members, sizeof(E_Member)*params->count); for(U64 idx = 0; idx < node->params.count; idx += 1) { - node->params.members[idx].name = push_str8_copy(e_type_state->arena, node->params.members[idx].name); - node->params.members[idx].inheritance_key_chain = e_type_key_list_copy(e_type_state->arena, &node->params.members[idx].inheritance_key_chain); + node->params.members[idx].name = push_str8_copy(e_cache->arena, node->params.members[idx].name); + node->params.members[idx].inheritance_key_chain = e_type_key_list_copy(e_cache->arena, &node->params.members[idx].inheritance_key_chain); U64 opl_off = (node->params.members[idx].off + e_type_byte_size_from_key(node->params.members[idx].type_key)); node->byte_size = Max(node->byte_size, opl_off); } } else if(params->enum_vals != 0) { - node->params.enum_vals = push_array(e_type_state->arena, E_EnumVal, params->count); + node->params.enum_vals = push_array(e_cache->arena, E_EnumVal, params->count); MemoryCopy(node->params.enum_vals, params->enum_vals, sizeof(E_EnumVal)*params->count); for(U64 idx = 0; idx < node->params.count; idx += 1) { - node->params.enum_vals[idx].name = push_str8_copy(e_type_state->arena, node->params.enum_vals[idx].name); + node->params.enum_vals[idx].name = push_str8_copy(e_cache->arena, node->params.enum_vals[idx].name); } node->byte_size = e_type_byte_size_from_key(node->params.direct_key); } else if(params->args != 0) { - node->params.args = push_array(e_type_state->arena, E_Expr *, params->count); + node->params.args = push_array(e_cache->arena, E_Expr *, params->count); for EachIndex(idx, params->count) { - node->params.args[idx] = e_expr_copy(e_type_state->arena, params->args[idx]); + node->params.args[idx] = e_expr_copy(e_cache->arena, params->args[idx]); } } else switch(params->kind) @@ -560,14 +517,14 @@ e_type_key_cons_base(Type *type) internal E_TypeKey e_type_key_file(void) { - E_TypeKey key = e_type_state->file_type_key; + E_TypeKey key = e_cache->file_type_key; return key; } internal E_TypeKey e_type_key_folder(void) { - E_TypeKey key = e_type_state->folder_type_key; + E_TypeKey key = e_cache->folder_type_key; return key; } @@ -669,8 +626,8 @@ e_type_byte_size_from_key(E_TypeKey key) case E_TypeKeyKind_Cons: { U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count; - E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx]; + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; for(E_ConsTypeNode *node = key_slot->first; node != 0; node = node->key_next) @@ -715,8 +672,8 @@ e_type_from_key(Arena *arena, E_TypeKey key) case E_TypeKeyKind_Cons: { U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count; - E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx]; + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; for(E_ConsTypeNode *node = key_slot->first; node != 0; node = node->key_next) @@ -1996,9 +1953,9 @@ e_type_from_key__cached(E_TypeKey key) E_Type *type = &e_type_nil; { U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_type_state->type_cache_slots_count; + U64 slot_idx = hash%e_cache->type_cache_slots_count; E_TypeCacheNode *node = 0; - for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) + for(E_TypeCacheNode *n = e_cache->type_cache_slots[slot_idx].first; n != 0; n = n->next) { if(e_type_key_match(key, n->key)) { @@ -2008,10 +1965,10 @@ e_type_from_key__cached(E_TypeKey key) } if(node == 0) { - node = push_array(e_type_state->arena, E_TypeCacheNode, 1); + node = push_array(e_cache->arena, E_TypeCacheNode, 1); node->key = key; - node->type = e_type_from_key(e_type_state->arena, key); - SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); + node->type = e_type_from_key(e_cache->arena, key); + SLLQueuePush(e_cache->type_cache_slots[slot_idx].first, e_cache->type_cache_slots[slot_idx].last, node); } type = node->type; } @@ -2022,8 +1979,8 @@ internal E_MemberCacheNode * e_member_cache_node_from_type_key(E_TypeKey key) { U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_type_state->member_cache_slots_count; - E_MemberCacheSlot *slot = &e_type_state->member_cache_slots[slot_idx]; + U64 slot_idx = hash%e_cache->member_cache_slots_count; + E_MemberCacheSlot *slot = &e_cache->member_cache_slots[slot_idx]; E_MemberCacheNode *node = 0; for(E_MemberCacheNode *n = slot->first; n != 0; n = n->next) { @@ -2035,19 +1992,19 @@ e_member_cache_node_from_type_key(E_TypeKey key) } if(node == 0) { - node = push_array(e_type_state->arena, E_MemberCacheNode, 1); + node = push_array(e_cache->arena, E_MemberCacheNode, 1); SLLQueuePush(slot->first, slot->last, node); node->key = key; - node->members = e_type_data_members_from_key(e_type_state->arena, key); + node->members = e_type_data_members_from_key(e_cache->arena, key); node->member_hash_slots_count = node->members.count; - node->member_hash_slots = push_array(e_type_state->arena, E_MemberHashSlot, node->member_hash_slots_count); + node->member_hash_slots = push_array(e_cache->arena, E_MemberHashSlot, node->member_hash_slots_count); node->member_filter_slots_count = 16; - node->member_filter_slots = push_array(e_type_state->arena, E_MemberFilterSlot, node->member_filter_slots_count); + node->member_filter_slots = push_array(e_cache->arena, E_MemberFilterSlot, node->member_filter_slots_count); for EachIndex(idx, node->members.count) { U64 hash = e_hash_from_string(5381, node->members.v[idx].name); U64 slot_idx = hash%node->member_hash_slots_count; - E_MemberHashNode *n = push_array(e_type_state->arena, E_MemberHashNode, 1); + E_MemberHashNode *n = push_array(e_cache->arena, E_MemberHashNode, 1); SLLQueuePush(node->member_hash_slots[slot_idx].first, node->member_hash_slots[slot_idx].last, n); n->member_idx = idx; } @@ -2083,8 +2040,8 @@ e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) if(filter_node == 0) { Temp scratch = scratch_begin(0, 0); - filter_node = push_array(e_type_state->arena, E_MemberFilterNode, 1); - filter_node->filter = push_str8_copy(e_type_state->arena, filter); + filter_node = push_array(e_cache->arena, E_MemberFilterNode, 1); + filter_node->filter = push_str8_copy(e_cache->arena, filter); E_MemberList member_list__filtered = {0}; for EachIndex(idx, node->members.count) { @@ -2095,7 +2052,7 @@ e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) e_member_list_push(scratch.arena, &member_list__filtered, member); } } - filter_node->members_filtered = e_member_array_from_list(e_type_state->arena, &member_list__filtered); + filter_node->members_filtered = e_member_array_from_list(e_cache->arena, &member_list__filtered); scratch_end(scratch); } members = filter_node->members_filtered; @@ -2300,6 +2257,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) irtree_stripped.type_key = type->direct_type_key; irtree_stripped.user_data = stripped_type->irext ? stripped_type->irext(scratch.arena, expr, &irtree_stripped).user_data : 0; E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(irtree_stripped.type_key); + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, expr, &irtree_stripped, filter); if(expand_info.expr_count < 4096) { @@ -2395,14 +2353,9 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) U64 count = 1; if(type->args != 0 && type->count > 0) { - E_Expr *count_expr = type->args[0]; - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = irtree; - { - E_Value count_value = e_value_from_expr(count_expr); - count = count_value.u64; - } - e_ir_state->overridden_irtree = prev_overridden_irtree; + E_Key count_key = e_key_from_expr(type->args[0]); + E_Value count_value = e_value_from_key(count_key); + count = count_value.u64; } E_TypeExpandInfo info = {0, count}; return info; @@ -2550,7 +2503,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) default: case E_ExprKind_MemberAccess: { - result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, expr, lhs_irtree); + result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, overridden, expr, lhs_irtree); }break; case E_ExprKind_ArrayIndex: { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index fdbcb08b..451dc8b0 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -20,141 +20,6 @@ enum E_TypeUnwrapFlag_AllDecorative = (E_TypeUnwrapFlag_All & ~E_TypeUnwrapFlag_Pointers) }; -//////////////////////////////// -//~ rjf: Type Evaluation State - -//- rjf: constructed type cache types - -typedef struct E_ConsTypeParams E_ConsTypeParams; -struct E_ConsTypeParams -{ - Arch arch; - E_TypeKind kind; - E_TypeFlags flags; - String8 name; - E_TypeKey direct_key; - U64 count; - U64 depth; - E_Member *members; - E_EnumVal *enum_vals; - E_Expr **args; - E_TypeIRExtFunctionType *irext; - E_TypeAccessFunctionType *access; - E_TypeExpandRule expand; -}; - -typedef struct E_ConsTypeNode E_ConsTypeNode; -struct E_ConsTypeNode -{ - E_ConsTypeNode *key_next; - E_ConsTypeNode *content_next; - E_TypeKey key; - E_ConsTypeParams params; - U64 byte_size; -}; - -typedef struct E_ConsTypeSlot E_ConsTypeSlot; -struct E_ConsTypeSlot -{ - E_ConsTypeNode *first; - E_ConsTypeNode *last; -}; - -//- rjf: unpacked type cache - -typedef struct E_TypeCacheNode E_TypeCacheNode; -struct E_TypeCacheNode -{ - E_TypeCacheNode *next; - E_TypeKey key; - E_Type *type; -}; - -typedef struct E_TypeCacheSlot E_TypeCacheSlot; -struct E_TypeCacheSlot -{ - E_TypeCacheNode *first; - E_TypeCacheNode *last; -}; - -//- rjf: member lookup cache types - -typedef struct E_MemberHashNode E_MemberHashNode; -struct E_MemberHashNode -{ - E_MemberHashNode *next; - U64 member_idx; -}; - -typedef struct E_MemberHashSlot E_MemberHashSlot; -struct E_MemberHashSlot -{ - E_MemberHashNode *first; - E_MemberHashNode *last; -}; - -typedef struct E_MemberFilterNode E_MemberFilterNode; -struct E_MemberFilterNode -{ - E_MemberFilterNode *next; - String8 filter; - E_MemberArray members_filtered; -}; - -typedef struct E_MemberFilterSlot E_MemberFilterSlot; -struct E_MemberFilterSlot -{ - E_MemberFilterNode *first; - E_MemberFilterNode *last; -}; - -typedef struct E_MemberCacheNode E_MemberCacheNode; -struct E_MemberCacheNode -{ - E_MemberCacheNode *next; - E_TypeKey key; - E_MemberArray members; - U64 member_hash_slots_count; - E_MemberHashSlot *member_hash_slots; - U64 member_filter_slots_count; - E_MemberFilterSlot *member_filter_slots; -}; - -typedef struct E_MemberCacheSlot E_MemberCacheSlot; -struct E_MemberCacheSlot -{ - E_MemberCacheNode *first; - E_MemberCacheNode *last; -}; - -//- rjf: bundle - -typedef struct E_TypeState E_TypeState; -struct E_TypeState -{ - Arena *arena; - U64 arena_eval_start_pos; - - // rjf: JIT-constructed types tables - U64 cons_id_gen; - U64 cons_content_slots_count; - U64 cons_key_slots_count; - E_ConsTypeSlot *cons_content_slots; - E_ConsTypeSlot *cons_key_slots; - - // rjf: build-in constructed type keys - E_TypeKey file_type_key; - E_TypeKey folder_type_key; - - // rjf: member cache table - U64 member_cache_slots_count; - E_MemberCacheSlot *member_cache_slots; - - // rjf: unpacked type cache - U64 type_cache_slots_count; - E_TypeCacheSlot *type_cache_slots; -}; - //////////////////////////////// //~ rjf: Globals @@ -171,7 +36,6 @@ global read_only E_TypeExpandRule e_type_expand_rule__default = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), }; -thread_static E_TypeState *e_type_state = 0; //////////////////////////////// //~ rjf: Type Kind Enum Functions @@ -192,11 +56,6 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem #define e_member_list_push_new(arena, list, ...) e_member_list_push((arena), (list), &(E_Member){.kind = E_MemberKind_DataField, __VA_ARGS__}) internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list); -//////////////////////////////// -//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) - -internal void e_type_eval_begin(void); - //////////////////////////////// //~ rjf: Type Operation Functions diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5fac14f3..77e7a380 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -586,6 +586,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval } // rjf: get top-level lookup/expansion info + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); @@ -705,7 +706,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, &t->eval.irtree, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); if(child_expr != &e_expr_nil) { - E_Eval child_eval = e_eval_from_expr(arena, child_expr); + E_Eval child_eval = e_eval_from_expr(child_expr); EV_Key child_key = child_keys[idx]; Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); @@ -725,7 +726,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval task->next = t->next; t->next = task; task->parent_block = t->parent_block; - task->eval = e_eval_from_expr(arena, t->eval.expr->next); + task->eval = e_eval_from_expr(t->eval.expr->next); task->child_id = t->child_id + 1; task->split_relative_idx = 0; task->default_expanded = t->default_expanded; @@ -1046,7 +1047,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 U64 child_id = ev_block_id_from_num(n->v.block, child_num); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; - E_Eval row_eval = e_eval_from_expr(arena, row_expr); + E_Eval row_eval = e_eval_from_expr(row_expr); EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -2055,7 +2056,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) if(ptr_data->type->count == 1) { E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); - E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); + E_Eval deref_eval = e_eval_from_expr(deref_expr); need_new_task = 1; need_pop = 0; new_task.params = *params; @@ -2105,6 +2106,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); expand_data->type = e_type_from_key__cached(type_key); expand_data->expand_rule = e_expand_rule_from_type_key(type_key); + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); } switch(task_idx) @@ -2134,7 +2136,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_new_task = 1; need_pop = 0; new_task.params = *params; - new_task.eval = e_eval_from_expr(arena, next_expr); + new_task.eval = e_eval_from_expr(next_expr); if(task_idx > 1) { *out_string = str8_lit(", "); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index de41c742..bed73c3f 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -294,7 +294,7 @@ global read_only EV_Block ev_nil_block = {0}, 0, {0}, - {&e_expr_nil, &e_irnode_nil}, + {{0}, &e_expr_nil, &e_irnode_nil}, {0}, &e_type_expand_rule__default, {0}, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0a4e3185..d7a435ec 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1245,7 +1245,7 @@ rd_setting_b32_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); B32 result = !!e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); return result; @@ -1257,7 +1257,7 @@ rd_setting_u64_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); U64 result = e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); return result; @@ -1269,7 +1269,7 @@ rd_setting_f32_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); F32 result = e_value_eval_from_eval(eval).value.f32; scratch_end(scratch); return result; @@ -2029,7 +2029,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) got_commit_data = 1; E_Expr *src_expr = e_parse_from_string(string).expr; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); - E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); + E_Eval src_eval = e_eval_from_expr(src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } @@ -2095,7 +2095,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) //- rjf: pointer? -> try to treat new value as numeric value if(!got_commit_data && type_kind == E_TypeKind_Ptr) { - E_Eval src_eval = e_eval_from_string(scratch.arena, string); + E_Eval src_eval = e_eval_from_string(string); E_Eval src_eval_value = e_value_eval_from_eval(src_eval); E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); if((e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || @@ -2156,7 +2156,7 @@ rd_file_path_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval eval = e_eval_from_string(string); result = rd_file_path_from_eval(arena, eval); scratch_end(scratch); } @@ -2617,7 +2617,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: unpack view's target expression & hash - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + E_Eval eval = e_eval_from_string(expr_string); Rng1U64 range = r1u64(0, 1024); U128 key = rd_key_from_eval_space_range(eval.space, range, 0); U128 hash = hs_hash_from_key(key, 0); @@ -2709,7 +2709,7 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_Font(RD_FontSlot_Code) { - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + E_Eval eval = e_eval_from_string(expr_string); RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; @@ -4260,8 +4260,7 @@ rd_view_ui(Rng2F32 rect) { E_Expr *min_expr = cell_type->args[0]; E_Expr *max_expr = cell_type->args[1]; - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &cell->eval.irtree; + E_ParentKey(cell->eval.key) { E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); slider_value_type_kind = e_type_kind_from_key(slider_value_type); @@ -4270,7 +4269,6 @@ rd_view_ui(Rng2F32 rect) cell_slider_min = e_value_from_expr(min_casted); cell_slider_max = e_value_from_expr(max_casted); } - e_ir_state->overridden_irtree = prev_overridden_irtree; } switch(slider_value_type_kind) { @@ -4399,10 +4397,10 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = cell->eval.irtree.prev; - cell_info.view_ui_rule->ui(cell->eval, cell_rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; + E_ParentKey(cell->eval.key) + { + cell_info.view_ui_rule->ui(cell->eval, cell_rect); + } // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4850,15 +4848,11 @@ rd_view_ui(Rng2F32 rect) { Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); - E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &expr_eval.irtree; - for(E_IRTreeAndType *prev = expr_eval.irtree.prev; prev != 0; prev = prev->prev) + E_Eval expr_eval = e_eval_from_string(expr_string); + E_ParentKey(expr_eval.key) { - e_ir_state->overridden_irtree = prev; + view_ui_rule->ui(expr_eval, rect); } - view_ui_rule->ui(expr_eval, rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; scratch_end(scratch); } } @@ -4950,48 +4944,34 @@ rd_view_cfg_from_string(String8 string) internal E_Value rd_view_cfg_value_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); String8 expr = root->first->string; - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); E_Value result = e_value_eval_from_eval(eval).value; - scratch_end(scratch); return result; } internal B32 rd_view_cfg_b32_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(bool)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - B32 result = !!e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + B32 result = !!e_value_from_stringf("(bool)(%S)", root->first->string).u64; return result; } internal U64 rd_view_cfg_u64_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - U64 result = e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + U64 result = e_value_from_stringf("(uint64)(%S)", root->first->string).u64; return result; } internal F32 rd_view_cfg_f32_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(float32)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - F32 result = e_value_eval_from_eval(eval).value.f32; - scratch_end(scratch); + F32 result = e_value_from_stringf("(float32)(%S)", root->first->string).f32; return result; } @@ -5912,7 +5892,7 @@ rd_window_frame(void) { rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); ui_spacer(ui_em(2.f, 1.f)); - E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); + E_Eval eval = e_eval_from_string(rd_state->drag_drop_regs->expr); if(eval.irtree.mode != E_Mode_Null) { EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; @@ -6294,7 +6274,7 @@ rd_window_frame(void) // rjf: evaluate hover evaluation expression, & determine if it evaluates // such that we want to build a hover eval. - E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + E_Eval hover_eval = e_eval_from_string(hover_eval_expr); { if(hover_eval.msgs.max_kind > E_MsgKind_Null) { @@ -6405,7 +6385,7 @@ rd_window_frame(void) if(query_is_open) { String8 expr = ws->query_regs->expr; - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); if(eval.msgs.max_kind > E_MsgKind_Null) { query_is_open = 0; @@ -6473,7 +6453,7 @@ rd_window_frame(void) } // rjf: evaluate query expression - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); + E_Eval query_eval = e_eval_from_string(query_expr); // rjf: determine & store row-height setting if(ws->query_regs->do_big_rows) @@ -10228,7 +10208,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string); + U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -10239,7 +10219,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_ir_state->ctx->member_map, string); + U64 member_num = e_num_from_string(e_ir_ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -10250,7 +10230,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -10261,7 +10241,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -10650,8 +10630,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) case RD_RegSlot_PID: goto use_numeric_eval; use_numeric_eval: { - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval eval = e_eval_from_string(string); if(eval.msgs.max_kind == E_MsgKind_Null) { E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); @@ -10691,7 +10670,6 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) { log_user_errorf("Couldn't evaluate \"%S\" as an address.", string); } - scratch_end(scratch); }break; } } @@ -10816,6 +10794,7 @@ rd_init(CmdLine *cmdln) rd_state->num_frames_requested = 2; rd_state->seconds_until_autosave = 0.5f; rd_state->match_store = di_match_store_alloc(); + rd_state->eval_cache = e_cache_alloc(); for(U64 idx = 0; idx < ArrayCount(rd_state->cmds_arenas); idx += 1) { rd_state->cmds_arenas[idx] = arena_alloc(); @@ -11815,6 +11794,11 @@ rd_frame(void) } ProfEnd(); + //////////////////////////// + //- rjf: begin evaluation + // + e_select_cache(rd_state->eval_cache); + //////////////////////////// //- rjf: build base evaluation context // @@ -11840,12 +11824,6 @@ rd_frame(void) } e_select_base_ctx(eval_base_ctx); - //////////////////////////// - //- rjf: begin type evaluation - // - e_parse_eval_begin(); - e_type_eval_begin(); - //////////////////////////// //- rjf: build extra types & maps // @@ -12460,11 +12438,6 @@ rd_frame(void) } e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); - //////////////////////////// - //- rjf: begin cached evaluations - // - e_cache_eval_begin(); - //////////////////////////// //- rjf: autosave if needed // @@ -15842,19 +15815,16 @@ Z(getting_started) { if(t->expr->kind == E_ExprKind_LeafIdentifier) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, t->expr->string); - if(macro_expr != &e_expr_nil) + E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, t->expr->string); + E_Eval eval = e_eval_from_string(t->expr->string); + switch(eval.space.kind) { - E_Eval eval = e_eval_from_expr(scratch.arena, macro_expr); - switch(eval.space.kind) + default:{is_static_for_ctrl_thread = 0;}break; + case E_SpaceKind_Null: + case RD_EvalSpaceKind_MetaCfg: { - default:{is_static_for_ctrl_thread = 0;}break; - case E_SpaceKind_Null: - case RD_EvalSpaceKind_MetaCfg: - { - is_static_for_ctrl_thread = 1; - }break; - } + is_static_for_ctrl_thread = 1; + }break; } } for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) @@ -15874,7 +15844,7 @@ Z(getting_started) String8 non_ctrl_thread_static_condition = src_bp_cnd; if(is_static_for_ctrl_thread) { - E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd); + E_Eval eval = e_eval_from_string(src_bp_cnd); E_Eval value_eval = e_value_eval_from_eval(eval); if(value_eval.value.u64 == 0) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 936afa92..7edf3690 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -635,6 +635,9 @@ struct RD_State // rjf: dbgi match store DI_MatchStore *match_store; + // rjf: evaluation cache + E_Cache *eval_cache; + // rjf: ambiguous path table (constructed from-scratch each frame) U64 ambiguous_path_slots_count; RD_AmbiguousPathNode **ambiguous_path_slots; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a3bd9650..4ff074b6 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -75,14 +75,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { String8 cmd_name = accel->v[idx]; - RD_CmdKindInfo *cmd_info = rd_cmd_kind_info_from_string(cmd_name); - E_TypeKey cmd_type = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - cmd_type = e_type_key_cons_meta_description(cmd_type, cmd_info->description); - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = cmd_type; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs_out[out_idx] = expr; + E_Eval cmd_eval = e_eval_from_stringf("query:commands.%S", cmd_name); + exprs_out[out_idx] = cmd_eval.expr; } } @@ -105,7 +99,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) B32 passes_filter = 1; if(filter.size != 0) { - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); E_Type *type = e_type_from_key__cached(eval.irtree.type_key); if(type->kind != E_TypeKind_Set) { @@ -196,7 +190,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(locals) E_TypeExpandInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_ctx->locals_map); e_string2num_map_node_array_sort__in_place(&nodes); String8List exprs_filtered = {0}; for EachIndex(idx, nodes.count) @@ -768,12 +762,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_from_string(str8_lit("query:commands")).expr; - E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(commands); + E_Eval cmds_eval = e_eval_from_stringf("query:commands"); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - exprs_out[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); + E_Eval cmd_eval = e_eval_wrapf(cmds_eval, "$.%S", cmd_name); + exprs_out[dst_idx] = cmd_eval.expr; } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 72dfa6a5..24238e73 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1108,14 +1108,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &row->eval.irtree; - for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + E_ParentKey(row->eval.key) { - E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + { + E_Eval cell_eval = e_eval_from_expr(maybe_table_type->args[idx]); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + } } - e_ir_state->overridden_irtree = prev_overridden_irtree; info.can_expand = 0; #undef take_pct } @@ -1229,7 +1229,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "enabled"), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "enabled"), .flags = RD_WatchCellFlag_Background, .px = floor_f32(ui_top_font_size()*5.f)); } @@ -1237,7 +1237,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + e_eval_from_stringf("query:commands.%S", cmd_name), .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*3.f)); } @@ -1259,7 +1259,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "active"), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "active"), .edit_string = row->edit_string, .px = floor_f32(ui_top_font_size()*5.f)); } @@ -1271,7 +1271,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) cmd_kind = RD_CmdKind_DeselectEntity; } String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf("query:commands.%S", cmd_name), .edit_string = row->edit_string, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*3.f)); @@ -1383,7 +1383,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1395,12 +1395,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.cell_style_key = str8_lit("call_stack_frame"); CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); - E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); - E_Eval module_eval = e_eval_from_expr(arena, expr); + E_Eval module_eval = ctrl_eval_from_handle(module->handle); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); RD_Cfg *w_cfg = style->first; @@ -1408,7 +1403,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct @@ -1430,8 +1425,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -2088,13 +2083,13 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); - eval = e_eval_from_stringf(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); + eval = e_eval_from_stringf("(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); } else { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); - eval = e_eval_from_stringf(scratch.arena, "(rip.u64 & (~(0x4000 - 1)))"); + eval = e_eval_from_stringf("(rip.u64 & (~(0x4000 - 1)))"); } } @@ -2655,10 +2650,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_ir_state->ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_ir_ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; - E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); + E_Eval local_eval = e_eval_from_string(local_name); if(local_eval.irtree.mode == E_Mode_Offset) { E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.irtree.type_key); @@ -3463,20 +3458,20 @@ rd_eval_color_from_eval(E_Eval eval) // rjf: leaf u32 -> take all 4 components case E_TypeKind_U32: { - component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); - component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); - component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x0000ff00) >> 8) / 255.f")); - component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x000000ff) >> 0) / 255.f")); + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x0000ff00) >> 8) / 255.f")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x000000ff) >> 0) / 255.f")); num_components_left -= 4; }break; //- rjf: array -> generate tasks for first four elements case E_TypeKind_Array: { - component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[0])")); - component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[1])")); - component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[2])")); - component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[3])")); + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[0])")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[1])")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[2])")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[3])")); num_components_left -= 4; }break; } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 27ca3d96..3fd8a761 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1983,7 +1983,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_Cfg *pin = n->v; String8 pin_expr = rd_expr_from_cfg(pin); - E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); + E_Eval eval = e_eval_from_string(pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { @@ -2327,7 +2327,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // if(!ui_dragging(text_container_sig) && text_container_sig.event_flags == 0 && mouse_expr.size != 0) { - E_Eval eval = e_eval_from_string(scratch.arena, mouse_expr); + E_Eval eval = e_eval_from_string(mouse_expr); if(eval.msgs.max_kind == E_MsgKind_Null && (eval.irtree.mode != E_Mode_Null || mouse_expr_is_explicit)) { U64 line_vaddr = 0; From a35e4836294a5739e14b642649fe338698cc84f9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 09:36:00 -0700 Subject: [PATCH 443/755] switch type expansion hooks to being eval-based, not expr/irtree-based --- src/eval/eval_core.c | 9 +- src/eval/eval_core.h | 52 +++++---- src/eval/eval_types.c | 76 +++++-------- .../eval_visualization_core.c | 50 ++++----- .../eval_visualization_core.h | 2 +- src/raddbg/raddbg_eval.c | 106 ++++++------------ 6 files changed, 111 insertions(+), 184 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 7e8d5757..c9d9ddb6 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -852,10 +852,11 @@ 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), + .key = bundle->key, + .string = bundle->string, + .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; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 3893e0ec..b56d64be 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -286,6 +286,16 @@ struct E_ExprList U64 count; }; +typedef struct E_Parse E_Parse; +struct E_Parse +{ + E_TokenArray tokens; + E_Token *last_token; + E_Expr *expr; + E_Expr *last_expr; + E_MsgList msgs; +}; + //////////////////////////////// //~ rjf: IR Tree Types @@ -312,6 +322,17 @@ struct E_IRTreeAndType E_IRTreeAndType *prev; }; +//////////////////////////////// +//~ rjf: Bytecode Interpretation Types + +typedef struct E_Interpretation E_Interpretation; +struct E_Interpretation +{ + E_Value value; + E_Space space; + E_InterpretationCode code; +}; + //////////////////////////////// //~ rjf: Evaluation Artifact Bundle @@ -319,6 +340,7 @@ typedef struct E_Eval E_Eval; struct E_Eval { E_Key key; + String8 string; E_Expr *expr; E_IRTreeAndType irtree; String8 bytecode; @@ -432,12 +454,12 @@ typedef E_TYPE_IREXT_FUNCTION_SIG(E_TypeIRExtFunctionType); #define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) typedef E_TYPE_ACCESS_FUNCTION_SIG(E_TypeAccessFunctionType); -#define E_TYPE_EXPAND_INFO_FUNCTION_SIG(name) E_TypeExpandInfo name(Arena *arena, E_Expr *expr, E_IRTreeAndType *irtree, String8 filter) +#define E_TYPE_EXPAND_INFO_FUNCTION_SIG(name) E_TypeExpandInfo name(Arena *arena, E_Eval eval, String8 filter) #define E_TYPE_EXPAND_INFO_FUNCTION_NAME(name) e_type_expand_info__##name #define E_TYPE_EXPAND_INFO_FUNCTION_DEF(name) internal E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TYPE_EXPAND_INFO_FUNCTION_NAME(name)) typedef E_TYPE_EXPAND_INFO_FUNCTION_SIG(E_TypeExpandInfoFunctionType); -#define E_TYPE_EXPAND_RANGE_FUNCTION_SIG(name) void name(Arena *arena, void *user_data, E_Expr *expr, E_IRTreeAndType *irtree, String8 filter, Rng1U64 idx_range, E_Expr **exprs_out, String8 *exprs_strings_out) +#define E_TYPE_EXPAND_RANGE_FUNCTION_SIG(name) void name(Arena *arena, void *user_data, E_Eval eval, String8 filter, Rng1U64 idx_range, E_Eval *evals_out) #define E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name) e_type_expand_range__##name #define E_TYPE_EXPAND_RANGE_FUNCTION_DEF(name) internal E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)) typedef E_TYPE_EXPAND_RANGE_FUNCTION_SIG(E_TypeExpandRangeFunctionType); @@ -698,30 +720,6 @@ struct E_IRCtx E_AutoHookMap *auto_hook_map; }; -//////////////////////////////// -//~ rjf: Parse Results - -typedef struct E_Parse E_Parse; -struct E_Parse -{ - E_TokenArray tokens; - E_Token *last_token; - E_Expr *expr; - E_Expr *last_expr; - E_MsgList msgs; -}; - -//////////////////////////////// -//~ rjf: Bytecode Interpretation Types - -typedef struct E_Interpretation E_Interpretation; -struct E_Interpretation -{ - E_Value value; - E_Space space; - E_InterpretationCode code; -}; - //////////////////////////////// //~ rjf: Core Evaluation Cache Types @@ -991,7 +989,7 @@ read_only global E_String2NumMap e_string2num_map_nil = {0}; read_only global E_String2ExprMap e_string2expr_map_nil = {0}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -read_only global E_Eval e_eval_nil = {{0}, &e_expr_nil, {&e_irnode_nil}}; +read_only global E_Eval e_eval_nil = {{0}, {0}, &e_expr_nil, {&e_irnode_nil}}; read_only global E_Module e_module_nil = {&rdi_parsed_nil}; read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; thread_static E_BaseCtx *e_base_ctx = 0; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6b4156b0..5b4d4d97 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2103,7 +2103,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) { //- rjf: try to extract a struct-like type key, enum-like, or array-like // type key, for expansion - E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + E_TypeKey expand_type_key = e_default_expansion_type_from_key(eval.irtree.type_key); //- rjf: struct type? -> use the struct type for expansion B32 did_expansion = 0; @@ -2154,7 +2154,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { //- rjf: try to extract a struct-like type key, enum-like, or array-like // type key, for expansion - E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + E_TypeKey expand_type_key = e_default_expansion_type_from_key(eval.irtree.type_key); E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); //- rjf: struct case -> the lookup-range will return a range of members @@ -2170,7 +2170,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = data_members.v[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); + evals_out[idx] = e_eval_wrapf(eval, "$.%S", member_name); } } @@ -2185,7 +2185,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = type->enum_vals[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); + evals_out[idx] = e_eval_wrapf(eval, "$.%S", member_name); } } @@ -2197,7 +2197,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); + evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", idx_range.min + idx); } } } @@ -2219,21 +2219,21 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) E_TYPE_EXPAND_INFO_FUNCTION_DEF(only) { - E_Type *type = e_type_from_key__cached(irtree->type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); E_TypeExpandInfo info = {0, type->count}; return info; } E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) { - E_Type *type = e_type_from_key__cached(irtree->type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); U64 out_idx = 0; for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { E_Expr *arg = type->args[idx]; if(arg->string.size != 0) { - exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, arg->string); + evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", arg->string); } } } @@ -2243,12 +2243,13 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) { - E_Type *type = e_type_from_key__cached(irtree->type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); String8Array allowed_children_array = {0}; { Temp scratch = scratch_begin(&arena, 1); String8List allowed_children = {0}; { +#if 0 // TODO(rjf): @eval E_Type *stripped_type = e_type_from_key__cached(type->direct_type_key); // TODO(rjf): this is kind of ugly due to the need to call irext, // i wish it was possible to have an easier way to "strip" the current @@ -2289,6 +2290,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) } } } +#endif } allowed_children_array = str8_array_from_list(arena, &allowed_children); scratch_end(scratch); @@ -2308,7 +2310,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(omit) String8 name = ext->v[idx]; if(name.size != 0) { - exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, name); + evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", name); } } } @@ -2318,18 +2320,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(omit) E_TYPE_EXPAND_INFO_FUNCTION_DEF(sequence) { - E_Type *type = e_type_from_key__cached(irtree->type_key); - U64 count = 0; - { - Temp scratch = scratch_begin(&arena, 1); - E_OpList count_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); - String8 count_bytecode = e_bytecode_from_oplist(scratch.arena, &count_oplist); - E_Interpretation count_interpret = e_interpret(count_bytecode); - E_Value count_value = count_interpret.value; - count = count_value.u64; - scratch_end(scratch); - } - E_TypeExpandInfo info = {0, count}; + E_TypeExpandInfo info = {0, eval.value.u64}; return info; } @@ -2338,9 +2329,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); - expr->value.u64 = idx_range.min + idx; - exprs_out[idx] = expr; + evals_out[idx] = e_eval_from_stringf("%I64u", idx_range.min + idx); } } @@ -2349,7 +2338,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence) E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) { - E_Type *type = e_type_from_key__cached(irtree->type_key); + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); U64 count = 1; if(type->args != 0 && type->count > 0) { @@ -2366,7 +2355,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); + evals_out[idx] = e_eval_wrapf(eval, "$[I64u]", idx_range.min + idx); } } @@ -2525,7 +2514,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice) { - E_SliceAccel *accel = (E_SliceAccel *)irtree->user_data; + E_SliceAccel *accel = (E_SliceAccel *)eval.irtree.user_data; E_TypeExpandInfo info = {accel, accel->count}; return info; } @@ -2535,7 +2524,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); + evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", idx_range.min + idx); } } @@ -2557,11 +2546,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder) Temp scratch = scratch_begin(&arena, 1); //- rjf: evaluate lhs file path ID - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - E_Value lhs_value = lhs_interp.value; - U64 lhs_string_id = lhs_value.u64; + U64 lhs_string_id = eval.value.u64; String8 folder_path = e_string_from_id(lhs_string_id); //- rjf: compute filter - omit common prefixes (common parent paths) @@ -2621,30 +2606,20 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder) for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = &e_expr_nil; - String8 expr_string = {0}; + String8 path_expr_string = {0}; if(0 <= idx && idx < accel->folders.count) { String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); - expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder")); - expr->space = e_space_make(E_SpaceKind_FileSystem); - expr->value.u64 = e_id_from_string(folder_path); - expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name)); + path_expr_string = push_str8f(arena, "file:\"%S\"", escaped_from_raw_str8(scratch.arena, folder_path)); } else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) { String8 file_name = accel->files.v[idx - accel->folders.count]; String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name); - expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file")); - expr->space = e_space_make(E_SpaceKind_FileSystem); - expr->value.u64 = e_id_from_string(file_path); - expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name)); + path_expr_string = push_str8f(arena, "file:\"%S\"", escaped_from_raw_str8(scratch.arena, file_path)); } - exprs_out[out_idx] = expr; - exprs_strings_out[out_idx] = expr_string; + evals_out[out_idx] = e_eval_from_string(path_expr_string); scratch_end(scratch); } } @@ -2783,7 +2758,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(file) E_TYPE_EXPAND_INFO_FUNCTION_DEF(file) { - E_FileAccel *accel = (E_FileAccel *)irtree->user_data; + E_FileAccel *accel = (E_FileAccel *)eval.irtree.user_data; E_TypeExpandInfo info = {accel, accel->fields.count}; return info; } @@ -2805,8 +2780,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file) rhs->string = push_str8_copy(arena, name); e_expr_push_child(expr, lhs); e_expr_push_child(expr, rhs); + evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", name); } - exprs_out[out_idx] = expr; - exprs_strings_out[out_idx] = string; } } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 77e7a380..422ff1ec 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -587,7 +587,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval // rjf: get top-level lookup/expansion info // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key - E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); + E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval, filter); EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); // rjf: determine expansion info @@ -701,21 +701,16 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval if(viz_expand_info.rows_default_expanded || ev_expansion_from_key(view, child_keys[idx])) { Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); - E_Expr *child_expr = &e_expr_nil; - String8 child_string = {0}; - type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, &t->eval.irtree, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); - if(child_expr != &e_expr_nil) - { - E_Eval child_eval = e_eval_from_expr(child_expr); - EV_Key child_key = child_keys[idx]; - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->parent_block = expansion_block; - task->eval = child_eval; - task->child_id = child_key.child_id; - task->split_relative_idx = split_relative_idx; - task->default_expanded = viz_expand_info.rows_default_expanded; - } + E_Eval child_eval = {0}; + type_expand_rule->range(arena, type_expand_info.user_data, t->eval, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); + EV_Key child_key = child_keys[idx]; + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->parent_block = expansion_block; + task->eval = child_eval; + task->child_id = child_key.child_id; + task->split_relative_idx = split_relative_idx; + task->default_expanded = viz_expand_info.rows_default_expanded; } } @@ -1009,11 +1004,10 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 // rjf: get info about expansion range B32 is_standalone_row = 0; U64 range_exprs_count = dim_1u64(block_relative_range__windowed); - E_Expr **range_exprs = push_array(arena, E_Expr *, range_exprs_count); - String8 *range_exprs_strings = push_array(arena, String8 ,range_exprs_count); + E_Eval *range_evals = push_array(arena, E_Eval, range_exprs_count); for EachIndex(idx, range_exprs_count) { - range_exprs[idx] = &e_expr_nil; + range_evals[idx] = e_eval_nil; } if(n->v.block->viz_expand_info.single_item || n->v.block->parent == &ev_nil_block) { @@ -1021,7 +1015,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } else { - n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval.expr, &n->v.block->eval.irtree, filter, block_relative_range__windowed, range_exprs, range_exprs_strings); + n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval, filter, block_relative_range__windowed, range_evals); } // rjf: no expansion operator applied -> push row for block expression; pass through block info @@ -1046,8 +1040,7 @@ ev_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 = ev_block_id_from_num(n->v.block, child_num); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); - E_Expr *row_expr = range_exprs[idx]; - E_Eval row_eval = e_eval_from_expr(row_expr); + E_Eval row_eval = range_evals[idx]; EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1055,7 +1048,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 row->block = n->v.block; row->key = row_key; row->visual_size = 1; - row->edit_string = range_exprs_strings[idx]; + row->edit_string = row_eval.string; row->eval = row_eval; } } @@ -2107,7 +2100,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) expand_data->type = e_type_from_key__cached(type_key); expand_data->expand_rule = e_expand_rule_from_type_key(type_key); // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key - expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); + expand_data->expand_info = expand_data->expand_rule->info(arena, eval, params->filter); } switch(task_idx) { @@ -2128,15 +2121,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: middle step -> generate new task for next thing in expansion else { - E_Expr *next_expr = &e_expr_nil; - String8 next_string = {0}; - expand_data->expand_rule->range(arena, expand_data->expand_info.user_data, eval.expr, &eval.irtree, params->filter, r1u64(task_idx-1, task_idx), &next_expr, &next_string); - if(next_expr != &e_expr_nil) + E_Eval next_eval = {0}; + expand_data->expand_rule->range(arena, expand_data->expand_info.user_data, eval, params->filter, r1u64(task_idx-1, task_idx), &next_eval); + if(next_eval.expr != 0 && next_eval.expr != &e_expr_nil) { need_new_task = 1; need_pop = 0; new_task.params = *params; - new_task.eval = e_eval_from_expr(next_expr); + new_task.eval = next_eval; if(task_idx > 1) { *out_string = str8_lit(", "); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index bed73c3f..84d2f7fb 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -294,7 +294,7 @@ global read_only EV_Block ev_nil_block = {0}, 0, {0}, - {{0}, &e_expr_nil, &e_irnode_nil}, + {{0}, {0}, &e_expr_nil, &e_irnode_nil}, {0}, &e_type_expand_rule__default, {0}, diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 4ff074b6..7ab12cce 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -76,7 +76,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) { String8 cmd_name = accel->v[idx]; E_Eval cmd_eval = e_eval_from_stringf("query:commands.%S", cmd_name); - exprs_out[out_idx] = cmd_eval.expr; + evals_out[out_idx] = cmd_eval; } } @@ -138,8 +138,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) if(cfg_idx < cfgs->count) { String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs_out[idx] = e_parse_from_string(expr_string).expr; - exprs_strings_out[idx] = push_str8_copy(arena, expr_string); + evals_out[idx] = e_eval_from_string(expr_string); } } } @@ -220,8 +219,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) for(U64 idx = 0; idx < read_range_count; idx += 1) { String8 expr_string = accel->v[read_range.min + idx]; - exprs_out[idx] = e_parse_from_string(expr_string).expr; - exprs_strings_out[idx] = push_str8_copy(arena, expr_string); + evals_out[idx] = e_eval_from_string(expr_string); } } @@ -271,8 +269,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) { String8 register_name = accel->v[read_range.min + idx]; String8 register_expr = push_str8f(arena, "reg:%S", register_name); - exprs_strings_out[idx] = register_name; - exprs_out[idx] = e_parse_from_string(register_expr).expr; + evals_out[idx] = e_eval_from_string(register_expr); } } @@ -503,7 +500,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) Temp scratch = scratch_begin(&arena, 1); // rjf: unpack - RD_SchemaIRExt *ext = (RD_SchemaIRExt *)irtree->user_data; + RD_SchemaIRExt *ext = (RD_SchemaIRExt *)eval.irtree.user_data; // rjf: gather expansion commands String8Array commands = {0}; @@ -597,7 +594,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) Rng1U64 read_range = intersect_1u64(idx_range, cmds_idx_range); for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) { - exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, accel->commands.v[idx - cmds_idx_range.min]); + evals_out[out_idx] = e_eval_from_stringf("query:commands.%S", accel->commands.v[idx - cmds_idx_range.min]); } } @@ -607,7 +604,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) { MD_Node *child_schema = accel->children[idx - chld_idx_range.min]; - exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, child_schema->string); + evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", child_schema->string); } } } @@ -719,7 +716,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs) Temp scratch = scratch_begin(&arena, 1); { //- rjf: unpack - RD_CfgsIRExt *ext = (RD_CfgsIRExt *)irtree->user_data; + RD_CfgsIRExt *ext = (RD_CfgsIRExt *)eval.irtree.user_data; //- rjf: filter cfgs RD_CfgArray cfgs__filtered = ext->cfgs; @@ -767,7 +764,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; E_Eval cmd_eval = e_eval_wrapf(cmds_eval, "$.%S", cmd_name); - exprs_out[dst_idx] = cmd_eval.expr; + evals_out[dst_idx] = cmd_eval; } } @@ -778,7 +775,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - exprs_out[dst_idx] = e_expr_irext_member_access(arena, expr, irtree, push_str8f(arena, "$%I64d", cfg->id)); + evals_out[dst_idx] = e_eval_wrapf(eval, "$.$%I64d", cfg->id); } } } @@ -883,7 +880,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack) E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) { - RD_CallStackAccel *accel = (RD_CallStackAccel *)irtree->user_data; + RD_CallStackAccel *accel = (RD_CallStackAccel *)eval.irtree.user_data; E_TypeExpandInfo result = {0}; result.user_data = accel; result.expr_count = accel->call_stack.count; @@ -945,7 +942,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(environment) E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) { - RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)irtree->user_data; + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)eval.irtree.user_data; E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; return result; } @@ -961,7 +958,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment) U64 cfg_idx = read_range.min + idx; if(cfg_idx < accel->cfgs.count) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, cfg_idx); + evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", cfg_idx); } } } @@ -1022,10 +1019,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) Temp scratch = scratch_begin(&arena, 1); //- rjf: evaluate lhs machine, if we have one - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); - CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(eval.space); //- rjf: gather all machines we're searching through CTRL_EntityArray machines = {0}; @@ -1113,12 +1107,13 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { +#if 0 // TODO(rjf): @eval E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); expr->type_key = unattached_process_type; expr->value.u128.u64[0] = accel->infos[idx].pid; expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); - exprs_out[out_idx] = expr; +#endif } } @@ -1170,17 +1165,14 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) Temp scratch = scratch_begin(&arena, 1); { //- rjf: determine which entity we're looking under - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); - String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); - E_Interpretation lhs_interp = e_interpret(lhs_bytecode); CTRL_Entity *scoping_entity = &ctrl_entity_nil; - if(lhs_interp.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { - scoping_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); + scoping_entity = rd_ctrl_entity_from_eval_space(eval.space); } //- rjf: determine which type of child we're gathering - E_TypeKey lhs_type_key = irtree->type_key; + E_TypeKey lhs_type_key = eval.irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); String8 name = rd_singular_from_code_name_plural(lhs_type->name); CTRL_EntityKind entity_kind = ctrl_entity_kind_from_string(name); @@ -1242,7 +1234,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(ctrl_entities) for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) { CTRL_Entity *entity = entities->v[out_idx + read_range.min]; - exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, ctrl_string_from_handle(arena, entity->handle)); + evals_out[out_idx] = ctrl_eval_from_handle(entity->handle); } } @@ -1265,7 +1257,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table) // rjf: determine which debug info section we're dealing with RDI_SectionKind section = RDI_SectionKind_NULL; { - E_TypeKey lhs_type_key = irtree->type_key; + E_TypeKey lhs_type_key = eval.irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); if(0){} else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} @@ -1327,8 +1319,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; E_Module *module = &e_base_ctx->modules[item->dbgi_idx]; - // rjf: build expr - E_Expr *item_expr = &e_expr_nil; + // rjf: build item's evaluation + E_Eval item_eval = e_eval_nil; { U64 element_idx = item->idx; switch(accel->section) @@ -1336,7 +1328,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) default:{}break; case RDI_SectionKind_Procedures: { - Temp scratch = scratch_begin(&arena, 1); RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx); RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx); U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first); @@ -1348,64 +1339,35 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); String8 symbol_name = {0}; symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); - String8List strings = {0}; - e_type_lhs_string_from_key(scratch.arena, type_key, &strings, 0, 0); - str8_list_push(scratch.arena, &strings, symbol_name); - e_type_rhs_string_from_key(scratch.arena, type_key, &strings, 0); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Value; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string = str8_list_join(arena, &strings, 0); - scratch_end(scratch); + item_eval = e_eval_from_string(symbol_name); }break; case RDI_SectionKind_GlobalVariables: { RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); - U64 voff = gvar->voff; - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = gvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size); + String8 symbol_name = {0}; + symbol_name.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &symbol_name.size); + item_eval = e_eval_from_string(symbol_name); }break; case RDI_SectionKind_ThreadVariables: { RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(tvar->tls_off)); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = tvar->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0); - item_expr->mode = E_Mode_Offset; - item_expr->space = module->space; - item_expr->type_key = type_key; - item_expr->bytecode = bytecode; - item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size); + String8 symbol_name = {0}; + symbol_name.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &symbol_name.size); + item_eval = e_eval_from_string(symbol_name); }break; case RDI_SectionKind_UDTs: { RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx); RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); - E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_base_ctx->modules)); - item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - item_expr->type_key = type_key; + String8 name = {0}; + name.str = rdi_string_from_idx(module->rdi, type_node->user_defined.name_string_idx, &name.size); + item_eval = e_eval_from_string(name); }break; } } // rjf: fill - exprs_out[idx] = item_expr; + evals_out[idx] = item_eval; } } From a6c9a1bd2aea55fd3bbe7b4ab493767244af0269 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 09:52:29 -0700 Subject: [PATCH 444/755] fix editable expression strings, fix command evaluation, etc. --- src/raddbg/raddbg_core.c | 12 ++++++------ src/raddbg/raddbg_eval.c | 8 +++++--- src/raddbg/raddbg_views.c | 29 ++++++++--------------------- src/raddbg/raddbg_views.h | 1 - 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d7a435ec..9375c84d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3219,15 +3219,15 @@ rd_view_ui(Rng2F32 rect) if(cell_info.flags & RD_WatchCellFlag_CanEdit) { any_edits_started = 1; - String8 string = cell->edit_string; - if(string.size == 0) + String8 string = {0}; + if(cell_info.flags & RD_WatchCellFlag_NoEval) + { + string = cell->eval.string; + } + else { string = dr_string_from_fstrs(scratch.arena, &cell_info.eval_fstrs); } - if(string.size == 0) - { - string = dr_string_from_fstrs(scratch.arena, &cell_info.expr_fstrs); - } string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); RD_WatchPt pt = {row->block->key, row->key, rd_id_from_watch_cell(cell)}; U64 hash = ev_hash_from_key(pt.key); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7ab12cce..d8eeea5f 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -638,7 +638,6 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs) //- rjf: gather commands String8List cmds_list = {0}; - if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) == &rd_nil_cfg) { MD_NodePtrList schemas = rd_schemas_from_name(cfg_name); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) @@ -738,9 +737,12 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs) } //- rjf: fill - accel->cmds = ext->cmds; + if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) == &rd_nil_cfg) + { + accel->cmds = ext->cmds; + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + } accel->cfgs = cfgs__filtered; - accel->cmds_idx_range = r1u64(0, accel->cmds.count); accel->cfgs_idx_range = r1u64(accel->cmds_idx_range.max, accel->cmds_idx_range.max + accel->cfgs.count); info.expr_count = (accel->cmds.count + accel->cfgs.count); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 24238e73..fdd40619 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1129,7 +1129,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_IsNonCode, .pct = 1.f); if(str8_match(type->name, str8_lit("file"), 0)) { info.can_expand = 0; @@ -1143,7 +1143,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1156,7 +1156,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) str8_match(row_type->name, str8_lit("unattached_process"), 0)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } @@ -1172,7 +1171,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { extra_flags |= RD_WatchCellFlag_NoEval; } - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = extra_flags|RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = extra_flags|RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1181,7 +1180,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(is_top_level && evalled_cfg != &rd_nil_cfg) { RD_Cfg *cfg = evalled_cfg; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { @@ -1252,7 +1251,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { CTRL_Entity *entity = evalled_entity; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button, .pct = 1.f); if(entity->kind == CTRL_EntityKind_Machine || @@ -1260,7 +1258,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Thread) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "active"), - .edit_string = row->edit_string, .px = floor_f32(ui_top_font_size()*5.f)); } if(entity->kind == CTRL_EntityKind_Thread) @@ -1272,7 +1269,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf("query:commands.%S", cmd_name), - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*3.f)); } @@ -1283,7 +1279,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// @@ -1295,13 +1291,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) if(type->kind == E_TypeKind_Set) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } else { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented|RD_WatchCellFlag_Button|RD_WatchCellFlag_ActivateWithSingleClick, .pct = 1.f); } @@ -1321,7 +1315,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(row->eval.expr == &e_expr_nil && info.group_cfg_name.size != 0 && info.group_cfg_child == &rd_nil_cfg) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } @@ -1335,7 +1328,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_Indented, .pct = 1.f); } @@ -1359,10 +1351,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .default_pct = 0.65f, .pct = take_pct()); #undef take_pct } @@ -1379,7 +1369,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); @@ -1421,7 +1410,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, - .edit_string = row->edit_string, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); @@ -1573,9 +1561,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla DR_FStrList expr_fstrs = {0}; if(cell->flags & RD_WatchCellFlag_Expr) { - // rjf: funnel-through this cell's string, if it has one B32 is_non_code = 0; - String8 expr_string = cell->edit_string; + String8 expr_string = {0}; // rjf: if this cell has a meta-display-name, then use that if(expr_string.size == 0) @@ -1620,10 +1607,10 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: generate expression string based on our notable expression switch(notable_expr->kind) { - // rjf: default case -> just walk the expression tree & generate a string + // rjf: default case -> just take whatever string was directly passed via the evaluation default: { - expr_string = e_string_from_expr(arena, notable_expr, str8_zero()); + expr_string = cell->eval.string; }break; // rjf: array indices -> fast path to [index] diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 03f8bbb0..c3ac1b20 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -70,7 +70,6 @@ struct RD_WatchCell RD_WatchCellKind kind; RD_WatchCellFlags flags; U64 index; - String8 edit_string; E_Eval eval; F32 default_pct; F32 pct; From a9685e6b9d7df902c76be4dc2702c017b23a41f8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 13:04:32 -0700 Subject: [PATCH 445/755] pass through eval msgs appropriately in eval cache evaluations; fix rules for reverting to overridden IR trees on usage of 'raw'; more fixes/improvements --- src/eval/eval_core.c | 20 +++ src/eval/eval_core.h | 2 + src/eval/eval_ir.c | 71 ++++++--- src/eval/eval_ir.h | 2 +- src/eval/eval_types.c | 136 ++++++++---------- .../eval_visualization_core.c | 16 ++- src/raddbg/raddbg_eval.c | 6 +- src/raddbg/raddbg_views.c | 29 ++++ src/raddbg/raddbg_widgets.c | 25 ++-- src/raddbg/raddbg_widgets.h | 1 + src/ui/ui_basic_widgets.c | 12 +- 11 files changed, 195 insertions(+), 125 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index c9d9ddb6..b1759155 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -160,6 +160,17 @@ e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push) MemoryZeroStruct(to_push); } +internal E_MsgList +e_msg_list_copy(Arena *arena, E_MsgList *src) +{ + E_MsgList dst = {0}; + for(E_Msg *msg = src->first; msg != 0; msg = msg->next) + { + e_msg(arena, &dst, msg->kind, msg->location, msg->text); + } + return dst; +} + //////////////////////////////// //~ rjf: Space Functions @@ -796,6 +807,8 @@ e_parse_from_bundle(E_CacheBundle *bundle) { bundle->flags |= E_CacheBundleFlag_Parse; bundle->parse = e_push_parse_from_string(e_cache->arena, bundle->string); + E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->parse.msgs); + e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } E_Parse parse = bundle->parse; return parse; @@ -810,6 +823,8 @@ e_irtree_from_bundle(E_CacheBundle *bundle) 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_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); + e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } E_IRTreeAndType result = bundle->irtree; return result; @@ -839,6 +854,10 @@ e_interpretation_from_bundle(E_CacheBundle *bundle) bundle->flags |= E_CacheBundleFlag_Interpret; String8 bytecode = e_bytecode_from_bundle(bundle); E_Interpretation interpret = e_interpret(bytecode); + if(E_InterpretationCode_Good < interpret.code && interpret.code < E_InterpretationCode_COUNT) + { + e_msg(e_cache->arena, &bundle->msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[interpret.code]); + } bundle->interpretation = interpret; } E_Interpretation interpret = bundle->interpretation; @@ -857,6 +876,7 @@ e_eval_from_bundle(E_CacheBundle *bundle) .expr = e_parse_from_bundle(bundle).expr, .irtree = e_irtree_from_bundle(bundle), .bytecode = e_bytecode_from_bundle(bundle), + .msgs = bundle->msgs, }; E_Interpretation interpretation = e_interpretation_from_bundle(bundle); eval.code = interpretation.code; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index b56d64be..5159b1c6 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -887,6 +887,7 @@ struct E_CacheBundle E_IRTreeAndType irtree; String8 bytecode; E_Interpretation interpretation; + E_MsgList msgs; }; typedef struct E_CacheNode E_CacheNode; @@ -1026,6 +1027,7 @@ internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text); internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...); internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push); +internal E_MsgList e_msg_list_copy(Arena *arena, E_MsgList *src); //////////////////////////////// //~ rjf: Space Functions diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ce077dc8..52eda47a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -493,14 +493,13 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr); + e_msg_list_concat_in_place(&result.msgs, &r.msgs); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); E_TypeKey direct_type = e_type_key_unwrap(l_restype, E_TypeUnwrapFlag_All); U64 direct_type_size = e_type_byte_size_from_key(direct_type); - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - e_msg_list_concat_in_place(&result.msgs, &r.msgs); // rjf: bad conditions? -> error if applicable, exit if(r.root->op == 0) @@ -586,7 +585,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -603,7 +602,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 E_Expr *expr; E_IRTreeAndType *prev; }; - Task start_task = {0, root_expr, overridden}; + Task start_task = {0, root_expr, root_overridden}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -614,9 +613,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 e_expr_poison(expr); //- rjf: select the task's previous ir-tree-and-type as the overridden tree + E_IRTreeAndType *overridden = 0; if(t->prev != 0) { - overridden = t->prev; + overridden = push_array(arena, E_IRTreeAndType, 1); + MemoryCopyStruct(overridden, t->prev); } //- rjf: do expr -> irtree generation for this expression @@ -636,6 +637,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 // rjf: unpack left-hand-side E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs); + e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev) @@ -692,11 +694,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: bad conditions? -> error if applicable, exit if(r_tree.root->op == 0) @@ -751,10 +753,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: bad conditions? -> error if applicable, exit if(r_tree.root->op == 0) @@ -779,6 +781,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr); + e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); @@ -915,12 +918,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); E_TypeKey r_type_promoted = e_type_key_promote(r_type); RDI_EvalOp op = e_opcode_from_expr_kind(kind); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: bad conditions? -> error if applicable, exit if(r_tree.root->op == 0) @@ -948,12 +951,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 // rjf: unpack operand E_Expr *r_expr = expr->first; E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool); RDI_EvalOp op = e_opcode_from_expr_kind(kind); - e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: bad conditions? -> error if applicable, exit if(r_tree.root->op == 0) @@ -1273,6 +1276,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 { E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs); + e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1294,19 +1298,30 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 e_expr_push_child(call, e_expr_ref(arena, arg)); } result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call); + E_MsgList new_msgs = {0}; + e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs); + e_msg_list_concat_in_place(&new_msgs, &result.msgs); + result.msgs = new_msgs; // rjf: is "raw"? -> try to return overridden tree, otherwise strip all // lens types from result; disallow auto-hooks if(str8_match(callee->string, str8_lit("raw"), 0)) { disallow_autohooks = 1; - if(overridden != 0) + if(overridden->root != &e_irnode_nil) { - result = *overridden; - for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) + E_MsgList existing_msgs = result.msgs; + for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev) { result = *prev; + if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens) + { + break; + } } + E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs); + result.msgs = existing_msgs; + e_msg_list_concat_in_place(&result.msgs, &overridden_msgs); } else { @@ -1322,7 +1337,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 Temp scratch = scratch_begin(&arena, 1); // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next); // rjf: count extra arguments U64 arg_count = 0; @@ -1346,17 +1361,25 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 if(str8_match(lhs_type->name, str8_lit("raw"), 0)) { disallow_autohooks = 1; - if(overridden != 0) + if(overridden->root != &e_irnode_nil) { + E_MsgList existing_msgs = result.msgs; result = *overridden; - for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) + for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev) { result = *prev; + if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens) + { + break; + } } + E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs); + result.msgs = existing_msgs; + e_msg_list_concat_in_place(&result.msgs, &overridden_msgs); } else { - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next); result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -1484,7 +1507,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 } //- rjf: try to map name as overridden expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && overridden != 0) + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && (overridden->root != &e_irnode_nil || overridden->msgs.first != 0)) { E_OpList oplist = e_oplist_from_irtree(arena, overridden->root); string_mapped = 1; @@ -1492,11 +1515,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 mapped_bytecode_mode = overridden->mode; mapped_type_key = overridden->type_key; disallow_autohooks = 1; + E_MsgList msgs = e_msg_list_copy(arena, &overridden->msgs); + e_msg_list_concat_in_place(&result.msgs, &msgs); } //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(!string_mapped && overridden != 0) + if(!string_mapped && overridden->root != &e_irnode_nil) { + // TODO(rjf): @eval E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string); E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access); if(access_irtree.root != &e_irnode_nil) @@ -1506,6 +1532,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 mapped_type_key = access_irtree.type_key; mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = access_irtree.mode; + e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); } } @@ -1884,7 +1911,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 } //- rjf: error on failure-to-generate - if(!generated) + if(!generated && !str8_match(string, str8_lit("$"), 0)) { e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); } @@ -2066,8 +2093,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 //- rjf: equip previous task's irtree if(t->prev != 0) { - result.prev = push_array(arena, E_IRTreeAndType, 1); - result.prev[0] = *t->prev; + result.prev = overridden; } //- rjf: find any auto hooks according to this generation's type @@ -2084,8 +2110,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; - task->prev = push_array(scratch.arena, E_IRTreeAndType, 1); - task->prev[0] = result; + task->prev = &result; break; } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 2bc467dd..c98a70fa 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 5b4d4d97..8f4fe480 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1367,7 +1367,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) padding_member->kind = E_MemberKind_Padding; padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, E_TypeFlag_IsNotText); padding_member->off = n->off; - padding_member->name = push_str8f(arena, "[padding %I64u]", padding_idx); + padding_member->name = push_str8f(arena, "$padding_%I64u", padding_idx); padding_idx += 1; } members = new_members; @@ -2355,13 +2355,21 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array) U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - evals_out[idx] = e_eval_wrapf(eval, "$[I64u]", idx_range.min + idx); + evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", idx_range.min + idx); } } //////////////////////////////// //~ rjf: (Built-In Type Hooks) `slice` lens +typedef struct E_SliceIRExt E_SliceIRExt; +struct E_SliceIRExt +{ + E_Member *base_ptr_member; + E_Member *opl_ptr_member; + E_Member *count_member; +}; + typedef struct E_SliceAccel E_SliceAccel; struct E_SliceAccel { @@ -2373,7 +2381,7 @@ struct E_SliceAccel E_TYPE_IREXT_FUNCTION_DEF(slice) { - E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1); + E_SliceIRExt *ext = push_array(arena, E_SliceIRExt, 1); { Temp scratch = scratch_begin(&arena, 1); @@ -2416,77 +2424,21 @@ E_TYPE_IREXT_FUNCTION_DEF(slice) } } - // rjf: determine architecture - Arch arch = e_base_ctx->primary_module->arch; - if(base_ptr_member != 0) - { - E_Type *type = e_type_from_key__cached(base_ptr_member->type_key); - arch = type->arch; - } - - // rjf: evaluate count member, determine count - U64 count = 0; - if(count_member != 0) - { - E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, irtree, count_member->name); - E_Value count_member_value = e_value_from_expr(count_member_expr); - count = count_member_value.u64; - } - - // rjf: evaluate base ptr member, determine base address - U64 base_ptr_vaddr = 0; - if(base_ptr_member != 0) - { - E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, base_ptr_member->name); - E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr); - base_ptr_vaddr = base_ptr_member_value.u64; - } - - // rjf: evaluate opl ptr member, determine opl address - U64 opl_ptr_vaddr = 0; - if(count_member == 0 && opl_ptr_member != 0) - { - E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, opl_ptr_member->name); - E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr); - opl_ptr_vaddr = opl_ptr_member_value.u64; - } - - // rjf: determine element type - E_TypeKey element_type_key = zero_struct; - if(base_ptr_member != 0) - { - element_type_key = e_type_key_direct(base_ptr_member->type_key); - } - - // rjf: if no count, but base/opl, swap base/opl if needed, and measure count - if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0) - { - U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr); - U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr); - base_ptr_vaddr = min_vaddr; - opl_ptr_vaddr = max_vaddr; - count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key); - } - - // rjf: fill - if((count_member || opl_ptr_member) && base_ptr_member) - { - accel->arch = arch; - accel->count = count; - accel->base_ptr_vaddr = base_ptr_vaddr; - accel->element_type_key = element_type_key; - } + // rjf: fill extension + ext->base_ptr_member = base_ptr_member; + ext->opl_ptr_member = opl_ptr_member; + ext->count_member = count_member; } scratch_end(scratch); } - E_IRExt result = {accel}; + E_IRExt result = {ext}; return result; } E_TYPE_ACCESS_FUNCTION_DEF(slice) { E_IRTreeAndType result = {&e_irnode_nil}; - E_SliceAccel *accel = (E_SliceAccel *)lhs_irtree->user_data; + E_SliceIRExt *ext = (E_SliceIRExt *)lhs_irtree->user_data; switch(expr->kind) { default: @@ -2495,18 +2447,37 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, overridden, expr, lhs_irtree); }break; case E_ExprKind_ArrayIndex: + if(ext->base_ptr_member != 0) { - E_Value rhs_value = e_value_from_expr(expr->first->next); - U64 rhs_idx = rhs_value.u64; - if(0 <= rhs_idx && rhs_idx < accel->count) + Temp scratch = scratch_begin(&arena, 1); + + // rjf: compute bytecode of struct + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root); + String8 lhs_bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + + // rjf: build expression tree to access base pointer's member, then do an index + E_Expr *idx_expr = e_push_expr(scratch.arena, E_ExprKind_ArrayIndex, 0); + E_Expr *dot_expr = e_push_expr(scratch.arena, E_ExprKind_MemberAccess, 0); + E_Expr *lhs_expr = e_push_expr(scratch.arena, E_ExprKind_LeafBytecode, 0); + E_Expr *base_ptr_expr = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, 0); + e_expr_push_child(dot_expr, lhs_expr); + e_expr_push_child(dot_expr, base_ptr_expr); + e_expr_push_child(idx_expr, dot_expr); + e_expr_push_child(idx_expr, e_expr_ref(scratch.arena, expr->first->next)); { - E_Type *element_type = e_type_from_key__cached(accel->element_type_key); - U64 offset = element_type->byte_size*rhs_idx; - U64 vaddr = accel->base_ptr_vaddr + offset; - result.root = e_irtree_const_u(arena, vaddr); - result.type_key = accel->element_type_key; - result.mode = E_Mode_Offset; + lhs_expr->mode = lhs_irtree->mode; + lhs_expr->bytecode = lhs_bytecode; + lhs_expr->type_key = e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_Lenses); } + { + base_ptr_expr->string = ext->base_ptr_member->name; + } + + // rjf: compute struct.base_ptr IR tree + E_IRTreeAndType override = {&e_irnode_nil}; + result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, idx_expr); + + scratch_end(scratch); }break; } return result; @@ -2514,8 +2485,19 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice) { - E_SliceAccel *accel = (E_SliceAccel *)eval.irtree.user_data; - E_TypeExpandInfo info = {accel, accel->count}; + E_SliceIRExt *accel = (E_SliceIRExt *)eval.irtree.user_data; + U64 count = 0; + { + if(accel->count_member != 0) + { + count = e_value_eval_from_eval(e_eval_wrapf(eval, "$.%S", accel->count_member->name)).value.u64; + } + else if(accel->opl_ptr_member != 0 && accel->base_ptr_member != 0) + { + count = e_value_eval_from_eval(e_eval_wrapf(eval, "$.%S - $.%S", accel->opl_ptr_member->name, accel->base_ptr_member->name)).value.u64; + } + } + E_TypeExpandInfo info = {0, count}; return info; } @@ -2611,7 +2593,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder) { String8 folder_name = accel->folders.v[idx - 0]; String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name); - path_expr_string = push_str8f(arena, "file:\"%S\"", escaped_from_raw_str8(scratch.arena, folder_path)); + path_expr_string = push_str8f(arena, "folder:\"%S/\"", escaped_from_raw_str8(scratch.arena, folder_path)); } else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count) { diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 422ff1ec..086b1605 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -542,12 +542,13 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval Task *next; EV_Block *parent_block; E_Eval eval; + E_Expr *next_expr; U64 child_id; U64 split_relative_idx; B32 default_expanded; B32 force_expanded; }; - Task start_task = {0, tree.root, tree.root->eval, 1, 0}; + Task start_task = {0, tree.root, tree.root->eval, tree.root->eval.expr->next, 1, 0}; Task *first_task = &start_task; Task *last_task = first_task; @@ -708,6 +709,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; task->eval = child_eval; + task->next_expr = &e_expr_nil; task->child_id = child_key.child_id; task->split_relative_idx = split_relative_idx; task->default_expanded = viz_expand_info.rows_default_expanded; @@ -715,13 +717,14 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval } // rjf: if this expr has a sibling, push another task to continue the chain - if(t->eval.expr->next != &e_expr_nil) + if(t->next_expr != &e_expr_nil) { Task *task = push_array(scratch.arena, Task, 1); task->next = t->next; t->next = task; task->parent_block = t->parent_block; - task->eval = e_eval_from_expr(t->eval.expr->next); + task->eval = e_eval_from_expr(t->next_expr); + task->next_expr = t->next_expr->next; task->child_id = t->child_id + 1; task->split_relative_idx = 0; task->default_expanded = t->default_expanded; @@ -2048,8 +2051,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // rjf: single-length pointers -> just gen new task for deref'd expr if(ptr_data->type->count == 1) { - E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); - E_Eval deref_eval = e_eval_from_expr(deref_expr); + E_Eval deref_eval = e_eval_wrapf(eval, "*$"); need_new_task = 1; need_pop = 0; new_task.params = *params; @@ -2121,9 +2123,9 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: middle step -> generate new task for next thing in expansion else { - E_Eval next_eval = {0}; + E_Eval next_eval = e_eval_nil; expand_data->expand_rule->range(arena, expand_data->expand_info.user_data, eval, params->filter, r1u64(task_idx-1, task_idx), &next_eval); - if(next_eval.expr != 0 && next_eval.expr != &e_expr_nil) + if(next_eval.expr != &e_expr_nil) { need_new_task = 1; need_pop = 0; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index d8eeea5f..b122e5e1 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -683,9 +683,9 @@ E_TYPE_ACCESS_FUNCTION_DEF(cfgs) { String8 rhs_name = expr->first->next->string; RD_CfgID id = 0; - if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0) && - try_u64_from_str8_c_rules(str8_skip(rhs_name, 1), &id)) + if(str8_match(str8_prefix(rhs_name, 1), str8_lit("$"), 0)) { + id = u64_from_str8(str8_skip(rhs_name, 1), 16); cfg = rd_cfg_from_id(id); } }break; @@ -777,7 +777,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - evals_out[dst_idx] = e_eval_wrapf(eval, "$.$%I64d", cfg->id); + evals_out[dst_idx] = e_eval_from_stringf("$%I64x", cfg->id); } } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index fdd40619..7327ed07 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1509,6 +1509,35 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { if(0){} + //- rjf: errors + else if(cell->eval.msgs.max_kind > E_MsgKind_Null && !(cell->flags & RD_WatchCellFlag_NoEval)) + { + RD_Font(RD_FontSlot_Main) + { + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_WarningBig], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + for(E_Msg *msg = cell->eval.msgs.first; msg != 0; msg = msg->next) + { + DR_FStrList msg_fstrs = rd_fstrs_from_rich_string(arena, msg->text); + dr_fstrs_concat_in_place(&fstrs, &msg_fstrs); + if(msg->next) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + } + } + } + result.expr_fstrs = fstrs; + } + } + //- rjf: cfg evaluation -> button for cfg else if(result.cfg != &rd_nil_cfg) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 3fd8a761..2503a391 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2595,12 +2595,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe S64 column = cursor->column; Vec2F32 advance = fnt_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, column-1)); F32 cursor_off_pixels = advance.x; - F32 cursor_thickness = ClampBot(4.f, line_box->font_size/6.f); + F32 cursor_thickness = ClampBot(1.f, floor_f32(line_box->font_size/10.f)); Rng2F32 cursor_rect = { - ui_box_text_position(line_box).x+cursor_off_pixels-cursor_thickness/2.f, + ui_box_text_position(line_box).x+cursor_off_pixels, line_box->rect.y0-params->font_size*0.125f, - ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness/2.f, + ui_box_text_position(line_box).x+cursor_off_pixels+cursor_thickness, line_box->rect.y1+params->font_size*0.125f, }; Vec4F32 cursor_color = ui_color_from_name(str8_lit("cursor")); @@ -2608,7 +2608,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { cursor_color.w *= 0.5f; } - dr_rect(cursor_rect, cursor_color, 1.f, 0, 1.f); + dr_rect(cursor_rect, cursor_color, 1.f, 0, 0.f); } // rjf: extra rendering for lines with line-info that match the hovered @@ -2849,10 +2849,10 @@ rd_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, Tx //////////////////////////////// //~ rjf: UI Widgets: Fancy Labels -internal UI_Signal -rd_label(String8 string) +internal DR_FStrList +rd_fstrs_from_rich_string(Arena *arena, String8 string) { - Temp scratch = scratch_begin(0, 0); + Temp scratch = scratch_begin(&arena, 1); typedef U32 StringPartFlags; enum { @@ -2907,8 +2907,17 @@ rd_label(String8 string) fstr.params.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); } } - dr_fstrs_push(scratch.arena, &fstrs, &fstr); + dr_fstrs_push(arena, &fstrs, &fstr); } + scratch_end(scratch); + return fstrs; +} + +internal UI_Signal +rd_label(String8 string) +{ + Temp scratch = scratch_begin(0, 0); + DR_FStrList fstrs = rd_fstrs_from_rich_string(scratch.arena, string); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(box, &fstrs); UI_Signal sig = ui_signal_from_box(box); diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index d0622470..f801fc1a 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -160,6 +160,7 @@ internal B32 rd_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count //////////////////////////////// //~ rjf: UI Widgets: Fancy Labels +internal DR_FStrList rd_fstrs_from_rich_string(Arena *arena, String8 string); internal UI_Signal rd_label(String8 string); internal UI_Signal rd_error_label(String8 string); internal B32 rd_help_label(String8 string); diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index c2e8c2e7..acf08194 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -143,24 +143,24 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) TxtPt mark = draw_data->mark; F32 cursor_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, cursor.column-1)).x; F32 mark_pixel_off = fnt_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, mark.column-1)).x; - F32 cursor_thickness = ClampBot(4.f, font_size/6.f); + F32 cursor_thickness = ClampBot(1.f, floor_f32(font_size/10.f)); Rng2F32 cursor_rect = { - text_position.x + cursor_pixel_off - cursor_thickness*0.50f, + text_position.x + cursor_pixel_off, box->parent->parent->rect.y0+ui_top_font_size()*0.5f, - text_position.x + cursor_pixel_off + cursor_thickness*0.50f, + text_position.x + cursor_pixel_off + cursor_thickness, box->parent->parent->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 mark_rect = { - text_position.x + mark_pixel_off - cursor_thickness*0.50f, + text_position.x + mark_pixel_off - cursor_thickness, box->parent->parent->rect.y0+ui_top_font_size()*0.5f, - text_position.x + mark_pixel_off + cursor_thickness*0.50f, + text_position.x + mark_pixel_off + cursor_thickness, box->parent->parent->rect.y1-ui_top_font_size()*0.5f, }; Rng2F32 select_rect = union_2f32(cursor_rect, mark_rect); dr_rect(select_rect, select_color, font_size/2.f, 0, 1.f); - dr_rect(cursor_rect, cursor_color, 0.f, 0, 1.f); + dr_rect(cursor_rect, cursor_color, 0.f, 0, 0.f); } internal UI_Signal From d0cbaee3443756ece4278222816dbecbc41c8311 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 13:39:26 -0700 Subject: [PATCH 446/755] prep watch windows for floating query stacks; fix member/array-index generated-expression visualization --- src/eval/eval_ir.c | 2 +- src/raddbg/raddbg_core.c | 34 ++++++--- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 144 +++++++++++++++++++----------------- src/raddbg/raddbg_widgets.c | 2 +- 5 files changed, 102 insertions(+), 81 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 52eda47a..d56fc852 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1295,7 +1295,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, e_expr_push_child(call, first_arg); for(E_Expr *arg = lhs->next; arg != &e_expr_nil; arg = arg->next) { - e_expr_push_child(call, e_expr_ref(arena, arg)); + e_expr_push_child(call, e_expr_copy(arena, arg)); } result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call); E_MsgList new_msgs = {0}; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9375c84d..b49d3336 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2348,6 +2348,15 @@ rd_view_ui(Rng2F32 rect) RD_ViewState *vs = rd_view_state_from_cfg(view); String8 view_name = view->string; String8 expr_string = rd_expr_from_cfg(view); + B32 view_is_floating = 0; + for(RD_Cfg *p = view->parent; p != &rd_nil_cfg; p = p->parent) + { + if(str8_match(p->string, str8_lit("immediate"), 0)) + { + view_is_floating = 1; + break; + } + } ////////////////////////////// //- rjf: query extension @@ -2987,14 +2996,13 @@ rd_view_ui(Rng2F32 rect) B32 taken = 0; ////////////////////////////// - //- rjf: consume query-completion events, if this view is being used as a query + //- rjf: consume query-completion events, if this view is being used as a lister // { - RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); - if(lister != &rd_nil_cfg && - evt->kind == UI_EventKind_Press && + if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept && - selection_tbl.min.y == selection_tbl.max.y) + selection_tbl.min.y == selection_tbl.max.y && + (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || view_is_floating)) { RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); @@ -4642,8 +4650,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: this watch window is a lister? -> move cursor & accept - RD_Cfg *lister = rd_cfg_child_from_string(view, str8_lit("lister")); - if(lister != &rd_nil_cfg) + if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Accept); @@ -4745,6 +4752,13 @@ rd_view_ui(Rng2F32 rect) { rd_cmd(RD_CmdKind_SelectThread, .thread = cell_info.entity->handle); } + + // rjf: other cases, but this watch window is floating? -> move cursor & accept + else + { + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); + } } // rjf: hovering with inheritance string -> show tooltip @@ -6841,8 +6855,8 @@ rd_window_frame(void) } // rjf: view menu - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - UI_CtxMenu(view_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") + UI_Key tab_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_menu_key_")); + UI_CtxMenu(tab_menu_key) UI_PrefWidth(ui_em(50.f, 1.f)) UI_TagF("implicit") { String8 cmds[] = { @@ -7003,7 +7017,7 @@ rd_window_frame(void) {str8_lit("File"), 'f', OS_Key_F, file_menu_key}, {str8_lit("Window"), 'w', OS_Key_W, window_menu_key}, {str8_lit("Panel"), 'p', OS_Key_P, panel_menu_key}, - {str8_lit("View"), 'v', OS_Key_V, view_menu_key}, + {str8_lit("Tab"), 'b', OS_Key_V, tab_menu_key}, {str8_lit("Targets"), 't', OS_Key_T, targets_menu_key}, {str8_lit("Control"), 'c', OS_Key_C, ctrl_menu_key}, {str8_lit("Help"), 'h', OS_Key_H, help_menu_key}, diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7edf3690..a35120df 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -526,6 +526,7 @@ struct RD_WindowState B32 query_is_active; Arena *query_arena; RD_Regs *query_regs; + RD_CfgID query_view_id; RD_CfgID query_last_view_id; // rjf: hover eval state diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 7327ed07..2f3a600a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1440,6 +1440,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla ////////////////////////////// //- rjf: unpack evaluation // + E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); E_Type *cell_type = e_type_from_key__cached(cell->eval.irtree.type_key); MD_NodePtrList cell_schemas = rd_schemas_from_name(cell_type->name); if(cell->eval.space.u64s[1] == 0 && cell_schemas.count != 0) @@ -1612,84 +1613,89 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: if this cell has no string specified, then we need to synthesize one from the evaluation if(expr_string.size == 0) { - // rjf: first, locate a notable expression - we special-case things like member accesses - // or array indices, so we should grab those if possible - E_Expr *notable_expr = cell->eval.expr; - for(B32 good = 0; !good;) + // rjf: defaultly fill the cell's expression string, before trying other things + expr_string = cell->eval.string; + + // rjf: try to form a simpler expression string out of the expression tree itself, *if* this + // is not an editable expression + if(!(block_type->flags & E_TypeFlag_EditableChildren)) { + // rjf: first, locate a notable expression - we special-case things like member accesses + // or array indices, so we should grab those if possible + E_Expr *notable_expr = cell->eval.expr; + for(B32 good = 0; !good;) + { + switch(notable_expr->kind) + { + default:{good = 1;}break; + case E_ExprKind_Address: + case E_ExprKind_Deref: + case E_ExprKind_Cast: + { + notable_expr = notable_expr->last; + }break; + case E_ExprKind_Ref: + { + notable_expr = notable_expr->ref; + }break; + } + } + + // rjf: generate expression string based on our notable expression switch(notable_expr->kind) { - default:{good = 1;}break; - case E_ExprKind_Address: - case E_ExprKind_Deref: - case E_ExprKind_Cast: + // rjf: default case -> just take whatever string was directly passed via the evaluation + default:{}break; + + // rjf: array indices -> fast path to [index] + case E_ExprKind_ArrayIndex: { - notable_expr = notable_expr->last; + expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero())); }break; - case E_ExprKind_Ref: + + // rjf: member accesses -> fast-path to .name + case E_ExprKind_MemberAccess: { - notable_expr = notable_expr->ref; + Temp scratch = scratch_begin(&arena, 1); + + // TODO(rjf): @cfg need to build inheritance tooltips +#if 0 + if(member.inheritance_key_chain.count != 0) + { + String8List strings = {0}; + for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) + { + String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); + str8_list_push(scratch.arena, &strings, base_class_name); + } + result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); + } +#endif + + // rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map + // to see if we have a fancy display string for this member. otherwise, we will just + // do a code-string of ".member_name" + String8 member_name = notable_expr->first->next->string; + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem) + { + String8 fancy_name = rd_display_from_code_name(member_name); + if(fancy_name.size != 0) + { + member_name = fancy_name; + is_non_code = 1; + } + } + if(member_name.size != 0) + { + expr_string = push_str8f(arena, ".%S", member_name); + } + scratch_end(scratch); }break; } } - - // rjf: generate expression string based on our notable expression - switch(notable_expr->kind) - { - // rjf: default case -> just take whatever string was directly passed via the evaluation - default: - { - expr_string = cell->eval.string; - }break; - - // rjf: array indices -> fast path to [index] - case E_ExprKind_ArrayIndex: - { - expr_string = push_str8f(arena, "[%S]", e_string_from_expr(arena, notable_expr->last, str8_zero())); - }break; - - // rjf: member accesses -> fast-path to .name - case E_ExprKind_MemberAccess: - { - Temp scratch = scratch_begin(&arena, 1); - - // TODO(rjf): @cfg need to build inheritance tooltips -#if 0 - if(member.inheritance_key_chain.count != 0) - { - String8List strings = {0}; - for(E_TypeKeyNode *n = member.inheritance_key_chain.first; n != 0; n = n->next) - { - String8 base_class_name = e_type_string_from_key(scratch.arena, n->v); - str8_list_push(scratch.arena, &strings, base_class_name); - } - result.inheritance_tooltip = str8_list_join(arena, &strings, &(StringJoin){.sep = str8_lit_comp("::")}); - } -#endif - - // rjf: in meta-evaluation spaces, we will try to look up into our vocabulary map - // to see if we have a fancy display string for this member. otherwise, we will just - // do a code-string of ".member_name" - String8 member_name = notable_expr->first->next->string; - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - cell->eval.space.kind == E_SpaceKind_File || - cell->eval.space.kind == E_SpaceKind_FileSystem) - { - String8 fancy_name = rd_display_from_code_name(member_name); - if(fancy_name.size != 0) - { - expr_string = fancy_name; - is_non_code = 1; - } - } - if(expr_string.size == 0) - { - expr_string = push_str8f(arena, ".%S", member_name); - } - scratch_end(scratch); - }break; - } } // rjf: use expression string / params to generate fancy strings diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2503a391..ca9593ac 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3454,7 +3454,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: build bindings // - if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main) + if(build_bindings) UI_Parent(box) RD_Font(RD_FontSlot_Main) UI_PermissionFlags(UI_PermissionFlag_Clicks) { UI_PrefWidth(ui_children_sum(1)) UI_Column UI_Padding(ui_px(ui_top_px_height()*0.2f, 1.f)) UI_HeightFill { From f4b364b66828d6c1cac237390c533185292dc689 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 15:21:51 -0700 Subject: [PATCH 447/755] autogenerate fixed tab list, autogenerate command metadata for opening fixed tabs --- src/raddbg/generated/raddbg.meta.c | 82 +++++++--------- src/raddbg/generated/raddbg.meta.h | 67 +++++++------ src/raddbg/raddbg.mdesk | 83 +++++++++++------ src/raddbg/raddbg_core.c | 145 +++++++++++++++-------------- src/raddbg/raddbg_views.c | 15 +-- src/raddbg/raddbg_widgets.c | 4 +- 6 files changed, 215 insertions(+), 181 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 720907f7..140107a7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[315] = +RD_VocabInfo rd_vocab_info_table[309] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -189,6 +189,7 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("move_tab_right"), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("move_tab_left"), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, {str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("duplicate_tab"), str8_lit_comp(""), str8_lit_comp("Duplicate Tab"), str8_lit_comp(""), RD_IconKind_Duplicate}, {str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, {str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, @@ -290,28 +291,6 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("search"), str8_lit_comp(""), str8_lit_comp("Search"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("search_backwards"), str8_lit_comp(""), str8_lit_comp("Search Backwards"), str8_lit_comp(""), RD_IconKind_Find}, -{str8_lit_comp("getting_started"), str8_lit_comp(""), str8_lit_comp("Getting Started"), str8_lit_comp(""), RD_IconKind_QuestionMark}, -{str8_lit_comp("commands"), str8_lit_comp(""), str8_lit_comp("Commands"), str8_lit_comp(""), RD_IconKind_List}, -{str8_lit_comp("targets"), str8_lit_comp(""), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target}, -{str8_lit_comp("file_path_map"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("breakpoints"), str8_lit_comp(""), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled}, -{str8_lit_comp("watch_pins"), str8_lit_comp(""), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin}, -{str8_lit_comp("scheduler"), str8_lit_comp(""), str8_lit_comp("Scheduler"), str8_lit_comp(""), RD_IconKind_Scheduler}, -{str8_lit_comp("call_stack"), str8_lit_comp(""), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread}, -{str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, -{str8_lit_comp("watch"), str8_lit_comp(""), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("locals"), str8_lit_comp(""), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("registers"), str8_lit_comp(""), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("globals"), str8_lit_comp(""), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("thread_locals"), str8_lit_comp(""), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("types"), str8_lit_comp(""), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("procedures"), str8_lit_comp(""), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("pending_file"), str8_lit_comp(""), str8_lit_comp("Pending File"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, -{str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, -{str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, -{str8_lit_comp("settings"), str8_lit_comp(""), str8_lit_comp("Settings"), str8_lit_comp(""), RD_IconKind_Gear}, {str8_lit_comp("pick_file"), str8_lit_comp(""), str8_lit_comp("Pick File"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("pick_folder"), str8_lit_comp(""), str8_lit_comp("Pick Folder"), str8_lit_comp(""), RD_IconKind_FolderOpenFilled}, {str8_lit_comp("pick_file_or_folder"), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), str8_lit_comp(""), RD_IconKind_FileOutline}, @@ -321,6 +300,21 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("update_query"), str8_lit_comp(""), str8_lit_comp("Update Query"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("toggle_dev_menu"), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("log_marker"), str8_lit_comp(""), str8_lit_comp("Log Marker"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("watches"), str8_lit_comp(""), str8_lit_comp("Watch"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("locals"), str8_lit_comp(""), str8_lit_comp("Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("registers"), str8_lit_comp(""), str8_lit_comp("Registers"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("globals"), str8_lit_comp(""), str8_lit_comp("Globals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("thread_locals"), str8_lit_comp(""), str8_lit_comp("Thread Locals"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("types"), str8_lit_comp(""), str8_lit_comp("Types"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("procedures"), str8_lit_comp(""), str8_lit_comp("Procedures"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("call_stack"), str8_lit_comp(""), str8_lit_comp("Call Stack"), str8_lit_comp(""), RD_IconKind_Thread}, +{str8_lit_comp("targets"), str8_lit_comp(""), str8_lit_comp("Targets"), str8_lit_comp(""), RD_IconKind_Target}, +{str8_lit_comp("breakpoints"), str8_lit_comp(""), str8_lit_comp("Breakpoints"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("watch_pins"), str8_lit_comp(""), str8_lit_comp("Watch Pins"), str8_lit_comp(""), RD_IconKind_Pin}, +{str8_lit_comp("threads"), str8_lit_comp(""), str8_lit_comp("Threads"), str8_lit_comp(""), RD_IconKind_Threads}, +{str8_lit_comp("processes"), str8_lit_comp(""), str8_lit_comp("Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, +{str8_lit_comp("machines"), str8_lit_comp(""), str8_lit_comp("Machines"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, }; RD_NameSchemaInfo rd_name_schema_info_table[21] = @@ -359,7 +353,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_CfgID)}, -{OffsetOf(RD_Regs, prev_view), OffsetOf(RD_Regs, prev_view) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, prev_tab), OffsetOf(RD_Regs, prev_tab) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, cfg), OffsetOf(RD_Regs, cfg) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, cfg_list), OffsetOf(RD_Regs, cfg_list) + sizeof(RD_CfgIDList)}, @@ -394,7 +388,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[211] = +RD_CmdKindInfo rd_cmd_kind_info_table[205] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -475,6 +469,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -576,28 +571,6 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("getting_started"), str8_lit_comp("Opens the menu for information on getting started."), str8_lit_comp("tutorial,help"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens the auto view rule editor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pending_file"), str8_lit_comp("Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("settings"), str8_lit_comp("Opens the settings view."), str8_lit_comp("theme,color,scheme,options"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -607,6 +580,21 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("update_query"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watches"), str8_lit_comp("Opens a Watch tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a Registers tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a Globals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a Thread Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a Types tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a Procedures tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens a Call Stack tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens a Targets tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens a Breakpoints tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens a Watch Pins tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("threads"), str8_lit_comp("Opens a Threads tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("processes"), str8_lit_comp("Opens a Processes tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 980bb613..e9f68d10 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -17,7 +17,7 @@ RD_RegSlot_CtrlEntity, RD_RegSlot_Window, RD_RegSlot_Panel, RD_RegSlot_View, -RD_RegSlot_PrevView, +RD_RegSlot_PrevTab, RD_RegSlot_DstPanel, RD_RegSlot_Cfg, RD_RegSlot_CfgList, @@ -134,6 +134,7 @@ RD_CmdKind_PrevTab, RD_CmdKind_MoveTabRight, RD_CmdKind_MoveTabLeft, RD_CmdKind_OpenTab, +RD_CmdKind_DuplicateTab, RD_CmdKind_CloseTab, RD_CmdKind_MoveTab, RD_CmdKind_TabBarTop, @@ -235,28 +236,6 @@ RD_CmdKind_RegisterAsJITDebugger, RD_CmdKind_FindCodeLocation, RD_CmdKind_Search, RD_CmdKind_SearchBackwards, -RD_CmdKind_GettingStarted, -RD_CmdKind_Commands, -RD_CmdKind_Targets, -RD_CmdKind_FilePathMap, -RD_CmdKind_AutoViewRules, -RD_CmdKind_Breakpoints, -RD_CmdKind_WatchPins, -RD_CmdKind_Scheduler, -RD_CmdKind_CallStack, -RD_CmdKind_Modules, -RD_CmdKind_Watch, -RD_CmdKind_Locals, -RD_CmdKind_Registers, -RD_CmdKind_Globals, -RD_CmdKind_ThreadLocals, -RD_CmdKind_Types, -RD_CmdKind_Procedures, -RD_CmdKind_PendingFile, -RD_CmdKind_Disassembly, -RD_CmdKind_Output, -RD_CmdKind_Memory, -RD_CmdKind_Settings, RD_CmdKind_PickFile, RD_CmdKind_PickFolder, RD_CmdKind_PickFileOrFolder, @@ -266,6 +245,21 @@ RD_CmdKind_CancelQuery, RD_CmdKind_UpdateQuery, RD_CmdKind_ToggleDevMenu, RD_CmdKind_LogMarker, +RD_CmdKind_OpenWatch, +RD_CmdKind_OpenLocals, +RD_CmdKind_OpenRegisters, +RD_CmdKind_OpenGlobals, +RD_CmdKind_OpenThreadLocals, +RD_CmdKind_OpenTypes, +RD_CmdKind_OpenProcedures, +RD_CmdKind_OpenCallStack, +RD_CmdKind_OpenTargets, +RD_CmdKind_OpenBreakpoints, +RD_CmdKind_OpenWatchPins, +RD_CmdKind_OpenThreads, +RD_CmdKind_OpenProcesses, +RD_CmdKind_OpenMachines, +RD_CmdKind_OpenModules, RD_CmdKind_COUNT, } RD_CmdKind; @@ -541,7 +535,7 @@ CTRL_Handle ctrl_entity; RD_CfgID window; RD_CfgID panel; RD_CfgID view; -RD_CfgID prev_view; +RD_CfgID prev_tab; RD_CfgID dst_panel; RD_CfgID cfg; RD_CfgIDList cfg_list; @@ -597,6 +591,27 @@ RD_CmdKindFlags flags; RD_Query query; }; +#define RD_FixedTabXList \ +X(watches)\ +X(locals)\ +X(registers)\ +X(globals)\ +X(thread_locals)\ +X(types)\ +X(procedures)\ +X(call_stack)\ +X(targets)\ +X(breakpoints)\ +X(watch_pins)\ +X(threads)\ +X(processes)\ +X(machines)\ +X(modules)\ +Y(output, text, "query:output")\ +Y(disasm, disasm, "")\ +Y(memory, memory, "")\ +Z(getting_started)\ + #define rd_regs_lit_init_top \ .machine = rd_regs()->machine,\ .module = rd_regs()->module,\ @@ -606,7 +621,7 @@ RD_Query query; .window = rd_regs()->window,\ .panel = rd_regs()->panel,\ .view = rd_regs()->view,\ -.prev_view = rd_regs()->prev_view,\ +.prev_tab = rd_regs()->prev_tab,\ .dst_panel = rd_regs()->dst_panel,\ .cfg = rd_regs()->cfg,\ .cfg_list = rd_regs()->cfg_list,\ @@ -641,7 +656,7 @@ RD_Query query; .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[315]; +extern RD_VocabInfo rd_vocab_info_table[309]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6c9bbb40..76864e27 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -11,6 +11,52 @@ //@embed_file rd_default_code_font_bytes: "../data/Inconsolata-Regular.ttf" @embed_file rd_icon_file_bytes: "../data/logo.ico" +//////////////////////////////// +//~ rjf: Fixed Tab Tables + +@table(name display_name name_lower icon) +RD_WatchTabFastPathTable: +{ + {Watch "Watch" watches Binoculars } + {Locals "Locals" locals Binoculars } + {Registers "Registers" registers Binoculars } + {Globals "Globals" globals Binoculars } + {ThreadLocals "Thread Locals" thread_locals Binoculars } + {Types "Types" types Binoculars } + {Procedures "Procedures" procedures Binoculars } + {CallStack "Call Stack" call_stack Thread } + {Targets "Targets" targets Target } + {Breakpoints "Breakpoints" breakpoints CircleFilled } + {WatchPins "Watch Pins" watch_pins Pin } + {Threads "Threads" threads Threads } + {Processes "Processes" processes Scheduler } + {Machines "Machines" machines Machine } + {Modules "Modules" modules Module } +} + +@table(name display_name name_lower view query icon) +RD_ViewTabFastPathTable: +{ + {Output "Output" output "text" "query:output" List } + {Disasm "Disassembly" disasm "" "" Glasses } + {Memory "Memory" memory "" "" Grid } +} + +@table(name display_name name_lower icon) +RD_FixedTabTable: +{ + {GettingStarted "Getting Started" getting_started "getting_started" QuestionMark } +} + +@gen +{ + `#define RD_FixedTabXList \\`; + @expand(RD_WatchTabFastPathTable a) `X($(a.name_lower))\\`; + @expand(RD_ViewTabFastPathTable a) `Y($(a.name_lower), $(a.view == "" -> a.name_lower)$(a.view != "" -> a.view), "$(a.query)")\\`; + @expand(RD_FixedTabTable a) `Z($(a.name_lower))\\`; + ``; +} + //////////////////////////////// //~ rjf: Vocabulary Map @@ -137,9 +183,10 @@ RD_VocabTable: @data(RD_VocabInfo) rd_vocab_info_table: { - @expand(RD_VocabTable a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; - @expand(D_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; - @expand(RD_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; + @expand(RD_VocabTable a) `{str8_lit_comp("$(a.code_name)"), str8_lit_comp("$(a.code_name_plural == _ -> a.code_name .. 's')$(a.code_name_plural != _ -> a.code_name_plural)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.display_name_plural == _ -> a.display_name .. 's')$(a.display_name_plural != _ -> a.display_name_plural)"), RD_IconKind_$(a.icon_kind)}`; + @expand(D_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; + @expand(RD_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; + @expand(RD_WatchTabFastPathTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.icon)}`; } //////////////////////////////// @@ -463,7 +510,7 @@ RD_RegTable: {RD_CfgID window Window } {RD_CfgID panel Panel } {RD_CfgID view View } - {RD_CfgID prev_view PrevView } + {RD_CfgID prev_tab PrevTab } {RD_CfgID dst_panel DstPanel } {RD_CfgID cfg Cfg } {RD_CfgIDList cfg_list CfgList } @@ -616,6 +663,7 @@ RD_CmdTable: // | | | | {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {DuplicateTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } @@ -760,30 +808,6 @@ RD_CmdTable: // | | | | {Search 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } {SearchBackwards 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search_backwards" "Search Backwards" "Begins searching backwards within the active interface." "sort,search,filter,find" "" } - //- rjf: view drivers - {GettingStarted 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 QuestionMark "getting_started" "Getting Started" "Opens the menu for information on getting started." "tutorial,help" "" } - {Commands 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "commands" "Commands" "Opens the list of all commands." "" "" } - {Targets 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Target "targets" "Targets" "Opens the list of all targets." "" "" } - {FilePathMap 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "file_path_map" "File Path Map" "Opens the file path mapping editor." "" "" } - {AutoViewRules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "auto_view_rules" "Auto View Rules" "Opens the auto view rule editor." "" "" } - {Breakpoints 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "breakpoints" "Breakpoints" "Opens the breakpoints view." "" "" } - {WatchPins 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pin "watch_pins" "Watch Pins" "Opens the watch pins view." "" "" } - {Scheduler 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Scheduler "scheduler" "Scheduler" "Opens the scheduler view, for process and thread controls." "threads,processes,targets" "" } - {CallStack 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Thread "call_stack" "Call Stack" "Opens the call stack view." "callstack,thread,unwind" "" } - {Modules 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Module "modules" "Modules" "Opens the modules view." "" "" } - {Watch 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "watch" "Watch" "Opens a watch view." "" "" } - {Locals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "locals" "Locals" "Opens a locals view." "" "" } - {Registers 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "registers" "Registers" "Opens a registers view." "" "" } - {Globals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "globals" "Globals" "Opens a globals view." "" "" } - {ThreadLocals 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "thread_locals" "Thread Locals" "Opens a thread locals view." "" "" } - {Types 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "types" "Types" "Opens a types view." "" "" } - {Procedures 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "procedures" "Procedures" "Opens a procedures view." "" "" } - {PendingFile 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "pending_file" "Pending File" "Opens a view which asynchronously analyzes the file path parameter, then picks an appropriate viewer for it." "" "" } - {Disassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "disasm" "Disassembly" "Opens the disassembly view." "disasm" "" } - {Output 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 List "output" "Output" "Opens an output view." "" "" } - {Memory 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Grid "memory" "Memory" "Opens a memory view." "" "" } - {Settings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "settings" "Settings" "Opens the settings view." "theme,color,scheme,options" "" } - //- rjf: queries {PickFile 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } {PickFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } @@ -805,6 +829,7 @@ RD_CmdTable: // | | | | `Null`, @expand(D_CmdTable a) `$(a.name)`, @expand(RD_CmdTable, a) `$(a.name)`, + @expand(RD_WatchTabFastPathTable, a) `Open$(a.name)`, COUNT, } @@ -834,6 +859,8 @@ RD_CmdTable: // | | | | ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + @expand(RD_WatchTabFastPathTable, a) + ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}```; } //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b49d3336..ef277746 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -518,12 +518,15 @@ internal RD_Cfg * rd_cfg_child_from_string(RD_Cfg *parent, String8 string) { RD_Cfg *child = &rd_nil_cfg; - for(RD_Cfg *c = parent->first; c != &rd_nil_cfg; c = c->next) + if(string.size != 0) { - if(str8_match(c->string, string, 0)) + for(RD_Cfg *c = parent->first; c != &rd_nil_cfg; c = c->next) { - child = c; - break; + if(str8_match(c->string, string, 0)) + { + child = c; + break; + } } } return child; @@ -4360,7 +4363,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: cell has hook? -> build ui by calling hook if(cell->kind == RD_WatchCellKind_ViewUI && cell_info.view_ui_rule != &rd_nil_view_ui_rule) { - RD_Cfg *root = rd_immediate_cfg_from_keyf("view_%I64x_%I64x", rd_regs()->view, row_hash); + RD_Cfg *root = rd_immediate_cfg_from_keyf("view%I64x_%I64x", rd_regs()->view, row_hash); RD_Cfg *view = rd_view_from_eval(root, cell->eval); Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); @@ -6860,48 +6863,40 @@ rd_window_frame(void) { String8 cmds[] = { - rd_cmd_kind_info_table[RD_CmdKind_Targets].string, - rd_cmd_kind_info_table[RD_CmdKind_Scheduler].string, - rd_cmd_kind_info_table[RD_CmdKind_CallStack].string, - rd_cmd_kind_info_table[RD_CmdKind_Modules].string, - rd_cmd_kind_info_table[RD_CmdKind_Output].string, - rd_cmd_kind_info_table[RD_CmdKind_Memory].string, - rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, - rd_cmd_kind_info_table[RD_CmdKind_Watch].string, - rd_cmd_kind_info_table[RD_CmdKind_Locals].string, - rd_cmd_kind_info_table[RD_CmdKind_Registers].string, - rd_cmd_kind_info_table[RD_CmdKind_Globals].string, - rd_cmd_kind_info_table[RD_CmdKind_ThreadLocals].string, - rd_cmd_kind_info_table[RD_CmdKind_Types].string, - rd_cmd_kind_info_table[RD_CmdKind_Procedures].string, - rd_cmd_kind_info_table[RD_CmdKind_Breakpoints].string, - rd_cmd_kind_info_table[RD_CmdKind_WatchPins].string, - rd_cmd_kind_info_table[RD_CmdKind_FilePathMap].string, - rd_cmd_kind_info_table[RD_CmdKind_AutoViewRules].string, - rd_cmd_kind_info_table[RD_CmdKind_Settings].string, - rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenTargets].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenMachines].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenProcesses].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenThreads].string, + //rd_cmd_kind_info_table[RD_CmdKind_Output].string, + //rd_cmd_kind_info_table[RD_CmdKind_Memory].string, + //rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenWatch].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenLocals].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenRegisters].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenGlobals].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenThreadLocals].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenTypes].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenProcedures].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenBreakpoints].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenWatchPins].string, + // rd_cmd_kind_info_table[RD_CmdKind_OpenFilePathMap].string, + // rd_cmd_kind_info_table[RD_CmdKind_OpenAutoViewRules].string, + // rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, }; U32 codepoints[] = { - 't', - 's', - 'k', - 'd', - 'o', - 'm', - 'y', - 'w', - 'l', - 'r', 0, 0, 0, 0, - 'b', - 'h', - 'p', - 'v', - 'g', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); @@ -8093,7 +8088,7 @@ rd_window_frame(void) .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, - .prev_view = rd_cfg_list_last(&panel->tabs)->id); + .prev_tab = rd_cfg_list_last(&panel->tabs)->id); } } } @@ -8571,14 +8566,14 @@ rd_window_frame(void) if(ui_pressed(sig)) { rd_cmd(RD_CmdKind_FocusPanel); - UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_")); - if(ui_ctx_menu_is_open(view_menu_key)) + UI_Key tab_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_menu_key_")); + if(ui_ctx_menu_is_open(tab_menu_key)) { ui_ctx_menu_close(); } else { - ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); + ui_ctx_menu_open(tab_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); } } } @@ -8598,7 +8593,7 @@ rd_window_frame(void) .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, - .prev_view = tab_drop_prev->id); + .prev_tab = tab_drop_prev->id); } ////////////////////////// @@ -8737,6 +8732,7 @@ rd_window_frame(void) //- rjf: recurse & draw U64 total_heatmap_sum_count = 0; + UI_Box *hover_debug_box = &ui_nil_box; for(UI_Box *box = ui_root_from_state(ws->ui); !ui_box_is_nil(box);) { // rjf: get corner radii @@ -8764,6 +8760,12 @@ rd_window_frame(void) } } + // rjf: grab if debug + if(box->flags & UI_BoxFlag_Debug && contains_2f32(box->rect, ui_mouse())) + { + hover_debug_box = box; + } + // rjf: push transparency if(box->transparency != 0) { @@ -9169,6 +9171,18 @@ rd_window_frame(void) } } + //- rjf: draw hover debug box + if(hover_debug_box != &ui_nil_box) + { + FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code); + Vec2F32 p = ui_mouse(); + dr_rect(hover_debug_box->rect, v4f32(1, 1, 1, 0.2f), 0, 0, 0); + dr_text(font, 12.f, 0, 0, FNT_RasterFlag_Hinted, p, v4f32(1, 1, 1, 1), push_str8f(scratch.arena, "key: 0x%I64x", hover_debug_box->key.u64[0])); + p.y += 20.f; + dr_text(font, 12.f, 0, 0, FNT_RasterFlag_Hinted, p, v4f32(1, 1, 1, 1), push_str8f(scratch.arena, "string: '%S'", hover_debug_box->string)); + p.y += 20.f; + } + //- rjf: draw border/overlay color to signify error if(ws->error_t > 0.01f) UI_TagF("bad") { @@ -13586,7 +13600,7 @@ rd_frame(void) rd_cmd(RD_CmdKind_MoveTab, .dst_panel = panel->cfg->id, .view = tab->id, - .prev_view = new_prev->id); + .prev_tab = new_prev->id); }break; case RD_CmdKind_OpenTab: { @@ -13610,6 +13624,13 @@ rd_frame(void) rd_panel_insert_tab_view(panel, panel->last_tab_view, view); #endif }break; + case RD_CmdKind_DuplicateTab: + { + RD_Cfg *src = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *dst = rd_cfg_deep_copy(src); + rd_cfg_insert_child(src->parent, src, dst); + rd_cmd(RD_CmdKind_FocusTab, .view = dst->id); + }break; case RD_CmdKind_CloseTab: { RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); @@ -13638,7 +13659,7 @@ rd_frame(void) case RD_CmdKind_MoveTab: { RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_view); + RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_tab); RD_Cfg *src_panel = tab->parent; RD_Cfg *dst_panel = rd_cfg_from_id(rd_regs()->dst_panel); if(dst_panel != &rd_nil_cfg && prev_tab != tab) @@ -13810,30 +13831,10 @@ rd_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); //- rjf: define all of the "fixed" tabs we care about -#define FixedTab_XList \ -X(watches)\ -X(locals)\ -X(registers)\ -X(globals)\ -X(thread_locals)\ -X(types)\ -X(procedures)\ -X(call_stack)\ -X(breakpoints)\ -X(watch_pins)\ -X(targets)\ -X(threads)\ -X(processes)\ -X(machines)\ -X(modules)\ -Y(output, text, "query:output")\ -Y(disasm, disasm, "")\ -Y(memory, memory, "")\ -Z(getting_started) #define X(name) RD_Cfg *name = &rd_nil_cfg; #define Y(name, rule, expr) RD_Cfg *name = &rd_nil_cfg; #define Z(name) RD_Cfg *name = &rd_nil_cfg; - FixedTab_XList + RD_FixedTabXList #undef X #undef Y #undef Z @@ -13853,7 +13854,7 @@ Z(getting_started) #define X(name) else if(str8_match(tab->string, str8_lit("watch"), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit("query:" #name), 0)) {name = tab;} #define Y(name, rule, expr) else if(str8_match(tab->string, str8_lit(#rule), 0) && str8_match(rd_expr_from_cfg(tab), str8_lit(expr), 0)) {name = tab;} #define Z(name) else if(str8_match(tab->string, str8_lit(#name), 0)) {name = tab;} - FixedTab_XList + RD_FixedTabXList #undef X #undef Y #undef Z @@ -13877,7 +13878,7 @@ Z(getting_started) #define X(name) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit("watch")); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit("query:" #name));} #define Y(name, rule, expr) if(name == &rd_nil_cfg) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#rule)); RD_Cfg *expr_cfg = rd_cfg_new(name, str8_lit("expression")); rd_cfg_new(expr_cfg, str8_lit(expr));} #define Z(name) if(name == &rd_nil_cfg && !any_fixed_tabs_found) {name = rd_cfg_alloc(); rd_cfg_equip_string(name, str8_lit(#name));} - FixedTab_XList + RD_FixedTabXList #undef X #undef Y #undef Z @@ -13886,7 +13887,7 @@ Z(getting_started) #define X(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} #define Y(name, rule, expr) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} #define Z(name) if(name != &rd_nil_cfg) {rd_cfg_release(rd_cfg_child_from_string(name, str8_lit("selected")));} - FixedTab_XList + RD_FixedTabXList #undef X #undef Y #undef Z @@ -14062,7 +14063,7 @@ Z(getting_started) #define X(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} #define Y(name, rule, expr) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} #define Z(name) if(name->parent == &rd_nil_cfg) {rd_cfg_release(name);} - FixedTab_XList + RD_FixedTabXList #undef X #undef Y #undef Z diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2f3a600a..92e44178 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1676,19 +1676,20 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // to see if we have a fancy display string for this member. otherwise, we will just // do a code-string of ".member_name" String8 member_name = notable_expr->first->next->string; + String8 fancy_name = {0}; if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || cell->eval.space.kind == E_SpaceKind_File || cell->eval.space.kind == E_SpaceKind_FileSystem) { - String8 fancy_name = rd_display_from_code_name(member_name); - if(fancy_name.size != 0) - { - member_name = fancy_name; - is_non_code = 1; - } + fancy_name = rd_display_from_code_name(member_name); } - if(member_name.size != 0) + if(fancy_name.size != 0) + { + is_non_code = 1; + expr_string = fancy_name; + } + else if(member_name.size != 0) { expr_string = push_str8f(arena, ".%S", member_name); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ca9593ac..5bf3f79d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3319,7 +3319,9 @@ rd_cell(RD_CellParams *params, String8 string) //- rjf: build line edit container box // UI_Box *edit_box = &ui_nil_box; - UI_Parent(box) if((is_focus_active || is_focus_active_disabled) || params->pre_edit_value.size != 0 || params->value_fstrs.node_count != 0 || (params->edit_string_size_out && params->edit_string_size_out[0] != 0)) + UI_Parent(box) if((is_focus_active || is_focus_active_disabled) || + params->pre_edit_value.size != 0 || + params->value_fstrs.node_count != 0) { UI_Size edit_box_size = ui_pct(1, 0); if(build_lhs_name_desc) From 23c7fcf09906a25aefa1d294b10360c3159026d8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 15:57:57 -0700 Subject: [PATCH 448/755] plug tab opening back in --- .../eval_visualization_core.c | 2 - src/raddbg/generated/raddbg.meta.c | 46 ++++++++++++++++- src/raddbg/generated/raddbg.meta.h | 7 ++- src/raddbg/raddbg.mdesk | 13 +++++ src/raddbg/raddbg_core.c | 49 ++++++++++--------- 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 086b1605..40a1710d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -587,7 +587,6 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval } // rjf: get top-level lookup/expansion info - // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval, filter); EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); @@ -2101,7 +2100,6 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); expand_data->type = e_type_from_key__cached(type_key); expand_data->expand_rule = e_expand_rule_from_type_key(type_key); - // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key expand_data->expand_info = expand_data->expand_rule->info(arena, eval, params->filter); } switch(task_idx) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 140107a7..cbd8d88f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,47 @@ //- GENERATED CODE C_LINKAGE_BEGIN -RD_VocabInfo rd_vocab_info_table[309] = +String8 rd_tab_fast_path_view_name_table[16] = +{ +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("watch"), +}; + +String8 rd_tab_fast_path_query_name_table[16] = +{ +str8_lit_comp("query:watches"), +str8_lit_comp("query:locals"), +str8_lit_comp("query:registers"), +str8_lit_comp("query:globals"), +str8_lit_comp("query:thread_locals"), +str8_lit_comp("query:types"), +str8_lit_comp("query:procedures"), +str8_lit_comp("query:call_stack"), +str8_lit_comp("query:targets"), +str8_lit_comp("query:breakpoints"), +str8_lit_comp("query:watch_pins"), +str8_lit_comp("query:threads"), +str8_lit_comp("query:processes"), +str8_lit_comp("query:machines"), +str8_lit_comp("query:modules"), +str8_lit_comp("query:file_path_maps"), +}; + +RD_VocabInfo rd_vocab_info_table[310] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -315,6 +355,7 @@ RD_VocabInfo rd_vocab_info_table[309] = {str8_lit_comp("processes"), str8_lit_comp(""), str8_lit_comp("Processes"), str8_lit_comp(""), RD_IconKind_Scheduler}, {str8_lit_comp("machines"), str8_lit_comp(""), str8_lit_comp("Machines"), str8_lit_comp(""), RD_IconKind_Machine}, {str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, +{str8_lit_comp("file_path_maps"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, }; RD_NameSchemaInfo rd_name_schema_info_table[21] = @@ -388,7 +429,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[205] = +RD_CmdKindInfo rd_cmd_kind_info_table[206] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -595,6 +636,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[205] = { str8_lit_comp("processes"), str8_lit_comp("Opens a Processes tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, { str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, { str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e9f68d10..7b3d99cc 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -260,7 +260,9 @@ RD_CmdKind_OpenThreads, RD_CmdKind_OpenProcesses, RD_CmdKind_OpenMachines, RD_CmdKind_OpenModules, +RD_CmdKind_OpenFilePathMaps, RD_CmdKind_COUNT, +RD_CmdKind_FirstTabFastPathCmd = RD_CmdKind_OpenWatch, } RD_CmdKind; typedef enum RD_IconKind @@ -607,6 +609,7 @@ X(threads)\ X(processes)\ X(machines)\ X(modules)\ +X(file_path_maps)\ Y(output, text, "query:output")\ Y(disasm, disasm, "")\ Y(memory, memory, "")\ @@ -656,7 +659,9 @@ Z(getting_started)\ .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern RD_VocabInfo rd_vocab_info_table[309]; +extern String8 rd_tab_fast_path_view_name_table[16]; +extern String8 rd_tab_fast_path_query_name_table[16]; +extern RD_VocabInfo rd_vocab_info_table[310]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 76864e27..6333b451 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -32,6 +32,7 @@ RD_WatchTabFastPathTable: {Processes "Processes" processes Scheduler } {Machines "Machines" machines Machine } {Modules "Modules" modules Module } + {FilePathMaps "File Path Map" file_path_maps FileOutline } } @table(name display_name name_lower view query icon) @@ -57,6 +58,16 @@ RD_FixedTabTable: ``; } +@data(String8) rd_tab_fast_path_view_name_table: +{ + @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("watch")`, +} + +@data(String8) rd_tab_fast_path_query_name_table: +{ + @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("query:$(a.name_lower)")`, +} + //////////////////////////////// //~ rjf: Vocabulary Map @@ -831,6 +842,8 @@ RD_CmdTable: // | | | | @expand(RD_CmdTable, a) `$(a.name)`, @expand(RD_WatchTabFastPathTable, a) `Open$(a.name)`, COUNT, + + `FirstTabFastPathCmd = RD_CmdKind_OpenWatch`, } @struct RD_Query: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ef277746..9f30aefa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3005,7 +3005,7 @@ rd_view_ui(Rng2F32 rect) if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.y == selection_tbl.max.y && - (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || view_is_floating)) + (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg)) { RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); RD_Cfg *cmd = rd_cfg_child_from_string(query, str8_lit("cmd")); @@ -4756,11 +4756,10 @@ rd_view_ui(Rng2F32 rect) rd_cmd(RD_CmdKind_SelectThread, .thread = cell_info.entity->handle); } - // rjf: other cases, but this watch window is floating? -> move cursor & accept - else + // rjf: other cases, but this watch window is floating? -> push query + else if(view_is_floating) { - ewv->next_cursor = ewv->next_mark = cell_pt; - rd_cmd(RD_CmdKind_Accept); + rd_cmd(RD_CmdKind_PushQuery, .expr = cell->eval.string); } } @@ -6485,7 +6484,7 @@ rd_window_frame(void) Rng2F32 rect = {0}; RD_RegsScope(.view = view->id) { - F32 row_height_px = ui_top_px_height(); + F32 row_height_px = ui_top_font_size() * rd_setting_f32_from_name(str8_lit("row_height")); Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); EV_BlockTree predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval); @@ -6494,7 +6493,8 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - query_height_px = row_height_px * (predicted_block_tree.total_row_count - !root_is_explicit); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!vs->query_is_selected, .initial = (F32)!!vs->query_is_selected, .epsilon = 0.01f); + query_height_px = row_height_px * (predicted_block_tree.total_row_count - !root_is_explicit) + ui_top_px_height()*search_row_open_t; query_height_px = Min(query_height_px, max_query_height_px); } rect = r2f32p(content_rect_center.x - query_width_px/2, @@ -6867,6 +6867,7 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenMachines].string, rd_cmd_kind_info_table[RD_CmdKind_OpenProcesses].string, rd_cmd_kind_info_table[RD_CmdKind_OpenThreads].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenCallStack].string, //rd_cmd_kind_info_table[RD_CmdKind_Output].string, //rd_cmd_kind_info_table[RD_CmdKind_Memory].string, //rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, @@ -6879,7 +6880,7 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenProcedures].string, rd_cmd_kind_info_table[RD_CmdKind_OpenBreakpoints].string, rd_cmd_kind_info_table[RD_CmdKind_OpenWatchPins].string, - // rd_cmd_kind_info_table[RD_CmdKind_OpenFilePathMap].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenFilePathMaps].string, // rd_cmd_kind_info_table[RD_CmdKind_OpenAutoViewRules].string, // rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, }; @@ -6898,6 +6899,8 @@ rd_window_frame(void) 0, 0, 0, + 0, + 0, }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); @@ -8565,16 +8568,14 @@ rd_window_frame(void) UI_Signal sig = ui_signal_from_box(add_new_box); if(ui_pressed(sig)) { - rd_cmd(RD_CmdKind_FocusPanel); - UI_Key tab_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_menu_key_")); - if(ui_ctx_menu_is_open(tab_menu_key)) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(tab_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight)); - } + rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); + rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:commands"), + .panel = panel->cfg->id, + .do_implicit_root = 1, + .do_lister = 1, + .do_big_rows = 1, + .ui_key = add_new_box->key, + .off_px = v2f32(0, dim_2f32(add_new_box->rect).y)); } } } @@ -12544,14 +12545,14 @@ rd_frame(void) d_push_cmd((D_CmdKind)kind, ¶ms); } - // rjf: try to open tabs for "view driver" commands -#if 0 // TODO(rjf): @cfg (tab opening) - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(cmd->name); - if(view_rule_info != &rd_nil_view_rule_info) + // rjf: try to open tabs, if this is a tab-fastpath-opener + if(kind >= RD_CmdKind_FirstTabFastPathCmd) { - rd_cmd(RD_CmdKind_OpenTab, .string = str8_zero(), .params_tree = md_tree_from_string(scratch.arena, cmd->name)->first); + U64 fast_path_idx = (kind - RD_CmdKind_FirstTabFastPathCmd); + String8 view_name = rd_tab_fast_path_view_name_table[fast_path_idx]; + String8 query_name = rd_tab_fast_path_query_name_table[fast_path_idx]; + rd_cmd(RD_CmdKind_OpenTab, .string = view_name, .expr = query_name); } -#endif }break; //- rjf: open palette From 0470b646cd489619d2842c758570fb898768f41d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 16:27:24 -0700 Subject: [PATCH 449/755] more tab-opening-fastpath coverage, fix described-code-string meta-cfg evaluation value rendering, tab settings cmd coverage --- .../eval_visualization_core.c | 5 +-- src/raddbg/generated/raddbg.meta.c | 32 +++++++++++++++---- src/raddbg/generated/raddbg.meta.h | 12 +++++-- src/raddbg/raddbg.mdesk | 22 ++++++++++--- src/raddbg/raddbg_core.c | 12 ++++--- 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 40a1710d..fef05868 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1740,9 +1740,10 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) }break; ////////////////////////// - //- rjf: modifiers + //- rjf: modifiers / no-ops // case E_TypeKind_Modifier: + case E_TypeKind_MetaDescription: { need_pop = 1; need_new_task = 1; @@ -2171,7 +2172,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_t = push_array(arena, EV_StringIterTask, 1); } MemoryCopyStruct(new_t, &new_task); - new_t->depth = top_task_depth+1; + new_t->depth = top_task_depth + 1*(!need_pop); SLLStackPush(it->top_task, new_t); new_t->idx = 0; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index cbd8d88f..24e9396a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 rd_tab_fast_path_view_name_table[16] = +String8 rd_tab_fast_path_view_name_table[20] = { str8_lit_comp("watch"), str8_lit_comp("watch"), @@ -22,9 +22,13 @@ str8_lit_comp("watch"), str8_lit_comp("watch"), str8_lit_comp("watch"), str8_lit_comp("watch"), +str8_lit_comp("watch"), +str8_lit_comp("text"), +str8_lit_comp("disasm"), +str8_lit_comp("memory"), }; -String8 rd_tab_fast_path_query_name_table[16] = +String8 rd_tab_fast_path_query_name_table[20] = { str8_lit_comp("query:watches"), str8_lit_comp("query:locals"), @@ -42,9 +46,13 @@ str8_lit_comp("query:processes"), str8_lit_comp("query:machines"), str8_lit_comp("query:modules"), str8_lit_comp("query:file_path_maps"), +str8_lit_comp("query:auto_view_rules"), +str8_lit_comp("query:output"), +str8_lit_comp(""), +str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[310] = +RD_VocabInfo rd_vocab_info_table[315] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -234,6 +242,7 @@ RD_VocabInfo rd_vocab_info_table[310] = {str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, {str8_lit_comp("tab_bar_bottom"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), str8_lit_comp(""), RD_IconKind_DownArrow}, +{str8_lit_comp("tab_settings"), str8_lit_comp(""), str8_lit_comp("Tab Settings"), str8_lit_comp(""), RD_IconKind_Gear}, {str8_lit_comp("set_current_path"), str8_lit_comp(""), str8_lit_comp("Set Current Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("open"), str8_lit_comp(""), str8_lit_comp("Open"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("switch"), str8_lit_comp(""), str8_lit_comp("Switch"), str8_lit_comp(""), RD_IconKind_FileOutline}, @@ -356,6 +365,10 @@ RD_VocabInfo rd_vocab_info_table[310] = {str8_lit_comp("machines"), str8_lit_comp(""), str8_lit_comp("Machines"), str8_lit_comp(""), RD_IconKind_Machine}, {str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, {str8_lit_comp("file_path_maps"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, +{str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, }; RD_NameSchemaInfo rd_name_schema_info_table[21] = @@ -366,9 +379,9 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, @@ -429,7 +442,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[206] = +RD_CmdKindInfo rd_cmd_kind_info_table[211] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -515,6 +528,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[206] = { str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -637,6 +651,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[206] = { str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, { str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, { str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens a Auto View Rules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("output"), str8_lit_comp("Opens a Output tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens a Disassembly tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 7b3d99cc..736aec89 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -139,6 +139,7 @@ RD_CmdKind_CloseTab, RD_CmdKind_MoveTab, RD_CmdKind_TabBarTop, RD_CmdKind_TabBarBottom, +RD_CmdKind_TabSettings, RD_CmdKind_SetCurrentPath, RD_CmdKind_Open, RD_CmdKind_Switch, @@ -261,6 +262,10 @@ RD_CmdKind_OpenProcesses, RD_CmdKind_OpenMachines, RD_CmdKind_OpenModules, RD_CmdKind_OpenFilePathMaps, +RD_CmdKind_OpenAutoViewRules, +RD_CmdKind_OpenOutput, +RD_CmdKind_OpenDisasm, +RD_CmdKind_OpenMemory, RD_CmdKind_COUNT, RD_CmdKind_FirstTabFastPathCmd = RD_CmdKind_OpenWatch, } RD_CmdKind; @@ -610,6 +615,7 @@ X(processes)\ X(machines)\ X(modules)\ X(file_path_maps)\ +X(auto_view_rules)\ Y(output, text, "query:output")\ Y(disasm, disasm, "")\ Y(memory, memory, "")\ @@ -659,9 +665,9 @@ Z(getting_started)\ .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern String8 rd_tab_fast_path_view_name_table[16]; -extern String8 rd_tab_fast_path_query_name_table[16]; -extern RD_VocabInfo rd_vocab_info_table[310]; +extern String8 rd_tab_fast_path_view_name_table[20]; +extern String8 rd_tab_fast_path_query_name_table[20]; +extern RD_VocabInfo rd_vocab_info_table[315]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6333b451..78d3613c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -33,14 +33,15 @@ RD_WatchTabFastPathTable: {Machines "Machines" machines Machine } {Modules "Modules" modules Module } {FilePathMaps "File Path Map" file_path_maps FileOutline } + {AutoViewRules "Auto View Rules" auto_view_rules Binoculars } } @table(name display_name name_lower view query icon) RD_ViewTabFastPathTable: { - {Output "Output" output "text" "query:output" List } - {Disasm "Disassembly" disasm "" "" Glasses } - {Memory "Memory" memory "" "" Grid } + {Output "Output" output text "query:output" List } + {Disasm "Disassembly" disasm disasm "" Glasses } + {Memory "Memory" memory memory "" Grid } } @table(name display_name name_lower icon) @@ -53,7 +54,7 @@ RD_FixedTabTable: { `#define RD_FixedTabXList \\`; @expand(RD_WatchTabFastPathTable a) `X($(a.name_lower))\\`; - @expand(RD_ViewTabFastPathTable a) `Y($(a.name_lower), $(a.view == "" -> a.name_lower)$(a.view != "" -> a.view), "$(a.query)")\\`; + @expand(RD_ViewTabFastPathTable a) `Y($(a.name_lower), $(a.view), "$(a.query)")\\`; @expand(RD_FixedTabTable a) `Z($(a.name_lower))\\`; ``; } @@ -61,11 +62,13 @@ RD_FixedTabTable: @data(String8) rd_tab_fast_path_view_name_table: { @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("watch")`, + @expand(RD_ViewTabFastPathTable a) `str8_lit_comp("$(a.view)")`, } @data(String8) rd_tab_fast_path_query_name_table: { @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("query:$(a.name_lower)")`, + @expand(RD_ViewTabFastPathTable a) `str8_lit_comp("$(a.query)")`, } //////////////////////////////// @@ -198,6 +201,7 @@ RD_VocabTable: @expand(D_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; @expand(RD_CmdTable a) `{str8_lit_comp("$(a.string)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.canonical_icon)}`; @expand(RD_WatchTabFastPathTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.icon)}`; + @expand(RD_ViewTabFastPathTable a) `{str8_lit_comp("$(a.name_lower)"), str8_lit_comp(""), str8_lit_comp("$(a.display_name)"), str8_lit_comp(""), RD_IconKind_$(a.icon)}`; } //////////////////////////////// @@ -333,6 +337,8 @@ RD_VocabTable: ``` @inherit(tab) x: { + @description("An expression to describe the base address or offset of the disassembly.") + 'expression': code_string, 'arch': arch, 'syntax': dasm_syntax, 'size': code_string, @@ -354,6 +360,8 @@ RD_VocabTable: ``` @inherit(tab) x: { + @description("An expression to describe the base address or offset of the memory view.") + 'expression': code_string, @description("The number of bytes of the viewed memory range.") 'size': code_string, @default(16) @description("The number of columns to build before building new rows.") @@ -368,6 +376,8 @@ RD_VocabTable: ``` @inherit(tab) x: { + @display_name("Base Pointer") @description("An expression to describe the base address or offset of the bitmap data.") + 'expression': code_string, @order(0) 'w': u64, @order(1) 'h': u64, @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") @@ -679,6 +689,7 @@ RD_CmdTable: // | | | | {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } + {TabSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Tab Settings" "Opens settings for a tab." "" "" } //- rjf: files {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } @@ -841,6 +852,7 @@ RD_CmdTable: // | | | | @expand(D_CmdTable a) `$(a.name)`, @expand(RD_CmdTable, a) `$(a.name)`, @expand(RD_WatchTabFastPathTable, a) `Open$(a.name)`, + @expand(RD_ViewTabFastPathTable, a) `Open$(a.name)`, COUNT, `FirstTabFastPathCmd = RD_CmdKind_OpenWatch`, @@ -874,6 +886,8 @@ RD_CmdTable: // | | | | ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_WatchTabFastPathTable, a) ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}```; + @expand(RD_ViewTabFastPathTable, a) + ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}```; } //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9f30aefa..93335438 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6868,9 +6868,9 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenProcesses].string, rd_cmd_kind_info_table[RD_CmdKind_OpenThreads].string, rd_cmd_kind_info_table[RD_CmdKind_OpenCallStack].string, - //rd_cmd_kind_info_table[RD_CmdKind_Output].string, - //rd_cmd_kind_info_table[RD_CmdKind_Memory].string, - //rd_cmd_kind_info_table[RD_CmdKind_Disassembly].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenOutput].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenMemory].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenDisasm].string, rd_cmd_kind_info_table[RD_CmdKind_OpenWatch].string, rd_cmd_kind_info_table[RD_CmdKind_OpenLocals].string, rd_cmd_kind_info_table[RD_CmdKind_OpenRegisters].string, @@ -6881,7 +6881,7 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_OpenBreakpoints].string, rd_cmd_kind_info_table[RD_CmdKind_OpenWatchPins].string, rd_cmd_kind_info_table[RD_CmdKind_OpenFilePathMaps].string, - // rd_cmd_kind_info_table[RD_CmdKind_OpenAutoViewRules].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenAutoViewRules].string, // rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, }; U32 codepoints[] = @@ -6901,6 +6901,10 @@ rd_window_frame(void) 0, 0, 0, + 0, + 0, + 0, + 0, }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); From b59528edeafd448e72302497d1fabd6ee446f00b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 16:55:52 -0700 Subject: [PATCH 450/755] tab/text-pt/text-range filtered commands, hook up to right-click menus --- src/dbg_engine/dbg_engine.mdesk | 72 ++--- src/raddbg/generated/raddbg.meta.c | 420 ++++++++++++++--------------- src/raddbg/raddbg.mdesk | 332 +++++++++++------------ src/raddbg/raddbg_core.c | 53 ++-- src/raddbg/raddbg_core.h | 3 + src/raddbg/raddbg_eval.c | 6 +- src/raddbg/raddbg_widgets.c | 19 +- 7 files changed, 456 insertions(+), 449 deletions(-) diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 2871eca7..cbfe3352 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -4,52 +4,52 @@ //////////////////////////////// //~ rjf: Built-In Command Tables -@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | | \___ _________________________________/ | | | | | | -// / | | | | \ / | | | | | | -D_CmdTable: // | | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis text_pt_vis text_rng_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | | | \___ _________________________________/ | | | | | | +// / | | | | | | \ / | | | | | | +D_CmdTable: // | | | | | | | | | | | | | | { //- rjf: low-level target control operations - {LaunchAndRun 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } - {LaunchAndStepInto 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_step_into" "Launch and Step Into" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } - {Kill 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } - {KillAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } - {Detach 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } - {Continue 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } - {StepIntoInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } - {StepOverInst 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } - {StepIntoLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } - {StepOverLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } - {StepOut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } - {Halt 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } - {SoftHaltRefresh 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } - {SetThreadIP 0 1 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } + {LaunchAndRun 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" } + {LaunchAndStepInto 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_step_into" "Launch and Step Into" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" } + {Kill 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" } + {KillAll 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" } + {Detach 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" } + {Continue 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" } + {StepIntoInst 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" } + {StepOverInst 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" } + {StepIntoLine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" } + {StepOverLine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" } + {StepOut 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" } + {Halt 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" } + {SoftHaltRefresh 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" } + {SetThreadIP 0 1 0 0 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" } //- rjf: high-level composite target control operations - {RunToLine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } - {Run 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } - {Restart 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } - {StepInto 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } - {StepOver 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } + {RunToLine 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," } + {Run 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" } + {Restart 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" } + {StepInto 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" } + {StepOver 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" } //- rjf: debug control context management operations - {FreezeThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } - {ThawThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } - {FreezeProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } - {ThawProcess 1 1 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } - {FreezeMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } - {ThawMachine 0 1 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } - {FreezeLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } - {ThawLocalMachine 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } - {FreezeEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } - {ThawEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } + {FreezeThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" } + {ThawThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" } + {FreezeProcess 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" } + {ThawProcess 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" } + {FreezeMachine 0 1 0 0 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" } + {ThawMachine 0 1 0 0 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" } + {FreezeLocalMachine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" } + {ThawLocalMachine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" } + {FreezeEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" } + {ThawEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" } //- rjf: entity decoration - {SetEntityColor 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } - {SetEntityName 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } + {SetEntityColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" } + {SetEntityName 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" } //- rjf: attaching - {Attach 1 1 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } + {Attach 1 1 0 0 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" } } @enum D_CmdKind: diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 24e9396a..2c9c378e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -445,216 +445,216 @@ Rng1U64 rd_reg_slot_range_table[42] = RD_CmdKindInfo rd_cmd_kind_info_table[211] = { {0}, -{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("launch_and_step_into"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, -{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, -{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_font_size"), str8_lit_comp("Increases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_font_size"), str8_lit_comp("Decreases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("window_settings"), str8_lit_comp("Opens settings for a window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("reset_to_simple_panels"), str8_lit_comp("Resets the window to the simple panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("user_settings"), str8_lit_comp("Opens user settings."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("project_settings"), str8_lit_comp("Opens project settings."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, -{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, -{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("push_query"), str8_lit_comp("Opens a new temporary query interface."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("complete_query"), str8_lit_comp("Completes and closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("cancel_query"), str8_lit_comp("Closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("update_query"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("watches"), str8_lit_comp("Opens a Watch tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("locals"), str8_lit_comp("Opens a Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("registers"), str8_lit_comp("Opens a Registers tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("globals"), str8_lit_comp("Opens a Globals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a Thread Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("types"), str8_lit_comp("Opens a Types tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("procedures"), str8_lit_comp("Opens a Procedures tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("call_stack"), str8_lit_comp("Opens a Call Stack tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("targets"), str8_lit_comp("Opens a Targets tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens a Breakpoints tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens a Watch Pins tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("threads"), str8_lit_comp("Opens a Threads tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("processes"), str8_lit_comp("Opens a Processes tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens a Auto View Rules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("output"), str8_lit_comp("Opens a Output tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("disasm"), str8_lit_comp("Opens a Disassembly tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, -{ str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}, +{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("launch_and_step_into"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing attached process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all attached processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified attached process(es)."), str8_lit_comp("detach"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("continue"), str8_lit_comp("Continues executing all attached processes."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("halt"), str8_lit_comp("Halts all attached processes."), str8_lit_comp("pause"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all attached processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the specified thread's instruction pointer at the specified address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("restart"), str8_lit_comp("Kills all attached processes, then launches all active targets."), str8_lit_comp("restart,retry"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either source lines or instructions."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Process, str8_lit_comp("query:processes"), str8_lit_comp(""), CTRL_EntityKind_Process}}, +{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Machine, str8_lit_comp("query:machines"), str8_lit_comp(""), CTRL_EntityKind_Machine}}, +{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_color"), str8_lit_comp("Sets the passed entity's color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_entity_name"), str8_lit_comp("Sets the passed entity's name."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("os_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the call stack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_font_size"), str8_lit_comp("Increases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_font_size"), str8_lit_comp("Decreases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("window_settings"), str8_lit_comp("Opens settings for a window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_simple_panels"), str8_lit_comp("Resets the window to the simple panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_left"), str8_lit_comp("Creates a new panel to the left of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_up"), str8_lit_comp("Creates a new panel at the top of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("split_panel"), str8_lit_comp("Creates a new panel in a given direction, and moves a tab to it, if specified."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("focus_tab"), str8_lit_comp("Focuses the passed tab within its containing panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("user_settings"), str8_lit_comp("Opens user settings."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("project_settings"), str8_lit_comp("Opens project settings."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_up_reorder"), str8_lit_comp("Moves the cursor or selection up, while swapping the currently selected element with that upward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_down_reorder"), str8_lit_comp("Moves the cursor or selection down, while swapping the currently selected element with that downward."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("$text_rng,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads"), str8_lit_comp(""), CTRL_EntityKind_Thread}}, +{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp("symbol_lister"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp("Adds or removes the expression that the mouse is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_cfg"), str8_lit_comp("Enables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_cfg"), str8_lit_comp("Disables a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_cfg"), str8_lit_comp("Selects a config tree, disabling all others of the same kind."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("deselect_cfg"), str8_lit_comp("Deselects a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("remove_cfg"), str8_lit_comp("Removes a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("name_cfg"), str8_lit_comp("Equips a config tree with a label."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*1)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("push_query"), str8_lit_comp("Opens a new temporary query interface."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("complete_query"), str8_lit_comp("Completes and closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("cancel_query"), str8_lit_comp("Closes a query."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("update_query"), str8_lit_comp("Updates a query input."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("watches"), str8_lit_comp("Opens a Watch tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("locals"), str8_lit_comp("Opens a Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("registers"), str8_lit_comp("Opens a Registers tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("globals"), str8_lit_comp("Opens a Globals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a Thread Locals tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("types"), str8_lit_comp("Opens a Types tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("procedures"), str8_lit_comp("Opens a Procedures tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("call_stack"), str8_lit_comp("Opens a Call Stack tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("targets"), str8_lit_comp("Opens a Targets tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens a Breakpoints tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens a Watch Pins tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("threads"), str8_lit_comp("Opens a Threads tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("processes"), str8_lit_comp("Opens a Processes tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens a Auto View Rules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("output"), str8_lit_comp("Opens a Output tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("disasm"), str8_lit_comp("Opens a Disassembly tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 78d3613c..0477a1a2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -604,246 +604,246 @@ RD_RegTable: //////////////////////////////// //~ rjf: Command Table -@table(name ui_vis ipc_docs_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) -// / | | | | \___ __________________________/ | | | | | | -// / | | | | \ / | | | | | | -RD_CmdTable: // | | | | | | | | | | | | +@table(name ui_vis ipc_docs_vis text_pt_vis text_rng_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter) +// / | | | | | \___ __________________________/ | | | | | | +// / | | | | | \ / | | | | | | +RD_CmdTable: // | | | | | | | | | | | | | { //- rjf: exiting - {Exit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } + {Exit 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 X "exit" "Exit" "Exits the debugger." "quit,close,abort" "" } //- rjf: palette - {OpenPalette 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 List "open_palette" "Open Palette" "Opens the palette." "help,cmd,lister" "" } + {OpenPalette 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "open_palette" "Open Palette" "Opens the palette." "help,cmd,lister" "" } //- rjf: command runner - {RunCommand 1 1 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } + {RunCommand 1 1 0 0 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" } //- rjf: os event passthrough - {OSEvent 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } + {OSEvent 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "os_event" "OS Event" "" "" "" } //- rjf: thread/frame selection - {SelectThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } - {SelectUnwind 0 1 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } - {UpOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } - {DownOneFrame 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } - {SelectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select Entity" "Selects a control entity." "" "" } - {DeselectEntity 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } + {SelectThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Thread "select_thread" "Select Thread" "Selects a thread." "" "" } + {SelectUnwind 0 1 0 0 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } + {UpOneFrame 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } + {DownOneFrame 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } + {SelectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select Entity" "Selects a control entity." "" "" } + {DeselectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } //- rjf: font sizes - {IncFontSize 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_font_size" "Increase Font Size" "Increases the font size by one point." "" "" } - {DecFontSize 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_font_size" "Decrease Font Size" "Decreases the font size by one point." "" "" } + {IncFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_font_size" "Increase Font Size" "Increases the font size by one point." "" "" } + {DecFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_font_size" "Decrease Font Size" "Decreases the font size by one point." "" "" } //- rjf: windows - {OpenWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } - {WindowSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "window_settings" "Window Settings" "Opens settings for a window." "" "" } - {CloseWindow 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } - {ToggleFullscreen 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } - {BringToFront 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } + {OpenWindow 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } + {WindowSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "window_settings" "Window Settings" "Opens settings for a window." "" "" } + {CloseWindow 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "close_window" "Close Window" "Closes an opened window." "" "" } + {ToggleFullscreen 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "toggle_fullscreen" "Toggle Fullscreen" "Toggles fullscreen view on the active window." "" "" } + {BringToFront 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "bring_to_front" "Bring To Front" "Brings all windows to the front, and focuses the most recently focused window." "top" "" } //- rjf: popups - {PopupAccept 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } - {PopupCancel 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } + {PopupAccept 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } + {PopupCancel 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } //- rjf: panel splitting - {ResetToDefaultPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } - {ResetToCompactPanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } - {ResetToSimplePanels 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_simple_panels" "Reset To Simple Panel Layout" "Resets the window to the simple panel layout." "panel" "" } - {NewPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } - {NewPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } - {NewPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } - {NewPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } - {SplitPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } + {ResetToDefaultPanels 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } + {ResetToCompactPanels 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } + {ResetToSimplePanels 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_simple_panels" "Reset To Simple Panel Layout" "Resets the window to the simple panel layout." "panel" "" } + {NewPanelLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_left" "Split Panel Left" "Creates a new panel to the left of the active panel." "panel" "" } + {NewPanelUp 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_up" "Split Panel Up" "Creates a new panel at the top of the active panel." "panel" "" } + {NewPanelRight 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 XSplit "new_panel_right" "Split Panel Right" "Creates a new panel to the right of the active panel." "panel" "" } + {NewPanelDown 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 YSplit "new_panel_down" "Split Panel Down" "Creates a new panel at the bottom of the active panel." "panel" "" } + {SplitPanel 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "split_panel" "Split Panel" "Creates a new panel in a given direction, and moves a tab to it, if specified." "" "" } //- rjf: panel rotation - {RotatePanelColumns 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } + {RotatePanelColumns 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "rotate_panel_columns" "Rotate Panel Columns" "Rotates all panels at the closest column level of the panel hierarchy." "" "" } //- rjf: focused panel changing - {NextPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } - {PrevPanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } - {FocusPanel 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } - {FocusPanelRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } - {FocusPanelLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } - {FocusPanelUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } - {FocusPanelDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } + {NextPanel 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_panel" "Focus Next Panel" "Cycles the active panel forward." "" "" } + {PrevPanel 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_panel" "Focus Previous Panel" "Cycles the active panel backwards." "" "" } + {FocusPanel 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_panel" "Focus Panel" "Focuses a new panel." "" "" } + {FocusPanelRight 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "focus_panel_right" "Focus Panel Right" "Focuses a panel rightward of the currently focused panel." "" "" } + {FocusPanelLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "focus_panel_left" "Focus Panel Left" "Focuses a panel leftward of the currently focused panel." "" "" } + {FocusPanelUp 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "focus_panel_up" "Focus Panel Up" "Focuses a panel upward of the currently focused panel." "" "" } + {FocusPanelDown 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "focus_panel_down" "Focus Panel Down" "Focuses a panel downward of the currently focused panel." "" "" } //- rjf: undo/redo - {Undo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } - {Redo 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } + {Undo 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Undo "undo" "Undo" "Undoes the previous action." "" "" } + {Redo 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "redo" "Redo" "Redoes the first previously undone action." "" "" } //- rjf: focus history - {GoBack 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } - {GoForward 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } + {GoBack 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "go_back" "Go Back" "Returns to the previously selected panel and tab in recorded history." "" "" } + {GoForward 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "go_forward" "Go Forward" "Returns to the next selected panel and tab in recorded history." "" "" } //- rjf: panel removal - {ClosePanel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } + {ClosePanel 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 ClosePanel "close_panel" "Close Panel" "Closes the currently active panel." "" "" } //- rjf: panel tab - {FocusTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } - {NextTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } - {PrevTab 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } - {MoveTabRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } - {MoveTabLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } - {OpenTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } - {DuplicateTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } - {CloseTab 1 1 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } - {MoveTab 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } - {TabBarTop 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } - {TabBarBottom 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } - {TabSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Tab Settings" "Opens settings for a tab." "" "" } + {FocusTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "focus_tab" "Focus Tab" "Focuses the passed tab within its containing panel." "" "" } + {NextTab 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "next_tab" "Focus Next Tab" "Focuses the next tab on the active panel." "" "" } + {PrevTab 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } + {MoveTabRight 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } + {MoveTabLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } + {OpenTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {DuplicateTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } + {CloseTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {TabBarTop 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } + {TabBarBottom 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } + {TabSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Tab Settings" "Opens settings for a tab." "" "" } //- rjf: files - {SetCurrentPath 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } - {Open 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } - {Switch 1 1 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } - {SwitchToPartnerFile 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } - {RecordFileInProject 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } - {ShowFileInExplorer 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } + {SetCurrentPath 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } + {Open 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } + {Switch 1 1 0 0 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {SwitchToPartnerFile 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } + {RecordFileInProject 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } + {ShowFileInExplorer 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm - {GoToDisassembly 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } - {GoToSource 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } + {GoToDisassembly 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } + {GoToSource 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" "" } //- rjf: override file links - {SetFileReplacementPath 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } + {SetFileReplacementPath 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths - {OpenUser 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } - {OpenProject 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } - {OpenRecentProject 1 1 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } + {OpenUser 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } + {OpenProject 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } + {OpenRecentProject 1 1 0 0 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } //- rjf: writing config changes - {WriteUserData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } - {WriteProjectData 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } + {WriteUserData 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } + {WriteProjectData 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" "" } //- rjf: opening user/project settings - {UserSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "user_settings" "User Settings" "Opens user settings." "" "" } - {ProjectSettings 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "project_settings" "Project Settings" "Opens project settings." "" "" } + {UserSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "user_settings" "User Settings" "Opens user settings." "" "" } + {ProjectSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "project_settings" "Project Settings" "Opens project settings." "" "" } //- rjf: meta controls - {Edit 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } - {Accept 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } - {Cancel 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } + {Edit 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" "" } + {Accept 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "accept" "Accept" "Accepts current changes, or answers prompts in the affirmative." "" "" } + {Cancel 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 X "cancel" "Cancel" "Rejects current changes, exits temporary menus, or answers prompts in the negative." "" "" } //- rjf: directional movement & text controls - {MoveLeft 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } - {MoveRight 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } - {MoveUp 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } - {MoveDown 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } - {MoveLeftSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } - {MoveRightSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } - {MoveUpSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } - {MoveDownSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } - {MoveLeftChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } - {MoveDownPage 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } - {MoveUpWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } - {MoveDownWhole 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } - {MoveLeftChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } - {MoveRightChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } - {MoveUpChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } - {MoveDownChunkSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } - {MoveUpPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } - {MoveDownPageSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } - {MoveUpWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } - {MoveDownWholeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } - {MoveUpReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } - {MoveDownReorder 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } - {MoveHome 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } - {MoveEnd 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } - {MoveHomeSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } - {MoveEndSelect 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } - {SelectAll 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } - {DeleteSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } - {DeleteChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } - {BackspaceSingle 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } - {BackspaceChunk 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } - {Copy 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } - {Cut 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } - {Paste 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } - {InsertText 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } + {MoveLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left" "Move Left" "Moves the cursor or selection left." "" "" } + {MoveRight 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right" "Move Right" "Moves the cursor or selection right." "" "" } + {MoveUp 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up" "Move Up" "Moves the cursor or selection up." "" "" } + {MoveDown 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down" "Move Down" "Moves the cursor or selection down." "" "" } + {MoveLeftSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_select" "Move Left Select" "Moves the cursor or selection left, while selecting." "" "" } + {MoveRightSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_select" "Move Right Select" "Moves the cursor or selection right, while selecting." "" "" } + {MoveUpSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_select" "Move Up Select" "Moves the cursor or selection up, while selecting." "" "" } + {MoveDownSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_select" "Move Down Select" "Moves the cursor or selection down, while selecting." "" "" } + {MoveLeftChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk" "Move Left Chunk" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk" "Move Right Chunk" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk" "Move Up Chunk" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk" "Move Down Chunk" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPage 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page" "Move Up Page" "Moves the cursor or selection up one page." "" "" } + {MoveDownPage 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page" "Move Down Page" "Moves the cursor or selection down one page." "" "" } + {MoveUpWhole 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole" "Move Up Whole" "Moves the cursor or selection to the beginning of the relevant content." "" "" } + {MoveDownWhole 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole" "Move Down Whole" "Moves the cursor or selection to the end of the relevant content." "" "" } + {MoveLeftChunkSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_left_chunk_select" "Move Left Chunk Select" "Moves the cursor or selection left one chunk." "" "" } + {MoveRightChunkSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_right_chunk_select" "Move Right Chunk Select" "Moves the cursor or selection right one chunk." "" "" } + {MoveUpChunkSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_chunk_select" "Move Up Chunk Select" "Moves the cursor or selection up one chunk." "" "" } + {MoveDownChunkSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_chunk_select" "Move Down Chunk Select" "Moves the cursor or selection down one chunk." "" "" } + {MoveUpPageSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_page_select" "Move Up Page Select" "Moves the cursor or selection up one page, while selecting." "" "" } + {MoveDownPageSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_page_select" "Move Down Page Select" "Moves the cursor or selection down one page, while selecting." "" "" } + {MoveUpWholeSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_whole_select" "Move Up Whole Select" "Moves the cursor or selection to the beginning of the relevant content, while selecting." "" "" } + {MoveDownWholeSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_whole_select" "Move Down Whole Select" "Moves the cursor or selection to the end of the relevant content, while selecting." "" "" } + {MoveUpReorder 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_up_reorder" "Move Up Reorder" "Moves the cursor or selection up, while swapping the currently selected element with that upward." "" "" } + {MoveDownReorder 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_down_reorder" "Move Down Reorder" "Moves the cursor or selection down, while swapping the currently selected element with that downward." "" "" } + {MoveHome 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home" "Move Home" "Moves the cursor to the beginning of the line." "" "" } + {MoveEnd 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end" "Move End" "Moves the cursor to the end of the line." "" "" } + {MoveHomeSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_home_select" "Move Home Select" "Moves the cursor to the beginning of the line, while selecting." "" "" } + {MoveEndSelect 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_end_select" "Move End Select" "Moves the cursor to the end of the line, while selecting." "" "" } + {SelectAll 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "select_all" "Select All" "Selects everything possible." "" "" } + {DeleteSingle 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_single" "Delete Single" "Deletes a single element to the right of the cursor, or the active selection." "" "" } + {DeleteChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "delete_chunk" "Delete Chunk" "Deletes a chunk to the right of the cursor, or the active selection." "" "" } + {BackspaceSingle 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_single" "Backspace Single" "Deletes a single element to the left of the cursor, or the active selection." "" "" } + {BackspaceChunk 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "backspace_chunk" "Backspace Chunk" "Deletes a chunk to the left of the cursor, or the active selection." "" "" } + {Copy 1 1 0 1 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "copy" "Copy" "Copies the active selection to the clipboard." "" "$text_rng," } + {Cut 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "cut" "Cut" "Copies the active selection to the clipboard, then deletes it." "" "" } + {Paste 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } + {InsertText 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } //- rjf: code navigation - {GoToLine 1 1 "" Cursor null Nil Null 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } - {GoToAddress 1 1 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } - {CenterCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } - {ContainCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } - {FindNext 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } - {FindPrev 1 1 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } + {GoToLine 1 1 0 0 "" Cursor null Nil Null 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } + {GoToAddress 1 1 0 0 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } + {CenterCursor 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "center_cursor" "Center Cursor" "Snaps the current code view to center the cursor." "" "" } + {ContainCursor 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "contain_cursor" "Contain Cursor" "Snaps the current code view to contain the cursor." "" "" } + {FindNext 1 1 0 0 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_next" "Find Next" "Searches the current code file forward (from the cursor) for the last searched string." "" "" } + {FindPrev 1 1 0 0 "" Null null Nil Null 0 0 1 0 0 0 0 Find "find_prev" "Find Previous" "Searches the current code file backwards (from the cursor) for the last searched string." "" "" } //- rjf: thread finding - {FindThread 1 1 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } - {FindSelectedThread 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } + {FindThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Find "find_thread" "Find Thread" "Jumps to the passed thread in either source code, disassembly, or both if they're already open." "" "" } + {FindSelectedThread 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Find "find_selected_thread" "Find Selected Thread" "Jumps to the selected thread in either source code, disassembly, or both if they're already open." "" "" } //- rjf: name finding - {GoToName 1 1 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } - {GoToNameAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } + {GoToName 1 1 0 0 "query:procedures" String symbol_lister Nil Null 0 0 0 0 1 1 1 Null "goto_name" "Go To Name" "Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible." "" "$text_pt," } + {GoToNameAtCursor 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "goto_name_at_cursor" "Go To Name At Cursor" "Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible." "" "" } //- rjf: watch expressions - {ToggleWatchExpression 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } - {ToggleWatchExpressionAtCursor 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } - {ToggleWatchExpressionAtMouse 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } + {ToggleWatchExpression 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr" "Toggle Watch Expression" "Adds or removes an expression to an opened watch view." "" "$text_pt," } + {ToggleWatchExpressionAtCursor 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_cursor" "Toggle Watch Expression At Cursor" "Adds or removes the expression that the cursor or selection is currently over to an opened watch view." "" "" } + {ToggleWatchExpressionAtMouse 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: general config operations - {EnableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } - {DisableCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } - {SelectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } - {DeselectCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree." "" "" } - {RemoveCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } - {NameCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } - {ConditionCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } - {DuplicateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } - {RelocateCfg 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } + {EnableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } + {DisableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } + {SelectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree." "" "" } + {RemoveCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } + {NameCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } - {AddAddressBreakpoint 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {ToggleBreakpoint 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } - {EnableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } - {DisableBreakpoint 1 1 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {AddBreakpoint 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddAddressBreakpoint 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } + {ToggleBreakpoint 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {EnableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } + {DisableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } //- rjf: watch pins - {AddWatchPin 1 1 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } - {ToggleWatchPin 1 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + {AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } + {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } //- rjf: auto view rule - {AddAutoViewRule 1 1 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } //- rjf: line operations - {SetNextStatement 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } + {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } //- rjf: targets - {AddTarget 1 1 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } - {SelectTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Target "select_target" "Select Target" "Selects a target." "" "" } - {EnableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } - {DisableTarget 1 1 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } + {AddTarget 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" "$targets," } + {SelectTarget 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Target "select_target" "Select Target" "Selects a target." "" "" } + {EnableTarget 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" "" } + {DisableTarget 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" "" } //- rjf: attaching - {RegisterAsJITDebugger 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } + {RegisterAsJITDebugger 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "register_as_jit_debugger" "Register As Just-In-Time (JIT) Debugger" "Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system." "" "" } //- rjf: snap-to-code-location - {FindCodeLocation 0 1 "" FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } + {FindCodeLocation 0 1 0 0 "" FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } //- rjf: searching - {Search 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } - {SearchBackwards 1 1 "" String null Nil Null 0 0 1 1 1 0 1 Find "search_backwards" "Search Backwards" "Begins searching backwards within the active interface." "sort,search,filter,find" "" } + {Search 1 1 0 0 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } + {SearchBackwards 1 1 0 0 "" String null Nil Null 0 0 1 1 1 0 1 Find "search_backwards" "Search Backwards" "Begins searching backwards within the active interface." "sort,search,filter,find" "" } //- rjf: queries - {PickFile 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } - {PickFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } - {PickFileOrFolder 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } + {PickFile 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "pick_file" "Pick File" "Opens the file browser to pick a file." "" "" } + {PickFolder 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 0 1 0 0 0 1 1 FolderOpenFilled "pick_folder" "Pick Folder" "Opens the file browser to pick a folder." "" "" } + {PickFileOrFolder 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 1 0 0 0 1 1 FileOutline "pick_file_or_folder" "Pick File/Folder" "Opens the file browser to pick a file or folder." "" "" } //- rjf: query stack - {PushQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_query" "Push Query" "Opens a new temporary query interface." "" "" } - {CompleteQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_query" "Complete Query" "Completes and closes a query." "" "" } - {CancelQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_query" "Cancel Query" "Closes a query." "" "" } - {UpdateQuery 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_query" "Update Query" "Updates a query input." "" "" } + {PushQuery 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "push_query" "Push Query" "Opens a new temporary query interface." "" "" } + {CompleteQuery 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "complete_query" "Complete Query" "Completes and closes a query." "" "" } + {CancelQuery 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "cancel_query" "Cancel Query" "Closes a query." "" "" } + {UpdateQuery 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "update_query" "Update Query" "Updates a query input." "" "" } //- rjf: developer commands - {ToggleDevMenu 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } - {LogMarker 1 1 "" Null null Nil Null 0 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } + {ToggleDevMenu 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" "" } + {LogMarker 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" "" } } @enum RD_CmdKind: @@ -881,13 +881,13 @@ RD_CmdTable: // | | | | { `{0}`, @expand(D_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis))|(RD_CmdKindFlag_ListInTextPt*$(a.text_pt_vis))|(RD_CmdKindFlag_ListInTextRng*$(a.text_rng_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_CmdTable, a) - ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; + ```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.ctx_filter)"), (RD_CmdKindFlag_ListInUI*$(a.ui_vis))|(RD_CmdKindFlag_ListInIPCDocs*$(a.ipc_docs_vis))|(RD_CmdKindFlag_ListInTextPt*$(a.text_pt_vis))|(RD_CmdKindFlag_ListInTextRng*$(a.text_rng_vis)), {(RD_QueryFlag_AllowFiles*$(a.q_allow_files))|(RD_QueryFlag_AllowFolders*$(a.q_allow_folders))|(RD_QueryFlag_CodeInput*$(a.q_is_code))|(RD_QueryFlag_KeepOldInput*$(a.q_keep_oi))|(RD_QueryFlag_SelectOldInput*$(a.q_select_oi))|(RD_QueryFlag_Floating*$(a.q_floating))|(RD_QueryFlag_Required*$(a.q_required)), RD_RegSlot_$(a.q_slot), str8_lit_comp("$(a.q_expr)"), str8_lit_comp("$(a.q_view != 'null' -> a.q_view)"), CTRL_EntityKind_$(a.q_ctrl_ent_kind)}}```; @expand(RD_WatchTabFastPathTable, a) - ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}```; + ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}```; @expand(RD_ViewTabFastPathTable, a) - ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs}```; + ```{ str8_lit_comp("$(a.name_lower)"), str8_lit_comp("Opens a $(a.display_name) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}```; } //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 93335438..2660f97f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6506,8 +6506,8 @@ rd_window_frame(void) UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); if(anchor_box != &ui_nil_box) { - rect.x0 = anchor_box->rect.x0; - rect.y0 = anchor_box->rect.y1; + rect.x0 = anchor_box->rect.x0 + ws->query_regs->off_px.x; + rect.y0 = anchor_box->rect.y1 + ws->query_regs->off_px.y; rect.x1 = rect.x0 + ui_top_font_size()*60.f; rect.y1 = rect.y0 + query_height_px; } @@ -8573,11 +8573,10 @@ rd_window_frame(void) if(ui_pressed(sig)) { rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); - rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:commands"), + rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:tab_commands"), .panel = panel->cfg->id, .do_implicit_root = 1, .do_lister = 1, - .do_big_rows = 1, .ui_key = add_new_box->key, .off_px = v2f32(0, dim_2f32(add_new_box->rect).y)); } @@ -11869,21 +11868,31 @@ rd_frame(void) EV_ExpandRuleTable *expand_rule_table = push_array(scratch.arena, EV_ExpandRuleTable, 1); rd_state->view_ui_rule_map = rd_view_ui_rule_map_make(scratch.arena, 512); { - //- rjf: add macro for commands + //- rjf: add macros for command groups { - String8 name = str8_lit("commands"); - E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, - .name = name, - .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + String8 names[] = + { + str8_lit("commands"), + str8_lit("tab_commands"), + str8_lit("text_pt_commands"), + str8_lit("text_range_commands"), + }; + for EachElement(idx, names) + { + String8 name = names[idx]; + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + } } //- rjf: build schema types & cache (name -> type) mapping @@ -13620,14 +13629,6 @@ rd_frame(void) rd_cfg_new(project, rd_state->project_path); } rd_cmd(RD_CmdKind_FocusTab, .view = tab->id); -#if 0 // TODO(rjf): @cfg (tab opening) - RD_Panel *panel = rd_panel_from_handle(rd_regs()->panel); - RD_View *view = rd_view_alloc(); - String8 query = rd_regs()->string; - RD_ViewRuleInfo *spec = rd_view_rule_info_from_string(rd_regs()->params_tree->string); - rd_view_equip_spec(view, spec, query, rd_regs()->params_tree); - rd_panel_insert_tab_view(panel, panel->last_tab_view, view); -#endif }break; case RD_CmdKind_DuplicateTab: { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index a35120df..960d2934 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -157,6 +157,9 @@ enum { RD_CmdKindFlag_ListInUI = (1<<0), RD_CmdKindFlag_ListInIPCDocs = (1<<1), + RD_CmdKindFlag_ListInTab = (1<<2), + RD_CmdKindFlag_ListInTextPt = (1<<3), + RD_CmdKindFlag_ListInTextRng = (1<<4), }; //////////////////////////////// diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index b122e5e1..98343f95 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -26,10 +26,14 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) { Temp scratch = scratch_begin(&arena, 1); String8List cmd_names = {0}; + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); for EachNonZeroEnumVal(RD_CmdKind, k) { RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - if(info->flags & RD_CmdKindFlag_ListInUI) + if(info->flags & RD_CmdKindFlag_ListInUI && + (!str8_match(type->name, str8_lit("text_pt_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTextPt) && + (!str8_match(type->name, str8_lit("text_range_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTextRng) && + (!str8_match(type->name, str8_lit("tab_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTab)) { String8 code_name = info->string; String8 description = info->description; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 5bf3f79d..ea327409 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2156,17 +2156,16 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min]; lines = params->line_infos[cursor->line - params->line_num_range.min]; } -#if 0 // TODO(rjf): @cfg rd_cmd(RD_CmdKind_PushQuery, - .reg_slot = RD_RegSlot_Cursor, - .ui_key = ui_get_selected_state()->root->key, - .off_px = sub_2f32(ui_mouse(), v2f32(2, 2)), - .cursor = *cursor, - .mark = *mark, - .vaddr = vaddr, - .lines = lines, - .lister_flags= RD_ListerFlag_LineEdit|RD_ListerFlag_Settings|RD_ListerFlag_Commands); -#endif + .expr = txt_pt_match(*cursor, *mark) ? str8_lit("query:text_pt_commands") : str8_lit("query:text_range_commands"), + .do_implicit_root = 1, + .do_lister = 1, + .ui_key = ui_get_selected_state()->root->key, + .off_px = ui_mouse(), + .cursor = *cursor, + .mark = *mark, + .vaddr = vaddr, + .lines = lines); } //- rjf: dragging threads, breakpoints, or watch pins over this slice -> From 0fbcd72a3ef0b52ee49407889641bea473d06668 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 24 Apr 2025 20:09:18 -0700 Subject: [PATCH 451/755] fix query offsets --- src/raddbg/raddbg_core.c | 4 +--- src/raddbg/raddbg_widgets.c | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2660f97f..dc3c87b6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8477,7 +8477,6 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_PushQuery, .ui_key = sig.box->key, - .off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0), .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); } else if(ui_middle_clicked(sig)) @@ -8577,8 +8576,7 @@ rd_window_frame(void) .panel = panel->cfg->id, .do_implicit_root = 1, .do_lister = 1, - .ui_key = add_new_box->key, - .off_px = v2f32(0, dim_2f32(add_new_box->rect).y)); + .ui_key = add_new_box->key); } } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ea327409..46fb322b 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1409,7 +1409,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = thread_box->key, - .off_px = v2f32(0, dim_2f32(thread_box->rect).y), .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) @@ -1564,7 +1563,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = thread_box->key, - .off_px = v2f32(0, dim_2f32(thread_box->rect).y), .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) @@ -1646,7 +1644,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = bp_box->key, - .off_px = v2f32(0, dim_2f32(bp_box->rect).y), .expr = push_str8f(scratch.arena, "$%I64x", bp->id)); } @@ -1704,7 +1701,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = pin_box->key, - .off_px = v2f32(0, dim_2f32(pin_box->rect).y), .expr = push_str8f(scratch.arena, "$%I64x", pin->id)); } From fe46e61acbc13fba0e10a8b0f5bc9e14e74da2c7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 08:25:00 -0700 Subject: [PATCH 452/755] eliminate recursion from ui size calculation pass, replace with iterative equivalents --- src/ui/ui_core.c | 137 ++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 79 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 53e68765..7a853e81 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1616,29 +1616,23 @@ internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis) { ProfBeginFunction(); - - switch(root->pref_size[axis].kind) + for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next) { - default:{}break; - case UI_SizeKind_Pixels: + switch(b->pref_size[axis].kind) { - root->fixed_size.v[axis] = root->pref_size[axis].value; - }break; - - case UI_SizeKind_TextContent: - { - F32 padding = root->pref_size[axis].value; - F32 text_size = root->display_fruns.dim.x; - root->fixed_size.v[axis] = padding + text_size + root->text_padding*2; - }break; + default:{}break; + case UI_SizeKind_Pixels: + { + b->fixed_size.v[axis] = b->pref_size[axis].value; + }break; + case UI_SizeKind_TextContent: + { + F32 padding = b->pref_size[axis].value; + F32 text_size = b->display_fruns.dim.x; + b->fixed_size.v[axis] = padding + text_size + b->text_padding*2; + }break; + } } - - //- rjf: recurse - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - ui_calc_sizes_standalone__in_place_rec(child, axis); - } - ProfEnd(); } @@ -1646,43 +1640,35 @@ internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) { ProfBeginFunction(); - - //- rjf: solve for all kinds that are upwards-dependent - switch(root->pref_size[axis].kind) + for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next) { - default: break; - - // rjf: if root has a parent percentage, figure out its size - case UI_SizeKind_ParentPct: + switch(b->pref_size[axis].kind) { - // rjf: find parent that has a fixed size - UI_Box *fixed_parent = &ui_nil_box; - for(UI_Box *p = root->parent; !ui_box_is_nil(p); p = p->parent) + default:{}break; + case UI_SizeKind_ParentPct: { - if(p->flags & (UI_BoxFlag_FixedWidth<pref_size[axis].kind == UI_SizeKind_Pixels || - p->pref_size[axis].kind == UI_SizeKind_TextContent || - p->pref_size[axis].kind == UI_SizeKind_ParentPct) + // rjf: find parent that has a fixed size + UI_Box *fixed_parent = &ui_nil_box; + for(UI_Box *p = b->parent; !ui_box_is_nil(p); p = p->parent) { - fixed_parent = p; - break; + if(p->flags & (UI_BoxFlag_FixedWidth<pref_size[axis].kind == UI_SizeKind_Pixels || + p->pref_size[axis].kind == UI_SizeKind_TextContent || + p->pref_size[axis].kind == UI_SizeKind_ParentPct) + { + fixed_parent = p; + break; + } } - } - - // rjf: figure out root's size on this axis - F32 size = fixed_parent->fixed_size.v[axis] * root->pref_size[axis].value; - - // rjf: mutate root to have this size - root->fixed_size.v[axis] = size; - }break; + + // rjf: figure out box's size on this axis + F32 size = fixed_parent->fixed_size.v[axis] * b->pref_size[axis].value; + + // rjf: mutate box to have this size + b->fixed_size.v[axis] = size; + }break; + } } - - //- rjf: recurse - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - ui_calc_sizes_upwards_dependent__in_place_rec(child, axis); - } - ProfEnd(); } @@ -1690,43 +1676,36 @@ internal void ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) { ProfBeginFunction(); - - //- rjf: recurse first. we may depend on children that have - // the same property - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + UI_BoxRec rec = {0}; + for(UI_Box *box = root; !ui_box_is_nil(box); box = rec.next) { - ui_calc_sizes_downwards_dependent__in_place_rec(child, axis); - } - - //- rjf: solve for all kinds that are downwards-dependent - switch(root->pref_size[axis].kind) - { - default: break; - - // rjf: sum children - case UI_SizeKind_ChildrenSum: + rec = ui_box_rec_df_pre(box, root); + S32 pop_idx = 0; + for(UI_Box *b = box; + !ui_box_is_nil(b) && pop_idx <= rec.pop_count; + b = b->parent, pop_idx += 1) { - F32 sum = 0; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + if(b->pref_size[axis].kind == UI_SizeKind_ChildrenSum) { - if(!(child->flags & (UI_BoxFlag_FloatingX<first; !ui_box_is_nil(child); child = child->next) { - if(axis == root->child_layout_axis) + if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis]; - } - else - { - sum = Max(sum, child->fixed_size.v[axis]); + if(axis == b->child_layout_axis) + { + sum += child->fixed_size.v[axis]; + } + else + { + sum = Max(sum, child->fixed_size.v[axis]); + } } } + b->fixed_size.v[axis] = sum; } - - // rjf: figure out root's size on this axis - root->fixed_size.v[axis] = sum; - }break; + } } - ProfEnd(); } From e0ba1155e843d7066f28da94519c636f5e9c8b28 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 08:29:44 -0700 Subject: [PATCH 453/755] eliminate recursive version of final ui layout position pass --- src/ui/ui_core.c | 272 +++++++++++++++++++++++------------------------ src/ui/ui_core.h | 10 +- 2 files changed, 137 insertions(+), 145 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 7a853e81..70abe70e 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1272,11 +1272,11 @@ ui_end_build(void) root->rect = new_root_rect; for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1)) { - ui_calc_sizes_standalone__in_place_rec(root, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(root, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(root, axis); - ui_layout_enforce_constraints__in_place_rec(root, axis); - ui_layout_position__in_place_rec(root, axis); + ui_calc_sizes_standalone__in_place(root, axis); + ui_calc_sizes_upwards_dependent__in_place(root, axis); + ui_calc_sizes_downwards_dependent__in_place(root, axis); + ui_layout_enforce_constraints__in_place(root, axis); + ui_layout_position__in_place(root, axis); } } } @@ -1613,7 +1613,7 @@ ui_end_build(void) } internal void -ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis) +ui_calc_sizes_standalone__in_place(UI_Box *root, Axis2 axis) { ProfBeginFunction(); for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next) @@ -1637,7 +1637,7 @@ ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis) } internal void -ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) +ui_calc_sizes_upwards_dependent__in_place(UI_Box *root, Axis2 axis) { ProfBeginFunction(); for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next) @@ -1673,7 +1673,7 @@ ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) } internal void -ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) +ui_calc_sizes_downwards_dependent__in_place(UI_Box *root, Axis2 axis) { ProfBeginFunction(); UI_BoxRec rec = {0}; @@ -1710,180 +1710,172 @@ ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis) } internal void -ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis) +ui_layout_enforce_constraints__in_place(UI_Box *root, Axis2 axis) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - - // NOTE(rjf): The "layout axis" is the direction in which children - // of some node are intended to be laid out. - - //- rjf: fixup children sizes (if we're solving along the *non-layout* axis) - if(axis != root->child_layout_axis && !(root->flags & (UI_BoxFlag_AllowOverflowX << axis))) + for(UI_Box *box = root; !ui_box_is_nil(box); box = ui_box_rec_df_pre(box, root).next) { - F32 allowed_size = root->fixed_size.v[axis]; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + //- rjf: fixup children sizes (if we're solving along the *non-layout* axis) + if(axis != box->child_layout_axis && !(box->flags & (UI_BoxFlag_AllowOverflowX << axis))) { - if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis]; + for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next) { - F32 child_size = child->fixed_size.v[axis]; - F32 violation = child_size - allowed_size; - F32 max_fixup = child_size; - F32 fixup = Clamp(0, violation, max_fixup); - if(fixup > 0) + if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis] -= fixup; + F32 child_size = child->fixed_size.v[axis]; + F32 violation = child_size - allowed_size; + F32 max_fixup = child_size; + F32 fixup = Clamp(0, violation, max_fixup); + if(fixup > 0) + { + child->fixed_size.v[axis] -= fixup; + } } } } - } - - //- rjf: fixup children sizes (in the direction of the layout axis) - if(axis == root->child_layout_axis && !(root->flags & (UI_BoxFlag_AllowOverflowX << axis))) - { - // rjf: figure out total allowed size & total size - F32 total_allowed_size = root->fixed_size.v[axis]; - F32 total_size = 0; - F32 total_weighted_size = 0; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis]; - total_weighted_size += child->fixed_size.v[axis] * (1-child->pref_size[axis].strictness); - } - } - // rjf: if we have a violation, we need to subtract some amount from all children - F32 violation = total_size - total_allowed_size; - if(violation > 0 && total_weighted_size > 0) + //- rjf: fixup children sizes (in the direction of the layout axis) + if(axis == box->child_layout_axis && !(box->flags & (UI_BoxFlag_AllowOverflowX << axis))) { - // rjf: figure out how much we can take in totality - F32 child_fixup_sum = 0; - F32 *child_fixups = push_array(scratch.arena, F32, root->child_count); + // rjf: figure out total allowed size & total size + F32 total_allowed_size = box->fixed_size.v[axis]; + F32 total_size = 0; + F32 total_weighted_size = 0; + for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next) { - U64 child_idx = 0; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next, child_idx += 1) + if(!(child->flags & (UI_BoxFlag_FloatingX<flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis] * (1-child->pref_size[axis].strictness); - fixup_size_this_child = ClampBot(0, fixup_size_this_child); - child_fixups[child_idx] = fixup_size_this_child; - child_fixup_sum += fixup_size_this_child; - } + total_size += child->fixed_size.v[axis]; + total_weighted_size += child->fixed_size.v[axis] * (1-child->pref_size[axis].strictness); } } - // rjf: fixup child sizes + // rjf: if we have a violation, we need to subtract some amount from all children + F32 violation = total_size - total_allowed_size; + if(violation > 0 && total_weighted_size > 0) { - U64 child_idx = 0; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next, child_idx += 1) + Temp temp = temp_begin(scratch.arena); + + // rjf: figure out how much we can take in totality + F32 child_fixup_sum = 0; + F32 *child_fixups = push_array(temp.arena, F32, box->child_count); { - if(!(child->flags & (UI_BoxFlag_FloatingX<first; !ui_box_is_nil(child); child = child->next, child_idx += 1) { - F32 fixup_pct = (violation / total_weighted_size); - fixup_pct = Clamp(0, fixup_pct, 1); - child->fixed_size.v[axis] -= child_fixups[child_idx] * fixup_pct; + if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis] * (1-child->pref_size[axis].strictness); + fixup_size_this_child = ClampBot(0, fixup_size_this_child); + child_fixups[child_idx] = fixup_size_this_child; + child_fixup_sum += fixup_size_this_child; + } } } + + // rjf: fixup child sizes + { + U64 child_idx = 0; + for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next, child_idx += 1) + { + if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis] -= child_fixups[child_idx] * fixup_pct; + } + } + } + + temp_end(temp); + } + } + + //- rjf: fixup upwards-relative sizes + if(box->flags & (UI_BoxFlag_AllowOverflowX << axis)) + { + for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next) + { + if(child->pref_size[axis].kind == UI_SizeKind_ParentPct) + { + child->fixed_size.v[axis] = box->fixed_size.v[axis] * child->pref_size[axis].value; + } } } - } - - //- rjf: fixup upwards-relative sizes - if(root->flags & (UI_BoxFlag_AllowOverflowX << axis)) - { - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + + //- rjf: enforce clamps + for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next) { - if(child->pref_size[axis].kind == UI_SizeKind_ParentPct) - { - child->fixed_size.v[axis] = root->fixed_size.v[axis] * child->pref_size[axis].value; - } + child->fixed_size.v[axis] = Max(child->fixed_size.v[axis], child->min_size.v[axis]); } } - - //- rjf: enforce clamps - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - child->fixed_size.v[axis] = Max(child->fixed_size.v[axis], child->min_size.v[axis]); - } - - //- rjf: recurse - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - ui_layout_enforce_constraints__in_place_rec(child, axis); - } - scratch_end(scratch); ProfEnd(); } internal void -ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis) +ui_layout_position__in_place(UI_Box *root, Axis2 axis) { ProfBeginFunction(); - F32 layout_position = 0; - - //- rjf: lay out children - F32 bounds = 0; - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) + for(UI_Box *box = root; !ui_box_is_nil(box); box = ui_box_rec_df_pre(box, root).next) { - // rjf: grab original position - F32 original_position = Min(child->rect.p0.v[axis], child->rect.p1.v[axis]); + F32 layout_position = 0; - // rjf: calculate fixed position & size - if(!(child->flags & (UI_BoxFlag_FloatingX<first; !ui_box_is_nil(child); child = child->next) { - child->fixed_position.v[axis] = layout_position; - if(root->child_layout_axis == axis) + // rjf: grab original position + F32 original_position = Min(child->rect.p0.v[axis], child->rect.p1.v[axis]); + + // rjf: calculate fixed position & size + if(!(child->flags & (UI_BoxFlag_FloatingX<fixed_size.v[axis]; - bounds += child->fixed_size.v[axis]; + child->fixed_position.v[axis] = layout_position; + if(box->child_layout_axis == axis) + { + layout_position += child->fixed_size.v[axis]; + bounds += child->fixed_size.v[axis]; + } + else + { + bounds = Max(bounds, child->fixed_size.v[axis]); + } + } + + // rjf: determine final rect for child, given fixed_position & size + if(child->flags & (UI_BoxFlag_AnimatePosX<first_touched_build_index == child->last_touched_build_index) + { + child->fixed_position_animated = child->fixed_position; + } + child->rect.p0.v[axis] = box->rect.p0.v[axis] + child->fixed_position_animated.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<view_off.v[axis]); } else { - bounds = Max(bounds, child->fixed_size.v[axis]); + child->rect.p0.v[axis] = box->rect.p0.v[axis] + child->fixed_position.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<view_off.v[axis]); } + child->rect.p1.v[axis] = child->rect.p0.v[axis] + child->fixed_size.v[axis]; + child->rect.p0.x = floor_f32(child->rect.p0.x); + child->rect.p0.y = floor_f32(child->rect.p0.y); + child->rect.p1.x = floor_f32(child->rect.p1.x); + child->rect.p1.y = floor_f32(child->rect.p1.y); + + // rjf: grab new position + F32 new_position = Min(child->rect.p0.v[axis], child->rect.p1.v[axis]); + + // rjf: store position delta + child->position_delta.v[axis] = new_position - original_position; } - // rjf: determine final rect for child, given fixed_position & size - if(child->flags & (UI_BoxFlag_AnimatePosX<first_touched_build_index == child->last_touched_build_index) - { - child->fixed_position_animated = child->fixed_position; - } - child->rect.p0.v[axis] = root->rect.p0.v[axis] + child->fixed_position_animated.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<view_off.v[axis]); + box->view_bounds.v[axis] = bounds; } - else - { - child->rect.p0.v[axis] = root->rect.p0.v[axis] + child->fixed_position.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<view_off.v[axis]); - } - child->rect.p1.v[axis] = child->rect.p0.v[axis] + child->fixed_size.v[axis]; - child->rect.p0.x = floor_f32(child->rect.p0.x); - child->rect.p0.y = floor_f32(child->rect.p0.y); - child->rect.p1.x = floor_f32(child->rect.p1.x); - child->rect.p1.y = floor_f32(child->rect.p1.y); - - // rjf: grab new position - F32 new_position = Min(child->rect.p0.v[axis], child->rect.p1.v[axis]); - - // rjf: store position delta - child->position_delta.v[axis] = new_position - original_position; } - - //- rjf: store view bounds - { - root->view_bounds.v[axis] = bounds; - } - - //- rjf: recurse - for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next) - { - ui_layout_position__in_place_rec(child, axis); - } - ProfEnd(); } @@ -1891,11 +1883,11 @@ internal void ui_layout_root(UI_Box *root, Axis2 axis) { ProfBegin("ui layout pass (%s)", axis == Axis2_X ? "x" : "y"); - ui_calc_sizes_standalone__in_place_rec(root, axis); - ui_calc_sizes_upwards_dependent__in_place_rec(root, axis); - ui_calc_sizes_downwards_dependent__in_place_rec(root, axis); - ui_layout_enforce_constraints__in_place_rec(root, axis); - ui_layout_position__in_place_rec(root, axis); + ui_calc_sizes_standalone__in_place(root, axis); + ui_calc_sizes_upwards_dependent__in_place(root, axis); + ui_calc_sizes_downwards_dependent__in_place(root, axis); + ui_layout_enforce_constraints__in_place(root, axis); + ui_layout_position__in_place(root, axis); ProfEnd(); } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index f2546163..98c0349c 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -862,11 +862,11 @@ internal UI_Box * ui_box_from_key(UI_Key key); internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt); internal void ui_end_build(void); -internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis); -internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); -internal void ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis); -internal void ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis); -internal void ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis); +internal void ui_calc_sizes_standalone__in_place(UI_Box *root, Axis2 axis); +internal void ui_calc_sizes_upwards_dependent__in_place(UI_Box *root, Axis2 axis); +internal void ui_calc_sizes_downwards_dependent__in_place(UI_Box *root, Axis2 axis); +internal void ui_layout_enforce_constraints__in_place(UI_Box *root, Axis2 axis); +internal void ui_layout_position__in_place(UI_Box *root, Axis2 axis); internal void ui_layout_root(UI_Box *root, Axis2 axis); //////////////////////////////// From 7dc920c14fd64bbdf6adc328988fd996d847aa26 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 09:45:43 -0700 Subject: [PATCH 454/755] font cache: add additional layer of caching for runs --- src/base/base_entry_point.c | 3 + src/font_cache/font_cache.c | 633 ++++++++++++++++++++---------------- src/font_cache/font_cache.h | 56 +++- 3 files changed, 390 insertions(+), 302 deletions(-) diff --git a/src/base/base_entry_point.c b/src/base/base_entry_point.c index 21bbc363..6d489e66 100644 --- a/src/base/base_entry_point.c +++ b/src/base/base_entry_point.c @@ -121,6 +121,9 @@ update(void) { ProfTick(0); ins_atomic_u64_inc_eval(&global_update_tick_idx); +#if defined(FONT_CACHE_H) + fnt_frame(); +#endif #if OS_FEATURE_GRAPHICAL B32 result = frame(); #else diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index 52c4aa3a..4070aa3c 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -24,9 +24,9 @@ fnt_hash_from_string(String8 string) } internal U64 -fnt_little_hash_from_string(String8 string) +fnt_little_hash_from_string(U64 seed, String8 string) { - U64 result = XXH3_64bits(string.str, string.size); + U64 result = XXH3_64bits_withSeed(string.str, string.size, seed); return result; } @@ -65,10 +65,10 @@ internal FP_Handle fnt_handle_from_tag(FNT_Tag tag) { ProfBeginFunction(); - U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size; + U64 slot_idx = tag.u64[1] % fnt_state->font_hash_table_size; FNT_FontHashNode *existing_node = 0; { - for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) + for(FNT_FontHashNode *n = fnt_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) { if(MemoryMatchStruct(&tag, &n->tag)) { @@ -90,10 +90,10 @@ internal FP_Metrics fnt_fp_metrics_from_tag(FNT_Tag tag) { ProfBeginFunction(); - U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size; + U64 slot_idx = tag.u64[1] % fnt_state->font_hash_table_size; FNT_FontHashNode *existing_node = 0; { - for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) + for(FNT_FontHashNode *n = fnt_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) { if(MemoryMatchStruct(&tag, &n->tag)) { @@ -125,12 +125,12 @@ fnt_tag_from_path(String8 path) } //- rjf: tag -> slot index - U64 slot_idx = result.u64[1] % f_state->font_hash_table_size; + U64 slot_idx = result.u64[1] % fnt_state->font_hash_table_size; //- rjf: slot * tag -> existing node FNT_FontHashNode *existing_node = 0; { - for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) + for(FNT_FontHashNode *n = fnt_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) { if(MemoryMatchStruct(&result, &n->tag)) { @@ -144,12 +144,12 @@ fnt_tag_from_path(String8 path) FNT_FontHashNode *new_node = 0; if(existing_node == 0) { - FNT_FontHashSlot *slot = &f_state->font_hash_table[slot_idx]; - new_node = push_array(f_state->permanent_arena, FNT_FontHashNode, 1); + FNT_FontHashSlot *slot = &fnt_state->font_hash_table[slot_idx]; + new_node = push_array(fnt_state->permanent_arena, FNT_FontHashNode, 1); new_node->tag = result; new_node->handle = fp_font_open(path); new_node->metrics = fp_metrics_from_font(new_node->handle); - new_node->path = push_str8_copy(f_state->permanent_arena, path); + new_node->path = push_str8_copy(fnt_state->permanent_arena, path); SLLQueuePush_N(slot->first, slot->last, new_node, hash_next); } @@ -172,12 +172,12 @@ fnt_tag_from_static_data_string(String8 *data_ptr) } //- rjf: tag -> slot index - U64 slot_idx = result.u64[1] % f_state->font_hash_table_size; + U64 slot_idx = result.u64[1] % fnt_state->font_hash_table_size; //- rjf: slot * tag -> existing node FNT_FontHashNode *existing_node = 0; { - for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) + for(FNT_FontHashNode *n = fnt_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) { if(MemoryMatchStruct(&result, &n->tag)) { @@ -191,8 +191,8 @@ fnt_tag_from_static_data_string(String8 *data_ptr) FNT_FontHashNode *new_node = 0; if(existing_node == 0) { - FNT_FontHashSlot *slot = &f_state->font_hash_table[slot_idx]; - new_node = push_array(f_state->permanent_arena, FNT_FontHashNode, 1); + FNT_FontHashSlot *slot = &fnt_state->font_hash_table[slot_idx]; + new_node = push_array(fnt_state->permanent_arena, FNT_FontHashNode, 1); new_node->tag = result; new_node->handle = fp_font_open_from_static_data_string(data_ptr); new_node->metrics = fp_metrics_from_font(new_node->handle); @@ -209,12 +209,12 @@ internal String8 fnt_path_from_tag(FNT_Tag tag) { //- rjf: tag -> slot index - U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size; + U64 slot_idx = tag.u64[1] % fnt_state->font_hash_table_size; //- rjf: slot * tag -> existing node FNT_FontHashNode *existing_node = 0; { - for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) + for(FNT_FontHashNode *n = fnt_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next) { if(MemoryMatchStruct(&tag, &n->tag)) { @@ -514,7 +514,7 @@ fnt_piece_array_copy(Arena *arena, FNT_PieceArray *src) } //////////////////////////////// -//~ rjf: Rasterization Cache +//~ rjf: Cache Usage internal FNT_Hash2StyleRasterCacheNode * fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) @@ -530,15 +530,15 @@ fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) *(U64 *)(&size_f64), (U64)flags, }; - style_hash = fnt_little_hash_from_string(str8((U8 *)buffer, sizeof(buffer))); + style_hash = fnt_little_hash_from_string(5381, str8((U8 *)buffer, sizeof(buffer))); } //- rjf: style hash -> style node FNT_Hash2StyleRasterCacheNode *hash2style_node = 0; { ProfBegin("style hash -> style node"); - U64 slot_idx = style_hash%f_state->hash2style_slots_count; - FNT_Hash2StyleRasterCacheSlot *slot = &f_state->hash2style_slots[slot_idx]; + U64 slot_idx = style_hash%fnt_state->hash2style_slots_count; + FNT_Hash2StyleRasterCacheSlot *slot = &fnt_state->hash2style_slots[slot_idx]; for(FNT_Hash2StyleRasterCacheNode *n = slot->first; n != 0; n = n->hash_next) @@ -552,14 +552,14 @@ fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) if(Unlikely(hash2style_node == 0)) { FNT_Metrics metrics = fnt_metrics_from_tag_size(tag, size); - hash2style_node = push_array(f_state->raster_arena, FNT_Hash2StyleRasterCacheNode, 1); + hash2style_node = push_array(fnt_state->raster_arena, FNT_Hash2StyleRasterCacheNode, 1); DLLPushBack_NP(slot->first, slot->last, hash2style_node, hash_next, hash_prev); hash2style_node->style_hash = style_hash; hash2style_node->ascent = metrics.ascent; hash2style_node->descent = metrics.descent; - hash2style_node->utf8_class1_direct_map = push_array_no_zero(f_state->raster_arena, F_RasterCacheInfo, 256); + hash2style_node->utf8_class1_direct_map = push_array_no_zero(fnt_state->raster_arena, FNT_RasterCacheInfo, 256); hash2style_node->hash2info_slots_count = 1024; - hash2style_node->hash2info_slots = push_array(f_state->raster_arena, FNT_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count); + hash2style_node->hash2info_slots = push_array(fnt_state->raster_arena, FNT_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count); } ProfEnd(); } @@ -575,274 +575,321 @@ fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, //- rjf: map tag/size to style node FNT_Hash2StyleRasterCacheNode *hash2style_node = fnt_hash2style_from_tag_size_flags(tag, size, flags); - //- rjf: decode string & produce run pieces - FNT_PieceChunkList piece_chunks = {0}; - Vec2F32 dim = {0}; - B32 font_handle_mapped_on_miss = 0; - FP_Handle font_handle = {0}; - U64 piece_substring_start_idx = 0; - U64 piece_substring_end_idx = 0; - for(U64 idx = 0; idx <= string.size;) + //- rjf: set up this style's run cache if needed + if(hash2style_node->run_slots_frame_index != fnt_state->frame_index) { - //- rjf: decode next codepoint & get piece substring, or continuation rule - U8 byte = (idx < string.size ? string.str[idx] : 0); - B32 need_another_codepoint = 0; - if(byte == 0) + hash2style_node->run_slots_count = 1024; + hash2style_node->run_slots = push_array(fnt_state->frame_arena, FNT_RunCacheSlot, hash2style_node->run_slots_count); + hash2style_node->run_slots_frame_index = fnt_state->frame_index; + } + + //- rjf: unpack run params + U64 run_hash = fnt_little_hash_from_string(5381, string); + U64 run_slot_idx = run_hash%hash2style_node->run_slots_count; + FNT_RunCacheSlot *run_slot = &hash2style_node->run_slots[run_slot_idx]; + + //- rjf: find existing run node for this string + FNT_RunCacheNode *run_node = 0; + { + for(FNT_RunCacheNode *n = run_slot->first; n != 0; n = n->next) { - idx += 1; - } - else switch(utf8_class[byte>>3]) - { - case 1: + if(str8_match(n->string, string, 0)) { - idx += 1; - piece_substring_end_idx += 1; - need_another_codepoint = 0; - }break; - default: - { - UnicodeDecode decode = utf8_decode(string.str+idx, string.size-idx); - idx += decode.inc; - piece_substring_end_idx += decode.inc; - need_another_codepoint = 0; - }break; - } - - //- rjf: need another codepoint, or have no substring? -> continue - if(need_another_codepoint || piece_substring_end_idx == piece_substring_start_idx) - { - continue; - } - - //- rjf: do not need another codepoint? -> grab substring, bump piece start idx - String8 piece_substring = str8_substr(string, r1u64(piece_substring_start_idx, piece_substring_end_idx)); - piece_substring_start_idx = idx; - piece_substring_end_idx = idx; - - //- rjf: determine if this piece is a tab - if so, use space info to draw - B32 is_tab = (piece_substring.size == 1 && piece_substring.str[0] == '\t'); - if(is_tab) - { - piece_substring = str8_lit(" "); - } - - //- rjf: piece substring -> raster cache info - F_RasterCacheInfo *info = 0; - U64 piece_hash = 0; - { - // rjf: fast path for utf8 class 1 -> direct map - if(piece_substring.size == 1 && hash2style_node->utf8_class1_direct_map_mask[piece_substring.str[0]/64] & (1ull<<(piece_substring.str[0]%64))) - { - info = &hash2style_node->utf8_class1_direct_map[piece_substring.str[0]]; - } - - // rjf: more general, slower path for other glyphs - if(piece_substring.size > 1) - { - piece_hash = fnt_little_hash_from_string(piece_substring); - U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count; - FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx]; - for(F_Hash2InfoRasterCacheNode *node = slot->first; node != 0; node = node->hash_next) - { - if(node->hash == piece_hash) - { - info = &node->info; - break; - } - } - } - } - - //- rjf: no info found -> miss... fill this hash in the cache - if(info == 0) - { - ProfBegin("no info found -> miss... fill this hash in the cache"); - Temp scratch = scratch_begin(&arena, 1); - - // rjf: grab font handle for this tag if we don't have one already - if(font_handle_mapped_on_miss == 0) - { - font_handle_mapped_on_miss = 1; - - // rjf: tag -> font slot index - U64 font_slot_idx = tag.u64[1] % f_state->font_hash_table_size; - - // rjf: tag * slot -> existing node - FNT_FontHashNode *existing_node = 0; - { - for(FNT_FontHashNode *n = f_state->font_hash_table[font_slot_idx].first; n != 0 ; n = n->hash_next) - { - if(MemoryMatchStruct(&n->tag, &tag)) - { - existing_node = n; - break; - } - } - } - - // rjf: existing node -> font handle - if(existing_node != 0) - { - font_handle = existing_node->handle; - } - } - - // rjf: call into font provider to rasterize this substring - FP_RasterResult raster = {0}; - if(size > 0) - { - FP_RasterFlags fp_flags = 0; - if(flags & FNT_RasterFlag_Smooth) { fp_flags |= FP_RasterFlag_Smooth; } - if(flags & FNT_RasterFlag_Hinted) { fp_flags |= FP_RasterFlag_Hinted; } - raster = fp_raster(scratch.arena, font_handle, floor_f32(size), flags, piece_substring); - } - - // rjf: allocate portion of an atlas to upload the rasterization - S16 chosen_atlas_num = 0; - FNT_Atlas *chosen_atlas = 0; - Rng2S16 chosen_atlas_region = {0}; - if(raster.atlas_dim.x != 0 && raster.atlas_dim.y != 0) - { - U64 num_atlases = 0; - for(FNT_Atlas *atlas = f_state->first_atlas;; atlas = atlas->next, num_atlases += 1) - { - // rjf: create atlas if needed - if(atlas == 0 && num_atlases < 64) - { - atlas = push_array(f_state->raster_arena, FNT_Atlas, 1); - DLLPushBack(f_state->first_atlas, f_state->last_atlas, atlas); - atlas->root_dim = v2s16(1024, 1024); - atlas->root = push_array(f_state->raster_arena, FNT_AtlasRegionNode, 1); - atlas->root->max_free_size[Corner_00] = - atlas->root->max_free_size[Corner_01] = - atlas->root->max_free_size[Corner_10] = - atlas->root->max_free_size[Corner_11] = v2s16(atlas->root_dim.x/2, atlas->root_dim.y/2); - atlas->texture = r_tex2d_alloc(R_ResourceKind_Dynamic, v2s32((S32)atlas->root_dim.x, (S32)atlas->root_dim.y), R_Tex2DFormat_RGBA8, 0); - } - - // rjf: allocate from atlas - if(atlas != 0) - { - Vec2S16 needed_dimensions = v2s16(raster.atlas_dim.x + 2, raster.atlas_dim.y + 2); - chosen_atlas_region = fnt_atlas_region_alloc(f_state->raster_arena, atlas, needed_dimensions); - if(chosen_atlas_region.x1 != chosen_atlas_region.x0) - { - chosen_atlas = atlas; - chosen_atlas_num = (S32)num_atlases; - break; - } - } - else - { - break; - } - } - } - - // rjf: upload rasterization to allocated region of atlas texture memory - if(chosen_atlas != 0) - { - Rng2S32 subregion = - { - chosen_atlas_region.x0, - chosen_atlas_region.y0, - chosen_atlas_region.x0 + raster.atlas_dim.x, - chosen_atlas_region.y0 + raster.atlas_dim.y - }; - r_fill_tex2d_region(chosen_atlas->texture, subregion, raster.atlas); - } - - // rjf: allocate & fill & push node - { - if(piece_substring.size == 1) - { - info = &hash2style_node->utf8_class1_direct_map[piece_substring.str[0]]; - hash2style_node->utf8_class1_direct_map_mask[piece_substring.str[0]/64] |= (1ull<<(piece_substring.str[0]%64)); - } - else - { - U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count; - FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx]; - F_Hash2InfoRasterCacheNode *node = push_array_no_zero(f_state->raster_arena, F_Hash2InfoRasterCacheNode, 1); - DLLPushBack_NP(slot->first, slot->last, node, hash_next, hash_prev); - node->hash = piece_hash; - info = &node->info; - } - if(info != 0) - { - info->subrect = chosen_atlas_region; - info->atlas_num = chosen_atlas_num; - info->raster_dim = raster.atlas_dim; - info->advance = raster.advance; - } - } - - scratch_end(scratch); - ProfEnd(); - } - - //- rjf: push piece for this raster portion - if(info != 0) - { - // rjf: find atlas - FNT_Atlas *atlas = 0; - { - if(info->subrect.x1 != 0 && info->subrect.y1 != 0) - { - S32 num = 0; - for(FNT_Atlas *a = f_state->first_atlas; a != 0; a = a->next, num += 1) - { - if(info->atlas_num == num) - { - atlas = a; - break; - } - } - } - } - - // rjf: on tabs -> expand advance - F32 advance = info->advance; - if(is_tab) - { - advance = floor_f32(tab_size_px) - mod_f32(floor_f32(base_align_px), floor_f32(tab_size_px)); - } - - // rjf: push piece - { - FNT_Piece *piece = fnt_piece_chunk_list_push_new(arena, &piece_chunks, string.size); - { - piece->texture = atlas ? atlas->texture : r_handle_zero(); - piece->subrect = r2s16p(info->subrect.x0, - info->subrect.y0, - info->subrect.x0 + info->raster_dim.x, - info->subrect.y0 + info->raster_dim.y); - piece->advance = advance; - piece->decode_size = piece_substring.size; - piece->offset = v2s16(0, -(hash2style_node->ascent + hash2style_node->descent)); - } - base_align_px += advance; - dim.x += piece->advance; - dim.y = Max(dim.y, info->raster_dim.y); + run_node = n; + break; } } } - //- rjf: tighten & return + //- rjf: no run node? -> cache miss - compute & build & fill node if possible + B32 run_is_cacheable = 1; FNT_Run run = {0}; + if(run_node) { - if(piece_chunks.node_count == 1) + run = run_node->run; + } + else + ProfScope("no run node? -> cache miss") + ProfScope("compute & build & fill node for '%.*s'", str8_varg(string)) + { + //- rjf: decode string & produce run pieces + FNT_PieceChunkList piece_chunks = {0}; + Vec2F32 dim = {0}; + B32 font_handle_mapped_on_miss = 0; + FP_Handle font_handle = {0}; + U64 piece_substring_start_idx = 0; + U64 piece_substring_end_idx = 0; + for(U64 idx = 0; idx <= string.size;) { - run.pieces.v = piece_chunks.first->v; - run.pieces.count = piece_chunks.first->count; + //- rjf: decode next codepoint & get piece substring, or continuation rule + U8 byte = (idx < string.size ? string.str[idx] : 0); + B32 need_another_codepoint = 0; + if(byte == 0) + { + idx += 1; + } + else switch(utf8_class[byte>>3]) + { + case 1: + { + idx += 1; + piece_substring_end_idx += 1; + need_another_codepoint = 0; + }break; + default: + { + UnicodeDecode decode = utf8_decode(string.str+idx, string.size-idx); + idx += decode.inc; + piece_substring_end_idx += decode.inc; + need_another_codepoint = 0; + }break; + } + + //- rjf: need another codepoint, or have no substring? -> continue + if(need_another_codepoint || piece_substring_end_idx == piece_substring_start_idx) + { + continue; + } + + //- rjf: do not need another codepoint? -> grab substring, bump piece start idx + String8 piece_substring = str8_substr(string, r1u64(piece_substring_start_idx, piece_substring_end_idx)); + piece_substring_start_idx = idx; + piece_substring_end_idx = idx; + + //- rjf: determine if this piece is a tab - if so, use space info to draw + B32 is_tab = (piece_substring.size == 1 && piece_substring.str[0] == '\t'); + if(is_tab) + { + run_is_cacheable = 0; + piece_substring = str8_lit(" "); + } + + //- rjf: piece substring -> raster cache info + FNT_RasterCacheInfo *info = 0; + U64 piece_hash = 0; + { + // rjf: fast path for utf8 class 1 -> direct map + if(piece_substring.size == 1 && hash2style_node->utf8_class1_direct_map_mask[piece_substring.str[0]/64] & (1ull<<(piece_substring.str[0]%64))) + { + info = &hash2style_node->utf8_class1_direct_map[piece_substring.str[0]]; + } + + // rjf: more general, slower path for other glyphs + if(piece_substring.size > 1) + { + piece_hash = fnt_little_hash_from_string(5381, piece_substring); + U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count; + FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx]; + for(FNT_Hash2InfoRasterCacheNode *node = slot->first; node != 0; node = node->hash_next) + { + if(node->hash == piece_hash) + { + info = &node->info; + break; + } + } + } + } + + //- rjf: no info found -> miss... fill this hash in the cache + if(info == 0) + { + ProfBegin("no info found -> miss... fill this hash in the cache"); + Temp scratch = scratch_begin(&arena, 1); + + // rjf: grab font handle for this tag if we don't have one already + if(font_handle_mapped_on_miss == 0) + { + font_handle_mapped_on_miss = 1; + + // rjf: tag -> font slot index + U64 font_slot_idx = tag.u64[1] % fnt_state->font_hash_table_size; + + // rjf: tag * slot -> existing node + FNT_FontHashNode *existing_node = 0; + { + for(FNT_FontHashNode *n = fnt_state->font_hash_table[font_slot_idx].first; n != 0 ; n = n->hash_next) + { + if(MemoryMatchStruct(&n->tag, &tag)) + { + existing_node = n; + break; + } + } + } + + // rjf: existing node -> font handle + if(existing_node != 0) + { + font_handle = existing_node->handle; + } + } + + // rjf: call into font provider to rasterize this substring + FP_RasterResult raster = {0}; + if(size > 0) + { + FP_RasterFlags fp_flags = 0; + if(flags & FNT_RasterFlag_Smooth) { fp_flags |= FP_RasterFlag_Smooth; } + if(flags & FNT_RasterFlag_Hinted) { fp_flags |= FP_RasterFlag_Hinted; } + raster = fp_raster(scratch.arena, font_handle, floor_f32(size), flags, piece_substring); + } + + // rjf: allocate portion of an atlas to upload the rasterization + S16 chosen_atlas_num = 0; + FNT_Atlas *chosen_atlas = 0; + Rng2S16 chosen_atlas_region = {0}; + if(raster.atlas_dim.x != 0 && raster.atlas_dim.y != 0) + { + U64 num_atlases = 0; + for(FNT_Atlas *atlas = fnt_state->first_atlas;; atlas = atlas->next, num_atlases += 1) + { + // rjf: create atlas if needed + if(atlas == 0 && num_atlases < 64) + { + atlas = push_array(fnt_state->raster_arena, FNT_Atlas, 1); + DLLPushBack(fnt_state->first_atlas, fnt_state->last_atlas, atlas); + atlas->root_dim = v2s16(1024, 1024); + atlas->root = push_array(fnt_state->raster_arena, FNT_AtlasRegionNode, 1); + atlas->root->max_free_size[Corner_00] = + atlas->root->max_free_size[Corner_01] = + atlas->root->max_free_size[Corner_10] = + atlas->root->max_free_size[Corner_11] = v2s16(atlas->root_dim.x/2, atlas->root_dim.y/2); + atlas->texture = r_tex2d_alloc(R_ResourceKind_Dynamic, v2s32((S32)atlas->root_dim.x, (S32)atlas->root_dim.y), R_Tex2DFormat_RGBA8, 0); + } + + // rjf: allocate from atlas + if(atlas != 0) + { + Vec2S16 needed_dimensions = v2s16(raster.atlas_dim.x + 2, raster.atlas_dim.y + 2); + chosen_atlas_region = fnt_atlas_region_alloc(fnt_state->raster_arena, atlas, needed_dimensions); + if(chosen_atlas_region.x1 != chosen_atlas_region.x0) + { + chosen_atlas = atlas; + chosen_atlas_num = (S32)num_atlases; + break; + } + } + else + { + break; + } + } + } + + // rjf: upload rasterization to allocated region of atlas texture memory + if(chosen_atlas != 0) + { + Rng2S32 subregion = + { + chosen_atlas_region.x0, + chosen_atlas_region.y0, + chosen_atlas_region.x0 + raster.atlas_dim.x, + chosen_atlas_region.y0 + raster.atlas_dim.y + }; + r_fill_tex2d_region(chosen_atlas->texture, subregion, raster.atlas); + } + + // rjf: allocate & fill & push node + { + if(piece_substring.size == 1) + { + info = &hash2style_node->utf8_class1_direct_map[piece_substring.str[0]]; + hash2style_node->utf8_class1_direct_map_mask[piece_substring.str[0]/64] |= (1ull<<(piece_substring.str[0]%64)); + } + else + { + U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count; + FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx]; + FNT_Hash2InfoRasterCacheNode *node = push_array_no_zero(fnt_state->raster_arena, FNT_Hash2InfoRasterCacheNode, 1); + DLLPushBack_NP(slot->first, slot->last, node, hash_next, hash_prev); + node->hash = piece_hash; + info = &node->info; + } + if(info != 0) + { + info->subrect = chosen_atlas_region; + info->atlas_num = chosen_atlas_num; + info->raster_dim = raster.atlas_dim; + info->advance = raster.advance; + } + } + + scratch_end(scratch); + ProfEnd(); + } + + //- rjf: push piece for this raster portion + if(info != 0) + { + // rjf: find atlas + FNT_Atlas *atlas = 0; + { + if(info->subrect.x1 != 0 && info->subrect.y1 != 0) + { + S32 num = 0; + for(FNT_Atlas *a = fnt_state->first_atlas; a != 0; a = a->next, num += 1) + { + if(info->atlas_num == num) + { + atlas = a; + break; + } + } + } + } + + // rjf: on tabs -> expand advance + F32 advance = info->advance; + if(is_tab) + { + advance = floor_f32(tab_size_px) - mod_f32(floor_f32(base_align_px), floor_f32(tab_size_px)); + } + + // rjf: push piece + { + FNT_Piece *piece = fnt_piece_chunk_list_push_new(fnt_state->frame_arena, &piece_chunks, string.size); + { + piece->texture = atlas ? atlas->texture : r_handle_zero(); + piece->subrect = r2s16p(info->subrect.x0, + info->subrect.y0, + info->subrect.x0 + info->raster_dim.x, + info->subrect.y0 + info->raster_dim.y); + piece->advance = advance; + piece->decode_size = piece_substring.size; + piece->offset = v2s16(0, -(hash2style_node->ascent + hash2style_node->descent)); + } + base_align_px += advance; + dim.x += piece->advance; + dim.y = Max(dim.y, info->raster_dim.y); + } + } } - else + + //- rjf: tighten & fill { - run.pieces = fnt_piece_array_from_chunk_list(arena, &piece_chunks); + if(piece_chunks.node_count == 1) + { + run.pieces.v = piece_chunks.first->v; + run.pieces.count = piece_chunks.first->count; + } + else + { + run.pieces = fnt_piece_array_from_chunk_list(fnt_state->frame_arena, &piece_chunks); + } + run.dim = dim; + run.ascent = hash2style_node->ascent; + run.descent = hash2style_node->descent; } - run.dim = dim; - run.ascent = hash2style_node->ascent; - run.descent = hash2style_node->descent; + } + + //- rjf: build node for cacheable runs + if(run_is_cacheable) + { + run_node = push_array(fnt_state->frame_arena, FNT_RunCacheNode, 1); + SLLQueuePush(run_slot->first, run_slot->last, run_node); + run_node->string = push_str8_copy(fnt_state->frame_arena, string); + run_node->run = run; } ProfEnd(); @@ -1057,23 +1104,31 @@ internal void fnt_init(void) { Arena *arena = arena_alloc(); - f_state = push_array(arena, FNT_State, 1); - f_state->permanent_arena = arena; - f_state->raster_arena = arena_alloc(); - f_state->font_hash_table_size = 64; - f_state->font_hash_table = push_array(f_state->permanent_arena, FNT_FontHashSlot, f_state->font_hash_table_size); + fnt_state = push_array(arena, FNT_State, 1); + fnt_state->permanent_arena = arena; + fnt_state->raster_arena = arena_alloc(); + fnt_state->frame_arena = arena_alloc(); + fnt_state->font_hash_table_size = 64; + fnt_state->font_hash_table = push_array(fnt_state->permanent_arena, FNT_FontHashSlot, fnt_state->font_hash_table_size); fnt_reset(); } internal void fnt_reset(void) { - for(FNT_Atlas *a = f_state->first_atlas; a != 0; a = a->next) + for(FNT_Atlas *a = fnt_state->first_atlas; a != 0; a = a->next) { r_tex2d_release(a->texture); } - f_state->first_atlas = f_state->last_atlas = 0; - arena_clear(f_state->raster_arena); - f_state->hash2style_slots_count = 1024; - f_state->hash2style_slots = push_array(f_state->raster_arena, FNT_Hash2StyleRasterCacheSlot, f_state->hash2style_slots_count); + fnt_state->first_atlas = fnt_state->last_atlas = 0; + arena_clear(fnt_state->raster_arena); + fnt_state->hash2style_slots_count = 1024; + fnt_state->hash2style_slots = push_array(fnt_state->raster_arena, FNT_Hash2StyleRasterCacheSlot, fnt_state->hash2style_slots_count); +} + +internal void +fnt_frame(void) +{ + fnt_state->frame_index += 1; + arena_clear(fnt_state->frame_arena); } diff --git a/src/font_cache/font_cache.h b/src/font_cache/font_cache.h index 9f343eca..d1ac1661 100644 --- a/src/font_cache/font_cache.h +++ b/src/font_cache/font_cache.h @@ -93,8 +93,10 @@ struct FNT_FontHashSlot //////////////////////////////// //~ rjf: Rasterization Cache Types -typedef struct F_RasterCacheInfo F_RasterCacheInfo; -struct F_RasterCacheInfo +//- rjf: base glyph rasterization / dimensions cache + +typedef struct FNT_RasterCacheInfo FNT_RasterCacheInfo; +struct FNT_RasterCacheInfo { Rng2S16 subrect; Vec2S16 raster_dim; @@ -102,22 +104,41 @@ struct F_RasterCacheInfo F32 advance; }; -typedef struct F_Hash2InfoRasterCacheNode F_Hash2InfoRasterCacheNode; -struct F_Hash2InfoRasterCacheNode +typedef struct FNT_Hash2InfoRasterCacheNode FNT_Hash2InfoRasterCacheNode; +struct FNT_Hash2InfoRasterCacheNode { - F_Hash2InfoRasterCacheNode *hash_next; - F_Hash2InfoRasterCacheNode *hash_prev; + FNT_Hash2InfoRasterCacheNode *hash_next; + FNT_Hash2InfoRasterCacheNode *hash_prev; U64 hash; - F_RasterCacheInfo info; + FNT_RasterCacheInfo info; }; typedef struct FNT_Hash2InfoRasterCacheSlot FNT_Hash2InfoRasterCacheSlot; struct FNT_Hash2InfoRasterCacheSlot { - F_Hash2InfoRasterCacheNode *first; - F_Hash2InfoRasterCacheNode *last; + FNT_Hash2InfoRasterCacheNode *first; + FNT_Hash2InfoRasterCacheNode *last; }; +//- rjf: run cache (arrangements of many glyphs to represent a full string) + +typedef struct FNT_RunCacheNode FNT_RunCacheNode; +struct FNT_RunCacheNode +{ + FNT_RunCacheNode *next; + String8 string; + FNT_Run run; +}; + +typedef struct FNT_RunCacheSlot FNT_RunCacheSlot; +struct FNT_RunCacheSlot +{ + FNT_RunCacheNode *first; + FNT_RunCacheNode *last; +}; + +//- rjf: style hash -> artifacts/metrics cache + typedef struct FNT_Hash2StyleRasterCacheNode FNT_Hash2StyleRasterCacheNode; struct FNT_Hash2StyleRasterCacheNode { @@ -127,10 +148,13 @@ struct FNT_Hash2StyleRasterCacheNode F32 ascent; F32 descent; F32 column_width; - F_RasterCacheInfo *utf8_class1_direct_map; + FNT_RasterCacheInfo *utf8_class1_direct_map; U64 utf8_class1_direct_map_mask[4]; U64 hash2info_slots_count; FNT_Hash2InfoRasterCacheSlot *hash2info_slots; + U64 run_slots_count; + FNT_RunCacheSlot *run_slots; + U64 run_slots_frame_index; }; typedef struct FNT_Hash2StyleRasterCacheSlot FNT_Hash2StyleRasterCacheSlot; @@ -189,6 +213,8 @@ struct FNT_State { Arena *permanent_arena; Arena *raster_arena; + Arena *frame_arena; + U64 frame_index; // rjf: font table U64 font_hash_table_size; @@ -206,13 +232,13 @@ struct FNT_State //////////////////////////////// //~ rjf: Globals -global FNT_State *f_state = 0; +global FNT_State *fnt_state = 0; //////////////////////////////// //~ rjf: Basic Functions internal U128 fnt_hash_from_string(String8 string); -internal U64 fnt_little_hash_from_string(String8 string); +internal U64 fnt_little_hash_from_string(U64 seed, String8 string); internal Vec2S32 fnt_vertex_from_corner(Corner corner); //////////////////////////////// @@ -241,10 +267,13 @@ internal FNT_PieceArray fnt_piece_array_from_chunk_list(Arena *arena, FNT_PieceC internal FNT_PieceArray fnt_piece_array_copy(Arena *arena, FNT_PieceArray *src); //////////////////////////////// -//~ rjf: Rasterization Cache +//~ rjf: Cache Usage +//- rjf: base cache lookups internal FNT_Hash2StyleRasterCacheNode *fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags); internal FNT_Run fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string); + +//- rjf: helpers internal String8List fnt_wrapped_string_lines_from_font_size_string_max(Arena *arena, FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max); internal Vec2F32 fnt_dim_from_tag_size_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string); internal Vec2F32 fnt_dim_from_tag_size_string_list(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list); @@ -262,5 +291,6 @@ internal F32 fnt_line_height_from_metrics(FNT_Metrics *metrics); internal void fnt_init(void); internal void fnt_reset(void); +internal void fnt_frame(void); #endif // FONT_CACHE_H From 0ed951e5378df9ff67d58f8409122f837f3cf137 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 09:46:58 -0700 Subject: [PATCH 455/755] simplify font cache run building api, since it is now cahced --- src/draw/draw.c | 4 ++-- src/font_cache/font_cache.c | 10 ++++---- src/font_cache/font_cache.h | 2 +- src/raddbg/raddbg_core.c | 47 +++++++++++++++++-------------------- src/raddbg/raddbg_widgets.c | 4 ++-- 5 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index 39c12fa4..4dc20b5c 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -171,7 +171,7 @@ dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) for(DR_FStrNode *n = strs->first; n != 0; n = n->next) { DR_FRunNode *dst_n = push_array(arena, DR_FRunNode, 1); - dst_n->v.run = fnt_push_run_from_string(arena, n->v.params.font, n->v.params.size, base_align_px, tab_size_px, n->v.params.raster_flags, n->v.string); + dst_n->v.run = fnt_run_from_string(n->v.params.font, n->v.params.size, base_align_px, tab_size_px, n->v.params.raster_flags, n->v.string); dst_n->v.color = n->v.params.color; dst_n->v.underline_thickness = n->v.params.underline_thickness; dst_n->v.strikethrough_thickness = n->v.params.strikethrough_thickness; @@ -712,7 +712,7 @@ internal void dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string) { Temp scratch = scratch_begin(0, 0); - FNT_Run run = fnt_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, flags, string); + FNT_Run run = fnt_run_from_string(font, size, base_align_px, tab_size_px, flags, string); dr_text_run(p, color, run); scratch_end(scratch); } diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index 4070aa3c..9754f352 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -568,7 +568,7 @@ fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags) } internal FNT_Run -fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string) +fnt_run_from_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string) { ProfBeginFunction(); @@ -695,7 +695,7 @@ fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, if(info == 0) { ProfBegin("no info found -> miss... fill this hash in the cache"); - Temp scratch = scratch_begin(&arena, 1); + Temp scratch = scratch_begin(0, 0); // rjf: grab font handle for this tag if we don't have one already if(font_handle_mapped_on_miss == 0) @@ -902,7 +902,7 @@ fnt_wrapped_string_lines_from_font_size_string_max(Arena *arena, FNT_Tag font, F String8List list = {0}; { Temp scratch = scratch_begin(&arena, 1); - FNT_Run run = fnt_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); + FNT_Run run = fnt_run_from_string(font, size, base_align_px, tab_size_px, 0, string); F32 off_px = 0; U64 off_bytes = 0; U64 line_start_off_bytes = 0; @@ -1015,7 +1015,7 @@ fnt_dim_from_tag_size_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_s ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); Vec2F32 result = {0}; - FNT_Run run = fnt_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string); + FNT_Run run = fnt_run_from_string(tag, size, base_align_px, tab_size_px, 0, string); result = run.dim; scratch_end(scratch); ProfEnd(); @@ -1052,7 +1052,7 @@ fnt_char_pos_from_tag_size_string_p(FNT_Tag tag, F32 size, F32 base_align_px, F3 F32 best_offset_px = inf32(); U64 offset_bytes = 0; F32 offset_px = 0.f; - FNT_Run run = fnt_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string); + FNT_Run run = fnt_run_from_string(tag, size, base_align_px, tab_size_px, 0, string); for(U64 idx = 0; idx <= run.pieces.count; idx += 1) { F32 this_piece_offset_px = abs_f32(offset_px - p); diff --git a/src/font_cache/font_cache.h b/src/font_cache/font_cache.h index d1ac1661..4bc6b0b7 100644 --- a/src/font_cache/font_cache.h +++ b/src/font_cache/font_cache.h @@ -271,7 +271,7 @@ internal FNT_PieceArray fnt_piece_array_copy(Arena *arena, FNT_PieceArray *src); //- rjf: base cache lookups internal FNT_Hash2StyleRasterCacheNode *fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags); -internal FNT_Run fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string); +internal FNT_Run fnt_run_from_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string); //- rjf: helpers internal String8List fnt_wrapped_string_lines_from_font_size_string_max(Arena *arena, FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index dc3c87b6..35718c3f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5532,36 +5532,31 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); RD_FontSlot slot = english_font_slots[idx]; String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - font_size, - 0, 0, 0, - sample_text); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(slot), - font_size, - 0, 0, 0, - sample_text); + fnt_run_from_string(rd_font_from_slot(slot), + font_size, + 0, 0, 0, + sample_text); + fnt_run_from_string(rd_font_from_slot(slot), + font_size, + 0, 0, 0, + sample_text); scratch_end(scratch); } for(RD_IconKind icon_kind = RD_IconKind_Null; icon_kind < RD_IconKind_COUNT; icon_kind = (RD_IconKind)(icon_kind+1)) { Temp scratch = scratch_begin(0, 0); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - font_size, - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - font_size, - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); - fnt_push_run_from_string(scratch.arena, - rd_font_from_slot(icon_font_slot), - font_size, - 0, 0, FNT_RasterFlag_Smooth, - rd_icon_kind_text_table[icon_kind]); + fnt_run_from_string(rd_font_from_slot(icon_font_slot), + font_size, + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_run_from_string(rd_font_from_slot(icon_font_slot), + font_size, + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); + fnt_run_from_string(rd_font_from_slot(icon_font_slot), + font_size, + 0, 0, FNT_RasterFlag_Smooth, + rd_icon_kind_text_table[icon_kind]); scratch_end(scratch); } } @@ -8947,7 +8942,7 @@ rd_window_frame(void) ellipses_raster_flags = box->display_fstrs.last->v.params.raster_flags; } max_x = (box->rect.x1-text_position.x); - ellipses_run = fnt_push_run_from_string(scratch.arena, ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); + ellipses_run = fnt_run_from_string(ellipses_font, ellipses_size, 0, box->tab_size, ellipses_raster_flags, str8_lit("...")); } if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) UI_TagF("match") { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 46fb322b..fe5eb327 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1164,7 +1164,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) { Temp scratch = scratch_begin(0, 0); Vec4F32 color = ui_color_from_name(str8_lit("text")); - FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.8f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("if")); + FNT_Run run = fnt_run_from_string(rd_font_from_slot(RD_FontSlot_Code), box->font_size*0.8f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("if")); Vec2F32 p = center_2f32(box->rect); p.x -= run.dim.x*0.5f; p.y += run.descent; @@ -1177,7 +1177,7 @@ internal UI_BOX_CUSTOM_DRAW(rd_bp_box_draw_extensions) { Temp scratch = scratch_begin(0, 0); Vec4F32 color = ui_color_from_name(str8_lit("breakpoint")); - FNT_Run run = fnt_push_run_from_string(scratch.arena, rd_font_from_slot(RD_FontSlot_Icons), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("x")); + FNT_Run run = fnt_run_from_string(rd_font_from_slot(RD_FontSlot_Icons), box->font_size*0.95f, 0, 0, FNT_RasterFlag_Smooth, str8_lit("x")); Vec2F32 box_dim = dim_2f32(box->rect); Vec2F32 p = center_2f32(box->rect); p.x += box_dim.x*0.1f; From 33362d91a07e2ef7230e35c47c4375ff6207c6a0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 10:04:42 -0700 Subject: [PATCH 456/755] add dedicated open tab command as a fast path for all tab commands, simplify/streamline new tab menu --- src/raddbg/generated/raddbg.meta.c | 12 +++-- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 7 ++- src/raddbg/raddbg_core.c | 80 ++++++++++++------------------ 4 files changed, 43 insertions(+), 59 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2c9c378e..6359005b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[315] = +RD_VocabInfo rd_vocab_info_table[316] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -236,7 +236,8 @@ RD_VocabInfo rd_vocab_info_table[315] = {str8_lit_comp("prev_tab"), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), str8_lit_comp(""), RD_IconKind_LeftArrow}, {str8_lit_comp("move_tab_right"), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("move_tab_left"), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), str8_lit_comp(""), RD_IconKind_LeftArrow}, -{str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open New Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("build_tab"), str8_lit_comp(""), str8_lit_comp("Build Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("duplicate_tab"), str8_lit_comp(""), str8_lit_comp("Duplicate Tab"), str8_lit_comp(""), RD_IconKind_Duplicate}, {str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, {str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, @@ -442,7 +443,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[211] = +RD_CmdKindInfo rd_cmd_kind_info_table[212] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -522,7 +523,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[211] = { str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:tab_commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, +{ str8_lit_comp("build_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -698,6 +700,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = {str8_lit_comp("close_tab"), {OS_Key_W, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("open_tab"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("open"), {OS_Key_O, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("switch"), {OS_Key_I, 0 |OS_Modifier_Ctrl }}, @@ -761,7 +764,6 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = {str8_lit_comp("toggle_watch_expr_at_mouse"), {OS_Key_D, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("toggle_watch_pin"), {OS_Key_F9, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, -{str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, {str8_lit_comp("open_palette"), {OS_Key_F1, 0 }}, {str8_lit_comp("open_palette"), {OS_Key_P, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 736aec89..046029f5 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -134,6 +134,7 @@ RD_CmdKind_PrevTab, RD_CmdKind_MoveTabRight, RD_CmdKind_MoveTabLeft, RD_CmdKind_OpenTab, +RD_CmdKind_BuildTab, RD_CmdKind_DuplicateTab, RD_CmdKind_CloseTab, RD_CmdKind_MoveTab, @@ -667,7 +668,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[315]; +extern RD_VocabInfo rd_vocab_info_table[316]; extern RD_NameSchemaInfo rd_name_schema_info_table[21]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 0477a1a2..fd92ac2f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -683,7 +683,8 @@ RD_CmdTable: // | | | | {PrevTab 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "prev_tab" "Focus Previous Tab" "Focuses the previous tab on the active panel." "" "" } {MoveTabRight 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "move_tab_right" "Move Tab Right" "Moves the selected tab right one slot." "" "$tab," } {MoveTabLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } - {OpenTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "open_tab" "Open Tab" "Opens a new tab with the parameterized view specification." "" "" } + {OpenTab 1 1 0 0 "query:tab_commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "open_tab" "Open New Tab" "Opens a new tab." "" "" } + {BuildTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "build_tab" "Build Tab" "Opens a new tab with the parameterized view specification." "" "" } {DuplicateTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } {CloseTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } {MoveTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } @@ -956,6 +957,7 @@ RD_DefaultBindingTable: { "close_tab" W ctrl 0 0 } { "tab_bar_top" Up ctrl shift alt } { "tab_bar_bottom" Down ctrl shift alt } + { "open_tab" T ctrl 0 0 } //- rjf: files { "open" O ctrl 0 0 } @@ -1038,9 +1040,6 @@ RD_DefaultBindingTable: //- rjf: breakpoints { "toggle_breakpoint" F9 0 0 0 } - //- rjf: targets - { "add_target" T ctrl 0 0 } - //- rjf: attaching { "attach" F6 0 shift 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 35718c3f..8569645d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3100,6 +3100,11 @@ rd_view_ui(Rng2F32 rect) U64 pid = eval.value.u128.u64[0]; rd_cmd(RD_CmdKind_CompleteQuery, .pid = pid); }break; + case RD_EvalSpaceKind_MetaCmd: + { + String8 cmd_name = rd_cmd_name_from_eval(eval); + rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = cmd_name); + }break; } // rjf: if we do not have a specific command, then we can just @@ -6820,9 +6825,6 @@ rd_window_frame(void) rd_cmd_kind_info_table[RD_CmdKind_RotatePanelColumns].string, rd_cmd_kind_info_table[RD_CmdKind_NextPanel].string, rd_cmd_kind_info_table[RD_CmdKind_PrevPanel].string, - rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, - rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, - rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, rd_cmd_kind_info_table[RD_CmdKind_TabBarTop].string, rd_cmd_kind_info_table[RD_CmdKind_TabBarBottom].string, rd_cmd_kind_info_table[RD_CmdKind_ResetToDefaultPanels].string, @@ -6839,9 +6841,6 @@ rd_window_frame(void) 'c', 'n', 'p', - 't', - 'b', - 'v', 0, 0, 0, @@ -6858,48 +6857,25 @@ rd_window_frame(void) { String8 cmds[] = { - rd_cmd_kind_info_table[RD_CmdKind_OpenTargets].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenMachines].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenProcesses].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenThreads].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenCallStack].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenOutput].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenMemory].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenDisasm].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenWatch].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenLocals].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenRegisters].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenGlobals].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenThreadLocals].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenTypes].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenProcedures].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenBreakpoints].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenWatchPins].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenFilePathMaps].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenAutoViewRules].string, - // rd_cmd_kind_info_table[RD_CmdKind_GettingStarted].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenTab].string, + rd_cmd_kind_info_table[RD_CmdKind_CloseTab].string, + rd_cmd_kind_info_table[RD_CmdKind_DuplicateTab].string, + rd_cmd_kind_info_table[RD_CmdKind_MoveTabLeft].string, + rd_cmd_kind_info_table[RD_CmdKind_MoveTabRight].string, + rd_cmd_kind_info_table[RD_CmdKind_NextTab].string, + rd_cmd_kind_info_table[RD_CmdKind_PrevTab].string, + rd_cmd_kind_info_table[RD_CmdKind_TabSettings].string, }; U32 codepoints[] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 'o', + 'c', + 'd', + 'l', + 'r', + 'n', + 'p', + 's', }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); rd_cmd_list_menu_buttons(ArrayCount(cmds), cmds, codepoints); @@ -12557,7 +12533,7 @@ rd_frame(void) U64 fast_path_idx = (kind - RD_CmdKind_FirstTabFastPathCmd); String8 view_name = rd_tab_fast_path_view_name_table[fast_path_idx]; String8 query_name = rd_tab_fast_path_query_name_table[fast_path_idx]; - rd_cmd(RD_CmdKind_OpenTab, .string = view_name, .expr = query_name); + rd_cmd(RD_CmdKind_BuildTab, .string = view_name, .expr = query_name); } }break; @@ -12589,8 +12565,9 @@ rd_frame(void) rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1, .view = tab->id); }break; - //- rjf: command fast path + //- rjf: command fast paths case RD_CmdKind_RunCommand: + case RD_CmdKind_OpenTab: { RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(cmd->regs->cmd_name); @@ -13609,7 +13586,7 @@ rd_frame(void) .view = tab->id, .prev_tab = new_prev->id); }break; - case RD_CmdKind_OpenTab: + case RD_CmdKind_BuildTab: { String8 expr_file_path = rd_file_path_from_eval_string(scratch.arena, rd_regs()->expr); RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); @@ -13699,6 +13676,11 @@ rd_frame(void) RD_Cfg *panel = rd_cfg_from_id(rd_regs()->panel); rd_cfg_child_from_string_or_alloc(panel, str8_lit("tabs_on_bottom")); }break; + case RD_CmdKind_TabSettings: + { + String8 expr = push_str8f(scratch.arena, "query:$%I64x", rd_regs()->view); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); + }break; //- rjf: files case RD_CmdKind_Open: @@ -13708,7 +13690,7 @@ rd_frame(void) if(props.created != 0) { rd_cmd(RD_CmdKind_RecordFileInProject); - rd_cmd(RD_CmdKind_OpenTab, .string = str8_lit("pending"), .expr = rd_eval_string_from_file_path(scratch.arena, path)); + rd_cmd(RD_CmdKind_BuildTab, .string = str8_lit("pending"), .expr = rd_eval_string_from_file_path(scratch.arena, path)); } else { From 970f40e516bb91a591d938df20278581d7295359 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 25 Apr 2025 11:08:46 -0700 Subject: [PATCH 457/755] notes --- src/raddbg/raddbg_main.c | 75 ++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index dca81f18..6e7df8fa 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -164,8 +164,6 @@ // // [ ] CLI argument over-mangling? // [ ] fix light themes -// [ ] make `array` view rule work with actual array types, to change their -// size dynamically // [ ] disasm starting address - need to use debug info for more correct // results... // [ ] linked list view rule @@ -187,13 +185,9 @@ //////////////////////////////// //~ rjf: Frontend/UI Pass Tasks // -// [ ] theme lister -> fonts & font sizes // [ ] "Browse..." buttons should adopt a more relevant starting search path, // if possible // -// [ ] font lister -// [ ] per-panel font size overrides -// // [ ] For the Scheduler window, it would be nice if you could dim or // folderize threads that are not your threads - eg., if a thread doesn't // have any resolved stack pointers in your executable code, then you can @@ -215,7 +209,6 @@ // jettison a collection of keys in retained mode fashion // // [ ] Jeff Notes -// [ ] sort locals by appearance in source code (or maybe just debug info) // [ ] sum view rule // [ ] plot view rule // [ ] histogram view rule @@ -295,55 +288,36 @@ // // [ ] eval wide/async transforms (e.g. diff(blob1, blob2)) // [ ] search-in-all-files -// [ ] Memory View +// [ ] memory view // [ ] memory view mutation controls // [ ] memory view user-made annotations // [ ] globally disable/configure default view rule-like things (string // viz for u8s in particular) -// [ ] @feature processor/data breakpoints // [ ] @feature automatically snap to search matches when searching source files -// [ ] automatically start search query with selected text //////////////////////////////// //~ rjf: Cold, Clean-up Tasks That Probably Only Ryan Notices // (E.G. Because They Are Code-Related Or Because Nobody Cares) // -// [ ] @bug view-snapping in scroll-lists, accounting for mapping between -// visual positions & logical positions (variably sized rows in watch, -// table headers, etc.) -// [ ] @cleanup straighten out index/number space & types & terminology for -// scroll lists // [ ] @cleanup eliminate explicit font parameters in the various ui paths (e.g. // code slice params) //////////////////////////////// //~ rjf: Cold, Unsorted Notes (Deferred Until Existing Lists Mostly Exhausted) // -// [ ] @feature disasm view improvement features -// [ ] visualize jump destinations in disasm +// [ ] @feature visualize jump destinations in disasm +// [ ] @feature serializing eval view maps (?) +// [ ] @feature multidimensional `array` +// [ ] @feature 2-vector, 3-vector, quaternion +// [ ] @feature audio waveform views +// [ ] @feature smart scopes - expression operators for "grab me the first type X" +// [ ] @feature "pinning" watch expressions, to attach it to a particular scope/evaluation +// context // -// [ ] @feature eval ui improvement features -// [ ] serializing eval view maps -// [ ] view rule hook coverage -// [ ] `array:(x, y)` - multidimensional array -// [ ] `each:(expr addition)` - apply some additional expression to all -// elements in an array/linked list would be useful to look at only a -// subset of an array of complex structs -// [ ] `slider:(min max)` view rule -// [ ] `v2f32` view rule -// [ ] `v3` view rule -// [ ] `quat` view rule -// [ ] `matrix` view rule -// [ ] `audio` waveform view rule -// [ ] smart scopes - expression operators for "grab me the first type X" -// [ ] "pinning" watch expressions, to attach it to a particular ctrl_ctx -// -// [ ] @feature header file for target -> debugger communication; printf, log, -// etc. // [ ] @feature just-in-time debugging // [ ] @feature step-out-of-loop // -//-[ ] long-term future notes from martins +// [ ] long-term future notes from martins // [ ] core dump saving/loading // [ ] parallel call stacks view // [ ] parallel watch view @@ -357,12 +331,6 @@ // others. would be good for e.g. the middle of a path // [ ] font cache eviction (both for font tags, closing fp handles, and // rasterizations) -// [ ] frontend speedup opportunities -// [ ] font cache layer -> can probably cache (string*font*size) -> (run) too -// (not just rasterization)... would save a *lot*, there is a ton of work -// just in looking up & stitching stuff repeatedly -// [ ] convert UI layout pass to not be naive recursive version -// [ ] (big change) parallelize window ui build codepaths per-panel //////////////////////////////// //~ rjf: Recently Completed Task Log @@ -425,6 +393,29 @@ // [x] single-line visualization busted with auto-view-rules applied, it seems... // not showing member variables, just commas, check w/ mohit // [x] r8 bitmap view rule seems incorrect? +// [x] font cache layer -> can probably cache (string*font*size) -> (run) too +// (not just rasterization)... would save a *lot*, there is a ton of work +// just in looking up & stitching stuff repeatedly +// [x] convert UI layout pass to not be naive recursive version +// [x] @feature header file for target -> debugger communication; printf, log, +// etc. +// [x] `slider:(min max)` view rule +// [x] `matrix` view rule +// [x] `each:(expr addition)` - apply some additional expression to all +// elements in an array/linked list would be useful to look at only a +// subset of an array of complex structs +// [x] @bug view-snapping in scroll-lists, accounting for mapping between +// visual positions & logical positions (variably sized rows in watch, +// table headers, etc.) +// [x] @cleanup straighten out index/number space & types & terminology for +// scroll lists +// [x] sort locals by appearance in source code (or maybe just debug info) +// [x] per-panel font size overrides +// [x] theme lister -> fonts & font sizes +// [x] make `array` view rule work with actual array types, to change their +// size dynamically +// [x] automatically start search query with selected text +// [x] @feature processor/data breakpoints //////////////////////////////// //~ rjf: Build Options From 09f248de590a44b09bbaaa1ca9879d1bfbae235a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 10:02:56 -0700 Subject: [PATCH 458/755] cfg evaluation improvements, tab expression editing, window size serialization fix, other small fixes --- src/eval/eval_ir.c | 2 +- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 4 + src/raddbg/raddbg_core.c | 152 ++++++++++++++++++----------- src/raddbg/raddbg_eval.c | 35 +++++-- src/raddbg/raddbg_eval.h | 17 ++-- src/raddbg/raddbg_views.c | 2 +- src/raddbg/raddbg_widgets.c | 4 +- 8 files changed, 146 insertions(+), 74 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index d56fc852..f8cabbfe 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -365,7 +365,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); E_TypeKey check_type_key = l_restype; E_TypeKind check_type_kind = l_restype_kind; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 6359005b..ead90914 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -378,8 +378,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index fd92ac2f..ce97c431 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -315,6 +315,8 @@ RD_VocabTable: { @default(3.f) @display_name('Tab Row Height') @description("Controls the tab's row height, in multiples of the font size.") 'row_height': @range[1.75f, 5.f] f32, + @description("The root expression which is evaluated to produce the watch window.") + 'expression': code_string, } ``` } @@ -329,6 +331,8 @@ RD_VocabTable: 'show_line_numbers':bool, @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, + @description("An expression to describe data which should be viewed as text or code.") + 'expression': code_string, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8569645d..2821b1e7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5573,6 +5573,7 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); B32 is_fullscreen = os_window_is_fullscreen(ws->os); B32 is_maximized = os_window_is_maximized(ws->os); + B32 is_minimized = os_window_is_minimized(ws->os); if(is_fullscreen) { rd_cfg_child_from_string_or_alloc(window, str8_lit("fullscreen")); @@ -5592,7 +5593,7 @@ rd_window_frame(void) //- rjf: commit position Rng2F32 window_rect = os_rect_from_window(ws->os); - if(!is_fullscreen && !is_maximized) + if(!is_fullscreen && !is_maximized && !is_minimized) { Vec2F32 pos = window_rect.p0; RD_Cfg *pos_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("pos")); @@ -5617,7 +5618,7 @@ rd_window_frame(void) } //- rjf: commit size - if(!is_fullscreen && !is_maximized) + if(!is_fullscreen && !is_maximized && !is_minimized) { Vec2F32 size = dim_2f32(window_rect); RD_Cfg *size_root = rd_cfg_child_from_string_or_alloc(window, str8_lit("size")); @@ -5642,6 +5643,7 @@ rd_window_frame(void) } //- rjf: commit monitor + if(!is_minimized) { OS_Handle monitor = os_monitor_from_window(ws->os); String8 monitor_name = os_name_from_monitor(scratch.arena, monitor); @@ -8448,7 +8450,7 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_PushQuery, .ui_key = sig.box->key, - .expr = push_str8f(scratch.arena, "$%I64x", tab->id)); + .expr = push_str8f(scratch.arena, "query:config.$%I64x", tab->id)); } else if(ui_middle_clicked(sig)) { @@ -8543,11 +8545,20 @@ rd_window_frame(void) if(ui_pressed(sig)) { rd_cmd(RD_CmdKind_FocusPanel, .panel = panel->cfg->id); - rd_cmd(RD_CmdKind_PushQuery, .expr = str8_lit("query:tab_commands"), - .panel = panel->cfg->id, - .do_implicit_root = 1, - .do_lister = 1, - .ui_key = add_new_box->key); + if(ws->query_is_active && + ui_key_match(add_new_box->key, ws->query_regs->ui_key)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + else + { + rd_cmd(RD_CmdKind_PushQuery, + .expr = str8_lit("query:tab_commands"), + .panel = panel->cfg->id, + .do_implicit_root = 1, + .do_lister = 1, + .ui_key = add_new_box->key); + } } } } @@ -11880,7 +11891,20 @@ rd_frame(void) e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); } - //- rjf: add macros for evallable top-level config trees + //- rjf: add macro for top-level config root + { + String8 name = str8_lit("config"); + E_TypeKey type_key = e_type_key_cons(.name = name, + .kind = E_TypeKind_Set, + .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs)); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); + } + + //- rjf: add macros for config "slice" collections (targets, breakpoints, etc.) String8 evallable_cfg_names[] = { str8_lit("breakpoint"), @@ -11891,29 +11915,68 @@ rd_frame(void) str8_lit("recent_project"), str8_lit("recent_file"), }; - for EachElement(idx, evallable_cfg_names) + for EachElement(cfg_name_idx, evallable_cfg_names) { - String8 name = evallable_cfg_names[idx]; - E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); - RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); - for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + String8 cfg_name = evallable_cfg_names[cfg_name_idx]; + String8 collection_name = rd_plural_from_code_name(cfg_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs_slice), + .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs_slice), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs_slice), + .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs_slice), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs_slice), + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); + } + + //- rjf: add macros for evallable top-level individual config entity trees - + // things with names either explicitly attached, or that we can infer + for EachElement(idx, rd_name_schema_info_table) + { + String8 name = rd_name_schema_info_table[idx].name; + MD_NodePtrList schemas = rd_schemas_from_name(name); + B32 is_individually_evallable = 0; + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { - RD_Cfg *cfg = n->v; - String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; - String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; - E_Space space = rd_eval_space_from_cfg(cfg); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", cfg->id), expr); - if(exe.size != 0) + if(md_node_has_child(n->v, str8_lit("label"), 0) || + md_node_has_child(n->v, str8_lit("executable"), 0)) { - e_string2expr_map_insert(scratch.arena, macro_map, str8_skip_last_slash(exe), expr); + is_individually_evallable = 1; + break; } - if(label.size != 0) + } + if(is_individually_evallable) + { + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + RD_CfgList cfgs = rd_cfg_top_level_list_from_string(scratch.arena, name); + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { - e_string2expr_map_insert(scratch.arena, macro_map, label, expr); + RD_Cfg *cfg = n->v; + String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; + String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; + if(exe.size != 0 || label.size != 0) + { + E_Space space = rd_eval_space_from_cfg(cfg); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = type_key; + if(exe.size != 0) + { + e_string2expr_map_insert(scratch.arena, macro_map, str8_skip_last_slash(exe), expr); + } + if(label.size != 0) + { + e_string2expr_map_insert(scratch.arena, macro_map, label, expr); + } + } } } } @@ -11983,28 +12046,6 @@ rd_frame(void) } } - //- rjf: add macros for all config collections - for EachElement(cfg_name_idx, evallable_cfg_names) - { - String8 cfg_name = evallable_cfg_names[cfg_name_idx]; - String8 collection_name = rd_plural_from_code_name(cfg_name); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, - .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs), - .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs), - .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs), - }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = collection_type_key; - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); - } - //- rjf: add macros for windows/tabs { RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); @@ -12018,7 +12059,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", window->id), expr); + e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "query:config.$%I64x", window->id), expr); } RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); for(RD_PanelNode *p = panel_tree.root; @@ -12034,7 +12075,7 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "$%I64x", tab->id), expr); + e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "query:config.$%I64x", tab->id), expr); } } } @@ -12545,8 +12586,8 @@ rd_frame(void) RD_Cfg *tab = panel_tree.focused->selected_tab; String8 expr = push_str8f(scratch.arena, "query:commands, " - "query:$%I64x, " - "query:$%I64x, " + "query:config.$%I64x, " + "query:config.$%I64x, " "query:targets, " "query:breakpoints, " "query:recent_files, " @@ -12646,7 +12687,7 @@ rd_frame(void) }break; case RD_CmdKind_WindowSettings: { - String8 expr = push_str8f(scratch.arena, "query:$%I64x", rd_regs()->window); + String8 expr = push_str8f(scratch.arena, "query:config.$%I64x", rd_regs()->window); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); }break; case RD_CmdKind_CloseWindow: @@ -13678,7 +13719,7 @@ rd_frame(void) }break; case RD_CmdKind_TabSettings: { - String8 expr = push_str8f(scratch.arena, "query:$%I64x", rd_regs()->view); + String8 expr = push_str8f(scratch.arena, "query:config.$%I64x", rd_regs()->view); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); }break; @@ -15129,6 +15170,7 @@ rd_frame(void) rd_cfg_newf(wdir, "%S/", working_directory); } rd_cmd(RD_CmdKind_SelectTarget, .cfg = target->id); + rd_cmd(RD_CmdKind_PushQuery, .expr = push_str8f(scratch.arena, "query:config.$%I64x", target->id)); }break; //- rjf: jit-debugger registration diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 98343f95..78327684 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -613,6 +613,27 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) } } +//////////////////////////////// +//~ rjf: Config Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(cfgs) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + E_Expr *rhs = expr->first->next; + if(rhs->kind == E_ExprKind_LeafIdentifier && + str8_match(str8_prefix(rhs->string, 1), str8_lit("$"), 0)) + { + String8 numeric_part = str8_skip(rhs->string, 1); + RD_CfgID id = u64_from_str8(numeric_part, 16); + RD_Cfg *cfg = rd_cfg_from_id(id); + E_Space space = rd_eval_space_from_cfg(cfg); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); + result.mode = E_Mode_Offset; + } + return result; +} + //////////////////////////////// //~ rjf: Config Collection Type Hooks @@ -626,7 +647,7 @@ struct RD_CfgsIRExt Rng1U64 cfgs_idx_range; }; -E_TYPE_IREXT_FUNCTION_DEF(cfgs) +E_TYPE_IREXT_FUNCTION_DEF(cfgs_slice) { RD_CfgsIRExt *ext = push_array(arena, RD_CfgsIRExt, 1); { @@ -666,7 +687,7 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs) return result; } -E_TYPE_ACCESS_FUNCTION_DEF(cfgs) +E_TYPE_ACCESS_FUNCTION_DEF(cfgs_slice) { E_IRTreeAndType result = {&e_irnode_nil}; RD_Cfg *cfg = &rd_nil_cfg; @@ -712,7 +733,7 @@ struct RD_CfgsExpandAccel Rng1U64 cfgs_idx_range; }; -E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_slice) { RD_CfgsExpandAccel *accel = push_array(arena, RD_CfgsExpandAccel, 1); E_TypeExpandInfo info = {accel}; @@ -754,7 +775,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs) return info; } -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs_slice) { RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; Rng1U64 cmds_idx_range = accel->cmds_idx_range; @@ -781,12 +802,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { RD_Cfg *cfg = accel->cfgs.v[idx + read_range.min - cfgs_idx_range.min]; - evals_out[dst_idx] = e_eval_from_stringf("$%I64x", cfg->id); + evals_out[dst_idx] = e_eval_from_stringf("query:config.$%I64x", cfg->id); } } } -E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs_slice) { U64 id = 0; RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; @@ -807,7 +828,7 @@ E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs) return id; } -E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs) +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs_slice) { U64 num = 0; RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 2c01a48e..91295bea 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -40,14 +40,19 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); //////////////////////////////// -//~ rjf: Config Collection Type Hooks +//~ rjf: Config Type Hooks -E_TYPE_IREXT_FUNCTION_DEF(cfgs); E_TYPE_ACCESS_FUNCTION_DEF(cfgs); -E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs); -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs); -E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs); -E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs); + +//////////////////////////////// +//~ rjf: Config Slice Type Hooks + +E_TYPE_IREXT_FUNCTION_DEF(cfgs_slice); +E_TYPE_ACCESS_FUNCTION_DEF(cfgs_slice); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_slice); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs_slice); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs_slice); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs_slice); //////////////////////////////// //~ rjf: `call_stack` Type Hooks diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 92e44178..d16f4b58 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1060,7 +1060,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: fill row's group cfg // - if(info.group_cfg_name.size != 0 && (block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs) || + if(info.group_cfg_name.size != 0 && (block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice) || block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) || block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment))) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index fe5eb327..a8184f78 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1644,7 +1644,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = bp_box->key, - .expr = push_str8f(scratch.arena, "$%I64x", bp->id)); + .expr = push_str8f(scratch.arena, "query:config.$%I64x", bp->id)); } // rjf: shift+click => enable breakpoint @@ -1701,7 +1701,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = pin_box->key, - .expr = push_str8f(scratch.arena, "$%I64x", pin->id)); + .expr = push_str8f(scratch.arena, "query:config.$%I64x", pin->id)); } // rjf: click => remove pin From 5103252a1ba7ef1ef51942de4cfe96acc92f4aee Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 10:27:21 -0700 Subject: [PATCH 459/755] eliminate watches as a top-level entity, nest watch expressions under tabs - allow many watch windows, each with their own set of expressions. --- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/generated/raddbg.meta.h | 34 ++--- src/raddbg/raddbg.mdesk | 42 +++--- src/raddbg/raddbg_core.c | 35 ++--- src/raddbg/raddbg_eval.c | 216 +++++++++++++++-------------- src/raddbg/raddbg_eval.h | 18 +-- 6 files changed, 184 insertions(+), 165 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index ead90914..672c4b0a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -30,7 +30,7 @@ str8_lit_comp("memory"), String8 rd_tab_fast_path_query_name_table[20] = { -str8_lit_comp("query:watches"), +str8_lit_comp(""), str8_lit_comp("query:locals"), str8_lit_comp("query:registers"), str8_lit_comp("query:globals"), @@ -378,7 +378,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 046029f5..3bf7d01c 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -600,23 +600,23 @@ RD_Query query; }; #define RD_FixedTabXList \ -X(watches)\ -X(locals)\ -X(registers)\ -X(globals)\ -X(thread_locals)\ -X(types)\ -X(procedures)\ -X(call_stack)\ -X(targets)\ -X(breakpoints)\ -X(watch_pins)\ -X(threads)\ -X(processes)\ -X(machines)\ -X(modules)\ -X(file_path_maps)\ -X(auto_view_rules)\ +Y(watches, watch, "")\ +X(locals) \ +X(registers) \ +X(globals) \ +X(thread_locals) \ +X(types) \ +X(procedures) \ +X(call_stack) \ +X(targets) \ +X(breakpoints) \ +X(watch_pins) \ +X(threads) \ +X(processes) \ +X(machines) \ +X(modules) \ +X(file_path_maps) \ +X(auto_view_rules) \ Y(output, text, "query:output")\ Y(disasm, disasm, "")\ Y(memory, memory, "")\ diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index ce97c431..c129ec95 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -14,26 +14,26 @@ //////////////////////////////// //~ rjf: Fixed Tab Tables -@table(name display_name name_lower icon) +@table(name display_name name_lower is_query icon) RD_WatchTabFastPathTable: { - {Watch "Watch" watches Binoculars } - {Locals "Locals" locals Binoculars } - {Registers "Registers" registers Binoculars } - {Globals "Globals" globals Binoculars } - {ThreadLocals "Thread Locals" thread_locals Binoculars } - {Types "Types" types Binoculars } - {Procedures "Procedures" procedures Binoculars } - {CallStack "Call Stack" call_stack Thread } - {Targets "Targets" targets Target } - {Breakpoints "Breakpoints" breakpoints CircleFilled } - {WatchPins "Watch Pins" watch_pins Pin } - {Threads "Threads" threads Threads } - {Processes "Processes" processes Scheduler } - {Machines "Machines" machines Machine } - {Modules "Modules" modules Module } - {FilePathMaps "File Path Map" file_path_maps FileOutline } - {AutoViewRules "Auto View Rules" auto_view_rules Binoculars } + {Watch "Watch" watches 0 Binoculars } + {Locals "Locals" locals 1 Binoculars } + {Registers "Registers" registers 1 Binoculars } + {Globals "Globals" globals 1 Binoculars } + {ThreadLocals "Thread Locals" thread_locals 1 Binoculars } + {Types "Types" types 1 Binoculars } + {Procedures "Procedures" procedures 1 Binoculars } + {CallStack "Call Stack" call_stack 1 Thread } + {Targets "Targets" targets 1 Target } + {Breakpoints "Breakpoints" breakpoints 1 CircleFilled } + {WatchPins "Watch Pins" watch_pins 1 Pin } + {Threads "Threads" threads 1 Threads } + {Processes "Processes" processes 1 Scheduler } + {Machines "Machines" machines 1 Machine } + {Modules "Modules" modules 1 Module } + {FilePathMaps "File Path Map" file_path_maps 1 FileOutline } + {AutoViewRules "Auto View Rules" auto_view_rules 1 Binoculars } } @table(name display_name name_lower view query icon) @@ -53,7 +53,7 @@ RD_FixedTabTable: @gen { `#define RD_FixedTabXList \\`; - @expand(RD_WatchTabFastPathTable a) `X($(a.name_lower))\\`; + @expand(RD_WatchTabFastPathTable a) `$(a.is_query -> 'X(' .. a.name_lower .. ')') $(a.is_query == 0 -> 'Y(' .. a.name_lower .. ', watch, ""' .. ')')\\`; @expand(RD_ViewTabFastPathTable a) `Y($(a.name_lower), $(a.view), "$(a.query)")\\`; @expand(RD_FixedTabTable a) `Z($(a.name_lower))\\`; ``; @@ -67,7 +67,7 @@ RD_FixedTabTable: @data(String8) rd_tab_fast_path_query_name_table: { - @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("query:$(a.name_lower)")`, + @expand(RD_WatchTabFastPathTable a) `str8_lit_comp("$(a.is_query -> 'query:' .. a.name_lower)")`, @expand(RD_ViewTabFastPathTable a) `str8_lit_comp("$(a.query)")`, } @@ -315,8 +315,10 @@ RD_VocabTable: { @default(3.f) @display_name('Tab Row Height') @description("Controls the tab's row height, in multiples of the font size.") 'row_height': @range[1.75f, 5.f] f32, + 'label': code_string, @description("The root expression which is evaluated to produce the watch window.") 'expression': code_string, + @no_expand 'watches': query, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2821b1e7..908c0dff 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2721,6 +2721,10 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_Font(RD_FontSlot_Code) { + if(expr_string.size == 0) + { + expr_string = push_str8f(scratch.arena, "query:config.$%I64x.watches", rd_regs()->view); + } E_Eval eval = e_eval_from_string(expr_string); RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); @@ -3412,7 +3416,7 @@ rd_view_ui(Rng2F32 rect) if(cell->flags & RD_WatchCellFlag_Expr && cell->flags & RD_WatchCellFlag_NoEval) { RD_Cfg *cfg = row_info.group_cfg_child; - String8 child_key = str8_lit("expression"); + String8 child_key = {0}; // str8_lit("expression"); if(cfg == &rd_nil_cfg && editing_complete && new_string.size != 0) { RD_Cfg *new_cfg_parent = row_info.group_cfg_parent; @@ -11981,22 +11985,6 @@ rd_frame(void) } } - //- rjf: add macro for watches group - { - String8 collection_name = str8_lit("watches"); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_EditableChildren, - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(watches), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(watches), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), - }); - e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); - } - //- rjf: add macros for all watches which define identifiers RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); for(RD_CfgNode *n = watches.first; n != 0; n = n->next) @@ -12205,6 +12193,19 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(environment), })); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("watches"), + e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_EditableChildren, + .name = str8_lit("watches"), + .irext = E_TYPE_IREXT_FUNCTION_NAME(watches), + .access = E_TYPE_ACCESS_FUNCTION_NAME(watches), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(watches), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(watches), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(watches), + })); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 78327684..9c57e91c 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -84,107 +84,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) } } -//////////////////////////////// -//~ rjf: `watches` Type Hooks - -E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) -{ - E_TypeExpandInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - RD_CfgList cfgs_list = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - RD_CfgList cfgs_list__filtered = cfgs_list; - if(filter.size != 0) - { - MemoryZeroStruct(&cfgs_list__filtered); - for(RD_CfgNode *n = cfgs_list.first; n != 0; n = n->next) - { - String8 expr = rd_expr_from_cfg(n->v); - B32 passes_filter = 1; - if(filter.size != 0) - { - E_Eval eval = e_eval_from_string(expr); - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind != E_TypeKind_Set) - { - passes_filter = 0; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr); - if(matches.count == matches.needle_part_count) - { - passes_filter = 1; - } - } - } - if(passes_filter) - { - rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, n->v); - } - } - } - RD_CfgArray *cfgs = push_array(arena, RD_CfgArray, 1); - cfgs[0] = rd_cfg_array_from_list(arena, &cfgs_list__filtered); - result.user_data = cfgs; - result.expr_count = cfgs->count + 1; - } - scratch_end(scratch); - return result; -} - -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) -{ - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); - Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); - U64 read_range_count = dim_1u64(read_range); - for(U64 idx = 0; idx < read_range_count; idx += 1) - { - U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) - { - String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - evals_out[idx] = e_eval_from_string(expr_string); - } - } -} - -E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches) -{ - U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) - { - U64 idx = (num-1); - id = cfgs->v[idx]->id; - } - else if(num == cfgs->count+1) - { - id = max_U64; - } - return id; -} - -E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) -{ - U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(id != 0 && id != max_U64) - { - for EachIndex(idx, cfgs->count) - { - if(cfgs->v[idx]->id == id) - { - num = idx+1; - break; - } - } - } - else if(id == max_U64) - { - num = cfgs->count + 1; - } - return num; -} - //////////////////////////////// //~ rjf: `locals` Type Hooks @@ -1028,6 +927,121 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment) return num; } +//////////////////////////////// +//~ rjf: `watches` Type Hooks + +typedef struct RD_WatchesAccel RD_WatchesAccel; +struct RD_WatchesAccel +{ + RD_CfgArray cfgs; +}; + +E_TYPE_IREXT_FUNCTION_DEF(watches) +{ + RD_WatchesAccel *accel = push_array(arena, RD_WatchesAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + E_Space space = interpret.space; + RD_Cfg *target = rd_cfg_from_eval_space(space); + RD_CfgList env_strings = {0}; + for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("watch"), 0)) + { + rd_cfg_list_push(scratch.arena, &env_strings, child); + } + } + accel->cfgs = rd_cfg_array_from_list(arena, &env_strings); + scratch_end(scratch); + } + E_IRExt result = {accel}; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(watches) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex) + { + RD_WatchesAccel *accel = (RD_WatchesAccel *)lhs_irtree->user_data; + RD_CfgArray *cfgs = &accel->cfgs; + E_Value rhs_value = e_value_from_expr(expr->first->next); + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), cfg->first->string.size, E_TypeFlag_IsCodeText); + result.mode = E_Mode_Offset; + } + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) +{ + RD_WatchesAccel *accel = (RD_WatchesAccel *)eval.irtree.user_data; + E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) +{ + RD_WatchesAccel *accel = (RD_WatchesAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->cfgs.count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 cfg_idx = read_range.min + idx; + if(cfg_idx < accel->cfgs.count) + { + RD_Cfg *cfg = accel->cfgs.v[cfg_idx]; + evals_out[idx] = e_eval_from_string(cfg->first->string); + } + } +} + +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches) +{ + U64 id = 0; + RD_WatchesAccel *accel = (RD_WatchesAccel *)user_data; + if(1 <= num && num <= accel->cfgs.count) + { + U64 idx = (num-1); + id = accel->cfgs.v[idx]->id; + } + else if(num == accel->cfgs.count+1) + { + id = max_U64; + } + return id; +} + +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches) +{ + U64 num = 0; + RD_WatchesAccel *accel = (RD_WatchesAccel *)user_data; + if(id != 0 && id != max_U64) + { + for EachIndex(idx, accel->cfgs.count) + { + if(accel->cfgs.v[idx]->id == id) + { + num = idx+1; + break; + } + } + } + else if(id == max_U64) + { + num = accel->cfgs.count + 1; + } + return num; +} + //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 91295bea..41715697 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -11,14 +11,6 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands); E_TYPE_ACCESS_FUNCTION_DEF(commands); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands); -//////////////////////////////// -//~ rjf: `watches` Type Hooks - -E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches); -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches); -E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); -E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); - //////////////////////////////// //~ rjf: `locals` Type Hooks @@ -71,6 +63,16 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(environment); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment); +//////////////////////////////// +//~ rjf: `watches` Type Hooks + +E_TYPE_IREXT_FUNCTION_DEF(watches); +E_TYPE_ACCESS_FUNCTION_DEF(watches); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(watches); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); + //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks From 19784ba4765a897663ae01f8ef6aa4d868dd1e54 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 10:48:49 -0700 Subject: [PATCH 460/755] improve labeled view titles, convert old watch-expression-gathering paths to using the per-watch-tab watches structure --- src/raddbg/raddbg_core.c | 178 +++++++++++++++++++++++------------- src/raddbg/raddbg_widgets.c | 8 +- 2 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 908c0dff..fd3b556a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11985,56 +11985,8 @@ rd_frame(void) } } - //- rjf: add macros for all watches which define identifiers - RD_CfgList watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - for(RD_CfgNode *n = watches.first; n != 0; n = n->next) - { - RD_Cfg *watch = n->v; - String8 expr = rd_expr_from_cfg(watch); - E_Parse parse = e_parse_from_string(expr); - if(parse.msgs.max_kind == E_MsgKind_Null) - { - for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) - { - typedef struct ExprWalkTask ExprWalkTask; - struct ExprWalkTask - { - ExprWalkTask *next; - E_Expr *expr; - }; - ExprWalkTask start_task = {0, expr}; - ExprWalkTask *first_task = &start_task; - ExprWalkTask *last_task = first_task; - for(ExprWalkTask *t = first_task; t != 0; t = t->next) - { - switch(t->expr->kind) - { - case E_ExprKind_Call:{}break; - case E_ExprKind_Define: - { - E_Expr *lhs = t->expr->first; - E_Expr *rhs = lhs->next; - if(lhs->kind == E_ExprKind_LeafIdentifier) - { - e_string2expr_map_insert(scratch.arena, macro_map, lhs->string, rhs); - } - }break; - default: - { - for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) - { - ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); - SLLQueuePush(first_task, last_task, task); - task->expr = child; - } - }break; - } - } - } - } - } - //- rjf: add macros for windows/tabs + RD_CfgList watch_tabs = {0}; { RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); for(RD_CfgNode *n = windows.first; n != 0; n = n->next) @@ -12064,11 +12016,69 @@ rd_frame(void) expr->mode = E_Mode_Offset; expr->type_key = type_key; e_string2expr_map_insert(scratch.arena, macro_map, push_str8f(scratch.arena, "query:config.$%I64x", tab->id), expr); + if(str8_match(tab->string, str8_lit("watch"), 0)) + { + rd_cfg_list_push(scratch.arena, &watch_tabs, tab); + } } } } } + //- rjf: add macros for all watches in all watch tabs which define identifiers + for(RD_CfgNode *n = watch_tabs.first; n != 0; n = n->next) + { + RD_Cfg *watch_tab = n->v; + for(RD_Cfg *child = watch_tab->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("watch"), 0)) + { + RD_Cfg *watch = child; + String8 expr = watch->first->string; + E_Parse parse = e_parse_from_string(expr); + if(parse.msgs.max_kind == E_MsgKind_Null) + { + for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) + { + typedef struct ExprWalkTask ExprWalkTask; + struct ExprWalkTask + { + ExprWalkTask *next; + E_Expr *expr; + }; + ExprWalkTask start_task = {0, expr}; + ExprWalkTask *first_task = &start_task; + ExprWalkTask *last_task = first_task; + for(ExprWalkTask *t = first_task; t != 0; t = t->next) + { + switch(t->expr->kind) + { + case E_ExprKind_Call:{}break; + case E_ExprKind_Define: + { + E_Expr *lhs = t->expr->first; + E_Expr *rhs = lhs->next; + if(lhs->kind == E_ExprKind_LeafIdentifier) + { + e_string2expr_map_insert(scratch.arena, macro_map, lhs->string, rhs); + } + }break; + default: + { + for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->expr = child; + } + }break; + } + } + } + } + } + } + } //- rjf: add macros for user/project { @@ -15079,29 +15089,69 @@ rd_frame(void) case RD_CmdKind_ToggleWatchExpression: if(rd_regs()->string.size != 0) { - RD_CfgList all_existing_watches = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("watch")); - RD_Cfg *existing_watch = &rd_nil_cfg; - for(RD_CfgNode *n = all_existing_watches.first; n != 0; n = n->next) + // rjf: pick a watch tab from all the windows to toggle this expression within + RD_Cfg *watch_tab = &rd_nil_cfg; { - RD_Cfg *watch = n->v; - String8 expr = rd_expr_from_cfg(watch); - if(str8_match(expr, rd_regs()->string, 0)) + B32 watch_tab_has_no_label = 0; + B32 watch_tab_matches_src_window = 0; + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) { - existing_watch = watch; + RD_Cfg *window = n->v; + RD_PanelTree panels = rd_panel_tree_from_cfg(scratch.arena, window); + for(RD_PanelNode *panel = panels.root; + panel != &rd_nil_panel_node; + panel = rd_panel_node_rec__depth_first_pre(panels.root, panel).next) + { + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) + { + RD_Cfg *tab = tab_n->v; + RD_Cfg *label = rd_cfg_child_from_string(tab, str8_lit("label")); + if(str8_match(tab->string, str8_lit("watch"), 0) && + rd_expr_from_cfg(tab).size == 0) + { + B32 tab_has_no_label = (label->first->string.size == 0); + B32 tab_matches_src_window = (window->id == rd_regs()->window); + if(tab_has_no_label > watch_tab_has_no_label || + tab_matches_src_window > watch_tab_matches_src_window || + watch_tab == &rd_nil_cfg) + { + watch_tab = tab; + if(tab_has_no_label && tab_matches_src_window) + { + goto end_watch_tab_search; + } + } + } + } + } + } + end_watch_tab_search:; + } + + // rjf: find the existing watch in the selected tab, if it exists + RD_Cfg *existing_watch = &rd_nil_cfg; + for(RD_Cfg *child = watch_tab->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("watch"), 0) && str8_match(child->first->string, rd_regs()->string, 0)) + { + existing_watch = child; break; } } - if(existing_watch == &rd_nil_cfg) - { - RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - RD_Cfg *watch = rd_cfg_new(project, str8_lit("watch")); - RD_Cfg *expr = rd_cfg_new(watch, str8_lit("expression")); - rd_cfg_new(expr, rd_regs()->string); - } - else + + // rjf: if this watch exists -> delete it + if(existing_watch != &rd_nil_cfg) { rd_cfg_release(existing_watch); } + + // rjf: otherwise, create it + else if(watch_tab != &rd_nil_cfg) + { + RD_Cfg *watch = rd_cfg_new(watch_tab, str8_lit("watch")); + rd_cfg_new(watch, rd_regs()->string); + } }break; //- rjf: cursor operations diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index a8184f78..b2d3001b 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -65,10 +65,6 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) { query_code_name = rd_singular_from_code_name_plural(query_name); collection_name = rd_display_plural_from_code_name(query_code_name); - if(str8_match(collection_name, str8_lit("Watches"), 0)) - { - collection_name = str8_lit("Watch"); - } } RD_IconKind query_icon_kind = rd_icon_kind_from_code_name(query_code_name); if(query_icon_kind != RD_IconKind_Null) @@ -117,8 +113,8 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); } - //- rjf: push view title, if from window, and no file path - if(is_within_window && file_path.size == 0 && collection_name.size == 0) + //- rjf: push view title, if from window, and no file path, and no label + if(is_within_window && file_path.size == 0 && collection_name.size == 0 && label_string.size == 0) { String8 view_display_name = rd_display_from_code_name(cfg->string); if(view_display_name.size != 0) From 6749f30b6b1a6c17ba000a135e7044d28314fdda Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 10:57:11 -0700 Subject: [PATCH 461/755] release notes --- src/raddbg/raddbg_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 6e7df8fa..4783e43e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -53,6 +53,12 @@ // which can be edited within the palette or a tab's right-click menu. If a // tab has no per-tab font size set, then it inherits the setting from the // window's font size. +// - Expressions inserted into a `Watch` tab are now stored per-tab. This makes +// many `Watch` tabs more useful, since different tabs can have a different +// set of expressions. `Watch` tabs can now also be labeled, so you can +// visually distinguish many `Watch` tabs more easily. +// - All tabs now allow hand-editing of their root expression in their +// right-click menu. // - Debugger settings have been upgraded to be stored as expressions, rather // than being locked to a specific value. These expressions are evaluated, // like any other expression, and their evaluated value is used when the @@ -69,7 +75,7 @@ // visualize the evaluation value with a slider, which can be used to edit // the value as well. // - The hover evaluation feature has been majorly upgraded to support all -// features normally available in the `Watch` view. +// features normally available in `Watch` tabs. // - Added "transient tabs", which are colored differently than normal tabs. // These tabs are automatically opened by the debugger when snapping to // source code which is not already opened. They are automatically replaced From 05b52cfaca38a96efd97e139154e86e86bd0de15 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 11:04:54 -0700 Subject: [PATCH 462/755] add extra bit that views can use to disable query bar - use in the case of watch window (and thus lister) editing --- src/raddbg/raddbg_core.c | 7 ++++++- src/raddbg/raddbg_core.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fd3b556a..c1f5d5e8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2402,7 +2402,7 @@ rd_view_ui(Rng2F32 rect) } //- rjf: build contents - UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected ? UI_FocusKind_On : UI_FocusKind_Off) + UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected && !vs->contents_are_focused ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) { if(cmd_name.size != 0) @@ -4861,6 +4861,11 @@ rd_view_ui(Rng2F32 rect) rd_cmd(RD_CmdKind_FocusPanel); } + ////////////////////////////// + //- rjf: disable query if text editing is occurring + // + vs->contents_are_focused = ewv->text_editing; + rd_store_view_scroll_pos(scroll_pos); } scratch_end(scratch); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 960d2934..7034ef82 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -214,6 +214,9 @@ struct RD_ViewState TxtPt query_mark; U8 query_buffer[KB(1)]; U64 query_string_size; + + // rjf: contents are focused (disables query focus) + B32 contents_are_focused; }; typedef struct RD_ViewStateSlot RD_ViewStateSlot; From db4f390fd0b5c93cb91642438e21332dbe26a08c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 11:13:36 -0700 Subject: [PATCH 463/755] fix input-expression-evaluation fallback in query views, to not be listerified; automatically open breakpoint editor when adding an address breakpoint manually --- src/raddbg/raddbg_core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c1f5d5e8..3ec31521 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12637,7 +12637,7 @@ rd_frame(void) // rjf: command has required query -> prep query else { - rd_cmd(RD_CmdKind_PushQuery, .do_implicit_root = 1, .do_lister = 1); + rd_cmd(RD_CmdKind_PushQuery, .do_implicit_root = 1, .do_lister = info->query.expr.size != 0); } }break; @@ -15039,12 +15039,16 @@ rd_frame(void) RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_Cfg *bp = rd_cfg_new(project, str8_lit("breakpoint")); rd_cmd(RD_CmdKind_RelocateCfg, .cfg = bp->id); + if(rd_regs()->do_lister) + { + rd_cmd(RD_CmdKind_PushQuery, .expr = push_str8f(scratch.arena, "query:config.$%I64x", bp->id), .do_lister = 0); + } } } }break; case RD_CmdKind_AddAddressBreakpoint: { - rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero()); + rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero(), .do_lister = 1); }break; //- rjf: watch pins From 6a9d212e70a79546855358f76b72c1f4c3b8ab46 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 11:17:47 -0700 Subject: [PATCH 464/755] adjust escape-to-close-query view rules, to account for non-lister query views, but with a command --- src/raddbg/raddbg_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3ec31521..e247e5aa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6708,7 +6708,10 @@ rd_window_frame(void) RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); // rjf: close queries - if(query_floating_view_task->pressed_outside || (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_selected) || ui_slot_press(UI_EventActionSlot_Cancel)) + if(query_floating_view_task->pressed_outside || + (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_selected) || + (cmd_name.size != 0 && !vs->query_is_selected) || + ui_slot_press(UI_EventActionSlot_Cancel)) { rd_cmd(RD_CmdKind_CancelQuery); } From ea18e5890341c348ebc35933a45da5c3baad5901 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 11:38:22 -0700 Subject: [PATCH 465/755] fix & simplify path/pt meta editing --- src/raddbg/generated/raddbg.meta.c | 9 +++++---- src/raddbg/raddbg.mdesk | 9 +++++---- src/raddbg/raddbg_core.c | 24 +++++++----------------- src/raddbg/raddbg_eval.c | 7 ------- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 672c4b0a..f95f718f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -330,7 +330,7 @@ RD_VocabInfo rd_vocab_info_table[316] = {str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, -{str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -385,8 +385,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, @@ -659,7 +659,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -764,6 +764,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[108] = {str8_lit_comp("toggle_watch_expr_at_mouse"), {OS_Key_D, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("toggle_watch_pin"), {OS_Key_F9, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, +{str8_lit_comp("add_address_breakpoint"), {OS_Key_F9, 0 |OS_Modifier_Shift }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, {str8_lit_comp("open_palette"), {OS_Key_F1, 0 }}, {str8_lit_comp("open_palette"), {OS_Key_P, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index c129ec95..66600047 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -439,7 +439,7 @@ RD_VocabTable: { 'label': code_string, 'condition': code_string, - 'source_location': path_pt, + 'source_location': string, 'address_location': code_string, 'hit_count': u64, 'address_range_size': @or(0, 1, 2, 4, 8) u64, @@ -456,11 +456,11 @@ RD_VocabTable: watch_pin, ``` @row_commands(duplicate_cfg, remove_cfg) - @collection_commands(add_watch_pin) + @collection_commands(add_watch_pin, toggle_watch_pin) x: { 'expression': code_string, - 'source_location': path_pt, + 'source_location': string, 'address_location': code_string, } ```, @@ -813,7 +813,7 @@ RD_CmdTable: // | | | | //- rjf: watch pins {AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } - {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Binoculars "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } + {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } //- rjf: auto view rule {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } @@ -1045,6 +1045,7 @@ RD_DefaultBindingTable: //- rjf: breakpoints { "toggle_breakpoint" F9 0 0 0 } + { "add_address_breakpoint" F9 0 shift 0 } //- rjf: attaching { "attach" F6 0 shift 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e247e5aa..5c3577e9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1109,12 +1109,9 @@ rd_location_from_cfg(RD_Cfg *cfg) RD_Cfg *addr_loc = rd_cfg_child_from_string(cfg, str8_lit("address_location")); if(src_loc != &rd_nil_cfg) { - dst_loc.file_path = src_loc->first->string; - try_s64_from_str8_c_rules(src_loc->first->first->string, &dst_loc.pt.line); - if(!try_s64_from_str8_c_rules(src_loc->first->first->first->string, &dst_loc.pt.column)) - { - dst_loc.pt.column = 1; - } + String8TxtPtPair loc_description = str8_txt_pt_pair_from_string(src_loc->first->string); + dst_loc.file_path = loc_description.string; + dst_loc.pt = loc_description.pt; } else if(addr_loc != &rd_nil_cfg) { @@ -1681,13 +1678,9 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) child_schema = md_child_from_string(n->v, child_key, 0); } String8 child_type_name = child_schema->first->string; - if(str8_match(child_type_name, str8_lit("path_pt"), 0)) - { - read_data = push_str8f(scratch.arena, "%S%s%S%s%S", cfg->first->string, cfg->first->string.size ? ":" : "", cfg->first->first->string, cfg->first->first->first->string.size ? ":" : "", cfg->first->first->first->string); - } - else if(str8_match(child_type_name, str8_lit("path"), 0) || - str8_match(child_type_name, str8_lit("code_string"), 0) || - str8_match(child_type_name, str8_lit("string"), 0)) + if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("string"), 0)) { read_data = cfg->first->string; } @@ -14991,10 +14984,7 @@ rd_frame(void) if(file_path.size != 0 && pt.line != 0) { RD_Cfg *src_loc = rd_cfg_new(cfg, str8_lit("source_location")); - RD_Cfg *file = rd_cfg_new(src_loc, file_path); - RD_Cfg *line = rd_cfg_newf(file, "%I64d", pt.line); - RD_Cfg *col = rd_cfg_newf(line, "%I64d", pt.column); - (void)col; + rd_cfg_newf(src_loc, "%S:%I64d:%I64d", file_path, pt.line, pt.column); } else if(expr_string.size != 0) { diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 9c57e91c..74b5b663 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -257,13 +257,6 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); } - else if(str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - String8 string = push_str8f(scratch.arena, "%S%s%S%s%S", child->first->string, child->first->string.size ? ":" : "", child->first->first->string, child->first->first->first->string.size ? ":" : "", child->first->first->first->string); - child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), string.size, E_TypeFlag_IsPathText); - scratch_end(scratch); - } else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); From 2092f5ca697a6e184e16fea2ba844c8a2ee3ef50 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 12:33:48 -0700 Subject: [PATCH 466/755] eval space generation, to gracefully mark cached evaluations as dirty when desired --- src/eval/eval_bundles.c | 398 ----------------------------- src/eval/eval_bundles.h | 32 --- src/eval/eval_core.c | 193 +++++++++++++- src/eval/eval_core.h | 15 +- src/eval/eval_inc.c | 1 - src/eval/eval_inc.h | 1 - src/eval/eval_interpret.c | 11 + src/eval/eval_interpret.h | 1 + src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 24 +- src/raddbg/raddbg_core.h | 3 + src/raddbg/raddbg_eval.c | 1 + 13 files changed, 248 insertions(+), 438 deletions(-) delete mode 100644 src/eval/eval_bundles.c delete mode 100644 src/eval/eval_bundles.h diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c deleted file mode 100644 index b05ea40c..00000000 --- a/src/eval/eval_bundles.c +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Bundled Evaluation Functions - -#if 0 -internal E_Eval -e_eval_from_expr(Arena *arena, E_Expr *expr) -{ - ProfBeginFunction(); - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(arena, expr); - E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - E_Eval eval = - { - .value = interp.value, - .space = interp.space, - .expr = expr, - .irtree = irtree, - .bytecode = bytecode, - .code = interp.code, - }; - e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); - if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT) - { - e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]); - } - ProfEnd(); - return eval; -} - -internal E_Eval -e_eval_from_string(Arena *arena, String8 string) -{ - ProfBeginFunction(); - ProfBegin("e_eval_from_string (%.*s)", str8_varg(string)); - E_Parse parse = e_parse_from_string(string); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(parse.expr); - E_OpList oplist = e_oplist_from_irtree(arena, irtree.root); - String8 bytecode = e_bytecode_from_oplist(arena, &oplist); - E_Interpretation interp = e_interpret(bytecode); - E_Eval eval = - { - .value = interp.value, - .space = interp.space, - .expr = parse.expr, - .irtree = irtree, - .bytecode = bytecode, - .code = interp.code, - }; - e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs); - if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT) - { - e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]); - } - ProfEnd(); - ProfEnd(); - return eval; -} - -internal E_Eval -e_eval_from_stringf(Arena *arena, char *fmt, ...) -{ - Temp scratch = scratch_begin(&arena, 1); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - E_Eval eval = e_eval_from_string(arena, string); - va_end(args); - scratch_end(scratch); - return eval; -} - -internal E_Eval -e_dynamically_typed_eval_from_eval(E_Eval eval) -{ - E_TypeKey type_key = eval.irtree.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_state != 0 && - e_interpret_ctx != 0 && - e_interpret_ctx->space_read != 0 && - e_interpret_ctx->module_base != 0 && - type_kind == E_TypeKind_Ptr) - { - Temp scratch = scratch_begin(0, 0); - E_TypeKey ptee_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_AllDecorative); - E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); - if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) - { - E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); - B32 has_vtable = 0; - for(U64 idx = 0; idx < ptee_type->count; idx += 1) - { - if(ptee_type->members[idx].kind == E_MemberKind_VirtualMethod) - { - has_vtable = 1; - break; - } - } - if(has_vtable) - { - U64 ptr_vaddr = eval.value.u64; - U64 addr_size = e_type_byte_size_from_key(e_type_key_unwrap(type_key, E_TypeUnwrapFlag_AllDecorative)); - U64 class_base_vaddr = 0; - U64 vtable_vaddr = 0; - if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && - e_space_read(eval.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) - { - Arch arch = e_base_ctx->primary_module->arch; - U32 rdi_idx = 0; - RDI_Parsed *rdi = 0; - U64 module_base = 0; - for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) - { - if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) - { - arch = e_base_ctx->modules[idx].arch; - rdi_idx = (U32)idx; - rdi = e_base_ctx->modules[idx].rdi; - module_base = e_base_ctx->modules[idx].vaddr_range.min; - break; - } - } - if(rdi != 0) - { - U64 vtable_voff = vtable_vaddr - module_base; - U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, vtable_voff); - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx); - if(global_var->link_flags & RDI_LinkFlag_TypeScoped) - { - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); - RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); - E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); - eval.irtree.type_key = ptr_to_derived_type_key; - } - } - } - } - } - scratch_end(scratch); - } - return eval; -} - -internal E_Value -e_value_from_string(String8 string) -{ - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, string); - E_Eval value_eval = e_value_eval_from_eval(eval); - E_Value result = value_eval.value; - scratch_end(scratch); - return result; -} - -internal E_Value -e_value_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_Value result = e_value_from_string(string); - va_end(args); - scratch_end(scratch); - return result; -} - -internal E_Value -e_value_from_expr(E_Expr *expr) -{ - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - E_Value result = value_eval.value; - scratch_end(scratch); - return result; -} - -internal E_Value -e_value_from_eval(E_Eval eval) -{ - E_Eval value_eval = e_value_eval_from_eval(eval); - E_Value result = value_eval.value; - return result; -} - -internal E_Eval -e_eval_wrap(Arena *arena, E_Eval eval, String8 string) -{ - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &eval.irtree; - E_Eval wrapped_eval = e_eval_from_string(arena, string); - e_ir_state->overridden_irtree = prev_overridden_irtree; - return wrapped_eval; -} - -internal E_Eval -e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...) -{ - Temp scratch = scratch_begin(&arena, 1); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - E_Eval result = e_eval_wrap(arena, eval, string); - va_end(args); - scratch_end(scratch); - return result; -} - -#endif - -internal U64 -e_base_offset_from_eval(E_Eval eval) -{ - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)))) - { - eval = e_value_eval_from_eval(eval); - } - return eval.value.u64; -} - -internal Rng1U64 -e_range_from_eval(E_Eval eval) -{ - U64 size = 0; - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) - { - size = e_value_from_expr(arg->first->next).u64; - break; - } - } - } - 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); - E_TypeKey direct_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(direct_type_key); - } - if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(type_key); - } - if(size == 0) - { - size = KB(16); - } - Rng1U64 result = {0}; - result.min = e_base_offset_from_eval(eval); - result.max = result.min + size; - return result; -} - - -//////////////////////////////// -//~ rjf: Debug Logging Functions - -internal String8 -e_debug_log_from_expr_string(Arena *arena, String8 string) -{ - Temp scratch = scratch_begin(&arena, 1); - char *indent_spaces = " "; - String8List strings = {0}; - - //- rjf: begin expression - String8 expr_text = string; - str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text); - - //- rjf: parse - E_Parse parse = e_push_parse_from_string(scratch.arena, expr_text); - { - typedef struct Task Task; - struct Task - { - Task *next; - E_Expr *expr; - S32 indent; - }; - E_TokenArray tokens = parse.tokens; - str8_list_pushf(scratch.arena, &strings, " tokens:\n"); - for EachIndex(idx, tokens.count) - { - E_Token token = tokens.v[idx]; - String8 token_string = str8_substr(expr_text, token.range); - str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); - } - str8_list_pushf(scratch.arena, &strings, " expr:\n"); - Task start_task = {0, parse.expr, 2}; - Task *first_task = &start_task; - for(Task *t = first_task; t != 0; t = t->next) - { - E_Expr *expr = t->expr; - str8_list_pushf(scratch.arena, &strings, "%.*s%S", (int)t->indent*4, indent_spaces, e_expr_kind_strings[expr->kind]); - switch(expr->kind) - { - default:{}break; - case E_ExprKind_LeafU64: - { - str8_list_pushf(scratch.arena, &strings, " (%I64u)", expr->value.u64); - }break; - case E_ExprKind_LeafIdentifier: - { - str8_list_pushf(scratch.arena, &strings, " (`%S`)", expr->string); - }break; - } - str8_list_pushf(scratch.arena, &strings, "\n"); - Task *last_task = t; - for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->next = last_task->next; - last_task->next = task; - task->expr = child; - task->indent = t->indent+1; - last_task = task; - } - } - } - - //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); - { - str8_list_pushf(scratch.arena, &strings, " type:\n"); - S32 indent = 2; - for(E_TypeKey type_key = irtree.type_key; - !e_type_key_match(e_type_key_zero(), type_key); - type_key = e_type_key_direct(type_key), - indent += 1) - { - E_Type *type = e_type_from_key(scratch.arena, type_key); - str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); - } - } - - //- rjf: irtree - { - typedef struct Task Task; - struct Task - { - Task *next; - E_IRNode *irnode; - S32 indent; - }; - str8_list_pushf(scratch.arena, &strings, " ir_tree:\n"); - Task start_task = {0, irtree.root, 2}; - Task *first_task = &start_task; - for(Task *t = first_task; t != 0; t = t->next) - { - E_IRNode *irnode = t->irnode; - str8_list_pushf(scratch.arena, &strings, "%.*s", (int)t->indent*4, indent_spaces); - switch(irnode->op) - { - default:{}break; -#define X(name) case RDI_EvalOp_##name:{str8_list_pushf(scratch.arena, &strings, #name);}break; - RDI_EvalOp_XList -#undef X - } - if(irnode->value.u64 != 0) - { - str8_list_pushf(scratch.arena, &strings, " (%I64u)", irnode->value.u64); - } - str8_list_pushf(scratch.arena, &strings, "\n"); - Task *last_task = t; - for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) - { - Task *task = push_array(scratch.arena, Task, 1); - task->next = last_task->next; - last_task->next = task; - task->irnode = child; - task->indent = t->indent+1; - last_task = task; - } - } - } - - str8_list_pushf(scratch.arena, &strings, "\n"); - - String8 result = str8_list_join(arena, &strings, 0); - scratch_end(scratch); - return result; -} diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h deleted file mode 100644 index 3d271963..00000000 --- a/src/eval/eval_bundles.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_BUNDLES_H -#define EVAL_BUNDLES_H - -//////////////////////////////// -//~ rjf: Bundled Evaluation Functions - -#if 0 -internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); -internal E_Eval e_eval_from_string(Arena *arena, String8 string); -internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); -internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval); -internal E_Eval e_value_eval_from_eval(E_Eval eval); -internal E_Value e_value_from_string(String8 string); -internal E_Value e_value_from_stringf(char *fmt, ...); -internal E_Value e_value_from_expr(E_Expr *expr); -internal E_Value e_value_from_eval(E_Eval eval); -internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string); -internal E_Eval e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...);; -#endif - -internal U64 e_base_offset_from_eval(E_Eval eval); -internal Rng1U64 e_range_from_eval(E_Eval eval); - -//////////////////////////////// -//~ rjf: Debug Logging Functions - -internal String8 e_debug_log_from_expr_string(Arena *arena, String8 string); - -#endif // EVAL_BUNDLES_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index b1759155..a0013fb8 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -727,7 +727,10 @@ e_key_from_string(String8 string) 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)) + if(e_key_match(parent_key, n->bundle.parent_key) && + str8_match(n->bundle.string, string, 0) && + (n->bundle.interpretation.space.kind == E_SpaceKind_Null || + e_space_gen(n->bundle.interpretation.space) == n->bundle.space_gen)) { node = n; break; @@ -859,6 +862,7 @@ e_interpretation_from_bundle(E_CacheBundle *bundle) e_msg(e_cache->arena, &bundle->msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[interpret.code]); } bundle->interpretation = interpret; + bundle->space_gen = e_space_gen(interpret.space); } E_Interpretation interpret = bundle->interpretation; return interpret; @@ -1113,3 +1117,190 @@ e_key_wrapf(E_Key key, char *fmt, ...) scratch_end(scratch); return result; } + +//////////////////////////////// +//~ rjf: Eval Info Extraction + +internal U64 +e_base_offset_from_eval(E_Eval eval) +{ + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)))) + { + eval = e_value_eval_from_eval(eval); + } + return eval.value.u64; +} + +internal Rng1U64 +e_range_from_eval(E_Eval eval) +{ + U64 size = 0; + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) + { + for EachIndex(idx, type->count) + { + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) + { + size = e_value_from_expr(arg->first->next).u64; + break; + } + } + } + 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); + E_TypeKey direct_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(direct_type_key); + } + if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || + type_kind == E_TypeKind_Union || + type_kind == E_TypeKind_Class || + type_kind == E_TypeKind_Array)) + { + size = e_type_byte_size_from_key(type_key); + } + if(size == 0) + { + size = KB(16); + } + Rng1U64 result = {0}; + result.min = e_base_offset_from_eval(eval); + result.max = result.min + size; + return result; +} + + +//////////////////////////////// +//~ rjf: Debug Functions + +internal String8 +e_debug_log_from_expr_string(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + char *indent_spaces = " "; + String8List strings = {0}; + + //- rjf: begin expression + String8 expr_text = string; + str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text); + + //- rjf: parse + E_Parse parse = e_push_parse_from_string(scratch.arena, expr_text); + { + typedef struct Task Task; + struct Task + { + Task *next; + E_Expr *expr; + S32 indent; + }; + E_TokenArray tokens = parse.tokens; + str8_list_pushf(scratch.arena, &strings, " tokens:\n"); + for EachIndex(idx, tokens.count) + { + E_Token token = tokens.v[idx]; + String8 token_string = str8_substr(expr_text, token.range); + str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string); + } + str8_list_pushf(scratch.arena, &strings, " expr:\n"); + Task start_task = {0, parse.expr, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_Expr *expr = t->expr; + str8_list_pushf(scratch.arena, &strings, "%.*s%S", (int)t->indent*4, indent_spaces, e_expr_kind_strings[expr->kind]); + switch(expr->kind) + { + default:{}break; + case E_ExprKind_LeafU64: + { + str8_list_pushf(scratch.arena, &strings, " (%I64u)", expr->value.u64); + }break; + case E_ExprKind_LeafIdentifier: + { + str8_list_pushf(scratch.arena, &strings, " (`%S`)", expr->string); + }break; + } + str8_list_pushf(scratch.arena, &strings, "\n"); + Task *last_task = t; + for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->next = last_task->next; + last_task->next = task; + task->expr = child; + task->indent = t->indent+1; + last_task = task; + } + } + } + + //- rjf: type + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); + { + str8_list_pushf(scratch.arena, &strings, " type:\n"); + S32 indent = 2; + for(E_TypeKey type_key = irtree.type_key; + !e_type_key_match(e_type_key_zero(), type_key); + type_key = e_type_key_direct(type_key), + indent += 1) + { + E_Type *type = e_type_from_key(scratch.arena, type_key); + str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); + } + } + + //- rjf: irtree + { + typedef struct Task Task; + struct Task + { + Task *next; + E_IRNode *irnode; + S32 indent; + }; + str8_list_pushf(scratch.arena, &strings, " ir_tree:\n"); + Task start_task = {0, irtree.root, 2}; + Task *first_task = &start_task; + for(Task *t = first_task; t != 0; t = t->next) + { + E_IRNode *irnode = t->irnode; + str8_list_pushf(scratch.arena, &strings, "%.*s", (int)t->indent*4, indent_spaces); + switch(irnode->op) + { + default:{}break; +#define X(name) case RDI_EvalOp_##name:{str8_list_pushf(scratch.arena, &strings, #name);}break; + RDI_EvalOp_XList +#undef X + } + if(irnode->value.u64 != 0) + { + str8_list_pushf(scratch.arena, &strings, " (%I64u)", irnode->value.u64); + } + str8_list_pushf(scratch.arena, &strings, "\n"); + Task *last_task = t; + for(E_IRNode *child = irnode->first; child != &e_irnode_nil; child = child->next) + { + Task *task = push_array(scratch.arena, Task, 1); + task->next = last_task->next; + last_task->next = task; + task->irnode = child; + task->indent = t->indent+1; + last_task = task; + } + } + } + + str8_list_pushf(scratch.arena, &strings, "\n"); + + String8 result = str8_list_join(arena, &strings, 0); + scratch_end(scratch); + return result; +} diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 5159b1c6..27ed36ad 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -682,6 +682,7 @@ struct E_AutoHookParams //////////////////////////////// //~ rjf: Evaluation Context +typedef U64 E_SpaceGenFunction(void *user_data, E_Space space); typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); //- rjf: base context @@ -703,6 +704,7 @@ struct E_BaseCtx // rjf: space hooks void *space_rw_user_data; + E_SpaceGenFunction *space_gen; E_SpaceRWFunction *space_read; E_SpaceRWFunction *space_write; }; @@ -887,6 +889,7 @@ struct E_CacheBundle E_IRTreeAndType irtree; String8 bytecode; E_Interpretation interpretation; + U64 space_gen; E_MsgList msgs; }; @@ -1143,7 +1146,6 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval); #define e_eval_from_stringf(...) e_eval_from_key(e_key_from_stringf(__VA_ARGS__)) #define e_value_from_string(string) e_value_eval_from_eval(e_eval_from_string(string)).value #define e_value_from_stringf(...) e_value_eval_from_eval(e_eval_from_stringf(__VA_ARGS__)).value -// TODO(rjf): (replace the old bundle APIs here) //- rjf: expr-based helpers #define e_eval_from_expr(expr) e_eval_from_key(e_key_from_expr(expr)) @@ -1167,4 +1169,15 @@ internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); #define e_eval_wrap(eval, string) e_eval_from_key(e_key_wrap((eval).key, (string))) #define e_eval_wrapf(eval, ...) e_eval_from_key(e_key_wrapf((eval).key, __VA_ARGS__)) +//////////////////////////////// +//~ rjf: Eval Info Extraction + +internal U64 e_base_offset_from_eval(E_Eval eval); +internal Rng1U64 e_range_from_eval(E_Eval eval); + +//////////////////////////////// +//~ rjf: Debug Functions + +internal String8 e_debug_log_from_expr_string(Arena *arena, String8 string); + #endif // EVAL_CORE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c index c4d2222c..cdfed3bd 100644 --- a/src/eval/eval_inc.c +++ b/src/eval/eval_inc.c @@ -6,4 +6,3 @@ #include "eval/eval_parse.c" #include "eval/eval_ir.c" #include "eval/eval_interpret.c" -#include "eval/eval_bundles.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h index 2c46335b..bb03829f 100644 --- a/src/eval/eval_inc.h +++ b/src/eval/eval_inc.h @@ -9,6 +9,5 @@ #include "eval/eval_parse.h" #include "eval/eval_ir.h" #include "eval/eval_interpret.h" -#include "eval/eval_bundles.h" #endif // EVAL_INC_H diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 670118df..5af37288 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -55,6 +55,17 @@ e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff //////////////////////////////// //~ rjf: Space Reading Helpers +internal U64 +e_space_gen(E_Space space) +{ + U64 result = 0; + if(e_base_ctx->space_gen != 0) + { + result = e_base_ctx->space_gen(e_base_ctx->space_rw_user_data, space); + } + return result; +} + internal B32 e_space_read(E_Space space, void *out, Rng1U64 range) { diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 0b4f37af..61ac98f0 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -35,6 +35,7 @@ internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rd //////////////////////////////// //~ rjf: Space Reading Helpers +internal U64 e_space_gen(E_Space space); internal B32 e_space_read(E_Space space, void *out, Rng1U64 range); internal B32 e_space_write(E_Space space, void *in, Rng1U64 range); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f95f718f..c5e96751 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -379,7 +379,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[21] = {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 66600047..2825168b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -327,14 +327,14 @@ RD_VocabTable: ``` @inherit(tab) x: { + @description("An expression to describe data which should be viewed as text or code.") + 'expression': code_string, @description("The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.") 'lang': lang, @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers':bool, @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, - @description("An expression to describe data which should be viewed as text or code.") - 'expression': code_string, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5c3577e9..b31bf879 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -276,6 +276,8 @@ rd_name_release(String8 string) internal RD_Cfg * rd_cfg_alloc(void) { + rd_state->cfg_change_gen += 1; + // rjf: allocate RD_Cfg *result = rd_state->free_cfg; { @@ -318,6 +320,8 @@ rd_cfg_alloc(void) internal void rd_cfg_release(RD_Cfg *cfg) { + rd_state->cfg_change_gen += 1; + Temp scratch = scratch_begin(0, 0); // rjf: unhook from context @@ -1561,6 +1565,21 @@ rd_cmd_name_from_eval(E_Eval eval) //- rjf: eval space reads/writes +internal U64 +rd_eval_space_gen(void *u, E_Space space) +{ + U64 result = 0; + switch(space.kind) + { + case RD_EvalSpaceKind_MetaCfg: + case RD_EvalSpaceKind_MetaQuery: + { + result = rd_state->cfg_change_gen; + }break; + } + return result; +} + internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { @@ -2820,6 +2839,7 @@ rd_view_ui(Rng2F32 rect) // if(state_dirty) ProfScope("state -> viz blocks") { + eval = e_eval_from_string(eval.string); MemoryZeroStruct(&block_tree); MemoryZeroStruct(&block_ranges); if(implicit_root || is_first_frame) @@ -11669,7 +11689,7 @@ rd_frame(void) } //- rjf: try menu bar operations - if(rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt"))) + if(rd_state->alt_menu_bar_enabled) { if(!take && event->kind == OS_EventKind_Press && event->key == OS_Key_Alt && event->modifiers == 0 && event->is_repeat == 0) { @@ -11836,6 +11856,7 @@ rd_frame(void) ctx->primary_module = eval_modules_primary; //- rjf: fill space hooks + ctx->space_gen = rd_eval_space_gen; ctx->space_read = rd_eval_space_read; ctx->space_write = rd_eval_space_write; } @@ -12518,6 +12539,7 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // + rd_state->alt_menu_bar_enabled = rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt")); if(rd_state->frame_depth == 0) { for(;rd_next_cmd(&cmd);) RD_RegsScope() diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7034ef82..d9412353 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -599,6 +599,7 @@ struct RD_State Arena *arena; B32 quit; B32 quit_after_success; + B32 alt_menu_bar_enabled; S32 frame_depth; U64 frame_eval_memread_endt_us; @@ -715,6 +716,7 @@ struct RD_State U64 cfg_id_gen; RD_CfgID cfg_last_accessed_id; RD_Cfg *cfg_last_accessed; + U64 cfg_change_gen; // rjf: window state cache U64 window_state_slots_count; @@ -923,6 +925,7 @@ internal E_Space rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind internal String8 rd_cmd_name_from_eval(E_Eval eval); //- rjf: eval space reads/writes +internal U64 rd_eval_space_gen(void *u, E_Space space); internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range); internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 74b5b663..2bf9f201 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -257,6 +257,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); } + else if(str8_match(child_schema->first->string, str8_lit("string"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPlainText); From 6a7420b7aa1fd92de3f9d444673378181ac3b880 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 14:50:49 -0700 Subject: [PATCH 467/755] exception code filter project settings / ui --- src/mule/mule_main.cpp | 15 ++++ src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 78 ++++++++++++++++++ src/raddbg/raddbg_core.c | 122 +++++++++++++++++------------ src/raddbg/raddbg_views.c | 12 ++- 5 files changed, 173 insertions(+), 56 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index c13ff6e3..9457bb21 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2524,6 +2524,19 @@ jit_stepping_tests(void) //////////////////////////////// // NOTE(allen): Exception Stepping +static void +exception_filter_test(void) +{ + __try + { + RaiseException(0xc0000095, 0, 0, 0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + OutputDebugStringA("did an exception\n"); + } +} + int *global_null_read_pointer = 0; static void trip(void){ @@ -2805,6 +2818,8 @@ mule_main(int argc, char** argv) fancy_viz_eval_tests(); + exception_filter_test(); + markup_tests(); // NOTE(allen): Stepping Tests diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c5e96751..a9a8bbf9 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -375,7 +375,7 @@ RD_VocabInfo rd_vocab_info_table[316] = RD_NameSchemaInfo rd_name_schema_info_table[21] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 2825168b..df3d1446 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -258,12 +258,90 @@ RD_VocabTable: } ``` } + + // TODO(rjf): the control codes could be fed from the CTRL_ExceptionCodeKindTable, but + // we do not support that in this generator - we'd need a way to form a table-generated + // string and put it into a table cell... { project ``` x: { @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, + @default(1) @display_name("Break On Win32 Control-C Exceptions") @description("Code: 0x40010005") + win32_ctrl_c: bool; + @default(1) @display_name("Break On Win32 Control-Break Exceptions") @description("Code: 0x40010008") + win32_ctrl_break: bool; + @default(0) @display_name("Break On Win32 WinRT Originate Error Exceptions") @description("Code: 0x40080201") + win32_win_rt_originate_error: bool; + @default(0) @display_name("Break On Win32 WinRT Transform Error Exceptions") @description("Code: 0x40080202") + win32_win_rt_transform_error: bool; + @default(0) @display_name("Break On Win32 RPC Call Cancelled Exceptions") @description("Code: 0x0000071a") + win32_rpc_call_cancelled: bool; + @default(0) @display_name("Break On Win32 Data Type Misalignment Exceptions") @description("Code: 0x80000002") + win32_datatype_misalignment: bool; + @default(1) @display_name("Break On Win32 Access Violation Exceptions") @description("Code: 0xc0000005") + win32_access_violation: bool; + @default(0) @display_name("Break On Win32 In Page Error Exceptions") @description("Code: 0xc0000006") + win32_in_page_error: bool; + @default(1) @display_name("Break On Win32 Invalid Handle Specified Exceptions") @description("Code: 0xc0000008") + win32_invalid_handle: bool; + @default(0) @display_name("Break On Win32 Not Enough Quota Exceptions") @description("Code: 0xc0000017") + win32_not_enough_quota: bool; + @default(0) @display_name("Break On Win32 Illegal Instruction Exceptions") @description("Code: 0xc000001d") + win32_illegal_instruction: bool; + @default(0) @display_name("Break On Win32 Cannot Continue From Exception Exceptions") @description("Code: 0xc0000025") + win32_cannot_continue_exception: bool; + @default(0) @display_name("Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions") @description("Code: 0xc0000026") + win32_invalid_exception_disposition: bool; + @default(0) @display_name("Break On Win32 Array Bounds Exceeded Exceptions") @description("Code: 0xc000008c") + win32_array_bounds_exceeded: bool; + @default(0) @display_name("Break On Win32 Floating-Point Denormal Operand Exceptions") @description("Code: 0xc000008d") + win32_floating_point_denormal_operand: bool; + @default(0) @display_name("Break On Win32 Floating-Point Division By Zero Exceptions") @description("Code: 0xc000008e") + win32_floating_point_division_by_zero: bool; + @default(0) @display_name("Break On Win32 Floating-Point Inexact Result Exceptions") @description("Code: 0xc000008f") + win32_floating_point_inexact_result: bool; + @default(0) @display_name("Break On Win32 Floating-Point Invalid Operation Exceptions") @description("Code: 0xc0000090") + win32_floating_point_invalid_operation: bool; + @default(0) @display_name("Break On Win32 Floating-Point Overflow Exceptions") @description("Code: 0xc0000091") + win32_floating_point_overflow: bool; + @default(0) @display_name("Break On Win32 Floating-Point Stack Check Exceptions") @description("Code: 0xc0000092") + win32_floating_point_stack_check: bool; + @default(0) @display_name("Break On Win32 Floating-Point Underflow Exceptions") @description("Code: 0xc0000093") + win32_floating_point_underflow: bool; + @default(0) @display_name("Break On Win32 Integer Division By Zero Exceptions") @description("Code: 0xc0000094") + win32_integer_division_by_zero: bool; + @default(0) @display_name("Break On Win32 Integer Overflow Exceptions") @description("Code: 0xc0000095") + win32_integer_overflow: bool; + @default(0) @display_name("Break On Win32 Privileged Instruction Exceptions") @description("Code: 0xc0000096") + win32_privileged_instruction: bool; + @default(0) @display_name("Break On Win32 Stack Overflow Exceptions") @description("Code: 0xc00000fd") + win32_stack_overflow: bool; + @default(0) @display_name("Break On Win32 Unable To Locate DLL Exceptions") @description("Code: 0xc0000135") + win32_unable_to_locate_dll: bool; + @default(0) @display_name("Break On Win32 Ordinal Not Found Exceptions") @description("Code: 0xc0000138") + win32_ordinal_not_found: bool; + @default(0) @display_name("Break On Win32 Entry Point Not Found Exceptions") @description("Code: 0xc0000139") + win32_entry_point_not_found: bool; + @default(0) @display_name("Break On Win32 DLL Initialization Failed Exceptions") @description("Code: 0xc0000142") + win32_dll_initialization_failed: bool; + @default(0) @display_name("Break On Win32 Floating Point SSE Multiple Faults Exceptions") @description("Code: 0xc00002b4") + win32_floating_point_sse_multiple_faults: bool; + @default(0) @display_name("Break On Win32 Floating Point SSE Multiple Traps Exceptions") @description("Code: 0xc00002b5") + win32_floating_point_sse_multiple_traps: bool; + @default(1) @display_name("Break On Win32 Assertion Failed Exceptions") @description("Code: 0xc0000420") + win32_assertion_failed: bool; + @default(0) @display_name("Break On Win32 Module Not Found Exceptions") @description("Code: 0xc06d007e") + win32_module_not_found: bool; + @default(0) @display_name("Break On Win32 Procedure Not Found Exceptions") @description("Code: 0xc06d007f") + win32_procedure_not_found: bool; + @default(1) @display_name("Break On Win32 Sanitizer Error Detected Exceptions") @description("Code: 0xe073616e") + win32_sanitizer_error_detected: bool; + @default(0) @display_name("Break On Win32 Sanitizer Raw Access Violation Exceptions") @description("Code: 0xe0736171") + win32_sanitizer_raw_access_violation: bool; + @default(1) @display_name("Break On Win32 DirectX Debug Layer Exceptions") @description("Code: 0x0000087a") + win32_directx_debug_layer: bool; } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b31bf879..e4f7320c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1213,19 +1213,65 @@ internal String8 rd_setting_from_name(String8 name) { String8 result = {0}; + if(name.size != 0) { - // rjf: find most-granular config scopes to begin looking for the setting - RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *start_cfg = &rd_nil_cfg; - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->panel); } - if(start_cfg == &rd_nil_cfg) { start_cfg = rd_cfg_from_id(rd_regs()->window); } + Temp scratch = scratch_begin(0, 0); - // rjf: scan upwards the config tree until we find the setting - RD_Cfg *setting = rd_cfg_child_from_string(view_cfg, name); - for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && setting == &rd_nil_cfg; cfg = cfg->parent) + // rjf: find most-granular config scopes to begin looking for the setting + typedef struct CfgSeedTask CfgSeedTask; + struct CfgSeedTask { - setting = rd_cfg_child_from_string(cfg, name); + CfgSeedTask *next; + RD_Cfg *cfg; + B32 allow_bucket_chains; + }; + RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); + CfgSeedTask panel_task = {0, &rd_nil_cfg, 1}; + if(panel_task.cfg == &rd_nil_cfg) { panel_task.cfg = rd_cfg_from_id(rd_regs()->panel); } + if(panel_task.cfg == &rd_nil_cfg) { panel_task.cfg = rd_cfg_from_id(rd_regs()->window); } + CfgSeedTask view_task = {&panel_task, view_cfg, 1}; + CfgSeedTask *first_task = &view_task; + CfgSeedTask *last_task = &panel_task; + + // rjf: for each task, look for the setting, follow parent chain upwards + RD_Cfg *setting = &rd_nil_cfg; + for(CfgSeedTask *t = first_task; t != 0; t = t->next) + { + for(RD_Cfg *cfg = t->cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) + { + setting = rd_cfg_child_from_string(cfg, name); + if(setting != &rd_nil_cfg) + { + goto break_all; + } + if(cfg->parent == rd_state->root_cfg && t->allow_bucket_chains) + { + String8 next_bucket = {0}; + B32 allow_bucket_chains = 0; + if(str8_match(cfg->string, str8_lit("user"), 0)) + { + next_bucket = str8_lit("project"); + } + else if(str8_match(cfg->string, str8_lit("project"), 0)) + { + next_bucket = str8_lit("user"); + } + else + { + allow_bucket_chains = 1; + next_bucket = str8_lit("user"); + } + if(next_bucket.size != 0) + { + CfgSeedTask *task = push_array(scratch.arena, CfgSeedTask, 1); + SLLQueuePush(first_task, last_task, task); + task->cfg = rd_cfg_child_from_string(rd_state->root_cfg, next_bucket); + task->allow_bucket_chains = allow_bucket_chains; + } + } + } } + break_all:; // rjf: return resultant child string stored under this key result = setting->first->string; @@ -1233,12 +1279,21 @@ rd_setting_from_name(String8 name) // rjf: no result -> look for default in schemas if(result.size == 0) { - result = rd_default_setting_from_names(view_cfg->string, name); - for(RD_Cfg *cfg = start_cfg; cfg != &rd_nil_cfg && result.size == 0; cfg = cfg->parent) + for(CfgSeedTask *t = first_task; t != 0; t = t->next) { - result = rd_default_setting_from_names(cfg->string, name); + for(RD_Cfg *cfg = t->cfg; cfg != &rd_nil_cfg; cfg = cfg->parent) + { + result = rd_default_setting_from_names(cfg->string, name); + if(result.size != 0) + { + goto break_all2; + } + } } + break_all2:; } + + scratch_end(scratch); } return result; } @@ -16030,50 +16085,15 @@ rd_frame(void) // U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64] = {0}; { - Temp scratch = scratch_begin(0, 0); - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1)) + for EachNonZeroEnumVal(CTRL_ExceptionCodeKind, k) { - if(ctrl_exception_code_kind_default_enable_table[k]) + String8 name = ctrl_exception_code_kind_lowercase_code_string_table[k]; + B32 setting = rd_setting_b32_from_name(name); + if(setting) { exception_code_filters[k/64] |= 1ull<<(k%64); } } - RD_CfgList exception_code_filters_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("exception_code_filters")); - for(RD_CfgNode *n = exception_code_filters_roots.first; n != 0; n = n->next) - { - for(RD_Cfg *rule = n->v->first; rule != &rd_nil_cfg; rule = rule->next) - { - String8 name = rule->string; - String8 val_string = rule->first->string; - U64 val = 0; - if(try_u64_from_str8_c_rules(val_string, &val)) - { - CTRL_ExceptionCodeKind kind = CTRL_ExceptionCodeKind_Null; - for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)(CTRL_ExceptionCodeKind_Null+1); - k < CTRL_ExceptionCodeKind_COUNT; - k = (CTRL_ExceptionCodeKind)(k+1)) - { - if(str8_match(name, ctrl_exception_code_kind_lowercase_code_string_table[k], 0)) - { - kind = k; - break; - } - } - if(kind != CTRL_ExceptionCodeKind_Null) - { - if(val) - { - exception_code_filters[kind/64] |= (1ull<<(kind%64)); - } - else - { - exception_code_filters[kind/64] &= ~(1ull<<(kind%64)); - } - } - } - } - } - scratch_end(scratch); } //////////////////////////// diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index d16f4b58..3afc52a0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1677,10 +1677,14 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // do a code-string of ".member_name" String8 member_name = notable_expr->first->next->string; String8 fancy_name = {0}; - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - cell->eval.space.kind == E_SpaceKind_File || - cell->eval.space.kind == E_SpaceKind_FileSystem) + if(str8_match(member_name, str8_lit("$padding"), StringMatchFlag_RightSideSloppy)) + { + fancy_name = str8_lit("Padding"); + } + else if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem) { fancy_name = rd_display_from_code_name(member_name); } From 282f6022e1d5d9d7bde3054e7a61c7adcdc338ad Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 17:30:34 -0700 Subject: [PATCH 468/755] begin color editing, fix some bugs with meta-type-info disrupting type chain scans --- src/eval/eval.mdesk | 2 + src/eval/eval_types.c | 8 ++- src/eval/generated/eval.meta.h | 2 + .../eval_visualization_core.c | 23 +++---- src/raddbg/generated/raddbg.meta.c | 16 +++-- src/raddbg/generated/raddbg.meta.h | 6 +- src/raddbg/raddbg.mdesk | 37 ++++++++++- src/raddbg/raddbg_core.c | 53 +++++++++++++++- src/raddbg/raddbg_core.h | 2 + src/raddbg/raddbg_eval.c | 61 +++++++++++++++++++ src/raddbg/raddbg_eval.h | 1 + src/raddbg/raddbg_views.c | 13 ++-- src/raddbg/raddbg_widgets.c | 17 ++++++ 13 files changed, 211 insertions(+), 30 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index e4d88531..5717a44d 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -183,6 +183,8 @@ e_token_kind_strings: `LastSigned2 = E_TypeKind_S512`, `FirstIncomplete = E_TypeKind_IncompleteStruct`, `LastIncomplete = E_TypeKind_IncompleteEnum`, + `FirstMeta = E_TypeKind_MetaExpr`, + `LastMeta = E_TypeKind_MetaDescription`, } @data(String8) e_type_kind_basic_string_table: diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 8f4fe480..2fa75880 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1382,14 +1382,14 @@ e_expand_rule_from_type_key(E_TypeKey key) { E_TypeExpandRule *rule = &e_type_expand_rule__default; { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key__cached(e_type_key_unwrap(key, E_TypeUnwrapFlag_Meta)); if(type->expand.info != 0) { rule = &type->expand; } for(E_Type *lens_type = type; lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; - lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + lens_type = e_type_from_key__cached(e_type_key_unwrap(lens_type->direct_type_key, E_TypeUnwrapFlag_Meta))) { if(lens_type->expand.info != 0) { @@ -1746,6 +1746,8 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr }break; case E_TypeKind_MetaExpr: + case E_TypeKind_MetaDisplayName: + case E_TypeKind_MetaDescription: { E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, prec, skip_return); @@ -1905,7 +1907,7 @@ e_default_expansion_type_from_key(E_TypeKey root_key) //- rjf: if we have meta-expression tags in the type chain, defer // to the next type in the chain. - else if(kind == E_TypeKind_MetaExpr) + else if(E_TypeKind_FirstMeta <= kind && kind <= E_TypeKind_LastMeta) { done = 0; } diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 5bd73d8d..8e3e570b 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -91,6 +91,8 @@ E_TypeKind_FirstSigned2 = E_TypeKind_S8, E_TypeKind_LastSigned2 = E_TypeKind_S512, E_TypeKind_FirstIncomplete = E_TypeKind_IncompleteStruct, E_TypeKind_LastIncomplete = E_TypeKind_IncompleteEnum, +E_TypeKind_FirstMeta = E_TypeKind_MetaExpr, +E_TypeKind_LastMeta = E_TypeKind_MetaDescription, } E_TypeKind; typedef U32 E_ExprKind; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index fef05868..d817f242 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -417,9 +417,9 @@ ev_expand_rule_from_type_key(E_TypeKey type_key) { EV_ExpandRule *rule = &ev_nil_expand_rule; { - E_TypeKey k = type_key; + E_TypeKey k = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_Meta); E_TypeKind kind = e_type_kind_from_key(k); - for(;kind == E_TypeKind_Lens; k = e_type_key_direct(k), kind = e_type_kind_from_key(k)) + for(;kind == E_TypeKind_Lens; k = e_type_key_direct(e_type_key_unwrap(k, E_TypeUnwrapFlag_Meta)), kind = e_type_kind_from_key(k)) { E_Type *type = e_type_from_key__cached(k); EV_ExpandRule *candidate = ev_expand_rule_from_string(type->name); @@ -536,10 +536,10 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval tree.total_item_count += 1; //- rjf: generate initial task, for root's evaluation - typedef struct Task Task; - struct Task + typedef struct BlockTreeBuildTask BlockTreeBuildTask; + struct BlockTreeBuildTask { - Task *next; + BlockTreeBuildTask *next; EV_Block *parent_block; E_Eval eval; E_Expr *next_expr; @@ -548,12 +548,12 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval B32 default_expanded; B32 force_expanded; }; - Task start_task = {0, tree.root, tree.root->eval, tree.root->eval.expr->next, 1, 0}; - Task *first_task = &start_task; - Task *last_task = first_task; + BlockTreeBuildTask start_task = {0, tree.root, tree.root->eval, tree.root->eval.expr->next, 1, 0}; + BlockTreeBuildTask *first_task = &start_task; + BlockTreeBuildTask *last_task = first_task; //- rjf: iterate all expansions & generate blocks for each - for(Task *t = first_task; t != 0; t = t->next) + for(BlockTreeBuildTask *t = first_task; t != 0; t = t->next) { // rjf: get task key EV_Key key = ev_key_make(ev_hash_from_key(t->parent_block->key), t->child_id); @@ -704,7 +704,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval E_Eval child_eval = {0}; type_expand_rule->range(arena, type_expand_info.user_data, t->eval, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); EV_Key child_key = child_keys[idx]; - Task *task = push_array(scratch.arena, Task, 1); + BlockTreeBuildTask *task = push_array(scratch.arena, BlockTreeBuildTask, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; task->eval = child_eval; @@ -718,7 +718,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval // rjf: if this expr has a sibling, push another task to continue the chain if(t->next_expr != &e_expr_nil) { - Task *task = push_array(scratch.arena, Task, 1); + BlockTreeBuildTask *task = push_array(scratch.arena, BlockTreeBuildTask, 1); task->next = t->next; t->next = task; task->parent_block = t->parent_block; @@ -1744,6 +1744,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // case E_TypeKind_Modifier: case E_TypeKind_MetaDescription: + case E_TypeKind_MetaDisplayName: { need_pop = 1; need_new_task = 1; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a9a8bbf9..879bb148 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[316] = +RD_VocabInfo rd_vocab_info_table[319] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -65,6 +65,7 @@ RD_VocabInfo rd_vocab_info_table[316] = {str8_lit_comp("source_location"), str8_lit_comp("source_locations"), str8_lit_comp("Source Location"), str8_lit_comp("Source Locations"), RD_IconKind_Null}, {str8_lit_comp("address_location"), str8_lit_comp("address_locations"), str8_lit_comp("Address Location"), str8_lit_comp("Address Locations"), RD_IconKind_Null}, {str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, +{str8_lit_comp("color"), str8_lit_comp("colors"), str8_lit_comp("Color"), str8_lit_comp("Colors"), RD_IconKind_Palette}, {str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, {str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, {str8_lit_comp("exe"), str8_lit_comp("exes"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, @@ -332,6 +333,8 @@ RD_VocabInfo rd_vocab_info_table[316] = {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("add_color"), str8_lit_comp(""), str8_lit_comp("Add Color"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("import_colors"), str8_lit_comp(""), str8_lit_comp("Import Colors"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -372,10 +375,11 @@ RD_VocabInfo rd_vocab_info_table[316] = {str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, }; -RD_NameSchemaInfo rd_name_schema_info_table[21] = +RD_NameSchemaInfo rd_name_schema_info_table[22] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n color: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -443,7 +447,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[212] = +RD_CmdKindInfo rd_cmd_kind_info_table[214] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -619,6 +623,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[212] = { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_color"), str8_lit_comp("Adds a new color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("import_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -905,7 +911,7 @@ String8 rd_theme_preset_cfg_string_table[9] = { str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x2f2633ff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), str8_lit_comp(""), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3bf7d01c..af560e67 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -229,6 +229,8 @@ RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, RD_CmdKind_AddAutoViewRule, +RD_CmdKind_AddColor, +RD_CmdKind_ImportColors, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -668,8 +670,8 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[316]; -extern RD_NameSchemaInfo rd_name_schema_info_table[21]; +extern RD_VocabInfo rd_vocab_info_table[319]; +extern RD_NameSchemaInfo rd_name_schema_info_table[22]; extern Rng1U64 rd_reg_slot_range_table[42]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index df3d1446..ee29a4df 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -90,6 +90,7 @@ RD_VocabTable: {source_location _ "Source Location" _ Null } {address_location _ "Address Location" _ Null } {target _ "Target" _ Target } + {color _ "Color" _ Palette } {executable _ "Executable" _ Module } {arguments arguments "Arguments" "Arguments" Null } {exe exes "Executable" _ Module } @@ -227,6 +228,14 @@ RD_VocabTable: 'main_font': string, 'code_font': string, + //- rjf: colors + @display_name('Color Preset') + 'color_preset': string, + @display_name('Color File') + 'color_file': path, + @display_name('Colors') + 'colors': query, + //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") 'thread_lines': bool, @@ -346,6 +355,18 @@ RD_VocabTable: ``` } + //- rjf: colors + { + color, + ``` + @collection_commands(add_color, import_colors) x: + { + @display_name('Tags') tags: string, + color: @color @hex u32, + } + ``` + } + //- rjf: windows { window, @@ -896,6 +917,10 @@ RD_CmdTable: // | | | | //- rjf: auto view rule {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + //- rjf: colors + {AddColor 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_color" "Add Color" "Adds a new color." "" "" } + {ImportColors 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "import_colors" "Import Colors" "Imports all colors from a loaded color theme file or color theme preset." "" "" } + //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } @@ -1405,7 +1430,15 @@ RD_ThemePresetTable: } { DefaultLight default_light "Default (Light)" } - { VSDark vs_dark "VS (Dark)" } + + { + VSDark vs_dark "VS (Dark)", + ```theme: + { + background: 0x1b0000ff, + } + ``` + } { VSLight vs_light "VS (Light)" } { SolarizedDark solarized_dark "Solarized (Dark)" } { SolarizedLight solarized_light "Solarized (Light)" } @@ -1414,7 +1447,7 @@ RD_ThemePresetTable: { FarManager far_manager "Far Manager" } } -@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) +@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) RD_ThemeColorTable: { {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e4f7320c..a9c353a2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1780,6 +1780,17 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) U64 value = e_value_from_string(value_string_casted).u64; read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } + else if(str8_match(child_type_name, str8_lit("u32"), 0)) + { + String8 value_string = cfg->first->string; + if(value_string.size == 0) + { + value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + } + String8 value_string_casted = push_str8f(scratch.arena, "(uint32)(%S)", value_string); + U64 value = e_value_from_string(value_string_casted).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } else if(str8_match(child_type_name, str8_lit("f32"), 0)) { String8 value_string = cfg->first->string; @@ -4741,6 +4752,10 @@ rd_view_ui(Rng2F32 rect) { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row->eval.space); + if(cfg == &rd_nil_cfg) + { + cfg = rd_cfg_from_eval_space(row->block->eval.space); + } RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) { if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) @@ -5483,7 +5498,7 @@ rd_window_frame(void) // that windows can have their own colors, and have those override higher-up settings. RD_Cfg *preset_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; - RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; + RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("theme")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; for EachElement(idx, scan_parents) { for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) @@ -10864,6 +10879,7 @@ rd_init(CmdLine *cmdln) cmd_line_has_flag(cmdln, str8_lit("q"))); rd_state->user_path_arena = arena_alloc(); rd_state->project_path_arena = arena_alloc(); + rd_state->theme_path_arena = arena_alloc(); rd_state->user_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_user_data_string_key")); rd_state->project_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_project_data_string_key")); rd_state->cmdln_cfg_string_key = hs_hash_from_data(str8_lit("raddbg_cmdln_data_string_key")); @@ -12304,6 +12320,19 @@ rd_frame(void) { .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(call_stack), })); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("colors"), + e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_EditableChildren, + .name = str8_lit("colors"), + .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs_slice), + .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs_slice), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(cfgs_query), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(cfgs_slice), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs_slice), + })); } //- rjf: add macro for collections with specific lookup rules (but no unique id rules) @@ -12846,7 +12875,9 @@ rd_frame(void) case RD_CmdKind_OpenUser: case RD_CmdKind_OpenProject: { - String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : str8_lit("project")); + String8 file_root_key = (kind == RD_CmdKind_OpenUser ? str8_lit("user") : + kind == RD_CmdKind_OpenProject ? str8_lit("project") : + str8_lit("other")); RD_Cfg *file_root = rd_cfg_child_from_string(rd_state->root_cfg, file_root_key); //- rjf: load the new file's data @@ -15164,6 +15195,24 @@ rd_frame(void) rd_cfg_new(project, str8_lit("auto_view_rule")); }break; + //- rjf: colors + case RD_CmdKind_AddColor: + { + RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + rd_cfg_new(parent, str8_lit("color")); + }break; + case RD_CmdKind_ImportColors: + { + RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("color")); + for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + // String8 color_preset = rd_setting_from_name(str8_lit("color_preset")); + // String8 color_file = rd_setting_from_name(str8_lit("color_file")); + }break; + //- rjf: watches case RD_CmdKind_ToggleWatchExpression: if(rd_regs()->string.size != 0) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index d9412353..6097e6bf 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -608,6 +608,8 @@ struct RD_State String8 user_path; Arena *project_path_arena; String8 project_path; + Arena *theme_path_arena; + String8 theme_path; // rjf: serialized config debug string keys U128 user_cfg_string_key; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 2bf9f201..02e78aa7 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -269,6 +269,11 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) child_type_key = e_type_key_basic(E_TypeKind_U64); wrap_child_w_meta_expr = 1; } + else if(str8_match(child_schema->first->string, str8_lit("u32"), 0)) + { + child_type_key = e_type_key_basic(E_TypeKind_U32); + wrap_child_w_meta_expr = 1; + } else if(str8_match(child_schema->first->string, str8_lit("f32"), 0)) { child_type_key = e_type_key_basic(E_TypeKind_F32); @@ -341,6 +346,28 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) } } + //- rjf: extend child type with hex lens + { + MD_Node *hex = md_tag_from_string(child_schema->first, str8_lit("hex"), 0); + if(!md_node_is_nil(hex)) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .name = str8_lit("hex"), + .direct_key = child_type_key); + } + } + + //- rjf: extend child type with color lens + { + MD_Node *color = md_tag_from_string(child_schema->first, str8_lit("color"), 0); + if(!md_node_is_nil(color)) + { + child_type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .name = str8_lit("color"), + .direct_key = child_type_key); + } + } + //- rjf: extend child type with ranges { MD_Node *range = md_tag_from_string(child_schema->first, str8_lit("range"), 0); @@ -668,6 +695,40 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_slice) return info; } +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_query) +{ + RD_CfgsExpandAccel *accel = push_array(arena, RD_CfgsExpandAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + RD_Cfg *root_cfg = rd_cfg_from_eval_space(eval.space); + String8 child_key = e_string_from_id(eval.space.u64s[1]); + String8 child_key_singular = rd_singular_from_code_name_plural(child_key); + if(child_key_singular.size != 0) + { + child_key = child_key_singular; + } + String8List cmds = {0}; + MD_NodePtrList schemas = rd_schemas_from_name(child_key); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + MD_Node *collection_cmds_root = md_tag_from_string(schema, str8_lit("collection_commands"), 0); + for MD_EachNode(cmd, collection_cmds_root->first) + { + str8_list_push(scratch.arena, &cmds, cmd->string); + } + } + RD_CfgList children = rd_cfg_child_list_from_string(scratch.arena, root_cfg, child_key); + accel->cmds = str8_array_from_list(arena, &cmds); + accel->cmds_idx_range = r1u64(0, accel->cmds.count); + accel->cfgs = rd_cfg_array_from_list(arena, &children); + accel->cfgs_idx_range = r1u64(accel->cmds.count + 0, accel->cmds.count + accel->cfgs.count); + scratch_end(scratch); + } + E_TypeExpandInfo info = {accel, accel->cfgs.count + accel->cmds.count}; + return info; +} + E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs_slice) { RD_CfgsExpandAccel *accel = (RD_CfgsExpandAccel *)user_data; diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 41715697..2edc84c0 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -40,6 +40,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(cfgs); //~ rjf: Config Slice Type Hooks E_TYPE_IREXT_FUNCTION_DEF(cfgs_slice); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_query); E_TYPE_ACCESS_FUNCTION_DEF(cfgs_slice); E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_slice); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs_slice); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3afc52a0..9f6f31e0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -945,7 +945,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) EV_Key key = row->key; EV_Block *block = row->block; E_Eval block_eval = row->block->eval; - E_TypeKey block_type_key = block_eval.irtree.type_key; + E_TypeKey block_type_key = e_type_key_unwrap(block_eval.irtree.type_key, E_TypeUnwrapFlag_Meta); E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); E_Type *block_type = e_type_from_key__cached(block_type_key); RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(row->eval.space); @@ -1277,7 +1277,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: @watch_row_build_cells queries // - else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery) + else if(row->eval.space.kind == RD_EvalSpaceKind_MetaQuery || + (row->eval.space.kind == RD_EvalSpaceKind_MetaCfg && + e_type_kind_from_key(e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_Meta)) == E_TypeKind_Set)) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .pct = 1.f); } @@ -1339,8 +1341,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || row->eval.space.kind == E_SpaceKind_File) { - if(e_type_kind_from_key(row->eval.irtree.type_key) == E_TypeKind_Array && - e_type_kind_from_key(e_type_key_direct(row->eval.irtree.type_key)) == E_TypeKind_U8) + E_TypeKey substantive_row_eval_type = e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_Meta); + if(e_type_kind_from_key(substantive_row_eval_type) == E_TypeKind_Array && + e_type_kind_from_key(e_type_key_direct(substantive_row_eval_type)) == E_TypeKind_U8) { info.can_expand = 0; } @@ -1742,7 +1745,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: determine if code B32 is_code = 1; { - E_Type *type = e_type_from_key__cached(cell->eval.irtree.type_key); + E_Type *type = e_type_from_key__cached(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_Meta)); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) { is_code = 0; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b2d3001b..7d5c8d70 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -393,6 +393,23 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); } + //- rjf: special case: colors + if(str8_match(cfg->string, str8_lit("color"), 0)) + { + String8 tags = rd_cfg_child_from_string(cfg, str8_lit("tags"))->first->string; + String8 color_string = rd_cfg_child_from_string(cfg, str8_lit("color"))->first->string; + U32 color_u32 = e_value_from_stringf("(uint32)(%S)", color_string).u32; + Vec4F32 color = rgba_from_u32(color_u32); + if(tags.size != 0) + { + dr_fstrs_push_new(arena, &result, ¶ms, tags, .color = color); + } + else + { + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("Color"), .color = rgba_secondary); + } + } + #undef start_secondary scratch_end(scratch); } From 1e82d31eba85cb48a266cc55d39d0eccbe3be689 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 19:01:35 -0700 Subject: [PATCH 469/755] first rough pass on theme editing --- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 205 +++++++++++------------------ src/raddbg/raddbg_core.c | 63 +++++---- src/raddbg/raddbg_views.c | 15 ++- src/raddbg/raddbg_widgets.c | 4 +- 5 files changed, 131 insertions(+), 160 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 879bb148..0a4ace89 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -379,7 +379,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[22] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n color: @color @hex u32,\n}\n")}, +{str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -909,7 +909,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n background: 0x1b1b1bff,\n alt: background: 0x222222ff,\n pop: background: 0x355b6eff,\n fresh: background: 0x31393dff,\n match: background: 0x31393dff,\n border: 0x404040ff,\n text: 0xe5e5e5ff,\n weak: text: 0xa4a4a4ff,\n good: text: 0x32a852ff,\n bad: text: 0xcf5242ff,\n hover: 0xffffffff,\n focus: 0xfda200ff,\n cursor: 0x8aff00ff,\n selection: 0x99ccffff,\n inactive: background: 0x0000002f,\n drop_shadow: 0x0000007f,\n\n good_pop:\n {\n background: 0x2c5b36ff,\n border: 0x568761ff,\n hover: 0xe3f5d3ff,\n weak: text: 0xe3f5d3ff,\n }\n\n bad_pop:\n {\n background: 0x803425ff,\n hover: 0xff825cff,\n }\n\n code_default: 0xcbcbcbff,\n code_symbol: 0x42a2cfff,\n code_type: 0xfec746ff,\n code_local: 0x98bc80ff,\n code_register: 0xb7afd5ff,\n code_keyword: 0xb38d4cff,\n code_delimiter_or_operator: 0x767676ff,\n code_numeric: 0x98abb1ff,\n code_numeric_alt_digit_group: 0x738287ff,\n code_string: 0x98abb1ff,\n code_meta: 0xd96759ff,\n code_comment: 0x717171ff,\n line_info_0: 0x4f3022ff,\n line_info_1: 0x4f3e15ff,\n line_info_2: 0x434e2aff,\n line_info_3: 0x36241fff,\n line_info_4: 0x4f3022ff,\n line_info_5: 0x4f3e15ff,\n line_info_6: 0x434e2aff,\n line_info_7: 0x36241fff,\n thread_0: 0xffcb7fff,\n thread_1: 0xb2ff65ff,\n thread_2: 0xff99e5ff,\n thread_3: 0x6598ffff,\n thread_4: 0x65ffcbff,\n thread_5: 0xff9819ff,\n thread_6: 0x9932ffff,\n thread_7: 0x65ff4cff,\n thread_unwound: 0xb2ccd8ff,\n thread_error: 0xb23219ff,\n breakpoint: 0xa72911ff,\n\n floating:\n {\n background: 0x1b1b1baf,\n background: alt: 0x0000005f,\n background: fresh: 0x31393d5f,\n border: 0xbfbfbf1f,\n scroll_bar:\n {\n background: 0x3b3b3b5f,\n border: 0x5f5f5f5f,\n }\n }\n\n menu_bar:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n\n scroll_bar:\n {\n background: 0x2b2b2bff,\n border: 0x3f3f3fff,\n }\n\n implicit:\n {\n background: 0x00000000,\n border: 0x00000000,\n }\n\n hollow:\n {\n background: 0x00000000,\n border: 0xffffff1f,\n }\n\n tab:\n {\n background: 0x6f5135ff,\n border: 0x8a6e54ff,\n inactive:\n {\n background: 0x2b3740ff,\n border: 0x3e4c57ff,\n }\n auto:\n {\n background: 0x693847ff,\n border: 0x9e6274ff,\n inactive:\n {\n background: 0x2f2633ff,\n border: 0x685073ff,\n }\n }\n }\n\n drop_site:\n {\n background: 0xffffff05,\n border: 0xffffff0f,\n }\n}\n"), +str8_lit_comp("theme:\n{\n color: {tags:\"background\", value: 0x1b1b1bff }\n color: {tags:\"alt background\", value: 0x222222ff }\n color: {tags:\"pop background\", value: 0x355b6eff }\n color: {tags:\"fresh background\", value: 0x31393dff }\n color: {tags:\"match background\", value: 0x31393dff }\n color: {tags:\"border\", value: 0x404040ff }\n color: {tags:\"text\", value: 0xe5e5e5ff }\n color: {tags:\"weak text\", value: 0xa4a4a4ff }\n color: {tags:\"good text\", value: 0x32a852ff }\n color: {tags:\"bad text\", value: 0xcf5242ff }\n color: {tags:\"hover\", value: 0xffffffff }\n color: {tags:\"focus\", value: 0xfda200ff }\n color: {tags:\"cursor\", value: 0x8aff00ff }\n color: {tags:\"selection\", value: 0x99ccffff }\n color: {tags:\"inactive background\", value: 0x0000002f }\n color: {tags:\"drop_shadow\", value: 0x0000007f }\n color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n color: {tags:\"good_pop border\", value: 0x568761ff }\n color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n color: {tags:\"bad_pop background\", value: 0x803425ff }\n color: {tags:\"bad_pop hover\", value: 0xff825cff }\n color: {tags:\"code_default\", value: 0xcbcbcbff }\n color: {tags:\"code_symbol\", value: 0x42a2cfff }\n color: {tags:\"code_type\", value: 0xfec746ff }\n color: {tags:\"code_local\", value: 0x98bc80ff }\n color: {tags:\"code_register\", value: 0xb7afd5ff }\n color: {tags:\"code_keyword\", value: 0xb38d4cff }\n color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n color: {tags:\"code_numeric\", value: 0x98abb1ff }\n color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n color: {tags:\"code_string\", value: 0x98abb1ff }\n color: {tags:\"code_meta\", value: 0xd96759ff }\n color: {tags:\"code_comment\", value: 0x717171ff }\n color: {tags:\"line_info_0\", value: 0x4f3022ff }\n color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n color: {tags:\"line_info_2\", value: 0x434e2aff }\n color: {tags:\"line_info_3\", value: 0x36241fff }\n color: {tags:\"line_info_4\", value: 0x4f3022ff }\n color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n color: {tags:\"line_info_6\", value: 0x434e2aff }\n color: {tags:\"line_info_7\", value: 0x36241fff }\n color: {tags:\"thread_0\", value: 0xffcb7fff }\n color: {tags:\"thread_1\", value: 0xb2ff65ff }\n color: {tags:\"thread_2\", value: 0xff99e5ff }\n color: {tags:\"thread_3\", value: 0x6598ffff }\n color: {tags:\"thread_4\", value: 0x65ffcbff }\n color: {tags:\"thread_5\", value: 0xff9819ff }\n color: {tags:\"thread_6\", value: 0x9932ffff }\n color: {tags:\"thread_7\", value: 0x65ff4cff }\n color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n color: {tags:\"thread_error\", value: 0xb23219ff }\n color: {tags:\"breakpoint\", value: 0xa72911ff }\n color: {tags:\"floating background\", value: 0x1b1b1baf }\n color: {tags:\"floating background alt\", value: 0x0000005f }\n color: {tags:\"floating background fresh\", value: 0x31393d5f }\n color: {tags:\"floating border\", value: 0xbfbfbf1f }\n color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n color: {tags:\"implicit background\", value: 0x00000000 }\n color: {tags:\"implicit border\", value: 0x00000000 }\n color: {tags:\"hollow background\", value: 0x00000000 }\n color: {tags:\"hollow border\", value: 0xffffff1f }\n color: {tags:\"tab background\", value: 0x6f5135ff }\n color: {tags:\"tab border\", value: 0x8a6e54ff }\n color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n color: {tags:\"tab auto background\", value: 0x693847ff }\n color: {tags:\"tab auto border\", value: 0x9e6274ff }\n color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n color: {tags:\"drop_site background\", value: 0xffffff05 }\n color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index ee29a4df..554dbcaf 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -362,7 +362,7 @@ RD_VocabTable: @collection_commands(add_color, import_colors) x: { @display_name('Tags') tags: string, - color: @color @hex u32, + @display_name('Value') value: @color @hex u32, } ``` } @@ -1299,132 +1299,83 @@ RD_ThemePresetTable: DefaultDark default_dark "Default (Dark)", ```theme: { - background: 0x1b1b1bff, - alt: background: 0x222222ff, - pop: background: 0x355b6eff, - fresh: background: 0x31393dff, - match: background: 0x31393dff, - border: 0x404040ff, - text: 0xe5e5e5ff, - weak: text: 0xa4a4a4ff, - good: text: 0x32a852ff, - bad: text: 0xcf5242ff, - hover: 0xffffffff, - focus: 0xfda200ff, - cursor: 0x8aff00ff, - selection: 0x99ccffff, - inactive: background: 0x0000002f, - drop_shadow: 0x0000007f, - - good_pop: - { - background: 0x2c5b36ff, - border: 0x568761ff, - hover: 0xe3f5d3ff, - weak: text: 0xe3f5d3ff, - } - - bad_pop: - { - background: 0x803425ff, - hover: 0xff825cff, - } - - code_default: 0xcbcbcbff, - code_symbol: 0x42a2cfff, - code_type: 0xfec746ff, - code_local: 0x98bc80ff, - code_register: 0xb7afd5ff, - code_keyword: 0xb38d4cff, - code_delimiter_or_operator: 0x767676ff, - code_numeric: 0x98abb1ff, - code_numeric_alt_digit_group: 0x738287ff, - code_string: 0x98abb1ff, - code_meta: 0xd96759ff, - code_comment: 0x717171ff, - line_info_0: 0x4f3022ff, - line_info_1: 0x4f3e15ff, - line_info_2: 0x434e2aff, - line_info_3: 0x36241fff, - line_info_4: 0x4f3022ff, - line_info_5: 0x4f3e15ff, - line_info_6: 0x434e2aff, - line_info_7: 0x36241fff, - thread_0: 0xffcb7fff, - thread_1: 0xb2ff65ff, - thread_2: 0xff99e5ff, - thread_3: 0x6598ffff, - thread_4: 0x65ffcbff, - thread_5: 0xff9819ff, - thread_6: 0x9932ffff, - thread_7: 0x65ff4cff, - thread_unwound: 0xb2ccd8ff, - thread_error: 0xb23219ff, - breakpoint: 0xa72911ff, - - floating: - { - background: 0x1b1b1baf, - background: alt: 0x0000005f, - background: fresh: 0x31393d5f, - border: 0xbfbfbf1f, - scroll_bar: - { - background: 0x3b3b3b5f, - border: 0x5f5f5f5f, - } - } - - menu_bar: - { - background: 0x2b3740ff, - border: 0x3e4c57ff, - } - - scroll_bar: - { - background: 0x2b2b2bff, - border: 0x3f3f3fff, - } - - implicit: - { - background: 0x00000000, - border: 0x00000000, - } - - hollow: - { - background: 0x00000000, - border: 0xffffff1f, - } - - tab: - { - background: 0x6f5135ff, - border: 0x8a6e54ff, - inactive: - { - background: 0x2b3740ff, - border: 0x3e4c57ff, - } - auto: - { - background: 0x693847ff, - border: 0x9e6274ff, - inactive: - { - background: 0x2f2633ff, - border: 0x685073ff, - } - } - } - - drop_site: - { - background: 0xffffff05, - border: 0xffffff0f, - } + color: {tags:"background", value: 0x1b1b1bff } + color: {tags:"alt background", value: 0x222222ff } + color: {tags:"pop background", value: 0x355b6eff } + color: {tags:"fresh background", value: 0x31393dff } + color: {tags:"match background", value: 0x31393dff } + color: {tags:"border", value: 0x404040ff } + color: {tags:"text", value: 0xe5e5e5ff } + color: {tags:"weak text", value: 0xa4a4a4ff } + color: {tags:"good text", value: 0x32a852ff } + color: {tags:"bad text", value: 0xcf5242ff } + color: {tags:"hover", value: 0xffffffff } + color: {tags:"focus", value: 0xfda200ff } + color: {tags:"cursor", value: 0x8aff00ff } + color: {tags:"selection", value: 0x99ccffff } + color: {tags:"inactive background", value: 0x0000002f } + color: {tags:"drop_shadow", value: 0x0000007f } + color: {tags:"good_pop background", value: 0x2c5b36ff } + color: {tags:"good_pop border", value: 0x568761ff } + color: {tags:"good_pop hover", value: 0xe3f5d3ff } + color: {tags:"good_pop weak text", value: 0xe3f5d3ff } + color: {tags:"bad_pop background", value: 0x803425ff } + color: {tags:"bad_pop hover", value: 0xff825cff } + color: {tags:"code_default", value: 0xcbcbcbff } + color: {tags:"code_symbol", value: 0x42a2cfff } + color: {tags:"code_type", value: 0xfec746ff } + color: {tags:"code_local", value: 0x98bc80ff } + color: {tags:"code_register", value: 0xb7afd5ff } + color: {tags:"code_keyword", value: 0xb38d4cff } + color: {tags:"code_delimiter_or_operator", value: 0x767676ff } + color: {tags:"code_numeric", value: 0x98abb1ff } + color: {tags:"code_numeric_alt_digit_group", value: 0x738287ff } + color: {tags:"code_string", value: 0x98abb1ff } + color: {tags:"code_meta", value: 0xd96759ff } + color: {tags:"code_comment", value: 0x717171ff } + color: {tags:"line_info_0", value: 0x4f3022ff } + color: {tags:"line_info_1", value: 0x4f3e15ff } + color: {tags:"line_info_2", value: 0x434e2aff } + color: {tags:"line_info_3", value: 0x36241fff } + color: {tags:"line_info_4", value: 0x4f3022ff } + color: {tags:"line_info_5", value: 0x4f3e15ff } + color: {tags:"line_info_6", value: 0x434e2aff } + color: {tags:"line_info_7", value: 0x36241fff } + color: {tags:"thread_0", value: 0xffcb7fff } + color: {tags:"thread_1", value: 0xb2ff65ff } + color: {tags:"thread_2", value: 0xff99e5ff } + color: {tags:"thread_3", value: 0x6598ffff } + color: {tags:"thread_4", value: 0x65ffcbff } + color: {tags:"thread_5", value: 0xff9819ff } + color: {tags:"thread_6", value: 0x9932ffff } + color: {tags:"thread_7", value: 0x65ff4cff } + color: {tags:"thread_unwound", value: 0xb2ccd8ff } + color: {tags:"thread_error", value: 0xb23219ff } + color: {tags:"breakpoint", value: 0xa72911ff } + color: {tags:"floating background", value: 0x1b1b1baf } + color: {tags:"floating background alt", value: 0x0000005f } + color: {tags:"floating background fresh", value: 0x31393d5f } + color: {tags:"floating border", value: 0xbfbfbf1f } + color: {tags:"floating scroll_bar background", value: 0x3b3b3b5f } + color: {tags:"floating scroll_bar border", value: 0x5f5f5f5f } + color: {tags:"menu_bar background", value: 0x2b3740ff } + color: {tags:"menu_bar border", value: 0x3e4c57ff } + color: {tags:"scroll_bar background", value: 0x2b2b2bff } + color: {tags:"scroll_bar border", value: 0x3f3f3fff } + color: {tags:"implicit background", value: 0x00000000 } + color: {tags:"implicit border", value: 0x00000000 } + color: {tags:"hollow background", value: 0x00000000 } + color: {tags:"hollow border", value: 0xffffff1f } + color: {tags:"tab background", value: 0x6f5135ff } + color: {tags:"tab border", value: 0x8a6e54ff } + color: {tags:"tab inactive background", value: 0x2b3740ff } + color: {tags:"tab inactive border", value: 0x3e4c57ff } + color: {tags:"tab auto background", value: 0x693847ff } + color: {tags:"tab auto border", value: 0x9e6274ff } + color: {tags:"tab auto inactive background", value: 0x2f2633ff } + color: {tags:"tab auto inactive border", value: 0x685073ff } + color: {tags:"drop_site background", value: 0xffffff05 } + color: {tags:"drop_site border", value: 0xffffff0f } } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a9c353a2..c79d8a35 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5498,27 +5498,23 @@ rd_window_frame(void) // that windows can have their own colors, and have those override higher-up settings. RD_Cfg *preset_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; - RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("theme")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; + RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; for EachElement(idx, scan_parents) { - for(RD_Cfg *parent_cfg = scan_parents[idx]; parent_cfg != &rd_nil_cfg; parent_cfg = parent_cfg->parent) + RD_Cfg *parent_cfg = scan_parents[idx]; + if(preset_cfg != &rd_nil_cfg) { - if(preset_cfg != &rd_nil_cfg) + RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); + if(possible_preset_cfg != &rd_nil_cfg) { - RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); - if(possible_preset_cfg != &rd_nil_cfg) - { - preset_cfg = possible_preset_cfg; - } + preset_cfg = possible_preset_cfg; } - RD_Cfg *colors_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("colors")); - if(colors_cfg != &rd_nil_cfg) + } + for(RD_Cfg *child = parent_cfg->first; child != &rd_nil_cfg; child = child->next) + { + if(str8_match(child->string, str8_lit("color"), 0)) { - rd_cfg_list_push_front(scratch.arena, &colors_cfgs, colors_cfg); - } - if(preset_cfg != &rd_nil_cfg && colors_cfg != &rd_nil_cfg) - { - break; + rd_cfg_list_push_front(scratch.arena, &colors_cfgs, child); } } } @@ -5553,7 +5549,7 @@ rd_window_frame(void) for(RD_CfgNode *n = colors_cfgs.first; n != 0; n = n->next) { ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); - SLLQueuePush(first_task, last_task, t); + SLLQueuePushFront(first_task, last_task, t); t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); } } @@ -5574,17 +5570,14 @@ rd_window_frame(void) MD_Node *tree_root = t->tree; for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) { - if(n->flags & MD_NodeFlag_Numeric && md_node_is_nil(n->first)) + if(str8_match(n->string, str8_lit("color"), 0)) { - U64 color_srgba_u64 = 0; - try_u64_from_str8_c_rules(n->string, &color_srgba_u64); - Vec4F32 color_srgba = rgba_from_u32((U32)color_srgba_u64); - Vec4F32 color_linear = linear_from_srgba(color_srgba); - String8List tags = {0}; - for(MD_Node *parent = n->parent; parent != tree_root && !md_node_is_nil(parent); parent = parent->parent) - { - str8_list_push(scratch.arena, &tags, push_str8_copy(rd_frame_arena(), parent->string)); - } + MD_Node *tags_child = md_child_from_string(n, str8_lit("tags"), 0); + MD_Node *value_child = md_child_from_string(n, str8_lit("value"), 0); + U8 split_char = ' '; + String8List tags = str8_split(scratch.arena, tags_child->first->string, &split_char, 1, 0); + U32 color_u32 = e_value_from_string(value_child->first->string).u32; + Vec4F32 color_linear = linear_from_srgba(rgba_from_u32(color_u32)); ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); node->pattern.tags = str8_array_from_list(rd_frame_arena(), &tags); node->pattern.linear = color_linear; @@ -15209,8 +15202,22 @@ rd_frame(void) { rd_cfg_release(n->v); } - // String8 color_preset = rd_setting_from_name(str8_lit("color_preset")); - // String8 color_file = rd_setting_from_name(str8_lit("color_file")); + String8 color_preset = rd_setting_from_name(str8_lit("color_preset")); + String8 color_file = rd_setting_from_name(str8_lit("color_file")); + RD_ThemePreset preset = RD_ThemePreset_DefaultDark; + // TODO(rjf): map preset via string + MD_Node *theme_tree = rd_state->theme_preset_trees[preset]; + for(MD_Node *n = theme_tree; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next) + { + if(str8_match(n->string, str8_lit("color"), 0)) + { + RD_Cfg *color = rd_cfg_new(parent, str8_lit("color")); + RD_Cfg *tags = rd_cfg_new(color, str8_lit("tags")); + RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); + rd_cfg_new(tags, md_child_from_string(n, str8_lit("tags"), 0)->first->string); + rd_cfg_new(value, md_child_from_string(n, str8_lit("value"), 0)->first->string); + } + } }break; //- rjf: watches diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9f6f31e0..135476df 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3648,10 +3648,11 @@ RD_VIEW_UI_FUNCTION_DEF(color) RD_Font(RD_FontSlot_Code) { UI_Signal sv_sig = ui_sat_val_pickerf(hsva.x, &hsva.y, &hsva.z, "sat_val_picker"); + UI_Signal h_sig = {0}; ui_spacer(ui_em(1.f, 1.f)); UI_PrefWidth(ui_em(3.f, 1.f)) { - UI_Signal h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); + h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); } ui_spacer(ui_em(1.f, 1.f)); UI_PrefWidth(ui_children_sum(1)) UI_Column @@ -3690,6 +3691,18 @@ RD_VIEW_UI_FUNCTION_DEF(color) } } } + if(ui_dragging(h_sig) || ui_dragging(sv_sig)) + { + // TODO(rjf): hard-coding U32 committing for now + E_Type *type = e_type_from_key__cached(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + if(type->kind == E_TypeKind_U32) + { + Vec4F32 new_rgba = rgba_from_hsva(hsva); + U32 u32 = u32_from_rgba(new_rgba); + String8 string = push_str8f(scratch.arena, "0x%x", u32); + rd_commit_eval_value_string(eval, string); + } + } } } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 7d5c8d70..bff716a4 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -397,9 +397,9 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) if(str8_match(cfg->string, str8_lit("color"), 0)) { String8 tags = rd_cfg_child_from_string(cfg, str8_lit("tags"))->first->string; - String8 color_string = rd_cfg_child_from_string(cfg, str8_lit("color"))->first->string; + String8 color_string = rd_cfg_child_from_string(cfg, str8_lit("value"))->first->string; U32 color_u32 = e_value_from_stringf("(uint32)(%S)", color_string).u32; - Vec4F32 color = rgba_from_u32(color_u32); + Vec4F32 color = linear_from_srgba(rgba_from_u32(color_u32)); if(tags.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, tags, .color = color); From 693ba7d077a51b786d24f5779741dad00640df80 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 20:49:03 -0700 Subject: [PATCH 470/755] fix 'cut' event being missed in standalone cell --- src/raddbg/raddbg_core.c | 2 ++ src/ui/ui_core.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c79d8a35..c180c27a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4535,6 +4535,7 @@ rd_view_ui(Rng2F32 rect) else { // rjf: compute visual params + ProfBegin("compute visual params"); B32 cell_has_fancy_editors = (!(cell->flags & RD_WatchCellFlag_NoEval)); B32 is_button = !!(cell_info.flags & RD_WatchCellFlag_Button); B32 has_background = !!(cell_info.flags & RD_WatchCellFlag_Background); @@ -4549,6 +4550,7 @@ rd_view_ui(Rng2F32 rect) is_button = 0; is_activated_on_single_click = 0; } + ProfEnd(); // rjf: determine query needle String8 needle = rd_view_query_input(); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 70abe70e..38f94cac 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2810,6 +2810,7 @@ ui_signal_from_box(UI_Box *box) //- rjf: focus is hot & copy event -> remember to copy this box tree's text content if(is_focus_hot && evt->flags & UI_EventFlag_Copy && + !(evt->flags & UI_EventFlag_Delete) && !ui_key_match(ui_key_zero(), box->key)) { ui_state->clipboard_copy_key = box->key; From 66187931aac72114a33d34079e55d5020c698455 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 26 Apr 2025 21:41:27 -0700 Subject: [PATCH 471/755] accept font names, as well as font paths --- src/font_cache/font_cache.c | 20 ++++--- .../dwrite/font_provider_dwrite.c | 58 +++++++++++++++++-- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 6 +- src/raddbg/raddbg_core.c | 11 ++-- src/raddbg/raddbg_main.c | 7 +-- 6 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index 9754f352..44fea4d1 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -141,16 +141,22 @@ fnt_tag_from_path(String8 path) } //- rjf: allocate & push new node if we don't have an existing one - FNT_FontHashNode *new_node = 0; if(existing_node == 0) { + FP_Handle handle = fp_font_open(path); FNT_FontHashSlot *slot = &fnt_state->font_hash_table[slot_idx]; - new_node = push_array(fnt_state->permanent_arena, FNT_FontHashNode, 1); - new_node->tag = result; - new_node->handle = fp_font_open(path); - new_node->metrics = fp_metrics_from_font(new_node->handle); - new_node->path = push_str8_copy(fnt_state->permanent_arena, path); - SLLQueuePush_N(slot->first, slot->last, new_node, hash_next); + existing_node = push_array(fnt_state->permanent_arena, FNT_FontHashNode, 1); + existing_node->tag = result; + existing_node->handle = handle; + existing_node->metrics = fp_metrics_from_font(existing_node->handle); + existing_node->path = push_str8_copy(fnt_state->permanent_arena, path); + SLLQueuePush_N(slot->first, slot->last, existing_node, hash_next); + } + + //- rjf: tag result must be zero if this is not a valid font + if(fp_handle_match(existing_node->handle, fp_handle_zero())) + { + MemoryZeroStruct(&result); } //- rjf: return diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 4770ebba..ebf81ff4 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -318,18 +318,64 @@ fp_font_open(String8 path) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - String16 path16 = str16_from_8(scratch.arena, path); FP_DWrite_Font font = {0}; HRESULT error = 0; - //- rjf: open font file reference - error = IDWriteFactory_CreateFontFileReference(fp_dwrite_state->factory, (WCHAR *)path16.str, 0, &font.file); + //- rjf: build initial path task + typedef struct PathTask PathTask; + struct PathTask + { + PathTask *next; + String8 path; + }; + PathTask start_task = {0, path}; + PathTask *first_task = &start_task; + PathTask *last_task = first_task; - //- rjf: open font face - error = IDWriteFactory_CreateFontFace(fp_dwrite_state->factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font.file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font.face); + //- rjf: try to open font + for(PathTask *t = first_task; t != 0 && font.file == 0; t = t->next) + { + String16 path16 = str16_from_8(scratch.arena, t->path); + error = IDWriteFactory_CreateFontFileReference(fp_dwrite_state->factory, (WCHAR *)path16.str, 0, &font.file); + error = IDWriteFactory_CreateFontFace(fp_dwrite_state->factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font.file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font.face); + + // rjf: failure trying just the normal path? -> generate new tasks that search in system folders + if(t == first_task && font.file == 0) + { + // rjf: generate task for user-installed fonts + { + HKEY reg_key = 0; + LSTATUS status = 0; + char name[256] = {0}; + char data[256] = {0}; + DWORD name_size = sizeof(name); + DWORD data_size = sizeof(data); + DWORD type = 0; + status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Fonts", 0, KEY_QUERY_VALUE, ®_key); + status = RegEnumValueA(reg_key, 0, name, &name_size, 0, &type, data, &data_size); + String8 user_fonts_path = str8_cstring(data); + PathTask *task = push_array(scratch.arena, PathTask, 1); + task->path = push_str8f(scratch.arena, "%s/%S", user_fonts_path, path); + SLLQueuePush(first_task, last_task, task); + } + + // rjf: generate task for windows directory (C:/Windows/Fonts, generally) + { + char windows_path[256] = {0}; + GetWindowsDirectoryA(windows_path, sizeof(windows_path)); + PathTask *task = push_array(scratch.arena, PathTask, 1); + task->path = push_str8f(scratch.arena, "%s/Fonts/%S", windows_path, path); + SLLQueuePush(first_task, last_task, task); + } + } + } //- rjf: handlify & return - FP_Handle handle = fp_dwrite_handle_from_font(font); + FP_Handle handle = {0}; + if(font.file != 0) + { + handle = fp_dwrite_handle_from_font(font); + } scratch_end(scratch); ProfEnd(); return handle; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0a4ace89..339f75e6 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -377,7 +377,7 @@ RD_VocabInfo rd_vocab_info_table[319] = RD_NameSchemaInfo rd_name_schema_info_table[22] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n 'main_font': string,\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name or path to the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name or path to the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 554dbcaf..77fb96be 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -225,8 +225,10 @@ RD_VocabTable: @default(1) 'scrolling_animations': bool, //- rjf: fonts - 'main_font': string, - 'code_font': string, + @display_name('UI Font') @description("The name or path to the font used when displaying non-code UI elements.") + 'main_font': string, + @display_name('Code Font') @description("The name or path to the font used when displaying code.") + 'code_font': string, //- rjf: colors @display_name('Color Preset') diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c180c27a..973e5741 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10394,7 +10394,11 @@ rd_font_from_slot(RD_FontSlot slot) // rjf: map name -> tag FNT_Tag result = {0}; - if(font_name.size == 0) + if(font_name.size != 0) + { + result = fnt_tag_from_path(font_name); + } + if(font_name.size == 0 || fnt_tag_match(fnt_tag_zero(), result)) { switch(slot) { @@ -10404,11 +10408,6 @@ rd_font_from_slot(RD_FontSlot slot) case RD_FontSlot_Icons:{result = fnt_tag_from_static_data_string(&rd_icon_font_bytes);}break; } } - else - { - // TODO(rjf): need to handle "system font names" here. - result = fnt_tag_from_path(font_name); - } return result; } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 4783e43e..a6c1515f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -207,10 +207,6 @@ //////////////////////////////// //~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup) // -// [ ] Setting the code_font/main_font values to a font name doesn't work. -// Should probably make note that you have to set it to a path to a TTF, -// since that's not normally how Windows fonts work. -// // [ ] "root" concept in hash store, which buckets keys & allows usage code to // jettison a collection of keys in retained mode fashion // @@ -422,6 +418,9 @@ // size dynamically // [x] automatically start search query with selected text // [x] @feature processor/data breakpoints +// [x] Setting the code_font/main_font values to a font name doesn't work. +// Should probably make note that you have to set it to a path to a TTF, +// since that's not normally how Windows fonts work. //////////////////////////////// //~ rjf: Build Options From 93b1e3988d098d947d2e31e6c3b332485627b5cf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 27 Apr 2025 20:32:36 -0700 Subject: [PATCH 472/755] notes --- src/raddbg/raddbg_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index a6c1515f..138768e7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -40,7 +40,7 @@ // the editing of bindings, just like the old command palette (although it // now also supports searching for command bindings themselves, in addition // to the original searching support for command names and descriptions). -// However, this palette now also lists: targets, breakpoints, recent files, +// However, this palette now also lists targets, breakpoints, recent files, // recent projects, settings (including tab settings, window settings, user // settings, project settings), attached processes, threads, modules, // functions, types, and global variables. This can be used to quickly search @@ -53,6 +53,10 @@ // which can be edited within the palette or a tab's right-click menu. If a // tab has no per-tab font size set, then it inherits the setting from the // window's font size. +// - The fonts which the debugger uses can now be set through settings UI +// (including the palette). +// - The debugger now accepts system font file names in addition to full font +// file paths to specify font settings. // - Expressions inserted into a `Watch` tab are now stored per-tab. This makes // many `Watch` tabs more useful, since different tabs can have a different // set of expressions. `Watch` tabs can now also be labeled, so you can @@ -249,9 +253,6 @@ // color to white (or the inverse of the background color, or whatever) so // that the user can see what things on the screen use that theme color. // -// [ ] I had to go into the user file to change the font. That should probably -// be in the theme window? -// // [ ] It'd be nice to have a "goto byte" option for source views, for jumping // to error messages that are byte-based instead of line-based. // @@ -421,6 +422,8 @@ // [x] Setting the code_font/main_font values to a font name doesn't work. // Should probably make note that you have to set it to a path to a TTF, // since that's not normally how Windows fonts work. +// [x] I had to go into the user file to change the font. That should probably +// be in the theme window? //////////////////////////////// //~ rjf: Build Options From 81425e8b909f538b0d585a14f6153edfab3444d3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 10:25:37 -0700 Subject: [PATCH 473/755] use more stable IDs for ctrl entity evaluations --- src/ctrl/ctrl_core.c | 10 ---------- src/ctrl/ctrl_core.h | 1 - src/raddbg/raddbg_core.c | 16 ++++++++++++++-- src/raddbg/raddbg_eval.c | 25 ++++++++++++++++++++++++- src/raddbg/raddbg_eval.h | 5 +++++ src/raddbg/raddbg_views.c | 2 +- 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index a8bb074b..1807a1e3 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -217,16 +217,6 @@ ctrl_handle_from_string(String8 string) return handle; } -internal E_Eval -ctrl_eval_from_handle(CTRL_Handle handle) -{ - Temp scratch = scratch_begin(0, 0); - String8 string = ctrl_string_from_handle(scratch.arena, handle); - E_Eval eval = e_eval_from_string(string); - scratch_end(scratch); - return eval; -} - //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 84af61bb..73f6b2c2 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -771,7 +771,6 @@ internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Ha internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle); internal CTRL_Handle ctrl_handle_from_string(String8 string); -internal E_Eval ctrl_eval_from_handle(CTRL_Handle handle); //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 973e5741..a7b2bedb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3269,7 +3269,7 @@ rd_view_ui(Rng2F32 rect) case RD_EvalSpaceKind_MetaCtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - rd_cmd(RD_CmdKind_PushQuery, .expr = ctrl_string_from_handle(scratch.arena, entity->handle)); + rd_cmd(RD_CmdKind_PushQuery, .expr = push_str8f(scratch.arena, "query:control.%S", ctrl_string_from_handle(scratch.arena, entity->handle))); }break; } if(did_cmd) @@ -11995,6 +11995,19 @@ rd_frame(void) e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); } + //- rjf: add macro for top-level control root + { + String8 name = str8_lit("control"); + E_TypeKey type_key = e_type_key_cons(.name = name, + .kind = E_TypeKind_Set, + .access = E_TYPE_ACCESS_FUNCTION_NAME(control)); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, name, type_key); + } + //- rjf: add macros for config "slice" collections (targets, breakpoints, etc.) String8 evallable_cfg_names[] = { @@ -12209,7 +12222,6 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - e_string2expr_map_insert(scratch.arena, macro_map, ctrl_string_from_handle(scratch.arena, entity->handle), expr); if(entity->string.size != 0) { e_string2expr_map_insert(scratch.arena, macro_map, entity->string, expr); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 02e78aa7..848d6880 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -554,6 +554,27 @@ E_TYPE_ACCESS_FUNCTION_DEF(cfgs) return result; } +//////////////////////////////// +//~ rjf: Control Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(control) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + E_Expr *rhs = expr->first->next; + if(rhs->kind == E_ExprKind_LeafIdentifier && + str8_match(str8_prefix(rhs->string, 1), str8_lit("$"), 0)) + { + CTRL_Handle handle = ctrl_handle_from_string(rhs->string); + CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); + result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); + result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); + result.mode = E_Mode_Offset; + } + return result; +} + + //////////////////////////////// //~ rjf: Config Collection Type Hooks @@ -1329,8 +1350,10 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(ctrl_entities) U64 read_count = dim_1u64(read_range); for(U64 out_idx = 0; out_idx < read_count; out_idx += 1) { + Temp scratch = scratch_begin(&arena, 1); CTRL_Entity *entity = entities->v[out_idx + read_range.min]; - evals_out[out_idx] = ctrl_eval_from_handle(entity->handle); + evals_out[out_idx] = e_eval_from_stringf("query:control.%S", ctrl_string_from_handle(scratch.arena, entity->handle)); + scratch_end(scratch); } } diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 2edc84c0..fdf8785b 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -36,6 +36,11 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema); E_TYPE_ACCESS_FUNCTION_DEF(cfgs); +//////////////////////////////// +//~ rjf: Control Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(control); + //////////////////////////////// //~ rjf: Config Slice Type Hooks diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 135476df..240dfae1 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1387,7 +1387,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.cell_style_key = str8_lit("call_stack_frame"); CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); - E_Eval module_eval = ctrl_eval_from_handle(module->handle); + E_Eval module_eval = e_eval_from_stringf("query:control.%S", ctrl_string_from_handle(scratch.arena, module->handle)); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); RD_Cfg *w_cfg = style->first; From c62ad20a9ae97547ca0d509bf819e1a691f01e70 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 11:50:23 -0700 Subject: [PATCH 474/755] switch cast expressions from being formally represented in the expression tree - instead use cast-like tree shapes to perform casts in the ir/typechecking phase. this is odd, given C's casting syntax, but it is much more natural given that the parser is not any longer doing identifier resolution, and as such it fixes a bunch of nasty edge cases. --- src/eval/eval.mdesk | 97 +++++++------- src/eval/eval_core.c | 41 ++++-- src/eval/eval_ir.c | 203 ++++++++++++++++++++++++----- src/eval/eval_ir.h | 2 +- src/eval/eval_parse.c | 24 +++- src/eval/eval_types.c | 2 +- src/eval/generated/eval.meta.c | 6 +- src/eval/generated/eval.meta.h | 5 +- src/lib_rdi_format/rdi_format.c | 12 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 53 +++++--- src/rdi_format/rdi_format.mdesk | 4 +- 13 files changed, 325 insertions(+), 130 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 5717a44d..46891e5d 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -82,63 +82,64 @@ E_TypeKindTable: @table(name op_kind precedence op_pre op_sep op_pos op_chain) E_ExprKindTable: { - { Nil Null 0 "" "" "" "" } - { Ref Null 0 "" "" "" "" } + { Nil Null 0 "" "" "" "" } + { Ref Null 0 "" "" "" "" } - { ArrayIndex Null 0 "" "[" "]" "" } - { MemberAccess Null 0 "" "." "" "" } - { Deref UnaryPrefix 2 "*" "" "" "" } - { Address UnaryPrefix 2 "&" "" "" "" } + { ArrayIndex Null 0 "" "[" "]" "" } + { MemberAccess Null 0 "" "." "" "" } + { Deref UnaryPrefix 2 "*" "" "" "" } + { Address UnaryPrefix 2 "&" "" "" "" } - { Cast Null 1 "(" ")" "" "" } - { Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" } - { Typeof UnaryPrefix 1 "typeof" "(" ")" "" } - { ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" } + { Cast Null 1 "(" ")" "" "" } + { Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" } + { Typeof UnaryPrefix 1 "typeof" "(" ")" "" } + { ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" } - { Pos UnaryPrefix 2 "+" "" "" "" } - { Neg UnaryPrefix 2 "-" "" "" "" } - { LogNot UnaryPrefix 2 "!" "" "" "" } - { BitNot UnaryPrefix 2 "~" "" "" "" } - { Mul Binary 3 "" " * " "" "" } - { Div Binary 3 "" " / " "" "" } - { Mod Binary 3 "" " % " "" "" } - { Add Binary 4 "" " + " "" "" } - { Sub Binary 4 "" " - " "" "" } - { LShift Binary 5 "" " << " "" "" } - { RShift Binary 5 "" " >> " "" "" } - { Less Binary 6 "" " < " "" "" } - { LsEq Binary 6 "" " <= " "" "" } - { Grtr Binary 6 "" " > " "" "" } - { GrEq Binary 6 "" " >= " "" "" } - { EqEq Binary 7 "" " == " "" "" } - { NtEq Binary 7 "" " != " "" "" } + { Pos UnaryPrefix 2 "+" "" "" "" } + { Neg UnaryPrefix 2 "-" "" "" "" } + { LogNot UnaryPrefix 2 "!" "" "" "" } + { BitNot UnaryPrefix 2 "~" "" "" "" } + { Mul Binary 3 "" " * " "" "" } + { Div Binary 3 "" " / " "" "" } + { Mod Binary 3 "" " % " "" "" } + { Add Binary 4 "" " + " "" "" } + { Sub Binary 4 "" " - " "" "" } + { LShift Binary 5 "" " << " "" "" } + { RShift Binary 5 "" " >> " "" "" } + { Less Binary 6 "" " < " "" "" } + { LsEq Binary 6 "" " <= " "" "" } + { Grtr Binary 6 "" " > " "" "" } + { GrEq Binary 6 "" " >= " "" "" } + { EqEq Binary 7 "" " == " "" "" } + { NtEq Binary 7 "" " != " "" "" } - { BitAnd Binary 8 "" " & " "" "" } - { BitXor Binary 9 "" " ^ " "" "" } - { BitOr Binary 10 "" " | " "" "" } - { LogAnd Binary 11 "" " && " "" "" } - { LogOr Binary 12 "" " || " "" "" } + { BitAnd Binary 8 "" " & " "" "" } + { BitXor Binary 9 "" " ^ " "" "" } + { BitOr Binary 10 "" " | " "" "" } + { LogAnd Binary 11 "" " && " "" "" } + { LogOr Binary 12 "" " || " "" "" } - { Ternary Null 0 "" " ? " " : " "" } + { Ternary Null 0 "" " ? " " : " "" } - { Call Null 15 "" "(" ")" ", "} + { Call Null 15 "" "(" ")" ", "} - { LeafBytecode Null 0 "" "" "" "" } - { LeafStringLiteral Null 0 "" "" "" "" } - { LeafU64 Null 0 "" "" "" "" } - { LeafF64 Null 0 "" "" "" "" } - { LeafF32 Null 0 "" "" "" "" } - { LeafIdentifier Null 0 "" "" "" "" } - { LeafOffset Null 0 "" "" "" "" } - { LeafValue Null 0 "" "" "" "" } - { LeafFilePath Null 0 "" "" "" "" } + { LeafBytecode Null 0 "" "" "" "" } + { LeafStringLiteral Null 0 "" "" "" "" } + { LeafU64 Null 0 "" "" "" "" } + { LeafF64 Null 0 "" "" "" "" } + { LeafF32 Null 0 "" "" "" "" } + { LeafIdentifier Null 0 "" "" "" "" } + { LeafOffset Null 0 "" "" "" "" } + { LeafValue Null 0 "" "" "" "" } + { LeafFilePath Null 0 "" "" "" "" } - { TypeIdent Null 0 "" "" "" "" } - { Ptr Null 0 "" "" "" "" } - { Array Null 0 "" "" "" "" } - { Func Null 0 "" "" "" "" } + { TypeIdent Null 0 "" "" "" "" } + { Ptr Null 0 "" "" "" "" } + { Array Null 0 "" "" "" "" } + { Func Null 0 "" "" "" "" } + { Unsigned Null 0 "unsigned " "" "" "" } - { Define Binary 13 "" " = " "" "" } + { Define Binary 13 "" " = " "" "" } } @table(name display_string) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index a0013fb8..3477e016 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -430,26 +430,41 @@ e_auto_hook_map_make(Arena *arena, U64 slots_count) internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) { + // rjf: get type key 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)) + + // rjf: get type pattern parts + String8List pattern_parts = {0}; + 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); + U8 pattern_split = '?'; + pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); } - else + + // rjf: if the type key is nonzero, *or* we have type patterns, then insert + // into map accordingle + if(!e_type_key_match(e_type_key_zero(), type_key) || + pattern_parts.node_count != 0) { - SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next); + E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); + node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key)); + node->type_pattern_parts = pattern_parts; + 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); + } } } @@ -825,7 +840,7 @@ e_irtree_from_bundle(E_CacheBundle *bundle) 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); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, 0, parse.expr); E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } @@ -1243,7 +1258,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, 0, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index f8cabbfe..450204e0 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -492,7 +492,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, 0, exprr); e_msg_list_concat_in_place(&result.msgs, &r.msgs); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -585,7 +585,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -636,7 +636,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain @@ -693,7 +693,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -752,7 +752,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); @@ -780,12 +780,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, cast_type_expr); e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -840,7 +840,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -868,7 +868,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -882,7 +882,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -910,14 +910,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -950,7 +950,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1005,8 +1005,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1229,9 +1229,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1275,18 +1275,72 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, case E_ExprKind_Call: { E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + // rjf: calling a type? -> treat as a cast of that type + if(lhs_irtree.mode == E_Mode_Null) + { + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); + e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); + E_TypeKey cast_type = lhs_irtree.type_key; + E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); + U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); + E_TypeKey casted_type = casted_tree.type_key; + E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); + U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); + U8 in_group = e_type_group_from_kind(casted_type_kind); + U8 out_group = e_type_group_from_kind(cast_type_kind); + RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); + + // rjf: bad conditions? -> error if applicable, exit + if(casted_tree.root->op == 0) + { + break; + } + else if(cast_type_kind == E_TypeKind_Null) + { + break; + } + else if(conversion_rule != RDI_EvalConversionKind_Noop && + conversion_rule != RDI_EvalConversionKind_Legal) + { + String8 text = str8_lit("Unknown cast conversion rule."); + if(conversion_rule < RDI_EvalConversionKind_COUNT) + { + text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); + } + e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); + break; + } + + // rjf: generate casted result + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); + E_IRNode *new_tree = in_tree; + if(conversion_rule == RDI_EvalConversionKind_Legal) + { + new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group); + } + if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind)) + { + new_tree = e_irtree_trunc(arena, in_tree, cast_type); + } + result.root = new_tree; + result.type_key = cast_type; + result.mode = E_Mode_Value; + } + } + // rjf: calling an unresolved leaf-identifier member access, and we can determine // that that identifer maps to a type? -> generate a call expression with the // left-hand-side of the dot operator as the first argument. this is a fast path // which prevents paren nesting in simple cases, to easily chain multiple // calls - for example, bin(2).digits(4) - if(lhs_type == &e_type_nil && - lhs->kind == E_ExprKind_MemberAccess) + else if(lhs_type == &e_type_nil && + lhs->kind == E_ExprKind_MemberAccess) { E_Expr *callee = lhs->first->next; E_Expr *first_arg = e_expr_ref(arena, lhs->first); @@ -1297,7 +1351,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { e_expr_push_child(call, e_expr_copy(arena, arg)); } - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call); E_MsgList new_msgs = {0}; e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs); e_msg_list_concat_in_place(&new_msgs, &result.msgs); @@ -1337,7 +1391,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, Temp scratch = scratch_begin(&arena, 1); // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next); // rjf: count extra arguments U64 arg_count = 0; @@ -1379,7 +1433,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, } else { - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next); result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -1522,9 +1576,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) if(!string_mapped && overridden->root != &e_irnode_nil) { - // TODO(rjf): @eval E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, 1, 1, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -1892,7 +1945,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { generated = 1; e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, macro_expr); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, macro_expr); e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); } } @@ -1977,15 +2030,45 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, result.type_key = expr->type_key; result.mode = E_Mode_Null; }break; + case E_ExprKind_Unsigned: + { + E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + result = direct_irtree; + E_TypeKey direct_type_key = result.type_key; + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(e_type_kind_is_signed(direct_type_kind)) + { + E_TypeKind new_kind = direct_type_kind; + switch(direct_type_kind) + { + default:{}break; + case E_TypeKind_Char8: {new_kind = E_TypeKind_UChar8;}break; + case E_TypeKind_Char16:{new_kind = E_TypeKind_UChar16;}break; + case E_TypeKind_Char32:{new_kind = E_TypeKind_UChar32;}break; + case E_TypeKind_S8:{new_kind = E_TypeKind_U8;}break; + case E_TypeKind_S16:{new_kind = E_TypeKind_U16;}break; + case E_TypeKind_S32:{new_kind = E_TypeKind_U32;}break; + case E_TypeKind_S64:{new_kind = E_TypeKind_U64;}break; + case E_TypeKind_S128:{new_kind = E_TypeKind_U128;}break; + case E_TypeKind_S256:{new_kind = E_TypeKind_U256;}break; + case E_TypeKind_S512:{new_kind = E_TypeKind_U512;}break; + } + result.type_key = e_type_key_basic(new_kind); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->first->location, "Cannot apply an `unsigned` modifier to this type."); + } + }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -1999,7 +2082,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, rhs); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); @@ -2007,6 +2090,66 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, }break; } + //- rjf: if our currently-computed result is just a type, and we have + // a chained expression, then treat the first expression as a cast on + // the second. + if(!disallow_chained_casts && result.mode == E_Mode_Null && expr->next != &e_expr_nil) + { + // rjf: unpack + E_IRTreeAndType cast_type_tree = result; + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->next); + e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); + E_TypeKey cast_type = cast_type_tree.type_key; + E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); + U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); + E_TypeKey casted_type = casted_tree.type_key; + E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); + U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); + U8 in_group = e_type_group_from_kind(casted_type_kind); + U8 out_group = e_type_group_from_kind(cast_type_kind); + RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); + + // rjf: bad conditions? -> error if applicable, exit + if(casted_tree.root->op == 0) + { + goto end_cast_gen; + } + else if(cast_type_kind == E_TypeKind_Null) + { + goto end_cast_gen; + } + else if(conversion_rule != RDI_EvalConversionKind_Noop && + conversion_rule != RDI_EvalConversionKind_Legal) + { + String8 text = str8_lit("Unknown cast conversion rule."); + if(conversion_rule < RDI_EvalConversionKind_COUNT) + { + text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); + } + e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); + goto end_cast_gen; + } + + // rjf: generate casted result + { + E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); + E_IRNode *new_tree = in_tree; + if(conversion_rule == RDI_EvalConversionKind_Legal) + { + new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group); + } + if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind)) + { + new_tree = e_irtree_trunc(arena, in_tree, cast_type); + } + result.root = new_tree; + result.type_key = cast_type; + result.mode = E_Mode_Value; + } + + end_cast_gen:; + } + //- rjf: check chained expressions for simple wrappers if(!disallow_chained_fastpaths) { diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index c98a70fa..314659bc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 116ddda1..1edb9733 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -672,6 +672,10 @@ e_type_key_from_expr(E_Expr *expr) { // TODO(rjf): do we support E_ExprKind_Func here? default:{}break; + case E_ExprKind_LeafIdentifier: + { + result = e_leaf_type_from_name(expr->string); + }break; case E_ExprKind_TypeIdent: { result = expr->type_key; @@ -867,6 +871,13 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } + // rjf: try 'unsigned' marker + if(str8_match(token_string, str8_lit("unsigned"), 0)) + { + prefix_unary_kind = E_ExprKind_Unsigned; + prefix_unary_precedence = 2; + } + // rjf: consume valid op if(prefix_unary_precedence != 0) { @@ -875,6 +886,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } // rjf: try casting expression +#if 0 if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) { E_Token some_type_identifier_maybe = e_token_at_it(it+1, &tokens); @@ -915,6 +927,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } } +#endif // rjf: break if we got no operators if(prefix_unary_precedence == 0) @@ -1341,7 +1354,16 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.expr; it = rhs_expr_parse.last_token; - if(rhs == &e_expr_nil) + if(rhs == &e_expr_nil && binary_kind == E_ExprKind_Mul) + { + // NOTE(rjf): C-style pointer syntax is shared with multiplication. + // carving out a special case here to allow "unfinished *s" to be + // treated as pointers instead. + E_Expr *ptee = atom; + atom = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(atom, ptee); + } + else if(rhs == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); } diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 2fa75880..b040e20f 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2477,7 +2477,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) // rjf: compute struct.base_ptr IR tree E_IRTreeAndType override = {&e_irnode_nil}; - result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, idx_expr); + result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, 0, idx_expr); scratch_end(scratch); }break; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 86a8ea6e..5577e0a1 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -144,7 +144,7 @@ U8 e_type_kind_basic_byte_size_table[61] = 0, }; -String8 e_expr_kind_strings[48] = +String8 e_expr_kind_strings[49] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -193,10 +193,11 @@ str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), +str8_lit_comp("Unsigned"), str8_lit_comp("Define"), }; -E_OpInfo e_expr_kind_op_info_table[48] = +E_OpInfo e_expr_kind_op_info_table[49] = { { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, @@ -245,6 +246,7 @@ E_OpInfo e_expr_kind_op_info_table[48] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp("unsigned "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp(" = "), str8_lit_comp(""), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 8e3e570b..e85f1b0f 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -145,6 +145,7 @@ E_ExprKind_TypeIdent, E_ExprKind_Ptr, E_ExprKind_Array, E_ExprKind_Func, +E_ExprKind_Unsigned, E_ExprKind_Define, E_ExprKind_COUNT, } E_ExprKindEnum; @@ -169,8 +170,8 @@ C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; extern String8 e_type_kind_basic_string_table[61]; extern U8 e_type_kind_basic_byte_size_table[61]; -extern String8 e_expr_kind_strings[48]; -extern E_OpInfo e_expr_kind_op_info_table[48]; +extern String8 e_expr_kind_strings[49]; +extern E_OpInfo e_expr_kind_op_info_table[49]; extern String8 e_interpretation_code_display_strings[11]; C_LINKAGE_END diff --git a/src/lib_rdi_format/rdi_format.c b/src/lib_rdi_format/rdi_format.c index 3765d03e..57f02162 100644 --- a/src/lib_rdi_format/rdi_format.c +++ b/src/lib_rdi_format/rdi_format.c @@ -160,12 +160,12 @@ struct {RDI_EvalConversionKind dst_typegroups[RDI_EvalTypeGroup_COUNT];} rdi_eva struct {RDI_U8 *str; RDI_U64 size;} rdi_eval_conversion_kind_message_string_table[6] = { -{(RDI_U8 *)"Other", sizeof("Other")}, -{(RDI_U8 *)"U", sizeof("U")}, -{(RDI_U8 *)"S", sizeof("S")}, -{(RDI_U8 *)"F32", sizeof("F32")}, -{(RDI_U8 *)"F64", sizeof("F64")}, -{(RDI_U8 *)"COUNT", sizeof("COUNT")}, +{(RDI_U8 *)"", sizeof("")}, +{(RDI_U8 *)"", sizeof("")}, +{(RDI_U8 *)"Cannot convert between these types.", sizeof("Cannot convert between these types.")}, +{(RDI_U8 *)"Cannot convert to this type.", sizeof("Cannot convert to this type.")}, +{(RDI_U8 *)"Cannot convert this type.", sizeof("Cannot convert this type.")}, +{(RDI_U8 *)"", sizeof("")}, }; RDI_PROC RDI_U64 diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 339f75e6..bb04e188 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -377,7 +377,7 @@ RD_VocabInfo rd_vocab_info_table[319] = RD_NameSchemaInfo rd_name_schema_info_table[22] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name or path to the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name or path to the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 77fb96be..4a858306 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -225,9 +225,9 @@ RD_VocabTable: @default(1) 'scrolling_animations': bool, //- rjf: fonts - @display_name('UI Font') @description("The name or path to the font used when displaying non-code UI elements.") + @display_name('UI Font') @description("The name of, or path to, the font used when displaying non-code UI elements.") 'main_font': string, - @display_name('Code Font') @description("The name or path to the font used when displaying code.") + @display_name('Code Font') @description("The name of, or path to, the font used when displaying code.") 'code_font': string, //- rjf: colors diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a7b2bedb..9dc1a189 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1301,36 +1301,48 @@ rd_setting_from_name(String8 name) internal B32 rd_setting_b32_from_name(String8 name) { - Temp scratch = scratch_begin(0, 0); + B32 result = 0; String8 value = rd_setting_from_name(name); - String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); - E_Eval eval = e_eval_from_string(expr); - B32 result = !!e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + if(value.size != 0) + { + Temp scratch = scratch_begin(0, 0); + String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); + E_Eval eval = e_eval_from_string(expr); + result = !!e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); + } return result; } internal U64 rd_setting_u64_from_name(String8 name) { - Temp scratch = scratch_begin(0, 0); + U64 result = 0; String8 value = rd_setting_from_name(name); - String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); - E_Eval eval = e_eval_from_string(expr); - U64 result = e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + if(value.size != 0) + { + Temp scratch = scratch_begin(0, 0); + String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); + E_Eval eval = e_eval_from_string(expr); + result = e_value_eval_from_eval(eval).value.u64; + scratch_end(scratch); + } return result; } internal F32 rd_setting_f32_from_name(String8 name) { - Temp scratch = scratch_begin(0, 0); + F32 result = 0.f; String8 value = rd_setting_from_name(name); - String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); - E_Eval eval = e_eval_from_string(expr); - F32 result = e_value_eval_from_eval(eval).value.f32; - scratch_end(scratch); + if(value.size != 0) + { + Temp scratch = scratch_begin(0, 0); + String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); + E_Eval eval = e_eval_from_string(expr); + result = e_value_eval_from_eval(eval).value.f32; + scratch_end(scratch); + } return result; } @@ -4357,16 +4369,15 @@ rd_view_ui(Rng2F32 rect) F32 cell_slider_value = 0.f; if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2) { - E_Expr *min_expr = cell_type->args[0]; - E_Expr *max_expr = cell_type->args[1]; + E_Key min_key = e_key_from_expr(cell_type->args[0]); + E_Key max_key = e_key_from_expr(cell_type->args[1]); E_ParentKey(cell->eval.key) { E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); slider_value_type_kind = e_type_kind_from_key(slider_value_type); - E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr); - E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr); - cell_slider_min = e_value_from_expr(min_casted); - cell_slider_max = e_value_from_expr(max_casted); + String8 slider_type_name = e_type_string_from_key(scratch.arena, slider_value_type); + cell_slider_min = e_value_from_key(e_key_wrapf(min_key, "(%S)$", slider_type_name)); + cell_slider_max = e_value_from_key(e_key_wrapf(max_key, "(%S)$", slider_type_name)); } } switch(slider_value_type_kind) diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 5639d5df..aabc166d 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -1376,7 +1376,7 @@ rdi_eval_typegroup_conversion_kind_matrix: @data(`struct {RDI_U8 *str; RDI_U64 size;}`) @c_file rdi_eval_conversion_kind_message_string_table: { - @expand(RDI_EvalTypeGroupTable a) `{(RDI_U8 *)"$(a.error_string)", sizeof("$(a.error_string)")}` + @expand(RDI_EvalConversionKindTable a) `{(RDI_U8 *)"$(a.error_string)", sizeof("$(a.error_string)")}` } //////////////////////////////// @@ -1503,7 +1503,7 @@ rdi_hash(RDI_U8 *ptr, RDI_U64 size) @expand(RDI_TypeKindTable a) ` case RDI_TypeKind_$(a.name): {result = (RDI_U8*)"$(a.name)"; *size_out = sizeof("$(a.name)")-1;}break;`, `}`; `return result;`; - `}`; + `}`; ``; } From 0cdcb06db8e89a7864596f5071e9090bdf6b901d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 12:11:38 -0700 Subject: [PATCH 475/755] fix some edge cases in new casting compilation, fix some old usage of cast expr trees --- src/eval/eval_ir.c | 22 ++-------------------- src/eval/eval_ir.h | 1 - src/eval/eval_parse.c | 14 +------------- src/eval/eval_parse.h | 1 - src/raddbg/raddbg_core.c | 4 +--- 5 files changed, 4 insertions(+), 38 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 450204e0..78c2bf10 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1275,13 +1275,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, case E_ExprKind_Call: { E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); // rjf: calling a type? -> treat as a cast of that type - if(lhs_irtree.mode == E_Mode_Null) + if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil) { E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); @@ -2543,21 +2543,3 @@ e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree) e_expr_push_child(root, rhs_bytecode); return root; } - -internal E_Expr * -e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_Cast, 0); - E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); - E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); - rhs_bytecode->string = e_string_from_expr(arena, rhs, str8_zero()); - rhs_bytecode->space = rhs->space; - rhs_bytecode->mode = rhs_irtree->mode; - rhs_bytecode->type_key = rhs_irtree->type_key; - rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); - E_Expr *lhs = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - lhs->type_key = type_key; - e_expr_push_child(root, lhs); - e_expr_push_child(root, rhs_bytecode); - return root; -} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 314659bc..973d17de 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -99,6 +99,5 @@ internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name); internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index); internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); -internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 1edb9733..00ffd23e 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -334,18 +334,6 @@ e_expr_ref(Arena *arena, E_Expr *ref) return expr; } -internal E_Expr * -e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_Cast, 0); - E_Expr *lhs = e_push_expr(arena, E_ExprKind_TypeIdent, 0); - lhs->type_key = type_key; - E_Expr *rhs_ref = e_expr_ref(arena, rhs); - e_expr_push_child(root, lhs); - e_expr_push_child(root, rhs_ref); - return root; -} - internal E_Expr * e_expr_copy(Arena *arena, E_Expr *src) { @@ -1195,7 +1183,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: no identifier after `.`? -> error else { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing identifier after `.`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing member name after `%S`.", token_string); } } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 54af1689..7ab6a07d 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -22,7 +22,6 @@ internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); -internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, 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); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9dc1a189..65e178d3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2120,9 +2120,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) type_kind == E_TypeKind_Enum)) { got_commit_data = 1; - E_Expr *src_expr = e_parse_from_string(string).expr; - E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); - E_Eval src_eval = e_eval_from_expr(src_expr__casted); + E_Eval src_eval = e_eval_from_stringf("(%S)(%S)", e_type_string_from_key(scratch.arena, type_key), string); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } From fff259e1131cf84a92c3f4ce3ab762d940bf8a6c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 14:04:02 -0700 Subject: [PATCH 476/755] cache font setting calculations per-frame rather than recomputing all the time, fix some expandability calculations in eval visualization w/ multiple composing views --- src/eval/eval_types.c | 2 +- .../eval_visualization_core.c | 100 ++++++++++++------ .../eval_visualization_core.h | 3 +- src/raddbg/raddbg_core.c | 52 ++++----- src/raddbg/raddbg_core.h | 3 + 5 files changed, 95 insertions(+), 65 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index b040e20f..7d0ee27f 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1264,7 +1264,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) U64 last_member_off = 0; for(U64 member_idx = 0; member_idx < type->count; member_idx += 1) { - if(type->members[member_idx].kind == E_MemberKind_DataField) + if(type->members[member_idx].name.size != 0 && type->members[member_idx].kind == E_MemberKind_DataField) { E_MemberNode *n = push_array(scratch.arena, E_MemberNode, 1); MemoryCopyStruct(&n->v, &type->members[member_idx]); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index d817f242..3e2ea5f5 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -79,38 +79,65 @@ ev_hash_from_key(EV_Key key) //- rjf: type info -> expandability/editablity +internal E_TypeKey +ev_expansion_type_from_key(E_TypeKey type_key) +{ + E_TypeKey result = zero_struct; + for(E_TypeKey key = type_key; + !e_type_key_match(key, e_type_key_zero()); + key = e_type_key_direct(key)) + { + B32 done = 1; + E_TypeKind kind = e_type_kind_from_key(key); + + //- rjf: lenses -> try to see if this lens has special expansion rules. if + // so, choose the current eval + if(kind == E_TypeKind_Lens) + { + E_Type *type = e_type_from_key__cached(key); + if(type->expand.info != 0 || + ev_expand_rule_from_string(type->name)) + { + done = 1; + result = key; + } + } + + //- rjf: if we have meta-expression tags in the type chain, defer + // to the next type in the chain. + else if(E_TypeKind_FirstMeta <= kind && kind <= E_TypeKind_LastMeta) + { + done = 0; + } + + //- rjf: break if done + if(done) + { + break; + } + } + return result; +} + internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; + if(!e_type_key_match(ev_expansion_type_from_key(type_key), e_type_key_zero())) { - if(!result && e_type_kind_from_key(type_key) == E_TypeKind_Lens) + result = 1; + } + else + { + E_TypeKey default_expansion_type_key = e_default_expansion_type_from_key(type_key); + E_TypeKind kind = e_type_kind_from_key(default_expansion_type_key); + if(kind == E_TypeKind_Enum) { - for(E_Type *lens_type = e_type_from_key__cached(type_key); - lens_type->kind == E_TypeKind_Lens; - lens_type = e_type_from_key__cached(lens_type->direct_type_key)) - { - if(lens_type->expand.info != 0) - { - result = 1; - break; - } - } + result = (mode == E_Mode_Null); } - if(!result) + else if(kind != E_TypeKind_Null) { - E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); - E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); - if(expand_type_kind == E_TypeKind_Struct || - expand_type_kind == E_TypeKind_Union || - expand_type_kind == E_TypeKind_Class || - expand_type_kind == E_TypeKind_Array || - expand_type_kind == E_TypeKind_Set || - e_type_kind_is_pointer_or_ref(expand_type_kind) || - (expand_type_kind == E_TypeKind_Enum && mode == E_Mode_Null)) - { - result = 1; - } + result = 1; } } return result; @@ -512,7 +539,7 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) //~ rjf: Block Building internal EV_BlockTree -ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval) +ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root_eval) { ProfBeginFunction(); EV_BlockTree tree = {&ev_nil_block}; @@ -528,7 +555,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval MemoryCopyStruct(tree.root, &ev_nil_block); tree.root->key = root_key; tree.root->string = str8_zero(); - tree.root->eval = eval; + tree.root->eval = root_eval; tree.root->type_expand_rule = &e_type_expand_rule__default; tree.root->viz_expand_rule = &ev_nil_expand_rule; tree.root->row_count = 1; @@ -574,21 +601,26 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval // rjf: unpack eval E_Mode mode = t->eval.irtree.mode; - E_TypeKey type_key = t->eval.irtree.type_key; + E_Eval eval = t->eval; + E_TypeKey expansion_type_key = ev_expansion_type_from_key(eval.irtree.type_key); + if(!e_type_key_match(expansion_type_key, e_type_key_zero())) + { + eval.irtree.type_key = expansion_type_key; + } // rjf: get expansion rules from type - E_TypeExpandRule *type_expand_rule = e_expand_rule_from_type_key(type_key); - EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(type_key); + E_TypeExpandRule *type_expand_rule = e_expand_rule_from_type_key(eval.irtree.type_key); + EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(eval.irtree.type_key); // rjf: skip if no expansion rule, & type info disallows expansion - if(viz_expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(type_key, mode)) + if(viz_expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(eval.irtree.type_key, mode)) { continue; } // rjf: get top-level lookup/expansion info - E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval, filter); - EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); + E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, eval, filter); + EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, eval.expr); // rjf: determine expansion info U64 expansion_row_count = type_expand_info.expr_count; @@ -615,7 +647,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval expansion_block->parent = t->parent_block; expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; - expansion_block->eval = t->eval; + expansion_block->eval = eval; expansion_block->type_expand_info = type_expand_info; expansion_block->type_expand_rule = type_expand_rule; expansion_block->viz_expand_info = viz_expand_info; @@ -702,7 +734,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval { Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Eval child_eval = {0}; - type_expand_rule->range(arena, type_expand_info.user_data, t->eval, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); + type_expand_rule->range(arena, type_expand_info.user_data, eval, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); EV_Key child_key = child_keys[idx]; BlockTreeBuildTask *task = push_array(scratch.arena, BlockTreeBuildTask, 1); SLLQueuePush(first_task, last_task, task); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 84d2f7fb..c7ff2bc7 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -315,6 +315,7 @@ internal U64 ev_hash_from_key(EV_Key key); //~ rjf: Type Info Helpers //- rjf: type info -> expandability/editablity +internal E_TypeKey ev_expansion_type_from_key(E_TypeKey type_key); internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode); internal B32 ev_type_key_is_editable(E_TypeKey type_key); @@ -351,7 +352,7 @@ internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); //////////////////////////////// //~ rjf: Block Building -internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval); +internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root_eval); internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 65e178d3..f062c932 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4570,6 +4570,7 @@ rd_view_ui(Rng2F32 rect) // rjf: form cell build parameters RD_CellParams cell_params = {0}; + ProfScope("form cell build parameters") { // rjf: set up base parameters cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); @@ -10389,35 +10390,8 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str internal FNT_Tag rd_font_from_slot(RD_FontSlot slot) { - // rjf: determine key name for this font slot - String8 key = {0}; - switch(slot) - { - default:{}break; - case RD_FontSlot_Main:{key = str8_lit("main_font");}break; - case RD_FontSlot_Code:{key = str8_lit("code_font");}break; - } - - // rjf: determine font name - String8 font_name = rd_setting_from_name(key); - - // rjf: map name -> tag - FNT_Tag result = {0}; - if(font_name.size != 0) - { - result = fnt_tag_from_path(font_name); - } - if(font_name.size == 0 || fnt_tag_match(fnt_tag_zero(), result)) - { - switch(slot) - { - default: - case RD_FontSlot_Main: {result = fnt_tag_from_static_data_string(&rd_default_main_font_bytes);}break; - case RD_FontSlot_Code: {result = fnt_tag_from_static_data_string(&rd_default_code_font_bytes);}break; - case RD_FontSlot_Icons:{result = fnt_tag_from_static_data_string(&rd_icon_font_bytes);}break; - } - } - return result; + FNT_Tag tag = rd_state->font_slot_table[slot]; + return tag; } internal FNT_RasterFlags @@ -11609,6 +11583,26 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: get fonts from config + // + ProfScope("get fonts from config") + { + String8 main_font_name = rd_setting_from_name(str8_lit("main_font")); + String8 code_font_name = rd_setting_from_name(str8_lit("code_font")); + rd_state->font_slot_table[RD_FontSlot_Main] = fnt_tag_from_path(main_font_name); + rd_state->font_slot_table[RD_FontSlot_Code] = fnt_tag_from_path(code_font_name); + if(fnt_tag_match(rd_state->font_slot_table[RD_FontSlot_Main], fnt_tag_zero())) + { + rd_state->font_slot_table[RD_FontSlot_Main] = fnt_tag_from_static_data_string(&rd_default_main_font_bytes); + } + if(fnt_tag_match(rd_state->font_slot_table[RD_FontSlot_Code], fnt_tag_zero())) + { + rd_state->font_slot_table[RD_FontSlot_Code] = fnt_tag_from_static_data_string(&rd_default_code_font_bytes); + } + rd_state->font_slot_table[RD_FontSlot_Icons] = fnt_tag_from_static_data_string(&rd_icon_font_bytes); + } + ////////////////////////////// //- rjf: build theme from config // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 6097e6bf..1f0b487f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -655,6 +655,9 @@ struct RD_State // rjf: key map (constructed from-scratch each frame) RD_KeyMap *key_map; + // rjf: slot -> font tag map (constructed from-scratch each frame) + FNT_Tag font_slot_table[RD_FontSlot_COUNT]; + // rjf: theme target (constructed from-scratch each frame) RD_Theme *theme; RD_Theme *theme_target; From 5a5e24a4a9f0553b7d0d1470f226ec21d687de5b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 14:06:02 -0700 Subject: [PATCH 477/755] ditto --- src/eval_visualization/eval_visualization_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 3e2ea5f5..ec03e66e 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -96,7 +96,7 @@ ev_expansion_type_from_key(E_TypeKey type_key) { E_Type *type = e_type_from_key__cached(key); if(type->expand.info != 0 || - ev_expand_rule_from_string(type->name)) + ev_expand_rule_from_string(type->name) != &ev_nil_expand_rule) { done = 1; result = key; @@ -123,7 +123,8 @@ internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; - if(!e_type_key_match(ev_expansion_type_from_key(type_key), e_type_key_zero())) + E_TypeKey ev_expansion_type_key = ev_expansion_type_from_key(type_key); + if(!e_type_key_match(ev_expansion_type_key, e_type_key_zero())) { result = 1; } From 9fdfc7fab97d07dcb2f13af1171016e732cdc3a1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 15:37:30 -0700 Subject: [PATCH 478/755] eval: distinguish irtree 'parents' from 'overrides' - parents are any irtree which some other expression is extending, and overrides are a subset of those, being just the irtrees overridden by auto-hooks. doing this because when we unwind the parent chain, sometimes we do not want to do that for basic expression extensions - we just want to undo the overrides. --- src/eval/eval_core.c | 4 +- src/eval/eval_ir.c | 259 ++++++++---------- src/eval/eval_ir.h | 2 +- src/eval/eval_types.c | 29 +- .../eval_visualization_core.c | 4 + 5 files changed, 136 insertions(+), 162 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 3477e016..d9d2fd15 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -838,9 +838,9 @@ 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_IRTreeAndType parent = 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, 0, parse.expr); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, 0, 0, 0, parse.expr); E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 78c2bf10..8e930ccf 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -348,7 +348,7 @@ e_expr_unpoison(E_Expr *expr) } } -//- rjf: default type access hook +//- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default) { @@ -582,10 +582,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) return result; } -//- rjf: top-level irtree/type extraction - internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -600,26 +598,19 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { Task *next; E_Expr *expr; - E_IRTreeAndType *prev; + E_IRTreeAndType *overridden; }; - Task start_task = {0, root_expr, root_overridden}; + Task start_task = {0, root_expr, 0}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) { E_Expr *expr = t->expr; + E_IRTreeAndType *parent = t->overridden ? t->overridden : root_parent; //- rjf: poison the expression we are about to use, so we don't recursively use it e_expr_poison(expr); - //- rjf: select the task's previous ir-tree-and-type as the overridden tree - E_IRTreeAndType *overridden = 0; - if(t->prev != 0) - { - overridden = push_array(arena, E_IRTreeAndType, 1); - MemoryCopyStruct(overridden, t->prev); - } - //- rjf: do expr -> irtree generation for this expression if(expr->kind == E_ExprKind_Ref) { @@ -636,7 +627,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain @@ -678,7 +669,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, } // rjf: call into hook to do access - result = lhs_access(arena, overridden, expr, lhs_irtree_try); + result = lhs_access(arena, parent, expr, lhs_irtree_try); // rjf: end chain if we found a result if(result.root != &e_irnode_nil) @@ -693,7 +684,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -752,7 +743,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); @@ -780,12 +771,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, cast_type_expr); e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -840,7 +831,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -868,7 +859,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -882,7 +873,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -910,14 +901,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -950,7 +941,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1005,8 +996,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1229,9 +1220,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1274,8 +1265,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, //- rjf: call case E_ExprKind_Call: { + B32 strip_lenses = 0; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1283,7 +1275,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, // rjf: calling a type? -> treat as a cast of that type if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil) { - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey cast_type = lhs_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); @@ -1351,108 +1343,69 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { e_expr_push_child(call, e_expr_copy(arena, arg)); } - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call); + if(str8_match(callee->string, str8_lit("raw"), 0)) + { + strip_lenses = 1; + disallow_autohooks = 1; + } + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call); E_MsgList new_msgs = {0}; e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs); e_msg_list_concat_in_place(&new_msgs, &result.msgs); result.msgs = new_msgs; - - // rjf: is "raw"? -> try to return overridden tree, otherwise strip all - // lens types from result; disallow auto-hooks - if(str8_match(callee->string, str8_lit("raw"), 0)) - { - disallow_autohooks = 1; - if(overridden->root != &e_irnode_nil) - { - E_MsgList existing_msgs = result.msgs; - for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev) - { - result = *prev; - if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens) - { - break; - } - } - E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs); - result.msgs = existing_msgs; - e_msg_list_concat_in_place(&result.msgs, &overridden_msgs); - } - else - { - result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); - } - } } - // rjf: calling a lens? -> generate IR for the first argument; wrap the type in - // a lens type, which preserves the name & arguments of the lens call expression + // rjf: calling a lens? -> generate IR for the first argument; if enabled, wrap + // the type in a lens type, which preserves the name & arguments of the lens call + // expression else if(lhs_type->kind == E_TypeKind_LensSpec) { - Temp scratch = scratch_begin(&arena, 1); - - // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next); - - // rjf: count extra arguments - U64 arg_count = 0; - for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next) - { - arg_count += 1; - } - - // rjf: flatten extra arguments - E_Expr **args = push_array(scratch.arena, E_Expr *, arg_count); - { - U64 idx = 0; - for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next, idx += 1) - { - args[idx] = arg; - } - } - - // rjf: is "raw"? -> try to return overridden tree, otherwise strip all - // lens types from result; disallow auto-hooks + // rjf: is "raw"? -> disable hooks if(str8_match(lhs_type->name, str8_lit("raw"), 0)) { + strip_lenses = 1; disallow_autohooks = 1; - if(overridden->root != &e_irnode_nil) - { - E_MsgList existing_msgs = result.msgs; - result = *overridden; - for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev) - { - result = *prev; - if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens) - { - break; - } - } - E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs); - result.msgs = existing_msgs; - e_msg_list_concat_in_place(&result.msgs, &overridden_msgs); - } - else - { - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next); - result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); - } } - // rjf: is non-raw -> patch resultant type with a lens w/ args, pointing to the original type - else + // rjf: generate result via first argument to lens + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, lhs->next); + + // rjf: if not raw, wrap resultant type with lens type + if(!strip_lenses) { - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, - .flags = lhs_type->flags, - .count = arg_count, - .args = args, - .direct_key = result.type_key, - .name = lhs_type->name, - .irext = lhs_type->irext, - .access = lhs_type->access, - .expand = lhs_type->expand); + Temp scratch = scratch_begin(&arena, 1); + + // rjf: count extra arguments + U64 arg_count = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next) + { + arg_count += 1; + } + + // rjf: flatten extra arguments + E_Expr **args = push_array(scratch.arena, E_Expr *, arg_count); + { + U64 idx = 0; + for(E_Expr *arg = lhs->next->next; arg != &e_expr_nil; arg = arg->next, idx += 1) + { + args[idx] = arg; + } + } + + // rjf: patch resultant type with a lens w/ args, pointing to the original type + { + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lhs_type->flags, + .count = arg_count, + .args = args, + .direct_key = result.type_key, + .name = lhs_type->name, + .irext = lhs_type->irext, + .access = lhs_type->access, + .expand = lhs_type->expand); + } + scratch_end(scratch); } - - scratch_end(scratch); } // rjf: calling any other type? -> not valid @@ -1460,6 +1413,23 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); } + + // rjf: strip overrides and lenses if needed + if(strip_lenses) + { + if(t->overridden) + { + E_MsgList existing_msgs = result.msgs; + for(E_IRTreeAndType *prev = t->overridden; prev != 0; prev = prev->prev) + { + result = *prev; + } + E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs); + result.msgs = existing_msgs; + e_msg_list_concat_in_place(&result.msgs, &overridden_msgs); + } + result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses|E_TypeUnwrapFlag_Meta); + } }break; //- rjf: leaf bytecode @@ -1560,24 +1530,32 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, } } - //- rjf: try to map name as overridden expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && (overridden->root != &e_irnode_nil || overridden->msgs.first != 0)) + //- rjf: try to map name as parent expression signifier ('$') + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) { - E_OpList oplist = e_oplist_from_irtree(arena, overridden->root); + E_IRTreeAndType *parent_irtree = parent; + if(disallow_autohooks) + { + for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) + { + parent_irtree = prev; + } + } + E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); string_mapped = 1; mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = overridden->mode; - mapped_type_key = overridden->type_key; + mapped_bytecode_mode = parent_irtree->mode; + mapped_type_key = parent_irtree->type_key; disallow_autohooks = 1; - E_MsgList msgs = e_msg_list_copy(arena, &overridden->msgs); + E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); e_msg_list_concat_in_place(&result.msgs, &msgs); } //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(!string_mapped && overridden->root != &e_irnode_nil) + if(!string_mapped && parent != 0 && parent->root != &e_irnode_nil) { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, 1, 1, access); + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, parent, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, parent, disallow_autohooks, 1, 1, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -1945,7 +1923,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { generated = 1; e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, macro_expr); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, macro_expr); e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); } } @@ -2032,7 +2010,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, }break; case E_ExprKind_Unsigned: { - E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); result = direct_irtree; E_TypeKey direct_type_key = result.type_key; E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); @@ -2062,13 +2040,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2082,7 +2060,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, rhs); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); @@ -2097,7 +2075,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, { // rjf: unpack E_IRTreeAndType cast_type_tree = result; - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->next); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, expr->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey cast_type = cast_type_tree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); @@ -2234,9 +2212,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, } //- rjf: equip previous task's irtree - if(t->prev != 0) + if(t->overridden != 0) { - result.prev = overridden; + result.prev = push_array(arena, E_IRTreeAndType, 1); + result.prev[0] = *t->overridden; } //- rjf: find any auto hooks according to this generation's type @@ -2253,11 +2232,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->expr = e; - task->prev = &result; - break; + task->overridden = push_array(scratch.arena, E_IRTreeAndType, 1); + task->overridden[0] = result; + goto end_autohook_find; } } } + end_autohook_find:; } } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 973d17de..a63bd7bc 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 7d0ee27f..d15832f6 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2251,31 +2251,22 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) Temp scratch = scratch_begin(&arena, 1); String8List allowed_children = {0}; { -#if 0 // TODO(rjf): @eval - E_Type *stripped_type = e_type_from_key__cached(type->direct_type_key); - // TODO(rjf): this is kind of ugly due to the need to call irext, - // i wish it was possible to have an easier way to "strip" the current - // lens & evaluate the wrapped expression? - E_IRTreeAndType irtree_stripped = *irtree; - irtree_stripped.type_key = type->direct_type_key; - irtree_stripped.user_data = stripped_type->irext ? stripped_type->irext(scratch.arena, expr, &irtree_stripped).user_data : 0; - E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(irtree_stripped.type_key); - // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key - E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, expr, &irtree_stripped, filter); + E_Eval eval_stripped = e_eval_wrapf(eval, "raw($)"); + E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(eval_stripped.irtree.type_key); + E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval_stripped, filter); if(expand_info.expr_count < 4096) { - E_Expr **exprs = push_array(scratch.arena, E_Expr *, expand_info.expr_count); - String8 *exprs_strings = push_array(scratch.arena, String8, expand_info.expr_count); + E_Eval *evals = push_array(scratch.arena, E_Eval, expand_info.expr_count); for EachIndex(idx, expand_info.expr_count) { - exprs[idx] = &e_expr_nil; + evals[idx] = e_eval_nil; } - expand_rule->range(scratch.arena, expand_info.user_data, expr, &irtree_stripped, filter, r1u64(0, expand_info.expr_count), exprs, exprs_strings); + expand_rule->range(scratch.arena, expand_info.user_data, eval_stripped, filter, r1u64(0, expand_info.expr_count), evals); for EachIndex(idx, expand_info.expr_count) { - if(exprs[idx]->kind == E_ExprKind_MemberAccess) + if(evals[idx].expr->kind == E_ExprKind_MemberAccess) { - String8 name = exprs[idx]->first->next->string; + String8 name = evals[idx].expr->first->next->string; B32 name_is_allowed = 1; for EachIndex(arg_idx, type->count) { @@ -2292,7 +2283,6 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) } } } -#endif } allowed_children_array = str8_array_from_list(arena, &allowed_children); scratch_end(scratch); @@ -2476,8 +2466,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) } // rjf: compute struct.base_ptr IR tree - E_IRTreeAndType override = {&e_irnode_nil}; - result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, 0, idx_expr); + result = e_push_irtree_and_type_from_expr(arena, 0, 0, 0, 0, idx_expr); scratch_end(scratch); }break; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index ec03e66e..3a013dd0 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -101,6 +101,10 @@ ev_expansion_type_from_key(E_TypeKey type_key) done = 1; result = key; } + else + { + done = 0; + } } //- rjf: if we have meta-expression tags in the type chain, defer From f72c956c9f448441301a3683c7bd50de3f229909 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 15:41:32 -0700 Subject: [PATCH 479/755] fix implicit parent/override member accesses --- src/eval/eval_ir.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 8e930ccf..e5c5ee9a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1554,16 +1554,20 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) if(!string_mapped && parent != 0 && parent->root != &e_irnode_nil) { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, parent, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, parent, disallow_autohooks, 1, 1, access); - if(access_irtree.root != &e_irnode_nil) + for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) { - string_mapped = 1; - E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); - mapped_type_key = access_irtree.type_key; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = access_irtree.mode; - e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, 1, access); + if(access_irtree.root != &e_irnode_nil) + { + string_mapped = 1; + E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); + mapped_type_key = access_irtree.type_key; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = access_irtree.mode; + e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); + break; + } } } From dc15a4fdc5485e6bc1f1c575a88ca20481ad8ffd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 16:02:48 -0700 Subject: [PATCH 480/755] fix busted chained dot-access-style views --- src/eval/eval_ir.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e5c5ee9a..5989eff7 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1273,7 +1273,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); // rjf: calling a type? -> treat as a cast of that type - if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil) + if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec) { E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); @@ -1331,8 +1331,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // left-hand-side of the dot operator as the first argument. this is a fast path // which prevents paren nesting in simple cases, to easily chain multiple // calls - for example, bin(2).digits(4) - else if(lhs_type == &e_type_nil && - lhs->kind == E_ExprKind_MemberAccess) + else if(lhs->kind == E_ExprKind_MemberAccess) { E_Expr *callee = lhs->first->next; E_Expr *first_arg = e_expr_ref(arena, lhs->first); @@ -1349,10 +1348,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks = 1; } result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call); - E_MsgList new_msgs = {0}; - e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs); - e_msg_list_concat_in_place(&new_msgs, &result.msgs); - result.msgs = new_msgs; + // NOTE(rjf): we do not want to accumulate messages from the original left-hand-side evaluation in this case, because + // this path only occurs if the member access fails specifically. } // rjf: calling a lens? -> generate IR for the first argument; if enabled, wrap From 57c331537b3a64b6a091fad58f6713cfcf14d01d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 16:19:05 -0700 Subject: [PATCH 481/755] release notes --- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_main.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f062c932..fbaededa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12719,6 +12719,7 @@ rd_frame(void) "query:breakpoints, " "query:recent_files, " "query:recent_projects, " + "query:machines, " "query:processes, " "query:threads, " "query:modules, " diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 138768e7..e93b0c7f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -34,6 +34,33 @@ // view which maps `Bitmap` to `bitmap(base, width, height)`. In this case, // `base`, `width`, and `height` are recognized as being member names of // `Bitmap`. This is equivalent to `bitmap($.base, $.width, $.height)`. +// - Breakpoints have been upgraded to support flags for breaking on writing, +// reading, or execution, as well as an address range size. When used with +// an address location, this can be used to express hardware data +// breakpoints, where the CPU will break when it sees particular addresses +// being written to, read from, or executed, regardless of where that code +// occurs. There is a maximum limit of four such breakpoints on a processor. +// Theoretically, this means a limit of four per thread, but for now, the +// debugger only supports four global data breakpoints. In the future, we +// plan to allow organizing these by thread, in which case the total number +// of data breakpoints we support will increase. +// - A new `table` view has been added, which allows one to define custom rules +// for how rows of a watch expansion are formed. The first argument a `table` +// is the expression which should be evaluated (like other views), and the +// remaining arguments are used to express a number of expressions which +// should be used to generated cells for each row in the expansion. For +// instance, `table(my_int_array, $, $*4, $*8)` would expand `my_int_array`, +// but instead of the default row structure (which displays an expression +// string, a value string, and a type string), three cells would be generated +// per row: one with the value of each element, one with that value +// multiplied by 4, and one multiplied by 8. +// - A new `sequence` view has been added. This is a simple view which simply +// takes a single integer scalar argument `n`, and returns a sequence of +// integers, from `0`, `1`, `2`, all the way to `n`. This sequence can be +// expanded. This can compose with the `table` view, to easily generate `n` +// rows, and use each integer as a value in each cell expression. As an +// example, `table(sequence(1000), array1[$], array2[$])` would display +// elements of `array1` and `array2` in each row, side-by-side. // - The F1 command palette has been replaced by a substantially more powerful // "everything palette" (referred to in the UI simply as "palette"), opened // with the `Open Palette` command. This palette lists commands and allows From 33479ec73260d939d85d9759d4c99286e3cf7cb4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 16:20:41 -0700 Subject: [PATCH 482/755] fix thread-in-code-view right-clicks, after moving to more stable ctrl entity evaluation --- src/raddbg/raddbg_widgets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index bff716a4..0685b77c 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1422,7 +1422,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = thread_box->key, - .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); + .expr = push_str8f(scratch.arena, "query:control.%S", ctrl_string_from_handle(scratch.arena, thread->handle))); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { @@ -1576,7 +1576,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { rd_cmd(RD_CmdKind_PushQuery, .ui_key = thread_box->key, - .expr = ctrl_string_from_handle(scratch.arena, thread->handle)); + .expr = push_str8f(scratch.arena, "query:control.%S", ctrl_string_from_handle(scratch.arena, thread->handle))); } if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) { From a2ba3933cf4b4472de2bb1bae935e1f2abcd3de6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 16:43:39 -0700 Subject: [PATCH 483/755] fix ui tags-key/name -> color mapping; if a pattern is too specific, it should never match more general queries. but more specific queries can match less general patterns --- src/raddbg/generated/raddbg.meta.c | 4 ++-- src/raddbg/raddbg.mdesk | 4 ++-- src/raddbg/raddbg_views.c | 8 +++++++- src/ui/ui_core.c | 13 ++++++++++--- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index bb04e188..d8fb5ecb 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -623,8 +623,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_color"), str8_lit_comp("Adds a new color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("import_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_color"), str8_lit_comp("Adds a new color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("import_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 4a858306..5c8002c2 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -920,8 +920,8 @@ RD_CmdTable: // | | | | {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } //- rjf: colors - {AddColor 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_color" "Add Color" "Adds a new color." "" "" } - {ImportColors 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "import_colors" "Import Colors" "Imports all colors from a loaded color theme file or color theme preset." "" "" } + {AddColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_color" "Add Color" "Adds a new color." "" "" } + {ImportColors 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "import_colors" "Import Colors" "Imports all colors from a loaded color theme file or color theme preset." "" "" } //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 240dfae1..e527a098 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3649,12 +3649,18 @@ RD_VIEW_UI_FUNCTION_DEF(color) { UI_Signal sv_sig = ui_sat_val_pickerf(hsva.x, &hsva.y, &hsva.z, "sat_val_picker"); UI_Signal h_sig = {0}; + UI_Signal a_sig = {0}; ui_spacer(ui_em(1.f, 1.f)); UI_PrefWidth(ui_em(3.f, 1.f)) { h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker"); } ui_spacer(ui_em(1.f, 1.f)); + UI_PrefWidth(ui_em(3.f, 1.f)) + { + a_sig = ui_alpha_pickerf(&hsva.w, "alpha_picker"); + } + ui_spacer(ui_em(1.f, 1.f)); UI_PrefWidth(ui_children_sum(1)) UI_Column { UI_PrefWidth(ui_em(6.f, 0.f)) UI_PrefHeight(ui_em(6.f, 0.f)) @@ -3691,7 +3697,7 @@ RD_VIEW_UI_FUNCTION_DEF(color) } } } - if(ui_dragging(h_sig) || ui_dragging(sv_sig)) + if(ui_dragging(h_sig) || ui_dragging(sv_sig) || ui_dragging(a_sig)) { // TODO(rjf): hard-coding U32 committing for now E_Type *type = e_type_from_key__cached(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 38f94cac..d2b6bbad 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2241,18 +2241,25 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) UI_ThemePattern *p = &theme->patterns[idx]; U64 match_count = 0; B32 name_matches = 0; - for EachIndex(key_tags_idx, tags.count+1) + for EachIndex(p_tags_idx, p->tags.count) { - String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; - for EachIndex(p_tags_idx, p->tags.count) + B32 p_tag_in_key = 0; + for EachIndex(key_tags_idx, tags.count+1) { + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) { name_matches = (key_tags_idx == tags.count); + p_tag_in_key = 1; match_count += 1; break; } } + if(!p_tag_in_key) + { + name_matches = 0; + break; + } } if(name_matches && match_count > best_match_count) { From 1f1c4f161b428c36695c9f8a038c2ff07145de8e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 16:53:53 -0700 Subject: [PATCH 484/755] cfg query eval filtering --- src/raddbg/raddbg_core.c | 5 ++++- src/raddbg/raddbg_eval.c | 17 ++++++++++++++++- src/raddbg/raddbg_views.c | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fbaededa..cfafe420 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15209,7 +15209,10 @@ rd_frame(void) case RD_CmdKind_AddColor: { RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); - rd_cfg_new(parent, str8_lit("color")); + RD_Cfg *color = rd_cfg_new(parent, str8_lit("color")); + rd_cfg_new(color, str8_lit("tags")); + RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); + rd_cfg_new(value, str8_lit("0xffffffff")); }break; case RD_CmdKind_ImportColors: { diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 848d6880..fe7de6e7 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -740,9 +740,24 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(cfgs_query) } } RD_CfgList children = rd_cfg_child_list_from_string(scratch.arena, root_cfg, child_key); + RD_CfgList children__filtered = children; + if(filter.size != 0) + { + MemoryZeroStruct(&children__filtered); + for(RD_CfgNode *n = children.first; n != 0; n = n->next) + { + DR_FStrList cfg_fstrs = rd_title_fstrs_from_cfg(scratch.arena, n->v); + String8 cfg_string = dr_string_from_fstrs(scratch.arena, &cfg_fstrs); + FuzzyMatchRangeList ranges = fuzzy_match_find(scratch.arena, filter, cfg_string); + if(ranges.count == ranges.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &children__filtered, n->v); + } + } + } accel->cmds = str8_array_from_list(arena, &cmds); accel->cmds_idx_range = r1u64(0, accel->cmds.count); - accel->cfgs = rd_cfg_array_from_list(arena, &children); + accel->cfgs = rd_cfg_array_from_list(arena, &children__filtered); accel->cfgs_idx_range = r1u64(accel->cmds.count + 0, accel->cmds.count + accel->cfgs.count); scratch_end(scratch); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index e527a098..473e0df8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3565,7 +3565,7 @@ rd_eval_color_from_eval(E_Eval eval) EV_EXPAND_RULE_INFO_FUNCTION_DEF(color) { EV_ExpandInfo info = {0}; - info.row_count = 8; + info.row_count = 12; info.single_item = 1; return info; } From eb3b2572f17858b8ae65aa546ec9425301f0a1bc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 17:13:22 -0700 Subject: [PATCH 485/755] more fixes to name -> color matching; more meta-type-tag usage fixes in reordering path --- src/raddbg/raddbg_core.c | 2 +- src/ui/ui_core.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cfafe420..0e7a3caf 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3836,7 +3836,7 @@ rd_view_ui(Rng2F32 rect) String8 group_cfg_name = {0}; { E_IRTreeAndType block_irtree = selection_block->eval.irtree; - E_TypeKey block_type_key = block_irtree.type_key; + E_TypeKey block_type_key = e_type_key_unwrap(block_irtree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); if(block_type_kind == E_TypeKind_Set) { diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index d2b6bbad..3e21a100 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2241,6 +2241,7 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) UI_ThemePattern *p = &theme->patterns[idx]; U64 match_count = 0; B32 name_matches = 0; + B32 all_p_tags_in_key = 1; for EachIndex(p_tags_idx, p->tags.count) { B32 p_tag_in_key = 0; @@ -2249,7 +2250,10 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) { - name_matches = (key_tags_idx == tags.count); + if(key_tags_idx == tags.count) + { + name_matches = 1; + } p_tag_in_key = 1; match_count += 1; break; @@ -2257,11 +2261,11 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) } if(!p_tag_in_key) { - name_matches = 0; + all_p_tags_in_key = 0; break; } } - if(name_matches && match_count > best_match_count) + if(name_matches && all_p_tags_in_key && match_count > best_match_count) { pattern = p; best_match_count = match_count; From e7acf145cfa5c31d1ae45203c98d9e1b921c435a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 17:29:13 -0700 Subject: [PATCH 486/755] clear cfgs on release --- src/raddbg/raddbg_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0e7a3caf..d358461c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -340,6 +340,9 @@ rd_cfg_release(RD_Cfg *cfg) RD_Cfg *c = n->v; rd_name_release(c->string); SLLStackPush(rd_state->free_cfg, c); + c->first = c->last = c->prev = c->parent = 0; + c->id = 0; + c->string = str8_zero(); U64 hash = d_hash_from_string(str8_struct(&c->id)); U64 slot_idx = hash%rd_state->cfg_id_slots_count; for(RD_CfgNode *n = rd_state->cfg_id_slots[slot_idx].first; n != 0; n = n->next) From 0c535b3e605c24a1021dc228e71c322b8021f7ed Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 17:51:45 -0700 Subject: [PATCH 487/755] pre-emptively accumulate label edits in evaluation macro map, to prevent mid-frame ui tearing on edited cfg state --- src/raddbg/raddbg_core.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d358461c..a6acec22 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1947,6 +1947,21 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) // rjf: child key -> look up & edit child else { + // rjf: modifying a label? -> poison this identifier in the macro map + if(str8_match(child_key, str8_lit("label"), 0)) + { + String8 pre_edit_label = rd_label_from_cfg(root_cfg); + if(!str8_match(pre_edit_label, write_string, 0)) + { + E_Expr *expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, pre_edit_label); + if(expr != &e_expr_nil) + { + e_string2expr_map_inc_poison(e_ir_ctx->macro_map, pre_edit_label); + e_string2expr_map_insert(e_cache->arena, e_ir_ctx->macro_map, write_string, expr); + } + } + } + // rjf: zero-range? delete child if(range.min == range.max) { @@ -12069,23 +12084,15 @@ rd_frame(void) for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) { RD_Cfg *cfg = n->v; - String8 label = rd_cfg_child_from_string(cfg, str8_lit("label"))->first->string; - String8 exe = rd_cfg_child_from_string(cfg, str8_lit("executable"))->first->string; - if(exe.size != 0 || label.size != 0) + String8 label = rd_label_from_cfg(cfg); + if(label.size != 0) { E_Space space = rd_eval_space_from_cfg(cfg); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; - if(exe.size != 0) - { - e_string2expr_map_insert(scratch.arena, macro_map, str8_skip_last_slash(exe), expr); - } - if(label.size != 0) - { - e_string2expr_map_insert(scratch.arena, macro_map, label, expr); - } + e_string2expr_map_insert(scratch.arena, macro_map, label, expr); } } } From 71bdeb8f92d03c7d8cf85ec1b6a8c13dd01ba561 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 28 Apr 2025 21:20:08 -0700 Subject: [PATCH 488/755] release notes work --- src/raddbg/raddbg_main.c | 172 +++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 80 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index e93b0c7f..e407d0c7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -4,7 +4,8 @@ //////////////////////////////// //~ rjf: 0.9.16 release notes // -// - "View rules", now simply called "views", have been formally integrated +// - **Formal integration of views (view rules) into the evaluation language.** +// "View rules", now simply called "views", have been formally integrated // into the debugger evaluation language. They now appear similar to function // calls, and are expressed directly within an expression. For example, an // expression `dynamic_array` with a view rule `slice` from prior versions @@ -18,96 +19,107 @@ // required in some cases (e.g. the `fmt`/format parameter for `bitmap`), are // expressed using `name = value` syntax: // `bitmap(base, width, height, fmt=bgra8)`. -// - "Auto view rules", now simply called "type views", have been upgraded -// to support type pattern-matching. This makes them usable for generic types -// in various languages. This pattern-matching is done by using `?` characters -// in a pattern, to specify placeholders for various parts of a type name. -// For example, the pattern `DynamicArray` would match -// `DynamicArray`, `DynamicArray`, and so on. -// - Type views have been upgraded to support a larger number of possibilities. -// Instead of mapping to a set of views which are applied to some other -// expression, type views can remap the expression itself, and apply -// additional views. These expressions can refer to the originating -// expression either explicitly using the `$` character, or implicitly in -// some cases. For instance, a type like -// `struct Bitmap {U8 *base; U32 width; U32 height;};` can be used in a type -// view which maps `Bitmap` to `bitmap(base, width, height)`. In this case, -// `base`, `width`, and `height` are recognized as being member names of -// `Bitmap`. This is equivalent to `bitmap($.base, $.width, $.height)`. -// - Breakpoints have been upgraded to support flags for breaking on writing, -// reading, or execution, as well as an address range size. When used with -// an address location, this can be used to express hardware data -// breakpoints, where the CPU will break when it sees particular addresses -// being written to, read from, or executed, regardless of where that code -// occurs. There is a maximum limit of four such breakpoints on a processor. -// Theoretically, this means a limit of four per thread, but for now, the -// debugger only supports four global data breakpoints. In the future, we -// plan to allow organizing these by thread, in which case the total number -// of data breakpoints we support will increase. -// - A new `table` view has been added, which allows one to define custom rules -// for how rows of a watch expansion are formed. The first argument a `table` -// is the expression which should be evaluated (like other views), and the -// remaining arguments are used to express a number of expressions which -// should be used to generated cells for each row in the expansion. For +// - **Support for generics in type views (auto view rules)**. "Auto view +// rules", now simply called "type views", have been upgraded to support type +// pattern-matching. This makes them usable for generic types in various +// languages. This pattern-matching is done by using `?` characters in a +// pattern, to specify placeholders for various parts of a type name. For +// example, the pattern `DynamicArray` would match `DynamicArray`, +// `DynamicArray`, and so on. `?(?)` would match all function types. +// - **Usage of the source expression within type views.** Type views have been +// upgraded to support a larger number of possibilities. Instead of mapping +// to a set of views which are applied to some other expression, type views +// can remap the expression itself, and apply additional views. These +// expressions can refer to the originating expression either explicitly +// using the `$` character, or implicitly in some cases. For instance, a type +// like `struct Bitmap {U8 *base; U32 width; U32 height;};` can be used in a +// type view which maps `Bitmap` to `bitmap(base, width, height)`. In this +// case, `base`, `width`, and `height` are recognized as being member names +// of `Bitmap`. This is equivalent to `bitmap($.base, $.width, $.height)`. +// - **Hardware data breakpoints.** Breakpoints have been upgraded to support +// flags for breaking on writing, reading, or execution, as well as an +// address range size. When used with an address location, this can be used +// to express hardware data breakpoints, where the CPU will break when it +// sees particular addresses being written to, read from, or executed, +// regardless of which code does it. There is a maximum limit of four such +// breakpoints on a processor. Theoretically, this means a limit of four per +// thread, but for now, the debugger only supports four global data +// breakpoints. In the future, we plan to allow organizing these by thread, +// in which case the total number of data breakpoints we support will +// increase. +// - **A new `table` view** has been added, which allows one to define custom +// rules for how rows of a watch expansion are formed. The first argument a +// `table` is the expression which should be evaluated (like other views), +// and the remaining arguments are used to express a number of expressions +// which should be used to generated cells for each row in the expansion. For // instance, `table(my_int_array, $, $*4, $*8)` would expand `my_int_array`, // but instead of the default row structure (which displays an expression // string, a value string, and a type string), three cells would be generated // per row: one with the value of each element, one with that value // multiplied by 4, and one multiplied by 8. -// - A new `sequence` view has been added. This is a simple view which simply -// takes a single integer scalar argument `n`, and returns a sequence of -// integers, from `0`, `1`, `2`, all the way to `n`. This sequence can be +// - **A new `sequence` view** has been added. This is a simple view which +// simply takes a single integer scalar argument `n`, and returns a sequence +// of integers, from `0`, `1`, `2`, all the way to `n`. This sequence can be // expanded. This can compose with the `table` view, to easily generate `n` // rows, and use each integer as a value in each cell expression. As an // example, `table(sequence(1000), array1[$], array2[$])` would display // elements of `array1` and `array2` in each row, side-by-side. -// - The F1 command palette has been replaced by a substantially more powerful -// "everything palette" (referred to in the UI simply as "palette"), opened -// with the `Open Palette` command. This palette lists commands and allows -// the editing of bindings, just like the old command palette (although it -// now also supports searching for command bindings themselves, in addition -// to the original searching support for command names and descriptions). -// However, this palette now also lists targets, breakpoints, recent files, -// recent projects, settings (including tab settings, window settings, user -// settings, project settings), attached processes, threads, modules, -// functions, types, and global variables. This can be used to quickly search -// for a large set of possible things, and either jump to them or edit them. -// - The tab right-click menu has been upgraded to show all tab-related -// settings, including ones specially-defined for specific visualizers (like -// the width and height parameters to the bitmap visualizer). -// - The debugger UI now more flexibly supports a larger set of possible -// combinations of font sizes. Each tab can have a specific font size set, -// which can be edited within the palette or a tab's right-click menu. If a -// tab has no per-tab font size set, then it inherits the setting from the -// window's font size. -// - The fonts which the debugger uses can now be set through settings UI -// (including the palette). -// - The debugger now accepts system font file names in addition to full font -// file paths to specify font settings. -// - Expressions inserted into a `Watch` tab are now stored per-tab. This makes -// many `Watch` tabs more useful, since different tabs can have a different -// set of expressions. `Watch` tabs can now also be labeled, so you can -// visually distinguish many `Watch` tabs more easily. -// - All tabs now allow hand-editing of their root expression in their -// right-click menu. -// - Debugger settings have been upgraded to be stored as expressions, rather -// than being locked to a specific value. These expressions are evaluated, -// like any other expression, and their evaluated value is used when the -// setting value is actually needed. -// - The `slice` view has been streamlined and simplified. When an expression -// with a `slice` view is expanded, it will simply expand to the slice's -// contents, which matches the behavior with static arrays. -// - The `slice` view now supports `first, one_past_last` pointer pairs, as -// well as `base_pointer, length` pairs. -// - The debugger now displays toggle switches as an additional visualization -// and editor for all boolean evaluations. -// - A new `range1` view has been added, which expresses bounds for some scalar -// value. When this view is used in an evaluation, the debugger will +// - **The everything palette**. The F1 command palette has been replaced by a +// substantially more powerful "everything palette" (referred to in the UI +// simply as "palette"), opened with the `Open Palette` command. This palette +// lists commands and allows the editing of bindings, just like the old +// command palette (although it now also supports searching for command +// bindings themselves, in addition to the original searching support for +// command names and descriptions). However, this palette now also lists +// targets, breakpoints, recent files, recent projects, settings (including +// tab settings, window settings, user settings, project settings), attached +// processes, threads, modules, functions, types, and global variables. This +// can be used to quickly search for a large set of possible things, and +// either jump to them or edit them. The old `Run Command` command still +// exists, and still presents a command palette, which is simply a +// special-case of the generalized palette. But this command is no longer +// bound to F1 by default. +// - **Upgraded per-tab settings.** The tab right-click menu has been upgraded +// to show all tab-related settings, including ones specially-defined for +// specific visualizers (like the width and height parameters to the bitmap +// visualizer). The debugger UI now also supports per-tab font sizes. If a +// tab has no per-tab font size set, then it inherits the window's font size. +// Each tab's root expression is now also editable in this interface. The tab +// right-click menu's options also show up in the palette when the +// corresponding tab is focused. They can also be manually opened with the +// `Tab Settings` command. +// - **UI for setting the font.** The fonts which the debugger uses can now be +// set through settings UI (including the palette), rather than just through +// the configuration files. +// - **Support for searching system font folders for fonts.** The debugger now +// accepts system font file names in addition to full font file paths to +// specify font settings. +// - **Per-`Watch` expressions and labels.** Expressions inserted into a +// `Watch` tab are now stored per-tab. This makes many `Watch` tabs more +// useful, since different tabs can have a different set of expressions. +// `Watch` tabs can now also be labeled, so you can visually distinguish +// many `Watch` tabs more easily. +// - **Settings expressions.** Debugger settings have been upgraded to be +// stored as expressions, rather than being locked to a specific value. +// These expressions are evaluated, like any other expression, and their +// evaluated value is used when the setting value is actually needed. +// - **Upgrades to the `slice` view.** The `slice` view has been streamlined +// and simplified. When an expression with a `slice` view is expanded, it +// will simply expand to the slice's contents, which matches the behavior +// with static arrays. The `slice` view now also supports +// `first, one_past_last` pointer pairs, as well as `base_pointer, length` +// pairs. +// - **Boolean evaluation toggle-switches.** The debugger now displays toggle +// switches as an additional visualization and editor for all boolean +// evaluations. +// - **A new `range1` view** has been added, which expresses bounds for some +// scalar value. When this view is used in an evaluation, the debugger will // visualize the evaluation value with a slider, which can be used to edit // the value as well. -// - The hover evaluation feature has been majorly upgraded to support all -// features normally available in `Watch` tabs. -// - Added "transient tabs", which are colored differently than normal tabs. +// - **Merging of `Watch` UI with hover evaluation.** The hover evaluation +// feature has been majorly upgraded to support all features normally +// available in `Watch` tabs. +// - Added **transient tabs**, which are colored differently than normal tabs. // These tabs are automatically opened by the debugger when snapping to // source code which is not already opened. They are automatically replaced // and recycled when the debugger needs to snap to new locations. This will From bc67abe4ca2d530abf566f6a324f520bd042899e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 09:01:09 -0700 Subject: [PATCH 489/755] fix block type extraction in row build; the block tree build resolves evals to whatever types it is using for expansion, but sometimes we need to see types which have been stripped for row building (e.g. tables) --- src/eval/eval_core.c | 31 ++++++++++++++++++++++++++++--- src/eval/eval_core.h | 4 ++++ src/eval/eval_types.c | 2 +- src/raddbg/raddbg_views.c | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index d9d2fd15..591e3964 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -86,6 +86,13 @@ e_key_match(E_Key a, E_Key b) return result; } +internal E_Key +e_key_zero(void) +{ + E_Key key = {0}; + return key; +} + //////////////////////////////// //~ rjf: Type Key Type Functions @@ -883,6 +890,27 @@ e_interpretation_from_bundle(E_CacheBundle *bundle) return interpret; } +//- rjf: key -> full expression string + +internal String8 +e_full_expr_string_from_key(Arena *arena, E_Key key) +{ + E_CacheBundle *bundle = e_cache_bundle_from_key(key); + String8 result = push_str8_copy(arena, bundle->string); + if(!e_key_match(bundle->parent_key, e_key_zero())) + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct ParentResolveTask ParentResolveTask; + struct ParentResolveTask + { + ParentResolveTask *next; + E_Key key; + }; + scratch_end(scratch); + } + return result; +} + //- rjf: comprehensive bundle internal E_Eval @@ -961,9 +989,6 @@ e_value_eval_from_eval(E_Eval eval) return eval; } -//- rjf: string-based helpers -// TODO(rjf): (replace the old bundle APIs here) - //- rjf: type key -> auto hooks internal E_ExprList diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 27ed36ad..ffdddc5c 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -1016,6 +1016,7 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); //~ rjf: Key Type Functions internal B32 e_key_match(E_Key a, E_Key b); +internal E_Key e_key_zero(void); //////////////////////////////// //~ rjf: Type Key Type Functions @@ -1131,6 +1132,9 @@ internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); #define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) #define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) +//- rjf: key -> full expression string +internal String8 e_full_expr_string_from_key(Arena *arena, E_Key key); + //- rjf: comprehensive bundle internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); internal E_Eval e_value_eval_from_eval(E_Eval eval); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d15832f6..1be51681 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2251,7 +2251,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) Temp scratch = scratch_begin(&arena, 1); String8List allowed_children = {0}; { - E_Eval eval_stripped = e_eval_wrapf(eval, "raw($)"); + E_Eval eval_stripped = e_eval_wrapf(eval, "q:raw($)"); E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(eval_stripped.irtree.type_key); E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval_stripped, filter); if(expand_info.expr_count < 4096) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 473e0df8..b40db3c4 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -944,7 +944,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) E_Type *row_type = e_type_from_key__cached(row->eval.irtree.type_key); EV_Key key = row->key; EV_Block *block = row->block; - E_Eval block_eval = row->block->eval; + E_Eval block_eval = e_eval_from_key(row->block->eval.key); E_TypeKey block_type_key = e_type_key_unwrap(block_eval.irtree.type_key, E_TypeUnwrapFlag_Meta); E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); E_Type *block_type = e_type_from_key__cached(block_type_key); From f4e2728e9c290b88cd835f3256c7e4b1ac0c2ede Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 09:16:26 -0700 Subject: [PATCH 490/755] full evaluation expression string computation, use for expression drag/drop - resolve parent expression chain in order --- src/eval/eval_core.c | 44 +++++++++++++++++++++++++++++++++++++++- src/raddbg/raddbg_core.c | 3 ++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 591e3964..096c86a1 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -900,12 +900,54 @@ e_full_expr_string_from_key(Arena *arena, E_Key key) if(!e_key_match(bundle->parent_key, e_key_zero())) { Temp scratch = scratch_begin(&arena, 1); + + //- NOTE(rjf): any individual eval does not contain all information for + // reconstructing an entire "flattened" expression string. this is because + // one evaluation may be e.g. `$.x`, in the context of `foobar`, and so + // the full thing is evaluated as equivalent to `foobar.x`. In that case, + // `foobar` is referred to via the "parent key" of the evaluation for + // `$.x`. + // + // because parents may themselves have parents, e.g. `$.x` in the context + // of `$` in the context of `foobar`, we need to apply the parent + // expression strings to each parent. + // + // we do this in order, from oldest ancestor to the passed-in evaluation + // key, so we gather the fully-resolved string at the end of the chain. + + //- rjf: gather the entire chain of parents (in order of deepest ancestor -> shallowest) typedef struct ParentResolveTask ParentResolveTask; struct ParentResolveTask { ParentResolveTask *next; - E_Key key; + E_CacheBundle *bundle; }; + ParentResolveTask start_task = {0, bundle}; + ParentResolveTask *first_task = &start_task; + ParentResolveTask *last_task = first_task; + for(ParentResolveTask *t = first_task, *next = 0; t != 0; (t = next, next = 0)) + { + if(!e_key_match(t->bundle->parent_key, e_key_zero())) + { + ParentResolveTask *task = push_array(scratch.arena, ParentResolveTask, 1); + SLLQueuePushFront(first_task, last_task, task); + task->bundle = e_cache_bundle_from_key(t->bundle->parent_key); + next = task; + } + } + + //- rjf: walk the chain of tasks, from deepest -> shallowest, producing a + // more fully resolved string at each step + String8 parent_string = {0}; + for(ParentResolveTask *t = first_task; t != 0; t = t->next) + { + E_Parse parse = e_parse_from_bundle(t->bundle); + parent_string = e_string_from_expr(scratch.arena, parse.expr, parent_string); + } + + //- rjf: take final string as result + result = push_str8_copy(arena, parent_string); + scratch_end(scratch); } return result; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a6acec22..22cfe548 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2323,6 +2323,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { MD_NodePtrList schemas = rd_schemas_from_name(schema_name); + E_Expr *primary_expr = eval.expr; E_Expr **args = 0; U64 args_count = 0; @@ -4747,7 +4748,7 @@ rd_view_ui(Rng2F32 rect) cell->eval.space.kind == E_SpaceKind_File || cell->eval.space.kind == E_SpaceKind_Null) { - RD_RegsScope(.expr = e_string_from_expr(scratch.arena, cell->eval.expr, e_string_from_expr(scratch.arena, row->eval.expr, str8_zero()))) + RD_RegsScope(.expr = e_full_expr_string_from_key(scratch.arena, cell->eval.key)) rd_drag_begin(RD_RegSlot_Expr); } } From c9be93485fddb5ed645dd2e53e81d9a087df64e9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 09:27:49 -0700 Subject: [PATCH 491/755] build full evaluation expr string when building a view from an eval --- src/raddbg/raddbg_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 22cfe548..88a3f8b6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2336,8 +2336,9 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) args = type->args; args_count = type->count; } + E_Eval primary_eval = e_eval_from_expr(primary_expr); RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replace(expr_root, e_string_from_expr(scratch.arena, primary_expr, str8_zero())); + rd_cfg_new_replace(expr_root, e_full_expr_string_from_key(scratch.arena, primary_eval.key)); { U64 unnamed_order_idx = 0; for EachIndex(arg_idx, args_count) From ddbb2148a4f03fd6f8069bb63608590fade30dac Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 09:55:02 -0700 Subject: [PATCH 492/755] distinguish tabs vs. views in rd_regs --- src/raddbg/generated/raddbg.meta.c | 11 ++-- src/raddbg/generated/raddbg.meta.h | 7 ++- src/raddbg/raddbg.mdesk | 7 ++- src/raddbg/raddbg_core.c | 96 +++++++++++++++++------------- src/raddbg/raddbg_main.c | 1 + 5 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d8fb5ecb..d6dcf229 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -241,7 +241,7 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("build_tab"), str8_lit_comp(""), str8_lit_comp("Build Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("duplicate_tab"), str8_lit_comp(""), str8_lit_comp("Duplicate Tab"), str8_lit_comp(""), RD_IconKind_Duplicate}, {str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, -{str8_lit_comp("move_tab"), str8_lit_comp(""), str8_lit_comp("Move Tab"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_view"), str8_lit_comp(""), str8_lit_comp("Move View"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, {str8_lit_comp("tab_bar_bottom"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), str8_lit_comp(""), RD_IconKind_DownArrow}, {str8_lit_comp("tab_settings"), str8_lit_comp(""), str8_lit_comp("Tab Settings"), str8_lit_comp(""), RD_IconKind_Gear}, @@ -401,7 +401,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[22] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[42] = +Rng1U64 rd_reg_slot_range_table[43] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -411,6 +411,7 @@ Rng1U64 rd_reg_slot_range_table[42] = {OffsetOf(RD_Regs, ctrl_entity), OffsetOf(RD_Regs, ctrl_entity) + sizeof(CTRL_Handle)}, {OffsetOf(RD_Regs, window), OffsetOf(RD_Regs, window) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, panel), OffsetOf(RD_Regs, panel) + sizeof(RD_CfgID)}, +{OffsetOf(RD_Regs, tab), OffsetOf(RD_Regs, tab) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, view), OffsetOf(RD_Regs, view) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, prev_tab), OffsetOf(RD_Regs, prev_tab) + sizeof(RD_CfgID)}, {OffsetOf(RD_Regs, dst_panel), OffsetOf(RD_Regs, dst_panel) + sizeof(RD_CfgID)}, @@ -529,9 +530,9 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:tab_commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("build_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_View, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Tab, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Tab, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_view"), str8_lit_comp("Moves a view to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index af560e67..5f0c9210 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -16,6 +16,7 @@ RD_RegSlot_Thread, RD_RegSlot_CtrlEntity, RD_RegSlot_Window, RD_RegSlot_Panel, +RD_RegSlot_Tab, RD_RegSlot_View, RD_RegSlot_PrevTab, RD_RegSlot_DstPanel, @@ -137,7 +138,7 @@ RD_CmdKind_OpenTab, RD_CmdKind_BuildTab, RD_CmdKind_DuplicateTab, RD_CmdKind_CloseTab, -RD_CmdKind_MoveTab, +RD_CmdKind_MoveView, RD_CmdKind_TabBarTop, RD_CmdKind_TabBarBottom, RD_CmdKind_TabSettings, @@ -544,6 +545,7 @@ CTRL_Handle thread; CTRL_Handle ctrl_entity; RD_CfgID window; RD_CfgID panel; +RD_CfgID tab; RD_CfgID view; RD_CfgID prev_tab; RD_CfgID dst_panel; @@ -632,6 +634,7 @@ Z(getting_started)\ .ctrl_entity = rd_regs()->ctrl_entity,\ .window = rd_regs()->window,\ .panel = rd_regs()->panel,\ +.tab = rd_regs()->tab,\ .view = rd_regs()->view,\ .prev_tab = rd_regs()->prev_tab,\ .dst_panel = rd_regs()->dst_panel,\ @@ -672,7 +675,7 @@ extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; extern RD_VocabInfo rd_vocab_info_table[319]; extern RD_NameSchemaInfo rd_name_schema_info_table[22]; -extern Rng1U64 rd_reg_slot_range_table[42]; +extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5c8002c2..01476ca5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -637,6 +637,7 @@ RD_RegTable: // rjf: cfgs {RD_CfgID window Window } {RD_CfgID panel Panel } + {RD_CfgID tab Tab } {RD_CfgID view View } {RD_CfgID prev_tab PrevTab } {RD_CfgID dst_panel DstPanel } @@ -792,9 +793,9 @@ RD_CmdTable: // | | | | {MoveTabLeft 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 LeftArrow "move_tab_left" "Move Tab Left" "Moves the selected tab left one slot." "" "$tab," } {OpenTab 1 1 0 0 "query:tab_commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "open_tab" "Open New Tab" "Opens a new tab." "" "" } {BuildTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "build_tab" "Build Tab" "Opens a new tab with the parameterized view specification." "" "" } - {DuplicateTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } - {CloseTab 1 1 0 0 "" View null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } - {MoveTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_tab" "Move Tab" "Moves a tab to a new panel." "" "" } + {DuplicateTab 1 1 0 0 "" Tab null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } + {CloseTab 1 1 0 0 "" Tab null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } + {MoveView 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_view" "Move View" "Moves a view to a new panel." "" "" } {TabBarTop 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } {TabBarBottom 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "tab_bar_bottom" "Anchor Tab Bar To Bottom" "Anchors a panel's tab bar to the bottom of the panel." "" "$tab," } {TabSettings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Gear "tab_settings" "Tab Settings" "Opens settings for a tab." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 88a3f8b6..56f3aa59 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1229,6 +1229,10 @@ rd_setting_from_name(String8 name) B32 allow_bucket_chains; }; RD_Cfg *view_cfg = rd_cfg_from_id(rd_regs()->view); + if(view_cfg == &rd_nil_cfg) + { + view_cfg = rd_cfg_from_id(rd_regs()->tab); + } CfgSeedTask panel_task = {0, &rd_nil_cfg, 1}; if(panel_task.cfg == &rd_nil_cfg) { panel_task.cfg = rd_cfg_from_id(rd_regs()->panel); } if(panel_task.cfg == &rd_nil_cfg) { panel_task.cfg = rd_cfg_from_id(rd_regs()->window); } @@ -5777,7 +5781,8 @@ rd_window_frame(void) //- rjf: @window_frame_part fill panel/view interaction registers // rd_regs()->panel = panel_tree.focused->cfg->id; - rd_regs()->view = panel_tree.focused->selected_tab->id; + rd_regs()->tab = panel_tree.focused->selected_tab->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; ////////////////////////////// //- rjf: @window_frame_part build UI @@ -5791,7 +5796,7 @@ rd_window_frame(void) { // rjf: get top-level font size info F32 top_level_font_size = 0; - RD_RegsScope(.view = 0) top_level_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + RD_RegsScope(.view = 0, .tab = 0) top_level_font_size = rd_setting_f32_from_name(str8_lit("font_size")); // rjf: build icon info UI_IconInfo icon_info = {0}; @@ -6046,6 +6051,7 @@ rd_window_frame(void) if(rd_drag_is_active() && window_is_focused) RD_RegsScope(.window = rd_state->drag_drop_regs->window, .panel = rd_state->drag_drop_regs->panel, + .tab = 0, .view = rd_state->drag_drop_regs->view) { Temp scratch = scratch_begin(0, 0); @@ -6458,7 +6464,7 @@ rd_window_frame(void) // rjf: determine size of hover evaluation container EV_BlockTree predicted_block_tree = {0}; - RD_RegsScope(.view = view->id) + RD_RegsScope(.view = view->id, .tab = 0) { predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); } @@ -6601,7 +6607,7 @@ rd_window_frame(void) // rjf: compute query view's top-level rectangle Rng2F32 rect = {0}; - RD_RegsScope(.view = view->id) + RD_RegsScope(.view = view->id, .tab = 0) { F32 row_height_px = ui_top_font_size() * rd_setting_f32_from_name(str8_lit("row_height")); Vec2F32 content_rect_center = center_2f32(content_rect); @@ -7781,7 +7787,7 @@ rd_window_frame(void) rd_cmd(RD_CmdKind_SplitPanel, .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, + .view = rd_state->drag_drop_regs->view, .dir2 = dir); } } @@ -7873,7 +7879,7 @@ rd_window_frame(void) rd_cmd(RD_CmdKind_SplitPanel, .dst_panel = split_panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, + .view = rd_state->drag_drop_regs->view, .dir2 = dir); } @@ -8184,7 +8190,7 @@ rd_window_frame(void) } else { - rd_cmd(RD_CmdKind_MoveTab, + rd_cmd(RD_CmdKind_MoveView, .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, .view = rd_state->drag_drop_regs->view, @@ -8276,7 +8282,8 @@ rd_window_frame(void) { //- rjf: push interaction registers, fill with per-view states rd_push_regs(.panel = panel->cfg->id, - .view = selected_tab->id); + .tab = selected_tab->id, + .view = selected_tab->id); { String8 view_expr = rd_expr_from_cfg(selected_tab); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); @@ -8480,7 +8487,7 @@ rd_window_frame(void) //- rjf: build tab DR_FStrList tab_fstrs = tab_task->fstrs; F32 tab_width_px = tab_task->tab_width; - if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id) + if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id, .tab = tab->id) { // rjf: gather info for this tab B32 tab_is_selected = (tab == panel->selected_tab); @@ -8693,10 +8700,10 @@ rd_window_frame(void) // if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) { - rd_cmd(RD_CmdKind_MoveTab, + rd_cmd(RD_CmdKind_MoveView, .dst_panel = panel->cfg->id, .panel = rd_state->drag_drop_regs->panel, - .view = rd_state->drag_drop_regs->view, + .view = rd_state->drag_drop_regs->view, .prev_tab = tab_drop_prev->id); } @@ -8757,11 +8764,11 @@ rd_window_frame(void) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncFontSize, .view = 0); + rd_cmd(RD_CmdKind_IncFontSize, .tab = 0, .view = 0); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecFontSize, .view = 0); + rd_cmd(RD_CmdKind_DecFontSize, .tab = 0, .view = 0); } } } @@ -11758,6 +11765,7 @@ rd_frame(void) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(ws->cfg_id)); rd_regs()->window = ws->cfg_id; rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->tab = panel_tree.focused->selected_tab->id; rd_regs()->view = panel_tree.focused->selected_tab->id; scratch_end(scratch); } @@ -12743,7 +12751,7 @@ rd_frame(void) "query:thread_locals, " , tab->id, window->id); - rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1, .view = tab->id); + rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1, .view = tab->id, .tab = tab->id); }break; //- rjf: command fast paths @@ -13102,7 +13110,7 @@ rd_frame(void) case RD_CmdKind_IncFontSize: { RD_Cfg *cfg = &rd_nil_cfg; - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->view); } + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->tab); } if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } if(cfg != &rd_nil_cfg) { @@ -13117,7 +13125,7 @@ rd_frame(void) case RD_CmdKind_DecFontSize: { RD_Cfg *cfg = &rd_nil_cfg; - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->view); } + if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->tab); } if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } if(cfg != &rd_nil_cfg) { @@ -13272,7 +13280,7 @@ rd_frame(void) { if(!rd_cfg_is_project_filtered(n->v)) { - rd_cmd(RD_CmdKind_FocusTab, .panel = origin_panel->cfg->id, .view = n->v->id); + rd_cmd(RD_CmdKind_FocusTab, .panel = origin_panel->cfg->id, .tab = n->v->id); break; } } @@ -13281,7 +13289,7 @@ rd_frame(void) { rd_cmd(RD_CmdKind_ClosePanel); } - rd_cmd(RD_CmdKind_FocusTab, .panel = new_panel_cfg->id, .view = dragdrop_tab->id); + rd_cmd(RD_CmdKind_FocusTab, .panel = new_panel_cfg->id, .tab = dragdrop_tab->id); } // rjf: focus new panel @@ -13638,7 +13646,7 @@ rd_frame(void) //- rjf: panel tab controls case RD_CmdKind_FocusTab: { - RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); RD_Cfg *panel = tab->parent; RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, panel); RD_PanelNode *panel_node = rd_panel_node_from_tree_cfg(panel_tree.root, panel); @@ -13690,7 +13698,7 @@ rd_frame(void) } if(next_selected_tab != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + rd_cmd(RD_CmdKind_FocusTab, .tab = next_selected_tab->id); } }break; case RD_CmdKind_PrevTab: @@ -13721,13 +13729,13 @@ rd_frame(void) } if(next_selected_tab != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + rd_cmd(RD_CmdKind_FocusTab, .tab = next_selected_tab->id); } }break; case RD_CmdKind_MoveTabRight: case RD_CmdKind_MoveTabLeft: { - RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); RD_Cfg *window = rd_window_from_cfg(tab); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); @@ -13764,9 +13772,9 @@ rd_frame(void) { new_prev = filtered_tabs.last->v; } - rd_cmd(RD_CmdKind_MoveTab, + rd_cmd(RD_CmdKind_MoveView, .dst_panel = panel->cfg->id, - .view = tab->id, + .view = tab->id, .prev_tab = new_prev->id); }break; case RD_CmdKind_BuildTab: @@ -13781,18 +13789,18 @@ rd_frame(void) RD_Cfg *project = rd_cfg_new(tab, str8_lit("project")); rd_cfg_new(project, rd_state->project_path); } - rd_cmd(RD_CmdKind_FocusTab, .view = tab->id); + rd_cmd(RD_CmdKind_FocusTab, .tab = tab->id); }break; case RD_CmdKind_DuplicateTab: { - RD_Cfg *src = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *src = rd_cfg_from_id(rd_regs()->tab); RD_Cfg *dst = rd_cfg_deep_copy(src); rd_cfg_insert_child(src->parent, src, dst); - rd_cmd(RD_CmdKind_FocusTab, .view = dst->id); + rd_cmd(RD_CmdKind_FocusTab, .tab = dst->id); }break; case RD_CmdKind_CloseTab: { - RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, tab); RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); B32 found_selected = 0; @@ -13812,20 +13820,20 @@ rd_frame(void) } } } - rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id); + rd_cmd(RD_CmdKind_FocusTab, .tab = next_selected_tab->id); rd_cfg_release(tab); }break; - case RD_CmdKind_MoveTab: + case RD_CmdKind_MoveView: { - RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_tab); - RD_Cfg *src_panel = tab->parent; + RD_Cfg *src_panel = view->parent; RD_Cfg *dst_panel = rd_cfg_from_id(rd_regs()->dst_panel); - if(dst_panel != &rd_nil_cfg && prev_tab != tab) + if(dst_panel != &rd_nil_cfg && prev_tab != view) { - rd_cfg_unhook(src_panel, tab); - rd_cfg_insert_child(dst_panel, prev_tab, tab); - rd_cmd(RD_CmdKind_FocusTab, .panel = dst_panel->id, .view = tab->id); + rd_cfg_unhook(src_panel, view); + rd_cfg_insert_child(dst_panel, prev_tab, view); + rd_cmd(RD_CmdKind_FocusTab, .panel = dst_panel->id, .tab = view->id); rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->id); RD_PanelTree src_panel_tree = rd_panel_tree_from_cfg(scratch.arena, src_panel); RD_PanelNode *src_panel_node = rd_panel_node_from_tree_cfg(src_panel_tree.root, src_panel); @@ -13837,7 +13845,7 @@ rd_frame(void) { if(!rd_cfg_is_project_filtered(n->v)) { - rd_cmd(RD_CmdKind_FocusTab, .panel = src_panel->id, .view = n->v->id); + rd_cmd(RD_CmdKind_FocusTab, .panel = src_panel->id, .tab = n->v->id); src_panel_is_empty = 0; break; } @@ -13861,7 +13869,7 @@ rd_frame(void) }break; case RD_CmdKind_TabSettings: { - String8 expr = push_str8f(scratch.arena, "query:config.$%I64x", rd_regs()->view); + String8 expr = push_str8f(scratch.arena, "query:config.$%I64x", rd_regs()->tab); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_big_rows = 1, .do_lister = 1); }break; @@ -14564,7 +14572,7 @@ rd_frame(void) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_RegsScope(.view = tab->id) + RD_RegsScope(.tab = tab->id, .view = tab->id) { if(str8_match(tab->string, str8_lit("text"), 0) && rd_view_cfg_b32_from_string(str8_lit("auto"))) @@ -14629,7 +14637,7 @@ rd_frame(void) { RD_Cfg *tab = tab_n->v; if(rd_cfg_is_project_filtered(tab)) { continue; } - RD_RegsScope(.view = tab->id) + RD_RegsScope(.view = tab->id, .tab = tab->id) { B32 tab_is_selected = (tab == panel->selected_tab); String8 expr_string = rd_expr_from_cfg(tab); @@ -14795,7 +14803,8 @@ rd_frame(void) // rjf: move cursor & snap-to-cursor if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, - .view = dst_tab->id) + .view = dst_tab->id, + .tab = dst_tab->id) { rd_cmd(RD_CmdKind_FocusTab); if(point.line != 0) @@ -14830,6 +14839,7 @@ rd_frame(void) // rjf: move cursor & snap-to-cursor if(dst_panel != &rd_nil_panel_node) RD_RegsScope(.panel = dst_panel->cfg->id, + .tab = dst_tab->id, .view = dst_tab->id) { rd_cmd(RD_CmdKind_FocusTab); @@ -14866,7 +14876,7 @@ rd_frame(void) // rjf: non-floating -> embed in tab parameter else { - view = rd_cfg_from_id(rd_regs()->view); + view = rd_cfg_from_id(rd_regs()->tab); } // rjf: determine if the target view is a lister (and thus already has a command) @@ -16389,7 +16399,7 @@ rd_frame(void) { continue; } - RD_RegsScope(.view = tab->id) + RD_RegsScope(.tab = tab->id, .view = tab->id) { String8 eval_string = rd_expr_from_cfg(tab); String8 file_path = rd_file_path_from_eval_string(scratch.arena, eval_string); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index e407d0c7..fbecdb5f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -886,6 +886,7 @@ entry_point(CmdLine *cmd_line) RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, rd_cfg_from_id(dst_ws->cfg_id)); rd_regs()->window = dst_ws->cfg_id; rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->tab = panel_tree.focused->selected_tab->id; rd_regs()->view = panel_tree.focused->selected_tab->id; scratch_end(scratch); } From 09372bd7c10d9d930e671bfc8868ccdf6467b2f1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 12:15:41 -0700 Subject: [PATCH 493/755] color visualizer / theme editing work --- src/eval/eval_core.c | 1 + src/eval/eval_core.h | 3 +- .../eval_visualization_core.h | 2 +- src/raddbg/generated/raddbg.meta.c | 26 ++- src/raddbg/generated/raddbg.meta.h | 10 +- src/raddbg/raddbg.mdesk | 193 ++++++++++-------- src/raddbg/raddbg_core.c | 80 +++++--- src/raddbg/raddbg_main.c | 8 +- src/raddbg/raddbg_views.c | 174 +++++++--------- src/raddbg/raddbg_widgets.c | 6 +- src/ui/ui_basic_widgets.c | 58 ++++-- 11 files changed, 301 insertions(+), 260 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 096c86a1..ee4bd038 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -961,6 +961,7 @@ e_eval_from_bundle(E_CacheBundle *bundle) E_Eval eval = { .key = bundle->key, + .parent_key= bundle->parent_key, .string = bundle->string, .expr = e_parse_from_bundle(bundle).expr, .irtree = e_irtree_from_bundle(bundle), diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index ffdddc5c..6fcb5957 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -340,6 +340,7 @@ typedef struct E_Eval E_Eval; struct E_Eval { E_Key key; + E_Key parent_key; String8 string; E_Expr *expr; E_IRTreeAndType irtree; @@ -993,7 +994,7 @@ read_only global E_String2NumMap e_string2num_map_nil = {0}; read_only global E_String2ExprMap e_string2expr_map_nil = {0}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -read_only global E_Eval e_eval_nil = {{0}, {0}, &e_expr_nil, {&e_irnode_nil}}; +read_only global E_Eval e_eval_nil = {{0}, {0}, {0}, &e_expr_nil, {&e_irnode_nil}}; read_only global E_Module e_module_nil = {&rdi_parsed_nil}; read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; thread_static E_BaseCtx *e_base_ctx = 0; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index c7ff2bc7..e4bccf36 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -294,7 +294,7 @@ global read_only EV_Block ev_nil_block = {0}, 0, {0}, - {{0}, {0}, &e_expr_nil, &e_irnode_nil}, + {{0}, {0}, {0}, &e_expr_nil, &e_irnode_nil}, {0}, &e_type_expand_rule__default, {0}, diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d6dcf229..b652d4de 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[319] = +RD_VocabInfo rd_vocab_info_table[322] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -66,6 +66,7 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("address_location"), str8_lit_comp("address_locations"), str8_lit_comp("Address Location"), str8_lit_comp("Address Locations"), RD_IconKind_Null}, {str8_lit_comp("target"), str8_lit_comp("targets"), str8_lit_comp("Target"), str8_lit_comp("Targets"), RD_IconKind_Target}, {str8_lit_comp("color"), str8_lit_comp("colors"), str8_lit_comp("Color"), str8_lit_comp("Colors"), RD_IconKind_Palette}, +{str8_lit_comp("theme_color"), str8_lit_comp("theme_colors"), str8_lit_comp("Theme Color"), str8_lit_comp("Theme Colors"), RD_IconKind_Palette}, {str8_lit_comp("executable"), str8_lit_comp("executables"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, {str8_lit_comp("arguments"), str8_lit_comp("arguments"), str8_lit_comp("Arguments"), str8_lit_comp("Arguments"), RD_IconKind_Null}, {str8_lit_comp("exe"), str8_lit_comp("exes"), str8_lit_comp("Executable"), str8_lit_comp("Executables"), RD_IconKind_Module}, @@ -333,8 +334,10 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("add_color"), str8_lit_comp(""), str8_lit_comp("Add Color"), str8_lit_comp(""), RD_IconKind_Palette}, -{str8_lit_comp("import_colors"), str8_lit_comp(""), str8_lit_comp("Import Colors"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("open_theme"), str8_lit_comp(""), str8_lit_comp("Open Theme"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp(""), str8_lit_comp("Fork Loaded Theme Colors"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("save_theme_colors"), str8_lit_comp(""), str8_lit_comp("Save Theme Colors"), str8_lit_comp(""), RD_IconKind_Save}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -375,11 +378,11 @@ RD_VocabInfo rd_vocab_info_table[319] = {str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, }; -RD_NameSchemaInfo rd_name_schema_info_table[22] = +RD_NameSchemaInfo rd_name_schema_info_table[23] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: colors\n @display_name('Color Preset')\n 'color_preset': string,\n @display_name('Color File')\n 'color_file': path,\n @display_name('Colors')\n 'colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("color"), str8_lit_comp("@collection_commands(add_color, import_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -387,6 +390,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[22] = {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, @@ -448,7 +452,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[214] = +RD_CmdKindInfo rd_cmd_kind_info_table[216] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -624,8 +628,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[214] = { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_color"), str8_lit_comp("Adds a new color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("import_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_theme_colors"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -910,7 +916,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n color: {tags:\"background\", value: 0x1b1b1bff }\n color: {tags:\"alt background\", value: 0x222222ff }\n color: {tags:\"pop background\", value: 0x355b6eff }\n color: {tags:\"fresh background\", value: 0x31393dff }\n color: {tags:\"match background\", value: 0x31393dff }\n color: {tags:\"border\", value: 0x404040ff }\n color: {tags:\"text\", value: 0xe5e5e5ff }\n color: {tags:\"weak text\", value: 0xa4a4a4ff }\n color: {tags:\"good text\", value: 0x32a852ff }\n color: {tags:\"bad text\", value: 0xcf5242ff }\n color: {tags:\"hover\", value: 0xffffffff }\n color: {tags:\"focus\", value: 0xfda200ff }\n color: {tags:\"cursor\", value: 0x8aff00ff }\n color: {tags:\"selection\", value: 0x99ccffff }\n color: {tags:\"inactive background\", value: 0x0000002f }\n color: {tags:\"drop_shadow\", value: 0x0000007f }\n color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n color: {tags:\"good_pop border\", value: 0x568761ff }\n color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n color: {tags:\"bad_pop background\", value: 0x803425ff }\n color: {tags:\"bad_pop hover\", value: 0xff825cff }\n color: {tags:\"code_default\", value: 0xcbcbcbff }\n color: {tags:\"code_symbol\", value: 0x42a2cfff }\n color: {tags:\"code_type\", value: 0xfec746ff }\n color: {tags:\"code_local\", value: 0x98bc80ff }\n color: {tags:\"code_register\", value: 0xb7afd5ff }\n color: {tags:\"code_keyword\", value: 0xb38d4cff }\n color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n color: {tags:\"code_numeric\", value: 0x98abb1ff }\n color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n color: {tags:\"code_string\", value: 0x98abb1ff }\n color: {tags:\"code_meta\", value: 0xd96759ff }\n color: {tags:\"code_comment\", value: 0x717171ff }\n color: {tags:\"line_info_0\", value: 0x4f3022ff }\n color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n color: {tags:\"line_info_2\", value: 0x434e2aff }\n color: {tags:\"line_info_3\", value: 0x36241fff }\n color: {tags:\"line_info_4\", value: 0x4f3022ff }\n color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n color: {tags:\"line_info_6\", value: 0x434e2aff }\n color: {tags:\"line_info_7\", value: 0x36241fff }\n color: {tags:\"thread_0\", value: 0xffcb7fff }\n color: {tags:\"thread_1\", value: 0xb2ff65ff }\n color: {tags:\"thread_2\", value: 0xff99e5ff }\n color: {tags:\"thread_3\", value: 0x6598ffff }\n color: {tags:\"thread_4\", value: 0x65ffcbff }\n color: {tags:\"thread_5\", value: 0xff9819ff }\n color: {tags:\"thread_6\", value: 0x9932ffff }\n color: {tags:\"thread_7\", value: 0x65ff4cff }\n color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n color: {tags:\"thread_error\", value: 0xb23219ff }\n color: {tags:\"breakpoint\", value: 0xa72911ff }\n color: {tags:\"floating background\", value: 0x1b1b1baf }\n color: {tags:\"floating background alt\", value: 0x0000005f }\n color: {tags:\"floating background fresh\", value: 0x31393d5f }\n color: {tags:\"floating border\", value: 0xbfbfbf1f }\n color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n color: {tags:\"implicit background\", value: 0x00000000 }\n color: {tags:\"implicit border\", value: 0x00000000 }\n color: {tags:\"hollow background\", value: 0x00000000 }\n color: {tags:\"hollow border\", value: 0xffffff1f }\n color: {tags:\"tab background\", value: 0x6f5135ff }\n color: {tags:\"tab border\", value: 0x8a6e54ff }\n color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n color: {tags:\"tab auto background\", value: 0x693847ff }\n color: {tags:\"tab auto border\", value: 0x9e6274ff }\n color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n color: {tags:\"drop_site background\", value: 0xffffff05 }\n color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccffff }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 5f0c9210..d82571be 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -230,8 +230,10 @@ RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, RD_CmdKind_AddAutoViewRule, -RD_CmdKind_AddColor, -RD_CmdKind_ImportColors, +RD_CmdKind_OpenTheme, +RD_CmdKind_AddThemeColor, +RD_CmdKind_ForkLoadedThemeColors, +RD_CmdKind_SaveThemeColors, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -673,8 +675,8 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[319]; -extern RD_NameSchemaInfo rd_name_schema_info_table[22]; +extern RD_VocabInfo rd_vocab_info_table[322]; +extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 01476ca5..d1c49698 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -91,6 +91,7 @@ RD_VocabTable: {address_location _ "Address Location" _ Null } {target _ "Target" _ Target } {color _ "Color" _ Palette } + {theme_color _ "Theme Color" _ Palette } {executable _ "Executable" _ Module } {arguments arguments "Arguments" "Arguments" Null } {exe exes "Executable" _ Module } @@ -230,13 +231,13 @@ RD_VocabTable: @display_name('Code Font') @description("The name of, or path to, the font used when displaying code.") 'code_font': string, - //- rjf: colors - @display_name('Color Preset') - 'color_preset': string, - @display_name('Color File') - 'color_file': path, - @display_name('Colors') - 'colors': query, + //- rjf: theme + @display_name('Theme Preset') @description("The selected built-in theme preset.") + 'theme_preset': string, + @no_expand @display_name('Theme File') @description("The path from which theme data is loaded, overriding the preset.") + 'theme_file': path, + @display_name('Theme Colors') @description("Additional theme colors which are applied on top of the theme file or preset.") + 'theme_colors': query, //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") @@ -357,11 +358,11 @@ RD_VocabTable: ``` } - //- rjf: colors + //- rjf: theme colors { - color, + theme_color, ``` - @collection_commands(add_color, import_colors) x: + @collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) x: { @display_name('Tags') tags: string, @display_name('Value') value: @color @hex u32, @@ -492,6 +493,16 @@ RD_VocabTable: } ``` } + { + color, + ``` + @inherit(tab) x: + { + @display_name("Value") @description("An expression to describe the value or location of the color.") + 'expression': code_string, + } + ``` + } { geo3d, ``` @@ -920,9 +931,11 @@ RD_CmdTable: // | | | | //- rjf: auto view rule {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } - //- rjf: colors - {AddColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_color" "Add Color" "Adds a new color." "" "" } - {ImportColors 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "import_colors" "Import Colors" "Imports all colors from a loaded color theme file or color theme preset." "" "" } + //- rjf: themes + {OpenTheme 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } + {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } + {ForkLoadedThemeColors 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme_colors" "Fork Loaded Theme Colors" "Imports all colors from a loaded color theme file or color theme preset, so they can be individually edited." "" "" } + {SaveThemeColors 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_theme_colors" "Save Theme Colors" "Saves all theme colors to a new theme file." "" "" } //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } @@ -1302,83 +1315,83 @@ RD_ThemePresetTable: DefaultDark default_dark "Default (Dark)", ```theme: { - color: {tags:"background", value: 0x1b1b1bff } - color: {tags:"alt background", value: 0x222222ff } - color: {tags:"pop background", value: 0x355b6eff } - color: {tags:"fresh background", value: 0x31393dff } - color: {tags:"match background", value: 0x31393dff } - color: {tags:"border", value: 0x404040ff } - color: {tags:"text", value: 0xe5e5e5ff } - color: {tags:"weak text", value: 0xa4a4a4ff } - color: {tags:"good text", value: 0x32a852ff } - color: {tags:"bad text", value: 0xcf5242ff } - color: {tags:"hover", value: 0xffffffff } - color: {tags:"focus", value: 0xfda200ff } - color: {tags:"cursor", value: 0x8aff00ff } - color: {tags:"selection", value: 0x99ccffff } - color: {tags:"inactive background", value: 0x0000002f } - color: {tags:"drop_shadow", value: 0x0000007f } - color: {tags:"good_pop background", value: 0x2c5b36ff } - color: {tags:"good_pop border", value: 0x568761ff } - color: {tags:"good_pop hover", value: 0xe3f5d3ff } - color: {tags:"good_pop weak text", value: 0xe3f5d3ff } - color: {tags:"bad_pop background", value: 0x803425ff } - color: {tags:"bad_pop hover", value: 0xff825cff } - color: {tags:"code_default", value: 0xcbcbcbff } - color: {tags:"code_symbol", value: 0x42a2cfff } - color: {tags:"code_type", value: 0xfec746ff } - color: {tags:"code_local", value: 0x98bc80ff } - color: {tags:"code_register", value: 0xb7afd5ff } - color: {tags:"code_keyword", value: 0xb38d4cff } - color: {tags:"code_delimiter_or_operator", value: 0x767676ff } - color: {tags:"code_numeric", value: 0x98abb1ff } - color: {tags:"code_numeric_alt_digit_group", value: 0x738287ff } - color: {tags:"code_string", value: 0x98abb1ff } - color: {tags:"code_meta", value: 0xd96759ff } - color: {tags:"code_comment", value: 0x717171ff } - color: {tags:"line_info_0", value: 0x4f3022ff } - color: {tags:"line_info_1", value: 0x4f3e15ff } - color: {tags:"line_info_2", value: 0x434e2aff } - color: {tags:"line_info_3", value: 0x36241fff } - color: {tags:"line_info_4", value: 0x4f3022ff } - color: {tags:"line_info_5", value: 0x4f3e15ff } - color: {tags:"line_info_6", value: 0x434e2aff } - color: {tags:"line_info_7", value: 0x36241fff } - color: {tags:"thread_0", value: 0xffcb7fff } - color: {tags:"thread_1", value: 0xb2ff65ff } - color: {tags:"thread_2", value: 0xff99e5ff } - color: {tags:"thread_3", value: 0x6598ffff } - color: {tags:"thread_4", value: 0x65ffcbff } - color: {tags:"thread_5", value: 0xff9819ff } - color: {tags:"thread_6", value: 0x9932ffff } - color: {tags:"thread_7", value: 0x65ff4cff } - color: {tags:"thread_unwound", value: 0xb2ccd8ff } - color: {tags:"thread_error", value: 0xb23219ff } - color: {tags:"breakpoint", value: 0xa72911ff } - color: {tags:"floating background", value: 0x1b1b1baf } - color: {tags:"floating background alt", value: 0x0000005f } - color: {tags:"floating background fresh", value: 0x31393d5f } - color: {tags:"floating border", value: 0xbfbfbf1f } - color: {tags:"floating scroll_bar background", value: 0x3b3b3b5f } - color: {tags:"floating scroll_bar border", value: 0x5f5f5f5f } - color: {tags:"menu_bar background", value: 0x2b3740ff } - color: {tags:"menu_bar border", value: 0x3e4c57ff } - color: {tags:"scroll_bar background", value: 0x2b2b2bff } - color: {tags:"scroll_bar border", value: 0x3f3f3fff } - color: {tags:"implicit background", value: 0x00000000 } - color: {tags:"implicit border", value: 0x00000000 } - color: {tags:"hollow background", value: 0x00000000 } - color: {tags:"hollow border", value: 0xffffff1f } - color: {tags:"tab background", value: 0x6f5135ff } - color: {tags:"tab border", value: 0x8a6e54ff } - color: {tags:"tab inactive background", value: 0x2b3740ff } - color: {tags:"tab inactive border", value: 0x3e4c57ff } - color: {tags:"tab auto background", value: 0x693847ff } - color: {tags:"tab auto border", value: 0x9e6274ff } - color: {tags:"tab auto inactive background", value: 0x2f2633ff } - color: {tags:"tab auto inactive border", value: 0x685073ff } - color: {tags:"drop_site background", value: 0xffffff05 } - color: {tags:"drop_site border", value: 0xffffff0f } + theme_color: {tags:"background", value: 0x1b1b1bff } + theme_color: {tags:"alt background", value: 0x222222ff } + theme_color: {tags:"pop background", value: 0x355b6eff } + theme_color: {tags:"fresh background", value: 0x31393dff } + theme_color: {tags:"match background", value: 0x31393dff } + theme_color: {tags:"border", value: 0x404040ff } + theme_color: {tags:"text", value: 0xe5e5e5ff } + theme_color: {tags:"weak text", value: 0xa4a4a4ff } + theme_color: {tags:"good text", value: 0x32a852ff } + theme_color: {tags:"bad text", value: 0xcf5242ff } + theme_color: {tags:"hover", value: 0xffffffff } + theme_color: {tags:"focus", value: 0xfda200ff } + theme_color: {tags:"cursor", value: 0x8aff00ff } + theme_color: {tags:"selection", value: 0x99ccffff } + theme_color: {tags:"inactive background", value: 0x0000002f } + theme_color: {tags:"drop_shadow", value: 0x0000007f } + theme_color: {tags:"good_pop background", value: 0x2c5b36ff } + theme_color: {tags:"good_pop border", value: 0x568761ff } + theme_color: {tags:"good_pop hover", value: 0xe3f5d3ff } + theme_color: {tags:"good_pop weak text", value: 0xe3f5d3ff } + theme_color: {tags:"bad_pop background", value: 0x803425ff } + theme_color: {tags:"bad_pop hover", value: 0xff825cff } + theme_color: {tags:"code_default", value: 0xcbcbcbff } + theme_color: {tags:"code_symbol", value: 0x42a2cfff } + theme_color: {tags:"code_type", value: 0xfec746ff } + theme_color: {tags:"code_local", value: 0x98bc80ff } + theme_color: {tags:"code_register", value: 0xb7afd5ff } + theme_color: {tags:"code_keyword", value: 0xb38d4cff } + theme_color: {tags:"code_delimiter_or_operator", value: 0x767676ff } + theme_color: {tags:"code_numeric", value: 0x98abb1ff } + theme_color: {tags:"code_numeric_alt_digit_group", value: 0x738287ff } + theme_color: {tags:"code_string", value: 0x98abb1ff } + theme_color: {tags:"code_meta", value: 0xd96759ff } + theme_color: {tags:"code_comment", value: 0x717171ff } + theme_color: {tags:"line_info_0", value: 0x4f3022ff } + theme_color: {tags:"line_info_1", value: 0x4f3e15ff } + theme_color: {tags:"line_info_2", value: 0x434e2aff } + theme_color: {tags:"line_info_3", value: 0x36241fff } + theme_color: {tags:"line_info_4", value: 0x4f3022ff } + theme_color: {tags:"line_info_5", value: 0x4f3e15ff } + theme_color: {tags:"line_info_6", value: 0x434e2aff } + theme_color: {tags:"line_info_7", value: 0x36241fff } + theme_color: {tags:"thread_0", value: 0xffcb7fff } + theme_color: {tags:"thread_1", value: 0xb2ff65ff } + theme_color: {tags:"thread_2", value: 0xff99e5ff } + theme_color: {tags:"thread_3", value: 0x6598ffff } + theme_color: {tags:"thread_4", value: 0x65ffcbff } + theme_color: {tags:"thread_5", value: 0xff9819ff } + theme_color: {tags:"thread_6", value: 0x9932ffff } + theme_color: {tags:"thread_7", value: 0x65ff4cff } + theme_color: {tags:"thread_unwound", value: 0xb2ccd8ff } + theme_color: {tags:"thread_error", value: 0xb23219ff } + theme_color: {tags:"breakpoint", value: 0xa72911ff } + theme_color: {tags:"floating background", value: 0x1b1b1baf } + theme_color: {tags:"floating background alt", value: 0x0000005f } + theme_color: {tags:"floating background fresh", value: 0x31393d5f } + theme_color: {tags:"floating border", value: 0xbfbfbf1f } + theme_color: {tags:"floating scroll_bar background", value: 0x3b3b3b5f } + theme_color: {tags:"floating scroll_bar border", value: 0x5f5f5f5f } + theme_color: {tags:"menu_bar background", value: 0x2b3740ff } + theme_color: {tags:"menu_bar border", value: 0x3e4c57ff } + theme_color: {tags:"scroll_bar background", value: 0x2b2b2bff } + theme_color: {tags:"scroll_bar border", value: 0x3f3f3fff } + theme_color: {tags:"implicit background", value: 0x00000000 } + theme_color: {tags:"implicit border", value: 0x00000000 } + theme_color: {tags:"hollow background", value: 0x00000000 } + theme_color: {tags:"hollow border", value: 0xffffff1f } + theme_color: {tags:"tab background", value: 0x6f5135ff } + theme_color: {tags:"tab border", value: 0x8a6e54ff } + theme_color: {tags:"tab inactive background", value: 0x2b3740ff } + theme_color: {tags:"tab inactive border", value: 0x3e4c57ff } + theme_color: {tags:"tab auto background", value: 0x693847ff } + theme_color: {tags:"tab auto border", value: 0x9e6274ff } + theme_color: {tags:"tab auto inactive background", value: 0x2f2633ff } + theme_color: {tags:"tab auto inactive border", value: 0x685073ff } + theme_color: {tags:"drop_site background", value: 0xffffff05 } + theme_color: {tags:"drop_site border", value: 0xffffff0f } } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 56f3aa59..226732df 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2326,24 +2326,27 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { - MD_NodePtrList schemas = rd_schemas_from_name(schema_name); - - E_Expr *primary_expr = eval.expr; - E_Expr **args = 0; - U64 args_count = 0; + // rjf: get expression evaluation + E_Eval expr_eval = eval; if(eval.expr->kind == E_ExprKind_Call) { - primary_expr = eval.expr->first->next; + expr_eval = e_eval_from_expr(eval.expr->first->next); } + + // rjf: get arguments to view + E_Expr **args = 0; + U64 args_count = 0; if(type->args != 0) { args = type->args; args_count = type->count; } - E_Eval primary_eval = e_eval_from_expr(primary_expr); + + // rjf: reflect expr & arguments in cfg tree RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replace(expr_root, e_full_expr_string_from_key(scratch.arena, primary_eval.key)); + rd_cfg_new_replace(expr_root, e_full_expr_string_from_key(scratch.arena, expr_eval.key)); { + MD_NodePtrList schemas = rd_schemas_from_name(schema_name); U64 unnamed_order_idx = 0; for EachIndex(arg_idx, args_count) { @@ -3284,13 +3287,17 @@ rd_view_ui(Rng2F32 rect) } else if(e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Set) { - rd_cmd(RD_CmdKind_PushQuery, .expr = e_string_from_expr(scratch.arena, eval.expr, str8_zero())); + rd_cmd(RD_CmdKind_PushQuery, .expr = e_full_expr_string_from_key(scratch.arena, eval.key)); } else { did_cmd = 0; } }break; + case RD_EvalSpaceKind_MetaQuery: + { + rd_cmd(RD_CmdKind_PushQuery, .expr = e_full_expr_string_from_key(scratch.arena, eval.key)); + }break; case RD_EvalSpaceKind_MetaUnattachedProcess: { U64 pid = eval.value.u128.u64[0]; @@ -4496,14 +4503,14 @@ rd_view_ui(Rng2F32 rect) UI_Flags(0) { // rjf: 'pull out' button - UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f, - ui_top_font_size()*1.5f + ui_top_font_size()*3.f)) - UI_CornerRadius(ui_top_font_size()*1.5f) + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(floor_f32(ui_top_font_size()*1.5f), + floor_f32(ui_top_font_size()*1.5f), + floor_f32(ui_top_font_size()*1.5f + ui_top_font_size()*3.f), + floor_f32(ui_top_font_size()*1.5f + ui_top_font_size()*3.f))) + UI_CornerRadius(floor_f32(ui_top_font_size()*1.5f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) - UI_FontSize(ui_top_font_size()*0.8f) + UI_FontSize(floor_f32(ui_top_font_size()*0.9f)) { UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| UI_BoxFlag_Floating| @@ -4786,6 +4793,8 @@ rd_view_ui(Rng2F32 rect) // rjf: has a command name? -> push command else if(cell_info.cmd_name.size != 0) { + String8 cmd_name = cell_info.cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(row->eval.space); RD_Cfg *cfg = rd_cfg_from_eval_space(row->eval.space); if(cfg == &rd_nil_cfg) @@ -4794,13 +4803,13 @@ rd_view_ui(Rng2F32 rect) } RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) { - if(cfg != &rd_nil_cfg || entity != &ctrl_entity_nil) + if(!(cmd_kind_info->query.flags & RD_QueryFlag_Required)) { rd_push_cmd(cell_info.cmd_name, rd_regs()); } else { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cell_info.cmd_name); + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = cmd_name); } } } @@ -5548,7 +5557,7 @@ rd_window_frame(void) } for(RD_Cfg *child = parent_cfg->first; child != &rd_nil_cfg; child = child->next) { - if(str8_match(child->string, str8_lit("color"), 0)) + if(str8_match(child->string, str8_lit("theme_color"), 0)) { rd_cfg_list_push_front(scratch.arena, &colors_cfgs, child); } @@ -5606,7 +5615,7 @@ rd_window_frame(void) MD_Node *tree_root = t->tree; for(MD_Node *n = tree_root; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, tree_root).next) { - if(str8_match(n->string, str8_lit("color"), 0)) + if(str8_match(n->string, str8_lit("theme_color"), 0)) { MD_Node *tags_child = md_child_from_string(n, str8_lit("tags"), 0); MD_Node *value_child = md_child_from_string(n, str8_lit("value"), 0); @@ -11638,8 +11647,8 @@ rd_frame(void) RD_Theme *theme_srgba = push_array(scratch.arena, RD_Theme, 1); //- rjf: gather globally-applying config options - RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("color_preset")); - RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("colors")); + RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("theme_preset")); + RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("theme_colors")); //- rjf: assume default-dark MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); @@ -12349,10 +12358,9 @@ rd_frame(void) { .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(call_stack), })); - e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("colors"), + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("theme_colors"), e_type_key_cons(.kind = E_TypeKind_Set, - .flags = E_TypeFlag_EditableChildren, - .name = str8_lit("colors"), + .name = str8_lit("theme_colors"), .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs_slice), .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs_slice), .expand = @@ -15227,33 +15235,39 @@ rd_frame(void) rd_cfg_new(project, str8_lit("auto_view_rule")); }break; - //- rjf: colors - case RD_CmdKind_AddColor: + //- rjf: themes + case RD_CmdKind_OpenTheme: + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *theme_file = rd_cfg_child_from_string_or_alloc(user, str8_lit("theme_file")); + rd_cfg_new_replace(theme_file, rd_regs()->file_path); + }break; + case RD_CmdKind_AddThemeColor: { RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); - RD_Cfg *color = rd_cfg_new(parent, str8_lit("color")); + RD_Cfg *color = rd_cfg_new(parent, str8_lit("theme_color")); rd_cfg_new(color, str8_lit("tags")); RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); rd_cfg_new(value, str8_lit("0xffffffff")); }break; - case RD_CmdKind_ImportColors: + case RD_CmdKind_ForkLoadedThemeColors: { RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); - RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("color")); + RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); for(RD_CfgNode *n = colors.first; n != 0; n = n->next) { rd_cfg_release(n->v); } - String8 color_preset = rd_setting_from_name(str8_lit("color_preset")); - String8 color_file = rd_setting_from_name(str8_lit("color_file")); + String8 color_preset = rd_setting_from_name(str8_lit("theme_preset")); + String8 color_file = rd_setting_from_name(str8_lit("theme_file")); RD_ThemePreset preset = RD_ThemePreset_DefaultDark; // TODO(rjf): map preset via string MD_Node *theme_tree = rd_state->theme_preset_trees[preset]; for(MD_Node *n = theme_tree; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next) { - if(str8_match(n->string, str8_lit("color"), 0)) + if(str8_match(n->string, str8_lit("theme_color"), 0)) { - RD_Cfg *color = rd_cfg_new(parent, str8_lit("color")); + RD_Cfg *color = rd_cfg_new(parent, str8_lit("theme_color")); RD_Cfg *tags = rd_cfg_new(color, str8_lit("tags")); RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); rd_cfg_new(tags, md_child_from_string(n, str8_lit("tags"), 0)->first->string); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index fbecdb5f..81c2cb64 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -188,10 +188,6 @@ // [ ] config hot-reloading, using cfg wins // [ ] undo/redo, using cfg wins // [ ] back/forward, using cfg wins -// [ ] autocompletion lister, file lister, function lister, command lister, -// etc., all need to be merged, and optionally contextualized/filtered. -// right-clicking a tab should be equivalent to spawning a command lister, -// but only with commands that are directly // // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // @@ -463,6 +459,10 @@ // since that's not normally how Windows fonts work. // [x] I had to go into the user file to change the font. That should probably // be in the theme window? +// [x] autocompletion lister, file lister, function lister, command lister, +// etc., all need to be merged, and optionally contextualized/filtered. +// right-clicking a tab should be equivalent to spawning a command lister, +// but only with commands that are directly //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b40db3c4..4a9a1a57 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3485,8 +3485,11 @@ rd_eval_color_from_eval(E_Eval eval) { default:{}break; - // rjf: leaf u32 -> take all 4 components + // rjf: leaf >u32/s32 -> take all 4 components case E_TypeKind_U32: + case E_TypeKind_S32: + case E_TypeKind_U64: + case E_TypeKind_S64: { component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); @@ -3521,40 +3524,42 @@ rd_eval_color_from_eval(E_Eval eval) break; } } - if(lens_type->kind == E_TypeKind_Lens) + String8 format_string = str8_lit("rgba"); + if(lens_type->kind == E_TypeKind_Lens && lens_type->count > 0) { - if(lens_type->count < 1 || str8_match(lens_type->args[0]->string, str8_lit("rgba"), 0)) - { - result.rgba_evals[0] = component_evals[0]; - result.rgba_evals[1] = component_evals[1]; - result.rgba_evals[2] = component_evals[2]; - result.rgba_evals[3] = component_evals[3]; - } - else if(str8_match(lens_type->args[0]->string, str8_lit("argb"), 0)) - { - result.rgba_evals[0] = component_evals[1]; - result.rgba_evals[1] = component_evals[2]; - result.rgba_evals[2] = component_evals[3]; - result.rgba_evals[3] = component_evals[0]; - } - else if(str8_match(lens_type->args[0]->string, str8_lit("bgra"), 0)) - { - result.rgba_evals[0] = component_evals[2]; - result.rgba_evals[1] = component_evals[1]; - result.rgba_evals[2] = component_evals[0]; - result.rgba_evals[3] = component_evals[3]; - } - else if(str8_match(lens_type->args[0]->string, str8_lit("abgr"), 0)) - { - result.rgba_evals[0] = component_evals[3]; - result.rgba_evals[1] = component_evals[2]; - result.rgba_evals[2] = component_evals[1]; - result.rgba_evals[3] = component_evals[0]; - } - for EachIndex(idx, 4) - { - result.rgba.v[idx] = e_value_eval_from_eval(result.rgba_evals[idx]).value.f32; - } + format_string = lens_type->args[0]->string; + } + if(str8_match(format_string, str8_lit("rgba"), 0)) + { + result.rgba_evals[0] = component_evals[0]; + result.rgba_evals[1] = component_evals[1]; + result.rgba_evals[2] = component_evals[2]; + result.rgba_evals[3] = component_evals[3]; + } + else if(str8_match(format_string, str8_lit("argb"), 0)) + { + result.rgba_evals[0] = component_evals[1]; + result.rgba_evals[1] = component_evals[2]; + result.rgba_evals[2] = component_evals[3]; + result.rgba_evals[3] = component_evals[0]; + } + else if(str8_match(format_string, str8_lit("bgra"), 0)) + { + result.rgba_evals[0] = component_evals[2]; + result.rgba_evals[1] = component_evals[1]; + result.rgba_evals[2] = component_evals[0]; + result.rgba_evals[3] = component_evals[3]; + } + else if(str8_match(format_string, str8_lit("abgr"), 0)) + { + result.rgba_evals[0] = component_evals[3]; + result.rgba_evals[1] = component_evals[2]; + result.rgba_evals[2] = component_evals[1]; + result.rgba_evals[3] = component_evals[0]; + } + for EachIndex(idx, 4) + { + result.rgba.v[idx] = e_value_eval_from_eval(result.rgba_evals[idx]).value.f32; } } @@ -3573,72 +3578,43 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(color) RD_VIEW_UI_FUNCTION_DEF(color) { Temp scratch = scratch_begin(0, 0); - Vec2F32 dim = dim_2f32(rect); - F32 padding = ui_top_font_size()*3.f; - F32 sv_dim_px = Min(dim.x, dim.y); - if(sv_dim_px == dim.x) + + ////////////////////////////// + //- rjf: unpack state + // + typedef struct RD_ColorViewState RD_ColorViewState; + struct RD_ColorViewState { - padding = ui_top_font_size()*30.f; + B32 initialized; + U32 start_rgba_u32; + Vec4F32 hsva; + }; + RD_ColorViewState *state = rd_view_state(RD_ColorViewState); + RD_EvalColor eval_color = rd_eval_color_from_eval(eval); + U32 rgba_u32 = u32_from_rgba(eval_color.rgba); + if(!state->initialized || rgba_u32 != state->start_rgba_u32) + { + Vec4F32 rgba = eval_color.rgba; + Vec4F32 hsva = hsva_from_rgba(rgba); + state->initialized = 1; + state->start_rgba_u32 = rgba_u32; + state->hsva = hsva; } + Vec4F32 hsva = state->hsva; + Vec4F32 rgba = rgba_from_hsva(hsva); + + ////////////////////////////// + //- rjf: calculate dimensions + // + Vec2F32 dim = dim_2f32(rect); + F32 sv_dim_px = Min(dim.x, dim.y); + F32 padding = sv_dim_px*0.2f; sv_dim_px -= padding*2.f; sv_dim_px = Min(sv_dim_px, ui_top_font_size()*70.f); - RD_EvalColor eval_color = rd_eval_color_from_eval(eval); - Vec4F32 rgba = eval_color.rgba; - Vec4F32 hsva = hsva_from_rgba(rgba); ////////////////////////////// - //- rjf: too small -> just show components + //- rjf: build UI // - if(dim.y <= ui_top_font_size()*12.f) - { - //- rjf: build text box - UI_Box *text_box = &ui_nil_box; - UI_WidthFill RD_Font(RD_FontSlot_Code) - { - text_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - DR_FStrList fstrs = {0}; - { - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("(")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.x), .color = linear_from_srgba(v4f32(1.f, 0.25f, 0.25f, 1.f)), .underline_thickness = 4.f); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.y), .color = linear_from_srgba(v4f32(0.25f, 1.f, 0.25f, 1.f)), .underline_thickness = 4.f); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.z), .color = linear_from_srgba(v4f32(0.25f, 0.25f, 1.f, 1.f)), .underline_thickness = 4.f); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", ")); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, push_str8f(scratch.arena, "%.2f", rgba.w), .color = v4f32(1.f, 1.f, 1.f, 1.f), .underline_thickness = 4.f); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")")); - } - ui_box_equip_display_fstrs(text_box, &fstrs); - } - - //- rjf: build color box - UI_Box *color_box = &ui_nil_box; - UI_PrefWidth(ui_em(1.875f, 1.f)) UI_ChildLayoutAxis(Axis2_Y) - { - color_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "color_box"); - UI_Parent(color_box) UI_PrefHeight(ui_em(1.875f, 1.f)) UI_Padding(ui_pct(1, 0)) - { - UI_BackgroundColor(rgba) UI_CornerRadius(ui_top_font_size()*0.5f) - ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); - } - } - - //- rjf: space - ui_spacer(ui_em(0.375f, 1.f)); - - //- rjf: hover color box -> show components - UI_Signal sig = ui_signal_from_box(color_box); - if(ui_hovering(sig)) - { - ui_do_color_tooltip_hsva(hsva); - } - } - - ////////////////////////////// - //- rjf: large enough -> full color picker - // - else { UI_WidthFill UI_HeightFill UI_PrefHeight(ui_children_sum(1)) UI_Column UI_Padding(ui_pct(1.f, 0.f)) @@ -3701,17 +3677,23 @@ RD_VIEW_UI_FUNCTION_DEF(color) { // TODO(rjf): hard-coding U32 committing for now E_Type *type = e_type_from_key__cached(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); - if(type->kind == E_TypeKind_U32) + if(type->kind == E_TypeKind_U32 || + type->kind == E_TypeKind_S32 || + type->kind == E_TypeKind_U64 || + type->kind == E_TypeKind_S64) { Vec4F32 new_rgba = rgba_from_hsva(hsva); U32 u32 = u32_from_rgba(new_rgba); String8 string = push_str8f(scratch.arena, "0x%x", u32); - rd_commit_eval_value_string(eval, string); + if(rd_commit_eval_value_string(eval, string)) + { + state->start_rgba_u32 = u32; + state->hsva = hsva; + } } } } } - scratch_end(scratch); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 0685b77c..7f87869d 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -394,7 +394,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } //- rjf: special case: colors - if(str8_match(cfg->string, str8_lit("color"), 0)) + if(str8_match(cfg->string, str8_lit("theme_color"), 0)) { String8 tags = rd_cfg_child_from_string(cfg, str8_lit("tags"))->first->string; String8 color_string = rd_cfg_child_from_string(cfg, str8_lit("value"))->first->string; @@ -402,12 +402,14 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) Vec4F32 color = linear_from_srgba(rgba_from_u32(color_u32)); if(tags.size != 0) { - dr_fstrs_push_new(arena, &result, ¶ms, tags, .color = color); + dr_fstrs_push_new(arena, &result, ¶ms, tags); } else { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit("Color"), .color = rgba_secondary); } + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_CircleFilled], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = color); } #undef start_secondary diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index acf08194..4f440de1 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -565,20 +565,40 @@ internal UI_BOX_CUSTOM_DRAW(ui_sat_val_picker_draw) // rjf: hue => rgb Vec3F32 hue_rgb = rgb_from_hsv(v3f32(data->hue, 1, 1)); + Vec3F32 hue_rgb_linear = linear_from_srgb(hue_rgb); - // rjf: white -> rgb background + // rjf: rgb background { - R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, -1.f), v4f32(hue_rgb.x, hue_rgb.y, hue_rgb.z, 1), 4.f, 0, 1.f); + dr_rect(pad_2f32(box->rect, -1.f), v4f32(hue_rgb_linear.x, hue_rgb_linear.y, hue_rgb_linear.z, 1), 4.f, 0, 1.f); + } + + // rjf: white gradient overlay + { + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, -1.f), v4f32(hue_rgb_linear.x, hue_rgb_linear.y, hue_rgb_linear.z, 0), 4.f, 0, 1.f); inst->colors[Corner_00] = inst->colors[Corner_01] = v4f32(1, 1, 1, 1); } - // rjf: black gradient overlay + // rjf: black gradient overlay pt. 1 + { + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, -1.f), v4f32(0, 0, 0, 0), 4.f, 0, 1.f); + inst->colors[Corner_01] = v4f32(0, 0, 0, 1.f); + inst->colors[Corner_11] = v4f32(0, 0, 0, 1.f); + } + + // rjf: black gradient overlay pt. 2 { R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, -1.f), v4f32(0, 0, 0, 0), 4.f, 0, 1.f); inst->colors[Corner_01] = v4f32(0, 0, 0, 1); inst->colors[Corner_11] = v4f32(0, 0, 0, 1); } + // rjf: black gradient overlay pt. 3 + { + R_Rect2DInst *inst = dr_rect(pad_2f32(box->rect, -1.f), v4f32(0, 0, 0, 0), 4.f, 0, 1.f); + inst->colors[Corner_01] = v4f32(0, 0, 0, 0.2f); + inst->colors[Corner_11] = v4f32(0, 0, 0, 0.2f); + } + // rjf: indicator { Vec2F32 box_rect_dim = dim_2f32(box->rect); @@ -588,7 +608,7 @@ internal UI_BOX_CUSTOM_DRAW(ui_sat_val_picker_draw) center.y - half_size, center.x + half_size, center.y + half_size); - dr_rect(rect, v4f32(1, 1, 1, 1), half_size/2, 2.f, 1.f); + dr_rect(rect, v4f32(1, 1, 1, 1), half_size/2.f, 2.f, 1.f); } } @@ -677,13 +697,13 @@ internal UI_BOX_CUSTOM_DRAW(ui_hue_picker_draw) F32 hue1 = (F32)(seg+1)/6; Vec3F32 rgb0 = rgb_from_hsv(v3f32(hue0, 1, 1)); Vec3F32 rgb1 = rgb_from_hsv(v3f32(hue1, 1, 1)); - Vec4F32 rgba0 = v4f32(rgb0.x, rgb0.y, rgb0.z, 1); - Vec4F32 rgba1 = v4f32(rgb1.x, rgb1.y, rgb1.z, 1); + Vec4F32 rgba0_linear = linear_from_srgba(v4f32(rgb0.x, rgb0.y, rgb0.z, 1)); + Vec4F32 rgba1_linear = linear_from_srgba(v4f32(rgb1.x, rgb1.y, rgb1.z, 1)); R_Rect2DInst *inst = dr_rect(rect, v4f32(0, 0, 0, 0), 0, 0, 0.f); - inst->colors[Corner_00] = rgba0; - inst->colors[Corner_01] = rgba1; - inst->colors[Corner_10] = rgba0; - inst->colors[Corner_11] = rgba1; + inst->colors[Corner_00] = rgba0_linear; + inst->colors[Corner_01] = rgba1_linear; + inst->colors[Corner_10] = rgba0_linear; + inst->colors[Corner_11] = rgba1_linear; rect.y0 += segment_dim; rect.y1 += segment_dim; } @@ -691,13 +711,13 @@ internal UI_BOX_CUSTOM_DRAW(ui_hue_picker_draw) // rjf: indicator { Vec2F32 box_rect_dim = dim_2f32(box->rect); - Vec2F32 center = v2f32((box->rect.x0+box->rect.x1)/2, box->rect.y0 + data->hue*box_rect_dim.y); - F32 half_size = box->font_size * (0.5f + box->active_t*0.2f); + Vec2F32 center = v2f32((box->rect.x0+box->rect.x1)/2, box->rect.y0 + (data->hue)*box_rect_dim.y); + F32 half_size = box_rect_dim.x * (0.52f + 0.02f * box->active_t); Rng2F32 rect = r2f32p(center.x - half_size, - center.y - 2.f, + center.y - box->font_size * (0.5f + 0.1f * box->active_t), center.x + half_size, - center.y + 2.f); - dr_rect(rect, v4f32(1, 1, 1, 1), half_size/2, 2.f, 1.f); + center.y + box->font_size * (0.5f + 0.1f * box->active_t)); + dr_rect(rect, v4f32(1, 1, 1, 1), 1.f, 2.f, 1.f); } } @@ -779,12 +799,12 @@ internal UI_BOX_CUSTOM_DRAW(ui_alpha_picker_draw) { Vec2F32 box_rect_dim = dim_2f32(box->rect); Vec2F32 center = v2f32((box->rect.x0+box->rect.x1)/2, box->rect.y0 + (1-data->alpha)*box_rect_dim.y); - F32 half_size = box->font_size * (0.5f + box->active_t*0.2f); + F32 half_size = box_rect_dim.x * (0.52f + 0.02f * box->active_t); Rng2F32 rect = r2f32p(center.x - half_size, - center.y - 2.f, + center.y - box->font_size * (0.5f + 0.1f * box->active_t), center.x + half_size, - center.y + 2.f); - dr_rect(rect, v4f32(1, 1, 1, 1), half_size/2, 2.f, 1.f); + center.y + box->font_size * (0.5f + 0.1f * box->active_t)); + dr_rect(rect, v4f32(1, 1, 1, 1), 1.f, 2.f, 1.f); } } From 3e6efb89352a94d2d47951b6efb057b82d3e847e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 13:21:52 -0700 Subject: [PATCH 494/755] fix lister row flags --- src/raddbg/raddbg_views.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4a9a1a57..8dd63020 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -823,9 +823,9 @@ rd_id_from_watch_cell(RD_WatchCell *cell) { U64 result = 5381; result = e_hash_from_string(result, str8_struct(&cell->kind)); - if(!(cell->flags & RD_WatchCellFlag_Expr)) + result = e_hash_from_string(result, str8_struct(&cell->index)); + if(cell->index != 0) { - result = e_hash_from_string(result, str8_struct(&cell->index)); result = e_hash_from_string(result, str8_struct(&cell->default_pct)); } return result; @@ -1166,12 +1166,12 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("lister")) != &rd_nil_cfg) { info.can_expand = 0; - RD_WatchCellFlags extra_flags = 0; - if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity) + RD_WatchCellFlags extra_flags = RD_WatchCellFlag_Expr; + if(e_type_kind_from_key(e_type_key_unwrap(row->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)) == E_TypeKind_Function) { - extra_flags |= RD_WatchCellFlag_NoEval; + extra_flags &= ~RD_WatchCellFlag_Expr; } - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = extra_flags|RD_WatchCellFlag_Expr|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = extra_flags|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } //////////////////////////// From 195883cbcb9c73af0b2bffa1575c09d518d9b8a7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 13:50:20 -0700 Subject: [PATCH 495/755] stub single line expansion flag --- src/eval/eval_core.h | 21 +++++----- .../eval_visualization_core.c | 15 +++++-- src/raddbg/raddbg_core.c | 40 +++++++++++++------ 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 6fcb5957..b1d2c3d7 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -374,16 +374,17 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_IsNotText = (1<<5), - E_TypeFlag_EditableChildren = (1<<6), - E_TypeFlag_InheritedByMembers = (1<<7), - E_TypeFlag_InheritedByElements = (1<<8), - E_TypeFlag_ArrayLikeExpansion = (1<<9), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_IsNotText = (1<<5), + E_TypeFlag_EditableChildren = (1<<6), + E_TypeFlag_InheritedByMembers = (1<<7), + E_TypeFlag_InheritedByElements = (1<<8), + E_TypeFlag_ArrayLikeExpansion = (1<<9), + E_TypeFlag_StubSingleLineExpansion = (1<<10), }; typedef struct E_Member E_Member; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 3a013dd0..0b6edc45 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -2138,16 +2138,23 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); expand_data->type = e_type_from_key__cached(type_key); - expand_data->expand_rule = e_expand_rule_from_type_key(type_key); - expand_data->expand_info = expand_data->expand_rule->info(arena, eval, params->filter); } switch(task_idx) { //- rjf: step 0 -> generate opener symbol case 0: { - need_pop = 0; - *out_string = expansion_opener_symbol; + if(expand_data->type->flags & E_TypeFlag_StubSingleLineExpansion) + { + *out_string = push_str8f(arena, "%S...%S", expansion_opener_symbol, expansion_closer_symbol); + } + else + { + need_pop = 0; + expand_data->expand_rule = e_expand_rule_from_type_key(type_key); + expand_data->expand_info = expand_data->expand_rule->info(arena, eval, params->filter); + *out_string = expansion_opener_symbol; + } }break; default: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 226732df..3f858790 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4371,14 +4371,6 @@ rd_view_ui(Rng2F32 rect) //////////// //- rjf: unpack cell info // - U64 cell_id = rd_id_from_watch_cell(cell); - RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; - RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); - B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - E_TypeKey cell_type_key = cell->eval.irtree.type_key; - E_Type *cell_type = e_type_from_key__cached(cell_type_key); - E_Eval cell_value_eval = e_value_eval_from_eval(cell->eval); F32 cell_width_px = cell->px + cell->pct * (dim_2f32(rect).x - floor_f32(ui_top_font_size()*1.5f)); F32 next_cell_x_px = cell_x_px + cell_width_px; F32 cell_width_strictness = 0.f; @@ -4386,6 +4378,19 @@ rd_view_ui(Rng2F32 rect) { cell_width_strictness = 1.f; } + F32 visual_row_string_max_size_px = cell_width_px * 1.5f; + if(cell->flags & RD_WatchCellFlag_Expr && !(cell->flags & RD_WatchCellFlag_NoEval)) + { + visual_row_string_max_size_px /= 2.f; + } + U64 cell_id = rd_id_from_watch_cell(cell); + RD_WatchPt cell_pt = {row->block->key, row->key, cell_id}; + RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); + B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), visual_row_string_max_size_px); + E_TypeKey cell_type_key = cell->eval.irtree.type_key; + E_Type *cell_type = e_type_from_key__cached(cell_type_key); + E_Eval cell_value_eval = e_value_eval_from_eval(cell->eval); B32 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; @@ -4613,12 +4618,17 @@ rd_view_ui(Rng2F32 rect) cell_params.edit_string_size_out = &cell_edit_state->input_size; cell_params.expanded_out = &next_row_expanded; cell_params.search_needle = needle; - cell_params.meta_fstrs = cell_info.expr_fstrs; - cell_params.value_fstrs = cell_info.eval_fstrs; + cell_params.meta_fstrs = cell_info.expr_fstrs; + cell_params.value_fstrs = cell_info.eval_fstrs; if(row_height_px > ui_top_font_size()*3.5f) { cell_params.description = cell_info.description; } + if(cell_selected && ewv->text_editing && cell->flags & RD_WatchCellFlag_NoEval) + { + MemoryZeroStruct(&cell_params.meta_fstrs); + MemoryZeroStruct(&cell_params.description); + } // rjf: apply expander (or substitute space) if(row_is_expandable && cell == row_info->cells.first) @@ -11992,6 +12002,7 @@ rd_frame(void) { String8 name = names[idx]; E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_StubSingleLineExpansion, .name = name, .access = E_TYPE_ACCESS_FUNCTION_NAME(commands), .expand = @@ -12300,7 +12311,9 @@ rd_frame(void) //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = collection_name, + .flags = E_TypeFlag_StubSingleLineExpansion, .expand = { .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), @@ -12336,7 +12349,7 @@ rd_frame(void) })); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("watches"), e_type_key_cons(.kind = E_TypeKind_Set, - .flags = E_TypeFlag_EditableChildren, + .flags = E_TypeFlag_EditableChildren|E_TypeFlag_StubSingleLineExpansion, .name = str8_lit("watches"), .irext = E_TYPE_IREXT_FUNCTION_NAME(watches), .access = E_TYPE_ACCESS_FUNCTION_NAME(watches), @@ -12351,6 +12364,7 @@ rd_frame(void) rd_state->meta_name2type_map, str8_lit("call_stack"), e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_StubSingleLineExpansion, .name = str8_lit("call_stack"), .irext = E_TYPE_IREXT_FUNCTION_NAME(call_stack), .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack), @@ -12360,6 +12374,7 @@ rd_frame(void) })); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("theme_colors"), e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_StubSingleLineExpansion, .name = str8_lit("theme_colors"), .irext = E_TYPE_IREXT_FUNCTION_NAME(cfgs_slice), .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs_slice), @@ -12417,6 +12432,7 @@ rd_frame(void) E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_StubSingleLineExpansion, .name = name, .expand = { From d41b414f2a1a1712a15e17811a47f9a781815a74 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 14:29:42 -0700 Subject: [PATCH 496/755] eliminate very-poorly-thought-through idea of 'chained casts' - we need to recognize cast operators in the parser somehow, otherwise we are using the expr chain for way too many things in many cases... --- src/eval/eval_ir.c | 73 ++++------------------------------------ src/eval/eval_parse.c | 78 ++++++++++++------------------------------- 2 files changed, 29 insertions(+), 122 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5989eff7..fc9ee2fc 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2069,82 +2069,23 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; } - //- rjf: if our currently-computed result is just a type, and we have - // a chained expression, then treat the first expression as a cast on - // the second. - if(!disallow_chained_casts && result.mode == E_Mode_Null && expr->next != &e_expr_nil) - { - // rjf: unpack - E_IRTreeAndType cast_type_tree = result; - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, expr->next); - e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); - E_TypeKey cast_type = cast_type_tree.type_key; - E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); - U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_TypeKey casted_type = casted_tree.type_key; - E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); - U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type); - U8 in_group = e_type_group_from_kind(casted_type_kind); - U8 out_group = e_type_group_from_kind(cast_type_kind); - RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); - - // rjf: bad conditions? -> error if applicable, exit - if(casted_tree.root->op == 0) - { - goto end_cast_gen; - } - else if(cast_type_kind == E_TypeKind_Null) - { - goto end_cast_gen; - } - else if(conversion_rule != RDI_EvalConversionKind_Noop && - conversion_rule != RDI_EvalConversionKind_Legal) - { - String8 text = str8_lit("Unknown cast conversion rule."); - if(conversion_rule < RDI_EvalConversionKind_COUNT) - { - text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); - } - e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); - goto end_cast_gen; - } - - // rjf: generate casted result - { - E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type); - E_IRNode *new_tree = in_tree; - if(conversion_rule == RDI_EvalConversionKind_Legal) - { - new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group); - } - if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind)) - { - new_tree = e_irtree_trunc(arena, in_tree, cast_type); - } - result.root = new_tree; - result.type_key = cast_type; - result.mode = E_Mode_Value; - } - - end_cast_gen:; - } - //- rjf: check chained expressions for simple wrappers if(!disallow_chained_fastpaths) { - struct + local_persist struct { String8 shorthand; String8 full_name; } shorthand_lens_pair_table[] = { - {str8_lit("x"), str8_lit("hex")}, - {str8_lit("b"), str8_lit("bin")}, - {str8_lit("o"), str8_lit("oct")}, - {str8_lit("d"), str8_lit("dec")}, + {str8_lit_comp("x"), str8_lit_comp("hex")}, + {str8_lit_comp("b"), str8_lit_comp("bin")}, + {str8_lit_comp("o"), str8_lit_comp("oct")}, + {str8_lit_comp("d"), str8_lit_comp("dec")}, }; - for(E_Expr *chained_expr = expr->next; + E_Expr *first_chained = expr->next; + for(E_Expr *chained_expr = first_chained; chained_expr != &e_expr_nil; chained_expr = chained_expr->next) { diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 00ffd23e..61b5c139 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -786,6 +786,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t ////////////////////////////// //- rjf: parse chain of expressions // + E_Expr *possible_cast = &e_expr_nil; for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { //////////////////////////// @@ -831,7 +832,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { PrefixUnaryTask *next; E_ExprKind kind; - E_Expr *cast_expr; void *location; }; PrefixUnaryTask *first_prefix_unary = 0; @@ -844,7 +844,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; E_ExprKind prefix_unary_kind = 0; - E_Expr *cast_expr = &e_expr_nil; void *location = 0; // rjf: try op table @@ -873,50 +872,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t it += 1; } - // rjf: try casting expression -#if 0 - if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) - { - E_Token some_type_identifier_maybe = e_token_at_it(it+1, &tokens); - String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); - if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) - { - E_TypeKey type_key = e_leaf_type_from_name(some_type_identifier_maybe_string); - if(!e_type_key_match(type_key, e_type_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) - { - // rjf: move past open paren - it += 1; - - // rjf: parse type expr - E_Parse type_parse = e_push_type_parse_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); - E_Expr *type = type_parse.expr; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - location = token_string.str; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, &tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); - } - - // rjf: consume ) - else - { - it += 1; - } - - // rjf: fill - prefix_unary_precedence = 2; - prefix_unary_kind = E_ExprKind_Cast; - cast_expr = type; - } - } - } -#endif - // rjf: break if we got no operators if(prefix_unary_precedence == 0) { @@ -933,7 +888,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { PrefixUnaryTask *op_n = push_array(scratch.arena, PrefixUnaryTask, 1); op_n->kind = prefix_unary_kind; - op_n->cast_expr = cast_expr; op_n->location = location; SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); } @@ -981,6 +935,9 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t atom = nested_parse.expr; it = nested_parse.last_token; + // rjf: this may have been a cast + possible_cast = atom; + // rjf: expect ) E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); @@ -1269,6 +1226,13 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } + // rjf: if this is a postfix unary, then we know the previous expression + // could not have been a cast. + if(is_postfix_unary) + { + possible_cast = &e_expr_nil; + } + // rjf: quit if this doesn't look like any patterns of postfix unary we know if(!is_postfix_unary) { @@ -1277,12 +1241,16 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } //////////////////////////// - //- rjf: no `atom`, but we have a cast expression? -> just evaluate the type as the atom - // - if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) + //- rjf: if we have an atom, and we have a potential cast expression, then remove + // the cast from the chain, and build a cast tree + if(atom != &e_expr_nil && possible_cast != &e_expr_nil && atom != possible_cast) { - atom = first_prefix_unary->cast_expr; - first_prefix_unary = first_prefix_unary->next; + E_Expr *casted = atom; + DLLRemove_NPZ(&e_expr_nil, result.expr, result.last_expr, possible_cast, next, prev); + atom = e_push_expr(arena, E_ExprKind_Cast, atom->location); + e_expr_push_child(atom, possible_cast); + e_expr_push_child(atom, casted); + possible_cast = &e_expr_nil; } //////////////////////////// @@ -1296,10 +1264,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { E_Expr *rhs = atom; atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } e_expr_push_child(atom, rhs); } } @@ -1338,6 +1302,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // precedence if(binary_precedence != 0 && binary_precedence <= max_precedence) { + possible_cast = &e_expr_nil; E_Parse rhs_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.expr; @@ -1370,6 +1335,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) { it += 1; + possible_cast = &e_expr_nil; // rjf: parse middle expression E_Parse middle_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); From 4cccc9cb42f7bced7fc411e6282a058c39bc5392 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 14:53:35 -0700 Subject: [PATCH 497/755] proper cast parsing, elimninate chained casts entirely --- src/eval/eval_core.c | 4 +- src/eval/eval_ir.c | 56 ++++++++++++------------- src/eval/eval_ir.h | 2 +- src/eval/eval_parse.c | 97 +++++++++++++++++++++++++++++++------------ src/eval/eval_types.c | 2 +- 5 files changed, 103 insertions(+), 58 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index ee4bd038..d7b37120 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -847,7 +847,7 @@ e_irtree_from_bundle(E_CacheBundle *bundle) bundle->flags |= E_CacheBundleFlag_IRTree; E_IRTreeAndType parent = 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, &parent, 0, 0, 0, parse.expr); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, 0, 0, parse.expr); E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } @@ -1326,7 +1326,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, 0, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index fc9ee2fc..d62fc929 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -492,7 +492,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, 0, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 1, exprr); e_msg_list_concat_in_place(&result.msgs, &r.msgs); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -583,7 +583,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -627,7 +627,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain @@ -684,7 +684,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -743,7 +743,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); @@ -771,12 +771,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, cast_type_expr); e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -831,7 +831,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -859,7 +859,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -873,7 +873,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -901,14 +901,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -941,7 +941,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -996,8 +996,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1220,9 +1220,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1267,7 +1267,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { B32 strip_lenses = 0; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1275,7 +1275,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: calling a type? -> treat as a cast of that type if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec) { - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, expr->first->next); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey cast_type = lhs_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); @@ -1347,7 +1347,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 strip_lenses = 1; disallow_autohooks = 1; } - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, call); // NOTE(rjf): we do not want to accumulate messages from the original left-hand-side evaluation in this case, because // this path only occurs if the member access fails specifically. } @@ -1365,7 +1365,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, disallow_chained_casts, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs->next); // rjf: if not raw, wrap resultant type with lens type if(!strip_lenses) @@ -1554,7 +1554,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) { E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, 1, access); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -1924,7 +1924,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { generated = 1; e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, macro_expr); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, macro_expr); e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); } } @@ -2011,7 +2011,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; case E_ExprKind_Unsigned: { - E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); result = direct_irtree; E_TypeKey direct_type_key = result.type_key; E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); @@ -2041,13 +2041,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2061,7 +2061,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, rhs); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index a63bd7bc..97889252 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 61b5c139..c437c23d 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -568,6 +568,21 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_U64); } + else if(Case("u128") || Case("uint128") || Case("uint128_t") || Case("U128")) + { + found = 1; + key = e_type_key_basic(E_TypeKind_U128); + } + else if(Case("u256") || Case("uint256") || Case("uint256_t") || Case("U256")) + { + found = 1; + key = e_type_key_basic(E_TypeKind_U256); + } + else if(Case("u512") || Case("uint512") || Case("uint512_t") || Case("U512")) + { + found = 1; + key = e_type_key_basic(E_TypeKind_U512); + } else if(Case("s8") || Case("b8") || Case("B8") || Case("i8") || Case("int8") || Case("int8_t") || Case("S8")) { found = 1; @@ -603,6 +618,16 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_S64); } + else if(Case("s256") || Case("i256") || Case("int256") || Case("int256_t") || Case("S256")) + { + found = 1; + key = e_type_key_basic(E_TypeKind_S256); + } + else if(Case("s512") || Case("i512") || Case("int512") || Case("int512_t") || Case("S512")) + { + found = 1; + key = e_type_key_basic(E_TypeKind_S512); + } else if(Case("void")) { found = 1; @@ -786,7 +811,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t ////////////////////////////// //- rjf: parse chain of expressions // - E_Expr *possible_cast = &e_expr_nil; for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { //////////////////////////// @@ -895,14 +919,23 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } //////////////////////////// - //- rjf: parse atom + //- rjf: parse atom, gather cast tasks // - E_Expr *atom = &e_expr_nil; - String8 atom_implicit_member_name = {0}; - if(it < it_opl) + typedef struct CastTask CastTask; + struct CastTask { + CastTask *next; + E_Expr *type_expr; + }; + CastTask *first_cast = 0; + CastTask *last_cast = 0; + E_Expr *atom = &e_expr_nil; + for(B32 done = 0; !done && it < it_opl;) + { + E_Expr *possible_cast = atom; E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); + done = 1; ////////////////////////// //- rjf: consume resolution qualifiers @@ -935,9 +968,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t atom = nested_parse.expr; it = nested_parse.last_token; - // rjf: this may have been a cast - possible_cast = atom; - // rjf: expect ) E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); @@ -951,6 +981,9 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { it += 1; } + + // rjf: this may have been a cast, so keep parsing after this + done = 0; } ////////////////////////// @@ -1094,11 +1127,31 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t it += 1; } + ////////////////////////// + //- rjf: not a recognized atom pattern + // + else + { + done = 1; + } + + ////////////////////////// //- rjf: upgrade atom w/ qualifier + // if(atom != &e_expr_nil && resolution_qualifier.size != 0) { atom->qualifier = resolution_qualifier; } + + ////////////////////////// + //- rjf: gather cast + // + if(possible_cast != &e_expr_nil && possible_cast != atom) + { + CastTask *t = push_array(scratch.arena, CastTask, 1); + t->type_expr = possible_cast; + SLLQueuePushFront(first_cast, last_cast, t); + } } //////////////////////////// @@ -1226,13 +1279,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } - // rjf: if this is a postfix unary, then we know the previous expression - // could not have been a cast. - if(is_postfix_unary) - { - possible_cast = &e_expr_nil; - } - // rjf: quit if this doesn't look like any patterns of postfix unary we know if(!is_postfix_unary) { @@ -1241,16 +1287,17 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } //////////////////////////// - //- rjf: if we have an atom, and we have a potential cast expression, then remove - // the cast from the chain, and build a cast tree - if(atom != &e_expr_nil && possible_cast != &e_expr_nil && atom != possible_cast) + //- rjf: upgrade `atom` w/ previously parsed casts + // + if(atom != &e_expr_nil) { - E_Expr *casted = atom; - DLLRemove_NPZ(&e_expr_nil, result.expr, result.last_expr, possible_cast, next, prev); - atom = e_push_expr(arena, E_ExprKind_Cast, atom->location); - e_expr_push_child(atom, possible_cast); - e_expr_push_child(atom, casted); - possible_cast = &e_expr_nil; + for(CastTask *cast = first_cast; cast != 0; cast = cast->next) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, E_ExprKind_Cast, cast->type_expr->location); + e_expr_push_child(atom, cast->type_expr); + e_expr_push_child(atom, rhs); + } } //////////////////////////// @@ -1302,7 +1349,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // precedence if(binary_precedence != 0 && binary_precedence <= max_precedence) { - possible_cast = &e_expr_nil; E_Parse rhs_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.expr; @@ -1335,7 +1381,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) { it += 1; - possible_cast = &e_expr_nil; // rjf: parse middle expression E_Parse middle_expr_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 1be51681..d59f999b 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2466,7 +2466,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) } // rjf: compute struct.base_ptr IR tree - result = e_push_irtree_and_type_from_expr(arena, 0, 0, 0, 0, idx_expr); + result = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, idx_expr); scratch_end(scratch); }break; From 0a214fda3ced43891319d85cfd358de0c129dc43 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 15:06:06 -0700 Subject: [PATCH 498/755] dynamic type resolution in ir tree / type generation pass --- src/eval/eval_ir.c | 68 ++++++++++++++++++++++++++++++++++++++++++ src/mule/mule_main.cpp | 14 ++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index d62fc929..56a3b45c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2153,6 +2153,74 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } } + //- rjf: if the evaluated type has a virtual table pointer, then we must + // pre-emptively evaluate this ir tree, and determine a more resolved type. + { + E_TypeKey type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative); + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(type_key))) + { + E_TypeKey ptee_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_All); + E_TypeKind ptee_kind = e_type_kind_from_key(ptee_key); + if(ptee_kind == E_TypeKind_Struct || + ptee_kind == E_TypeKind_Class) + { + E_Type *ptee_type = e_type_from_key__cached(ptee_key); + B32 has_vtable = 0; + for(U64 idx = 0; idx < ptee_type->count; idx += 1) + { + if(ptee_type->members[idx].kind == E_MemberKind_VirtualMethod) + { + has_vtable = 1; + break; + } + } + if(has_vtable) + { + E_OpList oplist = e_oplist_from_irtree(scratch.arena, result.root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + U64 ptr_vaddr = interpret.value.u64; + U64 addr_size = e_type_byte_size_from_key(type_key); + U64 class_base_vaddr = 0; + U64 vtable_vaddr = 0; + if(e_space_read(interpret.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && + e_space_read(interpret.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) + { + Arch arch = e_base_ctx->primary_module->arch; + U32 rdi_idx = 0; + RDI_Parsed *rdi = 0; + U64 module_base = 0; + for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) + { + if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) + { + arch = e_base_ctx->modules[idx].arch; + rdi_idx = (U32)idx; + rdi = e_base_ctx->modules[idx].rdi; + module_base = e_base_ctx->modules[idx].vaddr_range.min; + break; + } + } + if(rdi != 0) + { + U64 vtable_voff = vtable_vaddr - module_base; + U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, vtable_voff); + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx); + if(global_var->link_flags & RDI_LinkFlag_TypeScoped) + { + RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); + RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); + E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); + E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); + result.type_key = ptr_to_derived_type_key; + } + } + } + } + } + } + } + //- rjf: equip previous task's irtree if(t->overridden != 0) { diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 9457bb21..f42810ba 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1266,7 +1266,19 @@ struct Derived : Base int b; int a; virtual ~Derived() = default; - virtual void Foo() {a += 1;} + virtual void Foo() + { + x += 1; + y += 1; + y += 1; + z += 1; + z += 1; + z += 1; + a += 1; + a += 1; + a += 1; + a += 1; + } }; struct DerivedA : Base From f521e01d6e8d2b7c68d7dfe0641e5768779c5b1d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 15:26:40 -0700 Subject: [PATCH 499/755] dynamic ternaries in ir tree evaluation, fixes to over-ambitious parsing of identifier qualifiers --- src/eval/eval_ir.c | 32 ++++++++++++++++++++++++++++---- src/eval/eval_parse.c | 2 +- src/eval/eval_types.c | 9 ++++++++- src/mule/mule_main.cpp | 7 +++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 56a3b45c..5066136b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1232,7 +1232,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_TypeKind c_type_kind = e_type_kind_from_key(c_type); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey result_type = l_type; // rjf: bad conditions? -> error if applicable, exit if(c_tree.root->op == 0 || l_tree.root->op == 0 || r_tree.root->op == 0) @@ -1243,12 +1242,37 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Conditional term must be an integer or boolean type."); } - else if(!e_type_match(l_type, r_type)) + + // rjf: determine the resultant type - if the left/right types match, then we + // can just pick the left type, and defer 100% of our interpretation. however, + // if the types do *not* match, then we need to pre-emptively evaluate the + // condition, and pick the result based on that. + B32 ternary_is_dynamic = 0; + E_TypeKey result_type = l_type; + if(!e_type_match(l_type, r_type)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left and right terms must have matching types."); + ternary_is_dynamic = 1; } - // rjf: generate + // rjf: generate dynamic ternary + if(ternary_is_dynamic) + { + E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, c_value_tree); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpretation = e_interpret(bytecode); + if(interpretation.value.u64 != 0) + { + result = l_tree; + } + else + { + result = r_tree; + } + } + + // rjf: generate static ternary + else { E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index c437c23d..a2b2f1a0 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -945,7 +945,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { E_Token next_token = e_token_at_it(it+1, &tokens); String8 next_token_string = str8_substr(text, next_token.range); - if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) + if(next_token.range.min == token.range.max && next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) { it += 2; resolution_qualifier = token_string; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d59f999b..6264c1e7 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1516,7 +1516,14 @@ e_type_match(E_TypeKey l, E_TypeKey r) { default: { - result = 1; + if(e_type_kind_is_basic_or_enum(luk)) + { + result = 1; + } + else + { + result = 0; + } }break; case E_TypeKind_Ptr: diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f42810ba..b9276f41 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -249,6 +249,13 @@ struct Discriminated_Union }; }; +raddbg_auto_view_rule(Discriminated_Union, + kind == Kind.First ? first : + kind == Kind.Second ? second : + kind == Kind.Third ? third : + kind == Kind.Fourth ? fourth : + $); + struct Linked_List{ Linked_List *next; Linked_List *prev; From 7b5f55c3c80477a2d82011af58e282f355ccc242 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 15:34:39 -0700 Subject: [PATCH 500/755] convert mule_main to crlf, apparently..? --- src/mule/mule_main.cpp | 5764 ++++++++++++++++++++-------------------- 1 file changed, 2890 insertions(+), 2874 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index b9276f41..ed6a3568 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1,2874 +1,2890 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -/* -** Program to run in debugger organized to provide tests for -** stepping, breakpoints, evaluation, cross-module calls. -*/ - -#define RADDBG_MARKUP_IMPLEMENTATION -#include "lib_raddbg_markup/raddbg_markup.h" - -//////////////////////////////// -// NOTE(allen): System For DLL Testing - -typedef void TestFunction(void); - -static void mule_init(void); -static TestFunction* mule_get_module_function(char *name); - -#if _WIN32 - -#include - -HMODULE mule_dll = 0; - -static void -mule_init(void){ - mule_dll = LoadLibraryA("mule_module.dll"); -} - -static TestFunction* -mule_get_module_function(char *name){ - TestFunction *result = (TestFunction*)GetProcAddress(mule_dll, name); - return(result); -} - -#else - -static void -mule_init(void){ - // TODO(allen): implement -} - -static TestFunction* -mule_get_module_function(char *name){ - // TODO(allen): implement - return(0); -} - -#endif - - -//////////////////////////////// -// NOTE(nick): Entry Point - -int -mule_main(int argc, char **argv); - -#if _WIN32 -#include -#include -int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ - int argc = __argc; - char **argv = __argv; - int result = mule_main(argc, argv); - return(result); -} -#else -int main(int argc, char **argv){ - return(mule_main(argc, argv)); -} -#endif - -//////////////////////////////// -// NOTE(nick): BSS section test - -#if defined(__clang__) -# pragma clang section bss="muleBSS" -#elif defined(_MSC_VER) -// NOTE(nick): clang-cl is borken it allocates memory and sets Initialized Flag on the seciton. -// This is was reported by Jeff => https://bugs.llvm.org/show_bug.cgi?id=47939 -// -// This is still unresolved, last checked Sep 11, 2023. -# pragma bss_seg("muleBSS") -#else -# error "bss not defined" -#endif -char global_variable_in_bss[4096*10000]; - -//////////////////////////////// -// NOTE(allen): Inline Stepping (Built In Separate Unit) - -extern unsigned int fixed_frac_bits; -unsigned int inline_stepping_tests(void); - - -//////////////////////////////// -// NOTE(rjf): -O2 Optimized Code (Built In Separate Unit) - -void optimized_build_eval_tests(void); -void optimized_struct_parameters_eval_tests(void); - -//////////////////////////////// -// NOTE(allen): Type Coverage Eval - -#include -#include - -raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); - -struct Basics -{ - char a; - unsigned char b; - short c; - unsigned short d; - int e; - unsigned int f; - long long g; - unsigned long long h; - float i; - double j; - int z; -}; - -struct Basics_Stdint -{ - int8_t a; - uint8_t b; - int16_t c; - uint16_t d; - int32_t e; - uint32_t f; - int64_t g; - uint64_t h; - float i; - double j; -}; - -struct Pair -{ - int x; - float y; -}; - -struct Fixed_Array -{ - Pair pairs[10]; - int count; -}; - -struct Dynamic_Array -{ - Pair *pairs; - int count; -}; -raddbg_auto_view_rule(Dynamic_Array, slice($)); - -struct Struct_With_Embedded_Arrays -{ - int x; - float y; - Pair pairs[10]; - char z; -}; - -typedef unsigned int Custom_Index_Type; - -typedef void Function_No_Params_Type(void); -typedef void Function_Few_Params_Type(Pair *pairs, int count, Function_No_Params_Type *no_params_type); - -static Function_No_Params_Type *ty_no_params = 0; -static Function_Few_Params_Type *ty_few_params = 0; - -struct Callback{ - Function_Few_Params_Type *few_params; - Function_No_Params_Type *no_params; - Pair pair; -}; - -union Vector_R2 -{ - struct - { - float x; - float y; - }; - float v[2]; -}; -raddbg_auto_view_rule(Vector_R2, only($, x, y)); - -typedef union Matrix4x4F32 Matrix4x4F32; -union Matrix4x4F32 -{ - float elements[4][4]; -}; -raddbg_auto_view_rule(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); - -enum Kind -{ - Kind_None, - Kind_First, - Kind_Second, - Kind_Third, - Kind_Fourth, - Kind_COUNT, -}; - -enum Flag -{ - Flag_None = 0, - Flag_First = 1, - Flag_Second = 2, - Flag_Third = 4, - Flag_Fourth = 8, - Flag_AllMoreNarrow = 0xFF, - Flag_AllNarrow = 0xFFFF, - Flag_All = 0xFFFFFFFF, -}; - -struct Has_Enums -{ - Kind kind; - Flag flags; -}; - -struct Discriminated_Union -{ - Kind kind; - union - { - struct - { - int x; - int y; - Vector_R2 vector; - } first; - Pair second; - struct - { - Function_Few_Params_Type *few_params; - Pair pairs[4]; - } third; - struct - { - Kind sub_kind; - Flag flags; - } fourth; - }; -}; - -raddbg_auto_view_rule(Discriminated_Union, - kind == Kind.First ? first : - kind == Kind.Second ? second : - kind == Kind.Third ? third : - kind == Kind.Fourth ? fourth : - $); - -struct Linked_List{ - Linked_List *next; - Linked_List *prev; - int x; -}; - -enum{ - Anonymous_A, - Anonymous_B, - Anonymous_C, - Anonymous_D, -}; - -typedef Kind Alias1; -typedef Flag Alias2; -typedef Has_Enums Alias3; -typedef Discriminated_Union Alias4; - -struct Has_A_Pre_Forward_Reference{ - struct Gets_Referenced_Forwardly *pointer; -}; - -struct Gets_Referenced_Forwardly{ - int x; - int y; -}; - -struct Has_A_Post_Forward_Reference{ - struct Gets_Referenced_Forwardly value; -}; - -struct TypeWithMemberFunction -{ - int x; - int y; - int z; - char *name; - __declspec(noinline) void SetInfo(int _x, int _y, char *_name) - { - x = _x; - y = _y; - z = 0; - name = _name; - OutputDebugStringA("setting info\n"); - } -}; - -static void -no_params1(void){ - -} - -static void -few_params1(Pair *pairs, int count, Function_No_Params_Type *no_params_type){ - -} - -static void -type_coverage_eval_tests(void) -{ - Basics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; - Basics_Stdint basics_stdint = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; - - char string[] = "Hello World!"; - char longer_text[] = - "Suppose there was some text\n" - "With multiple lines in it\r\n" - "\t> What ways might it be rendered?\n" - "\t> How would it deal with line endings?\r\n"; - wchar_t a_wide_string[] = - L"This is a string, but instead of being encoded in a stream of bytes,\n" - L"it is encoded in a stream of 2-byte packages!\n"; - - const char *const_string = "Hello, World!"; - const char const_string_array[] = "Hello, World!"; - const char *const const_ptr_const_string = "Hello, World!"; - - void *pointer = &basics; - Basics *pointer_to_basics = &basics; - Basics **pointer_to_pointer_to_basics = &pointer_to_basics; - - Fixed_Array fixed = - { - { - { 3, 4.f}, - { 5, 6.f}, - { 7, 8.f}, - { 9, 10.f}, - {11, 12.f}, - {13, 14.f}, - {15, 16.f}, - {17, 18.f}, - {19, 20.f}, - }, - 9 - }; - Pair memory_[] = - { - {100, 1.f}, - {101, 2.f}, - {102, 4.f}, - {103, 8.f}, - {104, 16.f}, - {105, 32.f}, - }; - Dynamic_Array dynamic = - { - memory_, - 6 - }; - - raddbg_pin(table(sequence(6), fixed.pairs[$], memory_[$])); - raddbg_pin(basics); - raddbg_pin(fixed); - raddbg_pin(pointer); - raddbg_pin(dynamic); - - Struct_With_Embedded_Arrays swea = {0}; - { - swea.x = 4; - swea.y = 23.5f; - swea.pairs[0].x = 100; - swea.pairs[0].y = 123.f; - swea.pairs[2].x = 300; - swea.pairs[2].y = 323.f; - swea.pairs[5].x = 600; - swea.pairs[5].y = 623.f; - swea.z = 'z'; - } - - Struct_With_Embedded_Arrays *swea_ptr = &swea; - int access_via_ptr_member = swea_ptr->x; - - Custom_Index_Type custom_index = 42; - Custom_Index_Type more_custom_indices[] = { - 04,13,22,31,40 - }; - - Function_No_Params_Type *ptr_no_params = no_params1; - Function_No_Params_Type **ptr_ptr_no_params = &ptr_no_params; - Function_Few_Params_Type *ptr_few_params = few_params1; - Function_Few_Params_Type **ptr_ptr_few_params = &ptr_few_params; - Callback callback = {few_params1, no_params1, {1, 2.f}}; - - Matrix4x4F32 matrix = - { - { - {1.f, 0.f, 0.f, 0.f}, - {0.f, 1.f, 0.f, 0.f}, - {0.f, 0.f, 1.f, 0.f}, - {0.f, 0.f, 0.f, 1.f}, - } - }; - - Vector_R2 vector = {1.f, 2.f}; - - Has_Enums has_enums = {(Kind)4, (Flag)7}; - - Discriminated_Union discriminated_union = {Kind_First}; - discriminated_union.first.x = 16; - discriminated_union.first.y = 8; - discriminated_union.first.vector.x = 4.f; - discriminated_union.first.vector.y = 2.f; - - Linked_List list = {&list, &list, 0}; - - Alias1 a1 = has_enums.kind; - Alias2 a2 = has_enums.flags; - Alias3 a3 = has_enums; - Alias4 a4 = discriminated_union; - - Has_A_Pre_Forward_Reference r1 = {0}; - Has_A_Post_Forward_Reference r2 = {0}; - - Basics &basics_ref = basics; - const Basics *basics_const_ptr = &basics; - const Basics &basics_const_ref = basics; - - union - { - int x; - char y[4]; - } integer_slicing = {123456789}; - - typedef struct stks - { - void *left; - size_t len; - } stks; - stks stks_test[256] = {0}; - stks *stks_first = &stks_test[0]; - stks *stks_ptr = stks_first + 8; - - TypeWithMemberFunction twmf = {0}; - twmf.SetInfo(123, 456, "foobar"); - - TestFunction *function = mule_get_module_function("dll_type_eval_tests"); - function(); - - int abc = 0; - for(int i = 0; i < 1000; i += 1) - { - if(i == 500) - { - abc+= 1; - } - int a = i + abc; - int b = a*5; - } - - char *names[] = - { - "samwise gamgee", "mithrandir", "grima wormtongue", "theodred", "theoden", "eomer", "eowyn", - "arwen", "sauron", "baggins", "proudfoot", "hardbottle", "bag end", "hobbiton", - "bree", "imladris", "isengard", "moria", "mount doom", "helm's deep", "bracegirdle", - "buckleberry ferry", "amun sul", "frodo", "bilbo", "buckland", "fangorn", "elrond", - "numenor", "treebeard", "shadowfax", "brego", "erod", "azufel", "dunedain", - "saruman", "aragorn", "gandalf", "meriadoc brandybuck", "peregrine took", "faramir", "boromir", - "ecthelion", "denethor", "mithrandil", "isildur", "haldir", "elessar", "elendil", - "dead marsh", "rohan", "gondor", "anarion", "earendil", "cirith ungol", "minas morghul", - "minas tirith", "barad-dur", "rivendell", "pellenor", "ithilien", "anduril", "narsil", - "edoras", "mordor", "osgiliath", - }; - - for(int i = 0; i < sizeof(names)/sizeof(names[0]); i += 1) - { - OutputDebugStringA(names[i]); - OutputDebugStringA("\n"); - } - - const int32_t x1 = 3; - const int32_t y1 = -10; - const int32_t z1 = x1 + y1; - - std::vector int_vector; - int_vector.push_back(1); - int_vector.push_back(2); - int_vector.push_back(3); - int_vector.push_back(4); - int_vector.push_back(5); - int_vector.push_back(6); - int_vector.push_back(7); - - int x = (int)(Anonymous_D); -} - -//////////////////////////////// -// NOTE(allen): Mutating Variables Eval - -static const int con_some_constant = 4; -static const float con_some_constant_f = 0.04f; - -static int mut_x = 0; -static int mut_y; -static int mut_xarray[4] = {0, 1, 2, 3}; -static int *mut_xptr; - -static float mut_f = 0; -static float mut_g; -static float mut_farray[4] = {0.5f, 1.5f, 2.5f, 3.5f}; -static float *mut_fptr; - -static float mut_arrayarray[3][3]; - -static Linked_List mut_link; - -static void -mutate_in_function(int *array, int count){ - for (int i = 0; i < count; i += 1){ - array[i] += 1; - } - - for (int i = 0; i < 4; i += 1){ - mut_farray[i] += 1.f; - } -} - -static void -mutating_variables_eval_tests(void){ - //////////////////////////////// - // NOTE(allen): Basics - - int array_literal[10] = { - 10, 20, 30, 40, 50, 60, 70, 80, 90, - }; - - Basics struct_literal = { - -1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001, - }; - - array_literal[0] = struct_literal.e = 9; - - int x = mut_x; - int y = x + 10 + con_some_constant; - mut_y = y; - mut_xarray[0] += 0; - mut_xarray[1] += x; - mut_xarray[2] += y; - mut_xarray[3] += x + y; - - mut_xptr = &mut_xarray[2]; - - *mut_xptr -= (y - x)/2; - *(mut_xptr - 1) += 11; - - float f = mut_f + .333f + con_some_constant_f; - float g = f + 10.1f; - mut_g = g; - mut_farray[0] += 0.000001f; - mut_farray[1] += f; - mut_farray[2] += g; - mut_farray[3] += f + g; - - mut_fptr = &mut_farray[3]; - - *mut_fptr -= (g - f)*0.5f; - *(mut_fptr - 1) += 1.f; - - float a = 0.777f; - for (int i = 0; i < 3; i += 1){ - float b = a*a - 1.f; - for (int j = 0; j < 3; j += 1){ - mut_arrayarray[i][j] = b; - b += 0.111f; - } - a += 0.333f; - } - - //////////////////////////////// - // NOTE(allen): Changes in functions - - mutate_in_function(array_literal, 10); - - mutate_in_function(array_literal, 10); - - //////////////////////////////// - // NOTE(allen): Changes through pointers - - Basics basic = struct_literal; - Basics advanced = struct_literal; - - Basics *struct_pointer = &basic; - - basic.a += 1; - advanced.a += 1; - struct_pointer->a += 1; - - struct_pointer = &advanced; - - basic.b += 1; - advanced.b += 1; - struct_pointer->b += 1; - - Linked_List links[5]; - for (int i = 0; i < 5; i += 1){ - links[i].next = &links[i + 1]; - links[i].prev = &links[i - 1]; - links[i].x = i; - } - links[0].prev = 0; - links[4].next = &mut_link; - mut_link.prev = &links[4]; - mut_link.next = 0; - mut_link.x = 1000; - - Linked_List *link_ptr = links; - - link_ptr = link_ptr->next; - - link_ptr = &links[4]; - link_ptr = &mut_link; - - Linked_List sentinel = {0}; - sentinel.x = -1; - sentinel.next = &links[0]; - links[0].prev = &sentinel; - sentinel.prev = &mut_link; - mut_link.next = &sentinel; - - link_ptr = &sentinel; -} - -//////////////////////////////// -// NOTE(allen): Global Eval - -struct NestedNodeInner{ - unsigned int small0; - unsigned int small1; - unsigned int big0; - unsigned int big1; -}; - -struct NestedNodeOuter{ - NestedNodeOuter *next; - NestedNodeInner *inner_nodes; - unsigned int inner_node_count; -}; - -static void -nested_types_eval_tests(void){ - // doing some setup - NestedNodeOuter *outer1 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); - NestedNodeOuter *outer2 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); - NestedNodeOuter *outer3 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); - - outer1->next = outer2; - outer2->next = outer3; - outer3->next = 0; - - outer1->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); - outer1->inner_node_count = 10; - - outer2->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); - outer2->inner_node_count = 10; - - outer3->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); - outer3->inner_node_count = 10; - - for (unsigned int i = 0; i < 10; i += 1){ - outer1->inner_nodes[i].small0 = i; - outer1->inner_nodes[i].small1 = 2*i; - outer1->inner_nodes[i].big0 = 0xFFFFFF + 0xF*i; - outer1->inner_nodes[i].big1 = 0xFFFFFF + 0xFF*i; - - outer2->inner_nodes[i].small0 = 1 + i; - outer2->inner_nodes[i].small1 = 3*i; - outer2->inner_nodes[i].big0 = 0x1000000 + 0x10*i; - outer2->inner_nodes[i].big1 = 0x1000000 + 0x101*i; - - outer3->inner_nodes[i].small0 = 2 + i; - outer3->inner_nodes[i].small1 = 4*i; - outer3->inner_nodes[i].big0 = 0x8000000 + 0xF0*i; - outer3->inner_nodes[i].big1 = 0x8000000 + 0xF0F*i; - } - - // okay eval it here - int x = 0; -} - -//////////////////////////////// -// NOTE(rjf): Struct Parameters Eval - -static void -struct_parameter_helper(Basics basics) -{ - basics.a += 1; - basics.a += 1; - basics.a += 1; -} - -static void -struct_parameters_eval_tests(void) -{ - Basics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; - struct_parameter_helper(basics); -} - -//////////////////////////////// -// NOTE(allen): Global Eval - -static int g_abc = 100; -static float g_xyz = 21.f; -static Alias1 g_kind = Kind_First; - -// TODO(allen): more global test types - -static void -complicated_global_mutation(int *x){ - *x = (int)g_xyz; -} - -static void -cross_unit_global_mutation(void){ - fixed_frac_bits = 10; -} - -static void -global_eval_tests(void){ - g_abc = 11*11; - g_xyz = (float)g_abc - 21.f; - - int z = g_abc; - complicated_global_mutation(&z); - - complicated_global_mutation(&g_abc); - - if (g_kind == Kind_First){ - g_abc -= 1; - g_kind = Kind_None; - } - - cross_unit_global_mutation(); - - static int l_abc = 200; - static float l_xyz = 42.f; - static Alias1 l_kind = Kind_Second; - - l_abc = g_abc*2; - l_xyz = g_xyz*2; - l_kind = (Alias1)(g_kind + 1); -} - -//////////////////////////////// -// NOTE(allen): Return Eval - -static int -complicated_return_expression(void){ - int x = 171717; - return((x % 13) <= 5?(x % 19)*11:(x - 500)%200); -} - -static void -return_eval_tests(void){ - complicated_return_expression(); -} - -//////////////////////////////// -// NOTE(allen): TLS Eval - -#if _WIN32 -# define thread_var __declspec(thread) -#else -# define thread_var __thread -#endif - -thread_var int tls_a = 100; -thread_var int tls_b = 999; - -static void -tls_eval_tests(void){ - tls_a = (tls_a + tls_b)/2; - tls_b = tls_b - tls_a; - - TestFunction *dll_tls_eval_test = mule_get_module_function("dll_tls_eval_test"); - if (dll_tls_eval_test != 0){ - dll_tls_eval_test(); - } -} - -//////////////////////////////// -// NOTE(allen): Complicated Type Coverage Eval - -struct Complicated_Type_Members{ - int x600[2][2][2][2]; - int *x601[2][2][2][2]; - int (*x602)[2][2][2][2]; - int (*x603[2])[2][2][2]; - int (*(*x604[2])[2])[2][2]; - int (*(*(*x605[2])[2])[2])[2]; - - int (*x33[2])(void); - int (*x34[3])(void); - int (*x35[2][2])(void); - - int (*(*z33)(void))[2]; - int (*(*z34)(void))[3]; - int (*(*z35)(void))[2][2]; - - int (*(*f2)(void))(void); - int (*(*(*f3)(void))(void))(void); - int (*(*f4)(int))(void); - int (*(*f5)(void))(int); - int (*(*f6)(int))(int); - int (*(*(*f7_growing)(char))(short))(int); - int (*(*(*f7_shrinking)(int))(short))(char); -}; - -static void -complicated_type_coverage_tests(void){ - Complicated_Type_Members m = {0}; - - int x1 = {0}; - int *x2 = {0}; - int **x3 = {0}; - - int x4a[2] = {0}; - int *x4[2] = {0}; - int x5a[3] = {0}; - int *x5[3] = {0}; - int *x6[2][2] = {0}; - int (*x7)[2] = {0}; - int (*x8)[3] = {0}; - int (*x9)[2][2] = {0}; - - int x600[2][2][2][2] = {0}; - int *x601[2][2][2][2] = {0}; - int (*x602)[2][2][2][2] = {0}; - int (*x603[2])[2][2][2] = {0}; - int (*(*x604[2])[2])[2][2] = {0}; - int (*(*(*x605[2])[2])[2])[2] = {0}; - - int x606_growing [2][3][4][5] = {0}; - int x606_shrinking[5][4][3][2] = {0}; - - int (*(*(*x607_growing [2])[3])[4])[5] = {0}; - int (*(*(*x607_shrinking[5])[4])[3])[2] = {0}; - - int **x10[2] = {0}; - int **x11[3] = {0}; - int **x12[2][2] = {0}; - int *(*x13)[2] = {0}; - int *(*x14)[3] = {0}; - int *(*x15)[2][2] = {0}; - int **x16[2] = {0}; - int **x17[3] = {0}; - int **x18[2][2] = {0}; - - int (*y1[2])[2] = {0}; - int (*y2[3])[2] = {0}; - int (*y3[2][2])[2] = {0}; - int (*y4[2])[3] = {0}; - int (*y5[3])[3] = {0}; - int (*y6[2][2])[3] = {0}; - int (*y7[2])[2][2] = {0}; - int (*y8[3])[2][2] = {0}; - int (*y9[2][2])[2][2] = {0}; - - int (*x19)(void) = {0}; - int (*x20)(int) = {0}; - int (*x21)(int, int) = {0}; - int (*x22)(int*, int) = {0}; - int (*x23)(int**, int) = {0}; - int (*x24)(int**, int*) = {0}; - int (*x25)(int**, int**) = {0}; - - int *(*x26)(void) = {0}; - int *(*x27)(int) = {0}; - int *(*x28)(int, int) = {0}; - int *(*x29)(int*, int) = {0}; - int *(*x30)(int**, int) = {0}; - int *(*x31)(int**, int*) = {0}; - int *(*x32)(int**, int**) = {0}; - - int (*x33[2])(void) = {0}; - int (*x34[3])(void) = {0}; - int (*x35[2][2])(void) = {0}; - - int (*x36[2])(int) = {0}; - int (*x37[3])(int) = {0}; - int (*x38[2][2])(int) = {0}; - - int (*x39[2])(int, int) = {0}; - int (*x40[3])(int, int) = {0}; - int (*x41[2][2])(int, int) = {0}; - - int (*x42[2])(int*, int) = {0}; - int (*x43[3])(int*, int) = {0}; - int (*x44[2][2])(int*, int) = {0}; - - int (*x45[2])(int**, int) = {0}; - int (*x46[3])(int**, int) = {0}; - int (*x47[2][2])(int**, int) = {0}; - - int (*x48[2])(int**, int*) = {0}; - int (*x49[3])(int**, int*) = {0}; - int (*x50[2][2])(int**, int*) = {0}; - - int (*x51[2])(int**, int**) = {0}; - int (*x52[3])(int**, int**) = {0}; - int (*x53[2][2])(int**, int**) = {0}; - - int (*(*z33)(void))[2] = {0}; - int (*(*z34)(void))[3] = {0}; - int (*(*z35)(void))[2][2] = {0}; - - int (*(*z36)(int))[2] = {0}; - int (*(*z37)(int))[3] = {0}; - int (*(*z38)(int))[2][2] = {0}; - - int (*(*z39)(int, int))[2] = {0}; - int (*(*z40)(int, int))[3] = {0}; - int (*(*z41)(int, int))[2][2] = {0}; - - int (*(*z42)(int*, int))[2] = {0}; - int (*(*z43)(int*, int))[3] = {0}; - int (*(*z44)(int*, int))[2][2] = {0}; - - int (*(*z45)(int**, int))[2] = {0}; - int (*(*z46)(int**, int))[3] = {0}; - int (*(*z47)(int**, int))[2][2] = {0}; - - int (*(*z48)(int**, int*))[2] = {0}; - int (*(*z49)(int**, int*))[3] = {0}; - int (*(*z50)(int**, int*))[2][2] = {0}; - - int (*(*z51)(int**, int**))[2] = {0}; - int (*(*z52)(int**, int**))[3] = {0}; - int (*(*z53)(int**, int**))[2][2] = {0}; - - int (*(*z303[2])(void)) = {0}; - int (*(*z304[3])(void)) = {0}; - int (*(*z305[2][2])(void)) = {0}; - - int (*(*z306[2])(int)) = {0}; - int (*(*z307[3])(int)) = {0}; - int (*(*z308[2][2])(int)) = {0}; - - int (*(*z309[2])(int, int)) = {0}; - int (*(*z400[3])(int, int)) = {0}; - int (*(*z401[2][2])(int, int)) = {0}; - - int (*(*z402[2])(int*, int)) = {0}; - int (*(*z403[3])(int*, int)) = {0}; - int (*(*z404[2][2])(int*, int)) = {0}; - - int (*(*z405[2])(int**, int)) = {0}; - int (*(*z406[3])(int**, int)) = {0}; - int (*(*z407[2][2])(int**, int)) = {0}; - - int (*(*z408[2])(int**, int*)) = {0}; - int (*(*z409[3])(int**, int*)) = {0}; - int (*(*z500[2][2])(int**, int*)) = {0}; - - int (*(*z501[2])(int**, int**)) = {0}; - int (*(*z502[3])(int**, int**)) = {0}; - int (*(*z503[2][2])(int**, int**)) = {0}; - - int (*(*f2)(void))(void) = {0}; - int (*(*(*f3)(void))(void))(void) = {0}; - int (*(*f4)(int))(void) = {0}; - int (*(*f5)(void))(int) = {0}; - int (*(*f6)(int))(int) = {0}; - int (*(*(*f7_growing)(char))(short))(int) = {0}; - int (*(*(*f7_shrinking)(int))(short))(char) = {0}; - - int (*f8)(int (*)(void)) = {0}; - int (*f9)(void (*)(int)) = {0}; - void (*f10)(int (*)(int)) = {0}; - int (*f11)(int, int (*)(void)) = {0}; - int (*f12)(int (*)(void), int) = {0}; - int (*f13)(int (*)(void), int (*)(void)) = {0}; - - int (*f14)(int (*)(void)) = {0}; - int (*f15)(int (*)(int (*)(void))) = {0}; - int (*f16)(int (*)(int (*)(int (*)(void)))) = {0}; - int (*f17)(int (*)(int (*)(int (*)(int (*)(void))))) = {0}; - - int (*f18)(int (*)(void)) = {0}; - int (*f19)(int (*(*)(void))(void)) = {0}; - int (*f20)(int (*(*(*)(void))(void))(void)) = {0}; - int (*f21)(int (*(*(*(*)(void))(void))(void))(void)) = {0}; - - int (*(*(*(*f22)(void))(void))(void))(void) = {0}; - int (*(*(*(*f23)(int [2]))(void))(void))(void) = {0}; - int (*(*(*(*f24)(int *[2]))(int [3]))(void))(void) = {0}; - int (*(*(*(*f25)(int (*)[2]))(int *[3]))(int [4]))(void) = {0}; - int (*(*(*(*f26)(int **(**)[2]))(int (*)[3]))(int *[4]))(int [5]) = {0}; - - int x = 0; -} - -//////////////////////////////// -// NOTE(allen): Extended Type Coverage Eval - -template -struct Template_Example{ - X x; - int y; -}; - -template -struct Template_Example2{ - X x; - Y y; -}; - -template -struct Template_Example3{ - X x; - Y y; - Template_Example3(X x, Y y) - { - this->x = x; - this->y = y; - } - ~Template_Example3() - { - int x = 2; - int y = 5; - int z = x + y; - } -}; - -struct SingleInheritanceBase -{ - int x; - int y; -}; - -struct SingleInheritanceDerived : SingleInheritanceBase -{ - int z; - int w; -}; - -struct Has_Members{ - int a; - int b; - uint64_t c; - uint64_t d; - Basics bas; - - int w(void){ return a; } - int x(void){ return b; } - uint64_t y(void){ return c; } - uint64_t z(void){ return d; } - Basics bas_f(void){ return bas; } -}; - -struct Has_Static_Members{ - int a; - int b; - static uint64_t c; - static uint64_t d; - - int w(void){ return a; } - int x(void){ return b; } - static uint64_t y(void){ return c; } - static uint64_t z(void){ return d; } -}; - -uint64_t Has_Static_Members::c = 0; -uint64_t Has_Static_Members::d = 0; - -struct Pointer_To_Member{ - int Has_Members::*member_ptr_int; - uint64_t Has_Members::*member_ptr_u64; - Basics Has_Members::*member_ptr_bas; - - int (Has_Members::*method_ptr_int)(void); - uint64_t (Has_Members::*method_ptr_u64)(void); - Basics (Has_Members::*method_ptr_bas)(void); -}; - -struct Has_Sub_Types{ - struct Sub_Type1{ - int x; - int y; - }; - - struct Sub_Type2{ - float x; - float y; - }; - - Sub_Type1 a; - Sub_Type2 b; -}; - -struct Conflicting_Type_Names{ - struct Sub_Type1{ - uint64_t z; - }; - - struct Sub_Type2{ - int64_t z; - }; - - Sub_Type1 a; - Sub_Type2 b; -}; - -struct Has_Private_Sub_Types{ - Has_Private_Sub_Types(char x1, char y1, - float x2, int y2, - int x3, float y3){ - this->a.x = x1; - this->a.y = y1; - this->b.x = x2; - this->b.y = y2; - this->c.x = x3; - this->c.y = y3; - } - - struct Public_Sub_Type{ - char x; - char y; - }; - Public_Sub_Type a; - - protected: - struct Protected_Sub_Type{ - float x; - int y; - }; - Protected_Sub_Type b; - - private: - struct Private_Sub_Type{ - int x; - float y; - }; - Private_Sub_Type c; -}; - -struct Vtable_Parent{ - virtual void a_virtual_function(void) = 0; - virtual void b_virtual_function(void) = 0; - virtual void c_virtual_function(void) = 0; - - void a_virtual_function(int r){ - for (int i = 0; i < r; i += 1){ - a_virtual_function(); - } - } -}; - -struct Vtable_Child : Vtable_Parent{ - int x; - int y; - - Vtable_Child(int a, int b){ - x = a; - y = b; - } - virtual void a_virtual_function(void){ - x = 0; - }; - virtual void b_virtual_function(void){ - y = 0; - }; - virtual void c_virtual_function(void){ - x = y; - }; -}; - -struct Vinheritance_Base{ - int x; - int y; - - virtual void a_virtual_function(void){ - x = 0; - }; - virtual void b_virtual_function(void){ - y = 0; - }; - virtual void x_virtual_function(void){ - y = x; - }; -}; - -struct Vinheritance_MidLeft : virtual Vinheritance_Base{ - float left; - - virtual void c1_virtual_function(void){ - left = 0; - }; - virtual void c2_virtual_function(void){ - left = 0; - }; -}; - -struct Vinheritance_MidRight : virtual Vinheritance_Base{ - float right; - - virtual void d_virtual_function(void){ - right = 0; - }; -}; - -struct Vinheritance_Child : Vinheritance_MidLeft, Vinheritance_MidRight{ - char *name; - - virtual void a_virtual_function(void){ - x = 1; - }; - virtual void c1_virtual_function(void){ - left = 1; - }; -}; - -struct Minheritance_Base{ - int x; - int y; -}; - -struct Minheritance_MidLeft : Minheritance_Base{ - float left; -}; - -struct Minheritance_MidRight : Minheritance_Base{ - float right; -}; - -struct Minheritance_Child : Minheritance_MidLeft, Minheritance_MidRight{ - char *name; -}; - -struct Pure -{ - virtual ~Pure() = default; - virtual void Foo() = 0; -}; - -struct PureChild : Pure -{ - virtual ~PureChild() = default; - virtual void Foo() {a += 1;} - double a = 0; -}; - -struct Base -{ - int x; - int y; - int z; - virtual ~Base() = default; - virtual void Foo() = 0; -}; - -struct Derived : Base -{ - int r; - int g; - int b; - int a; - virtual ~Derived() = default; - virtual void Foo() - { - x += 1; - y += 1; - y += 1; - z += 1; - z += 1; - z += 1; - a += 1; - a += 1; - a += 1; - a += 1; - } -}; - -struct DerivedA : Base -{ - float a; - float b; - virtual void Foo() {a += 1;} - virtual ~DerivedA() = default; -}; - -struct DerivedB : Base -{ - double c; - double d; - virtual void Foo() {c += 1;} - virtual ~DerivedB() = default; -}; - -struct NonVirtualBase -{ - int x; - int y; - int z; -}; - -struct NonVirtualDerived : NonVirtualBase -{ - int r; - int g; - int b; - int a; -}; - -struct OverloadedMethods{ - int x; - int cool_method(void){ - return(x); - } - int cool_method(int z){ - int r = x; - x = z; - return(r); - } - void cool_method(int y, int z){ - if (x < z){ - x = y; - } - else{ - x = z; - } - } -}; - -struct HasStaticConstMembers -{ - int a; - int b; - static int c; - static int d; - static const int e = 789; - static const int f = 101112; -}; - -int HasStaticConstMembers::c = 123; -int HasStaticConstMembers::d = 456; - -struct Has_A_Constructor{ - int n; - int d; - Has_A_Constructor(int a, int b){ - int gcd = 1; - { - int x = a; - int y = b; - if (x < y){ - y = a; - x = b; - } - for (;y > 0;){ - int z = x%y; - x = y; - y = z; - } - gcd = x; - } - n = a/gcd; - d = b/gcd; - } - - static int N; - static int D; - ~Has_A_Constructor(){ - int m = N*d + n*D; - int e = d*D; - N = m; - D = d; - } -}; - -int Has_A_Constructor::N = 0; -int Has_A_Constructor::D = 1; - -struct Constructor_Gotcha_Test{ - int x; - int y; - void Constructor_Gotcha(void){ - x = y = 0; - } -}; - -struct Has_A_Friend{ - friend struct Modifies_Other; - int get_x(void){ return x; } - int get_y(void){ return y; } - - private: - int x; - int y; -}; - -struct Modifies_Other{ - int x; - int y; - - void talk_to_friend(Has_A_Friend *other){ - other->x = y; - other->y = x; - } -}; - -namespace UserNamespace{ - namespace SubA{ - struct Foo{ - int x; - int y; - }; - }; - namespace SubB{ - struct Foo{ - float u; - float v; - }; - }; - - SubA::Foo foo_a = {10, 20}; - SubB::Foo foo_b = {0.1f, 0.05f}; - - static void namespaced_function(void){ - foo_a.x = (int)(foo_a.y*foo_b.u); - foo_b.v = (float)(foo_a.x*foo_b.v); - } -}; - -static void -call_with_pass_by_reference(int &x){ - x += 1; -} - -static void -call_with_pass_by_const_reference(const int &x){ - int y = x; -} - -static void -extended_type_coverage_eval_tests(void){ - //////////////////////////////// - // NOTE(allen): Extensions to base type system. - { - int x = 0; - const int *x_ptr = &x; - int *const x_cptr = &x; - - call_with_pass_by_reference(x); - - call_with_pass_by_const_reference(x); - } - - //////////////////////////////// - // NOTE(allen): Extensions to user defined types - { - Template_Example temp_f = {1.f, 2}; - Template_Example temp_v = {(void*)&temp_f, 2}; - Template_Example > temp_tf = {temp_f, 2}; - Template_Example2 temp_if = {2, 1.f}; - Template_Example3 temp3_if(2, 1.f); - Template_Example3 temp3_vi((void *)&temp3_if, 1.f); - Template_Example3> temp3_itif(123, temp_if); - - SingleInheritanceDerived sid; - sid.x = 123; - sid.y = 456; - sid.z = 789; - sid.w = 999; - - Pointer_To_Member pointer_to_member = { - &Has_Members::a, &Has_Members::c, &Has_Members::bas, - &Has_Members::x, &Has_Members::z, &Has_Members::bas_f, - }; - - Has_Static_Members has_static_members = { 10, 20 }; - Has_Static_Members::c = 100; - Has_Static_Members::d = 110; - has_static_members.x(); - has_static_members.y(); - has_static_members.z(); - has_static_members.w(); - - Has_Sub_Types has_sub_types = { - {100, 200}, - {.1f, .2f}, - }; - - Conflicting_Type_Names conflicting_type_names = { - {10}, {-20}, - }; - - Has_Private_Sub_Types has_private_sub_types(1, 2, 4, 8, 16, 32); - - Vtable_Child vtable_child(1, 2); - vtable_child.a_virtual_function(); - - Vinheritance_Child vinheritance_child; - vinheritance_child.name = "foobar"; - vinheritance_child.left = 10.5f; - vinheritance_child.right = 13.0f; - vinheritance_child.x = -1; - vinheritance_child.y = -1; - - Minheritance_Child minheritance_child; - minheritance_child.name = "foobar"; - minheritance_child.left = 10.5f; - minheritance_child.right = 13.0f; - minheritance_child.Minheritance_MidLeft::x = -1; - minheritance_child.Minheritance_MidLeft::y = -1; - minheritance_child.Minheritance_MidRight::x = +1; - minheritance_child.Minheritance_MidRight::y = +1; - - Pure *child = new PureChild(); - child->Foo(); - child->Foo(); - child->Foo(); - delete child; - - Base *derived = new Derived(); - derived->Foo(); - derived->Foo(); - derived->Foo(); - delete derived; - - NonVirtualBase *non_virtual_derived = new NonVirtualDerived(); - non_virtual_derived->x += 1; - non_virtual_derived->x += 1; - non_virtual_derived->x += 1; - - Base *base_array[1024] = {0}; - for(int i = 0; i < sizeof(base_array)/sizeof(base_array[0]); i += 1) - { - if((i & 1) == 1) - { - base_array[i] = new DerivedA(); - } - else - { - base_array[i] = new DerivedB(); - } - } - - OverloadedMethods overloaded_methods; - { - overloaded_methods.x = 0; - int a = overloaded_methods.cool_method(); - overloaded_methods.cool_method(-10, 100); - int b = overloaded_methods.cool_method(100); - overloaded_methods.cool_method(b*2, a*2); - int c = overloaded_methods.cool_method(a + b); - int z = c; - } - - Has_A_Constructor construct_me(360, 25); - - Has_A_Friend has_a_friend; - - Modifies_Other modifies_other; - modifies_other.x = 57; - modifies_other.y = 66; - - modifies_other.talk_to_friend(&has_a_friend); - - int x = has_a_friend.get_x(); - int y = has_a_friend.get_y(); - int z = x; - - HasStaticConstMembers static_const_members = {0}; - static_const_members.a = 123 + HasStaticConstMembers::c * HasStaticConstMembers::e; - static_const_members.b = 456 + HasStaticConstMembers::d * HasStaticConstMembers::f; - } - - //////////////////////////////// - // NOTE(allen): Namespaces - { - UserNamespace::namespaced_function(); - } -} - -//////////////////////////////// -//~ rjf: Templated Function Eval Tests - -typedef struct TemplateArg TemplateArg; -struct TemplateArg -{ - int x; - int y; - int z; - float a; - float b; - float c; - char *name; -}; - -template static T -templated_factorial(T t) -{ - T result = t; - if(t > 1) - { - result *= templated_factorial(t-1); - } - return result; -} - -template static T -compute_template_arg_info(T t) -{ - int sum = t.x + t.y + t.z; - int size = sizeof(t); - float sum_f = t.a + t.b + t.c; - OutputDebugStringA(t.name); - return t; -} - -static void -templated_function_eval_tests(void) -{ - int int_factorial = templated_factorial(10); - float float_factorial = templated_factorial(10); - TemplateArg arg = {1, 2, 3, 4.f, 5.f, 6.f, "my template arg"}; - compute_template_arg_info(arg); - int x = 0; -} - -//////////////////////////////// -//~ NOTE(allen): C Type Coverage - -extern "C"{ -#include "mule_c.h" -} - -//////////////////////////////// -//~ rjf: Basic Inline Line Info Tests - -#if defined(_MSC_VER) -# define FORCE_INLINE __forceinline -#elif defined(__clang__) -# define FORCE_INLINE __attribute__((always_inline)) -#else -# error need force inline for this compiler -#endif - -static FORCE_INLINE void -basic_inlinee(int inlinee_param_x, int inlinee_param_y, int inlinee_param_z) -{ - OutputDebugStringA("A\n"); - OutputDebugStringA("B\n"); - OutputDebugStringA("C\n"); - OutputDebugStringA("D\n"); -} - -static void -basic_inline_tests(void) -{ - OutputDebugStringA("{\n"); - basic_inlinee(12, 34, 56); - OutputDebugStringA("}\n"); -} - -//////////////////////////////// -//~ rjf: Fancy Visualization Eval Tests - -struct Bitmap -{ - unsigned char *base; - int width; - int height; -}; -raddbg_auto_view_rule(Bitmap, lens:bitmap(base, width, height)); - -static unsigned int -mule_bswap_u32(unsigned int x) -{ - unsigned int result = (((x & 0xFF000000) >> 24) | - ((x & 0x00FF0000) >> 8) | - ((x & 0x0000FF00) << 8) | - ((x & 0x000000FF) << 24)); - return result; -} - -static void -fancy_viz_eval_tests(void) -{ - //- rjf: windows -> GetLastError -#if _WIN32 - DWORD error_code = 0; - SetLastError(1234); - error_code = GetLastError(); - SetLastError(4567); - error_code = GetLastError(); - (void)error_code; -#endif - - //- rjf: booleans (checkboxes) - bool bool1 = 0; raddbg_pin(bool1); - bool bool2 = 1; raddbg_pin(bool2); - bool bool3 = 0; raddbg_pin(bool3); - - //- rjf: sliders - float slide1 = 500.f; raddbg_pin(range1(slide1, 0, 1000)); - double slide2 = 0.75; raddbg_pin(range1(slide2, 0, 1.0)); - int slide3 = 25; raddbg_pin(range1(slide3, 0, 100)); - - //- rjf: colors - float example_color_4f32[4] = {1.00f, 0.85f, 0.25f, 1.00f}; - unsigned int example_color_u32 = 0xff6f30ff; - struct {float r, g, b, a;} example_color_struct = {0.50f, 0.95f, 0.75f, 1.00f}; - int x0 = 0; - raddbg_pin(color(example_color_4f32)); - raddbg_pin(color(example_color_u32)); - raddbg_pin(color(example_color_struct)); - - //- rjf: multiline text - char *long_string = ("This is an example of some very long text with line breaks\n" - "in it. This is a very common kind of data which is inspected\n" - "in the debugger while programming, and it is often a pain\n" - "when it is poorly supported.\n"); - char *code_string = ("#include \n" - "\n" - "int main(int argc, char**argv)\n" - "{\n" - " printf(\"Hello, World!\\n\");\n" - " return 0;\n" - "}\n\n"); - int x1 = 0; - raddbg_pin(text(long_string)); - raddbg_pin(text(code_string, lang=c)); - raddbg_pin(disasm(fancy_viz_eval_tests)); - - //- rjf: bitmaps - unsigned int background_color = 0x00000000; - unsigned int main_color = 0xff2424ff; - unsigned int shine_color = 0xff5693ff; - unsigned int shadow_color = 0xff238faf; - unsigned int bg = mule_bswap_u32(background_color); - unsigned int cl = mule_bswap_u32(main_color); - unsigned int sn = mule_bswap_u32(shine_color); - unsigned int sh = mule_bswap_u32(shadow_color); - unsigned int pixels[] = - { - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, cl, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, cl, cl, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, cl, cl, bg, cl, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, cl, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, cl, cl, cl, bg, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, cl, sn, sn, cl, cl, cl, sh, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, sh, sn, cl, cl, cl, sh, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, sh, cl, cl, cl, sh, sh, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, sh, sh, sh, bg, bg, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, - bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, - }; - raddbg_pin(bitmap(pixels, 18, 18)); - for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) - { - unsigned int r = pixels[i]&0x000000ff; - unsigned int a = pixels[i]&0xff000000; - pixels[i] = pixels[i]>>8; - pixels[i] &= ~0xffff0000; - pixels[i] |= (r<<16); - pixels[i] |= (a); - } - for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) - { - unsigned int r = pixels[i]&0x000000ff; - unsigned int a = pixels[i]&0xff000000; - pixels[i] = pixels[i]>>8; - pixels[i] &= ~0xffff0000; - pixels[i] |= (r<<16); - pixels[i] |= (a); - } - for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) - { - unsigned int r = pixels[i]&0x000000ff; - unsigned int a = pixels[i]&0xff000000; - pixels[i] = pixels[i]>>8; - pixels[i] &= ~0xffff0000; - pixels[i] |= (r<<16); - pixels[i] |= (a); - } - int x2 = 0; - - //- rjf: auto-view-rule'd bitmaps - Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; - raddbg_pin(foo); - - //- rjf: 3D geometry - float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ... - { - -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 2.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 2.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 8.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 8.0f, 0.973f, 0.480f, 0.002f, - -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 10.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 10.0f, 0.973f, 0.480f, 0.002f, - 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 10.0f, 0.973f, 0.480f, 0.002f, - 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 2.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 2.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 8.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 8.0f, 0.612f, 0.000f, 0.069f, - 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 10.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 10.0f, 0.612f, 0.000f, 0.069f, - -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 10.0f, 0.612f, 0.000f, 0.069f, - -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 2.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 2.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 8.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 8.0f, 0.000f, 0.254f, 0.637f, - -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 10.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 10.0f, 0.000f, 0.254f, 0.637f, - 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 10.0f, 0.000f, 0.254f, 0.637f, - -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 2.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 2.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 8.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 8.0f, 0.001f, 0.447f, 0.067f, - -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 10.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 10.0f, 0.001f, 0.447f, 0.067f, - 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 10.0f, 0.001f, 0.447f, 0.067f, - -0.6f, 0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - -0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, - 1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, - 0.6f, 0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - 0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, - -1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, - -0.6f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - 0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, - -0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - -0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - 0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, - }; - unsigned int index_data[] = - { - 0, 1, 9, 9, 8, 0, 1, 2, 5, 5, 4, 1, 6, 7, 10, 10, 9, 6, 2, 3, 11, 11, 10, 2, - 12, 13, 21, 21, 20, 12, 13, 14, 17, 17, 16, 13, 18, 19, 22, 22, 21, 18, 14, 15, 23, 23, 22, 14, - 24, 25, 33, 33, 32, 24, 25, 26, 29, 29, 28, 25, 30, 31, 34, 34, 33, 30, 26, 27, 35, 35, 34, 26, - 36, 37, 45, 45, 44, 36, 37, 38, 41, 41, 40, 37, 42, 43, 46, 46, 45, 42, 38, 39, 47, 47, 46, 38, - 48, 49, 57, 57, 56, 48, 49, 50, 53, 53, 52, 49, 54, 55, 58, 58, 57, 54, 50, 51, 59, 59, 58, 50, - 60, 61, 69, 69, 68, 60, 61, 62, 65, 65, 64, 61, 66, 67, 70, 70, 69, 66, 62, 63, 71, 71, 70, 62, - 72, 73, 74, 74, 75, 72, 76, 77, 78, 78, 79, 76, 80, 81, 82, 82, 83, 80, 84, 85, 86, 86, 87, 84, - 88, 89, 90, 90, 91, 88, 92, 93, 94, 94, 95, 92, 96, 97, 98, 98, 99, 96, 100, 101, 102, 102, 103, 100, - 104, 105, 106, 106, 107, 104, 108, 109, 110, 110, 111, 108, 112, 113, 114, 114, 115, 112, 116, 117, 118, 118, 119, 116, - 120, 121, 122, 122, 123, 120, 124, 125, 126, 126, 127, 124, 128, 129, 130, 130, 131, 128, 132, 133, 134, 134, 135, 132, - 136, 137, 138, 138, 139, 136, 140, 141, 142, 142, 143, 140, 144, 145, 146, 146, 147, 144, 148, 149, 150, 150, 151, 148, - 152, 153, 154, 154, 155, 152, 156, 157, 158, 158, 159, 156, 160, 161, 162, 162, 163, 160, 164, 165, 166, 166, 167, 164, - }; - int count = (sizeof index_data/4); - float *vtx = vertex_data; - int vtx_size = sizeof vertex_data; - raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size)); - int x3 = 0; -} - -//////////////////////////////// -//~ rjf: Markup Tests - -static void -markup_tests(void) -{ - int x = 0; - raddbg_add_breakpoint(&x, sizeof(x), 0, 1, 0); - for(int i = 0; i < 10000; i += 1) - { - if(i == 5000) - { - x += 1; - } - } - raddbg_remove_breakpoint(&x, sizeof(x), 0, 1, 0); -} - -//////////////////////////////// -//~ NOTE(allen): Function Overload Resolution - -static int -overloaded_function(float y){ - int r = (int)(y + 0.5f); - return(r); -} - -static int -overloaded_function(float y, int x){ - int r = overloaded_function(y) + x; - return(r); -} - -static int -overloaded_function(int x){ - float y = (float)x; - int r = overloaded_function(y, 1); - return(r); -} - -//////////////////////////////// -// NOTE(allen): Control Flow Stepping - -static void -control_flow_stepping_tests(void){ - { - int a = 1; - if (a < 1){ - a += 1; - } - if (a < 2){ - a += 2; - } - } - - { - int a = 1; - if (a < 1) - { - a += 1; - } - if (a < 2) - { - a += 2; - } - } - - { - int a = 1; - if (a < 1) - a += 1; - if (a < 2) - a += 2; - } - - { - int a = 1; - int b = 2; - if (a <= b){ - if (a == b){ - b += 1; - } - else{ - a += 1; - } - } - else{ - if (a%2){ - a = b; - } - else{ - a = b - 1; - } - } - } - - { - int a = 1; - int b = 2; - if (a <= b) - { - if (a == b) - { - b += 1; - } - else - { - a += 1; - } - } - else - { - if (a%2) - { - a = b; - } - else - { - a = b - 1; - } - } - } - - { - int a = 1; - int b = 2; - if (a <= b) - if (a == b) - b += 1; - else - a += 1; - else - if (a%2) - a = b; - else - a = b - 1; - } - - { - int x = 0; - for (int i = 0; i < 10; i += 1){ - x += i; - } - } - - { - int x = 0; - for (int i = 0; i < 10; i += 1) - { - x += i; - } - } - - { - int x = 0; - for (int i = 0; i < 10; i += 1) - x += i; - } - - { - int x = 0; - for (int i = 0; i < 10; i += 1) x += i; - } - - { - int a = 1; - for (;a < 10;){ - switch (a){ - case 0: case 1: case 2: - { - a += 2; - }break; - - default: - case 4: - case 5: - { - a += 1; - }break; - - case 6: a += 1; break; - case 7: a += 1; - case 8: - case 9: a += 1; - } - } - } - - { - int i = 0; - while (i < 5){ - i += 1; - } - - while (i < 10) - { - i += 1; - } - - while (i < 15) - i += 1; - - while (i < 20) i += 1; - } - - { - int i = 0; - do - { - i += 1; - } while (i < 10); - } - - { - int i = 17; - - check_again: - if (i <= 1) goto done; - if ((i&1) == 0) goto even_case; - - // odd_case: - i = 3*i + 1; - - even_case: - i /= 2; - goto check_again; - - done:; - } - - { - int x = 15; - label_same_line:; x -= 1; if(x > 0) { goto label_same_line; } else { goto end_label_same_line; } - } - end_label_same_line:; -} - -//////////////////////////////// -// NOTE(allen): Indirect Call/Jump Stepping Tests - -typedef int FunctionType(int); - -static int -function_foo(int a){ - if (a < 1){ - a += 1; - } - if (a < 2){ - a += 2; - } - return(a); -} - -static int -function_bar(int x){ - for (int i = 0; i < 10; i += 1){ - x += i; - } - return(x); -} - - -static void -indirect_call_jump_stepping_tests(void){ - int z = 1; - FunctionType *ptr = function_foo; - z = ptr(z); - if ((z & 1) == 0){ - ptr = function_bar; - } - z = ptr(z); - - switch (z&7){ - case 0: - { - z += 2; - ptr = function_bar; - }break; - - case 1: - { - z += 1; - ptr = function_bar; - }break; - - case 2: - { - z *= 2; - ptr = function_bar; - }break; - - case 3: - { - z -= 10; - ptr = function_foo; - }break; - - case 4: - { - z -= 5; - ptr = function_foo; - }break; - - case 5: - { - z = z ^ 0x10; - ptr = function_foo; - }break; - - case 6: - { - z = z & ~0x10; - ptr = function_foo; - }break; - - case 7: - { - z = z | 0x10; - ptr = function_foo; - }break; - } - - z = ptr(z); -} - -//////////////////////////////// -// NOTE(rjf): alloca (Variable-Width Stack Changes) Stepping Tests - -static void -alloca_stepping_tests(void) -{ - int x = 1; - int y = 3; - int z = 5; - -#if _WIN32 - int *mem = (int *)_alloca((x+y+z)*sizeof(int)); - mem[0] = x; - mem[1] = y; - mem[2] = z; -#else - int *mem = (int *)__builtin_alloca((x+y+z)*sizeof(int)); - mem[0] = x; - mem[1] = y; - mem[2] = z; -#endif -} - -//////////////////////////////// -// NOTE(allen): Overloaded Line Stepping - -static int -function_get_integer(void){ - return(1); -} - -static void -function_with_multiple_parameters(int x, int y){ - x += y; -} - -static int -recursive_single_line(int x){ return(x <= 1?0:x + recursive_single_line(x/2)); } - -static int shared_1(int x) { return(x); } static int shared_2(int x) { return(1 + shared_1(x)); } - -static void -overloaded_line_stepping_tests(void){ - function_with_multiple_parameters(function_get_integer(), function_get_integer()); - function_with_multiple_parameters(function_get_integer(), function_get_integer()); - function_with_multiple_parameters(function_get_integer(), function_get_integer()); - - recursive_single_line(50); - recursive_single_line(50); - recursive_single_line(50); - - shared_2(5); - shared_2(5); - shared_2(5); - - function_get_integer(); shared_1(1); shared_1(2); - - if ((shared_2(10) && shared_2(-1)) || - shared_2(function_get_integer())){ - int x = 0; - } - else{ - int y = 0; - } -} - -//////////////////////////////// -// NOTE(allen): Long Jump Stepping - -#include - -static jmp_buf global_jump_buffer; -static int global_jump_x; - -static void -long_jump_from_function(void){ - int spin = 0; - for (; spin < 5; spin += 1); - longjmp(global_jump_buffer, 2); - global_jump_x = spin; -} - -static void -long_jump_wrapped_in_function(void){ - global_jump_x = 0; - int val = setjmp(global_jump_buffer); - if (val == 0){ - global_jump_x = 1; - longjmp(global_jump_buffer, 1); - } - else if (val == 1){ - if (global_jump_x == 1){ - global_jump_x = 2; - long_jump_from_function(); - } - } - else if (val == 2){ - global_jump_x = 3; - } -} - -static void -long_jump_stepping_tests(void){ - - long_jump_wrapped_in_function(); - - long_jump_wrapped_in_function(); - - long_jump_wrapped_in_function(); - -} - -//////////////////////////////// -// NOTE(allen): Recursion Stepping - -static int -recursive_call(int x){ - if (x <= 1){ - return(x); - } - - int r1 = recursive_call(x - 1); - int r2 = recursive_call(x - 2); - return(r1 + r2); -} - -static int -tail_recursive_call(int x, int m){ - if (x <= 1){ - return(m); - } - return(tail_recursive_call(x - 1, x*m)); -} - -static void -recursion_stepping_tests(void){ - - recursive_call(4); - - recursive_call(4); - - tail_recursive_call(5, 1); - - tail_recursive_call(5, 1); - -} - -//////////////////////////////// -// NOTE(rjf): Debug Strings - -static void -debug_string_tests(void) -{ - for(int i = 0; i < 100; i += 1) - { - printf("here is a number: %i\n", i); - fflush(stdout); - } -#if _WIN32 - for(int i = 0; i < 100; i += 1) - { - OutputDebugStringA("Hello, World!\n"); - } - char message[65409+1]; - memset(&message[0], '=', sizeof(message)); - for(int i = 1; i < sizeof(message); i += 128) - { - message[i] = '\n'; - } - message[sizeof(message) - 1] = 0; - OutputDebugStringA(message); -#endif -} - -//////////////////////////////// -//~ rjf: Interrupt Stepping Tests - -#include - -static void -interrupt_stepping_tests(void) -{ - __debugbreak(); - __debugbreak(); - __debugbreak(); - __debugbreak(); - for(int i = 0; i < 1000; i += 1) - { - if(i == 999) - { - __debugbreak(); - } - } - for(int i = 0; i < 1000; i += 1) - { - if(i == 999) - { - assert(0); - } - } - int x = 0; -} - -//////////////////////////////// -//~ rjf: JIT Stepping Tests - -static void -jit_stepping_tests(void) -{ - OutputDebugString("A\n"); - VOID *code = VirtualAlloc(0, 0x1000, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); - *((uint32_t*)code) = 0xC39090CC; - ((void (__fastcall *)()) code)(); - OutputDebugString("B\n"); -} - -//////////////////////////////// -// NOTE(allen): Exception Stepping - -static void -exception_filter_test(void) -{ - __try - { - RaiseException(0xc0000095, 0, 0, 0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - OutputDebugStringA("did an exception\n"); - } -} - -int *global_null_read_pointer = 0; -static void -trip(void){ - *global_null_read_pointer = 0; -} - -static void -cpp_exception_in_function(void){ - int v = 0; - try{ - throw 1; - } - catch (...){ - v = 1; - } -} - -static void -cpp_throw_in_function(void){ - throw 1; -} - -static void -win32_exception_in_function(void){ -#if _WIN32 - int v = 0; - __try{ - trip(); - v = 1; - } - __except (EXCEPTION_EXECUTE_HANDLER){ - v = 2; - } - - v = 3; - __try{ - trip(); - v = 4; - } - __except (EXCEPTION_EXECUTE_HANDLER){ - v = 5; - } -#endif -} - -static void -cpp_recursive_exception(int x){ - try{ - if (x > 1){ - throw 1; - } - } - catch (...){ - x -= 1; - cpp_recursive_exception(x); - x += 1; - } -} - -static void -win32_recursive_exception(int x){ -#if _WIN32 - __try{ - if (x > 1){ - throw 1; - } - } - __except (EXCEPTION_EXECUTE_HANDLER){ - x -= 1; - win32_recursive_exception(x); - x += 1; - } -#endif -} - -static void -exception_stepping_tests(void){ - { - int v = 0; - try{ - throw 1; - } - catch (...){ - v = 1; - } - } - - { - int v = 0; - try{ - cpp_throw_in_function(); - } - catch (...){ - v = 1; - } - } - - cpp_exception_in_function(); - cpp_exception_in_function(); - -#if _WIN32 - win32_exception_in_function(); - win32_exception_in_function(); -#endif - - // NOTE(allen): Exception in catch tests - { - int v = 0; - try{ - v = 1; - throw 1; - } - catch (...){ - try{ - v = 2; - throw 2; - } - catch (...){ - v = 3; - } - } - } - - { - int v = 0; - try{ - v = 1; - throw 1; - } - catch (...){ - cpp_exception_in_function(); - } - } - -#if _WIN32 - { - int v = 0; - try{ - v = 1; - throw 1; - } - catch (...){ - win32_exception_in_function(); - } - } -#endif - - cpp_recursive_exception(4); - cpp_recursive_exception(4); - cpp_recursive_exception(4); - -#if _WIN32 - win32_recursive_exception(4); - win32_recursive_exception(4); - win32_recursive_exception(4); -#endif - - // NOTE(allen): Try in try tests - { - int v = 0; - try{ - try{ - v = 1; - throw 1; - } - catch (...){ - v = 2; - } - throw 2; - } - catch (...){ - v = 3; - } - } - - { - int v = 0; - try{ - try{ - v = 1; - cpp_throw_in_function(); - } - catch (...){ - v = 2; - } - throw 2; - } - catch (...){ - v = 3; - } - } - - { - int v = 0; - try{ - cpp_exception_in_function(); - throw 2; - } - catch (...){ - v = 3; - } - } - -#if _WIN32 - { - int v = 0; - try{ - win32_exception_in_function(); - throw 2; - } - catch (...){ - v = 3; - } - } -#endif - -} - -typedef void (*callback_t)(int a); -static void -dynamic_step_test(void){ -#if _WIN32 -#if defined(_x86_64) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( _M_AMD64 ) - void *page = VirtualAlloc(0, 4096, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); - char *ptr = (char*)page; - *ptr++ = 0x51; // push rcx - *ptr++ = 0x59; // pop rcx - *ptr++ = 0xC3; // ret - callback_t cb = (callback_t)page; - cb(1); -#endif -#endif -} - -//////////////////////////////// - -raddbg_entry_point(mule_main); - -int -mule_main(int argc, char** argv) -{ - raddbg_thread_name("mule_main_thread"); - raddbg_thread_color_rgba(0.4f, 0.9f, 0.2f, 1); - if(raddbg_is_attached()) - { - raddbg_log("raddbg is attached!\n"); - } - - mule_init(); - - // NOTE(allen): Eval Tests - type_coverage_eval_tests(); - - mutating_variables_eval_tests(); - - nested_types_eval_tests(); - - struct_parameters_eval_tests(); - - global_eval_tests(); - - return_eval_tests(); - - tls_eval_tests(); - - complicated_type_coverage_tests(); - - extended_type_coverage_eval_tests(); - - templated_function_eval_tests(); - - c_type_coverage_eval_tests(); - - c_type_with_bitfield_usage(); - - optimized_build_eval_tests(); - - optimized_struct_parameters_eval_tests(); - - fancy_viz_eval_tests(); - - exception_filter_test(); - - markup_tests(); - - // NOTE(allen): Stepping Tests - control_flow_stepping_tests(); - - indirect_call_jump_stepping_tests(); - - alloca_stepping_tests(); - - basic_inline_tests(); - - inline_stepping_tests(); - - overloaded_line_stepping_tests(); - - overloaded_function(100); - - dynamic_step_test(); - - long_jump_stepping_tests(); - - recursion_stepping_tests(); - - debug_string_tests(); - - jit_stepping_tests(); - - interrupt_stepping_tests(); - - exception_stepping_tests(); - - return(0); -} +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +/* +** Program to run in debugger organized to provide tests for +** stepping, breakpoints, evaluation, cross-module calls. +*/ + +#define RADDBG_MARKUP_IMPLEMENTATION +#include "lib_raddbg_markup/raddbg_markup.h" + +//////////////////////////////// +// NOTE(allen): System For DLL Testing + +typedef void TestFunction(void); + +static void mule_init(void); +static TestFunction* mule_get_module_function(char *name); + +#if _WIN32 + +#include + +HMODULE mule_dll = 0; + +static void +mule_init(void){ + mule_dll = LoadLibraryA("mule_module.dll"); +} + +static TestFunction* +mule_get_module_function(char *name){ + TestFunction *result = (TestFunction*)GetProcAddress(mule_dll, name); + return(result); +} + +#else + +static void +mule_init(void){ + // TODO(allen): implement +} + +static TestFunction* +mule_get_module_function(char *name){ + // TODO(allen): implement + return(0); +} + +#endif + + +//////////////////////////////// +// NOTE(nick): Entry Point + +int +mule_main(int argc, char **argv); + +#if _WIN32 +#include +#include +int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ + int argc = __argc; + char **argv = __argv; + int result = mule_main(argc, argv); + return(result); +} +#else +int main(int argc, char **argv){ + return(mule_main(argc, argv)); +} +#endif + +//////////////////////////////// +// NOTE(nick): BSS section test + +#if defined(__clang__) +# pragma clang section bss="muleBSS" +#elif defined(_MSC_VER) +// NOTE(nick): clang-cl is borken it allocates memory and sets Initialized Flag on the seciton. +// This is was reported by Jeff => https://bugs.llvm.org/show_bug.cgi?id=47939 +// +// This is still unresolved, last checked Sep 11, 2023. +# pragma bss_seg("muleBSS") +#else +# error "bss not defined" +#endif +char global_variable_in_bss[4096*10000]; + +//////////////////////////////// +// NOTE(allen): Inline Stepping (Built In Separate Unit) + +extern unsigned int fixed_frac_bits; +unsigned int inline_stepping_tests(void); + + +//////////////////////////////// +// NOTE(rjf): -O2 Optimized Code (Built In Separate Unit) + +void optimized_build_eval_tests(void); +void optimized_struct_parameters_eval_tests(void); + +//////////////////////////////// +// NOTE(allen): Type Coverage Eval + +#include +#include + +raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); + +struct Basics +{ + char a; + unsigned char b; + short c; + unsigned short d; + int e; + unsigned int f; + long long g; + unsigned long long h; + float i; + double j; + int z; +}; + +struct Basics_Stdint +{ + int8_t a; + uint8_t b; + int16_t c; + uint16_t d; + int32_t e; + uint32_t f; + int64_t g; + uint64_t h; + float i; + double j; +}; + +struct Pair +{ + int x; + float y; +}; + +struct Fixed_Array +{ + Pair pairs[10]; + int count; +}; + +struct Dynamic_Array +{ + Pair *pairs; + int count; +}; +raddbg_auto_view_rule(Dynamic_Array, slice($)); + +struct Struct_With_Embedded_Arrays +{ + int x; + float y; + Pair pairs[10]; + char z; +}; + +typedef unsigned int Custom_Index_Type; + +typedef void Function_No_Params_Type(void); +typedef void Function_Few_Params_Type(Pair *pairs, int count, Function_No_Params_Type *no_params_type); + +static Function_No_Params_Type *ty_no_params = 0; +static Function_Few_Params_Type *ty_few_params = 0; + +struct Callback{ + Function_Few_Params_Type *few_params; + Function_No_Params_Type *no_params; + Pair pair; +}; + +union Vector_R2 +{ + struct + { + float x; + float y; + }; + float v[2]; +}; +raddbg_auto_view_rule(Vector_R2, only($, x, y)); + +typedef union Matrix4x4F32 Matrix4x4F32; +union Matrix4x4F32 +{ + float elements[4][4]; +}; +raddbg_auto_view_rule(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); + +enum Kind +{ + Kind_None, + Kind_First, + Kind_Second, + Kind_Third, + Kind_Fourth, + Kind_COUNT, +}; + +enum Flag +{ + Flag_None = 0, + Flag_First = 1, + Flag_Second = 2, + Flag_Third = 4, + Flag_Fourth = 8, + Flag_AllMoreNarrow = 0xFF, + Flag_AllNarrow = 0xFFFF, + Flag_All = 0xFFFFFFFF, +}; + +struct Has_Enums +{ + Kind kind; + Flag flags; +}; + +struct Discriminated_Union +{ + Kind kind; + union + { + struct + { + int x; + int y; + Vector_R2 vector; + } first; + Pair second; + struct + { + Function_Few_Params_Type *few_params; + Pair pairs[4]; + } third; + struct + { + Kind sub_kind; + Flag flags; + } fourth; + }; +}; +raddbg_auto_view_rule(Discriminated_Union, + kind == Kind.First ? first : + kind == Kind.Second ? second : + kind == Kind.Third ? third : + kind == Kind.Fourth ? fourth : + $); + +struct Linked_List{ + Linked_List *next; + Linked_List *prev; + int x; +}; + +enum{ + Anonymous_A, + Anonymous_B, + Anonymous_C, + Anonymous_D, +}; + +typedef Kind Alias1; +typedef Flag Alias2; +typedef Has_Enums Alias3; +typedef Discriminated_Union Alias4; + +struct Has_A_Pre_Forward_Reference{ + struct Gets_Referenced_Forwardly *pointer; +}; + +struct Gets_Referenced_Forwardly{ + int x; + int y; +}; + +struct Has_A_Post_Forward_Reference{ + struct Gets_Referenced_Forwardly value; +}; + +struct TypeWithMemberFunction +{ + int x; + int y; + int z; + char *name; + __declspec(noinline) void SetInfo(int _x, int _y, char *_name) + { + x = _x; + y = _y; + z = 0; + name = _name; + OutputDebugStringA("setting info\n"); + } +}; + +static void +no_params1(void){ + +} + +static void +few_params1(Pair *pairs, int count, Function_No_Params_Type *no_params_type){ + +} + +static void +type_coverage_eval_tests(void) +{ + Basics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; + Basics_Stdint basics_stdint = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; + + char string[] = "Hello World!"; + char longer_text[] = + "Suppose there was some text\n" + "With multiple lines in it\r\n" + "\t> What ways might it be rendered?\n" + "\t> How would it deal with line endings?\r\n"; + wchar_t a_wide_string[] = + L"This is a string, but instead of being encoded in a stream of bytes,\n" + L"it is encoded in a stream of 2-byte packages!\n"; + + const char *const_string = "Hello, World!"; + const char const_string_array[] = "Hello, World!"; + const char *const const_ptr_const_string = "Hello, World!"; + + void *pointer = &basics; + Basics *pointer_to_basics = &basics; + Basics **pointer_to_pointer_to_basics = &pointer_to_basics; + + Fixed_Array fixed = + { + { + { 3, 4.f}, + { 5, 6.f}, + { 7, 8.f}, + { 9, 10.f}, + {11, 12.f}, + {13, 14.f}, + {15, 16.f}, + {17, 18.f}, + {19, 20.f}, + }, + 9 + }; + Pair memory_[] = + { + {100, 1.f}, + {101, 2.f}, + {102, 4.f}, + {103, 8.f}, + {104, 16.f}, + {105, 32.f}, + }; + Dynamic_Array dynamic = + { + memory_, + 6 + }; + + raddbg_pin(table(sequence(6), fixed.pairs[$], memory_[$])); + raddbg_pin(basics); + raddbg_pin(fixed); + raddbg_pin(pointer); + raddbg_pin(dynamic); + + Struct_With_Embedded_Arrays swea = {0}; + { + swea.x = 4; + swea.y = 23.5f; + swea.pairs[0].x = 100; + swea.pairs[0].y = 123.f; + swea.pairs[2].x = 300; + swea.pairs[2].y = 323.f; + swea.pairs[5].x = 600; + swea.pairs[5].y = 623.f; + swea.z = 'z'; + } + + Struct_With_Embedded_Arrays *swea_ptr = &swea; + int access_via_ptr_member = swea_ptr->x; + + Custom_Index_Type custom_index = 42; + Custom_Index_Type more_custom_indices[] = { + 04,13,22,31,40 + }; + + Function_No_Params_Type *ptr_no_params = no_params1; + Function_No_Params_Type **ptr_ptr_no_params = &ptr_no_params; + Function_Few_Params_Type *ptr_few_params = few_params1; + Function_Few_Params_Type **ptr_ptr_few_params = &ptr_few_params; + Callback callback = {few_params1, no_params1, {1, 2.f}}; + + Matrix4x4F32 matrix = + { + { + {1.f, 0.f, 0.f, 0.f}, + {0.f, 1.f, 0.f, 0.f}, + {0.f, 0.f, 1.f, 0.f}, + {0.f, 0.f, 0.f, 1.f}, + } + }; + + Vector_R2 vector = {1.f, 2.f}; + + Has_Enums has_enums = {(Kind)4, (Flag)7}; + + Discriminated_Union discriminated_union = {0}; + + discriminated_union.kind = Kind_First; + discriminated_union.first.x = 16; + discriminated_union.first.y = 8; + discriminated_union.first.vector.x = 4.f; + discriminated_union.first.vector.y = 2.f; + + discriminated_union.kind = Kind_Second; + discriminated_union.second.x = 123; + discriminated_union.second.y = 3.14f; + + discriminated_union.kind = Kind_Third; + discriminated_union.third.few_params = few_params1; + discriminated_union.third.pairs[0] = memory_[0]; + discriminated_union.third.pairs[1] = memory_[1]; + discriminated_union.third.pairs[2] = memory_[2]; + discriminated_union.third.pairs[3] = memory_[3]; + + discriminated_union.kind = Kind_Fourth; + discriminated_union.fourth.sub_kind = Kind_First; + discriminated_union.fourth.flags = (Flag)7; + + Linked_List list = {&list, &list, 0}; + + Alias1 a1 = has_enums.kind; + Alias2 a2 = has_enums.flags; + Alias3 a3 = has_enums; + Alias4 a4 = discriminated_union; + + Has_A_Pre_Forward_Reference r1 = {0}; + Has_A_Post_Forward_Reference r2 = {0}; + + Basics &basics_ref = basics; + const Basics *basics_const_ptr = &basics; + const Basics &basics_const_ref = basics; + + union + { + int x; + char y[4]; + } integer_slicing = {123456789}; + + typedef struct stks + { + void *left; + size_t len; + } stks; + stks stks_test[256] = {0}; + stks *stks_first = &stks_test[0]; + stks *stks_ptr = stks_first + 8; + + TypeWithMemberFunction twmf = {0}; + twmf.SetInfo(123, 456, "foobar"); + + TestFunction *function = mule_get_module_function("dll_type_eval_tests"); + function(); + + int abc = 0; + for(int i = 0; i < 1000; i += 1) + { + if(i == 500) + { + abc+= 1; + } + int a = i + abc; + int b = a*5; + } + + char *names[] = + { + "samwise gamgee", "mithrandir", "grima wormtongue", "theodred", "theoden", "eomer", "eowyn", + "arwen", "sauron", "baggins", "proudfoot", "hardbottle", "bag end", "hobbiton", + "bree", "imladris", "isengard", "moria", "mount doom", "helm's deep", "bracegirdle", + "buckleberry ferry", "amun sul", "frodo", "bilbo", "buckland", "fangorn", "elrond", + "numenor", "treebeard", "shadowfax", "brego", "erod", "azufel", "dunedain", + "saruman", "aragorn", "gandalf", "meriadoc brandybuck", "peregrine took", "faramir", "boromir", + "ecthelion", "denethor", "mithrandil", "isildur", "haldir", "elessar", "elendil", + "dead marsh", "rohan", "gondor", "anarion", "earendil", "cirith ungol", "minas morghul", + "minas tirith", "barad-dur", "rivendell", "pellenor", "ithilien", "anduril", "narsil", + "edoras", "mordor", "osgiliath", + }; + + for(int i = 0; i < sizeof(names)/sizeof(names[0]); i += 1) + { + OutputDebugStringA(names[i]); + OutputDebugStringA("\n"); + } + + const int32_t x1 = 3; + const int32_t y1 = -10; + const int32_t z1 = x1 + y1; + + std::vector int_vector; + int_vector.push_back(1); + int_vector.push_back(2); + int_vector.push_back(3); + int_vector.push_back(4); + int_vector.push_back(5); + int_vector.push_back(6); + int_vector.push_back(7); + + int x = (int)(Anonymous_D); +} + +//////////////////////////////// +// NOTE(allen): Mutating Variables Eval + +static const int con_some_constant = 4; +static const float con_some_constant_f = 0.04f; + +static int mut_x = 0; +static int mut_y; +static int mut_xarray[4] = {0, 1, 2, 3}; +static int *mut_xptr; + +static float mut_f = 0; +static float mut_g; +static float mut_farray[4] = {0.5f, 1.5f, 2.5f, 3.5f}; +static float *mut_fptr; + +static float mut_arrayarray[3][3]; + +static Linked_List mut_link; + +static void +mutate_in_function(int *array, int count){ + for (int i = 0; i < count; i += 1){ + array[i] += 1; + } + + for (int i = 0; i < 4; i += 1){ + mut_farray[i] += 1.f; + } +} + +static void +mutating_variables_eval_tests(void){ + //////////////////////////////// + // NOTE(allen): Basics + + int array_literal[10] = { + 10, 20, 30, 40, 50, 60, 70, 80, 90, + }; + + Basics struct_literal = { + -1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001, + }; + + array_literal[0] = struct_literal.e = 9; + + int x = mut_x; + int y = x + 10 + con_some_constant; + mut_y = y; + mut_xarray[0] += 0; + mut_xarray[1] += x; + mut_xarray[2] += y; + mut_xarray[3] += x + y; + + mut_xptr = &mut_xarray[2]; + + *mut_xptr -= (y - x)/2; + *(mut_xptr - 1) += 11; + + float f = mut_f + .333f + con_some_constant_f; + float g = f + 10.1f; + mut_g = g; + mut_farray[0] += 0.000001f; + mut_farray[1] += f; + mut_farray[2] += g; + mut_farray[3] += f + g; + + mut_fptr = &mut_farray[3]; + + *mut_fptr -= (g - f)*0.5f; + *(mut_fptr - 1) += 1.f; + + float a = 0.777f; + for (int i = 0; i < 3; i += 1){ + float b = a*a - 1.f; + for (int j = 0; j < 3; j += 1){ + mut_arrayarray[i][j] = b; + b += 0.111f; + } + a += 0.333f; + } + + //////////////////////////////// + // NOTE(allen): Changes in functions + + mutate_in_function(array_literal, 10); + + mutate_in_function(array_literal, 10); + + //////////////////////////////// + // NOTE(allen): Changes through pointers + + Basics basic = struct_literal; + Basics advanced = struct_literal; + + Basics *struct_pointer = &basic; + + basic.a += 1; + advanced.a += 1; + struct_pointer->a += 1; + + struct_pointer = &advanced; + + basic.b += 1; + advanced.b += 1; + struct_pointer->b += 1; + + Linked_List links[5]; + for (int i = 0; i < 5; i += 1){ + links[i].next = &links[i + 1]; + links[i].prev = &links[i - 1]; + links[i].x = i; + } + links[0].prev = 0; + links[4].next = &mut_link; + mut_link.prev = &links[4]; + mut_link.next = 0; + mut_link.x = 1000; + + Linked_List *link_ptr = links; + + link_ptr = link_ptr->next; + + link_ptr = &links[4]; + link_ptr = &mut_link; + + Linked_List sentinel = {0}; + sentinel.x = -1; + sentinel.next = &links[0]; + links[0].prev = &sentinel; + sentinel.prev = &mut_link; + mut_link.next = &sentinel; + + link_ptr = &sentinel; +} + +//////////////////////////////// +// NOTE(allen): Global Eval + +struct NestedNodeInner{ + unsigned int small0; + unsigned int small1; + unsigned int big0; + unsigned int big1; +}; + +struct NestedNodeOuter{ + NestedNodeOuter *next; + NestedNodeInner *inner_nodes; + unsigned int inner_node_count; +}; + +static void +nested_types_eval_tests(void){ + // doing some setup + NestedNodeOuter *outer1 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); + NestedNodeOuter *outer2 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); + NestedNodeOuter *outer3 = (NestedNodeOuter*)malloc(sizeof(NestedNodeOuter)); + + outer1->next = outer2; + outer2->next = outer3; + outer3->next = 0; + + outer1->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); + outer1->inner_node_count = 10; + + outer2->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); + outer2->inner_node_count = 10; + + outer3->inner_nodes = (NestedNodeInner*)malloc(sizeof(NestedNodeInner)*10); + outer3->inner_node_count = 10; + + for (unsigned int i = 0; i < 10; i += 1){ + outer1->inner_nodes[i].small0 = i; + outer1->inner_nodes[i].small1 = 2*i; + outer1->inner_nodes[i].big0 = 0xFFFFFF + 0xF*i; + outer1->inner_nodes[i].big1 = 0xFFFFFF + 0xFF*i; + + outer2->inner_nodes[i].small0 = 1 + i; + outer2->inner_nodes[i].small1 = 3*i; + outer2->inner_nodes[i].big0 = 0x1000000 + 0x10*i; + outer2->inner_nodes[i].big1 = 0x1000000 + 0x101*i; + + outer3->inner_nodes[i].small0 = 2 + i; + outer3->inner_nodes[i].small1 = 4*i; + outer3->inner_nodes[i].big0 = 0x8000000 + 0xF0*i; + outer3->inner_nodes[i].big1 = 0x8000000 + 0xF0F*i; + } + + // okay eval it here + int x = 0; +} + +//////////////////////////////// +// NOTE(rjf): Struct Parameters Eval + +static void +struct_parameter_helper(Basics basics) +{ + basics.a += 1; + basics.a += 1; + basics.a += 1; +} + +static void +struct_parameters_eval_tests(void) +{ + Basics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001}; + struct_parameter_helper(basics); +} + +//////////////////////////////// +// NOTE(allen): Global Eval + +static int g_abc = 100; +static float g_xyz = 21.f; +static Alias1 g_kind = Kind_First; + +// TODO(allen): more global test types + +static void +complicated_global_mutation(int *x){ + *x = (int)g_xyz; +} + +static void +cross_unit_global_mutation(void){ + fixed_frac_bits = 10; +} + +static void +global_eval_tests(void){ + g_abc = 11*11; + g_xyz = (float)g_abc - 21.f; + + int z = g_abc; + complicated_global_mutation(&z); + + complicated_global_mutation(&g_abc); + + if (g_kind == Kind_First){ + g_abc -= 1; + g_kind = Kind_None; + } + + cross_unit_global_mutation(); + + static int l_abc = 200; + static float l_xyz = 42.f; + static Alias1 l_kind = Kind_Second; + + l_abc = g_abc*2; + l_xyz = g_xyz*2; + l_kind = (Alias1)(g_kind + 1); +} + +//////////////////////////////// +// NOTE(allen): Return Eval + +static int +complicated_return_expression(void){ + int x = 171717; + return((x % 13) <= 5?(x % 19)*11:(x - 500)%200); +} + +static void +return_eval_tests(void){ + complicated_return_expression(); +} + +//////////////////////////////// +// NOTE(allen): TLS Eval + +#if _WIN32 +# define thread_var __declspec(thread) +#else +# define thread_var __thread +#endif + +thread_var int tls_a = 100; +thread_var int tls_b = 999; + +static void +tls_eval_tests(void){ + tls_a = (tls_a + tls_b)/2; + tls_b = tls_b - tls_a; + + TestFunction *dll_tls_eval_test = mule_get_module_function("dll_tls_eval_test"); + if (dll_tls_eval_test != 0){ + dll_tls_eval_test(); + } +} + +//////////////////////////////// +// NOTE(allen): Complicated Type Coverage Eval + +struct Complicated_Type_Members{ + int x600[2][2][2][2]; + int *x601[2][2][2][2]; + int (*x602)[2][2][2][2]; + int (*x603[2])[2][2][2]; + int (*(*x604[2])[2])[2][2]; + int (*(*(*x605[2])[2])[2])[2]; + + int (*x33[2])(void); + int (*x34[3])(void); + int (*x35[2][2])(void); + + int (*(*z33)(void))[2]; + int (*(*z34)(void))[3]; + int (*(*z35)(void))[2][2]; + + int (*(*f2)(void))(void); + int (*(*(*f3)(void))(void))(void); + int (*(*f4)(int))(void); + int (*(*f5)(void))(int); + int (*(*f6)(int))(int); + int (*(*(*f7_growing)(char))(short))(int); + int (*(*(*f7_shrinking)(int))(short))(char); +}; + +static void +complicated_type_coverage_tests(void){ + Complicated_Type_Members m = {0}; + + int x1 = {0}; + int *x2 = {0}; + int **x3 = {0}; + + int x4a[2] = {0}; + int *x4[2] = {0}; + int x5a[3] = {0}; + int *x5[3] = {0}; + int *x6[2][2] = {0}; + int (*x7)[2] = {0}; + int (*x8)[3] = {0}; + int (*x9)[2][2] = {0}; + + int x600[2][2][2][2] = {0}; + int *x601[2][2][2][2] = {0}; + int (*x602)[2][2][2][2] = {0}; + int (*x603[2])[2][2][2] = {0}; + int (*(*x604[2])[2])[2][2] = {0}; + int (*(*(*x605[2])[2])[2])[2] = {0}; + + int x606_growing [2][3][4][5] = {0}; + int x606_shrinking[5][4][3][2] = {0}; + + int (*(*(*x607_growing [2])[3])[4])[5] = {0}; + int (*(*(*x607_shrinking[5])[4])[3])[2] = {0}; + + int **x10[2] = {0}; + int **x11[3] = {0}; + int **x12[2][2] = {0}; + int *(*x13)[2] = {0}; + int *(*x14)[3] = {0}; + int *(*x15)[2][2] = {0}; + int **x16[2] = {0}; + int **x17[3] = {0}; + int **x18[2][2] = {0}; + + int (*y1[2])[2] = {0}; + int (*y2[3])[2] = {0}; + int (*y3[2][2])[2] = {0}; + int (*y4[2])[3] = {0}; + int (*y5[3])[3] = {0}; + int (*y6[2][2])[3] = {0}; + int (*y7[2])[2][2] = {0}; + int (*y8[3])[2][2] = {0}; + int (*y9[2][2])[2][2] = {0}; + + int (*x19)(void) = {0}; + int (*x20)(int) = {0}; + int (*x21)(int, int) = {0}; + int (*x22)(int*, int) = {0}; + int (*x23)(int**, int) = {0}; + int (*x24)(int**, int*) = {0}; + int (*x25)(int**, int**) = {0}; + + int *(*x26)(void) = {0}; + int *(*x27)(int) = {0}; + int *(*x28)(int, int) = {0}; + int *(*x29)(int*, int) = {0}; + int *(*x30)(int**, int) = {0}; + int *(*x31)(int**, int*) = {0}; + int *(*x32)(int**, int**) = {0}; + + int (*x33[2])(void) = {0}; + int (*x34[3])(void) = {0}; + int (*x35[2][2])(void) = {0}; + + int (*x36[2])(int) = {0}; + int (*x37[3])(int) = {0}; + int (*x38[2][2])(int) = {0}; + + int (*x39[2])(int, int) = {0}; + int (*x40[3])(int, int) = {0}; + int (*x41[2][2])(int, int) = {0}; + + int (*x42[2])(int*, int) = {0}; + int (*x43[3])(int*, int) = {0}; + int (*x44[2][2])(int*, int) = {0}; + + int (*x45[2])(int**, int) = {0}; + int (*x46[3])(int**, int) = {0}; + int (*x47[2][2])(int**, int) = {0}; + + int (*x48[2])(int**, int*) = {0}; + int (*x49[3])(int**, int*) = {0}; + int (*x50[2][2])(int**, int*) = {0}; + + int (*x51[2])(int**, int**) = {0}; + int (*x52[3])(int**, int**) = {0}; + int (*x53[2][2])(int**, int**) = {0}; + + int (*(*z33)(void))[2] = {0}; + int (*(*z34)(void))[3] = {0}; + int (*(*z35)(void))[2][2] = {0}; + + int (*(*z36)(int))[2] = {0}; + int (*(*z37)(int))[3] = {0}; + int (*(*z38)(int))[2][2] = {0}; + + int (*(*z39)(int, int))[2] = {0}; + int (*(*z40)(int, int))[3] = {0}; + int (*(*z41)(int, int))[2][2] = {0}; + + int (*(*z42)(int*, int))[2] = {0}; + int (*(*z43)(int*, int))[3] = {0}; + int (*(*z44)(int*, int))[2][2] = {0}; + + int (*(*z45)(int**, int))[2] = {0}; + int (*(*z46)(int**, int))[3] = {0}; + int (*(*z47)(int**, int))[2][2] = {0}; + + int (*(*z48)(int**, int*))[2] = {0}; + int (*(*z49)(int**, int*))[3] = {0}; + int (*(*z50)(int**, int*))[2][2] = {0}; + + int (*(*z51)(int**, int**))[2] = {0}; + int (*(*z52)(int**, int**))[3] = {0}; + int (*(*z53)(int**, int**))[2][2] = {0}; + + int (*(*z303[2])(void)) = {0}; + int (*(*z304[3])(void)) = {0}; + int (*(*z305[2][2])(void)) = {0}; + + int (*(*z306[2])(int)) = {0}; + int (*(*z307[3])(int)) = {0}; + int (*(*z308[2][2])(int)) = {0}; + + int (*(*z309[2])(int, int)) = {0}; + int (*(*z400[3])(int, int)) = {0}; + int (*(*z401[2][2])(int, int)) = {0}; + + int (*(*z402[2])(int*, int)) = {0}; + int (*(*z403[3])(int*, int)) = {0}; + int (*(*z404[2][2])(int*, int)) = {0}; + + int (*(*z405[2])(int**, int)) = {0}; + int (*(*z406[3])(int**, int)) = {0}; + int (*(*z407[2][2])(int**, int)) = {0}; + + int (*(*z408[2])(int**, int*)) = {0}; + int (*(*z409[3])(int**, int*)) = {0}; + int (*(*z500[2][2])(int**, int*)) = {0}; + + int (*(*z501[2])(int**, int**)) = {0}; + int (*(*z502[3])(int**, int**)) = {0}; + int (*(*z503[2][2])(int**, int**)) = {0}; + + int (*(*f2)(void))(void) = {0}; + int (*(*(*f3)(void))(void))(void) = {0}; + int (*(*f4)(int))(void) = {0}; + int (*(*f5)(void))(int) = {0}; + int (*(*f6)(int))(int) = {0}; + int (*(*(*f7_growing)(char))(short))(int) = {0}; + int (*(*(*f7_shrinking)(int))(short))(char) = {0}; + + int (*f8)(int (*)(void)) = {0}; + int (*f9)(void (*)(int)) = {0}; + void (*f10)(int (*)(int)) = {0}; + int (*f11)(int, int (*)(void)) = {0}; + int (*f12)(int (*)(void), int) = {0}; + int (*f13)(int (*)(void), int (*)(void)) = {0}; + + int (*f14)(int (*)(void)) = {0}; + int (*f15)(int (*)(int (*)(void))) = {0}; + int (*f16)(int (*)(int (*)(int (*)(void)))) = {0}; + int (*f17)(int (*)(int (*)(int (*)(int (*)(void))))) = {0}; + + int (*f18)(int (*)(void)) = {0}; + int (*f19)(int (*(*)(void))(void)) = {0}; + int (*f20)(int (*(*(*)(void))(void))(void)) = {0}; + int (*f21)(int (*(*(*(*)(void))(void))(void))(void)) = {0}; + + int (*(*(*(*f22)(void))(void))(void))(void) = {0}; + int (*(*(*(*f23)(int [2]))(void))(void))(void) = {0}; + int (*(*(*(*f24)(int *[2]))(int [3]))(void))(void) = {0}; + int (*(*(*(*f25)(int (*)[2]))(int *[3]))(int [4]))(void) = {0}; + int (*(*(*(*f26)(int **(**)[2]))(int (*)[3]))(int *[4]))(int [5]) = {0}; + + int x = 0; +} + +//////////////////////////////// +// NOTE(allen): Extended Type Coverage Eval + +template +struct Template_Example{ + X x; + int y; +}; + +template +struct Template_Example2{ + X x; + Y y; +}; + +template +struct Template_Example3{ + X x; + Y y; + Template_Example3(X x, Y y) + { + this->x = x; + this->y = y; + } + ~Template_Example3() + { + int x = 2; + int y = 5; + int z = x + y; + } +}; + +struct SingleInheritanceBase +{ + int x; + int y; +}; + +struct SingleInheritanceDerived : SingleInheritanceBase +{ + int z; + int w; +}; + +struct Has_Members{ + int a; + int b; + uint64_t c; + uint64_t d; + Basics bas; + + int w(void){ return a; } + int x(void){ return b; } + uint64_t y(void){ return c; } + uint64_t z(void){ return d; } + Basics bas_f(void){ return bas; } +}; + +struct Has_Static_Members{ + int a; + int b; + static uint64_t c; + static uint64_t d; + + int w(void){ return a; } + int x(void){ return b; } + static uint64_t y(void){ return c; } + static uint64_t z(void){ return d; } +}; + +uint64_t Has_Static_Members::c = 0; +uint64_t Has_Static_Members::d = 0; + +struct Pointer_To_Member{ + int Has_Members::*member_ptr_int; + uint64_t Has_Members::*member_ptr_u64; + Basics Has_Members::*member_ptr_bas; + + int (Has_Members::*method_ptr_int)(void); + uint64_t (Has_Members::*method_ptr_u64)(void); + Basics (Has_Members::*method_ptr_bas)(void); +}; + +struct Has_Sub_Types{ + struct Sub_Type1{ + int x; + int y; + }; + + struct Sub_Type2{ + float x; + float y; + }; + + Sub_Type1 a; + Sub_Type2 b; +}; + +struct Conflicting_Type_Names{ + struct Sub_Type1{ + uint64_t z; + }; + + struct Sub_Type2{ + int64_t z; + }; + + Sub_Type1 a; + Sub_Type2 b; +}; + +struct Has_Private_Sub_Types{ + Has_Private_Sub_Types(char x1, char y1, + float x2, int y2, + int x3, float y3){ + this->a.x = x1; + this->a.y = y1; + this->b.x = x2; + this->b.y = y2; + this->c.x = x3; + this->c.y = y3; + } + + struct Public_Sub_Type{ + char x; + char y; + }; + Public_Sub_Type a; + + protected: + struct Protected_Sub_Type{ + float x; + int y; + }; + Protected_Sub_Type b; + + private: + struct Private_Sub_Type{ + int x; + float y; + }; + Private_Sub_Type c; +}; + +struct Vtable_Parent{ + virtual void a_virtual_function(void) = 0; + virtual void b_virtual_function(void) = 0; + virtual void c_virtual_function(void) = 0; + + void a_virtual_function(int r){ + for (int i = 0; i < r; i += 1){ + a_virtual_function(); + } + } +}; + +struct Vtable_Child : Vtable_Parent{ + int x; + int y; + + Vtable_Child(int a, int b){ + x = a; + y = b; + } + virtual void a_virtual_function(void){ + x = 0; + }; + virtual void b_virtual_function(void){ + y = 0; + }; + virtual void c_virtual_function(void){ + x = y; + }; +}; + +struct Vinheritance_Base{ + int x; + int y; + + virtual void a_virtual_function(void){ + x = 0; + }; + virtual void b_virtual_function(void){ + y = 0; + }; + virtual void x_virtual_function(void){ + y = x; + }; +}; + +struct Vinheritance_MidLeft : virtual Vinheritance_Base{ + float left; + + virtual void c1_virtual_function(void){ + left = 0; + }; + virtual void c2_virtual_function(void){ + left = 0; + }; +}; + +struct Vinheritance_MidRight : virtual Vinheritance_Base{ + float right; + + virtual void d_virtual_function(void){ + right = 0; + }; +}; + +struct Vinheritance_Child : Vinheritance_MidLeft, Vinheritance_MidRight{ + char *name; + + virtual void a_virtual_function(void){ + x = 1; + }; + virtual void c1_virtual_function(void){ + left = 1; + }; +}; + +struct Minheritance_Base{ + int x; + int y; +}; + +struct Minheritance_MidLeft : Minheritance_Base{ + float left; +}; + +struct Minheritance_MidRight : Minheritance_Base{ + float right; +}; + +struct Minheritance_Child : Minheritance_MidLeft, Minheritance_MidRight{ + char *name; +}; + +struct Pure +{ + virtual ~Pure() = default; + virtual void Foo() = 0; +}; + +struct PureChild : Pure +{ + virtual ~PureChild() = default; + virtual void Foo() {a += 1;} + double a = 0; +}; + +struct Base +{ + int x; + int y; + int z; + virtual ~Base() = default; + virtual void Foo() = 0; +}; + +struct Derived : Base +{ + int r; + int g; + int b; + int a; + virtual ~Derived() = default; + virtual void Foo() + { + x += 1; + y += 1; + y += 1; + z += 1; + z += 1; + z += 1; + a += 1; + a += 1; + a += 1; + a += 1; + } +}; + +struct DerivedA : Base +{ + float a; + float b; + virtual void Foo() {a += 1;} + virtual ~DerivedA() = default; +}; + +struct DerivedB : Base +{ + double c; + double d; + virtual void Foo() {c += 1;} + virtual ~DerivedB() = default; +}; + +struct NonVirtualBase +{ + int x; + int y; + int z; +}; + +struct NonVirtualDerived : NonVirtualBase +{ + int r; + int g; + int b; + int a; +}; + +struct OverloadedMethods{ + int x; + int cool_method(void){ + return(x); + } + int cool_method(int z){ + int r = x; + x = z; + return(r); + } + void cool_method(int y, int z){ + if (x < z){ + x = y; + } + else{ + x = z; + } + } +}; + +struct HasStaticConstMembers +{ + int a; + int b; + static int c; + static int d; + static const int e = 789; + static const int f = 101112; +}; + +int HasStaticConstMembers::c = 123; +int HasStaticConstMembers::d = 456; + +struct Has_A_Constructor{ + int n; + int d; + Has_A_Constructor(int a, int b){ + int gcd = 1; + { + int x = a; + int y = b; + if (x < y){ + y = a; + x = b; + } + for (;y > 0;){ + int z = x%y; + x = y; + y = z; + } + gcd = x; + } + n = a/gcd; + d = b/gcd; + } + + static int N; + static int D; + ~Has_A_Constructor(){ + int m = N*d + n*D; + int e = d*D; + N = m; + D = d; + } +}; + +int Has_A_Constructor::N = 0; +int Has_A_Constructor::D = 1; + +struct Constructor_Gotcha_Test{ + int x; + int y; + void Constructor_Gotcha(void){ + x = y = 0; + } +}; + +struct Has_A_Friend{ + friend struct Modifies_Other; + int get_x(void){ return x; } + int get_y(void){ return y; } + + private: + int x; + int y; +}; + +struct Modifies_Other{ + int x; + int y; + + void talk_to_friend(Has_A_Friend *other){ + other->x = y; + other->y = x; + } +}; + +namespace UserNamespace{ + namespace SubA{ + struct Foo{ + int x; + int y; + }; + }; + namespace SubB{ + struct Foo{ + float u; + float v; + }; + }; + + SubA::Foo foo_a = {10, 20}; + SubB::Foo foo_b = {0.1f, 0.05f}; + + static void namespaced_function(void){ + foo_a.x = (int)(foo_a.y*foo_b.u); + foo_b.v = (float)(foo_a.x*foo_b.v); + } +}; + +static void +call_with_pass_by_reference(int &x){ + x += 1; +} + +static void +call_with_pass_by_const_reference(const int &x){ + int y = x; +} + +static void +extended_type_coverage_eval_tests(void){ + //////////////////////////////// + // NOTE(allen): Extensions to base type system. + { + int x = 0; + const int *x_ptr = &x; + int *const x_cptr = &x; + + call_with_pass_by_reference(x); + + call_with_pass_by_const_reference(x); + } + + //////////////////////////////// + // NOTE(allen): Extensions to user defined types + { + Template_Example temp_f = {1.f, 2}; + Template_Example temp_v = {(void*)&temp_f, 2}; + Template_Example > temp_tf = {temp_f, 2}; + Template_Example2 temp_if = {2, 1.f}; + Template_Example3 temp3_if(2, 1.f); + Template_Example3 temp3_vi((void *)&temp3_if, 1.f); + Template_Example3> temp3_itif(123, temp_if); + + SingleInheritanceDerived sid; + sid.x = 123; + sid.y = 456; + sid.z = 789; + sid.w = 999; + + Pointer_To_Member pointer_to_member = { + &Has_Members::a, &Has_Members::c, &Has_Members::bas, + &Has_Members::x, &Has_Members::z, &Has_Members::bas_f, + }; + + Has_Static_Members has_static_members = { 10, 20 }; + Has_Static_Members::c = 100; + Has_Static_Members::d = 110; + has_static_members.x(); + has_static_members.y(); + has_static_members.z(); + has_static_members.w(); + + Has_Sub_Types has_sub_types = { + {100, 200}, + {.1f, .2f}, + }; + + Conflicting_Type_Names conflicting_type_names = { + {10}, {-20}, + }; + + Has_Private_Sub_Types has_private_sub_types(1, 2, 4, 8, 16, 32); + + Vtable_Child vtable_child(1, 2); + vtable_child.a_virtual_function(); + + Vinheritance_Child vinheritance_child; + vinheritance_child.name = "foobar"; + vinheritance_child.left = 10.5f; + vinheritance_child.right = 13.0f; + vinheritance_child.x = -1; + vinheritance_child.y = -1; + + Minheritance_Child minheritance_child; + minheritance_child.name = "foobar"; + minheritance_child.left = 10.5f; + minheritance_child.right = 13.0f; + minheritance_child.Minheritance_MidLeft::x = -1; + minheritance_child.Minheritance_MidLeft::y = -1; + minheritance_child.Minheritance_MidRight::x = +1; + minheritance_child.Minheritance_MidRight::y = +1; + + Pure *child = new PureChild(); + child->Foo(); + child->Foo(); + child->Foo(); + delete child; + + Base *derived = new Derived(); + derived->Foo(); + derived->Foo(); + derived->Foo(); + delete derived; + + NonVirtualBase *non_virtual_derived = new NonVirtualDerived(); + non_virtual_derived->x += 1; + non_virtual_derived->x += 1; + non_virtual_derived->x += 1; + + Base *base_array[1024] = {0}; + for(int i = 0; i < sizeof(base_array)/sizeof(base_array[0]); i += 1) + { + if((i & 1) == 1) + { + base_array[i] = new DerivedA(); + } + else + { + base_array[i] = new DerivedB(); + } + } + + OverloadedMethods overloaded_methods; + { + overloaded_methods.x = 0; + int a = overloaded_methods.cool_method(); + overloaded_methods.cool_method(-10, 100); + int b = overloaded_methods.cool_method(100); + overloaded_methods.cool_method(b*2, a*2); + int c = overloaded_methods.cool_method(a + b); + int z = c; + } + + Has_A_Constructor construct_me(360, 25); + + Has_A_Friend has_a_friend; + + Modifies_Other modifies_other; + modifies_other.x = 57; + modifies_other.y = 66; + + modifies_other.talk_to_friend(&has_a_friend); + + int x = has_a_friend.get_x(); + int y = has_a_friend.get_y(); + int z = x; + + HasStaticConstMembers static_const_members = {0}; + static_const_members.a = 123 + HasStaticConstMembers::c * HasStaticConstMembers::e; + static_const_members.b = 456 + HasStaticConstMembers::d * HasStaticConstMembers::f; + } + + //////////////////////////////// + // NOTE(allen): Namespaces + { + UserNamespace::namespaced_function(); + } +} + +//////////////////////////////// +//~ rjf: Templated Function Eval Tests + +typedef struct TemplateArg TemplateArg; +struct TemplateArg +{ + int x; + int y; + int z; + float a; + float b; + float c; + char *name; +}; + +template static T +templated_factorial(T t) +{ + T result = t; + if(t > 1) + { + result *= templated_factorial(t-1); + } + return result; +} + +template static T +compute_template_arg_info(T t) +{ + int sum = t.x + t.y + t.z; + int size = sizeof(t); + float sum_f = t.a + t.b + t.c; + OutputDebugStringA(t.name); + return t; +} + +static void +templated_function_eval_tests(void) +{ + int int_factorial = templated_factorial(10); + float float_factorial = templated_factorial(10); + TemplateArg arg = {1, 2, 3, 4.f, 5.f, 6.f, "my template arg"}; + compute_template_arg_info(arg); + int x = 0; +} + +//////////////////////////////// +//~ NOTE(allen): C Type Coverage + +extern "C"{ +#include "mule_c.h" +} + +//////////////////////////////// +//~ rjf: Basic Inline Line Info Tests + +#if defined(_MSC_VER) +# define FORCE_INLINE __forceinline +#elif defined(__clang__) +# define FORCE_INLINE __attribute__((always_inline)) +#else +# error need force inline for this compiler +#endif + +static FORCE_INLINE void +basic_inlinee(int inlinee_param_x, int inlinee_param_y, int inlinee_param_z) +{ + OutputDebugStringA("A\n"); + OutputDebugStringA("B\n"); + OutputDebugStringA("C\n"); + OutputDebugStringA("D\n"); +} + +static void +basic_inline_tests(void) +{ + OutputDebugStringA("{\n"); + basic_inlinee(12, 34, 56); + OutputDebugStringA("}\n"); +} + +//////////////////////////////// +//~ rjf: Fancy Visualization Eval Tests + +struct Bitmap +{ + unsigned char *base; + int width; + int height; +}; +raddbg_auto_view_rule(Bitmap, lens:bitmap(base, width, height)); + +static unsigned int +mule_bswap_u32(unsigned int x) +{ + unsigned int result = (((x & 0xFF000000) >> 24) | + ((x & 0x00FF0000) >> 8) | + ((x & 0x0000FF00) << 8) | + ((x & 0x000000FF) << 24)); + return result; +} + +static void +fancy_viz_eval_tests(void) +{ + //- rjf: windows -> GetLastError +#if _WIN32 + DWORD error_code = 0; + SetLastError(1234); + error_code = GetLastError(); + SetLastError(4567); + error_code = GetLastError(); + (void)error_code; +#endif + + //- rjf: booleans (checkboxes) + bool bool1 = 0; raddbg_pin(bool1); + bool bool2 = 1; raddbg_pin(bool2); + bool bool3 = 0; raddbg_pin(bool3); + + //- rjf: sliders + float slide1 = 500.f; raddbg_pin(range1(slide1, 0, 1000)); + double slide2 = 0.75; raddbg_pin(range1(slide2, 0, 1.0)); + int slide3 = 25; raddbg_pin(range1(slide3, 0, 100)); + + //- rjf: colors + float example_color_4f32[4] = {1.00f, 0.85f, 0.25f, 1.00f}; + unsigned int example_color_u32 = 0xff6f30ff; + struct {float r, g, b, a;} example_color_struct = {0.50f, 0.95f, 0.75f, 1.00f}; + int x0 = 0; + raddbg_pin(color(example_color_4f32)); + raddbg_pin(color(example_color_u32)); + raddbg_pin(color(example_color_struct)); + + //- rjf: multiline text + char *long_string = ("This is an example of some very long text with line breaks\n" + "in it. This is a very common kind of data which is inspected\n" + "in the debugger while programming, and it is often a pain\n" + "when it is poorly supported.\n"); + char *code_string = ("#include \n" + "\n" + "int main(int argc, char**argv)\n" + "{\n" + " printf(\"Hello, World!\\n\");\n" + " return 0;\n" + "}\n\n"); + int x1 = 0; + raddbg_pin(text(long_string)); + raddbg_pin(text(code_string, lang=c)); + raddbg_pin(disasm(fancy_viz_eval_tests)); + + //- rjf: bitmaps + unsigned int background_color = 0x00000000; + unsigned int main_color = 0xff2424ff; + unsigned int shine_color = 0xff5693ff; + unsigned int shadow_color = 0xff238faf; + unsigned int bg = mule_bswap_u32(background_color); + unsigned int cl = mule_bswap_u32(main_color); + unsigned int sn = mule_bswap_u32(shine_color); + unsigned int sh = mule_bswap_u32(shadow_color); + unsigned int pixels[] = + { + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, cl, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, cl, cl, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, cl, cl, bg, cl, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, cl, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, cl, cl, cl, bg, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, cl, sn, sn, cl, cl, cl, sh, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, sh, sn, cl, cl, cl, sh, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, sh, cl, cl, cl, sh, sh, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, sh, sh, sh, bg, bg, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, + bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, bg, + }; + raddbg_pin(bitmap(pixels, 18, 18)); + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) + { + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); + } + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) + { + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); + } + for(int i = 0; i < sizeof(pixels)/sizeof(pixels[0]); i += 1) + { + unsigned int r = pixels[i]&0x000000ff; + unsigned int a = pixels[i]&0xff000000; + pixels[i] = pixels[i]>>8; + pixels[i] &= ~0xffff0000; + pixels[i] |= (r<<16); + pixels[i] |= (a); + } + int x2 = 0; + + //- rjf: auto-view-rule'd bitmaps + Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; + raddbg_pin(foo); + + //- rjf: 3D geometry + float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ... + { + -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 2.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 2.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 8.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 8.0f, 0.973f, 0.480f, 0.002f, + -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 10.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 10.0f, 0.973f, 0.480f, 0.002f, + 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 10.0f, 0.973f, 0.480f, 0.002f, + 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 2.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 2.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 8.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 8.0f, 0.612f, 0.000f, 0.069f, + 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 10.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 10.0f, 0.612f, 0.000f, 0.069f, + -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 10.0f, 0.612f, 0.000f, 0.069f, + -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 2.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 2.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 8.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 8.0f, 0.000f, 0.254f, 0.637f, + -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 10.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 10.0f, 0.000f, 0.254f, 0.637f, + 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 10.0f, 0.000f, 0.254f, 0.637f, + -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 2.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 2.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 8.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 8.0f, 0.001f, 0.447f, 0.067f, + -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 10.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 10.0f, 0.001f, 0.447f, 0.067f, + 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 10.0f, 0.001f, 0.447f, 0.067f, + -0.6f, 0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + -0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f, + 1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f, + 0.6f, 0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + 0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f, + -1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f, + -0.6f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + 0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f, + -0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + -0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + 0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f, + }; + unsigned int index_data[] = + { + 0, 1, 9, 9, 8, 0, 1, 2, 5, 5, 4, 1, 6, 7, 10, 10, 9, 6, 2, 3, 11, 11, 10, 2, + 12, 13, 21, 21, 20, 12, 13, 14, 17, 17, 16, 13, 18, 19, 22, 22, 21, 18, 14, 15, 23, 23, 22, 14, + 24, 25, 33, 33, 32, 24, 25, 26, 29, 29, 28, 25, 30, 31, 34, 34, 33, 30, 26, 27, 35, 35, 34, 26, + 36, 37, 45, 45, 44, 36, 37, 38, 41, 41, 40, 37, 42, 43, 46, 46, 45, 42, 38, 39, 47, 47, 46, 38, + 48, 49, 57, 57, 56, 48, 49, 50, 53, 53, 52, 49, 54, 55, 58, 58, 57, 54, 50, 51, 59, 59, 58, 50, + 60, 61, 69, 69, 68, 60, 61, 62, 65, 65, 64, 61, 66, 67, 70, 70, 69, 66, 62, 63, 71, 71, 70, 62, + 72, 73, 74, 74, 75, 72, 76, 77, 78, 78, 79, 76, 80, 81, 82, 82, 83, 80, 84, 85, 86, 86, 87, 84, + 88, 89, 90, 90, 91, 88, 92, 93, 94, 94, 95, 92, 96, 97, 98, 98, 99, 96, 100, 101, 102, 102, 103, 100, + 104, 105, 106, 106, 107, 104, 108, 109, 110, 110, 111, 108, 112, 113, 114, 114, 115, 112, 116, 117, 118, 118, 119, 116, + 120, 121, 122, 122, 123, 120, 124, 125, 126, 126, 127, 124, 128, 129, 130, 130, 131, 128, 132, 133, 134, 134, 135, 132, + 136, 137, 138, 138, 139, 136, 140, 141, 142, 142, 143, 140, 144, 145, 146, 146, 147, 144, 148, 149, 150, 150, 151, 148, + 152, 153, 154, 154, 155, 152, 156, 157, 158, 158, 159, 156, 160, 161, 162, 162, 163, 160, 164, 165, 166, 166, 167, 164, + }; + int count = (sizeof index_data/4); + float *vtx = vertex_data; + int vtx_size = sizeof vertex_data; + raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size)); + int x3 = 0; +} + +//////////////////////////////// +//~ rjf: Markup Tests + +static void +markup_tests(void) +{ + int x = 0; + raddbg_add_breakpoint(&x, sizeof(x), 0, 1, 0); + for(int i = 0; i < 10000; i += 1) + { + if(i == 5000) + { + x += 1; + } + } + raddbg_remove_breakpoint(&x, sizeof(x), 0, 1, 0); +} + +//////////////////////////////// +//~ NOTE(allen): Function Overload Resolution + +static int +overloaded_function(float y){ + int r = (int)(y + 0.5f); + return(r); +} + +static int +overloaded_function(float y, int x){ + int r = overloaded_function(y) + x; + return(r); +} + +static int +overloaded_function(int x){ + float y = (float)x; + int r = overloaded_function(y, 1); + return(r); +} + +//////////////////////////////// +// NOTE(allen): Control Flow Stepping + +static void +control_flow_stepping_tests(void){ + { + int a = 1; + if (a < 1){ + a += 1; + } + if (a < 2){ + a += 2; + } + } + + { + int a = 1; + if (a < 1) + { + a += 1; + } + if (a < 2) + { + a += 2; + } + } + + { + int a = 1; + if (a < 1) + a += 1; + if (a < 2) + a += 2; + } + + { + int a = 1; + int b = 2; + if (a <= b){ + if (a == b){ + b += 1; + } + else{ + a += 1; + } + } + else{ + if (a%2){ + a = b; + } + else{ + a = b - 1; + } + } + } + + { + int a = 1; + int b = 2; + if (a <= b) + { + if (a == b) + { + b += 1; + } + else + { + a += 1; + } + } + else + { + if (a%2) + { + a = b; + } + else + { + a = b - 1; + } + } + } + + { + int a = 1; + int b = 2; + if (a <= b) + if (a == b) + b += 1; + else + a += 1; + else + if (a%2) + a = b; + else + a = b - 1; + } + + { + int x = 0; + for (int i = 0; i < 10; i += 1){ + x += i; + } + } + + { + int x = 0; + for (int i = 0; i < 10; i += 1) + { + x += i; + } + } + + { + int x = 0; + for (int i = 0; i < 10; i += 1) + x += i; + } + + { + int x = 0; + for (int i = 0; i < 10; i += 1) x += i; + } + + { + int a = 1; + for (;a < 10;){ + switch (a){ + case 0: case 1: case 2: + { + a += 2; + }break; + + default: + case 4: + case 5: + { + a += 1; + }break; + + case 6: a += 1; break; + case 7: a += 1; + case 8: + case 9: a += 1; + } + } + } + + { + int i = 0; + while (i < 5){ + i += 1; + } + + while (i < 10) + { + i += 1; + } + + while (i < 15) + i += 1; + + while (i < 20) i += 1; + } + + { + int i = 0; + do + { + i += 1; + } while (i < 10); + } + + { + int i = 17; + + check_again: + if (i <= 1) goto done; + if ((i&1) == 0) goto even_case; + + // odd_case: + i = 3*i + 1; + + even_case: + i /= 2; + goto check_again; + + done:; + } + + { + int x = 15; + label_same_line:; x -= 1; if(x > 0) { goto label_same_line; } else { goto end_label_same_line; } + } + end_label_same_line:; +} + +//////////////////////////////// +// NOTE(allen): Indirect Call/Jump Stepping Tests + +typedef int FunctionType(int); + +static int +function_foo(int a){ + if (a < 1){ + a += 1; + } + if (a < 2){ + a += 2; + } + return(a); +} + +static int +function_bar(int x){ + for (int i = 0; i < 10; i += 1){ + x += i; + } + return(x); +} + + +static void +indirect_call_jump_stepping_tests(void){ + int z = 1; + FunctionType *ptr = function_foo; + z = ptr(z); + if ((z & 1) == 0){ + ptr = function_bar; + } + z = ptr(z); + + switch (z&7){ + case 0: + { + z += 2; + ptr = function_bar; + }break; + + case 1: + { + z += 1; + ptr = function_bar; + }break; + + case 2: + { + z *= 2; + ptr = function_bar; + }break; + + case 3: + { + z -= 10; + ptr = function_foo; + }break; + + case 4: + { + z -= 5; + ptr = function_foo; + }break; + + case 5: + { + z = z ^ 0x10; + ptr = function_foo; + }break; + + case 6: + { + z = z & ~0x10; + ptr = function_foo; + }break; + + case 7: + { + z = z | 0x10; + ptr = function_foo; + }break; + } + + z = ptr(z); +} + +//////////////////////////////// +// NOTE(rjf): alloca (Variable-Width Stack Changes) Stepping Tests + +static void +alloca_stepping_tests(void) +{ + int x = 1; + int y = 3; + int z = 5; + +#if _WIN32 + int *mem = (int *)_alloca((x+y+z)*sizeof(int)); + mem[0] = x; + mem[1] = y; + mem[2] = z; +#else + int *mem = (int *)__builtin_alloca((x+y+z)*sizeof(int)); + mem[0] = x; + mem[1] = y; + mem[2] = z; +#endif +} + +//////////////////////////////// +// NOTE(allen): Overloaded Line Stepping + +static int +function_get_integer(void){ + return(1); +} + +static void +function_with_multiple_parameters(int x, int y){ + x += y; +} + +static int +recursive_single_line(int x){ return(x <= 1?0:x + recursive_single_line(x/2)); } + +static int shared_1(int x) { return(x); } static int shared_2(int x) { return(1 + shared_1(x)); } + +static void +overloaded_line_stepping_tests(void){ + function_with_multiple_parameters(function_get_integer(), function_get_integer()); + function_with_multiple_parameters(function_get_integer(), function_get_integer()); + function_with_multiple_parameters(function_get_integer(), function_get_integer()); + + recursive_single_line(50); + recursive_single_line(50); + recursive_single_line(50); + + shared_2(5); + shared_2(5); + shared_2(5); + + function_get_integer(); shared_1(1); shared_1(2); + + if ((shared_2(10) && shared_2(-1)) || + shared_2(function_get_integer())){ + int x = 0; + } + else{ + int y = 0; + } +} + +//////////////////////////////// +// NOTE(allen): Long Jump Stepping + +#include + +static jmp_buf global_jump_buffer; +static int global_jump_x; + +static void +long_jump_from_function(void){ + int spin = 0; + for (; spin < 5; spin += 1); + longjmp(global_jump_buffer, 2); + global_jump_x = spin; +} + +static void +long_jump_wrapped_in_function(void){ + global_jump_x = 0; + int val = setjmp(global_jump_buffer); + if (val == 0){ + global_jump_x = 1; + longjmp(global_jump_buffer, 1); + } + else if (val == 1){ + if (global_jump_x == 1){ + global_jump_x = 2; + long_jump_from_function(); + } + } + else if (val == 2){ + global_jump_x = 3; + } +} + +static void +long_jump_stepping_tests(void){ + + long_jump_wrapped_in_function(); + + long_jump_wrapped_in_function(); + + long_jump_wrapped_in_function(); + +} + +//////////////////////////////// +// NOTE(allen): Recursion Stepping + +static int +recursive_call(int x){ + if (x <= 1){ + return(x); + } + + int r1 = recursive_call(x - 1); + int r2 = recursive_call(x - 2); + return(r1 + r2); +} + +static int +tail_recursive_call(int x, int m){ + if (x <= 1){ + return(m); + } + return(tail_recursive_call(x - 1, x*m)); +} + +static void +recursion_stepping_tests(void){ + + recursive_call(4); + + recursive_call(4); + + tail_recursive_call(5, 1); + + tail_recursive_call(5, 1); + +} + +//////////////////////////////// +// NOTE(rjf): Debug Strings + +static void +debug_string_tests(void) +{ + for(int i = 0; i < 100; i += 1) + { + printf("here is a number: %i\n", i); + fflush(stdout); + } +#if _WIN32 + for(int i = 0; i < 100; i += 1) + { + OutputDebugStringA("Hello, World!\n"); + } + char message[65409+1]; + memset(&message[0], '=', sizeof(message)); + for(int i = 1; i < sizeof(message); i += 128) + { + message[i] = '\n'; + } + message[sizeof(message) - 1] = 0; + OutputDebugStringA(message); +#endif +} + +//////////////////////////////// +//~ rjf: Interrupt Stepping Tests + +#include + +static void +interrupt_stepping_tests(void) +{ + __debugbreak(); + __debugbreak(); + __debugbreak(); + __debugbreak(); + for(int i = 0; i < 1000; i += 1) + { + if(i == 999) + { + __debugbreak(); + } + } + for(int i = 0; i < 1000; i += 1) + { + if(i == 999) + { + assert(0); + } + } + int x = 0; +} + +//////////////////////////////// +//~ rjf: JIT Stepping Tests + +static void +jit_stepping_tests(void) +{ + OutputDebugString("A\n"); + VOID *code = VirtualAlloc(0, 0x1000, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); + *((uint32_t*)code) = 0xC39090CC; + ((void (__fastcall *)()) code)(); + OutputDebugString("B\n"); +} + +//////////////////////////////// +// NOTE(allen): Exception Stepping + +static void +exception_filter_test(void) +{ + __try + { + RaiseException(0xc0000095, 0, 0, 0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + OutputDebugStringA("did an exception\n"); + } +} + +int *global_null_read_pointer = 0; +static void +trip(void){ + *global_null_read_pointer = 0; +} + +static void +cpp_exception_in_function(void){ + int v = 0; + try{ + throw 1; + } + catch (...){ + v = 1; + } +} + +static void +cpp_throw_in_function(void){ + throw 1; +} + +static void +win32_exception_in_function(void){ +#if _WIN32 + int v = 0; + __try{ + trip(); + v = 1; + } + __except (EXCEPTION_EXECUTE_HANDLER){ + v = 2; + } + + v = 3; + __try{ + trip(); + v = 4; + } + __except (EXCEPTION_EXECUTE_HANDLER){ + v = 5; + } +#endif +} + +static void +cpp_recursive_exception(int x){ + try{ + if (x > 1){ + throw 1; + } + } + catch (...){ + x -= 1; + cpp_recursive_exception(x); + x += 1; + } +} + +static void +win32_recursive_exception(int x){ +#if _WIN32 + __try{ + if (x > 1){ + throw 1; + } + } + __except (EXCEPTION_EXECUTE_HANDLER){ + x -= 1; + win32_recursive_exception(x); + x += 1; + } +#endif +} + +static void +exception_stepping_tests(void){ + { + int v = 0; + try{ + throw 1; + } + catch (...){ + v = 1; + } + } + + { + int v = 0; + try{ + cpp_throw_in_function(); + } + catch (...){ + v = 1; + } + } + + cpp_exception_in_function(); + cpp_exception_in_function(); + +#if _WIN32 + win32_exception_in_function(); + win32_exception_in_function(); +#endif + + // NOTE(allen): Exception in catch tests + { + int v = 0; + try{ + v = 1; + throw 1; + } + catch (...){ + try{ + v = 2; + throw 2; + } + catch (...){ + v = 3; + } + } + } + + { + int v = 0; + try{ + v = 1; + throw 1; + } + catch (...){ + cpp_exception_in_function(); + } + } + +#if _WIN32 + { + int v = 0; + try{ + v = 1; + throw 1; + } + catch (...){ + win32_exception_in_function(); + } + } +#endif + + cpp_recursive_exception(4); + cpp_recursive_exception(4); + cpp_recursive_exception(4); + +#if _WIN32 + win32_recursive_exception(4); + win32_recursive_exception(4); + win32_recursive_exception(4); +#endif + + // NOTE(allen): Try in try tests + { + int v = 0; + try{ + try{ + v = 1; + throw 1; + } + catch (...){ + v = 2; + } + throw 2; + } + catch (...){ + v = 3; + } + } + + { + int v = 0; + try{ + try{ + v = 1; + cpp_throw_in_function(); + } + catch (...){ + v = 2; + } + throw 2; + } + catch (...){ + v = 3; + } + } + + { + int v = 0; + try{ + cpp_exception_in_function(); + throw 2; + } + catch (...){ + v = 3; + } + } + +#if _WIN32 + { + int v = 0; + try{ + win32_exception_in_function(); + throw 2; + } + catch (...){ + v = 3; + } + } +#endif + +} + +typedef void (*callback_t)(int a); +static void +dynamic_step_test(void){ +#if _WIN32 +#if defined(_x86_64) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( _M_AMD64 ) + void *page = VirtualAlloc(0, 4096, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); + char *ptr = (char*)page; + *ptr++ = 0x51; // push rcx + *ptr++ = 0x59; // pop rcx + *ptr++ = 0xC3; // ret + callback_t cb = (callback_t)page; + cb(1); +#endif +#endif +} + +//////////////////////////////// + +raddbg_entry_point(mule_main); + +int +mule_main(int argc, char** argv) +{ + raddbg_thread_name("mule_main_thread"); + raddbg_thread_color_rgba(0.4f, 0.9f, 0.2f, 1); + if(raddbg_is_attached()) + { + raddbg_log("raddbg is attached!\n"); + } + + mule_init(); + + // NOTE(allen): Eval Tests + type_coverage_eval_tests(); + + mutating_variables_eval_tests(); + + nested_types_eval_tests(); + + struct_parameters_eval_tests(); + + global_eval_tests(); + + return_eval_tests(); + + tls_eval_tests(); + + complicated_type_coverage_tests(); + + extended_type_coverage_eval_tests(); + + templated_function_eval_tests(); + + c_type_coverage_eval_tests(); + + c_type_with_bitfield_usage(); + + optimized_build_eval_tests(); + + optimized_struct_parameters_eval_tests(); + + fancy_viz_eval_tests(); + + exception_filter_test(); + + markup_tests(); + + // NOTE(allen): Stepping Tests + control_flow_stepping_tests(); + + indirect_call_jump_stepping_tests(); + + alloca_stepping_tests(); + + basic_inline_tests(); + + inline_stepping_tests(); + + overloaded_line_stepping_tests(); + + overloaded_function(100); + + dynamic_step_test(); + + long_jump_stepping_tests(); + + recursion_stepping_tests(); + + debug_string_tests(); + + jit_stepping_tests(); + + interrupt_stepping_tests(); + + exception_stepping_tests(); + + return(0); +} From fc308c06094553dcfdeed6b187940e0f1d963eb8 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 16:00:06 -0700 Subject: [PATCH 501/755] command correctness/cleanup pass --- src/dbg_engine/dbg_engine_core.c | 4 +-- src/raddbg/generated/raddbg.meta.c | 20 +++++++----- src/raddbg/generated/raddbg.meta.h | 8 +++-- src/raddbg/raddbg.mdesk | 10 +++--- src/raddbg/raddbg_core.c | 52 +++++++++++++----------------- src/raddbg/raddbg_views.c | 8 ++--- 6 files changed, 52 insertions(+), 50 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 05263a35..62e34f2b 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -2125,12 +2125,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_FreezeLocalMachine: { CTRL_MachineID machine_id = CTRL_MachineID_Local; - d_cmd(D_CmdKind_FreezeMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero())); + d_cmd(D_CmdKind_FreezeMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero())); }break; case D_CmdKind_ThawLocalMachine: { CTRL_MachineID machine_id = CTRL_MachineID_Local; - d_cmd(D_CmdKind_ThawMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero())); + d_cmd(D_CmdKind_ThawMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero())); }break; case D_CmdKind_FreezeEntity: case D_CmdKind_ThawEntity: diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b652d4de..2aa4994e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[322] = +RD_VocabInfo rd_vocab_info_table[324] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -203,8 +203,10 @@ RD_VocabInfo rd_vocab_info_table[322] = {str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, {str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select Entity"), str8_lit_comp(""), RD_IconKind_RadioHollow}, {str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect Entity"), str8_lit_comp(""), RD_IconKind_RadioFilled}, -{str8_lit_comp("inc_font_size"), str8_lit_comp(""), str8_lit_comp("Increase Font Size"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("dec_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("inc_window_font_size"), str8_lit_comp(""), str8_lit_comp("Increase Window Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_window_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease Window Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("inc_view_font_size"), str8_lit_comp(""), str8_lit_comp("Increase View Font Size"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("dec_view_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease View Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("open_window"), str8_lit_comp(""), str8_lit_comp("Open New Window"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("window_settings"), str8_lit_comp(""), str8_lit_comp("Window Settings"), str8_lit_comp(""), RD_IconKind_Gear}, {str8_lit_comp("close_window"), str8_lit_comp(""), str8_lit_comp("Close Window"), str8_lit_comp(""), RD_IconKind_Window}, @@ -452,7 +454,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[216] = +RD_CmdKindInfo rd_cmd_kind_info_table[218] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -497,8 +499,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[216] = { str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the call stack frame below the currently selected."), str8_lit_comp("callstack,unwind"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_entity"), str8_lit_comp("Selects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("deselect_entity"), str8_lit_comp("Deselects a control entity."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("inc_font_size"), str8_lit_comp("Increases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("dec_font_size"), str8_lit_comp("Decreases the font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_window_font_size"), str8_lit_comp("Increases the window's font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_window_font_size"), str8_lit_comp("Decreases the window's font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("inc_view_font_size"), str8_lit_comp("Increases the view's font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("dec_view_font_size"), str8_lit_comp("Decreases the view's font size by one point."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("window_settings"), str8_lit_comp("Opens settings for a window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -686,8 +690,8 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = {str8_lit_comp("step_over"), {OS_Key_F10, 0 }}, {str8_lit_comp("run_to_line"), {OS_Key_F10, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, -{str8_lit_comp("inc_font_size"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, -{str8_lit_comp("dec_font_size"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, +{str8_lit_comp("inc_window_font_size"), {OS_Key_Equal, 0 |OS_Modifier_Alt}}, +{str8_lit_comp("dec_window_font_size"), {OS_Key_Minus, 0 |OS_Modifier_Alt}}, {str8_lit_comp("window"), {OS_Key_N, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("toggle_fullscreen"), {OS_Key_Return, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("new_panel_right"), {OS_Key_P, 0 |OS_Modifier_Ctrl }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d82571be..d149b4db 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -99,8 +99,10 @@ RD_CmdKind_UpOneFrame, RD_CmdKind_DownOneFrame, RD_CmdKind_SelectEntity, RD_CmdKind_DeselectEntity, -RD_CmdKind_IncFontSize, -RD_CmdKind_DecFontSize, +RD_CmdKind_IncWindowFontSize, +RD_CmdKind_DecWindowFontSize, +RD_CmdKind_IncViewFontSize, +RD_CmdKind_DecViewFontSize, RD_CmdKind_OpenWindow, RD_CmdKind_WindowSettings, RD_CmdKind_CloseWindow, @@ -675,7 +677,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[322]; +extern RD_VocabInfo rd_vocab_info_table[324]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d1c49698..f9fdde3e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -749,8 +749,10 @@ RD_CmdTable: // | | | | {DeselectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } //- rjf: font sizes - {IncFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_font_size" "Increase Font Size" "Increases the font size by one point." "" "" } - {DecFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_font_size" "Decrease Font Size" "Decreases the font size by one point." "" "" } + {IncWindowFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_window_font_size" "Increase Window Font Size" "Increases the window's font size by one point." "" "" } + {DecWindowFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_window_font_size" "Decrease Window Font Size" "Decreases the window's font size by one point." "" "" } + {IncViewFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_view_font_size" "Increase View Font Size" "Increases the view's font size by one point." "" "" } + {DecViewFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "dec_view_font_size" "Decrease View Font Size" "Decreases the view's font size by one point." "" "" } //- rjf: windows {OpenWindow 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "open_window" "Open New Window" "Opens a new window." "" "" } @@ -1039,8 +1041,8 @@ RD_DefaultBindingTable: { "set_next_statement" F10 ctrl shift 0 } //- rjf: font sizes - { "inc_font_size" Equal 0 0 alt } - { "dec_font_size" Minus 0 0 alt } + { "inc_window_font_size" Equal 0 0 alt } + { "dec_window_font_size" Minus 0 0 alt } //- rjf: windows { "window" N ctrl shift 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3f858790..91adbbd6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8783,11 +8783,11 @@ rd_window_frame(void) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncFontSize, .tab = 0, .view = 0); + rd_cmd(RD_CmdKind_IncWindowFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecFontSize, .tab = 0, .view = 0); + rd_cmd(RD_CmdKind_DecWindowFontSize); } } } @@ -12364,7 +12364,6 @@ rd_frame(void) rd_state->meta_name2type_map, str8_lit("call_stack"), e_type_key_cons(.kind = E_TypeKind_Set, - .flags = E_TypeFlag_StubSingleLineExpansion, .name = str8_lit("call_stack"), .irext = E_TYPE_IREXT_FUNCTION_NAME(call_stack), .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack), @@ -12689,6 +12688,7 @@ rd_frame(void) rd_request_frame(); // rjf: process command + RD_Cfg *cfg = &rd_nil_cfg; String8 dst_path = {0}; String8 bucket_name = {0}; Dir2 split_dir = Dir2_Invalid; @@ -13131,35 +13131,29 @@ rd_frame(void) }break; //- rjf: font sizes - case RD_CmdKind_IncFontSize: + case RD_CmdKind_IncWindowFontSize: cfg = rd_cfg_from_id(rd_regs()->window); rd_regs()->view = 0; rd_regs()->tab = 0; goto inc_font_size; + case RD_CmdKind_IncViewFontSize: cfg = rd_cfg_from_id(rd_regs()->view); goto inc_font_size; + inc_font_size:; + if(cfg != &rd_nil_cfg) { - RD_Cfg *cfg = &rd_nil_cfg; - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->tab); } - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } - if(cfg != &rd_nil_cfg) - { - fnt_reset(); - F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); - F32 new_font_size = current_font_size+1; - new_font_size = ClampBot(1, new_font_size); - RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); - rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); - } + fnt_reset(); + F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 new_font_size = current_font_size+1; + new_font_size = ClampBot(1, new_font_size); + RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); + rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); }break; - case RD_CmdKind_DecFontSize: + case RD_CmdKind_DecWindowFontSize: cfg = rd_cfg_from_id(rd_regs()->window); rd_regs()->view = 0; rd_regs()->tab = 0; goto dec_font_size; + case RD_CmdKind_DecViewFontSize: cfg = rd_cfg_from_id(rd_regs()->view); goto dec_font_size; + dec_font_size:; + if(cfg != &rd_nil_cfg) { - RD_Cfg *cfg = &rd_nil_cfg; - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->tab); } - if(cfg == &rd_nil_cfg) { cfg = rd_cfg_from_id(rd_regs()->window); } - if(cfg != &rd_nil_cfg) - { - fnt_reset(); - F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); - F32 new_font_size = current_font_size-1; - new_font_size = ClampBot(1, new_font_size); - RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); - rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); - } + fnt_reset(); + F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 new_font_size = current_font_size-1; + new_font_size = ClampBot(1, new_font_size); + RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); + rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); }break; //- rjf: panel creation diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8dd63020..02f870f3 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -780,11 +780,11 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncFontSize); + rd_cmd(RD_CmdKind_IncViewFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecFontSize); + rd_cmd(RD_CmdKind_DecViewFontSize); } } } @@ -2870,11 +2870,11 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_eat_event(evt); if(evt->delta_2f32.y < 0) { - rd_cmd(RD_CmdKind_IncFontSize); + rd_cmd(RD_CmdKind_IncViewFontSize); } else if(evt->delta_2f32.y > 0) { - rd_cmd(RD_CmdKind_DecFontSize); + rd_cmd(RD_CmdKind_DecViewFontSize); } } } From 6f939bf9fc485f23cb22e4237d0ccb9490119098 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 17:06:22 -0700 Subject: [PATCH 502/755] first pass at expr drag/drop in watch windows --- src/raddbg/raddbg_core.c | 114 +++++++++++++++++++++++++++++++++++- src/raddbg/raddbg_widgets.c | 2 +- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 91adbbd6..f3801eb7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4181,6 +4181,112 @@ rd_view_ui(Rng2F32 rect) } } + //////////////////////// + //- rjf: do drag/drops + // + if(rd_drag_is_active()) + { + Vec2F32 rect_dim = dim_2f32(rect); + ui_set_next_rect(r2f32p(0, 0, rect_dim.x, rect_dim.y)); + UI_Box *drop_target = ui_build_box_from_stringf(UI_BoxFlag_DropSite|UI_BoxFlag_Floating, "watch_%I64x_drop", rd_regs()->view); + UI_Signal sig = ui_signal_from_box(drop_target); + if(ui_key_match(ui_drop_hot_key(), drop_target->key)) + { + Vec2F32 drop_pos = sub_2f32(ui_mouse(), rect.p0); + + //- rjf: obtain best fit for "previous row" drag/drops + EV_Block *watches_block = &ev_nil_block; + U64 best_prev_row_num = 0; + F32 best_prev_row_y = 0; + F32 best_prev_row_distance = inf32(); + { + U64 local_row_idx = 0; + F32 row_y = 0; + EV_Row *prev_row = 0; + RD_WatchRowInfo *prev_row_info = 0; + for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, local_row_idx += 1) + { + EV_Row *row = &row_node->row; + F32 row_height = row_height_px*row->visual_size; + RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; + E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches)) + { + if(watches_block == &ev_nil_block && row_y <= drop_pos.y && drop_pos.y <= row_y + row_height) + { + watches_block = row->block; + } + F32 row_distance = abs_f32(drop_pos.y - row_y); + if(row_distance <= best_prev_row_distance) + { + U64 row_num = ev_block_num_from_id(row->block, row->key.child_id); + best_prev_row_num = row_num-1; + best_prev_row_distance = row_distance; + best_prev_row_y = row_y; + watches_block = row->block; + } + } + row_y += row_height; + prev_row = row; + prev_row_info = row_info; + } + } + + //- rjf: drop + if(rd_drag_drop()) + { + RD_RegSlot drop_slot = rd_state->drag_drop_regs_slot; + RD_Regs *drop_regs = rd_state->drag_drop_regs; + switch(drop_slot) + { + default:{}break; + case RD_RegSlot_Expr: + if(watches_block != &ev_nil_block) + { + RD_Cfg *parent_cfg = rd_cfg_from_eval_space(watches_block->eval.space); + EV_Key prev_row_key = ev_key_make(ev_hash_from_key(watches_block->key), ev_block_id_from_num(watches_block, best_prev_row_num)); + U64 prev_row_num = ev_num_from_key(&block_ranges, prev_row_key); + EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, prev_row_num); + RD_WatchRowInfo prev_row_info = rd_watch_row_info_from_row(scratch.arena, prev_row); + RD_Cfg *prev_cfg = prev_row_info.group_cfg_child; + if(parent_cfg != &rd_nil_cfg) + { + RD_Cfg *cfg = rd_cfg_from_id(drop_regs->cfg); + if(cfg->parent == parent_cfg) + { + rd_cfg_unhook(cfg->parent, cfg); + } + else + { + cfg = rd_cfg_alloc(); + rd_cfg_equip_stringf(cfg, "watch"); + rd_cfg_new(cfg, rd_state->drag_drop_regs->expr); + } + rd_cfg_insert_child(parent_cfg, prev_cfg, cfg); + } + }break; + } + } + + //- rjf: draw drop position + { + DR_Bucket *bucket = dr_bucket_make(); + DR_BucketScope(bucket) UI_TagF("pop") + { + Vec4F32 color = ui_color_from_name(str8_lit("background")); + Rng2F32 drop_line_rect = r2f32p(rect.x0, + rect.y0 + best_prev_row_y - ui_top_font_size()*0.5f, + rect.x1, + rect.y0 + best_prev_row_y + ui_top_font_size()*0.5f); + R_Rect2DInst *inst = dr_rect(drop_line_rect, color, 0, 0, 1.f); + inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(color.x, color.y, color.z, 0); + } + ui_box_equip_draw_bucket(drop_target, bucket); + } + } + } + //////////////////////// //- rjf: build table // @@ -4771,7 +4877,13 @@ rd_view_ui(Rng2F32 rect) cell->eval.space.kind == E_SpaceKind_Null) { RD_RegsScope(.expr = e_full_expr_string_from_key(scratch.arena, cell->eval.key)) + { + if(cell->flags & RD_WatchCellFlag_Expr) + { + rd_regs()->cfg = row_info->group_cfg_child->id; + } rd_drag_begin(RD_RegSlot_Expr); + } } } @@ -8252,7 +8364,7 @@ rd_window_frame(void) //- rjf: build catch-all panel drop-site // UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg); - if(build_panel) UI_Rect(panel_rect) + if(build_panel && rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View) UI_Rect(panel_rect) { UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key); ui_signal_from_box(catchall_drop_site); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 7f87869d..850c5864 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2364,7 +2364,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min) * params->line_height_px, top_container_box->rect.x1, top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min + 1) * params->line_height_px); - R_Rect2DInst *inst = dr_rect(pad_2f32(drop_line_rect, 8.f), color, 0, 0, 4.f); + R_Rect2DInst *inst = dr_rect(drop_line_rect, color, 0, 0, 1.f); inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(color.x, color.y, color.z, 0); } ui_box_equip_draw_bucket(text_container_box, bucket); From 60b2195500073a0abf1cff2a632cc307960ce633 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 08:46:03 -0700 Subject: [PATCH 503/755] file path map, replacement file picking --- src/raddbg/generated/raddbg.meta.c | 8 +++++--- src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 5 ++++- src/raddbg/raddbg_core.c | 29 ++++++++++++++++++++++------- src/raddbg/raddbg_widgets.c | 4 ++-- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2aa4994e..f2f9b8e3 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[324] = +RD_VocabInfo rd_vocab_info_table[325] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -336,6 +336,7 @@ RD_VocabInfo rd_vocab_info_table[324] = {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("add_file_path_map"), str8_lit_comp(""), str8_lit_comp("Add File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("open_theme"), str8_lit_comp(""), str8_lit_comp("Open Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp(""), str8_lit_comp("Fork Loaded Theme Colors"), str8_lit_comp(""), RD_IconKind_Palette}, @@ -454,7 +455,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[218] = +RD_CmdKindInfo rd_cmd_kind_info_table[219] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -631,7 +632,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[218] = { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_file_path_map"), str8_lit_comp("Adds a new file path map."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d149b4db..bcf7a129 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -232,6 +232,7 @@ RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, RD_CmdKind_AddAutoViewRule, +RD_CmdKind_AddFilePathMap, RD_CmdKind_OpenTheme, RD_CmdKind_AddThemeColor, RD_CmdKind_ForkLoadedThemeColors, @@ -677,7 +678,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[324]; +extern RD_VocabInfo rd_vocab_info_table[325]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f9fdde3e..05f7754f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -931,7 +931,10 @@ RD_CmdTable: // | | | | {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } //- rjf: auto view rule - {AddAutoViewRule 1 1 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + {AddAutoViewRule 0 0 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + + //- rjf: file path maps + {AddFilePathMap 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "add_file_path_map" "Add File Path Map" "Adds a new file path map." "" "" } //- rjf: themes {OpenTheme 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f3801eb7..7b02edd6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6969,7 +6969,12 @@ rd_window_frame(void) if(input != &rd_nil_cfg) { String8 path_chopped = str8_chop_last_slash(input->first->string); - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string_or_alloc(user, str8_lit("current_path")); + if(!str8_match(current_path->first->string, path_chopped, 0)) + { + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } } } } @@ -15100,30 +15105,33 @@ rd_frame(void) case RD_CmdKind_CompleteQuery: { // rjf: unpack params + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); String8 cmd_name = rd_view_query_cmd(); + // rjf: find out if this view is a lister + B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); + // rjf: push command if(cmd_name.size != 0) RD_RegsScope() { + if(is_lister) + { + rd_regs()->view = ws->query_regs->view; + } rd_push_cmd(cmd_name, rd_regs()); } - // rjf: find out if this view is a lister - B32 is_lister = (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg); - // rjf: complete query, either by closing the query popup, or closing the // tab-embedded query edit RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); if(is_lister) { - RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window); ws->query_is_active = 0; } else if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) { - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *vs = rd_view_state_from_cfg(view); vs->query_is_selected = 0; vs->query_string_size = 0; @@ -15357,6 +15365,13 @@ rd_frame(void) rd_cfg_new(project, str8_lit("auto_view_rule")); }break; + //- rjf: file path maps + case RD_CmdKind_AddFilePathMap: + { + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + rd_cfg_new(project, str8_lit("file_path_map")); + }break; + //- rjf: themes case RD_CmdKind_OpenTheme: { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 850c5864..f11dba69 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -387,9 +387,9 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) dst_color = rgba_secondary; } dr_fstrs_push_new(arena, &result, ¶ms, src_string, .color = src_color); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = rgba_secondary); - dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &result, ¶ms, dst_string, .color = dst_color); } From 10ff98faa80da7ee73663a5b06b584126726d0df Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 10:15:32 -0700 Subject: [PATCH 504/755] fix type pattern matching for auto hooks, improve slice array indexing operations to rely less on the full irtree path (it composes poorly when using combining type views --- src/eval/eval_core.c | 5 ++++ src/eval/eval_ir.c | 10 +++----- src/eval/eval_types.c | 58 ++++++++++++++++++++++++++---------------- src/mule/mule_main.cpp | 20 +++++++++++++++ 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index d7b37120..ba5f64de 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1075,6 +1075,11 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) continue; } U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0); + if(pattern_part_pos > scan_pos && n == auto_hook_node->type_pattern_parts.first) + { + fits_this_type_string = 0; + break; + } if(pattern_part_pos >= type_string.size) { fits_this_type_string = 0; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 5066136b..991e3281 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -457,9 +457,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_IRNode *new_tree = l.root; E_TypeKey new_tree_type = r_type; E_Mode mode = l.mode; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) + if(e_type_kind_is_pointer_or_ref(l_restype_kind)) { new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); if(l.mode != E_Mode_Null) @@ -627,7 +625,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, 0, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain @@ -831,7 +829,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -859,7 +857,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6264c1e7..d13607e5 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2450,30 +2450,44 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) { Temp scratch = scratch_begin(&arena, 1); - // rjf: compute bytecode of struct - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root); - String8 lhs_bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); - - // rjf: build expression tree to access base pointer's member, then do an index - E_Expr *idx_expr = e_push_expr(scratch.arena, E_ExprKind_ArrayIndex, 0); - E_Expr *dot_expr = e_push_expr(scratch.arena, E_ExprKind_MemberAccess, 0); - E_Expr *lhs_expr = e_push_expr(scratch.arena, E_ExprKind_LeafBytecode, 0); - E_Expr *base_ptr_expr = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, 0); - e_expr_push_child(dot_expr, lhs_expr); - e_expr_push_child(dot_expr, base_ptr_expr); - e_expr_push_child(idx_expr, dot_expr); - e_expr_push_child(idx_expr, e_expr_ref(scratch.arena, expr->first->next)); + // rjf: compute ir tree for struct base + E_IRNode *struct_base_tree = &e_irnode_nil; { - lhs_expr->mode = lhs_irtree->mode; - lhs_expr->bytecode = lhs_bytecode; - lhs_expr->type_key = e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_Lenses); - } - { - base_ptr_expr->string = ext->base_ptr_member->name; + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root); + String8 lhs_bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); + struct_base_tree = e_irtree_bytecode_no_copy(arena, lhs_bytecode); + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_AllDecorative)))) + { + struct_base_tree = e_irtree_resolve_to_value(arena, lhs_irtree->mode, lhs_irtree->root, lhs_irtree->type_key); + } } - // rjf: compute struct.base_ptr IR tree - result = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, idx_expr); + // rjf: compute ir tree for base pointer value calculation + E_IRNode *base_ptr_tree = &e_irnode_nil; + if(struct_base_tree != &e_irnode_nil) + { + base_ptr_tree = struct_base_tree; + if(ext->base_ptr_member->off != 0) + { + base_ptr_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, struct_base_tree, e_irtree_const_u(arena, ext->base_ptr_member->off)); + } + base_ptr_tree = e_irtree_mem_read_type(arena, base_ptr_tree, ext->base_ptr_member->type_key); + } + + // rjf: compute ir tree for adding to the base ptr member + E_IRNode *idxed_base_tree = &e_irnode_nil; + if(base_ptr_tree != &e_irnode_nil) + { + E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, expr->first->next); + E_IRNode *idx_root = e_irtree_resolve_to_value(arena, idx_irtree.mode, idx_irtree.root, idx_irtree.type_key); + E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All)))); + idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, base_ptr_tree, off_root); + } + + // rjf: form final result + result.root = idxed_base_tree; + result.type_key = e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All); + result.mode = E_Mode_Offset; scratch_end(scratch); }break; @@ -2492,7 +2506,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice) } else if(accel->opl_ptr_member != 0 && accel->base_ptr_member != 0) { - count = e_value_eval_from_eval(e_eval_wrapf(eval, "$.%S - $.%S", accel->opl_ptr_member->name, accel->base_ptr_member->name)).value.u64; + count = e_value_eval_from_eval(e_eval_wrapf(eval, "raw($.%S) - raw($.%S)", accel->opl_ptr_member->name, accel->base_ptr_member->name)).value.u64; } } E_TypeExpandInfo info = {0, count}; diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index ed6a3568..fa95ba20 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -104,9 +104,11 @@ void optimized_struct_parameters_eval_tests(void); // NOTE(allen): Type Coverage Eval #include +#include #include raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); +raddbg_auto_view_rule(std::unique_ptr, _Mypair._Myval2); struct Basics { @@ -1278,6 +1280,7 @@ struct Base int x; int y; int z; + Base(){x = 1; y = 2; z = 3;} virtual ~Base() = default; virtual void Foo() = 0; }; @@ -1308,6 +1311,7 @@ struct DerivedA : Base { float a; float b; + DerivedA() {a = 123.f; b = 123.f;} virtual void Foo() {a += 1;} virtual ~DerivedA() = default; }; @@ -1316,6 +1320,7 @@ struct DerivedB : Base { double c; double d; + DerivedB() {c = 123.0; d = 123.0;} virtual void Foo() {c += 1;} virtual ~DerivedB() = default; }; @@ -1556,6 +1561,21 @@ extended_type_coverage_eval_tests(void){ non_virtual_derived->x += 1; non_virtual_derived->x += 1; + std::unique_ptr ridiculous_cplusplus_base_class = std::make_unique(); + + std::vector> ridiculous_cplusplus_array; + for(int i = 0; i < 1024; i += 1) + { + if((i & 1) == 1) + { + ridiculous_cplusplus_array.push_back(std::make_unique()); + } + else + { + ridiculous_cplusplus_array.push_back(std::make_unique()); + } + } + Base *base_array[1024] = {0}; for(int i = 0; i < sizeof(base_array)/sizeof(base_array[0]); i += 1) { From 005ff83d677c64fdc7e32186e962ed405b9db937 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 10:19:44 -0700 Subject: [PATCH 505/755] eliminate now-0redundant `raw` usage in watch row build --- src/raddbg/raddbg_views.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 02f870f3..81ed690e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1416,8 +1416,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof($)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } From ee9017d5dba0375a3ae0413406c76caa9048c9b6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 10:50:36 -0700 Subject: [PATCH 506/755] cfg schema-based path relativization on save, derelativization on load; omit for file path maps --- src/path/path.c | 10 +-- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 133 ++++++++++++++++++++++------- src/raddbg/raddbg_core.h | 4 +- 6 files changed, 118 insertions(+), 41 deletions(-) diff --git a/src/path/path.c b/src/path/path.c index fa384748..a6b79995 100644 --- a/src/path/path.c +++ b/src/path/path.c @@ -90,7 +90,7 @@ path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src) if(dst_style == PathStyle_Relative) { Temp scratch = scratch_begin(&arena, 1); - String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", src, dst); + String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", str8_chop_last_slash(src), dst); String8 dst_from_src_absolute_normalized = path_normalized_from_string(arena, dst_from_src_absolute); result = dst_from_src_absolute_normalized; scratch_end(scratch); @@ -160,10 +160,10 @@ path_char_from_style(PathStyle style) String8 result = str8_zero(); switch (style) { - case PathStyle_Null: break; - case PathStyle_Relative: break; - case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break; - case PathStyle_UnixAbsolute: result = str8_lit("/"); break; + case PathStyle_Null: break; + case PathStyle_Relative: break; + case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break; + case PathStyle_UnixAbsolute: result = str8_lit("/"); break; } return result; } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f2f9b8e3..2e058d84 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[325] = +RD_VocabInfo rd_vocab_info_table[327] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -87,6 +87,8 @@ RD_VocabInfo rd_vocab_info_table[325] = {str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, {str8_lit_comp("src"), str8_lit_comp("srcs"), str8_lit_comp("Source"), str8_lit_comp("Sources"), RD_IconKind_Null}, {str8_lit_comp("dst"), str8_lit_comp("dsts"), str8_lit_comp("Destination"), str8_lit_comp("Destinations"), RD_IconKind_Null}, +{str8_lit_comp("source"), str8_lit_comp("sources"), str8_lit_comp("Source"), str8_lit_comp("Sources"), RD_IconKind_Null}, +{str8_lit_comp("dest"), str8_lit_comp("dests"), str8_lit_comp("Destination"), str8_lit_comp("Destinations"), RD_IconKind_Null}, {str8_lit_comp("conversion_task"), str8_lit_comp("conversion_tasks"), str8_lit_comp("Conversion Task"), str8_lit_comp("Conversion Tasks"), RD_IconKind_Null}, {str8_lit_comp("conversion_fail"), str8_lit_comp("conversion_fails"), str8_lit_comp("Conversion Fail"), str8_lit_comp("Conversion Fails"), RD_IconKind_Null}, {str8_lit_comp("lang"), str8_lit_comp("langs"), str8_lit_comp("Language"), str8_lit_comp("Languages"), RD_IconKind_Null}, @@ -398,7 +400,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, {str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index bcf7a129..30edd248 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -678,7 +678,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[325]; +extern RD_VocabInfo rd_vocab_info_table[327]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 05f7754f..56d66c5e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -112,6 +112,8 @@ RD_VocabTable: {recent_file _ "Recent File" _ FileOutline } {src _ "Source" _ Null } {dst _ "Destination" _ Null } + {source _ "Source" _ Null } + {dest _ "Destination" _ Null } {conversion_task _ "Conversion Task" _ Null } {conversion_fail _ "Conversion Fail" _ Null } {lang _ "Language" _ Null } @@ -581,7 +583,7 @@ RD_VocabTable: //- rjf: file path maps { file_path_map, - ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}```, + ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}```, } //- rjf: auto view rules diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 7b02edd6..2303d532 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -607,11 +607,15 @@ rd_cfg_array_from_list(Arena *arena, RD_CfgList *list) } internal RD_CfgList -rd_cfg_tree_list_from_string(Arena *arena, String8 string) +rd_cfg_tree_list_from_string(Arena *arena, String8 root_path, String8 string) { RD_CfgList result = {0}; Temp scratch = scratch_begin(&arena, 1); + + //- rjf: parse the string as metadesk MD_Node *root = md_tree_from_string(scratch.arena, string); + + //- rjf: iterate the top-level metadesk trees, generate new cfg trees for each for MD_EachNode(tln, root->first) { RD_Cfg *dst_root_n = &rd_nil_cfg; @@ -619,14 +623,39 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 string) MD_NodeRec rec = {0}; for(MD_Node *src_n = tln; !md_node_is_nil(src_n); src_n = rec.next) { + // rjf: lookup schema for this string + MD_Node *schema = &md_nil_node; + { + MD_NodePtrList schemas = rd_schemas_from_name(dst_active_parent_n->parent->string); + for(MD_NodePtrNode *n = schemas.first; n != 0 && schema == &md_nil_node; n = n->next) + { + schema = md_child_from_string(n->v, dst_active_parent_n->string, 0); + } + } + + // rjf: extract & transform metadesk node's string (it is raw textual data, so we need to + // go escaped -> raw, and derelativize paths) + String8 dst_n_string = {0}; + { + String8 src_n_string = src_n->string; + String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); + if(str8_match(schema->first->string, str8_lit("path"), 0) && + !md_node_has_tag(schema->first, str8_lit("absolute"), 0)) + { + src_n_string__raw = path_absolute_dst_from_relative_dst_src(scratch.arena, src_n_string__raw, root_path); + } + dst_n_string = src_n_string__raw; + } + + // rjf: allocate, fill, & insert new cfg for this metadesk node RD_Cfg *dst_n = rd_cfg_alloc(); - String8 src_n_string = src_n->string; - String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); - rd_cfg_equip_string(dst_n, src_n_string__raw); + rd_cfg_equip_string(dst_n, dst_n_string); if(dst_active_parent_n != &rd_nil_cfg) { rd_cfg_insert_child(dst_active_parent_n, dst_active_parent_n->last, dst_n); } + + // rjf: recurse rec = md_node_rec_depth_first_pre(src_n, tln); if(dst_active_parent_n == &rd_nil_cfg) { @@ -648,7 +677,7 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 string) } internal String8 -rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg) +rd_string_from_cfg_tree(Arena *arena, String8 root_path, RD_Cfg *cfg) { Temp scratch = scratch_begin(&arena, 1); String8List strings = {0}; @@ -658,49 +687,92 @@ rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg) { NestTask *next; RD_Cfg *cfg; + MD_Node *schema; B32 is_simple; }; NestTask *top_nest_task = 0; RD_CfgRec rec = {0}; for(RD_Cfg *c = cfg; c != &rd_nil_cfg; c = rec.next) { + // rjf: look up parent's schemas + MD_NodePtrList schemas = {0}; + if(top_nest_task != 0) + { + RD_Cfg *parent = top_nest_task->cfg; + schemas = rd_schemas_from_name(parent->string); + } + + // rjf: look up child schema + MD_Node *c_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && c_schema == &md_nil_node; n = n->next) + { + c_schema = md_child_from_string(n->v, c->string, 0); + } + // rjf: push name of this node if(c->string.size != 0 || c->first == &rd_nil_cfg) { + // rjf: extract the textualized form for this string (we may need to escape / relativize) + String8 c_serialized_string = c->string; + { + MD_Node *c_schema = &md_nil_node; + if(top_nest_task != 0) + { + c_schema = top_nest_task->schema; + } + + // rjf: paths -> relativize + if(str8_match(c_schema->first->string, str8_lit("path"), 0) && + !md_node_has_tag(c_schema->first, str8_lit("absolute"), 0)) + { + String8 path_absolute = c->string; + String8 path_relative = path_relative_dst_from_absolute_dst_src(arena, path_absolute, root_path); + c_serialized_string = path_relative; + } + + // rjf: all strings -> escape + c_serialized_string = escaped_from_raw_str8(arena, c_serialized_string); + } + + // rjf: generate all strings for this node's string String8List c_name_strings = {0}; - B32 name_can_be_pushed_standalone = 0; { - Temp temp = temp_begin(scratch.arena); - MD_TokenizeResult c_name_tokenize = md_tokenize_from_text(temp.arena, c->string); - name_can_be_pushed_standalone = (c_name_tokenize.tokens.count == 1 && c_name_tokenize.tokens.v[0].flags & (MD_TokenFlag_Identifier| - MD_TokenFlag_Numeric| - MD_TokenFlag_StringLiteral| - MD_TokenFlag_Symbol)); - temp_end(temp); - } - if(name_can_be_pushed_standalone) - { - str8_list_push(scratch.arena, &c_name_strings, c->string); - } - else - { - String8 c_name_escaped = escaped_from_raw_str8(scratch.arena, c->string); - str8_list_push(scratch.arena, &c_name_strings, str8_lit("\"")); - str8_list_push(scratch.arena, &c_name_strings, c_name_escaped); - str8_list_push(scratch.arena, &c_name_strings, str8_lit("\"")); + B32 name_can_be_pushed_standalone = 0; + { + Temp temp = temp_begin(scratch.arena); + MD_TokenizeResult c_name_tokenize = md_tokenize_from_text(temp.arena, c_serialized_string); + name_can_be_pushed_standalone = (c_name_tokenize.tokens.count == 1 && c_name_tokenize.tokens.v[0].flags & (MD_TokenFlag_Identifier| + MD_TokenFlag_Numeric| + MD_TokenFlag_StringLiteral| + MD_TokenFlag_Symbol)); + temp_end(temp); + } + if(name_can_be_pushed_standalone) + { + str8_list_push(scratch.arena, &c_name_strings, c_serialized_string); + } + else + { + str8_list_push(scratch.arena, &c_name_strings, str8_lit("\"")); + str8_list_push(scratch.arena, &c_name_strings, c_serialized_string); + str8_list_push(scratch.arena, &c_name_strings, str8_lit("\"")); + } } + + // rjf: if we're in a simple nesting task, then just break children by space if(top_nest_task != 0 && top_nest_task->is_simple) { str8_list_push(scratch.arena, &strings, str8_lit(" ")); } + + // rjf: join c's strings with main string list str8_list_concat_in_place(&strings, &c_name_strings); } // rjf: grab next recursion rec = rd_cfg_rec__depth_first(cfg, c); - // rjf: determine if this node is simple, and can be encoded on a single line - - // if so, push a new nesting task onto the stack + // rjf: push a new nesting task before descending to children if(c->first != &rd_nil_cfg) { B32 is_simple_children_list = 1; @@ -714,6 +786,7 @@ rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg) } NestTask *task = push_array(scratch.arena, NestTask, 1); task->cfg = c; + task->schema = c_schema; task->is_simple = is_simple_children_list; SLLStackPush(top_nest_task, task); } @@ -5717,7 +5790,7 @@ rd_window_frame(void) { ThemeTask *t = push_array(scratch.arena, ThemeTask, 1); SLLQueuePushFront(first_task, last_task, t); - t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, n->v)); + t->tree = md_tree_from_string(scratch.arena, rd_string_from_cfg_tree(scratch.arena, str8_zero(), n->v)); } } @@ -12707,7 +12780,7 @@ rd_frame(void) for(String8Node *text_n = raddbg_data_text_parts.first; text_n != 0; text_n = text_n->next) { String8 text = text_n->string; - RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, text); + RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, str8_zero(), text); String8 module_name = ctrl_string_from_handle(scratch.arena, module->handle); for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next, cfg_idx += 1) { @@ -13098,7 +13171,7 @@ rd_frame(void) RD_CfgList file_cfg_list = {0}; if(file_is_okay) { - file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_data); + file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_path, file_data); } //- rjf: store path @@ -13221,7 +13294,7 @@ rd_frame(void) str8_list_pushf(scratch.arena, &strings, "// raddbg %s %S file\n\n", BUILD_VERSION_STRING_LITERAL, bucket_name); for(RD_Cfg *child = tree_root->first; child != &rd_nil_cfg; child = child->next) { - str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, child)); + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, child)); } String8 data = str8_list_join(scratch.arena, &strings, 0); B32 temp_write_good = os_write_data_to_file_path(temp_path, data); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 1f0b487f..2a8d332f 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -865,8 +865,8 @@ internal RD_Cfg *rd_cfg_child_from_string_or_parent(RD_Cfg *parent, String8 stri internal RD_CfgList rd_cfg_child_list_from_string(Arena *arena, RD_Cfg *parent, String8 string); internal RD_CfgList rd_cfg_top_level_list_from_string(Arena *arena, String8 string); internal RD_CfgArray rd_cfg_array_from_list(Arena *arena, RD_CfgList *list); -internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 string); -internal String8 rd_string_from_cfg_tree(Arena *arena, RD_Cfg *cfg); +internal RD_CfgList rd_cfg_tree_list_from_string(Arena *arena, String8 root_path, String8 string); +internal String8 rd_string_from_cfg_tree(Arena *arena, String8 root_path, RD_Cfg *cfg); internal RD_CfgRec rd_cfg_rec__depth_first(RD_Cfg *root, RD_Cfg *cfg); internal void rd_cfg_list_push(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); internal void rd_cfg_list_push_front(Arena *arena, RD_CfgList *list, RD_Cfg *cfg); From e16f64f4e2fadee8c4bb96d163642b2b1ff1960b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 11:54:10 -0700 Subject: [PATCH 507/755] tighten up expr drag/drop --- src/raddbg/raddbg_core.c | 73 ++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2303d532..bb183f49 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4266,25 +4266,27 @@ rd_view_ui(Rng2F32 rect) if(ui_key_match(ui_drop_hot_key(), drop_target->key)) { Vec2F32 drop_pos = sub_2f32(ui_mouse(), rect.p0); + RD_RegSlot drag_slot = rd_state->drag_drop_regs_slot; + RD_Regs *drag_regs = rd_state->drag_drop_regs; - //- rjf: obtain best fit for "previous row" drag/drops + //- rjf: obtain best fit for target block & prev-row for this drag EV_Block *watches_block = &ev_nil_block; - U64 best_prev_row_num = 0; + U64 best_prev_row_block_num = 0; F32 best_prev_row_y = 0; F32 best_prev_row_distance = inf32(); { U64 local_row_idx = 0; F32 row_y = 0; - EV_Row *prev_row = 0; - RD_WatchRowInfo *prev_row_info = 0; for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, local_row_idx += 1) { EV_Row *row = &row_node->row; F32 row_height = row_height_px*row->visual_size; RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && - block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches)) + if(drag_slot == RD_RegSlot_Expr && + block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) && + (drag_regs->cfg == 0 || + (drag_regs->cfg != row_info->group_cfg_child->id))) { if(watches_block == &ev_nil_block && row_y <= drop_pos.y && drop_pos.y <= row_y + row_height) { @@ -4294,55 +4296,60 @@ rd_view_ui(Rng2F32 rect) if(row_distance <= best_prev_row_distance) { U64 row_num = ev_block_num_from_id(row->block, row->key.child_id); - best_prev_row_num = row_num-1; + best_prev_row_block_num = row_num-1; best_prev_row_distance = row_distance; best_prev_row_y = row_y; watches_block = row->block; } } row_y += row_height; - prev_row = row; - prev_row_info = row_info; + } + } + + //- rjf: unpack block/previous row info + B32 drag_target_is_good = 0; + RD_Cfg *drag_parent_cfg = &rd_nil_cfg; + RD_Cfg *drag_prev_cfg = &rd_nil_cfg; + if(watches_block != &ev_nil_block) + { + EV_Key prev_row_key = ev_key_make(ev_hash_from_key(watches_block->key), ev_block_id_from_num(watches_block, best_prev_row_block_num)); + U64 prev_row_num = ev_num_from_key(&block_ranges, prev_row_key); + EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, prev_row_num); + RD_WatchRowInfo prev_row_info = rd_watch_row_info_from_row(scratch.arena, prev_row); + drag_parent_cfg = rd_cfg_from_eval_space(watches_block->eval.space); + drag_prev_cfg = prev_row_info.group_cfg_child; + if(drag_regs->cfg == 0 || drag_prev_cfg->id != drag_regs->cfg) + { + drag_target_is_good = 1; } } //- rjf: drop - if(rd_drag_drop()) + if(drag_target_is_good && rd_drag_drop() && drag_parent_cfg != &rd_nil_cfg) { - RD_RegSlot drop_slot = rd_state->drag_drop_regs_slot; - RD_Regs *drop_regs = rd_state->drag_drop_regs; - switch(drop_slot) + switch(drag_slot) { default:{}break; case RD_RegSlot_Expr: - if(watches_block != &ev_nil_block) { - RD_Cfg *parent_cfg = rd_cfg_from_eval_space(watches_block->eval.space); - EV_Key prev_row_key = ev_key_make(ev_hash_from_key(watches_block->key), ev_block_id_from_num(watches_block, best_prev_row_num)); - U64 prev_row_num = ev_num_from_key(&block_ranges, prev_row_key); - EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, prev_row_num); - RD_WatchRowInfo prev_row_info = rd_watch_row_info_from_row(scratch.arena, prev_row); - RD_Cfg *prev_cfg = prev_row_info.group_cfg_child; - if(parent_cfg != &rd_nil_cfg) + RD_Cfg *cfg = rd_cfg_from_id(drag_regs->cfg); + if(cfg != &rd_nil_cfg) { - RD_Cfg *cfg = rd_cfg_from_id(drop_regs->cfg); - if(cfg->parent == parent_cfg) - { - rd_cfg_unhook(cfg->parent, cfg); - } - else - { - cfg = rd_cfg_alloc(); - rd_cfg_equip_stringf(cfg, "watch"); - rd_cfg_new(cfg, rd_state->drag_drop_regs->expr); - } - rd_cfg_insert_child(parent_cfg, prev_cfg, cfg); + rd_cfg_unhook(cfg->parent, cfg); } + if(cfg == &rd_nil_cfg) + { + cfg = rd_cfg_alloc(); + rd_cfg_equip_stringf(cfg, "watch"); + rd_cfg_new(cfg, drag_regs->expr); + } + rd_cfg_insert_child(drag_parent_cfg, drag_prev_cfg, cfg); }break; } } //- rjf: draw drop position + if(drag_target_is_good) { DR_Bucket *bucket = dr_bucket_make(); DR_BucketScope(bucket) UI_TagF("pop") From 9f468c44d9003e2e6d9fbf4628134291f5d6e069 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 11:57:35 -0700 Subject: [PATCH 508/755] ditto --- src/raddbg/raddbg_core.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bb183f49..5a1f24d2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4265,41 +4265,48 @@ rd_view_ui(Rng2F32 rect) UI_Signal sig = ui_signal_from_box(drop_target); if(ui_key_match(ui_drop_hot_key(), drop_target->key)) { - Vec2F32 drop_pos = sub_2f32(ui_mouse(), rect.p0); + Vec2F32 drag_pos = sub_2f32(ui_mouse(), rect.p0); RD_RegSlot drag_slot = rd_state->drag_drop_regs_slot; RD_Regs *drag_regs = rd_state->drag_drop_regs; //- rjf: obtain best fit for target block & prev-row for this drag - EV_Block *watches_block = &ev_nil_block; + EV_Block *drag_block = &ev_nil_block; U64 best_prev_row_block_num = 0; F32 best_prev_row_y = 0; - F32 best_prev_row_distance = inf32(); { + F32 best_prev_row_distance = inf32(); U64 local_row_idx = 0; F32 row_y = 0; for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, local_row_idx += 1) { + // rjf: unpack row EV_Row *row = &row_node->row; F32 row_height = row_height_px*row->visual_size; RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); - if(drag_slot == RD_RegSlot_Expr && - block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches) && - (drag_regs->cfg == 0 || - (drag_regs->cfg != row_info->group_cfg_child->id))) + + // rjf: determine if this row's block is good for the current drag/drop + B32 block_is_good_for_drop = 0; + if(drag_slot == RD_RegSlot_Expr && block_type->expand.id_from_num == E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(watches)) { - if(watches_block == &ev_nil_block && row_y <= drop_pos.y && drop_pos.y <= row_y + row_height) + block_is_good_for_drop = (drag_regs->cfg == 0 || (drag_regs->cfg != row_info->group_cfg_child->id)); + } + + // rjf: if this block is good, then test this row/block & grab if appropriate + if(block_is_good_for_drop) + { + if(drag_block == &ev_nil_block && row_y <= drag_pos.y && drag_pos.y <= row_y + row_height) { - watches_block = row->block; + drag_block = row->block; } - F32 row_distance = abs_f32(drop_pos.y - row_y); + F32 row_distance = abs_f32(drag_pos.y - row_y); if(row_distance <= best_prev_row_distance) { U64 row_num = ev_block_num_from_id(row->block, row->key.child_id); best_prev_row_block_num = row_num-1; best_prev_row_distance = row_distance; best_prev_row_y = row_y; - watches_block = row->block; + drag_block = row->block; } } row_y += row_height; @@ -4310,13 +4317,13 @@ rd_view_ui(Rng2F32 rect) B32 drag_target_is_good = 0; RD_Cfg *drag_parent_cfg = &rd_nil_cfg; RD_Cfg *drag_prev_cfg = &rd_nil_cfg; - if(watches_block != &ev_nil_block) + if(drag_block != &ev_nil_block) { - EV_Key prev_row_key = ev_key_make(ev_hash_from_key(watches_block->key), ev_block_id_from_num(watches_block, best_prev_row_block_num)); + EV_Key prev_row_key = ev_key_make(ev_hash_from_key(drag_block->key), ev_block_id_from_num(drag_block, best_prev_row_block_num)); U64 prev_row_num = ev_num_from_key(&block_ranges, prev_row_key); EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, prev_row_num); RD_WatchRowInfo prev_row_info = rd_watch_row_info_from_row(scratch.arena, prev_row); - drag_parent_cfg = rd_cfg_from_eval_space(watches_block->eval.space); + drag_parent_cfg = rd_cfg_from_eval_space(drag_block->eval.space); drag_prev_cfg = prev_row_info.group_cfg_child; if(drag_regs->cfg == 0 || drag_prev_cfg->id != drag_regs->cfg) { From b1d63cd1303d7f70eafbfe3956dacee6e9fcd245 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 13:34:05 -0700 Subject: [PATCH 509/755] unattached process evaluation / lister --- src/ctrl/ctrl_core.c | 13 +++---- src/eval/eval_ir.c | 83 ++++++++++++++++++++-------------------- src/raddbg/raddbg_core.c | 1 + src/raddbg/raddbg_eval.c | 58 ++++++++++++++++++++++++---- src/raddbg/raddbg_eval.h | 1 + src/raddbg/raddbg_main.c | 4 ++ 6 files changed, 103 insertions(+), 57 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1807a1e3..f38dfc76 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -189,7 +189,7 @@ ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src) internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle) { - String8 result = push_str8f(arena, "$0x%I64x$0x%I64x", handle.machine_id, handle.dmn_handle.u64[0]); + String8 result = push_str8f(arena, "$%I64x$%I64x", handle.machine_id, handle.dmn_handle.u64[0]); return result; } @@ -203,14 +203,11 @@ ctrl_handle_from_string(String8 string) String8List parts = str8_split(scratch.arena, string, &split, 1, 0); if(parts.first && parts.first->next) { - CTRL_MachineID machine_id = 0; + CTRL_MachineID machine_id = u64_from_str8(parts.first->string, 16); DMN_Handle dmn_handle = {0}; - if(try_u64_from_str8_c_rules(parts.first->string, &machine_id) && - try_u64_from_str8_c_rules(parts.first->next->string, &dmn_handle.u64[0])) - { - handle.machine_id = machine_id; - handle.dmn_handle = dmn_handle; - } + dmn_handle.u64[0] = u64_from_str8(parts.first->next->string, 16); + handle.machine_id = machine_id; + handle.dmn_handle = dmn_handle; } scratch_end(scratch); } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 991e3281..1dd39122 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1523,8 +1523,50 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Space mapped_bytecode_space = zero_struct; String8 mapped_bytecode = {0}; + //- rjf: try to map name as parent expression signifier ('$') + if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) + { + E_IRTreeAndType *parent_irtree = parent; + if(disallow_autohooks) + { + for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) + { + parent_irtree = prev; + } + } + E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); + string_mapped = 1; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = parent_irtree->mode; + mapped_type_key = parent_irtree->type_key; + disallow_autohooks = 1; + E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); + e_msg_list_concat_in_place(&result.msgs, &msgs); + } + + //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) + if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil) + { + for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) + { + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, access); + if(access_irtree.root != &e_irnode_nil) + { + string_mapped = 1; + E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); + mapped_type_key = access_irtree.type_key; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = access_irtree.mode; + e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); + break; + } + } + } + //- rjf: form namespaceified fallback versions of this lookup string String8List namespaceified_strings = {0}; + if(!string_mapped) { E_Module *module = e_base_ctx->primary_module; RDI_Parsed *rdi = module->rdi; @@ -1549,47 +1591,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } } - //- rjf: try to map name as parent expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) - { - E_IRTreeAndType *parent_irtree = parent; - if(disallow_autohooks) - { - for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) - { - parent_irtree = prev; - } - } - E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); - string_mapped = 1; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = parent_irtree->mode; - mapped_type_key = parent_irtree->type_key; - disallow_autohooks = 1; - E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); - e_msg_list_concat_in_place(&result.msgs, &msgs); - } - - //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(!string_mapped && parent != 0 && parent->root != &e_irnode_nil) - { - for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) - { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, access); - if(access_irtree.root != &e_irnode_nil) - { - string_mapped = 1; - E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); - mapped_type_key = access_irtree.type_key; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = access_irtree.mode; - e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); - break; - } - } - } - //- rjf: try to map name as member - if found, string__redirected := "this", and turn // on later implicit-member-lookup generation B32 string_is_implicit_member_name = 0; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5a1f24d2..27c652c9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12518,6 +12518,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .flags = E_TypeFlag_StubSingleLineExpansion, + .access = E_TYPE_ACCESS_FUNCTION_NAME(unattached_processes), .expand = { .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index fe7de6e7..7d11331e 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -574,7 +574,6 @@ E_TYPE_ACCESS_FUNCTION_DEF(control) return result; } - //////////////////////////////// //~ rjf: Config Collection Type Hooks @@ -1144,6 +1143,53 @@ struct RD_UnattachedProcessesAccel U64 infos_count; }; +E_TYPE_ACCESS_FUNCTION_DEF(unattached_processes) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_MemberAccess) + { + Temp scratch = scratch_begin(&arena, 1); + + // rjf: extract pid / name id from access string + U64 pid = 0; + U64 string_id = 0; + { + String8 pid_string = {0}; + String8 name_id_string = {0}; + U8 split_char = '$'; + String8List parts = str8_split(scratch.arena, expr->first->next->string, &split_char, 1, 0); + if(parts.first != 0 && parts.first->next != 0) + { + pid_string = parts.first->string; + name_id_string = parts.first->next->string; + pid = u64_from_str8(pid_string, 16); + string_id = u64_from_str8(name_id_string, 16); + } + } + + // rjf: get machine entity from space + E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpret = e_interpret(bytecode); + CTRL_Entity *machine = rd_ctrl_entity_from_eval_space(interpret.space); + + // rjf: build evaluation for this unattached process + if(machine != &ctrl_entity_nil) + { + E_IRNode *value_irnode = e_push_irnode(arena, RDI_EvalOp_ConstU128); + value_irnode->value.u128.u64[0] = pid; + value_irnode->value.u128.u64[1] = string_id; + E_Space space = rd_eval_space_from_ctrl_entity(machine, RD_EvalSpaceKind_MetaUnattachedProcess); + result.root = e_irtree_set_space(arena, space, value_irnode); + result.type_key = e_type_key_basic(E_TypeKind_U128); + result.mode = E_Mode_Value; + } + + scratch_end(scratch); + } + return result; +} + E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) { E_TypeExpandInfo info = {0}; @@ -1239,13 +1285,9 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) E_TypeKey unattached_process_type = e_type_key_cons(.kind = E_TypeKind_U128, .name = str8_lit("unattached_process")); for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { -#if 0 // TODO(rjf): @eval - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = unattached_process_type; - expr->value.u128.u64[0] = accel->infos[idx].pid; - expr->value.u128.u64[1] = e_id_from_string(accel->infos[idx].name); - expr->space = rd_eval_space_from_ctrl_entity(accel->machines[idx], RD_EvalSpaceKind_MetaUnattachedProcess); -#endif + CTRL_Entity *machine = accel->machines[idx]; + String8 string = ctrl_string_from_handle(arena, machine->handle); + evals_out[out_idx] = e_eval_wrapf(eval, "query:control.%S.unattached_processes.$%I64x$%I64x", string, accel->infos[idx].pid, e_id_from_string(accel->infos[idx].name)); } } diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index fdf8785b..67418101 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -82,6 +82,7 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(watches); //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks +E_TYPE_ACCESS_FUNCTION_DEF(unattached_processes); E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 81c2cb64..378d0dd7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -99,6 +99,10 @@ // useful, since different tabs can have a different set of expressions. // `Watch` tabs can now also be labeled, so you can visually distinguish // many `Watch` tabs more easily. +// - **Evaluation drag/drop.** Evaluations in a watch tree can be dragged and +// dropped. This can be used to create new top-level rows in a `Watch` tab, +// or to drag evaluations between `Watch` tabs, or to drag evaluations to +// source or disassembly views and pin the evaluation to some location there. // - **Settings expressions.** Debugger settings have been upgraded to be // stored as expressions, rather than being locked to a specific value. // These expressions are evaluated, like any other expression, and their From 9ed65c29973824e9cd7cb2b5a597e557a60be462 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 13:42:43 -0700 Subject: [PATCH 510/755] fix sizeof/typeof/bswap expr stringization --- src/eval/eval.mdesk | 6 +++--- src/eval/generated/eval.meta.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 46891e5d..b4760fca 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -91,9 +91,9 @@ E_ExprKindTable: { Address UnaryPrefix 2 "&" "" "" "" } { Cast Null 1 "(" ")" "" "" } - { Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" } - { Typeof UnaryPrefix 1 "typeof" "(" ")" "" } - { ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" } + { Sizeof UnaryPrefix 1 "sizeof " "" "" "" } + { Typeof UnaryPrefix 1 "typeof " "" "" "" } + { ByteSwap UnaryPrefix 1 "bswap " "" "" "" } { Pos UnaryPrefix 2 "+" "" "" "" } { Neg UnaryPrefix 2 "-" "" "" "" } diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 5577e0a1..85f28611 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -206,9 +206,9 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, -{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, From 24f4ef2d2d85a438560843610d85ab23f9dde0c4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 15:06:43 -0700 Subject: [PATCH 511/755] begin sketching out new autocompletion lister path --- src/raddbg/generated/raddbg.meta.c | 12 ++- src/raddbg/generated/raddbg.meta.h | 4 +- src/raddbg/raddbg.mdesk | 8 ++ src/raddbg/raddbg_core.c | 143 ++++++++++++++++++++++------- src/raddbg/raddbg_core.h | 12 ++- src/raddbg/raddbg_views.c | 9 ++ src/ui/ui_core.c | 16 +++- src/ui/ui_core.h | 17 ++-- 8 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2e058d84..8683025c 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -52,7 +52,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[327] = +RD_VocabInfo rd_vocab_info_table[329] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -308,6 +308,8 @@ RD_VocabInfo rd_vocab_info_table[327] = {str8_lit_comp("cut"), str8_lit_comp(""), str8_lit_comp("Cut"), str8_lit_comp(""), RD_IconKind_Clipboard}, {str8_lit_comp("paste"), str8_lit_comp(""), str8_lit_comp("Paste"), str8_lit_comp(""), RD_IconKind_Clipboard}, {str8_lit_comp("insert_text"), str8_lit_comp(""), str8_lit_comp("Insert Text"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_next"), str8_lit_comp(""), str8_lit_comp("Move Next"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("move_prev"), str8_lit_comp(""), str8_lit_comp("Move Previous"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("goto_line"), str8_lit_comp(""), str8_lit_comp("Go To Line"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("goto_address"), str8_lit_comp(""), str8_lit_comp("Go To Address"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("center_cursor"), str8_lit_comp(""), str8_lit_comp("Center Cursor"), str8_lit_comp(""), RD_IconKind_Null}, @@ -457,7 +459,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[219] = +RD_CmdKindInfo rd_cmd_kind_info_table[221] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -605,6 +607,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[219] = { str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_next"), str8_lit_comp("Moves the cursor or selection to the next element."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("move_prev"), str8_lit_comp("Moves the cursor or selection to the previous element."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Cursor, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_Vaddr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -680,7 +684,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[219] = { str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -772,6 +776,8 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[109] = {str8_lit_comp("paste"), {OS_Key_V, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("paste"), {OS_Key_Insert, 0 |OS_Modifier_Shift }}, {str8_lit_comp("insert_text"), {OS_Key_Null, 0 }}, +{str8_lit_comp("move_next"), {OS_Key_Tab, 0 }}, +{str8_lit_comp("move_prev"), {OS_Key_Tab, 0 |OS_Modifier_Shift }}, {str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_Modifier_Alt}}, {str8_lit_comp("search"), {OS_Key_F, 0 |OS_Modifier_Ctrl }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 30edd248..71d47cf2 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -202,6 +202,8 @@ RD_CmdKind_Copy, RD_CmdKind_Cut, RD_CmdKind_Paste, RD_CmdKind_InsertText, +RD_CmdKind_MoveNext, +RD_CmdKind_MovePrev, RD_CmdKind_GoToLine, RD_CmdKind_GoToAddress, RD_CmdKind_CenterCursor, @@ -678,7 +680,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[20]; extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[327]; +extern RD_VocabInfo rd_vocab_info_table[329]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 56d66c5e..06e9b746 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -889,6 +889,10 @@ RD_CmdTable: // | | | | {Paste 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } {InsertText 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } + //- rjf: secondary navigation + {MoveNext 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_next" "Move Next" "Moves the cursor or selection to the next element." "" "" } + {MovePrev 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_prev" "Move Previous" "Moves the cursor or selection to the previous element." "" "" } + //- rjf: code navigation {GoToLine 1 1 0 0 "" Cursor null Nil Null 0 0 0 0 1 0 1 Null "goto_line" "Go To Line" "Jumps to a line number in the current code file." "" "" } {GoToAddress 1 1 0 0 "" Vaddr null Nil Null 0 0 0 0 1 0 1 Null "goto_address" "Go To Address" "Jumps to an address in the current memory or disassembly view." "" "" } @@ -1149,6 +1153,10 @@ RD_DefaultBindingTable: { "paste" Insert 0 shift 0 } { "insert_text" Null 0 0 0 } + //- rjf: secondary navigation + { "move_next" Tab 0 0 0 } + { "move_prev" Tab 0 shift 0 } + //- rjf: code navigation { "goto_line" G ctrl 0 0 } { "goto_address" G 0 0 alt } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 27c652c9..12dd1112 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4902,19 +4902,20 @@ rd_view_ui(Rng2F32 rect) { ui_pop_background_color(); } -#if 0 // TODO(rjf): @cfg (autocompletion) if(ui_is_focus_active() && selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y && txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + rd_set_autocomp_regs(.ui_key = sig.box->key, .string = input, .cursor = cell_edit_state->cursor); +#if 0 // TODO(rjf): @cfg (autocompletion) rd_set_autocomp_lister_query(.ui_key = sig.box->key, .off_px = v2f32(0, dim_2f32(sig.box->rect).y), .string = input, .cursor = cell_edit_state->cursor, .lister_flags = cell_autocomp_flags); - } #endif + } } } @@ -4993,7 +4994,8 @@ rd_view_ui(Rng2F32 rect) } // rjf: this watch window is a lister? -> move cursor & accept - if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg) + if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || + rd_cfg_child_from_string(view, str8_lit("expr_lister")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Accept); @@ -5501,14 +5503,6 @@ rd_store_view_expr_string(String8 string) rd_cfg_new_replace(expr, string); } -internal void -rd_store_view_filter(String8 string) -{ - RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *filter = rd_cfg_child_from_string_or_alloc(view, str8_lit("filter")); - rd_cfg_new_replace(filter, string); -} - internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target) { @@ -5653,8 +5647,9 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->r = r_window_equip(ws->os); ws->ui = ui_state_alloc(); ws->drop_completion_arena = arena_alloc(); - ws->hover_eval_arena = arena_alloc(); ws->query_arena = arena_alloc(); + ws->hover_eval_arena = arena_alloc(); + ws->autocomp_arena = arena_alloc(); ws->last_dpi = os_dpi_from_window(ws->os); OS_Handle zero_monitor = {0}; if(!os_handle_match(zero_monitor, preferred_monitor)) @@ -6585,10 +6580,9 @@ rd_window_frame(void) FloatingViewTask *next; RD_Cfg *view; Rng2F32 rect; - String8 view_name; - String8 expr; B32 is_focused; B32 is_anchored; + B32 only_secondary_navigation; B32 reset_open; UI_Signal signal; // NOTE(rjf): output, from build B32 pressed; @@ -6600,7 +6594,57 @@ rd_window_frame(void) FloatingViewTask *last_floating_view_task = 0; RD_Font(RD_FontSlot_Code) { - //- rjf: try to add hover eval first + //- rjf: add autocompletion view task + if(ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index) + { + // rjf: build view + RD_Cfg *root = rd_immediate_cfg_from_keyf("autocomp_view_%I64x", window->id); + RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("expr_lister")); + RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); + rd_cfg_new_replace(input, ws->autocomp_regs->string); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new_replacef(expr, "query:locals, query:procedures, query:types"); + + // rjf: determine container size + EV_BlockTree predicted_block_tree = {0}; + RD_RegsScope(.view = view->id, .tab = 0) + { + String8 expr = rd_expr_from_cfg(view); + E_Eval list_eval = e_eval_from_string(expr); + predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), rd_view_query_input(), list_eval); + } + F32 row_height_px = ui_top_px_height(); + U64 max_row_count = (U64)floor_f32(ui_top_font_size()*30.f / row_height_px); + U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count - 1); + F32 width_px = floor_f32(40.f*ui_top_font_size()); + F32 height_px = needed_row_count*row_height_px; + + // rjf: determine list top-level rect + Rng2F32 rect = r2f32p(0, 0, 0, 0); + if(!ui_key_match(ui_key_zero(), ws->autocomp_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->autocomp_regs->ui_key); + rect.x0 = anchor_box->rect.x0; + rect.y0 = anchor_box->rect.y1; + rect.x1 = rect.x0 + width_px; + rect.y1 = rect.y0 + height_px; + } + + // rjf: push task + { + FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); + SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + t->view = view; + t->rect = rect; + t->is_focused = 1; + t->is_anchored = 1; + t->only_secondary_navigation = 1; + } + } + + //- rjf: try to add hover eval { B32 build_hover_eval = (hover_eval_is_open && !rd_drag_is_active()); @@ -6668,15 +6712,8 @@ rd_window_frame(void) EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(hover_eval.irtree.type_key); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule->string); - // rjf: determine view name - String8 view_name = str8_lit("watch"); - if(view_ui_rule != &rd_nil_view_ui_rule) - { - view_name = view_ui_rule->name; - } - // rjf: build view - RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view"); + RD_Cfg *root = rd_immediate_cfg_from_keyf("hover_eval_view_%I64x", ws->cfg_id); RD_Cfg *view = rd_view_from_eval(root, hover_eval); rd_cfg_child_from_string_or_alloc(view, str8_lit("explicit_root")); @@ -6715,8 +6752,6 @@ rd_window_frame(void) hover_eval_floating_view_task = t; t->view = view; t->rect = rect; - t->view_name = view_name; - t->expr = hover_eval_expr; t->is_focused = ws->hover_eval_focused; t->is_anchored = 1; } @@ -6864,8 +6899,6 @@ rd_window_frame(void) query_floating_view_task = t; t->view = view; t->rect = rect; - t->view_name = str8_lit("watch"); - t->expr = query_expr; t->is_focused = 1; t->is_anchored = query_is_anchored; t->reset_open = reset_open; @@ -6888,17 +6921,11 @@ rd_window_frame(void) // rjf: unpack RD_Cfg *view = t->view; Rng2F32 rect = t->rect; - String8 view_name = t->view_name; - String8 expr = t->expr; B32 is_focused = t->is_focused; B32 is_anchored = t->is_anchored; + B32 only_secondary_navigation = t->only_secondary_navigation; F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate, .reset = t->reset_open, .initial = 0.f); - // rjf: build cfg tree - RD_Cfg *expr_root = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); - rd_cfg_new_replace(expr_root, expr); - // rjf: push view regs rd_push_regs(.view = view->id); { @@ -6916,6 +6943,9 @@ rd_window_frame(void) // rjf: build UI_Focus(is_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_PermissionFlags(only_secondary_navigation ? + UI_PermissionFlag_KeyboardSecondary|UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX|UI_PermissionFlag_ScrollY : + UI_PermissionFlag_All) { // rjf: build top-level container box UI_Box *container = &ui_nil_box; @@ -9600,6 +9630,22 @@ rd_set_hover_eval(Vec2F32 pos, String8 string) } } +//////////////////////////////// +//~ rjf: Autocompletion Lister + +internal void +rd_set_autocomp_regs_(RD_Regs *regs) +{ + RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); + if(ws->autocomp_last_frame_index < rd_state->frame_index) + { + ws->autocomp_last_frame_index = rd_state->frame_index; + arena_clear(ws->autocomp_arena); + ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); + } +} + //////////////////////////////// //~ rjf: Lister Functions @@ -11503,8 +11549,9 @@ rd_frame(void) arena_release(lister->arena); } arena_release(ws->drop_completion_arena); - arena_release(ws->hover_eval_arena); arena_release(ws->query_arena); + arena_release(ws->hover_eval_arena); + arena_release(ws->autocomp_arena); arena_release(ws->arena); DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); @@ -15094,6 +15141,8 @@ rd_frame(void) RD_Cfg *window_query = rd_immediate_cfg_from_keyf("window_query_%p", window); rd_cfg_release_all_children(window_query); view = rd_cfg_child_from_string_or_alloc(window_query, str8_lit("watch")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new_replace(expr, rd_regs()->expr); } // rjf: non-floating -> embed in tab parameter @@ -16244,6 +16293,30 @@ rd_frame(void) evt.string = rd_regs()->string; ui_event_list_push(scratch.arena, &ws->ui_events, &evt); }break; + + //- rjf: secondary navigation + case RD_CmdKind_MoveNext: + { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; + evt.delta_unit = UI_EventDeltaUnit_Char; + evt.delta_2s32 = v2s32(+0, +1); + ui_event_list_push(scratch.arena, &ws->ui_events, &evt); + }break; + case RD_CmdKind_MovePrev: + { + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + UI_Event evt = zero_struct; + evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; + evt.delta_unit = UI_EventDeltaUnit_Char; + evt.delta_2s32 = v2s32(+0, -1); + ui_event_list_push(scratch.arena, &ws->ui_events, &evt); + }break; } } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 2a8d332f..5c76fa6d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -543,6 +543,11 @@ struct RD_WindowState U64 hover_eval_firstt_us; U64 hover_eval_lastt_us; + // rjf: autocompletion state + U64 autocomp_last_frame_index; + Arena *autocomp_arena; + RD_Regs *autocomp_regs; + // rjf: error state U8 error_buffer[512]; U64 error_string_size; @@ -988,7 +993,6 @@ internal Arena *rd_push_view_arena(void); //- rjf: storing view-attached state internal void rd_store_view_expr_string(String8 string); -internal void rd_store_view_filter(String8 string); internal void rd_store_view_loading_info(B32 is_loading, U64 progress_u64, U64 progress_u64_target); internal void rd_store_view_scroll_pos(UI_ScrollPt2 pos); internal void rd_store_view_param(String8 key, String8 value); @@ -1015,6 +1019,12 @@ internal String8 rd_value_string_from_eval(Arena *arena, String8 filter, EV_Stri internal void rd_set_hover_eval(Vec2F32 pos, String8 string); +//////////////////////////////// +//~ rjf: Autocompletion Lister + +internal void rd_set_autocomp_regs_(RD_Regs *regs); +#define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) + //////////////////////////////// //~ rjf: Lister Functions diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 81ed690e..f6ee3bc5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1160,6 +1160,15 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .pct = 1.f); } + //////////////////////////// + //- rjf: @watch_row_build_cells expr lister rows + // + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("expr_lister")) != &rd_nil_cfg) + { + info.can_expand = 0; + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); + } + //////////////////////////// //- rjf: @watch_row_build_cells lister rows // diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 3e21a100..245373d3 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -565,14 +565,22 @@ ui_next_event(UI_Event **ev) { good = 0; } - if(!(perms & UI_PermissionFlag_Keyboard) && - (n->v.kind == UI_EventKind_Press || - n->v.kind == UI_EventKind_Release) && + if((n->v.kind == UI_EventKind_Press || + n->v.kind == UI_EventKind_Release || + n->v.kind == UI_EventKind_Navigate || + n->v.kind == UI_EventKind_Edit) && (n->v.key != OS_Key_LeftMouseButton && n->v.key != OS_Key_MiddleMouseButton && n->v.key != OS_Key_RightMouseButton)) { - good = 0; + if((perms & UI_PermissionFlag_Keyboard) == UI_PermissionFlag_KeyboardSecondary) + { + good = !!(n->v.flags & UI_EventFlag_Secondary); + } + else if(!(perms & UI_PermissionFlag_Keyboard)) + { + good = 0; + } } else if(!(perms & UI_PermissionFlag_Text) && (n->v.kind == UI_EventKind_Text)) { diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 98c0349c..96bcb795 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -49,15 +49,17 @@ UI_MouseButtonKind; typedef U32 UI_PermissionFlags; enum { - UI_PermissionFlag_ClicksLeft = (1<<0), - UI_PermissionFlag_ClicksMiddle = (1<<1), - UI_PermissionFlag_ClicksRight = (1<<2), - UI_PermissionFlag_ScrollX = (1<<3), - UI_PermissionFlag_ScrollY = (1<<4), - UI_PermissionFlag_Keyboard = (1<<5), - UI_PermissionFlag_Text = (1<<6), + UI_PermissionFlag_ClicksLeft = (1<<0), + UI_PermissionFlag_ClicksMiddle = (1<<1), + UI_PermissionFlag_ClicksRight = (1<<2), + UI_PermissionFlag_ScrollX = (1<<3), + UI_PermissionFlag_ScrollY = (1<<4), + UI_PermissionFlag_KeyboardPrimary = (1<<5), + UI_PermissionFlag_KeyboardSecondary= (1<<6), + UI_PermissionFlag_Text = (1<<7), //- rjf bundles + UI_PermissionFlag_Keyboard = (UI_PermissionFlag_KeyboardPrimary|UI_PermissionFlag_KeyboardSecondary), UI_PermissionFlag_Clicks = (UI_PermissionFlag_ClicksLeft|UI_PermissionFlag_ClicksMiddle|UI_PermissionFlag_ClicksRight), UI_PermissionFlag_All = 0xffffffff, }; @@ -118,6 +120,7 @@ enum UI_EventFlag_CapAtLine = (1<<6), UI_EventFlag_ExplicitDirectional = (1<<7), UI_EventFlag_Reorder = (1<<8), + UI_EventFlag_Secondary = (1<<9), }; typedef enum UI_EventDeltaUnit From 9c53215daf05f658f704621da4effbef236ab6e0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 15:17:46 -0700 Subject: [PATCH 512/755] fix expression updating with query views --- src/raddbg/raddbg_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 12dd1112..ec77842b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6846,6 +6846,10 @@ rd_window_frame(void) } } + // rjf: store expression + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); + rd_cfg_new_replace(expr, query_expr); + // rjf: evaluate query expression E_Eval query_eval = e_eval_from_string(query_expr); @@ -13045,7 +13049,9 @@ rd_frame(void) // rjf: command has required query -> prep query else { - rd_cmd(RD_CmdKind_PushQuery, .do_implicit_root = 1, .do_lister = info->query.expr.size != 0); + rd_cmd(RD_CmdKind_PushQuery, + .do_implicit_root = 1, + .do_lister = info->query.expr.size != 0); } }break; From 6ea0a237ceb72eab23347ce4d9fa0606789545db Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 15:33:15 -0700 Subject: [PATCH 513/755] feed autocompletion rows forward from autocompletion lister --- src/raddbg/raddbg_core.c | 30 ++++++++++++++++++++++++++++-- src/raddbg/raddbg_views.c | 4 ++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ec77842b..893abc74 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4024,6 +4024,32 @@ rd_view_ui(Rng2F32 rect) } } + ////////////////////////////// + //- rjf: autocomplete watches -> feed autocompletion info forward + // + if(rd_watch_pt_match(ewv->cursor, ewv->mark) && + rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) + { + U64 row_num = ev_num_from_key(&block_ranges, ewv->cursor.key); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), &block_ranges, row_num); + RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); + RD_WatchCell *cell = row_info.cells.first; + if(cell != 0) + { + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, 0, &row_info, cell, ui_top_font(), ui_top_font_size(), dim_2f32(rect).y); + String8 string = dr_string_from_fstrs(ui_build_arena(), &cell_info.eval_fstrs); + if(string.size != 0) + { + UI_Event evt = zero_struct; + { + evt.kind = UI_EventKind_AutocompleteHint; + evt.string = string; + } + ui_event_list_push(ui_build_arena(), ui_state->events, &evt); + } + } + } + ////////////////////////////// //- rjf: build ui // @@ -4995,7 +5021,7 @@ rd_view_ui(Rng2F32 rect) // rjf: this watch window is a lister? -> move cursor & accept if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || - rd_cfg_child_from_string(view, str8_lit("expr_lister")) != &rd_nil_cfg) + rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Accept); @@ -6600,7 +6626,7 @@ rd_window_frame(void) // rjf: build view RD_Cfg *root = rd_immediate_cfg_from_keyf("autocomp_view_%I64x", window->id); RD_Cfg *view = rd_cfg_child_from_string_or_alloc(root, str8_lit("watch")); - rd_cfg_child_from_string_or_alloc(view, str8_lit("expr_lister")); + rd_cfg_child_from_string_or_alloc(view, str8_lit("autocomplete")); RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); rd_cfg_new_replace(input, ws->autocomp_regs->string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f6ee3bc5..a0563509 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1161,9 +1161,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } //////////////////////////// - //- rjf: @watch_row_build_cells expr lister rows + //- rjf: @watch_row_build_cells autocomplete rows // - else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("expr_lister")) != &rd_nil_cfg) + else if(rd_cfg_child_from_string(rd_cfg_from_id(rd_regs()->view), str8_lit("autocomplete")) != &rd_nil_cfg) { info.can_expand = 0; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); From 1d4aa927791e54b38ee13249a34b9e0b017fd9d6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 15:38:46 -0700 Subject: [PATCH 514/755] fix autocomplete hint rendering on non-active line edits --- src/raddbg/raddbg_widgets.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index f11dba69..2bbe61d8 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3211,6 +3211,7 @@ rd_cell(RD_CellParams *params, String8 string) //- rjf: determine autocompletion string // String8 autocomplete_hint_string = {0}; + if(is_focus_active) { for(UI_Event *evt = 0; ui_next_event(&evt);) { From c473cdf3b8207d617439bd53a1e904349c5782be Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 16:24:38 -0700 Subject: [PATCH 515/755] eliminate old autocompletion code --- src/raddbg/raddbg_core.c | 898 +-------------------------------------- src/raddbg/raddbg_core.h | 94 +--- 2 files changed, 7 insertions(+), 985 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 893abc74..8398ea5c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9663,713 +9663,6 @@ rd_set_hover_eval(Vec2F32 pos, String8 string) //////////////////////////////// //~ rjf: Autocompletion Lister -internal void -rd_set_autocomp_regs_(RD_Regs *regs) -{ - RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(ws->autocomp_last_frame_index < rd_state->frame_index) - { - ws->autocomp_last_frame_index = rd_state->frame_index; - arena_clear(ws->autocomp_arena); - ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); - } -} - -//////////////////////////////// -//~ rjf: Lister Functions - -internal void -rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item) -{ - RD_ListerItemChunkNode *n = list->last; - if(n == 0 || n->count >= n->cap) - { - n = push_array(arena, RD_ListerItemChunkNode, 1); - SLLQueuePush(list->first, list->last, n); - n->cap = cap; - n->v = push_array_no_zero(arena, RD_ListerItem, n->cap); - list->chunk_count += 1; - } - MemoryCopyStruct(&n->v[n->count], item); - n->count += 1; - list->total_count += 1; -} - -internal RD_ListerItemArray -rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list) -{ - RD_ListerItemArray array = {0}; - array.count = list->total_count; - array.v = push_array_no_zero(arena, RD_ListerItem, array.count); - U64 idx = 0; - for(RD_ListerItemChunkNode *n = list->first; n != 0; n = n->next) - { - MemoryCopy(array.v+idx, n->v, sizeof(RD_ListerItem)*n->count); - idx += n->count; - } - return array; -} - -internal int -rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b) -{ - int result = 0; - if(a->group < b->group) - { - result = -1; - } - else if(a->group > b->group) - { - result = +1; - } - else if(a->display_name__matches.count > b->display_name__matches.count) - { - result = -1; - } - else if(a->display_name__matches.count < b->display_name__matches.count) - { - result = +1; - } - else if(a->description__matches.count > b->description__matches.count) - { - result = -1; - } - else if(a->description__matches.count < b->description__matches.count) - { - result = +1; - } - else if(a->kind_name__matches.count > b->kind_name__matches.count) - { - result = -1; - } - else if(a->kind_name__matches.count < b->kind_name__matches.count) - { - result = +1; - } - else if(a->string.size < b->string.size) - { - result = -1; - } - else if(a->string.size > b->string.size) - { - result = +1; - } - else - { - result = strncmp((char *)a->string.str, (char *)b->string.str, Min(a->string.size, b->string.size)); - } - return result; -} - -internal void -rd_lister_item_array_sort__in_place(RD_ListerItemArray *array) -{ - quick_sort(array->v, array->count, sizeof(array->v[0]), rd_lister_item_qsort_compare); -} - -internal RD_ListerItemArray -rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off) -{ - Temp scratch = scratch_begin(&arena, 1); - DI_Scope *di_scope = di_scope_open(); - String8 needle_path = rd_lister_query_path_from_input_string_off(needle, cursor_off); - RD_ListerItemChunkList item_list = {0}; - 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); - -#if 0 // TODO(rjf): @cfg (lister) - - ////////////////////////// - //- rjf: determine all ctx filters - // - String8List ctx_filter_strings = {0}; - { - switch(regs->reg_slot) - { - default:{}break; - case RD_RegSlot_Cursor: - { - if(!txt_pt_match(regs->cursor, regs->mark)) - { - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_rng,"); - } - else - { - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$text_pt,"); - } - }break; - case RD_RegSlot_Cfg: - { - RD_Cfg *cfg = rd_cfg_from_id(regs->cfg); - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", cfg->string); - }break; - case RD_RegSlot_View: - { - RD_Cfg *view = rd_cfg_from_id(regs->view); - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$tab,"); - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$%S,", view->string); - String8 view_expr = rd_expr_from_cfg(view); - String8 view_file_path = rd_file_path_from_eval_string(scratch.arena, view_expr); - if(view_file_path.size != 0) - { - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$file,"); - } - } // fallthrough; - case RD_RegSlot_Panel: - { - str8_list_pushf(scratch.arena, &ctx_filter_strings, "$panel,"); - }break; - } - } - - ////////////////////////// - //- rjf: grab rdis - // - 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) - { - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], 0); - RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0); - rdis[idx] = rdi; - } - } - - //- rjf: gather locals - if(flags & RD_ListerFlag_Locals) - { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr); - DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); - E_String2NumMap *locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - E_String2NumMap *member_map = d_query_cached_member_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff); - for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - for(E_String2NumMapNode *n = member_map->first; n != 0; n = n->order_next) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, n->string); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = n->string, - .kind_name = str8_lit("Local (Member)"), - .display_name = n->string, - .display_name__matches = display_name__matches); - } - } - } - - //- rjf: gather registers - if(flags & RD_ListerFlag_Registers) - { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - Arch arch = thread->arch; - U64 reg_names_count = regs_reg_code_count_from_arch(arch); - U64 alias_names_count = regs_alias_code_count_from_arch(arch); - String8 *reg_names = regs_reg_code_string_table_from_arch(arch); - String8 *alias_names = regs_alias_code_string_table_from_arch(arch); - for(U64 idx = 0; idx < reg_names_count; idx += 1) - { - if(reg_names[idx].size != 0) - { - String8 display_name = reg_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Register"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - for(U64 idx = 0; idx < alias_names_count; idx += 1) - { - if(alias_names[idx].size != 0) - { - String8 display_name = alias_names[idx]; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Reg. Alias"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //- rjf: gather view rules - if(flags & RD_ListerFlag_ViewRules) - { - for(U64 slot_idx = 0; slot_idx < d_state->view_rule_spec_table_size; slot_idx += 1) - { - for(D_ViewRuleSpec *spec = d_state->view_rule_spec_table[slot_idx]; spec != 0 && spec != &d_nil_core_view_rule_spec; spec = spec->hash_next) - { - String8 display_name = spec->info.string; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - String8 description = spec->info.description; - FuzzyMatchRangeList description__matches = fuzzy_match_find(arena, needle, description); - if(display_name__matches.count == display_name__matches.needle_part_count || - description__matches.count == description__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("View Rule"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .description = description, - .description__matches = description__matches); - } - } - } - } - - //- rjf: gather members - if(flags & RD_ListerFlag_Members) - { - // TODO(rjf) - } - - //- rjf: gather globals - if(flags & RD_ListerFlag_Globals && needle.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_GlobalVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Global"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather thread locals - if(flags & RD_ListerFlag_ThreadLocals && needle.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_ThreadVariables, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Thread Local"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather procedures - if(flags & RD_ListerFlag_Procedures && needle.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_Procedures, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Procedure"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather types - if(flags & RD_ListerFlag_Types && needle.size != 0) - { - U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; - DI_SearchParams search_params = - { - RDI_SectionKind_UDTs, - dbgi_keys, - }; - B32 is_stale = 0; - DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, needle, 0, &is_stale); - for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) - { - // rjf: skip bad elements - if(items.v[idx].dbgi_idx >= rdis_count) - { - continue; - } - - // rjf: unpack info - RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; - String8 display_name = di_search_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); - FuzzyMatchRangeList display_name__matches = items.v[idx].match_ranges; - - // rjf: push item - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Type"), - .display_name = display_name, - .display_name__matches = display_name__matches, - .group = 1); - } - } - - //- rjf: gather languages - if(flags & RD_ListerFlag_Languages) - { - for EachNonZeroEnumVal(TXT_LangKind, lang) - { - String8 display_name = txt_extension_from_lang_kind(lang); - if(display_name.size != 0) - { - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Language"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - } - - //- rjf: gather architectures - if(flags & RD_ListerFlag_Architectures) - { - for EachNonZeroEnumVal(Arch, arch) - { - String8 display_name = string_from_arch(arch); - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("Architecture"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - - //- rjf: gather tex2dformats - if(flags & RD_ListerFlag_Tex2DFormats) - { - for EachEnumVal(R_Tex2DFormat, fmt) - { - String8 display_name = lower_from_str8(scratch.arena, r_tex2d_format_display_string_table[fmt]); - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("2D Texture Format"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } - - //- rjf: gather view rule params -#if 0 // TODO(rjf): @cfg (lister) - if(flags & RD_ListerFlag_ViewRuleParams) - { - for(String8Node *n = strings.first; n != 0; n = n->next) - { - String8 display_name = n->string; - FuzzyMatchRangeList display_name__matches = fuzzy_match_find(arena, needle, display_name); - if(display_name__matches.count == display_name__matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = display_name, - .kind_name = str8_lit("View Rule Parameter"), - .display_name = display_name, - .display_name__matches = display_name__matches); - } - } - } -#endif - - //- rjf: gather files - if(flags & RD_ListerFlag_Files) - { - // rjf: find containing directory in needle_path - String8 dir_str_in_input = {0}; - for(U64 i = 0; i < needle_path.size; i += 1) - { - String8 substr1 = str8_substr(needle_path, r1u64(i, i+1)); - String8 substr2 = str8_substr(needle_path, r1u64(i, i+2)); - String8 substr3 = str8_substr(needle_path, r1u64(i, i+3)); - if(str8_match(substr1, str8_lit("/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); - } - else if(i != 0 && str8_match(substr2, str8_lit(":/"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(needle_path, r1u64(i-1, needle_path.size)); - } - else if(str8_match(substr2, str8_lit("./"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); - } - else if(str8_match(substr3, str8_lit("../"), StringMatchFlag_SlashInsensitive)) - { - dir_str_in_input = str8_substr(needle_path, r1u64(i, needle_path.size)); - } - if(dir_str_in_input.size != 0) - { - break; - } - } - - // rjf: use needle_path string to form various parts of search space - String8 prefix = {0}; - String8 path = {0}; - String8 search = {0}; - if(dir_str_in_input.size != 0) - { - String8 dir = dir_str_in_input; - U64 one_past_last_slash = dir.size; - for(U64 i = 0; i < dir_str_in_input.size; i += 1) - { - if(dir_str_in_input.str[i] == '/' || dir_str_in_input.str[i] == '\\') - { - one_past_last_slash = i+1; - } - } - dir.size = one_past_last_slash; - path = dir; - search = str8_substr(dir_str_in_input, r1u64(one_past_last_slash, dir_str_in_input.size)); - prefix = str8_substr(needle_path, r1u64(0, path.str - needle_path.str)); - } - - // rjf: get current files, filtered - if(dir_str_in_input.size != 0) - { - B32 allow_dirs = 1; - OS_FileIter *it = os_file_iter_begin(scratch.arena, path, 0); - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) - { - FuzzyMatchRangeList match_ranges = fuzzy_match_find(arena, search, info.name); - B32 fits_search = (match_ranges.count == match_ranges.needle_part_count); - B32 fits_dir_only = (allow_dirs || !(info.props.flags & FilePropertyFlag_IsFolder)); - if(fits_search && fits_dir_only) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .string = info.name, - .kind_name = info.props.flags & FilePropertyFlag_IsFolder ? str8_lit("Folder") : str8_lit("File"), - .display_name = info.name, - .icon_kind = info.props.flags & FilePropertyFlag_IsFolder ? RD_IconKind_FolderClosedFilled : RD_IconKind_FileOutline, - .display_name__matches = match_ranges, - .flags = RD_ListerItemFlag_IsNonCode); - } - } - os_file_iter_end(it); - } - } - - //- rjf: gather commands - if(flags & RD_ListerFlag_Commands) - { - for EachNonZeroEnumVal(RD_CmdKind, k) - { - RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - B32 included_by_filter_string = 0; - for(String8Node *n = ctx_filter_strings.first; n != 0; n = n->next) - { - B32 n_match = (str8_find_needle(info->ctx_filter, 0, n->string, 0) < info->ctx_filter.size); - if(n_match) - { - included_by_filter_string = 1; - break; - } - } - if(ctx_filter_strings.node_count == 0 || included_by_filter_string) - { - String8 cmd_display_name = info->display_name; - String8 cmd_desc = info->description; - String8 cmd_tags = info->search_tags; - FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, cmd_display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(arena, needle, cmd_desc); - FuzzyMatchRangeList tags_matches = fuzzy_match_find(arena, needle, cmd_tags); - if(name_matches.count == name_matches.needle_part_count || - desc_matches.count == name_matches.needle_part_count || - tags_matches.count > 0 || - name_matches.needle_part_count == 0) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .icon_kind = info->icon_kind, - .string = info->string, - .kind_name = str8_lit("Command"), - .display_name = cmd_display_name, - .display_name__matches = name_matches, - .description = cmd_desc, - .description__matches = desc_matches, - .flags = RD_ListerItemFlag_IsNonCode|RD_ListerItemFlag_Bindings); - } - } - } - } - - //- rjf: gather settings - if(flags & RD_ListerFlag_Settings) - { -#if 0 // TODO(rjf): @cfg (lister) - String8List schema_strings = {0}; - - // rjf: push schema for view - { - RD_Cfg *view = rd_cfg_from_id(regs->view); - String8 view_name = view->string; - RD_ViewRuleInfo *view_rule_info = rd_view_rule_info_from_string(view_name); - str8_list_push(scratch.arena, &schema_strings, view_rule_info->params_schema); - } - - // rjf: for each schema, gather parameters - for(String8Node *n = schema_strings.first; n != 0; n = n->next) - { - MD_Node *schema = md_tree_from_string(scratch.arena, n->string)->first; - for MD_EachNode(param, schema->first) - { - RD_VocabInfo *param_vocab_info = rd_vocab_info_from_code_name(param->string); - String8 name = param_vocab_info->display_name; - RD_IconKind icon_kind = param_vocab_info->icon_kind; - FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); - if(name_matches.count == name_matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .icon_kind = icon_kind, - .string = param->string, - .kind_name = str8_lit("Setting"), - .display_name = name, - .display_name__matches = name_matches, - .flags = RD_ListerItemFlag_IsNonCode); - } - } - } -#endif - } - - //- rjf: gather system processes - if(flags & RD_ListerFlag_SystemProcesses) - { - U32 this_process_pid = os_get_process_info()->pid; - DMN_ProcessIter iter = {0}; - dmn_process_iter_begin(&iter); - for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) - { - if(info.pid == this_process_pid) - { - continue; - } - String8 name = push_str8f(scratch.arena, "%S (PID: %i)", info.name, info.pid); - FuzzyMatchRangeList name_matches = fuzzy_match_find(arena, needle, name); - if(name_matches.count == name_matches.needle_part_count) - { - rd_lister_item_chunk_list_push_new(scratch.arena, &item_list, 256, - .icon_kind = RD_IconKind_Threads, - .string = name, - .kind_name = str8_lit("System Process"), - .display_name = name, - .display_name__matches = name_matches, - .flags = RD_ListerItemFlag_IsNonCode); - } - } - dmn_process_iter_end(&iter); - } - - //- rjf: lister item list -> sorted array - RD_ListerItemArray item_array = rd_lister_item_array_from_chunk_list(arena, &item_list); - rd_lister_item_array_sort__in_place(&item_array); -#endif - RD_ListerItemArray item_array = {0}; - di_scope_close(di_scope); - scratch_end(scratch); - return item_array; -} - -internal U64 -rd_hash_from_lister_item(RD_ListerItem *item) -{ - U64 item_hash = 5381; - item_hash = d_hash_from_seed_string(item_hash, item->string); - item_hash = d_hash_from_seed_string(item_hash, item->kind_name); - item_hash = d_hash_from_seed_string(item_hash, str8_struct(&item->group)); - return item_hash; -} - internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) { @@ -10419,190 +9712,17 @@ rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) return path; } -#if 0 // TODO(rjf): @cfg (lister) - -internal RD_ListerParams -rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off) -{ - RD_ListerParams params = {0}; - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: do partial parse of input - MD_TokenizeResult input_tokenize = md_tokenize_from_text(scratch.arena, string); - - //- rjf: find descension steps to cursor - typedef struct DescendStep DescendStep; - struct DescendStep - { - DescendStep *next; - DescendStep *prev; - String8 string; - }; - DescendStep *first_step = 0; - DescendStep *last_step = 0; - DescendStep *free_step = 0; - S32 paren_nest = 0; - S32 colon_nest = 0; - String8 last_step_string = {0}; - for(U64 idx = 0; idx < input_tokenize.tokens.count; idx += 1) - { - MD_Token *token = &input_tokenize.tokens.v[idx]; - if(token->range.min >= cursor_off) - { - break; - } - String8 token_string = str8_substr(string, token->range); - if(token->flags & (MD_TokenFlag_Identifier|MD_TokenFlag_StringLiteral)) - { - last_step_string = token_string; - } - if(str8_match(token_string, str8_lit("("), 0) || str8_match(token_string, str8_lit("["), 0) || str8_match(token_string, str8_lit("{"), 0)) - { - paren_nest += 1; - } - if(str8_match(token_string, str8_lit(")"), 0) || str8_match(token_string, str8_lit("]"), 0) || str8_match(token_string, str8_lit("}"), 0)) - { - paren_nest -= 1; - for(;colon_nest > paren_nest; colon_nest -= 1) - { - if(last_step != 0) - { - DescendStep *step = last_step; - DLLRemove(first_step, last_step, step); - SLLStackPush(free_step, step); - } - } - if(paren_nest == 0 && last_step != 0) - { - DescendStep *step = last_step; - DLLRemove(first_step, last_step, step); - SLLStackPush(free_step, step); - } - } - if(str8_match(token_string, str8_lit(":"), 0)) - { - colon_nest += 1; - if(last_step_string.size != 0) - { - DescendStep *step = free_step; - if(step != 0) - { - SLLStackPop(free_step); - MemoryZeroStruct(step); - } - else - { - step = push_array(scratch.arena, DescendStep, 1); - } - step->string = last_step_string; - DLLPushBack(first_step, last_step, step); - } - } - if(str8_match(token_string, str8_lit(";"), 0) || str8_match(token_string, str8_lit(","), 0)) - { - for(;colon_nest > paren_nest; colon_nest -= 1) - { - if(last_step != 0) - { - DescendStep *step = last_step; - DLLRemove(first_step, last_step, step); - SLLStackPush(free_step, step); - } - } - } - } - - //- rjf: map view rule root to spec - D_ViewRuleSpec *spec = d_view_rule_spec_from_string(first_step ? first_step->string : str8_zero()); - - //- rjf: do parse of schema - MD_TokenizeResult schema_tokenize = md_tokenize_from_text(scratch.arena, spec->info.schema); - MD_ParseResult schema_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), spec->info.schema, schema_tokenize.tokens); - MD_Node *schema_rule_root = md_child_from_string(schema_parse.root, str8_lit("x"), 0); - - //- rjf: follow schema according to descend steps, gather flags from schema node matching cursor descension steps - if(first_step != 0) - { - MD_Node *schema_node = schema_rule_root; - for(DescendStep *step = first_step->next;;) - { - if(step == 0) - { - for MD_EachNode(child, schema_node->first) - { - if(0){} - else if(str8_match(child->string, str8_lit("expr"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Locals;} - else if(str8_match(child->string, str8_lit("member"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Members;} - else if(str8_match(child->string, str8_lit("lang"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Languages;} - else if(str8_match(child->string, str8_lit("arch"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Architectures;} - else if(str8_match(child->string, str8_lit("tex2dformat"), StringMatchFlag_CaseInsensitive)) {params.flags |= RD_ListerFlag_Tex2DFormats;} - else if(child->flags & (MD_NodeFlag_StringSingleQuote|MD_NodeFlag_StringDoubleQuote|MD_NodeFlag_StringTick)) - { - str8_list_push(arena, ¶ms.strings, child->string); - params.flags |= RD_ListerFlag_ViewRuleParams; - } - } - break; - } - if(step != 0) - { - MD_Node *next_node = md_child_from_string(schema_node, step->string, StringMatchFlag_CaseInsensitive); - schema_node = next_node; - step = step->next; - } - else - { - schema_node = schema_node->first; - } - } - } - - scratch_end(scratch); - } - return params; -} - internal void -rd_set_autocomp_lister_query_(RD_ListerParams *params) +rd_set_autocomp_regs_(RD_Regs *regs) { RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - arena_clear(ws->lister_arena); - ws->lister_regs = rd_regs_copy(ws->lister_arena, rd_regs()); - MemoryCopyStruct(&ws->lister_params, params); - ws->lister_params.strings = str8_list_copy(ws->lister_arena, &ws->lister_params.strings); - if(!(params->flags & RD_ListerFlag_LineEdit)) + if(ws->autocomp_last_frame_index < rd_state->frame_index) { - ws->lister_input_size = Min(params->input.size, sizeof(ws->lister_input_buffer)); - MemoryCopy(ws->lister_input_buffer, params->input.str, ws->lister_input_size); + ws->autocomp_last_frame_index = rd_state->frame_index; + arena_clear(ws->autocomp_arena); + ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); } - ws->lister_last_frame_idx = rd_state->frame_index; -} - -#endif - -internal void -rd_set_autocomp_lister_query_(RD_Regs *regs) -{ - RD_Cfg *window_cfg = rd_cfg_from_id(regs->window); - RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); - if(ws->autocomp_lister == 0) - { - Arena *arena = arena_alloc(); - ws->autocomp_lister = push_array(arena, RD_Lister, 1); - ws->autocomp_lister->arena = arena; - } - Arena *arena = ws->autocomp_lister->arena; - arena_clear(arena); - ws->autocomp_lister = push_array(arena, RD_Lister, 1); - ws->autocomp_lister->arena = arena; - ws->autocomp_lister->regs = rd_regs_copy(arena, regs); - ws->autocomp_lister->input_string_size = Min(regs->string.size, sizeof(ws->autocomp_lister->input_buffer)); - MemoryCopy(ws->autocomp_lister->input_buffer, regs->string.str, ws->autocomp_lister->input_string_size); - ws->autocomp_lister->input_cursor = regs->cursor; - ws->autocomp_lister->input_mark = regs->mark; - ws->autocomp_lister_last_frame_idx = rd_state->frame_index; } //////////////////////////////// @@ -11570,14 +10690,6 @@ rd_frame(void) ui_state_release(ws->ui); r_window_unequip(ws->os, ws->r); os_window_close(ws->os); - if(ws->autocomp_lister != 0) - { - arena_release(ws->autocomp_lister->arena); - } - for(RD_Lister *lister = ws->top_query_lister; lister != 0; lister = lister->next) - { - arena_release(lister->arena); - } arena_release(ws->drop_completion_arena); arena_release(ws->query_arena); arena_release(ws->hover_eval_arena); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5c76fa6d..0c0bae25 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -413,72 +413,6 @@ typedef enum RD_FontSlot } RD_FontSlot; -//////////////////////////////// -//~ rjf: Lister Types - -typedef U32 RD_ListerItemFlags; -enum -{ - RD_ListerItemFlag_IsNonCode = (1<<0), - RD_ListerItemFlag_Bindings = (1<<1), - RD_ListerItemFlag_Autocompletion = (1<<2), -}; - -typedef struct RD_ListerItem RD_ListerItem; -struct RD_ListerItem -{ - RD_ListerItemFlags flags; - RD_IconKind icon_kind; - String8 string; - String8 kind_name; - String8 display_name; - String8 description; - String8 search_tags; - FuzzyMatchRangeList kind_name__matches; - FuzzyMatchRangeList display_name__matches; - FuzzyMatchRangeList description__matches; - U64 group; -}; - -typedef struct RD_ListerItemChunkNode RD_ListerItemChunkNode; -struct RD_ListerItemChunkNode -{ - RD_ListerItemChunkNode *next; - RD_ListerItem *v; - U64 count; - U64 cap; -}; - -typedef struct RD_ListerItemChunkList RD_ListerItemChunkList; -struct RD_ListerItemChunkList -{ - RD_ListerItemChunkNode *first; - RD_ListerItemChunkNode *last; - U64 chunk_count; - U64 total_count; -}; - -typedef struct RD_ListerItemArray RD_ListerItemArray; -struct RD_ListerItemArray -{ - RD_ListerItem *v; - U64 count; -}; - -typedef struct RD_Lister RD_Lister; -struct RD_Lister -{ - RD_Lister *next; - Arena *arena; - RD_Regs *regs; - UI_ScrollPt scroll_pt; - U64 selected_item_hash; - U8 input_buffer[1024]; - U64 input_string_size; - TxtPt input_cursor; - TxtPt input_mark; -}; - //////////////////////////////// //~ rjf: Per-Window State @@ -519,11 +453,6 @@ struct RD_WindowState B32 menu_bar_key_held; B32 menu_bar_focus_press_started; - // rjf: lister state - RD_Lister *top_query_lister; - RD_Lister *autocomp_lister; - U64 autocomp_lister_last_frame_idx; - // rjf: drop-completion state Arena *drop_completion_arena; String8List drop_completion_paths; @@ -1022,29 +951,10 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //////////////////////////////// //~ rjf: Autocompletion Lister -internal void rd_set_autocomp_regs_(RD_Regs *regs); -#define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) - -//////////////////////////////// -//~ rjf: Lister Functions - -internal void rd_lister_item_chunk_list_push(Arena *arena, RD_ListerItemChunkList *list, U64 cap, RD_ListerItem *item); -#define rd_lister_item_chunk_list_push_new(arena, list, cap, ...) rd_lister_item_chunk_list_push((arena), (list), (cap), &(RD_ListerItem){.string = {0}, __VA_ARGS__}) -internal RD_ListerItemArray rd_lister_item_array_from_chunk_list(Arena *arena, RD_ListerItemChunkList *list); -internal int rd_lister_item_qsort_compare(RD_ListerItem *a, RD_ListerItem *b); -internal void rd_lister_item_array_sort__in_place(RD_ListerItemArray *array); -internal RD_ListerItemArray rd_lister_item_array_from_regs_needle_cursor_off(Arena *arena, RD_Regs *regs, String8 needle, U64 cursor_off); -internal U64 rd_hash_from_lister_item(RD_ListerItem *item); - internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); -#if 0 // TODO(rjf): @cfg (lister) -internal RD_ListerParams rd_view_rule_lister_params_from_input_cursor(Arena *arena, String8 string, U64 cursor_off); -internal void rd_set_autocomp_lister_query_(RD_ListerParams *params); -#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_ListerParams){.flags = 0, __VA_ARGS__}) -#endif -internal void rd_set_autocomp_lister_query_(RD_Regs *regs); -#define rd_set_autocomp_lister_query(...) rd_set_autocomp_lister_query_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) +internal void rd_set_autocomp_regs_(RD_Regs *regs); +#define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) //////////////////////////////// //~ rjf: Colors, Fonts, Config From 78928974cb0080ac1c0b8b8f6fcbd874fffc9e63 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 16:38:25 -0700 Subject: [PATCH 516/755] implicit member access path --- src/eval/eval_ir.c | 70 ++++++++++++++++++---------------------- src/raddbg/raddbg_core.c | 9 +----- 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 1dd39122..3652884d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1564,34 +1564,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } } - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_strings = {0}; - if(!string_mapped) - { - E_Module *module = e_base_ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_cache->thread_ip_procedure; - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); - str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try to map name as member - if found, string__redirected := "this", and turn + //- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn // on later implicit-member-lookup generation B32 string_is_implicit_member_name = 0; if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) @@ -1734,6 +1707,33 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } } + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_strings = {0}; + if(!string_mapped) + { + E_Module *module = e_base_ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); + str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + //- rjf: try globals if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) { @@ -1952,17 +1952,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } } - //- rjf: extend generation with member access, if original string was an - // implicit member access - if(generated && string_is_implicit_member_name) + //- rjf: extend generated result, if result was generated by an implicit member access + if(string_is_implicit_member_name) { - // TODO(rjf): @cfg -#if 0 - E_LookupRule *lookup_rule = &e_lookup_rule__default; - E_LookupInfo lookup_info = lookup_rule->info(arena, &result, &e_expr_nil, str8_zero()); - E_LookupAccess lookup_access = lookup_rule->access(arena, E_ExprKind_MemberAccess, lhs, rhs, &e_expr_nil, lookup_info.user_data); - result = lookup_access.irtree_and_type; -#endif + E_Expr *access = e_expr_irext_member_access(arena, &e_expr_nil, &result, string); + result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, access); } //- rjf: error on failure-to-generate diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8398ea5c..90c2fcbb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4934,13 +4934,6 @@ rd_view_ui(Rng2F32 rect) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); rd_set_autocomp_regs(.ui_key = sig.box->key, .string = input, .cursor = cell_edit_state->cursor); -#if 0 // TODO(rjf): @cfg (autocompletion) - rd_set_autocomp_lister_query(.ui_key = sig.box->key, - .off_px = v2f32(0, dim_2f32(sig.box->rect).y), - .string = input, - .cursor = cell_edit_state->cursor, - .lister_flags = cell_autocomp_flags); -#endif } } } @@ -6631,7 +6624,7 @@ rd_window_frame(void) RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); rd_cfg_new_replace(input, ws->autocomp_regs->string); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replacef(expr, "query:locals, query:procedures, query:types"); + rd_cfg_new_replacef(expr, "query:locals, query:globals, query:thread_locals, query:procedures, query:types"); // rjf: determine container size EV_BlockTree predicted_block_tree = {0}; From fd6637b87b2ade65c902d9516f05a5ddd20a302d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 16:41:01 -0700 Subject: [PATCH 517/755] more dead code elimination --- .../eval_visualization_core.c | 75 ------------------- .../eval_visualization_core.h | 7 -- src/raddbg/raddbg_core.c | 34 --------- src/raddbg/raddbg_core.h | 1 - 4 files changed, 117 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 0b6edc45..f40fa4c4 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -465,81 +465,6 @@ ev_expand_rule_from_type_key(E_TypeKey type_key) return rule; } -//////////////////////////////// -//~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) - -#if 0 // TODO(rjf): @cfg (dynamic type resolution) -internal E_Expr * -ev_resolved_from_expr(Arena *arena, E_Expr *expr) -{ - ProfBeginFunction(); - { - Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_expr(scratch.arena, expr); - E_TypeKey type_key = eval.type_key; - E_TypeKind type_kind = e_type_kind_from_key(type_key); - E_TypeKey ptee_type_key = e_type_unwrap(e_type_key_direct(e_type_unwrap(type_key))); - E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key); - if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class) - { - E_Type *ptee_type = e_type_from_key__cached(ptee_type_key); - B32 has_vtable = 0; - for(U64 idx = 0; idx < ptee_type->count; idx += 1) - { - if(ptee_type->members[idx].kind == E_MemberKind_VirtualMethod) - { - has_vtable = 1; - break; - } - } - if(has_vtable) - { - U64 ptr_vaddr = eval.value.u64; - U64 addr_size = e_type_byte_size_from_key(e_type_unwrap(type_key)); - U64 class_base_vaddr = 0; - U64 vtable_vaddr = 0; - if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && - e_space_read(eval.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) - { - Arch arch = e_base_ctx->primary_module->arch; - U32 rdi_idx = 0; - RDI_Parsed *rdi = 0; - U64 module_base = 0; - for(U64 idx = 0; idx < e_base_ctx->modules_count; idx += 1) - { - if(contains_1u64(e_base_ctx->modules[idx].vaddr_range, vtable_vaddr)) - { - arch = e_base_ctx->modules[idx].arch; - rdi_idx = (U32)idx; - rdi = e_base_ctx->modules[idx].rdi; - module_base = e_base_ctx->modules[idx].vaddr_range.min; - break; - } - } - if(rdi != 0) - { - U64 vtable_voff = vtable_vaddr - module_base; - U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, vtable_voff); - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx); - if(global_var->link_flags & RDI_LinkFlag_TypeScoped) - { - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx); - RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); - E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx); - E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 1, 0); - expr = e_expr_irext_cast(arena, ptr_to_derived_type_key); - } - } - } - } - } - scratch_end(scratch); - } - ProfEnd(); - return expr; -} -#endif - //////////////////////////////// //~ rjf: Block Building diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index e4bccf36..22341675 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -342,13 +342,6 @@ internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); internal EV_ExpandRule *ev_expand_rule_from_type_key(E_TypeKey type_key); -//////////////////////////////// -//~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) - -#if 0 // TODO(rjf): @cfg (dynamic type resolution) -internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); -#endif - //////////////////////////////// //~ rjf: Block Building diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 90c2fcbb..c97eaae5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9671,40 +9671,6 @@ rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) return query; } -internal String8 -rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off) -{ - // rjf: find start of path - U64 path_start_off = 0; - { - B32 single_quoted = 0; - B32 double_quoted = 0; - for(U64 off = 0; off < input.size && off < cursor_off; off += 1) - { - if(input.str[off] == '\'') - { - single_quoted ^= 1; - } - if(input.str[off] == '\"') - { - double_quoted ^= 1; - } - if(char_is_space(input.str[off]) && !single_quoted && !double_quoted) - { - path_start_off = off+1; - } - } - } - - // rjf: form path - String8 path = str8_skip(str8_prefix(input, cursor_off), path_start_off); - if(path.size >= 1 && path.str[0] == '"') { path = str8_skip(path, 1); } - if(path.size >= 1 && path.str[0] == '\'') { path = str8_skip(path, 1); } - if(path.size >= 1 && path.str[path.size-1] == '"') { path = str8_chop(path, 1); } - if(path.size >= 1 && path.str[path.size-1] == '\'') { path = str8_chop(path, 1); } - return path; -} - internal void rd_set_autocomp_regs_(RD_Regs *regs) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 0c0bae25..bb05d6ed 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -952,7 +952,6 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //~ rjf: Autocompletion Lister internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); -internal String8 rd_lister_query_path_from_input_string_off(String8 input, U64 cursor_off); internal void rd_set_autocomp_regs_(RD_Regs *regs); #define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) From c199ea61580c0ac7e8d64a2781e2d9bf800cb7bf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 16:48:23 -0700 Subject: [PATCH 518/755] fix empty case in autocompletion lister building --- src/raddbg/raddbg_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c97eaae5..9dea90cb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6632,6 +6632,7 @@ rd_window_frame(void) { String8 expr = rd_expr_from_cfg(view); E_Eval list_eval = e_eval_from_string(expr); + ev_key_set_expansion(rd_view_eval_view(), ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), rd_view_query_input(), list_eval); } F32 row_height_px = ui_top_px_height(); @@ -6652,6 +6653,7 @@ rd_window_frame(void) } // rjf: push task + if(predicted_block_tree.total_row_count > 1) { FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); SLLQueuePush(first_floating_view_task, last_floating_view_task, t); @@ -6740,6 +6742,7 @@ rd_window_frame(void) EV_BlockTree predicted_block_tree = {0}; RD_RegsScope(.view = view->id, .tab = 0) { + ev_key_set_expansion(rd_view_eval_view(), ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); } F32 row_height_px = ui_top_px_height(); @@ -6888,6 +6891,7 @@ rd_window_frame(void) F32 row_height_px = ui_top_font_size() * rd_setting_f32_from_name(str8_lit("row_height")); Vec2F32 content_rect_center = center_2f32(content_rect); Vec2F32 content_rect_dim = dim_2f32(content_rect); + ev_key_set_expansion(rd_view_eval_view(), ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); EV_BlockTree predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), rd_view_query_input(), query_eval); F32 query_width_px = floor_f32(content_rect_dim.x * 0.35f); F32 max_query_height_px = content_rect_dim.y*0.8f; From 58a3a364cf640598fa1b64b482d01b5b03e3664e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 16:55:56 -0700 Subject: [PATCH 519/755] sketch out autocompletion lister usage in query bars --- src/raddbg/raddbg_core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9dea90cb..cf7be839 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2620,6 +2620,13 @@ rd_view_ui(Rng2F32 rect) UI_Transparency(1-search_row_open_t) { UI_Signal sig = rd_cellf(¶ms, "###search"); + // TODO(rjf) +#if 0 + if(ui_is_focus_active()) + { + rd_set_autocomp_regs(.ui_key = sig.box->key, .string = str8(vs->query_buffer, vs->query_string_size), .cursor = vs->query_cursor); + } +#endif if(ui_pressed(sig)) { vs->query_is_selected = 1; From b0dd7700d7112c3154d1c611339b9bc7d36c163e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 30 Apr 2025 17:04:10 -0700 Subject: [PATCH 520/755] apply autocasting below the ir-tree generation level of lens calls, so that we don't accidentally strip away lenses --- src/eval/eval_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 3652884d..c3707912 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2173,7 +2173,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: if the evaluated type has a virtual table pointer, then we must // pre-emptively evaluate this ir tree, and determine a more resolved type. { - E_TypeKey type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKey type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Modifiers); if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(type_key))) { E_TypeKey ptee_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_All); From f73ef86a5449f6adb23e30f5693013e704aad783 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 07:36:34 -0700 Subject: [PATCH 521/755] fix row command query spawning rules --- src/raddbg/raddbg_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cf7be839..8baa3315 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5038,9 +5038,15 @@ rd_view_ui(Rng2F32 rect) { cfg = rd_cfg_from_eval_space(row->block->eval.space); } + if(entity == &ctrl_entity_nil) + { + entity = rd_ctrl_entity_from_eval_space(row->eval.space); + } RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) { - if(!(cmd_kind_info->query.flags & RD_QueryFlag_Required)) + if(!(cmd_kind_info->query.flags & RD_QueryFlag_Required) || + (cmd_kind_info->query.slot == RD_RegSlot_Cfg && cfg != &rd_nil_cfg) || + (cmd_kind_info->query.slot == RD_RegSlot_CtrlEntity && entity != &ctrl_entity_nil)) { rd_push_cmd(cell_info.cmd_name, rd_regs()); } From 91be06dea9df98a1f25ec75edfa956f48169ac3b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 07:50:46 -0700 Subject: [PATCH 522/755] fix single-line string value stringification; expand commands for tabs --- .../eval_visualization_core.c | 25 +++++++++++++------ src/raddbg/generated/raddbg.meta.c | 4 +-- src/raddbg/raddbg.mdesk | 5 +++- src/raddbg/raddbg_core.c | 9 +++++++ 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index f40fa4c4..96fedb41 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1775,18 +1775,27 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) Temp scratch = scratch_begin(&arena, 1); // rjf: read string data +#define EV_STRING_ITER_STRING_BUFFER_CAPACITY 4096 U64 string_memory_addr = ptr_data->value_eval.value.u64; - U64 string_buffer_size = 4096; + U64 string_buffer_size = EV_STRING_ITER_STRING_BUFFER_CAPACITY; U8 *string_buffer = push_array(scratch.arena, U8, string_buffer_size); - for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) + if(type_kind == E_TypeKind_Array && ptr_data->value_eval.irtree.mode == E_Mode_Value) { - B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); - if(read_good) - { - break; - } + StaticAssert(sizeof(ptr_data->value_eval.value.u512.u8) <= EV_STRING_ITER_STRING_BUFFER_CAPACITY, ev_string_iter_value_string_buffer_size_check); + MemoryCopy(string_buffer, ptr_data->value_eval.value.u512.u8, sizeof(ptr_data->value_eval.value.u512.u8)); + } + else + { + for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) + { + B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); + if(read_good) + { + break; + } + } + string_buffer[string_buffer_size-1] = 0; } - string_buffer[string_buffer_size-1] = 0; // rjf: check element size - if non-U8, assume UTF-16 or UTF-32 based on type, and convert U64 element_size = ptr_data->direct_type->byte_size; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8683025c..0b45faa2 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -389,9 +389,9 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) x:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("x:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("@expand_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 06e9b746..1ab59b87 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -364,7 +364,9 @@ RD_VocabTable: { theme_color, ``` - @collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) x: + @collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) + @row_commands(remove_cfg) + x: { @display_name('Tags') tags: string, @display_name('Value') value: @color @hex u32, @@ -403,6 +405,7 @@ RD_VocabTable: { tab, ``` + @expand_commands(duplicate_tab, close_tab) x: { @default(11) @display_name('Tab Font Size') @description("Controls the tab's font size.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8baa3315..4523b634 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5044,6 +5044,15 @@ rd_view_ui(Rng2F32 rect) } RD_RegsScope(.cfg = cfg->id, .ctrl_entity = entity->handle) { + if(cfg != &rd_nil_cfg) + { + RD_PanelTree panels = rd_panel_tree_from_cfg(scratch.arena, cfg); + RD_PanelNode *parent_panel_node = rd_panel_node_from_tree_cfg(panels.root, cfg->parent); + if(parent_panel_node != &rd_nil_panel_node) + { + rd_regs()->tab = rd_regs()->view = cfg->id; + } + } if(!(cmd_kind_info->query.flags & RD_QueryFlag_Required) || (cmd_kind_info->query.slot == RD_RegSlot_Cfg && cfg != &rd_nil_cfg) || (cmd_kind_info->query.slot == RD_RegSlot_CtrlEntity && entity != &ctrl_entity_nil)) From 791187b1520f83fb423124ce2ff1b3552a1d0076 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 08:18:14 -0700 Subject: [PATCH 523/755] blank cell rendering fixes, autocompletion work, fix to value-string visualization, more fixes/tweaks --- .../eval_visualization_core.c | 8 +-- src/raddbg/raddbg_core.c | 56 ++++++++++++++++--- src/raddbg/raddbg_widgets.c | 4 +- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 96fedb41..da44fd0d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1776,16 +1776,16 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) // rjf: read string data #define EV_STRING_ITER_STRING_BUFFER_CAPACITY 4096 - U64 string_memory_addr = ptr_data->value_eval.value.u64; U64 string_buffer_size = EV_STRING_ITER_STRING_BUFFER_CAPACITY; U8 *string_buffer = push_array(scratch.arena, U8, string_buffer_size); - if(type_kind == E_TypeKind_Array && ptr_data->value_eval.irtree.mode == E_Mode_Value) + if(type_kind == E_TypeKind_Array && eval.irtree.mode == E_Mode_Value) { - StaticAssert(sizeof(ptr_data->value_eval.value.u512.u8) <= EV_STRING_ITER_STRING_BUFFER_CAPACITY, ev_string_iter_value_string_buffer_size_check); - MemoryCopy(string_buffer, ptr_data->value_eval.value.u512.u8, sizeof(ptr_data->value_eval.value.u512.u8)); + StaticAssert(sizeof(eval.value.u512.u8) <= EV_STRING_ITER_STRING_BUFFER_CAPACITY, ev_string_iter_value_string_buffer_size_check); + MemoryCopy(string_buffer, eval.value.u512.u8, sizeof(eval.value.u512.u8)); } else { + U64 string_memory_addr = ptr_data->value_eval.value.u64; for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) { B32 read_good = e_space_read(eval.space, string_buffer, r1u64(string_memory_addr, string_memory_addr+try_size)); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4523b634..8111b70d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4834,6 +4834,9 @@ rd_view_ui(Rng2F32 rect) RD_CellParams cell_params = {0}; ProfScope("form cell build parameters") { + E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); + B32 cells_are_editable = !!(block_type->flags & E_TypeFlag_EditableChildren); + // rjf: set up base parameters cell_params.flags = (RD_CellFlag_KeyboardClickable|RD_CellFlag_NoBackground|RD_CellFlag_CodeContents); cell_params.depth = (cell->flags & RD_WatchCellFlag_Indented ? row_depth : 0); @@ -4857,17 +4860,30 @@ rd_view_ui(Rng2F32 rect) } // rjf: apply expander (or substitute space) - if(row_is_expandable && cell == row_info->cells.first) + if(!ewv->text_editing || !cell_selected) { - cell_params.flags |= RD_CellFlag_Expander; + if(row_is_expandable && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_Expander; + } + else if(cells_are_editable && row_depth == !implicit_root && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderPlaceholder; + } + else if(row_depth != 0 && cell == row_info->cells.first) + { + cell_params.flags |= RD_CellFlag_ExpanderSpace; + } } - else if(row_depth == !implicit_root && cell == row_info->cells.first) + + // rjf: apply blank cell ghost text + if(row_info->cells.first == row_info->cells.last && + cells_are_editable && + row->eval.expr == &e_expr_nil) { - cell_params.flags |= RD_CellFlag_ExpanderSpace; - } - else if(row_depth != 0 && cell == row_info->cells.first) - { - cell_params.flags |= RD_CellFlag_ExpanderSpace; + ghost_text = str8_lit("Expression"); + is_non_code = (!cell_selected || !ewv->text_editing); + cell_params.flags &= ~(RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder); } // rjf: apply single-click-activation @@ -6629,6 +6645,7 @@ rd_window_frame(void) B32 pressed; B32 pressed_outside; }; + FloatingViewTask *autocomp_floating_view_task = 0; FloatingViewTask *hover_eval_floating_view_task = 0; FloatingViewTask *query_floating_view_task = 0; FloatingViewTask *first_floating_view_task = 0; @@ -6679,6 +6696,7 @@ rd_window_frame(void) { FloatingViewTask *t = push_array(scratch.arena, FloatingViewTask, 1); SLLQueuePush(first_floating_view_task, last_floating_view_task, t); + autocomp_floating_view_task = t; t->view = view; t->rect = rect; t->is_focused = 1; @@ -7085,6 +7103,28 @@ rd_window_frame(void) //- rjf: @window_ui_part do special handling of floating view interactions // { + //- rjf: autocompletion view early-closing rules + if(autocomp_floating_view_task) + { + B32 has_autocomplete_hint = 0; + B32 has_accept_operation = 0; + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_AutocompleteHint) + { + has_autocomplete_hint = 1; + } + if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept) + { + has_accept_operation = 1; + } + } + if(has_autocomplete_hint && has_accept_operation) + { + autocomp_floating_view_task->signal.box->transparency = 1; + } + } + //- rjf: hover eval focus rules if(hover_eval_floating_view_task) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 2bbe61d8..1fcd8b6e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3308,7 +3308,7 @@ rd_cell(RD_CellParams *params, String8 string) { if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) { - ui_spacer(ui_em(0.5f, 1.f)); + ui_spacer(ui_em(1.f, 1.f)); } UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(name_box, &lhs_name_fstrs); @@ -3318,7 +3318,7 @@ rd_cell(RD_CellParams *params, String8 string) { UI_Row { - ui_spacer(ui_em(0.5f, 1.f)); + ui_spacer(ui_em(1.f, 1.f)); UI_Box *desc_box = ui_label(params->description).box; FuzzyMatchRangeList desc_fuzzy_matches = fuzzy_match_find(scratch.arena, params->search_needle, params->description); ui_box_equip_fuzzy_match_ranges(desc_box, &desc_fuzzy_matches); From ed4fe5e3d114bc854a61865b7887f7dd33b10638 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 08:27:03 -0700 Subject: [PATCH 524/755] fix auto-downcasting to work in all cases --- src/eval/eval_ir.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index c3707912..cc1c2b17 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2172,6 +2172,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: if the evaluated type has a virtual table pointer, then we must // pre-emptively evaluate this ir tree, and determine a more resolved type. + if(!disallow_autohooks && result.mode != E_Mode_Null) { E_TypeKey type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Modifiers); if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(type_key))) @@ -2193,15 +2194,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } if(has_vtable) { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, result.root); + E_IRNode *class_base_value_tree = e_irtree_resolve_to_value(scratch.arena, result.mode, result.root, result.type_key); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, class_base_value_tree); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); - U64 ptr_vaddr = interpret.value.u64; - U64 addr_size = e_type_byte_size_from_key(type_key); - U64 class_base_vaddr = 0; + U64 class_base_vaddr = interpret.value.u64; U64 vtable_vaddr = 0; - if(e_space_read(interpret.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) && - e_space_read(interpret.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) + U64 addr_size = e_type_byte_size_from_key(type_key); + if(e_space_read(interpret.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size))) { Arch arch = e_base_ctx->primary_module->arch; U32 rdi_idx = 0; From 2a1e19ad2388fdbf46b908405ccb9108783c30cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 08:34:43 -0700 Subject: [PATCH 525/755] fix view-embedded query pushing - needs to apply to view, not simply tabs; fix schema-expansion command filtering --- src/raddbg/raddbg_core.c | 4 ++-- src/raddbg/raddbg_eval.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8111b70d..59865ca2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14314,10 +14314,10 @@ rd_frame(void) rd_cfg_new_replace(expr, rd_regs()->expr); } - // rjf: non-floating -> embed in tab parameter + // rjf: non-floating -> embed in view else { - view = rd_cfg_from_id(rd_regs()->tab); + view = rd_cfg_from_id(rd_regs()->view); } // rjf: determine if the target view is a lister (and thus already has a command) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7d11331e..a6e36a51 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -436,7 +436,16 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) MD_Node *tag = md_tag_from_string(schema, str8_lit("expand_commands"), 0); for MD_EachNode(arg, tag->first) { - str8_list_push(scratch.arena, &commands_list, arg->string); + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(arg->string); + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, rd_display_from_code_name(cmd_kind_info->string)); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, cmd_kind_info->description); + FuzzyMatchRangeList tags_matches = fuzzy_match_find(scratch.arena, filter, cmd_kind_info->search_tags); + if(name_matches.count == name_matches.needle_part_count || + desc_matches.count == desc_matches.needle_part_count || + tags_matches.count == tags_matches.needle_part_count) + { + str8_list_push(scratch.arena, &commands_list, arg->string); + } } } commands = str8_array_from_list(arena, &commands_list); From 3a46e66efa5c254100a655c73fa21de0a4b8f504 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 09:05:42 -0700 Subject: [PATCH 526/755] expand eval expression tree location info to being based on textual range, rather than just offset --- src/eval/eval_core.c | 12 +++--- src/eval/eval_core.h | 8 ++-- src/eval/eval_ir.c | 86 ++++++++++++---------------------------- src/eval/eval_ir.h | 2 - src/eval/eval_parse.c | 82 +++++++++++++++++++------------------- src/eval/eval_parse.h | 2 +- src/eval/eval_types.c | 6 --- src/raddbg/raddbg_core.c | 32 +++++++-------- 8 files changed, 94 insertions(+), 136 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index ba5f64de..18e8c407 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -129,25 +129,25 @@ e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) //~ rjf: Message Functions internal void -e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text) +e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, Rng1U64 range, String8 text) { E_Msg *msg = push_array(arena, E_Msg, 1); SLLQueuePush(msgs->first, msgs->last, msg); msgs->count += 1; msgs->max_kind = Max(kind, msgs->max_kind); msg->kind = kind; - msg->location = location; + msg->range = range; msg->text = text; } internal void -e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...) +e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, Rng1U64 range, char *fmt, ...) { va_list args; va_start(args, fmt); String8 text = push_str8fv(arena, fmt, args); va_end(args); - e_msg(arena, msgs, kind, location, text); + e_msg(arena, msgs, kind, range, text); } internal void @@ -173,7 +173,7 @@ e_msg_list_copy(Arena *arena, E_MsgList *src) E_MsgList dst = {0}; for(E_Msg *msg = src->first; msg != 0; msg = msg->next) { - e_msg(arena, &dst, msg->kind, msg->location, msg->text); + e_msg(arena, &dst, msg->kind, msg->range, msg->text); } return dst; } @@ -881,7 +881,7 @@ e_interpretation_from_bundle(E_CacheBundle *bundle) E_Interpretation interpret = e_interpret(bytecode); if(E_InterpretationCode_Good < interpret.code && interpret.code < E_InterpretationCode_COUNT) { - e_msg(e_cache->arena, &bundle->msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[interpret.code]); + e_msg(e_cache->arena, &bundle->msgs, E_MsgKind_InterpretationError, r1u64(0, 0), e_interpretation_code_display_strings[interpret.code]); } bundle->interpretation = interpret; bundle->space_gen = e_space_gen(interpret.space); diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index b1d2c3d7..3497abfd 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -32,7 +32,7 @@ struct E_Msg { E_Msg *next; E_MsgKind kind; - void *location; + Rng1U64 range; String8 text; }; @@ -253,7 +253,7 @@ struct E_Expr E_Expr *next; E_Expr *prev; E_Expr *ref; - void *location; + Rng1U64 range; E_ExprKind kind; E_Mode mode; E_Space space; @@ -1030,8 +1030,8 @@ internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); //////////////////////////////// //~ rjf: Message Functions -internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text); -internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...); +internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, Rng1U64 range, String8 text); +internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, Rng1U64 range, char *fmt, ...); internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push); internal E_MsgList e_msg_list_copy(Arena *arena, E_MsgList *src); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index cc1c2b17..0f77359e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -429,12 +429,12 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) // rjf: bad conditions? -> error if applicable, exit if(exprr->kind != E_ExprKind_LeafIdentifier) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->range, "Expected member name."); break; } else if(!r_found) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->range, "Could not find a member named `%S`.", exprr->string); break; } else if(l.root == &e_irnode_nil || @@ -447,7 +447,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) check_type_kind != E_TypeKind_Union && check_type_kind != E_TypeKind_Enum) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->range, "Cannot perform member access on this type."); break; } @@ -506,22 +506,22 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->range, "Cannot index into this type."); break; } else if(!e_type_kind_is_integer(r_restype_kind)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->range, "Cannot index with this type."); break; } else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->range, "Cannot index into pointers of zero-sized types."); break; } else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->range, "Cannot index into arrays of zero-sized types."); break; } @@ -699,12 +699,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 r_type_kind == E_TypeKind_LRef || r_type_kind == E_TypeKind_RRef)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference pointers of zero-sized types."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->range, "Cannot dereference pointers of zero-sized types."); break; } else if(r_type_direct_size == 0 && r_type_kind == E_TypeKind_Array) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference arrays of zero-sized types."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->range, "Cannot dereference arrays of zero-sized types."); break; } else if(r_type_kind != E_TypeKind_Array && @@ -712,7 +712,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 r_type_kind != E_TypeKind_LRef && r_type_kind != E_TypeKind_RRef) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->location, "Cannot dereference this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, r_expr->range, "Cannot dereference this type."); break; } @@ -800,7 +800,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); } - e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); + e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, text); break; } @@ -880,7 +880,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: bad conditions? -> error if applicable, exit if(!e_type_kind_is_integer(r_type_kind) || (r_type_size != 8 && r_type_size != 4 && r_type_size != 2)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Byteswapping this type is not supported."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Byteswapping this type is not supported."); break; } @@ -921,7 +921,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Cannot use this operator on this type."); break; } @@ -954,7 +954,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } else if(!rdi_eval_op_typegroup_are_compatible(op, r_type_group)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Cannot use this operator on this type."); break; } @@ -1086,7 +1086,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 if(!rdi_eval_op_typegroup_are_compatible(op, l_type_group) || !rdi_eval_op_typegroup_are_compatible(op, r_type_group)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Cannot use this operator on this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Cannot use this operator on this type."); break; } @@ -1238,7 +1238,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } else if(!e_type_kind_is_integer(c_type_kind) && c_type_kind != E_TypeKind_Bool) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Conditional term must be an integer or boolean type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Conditional term must be an integer or boolean type."); } // rjf: determine the resultant type - if the left/right types match, then we @@ -1326,7 +1326,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); } - e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text); + e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, text); break; } @@ -1357,7 +1357,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { E_Expr *callee = lhs->first->next; E_Expr *first_arg = e_expr_ref(arena, lhs->first); - E_Expr *call = e_push_expr(arena, E_ExprKind_Call, 0); + E_Expr *call = e_push_expr(arena, E_ExprKind_Call, r1u64(0, 0)); e_expr_push_child(call, callee); e_expr_push_child(call, first_arg); for(E_Expr *arg = lhs->next; arg != &e_expr_nil; arg = arg->next) @@ -1430,7 +1430,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: calling any other type? -> not valid else { - e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); + e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->range, "Calling this type is not supported."); } // rjf: strip overrides and lenses if needed @@ -1962,7 +1962,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: error on failure-to-generate if(!generated && !str8_match(string, str8_lit("$"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); + e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->range, "`%S` could not be found.", string); } scratch_end(scratch); @@ -2053,7 +2053,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } else { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->first->location, "Cannot apply an `unsigned` modifier to this type."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->first->range, "Cannot apply an `unsigned` modifier to this type."); } }break; case E_ExprKind_Ptr: @@ -2070,7 +2070,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; case E_ExprKind_Func: { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Function type expressions are currently not supported."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Function type expressions are currently not supported."); }break; //- rjf: definitions @@ -2081,7 +2081,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Left side of assignment must be an unused identifier."); } }break; } @@ -2502,8 +2502,8 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist) internal E_Expr * e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name) { - E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); + E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, r1u64(0, 0)); + E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->range); E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); lhs_bytecode->string = e_string_from_expr(arena, lhs, str8_zero()); lhs_bytecode->qualifier = lhs->qualifier; @@ -2511,43 +2511,9 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, r1u64(0, 0)); rhs->string = push_str8_copy(arena, member_name); e_expr_push_child(root, lhs_bytecode); e_expr_push_child(root, rhs); return root; } - -internal E_Expr * -e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0); - E_Expr *lhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, lhs->location); - E_OpList lhs_oplist = e_oplist_from_irtree(arena, lhs_irtree->root); - lhs_bytecode->string = e_string_from_expr(arena, lhs, str8_zero()); - lhs_bytecode->qualifier = lhs->qualifier; - lhs_bytecode->space = lhs->space; - lhs_bytecode->mode = lhs_irtree->mode; - lhs_bytecode->type_key = lhs_irtree->type_key; - lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0); - rhs->value.u64 = index; - e_expr_push_child(root, lhs_bytecode); - e_expr_push_child(root, rhs); - return root; -} - -internal E_Expr * -e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree) -{ - E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0); - E_Expr *rhs_bytecode = e_push_expr(arena, E_ExprKind_LeafBytecode, rhs->location); - E_OpList rhs_oplist = e_oplist_from_irtree(arena, rhs_irtree->root); - rhs_bytecode->string = e_string_from_expr(arena, rhs, str8_zero()); - rhs_bytecode->space = rhs->space; - rhs_bytecode->mode = rhs_irtree->mode; - rhs_bytecode->type_key = rhs_irtree->type_key; - rhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &rhs_oplist); - e_expr_push_child(root, rhs_bytecode); - return root; -} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 97889252..afcf793d 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -97,7 +97,5 @@ internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); //- rjf: leaf-bytecode expression extensions internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name); -internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, U64 index); -internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index a2b2f1a0..5a7dcebc 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -299,11 +299,11 @@ e_token_array_make_first_opl(E_Token *first, E_Token *opl) //~ rjf: Expression Tree Building Functions internal E_Expr * -e_push_expr(Arena *arena, E_ExprKind kind, void *location) +e_push_expr(Arena *arena, E_ExprKind kind, Rng1U64 range) { E_Expr *e = push_array(arena, E_Expr, 1); e->first = e->last = e->next = e->prev = e->ref = &e_expr_nil; - e->location = location; + e->range = range; e->kind = kind; return e; } @@ -329,7 +329,7 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child) internal E_Expr * e_expr_ref(Arena *arena, E_Expr *ref) { - E_Expr *expr = e_push_expr(arena, E_ExprKind_Ref, 0); + E_Expr *expr = e_push_expr(arena, E_ExprKind_Ref, ref->range); expr->ref = ref; return expr; } @@ -355,7 +355,7 @@ e_expr_copy(Arena *arena, E_Expr *src) Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) { - E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->location); + E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->range); dst->mode = t->src->mode; dst->space = t->src->space; dst->type_key = t->src->type_key; @@ -763,7 +763,7 @@ e_push_type_parse_from_text_tokens(Arena *arena, String8 text, E_TokenArray toke } // rjf: construct leaf type - parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token.range); parse.expr->type_key = type_key; } } @@ -784,7 +784,7 @@ e_push_type_parse_from_text_tokens(Arena *arena, String8 text, E_TokenArray toke { token_it += 1; E_Expr *ptee = parse.expr; - parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token.range); e_expr_push_child(parse.expr, ptee); } else @@ -856,7 +856,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { PrefixUnaryTask *next; E_ExprKind kind; - void *location; + Rng1U64 range; }; PrefixUnaryTask *first_prefix_unary = 0; PrefixUnaryTask *last_prefix_unary = 0; @@ -868,7 +868,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; E_ExprKind prefix_unary_kind = 0; - void *location = 0; + Rng1U64 range = {0}; // rjf: try op table for EachNonZeroEnumVal(E_ExprKind, k) @@ -892,7 +892,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: consume valid op if(prefix_unary_precedence != 0) { - location = token_string.str; + range = token.range; it += 1; } @@ -912,7 +912,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { PrefixUnaryTask *op_n = push_array(scratch.arena, PrefixUnaryTask, 1); op_n->kind = prefix_unary_kind; - op_n->location = location; + op_n->range = range; SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); } } @@ -973,7 +973,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `)`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `)`."); } // rjf: consume ) @@ -1003,17 +1003,17 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: build cast-to-U64*, and dereference operators if(nested_parse.expr == &e_expr_nil) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected expression following `[`."); } else { - E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token.range); type->type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); E_Expr *casted = atom; - E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str); + E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token.range); e_expr_push_child(cast, type); e_expr_push_child(cast, casted); - atom = e_push_expr(arena, E_ExprKind_Deref, token_string.str); + atom = e_push_expr(arena, E_ExprKind_Deref, token.range); e_expr_push_child(atom, cast); } @@ -1022,7 +1022,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing `]`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `]`."); } // rjf: consume ) @@ -1037,7 +1037,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // else if(token.kind == E_TokenKind_Identifier) { - atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token.range); atom->string = token_string; it += 1; } @@ -1055,7 +1055,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { U64 val = 0; try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); atom->value.u64 = val; } @@ -1068,14 +1068,14 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: presence of f after . => f32 if(f_pos < token_string.size) { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafF32, token.range); atom->value.f32 = val; } // rjf: no f => f64 else { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafF64, token.range); atom->value.f64 = val; } } @@ -1092,12 +1092,12 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); atom->value.u64 = (U64)char_val; } else { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Malformed character literal."); } } @@ -1110,7 +1110,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token.range); atom->string = string_value_raw; it += 1; } @@ -1122,7 +1122,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token.range); atom->string = string_value_raw; it += 1; } @@ -1183,9 +1183,9 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { it += 1; E_Expr *lhs = atom; - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name_maybe_string.str); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name_maybe.range); rhs->string = member_name_maybe_string; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); + atom = e_push_expr(arena, E_ExprKind_MemberAccess, token.range); e_expr_push_child(atom, lhs); e_expr_push_child(atom, rhs); } @@ -1193,7 +1193,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: no identifier after `.`? -> error else { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing member name after `%S`.", token_string); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing member name after `%S`.", token_string); } } @@ -1216,7 +1216,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { E_Expr *array_expr = atom; E_Expr *index_expr = idx_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); + atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token.range); e_expr_push_child(atom, array_expr); e_expr_push_child(atom, index_expr); } @@ -1227,7 +1227,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `[`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Unclosed `[`."); } else { @@ -1247,7 +1247,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: parse all argument expressions E_Expr *callee_expr = atom; - E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); + E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token.range); call_expr->string = callee_expr->string; e_expr_push_child(call_expr, callee_expr); E_Parse args_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); @@ -1270,7 +1270,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Unclosed `(`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Unclosed `(`."); } else { @@ -1294,7 +1294,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t for(CastTask *cast = first_cast; cast != 0; cast = cast->next) { E_Expr *rhs = atom; - atom = e_push_expr(arena, E_ExprKind_Cast, cast->type_expr->location); + atom = e_push_expr(arena, E_ExprKind_Cast, cast->type_expr->range); e_expr_push_child(atom, cast->type_expr); e_expr_push_child(atom, rhs); } @@ -1310,13 +1310,13 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t prefix_unary = prefix_unary->next) { E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->range); e_expr_push_child(atom, rhs); } } else if(first_prefix_unary != 0) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->range, "Missing expression."); } //////////////////////////// @@ -1359,17 +1359,17 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // carving out a special case here to allow "unfinished *s" to be // treated as pointers instead. E_Expr *ptee = atom; - atom = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + atom = e_push_expr(arena, E_ExprKind_Ptr, token.range); e_expr_push_child(atom, ptee); } else if(rhs == &e_expr_nil) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing right-hand-side of `%S`.", token_string); } else { E_Expr *lhs = atom; - atom = e_push_expr(arena, binary_kind, token_string.str); + atom = e_push_expr(arena, binary_kind, token.range); e_expr_push_child(atom, lhs); e_expr_push_child(atom, rhs); } @@ -1389,7 +1389,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); if(middle_expr_parse.expr == &e_expr_nil) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected expression after `?`."); } // rjf: expect : @@ -1401,7 +1401,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected `:` after `?`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected `:` after `?`."); } else { @@ -1420,7 +1420,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); if(rhs_expr_parse.expr == &e_expr_nil) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token.range, "Expected expression after `:`."); } } @@ -1432,7 +1432,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t E_Expr *lhs = atom; E_Expr *mhs = middle_expr_parse.expr; E_Expr *rhs = rhs_expr_parse.expr; - atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); + atom = e_push_expr(arena, E_ExprKind_Ternary, token.range); e_expr_push_child(atom, lhs); e_expr_push_child(atom, mhs); e_expr_push_child(atom, rhs); diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 7ab6a07d..c8e91b4b 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -17,7 +17,7 @@ internal E_TokenArray e_token_array_make_first_opl(E_Token *first, E_Token *opl) //////////////////////////////// //~ rjf: Expression Tree Building Functions -internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location); +internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, Rng1U64 range); internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d13607e5..8170d349 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2768,12 +2768,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file) if(0 <= idx && idx < accel->fields.count) { String8 name = accel->fields.v[idx]; - expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *lhs = e_expr_ref(arena, expr); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); - rhs->string = push_str8_copy(arena, name); - e_expr_push_child(expr, lhs); - e_expr_push_child(expr, rhs); evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", name); } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 59865ca2..1f108d6f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11428,7 +11428,7 @@ rd_frame(void) .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(commands), .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(commands), }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, macro_map, name, expr); @@ -11457,7 +11457,7 @@ rd_frame(void) E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set, .access = E_TYPE_ACCESS_FUNCTION_NAME(cfgs)); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, macro_map, name, expr); @@ -11470,7 +11470,7 @@ rd_frame(void) E_TypeKey type_key = e_type_key_cons(.name = name, .kind = E_TypeKind_Set, .access = E_TYPE_ACCESS_FUNCTION_NAME(control)); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, macro_map, name, expr); @@ -11502,7 +11502,7 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(cfgs_slice), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(cfgs_slice), }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); @@ -11536,7 +11536,7 @@ rd_frame(void) if(label.size != 0) { E_Space space = rd_eval_space_from_cfg(cfg); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11556,7 +11556,7 @@ rd_frame(void) { E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, window->string); E_Space space = rd_eval_space_from_cfg(window); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11572,7 +11572,7 @@ rd_frame(void) RD_Cfg *tab = tab_n->v; E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, tab->string); E_Space space = rd_eval_space_from_cfg(tab); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11645,7 +11645,7 @@ rd_frame(void) { E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("user")); E_Space space = rd_eval_space_from_cfg(rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11654,7 +11654,7 @@ rd_frame(void) { E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("project")); E_Space space = rd_eval_space_from_cfg(rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project"))); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11679,7 +11679,7 @@ rd_frame(void) { CTRL_Entity *entity = array.v[idx]; E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = type_key; @@ -11719,7 +11719,7 @@ rd_frame(void) .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(ctrl_entities), .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(ctrl_entities) }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); @@ -11738,7 +11738,7 @@ rd_frame(void) .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(unattached_processes) }); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); e_string2expr_map_insert(scratch.arena, macro_map, collection_name, expr); @@ -11823,7 +11823,7 @@ rd_frame(void) for EachElement(idx, collection_infos) { String8 collection_name = collection_infos[idx].name; - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, .expand = @@ -11847,7 +11847,7 @@ rd_frame(void) for EachElement(idx, debug_info_table_collection_names) { String8 name = debug_info_table_collection_names[idx]; - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .flags = E_TypeFlag_StubSingleLineExpansion, @@ -11869,7 +11869,7 @@ rd_frame(void) U128 hash = hs_hash_from_key(key, 0); String8 data = hs_data_from_hash(hs_scope, hash); E_Space space = e_space_make(E_SpaceKind_HashStoreKey); - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); space.u128 = key; expr->space = space; expr->mode = E_Mode_Offset; @@ -11982,7 +11982,7 @@ rd_frame(void) { type_flags |= E_TypeFlag_ArrayLikeExpansion; } - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .flags = type_flags, .name = lens_table[idx].name, From aa9a00f754d72c035c886a501ca75496e3f5373d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 09:47:20 -0700 Subject: [PATCH 527/755] sketch out first pass of autocompletion list-expr/replace-range/filter based on cursor-offset -> expression-node path --- src/eval/eval_parse.c | 22 ++++++--- src/raddbg/raddbg_core.c | 93 ++++++++++++++++++++++++++++++++++--- src/raddbg/raddbg_core.h | 14 +++++- src/raddbg/raddbg_views.c | 12 ++--- src/raddbg/raddbg_widgets.c | 11 ++--- 5 files changed, 123 insertions(+), 29 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 5a7dcebc..f84126ce 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1177,20 +1177,28 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t // rjf: look for member name E_Token member_name_maybe = e_token_at_it(it, &tokens); String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); + B32 member_name_is_good = (member_name_maybe.kind == E_TokenKind_Identifier); - // rjf: if we have a member name, build dot-operator tree - if(member_name_maybe.kind == E_TokenKind_Identifier) + // rjf: build dot-operator tree + E_Expr *lhs = atom; + E_Expr *rhs = &e_expr_nil; + if(member_name_is_good) { - it += 1; - E_Expr *lhs = atom; - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name_maybe.range); + rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name_maybe.range); rhs->string = member_name_maybe_string; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, token.range); - e_expr_push_child(atom, lhs); + } + atom = e_push_expr(arena, E_ExprKind_MemberAccess, token.range); + e_expr_push_child(atom, lhs); + if(member_name_is_good) + { e_expr_push_child(atom, rhs); } // rjf: no identifier after `.`? -> error + if(member_name_is_good) + { + it += 1; + } else { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing member name after `%S`.", token_string); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1f108d6f..5622f84d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3578,13 +3578,12 @@ rd_view_ui(Rng2F32 rect) if(autocomplete_hint_string.size != 0) { take_autocomplete = 1; - String8 word_query = rd_lister_query_word_from_input_string_off(string, edit_state->cursor.column-1); - U64 word_off = (U64)(word_query.str - string.str); - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, string, edit_state->cursor.column-1); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info.replaced_range.min+1, autocomp_cursor_info.replaced_range.max+1), autocomplete_hint_string); new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, word_off+1+autocomplete_hint_string.size); + edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info.replaced_range.min+autocomplete_hint_string.size); string = str8(edit_state->input_buffer, edit_state->input_size); op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); } @@ -4956,7 +4955,10 @@ rd_view_ui(Rng2F32 rect) txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_regs(.ui_key = sig.box->key, .string = input, .cursor = cell_edit_state->cursor); + RD_AutocompCursorInfo cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, input, cell_edit_state->cursor.column-1); + rd_set_autocomp_regs(.ui_key = sig.box->key, + .string = cursor_info.filter, + .expr = cursor_info.list_expr); } } } @@ -6663,7 +6665,7 @@ rd_window_frame(void) RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); rd_cfg_new_replace(input, ws->autocomp_regs->string); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replacef(expr, "query:locals, query:globals, query:thread_locals, query:procedures, query:types"); + rd_cfg_new_replace(expr, ws->autocomp_regs->expr); // rjf: determine container size EV_BlockTree predicted_block_tree = {0}; @@ -9722,8 +9724,85 @@ rd_set_hover_eval(Vec2F32 pos, String8 string) //////////////////////////////// //~ rjf: Autocompletion Lister +internal RD_AutocompCursorInfo +rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off) +{ + RD_AutocompCursorInfo result = {0}; + { + result.list_expr = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); + result.filter = input; + result.replaced_range = r1u64(0, input.size); + } + Temp scratch = scratch_begin(&arena, 1); + E_Parse parse = e_parse_from_string(input); + + //- rjf: cursor offset -> cursor containing node + E_Expr *cursor_expr = &e_expr_nil; + E_Expr *cursor_expr_parent = &e_expr_nil; + { + typedef struct ExprWalkTask ExprWalkTask; + struct ExprWalkTask + { + ExprWalkTask *next; + E_Expr *parent; + E_Expr *expr; + }; + ExprWalkTask start_task = {0, &e_expr_nil, parse.expr}; + ExprWalkTask *first_task = &start_task; + ExprWalkTask *last_task = first_task; + for(E_Expr *chain = parse.expr->next; chain != &e_expr_nil; chain = chain->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = &e_expr_nil; + task->expr = chain; + } + for(ExprWalkTask *t = first_task; t != 0; t = t->next) + { + E_Expr *e = t->expr; + if(contains_1u64(e->range, cursor_off) || cursor_off == e->range.max) + { + cursor_expr_parent = t->parent; + cursor_expr = e; + break; + } + for(E_Expr *child = e->first; child != &e_expr_nil; child = child->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = e; + task->expr = child; + } + } + } + + //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side + { + E_Expr *dot_expr = &e_expr_nil; + if(cursor_expr->kind == E_ExprKind_MemberAccess && cursor_off == cursor_expr->range.max) + { + dot_expr = cursor_expr; + } + else if(cursor_expr_parent->kind == E_ExprKind_MemberAccess && cursor_expr == cursor_expr_parent->first->next) + { + dot_expr = cursor_expr_parent; + } + if(dot_expr != &e_expr_nil) + { + E_Eval lhs_eval = e_eval_from_expr(dot_expr->first); + E_Eval type_of_lhs_eval = e_eval_wrapf(lhs_eval, "typeof($)"); + result.list_expr = e_full_expr_string_from_key(arena, type_of_lhs_eval.key); + result.filter = cursor_expr->string; + result.replaced_range = union_1u64(dot_expr->range, cursor_expr->range); + } + } + + scratch_end(scratch); + return result; +} + internal String8 -rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off) +rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) { U64 word_start_off = 0; for(U64 off = 0; off < input.size && off < cursor_off; off += 1) diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index bb05d6ed..9b3a9415 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -162,6 +162,17 @@ enum RD_CmdKindFlag_ListInTextRng = (1<<4), }; +//////////////////////////////// +//~ rjf: Autocompletion Cursor Info Type + +typedef struct RD_AutocompCursorInfo RD_AutocompCursorInfo; +struct RD_AutocompCursorInfo +{ + String8 list_expr; + String8 filter; + Rng1U64 replaced_range; +}; + //////////////////////////////// //~ rjf: Generated Code @@ -951,7 +962,8 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //////////////////////////////// //~ rjf: Autocompletion Lister -internal String8 rd_lister_query_word_from_input_string_off(String8 input, U64 cursor_off); +internal RD_AutocompCursorInfo rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off); +internal String8 rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); internal void rd_set_autocomp_regs_(RD_Regs *regs); #define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a0563509..8e9631d0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1689,14 +1689,10 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // do a code-string of ".member_name" String8 member_name = notable_expr->first->next->string; String8 fancy_name = {0}; - if(str8_match(member_name, str8_lit("$padding"), StringMatchFlag_RightSideSloppy)) - { - fancy_name = str8_lit("Padding"); - } - else if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - cell->eval.space.kind == E_SpaceKind_File || - cell->eval.space.kind == E_SpaceKind_FileSystem) + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem) { fancy_name = rd_display_from_code_name(member_name); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1fcd8b6e..35710899 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3576,13 +3576,12 @@ rd_cell(RD_CellParams *params, String8 string) // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op if(autocomplete_hint_string.size != 0) { - String8 word_query = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); - U64 word_off = (U64)(word_query.str - edit_string.str); - String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(word_off+1, word_off+1+word_query.size), autocomplete_hint_string); + RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, edit_string, params->cursor->column-1); + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(autocomp_cursor_info.replaced_range.min+1, autocomp_cursor_info.replaced_range.max+1), autocomplete_hint_string); new_string.size = Min(params->edit_buffer_size, new_string.size); MemoryCopy(params->edit_buffer, new_string.str, new_string.size); params->edit_string_size_out[0] = new_string.size; - params->cursor[0] = params->mark[0] = txt_pt(1, word_off+1+autocomplete_hint_string.size); + params->cursor[0] = params->mark[0] = txt_pt(1, 1+autocomp_cursor_info.replaced_range.min+autocomplete_hint_string.size); edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); @@ -3652,8 +3651,8 @@ rd_cell(RD_CellParams *params, String8 string) DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); if(autocomplete_hint_string.size != 0) { - String8 query_word = rd_lister_query_word_from_input_string_off(edit_string, params->cursor->column-1); - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, query_word.size); + RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, edit_string, params->cursor->column-1); + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, params->cursor->column-1 - autocomp_cursor_info.replaced_range.min); U64 off = 0; U64 cursor_off = params->cursor->column-1; DR_FStrNode *prev_n = 0; From 80268dd770daaa168cdb763533271650d709f26c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 10:16:41 -0700 Subject: [PATCH 528/755] correctly evaluate array lens size arguments in the context of the parent expression --- src/eval/eval_types.c | 2 +- src/eval_visualization/eval_visualization_core.c | 14 ++++++++++---- src/raddbg/raddbg_core.c | 15 --------------- src/raddbg/raddbg_core.h | 1 - 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 8170d349..c0adc9e2 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2339,7 +2339,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) { E_Type *type = e_type_from_key__cached(eval.irtree.type_key); U64 count = 1; - if(type->args != 0 && type->count > 0) + if(type->args != 0 && type->count > 0) E_ParentKey(eval.key) { E_Key count_key = e_key_from_expr(type->args[0]); E_Value count_value = e_value_from_key(count_key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index da44fd0d..a8fbed76 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1575,8 +1575,11 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) else if(str8_match(type->name, str8_lit("hex"), 0)) { lens_params.radix = 16; } else if(str8_match(type->name, str8_lit("digits"), 0) && type->count >= 1) { - E_Value value = e_value_from_expr(type->args[0]); - lens_params.min_digits = value.u64; + E_ParentKey(eval.key) + { + E_Value value = e_value_from_expr(type->args[0]); + lens_params.min_digits = value.u64; + } } else if(str8_match(type->name, str8_lit("no_string"), 0)) { @@ -1596,8 +1599,11 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) element_type_kind == E_TypeKind_S8 || element_type_kind == E_TypeKind_U8))) { - lens_params.limit_strings = 1; - lens_params.limit_strings_size = e_value_from_expr(type->args[0]).u64; + E_ParentKey(eval.key) + { + lens_params.limit_strings = 1; + lens_params.limit_strings_size = e_value_from_expr(type->args[0]).u64; + } } else { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5622f84d..15df18d7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9801,21 +9801,6 @@ rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 c return result; } -internal String8 -rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off) -{ - U64 word_start_off = 0; - for(U64 off = 0; off < input.size && off < cursor_off; off += 1) - { - if(!char_is_alpha(input.str[off]) && !char_is_digit(input.str[off], 10) && input.str[off] != '_') - { - word_start_off = off+1; - } - } - String8 query = str8_skip(str8_prefix(input, cursor_off), word_start_off); - return query; -} - internal void rd_set_autocomp_regs_(RD_Regs *regs) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 9b3a9415..8473fb43 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -963,7 +963,6 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //~ rjf: Autocompletion Lister internal RD_AutocompCursorInfo rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off); -internal String8 rd_autocomp_query_word_from_input_string_off(String8 input, U64 cursor_off); internal void rd_set_autocomp_regs_(RD_Regs *regs); #define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) From 306ad2d382a40a0c2592295550976fd36919309b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 10:38:36 -0700 Subject: [PATCH 529/755] allow multiple leaf-identifier completions per input, using the cursor_off -> cursor_expr_node autocompletion querying path --- src/raddbg/raddbg_core.c | 17 ++++++++++++++--- src/raddbg/raddbg_widgets.c | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 15df18d7..a8f785ed 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3574,8 +3574,8 @@ rd_view_ui(Rng2F32 rect) os_set_clipboard_text(op.copy); } - // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op - if(autocomplete_hint_string.size != 0) + // rjf: any valid *additive* op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) { take_autocomplete = 1; RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, string, edit_state->cursor.column-1); @@ -6679,7 +6679,7 @@ rd_window_frame(void) F32 row_height_px = ui_top_px_height(); U64 max_row_count = (U64)floor_f32(ui_top_font_size()*30.f / row_height_px); U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count - 1); - F32 width_px = floor_f32(40.f*ui_top_font_size()); + F32 width_px = floor_f32(30.f*ui_top_font_size()); F32 height_px = needed_row_count*row_height_px; // rjf: determine list top-level rect @@ -9777,6 +9777,8 @@ rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 c } //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side + B32 did_special_cursor_case = 0; + if(!did_special_cursor_case) { E_Expr *dot_expr = &e_expr_nil; if(cursor_expr->kind == E_ExprKind_MemberAccess && cursor_off == cursor_expr->range.max) @@ -9789,6 +9791,7 @@ rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 c } if(dot_expr != &e_expr_nil) { + did_special_cursor_case = 1; E_Eval lhs_eval = e_eval_from_expr(dot_expr->first); E_Eval type_of_lhs_eval = e_eval_wrapf(lhs_eval, "typeof($)"); result.list_expr = e_full_expr_string_from_key(arena, type_of_lhs_eval.key); @@ -9797,6 +9800,14 @@ rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 c } } + //- rjf: cursor is on a leaf-identifier? -> replace just that identifier, keep the original list expression + if(!did_special_cursor_case && cursor_expr->kind == E_ExprKind_LeafIdentifier) + { + did_special_cursor_case = 1; + result.filter = str8_prefix(cursor_expr->string, cursor_off - cursor_expr->range.min); + result.replaced_range = cursor_expr->range; + } + scratch_end(scratch); return result; } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 35710899..c0817f38 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3573,8 +3573,8 @@ rd_cell(RD_CellParams *params, String8 string) // rjf: map this action to an op UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); - // rjf: any valid op & autocomplete hint? -> perform autocomplete first, then re-compute op - if(autocomplete_hint_string.size != 0) + // rjf: any valid *additive* op & autocomplete hint? -> perform autocomplete first, then re-compute op + if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) { RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, edit_string, params->cursor->column-1); String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(autocomp_cursor_info.replaced_range.min+1, autocomp_cursor_info.replaced_range.max+1), autocomplete_hint_string); From 36e77e9691fd795bfdb595358182a47a548b51e3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 11:04:14 -0700 Subject: [PATCH 530/755] clean up flow of active-targetless launch path; instead of just erroring, prompt user with selection, select if none selected, etc. --- src/eval/eval_types.c | 12 ++++++++++-- src/raddbg/raddbg_core.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index c0adc9e2..8f2d5345 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1222,7 +1222,15 @@ internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b) { int result = 0; - if(a->off < b->off) + if(a->kind < b->kind) + { + result = -1; + } + else if(a->kind > b->kind) + { + result = +1; + } + else if(a->off < b->off) { result = -1; } @@ -1272,7 +1280,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) n->v.inheritance_key_chain = task->inheritance_chain; SLLQueuePush(members_list.first, members_list.last, n); members_list.count += 1; - members_need_offset_sort = members_need_offset_sort || (n->v.off < last_member_off); + members_need_offset_sort = members_need_offset_sort || (type->members[member_idx].kind == E_MemberKind_DataField && n->v.off < last_member_off); last_member_off = n->v.off; } else if(type->members[member_idx].kind == E_MemberKind_Base) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a8f785ed..15eea6a5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12200,6 +12200,7 @@ rd_frame(void) case RD_CmdKind_StepOver: case RD_CmdKind_Restart: { + // rjf: reset hit counts CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); if(processes.count == 0 || kind == RD_CmdKind_Restart) { @@ -12210,6 +12211,41 @@ rd_frame(void) rd_cfg_new_replace(hit_count, str8_lit("0")); } } + + // rjf: determine if we have active targets + RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); + B32 has_active_targets = 0; + for(RD_CfgNode *n = targets.first; n != 0; n = n->next) + { + RD_Cfg *target = n->v; + if(!rd_disabled_from_cfg(target)) + { + has_active_targets = 1; + break; + } + } + + // rjf: run -> no active targets, no processes? -> do helper for launch-and-run + if((kind == RD_CmdKind_Run || + kind == RD_CmdKind_StepInto || + kind == RD_CmdKind_StepOver) && processes.count == 0) + { + if(!has_active_targets) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[kind == RD_CmdKind_Run ? RD_CmdKind_LaunchAndRun : RD_CmdKind_LaunchAndStepInto].string); + break; + } + } + + // rjf: if this is a low-level operation, e.g. launch-and-run or launch-and-step-into, + // and we do not have any active targets, then let's just select the ones that we are + // launching. + if(!has_active_targets && + (kind == RD_CmdKind_LaunchAndRun || + kind == RD_CmdKind_LaunchAndStepInto)) + { + rd_cmd(RD_CmdKind_SelectTarget, .cfg = rd_regs()->cfg); + } } // fallthrough default: { From 630394750e44ab1647e2e135a1ce392c1a53e878 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 11:39:08 -0700 Subject: [PATCH 531/755] add all visualizers to fixed tab list, derive language from view tree correctly rather than just the evaluation --- src/raddbg/generated/raddbg.meta.c | 32 ++++++++++++++++++++++-------- src/raddbg/generated/raddbg.meta.h | 14 ++++++++++--- src/raddbg/raddbg.mdesk | 16 ++++++++++----- src/raddbg/raddbg_core.c | 16 --------------- src/raddbg/raddbg_views.c | 14 +++++++++++-- 5 files changed, 58 insertions(+), 34 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0b45faa2..b82863df 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 rd_tab_fast_path_view_name_table[20] = +String8 rd_tab_fast_path_view_name_table[24] = { str8_lit_comp("watch"), str8_lit_comp("watch"), @@ -24,11 +24,15 @@ str8_lit_comp("watch"), str8_lit_comp("watch"), str8_lit_comp("watch"), str8_lit_comp("text"), +str8_lit_comp("text"), str8_lit_comp("disasm"), str8_lit_comp("memory"), +str8_lit_comp("bitmap"), +str8_lit_comp("color"), +str8_lit_comp("geo3d"), }; -String8 rd_tab_fast_path_query_name_table[20] = +String8 rd_tab_fast_path_query_name_table[24] = { str8_lit_comp(""), str8_lit_comp("query:locals"), @@ -50,9 +54,13 @@ str8_lit_comp("query:auto_view_rules"), str8_lit_comp("query:output"), str8_lit_comp(""), str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[329] = +RD_VocabInfo rd_vocab_info_table[333] = { {str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -381,8 +389,12 @@ RD_VocabInfo rd_vocab_info_table[329] = {str8_lit_comp("file_path_maps"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, +{str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, {str8_lit_comp("memory"), str8_lit_comp(""), str8_lit_comp("Memory"), str8_lit_comp(""), RD_IconKind_Grid}, +{str8_lit_comp("bitmap"), str8_lit_comp(""), str8_lit_comp("Bitmap"), str8_lit_comp(""), RD_IconKind_Bitmap}, +{str8_lit_comp("color"), str8_lit_comp(""), str8_lit_comp("Color"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, }; RD_NameSchemaInfo rd_name_schema_info_table[23] = @@ -393,12 +405,12 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@expand_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': lang,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': arch,\n 'syntax': dasm_syntax,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': tex2dformat,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, @@ -459,7 +471,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[221] = +RD_CmdKindInfo rd_cmd_kind_info_table[225] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -680,8 +692,12 @@ RD_CmdKindInfo rd_cmd_kind_info_table[221] = { str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens a Auto View Rules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("output"), str8_lit_comp("Opens a Output tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("text"), str8_lit_comp("Opens a Text tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("disasm"), str8_lit_comp("Opens a Disassembly tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("memory"), str8_lit_comp("Opens a Memory tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("bitmap"), str8_lit_comp("Opens a Bitmap tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("color"), str8_lit_comp("Opens a Color tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 71d47cf2..e8e32998 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -275,8 +275,12 @@ RD_CmdKind_OpenModules, RD_CmdKind_OpenFilePathMaps, RD_CmdKind_OpenAutoViewRules, RD_CmdKind_OpenOutput, +RD_CmdKind_OpenText, RD_CmdKind_OpenDisasm, RD_CmdKind_OpenMemory, +RD_CmdKind_OpenBitmap, +RD_CmdKind_OpenColor, +RD_CmdKind_OpenGeo3D, RD_CmdKind_COUNT, RD_CmdKind_FirstTabFastPathCmd = RD_CmdKind_OpenWatch, } RD_CmdKind; @@ -629,8 +633,12 @@ X(modules) \ X(file_path_maps) \ X(auto_view_rules) \ Y(output, text, "query:output")\ +Y(text, text, "")\ Y(disasm, disasm, "")\ Y(memory, memory, "")\ +Y(bitmap, bitmap, "")\ +Y(color, color, "")\ +Y(geo3d, geo3d, "")\ Z(getting_started)\ #define rd_regs_lit_init_top \ @@ -678,9 +686,9 @@ Z(getting_started)\ .os_event = rd_regs()->os_event,\ C_LINKAGE_BEGIN -extern String8 rd_tab_fast_path_view_name_table[20]; -extern String8 rd_tab_fast_path_query_name_table[20]; -extern RD_VocabInfo rd_vocab_info_table[329]; +extern String8 rd_tab_fast_path_view_name_table[24]; +extern String8 rd_tab_fast_path_query_name_table[24]; +extern RD_VocabInfo rd_vocab_info_table[333]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1ab59b87..b9426c93 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -40,8 +40,12 @@ RD_WatchTabFastPathTable: RD_ViewTabFastPathTable: { {Output "Output" output text "query:output" List } + {Text "Text" text text "" FileOutline } {Disasm "Disassembly" disasm disasm "" Glasses } {Memory "Memory" memory memory "" Grid } + {Bitmap "Bitmap" bitmap bitmap "" Bitmap } + {Color "Color" color color "" Palette } + {Geo3D "Geometry (3D)" geo3d geo3d "" Cube } } @table(name display_name name_lower icon) @@ -437,7 +441,7 @@ RD_VocabTable: @description("An expression to describe data which should be viewed as text or code.") 'expression': code_string, @description("The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.") - 'lang': lang, + 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers':bool, @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") @@ -452,9 +456,9 @@ RD_VocabTable: { @description("An expression to describe the base address or offset of the disassembly.") 'expression': code_string, - 'arch': arch, - 'syntax': dasm_syntax, - 'size': code_string, + 'arch': code_string, + 'syntax': code_string, + 'size': code_string, @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") 'show_addresses': bool, @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") @@ -494,7 +498,7 @@ RD_VocabTable: @order(0) 'w': u64, @order(1) 'h': u64, @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") - 'fmt': tex2dformat, + 'fmt': code_string, } ``` } @@ -513,6 +517,8 @@ RD_VocabTable: ``` @inherit(tab) x: { + @display_name("Expression") @description("An expression to describe the base address of the index buffer.") + 'expression': code_string, 'count': code_string, 'vtx': code_string, 'vtx_size': code_string, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 15eea6a5..3543a956 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5415,22 +5415,6 @@ rd_lang_kind_from_eval(E_Eval eval) { lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path)); } - if(lang_kind == TXT_LangKind_Null) - { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("lang"), 0)) - { - lang_kind = txt_lang_kind_from_extension(arg->first->next->string); - break; - } - } - } - } scratch_end(scratch); return lang_kind; } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8e9631d0..6d0a1269 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1908,7 +1908,15 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } Rng1U64 range = e_range_from_eval(eval); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); + String8 lang = rd_view_cfg_from_string(str8_lit("lang"))->first->string; + if(lang.size == 0) + { + rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); + } + else + { + rd_regs()->lang_kind = txt_lang_kind_from_extension(lang); + } U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); @@ -3307,6 +3315,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) //- rjf: equip loading info // if(offset_range.max != offset_range.min && + eval.string.size != 0 && eval.msgs.max_kind == E_MsgKind_Null && (u128_match(data_hash, u128_zero()) || r_handle_match(texture, r_handle_zero()) || @@ -3790,7 +3799,8 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: equip loading info // - if(eval.msgs.max_kind == E_MsgKind_Null && + if(eval.string.size != 0 && + eval.msgs.max_kind == E_MsgKind_Null && (r_handle_match(idxs_buffer, r_handle_zero()) || r_handle_match(vtxs_buffer, r_handle_zero()))) { From f7757cd163bf948b08422572f842c4d9ba084fe9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 11:56:27 -0700 Subject: [PATCH 532/755] update memory range parameter extraction in visualizers, to be based on cfg tree --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 27 +++++++++++++++------------ src/raddbg/raddbg_views.c | 27 +++++++++++++++++++++++++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b82863df..cbfad240 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -403,7 +403,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("@expand_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("@row_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b9426c93..8cdd5a92 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -409,7 +409,7 @@ RD_VocabTable: { tab, ``` - @expand_commands(duplicate_tab, close_tab) + @row_commands(duplicate_tab, close_tab) x: { @default(11) @display_name('Tab Font Size') @description("Controls the tab's font size.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3543a956..8a4f4b7b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13337,24 +13337,27 @@ rd_frame(void) RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, tab); RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent); - B32 found_selected = 0; - RD_Cfg *next_selected_tab = &rd_nil_cfg; - for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) + if(panel->selected_tab == tab) { - if(n->v == panel->selected_tab) + B32 found_selected = 0; + RD_Cfg *next_selected_tab = &rd_nil_cfg; + for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) { - found_selected = 1; - } - else if(!rd_cfg_is_project_filtered(n->v)) - { - next_selected_tab = n->v; - if(found_selected) + if(n->v == panel->selected_tab) { - break; + found_selected = 1; + } + else if(!rd_cfg_is_project_filtered(n->v)) + { + next_selected_tab = n->v; + if(found_selected) + { + break; + } } } + rd_cmd(RD_CmdKind_FocusTab, .tab = next_selected_tab->id); } - rd_cmd(RD_CmdKind_FocusTab, .tab = next_selected_tab->id); rd_cfg_release(tab); }break; case RD_CmdKind_MoveView: diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 6d0a1269..3e9be2cb 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1906,7 +1906,13 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - Rng1U64 range = e_range_from_eval(eval); + U64 base_offset = e_base_offset_from_eval(eval); + U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + if(size == 0) + { + size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + } + Rng1U64 range = r1u64(base_offset, base_offset+size); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); String8 lang = rd_view_cfg_from_string(str8_lit("lang"))->first->string; if(lang.size == 0) @@ -2174,7 +2180,13 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = e_range_from_eval(eval); + U64 base_offset = e_base_offset_from_eval(eval); + U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + if(size == 0) + { + size = KB(16); + } + Rng1U64 range = r1u64(base_offset, base_offset+size); Arch arch = rd_arch_from_eval(eval); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; @@ -2211,6 +2223,10 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { style_flags |= DASM_StyleFlag_SymbolNames; } + if(str8_match(rd_setting_from_name(str8_lit("syntax")), str8_lit("att"), 0)) + { + syntax = DASM_Syntax_ATT; + } } U128 dasm_key = rd_key_from_eval_space_range(space, range, 0); U128 dasm_data_hash = {0}; @@ -2343,6 +2359,13 @@ RD_VIEW_UI_FUNCTION_DEF(memory) //- rjf: unpack parameterization info // Rng1U64 space_range = e_range_from_eval(eval); + U64 base_offset = e_base_offset_from_eval(eval); + U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + if(size == 0) + { + size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + } + space_range = r1u64(base_offset, base_offset+size); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); From 3be17c7157803cfd1c377298cf89528a6ca29c70 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 12:52:33 -0700 Subject: [PATCH 533/755] merge local todo notes, pre/post 0.9.16 notes pass --- src/raddbg/raddbg_main.c | 340 ++++++++++++++++++++++----------------- 1 file changed, 188 insertions(+), 152 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 378d0dd7..0fdd7d8d 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -182,89 +182,23 @@ // configuration. // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. +// - Fixed substantial unnecessary memory usage with very large output logs. // - Made several visual improvements. //////////////////////////////// -//~ rjf: feature cleanup, code dedup, code elimination pass: -// -// [ ] *ALL* expressions in watch windows need to be editable. -// -// [ ] config hot-reloading, using cfg wins -// [ ] undo/redo, using cfg wins -// [ ] back/forward, using cfg wins +//~ rjf: 0.9.16 TODO notes // +// [ ] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop +// [ ] autocompletion lister +// [ ] "pop out" (hitting enter on visualizers should open them as tabs) +// [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs +// [ ] finish theme editing, build themes - replace code colors map with new theme stuff +// [ ] maybe add extra caching layer to process memory querying? we pay a pretty +// heavy cost even to just read 8 bytes... +// [ ] odin's demo is busted - need to revert PDB conversion type index changes. // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // -// [ ] stepping-onto a line with a conditional breakpoint, which fails, causes a -// single step over the first instruction of that line, even if the thread -// would've stopped at the first instruction due to the step, were that bp not -// there. -// -// [ ] if a breakpoint matches the entry point's starting address, its hit count -// is not correctly incremented. -// [ ] odin's demo is busted - need to revert PDB conversion type index changes. - -//////////////////////////////// -//~ rjf: post-0.9.12 TODO notes -// -// [ ] breakpoints in optimized code? maybe early-terminating bp resolution loop? @bpmiss -// - actually this seems to be potentially because of incomplete src-line-map info... -// [ ] Mohit-reported breakpoint not hitting - may be similar thing to @bpmiss -// -// [ ] CLI argument over-mangling? -// [ ] fix light themes -// [ ] disasm starting address - need to use debug info for more correct -// results... -// [ ] linked list view rule -// [ ] output: add option for scroll-to-bottom - ensure this shows up in universal ctx menu -// [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need -// to prioritize the primary rdi -// [ ] (reported by forrest) 'set-next-statement' -> prioritize current -// module/symbol, in cases where one line maps to many voffs -// [ ] universal ctx menu address/watch options; e.g. watch -> memory; watch -> add watch -// [ ] rich hover coverage; bitmap <-> geo <-> memory <-> disassembly <-> text; etc. -// [ ] visualize all breakpoints everywhere - source view should show up in -// disasm, disasm should show up in source view, function should show up in -// both, etc. -// [ ] ** Function breakpoints should show up in the source listing. Without -// them being visible, it is confusing when you run and you stop there, -// because you're like "wait why did it stop" and then you later remember -// that's because there was a function breakpoint there. - -//////////////////////////////// -//~ rjf: Frontend/UI Pass Tasks -// -// [ ] "Browse..." buttons should adopt a more relevant starting search path, -// if possible -// -// [ ] For the Scheduler window, it would be nice if you could dim or -// folderize threads that are not your threads - eg., if a thread doesn't -// have any resolved stack pointers in your executable code, then you can -// ignore it when you are focusing on your own code. I don't know what the -// best way to detect this is, other than by walking the call stack... one -// way might be to just have a way to separate threads you've named from -// threads you haven't? Or, there could even be a debugger-specific API -// that you use to tag them. Just some way that would make it easier to -// focus on your own threads. - -//////////////////////////////// -//~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup) -// -// [ ] "root" concept in hash store, which buckets keys & allows usage code to -// jettison a collection of keys in retained mode fashion -// -// [ ] Jeff Notes -// [ ] sum view rule -// [ ] plot view rule -// [ ] histogram view rule -// [ ] max view rule -// [ ] min view rule -// -// [ ] use backslashes on windows by default, forward slashes elsewhere (?) -// -// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not -// support it? -// +//- readme improvements // [ ] I was a little confused about what a profile file was. I understood // what the user file was, but the profile file sounded like it should // perhaps be per-project, yet it sounded like it was meant to be somewhat @@ -277,45 +211,76 @@ // the files myself in the shell, but it seemed weird that there was no // "save" option in the menus. // -// [ ] ** One very nice feature of RemedyBG that I use all the time is the -// ability to put "$err, hr" into the watch window, which will just show -// the value of GetLastError() as a string. This is super useful for -// debugging, so you don't have to litter your own code with it. -// (NOTE(rjf): NtQueryInformationThread) -// -// [ ] Tooltip Coverage: -// [ ] lock icon -// [ ] "rotation arrow" icon next to executables -// -// [ ] For theme editing, when you hove the mouse over a theme color entry and -// it highlights that entry, it might help to temporarily change that -// color to white (or the inverse of the background color, or whatever) so -// that the user can see what things on the screen use that theme color. -// -// [ ] It'd be nice to have a "goto byte" option for source views, for jumping -// to error messages that are byte-based instead of line-based. -// -// [ ] @feature debug info overrides (both path-based AND module-based) -// -// [ ] C++ virtual inheritance member visualization in watch window +//- no immediate action but check before release: +// [ ] user switching +// [ ] project switching //////////////////////////////// -//~ rjf: Hot, Low Priority Tasks (UI Opinions, Less-Serious Jank, Preferences, Cleanup) +//~ rjf: post-0.9.16 TODO notes // -// [ ] The hex format for color values in the config file was a real -// mindbender. It's prefixed with "0x", so I was assuming it was either -// Windows Big Endian (0xAARRGGBB) or Mac Little Endian (0xAABBGGRR). To -// my surprise, it was neither - it was actually web format (RRGGBBAA), -// which I was not expecting because that is normally written with a -// number sign (#AARRGGBB) not an 0x. +//- watch improvements +// [ ] *ALL* expressions in watch windows need to be editable. // +//- cfg improvements +// [ ] config hot-reloading, using cfg wins +// [ ] undo/redo, using cfg wins +// [ ] back/forward, using cfg wins +// [ ] mouse back button should make view to go back after I double clicked +// on function to open it +// +//- stepping or breakpoint oddness/fixes +// [ ] stepping-onto a line with a conditional breakpoint, which fails, causes a +// single step over the first instruction of that line, even if the thread +// would've stopped at the first instruction due to the step, were that bp not +// there. +// [ ] if a breakpoint matches the entry point's starting address, its hit count +// is not correctly incremented. +// [ ] breakpoints in optimized code? maybe early-terminating bp resolution loop? @bpmiss +// - actually this seems to be potentially because of incomplete src-line-map info... +// [ ] Mohit-reported breakpoint not hitting - may be similar thing to @bpmiss +// +//- ui improvements +// [ ] universal ctx menu address/watch options; e.g. watch -> memory; watch -> add watch +// [ ] rich hover coverage; bitmap <-> geo <-> memory <-> disassembly <-> text; etc. +// [ ] tooltip coverage pass (row commands, etc.) +// [ ] visualize all breakpoints everywhere - source view should show up in +// disasm, disasm should show up in source view, function should show up in +// both, etc. +// [ ] ** Function breakpoints should show up in the source listing. Without +// them being visible, it is confusing when you run and you stop there, +// because you're like "wait why did it stop" and then you later remember +// that's because there was a function breakpoint there. +// [ ] (reported by forrest) 'set-next-statement' -> prioritize current +// module/symbol, in cases where one line maps to many voffs +// [ ] "Browse..." buttons should adopt a more relevant starting search path, +// if possible +// [ ] (since browse buttons are currently gone i should just add them backin +// while respecting this old todo) +// [ ] For the Scheduler window, it would be nice if you could dim or +// folderize threads that are not your threads - eg., if a thread doesn't +// have any resolved stack pointers in your executable code, then you can +// ignore it when you are focusing on your own code. I don't know what the +// best way to detect this is, other than by walking the call stack... one +// way might be to just have a way to separate threads you've named from +// threads you haven't? Or, there could even be a debugger-specific API +// that you use to tag them. Just some way that would make it easier to +// focus on your own threads. +// [ ] use backslashes on windows by default, forward slashes elsewhere (?) +// [ ] For theme editing, when you hove the mouse over a theme color entry and +// it highlights that entry, it might help to temporarily change that +// color to white (or the inverse of the background color, or whatever) so +// that the user can see what things on the screen use that theme color. +// [ ] The hex format for color values in the config file was a real +// mindbender. It's prefixed with "0x", so I was assuming it was either +// Windows Big Endian (0xAARRGGBB) or Mac Little Endian (0xAABBGGRR). To +// my surprise, it was neither - it was actually web format (RRGGBBAA), +// which I was not expecting because that is normally written with a +// number sign (#AARRGGBB) not an 0x. +// [ ] It'd be nice to have a "goto byte" option for source views, for jumping +// to error messages that are byte-based instead of line-based. // [ ] Clicking on either side of a scroll bar is idiosyncratic. Normally, // that is "page up" / "page down", but here it is "smooth scroll upward" // / "smooth scroll downward" for some reason? -// -// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions? -// [ ] mouse back button should make view to go back after I double clicked -// on function to open it // [ ] Alt+8 to switch to disassembly would be nice (regardless on which // panel was previous, don't want to use ctrl+, multiple times) // Alt+8 for disasm and Alt+6 for memory view are shortcuts I often use @@ -323,54 +288,84 @@ // [ ] default font size is too small for me - not only source code, but // menus/tab/watch names (which don't resize). Maybe you could query // Windows for initial font size? -// [ ] Jump table thunks, on code w/o /INCREMENTAL:NO - -//////////////////////////////// -//~ rjf: Hot, Feature Tasks (Not really "low priority" but less urgent than fixes) -// -// [ ] eval wide/async transforms (e.g. diff(blob1, blob2)) -// [ ] search-in-all-files -// [ ] memory view -// [ ] memory view mutation controls -// [ ] memory view user-made annotations // [ ] globally disable/configure default view rule-like things (string // viz for u8s in particular) -// [ ] @feature automatically snap to search matches when searching source files - -//////////////////////////////// -//~ rjf: Cold, Clean-up Tasks That Probably Only Ryan Notices -// (E.G. Because They Are Code-Related Or Because Nobody Cares) -// -// [ ] @cleanup eliminate explicit font parameters in the various ui paths (e.g. -// code slice params) - -//////////////////////////////// -//~ rjf: Cold, Unsorted Notes (Deferred Until Existing Lists Mostly Exhausted) -// -// [ ] @feature visualize jump destinations in disasm -// [ ] @feature serializing eval view maps (?) -// [ ] @feature multidimensional `array` -// [ ] @feature 2-vector, 3-vector, quaternion -// [ ] @feature audio waveform views -// [ ] @feature smart scopes - expression operators for "grab me the first type X" -// [ ] @feature "pinning" watch expressions, to attach it to a particular scope/evaluation -// context -// -// [ ] @feature just-in-time debugging -// [ ] @feature step-out-of-loop -// -// [ ] long-term future notes from martins -// [ ] core dump saving/loading -// [ ] parallel call stacks view -// [ ] parallel watch view -// [ ] mixed native/interpreted/jit debugging -// - it seems python has a top-level linked list of interpreter states, -// which should allow the debugger to map native callstacks to python -// code -// // [ ] fancy string runs can include "weakness" information for text truncation // ... can prioritize certain parts of strings to be truncated before // others. would be good for e.g. the middle of a path +// +//- visualizer improvements +// [ ] disasm starting address - need to use debug info for more correct results... +// [ ] linked list view +// [ ] output: add option for scroll-to-bottom - ensure this shows up in universal ctx menu +// [ ] multidimensional `array` +// [ ] 2-vector, 3-vector, quaternion +// [ ] audio waveform views +// +//- eval improvements +// [ ] serializing eval view maps (?) +// [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need +// to prioritize the primary rdi +// [ ] wide transforms +// [ ] sum +// [ ] plot +// [ ] max view rule +// [ ] min view rule +// [ ] histogram view rule +// [ ] diffs? +// [ ] ** One very nice feature of RemedyBG that I use all the time is the +// ability to put "$err, hr" into the watch window, which will just show +// the value of GetLastError() as a string. This is super useful for +// debugging, so you don't have to litter your own code with it. +// (NOTE(rjf): NtQueryInformationThread) +// [ ] C++ virtual inheritance member visualization +// [ ] smart scopes - expression operators for "grab me the first type X" +// [ ] "pinning" watch expressions, to attach it to a particular scope/evaluation context +// +//- control improvements +// [ ] debug info overrides (both path-based AND module-based) +// [ ] symbol server +// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions? +// [ ] jump table thunks, on code w/o /INCREMENTAL:NO +// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not +// support it? +// [ ] just-in-time debugging +// [ ] step-out-of-loop +// +//- late-conversion performance improvements +// [ ] investigate wide-conversion performance +// [ ] oversubscribing cores? +// [ ] conversion crashes? +// [ ] fastpath lookup to determine debug info relevance? +// [ ] live++ investigations - ctrl+alt+f11 in UE? +// +//- memory usage improvements +// [ ] "root" concept in hash store, which buckets keys & allows usage code to +// jettison a collection of keys in retained mode fashion +// +//- short-to-medium term future features +// [ ] search-in-all-files +// [ ] automatically snap to search matches when searching source files +// [ ] memory view +// [ ] memory view mutation controls +// [ ] memory view user-made annotations +// [ ] memory view searching +// [ ] disasm view +// [ ] visualize jump destinations in disasm +// +//- longer-term future features +// [ ] long-term future notes from martins +// [ ] core dump saving/loading +// [ ] parallel call stacks view +// [ ] parallel watch view +// [ ] mixed native/interpreted/jit debugging +// - it seems python has a top-level linked list of interpreter states, +// which should allow the debugger to map native callstacks to python +// code +// +//- code cleanup +// [ ] eliminate explicit font parameters in the various ui paths (e.g. +// code slice params) // [ ] font cache eviction (both for font tags, closing fp handles, and // rasterizations) @@ -467,6 +462,47 @@ // etc., all need to be merged, and optionally contextualized/filtered. // right-clicking a tab should be equivalent to spawning a command lister, // but only with commands that are directly +// [x] tab opening +// [x] query listers +// [x] watch-window-defined query completion +// [x] rebindings +// [x] correct breakpoint/watch pin location visualization +// [x] config saving/loading +// [x] "pin hover eval" +// [x] member filtering +// [x] filtering is busted on ctrl_entities, cgs +// [x] right-click menus -> specialize query +// [x] writing ctrl entity names +// [x] saved view rules need to be applied when watch loads!!! +// [x] mechanism to promote tab -> non-auto +// [x] focusing a hover eval makes icons disappear! (seems to only work with +// table demo in mule_main) +// [x] need to distinguish between auto-genn'd expressions and editable expressions +// in watches. if I put in array[0] in the watch window, it just shows up as +// [0] (same for member names, foo.a shows as .a) +// [x] types in watch windows are missing! +// [x] MISSING ERRORS IN WATCH WINDOW +// [x] fix everything lister stopping at targets? +// [x] strange bug where typing on a non-editable expression cell (e.g. bp +// right-click menu) causes cmd icons to shift over +// [x] acceleration pass: +// [x] default setting schema lookup +// [x] evaluation, esp. setting evaluation (evaluation cache) +// [x] string -> run? +// [x] fix glitchiness when mutating cfgs - the cfgs evaluations are cached, and +// never are recomputed!!!! +// [x] fix editing source locations textually +// [x] see if I can make padding member names nicer +// [x] settings / exception filters +// [x] why does 'cut' not work??? +// [x] disallow chained fast paths when evaluating callee in call expr +// [x] missing function type decorations in lister etc. +// [x] dynamic type resolution +// [x] ensure "file picking", for file path map remap, works +// [x] paths in cfg -> relativization on save, de-relativization on load +// [x] "add hover eval to watch" (expr drag & drop -> watch window) +// [x] unattached process evaluation - need a string to evaluate so I can generate +// the evals //////////////////////////////// //~ rjf: Build Options From e3f68622f730cec3d3e8088566bd61571a7056d2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 13:06:16 -0700 Subject: [PATCH 534/755] window titles --- src/os/gfx/linux/os_gfx_linux.c | 7 +++++++ src/os/gfx/os_gfx.h | 1 + src/os/gfx/stub/os_gfx_stub.c | 5 +++++ src/os/gfx/win32/os_gfx_win32.c | 10 ++++++++++ src/raddbg/raddbg_core.c | 19 ++++++++++++++++++- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_main.c | 1 + 7 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index be83091f..c9fd1eba 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -136,6 +136,13 @@ os_window_close(OS_Handle handle) if(os_handle_match(handle, os_handle_zero())) {return;} } +internal void +os_window_set_title(OS_Handle window, String8 title) +{ + if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) +} + internal void os_window_first_paint(OS_Handle handle) { diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index edb4217b..028a0195 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -143,6 +143,7 @@ internal String8 os_get_clipboard_text(Arena *arena); internal OS_Handle os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title); internal void os_window_close(OS_Handle window); +internal void os_window_set_title(OS_Handle window, String8 title); internal void os_window_first_paint(OS_Handle window); internal void os_window_focus(OS_Handle window); internal B32 os_window_is_focused(OS_Handle window); diff --git a/src/os/gfx/stub/os_gfx_stub.c b/src/os/gfx/stub/os_gfx_stub.c index 66b3f898..bb89d335 100644 --- a/src/os/gfx/stub/os_gfx_stub.c +++ b/src/os/gfx/stub/os_gfx_stub.c @@ -45,6 +45,11 @@ os_window_close(OS_Handle window) { } +internal void +os_window_set_title(OS_Handle window, String8 title) +{ +} + internal void os_window_first_paint(OS_Handle window) { diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 4e8daab1..8d2698c6 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -1084,6 +1084,16 @@ os_window_close(OS_Handle handle) os_w32_window_release(window); } +internal void +os_window_set_title(OS_Handle handle, String8 title) +{ + Temp scratch = scratch_begin(0, 0); + OS_W32_Window *window = os_w32_window_from_handle(handle); + String16 title16 = str16_from_8(scratch.arena, title); + SetWindowTextW(window->hwnd, (WCHAR *)title16.str); + scratch_end(scratch); +} + internal void os_window_first_paint(OS_Handle window_handle) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8a4f4b7b..da0c7c05 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5591,6 +5591,13 @@ rd_store_view_paramf(String8 key, char *fmt, ...) //////////////////////////////// //~ rjf: Window Functions +internal String8 +rd_push_window_title(Arena *arena) +{ + String8 result = push_str8f(arena, "%S - %s", str8_skip_last_slash(rd_state->project_path), BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ")"); + return result; +} + internal RD_Cfg * rd_window_from_cfg(RD_Cfg *cfg) { @@ -5684,7 +5691,7 @@ rd_window_state_from_cfg(RD_Cfg *cfg) ws->cfg_id = id; ws->arena = arena_alloc(); { - String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL); + String8 title = rd_push_window_title(scratch.arena); ws->os = os_window_open(r2f32p(pos.x, pos.y, pos.x+size.x, pos.y+size.y), (!has_pos*OS_WindowFlag_UseDefaultPosition)|OS_WindowFlag_CustomBorder, title); } ws->r = r_window_equip(ws->os); @@ -12605,6 +12612,16 @@ rd_frame(void) rd_cfg_release(recent_projects.last->v); } } + + //- rjf: update all window titles + if(file_is_okay) + { + String8 window_title = rd_push_window_title(scratch.arena); + for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) + { + os_window_set_title(ws->os, window_title); + } + } }break; //- rjf: writing config changes diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 8473fb43..e9c3ccc8 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -944,6 +944,7 @@ internal void rd_store_view_paramf(String8 key, char *fmt, ...); //////////////////////////////// //~ rjf: Window Functions +internal String8 rd_push_window_title(Arena *arena); internal RD_Cfg *rd_window_from_cfg(RD_Cfg *cfg); internal RD_WindowState *rd_window_state_from_cfg(RD_Cfg *cfg); internal RD_WindowState *rd_window_state_from_os_handle(OS_Handle os); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 0fdd7d8d..b13c6406 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -180,6 +180,7 @@ // `raddbg_auto_view_rule(DynamicArray, slice)`: declares an // auto-view-rule from source code, rather than from debugger // configuration. +// - The debugger now incorporates the loaded project in all window titles. // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. // - Fixed substantial unnecessary memory usage with very large output logs. From b20f003e7fe7c0e7f3319206048cb65f46c86d5d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 14:09:05 -0700 Subject: [PATCH 535/755] tooltip coverage for all command evaluations, major top-bar simplification, anchored tooltips --- src/raddbg/generated/raddbg.meta.c | 24 +-- src/raddbg/raddbg.mdesk | 32 ++-- src/raddbg/raddbg_core.c | 246 +++++++---------------------- src/raddbg/raddbg_widgets.c | 64 ++++---- src/raddbg/raddbg_widgets.h | 2 +- src/ui/ui_core.c | 17 ++ src/ui/ui_core.h | 1 + 7 files changed, 144 insertions(+), 242 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index cbfad240..b2f8aab6 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -211,8 +211,8 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("select_unwind"), str8_lit_comp(""), str8_lit_comp("Select Unwind"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("up_one_frame"), str8_lit_comp(""), str8_lit_comp("Up One Frame"), str8_lit_comp(""), RD_IconKind_UpArrow}, {str8_lit_comp("down_one_frame"), str8_lit_comp(""), str8_lit_comp("Down One Frame"), str8_lit_comp(""), RD_IconKind_DownArrow}, -{str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select Entity"), str8_lit_comp(""), RD_IconKind_RadioHollow}, -{str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect Entity"), str8_lit_comp(""), RD_IconKind_RadioFilled}, +{str8_lit_comp("select_entity"), str8_lit_comp(""), str8_lit_comp("Select"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_entity"), str8_lit_comp(""), str8_lit_comp("Deselect"), str8_lit_comp(""), RD_IconKind_RadioFilled}, {str8_lit_comp("inc_window_font_size"), str8_lit_comp(""), str8_lit_comp("Increase Window Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("dec_window_font_size"), str8_lit_comp(""), str8_lit_comp("Decrease Window Font Size"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("inc_view_font_size"), str8_lit_comp(""), str8_lit_comp("Increase View Font Size"), str8_lit_comp(""), RD_IconKind_Null}, @@ -331,15 +331,15 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("toggle_watch_expr"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("toggle_watch_expr_at_mouse"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Mouse"), str8_lit_comp(""), RD_IconKind_Binoculars}, -{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckHollow}, -{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable Config Tree"), str8_lit_comp(""), RD_IconKind_CheckFilled}, -{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select Config Tree"), str8_lit_comp(""), RD_IconKind_RadioHollow}, -{str8_lit_comp("deselect_cfg"), str8_lit_comp(""), str8_lit_comp("Deselect Config Tree"), str8_lit_comp(""), RD_IconKind_RadioFilled}, -{str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove Config Tree"), str8_lit_comp(""), RD_IconKind_Trash}, -{str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, -{str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate Config Tree"), str8_lit_comp(""), RD_IconKind_Duplicate}, -{str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate Config Tree"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("enable_cfg"), str8_lit_comp(""), str8_lit_comp("Enable"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("disable_cfg"), str8_lit_comp(""), str8_lit_comp("Disable"), str8_lit_comp(""), RD_IconKind_CheckFilled}, +{str8_lit_comp("select_cfg"), str8_lit_comp(""), str8_lit_comp("Select"), str8_lit_comp(""), RD_IconKind_RadioHollow}, +{str8_lit_comp("deselect_cfg"), str8_lit_comp(""), str8_lit_comp("Deselect"), str8_lit_comp(""), RD_IconKind_RadioFilled}, +{str8_lit_comp("remove_cfg"), str8_lit_comp(""), str8_lit_comp("Remove"), str8_lit_comp(""), RD_IconKind_Trash}, +{str8_lit_comp("name_cfg"), str8_lit_comp(""), str8_lit_comp("Name"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate"), str8_lit_comp(""), RD_IconKind_Duplicate}, +{str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, @@ -400,7 +400,7 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[23] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme Colors') @description(\"Additional theme colors which are applied on top of the project's theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8cdd5a92..7a302ff9 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -286,6 +286,16 @@ RD_VocabTable: x: { @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, + + //- rjf: theme + @display_name('Project Theme Preset') @description("The selected built-in project theme preset.") + 'theme_preset': string, + @no_expand @display_name('Project Theme File') @description("The path from which project's theme data is loaded, overriding the preset.") + 'theme_file': path, + @display_name('Project Theme Colors') @description("Additional theme colors which are applied on top of the project's theme file or preset.") + 'theme_colors': query, + + //- rjf: exception settings @default(1) @display_name("Break On Win32 Control-C Exceptions") @description("Code: 0x40010005") win32_ctrl_c: bool; @default(1) @display_name("Break On Win32 Control-Break Exceptions") @description("Code: 0x40010008") @@ -756,8 +766,8 @@ RD_CmdTable: // | | | | {SelectUnwind 0 1 0 0 "query:call_stack" Null null Nil Null 0 0 0 0 0 0 0 Null "select_unwind" "Select Unwind" "Selects an unwind frame number for the selected thread." "" "" } {UpOneFrame 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "up_one_frame" "Up One Frame" "Selects the call stack frame above the currently selected." "" "" } {DownOneFrame 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 DownArrow "down_one_frame" "Down One Frame" "Selects the call stack frame below the currently selected." "callstack,unwind" "" } - {SelectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select Entity" "Selects a control entity." "" "" } - {DeselectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect Entity" "Deselects a control entity." "" "" } + {SelectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_entity" "Select" "Selects a control entity." "" "" } + {DeselectEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_entity" "Deselect" "Deselects a control entity." "" "" } //- rjf: font sizes {IncWindowFontSize 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "inc_window_font_size" "Increase Window Font Size" "Increases the window's font size by one point." "" "" } @@ -924,15 +934,15 @@ RD_CmdTable: // | | | | {ToggleWatchExpressionAtMouse 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Binoculars "toggle_watch_expr_at_mouse" "Toggle Watch Expression At Mouse" "Adds or removes the expression that the mouse is currently over to an opened watch view." "" "" } //- rjf: general config operations - {EnableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable Config Tree" "Enables a config tree." "" "" } - {DisableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable Config Tree" "Disables a config tree." "" "" } - {SelectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select Config Tree" "Selects a config tree, disabling all others of the same kind." "" "" } - {DeselectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect Config Tree" "Deselects a config tree." "" "" } - {RemoveCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove Config Tree" "Removes a config tree." "" "" } - {NameCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name Config Tree" "Equips a config tree with a label." "" "" } - {ConditionCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition Config Tree" "Equips a config tree with a condition string." "" "" } - {DuplicateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate Config Tree" "Duplicates a config tree." "" "" } - {RelocateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate Config Tree" "Relocates a config tree." "" "" } + {EnableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckHollow "enable_cfg" "Enable" "Enables a config tree." "" "" } + {DisableCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CheckFilled "disable_cfg" "Disable" "Disables a config tree." "" "" } + {SelectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioHollow "select_cfg" "Select" "Selects a config tree, disabling all others of the same kind." "" "" } + {DeselectCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 RadioFilled "deselect_cfg" "Deselect" "Deselects a config tree." "" "" } + {RemoveCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "remove_cfg" "Remove" "Removes a config tree." "" "" } + {NameCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "name_cfg" "Name" "Equips a config tree with a label." "" "" } + {ConditionCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition" "Equips a config tree with a condition string." "" "" } + {DuplicateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate" "Duplicates a config tree." "" "" } + {RelocateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate" "Relocates a config tree." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index da0c7c05..6b8f6155 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2780,7 +2780,7 @@ rd_view_ui(Rng2F32 rect) UI_Padding(ui_pct(1, 0)) { ui_labelf("use"); - UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero()); + UI_TextAlignment(UI_TextAlign_Center) rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero(), 1); ui_labelf("to search for commands and options"); } } @@ -4979,6 +4979,12 @@ rd_view_ui(Rng2F32 rect) RD_RegsScope(.ctrl_entity = cell_info.entity->handle, .no_rich_tooltip = 1) rd_set_hover_regs(RD_RegSlot_CtrlEntity); } + // rjf: hover -> rich hover commands (mini only) + if(ui_hovering(sig) && cell_info.cmd_name.size != 0 && cell->px != 0) + { + RD_RegsScope(.cmd_name = cell_info.cmd_name, .ui_key = sig.box->key) rd_set_hover_regs(RD_RegSlot_CmdName); + } + // rjf: dragging -> drag/drop if(ui_dragging(sig) && !contains_2f32(sig.box->rect, ui_mouse()) && (!cell_selected || !ewv->text_editing)) @@ -6135,10 +6141,28 @@ rd_window_frame(void) RD_RegSlot slot = ((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs_slot : rd_state->hover_regs_slot); RD_Regs *regs = (((rd_state->drag_drop_regs_slot != RD_RegSlot_Null && rd_drag_is_active()) ? rd_state->drag_drop_regs : rd_state->hover_regs)); CTRL_Entity *ctrl_entity = &ctrl_entity_nil; + ui_state->tooltip_anchor_key = regs->ui_key; + ui_state->tooltip_can_overflow_window = rd_drag_is_active(); switch(slot) { default:{}break; + //////////////////////// + //- rjf: command tooltips + // + case RD_RegSlot_CmdName: + UI_Tooltip + { + String8 cmd_name = regs->cmd_name; + DR_FStrList fstrs = rd_title_fstrs_from_code_name(scratch.arena, cmd_name); + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(5, 1)) + { + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(box, &fstrs); + rd_cmd_binding_buttons(cmd_name, str8_zero(), 0); + } + }break; + //////////////////////// //- rjf: file path tooltips // @@ -6294,13 +6318,16 @@ rd_window_frame(void) UI_Row { rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); - ui_spacer(ui_em(2.f, 1.f)); E_Eval eval = e_eval_from_string(rd_state->drag_drop_regs->expr); if(eval.irtree.mode != E_Mode_Null) { EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; String8 value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*20.f, eval); - rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); + if(value_string.size != 0) + { + ui_spacer(ui_em(2.f, 1.f)); + rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), value_string); + } } } }break; @@ -6584,6 +6611,7 @@ rd_window_frame(void) UI_Focus(UI_FocusKind_On) UI_BlurSize(10*rd_state->popup_t) UI_Transparency(1-rd_state->popup_t) + UI_TagF("floating") { bg_box = ui_build_box_from_stringf(UI_BoxFlag_FixedSize| UI_BoxFlag_Floating| @@ -6591,7 +6619,8 @@ rd_window_frame(void) UI_BoxFlag_Scroll| UI_BoxFlag_DefaultFocusNav| UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DrawBackgroundBlur, "###popup_%p", ws); + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_DrawBackground, "###popup_%p", ws); } if(rd_state->popup_active) UI_Parent(bg_box) UI_Transparency(1-rd_state->popup_t) { @@ -7420,7 +7449,7 @@ rd_window_frame(void) ui_labelf("Search for commands and options by pressing "); UI_Flags(UI_BoxFlag_DrawBorder) UI_TextAlignment(UI_TextAlign_Center) - rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero()); + rd_cmd_binding_buttons(rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, str8_zero(), 1); } ui_spacer(ui_em(1.f, 1.f)); UI_TagF("pop") @@ -7577,198 +7606,41 @@ rd_window_frame(void) Temp scratch = scratch_begin(0, 0); RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); - B32 have_targets = (targets.count != 0); B32 can_send_signal = !d_ctrl_targets_running(); - B32 can_play = (have_targets && (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())); - B32 can_pause = (!can_send_signal); - B32 can_stop = (processes.count != 0); - B32 can_step = (processes.count != 0 && can_send_signal); - - //- rjf: play button - if(can_play || !have_targets || processes.count == 0) - UI_TextAlignment(UI_TextAlign_Center) - UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_TagF(can_play ? "good" : "weak") + typedef struct CenterButtonTask CenterButtonTask; + struct CenterButtonTask { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Play]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(ui_hovering(sig) && !can_play) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); - } - if(ui_hovering(sig) && can_play) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - { - if(can_stop) - { - ui_labelf("Resume all processes"); - } - else - { - ui_labelf("Launch all active targets:"); - for(RD_CfgNode *n = targets.first; n != 0; n = n->next) - { - RD_Cfg *target = n->v; - B32 target_is_enabled = !rd_disabled_from_cfg(target); - if(target_is_enabled) - { - DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(ui_build_arena(), target); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(box, &title_fstrs); - } - } - } - } - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_Run); - } - } - - //- rjf: restart button - else UI_TextAlignment(UI_TextAlign_Center) - UI_TagF("good") + String8 cmd_name; + String8 tag; + B32 is_enabled; + }; + CenterButtonTask center_button_tasks[] = { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Redo]); + {rd_cmd_kind_info_table[RD_CmdKind_Run].string, str8_lit("good"), (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())}, + {rd_cmd_kind_info_table[RD_CmdKind_Restart].string, str8_lit("good"), processes.count != 0}, + {rd_cmd_kind_info_table[RD_CmdKind_Halt].string, str8_lit("weak"), !can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_KillAll].string, str8_lit("bad"), processes.count != 0}, + {rd_cmd_kind_info_table[RD_CmdKind_StepOver].string, str8_lit("weak"), can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_StepInto].string, str8_lit("weak"), can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_StepOut].string, str8_lit("weak"), processes.count != 0 && can_send_signal}, + }; + UI_TextAlignment(UI_TextAlign_Center) + for EachElement(idx, center_button_tasks) + UI_Flags(center_button_tasks[idx].is_enabled ? 0 : UI_BoxFlag_Disabled) + UI_Tag(center_button_tasks[idx].is_enabled ? center_button_tasks[idx].tag : str8_lit("")) + { + String8 cmd_name = center_button_tasks[idx].cmd_name; + UI_Signal sig = ui_button(rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); if(ui_hovering(sig)) { - UI_Tooltip RD_Font(RD_FontSlot_Main) - { - ui_labelf("Restart"); - } + RD_RegsScope(.cmd_name = cmd_name, .ui_key = sig.box->key) rd_set_hover_regs(RD_RegSlot_CmdName); } if(ui_clicked(sig)) { - rd_cmd(RD_CmdKind_Restart); + rd_push_cmd(cmd_name, rd_regs()); } } - - //- rjf: pause button - UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_pause ? 0 : UI_BoxFlag_Disabled) - UI_TagF("weak") - { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Pause]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(ui_hovering(sig) && !can_pause) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: Already halted"); - } - if(ui_hovering(sig) && can_pause) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Halt all attached processes"); - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_Halt); - } - } - - //- rjf: stop button - UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_stop ? 0 : UI_BoxFlag_Disabled) - UI_TagF(can_stop ? "bad" : "weak") - { - UI_Signal sig = {0}; - { - sig = ui_button(rd_icon_kind_text_table[RD_IconKind_Stop]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - } - if(ui_hovering(sig) && !can_stop) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Disabled: No processes are running"); - } - if(ui_hovering(sig) && can_stop) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Kill all attached processes"); - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_KillAll); - } - } - - //- rjf: step over button - UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_TagF("weak") - { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOver]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(ui_hovering(sig)) - { - if(can_play) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) ui_labelf("Step Over"); - } - else - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); - } - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_StepOver); - } - } - - //- rjf: step into button - UI_TextAlignment(UI_TextAlign_Center) UI_Flags((can_play ? 0 : UI_BoxFlag_Disabled)) - UI_TagF("weak") - { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepInto]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(ui_hovering(sig)) - { - if(can_play) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Step Into"); - } - else - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: %s", have_targets ? "Targets are currently running" : "No active targets exist"); - } - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_StepInto); - } - } - - //- rjf: step out button - UI_TextAlignment(UI_TextAlign_Center) UI_Flags(can_step ? 0 : UI_BoxFlag_Disabled) - UI_TagF("weak") - { - UI_Signal sig = ui_button(rd_icon_kind_text_table[RD_IconKind_StepOut]); - os_window_push_custom_title_bar_client_area(ws->os, sig.box->rect); - if(ui_hovering(sig) && !can_step && can_pause) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: Running"); - } - if(ui_hovering(sig) && !can_step && !can_stop) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Disabled: No processes are running"); - } - if(ui_hovering(sig) && can_step) - { - UI_Tooltip RD_Font(RD_FontSlot_Main) - ui_labelf("Step Out"); - } - if(ui_clicked(sig)) - { - rd_cmd(RD_CmdKind_StepOut); - } - } - scratch_end(scratch); } @@ -15917,7 +15789,7 @@ rd_frame(void) //- rjf: animate confirmation // { - F32 rate = rd_setting_b32_from_name(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-10.f * rd_state->frame_dt)) : 1.f; + F32 rate = rd_setting_b32_from_name(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-30.f * rd_state->frame_dt)) : 1.f; B32 popup_open = rd_state->popup_active; rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c0817f38..5ea5cddb 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -714,7 +714,7 @@ rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U64 progress_v_t //~ rjf: UI Widgets: Fancy Buttons internal void -rd_cmd_binding_buttons(String8 name, String8 filter) +rd_cmd_binding_buttons(String8 name, String8 filter, B32 add_new) { Temp scratch = scratch_begin(0, 0); RD_KeyMapNodePtrList key_map_nodes = rd_key_map_node_ptr_list_from_name(scratch.arena, name); @@ -722,6 +722,7 @@ rd_cmd_binding_buttons(String8 name, String8 filter) //- rjf: build buttons for each binding UI_CornerRadius(ui_top_font_size()*0.5f) for(RD_KeyMapNodePtr *n = key_map_nodes.first; n != 0; n = n->next) { + ui_spacer(ui_em(1.f, 1.f)); RD_Binding binding = n->v->binding; B32 rebinding_active_for_this_binding = (rd_state->bind_change_active && str8_match(rd_state->bind_change_cmd_name, name, 0) && @@ -826,40 +827,41 @@ rd_cmd_binding_buttons(String8 name, String8 filter) rd_state->bind_change_active = 0; } } - - //- rjf: space - ui_spacer(ui_em(1.f, 1.f)); } //- rjf: build "add new binding" button - B32 adding_new_binding = (rd_state->bind_change_active && - str8_match(rd_state->bind_change_cmd_name, name, 0) && - rd_state->bind_change_binding_id == 0); - RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") UI_CornerRadius(ui_top_font_size()*0.5f) + if(add_new) { - ui_set_next_text_alignment(UI_TextAlign_Center); - ui_set_next_group_key(ui_key_zero()); - ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.5f, 1)); - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| - UI_BoxFlag_Clickable| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground, - "%S###add_binding", rd_icon_kind_text_table[RD_IconKind_Add]); - UI_Signal sig = ui_signal_from_box(box); - if(ui_clicked(sig)) + B32 adding_new_binding = (rd_state->bind_change_active && + str8_match(rd_state->bind_change_cmd_name, name, 0) && + rd_state->bind_change_binding_id == 0); + ui_spacer(ui_em(1.f, 1.f)); + RD_Font(RD_FontSlot_Icons) UI_TagF(adding_new_binding ? "pop" : "") UI_CornerRadius(ui_top_font_size()*0.5f) { - if(!rd_state->bind_change_active && ui_clicked(sig)) + ui_set_next_text_alignment(UI_TextAlign_Center); + ui_set_next_group_key(ui_key_zero()); + ui_set_next_pref_width(ui_text_dim(ui_top_font_size()*1.5f, 1)); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_Clickable| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground, + "%S###add_binding", rd_icon_kind_text_table[RD_IconKind_Add]); + UI_Signal sig = ui_signal_from_box(box); + if(ui_clicked(sig)) { - arena_clear(rd_state->bind_change_arena); - rd_state->bind_change_active = 1; - rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); - rd_state->bind_change_binding_id = 0; - } - else if(rd_state->bind_change_active && ui_clicked(sig)) - { - rd_state->bind_change_active = 0; + if(!rd_state->bind_change_active && ui_clicked(sig)) + { + arena_clear(rd_state->bind_change_arena); + rd_state->bind_change_active = 1; + rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); + rd_state->bind_change_binding_id = 0; + } + else if(rd_state->bind_change_active && ui_clicked(sig)) + { + rd_state->bind_change_active = 0; + } } } } @@ -913,7 +915,7 @@ rd_cmd_spec_button(String8 name) UI_TagF("weak") UI_FastpathCodepoint(0) { - rd_cmd_binding_buttons(name, str8_zero()); + rd_cmd_binding_buttons(name, str8_zero(), 1); } } } @@ -3473,7 +3475,7 @@ rd_cell(RD_CellParams *params, String8 string) { UI_PrefWidth(ui_children_sum(1)) UI_Row UI_Padding(ui_em(1.f, 1.f)) { - rd_cmd_binding_buttons(params->bindings_name, params->search_needle); + rd_cmd_binding_buttons(params->bindings_name, params->search_needle, 1); } } } diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index f801fc1a..57dcd7f2 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -140,7 +140,7 @@ internal void rd_loading_overlay(Rng2F32 rect, F32 loading_t, U64 progress_v, U6 //////////////////////////////// //~ rjf: UI Widgets: Fancy Buttons -internal void rd_cmd_binding_buttons(String8 name, String8 filter); +internal void rd_cmd_binding_buttons(String8 name, String8 filter, B32 add_new); internal UI_Signal rd_menu_bar_button(String8 string); internal UI_Signal rd_cmd_spec_button(String8 name); internal void rd_cmd_list_menu_buttons(U64 count, String8 *cmd_names, U32 *fastpath_codepoints); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 245373d3..2ed424ff 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -805,6 +805,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->ctx_menu_changed = 0; ui_state->default_animation_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); ui_state->tooltip_can_overflow_window = 0; + ui_state->tooltip_anchor_key = ui_key_zero(); ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; ui_state->tags_cache_slots_count = 512; ui_state->tags_cache_slots = push_array(ui_build_arena(), UI_TagsCacheSlot, ui_state->tags_cache_slots_count); @@ -1248,6 +1249,22 @@ ui_end_build(void) } } + //- rjf: anchor tooltips + if(!ui_key_match(ui_state->tooltip_anchor_key, ui_key_zero())) + { + UI_Box *anchor_box = ui_box_from_key(ui_state->tooltip_anchor_key); + if(!ui_box_is_nil(anchor_box)) + { + ui_state->tooltip_root->rect.x0 = anchor_box->rect.x0; + ui_state->tooltip_root->rect.y0 = anchor_box->rect.y1 + anchor_box->font_size*0.5f; + } + else + { + ui_state->tooltip_root->rect.x0 = 10000; + ui_state->tooltip_root->rect.y0 = 10000; + } + } + //- rjf: ensure special floating roots are within screen bounds UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root}; B32 force_contain[] = diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 96bcb795..d0461bf9 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -676,6 +676,7 @@ struct UI_State //- rjf: build state machine state B32 is_in_open_ctx_menu; B32 tooltip_can_overflow_window; + UI_Key tooltip_anchor_key; String8Array current_gen_tags; U64 current_gen_tags_gen; UI_TagsKeyStackNode *tags_key_stack_top; From 23601f38a2f0df87953e548cc7387822548bbeb1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 14:17:57 -0700 Subject: [PATCH 536/755] more run-in-invalid-state case tweaks --- src/raddbg/raddbg_core.c | 9 +++++++++ src/ui/ui_core.c | 7 +++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6b8f6155..e94f2fca 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12088,6 +12088,15 @@ rd_frame(void) } } + // rjf: run -> no targets at all, no processes? -> do helper for add-target + if((kind == RD_CmdKind_Run || + kind == RD_CmdKind_StepInto || + kind == RD_CmdKind_StepOver) && targets.count == 0 && processes.count == 0) + { + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[RD_CmdKind_AddTarget].string); + break; + } + // rjf: run -> no active targets, no processes? -> do helper for launch-and-run if((kind == RD_CmdKind_Run || kind == RD_CmdKind_StepInto || diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 2ed424ff..dfc614e7 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1255,8 +1255,11 @@ ui_end_build(void) UI_Box *anchor_box = ui_box_from_key(ui_state->tooltip_anchor_key); if(!ui_box_is_nil(anchor_box)) { - ui_state->tooltip_root->rect.x0 = anchor_box->rect.x0; - ui_state->tooltip_root->rect.y0 = anchor_box->rect.y1 + anchor_box->font_size*0.5f; + Vec2F32 dim = dim_2f32(ui_state->tooltip_root->rect); + ui_state->tooltip_root->fixed_position.x = ui_state->tooltip_root->rect.x0 = anchor_box->rect.x0; + ui_state->tooltip_root->fixed_position.y = ui_state->tooltip_root->rect.y0 = anchor_box->rect.y1 + anchor_box->font_size*0.5f; + ui_state->tooltip_root->rect.x1 = ui_state->tooltip_root->rect.x0 + dim.x; + ui_state->tooltip_root->rect.y1 = ui_state->tooltip_root->rect.y0 + dim.y; } else { From afc3a1a8185871c1ca452ee7d22e24beba4f15c3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 16:43:20 -0700 Subject: [PATCH 537/755] begin memory view pass --- src/raddbg/generated/raddbg.meta.c | 6 +- src/raddbg/raddbg.mdesk | 15 +- src/raddbg/raddbg_core.c | 20 +- src/raddbg/raddbg_views.c | 360 ++++++++++++++++++----------- 4 files changed, 245 insertions(+), 156 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index b2f8aab6..ca54b5ae 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -399,7 +399,7 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[23] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme Colors') @description(\"Additional theme colors which are applied on top of the project's theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, @@ -407,7 +407,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n @default(1) @description(\"The number of bytes that each cell should represent.\")\n 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': code_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, @@ -946,7 +946,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccffff }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccffff }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 7a302ff9..cfac11bd 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -245,6 +245,10 @@ RD_VocabTable: @display_name('Theme Colors') @description("Additional theme colors which are applied on top of the theme file or preset.") 'theme_colors': query, + //- rjf: autocompletion + @display_name('Autocompletion Lister') @description("Enables the autocompletion lister while typing expressions.") @default(1) + 'autocompletion_lister': bool, + //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") 'thread_lines': bool, @@ -487,14 +491,16 @@ RD_VocabTable: ``` @inherit(tab) x: { - @description("An expression to describe the base address or offset of the memory view.") + @display_name("Base Address") @description("An expression to describe the base address or offset of the memory view.") 'expression': code_string, - @description("The number of bytes of the viewed memory range.") + @display_name("Address Range Size") @description("The number of bytes of the viewed memory range.") 'size': code_string, + @display_name("Cursor Address") @description("The address of the cursor.") + 'cursor': code_string, + @display_name("Cursor Size") @description("The size, in bytes, of the cursor.") + 'cursor_size': @range[1, 16] u64, @default(16) @description("The number of columns to build before building new rows.") 'num_columns': @range[1, 64] u64, - @default(1) @description("The number of bytes that each cell should represent.") - 'bytes_per_cell': @range[1, 8] u64, } ``` } @@ -1358,6 +1364,7 @@ RD_ThemePresetTable: theme_color: {tags:"text", value: 0xe5e5e5ff } theme_color: {tags:"weak text", value: 0xa4a4a4ff } theme_color: {tags:"good text", value: 0x32a852ff } + theme_color: {tags:"neutral text", value: 0x3a90bbff } theme_color: {tags:"bad text", value: 0xcf5242ff } theme_color: {tags:"hover", value: 0xffffffff } theme_color: {tags:"focus", value: 0xfda200ff } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e94f2fca..17cf8baa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6675,7 +6675,7 @@ rd_window_frame(void) RD_Font(RD_FontSlot_Code) { //- rjf: add autocompletion view task - if(ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index) + if(rd_setting_b32_from_name(str8_lit("autocompletion_lister")) && ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index) { // rjf: build view RD_Cfg *root = rd_immediate_cfg_from_keyf("autocomp_view_%I64x", window->id); @@ -7616,18 +7616,18 @@ rd_window_frame(void) }; CenterButtonTask center_button_tasks[] = { - {rd_cmd_kind_info_table[RD_CmdKind_Run].string, str8_lit("good"), (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())}, - {rd_cmd_kind_info_table[RD_CmdKind_Restart].string, str8_lit("good"), processes.count != 0}, - {rd_cmd_kind_info_table[RD_CmdKind_Halt].string, str8_lit("weak"), !can_send_signal}, - {rd_cmd_kind_info_table[RD_CmdKind_KillAll].string, str8_lit("bad"), processes.count != 0}, - {rd_cmd_kind_info_table[RD_CmdKind_StepOver].string, str8_lit("weak"), can_send_signal}, - {rd_cmd_kind_info_table[RD_CmdKind_StepInto].string, str8_lit("weak"), can_send_signal}, - {rd_cmd_kind_info_table[RD_CmdKind_StepOut].string, str8_lit("weak"), processes.count != 0 && can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_Run].string, str8_lit("good"), (can_send_signal || d_ctrl_last_run_frame_idx()+4 > d_frame_index())}, + {rd_cmd_kind_info_table[RD_CmdKind_Restart].string, str8_lit("neutral"), processes.count != 0}, + {rd_cmd_kind_info_table[RD_CmdKind_Halt].string, str8_lit("weak"), !can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_KillAll].string, str8_lit("bad"), processes.count != 0}, + {rd_cmd_kind_info_table[RD_CmdKind_StepOver].string, str8_lit("weak"), can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_StepInto].string, str8_lit("weak"), can_send_signal}, + {rd_cmd_kind_info_table[RD_CmdKind_StepOut].string, str8_lit("weak"), processes.count != 0 && can_send_signal}, }; UI_TextAlignment(UI_TextAlign_Center) for EachElement(idx, center_button_tasks) UI_Flags(center_button_tasks[idx].is_enabled ? 0 : UI_BoxFlag_Disabled) - UI_Tag(center_button_tasks[idx].is_enabled ? center_button_tasks[idx].tag : str8_lit("")) + UI_Tag(center_button_tasks[idx].is_enabled ? center_button_tasks[idx].tag : str8_lit("weak")) { String8 cmd_name = center_button_tasks[idx].cmd_name; UI_Signal sig = ui_button(rd_icon_kind_text_table[rd_icon_kind_from_code_name(cmd_name)]); @@ -10161,7 +10161,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) } else { - log_user_errorf("Couldn't evaluate \"%S\" as an address.", string); + log_user_errorf("Couldn't evaluate `%S` as an address.", string); } }break; } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3e9be2cb..cc6ee83a 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2336,6 +2336,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) typedef struct RD_MemoryViewState RD_MemoryViewState; struct RD_MemoryViewState { + Rng1U64 last_view_range; + Rng1U64 last_cursor_range; B32 center_cursor; B32 contain_cursor; }; @@ -2352,42 +2354,44 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - HS_Scope *hs_scope = hs_scope_open(); RD_MemoryViewState *mv = rd_view_state(RD_MemoryViewState); ////////////////////////////// //- rjf: unpack parameterization info // - Rng1U64 space_range = e_range_from_eval(eval); + F32 main_font_size = ui_bottom_font_size(); + Rng1U64 view_range = e_range_from_eval(eval); U64 base_offset = e_base_offset_from_eval(eval); U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; if(size == 0) { size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); } - space_range = r1u64(base_offset, base_offset+size); + view_range = r1u64(base_offset, base_offset+size); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); - space_range = rd_whole_range_from_eval_space(eval.space); + view_range = rd_whole_range_from_eval_space(eval.space); } - if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity && dim_1u64(space_range) == KB(16)) + if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity && dim_1u64(view_range) == KB(16)) { - space_range = r1u64(0, 0x7FFFFFFFFFFFull); + view_range = r1u64(0, 0x7FFFFFFFFFFFull); } - U64 cursor = rd_view_cfg_u64_from_string(str8_lit("cursor_vaddr")); - U64 mark = rd_view_cfg_u64_from_string(str8_lit("mark_vaddr")); - U64 bytes_per_cell = rd_view_cfg_u64_from_string(str8_lit("bytes_per_cell")); + U64 cursor_base_vaddr = rd_view_cfg_u64_from_string(str8_lit("cursor")); + U64 mark_base_vaddr = rd_view_cfg_u64_from_string(str8_lit("mark")); + U64 cursor_size = rd_view_cfg_u64_from_string(str8_lit("cursor_size")); + cursor_size = ClampBot(1, cursor_size); + U64 initial_cursor_base_vaddr = cursor_base_vaddr; + U64 initial_mark_base_vaddr = mark_base_vaddr; U64 num_columns = rd_view_cfg_u64_from_string(str8_lit("num_columns")); if(num_columns == 0) { num_columns = 16; } num_columns = ClampBot(1, num_columns); - bytes_per_cell = ClampBot(1, bytes_per_cell); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); Vec4F32 selection_color = ui_color_from_name(str8_lit("selection")); - Vec4F32 border_color = ui_color_from_name(str8_lit("border")); + Vec4F32 border_color = ui_color_from_name(str8_lit("selection")); ////////////////////////////// //- rjf: process commands @@ -2408,7 +2412,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) }break; case RD_CmdKind_GoToAddress: { - cursor = mark = cmd->regs->vaddr; + cursor_base_vaddr = mark_base_vaddr = cmd->regs->vaddr; mv->center_cursor = 1; }break; } @@ -2422,47 +2426,68 @@ RD_VIEW_UI_FUNCTION_DEF(memory) F32 font_size = ui_top_font_size(); F32 big_glyph_advance = fnt_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; F32 row_height_px = floor_f32(font_size*2.f); - F32 cell_width_px = floor_f32(font_size*2.f * bytes_per_cell); - F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); - Vec2F32 panel_dim = dim_2f32(rect); - F32 footer_dim = font_size*10.f; - Rng2F32 header_rect = r2f32p(0, 0, panel_dim.x, row_height_px); - Rng2F32 footer_rect = r2f32p(0, panel_dim.y-footer_dim, panel_dim.x, panel_dim.y); - Rng2F32 content_rect = r2f32p(0, row_height_px, panel_dim.x-scroll_bar_dim, footer_rect.y0); + F32 cell_width_px = floor_f32(font_size*2.f); ////////////////////////////// //- rjf: determine legal scroll range // - Rng1S64 scroll_idx_rng = r1s64(0, dim_1u64(space_range)/num_columns); + U64 view_range_last = view_range.max; + if(view_range_last != 0) + { + view_range_last -= 1; + } + Rng1S64 scroll_idx_rng = r1s64(0, (view_range_last - view_range.min) / num_columns); ////////////////////////////// - //- rjf: determine info about visible range of rows + //- rjf: determine visible range of rows // Rng1S64 viz_range_rows = {0}; - Rng1U64 viz_range_bytes = {0}; S64 num_possible_visible_rows = 0; { - num_possible_visible_rows = dim_2f32(content_rect).y/row_height_px; + num_possible_visible_rows = dim_2f32(rect).y/row_height_px; viz_range_rows.min = scroll_pos.y.idx + (S64)scroll_pos.y.off - !!(scroll_pos.y.off<0); viz_range_rows.max = scroll_pos.y.idx + (S64)scroll_pos.y.off + num_possible_visible_rows, viz_range_rows.min = clamp_1s64(scroll_idx_rng, viz_range_rows.min); viz_range_rows.max = clamp_1s64(scroll_idx_rng, viz_range_rows.max); - viz_range_bytes.min = space_range.min + viz_range_rows.min*num_columns; - viz_range_bytes.max = space_range.min + (viz_range_rows.max+1)*num_columns+1; - if(viz_range_bytes.min > viz_range_bytes.max) - { - Swap(U64, viz_range_bytes.min, viz_range_bytes.max); - } - viz_range_bytes = intersect_1u64(space_range, viz_range_bytes); } + ////////////////////////////// + //- rjf: calculate rectangles + // + F32 scroll_bar_dim = floor_f32(main_font_size*1.5f); + Vec2F32 panel_dim = dim_2f32(rect); + F32 footer_dim = floor_f32(main_font_size*10.f); + Rng2F32 header_rect = r2f32p(0, 0, panel_dim.x, row_height_px); + Rng2F32 footer_rect = r2f32p(0, panel_dim.y-footer_dim, panel_dim.x-scroll_bar_dim, panel_dim.y); + Rng2F32 content_rect = r2f32p(0, row_height_px, panel_dim.x-scroll_bar_dim, panel_dim.y); + + ////////////////////////////// + //- rjf: bump backwards if we are past the first + if(viz_range_rows.min > 0) + { + viz_range_rows.min -= 1; + content_rect.y0 -= row_height_px; + } + + ////////////////////////////// + //- rjf: determine visible range of bytes + // + Rng1U64 viz_range_bytes = {0}; + viz_range_bytes.min = view_range.min + (viz_range_rows.min)*num_columns; + viz_range_bytes.max = view_range.min + (viz_range_rows.max+1)*num_columns+1; + if(viz_range_bytes.min > viz_range_bytes.max) + { + Swap(U64, viz_range_bytes.min, viz_range_bytes.max); + } + viz_range_bytes = intersect_1u64(view_range, viz_range_bytes); + ////////////////////////////// //- rjf: take keyboard controls // UI_Focus(UI_FocusKind_On) if(ui_is_focus_active()) { - U64 next_cursor = cursor; - U64 next_mark = mark; + U64 next_cursor_base_vaddr = cursor_base_vaddr; + U64 next_mark_base_vaddr = mark_base_vaddr; for(UI_Event *evt = 0; ui_next_event(&evt);) { Vec2S64 cell_delta = {0}; @@ -2479,11 +2504,11 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { if(evt->delta_2s32.x < 0) { - cell_delta.x = -(S64)(cursor%num_columns); + cell_delta.x = -(S64)(cursor_base_vaddr%num_columns); } else if(evt->delta_2s32.x > 0) { - cell_delta.x = (num_columns-1) - (S64)(cursor%num_columns); + cell_delta.x = (num_columns-1) - (S64)(cursor_base_vaddr%num_columns); } if(evt->delta_2s32.y < 0) { @@ -2500,31 +2525,31 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { good_action = 1; } - if(good_action && evt->flags & UI_EventFlag_ZeroDeltaOnSelect && cursor != mark) + if(good_action && evt->flags & UI_EventFlag_ZeroDeltaOnSelect && cursor_base_vaddr != mark_base_vaddr) { MemoryZeroStruct(&cell_delta); } if(good_action) { - cell_delta.x = ClampBot(cell_delta.x, (S64)-next_cursor); - cell_delta.y = ClampBot(cell_delta.y, (S64)-(next_cursor/num_columns)); - next_cursor += cell_delta.x; - next_cursor += cell_delta.y*num_columns; + cell_delta.x = ClampBot(cell_delta.x, (S64)-next_cursor_base_vaddr); + cell_delta.y = ClampBot(cell_delta.y, (S64)-(next_cursor_base_vaddr/num_columns)); + next_cursor_base_vaddr += cell_delta.x; + next_cursor_base_vaddr += cell_delta.y*num_columns; } - if(good_action && evt->flags & UI_EventFlag_PickSelectSide && cursor != mark) + if(good_action && evt->flags & UI_EventFlag_PickSelectSide && cursor_base_vaddr != mark_base_vaddr) { if(evt->delta_2s32.x < 0 || evt->delta_2s32.y < 0) { - next_cursor = Min(cursor, mark); + next_cursor_base_vaddr = Min(cursor_base_vaddr, mark_base_vaddr); } else { - next_cursor = Max(cursor, mark); + next_cursor_base_vaddr = Max(cursor_base_vaddr, mark_base_vaddr); } } if(good_action && !(evt->flags & UI_EventFlag_KeepMark)) { - next_mark = next_cursor; + next_mark_base_vaddr = next_cursor_base_vaddr; } if(good_action) { @@ -2532,21 +2557,54 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_eat_event(evt); } } - cursor = next_cursor; - mark = next_mark; + cursor_base_vaddr = next_cursor_base_vaddr; + mark_base_vaddr = next_mark_base_vaddr; } ////////////////////////////// //- rjf: clamp cursor // + Rng1U64 cursor_valid_rng = view_range; + if(cursor_valid_rng.max != 0) { - Rng1U64 cursor_valid_rng = space_range; - if(cursor_valid_rng.max != 0) - { - cursor_valid_rng.max -= 1; - } - cursor = clamp_1u64(cursor_valid_rng, cursor); - mark = clamp_1u64(cursor_valid_rng, mark); + cursor_valid_rng.max -= 1; + } + if(cursor_base_vaddr != initial_cursor_base_vaddr) + { + cursor_base_vaddr = clamp_1u64(cursor_valid_rng, cursor_base_vaddr); + } + if(mark_base_vaddr != initial_mark_base_vaddr) + { + mark_base_vaddr = clamp_1u64(cursor_valid_rng, mark_base_vaddr); + } + + ////////////////////////////// + //- rjf: unpack post-move cursor/mark info + // + Rng1U64 cursor_range = r1u64(cursor_base_vaddr, cursor_base_vaddr + cursor_size); + Rng1U64 mark_range = r1u64(mark_base_vaddr, mark_base_vaddr + cursor_size); + Rng1U64 selection = union_1u64(r1u64(cursor_base_vaddr, cursor_base_vaddr+cursor_size-1), + r1u64(mark_base_vaddr, mark_base_vaddr+cursor_size-1)); + + ////////////////////////////// + //- rjf: center cursor if range has changed + // + if(mv->last_view_range.max != view_range.max || + mv->last_view_range.min != view_range.min) + { + mv->center_cursor = 1; + mv->last_view_range = view_range; + } + + ////////////////////////////// + //- rjf: match mark to cursor if cursor has changed + // + if(mv->last_cursor_range.min != cursor_range.min || + mv->last_cursor_range.max != cursor_range.max) + { + mv->contain_cursor = 1; + mv->last_cursor_range = cursor_range; + mark_range = cursor_range; } ////////////////////////////// @@ -2555,7 +2613,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) if(mv->center_cursor) { mv->center_cursor = 0; - S64 cursor_row_idx = cursor/num_columns; + S64 cursor_row_idx = (cursor_base_vaddr - view_range.min) / num_columns; S64 new_idx = (cursor_row_idx-num_possible_visible_rows/2+1); new_idx = clamp_1s64(scroll_idx_rng, new_idx); ui_scroll_pt_target_idx(&scroll_pos.y, new_idx); @@ -2567,7 +2625,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) if(mv->contain_cursor) { mv->contain_cursor = 0; - S64 cursor_row_idx = cursor/num_columns; + S64 cursor_row_idx = (cursor_base_vaddr - view_range.min) / num_columns; Rng1S64 cursor_viz_range = r1s64(clamp_1s64(scroll_idx_rng, cursor_row_idx-2), clamp_1s64(scroll_idx_rng, cursor_row_idx+3)); S64 min_delta = Min(0, cursor_viz_range.min-viz_range_rows.min); S64 max_delta = Max(0, cursor_viz_range.max-viz_range_rows.max); @@ -2577,11 +2635,12 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } ////////////////////////////// - //- rjf: produce fancy string runs for all possible byte values in all cells + //- rjf: produce fancy strings for all possible byte values in all cells // DR_FStrList byte_fstrs[256] = {0}; { - Vec4F32 full_color = ui_color_from_name(str8_lit("text")); + Vec4F32 full_color = {0}; + UI_TagF("neutral") full_color = ui_color_from_name(str8_lit("text")); Vec4F32 zero_color = full_color; UI_TagF("weak") zero_color = ui_color_from_name(str8_lit("text")); for(U64 idx = 0; idx < ArrayCount(byte_fstrs); idx += 1) @@ -2759,27 +2818,49 @@ RD_VIEW_UI_FUNCTION_DEF(memory) container_box = ui_build_box_from_stringf(0, "memory_view_container"); } + ////////////////////////////// + //- rjf: build scroll bar + // + UI_Parent(container_box) UI_FontSize(main_font_size) + { + ui_set_next_fixed_x(content_rect.x1); + ui_set_next_fixed_y(0); + ui_set_next_fixed_width(scroll_bar_dim); + ui_set_next_fixed_height(dim_2f32(rect).y); + { + scroll_pos.y = ui_scroll_bar(Axis2_Y, + ui_px(scroll_bar_dim, 1.f), + scroll_pos.y, + scroll_idx_rng, + num_possible_visible_rows); + } + } + ////////////////////////////// //- rjf: build header // UI_Box *header_box = &ui_nil_box; - UI_Parent(container_box) + UI_Parent(container_box) UI_TagF("floating") { - UI_WidthFill UI_PrefHeight(ui_px(row_height_px, 1.f)) UI_Row - header_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideBottom, "table_header"); + UI_Rect(r2f32p(0, 0, dim_2f32(rect).x - scroll_bar_dim, row_height_px)) + header_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideBottom| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackgroundBlur| + UI_BoxFlag_Floating, "table_header"); UI_Parent(header_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) - UI_TagF("weak") { UI_PrefWidth(ui_px(big_glyph_advance*20.f, 1.f)) ui_labelf("Address"); UI_PrefWidth(ui_px(cell_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) { - Rng1U64 col_selection_rng = r1u64(cursor%num_columns, mark%num_columns); - for(U64 row_off = 0; row_off < num_columns*bytes_per_cell; row_off += bytes_per_cell) + Rng1U64 col_selection_rng = r1u64(cursor_base_vaddr%num_columns, mark_base_vaddr%num_columns); + for(U64 row_off = 0; row_off < num_columns; row_off += 1) { - ui_labelf("%I64X", row_off); + B32 column_is_selected = (selection.min%num_columns <= row_off && row_off <= selection.max%num_columns); + UI_TagF(column_is_selected ? "" : "weak") ui_labelf("%I64X", row_off); } } ui_spacer(ui_px(big_glyph_advance*1.5f, 1.f)); @@ -2788,20 +2869,46 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } ////////////////////////////// - //- rjf: build scroll bar + //- rjf: build footer // - UI_Parent(container_box) + UI_Box *footer_box = &ui_nil_box; + UI_Parent(container_box) UI_FontSize(main_font_size) UI_TagF("floating") { - ui_set_next_fixed_x(content_rect.x1); - ui_set_next_fixed_y(content_rect.y0); - ui_set_next_fixed_width(scroll_bar_dim); - ui_set_next_fixed_height(dim_2f32(content_rect).y); + ui_set_next_fixed_x(footer_rect.x0); + ui_set_next_fixed_y(footer_rect.y0); + ui_set_next_fixed_width(dim_2f32(footer_rect).x); + ui_set_next_fixed_height(dim_2f32(footer_rect).y); + footer_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_DrawDropShadow, "footer"); + UI_Parent(footer_box) RD_Font(RD_FontSlot_Code) { - scroll_pos.y = ui_scroll_bar(Axis2_Y, - ui_px(scroll_bar_dim, 1.f), - scroll_pos.y, - scroll_idx_rng, - num_possible_visible_rows); + UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_TagF("weak") + UI_PrefHeight(ui_em(2.f, 0.f)) + { + ui_labelf("Address:"); + ui_labelf("U8:"); + ui_labelf("U16:"); + ui_labelf("U32:"); + ui_labelf("U64:"); + } + UI_PrefWidth(ui_em(45.f, 1.f)) UI_HeightFill UI_Column + UI_PrefHeight(ui_em(2.f, 0.f)) + { + ui_labelf("%016I64X", cursor_base_vaddr); + { + U64 as_u8 = 0; + U64 as_u16 = 0; + U64 as_u32 = 0; + U64 as_u64 = 0; + e_space_read(eval.space, &as_u64, r1u64(cursor_base_vaddr, cursor_base_vaddr+1)); + as_u32 = *(U32 *)&as_u64; + as_u16 = *(U16 *)&as_u64; + as_u8 = *(U8 *)&as_u64; + ui_labelf("%02X (%I64u)", as_u8, as_u8); + ui_labelf("%04X (%I64u)", as_u16, as_u16); + ui_labelf("%08X (%I64u)", as_u32, as_u32); + ui_labelf("%016I64X (%I64u)", as_u64, as_u64); + } + } } } @@ -2815,10 +2922,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_set_next_fixed_y(content_rect.y0); ui_set_next_fixed_width(dim_2f32(content_rect).x); ui_set_next_fixed_height(dim_2f32(content_rect).y); - ui_set_next_child_layout_axis(Axis2_Y); scrollable_box = ui_build_box_from_stringf(UI_BoxFlag_Clip| UI_BoxFlag_Scroll| - UI_BoxFlag_AllowOverflowX| UI_BoxFlag_AllowOverflowY, "scrollable_box"); container_box->view_off.x = container_box->view_off_target.x = scroll_pos.x.idx + scroll_pos.x.off; @@ -2833,7 +2938,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) UI_Parent(scrollable_box) UI_WidthFill UI_HeightFill { ui_set_next_child_layout_axis(Axis2_Y); - ui_set_next_hover_cursor(OS_Cursor_IBar); row_container_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable, "row_container"); UI_Parent(row_container_box) { @@ -2888,11 +2992,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { mv->contain_cursor = 1; } - cursor = mouse_hover_byte_num-1; - cursor = clamp_1u64(space_range, cursor); + cursor_base_vaddr = mouse_hover_byte_num-1; if(ui_pressed(sig)) { - mark = cursor; + mark_base_vaddr = cursor_base_vaddr; } } @@ -2922,24 +3025,25 @@ RD_VIEW_UI_FUNCTION_DEF(memory) // UI_Parent(row_container_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) { - Rng1U64 selection = r1u64(cursor, mark); U8 *row_ascii_buffer = push_array(scratch.arena, U8, num_columns); UI_WidthFill UI_PrefHeight(ui_px(row_height_px, 1.f)) for(S64 row_idx = viz_range_rows.min; row_idx <= viz_range_rows.max; row_idx += 1) { - Rng1U64 row_range_bytes = r1u64(space_range.min + row_idx*num_columns, - space_range.min + (row_idx+1)*num_columns); - if(row_range_bytes.min >= space_range.max) + Rng1U64 row_range_bytes = r1u64(view_range.min + row_idx*num_columns, view_range.min + (row_idx+1)*num_columns); + if(row_range_bytes.min >= view_range.max) { break; } - B32 row_is_boundary = 0; - if(row_range_bytes.min%64 == 0) + UI_BoxFlags row_flags = 0; + if(row_range_bytes.min <= selection.min && selection.min < row_range_bytes.max) { - row_is_boundary = 1; - ui_set_next_tag(str8_lit("pop")); + row_flags |= UI_BoxFlag_DrawSideTop; } - UI_Box *row = ui_build_box_from_stringf(UI_BoxFlag_DrawSideTop*!!row_is_boundary, "row_%I64x", row_range_bytes.min); + if(row_range_bytes.min <= selection.max && selection.max < row_range_bytes.max) + { + row_flags |= UI_BoxFlag_DrawSideBottom; + } + UI_Box *row = ui_build_box_from_stringf(row_flags, "row_%I64x", row_range_bytes.min); UI_Parent(row) { UI_PrefWidth(ui_px(big_glyph_advance*20.f, 1.f)) @@ -3000,6 +3104,14 @@ RD_VIEW_UI_FUNCTION_DEF(memory) cell_bg_rgba = selection_color; cell_bg_rgba.w *= 0.2f; } + if(selection.min%num_columns == col_idx) + { + cell_flags |= UI_BoxFlag_DrawSideLeft; + } + if(selection.max%num_columns == col_idx) + { + cell_flags |= UI_BoxFlag_DrawSideRight; + } // rjf: build ui_set_next_background_color(cell_bg_rgba); @@ -3108,53 +3220,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } - ////////////////////////////// - //- rjf: build footer - // - UI_Box *footer_box = &ui_nil_box; - UI_Parent(container_box) - { - ui_set_next_fixed_x(footer_rect.x0); - ui_set_next_fixed_y(footer_rect.y0); - ui_set_next_fixed_width(dim_2f32(footer_rect).x); - ui_set_next_fixed_height(dim_2f32(footer_rect).y); - footer_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, "footer"); - UI_Parent(footer_box) RD_Font(RD_FontSlot_Code) UI_FontSize(font_size) - { - UI_PrefWidth(ui_em(7.5f, 1.f)) UI_HeightFill UI_Column UI_TagF("weak") - UI_PrefHeight(ui_px(row_height_px, 0.f)) - { - ui_labelf("Address:"); - ui_labelf("U8:"); - ui_labelf("U16:"); - ui_labelf("U32:"); - ui_labelf("U64:"); - } - UI_PrefWidth(ui_em(45.f, 1.f)) UI_HeightFill UI_Column - UI_PrefHeight(ui_px(row_height_px, 0.f)) - { - B32 cursor_in_range = (viz_range_bytes.min <= cursor && cursor+8 <= viz_range_bytes.max); - ui_labelf("%016I64X", cursor); - if(cursor_in_range) - { - U64 as_u8 = 0; - U64 as_u16 = 0; - U64 as_u32 = 0; - U64 as_u64 = 0; - U64 cursor_off = cursor-viz_range_bytes.min; - as_u8 = (U64)*(U8 *)(visible_memory + cursor_off); - as_u16 = (U64)*(U16*)(visible_memory + cursor_off); - as_u32 = (U64)*(U32*)(visible_memory + cursor_off); - as_u64 = (U64)*(U64*)(visible_memory + cursor_off); - ui_labelf("%02X (%I64u)", as_u8, as_u8); - ui_labelf("%04X (%I64u)", as_u16, as_u16); - ui_labelf("%08X (%I64u)", as_u32, as_u32); - ui_labelf("%016I64X (%I64u)", as_u64, as_u64); - } - } - } - } - ////////////////////////////// //- rjf: scroll // @@ -3168,14 +3233,31 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } } + ////////////////////////////// + //- rjf: re-clamp + // + if(cursor_base_vaddr != initial_cursor_base_vaddr) + { + cursor_base_vaddr = clamp_1u64(cursor_valid_rng, cursor_base_vaddr); + } + if(mark_base_vaddr != initial_mark_base_vaddr) + { + mark_base_vaddr = clamp_1u64(cursor_valid_rng, mark_base_vaddr); + } + ////////////////////////////// //- rjf: save parameters // - rd_store_view_param_u64(str8_lit("cursor_vaddr"), cursor); - rd_store_view_param_u64(str8_lit("mark_vaddr"), mark); + if(cursor_base_vaddr != initial_cursor_base_vaddr) + { + rd_store_view_param_u64(str8_lit("cursor"), cursor_base_vaddr); + } + if(mark_base_vaddr != initial_mark_base_vaddr) + { + rd_store_view_param_u64(str8_lit("mark"), mark_base_vaddr); + } rd_store_view_scroll_pos(scroll_pos); - hs_scope_close(hs_scope); scratch_end(scratch); ProfEnd(); } From 2dbe8d42ebb81fc5e77624a5858bc99518a59931 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 1 May 2025 17:04:29 -0700 Subject: [PATCH 538/755] eliminate more old view settings code, simplify new, also clean up the targetless launch flow even more - if we only have one target, but it's inactive, and the user is trying to launch, then it doesn't hurt to just act as if that target was selected, then select it for them... --- src/eval/eval_core.c | 46 ---------------- src/eval/eval_core.h | 1 - src/raddbg/raddbg_core.c | 109 ++++++++++++-------------------------- src/raddbg/raddbg_core.h | 11 ++-- src/raddbg/raddbg_views.c | 60 ++++++++++++--------- 5 files changed, 73 insertions(+), 154 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 18e8c407..3212437d 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1219,52 +1219,6 @@ e_base_offset_from_eval(E_Eval eval) return eval.value.u64; } -internal Rng1U64 -e_range_from_eval(E_Eval eval) -{ - U64 size = 0; - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) - { - size = e_value_from_expr(arg->first->next).u64; - break; - } - } - } - 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); - E_TypeKey direct_type_key = e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(direct_type_key); - } - if(size == 0 && eval.irtree.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Union || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Array)) - { - size = e_type_byte_size_from_key(type_key); - } - if(size == 0) - { - size = KB(16); - } - Rng1U64 result = {0}; - result.min = e_base_offset_from_eval(eval); - result.max = result.min + size; - return result; -} - - //////////////////////////////// //~ rjf: Debug Functions diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 3497abfd..97738ec5 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -1179,7 +1179,6 @@ internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); //~ rjf: Eval Info Extraction internal U64 e_base_offset_from_eval(E_Eval eval); -internal Rng1U64 e_range_from_eval(E_Eval eval); //////////////////////////////// //~ rjf: Debug Functions diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 17cf8baa..116560e9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5367,45 +5367,48 @@ rd_view_query_input(void) return string; } -internal RD_Cfg * -rd_view_cfg_from_string(String8 string) +internal String8 +rd_view_setting_from_name(String8 name) { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); - RD_Cfg *cfg = rd_cfg_child_from_string(view, string); - return cfg; + String8 result = rd_cfg_child_from_string(view, name)->first->string; + if(result.size == 0) + { + result = rd_default_setting_from_names(view->string, name); + } + return result; } internal E_Value -rd_view_cfg_value_from_string(String8 string) +rd_view_setting_value_from_name(String8 name) { - RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = root->first->string; + String8 expr = rd_view_setting_from_name(name); E_Eval eval = e_eval_from_string(expr); E_Value result = e_value_eval_from_eval(eval).value; return result; } internal B32 -rd_view_cfg_b32_from_string(String8 string) +rd_view_setting_b32_from_name(String8 name) { - RD_Cfg *root = rd_view_cfg_from_string(string); - B32 result = !!e_value_from_stringf("(bool)(%S)", root->first->string).u64; + String8 string = rd_view_setting_from_name(name); + B32 result = !!e_value_from_stringf("(bool)(%S)", string).u64; return result; } internal U64 -rd_view_cfg_u64_from_string(String8 string) +rd_view_setting_u64_from_name(String8 name) { - RD_Cfg *root = rd_view_cfg_from_string(string); - U64 result = e_value_from_stringf("(uint64)(%S)", root->first->string).u64; + String8 string = rd_view_setting_from_name(name); + U64 result = e_value_from_stringf("(uint64)(%S)", string).u64; return result; } internal F32 -rd_view_cfg_f32_from_string(String8 string) +rd_view_setting_f32_from_name(String8 name) { - RD_Cfg *root = rd_view_cfg_from_string(string); - F32 result = e_value_from_stringf("(float32)(%S)", root->first->string).f32; + String8 string = rd_view_setting_from_name(name); + F32 result = e_value_from_stringf("(float32)(%S)", string).f32; return result; } @@ -5466,57 +5469,6 @@ rd_arch_from_eval(E_Eval eval) return arch; } -internal R_Tex2DFormat -rd_tex2dformat_from_eval(E_Eval eval) -{ - R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; - B32 got_fmt = 0; - - // rjf: try explicitly passed formats - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("fmt"), 0)) - { - got_fmt = 1; - for EachEnumVal(R_Tex2DFormat, f) - { - if(str8_match(arg->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) - { - fmt = f; - break; - } - } - } - } - } - - // rjf: try implicit non-define arguments - if(type->kind == E_TypeKind_Lens) - { - for EachIndex(idx, type->count) - { - E_Expr *arg = type->args[idx]; - if(arg->kind == E_ExprKind_LeafIdentifier) - { - for EachEnumVal(R_Tex2DFormat, f) - { - if(str8_match(arg->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) - { - fmt = f; - break; - } - } - } - } - } - - return fmt; -} - //- rjf: pushing/attaching view resources internal void * @@ -8698,7 +8650,7 @@ rd_window_frame(void) { // rjf: gather info for this tab B32 tab_is_selected = (tab == panel->selected_tab); - B32 tab_is_auto = rd_view_cfg_b32_from_string(str8_lit("auto")); + B32 tab_is_auto = rd_view_setting_b32_from_name(str8_lit("auto")); // rjf: begin vertical region for this tab ui_set_next_child_layout_axis(Axis2_Y); @@ -12088,6 +12040,16 @@ rd_frame(void) } } + // rjf: run -> no active targets, no processes, but we only have one target? -> just launch it, then select it + if((kind == RD_CmdKind_Run || + kind == RD_CmdKind_StepInto || + kind == RD_CmdKind_StepOver) && processes.count == 0 && targets.count == 1 && !has_active_targets) + { + rd_cmd(kind == RD_CmdKind_Run ? RD_CmdKind_LaunchAndRun : RD_CmdKind_LaunchAndStepInto, .cfg = targets.first->v->id); + rd_cmd(RD_CmdKind_SelectTarget, .cfg = targets.first->v->id); + break; + } + // rjf: run -> no targets at all, no processes? -> do helper for add-target if((kind == RD_CmdKind_Run || kind == RD_CmdKind_StepInto || @@ -12100,13 +12062,10 @@ rd_frame(void) // rjf: run -> no active targets, no processes? -> do helper for launch-and-run if((kind == RD_CmdKind_Run || kind == RD_CmdKind_StepInto || - kind == RD_CmdKind_StepOver) && processes.count == 0) + kind == RD_CmdKind_StepOver) && processes.count == 0 && !has_active_targets) { - if(!has_active_targets) - { - rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[kind == RD_CmdKind_Run ? RD_CmdKind_LaunchAndRun : RD_CmdKind_LaunchAndStepInto].string); - break; - } + rd_cmd(RD_CmdKind_RunCommand, .cmd_name = rd_cmd_kind_info_table[kind == RD_CmdKind_Run ? RD_CmdKind_LaunchAndRun : RD_CmdKind_LaunchAndStepInto].string); + break; } // rjf: if this is a low-level operation, e.g. launch-and-run or launch-and-step-into, @@ -14010,7 +13969,7 @@ rd_frame(void) RD_RegsScope(.tab = tab->id, .view = tab->id) { if(str8_match(tab->string, str8_lit("text"), 0) && - rd_view_cfg_b32_from_string(str8_lit("auto"))) + rd_view_setting_b32_from_name(str8_lit("auto"))) { panel_w_auto = panel; view_w_auto = tab; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index e9c3ccc8..307b1690 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -915,16 +915,15 @@ internal UI_ScrollPt2 rd_view_scroll_pos(void); internal EV_View *rd_view_eval_view(void); internal String8 rd_view_query_cmd(void); internal String8 rd_view_query_input(void); -internal RD_Cfg *rd_view_cfg_from_string(String8 string); -internal E_Value rd_view_cfg_value_from_string(String8 string); -internal B32 rd_view_cfg_b32_from_string(String8 string); -internal U64 rd_view_cfg_u64_from_string(String8 string); -internal F32 rd_view_cfg_f32_from_string(String8 string); +internal String8 rd_view_setting_from_name(String8 string); +internal E_Value rd_view_setting_value_from_name(String8 string); +internal B32 rd_view_setting_b32_from_name(String8 string); +internal U64 rd_view_setting_u64_from_name(String8 string); +internal F32 rd_view_setting_f32_from_name(String8 string); //- rjf: evaluation & tag (a view's 'call') parameter extraction internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval); internal Arch rd_arch_from_eval(E_Eval eval); -internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index cc6ee83a..fb34db1c 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1898,23 +1898,23 @@ RD_VIEW_UI_FUNCTION_DEF(text) rd_regs()->file_path = rd_file_path_from_eval(rd_frame_arena(), eval); rd_regs()->vaddr = 0; rd_regs()->prefer_disasm = 0; - rd_regs()->cursor.line = rd_view_cfg_value_from_string(str8_lit("cursor_line")).s64; - rd_regs()->cursor.column = rd_view_cfg_value_from_string(str8_lit("cursor_column")).s64; - rd_regs()->mark.line = rd_view_cfg_value_from_string(str8_lit("mark_line")).s64; - rd_regs()->mark.column = rd_view_cfg_value_from_string(str8_lit("mark_column")).s64; + rd_regs()->cursor.line = rd_view_setting_value_from_name(str8_lit("cursor_line")).s64; + rd_regs()->cursor.column = rd_view_setting_value_from_name(str8_lit("cursor_column")).s64; + rd_regs()->mark.line = rd_view_setting_value_from_name(str8_lit("mark_line")).s64; + rd_regs()->mark.column = rd_view_setting_value_from_name(str8_lit("mark_column")).s64; if(rd_regs()->cursor.line == 0) { rd_regs()->cursor.line = 1; } if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } U64 base_offset = e_base_offset_from_eval(eval); - U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); } Rng1U64 range = r1u64(base_offset, base_offset+size); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - String8 lang = rd_view_cfg_from_string(str8_lit("lang"))->first->string; + String8 lang = rd_view_setting_from_name(str8_lit("lang")); if(lang.size == 0) { rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); @@ -2181,7 +2181,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) space = auto_space; } U64 base_offset = e_base_offset_from_eval(eval); - U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { size = KB(16); @@ -2360,14 +2360,13 @@ RD_VIEW_UI_FUNCTION_DEF(memory) //- rjf: unpack parameterization info // F32 main_font_size = ui_bottom_font_size(); - Rng1U64 view_range = e_range_from_eval(eval); U64 base_offset = e_base_offset_from_eval(eval); - U64 size = rd_view_cfg_value_from_string(str8_lit("size")).u64; + U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); } - view_range = r1u64(base_offset, base_offset+size); + Rng1U64 view_range = r1u64(base_offset, base_offset+size); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -2377,13 +2376,13 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { view_range = r1u64(0, 0x7FFFFFFFFFFFull); } - U64 cursor_base_vaddr = rd_view_cfg_u64_from_string(str8_lit("cursor")); - U64 mark_base_vaddr = rd_view_cfg_u64_from_string(str8_lit("mark")); - U64 cursor_size = rd_view_cfg_u64_from_string(str8_lit("cursor_size")); + U64 cursor_base_vaddr = rd_view_setting_u64_from_name(str8_lit("cursor")); + U64 mark_base_vaddr = rd_view_setting_u64_from_name(str8_lit("mark")); + U64 cursor_size = rd_view_setting_u64_from_name(str8_lit("cursor_size")); cursor_size = ClampBot(1, cursor_size); U64 initial_cursor_base_vaddr = cursor_base_vaddr; U64 initial_mark_base_vaddr = mark_base_vaddr; - U64 num_columns = rd_view_cfg_u64_from_string(str8_lit("num_columns")); + U64 num_columns = rd_view_setting_u64_from_name(str8_lit("num_columns")); if(num_columns == 0) { num_columns = 16; @@ -3378,8 +3377,17 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - Vec2S32 dim = v2s32((S32)rd_view_cfg_u64_from_string(str8_lit("w")), (S32)rd_view_cfg_u64_from_string(str8_lit("h"))); - R_Tex2DFormat fmt = rd_tex2dformat_from_eval(eval); + Vec2S32 dim = v2s32((S32)rd_view_setting_u64_from_name(str8_lit("w")), (S32)rd_view_setting_u64_from_name(str8_lit("h"))); + String8 fmt_string = rd_view_setting_from_name(str8_lit("fmt")); + R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; + for EachNonZeroEnumVal(R_Tex2DFormat, f) + { + if(str8_match(fmt_string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } + } U64 base_offset = e_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -3387,11 +3395,11 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: unpack params // - F32 zoom = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; + F32 zoom = rd_view_setting_value_from_name(str8_lit("zoom")).f32; Vec2F32 view_center_pos = { - rd_view_cfg_value_from_string(str8_lit("x")).f32, - rd_view_cfg_value_from_string(str8_lit("y")).f32, + rd_view_setting_value_from_name(str8_lit("x")).f32, + rd_view_setting_value_from_name(str8_lit("y")).f32, }; if(zoom == 0) { @@ -3517,7 +3525,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) case R_Tex2DFormat_R8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, 0, 0, 1);}break; case R_Tex2DFormat_RG8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, 0, 1);}break; case R_Tex2DFormat_RGBA8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, ((U8 *)(data.str+off_bytes))[2]/255.f, ((U8 *)(data.str+off_bytes))[3]/255.f);}break; - case R_Tex2DFormat_BGRA8: {color = v4f32(((U8 *)(data.str+off_bytes))[3]/255.f, ((U8 *)(data.str+off_bytes))[2]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, ((U8 *)(data.str+off_bytes))[0]/255.f);}break; + case R_Tex2DFormat_BGRA8: {color = v4f32(((U8 *)(data.str+off_bytes))[2]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, ((U8 *)(data.str+off_bytes))[0]/255.f, ((U8 *)(data.str+off_bytes))[3]/255.f);}break; case R_Tex2DFormat_R16: {color = v4f32(((U16 *)(data.str+off_bytes))[0]/(F32)max_U16, 0, 0, 1);}break; case R_Tex2DFormat_RGBA16: {color = v4f32(((U16 *)(data.str+off_bytes))[0]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[1]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[2]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[3]/(F32)max_U16);}break; case R_Tex2DFormat_R32: {color = v4f32(((F32 *)(data.str+off_bytes))[0], 0, 0, 1);}break; @@ -3883,12 +3891,12 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_view_cfg_u64_from_string(str8_lit("count")); - U64 vtx_base_off = rd_view_cfg_u64_from_string(str8_lit("vtx")); - U64 vtx_size = rd_view_cfg_u64_from_string(str8_lit("vtx_size")); - F32 yaw_target = rd_view_cfg_f32_from_string(str8_lit("yaw")); - F32 pitch_target = rd_view_cfg_f32_from_string(str8_lit("pitch")); - F32 zoom_target = rd_view_cfg_f32_from_string(str8_lit("zoom")); + U64 count = rd_view_setting_u64_from_name(str8_lit("count")); + U64 vtx_base_off = rd_view_setting_u64_from_name(str8_lit("vtx")); + U64 vtx_size = rd_view_setting_u64_from_name(str8_lit("vtx_size")); + F32 yaw_target = rd_view_setting_f32_from_name(str8_lit("yaw")); + F32 pitch_target = rd_view_setting_f32_from_name(str8_lit("pitch")); + F32 zoom_target = rd_view_setting_f32_from_name(str8_lit("zoom")); ////////////////////////////// //- rjf: evaluate & unpack expression From a96546c5f53c1490d41c02a9823609ea5a18cb92 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 09:50:41 -0700 Subject: [PATCH 539/755] view rules / auto view rules -> views / type views --- src/eval/eval_core.h | 2 +- .../eval_visualization.mdesk | 107 ------------------ .../eval_visualization_core.c | 5 - .../eval_visualization_core.h | 5 - .../generated/eval_visualization.meta.c | 5 - .../generated/eval_visualization.meta.h | 9 -- src/lib_raddbg_markup/raddbg_markup.h | 4 +- src/mule/mule_main.cpp | 26 ++--- src/raddbg/generated/raddbg.meta.c | 19 ++-- src/raddbg/generated/raddbg.meta.h | 8 +- src/raddbg/raddbg.mdesk | 17 ++- src/raddbg/raddbg_core.c | 60 +++++++--- src/raddbg/raddbg_main.c | 7 +- src/raddbg/raddbg_views.h | 43 ------- src/raddbg/raddbg_widgets.c | 8 +- 15 files changed, 89 insertions(+), 236 deletions(-) delete mode 100644 src/eval_visualization/eval_visualization.mdesk delete mode 100644 src/eval_visualization/generated/eval_visualization.meta.c delete mode 100644 src/eval_visualization/generated/eval_visualization.meta.h diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 97738ec5..d9249a87 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -645,7 +645,7 @@ struct E_String2TypeKeyMap }; //////////////////////////////// -//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) +//~ rjf: Type Pattern -> Hook Key Data Structure (Type Views) typedef struct E_AutoHookNode E_AutoHookNode; struct E_AutoHookNode diff --git a/src/eval_visualization/eval_visualization.mdesk b/src/eval_visualization/eval_visualization.mdesk deleted file mode 100644 index 493c64a0..00000000 --- a/src/eval_visualization/eval_visualization.mdesk +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Built-In View Rules -// -// @view_rule_info -// -// NOTE(rjf): View rules are subtle in that they may impact any subset of the -// eval visualization pipeline. The "array" view rule, for example, functions -// by tweaking the type of an eval from `X *` to `X (*)[N]` (where N is -// computed from whatever expression is specified by the view rule). The "list" -// view rule, on the other hand, does not require any changes to the actual -// eval nor its type - instead, it follows an alternative path in constructing -// "viz blocks", and then constructing "viz rows" from those blocks. Compare -// these to the simpler 'dec', 'bin', or 'oct' rules, which simply tweak the -// radix used when stringizing numbers, which is something that only occurs in -// single-line eval stringization building. -// -// As such, each view rule specification has a mask, which determines which -// stages it may be used for. For a given view rule specification, if the bit -// corresponding to a particular eval stage is set, then that view rule spec- -// -ification also includes a hook which can be called from that stage. -// -// Below is a list of the stages in the eval visualization pipeline, as well as -// abbreviations which are used in the tables. -// -// expr resolution, "xp" -> provides a chance for a view rule to make -// modifications to expression trees that it is -// applied to -// -// viz block prod, "vb" -> given a resolved eval, produce a list of non- -// windowed "viz blocks", which correspond to one or -// many contiguous rows in a watch-window-style UI. -// one level of expanded struct members, with no sub- -// expansions, would be one viz block. if one of those -// members - in the middle - were expanded too, then -// it would require three viz blocks - one for the -// members before the sub-expansion, one for the -// sub expansion members, and one for the members -// after, and so on. this is done recursively. -// -// viz row prod, "vr" -> given a list of viz blocks, a windowed list of viz -// rows may be produced. each of these rows has info -// for building actual UI in e.g. a watch window - -// whether or not the row can be expanded, whether or -// not the row's value can be edited, what the edit- -// able string is for a row, what the display string -// is for a row, what the expression string is for a -// row, what the type is for a row, and so on. -// -// line stringize, "ls" -> this is the stage used to produce display strings -// in the "viz row prod" stage, as well as basically -// any time UI needs to display the result of an eval -// in a single line. this also occurs recursively, -// descending into members & elements as needed, -// constrained by # of available pixels and font size -// and so on. -// -// row ui build, "ru" -> finally, after the previous stages are completed, -// ui can finally be built according to all of the -// per-row information produced. this is the stage -// where view rules can insert their own arbitrary ui -// on a per-row basis. -// -// view ui build, "vu" -> view rules which want to supply more sophisticated -// visualizers have the ability to provide full -// arbitrary UI hooks, which can either be produced -// in a minified form via watch views, or via a -// standalone tab. -// -// A few other bits are included for various ways in which a view rule may be -// applied throughout the eval visualization pipeline. A list follows: -// -// inherited, "ih" -> is this view rule included, or not included, in -// child expansions? -// -// expandable, "ex" -> does this view rule force the ability to expand -// an expression, even if traditional analysis of type -// info would not allow expansion? -// -// Not all of these stages are specified at this layer, however, since the -// "df_core" layer is for the non-graphical core debugger features. So the -// information pertaining to the eval visualization pipeline stages which -// do require graphical subsystems (e.g. UI, fonts, rendering) are specified -// in the "df_gfx" layer. -// -// For any view rules in this layer which also have graphical features, they -// are specified in both tables under the same name. - -@table(coverage_check name name_lower string ih ex xr xe display_name docs schema description) -EV_ViewRuleTable: -{ - {x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } - {x List list "list" - - - x "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." } - {x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." } - {x ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed." } - {x Cast cast "cast" - - x - "Cast" x "x:{type}" "Specifies that the expression to which the view rule is applied should be casted to the provided type." } - {x Wrap wrap "wrap" - - x - "Wrap" x "x:{expr}" "Specifies that the expression should be wrapped with the view-rule-specified expression, which will refer to the original expression as `$expr`." } - {x Only only "only" x - x - "Only" x "" "Specifies that only the provided member names should be shown in user-defined-type expansions." } - {x Omit omit "omit" x - x - "Omit" x "" "Specifies that the provided member names should not be shown in user-defined-type expansions." } - {x Bin bin "bin" x - - - "Display In Binary" x "" "Specifies that all numeric values should be shown in base 2 (binary)." } - {x Oct oct "oct" x - - - "Display In Octal" x "" "Specifies that all numeric values should be shown in base 8 (octal)." } - {x Dec dec "dec" x - - - "Display In Decimal" x "" "Specifies that all numeric values should be shown in base 10 (decimal)." } - {x Hex hex "hex" x - - - "Display In Hexadecimal" x "" "Specifies that all numeric values should be shown in base 16 (hexadecimal)." } - {x NoAddress no_addr "no_addr" x - - - "Omit Addresses" x "" "Specifies that addresses should be omitted from visualizations, if possible." } -} diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index a8fbed76..cdcf9b1d 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1,11 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/eval_visualization.meta.c" - //////////////////////////////// //~ rjf: Nil/Identity View Rule Hooks diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 22341675..dcca9cb6 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -220,11 +220,6 @@ struct EV_WindowedRowList U64 count_before_semantic; }; -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/eval_visualization.meta.h" - //////////////////////////////// //~ rjf: String Generation Types diff --git a/src/eval_visualization/generated/eval_visualization.meta.c b/src/eval_visualization/generated/eval_visualization.meta.c deleted file mode 100644 index 3d32a4c2..00000000 --- a/src/eval_visualization/generated/eval_visualization.meta.c +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - diff --git a/src/eval_visualization/generated/eval_visualization.meta.h b/src/eval_visualization/generated/eval_visualization.meta.h deleted file mode 100644 index efcc2c2a..00000000 --- a/src/eval_visualization/generated/eval_visualization.meta.h +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -#ifndef EVAL_VISUALIZATION_META_H -#define EVAL_VISUALIZATION_META_H - -#endif // EVAL_VISUALIZATION_META_H diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 09de9b30..f6c8a160 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -26,7 +26,7 @@ # define raddbg_pin(expr, ...) # define raddbg_log(fmt, ...) ((void)0) # define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_auto_view_rule(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} # define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) # define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) #else @@ -40,7 +40,7 @@ # define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ # define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) # define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") -# define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("auto_view_rule: {type: \"" #type "\", view_rule: \"" #__VA_ARGS__ "\"}") +# define raddbg_type_view(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) #endif diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index fa95ba20..f92d5f89 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -107,8 +107,8 @@ void optimized_struct_parameters_eval_tests(void); #include #include -raddbg_auto_view_rule(std::vector, slice(_Mypair._Myval2)); -raddbg_auto_view_rule(std::unique_ptr, _Mypair._Myval2); +raddbg_type_view(std::vector, slice(_Mypair._Myval2)); +raddbg_type_view(std::unique_ptr, _Mypair._Myval2); struct Basics { @@ -156,7 +156,7 @@ struct Dynamic_Array Pair *pairs; int count; }; -raddbg_auto_view_rule(Dynamic_Array, slice($)); +raddbg_type_view(Dynamic_Array, slice($)); struct Struct_With_Embedded_Arrays { @@ -189,14 +189,14 @@ union Vector_R2 }; float v[2]; }; -raddbg_auto_view_rule(Vector_R2, only($, x, y)); +raddbg_type_view(Vector_R2, only($, x, y)); typedef union Matrix4x4F32 Matrix4x4F32; union Matrix4x4F32 { float elements[4][4]; }; -raddbg_auto_view_rule(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); +raddbg_type_view(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); enum Kind { @@ -250,12 +250,12 @@ struct Discriminated_Union } fourth; }; }; -raddbg_auto_view_rule(Discriminated_Union, - kind == Kind.First ? first : - kind == Kind.Second ? second : - kind == Kind.Third ? third : - kind == Kind.Fourth ? fourth : - $); +raddbg_type_view(Discriminated_Union, + kind == Kind.First ? first : + kind == Kind.Second ? second : + kind == Kind.Third ? third : + kind == Kind.Fourth ? fourth : + $); struct Linked_List{ Linked_List *next; @@ -1716,7 +1716,7 @@ struct Bitmap int width; int height; }; -raddbg_auto_view_rule(Bitmap, lens:bitmap(base, width, height)); +raddbg_type_view(Bitmap, lens:bitmap(base, width, height)); static unsigned int mule_bswap_u32(unsigned int x) @@ -1837,7 +1837,7 @@ fancy_viz_eval_tests(void) } int x2 = 0; - //- rjf: auto-view-rule'd bitmaps + //- rjf: type-viewed bitmaps Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; raddbg_pin(foo); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index ca54b5ae..da873124 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -50,7 +50,7 @@ str8_lit_comp("query:processes"), str8_lit_comp("query:machines"), str8_lit_comp("query:modules"), str8_lit_comp("query:file_path_maps"), -str8_lit_comp("query:auto_view_rules"), +str8_lit_comp("query:type_views"), str8_lit_comp("query:output"), str8_lit_comp(""), str8_lit_comp(""), @@ -60,13 +60,13 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[333] = +RD_VocabInfo rd_vocab_info_table[332] = { -{str8_lit_comp("auto_view_rule"), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rule"), str8_lit_comp("Auto View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, {str8_lit_comp("watch_pin"), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pin"), str8_lit_comp("Watch Pins"), RD_IconKind_Pin}, {str8_lit_comp("watch"), str8_lit_comp("watches"), str8_lit_comp("Watch"), str8_lit_comp("Watches"), RD_IconKind_Binoculars}, -{str8_lit_comp("view_rule"), str8_lit_comp("view_rules"), str8_lit_comp("View Rule"), str8_lit_comp("View Rules"), RD_IconKind_Binoculars}, +{str8_lit_comp("view"), str8_lit_comp("views"), str8_lit_comp("View"), str8_lit_comp("Views"), RD_IconKind_Binoculars}, {str8_lit_comp("breakpoint"), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoint"), str8_lit_comp("Breakpoints"), RD_IconKind_CircleFilled}, {str8_lit_comp("condition"), str8_lit_comp("conditions"), str8_lit_comp("Condition"), str8_lit_comp("Conditions"), RD_IconKind_Null}, {str8_lit_comp("location"), str8_lit_comp("locations"), str8_lit_comp("Location"), str8_lit_comp("Locations"), RD_IconKind_Null}, @@ -89,7 +89,6 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("stdin_path"), str8_lit_comp("stdin_paths"), str8_lit_comp("Standard Input Path"), str8_lit_comp("Standard Input Paths"), RD_IconKind_Null}, {str8_lit_comp("window"), str8_lit_comp("windows"), str8_lit_comp("Window"), str8_lit_comp("Windows"), RD_IconKind_Window}, {str8_lit_comp("panel"), str8_lit_comp("panels"), str8_lit_comp("Panel"), str8_lit_comp("Panels"), RD_IconKind_Null}, -{str8_lit_comp("view"), str8_lit_comp("views"), str8_lit_comp("View"), str8_lit_comp("Views"), RD_IconKind_Null}, {str8_lit_comp("tab"), str8_lit_comp("tabs"), str8_lit_comp("Tab"), str8_lit_comp("Tabs"), RD_IconKind_Null}, {str8_lit_comp("recent_project"), str8_lit_comp("recent_projects"), str8_lit_comp("Recent Project"), str8_lit_comp("Recent Projects"), RD_IconKind_Briefcase}, {str8_lit_comp("recent_file"), str8_lit_comp("recent_files"), str8_lit_comp("Recent File"), str8_lit_comp("Recent Files"), RD_IconKind_FileOutline}, @@ -347,7 +346,7 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, -{str8_lit_comp("add_auto_view_rule"), str8_lit_comp(""), str8_lit_comp("Add Auto View Rule"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("add_type_view"), str8_lit_comp(""), str8_lit_comp("Add Type View"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("add_file_path_map"), str8_lit_comp(""), str8_lit_comp("Add File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("open_theme"), str8_lit_comp(""), str8_lit_comp("Open Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, @@ -387,7 +386,7 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("machines"), str8_lit_comp(""), str8_lit_comp("Machines"), str8_lit_comp(""), RD_IconKind_Machine}, {str8_lit_comp("modules"), str8_lit_comp(""), str8_lit_comp("Modules"), str8_lit_comp(""), RD_IconKind_Module}, {str8_lit_comp("file_path_maps"), str8_lit_comp(""), str8_lit_comp("File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("auto_view_rules"), str8_lit_comp(""), str8_lit_comp("Auto View Rules"), str8_lit_comp(""), RD_IconKind_Binoculars}, +{str8_lit_comp("type_views"), str8_lit_comp(""), str8_lit_comp("Type Views"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("output"), str8_lit_comp(""), str8_lit_comp("Output"), str8_lit_comp(""), RD_IconKind_List}, {str8_lit_comp("text"), str8_lit_comp(""), str8_lit_comp("Text"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("disasm"), str8_lit_comp(""), str8_lit_comp("Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, @@ -415,7 +414,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, +{str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, @@ -650,7 +649,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[225] = { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("add_auto_view_rule"), str8_lit_comp("Adds a new auto view rule."), str8_lit_comp(""), str8_lit_comp("$auto_view_rules,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_type_view"), str8_lit_comp("Adds a new type view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_file_path_map"), str8_lit_comp("Adds a new file path map."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -690,7 +689,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[225] = { str8_lit_comp("machines"), str8_lit_comp("Opens a Machines tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("modules"), str8_lit_comp("Opens a Modules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("file_path_maps"), str8_lit_comp("Opens a File Path Map tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, -{ str8_lit_comp("auto_view_rules"), str8_lit_comp("Opens a Auto View Rules tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, +{ str8_lit_comp("type_views"), str8_lit_comp("Opens a Type Views tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("output"), str8_lit_comp("Opens a Output tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("text"), str8_lit_comp("Opens a Text tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, { str8_lit_comp("disasm"), str8_lit_comp("Opens a Disassembly tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e8e32998..68ad0245 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -233,7 +233,7 @@ RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, -RD_CmdKind_AddAutoViewRule, +RD_CmdKind_AddTypeView, RD_CmdKind_AddFilePathMap, RD_CmdKind_OpenTheme, RD_CmdKind_AddThemeColor, @@ -273,7 +273,7 @@ RD_CmdKind_OpenProcesses, RD_CmdKind_OpenMachines, RD_CmdKind_OpenModules, RD_CmdKind_OpenFilePathMaps, -RD_CmdKind_OpenAutoViewRules, +RD_CmdKind_OpenTypeViews, RD_CmdKind_OpenOutput, RD_CmdKind_OpenText, RD_CmdKind_OpenDisasm, @@ -631,7 +631,7 @@ X(processes) \ X(machines) \ X(modules) \ X(file_path_maps) \ -X(auto_view_rules) \ +X(type_views) \ Y(output, text, "query:output")\ Y(text, text, "")\ Y(disasm, disasm, "")\ @@ -688,7 +688,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[333]; +extern RD_VocabInfo rd_vocab_info_table[332]; extern RD_NameSchemaInfo rd_name_schema_info_table[23]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index cfac11bd..a68df07f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -33,7 +33,7 @@ RD_WatchTabFastPathTable: {Machines "Machines" machines 1 Machine } {Modules "Modules" modules 1 Module } {FilePathMaps "File Path Map" file_path_maps 1 FileOutline } - {AutoViewRules "Auto View Rules" auto_view_rules 1 Binoculars } + {TypeViews "Type Views" type_views 1 Binoculars } } @table(name display_name name_lower view query icon) @@ -83,11 +83,11 @@ RD_VocabTable: // NOTE(rjf): the _ character is used as a fastpath for default rules. when // pluralizing, you just append an `s`, and so on. { - {auto_view_rule _ "Auto View Rule" _ Binoculars } + {type_view _ "Type View" _ Binoculars } {file_path_map _ "File Path Map" _ FileOutline } {watch_pin _ "Watch Pin" _ Pin } {watch watches "Watch" "Watches" Binoculars } - {view_rule _ "View Rule" _ Binoculars } + {view _ "View" _ Binoculars } {breakpoint _ "Breakpoint" _ CircleFilled } {condition _ "Condition" _ Null } {location _ "Location" _ Null } @@ -110,7 +110,6 @@ RD_VocabTable: {stdin_path _ "Standard Input Path" _ Null } {window _ "Window" _ Window } {panel _ "Panel" _ Null } - {view _ "View" _ Null } {tab _ "Tab" _ Null } {recent_project _ "Recent Project" _ Briefcase } {recent_file _ "Recent File" _ FileOutline } @@ -611,10 +610,10 @@ RD_VocabTable: ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}```, } - //- rjf: auto view rules + //- rjf: type views { - auto_view_rule, - ```@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, + type_view, + ```@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}```, } //- rjf: recent projects @@ -961,8 +960,8 @@ RD_CmdTable: // | | | | {AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } {ToggleWatchPin 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "toggle_watch_pin" "Toggle Watch Pin" "Places or removes a watch pin at a given location (file path and line number or address)." "" "" } - //- rjf: auto view rule - {AddAutoViewRule 0 0 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_auto_view_rule" "Add Auto View Rule" "Adds a new auto view rule." "" "$auto_view_rules," } + //- rjf: type views + {AddTypeView 0 0 0 0 "" String null Nil Null 0 0 0 0 0 0 0 Binoculars "add_type_view" "Add Type View" "Adds a new type view." "" "" } //- rjf: file path maps {AddFilePathMap 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "add_file_path_map" "Add File Path Map" "Adds a new file path map." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 116560e9..9fd5b2b0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2388,12 +2388,14 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) E_TypeKey type_key = eval.irtree.type_key; E_Type *type = e_type_from_key__cached(type_key); String8 schema_name = str8_lit("watch"); + B32 type_is_visualizer = 0; if(type->kind == E_TypeKind_Lens) { RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(type->name); if(view_ui_rule != &rd_nil_view_ui_rule) { schema_name = type->name; + type_is_visualizer = 1; } } RD_Cfg *view = rd_cfg_child_from_string_or_alloc(parent, schema_name); @@ -2401,7 +2403,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) { // rjf: get expression evaluation E_Eval expr_eval = eval; - if(eval.expr->kind == E_ExprKind_Call) + if(eval.expr->kind == E_ExprKind_Call && type_is_visualizer) { expr_eval = e_eval_from_expr(eval.expr->first->next); } @@ -8456,6 +8458,17 @@ rd_window_frame(void) } } + //- rjf: visualizers -> accept expression drops + UI_Box *view_drop_site = &ui_nil_box; + { + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(selected_tab->string); + if(view_ui_rule != &rd_nil_view_ui_rule && rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) + { + UI_FixedSize(dim_2f32(content_rect)) + view_drop_site = ui_build_box_from_stringf(UI_BoxFlag_DropSite|UI_BoxFlag_Floating, "drop_site_%I64x", selected_tab->id); + } + } + //- rjf: build view container UI_Box *view_container_box = &ui_nil_box; UI_FixedWidth(dim_2f32(content_rect).x) @@ -8494,6 +8507,23 @@ rd_window_frame(void) rd_view_ui(content_rect); } + //- rjf: accept expression drops + if(view_drop_site != &ui_nil_box) + { + UI_Signal sig = ui_signal_from_box(view_drop_site); + if(ui_key_match(view_drop_site->key, ui_drop_hot_key())) + { + UI_Parent(view_drop_site) UI_WidthFill UI_HeightFill UI_TagF("drop_site") UI_Transparency(0.5f) + { + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); + } + if(rd_drag_drop()) + { + rd_store_view_expr_string(rd_state->drag_drop_regs->expr); + } + } + } + //- rjf: pop interaction registers; commit if this is the selected view RD_Regs *view_regs = rd_pop_regs(); if(panel_is_focused) @@ -11374,7 +11404,7 @@ rd_frame(void) str8_lit("watch_pin"), str8_lit("target"), str8_lit("file_path_map"), - str8_lit("auto_view_rule"), + str8_lit("type_view"), str8_lit("recent_project"), str8_lit("recent_file"), }; @@ -11885,9 +11915,9 @@ rd_frame(void) ev_select_expand_rule_table(expand_rule_table); //////////////////////////// - //- rjf: gather auto-view-rules from loaded modules + //- rjf: gather config from loaded modules // - RD_CfgList immediate_auto_view_rules = {0}; + RD_CfgList immediate_type_views = {0}; CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); for EachIndex(idx, modules.count) { @@ -11906,20 +11936,20 @@ rd_frame(void) RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfg_%I64x", module_name, cfg_idx); rd_cfg_release_all_children(immediate_root); rd_cfg_insert_child(immediate_root, immediate_root->last, n->v); - rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v); + rd_cfg_list_push(scratch.arena, &immediate_type_views, n->v); } } } //////////////////////////// - //- rjf: add auto-hook rules for auto-view-rules + //- rjf: add auto-hook rules for type views // { - RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule")); + RD_CfgList type_views = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("type_view")); RD_CfgList rules_lists[] = { - auto_view_rules, - immediate_auto_view_rules, + type_views, + immediate_type_views, }; for EachElement(list_idx, rules_lists) { @@ -11927,9 +11957,9 @@ rd_frame(void) for(RD_CfgNode *n = list.first; n != 0; n = n->next) { RD_Cfg *rule = n->v; - String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; - String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string; - e_auto_hook_map_insert_new(scratch.arena, auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string); + String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string; + String8 expr_string = rd_cfg_child_from_string(rule, str8_lit("expr"))->first->string; + e_auto_hook_map_insert_new(scratch.arena, auto_hook_map, .type_pattern = type_string, .tag_expr_string = expr_string); } } } @@ -14619,11 +14649,11 @@ rd_frame(void) } }break; - //- rjf: auto view rules - case RD_CmdKind_AddAutoViewRule: + //- rjf: type views + case RD_CmdKind_AddTypeView: { RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); - rd_cfg_new(project, str8_lit("auto_view_rule")); + rd_cfg_new(project, str8_lit("type_view")); }break; //- rjf: file path maps diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index b13c6406..cfd0f1d0 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -176,10 +176,9 @@ // - `raddbg_entry_point(name)`, e.g. `raddbg_entry_point(entry_point)`: // declares the entry point for an executable, which the debugger will use // when stepping into a program, rather than the defaults (e.g. `main`). -// - `raddbg_auto_view_rule(, )`, e.g. -// `raddbg_auto_view_rule(DynamicArray, slice)`: declares an -// auto-view-rule from source code, rather than from debugger -// configuration. +// - `raddbg_type_view(, )`, e.g. +// `raddbg_type_view(DynamicArray, slice($))`: declares a type view from +// source code, rather than from debugger configuration. // - The debugger now incorporates the loaded project in all window titles. // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index c3ac1b20..7851043d 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -119,49 +119,6 @@ struct RD_WatchRowCellInfo RD_ViewUIRule *view_ui_rule; }; -typedef enum RD_WatchViewColumnKind -{ - RD_WatchViewColumnKind_Expr, - RD_WatchViewColumnKind_Value, - RD_WatchViewColumnKind_Type, - RD_WatchViewColumnKind_ViewRule, - RD_WatchViewColumnKind_Member, - RD_WatchViewColumnKind_CallStackFrame, - RD_WatchViewColumnKind_CallStackFrameSelection, - RD_WatchViewColumnKind_Module, - RD_WatchViewColumnKind_COUNT -} -RD_WatchViewColumnKind; - -typedef struct RD_WatchViewColumnParams RD_WatchViewColumnParams; -struct RD_WatchViewColumnParams -{ - String8 string; - String8 display_string; - String8 view_rule; - B32 is_non_code; - B32 dequote_string; - B32 rangify_braces; -}; - -typedef struct RD_WatchViewColumn RD_WatchViewColumn; -struct RD_WatchViewColumn -{ - RD_WatchViewColumn *next; - RD_WatchViewColumn *prev; - RD_WatchViewColumnKind kind; - F32 pct; - U8 string_buffer[1024]; - U64 string_size; - U8 display_string_buffer[1024]; - U64 display_string_size; - U8 view_rule_buffer[1024]; - U64 view_rule_size; - B32 is_non_code; - B32 dequote_string; - B32 rangify_braces; -}; - typedef struct RD_WatchPt RD_WatchPt; struct RD_WatchPt { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 5ea5cddb..1248dc29 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -333,11 +333,11 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } } - //- rjf: special case: auto view rule - if(str8_match(cfg->string, str8_lit("auto_view_rule"), 0)) + //- rjf: special case: type views + if(str8_match(cfg->string, str8_lit("type_view"), 0)) { String8 src_string = rd_cfg_child_from_string(cfg, str8_lit("type"))->first->string; - String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("view_rule"))->first->string; + String8 dst_string = rd_cfg_child_from_string(cfg, str8_lit("expr"))->first->string; Vec4F32 src_color = rgba; Vec4F32 dst_color = rgba; DR_FStrList src_fstrs = {0}; @@ -354,7 +354,7 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) } if(dst_string.size == 0) { - dst_string = str8_lit("(view rule)"); + dst_string = str8_lit("(expression)"); dst_color = rgba_secondary; dr_fstrs_push_new(arena, &dst_fstrs, ¶ms, dst_string, .color = dst_color); } From 58b1aa41f600bbe2f1199bc2e01ec8954064a514 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 10:29:22 -0700 Subject: [PATCH 540/755] drag/drop work & cleanup; memory view work; pull initial project path (if not specified on command line) from user recent projects before forming a default path --- src/raddbg/generated/raddbg.meta.c | 13 ++-- src/raddbg/generated/raddbg.meta.h | 5 +- src/raddbg/raddbg.mdesk | 15 ++++- src/raddbg/raddbg_core.c | 44 +++++++++--- src/raddbg/raddbg_views.c | 5 ++ src/raddbg/raddbg_widgets.c | 103 +++++++++++++++-------------- 6 files changed, 118 insertions(+), 67 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index da873124..efa1de44 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[332] = +RD_VocabInfo rd_vocab_info_table[333] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -252,6 +252,7 @@ RD_VocabInfo rd_vocab_info_table[332] = {str8_lit_comp("open_tab"), str8_lit_comp(""), str8_lit_comp("Open New Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("build_tab"), str8_lit_comp(""), str8_lit_comp("Build Tab"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("duplicate_tab"), str8_lit_comp(""), str8_lit_comp("Duplicate Tab"), str8_lit_comp(""), RD_IconKind_Duplicate}, +{str8_lit_comp("copy_tab_full_path"), str8_lit_comp(""), str8_lit_comp("Copy Full Path"), str8_lit_comp(""), RD_IconKind_Clipboard}, {str8_lit_comp("close_tab"), str8_lit_comp(""), str8_lit_comp("Close Tab"), str8_lit_comp(""), RD_IconKind_X}, {str8_lit_comp("move_view"), str8_lit_comp(""), str8_lit_comp("Move View"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("tab_bar_top"), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), str8_lit_comp(""), RD_IconKind_UpArrow}, @@ -262,7 +263,7 @@ RD_VocabInfo rd_vocab_info_table[332] = {str8_lit_comp("switch"), str8_lit_comp(""), str8_lit_comp("Switch"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("switch_to_partner_file"), str8_lit_comp(""), str8_lit_comp("Switch To Partner File"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("record_file_in_project"), str8_lit_comp(""), str8_lit_comp("Record File In Project"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("show_file_in_explorer"), str8_lit_comp(""), str8_lit_comp("Show File In Explorer"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("show_file_in_explorer"), str8_lit_comp(""), str8_lit_comp("Show File In Explorer"), str8_lit_comp(""), RD_IconKind_FolderClosedFilled}, {str8_lit_comp("go_to_disassembly"), str8_lit_comp(""), str8_lit_comp("Go To Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, {str8_lit_comp("go_to_source"), str8_lit_comp(""), str8_lit_comp("Go To Source"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("set_file_replacement_path"), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), str8_lit_comp(""), RD_IconKind_Null}, @@ -396,13 +397,13 @@ RD_VocabInfo rd_vocab_info_table[332] = {str8_lit_comp("geo3d"), str8_lit_comp(""), str8_lit_comp("Geometry (3D)"), str8_lit_comp(""), RD_IconKind_Cube}, }; -RD_NameSchemaInfo rd_name_schema_info_table[23] = +RD_NameSchemaInfo rd_name_schema_info_table[24] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme Colors') @description(\"Additional theme colors which are applied on top of the project's theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("@row_commands(duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, @@ -410,6 +411,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[23] = {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, +{str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, @@ -470,7 +472,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[225] = +RD_CmdKindInfo rd_cmd_kind_info_table[226] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -555,6 +557,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[225] = { str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:tab_commands"), str8_lit_comp("commands"), CTRL_EntityKind_Null}}, { str8_lit_comp("build_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("duplicate_tab"), str8_lit_comp("Duplicates a tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Tab, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("copy_tab_full_path"), str8_lit_comp("Copies the full path of the file being viewed by this tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Tab, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Tab, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("move_view"), str8_lit_comp("Moves a view to a new panel."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("$tab,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 68ad0245..27f465e1 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -139,6 +139,7 @@ RD_CmdKind_MoveTabLeft, RD_CmdKind_OpenTab, RD_CmdKind_BuildTab, RD_CmdKind_DuplicateTab, +RD_CmdKind_CopyTabFullPath, RD_CmdKind_CloseTab, RD_CmdKind_MoveView, RD_CmdKind_TabBarTop, @@ -688,8 +689,8 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[332]; -extern RD_NameSchemaInfo rd_name_schema_info_table[23]; +extern RD_VocabInfo rd_vocab_info_table[333]; +extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a68df07f..6fb87c94 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -422,7 +422,7 @@ RD_VocabTable: { tab, ``` - @row_commands(duplicate_tab, close_tab) + @row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab) x: { @default(11) @display_name('Tab Font Size') @description("Controls the tab's font size.") @@ -544,6 +544,16 @@ RD_VocabTable: ``` } + //- rjf: getting started + { + getting_started, + ``` + @inherit(tab) x: + { + } + ``` + } + //- rjf: targets { target, @@ -833,6 +843,7 @@ RD_CmdTable: // | | | | {OpenTab 1 1 0 0 "query:tab_commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "open_tab" "Open New Tab" "Opens a new tab." "" "" } {BuildTab 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "build_tab" "Build Tab" "Opens a new tab with the parameterized view specification." "" "" } {DuplicateTab 1 1 0 0 "" Tab null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_tab" "Duplicate Tab" "Duplicates a tab." "" "$tab," } + {CopyTabFullPath 0 0 0 0 "" Tab null Nil Null 0 0 0 0 0 0 0 Clipboard "copy_tab_full_path" "Copy Full Path" "Copies the full path of the file being viewed by this tab." "" "$tab," } {CloseTab 1 1 0 0 "" Tab null Nil Null 0 0 0 0 0 0 0 X "close_tab" "Close Tab" "Closes the currently opened tab." "" "$tab," } {MoveView 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_view" "Move View" "Moves a view to a new panel." "" "" } {TabBarTop 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 UpArrow "tab_bar_top" "Anchor Tab Bar To Top" "Anchors a panel's tab bar to the top of the panel." "" "$tab," } @@ -845,7 +856,7 @@ RD_CmdTable: // | | | | {Switch 1 1 0 0 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } - {ShowFileInExplorer 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } + {ShowFileInExplorer 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FolderClosedFilled "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } //- rjf: source <-> disasm {GoToDisassembly 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" "$text_pt," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9fd5b2b0..6489cf3b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8462,7 +8462,9 @@ rd_window_frame(void) UI_Box *view_drop_site = &ui_nil_box; { RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(selected_tab->string); - if(view_ui_rule != &rd_nil_view_ui_rule && rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) + if(view_ui_rule != &rd_nil_view_ui_rule && rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && + !str8_match(selected_tab->string, str8_lit("text"), 0) && + !str8_match(selected_tab->string, str8_lit("disasm"), 0)) { UI_FixedSize(dim_2f32(content_rect)) view_drop_site = ui_build_box_from_stringf(UI_BoxFlag_DropSite|UI_BoxFlag_Floating, "drop_site_%I64x", selected_tab->id); @@ -8513,7 +8515,7 @@ rd_window_frame(void) UI_Signal sig = ui_signal_from_box(view_drop_site); if(ui_key_match(view_drop_site->key, ui_drop_hot_key())) { - UI_Parent(view_drop_site) UI_WidthFill UI_HeightFill UI_TagF("drop_site") UI_Transparency(0.5f) + UI_Parent(view_drop_site) UI_WidthFill UI_HeightFill UI_TagF("drop_site") { ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero()); } @@ -10396,15 +10398,14 @@ rd_init(CmdLine *cmdln) { user_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } - if(project_path.size == 0) - { - project_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); - } } - // rjf: do initial load - rd_cmd(RD_CmdKind_OpenUser, .file_path = user_path); - rd_cmd(RD_CmdKind_OpenProject, .file_path = project_path); + // rjf: do initial load of user (project will be loaded by the initial user load if not specified) + rd_cmd(RD_CmdKind_OpenUser, .file_path = user_path); + if(project_path.size != 0) + { + rd_cmd(RD_CmdKind_OpenProject, .file_path = project_path); + } scratch_end(scratch); } @@ -12483,6 +12484,24 @@ rd_frame(void) } } + //- rjf: if we've just loaded the user, and we do not have a project path, + // then we should try to look at the user's data for recent projects and + // load one of those, *or* just the default. + if(file_is_okay && kind == RD_CmdKind_OpenUser && rd_state->project_path.size == 0) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *recent_project = rd_cfg_child_from_string(user, str8_lit("recent_project")); + String8 project_path = rd_path_from_cfg(recent_project); + if(project_path.size == 0) + { + String8 user_program_data_path = os_get_process_info()->user_program_data_path; + String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); + os_make_directory(user_data_folder); + project_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); + } + rd_cmd(RD_CmdKind_OpenProject, .file_path = project_path); + } + //- rjf: update all window titles if(file_is_okay) { @@ -13219,6 +13238,13 @@ rd_frame(void) rd_cfg_insert_child(src->parent, src, dst); rd_cmd(RD_CmdKind_FocusTab, .tab = dst->id); }break; + case RD_CmdKind_CopyTabFullPath: + { + RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); + String8 expr = rd_expr_from_cfg(tab); + String8 full_path = rd_file_path_from_eval_string(scratch.arena, expr); + os_set_clipboard_text(full_path); + }break; case RD_CmdKind_CloseTab: { RD_Cfg *tab = rd_cfg_from_id(rd_regs()->tab); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index fb34db1c..c6a9aba0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1197,6 +1197,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("row_commands"), 0); for MD_EachNode(cmd, cmds_root->first) { + B32 is_file_only = md_node_has_tag(cmd, str8_lit("file"), 0); + if(is_file_only && e_eval_from_string(rd_expr_from_cfg(evalled_cfg)).space.kind != E_SpaceKind_File) + { + continue; + } String8 cmd_name = cmd->string; RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); switch(cmd_kind) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1248dc29..7a2361d0 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1261,6 +1261,52 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } } + ////////////////////////////// + //- rjf: dragging cfgs/entities/expressions? -> drop site + // + B32 drop_can_hit_lines = 0; + RD_Cfg *drop_cfg = &rd_nil_cfg; + CTRL_Entity *drop_thread = &ctrl_entity_nil; + String8 drop_expr = {0}; + Vec4F32 drop_color = pop_color; + UI_Key drop_site_key = ui_key_from_stringf(top_container_box->key, "drop_site"); + if(rd_drag_is_active()) + { + RD_Cfg *cfg = rd_cfg_from_id(rd_state->drag_drop_regs->cfg); + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && + (str8_match(cfg->string, str8_lit("breakpoint"), 0) || + str8_match(cfg->string, str8_lit("watch_pin"), 0))) + { + drop_can_hit_lines = 1; + drop_cfg = cfg; + drop_color = linear_from_srgba(rd_color_from_cfg(cfg)); + if(drop_color.w == 0) + { + drop_color = pop_color; + } + } + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) + { + drop_can_hit_lines = 1; + drop_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); + drop_color = rd_color_from_ctrl_entity(drop_thread); + if(drop_color.w == 0) + { + drop_color = pop_color; + } + } + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) + { + drop_can_hit_lines = 1; + drop_expr = rd_state->drag_drop_regs->expr; + } + if(drop_can_hit_lines) UI_WidthFill UI_HeightFill + { + UI_Box *drop_site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_Floating, drop_site_key); + ui_signal_from_box(drop_site_box); + } + } + ////////////////////////////// //- rjf: build per-line background colors // @@ -2102,10 +2148,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box); UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); - B32 line_drag_drop = 0; - RD_Cfg *line_drag_cfg = &rd_nil_cfg; - CTRL_Entity *line_drag_ctrl_entity = &ctrl_entity_nil; - Vec4F32 line_drag_drop_color = pop_color; { //- rjf: determine mouse drag range TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); @@ -2181,46 +2223,10 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe .lines = lines); } - //- rjf: dragging threads, breakpoints, or watch pins over this slice -> - // drop target - if(rd_drag_is_active() && contains_2f32(clipped_top_container_rect, ui_mouse())) - { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); - RD_Cfg *cfg = rd_cfg_from_id(rd_state->drag_drop_regs->cfg); - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && - (str8_match(cfg->string, str8_lit("breakpoint"), 0) || - str8_match(cfg->string, str8_lit("watch_pin"), 0))) - { - line_drag_drop = 1; - line_drag_cfg = cfg; - line_drag_drop_color = linear_from_srgba(rd_color_from_cfg(cfg)); - if(line_drag_drop_color.w == 0) - { - line_drag_drop_color = pop_color; - } - } - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) - { - line_drag_drop = 1; - line_drag_cfg = cfg; - line_drag_drop_color = pop_color; - } - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) - { - line_drag_drop = 1; - line_drag_ctrl_entity = thread; - line_drag_drop_color = rd_color_from_ctrl_entity(thread); - if(line_drag_drop_color.w == 0) - { - line_drag_drop_color = pop_color; - } - } - } - //- rjf: drop target is dropped -> process - if(contains_1s64(params->line_num_range, mouse_pt.line) && contains_2f32(clipped_top_container_rect, ui_mouse())) + if(drop_can_hit_lines && ui_key_match(ui_drop_hot_key(), drop_site_key) && rd_drag_drop()) { - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr && rd_drag_drop()) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Expr) { S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; @@ -2231,24 +2237,23 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); } - if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && line_drag_cfg != &rd_nil_cfg && rd_drag_drop()) + if(rd_state->drag_drop_regs_slot == RD_RegSlot_Cfg && drop_cfg != &rd_nil_cfg) { - RD_Cfg *dropped_cfg = line_drag_cfg; S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; U64 line_vaddr = params->line_vaddrs[line_idx]; rd_cmd(RD_CmdKind_RelocateCfg, - .cfg = dropped_cfg->id, + .cfg = drop_cfg->id, .file_path = line_vaddr == 0 ? rd_regs()->file_path : str8_zero(), .cursor = line_vaddr == 0 ? txt_pt(line_num, 1) : txt_pt(0, 0), .vaddr = line_vaddr); } - if(line_drag_ctrl_entity != &ctrl_entity_nil && rd_drag_drop()) + if(drop_thread != &ctrl_entity_nil) { S64 line_num = mouse_pt.line; U64 line_idx = line_num - params->line_num_range.min; U64 line_vaddr = params->line_vaddrs[line_idx]; - CTRL_Entity *thread = line_drag_ctrl_entity; + CTRL_Entity *thread = drop_thread; U64 new_rip_vaddr = line_vaddr; if(params->line_vaddrs[line_idx] == 0) { @@ -2355,12 +2360,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ////////////////////////////// //- rjf: dragging/dropping which applies to lines over this slice -> visualize // - if(line_drag_drop && contains_2f32(clipped_top_container_rect, ui_mouse())) + if(drop_can_hit_lines && ui_key_match(drop_site_key, ui_drop_hot_key())) { DR_Bucket *bucket = dr_bucket_make(); DR_BucketScope(bucket) { - Vec4F32 color = line_drag_drop_color; + Vec4F32 color = drop_color; color.w *= 0.2f; Rng2F32 drop_line_rect = r2f32p(top_container_box->rect.x0, top_container_box->rect.y0 + (mouse_pt.line - params->line_num_range.min) * params->line_height_px, From bbeeb3dde5b08ea94d89994df993454920822d40 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 10:35:37 -0700 Subject: [PATCH 541/755] ditto --- src/raddbg/raddbg_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6489cf3b..237acfe2 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10399,6 +10399,11 @@ rd_init(CmdLine *cmdln) user_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } } + if(project_path.size != 0) + { + arena_clear(rd_state->project_path_arena); + rd_state->project_path = push_str8_copy(rd_state->project_path_arena, project_path); + } // rjf: do initial load of user (project will be loaded by the initial user load if not specified) rd_cmd(RD_CmdKind_OpenUser, .file_path = user_path); From 137855c2173d9a67742824cc58b6384595cd7758 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 10:46:04 -0700 Subject: [PATCH 542/755] improve row-building for type evaluations (eliminate redunant cells, show offsets/sizes) --- src/raddbg/raddbg_views.c | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index c6a9aba0..f9e864f3 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1415,6 +1415,47 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } + //////////////////////////// + //- rjf: @watch_row_build_cells root-level type rows + // + else if(row->eval.irtree.mode == E_Mode_Null && row->block->eval.irtree.mode != E_Mode_Null) + { + info.cell_style_key = str8_lit("root_type"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, + .default_pct = 0.50f, + .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof($)"), .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "sizeof($)"), .default_pct = 0.15f, .pct = take_pct()); +#undef take_pct + } + + //////////////////////////// + //- rjf: @watch_row_build_cells sub-type rows + // + else if(row->eval.irtree.mode == E_Mode_Null) + { + info.cell_style_key = str8_lit("sub_type"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, + .default_pct = 0.35f, + .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof($)"), .default_pct = 0.35f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "sizeof($)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "(uint64)(&$)"), .default_pct = 0.15f, .pct = take_pct()); +#undef take_pct + } + //////////////////////////// //- rjf: @watch_row_build_cells catchall (normal rows) // From 2b12239300e400bb445265e77c8bd2e112f706d6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 11:10:14 -0700 Subject: [PATCH 543/755] preserve query regs in floating views, so that we can chain info from many query commands together; more progress on theme editing, simplify command surface --- src/raddbg/generated/raddbg.meta.c | 16 ++++++++-------- src/raddbg/generated/raddbg.meta.h | 4 ++-- src/raddbg/raddbg.mdesk | 18 +++++++++--------- src/raddbg/raddbg_core.c | 24 ++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index efa1de44..4f738014 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -351,8 +351,8 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("add_file_path_map"), str8_lit_comp(""), str8_lit_comp("Add File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("open_theme"), str8_lit_comp(""), str8_lit_comp("Open Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, -{str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp(""), str8_lit_comp("Fork Loaded Theme Colors"), str8_lit_comp(""), RD_IconKind_Palette}, -{str8_lit_comp("save_theme_colors"), str8_lit_comp(""), str8_lit_comp("Save Theme Colors"), str8_lit_comp(""), RD_IconKind_Save}, +{str8_lit_comp("fork_loaded_theme"), str8_lit_comp(""), str8_lit_comp("Fork Loaded Theme"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("save_theme"), str8_lit_comp(""), str8_lit_comp("Save Theme"), str8_lit_comp(""), RD_IconKind_Save}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -399,9 +399,9 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Theme Colors') @description(\"Additional theme colors which are applied on top of the theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme Colors') @description(\"Additional theme colors which are applied on top of the project's theme file or preset.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand @display_name('User Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @no_expand @display_name('User Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -654,10 +654,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[226] = { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_type_view"), str8_lit_comp("Adds a new type view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_file_path_map"), str8_lit_comp("Adds a new file path map."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("fork_loaded_theme_colors"), str8_lit_comp("Imports all colors from a loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("save_theme_colors"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("fork_loaded_theme"), str8_lit_comp("Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 27f465e1..deab288f 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -238,8 +238,8 @@ RD_CmdKind_AddTypeView, RD_CmdKind_AddFilePathMap, RD_CmdKind_OpenTheme, RD_CmdKind_AddThemeColor, -RD_CmdKind_ForkLoadedThemeColors, -RD_CmdKind_SaveThemeColors, +RD_CmdKind_ForkLoadedTheme, +RD_CmdKind_SaveTheme, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 6fb87c94..5a973a27 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -237,11 +237,11 @@ RD_VocabTable: 'code_font': string, //- rjf: theme - @display_name('Theme Preset') @description("The selected built-in theme preset.") + @no_expand @display_name('User Theme Preset') @description("The selected built-in theme preset.") 'theme_preset': string, - @no_expand @display_name('Theme File') @description("The path from which theme data is loaded, overriding the preset.") + @no_expand @no_expand @display_name('User Theme File') @description("The path from which theme data is loaded, overriding the preset.") 'theme_file': path, - @display_name('Theme Colors') @description("Additional theme colors which are applied on top of the theme file or preset.") + @display_name('User Theme') @description("The user's theme, which describes all colors used throughout the UI.") 'theme_colors': query, //- rjf: autocompletion @@ -291,11 +291,11 @@ RD_VocabTable: @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, //- rjf: theme - @display_name('Project Theme Preset') @description("The selected built-in project theme preset.") + @no_expand @display_name('Project Theme Preset') @description("The selected built-in project theme preset.") 'theme_preset': string, @no_expand @display_name('Project Theme File') @description("The path from which project's theme data is loaded, overriding the preset.") 'theme_file': path, - @display_name('Project Theme Colors') @description("Additional theme colors which are applied on top of the project's theme file or preset.") + @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") 'theme_colors': query, //- rjf: exception settings @@ -381,7 +381,7 @@ RD_VocabTable: { theme_color, ``` - @collection_commands(add_theme_color, fork_loaded_theme_colors, save_theme_colors) + @collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme) @row_commands(remove_cfg) x: { @@ -978,10 +978,10 @@ RD_CmdTable: // | | | | {AddFilePathMap 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "add_file_path_map" "Add File Path Map" "Adds a new file path map." "" "" } //- rjf: themes - {OpenTheme 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } + {OpenTheme 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } - {ForkLoadedThemeColors 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme_colors" "Fork Loaded Theme Colors" "Imports all colors from a loaded color theme file or color theme preset, so they can be individually edited." "" "" } - {SaveThemeColors 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_theme_colors" "Save Theme Colors" "Saves all theme colors to a new theme file." "" "" } + {ForkLoadedTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme" "Fork Loaded Theme" "Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited." "" "" } + {SaveTheme 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 237acfe2..fb5987b9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6612,6 +6612,7 @@ rd_window_frame(void) { FloatingViewTask *next; RD_Cfg *view; + RD_Regs *regs; Rng2F32 rect; B32 is_focused; B32 is_anchored; @@ -6941,6 +6942,7 @@ rd_window_frame(void) SLLQueuePush(first_floating_view_task, last_floating_view_task, t); query_floating_view_task = t; t->view = view; + t->regs = ws->query_regs; t->rect = rect; t->is_focused = 1; t->is_anchored = query_is_anchored; @@ -6970,8 +6972,13 @@ rd_window_frame(void) F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate, .reset = t->reset_open, .initial = 0.f); // rjf: push view regs - rd_push_regs(.view = view->id); + rd_push_regs(); { + if(t->regs != 0) + { + rd_regs()->cfg = t->regs->cfg; + } + rd_regs()->view = view->id; String8 view_expr = rd_expr_from_cfg(view); String8 view_file_path = rd_file_path_from_eval_string(rd_frame_arena(), view_expr); // NOTE(rjf): we want to only fill out this view's file path slot if it @@ -14709,7 +14716,7 @@ rd_frame(void) RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); rd_cfg_new(value, str8_lit("0xffffffff")); }break; - case RD_CmdKind_ForkLoadedThemeColors: + case RD_CmdKind_ForkLoadedTheme: { RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); @@ -14734,6 +14741,19 @@ rd_frame(void) } } }break; + case RD_CmdKind_SaveTheme: + { + String8 dst_path = rd_regs()->file_path; + RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); + String8List strings = {0}; + for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, n->v)); + } + String8 data = str8_list_join(scratch.arena, &strings, 0); + os_write_data_to_file_path(dst_path, data); + }break; //- rjf: watches case RD_CmdKind_ToggleWatchExpression: From adf2eabba7b5834d8240fe070e0e1d2902832b45 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 11:34:24 -0700 Subject: [PATCH 544/755] eliminate remaining usage code of old theme system; to not pay the cost of slower-path color lookups for every single syntax highlighted thing in the UI, just introduce 'code color slots', which are computed once per window per frame --- src/raddbg/generated/raddbg.meta.c | 1722 +--------------------------- src/raddbg/generated/raddbg.meta.h | 180 +-- src/raddbg/raddbg.mdesk | 253 +--- src/raddbg/raddbg_core.c | 167 +-- src/raddbg/raddbg_core.h | 21 +- src/raddbg/raddbg_widgets.c | 26 +- 6 files changed, 106 insertions(+), 2263 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 4f738014..f9746876 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -920,6 +920,24 @@ str8_lit_comp(")"), str8_lit_comp("#"), }; +String8 rd_code_color_slot_name_table[14] = +{ +str8_lit_comp("code_default"), +str8_lit_comp("code_symbol"), +str8_lit_comp("code_type"), +str8_lit_comp("code_local"), +str8_lit_comp("code_register"), +str8_lit_comp("code_keyword"), +str8_lit_comp("code_delimiter_or_operator"), +str8_lit_comp("code_numeric"), +str8_lit_comp("code_numeric_alt_digit_group"), +str8_lit_comp("code_string"), +str8_lit_comp("code_meta"), +str8_lit_comp("code_comment"), +str8_lit_comp("code_line_numbers"), +str8_lit_comp("code_line_numbers_selected"), +}; + String8 rd_theme_preset_display_string_table[9] = { str8_lit_comp("Default (Dark)"), @@ -959,1709 +977,5 @@ str8_lit_comp(""), str8_lit_comp(""), }; -String8 rd_theme_color_version_remap_old_name_table[22] = -{ -str8_lit_comp("plain_text"), -str8_lit_comp("plain_background"), -str8_lit_comp("plain_border"), -str8_lit_comp("plain_overlay"), -str8_lit_comp("code_function"), -str8_lit_comp("code_symbol"), -str8_lit_comp("code_numeric"), -str8_lit_comp("line_info_0"), -str8_lit_comp("line_info_1"), -str8_lit_comp("line_info_2"), -str8_lit_comp("line_info_3"), -str8_lit_comp("alt_background"), -str8_lit_comp("alt_border"), -str8_lit_comp("tab_inactive"), -str8_lit_comp("tab_active"), -str8_lit_comp("weak_text"), -str8_lit_comp("text_selection"), -str8_lit_comp("cursor"), -str8_lit_comp("highlight_0"), -str8_lit_comp("success_background"), -str8_lit_comp("failure_background"), -str8_lit_comp("action_background"), -}; - -String8 rd_theme_color_version_remap_new_name_table[22] = -{ -str8_lit_comp("text"), -str8_lit_comp("base_background"), -str8_lit_comp("base_border"), -str8_lit_comp("drop_site_overlay"), -str8_lit_comp("code_symbol"), -str8_lit_comp("code_delimiter_operator"), -str8_lit_comp("code_numeric_alt_digit_group"), -str8_lit_comp("line_info_background_0"), -str8_lit_comp("line_info_background_1"), -str8_lit_comp("line_info_background_2"), -str8_lit_comp("line_info_background_3"), -str8_lit_comp("menu_bar_background"), -str8_lit_comp("menu_bar_border"), -str8_lit_comp("tab_background_inactive"), -str8_lit_comp("tab_background"), -str8_lit_comp("text_weak"), -str8_lit_comp("selection"), -str8_lit_comp("cursor"), -str8_lit_comp("focus"), -str8_lit_comp("positive_pop_button_background"), -str8_lit_comp("negative_pop_button_background"), -str8_lit_comp("neutral_pop_button_background"), -}; - -Vec4F32 rd_theme_preset_colors__default_dark[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x2b3740ff), -rgba_from_u32_lit_comp(0x2b3740ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x222222ff), -rgba_from_u32_lit_comp(0x404040ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xcbcbcbff), -rgba_from_u32_lit_comp(0x42a2cfff), -rgba_from_u32_lit_comp(0xfec746ff), -rgba_from_u32_lit_comp(0x98bc80ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0xb38d4cff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0x98abb1ff), -rgba_from_u32_lit_comp(0x738287ff), -rgba_from_u32_lit_comp(0x98abb1ff), -rgba_from_u32_lit_comp(0xd96759ff), -rgba_from_u32_lit_comp(0x717171ff), -rgba_from_u32_lit_comp(0x7f7f7fff), -rgba_from_u32_lit_comp(0xbebebeff), -rgba_from_u32_lit_comp(0x99503dff), -rgba_from_u32_lit_comp(0xfe8249ff), -rgba_from_u32_lit_comp(0xffba17ff), -rgba_from_u32_lit_comp(0xcefd69ff), -rgba_from_u32_lit_comp(0x99503dff), -rgba_from_u32_lit_comp(0xfe8249ff), -rgba_from_u32_lit_comp(0xffba17ff), -rgba_from_u32_lit_comp(0xcefd69ff), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x355b6eff), -}; - -Vec4F32 rd_theme_preset_colors__default_light[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xa4a4a43f), -rgba_from_u32_lit_comp(0x0000004c), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0xccccccfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xa4a4a4fe), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4c4c4cff), -rgba_from_u32_lit_comp(0x4d4d4dff), -rgba_from_u32_lit_comp(0x205670fe), -rgba_from_u32_lit_comp(0x996b00ff), -rgba_from_u32_lit_comp(0x446a2bff), -rgba_from_u32_lit_comp(0x4c35a1ff), -rgba_from_u32_lit_comp(0x573700ff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0x3f6e7dff), -rgba_from_u32_lit_comp(0x1f4450ff), -rgba_from_u32_lit_comp(0x3c606bff), -rgba_from_u32_lit_comp(0xad3627ff), -rgba_from_u32_lit_comp(0x4b4b4bff), -rgba_from_u32_lit_comp(0x4b4b4bff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x945800ff), -rgba_from_u32_lit_comp(0x3f5b23ff), -rgba_from_u32_lit_comp(0x642a55ff), -rgba_from_u32_lit_comp(0x30456fff), -rgba_from_u32_lit_comp(0x264f41ff), -rgba_from_u32_lit_comp(0x736a5fff), -rgba_from_u32_lit_comp(0x472f5eff), -rgba_from_u32_lit_comp(0x405d3bff), -rgba_from_u32_lit_comp(0x49606aff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xff2800ff), -rgba_from_u32_lit_comp(0xa6becaff), -}; - -Vec4F32 rd_theme_preset_colors__vs_dark[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x1b1b1bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xe5e5e5ff), -rgba_from_u32_lit_comp(0xcbcbcbff), -rgba_from_u32_lit_comp(0xdcdcaaff), -rgba_from_u32_lit_comp(0x4ec9afff), -rgba_from_u32_lit_comp(0x9cdbfeff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0x569cd6ff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0xb5cea8ff), -rgba_from_u32_lit_comp(0x729360ff), -rgba_from_u32_lit_comp(0xd59b85ff), -rgba_from_u32_lit_comp(0xd59c85ff), -rgba_from_u32_lit_comp(0x57a54aff), -rgba_from_u32_lit_comp(0x2a91afff), -rgba_from_u32_lit_comp(0x9ddaecff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x355b6eff), -}; - -Vec4F32 rd_theme_preset_colors__vs_light[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0xfefefe53), -rgba_from_u32_lit_comp(0xa3a3a37e), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xfefefefe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xe7e7e7fe), -rgba_from_u32_lit_comp(0xb6b6b6ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0x000000ff), -rgba_from_u32_lit_comp(0xa33700ff), -rgba_from_u32_lit_comp(0x007666ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0x0000ffff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0x088658ff), -rgba_from_u32_lit_comp(0x0c3828ff), -rgba_from_u32_lit_comp(0xa31414ff), -rgba_from_u32_lit_comp(0x0000ffff), -rgba_from_u32_lit_comp(0x008000ff), -rgba_from_u32_lit_comp(0x227893ff), -rgba_from_u32_lit_comp(0x123d4bfe), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x945800ff), -rgba_from_u32_lit_comp(0x3f5b23ff), -rgba_from_u32_lit_comp(0x642a55ff), -rgba_from_u32_lit_comp(0x30456fff), -rgba_from_u32_lit_comp(0x264f41ff), -rgba_from_u32_lit_comp(0x736a5fff), -rgba_from_u32_lit_comp(0x472f5eff), -rgba_from_u32_lit_comp(0x405d3bff), -rgba_from_u32_lit_comp(0x49606aff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x6e9db5ff), -}; - -Vec4F32 rd_theme_preset_colors__solarized_dark[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x002a35fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xfefefe3a), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0x999999ff), -rgba_from_u32_lit_comp(0xcbcbcbff), -rgba_from_u32_lit_comp(0xcb4a15ff), -rgba_from_u32_lit_comp(0xcb4a15ff), -rgba_from_u32_lit_comp(0x98bc80ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0x849803ff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0xd33582ff), -rgba_from_u32_lit_comp(0x902559ff), -rgba_from_u32_lit_comp(0x1f9d91ff), -rgba_from_u32_lit_comp(0x839802ff), -rgba_from_u32_lit_comp(0x556a6fff), -rgba_from_u32_lit_comp(0x566c73ff), -rgba_from_u32_lit_comp(0xa2aaacff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x355b6eff), -}; - -Vec4F32 rd_theme_preset_colors__solarized_light[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000001c), -rgba_from_u32_lit_comp(0xc9bfa394), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0xfcf5e2fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0xbebaabfe), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x333333ff), -rgba_from_u32_lit_comp(0x657b83ff), -rgba_from_u32_lit_comp(0xcb4a15ff), -rgba_from_u32_lit_comp(0xcb4a15ff), -rgba_from_u32_lit_comp(0x258ad2ff), -rgba_from_u32_lit_comp(0x373345ff), -rgba_from_u32_lit_comp(0x586e75ff), -rgba_from_u32_lit_comp(0x767676ff), -rgba_from_u32_lit_comp(0xd33482ef), -rgba_from_u32_lit_comp(0x8e2659ff), -rgba_from_u32_lit_comp(0x29a198ff), -rgba_from_u32_lit_comp(0xd96759ff), -rgba_from_u32_lit_comp(0x93a1a1ff), -rgba_from_u32_lit_comp(0x227893ef), -rgba_from_u32_lit_comp(0x111e22ef), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x945800ff), -rgba_from_u32_lit_comp(0x3f5b23ff), -rgba_from_u32_lit_comp(0x642a55ff), -rgba_from_u32_lit_comp(0x30456fff), -rgba_from_u32_lit_comp(0x264f41ff), -rgba_from_u32_lit_comp(0x736a5fff), -rgba_from_u32_lit_comp(0x472f5eff), -rgba_from_u32_lit_comp(0x405d3bff), -rgba_from_u32_lit_comp(0x49606aff), -rgba_from_u32_lit_comp(0xb23218ff), -rgba_from_u32_lit_comp(0xff684bff), -rgba_from_u32_lit_comp(0xb2d3e3ff), -}; - -Vec4F32 rd_theme_preset_colors__handmade_hero[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x423525fe), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xcc5634ff), -rgba_from_u32_lit_comp(0xd8a51bff), -rgba_from_u32_lit_comp(0xc04047ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0xac7a09ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0x698e21ff), -rgba_from_u32_lit_comp(0x3a4e11ff), -rgba_from_u32_lit_comp(0x6a8e22ff), -rgba_from_u32_lit_comp(0xdab98fff), -rgba_from_u32_lit_comp(0x686868ff), -rgba_from_u32_lit_comp(0xa08462ff), -rgba_from_u32_lit_comp(0xc8b399ff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x15445cff), -}; - -Vec4F32 rd_theme_preset_colors__four_coder[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x0c0c0cfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x3f3f3ffe), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x42a2cffe), -rgba_from_u32_lit_comp(0xfd7c52ff), -rgba_from_u32_lit_comp(0x98bc80ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0xd08f1eff), -rgba_from_u32_lit_comp(0x90b080ff), -rgba_from_u32_lit_comp(0x4fff2eff), -rgba_from_u32_lit_comp(0x3ccd21ff), -rgba_from_u32_lit_comp(0x4fff2eff), -rgba_from_u32_lit_comp(0xa0b8a0ff), -rgba_from_u32_lit_comp(0x1e8fefff), -rgba_from_u32_lit_comp(0x7e7e7ffe), -rgba_from_u32_lit_comp(0xbebebeff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xa72911ff), -rgba_from_u32_lit_comp(0x1b323eff), -}; - -Vec4F32 rd_theme_preset_colors__far_manager[145] = -{ -rgba_from_u32_lit_comp(0xff00ffff), -rgba_from_u32_lit_comp(0x0000003f), -rgba_from_u32_lit_comp(0x0000007f), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x000081fe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x2b2b2bfe), -rgba_from_u32_lit_comp(0x0000fffe), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x65b1ffff), -rgba_from_u32_lit_comp(0xfec746ff), -rgba_from_u32_lit_comp(0x00ff00ff), -rgba_from_u32_lit_comp(0xb7afd5ff), -rgba_from_u32_lit_comp(0x00ffffff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x00ff00ff), -rgba_from_u32_lit_comp(0x738287ff), -rgba_from_u32_lit_comp(0x98abb1ff), -rgba_from_u32_lit_comp(0xff0000ff), -rgba_from_u32_lit_comp(0xffffffff), -rgba_from_u32_lit_comp(0x007d7dff), -rgba_from_u32_lit_comp(0x00fefeff), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0x99503d3f), -rgba_from_u32_lit_comp(0xfe82493f), -rgba_from_u32_lit_comp(0xffba173f), -rgba_from_u32_lit_comp(0xcefd693f), -rgba_from_u32_lit_comp(0xffcb7fff), -rgba_from_u32_lit_comp(0xb2ff65ff), -rgba_from_u32_lit_comp(0xff99e5ff), -rgba_from_u32_lit_comp(0x6598ffff), -rgba_from_u32_lit_comp(0x65ffcbff), -rgba_from_u32_lit_comp(0xff9819ff), -rgba_from_u32_lit_comp(0x9932ffff), -rgba_from_u32_lit_comp(0x65ff4cff), -rgba_from_u32_lit_comp(0xb2ccd8ff), -rgba_from_u32_lit_comp(0xb23219ff), -rgba_from_u32_lit_comp(0xff2800ff), -rgba_from_u32_lit_comp(0x933100ff), -}; - -Vec4F32* rd_theme_preset_colors_table[9] = -{ -rd_theme_preset_colors__default_dark, -rd_theme_preset_colors__default_light, -rd_theme_preset_colors__vs_dark, -rd_theme_preset_colors__vs_light, -rd_theme_preset_colors__solarized_dark, -rd_theme_preset_colors__solarized_light, -rd_theme_preset_colors__handmade_hero, -rd_theme_preset_colors__four_coder, -rd_theme_preset_colors__far_manager, -}; - -String8 rd_theme_color_display_string_table[145] = -{ -str8_lit_comp("Null"), -str8_lit_comp("Inactive Panel Overlay"), -str8_lit_comp("Drop Shadow"), -str8_lit_comp("Base Background"), -str8_lit_comp("Base Background (Alternate)"), -str8_lit_comp("Base Background (Good)"), -str8_lit_comp("Base Background (Bad)"), -str8_lit_comp("Base Background (Pop)"), -str8_lit_comp("Base Border"), -str8_lit_comp("Base Text"), -str8_lit_comp("Base Text (Weak)"), -str8_lit_comp("Base Hover"), -str8_lit_comp("Base Focus"), -str8_lit_comp("Base Cursor"), -str8_lit_comp("Base Selection"), -str8_lit_comp("Menu Bar Background"), -str8_lit_comp("Menu Bar Background (Alternate)"), -str8_lit_comp("Menu Bar Background (Good)"), -str8_lit_comp("Menu Bar Background (Bad)"), -str8_lit_comp("Menu Bar Background (Pop)"), -str8_lit_comp("Menu Bar Border"), -str8_lit_comp("Menu Bar Text"), -str8_lit_comp("Menu Bar Text (Weak)"), -str8_lit_comp("Menu Bar Hover"), -str8_lit_comp("Menu Bar Focus"), -str8_lit_comp("Menu Bar Cursor"), -str8_lit_comp("Menu Bar Selection"), -str8_lit_comp("Good Background"), -str8_lit_comp("Good Background (Alternate)"), -str8_lit_comp("Good Background (Good)"), -str8_lit_comp("Good Background (Bad)"), -str8_lit_comp("Good Background (Pop)"), -str8_lit_comp("Good Border"), -str8_lit_comp("Good Text"), -str8_lit_comp("Good Text (Weak)"), -str8_lit_comp("Good Hover"), -str8_lit_comp("Good Focus"), -str8_lit_comp("Good Cursor"), -str8_lit_comp("Good Selection"), -str8_lit_comp("Bad Background"), -str8_lit_comp("Bad Background (Alternate)"), -str8_lit_comp("Bad Background (Good)"), -str8_lit_comp("Bad Background (Bad)"), -str8_lit_comp("Bad Background (Pop)"), -str8_lit_comp("Bad Border"), -str8_lit_comp("Bad Text"), -str8_lit_comp("Bad Text (Weak)"), -str8_lit_comp("Bad Hover"), -str8_lit_comp("Bad Focus"), -str8_lit_comp("Bad Cursor"), -str8_lit_comp("Bad Selection"), -str8_lit_comp("Pop Background"), -str8_lit_comp("Pop Background (Alternate)"), -str8_lit_comp("Pop Background (Good)"), -str8_lit_comp("Pop Background (Bad)"), -str8_lit_comp("Pop Background (Pop)"), -str8_lit_comp("Pop Border"), -str8_lit_comp("Pop Text"), -str8_lit_comp("Pop Text (Weak)"), -str8_lit_comp("Pop Hover"), -str8_lit_comp("Pop Focus"), -str8_lit_comp("Pop Cursor"), -str8_lit_comp("Pop Selection"), -str8_lit_comp("Scroll Bar Background"), -str8_lit_comp("Scroll Bar Background (Alternate)"), -str8_lit_comp("Scroll Bar Background (Good)"), -str8_lit_comp("Scroll Bar Background (Bad)"), -str8_lit_comp("Scroll Bar Background (Pop)"), -str8_lit_comp("Scroll Bar Border"), -str8_lit_comp("Scroll Bar Text"), -str8_lit_comp("Scroll Bar Text (Weak)"), -str8_lit_comp("Scroll Bar Hover"), -str8_lit_comp("Scroll Bar Focus"), -str8_lit_comp("Scroll Bar Cursor"), -str8_lit_comp("Scroll Bar Selection"), -str8_lit_comp("Tab Background"), -str8_lit_comp("Tab Background (Alternate)"), -str8_lit_comp("Tab Background (Good)"), -str8_lit_comp("Tab Background (Bad)"), -str8_lit_comp("Tab Background (Pop)"), -str8_lit_comp("Tab Border"), -str8_lit_comp("Tab Text"), -str8_lit_comp("Tab Text (Weak)"), -str8_lit_comp("Tab Hover"), -str8_lit_comp("Tab Focus"), -str8_lit_comp("Tab Cursor"), -str8_lit_comp("Tab Selection"), -str8_lit_comp("Tab (Inactive) Background"), -str8_lit_comp("Tab (Inactive) Background (Alternate)"), -str8_lit_comp("Tab (Inactive) Background (Good)"), -str8_lit_comp("Tab (Inactive) Background (Bad)"), -str8_lit_comp("Tab (Inactive) Background (Pop)"), -str8_lit_comp("Tab (Inactive) Border"), -str8_lit_comp("Tab (Inactive) Text"), -str8_lit_comp("Tab (Inactive) Text (Weak)"), -str8_lit_comp("Tab (Inactive) Hover"), -str8_lit_comp("Tab (Inactive) Focus"), -str8_lit_comp("Tab (Inactive) Cursor"), -str8_lit_comp("Tab (Inactive) Selection"), -str8_lit_comp("Drop Site Background"), -str8_lit_comp("Drop Site Background (Alternate)"), -str8_lit_comp("Drop Site Background (Good)"), -str8_lit_comp("Drop Site Background (Bad)"), -str8_lit_comp("Drop Site Background (Pop)"), -str8_lit_comp("Drop Site Border"), -str8_lit_comp("Drop Site Text"), -str8_lit_comp("Drop Site Text (Weak)"), -str8_lit_comp("Drop Site Hover"), -str8_lit_comp("Drop Site Focus"), -str8_lit_comp("Drop Site Cursor"), -str8_lit_comp("Drop Site Selection"), -str8_lit_comp("Code (Default)"), -str8_lit_comp("Code (Symbol)"), -str8_lit_comp("Code (Type)"), -str8_lit_comp("Code (Local)"), -str8_lit_comp("Code (Register)"), -str8_lit_comp("Code (Keyword)"), -str8_lit_comp("Code (Delimiters/Operators)"), -str8_lit_comp("Code (Numeric)"), -str8_lit_comp("Code (Numeric, Alt. Digit Group)"), -str8_lit_comp("Code (String)"), -str8_lit_comp("Code (Meta)"), -str8_lit_comp("Code (Comment)"), -str8_lit_comp("Code Line Numbers"), -str8_lit_comp("Code Line Numbers (Selected)"), -str8_lit_comp("Line Info Background 0"), -str8_lit_comp("Line Info Background 1"), -str8_lit_comp("Line Info Background 2"), -str8_lit_comp("Line Info Background 3"), -str8_lit_comp("Line Info Background 4"), -str8_lit_comp("Line Info Background 5"), -str8_lit_comp("Line Info Background 6"), -str8_lit_comp("Line Info Background 7"), -str8_lit_comp("Thread 0"), -str8_lit_comp("Thread 1"), -str8_lit_comp("Thread 2"), -str8_lit_comp("Thread 3"), -str8_lit_comp("Thread 4"), -str8_lit_comp("Thread 5"), -str8_lit_comp("Thread 6"), -str8_lit_comp("Thread 7"), -str8_lit_comp("Thread (Unwound)"), -str8_lit_comp("Thread (Error)"), -str8_lit_comp("Breakpoint"), -str8_lit_comp("Cache Line Boundary"), -}; - -String8 rd_theme_color_cfg_string_table[145] = -{ -str8_lit_comp("null"), -str8_lit_comp("inactive_panel_overlay"), -str8_lit_comp("drop_shadow"), -str8_lit_comp("base_background"), -str8_lit_comp("base_background_alt"), -str8_lit_comp("base_background_good"), -str8_lit_comp("base_background_bad"), -str8_lit_comp("base_background_pop"), -str8_lit_comp("base_border"), -str8_lit_comp("base_text"), -str8_lit_comp("base_text_weak"), -str8_lit_comp("base_hover"), -str8_lit_comp("base_focus"), -str8_lit_comp("base_cursor"), -str8_lit_comp("base_cursor"), -str8_lit_comp("menu_bar_background"), -str8_lit_comp("menu_bar_background_alt"), -str8_lit_comp("menu_bar_background_good"), -str8_lit_comp("menu_bar_background_bad"), -str8_lit_comp("menu_bar_background_pop"), -str8_lit_comp("menu_bar_border"), -str8_lit_comp("menu_bar_text"), -str8_lit_comp("menu_bar_text_weak"), -str8_lit_comp("menu_bar_hover"), -str8_lit_comp("menu_bar_focus"), -str8_lit_comp("menu_bar_cursor"), -str8_lit_comp("menu_bar_cursor"), -str8_lit_comp("good_background"), -str8_lit_comp("good_background_alt"), -str8_lit_comp("good_background_good"), -str8_lit_comp("good_background_bad"), -str8_lit_comp("good_background_pop"), -str8_lit_comp("good_border"), -str8_lit_comp("good_text"), -str8_lit_comp("good_text_weak"), -str8_lit_comp("good_hover"), -str8_lit_comp("good_focus"), -str8_lit_comp("good_cursor"), -str8_lit_comp("good_cursor"), -str8_lit_comp("bad_background"), -str8_lit_comp("bad_background_alt"), -str8_lit_comp("bad_background_good"), -str8_lit_comp("bad_background_bad"), -str8_lit_comp("bad_background_pop"), -str8_lit_comp("bad_border"), -str8_lit_comp("bad_text"), -str8_lit_comp("bad_text_weak"), -str8_lit_comp("bad_hover"), -str8_lit_comp("bad_focus"), -str8_lit_comp("bad_cursor"), -str8_lit_comp("bad_cursor"), -str8_lit_comp("pop_background"), -str8_lit_comp("pop_background_alt"), -str8_lit_comp("pop_background_good"), -str8_lit_comp("pop_background_bad"), -str8_lit_comp("pop_background_pop"), -str8_lit_comp("pop_border"), -str8_lit_comp("pop_text"), -str8_lit_comp("pop_text_weak"), -str8_lit_comp("pop_hover"), -str8_lit_comp("pop_focus"), -str8_lit_comp("pop_cursor"), -str8_lit_comp("pop_cursor"), -str8_lit_comp("scroll_bar_background"), -str8_lit_comp("scroll_bar_background_alt"), -str8_lit_comp("scroll_bar_background_good"), -str8_lit_comp("scroll_bar_background_bad"), -str8_lit_comp("scroll_bar_background_pop"), -str8_lit_comp("scroll_bar_border"), -str8_lit_comp("scroll_bar_text"), -str8_lit_comp("scroll_bar_text_weak"), -str8_lit_comp("scroll_bar_hover"), -str8_lit_comp("scroll_bar_focus"), -str8_lit_comp("scroll_bar_cursor"), -str8_lit_comp("scroll_bar_cursor"), -str8_lit_comp("tab_background"), -str8_lit_comp("tab_background_alt"), -str8_lit_comp("tab_background_good"), -str8_lit_comp("tab_background_bad"), -str8_lit_comp("tab_background_pop"), -str8_lit_comp("tab_border"), -str8_lit_comp("tab_text"), -str8_lit_comp("tab_text_weak"), -str8_lit_comp("tab_hover"), -str8_lit_comp("tab_focus"), -str8_lit_comp("tab_cursor"), -str8_lit_comp("tab_cursor"), -str8_lit_comp("tab_inactive_background"), -str8_lit_comp("tab_inactive_background_alt"), -str8_lit_comp("tab_inactive_background_good"), -str8_lit_comp("tab_inactive_background_bad"), -str8_lit_comp("tab_inactive_background_pop"), -str8_lit_comp("tab_inactive_border"), -str8_lit_comp("tab_inactive_text"), -str8_lit_comp("tab_inactive_text_weak"), -str8_lit_comp("tab_inactive_hover"), -str8_lit_comp("tab_inactive_focus"), -str8_lit_comp("tab_inactive_cursor"), -str8_lit_comp("tab_inactive_cursor"), -str8_lit_comp("drop_site_background"), -str8_lit_comp("drop_site_background_alt"), -str8_lit_comp("drop_site_background_good"), -str8_lit_comp("drop_site_background_bad"), -str8_lit_comp("drop_site_background_pop"), -str8_lit_comp("drop_site_border"), -str8_lit_comp("drop_site_text"), -str8_lit_comp("drop_site_text_weak"), -str8_lit_comp("drop_site_hover"), -str8_lit_comp("drop_site_focus"), -str8_lit_comp("drop_site_cursor"), -str8_lit_comp("drop_site_cursor"), -str8_lit_comp("code_default"), -str8_lit_comp("code_symbol"), -str8_lit_comp("code_type"), -str8_lit_comp("code_local"), -str8_lit_comp("code_register"), -str8_lit_comp("code_keyword"), -str8_lit_comp("code_delimiter_operator"), -str8_lit_comp("code_numeric"), -str8_lit_comp("code_numeric_alt_digit_group"), -str8_lit_comp("code_string"), -str8_lit_comp("code_meta"), -str8_lit_comp("code_comment"), -str8_lit_comp("code_line_numbers"), -str8_lit_comp("code_line_numbers_selected"), -str8_lit_comp("line_info_background_0"), -str8_lit_comp("line_info_background_1"), -str8_lit_comp("line_info_background_2"), -str8_lit_comp("line_info_background_3"), -str8_lit_comp("line_info_background_4"), -str8_lit_comp("line_info_background_5"), -str8_lit_comp("line_info_background_6"), -str8_lit_comp("line_info_background_7"), -str8_lit_comp("thread_0"), -str8_lit_comp("thread_1"), -str8_lit_comp("thread_2"), -str8_lit_comp("thread_3"), -str8_lit_comp("thread_4"), -str8_lit_comp("thread_5"), -str8_lit_comp("thread_6"), -str8_lit_comp("thread_7"), -str8_lit_comp("thread_unwound"), -str8_lit_comp("thread_error"), -str8_lit_comp("breakpoint"), -str8_lit_comp("cache_line_boundary"), -}; - C_LINKAGE_END diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index deab288f..b6a08655 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -366,155 +366,24 @@ RD_IconKind_Duplicate, RD_IconKind_COUNT, } RD_IconKind; -typedef enum RD_ThemeColor +typedef enum RD_CodeColorSlot { -RD_ThemeColor_Null, -RD_ThemeColor_InactivePanelOverlay, -RD_ThemeColor_DropShadow, -RD_ThemeColor_BaseBackground, -RD_ThemeColor_BaseBackgroundAlt, -RD_ThemeColor_BaseBackgroundGood, -RD_ThemeColor_BaseBackgroundBad, -RD_ThemeColor_BaseBackgroundPop, -RD_ThemeColor_BaseBorder, -RD_ThemeColor_BaseText, -RD_ThemeColor_BaseTextWeak, -RD_ThemeColor_BaseHover, -RD_ThemeColor_BaseFocus, -RD_ThemeColor_BaseCursor, -RD_ThemeColor_BaseSelection, -RD_ThemeColor_MenuBarBackground, -RD_ThemeColor_MenuBarBackgroundAlt, -RD_ThemeColor_MenuBarBackgroundGood, -RD_ThemeColor_MenuBarBackgroundBad, -RD_ThemeColor_MenuBarBackgroundPop, -RD_ThemeColor_MenuBarBorder, -RD_ThemeColor_MenuBarText, -RD_ThemeColor_MenuBarTextWeak, -RD_ThemeColor_MenuBarHover, -RD_ThemeColor_MenuBarFocus, -RD_ThemeColor_MenuBarCursor, -RD_ThemeColor_MenuBarSelection, -RD_ThemeColor_GoodBackground, -RD_ThemeColor_GoodBackgroundAlt, -RD_ThemeColor_GoodBackgroundGood, -RD_ThemeColor_GoodBackgroundBad, -RD_ThemeColor_GoodBackgroundPop, -RD_ThemeColor_GoodBorder, -RD_ThemeColor_GoodText, -RD_ThemeColor_GoodTextWeak, -RD_ThemeColor_GoodHover, -RD_ThemeColor_GoodFocus, -RD_ThemeColor_GoodCursor, -RD_ThemeColor_GoodSelection, -RD_ThemeColor_BadBackground, -RD_ThemeColor_BadBackgroundAlt, -RD_ThemeColor_BadBackgroundGood, -RD_ThemeColor_BadBackgroundBad, -RD_ThemeColor_BadBackgroundPop, -RD_ThemeColor_BadBorder, -RD_ThemeColor_BadText, -RD_ThemeColor_BadTextWeak, -RD_ThemeColor_BadHover, -RD_ThemeColor_BadFocus, -RD_ThemeColor_BadCursor, -RD_ThemeColor_BadSelection, -RD_ThemeColor_PopBackground, -RD_ThemeColor_PopBackgroundAlt, -RD_ThemeColor_PopBackgroundGood, -RD_ThemeColor_PopBackgroundBad, -RD_ThemeColor_PopBackgroundPop, -RD_ThemeColor_PopBorder, -RD_ThemeColor_PopText, -RD_ThemeColor_PopTextWeak, -RD_ThemeColor_PopHover, -RD_ThemeColor_PopFocus, -RD_ThemeColor_PopCursor, -RD_ThemeColor_PopSelection, -RD_ThemeColor_ScrollBarBackground, -RD_ThemeColor_ScrollBarBackgroundAlt, -RD_ThemeColor_ScrollBarBackgroundGood, -RD_ThemeColor_ScrollBarBackgroundBad, -RD_ThemeColor_ScrollBarBackgroundPop, -RD_ThemeColor_ScrollBarBorder, -RD_ThemeColor_ScrollBarText, -RD_ThemeColor_ScrollBarTextWeak, -RD_ThemeColor_ScrollBarHover, -RD_ThemeColor_ScrollBarFocus, -RD_ThemeColor_ScrollBarCursor, -RD_ThemeColor_ScrollBarSelection, -RD_ThemeColor_TabBackground, -RD_ThemeColor_TabBackgroundAlt, -RD_ThemeColor_TabBackgroundGood, -RD_ThemeColor_TabBackgroundBad, -RD_ThemeColor_TabBackgroundPop, -RD_ThemeColor_TabBorder, -RD_ThemeColor_TabText, -RD_ThemeColor_TabTextWeak, -RD_ThemeColor_TabHover, -RD_ThemeColor_TabFocus, -RD_ThemeColor_TabCursor, -RD_ThemeColor_TabSelection, -RD_ThemeColor_TabInactiveBackground, -RD_ThemeColor_TabInactiveBackgroundAlt, -RD_ThemeColor_TabInactiveBackgroundGood, -RD_ThemeColor_TabInactiveBackgroundBad, -RD_ThemeColor_TabInactiveBackgroundPop, -RD_ThemeColor_TabInactiveBorder, -RD_ThemeColor_TabInactiveText, -RD_ThemeColor_TabInactiveTextWeak, -RD_ThemeColor_TabInactiveHover, -RD_ThemeColor_TabInactiveFocus, -RD_ThemeColor_TabInactiveCursor, -RD_ThemeColor_TabInactiveSelection, -RD_ThemeColor_DropSiteBackground, -RD_ThemeColor_DropSiteBackgroundAlt, -RD_ThemeColor_DropSiteBackgroundGood, -RD_ThemeColor_DropSiteBackgroundBad, -RD_ThemeColor_DropSiteBackgroundPop, -RD_ThemeColor_DropSiteBorder, -RD_ThemeColor_DropSiteText, -RD_ThemeColor_DropSiteTextWeak, -RD_ThemeColor_DropSiteHover, -RD_ThemeColor_DropSiteFocus, -RD_ThemeColor_DropSiteCursor, -RD_ThemeColor_DropSiteSelection, -RD_ThemeColor_CodeDefault, -RD_ThemeColor_CodeSymbol, -RD_ThemeColor_CodeType, -RD_ThemeColor_CodeLocal, -RD_ThemeColor_CodeRegister, -RD_ThemeColor_CodeKeyword, -RD_ThemeColor_CodeDelimiterOperator, -RD_ThemeColor_CodeNumeric, -RD_ThemeColor_CodeNumericAltDigitGroup, -RD_ThemeColor_CodeString, -RD_ThemeColor_CodeMeta, -RD_ThemeColor_CodeComment, -RD_ThemeColor_CodeLineNumbers, -RD_ThemeColor_CodeLineNumbersSelected, -RD_ThemeColor_LineInfoBackground0, -RD_ThemeColor_LineInfoBackground1, -RD_ThemeColor_LineInfoBackground2, -RD_ThemeColor_LineInfoBackground3, -RD_ThemeColor_LineInfoBackground4, -RD_ThemeColor_LineInfoBackground5, -RD_ThemeColor_LineInfoBackground6, -RD_ThemeColor_LineInfoBackground7, -RD_ThemeColor_Thread0, -RD_ThemeColor_Thread1, -RD_ThemeColor_Thread2, -RD_ThemeColor_Thread3, -RD_ThemeColor_Thread4, -RD_ThemeColor_Thread5, -RD_ThemeColor_Thread6, -RD_ThemeColor_Thread7, -RD_ThemeColor_ThreadUnwound, -RD_ThemeColor_ThreadError, -RD_ThemeColor_Breakpoint, -RD_ThemeColor_CacheLineBoundary, -RD_ThemeColor_COUNT, -} RD_ThemeColor; +RD_CodeColorSlot_CodeDefault, +RD_CodeColorSlot_CodeSymbol, +RD_CodeColorSlot_CodeType, +RD_CodeColorSlot_CodeLocal, +RD_CodeColorSlot_CodeRegister, +RD_CodeColorSlot_CodeKeyword, +RD_CodeColorSlot_CodeDelimiterOperator, +RD_CodeColorSlot_CodeNumeric, +RD_CodeColorSlot_CodeNumericAltDigitGroup, +RD_CodeColorSlot_CodeString, +RD_CodeColorSlot_CodeMeta, +RD_CodeColorSlot_CodeComment, +RD_CodeColorSlot_CodeLineNumbers, +RD_CodeColorSlot_CodeLineNumbersSelected, +RD_CodeColorSlot_COUNT, +} RD_CodeColorSlot; typedef enum RD_ThemePreset { @@ -695,23 +564,10 @@ extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; +extern String8 rd_code_color_slot_name_table[14]; extern String8 rd_theme_preset_display_string_table[9]; extern String8 rd_theme_preset_code_string_table[9]; extern String8 rd_theme_preset_cfg_string_table[9]; -extern String8 rd_theme_color_version_remap_old_name_table[22]; -extern String8 rd_theme_color_version_remap_new_name_table[22]; -extern Vec4F32 rd_theme_preset_colors__default_dark[145]; -extern Vec4F32 rd_theme_preset_colors__default_light[145]; -extern Vec4F32 rd_theme_preset_colors__vs_dark[145]; -extern Vec4F32 rd_theme_preset_colors__vs_light[145]; -extern Vec4F32 rd_theme_preset_colors__solarized_dark[145]; -extern Vec4F32 rd_theme_preset_colors__solarized_light[145]; -extern Vec4F32 rd_theme_preset_colors__handmade_hero[145]; -extern Vec4F32 rd_theme_preset_colors__four_coder[145]; -extern Vec4F32 rd_theme_preset_colors__far_manager[145]; -extern Vec4F32* rd_theme_preset_colors_table[9]; -extern String8 rd_theme_color_display_string_table[145]; -extern String8 rd_theme_color_cfg_string_table[145]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5a973a27..cd001619 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1465,211 +1465,34 @@ RD_ThemePresetTable: { FarManager far_manager "Far Manager" } } -@table(name display_name name_lower default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager desc) -RD_ThemeColorTable: +@table(name lower_name) +RD_CodeColorTable: { - {Null "Null" null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff ""} - - //- rjf: global colors - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 0x000000ff 0xa4a4a43f 0x0000003f 0xfefefe53 0x0000003f 0x0000001c 0x0000003f 0x0000003f 0x0000003f ""} - {DropShadow "Drop Shadow" drop_shadow 0x000000ff 0x0000004c 0x0000007f 0xa3a3a37e 0x0000007f 0xc9bfa394 0x0000007f 0x0000007f 0x0000007f ""} - - //- rjf: base palette - {BaseBackground "Base Background" base_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {BaseBackgroundAlt "Base Background (Alternate)" base_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBackgroundGood "Base Background (Good)" base_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBackgroundBad "Base Background (Bad)" base_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBackgroundPop "Base Background (Pop)" base_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BaseBorder "Base Border" base_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {BaseText "Base Text" base_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BaseTextWeak "Base Text (Weak)" base_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BaseHover "Base Hover" base_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BaseFocus "Base Focus" base_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BaseCursor "Base Cursor" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BaseSelection "Base Selection" base_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: menu bar palette - {MenuBarBackground "Menu Bar Background" menu_bar_background 0x2b3740ff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {MenuBarBackgroundAlt "Menu Bar Background (Alternate)" menu_bar_background_alt 0x2b3740ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {MenuBarBackgroundGood "Menu Bar Background (Good)" menu_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {MenuBarBackgroundBad "Menu Bar Background (Bad)" menu_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {MenuBarBackgroundPop "Menu Bar Background (Pop)" menu_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {MenuBarBorder "Menu Bar Border" menu_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {MenuBarText "Menu Bar Text" menu_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {MenuBarTextWeak "Menu Bar Text (Weak)" menu_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {MenuBarHover "Menu Bar Hover" menu_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {MenuBarFocus "Menu Bar Focus" menu_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {MenuBarCursor "Menu Bar Cursor" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {MenuBarSelection "Menu Bar Selection" menu_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: good palette - {GoodBackground "Good Background" good_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {GoodBackgroundAlt "Good Background (Alternate)" good_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {GoodBackgroundGood "Good Background (Good)" good_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {GoodBackgroundBad "Good Background (Bad)" good_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {GoodBackgroundPop "Good Background (Pop)" good_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {GoodBorder "Good Border" good_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {GoodText "Good Text" good_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {GoodTextWeak "Good Text (Weak)" good_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {GoodHover "Good Hover" good_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {GoodFocus "Good Focus" good_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {GoodCursor "Good Cursor" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {GoodSelection "Good Selection" good_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: bad palette - {BadBackground "Bad Background" bad_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {BadBackgroundAlt "Bad Background (Alternate)" bad_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BadBackgroundGood "Bad Background (Good)" bad_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BadBackgroundBad "Bad Background (Bad)" bad_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BadBackgroundPop "Bad Background (Pop)" bad_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {BadBorder "Bad Border" bad_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {BadText "Bad Text" bad_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BadTextWeak "Bad Text (Weak)" bad_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BadHover "Bad Hover" bad_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BadFocus "Bad Focus" bad_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BadCursor "Bad Cursor" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {BadSelection "Bad Selection" bad_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: pop palette - {PopBackground "Pop Background" pop_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {PopBackgroundAlt "Pop Background (Alternate)" pop_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {PopBackgroundGood "Pop Background (Good)" pop_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {PopBackgroundBad "Pop Background (Bad)" pop_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {PopBackgroundPop "Pop Background (Pop)" pop_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {PopBorder "Pop Border" pop_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {PopText "Pop Text" pop_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {PopTextWeak "Pop Text (Weak)" pop_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {PopHover "Pop Hover" pop_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {PopFocus "Pop Focus" pop_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {PopCursor "Pop Cursor" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {PopSelection "Pop Selection" pop_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: scroll bar palette - {ScrollBarBackground "Scroll Bar Background" scroll_bar_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {ScrollBarBackgroundAlt "Scroll Bar Background (Alternate)" scroll_bar_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {ScrollBarBackgroundGood "Scroll Bar Background (Good)" scroll_bar_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {ScrollBarBackgroundBad "Scroll Bar Background (Bad)" scroll_bar_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {ScrollBarBackgroundPop "Scroll Bar Background (Pop)" scroll_bar_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {ScrollBarBorder "Scroll Bar Border" scroll_bar_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {ScrollBarText "Scroll Bar Text" scroll_bar_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {ScrollBarTextWeak "Scroll Bar Text (Weak)" scroll_bar_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {ScrollBarHover "Scroll Bar Hover" scroll_bar_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {ScrollBarFocus "Scroll Bar Focus" scroll_bar_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {ScrollBarCursor "Scroll Bar Cursor" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {ScrollBarSelection "Scroll Bar Selection" scroll_bar_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: tab (active) palette - {TabBackground "Tab Background" tab_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {TabBackgroundAlt "Tab Background (Alternate)" tab_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabBackgroundGood "Tab Background (Good)" tab_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabBackgroundBad "Tab Background (Bad)" tab_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabBackgroundPop "Tab Background (Pop)" tab_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabBorder "Tab Border" tab_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {TabText "Tab Text" tab_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabTextWeak "Tab Text (Weak)" tab_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabHover "Tab Hover" tab_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabFocus "Tab Focus" tab_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabCursor "Tab Cursor" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabSelection "Tab Selection" tab_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: tab (inactive) palette - {TabInactiveBackground "Tab (Inactive) Background" tab_inactive_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {TabInactiveBackgroundAlt "Tab (Inactive) Background (Alternate)" tab_inactive_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabInactiveBackgroundGood "Tab (Inactive) Background (Good)" tab_inactive_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabInactiveBackgroundBad "Tab (Inactive) Background (Bad)" tab_inactive_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabInactiveBackgroundPop "Tab (Inactive) Background (Pop)" tab_inactive_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {TabInactiveBorder "Tab (Inactive) Border" tab_inactive_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {TabInactiveText "Tab (Inactive) Text" tab_inactive_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabInactiveTextWeak "Tab (Inactive) Text (Weak)" tab_inactive_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabInactiveHover "Tab (Inactive) Hover" tab_inactive_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabInactiveFocus "Tab (Inactive) Focus" tab_inactive_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabInactiveCursor "Tab (Inactive) Cursor" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {TabInactiveSelection "Tab (Inactive) Selection" tab_inactive_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: drop site palette - {DropSiteBackground "Drop Site Background" drop_site_background 0x1b1b1bff 0xccccccfe 0x1b1b1bfe 0xfefefefe 0x002a35fe 0xfcf5e2fe 0x0c0c0cfe 0x0c0c0cfe 0x000081fe ""} - {DropSiteBackgroundAlt "Drop Site Background (Alternate)" drop_site_background_alt 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {DropSiteBackgroundGood "Drop Site Background (Good)" drop_site_background_good 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {DropSiteBackgroundBad "Drop Site Background (Bad)" drop_site_background_bad 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {DropSiteBackgroundPop "Drop Site Background (Pop)" drop_site_background_pop 0x222222ff 0x2b2b2bfe 0x1b1b1bfe 0xe7e7e7fe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe 0x2b2b2bfe ""} - {DropSiteBorder "Drop Site Border" drop_site_border 0x404040ff 0xa4a4a4fe 0x3f3f3ffe 0xb6b6b6ff 0xfefefe3a 0xbebaabfe 0x423525fe 0x3f3f3ffe 0x0000fffe ""} - {DropSiteText "Drop Site Text" drop_site_text 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {DropSiteTextWeak "Drop Site Text (Weak)" drop_site_text_weak 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {DropSiteHover "Drop Site Hover" drop_site_hover 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {DropSiteFocus "Drop Site Focus" drop_site_focus 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {DropSiteCursor "Drop Site Cursor" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {DropSiteSelection "Drop Site Selection" drop_site_cursor 0xe5e5e5ff 0x4c4c4cff 0xe5e5e5ff 0x000000ff 0x999999ff 0x333333ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - - //- rjf: code colors (extra text colors which extend 'base') - {CodeDefault "Code (Default)" code_default 0xcbcbcbff 0x4d4d4dff 0xcbcbcbff 0x000000ff 0xcbcbcbff 0x657b83ff 0xa08462ff 0x90b080ff 0x00fefeff ""} - {CodeSymbol "Code (Symbol)" code_symbol 0x42a2cfff 0x205670fe 0xdcdcaaff 0x000000ff 0xcb4a15ff 0xcb4a15ff 0xcc5634ff 0x42a2cffe 0x65b1ffff ""} - {CodeType "Code (Type)" code_type 0xfec746ff 0x996b00ff 0x4ec9afff 0xa33700ff 0xcb4a15ff 0xcb4a15ff 0xd8a51bff 0xfd7c52ff 0xfec746ff ""} - {CodeLocal "Code (Local)" code_local 0x98bc80ff 0x446a2bff 0x9cdbfeff 0x007666ff 0x98bc80ff 0x258ad2ff 0xc04047ff 0x98bc80ff 0x00ff00ff ""} - {CodeRegister "Code (Register)" code_register 0xb7afd5ff 0x4c35a1ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff 0x373345ff 0xb7afd5ff 0xb7afd5ff 0xb7afd5ff ""} - {CodeKeyword "Code (Keyword)" code_keyword 0xb38d4cff 0x573700ff 0x569cd6ff 0x0000ffff 0x849803ff 0x586e75ff 0xac7a09ff 0xd08f1eff 0x00ffffff ""} - {CodeDelimiterOperator "Code (Delimiters/Operators)" code_delimiter_operator 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0x767676ff 0xa08462ff 0x90b080ff 0xffffffff ""} - {CodeNumeric "Code (Numeric)" code_numeric 0x98abb1ff 0x3f6e7dff 0xb5cea8ff 0x088658ff 0xd33582ff 0xd33482ef 0x698e21ff 0x4fff2eff 0x00ff00ff ""} - {CodeNumericAltDigitGroup "Code (Numeric, Alt. Digit Group)" code_numeric_alt_digit_group 0x738287ff 0x1f4450ff 0x729360ff 0x0c3828ff 0x902559ff 0x8e2659ff 0x3a4e11ff 0x3ccd21ff 0x738287ff ""} - {CodeString "Code (String)" code_string 0x98abb1ff 0x3c606bff 0xd59b85ff 0xa31414ff 0x1f9d91ff 0x29a198ff 0x6a8e22ff 0x4fff2eff 0x98abb1ff ""} - {CodeMeta "Code (Meta)" code_meta 0xd96759ff 0xad3627ff 0xd59c85ff 0x0000ffff 0x839802ff 0xd96759ff 0xdab98fff 0xa0b8a0ff 0xff0000ff ""} - {CodeComment "Code (Comment)" code_comment 0x717171ff 0x4b4b4bff 0x57a54aff 0x008000ff 0x556a6fff 0x93a1a1ff 0x686868ff 0x1e8fefff 0xffffffff ""} - {CodeLineNumbers "Code Line Numbers" code_line_numbers 0x7f7f7fff 0x4b4b4bff 0x2a91afff 0x227893ff 0x566c73ff 0x227893ef 0xa08462ff 0x7e7e7ffe 0x007d7dff ""} - {CodeLineNumbersSelected "Code Line Numbers (Selected)" code_line_numbers_selected 0xbebebeff 0x000000ff 0x9ddaecff 0x123d4bfe 0xa2aaacff 0x111e22ef 0xc8b399ff 0xbebebeff 0x00fefeff ""} - - //- rjf: debugging colors (extra text/element colors which extend 'base') - {LineInfoBackground0 "Line Info Background 0" line_info_background_0 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground1 "Line Info Background 1" line_info_background_1 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground2 "Line Info Background 2" line_info_background_2 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground3 "Line Info Background 3" line_info_background_3 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {LineInfoBackground4 "Line Info Background 4" line_info_background_4 0x99503dff 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f ""} - {LineInfoBackground5 "Line Info Background 5" line_info_background_5 0xfe8249ff 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f ""} - {LineInfoBackground6 "Line Info Background 6" line_info_background_6 0xffba17ff 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f ""} - {LineInfoBackground7 "Line Info Background 7" line_info_background_7 0xcefd69ff 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f ""} - {Thread0 "Thread 0" thread_0 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0x945800ff 0xffcb7fff 0xffcb7fff 0xffcb7fff ""} - {Thread1 "Thread 1" thread_1 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0x3f5b23ff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff ""} - {Thread2 "Thread 2" thread_2 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0x642a55ff 0xff99e5ff 0xff99e5ff 0xff99e5ff ""} - {Thread3 "Thread 3" thread_3 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x30456fff 0x6598ffff 0x6598ffff 0x6598ffff ""} - {Thread4 "Thread 4" thread_4 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x264f41ff 0x65ffcbff 0x65ffcbff 0x65ffcbff ""} - {Thread5 "Thread 5" thread_5 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0x736a5fff 0xff9819ff 0xff9819ff 0xff9819ff ""} - {Thread6 "Thread 6" thread_6 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x472f5eff 0x9932ffff 0x9932ffff 0x9932ffff ""} - {Thread7 "Thread 7" thread_7 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x405d3bff 0x65ff4cff 0x65ff4cff 0x65ff4cff ""} - {ThreadUnwound "Thread (Unwound)" thread_unwound 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0x49606aff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff ""} - {ThreadError "Thread (Error)" thread_error 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23218ff 0xb23219ff 0xb23219ff 0xb23219ff ""} - {Breakpoint "Breakpoint" breakpoint 0xa72911ff 0xff2800ff 0xa72911ff 0xa72911ff 0xa72911ff 0xff684bff 0xa72911ff 0xa72911ff 0xff2800ff ""} - {CacheLineBoundary "Cache Line Boundary" cache_line_boundary 0x355b6eff 0xa6becaff 0x355b6eff 0x6e9db5ff 0x355b6eff 0xb2d3e3ff 0x15445cff 0x1b323eff 0x933100ff ""} + {CodeDefault "code_default"} + {CodeSymbol "code_symbol"} + {CodeType "code_type"} + {CodeLocal "code_local"} + {CodeRegister "code_register"} + {CodeKeyword "code_keyword"} + {CodeDelimiterOperator "code_delimiter_or_operator"} + {CodeNumeric "code_numeric"} + {CodeNumericAltDigitGroup "code_numeric_alt_digit_group"} + {CodeString "code_string"} + {CodeMeta "code_meta"} + {CodeComment "code_comment"} + {CodeLineNumbers "code_line_numbers"} + {CodeLineNumbersSelected "code_line_numbers_selected"} } -@table(old_name new_name) -RD_ThemeColorVersionRemapTable: +@enum RD_CodeColorSlot: { - {plain_text text} - {plain_background base_background} - {plain_border base_border} - {plain_overlay drop_site_overlay} - {code_function code_symbol} - {code_symbol code_delimiter_operator} - {code_numeric code_numeric_alt_digit_group} - {line_info_0 line_info_background_0} - {line_info_1 line_info_background_1} - {line_info_2 line_info_background_2} - {line_info_3 line_info_background_3} - {alt_background menu_bar_background} - {alt_border menu_bar_border} - {tab_inactive tab_background_inactive} - {tab_active tab_background} - {weak_text text_weak} - {text_selection selection} - {cursor cursor} - {highlight_0 focus} - {success_background positive_pop_button_background} - {failure_background negative_pop_button_background} - {action_background neutral_pop_button_background} + @expand(RD_CodeColorTable a) `$(a.name)`, + COUNT } -@enum RD_ThemeColor: +@data(String8) rd_code_color_slot_name_table: { - @expand(RD_ThemeColorTable a) `$(a.name)`, - COUNT, + @expand(RD_CodeColorTable a) `str8_lit_comp("$(a.lower_name)")` } @enum RD_ThemePreset: @@ -1693,40 +1516,6 @@ RD_ThemeColorVersionRemapTable: @expand(RD_ThemePresetTable a) `str8_lit_comp("$(a.cfg)")`, } -@data(String8) rd_theme_color_version_remap_old_name_table: -{ - @expand(RD_ThemeColorVersionRemapTable a) `str8_lit_comp("$(a.old_name)")` -} - -@data(String8) rd_theme_color_version_remap_new_name_table: -{ - @expand(RD_ThemeColorVersionRemapTable a) `str8_lit_comp("$(a.new_name)")` -} - -@data(Vec4F32) rd_theme_preset_colors__default_dark: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.default_dark))`} -@data(Vec4F32) rd_theme_preset_colors__default_light: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.default_light))`} -@data(Vec4F32) rd_theme_preset_colors__vs_dark: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.vs_dark))`} -@data(Vec4F32) rd_theme_preset_colors__vs_light: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.vs_light))`} -@data(Vec4F32) rd_theme_preset_colors__solarized_dark: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.solarized_dark))`,} -@data(Vec4F32) rd_theme_preset_colors__solarized_light:{@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.solarized_light))`,} -@data(Vec4F32) rd_theme_preset_colors__handmade_hero: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.handmade_hero))`,} -@data(Vec4F32) rd_theme_preset_colors__four_coder: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.four_coder))`,} -@data(Vec4F32) rd_theme_preset_colors__far_manager: {@expand(RD_ThemeColorTable a) `rgba_from_u32_lit_comp($(a.far_manager))`;} -@data(`Vec4F32*`) rd_theme_preset_colors_table: -{ - @expand(RD_ThemePresetTable a) `rd_theme_preset_colors__$(a.name_lower)`, -} - -@data(String8) rd_theme_color_display_string_table: -{ - @expand(RD_ThemeColorTable a) `str8_lit_comp("$(a.display_name)")` -} - -@data(String8) rd_theme_color_cfg_string_table: -{ - @expand(RD_ThemeColorTable a) `str8_lit_comp("$(a.name_lower)")` -} - //////////////////////////////// //~ rjf: Help/Docs/README diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fb5987b9..45eb995b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6062,6 +6062,14 @@ rd_window_frame(void) ui_push_text_raster_flags(text_raster_flags); } + //////////////////////////// + //- rjf: @window_ui_part calculate code color slot RGBAs + // + for EachEnumVal(RD_CodeColorSlot, s) + { + ws->theme_code_colors[s] = ui_color_from_name(rd_code_color_slot_name_table[s]); + } + //////////////////////////// //- rjf: @window_ui_part calculate top-level rectangles/sizes // @@ -9685,32 +9693,34 @@ rd_set_autocomp_regs_(RD_Regs *regs) //- rjf: colors internal Vec4F32 -rd_rgba_from_theme_color(RD_ThemeColor color) +rd_rgba_from_code_color_slot(RD_CodeColorSlot slot) { - return rd_state->theme->colors[color]; + RD_WindowState *ws = rd_window_state_from_cfg(rd_cfg_from_id(rd_regs()->window)); + Vec4F32 result = ws->theme_code_colors[slot]; + return result; } -internal RD_ThemeColor -rd_theme_color_from_txt_token_kind(TXT_TokenKind kind) +internal RD_CodeColorSlot +rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind) { - RD_ThemeColor color = RD_ThemeColor_CodeDefault; + RD_CodeColorSlot color = RD_CodeColorSlot_CodeDefault; switch(kind) { default:break; - case TXT_TokenKind_Keyword:{color = RD_ThemeColor_CodeKeyword;}break; - case TXT_TokenKind_Numeric:{color = RD_ThemeColor_CodeNumeric;}break; - case TXT_TokenKind_String: {color = RD_ThemeColor_CodeString;}break; - case TXT_TokenKind_Meta: {color = RD_ThemeColor_CodeMeta;}break; - case TXT_TokenKind_Comment:{color = RD_ThemeColor_CodeComment;}break; - case TXT_TokenKind_Symbol: {color = RD_ThemeColor_CodeDelimiterOperator;}break; + case TXT_TokenKind_Keyword:{color = RD_CodeColorSlot_CodeKeyword;}break; + case TXT_TokenKind_Numeric:{color = RD_CodeColorSlot_CodeNumeric;}break; + case TXT_TokenKind_String: {color = RD_CodeColorSlot_CodeString;}break; + case TXT_TokenKind_Meta: {color = RD_CodeColorSlot_CodeMeta;}break; + case TXT_TokenKind_Comment:{color = RD_CodeColorSlot_CodeComment;}break; + case TXT_TokenKind_Symbol: {color = RD_CodeColorSlot_CodeDelimiterOperator;}break; } return color; } -internal RD_ThemeColor -rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string) +internal RD_CodeColorSlot +rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string) { - RD_ThemeColor color = RD_ThemeColor_CodeDefault; + RD_CodeColorSlot color = RD_CodeColorSlot_CodeDefault; if(kind == TXT_TokenKind_Identifier || kind == TXT_TokenKind_Keyword) { CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); @@ -9724,7 +9734,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str if(local_num != 0) { mapped = 1; - color = RD_ThemeColor_CodeLocal; + color = RD_CodeColorSlot_CodeLocal; } } @@ -9735,7 +9745,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str if(member_num != 0) { mapped = 1; - color = RD_ThemeColor_CodeLocal; + color = RD_CodeColorSlot_CodeLocal; } } @@ -9746,7 +9756,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str if(reg_num != 0) { mapped = 1; - color = RD_ThemeColor_CodeRegister; + color = RD_CodeColorSlot_CodeRegister; } } @@ -9757,7 +9767,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str if(alias_num != 0) { mapped = 1; - color = RD_ThemeColor_CodeRegister; + color = RD_CodeColorSlot_CodeRegister; } } @@ -9773,11 +9783,11 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str case RDI_SectionKind_GlobalVariables: case RDI_SectionKind_ThreadVariables: { - color = RD_ThemeColor_CodeSymbol; + color = RD_CodeColorSlot_CodeSymbol; }break; case RDI_SectionKind_TypeNodes: { - color = RD_ThemeColor_CodeType; + color = RD_CodeColorSlot_CodeType; }break; } } @@ -11000,123 +11010,6 @@ rd_frame(void) rd_state->font_slot_table[RD_FontSlot_Icons] = fnt_tag_from_static_data_string(&rd_icon_font_bytes); } - ////////////////////////////// - //- rjf: build theme from config - // - ProfScope("build theme from config") - { - RD_Theme *theme_srgba = push_array(scratch.arena, RD_Theme, 1); - - //- rjf: gather globally-applying config options - RD_CfgList preset_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("theme_preset")); - RD_CfgList colors_roots = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("theme_colors")); - - //- rjf: assume default-dark - MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[RD_ThemePreset_DefaultDark], sizeof(rd_theme_preset_colors__default_dark)); - - //- rjf: apply explicitly-specified presets - for(RD_CfgNode *n = preset_roots.first; n != 0; n = n->next) - { - RD_Cfg *preset = n->v; - String8 preset_name = preset->first->string; - RD_ThemePreset preset_kind = (RD_ThemePreset)0; - B32 found_preset_kind = 0; - for(RD_ThemePreset p = (RD_ThemePreset)0; p < RD_ThemePreset_COUNT; p = (RD_ThemePreset)(p+1)) - { - if(str8_match(preset_name, rd_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) - { - found_preset_kind = 1; - preset_kind = p; - break; - } - } - if(found_preset_kind) - { - MemoryCopy(theme_srgba->colors, rd_theme_preset_colors_table[preset_kind], sizeof(rd_theme_preset_colors__default_dark)); - } - } - - //- rjf: apply explicitly-specified color codes - for(RD_CfgNode *n = colors_roots.first; n != 0; n = n->next) - { - RD_Cfg *colors = n->v; - for(RD_Cfg *color = colors->first; color != &rd_nil_cfg; color = color->next) - { - String8 name = color->string; - RD_ThemeColor color_code = RD_ThemeColor_Null; - for(RD_ThemeColor c = RD_ThemeColor_Null; c < RD_ThemeColor_COUNT; c = (RD_ThemeColor)(c+1)) - { - if(str8_match(rd_theme_color_cfg_string_table[c], name, StringMatchFlag_CaseInsensitive)) - { - color_code = c; - break; - } - } - if(color_code != RD_ThemeColor_Null) - { - U64 color_val = 0; - if(try_u64_from_str8_c_rules(color->first->string, &color_val)) - { - Vec4F32 color_rgba = rgba_from_u32((U32)color_val); - theme_srgba->colors[color_code] = color_rgba; - } - } - } - } - - //- rjf: srgba -> linear, compute final theme - rd_state->theme_target = push_array(rd_frame_arena(), RD_Theme, 1); - RD_Theme *theme = rd_state->theme_target; - for EachEnumVal(RD_ThemeColor, c) - { - theme->colors[c] = linear_from_srgba(theme_srgba->colors[c]); - } - } - - ////////////////////////////// - //- rjf: animate theme - // - { - Temp scratch = scratch_begin(0, 0); - RD_Theme *last = push_array(scratch.arena, RD_Theme, 1); - if(rd_state->theme != 0) - { - MemoryCopyStruct(last, rd_state->theme); - } - rd_state->theme = push_array(rd_frame_arena(), RD_Theme, 1); - RD_Theme *current = rd_state->theme; - RD_Theme *target = rd_state->theme_target; - if(last) - { - MemoryCopyStruct(current, last); - } - if(rd_state->frame_index <= 2) - { - MemoryCopyStruct(current, target); - } - else - { - F32 rate = 1 - pow_f32(2, (-50.f * rd_state->frame_dt)); - for(RD_ThemeColor color = RD_ThemeColor_Null; - color < RD_ThemeColor_COUNT; - color = (RD_ThemeColor)(color+1)) - { - if(abs_f32(target->colors[color].x - current->colors[color].x) > 0.01f || - abs_f32(target->colors[color].y - current->colors[color].y) > 0.01f || - abs_f32(target->colors[color].z - current->colors[color].z) > 0.01f || - abs_f32(target->colors[color].w - current->colors[color].w) > 0.01f) - { - rd_request_frame(); - } - current->colors[color].x += (target->colors[color].x - current->colors[color].x) * rate; - current->colors[color].y += (target->colors[color].y - current->colors[color].y) * rate; - current->colors[color].z += (target->colors[color].z - current->colors[color].z) * rate; - current->colors[color].w += (target->colors[color].w - current->colors[color].w) * rate; - } - } - scratch_end(scratch); - } - ////////////////////////////// //- rjf: consume events // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 307b1690..40036bba 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -409,12 +409,6 @@ struct RD_RegsNode //////////////////////////////// //~ rjf: Structured Theme Types, Parsed From Config -typedef struct RD_Theme RD_Theme; -struct RD_Theme -{ - Vec4F32 colors[RD_ThemeColor_COUNT]; -}; - typedef enum RD_FontSlot { RD_FontSlot_Main, @@ -450,7 +444,8 @@ struct RD_WindowState Rng2F32 last_window_rect; // rjf: theme (recomputed each frame) - UI_Theme *theme; + UI_Theme *theme; + Vec4F32 theme_code_colors[RD_CodeColorSlot_COUNT]; // rjf: font raster flags (recomputed each frame) FNT_RasterFlags font_slot_raster_flags[RD_FontSlot_COUNT]; @@ -603,10 +598,6 @@ struct RD_State // rjf: slot -> font tag map (constructed from-scratch each frame) FNT_Tag font_slot_table[RD_FontSlot_COUNT]; - // rjf: theme target (constructed from-scratch each frame) - RD_Theme *theme; - RD_Theme *theme_target; - // rjf: meta name -> eval type key map (constructed from-scratch each frame) E_String2TypeKeyMap *meta_name2type_map; @@ -969,10 +960,10 @@ internal void rd_set_autocomp_regs_(RD_Regs *regs); //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: colors -internal Vec4F32 rd_rgba_from_theme_color(RD_ThemeColor color); -internal RD_ThemeColor rd_theme_color_from_txt_token_kind(TXT_TokenKind kind); -internal RD_ThemeColor rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); +//- rjf: colors +internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot); +internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind); +internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); //- rjf: fonts internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 7a2361d0..b54eab0a 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2467,7 +2467,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { params->font, ui_top_text_raster_flags(), - rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault), + rd_rgba_from_code_color_slot(RD_CodeColorSlot_CodeDefault), params->font_size, }; dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, line_string); @@ -2494,12 +2494,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe } // rjf: token -> token color - RD_ThemeColor token_theme_color = rd_theme_color_from_txt_token_kind(token->kind); - RD_ThemeColor lookup_theme_color = rd_theme_color_from_txt_token_kind_lookup_string(token->kind, token_string); - Vec4F32 token_color = rd_rgba_from_theme_color(token_theme_color); - if(lookup_theme_color != RD_ThemeColor_CodeDefault) + RD_CodeColorSlot token_color_slot = rd_code_color_slot_from_txt_token_kind(token->kind); + RD_CodeColorSlot lookup_color_slot = rd_code_color_slot_from_txt_token_kind_lookup_string(token->kind, token_string); + Vec4F32 token_color = rd_rgba_from_code_color_slot(token_color_slot); + if(lookup_color_slot != RD_CodeColorSlot_CodeDefault) { - Vec4F32 lookup_color = rd_rgba_from_theme_color(lookup_theme_color); + Vec4F32 lookup_color = rd_rgba_from_code_color_slot(lookup_color_slot); F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); token_color = mix_4f32(token_color, lookup_color, lookup_color_mix_t); } @@ -2921,7 +2921,7 @@ rd_fstrs_from_rich_string(Arena *arena, String8 string) { fstr.params.font = rd_font_from_slot(RD_FontSlot_Code); fstr.params.raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Code); - fstr.params.color = rd_rgba_from_theme_color(RD_ThemeColor_CodeDefault); + fstr.params.color = rd_rgba_from_code_color_slot(RD_CodeColorSlot_CodeDefault); } } dr_fstrs_push(arena, &fstrs, &fstr); @@ -2996,8 +2996,8 @@ rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, indirection_size_change = 0; for(TXT_Token *token = tokens.v; token < tokens_opl; token += 1) { - RD_ThemeColor token_color = rd_theme_color_from_txt_token_kind(token->kind); - Vec4F32 token_color_rgba = rd_rgba_from_theme_color(token_color); + RD_CodeColorSlot token_color_slot = rd_code_color_slot_from_txt_token_kind(token->kind); + Vec4F32 token_color_rgba = rd_rgba_from_code_color_slot(token_color_slot); token_color_rgba.w *= alpha; String8 token_string = str8_substr(string, token->range); if(str8_match(token_string, str8_lit("{"), 0)) { indirection_counter += 1; } @@ -3022,10 +3022,10 @@ rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, case TXT_TokenKind_Identifier: case TXT_TokenKind_Keyword: { - RD_ThemeColor lookup_theme_color = rd_theme_color_from_txt_token_kind_lookup_string(token->kind, token_string); - if(lookup_theme_color != RD_ThemeColor_CodeDefault) + RD_CodeColorSlot lookup_theme_color_slot = rd_code_color_slot_from_txt_token_kind_lookup_string(token->kind, token_string); + if(lookup_theme_color_slot != RD_CodeColorSlot_CodeDefault) { - Vec4F32 lookup_color = rd_rgba_from_theme_color(lookup_theme_color); + Vec4F32 lookup_color = rd_rgba_from_code_color_slot(lookup_theme_color_slot); F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); token_color_rgba = mix_4f32(token_color_rgba, lookup_color, lookup_color_mix_t); } @@ -3043,7 +3043,7 @@ rd_fstrs_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, }break; case TXT_TokenKind_Numeric: { - Vec4F32 token_color_rgba_alt = rd_rgba_from_theme_color(RD_ThemeColor_CodeNumericAltDigitGroup); + Vec4F32 token_color_rgba_alt = rd_rgba_from_code_color_slot(RD_CodeColorSlot_CodeNumericAltDigitGroup); token_color_rgba_alt.w *= alpha; F32 font_size = ui_top_font_size() * (1.f - !!indirection_size_change*(indirection_counter/10.f)); From dddc79e852f1eda1c9d1c2aeaa0a4cf457c4f896 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 13:17:17 -0700 Subject: [PATCH 545/755] adjust tags in accordance with theme design pass --- src/raddbg/generated/raddbg.meta.c | 4 ++-- src/raddbg/raddbg.mdesk | 4 ++-- src/raddbg/raddbg_core.c | 4 ++-- src/raddbg/raddbg_views.c | 1 - src/raddbg/raddbg_widgets.c | 2 +- src/ui/ui_basic_widgets.c | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index f9746876..dd65bc17 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -401,7 +401,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand @display_name('User Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @no_expand @display_name('User Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -966,7 +966,7 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[9] = { -str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccffff }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index cd001619..f3dc5028 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -382,7 +382,7 @@ RD_VocabTable: theme_color, ``` @collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme) - @row_commands(remove_cfg) + @row_commands(duplicate_cfg, remove_cfg) x: { @display_name('Tags') tags: string, @@ -1379,7 +1379,7 @@ RD_ThemePresetTable: theme_color: {tags:"hover", value: 0xffffffff } theme_color: {tags:"focus", value: 0xfda200ff } theme_color: {tags:"cursor", value: 0x8aff00ff } - theme_color: {tags:"selection", value: 0x99ccffff } + theme_color: {tags:"selection", value: 0x99ccff0f } theme_color: {tags:"inactive background", value: 0x0000002f } theme_color: {tags:"drop_shadow", value: 0x0000007f } theme_color: {tags:"good_pop background", value: 0x2c5b36ff } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 45eb995b..e3d234fa 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8589,7 +8589,7 @@ rd_window_frame(void) U64 tab_task_count = 0; F32 tab_close_width_px = ui_top_font_size()*2.5f; F32 max_tab_width_px = ui_top_font_size()*20.f; - if(build_panel) + if(build_panel) UI_TagF("tab") { B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next) @@ -8748,7 +8748,7 @@ rd_window_frame(void) UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center) RD_Font(RD_FontSlot_Icons) UI_FontSize(ui_top_font_size()*0.75f) - UI_TagF(".") UI_TagF("weak") UI_TagF("implicit") + UI_TagF(".") UI_TagF("tab") UI_TagF("weak") UI_TagF("implicit") UI_CornerRadius00(0) UI_CornerRadius01(0) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f9e864f3..b2b35fdf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3147,7 +3147,6 @@ RD_VIEW_UI_FUNCTION_DEF(memory) { cell_flags |= UI_BoxFlag_DrawBackground; cell_bg_rgba = selection_color; - cell_bg_rgba.w *= 0.2f; } if(selection.min%num_columns == col_idx) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index b54eab0a..1321eecf 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -2404,6 +2404,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe TxtRngColorPairNode *n = push_array(scratch.arena, TxtRngColorPairNode, 1); n->rng = result.mouse_expr_rng; n->color = ui_color_from_name(str8_lit("background")); + n->color.w *= 0.2f; SLLQueuePush(first_txt_rng_color_pair, last_txt_rng_color_pair, n); } } @@ -2591,7 +2592,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ceil_f32(line_box->rect.y1) + 1.f, }; Vec4F32 color = n->color; - color.w = ClampTop(color.w, 0.1f); if(!is_focused) { color.w *= 0.5f; diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index 4f440de1..de24ce72 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -136,7 +136,7 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) Vec4F32 cursor_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("cursor")); cursor_color.w *= box->parent->parent->focus_active_t; Vec4F32 select_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("selection")); - select_color.w *= 0.1f*(box->parent->parent->focus_active_t*0.2f + 0.8f); + select_color.w *= (box->parent->parent->focus_active_t*0.2f + 0.8f); Vec2F32 text_position = ui_box_text_position(box); String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; From d98335ef7627e446fddcd9038b7f9a12ce2172bf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 13:24:01 -0700 Subject: [PATCH 546/755] per-window theme-usage setting - by default, prioritize project theme settings, but allow using only user themes per-window as well. --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 ++++ src/raddbg/raddbg_core.c | 16 +++++++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index dd65bc17..c8ad4b9d 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -402,7 +402,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand @display_name('User Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @no_expand @display_name('User Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, -{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n}\n")}, +{str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f3dc5028..9748ef1f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -414,6 +414,10 @@ RD_VocabTable: 'row_height': @range[1.75f, 5.f] f32, @default(3.f) @description("Controls the height of tabs, in multiples of the font size.") 'tab_height': @range[1.75f, 5.f] f32, + + //- rjf: theme settings + @default(1) @display_name('Use Project Theme') @description("Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.") + 'use_project_theme': bool, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e3d234fa..c49e656d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5757,10 +5757,20 @@ rd_window_frame(void) // that windows can have their own colors, and have those override higher-up settings. RD_Cfg *preset_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; - RD_Cfg *scan_parents[] = {window, rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user"))}; - for EachElement(idx, scan_parents) + RD_Cfg *theme_parents[] = { - RD_Cfg *parent_cfg = scan_parents[idx]; + rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), + rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")) + }; + U64 theme_parents_count = ArrayCount(theme_parents); + if(!rd_setting_b32_from_name(str8_lit("use_project_theme"))) + { + theme_parents[0] = theme_parents[1]; + theme_parents_count -= 1; + } + for EachIndex(idx, theme_parents_count) + { + RD_Cfg *parent_cfg = theme_parents[idx]; if(preset_cfg != &rd_nil_cfg) { RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); From 644ba8d02eadddbf1f6526031806cd901eb68ae4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 15:28:56 -0700 Subject: [PATCH 547/755] theme presets work --- src/base/base_strings.c | 13 ++ src/base/base_strings.h | 1 + src/raddbg/generated/raddbg.meta.c | 15 +- src/raddbg/generated/raddbg.meta.h | 7 +- src/raddbg/raddbg.mdesk | 270 ++++++++++++++++++++++++++++- src/raddbg/raddbg_core.c | 47 ++++- src/raddbg/raddbg_views.c | 2 +- src/ui/ui_core.c | 27 ++- src/ui/ui_core.h | 1 + 9 files changed, 356 insertions(+), 27 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 47b94f74..d3823676 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1174,6 +1174,19 @@ str8_array_reserve(Arena *arena, U64 count) return arr; } +internal String8Array +str8_array_copy(Arena *arena, String8Array array) +{ + String8Array result = {0}; + result.count = array.count; + result.v = push_array(arena, String8, result.count); + for EachIndex(idx, result.count) + { + result.v[idx] = push_str8_copy(arena, array.v[idx]); + } + return result; +} + //////////////////////////////// //~ rjf: String Path Helpers diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 9e5878f0..d5ccaad1 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -291,6 +291,7 @@ internal void str8_list_from_flags(Arena *arena, String8List *list, U32 internal String8Array str8_array_zero(void); internal String8Array str8_array_from_list(Arena *arena, String8List *list); internal String8Array str8_array_reserve(Arena *arena, U64 count); +internal String8Array str8_array_copy(Arena *arena, String8Array array); //////////////////////////////// //~ rjf: String Path Helpers diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index c8ad4b9d..a80d3443 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -938,7 +938,7 @@ str8_lit_comp("code_line_numbers"), str8_lit_comp("code_line_numbers_selected"), }; -String8 rd_theme_preset_display_string_table[9] = +String8 rd_theme_preset_display_string_table[10] = { str8_lit_comp("Default (Dark)"), str8_lit_comp("Default (Light)"), @@ -948,10 +948,11 @@ str8_lit_comp("Solarized (Dark)"), str8_lit_comp("Solarized (Light)"), str8_lit_comp("Handmade Hero"), str8_lit_comp("4coder"), +str8_lit_comp("Grove"), str8_lit_comp("Far Manager"), }; -String8 rd_theme_preset_code_string_table[9] = +String8 rd_theme_preset_code_string_table[10] = { str8_lit_comp("default_dark"), str8_lit_comp("default_light"), @@ -961,19 +962,21 @@ str8_lit_comp("solarized_dark"), str8_lit_comp("solarized_light"), str8_lit_comp("handmade_hero"), str8_lit_comp("four_coder"), +str8_lit_comp("grove"), str8_lit_comp("far_manager"), }; -String8 rd_theme_preset_cfg_string_table[9] = +String8 rd_theme_preset_cfg_string_table[10] = { -str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), -str8_lit_comp(""), -str8_lit_comp("theme:\n{\n background: 0x1b0000ff,\n}\n"), +str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus overlay\", value: 0xfda20012 }\n theme_color: {tags:\"focus border\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0xffffffff }\n theme_color:{ tags: \"alt background\" value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" value: 0xeaddceff }\n theme_color:{ tags: \"match background\" value: 0xc1e9c4ff }\n theme_color:{ tags: border value: 0xcbcbcbff }\n theme_color:{ tags: text value: 0xff }\n theme_color:{ tags: \"weak text\" value: 0x727272ff }\n theme_color:{ tags: \"good text\" value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" value: 0x972717ff }\n theme_color:{ tags: hover value: 0xff }\n theme_color:{ tags: \"focus overlay\" value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" value: 0x67ffff }\n theme_color:{ tags: cursor value: 0xff }\n theme_color:{ tags: selection value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" value: 0x8 }\n theme_color:{ tags: drop_shadow value: 0xb }\n theme_color:{ tags: \"good_pop background\" value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0x80808ff }\n theme_color:{ tags: code_symbol value: 0x4ac3ff }\n theme_color:{ tags: code_type value: 0xf46200ff }\n theme_color:{ tags: code_local value: 0x317c00ff }\n theme_color:{ tags: code_register value: 0x9a00ffff }\n theme_color:{ tags: code_keyword value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0xb56aff }\n theme_color:{ tags: code_string value: 0x63549fff }\n theme_color:{ tags: code_meta value: 0xd96759ff }\n theme_color:{ tags: code_comment value: 0x717171ff }\n theme_color:{ tags: line_info_0 value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 value: 0xba917eff }\n theme_color:{ tags: thread_0 value: 0xffa700ff }\n theme_color:{ tags: thread_1 value: 0xb41fff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" value: 0xffffffff }\n theme_color:{ tags: \"tab background\" value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" value: 0x222222ff }\n theme_color:{ tags: \"pop background\" value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" value: 0x31393dff }\n theme_color:{ tags: \"match background\" value: 0x31393dff }\n theme_color:{ tags: border value: 0x404040ff }\n theme_color:{ tags: text value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" value: 0xcf5242ff }\n theme_color:{ tags: hover value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" value: 0x7160e8ff }\n theme_color:{ tags: cursor value: 0x8aff00ff }\n theme_color:{ tags: selection value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" value: 0x0000002f }\n theme_color:{ tags: drop_shadow value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol value: 0xdcdcaaff }\n theme_color:{ tags: code_type value: 0x4ec9b0ff }\n theme_color:{ tags: code_local value: 0x9cdcfeff }\n theme_color:{ tags: code_register value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x767676ff }\n theme_color:{ tags: code_numeric value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0x7c986dff }\n theme_color:{ tags: code_string value: 0xd69d85ff }\n theme_color:{ tags: code_meta value: 0x9b9b9bff }\n theme_color:{ tags: code_comment value: 0x51a644ff }\n theme_color:{ tags: line_info_0 value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 value: 0x434e2aff }\n theme_color:{ tags: line_info_3 value: 0x36241fff }\n theme_color:{ tags: line_info_4 value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 value: 0x434e2aff }\n theme_color:{ tags: line_info_7 value: 0x36241fff }\n theme_color:{ tags: thread_0 value: 0xffdc48ff }\n theme_color:{ tags: thread_1 value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" value: 0x333333ff }\n theme_color:{ tags: \"tab border\" value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" value: 0x232929ff }\n theme_color:{ tags: \"pop background\" value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" value: 0x31393dff }\n theme_color:{ tags: \"match background\" value: 0x31393dff }\n theme_color:{ tags: border value: 0x485347ff }\n theme_color:{ tags: text value: 0xffffffff }\n theme_color:{ tags: \"weak text\" value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" value: 0xcf5242ff }\n theme_color:{ tags: hover value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" value: 0xfda200ff }\n theme_color:{ tags: cursor value: 0x8aff00ff }\n theme_color:{ tags: selection value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" value: 0x0 }\n theme_color:{ tags: drop_shadow value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0xad8b69ff }\n theme_color:{ tags: code_symbol value: 0x87ad6aff }\n theme_color:{ tags: code_type value: 0xb67474ff }\n theme_color:{ tags: code_local value: 0xe9bf95ff }\n theme_color:{ tags: code_register value: 0xa688b2ff }\n theme_color:{ tags: code_keyword value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x795e43ff }\n theme_color:{ tags: code_numeric value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0x688b71ff }\n theme_color:{ tags: code_string value: 0x98b19eff }\n theme_color:{ tags: code_meta value: 0xad5979ff }\n theme_color:{ tags: code_comment value: 0x52675dff }\n theme_color:{ tags: line_info_0 value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 value: 0x434e2aff }\n theme_color:{ tags: line_info_3 value: 0x36241fff }\n theme_color:{ tags: line_info_4 value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 value: 0x434e2aff }\n theme_color:{ tags: line_info_7 value: 0x36241fff }\n theme_color:{ tags: thread_0 value: 0xffc258ff }\n theme_color:{ tags: thread_1 value: 0x82d331ff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), str8_lit_comp(""), }; diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index b6a08655..d966c718 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -395,6 +395,7 @@ RD_ThemePreset_SolarizedDark, RD_ThemePreset_SolarizedLight, RD_ThemePreset_HandmadeHero, RD_ThemePreset_FourCoder, +RD_ThemePreset_Grove, RD_ThemePreset_FarManager, RD_ThemePreset_COUNT, } RD_ThemePreset; @@ -565,9 +566,9 @@ extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; extern String8 rd_code_color_slot_name_table[14]; -extern String8 rd_theme_preset_display_string_table[9]; -extern String8 rd_theme_preset_code_string_table[9]; -extern String8 rd_theme_preset_cfg_string_table[9]; +extern String8 rd_theme_preset_display_string_table[10]; +extern String8 rd_theme_preset_code_string_table[10]; +extern String8 rd_theme_preset_cfg_string_table[10]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9748ef1f..9d896b22 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1381,7 +1381,8 @@ RD_ThemePresetTable: theme_color: {tags:"neutral text", value: 0x3a90bbff } theme_color: {tags:"bad text", value: 0xcf5242ff } theme_color: {tags:"hover", value: 0xffffffff } - theme_color: {tags:"focus", value: 0xfda200ff } + theme_color: {tags:"focus overlay", value: 0xfda20012 } + theme_color: {tags:"focus border", value: 0xfda200ff } theme_color: {tags:"cursor", value: 0x8aff00ff } theme_color: {tags:"selection", value: 0x99ccff0f } theme_color: {tags:"inactive background", value: 0x0000002f } @@ -1451,21 +1452,284 @@ RD_ThemePresetTable: ``` } - { DefaultLight default_light "Default (Light)" } + //- rjf: default light theme + { DefaultLight default_light "Default (Light)", + ```theme: + { + theme_color:{ tags: background value: 0xffffffff } + theme_color:{ tags: "alt background" value: 0xf8f8f8ff } + theme_color:{ tags: "pop background" value: 0xcbe4f2ff } + theme_color:{ tags: "menu_bar pop background" value: 0x5aabd9ff } + theme_color:{ tags: "fresh background" value: 0xeaddceff } + theme_color:{ tags: "match background" value: 0xc1e9c4ff } + theme_color:{ tags: border value: 0xcbcbcbff } + theme_color:{ tags: text value: 0xff } + theme_color:{ tags: "weak text" value: 0x727272ff } + theme_color:{ tags: "good text" value: 0x217538ff } + theme_color:{ tags: "neutral text" value: 0x1a5b7cff } + theme_color:{ tags: "bad text" value: 0x972717ff } + theme_color:{ tags: hover value: 0xff } + theme_color:{ tags: "focus overlay" value: 0x67ff4b } + theme_color:{ tags: "focus border" value: 0x67ffff } + theme_color:{ tags: cursor value: 0xff } + theme_color:{ tags: selection value: 0x283d5166 } + theme_color:{ tags: "inactive background" value: 0x8 } + theme_color:{ tags: drop_shadow value: 0xb } + theme_color:{ tags: "good_pop background" value: 0x90c09aff } + theme_color:{ tags: "good_pop border" value: 0x1e7231ff } + theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop text" value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" value: 0xa93620ff } + theme_color:{ tags: "bad_pop text" value: 0xffffffff } + theme_color:{ tags: "bad_pop text weak" value: 0xffffffff } + theme_color:{ tags: "menu_bar bad_pop background" value: 0xff2a00ff } + theme_color:{ tags: "menu_bar bad_pop text" value: 0xffffffff } + theme_color:{ tags: "bad_pop hover" value: 0xff825cff } + theme_color:{ tags: code_default value: 0x80808ff } + theme_color:{ tags: code_symbol value: 0x4ac3ff } + theme_color:{ tags: code_type value: 0xf46200ff } + theme_color:{ tags: code_local value: 0x317c00ff } + theme_color:{ tags: code_register value: 0x9a00ffff } + theme_color:{ tags: code_keyword value: 0xff0600ff } + theme_color:{ tags: code_delimiter_or_operator value: 0x8a8a8aff } + theme_color:{ tags: code_numeric value: 0x7d49ff } + theme_color:{ tags: code_numeric_alt_digit_group value: 0xb56aff } + theme_color:{ tags: code_string value: 0x63549fff } + theme_color:{ tags: code_meta value: 0xd96759ff } + theme_color:{ tags: code_comment value: 0x717171ff } + theme_color:{ tags: line_info_0 value: 0xe6d5cdff } + theme_color:{ tags: line_info_1 value: 0xdbcfb2ff } + theme_color:{ tags: line_info_2 value: 0xddeac1ff } + theme_color:{ tags: line_info_3 value: 0xddc4bdff } + theme_color:{ tags: line_info_4 value: 0xba917eff } + theme_color:{ tags: thread_0 value: 0xffa700ff } + theme_color:{ tags: thread_1 value: 0xb41fff } + theme_color:{ tags: thread_2 value: 0xff99e5ff } + theme_color:{ tags: thread_3 value: 0x6598ffff } + theme_color:{ tags: thread_4 value: 0x65ffcbff } + theme_color:{ tags: thread_5 value: 0xff9819ff } + theme_color:{ tags: thread_6 value: 0x9932ffff } + theme_color:{ tags: thread_7 value: 0x65ff4cff } + theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } + theme_color:{ tags: thread_error value: 0xb23219ff } + theme_color:{ tags: breakpoint value: 0xff2800ff } + theme_color:{ tags: "floating background" value: 0xffffffc7 } + theme_color:{ tags: "floating background alt" value: 0x23 } + theme_color:{ tags: "floating background fresh" value: 0xeaddceff } + theme_color:{ tags: "floating border" value: 0x88888884 } + theme_color:{ tags: "scroll_bar background" value: 0xe9e9e9ff } + theme_color:{ tags: "scroll_bar border" value: 0x5f5f5f5f } + theme_color:{ tags: "floating scroll_bar background" value: 0xe9e9e9ff } + theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } + theme_color:{ tags: "menu_bar background" value: 0x2b6b9aff } + theme_color:{ tags: "menu_bar border" value: 0x4d } + theme_color:{ tags: "menu_bar text" value: 0xffffffff } + theme_color:{ tags: "menu_bar text weak" value: 0xffffffff } + theme_color:{ tags: "good menu_bar text" value: 0x70db8dff } + theme_color:{ tags: "bad menu_bar text" value: 0xffa79bff } + theme_color:{ tags: "neutral menu_bar text" value: 0xc4dbe7ff } + theme_color:{ tags: "implicit background" value: 0x00000000 } + theme_color:{ tags: "implicit border" value: 0x00000000 } + theme_color:{ tags: "hollow background" value: 0x00000000 } + theme_color:{ tags: "hollow border" value: 0xffffff1f } + theme_color:{ tags: "tab text" value: 0xffffffff } + theme_color:{ tags: "tab text weak" value: 0xffffffff } + theme_color:{ tags: "tab background" value: 0xb67e48ff } + theme_color:{ tags: "tab border" value: 0x875b31ff } + theme_color:{ tags: "tab inactive background" value: 0xcacacaff } + theme_color:{ tags: "tab inactive border" value: 0xb5b5b5ff } + theme_color:{ tags: "tab auto background" value: 0xc41c69ff } + theme_color:{ tags: "tab auto border" value: 0x981039ff } + theme_color:{ tags: "tab auto inactive background" value: 0x9b88a3ff } + theme_color:{ tags: "tab auto inactive border" value: 0x373737ff } + theme_color:{ tags: "drop_site background" value: 0xffffff05 } + theme_color:{ tags: "drop_site border" value: 0xffffff0f } + } + ``` + } + //- rjf: vs dark theme { VSDark vs_dark "VS (Dark)", ```theme: { - background: 0x1b0000ff, + theme_color:{ tags: background value: 0x1f1f1fff } + theme_color:{ tags: "alt background" value: 0x222222ff } + theme_color:{ tags: "pop background" value: 0x383167ff } + theme_color:{ tags: "fresh background" value: 0x31393dff } + theme_color:{ tags: "match background" value: 0x31393dff } + theme_color:{ tags: border value: 0x404040ff } + theme_color:{ tags: text value: 0xe5e5e5ff } + theme_color:{ tags: "weak text" value: 0xa4a4a4ff } + theme_color:{ tags: "good text" value: 0x32a852ff } + theme_color:{ tags: "neutral text" value: 0x3a90bbff } + theme_color:{ tags: "bad text" value: 0xcf5242ff } + theme_color:{ tags: hover value: 0xffffffff } + theme_color:{ tags: "focus overlay" value: 0x7160e81e } + theme_color:{ tags: "focus border" value: 0x7160e8ff } + theme_color:{ tags: cursor value: 0x8aff00ff } + theme_color:{ tags: selection value: 0x99ccff0f } + theme_color:{ tags: "inactive background" value: 0x0000002f } + theme_color:{ tags: drop_shadow value: 0x0000007f } + theme_color:{ tags: "good_pop background" value: 0x2c5b36ff } + theme_color:{ tags: "good_pop border" value: 0x568761ff } + theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" value: 0x803425ff } + theme_color:{ tags: "bad_pop hover" value: 0xff825cff } + theme_color:{ tags: code_default value: 0xe0e0e0ff } + theme_color:{ tags: code_symbol value: 0xdcdcaaff } + theme_color:{ tags: code_type value: 0x4ec9b0ff } + theme_color:{ tags: code_local value: 0x9cdcfeff } + theme_color:{ tags: code_register value: 0xb7afd5ff } + theme_color:{ tags: code_keyword value: 0x569cd6ff } + theme_color:{ tags: code_delimiter_or_operator value: 0x767676ff } + theme_color:{ tags: code_numeric value: 0xb5cea8ff } + theme_color:{ tags: code_numeric_alt_digit_group value: 0x7c986dff } + theme_color:{ tags: code_string value: 0xd69d85ff } + theme_color:{ tags: code_meta value: 0x9b9b9bff } + theme_color:{ tags: code_comment value: 0x51a644ff } + theme_color:{ tags: line_info_0 value: 0x4f3022ff } + theme_color:{ tags: line_info_1 value: 0x4f3e15ff } + theme_color:{ tags: line_info_2 value: 0x434e2aff } + theme_color:{ tags: line_info_3 value: 0x36241fff } + theme_color:{ tags: line_info_4 value: 0x4f3022ff } + theme_color:{ tags: line_info_5 value: 0x4f3e15ff } + theme_color:{ tags: line_info_6 value: 0x434e2aff } + theme_color:{ tags: line_info_7 value: 0x36241fff } + theme_color:{ tags: thread_0 value: 0xffdc48ff } + theme_color:{ tags: thread_1 value: 0xb2ff65ff } + theme_color:{ tags: thread_2 value: 0xff99e5ff } + theme_color:{ tags: thread_3 value: 0x6598ffff } + theme_color:{ tags: thread_4 value: 0x65ffcbff } + theme_color:{ tags: thread_5 value: 0xff9819ff } + theme_color:{ tags: thread_6 value: 0x9932ffff } + theme_color:{ tags: thread_7 value: 0x65ff4cff } + theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } + theme_color:{ tags: thread_error value: 0xb23219ff } + theme_color:{ tags: breakpoint value: 0xa72911ff } + theme_color:{ tags: "floating background" value: 0x1b1b1baf } + theme_color:{ tags: "floating background alt" value: 0x0000005f } + theme_color:{ tags: "floating background fresh" value: 0x31393d5f } + theme_color:{ tags: "floating border" value: 0xbfbfbf1f } + theme_color:{ tags: "floating scroll_bar background" value: 0x3b3b3b5f } + theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } + theme_color:{ tags: "scroll_bar background" value: 0x2b2b2bff } + theme_color:{ tags: "scroll_bar border" value: 0x3f3f3fff } + theme_color:{ tags: "implicit background" value: 0x00000000 } + theme_color:{ tags: "implicit border" value: 0x00000000 } + theme_color:{ tags: "hollow background" value: 0x00000000 } + theme_color:{ tags: "hollow border" value: 0xffffff1f } + theme_color:{ tags: "tab background" value: 0x333333ff } + theme_color:{ tags: "tab border" value: 0x7160e8ff } + theme_color:{ tags: "tab inactive background" value: 0x171717ff } + theme_color:{ tags: "tab inactive border" value: 0x3e4c57ff } + theme_color:{ tags: "tab auto background" value: 0x3f386dff } + theme_color:{ tags: "tab auto border" value: 0x7160e8ff } + theme_color:{ tags: "tab auto inactive background" value: 0x2f2633ff } + theme_color:{ tags: "tab auto inactive border" value: 0x685073ff } + theme_color:{ tags: "drop_site background" value: 0xffffff05 } + theme_color:{ tags: "drop_site border" value: 0xffffff0f } } ``` } + + //- rjf: to-do { VSLight vs_light "VS (Light)" } { SolarizedDark solarized_dark "Solarized (Dark)" } { SolarizedLight solarized_light "Solarized (Light)" } { HandmadeHero handmade_hero "Handmade Hero" } { FourCoder four_coder "4coder" } + + //- rjf: grove theme + { Grove grove "Grove", + ```theme: + { + theme_color:{ tags: background value: 0x1b1f22ff } + theme_color:{ tags: "alt background" value: 0x232929ff } + theme_color:{ tags: "pop background" value: 0x2f4838ff } + theme_color:{ tags: "fresh background" value: 0x31393dff } + theme_color:{ tags: "match background" value: 0x31393dff } + theme_color:{ tags: border value: 0x485347ff } + theme_color:{ tags: text value: 0xffffffff } + theme_color:{ tags: "weak text" value: 0xa2a2a2ff } + theme_color:{ tags: "good text" value: 0x32a852ff } + theme_color:{ tags: "neutral text" value: 0x3a90bbff } + theme_color:{ tags: "bad text" value: 0xcf5242ff } + theme_color:{ tags: hover value: 0xffffffff } + theme_color:{ tags: "focus overlay" value: 0xfda20012 } + theme_color:{ tags: "focus border" value: 0xfda200ff } + theme_color:{ tags: cursor value: 0x8aff00ff } + theme_color:{ tags: selection value: 0x99ccff0f } + theme_color:{ tags: "inactive background" value: 0x0 } + theme_color:{ tags: drop_shadow value: 0x0000007f } + theme_color:{ tags: "good_pop background" value: 0x2c5b36ff } + theme_color:{ tags: "good_pop border" value: 0x568761ff } + theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" value: 0x803425ff } + theme_color:{ tags: "bad_pop hover" value: 0xff825cff } + theme_color:{ tags: code_default value: 0xad8b69ff } + theme_color:{ tags: code_symbol value: 0x87ad6aff } + theme_color:{ tags: code_type value: 0xb67474ff } + theme_color:{ tags: code_local value: 0xe9bf95ff } + theme_color:{ tags: code_register value: 0xa688b2ff } + theme_color:{ tags: code_keyword value: 0xe49e17ff } + theme_color:{ tags: code_delimiter_or_operator value: 0x795e43ff } + theme_color:{ tags: code_numeric value: 0x98b19eff } + theme_color:{ tags: code_numeric_alt_digit_group value: 0x688b71ff } + theme_color:{ tags: code_string value: 0x98b19eff } + theme_color:{ tags: code_meta value: 0xad5979ff } + theme_color:{ tags: code_comment value: 0x52675dff } + theme_color:{ tags: line_info_0 value: 0x4f3022ff } + theme_color:{ tags: line_info_1 value: 0x4f3e15ff } + theme_color:{ tags: line_info_2 value: 0x434e2aff } + theme_color:{ tags: line_info_3 value: 0x36241fff } + theme_color:{ tags: line_info_4 value: 0x4f3022ff } + theme_color:{ tags: line_info_5 value: 0x4f3e15ff } + theme_color:{ tags: line_info_6 value: 0x434e2aff } + theme_color:{ tags: line_info_7 value: 0x36241fff } + theme_color:{ tags: thread_0 value: 0xffc258ff } + theme_color:{ tags: thread_1 value: 0x82d331ff } + theme_color:{ tags: thread_2 value: 0xff99e5ff } + theme_color:{ tags: thread_3 value: 0x6598ffff } + theme_color:{ tags: thread_4 value: 0x65ffcbff } + theme_color:{ tags: thread_5 value: 0xff9819ff } + theme_color:{ tags: thread_6 value: 0x9932ffff } + theme_color:{ tags: thread_7 value: 0x65ff4cff } + theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } + theme_color:{ tags: thread_error value: 0xb23219ff } + theme_color:{ tags: breakpoint value: 0xa72911ff } + theme_color:{ tags: "floating background" value: 0x1b1f2276 } + theme_color:{ tags: "floating background alt" value: 0x0000005f } + theme_color:{ tags: "floating background fresh" value: 0x31393d5f } + theme_color:{ tags: "floating border" value: 0xbfbfbf1f } + theme_color:{ tags: "floating scroll_bar background" value: 0x3b3b3b5f } + theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } + theme_color:{ tags: "menu_bar background" value: 0x243d32ff } + theme_color:{ tags: "menu_bar border" value: 0x597b63ff } + theme_color:{ tags: "scroll_bar background" value: 0x232929ff } + theme_color:{ tags: "scroll_bar border" value: 0x3c4a3fff } + theme_color:{ tags: "implicit background" value: 0x00000000 } + theme_color:{ tags: "implicit border" value: 0x00000000 } + theme_color:{ tags: "hollow background" value: 0x00000000 } + theme_color:{ tags: "hollow border" value: 0xffffff1f } + theme_color:{ tags: "tab background" value: 0x243d32ff } + theme_color:{ tags: "tab border" value: 0x597b63ff } + theme_color:{ tags: "tab inactive background" value: 0x30383eff } + theme_color:{ tags: "tab inactive border" value: 0x6b7680ff } + theme_color:{ tags: "tab auto background" value: 0x30636dff } + theme_color:{ tags: "tab auto border" value: 0x768f94ff } + theme_color:{ tags: "tab auto inactive background" value: 0x2f2633ff } + theme_color:{ tags: "tab auto inactive border" value: 0x685073ff } + theme_color:{ tags: "drop_site background" value: 0xffffff05 } + theme_color:{ tags: "drop_site border" value: 0xffffff0f } + } + ``` + } + + //- rjf: todo { FarManager far_manager "Far Manager" } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c49e656d..a3276a60 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5752,10 +5752,13 @@ rd_window_frame(void) //- rjf: @window_frame_part compute window's theme // { + HS_Scope *hs_scope = hs_scope_open(); + //- rjf: for this window, scan upwards, and then try the project, then the user, until we // find explicit preset / colors trees in the config. we will prefer the tightest ones, so // that windows can have their own colors, and have those override higher-up settings. RD_Cfg *preset_cfg = &rd_nil_cfg; + RD_Cfg *file_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; RD_Cfg *theme_parents[] = { @@ -5771,14 +5774,22 @@ rd_window_frame(void) for EachIndex(idx, theme_parents_count) { RD_Cfg *parent_cfg = theme_parents[idx]; - if(preset_cfg != &rd_nil_cfg) + if(preset_cfg == &rd_nil_cfg) { - RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("color_preset")); + RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme_preset")); if(possible_preset_cfg != &rd_nil_cfg) { preset_cfg = possible_preset_cfg; } } + if(file_cfg == &rd_nil_cfg) + { + RD_Cfg *possible_file_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme_file")); + if(possible_file_cfg != &rd_nil_cfg) + { + file_cfg = possible_file_cfg; + } + } for(RD_Cfg *child = parent_cfg->first; child != &rd_nil_cfg; child = child->next) { if(str8_match(child->string, str8_lit("theme_color"), 0)) @@ -5803,6 +5814,21 @@ rd_window_frame(void) } } + //- rjf: map the file config to the associated theme file parse + MD_Node *file_tree = &md_nil_node; + if(file_cfg != &rd_nil_cfg) + { + String8 path = file_cfg->first->string; + U64 endt_us = 0; + if(ws->frames_alive == 0) + { + endt_us = os_now_microseconds()+50000; + } + U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us); + String8 data = hs_data_from_hash(hs_scope, hash); + file_tree = md_tree_from_string(scratch.arena, data); + } + //- rjf: build tasks for color applications - each task comprises of a metadesk // tree, describing the color patterns typedef struct ThemeTask ThemeTask; @@ -5811,7 +5837,7 @@ rd_window_frame(void) ThemeTask *next; MD_Node *tree; }; - ThemeTask start_task = {0, preset_tree}; + ThemeTask start_task = {0, !md_node_is_nil(file_tree) ? file_tree : preset_tree}; ThemeTask *first_task = &start_task; ThemeTask *last_task = first_task; { @@ -5867,6 +5893,8 @@ rd_window_frame(void) ws->theme->patterns[idx] = n->pattern; } } + + hs_scope_close(hs_scope); } ////////////////////////////// @@ -8852,6 +8880,7 @@ rd_window_frame(void) UI_TextAlignment(UI_TextAlign_Center) UI_PrefWidth(ui_px(tab_bar_vheight, 1.f)) UI_PrefHeight(ui_px(tab_bar_vheight, 1.f)) + UI_TagF(".") { ui_set_next_child_layout_axis(Axis2_Y); UI_Box *container = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "###add_new_tab"); @@ -9431,8 +9460,10 @@ rd_window_frame(void) // rjf: draw focus overlay if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusOverlay) && b->focus_hot_t > 0.01f) { - Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); - color.w *= 0.09f*b->focus_hot_t; + String8 extras[] = {str8_lit("focus"), str8_lit("overlay")}; + String8Array extras_array = {extras, ArrayCount(extras)}; + Vec4F32 color = ui_color_from_tags_key_extras(b->tags_key, extras_array); + color.w *= b->focus_hot_t; R_Rect2DInst *inst = dr_rect(b->rect, color, 0, 0, 0.f); MemoryCopyArray(inst->corner_radii, b_corner_radii); } @@ -9446,7 +9477,9 @@ rd_window_frame(void) rect = pad_2f32(rect, 1.f); rect = intersect_2f32(window_rect, rect); } - Vec4F32 color = ui_color_from_tags_key_name(box->tags_key, str8_lit("focus")); + String8 extras[] = {str8_lit("focus"), str8_lit("border")}; + String8Array extras_array = {extras, ArrayCount(extras)}; + Vec4F32 color = ui_color_from_tags_key_extras(b->tags_key, extras_array); color.w *= b->focus_active_t; R_Rect2DInst *inst = dr_rect(rect, color, 0, 1.f, border_softness*1.f); MemoryCopyArray(inst->corner_radii, b_corner_radii); @@ -14628,10 +14661,10 @@ rd_frame(void) rd_cfg_release(n->v); } String8 color_preset = rd_setting_from_name(str8_lit("theme_preset")); - String8 color_file = rd_setting_from_name(str8_lit("theme_file")); RD_ThemePreset preset = RD_ThemePreset_DefaultDark; // TODO(rjf): map preset via string MD_Node *theme_tree = rd_state->theme_preset_trees[preset]; + String8 color_file = rd_setting_from_name(str8_lit("theme_file")); for(MD_Node *n = theme_tree; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next) { if(str8_match(n->string, str8_lit("theme_color"), 0)) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b2b35fdf..3f8192bf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1418,7 +1418,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: @watch_row_build_cells root-level type rows // - else if(row->eval.irtree.mode == E_Mode_Null && row->block->eval.irtree.mode != E_Mode_Null) + else if(row->eval.irtree.mode == E_Mode_Null && (e_type_key_match(row->block->eval.irtree.type_key, e_type_key_zero()) || row->block->eval.irtree.mode != E_Mode_Null)) { info.cell_style_key = str8_lit("root_type"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index dfc614e7..239ccdeb 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2221,12 +2221,17 @@ ui_color_from_name(String8 name) } internal Vec4F32 -ui_color_from_tags_key_name(UI_Key key, String8 name) +ui_color_from_tags_key_extras(UI_Key key, String8Array extras) { Vec4F32 result = {0}; + if(ui_state->theme_pattern_cache_slots_count && extras.count > 0) { - //- rjf: compute final key, mixing (tags_key, name) - UI_Key final_key = ui_key_from_string(key, name); + //- rjf: compute final key, mixing (tags_key, extras) + UI_Key final_key = key; + for EachIndex(idx, extras.count) + { + final_key = ui_key_from_string(final_key, extras.v[idx]); + } //- rjf: map to existing node U64 slot_idx = final_key.u64[0]%ui_state->theme_pattern_cache_slots_count; @@ -2273,12 +2278,12 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) for EachIndex(p_tags_idx, p->tags.count) { B32 p_tag_in_key = 0; - for EachIndex(key_tags_idx, tags.count+1) + for EachIndex(key_tags_idx, tags.count + extras.count) { - String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : name; + String8 key_string = key_tags_idx < tags.count ? tags.v[key_tags_idx] : extras.v[key_tags_idx - tags.count]; if(str8_match(p->tags.v[p_tags_idx], key_string, 0)) { - if(key_tags_idx == tags.count) + if(key_tags_idx == tags.count + extras.count - 1) { name_matches = 1; } @@ -2298,7 +2303,7 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) pattern = p; best_match_count = match_count; } - if(match_count == tags.count+1) + if(match_count == tags.count + extras.count) { break; } @@ -2320,6 +2325,14 @@ ui_color_from_tags_key_name(UI_Key key, String8 name) return result; } +internal Vec4F32 +ui_color_from_tags_key_name(UI_Key key, String8 name) +{ + String8Array extras = {&name, 1}; + Vec4F32 result = ui_color_from_tags_key_extras(key, extras); + return result; +} + //- rjf: box node construction internal UI_Box * diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index d0461bf9..18d99706 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -908,6 +908,7 @@ internal UI_Key ui_top_tags_key(void); //- rjf: theme color lookups internal Vec4F32 ui_color_from_name(String8 name); +internal Vec4F32 ui_color_from_tags_key_extras(UI_Key key, String8Array extras); internal Vec4F32 ui_color_from_tags_key_name(UI_Key key, String8 name); //- rjf: box node construction From 6c2cf98ea63e183e7570ee164dc40e4d91ff6131 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 15:52:21 -0700 Subject: [PATCH 548/755] themes collection evaluation, begin moving theme preset/file setting to just being based on the themes folder, rather than completely path-based --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 51 +++++++++++++++++---- src/raddbg/raddbg_core.h | 3 +- src/raddbg/raddbg_eval.c | 73 ++++++++++++++++++++++++++++++ src/raddbg/raddbg_eval.h | 9 +++- 6 files changed, 127 insertions(+), 13 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a80d3443..9e71ec9f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -657,7 +657,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[226] = { str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("fork_loaded_theme"), str8_lit_comp("Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9d896b22..144360df 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -985,7 +985,7 @@ RD_CmdTable: // | | | | {OpenTheme 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } {ForkLoadedTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme" "Fork Loaded Theme" "Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited." "" "" } - {SaveTheme 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } + {SaveTheme 0 0 0 0 "" String null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a3276a60..14b081d4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5819,7 +5819,7 @@ rd_window_frame(void) if(file_cfg != &rd_nil_cfg) { String8 path = file_cfg->first->string; - U64 endt_us = 0; + U64 endt_us = os_now_microseconds()+100; if(ws->frames_alive == 0) { endt_us = os_now_microseconds()+50000; @@ -11304,6 +11304,31 @@ rd_frame(void) } } + //- rjf: add macro for themes + { + String8 names[] = + { + str8_lit("themes"), + }; + for EachElement(idx, names) + { + String8 name = names[idx]; + E_TypeKey type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .flags = E_TypeFlag_StubSingleLineExpansion, + .name = name, + .access = E_TYPE_ACCESS_FUNCTION_NAME(themes), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(themes), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(themes), + }); + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); + expr->type_key = type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaQuery); + e_string2expr_map_insert(scratch.arena, macro_map, name, expr); + } + } + //- rjf: build schema types & cache (name -> type) mapping for EachElement(idx, rd_name_schema_info_table) { @@ -14679,16 +14704,24 @@ rd_frame(void) }break; case RD_CmdKind_SaveTheme: { - String8 dst_path = rd_regs()->file_path; - RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); - RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); - String8List strings = {0}; - for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + String8 name = rd_regs()->string; + if(name.size != 0) { - str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, n->v)); + String8 themes_folder = push_str8f(scratch.arena, "%S/raddbg/themes", os_get_process_info()->user_program_data_path); + if(os_make_directory(themes_folder)) + { + String8 dst_path = push_str8f(scratch.arena, "%S/%S", themes_folder, name); + RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); + String8List strings = {0}; + for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + { + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, n->v)); + } + String8 data = str8_list_join(scratch.arena, &strings, 0); + os_write_data_to_file_path(dst_path, data); + } } - String8 data = str8_list_join(scratch.arena, &strings, 0); - os_write_data_to_file_path(dst_path, data); }break; //- rjf: watches diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 40036bba..d60372fb 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -84,7 +84,8 @@ enum RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaQuery, RD_EvalSpaceKind_MetaCfg, - RD_EvalSpaceKind_MetaCmd, + RD_EvalSpaceKind_MetaCmd, + RD_EvalSpaceKind_MetaTheme, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaUnattachedProcess, }; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a6e36a51..a70380c5 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -84,6 +84,79 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) } } +//////////////////////////////// +//~ rjf: `themes` Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(themes) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex && + expr->first->next->kind == E_ExprKind_LeafStringLiteral) + { + String8 theme_name = expr->first->next->string; + E_TypeKey theme_type = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("theme")); + result.type_key = theme_type; + result.mode = E_Mode_Value; + result.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaTheme), e_irtree_const_u(arena, e_id_from_string(theme_name))); + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(themes) +{ + E_TypeExpandInfo result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: gather presets + String8List names = {0}; + for EachEnumVal(RD_ThemePreset, p) + { + String8 name = rd_theme_preset_display_string_table[p]; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, name); + if(name_matches.count == name_matches.needle_part_count) + { + str8_list_push(scratch.arena, &names, name); + } + } + + //- rjf: gather theme files + { + String8 theme_folder = push_str8f(scratch.arena, "%S/raddbg/themes", os_get_process_info()->user_program_data_path); + OS_FileIter *it = os_file_iter_begin(scratch.arena, theme_folder, OS_FileIterFlag_SkipFolders); + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + { + String8 name = info.name; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, name); + if(name_matches.count == name_matches.needle_part_count) + { + str8_list_push(scratch.arena, &names, name); + } + } + os_file_iter_end(it); + } + + //- rjf: flatten & build accelerator + String8Array *accel = push_array(arena, String8Array, 1); + *accel = str8_array_from_list(arena, &names); + result.user_data = accel; + result.expr_count = accel->count; + scratch_end(scratch); + } + return result; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(themes) +{ + U64 out_idx = 0; + String8Array *accel = (String8Array *)user_data; + for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + { + String8 name = accel->v[idx]; + evals_out[out_idx] = e_eval_wrapf(eval, "$[\"%S\"]", name); + } +} + //////////////////////////////// //~ rjf: `locals` Type Hooks diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 67418101..c866f317 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -7,10 +7,17 @@ //////////////////////////////// //~ rjf: `commands` Type Hooks -E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands); E_TYPE_ACCESS_FUNCTION_DEF(commands); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands); +//////////////////////////////// +//~ rjf: `themes` Type Hooks + +E_TYPE_ACCESS_FUNCTION_DEF(themes); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(themes); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(themes); + //////////////////////////////// //~ rjf: `locals` Type Hooks From f7ae0a1b477c5355e5446707c01170c3e5e44079 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 16:13:39 -0700 Subject: [PATCH 549/755] collapse theme-file vs. theme-preset, plug all theme selection paths into picking that single string, plug theme lister in --- src/raddbg/generated/raddbg.meta.c | 12 +- src/raddbg/raddbg.mdesk | 502 ++++++++++++++--------------- src/raddbg/raddbg_core.c | 80 +++-- 3 files changed, 291 insertions(+), 303 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 9e71ec9f..a59d0e98 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -399,8 +399,8 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand @display_name('User Theme Preset') @description(\"The selected built-in theme preset.\")\n 'theme_preset': string,\n @no_expand @no_expand @display_name('User Theme File') @description(\"The path from which theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand @display_name('Project Theme Preset') @description(\"The selected built-in project theme preset.\")\n 'theme_preset': string,\n @no_expand @display_name('Project Theme File') @description(\"The path from which project's theme data is loaded, overriding the preset.\")\n 'theme_file': path,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, @@ -654,7 +654,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[226] = { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_type_view"), str8_lit_comp("Adds a new type view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_file_path_map"), str8_lit_comp("Adds a new file path map."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme file."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:themes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("fork_loaded_theme"), str8_lit_comp("Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -969,14 +969,14 @@ str8_lit_comp("far_manager"), String8 rd_theme_preset_cfg_string_table[10] = { str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus overlay\", value: 0xfda20012 }\n theme_color: {tags:\"focus border\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), -str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0xffffffff }\n theme_color:{ tags: \"alt background\" value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" value: 0xeaddceff }\n theme_color:{ tags: \"match background\" value: 0xc1e9c4ff }\n theme_color:{ tags: border value: 0xcbcbcbff }\n theme_color:{ tags: text value: 0xff }\n theme_color:{ tags: \"weak text\" value: 0x727272ff }\n theme_color:{ tags: \"good text\" value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" value: 0x972717ff }\n theme_color:{ tags: hover value: 0xff }\n theme_color:{ tags: \"focus overlay\" value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" value: 0x67ffff }\n theme_color:{ tags: cursor value: 0xff }\n theme_color:{ tags: selection value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" value: 0x8 }\n theme_color:{ tags: drop_shadow value: 0xb }\n theme_color:{ tags: \"good_pop background\" value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0x80808ff }\n theme_color:{ tags: code_symbol value: 0x4ac3ff }\n theme_color:{ tags: code_type value: 0xf46200ff }\n theme_color:{ tags: code_local value: 0x317c00ff }\n theme_color:{ tags: code_register value: 0x9a00ffff }\n theme_color:{ tags: code_keyword value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0xb56aff }\n theme_color:{ tags: code_string value: 0x63549fff }\n theme_color:{ tags: code_meta value: 0xd96759ff }\n theme_color:{ tags: code_comment value: 0x717171ff }\n theme_color:{ tags: line_info_0 value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 value: 0xba917eff }\n theme_color:{ tags: thread_0 value: 0xffa700ff }\n theme_color:{ tags: thread_1 value: 0xb41fff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" value: 0xffffffff }\n theme_color:{ tags: \"tab background\" value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), -str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" value: 0x222222ff }\n theme_color:{ tags: \"pop background\" value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" value: 0x31393dff }\n theme_color:{ tags: \"match background\" value: 0x31393dff }\n theme_color:{ tags: border value: 0x404040ff }\n theme_color:{ tags: text value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" value: 0xcf5242ff }\n theme_color:{ tags: hover value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" value: 0x7160e8ff }\n theme_color:{ tags: cursor value: 0x8aff00ff }\n theme_color:{ tags: selection value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" value: 0x0000002f }\n theme_color:{ tags: drop_shadow value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol value: 0xdcdcaaff }\n theme_color:{ tags: code_type value: 0x4ec9b0ff }\n theme_color:{ tags: code_local value: 0x9cdcfeff }\n theme_color:{ tags: code_register value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x767676ff }\n theme_color:{ tags: code_numeric value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0x7c986dff }\n theme_color:{ tags: code_string value: 0xd69d85ff }\n theme_color:{ tags: code_meta value: 0x9b9b9bff }\n theme_color:{ tags: code_comment value: 0x51a644ff }\n theme_color:{ tags: line_info_0 value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 value: 0x434e2aff }\n theme_color:{ tags: line_info_3 value: 0x36241fff }\n theme_color:{ tags: line_info_4 value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 value: 0x434e2aff }\n theme_color:{ tags: line_info_7 value: 0x36241fff }\n theme_color:{ tags: thread_0 value: 0xffdc48ff }\n theme_color:{ tags: thread_1 value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" value: 0x333333ff }\n theme_color:{ tags: \"tab border\" value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff }\n theme_color:{ tags: \"alt background\" , value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" , value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" , value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" , value: 0xeaddceff }\n theme_color:{ tags: \"match background\" , value: 0xc1e9c4ff }\n theme_color:{ tags: border , value: 0xcbcbcbff }\n theme_color:{ tags: text , value: 0xff }\n theme_color:{ tags: \"weak text\" , value: 0x727272ff }\n theme_color:{ tags: \"good text\" , value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" , value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" , value: 0x972717ff }\n theme_color:{ tags: hover , value: 0xff }\n theme_color:{ tags: \"focus overlay\" , value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" , value: 0x67ffff }\n theme_color:{ tags: cursor , value: 0xff }\n theme_color:{ tags: selection , value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" , value: 0x8 }\n theme_color:{ tags: drop_shadow , value: 0xb }\n theme_color:{ tags: \"good_pop background\" , value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" , value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" , value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0x80808ff }\n theme_color:{ tags: code_symbol , value: 0x4ac3ff }\n theme_color:{ tags: code_type , value: 0xf46200ff }\n theme_color:{ tags: code_local , value: 0x317c00ff }\n theme_color:{ tags: code_register , value: 0x9a00ffff }\n theme_color:{ tags: code_keyword , value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric , value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff }\n theme_color:{ tags: code_string , value: 0x63549fff }\n theme_color:{ tags: code_meta , value: 0xd96759ff }\n theme_color:{ tags: code_comment , value: 0x717171ff }\n theme_color:{ tags: line_info_0 , value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 , value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 , value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 , value: 0xba917eff }\n theme_color:{ tags: thread_0 , value: 0xffa700ff }\n theme_color:{ tags: thread_1 , value: 0xb41fff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" , value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" , value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" , value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" , value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" , value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" , value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" , value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" , value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"tab background\" , value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" , value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" , value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" , value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" , value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), -str8_lit_comp("theme:\n{\n theme_color:{ tags: background value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" value: 0x232929ff }\n theme_color:{ tags: \"pop background\" value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" value: 0x31393dff }\n theme_color:{ tags: \"match background\" value: 0x31393dff }\n theme_color:{ tags: border value: 0x485347ff }\n theme_color:{ tags: text value: 0xffffffff }\n theme_color:{ tags: \"weak text\" value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" value: 0xcf5242ff }\n theme_color:{ tags: hover value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" value: 0xfda200ff }\n theme_color:{ tags: cursor value: 0x8aff00ff }\n theme_color:{ tags: selection value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" value: 0x0 }\n theme_color:{ tags: drop_shadow value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" value: 0xff825cff }\n theme_color:{ tags: code_default value: 0xad8b69ff }\n theme_color:{ tags: code_symbol value: 0x87ad6aff }\n theme_color:{ tags: code_type value: 0xb67474ff }\n theme_color:{ tags: code_local value: 0xe9bf95ff }\n theme_color:{ tags: code_register value: 0xa688b2ff }\n theme_color:{ tags: code_keyword value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator value: 0x795e43ff }\n theme_color:{ tags: code_numeric value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group value: 0x688b71ff }\n theme_color:{ tags: code_string value: 0x98b19eff }\n theme_color:{ tags: code_meta value: 0xad5979ff }\n theme_color:{ tags: code_comment value: 0x52675dff }\n theme_color:{ tags: line_info_0 value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 value: 0x434e2aff }\n theme_color:{ tags: line_info_3 value: 0x36241fff }\n theme_color:{ tags: line_info_4 value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 value: 0x434e2aff }\n theme_color:{ tags: line_info_7 value: 0x36241fff }\n theme_color:{ tags: thread_0 value: 0xffc258ff }\n theme_color:{ tags: thread_1 value: 0x82d331ff }\n theme_color:{ tags: thread_2 value: 0xff99e5ff }\n theme_color:{ tags: thread_3 value: 0x6598ffff }\n theme_color:{ tags: thread_4 value: 0x65ffcbff }\n theme_color:{ tags: thread_5 value: 0xff9819ff }\n theme_color:{ tags: thread_6 value: 0x9932ffff }\n theme_color:{ tags: thread_7 value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error value: 0xb23219ff }\n theme_color:{ tags: breakpoint value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" value: 0xffffff0f }\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" , value: 0x232929ff }\n theme_color:{ tags: \"pop background\" , value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x485347ff }\n theme_color:{ tags: text , value: 0xffffffff }\n theme_color:{ tags: \"weak text\" , value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" , value: 0xfda200ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0 }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xad8b69ff }\n theme_color:{ tags: code_symbol , value: 0x87ad6aff }\n theme_color:{ tags: code_type , value: 0xb67474ff }\n theme_color:{ tags: code_local , value: 0xe9bf95ff }\n theme_color:{ tags: code_register , value: 0xa688b2ff }\n theme_color:{ tags: code_keyword , value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff }\n theme_color:{ tags: code_numeric , value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff }\n theme_color:{ tags: code_string , value: 0x98b19eff }\n theme_color:{ tags: code_meta , value: 0xad5979ff }\n theme_color:{ tags: code_comment , value: 0x52675dff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffc258ff }\n theme_color:{ tags: thread_1 , value: 0x82d331ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" , value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 144360df..716ad1b4 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -237,10 +237,7 @@ RD_VocabTable: 'code_font': string, //- rjf: theme - @no_expand @display_name('User Theme Preset') @description("The selected built-in theme preset.") - 'theme_preset': string, - @no_expand @no_expand @display_name('User Theme File') @description("The path from which theme data is loaded, overriding the preset.") - 'theme_file': path, + @no_expand 'theme': string, @display_name('User Theme') @description("The user's theme, which describes all colors used throughout the UI.") 'theme_colors': query, @@ -291,10 +288,7 @@ RD_VocabTable: @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, //- rjf: theme - @no_expand @display_name('Project Theme Preset') @description("The selected built-in project theme preset.") - 'theme_preset': string, - @no_expand @display_name('Project Theme File') @description("The path from which project's theme data is loaded, overriding the preset.") - 'theme_file': path, + @no_expand 'theme': string, @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") 'theme_colors': query, @@ -982,7 +976,7 @@ RD_CmdTable: // | | | | {AddFilePathMap 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "add_file_path_map" "Add File Path Map" "Adds a new file path map." "" "" } //- rjf: themes - {OpenTheme 0 0 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme file." "color" "" } + {OpenTheme 0 0 0 0 "query:themes" String null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme." "color" "" } {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } {ForkLoadedTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme" "Fork Loaded Theme" "Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited." "" "" } {SaveTheme 0 0 0 0 "" String null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } @@ -1456,95 +1450,95 @@ RD_ThemePresetTable: { DefaultLight default_light "Default (Light)", ```theme: { - theme_color:{ tags: background value: 0xffffffff } - theme_color:{ tags: "alt background" value: 0xf8f8f8ff } - theme_color:{ tags: "pop background" value: 0xcbe4f2ff } - theme_color:{ tags: "menu_bar pop background" value: 0x5aabd9ff } - theme_color:{ tags: "fresh background" value: 0xeaddceff } - theme_color:{ tags: "match background" value: 0xc1e9c4ff } - theme_color:{ tags: border value: 0xcbcbcbff } - theme_color:{ tags: text value: 0xff } - theme_color:{ tags: "weak text" value: 0x727272ff } - theme_color:{ tags: "good text" value: 0x217538ff } - theme_color:{ tags: "neutral text" value: 0x1a5b7cff } - theme_color:{ tags: "bad text" value: 0x972717ff } - theme_color:{ tags: hover value: 0xff } - theme_color:{ tags: "focus overlay" value: 0x67ff4b } - theme_color:{ tags: "focus border" value: 0x67ffff } - theme_color:{ tags: cursor value: 0xff } - theme_color:{ tags: selection value: 0x283d5166 } - theme_color:{ tags: "inactive background" value: 0x8 } - theme_color:{ tags: drop_shadow value: 0xb } - theme_color:{ tags: "good_pop background" value: 0x90c09aff } - theme_color:{ tags: "good_pop border" value: 0x1e7231ff } - theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } - theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } - theme_color:{ tags: "good_pop text" value: 0xe3f5d3ff } - theme_color:{ tags: "bad_pop background" value: 0xa93620ff } - theme_color:{ tags: "bad_pop text" value: 0xffffffff } - theme_color:{ tags: "bad_pop text weak" value: 0xffffffff } - theme_color:{ tags: "menu_bar bad_pop background" value: 0xff2a00ff } - theme_color:{ tags: "menu_bar bad_pop text" value: 0xffffffff } - theme_color:{ tags: "bad_pop hover" value: 0xff825cff } - theme_color:{ tags: code_default value: 0x80808ff } - theme_color:{ tags: code_symbol value: 0x4ac3ff } - theme_color:{ tags: code_type value: 0xf46200ff } - theme_color:{ tags: code_local value: 0x317c00ff } - theme_color:{ tags: code_register value: 0x9a00ffff } - theme_color:{ tags: code_keyword value: 0xff0600ff } - theme_color:{ tags: code_delimiter_or_operator value: 0x8a8a8aff } - theme_color:{ tags: code_numeric value: 0x7d49ff } - theme_color:{ tags: code_numeric_alt_digit_group value: 0xb56aff } - theme_color:{ tags: code_string value: 0x63549fff } - theme_color:{ tags: code_meta value: 0xd96759ff } - theme_color:{ tags: code_comment value: 0x717171ff } - theme_color:{ tags: line_info_0 value: 0xe6d5cdff } - theme_color:{ tags: line_info_1 value: 0xdbcfb2ff } - theme_color:{ tags: line_info_2 value: 0xddeac1ff } - theme_color:{ tags: line_info_3 value: 0xddc4bdff } - theme_color:{ tags: line_info_4 value: 0xba917eff } - theme_color:{ tags: thread_0 value: 0xffa700ff } - theme_color:{ tags: thread_1 value: 0xb41fff } - theme_color:{ tags: thread_2 value: 0xff99e5ff } - theme_color:{ tags: thread_3 value: 0x6598ffff } - theme_color:{ tags: thread_4 value: 0x65ffcbff } - theme_color:{ tags: thread_5 value: 0xff9819ff } - theme_color:{ tags: thread_6 value: 0x9932ffff } - theme_color:{ tags: thread_7 value: 0x65ff4cff } - theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } - theme_color:{ tags: thread_error value: 0xb23219ff } - theme_color:{ tags: breakpoint value: 0xff2800ff } - theme_color:{ tags: "floating background" value: 0xffffffc7 } - theme_color:{ tags: "floating background alt" value: 0x23 } - theme_color:{ tags: "floating background fresh" value: 0xeaddceff } - theme_color:{ tags: "floating border" value: 0x88888884 } - theme_color:{ tags: "scroll_bar background" value: 0xe9e9e9ff } - theme_color:{ tags: "scroll_bar border" value: 0x5f5f5f5f } - theme_color:{ tags: "floating scroll_bar background" value: 0xe9e9e9ff } - theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } - theme_color:{ tags: "menu_bar background" value: 0x2b6b9aff } - theme_color:{ tags: "menu_bar border" value: 0x4d } - theme_color:{ tags: "menu_bar text" value: 0xffffffff } - theme_color:{ tags: "menu_bar text weak" value: 0xffffffff } - theme_color:{ tags: "good menu_bar text" value: 0x70db8dff } - theme_color:{ tags: "bad menu_bar text" value: 0xffa79bff } - theme_color:{ tags: "neutral menu_bar text" value: 0xc4dbe7ff } - theme_color:{ tags: "implicit background" value: 0x00000000 } - theme_color:{ tags: "implicit border" value: 0x00000000 } - theme_color:{ tags: "hollow background" value: 0x00000000 } - theme_color:{ tags: "hollow border" value: 0xffffff1f } - theme_color:{ tags: "tab text" value: 0xffffffff } - theme_color:{ tags: "tab text weak" value: 0xffffffff } - theme_color:{ tags: "tab background" value: 0xb67e48ff } - theme_color:{ tags: "tab border" value: 0x875b31ff } - theme_color:{ tags: "tab inactive background" value: 0xcacacaff } - theme_color:{ tags: "tab inactive border" value: 0xb5b5b5ff } - theme_color:{ tags: "tab auto background" value: 0xc41c69ff } - theme_color:{ tags: "tab auto border" value: 0x981039ff } - theme_color:{ tags: "tab auto inactive background" value: 0x9b88a3ff } - theme_color:{ tags: "tab auto inactive border" value: 0x373737ff } - theme_color:{ tags: "drop_site background" value: 0xffffff05 } - theme_color:{ tags: "drop_site border" value: 0xffffff0f } + theme_color:{ tags: background , value: 0xffffffff } + theme_color:{ tags: "alt background" , value: 0xf8f8f8ff } + theme_color:{ tags: "pop background" , value: 0xcbe4f2ff } + theme_color:{ tags: "menu_bar pop background" , value: 0x5aabd9ff } + theme_color:{ tags: "fresh background" , value: 0xeaddceff } + theme_color:{ tags: "match background" , value: 0xc1e9c4ff } + theme_color:{ tags: border , value: 0xcbcbcbff } + theme_color:{ tags: text , value: 0xff } + theme_color:{ tags: "weak text" , value: 0x727272ff } + theme_color:{ tags: "good text" , value: 0x217538ff } + theme_color:{ tags: "neutral text" , value: 0x1a5b7cff } + theme_color:{ tags: "bad text" , value: 0x972717ff } + theme_color:{ tags: hover , value: 0xff } + theme_color:{ tags: "focus overlay" , value: 0x67ff4b } + theme_color:{ tags: "focus border" , value: 0x67ffff } + theme_color:{ tags: cursor , value: 0xff } + theme_color:{ tags: selection , value: 0x283d5166 } + theme_color:{ tags: "inactive background" , value: 0x8 } + theme_color:{ tags: drop_shadow , value: 0xb } + theme_color:{ tags: "good_pop background" , value: 0x90c09aff } + theme_color:{ tags: "good_pop border" , value: 0x1e7231ff } + theme_color:{ tags: "good_pop hover" , value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" , value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop text" , value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" , value: 0xa93620ff } + theme_color:{ tags: "bad_pop text" , value: 0xffffffff } + theme_color:{ tags: "bad_pop text weak" , value: 0xffffffff } + theme_color:{ tags: "menu_bar bad_pop background" , value: 0xff2a00ff } + theme_color:{ tags: "menu_bar bad_pop text" , value: 0xffffffff } + theme_color:{ tags: "bad_pop hover" , value: 0xff825cff } + theme_color:{ tags: code_default , value: 0x80808ff } + theme_color:{ tags: code_symbol , value: 0x4ac3ff } + theme_color:{ tags: code_type , value: 0xf46200ff } + theme_color:{ tags: code_local , value: 0x317c00ff } + theme_color:{ tags: code_register , value: 0x9a00ffff } + theme_color:{ tags: code_keyword , value: 0xff0600ff } + theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff } + theme_color:{ tags: code_numeric , value: 0x7d49ff } + theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff } + theme_color:{ tags: code_string , value: 0x63549fff } + theme_color:{ tags: code_meta , value: 0xd96759ff } + theme_color:{ tags: code_comment , value: 0x717171ff } + theme_color:{ tags: line_info_0 , value: 0xe6d5cdff } + theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff } + theme_color:{ tags: line_info_2 , value: 0xddeac1ff } + theme_color:{ tags: line_info_3 , value: 0xddc4bdff } + theme_color:{ tags: line_info_4 , value: 0xba917eff } + theme_color:{ tags: thread_0 , value: 0xffa700ff } + theme_color:{ tags: thread_1 , value: 0xb41fff } + theme_color:{ tags: thread_2 , value: 0xff99e5ff } + theme_color:{ tags: thread_3 , value: 0x6598ffff } + theme_color:{ tags: thread_4 , value: 0x65ffcbff } + theme_color:{ tags: thread_5 , value: 0xff9819ff } + theme_color:{ tags: thread_6 , value: 0x9932ffff } + theme_color:{ tags: thread_7 , value: 0x65ff4cff } + theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff } + theme_color:{ tags: thread_error , value: 0xb23219ff } + theme_color:{ tags: breakpoint , value: 0xff2800ff } + theme_color:{ tags: "floating background" , value: 0xffffffc7 } + theme_color:{ tags: "floating background alt" , value: 0x23 } + theme_color:{ tags: "floating background fresh" , value: 0xeaddceff } + theme_color:{ tags: "floating border" , value: 0x88888884 } + theme_color:{ tags: "scroll_bar background" , value: 0xe9e9e9ff } + theme_color:{ tags: "scroll_bar border" , value: 0x5f5f5f5f } + theme_color:{ tags: "floating scroll_bar background" , value: 0xe9e9e9ff } + theme_color:{ tags: "floating scroll_bar border" , value: 0x5f5f5f5f } + theme_color:{ tags: "menu_bar background" , value: 0x2b6b9aff } + theme_color:{ tags: "menu_bar border" , value: 0x4d } + theme_color:{ tags: "menu_bar text" , value: 0xffffffff } + theme_color:{ tags: "menu_bar text weak" , value: 0xffffffff } + theme_color:{ tags: "good menu_bar text" , value: 0x70db8dff } + theme_color:{ tags: "bad menu_bar text" , value: 0xffa79bff } + theme_color:{ tags: "neutral menu_bar text" , value: 0xc4dbe7ff } + theme_color:{ tags: "implicit background" , value: 0x00000000 } + theme_color:{ tags: "implicit border" , value: 0x00000000 } + theme_color:{ tags: "hollow background" , value: 0x00000000 } + theme_color:{ tags: "hollow border" , value: 0xffffff1f } + theme_color:{ tags: "tab text" , value: 0xffffffff } + theme_color:{ tags: "tab text weak" , value: 0xffffffff } + theme_color:{ tags: "tab background" , value: 0xb67e48ff } + theme_color:{ tags: "tab border" , value: 0x875b31ff } + theme_color:{ tags: "tab inactive background" , value: 0xcacacaff } + theme_color:{ tags: "tab inactive border" , value: 0xb5b5b5ff } + theme_color:{ tags: "tab auto background" , value: 0xc41c69ff } + theme_color:{ tags: "tab auto border" , value: 0x981039ff } + theme_color:{ tags: "tab auto inactive background" , value: 0x9b88a3ff } + theme_color:{ tags: "tab auto inactive border" , value: 0x373737ff } + theme_color:{ tags: "drop_site background" , value: 0xffffff05 } + theme_color:{ tags: "drop_site border" , value: 0xffffff0f } } ``` } @@ -1554,83 +1548,83 @@ RD_ThemePresetTable: VSDark vs_dark "VS (Dark)", ```theme: { - theme_color:{ tags: background value: 0x1f1f1fff } - theme_color:{ tags: "alt background" value: 0x222222ff } - theme_color:{ tags: "pop background" value: 0x383167ff } - theme_color:{ tags: "fresh background" value: 0x31393dff } - theme_color:{ tags: "match background" value: 0x31393dff } - theme_color:{ tags: border value: 0x404040ff } - theme_color:{ tags: text value: 0xe5e5e5ff } - theme_color:{ tags: "weak text" value: 0xa4a4a4ff } - theme_color:{ tags: "good text" value: 0x32a852ff } - theme_color:{ tags: "neutral text" value: 0x3a90bbff } - theme_color:{ tags: "bad text" value: 0xcf5242ff } - theme_color:{ tags: hover value: 0xffffffff } - theme_color:{ tags: "focus overlay" value: 0x7160e81e } - theme_color:{ tags: "focus border" value: 0x7160e8ff } - theme_color:{ tags: cursor value: 0x8aff00ff } - theme_color:{ tags: selection value: 0x99ccff0f } - theme_color:{ tags: "inactive background" value: 0x0000002f } - theme_color:{ tags: drop_shadow value: 0x0000007f } - theme_color:{ tags: "good_pop background" value: 0x2c5b36ff } - theme_color:{ tags: "good_pop border" value: 0x568761ff } - theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } - theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } - theme_color:{ tags: "bad_pop background" value: 0x803425ff } - theme_color:{ tags: "bad_pop hover" value: 0xff825cff } - theme_color:{ tags: code_default value: 0xe0e0e0ff } - theme_color:{ tags: code_symbol value: 0xdcdcaaff } - theme_color:{ tags: code_type value: 0x4ec9b0ff } - theme_color:{ tags: code_local value: 0x9cdcfeff } - theme_color:{ tags: code_register value: 0xb7afd5ff } - theme_color:{ tags: code_keyword value: 0x569cd6ff } - theme_color:{ tags: code_delimiter_or_operator value: 0x767676ff } - theme_color:{ tags: code_numeric value: 0xb5cea8ff } - theme_color:{ tags: code_numeric_alt_digit_group value: 0x7c986dff } - theme_color:{ tags: code_string value: 0xd69d85ff } - theme_color:{ tags: code_meta value: 0x9b9b9bff } - theme_color:{ tags: code_comment value: 0x51a644ff } - theme_color:{ tags: line_info_0 value: 0x4f3022ff } - theme_color:{ tags: line_info_1 value: 0x4f3e15ff } - theme_color:{ tags: line_info_2 value: 0x434e2aff } - theme_color:{ tags: line_info_3 value: 0x36241fff } - theme_color:{ tags: line_info_4 value: 0x4f3022ff } - theme_color:{ tags: line_info_5 value: 0x4f3e15ff } - theme_color:{ tags: line_info_6 value: 0x434e2aff } - theme_color:{ tags: line_info_7 value: 0x36241fff } - theme_color:{ tags: thread_0 value: 0xffdc48ff } - theme_color:{ tags: thread_1 value: 0xb2ff65ff } - theme_color:{ tags: thread_2 value: 0xff99e5ff } - theme_color:{ tags: thread_3 value: 0x6598ffff } - theme_color:{ tags: thread_4 value: 0x65ffcbff } - theme_color:{ tags: thread_5 value: 0xff9819ff } - theme_color:{ tags: thread_6 value: 0x9932ffff } - theme_color:{ tags: thread_7 value: 0x65ff4cff } - theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } - theme_color:{ tags: thread_error value: 0xb23219ff } - theme_color:{ tags: breakpoint value: 0xa72911ff } - theme_color:{ tags: "floating background" value: 0x1b1b1baf } - theme_color:{ tags: "floating background alt" value: 0x0000005f } - theme_color:{ tags: "floating background fresh" value: 0x31393d5f } - theme_color:{ tags: "floating border" value: 0xbfbfbf1f } - theme_color:{ tags: "floating scroll_bar background" value: 0x3b3b3b5f } - theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } - theme_color:{ tags: "scroll_bar background" value: 0x2b2b2bff } - theme_color:{ tags: "scroll_bar border" value: 0x3f3f3fff } - theme_color:{ tags: "implicit background" value: 0x00000000 } - theme_color:{ tags: "implicit border" value: 0x00000000 } - theme_color:{ tags: "hollow background" value: 0x00000000 } - theme_color:{ tags: "hollow border" value: 0xffffff1f } - theme_color:{ tags: "tab background" value: 0x333333ff } - theme_color:{ tags: "tab border" value: 0x7160e8ff } - theme_color:{ tags: "tab inactive background" value: 0x171717ff } - theme_color:{ tags: "tab inactive border" value: 0x3e4c57ff } - theme_color:{ tags: "tab auto background" value: 0x3f386dff } - theme_color:{ tags: "tab auto border" value: 0x7160e8ff } - theme_color:{ tags: "tab auto inactive background" value: 0x2f2633ff } - theme_color:{ tags: "tab auto inactive border" value: 0x685073ff } - theme_color:{ tags: "drop_site background" value: 0xffffff05 } - theme_color:{ tags: "drop_site border" value: 0xffffff0f } + theme_color:{ tags: background , value: 0x1f1f1fff } + theme_color:{ tags: "alt background" , value: 0x222222ff } + theme_color:{ tags: "pop background" , value: 0x383167ff } + theme_color:{ tags: "fresh background" , value: 0x31393dff } + theme_color:{ tags: "match background" , value: 0x31393dff } + theme_color:{ tags: border , value: 0x404040ff } + theme_color:{ tags: text , value: 0xe5e5e5ff } + theme_color:{ tags: "weak text" , value: 0xa4a4a4ff } + theme_color:{ tags: "good text" , value: 0x32a852ff } + theme_color:{ tags: "neutral text" , value: 0x3a90bbff } + theme_color:{ tags: "bad text" , value: 0xcf5242ff } + theme_color:{ tags: hover , value: 0xffffffff } + theme_color:{ tags: "focus overlay" , value: 0x7160e81e } + theme_color:{ tags: "focus border" , value: 0x7160e8ff } + theme_color:{ tags: cursor , value: 0x8aff00ff } + theme_color:{ tags: selection , value: 0x99ccff0f } + theme_color:{ tags: "inactive background" , value: 0x0000002f } + theme_color:{ tags: drop_shadow , value: 0x0000007f } + theme_color:{ tags: "good_pop background" , value: 0x2c5b36ff } + theme_color:{ tags: "good_pop border" , value: 0x568761ff } + theme_color:{ tags: "good_pop hover" , value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" , value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" , value: 0x803425ff } + theme_color:{ tags: "bad_pop hover" , value: 0xff825cff } + theme_color:{ tags: code_default , value: 0xe0e0e0ff } + theme_color:{ tags: code_symbol , value: 0xdcdcaaff } + theme_color:{ tags: code_type , value: 0x4ec9b0ff } + theme_color:{ tags: code_local , value: 0x9cdcfeff } + theme_color:{ tags: code_register , value: 0xb7afd5ff } + theme_color:{ tags: code_keyword , value: 0x569cd6ff } + theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff } + theme_color:{ tags: code_numeric , value: 0xb5cea8ff } + theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff } + theme_color:{ tags: code_string , value: 0xd69d85ff } + theme_color:{ tags: code_meta , value: 0x9b9b9bff } + theme_color:{ tags: code_comment , value: 0x51a644ff } + theme_color:{ tags: line_info_0 , value: 0x4f3022ff } + theme_color:{ tags: line_info_1 , value: 0x4f3e15ff } + theme_color:{ tags: line_info_2 , value: 0x434e2aff } + theme_color:{ tags: line_info_3 , value: 0x36241fff } + theme_color:{ tags: line_info_4 , value: 0x4f3022ff } + theme_color:{ tags: line_info_5 , value: 0x4f3e15ff } + theme_color:{ tags: line_info_6 , value: 0x434e2aff } + theme_color:{ tags: line_info_7 , value: 0x36241fff } + theme_color:{ tags: thread_0 , value: 0xffdc48ff } + theme_color:{ tags: thread_1 , value: 0xb2ff65ff } + theme_color:{ tags: thread_2 , value: 0xff99e5ff } + theme_color:{ tags: thread_3 , value: 0x6598ffff } + theme_color:{ tags: thread_4 , value: 0x65ffcbff } + theme_color:{ tags: thread_5 , value: 0xff9819ff } + theme_color:{ tags: thread_6 , value: 0x9932ffff } + theme_color:{ tags: thread_7 , value: 0x65ff4cff } + theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff } + theme_color:{ tags: thread_error , value: 0xb23219ff } + theme_color:{ tags: breakpoint , value: 0xa72911ff } + theme_color:{ tags: "floating background" , value: 0x1b1b1baf } + theme_color:{ tags: "floating background alt" , value: 0x0000005f } + theme_color:{ tags: "floating background fresh" , value: 0x31393d5f } + theme_color:{ tags: "floating border" , value: 0xbfbfbf1f } + theme_color:{ tags: "floating scroll_bar background" , value: 0x3b3b3b5f } + theme_color:{ tags: "floating scroll_bar border" , value: 0x5f5f5f5f } + theme_color:{ tags: "scroll_bar background" , value: 0x2b2b2bff } + theme_color:{ tags: "scroll_bar border" , value: 0x3f3f3fff } + theme_color:{ tags: "implicit background" , value: 0x00000000 } + theme_color:{ tags: "implicit border" , value: 0x00000000 } + theme_color:{ tags: "hollow background" , value: 0x00000000 } + theme_color:{ tags: "hollow border" , value: 0xffffff1f } + theme_color:{ tags: "tab background" , value: 0x333333ff } + theme_color:{ tags: "tab border" , value: 0x7160e8ff } + theme_color:{ tags: "tab inactive background" , value: 0x171717ff } + theme_color:{ tags: "tab inactive border" , value: 0x3e4c57ff } + theme_color:{ tags: "tab auto background" , value: 0x3f386dff } + theme_color:{ tags: "tab auto border" , value: 0x7160e8ff } + theme_color:{ tags: "tab auto inactive background" , value: 0x2f2633ff } + theme_color:{ tags: "tab auto inactive border" , value: 0x685073ff } + theme_color:{ tags: "drop_site background" , value: 0xffffff05 } + theme_color:{ tags: "drop_site border" , value: 0xffffff0f } } ``` } @@ -1646,85 +1640,85 @@ RD_ThemePresetTable: { Grove grove "Grove", ```theme: { - theme_color:{ tags: background value: 0x1b1f22ff } - theme_color:{ tags: "alt background" value: 0x232929ff } - theme_color:{ tags: "pop background" value: 0x2f4838ff } - theme_color:{ tags: "fresh background" value: 0x31393dff } - theme_color:{ tags: "match background" value: 0x31393dff } - theme_color:{ tags: border value: 0x485347ff } - theme_color:{ tags: text value: 0xffffffff } - theme_color:{ tags: "weak text" value: 0xa2a2a2ff } - theme_color:{ tags: "good text" value: 0x32a852ff } - theme_color:{ tags: "neutral text" value: 0x3a90bbff } - theme_color:{ tags: "bad text" value: 0xcf5242ff } - theme_color:{ tags: hover value: 0xffffffff } - theme_color:{ tags: "focus overlay" value: 0xfda20012 } - theme_color:{ tags: "focus border" value: 0xfda200ff } - theme_color:{ tags: cursor value: 0x8aff00ff } - theme_color:{ tags: selection value: 0x99ccff0f } - theme_color:{ tags: "inactive background" value: 0x0 } - theme_color:{ tags: drop_shadow value: 0x0000007f } - theme_color:{ tags: "good_pop background" value: 0x2c5b36ff } - theme_color:{ tags: "good_pop border" value: 0x568761ff } - theme_color:{ tags: "good_pop hover" value: 0xe3f5d3ff } - theme_color:{ tags: "good_pop weak text" value: 0xe3f5d3ff } - theme_color:{ tags: "bad_pop background" value: 0x803425ff } - theme_color:{ tags: "bad_pop hover" value: 0xff825cff } - theme_color:{ tags: code_default value: 0xad8b69ff } - theme_color:{ tags: code_symbol value: 0x87ad6aff } - theme_color:{ tags: code_type value: 0xb67474ff } - theme_color:{ tags: code_local value: 0xe9bf95ff } - theme_color:{ tags: code_register value: 0xa688b2ff } - theme_color:{ tags: code_keyword value: 0xe49e17ff } - theme_color:{ tags: code_delimiter_or_operator value: 0x795e43ff } - theme_color:{ tags: code_numeric value: 0x98b19eff } - theme_color:{ tags: code_numeric_alt_digit_group value: 0x688b71ff } - theme_color:{ tags: code_string value: 0x98b19eff } - theme_color:{ tags: code_meta value: 0xad5979ff } - theme_color:{ tags: code_comment value: 0x52675dff } - theme_color:{ tags: line_info_0 value: 0x4f3022ff } - theme_color:{ tags: line_info_1 value: 0x4f3e15ff } - theme_color:{ tags: line_info_2 value: 0x434e2aff } - theme_color:{ tags: line_info_3 value: 0x36241fff } - theme_color:{ tags: line_info_4 value: 0x4f3022ff } - theme_color:{ tags: line_info_5 value: 0x4f3e15ff } - theme_color:{ tags: line_info_6 value: 0x434e2aff } - theme_color:{ tags: line_info_7 value: 0x36241fff } - theme_color:{ tags: thread_0 value: 0xffc258ff } - theme_color:{ tags: thread_1 value: 0x82d331ff } - theme_color:{ tags: thread_2 value: 0xff99e5ff } - theme_color:{ tags: thread_3 value: 0x6598ffff } - theme_color:{ tags: thread_4 value: 0x65ffcbff } - theme_color:{ tags: thread_5 value: 0xff9819ff } - theme_color:{ tags: thread_6 value: 0x9932ffff } - theme_color:{ tags: thread_7 value: 0x65ff4cff } - theme_color:{ tags: thread_unwound value: 0xb2ccd8ff } - theme_color:{ tags: thread_error value: 0xb23219ff } - theme_color:{ tags: breakpoint value: 0xa72911ff } - theme_color:{ tags: "floating background" value: 0x1b1f2276 } - theme_color:{ tags: "floating background alt" value: 0x0000005f } - theme_color:{ tags: "floating background fresh" value: 0x31393d5f } - theme_color:{ tags: "floating border" value: 0xbfbfbf1f } - theme_color:{ tags: "floating scroll_bar background" value: 0x3b3b3b5f } - theme_color:{ tags: "floating scroll_bar border" value: 0x5f5f5f5f } - theme_color:{ tags: "menu_bar background" value: 0x243d32ff } - theme_color:{ tags: "menu_bar border" value: 0x597b63ff } - theme_color:{ tags: "scroll_bar background" value: 0x232929ff } - theme_color:{ tags: "scroll_bar border" value: 0x3c4a3fff } - theme_color:{ tags: "implicit background" value: 0x00000000 } - theme_color:{ tags: "implicit border" value: 0x00000000 } - theme_color:{ tags: "hollow background" value: 0x00000000 } - theme_color:{ tags: "hollow border" value: 0xffffff1f } - theme_color:{ tags: "tab background" value: 0x243d32ff } - theme_color:{ tags: "tab border" value: 0x597b63ff } - theme_color:{ tags: "tab inactive background" value: 0x30383eff } - theme_color:{ tags: "tab inactive border" value: 0x6b7680ff } - theme_color:{ tags: "tab auto background" value: 0x30636dff } - theme_color:{ tags: "tab auto border" value: 0x768f94ff } - theme_color:{ tags: "tab auto inactive background" value: 0x2f2633ff } - theme_color:{ tags: "tab auto inactive border" value: 0x685073ff } - theme_color:{ tags: "drop_site background" value: 0xffffff05 } - theme_color:{ tags: "drop_site border" value: 0xffffff0f } + theme_color:{ tags: background , value: 0x1b1f22ff } + theme_color:{ tags: "alt background" , value: 0x232929ff } + theme_color:{ tags: "pop background" , value: 0x2f4838ff } + theme_color:{ tags: "fresh background" , value: 0x31393dff } + theme_color:{ tags: "match background" , value: 0x31393dff } + theme_color:{ tags: border , value: 0x485347ff } + theme_color:{ tags: text , value: 0xffffffff } + theme_color:{ tags: "weak text" , value: 0xa2a2a2ff } + theme_color:{ tags: "good text" , value: 0x32a852ff } + theme_color:{ tags: "neutral text" , value: 0x3a90bbff } + theme_color:{ tags: "bad text" , value: 0xcf5242ff } + theme_color:{ tags: hover , value: 0xffffffff } + theme_color:{ tags: "focus overlay" , value: 0xfda20012 } + theme_color:{ tags: "focus border" , value: 0xfda200ff } + theme_color:{ tags: cursor , value: 0x8aff00ff } + theme_color:{ tags: selection , value: 0x99ccff0f } + theme_color:{ tags: "inactive background" , value: 0x0 } + theme_color:{ tags: drop_shadow , value: 0x0000007f } + theme_color:{ tags: "good_pop background" , value: 0x2c5b36ff } + theme_color:{ tags: "good_pop border" , value: 0x568761ff } + theme_color:{ tags: "good_pop hover" , value: 0xe3f5d3ff } + theme_color:{ tags: "good_pop weak text" , value: 0xe3f5d3ff } + theme_color:{ tags: "bad_pop background" , value: 0x803425ff } + theme_color:{ tags: "bad_pop hover" , value: 0xff825cff } + theme_color:{ tags: code_default , value: 0xad8b69ff } + theme_color:{ tags: code_symbol , value: 0x87ad6aff } + theme_color:{ tags: code_type , value: 0xb67474ff } + theme_color:{ tags: code_local , value: 0xe9bf95ff } + theme_color:{ tags: code_register , value: 0xa688b2ff } + theme_color:{ tags: code_keyword , value: 0xe49e17ff } + theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff } + theme_color:{ tags: code_numeric , value: 0x98b19eff } + theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff } + theme_color:{ tags: code_string , value: 0x98b19eff } + theme_color:{ tags: code_meta , value: 0xad5979ff } + theme_color:{ tags: code_comment , value: 0x52675dff } + theme_color:{ tags: line_info_0 , value: 0x4f3022ff } + theme_color:{ tags: line_info_1 , value: 0x4f3e15ff } + theme_color:{ tags: line_info_2 , value: 0x434e2aff } + theme_color:{ tags: line_info_3 , value: 0x36241fff } + theme_color:{ tags: line_info_4 , value: 0x4f3022ff } + theme_color:{ tags: line_info_5 , value: 0x4f3e15ff } + theme_color:{ tags: line_info_6 , value: 0x434e2aff } + theme_color:{ tags: line_info_7 , value: 0x36241fff } + theme_color:{ tags: thread_0 , value: 0xffc258ff } + theme_color:{ tags: thread_1 , value: 0x82d331ff } + theme_color:{ tags: thread_2 , value: 0xff99e5ff } + theme_color:{ tags: thread_3 , value: 0x6598ffff } + theme_color:{ tags: thread_4 , value: 0x65ffcbff } + theme_color:{ tags: thread_5 , value: 0xff9819ff } + theme_color:{ tags: thread_6 , value: 0x9932ffff } + theme_color:{ tags: thread_7 , value: 0x65ff4cff } + theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff } + theme_color:{ tags: thread_error , value: 0xb23219ff } + theme_color:{ tags: breakpoint , value: 0xa72911ff } + theme_color:{ tags: "floating background" , value: 0x1b1f2276 } + theme_color:{ tags: "floating background alt" , value: 0x0000005f } + theme_color:{ tags: "floating background fresh" , value: 0x31393d5f } + theme_color:{ tags: "floating border" , value: 0xbfbfbf1f } + theme_color:{ tags: "floating scroll_bar background" , value: 0x3b3b3b5f } + theme_color:{ tags: "floating scroll_bar border" , value: 0x5f5f5f5f } + theme_color:{ tags: "menu_bar background" , value: 0x243d32ff } + theme_color:{ tags: "menu_bar border" , value: 0x597b63ff } + theme_color:{ tags: "scroll_bar background" , value: 0x232929ff } + theme_color:{ tags: "scroll_bar border" , value: 0x3c4a3fff } + theme_color:{ tags: "implicit background" , value: 0x00000000 } + theme_color:{ tags: "implicit border" , value: 0x00000000 } + theme_color:{ tags: "hollow background" , value: 0x00000000 } + theme_color:{ tags: "hollow border" , value: 0xffffff1f } + theme_color:{ tags: "tab background" , value: 0x243d32ff } + theme_color:{ tags: "tab border" , value: 0x597b63ff } + theme_color:{ tags: "tab inactive background" , value: 0x30383eff } + theme_color:{ tags: "tab inactive border" , value: 0x6b7680ff } + theme_color:{ tags: "tab auto background" , value: 0x30636dff } + theme_color:{ tags: "tab auto border" , value: 0x768f94ff } + theme_color:{ tags: "tab auto inactive background" , value: 0x2f2633ff } + theme_color:{ tags: "tab auto inactive border" , value: 0x685073ff } + theme_color:{ tags: "drop_site background" , value: 0xffffff05 } + theme_color:{ tags: "drop_site border" , value: 0xffffff0f } } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 14b081d4..a0564612 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3307,6 +3307,11 @@ rd_view_ui(Rng2F32 rect) String8 cmd_name = rd_cmd_name_from_eval(eval); rd_cmd(RD_CmdKind_CompleteQuery, .cmd_name = cmd_name); }break; + case RD_EvalSpaceKind_MetaTheme: + { + String8 name = e_string_from_id(eval.value.u64); + rd_cmd(RD_CmdKind_CompleteQuery, .string = name); + }break; } // rjf: if we do not have a specific command, then we can just @@ -5754,11 +5759,8 @@ rd_window_frame(void) { HS_Scope *hs_scope = hs_scope_open(); - //- rjf: for this window, scan upwards, and then try the project, then the user, until we - // find explicit preset / colors trees in the config. we will prefer the tightest ones, so - // that windows can have their own colors, and have those override higher-up settings. - RD_Cfg *preset_cfg = &rd_nil_cfg; - RD_Cfg *file_cfg = &rd_nil_cfg; + //- rjf: try to find theme settings from the project, then the user. + RD_Cfg *theme_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; RD_Cfg *theme_parents[] = { @@ -5774,20 +5776,12 @@ rd_window_frame(void) for EachIndex(idx, theme_parents_count) { RD_Cfg *parent_cfg = theme_parents[idx]; - if(preset_cfg == &rd_nil_cfg) + if(theme_cfg == &rd_nil_cfg) { - RD_Cfg *possible_preset_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme_preset")); - if(possible_preset_cfg != &rd_nil_cfg) + RD_Cfg *possible_theme_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme")); + if(possible_theme_cfg != &rd_nil_cfg) { - preset_cfg = possible_preset_cfg; - } - } - if(file_cfg == &rd_nil_cfg) - { - RD_Cfg *possible_file_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme_file")); - if(possible_file_cfg != &rd_nil_cfg) - { - file_cfg = possible_file_cfg; + theme_cfg = possible_theme_cfg; } } for(RD_Cfg *child = parent_cfg->first; child != &rd_nil_cfg; child = child->next) @@ -5799,36 +5793,36 @@ rd_window_frame(void) } } - //- rjf: map the preset config to the associated preset tree - MD_Node *preset_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; - if(preset_cfg != &rd_nil_cfg) + //- rjf: map the theme config to the associated tree (either from a preset, or from a file) + MD_Node *theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; + if(theme_cfg != &rd_nil_cfg) { - String8 preset_name = preset_cfg->first->string; - for EachEnumVal(RD_ThemePreset, p) + String8 theme_name = theme_cfg->first->string; + if(theme_name.size != 0) { - if(str8_match(preset_name, rd_theme_preset_code_string_table[p], 0)) + for EachEnumVal(RD_ThemePreset, p) { - preset_tree = rd_state->theme_preset_trees[p]; - break; + if(str8_match(theme_name, rd_theme_preset_display_string_table[p], 0)) + { + theme_tree = rd_state->theme_preset_trees[p]; + break; + } + } + if(theme_tree == &md_nil_node) + { + String8 path = push_str8f(scratch.arena, "%S/raddbg/themes/%S", os_get_process_info()->user_program_data_path, theme_name); + U64 endt_us = os_now_microseconds()+100; + if(ws->frames_alive == 0) + { + endt_us = os_now_microseconds()+50000; + } + U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us); + String8 data = hs_data_from_hash(hs_scope, hash); + theme_tree = md_tree_from_string(scratch.arena, data); } } } - //- rjf: map the file config to the associated theme file parse - MD_Node *file_tree = &md_nil_node; - if(file_cfg != &rd_nil_cfg) - { - String8 path = file_cfg->first->string; - U64 endt_us = os_now_microseconds()+100; - if(ws->frames_alive == 0) - { - endt_us = os_now_microseconds()+50000; - } - U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us); - String8 data = hs_data_from_hash(hs_scope, hash); - file_tree = md_tree_from_string(scratch.arena, data); - } - //- rjf: build tasks for color applications - each task comprises of a metadesk // tree, describing the color patterns typedef struct ThemeTask ThemeTask; @@ -5837,7 +5831,7 @@ rd_window_frame(void) ThemeTask *next; MD_Node *tree; }; - ThemeTask start_task = {0, !md_node_is_nil(file_tree) ? file_tree : preset_tree}; + ThemeTask start_task = {0, theme_tree}; ThemeTask *first_task = &start_task; ThemeTask *last_task = first_task; { @@ -14666,8 +14660,8 @@ rd_frame(void) case RD_CmdKind_OpenTheme: { RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *theme_file = rd_cfg_child_from_string_or_alloc(user, str8_lit("theme_file")); - rd_cfg_new_replace(theme_file, rd_regs()->file_path); + RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(user, str8_lit("theme")); + rd_cfg_new_replace(theme, rd_regs()->string); }break; case RD_CmdKind_AddThemeColor: { From a140197fcd1931f0e96b49484bcd06216d7ec429 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 16:20:17 -0700 Subject: [PATCH 550/755] crazier union test --- src/mule/mule_main.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f92d5f89..7e387698 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -257,6 +257,44 @@ raddbg_type_view(Discriminated_Union, kind == Kind.Fourth ? fourth : $); +struct Crazy_Union +{ + Kind kind; + union + { + struct + { + int first_and_third__x; + int first_and_third__y; + int first_and_third__z; + } first_and_third; + struct + { + char *second__name; + Pair second__pairs[16]; + } second; + }; + union + { + struct + { + char *first__name; + int first__x; + } first; + struct + { + char *third__name; + Function_Few_Params_Type *third__few_params; + } third; + }; +}; +raddbg_type_view(Crazy_Union, + kind == Kind.First ? only($, first_and_third, first) : + kind == Kind.Second ? only($, second) : + kind == Kind.Third ? only($, first_and_third, third) : + kind == Kind.Fourth ? kind : + $); + struct Linked_List{ Linked_List *next; Linked_List *prev; @@ -415,6 +453,13 @@ type_coverage_eval_tests(void) Has_Enums has_enums = {(Kind)4, (Flag)7}; + Crazy_Union crazy_union = {0}; + + crazy_union.kind = Kind_First; + crazy_union.kind = Kind_Second; + crazy_union.kind = Kind_Third; + crazy_union.kind = Kind_Fourth; + Discriminated_Union discriminated_union = {0}; discriminated_union.kind = Kind_First; From 293738e084af2f141e3ce42977965ad5c7b3d6f2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 16:25:01 -0700 Subject: [PATCH 551/755] parameterize open-theme path correctly by parent bucket, rather than assuming user --- src/raddbg/raddbg_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a0564612..66d6dde6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14659,8 +14659,8 @@ rd_frame(void) //- rjf: themes case RD_CmdKind_OpenTheme: { - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(user, str8_lit("theme")); + RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); rd_cfg_new_replace(theme, rd_regs()->string); }break; case RD_CmdKind_AddThemeColor: From 2835706d3d502ac79336fa37364eac566c68bd3d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 2 May 2025 20:44:50 -0700 Subject: [PATCH 552/755] 4coder theme --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 71 +++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a59d0e98..2c65cda9 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -975,7 +975,7 @@ str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background,value: 0xc0c0cff}\n theme_color:{tags: \"alt background\", value: 0x131313ff}\n theme_color:{tags: \"pop background\", value: 0x4c00ff}\n theme_color:{tags: \"fresh background\", value: 0x4c00ff}\n theme_color:{tags: \"match background\", value: 0x4c00ff}\n theme_color:{tags: border, value: 0x272727ff}\n theme_color:{tags: text, value: 0x90b080ff}\n theme_color:{tags: \"weak text\", value: 0x6b845fff}\n theme_color:{tags: \"menu_bar background\", value: 0x888888ff}\n theme_color:{tags: \"menu_bar text\", value: 0x20202ff}\n theme_color:{tags: \"menu_bar text weak\", value: 0x525252ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xee00ff}\n theme_color:{tags: \"focus overlay\", value: 0xee0012}\n theme_color:{tags: \"focus border\", value: 0x00ee00ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x4900ff}\n theme_color:{tags: \"good_pop border\", value: 0x4900ff}\n theme_color:{tags: \"bad_pop background\", value: 0x430b00ff}\n theme_color:{tags: code_default, value: 0x90b080ff}\n theme_color:{tags: code_symbol, value: 0xbfd9b2ff}\n theme_color:{tags: code_type, value: 0xbfd9b2ff}\n theme_color:{tags: code_local, value: 0xbfd9b2ff}\n theme_color:{tags: code_register, value: 0xb84cffff}\n theme_color:{tags: code_keyword, value: 0xd08f1fff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff}\n theme_color:{tags: code_numeric, value: 0x50ff2fff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff}\n theme_color:{tags: code_string, value: 0x50ff2fff}\n theme_color:{tags: code_meta, value: 0x90b080ff}\n theme_color:{tags: code_comment, value: 0x1f90f0ff}\n theme_color:{tags: line_info_0, value: 0xa253dff}\n theme_color:{tags: line_info_1, value: 0x9103dff}\n theme_color:{tags: line_info_2, value: 0x1e083dff}\n theme_color:{tags: line_info_3, value: 0x1e083dff}\n theme_color:{tags: thread_0, value: 0xd08f1fff}\n theme_color:{tags: thread_1, value: 0x1ea5d0ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x1d1d1dff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x15490cff}\n theme_color:{tags: \"tab border\", value: 0x15490cff}\n theme_color:{tags: \"tab text\", value: 0x90b080ff}\n theme_color:{tags: \"tab text weak\", value: 0x90b080ff}\n theme_color:{tags: \"tab inactive background\", value: 0x21321eff}\n theme_color:{tags: \"tab inactive border\", value: 0x21321eff}\n theme_color:{tags: \"tab auto background\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto border\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x47382eff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x47382eff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" , value: 0x232929ff }\n theme_color:{ tags: \"pop background\" , value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x485347ff }\n theme_color:{ tags: text , value: 0xffffffff }\n theme_color:{ tags: \"weak text\" , value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" , value: 0xfda200ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0 }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xad8b69ff }\n theme_color:{ tags: code_symbol , value: 0x87ad6aff }\n theme_color:{ tags: code_type , value: 0xb67474ff }\n theme_color:{ tags: code_local , value: 0xe9bf95ff }\n theme_color:{ tags: code_register , value: 0xa688b2ff }\n theme_color:{ tags: code_keyword , value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff }\n theme_color:{ tags: code_numeric , value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff }\n theme_color:{ tags: code_string , value: 0x98b19eff }\n theme_color:{ tags: code_meta , value: 0xad5979ff }\n theme_color:{ tags: code_comment , value: 0x52675dff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffc258ff }\n theme_color:{ tags: thread_1 , value: 0x82d331ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" , value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 716ad1b4..aec22d17 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1634,7 +1634,76 @@ RD_ThemePresetTable: { SolarizedDark solarized_dark "Solarized (Dark)" } { SolarizedLight solarized_light "Solarized (Light)" } { HandmadeHero handmade_hero "Handmade Hero" } - { FourCoder four_coder "4coder" } + + //- rjf: 4coder theme + { FourCoder four_coder "4coder", + ```theme: + { + theme_color:{tags: background,value: 0xc0c0cff} + theme_color:{tags: "alt background", value: 0x131313ff} + theme_color:{tags: "pop background", value: 0x4c00ff} + theme_color:{tags: "fresh background", value: 0x4c00ff} + theme_color:{tags: "match background", value: 0x4c00ff} + theme_color:{tags: border, value: 0x272727ff} + theme_color:{tags: text, value: 0x90b080ff} + theme_color:{tags: "weak text", value: 0x6b845fff} + theme_color:{tags: "menu_bar background", value: 0x888888ff} + theme_color:{tags: "menu_bar text", value: 0x20202ff} + theme_color:{tags: "menu_bar text weak", value: 0x525252ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: hover, value: 0xee00ff} + theme_color:{tags: "focus overlay", value: 0xee0012} + theme_color:{tags: "focus border", value: 0x00ee00ff} + theme_color:{tags: cursor, value: 0x00ee00ff} + theme_color:{tags: selection, value: 0x99ccff0f} + theme_color:{tags: "inactive background", value: 0x0000002f} + theme_color:{tags: drop_shadow, value: 0x0000007f} + theme_color:{tags: "good_pop background", value: 0x4900ff} + theme_color:{tags: "good_pop border", value: 0x4900ff} + theme_color:{tags: "bad_pop background", value: 0x430b00ff} + theme_color:{tags: code_default, value: 0x90b080ff} + theme_color:{tags: code_symbol, value: 0xbfd9b2ff} + theme_color:{tags: code_type, value: 0xbfd9b2ff} + theme_color:{tags: code_local, value: 0xbfd9b2ff} + theme_color:{tags: code_register, value: 0xb84cffff} + theme_color:{tags: code_keyword, value: 0xd08f1fff} + theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff} + theme_color:{tags: code_numeric, value: 0x50ff2fff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff} + theme_color:{tags: code_string, value: 0x50ff2fff} + theme_color:{tags: code_meta, value: 0x90b080ff} + theme_color:{tags: code_comment, value: 0x1f90f0ff} + theme_color:{tags: line_info_0, value: 0xa253dff} + theme_color:{tags: line_info_1, value: 0x9103dff} + theme_color:{tags: line_info_2, value: 0x1e083dff} + theme_color:{tags: line_info_3, value: 0x1e083dff} + theme_color:{tags: thread_0, value: 0xd08f1fff} + theme_color:{tags: thread_1, value: 0x1ea5d0ff} + theme_color:{tags: thread_unwound, value: 0xb2ccd8ff} + theme_color:{tags: thread_error, value: 0xb23219ff} + theme_color:{tags: breakpoint, value: 0xa72911ff} + theme_color:{tags: "scroll_bar background", value: 0x1d1d1dff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0x15490cff} + theme_color:{tags: "tab border", value: 0x15490cff} + theme_color:{tags: "tab text", value: 0x90b080ff} + theme_color:{tags: "tab text weak", value: 0x90b080ff} + theme_color:{tags: "tab inactive background", value: 0x21321eff} + theme_color:{tags: "tab inactive border", value: 0x21321eff} + theme_color:{tags: "tab auto background", value: 0x674f3eff} + theme_color:{tags: "tab auto border", value: 0x674f3eff} + theme_color:{tags: "tab auto inactive background", value: 0x47382eff} + theme_color:{tags: "tab auto inactive border", value: 0x47382eff} + theme_color:{tags: "drop_site background", value: 0xffffff05} + theme_color:{tags: "drop_site border", value: 0xffffff0f} + } + ``` + } //- rjf: grove theme { Grove grove "Grove", From d3a60e1808ee502662d1efc96a69cdc72f6e47cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 05:30:16 -0700 Subject: [PATCH 553/755] solarized dark theme --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 72 +++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2c65cda9..da254a36 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -972,7 +972,7 @@ str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff }\n theme_color:{ tags: \"alt background\" , value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" , value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" , value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" , value: 0xeaddceff }\n theme_color:{ tags: \"match background\" , value: 0xc1e9c4ff }\n theme_color:{ tags: border , value: 0xcbcbcbff }\n theme_color:{ tags: text , value: 0xff }\n theme_color:{ tags: \"weak text\" , value: 0x727272ff }\n theme_color:{ tags: \"good text\" , value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" , value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" , value: 0x972717ff }\n theme_color:{ tags: hover , value: 0xff }\n theme_color:{ tags: \"focus overlay\" , value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" , value: 0x67ffff }\n theme_color:{ tags: cursor , value: 0xff }\n theme_color:{ tags: selection , value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" , value: 0x8 }\n theme_color:{ tags: drop_shadow , value: 0xb }\n theme_color:{ tags: \"good_pop background\" , value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" , value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" , value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0x80808ff }\n theme_color:{ tags: code_symbol , value: 0x4ac3ff }\n theme_color:{ tags: code_type , value: 0xf46200ff }\n theme_color:{ tags: code_local , value: 0x317c00ff }\n theme_color:{ tags: code_register , value: 0x9a00ffff }\n theme_color:{ tags: code_keyword , value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric , value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff }\n theme_color:{ tags: code_string , value: 0x63549fff }\n theme_color:{ tags: code_meta , value: 0xd96759ff }\n theme_color:{ tags: code_comment , value: 0x717171ff }\n theme_color:{ tags: line_info_0 , value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 , value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 , value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 , value: 0xba917eff }\n theme_color:{ tags: thread_0 , value: 0xffa700ff }\n theme_color:{ tags: thread_1 , value: 0xb41fff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" , value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" , value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" , value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" , value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" , value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" , value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" , value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" , value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"tab background\" , value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" , value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" , value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" , value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" , value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x002a35ff}\n theme_color:{tags: \"alt background\", value: 0x053542ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x65166ff}\n theme_color:{tags: text, value: 0xeee8d5ff}\n theme_color:{tags: \"weak text\", value: 0x93a1a1ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xca4b16ff}\n theme_color:{tags: \"focus overlay\", value: 0xca4b151f}\n theme_color:{tags: \"focus border\", value: 0xca4b16ff}\n theme_color:{tags: cursor, value: 0xca4b16ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x5f8700ff}\n theme_color:{tags: \"good_pop border\", value: 0x5f8700ff}\n theme_color:{tags: \"bad_pop background\", value: 0x810000ff}\n theme_color:{tags: code_default, value: 0x839496ff}\n theme_color:{tags: code_symbol, value: 0xb3880eff}\n theme_color:{tags: code_type, value: 0xb3880eff}\n theme_color:{tags: code_local, value: 0xeee8d5ff}\n theme_color:{tags: code_register, value: 0xeee8d5ff}\n theme_color:{tags: code_keyword, value: 0x849804ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff}\n theme_color:{tags: code_numeric, value: 0x2aa198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff}\n theme_color:{tags: code_string, value: 0x2aa198ff}\n theme_color:{tags: code_meta, value: 0xca4b16ff}\n theme_color:{tags: code_comment, value: 0x586e75ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x2a3574}\n theme_color:{tags: \"floating background alt\", value: 0x4f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x586e75ff}\n theme_color:{tags: \"tab border\", value: 0x90abb3ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x33494fff}\n theme_color:{tags: \"tab auto background\", value: 0x565ed2ff}\n theme_color:{tags: \"tab auto border\", value: 0xa2a6dfff}\n theme_color:{tags: \"tab auto inactive background\", value: 0}\n theme_color:{tags: \"tab auto inactive border\", value: 0x595fbcff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("theme:\n{\n theme_color:{tags: background,value: 0xc0c0cff}\n theme_color:{tags: \"alt background\", value: 0x131313ff}\n theme_color:{tags: \"pop background\", value: 0x4c00ff}\n theme_color:{tags: \"fresh background\", value: 0x4c00ff}\n theme_color:{tags: \"match background\", value: 0x4c00ff}\n theme_color:{tags: border, value: 0x272727ff}\n theme_color:{tags: text, value: 0x90b080ff}\n theme_color:{tags: \"weak text\", value: 0x6b845fff}\n theme_color:{tags: \"menu_bar background\", value: 0x888888ff}\n theme_color:{tags: \"menu_bar text\", value: 0x20202ff}\n theme_color:{tags: \"menu_bar text weak\", value: 0x525252ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xee00ff}\n theme_color:{tags: \"focus overlay\", value: 0xee0012}\n theme_color:{tags: \"focus border\", value: 0x00ee00ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x4900ff}\n theme_color:{tags: \"good_pop border\", value: 0x4900ff}\n theme_color:{tags: \"bad_pop background\", value: 0x430b00ff}\n theme_color:{tags: code_default, value: 0x90b080ff}\n theme_color:{tags: code_symbol, value: 0xbfd9b2ff}\n theme_color:{tags: code_type, value: 0xbfd9b2ff}\n theme_color:{tags: code_local, value: 0xbfd9b2ff}\n theme_color:{tags: code_register, value: 0xb84cffff}\n theme_color:{tags: code_keyword, value: 0xd08f1fff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff}\n theme_color:{tags: code_numeric, value: 0x50ff2fff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff}\n theme_color:{tags: code_string, value: 0x50ff2fff}\n theme_color:{tags: code_meta, value: 0x90b080ff}\n theme_color:{tags: code_comment, value: 0x1f90f0ff}\n theme_color:{tags: line_info_0, value: 0xa253dff}\n theme_color:{tags: line_info_1, value: 0x9103dff}\n theme_color:{tags: line_info_2, value: 0x1e083dff}\n theme_color:{tags: line_info_3, value: 0x1e083dff}\n theme_color:{tags: thread_0, value: 0xd08f1fff}\n theme_color:{tags: thread_1, value: 0x1ea5d0ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x1d1d1dff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x15490cff}\n theme_color:{tags: \"tab border\", value: 0x15490cff}\n theme_color:{tags: \"tab text\", value: 0x90b080ff}\n theme_color:{tags: \"tab text weak\", value: 0x90b080ff}\n theme_color:{tags: \"tab inactive background\", value: 0x21321eff}\n theme_color:{tags: \"tab inactive border\", value: 0x21321eff}\n theme_color:{tags: \"tab auto background\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto border\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x47382eff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x47382eff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index aec22d17..a5783333 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1631,7 +1631,77 @@ RD_ThemePresetTable: //- rjf: to-do { VSLight vs_light "VS (Light)" } - { SolarizedDark solarized_dark "Solarized (Dark)" } + + //- rjf: solarized (dark) theme + { SolarizedDark solarized_dark "Solarized (Dark)", + ```theme: + { + theme_color:{tags: background, value: 0x002a35ff} + theme_color:{tags: "alt background", value: 0x053542ff} + theme_color:{tags: "pop background", value: 0x355b6eff} + theme_color:{tags: "fresh background", value: 0x31393dff} + theme_color:{tags: "match background", value: 0x31393dff} + theme_color:{tags: border, value: 0x65166ff} + theme_color:{tags: text, value: 0xeee8d5ff} + theme_color:{tags: "weak text", value: 0x93a1a1ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: hover, value: 0xca4b16ff} + theme_color:{tags: "focus overlay", value: 0xca4b151f} + theme_color:{tags: "focus border", value: 0xca4b16ff} + theme_color:{tags: cursor, value: 0xca4b16ff} + theme_color:{tags: selection, value: 0x99ccff0f} + theme_color:{tags: "inactive background", value: 0x0000002f} + theme_color:{tags: drop_shadow, value: 0x0000007f} + theme_color:{tags: "good_pop background", value: 0x5f8700ff} + theme_color:{tags: "good_pop border", value: 0x5f8700ff} + theme_color:{tags: "bad_pop background", value: 0x810000ff} + theme_color:{tags: code_default, value: 0x839496ff} + theme_color:{tags: code_symbol, value: 0xb3880eff} + theme_color:{tags: code_type, value: 0xb3880eff} + theme_color:{tags: code_local, value: 0xeee8d5ff} + theme_color:{tags: code_register, value: 0xeee8d5ff} + theme_color:{tags: code_keyword, value: 0x849804ff} + theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff} + theme_color:{tags: code_numeric, value: 0x2aa198ff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff} + theme_color:{tags: code_string, value: 0x2aa198ff} + theme_color:{tags: code_meta, value: 0xca4b16ff} + theme_color:{tags: code_comment, value: 0x586e75ff} + theme_color:{tags: line_info_0, value: 0x4f3022ff} + theme_color:{tags: line_info_1, value: 0x4f3e15ff} + theme_color:{tags: line_info_2, value: 0x434e2aff} + theme_color:{tags: line_info_3, value: 0x36241fff} + theme_color:{tags: thread_0, value: 0xffcb7fff} + theme_color:{tags: thread_1, value: 0xb2ff65ff} + theme_color:{tags: thread_unwound, value: 0xb2ccd8ff} + theme_color:{tags: thread_error, value: 0xb23219ff} + theme_color:{tags: breakpoint, value: 0xa72911ff} + theme_color:{tags: "floating background", value: 0x2a3574} + theme_color:{tags: "floating background alt", value: 0x4f} + theme_color:{tags: "floating background fresh", value: 0x31393d5f} + theme_color:{tags: "floating scroll_bar background", value: 0x53542ff} + theme_color:{tags: "scroll_bar background", value: 0x53542ff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0x586e75ff} + theme_color:{tags: "tab border", value: 0x90abb3ff} + theme_color:{tags: "tab inactive background", value: 0x0} + theme_color:{tags: "tab inactive border", value: 0x33494fff} + theme_color:{tags: "tab auto background", value: 0x565ed2ff} + theme_color:{tags: "tab auto border", value: 0xa2a6dfff} + theme_color:{tags: "tab auto inactive background", value: 0} + theme_color:{tags: "tab auto inactive border", value: 0x595fbcff} + theme_color:{tags: "drop_site background", value: 0xffffff05} + theme_color:{tags: "drop_site border", value: 0xffffff0f} + } + ``` + } + + //- rjf: todo { SolarizedLight solarized_light "Solarized (Light)" } { HandmadeHero handmade_hero "Handmade Hero" } From fe7bd82bda521a7afef07c977316b8656fcedb73 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 05:52:56 -0700 Subject: [PATCH 554/755] handmade hero theme --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 80 +++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index da254a36..9d7b3c61 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -974,7 +974,7 @@ str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff str8_lit_comp(""), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x002a35ff}\n theme_color:{tags: \"alt background\", value: 0x053542ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x65166ff}\n theme_color:{tags: text, value: 0xeee8d5ff}\n theme_color:{tags: \"weak text\", value: 0x93a1a1ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xca4b16ff}\n theme_color:{tags: \"focus overlay\", value: 0xca4b151f}\n theme_color:{tags: \"focus border\", value: 0xca4b16ff}\n theme_color:{tags: cursor, value: 0xca4b16ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x5f8700ff}\n theme_color:{tags: \"good_pop border\", value: 0x5f8700ff}\n theme_color:{tags: \"bad_pop background\", value: 0x810000ff}\n theme_color:{tags: code_default, value: 0x839496ff}\n theme_color:{tags: code_symbol, value: 0xb3880eff}\n theme_color:{tags: code_type, value: 0xb3880eff}\n theme_color:{tags: code_local, value: 0xeee8d5ff}\n theme_color:{tags: code_register, value: 0xeee8d5ff}\n theme_color:{tags: code_keyword, value: 0x849804ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff}\n theme_color:{tags: code_numeric, value: 0x2aa198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff}\n theme_color:{tags: code_string, value: 0x2aa198ff}\n theme_color:{tags: code_meta, value: 0xca4b16ff}\n theme_color:{tags: code_comment, value: 0x586e75ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x2a3574}\n theme_color:{tags: \"floating background alt\", value: 0x4f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x586e75ff}\n theme_color:{tags: \"tab border\", value: 0x90abb3ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x33494fff}\n theme_color:{tags: \"tab auto background\", value: 0x565ed2ff}\n theme_color:{tags: \"tab auto border\", value: 0xa2a6dfff}\n theme_color:{tags: \"tab auto inactive background\", value: 0}\n theme_color:{tags: \"tab auto inactive border\", value: 0x595fbcff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp(""), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x0c0c0cff}\n theme_color:{tags: \"alt background\", value: 0x161616ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x404040ff}\n theme_color:{tags: text, value: 0xcac1b6ff}\n theme_color:{tags: \"weak text\", value: 0xa08563ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0x7485971e}\n theme_color:{tags: \"focus border\", value: 0x5e6b79ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x2c5b36ff}\n theme_color:{tags: \"good_pop border\", value: 0x568761ff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0x803425ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0xa08563ff}\n theme_color:{tags: code_symbol, value: 0xcc5735ff}\n theme_color:{tags: code_type, value: 0xd8a51cff}\n theme_color:{tags: code_local, value: 0xd6b995ff}\n theme_color:{tags: code_register, value: 0xc04047ff}\n theme_color:{tags: code_keyword, value: 0xac7b0aff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x907553ff}\n theme_color:{tags: code_numeric, value: 0x6b8e23ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x4f681cff}\n theme_color:{tags: code_string, value: 0x6b8e23ff}\n theme_color:{tags: code_meta, value: 0xdab98fff}\n theme_color:{tags: code_comment, value: 0x686868ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x18181980}\n theme_color:{tags: \"floating background alt\", value: 0x0000005f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating border\", value: 0xbfbfbf1f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x3b3b3b5f}\n theme_color:{tags: \"floating scroll_bar border\", value: 0x5f5f5f5f}\n theme_color:{tags: \"menu_bar background\", value: 0x1f1f27ff}\n theme_color:{tags: \"menu_bar border\", value: 0x3d3d47ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x2b2b2bff}\n theme_color:{tags: \"scroll_bar border\", value: 0x3f3f3fff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab border\", value: 0x3d3d47ff}\n theme_color:{tags: \"tab text\", value: 0xca9301ff}\n theme_color:{tags: \"tab text weak\", value: 0x8c690eff}\n theme_color:{tags: \"tab inactive background\", value: 0x171718ff}\n theme_color:{tags: \"tab inactive border\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab auto background\", value: 0x243b38ff}\n theme_color:{tags: \"tab auto border\", value: 0x478980ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x102623ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x1e5850ff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background,value: 0xc0c0cff}\n theme_color:{tags: \"alt background\", value: 0x131313ff}\n theme_color:{tags: \"pop background\", value: 0x4c00ff}\n theme_color:{tags: \"fresh background\", value: 0x4c00ff}\n theme_color:{tags: \"match background\", value: 0x4c00ff}\n theme_color:{tags: border, value: 0x272727ff}\n theme_color:{tags: text, value: 0x90b080ff}\n theme_color:{tags: \"weak text\", value: 0x6b845fff}\n theme_color:{tags: \"menu_bar background\", value: 0x888888ff}\n theme_color:{tags: \"menu_bar text\", value: 0x20202ff}\n theme_color:{tags: \"menu_bar text weak\", value: 0x525252ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xee00ff}\n theme_color:{tags: \"focus overlay\", value: 0xee0012}\n theme_color:{tags: \"focus border\", value: 0x00ee00ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x4900ff}\n theme_color:{tags: \"good_pop border\", value: 0x4900ff}\n theme_color:{tags: \"bad_pop background\", value: 0x430b00ff}\n theme_color:{tags: code_default, value: 0x90b080ff}\n theme_color:{tags: code_symbol, value: 0xbfd9b2ff}\n theme_color:{tags: code_type, value: 0xbfd9b2ff}\n theme_color:{tags: code_local, value: 0xbfd9b2ff}\n theme_color:{tags: code_register, value: 0xb84cffff}\n theme_color:{tags: code_keyword, value: 0xd08f1fff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff}\n theme_color:{tags: code_numeric, value: 0x50ff2fff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff}\n theme_color:{tags: code_string, value: 0x50ff2fff}\n theme_color:{tags: code_meta, value: 0x90b080ff}\n theme_color:{tags: code_comment, value: 0x1f90f0ff}\n theme_color:{tags: line_info_0, value: 0xa253dff}\n theme_color:{tags: line_info_1, value: 0x9103dff}\n theme_color:{tags: line_info_2, value: 0x1e083dff}\n theme_color:{tags: line_info_3, value: 0x1e083dff}\n theme_color:{tags: thread_0, value: 0xd08f1fff}\n theme_color:{tags: thread_1, value: 0x1ea5d0ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x1d1d1dff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x15490cff}\n theme_color:{tags: \"tab border\", value: 0x15490cff}\n theme_color:{tags: \"tab text\", value: 0x90b080ff}\n theme_color:{tags: \"tab text weak\", value: 0x90b080ff}\n theme_color:{tags: \"tab inactive background\", value: 0x21321eff}\n theme_color:{tags: \"tab inactive border\", value: 0x21321eff}\n theme_color:{tags: \"tab auto background\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto border\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x47382eff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x47382eff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" , value: 0x232929ff }\n theme_color:{ tags: \"pop background\" , value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x485347ff }\n theme_color:{ tags: text , value: 0xffffffff }\n theme_color:{ tags: \"weak text\" , value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" , value: 0xfda200ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0 }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xad8b69ff }\n theme_color:{ tags: code_symbol , value: 0x87ad6aff }\n theme_color:{ tags: code_type , value: 0xb67474ff }\n theme_color:{ tags: code_local , value: 0xe9bf95ff }\n theme_color:{ tags: code_register , value: 0xa688b2ff }\n theme_color:{ tags: code_keyword , value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff }\n theme_color:{ tags: code_numeric , value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff }\n theme_color:{ tags: code_string , value: 0x98b19eff }\n theme_color:{ tags: code_meta , value: 0xad5979ff }\n theme_color:{ tags: code_comment , value: 0x52675dff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffc258ff }\n theme_color:{ tags: thread_1 , value: 0x82d331ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" , value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a5783333..c8ade46b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1703,7 +1703,85 @@ RD_ThemePresetTable: //- rjf: todo { SolarizedLight solarized_light "Solarized (Light)" } - { HandmadeHero handmade_hero "Handmade Hero" } + + //- rjf: handmade hero theme + { HandmadeHero handmade_hero "Handmade Hero", + ```theme: + { + theme_color:{tags: background, value: 0x0c0c0cff} + theme_color:{tags: "alt background", value: 0x161616ff} + theme_color:{tags: "pop background", value: 0x355b6eff} + theme_color:{tags: "fresh background", value: 0x31393dff} + theme_color:{tags: "match background", value: 0x31393dff} + theme_color:{tags: border, value: 0x404040ff} + theme_color:{tags: text, value: 0xcac1b6ff} + theme_color:{tags: "weak text", value: 0xa08563ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: hover, value: 0xffffffff} + theme_color:{tags: "focus overlay", value: 0x7485971e} + theme_color:{tags: "focus border", value: 0x5e6b79ff} + theme_color:{tags: cursor, value: 0x00ee00ff} + theme_color:{tags: selection, value: 0x99ccff0f} + theme_color:{tags: "inactive background", value: 0x0000002f} + theme_color:{tags: drop_shadow, value: 0x0000007f} + theme_color:{tags: "good_pop background", value: 0x2c5b36ff} + theme_color:{tags: "good_pop border", value: 0x568761ff} + theme_color:{tags: "good_pop hover", value: 0xe3f5d3ff} + theme_color:{tags: "good_pop weak text", value: 0xe3f5d3ff} + theme_color:{tags: "bad_pop background", value: 0x803425ff} + theme_color:{tags: "bad_pop hover", value: 0xff825cff} + theme_color:{tags: code_default, value: 0xa08563ff} + theme_color:{tags: code_symbol, value: 0xcc5735ff} + theme_color:{tags: code_type, value: 0xd8a51cff} + theme_color:{tags: code_local, value: 0xd6b995ff} + theme_color:{tags: code_register, value: 0xc04047ff} + theme_color:{tags: code_keyword, value: 0xac7b0aff} + theme_color:{tags: code_delimiter_or_operator, value: 0x907553ff} + theme_color:{tags: code_numeric, value: 0x6b8e23ff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x4f681cff} + theme_color:{tags: code_string, value: 0x6b8e23ff} + theme_color:{tags: code_meta, value: 0xdab98fff} + theme_color:{tags: code_comment, value: 0x686868ff} + theme_color:{tags: line_info_0, value: 0x4f3022ff} + theme_color:{tags: line_info_1, value: 0x4f3e15ff} + theme_color:{tags: line_info_2, value: 0x434e2aff} + theme_color:{tags: line_info_3, value: 0x36241fff} + theme_color:{tags: thread_0, value: 0xffcb7fff} + theme_color:{tags: thread_1, value: 0xb2ff65ff} + theme_color:{tags: thread_unwound, value: 0xb2ccd8ff} + theme_color:{tags: thread_error, value: 0xb23219ff} + theme_color:{tags: breakpoint, value: 0xa72911ff} + theme_color:{tags: "floating background", value: 0x18181980} + theme_color:{tags: "floating background alt", value: 0x0000005f} + theme_color:{tags: "floating background fresh", value: 0x31393d5f} + theme_color:{tags: "floating border", value: 0xbfbfbf1f} + theme_color:{tags: "floating scroll_bar background", value: 0x3b3b3b5f} + theme_color:{tags: "floating scroll_bar border", value: 0x5f5f5f5f} + theme_color:{tags: "menu_bar background", value: 0x1f1f27ff} + theme_color:{tags: "menu_bar border", value: 0x3d3d47ff} + theme_color:{tags: "scroll_bar background", value: 0x2b2b2bff} + theme_color:{tags: "scroll_bar border", value: 0x3f3f3fff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0x1f1f27ff} + theme_color:{tags: "tab border", value: 0x3d3d47ff} + theme_color:{tags: "tab text", value: 0xca9301ff} + theme_color:{tags: "tab text weak", value: 0x8c690eff} + theme_color:{tags: "tab inactive background", value: 0x171718ff} + theme_color:{tags: "tab inactive border", value: 0x1f1f27ff} + theme_color:{tags: "tab auto background", value: 0x243b38ff} + theme_color:{tags: "tab auto border", value: 0x478980ff} + theme_color:{tags: "tab auto inactive background", value: 0x102623ff} + theme_color:{tags: "tab auto inactive border", value: 0x1e5850ff} + theme_color:{tags: "drop_site background", value: 0xffffff05} + theme_color:{tags: "drop_site border", value: 0xffffff0f} + } + ``` + } //- rjf: 4coder theme { FourCoder four_coder "4coder", From dfd0fe3fcbd082932a8464c1f62c9cf4c2fea65a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 06:18:26 -0700 Subject: [PATCH 555/755] raddbg_markup: stl batteries-included basics --- src/lib_raddbg_markup/raddbg_markup.h | 22 ++++++++++++++++++++++ src/mule/mule_main.cpp | 11 ++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index f6c8a160..7be2bb31 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -12,6 +12,10 @@ # define RADDBG_MARKUP_VSNPRINTF vsnprintf #endif +#if !defined(RADDBG_MARKUP_STL_TYPE_VIEWS) +# define RADDBG_MARKUP_STL_TYPE_VIEWS 1 +#endif + //////////////////////////////// //~ Usage Macros @@ -383,4 +387,22 @@ raddbg_add_or_remove_breakpoint__impl(void *ptr, int set, int size, int r, int w #endif // defined(_WIN32) #endif // defined(RADDBG_MARKUP_IMPLEMENTATION) +//////////////////////////////// +//~ Win32 STL Type Views + +#if defined(_WIN32) && defined(RADDBG_MARKUP_IMPLEMENTATION) && RADDBG_MARKUP_STL_TYPE_VIEWS +# if defined(_VECTOR_) +raddbg_type_view(std::vector, slice(_Mypair._Myval2)); +# endif +# if defined(_MEMORY_) +raddbg_type_view(std::unique_ptr, _Mypair._Myval2); +# endif +# if defined(_STRING_) +raddbg_type_view(std::basic_string, _Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : _Mypair._Myval2._Bx._Ptr); +# endif +# if defined(_STRING_VIEW_) +// TODO(rjf) +# endif +#endif // defined(_WIN32) && defined(RADDBG_MARKUP_IMPLEMENTATION) && RADDBG_MARKUP_STL_TYPE_VIEWS + #endif // RADDBG_MARKUP_H diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 7e387698..36554a68 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -6,6 +6,9 @@ ** stepping, breakpoints, evaluation, cross-module calls. */ +#include +#include +#include #define RADDBG_MARKUP_IMPLEMENTATION #include "lib_raddbg_markup/raddbg_markup.h" @@ -103,13 +106,8 @@ void optimized_struct_parameters_eval_tests(void); //////////////////////////////// // NOTE(allen): Type Coverage Eval -#include -#include #include -raddbg_type_view(std::vector, slice(_Mypair._Myval2)); -raddbg_type_view(std::unique_ptr, _Mypair._Myval2); - struct Basics { char a; @@ -553,6 +551,9 @@ type_coverage_eval_tests(void) const int32_t y1 = -10; const int32_t z1 = x1 + y1; + std::string small_cplusplus_string = "smallstr"; + std::string cplusplus_string = "This is a C++ string!"; + std::vector int_vector; int_vector.push_back(1); int_vector.push_back(2); From edafc4d5c210c95408f9c7e7415da77d9053e112 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 09:19:48 -0700 Subject: [PATCH 556/755] batteries-included std::string_view --- src/lib_raddbg_markup/raddbg_markup.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 7be2bb31..98062318 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -398,10 +398,10 @@ raddbg_type_view(std::vector, slice(_Mypair._Myval2)); raddbg_type_view(std::unique_ptr, _Mypair._Myval2); # endif # if defined(_STRING_) -raddbg_type_view(std::basic_string, _Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : _Mypair._Myval2._Bx._Ptr); +raddbg_type_view(std::basic_string, _Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : array(_Mypair._Myval2._Bx._Ptr, _Mypair._Myval2._Mysize)); # endif # if defined(_STRING_VIEW_) -// TODO(rjf) +raddbg_type_view(std::basic_string_view, array(_Mydata, _Mysize)); # endif #endif // defined(_WIN32) && defined(RADDBG_MARKUP_IMPLEMENTATION) && RADDBG_MARKUP_STL_TYPE_VIEWS From ad8ae313f47c78eb189f426b895caaa9c8d20067 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 09:43:02 -0700 Subject: [PATCH 557/755] windows: clear unneeded working set pages shortly after startup/initialization --- src/raddbg/raddbg_core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 66d6dde6..10420269 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -16057,6 +16057,16 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: [windows] clear pages from working set shortly after startup, many of which will not be needed + // +#if OS_WINDOWS + if(rd_state->frame_index == 10) + { + SetProcessWorkingSetSize(GetCurrentProcess(), max_U64, max_U64); + } +#endif + scratch_end(scratch); ProfEnd(); } From 473f84cbda02e81ccd1fe2bd428aa47265eadda4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 16:17:10 -0700 Subject: [PATCH 558/755] flip priority of (handle, id) thread name events; prefer id if it is there, to correctly work with the set-suspended-thread-name-by-ID case --- src/ctrl/ctrl_core.c | 10 +++--- src/lib_raddbg_markup/raddbg_markup.h | 2 +- src/mule/mule_main.cpp | 52 +++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index f38dfc76..c5fce76f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1251,15 +1251,15 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) { CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); - if(thread != &ctrl_entity_nil) - { - ctrl_entity_equip_string(store, thread, event->string); - } - else + if(event->entity_id != 0) { CTRL_Entity *pending_name = ctrl_entity_alloc(store, process, CTRL_EntityKind_PendingThreadName, Arch_Null, ctrl_handle_zero(), event->entity_id); ctrl_entity_equip_string(store, pending_name, event->string); } + else if(thread != &ctrl_entity_nil) + { + ctrl_entity_equip_string(store, thread, event->string); + } }break; case CTRL_EventKind_ThreadColor: { diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 98062318..4b186079 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -209,7 +209,7 @@ raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint) static inline int raddbg_is_attached__impl(void) { - return !!raddbg_is_attached_byte_marker; + return !!raddbg_is_attached_byte_marker[0]; } static inline void diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 36554a68..645ee7cc 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -451,14 +451,14 @@ type_coverage_eval_tests(void) Has_Enums has_enums = {(Kind)4, (Flag)7}; - Crazy_Union crazy_union = {0}; + Crazy_Union crazy_union = {}; crazy_union.kind = Kind_First; crazy_union.kind = Kind_Second; crazy_union.kind = Kind_Third; crazy_union.kind = Kind_Fourth; - Discriminated_Union discriminated_union = {0}; + Discriminated_Union discriminated_union = {}; discriminated_union.kind = Kind_First; discriminated_union.first.x = 16; @@ -2580,6 +2580,52 @@ debug_string_tests(void) #endif } +//////////////////////////////// +//~ rjf: Thread Name Test + +#if _WIN32 +DWORD dummy_thread(void *p) +{ + Sleep(10); + return 0; +} +#endif + +static void +thread_name_tests(void) +{ +#if _WIN32 + DWORD id = 0; + HANDLE h = CreateThread(0, 0, dummy_thread, 0, CREATE_SUSPENDED, &id); + { +#pragma pack(push, 8) + typedef struct THREADNAME_INFO THREADNAME_INFO; + struct THREADNAME_INFO + { + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; + }; +#pragma pack(pop) + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = "dummy_thread"; + info.dwThreadID = id; + info.dwFlags = 0; + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); + } + __except(1) + { + } + } + ResumeThread(h); + WaitForSingleObject(h, INFINITE); +#endif +} + //////////////////////////////// //~ rjf: Interrupt Stepping Tests @@ -2946,6 +2992,8 @@ mule_main(int argc, char** argv) debug_string_tests(); + thread_name_tests(); + jit_stepping_tests(); interrupt_stepping_tests(); From 5086d1b3db0d39b36bd48b05e71fed49320d733e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 16:18:58 -0700 Subject: [PATCH 559/755] notes --- src/raddbg/raddbg_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index cfd0f1d0..8f00f15e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -183,6 +183,9 @@ // - Fixed an annoyance where the debugger would open a console window, even // for graphical programs, causing a flicker. // - Fixed substantial unnecessary memory usage with very large output logs. +// - Fixed a debugger regression which was incorrectly using thread name events +// when those events were sent to name a suspended thread by a different +// thread. (#430) // - Made several visual improvements. //////////////////////////////// From 8b7e7471f51201f20886cc0ee1e18b8fea0b678b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 16:45:45 -0700 Subject: [PATCH 560/755] markup: thread id based APIs for names/colors; handle names/colors-before-thread, or id-based application, in ctrl layer --- src/ctrl/ctrl.mdesk | 5 +- src/ctrl/ctrl_core.c | 70 +++++++++++++++++++++++---- src/ctrl/ctrl_core.h | 1 + src/ctrl/generated/ctrl.meta.c | 6 ++- src/ctrl/generated/ctrl.meta.h | 5 +- src/demon/win32/demon_core_win32.c | 3 +- src/lib_raddbg_markup/raddbg_markup.h | 65 +++++++++++++++---------- src/mule/mule_main.cpp | 26 +--------- src/raddbg/raddbg_main.c | 4 +- 9 files changed, 118 insertions(+), 67 deletions(-) diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index 5665654d..ceb2fca1 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -14,8 +14,9 @@ CTRL_EntityKindTable: {Module module "Module" } {EntryPoint entry_point "Entry Point" } {DebugInfoPath debug_info_path "Debug Info Path" } - {PendingThreadName pending_thread_name "Pending Thread Name" } - {Breakpoint breakpoint "Breakpoint" } + {PendingThreadName pending_thread_name "Pending Thread Name" } + {PendingThreadColor pending_thread_color "Pending Thread Color" } + {Breakpoint breakpoint "Breakpoint" } } @enum CTRL_EntityKind: diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index c5fce76f..1b9a4c48 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1023,6 +1023,21 @@ ctrl_process_from_entity(CTRL_Entity *entity) return result; } +internal CTRL_Entity * +ctrl_thread_from_id(CTRL_EntityStore *store, U64 id) +{ + CTRL_Entity *thread = &ctrl_entity_nil; + CTRL_EntityArray threads = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) + { + if(threads.v[idx]->id == id) + { + thread = threads.v[idx]; + } + } + return thread; +} + internal CTRL_Entity * ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr) { @@ -1239,6 +1254,17 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) break; } } + CTRL_EntityArray pending_thread_colors = ctrl_entity_array_from_kind(store, CTRL_EntityKind_PendingThreadColor); + for EachIndex(idx, pending_thread_colors.count) + { + CTRL_Entity *entity = pending_thread_colors.v[idx]; + if(entity->id == event->entity_id) + { + thread->rgba = entity->rgba; + ctrl_entity_release(store, entity); + break; + } + } thread->stack_base = event->stack_base; ctrl_query_cached_rip_from_thread(store, event->entity); }break; @@ -1250,21 +1276,46 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) case CTRL_EventKind_ThreadName: { CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); - if(event->entity_id != 0) + CTRL_Entity *thread = &ctrl_entity_nil; + if(event->entity_id == 0) + { + thread = ctrl_entity_from_handle(store, event->entity); + } + else + { + thread = ctrl_thread_from_id(store, event->entity_id); + } + if(thread != &ctrl_entity_nil) + { + ctrl_entity_equip_string(store, thread, event->string); + } + else { CTRL_Entity *pending_name = ctrl_entity_alloc(store, process, CTRL_EntityKind_PendingThreadName, Arch_Null, ctrl_handle_zero(), event->entity_id); ctrl_entity_equip_string(store, pending_name, event->string); } - else if(thread != &ctrl_entity_nil) - { - ctrl_entity_equip_string(store, thread, event->string); - } }break; case CTRL_EventKind_ThreadColor: { - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); - thread->rgba = event->rgba; + CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *thread = &ctrl_entity_nil; + if(event->entity_id == 0) + { + thread = ctrl_entity_from_handle(store, event->entity); + } + else + { + thread = ctrl_thread_from_id(store, event->entity_id); + } + if(thread != &ctrl_entity_nil) + { + thread->rgba = event->rgba; + } + else + { + CTRL_Entity *pending = ctrl_entity_alloc(store, process, CTRL_EntityKind_PendingThreadColor, Arch_Null, ctrl_handle_zero(), event->entity_id); + pending->rgba = event->rgba; + } }break; case CTRL_EventKind_ThreadFrozen: { @@ -4399,7 +4450,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->msg_id = msg->msg_id; out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); - out_evt->rgba = event->code; + out_evt->entity_id = event->code; + out_evt->rgba = event->user_data; }break; case DMN_EventKind_SetBreakpoint: { diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 73f6b2c2..86edf6c3 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -843,6 +843,7 @@ internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Hand internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); +internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityStore *store, U64 id); internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 87ed9c81..c7d5dd88 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 ctrl_entity_kind_code_name_table[10] = +String8 ctrl_entity_kind_code_name_table[11] = { {0}, str8_lit_comp("root"), @@ -15,10 +15,11 @@ str8_lit_comp("module"), str8_lit_comp("entry_point"), str8_lit_comp("debug_info_path"), str8_lit_comp("pending_thread_name"), +str8_lit_comp("pending_thread_color"), str8_lit_comp("breakpoint"), }; -String8 ctrl_entity_kind_display_string_table[10] = +String8 ctrl_entity_kind_display_string_table[11] = { {0}, str8_lit_comp("Root"), @@ -29,6 +30,7 @@ str8_lit_comp("Module"), str8_lit_comp("EntryPoint"), str8_lit_comp("DebugInfoPath"), str8_lit_comp("PendingThreadName"), +str8_lit_comp("PendingThreadColor"), str8_lit_comp("Breakpoint"), }; diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 14dfc6a8..56f7b8db 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -17,6 +17,7 @@ CTRL_EntityKind_Module, CTRL_EntityKind_EntryPoint, CTRL_EntityKind_DebugInfoPath, CTRL_EntityKind_PendingThreadName, +CTRL_EntityKind_PendingThreadColor, CTRL_EntityKind_Breakpoint, CTRL_EntityKind_COUNT, } CTRL_EntityKind; @@ -65,8 +66,8 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN -extern String8 ctrl_entity_kind_code_name_table[10]; -extern String8 ctrl_entity_kind_display_string_table[10]; +extern String8 ctrl_entity_kind_code_name_table[11]; +extern String8 ctrl_entity_kind_display_string_table[11]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38]; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 6480d200..bd6bfb6f 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2524,7 +2524,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR: { e->kind = DMN_EventKind_SetThreadColor; - e->code = exception->ExceptionInformation[1]; + e->code = exception->ExceptionInformation[0]; + e->user_data = exception->ExceptionInformation[1]; }break; //- rjf: fill set-data-breakpoint info diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 4b186079..9e639a4d 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -19,25 +19,15 @@ //////////////////////////////// //~ Usage Macros -#if defined(RADDBG_MARKUP_STUBS) -# define raddbg_is_attached(...) (0) -# define raddbg_thread_name(fmt, ...) ((void)0) -# define raddbg_thread_color_hex(hexcode) ((void)0) -# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) -# define raddbg_break(...) ((void)0) -# define raddbg_break_if(expr, ...) ((void)expr) -# define raddbg_watch(fmt, ...) ((void)0) -# define raddbg_pin(expr, ...) -# define raddbg_log(fmt, ...) ((void)0) -# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) -# define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) -#else +#if !defined(RADDBG_MARKUP_STUBS) # define raddbg_is_attached(...) raddbg_is_attached__impl() -# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_thread_id(...) raddbg_thread_id__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl(raddbg_thread_id(), (fmt), __VA_ARGS__) +# define raddbg_thread_id_name(id, fmt, ...) raddbg_thread_name__impl((id), (fmt), __VA_ARGS__) +# define raddbg_thread_color_u32(u32) raddbg_thread_color__impl(raddbg_thread_id(), (u32)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(raddbg_thread_id(), ((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_thread_id_color_u32(id, u32) raddbg_thread_color__impl((id), (u32)) +# define raddbg_thread_id_color_rgba(id, r, g, b, a) raddbg_thread_color__impl((id), ((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) # define raddbg_break(...) raddbg_break__impl() # define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) @@ -47,6 +37,24 @@ # define raddbg_type_view(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) +#else +# define raddbg_is_attached(...) (0) +# define raddbg_thread_id(...) ((void)0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_id_name(id, fmt, ...) ((void)0) +# define raddbg_thread_color_u32(u32) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_thread_id_color_u32(id, u32) ((void)0) +# define raddbg_thread_id_color_rgba(id, r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)expr) +# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_pin(expr, ...) +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) +# define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) #endif //////////////////////////////// @@ -212,8 +220,15 @@ raddbg_is_attached__impl(void) return !!raddbg_is_attached_byte_marker[0]; } +static inline int +raddbg_thread_id__impl(void) +{ + DWORD result = GetCurrentThreadId(); + return result; +} + static inline void -raddbg_thread_name__impl(char *fmt, ...) +raddbg_thread_name__impl(int id, char *fmt, ...) { // rjf: resolve variadic arguments char buffer[512] = {0}; @@ -247,7 +262,7 @@ raddbg_thread_name__impl(char *fmt, ...) } // rjf: set thread name, windows 10 style - if(SetThreadDescription_function) + if(SetThreadDescription_function && id == GetCurrentThreadId()) { WCHAR buffer16[1024] = {0}; int name_length = 0; @@ -277,7 +292,7 @@ raddbg_thread_name__impl(char *fmt, ...) THREADNAME_INFO info; info.dwType = 0x1000; info.szName = name; - info.dwThreadID = GetCurrentThreadId(); + info.dwThreadID = id; info.dwFlags = 0; #pragma warning(push) #pragma warning(disable: 6320 6322) @@ -293,7 +308,7 @@ raddbg_thread_name__impl(char *fmt, ...) } static inline void -raddbg_thread_color__impl(unsigned int hexcode) +raddbg_thread_color__impl(int id, unsigned int hexcode) { if(raddbg_is_attached()) { @@ -302,13 +317,13 @@ raddbg_thread_color__impl(unsigned int hexcode) struct RADDBG_ThreadColorInfo { DWORD dwThreadID; - DWORD _pad0_; + DWORD _pad_0; DWORD rgba; - DWORD _pad1_; + DWORD _pad_1; }; #pragma pack(pop) RADDBG_ThreadColorInfo info; - info.dwThreadID = GetCurrentThreadId(); + info.dwThreadID = id; info.rgba = hexcode; #pragma warning(push) #pragma warning(disable: 6320 6322) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 645ee7cc..d5b43817 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2597,30 +2597,8 @@ thread_name_tests(void) #if _WIN32 DWORD id = 0; HANDLE h = CreateThread(0, 0, dummy_thread, 0, CREATE_SUSPENDED, &id); - { -#pragma pack(push, 8) - typedef struct THREADNAME_INFO THREADNAME_INFO; - struct THREADNAME_INFO - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - }; -#pragma pack(pop) - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = "dummy_thread"; - info.dwThreadID = id; - info.dwFlags = 0; - __try - { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); - } - __except(1) - { - } - } + raddbg_thread_id_name(id, "dummy_thread"); + raddbg_thread_id_color_u32(id, 0xff1f23ff); ResumeThread(h); WaitForSingleObject(h, INFINITE); #endif diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 8f00f15e..2a289b3b 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -164,8 +164,8 @@ // - `raddbg_log(format, ...)`, e.g. // `raddbg_log("This is a number: %i", 123)`: Writes a debug string for a // debugger to read and display in its UI. -// - `raddbg_thread_color_hex(hexcode)`, e.g. -// `raddbg_thread_color_hex(0xff0000ff)`: Sets the calling thread's color. +// - `raddbg_thread_color_u32(hexcode)`, e.g. +// `raddbg_thread_color_u32(0xff0000ff)`: Sets the calling thread's color. // - Also can be done with individual `[0, 1]` color components: // `raddbg_thread_color_rgba(1.f, 0.f, 0.f, 1.f)` // - `raddbg_pin()`, e.g. From 8fddc7b7125ba1c98e921a2c4c798d0272bc05f3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 16:53:57 -0700 Subject: [PATCH 561/755] markup: omit static in global raddbg-section data, since clang will strip it --- src/lib_raddbg_markup/raddbg_markup.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 9e639a4d..6a21c40d 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -33,8 +33,8 @@ # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) # define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ # define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) -# define raddbg_entry_point(...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") -# define raddbg_type_view(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") +# define raddbg_entry_point(...) raddbg_exe_data char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") +# define raddbg_type_view(type, ...) raddbg_exe_data char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) #else From 6c7568f946299be0ff8f52c692f2779d6daa4cf1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 16:56:54 -0700 Subject: [PATCH 562/755] fix out-of-date file rendering --- src/raddbg/raddbg_views.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3f8192bf..8c52ac57 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2066,7 +2066,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: build bottom bar // - if(!file_is_missing && key_has_data) UI_FontSize(main_font_size) + if(!file_is_missing && key_has_data) UI_FontSize(main_font_size) UI_TagF(file_is_out_of_date ? "bad_pop" : ".") { ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f))); ui_set_next_flags(UI_BoxFlag_DrawBackground); @@ -2075,7 +2075,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_PrefWidth(ui_text_dim(10, 1)) UI_TagF("weak") { - if(file_is_out_of_date) UI_TagF("bad_pop") + if(file_is_out_of_date) { UI_Box *box = &ui_nil_box; RD_Font(RD_FontSlot_Icons) @@ -2085,11 +2085,11 @@ RD_VIEW_UI_FUNCTION_DEF(text) UI_Signal sig = ui_signal_from_box(box); if(ui_hovering(sig)) UI_Tooltip { - UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1)) UI_TextPadding(0) { - ui_labelf("This file has changed since ", out_of_date_dbgi_name); + UI_TagF("weak") ui_labelf("This file has changed since "); ui_label(out_of_date_dbgi_name); - ui_labelf(" was produced."); + UI_TagF("weak") ui_labelf(" was produced."); } } } From 24148dd6720a829f12d03dd97a3aa179517dc7ee Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 3 May 2025 21:01:26 -0700 Subject: [PATCH 563/755] set up settings for enabling/disabling pre-packaged stl/ue type view rules; fill out basic stl ones --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 6 +++++ src/raddbg/raddbg_core.c | 42 +++++++++++++++++++++++++++++- src/raddbg/raddbg_core.h | 23 +++++++++------- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 9d7b3c61..53c9a85e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -400,7 +400,7 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { {str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index c8ade46b..184462e9 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -287,6 +287,12 @@ RD_VocabTable: { @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, + //- rjf: visualizers + @display_name('Use Default C++ STL Type Visualizers') @description("Enables the built-in type views for C++ STL types.") + @default(1) use_default_stl_type_views: bool, + @display_name('Use Default Unreal Engine Type Visualizers') @description("Enables the built-in type views for Unreal Engine types.") + @default(1) use_default_ue_type_views: bool, + //- rjf: theme @no_expand 'theme': string, @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 10420269..58aa88f6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11909,6 +11909,39 @@ rd_frame(void) } } + //////////////////////////// + //- rjf: construct default immediate-mode configs based on loaded modules + // + if(rd_state->use_default_stl_type_views) + { + local_persist read_only struct + { + String8 pattern; + String8 expr; + } + type_views[] = + { + { str8_lit_comp("std::vector"), str8_lit_comp("slice(_Mypair._Myval2)") }, + { str8_lit_comp("std::unique_ptr"), str8_lit_comp("_Mypair._Myval2") }, + { str8_lit_comp("std::basic_string"), str8_lit_comp("_Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : array(_Mypair._Myval2._Bx._Ptr, _Mypair._Myval2._Mysize)") }, + { str8_lit_comp("std::basic_string_view"), str8_lit_comp("array(_Mydata, _Mysize)") } + }; + for EachElement(idx, type_views) + { + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("default_stl_type_vis_%I64x", idx); + RD_Cfg *type_view = rd_cfg_child_from_string_or_alloc(immediate_root, str8_lit("type_view")); + RD_Cfg *type = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("type")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("expr")); + rd_cfg_new_replace(type, type_views[idx].pattern); + rd_cfg_new_replace(expr, type_views[idx].expr); + rd_cfg_list_push(scratch.arena, &immediate_type_views, type_view); + } + } + if(rd_state->use_default_ue_type_views) + { + // TODO(rjf) + } + //////////////////////////// //- rjf: add auto-hook rules for type views // @@ -11966,6 +11999,14 @@ rd_frame(void) } e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); + //////////////////////////// + //- rjf: evaluate unpacked settings (must be used earlier than this point in the frame, + // but cannot evaluate before this point, so we need to prep for next frame + // + rd_state->alt_menu_bar_enabled = rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt")); + rd_state->use_default_stl_type_views = rd_setting_b32_from_name(str8_lit("use_default_stl_type_views")); + rd_state->use_default_ue_type_views = rd_setting_b32_from_name(str8_lit("use_default_ue_type_views")); + //////////////////////////// //- rjf: autosave if needed // @@ -11982,7 +12023,6 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // - rd_state->alt_menu_bar_enabled = rd_setting_b32_from_name(str8_lit("focus_menu_bar_with_alt")); if(rd_state->frame_depth == 0) { for(;rd_next_cmd(&cmd);) RD_RegsScope() diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index d60372fb..fbf1eb1e 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -84,8 +84,8 @@ enum RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaQuery, RD_EvalSpaceKind_MetaCfg, - RD_EvalSpaceKind_MetaCmd, - RD_EvalSpaceKind_MetaTheme, + RD_EvalSpaceKind_MetaCmd, + RD_EvalSpaceKind_MetaTheme, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaUnattachedProcess, }; @@ -445,8 +445,8 @@ struct RD_WindowState Rng2F32 last_window_rect; // rjf: theme (recomputed each frame) - UI_Theme *theme; - Vec4F32 theme_code_colors[RD_CodeColorSlot_COUNT]; + UI_Theme *theme; + Vec4F32 theme_code_colors[RD_CodeColorSlot_COUNT]; // rjf: font raster flags (recomputed each frame) FNT_RasterFlags font_slot_raster_flags[RD_FontSlot_COUNT]; @@ -540,7 +540,6 @@ struct RD_State Arena *arena; B32 quit; B32 quit_after_success; - B32 alt_menu_bar_enabled; S32 frame_depth; U64 frame_eval_memread_endt_us; @@ -552,6 +551,12 @@ struct RD_State Arena *theme_path_arena; String8 theme_path; + // rjf: unpacked settings (cached, because they need to be used + // earlier than setting evaluation is legal in a frame) + B32 alt_menu_bar_enabled; + B32 use_default_stl_type_views; + B32 use_default_ue_type_views; + // rjf: serialized config debug string keys U128 user_cfg_string_key; U128 project_cfg_string_key; @@ -961,10 +966,10 @@ internal void rd_set_autocomp_regs_(RD_Regs *regs); //////////////////////////////// //~ rjf: Colors, Fonts, Config -//- rjf: colors -internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot); -internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind); -internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); +//- rjf: colors +internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot); +internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind); +internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); //- rjf: fonts internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); From 9b3a2c2428131f42aceca360c52a0a8c30a4337f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 4 May 2025 15:28:47 -0700 Subject: [PATCH 564/755] pull out decision of autocompletion list expression, so that we can begin basing it on destination evaluations; adjust top-level theme editing controls to be less annoying --- src/raddbg/generated/raddbg.meta.c | 29 ++++++++------ src/raddbg/generated/raddbg.meta.h | 14 ++++--- src/raddbg/raddbg.mdesk | 22 +++++----- src/raddbg/raddbg_core.c | 64 ++++++++++++++++++++++-------- src/raddbg/raddbg_core.h | 1 + 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 53c9a85e..64fec4e1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[333] = +RD_VocabInfo rd_vocab_info_table[334] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -349,9 +349,10 @@ RD_VocabInfo rd_vocab_info_table[333] = {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_type_view"), str8_lit_comp(""), str8_lit_comp("Add Type View"), str8_lit_comp(""), RD_IconKind_Binoculars}, {str8_lit_comp("add_file_path_map"), str8_lit_comp(""), str8_lit_comp("Add File Path Map"), str8_lit_comp(""), RD_IconKind_FileOutline}, -{str8_lit_comp("open_theme"), str8_lit_comp(""), str8_lit_comp("Open Theme"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("edit_user_theme"), str8_lit_comp(""), str8_lit_comp("Edit User Theme"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("edit_project_theme"), str8_lit_comp(""), str8_lit_comp("Edit Project Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, -{str8_lit_comp("fork_loaded_theme"), str8_lit_comp(""), str8_lit_comp("Fork Loaded Theme"), str8_lit_comp(""), RD_IconKind_Palette}, +{str8_lit_comp("fork_theme"), str8_lit_comp(""), str8_lit_comp("Fork Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("save_theme"), str8_lit_comp(""), str8_lit_comp("Save Theme"), str8_lit_comp(""), RD_IconKind_Save}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -399,9 +400,9 @@ RD_VocabInfo rd_vocab_info_table[333] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @no_expand 'theme': string,\n @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('User Theme') 'theme': string,\n @no_expand @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @display_name('Project Theme') 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -472,7 +473,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[226] = +RD_CmdKindInfo rd_cmd_kind_info_table[227] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -654,9 +655,10 @@ RD_CmdKindInfo rd_cmd_kind_info_table[226] = { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_type_view"), str8_lit_comp("Adds a new type view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_file_path_map"), str8_lit_comp("Adds a new file path map."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("open_theme"), str8_lit_comp("Opens a theme."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:themes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit_user_theme"), str8_lit_comp("Edits the current user's theme."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp("query:themes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("edit_project_theme"), str8_lit_comp("Edits the current project's theme."), str8_lit_comp("color"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp("query:themes"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("fork_loaded_theme"), str8_lit_comp("Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("fork_theme"), str8_lit_comp("Imports all colors from the current theme so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -938,8 +940,9 @@ str8_lit_comp("code_line_numbers"), str8_lit_comp("code_line_numbers_selected"), }; -String8 rd_theme_preset_display_string_table[10] = +String8 rd_theme_preset_display_string_table[11] = { +str8_lit_comp("None"), str8_lit_comp("Default (Dark)"), str8_lit_comp("Default (Light)"), str8_lit_comp("VS (Dark)"), @@ -952,8 +955,9 @@ str8_lit_comp("Grove"), str8_lit_comp("Far Manager"), }; -String8 rd_theme_preset_code_string_table[10] = +String8 rd_theme_preset_code_string_table[11] = { +str8_lit_comp("none"), str8_lit_comp("default_dark"), str8_lit_comp("default_light"), str8_lit_comp("vs_dark"), @@ -966,8 +970,9 @@ str8_lit_comp("grove"), str8_lit_comp("far_manager"), }; -String8 rd_theme_preset_cfg_string_table[10] = +String8 rd_theme_preset_cfg_string_table[11] = { +str8_lit_comp(""), str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus overlay\", value: 0xfda20012 }\n theme_color: {tags:\"focus border\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff }\n theme_color:{ tags: \"alt background\" , value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" , value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" , value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" , value: 0xeaddceff }\n theme_color:{ tags: \"match background\" , value: 0xc1e9c4ff }\n theme_color:{ tags: border , value: 0xcbcbcbff }\n theme_color:{ tags: text , value: 0xff }\n theme_color:{ tags: \"weak text\" , value: 0x727272ff }\n theme_color:{ tags: \"good text\" , value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" , value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" , value: 0x972717ff }\n theme_color:{ tags: hover , value: 0xff }\n theme_color:{ tags: \"focus overlay\" , value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" , value: 0x67ffff }\n theme_color:{ tags: cursor , value: 0xff }\n theme_color:{ tags: selection , value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" , value: 0x8 }\n theme_color:{ tags: drop_shadow , value: 0xb }\n theme_color:{ tags: \"good_pop background\" , value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" , value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" , value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0x80808ff }\n theme_color:{ tags: code_symbol , value: 0x4ac3ff }\n theme_color:{ tags: code_type , value: 0xf46200ff }\n theme_color:{ tags: code_local , value: 0x317c00ff }\n theme_color:{ tags: code_register , value: 0x9a00ffff }\n theme_color:{ tags: code_keyword , value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric , value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff }\n theme_color:{ tags: code_string , value: 0x63549fff }\n theme_color:{ tags: code_meta , value: 0xd96759ff }\n theme_color:{ tags: code_comment , value: 0x717171ff }\n theme_color:{ tags: line_info_0 , value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 , value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 , value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 , value: 0xba917eff }\n theme_color:{ tags: thread_0 , value: 0xffa700ff }\n theme_color:{ tags: thread_1 , value: 0xb41fff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" , value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" , value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" , value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" , value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" , value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" , value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" , value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" , value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"tab background\" , value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" , value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" , value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" , value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" , value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index d966c718..f00117db 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -236,9 +236,10 @@ RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, RD_CmdKind_AddTypeView, RD_CmdKind_AddFilePathMap, -RD_CmdKind_OpenTheme, +RD_CmdKind_EditUserTheme, +RD_CmdKind_EditProjectTheme, RD_CmdKind_AddThemeColor, -RD_CmdKind_ForkLoadedTheme, +RD_CmdKind_ForkTheme, RD_CmdKind_SaveTheme, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, @@ -387,6 +388,7 @@ RD_CodeColorSlot_COUNT, typedef enum RD_ThemePreset { +RD_ThemePreset_None, RD_ThemePreset_DefaultDark, RD_ThemePreset_DefaultLight, RD_ThemePreset_VSDark, @@ -559,16 +561,16 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[333]; +extern RD_VocabInfo rd_vocab_info_table[334]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; extern String8 rd_code_color_slot_name_table[14]; -extern String8 rd_theme_preset_display_string_table[10]; -extern String8 rd_theme_preset_code_string_table[10]; -extern String8 rd_theme_preset_cfg_string_table[10]; +extern String8 rd_theme_preset_display_string_table[11]; +extern String8 rd_theme_preset_code_string_table[11]; +extern String8 rd_theme_preset_cfg_string_table[11]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 184462e9..fae19138 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -220,7 +220,7 @@ RD_VocabTable: { user ``` - x: + @expand_commands(edit_user_theme) x: { //- rjf: animations @default(1) 'hover_animations': bool, @@ -237,8 +237,8 @@ RD_VocabTable: 'code_font': string, //- rjf: theme - @no_expand 'theme': string, - @display_name('User Theme') @description("The user's theme, which describes all colors used throughout the UI.") + @display_name('User Theme') 'theme': string, + @no_expand @display_name('User Theme') @description("The user's theme, which describes all colors used throughout the UI.") 'theme_colors': query, //- rjf: autocompletion @@ -283,7 +283,7 @@ RD_VocabTable: { project ``` - x: + @expand_commands(edit_project_theme) x: { @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64, @@ -294,8 +294,8 @@ RD_VocabTable: @default(1) use_default_ue_type_views: bool, //- rjf: theme - @no_expand 'theme': string, - @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") + @display_name('Project Theme') 'theme': string, + @no_expand @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") 'theme_colors': query, //- rjf: exception settings @@ -381,7 +381,7 @@ RD_VocabTable: { theme_color, ``` - @collection_commands(open_theme, add_theme_color, fork_loaded_theme, save_theme) + @collection_commands(add_theme_color, fork_theme, save_theme) @row_commands(duplicate_cfg, remove_cfg) x: { @@ -982,9 +982,10 @@ RD_CmdTable: // | | | | {AddFilePathMap 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "add_file_path_map" "Add File Path Map" "Adds a new file path map." "" "" } //- rjf: themes - {OpenTheme 0 0 0 0 "query:themes" String null Nil Null 1 0 0 0 0 1 1 Palette "open_theme" "Open Theme" "Opens a theme." "color" "" } + {EditUserTheme 0 0 0 0 "query:themes" String null Nil Null 0 0 0 0 0 0 0 Palette "edit_user_theme" "Edit User Theme" "Edits the current user's theme." "color" "" } + {EditProjectTheme 0 0 0 0 "query:themes" String null Nil Null 0 0 0 0 0 0 0 Palette "edit_project_theme" "Edit Project Theme" "Edits the current project's theme." "color" "" } {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } - {ForkLoadedTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_loaded_theme" "Fork Loaded Theme" "Imports all colors from the loaded color theme file or color theme preset, so they can be individually edited." "" "" } + {ForkTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_theme" "Fork Theme" "Imports all colors from the current theme so they can be individually edited." "" "" } {SaveTheme 0 0 0 0 "" String null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } //- rjf: line operations @@ -1364,6 +1365,9 @@ RD_IconTable: @table(name_upper name_lower display_string cfg) RD_ThemePresetTable: { + //- rjf: stub + {None none "None" ""} + //- rjf: default dark theme { DefaultDark default_dark "Default (Dark)", diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 58aa88f6..80222fb3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4962,10 +4962,15 @@ rd_view_ui(Rng2F32 rect) txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); + String8 list_expr = rd_autocomp_primary_list_expr_from_dst_eval(scratch.arena, cell->eval); RD_AutocompCursorInfo cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, input, cell_edit_state->cursor.column-1); + if(cursor_info.list_expr.size != 0) + { + list_expr = cursor_info.list_expr; + } rd_set_autocomp_regs(.ui_key = sig.box->key, .string = cursor_info.filter, - .expr = cursor_info.list_expr); + .expr = list_expr); } } } @@ -5760,28 +5765,26 @@ rd_window_frame(void) HS_Scope *hs_scope = hs_scope_open(); //- rjf: try to find theme settings from the project, then the user. - RD_Cfg *theme_cfg = &rd_nil_cfg; RD_CfgList colors_cfgs = {0}; RD_Cfg *theme_parents[] = { rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")), rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")) }; - U64 theme_parents_count = ArrayCount(theme_parents); - if(!rd_setting_b32_from_name(str8_lit("use_project_theme"))) + RD_Cfg *theme_cfgs[] = { - theme_parents[0] = theme_parents[1]; - theme_parents_count -= 1; - } - for EachIndex(idx, theme_parents_count) + &rd_nil_cfg, + &rd_nil_cfg, + }; + for EachIndex(idx, ArrayCount(theme_parents)) { RD_Cfg *parent_cfg = theme_parents[idx]; - if(theme_cfg == &rd_nil_cfg) + if(theme_cfgs[idx] == &rd_nil_cfg) { RD_Cfg *possible_theme_cfg = rd_cfg_child_from_string(parent_cfg, str8_lit("theme")); if(possible_theme_cfg != &rd_nil_cfg) { - theme_cfg = possible_theme_cfg; + theme_cfgs[idx] = possible_theme_cfg; } } for(RD_Cfg *child = parent_cfg->first; child != &rd_nil_cfg; child = child->next) @@ -5793,6 +5796,17 @@ rd_window_frame(void) } } + //- rjf: choose which theme cfg to use + RD_Cfg *theme_cfg = theme_cfgs[1]; + if(rd_setting_b32_from_name(str8_lit("use_project_theme"))) + { + theme_cfg = theme_cfgs[0]; + if(theme_cfg == &rd_nil_cfg || str8_match(theme_cfg->first->string, rd_theme_preset_display_string_table[RD_ThemePreset_None], 0)) + { + theme_cfg = theme_cfgs[1]; + } + } + //- rjf: map the theme config to the associated tree (either from a preset, or from a file) MD_Node *theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; if(theme_cfg != &rd_nil_cfg) @@ -5800,7 +5814,7 @@ rd_window_frame(void) String8 theme_name = theme_cfg->first->string; if(theme_name.size != 0) { - for EachEnumVal(RD_ThemePreset, p) + for EachNonZeroEnumVal(RD_ThemePreset, p) { if(str8_match(theme_name, rd_theme_preset_display_string_table[p], 0)) { @@ -9623,12 +9637,24 @@ rd_set_hover_eval(Vec2F32 pos, String8 string) //////////////////////////////// //~ rjf: Autocompletion Lister +internal String8 +rd_autocomp_primary_list_expr_from_dst_eval(Arena *arena, E_Eval dst_eval) +{ + String8 result = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); + { + if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) + { + result = str8_lit("query:themes"); + } + } + return result; +} + internal RD_AutocompCursorInfo rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off) { RD_AutocompCursorInfo result = {0}; { - result.list_expr = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); result.filter = input; result.replaced_range = r1u64(0, input.size); } @@ -14697,11 +14723,15 @@ rd_frame(void) }break; //- rjf: themes - case RD_CmdKind_OpenTheme: + case RD_CmdKind_EditUserTheme: { - RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); - RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); - rd_cfg_new_replace(theme, rd_regs()->string); + RD_Cfg *parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + rd_cmd(RD_CmdKind_PushQuery, .expr = push_str8f(scratch.arena, "query:config.$%I64x.theme_colors", parent->id)); + }break; + case RD_CmdKind_EditProjectTheme: + { + RD_Cfg *parent = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + rd_cmd(RD_CmdKind_PushQuery, .expr = push_str8f(scratch.arena, "query:config.$%I64x.theme_colors", parent->id)); }break; case RD_CmdKind_AddThemeColor: { @@ -14711,7 +14741,7 @@ rd_frame(void) RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); rd_cfg_new(value, str8_lit("0xffffffff")); }break; - case RD_CmdKind_ForkLoadedTheme: + case RD_CmdKind_ForkTheme: { RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index fbf1eb1e..e60b6611 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -959,6 +959,7 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //////////////////////////////// //~ rjf: Autocompletion Lister +internal String8 rd_autocomp_primary_list_expr_from_dst_eval(Arena *arena, E_Eval dst_eval); internal RD_AutocompCursorInfo rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off); internal void rd_set_autocomp_regs_(RD_Regs *regs); #define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) From 19acf2cdee3438ea4f2a2c22ba6ce04fd3bdffc4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 4 May 2025 16:57:50 -0700 Subject: [PATCH 565/755] checkpoint on final pre-release pass over 'fancy rows' (combined line edit, toggler, slider, etc. widget), plug autocompletion in for theme selection lister --- src/raddbg/generated/raddbg.meta.c | 13 ++-- src/raddbg/generated/raddbg.meta.h | 7 +- src/raddbg/raddbg.mdesk | 12 +-- src/raddbg/raddbg_core.c | 15 +++- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_views.c | 19 +++++ src/raddbg/raddbg_widgets.c | 121 ++++++++++++++++++++++++++--- src/raddbg/raddbg_widgets.h | 1 + 8 files changed, 156 insertions(+), 33 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 64fec4e1..3d6fe3db 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -400,8 +400,8 @@ RD_VocabInfo rd_vocab_info_table[334] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @display_name('User Theme') 'theme': string,\n @no_expand @display_name('User Theme') @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @display_name('Project Theme') 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, @@ -940,9 +940,8 @@ str8_lit_comp("code_line_numbers"), str8_lit_comp("code_line_numbers_selected"), }; -String8 rd_theme_preset_display_string_table[11] = +String8 rd_theme_preset_display_string_table[10] = { -str8_lit_comp("None"), str8_lit_comp("Default (Dark)"), str8_lit_comp("Default (Light)"), str8_lit_comp("VS (Dark)"), @@ -955,9 +954,8 @@ str8_lit_comp("Grove"), str8_lit_comp("Far Manager"), }; -String8 rd_theme_preset_code_string_table[11] = +String8 rd_theme_preset_code_string_table[10] = { -str8_lit_comp("none"), str8_lit_comp("default_dark"), str8_lit_comp("default_light"), str8_lit_comp("vs_dark"), @@ -970,9 +968,8 @@ str8_lit_comp("grove"), str8_lit_comp("far_manager"), }; -String8 rd_theme_preset_cfg_string_table[11] = +String8 rd_theme_preset_cfg_string_table[10] = { -str8_lit_comp(""), str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus overlay\", value: 0xfda20012 }\n theme_color: {tags:\"focus border\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff }\n theme_color:{ tags: \"alt background\" , value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" , value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" , value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" , value: 0xeaddceff }\n theme_color:{ tags: \"match background\" , value: 0xc1e9c4ff }\n theme_color:{ tags: border , value: 0xcbcbcbff }\n theme_color:{ tags: text , value: 0xff }\n theme_color:{ tags: \"weak text\" , value: 0x727272ff }\n theme_color:{ tags: \"good text\" , value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" , value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" , value: 0x972717ff }\n theme_color:{ tags: hover , value: 0xff }\n theme_color:{ tags: \"focus overlay\" , value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" , value: 0x67ffff }\n theme_color:{ tags: cursor , value: 0xff }\n theme_color:{ tags: selection , value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" , value: 0x8 }\n theme_color:{ tags: drop_shadow , value: 0xb }\n theme_color:{ tags: \"good_pop background\" , value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" , value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" , value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0x80808ff }\n theme_color:{ tags: code_symbol , value: 0x4ac3ff }\n theme_color:{ tags: code_type , value: 0xf46200ff }\n theme_color:{ tags: code_local , value: 0x317c00ff }\n theme_color:{ tags: code_register , value: 0x9a00ffff }\n theme_color:{ tags: code_keyword , value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric , value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff }\n theme_color:{ tags: code_string , value: 0x63549fff }\n theme_color:{ tags: code_meta , value: 0xd96759ff }\n theme_color:{ tags: code_comment , value: 0x717171ff }\n theme_color:{ tags: line_info_0 , value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 , value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 , value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 , value: 0xba917eff }\n theme_color:{ tags: thread_0 , value: 0xffa700ff }\n theme_color:{ tags: thread_1 , value: 0xb41fff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" , value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" , value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" , value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" , value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" , value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" , value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" , value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" , value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"tab background\" , value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" , value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" , value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" , value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" , value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index f00117db..e59c41cd 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -388,7 +388,6 @@ RD_CodeColorSlot_COUNT, typedef enum RD_ThemePreset { -RD_ThemePreset_None, RD_ThemePreset_DefaultDark, RD_ThemePreset_DefaultLight, RD_ThemePreset_VSDark, @@ -568,9 +567,9 @@ extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; extern String8 rd_code_color_slot_name_table[14]; -extern String8 rd_theme_preset_display_string_table[11]; -extern String8 rd_theme_preset_code_string_table[11]; -extern String8 rd_theme_preset_cfg_string_table[11]; +extern String8 rd_theme_preset_display_string_table[10]; +extern String8 rd_theme_preset_code_string_table[10]; +extern String8 rd_theme_preset_cfg_string_table[10]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index fae19138..8c1f523f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -237,8 +237,10 @@ RD_VocabTable: 'code_font': string, //- rjf: theme - @display_name('User Theme') 'theme': string, - @no_expand @display_name('User Theme') @description("The user's theme, which describes all colors used throughout the UI.") + @default("Default (Dark)") @display_name('User Theme') + @description("The user's theme, which describes all colors used throughout the UI.") + 'theme': string, + @no_expand @display_name('User Theme') 'theme_colors': query, //- rjf: autocompletion @@ -294,7 +296,8 @@ RD_VocabTable: @default(1) use_default_ue_type_views: bool, //- rjf: theme - @display_name('Project Theme') 'theme': string, + @default("None") @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") + 'theme': string, @no_expand @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") 'theme_colors': query, @@ -1365,9 +1368,6 @@ RD_IconTable: @table(name_upper name_lower display_string cfg) RD_ThemePresetTable: { - //- rjf: stub - {None none "None" ""} - //- rjf: default dark theme { DefaultDark default_dark "Default (Dark)", diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 80222fb3..5dd3ded3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4837,6 +4837,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: form cell build parameters + UI_Key line_edit_key = {0}; RD_CellParams cell_params = {0}; ProfScope("form cell build parameters") { @@ -4851,6 +4852,7 @@ rd_view_ui(Rng2F32 rect) cell_params.edit_buffer = cell_edit_state->input_buffer; cell_params.edit_buffer_size = sizeof(cell_edit_state->input_buffer); cell_params.edit_string_size_out = &cell_edit_state->input_size; + cell_params.line_edit_key_out = &line_edit_key; cell_params.expanded_out = &next_row_expanded; cell_params.search_needle = needle; cell_params.meta_fstrs = cell_info.expr_fstrs; @@ -4968,7 +4970,7 @@ rd_view_ui(Rng2F32 rect) { list_expr = cursor_info.list_expr; } - rd_set_autocomp_regs(.ui_key = sig.box->key, + rd_set_autocomp_regs(.ui_key = line_edit_key, .string = cursor_info.filter, .expr = list_expr); } @@ -5801,7 +5803,7 @@ rd_window_frame(void) if(rd_setting_b32_from_name(str8_lit("use_project_theme"))) { theme_cfg = theme_cfgs[0]; - if(theme_cfg == &rd_nil_cfg || str8_match(theme_cfg->first->string, rd_theme_preset_display_string_table[RD_ThemePreset_None], 0)) + if(theme_cfg == &rd_nil_cfg) { theme_cfg = theme_cfgs[1]; } @@ -5814,7 +5816,7 @@ rd_window_frame(void) String8 theme_name = theme_cfg->first->string; if(theme_name.size != 0) { - for EachNonZeroEnumVal(RD_ThemePreset, p) + for EachEnumVal(RD_ThemePreset, p) { if(str8_match(theme_name, rd_theme_preset_display_string_table[p], 0)) { @@ -9642,10 +9644,17 @@ rd_autocomp_primary_list_expr_from_dst_eval(Arena *arena, E_Eval dst_eval) { String8 result = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); { + E_TypeKey maybe_enum_type = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) { result = str8_lit("query:themes"); } +#if 0 + else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) + { + result = e_type_string_from_key(arena, maybe_enum_type); + } +#endif } return result; } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index e60b6611..5b96ae1a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -968,6 +968,7 @@ internal void rd_set_autocomp_regs_(RD_Regs *regs); //~ rjf: Colors, Fonts, Config //- rjf: colors +internal UI_Theme *rd_ui_theme_from_tree(MD_Node *tree); internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot); internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind); internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8c52ac57..15012f4d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1851,6 +1851,25 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla dr_fstrs_push_new(arena, &fstrs, ¶ms, name); result.expr_fstrs = fstrs; }break; + + //- rjf: unattached processes + case RD_EvalSpaceKind_MetaTheme: + { + String8 name = e_string_from_id(cell->eval.value.u64); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Main), rd_raster_flags_from_slot(RD_FontSlot_Main), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + DR_FStrList fstrs = {0}; + UI_TagF("weak") + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_Palette], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = ui_color_from_name(str8_lit("text"))); + } + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + result.eval_fstrs = fstrs; + }break; } scratch_end(scratch); return result; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1321eecf..c44c4f99 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3211,6 +3211,7 @@ rd_cell(RD_CellParams *params, String8 string) B32 build_slider = !!(params->flags & RD_CellFlag_Slider) && !is_focus_active; B32 build_bindings = !!(params->flags & RD_CellFlag_Bindings) && !is_focus_active; B32 build_lhs_name_desc = (params->meta_fstrs.node_count != 0 || params->description.size != 0); + B32 build_line_edit = (params->pre_edit_value.size != 0 || params->value_fstrs.node_count != 0); DR_FStrList lhs_name_fstrs = params->meta_fstrs; DR_FStrList value_name_fstrs = params->value_fstrs; @@ -3237,6 +3238,7 @@ rd_cell(RD_CellParams *params, String8 string) ui_set_next_hover_cursor(OS_Cursor_IBar); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| + (!!build_lhs_name_desc*UI_BoxFlag_DisableFocusBorder)| (!!(params->flags & RD_CellFlag_KeyboardClickable)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_ClickToFocus| (!!(params->flags & RD_CellFlag_Button)*UI_BoxFlag_DrawHotEffects)| @@ -3297,6 +3299,10 @@ rd_cell(RD_CellParams *params, String8 string) { UI_Parent(box) UI_WidthFill UI_ChildLayoutAxis(Axis2_Y) { + if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) + { + ui_spacer(ui_em(1.f, 1.f)); + } lhs_box = ui_build_box_from_stringf(0, "lhs_box"); } } @@ -3313,10 +3319,6 @@ rd_cell(RD_CellParams *params, String8 string) } UI_Row { - if(ui_top_text_alignment() == UI_TextAlign_Left && (params->flags & (RD_CellFlag_Expander|RD_CellFlag_ExpanderSpace|RD_CellFlag_ExpanderPlaceholder)) == 0) - { - ui_spacer(ui_em(1.f, 1.f)); - } UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); ui_box_equip_display_fstrs(name_box, &lhs_name_fstrs); ui_box_equip_fuzzy_match_ranges(name_box, &fuzzy_matches); @@ -3325,7 +3327,6 @@ rd_cell(RD_CellParams *params, String8 string) { UI_Row { - ui_spacer(ui_em(1.f, 1.f)); UI_Box *desc_box = ui_label(params->description).box; FuzzyMatchRangeList desc_fuzzy_matches = fuzzy_match_find(scratch.arena, params->search_needle, params->description); ui_box_equip_fuzzy_match_ranges(desc_box, &desc_fuzzy_matches); @@ -3333,21 +3334,115 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build reset-to-default, if line edit is embedded & it is marked + // +#if 0 + if(!is_focus_active && !is_focus_active_disabled) + { + UI_TagF(".") + UI_TagF("weak") + UI_TagF("implicit") + UI_Parent(box) + UI_PrefWidth(ui_em(2.f, 1.f)) + { + UI_Column + UI_Padding(ui_pct(1, 0)) + UI_PrefHeight(ui_em(2.f, 1.f)) + UI_CornerRadius(ui_top_font_size()*0.5f) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + { + UI_Box *edit_start_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DisableFocusBorder| + UI_BoxFlag_Clickable, + "%S##undo", rd_icon_kind_text_table[RD_IconKind_Undo]); + UI_Signal sig = ui_signal_from_box(edit_start_box); + } + } + } +#endif + ////////////////////////////// //- rjf: build line edit container box // UI_Box *edit_box = &ui_nil_box; - UI_Parent(box) if((is_focus_active || is_focus_active_disabled) || - params->pre_edit_value.size != 0 || - params->value_fstrs.node_count != 0) + if((is_focus_active || is_focus_active_disabled) || build_line_edit) + UI_Parent(box) { + B32 is_editing = (is_focus_active || is_focus_active_disabled); UI_Size edit_box_size = ui_pct(1, 0); if(build_lhs_name_desc) { - edit_box_size = ui_children_sum(1); + F32 px_size = is_editing ? (floor_f32(dim_2f32(box->rect).x*0.5f)) : floor_f32(dr_dim_from_fstrs(&value_name_fstrs).x + ui_top_font_size()*1.5f); + edit_box_size = ui_px(px_size, 1.f); } UI_PrefWidth(edit_box_size) - edit_box = ui_build_box_from_stringf(0, "edit_box"); + { + if(ui_top_px_height() > ui_top_font_size()*3.f) + { + ui_set_next_pref_width(ui_children_sum(1)); + UI_Column UI_Padding(ui_em(1, 0)) UI_Focus(UI_FocusKind_On) + { + UI_PrefHeight(ui_em(3.f, 1.f)) UI_CornerRadius(ui_top_font_size()*0.5f) + edit_box = ui_build_box_from_stringf((!!is_editing*UI_BoxFlag_DrawBorder)| + UI_BoxFlag_Clickable| + UI_BoxFlag_DisableFocusOverlay, + "edit_box"); + if(params->line_edit_key_out) + { + params->line_edit_key_out[0] = edit_box->key; + } + } + ui_spacer(ui_em(1.f, 1.f)); + } + else + { + edit_box = ui_build_box_from_stringf(0, "edit_box"); + if(params->line_edit_key_out) + { + params->line_edit_key_out[0] = edit_box->key; + } + } + } + } + + ////////////////////////////// + //- rjf: build edit-button, if line edit is embedded, and has no string + // + if(!is_focus_active && !is_focus_active_disabled && build_lhs_name_desc && build_line_edit && value_name_fstrs.total_size == 0) + { + UI_TagF(".") + UI_TagF("weak") + UI_TagF("implicit") + UI_Parent(box) + UI_PrefWidth(ui_em(2.f, 1.f)) + { + UI_Column + UI_Padding(ui_pct(1, 0)) + UI_PrefHeight(ui_em(2.f, 1.f)) + UI_CornerRadius(ui_top_font_size()*0.5f) + UI_HoverCursor(OS_Cursor_HandPoint) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + { + UI_Box *edit_start_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DisableFocusBorder| + UI_BoxFlag_Clickable, + "%S##edit", rd_icon_kind_text_table[RD_IconKind_Pencil]); + UI_Signal sig = ui_signal_from_box(edit_start_box); + } + ui_spacer(ui_em(1.f, 1.f)); + } } ////////////////////////////// @@ -3374,7 +3469,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) - UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_PrefWidth(ui_em(3.5f, 1.f)) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) @@ -3410,6 +3505,7 @@ rd_cell(RD_CellParams *params, String8 string) params->toggled_out[0] ^= 1; } } + ui_spacer(ui_em(1.f, 1.f)); } ////////////////////////////// @@ -3422,7 +3518,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefWidth(ui_children_sum(1.f)) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) - UI_Row UI_Padding(ui_px(padding_px, 1.f)) + UI_Row UI_PrefWidth(ui_pct(0.5f - 0.2f*(!!build_lhs_name_desc), 0.f)) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) @@ -3469,6 +3565,7 @@ rd_cell(RD_CellParams *params, String8 string) ui_spacer(ui_pct(1-Clamp(0, params->slider_value_out[0], 1), 0.f)); } } + ui_spacer(ui_em(1.f, 1.f)); } ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 57dcd7f2..305eb4cc 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -68,6 +68,7 @@ struct RD_CellParams U8 *edit_buffer; U64 edit_buffer_size; U64 *edit_string_size_out; + UI_Key *line_edit_key_out; }; //////////////////////////////// From da8e583f93679b0b96c1dd23106a00625d807388 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 05:32:26 -0700 Subject: [PATCH 566/755] hook up fancy-cell edit button to double-click action, ensure double-click starts edits in listers for editable cells --- src/raddbg/raddbg_core.c | 7 ++++++- src/raddbg/raddbg_widgets.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5dd3ded3..8508ad0a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5057,12 +5057,16 @@ rd_view_ui(Rng2F32 rect) ui_kill_action(); } - // rjf: this watch window is a lister? -> move cursor & accept + // rjf: this watch window is a lister? -> move cursor & edit or accept if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Accept); + if(cell_info.flags & RD_WatchCellFlag_CanEdit) + { + rd_cmd(RD_CmdKind_Edit); + } } // rjf: has a command name? -> push command @@ -5117,6 +5121,7 @@ rd_view_ui(Rng2F32 rect) else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); rd_cmd(RD_CmdKind_Edit); } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c44c4f99..ca5d8721 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3415,6 +3415,7 @@ rd_cell(RD_CellParams *params, String8 string) ////////////////////////////// //- rjf: build edit-button, if line edit is embedded, and has no string // + B32 edit_started = 0; if(!is_focus_active && !is_focus_active_disabled && build_lhs_name_desc && build_line_edit && value_name_fstrs.total_size == 0) { UI_TagF(".") @@ -3427,7 +3428,6 @@ rd_cell(RD_CellParams *params, String8 string) UI_Padding(ui_pct(1, 0)) UI_PrefHeight(ui_em(2.f, 1.f)) UI_CornerRadius(ui_top_font_size()*0.5f) - UI_HoverCursor(OS_Cursor_HandPoint) RD_Font(RD_FontSlot_Icons) UI_TextAlignment(UI_TextAlign_Center) { @@ -3440,6 +3440,10 @@ rd_cell(RD_CellParams *params, String8 string) UI_BoxFlag_Clickable, "%S##edit", rd_icon_kind_text_table[RD_IconKind_Pencil]); UI_Signal sig = ui_signal_from_box(edit_start_box); + if(ui_pressed(sig)) + { + edit_started = 1; + } } ui_spacer(ui_em(1.f, 1.f)); } @@ -3719,6 +3723,14 @@ rd_cell(RD_CellParams *params, String8 string) scratch_end(scratch); } + ////////////////////////////// + //- rjf: click-driven "start editing" + // + if(edit_started) + { + sig.f |= UI_SignalFlag_DoubleClicked; + } + ////////////////////////////// //- rjf: compute editable fancy strings // From d13bf27ab7167e15b94cea1b632e2b6db0bd4395 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 06:00:45 -0700 Subject: [PATCH 567/755] shift theme pattern cache from a per-frame cache to a permanent cache; use to animate (ui_key -> color) --- src/ui/ui_core.c | 87 ++++++++++++++++++++++++++++++++++++++++++------ src/ui/ui_core.h | 16 +++++++-- 2 files changed, 89 insertions(+), 14 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 239ccdeb..f6e8c5e6 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -435,6 +435,8 @@ ui_state_alloc(void) ui->box_table = push_array(arena, UI_BoxHashSlot, ui->box_table_size); ui->anim_slots_count = 4096; ui->anim_slots = push_array(arena, UI_AnimSlot, ui->anim_slots_count); + ui->theme_pattern_cache_slots_count = 1024; + ui->theme_pattern_cache_slots = push_array(arena, UI_ThemePatternCacheSlot, ui->theme_pattern_cache_slots_count); UI_InitStackNils(ui); return ui; } @@ -809,8 +811,6 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; ui_state->tags_cache_slots_count = 512; ui_state->tags_cache_slots = push_array(ui_build_arena(), UI_TagsCacheSlot, ui_state->tags_cache_slots_count); - ui_state->theme_pattern_cache_slots_count = 512; - ui_state->theme_pattern_cache_slots = push_array(ui_build_arena(), UI_ThemePatternCacheSlot, ui_state->theme_pattern_cache_slots_count); } //- rjf: prune unused animation nodes @@ -834,6 +834,27 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U } } + //- rjf: prune unused theme pattern cache nodes + ProfScope("ui prune unused theme pattern cache") + { + for(UI_ThemePatternCacheNode *n = ui_state->lru_theme_pattern_cache_node, *next = 0; n != 0; n = next) + { + next = n->lru_next; + if(n->last_build_index_accessed+2 < ui_state->build_index) + { + U64 slot_idx = n->key.u64[0]%ui_state->theme_pattern_cache_slots_count; + UI_ThemePatternCacheSlot *slot = &ui_state->theme_pattern_cache_slots[slot_idx]; + DLLRemove_NP(slot->first, slot->last, n, slot_next, slot_prev); + DLLRemove_NP(ui_state->lru_theme_pattern_cache_node, ui_state->mru_theme_pattern_cache_node, n, lru_next, lru_prev); + SLLStackPush_N(ui_state->theme_pattern_cache_node_free, n, slot_next); + } + else + { + break; + } + } + } + //- rjf: detect mouse-moves for(UI_EventNode *n = events->first; n != 0; n = n->next) { @@ -1366,6 +1387,19 @@ ui_end_build(void) } F32 fast_rate = ui_state->default_animation_rate; F32 slow_rate = 1 - pow_f32(2, (-30.f * ui_state->animation_dt)); + for(U64 slot_idx = 0; slot_idx < ui_state->theme_pattern_cache_slots_count; slot_idx += 1) + { + for(UI_ThemePatternCacheNode *n = ui_state->theme_pattern_cache_slots[slot_idx].first; + n != 0; + n = n->slot_next) + { + for EachIndex(idx, 4) + { + n->current_rgba.v[idx] += (n->target_rgba.v[idx] - n->current_rgba.v[idx]) * slow_rate; + ui_state->is_animating = (ui_state->is_animating || abs_f32(n->target_rgba.v[idx] - n->current_rgba.v[idx]) > 0.001f); + } + } + } ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? fast_rate : 1); ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) > 0.01f); if(ui_state->ctx_menu_open_t >= 0.99f && ui_state->ctx_menu_open) @@ -2239,7 +2273,7 @@ ui_color_from_tags_key_extras(UI_Key key, String8Array extras) UI_ThemePatternCacheNode *node = 0; for(UI_ThemePatternCacheNode *n = slot->first; n != 0; - n = n->next) + n = n->slot_next) { if(ui_key_match(n->key, final_key)) { @@ -2247,8 +2281,8 @@ ui_color_from_tags_key_extras(UI_Key key, String8Array extras) } } - //- rjf: no node? create - if(node == 0) + //- rjf: no node, or this node is stale? create and/or update + if(node == 0 || node->last_build_index_accessed < ui_state->build_index) { // rjf: map tags_key (without name) -> full list of tags String8Array tags = {0}; @@ -2310,16 +2344,47 @@ ui_color_from_tags_key_extras(UI_Key key, String8Array extras) } // rjf: store in (key, name) -> (pattern) cache - node = push_array(ui_build_arena(), UI_ThemePatternCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->key = final_key; - node->pattern = pattern; + B32 node_is_new = 0; + if(node == 0) + { + node_is_new = 1; + node = ui_state->theme_pattern_cache_node_free; + if(node != 0) + { + SLLStackPop_N(ui_state->theme_pattern_cache_node_free, slot_next); + } + else + { + node = push_array(ui_state->arena, UI_ThemePatternCacheNode, 1); + } + DLLPushBack_NP(slot->first, slot->last, node, slot_next, slot_prev); + DLLPushBack_NP(ui_state->lru_theme_pattern_cache_node, ui_state->mru_theme_pattern_cache_node, node, lru_next, lru_prev); + node->key = final_key; + } + + // rjf: update node's target color + if(pattern != 0) + { + node->target_rgba = pattern->linear; + if(node_is_new) + { + node->current_rgba = node->target_rgba; + } + } + } + + //- rjf: mark this node as most-recently-used + if(node != 0 && node->last_build_index_accessed < ui_state->build_index) + { + node->last_build_index_accessed = ui_state->build_index; + DLLRemove_NP(ui_state->lru_theme_pattern_cache_node, ui_state->mru_theme_pattern_cache_node, node, lru_next, lru_prev); + DLLPushBack_NP(ui_state->lru_theme_pattern_cache_node, ui_state->mru_theme_pattern_cache_node, node, lru_next, lru_prev); } //- rjf: grab resultant color - if(node != 0 && node->pattern != 0) + if(node != 0) { - result = node->pattern->linear; + result = node->current_rgba; } } return result; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 18d99706..7c9a8a94 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -620,14 +620,19 @@ struct UI_TagsKeyStackNode UI_Key key; }; -//- rjf: cache for mapping 64-bit key * string -> theme pattern +//- rjf: cache for mapping 64-bit key -> theme pattern typedef struct UI_ThemePatternCacheNode UI_ThemePatternCacheNode; struct UI_ThemePatternCacheNode { - UI_ThemePatternCacheNode *next; + UI_ThemePatternCacheNode *slot_next; + UI_ThemePatternCacheNode *slot_prev; + UI_ThemePatternCacheNode *lru_next; + UI_ThemePatternCacheNode *lru_prev; + U64 last_build_index_accessed; UI_Key key; - UI_ThemePattern *pattern; + Vec4F32 target_rgba; + Vec4F32 current_rgba; }; typedef struct UI_ThemePatternCacheSlot UI_ThemePatternCacheSlot; @@ -683,8 +688,13 @@ struct UI_State UI_TagsKeyStackNode *tags_key_stack_free; U64 tags_cache_slots_count; UI_TagsCacheSlot *tags_cache_slots; + + //- rjf: theme pattern cache U64 theme_pattern_cache_slots_count; UI_ThemePatternCacheSlot *theme_pattern_cache_slots; + UI_ThemePatternCacheNode *theme_pattern_cache_node_free; + UI_ThemePatternCacheNode *lru_theme_pattern_cache_node; + UI_ThemePatternCacheNode *mru_theme_pattern_cache_node; //- rjf: build phase output UI_Box *root; From f7a32392944725d641eeaa9ad8e866d92842d083 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 09:21:54 -0700 Subject: [PATCH 568/755] utility for stripping debug info out of libs --- build.bat | 1 + src/strip_lib_debug/strip_lib_debug.c | 116 ++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/strip_lib_debug/strip_lib_debug.c diff --git a/build.bat b/build.bat index e2cc8eef..51f73739 100644 --- a/build.bat +++ b/build.bat @@ -119,6 +119,7 @@ if "%textperf%"=="1" set didbuild=1 && %compile% ..\src\scratc if "%convertperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\convertperf.c %compile_link% %out%convertperf.exe || exit /b 1 if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1 if "%parse_inline_sites%"=="1" set didbuild=1 && %compile% ..\src\scratch\parse_inline_sites.c %compile_link% %out%parse_inline_sites.exe || exit /b 1 +if "%strip_lib_debug%"=="1" set didbuild=1 && %compile% ..\src\strip_lib_debug\strip_lib_debug.c %compile_link% %out%strip_lib_debug.exe || exit /b 1 if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1 if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 diff --git a/src/strip_lib_debug/strip_lib_debug.c b/src/strip_lib_debug/strip_lib_debug.c new file mode 100644 index 00000000..6cae4820 --- /dev/null +++ b/src/strip_lib_debug/strip_lib_debug.c @@ -0,0 +1,116 @@ +// Copyright (c) 2025 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#define BUILD_TITLE "Epic Games Tools (R) Lib Strip Debug" +#define BUILD_CONSOLE_INTERFACE 1 + +//////////////////////////////// +// Headers + +#include "base/base_inc.h" +#include "os/os_inc.h" +#include "coff/coff.h" +#include "coff/coff_parse.h" + +//////////////////////////////// +// Implementations + +#include "base/base_inc.c" +#include "os/os_inc.c" +#include "coff/coff.c" +#include "coff/coff_parse.c" + +internal void +sld_main(CmdLine *cmdl) +{ + B32 do_help = cmd_line_has_flag(cmdl, str8_lit("help")) || + cmd_line_has_flag(cmdl, str8_lit("h")) || + cmd_line_has_flag(cmdl, str8_lit("?")) || + cmdl->argc == 1; + if (do_help) { fprintf(stderr, "--- Help ---------------------------------------------------------------------\n"); + fprintf(stderr, " %s\n\n", BUILD_TITLE_STRING_LITERAL); + fprintf(stderr, " Usage: strip_lib_debug [Options]\n\n"); + fprintf(stderr, " Options:\n"); + fprintf(stderr, " -in: Path to input lib file\n"); + fprintf(stderr, " -out: Path to output lib file\n"); + os_abort(0); + } + + Temp scratch = scratch_begin(0,0); + + String8 in_lib_path = cmd_line_string(cmdl, str8_lit("in")); + String8 out_lib_path = cmd_line_string(cmdl, str8_lit("out")); + + if (in_lib_path.size == 0) { + fprintf(stderr, "ERROR: please provide an input path via -in:\n"); + os_abort(1); + } + if (out_lib_path.size == 0) { + fprintf(stderr, "ERROR: please provide an output path via -out:\n"); + os_abort(1); + } + + String8 in_lib = os_data_from_file_path(scratch.arena, in_lib_path); + if (in_lib.size == 0) { + fprintf(stderr, "ERROR: unable to read file %.*s\n", str8_varg(in_lib_path)); + os_abort(1); + } + + if (!coff_is_regular_archive(in_lib)) { + fprintf(stderr, "ERROR: input lib is not COFF archive\n"); + os_abort(1); + } + + // read & parse lib + String8 out_lib = push_str8_copy(scratch.arena, in_lib); + COFF_ArchiveParse parse = coff_archive_parse_from_data(out_lib); + + // was parse successful? + if (parse.error.size) { + fprintf(stderr, "ERROR: %.*s: %.*s\n", str8_varg(in_lib_path), str8_varg(parse.error)); + os_abort(1); + } + + // convert big endian offsets + U32 member_offsets_count = parse.first_member.symbol_count; + U32 *member_offsets = push_array(scratch.arena, U32, parse.first_member.member_offset_count); + for (U32 offset_idx = 0; offset_idx < member_offsets_count; offset_idx += 1) { + member_offsets[offset_idx] = from_be_u32(parse.first_member.member_offsets[offset_idx]); + } + + // fixup sections + for (U64 member_idx = 0; member_idx < member_offsets_count; member_idx += 1) { + COFF_ParsedArchiveMemberHeader member_header = {0}; + coff_parse_archive_member_header(out_lib, member_offsets[member_idx], &member_header); + String8 member_data = str8_substr(out_lib, member_header.data_range); + COFF_DataType member_type = coff_data_type_from_data(member_data); + if (member_type == COFF_DataType_BigObj || member_type == COFF_DataType_Obj) { + COFF_FileHeaderInfo file_header_info = coff_file_header_info_from_data(member_data); + COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(member_data, file_header_info.section_table_range).str; + String8 string_table = str8_substr(member_data, file_header_info.string_table_range); + for (U64 sect_idx = 0; sect_idx < file_header_info.section_count_no_null; sect_idx += 1) { + COFF_SectionHeader *sect_header = §ion_table[sect_idx]; + String8 name = coff_name_from_section_header(string_table, sect_header); + if (str8_match(str8_lit(".debug$S"), name, 0) || str8_match(str8_lit(".debug$T"), name, 0)) { + sect_header->flags = COFF_SectionFlag_LnkRemove; + MemorySet(sect_header->name, 'x', sizeof(sect_header->name)); + } + } + } + } + + // wirte modified library + if (!os_write_data_to_file_path(out_lib_path, out_lib)) { + fprintf(stderr, "ERROR: unable to write output file to %.*s\n", str8_varg(out_lib_path)); + os_abort(1); + } + + scratch_end(scratch); +} + +internal void +entry_point(CmdLine *cmdl) +{ + sld_main(cmdl); +} + From c840071bf80e058346704c06b2c733661ad64bf2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 09:48:07 -0700 Subject: [PATCH 569/755] clean up visualizer default sizes, clean up rough edges of various combos of theme setting / config state --- src/eval/eval_core.c | 18 ++++ src/eval/eval_core.h | 1 + src/raddbg/generated/raddbg.meta.c | 8 +- src/raddbg/generated/raddbg.meta.h | 3 +- src/raddbg/raddbg.mdesk | 3 +- src/raddbg/raddbg_core.c | 166 +++++++++++++++++------------ src/raddbg/raddbg_core.h | 6 +- src/raddbg/raddbg_eval.c | 2 +- src/raddbg/raddbg_views.c | 38 ++++++- 9 files changed, 164 insertions(+), 81 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 3212437d..de8979e7 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1219,6 +1219,24 @@ e_base_offset_from_eval(E_Eval eval) return eval.value.u64; } +internal U64 +e_range_size_from_eval(E_Eval eval) +{ + U64 result = 256; + E_TypeKey type_unwrapped = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKind type_unwrapped_kind = e_type_kind_from_key(type_unwrapped); + if(e_type_kind_is_pointer_or_ref(type_unwrapped_kind) || + type_unwrapped_kind == E_TypeKind_Function) + { + result = KB(16); + } + else + { + result = e_type_byte_size_from_key(type_unwrapped); + } + return result; +} + //////////////////////////////// //~ rjf: Debug Functions diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index d9249a87..5138e754 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -1179,6 +1179,7 @@ internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); //~ rjf: Eval Info Extraction internal U64 e_base_offset_from_eval(E_Eval eval); +internal U64 e_range_size_from_eval(E_Eval eval); //////////////////////////////// //~ rjf: Debug Functions diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 3d6fe3db..8fb1115f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[334] = +RD_VocabInfo rd_vocab_info_table[335] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -354,6 +354,7 @@ RD_VocabInfo rd_vocab_info_table[334] = {str8_lit_comp("add_theme_color"), str8_lit_comp(""), str8_lit_comp("Add Theme Color"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("fork_theme"), str8_lit_comp(""), str8_lit_comp("Fork Theme"), str8_lit_comp(""), RD_IconKind_Palette}, {str8_lit_comp("save_theme"), str8_lit_comp(""), str8_lit_comp("Save Theme"), str8_lit_comp(""), RD_IconKind_Save}, +{str8_lit_comp("save_and_set_theme"), str8_lit_comp(""), str8_lit_comp("Save And Set Theme"), str8_lit_comp(""), RD_IconKind_Save}, {str8_lit_comp("set_next_statement"), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), str8_lit_comp(""), RD_IconKind_RightArrow}, {str8_lit_comp("add_target"), str8_lit_comp(""), str8_lit_comp("Add Target"), str8_lit_comp(""), RD_IconKind_Target}, {str8_lit_comp("select_target"), str8_lit_comp(""), str8_lit_comp("Select Target"), str8_lit_comp(""), RD_IconKind_Target}, @@ -402,7 +403,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = { {str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, -{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, +{str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, @@ -473,7 +474,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[227] = +RD_CmdKindInfo rd_cmd_kind_info_table[228] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -660,6 +661,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[227] = { str8_lit_comp("add_theme_color"), str8_lit_comp("Adds a new theme color."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("fork_theme"), str8_lit_comp("Imports all colors from the current theme so they can be individually edited."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("save_theme"), str8_lit_comp("Saves all theme colors to a new theme file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_and_set_theme"), str8_lit_comp("Saves all theme colors to a new theme file, and then sets that theme as the selected theme."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("$targets,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index e59c41cd..46514db7 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -241,6 +241,7 @@ RD_CmdKind_EditProjectTheme, RD_CmdKind_AddThemeColor, RD_CmdKind_ForkTheme, RD_CmdKind_SaveTheme, +RD_CmdKind_SaveAndSetTheme, RD_CmdKind_SetNextStatement, RD_CmdKind_AddTarget, RD_CmdKind_SelectTarget, @@ -560,7 +561,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[334]; +extern RD_VocabInfo rd_vocab_info_table[335]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8c1f523f..25a49063 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -384,7 +384,7 @@ RD_VocabTable: { theme_color, ``` - @collection_commands(add_theme_color, fork_theme, save_theme) + @collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme) @row_commands(duplicate_cfg, remove_cfg) x: { @@ -990,6 +990,7 @@ RD_CmdTable: // | | | | {AddThemeColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "add_theme_color" "Add Theme Color" "Adds a new theme color." "" "" } {ForkTheme 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Palette "fork_theme" "Fork Theme" "Imports all colors from the current theme so they can be individually edited." "" "" } {SaveTheme 0 0 0 0 "" String null Nil Null 1 0 0 0 0 1 1 Save "save_theme" "Save Theme" "Saves all theme colors to a new theme file." "" "" } + {SaveAndSetTheme 0 0 0 0 "" String null Nil Null 1 0 0 0 0 1 1 Save "save_and_set_theme" "Save And Set Theme" "Saves all theme colors to a new theme file, and then sets that theme as the selected theme." "" "" } //- rjf: line operations {SetNextStatement 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 RightArrow "set_next_statement" "Set Next Statement" "Sets the selected thread's instruction pointer to the cursor's position." "" "$text_pt," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8508ad0a..c9e58895 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5188,10 +5188,10 @@ rd_view_ui(Rng2F32 rect) rd_cmd(RD_CmdKind_SelectThread, .thread = cell_info.entity->handle); } - // rjf: other cases, but this watch window is floating? -> push query - else if(view_is_floating) + // rjf: other cases, but this watch window is floating, and this has a cfg/entity? -> push query + else if(view_is_floating && (cell_info.entity != &ctrl_entity_nil || cell_info.cfg != &rd_nil_cfg)) { - rd_cmd(RD_CmdKind_PushQuery, .expr = cell->eval.string); + rd_cmd(RD_CmdKind_PushQuery, .expr = e_full_expr_string_from_key(scratch.arena, cell->eval.key)); } } @@ -5815,33 +5815,10 @@ rd_window_frame(void) } //- rjf: map the theme config to the associated tree (either from a preset, or from a file) - MD_Node *theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; - if(theme_cfg != &rd_nil_cfg) + MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme_cfg->first->string); + if(colors_cfgs.count == 0 && theme_tree == &md_nil_node) { - String8 theme_name = theme_cfg->first->string; - if(theme_name.size != 0) - { - for EachEnumVal(RD_ThemePreset, p) - { - if(str8_match(theme_name, rd_theme_preset_display_string_table[p], 0)) - { - theme_tree = rd_state->theme_preset_trees[p]; - break; - } - } - if(theme_tree == &md_nil_node) - { - String8 path = push_str8f(scratch.arena, "%S/raddbg/themes/%S", os_get_process_info()->user_program_data_path, theme_name); - U64 endt_us = os_now_microseconds()+100; - if(ws->frames_alive == 0) - { - endt_us = os_now_microseconds()+50000; - } - U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us); - String8 data = hs_data_from_hash(hs_scope, hash); - theme_tree = md_tree_from_string(scratch.arena, data); - } - } + theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; } //- rjf: build tasks for color applications - each task comprises of a metadesk @@ -9769,6 +9746,38 @@ rd_set_autocomp_regs_(RD_Regs *regs) //- rjf: colors +internal MD_Node * +rd_theme_tree_from_name(Arena *arena, HS_Scope *scope, String8 theme_name) +{ + Temp scratch = scratch_begin(&arena, 1); + MD_Node *theme_tree = &md_nil_node; + if(theme_name.size != 0) + { + for EachEnumVal(RD_ThemePreset, p) + { + if(str8_match(theme_name, rd_theme_preset_display_string_table[p], 0)) + { + theme_tree = rd_state->theme_preset_trees[p]; + break; + } + } + if(theme_tree == &md_nil_node) + { + String8 path = push_str8f(scratch.arena, "%S/raddbg/themes/%S", os_get_process_info()->user_program_data_path, theme_name); + U64 endt_us = os_now_microseconds()+100; + if(rd_state->frame_index <= 5) + { + endt_us = os_now_microseconds()+50000; + } + U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us); + String8 data = hs_data_from_hash(scope, hash); + theme_tree = md_tree_from_string(arena, data); + } + } + scratch_end(scratch); + return theme_tree; +} + internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot) { @@ -10121,20 +10130,6 @@ rd_frame_arena(void) //////////////////////////////// //~ rjf: Registers -internal RD_Regs * -rd_regs(void) -{ - RD_Regs *regs = &rd_state->top_regs->v; - return regs; -} - -internal RD_Regs * -rd_base_regs(void) -{ - RD_Regs *regs = &rd_state->base_regs.v; - return regs; -} - internal RD_Regs * rd_push_regs_(RD_Regs *regs) { @@ -12194,26 +12189,33 @@ rd_frame(void) RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window); RD_Cfg *tab = panel_tree.focused->selected_tab; - String8 expr = push_str8f(scratch.arena, - "query:commands, " - "query:config.$%I64x, " - "query:config.$%I64x, " - "query:targets, " - "query:breakpoints, " - "query:recent_files, " - "query:recent_projects, " - "query:machines, " - "query:processes, " - "query:threads, " - "query:modules, " - "query:user_settings, " - "query:project_settings, " - "query:procedures, " - "query:types, " - "query:globals, " - "query:thread_locals, " - , - tab->id, window->id); + String8List exprs = {0}; + { + str8_list_pushf(scratch.arena, &exprs, "query:commands"); + if(tab != &rd_nil_cfg) + { + str8_list_pushf(scratch.arena, &exprs, "query:config.$%I64x", tab->id); + } + if(window != &rd_nil_cfg) + { + str8_list_pushf(scratch.arena, &exprs, "query:config.$%I64x", window->id); + } + str8_list_pushf(scratch.arena, &exprs, "query:targets"); + str8_list_pushf(scratch.arena, &exprs, "query:breakpoints"); + str8_list_pushf(scratch.arena, &exprs, "query:recent_files"); + str8_list_pushf(scratch.arena, &exprs, "query:recent_projects"); + str8_list_pushf(scratch.arena, &exprs, "query:machines"); + str8_list_pushf(scratch.arena, &exprs, "query:processes"); + str8_list_pushf(scratch.arena, &exprs, "query:threads"); + str8_list_pushf(scratch.arena, &exprs, "query:modules"); + str8_list_pushf(scratch.arena, &exprs, "query:user_settings"); + str8_list_pushf(scratch.arena, &exprs, "query:project_settings"); + str8_list_pushf(scratch.arena, &exprs, "query:procedures"); + str8_list_pushf(scratch.arena, &exprs, "query:types"); + str8_list_pushf(scratch.arena, &exprs, "query:globals"); + str8_list_pushf(scratch.arena, &exprs, "query:thread_locals"); + } + String8 expr = str8_list_join(scratch.arena, &exprs, &(StringJoin){.sep = str8_lit(", ")}); rd_cmd(RD_CmdKind_PushQuery, .expr = expr, .do_implicit_root = 1, .do_lister = 1, .do_big_rows = 1, .view = tab->id, .tab = tab->id); }break; @@ -14749,25 +14751,36 @@ rd_frame(void) }break; case RD_CmdKind_AddThemeColor: { + HS_Scope *hs_scope = hs_scope_open(); RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); + RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); + MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme->first->string); + if(theme_tree == &md_nil_node) + { + rd_cfg_new_replace(theme, rd_theme_preset_display_string_table[RD_ThemePreset_DefaultDark]); + } RD_Cfg *color = rd_cfg_new(parent, str8_lit("theme_color")); rd_cfg_new(color, str8_lit("tags")); RD_Cfg *value = rd_cfg_new(color, str8_lit("value")); rd_cfg_new(value, str8_lit("0xffffffff")); + hs_scope_close(hs_scope); }break; case RD_CmdKind_ForkTheme: { + HS_Scope *hs_scope = hs_scope_open(); RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg); RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color")); for(RD_CfgNode *n = colors.first; n != 0; n = n->next) { rd_cfg_release(n->v); } - String8 color_preset = rd_setting_from_name(str8_lit("theme_preset")); - RD_ThemePreset preset = RD_ThemePreset_DefaultDark; - // TODO(rjf): map preset via string - MD_Node *theme_tree = rd_state->theme_preset_trees[preset]; - String8 color_file = rd_setting_from_name(str8_lit("theme_file")); + RD_Cfg *theme_cfg = rd_cfg_child_from_string(parent, str8_lit("theme")); + String8 theme_name = theme_cfg->first->string; + MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme_name); + if(theme_tree == &md_nil_node) + { + theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark]; + } for(MD_Node *n = theme_tree; !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next) { if(str8_match(n->string, str8_lit("theme_color"), 0)) @@ -14779,8 +14792,11 @@ rd_frame(void) rd_cfg_new(value, md_child_from_string(n, str8_lit("value"), 0)->first->string); } } + rd_cfg_release(theme_cfg); + hs_scope_close(hs_scope); }break; case RD_CmdKind_SaveTheme: + case RD_CmdKind_SaveAndSetTheme: { String8 name = rd_regs()->string; if(name.size != 0) @@ -14797,7 +14813,19 @@ rd_frame(void) str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, n->v)); } String8 data = str8_list_join(scratch.arena, &strings, 0); - os_write_data_to_file_path(dst_path, data); + if(os_write_data_to_file_path(dst_path, data)) + { + for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); + rd_cfg_new_replace(theme, name); + } + else + { + log_user_errorf("Could not successfully write to '%S'.", dst_path); + } } } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5b96ae1a..5699383d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -968,7 +968,7 @@ internal void rd_set_autocomp_regs_(RD_Regs *regs); //~ rjf: Colors, Fonts, Config //- rjf: colors -internal UI_Theme *rd_ui_theme_from_tree(MD_Node *tree); +internal MD_Node *rd_theme_tree_from_name(Arena *arena, HS_Scope *scope, String8 theme_name); internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot); internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind); internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); @@ -1008,8 +1008,8 @@ internal Arena *rd_frame_arena(void); //////////////////////////////// //~ rjf: Registers -internal RD_Regs *rd_regs(void); -internal RD_Regs *rd_base_regs(void); +#define rd_regs() (&rd_state->top_regs->v) +#define rd_base_regs() (&rd_state->base_regs.v) internal RD_Regs *rd_push_regs_(RD_Regs *regs); #define rd_push_regs(...) rd_push_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) internal RD_Regs *rd_pop_regs(void); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a70380c5..25e46912 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -130,7 +130,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(themes) FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, name); if(name_matches.count == name_matches.needle_part_count) { - str8_list_push(scratch.arena, &names, name); + str8_list_push(scratch.arena, &names, push_str8_copy(arena, name)); } } os_file_iter_end(it); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 15012f4d..90856539 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1868,6 +1868,38 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); dr_fstrs_push_new(arena, &fstrs, ¶ms, name); + { + HS_Scope *hs_scope = hs_scope_open(); + MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, name); + U64 color_idx = 0; + for(MD_Node *n = theme_tree; color_idx < 4 && !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next) + { + if(str8_match(n->string, str8_lit("theme_color"), 0)) + { + String8 tags = md_child_from_string(n, str8_lit("tags"), 0)->first->string; + if(str8_match(tags, str8_lit("background"), 0) || + str8_match(tags, str8_lit("text"), 0) || + str8_match(tags, str8_lit("focus border"), 0) || + str8_match(tags, str8_lit("menu_bar background"), 0) || + str8_match(tags, str8_lit("tab background"), 0) || + str8_match(tags, str8_lit("code_default"), 0)) + { + U64 color = 0; + if(try_u64_from_str8_c_rules(md_child_from_string(n, str8_lit("value"), 0)->first->string, &color)) + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, + rd_icon_kind_text_table[RD_IconKind_CircleFilled], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), + .color = linear_from_srgba(rgba_from_u32((U32)color))); + color_idx += 1; + } + } + } + } + hs_scope_close(hs_scope); + } result.eval_fstrs = fstrs; }break; } @@ -1975,7 +2007,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { - size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + size = e_range_size_from_eval(eval); } Rng1U64 range = r1u64(base_offset, base_offset+size); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); @@ -2249,7 +2281,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { - size = KB(16); + size = e_range_size_from_eval(eval); } Rng1U64 range = r1u64(base_offset, base_offset+size); Arch arch = rd_arch_from_eval(eval); @@ -2429,7 +2461,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) U64 size = rd_view_setting_value_from_name(str8_lit("size")).u64; if(size == 0) { - size = e_type_byte_size_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + size = e_range_size_from_eval(eval); } Rng1U64 view_range = r1u64(base_offset, base_offset+size); if(eval.space.kind == 0) From e2266322d0e11c3572dbb0bbe747461b53aeb1a7 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 09:51:06 -0700 Subject: [PATCH 570/755] Revert "pass over PDB converter" This reverts commit f1e88b566784939b458f1190002d5e851d7c70c5. --- src/lib_rdi_make/rdi_make.c | 214 +--- src/lib_rdi_make/rdi_make.h | 25 - src/rdi_from_pdb/rdi_from_pdb.c | 1467 +++++++++++++++++--------- src/rdi_from_pdb/rdi_from_pdb.h | 39 + src/rdi_from_pdb/rdi_from_pdb_main.c | 3 - src/rdi_make/rdi_make_help.c | 925 ++++++++++++++++ src/rdi_make/rdi_make_help.h | 342 ++++++ 7 files changed, 2258 insertions(+), 757 deletions(-) create mode 100644 src/rdi_make/rdi_make_help.c create mode 100644 src/rdi_make/rdi_make_help.h diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 40a1bf0f..5fc16a59 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -438,153 +438,6 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r } } -//////////////////////////////// -//~ Data Model - -RDI_PROC RDI_TypeKind -rdim_short_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_int_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_long_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_long_long_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - -RDI_PROC RDI_TypeKind -rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model) -{ - switch(data_model) - { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; - } - return RDI_TypeKind_NULL; -} - //////////////////////////////// //~ rjf: [Building] Binary Section List Building @@ -1216,10 +1069,9 @@ rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *ri } else { - left_dst->last_op->next = right_destroyed->first_op; - left_dst->last_op = right_destroyed->last_op; - left_dst->op_count += right_destroyed->op_count; - left_dst->encoded_size += right_destroyed->encoded_size; + left_dst->last_op = right_destroyed->last_op; + left_dst->op_count += right_destroyed->op_count; + left_dst->encoded_size += right_destroyed->encoded_size; } rdim_memzero_struct(right_destroyed); } @@ -1307,59 +1159,10 @@ rdim_count_from_location_block_chunk_list(RDIM_String8List *list) //////////////////////////////// -RDI_PROC RDIM_Type * -rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind) -{ - RDI_U64 type_idx = 0; - if (type_kind != RDI_TypeKind_NULL) { - type_idx = (type_kind - RDI_TypeKind_FirstBuiltIn) + 1; - } - RDIM_Type *builtin = &list.first->v[type_idx]; - return builtin; -} - -RDI_PROC RDIM_TypeChunkList -rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) -{ - RDIM_TypeChunkList list = {0}; - - RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; - - RDIM_Type *null_type = rdim_type_chunk_list_push(arena, &list, type_cap); - - for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) - { - RDIM_String8 name = {0}; - name.str = rdi_string_from_type_kind(type_kind, &name.size); - - RDIM_Type *type = rdim_type_chunk_list_push(arena, &list, type_cap); - type->name = name; - type->kind = type_kind; - type->byte_size = rdi_size_from_basic_type_kind(type_kind); - } - - RDIM_Type *void_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Void); - void_type->byte_size = rdi_addr_size_from_arch(arch); - - RDIM_Type *handle_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Handle); - handle_type->byte_size = rdi_addr_size_from_arch(arch); - - return list; -} - -//////////////////////////////// - RDI_PROC void rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) { RDI_U64 type_pos = rdim_idx_from_type(type); - - if(type->kind == RDI_TypeKind_NULL) - { - type_indices[type_pos] = 0; - return; - } - if(type_indices[type_pos] == 0) { if(type->param_types) @@ -1383,8 +1186,6 @@ rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) RDI_PROC RDI_U64 * rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) { - ProfBeginFunction(); - RDI_U64 *type_indices = rdim_push_array(arena, RDI_U64, types->total_count + 1); RDI_U64 type_indices_count = 1; @@ -1396,7 +1197,6 @@ rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) } } - ProfEnd(); return type_indices; } @@ -2393,7 +2193,6 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI for(RDI_U64 idx = 0; idx < n->count; idx += 1) { RDI_U32 type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, &n->v[idx]); // TODO(rjf): @u64_to_u32 - if(type_idx == 0) {continue;} rdim_bake_name_map_push(arena, map, n->v[idx].name, type_idx); } } @@ -3238,11 +3037,6 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId RDIM_Type *src = &n->v[chunk_idx]; U64 dst_idx = rdim_final_idx_from_type(type_indices, src); RDI_TypeNode *dst = &type_nodes[dst_idx]; - - if(src->kind == RDI_TypeKind_NULL) - { - continue; - } //- rjf: fill shared type node info dst->kind = src->kind; @@ -3533,7 +3327,7 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, } RDI_PROC U64 -rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) +rdim_bake_location(Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) { U64 location_data_off = location_data_blobs->total_size; diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 43afb3c9..647f8cc4 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -595,17 +595,6 @@ struct RDIM_UnitChunkList //////////////////////////////// //~ rjf: Type System Node Types -typedef RDI_U32 RDIM_DataModel; -enum RDIM_DataModelEnum -{ - RDIM_DataModel_Null, - RDIM_DataModel_ILP32, - RDIM_DataModel_LLP64, - RDIM_DataModel_LP64, - RDIM_DataModel_ILP64, - RDIM_DataModel_SILP64 -}; - typedef struct RDIM_Type RDIM_Type; struct RDIM_Type { @@ -616,7 +605,6 @@ struct RDIM_Type RDI_U32 off; RDI_U32 count; RDIM_String8 name; - RDIM_String8 link_name; RDIM_Type *direct_type; RDIM_Type **param_types; struct RDIM_UDT *udt; @@ -1360,19 +1348,6 @@ RDI_PROC RDIM_SortKey *rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys //- rjf: rng1u64 list RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r); -//////////////////////////////// -//~ Data Model - -RDI_PROC RDI_TypeKind rdim_short_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_int_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_long_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_long_long_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model); -RDI_PROC RDI_TypeKind rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model); - //////////////////////////////// //~ rjf: [Building] Binary Section Info Building diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index e84bb0eb..6d06f195 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -994,6 +994,439 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) return 0; } +//////////////////////////////// +//~ rjf: Type Parsing/Conversion Tasks + +ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work) +{ + ProfBeginFunction(); + Arena *arena = p2r_state->work_thread_arenas[thread_idx]; + P2R_ITypeFwdMapFillIn *in = (P2R_ITypeFwdMapFillIn *)input; + ProfScope("fill itype fwd map") for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) + { + //- rjf: skip if not in the actually stored itype range + if(itype < in->tpi_leaf->itype_first) + { + continue; + } + + //- rjf: determine if this itype resolves to another + CV_TypeId itype_fwd = 0; + CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[itype-in->tpi_leaf->itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + if(range->off+range->hdr.size <= in->tpi_leaf->data.size && + range->off+2+header_struct_size <= in->tpi_leaf->data.size && + range->hdr.size >= 2) + { + U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + switch(kind) + { + default:{}break; + + //- rjf: CLASS/STRUCTURE + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + { + // rjf: unpack leaf header + CV_LeafStruct *lf_struct = (CV_LeafStruct *)itype_leaf_first; + + // rjf: has fwd ref flag -> lookup itype that this itype resolves to + if(lf_struct->props & CV_TypeProp_FwdRef) + { + // rjf: unpack rest of leaf + U8 *numeric_ptr = (U8 *)(lf_struct + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + + // rjf: lookup + B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && + ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); + itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); + } + }break; + + //- rjf: CLASS2/STRUCT2 + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + // rjf: unpack leaf header + CV_LeafStruct2 *lf_struct = (CV_LeafStruct2 *)itype_leaf_first; + + // rjf: has fwd ref flag -> lookup itype that this itype resolves to + if(lf_struct->props & CV_TypeProp_FwdRef) + { + // rjf: unpack rest of leaf + U8 *numeric_ptr = (U8 *)(lf_struct + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U8 *name_ptr = (U8 *)numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + + // rjf: lookup + B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && + ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); + itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); + } + }break; + + //- rjf: UNION + case CV_LeafKind_UNION: + { + // rjf: unpack leaf + CV_LeafUnion *lf_union = (CV_LeafUnion *)itype_leaf_first; + U8 *numeric_ptr = (U8 *)(lf_union + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + + // rjf: has fwd ref flag -> lookup itype that this itype resolves tos + if(lf_union->props & CV_TypeProp_FwdRef) + { + B32 do_unique_name_lookup = (((lf_union->props & CV_TypeProp_Scoped) != 0) && + ((lf_union->props & CV_TypeProp_HasUniqueName) != 0)); + itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); + } + }break; + + //- rjf: ENUM + case CV_LeafKind_ENUM: + { + // rjf: unpack leaf + CV_LeafEnum *lf_enum = (CV_LeafEnum*)itype_leaf_first; + U8 *name_ptr = (U8 *)(lf_enum + 1); + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); + + // rjf: has fwd ref flag -> lookup itype that this itype resolves to + if(lf_enum->props & CV_TypeProp_FwdRef) + { + B32 do_unique_name_lookup = (((lf_enum->props & CV_TypeProp_Scoped) != 0) && + ((lf_enum->props & CV_TypeProp_HasUniqueName) != 0)); + itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); + } + }break; + } + } + + //- rjf: if the forwarded itype is nonzero & in TPI range -> save to map + if(itype_fwd != 0 && itype_fwd < in->tpi_leaf->itype_opl) + { + in->itype_fwd_map[itype] = itype_fwd; + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(p2r_itype_chain_build_work) +{ + ProfBeginFunction(); + Arena *arena = p2r_state->work_thread_arenas[thread_idx]; + Temp scratch = scratch_begin(&arena, 1); + P2R_ITypeChainBuildIn *in = (P2R_ITypeChainBuildIn *)input; + ProfScope("dependency itype chain build") + { + for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) + { + //- rjf: push initial itype - should be final-visited-itype for this itype + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = itype; + SLLStackPush(in->itype_chains[itype], c); + } + + //- rjf: skip basic types for dependency walk + if(itype < in->tpi_leaf->itype_first) + { + continue; + } + + //- rjf: walk dependent types, push to chain + P2R_TypeIdChain start_walk_task = {0, itype}; + P2R_TypeIdChain *first_walk_task = &start_walk_task; + P2R_TypeIdChain *last_walk_task = &start_walk_task; + for(P2R_TypeIdChain *walk_task = first_walk_task; + walk_task != 0; + walk_task = walk_task->next) + { + CV_TypeId walk_itype = in->itype_fwd_map[walk_task->itype] ? in->itype_fwd_map[walk_task->itype] : walk_task->itype; + if(walk_itype < in->tpi_leaf->itype_first) + { + continue; + } + CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[walk_itype-in->tpi_leaf->itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + if(range->off+range->hdr.size <= in->tpi_leaf->data.size && + range->off+2+header_struct_size <= in->tpi_leaf->data.size && + range->hdr.size >= 2) + { + U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + switch(kind) + { + default:{}break; + + //- rjf: MODIFIER + case CV_LeafKind_MODIFIER: + { + CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; + + // rjf: push dependent itype to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itype + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: POINTER + case CV_LeafKind_POINTER: + { + CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; + + // rjf: push dependent itype to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itype + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: PROCEDURE + case CV_LeafKind_PROCEDURE: + { + CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; + + // rjf: push return itypes to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->ret_itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk return itype + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->ret_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: push arg types to chain + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = arglist_itypes_base[idx]; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk arg types + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = arglist_itypes_base[idx]; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: MFUNCTION + case CV_LeafKind_MFUNCTION: + { + CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; + + // rjf: push dependent itypes to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->ret_itype; + SLLStackPush(in->itype_chains[itype], c); + } + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->arg_itype; + SLLStackPush(in->itype_chains[itype], c); + } + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->this_itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itypes + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->ret_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->arg_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->this_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: push arg types to chain + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = arglist_itypes_base[idx]; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk arg types + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = arglist_itypes_base[idx]; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: BITFIELD + case CV_LeafKind_BITFIELD: + { + CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; + + // rjf: push dependent itype to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itype + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: ARRAY + case CV_LeafKind_ARRAY: + { + CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; + + // rjf: push dependent itypes to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->entry_itype; + SLLStackPush(in->itype_chains[itype], c); + } + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->index_itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itypes + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->entry_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->index_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + + //- rjf: ENUM + case CV_LeafKind_ENUM: + { + CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; + + // rjf: push dependent itypes to chain + { + P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); + c->itype = lf->base_itype; + SLLStackPush(in->itype_chains[itype], c); + } + + // rjf: push task to walk dependency itypes + { + P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); + c->itype = lf->base_itype; + SLLQueuePush(first_walk_task, last_walk_task, c); + } + }break; + } + } + } + } + } + scratch_end(scratch); + ProfEnd(); + return 0; +} + //////////////////////////////// //~ rjf: UDT Conversion Tasks @@ -1002,7 +1435,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; -#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); RDI_U64 udts_chunk_cap = 1024; ProfScope("convert UDT info") @@ -1640,21 +2073,21 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) Arena *arena = p2r_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; -#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) +#define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) ////////////////////////// //- rjf: set up outputs for this sym stream // - U64 sym_procedures_chunk_cap = 1024; + U64 sym_procedures_chunk_cap = 1024; U64 sym_global_variables_chunk_cap = 1024; U64 sym_thread_variables_chunk_cap = 1024; - U64 sym_scopes_chunk_cap = 1024; - U64 sym_inline_sites_chunk_cap = 1024; - RDIM_SymbolChunkList sym_procedures = {0}; - RDIM_SymbolChunkList sym_global_variables = {0}; - RDIM_SymbolChunkList sym_thread_variables = {0}; - RDIM_ScopeChunkList sym_scopes = {0}; - RDIM_InlineSiteChunkList sym_inline_sites = {0}; + U64 sym_scopes_chunk_cap = 1024; + U64 sym_inline_sites_chunk_cap = 1024; + RDIM_SymbolChunkList sym_procedures = {0}; + RDIM_SymbolChunkList sym_global_variables = {0}; + RDIM_SymbolChunkList sym_thread_variables = {0}; + RDIM_ScopeChunkList sym_scopes = {0}; + RDIM_InlineSiteChunkList sym_inline_sites = {0}; ////////////////////////// //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) @@ -2865,9 +3298,9 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) //- rjf: join ipi/tpi hash/leaf parses // PDB_TpiHashParsed *tpi_hash = 0; - CV_LeafParsed *tpi_leaf = 0; + CV_LeafParsed *tpi_leaf = 0; PDB_TpiHashParsed *ipi_hash = 0; - CV_LeafParsed *ipi_leaf = 0; + CV_LeafParsed *ipi_leaf = 0; { tpi_hash = async_task_join_struct(tpi_hash_task, PDB_TpiHashParsed); tpi_leaf = async_task_join_struct(tpi_leaf_task, CV_LeafParsed); @@ -2876,551 +3309,546 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) } ////////////////////////////////////////////////////////////// - //- rjf: types pass 1: construct all types from TPI + //- rjf: types pass 1: produce type forward resolution map + // + // this map is used to resolve usage of "incomplete structs" in codeview's + // type info. this often happens when e.g. "struct Foo" is used to refer to + // a later-defined "Foo", which actually contains members and so on. we want + // to hook types up to their actual destination complete types wherever + // possible, and so this map can be used to do that in subsequent stages. + // + CV_TypeId *itype_fwd_map = 0; + CV_TypeId itype_first = 0; + CV_TypeId itype_opl = 0; + if(tpi_leaf != 0 && in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: produce type forward resolution map") + { + //- rjf: allocate forward resolution map + itype_first = tpi_leaf->itype_first; + itype_opl = tpi_leaf->itype_opl; + itype_fwd_map = push_array(arena, CV_TypeId, (U64)itype_opl); + + //- rjf: kick off tasks to fill forward resolution map + U64 task_size_itypes = 1024; + U64 tasks_count = ((U64)itype_opl+(task_size_itypes-1))/task_size_itypes; + P2R_ITypeFwdMapFillIn *tasks_inputs = push_array(scratch.arena, P2R_ITypeFwdMapFillIn, tasks_count); + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, tasks_count); + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + tasks_inputs[idx].tpi_hash = tpi_hash; + tasks_inputs[idx].tpi_leaf = tpi_leaf; + tasks_inputs[idx].itype_first = idx*task_size_itypes; + tasks_inputs[idx].itype_opl = tasks_inputs[idx].itype_first + task_size_itypes; + tasks_inputs[idx].itype_opl = ClampTop(tasks_inputs[idx].itype_opl, itype_opl); + tasks_inputs[idx].itype_fwd_map = itype_fwd_map; + tasks[idx] = async_task_launch(scratch.arena, p2r_itype_fwd_map_fill_work, .input = &tasks_inputs[idx]); + } + + //- rjf: join all tasks + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + async_task_join(tasks[idx]); + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: types pass 2: produce per-itype itype chain + // + // this pass is to ensure that subsequent passes always produce types for + // dependent itypes first - guaranteeing rdi's "only reference backward" + // rule (which eliminates cycles). each itype slot gets a list of itypes, + // starting with the deepest dependency - when types are produced per-itype, + // this chain is walked, so that deeper dependencies are built first, and + // as such, always show up *earlier* in the actually built types. + // + P2R_TypeIdChain **itype_chains = 0; + if(tpi_leaf != 0 && in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 2: produce per-itype itype chain (for producing dependent types first)") + { + //- rjf: allocate itype chain table + itype_chains = push_array(arena, P2R_TypeIdChain *, (U64)itype_opl); + + //- rjf: kick off tasks to fill itype chain table + U64 task_size_itypes = 1024; + U64 tasks_count = ((U64)itype_opl+(task_size_itypes-1))/task_size_itypes; + P2R_ITypeChainBuildIn *tasks_inputs = push_array(scratch.arena, P2R_ITypeChainBuildIn, tasks_count); + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, tasks_count); + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + tasks_inputs[idx].tpi_leaf = tpi_leaf; + tasks_inputs[idx].itype_first = idx*task_size_itypes; + tasks_inputs[idx].itype_opl = tasks_inputs[idx].itype_first + task_size_itypes; + tasks_inputs[idx].itype_opl = ClampTop(tasks_inputs[idx].itype_opl, itype_opl); + tasks_inputs[idx].itype_chains = itype_chains; + tasks_inputs[idx].itype_fwd_map = itype_fwd_map; + tasks[idx] = async_task_launch(scratch.arena, p2r_itype_chain_build_work, .input = &tasks_inputs[idx]); + } + + //- rjf: join all tasks + for(U64 idx = 0; idx < tasks_count; idx += 1) + { + async_task_join(tasks[idx]); + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: types pass 3: construct all types from TPI // // this doesn't gather struct/class/union/enum members, which is done by // subsequent passes, to build RDI "UDT" information, which is distinct // from regular type info. // - RDIM_Type **itype_type_ptrs = 0; - RDIM_TypeChunkList all_types = {0}; -#define p2r_type_ptr_from_itype(itype) (((itype) < tpi_leaf->itype_opl) ? itype_type_ptrs[itype] : 0) - if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") + RDIM_Type **itype_type_ptrs = 0; + RDIM_TypeChunkList all_types = {0}; +#define p2r_type_ptr_from_itype(itype) ((itype_type_ptrs && (itype) < itype_opl) ? (itype_type_ptrs[(itype_fwd_map[(itype)] ? itype_fwd_map[(itype)] : (itype))]) : 0) + if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 3: construct all root/stub types from TPI") { - itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); - - ////////////////////////// - //- build basic type - // + itype_type_ptrs = push_array(arena, RDIM_Type *, (U64)(itype_opl)); + for(CV_TypeId root_itype = 0; root_itype < itype_opl; root_itype += 1) { - RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - - RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); - RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); - RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); - RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); - RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); - RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); - RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); - RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); - RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); - - struct + for(P2R_TypeIdChain *itype_chain = itype_chains[root_itype]; + itype_chain != 0; + itype_chain = itype_chain->next) { - char * name; - RDI_TypeKind kind_rdi; - CV_LeafKind kind_cv; - B32 make_pointer_near; - B32 make_pointer_32; - B32 make_pointer_64; - } - table[] = - { - { "" , RDI_TypeKind_NULL , CV_BasicType_NOTYPE , 0, 0, 0 }, - { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, - { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, - { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, - { "short" , short_type , CV_BasicType_SHORT , 1, 1, 1 }, - { "long" , long_type , CV_BasicType_LONG , 1, 1, 1 }, - { "long long" , long_long_type , CV_BasicType_QUAD , 1, 1, 1 }, - { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT , 1, 1, 1 }, // Clang type - { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR , 1, 1, 1 }, - { "unsigned short" , ushort_type , CV_BasicType_USHORT , 1, 1, 1 }, - { "unsigned long" , ulong_type , CV_BasicType_ULONG , 1, 1, 1 }, - { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD , 1, 1, 1 }, - { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT , 1, 1, 1 }, // Clang type - { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 , 1, 1, 1 }, - { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 , 1, 1, 1 }, // not real C type - { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 , 1, 1, 1 }, // not real C type - { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 , 1, 1, 1 }, - { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 , 1, 1, 1 }, - { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 , 1, 1, 1 }, - { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 , 1, 1, 1 }, // Clang type - { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 , 1, 1, 1 }, // not real C type - { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP , 1, 1, 1 }, // not real C type - { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 , 0, 0, 0 }, - { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 , 0, 0, 0 }, - { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 , 0, 0, 0 }, - { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 , 0, 0, 0 }, - { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 , 1, 1, 1 }, - { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, - { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, - { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, - { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, - { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, - { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, - { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, - { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, - { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 , 1, 1, 1 }, - { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR , 1, 1, 1 }, // always ASCII - { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR , 1, 1, 1 }, // on windows always UTF-16 - { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 , 1, 1, 1 }, // always UTF-8 - { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 , 1, 1, 1 }, // always UTF-16 - { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 - { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } - }; - - for(U64 i = 0; i < ArrayCount(table); i += 1) - { - U64 builtin_size; - if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) + CV_TypeId itype = (root_itype != itype_chain->itype && itype_chain->itype < itype_opl && itype_fwd_map[itype_chain->itype]) ? itype_fwd_map[itype_chain->itype] : itype_chain->itype; + B32 itype_is_basic = (itype < 0x1000); + + ////////////////////////// + //- rjf: skip forward-reference itypes - all future resolutions will + // reference whatever this itype resolves to, and so there is no point + // in filling out this slot + // + if(itype_fwd_map[root_itype] != 0) { - builtin_size = arch_addr_size; + continue; } - else + + ////////////////////////// + //- rjf: skip already produced dependencies + // + if(itype_type_ptrs[itype] != 0) { - builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); + continue; } - - RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - builtin->kind = table[i].kind_rdi; - builtin->name = str8_cstring(table[i].name); - builtin->byte_size = builtin_size; - - itype_type_ptrs[table[i].kind_cv] = builtin; - - if(table[i].make_pointer_near) + + ////////////////////////// + //- rjf: build basic type + // + if(itype_is_basic) { - CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; - RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_near->kind = RDI_TypeKind_Ptr; - ptr_near->byte_size = 2; - ptr_near->direct_type = builtin; - - itype_type_ptrs[near_ptr_itype] = ptr_near; - } - if(table[i].make_pointer_32) - { - CV_TypeIndex ptr_32_itype = table[i].kind_cv | 0x400; - RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_32->kind = RDI_TypeKind_Ptr; - ptr_32->byte_size = 4; - ptr_32->direct_type = builtin; - - itype_type_ptrs[ptr_32_itype] = ptr_32; - } - if(table[i].make_pointer_64) - { - CV_TypeIndex ptr_64_itype = table[i].kind_cv | 0x600; - RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_64->kind = RDI_TypeKind_Ptr; - ptr_64->byte_size = 8; - ptr_64->direct_type = builtin; - - itype_type_ptrs[ptr_64_itype] = ptr_64; - } - } - } - - ////////////////////////// - //- rjf: build non-basic type - // - for(CV_TypeId itype = tpi_leaf->itype_first; itype < tpi_leaf->itype_opl; itype += 1) - { - RDIM_Type *dst_type = 0; - CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; - CV_LeafKind kind = range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - - if(range->off+range->hdr.size <= tpi_leaf->data.size && - range->off+2+header_struct_size <= tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - //- rjf: MODIFIER - case CV_LeafKind_MODIFIER: - { - // rjf: unpack leaf - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: cv -> rdi flags - RDI_TypeModifierFlags flags = 0; - if(lf->flags & CV_ModifierFlag_Const) {flags |= RDI_TypeModifierFlag_Const;} - if(lf->flags & CV_ModifierFlag_Volatile) {flags |= RDI_TypeModifierFlag_Volatile;} - - // rjf: fill type - if(flags == 0) - { - dst_type = p2r_type_ptr_from_itype(lf->itype); - } - else - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = RDI_TypeKind_Modifier; - dst_type->flags = flags; - dst_type->direct_type = p2r_type_ptr_from_itype(lf->itype); - dst_type->byte_size = dst_type->direct_type ? dst_type->direct_type->byte_size : 0; - } - }break; + RDIM_Type *dst_type = 0; - //- rjf: POINTER - case CV_LeafKind_POINTER: - { - // TODO(rjf): if ptr_mode in {PtrMem, PtrMethod} then output a member pointer instead - - // rjf: unpack leaf - CV_LeafPointer *lf = (CV_LeafPointer *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); - CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(lf->attribs); - CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(lf->attribs); - U32 ptr_size = CV_PointerAttribs_Extract_Size(lf->attribs); - - // rjf: cv -> rdi modifier flags - RDI_TypeModifierFlags modifier_flags = 0; - if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} - if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} - if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} - - // rjf: cv info -> rdi pointer type kind - RDI_TypeKind type_kind = RDI_TypeKind_Ptr; - { - if(lf->attribs & CV_PointerAttrib_LRef) - { - type_kind = RDI_TypeKind_LRef; - } - else if(lf->attribs & CV_PointerAttrib_RRef) - { - type_kind = RDI_TypeKind_RRef; - } - if(ptr_mode == CV_PointerMode_LRef) - { - type_kind = RDI_TypeKind_LRef; - } - else if(ptr_mode == CV_PointerMode_RRef) - { - type_kind = RDI_TypeKind_RRef; - } - } - - // rjf: fill type - if(modifier_flags != 0) - { - RDIM_Type *pointer_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = RDI_TypeKind_Modifier; - dst_type->flags = modifier_flags; - dst_type->direct_type = pointer_type; - dst_type->byte_size = arch_addr_size; - pointer_type->kind = type_kind; - pointer_type->byte_size = arch_addr_size; - pointer_type->direct_type = direct_type; - } - else - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = type_kind; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = direct_type; - } - }break; + // rjf: unpack itype + CV_BasicPointerKind cv_basic_ptr_kind = CV_BasicPointerKindFromTypeId(itype); + CV_BasicType cv_basic_type_code = CV_BasicTypeFromTypeId(itype); - //- rjf: PROCEDURE - case CV_LeafKind_PROCEDURE: + // rjf: get basic type slot, fill if unfilled + RDIM_Type *basic_type = itype_type_ptrs[cv_basic_type_code]; + if(basic_type == 0) { - // TODO(rjf): handle call_kind & attribs - - // rjf: unpack leaf - CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; - RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); - - // rjf: fill type's basics - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = RDI_TypeKind_Function; + RDI_TypeKind type_kind = p2r_rdi_type_kind_from_cv_basic_type(cv_basic_type_code); + U32 byte_size = rdi_size_from_basic_type_kind(type_kind); + basic_type = dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(byte_size == 0xffffffff) + { + byte_size = arch_addr_size; + } + basic_type->kind = type_kind; + basic_type->name = cv_type_name_from_basic_type(cv_basic_type_code); + basic_type->byte_size = byte_size; + } + + // rjf: nonzero ptr kind -> form ptr type to basic tpye + if(cv_basic_ptr_kind != 0) + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Ptr; dst_type->byte_size = arch_addr_size; - dst_type->direct_type = ret_type; - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: build param type array - RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count); - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - params[idx] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); - } - - // rjf: fill dst type - dst_type->count = arglist_itypes_count; - dst_type->param_types = params; - }break; + dst_type->direct_type = basic_type; + } - //- rjf: MFUNCTION - case CV_LeafKind_MFUNCTION: + // rjf: fill this itype's slot with the finished type + itype_type_ptrs[itype] = dst_type; + } + + ////////////////////////// + //- rjf: build non-basic type + // + if(!itype_is_basic && itype >= itype_first) + { + RDIM_Type *dst_type = 0; + CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-itype_first]; + CV_LeafKind kind = range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); + if(range->off+range->hdr.size <= tpi_leaf->data.size && + range->off+2+header_struct_size <= tpi_leaf->data.size && + range->hdr.size >= 2) { - // TODO(rjf): handle call_kind & attribs - // TODO(rjf): preserve "this_adjust" - - // rjf: unpack leaf - CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; - RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = (lf->this_itype != 0) ? RDI_TypeKind_Method : RDI_TypeKind_Function; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = ret_type; - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + U8 *itype_leaf_first = tpi_leaf->data.str + range->off+2; + U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; + switch(kind) { - break; + //- rjf: MODIFIER + case CV_LeafKind_MODIFIER: + { + // rjf: unpack leaf + CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; + + // rjf: cv -> rdi flags + RDI_TypeModifierFlags flags = 0; + if(lf->flags & CV_ModifierFlag_Const) {flags |= RDI_TypeModifierFlag_Const;} + if(lf->flags & CV_ModifierFlag_Volatile) {flags |= RDI_TypeModifierFlag_Volatile;} + + // rjf: fill type + if(flags == 0) + { + dst_type = p2r_type_ptr_from_itype(lf->itype); + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = flags; + dst_type->direct_type = p2r_type_ptr_from_itype(lf->itype); + dst_type->byte_size = dst_type->direct_type ? dst_type->direct_type->byte_size : 0; + } + }break; + + //- rjf: POINTER + case CV_LeafKind_POINTER: + { + // TODO(rjf): if ptr_mode in {PtrMem, PtrMethod} then output a member pointer instead + + // rjf: unpack leaf + CV_LeafPointer *lf = (CV_LeafPointer *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(lf->attribs); + CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(lf->attribs); + U32 ptr_size = CV_PointerAttribs_Extract_Size(lf->attribs); + + // rjf: cv -> rdi modifier flags + RDI_TypeModifierFlags modifier_flags = 0; + if(lf->attribs & CV_PointerAttrib_Const) {modifier_flags |= RDI_TypeModifierFlag_Const;} + if(lf->attribs & CV_PointerAttrib_Volatile) {modifier_flags |= RDI_TypeModifierFlag_Volatile;} + if(lf->attribs & CV_PointerAttrib_Restricted) {modifier_flags |= RDI_TypeModifierFlag_Restrict;} + + // rjf: cv info -> rdi pointer type kind + RDI_TypeKind type_kind = RDI_TypeKind_Ptr; + { + if(lf->attribs & CV_PointerAttrib_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(lf->attribs & CV_PointerAttrib_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + if(ptr_mode == CV_PointerMode_LRef) + { + type_kind = RDI_TypeKind_LRef; + } + else if(ptr_mode == CV_PointerMode_RRef) + { + type_kind = RDI_TypeKind_RRef; + } + } + + // rjf: fill type + if(modifier_flags != 0) + { + RDIM_Type *pointer_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Modifier; + dst_type->flags = modifier_flags; + dst_type->direct_type = pointer_type; + dst_type->byte_size = arch_addr_size; + pointer_type->kind = type_kind; + pointer_type->byte_size = arch_addr_size; + pointer_type->direct_type = direct_type; + } + else + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = type_kind; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = direct_type; + } + }break; + + //- rjf: PROCEDURE + case CV_LeafKind_PROCEDURE: + { + // TODO(rjf): handle call_kind & attribs + + // rjf: unpack leaf + CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type's basics + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count; + dst_type->param_types = params; + }break; + + //- rjf: MFUNCTION + case CV_LeafKind_MFUNCTION: + { + // TODO(rjf): handle call_kind & attribs + // TODO(rjf): preserve "this_adjust" + + // rjf: unpack leaf + CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; + RDIM_Type *ret_type = p2r_type_ptr_from_itype(lf->ret_itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = (lf->this_itype != 0) ? RDI_TypeKind_Method : RDI_TypeKind_Function; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = ret_type; + + // rjf: unpack arglist range + CV_RecRange *arglist_range = &tpi_leaf->leaf_ranges.ranges[lf->arg_itype-itype_first]; + if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || + arglist_range->hdr.size<2 || + arglist_range->off + arglist_range->hdr.size > tpi_leaf->data.size) + { + break; + } + U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; + U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; + if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) + { + break; + } + + // rjf: unpack arglist info + CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; + CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); + U32 arglist_itypes_count = arglist->count; + + // rjf: build param type array + U64 num_this_extras = 1; + if(lf->this_itype == 0) + { + num_this_extras = 0; + } + RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count+num_this_extras); + for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) + { + params[idx+num_this_extras] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); + } + if(lf->this_itype != 0) + { + params[0] = p2r_type_ptr_from_itype(lf->this_itype); + } + + // rjf: fill dst type + dst_type->count = arglist_itypes_count+num_this_extras; + dst_type->param_types = params; + }break; + + //- rjf: BITFIELD + case CV_LeafKind_BITFIELD: + { + // rjf: unpack leaf + CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Bitfield; + dst_type->off = lf->pos; + dst_type->count = lf->len; + dst_type->byte_size = direct_type?direct_type->byte_size:0; + dst_type->direct_type = direct_type; + }break; + + //- rjf: ARRAY + case CV_LeafKind_ARRAY: + { + // rjf: unpack leaf + CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->entry_itype); + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed array_count = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 full_size = cv_u64_from_numeric(&array_count); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Array; + dst_type->direct_type = direct_type; + dst_type->byte_size = full_size; + dst_type->count = (direct_type && direct_type->byte_size) ? (dst_type->byte_size/direct_type->byte_size) : 0; + }break; + + //- rjf: CLASS/STRUCTURE + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + dst_type->name = name; + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + }break; + + //- rjf: CLASS2/STRUCT2 + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); + dst_type->name = name; + } + else + { + dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_Class : RDI_TypeKind_Struct); + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + }break; + + //- rjf: UNION + case CV_LeafKind_UNION: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; + U8 *numeric_ptr = (U8*)(lf + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); + U64 size_u64 = cv_u64_from_numeric(&size); + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteUnion; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Union; + dst_type->byte_size = (U32)size_u64; + dst_type->name = name; + } + }break; + + //- rjf: ENUM + case CV_LeafKind_ENUM: + { + // TODO(rjf): handle props + + // rjf: unpack leaf + CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; + RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->base_itype); + U8 *name_ptr = (U8 *)(lf + 1); + String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); + + // rjf: fill type + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(lf->props & CV_TypeProp_FwdRef) + { + dst_type->kind = RDI_TypeKind_IncompleteEnum; + dst_type->name = name; + } + else + { + dst_type->kind = RDI_TypeKind_Enum; + dst_type->direct_type = direct_type; + dst_type->byte_size = direct_type ? direct_type->byte_size : 0; + dst_type->name = name; + } + }break; } - U8 *arglist_first = tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: build param type array - U64 num_this_extras = 1; - if(lf->this_itype == 0) - { - num_this_extras = 0; - } - RDIM_Type **params = push_array(arena, RDIM_Type *, arglist_itypes_count+num_this_extras); - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - params[idx+num_this_extras] = p2r_type_ptr_from_itype(arglist_itypes_base[idx]); - } - if(lf->this_itype != 0) - { - params[0] = p2r_type_ptr_from_itype(lf->this_itype); - } - - // rjf: fill dst type - dst_type->count = arglist_itypes_count+num_this_extras; - dst_type->param_types = params; - }break; + } - //- rjf: BITFIELD - case CV_LeafKind_BITFIELD: - { - // rjf: unpack leaf - CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->itype); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = RDI_TypeKind_Bitfield; - dst_type->off = lf->pos; - dst_type->count = lf->len; - dst_type->byte_size = direct_type?direct_type->byte_size:0; - dst_type->direct_type = direct_type; - }break; - - //- rjf: ARRAY - case CV_LeafKind_ARRAY: - { - // rjf: unpack leaf - CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->entry_itype); - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed array_count = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 full_size = cv_u64_from_numeric(&array_count); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - dst_type->kind = RDI_TypeKind_Array; - dst_type->direct_type = direct_type; - dst_type->byte_size = full_size; - }break; - - //- rjf: CLASS/STRUCTURE - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); - } - else - { - dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); - } - - B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && - ((lf->props & CV_TypeProp_HasUniqueName) != 0)); - if(do_unique_name_lookup) - { - U8 *unique_name_ptr = name_ptr + name.size + 1; - dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - } - - dst_type->name = name; - dst_type->byte_size = safe_cast_u32(size_u64); - }break; - - //- rjf: CLASS2/STRUCT2 - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_IncompleteStruct); - dst_type->name = name; - } - else - { - dst_type->kind = (kind == CV_LeafKind_CLASS2 ? RDI_TypeKind_Class : RDI_TypeKind_Struct); - dst_type->byte_size = (U32)size_u64; - dst_type->name = name; - } - - B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && - ((lf->props & CV_TypeProp_HasUniqueName) != 0)); - if(do_unique_name_lookup) - { - U8 *unique_name_ptr = name_ptr + name.size + 1; - dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - } - }break; - - //- rjf: UNION - case CV_LeafKind_UNION: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; - U8 *numeric_ptr = (U8*)(lf + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U64 size_u64 = cv_u64_from_numeric(&size); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = RDI_TypeKind_IncompleteUnion; - dst_type->name = name; - } - else - { - dst_type->kind = RDI_TypeKind_Union; - dst_type->byte_size = (U32)size_u64; - dst_type->name = name; - } - - B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && - ((lf->props & CV_TypeProp_HasUniqueName) != 0)); - if(do_unique_name_lookup) - { - U8 *unique_name_ptr = name_ptr + name.size + 1; - dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - // TODO(rjf): handle props - - // rjf: unpack leaf - CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; - RDIM_Type *direct_type = p2r_type_ptr_from_itype(lf->base_itype); - U8 *name_ptr = (U8 *)(lf + 1); - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - - // rjf: fill type - dst_type = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - if(lf->props & CV_TypeProp_FwdRef) - { - dst_type->kind = RDI_TypeKind_IncompleteEnum; - dst_type->name = name; - } - else - { - dst_type->kind = RDI_TypeKind_Enum; - dst_type->direct_type = direct_type; - dst_type->byte_size = direct_type ? direct_type->byte_size : 0; - dst_type->name = name; - } - - B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && - ((lf->props & CV_TypeProp_HasUniqueName) != 0)); - if(do_unique_name_lookup) - { - U8 *unique_name_ptr = name_ptr + name.size + 1; - dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - } - }break; + //- rjf: store finalized type to this itype's slot + itype_type_ptrs[itype] = dst_type; } } - - //- rjf: store finalized type to this itype's slot - itype_type_ptrs[itype] = dst_type; } } ////////////////////////////////////////////////////////////// - //- rjf: types pass 2: kick off UDT build + //- rjf: types pass 4: kick off UDT build // U64 udt_task_size_itypes = 4096; - U64 udt_tasks_count = (tpi_leaf->itype_opl+(udt_task_size_itypes-1))/udt_task_size_itypes; + U64 udt_tasks_count = ((U64)itype_opl+(udt_task_size_itypes-1))/udt_task_size_itypes; P2R_UDTConvertIn *udt_tasks_inputs = push_array(scratch.arena, P2R_UDTConvertIn, udt_tasks_count); ASYNC_Task **udt_tasks = push_array(scratch.arena, ASYNC_Task *, udt_tasks_count); - if(in->flags & P2R_ConvertFlag_UDTs) ProfScope("types pass 2: kick off UDT build") + if(in->flags & P2R_ConvertFlag_UDTs) ProfScope("types pass 4: kick off UDT build") { for(U64 idx = 0; idx < udt_tasks_count; idx += 1) { udt_tasks_inputs[idx].tpi_leaf = tpi_leaf; udt_tasks_inputs[idx].itype_first = idx*udt_task_size_itypes; udt_tasks_inputs[idx].itype_opl = udt_tasks_inputs[idx].itype_first + udt_task_size_itypes; - udt_tasks_inputs[idx].itype_opl = ClampTop(udt_tasks_inputs[idx].itype_opl, tpi_leaf->itype_opl); + udt_tasks_inputs[idx].itype_opl = ClampTop(udt_tasks_inputs[idx].itype_opl, itype_opl); + udt_tasks_inputs[idx].itype_fwd_map = itype_fwd_map; udt_tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; udt_tasks[idx] = async_task_launch(scratch.arena, p2r_udt_convert_work, .input = &udt_tasks_inputs[idx]); } @@ -3479,6 +3907,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) tasks_inputs[idx].tpi_hash = tpi_hash; tasks_inputs[idx].tpi_leaf = tpi_leaf; tasks_inputs[idx].ipi_leaf = ipi_leaf; + tasks_inputs[idx].itype_fwd_map = itype_fwd_map; tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; tasks_inputs[idx].link_name_map = link_name_map; if(idx < global_stream_subdivision_tasks_count) diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index f9effda5..03cae2d2 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -201,6 +201,37 @@ struct P2R_LinkNameMapBuildIn P2R_LinkNameMap *link_name_map; }; +//- rjf: type forward resolution map build + +typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn; +struct P2R_ITypeFwdMapFillIn +{ + PDB_TpiHashParsed *tpi_hash; + CV_LeafParsed *tpi_leaf; + CV_TypeId itype_first; + CV_TypeId itype_opl; + CV_TypeId *itype_fwd_map; +}; + +//- rjf: itype chain build + +typedef struct P2R_TypeIdChain P2R_TypeIdChain; +struct P2R_TypeIdChain +{ + P2R_TypeIdChain *next; + CV_TypeId itype; +}; + +typedef struct P2R_ITypeChainBuildIn P2R_ITypeChainBuildIn; +struct P2R_ITypeChainBuildIn +{ + CV_LeafParsed *tpi_leaf; + CV_TypeId itype_first; + CV_TypeId itype_opl; + CV_TypeId *itype_fwd_map; + P2R_TypeIdChain **itype_chains; +}; + //- rjf: udt conversion typedef struct P2R_UDTConvertIn P2R_UDTConvertIn; @@ -209,6 +240,7 @@ struct P2R_UDTConvertIn CV_LeafParsed *tpi_leaf; CV_TypeId itype_first; CV_TypeId itype_opl; + CV_TypeId *itype_fwd_map; RDIM_Type **itype_type_ptrs; }; @@ -225,6 +257,7 @@ struct P2R_SymbolStreamConvertIn CV_SymParsed *sym; U64 sym_ranges_first; U64 sym_ranges_opl; + CV_TypeId *itype_fwd_map; RDIM_Type **itype_type_ptrs; P2R_LinkNameMap *link_name_map; RDIM_LineTable *first_inline_site_line_table; @@ -308,6 +341,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work); ASYNC_WORK_DEF(p2r_link_name_map_build_work); +//////////////////////////////// +//~ rjf: Type Parsing/Conversion Tasks + +ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work); +ASYNC_WORK_DEF(p2r_itype_chain_build_work); + //////////////////////////////// //~ rjf: UDT Conversion Tasks diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index 6ab7a29b..9b2e49b5 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -15,9 +15,6 @@ #include "lib_rdi_format/rdi_format.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" -#define XXH_STATIC_LINKING_ONLY -#include "third_party/xxHash/xxhash.h" -#include "third_party/xxHash/xxhash.c" //- rjf: [h] #include "base/base_inc.h" diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c new file mode 100644 index 00000000..28d27f22 --- /dev/null +++ b/src/rdi_make/rdi_make_help.c @@ -0,0 +1,925 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: bake string map building + +#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) + +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_units_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_types_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake type strings") + { + for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_udts_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake udt strings") + { + for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake symbol strings") + { + for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSiteStringsIn *in = input; + rdim_make_string_map_if_needed(); + ProfScope("bake inline site strings") + { + for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake scope strings") + { + for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_line_tables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; + RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); + ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); + return out; +} + +#undef rdim_make_string_map_if_needed + +//- rjf: bake string map joining + +ASYNC_WORK_DEF(rdim_bake_string_map_join_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; + ProfScope("join bake string maps") + { + for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) + { + for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) + { + B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); + B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); + if(src_slots_good && dst_slot_is_zero) + { + in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; + } + else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) + { + rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: bake string map sorting + +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; + ProfScope("sort bake string chunk list map range") + { + for(U64 slot_idx = in->slot_idx; + slot_idx < in->slot_idx+in->slot_count; + slot_idx += 1) + { + if(in->src_map->slots[slot_idx] != 0) + { + if(in->src_map->slots[slot_idx]->total_count > 1) + { + in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); + *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); + } + else + { + in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: pass 1: interner/deduper map builds + +ASYNC_WORK_DEF(rdim_build_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; + RDIM_BakeNameMap *name_map = 0; + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); + ProfEnd(); + return name_map; +} + +//- rjf: pass 2: string-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_units_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; + RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); + ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; + RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); + ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_src_files_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; + RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); + ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_udts_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; + RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; + RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; + RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); + ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_thread_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; + RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_procedures_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; + RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; + RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; + RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); + ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_inline_sites_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; + RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_file_paths_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; + RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); + ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; + RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); + ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); + ProfEnd(); + return out; +} + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_type_nodes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; + RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; + RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); + ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_idx_runs_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; + RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; + RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); + ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); + ProfEnd(); + return out; +} + +internal RDIM_HelpState * +rdim_help_init(void) +{ + Arena *arena = arena_alloc(); + RDIM_HelpState *state = push_array(arena, RDIM_HelpState, 1); + state->arena = arena; + state->work_thread_arenas_count = async_thread_count(); + state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); + for EachIndex(idx, state->work_thread_arenas_count) + { + state->work_thread_arenas[idx] = arena_alloc(); + } + return state; +} + +internal RDIM_BakeResults +rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +{ + Temp scratch = scratch_begin(0,0); + RDIM_BakeResults out = {0}; + + rdim_help_state = state; + + //////////////////////////////// + // compute type indices + + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); + + ////////////////////////////// + //- rjf: kick off line tables baking + // + ASYNC_Task *bake_line_tables_task = 0; + { + RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); + in->line_tables = &in_params->line_tables; + bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); + } + + ////////////////////////////// + //- rjf: build interned path tree + // + RDIM_BakePathTree *path_tree = 0; + ProfScope("build interned path tree") + { + path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + } + + ////////////////////////////// + //- rjf: kick off string map building tasks + // + RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + + in_params->procedures.total_count*1 + + in_params->global_variables.total_count*1 + + in_params->thread_variables.total_count*1 + + in_params->types.total_count/2)}; + RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); + ASYNC_TaskList bake_string_map_build_tasks = {0}; + { + // rjf: src files + ProfScope("kick off src files string map build task") + { + RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->src_files; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); + } + + // rjf: units + ProfScope("kick off units string map build task") + { + RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->units; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); + } + + // rjf: types + ProfScope("kick off types string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; + RDIM_TypeChunkNode *chunk = in_params->types.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); + } + } + + // rjf: UDTs + ProfScope("kick off udts string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; + RDIM_UDTChunkNode *chunk = in_params->udts.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); + } + } + + // rjf: symbols + ProfScope("kick off symbols string map build tasks") + { + RDIM_SymbolChunkList *symbol_lists[] = + { + &in_params->global_variables, + &in_params->thread_variables, + &in_params->procedures, + }; + for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) + { + U64 items_per_task = 4096; + U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; + RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); + } + } + } + + ProfScope("kick off inline site string map build task") + { + U64 items_per_task = 4096; + U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); + RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); + } + } + + // rjf: scope chunks + ProfScope("kick off scope chunks string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; + RDIM_ScopeChunkNode *chunk = in_params->scopes.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); + } + } + } + + ////////////////////////////// + //- rjf: kick off name map building tasks + // + RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; + ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + build_bake_name_map_in[k].k = k; + build_bake_name_map_in[k].type_indices = type_indices; + build_bake_name_map_in[k].params = in_params; + build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); + } + + ////////////////////////////// + //- rjf: join string map building tasks + // + ProfScope("join string map building tasks") + { + for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + + ////////////////////////////// + //- rjf: produce joined string map + // + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + ProfScope("produce joined string map") + { + U64 slots_per_task = 16384; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); + + // rjf: kickoff tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); + in->top = &bake_string_map_topology; + in->src_maps = bake_string_maps__in_progress; + in->src_maps_count = async_thread_count(); + in->dst_map = unsorted_bake_string_map; + in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); + in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); + tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); + } + + // rjf: join tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + async_task_join(tasks[task_idx]); + } + + // rjf: insert small top-level stuff + rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + } + + ////////////////////////////// + //- rjf: kick off string map sorting tasks + // + ASYNC_TaskList sort_bake_string_map_tasks = {0}; + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + { + U64 slots_per_task = 4096; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); + { + in->top = &bake_string_map_topology; + in->src_map = unsorted_bake_string_map; + in->dst_map = sorted_bake_string_map__in_progress; + in->slot_idx = task_idx*slots_per_task; + in->slot_count = slots_per_task; + if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) + { + in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; + } + } + async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); + } + } + + ////////////////////////////// + //- rjf: join string map sorting tasks + // + ProfScope("join string map sorting tasks") + { + for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; + + ////////////////////////////// + //- rjf: build finalized string map + // + ProfBegin("build finalized string map base indices"); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + ProfEnd(); + ProfBegin("build finalized string map"); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + ProfEnd(); + + ////////////////////////////// + //- rjf: kick off pass 2 tasks + // + RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; + ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); + RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; + ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); + RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; + ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; + ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); + RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; + ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); + RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; + ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; + ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); + RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; + ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); + RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; + ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); + + RDIM_String8List location_blocks = {0}; + RDIM_String8List location_data_blobs = {0}; + + // reserve null location block for opl + rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); + + // TODO: export location instead of VOFF + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; + ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); + ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); + + // TODO: export location instead of VOFF + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; + ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); + ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); + + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); + ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); + + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); + ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); + + ////////////////////////////// + //- rjf: join name map building tasks + // + RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; + ProfScope("join name map building tasks") + { + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); + } + } + + ////////////////////////////// + //- rjf: build interned idx run map + // + RDIM_BakeIdxRunMap *idx_runs = 0; + ProfScope("build interned idx run map") + { + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); + } + + ////////////////////////////// + //- rjf: do small top-level bakes + // + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + + ////////////////////////////// + //- rjf: kick off pass 3 tasks + // + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; + ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); + ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + if(name_maps[k] == 0 || name_maps[k]->name_count == 0) + { + continue; + } + RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); + in->strings = &bake_strings; + in->idx_runs = idx_runs; + in->map = name_maps[k]; + in->kind = k; + bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); + } + } + RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; + ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); + + ////////////////////////////// + //- rjf: join remaining completed bakes + // + ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); + ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); + ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); + ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); + ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); + ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); + ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); + ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); + ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); + ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); + ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); + ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); + + ////////////////////////////// + //- rjf: join individual name map bakes + // + RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; + ProfScope("name maps") + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); + if(bake != 0) + { + name_map_bakes[k] = *bake; + } + } + } + + ////////////////////////////// + //- rjf: join all individual name map bakes + // + ProfScope("join all name map bakes into final name map bake") + { + out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + } + + + //////////////////////////////// + + out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); + + rdim_help_state = 0; + + scratch_end(scratch); + return out; +} + +internal RDIM_SerializedSectionBundle +rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) +{ + RDIM_SerializedSectionBundle out = {0}; + + //- rjf: set up compression context + rr_lzb_simple_context ctx = {0}; + ctx.m_tableSizeBits = 14; + ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; + RDIM_SerializedSection *dst = &out.sections[k]; + MemoryCopyStruct(dst, src); + + // rjf: determine if this section should be compressed + B32 should_compress = 1; + + // rjf: compress if needed + if(should_compress) + { + MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); + dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); + dst->unpacked_size = src->encoded_size; + dst->encoding = RDI_SectionEncoding_LZB; + } + } + + return out; +} diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h new file mode 100644 index 00000000..08c64391 --- /dev/null +++ b/src/rdi_make/rdi_make_help.h @@ -0,0 +1,342 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RDIM_MAKE_HELP +#define RDIM_MAKE_HELP + +//- rjf: line table baking task types + +typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; +struct RDIM_BakeLineTablesIn +{ + RDIM_LineTableChunkList *line_tables; +}; + +//- rjf: string map baking task types + +typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; +struct RDIM_BakeSrcFilesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_SrcFileChunkList *list; +}; + +typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; +struct RDIM_BakeUnitsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_UnitChunkList *list; +}; + +typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; +struct RDIM_BakeUDTsStringsInNode +{ + RDIM_BakeUDTsStringsInNode *next; + RDIM_UDT *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; +struct RDIM_BakeTypesStringsInNode +{ + RDIM_BakeTypesStringsInNode *next; + RDIM_Type *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; +struct RDIM_BakeTypesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeTypesStringsInNode *first; + RDIM_BakeTypesStringsInNode *last; +}; + +typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; +struct RDIM_BakeUDTsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeUDTsStringsInNode *first; + RDIM_BakeUDTsStringsInNode *last; +}; + +typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; +struct RDIM_BakeSymbolsStringsInNode +{ + RDIM_BakeSymbolsStringsInNode *next; + RDIM_Symbol *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; +struct RDIM_BakeSymbolsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeSymbolsStringsInNode *first; + RDIM_BakeSymbolsStringsInNode *last; +}; + +typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; +struct RDIM_BakeInlineSiteStringsInNode +{ + RDIM_BakeInlineSiteStringsInNode *next; + RDIM_InlineSite *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; +struct RDIM_BakeInlineSiteStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeInlineSiteStringsInNode *first; + RDIM_BakeInlineSiteStringsInNode *last; +}; + +typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; +struct RDIM_BakeScopesStringsInNode +{ + RDIM_BakeScopesStringsInNode *next; + RDIM_Scope *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; +struct RDIM_BakeScopesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeScopesStringsInNode *first; + RDIM_BakeScopesStringsInNode *last; +}; + +//- rjf: OLD string map baking types + +typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; +struct RDIM_BuildBakeStringMapIn +{ + RDIM_BakePathTree *path_tree; + RDIM_BakeParams *params; +}; + +typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; +struct RDIM_BuildBakeNameMapIn +{ + RDI_NameMapKind k; + RDI_U64 *type_indices; + RDIM_BakeParams *params; +}; + +//- rjf: string map joining task types + +typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; +struct RDIM_JoinBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **src_maps; + U64 src_maps_count; + RDIM_BakeStringMapLoose *dst_map; + Rng1U64 slot_idx_range; +}; + +//- rjf: string map sorting task types + +typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; +struct RDIM_SortBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose *src_map; + RDIM_BakeStringMapLoose *dst_map; + U64 slot_idx; + U64 slot_count; +}; + +//- rjf: debug info baking task types + +typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; +struct RDIM_BakeUnitsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; +struct RDIM_BakeUnitVMapIn +{ + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; +struct RDIM_BakeSrcFilesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_SrcFileChunkList *src_files; +}; + +typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; +struct RDIM_BakeUDTsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_UDTChunkList *udts; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; +struct RDIM_BakeGlobalVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *global_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; +struct RDIM_BakeGlobalVMapIn +{ + RDIM_SymbolChunkList *global_variables; +}; + +typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; +struct RDIM_BakeThreadVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *thread_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; +struct RDIM_BakeProceduresIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *procedures; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; +struct RDIM_BakeScopesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_ScopeChunkList *scopes; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; +struct RDIM_BakeScopeVMapIn +{ + RDIM_ScopeChunkList *scopes; +}; + +typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; +struct RDIM_BakeInlineSitesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_InlineSiteChunkList *inline_sites; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; +struct RDIM_BakeFilePathsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; +}; + +typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; +struct RDIM_BakeStringsIn +{ + RDIM_BakeStringMapTight *strings; +}; + +typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; +struct RDIM_BakeTypeNodesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_TypeChunkList *types; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; +struct RDIM_BakeNameMapIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_BakeNameMap *map; + RDI_NameMapKind kind; +}; + +typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; +struct RDIM_BakeIdxRunsIn +{ + RDIM_BakeIdxRunMap *idx_runs; +}; + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: unsorted bake string map building +ASYNC_WORK_DEF(p2r_bake_src_files_strings_work); +ASYNC_WORK_DEF(p2r_bake_units_strings_work); +ASYNC_WORK_DEF(p2r_bake_types_strings_work); +ASYNC_WORK_DEF(p2r_bake_udts_strings_work); +ASYNC_WORK_DEF(p2r_bake_symbols_strings_work); +ASYNC_WORK_DEF(p2r_bake_scopes_strings_work); +ASYNC_WORK_DEF(p2r_bake_line_tables_work); + +//- rjf: bake string map joining +ASYNC_WORK_DEF(p2r_bake_string_map_join_work); + +//- rjf: bake string map sorting +ASYNC_WORK_DEF(p2r_bake_string_map_sort_work); + +//- rjf: pass 1: interner/deduper map builds +ASYNC_WORK_DEF(p2r_build_bake_name_map_work); + +//- rjf: pass 2: string-map-dependent debug info stream builds +ASYNC_WORK_DEF(p2r_bake_units_work); +ASYNC_WORK_DEF(p2r_bake_unit_vmap_work); +ASYNC_WORK_DEF(p2r_bake_src_files_work); +ASYNC_WORK_DEF(p2r_bake_udts_work); +ASYNC_WORK_DEF(p2r_bake_global_variables_work); +ASYNC_WORK_DEF(p2r_bake_global_vmap_work); +ASYNC_WORK_DEF(p2r_bake_thread_variables_work); +ASYNC_WORK_DEF(p2r_bake_procedures_work); +ASYNC_WORK_DEF(p2r_bake_scopes_work); +ASYNC_WORK_DEF(p2r_bake_scope_vmap_work); +ASYNC_WORK_DEF(p2r_bake_file_paths_work); +ASYNC_WORK_DEF(p2r_bake_strings_work); + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds +ASYNC_WORK_DEF(p2r_bake_type_nodes_work); +ASYNC_WORK_DEF(p2r_bake_name_map_work); +ASYNC_WORK_DEF(p2r_bake_idx_runs_work); + +typedef struct RDIM_HelpState RDIM_HelpState; +struct RDIM_HelpState +{ + Arena *arena; + U64 work_thread_arenas_count; + Arena **work_thread_arenas; +}; + +//////////////////////////////// + +global RDIM_HelpState *rdim_help_state = 0; + +//////////////////////////////// + +internal RDIM_HelpState * rdim_help_init(void); +internal RDIM_BakeResults rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in); +internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); + +#endif // RDIM_MAKE_HELP From e1ca449ccbf3294259da72e5f110430b29ab3c25 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 10:16:28 -0700 Subject: [PATCH 571/755] revert type indices change --- src/lib_rdi_make/rdi_make.c | 272 +++++++++++++++++++++------- src/lib_rdi_make/rdi_make.h | 50 +++-- src/rdi_from_dwarf/rdi_from_dwarf.c | 64 +++++++ src/rdi_from_pdb/rdi_from_pdb.c | 168 ++++++++++++----- src/rdi_make/rdi_make_local.c | 43 ++--- src/rdi_make/rdi_make_local.h | 8 - 6 files changed, 444 insertions(+), 161 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 5fc16a59..278dedc1 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -438,6 +438,153 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r } } +//////////////////////////////// +//~ Data Model + +RDI_PROC RDI_TypeKind +rdim_short_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_int_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_long_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + +RDI_PROC RDI_TypeKind +rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model) +{ + switch(data_model) + { + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; + } + return RDI_TypeKind_NULL; +} + //////////////////////////////// //~ rjf: [Building] Binary Section List Building @@ -705,14 +852,6 @@ rdim_idx_from_type(RDIM_Type *type) return idx; } -RDI_PROC RDI_U64 -rdim_final_idx_from_type(RDI_U64 *type_indices, RDIM_Type *type) -{ - RDI_U64 pos = rdim_idx_from_type(type); - RDI_U64 idx = type_indices[pos]; - return idx; -} - RDI_PROC void rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push) { @@ -1069,9 +1208,10 @@ rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *ri } else { - left_dst->last_op = right_destroyed->last_op; - left_dst->op_count += right_destroyed->op_count; - left_dst->encoded_size += right_destroyed->encoded_size; + left_dst->last_op->next = right_destroyed->first_op; + left_dst->last_op = right_destroyed->last_op; + left_dst->op_count += right_destroyed->op_count; + left_dst->encoded_size += right_destroyed->encoded_size; } rdim_memzero_struct(right_destroyed); } @@ -1159,45 +1299,44 @@ rdim_count_from_location_block_chunk_list(RDIM_String8List *list) //////////////////////////////// -RDI_PROC void -rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) +RDI_PROC RDIM_Type * +rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind) { - RDI_U64 type_pos = rdim_idx_from_type(type); - if(type_indices[type_pos] == 0) - { - if(type->param_types) - { - for(RDI_U64 param_idx = 0; param_idx < type->count; param_idx += 1) - { - rdim_assign_type_index(type->param_types[param_idx], type_indices, curr_type_idx); - } + RDI_U64 type_idx = 0; + if (type_kind != RDI_TypeKind_NULL) { + type_idx = (type_kind - RDI_TypeKind_FirstBuiltIn) + 1; } - - if(type->direct_type) - { - rdim_assign_type_index(type->direct_type, type_indices, curr_type_idx); - } - - type_indices[type_pos] = *curr_type_idx; - *curr_type_idx += 1; - } + RDIM_Type *builtin = &list.first->v[type_idx]; + return builtin; } -RDI_PROC RDI_U64 * -rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) +RDI_PROC RDIM_TypeChunkList +rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) { - RDI_U64 *type_indices = rdim_push_array(arena, RDI_U64, types->total_count + 1); - RDI_U64 type_indices_count = 1; + RDIM_TypeChunkList list = {0}; - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; + + RDIM_Type *null_type = rdim_type_chunk_list_push(arena, &list, type_cap); + + for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) { - for(RDI_U64 i = 0; i < chunk->count; i += 1) - { - rdim_assign_type_index(&chunk->v[i], type_indices, &type_indices_count); - } + RDIM_String8 name = {0}; + name.str = rdi_string_from_type_kind(type_kind, &name.size); + + RDIM_Type *type = rdim_type_chunk_list_push(arena, &list, type_cap); + type->name = name; + type->kind = type_kind; + type->byte_size = rdi_size_from_basic_type_kind(type_kind); } - return type_indices; + RDIM_Type *void_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Void); + void_type->byte_size = rdi_addr_size_from_arch(arch); + + RDIM_Type *handle_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Handle); + handle_type->byte_size = rdi_addr_size_from_arch(arch); + + return list; } //////////////////////////////// @@ -2139,7 +2278,7 @@ rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopo //- rjf: bake name map building RDI_PROC RDIM_BakeNameMap * -rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI_U64 *type_indices, RDIM_BakeParams *params) +rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params) { RDIM_BakeNameMap *map = rdim_push_array(arena, RDIM_BakeNameMap, 1); switch(kind) @@ -2192,7 +2331,8 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI { for(RDI_U64 idx = 0; idx < n->count; idx += 1) { - RDI_U32 type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, &n->v[idx]); // TODO(rjf): @u64_to_u32 + RDI_U32 type_idx = (RDI_U32)rdim_idx_from_type(&n->v[idx]); // TODO(rjf): @u64_to_u32 + if(type_idx == 0) {continue;} rdim_bake_name_map_push(arena, map, n->v[idx].name, type_idx); } } @@ -2231,7 +2371,7 @@ rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI //- rjf: idx run map building RDI_PROC RDIM_BakeIdxRunMap * -rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDI_U64 *type_indices, RDIM_BakeParams *params) +rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params) { //- rjf: set up map RDIM_BakeIdxRunMap *idx_runs = rdim_push_array(arena, RDIM_BakeIdxRunMap, 1); @@ -2251,7 +2391,7 @@ rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) { - param_idx_run[idx] = (RDI_U32)rdim_final_idx_from_type(type_indices, type->param_types[idx]); // TODO(rjf): @u64_to_u32 + param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(type->param_types[idx]); // TODO(rjf): @u64_to_u32 } rdim_bake_idx_run_map_insert(arena, idx_runs, param_idx_run, param_idx_run_count); } @@ -3027,7 +3167,7 @@ rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src) } RDI_PROC RDIM_TypeNodeBakeResult -rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDI_U64 *type_indices, RDIM_TypeChunkList *src) +rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src) { RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, src->total_count+1); for(RDIM_TypeChunkNode *n = src->first; n != 0; n = n->next) @@ -3035,7 +3175,7 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) { RDIM_Type *src = &n->v[chunk_idx]; - U64 dst_idx = rdim_final_idx_from_type(type_indices, src); + U64 dst_idx = rdim_idx_from_type(src); RDI_TypeNode *dst = &type_nodes[dst_idx]; //- rjf: fill shared type node info @@ -3056,14 +3196,14 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId { direct_byte_size = src->direct_type->byte_size; } - dst->constructed.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); + dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); dst->constructed.count = src->byte_size / direct_byte_size; } //- rjf: fill constructed type node info else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) { - dst->constructed.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 + dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 dst->constructed.count = src->count; if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) { @@ -3071,7 +3211,7 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) { - param_idx_run[idx] = (RDI_U32)rdim_final_idx_from_type(type_indices, src->param_types[idx]); // TODO(rjf): @u64_to_u32 + param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(src->param_types[idx]); // TODO(rjf): @u64_to_u32 } dst->constructed.param_idx_run_first = rdim_bake_idx_from_idx_run(idx_runs, param_idx_run, param_idx_run_count); } @@ -3086,13 +3226,13 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId { dst->user_defined.name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->user_defined.udt_idx = (RDI_U32)rdim_idx_from_udt(src->udt); // TODO(rjf): @u64_to_u32 - dst->user_defined.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 + dst->user_defined.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 } //- rjf: fill bitfield info else if(dst->kind == RDI_TypeKind_Bitfield) { - dst->bitfield.direct_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->direct_type); // TODO(rjf): @u64_to_u32 + dst->bitfield.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 dst->bitfield.off = src->off; dst->bitfield.size = src->count; } @@ -3105,7 +3245,7 @@ rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeId } RDI_PROC RDIM_UDTBakeResult -rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_UDTChunkList *src) +rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src) { //- rjf: build tables RDI_UDT * udts = push_array(arena, RDI_UDT, src->total_count+1); @@ -3123,7 +3263,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *typ RDI_UDT *dst_udt = &udts[dst_udt_idx]; //- rjf: fill basics - dst_udt->self_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_udt->self_type); // TODO(rjf): @u64_to_u32 + dst_udt->self_type_idx = (RDI_U32)rdim_idx_from_type(src_udt->self_type); // TODO(rjf): @u64_to_u32 dst_udt->file_idx = (RDI_U32)rdim_idx_from_src_file(src_udt->src_file); // TODO(rjf): @u64_to_u32 dst_udt->line = src_udt->line; dst_udt->col = src_udt->col; @@ -3140,7 +3280,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *typ RDI_Member *dst_member = &members[dst_member_idx]; dst_member->kind = src_member->kind; dst_member->name_string_idx = rdim_bake_idx_from_string(strings, src_member->name); - dst_member->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_member->type); // TODO(rjf): @u64_to_u32 + dst_member->type_idx = (RDI_U32)rdim_idx_from_type(src_member->type); // TODO(rjf): @u64_to_u32 dst_member->off = src_member->off; } } @@ -3178,7 +3318,7 @@ rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *typ } RDI_PROC RDIM_GlobalVariableBakeResult -rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src) +rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) { RDI_GlobalVariable *global_variables = push_array(arena, RDI_GlobalVariable, src->total_count+1); RDI_U32 dst_idx = 1; @@ -3190,7 +3330,7 @@ rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_GlobalVariable *dst = &global_variables[dst_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->voff = src->offset; - dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 if(src->is_extern) { dst->link_flags |= RDI_LinkFlag_External; @@ -3291,7 +3431,7 @@ rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src) } RDI_PROC RDIM_ThreadVariableBakeResult -rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src) +rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) { RDI_ThreadVariable *thread_variables = push_array(arena, RDI_ThreadVariable, src->total_count+1); RDI_U32 dst_idx = 1; @@ -3303,7 +3443,7 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_ThreadVariable *dst = &thread_variables[dst_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->tls_off = (RDI_U32)src->offset; // TODO(rjf): @u64_to_u32 - dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); if(src->is_extern) { dst->link_flags |= RDI_LinkFlag_External; @@ -3327,7 +3467,7 @@ rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, } RDI_PROC U64 -rdim_bake_location(Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) +rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) { U64 location_data_off = location_data_blobs->total_size; @@ -3420,7 +3560,6 @@ rdim_bake_locset(RDIM_Arena *arena, RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, - RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_SymbolChunkList *src) @@ -3453,7 +3592,7 @@ rdim_bake_procedures(RDIM_Arena *arena, dst->link_flags |= RDI_LinkFlag_ProcScoped; dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 } - dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 dst->frame_base_location_first = frame_base_location_first; dst->frame_base_location_opl = frame_base_location_opl; @@ -3468,7 +3607,6 @@ rdim_bake_procedures(RDIM_Arena *arena, RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, - RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_ScopeChunkList *src) @@ -3521,7 +3659,7 @@ rdim_bake_scopes(RDIM_Arena *arena, RDI_Local *dst_local = &locals[dst_local_idx]; dst_local->kind = src_local->kind; dst_local->name_string_idx = rdim_bake_idx_from_string(strings, src_local->name); - dst_local->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src_local->type); // TODO(rjf): @u64_to_u32 + dst_local->type_idx = (RDI_U32)rdim_idx_from_type(src_local->type); // TODO(rjf): @u64_to_u32 dst_local->location_first = location_block_idx_first; dst_local->location_opl = location_block_idx_opl; } @@ -3606,7 +3744,7 @@ rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src) } RDI_PROC RDIM_InlineSiteBakeResult -rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_InlineSiteChunkList *src) +rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src) { RDIM_InlineSiteBakeResult result = {0}; { @@ -3620,8 +3758,8 @@ rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_ RDI_InlineSite *dst = &result.inline_sites[dst_idx]; RDIM_InlineSite *src = &n->v[chunk_idx]; dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->type); // TODO(rjf): @u64_to_u32 - dst->owner_type_idx = (RDI_U32)rdim_final_idx_from_type(type_indices, src->owner); // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 } } diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 647f8cc4..74024ff2 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -595,6 +595,17 @@ struct RDIM_UnitChunkList //////////////////////////////// //~ rjf: Type System Node Types +typedef RDI_U32 RDIM_DataModel; +enum RDIM_DataModelEnum +{ + RDIM_DataModel_Null, + RDIM_DataModel_ILP32, + RDIM_DataModel_LLP64, + RDIM_DataModel_LP64, + RDIM_DataModel_ILP64, + RDIM_DataModel_SILP64 +}; + typedef struct RDIM_Type RDIM_Type; struct RDIM_Type { @@ -605,6 +616,7 @@ struct RDIM_Type RDI_U32 off; RDI_U32 count; RDIM_String8 name; + RDIM_String8 link_name; RDIM_Type *direct_type; RDIM_Type **param_types; struct RDIM_UDT *udt; @@ -1348,6 +1360,19 @@ RDI_PROC RDIM_SortKey *rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys //- rjf: rng1u64 list RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r); +//////////////////////////////// +//~ Data Model + +RDI_PROC RDI_TypeKind rdim_short_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_int_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_long_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model); +RDI_PROC RDI_TypeKind rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model); + //////////////////////////////// //~ rjf: [Building] Binary Section Info Building @@ -1381,7 +1406,6 @@ RDI_PROC void rdim_unit_chunk_list_concat_in_place(RDIM_UnitChunkList *dst, RDIM RDI_PROC RDIM_Type *rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_type(RDIM_Type *type); -RDI_PROC RDI_U64 rdim_final_idx_from_type(RDI_U64 *type_indices, RDIM_Type *type); RDI_PROC void rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push); RDI_PROC RDIM_UDT *rdim_udt_chunk_list_push(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_udt(RDIM_UDT *udt); @@ -1439,12 +1463,6 @@ RDI_PROC RDI_U32 rdim_count_from_location_block_chunk_list(RDIM_String8List *lis RDI_PROC RDIM_TypeChunkList rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch); RDI_PROC RDIM_Type * rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind); -//////////////////////////////// -// Type Index - -RDI_PROC void rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx); -RDI_PROC RDI_U64 * rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types); - //////////////////////////////// //~ rjf: [Baking Helpers] Baked VMap Building @@ -1515,10 +1533,10 @@ RDI_PROC void rdim_bake_string_map_loose_push_symbols(RDIM_Arena *arena, RDIM_Ba RDI_PROC void rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_ScopeChunkList *list); //- rjf: bake name map building -RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDI_U64 *type_indices, RDIM_BakeParams *params); +RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params); //- rjf: bake idx run map building -RDI_PROC RDIM_BakeIdxRunMap *rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDI_U64 *type_indices, RDIM_BakeParams *params); +RDI_PROC RDIM_BakeIdxRunMap *rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params); //- rjf: bake path tree building RDI_PROC RDIM_BakePathTree *rdim_bake_path_tree_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); @@ -1539,15 +1557,15 @@ RDI_PROC RDIM_UnitBakeResult rdim_bake_units(RDIM_Arena *arena, RDIM_ RDI_PROC RDIM_UnitVMapBakeResult rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units); RDI_PROC RDIM_SrcFileBakeResult rdim_bake_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_SrcFileChunkList *src); RDI_PROC RDIM_LineTableBakeResult rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src); -RDI_PROC RDIM_TypeNodeBakeResult rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDI_U64 *type_indices, RDIM_TypeChunkList *src); -RDI_PROC RDIM_UDTBakeResult rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_UDTChunkList *src); -RDI_PROC RDIM_GlobalVariableBakeResult rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_TypeNodeBakeResult rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src); +RDI_PROC RDIM_UDTBakeResult rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src); +RDI_PROC RDIM_GlobalVariableBakeResult rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); RDI_PROC RDIM_GlobalVMapBakeResult rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_ScopeChunkList *src); +RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_SymbolChunkList *src); +RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_ScopeChunkList *src); RDI_PROC RDIM_ScopeVMapBakeResult rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src); -RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDI_U64 *type_indices, RDIM_InlineSiteChunkList *src); +RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src); RDI_PROC RDIM_TopLevelNameMapBakeResult rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]); RDI_PROC RDIM_FilePathBakeResult rdim_bake_file_paths(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree); RDI_PROC RDIM_StringBakeResult rdim_bake_strings(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings); diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index 91a5b73b..8d600762 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -1837,9 +1837,73 @@ d2r_convert(Arena *arena, D2R_User2Convert *in) return bake_params; } +RDI_PROC void +rdim_assign_type_index(RDIM_Type *type, U64 *type_indices, U64 *curr_type_idx) +{ + RDI_U64 type_pos = rdim_idx_from_type(type); + + if(type->kind == RDI_TypeKind_NULL) + { + type_indices[type_pos] = 0; + return; + } + + if(type_indices[type_pos] == 0) + { + if(type->param_types) + { + for(RDI_U64 param_idx = 0; param_idx < type->count; param_idx += 1) + { + rdim_assign_type_index(type->param_types[param_idx], type_indices, curr_type_idx); + } + } + + if(type->direct_type) + { + rdim_assign_type_index(type->direct_type, type_indices, curr_type_idx); + } + + type_indices[type_pos] = *curr_type_idx; + *curr_type_idx += 1; + } +} + +RDI_PROC RDI_U64 * +rdim_make_type_indices(RDIM_Arena *arena, RDIM_TypeChunkList *types) +{ + ProfBeginFunction(); + + RDI_U64 *type_indices = rdim_push_array(arena, RDI_U64, types->total_count + 1); + RDI_U64 type_indices_count = 1; + + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + rdim_assign_type_index(&chunk->v[i], type_indices, &type_indices_count); + } + } + + ProfEnd(); + return type_indices; +} + internal RDIM_BakeResults d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { + //////////////////////////////// + // resolve incomplete types + + rdim_local_resolve_incomplete_types(&in_params->types, &in_params->udts); + + //////////////////////////////// + // compute type indices + + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); + + // using type indices create a correct type array layout + NotImplemented; + return rdim_bake(state, in_params); } diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 6d06f195..50bee21b 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -3402,14 +3402,137 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 3: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, (U64)(itype_opl)); - for(CV_TypeId root_itype = 0; root_itype < itype_opl; root_itype += 1) + + ////////////////////////// + //- build basic types + // + { + RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); + + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); + RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); + RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); + RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); + RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); + RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); + RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); + RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); + RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); + + struct + { + char * name; + RDI_TypeKind kind_rdi; + CV_LeafKind kind_cv; + B32 make_pointer_near; + B32 make_pointer_32; + B32 make_pointer_64; + } + table[] = + { + { "" , RDI_TypeKind_NULL , CV_BasicType_NOTYPE , 0, 0, 0 }, + { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, + { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, + { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, + { "short" , short_type , CV_BasicType_SHORT , 1, 1, 1 }, + { "long" , long_type , CV_BasicType_LONG , 1, 1, 1 }, + { "long long" , long_long_type , CV_BasicType_QUAD , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT , 1, 1, 1 }, // Clang type + { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR , 1, 1, 1 }, + { "unsigned short" , ushort_type , CV_BasicType_USHORT , 1, 1, 1 }, + { "unsigned long" , ulong_type , CV_BasicType_ULONG , 1, 1, 1 }, + { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT , 1, 1, 1 }, // Clang type + { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 , 1, 1, 1 }, + { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 , 1, 1, 1 }, // not real C type + { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 , 1, 1, 1 }, // not real C type + { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 , 1, 1, 1 }, + { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 , 1, 1, 1 }, + { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 , 1, 1, 1 }, + { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 , 1, 1, 1 }, // Clang type + { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 , 1, 1, 1 }, // not real C type + { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP , 1, 1, 1 }, // not real C type + { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 , 0, 0, 0 }, + { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 , 0, 0, 0 }, + { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 , 0, 0, 0 }, + { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 , 0, 0, 0 }, + { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 , 1, 1, 1 }, + { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, + { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, + { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, + { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, + { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, + { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, + { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 , 1, 1, 1 }, + { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR , 1, 1, 1 }, // always ASCII + { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR , 1, 1, 1 }, // on windows always UTF-16 + { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 , 1, 1, 1 }, // always UTF-8 + { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 , 1, 1, 1 }, // always UTF-16 + { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 + { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } + }; + + for(U64 i = 0; i < ArrayCount(table); i += 1) + { + U64 builtin_size; + if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) + { + builtin_size = arch_addr_size; + } + else + { + builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); + } + + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + builtin->kind = table[i].kind_rdi; + builtin->name = str8_cstring(table[i].name); + builtin->byte_size = builtin_size; + + itype_type_ptrs[table[i].kind_cv] = builtin; + + if(table[i].make_pointer_near) + { + CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; + RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_near->kind = RDI_TypeKind_Ptr; + ptr_near->byte_size = 2; + ptr_near->direct_type = builtin; + + itype_type_ptrs[near_ptr_itype] = ptr_near; + } + if(table[i].make_pointer_32) + { + CV_TypeIndex ptr_32_itype = table[i].kind_cv | 0x400; + RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_32->kind = RDI_TypeKind_Ptr; + ptr_32->byte_size = 4; + ptr_32->direct_type = builtin; + + itype_type_ptrs[ptr_32_itype] = ptr_32; + } + if(table[i].make_pointer_64) + { + CV_TypeIndex ptr_64_itype = table[i].kind_cv | 0x600; + RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + ptr_64->kind = RDI_TypeKind_Ptr; + ptr_64->byte_size = 8; + ptr_64->direct_type = builtin; + + itype_type_ptrs[ptr_64_itype] = ptr_64; + } + } + } + + for(CV_TypeId root_itype = tpi->itype_first; root_itype < itype_opl; root_itype += 1) { for(P2R_TypeIdChain *itype_chain = itype_chains[root_itype]; itype_chain != 0; itype_chain = itype_chain->next) { CV_TypeId itype = (root_itype != itype_chain->itype && itype_chain->itype < itype_opl && itype_fwd_map[itype_chain->itype]) ? itype_fwd_map[itype_chain->itype] : itype_chain->itype; - B32 itype_is_basic = (itype < 0x1000); ////////////////////////// //- rjf: skip forward-reference itypes - all future resolutions will @@ -3429,50 +3552,9 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) continue; } - ////////////////////////// - //- rjf: build basic type - // - if(itype_is_basic) - { - RDIM_Type *dst_type = 0; - - // rjf: unpack itype - CV_BasicPointerKind cv_basic_ptr_kind = CV_BasicPointerKindFromTypeId(itype); - CV_BasicType cv_basic_type_code = CV_BasicTypeFromTypeId(itype); - - // rjf: get basic type slot, fill if unfilled - RDIM_Type *basic_type = itype_type_ptrs[cv_basic_type_code]; - if(basic_type == 0) - { - RDI_TypeKind type_kind = p2r_rdi_type_kind_from_cv_basic_type(cv_basic_type_code); - U32 byte_size = rdi_size_from_basic_type_kind(type_kind); - basic_type = dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - if(byte_size == 0xffffffff) - { - byte_size = arch_addr_size; - } - basic_type->kind = type_kind; - basic_type->name = cv_type_name_from_basic_type(cv_basic_type_code); - basic_type->byte_size = byte_size; - } - - // rjf: nonzero ptr kind -> form ptr type to basic tpye - if(cv_basic_ptr_kind != 0) - { - dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); - dst_type->kind = RDI_TypeKind_Ptr; - dst_type->byte_size = arch_addr_size; - dst_type->direct_type = basic_type; - } - - // rjf: fill this itype's slot with the finished type - itype_type_ptrs[itype] = dst_type; - } - ////////////////////////// //- rjf: build non-basic type // - if(!itype_is_basic && itype >= itype_first) { RDIM_Type *dst_type = 0; CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-itype_first]; diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index 302126fe..575a5421 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -266,7 +266,7 @@ ASYNC_WORK_DEF(rdim_build_bake_name_map_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; RDIM_BakeNameMap *name_map = 0; - ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->params); ProfEnd(); return name_map; } @@ -312,7 +312,7 @@ ASYNC_WORK_DEF(rdim_bake_udts_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); - ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->udts); ProfEnd(); return out; } @@ -323,7 +323,7 @@ ASYNC_WORK_DEF(rdim_bake_global_variables_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); - ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->global_variables); ProfEnd(); return out; } @@ -345,7 +345,7 @@ ASYNC_WORK_DEF(rdim_bake_thread_variables_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); - ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->thread_variables); ProfEnd(); return out; } @@ -356,7 +356,7 @@ ASYNC_WORK_DEF(rdim_bake_procedures_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); - ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->location_blocks, in->location_data_blobs, in->procedures); ProfEnd(); return out; } @@ -367,7 +367,7 @@ ASYNC_WORK_DEF(rdim_bake_scopes_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); - ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->location_blocks, in->location_data_blobs, in->scopes); ProfEnd(); return out; } @@ -389,7 +389,7 @@ ASYNC_WORK_DEF(rdim_bake_inline_sites_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); - ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); ProfEnd(); return out; } @@ -424,7 +424,7 @@ ASYNC_WORK_DEF(rdim_bake_type_nodes_work) Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); - ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->types); ProfEnd(); return out; } @@ -652,16 +652,6 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) RDIM_BakeResults out = {0}; rdim_local_state = state; - - //////////////////////////////// - // resolve incomplete types - - rdim_local_resolve_incomplete_types(&in_params->types, &in_params->udts); - - //////////////////////////////// - // compute type indices - - RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); ////////////////////////////// //- rjf: kick off line tables baking @@ -892,7 +882,6 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) k = (RDI_NameMapKind)(k+1)) { build_bake_name_map_in[k].k = k; - build_bake_name_map_in[k].type_indices = type_indices; build_bake_name_map_in[k].params = in_params; build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); } @@ -1000,13 +989,13 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); - RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts}; ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); - RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites}; ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); @@ -1020,20 +1009,20 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); // TODO: export location instead of VOFF - RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); // TODO: export location instead of VOFF - RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); @@ -1057,7 +1046,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) RDIM_BakeIdxRunMap *idx_runs = 0; ProfScope("build interned idx run map") { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, in_params); } ////////////////////////////// @@ -1070,7 +1059,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) ////////////////////////////// //- rjf: kick off pass 3 tasks // - RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types}; ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; { diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index 290265b8..5dc7ec6b 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -173,7 +173,6 @@ typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; struct RDIM_BuildBakeNameMapIn { RDI_NameMapKind k; - RDI_U64 *type_indices; RDIM_BakeParams *params; }; @@ -230,7 +229,6 @@ struct RDIM_BakeUDTsIn { RDIM_BakeStringMapTight *strings; RDIM_UDTChunkList *udts; - RDI_U64 *type_indices; }; typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; @@ -238,7 +236,6 @@ struct RDIM_BakeGlobalVariablesIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *global_variables; - RDI_U64 *type_indices; }; typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; @@ -252,7 +249,6 @@ struct RDIM_BakeThreadVariablesIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *thread_variables; - RDI_U64 *type_indices; }; typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; @@ -260,7 +256,6 @@ struct RDIM_BakeProceduresIn { RDIM_BakeStringMapTight *strings; RDIM_SymbolChunkList *procedures; - RDI_U64 *type_indices; RDIM_String8List *location_blocks; RDIM_String8List *location_data_blobs; }; @@ -270,7 +265,6 @@ struct RDIM_BakeScopesIn { RDIM_BakeStringMapTight *strings; RDIM_ScopeChunkList *scopes; - RDI_U64 *type_indices; RDIM_String8List *location_blocks; RDIM_String8List *location_data_blobs; }; @@ -286,7 +280,6 @@ struct RDIM_BakeInlineSitesIn { RDIM_BakeStringMapTight *strings; RDIM_InlineSiteChunkList *inline_sites; - RDI_U64 *type_indices; }; typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; @@ -308,7 +301,6 @@ struct RDIM_BakeTypeNodesIn RDIM_BakeStringMapTight *strings; RDIM_BakeIdxRunMap *idx_runs; RDIM_TypeChunkList *types; - RDI_U64 *type_indices; }; typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; From 573a6b0bb290307af3688e6ec5682ca1bea941f9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 10:45:32 -0700 Subject: [PATCH 572/755] further work on autocompletion system; more carefully preserve information about cursor / what is being replaced, do not apply autocompletion lister enabling setting to required listers (e.g. for settings/themes), and adjust navigation controls such that arrowkeys are consumed by the autocompletion lister (in principle this is 'stealing' functionality from the source ui, e.g. the watch window using up/down to go to different rows, but in practice when an autocompletion lister pops up, it feels way more natural to use arrowkeys) --- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 269 +++++++++++++++++++----------------- src/raddbg/raddbg_core.h | 7 +- src/raddbg/raddbg_views.c | 4 +- src/raddbg/raddbg_widgets.c | 133 ++++++++++-------- src/ui/ui_core.h | 16 +-- 6 files changed, 234 insertions(+), 197 deletions(-) diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 25a49063..b2b460a5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -931,7 +931,7 @@ RD_CmdTable: // | | | | {Paste 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Clipboard "paste" "Paste" "Pastes the current contents of the clipboard." "" "" } {InsertText 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "insert_text" "Insert Text" "Inserts the text that was used to cause this command." "" "" } - //- rjf: secondary navigation + //- rjf: directionless navigation {MoveNext 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_next" "Move Next" "Moves the cursor or selection to the next element." "" "" } {MovePrev 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "move_prev" "Move Previous" "Moves the cursor or selection to the previous element." "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c9e58895..28d47877 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3585,12 +3585,14 @@ rd_view_ui(Rng2F32 rect) if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) { take_autocomplete = 1; - RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, string, edit_state->cursor.column-1); - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info.replaced_range.min+1, autocomp_cursor_info.replaced_range.max+1), autocomplete_hint_string); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_hint_string); new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info.replaced_range.min+autocomplete_hint_string.size); + edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size); string = str8(edit_state->input_buffer, edit_state->input_size); op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); } @@ -4964,15 +4966,7 @@ rd_view_ui(Rng2F32 rect) txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - String8 list_expr = rd_autocomp_primary_list_expr_from_dst_eval(scratch.arena, cell->eval); - RD_AutocompCursorInfo cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, input, cell_edit_state->cursor.column-1); - if(cursor_info.list_expr.size != 0) - { - list_expr = cursor_info.list_expr; - } - rd_set_autocomp_regs(.ui_key = line_edit_key, - .string = cursor_info.filter, - .expr = list_expr); + rd_set_autocomp_regs(cell->eval, .ui_key = line_edit_key, .string = input); } } } @@ -6668,7 +6662,7 @@ rd_window_frame(void) RD_Font(RD_FontSlot_Code) { //- rjf: add autocompletion view task - if(rd_setting_b32_from_name(str8_lit("autocompletion_lister")) && ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index) + if(ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index) { // rjf: build view RD_Cfg *root = rd_immediate_cfg_from_keyf("autocomp_view_%I64x", window->id); @@ -6678,7 +6672,7 @@ rd_window_frame(void) RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); rd_cfg_new_replace(input, ws->autocomp_regs->string); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); - rd_cfg_new_replace(expr, ws->autocomp_regs->expr); + rd_cfg_new_replace(expr, ws->autocomp_cursor_info.list_expr); // rjf: determine container size EV_BlockTree predicted_block_tree = {0}; @@ -9621,123 +9615,142 @@ rd_set_hover_eval(Vec2F32 pos, String8 string) //////////////////////////////// //~ rjf: Autocompletion Lister -internal String8 -rd_autocomp_primary_list_expr_from_dst_eval(Arena *arena, E_Eval dst_eval) -{ - String8 result = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); - { - E_TypeKey maybe_enum_type = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); - if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) - { - result = str8_lit("query:themes"); - } -#if 0 - else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) - { - result = e_type_string_from_key(arena, maybe_enum_type); - } -#endif - } - return result; -} - -internal RD_AutocompCursorInfo -rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off) -{ - RD_AutocompCursorInfo result = {0}; - { - result.filter = input; - result.replaced_range = r1u64(0, input.size); - } - Temp scratch = scratch_begin(&arena, 1); - E_Parse parse = e_parse_from_string(input); - - //- rjf: cursor offset -> cursor containing node - E_Expr *cursor_expr = &e_expr_nil; - E_Expr *cursor_expr_parent = &e_expr_nil; - { - typedef struct ExprWalkTask ExprWalkTask; - struct ExprWalkTask - { - ExprWalkTask *next; - E_Expr *parent; - E_Expr *expr; - }; - ExprWalkTask start_task = {0, &e_expr_nil, parse.expr}; - ExprWalkTask *first_task = &start_task; - ExprWalkTask *last_task = first_task; - for(E_Expr *chain = parse.expr->next; chain != &e_expr_nil; chain = chain->next) - { - ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = &e_expr_nil; - task->expr = chain; - } - for(ExprWalkTask *t = first_task; t != 0; t = t->next) - { - E_Expr *e = t->expr; - if(contains_1u64(e->range, cursor_off) || cursor_off == e->range.max) - { - cursor_expr_parent = t->parent; - cursor_expr = e; - break; - } - for(E_Expr *child = e->first; child != &e_expr_nil; child = child->next) - { - ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); - SLLQueuePush(first_task, last_task, task); - task->parent = e; - task->expr = child; - } - } - } - - //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side - B32 did_special_cursor_case = 0; - if(!did_special_cursor_case) - { - E_Expr *dot_expr = &e_expr_nil; - if(cursor_expr->kind == E_ExprKind_MemberAccess && cursor_off == cursor_expr->range.max) - { - dot_expr = cursor_expr; - } - else if(cursor_expr_parent->kind == E_ExprKind_MemberAccess && cursor_expr == cursor_expr_parent->first->next) - { - dot_expr = cursor_expr_parent; - } - if(dot_expr != &e_expr_nil) - { - did_special_cursor_case = 1; - E_Eval lhs_eval = e_eval_from_expr(dot_expr->first); - E_Eval type_of_lhs_eval = e_eval_wrapf(lhs_eval, "typeof($)"); - result.list_expr = e_full_expr_string_from_key(arena, type_of_lhs_eval.key); - result.filter = cursor_expr->string; - result.replaced_range = union_1u64(dot_expr->range, cursor_expr->range); - } - } - - //- rjf: cursor is on a leaf-identifier? -> replace just that identifier, keep the original list expression - if(!did_special_cursor_case && cursor_expr->kind == E_ExprKind_LeafIdentifier) - { - did_special_cursor_case = 1; - result.filter = str8_prefix(cursor_expr->string, cursor_off - cursor_expr->range.min); - result.replaced_range = cursor_expr->range; - } - - scratch_end(scratch); - return result; -} - internal void -rd_set_autocomp_regs_(RD_Regs *regs) +rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) { RD_Cfg *window_cfg = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); if(ws->autocomp_last_frame_index < rd_state->frame_index) { - ws->autocomp_last_frame_index = rd_state->frame_index; - arena_clear(ws->autocomp_arena); - ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); + //- rjf: calculate information about the cursor: + // * what list should we generate? + // * what string in the input should we replace? + // etc. + B32 is_allowed = 0; + RD_AutocompCursorInfo cursor_info = {0}; + { + Temp scratch = scratch_begin(0, 0); + + // rjf: calculate most general list expression, given the dst_eval space + B32 force_allow = 0; + B32 expr_based_replace = 1; + String8 list_expr = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); + { + E_TypeKey maybe_enum_type = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); + if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) + { + list_expr = str8_lit("query:themes"); + expr_based_replace = 0; + force_allow = 1; + } +#if 0 + else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) + { + list_expr = e_type_string_from_key(arena, maybe_enum_type); + } +#endif + } + + // rjf: determine if autocompletion lister is allowed + is_allowed = (force_allow || rd_setting_b32_from_name(str8_lit("autocompletion_lister"))); + + // rjf: tighten list_expr, and filter / replaced-range, if needed + String8 filter = regs->string; + Rng1U64 replaced_range = r1u64(0, filter.size); + if(expr_based_replace) + { + U64 cursor_off = (U64)(regs->cursor.column-1); + E_Parse parse = e_parse_from_string(regs->string); + + //- rjf: cursor offset -> cursor containing node + E_Expr *cursor_expr = &e_expr_nil; + E_Expr *cursor_expr_parent = &e_expr_nil; + { + typedef struct ExprWalkTask ExprWalkTask; + struct ExprWalkTask + { + ExprWalkTask *next; + E_Expr *parent; + E_Expr *expr; + }; + ExprWalkTask start_task = {0, &e_expr_nil, parse.expr}; + ExprWalkTask *first_task = &start_task; + ExprWalkTask *last_task = first_task; + for(E_Expr *chain = parse.expr->next; chain != &e_expr_nil; chain = chain->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = &e_expr_nil; + task->expr = chain; + } + for(ExprWalkTask *t = first_task; t != 0; t = t->next) + { + E_Expr *e = t->expr; + if(contains_1u64(e->range, cursor_off) || cursor_off == e->range.max) + { + cursor_expr_parent = t->parent; + cursor_expr = e; + break; + } + for(E_Expr *child = e->first; child != &e_expr_nil; child = child->next) + { + ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); + SLLQueuePush(first_task, last_task, task); + task->parent = e; + task->expr = child; + } + } + } + + //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side + B32 did_special_cursor_case = 0; + if(!did_special_cursor_case) + { + E_Expr *dot_expr = &e_expr_nil; + if(cursor_expr->kind == E_ExprKind_MemberAccess && cursor_off == cursor_expr->range.max) + { + dot_expr = cursor_expr; + } + else if(cursor_expr_parent->kind == E_ExprKind_MemberAccess && cursor_expr == cursor_expr_parent->first->next) + { + dot_expr = cursor_expr_parent; + } + if(dot_expr != &e_expr_nil) + { + did_special_cursor_case = 1; + E_Eval lhs_eval = e_eval_from_expr(dot_expr->first); + E_Eval type_of_lhs_eval = e_eval_wrapf(lhs_eval, "typeof($)"); + list_expr = e_full_expr_string_from_key(scratch.arena, type_of_lhs_eval.key); + filter = cursor_expr->string; + replaced_range = union_1u64(dot_expr->range, cursor_expr->range); + } + } + + //- rjf: cursor is on a leaf-identifier? -> replace just that identifier, keep the original list expression + if(!did_special_cursor_case && cursor_expr->kind == E_ExprKind_LeafIdentifier) + { + did_special_cursor_case = 1; + filter = str8_prefix(cursor_expr->string, cursor_off - cursor_expr->range.min); + replaced_range = cursor_expr->range; + } + } + + // rjf: fill bundle + cursor_info.list_expr = push_str8_copy(ws->autocomp_arena, list_expr); + cursor_info.filter = push_str8_copy(ws->autocomp_arena, filter); + cursor_info.replaced_range = replaced_range; + + scratch_end(scratch); + } + + //- rjf: commit autocompletion info + if(is_allowed) + { + ws->autocomp_last_frame_index = rd_state->frame_index; + arena_clear(ws->autocomp_arena); + ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); + ws->autocomp_cursor_info = cursor_info; + } } } @@ -15181,7 +15194,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, -1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15192,7 +15205,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15574,7 +15587,7 @@ rd_frame(void) ui_event_list_push(scratch.arena, &ws->ui_events, &evt); }break; - //- rjf: secondary navigation + //- rjf: directionless navigation case RD_CmdKind_MoveNext: { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 5699383d..df7f202a 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -483,6 +483,7 @@ struct RD_WindowState U64 autocomp_last_frame_index; Arena *autocomp_arena; RD_Regs *autocomp_regs; + RD_AutocompCursorInfo autocomp_cursor_info; // rjf: error state U8 error_buffer[512]; @@ -959,10 +960,8 @@ internal void rd_set_hover_eval(Vec2F32 pos, String8 string); //////////////////////////////// //~ rjf: Autocompletion Lister -internal String8 rd_autocomp_primary_list_expr_from_dst_eval(Arena *arena, E_Eval dst_eval); -internal RD_AutocompCursorInfo rd_autocomp_cursor_info_from_input_string_off(Arena *arena, String8 input, U64 cursor_off); -internal void rd_set_autocomp_regs_(RD_Regs *regs); -#define rd_set_autocomp_regs(...) rd_set_autocomp_regs_(&(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) +internal void rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs); +#define rd_set_autocomp_regs(dst_eval, ...) rd_set_autocomp_regs_((dst_eval), &(RD_Regs){rd_regs_lit_init_top __VA_ARGS__}) //////////////////////////////// //~ rjf: Colors, Fonts, Config diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 90856539..09a47389 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1244,7 +1244,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "enabled"), .flags = RD_WatchCellFlag_Background, - .px = floor_f32(ui_top_font_size()*5.f)); + .px = floor_f32(ui_top_font_size()*5.5f)); } else if(cmd_kind != RD_CmdKind_Null) { @@ -1272,7 +1272,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Thread) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "active"), - .px = floor_f32(ui_top_font_size()*5.f)); + .px = floor_f32(ui_top_font_size()*5.5f)); } if(entity->kind == CTRL_EntityKind_Thread) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index ca5d8721..fca267bd 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3399,7 +3399,10 @@ rd_cell(RD_CellParams *params, String8 string) params->line_edit_key_out[0] = edit_box->key; } } - ui_spacer(ui_em(1.f, 1.f)); + if(ui_top_text_alignment() == UI_TextAlign_Left) + { + ui_spacer(ui_em(1.f, 1.f)); + } } else { @@ -3474,42 +3477,55 @@ rd_cell(RD_CellParams *params, String8 string) UI_HeightFill UI_Column UI_Padding(ui_px(padding_px, 1.f)) UI_Row - UI_PrefWidth(ui_em(3.5f, 1.f)) - UI_PrefHeight(ui_px(height_px, 1.f)) - UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) - UI_TagF(is_toggled ? "good_pop" : "") { - UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); - UI_Parent(switch_box) + if(ui_top_text_alignment() == UI_TextAlign_Center) { - RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_pct(toggle_t, 0)) UI_Transparency(1.f - toggle_t) - { - ui_build_box_from_stringf(UI_BoxFlag_DisableTextTrunc | (toggle_t > 0.001f ? UI_BoxFlag_DrawText : 0), - "%S", rd_icon_kind_text_table[RD_IconKind_Check]); - } - UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) - UI_PrefWidth(ui_px(height_px, 1.f)) - { - F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); - F32 toggler_size_px = ceil_f32(height_px - extratoggler_padding_px*2.f) - 1.f; - UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) - UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) - UI_PrefWidth(ui_px(toggler_size_px, 1.f)) - UI_PrefHeight(ui_px(toggler_size_px, 1.f)) - UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) - { - UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); - } - } - ui_spacer(ui_pct(1.f-toggle_t, 0)); + ui_spacer(ui_em(1.f, 0.f)); } - UI_Signal switch_sig = ui_signal_from_box(switch_box); - if(ui_pressed(switch_sig)) + UI_PrefWidth(ui_em(3.5f, 1.f)) + UI_PrefHeight(ui_px(height_px, 1.f)) + UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) + UI_TagF(is_toggled ? "good_pop" : "") { - params->toggled_out[0] ^= 1; + UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); + UI_Parent(switch_box) + { + RD_Font(RD_FontSlot_Icons) UI_PrefWidth(ui_pct(toggle_t, 0)) UI_Transparency(1.f - toggle_t) + { + ui_build_box_from_stringf(UI_BoxFlag_DisableTextTrunc | (toggle_t > 0.001f ? UI_BoxFlag_DrawText : 0), + "%S", rd_icon_kind_text_table[RD_IconKind_Check]); + } + UI_BackgroundColor(ui_color_from_name(str8_lit("text"))) + UI_PrefWidth(ui_px(height_px, 1.f)) + { + F32 extratoggler_padding_px = floor_f32(ui_top_font_size()*0.35f); + F32 toggler_size_px = ceil_f32(height_px - extratoggler_padding_px*2.f) - 1.f; + UI_Column UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_Row UI_Padding(ui_px(extratoggler_padding_px, 1.f)) + UI_PrefWidth(ui_px(toggler_size_px, 1.f)) + UI_PrefHeight(ui_px(toggler_size_px, 1.f)) + UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) + { + UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + } + } + ui_spacer(ui_pct(1.f-toggle_t, 0)); + } + UI_Signal switch_sig = ui_signal_from_box(switch_box); + if(ui_pressed(switch_sig)) + { + params->toggled_out[0] ^= 1; + } + } + if(ui_top_text_alignment() == UI_TextAlign_Center) + { + ui_spacer(ui_em(1.f, 0.f)); } } - ui_spacer(ui_em(1.f, 1.f)); + if(ui_top_text_alignment() == UI_TextAlign_Left) + { + ui_spacer(ui_em(1.f, 1.f)); + } } ////////////////////////////// @@ -3684,12 +3700,14 @@ rd_cell(RD_CellParams *params, String8 string) // rjf: any valid *additive* op & autocomplete hint? -> perform autocomplete first, then re-compute op if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) { - RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, edit_string, params->cursor->column-1); - String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(autocomp_cursor_info.replaced_range.min+1, autocomp_cursor_info.replaced_range.max+1), autocomplete_hint_string); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; + String8 new_string = ui_push_string_replace_range(scratch.arena, edit_string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_hint_string); new_string.size = Min(params->edit_buffer_size, new_string.size); MemoryCopy(params->edit_buffer, new_string.str, new_string.size); params->edit_string_size_out[0] = new_string.size; - params->cursor[0] = params->mark[0] = txt_pt(1, 1+autocomp_cursor_info.replaced_range.min+autocomplete_hint_string.size); + params->cursor[0] = params->mark[0] = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size); edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); op = ui_single_line_txt_op_from_event(scratch.arena, evt, edit_string, params->cursor[0], params->mark[0]); MemoryZeroStruct(&autocomplete_hint_string); @@ -3761,18 +3779,30 @@ rd_cell(RD_CellParams *params, String8 string) } //- rjf: (editing) - else if((is_focus_active || is_focus_active_disabled) && params->flags & RD_CellFlag_CodeContents) + else if(is_focus_active || is_focus_active_disabled) { String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrList code_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); + DR_FStrList edit_string_fstrs = {0}; + if(params->flags & RD_CellFlag_CodeContents) + { + edit_string_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, ui_color_from_name(str8_lit("text")), edit_string); + } + else + { + String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &edit_string_fstrs, ¶ms, edit_string); + } if(autocomplete_hint_string.size != 0) { - RD_AutocompCursorInfo autocomp_cursor_info = rd_autocomp_cursor_info_from_input_string_off(scratch.arena, edit_string, params->cursor->column-1); - String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, params->cursor->column-1 - autocomp_cursor_info.replaced_range.min); + RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); + RD_WindowState *ws = rd_window_state_from_cfg(window); + RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; + String8 autocomplete_append_string = str8_skip(autocomplete_hint_string, params->cursor->column-1 - autocomp_cursor_info->replaced_range.min); U64 off = 0; U64 cursor_off = params->cursor->column-1; DR_FStrNode *prev_n = 0; - for(DR_FStrNode *n = code_fstrs.first; n != 0; n = n->next) + for(DR_FStrNode *n = edit_string_fstrs.first; n != 0; n = n->next) { if(off <= cursor_off && cursor_off <= off+n->v.string.size) { @@ -3786,6 +3816,7 @@ rd_cell(RD_CellParams *params, String8 string) DR_FStr *fstr = &autocomp_fstr_n->v; fstr->string = autocomplete_append_string; fstr->params.font = ui_top_font(); + fstr->params.raster_flags = ui_top_text_raster_flags(); fstr->params.color = ui_color_from_name(str8_lit("text")); fstr->params.color.w *= 0.5f; fstr->params.size = ui_top_font_size(); @@ -3796,20 +3827,20 @@ rd_cell(RD_CellParams *params, String8 string) } if(prev_n == 0) { - code_fstrs.first = code_fstrs.last = autocomp_fstr_n; + edit_string_fstrs.first = edit_string_fstrs.last = autocomp_fstr_n; } if(prev_n != 0 && prev_n->next == 0) { - code_fstrs.last = autocomp_fstr_n; + edit_string_fstrs.last = autocomp_fstr_n; } - code_fstrs.node_count += 1; - code_fstrs.total_size += autocomplete_hint_string.size; + edit_string_fstrs.node_count += 1; + edit_string_fstrs.total_size += autocomplete_hint_string.size; if(prev_n != 0 && cursor_off - off < prev_n->v.string.size) { String8 full_string = prev_n->v.string; U64 chop_amt = full_string.size - (cursor_off - off); prev_n->v.string = str8_chop(full_string, chop_amt); - code_fstrs.total_size -= chop_amt; + edit_string_fstrs.total_size -= chop_amt; if(chop_amt != 0) { String8 post_cursor = str8_skip(full_string, cursor_off - off); @@ -3819,23 +3850,17 @@ rd_cell(RD_CellParams *params, String8 string) post_fstr->string = post_cursor; if(autocomp_fstr_n->next == 0) { - code_fstrs.last = post_fstr_n; + edit_string_fstrs.last = post_fstr_n; } post_fstr_n->next = autocomp_fstr_n->next; autocomp_fstr_n->next = post_fstr_n; - code_fstrs.node_count += 1; - code_fstrs.total_size += post_cursor.size; + edit_string_fstrs.node_count += 1; + edit_string_fstrs.total_size += post_cursor.size; } } } } - fstrs = code_fstrs; - } - else if((is_focus_active || is_focus_active_disabled) && !(params->flags & RD_CellFlag_CodeContents)) - { - String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); - DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, edit_string); + fstrs = edit_string_fstrs; } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 7c9a8a94..cfc7c328 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -49,14 +49,14 @@ UI_MouseButtonKind; typedef U32 UI_PermissionFlags; enum { - UI_PermissionFlag_ClicksLeft = (1<<0), - UI_PermissionFlag_ClicksMiddle = (1<<1), - UI_PermissionFlag_ClicksRight = (1<<2), - UI_PermissionFlag_ScrollX = (1<<3), - UI_PermissionFlag_ScrollY = (1<<4), - UI_PermissionFlag_KeyboardPrimary = (1<<5), - UI_PermissionFlag_KeyboardSecondary= (1<<6), - UI_PermissionFlag_Text = (1<<7), + UI_PermissionFlag_ClicksLeft = (1<<0), + UI_PermissionFlag_ClicksMiddle = (1<<1), + UI_PermissionFlag_ClicksRight = (1<<2), + UI_PermissionFlag_ScrollX = (1<<3), + UI_PermissionFlag_ScrollY = (1<<4), + UI_PermissionFlag_KeyboardPrimary = (1<<5), + UI_PermissionFlag_KeyboardSecondary = (1<<6), + UI_PermissionFlag_Text = (1<<7), //- rjf bundles UI_PermissionFlag_Keyboard = (UI_PermissionFlag_KeyboardPrimary|UI_PermissionFlag_KeyboardSecondary), From cf33470cb1288a590f7d739179b99e35255aa185 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 10:49:52 -0700 Subject: [PATCH 573/755] fix incorrect usage of type byte size for eval memory range sizes --- src/eval/eval_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index de8979e7..394d67bf 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1225,14 +1225,16 @@ e_range_size_from_eval(E_Eval eval) U64 result = 256; E_TypeKey type_unwrapped = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind type_unwrapped_kind = e_type_kind_from_key(type_unwrapped); - if(e_type_kind_is_pointer_or_ref(type_unwrapped_kind) || - type_unwrapped_kind == E_TypeKind_Function) + if(type_unwrapped_kind == E_TypeKind_Array || + type_unwrapped_kind == E_TypeKind_Struct || + type_unwrapped_kind == E_TypeKind_Union || + type_unwrapped_kind == E_TypeKind_Class) { - result = KB(16); + result = e_type_byte_size_from_key(type_unwrapped); } else { - result = e_type_byte_size_from_key(type_unwrapped); + result = KB(16); } return result; } From 4ad3748d1e6b7ed6ab8f7797c2360a9fa7f7ce1c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 10:53:25 -0700 Subject: [PATCH 574/755] commit panel/tab/view to rd_regs earlier in window_frame, this allows correct calculation of per-window settings in theme calc etc. --- src/raddbg/raddbg_core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 28d47877..90db8c77 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5759,6 +5759,13 @@ rd_window_frame(void) ws->window_temporarily_focused_ipc = 0; ui_select_state(ws->ui); + ////////////////////////////// + //- rjf: @window_frame_part fill panel/view interaction registers + // + rd_regs()->panel = panel_tree.focused->cfg->id; + rd_regs()->tab = panel_tree.focused->selected_tab->id; + rd_regs()->view = panel_tree.focused->selected_tab->id; + ////////////////////////////// //- rjf: @window_frame_part compute window's theme // @@ -6024,13 +6031,6 @@ rd_window_frame(void) scratch_end(scratch); } - ////////////////////////////// - //- rjf: @window_frame_part fill panel/view interaction registers - // - rd_regs()->panel = panel_tree.focused->cfg->id; - rd_regs()->tab = panel_tree.focused->selected_tab->id; - rd_regs()->view = panel_tree.focused->selected_tab->id; - ////////////////////////////// //- rjf: @window_frame_part build UI // From ced9c7a3f5388050a555000447d4fe612576bcdc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 11:26:14 -0700 Subject: [PATCH 575/755] fix more secondary-flag coverage, fix error rows being generated as type rows, fix improper piping of autocompletion cursor info into autocompletion lister build --- src/raddbg/raddbg_core.c | 18 +++++++++++------- src/raddbg/raddbg_main.c | 1 + src/raddbg/raddbg_views.c | 21 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 90db8c77..106e3ddc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4966,7 +4966,7 @@ rd_view_ui(Rng2F32 rect) txt_pt_match(cell_edit_state->cursor, cell_edit_state->mark)) { String8 input = str8(cell_edit_state->input_buffer, cell_edit_state->input_size); - rd_set_autocomp_regs(cell->eval, .ui_key = line_edit_key, .string = input); + rd_set_autocomp_regs(cell->eval, .ui_key = line_edit_key, .string = input, .cursor = cell_edit_state->cursor); } } } @@ -6670,7 +6670,7 @@ rd_window_frame(void) rd_cfg_child_from_string_or_alloc(view, str8_lit("autocomplete")); RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); - rd_cfg_new_replace(input, ws->autocomp_regs->string); + rd_cfg_new_replace(input, ws->autocomp_cursor_info.filter); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); rd_cfg_new_replace(expr, ws->autocomp_cursor_info.list_expr); @@ -7136,7 +7136,7 @@ rd_window_frame(void) } if(has_autocomplete_hint && has_accept_operation) { - autocomp_floating_view_task->signal.box->transparency = 1; + autocomp_floating_view_task->signal.box->fixed_position = v2f32(10000, 10000); } } @@ -15238,7 +15238,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, -1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15249,7 +15249,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_KeepMark|UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15282,7 +15282,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, -1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15293,7 +15293,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; - evt.flags = UI_EventFlag_ExplicitDirectional; + evt.flags = UI_EventFlag_ExplicitDirectional|UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15304,6 +15304,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, -1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15314,6 +15315,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Page; evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15324,6 +15326,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, -1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15334,6 +15337,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Navigate; + evt.flags = UI_EventFlag_Secondary; evt.delta_unit = UI_EventDeltaUnit_Whole; evt.delta_2s32 = v2s32(+0, +1); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 2a289b3b..0dba338e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -196,6 +196,7 @@ // [ ] "pop out" (hitting enter on visualizers should open them as tabs) // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // [ ] finish theme editing, build themes - replace code colors map with new theme stuff +// // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... // [ ] odin's demo is busted - need to revert PDB conversion type index changes. diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 09a47389..86b989ba 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1415,10 +1415,29 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } + //////////////////////////// + //- rjf: @watch_row_build_cells error rows + // + else if(row->eval.irtree.mode == E_Mode_Null && row->eval.msgs.max_kind > E_MsgKind_Null) + { + info.cell_style_key = str8_lit("expr_and_error"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, + .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, + .default_pct = 0.60f, + .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); +#undef take_pct + } + //////////////////////////// //- rjf: @watch_row_build_cells root-level type rows // - else if(row->eval.irtree.mode == E_Mode_Null && (e_type_key_match(row->block->eval.irtree.type_key, e_type_key_zero()) || row->block->eval.irtree.mode != E_Mode_Null)) + else if(row->eval.irtree.mode == E_Mode_Null && (row->block->eval.irtree.mode != E_Mode_Null || row->block->parent == &ev_nil_block)) { info.cell_style_key = str8_lit("root_type"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); From cbe2783e0d6a72f14cc6452538724fd3de0c4635 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 11:09:25 -0700 Subject: [PATCH 576/755] always create RDI builtins --- src/lib_rdi_make/rdi_make.c | 11 +++-------- src/rdi_from_pdb/rdi_from_pdb.c | 33 ++++++++++++--------------------- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 278dedc1..7398deae 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -1305,7 +1305,7 @@ rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind) RDI_U64 type_idx = 0; if (type_kind != RDI_TypeKind_NULL) { type_idx = (type_kind - RDI_TypeKind_FirstBuiltIn) + 1; - } + } RDIM_Type *builtin = &list.first->v[type_idx]; return builtin; } @@ -1315,17 +1315,12 @@ rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) { RDIM_TypeChunkList list = {0}; - RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; - - RDIM_Type *null_type = rdim_type_chunk_list_push(arena, &list, type_cap); + RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 1; for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) { - RDIM_String8 name = {0}; - name.str = rdi_string_from_type_kind(type_kind, &name.size); - RDIM_Type *type = rdim_type_chunk_list_push(arena, &list, type_cap); - type->name = name; + type->name.str = rdi_string_from_type_kind(type_kind, &type->name.size); type->kind = type_kind; type->byte_size = rdi_size_from_basic_type_kind(type_kind); } diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 50bee21b..3494c0f1 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -3397,7 +3397,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) // from regular type info. // RDIM_Type **itype_type_ptrs = 0; - RDIM_TypeChunkList all_types = {0}; + RDIM_TypeChunkList all_types = rdim_init_type_chunk_list(arena, top_level_info.arch); #define p2r_type_ptr_from_itype(itype) ((itype_type_ptrs && (itype) < itype_opl) ? (itype_type_ptrs[(itype_fwd_map[(itype)] ? itype_fwd_map[(itype)] : (itype))]) : 0) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 3: construct all root/stub types from TPI") { @@ -3408,7 +3408,6 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) // { RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); @@ -3430,7 +3429,6 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) } table[] = { - { "" , RDI_TypeKind_NULL , CV_BasicType_NOTYPE , 0, 0, 0 }, { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, @@ -3474,24 +3472,17 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } }; + // special case for null type + itype_type_ptrs[CV_BasicType_NOTYPE] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_NULL); + for(U64 i = 0; i < ArrayCount(table); i += 1) { - U64 builtin_size; - if(table[i].kind_rdi == RDI_TypeKind_Void || table[i].kind_rdi == RDI_TypeKind_Handle) - { - builtin_size = arch_addr_size; - } - else - { - builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); - } + RDIM_Type *builtin_alias = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); + builtin_alias->kind = RDI_TypeKind_Alias; + builtin_alias->name = str8_cstring(table[i].name); + builtin_alias->direct_type = rdim_builtin_type_from_kind(all_types, table[i].kind_rdi); - RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - builtin->kind = table[i].kind_rdi; - builtin->name = str8_cstring(table[i].name); - builtin->byte_size = builtin_size; - - itype_type_ptrs[table[i].kind_cv] = builtin; + itype_type_ptrs[table[i].kind_cv] = builtin_alias; if(table[i].make_pointer_near) { @@ -3499,7 +3490,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_near->kind = RDI_TypeKind_Ptr; ptr_near->byte_size = 2; - ptr_near->direct_type = builtin; + ptr_near->direct_type = builtin_alias; itype_type_ptrs[near_ptr_itype] = ptr_near; } @@ -3509,7 +3500,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_32->kind = RDI_TypeKind_Ptr; ptr_32->byte_size = 4; - ptr_32->direct_type = builtin; + ptr_32->direct_type = builtin_alias; itype_type_ptrs[ptr_32_itype] = ptr_32; } @@ -3519,7 +3510,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); ptr_64->kind = RDI_TypeKind_Ptr; ptr_64->byte_size = 8; - ptr_64->direct_type = builtin; + ptr_64->direct_type = builtin_alias; itype_type_ptrs[ptr_64_itype] = ptr_64; } From d3f8c1864de52331432aae830eca84f3d4278ddb Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 15:03:25 -0700 Subject: [PATCH 577/755] simplify aliases table and build basic types for unknown records --- src/lib_rdi_make/rdi_make.c | 12 +-- src/rdi_from_pdb/rdi_from_pdb.c | 169 ++++++++++++++++---------------- 2 files changed, 92 insertions(+), 89 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 7398deae..a487fbf3 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -1302,12 +1302,7 @@ rdim_count_from_location_block_chunk_list(RDIM_String8List *list) RDI_PROC RDIM_Type * rdim_builtin_type_from_kind(RDIM_TypeChunkList list, RDI_TypeKind type_kind) { - RDI_U64 type_idx = 0; - if (type_kind != RDI_TypeKind_NULL) { - type_idx = (type_kind - RDI_TypeKind_FirstBuiltIn) + 1; - } - RDIM_Type *builtin = &list.first->v[type_idx]; - return builtin; + return &list.first->v[type_kind]; } RDI_PROC RDIM_TypeChunkList @@ -1315,7 +1310,10 @@ rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) { RDIM_TypeChunkList list = {0}; - RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 1; + RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; + + // RDI_TypeKind_NULL + rdim_type_chunk_list_push(arena, &list, type_cap); for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) { diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 3494c0f1..d6abec95 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -3404,14 +3404,12 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) itype_type_ptrs = push_array(arena, RDIM_Type *, (U64)(itype_opl)); ////////////////////////// - //- build basic types + //- basic type aliases // { RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); - RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); - RDI_TypeKind uint_type = rdim_unsigned_int_type_from_data_model(data_model); RDI_TypeKind long_type = rdim_long_type_from_data_model(data_model); RDI_TypeKind ulong_type = rdim_unsigned_long_type_from_data_model(data_model); RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); @@ -3423,57 +3421,54 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) char * name; RDI_TypeKind kind_rdi; CV_LeafKind kind_cv; - B32 make_pointer_near; - B32 make_pointer_32; - B32 make_pointer_64; } table[] = { - { "void" , RDI_TypeKind_Void , CV_BasicType_VOID , 1, 1, 1 }, - { "HRESULT" , RDI_TypeKind_Handle , CV_BasicType_HRESULT , 0, 1, 1 }, - { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR , 1, 1, 1 }, - { "short" , short_type , CV_BasicType_SHORT , 1, 1, 1 }, - { "long" , long_type , CV_BasicType_LONG , 1, 1, 1 }, - { "long long" , long_long_type , CV_BasicType_QUAD , 1, 1, 1 }, - { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT , 1, 1, 1 }, // Clang type - { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR , 1, 1, 1 }, - { "unsigned short" , ushort_type , CV_BasicType_USHORT , 1, 1, 1 }, - { "unsigned long" , ulong_type , CV_BasicType_ULONG , 1, 1, 1 }, - { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD , 1, 1, 1 }, - { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT , 1, 1, 1 }, // Clang type - { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 , 1, 1, 1 }, - { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 , 1, 1, 1 }, // not real C type - { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 , 1, 1, 1 }, // not real C type - { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 , 1, 1, 1 }, - { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 , 1, 1, 1 }, - { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 , 1, 1, 1 }, - { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 , 1, 1, 1 }, // Clang type - { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 , 1, 1, 1 }, // not real C type - { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP , 1, 1, 1 }, // not real C type - { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 , 0, 0, 0 }, - { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 , 0, 0, 0 }, - { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 , 0, 0, 0 }, - { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 , 0, 0, 0 }, - { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 , 1, 1, 1 }, - { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 , 1, 1, 1 }, - { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 , 1, 1, 1 }, - { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 , 1, 1, 1 }, - { "int" , int_type , CV_BasicType_INT32 , 1, 1, 1 }, - { "unsigned int" , uint_type , CV_BasicType_UINT32 , 1, 1, 1 }, - { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 , 1, 1, 1 }, - { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 , 1, 1, 1 }, - { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 , 1, 1, 1 }, - { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 , 1, 1, 1 }, - { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR , 1, 1, 1 }, // always ASCII - { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR , 1, 1, 1 }, // on windows always UTF-16 - { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 , 1, 1, 1 }, // always UTF-8 - { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 , 1, 1, 1 }, // always UTF-16 - { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 - { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } + { "signed char" , RDI_TypeKind_Char8 , CV_BasicType_CHAR }, + { "short" , short_type , CV_BasicType_SHORT }, + { "long" , long_type , CV_BasicType_LONG }, + { "long long" , long_long_type , CV_BasicType_QUAD }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_OCT }, // Clang type + { "unsigned char" , RDI_TypeKind_UChar8 , CV_BasicType_UCHAR }, + { "unsigned short" , ushort_type , CV_BasicType_USHORT }, + { "unsigned long" , ulong_type , CV_BasicType_ULONG }, + { "unsigned long long" , ulong_long_type , CV_BasicType_UQUAD }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UOCT }, // Clang type + { "bool" , RDI_TypeKind_S8 , CV_BasicType_BOOL8 }, + { "__bool16" , RDI_TypeKind_S16 , CV_BasicType_BOOL16 }, // not real C type + { "__bool32" , RDI_TypeKind_S32 , CV_BasicType_BOOL32 }, // not real C type + { "float" , RDI_TypeKind_F32 , CV_BasicType_FLOAT32 }, + { "double" , RDI_TypeKind_F64 , CV_BasicType_FLOAT64 }, + { "long double" , RDI_TypeKind_F80 , CV_BasicType_FLOAT80 }, + { "__float128" , RDI_TypeKind_F128 , CV_BasicType_FLOAT128 }, // Clang type + { "__float48" , RDI_TypeKind_F48 , CV_BasicType_FLOAT48 }, // not real C type + { "__float32pp" , RDI_TypeKind_F32PP , CV_BasicType_FLOAT32PP }, // not real C type + { "__float16" , RDI_TypeKind_F16 , CV_BasicType_FLOAT16 }, + { "_Complex float" , RDI_TypeKind_ComplexF32 , CV_BasicType_COMPLEX32 }, + { "_Complex double" , RDI_TypeKind_ComplexF64 , CV_BasicType_COMPLEX64 }, + { "_Complex long double" , RDI_TypeKind_ComplexF80 , CV_BasicType_COMPLEX80 }, + { "_Complex __float128" , RDI_TypeKind_ComplexF128, CV_BasicType_COMPLEX128 }, + { "__int8" , RDI_TypeKind_S8 , CV_BasicType_INT8 }, + { "__uint8" , RDI_TypeKind_U8 , CV_BasicType_UINT8 }, + { "__int16" , RDI_TypeKind_S16 , CV_BasicType_INT16 }, + { "__uint16" , RDI_TypeKind_U16 , CV_BasicType_UINT16 }, + { "int32" , RDI_TypeKind_S32 , CV_BasicType_INT32 }, + { "uint32" , RDI_TypeKind_U32 , CV_BasicType_UINT32 }, + { "__int64" , RDI_TypeKind_S64 , CV_BasicType_INT64 }, + { "__uint64" , RDI_TypeKind_U64 , CV_BasicType_UINT64 }, + { "__int128" , RDI_TypeKind_S128 , CV_BasicType_INT128 }, + { "__uint128" , RDI_TypeKind_U128 , CV_BasicType_UINT128 }, + { "char" , RDI_TypeKind_Char8 , CV_BasicType_RCHAR }, // always ASCII + { "wchar_t" , RDI_TypeKind_UChar16 , CV_BasicType_WCHAR }, // on windows always UTF-16 + { "char8_t" , RDI_TypeKind_Char8 , CV_BasicType_CHAR8 }, // always UTF-8 + { "char16_t" , RDI_TypeKind_Char16 , CV_BasicType_CHAR16 }, // always UTF-16 + { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 }, // always UTF-32 + { "__pointer" , ptr_type , CV_BasicType_PTR } }; - // special case for null type - itype_type_ptrs[CV_BasicType_NOTYPE] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_NULL); + itype_type_ptrs[CV_BasicType_NOTYPE] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_NULL); + itype_type_ptrs[CV_BasicType_HRESULT] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_HResult); + itype_type_ptrs[CV_BasicType_VOID] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_Void); for(U64 i = 0; i < ArrayCount(table); i += 1) { @@ -3481,49 +3476,18 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) builtin_alias->kind = RDI_TypeKind_Alias; builtin_alias->name = str8_cstring(table[i].name); builtin_alias->direct_type = rdim_builtin_type_from_kind(all_types, table[i].kind_rdi); - itype_type_ptrs[table[i].kind_cv] = builtin_alias; - - if(table[i].make_pointer_near) - { - CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; - RDIM_Type *ptr_near = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_near->kind = RDI_TypeKind_Ptr; - ptr_near->byte_size = 2; - ptr_near->direct_type = builtin_alias; - - itype_type_ptrs[near_ptr_itype] = ptr_near; - } - if(table[i].make_pointer_32) - { - CV_TypeIndex ptr_32_itype = table[i].kind_cv | 0x400; - RDIM_Type *ptr_32 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_32->kind = RDI_TypeKind_Ptr; - ptr_32->byte_size = 4; - ptr_32->direct_type = builtin_alias; - - itype_type_ptrs[ptr_32_itype] = ptr_32; - } - if(table[i].make_pointer_64) - { - CV_TypeIndex ptr_64_itype = table[i].kind_cv | 0x600; - RDIM_Type *ptr_64 = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); - ptr_64->kind = RDI_TypeKind_Ptr; - ptr_64->byte_size = 8; - ptr_64->direct_type = builtin_alias; - - itype_type_ptrs[ptr_64_itype] = ptr_64; - } } } - for(CV_TypeId root_itype = tpi->itype_first; root_itype < itype_opl; root_itype += 1) + for(CV_TypeId root_itype = 0; root_itype < itype_opl; root_itype += 1) { for(P2R_TypeIdChain *itype_chain = itype_chains[root_itype]; itype_chain != 0; itype_chain = itype_chain->next) { CV_TypeId itype = (root_itype != itype_chain->itype && itype_chain->itype < itype_opl && itype_fwd_map[itype_chain->itype]) ? itype_fwd_map[itype_chain->itype] : itype_chain->itype; + B32 itype_is_basic = (itype < tpi->itype_first); ////////////////////////// //- rjf: skip forward-reference itypes - all future resolutions will @@ -3542,10 +3506,51 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { continue; } + + ////////////////////////// + //- rjf: build basic type + // + if(itype_is_basic) + { + RDIM_Type *dst_type = 0; + + // rjf: unpack itype + CV_BasicPointerKind cv_basic_ptr_kind = CV_BasicPointerKindFromTypeId(itype); + CV_BasicType cv_basic_type_code = CV_BasicTypeFromTypeId(itype); + + // rjf: get basic type slot, fill if unfilled + RDIM_Type *basic_type = itype_type_ptrs[cv_basic_type_code]; + if(basic_type == 0) + { + RDI_TypeKind type_kind = p2r_rdi_type_kind_from_cv_basic_type(cv_basic_type_code); + U32 byte_size = rdi_size_from_basic_type_kind(type_kind); + basic_type = dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + if(byte_size == 0xffffffff) + { + byte_size = arch_addr_size; + } + basic_type->kind = type_kind; + basic_type->name = cv_type_name_from_basic_type(cv_basic_type_code); + basic_type->byte_size = byte_size; + } + + // rjf: nonzero ptr kind -> form ptr type to basic tpye + if(cv_basic_ptr_kind != 0) + { + dst_type = rdim_type_chunk_list_push(arena, &all_types, (U64)itype_opl); + dst_type->kind = RDI_TypeKind_Ptr; + dst_type->byte_size = arch_addr_size; + dst_type->direct_type = basic_type; + } + + // rjf: fill this itype's slot with the finished type + itype_type_ptrs[itype] = dst_type; + } ////////////////////////// //- rjf: build non-basic type // + if(!itype_is_basic && itype >= itype_first) { RDIM_Type *dst_type = 0; CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-itype_first]; From 08515428fbc89672d4c64174fdbbbf5b379a6274 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 5 May 2025 15:11:34 -0700 Subject: [PATCH 578/755] convert typedefs from PDB --- src/rdi_from_pdb/rdi_from_pdb.c | 26 ++++++++++++++++++++++---- src/rdi_from_pdb/rdi_from_pdb.h | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index d6abec95..5f743620 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -2088,6 +2088,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) RDIM_SymbolChunkList sym_thread_variables = {0}; RDIM_ScopeChunkList sym_scopes = {0}; RDIM_InlineSiteChunkList sym_inline_sites = {0}; + RDIM_TypeChunkList typedefs = {0}; ////////////////////////// //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) @@ -2310,6 +2311,20 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) symbol->container_type = container_type; } }break; + + case CV_SymKind_UDT: + { + if(in->parsing_global_stream && top_scope_node == 0) + { + CV_SymUDT *udt = (CV_SymUDT *)sym_header_struct_base; + String8 name = str8_cstring_capped(udt+1, sym_data_opl); + + RDIM_Type *type = rdim_type_chunk_list_push(arena, &typedefs, 4096); + type->kind = RDI_TypeKind_Alias; + type->name = name; + type->direct_type = p2r_type_ptr_from_itype(udt->itype); + } + }break; //- rjf: LPROC32/GPROC32 case CV_SymKind_LPROC32: @@ -2919,6 +2934,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) out->thread_variables = sym_thread_variables; out->scopes = sym_scopes; out->inline_sites = sym_inline_sites; + out->typedefs = typedefs; } #undef p2r_type_ptr_from_itype @@ -3990,10 +4006,11 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) tasks_inputs[idx].link_name_map = link_name_map; if(idx < global_stream_subdivision_tasks_count) { - tasks_inputs[idx].sym = sym; - tasks_inputs[idx].sym_ranges_first= idx*global_stream_syms_per_task; - tasks_inputs[idx].sym_ranges_opl = tasks_inputs[idx].sym_ranges_first + global_stream_syms_per_task; - tasks_inputs[idx].sym_ranges_opl = ClampTop(tasks_inputs[idx].sym_ranges_opl, sym->sym_ranges.count); + tasks_inputs[idx].parsing_global_stream = 1; + tasks_inputs[idx].sym = sym; + tasks_inputs[idx].sym_ranges_first = idx*global_stream_syms_per_task; + tasks_inputs[idx].sym_ranges_opl = tasks_inputs[idx].sym_ranges_first + global_stream_syms_per_task; + tasks_inputs[idx].sym_ranges_opl = ClampTop(tasks_inputs[idx].sym_ranges_opl, sym->sym_ranges.count); } else { @@ -4019,6 +4036,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) rdim_symbol_chunk_list_concat_in_place(&all_thread_variables, &out->thread_variables); rdim_scope_chunk_list_concat_in_place(&all_scopes, &out->scopes); rdim_inline_site_chunk_list_concat_in_place(&all_inline_sites,&out->inline_sites); + rdim_type_chunk_list_concat_in_place(&all_types, &out->typedefs); } } } diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index 03cae2d2..e8642256 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -249,6 +249,7 @@ struct P2R_UDTConvertIn typedef struct P2R_SymbolStreamConvertIn P2R_SymbolStreamConvertIn; struct P2R_SymbolStreamConvertIn { + B32 parsing_global_stream; RDI_Arch arch; COFF_SectionHeaderArray coff_sections; PDB_TpiHashParsed *tpi_hash; @@ -271,6 +272,7 @@ struct P2R_SymbolStreamConvertOut RDIM_SymbolChunkList thread_variables; RDIM_ScopeChunkList scopes; RDIM_InlineSiteChunkList inline_sites; + RDIM_TypeChunkList typedefs; }; //////////////////////////////// From 9c969d7c2b03f1598836f084e52641466e650c69 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 15:15:19 -0700 Subject: [PATCH 579/755] readme pass --- src/raddbg/raddbg.mdesk | 157 +++++++++++++++++++++++---------------- src/raddbg/raddbg_core.c | 40 +++++----- src/raddbg/raddbg_main.c | 1 + 3 files changed, 118 insertions(+), 80 deletions(-) diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b2b460a5..a00ebf22 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -14,26 +14,26 @@ //////////////////////////////// //~ rjf: Fixed Tab Tables -@table(name display_name name_lower is_query icon) +@table(name display_name name_lower is_query icon description) RD_WatchTabFastPathTable: { - {Watch "Watch" watches 0 Binoculars } - {Locals "Locals" locals 1 Binoculars } - {Registers "Registers" registers 1 Binoculars } - {Globals "Globals" globals 1 Binoculars } - {ThreadLocals "Thread Locals" thread_locals 1 Binoculars } - {Types "Types" types 1 Binoculars } - {Procedures "Procedures" procedures 1 Binoculars } - {CallStack "Call Stack" call_stack 1 Thread } - {Targets "Targets" targets 1 Target } - {Breakpoints "Breakpoints" breakpoints 1 CircleFilled } - {WatchPins "Watch Pins" watch_pins 1 Pin } - {Threads "Threads" threads 1 Threads } - {Processes "Processes" processes 1 Scheduler } - {Machines "Machines" machines 1 Machine } - {Modules "Modules" modules 1 Module } - {FilePathMaps "File Path Map" file_path_maps 1 FileOutline } - {TypeViews "Type Views" type_views 1 Binoculars } + {Watch "Watch" watches 0 Binoculars "An editable table interface for entering one or many expressions to evaluate, and visualizing and exploring their values."} + {Locals "Locals" locals 1 Binoculars "Like the Watch tab, but not editable, and displays the set of local variables found at the selected thread's current location."} + {Registers "Registers" registers 1 Binoculars "Like the Watch tab, but not editable, and displays the set of registers for the selected thread."} + {Globals "Globals" globals 1 Binoculars "Like the Watch tab, but not editable, and displays all global variables from all loaded modules."} + {ThreadLocals "Thread Locals" thread_locals 1 Binoculars "Like the Watch tab, but not editable, and displays all thread-local variables from all loaded modules."} + {Types "Types" types 1 Binoculars "Like the Watch tab, but not editable, and displays all types from all loaded modules."} + {Procedures "Procedures" procedures 1 Binoculars "Like the Watch tab, but not editable, and displays all procedures from all loaded modules."} + {CallStack "Call Stack" call_stack 1 Thread "Displays the currently selected thread's call stack, and allows selecting a frame in the call stack, which will unwind the selected thread's registers and evaluate expressions within that frame's context."} + {Targets "Targets" targets 1 Target "Displays, and allows editing of, the list of all targets."} + {Breakpoints "Breakpoints" breakpoints 1 CircleFilled "Displays, and allows editing of, the list of all breakpoints."} + {WatchPins "Watch Pins" watch_pins 1 Pin "Displays, and allows editing of, the list of all watch pins."} + {Threads "Threads" threads 1 Threads "Displays the list of all threads in all processes to which the debugger is attached."} + {Processes "Processes" processes 1 Scheduler "Displays the list of all processes to which the debugger is attached."} + {Machines "Machines" machines 1 Machine "Displays the list of all machines to which the debugger is connected."} + {Modules "Modules" modules 1 Module "Displays the list of all modules in all processes to which the debugger is attached."} + {FilePathMaps "File Path Map" file_path_maps 1 FileOutline "Displays, and allows editing of, the list of all file path maps. This allows remapping source code paths referenced by debug information to other paths on your local machine."} + {TypeViews "Type Views" type_views 1 Binoculars "Displays, and allows editing of, the list of all type views, which allow automatically adjusting the visualizations for evaluations of a certain type."} } @table(name display_name name_lower view query icon) @@ -2013,13 +2013,13 @@ RD_CodeColorTable: raddbg_readme: { @title "The RAD Debugger (ALPHA)"; - @p "The RAD Debugger is a native, user-mode, multi-process, graphical debugger. It currently only supports local-machine Windows x64 debugging with PDBs, with plans to expand and port in the future."; + @p "The RAD Debugger is a native, user-mode, multi-process, graphical debugger. It currently only supports local-machine Windows x64 debugging with PDBs, but we're actively working on support and ports for other toolchains and platforms."; @subtitle "Getting Started"; - @p "To launch the RAD Debugger with your executable and command line arguments, run `raddbg` from the command line like so:"; + @p "**Launching the debugger with your program information:** To launch the RAD Debugger with your executable and command line arguments, run `raddbg` from the command line like so:"; @p "```raddbg my_program.exe --foo --bar --baz```"; - @p "For more information, see the 'Command-Line Usage' section."; - @p "Default keyboard shortcuts for common debugger controls include:"; + @p "For more information, see the **Command-Line Usage** section."; + @p "**Basic commands and keybindings:** Default keyboard shortcuts for common debugger controls include:"; @unordered_list { @p "**Ctrl + O**: Open Source Code File"; @@ -2038,63 +2038,75 @@ raddbg_readme: @p "**Ctrl + Tab**: Focus Next Tab"; @p "**Ctrl + Shift + Tab**: Focus Previous Tab"; @p "**Ctrl + W**: Close Tab"; - @p "**F1**: Open Command Palette"; + @p "**F1**: Open Palette (lists commands, keybindings, settings, threads, processes, modules, types, and many other things)"; } - @p "For more information, see the 'Commands' section."; - @p "View rules can be used to visualize expressions differently in the watch window. Here are some examples:"; + @p "For more information, see the **Commands** section."; + + @p "**Configuration files (users and projects):** The RAD Debugger stores configuration in two files. One is the 'user file', the other is the 'project file'. Both files are the same format and can store the same kinds of data, but the user file is preferred by the debugger for more likely user-related data (windows, keybindings, theme), and the project file is preferred by the debugger for more likely project-related data (executable debugging targets, breakpoints, recent source files). Project files are more likely to be what you'd check into source control, whereas a user file is more likely to have your personal debugger settings (which will apply identically regardless of which project file is opened)."; + + @p "The debugger autosaves user and project files. You do not need to manually save them. To switch which path you are using for either, you can use the `Open User` (Ctrl + Alt + Shift + O, by default), or `Open Project` (Ctrl + Alt + O, by default) commands respectively. If a file does not exist at the path you enter for either, then a new one will be created, and the debugger will begin autosaving to it. If the initial paths to these files are not specified on the command line (via `--user` or `--project`), then the debugger uses default paths for them. The user file path, by default, will be `%appdata%/raddbg/default.raddbg_user`. The project file path will be whatever project path was last loaded for the user, or if no such path exists, `%appdata%/raddbg/default.raddbg_project`. If you suspect that your configuration files are corrupted or causing the debugger to behave poorly, it might help to delete your `%appdata%/raddbg` folder (although it'd also help if you [sent it to us in a bug report](https://github.com/EpicGamesExt/raddebugger/issues), so that we can investigate why they were corrupted to begin with!)."; + @p "For more information, see the `**User & Project Files** section."; + + @p "**Watch tabs and visualizers:** 'Watch' tabs in the RAD Debugger allow entering expressions, which can reference variables in your program, and visualize what their value is when your program is stopped at a particular time. These expressions roughly follow C expression syntax, but there are a number of extensions which can be used to visualize expressions in a more useful way. Here are some examples:"; @unordered_list { - @p "`array:16`: Visualize a pointer as pointing to a 16-element array."; - @p "`array:(count*2)`: Visualize a pointer as pointing to a `count*2`-element array."; - // @p "`list:next`: Visualize a linked list flatly, where each node has a `next` pointer, which points to the next node in the list."; - @p "`hex`: Visualize numeric literals as base-16 (hexadecimal)."; - @p "`dec`: Visualize numeric literals as base-10 (decimal)."; - @p "`oct`: Visualize numeric literals as base-8 (octal)."; - @p "`bin`: Visualize numeric literals as base-2 (binary)."; - @p "`omit:(foo bar baz)`: Prohibits members named `foo`, `bar`, and `baz` from being displayed."; - @p "`only:(foo bar baz)`: Only allows members named `foo`, `bar`, and `baz` to be displayed."; - @p "`slice`: Attempts to interpret a structure evaluation as encoding a slice, with a base pointer and an integer delimiting the number of elements to which the pointer points."; + @p "`array(pointer, 64)`: Visualizes `pointer` as pointing to a 256-element array."; + @p "`pointer, 64`: Visualizes `pointer` as pointing to a 256-element array."; + @p "`pointer, count`: Visualizes `pointer` as pointing to a `count`-element array."; + @p "`slice(some_slice_struct)`: Interprets a structure type as containing a base pointer and a count (either through an integer, or an 'end pointer'), and visualizes the base pointer, pointing to that many elements."; + @p "`only(some_struct, a, b, c)`: Displays the value of `some_struct`, but only showing members `a`, `b`, and `c`."; + @p "`omit(some_struct, a, b, c)`: Displays the value of `some_struct`, but only showing members other than `a`, `b`, and `c`."; + @p "`hex(my_int)`: Visualizes the value of `my_int` in base-16 (hexadecimal) form."; + @p "`dec(my_int)`: Visualizes the value of `my_int` in base-10 (decimal) form."; + @p "`bin(my_int)`: Visualizes the value of `my_int` in base-2 (binary) form."; + @p "`oct(my_int)`: Visualizes the value of `my_int` in base-8 (octal) form."; + @p "`my_int, x`: Visualizes the value of `my_int` in base-16 (hexadecimal) form."; + @p "`my_int, d`: Visualizes the value of `my_int` in base-10 (decimal) form."; + @p "`my_int, b`: Visualizes the value of `my_int` in base-2 (binary) form."; + @p "`my_int, o`: Visualizes the value of `my_int` in base-8 (octal) form."; + @p "`digits(bin(my_int), 32)`: Visualizes the value of `my_int` in base-2 (binary) form, showing at minimum 32 bits."; + @p "`my_int.bin().digits(32)`: Visualizes the value of `my_int` in base-2 (binary) form, showing at minimum 32 bits."; + @p "`bitmap(base_pointer, width, height, fmt=rgba8)`: Visualizes the data starting at `base_pointer` as a bitmap, with width `width` and height `height`, with format `rgba8`."; } - @p "Multiple view rules can be specified on one line, so they can be combined like so:"; - @p "```array:16, hex, only: {x, y, z}```"; - @p "For more information, see the 'View Rules' section."; + @p "For more information, see the **Views** section."; @subtitle "Command-Line Usage"; - @p "When run normally, either by launching through a file explorer or running from a command line without arguments, `raddbg` will open a new instance of the debugger, and await further operations. But it also supports a number of command line options for a number of other purposes. These options are specified with a `-` or `--` prefix, followed by the name of the option, and if the option requires a parameter, followed by a `:` or `=`, followed by the parameter's content. A list of the possible options follows:"; + @p "When run normally, either by launching through a file explorer or running from a command line without arguments, `raddbg` will open a new instance of the debugger, and await further operations. But it also supports a number of command line options for a number of other purposes. These options are specified with a `-` or `--` prefix, followed by the name of the option, and if the option requires an argument value, followed by a `:` or `=`, followed by the argument value. A list of the possible options follows:"; @unordered_list { @p "`--help` Displays a help menu which documents the possible command line options."; - @p "`--user:` Use to specify the location of a user file which should be used. User files are used to store settings for users, including window and panel setups, path mapping, and visual settings. If this file does not exist, it will be created as necessary. This file will be autosaved as user-related changes are made. For more information on user files, read the 'User & Profile Files' section."; - @p "`--project:` Use to specify the location of a project file which should be used. Project files are used to store settings for users and projects. If this file does not exist, it will be created as necessary. This file will be autosaved as project-related changes are made. For more information on project files, read the 'User & Project Files' section."; + @p "`--user:` Use to specify the location of a user file which should be used. User files are used by default to store user-related settings, including window and panel setups, path mapping, and visual settings. If this file does not exist, it will be created as necessary. This file will be autosaved as user-related changes are made. For more information on user files, see the **User & Project Files** section."; + @p "`--project:` Use to specify the location of a project file which should be used. Project files are used by default to store project-related settings. If this file does not exist, it will be created as necessary. This file will be autosaved as project-related changes are made. For more information on project files, read the 'User & Project Files' section."; @p "`--auto_step` This will step into all active targets after the debugger initially starts."; @p "`--auto_run` This will run all active targets after the debugger initially starts."; - @p "`--quit_after_success` (or `-q`) This will close the debugger automatically after all processes exit, if they all exited successfully (with code 0), and ran with no interruptions.."; - @p "`--ipc` This will launch the debugger in the non-graphical IPC mode, which is used to communicate with another running instance of the debugger. The debugger instance will launch, send the specified command, then immediately terminate. This may be used by editors or other programs to control the debugger. For more information on commands, read the 'Commands' section. For more information on driving another debugger instance with this argument, read the 'Driving Another Debugger Instance' section." + @p "`--quit_after_success` (or `-q`) This will close the debugger automatically after all processes exit, if they all exited successfully (with code 0), and ran with no interruptions."; + @p "`--ipc` This will launch the debugger in the non-graphical IPC mode, which is used to communicate with another running instance of the debugger. The debugger instance will launch, send the specified command, then immediately terminate. This may be used by editors or other programs to control the debugger. For more information on the set of available commands, see the **Commands** section. For more information on driving another debugger instance with this argument, see the **Driving Another Debugger Instance** section."; } - @p "On the command line, non-options (meaning any command line arguments *not* prefixed with a `-` or `--`) can also be specified. with normal usage, they are interpreted as the command line for a target (see the 'Targets' section). When driving another debugger instance (using the `--ipc` argument), this additional command line text is used to encode a debugger command."; + @p "On the command line, non-options (meaning any command line arguments *not* prefixed with a `-` or `--`) can also be specified. With normal usage, they are interpreted as the command line for a target (see the **Targets** section). When driving another debugger instance (using the `--ipc` argument), this additional command line text is used to encode a debugger command."; @p "The debugger will stop parsing `-` and `--` prefixes as arguments after seeing a standalone `--`, *or* after seeing the first non-option argument, when reading the command line left-to-right. Some examples of command line usage and their interpretations are below:"; @unordered_list { - @p "`raddbg --foo --bar --a:b --c=d test.exe` All options are used to configure `raddbg`. `test.exe` is interpreted as a target executable. `b` is interpreted as the parameter for the `a` option. `d` is interpreted as the parameter for the `c` option."; - @p "`raddbg test.exe --foo --bar` `test.exe` is interpreted as a target executable. `--foo --bar` is interpreted as arguments for `test.exe`, and thus are *not* used to configure `raddbg`."; - @p "`raddbg -- test.exe` `test.exe` is interpreted as a target executable."; - @p "`raddbg --ipc find_code_location \"c:/foo/bar/baz.c:123:1\"` `--ipc` configures `raddbg` to drive another instance of `raddbg`. The remainder of the text is interpreted as a command."; - @p "`raddbg \"C:/path with spaces/test.exe\" --foo --bar` A target is formed from the `test.exe` path, and `--foo --bar` are interpreted as arguments to the `test.exe` target."; + @p "`raddbg --foo --bar --a:b --c=d test.exe`: All options are used to configure `raddbg`. `test.exe` is interpreted as a target executable. `b` is interpreted as the parameter for the `a` option. `d` is interpreted as the parameter for the `c` option."; + @p "`raddbg test.exe --foo --bar`: `test.exe`is interpreted as a target executable. `--foo --bar` is interpreted as arguments for `test.exe`, and thus are *not* used to configure `raddbg`."; + @p "`raddbg -- test.exe`: `test.exe` is interpreted as a target executable."; + @p "`raddbg --ipc find_code_location \"C:/foo/bar/baz.c:123:1\"`: `--ipc` configures `raddbg` to drive another instance of `raddbg`. The remainder of the text is interpreted as a command."; + @p "`raddbg \"C:/path with spaces/test.exe\" --foo --bar`: A target is formed from the `test.exe` path, and `--foo --bar` are interpreted as arguments to the `test.exe` target."; } @subtitle "Windows, Panels, & Tabs"; - @p "Each opened *window* in the debugger frontend is subdivided into *panels*. Panels subdivide regions of their window without overlapping. Each panel can contain multiple *tabs*, and can have one tab selected at any time. Tabs can be dragged and dropped between panels. Each tab is used to view one of the many supported debugger interfaces, including source code, disassembly, memory, or watches. When a tab is selected, that interface will fill the tab's containing panel's region of the containing window."; + @p "Each opened debugger window is subdivided into panels. Panels subdivide regions of their window without overlapping. Each panel can contain multiple tabs, and can have one tab selected at any time. Tabs can be dragged and dropped between panels. Each tab is used to view one of the many supported debugger interfaces, including source code, disassembly, memory, or watch tables. When a tab is selected, that interface will fill the tab's containing panel's region of the containing window."; @p "There are no 'special' windows, panels, or tabs; the debugger is written such that the number of windows, each window's panel organization, and the placement and arrangement of tabs can all be organized in a large variety of ways."; @p "A list of debugger interfaces, which can occupy tabs, are below:"; @unordered_list { - @expand(RD_ViewRuleTable a) @p "$(a.show_in_docs -> '`'..a.display_name..'` '..a.description)"; + @expand(RD_WatchTabFastPathTable a) @p "**$(a.display_name)**: $(a.description)"; } + @p "You can open one of these tabs in any panel by clicking the `+` icon next to that panel's tabs, or by executing the `Open Tab` command (bound to Ctrl + T) by default."; @subtitle "Commands"; - @p "The debugger is operated with *commands*. Commands may be manually executed in the debugger UI through the `Commands` menu, which you can open with the `Run Command` keybinding, which is F1 by default). Operations in the debugger UI are implemented with commands, so if it's ever unclear how to accomplish some operation through the UI, a useful fallback is searching for and running the command through the command menu."; + @p "The debugger, including implicitly with its UI, is operated almost entirely through 'commands'. Commands may be manually executed in the debugger UI within the palette (which you can open with F1 by default), or within the commands list which is opened when you execute the 'Run Command' command. Operations in the debugger UI are implemented with commands, so if it's ever unclear how to accomplish some operation through the UI, a useful fallback is searching for and running the command through the palette."; @p "Commands are also how a debugger instance launched with `--ipc` may communicate with a primary debugger instance."; - @p "A list of commands, how they're referred to textually (for the purposes of `--ipc` debugger instances), and their descriptions are below:"; + @p "A list of commands, how they're referred to textually (for the purposes of `--ipc` debugger instances), and their descriptions, are below:"; @unordered_list { @expand(D_CmdTable a) @p "$(a.ipc_docs_vis == 1 -> '`'..a.display_name..'` '..'(`'..a.string..'`) '..a.desc)"; @@ -2102,26 +2114,47 @@ raddbg_readme: } @subtitle "Targets"; - @p "A *target* is one executable and configuration for launching that executable, including command line arguments and working directory (the directory from which the executable is launched). Each target may also have a custom label (replaces the executable path when visualizing the target), and the name of a custom entry point function (when the default entry points - `main`, `WinMain`, etc. - are not desired when stepping into the program upon launch). The debugger can have several targets at once. Each target can also be enabled or disabled. Some operations work on all enabled targets - for instance, the `Run` or `Kill All` commands (standardly bound as F5 or Shift + F5). Enabling and disabling targets allows one to filter which targets are currently being worked with."; + @p "A *target* is one executable and configuration for launching that executable, including command line arguments and working directory (the directory from which the executable is launched). Each target may also have a custom label (prioritized over the executable name when visualizing the target, and also allows evaluation of the target in a Watch tab), and the name of a custom entry point function (when the default entry points - `main`, `WinMain`, etc. - are not desired when stepping into the program upon launch). The debugger can have several targets at once. Each target can also be enabled or disabled. Some operations work on all enabled targets - for instance, the `Run` or `Kill All` commands (standardly bound as F5 or Shift + F5). Enabling and disabling targets allows one to filter which targets are currently being worked with."; @p "To add a target, you can run the `Add Target` command. A target is also created automatically from command line arguments - the rules for how this happens can be found in the `Command-Line Usage` section."; @p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, you can right click the command-line-created target in the `Targets` view, and click `Save To Project`. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line."; - @subtitle "View Rules"; - @p "*View rules* are used to transform the way that evaluations in the debugger are visualized. An evaluation is produced by taking an expression string - for instance, the name of a variable - and using debug info and information from an attached process' live runtime (memory, registers, and so on) to interpret it."; + @subtitle "Views"; + @p "*Views* are used to transform the way that evaluations in the debugger are visualized. An evaluation is produced by taking an expression string - for instance, the name of a variable - and using debug info and information from an attached process' live runtime (memory, registers, and so on) to interpret it."; @p "Evaluations may be visualized in a variety of ways. A 64-bit unsigned integer may be visualized as a textual representation of the value with a radix of 10. A 32-bit floating-point value may be visualized as a textual representation of the value. An array of 32-bit floating-point values can be visualized as a list of textual representations of those values."; - @p "But all of these cases may be visualized in a number of other ways, as well. A 64-bit unsigned integer may be more usefully represented with a radix of 16, 8, or 2. An array of 32-bit floating-point values may encode the R, G, B, and A components of a color, or vertex positions for 3D geometry, or samples for a waveform. An array of bytes may encode raw pixel data for an image, or image data in a compressed format. A struct may have several members which are not useful to look at all the time. A struct may form the head of a linked list, and a flat linked list representation may be more preferable than the traditional watch view representation, which adds an additional layer of hierarchical nesting with the expansion of each 'next' pointer in a linked list. When designing the debugger, we felt that the traditional memory view and watch view representations of data in a debugged-process were not sufficient. View rules were added to the traditional watch view structure to allow per-row specification of extra visualization parameters."; - @p "View rules are specified with the name of a view rule, and depending on the view rule, a `:`, followed by parameters for the view rule. These parameters may be whitespace delimited, but importantly, multiple view rules may be specified per-row in a watch view. To explicitly separate the parameters of one view rule from the name of another - for instance, in a case like `array:16 bin`, where `bin` will not be interpreted as a view rule, but as a parameter of `array` - then commas and semicolons may be used to separate the two view rules (`array:16, bin`), or parentheses/braces/brackets may also be used to explicitly delimit the view rule parameters (`array:(16) bin`)."; - @p "A list of currently-supported view rules are below:"; + @p "But all of these cases may be visualized in a number of other ways, as well. A 64-bit unsigned integer may be more usefully represented with a radix of 16, 8, or 2. An array of 32-bit floating-point values may encode the R, G, B, and A components of a color, or vertex positions for 3D geometry, or samples for a waveform. An array of bytes may encode raw pixel data for an image, or image data in a compressed format. A struct may have several members which are not useful to look at all the time. A struct may form the head of a linked list, and a flat linked list representation may be more preferable than the traditional watch view representation, which adds an additional layer of hierarchical nesting with the expansion of each 'next' pointer in a linked list. When designing the debugger, we felt that the traditional memory view and watch view representations of data in a debugged-process were not sufficient. Views were added to the traditional watch table structure to allow per-expression specification of extra visualization parameters."; + @p "Views look just like function calls. They start with the name of the view, a `(`, then a list of expressions which form the arguments for the view (optionally delimited by `,`s), followed by a `)`. The meaning of these arguments can sometimes be inferred through their order; for example, in the case of `bitmap(ptr, 512, 256)`, the `bitmap` view uses the `ptr` as the primary expression to interpret as bitmap data, then assumes the widely-used pattern of width, then height, to interpret the following arguments as the dimensions of the bitmap. In other cases, arguments must be specifically named. For instance, the `fmt` argument in `bitmap(ptr, 512, 256, fmt=bgra8)` is required to override the `bitmap` view's default assumption of RGBA8 bitmap data."; + @p "A list of currently-supported views are below:"; @unordered_list { - @expand(D_ViewRuleTable a) @p "$(a.docs == 'x' -> '`'..a.string..'` ('..a.display_name..') '..a.description)"; + // TODO(rjf): @lenses generate via metaprogram + @p "`raw(expr)`: Ignores all views used in `expr`, including those automatically applied by type views."; + @p "`bin(expr)`: Visualizes all numeric values evaluated in `expr` as base-2 (binary)."; + @p "`oct(expr)`: Visualizes all numeric values evaluated in `expr` as base-8 (octal)."; + @p "`dec(expr)`: Visualizes all numeric values evaluated in `expr` as base-10 (decimal)."; + @p "`hex(expr)`: Visualizes all numeric values evaluated in `expr` as base-16 (hexadecimal)."; + @p "`digits(expr, num)`: Visualizes at least `num` digits in all numeric values evaluated in `expr`."; + @p "`no_string(expr)`: Disables textual string visualization with pointer evaluations in `expr`."; + @p "`no_char(expr)`: Disables character visualization with character or integer evaluations in `expr`."; + @p "`no_addr(expr)`: Disables explicit address visualization with pointer evaluations in `expr`."; + @p "`sequence(expr)`: Interprets `expr` as an integer, encoding how many sub-expressions `expr` should expand to produce. This can be used in combination with the `table` view to easily generate tables, indexing amongst many arrays."; + @p "`only(expr, ...)`: Interpreting all post-`expr` arguments as member names, only expands to show those members of `expr`."; + @p "`omit(expr, ...)`: Interpreting all post-`expr` arguments as member names, expands to show all members of `expr`, except those with matching names."; + @p "`range1(expr, min, max)`: Expresses that `expr` is a bounded numeric value between `min` and `max`. Interpreted by the debugger to build slider UI for an evaluation."; + @p "`array(expr, count)`: Expresses that `expr` points to `count` values, rather than 1, or the fixed size implied by a static array. When expanded, displays only that many values."; + @p "`slice(expr)`: Expresses that `expr` evaluates to a structure type which bundles a base pointer and a count (encoding how many elements to which the base pointer points). This count can be expressed either as an integer, or as an 'end pointer'. When expanded, displays that many elements following that base pointer."; + @p "`table(expr, ...)`: Expresses that `expr` should be expanded normally, but interprets all post-`expr` arguments as expressions which should be used to form cells for rows which are generated by this expression's expansions. This replaces the normal cells which are generated for an expansion in a Watch table."; + @p "`text(expr, [lang = ...])`: Generates a text visualizer, interpreting `expr` as (being or pointing to) text."; + @p "`disasm(expr, [size = ...]`: Generates a disassembly visualizer, interpreting `expr` as (being or pointing to) machine code."; + @p "`memory(expr, [size = ...])`: Generates a memory visualizer, interpreting `expr` as (being or pointing to) raw bytes."; + @p "`bitmap(expr, width, height, [fmt = ...])`: Generates a bitmap visualizer, interpreting `expr` as (being or pointing to) raw bitmap data, with `width` and `height` as dimensions."; + @p "`color(expr)`: Generates a color picker, interpreting `expr` as a color value."; } @subtitle "Breakpoints"; - @p "Breakpoints interrupt execution of attached processes. They may be placed on specific code addresses, lines of source code, on specific symbol names. In the latter two cases, the higher level locations are resolved to code addresses. If there is no code associated with a line of source code, then the resolution path chooses to use the next closest line of source code in the same file. A symbol name breakpoint will only work if the symbol name is found within loaded debug info."; + @p "Breakpoints interrupt execution of attached processes. They may be placed on arbitrary addresses (e.g. by placing a breakpoint on an instruction within a disassembly view, or with an arbitrary expression, like the name of a function), or on lines of source code. In the latter case, the source code location is resolved to code addresses. If there is no code associated with a line of source code, then the resolution path chooses to use the next closest line of source code in the same file."; @p "Breakpoints may have stop conditions attached to them. When a breakpoint is hit by a thread, before it stops execution, the stop condition is evaluated, and if it evaluates to a nonzero value, only then is execution stopped."; @p "Each breakpoint has a hit count. Every time a breakpoint causes execution to stop, this counter is increased."; - @p "Processor breakpoints are not currently supported, but planned to be in the future."; + @p "Address breakpoints can also point to data, rather than code. This will cause execution to stop if some data is read from, written to, or executed. In this case, the debugger configures the hardware to use the available hardware data breakpoints feature. To enable this path, in the breakpoint's editor, express the number of bytes following the address that should be checked for writes/reads/executions (can be 1, 2, 4, or 8), and select whether or not you want to break on reads, writes, or executions."; @subtitle "User & Project Files"; @p "Applicable state controlling the debugger's appearance, behavior, targets, breakpoints, and other configurations is saved and reloaded across runs of the debugger through both *user files* and *project files*. These files are auto-saved. These files are written in a textual format which can be hand-edited as necessary, but they're also continuously re-read and re-written by the debugger. By default, the debugger uses `%appdata%/raddbg/default.raddbg_user` for its user file path, and `%appdata%/raddbg/default.raddbg_project` for its project file path. These paths can be overridden on the command line (see the 'Command-Line Usage' section)."; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 106e3ddc..a201690e 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11848,7 +11848,7 @@ rd_frame(void) #endif //- rjf: choose set of lenses - // TODO(rjf): generate via metaprogram + // TODO(rjf): @lenses generate via metaprogram struct { String8 name; @@ -11960,35 +11960,39 @@ rd_frame(void) //////////////////////////// //- rjf: construct default immediate-mode configs based on loaded modules // - if(rd_state->use_default_stl_type_views) { local_persist read_only struct { + B32 stl; + B32 ue; String8 pattern; String8 expr; } type_views[] = { - { str8_lit_comp("std::vector"), str8_lit_comp("slice(_Mypair._Myval2)") }, - { str8_lit_comp("std::unique_ptr"), str8_lit_comp("_Mypair._Myval2") }, - { str8_lit_comp("std::basic_string"), str8_lit_comp("_Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : array(_Mypair._Myval2._Bx._Ptr, _Mypair._Myval2._Mysize)") }, - { str8_lit_comp("std::basic_string_view"), str8_lit_comp("array(_Mydata, _Mysize)") } + { 1, 0, str8_lit_comp("std::vector"), str8_lit_comp("slice(_Mypair._Myval2)") }, + { 1, 0, str8_lit_comp("std::unique_ptr"), str8_lit_comp("_Mypair._Myval2") }, + { 1, 0, str8_lit_comp("std::basic_string"), str8_lit_comp("_Mypair._Myval2._Myres <= 15 ? _Mypair._Myval2._Bx._Buf : array(_Mypair._Myval2._Bx._Ptr, _Mypair._Myval2._Mysize)") }, + { 1, 0, str8_lit_comp("std::basic_string_view"), str8_lit_comp("array(_Mydata, _Mysize)") }, }; - for EachElement(idx, type_views) + if(rd_state->use_default_stl_type_views) { - RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("default_stl_type_vis_%I64x", idx); - RD_Cfg *type_view = rd_cfg_child_from_string_or_alloc(immediate_root, str8_lit("type_view")); - RD_Cfg *type = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("type")); - RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("expr")); - rd_cfg_new_replace(type, type_views[idx].pattern); - rd_cfg_new_replace(expr, type_views[idx].expr); - rd_cfg_list_push(scratch.arena, &immediate_type_views, type_view); + for EachElement(idx, type_views) + { + if((type_views[idx].stl && rd_state->use_default_stl_type_views) || + (type_views[idx].ue && rd_state->use_default_ue_type_views)) + { + RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("default_stl_type_vis_%I64x", idx); + RD_Cfg *type_view = rd_cfg_child_from_string_or_alloc(immediate_root, str8_lit("type_view")); + RD_Cfg *type = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("type")); + RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(type_view, str8_lit("expr")); + rd_cfg_new_replace(type, type_views[idx].pattern); + rd_cfg_new_replace(expr, type_views[idx].expr); + rd_cfg_list_push(scratch.arena, &immediate_type_views, type_view); + } + } } } - if(rd_state->use_default_ue_type_views) - { - // TODO(rjf) - } //////////////////////////// //- rjf: add auto-hook rules for type views diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 0dba338e..9de46c2e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -196,6 +196,7 @@ // [ ] "pop out" (hitting enter on visualizers should open them as tabs) // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // [ ] finish theme editing, build themes - replace code colors map with new theme stuff +// [ ] save-to-project (command line targets) // // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... From 27072e11487627739d8b811c6f30d86f70cb3a85 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 15:23:11 -0700 Subject: [PATCH 580/755] save to project --- src/raddbg/generated/raddbg.meta.c | 8 +++++--- src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 5 +++-- src/raddbg/raddbg_core.c | 7 +++++++ src/raddbg/raddbg_main.c | 2 +- src/raddbg/raddbg_views.c | 18 ++++++++++++++++++ 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8fb1115f..ee791fa1 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[335] = +RD_VocabInfo rd_vocab_info_table[336] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -340,6 +340,7 @@ RD_VocabInfo rd_vocab_info_table[335] = {str8_lit_comp("condition_cfg"), str8_lit_comp(""), str8_lit_comp("Condition"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate"), str8_lit_comp(""), RD_IconKind_Duplicate}, {str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("save_cfg_to_project"), str8_lit_comp(""), str8_lit_comp("Save To Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, {str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, @@ -414,7 +415,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, @@ -474,7 +475,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[228] = +RD_CmdKindInfo rd_cmd_kind_info_table[229] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -647,6 +648,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[228] = { str8_lit_comp("condition_cfg"), str8_lit_comp("Equips a config tree with a condition string."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("duplicate_cfg"), str8_lit_comp("Duplicates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("relocate_cfg"), str8_lit_comp("Relocates a config tree."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_cfg_to_project"), str8_lit_comp("Saves the config tree to the project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 46514db7..409be95b 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -227,6 +227,7 @@ RD_CmdKind_NameCfg, RD_CmdKind_ConditionCfg, RD_CmdKind_DuplicateCfg, RD_CmdKind_RelocateCfg, +RD_CmdKind_SaveToProject, RD_CmdKind_AddBreakpoint, RD_CmdKind_AddAddressBreakpoint, RD_CmdKind_ToggleBreakpoint, @@ -561,7 +562,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[335]; +extern RD_VocabInfo rd_vocab_info_table[336]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a00ebf22..609c767f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -565,7 +565,7 @@ RD_VocabTable: { target, ``` - @row_commands(enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg) + @row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg) @collection_commands(add_target) x: { @@ -966,6 +966,7 @@ RD_CmdTable: // | | | | {ConditionCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "condition_cfg" "Condition" "Equips a config tree with a condition string." "" "" } {DuplicateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Duplicate "duplicate_cfg" "Duplicate" "Duplicates a config tree." "" "" } {RelocateCfg 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "relocate_cfg" "Relocate" "Relocates a config tree." "" "" } + {SaveToProject 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Briefcase "save_cfg_to_project" "Save To Project" "Saves the config tree to the project." "" "" } //- rjf: breakpoints {AddBreakpoint 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } @@ -2116,7 +2117,7 @@ raddbg_readme: @subtitle "Targets"; @p "A *target* is one executable and configuration for launching that executable, including command line arguments and working directory (the directory from which the executable is launched). Each target may also have a custom label (prioritized over the executable name when visualizing the target, and also allows evaluation of the target in a Watch tab), and the name of a custom entry point function (when the default entry points - `main`, `WinMain`, etc. - are not desired when stepping into the program upon launch). The debugger can have several targets at once. Each target can also be enabled or disabled. Some operations work on all enabled targets - for instance, the `Run` or `Kill All` commands (standardly bound as F5 or Shift + F5). Enabling and disabling targets allows one to filter which targets are currently being worked with."; @p "To add a target, you can run the `Add Target` command. A target is also created automatically from command line arguments - the rules for how this happens can be found in the `Command-Line Usage` section."; - @p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, you can right click the command-line-created target in the `Targets` view, and click `Save To Project`. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line."; + @p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, find the target in the `Targets` tab, and click the `Save To Project` button on that target's row. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line."; @subtitle "Views"; @p "*Views* are used to transform the way that evaluations in the debugger are visualized. An evaluation is produced by taking an expression string - for instance, the name of a variable - and using debug info and information from an attached process' live runtime (memory, registers, and so on) to interpret it."; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a201690e..23a08b54 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14654,6 +14654,13 @@ rd_frame(void) } } }break; + case RD_CmdKind_SaveToProject: + { + RD_Cfg *cfg = rd_cfg_from_id(rd_regs()->cfg); + rd_cfg_unhook(cfg->parent, cfg); + RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); + rd_cfg_insert_child(project, project->last, cfg); + }break; //- rjf: breakpoints case RD_CmdKind_AddBreakpoint: diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 9de46c2e..bc5c04b3 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -196,7 +196,6 @@ // [ ] "pop out" (hitting enter on visualizers should open them as tabs) // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // [ ] finish theme editing, build themes - replace code colors map with new theme stuff -// [ ] save-to-project (command line targets) // // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... @@ -508,6 +507,7 @@ // [x] "add hover eval to watch" (expr drag & drop -> watch window) // [x] unattached process evaluation - need a string to evaluate so I can generate // the evals +// [x] save-to-project (command line targets) //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 86b989ba..91cdca2b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1198,10 +1198,28 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) for MD_EachNode(cmd, cmds_root->first) { B32 is_file_only = md_node_has_tag(cmd, str8_lit("file"), 0); + B32 is_cmd_line_only = md_node_has_tag(cmd, str8_lit("cmd_line"), 0); if(is_file_only && e_eval_from_string(rd_expr_from_cfg(evalled_cfg)).space.kind != E_SpaceKind_File) { continue; } + if(is_cmd_line_only) + { + B32 is_cmd_line = 0; + RD_Cfg *cmd_line = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("command_line")); + for(RD_Cfg *p = evalled_cfg->parent; p != &rd_nil_cfg; p = p->parent) + { + if(p == cmd_line) + { + is_cmd_line = 1; + break; + } + } + if(!is_cmd_line) + { + continue; + } + } String8 cmd_name = cmd->string; RD_CmdKind cmd_kind = rd_cmd_kind_from_string(cmd_name); switch(cmd_kind) From d17502fac448d8775095e5f44331a3604e79a4bb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 15:29:07 -0700 Subject: [PATCH 581/755] fix missing byte sizes on alises --- src/rdi_from_pdb/rdi_from_pdb.c | 43 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 5f743620..fd1620bf 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -787,12 +787,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } // rjf: build line table, fill with parsed binary annotations - + if(inlinee_lines_parsed != 0) { // rjf: grab checksums sub-section CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; - + // rjf: gathered lines typedef struct LineChunk LineChunk; struct LineChunk @@ -810,12 +810,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) U32 last_file_off = max_U32; U32 curr_file_off = max_U32; RDIM_LineTable* line_table = 0; - + CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) { last_file_off = curr_file_off; @@ -829,7 +829,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) if((last_file_off != max_U32 && last_file_off != curr_file_off)) { String8 seq_file_name = {0}; - + if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off); @@ -901,7 +901,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) first_line_chunk = last_line_chunk = 0; total_line_chunk_line_count = 0; } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) { LineChunk *chunk = last_line_chunk; @@ -919,7 +919,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) chunk->count += 1; total_line_chunk_line_count += 1; } - + if(step.flags == 0) { break; @@ -2311,18 +2311,22 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) symbol->container_type = container_type; } }break; - + case CV_SymKind_UDT: { if(in->parsing_global_stream && top_scope_node == 0) { CV_SymUDT *udt = (CV_SymUDT *)sym_header_struct_base; String8 name = str8_cstring_capped(udt+1, sym_data_opl); - + RDIM_Type *type = rdim_type_chunk_list_push(arena, &typedefs, 4096); type->kind = RDI_TypeKind_Alias; type->name = name; type->direct_type = p2r_type_ptr_from_itype(udt->itype); + if(type->direct_type != 0) + { + type->byte_size = type->direct_type->byte_size; + } } }break; @@ -2884,14 +2888,14 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) { // rjf: build new range & add to scope RDIM_Rng1U64 voff_range = { step.range.min, step.range.max }; rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) { if(scope->voff_ranges.last != 0) @@ -2899,7 +2903,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) scope->voff_ranges.last->v.max = step.range.max; } } - + if(step.flags == 0) { break; @@ -2973,7 +2977,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) named_streams = pdb_named_stream_table_from_info(arena, info); MemoryCopyStruct(&auth_guid, &info->auth_guid); scratch_end(scratch); - + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); os_abort(1); @@ -3418,7 +3422,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 3: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, (U64)(itype_opl)); - + ////////////////////////// //- basic type aliases // @@ -3431,7 +3435,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); - + struct { char * name; @@ -3481,17 +3485,18 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 }, // always UTF-32 { "__pointer" , ptr_type , CV_BasicType_PTR } }; - + itype_type_ptrs[CV_BasicType_NOTYPE] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_NULL); itype_type_ptrs[CV_BasicType_HRESULT] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_HResult); itype_type_ptrs[CV_BasicType_VOID] = rdim_builtin_type_from_kind(all_types, RDI_TypeKind_Void); - + for(U64 i = 0; i < ArrayCount(table); i += 1) { RDIM_Type *builtin_alias = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); builtin_alias->kind = RDI_TypeKind_Alias; builtin_alias->name = str8_cstring(table[i].name); builtin_alias->direct_type = rdim_builtin_type_from_kind(all_types, table[i].kind_rdi); + builtin_alias->byte_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); itype_type_ptrs[table[i].kind_cv] = builtin_alias; } } @@ -3522,7 +3527,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { continue; } - + ////////////////////////// //- rjf: build basic type // @@ -4101,7 +4106,7 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in) local_state.arena = p2r_state->arena; local_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; local_state.work_thread_arenas = p2r_state->work_thread_arenas; - + P2R_Bake2Serialize *result = push_array(arena, P2R_Bake2Serialize, 1); result->bake_results = rdim_bake(&local_state, &in->bake_params); return result; From 5f3c2d6932369ed97b4ce3af8fafa4b2fb223a36 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 15:51:42 -0700 Subject: [PATCH 582/755] new/save user/project commands --- src/raddbg/generated/raddbg.meta.c | 18 +++++-- src/raddbg/generated/raddbg.meta.h | 6 ++- src/raddbg/raddbg.mdesk | 8 +++ src/raddbg/raddbg_core.c | 80 +++++++++++++++++++++++++++++- src/raddbg/raddbg_main.c | 28 +++++------ 5 files changed, 120 insertions(+), 20 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index ee791fa1..d234223e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[336] = +RD_VocabInfo rd_vocab_info_table[340] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -267,9 +267,13 @@ RD_VocabInfo rd_vocab_info_table[336] = {str8_lit_comp("go_to_disassembly"), str8_lit_comp(""), str8_lit_comp("Go To Disassembly"), str8_lit_comp(""), RD_IconKind_Glasses}, {str8_lit_comp("go_to_source"), str8_lit_comp(""), str8_lit_comp("Go To Source"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("set_file_replacement_path"), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("new_user"), str8_lit_comp(""), str8_lit_comp("New User"), str8_lit_comp(""), RD_IconKind_Add}, +{str8_lit_comp("new_project"), str8_lit_comp(""), str8_lit_comp("New Project"), str8_lit_comp(""), RD_IconKind_Add}, {str8_lit_comp("open_user"), str8_lit_comp(""), str8_lit_comp("Open User"), str8_lit_comp(""), RD_IconKind_Person}, {str8_lit_comp("open_project"), str8_lit_comp(""), str8_lit_comp("Open Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, {str8_lit_comp("open_recent_project"), str8_lit_comp(""), str8_lit_comp("Open Recent Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, +{str8_lit_comp("save_user"), str8_lit_comp(""), str8_lit_comp("Save User"), str8_lit_comp(""), RD_IconKind_Save}, +{str8_lit_comp("save_project"), str8_lit_comp(""), str8_lit_comp("Save Project"), str8_lit_comp(""), RD_IconKind_Save}, {str8_lit_comp("write_user_data"), str8_lit_comp(""), str8_lit_comp("Write User Data"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("write_project_data"), str8_lit_comp(""), str8_lit_comp("Write Project Data"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("user_settings"), str8_lit_comp(""), str8_lit_comp("User Settings"), str8_lit_comp(""), RD_IconKind_Gear}, @@ -475,7 +479,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[229] = +RD_CmdKindInfo rd_cmd_kind_info_table[233] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -575,9 +579,13 @@ RD_CmdKindInfo rd_cmd_kind_info_table[229] = { str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_user"), str8_lit_comp("Creates a new user file, and sets the current user path as that file's path."), str8_lit_comp("new,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("new_project"), str8_lit_comp("Creates a new project file, and sets the current project path as that file's path."), str8_lit_comp("new,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_projects"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_user"), str8_lit_comp("Saves user data to a file, and sets the current user path as that path."), str8_lit_comp("load,user,project,layout"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("save_project"), str8_lit_comp("Saves project data to a file, and sets the current project path as that path."), str8_lit_comp("project,project,session"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("user_settings"), str8_lit_comp("Opens user settings."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -708,7 +716,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[229] = { str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -754,8 +762,12 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[111] = {str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("switch"), {OS_Key_I, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_Modifier_Alt}}, +{str8_lit_comp("open_user"), {OS_Key_N, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("open_project"), {OS_Key_N, 0 |OS_Modifier_Ctrl |OS_Modifier_Alt}}, {str8_lit_comp("open_user"), {OS_Key_O, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("open_project"), {OS_Key_O, 0 |OS_Modifier_Ctrl |OS_Modifier_Alt}}, +{str8_lit_comp("save_user"), {OS_Key_S, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, +{str8_lit_comp("save_project"), {OS_Key_S, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("edit"), {OS_Key_F2, 0 }}, {str8_lit_comp("accept"), {OS_Key_Return, 0 }}, {str8_lit_comp("cancel"), {OS_Key_Esc, 0 }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 409be95b..5b204498 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -154,9 +154,13 @@ RD_CmdKind_ShowFileInExplorer, RD_CmdKind_GoToDisassembly, RD_CmdKind_GoToSource, RD_CmdKind_SetFileReplacementPath, +RD_CmdKind_NewUser, +RD_CmdKind_NewProject, RD_CmdKind_OpenUser, RD_CmdKind_OpenProject, RD_CmdKind_OpenRecentProject, +RD_CmdKind_SaveUser, +RD_CmdKind_SaveProject, RD_CmdKind_WriteUserData, RD_CmdKind_WriteProjectData, RD_CmdKind_UserSettings, @@ -562,7 +566,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[336]; +extern RD_VocabInfo rd_vocab_info_table[340]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 609c767f..b1e31d2e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -873,9 +873,13 @@ RD_CmdTable: // | | | | {SetFileReplacementPath 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_file_replacement_path" "Set File Replacement Path" "Sets the path which should be used as the replacement for the passed file." "" "" } //- rjf: setting config paths + {NewUser 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Add "new_user" "New User" "Creates a new user file, and sets the current user path as that file's path." "new,user,project,layout" "" } + {NewProject 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Add "new_project" "New Project" "Creates a new project file, and sets the current project path as that file's path." "new,user,project,layout" "" } {OpenUser 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" "" } {OpenProject 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" "" } {OpenRecentProject 1 1 0 0 "query:recent_projects" Cfg null RecentProject Null 0 0 0 0 0 1 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" "" } + {SaveUser 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_user" "Save User" "Saves user data to a file, and sets the current user path as that path." "load,user,project,layout" "" } + {SaveProject 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 Save "save_project" "Save Project" "Saves project data to a file, and sets the current project path as that path." "project,project,session" "" } //- rjf: writing config changes {WriteUserData 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" "" } @@ -1147,8 +1151,12 @@ RD_DefaultBindingTable: { "switch_to_partner_file" O 0 0 alt } //- rjf: setting config paths + { "open_user" N ctrl shift alt } + { "open_project" N ctrl 0 alt } { "open_user" O ctrl shift alt } { "open_project" O ctrl 0 alt } + { "save_user" S ctrl shift alt } + { "save_project" S ctrl shift 0 } //- rjf: meta controls { "edit" F2 0 0 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 23a08b54..3433b6b5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7251,10 +7251,14 @@ rd_window_frame(void) String8 cmds[] = { rd_cmd_kind_info_table[RD_CmdKind_Open].string, + rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, + rd_cmd_kind_info_table[RD_CmdKind_NewUser].string, + rd_cmd_kind_info_table[RD_CmdKind_NewProject].string, rd_cmd_kind_info_table[RD_CmdKind_OpenUser].string, rd_cmd_kind_info_table[RD_CmdKind_OpenProject].string, rd_cmd_kind_info_table[RD_CmdKind_OpenRecentProject].string, - rd_cmd_kind_info_table[RD_CmdKind_OpenPalette].string, + rd_cmd_kind_info_table[RD_CmdKind_SaveUser].string, + rd_cmd_kind_info_table[RD_CmdKind_SaveProject].string, rd_cmd_kind_info_table[RD_CmdKind_UserSettings].string, rd_cmd_kind_info_table[RD_CmdKind_ProjectSettings].string, rd_cmd_kind_info_table[RD_CmdKind_Exit].string, @@ -7262,10 +7266,14 @@ rd_window_frame(void) U32 codepoints[] = { 'o', + 'n', + 'w', + 'j', 'u', 'p', 'r', - 'n', + 's', + 'a', 'e', 't', 'x', @@ -12578,6 +12586,74 @@ rd_frame(void) } } }break; + case RD_CmdKind_NewUser: + case RD_CmdKind_NewProject: + { + String8 new_path = rd_regs()->file_path; + B32 file_will_be_overwritten = (os_properties_from_file_path(new_path).created != 0); + UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("new_config_overwrite_confirm")); + if(file_will_be_overwritten && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key)) + { + rd_state->popup_key = key; + rd_state->popup_active = 1; + arena_clear(rd_state->popup_arena); + MemoryZeroStruct(&rd_state->popup_cmds); + rd_state->popup_title = push_str8f(rd_state->popup_arena, "Are you sure you want to save to this path?"); + rd_state->popup_desc = push_str8f(rd_state->popup_arena, "The existing file at '%S' will be overwritten.", new_path); + RD_Regs *regs = rd_regs_copy(rd_frame_arena(), rd_regs()); + regs->force_confirm = 1; + rd_cmd_list_push_new(rd_state->popup_arena, &rd_state->popup_cmds, rd_cmd_kind_info_table[kind].string, regs); + } + else switch(kind) + { + default:{}break; + case RD_CmdKind_NewUser: + { + os_delete_file_at_path(new_path); + rd_cmd(RD_CmdKind_OpenUser, .file_path = new_path); + }break; + case RD_CmdKind_NewProject: + { + os_delete_file_at_path(new_path); + rd_cmd(RD_CmdKind_OpenProject, .file_path = new_path); + }break; + } + }break; + case RD_CmdKind_SaveUser: + case RD_CmdKind_SaveProject: + { + String8 new_path = rd_regs()->file_path; + B32 file_will_be_overwritten = (os_properties_from_file_path(new_path).created != 0); + UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("save_config_overwrite_confirm")); + if(file_will_be_overwritten && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key)) + { + rd_state->popup_key = key; + rd_state->popup_active = 1; + arena_clear(rd_state->popup_arena); + MemoryZeroStruct(&rd_state->popup_cmds); + rd_state->popup_title = push_str8f(rd_state->popup_arena, "Are you sure you want to save to this path?"); + rd_state->popup_desc = push_str8f(rd_state->popup_arena, "The existing file at '%S' will be overwritten.", new_path); + RD_Regs *regs = rd_regs_copy(rd_frame_arena(), rd_regs()); + regs->force_confirm = 1; + rd_cmd_list_push_new(rd_state->popup_arena, &rd_state->popup_cmds, rd_cmd_kind_info_table[kind].string, regs); + } + else switch(kind) + { + default:{}break; + case RD_CmdKind_SaveUser: + { + arena_clear(rd_state->user_path_arena); + rd_state->user_path = push_str8_copy(rd_state->user_path_arena, new_path); + rd_cmd(RD_CmdKind_WriteUserData); + }break; + case RD_CmdKind_SaveProject: + { + arena_clear(rd_state->project_path_arena); + rd_state->project_path = push_str8_copy(rd_state->project_path_arena, new_path); + rd_cmd(RD_CmdKind_WriteProjectData); + }break; + } + }break; //- rjf: writing config changes case RD_CmdKind_WriteUserData: dst_path = rd_state->user_path; bucket_name = str8_lit("user"); goto write; diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index bc5c04b3..5cf18237 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -197,24 +197,11 @@ // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // [ ] finish theme editing, build themes - replace code colors map with new theme stuff // +// [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... -// [ ] odin's demo is busted - need to revert PDB conversion type index changes. // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // -//- readme improvements -// [ ] I was a little confused about what a profile file was. I understood -// what the user file was, but the profile file sounded like it should -// perhaps be per-project, yet it sounded like it was meant to be somewhat -// global? I don't have any feedback here because it probably will make -// sense once I use the debugger more, but I just thought I'd make a note -// to say that I was confused about it after reading the manual, so -// perhaps you could elaborate a little more on it in there. -// [ ] It wasn't clear to me how you save a user or project file. I can see -// how to load them, but not how you save them. Obviously I can just copy -// the files myself in the shell, but it seemed weird that there was no -// "save" option in the menus. -// //- no immediate action but check before release: // [ ] user switching // [ ] project switching @@ -508,6 +495,19 @@ // [x] unattached process evaluation - need a string to evaluate so I can generate // the evals // [x] save-to-project (command line targets) +// [x] odin's demo is busted - need to revert PDB conversion type index changes. +//- readme improvements +// [x] I was a little confused about what a profile file was. I understood +// what the user file was, but the profile file sounded like it should +// perhaps be per-project, yet it sounded like it was meant to be somewhat +// global? I don't have any feedback here because it probably will make +// sense once I use the debugger more, but I just thought I'd make a note +// to say that I was confused about it after reading the manual, so +// perhaps you could elaborate a little more on it in there. +// [x] It wasn't clear to me how you save a user or project file. I can see +// how to load them, but not how you save them. Obviously I can just copy +// the files myself in the shell, but it seemed weird that there was no +// "save" option in the menus. //////////////////////////////// //~ rjf: Build Options From b2e24fe7602f458c89929e1de77aa0cc75359e18 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 15:56:28 -0700 Subject: [PATCH 583/755] do not synthesize simpler expression strings on unsuccessful evaluation --- src/raddbg/raddbg_views.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 91cdca2b..febbeab3 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1180,6 +1180,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { extra_flags &= ~RD_WatchCellFlag_Expr; } + if(row->eval.msgs.max_kind != E_MsgKind_Null) + { + extra_flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval; + } rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .flags = extra_flags|RD_WatchCellFlag_Button|RD_WatchCellFlag_Indented, .pct = 1.f); } @@ -1712,8 +1716,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla expr_string = cell->eval.string; // rjf: try to form a simpler expression string out of the expression tree itself, *if* this - // is not an editable expression - if(!(block_type->flags & E_TypeFlag_EditableChildren)) + // is not an editable expression, and if this evaluation was successful + if(!(block_type->flags & E_TypeFlag_EditableChildren) && cell->eval.msgs.max_kind == E_MsgKind_Null) { // rjf: first, locate a notable expression - we special-case things like member accesses // or array indices, so we should grab those if possible From afae94b49c7c4e19805a247ce7c927acad3804d5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 16:00:57 -0700 Subject: [PATCH 584/755] opaque backgrounds setting coverage --- src/raddbg/raddbg_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3433b6b5..06911dd7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9049,6 +9049,7 @@ rd_window_frame(void) F32 rounded_corner_amount = rd_setting_f32_from_name(str8_lit("rounded_corner_amount")); F32 border_softness = 1.f; B32 do_background_blur = rd_setting_b32_from_name(str8_lit("background_blur")); + B32 force_opaque_floating_backgrounds = rd_setting_b32_from_name(str8_lit("opaque_backgrounds")); B32 do_drop_shadows = rd_setting_b32_from_name(str8_lit("drop_shadows")); Vec4F32 base_background_color = ui_color_from_name(str8_lit("background")); @@ -9168,6 +9169,10 @@ rd_window_frame(void) // rjf: compute background color Vec4F32 box_background_color = box->background_color; + if(force_opaque_floating_backgrounds && box->flags & UI_BoxFlag_Floating && box->flags & UI_BoxFlag_DrawDropShadow) + { + box_background_color.w = 1.f; + } // rjf: draw background if(box->flags & UI_BoxFlag_DrawBackground) From e52ab7ad6bbda202376f51d200e6331a89ba6f65 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 16:30:31 -0700 Subject: [PATCH 585/755] garbage collect window states based on frame touch, and on cfg elimination --- src/raddbg/raddbg_core.c | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 06911dd7..26d48913 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10741,34 +10741,6 @@ rd_frame(void) } } - ////////////////////////////// - //- rjf: garbage collect untouched window states - // - if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) - { - for EachIndex(slot_idx, rd_state->window_state_slots_count) - { - for(RD_WindowState *ws = rd_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) - { - next = ws->hash_next; - if(ws->last_frame_index_touched+2 < rd_state->frame_index) - { - ui_state_release(ws->ui); - r_window_unequip(ws->os, ws->r); - os_window_close(ws->os); - arena_release(ws->drop_completion_arena); - arena_release(ws->query_arena); - arena_release(ws->hover_eval_arena); - arena_release(ws->autocomp_arena); - arena_release(ws->arena); - DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); - DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); - SLLStackPush_N(rd_state->free_window_state, ws, order_next); - } - } - } - } - ////////////////////////////// //- rjf: garbage collect untouched view states // @@ -16171,6 +16143,34 @@ rd_frame(void) } } + ////////////////////////////// + //- rjf: garbage collect untouched window states + // + { + for EachIndex(slot_idx, rd_state->window_state_slots_count) + { + for(RD_WindowState *ws = rd_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) + { + next = ws->hash_next; + RD_Cfg *cfg = rd_cfg_from_id(ws->cfg_id); + if(cfg == &rd_nil_cfg || ws->last_frame_index_touched < rd_state->frame_index) + { + ui_state_release(ws->ui); + r_window_unequip(ws->os, ws->r); + os_window_close(ws->os); + arena_release(ws->drop_completion_arena); + arena_release(ws->query_arena); + arena_release(ws->hover_eval_arena); + arena_release(ws->autocomp_arena); + arena_release(ws->arena); + DLLRemove_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); + DLLRemove_NP(rd_state->window_state_slots[slot_idx].first, rd_state->window_state_slots[slot_idx].last, ws, hash_next, hash_prev); + SLLStackPush_N(rd_state->free_window_state, ws, order_next); + } + } + } + } + ////////////////////////////// //- rjf: simulate lag // From 64010486fe7d3fc73c1659916218798787463c27 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 17:19:29 -0700 Subject: [PATCH 586/755] theme preset coverage --- src/raddbg/generated/raddbg.meta.c | 11 +- src/raddbg/generated/raddbg.meta.h | 7 +- src/raddbg/raddbg.mdesk | 160 ++++++++++++++++++++++++++++- src/raddbg/raddbg_core.c | 30 +++--- src/raddbg/raddbg_main.c | 6 +- 5 files changed, 190 insertions(+), 24 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index d234223e..8279b195 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -956,7 +956,7 @@ str8_lit_comp("code_line_numbers"), str8_lit_comp("code_line_numbers_selected"), }; -String8 rd_theme_preset_display_string_table[10] = +String8 rd_theme_preset_display_string_table[11] = { str8_lit_comp("Default (Dark)"), str8_lit_comp("Default (Light)"), @@ -965,12 +965,13 @@ str8_lit_comp("VS (Light)"), str8_lit_comp("Solarized (Dark)"), str8_lit_comp("Solarized (Light)"), str8_lit_comp("Handmade Hero"), +str8_lit_comp("Naysayer"), str8_lit_comp("4coder"), str8_lit_comp("Grove"), str8_lit_comp("Far Manager"), }; -String8 rd_theme_preset_code_string_table[10] = +String8 rd_theme_preset_code_string_table[11] = { str8_lit_comp("default_dark"), str8_lit_comp("default_light"), @@ -979,20 +980,22 @@ str8_lit_comp("vs_light"), str8_lit_comp("solarized_dark"), str8_lit_comp("solarized_light"), str8_lit_comp("handmade_hero"), +str8_lit_comp("naysayer"), str8_lit_comp("four_coder"), str8_lit_comp("grove"), str8_lit_comp("far_manager"), }; -String8 rd_theme_preset_cfg_string_table[10] = +String8 rd_theme_preset_cfg_string_table[11] = { str8_lit_comp("theme:\n{\n theme_color: {tags:\"background\", value: 0x1b1b1bff }\n theme_color: {tags:\"alt background\", value: 0x222222ff }\n theme_color: {tags:\"pop background\", value: 0x355b6eff }\n theme_color: {tags:\"fresh background\", value: 0x31393dff }\n theme_color: {tags:\"match background\", value: 0x31393dff }\n theme_color: {tags:\"border\", value: 0x404040ff }\n theme_color: {tags:\"text\", value: 0xe5e5e5ff }\n theme_color: {tags:\"weak text\", value: 0xa4a4a4ff }\n theme_color: {tags:\"good text\", value: 0x32a852ff }\n theme_color: {tags:\"neutral text\", value: 0x3a90bbff }\n theme_color: {tags:\"bad text\", value: 0xcf5242ff }\n theme_color: {tags:\"hover\", value: 0xffffffff }\n theme_color: {tags:\"focus overlay\", value: 0xfda20012 }\n theme_color: {tags:\"focus border\", value: 0xfda200ff }\n theme_color: {tags:\"cursor\", value: 0x8aff00ff }\n theme_color: {tags:\"selection\", value: 0x99ccff0f }\n theme_color: {tags:\"inactive background\", value: 0x0000002f }\n theme_color: {tags:\"drop_shadow\", value: 0x0000007f }\n theme_color: {tags:\"good_pop background\", value: 0x2c5b36ff }\n theme_color: {tags:\"good_pop border\", value: 0x568761ff }\n theme_color: {tags:\"good_pop hover\", value: 0xe3f5d3ff }\n theme_color: {tags:\"good_pop weak text\", value: 0xe3f5d3ff }\n theme_color: {tags:\"bad_pop background\", value: 0x803425ff }\n theme_color: {tags:\"bad_pop hover\", value: 0xff825cff }\n theme_color: {tags:\"code_default\", value: 0xcbcbcbff }\n theme_color: {tags:\"code_symbol\", value: 0x42a2cfff }\n theme_color: {tags:\"code_type\", value: 0xfec746ff }\n theme_color: {tags:\"code_local\", value: 0x98bc80ff }\n theme_color: {tags:\"code_register\", value: 0xb7afd5ff }\n theme_color: {tags:\"code_keyword\", value: 0xb38d4cff }\n theme_color: {tags:\"code_delimiter_or_operator\", value: 0x767676ff }\n theme_color: {tags:\"code_numeric\", value: 0x98abb1ff }\n theme_color: {tags:\"code_numeric_alt_digit_group\", value: 0x738287ff }\n theme_color: {tags:\"code_string\", value: 0x98abb1ff }\n theme_color: {tags:\"code_meta\", value: 0xd96759ff }\n theme_color: {tags:\"code_comment\", value: 0x717171ff }\n theme_color: {tags:\"line_info_0\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_1\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_2\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_3\", value: 0x36241fff }\n theme_color: {tags:\"line_info_4\", value: 0x4f3022ff }\n theme_color: {tags:\"line_info_5\", value: 0x4f3e15ff }\n theme_color: {tags:\"line_info_6\", value: 0x434e2aff }\n theme_color: {tags:\"line_info_7\", value: 0x36241fff }\n theme_color: {tags:\"thread_0\", value: 0xffcb7fff }\n theme_color: {tags:\"thread_1\", value: 0xb2ff65ff }\n theme_color: {tags:\"thread_2\", value: 0xff99e5ff }\n theme_color: {tags:\"thread_3\", value: 0x6598ffff }\n theme_color: {tags:\"thread_4\", value: 0x65ffcbff }\n theme_color: {tags:\"thread_5\", value: 0xff9819ff }\n theme_color: {tags:\"thread_6\", value: 0x9932ffff }\n theme_color: {tags:\"thread_7\", value: 0x65ff4cff }\n theme_color: {tags:\"thread_unwound\", value: 0xb2ccd8ff }\n theme_color: {tags:\"thread_error\", value: 0xb23219ff }\n theme_color: {tags:\"breakpoint\", value: 0xa72911ff }\n theme_color: {tags:\"floating background\", value: 0x1b1b1baf }\n theme_color: {tags:\"floating background alt\", value: 0x0000005f }\n theme_color: {tags:\"floating background fresh\", value: 0x31393d5f }\n theme_color: {tags:\"floating border\", value: 0xbfbfbf1f }\n theme_color: {tags:\"floating scroll_bar background\", value: 0x3b3b3b5f }\n theme_color: {tags:\"floating scroll_bar border\", value: 0x5f5f5f5f }\n theme_color: {tags:\"menu_bar background\", value: 0x2b3740ff }\n theme_color: {tags:\"menu_bar border\", value: 0x3e4c57ff }\n theme_color: {tags:\"scroll_bar background\", value: 0x2b2b2bff }\n theme_color: {tags:\"scroll_bar border\", value: 0x3f3f3fff }\n theme_color: {tags:\"implicit background\", value: 0x00000000 }\n theme_color: {tags:\"implicit border\", value: 0x00000000 }\n theme_color: {tags:\"hollow background\", value: 0x00000000 }\n theme_color: {tags:\"hollow border\", value: 0xffffff1f }\n theme_color: {tags:\"tab background\", value: 0x6f5135ff }\n theme_color: {tags:\"tab border\", value: 0x8a6e54ff }\n theme_color: {tags:\"tab inactive background\", value: 0x2b3740ff }\n theme_color: {tags:\"tab inactive border\", value: 0x3e4c57ff }\n theme_color: {tags:\"tab auto background\", value: 0x693847ff }\n theme_color: {tags:\"tab auto border\", value: 0x9e6274ff }\n theme_color: {tags:\"tab auto inactive background\", value: 0x2f2633ff }\n theme_color: {tags:\"tab auto inactive border\", value: 0x685073ff }\n theme_color: {tags:\"drop_site background\", value: 0xffffff05 }\n theme_color: {tags:\"drop_site border\", value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff }\n theme_color:{ tags: \"alt background\" , value: 0xf8f8f8ff }\n theme_color:{ tags: \"pop background\" , value: 0xcbe4f2ff }\n theme_color:{ tags: \"menu_bar pop background\" , value: 0x5aabd9ff }\n theme_color:{ tags: \"fresh background\" , value: 0xeaddceff }\n theme_color:{ tags: \"match background\" , value: 0xc1e9c4ff }\n theme_color:{ tags: border , value: 0xcbcbcbff }\n theme_color:{ tags: text , value: 0xff }\n theme_color:{ tags: \"weak text\" , value: 0x727272ff }\n theme_color:{ tags: \"good text\" , value: 0x217538ff }\n theme_color:{ tags: \"neutral text\" , value: 0x1a5b7cff }\n theme_color:{ tags: \"bad text\" , value: 0x972717ff }\n theme_color:{ tags: hover , value: 0xff }\n theme_color:{ tags: \"focus overlay\" , value: 0x67ff4b }\n theme_color:{ tags: \"focus border\" , value: 0x67ffff }\n theme_color:{ tags: cursor , value: 0xff }\n theme_color:{ tags: selection , value: 0x283d5166 }\n theme_color:{ tags: \"inactive background\" , value: 0x8 }\n theme_color:{ tags: drop_shadow , value: 0xb }\n theme_color:{ tags: \"good_pop background\" , value: 0x90c09aff }\n theme_color:{ tags: \"good_pop border\" , value: 0x1e7231ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0xa93620ff }\n theme_color:{ tags: \"bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar bad_pop background\" , value: 0xff2a00ff }\n theme_color:{ tags: \"menu_bar bad_pop text\" , value: 0xffffffff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0x80808ff }\n theme_color:{ tags: code_symbol , value: 0x4ac3ff }\n theme_color:{ tags: code_type , value: 0xf46200ff }\n theme_color:{ tags: code_local , value: 0x317c00ff }\n theme_color:{ tags: code_register , value: 0x9a00ffff }\n theme_color:{ tags: code_keyword , value: 0xff0600ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x8a8a8aff }\n theme_color:{ tags: code_numeric , value: 0x7d49ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0xb56aff }\n theme_color:{ tags: code_string , value: 0x63549fff }\n theme_color:{ tags: code_meta , value: 0xd96759ff }\n theme_color:{ tags: code_comment , value: 0x717171ff }\n theme_color:{ tags: line_info_0 , value: 0xe6d5cdff }\n theme_color:{ tags: line_info_1 , value: 0xdbcfb2ff }\n theme_color:{ tags: line_info_2 , value: 0xddeac1ff }\n theme_color:{ tags: line_info_3 , value: 0xddc4bdff }\n theme_color:{ tags: line_info_4 , value: 0xba917eff }\n theme_color:{ tags: thread_0 , value: 0xffa700ff }\n theme_color:{ tags: thread_1 , value: 0xb41fff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xff2800ff }\n theme_color:{ tags: \"floating background\" , value: 0xffffffc7 }\n theme_color:{ tags: \"floating background alt\" , value: 0x23 }\n theme_color:{ tags: \"floating background fresh\" , value: 0xeaddceff }\n theme_color:{ tags: \"floating border\" , value: 0x88888884 }\n theme_color:{ tags: \"scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0xe9e9e9ff }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x2b6b9aff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x4d }\n theme_color:{ tags: \"menu_bar text\" , value: 0xffffffff }\n theme_color:{ tags: \"menu_bar text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"good menu_bar text\" , value: 0x70db8dff }\n theme_color:{ tags: \"bad menu_bar text\" , value: 0xffa79bff }\n theme_color:{ tags: \"neutral menu_bar text\" , value: 0xc4dbe7ff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab text\" , value: 0xffffffff }\n theme_color:{ tags: \"tab text weak\" , value: 0xffffffff }\n theme_color:{ tags: \"tab background\" , value: 0xb67e48ff }\n theme_color:{ tags: \"tab border\" , value: 0x875b31ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0xcacacaff }\n theme_color:{ tags: \"tab inactive border\" , value: 0xb5b5b5ff }\n theme_color:{ tags: \"tab auto background\" , value: 0xc41c69ff }\n theme_color:{ tags: \"tab auto border\" , value: 0x981039ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x9b88a3ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x373737ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0xffffffff}\n theme_color:{tags: \"alt background\", value: 0xefefefff}\n theme_color:{tags: \"pop background\", value: 0xe3eaf2ff}\n theme_color:{tags: \"fresh background\", value: 0xeccbbeff}\n theme_color:{tags: \"match background\", value: 0xedcbf9ff}\n theme_color:{tags: border, value: 0xe7e7e7ff}\n theme_color:{tags: text, value: 0xff}\n theme_color:{tags: \"weak text\", value: 0x353535ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xa7ffff}\n theme_color:{tags: \"focus overlay\", value: 0x8eff3f}\n theme_color:{tags: \"focus border\", value: 0x8effff}\n theme_color:{tags: cursor, value: 0xff}\n theme_color:{tags: selection, value: 0x56aaff77}\n theme_color:{tags: \"inactive background\", value: 0x17}\n theme_color:{tags: drop_shadow, value: 0xe7b27}\n theme_color:{tags: \"good_pop background\", value: 0x21a43dff}\n theme_color:{tags: \"good_pop border\", value: 0x21a43dff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0xcb3f23ff}\n theme_color:{tags: \"bad_pop text\", value: 0xffcdc4ff}\n theme_color:{tags: \"bad_pop text weak\", value: 0xffcdc4ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0x000000ff}\n theme_color:{tags: code_symbol, value: 0x74531fff}\n theme_color:{tags: code_type, value: 0x2b91afff}\n theme_color:{tags: code_local, value: 0x1f377fff}\n theme_color:{tags: code_register, value: 0x8a1bffff}\n theme_color:{tags: code_keyword, value: 0x0000ffff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff}\n theme_color:{tags: code_numeric, value: 0xff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x1d1d1dff}\n theme_color:{tags: code_string, value: 0xa61515ff}\n theme_color:{tags: code_meta, value: 0x808080ff}\n theme_color:{tags: code_comment, value: 0x008000ff}\n theme_color:{tags: line_info_0, value: 0xb5d9c8ff}\n theme_color:{tags: line_info_1, value: 0xa9c1d0ff}\n theme_color:{tags: line_info_2, value: 0x99abc5ff}\n theme_color:{tags: line_info_3, value: 0xc6bcd5ff}\n theme_color:{tags: thread_0, value: 0xffb141ff}\n theme_color:{tags: thread_1, value: 0x66c407ff}\n theme_color:{tags: thread_unwound, value: 0x67b3d7ff}\n theme_color:{tags: thread_error, value: 0xff2900ff}\n theme_color:{tags: breakpoint, value: 0xff2800ff}\n theme_color:{tags: \"floating background\", value: 0xffffffff}\n theme_color:{tags: \"floating background alt\", value: 0x11}\n theme_color:{tags: \"floating background fresh\", value: 0xa0c2d318}\n theme_color:{tags: \"floating border\", value: 0x50}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x3b3b3b5f}\n theme_color:{tags: \"floating scroll_bar border\", value: 0x5f5f5f5f}\n theme_color:{tags: \"menu_bar background\", value: 0xccd5f0ff}\n theme_color:{tags: \"menu_bar border\", value: 0xbabdc3ff}\n theme_color:{tags: \"scroll_bar background\", value: 0xe4e4e4ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0xf5cc84ff}\n theme_color:{tags: \"tab border\", value: 0xae7718ff}\n theme_color:{tags: \"tab inactive background\", value: 0x3b4f81ff}\n theme_color:{tags: \"tab inactive text\", value: 0xffffffff}\n theme_color:{tags: \"tab inactive border\", value: 0x3b4f81ff}\n theme_color:{tags: \"tab auto background\", value: 0xe99595ff}\n theme_color:{tags: \"tab auto border\", value: 0xff6262ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0xac6060ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0xff6262ff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xa7ffff}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x002a35ff}\n theme_color:{tags: \"alt background\", value: 0x053542ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x65166ff}\n theme_color:{tags: text, value: 0xeee8d5ff}\n theme_color:{tags: \"weak text\", value: 0x93a1a1ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xca4b16ff}\n theme_color:{tags: \"focus overlay\", value: 0xca4b151f}\n theme_color:{tags: \"focus border\", value: 0xca4b16ff}\n theme_color:{tags: cursor, value: 0xca4b16ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x5f8700ff}\n theme_color:{tags: \"good_pop border\", value: 0x5f8700ff}\n theme_color:{tags: \"bad_pop background\", value: 0x810000ff}\n theme_color:{tags: code_default, value: 0x839496ff}\n theme_color:{tags: code_symbol, value: 0xb3880eff}\n theme_color:{tags: code_type, value: 0xb3880eff}\n theme_color:{tags: code_local, value: 0xeee8d5ff}\n theme_color:{tags: code_register, value: 0xeee8d5ff}\n theme_color:{tags: code_keyword, value: 0x849804ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff}\n theme_color:{tags: code_numeric, value: 0x2aa198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff}\n theme_color:{tags: code_string, value: 0x2aa198ff}\n theme_color:{tags: code_meta, value: 0xca4b16ff}\n theme_color:{tags: code_comment, value: 0x586e75ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x2a3574}\n theme_color:{tags: \"floating background alt\", value: 0x4f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x586e75ff}\n theme_color:{tags: \"tab border\", value: 0x90abb3ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x33494fff}\n theme_color:{tags: \"tab auto background\", value: 0x565ed2ff}\n theme_color:{tags: \"tab auto border\", value: 0xa2a6dfff}\n theme_color:{tags: \"tab auto inactive background\", value: 0}\n theme_color:{tags: \"tab auto inactive border\", value: 0x595fbcff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp(""), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x0c0c0cff}\n theme_color:{tags: \"alt background\", value: 0x161616ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x404040ff}\n theme_color:{tags: text, value: 0xcac1b6ff}\n theme_color:{tags: \"weak text\", value: 0xa08563ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0x7485971e}\n theme_color:{tags: \"focus border\", value: 0x5e6b79ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x2c5b36ff}\n theme_color:{tags: \"good_pop border\", value: 0x568761ff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0x803425ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0xa08563ff}\n theme_color:{tags: code_symbol, value: 0xcc5735ff}\n theme_color:{tags: code_type, value: 0xd8a51cff}\n theme_color:{tags: code_local, value: 0xd6b995ff}\n theme_color:{tags: code_register, value: 0xc04047ff}\n theme_color:{tags: code_keyword, value: 0xac7b0aff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x907553ff}\n theme_color:{tags: code_numeric, value: 0x6b8e23ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x4f681cff}\n theme_color:{tags: code_string, value: 0x6b8e23ff}\n theme_color:{tags: code_meta, value: 0xdab98fff}\n theme_color:{tags: code_comment, value: 0x686868ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x18181980}\n theme_color:{tags: \"floating background alt\", value: 0x0000005f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating border\", value: 0xbfbfbf1f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x3b3b3b5f}\n theme_color:{tags: \"floating scroll_bar border\", value: 0x5f5f5f5f}\n theme_color:{tags: \"menu_bar background\", value: 0x1f1f27ff}\n theme_color:{tags: \"menu_bar border\", value: 0x3d3d47ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x2b2b2bff}\n theme_color:{tags: \"scroll_bar border\", value: 0x3f3f3fff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab border\", value: 0x3d3d47ff}\n theme_color:{tags: \"tab text\", value: 0xca9301ff}\n theme_color:{tags: \"tab text weak\", value: 0x8c690eff}\n theme_color:{tags: \"tab inactive background\", value: 0x171718ff}\n theme_color:{tags: \"tab inactive border\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab auto background\", value: 0x243b38ff}\n theme_color:{tags: \"tab auto border\", value: 0x478980ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x102623ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x1e5850ff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x042327ff}\n theme_color:{tags: \"alt background\", value: 0x11b1fff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"pop text\", value: 0xbad7e6ff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x334d50ff}\n theme_color:{tags: text, value: 0xdad3beff}\n theme_color:{tags: \"weak text\", value: 0xb0a688ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: \"menu_bar good text\", value: 0x2a8242ff}\n theme_color:{tags: \"menu_bar neutral text\", value: 0x5681ff}\n theme_color:{tags: \"menu_bar bad text\", value: 0xa21200ff}\n theme_color:{tags: \"menu_bar weak text\", value: 0x313131ff}\n theme_color:{tags: \"menu_bar bad_pop text weak\", value: 0xffffffff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0x86e08e20}\n theme_color:{tags: \"focus border\", value: 0x86e08fff}\n theme_color:{tags: cursor, value: 0x86e08fff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x2c5b36ff}\n theme_color:{tags: \"good_pop border\", value: 0x568761ff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0x803425ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0xbdb395ff}\n theme_color:{tags: code_symbol, value: 0xcbe0f5ff}\n theme_color:{tags: code_type, value: 0xcbe0f5ff}\n theme_color:{tags: code_local, value: 0xd9cfb3ff}\n theme_color:{tags: code_register, value: 0xb7afd5ff}\n theme_color:{tags: code_keyword, value: 0x9de3c0ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff}\n theme_color:{tags: code_numeric, value: 0x2ca198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x217770ff}\n theme_color:{tags: code_string, value: 0x2ca198ff}\n theme_color:{tags: code_meta, value: 0xB0FFB0ff}\n theme_color:{tags: code_comment, value: 0x31b72cff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x3232792}\n theme_color:{tags: \"floating background alt\", value: 0x0000005f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0xe363bff}\n theme_color:{tags: \"menu_bar background\", value: 0xb59e7aff}\n theme_color:{tags: \"menu_bar text\", value: 0xff}\n theme_color:{tags: \"menu_bar border\", value: 0x947d5aff}\n theme_color:{tags: \"scroll_bar background\", value: 0xe363bff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x13533aff}\n theme_color:{tags: \"tab border\", value: 0x6c9182ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x947d5a6c}\n theme_color:{tags: \"tab auto background\", value: 0x5b3939ff}\n theme_color:{tags: \"tab auto border\", value: 0x875c5cff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x251b1bff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x563d3dff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background,value: 0xc0c0cff}\n theme_color:{tags: \"alt background\", value: 0x131313ff}\n theme_color:{tags: \"pop background\", value: 0x4c00ff}\n theme_color:{tags: \"fresh background\", value: 0x4c00ff}\n theme_color:{tags: \"match background\", value: 0x4c00ff}\n theme_color:{tags: border, value: 0x272727ff}\n theme_color:{tags: text, value: 0x90b080ff}\n theme_color:{tags: \"weak text\", value: 0x6b845fff}\n theme_color:{tags: \"menu_bar background\", value: 0x888888ff}\n theme_color:{tags: \"menu_bar text\", value: 0x20202ff}\n theme_color:{tags: \"menu_bar text weak\", value: 0x525252ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xee00ff}\n theme_color:{tags: \"focus overlay\", value: 0xee0012}\n theme_color:{tags: \"focus border\", value: 0x00ee00ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x4900ff}\n theme_color:{tags: \"good_pop border\", value: 0x4900ff}\n theme_color:{tags: \"bad_pop background\", value: 0x430b00ff}\n theme_color:{tags: code_default, value: 0x90b080ff}\n theme_color:{tags: code_symbol, value: 0xbfd9b2ff}\n theme_color:{tags: code_type, value: 0xbfd9b2ff}\n theme_color:{tags: code_local, value: 0xbfd9b2ff}\n theme_color:{tags: code_register, value: 0xb84cffff}\n theme_color:{tags: code_keyword, value: 0xd08f1fff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff}\n theme_color:{tags: code_numeric, value: 0x50ff2fff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff}\n theme_color:{tags: code_string, value: 0x50ff2fff}\n theme_color:{tags: code_meta, value: 0x90b080ff}\n theme_color:{tags: code_comment, value: 0x1f90f0ff}\n theme_color:{tags: line_info_0, value: 0xa253dff}\n theme_color:{tags: line_info_1, value: 0x9103dff}\n theme_color:{tags: line_info_2, value: 0x1e083dff}\n theme_color:{tags: line_info_3, value: 0x1e083dff}\n theme_color:{tags: thread_0, value: 0xd08f1fff}\n theme_color:{tags: thread_1, value: 0x1ea5d0ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x1d1d1dff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x15490cff}\n theme_color:{tags: \"tab border\", value: 0x15490cff}\n theme_color:{tags: \"tab text\", value: 0x90b080ff}\n theme_color:{tags: \"tab text weak\", value: 0x90b080ff}\n theme_color:{tags: \"tab inactive background\", value: 0x21321eff}\n theme_color:{tags: \"tab inactive border\", value: 0x21321eff}\n theme_color:{tags: \"tab auto background\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto border\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x47382eff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x47382eff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" , value: 0x232929ff }\n theme_color:{ tags: \"pop background\" , value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x485347ff }\n theme_color:{ tags: text , value: 0xffffffff }\n theme_color:{ tags: \"weak text\" , value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" , value: 0xfda200ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0 }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xad8b69ff }\n theme_color:{ tags: code_symbol , value: 0x87ad6aff }\n theme_color:{ tags: code_type , value: 0xb67474ff }\n theme_color:{ tags: code_local , value: 0xe9bf95ff }\n theme_color:{ tags: code_register , value: 0xa688b2ff }\n theme_color:{ tags: code_keyword , value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff }\n theme_color:{ tags: code_numeric , value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff }\n theme_color:{ tags: code_string , value: 0x98b19eff }\n theme_color:{ tags: code_meta , value: 0xad5979ff }\n theme_color:{ tags: code_comment , value: 0x52675dff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffc258ff }\n theme_color:{ tags: thread_1 , value: 0x82d331ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" , value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp(""), diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 5b204498..1f829d00 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -401,6 +401,7 @@ RD_ThemePreset_VSLight, RD_ThemePreset_SolarizedDark, RD_ThemePreset_SolarizedLight, RD_ThemePreset_HandmadeHero, +RD_ThemePreset_Naysayer, RD_ThemePreset_FourCoder, RD_ThemePreset_Grove, RD_ThemePreset_FarManager, @@ -573,9 +574,9 @@ extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; extern String8 rd_code_color_slot_name_table[14]; -extern String8 rd_theme_preset_display_string_table[10]; -extern String8 rd_theme_preset_code_string_table[10]; -extern String8 rd_theme_preset_cfg_string_table[10]; +extern String8 rd_theme_preset_display_string_table[11]; +extern String8 rd_theme_preset_code_string_table[11]; +extern String8 rd_theme_preset_cfg_string_table[11]; read_only global U8 rd_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x43,0x62,0x25,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0xa3,0x60,0xa4,0x23,0x00,0x00,0x01,0xb0,0x00,0x00,0x06,0x12,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b1e31d2e..a27ac50d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1650,7 +1650,84 @@ RD_ThemePresetTable: } //- rjf: to-do - { VSLight vs_light "VS (Light)" } + { VSLight vs_light "VS (Light)", + ```theme: + { + theme_color:{tags: background, value: 0xffffffff} + theme_color:{tags: "alt background", value: 0xefefefff} + theme_color:{tags: "pop background", value: 0xe3eaf2ff} + theme_color:{tags: "fresh background", value: 0xeccbbeff} + theme_color:{tags: "match background", value: 0xedcbf9ff} + theme_color:{tags: border, value: 0xe7e7e7ff} + theme_color:{tags: text, value: 0xff} + theme_color:{tags: "weak text", value: 0x353535ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: hover, value: 0xa7ffff} + theme_color:{tags: "focus overlay", value: 0x8eff3f} + theme_color:{tags: "focus border", value: 0x8effff} + theme_color:{tags: cursor, value: 0xff} + theme_color:{tags: selection, value: 0x56aaff77} + theme_color:{tags: "inactive background", value: 0x17} + theme_color:{tags: drop_shadow, value: 0xe7b27} + theme_color:{tags: "good_pop background", value: 0x21a43dff} + theme_color:{tags: "good_pop border", value: 0x21a43dff} + theme_color:{tags: "good_pop hover", value: 0xe3f5d3ff} + theme_color:{tags: "good_pop weak text", value: 0xe3f5d3ff} + theme_color:{tags: "good_pop text", value: 0xe3f5d3ff} + theme_color:{tags: "bad_pop background", value: 0xcb3f23ff} + theme_color:{tags: "bad_pop text", value: 0xffcdc4ff} + theme_color:{tags: "bad_pop text weak", value: 0xffcdc4ff} + theme_color:{tags: "bad_pop hover", value: 0xff825cff} + theme_color:{tags: code_default, value: 0x000000ff} + theme_color:{tags: code_symbol, value: 0x74531fff} + theme_color:{tags: code_type, value: 0x2b91afff} + theme_color:{tags: code_local, value: 0x1f377fff} + theme_color:{tags: code_register, value: 0x8a1bffff} + theme_color:{tags: code_keyword, value: 0x0000ffff} + theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff} + theme_color:{tags: code_numeric, value: 0xff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x1d1d1dff} + theme_color:{tags: code_string, value: 0xa61515ff} + theme_color:{tags: code_meta, value: 0x808080ff} + theme_color:{tags: code_comment, value: 0x008000ff} + theme_color:{tags: line_info_0, value: 0xb5d9c8ff} + theme_color:{tags: line_info_1, value: 0xa9c1d0ff} + theme_color:{tags: line_info_2, value: 0x99abc5ff} + theme_color:{tags: line_info_3, value: 0xc6bcd5ff} + theme_color:{tags: thread_0, value: 0xffb141ff} + theme_color:{tags: thread_1, value: 0x66c407ff} + theme_color:{tags: thread_unwound, value: 0x67b3d7ff} + theme_color:{tags: thread_error, value: 0xff2900ff} + theme_color:{tags: breakpoint, value: 0xff2800ff} + theme_color:{tags: "floating background", value: 0xffffffff} + theme_color:{tags: "floating background alt", value: 0x11} + theme_color:{tags: "floating background fresh", value: 0xa0c2d318} + theme_color:{tags: "floating border", value: 0x50} + theme_color:{tags: "floating scroll_bar background", value: 0x3b3b3b5f} + theme_color:{tags: "floating scroll_bar border", value: 0x5f5f5f5f} + theme_color:{tags: "menu_bar background", value: 0xccd5f0ff} + theme_color:{tags: "menu_bar border", value: 0xbabdc3ff} + theme_color:{tags: "scroll_bar background", value: 0xe4e4e4ff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0xf5cc84ff} + theme_color:{tags: "tab border", value: 0xae7718ff} + theme_color:{tags: "tab inactive background", value: 0x3b4f81ff} + theme_color:{tags: "tab inactive text", value: 0xffffffff} + theme_color:{tags: "tab inactive border", value: 0x3b4f81ff} + theme_color:{tags: "tab auto background", value: 0xe99595ff} + theme_color:{tags: "tab auto border", value: 0xff6262ff} + theme_color:{tags: "tab auto inactive background", value: 0xac6060ff} + theme_color:{tags: "tab auto inactive border", value: 0xff6262ff} + theme_color:{tags: "drop_site background", value: 0xffffff05} + theme_color:{tags: "drop_site border", value: 0xa7ffff} + } + ``` + } //- rjf: solarized (dark) theme { SolarizedDark solarized_dark "Solarized (Dark)", @@ -1803,6 +1880,87 @@ RD_ThemePresetTable: ``` } + //- rjf: naysayer + { Naysayer naysayer "Naysayer", + ```theme: + { + theme_color:{tags: background, value: 0x042327ff} + theme_color:{tags: "alt background", value: 0x11b1fff} + theme_color:{tags: "pop background", value: 0x355b6eff} + theme_color:{tags: "pop text", value: 0xbad7e6ff} + theme_color:{tags: "fresh background", value: 0x31393dff} + theme_color:{tags: "match background", value: 0x31393dff} + theme_color:{tags: border, value: 0x334d50ff} + theme_color:{tags: text, value: 0xdad3beff} + theme_color:{tags: "weak text", value: 0xb0a688ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: "menu_bar good text", value: 0x2a8242ff} + theme_color:{tags: "menu_bar neutral text", value: 0x5681ff} + theme_color:{tags: "menu_bar bad text", value: 0xa21200ff} + theme_color:{tags: "menu_bar weak text", value: 0x313131ff} + theme_color:{tags: "menu_bar bad_pop text weak", value: 0xffffffff} + theme_color:{tags: hover, value: 0xffffffff} + theme_color:{tags: "focus overlay", value: 0x86e08e20} + theme_color:{tags: "focus border", value: 0x86e08fff} + theme_color:{tags: cursor, value: 0x86e08fff} + theme_color:{tags: selection, value: 0x99ccff0f} + theme_color:{tags: "inactive background", value: 0x0000002f} + theme_color:{tags: drop_shadow, value: 0x0000007f} + theme_color:{tags: "good_pop background", value: 0x2c5b36ff} + theme_color:{tags: "good_pop border", value: 0x568761ff} + theme_color:{tags: "good_pop hover", value: 0xe3f5d3ff} + theme_color:{tags: "good_pop weak text", value: 0xe3f5d3ff} + theme_color:{tags: "bad_pop background", value: 0x803425ff} + theme_color:{tags: "bad_pop hover", value: 0xff825cff} + theme_color:{tags: code_default, value: 0xbdb395ff} + theme_color:{tags: code_symbol, value: 0xcbe0f5ff} + theme_color:{tags: code_type, value: 0xcbe0f5ff} + theme_color:{tags: code_local, value: 0xd9cfb3ff} + theme_color:{tags: code_register, value: 0xb7afd5ff} + theme_color:{tags: code_keyword, value: 0x9de3c0ff} + theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff} + theme_color:{tags: code_numeric, value: 0x2ca198ff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x217770ff} + theme_color:{tags: code_string, value: 0x2ca198ff} + theme_color:{tags: code_meta, value: 0xB0FFB0ff} + theme_color:{tags: code_comment, value: 0x31b72cff} + theme_color:{tags: line_info_0, value: 0x4f3022ff} + theme_color:{tags: line_info_1, value: 0x4f3e15ff} + theme_color:{tags: line_info_2, value: 0x434e2aff} + theme_color:{tags: line_info_3, value: 0x36241fff} + theme_color:{tags: thread_0, value: 0xffcb7fff} + theme_color:{tags: thread_1, value: 0xb2ff65ff} + theme_color:{tags: thread_unwound, value: 0xb2ccd8ff} + theme_color:{tags: thread_error, value: 0xb23219ff} + theme_color:{tags: breakpoint, value: 0xa72911ff} + theme_color:{tags: "floating background", value: 0x3232792} + theme_color:{tags: "floating background alt", value: 0x0000005f} + theme_color:{tags: "floating background fresh", value: 0x31393d5f} + theme_color:{tags: "floating scroll_bar background", value: 0xe363bff} + theme_color:{tags: "menu_bar background", value: 0xb59e7aff} + theme_color:{tags: "menu_bar text", value: 0xff} + theme_color:{tags: "menu_bar border", value: 0x947d5aff} + theme_color:{tags: "scroll_bar background", value: 0xe363bff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0x13533aff} + theme_color:{tags: "tab border", value: 0x6c9182ff} + theme_color:{tags: "tab inactive background", value: 0x0} + theme_color:{tags: "tab inactive border", value: 0x947d5a6c} + theme_color:{tags: "tab auto background", value: 0x5b3939ff} + theme_color:{tags: "tab auto border", value: 0x875c5cff} + theme_color:{tags: "tab auto inactive background", value: 0x251b1bff} + theme_color:{tags: "tab auto inactive border", value: 0x563d3dff} + theme_color:{tags: "drop_site background", value: 0xffffff05} + theme_color:{tags: "drop_site border", value: 0xffffff0f} + } + ``` + } + //- rjf: 4coder theme { FourCoder four_coder "4coder", ```theme: diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 26d48913..5219faf5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8631,14 +8631,17 @@ rd_window_frame(void) { continue; } - TabTask *t = push_array(scratch.arena, TabTask, 1); - t->tab = tab; - t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); - F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; - tab_width_target = Min(max_tab_width_px, tab_width_target); - t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0)); - SLLQueuePush(first_tab_task, last_tab_task, t); - tab_task_count += 1; + UI_TagF(tab != panel->selected_tab ? "inactive" : "") + { + TabTask *t = push_array(scratch.arena, TabTask, 1); + t->tab = tab; + t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); + F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + tab_width_target = Min(max_tab_width_px, tab_width_target); + t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0)); + SLLQueuePush(first_tab_task, last_tab_task, t); + tab_task_count += 1; + } } } @@ -14892,12 +14895,15 @@ rd_frame(void) String8 data = str8_list_join(scratch.arena, &strings, 0); if(os_write_data_to_file_path(dst_path, data)) { - for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + if(kind == RD_CmdKind_SaveAndSetTheme) { - rd_cfg_release(n->v); + for(RD_CfgNode *n = colors.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); + rd_cfg_new_replace(theme, name); } - RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme")); - rd_cfg_new_replace(theme, name); } else { diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 5cf18237..de9b6d3a 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -201,10 +201,6 @@ // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) -// -//- no immediate action but check before release: -// [ ] user switching -// [ ] project switching //////////////////////////////// //~ rjf: post-0.9.16 TODO notes @@ -508,6 +504,8 @@ // how to load them, but not how you save them. Obviously I can just copy // the files myself in the shell, but it seemed weird that there was no // "save" option in the menus. +// [x] user switching +// [x] project switching //////////////////////////////// //~ rjf: Build Options From 241d2454be8487effaee8db79ee5692e5e6747af Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 20:01:44 -0700 Subject: [PATCH 587/755] stop funnelling autocompletion through via events - it is not an event-like thing, and making it one led to weirdness... --- src/raddbg/raddbg_core.c | 49 +++++++++---------------------------- src/raddbg/raddbg_main.c | 1 + src/raddbg/raddbg_widgets.c | 8 +----- src/ui/ui_core.c | 22 +++++++++++++++++ src/ui/ui_core.h | 7 +++++- 5 files changed, 41 insertions(+), 46 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5219faf5..f514c9d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2973,17 +2973,7 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: determine autocompletion string // - String8 autocomplete_hint_string = {0}; - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - autocomplete_hint_string = evt->string; - break; - } - } - } + String8 autocomplete_hint_string = ui_autocomplete_string(); ////////////////////////////// //- rjf: process commands @@ -3016,7 +3006,6 @@ rd_view_ui(Rng2F32 rect) B32 state_dirty = 1; B32 snap_to_cursor = 0; B32 cursor_dirty__tbl = 0; - B32 take_autocomplete = 0; for(UI_Event *event = 0;;) { ////////////////////////// @@ -3584,15 +3573,15 @@ rd_view_ui(Rng2F32 rect) // rjf: any valid *additive* op & autocomplete hint? -> perform autocomplete first, then re-compute op if(!(evt->flags & UI_EventFlag_Delete) && autocomplete_hint_string.size != 0) { - take_autocomplete = 1; + String8 autocomplete_string = ui_autocomplete(); RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); RD_AutocompCursorInfo *autocomp_cursor_info = &ws->autocomp_cursor_info; - String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_hint_string); + String8 new_string = ui_push_string_replace_range(scratch.arena, string, r1s64(autocomp_cursor_info->replaced_range.min+1, autocomp_cursor_info->replaced_range.max+1), autocomplete_string); new_string.size = Min(sizeof(edit_state->input_buffer), new_string.size); MemoryCopy(edit_state->input_buffer, new_string.str, new_string.size); edit_state->input_size = new_string.size; - edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_hint_string.size); + edit_state->cursor = edit_state->mark = txt_pt(1, 1+autocomp_cursor_info->replaced_range.min+autocomplete_string.size); string = str8(edit_state->input_buffer, edit_state->input_size); op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); } @@ -4026,17 +4015,6 @@ rd_view_ui(Rng2F32 rect) ui_eat_event(evt); } } - if(take_autocomplete) - { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - ui_eat_event(evt); - break; - } - } - } } ////////////////////////////// @@ -4055,12 +4033,7 @@ rd_view_ui(Rng2F32 rect) String8 string = dr_string_from_fstrs(ui_build_arena(), &cell_info.eval_fstrs); if(string.size != 0) { - UI_Event evt = zero_struct; - { - evt.kind = UI_EventKind_AutocompleteHint; - evt.string = string; - } - ui_event_list_push(ui_build_arena(), ui_state->events, &evt); + ui_set_autocomplete_string(string); } } } @@ -5115,7 +5088,10 @@ rd_view_ui(Rng2F32 rect) else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { ewv->next_cursor = ewv->next_mark = cell_pt; - rd_cmd(RD_CmdKind_Accept); + if(!row_is_expandable) + { + rd_cmd(RD_CmdKind_Accept); + } rd_cmd(RD_CmdKind_Edit); } @@ -7121,17 +7097,14 @@ rd_window_frame(void) //- rjf: autocompletion view early-closing rules if(autocomp_floating_view_task) { - B32 has_autocomplete_hint = 0; + B32 has_autocomplete_hint = ui_autocomplete_string().size != 0; B32 has_accept_operation = 0; for(UI_Event *evt = 0; ui_next_event(&evt);) { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - has_autocomplete_hint = 1; - } if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept) { has_accept_operation = 1; + break; } } if(has_autocomplete_hint && has_accept_operation) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index de9b6d3a..6a38b838 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -201,6 +201,7 @@ // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) +// [ ] do not apply filters past one block layer //////////////////////////////// //~ rjf: post-0.9.16 TODO notes diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index fca267bd..42fb811e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3221,13 +3221,7 @@ rd_cell(RD_CellParams *params, String8 string) String8 autocomplete_hint_string = {0}; if(is_focus_active) { - for(UI_Event *evt = 0; ui_next_event(&evt);) - { - if(evt->kind == UI_EventKind_AutocompleteHint) - { - autocomplete_hint_string = evt->string; - } - } + autocomplete_hint_string = ui_autocomplete_string(); } ////////////////////////////// diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index f6e8c5e6..116a50f1 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -678,6 +678,28 @@ ui_slot_press(UI_EventActionSlot slot) return result; } +//- rjf: autocomplete info + +internal void +ui_set_autocomplete_string(String8 string) +{ + ui_state->autocomplete_string = push_str8_copy(ui_build_arena(), string); +} + +internal String8 +ui_autocomplete_string(void) +{ + return ui_state->autocomplete_string; +} + +internal String8 +ui_autocomplete(void) +{ + String8 result = ui_state->autocomplete_string; + MemoryZeroStruct(&ui_state->autocomplete_string); + return result; +} + //- rjf: drag data internal Vec2F32 diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index cfc7c328..599f1246 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -92,7 +92,6 @@ typedef enum UI_EventKind UI_EventKind_Edit, UI_EventKind_MouseMove, UI_EventKind_Scroll, - UI_EventKind_AutocompleteHint, UI_EventKind_FileDrop, UI_EventKind_COUNT } @@ -680,6 +679,7 @@ struct UI_State //- rjf: build state machine state B32 is_in_open_ctx_menu; + String8 autocomplete_string; B32 tooltip_can_overflow_window; UI_Key tooltip_anchor_key; String8Array current_gen_tags; @@ -848,6 +848,11 @@ internal B32 ui_key_release(OS_Modifiers mods, OS_Key key); internal B32 ui_text(U32 character); internal B32 ui_slot_press(UI_EventActionSlot slot); +//- rjf: autocomplete info +internal void ui_set_autocomplete_string(String8 string); +internal String8 ui_autocomplete_string(void); +internal String8 ui_autocomplete(void); + //- rjf: drag data internal Vec2F32 ui_drag_start_mouse(void); internal Vec2F32 ui_drag_delta(void); From 0e1599c5543e07c5a662ccc898287f7c3c46fc3f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 20:14:31 -0700 Subject: [PATCH 588/755] constrain queries to window --- src/raddbg/raddbg_core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f514c9d8..c7952ef6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6624,6 +6624,7 @@ rd_window_frame(void) Rng2F32 rect; B32 is_focused; B32 is_anchored; + B32 force_inside_window; B32 only_secondary_navigation; B32 reset_open; UI_Signal signal; // NOTE(rjf): output, from build @@ -6955,6 +6956,7 @@ rd_window_frame(void) t->is_focused = 1; t->is_anchored = query_is_anchored; t->reset_open = reset_open; + t->force_inside_window = 1; } } } @@ -6979,6 +6981,17 @@ rd_window_frame(void) B32 only_secondary_navigation = t->only_secondary_navigation; F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate, .reset = t->reset_open, .initial = 0.f); + // rjf: force rect inside window if needed + if(t->force_inside_window) + { + Rng2F32 window_rect = os_client_rect_from_window(ws->os); + Vec2F32 max_delta = sub_2f32(rect.p1, window_rect.p1); + Vec2F32 min_delta = sub_2f32(window_rect.p0, rect.p0); + Vec2F32 total_delta = v2f32(Max(min_delta.x, 0) - Max(max_delta.x, 0), + Max(min_delta.y, 0) - Max(max_delta.y, 0)); + rect = shift_2f32(rect, total_delta); + } + // rjf: push view regs rd_push_regs(); { From 0594d99c8d7dac9be78c265a87c7b1d0f9ef187e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 20:45:17 -0700 Subject: [PATCH 589/755] clean up status bar rendering, collapse ui for rebinding/run-status/errors/conversions --- src/raddbg/raddbg_core.c | 172 ++++++++++++++++++++---------------- src/raddbg/raddbg_widgets.c | 4 +- 2 files changed, 100 insertions(+), 76 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c7952ef6..9e32b531 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7549,36 +7549,6 @@ rd_window_frame(void) } } } - - ui_spacer(ui_em(0.75f, 1)); - - // rjf: conversion task visualization - UI_PrefWidth(ui_text_dim(10, 1)) UI_HeightFill UI_TagF("pop") - { - Temp scratch = scratch_begin(0, 0); - RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); - for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) - { - RD_Cfg *task = n->v; - F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f); - if(task_t > 0.5f) - { - String8 rdi_path = task->first->string; - String8 rdi_name = str8_skip_last_slash(rdi_path); - String8 task_text = push_str8f(scratch.arena, "Creating %S...", rdi_name); - UI_Key key = ui_key_from_stringf(ui_key_zero(), "task_%p", task); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawText|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, key); - os_window_push_custom_title_bar_client_area(ws->os, box->rect); - UI_Signal sig = ui_signal_from_box(box); - if(ui_hovering(sig)) UI_Tooltip - { - ui_label(rdi_path); - } - ui_box_equip_display_string(box, task_text); - } - } - scratch_end(scratch); - } } } } @@ -7768,10 +7738,31 @@ rd_window_frame(void) // ProfScope("build bottom bar") { + //- rjf: unpack status info B32 is_running = d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < d_frame_index(); CTRL_Event stop_event = d_ctrl_last_stop_event(); String8 tag = str8_lit("pop"); - if(!is_running) + RD_CfgList tasks = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("conversion_task")); + RD_CfgList long_running_tasks = {0}; + F32 alive_t_rate = 1 - pow_f32(2, (-5.f * rd_state->frame_dt)); + for(RD_CfgNode *n = tasks.first; n != 0; n = n->next) + { + RD_Cfg *task = n->v; + F32 task_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "task_anim_%I64u", task->id), 1.f, .rate = alive_t_rate); + if(task_t > 0.5f) + { + rd_cfg_list_push(scratch.arena, &long_running_tasks, task); + } + } + if(rd_state->bind_change_active) + { + tag = str8_lit("pop"); + } + else if(ws->error_t >= 0.01f && ws->error_string_size != 0) + { + tag = str8_lit("bad_pop"); + } + else if(!is_running) { switch(stop_event.cause) { @@ -7789,11 +7780,65 @@ rd_window_frame(void) }break; } } + + //- rjf: compute fstrs for status explanation + DR_FStrList status_fstrs = {0}; + { + if(rd_state->bind_change_active) + { + RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); + String8 display_name = rd_display_from_code_name(info->string); + String8 string = push_str8f(scratch.arena, "Currently rebinding \"%S\"", display_name); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, string); + } + else if(ws->error_t >= 0.01f && ws->error_string_size != 0) + { + String8 error_string = str8(ws->error_buffer, ws->error_string_size); + ws->error_t -= rd_state->frame_dt/8.f; + rd_request_frame(); + ui_set_next_pref_width(ui_children_sum(1)); + UI_CornerRadius(4) + UI_Row + UI_PrefWidth(ui_text_dim(10, 1)) + UI_TextAlignment(UI_TextAlign_Center) + { + DR_FStrList error_fstrs = rd_fstrs_from_rich_string(scratch.arena, error_string); + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, str8_lit(" ")); + dr_fstrs_concat_in_place(&status_fstrs, &error_fstrs); + } + } + else if(is_running) + { + DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_Play], + .font = rd_font_from_slot(RD_FontSlot_Icons), + .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, str8_lit(" Running...")); + if(long_running_tasks.count != 0) + { + String8 string = push_str8f(scratch.arena, " Loading %I64u debug information file%s...", long_running_tasks.count, long_running_tasks.count == 1 ? "" : "s"); + dr_fstrs_push_new(scratch.arena, &status_fstrs, ¶ms, string); + } + } + else + { + status_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); + } + } + + //- rjf: build bottom bar UI_Flags(UI_BoxFlag_DrawBackground) UI_CornerRadius(0) UI_Tag(tag) UI_Pane(bottom_bar_rect, str8_lit("###bottom_bar")) UI_WidthFill UI_Row UI_Flags(0) { + Temp scratch = scratch_begin(0, 0); + // rjf: developer frame-time indicator if(DEV_updating_indicator) { @@ -7804,57 +7849,24 @@ rd_window_frame(void) ui_spacer(ui_em(1.5f*(1-animation_t), 1.f)); } - // rjf: status + // rjf: build status { ui_spacer(ui_em(1.f, 1.f)); - if(is_running) - { - ui_label(str8_lit("Running")); - } - else - { - Temp scratch = scratch_begin(0, 0); - DR_FStrList explanation_fstrs = rd_stop_explanation_fstrs_from_ctrl_event(scratch.arena, &stop_event); - UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(box, &explanation_fstrs); - scratch_end(scratch); - } + UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(box, &status_fstrs); } ui_spacer(ui_pct(1, 0)); - // rjf: bind change visualization - if(rd_state->bind_change_active) - { - RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(rd_state->bind_change_cmd_name); - String8 display_name = rd_display_from_code_name(info->string); + // rjf: version + UI_FontSize(ui_top_font_size()*0.85f) UI_PrefWidth(ui_text_dim(10, 1)) - UI_Flags(UI_BoxFlag_DrawBackground) - UI_TextAlignment(UI_TextAlign_Center) - UI_CornerRadius(4) - UI_TagF("pop") - ui_labelf("Currently rebinding \"%S\" hotkey", display_name); + UI_TextAlignment(UI_TextAlign_Center) + { + ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL)); } - // rjf: error visualization - else if(ws->error_t >= 0.01f) - { - ws->error_t -= rd_state->frame_dt/8.f; - rd_request_frame(); - String8 error_string = str8(ws->error_buffer, ws->error_string_size); - if(error_string.size != 0) - { - ui_set_next_pref_width(ui_children_sum(1)); - UI_CornerRadius(4) - UI_Row - UI_PrefWidth(ui_text_dim(10, 1)) - UI_TextAlignment(UI_TextAlign_Center) - { - RD_Font(RD_FontSlot_Icons) ui_label(rd_icon_kind_text_table[RD_IconKind_WarningBig]); - rd_label(error_string); - } - } - } + scratch_end(scratch); } } @@ -9541,6 +9553,15 @@ rd_window_frame(void) dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.025f), 0, 0, 0); } + //- rjf: draw border/overlay color to signify rebinding + if(rd_state->bind_change_active) UI_TagF("pop") + { + Vec4F32 color = ui_color_from_name(str8_lit("background")); + Rng2F32 rect = os_client_rect_from_window(ws->os); + dr_rect(pad_2f32(rect, 24.f), color, 0, 16.f, 12.f); + dr_rect(rect, v4f32(color.x, color.y, color.z, color.w*0.025f), 0, 0, 0); + } + scratch_end(scratch); } @@ -9941,7 +9962,10 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; switch(event->cause) { - default:{}break; + default: + { + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Not running")); + }break; //- rjf: finished operation; if active thread, completed thread, otherwise we're just stopped case CTRL_EventCause_Finished: diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 42fb811e..9944e58c 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -851,14 +851,14 @@ rd_cmd_binding_buttons(String8 name, String8 filter, B32 add_new) UI_Signal sig = ui_signal_from_box(box); if(ui_clicked(sig)) { - if(!rd_state->bind_change_active && ui_clicked(sig)) + if(!adding_new_binding && ui_clicked(sig)) { arena_clear(rd_state->bind_change_arena); rd_state->bind_change_active = 1; rd_state->bind_change_cmd_name = push_str8_copy(rd_state->bind_change_arena, name); rd_state->bind_change_binding_id = 0; } - else if(rd_state->bind_change_active && ui_clicked(sig)) + else if(adding_new_binding && ui_clicked(sig)) { rd_state->bind_change_active = 0; } From ac0a242f73278bc0b6a8ee7ea9832c004f0aff85 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 22:04:40 -0700 Subject: [PATCH 590/755] sketch out simple old-config-loader to just preserve targets/file_path_maps/etc. from 0.9.15 and before --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 18 ++++---- src/raddbg/raddbg_inc.c | 1 + src/raddbg/raddbg_inc.h | 1 + src/raddbg/raddbg_legacy_config.c | 68 ++++++++++++++++++++++++++++++ src/raddbg/raddbg_legacy_config.h | 9 ++++ 7 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 src/raddbg/raddbg_legacy_config.c create mode 100644 src/raddbg/raddbg_legacy_config.h diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 8279b195..351094f0 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -407,7 +407,7 @@ RD_VocabInfo rd_vocab_info_table[340] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { {str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, -{str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, +{str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index a27ac50d..9434beed 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -292,8 +292,8 @@ RD_VocabTable: //- rjf: visualizers @display_name('Use Default C++ STL Type Visualizers') @description("Enables the built-in type views for C++ STL types.") @default(1) use_default_stl_type_views: bool, - @display_name('Use Default Unreal Engine Type Visualizers') @description("Enables the built-in type views for Unreal Engine types.") - @default(1) use_default_ue_type_views: bool, + // @display_name('Use Default Unreal Engine Type Visualizers') @description("Enables the built-in type views for Unreal Engine types.") + // @default(1) use_default_ue_type_views: bool, //- rjf: theme @default("None") @display_name('Project Theme') @description("The project's theme, which describes all colors used throughout the UI, and can override the user's theme.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9e32b531..024950c8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12414,13 +12414,6 @@ rd_frame(void) U64 first_space = str8_find_needle(file_version, 0, str8_lit(" "), 0); file_version = str8_prefix(file_version, first_space); file_version = str8_skip_chop_whitespace(file_version); - String8 current_version = str8_lit(BUILD_VERSION_STRING_LITERAL); - if(!str8_match(file_version, current_version, 0)) - { - String8 msg = push_str8f(scratch.arena, "You are trying to run a new development version of RADDBG (%S) with old configuration files. This would overwrite your old configuration files, since the code to appropriately handle old configuration files hasn't been written yet. Out of caution, the program will now exit. If you want to use this new version anyway, delete or rename your configuration file at %S, so that the new development version can begin safely saving to it.", current_version, file_path); - os_graphical_message(1, str8_lit("Unsupported Configuration File Version"), msg); - os_abort(1); - } } //- rjf: bad file -> alert user @@ -12439,7 +12432,16 @@ rd_frame(void) RD_CfgList file_cfg_list = {0}; if(file_is_okay) { - file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_path, file_data); + String8 current_version = str8_lit(BUILD_VERSION_STRING_LITERAL); + if(!str8_match(file_version, current_version, 0)) + { + RD_CfgList (*legacy_parse_function)(Arena *arena, String8 file_path, String8 data) = rd_cfg_tree_list_from_string__pre_0_9_16; + file_cfg_list = legacy_parse_function(scratch.arena, file_path, file_data); + } + else + { + file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_path, file_data); + } } //- rjf: store path diff --git a/src/raddbg/raddbg_inc.c b/src/raddbg/raddbg_inc.c index e3fef691..ece449df 100644 --- a/src/raddbg/raddbg_inc.c +++ b/src/raddbg/raddbg_inc.c @@ -5,3 +5,4 @@ #include "raddbg_eval.c" #include "raddbg_widgets.c" #include "raddbg_views.c" +#include "raddbg_legacy_config.c" diff --git a/src/raddbg/raddbg_inc.h b/src/raddbg/raddbg_inc.h index 2e131faf..deca7cb0 100644 --- a/src/raddbg/raddbg_inc.h +++ b/src/raddbg/raddbg_inc.h @@ -8,5 +8,6 @@ #include "raddbg_eval.h" #include "raddbg_widgets.h" #include "raddbg_views.h" +#include "raddbg_legacy_config.h" #endif // RADDBG_INC_H diff --git a/src/raddbg/raddbg_legacy_config.c b/src/raddbg/raddbg_legacy_config.c new file mode 100644 index 00000000..3932abce --- /dev/null +++ b/src/raddbg/raddbg_legacy_config.c @@ -0,0 +1,68 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal RD_CfgList +rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String8 data) +{ + RD_CfgList result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + MD_Node *src_root = md_parse_from_text(scratch.arena, file_path, data).root; + { + for MD_EachNode(tln, src_root->first) + { + //- rjf: targets + if(str8_match(tln->string, str8_lit("target"), 0)) + { + String8 disabled_string = md_child_from_string(tln, str8_lit("disabled"), 0)->first->string; + String8 executable = md_child_from_string(tln, str8_lit("executable"), 0)->first->string; + String8 arguments = md_child_from_string(tln, str8_lit("arguments"), 0)->first->string; + String8 working_directory = md_child_from_string(tln, str8_lit("working_directory"), 0)->first->string; + String8 entry_point = md_child_from_string(tln, str8_lit("entry_point"), 0)->first->string; + String8 stdout_path = md_child_from_string(tln, str8_lit("stdout_path"), 0)->first->string; + String8 stderr_path = md_child_from_string(tln, str8_lit("stderr_path"), 0)->first->string; + String8 stdin_path = md_child_from_string(tln, str8_lit("stdin_path"), 0)->first->string; + String8 debug_subprocesses= md_child_from_string(tln, str8_lit("debug_subprocesses"), 0)->first->string; + RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, str8_lit("target")); + rd_cfg_list_push(arena, &result, dst_root); + { + if(executable.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("executable")), path_absolute_dst_from_relative_dst_src(scratch.arena, executable, file_path)); } + if(arguments.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("arguments")), raw_from_escaped_str8(scratch.arena, arguments)); } + if(working_directory.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("working_directory")), path_absolute_dst_from_relative_dst_src(scratch.arena, working_directory, file_path)); } + if(entry_point.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("entry_point")), raw_from_escaped_str8(scratch.arena, entry_point)); } + if(stdout_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdout_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdout_path, file_path)); } + if(stderr_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stderr_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stderr_path, file_path)); } + if(stdin_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdin_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdin_path, file_path)); } + if(debug_subprocesses.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("debug_subprocesses")), raw_from_escaped_str8(scratch.arena, debug_subprocesses)); } + if(!str8_match(disabled_string, str8_lit("1"), 0)) + { + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("enabled")), str8_lit("1")); + } + } + } + + //- rjf: recent files / projects + if(str8_match(tln->string, str8_lit("recent_file"), 0) || + str8_match(tln->string, str8_lit("recent_project"), 0)) + { + RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, tln->string); + rd_cfg_list_push(arena, &result, dst_root); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("path")), path_absolute_dst_from_relative_dst_src(scratch.arena, tln->first->string, file_path)); + } + + //- rjf: file path maps + if(str8_match(tln->string, str8_lit("file_path_map"), 0)) + { + String8 source = md_child_from_string(tln, str8_lit("source"), 0)->first->string; + String8 dest = md_child_from_string(tln, str8_lit("dest"), 0)->first->string; + RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, tln->string); + rd_cfg_list_push(arena, &result, dst_root); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("source")), path_absolute_dst_from_relative_dst_src(scratch.arena, source, file_path)); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("dest")), path_absolute_dst_from_relative_dst_src(scratch.arena, dest, file_path)); + } + } + } + scratch_end(scratch); + } + return result; +} diff --git a/src/raddbg/raddbg_legacy_config.h b/src/raddbg/raddbg_legacy_config.h new file mode 100644 index 00000000..31d2f8da --- /dev/null +++ b/src/raddbg/raddbg_legacy_config.h @@ -0,0 +1,9 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RADDBG_LEGACY_CONFIG_H +#define RADDBG_LEGACY_CONFIG_H + +internal RD_CfgList rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String8 data); + +#endif // RADDBG_LEGACY_CONFIG_H From f218ac6628ca29fbf3bbd50fa7ddbc305cc6e318 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 May 2025 23:06:23 -0700 Subject: [PATCH 591/755] release notes --- src/raddbg/raddbg_core.c | 5 +++-- src/raddbg/raddbg_main.c | 26 ++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 024950c8..31d519b9 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7850,6 +7850,7 @@ rd_window_frame(void) } // rjf: build status + UI_PrefWidth(ui_text_dim(10, 1)) { ui_spacer(ui_em(1.f, 1.f)); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); @@ -10068,7 +10069,7 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) else { dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_WarningBig], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Hit an exception: ")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" Hit an exception: ")); String8 exception_code_string = str8_from_u64(arena, event->exception_code, 16, 0, 0); String8 exception_explanation_string = rd_string_from_exception_code(event->exception_code); String8 exception_info_string = push_str8f(arena, "%S%s%S%s", @@ -10093,7 +10094,7 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) case CTRL_EventCause_InterruptedByHalt: { dr_fstrs_push_new(arena, &fstrs, ¶ms, rd_icon_kind_text_table[RD_IconKind_Pause], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons)); - dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit("Halted")); + dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" Halted")); }break; } return fstrs; diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 6a38b838..d8e0f2b7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -26,6 +26,7 @@ // pattern, to specify placeholders for various parts of a type name. For // example, the pattern `DynamicArray` would match `DynamicArray`, // `DynamicArray`, and so on. `?(?)` would match all function types. +// (#118, #345) // - **Usage of the source expression within type views.** Type views have been // upgraded to support a larger number of possibilities. Instead of mapping // to a set of views which are applied to some other expression, type views @@ -103,6 +104,7 @@ // dropped. This can be used to create new top-level rows in a `Watch` tab, // or to drag evaluations between `Watch` tabs, or to drag evaluations to // source or disassembly views and pin the evaluation to some location there. +// (#137, #388) // - **Settings expressions.** Debugger settings have been upgraded to be // stored as expressions, rather than being locked to a specific value. // These expressions are evaluated, like any other expression, and their @@ -122,7 +124,7 @@ // the value as well. // - **Merging of `Watch` UI with hover evaluation.** The hover evaluation // feature has been majorly upgraded to support all features normally -// available in `Watch` tabs. +// available in `Watch` tabs. (#342) // - Added **transient tabs**, which are colored differently than normal tabs. // These tabs are automatically opened by the debugger when snapping to // source code which is not already opened. They are automatically replaced @@ -143,7 +145,7 @@ // pins (the right-click context menu and the dedicated tabs) have been // merged. Both interfaces support exactly the same features in exactly the // same way. The same interface is also accessible through the palette. -// - Added the ability to add a list of environment strings to targets. +// - Added the ability to add a list of environment strings to targets. (#73) // - The debugger releases are now packaged with a `raddbg_markup.h` // single-header library which contains a number of source code markup tools // which can be used in your programs. Some of these features are for direct @@ -186,6 +188,26 @@ // - Fixed a debugger regression which was incorrectly using thread name events // when those events were sent to name a suspended thread by a different // thread. (#430) +// - Added support for Tab and Shift + Tab style navigation in Watch tables, +// using the `Move Next` and `Move Previous` commands. (#93) +// - The debugger now correctly serializes window sizes when fullscreened. +// (#130) +// - Added an option to disable the Alt key Windows-style menu-bar focusing +// behavior. (#382) +// - Added an option to quickly duplicate configuration entities (targets, +// breakpoints, etc.). (#451) +// - Fixed a crash relating to truncated string hover tooltips when font sizes +// were changed. (#416) +// - Fixed the debugger's lack of robustness to selecting non-config files as +// config files. (#432, #409) +// - Fixed crashes caused by quick changes in the set of loaded modules while +// debug information table tabs (`Procedures`, `Globals`, `Types`) were open. +// (#467, #459, #458, #440, #436, #415, #412) +// - Fixed a crash where the debugger would crash when toggling fullscreen, if +// launched in fullscreen mode. (#454, #413) +// - Adjusted breakpoint placement to automatically deduplicate identical +// breakpoints, if placed at the same location, with no extra information +// attached (condition or label). (#407) // - Made several visual improvements. //////////////////////////////// From b8eace001a6fe41bbb058c10d4e4471c48e92886 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 08:56:11 -0700 Subject: [PATCH 592/755] working on visualizer tab pull-outs in all cases, cleaning up some rough edges of watch window controls --- src/raddbg/raddbg_core.c | 101 ++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 13 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 31d519b9..c081cd3f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4393,10 +4393,16 @@ rd_view_ui(Rng2F32 rect) // ProfScope("build table") { + F32 row_y_px = rect.y0; U64 local_row_idx = 0; U64 global_row_idx = rows.count_before_semantic; RD_WatchRowInfo last_row_info = {0}; - for(EV_WindowedRowNode *row_node = rows.first; row_node != 0; row_node = row_node->next, global_row_idx += 1, local_row_idx += 1) + for(EV_WindowedRowNode *row_node = rows.first; + row_node != 0; + (row_y_px += row_height_px * (row_node->row.visual_size), + row_node = row_node->next, + global_row_idx += 1, + local_row_idx += 1)) { //////////////////////// //- rjf: unpack row info @@ -4691,6 +4697,7 @@ rd_view_ui(Rng2F32 rect) //////////// //- rjf: build cell contents // + RD_Cfg *cell_view = &rd_nil_cfg; UI_Signal sig = {0}; ProfScope("build cell contents") UI_Parent(cell_box) @@ -4704,17 +4711,18 @@ rd_view_ui(Rng2F32 rect) if(cell->kind == RD_WatchCellKind_ViewUI && cell_info.view_ui_rule != &rd_nil_view_ui_rule) { RD_Cfg *root = rd_immediate_cfg_from_keyf("view%I64x_%I64x", rd_regs()->view, row_hash); - RD_Cfg *view = rd_view_from_eval(root, cell->eval); - Rng2F32 cell_rect = r2f32p(cell_x_px, 0, next_cell_x_px, row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); + cell_view = rd_view_from_eval(root, cell->eval); + Rng2F32 cell_rect = r2f32p(cell_x_px, row_y_px, next_cell_x_px, row_y_px + row_height_px*(row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped)); ui_set_next_fixed_y(-1.f * (row_node->visual_size_skipped) * row_height_px); ui_set_next_fixed_height((row_node->visual_size_skipped + row->visual_size + row_node->visual_size_chopped) * row_height_px); UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable|UI_BoxFlag_FloatingY, "###val_%I64x", row_hash); UI_Parent(box) - RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell->eval)) + RD_RegsScope(.view = cell_view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell->eval)) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) UI_Flags(0) { // rjf: 'pull out' button + UI_Signal pull_out_sig = {0}; UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(floor_f32(ui_top_font_size()*1.5f), floor_f32(ui_top_font_size()*1.5f), floor_f32(ui_top_font_size()*1.5f + ui_top_font_size()*3.f), @@ -4733,11 +4741,16 @@ rd_view_ui(Rng2F32 rect) UI_BoxFlag_DrawHotEffects, "%S###pull_out", rd_icon_kind_text_table[RD_IconKind_Window]); - UI_Signal sig = ui_signal_from_box(box); - if(ui_dragging(sig) && !contains_2f32(box->rect, ui_mouse())) - { - rd_drag_begin(RD_RegSlot_View); - } + pull_out_sig = ui_signal_from_box(box); + } + if(ui_hovering(pull_out_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) + { + ui_state->tooltip_anchor_key = pull_out_sig.box->key; + ui_labelf("Pull Out As New Tab"); + } + if(ui_dragging(pull_out_sig) && !contains_2f32(pull_out_sig.box->rect, ui_mouse())) + { + rd_drag_begin(RD_RegSlot_View); } // rjf: loading animation container @@ -4756,7 +4769,7 @@ rd_view_ui(Rng2F32 rect) // rjf: loading fill UI_Parent(loading_overlay_container) { - RD_ViewState *vs = rd_view_state_from_cfg(view); + RD_ViewState *vs = rd_view_state_from_cfg(cell_view); rd_loading_overlay(cell_rect, vs->loading_t, vs->loading_progress_v, vs->loading_progress_v_target); } } @@ -5024,9 +5037,33 @@ rd_view_ui(Rng2F32 rect) ui_kill_action(); } + // rjf: cell w/ a visualizer hook? -> + // if keyboard: open in tab, if within tab + // if double-click: focus this visualizer (via edit) + if(cell->kind == RD_WatchCellKind_ViewUI && + cell_info.view_ui_rule != &rd_nil_view_ui_rule && + cell_view != &rd_nil_cfg) + { + if(!view_is_floating && sig.f & UI_SignalFlag_KeyboardPressed) + { + rd_cfg_unhook(cell_view->parent, cell_view); + rd_cfg_insert_child(view->parent, view, cell_view); + rd_cmd(RD_CmdKind_FocusTab, .tab = cell_view->id); + } + else if(sig.f & UI_SignalFlag_DoubleClicked) + { + ewv->next_cursor = ewv->next_mark = cell_pt; + if(!rd_watch_pt_match(ewv->cursor, cell_pt) && ewv->text_editing) + { + rd_cmd(RD_CmdKind_Accept); + } + rd_cmd(RD_CmdKind_Edit); + } + } + // rjf: this watch window is a lister? -> move cursor & edit or accept - if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || - rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) + else if(rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg || + rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; rd_cmd(RD_CmdKind_Accept); @@ -5088,7 +5125,7 @@ rd_view_ui(Rng2F32 rect) else if(!(sig.f & UI_SignalFlag_KeyboardPressed) && cell_info.flags & RD_WatchCellFlag_CanEdit) { ewv->next_cursor = ewv->next_mark = cell_pt; - if(!row_is_expandable) + if(!rd_watch_pt_match(ewv->cursor, cell_pt)) { rd_cmd(RD_CmdKind_Accept); } @@ -5272,10 +5309,48 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(expr_string); + + // rjf: 'pull out' button, if floating + if(view_is_floating) + { + UI_Signal pull_out_sig = {0}; + UI_TagF(".") UI_TagF("tab") UI_Rect(r2f32p(floor_f32(ui_top_font_size()*1.5f), + floor_f32(ui_top_font_size()*1.5f), + floor_f32(ui_top_font_size()*1.5f + ui_top_font_size()*3.f), + floor_f32(ui_top_font_size()*1.5f + ui_top_font_size()*3.f))) + UI_CornerRadius(floor_f32(ui_top_font_size()*1.5f)) + UI_TextAlignment(UI_TextAlign_Center) + RD_Font(RD_FontSlot_Icons) + UI_FontSize(floor_f32(ui_top_font_size()*0.9f)) + { + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_Floating| + UI_BoxFlag_DrawText| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawActiveEffects| + UI_BoxFlag_DrawHotEffects, + "%S###pull_out", + rd_icon_kind_text_table[RD_IconKind_Window]); + pull_out_sig = ui_signal_from_box(box); + } + if(ui_dragging(pull_out_sig) && !contains_2f32(pull_out_sig.box->rect, ui_mouse())) + { + rd_drag_begin(RD_RegSlot_View); + } + if(ui_hovering(pull_out_sig)) UI_Tooltip RD_Font(RD_FontSlot_Main) + { + ui_state->tooltip_anchor_key = pull_out_sig.box->key; + ui_labelf("Pull Out As New Tab"); + } + } + + // rjf: build ui via hook E_ParentKey(expr_eval.key) { view_ui_rule->ui(expr_eval, rect); } + scratch_end(scratch); } } From e5a2f6da11aca8c6720e166ff1e0ffbe13ed4a26 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 09:24:34 -0700 Subject: [PATCH 593/755] do not apply filters past one block layer (fixes broken expansions in debug info table tabs) --- .../eval_visualization_core.c | 26 ++++++++++++------- .../eval_visualization_core.h | 8 +++--- src/raddbg/raddbg_core.c | 22 ++++++++-------- src/raddbg/raddbg_eval.c | 24 ++++++++++++++++- src/raddbg/raddbg_main.c | 5 ++-- src/raddbg/raddbg_views.c | 4 +-- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index cdcf9b1d..1fec0f3e 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -499,6 +499,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root U64 split_relative_idx; B32 default_expanded; B32 force_expanded; + S32 depth; }; BlockTreeBuildTask start_task = {0, tree.root, tree.root->eval, tree.root->eval.expr->next, 1, 0}; BlockTreeBuildTask *first_task = &start_task; @@ -543,9 +544,12 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root continue; } + // rjf: get filter for this task + String8 task_filter = t->depth == 0 ? filter : str8_zero(); + // rjf: get top-level lookup/expansion info - E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, eval, filter); - EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, eval.expr); + E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, eval, task_filter); + EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, task_filter, eval.expr); // rjf: determine expansion info U64 expansion_row_count = type_expand_info.expr_count; @@ -573,6 +577,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root expansion_block->key = key; expansion_block->split_relative_idx = t->split_relative_idx; expansion_block->eval = eval; + expansion_block->filter = task_filter; expansion_block->type_expand_info = type_expand_info; expansion_block->type_expand_rule = type_expand_rule; expansion_block->viz_expand_info = viz_expand_info; @@ -659,7 +664,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root { Rng1U64 child_range = r1u64(split_relative_idx, split_relative_idx+1); E_Eval child_eval = {0}; - type_expand_rule->range(arena, type_expand_info.user_data, eval, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); + type_expand_rule->range(arena, type_expand_info.user_data, eval, task_filter, r1u64(split_relative_idx, split_relative_idx+1), &child_eval); EV_Key child_key = child_keys[idx]; BlockTreeBuildTask *task = push_array(scratch.arena, BlockTreeBuildTask, 1); SLLQueuePush(first_task, last_task, task); @@ -669,6 +674,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root task->child_id = child_key.child_id; task->split_relative_idx = split_relative_idx; task->default_expanded = viz_expand_info.rows_default_expanded; + task->depth = t->depth+1; } } @@ -685,6 +691,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root task->split_relative_idx = 0; task->default_expanded = t->default_expanded; task->force_expanded = 1; + task->depth = t->depth; } } scratch_end(scratch); @@ -907,7 +914,7 @@ ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vnum) //~ rjf: Row Building internal EV_WindowedRowList -ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range) +ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range) { EV_WindowedRowList rows = {0}; { @@ -918,6 +925,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 Rng1U64 block_relative_range = n->v.range; U64 block_num_visual_rows = dim_1u64(block_relative_range); Rng1U64 block_global_range = r1u64(base_vnum, base_vnum + block_num_visual_rows); + String8 block_filter = n->v.block->filter; // rjf: get skip/chop of global range U64 num_skipped = 0; @@ -974,7 +982,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } else { - n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval, filter, block_relative_range__windowed, range_evals); + n->v.block->type_expand_rule->range(arena, n->v.block->type_expand_info.user_data, n->v.block->eval, block_filter, block_relative_range__windowed, range_evals); } // rjf: no expansion operator applied -> push row for block expression; pass through block info @@ -1017,10 +1025,10 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 } internal EV_Row * -ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num) +ev_row_from_num(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, U64 num) { U64 vidx = ev_vnum_from_num(block_ranges, num); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, r1u64(vidx, vidx+1)); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, block_ranges, r1u64(vidx, vidx+1)); EV_Row *result = 0; if(rows.first != 0) { @@ -1036,10 +1044,10 @@ ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList * } internal EV_WindowedRowList -ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range) +ev_rows_from_num_range(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 num_range) { Rng1U64 vnum_range = r1u64(ev_vnum_from_num(block_ranges, num_range.min), ev_vnum_from_num(block_ranges, num_range.max)+1); - EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, filter, block_ranges, vnum_range); + EV_WindowedRowList rows = ev_windowed_row_list_from_block_range_list(arena, view, block_ranges, vnum_range); return rows; } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index dcca9cb6..5f5a8d9d 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -149,6 +149,7 @@ struct EV_Block // rjf: evaluation info String8 string; E_Eval eval; + String8 filter; E_TypeExpandInfo type_expand_info; E_TypeExpandRule *type_expand_rule; EV_ExpandInfo viz_expand_info; @@ -291,6 +292,7 @@ global read_only EV_Block ev_nil_block = {0}, {{0}, {0}, {0}, &e_expr_nil, &e_irnode_nil}, {0}, + {0}, &e_type_expand_rule__default, {0}, &ev_nil_expand_rule, @@ -358,9 +360,9 @@ internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx); //////////////////////////////// //~ rjf: Row Building -internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); -internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, U64 num); -internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 num_range); +internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range); +internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, U64 num); +internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 num_range); internal B32 ev_eval_is_expandable(E_Eval eval); internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c081cd3f..6f4c8235 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3111,7 +3111,7 @@ rd_view_ui(Rng2F32 rect) // rjf: compute legal coordinate range, given selection-defining row Rng1S64 cursor_x_range = {0}; { - EV_Row *row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, mark_tbl.y); + EV_Row *row = ev_row_from_num(scratch.arena, eval_view, &block_ranges, mark_tbl.y); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); cursor_x_range = r1s64(0, (S64)row_info.cells.count-1); } @@ -3206,13 +3206,13 @@ rd_view_ui(Rng2F32 rect) EV_Row *row = 0; if(selection_tbl.min.y == 0 && selection_tbl.max.y == 0) { - row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, 1); + row = ev_row_from_num(scratch.arena, eval_view, &block_ranges, 1); } // rjf: if we do have a selection, compute that row else { - row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, selection_tbl.min.y); + row = ev_row_from_num(scratch.arena, eval_view, &block_ranges, selection_tbl.min.y); } // rjf: use row to complete query @@ -3417,7 +3417,7 @@ rd_view_ui(Rng2F32 rect) ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1); ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64); ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState*, ewv->text_edit_state_slots_count); - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; B32 any_edits_started = 0; for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) @@ -3471,7 +3471,7 @@ rd_view_ui(Rng2F32 rect) (selection_tbl.min.y != 0 || selection_tbl.max.y != 0) && (selection_tbl.max.y - selection_tbl.min.y > 0)) { - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; if(row_node != 0) { @@ -3546,7 +3546,7 @@ rd_view_ui(Rng2F32 rect) evt->delta_2s32.y == 0)) { taken = 1; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { @@ -3678,7 +3678,7 @@ rd_view_ui(Rng2F32 rect) { taken = 1; String8List strs = {0}; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row_node != 0; y += 1, row_node = row_node->next) { @@ -3731,7 +3731,7 @@ rd_view_ui(Rng2F32 rect) RD_CfgList cfgs_to_remove = {0}; RD_WatchPt next_cursor_pt = {0}; B32 next_cursor_set = 0; - EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); + EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; for(S64 y = selection_tbl.min.y; row_node != 0 && y <= selection_tbl.max.y; y += 1, row_node = row_node->next) { @@ -4024,7 +4024,7 @@ rd_view_ui(Rng2F32 rect) rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { U64 row_num = ev_num_from_key(&block_ranges, ewv->cursor.key); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), &block_ranges, row_num); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), &block_ranges, row_num); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); RD_WatchCell *cell = row_info.cells.first; if(cell != 0) @@ -4083,7 +4083,7 @@ rd_view_ui(Rng2F32 rect) // EV_WindowedRowList rows = {0}; { - rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, filter, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); + rows = ev_windowed_row_list_from_block_range_list(scratch.arena, eval_view, &block_ranges, r1u64(visible_row_rng.min+1, visible_row_rng.max+2)); } //////////////////////// @@ -4335,7 +4335,7 @@ rd_view_ui(Rng2F32 rect) { EV_Key prev_row_key = ev_key_make(ev_hash_from_key(drag_block->key), ev_block_id_from_num(drag_block, best_prev_row_block_num)); U64 prev_row_num = ev_num_from_key(&block_ranges, prev_row_key); - EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, filter, &block_ranges, prev_row_num); + EV_Row *prev_row = ev_row_from_num(scratch.arena, eval_view, &block_ranges, prev_row_num); RD_WatchRowInfo prev_row_info = rd_watch_row_info_from_row(scratch.arena, prev_row); drag_parent_cfg = rd_cfg_from_eval_space(drag_block->eval.space); drag_prev_cfg = prev_row_info.group_cfg_child; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 25e46912..84df2423 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1154,7 +1154,29 @@ E_TYPE_ACCESS_FUNCTION_DEF(watches) E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) { - RD_WatchesAccel *accel = (RD_WatchesAccel *)eval.irtree.user_data; + RD_WatchesAccel *ext = (RD_WatchesAccel *)eval.irtree.user_data; + RD_WatchesAccel *accel = push_array(arena, RD_WatchesAccel, 1); + { + RD_CfgArray cfgs__filtered = ext->cfgs; + if(filter.size != 0) + { + Temp scratch = scratch_begin(&arena, 1); + RD_CfgList cfgs_list__filtered = {0}; + for EachIndex(idx, ext->cfgs.count) + { + RD_Cfg *watch = ext->cfgs.v[idx]; + String8 string = watch->first->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, string); + if(matches.count == matches.needle_part_count) + { + rd_cfg_list_push(scratch.arena, &cfgs_list__filtered, watch); + } + } + cfgs__filtered = rd_cfg_array_from_list(arena, &cfgs_list__filtered); + scratch_end(scratch); + } + accel->cfgs = cfgs__filtered; + } E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; return result; } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index d8e0f2b7..f6d421e4 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -215,15 +215,14 @@ // // [ ] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop // [ ] autocompletion lister -// [ ] "pop out" (hitting enter on visualizers should open them as tabs) // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs +// (actually, just kill the tabs on load if they refer to transient things) // [ ] finish theme editing, build themes - replace code colors map with new theme stuff // // [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... // [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) -// [ ] do not apply filters past one block layer //////////////////////////////// //~ rjf: post-0.9.16 TODO notes @@ -529,6 +528,8 @@ // "save" option in the menus. // [x] user switching // [x] project switching +// [x] do not apply filters past one block layer +// [x] "pop out" (hitting enter on visualizers should open them as tabs) //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index febbeab3..3ff060a0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -872,7 +872,7 @@ rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) RD_WatchPt pt = zero_struct; { Temp scratch = scratch_begin(0, 0); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, (U64)tbl.y); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), block_ranges, (U64)tbl.y); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); { S64 x = 0; @@ -899,7 +899,7 @@ rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Temp scratch = scratch_begin(0, 0); U64 num = ev_num_from_key(block_ranges, pt.key); - EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), rd_view_query_input(), block_ranges, num); + EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), block_ranges, num); RD_WatchRowInfo row_info = rd_watch_row_info_from_row(scratch.arena, row); tbl.x = 0; { From 2b1e286aad1bb1baf169b20e62a972060ca35afe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 09:31:16 -0700 Subject: [PATCH 594/755] preserve dbgi fuzzy searching results based on key alone, rather than throwing away all results if params change (although still re-querying if params change); also fix not clearing the autocompletion string gathered for a UI build across frames --- src/dbgi/dbgi.c | 9 ++++----- src/ui/ui_core.c | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 15ccb4b3..f790a166 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -704,12 +704,11 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams B32 params_stale = 1; B32 query_stale = 1; B32 results_stale = 1; - if(params_hash == node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash && - node->bucket_read_gen != 0) + if(node->bucket_read_gen != 0) { di_scope_touch_search_node__stripe_mutex_r_guarded(scope, node); items = node->items; - params_stale = 0; + params_stale = (params_hash != node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash); query_stale = !str8_match(query, node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].query, 0); results_stale = (node->bucket_read_gen < node->bucket_write_gen); } @@ -718,8 +717,8 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams *stale_out = (params_stale || query_stale || results_stale); } - // rjf: if query stale -> request again - if(query_stale && node->bucket_read_gen <= node->bucket_write_gen && node->bucket_write_gen < node->bucket_read_gen + ArrayCount(node->buckets)-1) + // rjf: if query or params stale -> request again + if((query_stale || params_stale) && node->bucket_read_gen <= node->bucket_write_gen && node->bucket_write_gen < node->bucket_read_gen + ArrayCount(node->buckets)-1) { node->bucket_write_gen += 1; if(node->bucket_write_gen >= node->bucket_items_gen + ArrayCount(node->buckets)) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 116a50f1..4198c53e 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -833,6 +833,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->tags_key_stack_top = ui_state->tags_key_stack_free = 0; ui_state->tags_cache_slots_count = 512; ui_state->tags_cache_slots = push_array(ui_build_arena(), UI_TagsCacheSlot, ui_state->tags_cache_slots_count); + ui_state->autocomplete_string = str8_zero(); } //- rjf: prune unused animation nodes From 08402a57b4bd2d28467beade68fc3db10ad6885a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 09:41:54 -0700 Subject: [PATCH 595/755] notes --- src/raddbg/raddbg_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index f6d421e4..c9352c6d 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -222,7 +222,6 @@ // [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... -// [ ] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) //////////////////////////////// //~ rjf: post-0.9.16 TODO notes @@ -530,6 +529,7 @@ // [x] project switching // [x] do not apply filters past one block layer // [x] "pop out" (hitting enter on visualizers should open them as tabs) +// [x] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) //////////////////////////////// //~ rjf: Build Options From a6eda7db04da7b72e04e70e1fb313a0affa5b5a5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 13:02:48 -0700 Subject: [PATCH 596/755] fix incorrect parsing / expr-building order of casts vs. other prefix unaries in new parser path --- src/eval/eval_parse.c | 540 ++++++++++++++++++++++-------------------- 1 file changed, 279 insertions(+), 261 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index f84126ce..ba0f8b0e 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -849,7 +849,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } //////////////////////////// - //- rjf: parse prefix unaries + //- rjf: parse atom, gather prefix unary tasks // typedef struct PrefixUnaryTask PrefixUnaryTask; struct PrefixUnaryTask @@ -857,13 +857,18 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t PrefixUnaryTask *next; E_ExprKind kind; Rng1U64 range; + E_Expr *cast_type_expr; }; PrefixUnaryTask *first_prefix_unary = 0; PrefixUnaryTask *last_prefix_unary = 0; + E_Expr *atom = &e_expr_nil; + B32 atom_is_maybe_cast = 0; + for(B32 done = 0; !done && it < it_opl;) { - for(;it < it_opl;) + ////////////////////////// + //- rjf: prefix unary operators + // { - E_Token *start_it = it; E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; @@ -889,269 +894,286 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t prefix_unary_precedence = 2; } - // rjf: consume valid op + // rjf: push prefix unary if we got one if(prefix_unary_precedence != 0) { range = token.range; - it += 1; - } - - // rjf: break if we got no operators - if(prefix_unary_precedence == 0) - { - break; - } - - // rjf: break if the token node iterator has not changed - if(it == start_it) - { - break; - } - - // rjf: push prefix unary if we got one - { - PrefixUnaryTask *op_n = push_array(scratch.arena, PrefixUnaryTask, 1); - op_n->kind = prefix_unary_kind; - op_n->range = range; - SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); - } - } - } - - //////////////////////////// - //- rjf: parse atom, gather cast tasks - // - typedef struct CastTask CastTask; - struct CastTask - { - CastTask *next; - E_Expr *type_expr; - }; - CastTask *first_cast = 0; - CastTask *last_cast = 0; - E_Expr *atom = &e_expr_nil; - for(B32 done = 0; !done && it < it_opl;) - { - E_Expr *possible_cast = atom; - E_Token token = e_token_at_it(it, &tokens); - String8 token_string = str8_substr(text, token.range); - done = 1; - - ////////////////////////// - //- rjf: consume resolution qualifiers - // - String8 resolution_qualifier = {0}; - if(token.kind == E_TokenKind_Identifier) - { - E_Token next_token = e_token_at_it(it+1, &tokens); - String8 next_token_string = str8_substr(text, next_token.range); - if(next_token.range.min == token.range.max && next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) - { - it += 2; - resolution_qualifier = token_string; - token = e_token_at_it(it, &tokens); - token_string = str8_substr(text, token.range); - } - } - - ////////////////////////// - //- rjf: descent to nested expression (...) - // - if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) - { - // rjf: skip ( - it += 1; - - // rjf: parse () contents - E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, &tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `)`."); - } - - // rjf: consume ) - else - { - it += 1; - } - - // rjf: this may have been a cast, so keep parsing after this - done = 0; - } - - ////////////////////////// - //- rjf: descent to assembly-style dereference sub-expression [...] - // - else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) - { - // rjf: skip [ - it += 1; - - // rjf: parse [] contents - E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); - e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.expr == &e_expr_nil) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected expression following `[`."); - } - else - { - E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token.range); - type->type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); - E_Expr *casted = atom; - E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token.range); - e_expr_push_child(cast, type); - e_expr_push_child(cast, casted); - atom = e_push_expr(arena, E_ExprKind_Deref, token.range); - e_expr_push_child(atom, cast); - } - - // rjf: expect ] - E_Token close_paren_maybe = e_token_at_it(it, &tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `]`."); - } - - // rjf: consume ) - else - { + PrefixUnaryTask *prefix_unary_task = push_array(scratch.arena, PrefixUnaryTask, 1); + prefix_unary_task->kind = prefix_unary_kind; + prefix_unary_task->range = range; + SLLQueuePush(first_prefix_unary, last_prefix_unary, prefix_unary_task); it += 1; } } ////////////////////////// - //- rjf: leaf identifier + //- rjf: try to parse an atom // - else if(token.kind == E_TokenKind_Identifier) + if(atom == &e_expr_nil || atom_is_maybe_cast) { - atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token.range); - atom->string = token_string; - it += 1; - } - - ////////////////////////// - //- rjf: leaf numeric - // - else if(token.kind == E_TokenKind_Numeric) - { - U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); - it += 1; + B32 got_new_atom = 0; + E_Expr *maybe_cast = atom_is_maybe_cast ? atom : &e_expr_nil; + atom_is_maybe_cast = 0; - // rjf: no . => integral - if(dot_pos == token_string.size) + //////////////////////// + //- rjf: consume resolution qualifiers + // + String8 resolution_qualifier = {0}; { - U64 val = 0; - try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); - atom->value.u64 = val; - } - - // rjf: presence of . => double or float - if(dot_pos < token_string.size) - { - F64 val = f64_from_str8(token_string); - U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); - - // rjf: presence of f after . => f32 - if(f_pos < token_string.size) + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Identifier) { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token.range); - atom->value.f32 = val; - } - - // rjf: no f => f64 - else - { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token.range); - atom->value.f64 = val; + E_Token next_token = e_token_at_it(it+1, &tokens); + String8 next_token_string = str8_substr(text, next_token.range); + if(next_token.range.min == token.range.max && next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) + { + it += 2; + resolution_qualifier = token_string; + } } } - } - - ////////////////////////// - //- rjf: leaf char literal - // - else if(token.kind == E_TokenKind_CharLiteral) - { - it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + + //////////////////////// + //- rjf: descent to nested expression (...) + // + if(!got_new_atom) { - String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); - String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); - U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); - atom->value.u64 = (U64)char_val; + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) + { + // rjf: skip ( + it += 1; + + // rjf: parse () contents + E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.expr; + it = nested_parse.last_token; + atom_is_maybe_cast = 1; + got_new_atom = 1; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, &tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `)`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } } - else + + //////////////////////// + //- rjf: descent to assembly-style dereference sub-expression [...] + // + if(!got_new_atom) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Malformed character literal."); + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) + { + // rjf: skip [ + it += 1; + + // rjf: parse [] contents + E_Parse nested_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); + atom = nested_parse.expr; + it = nested_parse.last_token; + got_new_atom = 1; + + // rjf: build cast-to-U64*, and dereference operators + if(nested_parse.expr == &e_expr_nil) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected expression following `[`."); + } + else + { + E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token.range); + type->type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0); + E_Expr *casted = atom; + E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token.range); + e_expr_push_child(cast, type); + e_expr_push_child(cast, casted); + atom = e_push_expr(arena, E_ExprKind_Deref, token.range); + e_expr_push_child(atom, cast); + } + + // rjf: expect ] + E_Token close_paren_maybe = e_token_at_it(it, &tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `]`."); + } + + // rjf: consume ) + else + { + it += 1; + } + } + } + + //////////////////////// + //- rjf: leaf identifier + // + if(!got_new_atom) + { + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Identifier) + { + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token.range); + atom->string = token_string; + it += 1; + got_new_atom = 1; + } + } + + //////////////////////// + //- rjf: leaf numeric + // + if(!got_new_atom) + { + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_Numeric) + { + U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); + it += 1; + + // rjf: no . => integral + if(dot_pos == token_string.size) + { + U64 val = 0; + try_u64_from_str8_c_rules(token_string, &val); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); + atom->value.u64 = val; + } + + // rjf: presence of . => double or float + if(dot_pos < token_string.size) + { + F64 val = f64_from_str8(token_string); + U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); + + // rjf: presence of f after . => f32 + if(f_pos < token_string.size) + { + atom = e_push_expr(arena, E_ExprKind_LeafF32, token.range); + atom->value.f32 = val; + } + + // rjf: no f => f64 + else + { + atom = e_push_expr(arena, E_ExprKind_LeafF64, token.range); + atom->value.f64 = val; + } + } + + got_new_atom = 1; + } + } + + //////////////////////// + //- rjf: leaf char literal + // + if(!got_new_atom) + { + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_CharLiteral) + { + it += 1; + if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + { + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; + atom = e_push_expr(arena, E_ExprKind_LeafU64, token.range); + atom->value.u64 = (U64)char_val; + got_new_atom = 1; + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Malformed character literal."); + } + } + } + + //////////////////////// + //- rjf: filesystem-qualified leaf string literal + // + if(!got_new_atom) + { + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_StringLiteral && + (str8_match(resolution_qualifier, str8_lit("file"), 0) || + str8_match(resolution_qualifier, str8_lit("folder"), 0))) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token.range); + atom->string = string_value_raw; + it += 1; + got_new_atom = 1; + } + } + + //////////////////////// + //- rjf: leaf string literal + // + if(!got_new_atom) + { + E_Token token = e_token_at_it(it, &tokens); + String8 token_string = str8_substr(text, token.range); + if(token.kind == E_TokenKind_StringLiteral) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token.range); + atom->string = string_value_raw; + it += 1; + got_new_atom = 1; + } + } + + //////////////////////// + //- rjf: upgrade atom w/ qualifier + // + if(atom != &e_expr_nil && resolution_qualifier.size != 0) + { + atom->qualifier = resolution_qualifier; + } + + //////////////////////// + //- rjf: got new atom, but we had a potential cast atom? -> gather cast operator + // + if(got_new_atom && maybe_cast != &e_expr_nil) + { + PrefixUnaryTask *prefix_unary_task = push_array(scratch.arena, PrefixUnaryTask, 1); + prefix_unary_task->kind = E_ExprKind_Cast; + prefix_unary_task->range = maybe_cast->range; + prefix_unary_task->cast_type_expr = maybe_cast; + SLLQueuePush(first_prefix_unary, last_prefix_unary, prefix_unary_task); } } - ////////////////////////// - //- rjf: filesystem-qualified leaf string literal + //////////////////////// + //- rjf: if our atom is not potentially a cast, *or* if we simply did not get an atom, + // then we need to stop parsing at this stage. // - else if(token.kind == E_TokenKind_StringLiteral && - (str8_match(resolution_qualifier, str8_lit("file"), 0) || - str8_match(resolution_qualifier, str8_lit("folder"), 0))) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token.range); - atom->string = string_value_raw; - it += 1; - } - - ////////////////////////// - //- rjf: leaf string literal - // - else if(token.kind == E_TokenKind_StringLiteral) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token.range); - atom->string = string_value_raw; - it += 1; - } - - ////////////////////////// - //- rjf: not a recognized atom pattern - // - else - { - done = 1; - } - - ////////////////////////// - //- rjf: upgrade atom w/ qualifier - // - if(atom != &e_expr_nil && resolution_qualifier.size != 0) - { - atom->qualifier = resolution_qualifier; - } - - ////////////////////////// - //- rjf: gather cast - // - if(possible_cast != &e_expr_nil && possible_cast != atom) - { - CastTask *t = push_array(scratch.arena, CastTask, 1); - t->type_expr = possible_cast; - SLLQueuePushFront(first_cast, last_cast, t); - } + done = (!atom_is_maybe_cast || atom == &e_expr_nil); } //////////////////////////// @@ -1294,20 +1316,6 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } - //////////////////////////// - //- rjf: upgrade `atom` w/ previously parsed casts - // - if(atom != &e_expr_nil) - { - for(CastTask *cast = first_cast; cast != 0; cast = cast->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, E_ExprKind_Cast, cast->type_expr->range); - e_expr_push_child(atom, cast->type_expr); - e_expr_push_child(atom, rhs); - } - } - //////////////////////////// //- rjf: upgrade `atom` w/ previously parsed prefix unaries // @@ -1317,9 +1325,19 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t prefix_unary != 0; prefix_unary = prefix_unary->next) { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->range); - e_expr_push_child(atom, rhs); + if(prefix_unary->kind == E_ExprKind_Cast) + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->range); + e_expr_push_child(atom, prefix_unary->cast_type_expr); + e_expr_push_child(atom, rhs); + } + else + { + E_Expr *rhs = atom; + atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->range); + e_expr_push_child(atom, rhs); + } } } else if(first_prefix_unary != 0) From fe8d7e86fee9b77b3086f1f3d30c88efb6381906 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 13:09:47 -0700 Subject: [PATCH 597/755] fix expression editability condition in watch tables; notes --- src/raddbg/raddbg_main.c | 2 +- src/raddbg/raddbg_views.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index c9352c6d..cc0a8a57 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -213,7 +213,6 @@ //////////////////////////////// //~ rjf: 0.9.16 TODO notes // -// [ ] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop // [ ] autocompletion lister // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // (actually, just kill the tabs on load if they refer to transient things) @@ -530,6 +529,7 @@ // [x] do not apply filters past one block layer // [x] "pop out" (hitting enter on visualizers should open them as tabs) // [x] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) +// [x] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 3ff060a0..5afb5e9f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -971,7 +971,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: fill if row's expression is editable // - if(block_type->flags & E_TypeFlag_EditableChildren || row->eval.expr == &e_expr_nil) + if(block_type->flags & E_TypeFlag_EditableChildren || (e_key_match(row->eval.key, e_key_zero()) && row->eval.expr == &e_expr_nil)) { info.expr_is_editable = 1; } From e1bdae4144b4307c38581390d99e7c10ac9698e4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 13:20:52 -0700 Subject: [PATCH 598/755] adjust focuses on project-load, if project-filtered tabs are focused --- src/raddbg/raddbg_core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6f4c8235..bbc2a650 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12626,6 +12626,31 @@ rd_frame(void) } } + //- rjf: eliminate all project-filtered tab focuses + if(file_is_okay && kind == RD_CmdKind_OpenProject) + { + RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); + for(RD_CfgNode *n = windows.first; n != 0; n = n->next) + { + RD_PanelTree panels = rd_panel_tree_from_cfg(scratch.arena, n->v); + for(RD_PanelNode *panel = panels.root; panel != &rd_nil_panel_node; panel = rd_panel_node_rec__depth_first_pre(panels.root, panel).next) + { + if(rd_cfg_is_project_filtered(panel->selected_tab)) + { + for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next) + { + RD_Cfg *tab = tab_n->v; + if(!rd_cfg_is_project_filtered(tab)) + { + rd_cmd(RD_CmdKind_FocusTab, .tab = tab->id); + break; + } + } + } + } + } + } + //- rjf: if we've just loaded the user, and we do not have a project path, // then we should try to look at the user's data for recent projects and // load one of those, *or* just the default. From 686c666058161243198caf4083cf899b5a51400b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 14:03:22 -0700 Subject: [PATCH 599/755] final theme presets pass --- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 135 ++++++++++++++++++++++++++++- src/raddbg/raddbg_main.c | 2 +- 3 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 351094f0..125914fd 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -993,12 +993,12 @@ str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0xffffffff str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1f1f1fff }\n theme_color:{ tags: \"alt background\" , value: 0x222222ff }\n theme_color:{ tags: \"pop background\" , value: 0x383167ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x404040ff }\n theme_color:{ tags: text , value: 0xe5e5e5ff }\n theme_color:{ tags: \"weak text\" , value: 0xa4a4a4ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0x7160e81e }\n theme_color:{ tags: \"focus border\" , value: 0x7160e8ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0000002f }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xe0e0e0ff }\n theme_color:{ tags: code_symbol , value: 0xdcdcaaff }\n theme_color:{ tags: code_type , value: 0x4ec9b0ff }\n theme_color:{ tags: code_local , value: 0x9cdcfeff }\n theme_color:{ tags: code_register , value: 0xb7afd5ff }\n theme_color:{ tags: code_keyword , value: 0x569cd6ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x767676ff }\n theme_color:{ tags: code_numeric , value: 0xb5cea8ff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x7c986dff }\n theme_color:{ tags: code_string , value: 0xd69d85ff }\n theme_color:{ tags: code_meta , value: 0x9b9b9bff }\n theme_color:{ tags: code_comment , value: 0x51a644ff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffdc48ff }\n theme_color:{ tags: thread_1 , value: 0xb2ff65ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1b1baf }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x2b2b2bff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3f3f3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x333333ff }\n theme_color:{ tags: \"tab border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x171717ff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x3e4c57ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x3f386dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x7160e8ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0xffffffff}\n theme_color:{tags: \"alt background\", value: 0xefefefff}\n theme_color:{tags: \"pop background\", value: 0xe3eaf2ff}\n theme_color:{tags: \"fresh background\", value: 0xeccbbeff}\n theme_color:{tags: \"match background\", value: 0xedcbf9ff}\n theme_color:{tags: border, value: 0xe7e7e7ff}\n theme_color:{tags: text, value: 0xff}\n theme_color:{tags: \"weak text\", value: 0x353535ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xa7ffff}\n theme_color:{tags: \"focus overlay\", value: 0x8eff3f}\n theme_color:{tags: \"focus border\", value: 0x8effff}\n theme_color:{tags: cursor, value: 0xff}\n theme_color:{tags: selection, value: 0x56aaff77}\n theme_color:{tags: \"inactive background\", value: 0x17}\n theme_color:{tags: drop_shadow, value: 0xe7b27}\n theme_color:{tags: \"good_pop background\", value: 0x21a43dff}\n theme_color:{tags: \"good_pop border\", value: 0x21a43dff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0xcb3f23ff}\n theme_color:{tags: \"bad_pop text\", value: 0xffcdc4ff}\n theme_color:{tags: \"bad_pop text weak\", value: 0xffcdc4ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0x000000ff}\n theme_color:{tags: code_symbol, value: 0x74531fff}\n theme_color:{tags: code_type, value: 0x2b91afff}\n theme_color:{tags: code_local, value: 0x1f377fff}\n theme_color:{tags: code_register, value: 0x8a1bffff}\n theme_color:{tags: code_keyword, value: 0x0000ffff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff}\n theme_color:{tags: code_numeric, value: 0xff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x1d1d1dff}\n theme_color:{tags: code_string, value: 0xa61515ff}\n theme_color:{tags: code_meta, value: 0x808080ff}\n theme_color:{tags: code_comment, value: 0x008000ff}\n theme_color:{tags: line_info_0, value: 0xb5d9c8ff}\n theme_color:{tags: line_info_1, value: 0xa9c1d0ff}\n theme_color:{tags: line_info_2, value: 0x99abc5ff}\n theme_color:{tags: line_info_3, value: 0xc6bcd5ff}\n theme_color:{tags: thread_0, value: 0xffb141ff}\n theme_color:{tags: thread_1, value: 0x66c407ff}\n theme_color:{tags: thread_unwound, value: 0x67b3d7ff}\n theme_color:{tags: thread_error, value: 0xff2900ff}\n theme_color:{tags: breakpoint, value: 0xff2800ff}\n theme_color:{tags: \"floating background\", value: 0xffffffff}\n theme_color:{tags: \"floating background alt\", value: 0x11}\n theme_color:{tags: \"floating background fresh\", value: 0xa0c2d318}\n theme_color:{tags: \"floating border\", value: 0x50}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x3b3b3b5f}\n theme_color:{tags: \"floating scroll_bar border\", value: 0x5f5f5f5f}\n theme_color:{tags: \"menu_bar background\", value: 0xccd5f0ff}\n theme_color:{tags: \"menu_bar border\", value: 0xbabdc3ff}\n theme_color:{tags: \"scroll_bar background\", value: 0xe4e4e4ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0xf5cc84ff}\n theme_color:{tags: \"tab border\", value: 0xae7718ff}\n theme_color:{tags: \"tab inactive background\", value: 0x3b4f81ff}\n theme_color:{tags: \"tab inactive text\", value: 0xffffffff}\n theme_color:{tags: \"tab inactive border\", value: 0x3b4f81ff}\n theme_color:{tags: \"tab auto background\", value: 0xe99595ff}\n theme_color:{tags: \"tab auto border\", value: 0xff6262ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0xac6060ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0xff6262ff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xa7ffff}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x002a35ff}\n theme_color:{tags: \"alt background\", value: 0x053542ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x65166ff}\n theme_color:{tags: text, value: 0xeee8d5ff}\n theme_color:{tags: \"weak text\", value: 0x93a1a1ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xca4b16ff}\n theme_color:{tags: \"focus overlay\", value: 0xca4b151f}\n theme_color:{tags: \"focus border\", value: 0xca4b16ff}\n theme_color:{tags: cursor, value: 0xca4b16ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x5f8700ff}\n theme_color:{tags: \"good_pop border\", value: 0x5f8700ff}\n theme_color:{tags: \"bad_pop background\", value: 0x810000ff}\n theme_color:{tags: code_default, value: 0x839496ff}\n theme_color:{tags: code_symbol, value: 0xb3880eff}\n theme_color:{tags: code_type, value: 0xb3880eff}\n theme_color:{tags: code_local, value: 0xeee8d5ff}\n theme_color:{tags: code_register, value: 0xeee8d5ff}\n theme_color:{tags: code_keyword, value: 0x849804ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff}\n theme_color:{tags: code_numeric, value: 0x2aa198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff}\n theme_color:{tags: code_string, value: 0x2aa198ff}\n theme_color:{tags: code_meta, value: 0xca4b16ff}\n theme_color:{tags: code_comment, value: 0x586e75ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x2a3574}\n theme_color:{tags: \"floating background alt\", value: 0x4f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x53542ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x586e75ff}\n theme_color:{tags: \"tab border\", value: 0x90abb3ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x33494fff}\n theme_color:{tags: \"tab auto background\", value: 0x565ed2ff}\n theme_color:{tags: \"tab auto border\", value: 0xa2a6dfff}\n theme_color:{tags: \"tab auto inactive background\", value: 0}\n theme_color:{tags: \"tab auto inactive border\", value: 0x595fbcff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0xfdf6e3ff}\n theme_color:{tags: \"alt background\", value: 0xeee8d5ff}\n theme_color:{tags: \"pop background\", value: 0x29a19890}\n theme_color:{tags: \"fresh background\", value: 0xf7d38dff}\n theme_color:{tags: \"match background\", value: 0xdcddddff}\n theme_color:{tags: border, value: 0xd1ccbdff}\n theme_color:{tags: \"weak text\", value: 0x93a1a1ff}\n theme_color:{tags: text, value: 0x657b83ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xca4b16ff}\n theme_color:{tags: \"focus overlay\", value: 0xca4b1454}\n theme_color:{tags: \"focus border\", value: 0xca4b16ff}\n theme_color:{tags: cursor, value: 0xca4b16ff}\n theme_color:{tags: selection, value: 0x8594a264}\n theme_color:{tags: \"inactive background\", value: 0x14}\n theme_color:{tags: drop_shadow, value: 0x3a}\n theme_color:{tags: \"good_pop background\", value: 0xd1e99aff}\n theme_color:{tags: \"good_pop border\", value: 0xd1e99aff}\n theme_color:{tags: \"bad_pop background\", value: 0xd26c6cff}\n theme_color:{tags: \"bad_pop border\", value: 0xd26c6cff}\n theme_color:{tags: \"bad_pop weak text\", value: 0xffffffff}\n theme_color:{tags: \"bad_pop text\", value: 0xffffffff}\n theme_color:{tags: code_default, value: 0x839496ff}\n theme_color:{tags: code_symbol, value: 0xb3880eff}\n theme_color:{tags: code_type, value: 0xb3880eff}\n theme_color:{tags: code_local, value: 0x657b83ff}\n theme_color:{tags: code_register, value: 0x947298ff}\n theme_color:{tags: code_keyword, value: 0x849804ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff}\n theme_color:{tags: code_numeric, value: 0x2aa198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff}\n theme_color:{tags: code_string, value: 0x2aa198ff}\n theme_color:{tags: code_meta, value: 0xca4b16ff}\n theme_color:{tags: code_comment, value: 0x586e75ff}\n theme_color:{tags: line_info_0, value: 0xeee1dbff}\n theme_color:{tags: line_info_1, value: 0xe5d5b1ff}\n theme_color:{tags: line_info_2, value: 0xd9e8b6ff}\n theme_color:{tags: line_info_3, value: 0xf5d5ccff}\n theme_color:{tags: thread_0, value: 0xffa100ff}\n theme_color:{tags: thread_1, value: 0x6edd00ff}\n theme_color:{tags: thread_unwound, value: 0x708f9eff}\n theme_color:{tags: thread_error, value: 0xff5231ff}\n theme_color:{tags: breakpoint, value: 0xff411dff}\n theme_color:{tags: \"floating background\", value: 0xfdf6e3b1}\n theme_color:{tags: \"floating background alt\", value: 0x22}\n theme_color:{tags: \"floating background fresh\", value: 0xf7d38dff}\n theme_color:{tags: \"scroll_bar background\", value: 0xeee6d0ff}\n theme_color:{tags: \"scroll_bar floating background\", value: 0xd5ccb5ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0xfdf6e3ff}\n theme_color:{tags: \"tab inactive background\", value: 0xe0d6bbff}\n theme_color:{tags: \"tab auto background\", value: 0xf5cfe1ff}\n theme_color:{tags: \"tab auto border\", value: 0xa2a6dfff}\n theme_color:{tags: \"tab auto inactive background\", value: 0xc8a5b5ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x595fbcff}\n theme_color:{tags: \"drop_site background\", value: 0x29a19890}\n theme_color:{tags: \"drop_site border\", value: 0x81ddd690}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x0c0c0cff}\n theme_color:{tags: \"alt background\", value: 0x161616ff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x404040ff}\n theme_color:{tags: text, value: 0xcac1b6ff}\n theme_color:{tags: \"weak text\", value: 0xa08563ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0x7485971e}\n theme_color:{tags: \"focus border\", value: 0x5e6b79ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x2c5b36ff}\n theme_color:{tags: \"good_pop border\", value: 0x568761ff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0x803425ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0xa08563ff}\n theme_color:{tags: code_symbol, value: 0xcc5735ff}\n theme_color:{tags: code_type, value: 0xd8a51cff}\n theme_color:{tags: code_local, value: 0xd6b995ff}\n theme_color:{tags: code_register, value: 0xc04047ff}\n theme_color:{tags: code_keyword, value: 0xac7b0aff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x907553ff}\n theme_color:{tags: code_numeric, value: 0x6b8e23ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x4f681cff}\n theme_color:{tags: code_string, value: 0x6b8e23ff}\n theme_color:{tags: code_meta, value: 0xdab98fff}\n theme_color:{tags: code_comment, value: 0x686868ff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x18181980}\n theme_color:{tags: \"floating background alt\", value: 0x0000005f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating border\", value: 0xbfbfbf1f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0x3b3b3b5f}\n theme_color:{tags: \"floating scroll_bar border\", value: 0x5f5f5f5f}\n theme_color:{tags: \"menu_bar background\", value: 0x1f1f27ff}\n theme_color:{tags: \"menu_bar border\", value: 0x3d3d47ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x2b2b2bff}\n theme_color:{tags: \"scroll_bar border\", value: 0x3f3f3fff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab border\", value: 0x3d3d47ff}\n theme_color:{tags: \"tab text\", value: 0xca9301ff}\n theme_color:{tags: \"tab text weak\", value: 0x8c690eff}\n theme_color:{tags: \"tab inactive background\", value: 0x171718ff}\n theme_color:{tags: \"tab inactive border\", value: 0x1f1f27ff}\n theme_color:{tags: \"tab auto background\", value: 0x243b38ff}\n theme_color:{tags: \"tab auto border\", value: 0x478980ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x102623ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x1e5850ff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x042327ff}\n theme_color:{tags: \"alt background\", value: 0x11b1fff}\n theme_color:{tags: \"pop background\", value: 0x355b6eff}\n theme_color:{tags: \"pop text\", value: 0xbad7e6ff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x334d50ff}\n theme_color:{tags: text, value: 0xdad3beff}\n theme_color:{tags: \"weak text\", value: 0xb0a688ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: \"menu_bar good text\", value: 0x2a8242ff}\n theme_color:{tags: \"menu_bar neutral text\", value: 0x5681ff}\n theme_color:{tags: \"menu_bar bad text\", value: 0xa21200ff}\n theme_color:{tags: \"menu_bar weak text\", value: 0x313131ff}\n theme_color:{tags: \"menu_bar bad_pop text weak\", value: 0xffffffff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0x86e08e20}\n theme_color:{tags: \"focus border\", value: 0x86e08fff}\n theme_color:{tags: cursor, value: 0x86e08fff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x2c5b36ff}\n theme_color:{tags: \"good_pop border\", value: 0x568761ff}\n theme_color:{tags: \"good_pop hover\", value: 0xe3f5d3ff}\n theme_color:{tags: \"good_pop weak text\", value: 0xe3f5d3ff}\n theme_color:{tags: \"bad_pop background\", value: 0x803425ff}\n theme_color:{tags: \"bad_pop hover\", value: 0xff825cff}\n theme_color:{tags: code_default, value: 0xbdb395ff}\n theme_color:{tags: code_symbol, value: 0xcbe0f5ff}\n theme_color:{tags: code_type, value: 0xcbe0f5ff}\n theme_color:{tags: code_local, value: 0xd9cfb3ff}\n theme_color:{tags: code_register, value: 0xb7afd5ff}\n theme_color:{tags: code_keyword, value: 0x9de3c0ff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x767676ff}\n theme_color:{tags: code_numeric, value: 0x2ca198ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x217770ff}\n theme_color:{tags: code_string, value: 0x2ca198ff}\n theme_color:{tags: code_meta, value: 0xB0FFB0ff}\n theme_color:{tags: code_comment, value: 0x31b72cff}\n theme_color:{tags: line_info_0, value: 0x4f3022ff}\n theme_color:{tags: line_info_1, value: 0x4f3e15ff}\n theme_color:{tags: line_info_2, value: 0x434e2aff}\n theme_color:{tags: line_info_3, value: 0x36241fff}\n theme_color:{tags: thread_0, value: 0xffcb7fff}\n theme_color:{tags: thread_1, value: 0xb2ff65ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"floating background\", value: 0x3232792}\n theme_color:{tags: \"floating background alt\", value: 0x0000005f}\n theme_color:{tags: \"floating background fresh\", value: 0x31393d5f}\n theme_color:{tags: \"floating scroll_bar background\", value: 0xe363bff}\n theme_color:{tags: \"menu_bar background\", value: 0xb59e7aff}\n theme_color:{tags: \"menu_bar text\", value: 0xff}\n theme_color:{tags: \"menu_bar border\", value: 0x947d5aff}\n theme_color:{tags: \"scroll_bar background\", value: 0xe363bff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x13533aff}\n theme_color:{tags: \"tab border\", value: 0x6c9182ff}\n theme_color:{tags: \"tab inactive background\", value: 0x0}\n theme_color:{tags: \"tab inactive border\", value: 0x947d5a6c}\n theme_color:{tags: \"tab auto background\", value: 0x5b3939ff}\n theme_color:{tags: \"tab auto border\", value: 0x875c5cff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x251b1bff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x563d3dff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{tags: background,value: 0xc0c0cff}\n theme_color:{tags: \"alt background\", value: 0x131313ff}\n theme_color:{tags: \"pop background\", value: 0x4c00ff}\n theme_color:{tags: \"fresh background\", value: 0x4c00ff}\n theme_color:{tags: \"match background\", value: 0x4c00ff}\n theme_color:{tags: border, value: 0x272727ff}\n theme_color:{tags: text, value: 0x90b080ff}\n theme_color:{tags: \"weak text\", value: 0x6b845fff}\n theme_color:{tags: \"menu_bar background\", value: 0x888888ff}\n theme_color:{tags: \"menu_bar text\", value: 0x20202ff}\n theme_color:{tags: \"menu_bar text weak\", value: 0x525252ff}\n theme_color:{tags: \"good text\", value: 0x32a852ff}\n theme_color:{tags: \"neutral text\", value: 0x3a90bbff}\n theme_color:{tags: \"bad text\", value: 0xcf5242ff}\n theme_color:{tags: hover, value: 0xee00ff}\n theme_color:{tags: \"focus overlay\", value: 0xee0012}\n theme_color:{tags: \"focus border\", value: 0x00ee00ff}\n theme_color:{tags: cursor, value: 0x00ee00ff}\n theme_color:{tags: selection, value: 0x99ccff0f}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x4900ff}\n theme_color:{tags: \"good_pop border\", value: 0x4900ff}\n theme_color:{tags: \"bad_pop background\", value: 0x430b00ff}\n theme_color:{tags: code_default, value: 0x90b080ff}\n theme_color:{tags: code_symbol, value: 0xbfd9b2ff}\n theme_color:{tags: code_type, value: 0xbfd9b2ff}\n theme_color:{tags: code_local, value: 0xbfd9b2ff}\n theme_color:{tags: code_register, value: 0xb84cffff}\n theme_color:{tags: code_keyword, value: 0xd08f1fff}\n theme_color:{tags: code_delimiter_or_operator, value: 0x90b080ff}\n theme_color:{tags: code_numeric, value: 0x50ff2fff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0x30af18ff}\n theme_color:{tags: code_string, value: 0x50ff2fff}\n theme_color:{tags: code_meta, value: 0x90b080ff}\n theme_color:{tags: code_comment, value: 0x1f90f0ff}\n theme_color:{tags: line_info_0, value: 0xa253dff}\n theme_color:{tags: line_info_1, value: 0x9103dff}\n theme_color:{tags: line_info_2, value: 0x1e083dff}\n theme_color:{tags: line_info_3, value: 0x1e083dff}\n theme_color:{tags: thread_0, value: 0xd08f1fff}\n theme_color:{tags: thread_1, value: 0x1ea5d0ff}\n theme_color:{tags: thread_unwound, value: 0xb2ccd8ff}\n theme_color:{tags: thread_error, value: 0xb23219ff}\n theme_color:{tags: breakpoint, value: 0xa72911ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x1d1d1dff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x15490cff}\n theme_color:{tags: \"tab border\", value: 0x15490cff}\n theme_color:{tags: \"tab text\", value: 0x90b080ff}\n theme_color:{tags: \"tab text weak\", value: 0x90b080ff}\n theme_color:{tags: \"tab inactive background\", value: 0x21321eff}\n theme_color:{tags: \"tab inactive border\", value: 0x21321eff}\n theme_color:{tags: \"tab auto background\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto border\", value: 0x674f3eff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x47382eff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x47382eff}\n theme_color:{tags: \"drop_site background\", value: 0xffffff05}\n theme_color:{tags: \"drop_site border\", value: 0xffffff0f}\n}\n"), str8_lit_comp("theme:\n{\n theme_color:{ tags: background , value: 0x1b1f22ff }\n theme_color:{ tags: \"alt background\" , value: 0x232929ff }\n theme_color:{ tags: \"pop background\" , value: 0x2f4838ff }\n theme_color:{ tags: \"fresh background\" , value: 0x31393dff }\n theme_color:{ tags: \"match background\" , value: 0x31393dff }\n theme_color:{ tags: border , value: 0x485347ff }\n theme_color:{ tags: text , value: 0xffffffff }\n theme_color:{ tags: \"weak text\" , value: 0xa2a2a2ff }\n theme_color:{ tags: \"good text\" , value: 0x32a852ff }\n theme_color:{ tags: \"neutral text\" , value: 0x3a90bbff }\n theme_color:{ tags: \"bad text\" , value: 0xcf5242ff }\n theme_color:{ tags: hover , value: 0xffffffff }\n theme_color:{ tags: \"focus overlay\" , value: 0xfda20012 }\n theme_color:{ tags: \"focus border\" , value: 0xfda200ff }\n theme_color:{ tags: cursor , value: 0x8aff00ff }\n theme_color:{ tags: selection , value: 0x99ccff0f }\n theme_color:{ tags: \"inactive background\" , value: 0x0 }\n theme_color:{ tags: drop_shadow , value: 0x0000007f }\n theme_color:{ tags: \"good_pop background\" , value: 0x2c5b36ff }\n theme_color:{ tags: \"good_pop border\" , value: 0x568761ff }\n theme_color:{ tags: \"good_pop hover\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"good_pop weak text\" , value: 0xe3f5d3ff }\n theme_color:{ tags: \"bad_pop background\" , value: 0x803425ff }\n theme_color:{ tags: \"bad_pop hover\" , value: 0xff825cff }\n theme_color:{ tags: code_default , value: 0xad8b69ff }\n theme_color:{ tags: code_symbol , value: 0x87ad6aff }\n theme_color:{ tags: code_type , value: 0xb67474ff }\n theme_color:{ tags: code_local , value: 0xe9bf95ff }\n theme_color:{ tags: code_register , value: 0xa688b2ff }\n theme_color:{ tags: code_keyword , value: 0xe49e17ff }\n theme_color:{ tags: code_delimiter_or_operator , value: 0x795e43ff }\n theme_color:{ tags: code_numeric , value: 0x98b19eff }\n theme_color:{ tags: code_numeric_alt_digit_group , value: 0x688b71ff }\n theme_color:{ tags: code_string , value: 0x98b19eff }\n theme_color:{ tags: code_meta , value: 0xad5979ff }\n theme_color:{ tags: code_comment , value: 0x52675dff }\n theme_color:{ tags: line_info_0 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_1 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_2 , value: 0x434e2aff }\n theme_color:{ tags: line_info_3 , value: 0x36241fff }\n theme_color:{ tags: line_info_4 , value: 0x4f3022ff }\n theme_color:{ tags: line_info_5 , value: 0x4f3e15ff }\n theme_color:{ tags: line_info_6 , value: 0x434e2aff }\n theme_color:{ tags: line_info_7 , value: 0x36241fff }\n theme_color:{ tags: thread_0 , value: 0xffc258ff }\n theme_color:{ tags: thread_1 , value: 0x82d331ff }\n theme_color:{ tags: thread_2 , value: 0xff99e5ff }\n theme_color:{ tags: thread_3 , value: 0x6598ffff }\n theme_color:{ tags: thread_4 , value: 0x65ffcbff }\n theme_color:{ tags: thread_5 , value: 0xff9819ff }\n theme_color:{ tags: thread_6 , value: 0x9932ffff }\n theme_color:{ tags: thread_7 , value: 0x65ff4cff }\n theme_color:{ tags: thread_unwound , value: 0xb2ccd8ff }\n theme_color:{ tags: thread_error , value: 0xb23219ff }\n theme_color:{ tags: breakpoint , value: 0xa72911ff }\n theme_color:{ tags: \"floating background\" , value: 0x1b1f2276 }\n theme_color:{ tags: \"floating background alt\" , value: 0x0000005f }\n theme_color:{ tags: \"floating background fresh\" , value: 0x31393d5f }\n theme_color:{ tags: \"floating border\" , value: 0xbfbfbf1f }\n theme_color:{ tags: \"floating scroll_bar background\" , value: 0x3b3b3b5f }\n theme_color:{ tags: \"floating scroll_bar border\" , value: 0x5f5f5f5f }\n theme_color:{ tags: \"menu_bar background\" , value: 0x243d32ff }\n theme_color:{ tags: \"menu_bar border\" , value: 0x597b63ff }\n theme_color:{ tags: \"scroll_bar background\" , value: 0x232929ff }\n theme_color:{ tags: \"scroll_bar border\" , value: 0x3c4a3fff }\n theme_color:{ tags: \"implicit background\" , value: 0x00000000 }\n theme_color:{ tags: \"implicit border\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow background\" , value: 0x00000000 }\n theme_color:{ tags: \"hollow border\" , value: 0xffffff1f }\n theme_color:{ tags: \"tab background\" , value: 0x243d32ff }\n theme_color:{ tags: \"tab border\" , value: 0x597b63ff }\n theme_color:{ tags: \"tab inactive background\" , value: 0x30383eff }\n theme_color:{ tags: \"tab inactive border\" , value: 0x6b7680ff }\n theme_color:{ tags: \"tab auto background\" , value: 0x30636dff }\n theme_color:{ tags: \"tab auto border\" , value: 0x768f94ff }\n theme_color:{ tags: \"tab auto inactive background\" , value: 0x2f2633ff }\n theme_color:{ tags: \"tab auto inactive border\" , value: 0x685073ff }\n theme_color:{ tags: \"drop_site background\" , value: 0xffffff05 }\n theme_color:{ tags: \"drop_site border\" , value: 0xffffff0f }\n}\n"), -str8_lit_comp(""), +str8_lit_comp("theme:\n{\n theme_color:{tags: background, value: 0x000080ff}\n theme_color:{tags: \"pop background\", value: 0x8080ff}\n theme_color:{tags: \"fresh background\", value: 0x31393dff}\n theme_color:{tags: \"match background\", value: 0x31393dff}\n theme_color:{tags: border, value: 0x8080ff}\n theme_color:{tags: text, value: 0xffffffff}\n theme_color:{tags: \"weak text\", value: 0xffffffff}\n theme_color:{tags: \"good text\", value: 0x00ff00ff}\n theme_color:{tags: \"neutral text\", value: 0x00ffffff}\n theme_color:{tags: \"bad text\", value: 0xff0000ff}\n theme_color:{tags: hover, value: 0xffffffff}\n theme_color:{tags: \"focus overlay\", value: 0xffff0012}\n theme_color:{tags: \"focus border\", value: 0xffff00ff}\n theme_color:{tags: cursor, value: 0xffff00ff}\n theme_color:{tags: selection, value: 0xffff0018}\n theme_color:{tags: \"inactive background\", value: 0x0000002f}\n theme_color:{tags: drop_shadow, value: 0x0000007f}\n theme_color:{tags: \"good_pop background\", value: 0x6c17ff}\n theme_color:{tags: \"good_pop border\", value: 0x6c17ff}\n theme_color:{tags: \"bad_pop background\", value: 0xff0000ff}\n theme_color:{tags: code_default, value: 0xffffffff}\n theme_color:{tags: code_symbol, value: 0xffffff}\n theme_color:{tags: code_type, value: 0x00ff00ff}\n theme_color:{tags: code_local, value: 0x00ffffff}\n theme_color:{tags: code_register, value: 0xff00ffff}\n theme_color:{tags: code_keyword, value: 0xffffffff}\n theme_color:{tags: code_delimiter_or_operator, value: 0xffffffff}\n theme_color:{tags: code_numeric, value: 0xffff00ff}\n theme_color:{tags: code_numeric_alt_digit_group, value: 0xffff00ff}\n theme_color:{tags: code_string, value: 0xffff00ff}\n theme_color:{tags: code_meta, value: 0xff0000ff}\n theme_color:{tags: code_comment, value: 0x008080ff}\n theme_color:{tags: line_info_0, value: 0x8080ff}\n theme_color:{tags: line_info_1, value: 0x800080ff}\n theme_color:{tags: line_info_2, value: 0x800000ff}\n theme_color:{tags: line_info_3, value: 0x08000ff}\n theme_color:{tags: thread_0, value: 0xffff00ff}\n theme_color:{tags: thread_1, value: 0x00ff00ff}\n theme_color:{tags: thread_unwound, value: 0x00ffffff}\n theme_color:{tags: thread_error, value: 0xff0000ff}\n theme_color:{tags: breakpoint, value: 0xff0000ff}\n theme_color:{tags: \"menu_bar background\", value: 0x008080ff}\n theme_color:{tags: \"menu_bar border\", value: 0x8080ff}\n theme_color:{tags: \"scroll_bar background\", value: 0x008080ff}\n theme_color:{tags: \"implicit background\", value: 0x00000000}\n theme_color:{tags: \"implicit border\", value: 0x00000000}\n theme_color:{tags: \"hollow background\", value: 0x00000000}\n theme_color:{tags: \"hollow border\", value: 0xffffff1f}\n theme_color:{tags: \"tab background\", value: 0x8080ff}\n theme_color:{tags: \"tab border\", value: 0x8080ff}\n theme_color:{tags: \"tab inactive background\", value:0}\n theme_color:{tags: \"tab auto background\", value: 0x800000ff}\n theme_color:{tags: \"tab auto border\", value: 0x8080ff}\n theme_color:{tags: \"tab auto inactive background\", value: 0x300000ff}\n theme_color:{tags: \"tab auto inactive border\", value: 0x8080ff}\n theme_color:{tags: \"drop_site background\", value: 0x80ff}\n theme_color:{tags: \"drop_site border\", value: 0xffffff}\n}\n"), }; C_LINKAGE_END diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9434beed..db258abe 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1798,8 +1798,75 @@ RD_ThemePresetTable: ``` } - //- rjf: todo - { SolarizedLight solarized_light "Solarized (Light)" } + //- rjf: solarized light + { SolarizedLight solarized_light "Solarized (Light)", + ```theme: + { + theme_color:{tags: background, value: 0xfdf6e3ff} + theme_color:{tags: "alt background", value: 0xeee8d5ff} + theme_color:{tags: "pop background", value: 0x29a19890} + theme_color:{tags: "fresh background", value: 0xf7d38dff} + theme_color:{tags: "match background", value: 0xdcddddff} + theme_color:{tags: border, value: 0xd1ccbdff} + theme_color:{tags: "weak text", value: 0x93a1a1ff} + theme_color:{tags: text, value: 0x657b83ff} + theme_color:{tags: "good text", value: 0x32a852ff} + theme_color:{tags: "neutral text", value: 0x3a90bbff} + theme_color:{tags: "bad text", value: 0xcf5242ff} + theme_color:{tags: hover, value: 0xca4b16ff} + theme_color:{tags: "focus overlay", value: 0xca4b1454} + theme_color:{tags: "focus border", value: 0xca4b16ff} + theme_color:{tags: cursor, value: 0xca4b16ff} + theme_color:{tags: selection, value: 0x8594a264} + theme_color:{tags: "inactive background", value: 0x14} + theme_color:{tags: drop_shadow, value: 0x3a} + theme_color:{tags: "good_pop background", value: 0xd1e99aff} + theme_color:{tags: "good_pop border", value: 0xd1e99aff} + theme_color:{tags: "bad_pop background", value: 0xd26c6cff} + theme_color:{tags: "bad_pop border", value: 0xd26c6cff} + theme_color:{tags: "bad_pop weak text", value: 0xffffffff} + theme_color:{tags: "bad_pop text", value: 0xffffffff} + theme_color:{tags: code_default, value: 0x839496ff} + theme_color:{tags: code_symbol, value: 0xb3880eff} + theme_color:{tags: code_type, value: 0xb3880eff} + theme_color:{tags: code_local, value: 0x657b83ff} + theme_color:{tags: code_register, value: 0x947298ff} + theme_color:{tags: code_keyword, value: 0x849804ff} + theme_color:{tags: code_delimiter_or_operator, value: 0x839496ff} + theme_color:{tags: code_numeric, value: 0x2aa198ff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0x19766bff} + theme_color:{tags: code_string, value: 0x2aa198ff} + theme_color:{tags: code_meta, value: 0xca4b16ff} + theme_color:{tags: code_comment, value: 0x586e75ff} + theme_color:{tags: line_info_0, value: 0xeee1dbff} + theme_color:{tags: line_info_1, value: 0xe5d5b1ff} + theme_color:{tags: line_info_2, value: 0xd9e8b6ff} + theme_color:{tags: line_info_3, value: 0xf5d5ccff} + theme_color:{tags: thread_0, value: 0xffa100ff} + theme_color:{tags: thread_1, value: 0x6edd00ff} + theme_color:{tags: thread_unwound, value: 0x708f9eff} + theme_color:{tags: thread_error, value: 0xff5231ff} + theme_color:{tags: breakpoint, value: 0xff411dff} + theme_color:{tags: "floating background", value: 0xfdf6e3b1} + theme_color:{tags: "floating background alt", value: 0x22} + theme_color:{tags: "floating background fresh", value: 0xf7d38dff} + theme_color:{tags: "scroll_bar background", value: 0xeee6d0ff} + theme_color:{tags: "scroll_bar floating background", value: 0xd5ccb5ff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0xfdf6e3ff} + theme_color:{tags: "tab inactive background", value: 0xe0d6bbff} + theme_color:{tags: "tab auto background", value: 0xf5cfe1ff} + theme_color:{tags: "tab auto border", value: 0xa2a6dfff} + theme_color:{tags: "tab auto inactive background", value: 0xc8a5b5ff} + theme_color:{tags: "tab auto inactive border", value: 0x595fbcff} + theme_color:{tags: "drop_site background", value: 0x29a19890} + theme_color:{tags: "drop_site border", value: 0x81ddd690} + } + ``` + } //- rjf: handmade hero theme { HandmadeHero handmade_hero "Handmade Hero", @@ -2119,7 +2186,69 @@ RD_ThemePresetTable: } //- rjf: todo - { FarManager far_manager "Far Manager" } + { FarManager far_manager "Far Manager", + ```theme: + { + theme_color:{tags: background, value: 0x000080ff} + theme_color:{tags: "pop background", value: 0x8080ff} + theme_color:{tags: "fresh background", value: 0x31393dff} + theme_color:{tags: "match background", value: 0x31393dff} + theme_color:{tags: border, value: 0x8080ff} + theme_color:{tags: text, value: 0xffffffff} + theme_color:{tags: "weak text", value: 0xffffffff} + theme_color:{tags: "good text", value: 0x00ff00ff} + theme_color:{tags: "neutral text", value: 0x00ffffff} + theme_color:{tags: "bad text", value: 0xff0000ff} + theme_color:{tags: hover, value: 0xffffffff} + theme_color:{tags: "focus overlay", value: 0xffff0012} + theme_color:{tags: "focus border", value: 0xffff00ff} + theme_color:{tags: cursor, value: 0xffff00ff} + theme_color:{tags: selection, value: 0xffff0018} + theme_color:{tags: "inactive background", value: 0x0000002f} + theme_color:{tags: drop_shadow, value: 0x0000007f} + theme_color:{tags: "good_pop background", value: 0x6c17ff} + theme_color:{tags: "good_pop border", value: 0x6c17ff} + theme_color:{tags: "bad_pop background", value: 0xff0000ff} + theme_color:{tags: code_default, value: 0xffffffff} + theme_color:{tags: code_symbol, value: 0xffffff} + theme_color:{tags: code_type, value: 0x00ff00ff} + theme_color:{tags: code_local, value: 0x00ffffff} + theme_color:{tags: code_register, value: 0xff00ffff} + theme_color:{tags: code_keyword, value: 0xffffffff} + theme_color:{tags: code_delimiter_or_operator, value: 0xffffffff} + theme_color:{tags: code_numeric, value: 0xffff00ff} + theme_color:{tags: code_numeric_alt_digit_group, value: 0xffff00ff} + theme_color:{tags: code_string, value: 0xffff00ff} + theme_color:{tags: code_meta, value: 0xff0000ff} + theme_color:{tags: code_comment, value: 0x008080ff} + theme_color:{tags: line_info_0, value: 0x8080ff} + theme_color:{tags: line_info_1, value: 0x800080ff} + theme_color:{tags: line_info_2, value: 0x800000ff} + theme_color:{tags: line_info_3, value: 0x08000ff} + theme_color:{tags: thread_0, value: 0xffff00ff} + theme_color:{tags: thread_1, value: 0x00ff00ff} + theme_color:{tags: thread_unwound, value: 0x00ffffff} + theme_color:{tags: thread_error, value: 0xff0000ff} + theme_color:{tags: breakpoint, value: 0xff0000ff} + theme_color:{tags: "menu_bar background", value: 0x008080ff} + theme_color:{tags: "menu_bar border", value: 0x8080ff} + theme_color:{tags: "scroll_bar background", value: 0x008080ff} + theme_color:{tags: "implicit background", value: 0x00000000} + theme_color:{tags: "implicit border", value: 0x00000000} + theme_color:{tags: "hollow background", value: 0x00000000} + theme_color:{tags: "hollow border", value: 0xffffff1f} + theme_color:{tags: "tab background", value: 0x8080ff} + theme_color:{tags: "tab border", value: 0x8080ff} + theme_color:{tags: "tab inactive background", value:0} + theme_color:{tags: "tab auto background", value: 0x800000ff} + theme_color:{tags: "tab auto border", value: 0x8080ff} + theme_color:{tags: "tab auto inactive background", value: 0x300000ff} + theme_color:{tags: "tab auto inactive border", value: 0x8080ff} + theme_color:{tags: "drop_site background", value: 0x80ff} + theme_color:{tags: "drop_site border", value: 0xffffff} + } + ``` + } } @table(name lower_name) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index cc0a8a57..51b0f05c 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -216,7 +216,6 @@ // [ ] autocompletion lister // [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs // (actually, just kill the tabs on load if they refer to transient things) -// [ ] finish theme editing, build themes - replace code colors map with new theme stuff // // [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty @@ -530,6 +529,7 @@ // [x] "pop out" (hitting enter on visualizers should open them as tabs) // [x] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // [x] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop +// [x] finish theme editing, build themes - replace code colors map with new theme stuff //////////////////////////////// //~ rjf: Build Options From 848f144ab976a8cefebb029052c207cdfeb34968 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 14:42:27 -0700 Subject: [PATCH 600/755] distinguish between expr strings and code strings in schemas; use normal autocompletion in meta-evaluation spaces only when editing expr strings, whereas code strings you want to look like code but do not generally refer to things that expressions can, e.g. it is a label --- src/raddbg/generated/raddbg.meta.c | 22 ++++++++--------- src/raddbg/raddbg.mdesk | 38 +++++++++++++++--------------- src/raddbg/raddbg_core.c | 28 ++++++++++++++++------ src/raddbg/raddbg_eval.c | 3 ++- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 125914fd..2669a578 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -411,19 +411,19 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': code_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': code_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': code_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': code_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': code_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': code_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': code_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': code_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, -{str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': code_string,\n}\n")}, -{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': code_string,\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, +{str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, +{str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': string,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': code_string,\n 'source_location': string,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, -{str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}")}, +{str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index db258abe..5851ebe6 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -448,7 +448,7 @@ RD_VocabTable: 'row_height': @range[1.75f, 5.f] f32, 'label': code_string, @description("The root expression which is evaluated to produce the watch window.") - 'expression': code_string, + 'expression': expr_string, @no_expand 'watches': query, } ``` @@ -459,7 +459,7 @@ RD_VocabTable: @inherit(tab) x: { @description("An expression to describe data which should be viewed as text or code.") - 'expression': code_string, + 'expression': expr_string, @description("The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.") 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") @@ -475,10 +475,10 @@ RD_VocabTable: @inherit(tab) x: { @description("An expression to describe the base address or offset of the disassembly.") - 'expression': code_string, + 'expression': expr_string, 'arch': code_string, 'syntax': code_string, - 'size': code_string, + 'size': expr_string, @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") 'show_addresses': bool, @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") @@ -498,11 +498,11 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Base Address") @description("An expression to describe the base address or offset of the memory view.") - 'expression': code_string, + 'expression': expr_string, @display_name("Address Range Size") @description("The number of bytes of the viewed memory range.") - 'size': code_string, + 'size': expr_string, @display_name("Cursor Address") @description("The address of the cursor.") - 'cursor': code_string, + 'cursor': expr_string, @display_name("Cursor Size") @description("The size, in bytes, of the cursor.") 'cursor_size': @range[1, 16] u64, @default(16) @description("The number of columns to build before building new rows.") @@ -516,7 +516,7 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Base Pointer") @description("An expression to describe the base address or offset of the bitmap data.") - 'expression': code_string, + 'expression': expr_string, @order(0) 'w': u64, @order(1) 'h': u64, @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") @@ -530,7 +530,7 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Value") @description("An expression to describe the value or location of the color.") - 'expression': code_string, + 'expression': expr_string, } ``` } @@ -540,10 +540,10 @@ RD_VocabTable: @inherit(tab) x: { @display_name("Expression") @description("An expression to describe the base address of the index buffer.") - 'expression': code_string, - 'count': code_string, - 'vtx': code_string, - 'vtx_size': code_string, + 'expression': expr_string, + 'count': expr_string, + 'vtx': expr_string, + 'vtx_size': expr_string, 'yaw': @range[0, 1] f32, 'pitch': @range[-0.5, 0] f32, 'zoom': @range[0, 100] f32, @@ -573,7 +573,7 @@ RD_VocabTable: 'executable': path, 'arguments': string, 'working_directory': path, - 'entry_point': code_string, + 'entry_point': expr_string, 'stdout_path': path, 'stderr_path': path, 'stdin_path': path, @@ -593,9 +593,9 @@ RD_VocabTable: x: { 'label': code_string, - 'condition': code_string, + 'condition': expr_string, 'source_location': string, - 'address_location': code_string, + 'address_location': expr_string, 'hit_count': u64, 'address_range_size': @or(0, 1, 2, 4, 8) u64, 'break_on_write': bool, @@ -614,9 +614,9 @@ RD_VocabTable: @collection_commands(add_watch_pin, toggle_watch_pin) x: { - 'expression': code_string, + 'expression': expr_string, 'source_location': string, - 'address_location': code_string, + 'address_location': expr_string, } ```, } @@ -630,7 +630,7 @@ RD_VocabTable: //- rjf: type views { type_view, - ```@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':code_string, 'expr':code_string}```, + ```@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}```, } //- rjf: recent projects diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bbc2a650..20dd15e7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1846,6 +1846,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path"), 0) || str8_match(child_type_name, str8_lit("code_string"), 0) || + str8_match(child_type_name, str8_lit("expr_string"), 0) || str8_match(child_type_name, str8_lit("string"), 0)) { read_data = cfg->first->string; @@ -9736,18 +9737,31 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) String8 list_expr = str8_lit("query:locals, query:globals, query:thread_locals, query:procedures, query:types"); { E_TypeKey maybe_enum_type = e_type_key_unwrap(dst_eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative & ~E_TypeUnwrapFlag_Enums); - if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg && str8_match(e_string_from_id(dst_eval.space.u64s[1]), str8_lit("theme"), 0)) + if(dst_eval.space.kind == RD_EvalSpaceKind_MetaCfg) { - list_expr = str8_lit("query:themes"); - expr_based_replace = 0; - force_allow = 1; + RD_Cfg *parent = rd_cfg_from_eval_space(dst_eval.space); + String8 child_key = e_string_from_id(dst_eval.space.u64s[1]); + MD_NodePtrList schemas = rd_schemas_from_name(parent->string); + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; n != 0 && md_node_is_nil(child_schema); n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } + if(str8_match(child_key, str8_lit("theme"), 0)) + { + list_expr = str8_lit("query:themes"); + expr_based_replace = 0; + force_allow = 1; + } + else if(!str8_match(child_schema->first->string, str8_lit("expr_string"), 0)) + { + MemoryZeroStruct(&list_expr); + } } -#if 0 else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) { - list_expr = e_type_string_from_key(arena, maybe_enum_type); + list_expr = e_type_string_from_key(scratch.arena, maybe_enum_type); } -#endif } // rjf: determine if autocompletion lister is allowed diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 84df2423..6317af59 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -322,7 +322,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) } //- rjf: cfg members - else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0)) + else if(str8_match(child_schema->first->string, str8_lit("code_string"), 0) || + str8_match(child_schema->first->string, str8_lit("expr_string"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); } From b902b0a5b387fcb61bb66b574bf579f95a5ac1b3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 15:21:01 -0700 Subject: [PATCH 601/755] animation setting coverage --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 14 +-- src/raddbg/raddbg_core.c | 152 +++++++++++++++++------------ src/raddbg/raddbg_core.h | 9 ++ src/raddbg/raddbg_eval.c | 37 ++++--- src/raddbg/raddbg_main.c | 7 +- src/raddbg/raddbg_widgets.c | 6 +- src/ui/ui_core.c | 16 +-- src/ui/ui_core.h | 19 ++-- 9 files changed, 151 insertions(+), 111 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 2669a578..bd4a3c0e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -406,7 +406,7 @@ RD_VocabInfo rd_vocab_info_table[340] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @default(1) 'hover_animations': bool,\n @default(1) 'press_animations': bool,\n @default(0) 'focus_animations': bool,\n @default(1) 'tooltip_animations': bool,\n @default(1) 'menu_animations': bool,\n @default(1) 'scrolling_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5851ebe6..1f600f20 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -223,12 +223,14 @@ RD_VocabTable: @expand_commands(edit_user_theme) x: { //- rjf: animations - @default(1) 'hover_animations': bool, - @default(1) 'press_animations': bool, - @default(0) 'focus_animations': bool, - @default(1) 'tooltip_animations': bool, - @default(1) 'menu_animations': bool, - @default(1) 'scrolling_animations': bool, + @display_name('Animations') @description("Enables animations.") + @default(1) 'animations': bool, + @display_name('Scrolling Animations') @description("Enables scrolling animations.") + @expand_if("$.animations") @default(1) 'scrolling_animations': bool, + @display_name('Tooltip Animations') @description("Enables tooltip animations.") + @expand_if("$.animations") @default(1) 'tooltip_animations': bool, + @display_name('Menu Animations') @description("Enables menu animations.") + @expand_if("$.animations") @default(1) 'menu_animations': bool, //- rjf: fonts @display_name('UI Font') @description("The name of, or path to, the font used when displaying non-code UI elements.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 20dd15e7..ac4fdbf0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2560,7 +2560,11 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); String8 current_input = input_root->first->string; B32 search_row_is_open = (vs->query_is_selected); - F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open, .epsilon = 0.01f); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), + (F32)!!search_row_is_open, + .initial = (F32)!!search_row_is_open, + .epsilon = 0.01f, + .rate = rd_state->menu_animation_rate); if(search_row_open_t > 0.001f) { String8 cmd_name = cmd_root->first->string; @@ -6116,12 +6120,12 @@ rd_window_frame(void) // rjf: build animation info UI_AnimationInfo animation_info = {0}; { - if(rd_setting_b32_from_name(str8_lit("hover_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_HotAnimations;} - if(rd_setting_b32_from_name(str8_lit("press_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ActiveAnimations;} - if(rd_setting_b32_from_name(str8_lit("focus_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_FocusAnimations;} - if(rd_setting_b32_from_name(str8_lit("tooltip_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_TooltipAnimations;} - if(rd_setting_b32_from_name(str8_lit("menu_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ContextMenuAnimations;} - if(rd_setting_b32_from_name(str8_lit("scrolling_animations"))) {animation_info.flags |= UI_AnimationInfoFlag_ScrollingAnimations;} + animation_info.hot_animation_rate = rd_state->catchall_animation_rate; + animation_info.active_animation_rate = rd_state->catchall_animation_rate; + animation_info.focus_animation_rate = 1.f; + animation_info.tooltip_animation_rate = rd_state->tooltip_animation_rate; + animation_info.menu_animation_rate = rd_state->menu_animation_rate; + animation_info.scroll_animation_rate = rd_state->scrolling_animation_rate; } // rjf: begin & push initial stack values @@ -7000,7 +7004,11 @@ rd_window_frame(void) F32 query_height_px = max_query_height_px; if(size_query_by_expr_eval) { - F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!vs->query_is_selected, .initial = (F32)!!vs->query_is_selected, .epsilon = 0.01f); + F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), + (F32)!!vs->query_is_selected, + .initial = (F32)!!vs->query_is_selected, + .epsilon = 0.01f, + .rate = rd_state->menu_animation_rate); query_height_px = row_height_px * (predicted_block_tree.total_row_count - !root_is_explicit) + ui_top_px_height()*search_row_open_t; query_height_px = Min(query_height_px, max_query_height_px); } @@ -7045,8 +7053,8 @@ rd_window_frame(void) UI_TagF("floating") UI_Focus(ui_any_ctx_menu_is_open() || ws->menu_bar_focused ? UI_FocusKind_Off : UI_FocusKind_Null) { - F32 fast_open_rate = 1 - pow_f32(2, (-70.f * ui_state->animation_dt)); - F32 slow_open_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + F32 fast_open_rate = rd_state->menu_animation_rate; + F32 slow_open_rate = rd_state->menu_animation_rate__slow; for(FloatingViewTask *t = first_floating_view_task; t != 0; t = t->next) { // rjf: unpack @@ -7055,7 +7063,10 @@ rd_window_frame(void) B32 is_focused = t->is_focused; B32 is_anchored = t->is_anchored; B32 only_secondary_navigation = t->only_secondary_navigation; - F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, .rate = is_anchored ? fast_open_rate : slow_open_rate, .reset = t->reset_open, .initial = 0.f); + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "floating_view_open_%p", view), 1.f, + .rate = is_anchored ? fast_open_rate : slow_open_rate, + .reset = t->reset_open, + .initial = 0.f); // rjf: force rect inside window if needed if(t->force_inside_window) @@ -8003,7 +8014,7 @@ rd_window_frame(void) // rjf: build UI_Box *site_box = &ui_nil_box; { - F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f, .rate = rd_state->menu_animation_rate); UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); @@ -8047,10 +8058,10 @@ rd_window_frame(void) Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); Rng2F32 future_split_rect = { - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), }; UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { @@ -8094,7 +8105,7 @@ rd_window_frame(void) // rjf: build UI_Box *site_box = &ui_nil_box; { - F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f, .rate = rd_state->menu_animation_rate); UI_Rect(site_rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); @@ -8138,10 +8149,10 @@ rd_window_frame(void) Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); Rng2F32 future_split_rect = { - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), }; UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { @@ -8266,10 +8277,10 @@ rd_window_frame(void) target_rect_px.x1/content_rect_dim.x, target_rect_px.y1/content_rect_dim.y); B32 reset = (window_is_resizing || ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset, .rate = rd_state->menu_animation_rate); } } ws->window_layout_reset = 0; @@ -8306,10 +8317,10 @@ rd_window_frame(void) target_rect_px.y0 / content_rect_dim.y, target_rect_px.x1 / content_rect_dim.x, target_rect_px.y1 / content_rect_dim.y); - Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1)); + Rng2F32 panel_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .rate = rd_state->menu_animation_rate)); Rng2F32 panel_rect = r2f32p(panel_rect_pct.x0*content_rect_dim.x, panel_rect_pct.y0*content_rect_dim.y, panel_rect_pct.x1*content_rect_dim.x, @@ -8412,7 +8423,7 @@ rd_window_frame(void) } UI_Box *site_box = &ui_nil_box; { - F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f); + F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f, .rate = rd_state->menu_animation_rate); UI_Rect(rect) UI_Squish(0.1f-0.1f*site_open_t) UI_Transparency(1-site_open_t) { site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key); @@ -8498,10 +8509,10 @@ rd_window_frame(void) Vec2F32 future_split_rect_target_center = center_2f32(future_split_rect_target); Rng2F32 future_split_rect = { - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x), - ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v0"), future_split_rect_target.x0, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v1"), future_split_rect_target.y0, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v2"), future_split_rect_target.x1, .initial = future_split_rect_target_center.x, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "drop_site_v3"), future_split_rect_target.y1, .initial = future_split_rect_target_center.y, .rate = rd_state->menu_animation_rate), }; UI_Rect(future_split_rect) UI_TagF("drop_site") UI_CornerRadius(ui_top_font_size()*2.f) { @@ -8713,7 +8724,7 @@ rd_window_frame(void) t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; tab_width_target = Min(max_tab_width_px, tab_width_target); - t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0)); + t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0, .rate = rd_state->menu_animation_rate)); SLLQueuePush(first_tab_task, last_tab_task, t); tab_task_count += 1; } @@ -10919,8 +10930,8 @@ rd_frame(void) F32 scroll_x_diff = (-vs->scroll_pos.x.off); F32 scroll_y_diff = (-vs->scroll_pos.y.off); F32 loading_t_diff = (vs->loading_t_target - vs->loading_t); - vs->scroll_pos.x.off += scroll_x_diff*fast_rate; - vs->scroll_pos.y.off += scroll_y_diff*fast_rate; + vs->scroll_pos.x.off += scroll_x_diff*rd_state->scrolling_animation_rate; + vs->scroll_pos.y.off += scroll_y_diff*rd_state->scrolling_animation_rate; vs->loading_t += loading_t_diff * slow_rate; if(abs_f32(loading_t_diff) > 0.01f || abs_f32(scroll_x_diff) > 0.01f || @@ -12924,10 +12935,10 @@ rd_frame(void) target_prev_rect_px.y0/stub_content_rect_dim.y, target_prev_rect_px.x1/stub_content_rect_dim.x, target_prev_rect_px.y1/stub_content_rect_dim.y); - Rng2F32 prev_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->prev->cfg), target_prev_rect_pct.x0, .initial = target_prev_rect_pct.x0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->prev->cfg), target_prev_rect_pct.y0, .initial = target_prev_rect_pct.y0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->prev->cfg), target_prev_rect_pct.x1, .initial = target_prev_rect_pct.x1), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->prev->cfg), target_prev_rect_pct.y1, .initial = target_prev_rect_pct.y1)); + Rng2F32 prev_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->prev->cfg), target_prev_rect_pct.x0, .initial = target_prev_rect_pct.x0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->prev->cfg), target_prev_rect_pct.y0, .initial = target_prev_rect_pct.y0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->prev->cfg), target_prev_rect_pct.x1, .initial = target_prev_rect_pct.x1, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->prev->cfg), target_prev_rect_pct.y1, .initial = target_prev_rect_pct.y1, .rate = rd_state->menu_animation_rate)); new_rect_pct = prev_rect_pct; new_rect_pct.p0.v[split_axis] = new_rect_pct.p1.v[split_axis]; } @@ -12938,17 +12949,17 @@ rd_frame(void) target_next_rect_px.y0/stub_content_rect_dim.y, target_next_rect_px.x1/stub_content_rect_dim.x, target_next_rect_px.y1/stub_content_rect_dim.y); - Rng2F32 next_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->next->cfg), target_next_rect_pct.x0, .initial = target_next_rect_pct.x0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->next->cfg), target_next_rect_pct.y0, .initial = target_next_rect_pct.y0), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->next->cfg), target_next_rect_pct.x1, .initial = target_next_rect_pct.x1), - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->next->cfg), target_next_rect_pct.y1, .initial = target_next_rect_pct.y1)); + Rng2F32 next_rect_pct = r2f32p(ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->next->cfg), target_next_rect_pct.x0, .initial = target_next_rect_pct.x0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->next->cfg), target_next_rect_pct.y0, .initial = target_next_rect_pct.y0, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->next->cfg), target_next_rect_pct.x1, .initial = target_next_rect_pct.x1, .rate = rd_state->menu_animation_rate), + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->next->cfg), target_next_rect_pct.y1, .initial = target_next_rect_pct.y1, .rate = rd_state->menu_animation_rate)); new_rect_pct = next_rect_pct; new_rect_pct.p1.v[split_axis] = new_rect_pct.p0.v[split_axis]; } - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->cfg), new_rect_pct.x0, .initial = new_rect_pct.x0, .reset = 1); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->cfg), new_rect_pct.x1, .initial = new_rect_pct.x1, .reset = 1); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->cfg), new_rect_pct.y0, .initial = new_rect_pct.y0, .reset = 1); - ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->cfg), new_rect_pct.y1, .initial = new_rect_pct.y1, .reset = 1); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", new_panel->cfg), new_rect_pct.x0, .initial = new_rect_pct.x0, .reset = 1, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", new_panel->cfg), new_rect_pct.x1, .initial = new_rect_pct.x1, .reset = 1, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", new_panel->cfg), new_rect_pct.y0, .initial = new_rect_pct.y0, .reset = 1, .rate = rd_state->menu_animation_rate); + ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", new_panel->cfg), new_rect_pct.y1, .initial = new_rect_pct.y1, .reset = 1, .rate = rd_state->menu_animation_rate); } } @@ -16123,19 +16134,6 @@ rd_frame(void) rd_cmd(RD_CmdKind_FindThread, .thread = find_thread_retry); } - ////////////////////////////// - //- rjf: animate confirmation - // - { - F32 rate = rd_setting_b32_from_name(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-30.f * rd_state->frame_dt)) : 1.f; - B32 popup_open = rd_state->popup_active; - rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); - if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) - { - rd_request_frame(); - } - } - //////////////////////////// //- rjf: rotate command slots, bump command gen counter // @@ -16249,6 +16247,36 @@ rd_frame(void) di_match_store_begin(rd_state->match_store, keys); } + ////////////////////////////// + //- rjf: compute animation rates, given config + // + { + F32 master_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("animations")); + F32 scrolling_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("scrolling_animations")); + F32 tooltip_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("tooltip_animations")); + F32 menu_animations_f = (F32)!!rd_setting_b32_from_name(str8_lit("menu_animations")); + rd_state->catchall_animation_rate = 1 - master_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt)); + rd_state->menu_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-70.f * rd_state->frame_dt)); + rd_state->menu_animation_rate__slow = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt)); + rd_state->entity_alive_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-30.f * rd_state->frame_dt)); + rd_state->rich_hover_animation_rate = 1 - master_animations_f*menu_animations_f*pow_f32(2, (-50.f * rd_state->frame_dt)); + rd_state->scrolling_animation_rate = 1 - master_animations_f*scrolling_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt)); + rd_state->tooltip_animation_rate = 1 - master_animations_f*tooltip_animations_f*pow_f32(2, (-60.f * rd_state->frame_dt)); + } + + ////////////////////////////// + //- rjf: animate confirmation + // + { + F32 rate = rd_setting_b32_from_name(str8_lit("menu_animations")) ? 1 - pow_f32(2, (-30.f * rd_state->frame_dt)) : 1.f; + B32 popup_open = rd_state->popup_active; + rd_state->popup_t += rate * ((F32)!!popup_open-rd_state->popup_t); + if(abs_f32(rd_state->popup_t - (F32)!!popup_open) > 0.005f) + { + rd_request_frame(); + } + } + ////////////////////////////// //- rjf: update/render all windows // diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index df7f202a..eca72713 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -558,6 +558,15 @@ struct RD_State B32 use_default_stl_type_views; B32 use_default_ue_type_views; + // rjf: animation rates + F32 catchall_animation_rate; + F32 menu_animation_rate; + F32 menu_animation_rate__slow; + F32 entity_alive_animation_rate; + F32 rich_hover_animation_rate; + F32 scrolling_animation_rate; + F32 tooltip_animation_rate; + // rjf: serialized config debug string keys U128 user_cfg_string_key; U128 project_cfg_string_key; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 6317af59..dd75b081 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -542,23 +542,32 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) { if(!md_node_has_tag(child, str8_lit("no_expand"), 0)) { - String8 display_name = md_tag_from_string(child, str8_lit("display_name"), 0)->first->string; - if(display_name.size == 0) + MD_Node *expand_check = md_tag_from_string(child, str8_lit("expand_if"), 0); + B32 expand_this_child = 1; + if(!md_node_is_nil(expand_check)) E_ParentKey(eval.key) { - display_name = rd_display_from_code_name(child->string); + expand_this_child = !!e_value_from_string(expand_check->first->string).u64; } - String8 desc = md_tag_from_string(child, str8_lit("description"), 0)->first->string; - FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, child->string); - FuzzyMatchRangeList display_name_matches = fuzzy_match_find(scratch.arena, filter, display_name); - FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, desc); - if(name_matches.count == name_matches.needle_part_count || - display_name_matches.count == display_name_matches.needle_part_count || - desc_matches.count == desc_matches.needle_part_count) + if(expand_this_child) { - ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); - n->n = child; - SLLQueuePush(first_child_node, last_child_node, n); - child_count += 1; + String8 display_name = md_tag_from_string(child, str8_lit("display_name"), 0)->first->string; + if(display_name.size == 0) + { + display_name = rd_display_from_code_name(child->string); + } + String8 desc = md_tag_from_string(child, str8_lit("description"), 0)->first->string; + FuzzyMatchRangeList name_matches = fuzzy_match_find(scratch.arena, filter, child->string); + FuzzyMatchRangeList display_name_matches = fuzzy_match_find(scratch.arena, filter, display_name); + FuzzyMatchRangeList desc_matches = fuzzy_match_find(scratch.arena, filter, desc); + if(name_matches.count == name_matches.needle_part_count || + display_name_matches.count == display_name_matches.needle_part_count || + desc_matches.count == desc_matches.needle_part_count) + { + ExpandChildNode *n = push_array(scratch.arena, ExpandChildNode, 1); + n->n = child; + SLLQueuePush(first_child_node, last_child_node, n); + child_count += 1; + } } } } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 51b0f05c..24b227f2 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -213,10 +213,6 @@ //////////////////////////////// //~ rjf: 0.9.16 TODO notes // -// [ ] autocompletion lister -// [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs -// (actually, just kill the tabs on load if they refer to transient things) -// // [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... @@ -246,6 +242,8 @@ // [ ] Mohit-reported breakpoint not hitting - may be similar thing to @bpmiss // //- ui improvements +// [ ] we probably want to disable pop/pull out for transient things, e.g. theme color cfgs +// (actually, just kill the tabs on load if they refer to transient things) // [ ] universal ctx menu address/watch options; e.g. watch -> memory; watch -> add watch // [ ] rich hover coverage; bitmap <-> geo <-> memory <-> disassembly <-> text; etc. // [ ] tooltip coverage pass (row commands, etc.) @@ -530,6 +528,7 @@ // [x] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) // [x] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop // [x] finish theme editing, build themes - replace code colors map with new theme stuff +// [x] autocompletion lister //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 9944e58c..43f07958 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1229,8 +1229,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe ui_color_from_name(str8_lit("line_info_3")), }; F32 line_num_padding_px = ui_top_font_size()*1.f; - F32 entity_alive_t_rate = (1 - pow_f32(2, (-30.f * rd_state->frame_dt))); - F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; + F32 entity_alive_t_rate = rd_state->entity_alive_animation_rate; + F32 entity_hover_t_rate = rd_state->rich_hover_animation_rate; B32 do_thread_lines = rd_setting_b32_from_name(str8_lit("thread_lines")); B32 do_thread_glow = rd_setting_b32_from_name(str8_lit("thread_glow")); B32 do_bp_lines = rd_setting_b32_from_name(str8_lit("breakpoint_lines")); @@ -3464,7 +3464,7 @@ rd_cell(RD_CellParams *params, String8 string) if(build_toggle_switch) UI_Parent(box) { B32 is_toggled = !!params->toggled_out[0]; - F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled); + F32 toggle_t = ui_anim(ui_key_from_stringf(key, "toggled"), (F32)is_toggled, .initial = (F32)is_toggled, .rate = rd_state->menu_animation_rate); F32 height_px = ceil_f32(ui_top_font_size() * 1.75f); F32 padding_px = ceil_f32((ui_top_px_height() - height_px) / 2.f); UI_PrefWidth(ui_children_sum(1.f)) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 4198c53e..413915a7 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1423,13 +1423,13 @@ ui_end_build(void) } } } - ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_ContextMenuAnimations ? fast_rate : 1); + ui_state->ctx_menu_open_t += ((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) * ui_state->animation_info.menu_animation_rate; ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->ctx_menu_open - ui_state->ctx_menu_open_t) > 0.01f); if(ui_state->ctx_menu_open_t >= 0.99f && ui_state->ctx_menu_open) { ui_state->ctx_menu_open_t = 1.f; } - ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * (ui_state->animation_info.flags & UI_AnimationInfoFlag_TooltipAnimations ? fast_rate : 1); + ui_state->tooltip_open_t += ((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) * ui_state->animation_info.tooltip_animation_rate; ui_state->is_animating = (ui_state->is_animating || abs_f32((F32)!!ui_state->tooltip_open - ui_state->tooltip_open_t) > 0.01f); if(ui_state->tooltip_open_t >= 0.99f && ui_state->tooltip_open) { @@ -1452,10 +1452,10 @@ ui_end_build(void) B32 is_focus_active_disabled = !!(box->flags & UI_BoxFlag_FocusActiveDisabled); // rjf: determine rates - F32 hot_rate = (ui_state->animation_info.flags & UI_AnimationInfoFlag_HotAnimations ? fast_rate : 1); - F32 active_rate = (ui_state->animation_info.flags & UI_AnimationInfoFlag_ActiveAnimations ? fast_rate : 1); - F32 disabled_rate = (ui_state->animation_info.flags & UI_AnimationInfoFlag_HotAnimations ? slow_rate : 1); - F32 focus_rate = (ui_state->animation_info.flags & UI_AnimationInfoFlag_FocusAnimations ? fast_rate : 1); + F32 hot_rate = ui_state->animation_info.hot_animation_rate; + F32 active_rate = ui_state->animation_info.active_animation_rate; + F32 disabled_rate = slow_rate; + F32 focus_rate = ui_state->animation_info.focus_animation_rate; // rjf: determine animating status B32 box_is_animating = 0; @@ -1520,8 +1520,8 @@ ui_end_build(void) // rjf: animate view offset { - box->view_off.x += fast_rate * (box->view_off_target.x - box->view_off.x); - box->view_off.y += fast_rate * (box->view_off_target.y - box->view_off.y); + box->view_off.x += ui_state->animation_info.scroll_animation_rate * (box->view_off_target.x - box->view_off.x); + box->view_off.y += ui_state->animation_info.scroll_animation_rate * (box->view_off_target.y - box->view_off.y); if(abs_f32(box->view_off.x - box->view_off_target.x) < 2) { box->view_off.x = box->view_off_target.x; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 599f1246..5cec6662 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -238,22 +238,15 @@ struct UI_Theme //////////////////////////////// //~ rjf: Animation Info -typedef U32 UI_AnimationInfoFlags; -enum -{ - UI_AnimationInfoFlag_HotAnimations = (1<<0), - UI_AnimationInfoFlag_ActiveAnimations = (1<<1), - UI_AnimationInfoFlag_FocusAnimations = (1<<2), - UI_AnimationInfoFlag_TooltipAnimations = (1<<3), - UI_AnimationInfoFlag_ContextMenuAnimations = (1<<4), - UI_AnimationInfoFlag_ScrollingAnimations = (1<<5), - UI_AnimationInfoFlag_All = 0xffffffff, -}; - typedef struct UI_AnimationInfo UI_AnimationInfo; struct UI_AnimationInfo { - UI_AnimationInfoFlags flags; + F32 hot_animation_rate; + F32 active_animation_rate; + F32 focus_animation_rate; + F32 tooltip_animation_rate; + F32 menu_animation_rate; + F32 scroll_animation_rate; }; //////////////////////////////// From 53fea4a17e4cb4180a331fbd3678d6ec259ebbe6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 15:29:38 -0700 Subject: [PATCH 602/755] hack to fix corner case in watch window controls --- src/raddbg/raddbg_core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ac4fdbf0..8e1f18f8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5071,7 +5071,10 @@ rd_view_ui(Rng2F32 rect) rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; - rd_cmd(RD_CmdKind_Accept); + // TODO(rjf): @hack - we really want navigations to be event-like, but we need + // to insert a dumb no-op here so that the "rugpull" cursor move can take effect + // before the edit command we are queueing up... + rd_cmd(RD_CmdKind_Edit); if(cell_info.flags & RD_WatchCellFlag_CanEdit) { rd_cmd(RD_CmdKind_Edit); @@ -5132,7 +5135,8 @@ rd_view_ui(Rng2F32 rect) ewv->next_cursor = ewv->next_mark = cell_pt; if(!rd_watch_pt_match(ewv->cursor, cell_pt)) { - rd_cmd(RD_CmdKind_Accept); + // TODO(rjf): see above @hack + rd_cmd(RD_CmdKind_Edit); } rd_cmd(RD_CmdKind_Edit); } From 8d8e9b3cc5c037e8283eb0f7a1a71fe14db0563f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 15:42:36 -0700 Subject: [PATCH 603/755] be more judicious about edit buttons in fancy rows; allow escape-hatch identifier evaluation via grave accents --- src/eval/eval_parse.c | 7 ++++++- src/raddbg/raddbg_core.c | 26 ++++++++++++++++++++++---- src/raddbg/raddbg_widgets.c | 2 +- src/raddbg/raddbg_widgets.h | 17 ++++++++++------- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index ba0f8b0e..782b16eb 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1031,8 +1031,13 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 token_string = str8_substr(text, token.range); if(token.kind == E_TokenKind_Identifier) { + String8 identifier_string = token_string; + if(identifier_string.size >= 2 && identifier_string.str[0] == '`' && identifier_string.str[identifier_string.size-1] == '`') + { + identifier_string = str8_skip(str8_chop(identifier_string, 1), 1); + } atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token.range); - atom->string = token_string; + atom->string = identifier_string; it += 1; got_new_atom = 1; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8e1f18f8..1eb60a08 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4860,6 +4860,12 @@ rd_view_ui(Rng2F32 rect) MemoryZeroStruct(&cell_params.description); } + // rjf: extra edit button for meta-cfg strings + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + cell_params.flags |= RD_CellFlag_EmptyEditButton; + } + // rjf: apply expander (or substitute space) if(!ewv->text_editing || !cell_selected) { @@ -5071,13 +5077,19 @@ rd_view_ui(Rng2F32 rect) rd_cfg_child_from_string(view, str8_lit("autocomplete")) != &rd_nil_cfg) { ewv->next_cursor = ewv->next_mark = cell_pt; - // TODO(rjf): @hack - we really want navigations to be event-like, but we need - // to insert a dumb no-op here so that the "rugpull" cursor move can take effect - // before the edit command we are queueing up... - rd_cmd(RD_CmdKind_Edit); if(cell_info.flags & RD_WatchCellFlag_CanEdit) { + // TODO(rjf): @hack - we really want navigations to be event-like, but we need + // to insert a dumb no-op here so that the "rugpull" cursor move can take effect + // before the edit command we are queueing up... rd_cmd(RD_CmdKind_Edit); + rd_cmd(RD_CmdKind_Edit); + } + else + { + rd_cmd(RD_CmdKind_Edit); + ewv->next_cursor = ewv->next_mark = cell_pt; + rd_cmd(RD_CmdKind_Accept); } } @@ -14055,6 +14067,12 @@ rd_frame(void) { B32 name_resolved = 0; + // rjf: strip `s + if(name.size >= 2 && name.str[0] == '`' && name.str[name.size-1] == '`') + { + name = str8_skip(str8_chop(name, 1), 1); + } + // rjf: try to resolve name as a symbol U64 voff = 0; DI_Key voff_dbgi_key = {0}; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 43f07958..bfe14340 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3413,7 +3413,7 @@ rd_cell(RD_CellParams *params, String8 string) //- rjf: build edit-button, if line edit is embedded, and has no string // B32 edit_started = 0; - if(!is_focus_active && !is_focus_active_disabled && build_lhs_name_desc && build_line_edit && value_name_fstrs.total_size == 0) + if(params->flags & RD_CellFlag_EmptyEditButton && !is_focus_active && !is_focus_active_disabled && build_lhs_name_desc && build_line_edit && value_name_fstrs.total_size == 0) { UI_TagF(".") UI_TagF("weak") diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index 305eb4cc..b709d12d 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -24,18 +24,21 @@ enum //- rjf: bindings extension RD_CellFlag_Bindings = (1<<5), + //- rjf: extra button extensions + RD_CellFlag_EmptyEditButton = (1<<6), + //- rjf: behavior - RD_CellFlag_DisableEdit = (1<<6), - RD_CellFlag_KeyboardClickable = (1<<7), - RD_CellFlag_SingleClickActivate = (1<<8), + RD_CellFlag_DisableEdit = (1<<7), + RD_CellFlag_KeyboardClickable = (1<<8), + RD_CellFlag_SingleClickActivate = (1<<9), //- rjf: contents description - RD_CellFlag_CodeContents = (1<<9), + RD_CellFlag_CodeContents = (1<<10), //- rjf: appearance - RD_CellFlag_Border = (1<<10), - RD_CellFlag_NoBackground = (1<<11), - RD_CellFlag_Button = (1<<12), + RD_CellFlag_Border = (1<<11), + RD_CellFlag_NoBackground = (1<<12), + RD_CellFlag_Button = (1<<13), }; typedef struct RD_CellParams RD_CellParams; From de5ae9746dad75d778c3cc639c347e00120da5f7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 15:48:57 -0700 Subject: [PATCH 604/755] when generating debug info table evaluations, check for non-simple symbol identifiers, and generate slightly-better-though-not-comprehensive-escape-hatch for that symbol expression --- src/raddbg/raddbg_eval.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index dd75b081..e543ea33 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1592,6 +1592,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table) E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) { + Temp scratch = scratch_begin(&arena, 1); RD_DebugInfoTableLookupAccel *accel = (RD_DebugInfoTableLookupAccel *)user_data; U64 needed_row_count = dim_1u64(idx_range); for EachIndex(idx, needed_row_count) @@ -1609,8 +1610,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; E_Module *module = &e_base_ctx->modules[item->dbgi_idx]; - // rjf: build item's evaluation - E_Eval item_eval = e_eval_nil; + // rjf: get item's string + String8 item_string = {0}; { U64 element_idx = item->idx; switch(accel->section) @@ -1629,21 +1630,21 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_base_ctx->modules)); String8 symbol_name = {0}; symbol_name.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &symbol_name.size); - item_eval = e_eval_from_string(symbol_name); + item_string = symbol_name; }break; case RDI_SectionKind_GlobalVariables: { RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx); String8 symbol_name = {0}; symbol_name.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &symbol_name.size); - item_eval = e_eval_from_string(symbol_name); + item_string = symbol_name; }break; case RDI_SectionKind_ThreadVariables: { RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx); String8 symbol_name = {0}; symbol_name.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &symbol_name.size); - item_eval = e_eval_from_string(symbol_name); + item_string = symbol_name; }break; case RDI_SectionKind_UDTs: { @@ -1651,14 +1652,29 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx); String8 name = {0}; name.str = rdi_string_from_idx(module->rdi, type_node->user_defined.name_string_idx, &name.size); - item_eval = e_eval_from_string(name); + item_string = name; }break; } } + // rjf: build a valid expression string given item string + String8 item_expr = item_string; + { + E_TokenArray tokens = e_token_array_from_text(scratch.arena, item_expr); + if(tokens.count != 1) + { + item_expr = push_str8f(scratch.arena, "`%S`", item_string); + } + } + + // rjf: item's eval + E_Eval item_eval = e_eval_from_string(item_expr); + // rjf: fill evals_out[idx] = item_eval; + temp_end(scratch); } + scratch_end(scratch); } E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(debug_info_table) From 6b4c1997e100826e479089a101e162369aa7c156 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 16:25:04 -0700 Subject: [PATCH 605/755] eliminate defaults for overridden properties, e.g. per-tab font size; just pull value from hierarchy --- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 60 ++++++++++++++---------------- src/raddbg/raddbg_main.c | 2 +- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index bd4a3c0e..75bcc63f 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -410,8 +410,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @default(11) @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, -{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @default(3.f) @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @override @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 1f600f20..8be3d3d4 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -434,7 +434,7 @@ RD_VocabTable: @row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab) x: { - @default(11) @display_name('Tab Font Size') @description("Controls the tab's font size.") + @override @display_name('Tab Font Size') @description("Controls the tab's font size.") 'font_size': @range[6, 72] u64, } ``` @@ -446,7 +446,7 @@ RD_VocabTable: ``` @inherit(tab) x: { - @default(3.f) @display_name('Tab Row Height') @description("Controls the tab's row height, in multiples of the font size.") + @override @display_name('Tab Row Height') @description("Controls the tab's row height, in multiples of the font size.") 'row_height': @range[1.75f, 5.f] f32, 'label': code_string, @description("The root expression which is evaluated to produce the watch window.") diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 1eb60a08..09b8eee6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1851,49 +1851,45 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { read_data = cfg->first->string; } - else if(str8_match(child_type_name, str8_lit("bool"), 0)) + else { String8 value_string = cfg->first->string; if(value_string.size == 0) { value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; } - String8 value_string_casted = push_str8f(scratch.arena, "(bool)(%S)", value_string); - B32 value = !!e_value_from_string(value_string_casted).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); - } - else if(str8_match(child_type_name, str8_lit("u64"), 0)) - { - String8 value_string = cfg->first->string; - if(value_string.size == 0) + if(value_string.size == 0 && !md_node_is_nil(md_tag_from_string(child_schema, str8_lit("override"), 0))) { - value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + for(RD_Cfg *parent = root_cfg->parent; parent != &rd_nil_cfg; parent = parent->parent) + { + RD_Cfg *parent_child_w_key = rd_cfg_child_from_string(parent, child_key); + if(parent_child_w_key != &rd_nil_cfg) + { + value_string = parent_child_w_key->first->string; + break; + } + } } - String8 value_string_casted = push_str8f(scratch.arena, "(uint64)(%S)", value_string); - U64 value = e_value_from_string(value_string_casted).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); - } - else if(str8_match(child_type_name, str8_lit("u32"), 0)) - { - String8 value_string = cfg->first->string; - if(value_string.size == 0) + if(str8_match(child_type_name, str8_lit("bool"), 0)) { - value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + B32 value = !!e_value_from_stringf("(bool)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } - String8 value_string_casted = push_str8f(scratch.arena, "(uint32)(%S)", value_string); - U64 value = e_value_from_string(value_string_casted).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); - } - else if(str8_match(child_type_name, str8_lit("f32"), 0)) - { - String8 value_string = cfg->first->string; - if(value_string.size == 0) + else if(str8_match(child_type_name, str8_lit("u64"), 0)) { - value_string = md_tag_from_string(child_schema, str8_lit("default"), 0)->first->string; + U64 value = e_value_from_stringf("(uint64)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("u32"), 0)) + { + U64 value = e_value_from_stringf("(uint32)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("f32"), 0)) + { + F32 value = e_value_from_stringf("(float32)(%S)", value_string).f32; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } - String8 value_string_casted = push_str8f(scratch.arena, "(float32)(%S)", value_string); - F32 value = e_value_from_string(value_string_casted).f32; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); } } @@ -4867,7 +4863,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: apply expander (or substitute space) - if(!ewv->text_editing || !cell_selected) + if(!ewv->text_editing || !cell_selected || row_depth > 0) { if(row_is_expandable && cell == row_info->cells.first) { diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 24b227f2..f178571f 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -213,7 +213,6 @@ //////////////////////////////// //~ rjf: 0.9.16 TODO notes // -// [ ] evaluate `foo.bar` symbol names??? // [ ] maybe add extra caching layer to process memory querying? we pay a pretty // heavy cost even to just read 8 bytes... @@ -307,6 +306,7 @@ // [ ] audio waveform views // //- eval improvements +// [ ] evaluate `foo.bar` symbol names without escape hatch? // [ ] serializing eval view maps (?) // [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need // to prioritize the primary rdi From 1447e6ca24f111e47c6f42c9326e12873efe81df Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 17:09:01 -0700 Subject: [PATCH 606/755] revert-to-default ui for meta setting editors --- src/raddbg/generated/raddbg.meta.c | 6 +-- src/raddbg/raddbg.mdesk | 6 +-- src/raddbg/raddbg_core.c | 42 +++++++++++++++ src/raddbg/raddbg_widgets.c | 84 +++++++++++++++++------------- src/raddbg/raddbg_widgets.h | 18 ++++--- src/ui/ui_core.c | 42 ++++++++------- 6 files changed, 129 insertions(+), 69 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 75bcc63f..4ba71708 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -412,15 +412,15 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @override @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, {str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 8be3d3d4..ddb39c7f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -466,7 +466,7 @@ RD_VocabTable: 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers':bool, - @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") + @no_revert @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, } ``` @@ -581,7 +581,7 @@ RD_VocabTable: 'stdin_path': path, 'environment': query, 'debug_subprocesses': bool, - @no_expand @default(0) 'enabled': bool, + @no_revert @no_expand @default(0) 'enabled': bool, } ```, } @@ -603,7 +603,7 @@ RD_VocabTable: 'break_on_write': bool, 'break_on_read': bool, 'break_on_execute': bool, - @no_expand @default(1) 'enabled': bool, + @no_revert @no_expand @default(1) 'enabled': bool, } ```, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 09b8eee6..62b6ecf1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1868,6 +1868,11 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) value_string = parent_child_w_key->first->string; break; } + value_string = rd_default_setting_from_names(parent->string, child_key); + if(value_string.size != 0) + { + break; + } } } if(str8_match(child_type_name, str8_lit("bool"), 0)) @@ -4699,6 +4704,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: build cell contents // RD_Cfg *cell_view = &rd_nil_cfg; + B32 revert_cell = 0; UI_Signal sig = {0}; ProfScope("build cell contents") UI_Parent(cell_box) @@ -4862,6 +4868,34 @@ rd_view_ui(Rng2F32 rect) cell_params.flags |= RD_CellFlag_EmptyEditButton; } + // rjf: extra revert button for non-default meta-cfgs + if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg && + !(cell->flags & RD_WatchCellFlag_NoEval)) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(cell->eval.space); + String8 child_key = e_string_from_id(cell->eval.space.u64s[1]); + RD_Cfg *child_cfg = rd_cfg_child_from_string(cfg, child_key); + if(child_cfg != &rd_nil_cfg) + { + MD_NodePtrList schemas = rd_schemas_from_name(cfg->string); + if(schemas.count != 0) + { + MD_Node *child_schema = &md_nil_node; + for(MD_NodePtrNode *n = schemas.first; md_node_is_nil(child_schema) && n != 0; n = n->next) + { + child_schema = md_child_from_string(n->v, child_key, 0); + } + if((md_node_has_tag(child_schema, str8_lit("override"), 0) || + md_node_has_tag(child_schema, str8_lit("default"), 0)) && + !md_node_has_tag(child_schema, str8_lit("no_revert"), 0)) + { + cell_params.flags |= RD_CellFlag_RevertButton; + cell_params.revert_out = &revert_cell; + } + } + } + } + // rjf: apply expander (or substitute space) if(!ewv->text_editing || !cell_selected || row_depth > 0) { @@ -5033,6 +5067,14 @@ rd_view_ui(Rng2F32 rect) pressed = 1; } + // rjf: reversion + if(revert_cell && cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg) + { + RD_Cfg *cfg = rd_cfg_from_eval_space(cell->eval.space); + String8 child_key = e_string_from_id(cell->eval.space.u64s[1]); + rd_cfg_release(rd_cfg_child_from_string(cfg, child_key)); + } + // rjf: activation (double-click normally, or single-clicks with special buttons) if((!(cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_double_clicked(sig)) || ((cell_info.flags & RD_WatchCellFlag_ActivateWithSingleClick) && ui_clicked(sig)) || diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index bfe14340..46407e52 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3328,40 +3328,6 @@ rd_cell(RD_CellParams *params, String8 string) } } - ////////////////////////////// - //- rjf: build reset-to-default, if line edit is embedded & it is marked - // -#if 0 - if(!is_focus_active && !is_focus_active_disabled) - { - UI_TagF(".") - UI_TagF("weak") - UI_TagF("implicit") - UI_Parent(box) - UI_PrefWidth(ui_em(2.f, 1.f)) - { - UI_Column - UI_Padding(ui_pct(1, 0)) - UI_PrefHeight(ui_em(2.f, 1.f)) - UI_CornerRadius(ui_top_font_size()*0.5f) - UI_HoverCursor(OS_Cursor_HandPoint) - RD_Font(RD_FontSlot_Icons) - UI_TextAlignment(UI_TextAlign_Center) - { - UI_Box *edit_start_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| - UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_DisableFocusOverlay| - UI_BoxFlag_DisableFocusBorder| - UI_BoxFlag_Clickable, - "%S##undo", rd_icon_kind_text_table[RD_IconKind_Undo]); - UI_Signal sig = ui_signal_from_box(edit_start_box); - } - } - } -#endif - ////////////////////////////// //- rjf: build line edit container box // @@ -3373,8 +3339,14 @@ rd_cell(RD_CellParams *params, String8 string) UI_Size edit_box_size = ui_pct(1, 0); if(build_lhs_name_desc) { - F32 px_size = is_editing ? (floor_f32(dim_2f32(box->rect).x*0.5f)) : floor_f32(dr_dim_from_fstrs(&value_name_fstrs).x + ui_top_font_size()*1.5f); - edit_box_size = ui_px(px_size, 1.f); + if(is_editing) + { + edit_box_size = ui_px(floor_f32(dim_2f32(box->rect).x*0.5f), 1.f); + } + else + { + edit_box_size = ui_children_sum(1); + } } UI_PrefWidth(edit_box_size) { @@ -3458,6 +3430,46 @@ rd_cell(RD_CellParams *params, String8 string) } } + ////////////////////////////// + //- rjf: build revert-button + // + if(params->flags & RD_CellFlag_RevertButton && !is_focus_active && !is_focus_active_disabled) + { + UI_Parent(edit_box) + UI_PrefWidth(ui_em(2.f, 1.f)) + { + UI_TagF(".") + UI_TagF("weak") + UI_TagF("implicit") + UI_Column + UI_Padding(ui_pct(1, 0)) + UI_PrefHeight(ui_em(2.f, 1.f)) + UI_CornerRadius(ui_top_font_size()*0.5f) + RD_Font(RD_FontSlot_Icons) + UI_TextAlignment(UI_TextAlign_Center) + { + UI_Box *revert_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DisableFocusOverlay| + UI_BoxFlag_DisableFocusBorder| + UI_BoxFlag_Clickable, + "%S##revert", rd_icon_kind_text_table[RD_IconKind_Undo]); + UI_Signal sig = ui_signal_from_box(revert_box); + if(ui_pressed(sig) && params->revert_out) + { + params->revert_out[0] = 1; + } + } + // TODO(rjf): @hack + if(build_toggle_switch || build_slider) + { + ui_spacer(ui_em(1.f, 1.f)); + } + } + } + ////////////////////////////// //- rjf: build toggle-switch // diff --git a/src/raddbg/raddbg_widgets.h b/src/raddbg/raddbg_widgets.h index b709d12d..36014bad 100644 --- a/src/raddbg/raddbg_widgets.h +++ b/src/raddbg/raddbg_widgets.h @@ -26,19 +26,20 @@ enum //- rjf: extra button extensions RD_CellFlag_EmptyEditButton = (1<<6), + RD_CellFlag_RevertButton = (1<<7), //- rjf: behavior - RD_CellFlag_DisableEdit = (1<<7), - RD_CellFlag_KeyboardClickable = (1<<8), - RD_CellFlag_SingleClickActivate = (1<<9), + RD_CellFlag_DisableEdit = (1<<8), + RD_CellFlag_KeyboardClickable = (1<<9), + RD_CellFlag_SingleClickActivate = (1<<10), //- rjf: contents description - RD_CellFlag_CodeContents = (1<<10), + RD_CellFlag_CodeContents = (1<<11), //- rjf: appearance - RD_CellFlag_Border = (1<<11), - RD_CellFlag_NoBackground = (1<<12), - RD_CellFlag_Button = (1<<13), + RD_CellFlag_Border = (1<<12), + RD_CellFlag_NoBackground = (1<<13), + RD_CellFlag_Button = (1<<14), }; typedef struct RD_CellParams RD_CellParams; @@ -65,6 +66,9 @@ struct RD_CellParams //- rjf: bindings name w info String8 bindings_name; + //- rjf: revert out + B32 *revert_out; + //- rjf: text editing r/w info TxtPt *cursor; TxtPt *mark; diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 413915a7..75a7cb3a 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -3341,15 +3341,17 @@ return old_value; internal void ui__push_tags_key_from_appended_string(String8 string) { + B32 is_new_root = str8_match(str8_lit("."), string, 0); + // rjf: generate new key, by combining hash of this new string with the top // of the tags key stack UI_Key seed_key = {0}; - if(ui_state->tags_key_stack_top != 0) + if(!is_new_root && ui_state->tags_key_stack_top != 0) { seed_key = ui_state->tags_key_stack_top->key; } UI_Key key = seed_key; - if(!str8_match(str8_lit("."), string, 0) && string.size > 0) + if(!is_new_root && string.size > 0) { key = ui_key_from_string(seed_key, string); } @@ -3370,23 +3372,23 @@ ui__push_tags_key_from_appended_string(String8 string) } // rjf: store in tags cache - U64 slot_idx = key.u64[0] % ui_state->tags_cache_slots_count; - UI_TagsCacheSlot *slot = &ui_state->tags_cache_slots[slot_idx]; - UI_TagsCacheNode *node = 0; - for(UI_TagsCacheNode *n = slot->first; n != 0; n = n->next) + if(!is_new_root) { - if(ui_key_match(n->key, key)) + U64 slot_idx = key.u64[0] % ui_state->tags_cache_slots_count; + UI_TagsCacheSlot *slot = &ui_state->tags_cache_slots[slot_idx]; + UI_TagsCacheNode *node = 0; + for(UI_TagsCacheNode *n = slot->first; n != 0; n = n->next) { - node = n; - break; + if(ui_key_match(n->key, key)) + { + node = n; + break; + } } - } - if(node == 0) - { - Temp scratch = scratch_begin(0, 0); - String8List tags = {0}; - if(!str8_match(string, str8_lit("."), 0)) + if(node == 0) { + Temp scratch = scratch_begin(0, 0); + String8List tags = {0}; if(string.size != 0) { str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), string)); @@ -3402,12 +3404,12 @@ ui__push_tags_key_from_appended_string(String8 string) str8_list_push(scratch.arena, &tags, push_str8_copy(ui_build_arena(), n->v)); } } + node = push_array(ui_build_arena(), UI_TagsCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = key; + node->tags = str8_array_from_list(ui_build_arena(), &tags); + scratch_end(scratch); } - node = push_array(ui_build_arena(), UI_TagsCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->key = key; - node->tags = str8_array_from_list(ui_build_arena(), &tags); - scratch_end(scratch); } } From df8c29d7b11a988679463ebad6895271d41333cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 17:22:59 -0700 Subject: [PATCH 607/755] clamp font size settings --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 ++-- src/raddbg/raddbg_core.c | 22 +++++++++++++++------- src/raddbg/raddbg_core.h | 1 + 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 4ba71708..36dc1901 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -406,7 +406,7 @@ RD_VocabInfo rd_vocab_info_table[340] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n @default('') 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n @default('') 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index ddb39c7f..2a3efc82 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -234,9 +234,9 @@ RD_VocabTable: //- rjf: fonts @display_name('UI Font') @description("The name of, or path to, the font used when displaying non-code UI elements.") - 'main_font': string, + @default('') 'main_font': string, @display_name('Code Font') @description("The name of, or path to, the font used when displaying code.") - 'code_font': string, + @default('') 'code_font': string, //- rjf: theme @default("Default (Dark)") @display_name('User Theme') diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 62b6ecf1..607fee83 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2664,7 +2664,7 @@ rd_view_ui(Rng2F32 rect) //- rjf: fill view container // UI_Parent(view_container) - UI_FontSize(rd_setting_f32_from_name(str8_lit("font_size"))) + UI_FontSize(rd_font_size()) UI_PrefHeight(ui_px(floor_f32(ui_top_font_size()*rd_setting_f32_from_name(str8_lit("row_height"))), 1.f)) { //////////////////////////// @@ -6014,7 +6014,7 @@ rd_window_frame(void) // if(rd_state->first_window_state == ws && rd_state->last_window_state == ws && ws->frames_alive == 0) { - F32 font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 font_size = rd_font_size(); RD_FontSlot english_font_slots[] = {RD_FontSlot_Main, RD_FontSlot_Code}; RD_FontSlot icon_font_slot = RD_FontSlot_Icons; for(U64 idx = 0; idx < ArrayCount(english_font_slots); idx += 1) @@ -6153,7 +6153,7 @@ rd_window_frame(void) { // rjf: get top-level font size info F32 top_level_font_size = 0; - RD_RegsScope(.view = 0, .tab = 0) top_level_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + RD_RegsScope(.view = 0, .tab = 0) top_level_font_size = rd_font_size(); // rjf: build icon info UI_IconInfo icon_info = {0}; @@ -10074,6 +10074,14 @@ rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 //- rjf: fonts/sizes +internal F32 +rd_font_size(void) +{ + F32 size = rd_setting_f32_from_name(str8_lit("font_size")); + size = Clamp(6.f, size, 72.f); + return size; +} + internal FNT_Tag rd_font_from_slot(RD_FontSlot slot) { @@ -12873,9 +12881,9 @@ rd_frame(void) if(cfg != &rd_nil_cfg) { fnt_reset(); - F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 current_font_size = rd_font_size(); F32 new_font_size = current_font_size+1; - new_font_size = ClampBot(1, new_font_size); + new_font_size = Clamp(6.f, new_font_size, 72.f); RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); }break; @@ -12885,9 +12893,9 @@ rd_frame(void) if(cfg != &rd_nil_cfg) { fnt_reset(); - F32 current_font_size = rd_setting_f32_from_name(str8_lit("font_size")); + F32 current_font_size = rd_font_size(); F32 new_font_size = current_font_size-1; - new_font_size = ClampBot(1, new_font_size); + new_font_size = Clamp(6.f, new_font_size, 72.f); RD_Cfg *font_size_cfg = rd_cfg_child_from_string_or_alloc(cfg, str8_lit("font_size")); rd_cfg_new_replacef(font_size_cfg, "%I64u", (U64)new_font_size); }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index eca72713..550aeee7 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -982,6 +982,7 @@ internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind k internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string); //- rjf: fonts +internal F32 rd_font_size(void); internal FNT_Tag rd_font_from_slot(RD_FontSlot slot); internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); From 7048a8748c739366aefe905322b485b6306380ca Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 May 2025 17:34:49 -0700 Subject: [PATCH 608/755] bindings resetting function --- src/raddbg/generated/raddbg.meta.c | 6 +++-- src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 3 +++ src/raddbg/raddbg_core.c | 40 ++++++++++++++++++------------ src/raddbg/raddbg_main.c | 8 ++---- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 36dc1901..63c2536d 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[340] = +RD_VocabInfo rd_vocab_info_table[341] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -223,6 +223,7 @@ RD_VocabInfo rd_vocab_info_table[340] = {str8_lit_comp("bring_to_front"), str8_lit_comp(""), str8_lit_comp("Bring To Front"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("popup_accept"), str8_lit_comp(""), str8_lit_comp("Popup Accept"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("popup_cancel"), str8_lit_comp(""), str8_lit_comp("Popup Cancel"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("reset_to_default_bindings"), str8_lit_comp(""), str8_lit_comp("Reset To Default Bindings"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("reset_to_default_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Default Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("reset_to_compact_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Compact Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, {str8_lit_comp("reset_to_simple_panels"), str8_lit_comp(""), str8_lit_comp("Reset To Simple Panel Layout"), str8_lit_comp(""), RD_IconKind_Window}, @@ -479,7 +480,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[233] = +RD_CmdKindInfo rd_cmd_kind_info_table[234] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -535,6 +536,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[233] = { str8_lit_comp("bring_to_front"), str8_lit_comp("Brings all windows to the front, and focuses the most recently focused window."), str8_lit_comp("top"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("popup_accept"), str8_lit_comp("Accepts the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("popup_cancel"), str8_lit_comp("Cancels the active popup prompt."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("reset_to_default_bindings"), str8_lit_comp("Resets all keybindings to their defaults."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("reset_to_compact_panels"), str8_lit_comp("Resets the window to the compact panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("reset_to_simple_panels"), str8_lit_comp("Resets the window to the simple panel layout."), str8_lit_comp("panel"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 1f829d00..68f92465 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -110,6 +110,7 @@ RD_CmdKind_ToggleFullscreen, RD_CmdKind_BringToFront, RD_CmdKind_PopupAccept, RD_CmdKind_PopupCancel, +RD_CmdKind_ResetToDefaultBindings, RD_CmdKind_ResetToDefaultPanels, RD_CmdKind_ResetToCompactPanels, RD_CmdKind_ResetToSimplePanels, @@ -567,7 +568,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[340]; +extern RD_VocabInfo rd_vocab_info_table[341]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 2a3efc82..b671872f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -810,6 +810,9 @@ RD_CmdTable: // | | | | {PopupAccept 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_accept" "Popup Accept" "Accepts the active popup prompt." "" "" } {PopupCancel 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "popup_cancel" "Popup Cancel" "Cancels the active popup prompt." "" "" } + //- rjf: keybindings + {ResetToDefaultBindings 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "reset_to_default_bindings" "Reset To Default Bindings" "Resets all keybindings to their defaults." "" "" } + //- rjf: panel splitting {ResetToDefaultPanels 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_default_panels" "Reset To Default Panel Layout" "Resets the window to the default panel layout." "panel" "" } {ResetToCompactPanels 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Window "reset_to_compact_panels" "Reset To Compact Panel Layout" "Resets the window to the compact panel layout." "panel" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 607fee83..08c78e06 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12536,6 +12536,29 @@ rd_frame(void) rd_state->popup_key = ui_key_zero(); }break; + //- rjf: keybindings + case RD_CmdKind_ResetToDefaultBindings: + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_CfgList all_keybindings = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("keybindings")); + for(RD_CfgNode *n = all_keybindings.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + RD_Cfg *keybindings = rd_cfg_new(user, str8_lit("keybindings")); + for EachElement(idx, rd_default_binding_table) + { + String8 name = rd_default_binding_table[idx].string; + RD_Binding binding = rd_default_binding_table[idx].binding; + RD_Cfg *binding_root = rd_cfg_new(keybindings, str8_zero()); + rd_cfg_new(binding_root, name); + rd_cfg_new(binding_root, os_g_key_cfg_string_table[binding.key]); + if(binding.modifiers & OS_Modifier_Ctrl) {rd_cfg_newf(binding_root, "ctrl");} + if(binding.modifiers & OS_Modifier_Shift) {rd_cfg_newf(binding_root, "shift");} + if(binding.modifiers & OS_Modifier_Alt) {rd_cfg_newf(binding_root, "alt");} + } + }break; + //- rjf: config path saving/loading/applying case RD_CmdKind_OpenRecentProject: { @@ -12666,22 +12689,7 @@ rd_frame(void) //- rjf: if config did not define any keybindings for the user, then we need to build a sensible default if(file_is_okay && kind == RD_CmdKind_OpenUser) { - RD_CfgList all_keybindings = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("keybindings")); - if(all_keybindings.count == 0) - { - RD_Cfg *keybindings = rd_cfg_new(file_root, str8_lit("keybindings")); - for EachElement(idx, rd_default_binding_table) - { - String8 name = rd_default_binding_table[idx].string; - RD_Binding binding = rd_default_binding_table[idx].binding; - RD_Cfg *binding_root = rd_cfg_new(keybindings, str8_zero()); - rd_cfg_new(binding_root, name); - rd_cfg_new(binding_root, os_g_key_cfg_string_table[binding.key]); - if(binding.modifiers & OS_Modifier_Ctrl) {rd_cfg_newf(binding_root, "ctrl");} - if(binding.modifiers & OS_Modifier_Shift) {rd_cfg_newf(binding_root, "shift");} - if(binding.modifiers & OS_Modifier_Alt) {rd_cfg_newf(binding_root, "alt");} - } - } + rd_cmd(RD_CmdKind_ResetToDefaultBindings); } //- rjf: record recently-opened projects in the user diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index f178571f..b84c3500 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -210,12 +210,6 @@ // attached (condition or label). (#407) // - Made several visual improvements. -//////////////////////////////// -//~ rjf: 0.9.16 TODO notes -// -// [ ] maybe add extra caching layer to process memory querying? we pay a pretty -// heavy cost even to just read 8 bytes... - //////////////////////////////// //~ rjf: post-0.9.16 TODO notes // @@ -306,6 +300,8 @@ // [ ] audio waveform views // //- eval improvements +// [ ] maybe add extra caching layer to process memory querying? we pay a pretty +// heavy cost even to just read 8 bytes... // [ ] evaluate `foo.bar` symbol names without escape hatch? // [ ] serializing eval view maps (?) // [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need From afd1f0c713357f3306ddc176d2b86c2f25a14eca Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 05:50:47 -0700 Subject: [PATCH 609/755] do not reset to default bindings if not needed... --- src/raddbg/raddbg_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 08c78e06..d0c173bb 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12689,7 +12689,11 @@ rd_frame(void) //- rjf: if config did not define any keybindings for the user, then we need to build a sensible default if(file_is_okay && kind == RD_CmdKind_OpenUser) { - rd_cmd(RD_CmdKind_ResetToDefaultBindings); + RD_CfgList all_keybindings = rd_cfg_child_list_from_string(scratch.arena, file_root, str8_lit("keybindings")); + if(all_keybindings.count == 0) + { + rd_cmd(RD_CmdKind_ResetToDefaultBindings); + } } //- rjf: record recently-opened projects in the user From 84e299e0810fc681dbcaef0007beebea25999247 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 05:56:41 -0700 Subject: [PATCH 610/755] readme adjustments --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index be4e9c25..8d8396ec 100644 --- a/README.md +++ b/README.md @@ -90,10 +90,11 @@ You should see the following output: ``` [debug mode] [msvc compile] +[default mode, assuming `raddbg` build] metagen_main.c -searching C:\devel\raddebugger/src... 309 files found -parsing metadesk... 15 metadesk files parsed -gathering tables... 96 tables found +searching C:\devel\raddebugger/src... 447 files found +parsing metadesk... 14 metadesk files parsed +gathering tables... 93 tables found generating layer code... raddbg_main.c ``` @@ -101,6 +102,16 @@ raddbg_main.c If everything worked correctly, there will be a `build` folder in the root level of the codebase, and it will contain a freshly-built `raddbg.exe`. +This `raddbg.exe` will have been built in **debug mode**, which is not built +with optimizations, and may perform worse. To produce a +**release mode executable**, run `build.bat` with a `release` argument: + +``` +build release +``` + +This build will take significantly longer. + ## Short-To-Medium-Term Roadmap ### The Initial Alpha Battle-Testing Phase From 2919ecb13502c76c53c51b47e4f2384a5fd92b86 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 06:25:47 -0700 Subject: [PATCH 611/755] more robustness to malformed expressions --- src/eval/eval_ir.c | 2 +- src/eval_visualization/eval_visualization_core.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 0f77359e..d24c6d39 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1353,7 +1353,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // left-hand-side of the dot operator as the first argument. this is a fast path // which prevents paren nesting in simple cases, to easily chain multiple // calls - for example, bin(2).digits(4) - else if(lhs->kind == E_ExprKind_MemberAccess) + else if(lhs->kind == E_ExprKind_MemberAccess && lhs->first->next != &e_expr_nil) { E_Expr *callee = lhs->first->next; E_Expr *first_arg = e_expr_ref(arena, lhs->first); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 1fec0f3e..7e8deaf1 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -557,6 +557,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root { expansion_row_count = viz_expand_info.row_count; } + expansion_row_count = Min(0x0fffffffffffffffull, expansion_row_count); // rjf: determine if this expansion supports child expansions B32 allow_child_expansions = 1; From 73d30759a1787fd7a90b0403c5844b79b4521b1e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 06:27:34 -0700 Subject: [PATCH 612/755] fix incorrect command usage in auto-run path --- src/raddbg/raddbg_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index b84c3500..622c9cc6 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -973,7 +973,7 @@ entry_point(CmdLine *cmd_line) if(auto_run) { auto_run = 0; - rd_cmd(RD_CmdKind_LaunchAndRun); + rd_cmd(RD_CmdKind_Run); } //- rjf: auto step From 4d6d4429e1ab06bf810199f138497e90c6419023 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 06:31:19 -0700 Subject: [PATCH 613/755] fix incorrect rad <-> turn conversion path --- src/base/base_math.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/base_math.h b/src/base/base_math.h index 21e238bf..e6f76423 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -386,8 +386,8 @@ struct Rng1S64Array #define floor_f32(v) floorf(v) #define round_f32(v) roundf(v) #define abs_f32(v) fabsf(v) -#define radians_from_turns_f32(v) ((v)*2*3.1415926535897f) -#define turns_from_radians_f32(v) ((v)/2*3.1415926535897f) +#define radians_from_turns_f32(v) ((v)*(2*3.1415926535897f)) +#define turns_from_radians_f32(v) ((v)/(2*3.1415926535897f)) #define degrees_from_turns_f32(v) ((v)*360.f) #define turns_from_degrees_f32(v) ((v)/360.f) #define degrees_from_radians_f32(v) (degrees_from_turns_f32(turns_from_radians_f32(v))) @@ -404,8 +404,8 @@ struct Rng1S64Array #define floor_f64(v) floor(v) #define round_f64(v) round(v) #define abs_f64(v) fabs(v) -#define radians_from_turns_f64(v) ((v)*2*3.1415926535897) -#define turns_from_radians_f64(v) ((v)/2*3.1415926535897) +#define radians_from_turns_f64(v) ((v)*(2*3.1415926535897)) +#define turns_from_radians_f64(v) ((v)/(2*3.1415926535897)) #define degrees_from_turns_f64(v) ((v)*360.0) #define turns_from_degrees_f64(v) ((v)/360.0) #define degrees_from_radians_f64(v) (degrees_from_turns_f64(turns_from_radians_f64(v))) From 1284c25b9e83a65a2ca46e79ed9233084a3883f0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 08:58:12 -0700 Subject: [PATCH 614/755] sketch out better usage of expansion info in text visualizer; notes; naming pass --- src/eval/eval_core.c | 55 ++- src/eval/eval_ir.c | 22 +- src/eval/eval_types.c | 68 ++-- src/eval/eval_types.h | 4 +- .../eval_visualization_core.c | 22 +- src/raddbg/raddbg_core.c | 14 +- src/raddbg/raddbg_eval.c | 12 +- src/raddbg/raddbg_main.c | 363 ------------------ src/raddbg/raddbg_views.c | 32 +- 9 files changed, 126 insertions(+), 466 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 394d67bf..ce82cff8 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1001,8 +1001,7 @@ e_value_eval_from_eval(E_Eval eval) // 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); + E_Type *type = e_type_from_key(type_key); U64 valid_bits_mask = 0; for(U64 idx = 0; idx < type->count; idx += 1) { @@ -1011,7 +1010,6 @@ e_value_eval_from_eval(E_Eval eval) 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 @@ -1222,19 +1220,44 @@ e_base_offset_from_eval(E_Eval eval) internal U64 e_range_size_from_eval(E_Eval eval) { - U64 result = 256; - E_TypeKey type_unwrapped = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); - E_TypeKind type_unwrapped_kind = e_type_kind_from_key(type_unwrapped); - if(type_unwrapped_kind == E_TypeKind_Array || - type_unwrapped_kind == E_TypeKind_Struct || - type_unwrapped_kind == E_TypeKind_Union || - type_unwrapped_kind == E_TypeKind_Class) + U64 result = KB(16); { - result = e_type_byte_size_from_key(type_unwrapped); - } - else - { - result = KB(16); + E_TypeKey type_core = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKind type_core_kind = e_type_kind_from_key(type_core); + B32 got_size = 0; + + // rjf: try getting size from expansions + if(!got_size) + { + E_TypeKey maybe_lens_type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_Meta); + E_TypeKind maybe_lens_type_kind = e_type_kind_from_key(maybe_lens_type_key); + if(maybe_lens_type_kind == E_TypeKind_Lens) + { + E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(maybe_lens_type_key); + if(expand_rule->info != 0) + { + Temp scratch = scratch_begin(0, 0); + U64 element_size = e_type_byte_size_from_key(e_type_key_unwrap(type_core, E_TypeUnwrapFlag_All)); + E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval, str8_zero()); + result = expand_info.expr_count * element_size; + got_size = 1; + scratch_end(scratch); + } + } + } + + // rjf: try getting size from intrinsic type (e.g. arrays/etc.) + if(!got_size) + { + if(type_core_kind == E_TypeKind_Array || + type_core_kind == E_TypeKind_Struct || + type_core_kind == E_TypeKind_Union || + type_core_kind == E_TypeKind_Class) + { + result = e_type_byte_size_from_key(type_core); + got_size = 1; + } + } } return result; } @@ -1314,7 +1337,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) type_key = e_type_key_direct(type_key), indent += 1) { - E_Type *type = e_type_from_key(scratch.arena, type_key); + E_Type *type = e_push_type_from_key(scratch.arena, type_key); str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]); } } diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index d24c6d39..62e88a1a 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -397,7 +397,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } if(match.kind == E_MemberKind_Null) { - E_Type *type = e_type_from_key__cached(check_type_key); + E_Type *type = e_type_from_key(check_type_key); if(type->enum_vals != 0) { String8 lookup_string = exprr->string; @@ -637,7 +637,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_TypeKind kind = e_type_kind_from_key(k); for(;kind == E_TypeKind_Lens;) { - E_Type *lens_type = e_type_from_key__cached(k); + E_Type *lens_type = e_type_from_key(k); if((lens_type->flags & E_TypeFlag_InheritedByMembers && expr->kind == E_ExprKind_MemberAccess) || (lens_type->flags & E_TypeFlag_InheritedByElements && expr->kind == E_ExprKind_ArrayIndex)) { @@ -649,11 +649,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } // rjf: pick access hook based on type - E_Type *lhs_type = e_type_from_key__cached(lhs_irtree_try->type_key); + E_Type *lhs_type = e_type_from_key(lhs_irtree_try->type_key); E_TypeAccessFunctionType *lhs_access = lhs_type->access; for(E_Type *lens_type = lhs_type; lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; - lens_type = e_type_from_key__cached(lens_type->direct_type_key)) + lens_type = e_type_from_key(lens_type->direct_type_key)) { if(lens_type->access != 0) { @@ -1292,7 +1292,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + E_Type *lhs_type = e_type_from_key(lhs_type_key); // rjf: calling a type? -> treat as a cast of that type if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec) @@ -2130,7 +2130,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { E_Expr *lens_spec_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, str8_lit("array")); E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; - E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); + E_Type *lens_spec_type = e_type_from_key(lens_spec_type_key); result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .flags = lens_spec_type->flags, .count = 1, @@ -2147,10 +2147,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: if the evaluated type has a hook for an extra layer of ir extension, // call into it - E_Type *type = e_type_from_key__cached(result.type_key); + E_Type *type = e_type_from_key(result.type_key); { E_TypeIRExtFunctionType *irext = type->irext; - for(E_Type *t = type; t->kind == E_TypeKind_Lens || t->kind == E_TypeKind_Set; t = e_type_from_key__cached(t->direct_type_key)) + for(E_Type *t = type; t->kind == E_TypeKind_Lens || t->kind == E_TypeKind_Set; t = e_type_from_key(t->direct_type_key)) { if(t->irext != 0) { @@ -2182,7 +2182,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 if(ptee_kind == E_TypeKind_Struct || ptee_kind == E_TypeKind_Class) { - E_Type *ptee_type = e_type_from_key__cached(ptee_key); + E_Type *ptee_type = e_type_from_key(ptee_key); B32 has_vtable = 0; for(U64 idx = 0; idx < ptee_type->count; idx += 1) { @@ -2282,10 +2282,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // if(inherited_lenses.count != 0) { - E_Type *result_type = e_type_from_key__cached(result.type_key); + E_Type *result_type = e_type_from_key(result.type_key); for(E_TypeKeyNode *n = inherited_lenses.first; n != 0; n = n->next) { - E_Type *src_type = e_type_from_key__cached(n->v); + E_Type *src_type = e_type_from_key(n->v); E_TypeKey dst_type_key = e_type_key_cons(.kind = src_type->kind, .flags = src_type->flags, .name = src_type->name, diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 8f2d5345..a0293565 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -645,7 +645,7 @@ e_type_byte_size_from_key(E_TypeKey key) } internal E_Type * -e_type_from_key(Arena *arena, E_TypeKey key) +e_push_type_from_key(Arena *arena, E_TypeKey key) { ProfBeginFunction(); E_Type *type = &e_type_nil; @@ -1251,7 +1251,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) E_MemberList members_list = {0}; B32 members_need_offset_sort = 0; { - E_Type *root_type = e_type_from_key__cached(key); + E_Type *root_type = e_type_from_key(key); typedef struct Task Task; struct Task { @@ -1290,7 +1290,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key) t->inheritance_chain = e_type_key_list_copy(scratch.arena, &task->inheritance_chain); e_type_key_list_push(scratch.arena, &t->inheritance_chain, type->members[member_idx].type_key); t->type_key = type->members[member_idx].type_key; - t->type = e_type_from_key__cached(type->members[member_idx].type_key); + t->type = e_type_from_key(type->members[member_idx].type_key); SLLQueuePush(first_task, last_task, t); members_need_offset_sort = 1; } @@ -1390,14 +1390,14 @@ e_expand_rule_from_type_key(E_TypeKey key) { E_TypeExpandRule *rule = &e_type_expand_rule__default; { - E_Type *type = e_type_from_key__cached(e_type_key_unwrap(key, E_TypeUnwrapFlag_Meta)); + E_Type *type = e_type_from_key(e_type_key_unwrap(key, E_TypeUnwrapFlag_Meta)); if(type->expand.info != 0) { rule = &type->expand; } for(E_Type *lens_type = type; lens_type->kind == E_TypeKind_Lens || lens_type->kind == E_TypeKind_Set; - lens_type = e_type_from_key__cached(e_type_key_unwrap(lens_type->direct_type_key, E_TypeUnwrapFlag_Meta))) + lens_type = e_type_from_key(e_type_key_unwrap(lens_type->direct_type_key, E_TypeUnwrapFlag_Meta))) { if(lens_type->expand.info != 0) { @@ -1421,7 +1421,7 @@ e_type_key_direct(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); result = type->direct_type_key; }break; } @@ -1438,7 +1438,7 @@ e_type_key_owner(E_TypeKey key) case E_TypeKeyKind_Ext: case E_TypeKeyKind_Cons: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); result = type->owner_type_key; }break; } @@ -1554,8 +1554,8 @@ e_type_match(E_TypeKey l, E_TypeKey r) case E_TypeKind_Array: { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); + E_Type *lt = e_type_from_key(l); + E_Type *rt = e_type_from_key(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { result = 1; @@ -1564,8 +1564,8 @@ e_type_match(E_TypeKey l, E_TypeKey r) case E_TypeKind_Function: { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); + E_Type *lt = e_type_from_key(l); + E_Type *rt = e_type_from_key(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key)) { B32 params_match = 1; @@ -1586,8 +1586,8 @@ e_type_match(E_TypeKey l, E_TypeKey r) case E_TypeKind_Method: { - E_Type *lt = e_type_from_key__cached(l); - E_Type *rt = e_type_from_key__cached(r); + E_Type *lt = e_type_from_key(l); + E_Type *rt = e_type_from_key(r); if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key) && e_type_match(lt->owner_type_key, rt->owner_type_key)) @@ -1625,20 +1625,20 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr { default: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_Bitfield: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); e_type_lhs_string_from_key(arena, type->direct_type_key, out, prec, skip_return); str8_list_pushf(arena, out, ": %I64u", type->count); }break; case E_TypeKind_Modifier: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); if(type->flags & E_TypeFlag_Const) @@ -1662,7 +1662,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Class: case E_TypeKind_Alias: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); str8_list_pushf(arena, out, "%S ", type->name); }break; @@ -1672,7 +1672,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_IncompleteClass: keyword = str8_lit("class"); goto fwd_udt; fwd_udt:; { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); str8_list_pushf(arena, out, "%S ", type->name); @@ -1703,7 +1703,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Lens: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); str8_list_pushf(arena, out, "%S(", type->name); E_TypeKey direct = e_type_key_direct(key); String8 direct_string = e_type_string_from_key(arena, direct); @@ -1722,7 +1722,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_key_direct(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); str8_list_push(arena, out, str8_lit("*")); - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); if(type->count != 1) { str8_list_pushf(arena, out, ".%I64u", type->count); @@ -1745,10 +1745,10 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_MemberPtr: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); E_TypeKey direct = type->direct_type_key; e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - E_Type *container = e_type_from_key__cached(type->owner_type_key); + E_Type *container = e_type_from_key(type->owner_type_key); if(container->kind != E_TypeKind_Null) { str8_list_push(arena, out, push_str8_copy(arena, container->name)); @@ -1796,7 +1796,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Array: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1811,7 +1811,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Function: { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); if(prec == 1) { str8_list_push(arena, out, str8_lit(")")); @@ -1884,7 +1884,7 @@ e_default_expansion_type_from_key(E_TypeKey root_key) // if(e_type_kind_is_pointer_or_ref(kind)) { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); if(!e_type_key_match(e_type_key_basic(E_TypeKind_Void), type->direct_type_key)) { if(type->count == 1 && hit_1ptr) @@ -1965,7 +1965,7 @@ e_default_expansion_type_from_key(E_TypeKey root_key) //~ rjf: Cache Lookups internal E_Type * -e_type_from_key__cached(E_TypeKey key) +e_type_from_key(E_TypeKey key) { E_Type *type = &e_type_nil; { @@ -1984,7 +1984,7 @@ e_type_from_key__cached(E_TypeKey key) { node = push_array(e_cache->arena, E_TypeCacheNode, 1); node->key = key; - node->type = e_type_from_key(e_cache->arena, key); + node->type = e_push_type_from_key(e_cache->arena, key); SLLQueuePush(e_cache->type_cache_slots[slot_idx].first, e_cache->type_cache_slots[slot_idx].last, node); } type = node->type; @@ -2144,7 +2144,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) if(array_type_kind == E_TypeKind_Array || array_type_kind == E_TypeKind_Ptr) { - E_Type *array_type = e_type_from_key__cached(expand_type_key); + E_Type *array_type = e_type_from_key(expand_type_key); result.expr_count = array_type->count; did_expansion = 1; } @@ -2156,7 +2156,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) E_TypeKind enum_type_kind = e_type_kind_from_key(expand_type_key); if(enum_type_kind == E_TypeKind_Enum) { - E_Type *enum_type = e_type_from_key__cached(expand_type_key); + E_Type *enum_type = e_type_from_key(expand_type_key); result.expr_count = enum_type->count; did_expansion = 1; } @@ -2194,7 +2194,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) //- rjf: enum case -> the lookup-range will return a range of enum constants else if(expand_type_kind == E_TypeKind_Enum) { - E_Type *type = e_type_from_key__cached(expand_type_key); + E_Type *type = e_type_from_key(expand_type_key); Rng1U64 legal_idx_range = r1u64(0, type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -2236,14 +2236,14 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) E_TYPE_EXPAND_INFO_FUNCTION_DEF(only) { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); E_TypeExpandInfo info = {0, type->count}; return info; } E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); U64 out_idx = 0; for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { @@ -2260,7 +2260,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); String8Array allowed_children_array = {0}; { Temp scratch = scratch_begin(&arena, 1); @@ -2345,7 +2345,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence) E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); U64 count = 1; if(type->args != 0 && type->count > 0) E_ParentKey(eval.key) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 451dc8b0..0ce41cd2 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -89,7 +89,7 @@ internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); internal U64 e_hash_from_type(E_Type *type); internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key); -internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); +internal E_Type *e_push_type_from_key(Arena *arena, E_TypeKey key); internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b); internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key); internal E_TypeExpandRule *e_expand_rule_from_type_key(E_TypeKey key); @@ -112,7 +112,7 @@ internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key); //////////////////////////////// //~ rjf: Cache Lookups -internal E_Type *e_type_from_key__cached(E_TypeKey key); +internal E_Type *e_type_from_key(E_TypeKey key); internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 7e8deaf1..a9e70f6a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -89,7 +89,7 @@ ev_expansion_type_from_key(E_TypeKey type_key) // so, choose the current eval if(kind == E_TypeKind_Lens) { - E_Type *type = e_type_from_key__cached(key); + E_Type *type = e_type_from_key(key); if(type->expand.info != 0 || ev_expand_rule_from_string(type->name) != &ev_nil_expand_rule) { @@ -167,7 +167,7 @@ ev_type_key_is_editable(E_TypeKey type_key) }break; case E_TypeKind_Array: { - E_Type *type = e_type_from_key__cached(t); + E_Type *type = e_type_from_key(t); if(type->flags & E_TypeFlag_IsNotText) { result = 0; @@ -448,7 +448,7 @@ ev_expand_rule_from_type_key(E_TypeKey type_key) E_TypeKind kind = e_type_kind_from_key(k); for(;kind == E_TypeKind_Lens; k = e_type_key_direct(e_type_key_unwrap(k, E_TypeUnwrapFlag_Meta)), kind = e_type_kind_from_key(k)) { - E_Type *type = e_type_from_key__cached(k); + E_Type *type = e_type_from_key(k); EV_ExpandRule *candidate = ev_expand_rule_from_string(type->name); if(candidate != &ev_nil_expand_rule) { @@ -1420,7 +1420,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval e case E_TypeKind_Enum: { Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); String8 constant_name = {0}; for(U64 val_idx = 0; val_idx < type->count; val_idx += 1) { @@ -1560,7 +1560,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { if(it->top_task->redirect_to_sets_and_structs) { - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); if(type->flags & E_TypeFlag_ArrayLikeExpansion) { expansion_opener_symbol = str8_lit("["); @@ -1568,7 +1568,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } goto arrays_and_sets_and_structs; } - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); E_TypeKind element_type_kind = e_type_kind_from_key(e_type_key_unwrap(type->direct_type_key, E_TypeUnwrapFlag_All)); B32 lens_applied = 1; EV_StringParams lens_params = *params; @@ -1690,7 +1690,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) default:{}break; case 0: { - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); *out_string = push_str8f(arena, "%S (", type->name); need_pop = 0; need_new_task = 1; @@ -1706,7 +1706,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } else { - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); *out_string = type->name; } }break; @@ -1756,8 +1756,8 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { ptr_data = it->top_task->user_data = push_array(arena, EV_StringPtrData, 1); ptr_data->value_eval = e_value_eval_from_eval(eval); - ptr_data->type = e_type_from_key__cached(type_key); - ptr_data->direct_type = e_type_from_key__cached(e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All)); + ptr_data->type = e_type_from_key(type_key); + ptr_data->direct_type = e_type_from_key(e_type_key_unwrap(type_key, E_TypeUnwrapFlag_All)); ptr_data->ptee_has_content = (ptr_data->value_eval.value.u64 != 0 && ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || ptr_data->direct_type->kind == E_TypeKind_S8 || @@ -2081,7 +2081,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) if(expand_data == 0) { expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); - expand_data->type = e_type_from_key__cached(type_key); + expand_data->type = e_type_from_key(type_key); } switch(task_idx) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d0c173bb..279d6088 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2388,7 +2388,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) { Temp scratch = scratch_begin(0, 0); E_TypeKey type_key = eval.irtree.type_key; - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); String8 schema_name = str8_lit("watch"); B32 type_is_visualizer = 0; if(type->kind == E_TypeKind_Lens) @@ -3262,7 +3262,7 @@ rd_view_ui(Rng2F32 rect) case E_SpaceKind_File: case E_SpaceKind_FileSystem: { - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); String8 file = rd_file_path_from_eval(scratch.arena, eval); if(str8_match(type->name, str8_lit("folder"), 0)) { @@ -3954,7 +3954,7 @@ rd_view_ui(Rng2F32 rect) E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); if(block_type_kind == E_TypeKind_Set) { - E_Type *block_type = e_type_from_key__cached(block_type_key); + E_Type *block_type = e_type_from_key(block_type_key); group_cfg_name = rd_singular_from_code_name_plural(block_type->name); if(group_cfg_name.size == 0) { @@ -4303,7 +4303,7 @@ rd_view_ui(Rng2F32 rect) EV_Row *row = &row_node->row; F32 row_height = row_height_px*row->visual_size; RD_WatchRowInfo *row_info = &row_infos[local_row_idx]; - E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); + E_Type *block_type = e_type_from_key(row->block->eval.irtree.type_key); // rjf: determine if this row's block is good for the current drag/drop B32 block_is_good_for_drop = 0; @@ -4608,7 +4608,7 @@ rd_view_ui(Rng2F32 rect) B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_x && cell_x <= selection_tbl.max.x); RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, row_info, cell, ui_top_font(), ui_top_font_size(), visual_row_string_max_size_px); E_TypeKey cell_type_key = cell->eval.irtree.type_key; - E_Type *cell_type = e_type_from_key__cached(cell_type_key); + E_Type *cell_type = e_type_from_key(cell_type_key); E_Eval cell_value_eval = e_value_eval_from_eval(cell->eval); B32 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; @@ -4836,7 +4836,7 @@ rd_view_ui(Rng2F32 rect) RD_CellParams cell_params = {0}; ProfScope("form cell build parameters") { - E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); + E_Type *block_type = e_type_from_key(row->block->eval.irtree.type_key); B32 cells_are_editable = !!(block_type->flags & E_TypeFlag_EditableChildren); // rjf: set up base parameters @@ -5568,7 +5568,7 @@ rd_arch_from_eval(E_Eval eval) } // rjf: try arch arguments - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); if(type->kind == E_TypeKind_Lens) { for EachIndex(idx, type->count) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index e543ea33..7c848b68 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -26,7 +26,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) { Temp scratch = scratch_begin(&arena, 1); String8List cmd_names = {0}; - E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + E_Type *type = e_type_from_key(eval.irtree.type_key); for EachNonZeroEnumVal(RD_CmdKind, k) { RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; @@ -269,7 +269,7 @@ E_TYPE_IREXT_FUNCTION_DEF(schema) String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); E_TypeKey type_key = irtree->type_key; - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); ext->cfg = rd_cfg_from_eval_space(interpret.space); ext->entity = rd_ctrl_entity_from_eval_space(interpret.space); ext->schemas = rd_schemas_from_name(type->name); @@ -687,7 +687,7 @@ E_TYPE_IREXT_FUNCTION_DEF(cfgs_slice) //- rjf: determine which key we'll be gathering E_TypeKey type_key = irtree->type_key; - E_Type *type = e_type_from_key__cached(type_key); + E_Type *type = e_type_from_key(type_key); String8 cfg_name = rd_singular_from_code_name_plural(type->name); //- rjf: gather cfgs @@ -1423,7 +1423,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities) }break; case E_ExprKind_ArrayIndex: { - E_Type *type = e_type_from_key__cached(lhs_irtree->type_key); + E_Type *type = e_type_from_key(lhs_irtree->type_key); CTRL_EntityKind kind = ctrl_entity_kind_from_string(rd_singular_from_code_name_plural(type->name)); E_Value rhs_value = e_value_from_expr(expr->first->next); U64 rhs_idx = rhs_value.u64; @@ -1461,7 +1461,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) //- rjf: determine which type of child we're gathering E_TypeKey lhs_type_key = eval.irtree.type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + E_Type *lhs_type = e_type_from_key(lhs_type_key); String8 name = rd_singular_from_code_name_plural(lhs_type->name); CTRL_EntityKind entity_kind = ctrl_entity_kind_from_string(name); @@ -1548,7 +1548,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table) RDI_SectionKind section = RDI_SectionKind_NULL; { E_TypeKey lhs_type_key = eval.irtree.type_key; - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); + E_Type *lhs_type = e_type_from_key(lhs_type_key); if(0){} else if(str8_match(lhs_type->name, str8_lit("procedures"), 0)) {section = RDI_SectionKind_Procedures;} else if(str8_match(lhs_type->name, str8_lit("globals"), 0)) {section = RDI_SectionKind_GlobalVariables;} diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 622c9cc6..5cc5210c 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -1,215 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: 0.9.16 release notes -// -// - **Formal integration of views (view rules) into the evaluation language.** -// "View rules", now simply called "views", have been formally integrated -// into the debugger evaluation language. They now appear similar to function -// calls, and are expressed directly within an expression. For example, an -// expression `dynamic_array` with a view rule `slice` from prior versions -// would now be expressed as `slice(dynamic_array)`. Alternatively, views -// can be expressed with similar syntax to method calls: -// `dynamic_array.slice()`. Many views can still be attached to a single -// expression, like `dynamic_array.slice().hex()` (equivalent to -// `hex(slice(dynamic_array))`. The first argument to a view is the -// expression to which the view should apply. Some views take additional -// parameters, like `bitmap(base_pointer, width, height)`. Named parameters, -// required in some cases (e.g. the `fmt`/format parameter for `bitmap`), are -// expressed using `name = value` syntax: -// `bitmap(base, width, height, fmt=bgra8)`. -// - **Support for generics in type views (auto view rules)**. "Auto view -// rules", now simply called "type views", have been upgraded to support type -// pattern-matching. This makes them usable for generic types in various -// languages. This pattern-matching is done by using `?` characters in a -// pattern, to specify placeholders for various parts of a type name. For -// example, the pattern `DynamicArray` would match `DynamicArray`, -// `DynamicArray`, and so on. `?(?)` would match all function types. -// (#118, #345) -// - **Usage of the source expression within type views.** Type views have been -// upgraded to support a larger number of possibilities. Instead of mapping -// to a set of views which are applied to some other expression, type views -// can remap the expression itself, and apply additional views. These -// expressions can refer to the originating expression either explicitly -// using the `$` character, or implicitly in some cases. For instance, a type -// like `struct Bitmap {U8 *base; U32 width; U32 height;};` can be used in a -// type view which maps `Bitmap` to `bitmap(base, width, height)`. In this -// case, `base`, `width`, and `height` are recognized as being member names -// of `Bitmap`. This is equivalent to `bitmap($.base, $.width, $.height)`. -// - **Hardware data breakpoints.** Breakpoints have been upgraded to support -// flags for breaking on writing, reading, or execution, as well as an -// address range size. When used with an address location, this can be used -// to express hardware data breakpoints, where the CPU will break when it -// sees particular addresses being written to, read from, or executed, -// regardless of which code does it. There is a maximum limit of four such -// breakpoints on a processor. Theoretically, this means a limit of four per -// thread, but for now, the debugger only supports four global data -// breakpoints. In the future, we plan to allow organizing these by thread, -// in which case the total number of data breakpoints we support will -// increase. -// - **A new `table` view** has been added, which allows one to define custom -// rules for how rows of a watch expansion are formed. The first argument a -// `table` is the expression which should be evaluated (like other views), -// and the remaining arguments are used to express a number of expressions -// which should be used to generated cells for each row in the expansion. For -// instance, `table(my_int_array, $, $*4, $*8)` would expand `my_int_array`, -// but instead of the default row structure (which displays an expression -// string, a value string, and a type string), three cells would be generated -// per row: one with the value of each element, one with that value -// multiplied by 4, and one multiplied by 8. -// - **A new `sequence` view** has been added. This is a simple view which -// simply takes a single integer scalar argument `n`, and returns a sequence -// of integers, from `0`, `1`, `2`, all the way to `n`. This sequence can be -// expanded. This can compose with the `table` view, to easily generate `n` -// rows, and use each integer as a value in each cell expression. As an -// example, `table(sequence(1000), array1[$], array2[$])` would display -// elements of `array1` and `array2` in each row, side-by-side. -// - **The everything palette**. The F1 command palette has been replaced by a -// substantially more powerful "everything palette" (referred to in the UI -// simply as "palette"), opened with the `Open Palette` command. This palette -// lists commands and allows the editing of bindings, just like the old -// command palette (although it now also supports searching for command -// bindings themselves, in addition to the original searching support for -// command names and descriptions). However, this palette now also lists -// targets, breakpoints, recent files, recent projects, settings (including -// tab settings, window settings, user settings, project settings), attached -// processes, threads, modules, functions, types, and global variables. This -// can be used to quickly search for a large set of possible things, and -// either jump to them or edit them. The old `Run Command` command still -// exists, and still presents a command palette, which is simply a -// special-case of the generalized palette. But this command is no longer -// bound to F1 by default. -// - **Upgraded per-tab settings.** The tab right-click menu has been upgraded -// to show all tab-related settings, including ones specially-defined for -// specific visualizers (like the width and height parameters to the bitmap -// visualizer). The debugger UI now also supports per-tab font sizes. If a -// tab has no per-tab font size set, then it inherits the window's font size. -// Each tab's root expression is now also editable in this interface. The tab -// right-click menu's options also show up in the palette when the -// corresponding tab is focused. They can also be manually opened with the -// `Tab Settings` command. -// - **UI for setting the font.** The fonts which the debugger uses can now be -// set through settings UI (including the palette), rather than just through -// the configuration files. -// - **Support for searching system font folders for fonts.** The debugger now -// accepts system font file names in addition to full font file paths to -// specify font settings. -// - **Per-`Watch` expressions and labels.** Expressions inserted into a -// `Watch` tab are now stored per-tab. This makes many `Watch` tabs more -// useful, since different tabs can have a different set of expressions. -// `Watch` tabs can now also be labeled, so you can visually distinguish -// many `Watch` tabs more easily. -// - **Evaluation drag/drop.** Evaluations in a watch tree can be dragged and -// dropped. This can be used to create new top-level rows in a `Watch` tab, -// or to drag evaluations between `Watch` tabs, or to drag evaluations to -// source or disassembly views and pin the evaluation to some location there. -// (#137, #388) -// - **Settings expressions.** Debugger settings have been upgraded to be -// stored as expressions, rather than being locked to a specific value. -// These expressions are evaluated, like any other expression, and their -// evaluated value is used when the setting value is actually needed. -// - **Upgrades to the `slice` view.** The `slice` view has been streamlined -// and simplified. When an expression with a `slice` view is expanded, it -// will simply expand to the slice's contents, which matches the behavior -// with static arrays. The `slice` view now also supports -// `first, one_past_last` pointer pairs, as well as `base_pointer, length` -// pairs. -// - **Boolean evaluation toggle-switches.** The debugger now displays toggle -// switches as an additional visualization and editor for all boolean -// evaluations. -// - **A new `range1` view** has been added, which expresses bounds for some -// scalar value. When this view is used in an evaluation, the debugger will -// visualize the evaluation value with a slider, which can be used to edit -// the value as well. -// - **Merging of `Watch` UI with hover evaluation.** The hover evaluation -// feature has been majorly upgraded to support all features normally -// available in `Watch` tabs. (#342) -// - Added **transient tabs**, which are colored differently than normal tabs. -// These tabs are automatically opened by the debugger when snapping to -// source code which is not already opened. They are automatically replaced -// and recycled when the debugger needs to snap to new locations. This will -// greatly reduce the number of unused source code tabs accumulated -// throughout a debugging session. These tabs can still be promoted to -// permanent tabs, in which case they'll stay around until manually closed. -// - The `Scheduler` tab has been removed, in favor of three separate tabs, -// which present various versions of the same information: `Threads`, -// `Processes`, and `Machines`. The justification for this is that the -// common case is debugging a small number of programs, usually 1, and for -// those purposes, the `Threads` tab is sufficient if not desirable, and -// the extra information provided by `Processes` and `Machines`, while useful -// in other contexts, is not useful in that common case. The `Machines` tab -// now shows a superset of the information previously found in the -// `Scheduler` tab. -// - The two separate interfaces for editing threads, breakpoints, and watch -// pins (the right-click context menu and the dedicated tabs) have been -// merged. Both interfaces support exactly the same features in exactly the -// same way. The same interface is also accessible through the palette. -// - Added the ability to add a list of environment strings to targets. (#73) -// - The debugger releases are now packaged with a `raddbg_markup.h` -// single-header library which contains a number of source code markup tools -// which can be used in your programs. Some of these features are for direct -// interaction with the RAD Debugger. Others are simply helpers (often -// abstracting over platform functionality) for very commonly needed -// debugger-related features, like setting thread names. This second set of -// features will work with any debugger. Here is a list of this library's -// initial features (proper documentation will be written once the library -// matures): -// - `raddbg_is_attached()`: Returns 1 if the RAD Debugger is attached, -// otherwise returns 0. -// - `raddbg_break()`: Generates a trap instruction at the usage site. -// - `raddbg_break_if(expr)`: Generates a trap instruction guarded by a -// conditional, evaluating `expr`. -// - `raddbg_thread_name(format, ...)`, e.g. -// `raddbg_thread_name("worker_thread_%i", index)`: Sets the calling -// thread's name. -// - `raddbg_log(format, ...)`, e.g. -// `raddbg_log("This is a number: %i", 123)`: Writes a debug string for a -// debugger to read and display in its UI. -// - `raddbg_thread_color_u32(hexcode)`, e.g. -// `raddbg_thread_color_u32(0xff0000ff)`: Sets the calling thread's color. -// - Also can be done with individual `[0, 1]` color components: -// `raddbg_thread_color_rgba(1.f, 0.f, 0.f, 1.f)` -// - `raddbg_pin()`, e.g. -// `raddbg_pin(slice(dynamic_array))`: Like watch pins, but defined in -// source code. This is used by the debugger UI, but does not show up -// anywhere other than the source code, so it can either be used as a macro -// (which expands to nothing), or in comments too. -// - `raddbg_entry_point(name)`, e.g. `raddbg_entry_point(entry_point)`: -// declares the entry point for an executable, which the debugger will use -// when stepping into a program, rather than the defaults (e.g. `main`). -// - `raddbg_type_view(, )`, e.g. -// `raddbg_type_view(DynamicArray, slice($))`: declares a type view from -// source code, rather than from debugger configuration. -// - The debugger now incorporates the loaded project in all window titles. -// - Fixed an annoyance where the debugger would open a console window, even -// for graphical programs, causing a flicker. -// - Fixed substantial unnecessary memory usage with very large output logs. -// - Fixed a debugger regression which was incorrectly using thread name events -// when those events were sent to name a suspended thread by a different -// thread. (#430) -// - Added support for Tab and Shift + Tab style navigation in Watch tables, -// using the `Move Next` and `Move Previous` commands. (#93) -// - The debugger now correctly serializes window sizes when fullscreened. -// (#130) -// - Added an option to disable the Alt key Windows-style menu-bar focusing -// behavior. (#382) -// - Added an option to quickly duplicate configuration entities (targets, -// breakpoints, etc.). (#451) -// - Fixed a crash relating to truncated string hover tooltips when font sizes -// were changed. (#416) -// - Fixed the debugger's lack of robustness to selecting non-config files as -// config files. (#432, #409) -// - Fixed crashes caused by quick changes in the set of loaded modules while -// debug information table tabs (`Procedures`, `Globals`, `Types`) were open. -// (#467, #459, #458, #440, #436, #415, #412) -// - Fixed a crash where the debugger would crash when toggling fullscreen, if -// launched in fullscreen mode. (#454, #413) -// - Adjusted breakpoint placement to automatically deduplicate identical -// breakpoints, if placed at the same location, with no extra information -// attached (condition or label). (#407) -// - Made several visual improvements. - //////////////////////////////// //~ rjf: post-0.9.16 TODO notes // @@ -371,160 +162,6 @@ //////////////////////////////// //~ rjf: Recently Completed Task Log -// -// [x] filesystem drag/drop support -// [x] ** Converter performance & heuristics for asynchronously doing it early -// [x] icon fonts glyphs sometimes disappear for specific font size, but they -// reappear if you go +1 higher or -1 lower. Mostly red triangle in watch -// values for "unknown identifier". But also yellow arrow in call stack -// disappears if font size gets too large. -// [x] @cleanup central worker thread pool - eliminate per-layer thread pools -// [x] frontend config entities, serialization/deserialization, remove hacks, -// etc. - the entity structure should be dramatically simplified & made -// to reflect a more flexible string-tree data structure which can be -// more trivially derived from config, and more flexibly rearranged. -// drag/drop watch rows -> tabs, tabs -> watch rows, etc. -// [x] frontend entities need to be the "upstream state" for windows, panels, -// tabs, etc. - entities can be mapped to caches of window/panel/view state -// in purely immediate-mode fashion, so the only *state* part of the -// equation only has to do with the string tree. -// [x] watch table UI - hidden table boundaries, special-cased control hacks -// [x] hash store -> need to somehow hold on to hash blobs which are still -// depended upon by usage layers, e.g. extra dependency refcount, e.g. -// text cache can explicitly correllate nodes in its cache to hashes, -// bump their refcount - this would keep the hash correllated to its key -// and it would prevent it from being evicted (output debug string perf) -// [x] OutputDebugString spam, keeping way too much around! -// [x] auto view rule templates (?) -// [x] auto-view-rules likely should apply at each level in the expression -// tree -// [x] `slice` view rule - extend to support begin/end style as well -// [x] investigate false exceptions, being reported while stepping through init code -// [x] collapse upstream state for theme/bindings/settings into entities; use cache accelerators if needed to make up difference -// [x] collapse upstream state for windows/panels/tabs into entities; use downstream window/view resource cache to make up the difference -// [x] entity <-> mdesk paths -// [x] save view column pcts; generalize to being a first-class thing in -// RD_View, e.g. by just having a string -> f32 store -// [x] transient view timeout releasing -// [x] view rule editors in hover-eval -// [x] table column boundaries should be checked against *AFTER* table -// contents, not before -// [x] In a "hover watch" (where you hover over a variable and it shows a pop- -// up watch window), if you expand an item near the bottom of the listing, -// it will be clipped to the bottom of the listing instead of showing the -// actual items (ie., it doesn't resize the listing based on what's -// actually visible) -// [x] Right-clicking on a thread in the Scheduler window pops up a context -// menu, but you can't actually see it because the tooltip for the thread -// draws on top of it, so you can't see the menu. -// [x] double-click vs. single-click for folder navigation, see if we can infer -// [x] 'view rules' need to be rephrased as "function" calls in the expression language -// [x] need a formalization which takes unknown identifiers which are called, and tries -// to use that to apply a IR-generation rule, which is keyed by that unknown -// identifier -// [x] we need to select expressions as "parents" when possible, so that when using an -// auto-view-rule (or similar context), leaf identifiers referring to e.g. members -// of an expression's type resolve correctly (e.g. bitmap(base, width, height) being -// used as a shorthand for bitmap(foo.base, foo.width, foo.height) when evaluating -// foo). -// [x] single-line visualization busted with auto-view-rules applied, it seems... -// not showing member variables, just commas, check w/ mohit -// [x] r8 bitmap view rule seems incorrect? -// [x] font cache layer -> can probably cache (string*font*size) -> (run) too -// (not just rasterization)... would save a *lot*, there is a ton of work -// just in looking up & stitching stuff repeatedly -// [x] convert UI layout pass to not be naive recursive version -// [x] @feature header file for target -> debugger communication; printf, log, -// etc. -// [x] `slider:(min max)` view rule -// [x] `matrix` view rule -// [x] `each:(expr addition)` - apply some additional expression to all -// elements in an array/linked list would be useful to look at only a -// subset of an array of complex structs -// [x] @bug view-snapping in scroll-lists, accounting for mapping between -// visual positions & logical positions (variably sized rows in watch, -// table headers, etc.) -// [x] @cleanup straighten out index/number space & types & terminology for -// scroll lists -// [x] sort locals by appearance in source code (or maybe just debug info) -// [x] per-panel font size overrides -// [x] theme lister -> fonts & font sizes -// [x] make `array` view rule work with actual array types, to change their -// size dynamically -// [x] automatically start search query with selected text -// [x] @feature processor/data breakpoints -// [x] Setting the code_font/main_font values to a font name doesn't work. -// Should probably make note that you have to set it to a path to a TTF, -// since that's not normally how Windows fonts work. -// [x] I had to go into the user file to change the font. That should probably -// be in the theme window? -// [x] autocompletion lister, file lister, function lister, command lister, -// etc., all need to be merged, and optionally contextualized/filtered. -// right-clicking a tab should be equivalent to spawning a command lister, -// but only with commands that are directly -// [x] tab opening -// [x] query listers -// [x] watch-window-defined query completion -// [x] rebindings -// [x] correct breakpoint/watch pin location visualization -// [x] config saving/loading -// [x] "pin hover eval" -// [x] member filtering -// [x] filtering is busted on ctrl_entities, cgs -// [x] right-click menus -> specialize query -// [x] writing ctrl entity names -// [x] saved view rules need to be applied when watch loads!!! -// [x] mechanism to promote tab -> non-auto -// [x] focusing a hover eval makes icons disappear! (seems to only work with -// table demo in mule_main) -// [x] need to distinguish between auto-genn'd expressions and editable expressions -// in watches. if I put in array[0] in the watch window, it just shows up as -// [0] (same for member names, foo.a shows as .a) -// [x] types in watch windows are missing! -// [x] MISSING ERRORS IN WATCH WINDOW -// [x] fix everything lister stopping at targets? -// [x] strange bug where typing on a non-editable expression cell (e.g. bp -// right-click menu) causes cmd icons to shift over -// [x] acceleration pass: -// [x] default setting schema lookup -// [x] evaluation, esp. setting evaluation (evaluation cache) -// [x] string -> run? -// [x] fix glitchiness when mutating cfgs - the cfgs evaluations are cached, and -// never are recomputed!!!! -// [x] fix editing source locations textually -// [x] see if I can make padding member names nicer -// [x] settings / exception filters -// [x] why does 'cut' not work??? -// [x] disallow chained fast paths when evaluating callee in call expr -// [x] missing function type decorations in lister etc. -// [x] dynamic type resolution -// [x] ensure "file picking", for file path map remap, works -// [x] paths in cfg -> relativization on save, de-relativization on load -// [x] "add hover eval to watch" (expr drag & drop -> watch window) -// [x] unattached process evaluation - need a string to evaluate so I can generate -// the evals -// [x] save-to-project (command line targets) -// [x] odin's demo is busted - need to revert PDB conversion type index changes. -//- readme improvements -// [x] I was a little confused about what a profile file was. I understood -// what the user file was, but the profile file sounded like it should -// perhaps be per-project, yet it sounded like it was meant to be somewhat -// global? I don't have any feedback here because it probably will make -// sense once I use the debugger more, but I just thought I'd make a note -// to say that I was confused about it after reading the manual, so -// perhaps you could elaborate a little more on it in there. -// [x] It wasn't clear to me how you save a user or project file. I can see -// how to load them, but not how you save them. Obviously I can just copy -// the files myself in the shell, but it seemed weird that there was no -// "save" option in the menus. -// [x] user switching -// [x] project switching -// [x] do not apply filters past one block layer -// [x] "pop out" (hitting enter on visualizers should open them as tabs) -// [x] crash bug, release mode - filter globals view (try with debugging raddbg, typing `dev` in globals view) -// [x] fix operator precedence in (u64)&foo - merge prefix-unary parsing with atom parsing loop -// [x] finish theme editing, build themes - replace code colors map with new theme stuff -// [x] autocompletion lister //////////////////////////////// //~ rjf: Build Options diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5afb5e9f..f6488046 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -941,13 +941,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //////////////////////////// //- rjf: unpack row's evaluation, key, & block info // - E_Type *row_type = e_type_from_key__cached(row->eval.irtree.type_key); + E_Type *row_type = e_type_from_key(row->eval.irtree.type_key); EV_Key key = row->key; EV_Block *block = row->block; E_Eval block_eval = e_eval_from_key(row->block->eval.key); E_TypeKey block_type_key = e_type_key_unwrap(block_eval.irtree.type_key, E_TypeUnwrapFlag_Meta); E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - E_Type *block_type = e_type_from_key__cached(block_type_key); + E_Type *block_type = e_type_from_key(block_type_key); RD_Cfg *evalled_cfg = rd_cfg_from_eval_space(row->eval.space); CTRL_Entity *evalled_entity = (row->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity ? rd_ctrl_entity_from_eval_space(row->eval.space) : &ctrl_entity_nil); @@ -1086,7 +1086,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } else if(maybe_table_type->kind == E_TypeKind_Lens) { - maybe_table_type = e_type_from_key__cached(maybe_table_type->direct_type_key); + maybe_table_type = e_type_from_key(maybe_table_type->direct_type_key); continue; } else @@ -1125,7 +1125,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == E_SpaceKind_FileSystem) { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); + E_Type *type = e_type_from_key(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { String8 file_path = e_string_from_id(row->eval.value.u64); @@ -1325,7 +1325,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) // else if(row->eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - E_Type *type = e_type_from_key__cached(row->eval.irtree.type_key); + E_Type *type = e_type_from_key(row->eval.irtree.type_key); if(type->kind == E_TypeKind_Set) { rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, @@ -1539,8 +1539,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla ////////////////////////////// //- rjf: unpack evaluation // - E_Type *block_type = e_type_from_key__cached(row->block->eval.irtree.type_key); - E_Type *cell_type = e_type_from_key__cached(cell->eval.irtree.type_key); + E_Type *block_type = e_type_from_key(row->block->eval.irtree.type_key); + E_Type *cell_type = e_type_from_key(cell->eval.irtree.type_key); MD_NodePtrList cell_schemas = rd_schemas_from_name(cell_type->name); if(cell->eval.space.u64s[1] == 0 && cell_schemas.count != 0) { @@ -1554,7 +1554,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla result.file_path = rd_file_path_from_eval(arena, cell->eval); for(E_Type *type = cell_type; type->kind == E_TypeKind_Lens; - type = e_type_from_key__cached(type->direct_type_key)) + type = e_type_from_key(type->direct_type_key)) { RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(type->name); if(view_ui_rule != &rd_nil_view_ui_rule) @@ -1569,7 +1569,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // for(E_Type *type = cell_type; type->kind != E_TypeKind_Null; - type = e_type_from_key__cached(type->direct_type_key)) + type = e_type_from_key(type->direct_type_key)) { if(type->kind == E_TypeKind_MetaDescription) { @@ -1696,9 +1696,9 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: if this cell has a meta-display-name, then use that if(expr_string.size == 0) { - for(E_Type *t = e_type_from_key__cached(cell->eval.irtree.type_key); + for(E_Type *t = e_type_from_key(cell->eval.irtree.type_key); t != &e_type_nil; - t = e_type_from_key__cached(t->direct_type_key)) + t = e_type_from_key(t->direct_type_key)) { if(t->kind == E_TypeKind_MetaDisplayName) { @@ -1837,7 +1837,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // rjf: determine if code B32 is_code = 1; { - E_Type *type = e_type_from_key__cached(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_Meta)); + E_Type *type = e_type_from_key(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_Meta)); if(type->flags & (E_TypeFlag_IsPlainText|E_TypeFlag_IsPathText)) { is_code = 0; @@ -3744,7 +3744,7 @@ rd_eval_color_from_eval(E_Eval eval) LeafTask *last_task = first_task; for(LeafTask *t = first_task; t != 0 && num_components_left > 0; t = t->next) { - E_Type *type = e_type_from_key__cached(e_type_key_unwrap(t->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + E_Type *type = e_type_from_key(e_type_key_unwrap(t->eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); switch(type->kind) { default:{}break; @@ -3779,8 +3779,8 @@ rd_eval_color_from_eval(E_Eval eval) // (the lens implicitly tells us the format) RD_EvalColor result = {0}; { - E_Type *lens_type = e_type_from_key__cached(eval.irtree.type_key); - for(E_Type *t = lens_type; t->kind == E_TypeKind_Lens; t = e_type_from_key__cached(t->direct_type_key)) + E_Type *lens_type = e_type_from_key(eval.irtree.type_key); + for(E_Type *t = lens_type; t->kind == E_TypeKind_Lens; t = e_type_from_key(t->direct_type_key)) { if(str8_match(t->name, str8_lit("color"), 0)) { @@ -3940,7 +3940,7 @@ RD_VIEW_UI_FUNCTION_DEF(color) if(ui_dragging(h_sig) || ui_dragging(sv_sig) || ui_dragging(a_sig)) { // TODO(rjf): hard-coding U32 committing for now - E_Type *type = e_type_from_key__cached(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); + E_Type *type = e_type_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); if(type->kind == E_TypeKind_U32 || type->kind == E_TypeKind_S32 || type->kind == E_TypeKind_U64 || From cbc0ec12543101e27c3131f13336a616b365ba19 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 09:13:59 -0700 Subject: [PATCH 615/755] commit root-level split axis data on panel tree edits --- src/raddbg/raddbg_core.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 279d6088..33cd7533 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12974,6 +12974,14 @@ rd_frame(void) rd_cfg_equip_string(new_parent, str8_lit("panels")); RD_Cfg *window_cfg = rd_window_from_cfg(split_panel); rd_cfg_insert_child(window_cfg, window_cfg->last, new_parent); + if(split_axis == Axis2_X) + { + rd_cfg_child_from_string_or_alloc(window_cfg, str8_lit("split_x")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(window_cfg, str8_lit("split_x"))); + } } RD_Cfg *min = split_panel; RD_Cfg *max = new_sibling; @@ -13339,6 +13347,14 @@ rd_frame(void) // rjf: re-hook our kept child into the overall tree if(grandparent == &rd_nil_panel_node) { + if(keep_child->split_axis == Axis2_X) + { + rd_cfg_child_from_string_or_alloc(window, str8_lit("split_x")); + } + else + { + rd_cfg_release(rd_cfg_child_from_string(window, str8_lit("split_x"))); + } rd_cfg_equip_string(keep_child->cfg, str8_lit("panels")); rd_cfg_insert_child(window, window->last, keep_child->cfg); } From db2c8607fb76a4978be7aea2f3d828f3f519d461 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 09:23:42 -0700 Subject: [PATCH 616/755] clear breakpoints command --- src/raddbg/generated/raddbg.meta.c | 8 +++++--- src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 3 ++- src/raddbg/raddbg_core.c | 8 ++++++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 63c2536d..45b16fdb 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[341] = +RD_VocabInfo rd_vocab_info_table[342] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -351,6 +351,7 @@ RD_VocabInfo rd_vocab_info_table[341] = {str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, +{str8_lit_comp("clear_breakpoints"), str8_lit_comp(""), str8_lit_comp("Clear Breakpoints"), str8_lit_comp(""), RD_IconKind_Trash}, {str8_lit_comp("add_watch_pin"), str8_lit_comp(""), str8_lit_comp("Add Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("toggle_watch_pin"), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), str8_lit_comp(""), RD_IconKind_Pin}, {str8_lit_comp("add_type_view"), str8_lit_comp(""), str8_lit_comp("Add Type View"), str8_lit_comp(""), RD_IconKind_Binoculars}, @@ -421,7 +422,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, {str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, @@ -480,7 +481,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[234] = +RD_CmdKindInfo rd_cmd_kind_info_table[235] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -664,6 +665,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[234] = { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("clear_breakpoints"), str8_lit_comp("Removes all breakpoints."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_watch_pin"), str8_lit_comp("Places a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp("$watch_pins,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin at a given location (file path and line number or address)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_type_view"), str8_lit_comp("Adds a new type view."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 68f92465..93ee5fe2 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -238,6 +238,7 @@ RD_CmdKind_AddAddressBreakpoint, RD_CmdKind_ToggleBreakpoint, RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, +RD_CmdKind_ClearBreakpoints, RD_CmdKind_AddWatchPin, RD_CmdKind_ToggleWatchPin, RD_CmdKind_AddTypeView, @@ -568,7 +569,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[341]; +extern RD_VocabInfo rd_vocab_info_table[342]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index b671872f..368d55f1 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -591,7 +591,7 @@ RD_VocabTable: breakpoint, ``` @row_commands(enable_cfg, duplicate_cfg, remove_cfg) - @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint) + @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints) x: { 'label': code_string, @@ -983,6 +983,7 @@ RD_CmdTable: // | | | | {ToggleBreakpoint 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } {EnableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } {DisableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } + {ClearBreakpoints 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "clear_breakpoints" "Clear Breakpoints" "Removes all breakpoints." "" "" } //- rjf: watch pins {AddWatchPin 1 1 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 Pin "add_watch_pin" "Add Watch Pin" "Places a watch pin at a given location (file path and line number or address)." "" "$watch_pins," } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 33cd7533..3d49acfe 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15001,6 +15001,14 @@ rd_frame(void) { rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero(), .do_lister = 1); }break; + case RD_CmdKind_ClearBreakpoints: + { + RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); + for(RD_CfgNode *n = bps.first; n != 0; n = n->next) + { + rd_cfg_release(n->v); + } + }break; //- rjf: watch pins case RD_CmdKind_AddWatchPin: From 1cc5561f1f0fc143c82ca5b9c63bc9b82edc1d99 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 10:50:27 -0700 Subject: [PATCH 617/755] evaluate settings in raw mode, always --- src/mule/mule_main.cpp | 27 +++++++++++++++++++++++++++ src/raddbg/raddbg_core.c | 14 +++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index d5b43817..664e79f1 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1823,6 +1823,33 @@ fancy_viz_eval_tests(void) raddbg_pin(text(code_string, lang=c)); raddbg_pin(disasm(fancy_viz_eval_tests)); + //- rjf: table index lookups + struct + { + char *name; + int x; + int y; + int z; + } + nodes[] = + { + {"---", 1, 7, 3}, + {"---", 5, 4, 2}, + {"second", 12, 41, 22}, + {"---", 8, 9, 1}, + {"---", 1, 1, 1}, + {"first", 50, 50, 50}, + {"fourth", 7, 7, 7}, + {"---", 7, 12, 1}, + {"third", 27, 43, 41}, + {"---", 2, 17, 50}, + }; + int node_indices[] = + { + 5, 2, 8, 6 + }; + raddbg_pin(table(node_indices, nodes[$])); + //- rjf: bitmaps unsigned int background_color = 0x00000000; unsigned int main_color = 0xff2424ff; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3d49acfe..f790b368 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1386,7 +1386,7 @@ rd_setting_b32_from_name(String8 name) if(value.size != 0) { Temp scratch = scratch_begin(0, 0); - String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); + String8 expr = push_str8f(scratch.arena, "raw((bool)(%S))", value); E_Eval eval = e_eval_from_string(expr); result = !!e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); @@ -1402,7 +1402,7 @@ rd_setting_u64_from_name(String8 name) if(value.size != 0) { Temp scratch = scratch_begin(0, 0); - String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); + String8 expr = push_str8f(scratch.arena, "raw((uint64)(%S))", value); E_Eval eval = e_eval_from_string(expr); result = e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); @@ -1418,7 +1418,7 @@ rd_setting_f32_from_name(String8 name) if(value.size != 0) { Temp scratch = scratch_begin(0, 0); - String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); + String8 expr = push_str8f(scratch.arena, "raw((float32)(%S))", value); E_Eval eval = e_eval_from_string(expr); result = e_value_eval_from_eval(eval).value.f32; scratch_end(scratch); @@ -5515,7 +5515,7 @@ internal B32 rd_view_setting_b32_from_name(String8 name) { String8 string = rd_view_setting_from_name(name); - B32 result = !!e_value_from_stringf("(bool)(%S)", string).u64; + B32 result = !!e_value_from_stringf("raw((bool)(%S))", string).u64; return result; } @@ -5523,7 +5523,7 @@ internal U64 rd_view_setting_u64_from_name(String8 name) { String8 string = rd_view_setting_from_name(name); - U64 result = e_value_from_stringf("(uint64)(%S)", string).u64; + U64 result = e_value_from_stringf("raw((uint64)(%S))", string).u64; return result; } @@ -5531,7 +5531,7 @@ internal F32 rd_view_setting_f32_from_name(String8 name) { String8 string = rd_view_setting_from_name(name); - F32 result = e_value_from_stringf("(float32)(%S)", string).f32; + F32 result = e_value_from_stringf("raw((float32)(%S))", string).f32; return result; } @@ -5974,7 +5974,7 @@ rd_window_frame(void) MD_Node *value_child = md_child_from_string(n, str8_lit("value"), 0); U8 split_char = ' '; String8List tags = str8_split(scratch.arena, tags_child->first->string, &split_char, 1, 0); - U32 color_u32 = e_value_from_string(value_child->first->string).u32; + U32 color_u32 = e_value_from_stringf("raw(%S)", value_child->first->string).u32; Vec4F32 color_linear = linear_from_srgba(rgba_from_u32(color_u32)); ThemePatternNode *node = push_array(scratch.arena, ThemePatternNode, 1); node->pattern.tags = str8_array_from_list(rd_frame_arena(), &tags); From 9c296cb9b21516ae73ef5decc8fa51fba867290e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 14:19:39 -0700 Subject: [PATCH 618/755] fixes for arithmetic with bitfields; bitfield -> numeric value path in irtree generation; fix bad stomping / mutation when generating a synthetic UFCS tree --- src/eval/eval_ir.c | 34 ++++++++++++++++++++++++++- src/lib_raddbg_markup/raddbg_markup.h | 2 +- src/mule/mule_main.cpp | 34 +++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 62e88a1a..dc406f93 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -301,6 +301,20 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type { result = e_irtree_mem_read_type(arena, tree, type_key); } + if(e_type_kind_from_key(type_key) == E_TypeKind_Bitfield) + { + E_Type *type = e_type_from_key(type_key); + if(type->byte_size <= sizeof(U64)) + { + U64 valid_bits_mask = 0; + for(U64 idx = 0; idx < type->count; idx += 1) + { + valid_bits_mask |= (1ull<off)); + result = e_irtree_binary_op_u(arena, RDI_EvalOp_BitAnd, result, e_irtree_const_u(arena, valid_bits_mask)); + } + } return result; } @@ -1002,6 +1016,22 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); + + // rjf: resolve complex types to simple arithmetic tyeps + if(l_type_kind == E_TypeKind_Bitfield) + { + l_tree.root = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_tree.type_key); + l_type = e_type_key_unwrap(e_type_key_direct(l_tree.type_key), E_TypeUnwrapFlag_AllDecorative); + l_type_kind = e_type_kind_from_key(r_type); + l_tree.mode = E_Mode_Value; + } + if(r_type_kind == E_TypeKind_Bitfield) + { + r_tree.root = e_irtree_resolve_to_value(arena, r_tree.mode, r_tree.root, r_tree.type_key); + r_type = e_type_key_unwrap(e_type_key_direct(r_tree.type_key), E_TypeUnwrapFlag_AllDecorative); + r_type_kind = e_type_kind_from_key(r_type); + r_tree.mode = E_Mode_Value; + } if(l_type.kind == E_TypeKeyKind_Reg) { l_type_kind = E_TypeKind_U64; @@ -1012,6 +1042,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 r_type_kind = E_TypeKind_U64; r_type = e_type_key_basic(r_type_kind); } + + // rjf: unpack info about resolved types B32 l_is_pointer = (l_type_kind == E_TypeKind_Ptr); B32 l_is_decay = (l_type_kind == E_TypeKind_Array && l_tree.mode == E_Mode_Offset); B32 l_is_pointer_like = (l_is_pointer || l_is_decay); @@ -1355,7 +1387,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // calls - for example, bin(2).digits(4) else if(lhs->kind == E_ExprKind_MemberAccess && lhs->first->next != &e_expr_nil) { - E_Expr *callee = lhs->first->next; + E_Expr *callee = e_expr_ref(arena, lhs->first->next); E_Expr *first_arg = e_expr_ref(arena, lhs->first); E_Expr *call = e_push_expr(arena, E_ExprKind_Call, r1u64(0, 0)); e_expr_push_child(call, callee); diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 6a21c40d..4913a86c 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -34,7 +34,7 @@ # define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */ # define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__) # define raddbg_entry_point(...) raddbg_exe_data char raddbg_gen_data_id()[] = ("entry_point: \"" #__VA_ARGS__ "\"") -# define raddbg_type_view(type, ...) raddbg_exe_data char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") +# define raddbg_type_view(type, ...) raddbg_exe_data char raddbg_gen_data_id()[] = ("type_view: {type: ```" #type "```, expr: ```" #__VA_ARGS__ "```}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) #else diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 664e79f1..e2a3b06e 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -196,6 +196,25 @@ union Matrix4x4F32 }; raddbg_type_view(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); +union PackedF16 +{ + uint16_t v; + struct + { + uint16_t mantissa : 10; + uint16_t exponent : 5; + uint16_t sign : 1; + }; +}; +raddbg_type_view(PackedF16, + exponent == 0 ? (0.00006103515625f*mantissa/1024.f) : + (exponent == 31 && mantissa == 0 && sign == 1) ? "-infinity" : + (exponent == 31 && mantissa == 0 && sign == 1) ? "+infinity" : + (exponent == 31) ? "NaN" : + (exponent < 15) ? (1.f/(1<<(15 - exponent)) * (sign * -2 + 1.f) * (1.f + mantissa/1024.f)) : + (exponent > 15) ? ((1<<(exponent-15)) * (sign * -2 + 1.f) * (1.f + mantissa/1024.f)) : + ((sign * -2 + 1) * 1.f + mantissa/1024.f)); + enum Kind { Kind_None, @@ -1823,6 +1842,21 @@ fancy_viz_eval_tests(void) raddbg_pin(text(code_string, lang=c)); raddbg_pin(disasm(fancy_viz_eval_tests)); + //- rjf: half-floats + PackedF16 f16s[] = + { + {0x0001}, // ~0.000000059604645 + {0x03ff}, // ~0.000060975552 + {0x0400}, // ~0.00006103515625 + {0x3555}, // ~0.33325195 + {0x3bff}, // ~0.99951172 + {0x3c00}, // 1 + {0x3c01}, // 1.00097656 + {0x7bff}, // 65504, + {0x7c00}, // +inf + {0xfc00}, // -inf + }; + //- rjf: table index lookups struct { From 4f980c4820d5b21ff2f07a01e5f99bfdf50dc2b7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 14:36:39 -0700 Subject: [PATCH 619/755] correctly flag deletion editing commands as zeroing delta on selection --- src/raddbg/raddbg_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f790b368..3490fb0a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -15828,7 +15828,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; - evt.flags = UI_EventFlag_Delete; + evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; evt.delta_unit = UI_EventDeltaUnit_Char; evt.delta_2s32 = v2s32(+1, +0); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15839,7 +15839,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; - evt.flags = UI_EventFlag_Delete; + evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(+1, +0); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); @@ -15861,7 +15861,7 @@ rd_frame(void) RD_WindowState *ws = rd_window_state_from_cfg(window); UI_Event evt = zero_struct; evt.kind = UI_EventKind_Edit; - evt.flags = UI_EventFlag_Delete; + evt.flags = UI_EventFlag_Delete|UI_EventFlag_ZeroDeltaOnSelect; evt.delta_unit = UI_EventDeltaUnit_Word; evt.delta_2s32 = v2s32(-1, +0); ui_event_list_push(scratch.arena, &ws->ui_events, &evt); From a4367e02f21be3155a6d77c444fc478d8dc59085 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 14:58:23 -0700 Subject: [PATCH 620/755] pdb -> rdi: more gracefully handle ..s in file paths when building source line maps, normalized file paths, and path tree --- src/lib_rdi_make/rdi_make.c | 190 +++++++++++++++++++------------- src/rdi_from_pdb/rdi_from_pdb.c | 9 +- 2 files changed, 120 insertions(+), 79 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index a487fbf3..afc1ef9f 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -446,13 +446,13 @@ rdim_short_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -462,13 +462,13 @@ rdim_unsigned_short_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -478,13 +478,13 @@ rdim_int_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -494,13 +494,13 @@ rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -510,13 +510,13 @@ rdim_long_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -526,13 +526,13 @@ rdim_unsigned_long_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -542,13 +542,13 @@ rdim_long_long_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -558,13 +558,13 @@ rdim_unsigned_long_long_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -574,13 +574,13 @@ rdim_pointer_size_t_type_from_data_model(RDIM_DataModel data_model) { switch(data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null : break; + case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; + case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; + case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; + default: InvalidPath; } return RDI_TypeKind_NULL; } @@ -1309,12 +1309,12 @@ RDI_PROC RDIM_TypeChunkList rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) { RDIM_TypeChunkList list = {0}; - + RDI_U64 type_cap = (RDI_TypeKind_LastBuiltIn - RDI_TypeKind_FirstBuiltIn) + 2; - + // RDI_TypeKind_NULL rdim_type_chunk_list_push(arena, &list, type_cap); - + for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) { RDIM_Type *type = rdim_type_chunk_list_push(arena, &list, type_cap); @@ -1322,13 +1322,13 @@ rdim_init_type_chunk_list(RDIM_Arena *arena, RDI_Arch arch) type->kind = type_kind; type->byte_size = rdi_size_from_basic_type_kind(type_kind); } - + RDIM_Type *void_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Void); void_type->byte_size = rdi_addr_size_from_arch(arch); - + RDIM_Type *handle_type = rdim_builtin_type_from_kind(list, RDI_TypeKind_Handle); handle_type->byte_size = rdi_addr_size_from_arch(arch); - + return list; } @@ -1921,6 +1921,25 @@ rdim_bake_path_node_from_string(RDIM_BakePathTree *tree, RDIM_String8 string) } } + // rjf: .. -> go up + if(sub_dir.RDIM_String8_SizeMember == 2 && + sub_dir.RDIM_String8_BaseMember[0] == '.' && + sub_dir.RDIM_String8_BaseMember[1] == '.') + { + sub_dir_node = node->parent; + if(sub_dir_node == 0) + { + sub_dir_node = &tree->root; + } + } + + // rjf: . -> stay here + else if(sub_dir.RDIM_String8_SizeMember == 1 && + sub_dir.RDIM_String8_BaseMember[0] == '.') + { + sub_dir_node = node; + } + // rjf: descend to child node = sub_dir_node; } @@ -1975,8 +1994,27 @@ rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_Stri } } + // rjf: .. -> go up + if(sub_dir.RDIM_String8_SizeMember == 2 && + sub_dir.RDIM_String8_BaseMember[0] == '.' && + sub_dir.RDIM_String8_BaseMember[1] == '.') + { + sub_dir_node = node->parent; + if(sub_dir_node == 0) + { + sub_dir_node = &tree->root; + } + } + + // rjf: . -> stay here + else if(sub_dir.RDIM_String8_SizeMember == 1 && + sub_dir.RDIM_String8_BaseMember[0] == '.') + { + sub_dir_node = node; + } + // rjf: no child -> make one - if(sub_dir_node == 0) + else if(sub_dir_node == 0) { sub_dir_node = rdim_push_array(arena, RDIM_BakePathNode, 1); RDIM_SLLQueuePush_N(tree->first, tree->last, sub_dir_node, next_order); @@ -3463,7 +3501,7 @@ RDI_PROC U64 rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) { U64 location_data_off = location_data_blobs->total_size; - + // rjf: nil location if(src_location == 0) { @@ -3523,7 +3561,7 @@ rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDI rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&loc))); }break; } - + return location_data_off; } @@ -3537,7 +3575,7 @@ rdim_bake_locset(RDIM_Arena *arena, if(locset.location_case_count > 0) { locset_idx = rdim_count_from_location_block_chunk_list(location_blocks); - + RDI_LocationBlock *dst_arr = rdim_location_block_chunk_list_push_array(arena, location_blocks, locset.location_case_count); RDI_LocationBlock *dst = dst_arr; for(RDIM_LocationCase *src = locset.first_location_case; src != 0; src = src->next, ++dst) @@ -3565,10 +3603,10 @@ rdim_bake_procedures(RDIM_Arena *arena, { RDIM_Symbol *src = &n->v[chunk_idx]; RDI_Procedure *dst = &procedures[dst_idx]; - + RDI_U32 frame_base_location_first = rdim_bake_locset(arena, location_blocks, location_data_blobs, src->frame_base); RDI_U32 frame_base_location_opl = frame_base_location_first + src->frame_base.location_case_count; - + dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); dst->link_name_string_idx = rdim_bake_idx_from_string(strings, src->link_name); if(src->is_extern) @@ -3612,7 +3650,7 @@ rdim_bake_scopes(RDIM_Arena *arena, RDI_Scope *scopes = rdim_push_array(arena, RDI_Scope, src->total_count+1); RDI_U64 *scope_voffs = rdim_push_array(arena, RDI_U64, src->scope_voff_count+1); RDI_Local *locals = rdim_push_array(arena, RDI_Local, src->local_count+1); - + RDIM_ProfScope("build all scopes, scope voffs, locals, and location blocks") { RDI_U64 dst_scope_idx = 1; diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index fd1620bf..7228b9d0 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -641,12 +641,15 @@ ASYNC_WORK_DEF(p2r_units_convert_work) // rjf: file name -> normalized file path String8 file_path = lines->file_name; String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); - for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) { - if(file_path_normalized.str[idx] == '\\') + for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) { - file_path_normalized.str[idx] = '/'; + if(file_path_normalized.str[idx] == '\\') + { + file_path_normalized.str[idx] = '/'; + } } + file_path_normalized = path_normalized_from_string(scratch.arena, file_path_normalized); } // rjf: normalized file path -> source file node From 7ded00af72462383e62d749bb9c3fb32151d79a1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 15:20:12 -0700 Subject: [PATCH 621/755] pdb -> rdi: correctly convert negative enumerate numerics; move enum value visualization into complex string-iterator visualization path, rather than hacking it into the simply-typed eval path (we want to generate a new task for the numeric value itself); handle negative enums correctly --- src/codeview/codeview_parse.c | 1324 +++++++++-------- .../eval_visualization_core.c | 54 + src/mule/mule_main.cpp | 1 + 3 files changed, 719 insertions(+), 660 deletions(-) diff --git a/src/codeview/codeview_parse.c b/src/codeview/codeview_parse.c index 94c72e43..57a0020c 100644 --- a/src/codeview/codeview_parse.c +++ b/src/codeview/codeview_parse.c @@ -137,6 +137,10 @@ cv_u64_from_numeric(CV_NumericParsed *num) U64 result = 0; switch(num->kind) { + case CV_NumericKind_CHAR: {result = (U64)(S64)*(S8*)num->val;}break; + case CV_NumericKind_SHORT: {result = (U64)(S64)*(S16*)num->val;}break; + case CV_NumericKind_LONG: {result = (U64)(S64)*(S32*)num->val;}break; + case CV_NumericKind_QUADWORD: {result = (U64)(S64)*(S64*)num->val;}break; case CV_NumericKind_USHORT: {result = *(U16*)num->val;}break; case CV_NumericKind_ULONG: {result = *(U32*)num->val;}break; case CV_NumericKind_UQUADWORD:{result = *(U64*)num->val;}break; @@ -273,144 +277,144 @@ internal CV_C13InlineSiteDecoderStep cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary_annots) { CV_C13InlineSiteDecoderStep result = {0}; - + for (; decoder->cursor < binary_annots.size && result.flags == 0; ) { U32 op = CV_InlineBinaryAnnotation_Null; decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &op); - + switch (op) { - case CV_InlineBinaryAnnotation_Null: { - decoder->cursor = binary_annots.size; - // this is last run, append range with left over code bytes - decoder->code_length = decoder->code_offset - decoder->code_offset_lo; - decoder->code_length_changed = 1; - } break; - case CV_InlineBinaryAnnotation_CodeOffset: { - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_offset); - decoder->code_offset_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: { - AssertAlways(!"TODO: test case"); - // U32 delta = 0; - // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta); - // decoder->code_offset_base = decoder->code_offset; - // decoder->code_offset_end = decoder->code_offset + delta; - // decoder->code_offset += delta; - } break; - case CV_InlineBinaryAnnotation_ChangeCodeOffset: { - U32 delta = 0; - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta); - - decoder->code_offset += delta; - - if (!decoder->code_offset_lo_changed) { - decoder->code_offset_lo = decoder->code_offset; - decoder->code_offset_lo_changed = 1; - } - decoder->code_offset_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeCodeLength: { - decoder->code_length = 0; - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length); - decoder->code_length_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeFile: { - U32 old_file_off = decoder->file_off; - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->file_off); - decoder->file_off_changed = old_file_off != decoder->file_off; - // Compiler isn't obligated to terminate code sequence before chaning files, - // so we have to always force emit code range on file change. - decoder->code_length_changed = decoder->file_off_changed; - } break; - case CV_InlineBinaryAnnotation_ChangeLineOffset: { - S32 delta = 0; - decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta); - - decoder->ln += delta; - decoder->ln_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeLineEndDelta: { - AssertAlways(!"TODO: test case"); - // S32 end_delta = 1; - // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta); - // decoder->ln += end_delta; - } break; - case CV_InlineBinaryAnnotation_ChangeRangeKind: { - AssertAlways(!"TODO: test case"); - // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &range_kind); - } break; - case CV_InlineBinaryAnnotation_ChangeColumnStart: { - AssertAlways(!"TODO: test case"); - // S32 delta; - // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta); - // decoder->cn += delta; - } break; - case CV_InlineBinaryAnnotation_ChangeColumnEndDelta: { - AssertAlways(!"TODO: test case"); - // S32 end_delta; - // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta); - // decoder->cn += end_delta; - } break; - case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: { - U32 code_offset_and_line_offset = 0; - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &code_offset_and_line_offset); - - S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4); - U32 code_delta = (code_offset_and_line_offset & 0xf); - - decoder->code_offset += code_delta; - decoder->ln += line_delta; - - if (!decoder->code_offset_lo_changed) { - decoder->code_offset_lo = decoder->code_offset; - decoder->code_offset_lo_changed = 1; - } - - decoder->code_offset_changed = 1; - decoder->ln_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: { - U32 offset_delta = 0; - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length); - decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &offset_delta); - - decoder->code_offset += offset_delta; - - if (!decoder->code_offset_lo_changed) { - decoder->code_offset_lo = decoder->code_offset; - decoder->code_offset_lo_changed = 1; - } - - decoder->code_offset_changed = 1; - decoder->code_length_changed = 1; - } break; - case CV_InlineBinaryAnnotation_ChangeColumnEnd: { - AssertAlways(!"TODO: test case"); - // U32 column_end = 0; - // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &column_end); - } break; + case CV_InlineBinaryAnnotation_Null: { + decoder->cursor = binary_annots.size; + // this is last run, append range with left over code bytes + decoder->code_length = decoder->code_offset - decoder->code_offset_lo; + decoder->code_length_changed = 1; + } break; + case CV_InlineBinaryAnnotation_CodeOffset: { + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_offset); + decoder->code_offset_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: { + AssertAlways(!"TODO: test case"); + // U32 delta = 0; + // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta); + // decoder->code_offset_base = decoder->code_offset; + // decoder->code_offset_end = decoder->code_offset + delta; + // decoder->code_offset += delta; + } break; + case CV_InlineBinaryAnnotation_ChangeCodeOffset: { + U32 delta = 0; + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta); + + decoder->code_offset += delta; + + if (!decoder->code_offset_lo_changed) { + decoder->code_offset_lo = decoder->code_offset; + decoder->code_offset_lo_changed = 1; + } + decoder->code_offset_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeCodeLength: { + decoder->code_length = 0; + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length); + decoder->code_length_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeFile: { + U32 old_file_off = decoder->file_off; + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->file_off); + decoder->file_off_changed = old_file_off != decoder->file_off; + // Compiler isn't obligated to terminate code sequence before chaning files, + // so we have to always force emit code range on file change. + decoder->code_length_changed = decoder->file_off_changed; + } break; + case CV_InlineBinaryAnnotation_ChangeLineOffset: { + S32 delta = 0; + decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta); + + decoder->ln += delta; + decoder->ln_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeLineEndDelta: { + AssertAlways(!"TODO: test case"); + // S32 end_delta = 1; + // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta); + // decoder->ln += end_delta; + } break; + case CV_InlineBinaryAnnotation_ChangeRangeKind: { + AssertAlways(!"TODO: test case"); + // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &range_kind); + } break; + case CV_InlineBinaryAnnotation_ChangeColumnStart: { + AssertAlways(!"TODO: test case"); + // S32 delta; + // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta); + // decoder->cn += delta; + } break; + case CV_InlineBinaryAnnotation_ChangeColumnEndDelta: { + AssertAlways(!"TODO: test case"); + // S32 end_delta; + // decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta); + // decoder->cn += end_delta; + } break; + case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: { + U32 code_offset_and_line_offset = 0; + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &code_offset_and_line_offset); + + S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4); + U32 code_delta = (code_offset_and_line_offset & 0xf); + + decoder->code_offset += code_delta; + decoder->ln += line_delta; + + if (!decoder->code_offset_lo_changed) { + decoder->code_offset_lo = decoder->code_offset; + decoder->code_offset_lo_changed = 1; + } + + decoder->code_offset_changed = 1; + decoder->ln_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: { + U32 offset_delta = 0; + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length); + decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &offset_delta); + + decoder->code_offset += offset_delta; + + if (!decoder->code_offset_lo_changed) { + decoder->code_offset_lo = decoder->code_offset; + decoder->code_offset_lo_changed = 1; + } + + decoder->code_offset_changed = 1; + decoder->code_length_changed = 1; + } break; + case CV_InlineBinaryAnnotation_ChangeColumnEnd: { + AssertAlways(!"TODO: test case"); + // U32 column_end = 0; + // decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &column_end); + } break; } - + U64 line_code_offset = decoder->code_offset; - + if (decoder->code_length_changed) { // compute upper bound of the range U64 code_offset_hi = decoder->code_offset + decoder->code_length; - + // can last code range be extended to cover current sequence too? if (decoder->last_range.max == decoder->parent_voff + decoder->code_offset_lo) { decoder->last_range.max = decoder->parent_voff + code_offset_hi; - + result.flags |= CV_C13InlineSiteDecoderStepFlag_ExtendLastRange; result.range = decoder->last_range; } else { decoder->last_range = rng_1u64(decoder->parent_voff + decoder->code_offset_lo, decoder->parent_voff + code_offset_hi); decoder->file_last_range = decoder->last_range; - + result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitRange; result.range = decoder->last_range; } - + // update state decoder->code_offset_lo = code_offset_hi; decoder->code_offset += decoder->code_length; @@ -418,18 +422,18 @@ cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary decoder->code_length_changed = 0; decoder->code_length = 0; } - + if (decoder->file_off_changed || (decoder->file_count == 0)) { result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitFile; result.file_off = decoder->file_off; - + // update state decoder->file_last_range = decoder->last_range; decoder->file_off_changed = 0; decoder->file_count += 1; decoder->file_line_count = 0; } - + if (decoder->code_offset_changed && decoder->ln_changed) { if (decoder->file_line_count == 0 || decoder->file_last_ln != decoder->ln) { result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitLine; @@ -437,18 +441,18 @@ cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary result.cn = decoder->cn; result.line_voff = decoder->parent_voff + line_code_offset; result.line_voff_end = decoder->last_range.max; - + // update state decoder->file_line_count += 1; decoder->file_last_ln = decoder->ln; } - + // update state decoder->code_offset_changed = 0; decoder->ln_changed = 0; } } - + return result; } @@ -459,9 +463,9 @@ cv_is_udt_name_anon(String8 name) { // corresponds to fUDTAnon from dbi/tm.cpp:817 B32 is_anon = str8_match_lit("", name, 0) || - str8_match_lit("__unnamed", name, 0) || - str8_match_lit("::", name, StringMatchFlag_RightSideSloppy) || - str8_match_lit("::__unnamed", name, StringMatchFlag_RightSideSloppy); + str8_match_lit("__unnamed", name, 0) || + str8_match_lit("::", name, StringMatchFlag_RightSideSloppy) || + str8_match_lit("::__unnamed", name, StringMatchFlag_RightSideSloppy); return is_anon; } @@ -469,15 +473,15 @@ internal B32 cv_is_udt(CV_LeafKind kind) { B32 is_udt = kind == CV_LeafKind_CLASS || - kind == CV_LeafKind_STRUCTURE || - kind == CV_LeafKind_CLASS2 || - kind == CV_LeafKind_STRUCT2 || - kind == CV_LeafKind_INTERFACE || - kind == CV_LeafKind_UNION || - kind == CV_LeafKind_ENUM || - kind == CV_LeafKind_UDT_MOD_SRC_LINE || - kind == CV_LeafKind_UDT_SRC_LINE || - kind == CV_LeafKind_ALIAS; + kind == CV_LeafKind_STRUCTURE || + kind == CV_LeafKind_CLASS2 || + kind == CV_LeafKind_STRUCT2 || + kind == CV_LeafKind_INTERFACE || + kind == CV_LeafKind_UNION || + kind == CV_LeafKind_ENUM || + kind == CV_LeafKind_UDT_MOD_SRC_LINE || + kind == CV_LeafKind_UDT_SRC_LINE || + kind == CV_LeafKind_ALIAS; return is_udt; } @@ -485,13 +489,13 @@ internal B32 cv_is_global_symbol(CV_SymKind kind) { B32 is_global_symbol = kind == CV_SymKind_CONSTANT || - kind == CV_SymKind_GDATA16 || - kind == CV_SymKind_GDATA32_16t || - kind == CV_SymKind_GDATA32_ST || - kind == CV_SymKind_GDATA32 || - kind == CV_SymKind_GTHREAD32_16t || - kind == CV_SymKind_GTHREAD32_ST || - kind == CV_SymKind_GTHREAD32; + kind == CV_SymKind_GDATA16 || + kind == CV_SymKind_GDATA32_16t || + kind == CV_SymKind_GDATA32_ST || + kind == CV_SymKind_GDATA32 || + kind == CV_SymKind_GTHREAD32_16t || + kind == CV_SymKind_GTHREAD32_ST || + kind == CV_SymKind_GTHREAD32; return is_global_symbol; } @@ -499,8 +503,8 @@ internal B32 cv_is_typedef(CV_SymKind kind) { B32 is_typedef = kind == CV_SymKind_UDT_16t || - kind == CV_SymKind_UDT_ST || - kind == CV_SymKind_UDT; + kind == CV_SymKind_UDT_ST || + kind == CV_SymKind_UDT; return is_typedef; } @@ -508,15 +512,15 @@ internal B32 cv_is_scope_symbol(CV_SymKind kind) { B32 is_scope = kind == CV_SymKind_GPROC32 || - kind == CV_SymKind_LPROC32 || - kind == CV_SymKind_BLOCK32 || - kind == CV_SymKind_THUNK32 || - kind == CV_SymKind_INLINESITE || - kind == CV_SymKind_INLINESITE2 || - kind == CV_SymKind_WITH32 || - kind == CV_SymKind_SEPCODE || - kind == CV_SymKind_GPROC32_ID || - kind == CV_SymKind_LPROC32_ID; + kind == CV_SymKind_LPROC32 || + kind == CV_SymKind_BLOCK32 || + kind == CV_SymKind_THUNK32 || + kind == CV_SymKind_INLINESITE || + kind == CV_SymKind_INLINESITE2 || + kind == CV_SymKind_WITH32 || + kind == CV_SymKind_SEPCODE || + kind == CV_SymKind_GPROC32_ID || + kind == CV_SymKind_LPROC32_ID; return is_scope; } @@ -524,8 +528,8 @@ internal B32 cv_is_end_symbol(CV_SymKind kind) { B32 is_end = kind == CV_SymKind_END || - kind == CV_SymKind_PROC_ID_END || - kind == CV_SymKind_INLINESITE_END; + kind == CV_SymKind_PROC_ID_END || + kind == CV_SymKind_INLINESITE_END; return is_end; } @@ -533,8 +537,8 @@ internal B32 cv_is_leaf_type_server(CV_LeafKind kind) { B32 is_type_server = kind == CV_LeafKind_TYPESERVER || - kind == CV_LeafKind_TYPESERVER2 || - kind == CV_LeafKind_TYPESERVER_ST; + kind == CV_LeafKind_TYPESERVER2 || + kind == CV_LeafKind_TYPESERVER_ST; return is_type_server; } @@ -542,8 +546,8 @@ internal B32 cv_is_leaf_pch(CV_LeafKind kind) { B32 is_pch = kind == CV_LeafKind_PRECOMP || - kind == CV_LeafKind_PRECOMP_ST || - kind == CV_LeafKind_PRECOMP_16t; + kind == CV_LeafKind_PRECOMP_ST || + kind == CV_LeafKind_PRECOMP_16t; return is_pch; } @@ -552,12 +556,12 @@ cv_type_index_source_from_leaf_kind(CV_LeafKind leaf_kind) { CV_TypeIndexSource source; if(leaf_kind == CV_LeafKind_FUNC_ID || - leaf_kind == CV_LeafKind_MFUNC_ID || - leaf_kind == CV_LeafKind_BUILDINFO || - leaf_kind == CV_LeafKind_SUBSTR_LIST || - leaf_kind == CV_LeafKind_STRING_ID || - leaf_kind == CV_LeafKind_UDT_SRC_LINE || - leaf_kind == CV_LeafKind_UDT_MOD_SRC_LINE) + leaf_kind == CV_LeafKind_MFUNC_ID || + leaf_kind == CV_LeafKind_BUILDINFO || + leaf_kind == CV_LeafKind_SUBSTR_LIST || + leaf_kind == CV_LeafKind_STRING_ID || + leaf_kind == CV_LeafKind_UDT_SRC_LINE || + leaf_kind == CV_LeafKind_UDT_MOD_SRC_LINE) { source = CV_TypeIndexSource_IPI; } @@ -579,10 +583,10 @@ cv_symbol_type_index_info_push(Arena *arena, CV_TypeIndexInfoList *list, CV_Type info->next = 0; info->offset = offset; info->source = source; - + SLLQueuePush(list->first, list->last, info); list->count += 1; - + return info; } @@ -591,63 +595,63 @@ cv_get_symbol_type_index_offsets(Arena *arena, CV_SymKind kind, String8 data) { CV_TypeIndexInfoList list = {0}; switch (kind) { - case CV_SymKind_BUILDINFO: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymBuildInfo, id)); - } break; - case CV_SymKind_GDATA32: - case CV_SymKind_LDATA32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymData32, itype)); - } break; - case CV_SymKind_LPROC32_ID: - case CV_SymKind_GPROC32_ID: - case CV_SymKind_LPROC32_DPC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymProc32, itype)); - } break; - case CV_SymKind_GPROC32: - case CV_SymKind_LPROC32: - case CV_SymKind_LPROC32_DPC: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymProc32, itype)); - } break; - case CV_SymKind_UDT: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymUDT, itype)); - } break; - case CV_SymKind_GTHREAD32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymThread32, itype)); - } break; - case CV_SymKind_FILESTATIC: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymFileStatic, itype)); - } break; - case CV_SymKind_LOCAL: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymLocal, itype)); - } break; - case CV_SymKind_REGREL32: - case CV_SymKind_BPREL32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegrel32, itype)); - } break; - case CV_SymKind_REGISTER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegister, itype)); - } break; - case CV_SymKind_CONSTANT: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymConstant, itype)); - } break; - case CV_SymKind_CALLSITEINFO: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymCallSiteInfo, itype)); - } break; - case CV_SymKind_CALLERS: - case CV_SymKind_CALLEES: - case CV_SymKind_INLINEES: { - Assert(data.size >= sizeof(CV_SymFunctionList)); - CV_SymFunctionList *func_list = (CV_SymFunctionList*)data.str; - for (U64 i = 0; i < func_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_SymFunctionList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_SymKind_INLINESITE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymInlineSite, inlinee)); - } break; - case CV_SymKind_HEAPALLOCSITE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymHeapAllocSite, itype)); - } break; + case CV_SymKind_BUILDINFO: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymBuildInfo, id)); + } break; + case CV_SymKind_GDATA32: + case CV_SymKind_LDATA32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymData32, itype)); + } break; + case CV_SymKind_LPROC32_ID: + case CV_SymKind_GPROC32_ID: + case CV_SymKind_LPROC32_DPC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymProc32, itype)); + } break; + case CV_SymKind_GPROC32: + case CV_SymKind_LPROC32: + case CV_SymKind_LPROC32_DPC: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymProc32, itype)); + } break; + case CV_SymKind_UDT: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymUDT, itype)); + } break; + case CV_SymKind_GTHREAD32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymThread32, itype)); + } break; + case CV_SymKind_FILESTATIC: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymFileStatic, itype)); + } break; + case CV_SymKind_LOCAL: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymLocal, itype)); + } break; + case CV_SymKind_REGREL32: + case CV_SymKind_BPREL32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegrel32, itype)); + } break; + case CV_SymKind_REGISTER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegister, itype)); + } break; + case CV_SymKind_CONSTANT: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymConstant, itype)); + } break; + case CV_SymKind_CALLSITEINFO: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymCallSiteInfo, itype)); + } break; + case CV_SymKind_CALLERS: + case CV_SymKind_CALLEES: + case CV_SymKind_INLINEES: { + Assert(data.size >= sizeof(CV_SymFunctionList)); + CV_SymFunctionList *func_list = (CV_SymFunctionList*)data.str; + for (U64 i = 0; i < func_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_SymFunctionList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_SymKind_INLINESITE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymInlineSite, inlinee)); + } break; + case CV_SymKind_HEAPALLOCSITE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymHeapAllocSite, itype)); + } break; } return list; } @@ -657,295 +661,295 @@ cv_get_leaf_type_index_offsets(Arena *arena, CV_LeafKind leaf_kind, String8 data { CV_TypeIndexInfoList list = {0}; switch (leaf_kind) { - case CV_LeafKind_NOTYPE: - case CV_LeafKind_VTSHAPE: - case CV_LeafKind_LABEL: - case CV_LeafKind_NULL: - case CV_LeafKind_NOTTRAN: { - // no type indices - } break; - case CV_LeafKind_MODIFIER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafModifier, itype)); - } break; - case CV_LeafKind_POINTER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafPointer, itype)); - CV_LeafPointer *ptr = (CV_LeafPointer *)data.str; - CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(ptr->attribs); - if (ptr_kind == CV_PointerKind_BaseType) { - // TODO: add CV_LeafPointerBaseType - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); - } else { - CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(ptr->attribs); - if (ptr_mode == CV_PointerMode_PtrMem || ptr_mode == CV_PointerMode_PtrMethod) { - // TODO: add type for the CvLeafPointerMember to syms_cv.mc + case CV_LeafKind_NOTYPE: + case CV_LeafKind_VTSHAPE: + case CV_LeafKind_LABEL: + case CV_LeafKind_NULL: + case CV_LeafKind_NOTTRAN: { + // no type indices + } break; + case CV_LeafKind_MODIFIER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafModifier, itype)); + } break; + case CV_LeafKind_POINTER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafPointer, itype)); + CV_LeafPointer *ptr = (CV_LeafPointer *)data.str; + CV_PointerKind ptr_kind = CV_PointerAttribs_Extract_Kind(ptr->attribs); + if (ptr_kind == CV_PointerKind_BaseType) { + // TODO: add CV_LeafPointerBaseType cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); - } - } - } break; - case CV_LeafKind_ARRAY: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, entry_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, index_itype)); - } break; - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - case CV_LeafKind_INTERFACE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, field_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, derived_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, vshape_itype)); - } break; - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, field_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, derived_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, vshape_itype)); - } break; - case CV_LeafKind_UNION: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUnion, field_itype)); - } break; - case CV_LeafKind_ALIAS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafAlias, itype)); - } break; - case CV_LeafKind_FUNC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafFuncId, scope_string_id)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafFuncId, itype)); - } break; - case CV_LeafKind_MFUNC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, owner_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, itype)); - } break; - case CV_LeafKind_STRING_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafStringId, substr_list_id)); - } break; - case CV_LeafKind_UDT_SRC_LINE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTSrcLine, udt_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTSrcLine, src_string_id)); - } break; - case CV_LeafKind_UDT_MOD_SRC_LINE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTModSrcLine, udt_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTModSrcLine, src_string_id)); - } break; - case CV_LeafKind_BUILDINFO: { - Assert(data.size >= sizeof(CV_LeafBuildInfo)); - CV_LeafBuildInfo *build_info = (CV_LeafBuildInfo *)data.str; - for (U16 i = 0; i < build_info->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafBuildInfo) + i * sizeof(CV_ItemId)); - } - } break; - case CV_LeafKind_ENUM: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, base_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, field_itype)); - } break; - case CV_LeafKind_PROCEDURE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, ret_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, arg_itype)); - } break; - case CV_LeafKind_MFUNCTION: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, ret_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, class_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, this_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, arg_itype)); - } break; - case CV_LeafKind_VFTABLE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, owner_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, base_table_itype)); - } break; - case CV_LeafKind_VFTPATH: { - Assert(sizeof(CV_LeafVFPath) <= data.size); - CV_LeafVFPath *vfpath = (CV_LeafVFPath *)data.str; - for (U32 i = 0; i < vfpath->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafVFPath) + i * sizeof(CV_TypeId)); - } - } break; - case CV_LeafKind_TYPESERVER: - case CV_LeafKind_TYPESERVER2: - case CV_LeafKind_TYPESERVER_ST: { - // no type indices - } break; - case CV_LeafKind_SKIP: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafSkip, itype)); - } break; - case CV_LeafKind_SUBSTR_LIST: { - Assert(sizeof(CV_LeafArgList) <= data.size); - CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; - for (U32 i = 0; i < arg_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_LeafKind_ARGLIST: { - Assert(sizeof(CV_LeafArgList) <= data.size); - CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; - for (U32 i = 0; i < arg_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_LeafKind_LIST: - case CV_LeafKind_FIELDLIST: { - for (U64 cursor = 0; cursor < data.size; ) { - CV_LeafKind list_member_kind = 0; - U64 read_size = str8_deserial_read_struct(data, cursor, &list_member_kind); - - if(read_size != sizeof(list_member_kind)) { - Assert(!"malformed LF_FIELDLIST"); - break; - } - cursor += read_size; - - switch (list_member_kind) { - default: Assert(!"TODO: handle malformed field member"); break; - case CV_LeafKind_INDEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafIndex, itype)); - cursor += sizeof(CV_LeafIndex); - } break; - case CV_LeafKind_MEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMember, itype)); - cursor += sizeof(CV_LeafMember); - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_STMEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafStMember, itype)); - cursor += sizeof(CV_LeafStMember); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_METHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethod, list_itype)); - cursor += sizeof(CV_LeafMethod); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_ONEMETHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafOneMethod, itype)); - - CV_LeafOneMethod onemethod; - cursor += str8_deserial_read_struct(data, cursor, &onemethod); - - CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(onemethod.attribs); - if(prop == CV_MethodProp_PureIntro || prop == CV_MethodProp_Intro) - { - cursor += sizeof(U32); // virtoff + } else { + CV_PointerMode ptr_mode = CV_PointerAttribs_Extract_Mode(ptr->attribs); + if (ptr_mode == CV_PointerMode_PtrMem || ptr_mode == CV_PointerMode_PtrMethod) { + // TODO: add type for the CvLeafPointerMember to syms_cv.mc + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); } - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_ENUMERATE: { - // no type index - cursor += sizeof(CV_LeafEnumerate); - CV_NumericParsed value; - cursor += cv_read_numeric(data, cursor, &value); - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_NESTTYPE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestType, itype)); - cursor += sizeof(CV_LeafNestType); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_NESTTYPEEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestTypeEx, itype)); - - cursor += sizeof(CV_LeafNestTypeEx); - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_BCLASS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafBClass, itype)); - - cursor += sizeof(CV_LeafBClass); - CV_NumericParsed offset; - cursor += cv_read_numeric(data, cursor, &offset); - } break; - case CV_LeafKind_VBCLASS: - case CV_LeafKind_IVBCLASS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVBClass, itype)); - cursor += sizeof(CV_LeafVBClass); - - CV_NumericParsed virtual_base_pointer; - cursor += cv_read_numeric(data, cursor, &virtual_base_pointer); - - CV_NumericParsed virtual_base_offset; - cursor += cv_read_numeric(data, cursor, &virtual_base_offset); - } break; - case CV_LeafKind_VFUNCTAB: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncTab, itype)); - cursor += sizeof(CV_LeafVFuncTab); - } break; - case CV_LeafKind_VFUNCOFF: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncOff, itype)); - cursor += sizeof(CV_LeafVFuncOff); - } break; } - cursor = AlignPow2(cursor, 4); - } - } break; - case CV_LeafKind_METHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMethod, list_itype)); - } break; - case CV_LeafKind_METHODLIST: { - for (U64 cursor = 0; cursor < data.size; ) { - // read method - CV_LeafMethodListMember method; - U64 read_size = str8_deserial_read_struct(data, cursor, &method); - - // error check read - if (read_size != sizeof(method)) { - Assert(!"malformed LF_METHODLIST"); - break; + } break; + case CV_LeafKind_ARRAY: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, entry_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, index_itype)); + } break; + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + case CV_LeafKind_INTERFACE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, field_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, derived_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, vshape_itype)); + } break; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, field_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, derived_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, vshape_itype)); + } break; + case CV_LeafKind_UNION: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUnion, field_itype)); + } break; + case CV_LeafKind_ALIAS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafAlias, itype)); + } break; + case CV_LeafKind_FUNC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafFuncId, scope_string_id)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafFuncId, itype)); + } break; + case CV_LeafKind_MFUNC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, owner_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, itype)); + } break; + case CV_LeafKind_STRING_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafStringId, substr_list_id)); + } break; + case CV_LeafKind_UDT_SRC_LINE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTSrcLine, udt_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTSrcLine, src_string_id)); + } break; + case CV_LeafKind_UDT_MOD_SRC_LINE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTModSrcLine, udt_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTModSrcLine, src_string_id)); + } break; + case CV_LeafKind_BUILDINFO: { + Assert(data.size >= sizeof(CV_LeafBuildInfo)); + CV_LeafBuildInfo *build_info = (CV_LeafBuildInfo *)data.str; + for (U16 i = 0; i < build_info->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafBuildInfo) + i * sizeof(CV_ItemId)); } - - // push type index offset - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethodListMember, itype)); - - // take into account intro virtual offset - CV_MethodProp mprop = CV_FieldAttribs_Extract_MethodProp(method.attribs); - if (mprop == CV_MethodProp_Intro || mprop == CV_MethodProp_PureIntro) { - read_size += sizeof(U32); + } break; + case CV_LeafKind_ENUM: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, base_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, field_itype)); + } break; + case CV_LeafKind_PROCEDURE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, ret_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, arg_itype)); + } break; + case CV_LeafKind_MFUNCTION: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, ret_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, class_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, this_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, arg_itype)); + } break; + case CV_LeafKind_VFTABLE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, owner_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, base_table_itype)); + } break; + case CV_LeafKind_VFTPATH: { + Assert(sizeof(CV_LeafVFPath) <= data.size); + CV_LeafVFPath *vfpath = (CV_LeafVFPath *)data.str; + for (U32 i = 0; i < vfpath->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafVFPath) + i * sizeof(CV_TypeId)); } - - // advance - cursor += read_size; - } - } break; - case CV_LeafKind_ONEMETHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafOneMethod, itype)); - } break; - case CV_LeafKind_BITFIELD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafBitField, itype)); - } break; - case CV_LeafKind_PRECOMP: - case CV_LeafKind_REFSYM: { - // no type indices - } break; - case CV_LeafKind_INDEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafIndex, itype)); - } break; - case CV_LeafKind_MEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMember, itype)); - } break; - case CV_LeafKind_VFUNCTAB: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncTab, itype)); - } break; - case CV_LeafKind_VFUNCOFF: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncOff, itype)); - } break; - case CV_LeafKind_NESTTYPE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestType, itype)); - } break; - case CV_LeafKind_NESTTYPEEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestTypeEx, itype)); - } break; - default: { - NotImplemented; - } break; + } break; + case CV_LeafKind_TYPESERVER: + case CV_LeafKind_TYPESERVER2: + case CV_LeafKind_TYPESERVER_ST: { + // no type indices + } break; + case CV_LeafKind_SKIP: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafSkip, itype)); + } break; + case CV_LeafKind_SUBSTR_LIST: { + Assert(sizeof(CV_LeafArgList) <= data.size); + CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; + for (U32 i = 0; i < arg_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_LeafKind_ARGLIST: { + Assert(sizeof(CV_LeafArgList) <= data.size); + CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; + for (U32 i = 0; i < arg_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_LeafKind_LIST: + case CV_LeafKind_FIELDLIST: { + for (U64 cursor = 0; cursor < data.size; ) { + CV_LeafKind list_member_kind = 0; + U64 read_size = str8_deserial_read_struct(data, cursor, &list_member_kind); + + if(read_size != sizeof(list_member_kind)) { + Assert(!"malformed LF_FIELDLIST"); + break; + } + cursor += read_size; + + switch (list_member_kind) { + default: Assert(!"TODO: handle malformed field member"); break; + case CV_LeafKind_INDEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafIndex, itype)); + cursor += sizeof(CV_LeafIndex); + } break; + case CV_LeafKind_MEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMember, itype)); + cursor += sizeof(CV_LeafMember); + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_STMEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafStMember, itype)); + cursor += sizeof(CV_LeafStMember); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_METHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethod, list_itype)); + cursor += sizeof(CV_LeafMethod); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_ONEMETHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafOneMethod, itype)); + + CV_LeafOneMethod onemethod; + cursor += str8_deserial_read_struct(data, cursor, &onemethod); + + CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(onemethod.attribs); + if(prop == CV_MethodProp_PureIntro || prop == CV_MethodProp_Intro) + { + cursor += sizeof(U32); // virtoff + } + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_ENUMERATE: { + // no type index + cursor += sizeof(CV_LeafEnumerate); + CV_NumericParsed value; + cursor += cv_read_numeric(data, cursor, &value); + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_NESTTYPE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestType, itype)); + cursor += sizeof(CV_LeafNestType); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_NESTTYPEEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestTypeEx, itype)); + + cursor += sizeof(CV_LeafNestTypeEx); + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_BCLASS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafBClass, itype)); + + cursor += sizeof(CV_LeafBClass); + CV_NumericParsed offset; + cursor += cv_read_numeric(data, cursor, &offset); + } break; + case CV_LeafKind_VBCLASS: + case CV_LeafKind_IVBCLASS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVBClass, itype)); + cursor += sizeof(CV_LeafVBClass); + + CV_NumericParsed virtual_base_pointer; + cursor += cv_read_numeric(data, cursor, &virtual_base_pointer); + + CV_NumericParsed virtual_base_offset; + cursor += cv_read_numeric(data, cursor, &virtual_base_offset); + } break; + case CV_LeafKind_VFUNCTAB: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncTab, itype)); + cursor += sizeof(CV_LeafVFuncTab); + } break; + case CV_LeafKind_VFUNCOFF: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncOff, itype)); + cursor += sizeof(CV_LeafVFuncOff); + } break; + } + cursor = AlignPow2(cursor, 4); + } + } break; + case CV_LeafKind_METHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMethod, list_itype)); + } break; + case CV_LeafKind_METHODLIST: { + for (U64 cursor = 0; cursor < data.size; ) { + // read method + CV_LeafMethodListMember method; + U64 read_size = str8_deserial_read_struct(data, cursor, &method); + + // error check read + if (read_size != sizeof(method)) { + Assert(!"malformed LF_METHODLIST"); + break; + } + + // push type index offset + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethodListMember, itype)); + + // take into account intro virtual offset + CV_MethodProp mprop = CV_FieldAttribs_Extract_MethodProp(method.attribs); + if (mprop == CV_MethodProp_Intro || mprop == CV_MethodProp_PureIntro) { + read_size += sizeof(U32); + } + + // advance + cursor += read_size; + } + } break; + case CV_LeafKind_ONEMETHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafOneMethod, itype)); + } break; + case CV_LeafKind_BITFIELD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafBitField, itype)); + } break; + case CV_LeafKind_PRECOMP: + case CV_LeafKind_REFSYM: { + // no type indices + } break; + case CV_LeafKind_INDEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafIndex, itype)); + } break; + case CV_LeafKind_MEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMember, itype)); + } break; + case CV_LeafKind_VFUNCTAB: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncTab, itype)); + } break; + case CV_LeafKind_VFUNCOFF: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncOff, itype)); + } break; + case CV_LeafKind_NESTTYPE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestType, itype)); + } break; + case CV_LeafKind_NESTTYPEEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestTypeEx, itype)); + } break; + default: { + NotImplemented; + } break; } return list; } @@ -954,34 +958,34 @@ internal CV_TypeIndexInfoList cv_get_inlinee_type_index_offsets(Arena *arena, String8 raw_data) { CV_TypeIndexInfoList list = {0}; - + U64 cursor = 0; - + // first four bytes are always signature CV_C13InlineeLinesSig sig = max_U32; cursor += str8_deserial_read_struct(raw_data, cursor, &sig); - + while(cursor < raw_data.size) { // read header CV_C13InlineeSourceLineHeader *header = (CV_C13InlineeSourceLineHeader *) str8_deserial_get_raw_ptr(raw_data, cursor, sizeof(CV_C13InlineeSourceLineHeader)); - + // store type index offset cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, cursor + OffsetOf(CV_C13InlineeSourceLineHeader, inlinee)); - + // advance past header cursor += sizeof(*header); - + // skip extra files B32 has_extra_files = (sig == CV_C13InlineeLinesSig_EXTRA_FILES); if (has_extra_files) - { + { U32 file_count = 0; cursor += str8_deserial_read_struct(raw_data, cursor, &file_count); cursor += /* file id: */ sizeof(U32) * file_count; } } - + return list; } @@ -993,17 +997,17 @@ cv_get_data_around_type_indices(Arena *arena, CV_TypeIndexInfoList ti_list, Stri { result.count = ti_list.count + 1; result.v = push_array_no_zero(arena, String8, result.count); - + U64 cursor = 0; U64 ti_idx = 0; - + for(CV_TypeIndexInfo *ti_info = ti_list.first; ti_info != 0; ti_info = ti_info->next, ++ti_idx) - { + { result.v[ti_idx].size = ti_info->offset - cursor; result.v[ti_idx].str = data.str + cursor; cursor = ti_info->offset + sizeof(CV_TypeIndex); } - + result.v[result.count-1].size = data.size - cursor; result.v[result.count-1].str = data.str + cursor; } @@ -1021,62 +1025,62 @@ cv_name_offset_from_symbol(CV_SymKind kind, String8 data) { U64 offset = data.size; switch (kind) { - case CV_SymKind_COMPILE: break; - case CV_SymKind_OBJNAME: break; - case CV_SymKind_THUNK32: { - offset = sizeof(CV_SymThunk32); - } break; - case CV_SymKind_LABEL32: { - offset = sizeof(CV_SymLabel32); - } break; - case CV_SymKind_REGISTER: { - offset = sizeof(CV_SymRegister); - } break; - case CV_SymKind_CONSTANT: { - offset = sizeof(CV_SymConstant); - CV_NumericParsed size; - offset += cv_read_numeric(data, offset, &size); - } break; - case CV_SymKind_UDT: { - offset = sizeof(CV_SymUDT); - } break; - case CV_SymKind_BPREL32: { - offset = sizeof(CV_SymBPRel32); - } break; - case CV_SymKind_LDATA32: - case CV_SymKind_GDATA32: { - offset = sizeof(CV_SymData32); - } break; - case CV_SymKind_PUB32: { - offset = sizeof(CV_SymPub32); - } break; - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - case CV_SymKind_LPROC32_ID: - case CV_SymKind_GPROC32_ID: { - offset = sizeof(CV_SymProc32); - } break; - case CV_SymKind_REGREL32: { - offset = sizeof(CV_SymRegrel32); - } break; - case CV_SymKind_LTHREAD32: - case CV_SymKind_GTHREAD32: { - offset = sizeof(CV_SymData32); - } break; - case CV_SymKind_COMPILE2: break; - case CV_SymKind_LOCALSLOT: { - offset = sizeof(CV_SymSlot); - } break; - case CV_SymKind_PROCREF: - case CV_SymKind_LPROCREF: - case CV_SymKind_DATAREF: { - offset = sizeof(CV_SymRef2); - } break; - case CV_SymKind_TRAMPOLINE: break; - case CV_SymKind_LOCAL: { - offset = sizeof(CV_SymLocal); - } break; - default: InvalidPath; + case CV_SymKind_COMPILE: break; + case CV_SymKind_OBJNAME: break; + case CV_SymKind_THUNK32: { + offset = sizeof(CV_SymThunk32); + } break; + case CV_SymKind_LABEL32: { + offset = sizeof(CV_SymLabel32); + } break; + case CV_SymKind_REGISTER: { + offset = sizeof(CV_SymRegister); + } break; + case CV_SymKind_CONSTANT: { + offset = sizeof(CV_SymConstant); + CV_NumericParsed size; + offset += cv_read_numeric(data, offset, &size); + } break; + case CV_SymKind_UDT: { + offset = sizeof(CV_SymUDT); + } break; + case CV_SymKind_BPREL32: { + offset = sizeof(CV_SymBPRel32); + } break; + case CV_SymKind_LDATA32: + case CV_SymKind_GDATA32: { + offset = sizeof(CV_SymData32); + } break; + case CV_SymKind_PUB32: { + offset = sizeof(CV_SymPub32); + } break; + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: + case CV_SymKind_LPROC32_ID: + case CV_SymKind_GPROC32_ID: { + offset = sizeof(CV_SymProc32); + } break; + case CV_SymKind_REGREL32: { + offset = sizeof(CV_SymRegrel32); + } break; + case CV_SymKind_LTHREAD32: + case CV_SymKind_GTHREAD32: { + offset = sizeof(CV_SymData32); + } break; + case CV_SymKind_COMPILE2: break; + case CV_SymKind_LOCALSLOT: { + offset = sizeof(CV_SymSlot); + } break; + case CV_SymKind_PROCREF: + case CV_SymKind_LPROCREF: + case CV_SymKind_DATAREF: { + offset = sizeof(CV_SymRef2); + } break; + case CV_SymKind_TRAMPOLINE: break; + case CV_SymKind_LOCAL: { + offset = sizeof(CV_SymLocal); + } break; + default: InvalidPath; } return offset; } @@ -1099,95 +1103,95 @@ cv_get_udt_info(CV_LeafKind kind, String8 data) CV_TypeProps props = 0; switch(kind) { - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - case CV_LeafKind_INTERFACE: { - U64 cursor = 0; + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + case CV_LeafKind_INTERFACE: { + U64 cursor = 0; + + CV_LeafStruct udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if (udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; - CV_LeafStruct udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: { + U64 cursor = 0; + + CV_LeafStruct2 udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if (udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); + case CV_LeafKind_UNION: { + U64 cursor = 0; + + CV_LeafUnion udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + props = udt.props; + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if(udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; - cursor += str8_deserial_read_cstr(data, cursor, &name); + case CV_LeafKind_ENUM: { + U64 cursor = 0; + + CV_LeafEnum udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if(udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; - if (udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: { - U64 cursor = 0; - - CV_LeafStruct2 udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if (udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_UNION: { - U64 cursor = 0; + // dbi/tpi.cpp:1332 + case CV_LeafKind_UDT_SRC_LINE: { + CV_LeafUDTSrcLine *src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTSrcLine)); + name = str8_struct(&src_line->udt_itype); + } break; + case CV_LeafKind_UDT_MOD_SRC_LINE: { + CV_LeafUDTModSrcLine *mod_src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTModSrcLine)); + name = str8_struct(&mod_src_line->udt_itype); + } break; - CV_LeafUnion udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - props = udt.props; + case CV_LeafKind_ALIAS: { + str8_deserial_read_cstr(data, 0, &name); + } break; - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if(udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_ENUM: { - U64 cursor = 0; - - CV_LeafEnum udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if(udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - // dbi/tpi.cpp:1332 - case CV_LeafKind_UDT_SRC_LINE: { - CV_LeafUDTSrcLine *src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTSrcLine)); - name = str8_struct(&src_line->udt_itype); - } break; - case CV_LeafKind_UDT_MOD_SRC_LINE: { - CV_LeafUDTModSrcLine *mod_src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTModSrcLine)); - name = str8_struct(&mod_src_line->udt_itype); - } break; - - case CV_LeafKind_ALIAS: { - str8_deserial_read_cstr(data, 0, &name); - } break; - - default: { - InvalidPath; - } break; + default: { + InvalidPath; + } break; } CV_UDTInfo info = {0}; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index a9e70f6a..d953c3d3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1417,6 +1417,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval e case E_TypeKind_RRef:{result = push_str8f(arena, "0x%I64x", eval.value.u64);}break; case E_TypeKind_Function:{result = push_str8f(arena, "0x%I64x", eval.value.u64);}break; +#if 0 case E_TypeKind_Enum: { Temp scratch = scratch_begin(&arena, 1); @@ -1452,6 +1453,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval e } scratch_end(scratch); }break; +#endif } return result; } @@ -1553,6 +1555,58 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) *out_string = ev_string_from_simple_typed_eval(arena, params, value_eval); }break; + ////////////////////////// + //- rjf: enums + // + case E_TypeKind_Enum: + { + switch(task_idx) + { + default:{}break; + case 0: + { + E_Type *type = e_type_from_key(type_key); + E_Eval value_eval = e_value_eval_from_eval(eval); + String8 constant_name = {0}; + for(U64 val_idx = 0; val_idx < type->count; val_idx += 1) + { + if(value_eval.value.u64 == type->enum_vals[val_idx].val) + { + constant_name = type->enum_vals[val_idx].name; + break; + } + } + String8 sufficient_suffix = constant_name; + if(str8_match(sufficient_suffix, type->name, StringMatchFlag_RightSideSloppy)) + { + sufficient_suffix = str8_skip(sufficient_suffix, type->name.size); + if(str8_match(sufficient_suffix, str8_lit("_"), StringMatchFlag_RightSideSloppy)) + { + sufficient_suffix = str8_skip(sufficient_suffix, 1); + } + } + *out_string = push_str8f(arena, "%S.%S", type->name, sufficient_suffix); + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + { + need_pop = 0; + } + }break; + case 1: + { + *out_string = str8_lit(" ("); + need_pop = 0; + need_new_task = 1; + new_task.params = *params; + new_task.eval = e_value_eval_from_eval(eval); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); + }break; + case 2: + { + *out_string = str8_lit(")"); + }break; + } + }break; + ////////////////////////// //- rjf: lenses // diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index e2a3b06e..f19eecbf 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -217,6 +217,7 @@ raddbg_type_view(PackedF16, enum Kind { + Kind_Negative = -1, Kind_None, Kind_First, Kind_Second, From 1929bcac0aff6114dd3cff0b5f9830c630795e6d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 15:20:49 -0700 Subject: [PATCH 622/755] defer to simple numeric evaluation if we cannot visualize an enum value by name --- .../eval_visualization_core.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index d953c3d3..e3ae7724 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1585,10 +1585,21 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) sufficient_suffix = str8_skip(sufficient_suffix, 1); } } - *out_string = push_str8f(arena, "%S.%S", type->name, sufficient_suffix); - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + if(sufficient_suffix.size != 0) { - need_pop = 0; + *out_string = push_str8f(arena, "%S.%S", type->name, sufficient_suffix); + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + { + need_pop = 0; + } + } + else + { + need_pop = 1; + need_new_task = 1; + new_task.params = *params; + new_task.eval = e_value_eval_from_eval(eval); + new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); } }break; case 1: From e7a4f407bb05bb13b20ff22716b7b2a30e94e088 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 15:24:23 -0700 Subject: [PATCH 623/755] use 'sufficient suffixes' when generating enum expansions --- src/eval/eval_types.c | 11 +++++- .../eval_visualization_core.c | 38 ------------------- src/raddbg/raddbg_core.c | 4 -- 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index a0293565..353dd018 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2202,7 +2202,16 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = type->enum_vals[member_idx].name; - evals_out[idx] = e_eval_wrapf(eval, "$.%S", member_name); + String8 sufficient_suffix = member_name; + if(str8_match(sufficient_suffix, type->name, StringMatchFlag_RightSideSloppy)) + { + sufficient_suffix = str8_skip(sufficient_suffix, type->name.size); + if(str8_match(sufficient_suffix, str8_lit("_"), StringMatchFlag_RightSideSloppy)) + { + sufficient_suffix = str8_skip(sufficient_suffix, 1); + } + } + evals_out[idx] = e_eval_wrapf(eval, "$.%S", sufficient_suffix); } } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index e3ae7724..97c68827 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1416,44 +1416,6 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval e case E_TypeKind_LRef:{result = push_str8f(arena, "0x%I64x", eval.value.u64);}break; case E_TypeKind_RRef:{result = push_str8f(arena, "0x%I64x", eval.value.u64);}break; case E_TypeKind_Function:{result = push_str8f(arena, "0x%I64x", eval.value.u64);}break; - -#if 0 - case E_TypeKind_Enum: - { - Temp scratch = scratch_begin(&arena, 1); - E_Type *type = e_type_from_key(type_key); - String8 constant_name = {0}; - for(U64 val_idx = 0; val_idx < type->count; val_idx += 1) - { - if(eval.value.u64 == type->enum_vals[val_idx].val) - { - constant_name = type->enum_vals[val_idx].name; - break; - } - } - String8 numeric_value_string = str8_from_u64(scratch.arena, eval.value.u64, params->radix, params->min_digits, digit_group_separator); - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) - { - if(constant_name.size != 0) - { - result = push_str8f(arena, "%S (%S)", numeric_value_string, constant_name); - } - else - { - result = push_str8_copy(arena, numeric_value_string); - } - } - else if(constant_name.size != 0) - { - result = push_str8_copy(arena, constant_name); - } - else - { - result = push_str8_copy(arena, numeric_value_string); - } - scratch_end(scratch); - }break; -#endif } return result; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3490fb0a..30b5a2e5 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9823,10 +9823,6 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) MemoryZeroStruct(&list_expr); } } - else if(e_type_kind_from_key(maybe_enum_type) == E_TypeKind_Enum) - { - list_expr = e_type_string_from_key(scratch.arena, maybe_enum_type); - } } // rjf: determine if autocompletion lister is allowed From 80f1a8b7ba24434630554844217d9082a79e51cc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 15:46:59 -0700 Subject: [PATCH 624/755] enum value filtering / lookup cache --- src/eval/eval_core.c | 2 + src/eval/eval_core.h | 68 ++++++++++++++++ src/eval/eval_types.c | 176 ++++++++++++++++++++++++++++++++++++++++-- src/eval/eval_types.h | 15 ++++ 4 files changed, 256 insertions(+), 5 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index ce82cff8..485b3386 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -650,6 +650,8 @@ e_select_base_ctx(E_BaseCtx *ctx) 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->enum_val_cache_slots_count = 256; + e_cache->enum_val_cache_slots = push_array(e_cache->arena, E_EnumValCacheSlot, e_cache->enum_val_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, diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 5138e754..4c9c8017 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -426,6 +426,21 @@ struct E_EnumVal U64 val; }; +typedef struct E_EnumValNode E_EnumValNode; +struct E_EnumValNode +{ + E_EnumValNode *next; + E_EnumVal v; +}; + +typedef struct E_EnumValList E_EnumValList; +struct E_EnumValList +{ + E_EnumValNode *first; + E_EnumValNode *last; + U64 count; +}; + typedef struct E_EnumValArray E_EnumValArray; struct E_EnumValArray { @@ -794,6 +809,55 @@ struct E_MemberCacheSlot E_MemberCacheNode *last; }; +//- rjf: enum val lookup cache types + +typedef struct E_EnumValHashNode E_EnumValHashNode; +struct E_EnumValHashNode +{ + E_EnumValHashNode *next; + U64 val_idx; +}; + +typedef struct E_EnumValHashSlot E_EnumValHashSlot; +struct E_EnumValHashSlot +{ + E_EnumValHashNode *first; + E_EnumValHashNode *last; +}; + +typedef struct E_EnumValFilterNode E_EnumValFilterNode; +struct E_EnumValFilterNode +{ + E_EnumValFilterNode *next; + String8 filter; + E_EnumValArray vals_filtered; +}; + +typedef struct E_EnumValFilterSlot E_EnumValFilterSlot; +struct E_EnumValFilterSlot +{ + E_EnumValFilterNode *first; + E_EnumValFilterNode *last; +}; + +typedef struct E_EnumValCacheNode E_EnumValCacheNode; +struct E_EnumValCacheNode +{ + E_EnumValCacheNode *next; + E_TypeKey key; + U64 val_hash_slots_count; + E_EnumValHashSlot *val_hash_slots; + U64 val_filter_slots_count; + E_EnumValFilterSlot *val_filter_slots; +}; + +typedef struct E_EnumValCacheSlot E_EnumValCacheSlot; +struct E_EnumValCacheSlot +{ + E_EnumValCacheNode *first; + E_EnumValCacheNode *last; +}; + //- rjf: used expression map typedef struct E_UsedExprNode E_UsedExprNode; @@ -966,6 +1030,10 @@ struct E_Cache U64 member_cache_slots_count; E_MemberCacheSlot *member_cache_slots; + //- rjf: [types] enum val cache table + U64 enum_val_cache_slots_count; + E_EnumValCacheSlot *enum_val_cache_slots; + //- rjf: [types] unpacked type cache U64 type_cache_slots_count; E_TypeCacheSlot *type_cache_slots; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 353dd018..6493b55e 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -222,6 +222,34 @@ e_member_array_from_list(Arena *arena, E_MemberList *list) return array; } +//////////////////////////////// +//~ rjf: Enum Value Functions + +internal void +e_enum_val_list_push(Arena *arena, E_EnumValList *list, E_EnumVal *enum_val) +{ + E_EnumValNode *n = push_array(arena, E_EnumValNode, 1); + MemoryCopyStruct(&n->v, enum_val); + SLLQueuePush(list->first, list->last, n); + list->count += 1; +} + +internal E_EnumValArray +e_enum_val_array_from_list(Arena *arena, E_EnumValList *list) +{ + E_EnumValArray array = {0}; + array.count = list->count; + array.v = push_array(arena, E_EnumVal, array.count); + { + U64 idx = 0; + for(E_EnumValNode *n = list->first; n != 0; n = n->next, idx += 1) + { + MemoryCopyStruct(&array.v[idx], &n->v); + } + } + return array; +} + //////////////////////////////// //~ rjf: Type Operation Functions @@ -1992,6 +2020,8 @@ e_type_from_key(E_TypeKey key) return type; } +//- rjf: member lookups + internal E_MemberCacheNode * e_member_cache_node_from_type_key(E_TypeKey key) { @@ -2111,6 +2141,141 @@ e_type_member_from_key_name__cached(E_TypeKey key, String8 name) return result; } +//- rjf: enum val lookups + +internal E_EnumValCacheNode * +e_enum_val_cache_node_from_type_key(E_TypeKey key) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&key)); + U64 slot_idx = hash%e_cache->enum_val_cache_slots_count; + E_EnumValCacheSlot *slot = &e_cache->enum_val_cache_slots[slot_idx]; + E_EnumValCacheNode *node = 0; + for(E_EnumValCacheNode *n = slot->first; n != 0; n = n->next) + { + if(e_type_key_match(n->key, key)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(e_cache->arena, E_EnumValCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = key; + E_Type *type = e_type_from_key(key); + if(type->kind == E_TypeKind_Enum) + { + node->val_hash_slots_count = type->count; + node->val_hash_slots = push_array(e_cache->arena, E_EnumValHashSlot, node->val_hash_slots_count); + node->val_filter_slots_count = 16; + node->val_filter_slots = push_array(e_cache->arena, E_EnumValFilterSlot, node->val_filter_slots_count); + for EachIndex(idx, type->count) + { + U64 hash = e_hash_from_string(5381, type->enum_vals[idx].name); + U64 slot_idx = hash%node->val_hash_slots_count; + E_EnumValHashNode *n = push_array(e_cache->arena, E_EnumValHashNode, 1); + SLLQueuePush(node->val_hash_slots[slot_idx].first, node->val_hash_slots[slot_idx].last, n); + n->val_idx = idx; + } + } + } + return node; +} + +internal E_EnumValArray +e_type_enum_vals_from_key_filter__cached(E_TypeKey key, String8 filter) +{ + E_EnumValArray enum_vals = {0}; + E_EnumValCacheNode *node = e_enum_val_cache_node_from_type_key(key); + if(node != 0) + { + if(filter.size == 0) + { + E_Type *type = e_type_from_key(key); + if(type->kind == E_TypeKind_Enum) + { + enum_vals.v = type->enum_vals; + enum_vals.count = type->count; + } + } + else + { + U64 hash = e_hash_from_string(5381, filter); + U64 slot_idx = hash%node->val_filter_slots_count; + E_EnumValFilterSlot *slot = &node->val_filter_slots[slot_idx]; + E_EnumValFilterNode *filter_node = 0; + for(E_EnumValFilterNode *n = slot->first; n != 0; n = n->next) + { + if(str8_match(n->filter, filter, 0)) + { + filter_node = n; + break; + } + } + if(filter_node == 0) + { + Temp scratch = scratch_begin(0, 0); + filter_node = push_array(e_cache->arena, E_EnumValFilterNode, 1); + filter_node->filter = push_str8_copy(e_cache->arena, filter); + E_Type *type = e_type_from_key(key); + E_EnumValList enum_val_list__filtered = {0}; + if(type->kind == E_TypeKind_Enum) + { + for EachIndex(idx, type->count) + { + E_EnumVal *enum_val = &type->enum_vals[idx]; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, enum_val->name); + if(matches.count == matches.needle_part_count) + { + e_enum_val_list_push(scratch.arena, &enum_val_list__filtered, enum_val); + } + } + } + filter_node->vals_filtered = e_enum_val_array_from_list(e_cache->arena, &enum_val_list__filtered); + scratch_end(scratch); + } + enum_vals = filter_node->vals_filtered; + } + } + return enum_vals; +} + +internal E_EnumValArray +e_type_enum_vals_from_key__cached(E_TypeKey key) +{ + E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(key, str8_zero()); + return enum_vals; +} + +internal E_EnumVal +e_type_enum_val_from_key_name__cached(E_TypeKey key, String8 name) +{ + E_EnumVal result = {0}; + E_EnumValCacheNode *node = e_enum_val_cache_node_from_type_key(key); + if(node != 0 && node->val_hash_slots_count != 0) + { + Temp scratch = scratch_begin(0, 0); + E_Type *type = e_type_from_key(key); + String8 name_qualified_0 = push_str8f(scratch.arena, "%S%S", type->name, name); + String8 name_qualified_1 = push_str8f(scratch.arena, "%S_%S", type->name, name); + U64 hash = e_hash_from_string(5381, name); + U64 slot_idx = hash%node->val_hash_slots_count; + for(E_EnumValHashNode *n = node->val_hash_slots[slot_idx].first; n != 0; n = n->next) + { + if(str8_match(type->enum_vals[n->val_idx].name, name, 0) || + str8_match(type->enum_vals[n->val_idx].name, name_qualified_0, 0) || + str8_match(type->enum_vals[n->val_idx].name, name_qualified_1, 0)) + { + result = type->enum_vals[n->val_idx]; + break; + } + } + scratch_end(scratch); + } + return result; +} + //////////////////////////////// //~ rjf: (Built-In Type Hooks) Default Hooks @@ -2156,8 +2321,8 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) E_TypeKind enum_type_kind = e_type_kind_from_key(expand_type_key); if(enum_type_kind == E_TypeKind_Enum) { - E_Type *enum_type = e_type_from_key(expand_type_key); - result.expr_count = enum_type->count; + E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(expand_type_key, filter); + result.expr_count = enum_vals.count; did_expansion = 1; } } @@ -2195,13 +2360,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) else if(expand_type_kind == E_TypeKind_Enum) { E_Type *type = e_type_from_key(expand_type_key); - Rng1U64 legal_idx_range = r1u64(0, type->count); + E_EnumValArray enum_vals = e_type_enum_vals_from_key_filter__cached(expand_type_key, filter); + Rng1U64 legal_idx_range = r1u64(0, enum_vals.count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - U64 member_idx = idx + read_range.min; - String8 member_name = type->enum_vals[member_idx].name; + U64 val_idx = idx + read_range.min; + String8 member_name = enum_vals.v[val_idx].name; String8 sufficient_suffix = member_name; if(str8_match(sufficient_suffix, type->name, StringMatchFlag_RightSideSloppy)) { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 0ce41cd2..4577152c 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -56,6 +56,13 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem #define e_member_list_push_new(arena, list, ...) e_member_list_push((arena), (list), &(E_Member){.kind = E_MemberKind_DataField, __VA_ARGS__}) internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list); +//////////////////////////////// +//~ rjf: Enum Value Functions + +internal void e_enum_val_list_push(Arena *arena, E_EnumValList *list, E_EnumVal *enum_val); +#define e_enum_val_list_push_new(arena, list, ...) e_enum_val_list_push((arena), (list), &(E_EnumVal){.val = 0, __VA_ARGS__}) +internal E_EnumValArray e_enum_val_array_from_list(Arena *arena, E_EnumValList *list); + //////////////////////////////// //~ rjf: Type Operation Functions @@ -113,11 +120,19 @@ internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key); //~ rjf: Cache Lookups internal E_Type *e_type_from_key(E_TypeKey key); + +//- rjf: member lookups internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); +//- rjf: enum val lookups +internal E_EnumValCacheNode *e_enum_val_cache_node_from_type_key(E_TypeKey key); +internal E_EnumValArray e_type_enum_vals_from_key_filter__cached(E_TypeKey key, String8 filter); +internal E_EnumValArray e_type_enum_vals_from_key__cached(E_TypeKey key); +internal E_EnumVal e_type_enum_val_from_key_name__cached(E_TypeKey key, String8 name); + //////////////////////////////// //~ rjf: (Built-In Type Hooks) Default Hooks From 43c1a5d68b3b5f13999ebdd21f772b885cc124a2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 16:00:06 -0700 Subject: [PATCH 625/755] oops, fix bad reset of autocompletion arena! --- src/raddbg/raddbg_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 30b5a2e5..847c9f06 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9787,6 +9787,8 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) RD_WindowState *ws = rd_window_state_from_cfg(window_cfg); if(ws->autocomp_last_frame_index < rd_state->frame_index) { + arena_clear(ws->autocomp_arena); + //- rjf: calculate information about the cursor: // * what list should we generate? // * what string in the input should we replace? @@ -9921,7 +9923,6 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) if(is_allowed) { ws->autocomp_last_frame_index = rd_state->frame_index; - arena_clear(ws->autocomp_arena); ws->autocomp_regs = rd_regs_copy(ws->autocomp_arena, regs); ws->autocomp_cursor_info = cursor_info; } From 64e12d059135bb514247a10f270b5839945e36cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 16:10:22 -0700 Subject: [PATCH 626/755] fix binary tool builds after usage of path in rdi_from_pdb layer --- src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c | 2 ++ src/rdi_from_pdb/rdi_from_pdb_main.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index f3c72e7e..6e6b71d0 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -21,6 +21,7 @@ //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" +#include "path/path.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" #include "coff/coff.h" @@ -38,6 +39,7 @@ //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" +#include "path/path.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" #include "coff/coff.c" diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index 9b2e49b5..a0d02a7d 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -19,6 +19,7 @@ //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" +#include "path/path.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" #include "coff/coff.h" @@ -35,6 +36,7 @@ //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" +#include "path/path.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" #include "coff/coff.c" From 54a0560cefb0154b899880f6c514c756d3a3c41f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 17:05:25 -0700 Subject: [PATCH 627/755] make window-level font size changing more strict wrt modifiers; do not accept ctrl+shift --- src/raddbg/raddbg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 847c9f06..041cd088 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9141,7 +9141,7 @@ rd_window_frame(void) // for(UI_Event *evt = 0; ui_next_event(&evt);) { - if(evt->kind == UI_EventKind_Scroll && evt->modifiers & OS_Modifier_Ctrl) + if(evt->kind == UI_EventKind_Scroll && evt->modifiers == OS_Modifier_Ctrl) { ui_eat_event(evt); if(evt->delta_2f32.y < 0) From ead193ee3ba17b32e19cd05917fef92e2f53218c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 May 2025 17:08:28 -0700 Subject: [PATCH 628/755] move enum value by-name lookup onto cached fastpath --- src/eval/eval_ir.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index dc406f93..b78a8aa3 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -412,29 +412,19 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) if(match.kind == E_MemberKind_Null) { E_Type *type = e_type_from_key(check_type_key); - if(type->enum_vals != 0) + String8 lookup_string = exprr->string; + String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); + String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); + E_EnumVal enum_val = {0}; + if(enum_val.name.size == 0) { enum_val = e_type_enum_val_from_key_name__cached(check_type_key, lookup_string); } + if(enum_val.name.size == 0) { enum_val = e_type_enum_val_from_key_name__cached(check_type_key, lookup_string_append_1); } + if(enum_val.name.size == 0) { enum_val = e_type_enum_val_from_key_name__cached(check_type_key, lookup_string_append_2); } + if(enum_val.name.size != 0) { - String8 lookup_string = exprr->string; - String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); - String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); - E_EnumVal *enum_val_match = 0; - for EachIndex(idx, type->count) - { - if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) - { - enum_val_match = &type->enum_vals[idx]; - break; - } - } - if(enum_val_match != 0) - { - r_found = 1; - r_type = check_type_key; - r_value = enum_val_match->val; - r_is_constant_value = 1; - } + r_found = 1; + r_type = check_type_key; + r_value = enum_val.val; + r_is_constant_value = 1; } } scratch_end(scratch); From a31840fd8ce9c406cd6a170c29646e68d5dd1ce3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 09:20:09 -0700 Subject: [PATCH 629/755] eliminate reload-active command binding - it is no longer a command --- src/raddbg/generated/raddbg.meta.c | 3 +-- src/raddbg/raddbg.mdesk | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 45b16fdb..e210208e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -720,7 +720,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[235] = { str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[114] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -763,7 +763,6 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = {str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, {str8_lit_comp("open_tab"), {OS_Key_T, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("open"), {OS_Key_O, 0 |OS_Modifier_Ctrl }}, -{str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("switch"), {OS_Key_I, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_Modifier_Alt}}, {str8_lit_comp("open_user"), {OS_Key_N, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift |OS_Modifier_Alt}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 368d55f1..c4d1b39d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1152,7 +1152,6 @@ RD_DefaultBindingTable: //- rjf: files { "open" O ctrl 0 0 } - { "reload_active" R ctrl shift 0 } { "switch" I ctrl 0 0 } { "switch_to_partner_file" O 0 0 alt } From b59e8e50240eb9c78d6c82020dac87c541d01dcd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 09:57:17 -0700 Subject: [PATCH 630/755] absolutify initial user/project paths; need absolute path information in order to relativize/absolutify paths in config --- src/raddbg/raddbg_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 041cd088..821f8552 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10678,6 +10678,17 @@ rd_init(CmdLine *cmdln) // rjf: unpack command line arguments String8 user_path = cmd_line_string(cmdln, str8_lit("user")); String8 project_path = cmd_line_string(cmdln, str8_lit("project")); + { + String8 initial_path = push_str8f(scratch.arena, "%S/", os_get_process_info()->initial_path); + if(user_path.size != 0) + { + user_path = path_absolute_dst_from_relative_dst_src(scratch.arena, user_path, initial_path); + } + if(project_path.size != 0) + { + project_path = path_absolute_dst_from_relative_dst_src(scratch.arena, project_path, initial_path); + } + } { String8 user_program_data_path = os_get_process_info()->user_program_data_path; String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); From e0202c5c1878a93ef7bc69140a654cfeb4f3868d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 10:23:46 -0700 Subject: [PATCH 631/755] path_pt schema type, which bundles a file path & textual location; use to do path relativization on serialize with breakpoints/watch pins --- src/raddbg/generated/raddbg.meta.c | 4 ++-- src/raddbg/raddbg.mdesk | 4 ++-- src/raddbg/raddbg_core.c | 33 ++++++++++++++++++++++-------- src/raddbg/raddbg_eval.c | 3 ++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index e210208e..51e8cb71 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -422,8 +422,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': string,\n 'address_location': expr_string,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, {str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index c4d1b39d..bd1a1cb0 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -596,7 +596,7 @@ RD_VocabTable: { 'label': code_string, 'condition': expr_string, - 'source_location': string, + 'source_location': path_pt, 'address_location': expr_string, 'hit_count': u64, 'address_range_size': @or(0, 1, 2, 4, 8) u64, @@ -617,7 +617,7 @@ RD_VocabTable: x: { 'expression': expr_string, - 'source_location': string, + 'source_location': path_pt, 'address_location': expr_string, } ```, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 821f8552..6732067c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -639,10 +639,17 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 root_path, String8 string) { String8 src_n_string = src_n->string; String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); - if(str8_match(schema->first->string, str8_lit("path"), 0) && - !md_node_has_tag(schema->first, str8_lit("absolute"), 0)) + if(!md_node_has_tag(schema->first, str8_lit("absolute"), 0)) { - src_n_string__raw = path_absolute_dst_from_relative_dst_src(scratch.arena, src_n_string__raw, root_path); + if(str8_match(schema->first->string, str8_lit("path"), 0)) + { + src_n_string__raw = path_absolute_dst_from_relative_dst_src(scratch.arena, src_n_string__raw, root_path); + } + else if(str8_match(schema->first->string, str8_lit("path_pt"), 0)) + { + String8TxtPtPair parts = str8_txt_pt_pair_from_string(src_n_string__raw); + src_n_string__raw = push_str8f(scratch.arena, "%S:%I64d:%I64d", path_absolute_dst_from_relative_dst_src(scratch.arena, parts.string, root_path), parts.pt.line, parts.pt.column); + } } dst_n_string = src_n_string__raw; } @@ -722,12 +729,21 @@ rd_string_from_cfg_tree(Arena *arena, String8 root_path, RD_Cfg *cfg) } // rjf: paths -> relativize - if(str8_match(c_schema->first->string, str8_lit("path"), 0) && - !md_node_has_tag(c_schema->first, str8_lit("absolute"), 0)) + if(!md_node_has_tag(c_schema->first, str8_lit("absolute"), 0)) { - String8 path_absolute = c->string; - String8 path_relative = path_relative_dst_from_absolute_dst_src(arena, path_absolute, root_path); - c_serialized_string = path_relative; + if(str8_match(c_schema->first->string, str8_lit("path"), 0)) + { + String8 path_absolute = c->string; + String8 path_relative = path_relative_dst_from_absolute_dst_src(arena, path_absolute, root_path); + c_serialized_string = path_relative; + } + else if(str8_match(c_schema->first->string, str8_lit("path_pt"), 0)) + { + String8 value = c->string; + String8TxtPtPair parts = str8_txt_pt_pair_from_string(value); + String8 path_relative = path_relative_dst_from_absolute_dst_src(scratch.arena, parts.string, root_path); + c_serialized_string = push_str8f(arena, "%S:%I64d:%I64d", path_relative, parts.pt.line, parts.pt.column); + } } // rjf: all strings -> escape @@ -1845,6 +1861,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path"), 0) || + str8_match(child_type_name, str8_lit("path_pt"), 0) || str8_match(child_type_name, str8_lit("code_string"), 0) || str8_match(child_type_name, str8_lit("expr_string"), 0) || str8_match(child_type_name, str8_lit("string"), 0)) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7c848b68..ff3e7ee3 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -327,7 +327,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsCodeText); } - else if(str8_match(child_schema->first->string, str8_lit("path"), 0)) + else if(str8_match(child_schema->first->string, str8_lit("path"), 0) || + str8_match(child_schema->first->string, str8_lit("path_pt"), 0)) { child_type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), child->first->string.size, E_TypeFlag_IsPathText); } From a95780f2be1fde0ceb7bb90a38f16278f3ae9b32 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 11:04:11 -0700 Subject: [PATCH 632/755] provide path for explicit cast operator in eval parser; abort trying c-style casts in non-trivial cases (the parse becomes ambiguous, and it is better for us to prefer the usual non-casting path --- src/eval/eval.mdesk | 2 +- src/eval/eval_parse.c | 56 ++++++++++++++++++++++++++++++++-- src/eval/generated/eval.meta.c | 2 +- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index b4760fca..3b8d0588 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -90,7 +90,7 @@ E_ExprKindTable: { Deref UnaryPrefix 2 "*" "" "" "" } { Address UnaryPrefix 2 "&" "" "" "" } - { Cast Null 1 "(" ")" "" "" } + { Cast Null 1 "cast(" ")" "" "" } { Sizeof UnaryPrefix 1 "sizeof " "" "" "" } { Typeof UnaryPrefix 1 "typeof " "" "" "" } { ByteSwap UnaryPrefix 1 "bswap " "" "" "" } diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 782b16eb..7fa4e4aa 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -873,7 +873,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; E_ExprKind prefix_unary_kind = 0; - Rng1U64 range = {0}; + E_Expr *prefix_unary_cast_expr = &e_expr_nil; // rjf: try op table for EachNonZeroEnumVal(E_ExprKind, k) @@ -887,6 +887,23 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t } } + // rjf: if we found a symbolic prefix unary operator, but we are + // looking for a casted expression, then we need to abort this + // path. C-style casts are only legal in very simple and unambiguous + // cases, e.g. (x)123, but they cannot be made legal in more + // complex cases like (x) * y, because this is fundamentally ambiguous + // (the meaning / tree shape / etc. is entirely different depending on + // the type / mode of `x`). + // + // because of things like hover-evaluation we do actually want to + // support basic C-style casts. but past a certain point of complexity, + // we will simply require usage of the explicit `cast` operator. + // + if(prefix_unary_precedence != 0 && atom_is_maybe_cast) + { + break; + } + // rjf: try 'unsigned' marker if(str8_match(token_string, str8_lit("unsigned"), 0)) { @@ -894,13 +911,46 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t prefix_unary_precedence = 2; } + // rjf: try explicit cast + if(str8_match(token_string, str8_lit("cast"), 0)) + { + // rjf: consume cast & open paren + E_Token open_paren_maybe = e_token_at_it(it+1, &tokens); + String8 open_paren_maybe_string = str8_substr(text, open_paren_maybe.range); + if(!str8_match(open_paren_maybe_string, str8_lit("("), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Expected `(` following `cast`."); + goto end_cast_parse; + } + it += 2; + + // rjf: parse type expression + E_Parse type_parse = e_push_parse_from_string_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + + // rjf: expect ) + E_Token close_paren_maybe = e_token_at_it(it, &tokens); + String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); + if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Missing `)`."); + } + + // rjf: fill prefix unary info + prefix_unary_kind = E_ExprKind_Cast; + prefix_unary_precedence = 2; + prefix_unary_cast_expr = type_parse.expr; + end_cast_parse:; + } + // rjf: push prefix unary if we got one if(prefix_unary_precedence != 0) { - range = token.range; PrefixUnaryTask *prefix_unary_task = push_array(scratch.arena, PrefixUnaryTask, 1); prefix_unary_task->kind = prefix_unary_kind; - prefix_unary_task->range = range; + prefix_unary_task->range = token.range; + prefix_unary_task->cast_type_expr = prefix_unary_cast_expr; SLLQueuePush(first_prefix_unary, last_prefix_unary, prefix_unary_task); it += 1; } diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 85f28611..28c61a6b 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -205,7 +205,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(""), str8_lit_comp("") }, +{ E_OpKind_Null, 1, str8_lit_comp("cast("), str8_lit_comp(")"), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, From ef974b8dc0387bdc3b1626b698e01f50080d1cae Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 12:03:12 -0700 Subject: [PATCH 633/755] begin sketching out the callee info helper, as an additional mechanism within the autocompletion system - find the call we're in, evaluate the callee, look up schema, show args/docs --- src/eval/eval_parse.c | 2 + src/raddbg/generated/raddbg.meta.c | 8 +-- src/raddbg/raddbg.mdesk | 16 ++--- src/raddbg/raddbg_core.c | 98 +++++++++++++++++++++++++++++- src/raddbg/raddbg_core.h | 1 + 5 files changed, 112 insertions(+), 13 deletions(-) diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 7fa4e4aa..980f2977 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1356,9 +1356,11 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token.range, "Unclosed `(`."); + call_expr->range.max = text.size; } else { + call_expr->range = union_1u64(call_expr->range, close_paren_maybe.range); it += 1; } } diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 51e8cb71..49c88fcc 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -408,14 +408,14 @@ RD_VocabInfo rd_vocab_info_table[342] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n @default('') 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n @default('') 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n @default('') 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n @default('') 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n @display_name('View Call Argument Helper') @description(\"Enables the view call argument helper, which shows view arguments and documentation, while typing expressions.\") @default(1)\n 'view_call_argument_helper': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, -{str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @override @display_name('Tab Font Size') @description(\"Controls the tab's font size.\")\n 'font_size': @range[6, 72] u64,\n}\n")}, +{str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @override @display_name('Tab Font Size') @description(\"Controls the tab's font size.\") @no_callee_helper\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, -{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index bd1a1cb0..fd46147b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -248,6 +248,8 @@ RD_VocabTable: //- rjf: autocompletion @display_name('Autocompletion Lister') @description("Enables the autocompletion lister while typing expressions.") @default(1) 'autocompletion_lister': bool, + @display_name('View Call Argument Helper') @description("Enables the view call argument helper, which shows view arguments and documentation, while typing expressions.") @default(1) + 'view_call_argument_helper': bool, //- rjf: thread & breakpoint decorations @default(1) @display_name('Thread Lines') @description("Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.") @@ -434,7 +436,7 @@ RD_VocabTable: @row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab) x: { - @override @display_name('Tab Font Size') @description("Controls the tab's font size.") + @override @display_name('Tab Font Size') @description("Controls the tab's font size.") @no_callee_helper 'font_size': @range[6, 72] u64, } ``` @@ -466,7 +468,7 @@ RD_VocabTable: 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers':bool, - @no_revert @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") + @no_callee_helper @no_revert @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, } ``` @@ -481,15 +483,15 @@ RD_VocabTable: 'arch': code_string, 'syntax': code_string, 'size': expr_string, - @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") + @no_callee_helper @default(1) @description("Controls whether or not addresses are shown in the disassembly text.") 'show_addresses': bool, - @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") + @no_callee_helper @default(0) @description("Controls whether or not code bytes are shown in the disassembly text.") 'show_code_bytes': bool, - @default(1) @description("Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.") + @no_callee_helper @default(1) @description("Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.") 'show_source_lines': bool, - @default(1) @description("Controls whether or not disassembly text is decorated with symbol names.") + @no_callee_helper @default(1) @description("Controls whether or not disassembly text is decorated with symbol names.") 'show_symbol_names': bool, - @default(1) @description("Controls whether or not line numbers are shown.") + @no_callee_helper @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers': bool, } ``` diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6732067c..2a8cc189 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6763,6 +6763,84 @@ rd_window_frame(void) } } + //////////////////////////// + //- rjf: @window_ui_part build autocompletion callee info helper + // + F32 autocomp_callee_helper_height_px = 0; + if(rd_setting_b32_from_name(str8_lit("view_call_argument_helper")) && + ws->autocomp_regs != 0 && ws->autocomp_last_frame_index+1 >= rd_state->frame_index && + ws->autocomp_cursor_info.callee_expr.size != 0) + { + E_Eval eval = e_eval_from_string(ws->autocomp_cursor_info.callee_expr); + E_Type *type = e_type_from_key(eval.irtree.type_key); + if(type->kind == E_TypeKind_LensSpec) UI_TagF("floating") + { + F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "autocomp_callee_helper_t"), 1.f, .rate = rd_state->menu_animation_rate); + + //- rjf: build top-level lens calling helper fancy strings + DR_FStrList fstrs = {0}; + { + Vec4F32 color_delimiter = ui_color_from_name(str8_lit("code_delimiter_or_operator")); + Vec4F32 color_arg = ui_color_from_name(str8_lit("code_local")); + MD_NodePtrList schemas = rd_schemas_from_name(type->name); + DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), ui_color_from_name(str8_lit("code_default")), ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, type->name); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("("), .color = color_delimiter); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + B32 first = 1; + for MD_EachNode(child, schema->first) + { + if(!md_node_has_tag(child, str8_lit("no_callee_helper"), 0)) + { + if(!first) + { + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", "), .color = color_delimiter); + } + first = 0; + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, child->string, .color = color_arg); + } + } + } + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")"), .color = color_delimiter); + } + + //- rjf: determine callee helper rect + Rng2F32 callee_helper_rect = {0}; + { + F32 width_px = dr_dim_from_fstrs(&fstrs).x; + UI_Box *anchor_box = ui_box_from_key(ws->autocomp_regs->ui_key); + callee_helper_rect.x0 = anchor_box->rect.x0; + callee_helper_rect.x1 = anchor_box->rect.x0 + width_px + ui_top_font_size()*2.5f; + callee_helper_rect.y0 = anchor_box->rect.y1; + callee_helper_rect.y1 = callee_helper_rect.y0 + ui_top_font_size()*4.f; + } + autocomp_callee_helper_height_px = dim_2f32(callee_helper_rect).y; + autocomp_callee_helper_height_px *= open_t; + + //- rjf: build top-level callee helper box + UI_Box *callee_helper = &ui_nil_box; + UI_Rect(callee_helper_rect) + UI_Squish(0.1f-0.1f*open_t) + UI_Transparency(1.f-open_t) + UI_CornerRadius(ui_top_font_size()*0.25f) + { + callee_helper = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow| + UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_SquishAnchored|UI_BoxFlag_Clickable, + "top_level_window_callee_helper"); + ui_signal_from_box(callee_helper); + } + + //- rjf: fill helper + UI_Parent(callee_helper) UI_WidthFill UI_HeightFill UI_Padding(ui_em(1.f, 1.f)) + { + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(label, &fstrs); + } + } + } + //////////////////////////// //- rjf: @window_ui_part gather all tasks to build floating views // @@ -6823,7 +6901,7 @@ rd_window_frame(void) { UI_Box *anchor_box = ui_box_from_key(ws->autocomp_regs->ui_key); rect.x0 = anchor_box->rect.x0; - rect.y0 = anchor_box->rect.y1; + rect.y0 = anchor_box->rect.y1 + autocomp_callee_helper_height_px; rect.x1 = rect.x0 + width_px; rect.y1 = rect.y0 + height_px; } @@ -7178,7 +7256,9 @@ rd_window_frame(void) { // rjf: build top-level container box UI_Box *container = &ui_nil_box; - UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) + UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y) + UI_Squish(0.1f-0.1f*open_t) + UI_Transparency(1.f-open_t) UI_CornerRadius(ui_top_font_size()*0.25f) { container = ui_build_box_from_stringf(UI_BoxFlag_Clickable| @@ -9848,6 +9928,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) is_allowed = (force_allow || rd_setting_b32_from_name(str8_lit("autocompletion_lister"))); // rjf: tighten list_expr, and filter / replaced-range, if needed + String8 callee_expr = {0}; String8 filter = regs->string; Rng1U64 replaced_range = r1u64(0, filter.size); if(expr_based_replace) @@ -9895,6 +9976,18 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) } } + //- rjf: cursor is within a call? -> generate an expression for the callee + if(cursor_expr_parent->kind == E_ExprKind_Call) + { + E_Key callee_key = e_key_from_expr(cursor_expr_parent->first); + callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); + } + else if(cursor_expr->kind == E_ExprKind_Call) + { + E_Key callee_key = e_key_from_expr(cursor_expr->first); + callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); + } + //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side B32 did_special_cursor_case = 0; if(!did_special_cursor_case) @@ -9930,6 +10023,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) // rjf: fill bundle cursor_info.list_expr = push_str8_copy(ws->autocomp_arena, list_expr); + cursor_info.callee_expr = push_str8_copy(ws->autocomp_arena, callee_expr); cursor_info.filter = push_str8_copy(ws->autocomp_arena, filter); cursor_info.replaced_range = replaced_range; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 550aeee7..381389e9 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -170,6 +170,7 @@ typedef struct RD_AutocompCursorInfo RD_AutocompCursorInfo; struct RD_AutocompCursorInfo { String8 list_expr; + String8 callee_expr; String8 filter; Rng1U64 replaced_range; }; From 13324d90736af280a633b05a912017dc943b2945 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 12:25:31 -0700 Subject: [PATCH 634/755] more progress on view caller helper --- src/raddbg/raddbg_core.c | 73 +++++++++++++++++++++++++++++++--------- src/raddbg/raddbg_core.h | 3 +- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2a8cc189..ccddc75b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6779,6 +6779,7 @@ rd_window_frame(void) //- rjf: build top-level lens calling helper fancy strings DR_FStrList fstrs = {0}; + MD_Node *active_child_schema = &md_nil_node; { Vec4F32 color_delimiter = ui_color_from_name(str8_lit("code_delimiter_or_operator")); Vec4F32 color_arg = ui_color_from_name(str8_lit("code_local")); @@ -6790,6 +6791,7 @@ rd_window_frame(void) { MD_Node *schema = n->v; B32 first = 1; + U64 arg_idx = 0; for MD_EachNode(child, schema->first) { if(!md_node_has_tag(child, str8_lit("no_callee_helper"), 0)) @@ -6799,7 +6801,13 @@ rd_window_frame(void) dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", "), .color = color_delimiter); } first = 0; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, child->string, .color = color_arg); + dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, child->string, .color = color_arg, + .underline_thickness = (ws->autocomp_cursor_info.callee_arg_idx == arg_idx ? 2.f : 0.f)); + if(ws->autocomp_cursor_info.callee_arg_idx == arg_idx) + { + active_child_schema = child; + } + arg_idx += 1; } } } @@ -6807,24 +6815,23 @@ rd_window_frame(void) } //- rjf: determine callee helper rect - Rng2F32 callee_helper_rect = {0}; + Vec2F32 callee_helper_pos = {0}; { - F32 width_px = dr_dim_from_fstrs(&fstrs).x; UI_Box *anchor_box = ui_box_from_key(ws->autocomp_regs->ui_key); - callee_helper_rect.x0 = anchor_box->rect.x0; - callee_helper_rect.x1 = anchor_box->rect.x0 + width_px + ui_top_font_size()*2.5f; - callee_helper_rect.y0 = anchor_box->rect.y1; - callee_helper_rect.y1 = callee_helper_rect.y0 + ui_top_font_size()*4.f; + callee_helper_pos.x = anchor_box->rect.x0; + callee_helper_pos.y = anchor_box->rect.y1; } - autocomp_callee_helper_height_px = dim_2f32(callee_helper_rect).y; + autocomp_callee_helper_height_px = ui_top_font_size()*8.f; autocomp_callee_helper_height_px *= open_t; //- rjf: build top-level callee helper box UI_Box *callee_helper = &ui_nil_box; - UI_Rect(callee_helper_rect) + UI_FixedPos(callee_helper_pos) UI_Squish(0.1f-0.1f*open_t) UI_Transparency(1.f-open_t) UI_CornerRadius(ui_top_font_size()*0.25f) + UI_PrefWidth(ui_children_sum(1)) + UI_PrefHeight(ui_px(autocomp_callee_helper_height_px, 1.f)) { callee_helper = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow| UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_SquishAnchored|UI_BoxFlag_Clickable, @@ -6833,10 +6840,31 @@ rd_window_frame(void) } //- rjf: fill helper - UI_Parent(callee_helper) UI_WidthFill UI_HeightFill UI_Padding(ui_em(1.f, 1.f)) + UI_Parent(callee_helper) + UI_Padding(ui_em(1.f, 1.f)) + UI_PrefWidth(ui_children_sum(1)) + UI_HeightFill + UI_Column + UI_Padding(ui_em(1.f, 1.f)) { - UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(label, &fstrs); + // rjf: main call label + UI_PrefWidth(ui_text_dim(10, 1)) + { + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fstrs(label, &fstrs); + } + + // rjf: active child schema info + if(active_child_schema != &md_nil_node) + { + String8 display_name = md_tag_from_string(active_child_schema, str8_lit("display_name"), 0)->first->string; + String8 desc = md_tag_from_string(active_child_schema, str8_lit("description"), 0)->first->string; + if(display_name.size != 0 && desc.size != 0) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) + { + ui_label(display_name); + ui_label(desc); + } + } } } } @@ -9928,9 +9956,10 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) is_allowed = (force_allow || rd_setting_b32_from_name(str8_lit("autocompletion_lister"))); // rjf: tighten list_expr, and filter / replaced-range, if needed - String8 callee_expr = {0}; String8 filter = regs->string; Rng1U64 replaced_range = r1u64(0, filter.size); + String8 callee_expr = {0}; + U64 callee_arg_idx = 0; if(expr_based_replace) { U64 cursor_off = (U64)(regs->cursor.column-1); @@ -9946,10 +9975,12 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) ExprWalkTask *next; E_Expr *parent; E_Expr *expr; + S32 depth; }; ExprWalkTask start_task = {0, &e_expr_nil, parse.expr}; ExprWalkTask *first_task = &start_task; ExprWalkTask *last_task = first_task; + S32 best_depth = 0; for(E_Expr *chain = parse.expr->next; chain != &e_expr_nil; chain = chain->next) { ExprWalkTask *task = push_array(scratch.arena, ExprWalkTask, 1); @@ -9960,11 +9991,11 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) for(ExprWalkTask *t = first_task; t != 0; t = t->next) { E_Expr *e = t->expr; - if(contains_1u64(e->range, cursor_off) || cursor_off == e->range.max) + if(t->depth >= best_depth && (contains_1u64(e->range, cursor_off) || cursor_off == e->range.max)) { cursor_expr_parent = t->parent; cursor_expr = e; - break; + best_depth = t->depth; } for(E_Expr *child = e->first; child != &e_expr_nil; child = child->next) { @@ -9972,6 +10003,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) SLLQueuePush(first_task, last_task, task); task->parent = e; task->expr = child; + task->depth = t->depth+1; } } } @@ -9981,11 +10013,19 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) { E_Key callee_key = e_key_from_expr(cursor_expr_parent->first); callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); + for(E_Expr *arg = cursor_expr->prev; arg != cursor_expr_parent->first && arg != &e_expr_nil; arg = arg->prev) + { + callee_arg_idx += 1; + } } else if(cursor_expr->kind == E_ExprKind_Call) { E_Key callee_key = e_key_from_expr(cursor_expr->first); callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); + for(E_Expr *arg = cursor_expr->first->next; arg != &e_expr_nil; arg = arg->next) + { + callee_arg_idx += 1; + } } //- rjf: cursor is on right-hand-side of dot? -> show members of left-hand-side @@ -10023,9 +10063,10 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) // rjf: fill bundle cursor_info.list_expr = push_str8_copy(ws->autocomp_arena, list_expr); - cursor_info.callee_expr = push_str8_copy(ws->autocomp_arena, callee_expr); cursor_info.filter = push_str8_copy(ws->autocomp_arena, filter); cursor_info.replaced_range = replaced_range; + cursor_info.callee_expr = push_str8_copy(ws->autocomp_arena, callee_expr); + cursor_info.callee_arg_idx = callee_arg_idx; scratch_end(scratch); } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 381389e9..aedddccc 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -170,9 +170,10 @@ typedef struct RD_AutocompCursorInfo RD_AutocompCursorInfo; struct RD_AutocompCursorInfo { String8 list_expr; - String8 callee_expr; String8 filter; Rng1U64 replaced_range; + String8 callee_expr; + U64 callee_arg_idx; }; //////////////////////////////// From 4c49daa5a4648128b628bdf3ed884d94ceca32bc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 13:22:16 -0700 Subject: [PATCH 635/755] reintroduce add function breakpoint fast-path --- src/raddbg/generated/raddbg.meta.c | 15 +++++++++------ src/raddbg/generated/raddbg.meta.h | 3 ++- src/raddbg/raddbg.mdesk | 8 +++++--- src/raddbg/raddbg_core.c | 13 +++++++++++-- src/raddbg/raddbg_widgets.c | 14 ++++++++++++-- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 49c88fcc..64b85b35 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -60,7 +60,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[342] = +RD_VocabInfo rd_vocab_info_table[343] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -346,9 +346,10 @@ RD_VocabInfo rd_vocab_info_table[342] = {str8_lit_comp("duplicate_cfg"), str8_lit_comp(""), str8_lit_comp("Duplicate"), str8_lit_comp(""), RD_IconKind_Duplicate}, {str8_lit_comp("relocate_cfg"), str8_lit_comp(""), str8_lit_comp("Relocate"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("save_cfg_to_project"), str8_lit_comp(""), str8_lit_comp("Save To Project"), str8_lit_comp(""), RD_IconKind_Briefcase}, -{str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Line Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("add_address_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Address Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, -{str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("add_function_breakpoint"), str8_lit_comp(""), str8_lit_comp("Add Function Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, +{str8_lit_comp("toggle_breakpoint"), str8_lit_comp(""), str8_lit_comp("Toggle Line Breakpoint"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("enable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckFilled}, {str8_lit_comp("disable_breakpoint"), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), str8_lit_comp(""), RD_IconKind_CheckHollow}, {str8_lit_comp("clear_breakpoints"), str8_lit_comp(""), str8_lit_comp("Clear Breakpoints"), str8_lit_comp(""), RD_IconKind_Trash}, @@ -422,7 +423,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, {str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, {str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, @@ -481,7 +482,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, os_event), OffsetOf(RD_Regs, os_event) + sizeof(OS_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[235] = +RD_CmdKindInfo rd_cmd_kind_info_table[236] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -662,6 +663,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[235] = { str8_lit_comp("save_cfg_to_project"), str8_lit_comp("Saves the config tree to the project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_breakpoint"), str8_lit_comp("Places a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("add_address_breakpoint"), str8_lit_comp("Places a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("add_function_breakpoint"), str8_lit_comp("Places a breakpoint on the first address of the specified function."), str8_lit_comp(""), str8_lit_comp("$breakpoints,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("query:procedures"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("toggle_breakpoint"), str8_lit_comp("Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)."), str8_lit_comp(""), str8_lit_comp("$text_pt,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*1)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:breakpoints"), str8_lit_comp(""), CTRL_EntityKind_Null}}, @@ -720,7 +722,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[235] = { str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[114] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -831,6 +833,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[114] = {str8_lit_comp("toggle_watch_pin"), {OS_Key_F9, 0 |OS_Modifier_Ctrl }}, {str8_lit_comp("toggle_breakpoint"), {OS_Key_F9, 0 }}, {str8_lit_comp("add_address_breakpoint"), {OS_Key_F9, 0 |OS_Modifier_Shift }}, +{str8_lit_comp("add_function_breakpoint"), {OS_Key_F9, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_Modifier_Shift }}, {str8_lit_comp("open_palette"), {OS_Key_F1, 0 }}, {str8_lit_comp("open_palette"), {OS_Key_P, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 93ee5fe2..3056593d 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -235,6 +235,7 @@ RD_CmdKind_RelocateCfg, RD_CmdKind_SaveToProject, RD_CmdKind_AddBreakpoint, RD_CmdKind_AddAddressBreakpoint, +RD_CmdKind_AddFunctionBreakpoint, RD_CmdKind_ToggleBreakpoint, RD_CmdKind_EnableBreakpoint, RD_CmdKind_DisableBreakpoint, @@ -569,7 +570,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; -extern RD_VocabInfo rd_vocab_info_table[342]; +extern RD_VocabInfo rd_vocab_info_table[343]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; extern Rng1U64 rd_reg_slot_range_table[43]; extern String8 rd_binding_version_remap_old_name_table[8]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index fd46147b..d8719b28 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -593,7 +593,7 @@ RD_VocabTable: breakpoint, ``` @row_commands(enable_cfg, duplicate_cfg, remove_cfg) - @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, clear_breakpoints) + @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint, clear_breakpoints) x: { 'label': code_string, @@ -980,9 +980,10 @@ RD_CmdTable: // | | | | {SaveToProject 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Briefcase "save_cfg_to_project" "Save To Project" "Saves the config tree to the project." "" "" } //- rjf: breakpoints - {AddBreakpoint 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } + {AddBreakpoint 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "add_breakpoint" "Add Line Breakpoint" "Places a breakpoint at a given location (file path and line number, address, or symbol name)." "" "" } {AddAddressBreakpoint 1 0 0 0 "" Expr null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_address_breakpoint" "Add Address Breakpoint" "Places a breakpoint on the specified address." "" "$breakpoints," } - {ToggleBreakpoint 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } + {AddFunctionBreakpoint 1 0 0 0 "query:procedures" String null Nil Null 0 0 0 0 1 1 1 CircleFilled "add_function_breakpoint" "Add Function Breakpoint" "Places a breakpoint on the first address of the specified function." "" "$breakpoints," } + {ToggleBreakpoint 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 CircleFilled "toggle_breakpoint" "Toggle Line Breakpoint" "Places or removes a breakpoint at a given location (file path and line number, address, or symbol name)." "" "$text_pt," } {EnableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckFilled "enable_breakpoint" "Enable Breakpoint" "Enables a breakpoint." "" "" } {DisableBreakpoint 1 1 0 0 "query:breakpoints" Cfg null Breakpoint Null 0 0 0 0 1 1 1 CheckHollow "disable_breakpoint" "Disable Breakpoint" "Disables a breakpoint." "" "" } {ClearBreakpoints 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Trash "clear_breakpoints" "Clear Breakpoints" "Removes all breakpoints." "" "" } @@ -1240,6 +1241,7 @@ RD_DefaultBindingTable: //- rjf: breakpoints { "toggle_breakpoint" F9 0 0 0 } { "add_address_breakpoint" F9 0 shift 0 } + { "add_function_breakpoint" F9 ctrl shift 0 } //- rjf: attaching { "attach" F6 0 shift 0 } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index ccddc75b..a104f50c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2631,6 +2631,7 @@ rd_view_ui(Rng2F32 rect) ui_label(rd_display_from_code_name(cmd_name)); ui_spacer(ui_em(0.5f, 1.f)); } + UI_Key line_edit_key = {0}; RD_CellParams params = {0}; { params.flags |= !!(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput) * RD_CellFlag_CodeContents; @@ -2641,15 +2642,19 @@ rd_view_ui(Rng2F32 rect) params.edit_string_size_out = &vs->query_string_size; params.edit_buffer_size = sizeof(vs->query_buffer); params.pre_edit_value = current_input; + params.line_edit_key_out = &line_edit_key; } UI_Transparency(1-search_row_open_t) { UI_Signal sig = rd_cellf(¶ms, "###search"); - // TODO(rjf) #if 0 + // TODO(rjf) if(ui_is_focus_active()) { - rd_set_autocomp_regs(.ui_key = sig.box->key, .string = str8(vs->query_buffer, vs->query_string_size), .cursor = vs->query_cursor); + rd_set_autocomp_regs(e_eval_nil, + .ui_key = line_edit_key, + .string = str8(vs->query_buffer, vs->query_string_size), + .cursor = vs->query_cursor); } #endif if(ui_pressed(sig)) @@ -15161,6 +15166,10 @@ rd_frame(void) { rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero(), .do_lister = 1); }break; + case RD_CmdKind_AddFunctionBreakpoint: + { + rd_cmd(RD_CmdKind_AddBreakpoint, .file_path = str8_zero(), .expr = rd_regs()->string); + }break; case RD_CmdKind_ClearBreakpoints: { RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 46407e52..9b47d471 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3695,7 +3695,14 @@ rd_cell(RD_CellParams *params, String8 string) String8 edit_string = str8(params->edit_buffer, params->edit_string_size_out[0]); // rjf: do not consume anything that doesn't fit a single-line's operations - if((evt->kind != UI_EventKind_Edit && evt->kind != UI_EventKind_Navigate && evt->kind != UI_EventKind_Text) || evt->delta_2s32.y != 0) + B32 is_autocompletion_completion = (autocomplete_hint_string.size != 0 && + evt->kind == UI_EventKind_Press && + evt->slot == UI_EventActionSlot_Accept); + if(!is_autocompletion_completion && + ((evt->kind != UI_EventKind_Edit && + evt->kind != UI_EventKind_Navigate && + evt->kind != UI_EventKind_Text) || + evt->delta_2s32.y != 0)) { continue; } @@ -3740,7 +3747,10 @@ rd_cell(RD_CellParams *params, String8 string) // rjf: consume event { - ui_eat_event(evt); + if(!is_autocompletion_completion) + { + ui_eat_event(evt); + } changes_made = 1; } } From e13de0863705fb6e5bb3a119a919e782f11eba46 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 13:34:38 -0700 Subject: [PATCH 636/755] fix process choice in lister-completion-evaluation; do not rely on selected process! fixes 'enter' in listers not functioning when initially launching a process. --- src/raddbg/raddbg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a104f50c..93a587c1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -3256,7 +3256,7 @@ rd_view_ui(Rng2F32 rect) default: { U64 vaddr = eval.value.u64; - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); From b30e928501fa112cb5ac9f79264934bcb30cd760 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 14:00:54 -0700 Subject: [PATCH 637/755] fall back on creating a synthetic symbol name when a chain of leaf-identifier member accesses fail, and produce synthetic leaf-identifier expression to try to resolve it that way. --- src/eval/eval_ir.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index b78a8aa3..87bffbd8 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -679,6 +679,42 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 break; } } + + // rjf: invalid generation, chain of member accesses all stemming from + // a single leaf identifier -> try to join as single string & resolve it + // that way + if(result.root == &e_irnode_nil) + { + B32 is_ident_chain = 1; + for(E_Expr *l = lhs; l != &e_expr_nil; l = l->first) + { + if(l->kind != E_ExprKind_MemberAccess && l->kind != E_ExprKind_LeafIdentifier) + { + is_ident_chain = 0; + break; + } + } + if(is_ident_chain) + { + String8List parts = {0}; + str8_list_push_front(scratch.arena, &parts, lhs->next->string); + for(E_Expr *l = lhs; l != &e_expr_nil; l = l->first) + { + if(l->kind == E_ExprKind_LeafIdentifier) + { + str8_list_push_front(scratch.arena, &parts, l->string); + } + else if(l->kind == E_ExprKind_MemberAccess) + { + str8_list_push_front(scratch.arena, &parts, l->first->next->string); + } + } + String8 full_qualified_name = str8_list_join(scratch.arena, &parts, &(StringJoin){.sep = str8_lit(".")}); + E_Expr *leaf_expr_name = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, r1u64(0, 0)); + leaf_expr_name->string = full_qualified_name; + result = e_push_irtree_and_type_from_expr(arena, root_parent, disallow_autohooks, disallow_autohooks, leaf_expr_name); + } + } }break; //- rjf: dereference From 2a3c5527e0e4f7ee74c8c22d0a96fde5cd49daab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 14:14:30 -0700 Subject: [PATCH 638/755] only decorate debug-info-table-generated expressions with `s when we can detect it is necessary (.s are now allowed); only generate simplified expression extension strings for expressions in watch windows if parent keys are present, otherwise just do the full expression --- src/raddbg/raddbg_eval.c | 15 +++++++++++++-- src/raddbg/raddbg_views.c | 9 ++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index ff3e7ee3..f2674ae2 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1661,8 +1661,19 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table) // rjf: build a valid expression string given item string String8 item_expr = item_string; { - E_TokenArray tokens = e_token_array_from_text(scratch.arena, item_expr); - if(tokens.count != 1) + B32 string_can_be_evalled = 1; + E_TokenArray tokens = e_token_array_from_text(scratch.arena, item_string); + for EachIndex(idx, tokens.count) + { + String8 token_string = str8_substr(item_string, tokens.v[idx].range); + if(tokens.v[idx].kind != E_TokenKind_Identifier && + !str8_match(token_string, str8_lit("."), 0)) + { + string_can_be_evalled = 0; + break; + } + } + if(!string_can_be_evalled) { item_expr = push_str8f(scratch.arena, "`%S`", item_string); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f6488046..b773d990 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1716,8 +1716,11 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla expr_string = cell->eval.string; // rjf: try to form a simpler expression string out of the expression tree itself, *if* this - // is not an editable expression, and if this evaluation was successful - if(!(block_type->flags & E_TypeFlag_EditableChildren) && cell->eval.msgs.max_kind == E_MsgKind_Null) + // is not an editable expression, and if this evaluation was successful, and if this evaluation + // has a parent + if(!e_key_match(cell->eval.parent_key, e_key_zero()) && + !(block_type->flags & E_TypeFlag_EditableChildren) && + cell->eval.msgs.max_kind == E_MsgKind_Null) { // rjf: first, locate a notable expression - we special-case things like member accesses // or array indices, so we should grab those if possible @@ -1740,7 +1743,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla } } - // rjf: generate expression string based on our notable expression + // rjf: generate expression extension string based on our notable expression switch(notable_expr->kind) { // rjf: default case -> just take whatever string was directly passed via the evaluation From 802da729b204c54a785d386312f3d6ee16542fca Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 15:18:09 -0700 Subject: [PATCH 639/755] further work on view callee helper ui --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 163 ++++++++++++++++++----------- src/raddbg/raddbg_core.h | 2 +- 4 files changed, 104 insertions(+), 67 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 64b85b35..a451e20b 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -418,7 +418,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @description(\"An expression describing the width of the bitmap, in pixels.\") @order(0) 'w': u64,\n @description(\"An expression describing the height of the bitmap, in pixels.\") @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index d8719b28..0fecea56 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -521,8 +521,8 @@ RD_VocabTable: { @display_name("Base Pointer") @description("An expression to describe the base address or offset of the bitmap data.") 'expression': expr_string, - @order(0) 'w': u64, - @order(1) 'h': u64, + @description("An expression describing the width of the bitmap, in pixels.") @order(0) 'w': u64, + @description("An expression describing the height of the bitmap, in pixels.") @order(1) 'h': u64, @display_name("Bitmap Format") @description("The pixel format that the bitmap data should be interpreted as being within.") 'fmt': code_string, } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 93a587c1..b197f39f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6782,52 +6782,17 @@ rd_window_frame(void) { F32 open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "autocomp_callee_helper_t"), 1.f, .rate = rd_state->menu_animation_rate); - //- rjf: build top-level lens calling helper fancy strings - DR_FStrList fstrs = {0}; - MD_Node *active_child_schema = &md_nil_node; - { - Vec4F32 color_delimiter = ui_color_from_name(str8_lit("code_delimiter_or_operator")); - Vec4F32 color_arg = ui_color_from_name(str8_lit("code_local")); - MD_NodePtrList schemas = rd_schemas_from_name(type->name); - DR_FStrParams params = {rd_font_from_slot(RD_FontSlot_Code), rd_raster_flags_from_slot(RD_FontSlot_Code), ui_color_from_name(str8_lit("code_default")), ui_top_font_size()}; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, type->name); - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit("("), .color = color_delimiter); - for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) - { - MD_Node *schema = n->v; - B32 first = 1; - U64 arg_idx = 0; - for MD_EachNode(child, schema->first) - { - if(!md_node_has_tag(child, str8_lit("no_callee_helper"), 0)) - { - if(!first) - { - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(", "), .color = color_delimiter); - } - first = 0; - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, child->string, .color = color_arg, - .underline_thickness = (ws->autocomp_cursor_info.callee_arg_idx == arg_idx ? 2.f : 0.f)); - if(ws->autocomp_cursor_info.callee_arg_idx == arg_idx) - { - active_child_schema = child; - } - arg_idx += 1; - } - } - } - dr_fstrs_push_new(scratch.arena, &fstrs, ¶ms, str8_lit(")"), .color = color_delimiter); - } - - //- rjf: determine callee helper rect + //- rjf: determine rects/sizes + F32 row_height_px = ui_top_font_size()*2.f; + F32 padding_px = ui_top_font_size()*1.f; Vec2F32 callee_helper_pos = {0}; { UI_Box *anchor_box = ui_box_from_key(ws->autocomp_regs->ui_key); callee_helper_pos.x = anchor_box->rect.x0; callee_helper_pos.y = anchor_box->rect.y1; } - autocomp_callee_helper_height_px = ui_top_font_size()*8.f; - autocomp_callee_helper_height_px *= open_t; + F32 height_px_target = row_height_px*1.f + padding_px*2.f; + autocomp_callee_helper_height_px = height_px_target * open_t; //- rjf: build top-level callee helper box UI_Box *callee_helper = &ui_nil_box; @@ -6836,41 +6801,82 @@ rd_window_frame(void) UI_Transparency(1.f-open_t) UI_CornerRadius(ui_top_font_size()*0.25f) UI_PrefWidth(ui_children_sum(1)) - UI_PrefHeight(ui_px(autocomp_callee_helper_height_px, 1.f)) + UI_PrefHeight(ui_px(height_px_target, 1.f)) { callee_helper = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow| UI_BoxFlag_DrawBackgroundBlur|UI_BoxFlag_SquishAnchored|UI_BoxFlag_Clickable, "top_level_window_callee_helper"); - ui_signal_from_box(callee_helper); } //- rjf: fill helper UI_Parent(callee_helper) - UI_Padding(ui_em(1.f, 1.f)) + UI_Padding(ui_px(padding_px, 1.f)) UI_PrefWidth(ui_children_sum(1)) UI_HeightFill UI_Column - UI_Padding(ui_em(1.f, 1.f)) + UI_PrefHeight(ui_px(row_height_px, 1.f)) + UI_Padding(ui_px(padding_px, 1.f)) { - // rjf: main call label - UI_PrefWidth(ui_text_dim(10, 1)) + // rjf: main name / args text + UI_Row UI_TextPadding(0) UI_PrefWidth(ui_text_dim(0, 1)) RD_Font(RD_FontSlot_Code) { - UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fstrs(label, &fstrs); - } - - // rjf: active child schema info - if(active_child_schema != &md_nil_node) - { - String8 display_name = md_tag_from_string(active_child_schema, str8_lit("display_name"), 0)->first->string; - String8 desc = md_tag_from_string(active_child_schema, str8_lit("description"), 0)->first->string; - if(display_name.size != 0 && desc.size != 0) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) + Vec4F32 code_default = ui_color_from_name(str8_lit("code_default")); + String8 opener = push_str8f(scratch.arena, "%S(", type->name); + rd_code_label(1, 0, code_default, opener); + MD_NodePtrList schemas = rd_schemas_from_name(type->name); + B32 first = 1; + UI_TagF(".") for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { - ui_label(display_name); - ui_label(desc); + for MD_EachNode(child, n->v->first) + { + if(md_node_has_tag(child, str8_lit("no_callee_helper"), 0)) + { + continue; + } + if(!first) + { + rd_code_label(1, 0, code_default, str8_lit(", ")); + } + first = 0; + UI_Key arg_key = ui_key_from_stringf(ui_active_seed_key(), "###arg_%p", child); + DR_FStrList arg_fstrs = rd_fstrs_from_code_string(scratch.arena, 1.f, 0, code_default, child->string); + if(child == ws->autocomp_cursor_info.arg_schema) + { + ui_set_next_flags(UI_BoxFlag_DrawSideBottom); + ui_set_next_tag(str8_lit("good_pop")); + } + UI_Box *arg_box = ui_build_box_from_key(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable|UI_BoxFlag_DrawHotEffects, arg_key); + ui_box_equip_display_fstrs(arg_box, &arg_fstrs); + UI_Signal arg_sig = ui_signal_from_box(arg_box); + if(ui_hovering(arg_sig)) + { + String8 display_name = md_tag_from_string(child, str8_lit("display_name"), 0)->first->string; + String8 desc = md_tag_from_string(child, str8_lit("description"), 0)->first->string; + if(desc.size != 0) + UI_Tooltip RD_Font(RD_FontSlot_Main) + { + ui_state->tooltip_anchor_key = arg_box->key; + UI_Row + { + RD_Font(RD_FontSlot_Code) ui_label(child->string); + if(display_name.size != 0) + { + ui_spacer(ui_em(0.5f, 1.f)); + UI_TagF("weak") ui_label(display_name); + } + } + UI_TagF("weak") ui_label(desc); + } + } + } } + rd_code_label(1, 0, code_default, str8_lit(")")); } } + + //- rjf: fall-through interactions with helper + UI_Signal sig = ui_signal_from_box(callee_helper); + (void)sig; } } @@ -9964,7 +9970,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) String8 filter = regs->string; Rng1U64 replaced_range = r1u64(0, filter.size); String8 callee_expr = {0}; - U64 callee_arg_idx = 0; + U64 cursor_arg_idx = 0; if(expr_based_replace) { U64 cursor_off = (U64)(regs->cursor.column-1); @@ -10013,14 +10019,15 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) } } - //- rjf: cursor is within a call? -> generate an expression for the callee + //- rjf: cursor is within a call? -> generate an expression for the callee, determine + // which argument the cursor is on if(cursor_expr_parent->kind == E_ExprKind_Call) { E_Key callee_key = e_key_from_expr(cursor_expr_parent->first); callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); for(E_Expr *arg = cursor_expr->prev; arg != cursor_expr_parent->first && arg != &e_expr_nil; arg = arg->prev) { - callee_arg_idx += 1; + cursor_arg_idx += 1; } } else if(cursor_expr->kind == E_ExprKind_Call) @@ -10029,7 +10036,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) callee_expr = e_full_expr_string_from_key(scratch.arena, callee_key); for(E_Expr *arg = cursor_expr->first->next; arg != &e_expr_nil; arg = arg->next) { - callee_arg_idx += 1; + cursor_arg_idx += 1; } } @@ -10066,12 +10073,42 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs) } } + // rjf: try to map the cursor, within a call, to some schema + MD_Node *arg_schema = &md_nil_node; + if(callee_expr.size != 0) + { + E_Eval callee_eval = e_eval_from_string(callee_expr); + E_Type *callee_type = e_type_from_key(callee_eval.irtree.type_key); + if(callee_type->kind == E_TypeKind_LensSpec) + { + U64 arg_idx = 0; + MD_NodePtrList schemas = rd_schemas_from_name(callee_type->name); + for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + for MD_EachNode(child, schema->first) + { + if(!md_node_has_tag(child, str8_lit("no_callee_helper"), 0)) + { + if(cursor_arg_idx == arg_idx) + { + arg_schema = child; + goto end_schema_search; + } + arg_idx += 1; + } + } + } + end_schema_search:; + } + } + // rjf: fill bundle cursor_info.list_expr = push_str8_copy(ws->autocomp_arena, list_expr); cursor_info.filter = push_str8_copy(ws->autocomp_arena, filter); cursor_info.replaced_range = replaced_range; cursor_info.callee_expr = push_str8_copy(ws->autocomp_arena, callee_expr); - cursor_info.callee_arg_idx = callee_arg_idx; + cursor_info.arg_schema = arg_schema; scratch_end(scratch); } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index aedddccc..643aa90d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -173,7 +173,7 @@ struct RD_AutocompCursorInfo String8 filter; Rng1U64 replaced_range; String8 callee_expr; - U64 callee_arg_idx; + MD_Node *arg_schema; }; //////////////////////////////// From 5bfef5091586ea2338aa333c6f9730c381573866 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 15:24:35 -0700 Subject: [PATCH 640/755] bump to 0.9.17 --- src/base/base_context_cracking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index 62a6881f..d1717744 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -159,7 +159,7 @@ #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 16 +# define BUILD_VERSION_PATCH 17 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) From f237f6cb24941a3289c2ce6ee083fe2c37fcd0bb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 8 May 2025 16:16:42 -0700 Subject: [PATCH 641/755] hack in fix for not automatically escaping user inputs - was preventing backslashes from being used correctly in query inputs --- src/raddbg/raddbg_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b197f39f..d7bb2460 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7158,7 +7158,12 @@ rd_window_frame(void) { String8 pre_insertion = str8_prefix(query_expr, input_insertion_pos); String8 post_insertion = str8_skip(query_expr, input_insertion_pos + 6); - query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, str8(vs->query_buffer, vs->query_string_size), post_insertion); + String8 input_text = str8(vs->query_buffer, vs->query_string_size); + String8 input_text__escaped = escaped_from_raw_str8(scratch.arena, input_text); + // TODO(rjf): @hack need to escape because this is putting the user's input + // into a containing "folder:"..."" in all cases. but this is kinda shady + // and should be replaced long-term with something more solid... + query_expr = push_str8f(scratch.arena, "%S%S%S", pre_insertion, input_text__escaped, post_insertion); } } From bbdbcead163ae329be97b23f3a0ca15a819dbebe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 09:05:51 -0700 Subject: [PATCH 642/755] correctly allow space keybindings; bind by default to 'accept', along with return; -> allow space for hitting buttons, expansions, etc. --- src/os/gfx/os_gfx.c | 1 + src/raddbg/generated/raddbg.meta.c | 3 ++- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 30 +++++++++++++++--------------- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/os/gfx/os_gfx.c b/src/os/gfx/os_gfx.c index c5800b57..7523984b 100644 --- a/src/os/gfx/os_gfx.c +++ b/src/os/gfx/os_gfx.c @@ -156,6 +156,7 @@ os_codepoint_from_modifiers_and_key(OS_Modifiers modifiers, OS_Key key) {'X', OS_Key_X, OS_Modifier_Shift}, {'Y', OS_Key_Y, OS_Modifier_Shift}, {'Z', OS_Key_Z, OS_Modifier_Shift}, + {' ', OS_Key_Space, 0}, }; // rjf: check numeric diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a451e20b..0bc62eca 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -722,7 +722,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[236] = { str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab}, }; -struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = +struct {String8 string; RD_Binding binding;} rd_default_binding_table[116] = { {str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_Modifier_Shift }}, {str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_Modifier_Alt}}, @@ -775,6 +775,7 @@ struct {String8 string; RD_Binding binding;} rd_default_binding_table[115] = {str8_lit_comp("save_project"), {OS_Key_S, 0 |OS_Modifier_Ctrl |OS_Modifier_Shift }}, {str8_lit_comp("edit"), {OS_Key_F2, 0 }}, {str8_lit_comp("accept"), {OS_Key_Return, 0 }}, +{str8_lit_comp("accept"), {OS_Key_Space, 0 }}, {str8_lit_comp("cancel"), {OS_Key_Esc, 0 }}, {str8_lit_comp("move_left"), {OS_Key_Left, 0 }}, {str8_lit_comp("move_right"), {OS_Key_Right, 0 }}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 0fecea56..e05ce1ea 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1169,6 +1169,7 @@ RD_DefaultBindingTable: //- rjf: meta controls { "edit" F2 0 0 0 } { "accept" Return 0 0 0 } + { "accept" Space 0 0 0 } { "cancel" Esc 0 0 0 } //- rjf: directional movement & text controls diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d7bb2460..4328debc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2577,7 +2577,7 @@ rd_view_ui(Rng2F32 rect) RD_Cfg *input_root = rd_cfg_child_from_string(query_root, str8_lit("input")); RD_Cfg *cmd_root = rd_cfg_child_from_string(query_root, str8_lit("cmd")); String8 current_input = input_root->first->string; - B32 search_row_is_open = (vs->query_is_selected); + B32 search_row_is_open = (vs->query_is_open); F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), (F32)!!search_row_is_open, .initial = (F32)!!search_row_is_open, @@ -2615,7 +2615,7 @@ rd_view_ui(Rng2F32 rect) } //- rjf: build contents - UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_selected && !vs->contents_are_focused ? UI_FocusKind_On : UI_FocusKind_Off) + UI_Parent(search_row) UI_WidthFill UI_HeightFill UI_Focus(vs->query_is_open && !vs->contents_are_focused ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(cmd_kind_info->query.flags & RD_QueryFlag_CodeInput ? RD_FontSlot_Code : RD_FontSlot_Main) { if(cmd_name.size != 0) @@ -2659,7 +2659,7 @@ rd_view_ui(Rng2F32 rect) #endif if(ui_pressed(sig)) { - vs->query_is_selected = 1; + vs->query_is_open = 1; rd_cmd(RD_CmdKind_FocusPanel); } } @@ -3015,7 +3015,7 @@ rd_view_ui(Rng2F32 rect) case RD_CmdKind_Search: case RD_CmdKind_SearchBackwards: { - vs->query_is_selected = 0; + vs->query_is_open = 0; }break; } } @@ -5439,11 +5439,11 @@ rd_view_ui(Rng2F32 rect) //////////////////////////// //- rjf: catchall completion controls // - if(vs->query_is_selected) UI_Focus(UI_FocusKind_On) + if(vs->query_is_open) UI_Focus(UI_FocusKind_On) { if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Cancel)) { - vs->query_is_selected = 0; + vs->query_is_open = 0; vs->query_string_size = 0; } if(ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) @@ -7198,8 +7198,8 @@ rd_window_frame(void) if(size_query_by_expr_eval) { F32 search_row_open_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "search_row_open_%p", view), - (F32)!!vs->query_is_selected, - .initial = (F32)!!vs->query_is_selected, + (F32)!!vs->query_is_open, + .initial = (F32)!!vs->query_is_open, .epsilon = 0.01f, .rate = rd_state->menu_animation_rate); query_height_px = row_height_px * (predicted_block_tree.total_row_count - !root_is_explicit) + ui_top_px_height()*search_row_open_t; @@ -7443,8 +7443,8 @@ rd_window_frame(void) // rjf: close queries if(query_floating_view_task->pressed_outside || - (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_selected) || - (cmd_name.size != 0 && !vs->query_is_selected) || + (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_open) || + (cmd_name.size != 0 && !vs->query_is_open) || ui_slot_press(UI_EventActionSlot_Cancel)) { rd_cmd(RD_CmdKind_CancelQuery); @@ -14957,7 +14957,7 @@ rd_frame(void) RD_ViewState *vs = rd_view_state_from_cfg(view); if(cmd_name.size != 0) { - if(!vs->query_is_selected && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) + if(!vs->query_is_open && cmd_kind_info->query.flags & RD_QueryFlag_SelectOldInput) { vs->query_cursor = txt_pt(1, 1+input->first->string.size); vs->query_mark = txt_pt(1, 1); @@ -14969,16 +14969,16 @@ rd_frame(void) } if(!str8_match(current_query_cmd_name, cmd_name, 0)) { - vs->query_is_selected = 1; + vs->query_is_open = 1; } else { - vs->query_is_selected ^= 1; + vs->query_is_open ^= 1; } } if(rd_regs()->do_lister) { - vs->query_is_selected = 1; + vs->query_is_open = 1; } } }break; @@ -15013,7 +15013,7 @@ rd_frame(void) else if(!(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput)) { RD_ViewState *vs = rd_view_state_from_cfg(view); - vs->query_is_selected = 0; + vs->query_is_open = 0; vs->query_string_size = 0; } }break; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 643aa90d..790b9904 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -223,7 +223,7 @@ struct RD_ViewState void *user_data; // rjf: query state - B32 query_is_selected; + B32 query_is_open; TxtPt query_cursor; TxtPt query_mark; U8 query_buffer[KB(1)]; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index b773d990..80e14e9c 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -161,7 +161,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla { RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_ViewState *vs = rd_view_state_from_cfg(view); - if(!vs->query_is_selected) + if(!vs->query_is_open) { RD_Cfg *query = rd_cfg_child_from_string_or_alloc(view, str8_lit("query")); RD_Cfg *input = rd_cfg_child_from_string_or_alloc(query, str8_lit("input")); From dd3f3366a86a224f172e12a63a81179cd2aa3540 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 09:48:54 -0700 Subject: [PATCH 643/755] fix bad 0.9.16 version check in config loading; helpers for building version codes, so they can be compared --- src/base/base_core.h | 8 ++++++++ src/base/base_strings.c | 35 +++++++++++++++++++++++++++++++++++ src/base/base_strings.h | 6 ++++++ src/raddbg/raddbg_core.c | 4 ++-- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/base/base_core.h b/src/base/base_core.h index cc0a6545..dd50fbc9 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -65,6 +65,14 @@ # define C_LINKAGE #endif +//////////////////////////////// +//~ rjf: Versions + +#define Version(major, minor, patch) (U64)((((U64)(major) & 0xffff) << 32) | ((((U64)(minor) & 0xffff) << 16)) | ((((U64)(patch) & 0xffff) << 0))) +#define MajorFromVersion(version) (((version) & 0xffff00000000ull) >> 32) +#define MinorFromVersion(version) (((version) & 0x0000ffff0000ull) >> 16) +#define PatchFromVersion(version) (((version) & 0x00000000ffffull) >> 0) + //////////////////////////////// //~ rjf: Units diff --git a/src/base/base_strings.c b/src/base/base_strings.c index d3823676..b51e70fc 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1187,6 +1187,41 @@ str8_array_copy(Arena *arena, String8Array array) return result; } +//////////////////////////////// +//~ rjf: String Version Helpers + +internal U64 +version_from_str8(String8 string) +{ + U64 result = 0; + Temp scratch = scratch_begin(0, 0); + U64 version_major = 0; + U64 version_minor = 0; + U64 version_patch = 0; + String8List version_parts = str8_split(scratch.arena, string, (U8 *)".", 1, 0); + if(version_parts.first && + version_parts.first->next && + version_parts.first->next->next) + { + try_u64_from_str8_c_rules(version_parts.first->string, &version_major); + try_u64_from_str8_c_rules(version_parts.first->next->string, &version_minor); + try_u64_from_str8_c_rules(version_parts.first->next->next->string, &version_patch); + result = Version(version_major, version_minor, version_patch); + } + scratch_end(scratch); + return result; +} + +internal String8 +str8_from_version(Arena *arena, U64 version) +{ + U64 version_major = MajorFromVersion(version); + U64 version_minor = MinorFromVersion(version); + U64 version_patch = PatchFromVersion(version); + String8 result = push_str8f(arena, "%I64d.%I64d.%I64d", version_major, version_minor, version_patch); + return result; +} + //////////////////////////////// //~ rjf: String Path Helpers diff --git a/src/base/base_strings.h b/src/base/base_strings.h index d5ccaad1..06c7bbfc 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -293,6 +293,12 @@ internal String8Array str8_array_from_list(Arena *arena, String8List *list); internal String8Array str8_array_reserve(Arena *arena, U64 count); internal String8Array str8_array_copy(Arena *arena, String8Array array); +//////////////////////////////// +//~ rjf: String Version Helpers + +internal U64 version_from_str8(String8 string); +internal String8 str8_from_version(Arena *arena, U64 version); + //////////////////////////////// //~ rjf: String Path Helpers diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4328debc..c0276778 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12825,8 +12825,8 @@ rd_frame(void) RD_CfgList file_cfg_list = {0}; if(file_is_okay) { - String8 current_version = str8_lit(BUILD_VERSION_STRING_LITERAL); - if(!str8_match(file_version, current_version, 0)) + U64 file_version_code = version_from_str8(file_version); + if(file_version_code < Version(0, 9, 16)) { RD_CfgList (*legacy_parse_function)(Arena *arena, String8 file_path, String8 data) = rd_cfg_tree_list_from_string__pre_0_9_16; file_cfg_list = legacy_parse_function(scratch.arena, file_path, file_data); From cb2e9fe27cfd47ed887838d740fa076672542111 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 09:56:16 -0700 Subject: [PATCH 644/755] record last opened user in program data, recall on startup --- src/raddbg/raddbg_core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index c0276778..84f8e22a 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -10890,9 +10890,14 @@ rd_init(CmdLine *cmdln) } { String8 user_program_data_path = os_get_process_info()->user_program_data_path; - String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); + String8 user_data_folder = push_str8f(scratch.arena, "%S/raddbg", user_program_data_path); os_make_directory(user_data_folder); if(user_path.size == 0) + { + String8 last_user_path = push_str8f(scratch.arena, "%S/last_user", user_data_folder); + user_path = os_data_from_file_path(scratch.arena, last_user_path); + } + if(user_path.size == 0) { user_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } @@ -12903,6 +12908,13 @@ rd_frame(void) } } + //- rjf: record last-opened user in config directory + if(file_is_okay && kind == RD_CmdKind_OpenUser) + { + String8 last_user_path = push_str8f(scratch.arena, "%S/raddbg/last_user", os_get_process_info()->user_program_data_path); + os_write_data_to_file_path(last_user_path, file_path); + } + //- rjf: record recently-opened projects in the user if(file_is_okay && kind == RD_CmdKind_OpenProject) { From e491a76861679cc8974af8d2a7ba1fbb7632a327 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 09:58:39 -0700 Subject: [PATCH 645/755] prevent mutating nil trees in irtree generation --- src/eval/eval_ir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 87bffbd8..4f3104c3 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -122,7 +122,10 @@ e_push_irnode(Arena *arena, RDI_EvalOp op) internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child) { - SLLQueuePush_NZ(&e_irnode_nil, parent->first, parent->last, child, next); + if(parent != &e_irnode_nil && child != &e_irnode_nil) + { + SLLQueuePush_NZ(&e_irnode_nil, parent->first, parent->last, child, next); + } } //- rjf: ir subtree building helpers From 417202c0a0e7a122e6dee0a7ad97b1d09779f3ab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 10:16:49 -0700 Subject: [PATCH 646/755] press in view content -> steal focus from query bar --- src/raddbg/raddbg_core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 84f8e22a..273dce16 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2660,6 +2660,7 @@ rd_view_ui(Rng2F32 rect) if(ui_pressed(sig)) { vs->query_is_open = 1; + vs->contents_are_focused = 0; rd_cmd(RD_CmdKind_FocusPanel); } } @@ -5391,6 +5392,16 @@ rd_view_ui(Rng2F32 rect) RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(expr_string); + // rjf: peek presses, steal focus from query bar + for(UI_Event *evt = 0; ui_next_event(&evt);) + { + if(evt->kind == UI_EventKind_Press && contains_2f32(rect, evt->pos)) + { + vs->contents_are_focused = 1; + break; + } + } + // rjf: 'pull out' button, if floating if(view_is_floating) { @@ -14992,6 +15003,7 @@ rd_frame(void) { vs->query_is_open = 1; } + vs->contents_are_focused = 0; } }break; case RD_CmdKind_CompleteQuery: From 3b0064d8cd23ef1fa648602150edc9e9a1213493 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 10:34:00 -0700 Subject: [PATCH 647/755] multi-toggle-switch-toggle-in-single-press --- src/raddbg/raddbg_widgets.c | 35 ++++++++++++++++++++++++++++++++--- src/ui/ui_core.h | 2 +- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 9b47d471..9c8b872e 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3492,6 +3492,7 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefHeight(ui_px(height_px, 1.f)) UI_CornerRadius(floor_f32(height_px/2.f - 1.f)) UI_TagF(is_toggled ? "good_pop" : "") + UI_GroupKey(ui_key_from_stringf(ui_key_zero(), "toggle_switch_group_key")) { UI_Box *switch_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "toggle_switch"); UI_Parent(switch_box) @@ -3512,15 +3513,43 @@ rd_cell(RD_CellParams *params, String8 string) UI_PrefHeight(ui_px(toggler_size_px, 1.f)) UI_CornerRadius(floor_f32(toggler_size_px/2.f - 1.f)) { - UI_Box *toggler = ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); + ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, ui_key_zero()); } } ui_spacer(ui_pct(1.f-toggle_t, 0)); } UI_Signal switch_sig = ui_signal_from_box(switch_box); - if(ui_pressed(switch_sig)) + if(ui_dragging(switch_sig)) { - params->toggled_out[0] ^= 1; + // rjf: press -> toggle, & gather this key + if(ui_pressed(switch_sig)) + { + ui_store_drag_struct(&switch_box->key); + params->toggled_out[0] ^= 1; + } + + // rjf: dragging -> check if key is in batch of touched keys. if so, do nothing, otherwise, toggle. + // always store this new key if not in batch + String8 all_keys_data = ui_get_drag_data(sizeof(UI_Key)); + UI_Key *keys = (UI_Key *)all_keys_data.str; + U64 keys_count = all_keys_data.size / sizeof(UI_Key); + B32 key_is_touched = 0; + for EachIndex(idx, keys_count) + { + if(ui_key_match(keys[idx], switch_box->key)) + { + key_is_touched = 1; + break; + } + } + if(!key_is_touched) + { + params->toggled_out[0] ^= 1; + UI_Key *new_keys = push_array(scratch.arena, UI_Key, keys_count+1); + MemoryCopy(new_keys, keys, sizeof(UI_Key)*keys_count); + new_keys[keys_count] = switch_box->key; + ui_store_drag_data(str8((U8 *)new_keys, sizeof(UI_Key) * (keys_count+1))); + } } } if(ui_top_text_alignment() == UI_TextAlign_Center) diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 5cec6662..1c915ee5 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -827,7 +827,7 @@ internal UI_State *ui_get_selected_state(void); internal Arena * ui_build_arena(void); internal OS_Handle ui_window(void); internal Vec2F32 ui_mouse(void); -internal FNT_Tag ui_icon_font(void); +internal FNT_Tag ui_icon_font(void); internal String8 ui_icon_string_from_kind(UI_IconKind icon_kind); internal F32 ui_dt(void); From 5fce46baaf399f9ef84067798a61f611f1515aa4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 10:43:17 -0700 Subject: [PATCH 648/755] adjust toggle-switch-dragging path so that keyboard presses still register --- src/raddbg/raddbg_widgets.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 9c8b872e..1f7659c0 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -3519,17 +3519,21 @@ rd_cell(RD_CellParams *params, String8 string) ui_spacer(ui_pct(1.f-toggle_t, 0)); } UI_Signal switch_sig = ui_signal_from_box(switch_box); - if(ui_dragging(switch_sig)) + + // rjf: press -> toggle, & gather this key + if(ui_pressed(switch_sig)) { - // rjf: press -> toggle, & gather this key - if(ui_pressed(switch_sig)) + if(ui_dragging(switch_sig)) { ui_store_drag_struct(&switch_box->key); - params->toggled_out[0] ^= 1; } - - // rjf: dragging -> check if key is in batch of touched keys. if so, do nothing, otherwise, toggle. - // always store this new key if not in batch + params->toggled_out[0] ^= 1; + } + + // rjf: dragging -> check if key is in batch of touched keys. if so, do nothing, otherwise, toggle. + // always store this new key if not in batch + if(ui_dragging(switch_sig)) + { String8 all_keys_data = ui_get_drag_data(sizeof(UI_Key)); UI_Key *keys = (UI_Key *)all_keys_data.str; U64 keys_count = all_keys_data.size / sizeof(UI_Key); From 1c4ad499dc344e2b111db152b275bbe5d7cc9a63 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 10:51:03 -0700 Subject: [PATCH 649/755] prohibit DefWindowProc from running on syschars, for everything except alt+space --- src/os/gfx/win32/os_gfx_win32.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 8d2698c6..7d04f2c2 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -489,7 +489,15 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SYSCHAR: { - result = DefWindowProcW(hwnd, uMsg, wParam, lParam); + WORD vk_code = LOWORD(wParam); + if(vk_code == VK_SPACE) + { + result = DefWindowProcW(hwnd, uMsg, wParam, lParam); + } + else + { + result = 0; + } }break; case WM_CHAR: From f2bf8ccb2e5ea55c23c035e75ced1160416ed48a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 11:15:00 -0700 Subject: [PATCH 650/755] layer color coverage / usage in thread colors --- src/async/async.c | 3 +++ src/base/base_inc.c | 4 ++-- src/base/base_markup.h | 7 ++++-- src/base/base_profile.h | 40 ++++++++++++++----------------- src/base/base_thread_context.h | 2 +- src/ctrl/ctrl_inc.c | 3 +++ src/dasm_cache/dasm_cache.c | 3 +++ src/dbg_engine/dbg_engine_core.c | 4 ++-- src/dbgi/dbgi.c | 3 +++ src/file_stream/file_stream.c | 3 +++ src/geo_cache/geo_cache.c | 3 +++ src/hash_store/hash_store.c | 3 +++ src/mutable_text/mutable_text.c | 3 +++ src/raddbg/raddbg_core.c | 4 ++-- src/render/d3d11/render_d3d11.c | 3 --- src/render/render_inc.c | 3 +++ src/text_cache/text_cache.c | 3 +++ src/texture_cache/texture_cache.c | 3 +++ src/ui/ui_core.c | 3 --- src/ui/ui_inc.c | 4 ++-- 20 files changed, 65 insertions(+), 39 deletions(-) diff --git a/src/async/async.c b/src/async/async.c index 9e8cda09..75c1318e 100644 --- a/src/async/async.c +++ b/src/async/async.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0x59b6c3ff + //////////////////////////////// //~ rjf: Top-Level Layer Initialization diff --git a/src/base/base_inc.c b/src/base/base_inc.c index dc2916bf..299d9042 100644 --- a/src/base/base_inc.c +++ b/src/base/base_inc.c @@ -4,8 +4,8 @@ //////////////////////////////// //~ rjf: Base Includes -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.20f, 0.60f, 0.80f +#undef LAYER_COLOR +#define LAYER_COLOR 0.20f, 0.60f, 0.80f #include "base_core.c" #include "base_profile.c" diff --git a/src/base/base_markup.h b/src/base/base_markup.h index 8a1c6578..db63f545 100644 --- a/src/base/base_markup.h +++ b/src/base/base_markup.h @@ -8,9 +8,12 @@ #define RADDBG_MARKUP_VSNPRINTF raddbg_vsnprintf #include "lib_raddbg_markup/raddbg_markup.h" +#if !defined(LAYER_COLOR) +# define LAYER_COLOR 0x404040ff +#endif + internal void set_thread_name(String8 string); internal void set_thread_namef(char *fmt, ...); -#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__)) -#define ThreadName(str) (set_thread_name(str)) +#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__), raddbg_thread_color_u32(LAYER_COLOR)) #endif // BASE_MARKUP_H diff --git a/src/base/base_profile.h b/src/base/base_profile.h index 098270f4..b39a2fc5 100644 --- a/src/base/base_profile.h +++ b/src/base/base_profile.h @@ -11,10 +11,6 @@ # define PROFILE_TELEMETRY 0 #endif -#if !defined(MARKUP_LAYER_COLOR) -# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f -#endif - //////////////////////////////// //~ rjf: Third Party Includes @@ -44,25 +40,25 @@ # define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__) # define ProfColor(color) tmZoneColorSticky(color) # define ProfBeginV(...) \ - if (TM_API_PTR) { \ - static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ - Temp scratch = scratch_begin(0,0); \ - String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ - tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ - hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ - TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \ - scratch_end(scratch); \ - } +if (TM_API_PTR) { \ +static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ +Temp scratch = scratch_begin(0,0); \ +String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ +tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ +hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ +TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \ +scratch_end(scratch); \ +} # define ProfNoteV(...) \ - if (TM_API_PTR) { \ - static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ - Temp scratch = scratch_begin(0,0); \ - String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ - tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ - hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ - TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \ - scratch_end(scratch); \ - } +if (TM_API_PTR) { \ +static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \ +Temp scratch = scratch_begin(0,0); \ +String8 string = push_str8f(scratch.arena, __VA_ARGS__); \ +tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \ +hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \ +TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \ +scratch_end(scratch); \ +} #endif //////////////////////////////// diff --git a/src/base/base_thread_context.h b/src/base/base_thread_context.h index b2515c93..90a396fe 100644 --- a/src/base/base_thread_context.h +++ b/src/base/base_thread_context.h @@ -26,7 +26,7 @@ internal void tctx_init_and_equip(TCTX *tctx); internal void tctx_release(void); internal TCTX* tctx_get_equipped(void); -internal Arena* tctx_get_scratch(Arena **conflicts, U64 countt); +internal Arena* tctx_get_scratch(Arena **conflicts, U64 count); internal void tctx_set_thread_name(String8 name); internal String8 tctx_get_thread_name(void); diff --git a/src/ctrl/ctrl_inc.c b/src/ctrl/ctrl_inc.c index ce59e6dc..d2dcdb61 100644 --- a/src/ctrl/ctrl_inc.c +++ b/src/ctrl/ctrl_inc.c @@ -1,4 +1,7 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0x969696ff + #include "ctrl_core.c" diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index d3360793..3c937b37 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xe34cd4ff + //////////////////////////////// //~ rjf: Instruction Decoding/Disassembling Type Functions diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 62e34f2b..f8b15ef2 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.70f, 0.50f, 0.25f +#undef LAYER_COLOR +#define LAYER_COLOR 0x4d9ae3ff //////////////////////////////// //~ rjf: Generated Code diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index f790a166..4aea445c 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0x7c4ce3ff + //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index 792bc6d7..3229a321 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xfffa00ff + //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/geo_cache/geo_cache.c b/src/geo_cache/geo_cache.c index 530e6f7a..1af64fec 100644 --- a/src/geo_cache/geo_cache.c +++ b/src/geo_cache/geo_cache.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xe34cd4ff + //////////////////////////////// //~ rjf: Main Layer Initialization diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 587a45c0..8296ec38 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0x684123ff + //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/mutable_text/mutable_text.c b/src/mutable_text/mutable_text.c index 61b6dc9b..006ea601 100644 --- a/src/mutable_text/mutable_text.c +++ b/src/mutable_text/mutable_text.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xb8a06bff + //////////////////////////////// //~ rjf: Main Layer Initialization diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 273dce16..535c8f68 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.10f, 0.20f, 0.25f +#undef LAYER_COLOR +#define LAYER_COLOR 0xf0a215ff //////////////////////////////// //~ rjf: Generated Code diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index d4cdd22c..f3ba394c 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -1,9 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.80f, 0.60f, 0.20f - //////////////////////////////// //~ rjf: Input Layout Element Tables diff --git a/src/render/render_inc.c b/src/render/render_inc.c index 84612fa8..52e5c365 100644 --- a/src/render/render_inc.c +++ b/src/render/render_inc.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xc22121ff + #include "render_core.c" #if R_BACKEND == R_BACKEND_STUB diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 7a1fae94..e8c5da5c 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xe34cd4ff + //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index 8a663a5c..bca74e24 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +#undef LAYER_COLOR +#define LAYER_COLOR 0xe34cd4ff + //////////////////////////////// //~ rjf: Basic Helpers diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 75a7cb3a..37887e5d 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1,9 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.80f, 0.40f, 0.35f - //////////////////////////////// //~ rjf: Globals diff --git a/src/ui/ui_inc.c b/src/ui/ui_inc.c index 7d4e8378..c9bed64e 100644 --- a/src/ui/ui_inc.c +++ b/src/ui/ui_inc.c @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#undef MARKUP_LAYER_COLOR -#define MARKUP_LAYER_COLOR 0.70f, 0.30f, 0.15f +#undef LAYER_COLOR +#define LAYER_COLOR 0xb5438dff #include "ui_core.c" #include "ui_basic_widgets.c" From a3e471897c0b639b905653a8d255162cdef78d59 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 11:31:54 -0700 Subject: [PATCH 651/755] scroll-to-bottom-on-change setting for text (inc. output) visualizers --- src/ctrl/ctrl_core.h | 1 + src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 ++ src/raddbg/raddbg_views.c | 14 +++++++++++++- src/raddbg/raddbg_views.h | 2 ++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 86edf6c3..4c33c20d 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -103,6 +103,7 @@ struct CTRL_Entity CTRL_EntityKind kind; Arch arch; B32 is_frozen; + B32 is_soloed; U32 rgba; CTRL_Handle handle; U64 id; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0bc62eca..063d4e87 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -415,7 +415,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, {str8_lit_comp("tab"), str8_lit_comp("@row_commands(@file copy_tab_full_path, @file show_file_in_explorer, duplicate_tab, close_tab)\nx:\n{\n @override @display_name('Tab Font Size') @description(\"Controls the tab's font size.\") @no_callee_helper\n 'font_size': @range[6, 72] u64,\n}\n")}, {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, -{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, +{str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @default(0) @display_name('Scroll To Bottom On Change') @description(\"Scrolls to the bottom if the text is changed.\")\n 'scroll_to_bottom_on_change':bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @description(\"An expression describing the width of the bitmap, in pixels.\") @order(0) 'w': u64,\n @description(\"An expression describing the height of the bitmap, in pixels.\") @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e05ce1ea..5a457c3c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -468,6 +468,8 @@ RD_VocabTable: 'lang': code_string, @default(1) @description("Controls whether or not line numbers are shown.") 'show_line_numbers':bool, + @no_callee_helper @default(0) @display_name('Scroll To Bottom On Change') @description("Scrolls to the bottom if the text is changed.") + 'scroll_to_bottom_on_change':bool, @no_callee_helper @no_revert @default(0) @display_name('Transient') @description("Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.") 'auto': bool, } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 80e14e9c..cd4653ae 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -573,7 +573,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla cv->goto_line_num = 0; line_num = Clamp(1, line_num, text_info->lines_count); rd_regs()->cursor = rd_regs()->mark = txt_pt(line_num, 1); - cv->center_cursor = !cv->contain_cursor || (line_num < target_visible_line_num_range.min+4 || target_visible_line_num_range.max-4 < line_num); + cv->center_cursor = !cv->force_contain_only && (!cv->contain_cursor || (line_num < target_visible_line_num_range.min+4 || target_visible_line_num_range.max-4 < line_num)); } ////////////////////////////// @@ -807,6 +807,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla //- rjf: store state // rd_store_view_scroll_pos(scroll_pos); + cv->force_contain_only = 0; scratch_end(scratch); ProfEnd(); @@ -2071,6 +2072,17 @@ RD_VIEW_UI_FUNCTION_DEF(text) B32 key_has_data = !u128_match(hash, u128_zero()) && info.lines_count; ProfEnd(); + ////////////////////////////// + //- rjf: update last hash - scroll-to-bottom if needed + // + if(rd_setting_b32_from_name(str8_lit("scroll_to_bottom_on_change")) && !u128_match(hash, cv->last_hash) && !u128_match(cv->last_hash, u128_zero())) + { + cv->goto_line_num = info.lines_count; + cv->contain_cursor = 1; + cv->force_contain_only = 1; + } + cv->last_hash = hash; + ////////////////////////////// //- rjf: build missing file interface // diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 7851043d..5f8d0869 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -21,11 +21,13 @@ struct RD_CodeViewState B32 initialized; S64 preferred_column; B32 drifted_for_search; + U128 last_hash; // rjf: per-frame command info S64 goto_line_num; B32 center_cursor; B32 contain_cursor; + B32 force_contain_only; B32 watch_expr_at_mouse; Arena *find_text_arena; String8 find_text_fwd; From 7939bcbc95ca2b4df5c0f48eb36f4f19a8095ec5 Mon Sep 17 00:00:00 2001 From: Jan Hebbel Date: Fri, 17 Jan 2025 20:17:11 +0100 Subject: [PATCH 652/755] Fixed signed minimum values. --- src/base/base_core.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/base/base_core.h b/src/base/base_core.h index dd50fbc9..ab7b35f3 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -598,15 +598,15 @@ global U32 max_U32 = 0xffffffff; global U16 max_U16 = 0xffff; global U8 max_U8 = 0xff; -global S64 max_S64 = (S64)0x7fffffffffffffffull; +global S64 max_S64 = (S64)0x7fffffffffffffffll; global S32 max_S32 = (S32)0x7fffffff; global S16 max_S16 = (S16)0x7fff; global S8 max_S8 = (S8)0x7f; -global S64 min_S64 = (S64)0xffffffffffffffffull; -global S32 min_S32 = (S32)0xffffffff; -global S16 min_S16 = (S16)0xffff; -global S8 min_S8 = (S8)0xff; +global S64 min_S64 = (S64)0x8000000000000000ll; +global S32 min_S32 = (S32)0x80000000; +global S16 min_S16 = (S16)0x8000; +global S8 min_S8 = (S8)0x80; global const U32 bitmask1 = 0x00000001; global const U32 bitmask2 = 0x00000003; From 719e8ce1794a74d1991bc285a77e986d73088a32 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 12:05:38 -0700 Subject: [PATCH 653/755] crash dump generation from crash dialog, or via --gen_crash_dump for CLI --- src/os/core/win32/os_core_win32.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 6cc494f0..94d994b4 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1407,6 +1407,7 @@ os_make_guid(void) #include internal B32 win32_g_is_quiet = 0; +internal B32 win32_g_gen_dump = 0; internal HRESULT WINAPI win32_dialog_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LONG_PTR data) @@ -1442,6 +1443,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"A fatal exception (code 0x%x) occurred. The process is terminating.\n", exception_code); // load dbghelp dynamically just in case if it is missing + BOOL (WINAPI *dbg_MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); HMODULE dbghelp = LoadLibraryA("dbghelp.dll"); if(dbghelp) { @@ -1465,6 +1467,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) *(FARPROC*)&dbg_SymFromAddrW = GetProcAddress(dbghelp, "SymFromAddrW"); *(FARPROC*)&dbg_SymGetLineFromAddrW64 = GetProcAddress(dbghelp, "SymGetLineFromAddrW64"); *(FARPROC*)&dbg_SymGetModuleInfoW64 = GetProcAddress(dbghelp, "SymGetModuleInfoW64"); + *(FARPROC*)&dbg_MiniDumpWriteDump = GetProcAddress(dbghelp, "MiniDumpWriteDump"); if(dbg_SymSetOptions && dbg_SymInitializeW && dbg_StackWalk64 && dbg_SymFunctionTableAccess64 && dbg_SymGetModuleBase64 && dbg_SymFromAddrW && dbg_SymGetLineFromAddrW64 && dbg_SymGetModuleInfoW64) { @@ -1594,10 +1597,13 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nVersion: %S%S", BUILD_VERSION_STRING_LITERAL, BUILD_GIT_HASH_STRING_LITERAL_APPEND); + B32 generate_crash_dump = win32_g_gen_dump; #if BUILD_CONSOLE_INTERFACE fwprintf(stderr, L"\n--- Fatal Exception ---\n"); fwprintf(stderr, L"%s\n\n", buffer); #else + int selected_button = 0; + TASKDIALOG_BUTTON generate_dump = {1, L"Generate Crash Dump File"}; TASKDIALOGCONFIG dialog = {0}; dialog.cbSize = sizeof(dialog); dialog.dwFlags = TDF_SIZE_TO_CONTENT | TDF_ENABLE_HYPERLINKS | TDF_ALLOW_DIALOG_CANCELLATION; @@ -1606,9 +1612,25 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) dialog.pszWindowTitle = L"Fatal Exception"; dialog.pszContent = buffer; dialog.pfCallback = &win32_dialog_callback; - TaskDialogIndirect(&dialog, 0, 0, 0); + dialog.cButtons = 1; + dialog.pButtons = &generate_dump; + TaskDialogIndirect(&dialog, &selected_button, 0, 0); + generate_crash_dump = (selected_button == generate_dump.nButtonID); #endif + if(dbg_MiniDumpWriteDump && generate_crash_dump) + { + WCHAR desktop_path[512] = {0}; + SHGetFolderPathW(0, CSIDL_DESKTOP, 0, 0, desktop_path); + WCHAR dump_file_path[512] = {0}; + wnsprintfW(dump_file_path, ArrayCount(dump_file_path), L"%s\\raddbg_crash_dump.dmp", desktop_path); + SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0}; + HANDLE file = CreateFileW(dump_file_path, GENERIC_WRITE, 0, &security_attributes, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + BOOL dump_successful = dbg_MiniDumpWriteDump(GetCurrentProcess(), os_get_process_info()->pid, file, MiniDumpNormal, 0, 0, 0); + CloseHandle(file); + (void)dump_successful; + } + ExitProcess(1); } @@ -1695,6 +1717,11 @@ w32_entry_point_caller(int argc, WCHAR **wargv) arena_default_reserve_size = Max(MB(64), os_w32_state.system_info.large_page_size); arena_default_commit_size = arena_default_reserve_size; } + if(str8_match(arg8, str8_lit("--gen_crash_dump"), StringMatchFlag_CaseInsensitive) || + str8_match(arg8, str8_lit("-gen_crash_dump"), StringMatchFlag_CaseInsensitive)) + { + win32_g_gen_dump = 1; + } argv[i] = (char *)arg8.str; } From 2c58b81ddee6f64ad307d8e8b6c403d30fb29560 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 12:22:27 -0700 Subject: [PATCH 654/755] parameterize find-code-location by forcing-focus to destination panel; use that in 'switch' command --- src/raddbg/generated/raddbg.meta.c | 3 ++- src/raddbg/generated/raddbg.meta.h | 5 ++++- src/raddbg/raddbg.mdesk | 1 + src/raddbg/raddbg_core.c | 6 +++++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 063d4e87..55c027df 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -435,7 +435,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("thread"), str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':query}")}, }; -Rng1U64 rd_reg_slot_range_table[43] = +Rng1U64 rd_reg_slot_range_table[44] = { {0}, {OffsetOf(RD_Regs, machine), OffsetOf(RD_Regs, machine) + sizeof(CTRL_Handle)}, @@ -470,6 +470,7 @@ Rng1U64 rd_reg_slot_range_table[43] = {OffsetOf(RD_Regs, reg_slot), OffsetOf(RD_Regs, reg_slot) + sizeof(RD_RegSlot)}, {OffsetOf(RD_Regs, pid), OffsetOf(RD_Regs, pid) + sizeof(U32)}, {OffsetOf(RD_Regs, force_confirm), OffsetOf(RD_Regs, force_confirm) + sizeof(B32)}, +{OffsetOf(RD_Regs, force_focus), OffsetOf(RD_Regs, force_focus) + sizeof(B32)}, {OffsetOf(RD_Regs, prefer_disasm), OffsetOf(RD_Regs, prefer_disasm) + sizeof(B32)}, {OffsetOf(RD_Regs, no_rich_tooltip), OffsetOf(RD_Regs, no_rich_tooltip) + sizeof(B32)}, {OffsetOf(RD_Regs, do_implicit_root), OffsetOf(RD_Regs, do_implicit_root) + sizeof(B32)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3056593d..6473c8bd 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -41,6 +41,7 @@ RD_RegSlot_OffPx, RD_RegSlot_RegSlot, RD_RegSlot_PID, RD_RegSlot_ForceConfirm, +RD_RegSlot_ForceFocus, RD_RegSlot_PreferDisasm, RD_RegSlot_NoRichTooltip, RD_RegSlot_DoImplicitRoot, @@ -463,6 +464,7 @@ Vec2F32 off_px; RD_RegSlot reg_slot; U32 pid; B32 force_confirm; +B32 force_focus; B32 prefer_disasm; B32 no_rich_tooltip; B32 do_implicit_root; @@ -556,6 +558,7 @@ Z(getting_started)\ .reg_slot = rd_regs()->reg_slot,\ .pid = rd_regs()->pid,\ .force_confirm = rd_regs()->force_confirm,\ +.force_focus = rd_regs()->force_focus,\ .prefer_disasm = rd_regs()->prefer_disasm,\ .no_rich_tooltip = rd_regs()->no_rich_tooltip,\ .do_implicit_root = rd_regs()->do_implicit_root,\ @@ -572,7 +575,7 @@ extern String8 rd_tab_fast_path_view_name_table[24]; extern String8 rd_tab_fast_path_query_name_table[24]; extern RD_VocabInfo rd_vocab_info_table[343]; extern RD_NameSchemaInfo rd_name_schema_info_table[24]; -extern Rng1U64 rd_reg_slot_range_table[43]; +extern Rng1U64 rd_reg_slot_range_table[44]; extern String8 rd_binding_version_remap_old_name_table[8]; extern String8 rd_binding_version_remap_new_name_table[8]; extern String8 rd_icon_kind_text_table[75]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5a457c3c..e67e63b8 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -732,6 +732,7 @@ RD_RegTable: // rjf: general parameters {U32 pid PID } {B32 force_confirm ForceConfirm } + {B32 force_focus ForceFocus } {B32 prefer_disasm PreferDisasm } {B32 no_rich_tooltip NoRichTooltip } {B32 do_implicit_root DoImplicitRoot} diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 535c8f68..cac4e9f1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13923,7 +13923,7 @@ rd_frame(void) RD_Cfg *recent_file = rd_cfg_from_id(rd_regs()->cfg); RD_Cfg *path_root = rd_cfg_child_from_string(recent_file, str8_lit("path")); String8 path = path_root->first->string; - rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .cursor = txt_pt(0, 0), .vaddr = 0); + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = path, .cursor = txt_pt(0, 0), .vaddr = 0, .force_focus = 1); }break; case RD_CmdKind_SwitchToPartnerFile: { @@ -14842,6 +14842,10 @@ rd_frame(void) .view = dst_tab->id, .tab = dst_tab->id) { + if(rd_regs()->force_focus) + { + rd_cmd(RD_CmdKind_FocusPanel); + } rd_cmd(RD_CmdKind_FocusTab); if(point.line != 0) { From 345d5579d29798fba2838e64fcb4a8b6ff946c35 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 12:27:35 -0700 Subject: [PATCH 655/755] do not show `switch` in IPC docs --- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 55c027df..7bd6942a 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -577,7 +577,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[236] = { str8_lit_comp("tab_settings"), str8_lit_comp("Opens settings for a tab."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), CTRL_EntityKind_Null}}, -{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, +{ str8_lit_comp("switch"), str8_lit_comp("Switches to a recent file."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:recent_files"), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("record_file_in_project"), str8_lit_comp("Records the passed file path as a recent file in the currently loaded project."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, { str8_lit_comp("show_file_in_explorer"), str8_lit_comp("Opens the operating system's file explorer and shows the selected file."), str8_lit_comp(""), str8_lit_comp("$file,"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), CTRL_EntityKind_Null}}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index e67e63b8..12fde4a5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -870,7 +870,7 @@ RD_CmdTable: // | | | | //- rjf: files {SetCurrentPath 0 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "set_current_path" "Set Current Path" "Sets the debugger's current path, which is used as a starting point when browsing for files." "" "" } {Open 1 1 0 0 `folder:\\"$input\\"` FilePath null Nil Null 1 0 0 0 0 1 1 FileOutline "open" "Open" "Opens a file." "code,source,file" "" } - {Switch 1 1 0 0 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } + {Switch 1 0 0 0 "query:recent_files" Cfg null RecentFile Null 0 0 0 0 0 1 1 FileOutline "switch" "Switch" "Switches to a recent file." "code,source,file" "" } {SwitchToPartnerFile 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" "" } {RecordFileInProject 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FileOutline "record_file_in_project" "Record File In Project" "Records the passed file path as a recent file in the currently loaded project." "" "" } {ShowFileInExplorer 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 FolderClosedFilled "show_file_in_explorer" "Show File In Explorer" "Opens the operating system's file explorer and shows the selected file." "" "$file," } From f38da420e9e12a523c2c27145c367ac412addce0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 12:51:02 -0700 Subject: [PATCH 656/755] force hover eval in window on X axis only; store expr strings rather than expr trees in auto hook map --- src/eval/eval_core.c | 8 +++++--- src/eval/eval_core.h | 8 +++++++- src/raddbg/raddbg_core.c | 24 ++++++++++++++++-------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 485b3386..61e90d0d 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -461,7 +461,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key)); node->type_pattern_parts = pattern_parts; - node->expr = e_parse_from_string(params->tag_expr_string).expr; + node->expr_string = push_str8_copy(arena, params->tag_expr_string); if(!e_type_key_match(e_type_key_zero(), type_key)) { U64 hash = e_hash_from_string(5381, node->type_string); @@ -1054,7 +1054,8 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { if(str8_match(n->type_string, type_string, 0)) { - e_expr_list_push(arena, &exprs, n->expr); + E_Expr *expr = e_parse_from_string(n->expr_string).expr; + e_expr_list_push(arena, &exprs, expr); } } } @@ -1089,7 +1090,8 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } if(fits_this_type_string) { - e_expr_list_push(arena, &exprs, auto_hook_node->expr); + E_Expr *expr = e_parse_from_string(auto_hook_node->expr_string).expr; + e_expr_list_push(arena, &exprs, expr); } } } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 4c9c8017..d577270e 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -669,7 +669,7 @@ struct E_AutoHookNode E_AutoHookNode *pattern_order_next; String8 type_string; String8List type_pattern_parts; - E_Expr *expr; + String8 expr_string; }; typedef struct E_AutoHookSlot E_AutoHookSlot; @@ -884,6 +884,12 @@ struct E_UsedExprMap //- rjf: type key -> auto hook expression list cache +typedef struct E_TypeAutoHookMatch E_TypeAutoHookMatch; +struct E_TypeAutoHookMatch +{ + String8 expr; +}; + typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; struct E_TypeAutoHookCacheNode { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index cac4e9f1..736f3212 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6903,7 +6903,8 @@ rd_window_frame(void) Rng2F32 rect; B32 is_focused; B32 is_anchored; - B32 force_inside_window; + B32 force_inside_window_x; + B32 force_inside_window_y; B32 only_secondary_navigation; B32 reset_open; UI_Signal signal; // NOTE(rjf): output, from build @@ -7081,6 +7082,7 @@ rd_window_frame(void) t->rect = rect; t->is_focused = ws->hover_eval_focused; t->is_anchored = 1; + t->force_inside_window_x = 1; } } @@ -7244,7 +7246,8 @@ rd_window_frame(void) t->is_focused = 1; t->is_anchored = query_is_anchored; t->reset_open = reset_open; - t->force_inside_window = 1; + t->force_inside_window_x = 1; + t->force_inside_window_y = 1; } } } @@ -7273,14 +7276,19 @@ rd_window_frame(void) .initial = 0.f); // rjf: force rect inside window if needed - if(t->force_inside_window) + if(t->force_inside_window_x || t->force_inside_window_y) { + B32 axis_mask[] = {t->force_inside_window_x, t->force_inside_window_y}; Rng2F32 window_rect = os_client_rect_from_window(ws->os); - Vec2F32 max_delta = sub_2f32(rect.p1, window_rect.p1); - Vec2F32 min_delta = sub_2f32(window_rect.p0, rect.p0); - Vec2F32 total_delta = v2f32(Max(min_delta.x, 0) - Max(max_delta.x, 0), - Max(min_delta.y, 0) - Max(max_delta.y, 0)); - rect = shift_2f32(rect, total_delta); + for EachEnumVal(Axis2, axis) + { + if(!axis_mask[axis]) { continue; } + F32 max_delta = rect.p1.v[axis] - window_rect.p1.v[axis]; + F32 min_delta = window_rect.p0.v[axis] - rect.p0.v[axis]; + F32 total_delta = Max(min_delta, 0) - Max(max_delta, 0); + rect.p0.v[axis] += total_delta; + rect.p1.v[axis] += total_delta; + } } // rjf: push view regs From 1b7a57914ecd14ab3f649c19846e626b656b0786 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 13:44:17 -0700 Subject: [PATCH 657/755] get linux building again --- src/base/base_markup.h | 3 +++ src/eval/eval_core.h | 6 ----- src/lib_raddbg_markup/raddbg_markup.h | 4 +-- .../core/linux/metagen_os_core_linux.c | 1 + src/mule/mule_main.cpp | 3 +++ src/os/core/linux/os_core_linux.c | 1 + src/os/gfx/linux/os_gfx_linux.c | 27 ++++++++++--------- src/scratch/ryan_scratch.c | 24 +++-------------- 8 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/base/base_markup.h b/src/base/base_markup.h index db63f545..2de3aa5d 100644 --- a/src/base/base_markup.h +++ b/src/base/base_markup.h @@ -6,6 +6,9 @@ #define RADDBG_MARKUP_IMPLEMENTATION #define RADDBG_MARKUP_VSNPRINTF raddbg_vsnprintf +#if OS_LINUX +# define RADDBG_MARKUP_STUBS +#endif #include "lib_raddbg_markup/raddbg_markup.h" #if !defined(LAYER_COLOR) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index d577270e..c9561d3a 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -884,12 +884,6 @@ struct E_UsedExprMap //- rjf: type key -> auto hook expression list cache -typedef struct E_TypeAutoHookMatch E_TypeAutoHookMatch; -struct E_TypeAutoHookMatch -{ - String8 expr; -}; - typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; struct E_TypeAutoHookCacheNode { diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 4913a86c..e1257cf4 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -51,8 +51,8 @@ # define raddbg_watch(fmt, ...) ((void)0) # define raddbg_pin(expr, ...) # define raddbg_log(fmt, ...) ((void)0) -# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__;} +# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__;} # define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) # define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) #endif diff --git a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c index 5acd5cf8..23ec77cf 100644 --- a/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c +++ b/src/metagen/metagen_os/core/linux/metagen_os_core_linux.c @@ -447,6 +447,7 @@ internal B32 os_move_file_path(String8 dst, String8 src) { // TODO(rjf) + return 0; } internal String8 diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f19eecbf..cc199519 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -9,6 +9,9 @@ #include #include #include +#if !_WIN32 +# define RADDBG_MARKUP_STUBS +#endif #define RADDBG_MARKUP_IMPLEMENTATION #include "lib_raddbg_markup/raddbg_markup.h" diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 5acd5cf8..23ec77cf 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -447,6 +447,7 @@ internal B32 os_move_file_path(String8 dst, String8 src) { // TODO(rjf) + return 0; } internal String8 diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index c9fd1eba..ad9c15df 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -137,7 +137,7 @@ os_window_close(OS_Handle handle) } internal void -os_window_set_title(OS_Handle window, String8 title) +os_window_set_title(OS_Handle handle, String8 title) { if(os_handle_match(handle, os_handle_zero())) {return;} // TODO(rjf) @@ -191,13 +191,14 @@ os_window_set_maximized(OS_Handle handle, B32 maximized) } internal B32 -os_window_is_minimized(OS_Handle window) +os_window_is_minimized(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} + return 0; } internal void -os_window_set_minimized(OS_Handle window, B32 minimized) +os_window_set_minimized(OS_Handle handle, B32 minimized) { if(os_handle_match(handle, os_handle_zero())) {return;} } @@ -324,10 +325,10 @@ os_get_events(Arena *arena, B32 wait) case KeyRelease: { // rjf: determine flags - OS_Modifiers flags = 0; - if(evt.xkey.state & ShiftMask) { flags |= OS_Modifier_Shift; } - if(evt.xkey.state & ControlMask) { flags |= OS_Modifier_Ctrl; } - if(evt.xkey.state & Mod1Mask) { flags |= OS_Modifier_Alt; } + OS_Modifiers modifiers = 0; + if(evt.xkey.state & ShiftMask) { modifiers |= OS_Modifier_Shift; } + if(evt.xkey.state & ControlMask) { modifiers |= OS_Modifier_Ctrl; } + if(evt.xkey.state & Mod1Mask) { modifiers |= OS_Modifier_Alt; } // rjf: map keycode -> keysym U32 keysym = XLookupKeysym(&evt.xkey, 0); @@ -386,7 +387,7 @@ os_get_events(Arena *arena, B32 wait) OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xclient.window); OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == KeyPress ? OS_EventKind_Press : OS_EventKind_Release); e->window.u64[0] = (U64)window; - e->flags = flags; + e->modifiers = modifiers; e->key = key; }break; @@ -395,10 +396,10 @@ os_get_events(Arena *arena, B32 wait) case ButtonRelease: { // rjf: determine flags - OS_Modifiers flags = 0; - if(evt.xbutton.state & ShiftMask) { flags |= OS_Modifier_Shift; } - if(evt.xbutton.state & ControlMask) { flags |= OS_Modifier_Ctrl; } - if(evt.xbutton.state & Mod1Mask) { flags |= OS_Modifier_Alt; } + OS_Modifiers modifiers = 0; + if(evt.xbutton.state & ShiftMask) { modifiers |= OS_Modifier_Shift; } + if(evt.xbutton.state & ControlMask) { modifiers |= OS_Modifier_Ctrl; } + if(evt.xbutton.state & Mod1Mask) { modifiers |= OS_Modifier_Alt; } // rjf: map button -> OS_Key OS_Key key = OS_Key_Null; @@ -414,7 +415,7 @@ os_get_events(Arena *arena, B32 wait) OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xclient.window); OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == ButtonPress ? OS_EventKind_Press : OS_EventKind_Release); e->window.u64[0] = (U64)window; - e->flags = flags; + e->modifiers = modifiers; e->key = key; }break; diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index 317413f3..8f1a564b 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -19,28 +19,10 @@ //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" -#include "rdi_make/rdi_make_local.h" -#include "coff/coff.h" -#include "codeview/codeview.h" -#include "codeview/codeview_stringize.h" -#include "msf/msf.h" -#include "msf/msf_parse.h" -#include "pdb/pdb.h" -#include "pdb/pdb_parse.h" -#include "pdb/pdb_stringize.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" -#include "rdi_make/rdi_make_local.c" -#include "coff/coff.c" -#include "codeview/codeview.c" -#include "codeview/codeview_stringize.c" -#include "msf/msf.c" -#include "msf/msf_parse.c" -#include "pdb/pdb.c" -#include "pdb/pdb_parse.c" -#include "pdb/pdb_stringize.c" //////////////////////////////// //~ rjf: Entry Points @@ -57,12 +39,12 @@ frame(void) { String8 string = push_str8f(scratch.arena, "%S (%S)\n", os_string_from_event_kind(ev->kind), os_g_key_display_string_table[ev->key]); printf("%.*s", str8_varg(string)); - OutputDebugStringA((char *)string.str); + raddbg_log((char *)string.str); fflush(stdout); } if(ev->kind == OS_EventKind_Press && ev->key == OS_Key_X) { - *(int *)0 = 0; + *(volatile int *)0 = 0; } } for(OS_Event *ev = events.first; ev != 0; ev = ev->next) @@ -80,7 +62,7 @@ frame(void) internal void entry_point(CmdLine *cmdline) { - OS_Handle window = os_window_open(v2f32(1280, 720), 0, str8_lit("Window")); + OS_Handle window = os_window_open(r2f32p(0, 0, 1280, 720), OS_WindowFlag_UseDefaultPosition, str8_lit("Window")); os_window_first_paint(window); for(;!update();); } From 48b8c41713b931740f8286b8b235aa5229844ad0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 19:48:41 -0700 Subject: [PATCH 658/755] opengl render backend --- build.bat | 1 + project.4coder | 2 +- src/base/base_math.c | 15 + src/base/base_math.h | 1 + .../d3d11/generated/render_d3d11.meta.h | 3 +- src/render/d3d11/render_d3d11.c | 49 +- src/render/d3d11/render_d3d11.h | 2 +- src/render/d3d11/render_d3d11.mdesk | 3 +- .../opengl/generated/render_opengl.meta.c | 38 ++ .../opengl/generated/render_opengl.meta.h | 276 ++++++++++ src/render/opengl/render_opengl.c | 480 ++++++++++++++++++ src/render/opengl/render_opengl.h | 217 ++++++++ src/render/opengl/render_opengl.mdesk | 292 +++++++++++ src/render/opengl/win32/render_opengl_win32.c | 184 +++++++ src/render/opengl/win32/render_opengl_win32.h | 34 ++ src/render/render_core.c | 27 + src/render/render_core.h | 5 + src/render/render_inc.c | 2 + src/render/render_inc.h | 5 + 19 files changed, 1598 insertions(+), 38 deletions(-) create mode 100644 src/render/opengl/generated/render_opengl.meta.c create mode 100644 src/render/opengl/generated/render_opengl.meta.h create mode 100644 src/render/opengl/render_opengl.c create mode 100644 src/render/opengl/render_opengl.h create mode 100644 src/render/opengl/render_opengl.mdesk create mode 100644 src/render/opengl/win32/render_opengl_win32.c create mode 100644 src/render/opengl/win32/render_opengl_win32.h diff --git a/build.bat b/build.bat index 51f73739..d8a2ca72 100644 --- a/build.bat +++ b/build.bat @@ -40,6 +40,7 @@ if "%~1"=="release" if "%~2"=="" echo [default mode, assuming `raddbg` build] && set auto_compile_flags= if "%telemetry%"=="1" set auto_compile_flags=%auto_compile_flags% -DPROFILE_TELEMETRY=1 && echo [telemetry profiling enabled] if "%asan%"=="1" set auto_compile_flags=%auto_compile_flags% -fsanitize=address && echo [asan enabled] +if "%opengl%"=="1" set auto_compile_flags=%auto_compile_flags% -DR_BACKEND=R_BACKEND_OPENGL && echo [opengl render backend] :: --- Compile/Link Line Definitions ------------------------------------------ set cl_common= /I..\src\ /I..\local\ /nologo /FC /Z7 diff --git a/project.4coder b/project.4coder index a725e0d6..3e46160f 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: [raddbg] - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry opengl", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_math.c b/src/base/base_math.c index 4f5903c5..7a65b45b 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -386,6 +386,21 @@ derotate_4x4f32(Mat4x4F32 mat) return mat; } +internal Mat4x4F32 +transpose_4x4f32(Mat4x4F32 mat) +{ + Mat4x4F32 result = + { + { + mat.v[0][0], mat.v[1][0], mat.v[2][0], mat.v[3][0], + mat.v[0][1], mat.v[1][1], mat.v[2][1], mat.v[3][1], + mat.v[0][2], mat.v[1][2], mat.v[2][2], mat.v[3][2], + mat.v[0][3], mat.v[1][3], mat.v[2][3], mat.v[3][3], + } + }; + return result; +} + //////////////////////////////// //~ rjf: Range Ops diff --git a/src/base/base_math.h b/src/base/base_math.h index e6f76423..eb322865 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -545,6 +545,7 @@ internal Mat4x4F32 mul_4x4f32(Mat4x4F32 a, Mat4x4F32 b); internal Mat4x4F32 scale_4x4f32(Mat4x4F32 m, F32 scale); internal Mat4x4F32 inverse_4x4f32(Mat4x4F32 m); internal Mat4x4F32 derotate_4x4f32(Mat4x4F32 mat); +internal Mat4x4F32 transpose_4x4f32(Mat4x4F32 mat); //////////////////////////////// //~ rjf: Range Ops diff --git a/src/render/d3d11/generated/render_d3d11.meta.h b/src/render/d3d11/generated/render_d3d11.meta.h index 5f5e1f12..6fd7f833 100644 --- a/src/render/d3d11/generated/render_d3d11.meta.h +++ b/src/render/d3d11/generated/render_d3d11.meta.h @@ -279,8 +279,7 @@ str8_lit_comp( " corner_radii_px.w,\n" " corner_radii_px.z,\n" " };\n" -" float2 cornercoords__pct = float2(\n" -" (c2v.vertex_id >> 1) ? 1.f : 0.f,\n" +" float2 cornercoords__pct = float2((c2v.vertex_id >> 1) ? 1.f : 0.f,\n" " (c2v.vertex_id & 1) ? 0.f : 1.f);\n" " \n" " float2 vertex_position__pct = vertex_positions__scrn[c2v.vertex_id] / viewport_size;\n" diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index f3ba394c..dca4586c 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -669,11 +669,11 @@ r_tex2d_release(R_Handle handle) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - if(texture != &r_d3d11_tex2d_nil) - { - SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); - } + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { + SLLStackPush(r_d3d11_state->first_to_free_tex2d, texture); + } } ProfEnd(); } @@ -705,19 +705,19 @@ r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) ProfBeginFunction(); OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { - R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); - if(texture != &r_d3d11_tex2d_nil) - { + R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + if(texture != &r_d3d11_tex2d_nil) + { Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; - Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); + Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); D3D11_BOX dst_box = { (UINT)subrect.x0, (UINT)subrect.y0, 0, (UINT)subrect.x1, (UINT)subrect.y1, 1, }; - r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); - } + r_d3d11_state->device_ctx->lpVtbl->UpdateSubresource(r_d3d11_state->device_ctx, (ID3D11Resource *)texture->texture, 0, &dst_box, data, dim.x*bytes_per_pixel, 0); + } } ProfEnd(); } @@ -823,10 +823,10 @@ r_end_frame(void) tex = next) { next = tex->next; - tex->view->lpVtbl->Release(tex->view); - tex->texture->lpVtbl->Release(tex->texture); - tex->view = 0; - tex->texture = 0; + tex->view->lpVtbl->Release(tex->view); + tex->texture->lpVtbl->Release(tex->texture); + tex->view = 0; + tex->texture = 0; tex->generation += 1; SLLStackPush(r_d3d11_state->first_free_tex2d, tex); } @@ -1119,29 +1119,14 @@ r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(texture_handle); // rjf: get texture sample map matrix, based on format - Vec4F32 texture_sample_channel_map[] = - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, - }; - switch(texture->format) - { - default: break; - case R_Tex2DFormat_R8: - { - MemoryZeroArray(texture_sample_channel_map); - texture_sample_channel_map[0] = v4f32(1, 1, 1, 1); - }break; - } + Mat4x4F32 texture_sample_channel_map = r_sample_channel_map_from_tex2dformat(texture->format); // rjf: upload uniforms R_D3D11_Uniforms_Rect uniforms = {0}; { uniforms.viewport_size = v2f32(resolution.x, resolution.y); uniforms.opacity = 1-group_params->transparency; - MemoryCopyArray(uniforms.texture_sample_channel_map, texture_sample_channel_map); + uniforms.texture_sample_channel_map = texture_sample_channel_map; uniforms.texture_t2d_size = v2f32(texture->size.x, texture->size.y); uniforms.xform[0] = v4f32(group_params->xform.v[0][0], group_params->xform.v[1][0], group_params->xform.v[2][0], 0); uniforms.xform[1] = v4f32(group_params->xform.v[0][1], group_params->xform.v[1][1], group_params->xform.v[2][1], 0); diff --git a/src/render/d3d11/render_d3d11.h b/src/render/d3d11/render_d3d11.h index aba28899..b1b0d5fd 100644 --- a/src/render/d3d11/render_d3d11.h +++ b/src/render/d3d11/render_d3d11.h @@ -29,7 +29,7 @@ struct R_D3D11_Uniforms_Rect Vec2F32 viewport_size; F32 opacity; F32 _padding0_; - Vec4F32 texture_sample_channel_map[4]; + Mat4x4F32 texture_sample_channel_map; Vec2F32 texture_t2d_size; Vec2F32 translate; Vec4F32 xform[3]; diff --git a/src/render/d3d11/render_d3d11.mdesk b/src/render/d3d11/render_d3d11.mdesk index 1c78b56b..81e2084d 100644 --- a/src/render/d3d11/render_d3d11.mdesk +++ b/src/render/d3d11/render_d3d11.mdesk @@ -277,8 +277,7 @@ vs_main(CPU2Vertex c2v) corner_radii_px.w, corner_radii_px.z, }; - float2 cornercoords__pct = float2( - (c2v.vertex_id >> 1) ? 1.f : 0.f, + float2 cornercoords__pct = float2((c2v.vertex_id >> 1) ? 1.f : 0.f, (c2v.vertex_id & 1) ? 0.f : 1.f); float2 vertex_position__pct = vertex_positions__scrn[c2v.vertex_id] / viewport_size; diff --git a/src/render/opengl/generated/render_opengl.meta.c b/src/render/opengl/generated/render_opengl.meta.c new file mode 100644 index 00000000..60c10194 --- /dev/null +++ b/src/render/opengl/generated/render_opengl.meta.c @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//- GENERATED CODE + +C_LINKAGE_BEGIN +String8 r_ogl_shader_kind_name_table[2] = +{ +str8_lit_comp("rect"), +str8_lit_comp("blur"), +}; + +String8 * r_ogl_shader_kind_vshad_src_table[2] = +{ +&r_ogl_rect_vshad_src, +&r_ogl_blur_vshad_src, +}; + +String8 * r_ogl_shader_kind_pshad_src_table[2] = +{ +&r_ogl_rect_pshad_src, +&r_ogl_blur_pshad_src, +}; + +R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2] = +{ +{ r_ogl_rect_input_attributes, ArrayCount(r_ogl_rect_input_attributes) }, +{ 0, }, +}; + +R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2] = +{ +{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, +{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, +}; + +C_LINKAGE_END + diff --git a/src/render/opengl/generated/render_opengl.meta.h b/src/render/opengl/generated/render_opengl.meta.h new file mode 100644 index 00000000..6e7f6024 --- /dev/null +++ b/src/render/opengl/generated/render_opengl.meta.h @@ -0,0 +1,276 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//- GENERATED CODE + +#ifndef RENDER_OPENGL_META_H +#define RENDER_OPENGL_META_H + +typedef enum R_OGL_ShaderKind +{ +R_OGL_ShaderKind_Rect, +R_OGL_ShaderKind_Blur, +R_OGL_ShaderKind_COUNT, +} R_OGL_ShaderKind; + +C_LINKAGE_BEGIN +extern String8 r_ogl_shader_kind_name_table[2]; +extern String8 * r_ogl_shader_kind_vshad_src_table[2]; +extern String8 * r_ogl_shader_kind_pshad_src_table[2]; +extern R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2]; +extern R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2]; +read_only global String8 r_ogl_rect_vshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"in vec4 c2v_dst_rect;\n" +"in vec4 c2v_src_rect;\n" +"in vec4 c2v_colors_0;\n" +"in vec4 c2v_colors_1;\n" +"in vec4 c2v_colors_2;\n" +"in vec4 c2v_colors_3;\n" +"in vec4 c2v_corner_radii;\n" +"in vec4 c2v_style; // x: border_thickness_px, y: softness_px, z: omit_texture, w: unused\n" +"\n" +"out vec2 v2p_sdf_sample_pos;\n" +"out vec2 v2p_texcoord_pct;\n" +"out vec2 v2p_rect_half_size_px;\n" +"out vec4 v2p_tint;\n" +"out float v2p_corner_radius;\n" +"out float v2p_border_thickness;\n" +"out float v2p_softness;\n" +"out float v2p_omit_texture;\n" +"\n" +"uniform sampler2D u_tex_color;\n" +"uniform vec2 u_viewport_size_px;\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: constants\n" +" vec2 vertices[] = vec2[](vec2(-1, -1), vec2(-1, +1), vec2(+1, -1), vec2(+1, +1));\n" +" \n" +" // rjf: find dst position\n" +" vec2 dst_half_size = (c2v_dst_rect.zw - c2v_dst_rect.xy) / 2;\n" +" vec2 dst_center = (c2v_dst_rect.zw + c2v_dst_rect.xy) / 2;\n" +" vec2 dst_position = vertices[gl_VertexID] * dst_half_size + dst_center;\n" +" \n" +" // rjf: find src position\n" +" vec2 src_half_size = (c2v_src_rect.zw - c2v_src_rect.xy) / 2;\n" +" vec2 src_center = (c2v_src_rect.zw + c2v_src_rect.xy) / 2;\n" +" vec2 src_position = vertices[gl_VertexID] * src_half_size + src_center;\n" +" \n" +" // rjf: find color\n" +" vec4 colors[] = vec4[](c2v_colors_0, c2v_colors_1, c2v_colors_2, c2v_colors_3);\n" +" vec4 color = colors[gl_VertexID];\n" +" \n" +" // rjf: find corner radius\n" +" float corner_radii[] = float[](c2v_corner_radii.x, c2v_corner_radii.y, c2v_corner_radii.z, c2v_corner_radii.w);\n" +" float corner_radius = corner_radii[gl_VertexID];\n" +" \n" +" // rjf: fill outputs\n" +" vec2 dst_verts_pct = vec2(((gl_VertexID >> 1) != 1) ? 1.f : 0.f,\n" +" ((gl_VertexID & 1) != 0) ? 0.f : 1.f);\n" +" ivec2 u_tex_color_size_i = textureSize(u_tex_color, 0);\n" +" vec2 u_tex_color_size = vec2(float(u_tex_color_size_i.x), float(u_tex_color_size_i.y));\n" +" {\n" +" gl_Position = vec4(2 * dst_position.x / u_viewport_size_px.x - 1,\n" +" 2 * (1 - dst_position.y / u_viewport_size_px.y) - 1,\n" +" 0.0, 1.0);\n" +" v2p_sdf_sample_pos = (2.f * dst_verts_pct - 1.f) * dst_half_size;\n" +" v2p_texcoord_pct = src_position / u_tex_color_size;\n" +" v2p_rect_half_size_px = dst_half_size;\n" +" v2p_tint = color;\n" +" v2p_corner_radius = corner_radius;\n" +" v2p_border_thickness = c2v_style.x;\n" +" v2p_softness = c2v_style.y;\n" +" v2p_omit_texture = c2v_style.z;\n" +" }\n" +"}\n" +"" +); + +read_only global String8 r_ogl_rect_pshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"in vec2 v2p_sdf_sample_pos;\n" +"in vec2 v2p_texcoord_pct;\n" +"in vec2 v2p_rect_half_size_px;\n" +"in vec4 v2p_tint;\n" +"in float v2p_corner_radius;\n" +"in float v2p_border_thickness;\n" +"in float v2p_softness;\n" +"in float v2p_omit_texture;\n" +"\n" +"out vec4 final_color;\n" +"\n" +"uniform float u_opacity;\n" +"uniform sampler2D u_tex_color;\n" +"uniform mat4 u_texture_sample_channel_map;\n" +"\n" +"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" +"{\n" +" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" +"}\n" +"\n" +"float linear_from_srgb_f32(float x)\n" +"{\n" +" return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);\n" +"}\n" +"\n" +"vec4 linear_from_srgba(vec4 v)\n" +"{\n" +" vec4 result = vec4(linear_from_srgb_f32(v.x),\n" +" linear_from_srgb_f32(v.y),\n" +" linear_from_srgb_f32(v.z),\n" +" v.w);\n" +" return result;\n" +"}\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: sample texture\n" +" vec4 albedo_sample = vec4(1, 1, 1, 1);\n" +" if(v2p_omit_texture < 1)\n" +" {\n" +" albedo_sample = u_texture_sample_channel_map * texture(u_tex_color, v2p_texcoord_pct);\n" +" albedo_sample = linear_from_srgba(albedo_sample);\n" +" }\n" +" \n" +" // rjf: sample for borders\n" +" float border_sdf_t = 1;\n" +" if(v2p_border_thickness > 0)\n" +" {\n" +" float border_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" +" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f) - v2p_border_thickness,\n" +" max(v2p_corner_radius-v2p_border_thickness, 0));\n" +" border_sdf_t = smoothstep(0, 2*v2p_softness, border_sdf_s);\n" +" }\n" +" if(border_sdf_t < 0.001f)\n" +" {\n" +" discard;\n" +" }\n" +" \n" +" // rjf: sample for corners\n" +" float corner_sdf_t = 1;\n" +" if(v2p_corner_radius > 0 || v2p_softness > 0.75f)\n" +" {\n" +" float corner_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" +" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f),\n" +" v2p_corner_radius);\n" +" corner_sdf_t = 1-smoothstep(0, 2*v2p_softness, corner_sdf_s);\n" +" }\n" +" \n" +" // rjf: form+return final color\n" +" final_color = albedo_sample;\n" +" final_color *= v2p_tint;\n" +" final_color.a *= u_opacity;\n" +" final_color.a *= corner_sdf_t;\n" +" final_color.a *= border_sdf_t;\n" +"}\n" +"" +); + +read_only global String8 r_ogl_blur_vshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"uniform vec4 rect;\n" +"uniform vec4 corner_radii_px;\n" +"uniform vec2 viewport_size;\n" +"uniform uint blur_count;\n" +"\n" +"out vec2 texcoord;\n" +"out vec2 sdf_sample_pos;\n" +"out vec2 rect_half_size;\n" +"out float corner_radius;\n" +"\n" +"void main(void)\n" +"{\n" +" vec2 vertex_positions_scrn[] = vec2[](rect.xw,\n" +" rect.xy,\n" +" rect.zw,\n" +" rect.zy);\n" +" float corner_radii_px[] = float[](corner_radii_px.y,\n" +" corner_radii_px.x,\n" +" corner_radii_px.w,\n" +" corner_radii_px.z);\n" +" vec2 cornercoords_pct = vec2((gl_VertexID >> 1) != 0 ? 1.f : 0.f,\n" +" (gl_VertexID & 1) != 0 ? 0.f : 1.f);\n" +" \n" +" vec2 vertex_position_pct = vertex_positions_scrn[gl_VertexID] / viewport_size;\n" +" vec2 vertex_position_scr = 2.f * vertex_position_pct - 1.f;\n" +" \n" +" vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2);\n" +" \n" +" gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f);\n" +" texcoord = vertex_position_pct;\n" +" sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size;\n" +" rect_half_size = rect_half_size - 2.f;\n" +" corner_radius = corner_radii_px[gl_VertexID];\n" +"}\n" +"" +); + +read_only global String8 r_ogl_blur_pshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"uniform sampler2D tex;\n" +"uniform vec4 kernel[32];\n" +"uniform int blur_count;\n" +"uniform vec2 direction;\n" +"\n" +"in vec2 texcoord;\n" +"in vec2 sdf_sample_pos;\n" +"in vec2 rect_half_size;\n" +"in float corner_radius;\n" +"\n" +"out vec4 final_color;\n" +"\n" +"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" +"{\n" +" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" +"}\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: blend weighted texture samples into color\n" +" vec3 color = kernel[0].x * texture(tex, texcoord).rgb;\n" +" \n" +" for(int i = 1; i < blur_count; i += 1)\n" +" {\n" +" float weight = kernel[i].x;\n" +" float offset = kernel[i].y;\n" +" color += weight * texture(tex, texcoord - offset * direction).rgb;\n" +" color += weight * texture(tex, texcoord + offset * direction).rgb;\n" +" }\n" +" \n" +" // rjf: sample for corners\n" +" float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius);\n" +" float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s);\n" +" \n" +" // rjf: weight output color by sdf\n" +" // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n" +" if(corner_sdf_t < 0.9f)\n" +" {\n" +" discard;\n" +" }\n" +" \n" +" final_color = vec4(color, 1.f);\n" +"}\n" +"" +); + + +C_LINKAGE_END + +#endif // RENDER_OPENGL_META_H diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c new file mode 100644 index 00000000..cfbec7de --- /dev/null +++ b/src/render/opengl/render_opengl.c @@ -0,0 +1,480 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: OS Portion Includes + +#if OS_WINDOWS +# include "render/opengl/win32/render_opengl_win32.c" +#else +# error OS portion of OpenGL rendering backend not defined. +#endif + +//////////////////////////////// +//~ rjf: Attribute Tables + +global read_only R_OGL_Attribute r_ogl_rect_input_attributes[] = +{ + {0, str8_lit_comp("c2v_dst_rect"), GL_FLOAT, 4}, + {1, str8_lit_comp("c2v_src_rect"), GL_FLOAT, 4}, + {2, str8_lit_comp("c2v_colors_0"), GL_FLOAT, 4}, + {3, str8_lit_comp("c2v_colors_1"), GL_FLOAT, 4}, + {4, str8_lit_comp("c2v_colors_2"), GL_FLOAT, 4}, + {5, str8_lit_comp("c2v_colors_3"), GL_FLOAT, 4}, + {6, str8_lit_comp("c2v_corner_radii"), GL_FLOAT, 4}, + {7, str8_lit_comp("c2v_style"), GL_FLOAT, 4}, +}; + +global read_only R_OGL_Attribute r_ogl_single_color_output_attributes[] = +{ + {0, str8_lit_comp("final_color")}, +}; + +//////////////////////////////// +//~ rjf: Generated Code + +#include "render/opengl/generated/render_opengl.meta.c" + +//////////////////////////////// +//~ rjf: Helpers + +internal R_Handle +r_ogl_handle_from_tex2d(R_OGL_Tex2D *t) +{ + R_Handle h = {(U64)t}; + return h; +} + +internal R_OGL_Tex2D * +r_ogl_tex2d_from_handle(R_Handle h) +{ + R_OGL_Tex2D *t = (R_OGL_Tex2D *)h.u64[0]; + return t; +} + +internal R_OGL_FormatInfo +r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt) +{ + R_OGL_FormatInfo result; + result.internal_format = GL_RGBA; + result.format = GL_RGBA; + result.base_type = GL_UNSIGNED_BYTE; + // TODO(rjf) + return result; +} + +internal void +r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +{ + raddbg_log("[OpenGL] %.*s\n", (int)length, message); +} + +//////////////////////////////// +//~ rjf: Backend Hooks + +//- rjf: top-level layer initialization + +r_hook void +r_init(CmdLine *cmdln) +{ + //- rjf: do os-specific portion of work + r_ogl_os_init(cmdln); + + //- rjf: top-level initialization + Arena *arena = arena_alloc(); + r_ogl_state = push_array(arena, R_OGL_State, 1); + r_ogl_state->arena = arena; + + //- rjf: load gl procedures +#define X(name, r, p) name = (name##_FunctionType *)r_ogl_os_load_procedure(#name); + R_OGL_ProcedureXList +#undef X + + //- rjf: build all shaders + for EachEnumVal(R_OGL_ShaderKind, k) + { + // rjf: compile + struct {GLenum type; String8 *src; GLuint out; String8 errors;} stages[] = + { + {GL_VERTEX_SHADER, r_ogl_shader_kind_vshad_src_table[k]}, + {GL_FRAGMENT_SHADER, r_ogl_shader_kind_pshad_src_table[k]}, + }; + for EachElement(idx, stages) + { + stages[idx].out = glCreateShader(stages[idx].type); + GLint src_size = stages[idx].src->size; + glShaderSource(stages[idx].out, 1, &stages[idx].src->str, &src_size); + glCompileShader(stages[idx].out); + GLint info_log_length = 0; + GLint status = 0; + glGetShaderiv(stages[idx].out, GL_COMPILE_STATUS, &status); + glGetShaderiv(stages[idx].out, GL_INFO_LOG_LENGTH, &info_log_length); + if(info_log_length != 0) + { + stages[idx].errors.str = push_array(r_ogl_state->arena, U8, info_log_length+1); + stages[idx].errors.size = info_log_length; + glGetShaderInfoLog(stages[idx].out, info_log_length, 0, stages[idx].errors.str); + } + raddbg_pin(text(stages[idx].errors.str)); + } + + // rjf: attach compilations to program + GLuint program = glCreateProgram(); + for EachElement(idx, stages) + { + glAttachShader(program, stages[idx].out); + } + + // rjf: bind inputs + R_OGL_AttributeArray inputs = r_ogl_shader_kind_input_attributes_table[k]; + for EachIndex(idx, inputs.count) + { + glBindAttribLocation(program, inputs.v[idx].index, inputs.v[idx].name.str); + } + + // rjf: bind outputs + R_OGL_AttributeArray outputs = r_ogl_shader_kind_output_attributes_table[k]; + for EachIndex(idx, outputs.count) + { + glBindFragDataLocation(program, outputs.v[idx].index, outputs.v[idx].name.str); + } + + // rjf: link / validate / store + glLinkProgram(program); + glValidateProgram(program); + r_ogl_state->shaders[k] = program; + } + + //- rjf: set up built-in resources + glGenVertexArrays(1, &r_ogl_state->all_purpose_vao); + glGenBuffers(1, &r_ogl_state->scratch_buffer_2mb); + glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_2mb); + glBufferData(GL_ARRAY_BUFFER, MB(2), 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glGenTextures(1, &r_ogl_state->white_texture); + glBindTexture(GL_TEXTURE_2D, r_ogl_state->white_texture); + U32 white_pixel = 0xffffffff; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_pixel); + glEnable(GL_FRAMEBUFFER_SRGB); + + //- rjf: set up debug callback + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(r_ogl_debug_message_callback, 0); +} + +//- rjf: window setup/teardown + +r_hook R_Handle +r_window_equip(OS_Handle window) +{ + R_Handle result = r_ogl_os_window_equip(window); + return result; +} + +r_hook void +r_window_unequip(OS_Handle window, R_Handle window_equip) +{ + r_ogl_os_window_unequip(window, window_equip); +} + +//- rjf: textures + +r_hook R_Handle +r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) +{ + //- rjf: allocate texture record + R_OGL_Tex2D *tex2d = r_ogl_state->free_tex2d; + if(tex2d) + { + SLLStackPop(r_ogl_state->free_tex2d); + } + else + { + tex2d = push_array(r_ogl_state->arena, R_OGL_Tex2D, 1); + } + + //- rjf: map kind/format -> gl counterparts + R_OGL_FormatInfo gl_fmt_info = r_ogl_format_info_from_tex2dformat(format); + + //- rjf: allocate GL texture + { + glGenTextures(1, &tex2d->id); + glBindTexture(GL_TEXTURE_2D, tex2d->id); + glTexImage2D(GL_TEXTURE_2D, 0, gl_fmt_info.internal_format, size.x, size.y, 0, gl_fmt_info.format, gl_fmt_info.base_type, data); + glBindTexture(GL_TEXTURE_2D, 0); + } + + //- rjf: fill + tex2d->resource_kind = kind; + tex2d->fmt = format; + tex2d->size = size; + + //- rjf: bundle & return + R_Handle result = r_ogl_handle_from_tex2d(tex2d); + return result; +} + +r_hook void +r_tex2d_release(R_Handle texture) +{ + R_OGL_Tex2D *t = r_ogl_tex2d_from_handle(texture); + if(t != 0) + { + glDeleteTextures(1, &t->id); + SLLStackPush(r_ogl_state->free_tex2d, t); + } +} + +r_hook R_ResourceKind +r_kind_from_tex2d(R_Handle texture) +{ + R_ResourceKind result = R_ResourceKind_Static; + R_OGL_Tex2D *t = r_ogl_tex2d_from_handle(texture); + if(t) + { + result = t->resource_kind; + } + return result; +} + +r_hook Vec2S32 +r_size_from_tex2d(R_Handle texture) +{ + Vec2S32 result = {0, 0}; + R_OGL_Tex2D *t = r_ogl_tex2d_from_handle(texture); + if(t) + { + result = t->size; + } + return result; +} + +r_hook R_Tex2DFormat +r_format_from_tex2d(R_Handle texture) +{ + R_Tex2DFormat result = R_Tex2DFormat_RGBA8; + R_OGL_Tex2D *t = r_ogl_tex2d_from_handle(texture); + if(t) + { + result = t->fmt; + } + return result; +} + +r_hook void +r_fill_tex2d_region(R_Handle texture, Rng2S32 subrect, void *data) +{ + R_OGL_Tex2D *t = r_ogl_tex2d_from_handle(texture); + if(t) + { + R_OGL_FormatInfo fmt_info = r_ogl_format_info_from_tex2dformat(t->fmt); + glBindTexture(GL_TEXTURE_2D, t->id); + Vec2S32 rect_size = dim_2s32(subrect); + glTexSubImage2D(GL_TEXTURE_2D, 0, subrect.x0, subrect.y0, rect_size.x, rect_size.y, fmt_info.format, fmt_info.base_type, data); + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +//- rjf: buffers + +r_hook R_Handle +r_buffer_alloc(R_ResourceKind kind, U64 size, void *data) +{ + R_Handle result = {0}; + return result; +} + +r_hook void +r_buffer_release(R_Handle buffer) +{ + // TODO(rjf) +} + +//- rjf: frame markers + +r_hook void +r_begin_frame(void) +{ + // TODO(rjf) +} + +r_hook void +r_end_frame(void) +{ + // TODO(rjf) +} + +r_hook void +r_window_begin_frame(OS_Handle os, R_Handle r) +{ + r_ogl_os_select_window(os, r); + + //- rjf: unpack window viewport info + Rng2F32 client_rect = os_client_rect_from_window(os); + Vec2F32 client_rect_dim = dim_2f32(client_rect); + + //- rjf: clear and reset state + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, (S32)client_rect_dim.x, (S32)client_rect_dim.y); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +r_hook void +r_window_end_frame(OS_Handle os, R_Handle r) +{ + r_ogl_os_window_swap(os, r); +} + +//- rjf: render pass submission + +r_hook void +r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) +{ + Rng2F32 viewport_rect = os_client_rect_from_window(window); + Vec2F32 viewport_dim = dim_2f32(viewport_rect); + for(R_PassNode *pass_n = passes->first; pass_n != 0; pass_n = pass_n->next) + { + R_Pass *pass = &pass_n->v; + switch(pass->kind) + { + default:{}break; + + //////////////////////// + //- rjf: ui rendering pass + // + case R_PassKind_UI: + { + //- rjf: unpack params + R_PassParams_UI *params = pass->params_ui; + R_BatchGroup2DList *rect_batch_groups = ¶ms->rects; + + //- rjf: draw each batch group + GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Rect]; + glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) + { + for(R_BatchGroup2DNode *group_n = rect_batch_groups->first; group_n != 0; group_n = group_n->next) + { + R_BatchList *batches = &group_n->batches; + R_BatchGroup2DParams *group_params = &group_n->params; + + //- rjf: unpack texture + R_Tex2DFormat texture_fmt = R_Tex2DFormat_RGBA8; + GLuint texture_id = r_ogl_state->white_texture; + { + R_OGL_Tex2D *tex = r_ogl_tex2d_from_handle(group_params->tex); + if(tex != 0) + { + texture_id = tex->id; + texture_fmt = tex->fmt; + } + } + + //- rjf: get & fill buffer + GLuint buffer = r_ogl_state->scratch_buffer_2mb; // TODO(rjf): r_ogl_instance_buffer_from_size(batches->byte_count); + { + glBindBuffer(GL_ARRAY_BUFFER, buffer); + U64 off = 0; + for(R_BatchNode *batch_n = batches->first; batch_n != 0; batch_n = batch_n->next) + { + glBufferSubData(GL_ARRAY_BUFFER, off, batch_n->v.byte_count, batch_n->v.v); + off += batch_n->v.byte_count; + } + } + + //- rjf: bind input attributes + { + R_OGL_AttributeArray inputs = r_ogl_shader_kind_input_attributes_table[R_OGL_ShaderKind_Rect]; + U64 off = 0; + for EachIndex(idx, inputs.count) + { + glEnableVertexAttribArray(inputs.v[idx].index); + glVertexAttribDivisor(inputs.v[idx].index, 1); + glVertexAttribPointer(inputs.v[idx].index, inputs.v[idx].count, inputs.v[idx].type, GL_FALSE, sizeof(R_Rect2DInst), (void *)(off)); + // TODO(rjf): this is not correct if type != GL_FLOAT + off += inputs.v[idx].count*sizeof(F32); + } + } + + //- rjf: bind texture + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + switch(group_params->tex_sample_kind) + { + default: + case R_Tex2DSampleKind_Nearest: + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + }break; + case R_Tex2DSampleKind_Linear: + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + }break; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glUniform1i(glGetUniformLocation(shader, "u_tex_color"), 0); + } + + //- rjf: upload misc. uniforms + { + Mat4x4F32 texture_sample_channel_map = r_sample_channel_map_from_tex2dformat(texture_fmt); + glUniformMatrix4fv(glGetUniformLocation(shader, "u_texture_sample_channel_map"), 1, 0, &texture_sample_channel_map.v[0][0]); + glUniform2f(glGetUniformLocation(shader, "u_viewport_size_px"), viewport_dim.x, viewport_dim.y); + glUniform1f(glGetUniformLocation(shader, "u_opacity"), 1.f - group_params->transparency); + } + + //- rjf: set up scissor + if(group_params->clip.x0 != 0 || + group_params->clip.x1 != 0 || + group_params->clip.y0 != 0 || + group_params->clip.y1 != 0) + { + Rng2F32 clip = group_params->clip; + glScissor(clip.x0, viewport_dim.y - clip.y1, (clip.x1-clip.x0) + 1, (clip.y1-clip.y0)+1); + glEnable(GL_SCISSOR_TEST); + } + + //- rjf: draw + { + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, batches->byte_count / batches->bytes_per_inst); + } + + //- rjf: unset scissor + glDisable(GL_SCISSOR_TEST); + } + } + }break; + + //////////////////////// + //- rjf: blur rendering pass + // + case R_PassKind_Blur: + { + R_PassParams_Blur *params = pass->params_blur; + GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Blur]; + glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) + { + // TODO(rjf) + } + }break; + + + //////////////////////// + //- rjf: 3d geometry rendering pass + // + case R_PassKind_Geo3D: + { + //- rjf: unpack params + R_PassParams_Geo3D *params = pass->params_geo3d; + R_BatchGroup3DMap *mesh_group_map = ¶ms->mesh_batches; + // TODO(rjf) + }break; + } + } +} diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h new file mode 100644 index 00000000..39ee5b5d --- /dev/null +++ b/src/render/opengl/render_opengl.h @@ -0,0 +1,217 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_H +#define RENDER_OPENGL_H + +//////////////////////////////// +//~ rjf: OS Backend Includes + +#if OS_WINDOWS +# include "render/opengl/win32/render_opengl_win32.h" +#else +# error OS portion of OpenGL rendering backend not defined. +#endif + +//////////////////////////////// +//~ rjf: Shader Metadata Types + +typedef struct R_OGL_Attribute R_OGL_Attribute; +struct R_OGL_Attribute +{ + U64 index; + String8 name; + GLenum type; + U64 count; +}; + +typedef struct R_OGL_AttributeArray R_OGL_AttributeArray; +struct R_OGL_AttributeArray +{ + R_OGL_Attribute *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Generated Code + +#include "render/opengl/generated/render_opengl.meta.h" + +//////////////////////////////// +//~ rjf: Defines + +typedef char GLchar; +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_TEXTURE_MAX_LEVEL 0x813D + +#define GL_R8 0x8229 + +#define GL_ARRAY_BUFFER 0x8892 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA + +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_INFO_LOG_LENGTH 0x8B84 + +#define GL_TEXTURE_2D_ARRAY 0x8C1A + +#define GL_COMPILE_STATUS 0x8B81 + +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF + +#define GL_DEBUG_OUTPUT 0x92E0 + +//////////////////////////////// +//~ rjf: OpenGL Procedure List + +#define R_OGL_ProcedureXList \ +X(glGenBuffers, void, (GLsizei n, GLuint *buffers))\ +X(glBindBuffer, void, (GLenum target, GLuint buffer))\ +X(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))\ +X(glBindVertexArray, void, (GLuint array))\ +X(glCreateProgram, GLuint, (void))\ +X(glCreateShader, GLuint, (GLenum type))\ +X(glShaderSource, void, (GLuint shader, GLsizei count, char **string, GLint *length))\ +X(glCompileShader, void, (GLuint shader))\ +X(glGetShaderiv, void, (GLuint shader, GLenum pname, GLint *params))\ +X(glGetShaderInfoLog, void, (GLuint shader, GLsizei bufSize, GLsizei *length, char *infoLog))\ +X(glGetProgramiv, void, (GLuint program, GLenum pname, GLint *params))\ +X(glGetProgramInfoLog, void, (GLuint program, GLsizei bufSize, GLsizei *length, char *infoLog))\ +X(glAttachShader, void, (GLuint program, GLuint shader))\ +X(glLinkProgram, void, (GLuint program))\ +X(glValidateProgram, void, (GLuint program))\ +X(glDeleteShader, void, (GLuint shader))\ +X(glUseProgram, void, (GLuint program))\ +X(glGetUniformLocation, GLint, (GLuint program, char *name))\ +X(glGetAttribLocation, GLint, (GLuint program, char *name))\ +X(glEnableVertexAttribArray, void, (GLuint index))\ +X(glVertexAttribPointer, void, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer))\ +X(glBufferData, void, (GLenum target, ptrdiff_t size, void *data, GLenum usage))\ +X(glBufferSubData, void, (GLenum target, ptrdiff_t offset, ptrdiff_t size, const void *data))\ +X(glBlendFuncSeparate, void, (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha))\ +X(glUniform1f, void, (GLint location, GLfloat v0))\ +X(glUniform2f, void, (GLint location, GLfloat v0, GLfloat v1))\ +X(glUniform3f, void, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2))\ +X(glUniform4f, void, (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3))\ +X(glUniformMatrix4fv, void, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value))\ +X(glUniform1i, void, (GLint location, GLint v0))\ +X(glTexImage3D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels))\ +X(glTexSubImage3D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels))\ +X(glGenerateMipmap, void, (GLenum target))\ +X(glBindAttribLocation, void, (GLuint programObj, GLuint index, char *name))\ +X(glBindFragDataLocation, void, (GLuint program, GLuint color, char *name))\ +X(glActiveTexture, void, (GLenum texture))\ +X(glVertexAttribDivisor, void, (GLuint index, GLuint divisor))\ +X(glDrawArraysInstanced, void, (GLenum mode, GLint first, GLsizei count, GLsizei instancecount))\ +X(glDebugMessageCallback, void, (void (*)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam), void *user_data))\ + +#define X(name, r, p) typedef r name##_FunctionType p; +R_OGL_ProcedureXList +#undef X +#define X(name, r, p) global name##_FunctionType *name = 0; +R_OGL_ProcedureXList +#undef X + +//////////////////////////////// +//~ rjf: State Types + +typedef struct R_OGL_FormatInfo R_OGL_FormatInfo; +struct R_OGL_FormatInfo +{ + GLint internal_format; + GLenum format; + GLenum base_type; +}; + +typedef struct R_OGL_Tex2D R_OGL_Tex2D; +struct R_OGL_Tex2D +{ + R_OGL_Tex2D *next; + GLuint id; + R_ResourceKind resource_kind; + R_Tex2DFormat fmt; + Vec2S32 size; +}; + +typedef struct R_OGL_State R_OGL_State; +struct R_OGL_State +{ + Arena *arena; + R_OGL_Tex2D *free_tex2d; + GLuint shaders[R_OGL_ShaderKind_COUNT]; + GLuint all_purpose_vao; + GLuint scratch_buffer_2mb; + GLuint white_texture; +}; + +//////////////////////////////// +//~ rjf: Globals + +global R_OGL_State *r_ogl_state = 0; + +//////////////////////////////// +//~ rjf: Helpers + +internal R_Handle r_ogl_handle_from_tex2d(R_OGL_Tex2D *t); +internal R_OGL_Tex2D *r_ogl_tex2d_from_handle(R_Handle h); +internal R_OGL_FormatInfo r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt); +internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + +#define glUseProgramScope(...) DeferLoop(glUseProgram(__VA_ARGS__), glUseProgram(0)) +#define glBindVertexArrayScope(...) DeferLoop(glBindVertexArray(__VA_ARGS__), glBindVertexArray(0)) + +//////////////////////////////// +//~ rjf: OS-Specific Hooks + +internal VoidProc *r_ogl_os_load_procedure(char *name); +internal void r_ogl_os_init(CmdLine *cmdln); +internal R_Handle r_ogl_os_window_equip(OS_Handle window); +internal void r_ogl_os_window_unequip(OS_Handle os, R_Handle r); +internal void r_ogl_os_select_window(OS_Handle os, R_Handle r); +internal void r_ogl_os_window_swap(OS_Handle os, R_Handle r); + +#endif // RENDER_OPENGL_H diff --git a/src/render/opengl/render_opengl.mdesk b/src/render/opengl/render_opengl.mdesk new file mode 100644 index 00000000..d96874cd --- /dev/null +++ b/src/render/opengl/render_opengl.mdesk @@ -0,0 +1,292 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Shader Table + +@table(name name_lower input_atts output_atts) +R_OGL_ShaderTable: +{ + {Rect rect r_ogl_rect_input_attributes r_ogl_single_color_output_attributes} + {Blur blur 0 r_ogl_single_color_output_attributes} +} + +@enum R_OGL_ShaderKind: +{ + @expand(R_OGL_ShaderTable a) `$(a.name)`, + COUNT +} + +@data(String8) r_ogl_shader_kind_name_table: +{ + @expand(R_OGL_ShaderTable a) `str8_lit_comp("$(a.name_lower)")`, +} + +@data(`String8 *`) r_ogl_shader_kind_vshad_src_table: +{ + @expand(R_OGL_ShaderTable a) `&r_ogl_$(a.name_lower)_vshad_src`, +} + +@data(`String8 *`) r_ogl_shader_kind_pshad_src_table: +{ + @expand(R_OGL_ShaderTable a) `&r_ogl_$(a.name_lower)_pshad_src`, +} + +@data(R_OGL_AttributeArray) r_ogl_shader_kind_input_attributes_table: +{ + @expand(R_OGL_ShaderTable a) `{ $(a.input_atts), $(a.input_atts != 0 -> "ArrayCount(" .. a.input_atts .. ")") }`, +} + +@data(R_OGL_AttributeArray) r_ogl_shader_kind_output_attributes_table: +{ + @expand(R_OGL_ShaderTable a) `{ $(a.output_atts), ArrayCount($(a.output_atts)) }`, +} + +//////////////////////////////// +//~ rjf: UI Rectangle Shaders + +//- rjf: vertex +@embed_string r_ogl_rect_vshad_src: +``` +#version 330 core + +in vec4 c2v_dst_rect; +in vec4 c2v_src_rect; +in vec4 c2v_colors_0; +in vec4 c2v_colors_1; +in vec4 c2v_colors_2; +in vec4 c2v_colors_3; +in vec4 c2v_corner_radii; +in vec4 c2v_style; // x: border_thickness_px, y: softness_px, z: omit_texture, w: unused + +out vec2 v2p_sdf_sample_pos; +out vec2 v2p_texcoord_pct; +out vec2 v2p_rect_half_size_px; +out vec4 v2p_tint; +out float v2p_corner_radius; +out float v2p_border_thickness; +out float v2p_softness; +out float v2p_omit_texture; + +uniform sampler2D u_tex_color; +uniform vec2 u_viewport_size_px; + +void main(void) +{ + // rjf: constants + vec2 vertices[] = vec2[](vec2(-1, -1), vec2(-1, +1), vec2(+1, -1), vec2(+1, +1)); + + // rjf: find dst position + vec2 dst_half_size = (c2v_dst_rect.zw - c2v_dst_rect.xy) / 2; + vec2 dst_center = (c2v_dst_rect.zw + c2v_dst_rect.xy) / 2; + vec2 dst_position = vertices[gl_VertexID] * dst_half_size + dst_center; + + // rjf: find src position + vec2 src_half_size = (c2v_src_rect.zw - c2v_src_rect.xy) / 2; + vec2 src_center = (c2v_src_rect.zw + c2v_src_rect.xy) / 2; + vec2 src_position = vertices[gl_VertexID] * src_half_size + src_center; + + // rjf: find color + vec4 colors[] = vec4[](c2v_colors_0, c2v_colors_1, c2v_colors_2, c2v_colors_3); + vec4 color = colors[gl_VertexID]; + + // rjf: find corner radius + float corner_radii[] = float[](c2v_corner_radii.x, c2v_corner_radii.y, c2v_corner_radii.z, c2v_corner_radii.w); + float corner_radius = corner_radii[gl_VertexID]; + + // rjf: fill outputs + vec2 dst_verts_pct = vec2(((gl_VertexID >> 1) != 1) ? 1.f : 0.f, + ((gl_VertexID & 1) != 0) ? 0.f : 1.f); + ivec2 u_tex_color_size_i = textureSize(u_tex_color, 0); + vec2 u_tex_color_size = vec2(float(u_tex_color_size_i.x), float(u_tex_color_size_i.y)); + { + gl_Position = vec4(2 * dst_position.x / u_viewport_size_px.x - 1, + 2 * (1 - dst_position.y / u_viewport_size_px.y) - 1, + 0.0, 1.0); + v2p_sdf_sample_pos = (2.f * dst_verts_pct - 1.f) * dst_half_size; + v2p_texcoord_pct = src_position / u_tex_color_size; + v2p_rect_half_size_px = dst_half_size; + v2p_tint = color; + v2p_corner_radius = corner_radius; + v2p_border_thickness = c2v_style.x; + v2p_softness = c2v_style.y; + v2p_omit_texture = c2v_style.z; + } +} +``` + +//- rjf: pixel +@embed_string r_ogl_rect_pshad_src: +``` +#version 330 core + +in vec2 v2p_sdf_sample_pos; +in vec2 v2p_texcoord_pct; +in vec2 v2p_rect_half_size_px; +in vec4 v2p_tint; +in float v2p_corner_radius; +in float v2p_border_thickness; +in float v2p_softness; +in float v2p_omit_texture; + +out vec4 final_color; + +uniform float u_opacity; +uniform sampler2D u_tex_color; +uniform mat4 u_texture_sample_channel_map; + +float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r) +{ + return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r; +} + +float linear_from_srgb_f32(float x) +{ + return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4); +} + +vec4 linear_from_srgba(vec4 v) +{ + vec4 result = vec4(linear_from_srgb_f32(v.x), + linear_from_srgb_f32(v.y), + linear_from_srgb_f32(v.z), + v.w); + return result; +} + +void main(void) +{ + // rjf: sample texture + vec4 albedo_sample = vec4(1, 1, 1, 1); + if(v2p_omit_texture < 1) + { + albedo_sample = u_texture_sample_channel_map * texture(u_tex_color, v2p_texcoord_pct); + albedo_sample = linear_from_srgba(albedo_sample); + } + + // rjf: sample for borders + float border_sdf_t = 1; + if(v2p_border_thickness > 0) + { + float border_sdf_s = rect_sdf(v2p_sdf_sample_pos, + v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f) - v2p_border_thickness, + max(v2p_corner_radius-v2p_border_thickness, 0)); + border_sdf_t = smoothstep(0, 2*v2p_softness, border_sdf_s); + } + if(border_sdf_t < 0.001f) + { + discard; + } + + // rjf: sample for corners + float corner_sdf_t = 1; + if(v2p_corner_radius > 0 || v2p_softness > 0.75f) + { + float corner_sdf_s = rect_sdf(v2p_sdf_sample_pos, + v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f), + v2p_corner_radius); + corner_sdf_t = 1-smoothstep(0, 2*v2p_softness, corner_sdf_s); + } + + // rjf: form+return final color + final_color = albedo_sample; + final_color *= v2p_tint; + final_color.a *= u_opacity; + final_color.a *= corner_sdf_t; + final_color.a *= border_sdf_t; +} +``` + +//////////////////////////////// +//~ rjf: Blur Shaders + +//- rjf: vertex +@embed_string r_ogl_blur_vshad_src: +``` +#version 330 core + +uniform vec4 rect; +uniform vec4 corner_radii_px; +uniform vec2 viewport_size; +uniform uint blur_count; + +out vec2 texcoord; +out vec2 sdf_sample_pos; +out vec2 rect_half_size; +out float corner_radius; + +void main(void) +{ + vec2 vertex_positions_scrn[] = vec2[](rect.xw, + rect.xy, + rect.zw, + rect.zy); + float corner_radii_px[] = float[](corner_radii_px.y, + corner_radii_px.x, + corner_radii_px.w, + corner_radii_px.z); + vec2 cornercoords_pct = vec2((gl_VertexID >> 1) != 0 ? 1.f : 0.f, + (gl_VertexID & 1) != 0 ? 0.f : 1.f); + + vec2 vertex_position_pct = vertex_positions_scrn[gl_VertexID] / viewport_size; + vec2 vertex_position_scr = 2.f * vertex_position_pct - 1.f; + + vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2); + + gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f); + texcoord = vertex_position_pct; + sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size; + rect_half_size = rect_half_size - 2.f; + corner_radius = corner_radii_px[gl_VertexID]; +} +``` + +//- rjf: pixel +@embed_string r_ogl_blur_pshad_src: +``` +#version 330 core + +uniform sampler2D tex; +uniform vec4 kernel[32]; +uniform int blur_count; +uniform vec2 direction; + +in vec2 texcoord; +in vec2 sdf_sample_pos; +in vec2 rect_half_size; +in float corner_radius; + +out vec4 final_color; + +float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r) +{ + return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r; +} + +void main(void) +{ + // rjf: blend weighted texture samples into color + vec3 color = kernel[0].x * texture(tex, texcoord).rgb; + + for(int i = 1; i < blur_count; i += 1) + { + float weight = kernel[i].x; + float offset = kernel[i].y; + color += weight * texture(tex, texcoord - offset * direction).rgb; + color += weight * texture(tex, texcoord + offset * direction).rgb; + } + + // rjf: sample for corners + float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius); + float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s); + + // rjf: weight output color by sdf + // this is doing alpha testing, leave blurring only where mostly opaque pixels are + if(corner_sdf_t < 0.9f) + { + discard; + } + + final_color = vec4(color, 1.f); +} +``` diff --git a/src/render/opengl/win32/render_opengl_win32.c b/src/render/opengl/win32/render_opengl_win32.c new file mode 100644 index 00000000..7b40d711 --- /dev/null +++ b/src/render/opengl/win32/render_opengl_win32.c @@ -0,0 +1,184 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal VoidProc * +r_ogl_os_load_procedure(char *name) +{ + VoidProc *p = (VoidProc*)wglGetProcAddress(name); + if(p == (VoidProc*)1 || p == (VoidProc*)2 || p == (VoidProc*)3 || p == (VoidProc*)-1) + { + p = 0; + } + return p; +} + +internal void +r_ogl_os_init(CmdLine *cmdline) +{ + //- rjf: create bootstrapping window + HWND bootstrap_hwnd = 0; + { + WNDCLASSEXW wndclass = { sizeof(wndclass) }; + wndclass.lpfnWndProc = DefWindowProcW; + wndclass.hInstance = GetModuleHandle(0); + wndclass.lpszClassName = L"bootstrap-window"; + ATOM wndatom = RegisterClassExW(&wndclass); + bootstrap_hwnd = CreateWindowExW(0, L"bootstrap-window", L"", 0, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + 0, 0, wndclass.hInstance, 0); + } + + //- rjf: grab dc + HDC dc = GetDC(bootstrap_hwnd); + + //- rjf: build pixel format descriptor + int pf = 0; + { + PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)}; + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + pfd.iLayerType = PFD_MAIN_PLANE; + pf = ChoosePixelFormat(dc, &pfd); + BOOL describe = DescribePixelFormat(dc, pf, sizeof(pfd), &pfd); + BOOL set_pf = SetPixelFormat(dc, pf, &pfd); + } + + //- rjf: make bootstrap ctx + make current + HGLRC bootstrap_ctx = wglCreateContext(dc); + wglMakeCurrent(dc, bootstrap_ctx); + + //- rjf: load modern extensions + wglChoosePixelFormatARB = (FNWGLCHOOSEPIXELFORMATARBPROC*) r_ogl_os_load_procedure("wglChoosePixelFormatARB"); + wglCreateContextAttribsARB = (FNWGLCREATECONTEXTATTRIBSARBPROC*)r_ogl_os_load_procedure("wglCreateContextAttribsARB"); + wglSwapIntervalEXT = (FNWGLSWAPINTERVALEXTPROC*) r_ogl_os_load_procedure("wglSwapIntervalEXT"); + + //- rjf: set up real pixel format + { + int pf_attribs_i[] = + { + WGL_DRAW_TO_WINDOW_ARB, 1, + WGL_SUPPORT_OPENGL_ARB, 1, + WGL_DOUBLE_BUFFER_ARB, 1, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_COLOR_BITS_ARB, 32, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + 0 + }; + UINT num_formats = 0; + wglChoosePixelFormatARB(dc, pf_attribs_i, 0, 1, &pf, &num_formats); + } + + //- rjf: make real gl ctx + HGLRC real_ctx = 0; + if(pf) + { + const int context_attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + 0 + }; + real_ctx = wglCreateContextAttribsARB(dc, bootstrap_ctx, context_attribs); + r_ogl_w32_hglrc = real_ctx; + } + + //- rjf: clean up bootstrap context + wglMakeCurrent(dc, 0); + wglDeleteContext(bootstrap_ctx); + wglMakeCurrent(dc, real_ctx); + wglSwapIntervalEXT(1); + ReleaseDC(bootstrap_hwnd, dc); + DestroyWindow(bootstrap_hwnd); +} + +internal R_Handle +r_ogl_os_window_equip(OS_Handle window) +{ + //- rjf: unpack window + OS_W32_Window *w = os_w32_window_from_handle(window); + HWND hwnd = w->hwnd; + HDC hdc = GetDC(hwnd); + + //- rjf: select in ctx + wglMakeCurrent(hdc, r_ogl_w32_hglrc); + + //- rjf: setup real pixel format + int pixel_format = 0; + UINT num_formats = 0; + int pf_attribs_i[] = + { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_COLOR_BITS_ARB, 32, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + 0 + }; + wglChoosePixelFormatARB(hdc, + pf_attribs_i, + 0, + 1, + &pixel_format, + &num_formats); + + // NOTE(rjf): This doesn't seem to be necessary for SetPixelFormat, we can + // just pass 0 for it, and SetPixelFormat needs to be called here, but the + // docs don't seem to suggest that 0 is an acceptable value, so I am just + // filling this out with the same attribs as that for the wgl function, + // and passing it. + PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd)}; + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + pfd.iLayerType = PFD_MAIN_PLANE; + + //- rjf: set pixel format + SetPixelFormat(hdc, pixel_format, &pfd); + + //- rjf: release hdc + ReleaseDC(hwnd, hdc); + R_Handle result = {0}; + return result; +} + +internal void +r_ogl_os_window_unequip(OS_Handle os, R_Handle r) +{ +} + +internal void +r_ogl_os_select_window(OS_Handle os, R_Handle r) +{ + OS_W32_Window *w = os_w32_window_from_handle(os); + if(w != 0) + { + HWND hwnd = w->hwnd; + HDC hdc = GetDC(hwnd); + wglMakeCurrent(hdc, r_ogl_w32_hglrc); + ReleaseDC(hwnd, hdc); + } +} + +internal void +r_ogl_os_window_swap(OS_Handle os, R_Handle r) +{ + OS_W32_Window *w = os_w32_window_from_handle(os); + if(w != 0) + { + HDC dc = GetDC(w->hwnd); + SwapBuffers(dc); + ReleaseDC(w->hwnd, dc); + } +} diff --git a/src/render/opengl/win32/render_opengl_win32.h b/src/render/opengl/win32/render_opengl_win32.h new file mode 100644 index 00000000..24e53c14 --- /dev/null +++ b/src/render/opengl/win32/render_opengl_win32.h @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_WIN32_H +#define RENDER_OPENGL_WIN32_H + +#include +#pragma comment(lib, "opengl32") + +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 + +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 + +typedef BOOL WINAPI FNWGLCHOOSEPIXELFORMATARBPROC(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef HGLRC WINAPI FNWGLCREATECONTEXTATTRIBSARBPROC(HDC hDC, HGLRC hShareContext, const int *attribList); +typedef BOOL WINAPI FNWGLSWAPINTERVALEXTPROC(int interval); + +FNWGLCHOOSEPIXELFORMATARBPROC *wglChoosePixelFormatARB; +FNWGLCREATECONTEXTATTRIBSARBPROC *wglCreateContextAttribsARB; +FNWGLSWAPINTERVALEXTPROC *wglSwapIntervalEXT; + +global HGLRC r_ogl_w32_hglrc = 0; + +#endif // RENDER_OPENGL_WIN32_H diff --git a/src/render/render_core.c b/src/render/render_core.c index 4d6ebdf7..80ca84bf 100644 --- a/src/render/render_core.c +++ b/src/render/render_core.c @@ -6,6 +6,33 @@ #include "generated/render.meta.c" +//////////////////////////////// +//~ rjf: Helpers + +internal Mat4x4F32 +r_sample_channel_map_from_tex2dformat(R_Tex2DFormat fmt) +{ + Mat4x4F32 result = + { + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + } + }; + switch(fmt) + { + default:{}break; + case R_Tex2DFormat_R8: + { + MemoryZeroArray(result.v[0]); + result.v[0][0] = result.v[0][1] = result.v[0][2] = result.v[0][3] = 1.f; + }break; + } + return result; +} + //////////////////////////////// //~ rjf: Basic Type Functions diff --git a/src/render/render_core.h b/src/render/render_core.h index a7ef99c9..7725c5a3 100644 --- a/src/render/render_core.h +++ b/src/render/render_core.h @@ -194,6 +194,11 @@ struct R_PassList U64 count; }; +//////////////////////////////// +//~ rjf: Helpers + +internal Mat4x4F32 r_sample_channel_map_from_tex2dformat(R_Tex2DFormat fmt); + //////////////////////////////// //~ rjf: Handle Type Functions diff --git a/src/render/render_inc.c b/src/render/render_inc.c index 52e5c365..bb15be84 100644 --- a/src/render/render_inc.c +++ b/src/render/render_inc.c @@ -10,6 +10,8 @@ # include "stub/render_stub.c" #elif R_BACKEND == R_BACKEND_D3D11 # include "d3d11/render_d3d11.c" +#elif R_BACKEND == R_BACKEND_OPENGL +# include "opengl/render_opengl.c" #else # error Renderer backend not specified. #endif diff --git a/src/render/render_inc.h b/src/render/render_inc.h index 64802e5c..d0e87c3c 100644 --- a/src/render/render_inc.h +++ b/src/render/render_inc.h @@ -9,12 +9,15 @@ #define R_BACKEND_STUB 0 #define R_BACKEND_D3D11 1 +#define R_BACKEND_OPENGL 2 //////////////////////////////// //~ rjf: Decide On Backend #if !defined(R_BACKEND) && OS_WINDOWS # define R_BACKEND R_BACKEND_D3D11 +#elif !defined(R_BACKEND) && OS_LINUX +# define R_BACKEND R_BACKEND_OPENGL #endif //////////////////////////////// @@ -29,6 +32,8 @@ # include "stub/render_stub.h" #elif R_BACKEND == R_BACKEND_D3D11 # include "d3d11/render_d3d11.h" +#elif R_BACKEND == R_BACKEND_OPENGL +# include "opengl/render_opengl.h" #else # error Renderer backend not specified. #endif From 5939c3f010eafa344d772b2d8879234b68c58e71 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 19:51:24 -0700 Subject: [PATCH 659/755] switch 4coder back to defaultly building with d3d11 backend --- project.4coder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.4coder b/project.4coder index 3e46160f..6b22acea 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: [raddbg] - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry opengl", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, From a1318e6117e95e92cb2c5af7eafb9052b22427e3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 9 May 2025 21:51:48 -0700 Subject: [PATCH 660/755] sketch out first bit of linux-backend of opengl-backend --- build.sh | 3 +- project.4coder | 8 +- src/render/opengl/linux/render_opengl_linux.c | 110 ++++++++++++++++++ src/render/opengl/linux/render_opengl_linux.h | 25 ++++ src/render/opengl/render_opengl.c | 22 +++- src/render/opengl/render_opengl.h | 2 + src/render/opengl/win32/render_opengl_win32.c | 8 +- src/scratch/ryan_scratch.c | 46 ++++++-- 8 files changed, 205 insertions(+), 19 deletions(-) create mode 100644 src/render/opengl/linux/render_opengl_linux.c create mode 100644 src/render/opengl/linux/render_opengl_linux.h diff --git a/build.sh b/build.sh index 03bde82c..ae301d3f 100644 --- a/build.sh +++ b/build.sh @@ -33,6 +33,7 @@ gcc_out="-o" # --- Per-Build Settings ------------------------------------------------------ link_dll="-fPIC" link_os_gfx="-lX11 -lXext" +link_render="-lGL" # --- Choose Compile/Link Lines ----------------------------------------------- if [ -v gcc ]; then compile_debug="$gcc_debug"; fi @@ -68,7 +69,7 @@ if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi if [ -v rdi_dump ]; then didbuild=1 && $compile ../src/rdi_dump/rdi_dump_main.c $compile_link $out rdi_dump; fi if [ -v rdi_breakpad_from_pdb ]; then didbuild=1 && $compile ../src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c $compile_link $out rdi_breakpad_from_pdb; fi -if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $out ryan_scratch; fi +if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $link_render $out ryan_scratch; fi cd .. # --- Warn On No Builds ------------------------------------------------------- diff --git a/project.4coder b/project.4coder index 6b22acea..dd21c25b 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: [raddbg] - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, @@ -54,9 +54,13 @@ commands = //- rjf: [tester] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: [ryan_scratch] + .f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + //- rjf: running target - .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "wsl /mnt/c/devel/raddebugger/build/ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/render/opengl/linux/render_opengl_linux.c b/src/render/opengl/linux/render_opengl_linux.c new file mode 100644 index 00000000..0214b97a --- /dev/null +++ b/src/render/opengl/linux/render_opengl_linux.c @@ -0,0 +1,110 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal VoidProc * +r_ogl_os_load_procedure(char *name) +{ + VoidProc *result = (VoidProc *)glXGetProcAddressARB((U8 *)name); + return result; +} + +internal void +r_ogl_os_init(CmdLine *cmdln) +{ + //- rjf: require GLX 1.3+ + int glx_version_major = 0; + int glx_version_minor = 0; + if(!glXQueryVersion(os_lnx_gfx_state->display, &glx_version_major, &glx_version_minor) || + (glx_version_major == 1 && glx_version_minor < 3) || + glx_version_major < 1) + { + Temp scratch = scratch_begin(0, 0); + String8 message = push_str8f(scratch.arena, "Unsupported GLX version (%i.%i, need at least 1.3)", glx_version_major, glx_version_minor); + os_graphical_message(1, str8_lit("Fatal Error"), message); + os_abort(1); + scratch_end(scratch); + } + + //- rjf: get frame buffer configs + local_persist int framebuffer_config_options[] = + { + GLX_X_RENDERABLE, 1, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + GLX_DOUBLEBUFFER, 1, + None + }; + int framebuffer_configs_count = 0; + GLXFBConfig *framebuffer_configs = glXChooseFBConfig(os_lnx_gfx_state->display, DefaultScreen(os_lnx_gfx_state->display), framebuffer_config_options, &framebuffer_configs_count); + if(framebuffer_configs == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Could not find a suitable framebuffer configuration.")); + os_abort(1); + } + GLXFBConfig framebuffer_config = framebuffer_configs[0]; + XFree(framebuffer_configs); + + //- rjf: get visual info; create color map + XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config); + Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone); + + //- rjf: construct set-window-attributes + XSetWindowAttributes set_window_attributes = {0}; + set_window_attributes.background_pixmap = None; + set_window_attributes.border_pixel = 0; + set_window_attributes.event_mask = StructureNotifyMask; + + //- rjf: construct context + { + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((U8 *)"glXCreateContextAttribsARB"); + int context_options[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_FLAGS_ARB, !!debug_mode*GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; + r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); + } + + glXMakeCurrent(os_lnx_gfx_state->display, None, r_ogl_lnx_ctx); +} + +internal R_Handle +r_ogl_os_window_equip(OS_Handle window) +{ + R_Handle result = {0}; + return result; +} + +internal void +r_ogl_os_window_unequip(OS_Handle os, R_Handle r) +{ + +} + +internal void +r_ogl_os_select_window(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx); +} + +internal void +r_ogl_os_window_swap(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXSwapBuffers(os_lnx_gfx_state->display, w->window); +} diff --git a/src/render/opengl/linux/render_opengl_linux.h b/src/render/opengl/linux/render_opengl_linux.h new file mode 100644 index 00000000..f70f40a5 --- /dev/null +++ b/src/render/opengl/linux/render_opengl_linux.h @@ -0,0 +1,25 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_LINUX_H +#define RENDER_OPENGL_LINUX_H + +#define glTexImage3D glTexImage3D__static +#define glTexSubImage3D glTexSubImage3D__static +#define glActiveTexture glActiveTexture__static +#include +#include +#undef glTexImage3D +#undef glTexSubImage3D +#undef glActiveTexture + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +global GLXContext r_ogl_lnx_ctx = 0; + +#endif // RENDER_OPENGL_LINUX_H diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index cfbec7de..60266ce0 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -6,6 +6,8 @@ #if OS_WINDOWS # include "render/opengl/win32/render_opengl_win32.c" +#elif OS_LINUX +# include "render/opengl/linux/render_opengl_linux.c" #else # error OS portion of OpenGL rendering backend not defined. #endif @@ -67,6 +69,7 @@ internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { raddbg_log("[OpenGL] %.*s\n", (int)length, message); + fprintf(stderr, "[OpenGL] %.*s\n", (int)length, message); } //////////////////////////////// @@ -103,7 +106,7 @@ r_init(CmdLine *cmdln) { stages[idx].out = glCreateShader(stages[idx].type); GLint src_size = stages[idx].src->size; - glShaderSource(stages[idx].out, 1, &stages[idx].src->str, &src_size); + glShaderSource(stages[idx].out, 1, (char **)&stages[idx].src->str, &src_size); glCompileShader(stages[idx].out); GLint info_log_length = 0; GLint status = 0; @@ -113,7 +116,7 @@ r_init(CmdLine *cmdln) { stages[idx].errors.str = push_array(r_ogl_state->arena, U8, info_log_length+1); stages[idx].errors.size = info_log_length; - glGetShaderInfoLog(stages[idx].out, info_log_length, 0, stages[idx].errors.str); + glGetShaderInfoLog(stages[idx].out, info_log_length, 0, (char *)stages[idx].errors.str); } raddbg_pin(text(stages[idx].errors.str)); } @@ -129,14 +132,14 @@ r_init(CmdLine *cmdln) R_OGL_AttributeArray inputs = r_ogl_shader_kind_input_attributes_table[k]; for EachIndex(idx, inputs.count) { - glBindAttribLocation(program, inputs.v[idx].index, inputs.v[idx].name.str); + glBindAttribLocation(program, inputs.v[idx].index, (char *)inputs.v[idx].name.str); } // rjf: bind outputs R_OGL_AttributeArray outputs = r_ogl_shader_kind_output_attributes_table[k]; for EachIndex(idx, outputs.count) { - glBindFragDataLocation(program, outputs.v[idx].index, outputs.v[idx].name.str); + glBindFragDataLocation(program, outputs.v[idx].index, (char *)outputs.v[idx].name.str); } // rjf: link / validate / store @@ -158,8 +161,15 @@ r_init(CmdLine *cmdln) glEnable(GL_FRAMEBUFFER_SRGB); //- rjf: set up debug callback - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(r_ogl_debug_message_callback, 0); + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + if(debug_mode) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(r_ogl_debug_message_callback, 0); + } } //- rjf: window setup/teardown diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index 39ee5b5d..8f020c5e 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -9,6 +9,8 @@ #if OS_WINDOWS # include "render/opengl/win32/render_opengl_win32.h" +#elif OS_LINUX +# include "render/opengl/linux/render_opengl_linux.h" #else # error OS portion of OpenGL rendering backend not defined. #endif diff --git a/src/render/opengl/win32/render_opengl_win32.c b/src/render/opengl/win32/render_opengl_win32.c index 7b40d711..7e08edb0 100644 --- a/src/render/opengl/win32/render_opengl_win32.c +++ b/src/render/opengl/win32/render_opengl_win32.c @@ -78,11 +78,15 @@ r_ogl_os_init(CmdLine *cmdline) HGLRC real_ctx = 0; if(pf) { - const int context_attribs[] = + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + int context_attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, !!debug_mode*WGL_CONTEXT_DEBUG_BIT_ARB, 0 }; real_ctx = wglCreateContextAttribsARB(dc, bootstrap_ctx, context_attribs); diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index 8f1a564b..aa195640 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -10,19 +10,21 @@ //////////////////////////////// //~ rjf: Includes -//- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format.c" -#include "third_party/rad_lzb_simple/rad_lzb_simple.h" -#include "third_party/rad_lzb_simple/rad_lzb_simple.c" - //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" +#include "render/render_inc.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" +#include "render/render_inc.c" + +//////////////////////////////// +//~ rjf: Globals + +global OS_Handle window_os = {0}; +global R_Handle window_r = {0}; //////////////////////////////// //~ rjf: Entry Points @@ -32,6 +34,8 @@ frame(void) { B32 quit = 0; Temp scratch = scratch_begin(0, 0); + + //- rjf: events test OS_EventList events = os_get_events(scratch.arena, 0); for(OS_Event *ev = events.first; ev != 0; ev = ev->next) { @@ -55,6 +59,31 @@ frame(void) break; } } + + //- rjf: drawing test + r_begin_frame(); + r_window_begin_frame(window_os, window_r); + { + R_PassList passes = {0}; + R_Pass *pass = r_pass_from_kind(scratch.arena, &passes, R_PassKind_UI); + R_PassParams_UI *pass_ui = pass->params_ui; + R_BatchGroup2DNode group = {0}; + pass_ui->rects.first = pass_ui->rects.last = &group; + pass_ui->rects.count = 1; + group.batches = r_batch_list_make(sizeof(R_Rect2DInst)); + group.params.xform = mat_3x3f32(1.f); + group.params.clip = os_client_rect_from_window(window_os); + R_Rect2DInst *inst = r_batch_list_push_inst(scratch.arena, &group.batches, 256); + MemoryZeroStruct(inst); + inst->dst = r2f32p(30, 30, 100 ,100); + inst->src = r2f32p(0, 0, 1, 1); + inst->colors[Corner_00] = inst->colors[Corner_01] = inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(1, 0, 0, 1); + inst->corner_radii[Corner_00] = inst->corner_radii[Corner_01] = inst->corner_radii[Corner_10] = inst->corner_radii[Corner_11] = 8.f; + r_window_submit(window_os, window_r, &passes); + } + r_window_end_frame(window_os, window_r); + r_end_frame(); + scratch_end(scratch); return quit; } @@ -62,7 +91,8 @@ frame(void) internal void entry_point(CmdLine *cmdline) { - OS_Handle window = os_window_open(r2f32p(0, 0, 1280, 720), OS_WindowFlag_UseDefaultPosition, str8_lit("Window")); - os_window_first_paint(window); + window_os = os_window_open(r2f32p(0, 0, 1280, 720), OS_WindowFlag_UseDefaultPosition, str8_lit("Window")); + os_window_first_paint(window_os); + window_r = r_window_equip(window_os); for(;!update();); } From ab5c47a0fdb8480181e2735609b22c2cef68c2a5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 08:36:13 -0700 Subject: [PATCH 661/755] fix opengl win32 build --- src/render/opengl/linux/render_opengl_linux.c | 2 +- src/render/opengl/win32/render_opengl_win32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/opengl/linux/render_opengl_linux.c b/src/render/opengl/linux/render_opengl_linux.c index 0214b97a..66403bc3 100644 --- a/src/render/opengl/linux/render_opengl_linux.c +++ b/src/render/opengl/linux/render_opengl_linux.c @@ -79,7 +79,7 @@ r_ogl_os_init(CmdLine *cmdln) r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); } - glXMakeCurrent(os_lnx_gfx_state->display, None, r_ogl_lnx_ctx); + glXMakeCurrent(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), r_ogl_lnx_ctx); } internal R_Handle diff --git a/src/render/opengl/win32/render_opengl_win32.c b/src/render/opengl/win32/render_opengl_win32.c index 7e08edb0..48944a80 100644 --- a/src/render/opengl/win32/render_opengl_win32.c +++ b/src/render/opengl/win32/render_opengl_win32.c @@ -78,7 +78,7 @@ r_ogl_os_init(CmdLine *cmdline) HGLRC real_ctx = 0; if(pf) { - B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); + B32 debug_mode = cmd_line_has_flag(cmdline, str8_lit("opengl_debug")); #if BUILD_DEBUG debug_mode = 1; #endif From b9350c867c654337a8fbcf164e552d5be65b129a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 11:04:59 -0700 Subject: [PATCH 662/755] egl backend for linux backend of opengl backend of render --- build.sh | 2 +- project.4coder | 2 +- src/os/gfx/linux/os_gfx_linux.c | 7 +- .../linux/egl/render_opengl_linux_egl.c | 160 ++++++++++++++++++ .../linux/egl/render_opengl_linux_egl.h | 35 ++++ .../linux/glx/render_opengl_linux_glx.c | 110 ++++++++++++ .../linux/glx/render_opengl_linux_glx.h | 25 +++ src/render/opengl/linux/render_opengl_linux.c | 113 +------------ src/render/opengl/linux/render_opengl_linux.h | 36 ++-- src/render/opengl/render_opengl.h | 70 ++++---- 10 files changed, 402 insertions(+), 158 deletions(-) create mode 100644 src/render/opengl/linux/egl/render_opengl_linux_egl.c create mode 100644 src/render/opengl/linux/egl/render_opengl_linux_egl.h create mode 100644 src/render/opengl/linux/glx/render_opengl_linux_glx.c create mode 100644 src/render/opengl/linux/glx/render_opengl_linux_glx.h diff --git a/build.sh b/build.sh index ae301d3f..f5559620 100644 --- a/build.sh +++ b/build.sh @@ -33,7 +33,7 @@ gcc_out="-o" # --- Per-Build Settings ------------------------------------------------------ link_dll="-fPIC" link_os_gfx="-lX11 -lXext" -link_render="-lGL" +link_render="-lGL -lEGL" # --- Choose Compile/Link Lines ----------------------------------------------- if [ -v gcc ]; then compile_debug="$gcc_debug"; fi diff --git a/project.4coder b/project.4coder index dd21c25b..bc86d180 100644 --- a/project.4coder +++ b/project.4coder @@ -60,7 +60,7 @@ commands = //- rjf: running target // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "wsl /mnt/c/devel/raddebugger/build/ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index ad9c15df..0d5d6151 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -497,7 +497,12 @@ os_set_cursor(OS_Cursor cursor) internal void os_graphical_message(B32 error, String8 title, String8 message) { - + if(error) + { + fprintf(stderr, "[X] "); + } + fprintf(stderr, "%.*s\n", str8_varg(title)); + fprintf(stderr, "%.*s\n\n", str8_varg(message)); } //////////////////////////////// diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.c b/src/render/opengl/linux/egl/render_opengl_linux_egl.c new file mode 100644 index 00000000..dc34a3b0 --- /dev/null +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.c @@ -0,0 +1,160 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal VoidProc * +r_ogl_os_load_procedure(char *name) +{ + VoidProc *result = (VoidProc *)eglGetProcAddress(name); + return result; +} + +internal void +r_ogl_os_init(CmdLine *cmdln) +{ + //- rjf: set up state + { + Arena *arena = arena_alloc(); + r_ogl_lnx_state = push_array(arena, R_OGL_LNX_State, 1); + r_ogl_lnx_state->arena = arena; + } + + //- rjf: get EGL display + { + r_ogl_lnx_state->display = eglGetDisplay((EGLNativeDisplayType)os_lnx_gfx_state->display); + if(r_ogl_lnx_state->display == EGL_NO_DISPLAY) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Failed to get EGL display.")); + os_abort(1); + } + } + + //- rjf: initialize GL version + EGLint egl_version_major = 0; + EGLint egl_version_minor = 0; + if(!eglInitialize(r_ogl_lnx_state->display, &egl_version_major, &egl_version_minor)) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't initialize EGL display.")); + os_abort(1); + } + if(egl_version_major < 1 || (egl_version_major == 1 && egl_version_minor < 5)) + { + Temp scratch = scratch_begin(0, 0); + String8 message = push_str8f(scratch.arena, "Unsupported EGL version (%i.%i, need at least 1.5)", egl_version_major, egl_version_minor); + os_graphical_message(1, str8_lit("Fatal Error"), message); + os_abort(1); + scratch_end(scratch); + } + + //- rjf: pick GL API + if(!eglBindAPI(EGL_OPENGL_API)) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't initialize EGL API to OpenGL.")); + os_abort(1); + } + + //- rjf: set up EGL config + { + EGLint options[] = + { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_CONFORMANT, EGL_OPENGL_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, + + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + + EGL_NONE, + }; + EGLint config_count = 0; + if(!eglChooseConfig(r_ogl_lnx_state->display, options, &r_ogl_lnx_state->config, 1, &config_count) || config_count != 1) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); + os_abort(1); + } + } + + //- rjf: construct context + { + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + EGLint options[] = + { + EGL_CONTEXT_MAJOR_VERSION, 3, + EGL_CONTEXT_MINOR_VERSION, 3, + EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + debug_mode ? EGL_CONTEXT_OPENGL_DEBUG : EGL_NONE, EGL_TRUE, + EGL_NONE, + }; + r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, r_ogl_lnx_state->config, EGL_NO_CONTEXT, options); + if(r_ogl_lnx_state->context == EGL_NO_CONTEXT) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create OpenGL context with EGL.")); + os_abort(1); + } + } + + eglMakeCurrent(r_ogl_lnx_state->display, 0, 0, r_ogl_lnx_state->context); +} + +internal R_Handle +r_ogl_os_window_equip(OS_Handle window) +{ + OS_LNX_Window *window_os = (OS_LNX_Window *)window.u64[0]; + R_OGL_LNX_Window *w = r_ogl_lnx_state->free_window; + if(w != 0) + { + SLLStackPop(r_ogl_lnx_state->free_window); + } + else + { + w = push_array(r_ogl_lnx_state->arena, R_OGL_LNX_Window, 1); + } + { + EGLint options[] = + { + EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR, + EGL_RENDER_BUFFER, EGL_BACK_BUFFER, + EGL_NONE, + }; + w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, options); + if(w->surface == EGL_NO_SURFACE) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create EGL surface.")); + os_abort(1); + } + } + R_Handle result = {(U64)w}; + return result; +} + +internal void +r_ogl_os_window_unequip(OS_Handle os, R_Handle r) +{ + R_OGL_LNX_Window *w = (R_OGL_LNX_Window *)r.u64[0]; + { + + } + SLLStackPush(r_ogl_lnx_state->free_window, w); +} + +internal void +r_ogl_os_select_window(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0]; + eglMakeCurrent(r_ogl_lnx_state->display, w_r->surface, w_r->surface, r_ogl_lnx_state->context); +} + +internal void +r_ogl_os_window_swap(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0]; + eglSwapBuffers(r_ogl_lnx_state->display, w_r->surface); +} diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.h b/src/render/opengl/linux/egl/render_opengl_linux_egl.h new file mode 100644 index 00000000..54a419d1 --- /dev/null +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.h @@ -0,0 +1,35 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_LINUX_EGL_H +#define RENDER_OPENGL_LINUX_EGL_H + +#define glTexImage3D glTexImage3D__static +#define glTexSubImage3D glTexSubImage3D__static +#define glActiveTexture glActiveTexture__static +#include +#include +#undef glTexImage3D +#undef glTexSubImage3D +#undef glActiveTexture + +typedef struct R_OGL_LNX_Window R_OGL_LNX_Window; +struct R_OGL_LNX_Window +{ + R_OGL_LNX_Window *next; + EGLSurface *surface; +}; + +typedef struct R_OGL_LNX_State R_OGL_LNX_State; +struct R_OGL_LNX_State +{ + Arena *arena; + EGLDisplay *display; + EGLConfig config; + EGLContext *context; + R_OGL_LNX_Window *free_window; +}; + +global R_OGL_LNX_State *r_ogl_lnx_state = 0; + +#endif // RENDER_OPENGL_LINUX_EGL_H diff --git a/src/render/opengl/linux/glx/render_opengl_linux_glx.c b/src/render/opengl/linux/glx/render_opengl_linux_glx.c new file mode 100644 index 00000000..66403bc3 --- /dev/null +++ b/src/render/opengl/linux/glx/render_opengl_linux_glx.c @@ -0,0 +1,110 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal VoidProc * +r_ogl_os_load_procedure(char *name) +{ + VoidProc *result = (VoidProc *)glXGetProcAddressARB((U8 *)name); + return result; +} + +internal void +r_ogl_os_init(CmdLine *cmdln) +{ + //- rjf: require GLX 1.3+ + int glx_version_major = 0; + int glx_version_minor = 0; + if(!glXQueryVersion(os_lnx_gfx_state->display, &glx_version_major, &glx_version_minor) || + (glx_version_major == 1 && glx_version_minor < 3) || + glx_version_major < 1) + { + Temp scratch = scratch_begin(0, 0); + String8 message = push_str8f(scratch.arena, "Unsupported GLX version (%i.%i, need at least 1.3)", glx_version_major, glx_version_minor); + os_graphical_message(1, str8_lit("Fatal Error"), message); + os_abort(1); + scratch_end(scratch); + } + + //- rjf: get frame buffer configs + local_persist int framebuffer_config_options[] = + { + GLX_X_RENDERABLE, 1, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + GLX_DOUBLEBUFFER, 1, + None + }; + int framebuffer_configs_count = 0; + GLXFBConfig *framebuffer_configs = glXChooseFBConfig(os_lnx_gfx_state->display, DefaultScreen(os_lnx_gfx_state->display), framebuffer_config_options, &framebuffer_configs_count); + if(framebuffer_configs == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Could not find a suitable framebuffer configuration.")); + os_abort(1); + } + GLXFBConfig framebuffer_config = framebuffer_configs[0]; + XFree(framebuffer_configs); + + //- rjf: get visual info; create color map + XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config); + Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone); + + //- rjf: construct set-window-attributes + XSetWindowAttributes set_window_attributes = {0}; + set_window_attributes.background_pixmap = None; + set_window_attributes.border_pixel = 0; + set_window_attributes.event_mask = StructureNotifyMask; + + //- rjf: construct context + { + B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); +#if BUILD_DEBUG + debug_mode = 1; +#endif + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((U8 *)"glXCreateContextAttribsARB"); + int context_options[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_FLAGS_ARB, !!debug_mode*GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; + r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); + } + + glXMakeCurrent(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), r_ogl_lnx_ctx); +} + +internal R_Handle +r_ogl_os_window_equip(OS_Handle window) +{ + R_Handle result = {0}; + return result; +} + +internal void +r_ogl_os_window_unequip(OS_Handle os, R_Handle r) +{ + +} + +internal void +r_ogl_os_select_window(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx); +} + +internal void +r_ogl_os_window_swap(OS_Handle os, R_Handle r) +{ + OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; + glXSwapBuffers(os_lnx_gfx_state->display, w->window); +} diff --git a/src/render/opengl/linux/glx/render_opengl_linux_glx.h b/src/render/opengl/linux/glx/render_opengl_linux_glx.h new file mode 100644 index 00000000..995172b0 --- /dev/null +++ b/src/render/opengl/linux/glx/render_opengl_linux_glx.h @@ -0,0 +1,25 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RENDER_OPENGL_LINUX_GLX_H +#define RENDER_OPENGL_LINUX_GLX_H + +#define glTexImage3D glTexImage3D__static +#define glTexSubImage3D glTexSubImage3D__static +#define glActiveTexture glActiveTexture__static +#include +#include +#undef glTexImage3D +#undef glTexSubImage3D +#undef glActiveTexture + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +global GLXContext r_ogl_lnx_ctx = 0; + +#endif // RENDER_OPENGL_LINUX_GLX_H diff --git a/src/render/opengl/linux/render_opengl_linux.c b/src/render/opengl/linux/render_opengl_linux.c index 66403bc3..4e0e2964 100644 --- a/src/render/opengl/linux/render_opengl_linux.c +++ b/src/render/opengl/linux/render_opengl_linux.c @@ -1,110 +1,13 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal VoidProc * -r_ogl_os_load_procedure(char *name) -{ - VoidProc *result = (VoidProc *)glXGetProcAddressARB((U8 *)name); - return result; -} +//////////////////////////////// +//~ rjf: Backend Includes -internal void -r_ogl_os_init(CmdLine *cmdln) -{ - //- rjf: require GLX 1.3+ - int glx_version_major = 0; - int glx_version_minor = 0; - if(!glXQueryVersion(os_lnx_gfx_state->display, &glx_version_major, &glx_version_minor) || - (glx_version_major == 1 && glx_version_minor < 3) || - glx_version_major < 1) - { - Temp scratch = scratch_begin(0, 0); - String8 message = push_str8f(scratch.arena, "Unsupported GLX version (%i.%i, need at least 1.3)", glx_version_major, glx_version_minor); - os_graphical_message(1, str8_lit("Fatal Error"), message); - os_abort(1); - scratch_end(scratch); - } - - //- rjf: get frame buffer configs - local_persist int framebuffer_config_options[] = - { - GLX_X_RENDERABLE, 1, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_DOUBLEBUFFER, 1, - None - }; - int framebuffer_configs_count = 0; - GLXFBConfig *framebuffer_configs = glXChooseFBConfig(os_lnx_gfx_state->display, DefaultScreen(os_lnx_gfx_state->display), framebuffer_config_options, &framebuffer_configs_count); - if(framebuffer_configs == 0) - { - os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Could not find a suitable framebuffer configuration.")); - os_abort(1); - } - GLXFBConfig framebuffer_config = framebuffer_configs[0]; - XFree(framebuffer_configs); - - //- rjf: get visual info; create color map - XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config); - Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone); - - //- rjf: construct set-window-attributes - XSetWindowAttributes set_window_attributes = {0}; - set_window_attributes.background_pixmap = None; - set_window_attributes.border_pixel = 0; - set_window_attributes.event_mask = StructureNotifyMask; - - //- rjf: construct context - { - B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); -#if BUILD_DEBUG - debug_mode = 1; +#if R_OPENGL_LINUX_BACKEND == R_OPENGL_LINUX_BACKEND_GLX +# include "glx/render_opengl_linux_glx.c" +#elif R_OPENGL_LINUX_BACKEND == R_OPENGL_LINUX_BACKEND_EGL +# include "egl/render_opengl_linux_egl.c" +#else +# error Linux OpenGL backend not specified. #endif - glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; - glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((U8 *)"glXCreateContextAttribsARB"); - int context_options[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 3, - GLX_CONTEXT_FLAGS_ARB, !!debug_mode*GLX_CONTEXT_DEBUG_BIT_ARB, - None - }; - r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); - } - - glXMakeCurrent(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), r_ogl_lnx_ctx); -} - -internal R_Handle -r_ogl_os_window_equip(OS_Handle window) -{ - R_Handle result = {0}; - return result; -} - -internal void -r_ogl_os_window_unequip(OS_Handle os, R_Handle r) -{ - -} - -internal void -r_ogl_os_select_window(OS_Handle os, R_Handle r) -{ - OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; - glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx); -} - -internal void -r_ogl_os_window_swap(OS_Handle os, R_Handle r) -{ - OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0]; - glXSwapBuffers(os_lnx_gfx_state->display, w->window); -} diff --git a/src/render/opengl/linux/render_opengl_linux.h b/src/render/opengl/linux/render_opengl_linux.h index f70f40a5..8fcbd629 100644 --- a/src/render/opengl/linux/render_opengl_linux.h +++ b/src/render/opengl/linux/render_opengl_linux.h @@ -4,22 +4,28 @@ #ifndef RENDER_OPENGL_LINUX_H #define RENDER_OPENGL_LINUX_H -#define glTexImage3D glTexImage3D__static -#define glTexSubImage3D glTexSubImage3D__static -#define glActiveTexture glActiveTexture__static -#include -#include -#undef glTexImage3D -#undef glTexSubImage3D -#undef glActiveTexture +//////////////////////////////// +//~ rjf: Backend Constants -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define GLX_CONTEXT_FLAGS_ARB 0x2094 -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); +#define R_OPENGL_LINUX_BACKEND_GLX 0 +#define R_OPENGL_LINUX_BACKEND_EGL 1 -global GLXContext r_ogl_lnx_ctx = 0; +//////////////////////////////// +//~ rjf: Decide On Backend + +#if !defined(R_OPENGL_LINUX_BACKEND) +# define R_OPENGL_LINUX_BACKEND R_OPENGL_LINUX_BACKEND_GLX +#endif + +//////////////////////////////// +//~ rjf: Backend Includes + +#if R_OPENGL_LINUX_BACKEND == R_OPENGL_LINUX_BACKEND_GLX +# include "glx/render_opengl_linux_glx.h" +#elif R_OPENGL_LINUX_BACKEND == R_OPENGL_LINUX_BACKEND_EGL +# include "egl/render_opengl_linux_egl.h" +#else +# error Linux OpenGL backend not specified. +#endif #endif // RENDER_OPENGL_LINUX_H diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index 8f020c5e..dde24165 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -4,41 +4,6 @@ #ifndef RENDER_OPENGL_H #define RENDER_OPENGL_H -//////////////////////////////// -//~ rjf: OS Backend Includes - -#if OS_WINDOWS -# include "render/opengl/win32/render_opengl_win32.h" -#elif OS_LINUX -# include "render/opengl/linux/render_opengl_linux.h" -#else -# error OS portion of OpenGL rendering backend not defined. -#endif - -//////////////////////////////// -//~ rjf: Shader Metadata Types - -typedef struct R_OGL_Attribute R_OGL_Attribute; -struct R_OGL_Attribute -{ - U64 index; - String8 name; - GLenum type; - U64 count; -}; - -typedef struct R_OGL_AttributeArray R_OGL_AttributeArray; -struct R_OGL_AttributeArray -{ - R_OGL_Attribute *v; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Generated Code - -#include "render/opengl/generated/render_opengl.meta.h" - //////////////////////////////// //~ rjf: Defines @@ -107,6 +72,41 @@ typedef ptrdiff_t GLintptr; #define GL_DEBUG_OUTPUT 0x92E0 +//////////////////////////////// +//~ rjf: OS Backend Includes + +#if OS_WINDOWS +# include "render/opengl/win32/render_opengl_win32.h" +#elif OS_LINUX +# include "render/opengl/linux/render_opengl_linux.h" +#else +# error OS portion of OpenGL rendering backend not defined. +#endif + +//////////////////////////////// +//~ rjf: Shader Metadata Types + +typedef struct R_OGL_Attribute R_OGL_Attribute; +struct R_OGL_Attribute +{ + U64 index; + String8 name; + GLenum type; + U64 count; +}; + +typedef struct R_OGL_AttributeArray R_OGL_AttributeArray; +struct R_OGL_AttributeArray +{ + R_OGL_Attribute *v; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Generated Code + +#include "render/opengl/generated/render_opengl.meta.h" + //////////////////////////////// //~ rjf: OpenGL Procedure List From b52e3be5ae0984f25b40f8dc505547f597db97b7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 11:38:43 -0700 Subject: [PATCH 663/755] fill out more linux os layer coverage --- src/os/gfx/linux/os_gfx_linux.c | 74 ++++++++++++++++--- src/render/opengl/linux/render_opengl_linux.h | 2 +- src/scratch/ryan_scratch.c | 3 +- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 0d5d6151..189a7ad8 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -134,13 +134,19 @@ internal void os_window_close(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return;} + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + XDestroyWindow(os_lnx_gfx_state->display, w->window); } internal void os_window_set_title(OS_Handle handle, String8 title) { if(os_handle_match(handle, os_handle_zero())) {return;} - // TODO(rjf) + Temp scratch = scratch_begin(0, 0); + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + String8 title_copy = push_str8_copy(scratch.arena, title); + XStoreName(os_lnx_gfx_state->display, w->window, (char *)title_copy.str); + scratch_end(scratch); } internal void @@ -155,12 +161,15 @@ internal void os_window_focus(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return;} + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + XSetInputFocus(os_lnx_gfx_state->display, w->window, RevertToNone, CurrentTime); } internal B32 os_window_is_focused(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} + // TODO(rjf) return 0; } @@ -168,6 +177,7 @@ internal B32 os_window_is_fullscreen(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} + // TODO(rjf) return 0; } @@ -175,12 +185,14 @@ internal void os_window_set_fullscreen(OS_Handle handle, B32 fullscreen) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal B32 os_window_is_maximized(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} + // TODO(rjf) return 0; } @@ -188,12 +200,14 @@ internal void os_window_set_maximized(OS_Handle handle, B32 maximized) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal B32 os_window_is_minimized(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} + // TODO(rjf) return 0; } @@ -201,60 +215,77 @@ internal void os_window_set_minimized(OS_Handle handle, B32 minimized) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_bring_to_front(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_set_monitor(OS_Handle handle, OS_Handle monitor) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_clear_custom_border_data(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_push_custom_title_bar(OS_Handle handle, F32 thickness) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_push_custom_edges(OS_Handle handle, F32 thickness) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal void os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect) { if(os_handle_match(handle, os_handle_zero())) {return;} + // TODO(rjf) } internal Rng2F32 os_rect_from_window(OS_Handle handle) { - return r2f32p(0, 0, 0, 0); + if(os_handle_match(handle, os_handle_zero())) {return r2f32p(0, 0, 0, 0);} + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + XWindowAttributes atts = {0}; + Status s = XGetWindowAttributes(os_lnx_gfx_state->display, w->window, &atts); + Rng2F32 result = r2f32p((F32)atts.x, (F32)atts.y, (F32)atts.x + (F32)atts.width, (F32)atts.y + (F32)atts.height); + return result; } internal Rng2F32 os_client_rect_from_window(OS_Handle handle) { - return r2f32p(0, 0, 0, 0); + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + XWindowAttributes atts = {0}; + Status s = XGetWindowAttributes(os_lnx_gfx_state->display, w->window, &atts); + Rng2F32 result = r2f32p((F32)atts.x, (F32)atts.y, (F32)atts.x + (F32)atts.width, (F32)atts.y + (F32)atts.height); + return result; } internal F32 os_dpi_from_window(OS_Handle handle) { - return 0; + // TODO(rjf) + return 96.f; } //////////////////////////////// @@ -264,6 +295,7 @@ internal OS_HandleArray os_push_monitors_array(Arena *arena) { OS_HandleArray result = {0}; + // TODO(rjf) return result; } @@ -271,6 +303,7 @@ internal OS_Handle os_primary_monitor(void) { OS_Handle result = {0}; + // TODO(rjf) return result; } @@ -278,24 +311,28 @@ internal OS_Handle os_monitor_from_window(OS_Handle window) { OS_Handle result = {0}; + // TODO(rjf) return result; } internal String8 os_name_from_monitor(Arena *arena, OS_Handle monitor) { + // TODO(rjf) return str8_zero(); } internal Vec2F32 os_dim_from_monitor(OS_Handle monitor) { + // TODO(rjf) return v2f32(0, 0); } internal F32 os_dpi_from_monitor(OS_Handle monitor) { + // TODO(rjf) return 96.f; } @@ -305,7 +342,7 @@ os_dpi_from_monitor(OS_Handle monitor) internal void os_send_wakeup_event(void) { - + // TODO(rjf) } internal OS_EventList @@ -467,19 +504,38 @@ os_get_events(Arena *arena, B32 wait) internal OS_Modifiers os_get_modifiers(void) { + // TODO(rjf) return 0; } internal B32 os_key_is_down(OS_Key key) { + // TODO(rjf) return 0; } internal Vec2F32 os_mouse_from_window(OS_Handle handle) { - return v2f32(0, 0); + if(os_handle_match(handle, os_handle_zero())) {return v2f32(0, 0);} + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + Vec2F32 result = {0}; + { + Window root_window = 0; + Window child_window = 0; + int root_rel_x = 0; + int root_rel_y = 0; + int child_rel_x = 0; + int child_rel_y = 0; + unsigned int mask = 0; + if(XQueryPointer(os_lnx_gfx_state->display, w->window, &root_window, &child_window, &root_rel_x, &root_rel_y, &child_rel_x, &child_rel_y, &mask)) + { + result.x = child_rel_x; + result.y = child_rel_y; + } + } + return result; } //////////////////////////////// @@ -488,7 +544,7 @@ os_mouse_from_window(OS_Handle handle) internal void os_set_cursor(OS_Cursor cursor) { - + // TODO(rjf) } //////////////////////////////// @@ -511,11 +567,11 @@ os_graphical_message(B32 error, String8 title, String8 message) internal void os_show_in_filesystem_ui(String8 path) { - + // TODO(rjf) } internal void os_open_in_browser(String8 url) { - + // TODO(rjf) } diff --git a/src/render/opengl/linux/render_opengl_linux.h b/src/render/opengl/linux/render_opengl_linux.h index 8fcbd629..21069e8d 100644 --- a/src/render/opengl/linux/render_opengl_linux.h +++ b/src/render/opengl/linux/render_opengl_linux.h @@ -14,7 +14,7 @@ //~ rjf: Decide On Backend #if !defined(R_OPENGL_LINUX_BACKEND) -# define R_OPENGL_LINUX_BACKEND R_OPENGL_LINUX_BACKEND_GLX +# define R_OPENGL_LINUX_BACKEND R_OPENGL_LINUX_BACKEND_EGL #endif //////////////////////////////// diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index aa195640..f84f5b24 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -73,9 +73,10 @@ frame(void) group.batches = r_batch_list_make(sizeof(R_Rect2DInst)); group.params.xform = mat_3x3f32(1.f); group.params.clip = os_client_rect_from_window(window_os); + Vec2F32 mouse = os_mouse_from_window(window_os); R_Rect2DInst *inst = r_batch_list_push_inst(scratch.arena, &group.batches, 256); MemoryZeroStruct(inst); - inst->dst = r2f32p(30, 30, 100 ,100); + inst->dst = r2f32p(mouse.x+30, mouse.y+30, mouse.x+100, mouse.y+100); inst->src = r2f32p(0, 0, 1, 1); inst->colors[Corner_00] = inst->colors[Corner_01] = inst->colors[Corner_10] = inst->colors[Corner_11] = v4f32(1, 0, 0, 1); inst->corner_radii[Corner_00] = inst->corner_radii[Corner_01] = inst->corner_radii[Corner_10] = inst->corner_radii[Corner_11] = 8.f; From 3fd1f9d25585a905a25b5eec1b3b240d2d35ffec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 14:27:55 -0700 Subject: [PATCH 664/755] stub out demon/fontprovider so we can build debugger --- build.sh | 2 +- project.4coder | 4 +- src/base/base_log.h | 6 +-- src/ctrl/ctrl_core.c | 2 +- src/demon/linux/demon_core_linux.c | 21 ++++++++++ src/font_provider/font_provider_inc.c | 2 + .../freetype/font_provider_freetype.c | 42 +++++++++++++++++++ src/os/gfx/linux/os_gfx_linux.c | 2 +- src/raddbg/raddbg_core.c | 14 +++---- src/scratch/ryan_scratch.c | 6 +++ 10 files changed, 86 insertions(+), 15 deletions(-) diff --git a/build.sh b/build.sh index f5559620..07163698 100644 --- a/build.sh +++ b/build.sh @@ -63,7 +63,7 @@ fi # --- Build Everything (@build_targets) --------------------------------------- cd build -if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $out raddbg; fi +if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $link_render $out raddbg; fi if [ -v radlink ]; then didbuild=1 && $compile ../src/linker/lnk.c $compile_link $out radlink; fi if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb/rdi_from_pdb_main.c $compile_link $out rdi_from_pdb; fi if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi diff --git a/project.4coder b/project.4coder index bc86d180..275657ca 100644 --- a/project.4coder +++ b/project.4coder @@ -55,12 +55,12 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [ryan_scratch] - .f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_log.h b/src/base/base_log.h index 3687390e..ba181ce2 100644 --- a/src/base/base_log.h +++ b/src/base/base_log.h @@ -49,12 +49,12 @@ internal void log_select(Log *log); internal void log_msg(LogMsgKind kind, String8 string); internal void log_msgf(LogMsgKind kind, char *fmt, ...); #define log_info(s) log_msg(LogMsgKind_Info, (s)) -#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__) +#define log_infof(...) log_msgf(LogMsgKind_Info, __VA_ARGS__) #define log_user_error(s) log_msg(LogMsgKind_UserError, (s)) -#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__) +#define log_user_errorf(...) log_msgf(LogMsgKind_UserError, __VA_ARGS__) #define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n")) -#define LogInfoNamedBlockF(fmt, ...) DeferLoop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n")) +#define LogInfoNamedBlockF(...) DeferLoop((log_infof(__VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n")) //////////////////////////////// //~ rjf: Log Scopes diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1b9a4c48..b3d477d1 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3928,7 +3928,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec); for EachIndex(idx, sec_count) { - String8 section_name = str8_cstring(sec[idx].name); + String8 section_name = str8_cstring((char *)sec[idx].name); if(str8_match(section_name, str8_lit(".raddbg"), 0)) { raddbg_section_voff_range.min = sec[idx].voff; diff --git a/src/demon/linux/demon_core_linux.c b/src/demon/linux/demon_core_linux.c index 861c21d3..ffa705af 100644 --- a/src/demon/linux/demon_core_linux.c +++ b/src/demon/linux/demon_core_linux.c @@ -15,6 +15,8 @@ dmn_init(void) internal DMN_CtrlCtx * dmn_ctrl_begin(void) { + DMN_CtrlCtx *ctx = (DMN_CtrlCtx *)1; + return ctx; } internal void @@ -30,26 +32,32 @@ dmn_ctrl_exclusive_access_end(void) internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) { + return 0; } internal B32 dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid) { + return 0; } internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code) { + return 0; } internal B32 dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process) { + return 0; } internal DMN_EventList dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { + DMN_EventList evts = {0}; + return evts; } //////////////////////////////// @@ -68,16 +76,19 @@ dmn_halt(U64 code, U64 user_data) internal U64 dmn_run_gen(void) { + return 0; } internal U64 dmn_mem_gen(void) { + return 0; } internal U64 dmn_reg_gen(void) { + return 0; } //- rjf: non-blocking-control-thread access barriers @@ -85,6 +96,7 @@ dmn_reg_gen(void) internal B32 dmn_access_open(void) { + return 0; } internal void @@ -97,6 +109,7 @@ dmn_access_close(void) internal U64 dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size) { + return 0; } internal void @@ -122,11 +135,13 @@ dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFla internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst) { + return 0; } internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src) { + return 0; } //- rjf: threads @@ -134,26 +149,31 @@ dmn_process_write(DMN_Handle process, Rng1U64 range, void *src) internal Arch dmn_arch_from_thread(DMN_Handle handle) { + return Arch_Null; } internal U64 dmn_stack_base_vaddr_from_thread(DMN_Handle handle) { + return 0; } internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle) { + return 0; } internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block) { + return 0; } internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block) { + return 0; } //- rjf: system process listing @@ -166,6 +186,7 @@ dmn_process_iter_begin(DMN_ProcessIter *iter) internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out) { + return 0; } internal void diff --git a/src/font_provider/font_provider_inc.c b/src/font_provider/font_provider_inc.c index d5c7665b..c589b27a 100644 --- a/src/font_provider/font_provider_inc.c +++ b/src/font_provider/font_provider_inc.c @@ -5,6 +5,8 @@ #if FP_BACKEND == FP_BACKEND_DWRITE # include "dwrite/font_provider_dwrite.c" +#elif FP_BACKEND == FP_BACKEND_FREETYPE +# include "freetype/font_provider_freetype.c" #else # error Font provider backend not specified. #endif diff --git a/src/font_provider/freetype/font_provider_freetype.c b/src/font_provider/freetype/font_provider_freetype.c index 8ac6bce5..a09a5148 100644 --- a/src/font_provider/freetype/font_provider_freetype.c +++ b/src/font_provider/freetype/font_provider_freetype.c @@ -1,2 +1,44 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Backend Implementations + +fp_hook void +fp_init(void) +{ + +} + +fp_hook FP_Handle +fp_font_open(String8 path) +{ + FP_Handle f = {0}; + return f; +} + +fp_hook FP_Handle +fp_font_open_from_static_data_string(String8 *data_ptr) +{ + FP_Handle f = {0}; + return f; +} + +fp_hook void +fp_font_close(FP_Handle handle) +{ +} + +fp_hook FP_Metrics +fp_metrics_from_font(FP_Handle font) +{ + FP_Metrics m = {0}; + return m; +} + +fp_hook NO_ASAN FP_RasterResult +fp_raster(Arena *arena, FP_Handle font, F32 size, FP_RasterFlags flags, String8 string) +{ + FP_RasterResult r = {0}; + return r; +} diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 189a7ad8..aae73b6b 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -277,7 +277,7 @@ os_client_rect_from_window(OS_Handle handle) OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; XWindowAttributes atts = {0}; Status s = XGetWindowAttributes(os_lnx_gfx_state->display, w->window, &atts); - Rng2F32 result = r2f32p((F32)atts.x, (F32)atts.y, (F32)atts.x + (F32)atts.width, (F32)atts.y + (F32)atts.height); + Rng2F32 result = r2f32p(0, 0, (F32)atts.width, (F32)atts.height); return result; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 736f3212..8de188d8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2243,13 +2243,13 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) // new value string as textual data if(!got_commit_data && ((type_kind == E_TypeKind_Ptr || type_kind == E_TypeKind_Array) && - direct_type_kind == E_TypeKind_Char8 || - direct_type_kind == E_TypeKind_Char16 || - direct_type_kind == E_TypeKind_Char32 || - direct_type_kind == E_TypeKind_UChar8 || - direct_type_kind == E_TypeKind_UChar16 || - direct_type_kind == E_TypeKind_UChar32 || - e_type_kind_is_integer(direct_type_kind))) + (direct_type_kind == E_TypeKind_Char8 || + direct_type_kind == E_TypeKind_Char16 || + direct_type_kind == E_TypeKind_Char32 || + direct_type_kind == E_TypeKind_UChar8 || + direct_type_kind == E_TypeKind_UChar16 || + direct_type_kind == E_TypeKind_UChar32 || + e_type_kind_is_integer(direct_type_kind)))) { got_commit_data = 1; B32 is_quoted = 0; diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index f84f5b24..48b3a3fc 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -14,11 +14,17 @@ #include "base/base_inc.h" #include "os/os_inc.h" #include "render/render_inc.h" +#include "font_provider/font_provider_inc.h" +#include "font_cache/font_cache.h" +#include "draw/draw.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" #include "render/render_inc.c" +#include "font_provider/font_provider_inc.c" +#include "font_cache/font_cache.c" +#include "draw/draw.c" //////////////////////////////// //~ rjf: Globals From 868f2d066037537e2d09d69d4f5ca1ee1a6b843f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 14:39:32 -0700 Subject: [PATCH 665/755] be a bit more robust to failures in window creation, IPC thread launching, & semaphore non-implemented parts --- src/os/core/linux/os_core_linux.c | 2 +- src/raddbg/raddbg_core.c | 4 ++++ src/raddbg/raddbg_main.c | 7 +++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 23ec77cf..4555d5a9 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -1071,7 +1071,7 @@ os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name) OS_Handle result = {0}; if (name.size > 0) { // TODO: we need to allocate shared memory to store sem_t - NotImplemented; + // NotImplemented; } else { sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); AssertAlways(s != MAP_FAILED); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8de188d8..9d5855ec 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12900,6 +12900,10 @@ rd_frame(void) Vec2F32 monitor_dim = os_dim_from_monitor(monitor); F32 monitor_dpi = os_dpi_from_monitor(monitor); Vec2F32 window_dim = v2f32(monitor_dim.x*4/5, monitor_dim.y*4/5); + if(window_dim.x == 0 || window_dim.y == 0) + { + window_dim = v2f32(1280, 720); + } RD_Cfg *new_window = rd_cfg_new(file_root, str8_lit("window")); RD_Cfg *size = rd_cfg_new(new_window, str8_lit("size")); rd_cfg_newf(size, "%f", window_dim.x); diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 5cc5210c..a3abc191 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -528,8 +528,11 @@ entry_point(CmdLine *cmd_line) ipc_s2m_ring_mutex = os_mutex_alloc(); ipc_s2m_ring_cv = os_condition_variable_alloc(); IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base; - MemoryZeroStruct(ipc_info); - os_thread_launch(ipc_signaler_thread__entry_point, 0, 0); + if(ipc_shared_memory_base != 0) + { + MemoryZeroStruct(ipc_info); + os_thread_launch(ipc_signaler_thread__entry_point, 0, 0); + } scratch_end(scratch); } From 219e5bd2112899a9cd226b6f329426c44dbe4e46 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 15:59:44 -0700 Subject: [PATCH 666/755] first pass at standing up freetype font provider backend --- build.sh | 5 +- src/draw/draw.c | 2 +- .../freetype/font_provider_freetype.c | 127 ++++++++++++++++-- .../freetype/font_provider_freetype.h | 36 +++++ src/render/opengl/render_opengl.c | 2 +- 5 files changed, 156 insertions(+), 16 deletions(-) diff --git a/build.sh b/build.sh index 07163698..06062df4 100644 --- a/build.sh +++ b/build.sh @@ -19,7 +19,7 @@ git_hash=$(git rev-parse HEAD) git_hash_full=$(git rev-parse HEAD) # --- Compile/Link Line Definitions ------------------------------------------- -clang_common="-I../src/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf" +clang_common="-I../src/ -I/usr/include/freetype2/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common} ${auto_compile_flags}" clang_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}" clang_link="-lpthread -lm -lrt -ldl" @@ -34,6 +34,7 @@ gcc_out="-o" link_dll="-fPIC" link_os_gfx="-lX11 -lXext" link_render="-lGL -lEGL" +link_font_provider="-lfreetype" # --- Choose Compile/Link Lines ----------------------------------------------- if [ -v gcc ]; then compile_debug="$gcc_debug"; fi @@ -63,7 +64,7 @@ fi # --- Build Everything (@build_targets) --------------------------------------- cd build -if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $link_render $out raddbg; fi +if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $link_render $link_font_provider $out raddbg; fi if [ -v radlink ]; then didbuild=1 && $compile ../src/linker/lnk.c $compile_link $out radlink; fi if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb/rdi_from_pdb_main.c $compile_link $out rdi_from_pdb; fi if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi diff --git a/src/draw/draw.c b/src/draw/draw.c index 4dc20b5c..e26a55b6 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -574,7 +574,7 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run tra if(!r_handle_match(texture, r_handle_zero())) { dr_img(dst, src, texture, fr->color, 0, 0, 0); - //dr_rect(dst, v4f32(0, 1, 0, 0.5f), 0, 1.f, 0.f); + // dr_rect(dst, v4f32(0, 1, 0, 0.5f), 0, 1.f, 0.f); } advance += piece->advance; pixel_range.min = Min(pre_advance, pixel_range.min); diff --git a/src/font_provider/freetype/font_provider_freetype.c b/src/font_provider/freetype/font_provider_freetype.c index a09a5148..979d5133 100644 --- a/src/font_provider/freetype/font_provider_freetype.c +++ b/src/font_provider/freetype/font_provider_freetype.c @@ -1,44 +1,147 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: Helpers + +internal FP_FT_Font +fp_ft_font_from_handle(FP_Handle handle) +{ + FP_FT_Font result = {(FT_Face)handle.u64[0]}; + return result; +} + +internal FP_Handle +fp_ft_handle_from_font(FP_FT_Font font) +{ + FP_Handle result = {(U64)font.face}; + return result; +} + //////////////////////////////// //~ rjf: Backend Implementations fp_hook void fp_init(void) { - + Arena *arena = arena_alloc(); + fp_ft_state = push_array(arena, FP_FT_State, 1); + fp_ft_state->arena = arena; + FT_Init_FreeType(&fp_ft_state->library); } fp_hook FP_Handle fp_font_open(String8 path) { - FP_Handle f = {0}; - return f; + Temp scratch = scratch_begin(0, 0); + String8 path_copy = push_str8_copy(scratch.arena, path); + FP_FT_Font font = {0}; + FT_New_Face(fp_ft_state->library, (char *)path_copy.str, 0, &font.face); + FP_Handle handle = fp_ft_handle_from_font(font); + scratch_end(scratch); + return handle; } fp_hook FP_Handle fp_font_open_from_static_data_string(String8 *data_ptr) { - FP_Handle f = {0}; - return f; + FP_FT_Font font = {0}; + FT_New_Memory_Face(fp_ft_state->library, data_ptr->str, (FT_Long)data_ptr->size, 0, &font.face); + FP_Handle handle = fp_ft_handle_from_font(font); + return handle; } fp_hook void fp_font_close(FP_Handle handle) { + FP_FT_Font font = fp_ft_font_from_handle(handle); + if(font.face != 0) + { + FT_Done_Face(font.face); + } } fp_hook FP_Metrics -fp_metrics_from_font(FP_Handle font) +fp_metrics_from_font(FP_Handle handle) { - FP_Metrics m = {0}; - return m; + FP_FT_Font font = fp_ft_font_from_handle(handle); + FP_Metrics result = {0}; + if(font.face != 0) + { + result.design_units_per_em = (F32)font.face->units_per_EM; + result.ascent = (F32)font.face->ascender; + result.descent = (F32)font.face->descender; + result.line_gap = (F32)(font.face->height - font.face->ascender + font.face->descender); + result.capital_height = (F32)(font.face->ascender + font.face->descender); + } + return result; } -fp_hook NO_ASAN FP_RasterResult -fp_raster(Arena *arena, FP_Handle font, F32 size, FP_RasterFlags flags, String8 string) +fp_hook FP_RasterResult +fp_raster(Arena *arena, FP_Handle handle, F32 size, FP_RasterFlags flags, String8 string) { - FP_RasterResult r = {0}; - return r; + ProfBeginFunction(); + FP_FT_Font font = fp_ft_font_from_handle(handle); + FP_RasterResult result = {0}; + if(font.face != 0) + { + Temp scratch = scratch_begin(&arena, 1); + + //- rjf: unpack font + FT_Face face = font.face; + FT_Set_Pixel_Sizes(face, 0, (FT_UInt)size); + S64 ascent = face->size->metrics.ascender >> 6; + S64 descent = abs_s64(face->size->metrics.descender >> 6); + S64 height = face->size->metrics.height >> 6; + + //- rjf: unpack string + String32 string32 = str32_from_8(scratch.arena, string); + + //- rjf: measure + S32 total_width = 0; + for EachIndex(idx, string32.size) + { + FT_Load_Char(face, string32.str[idx], FT_LOAD_RENDER); + total_width += (face->glyph->advance.x >> 6); + } + + //- rjf: allocate & fill atlas w/ rasterization + Vec2S16 dim = {(S16)total_width+1, height+1}; + U64 atlas_size = dim.x * dim.y * 4; + U8 *atlas = push_array(arena, U8, atlas_size); + S32 baseline = ascent; + S32 atlas_write_x = 0; + for EachIndex(idx, string32.size) + { + FT_Load_Char(face, string32.str[idx], FT_LOAD_RENDER); + FT_Bitmap *bmp = &face->glyph->bitmap; + S32 top = face->glyph->bitmap_top; + S32 left = face->glyph->bitmap_left; + for(S32 row = 0; row < (S32)bmp->rows; row += 1) + { + S32 y = baseline - top + row; + for(S32 col = 0; col < (S32)bmp->width; col += 1) + { + S32 x = atlas_write_x + left + col; + U64 off = (y*dim.x + x)*4; + if(off+4 <= atlas_size) + { + atlas[off+0] = 255; + atlas[off+1] = 255; + atlas[off+2] = 255; + atlas[off+3] = bmp->buffer[row*bmp->pitch + col]; + } + } + } + atlas_write_x += (face->glyph->advance.x >> 6); + } + + //- rjf: fill result + result.atlas_dim = dim; + result.advance = (F32)total_width; + result.atlas = atlas; + scratch_end(scratch); + } + ProfEnd(); + return result; } diff --git a/src/font_provider/freetype/font_provider_freetype.h b/src/font_provider/freetype/font_provider_freetype.h index 2efe2a50..b1e37c2f 100644 --- a/src/font_provider/freetype/font_provider_freetype.h +++ b/src/font_provider/freetype/font_provider_freetype.h @@ -4,4 +4,40 @@ #ifndef FONT_PROVIDER_FREETYPE_H #define FONT_PROVIDER_FREETYPE_H +//////////////////////////////// +//~ rjf: Freetype Includes + +#undef internal +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H +#define internal static + +//////////////////////////////// +//~ rjf: State Types + +typedef struct FP_FT_Font FP_FT_Font; +struct FP_FT_Font +{ + FT_Face face; +}; + +typedef struct FP_FT_State FP_FT_State; +struct FP_FT_State +{ + Arena *arena; + FT_Library library; +}; + +//////////////////////////////// +//~ rjf: Globals + +global FP_FT_State *fp_ft_state = 0; + +//////////////////////////////// +//~ rjf: Helpers + +internal FP_FT_Font fp_ft_font_from_handle(FP_Handle handle); +internal FP_Handle fp_ft_handle_from_font(FP_FT_Font font); + #endif // FONT_PROVIDER_FREETYPE_H diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index 60266ce0..eb8240ed 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -468,7 +468,7 @@ r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) { R_PassParams_Blur *params = pass->params_blur; GLuint shader = r_ogl_state->shaders[R_OGL_ShaderKind_Blur]; - glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) + // TODO(rjf): glBindVertexArrayScope(r_ogl_state->all_purpose_vao) glUseProgramScope(shader) { // TODO(rjf) } From 0a3869981f8e34aad212bbb81b83a03ceef8f39b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 16:01:56 -0700 Subject: [PATCH 667/755] correctly calculate shortened hash w/ dirty marker in build.sh --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 06062df4..a8b0fd41 100644 --- a/build.sh +++ b/build.sh @@ -15,7 +15,7 @@ if [ -v gcc ]; then compiler="${CC:-gcc}"; echo "[gcc compile]"; fi auto_compile_flags='' # --- Get Current Git Commit Id ----------------------------------------------- -git_hash=$(git rev-parse HEAD) +git_hash=$(git describe --always --dirty) git_hash_full=$(git rev-parse HEAD) # --- Compile/Link Line Definitions ------------------------------------------- From 6df96b7eef3ef47867f7e193c5f196a3d97ed5cd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 10 May 2025 17:08:40 -0700 Subject: [PATCH 668/755] preserve mouse coordinates from xlib button events --- build.sh | 2 +- src/os/gfx/linux/os_gfx_linux.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index a8b0fd41..f7ea6139 100644 --- a/build.sh +++ b/build.sh @@ -70,7 +70,7 @@ if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi if [ -v rdi_dump ]; then didbuild=1 && $compile ../src/rdi_dump/rdi_dump_main.c $compile_link $out rdi_dump; fi if [ -v rdi_breakpad_from_pdb ]; then didbuild=1 && $compile ../src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c $compile_link $out rdi_breakpad_from_pdb; fi -if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $link_render $out ryan_scratch; fi +if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $link_render $link_font_provider $out ryan_scratch; fi cd .. # --- Warn On No Builds ------------------------------------------------------- diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index aae73b6b..6c81fbb0 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -391,6 +391,7 @@ os_get_events(Arena *arena, B32 wait) case ',':{key = OS_Key_Comma;}break; case '/':{key = OS_Key_Slash;}break; case '\\':{key = OS_Key_BackSlash;}break; + case '\t':{key = OS_Key_Tab;}break; case 'a':case 'A':{key = OS_Key_A;}break; case 'b':case 'B':{key = OS_Key_B;}break; case 'c':case 'C':{key = OS_Key_C;}break; @@ -454,6 +455,7 @@ os_get_events(Arena *arena, B32 wait) e->window.u64[0] = (U64)window; e->modifiers = modifiers; e->key = key; + e->pos = v2f32((F32)evt.xbutton.x, (F32)evt.xbutton.y); }break; //- rjf: mouse motion From 8b3f07c7b5f146c63741b94a7536eec86825e7a4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 13:27:59 -0700 Subject: [PATCH 669/755] eliminate font fudge factors; fix size units in freetype backend; fix directory iteration lack-of-robustness-to-failed-dir-open --- src/font_provider/dwrite/font_provider_dwrite.c | 3 +-- src/font_provider/freetype/font_provider_freetype.c | 6 +++--- src/os/core/linux/os_core_linux.c | 2 +- src/ui/ui_core.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index ebf81ff4..2c2fa96e 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -525,14 +525,13 @@ fp_raster(Arena *arena, FP_Handle font_handle, F32 size, FP_RasterFlags flags, S } //- rjf: draw glyph run - Vec2F32 draw_p = {0, (F32)atlas_dim.y - 1}; + Vec2F32 draw_p = {0, (F32)atlas_dim.y}; if(font.face != 0) { F32 descent = round_f32((96.f/72.f)*size * font_metrics.descent / design_units_per_em); F32 line_gap = round_f32((96.f/72.f)*size * font_metrics.lineGap / design_units_per_em); draw_p.y -= descent; draw_p.y -= line_gap; - draw_p.y += 1; } DWRITE_GLYPH_RUN glyph_run = {0}; if(font.face != 0) diff --git a/src/font_provider/freetype/font_provider_freetype.c b/src/font_provider/freetype/font_provider_freetype.c index 979d5133..b98735b8 100644 --- a/src/font_provider/freetype/font_provider_freetype.c +++ b/src/font_provider/freetype/font_provider_freetype.c @@ -68,11 +68,11 @@ fp_metrics_from_font(FP_Handle handle) FP_Metrics result = {0}; if(font.face != 0) { - result.design_units_per_em = (F32)font.face->units_per_EM; + result.design_units_per_em = (F32)(font.face->units_per_EM * 72.f/96.f); result.ascent = (F32)font.face->ascender; result.descent = (F32)font.face->descender; result.line_gap = (F32)(font.face->height - font.face->ascender + font.face->descender); - result.capital_height = (F32)(font.face->ascender + font.face->descender); + result.capital_height = (F32)(font.face->ascender); } return result; } @@ -89,7 +89,7 @@ fp_raster(Arena *arena, FP_Handle handle, F32 size, FP_RasterFlags flags, String //- rjf: unpack font FT_Face face = font.face; - FT_Set_Pixel_Sizes(face, 0, (FT_UInt)size); + FT_Set_Pixel_Sizes(face, 0, (FT_UInt)((96.f/72.f) * size)); S64 ascent = face->size->metrics.ascender >> 6; S64 descent = abs_s64(face->size->metrics.descender >> 6); S64 height = face->size->metrics.height >> 6; diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 4555d5a9..a44072f7 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -569,7 +569,7 @@ os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out) { B32 good = 0; OS_LNX_FileIter *lnx_iter = (OS_LNX_FileIter *)iter->memory; - for(;;) + for(;lnx_iter->dir != 0;) { // rjf: get next entry lnx_iter->dp = readdir(lnx_iter->dir); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 37887e5d..0d3c78f3 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2767,7 +2767,7 @@ ui_box_text_position(UI_Box *box) FNT_Tag font = box->font; F32 font_size = box->font_size; FNT_Metrics font_metrics = fnt_metrics_from_tag_size(font, font_size); - result.y = floor_f32((box->rect.p0.y + box->rect.p1.y)/2.f) + font_metrics.capital_height/2.f - 1.f; + result.y = floor_f32((box->rect.p0.y + box->rect.p1.y)/2.f) + font_metrics.ascent/2.f - 2.f; if(!fnt_tag_match(font, ui_icon_font())) { result.y += font_metrics.descent/2; From 9de203e2cd50d8c76a419a503608e444e1b5e74c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 13:48:05 -0700 Subject: [PATCH 670/755] adjust smooth-unhinted dwrite raster params --- src/font_provider/dwrite/font_provider_dwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 2c2fa96e..f46aea56 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -287,7 +287,7 @@ fp_init(void) enhanced_contrast, 0.f, DWRITE_PIXEL_GEOMETRY_FLAT, - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, DWRITE_GRID_FIT_MODE_DISABLED, (IDWriteRenderingParams2 **)&fp_dwrite_state->rendering_params_smooth_unhinted); } From 684402efac721e8a6d43aeb4c1b86efee0c65b72 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 14:14:12 -0700 Subject: [PATCH 671/755] x11 event coverage --- src/os/gfx/linux/os_gfx_linux.c | 61 +++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 6c81fbb0..7f5ce53b 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -367,8 +367,10 @@ os_get_events(Arena *arena, B32 wait) if(evt.xkey.state & ControlMask) { modifiers |= OS_Modifier_Ctrl; } if(evt.xkey.state & Mod1Mask) { modifiers |= OS_Modifier_Alt; } - // rjf: map keycode -> keysym - U32 keysym = XLookupKeysym(&evt.xkey, 0); + // rjf: map keycode -> keysym & codepoint + KeySym keysym = 0; + U8 text[256] = {0}; + U64 text_size = XLookupString(&evt.xkey, (char *)text, sizeof(text), &keysym, 0); // rjf: map keysym -> OS_Key OS_Key key = OS_Key_Null; @@ -381,6 +383,19 @@ os_get_events(Arena *arena, B32 wait) else if('0' <= keysym && keysym <= '9') { key = OS_Key_0 + (keysym-'0'); } }break; case XK_Escape:{key = OS_Key_Esc;};break; + case XK_BackSpace:{key = OS_Key_Backspace;}break; + case XK_Delete:{key = OS_Key_Delete;}break; + case XK_Return:{key = OS_Key_Return;}break; + case XK_Pause:{key = OS_Key_Pause;}break; + case XK_Tab:{key = OS_Key_Tab;}break; + case XK_Left:{key = OS_Key_Left;}break; + case XK_Right:{key = OS_Key_Right;}break; + case XK_Up:{key = OS_Key_Up;}break; + case XK_Down:{key = OS_Key_Down;}break; + case XK_Home:{key = OS_Key_Home;}break; + case XK_End:{key = OS_Key_End;}break; + case XK_Page_Up:{key = OS_Key_PageUp;}break; + case XK_Page_Down:{key = OS_Key_PageDown;}break; case '-':{key = OS_Key_Minus;}break; case '=':{key = OS_Key_Equal;}break; case '[':{key = OS_Key_LeftBracket;}break; @@ -421,12 +436,34 @@ os_get_events(Arena *arena, B32 wait) case ' ':{key = OS_Key_Space;}break; } - // rjf: push event - OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xclient.window); - OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == KeyPress ? OS_EventKind_Press : OS_EventKind_Release); - e->window.u64[0] = (U64)window; - e->modifiers = modifiers; - e->key = key; + // rjf: push text event + OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xkey.window); + if(evt.type == KeyPress && text_size != 0) + { + for(U64 off = 0; off < text_size;) + { + UnicodeDecode decode = utf8_decode(text+off, text_size-off); + if(decode.codepoint != 0 && (decode.codepoint >= 32 || decode.codepoint == '\t')) + { + OS_Event *e = os_event_list_push_new(arena, &evts, OS_EventKind_Text); + e->window.u64[0] = (U64)window; + e->character = decode.codepoint; + } + if(decode.inc == 0) + { + break; + } + off += decode.inc; + } + } + + // rjf: push key event + { + OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == KeyPress ? OS_EventKind_Press : OS_EventKind_Release); + e->window.u64[0] = (U64)window; + e->modifiers = modifiers; + e->key = key; + } }break; //- rjf: mouse button presses/releases @@ -450,7 +487,7 @@ os_get_events(Arena *arena, B32 wait) } // rjf: push event - OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xclient.window); + OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xbutton.window); OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == ButtonPress ? OS_EventKind_Press : OS_EventKind_Release); e->window.u64[0] = (U64)window; e->modifiers = modifiers; @@ -470,9 +507,13 @@ os_get_events(Arena *arena, B32 wait) //- rjf: window focus/unfocus case FocusIn: + { + }break; case FocusOut: { - + OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xfocus.window); + OS_Event *e = os_event_list_push_new(arena, &evts, OS_EventKind_WindowLoseFocus); + e->window.u64[0] = (U64)window; }break; //- rjf: client messages From 1896ec2a853d3c838ceb9aacc0daf9471256058d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 15:19:40 -0700 Subject: [PATCH 672/755] more os/gfx linux coverage --- src/os/gfx/linux/os_gfx_linux.c | 74 ++++++++++++++++++++++++++++++--- src/os/gfx/linux/os_gfx_linux.h | 3 ++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 7f5ce53b..54c31736 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -40,6 +40,31 @@ os_gfx_init(void) os_lnx_gfx_state->gfx_info.double_click_time = 0.5f; os_lnx_gfx_state->gfx_info.caret_blink_time = 0.5f; os_lnx_gfx_state->gfx_info.default_refresh_rate = 60.f; + + //- rjf: fill out cursors + { + struct + { + OS_Cursor cursor; + unsigned int id; + } + map[] = + { + {OS_Cursor_Pointer, XC_left_ptr}, + {OS_Cursor_IBar, XC_xterm}, + {OS_Cursor_LeftRight, XC_sb_h_double_arrow}, + {OS_Cursor_UpDown, XC_sb_v_double_arrow}, + {OS_Cursor_DownRight, XC_bottom_right_corner}, + {OS_Cursor_UpRight, XC_top_right_corner}, + {OS_Cursor_UpDownLeftRight, XC_fleur}, + {OS_Cursor_HandPoint, XC_hand1}, + {OS_Cursor_Disabled, XC_X_cursor}, + }; + for EachElement(idx, map) + { + os_lnx_gfx_state->cursors[map[idx].cursor] = XCreateFontCursor(os_lnx_gfx_state->display, map[idx].id); + } + } } //////////////////////////////// @@ -353,6 +378,7 @@ os_get_events(Arena *arena, B32 wait) { XEvent evt = {0}; XNextEvent(os_lnx_gfx_state->display, &evt); + B32 set_mouse_cursor = 0; switch(evt.type) { default:{}break; @@ -373,6 +399,7 @@ os_get_events(Arena *arena, B32 wait) U64 text_size = XLookupString(&evt.xkey, (char *)text, sizeof(text), &keysym, 0); // rjf: map keysym -> OS_Key + B32 is_right_sided = 0; OS_Key key = OS_Key_Null; switch(keysym) { @@ -396,6 +423,12 @@ os_get_events(Arena *arena, B32 wait) case XK_End:{key = OS_Key_End;}break; case XK_Page_Up:{key = OS_Key_PageUp;}break; case XK_Page_Down:{key = OS_Key_PageDown;}break; + case XK_Alt_L:{ key = OS_Key_Alt; }break; + case XK_Alt_R:{ key = OS_Key_Alt; is_right_sided = 1;}break; + case XK_Shift_L:{ key = OS_Key_Shift; }break; + case XK_Shift_R:{ key = OS_Key_Shift; is_right_sided = 1;}break; + case XK_Control_L:{ key = OS_Key_Ctrl; }break; + case XK_Control_R:{ key = OS_Key_Ctrl; is_right_sided = 1;}break; case '-':{key = OS_Key_Minus;}break; case '=':{key = OS_Key_Equal;}break; case '[':{key = OS_Key_LeftBracket;}break; @@ -463,6 +496,7 @@ os_get_events(Arena *arena, B32 wait) e->window.u64[0] = (U64)window; e->modifiers = modifiers; e->key = key; + e->right_sided = is_right_sided; } }break; @@ -488,11 +522,23 @@ os_get_events(Arena *arena, B32 wait) // rjf: push event OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xbutton.window); - OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == ButtonPress ? OS_EventKind_Press : OS_EventKind_Release); - e->window.u64[0] = (U64)window; - e->modifiers = modifiers; - e->key = key; - e->pos = v2f32((F32)evt.xbutton.x, (F32)evt.xbutton.y); + if(key != OS_Key_Null) + { + OS_Event *e = os_event_list_push_new(arena, &evts, evt.type == ButtonPress ? OS_EventKind_Press : OS_EventKind_Release); + e->window.u64[0] = (U64)window; + e->modifiers = modifiers; + e->key = key; + e->pos = v2f32((F32)evt.xbutton.x, (F32)evt.xbutton.y); + } + else if(evt.xbutton.button == Button4 || + evt.xbutton.button == Button5) + { + OS_Event *e = os_event_list_push_new(arena, &evts, OS_EventKind_Scroll); + e->window.u64[0] = (U64)window; + e->modifiers = modifiers; + e->delta = v2f32(0, evt.xbutton.button == Button4 ? -1.f : +1.f); + e->pos = v2f32((F32)evt.xbutton.x, (F32)evt.xbutton.y); + } }break; //- rjf: mouse motion @@ -503,6 +549,7 @@ os_get_events(Arena *arena, B32 wait) e->window.u64[0] = (U64)window; e->pos.x = (F32)evt.xmotion.x; e->pos.y = (F32)evt.xmotion.y; + set_mouse_cursor = 1; }break; //- rjf: window focus/unfocus @@ -540,6 +587,21 @@ os_get_events(Arena *arena, B32 wait) } }break; } + if(set_mouse_cursor) + { + Window root_window = 0; + Window child_window = 0; + int root_rel_x = 0; + int root_rel_y = 0; + int child_rel_x = 0; + int child_rel_y = 0; + unsigned int mask = 0; + if(XQueryPointer(os_lnx_gfx_state->display, XDefaultRootWindow(os_lnx_gfx_state->display), &root_window, &child_window, &root_rel_x, &root_rel_y, &child_rel_x, &child_rel_y, &mask)) + { + XDefineCursor(os_lnx_gfx_state->display, root_window, os_lnx_gfx_state->cursors[os_lnx_gfx_state->last_set_cursor]); + XFlush(os_lnx_gfx_state->display); + } + } } return evts; } @@ -587,7 +649,7 @@ os_mouse_from_window(OS_Handle handle) internal void os_set_cursor(OS_Cursor cursor) { - // TODO(rjf) + os_lnx_gfx_state->last_set_cursor = cursor; } //////////////////////////////// diff --git a/src/os/gfx/linux/os_gfx_linux.h b/src/os/gfx/linux/os_gfx_linux.h index 4ac97ab3..96341575 100644 --- a/src/os/gfx/linux/os_gfx_linux.h +++ b/src/os/gfx/linux/os_gfx_linux.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,8 @@ struct OS_LNX_GfxState Atom wm_delete_window_atom; Atom wm_sync_request_atom; Atom wm_sync_request_counter_atom; + Cursor cursors[OS_Cursor_COUNT]; + OS_Cursor last_set_cursor; OS_GfxInfo gfx_info; }; From cc319190c6f4226e044563809234576bd98f3fe3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 15:26:05 -0700 Subject: [PATCH 673/755] render/opengl: flushed instance buffers --- src/render/opengl/render_opengl.c | 40 +++++++++++++++++++++++++++---- src/render/opengl/render_opengl.h | 14 ++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index eb8240ed..e23df2ac 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -65,6 +65,29 @@ r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt) return result; } +internal GLuint +r_ogl_instance_buffer_from_size(U64 size) +{ + GLuint buffer = r_ogl_state->scratch_buffer_64kb; + if(size > KB(64)) + { + // rjf: build buffer + U64 flushed_buffer_size = size; + flushed_buffer_size += MB(1)-1; + flushed_buffer_size -= flushed_buffer_size%MB(1); + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, flushed_buffer_size, 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // rjf: push buffer to flush list + R_OGL_FlushBuffer *n = push_array(r_ogl_state->buffer_flush_arena, R_OGL_FlushBuffer, 1); + n->id = buffer; + SLLQueuePush(r_ogl_state->first_buffer_to_flush, r_ogl_state->last_buffer_to_flush, n); + } + return buffer; +} + internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { @@ -150,9 +173,9 @@ r_init(CmdLine *cmdln) //- rjf: set up built-in resources glGenVertexArrays(1, &r_ogl_state->all_purpose_vao); - glGenBuffers(1, &r_ogl_state->scratch_buffer_2mb); - glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_2mb); - glBufferData(GL_ARRAY_BUFFER, MB(2), 0, GL_DYNAMIC_DRAW); + glGenBuffers(1, &r_ogl_state->scratch_buffer_64kb); + glBindBuffer(GL_ARRAY_BUFFER, r_ogl_state->scratch_buffer_64kb); + glBufferData(GL_ARRAY_BUFFER, KB(64), 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenTextures(1, &r_ogl_state->white_texture); glBindTexture(GL_TEXTURE_2D, r_ogl_state->white_texture); @@ -160,6 +183,9 @@ r_init(CmdLine *cmdln) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &white_pixel); glEnable(GL_FRAMEBUFFER_SRGB); + //- rjf: set up buffer flush state + r_ogl_state->buffer_flush_arena = arena_alloc(); + //- rjf: set up debug callback B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); #if BUILD_DEBUG @@ -334,6 +360,12 @@ r_window_begin_frame(OS_Handle os, R_Handle r) r_hook void r_window_end_frame(OS_Handle os, R_Handle r) { + for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next) + { + glDeleteBuffers(1, &flush_buffer->id); + } + arena_clear(r_ogl_state->buffer_flush_arena); + r_ogl_state->first_buffer_to_flush = r_ogl_state->last_buffer_to_flush = 0; r_ogl_os_window_swap(os, r); } @@ -382,7 +414,7 @@ r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) } //- rjf: get & fill buffer - GLuint buffer = r_ogl_state->scratch_buffer_2mb; // TODO(rjf): r_ogl_instance_buffer_from_size(batches->byte_count); + GLuint buffer = r_ogl_instance_buffer_from_size(batches->byte_count); { glBindBuffer(GL_ARRAY_BUFFER, buffer); U64 off = 0; diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index dde24165..e8c56ccb 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -113,6 +113,7 @@ struct R_OGL_AttributeArray #define R_OGL_ProcedureXList \ X(glGenBuffers, void, (GLsizei n, GLuint *buffers))\ X(glBindBuffer, void, (GLenum target, GLuint buffer))\ +X(glDeleteBuffers, void, (GLsizei n, GLuint *buffers))\ X(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))\ X(glBindVertexArray, void, (GLuint array))\ X(glCreateProgram, GLuint, (void))\ @@ -179,6 +180,13 @@ struct R_OGL_Tex2D Vec2S32 size; }; +typedef struct R_OGL_FlushBuffer R_OGL_FlushBuffer; +struct R_OGL_FlushBuffer +{ + R_OGL_FlushBuffer *next; + GLuint id; +}; + typedef struct R_OGL_State R_OGL_State; struct R_OGL_State { @@ -186,8 +194,11 @@ struct R_OGL_State R_OGL_Tex2D *free_tex2d; GLuint shaders[R_OGL_ShaderKind_COUNT]; GLuint all_purpose_vao; - GLuint scratch_buffer_2mb; + GLuint scratch_buffer_64kb; GLuint white_texture; + Arena *buffer_flush_arena; + R_OGL_FlushBuffer *first_buffer_to_flush; + R_OGL_FlushBuffer *last_buffer_to_flush; }; //////////////////////////////// @@ -201,6 +212,7 @@ global R_OGL_State *r_ogl_state = 0; internal R_Handle r_ogl_handle_from_tex2d(R_OGL_Tex2D *t); internal R_OGL_Tex2D *r_ogl_tex2d_from_handle(R_Handle h); internal R_OGL_FormatInfo r_ogl_format_info_from_tex2dformat(R_Tex2DFormat fmt); +internal GLuint r_ogl_instance_buffer_from_size(U64 size); internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); #define glUseProgramScope(...) DeferLoop(glUseProgram(__VA_ARGS__), glUseProgram(0)) From 2307d445060c70f0cc04a9a9257e5c7ffe8b58bf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 21:26:25 -0700 Subject: [PATCH 674/755] forward declare XLookupString ourselves, since it is apparently missing in libx11-dev --- src/os/gfx/linux/os_gfx_linux.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/os/gfx/linux/os_gfx_linux.h b/src/os/gfx/linux/os_gfx_linux.h index 96341575..4a562ae5 100644 --- a/src/os/gfx/linux/os_gfx_linux.h +++ b/src/os/gfx/linux/os_gfx_linux.h @@ -14,6 +14,17 @@ #include #include +//////////////////////////////// +//~ rjf: Prototypes (which seem to sometimes be missing) + +typedef struct _XComposeStatus +{ + XPointer compose_ptr; + int chars_matched; +} +XComposeStatus; +int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out); + //////////////////////////////// //~ rjf: Window State From 8688322a431575731f491c861c9418df72bb3fb9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 11 May 2025 21:47:24 -0700 Subject: [PATCH 675/755] more of the same --- src/os/gfx/linux/os_gfx_linux.c | 5 +++++ src/os/gfx/linux/os_gfx_linux.h | 11 ----------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 54c31736..a125f5c3 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -1,6 +1,11 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: Prototypes (which seem to sometimes be missing) + +int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out); + //////////////////////////////// //~ rjf: Helpers diff --git a/src/os/gfx/linux/os_gfx_linux.h b/src/os/gfx/linux/os_gfx_linux.h index 4a562ae5..96341575 100644 --- a/src/os/gfx/linux/os_gfx_linux.h +++ b/src/os/gfx/linux/os_gfx_linux.h @@ -14,17 +14,6 @@ #include #include -//////////////////////////////// -//~ rjf: Prototypes (which seem to sometimes be missing) - -typedef struct _XComposeStatus -{ - XPointer compose_ptr; - int chars_matched; -} -XComposeStatus; -int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out); - //////////////////////////////// //~ rjf: Window State From fe3cac7ac3d9e7977f6d191c7f08ccf921077f99 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 11:56:57 -0700 Subject: [PATCH 676/755] parameterize irtree generation path with identifier resolution rules; in most cases, we want the usual order: implicit accesses -> locals -> registers -> globals/tlocals/types/procedures -> macros; but if we are specifically evaluating a call expression tree, we want to prefer callables - in this case, macros should be prioritized. --- project.4coder | 9 +- src/eval/eval_core.c | 12 +- src/eval/eval_ir.c | 883 +++++++++--------- src/eval/eval_ir.h | 74 +- src/eval/eval_types.c | 2 +- src/mule/mule_main.cpp | 8 +- .../opengl/generated/render_opengl.meta.c | 76 +- .../opengl/generated/render_opengl.meta.h | 552 +++++------ 8 files changed, 863 insertions(+), 753 deletions(-) diff --git a/project.4coder b/project.4coder index 275657ca..22f59d81 100644 --- a/project.4coder +++ b/project.4coder @@ -46,7 +46,7 @@ load_paths = commands = { //- rjf: [raddbg] - // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, @@ -54,13 +54,10 @@ commands = //- rjf: [tester] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - //- rjf: [ryan_scratch] - .f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - //- rjf: running target - // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: local target builds .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 61e90d0d..1a5d11cf 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -849,7 +849,7 @@ e_irtree_from_bundle(E_CacheBundle *bundle) bundle->flags |= E_CacheBundleFlag_IRTree; E_IRTreeAndType parent = 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, &parent, 0, 0, parse.expr); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, &e_default_identifier_resolution_rule, 0, 0, parse.expr); E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } @@ -1243,8 +1243,12 @@ e_range_size_from_eval(E_Eval eval) Temp scratch = scratch_begin(0, 0); U64 element_size = e_type_byte_size_from_key(e_type_key_unwrap(type_core, E_TypeUnwrapFlag_All)); E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval, str8_zero()); - result = expand_info.expr_count * element_size; - got_size = 1; + U64 new_result_maybe = expand_info.expr_count * element_size; + if(new_result_maybe != 0) + { + result = new_result_maybe; + got_size = 1; + } scratch_end(scratch); } } @@ -1332,7 +1336,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, &e_default_identifier_resolution_rule, 0, 0, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 4f3104c3..9ec5976c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -497,7 +497,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 1, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, &e_default_identifier_resolution_rule, 0, 1, exprr); e_msg_list_concat_in_place(&result.msgs, &r.msgs); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -588,7 +588,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) } internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_IdentifierResolutionRule *identifier_resolution_rule, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -632,7 +632,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, 0, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 0, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); // rjf: try all IR trees in chain @@ -715,7 +715,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 String8 full_qualified_name = str8_list_join(scratch.arena, &parts, &(StringJoin){.sep = str8_lit(".")}); E_Expr *leaf_expr_name = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, r1u64(0, 0)); leaf_expr_name->string = full_qualified_name; - result = e_push_irtree_and_type_from_expr(arena, root_parent, disallow_autohooks, disallow_autohooks, leaf_expr_name); + result = e_push_irtree_and_type_from_expr(arena, root_parent, &e_default_identifier_resolution_rule, disallow_autohooks, disallow_autohooks, leaf_expr_name); } } }break; @@ -725,7 +725,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -784,7 +784,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); @@ -812,12 +812,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, cast_type_expr); e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -872,7 +872,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 1, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -900,7 +900,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 1, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -914,7 +914,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -942,14 +942,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -982,7 +982,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1037,8 +1037,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1279,9 +1279,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1350,7 +1350,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { B32 strip_lenses = 0; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_callable_identifier_resolution_rule, disallow_autohooks, 1, lhs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key(lhs_type_key); @@ -1358,7 +1358,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 // rjf: calling a type? -> treat as a cast of that type if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec) { - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first->next); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first->next); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey cast_type = lhs_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); @@ -1430,7 +1430,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 strip_lenses = 1; disallow_autohooks = 1; } - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, call); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, call); // NOTE(rjf): we do not want to accumulate messages from the original left-hand-side evaluation in this case, because // this path only occurs if the member access fails specifically. } @@ -1448,7 +1448,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 } // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, lhs->next); // rjf: if not raw, wrap resultant type with lens type if(!strip_lenses) @@ -1576,448 +1576,479 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 String8 qualifier = expr->qualifier; String8 string = expr->string; String8 string__redirected = string; + String8List namespaceified_strings = {0}; B32 string_mapped = 0; + B32 string_is_implicit_member_name = 0; E_TypeKey mapped_type_key = zero_struct; E_Module *mapped_location_block_module = &e_module_nil; RDI_LocationBlock *mapped_location_block = 0; E_Mode mapped_bytecode_mode = E_Mode_Offset; E_Space mapped_bytecode_space = zero_struct; String8 mapped_bytecode = {0}; + B32 generated = 0; - //- rjf: try to map name as parent expression signifier ('$') - if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) + //- rjf: iterate identifier resolution rule paths, try to resolve + // identifier in that order. + for(U64 path_idx = 0; !generated && path_idx < identifier_resolution_rule->count; path_idx += 1) { - E_IRTreeAndType *parent_irtree = parent; - if(disallow_autohooks) + //- rjf: try to map identifier via this path + E_IdentifierResolutionPath path = identifier_resolution_rule->paths[path_idx]; + switch(path) { - for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) - { - parent_irtree = prev; - } - } - E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); - string_mapped = 1; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = parent_irtree->mode; - mapped_type_key = parent_irtree->type_key; - disallow_autohooks = 1; - E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); - e_msg_list_concat_in_place(&result.msgs, &msgs); - } - - //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil) - { - for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) - { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, access); - if(access_irtree.root != &e_irnode_nil) - { - string_mapped = 1; - E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); - mapped_type_key = access_irtree.type_key; - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = access_irtree.mode; - e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); - break; - } - } - } - - //- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn - // on later implicit-member-lookup generation - B32 string_is_implicit_member_name = 0; - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) - { - E_Module *module = e_base_ctx->primary_module; - U32 module_idx = (U32)(module - e_base_ctx->modules); - RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_cache->thread_ip_procedure; - RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); - E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); - E_Member member = e_type_member_from_key_name__cached(container_type_key, string); - if(member.kind != E_MemberKind_Null) - { - string_is_implicit_member_name = 1; - string__redirected = str8_lit("this"); - } - } - - //- rjf: try locals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) - { - E_Module *module = e_base_ctx->primary_module; - U32 module_idx = (U32)(module - e_base_ctx->modules); - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected); - if(local_num != 0) - { - RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); + default:{}break; - // rjf: extract local's type key - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); - - // rjf: extract local's location block - U64 ip_voff = e_base_ctx->thread_ip_voff; - for(U32 loc_block_idx = local->location_first; - loc_block_idx < local->location_opl; - loc_block_idx += 1) + //- rjf: try to map name as parent expression signifier ('$') + case E_IdentifierResolutionPath_ParentExpr: + if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) + E_IRTreeAndType *parent_irtree = parent; + if(disallow_autohooks) { - mapped_location_block_module = module; - mapped_location_block = block; - } - } - } - } - - //- rjf: mapped to location block -> extract or produce bytecode for this mapping - if(mapped_location_block != 0) - { - E_Module *module = mapped_location_block_module; - E_Space space = module->space; - Arch arch = module->arch; - RDI_Parsed *rdi = module->rdi; - RDI_LocationBlock *block = mapped_location_block; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) - { - RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) - { - default:{}break; - case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; - bytecode_stream:; - { - string_mapped = 1; - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) + for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) + parent_irtree = prev; + } + } + E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); + string_mapped = 1; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = parent_irtree->mode; + mapped_type_key = parent_irtree->type_key; + disallow_autohooks = 1; + E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); + e_msg_list_concat_in_place(&result.msgs, &msgs); + } + break; + + //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) + case E_IdentifierResolutionPath_ParentExprMember: + if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil) + { + for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) + { + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); + if(access_irtree.root != &e_irnode_nil) + { + string_mapped = 1; + E_OpList oplist = e_oplist_from_irtree(scratch.arena, access_irtree.root); + mapped_type_key = access_irtree.type_key; + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = access_irtree.mode; + e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs); + break; + } + } + }break; + + //- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn + // on later implicit-member-lookup generation + case E_IdentifierResolutionPath_ImplicitThisMember: + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) + { + E_Module *module = e_base_ctx->primary_module; + U32 module_idx = (U32)(module - e_base_ctx->modules); + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; + RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); + E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); + E_Member member = e_type_member_from_key_name__cached(container_type_key, string); + if(member.kind != E_MemberKind_Null) + { + string_is_implicit_member_name = 1; + string__redirected = str8_lit("this"); + } + }break; + + //- rjf: try locals + case E_IdentifierResolutionPath_Local: + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) + { + E_Module *module = e_base_ctx->primary_module; + U32 module_idx = (U32)(module - e_base_ctx->modules); + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected); + if(local_num != 0) + { + RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); + + // rjf: extract local's type key + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); + + // rjf: extract local's location block + U64 ip_voff = e_base_ctx->thread_ip_voff; + for(U32 loc_block_idx = local->location_first; + loc_block_idx < local->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) + { + mapped_location_block_module = module; + mapped_location_block = block; + } + } + } + }break; + + //- rjf: globals / procedures / types + case E_IdentifierResolutionPath_Globals: + case E_IdentifierResolutionPath_Procedures: + case E_IdentifierResolutionPath_ThreadLocals: + { + //- rjf: form namespaceified fallback versions of this lookup string + if(!string_mapped) + { + E_Module *module = e_base_ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) { break; } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); + str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; } - mapped_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) + } + + //- rjf: try globals + if(path == E_IdentifierResolutionPath_Globals && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) + { + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_base_ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try thread-locals + if(path == E_IdentifierResolutionPath_ThreadLocals && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) + { + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_base_ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = module->space; + break; + } + } + } + + //- rjf: try procedures + if(path == E_IdentifierResolutionPath_Procedures && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) + { + for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_base_ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[matches_count-1]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + string_mapped = 1; + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = module->space; + break; + } + } + } + }break; + + //- rjf: try types + case E_IdentifierResolutionPath_Types: + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) + { + mapped_type_key = e_leaf_type_from_name(string); + if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) { string_mapped = 1; - RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + } + }break; + + + //- rjf: try registers + case E_IdentifierResolutionPath_Registers: + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); + if(reg_num != 0) + { + string_mapped = 1; + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num]; E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = space; - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: + mapped_bytecode_space = e_base_ctx->thread_reg_space; + mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num); + } + }break; + + //- rjf: try register aliases + case E_IdentifierResolutionPath_RegisterAliases: + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) + { + U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); + if(alias_num != 0) { string_mapped = 1; - RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code]; E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = space; - }break; - case RDI_LocationKind_ValReg: - if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) - { - string_mapped = 1; - RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); - - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - mapped_bytecode_space = space; - }break; - } - } - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_strings = {0}; - if(!string_mapped) - { - E_Module *module = e_base_ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_cache->thread_ip_procedure; - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) + mapped_bytecode_space = e_base_ctx->thread_reg_space; + mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num); + } + }break; + + //- rjf: try basic constants + case E_IdentifierResolutionPath_Constants: + if(!string_mapped && str8_match(string, str8_lit("true"), 0)) { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); - str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try globals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0))) - { - for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_base_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = module->space; - break; - } - } - } - - //- rjf: try thread-locals - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0))) - { - for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_base_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = module->space; - break; - } - } - } - - //- rjf: try procedures - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0))) - { - for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_base_ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[matches_count-1]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - string_mapped = 1; - mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + e_oplist_push_uconst(arena, &oplist, 1); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = E_Mode_Value; - mapped_bytecode_space = module->space; - break; + } + if(!string_mapped && str8_match(string, str8_lit("false"), 0)) + { + string_mapped = 1; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, 0); + mapped_type_key = e_type_key_basic(E_TypeKind_Bool); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + }break; + + //- rjf: try macros + case E_IdentifierResolutionPath_Macros: + { + if(!generated) + { + E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, string); + if(macro_expr != &e_expr_nil) + { + generated = 1; + e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, macro_expr); + e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); + } + } + }break; + } + + //- rjf: mapped to location block -> extract or produce bytecode for this mapping + if(!generated && mapped_location_block != 0) + { + E_Module *module = mapped_location_block_module; + E_Space space = module->space; + Arch arch = module->arch; + RDI_Parsed *rdi = module->rdi; + RDI_LocationBlock *block = mapped_location_block; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{}break; + case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; + bytecode_stream:; + { + string_mapped = 1; + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + mapped_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_ValReg: + if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); + + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = space; + }break; + } } } - } - - //- rjf: try types - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0))) - { - mapped_type_key = e_leaf_type_from_name(string); - if(!e_type_key_match(e_type_key_zero(), mapped_type_key)) - { - string_mapped = 1; - } - } - - //- rjf: try registers - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) - { - U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); - if(reg_num != 0) - { - string_mapped = 1; - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_base_ctx->thread_reg_space; - mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num); - } - } - - //- rjf: try register aliases - if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) - { - U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); - if(alias_num != 0) - { - string_mapped = 1; - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Offset; - mapped_bytecode_space = e_base_ctx->thread_reg_space; - mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num); - } - } - - //- rjf: try basic constants - if(!string_mapped && str8_match(string, str8_lit("true"), 0)) - { - string_mapped = 1; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, 1); - mapped_type_key = e_type_key_basic(E_TypeKind_Bool); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - } - if(!string_mapped && str8_match(string, str8_lit("false"), 0)) - { - string_mapped = 1; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, 0); - mapped_type_key = e_type_key_basic(E_TypeKind_Bool); - mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = E_Mode_Value; - } - - //- rjf: generate IR trees for bytecode - B32 generated = 0; - if(!generated && mapped_bytecode.size != 0) - { - generated = 1; - E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); - root->space = mapped_bytecode_space; - result.root = root; - result.type_key = mapped_type_key; - result.mode = mapped_bytecode_mode; - } - - //- rjf: generate nil-IR trees w/ type for types - if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) - { - generated = 1; - result.root = e_irtree_const_u(arena, 0); - result.type_key = mapped_type_key; - result.mode = E_Mode_Null; - } - - //- rjf: generate IR trees for macros - if(!generated) - { - E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, string); - if(macro_expr != &e_expr_nil) + + //- rjf: generate IR trees for bytecode + if(!generated && mapped_bytecode.size != 0) { generated = 1; - e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, macro_expr); - e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); + E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); + root->space = mapped_bytecode_space; + result.root = root; + result.type_key = mapped_type_key; + result.mode = mapped_bytecode_mode; + } + + //- rjf: generate nil-IR trees w/ type for types + if(!generated && !e_type_key_match(e_type_key_zero(), mapped_type_key)) + { + generated = 1; + result.root = e_irtree_const_u(arena, 0); + result.type_key = mapped_type_key; + result.mode = E_Mode_Null; } } //- rjf: extend generated result, if result was generated by an implicit member access - if(string_is_implicit_member_name) + if(generated && string_is_implicit_member_name) { E_Expr *access = e_expr_irext_member_access(arena, &e_expr_nil, &result, string); - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, access); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); } //- rjf: error on failure-to-generate @@ -2089,7 +2120,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; case E_ExprKind_Unsigned: { - E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); + E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first); result = direct_irtree; E_TypeKey direct_type_key = result.type_key; E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); @@ -2119,13 +2150,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2139,7 +2170,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, rhs); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Left side of assignment must be an unused identifier."); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index afcf793d..c7b9e338 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -4,6 +4,33 @@ #ifndef EVAL_IR_H #define EVAL_IR_H +//////////////////////////////// +//~ rjf: Identifier Resolution Rule Types + +typedef enum E_IdentifierResolutionPath +{ + E_IdentifierResolutionPath_ParentExpr, + E_IdentifierResolutionPath_ParentExprMember, + E_IdentifierResolutionPath_ImplicitThisMember, + E_IdentifierResolutionPath_Local, + E_IdentifierResolutionPath_Globals, + E_IdentifierResolutionPath_ThreadLocals, + E_IdentifierResolutionPath_Procedures, + E_IdentifierResolutionPath_Types, + E_IdentifierResolutionPath_Registers, + E_IdentifierResolutionPath_RegisterAliases, + E_IdentifierResolutionPath_Constants, + E_IdentifierResolutionPath_Macros, +} +E_IdentifierResolutionPath; + +typedef struct E_IdentifierResolutionRule E_IdentifierResolutionRule; +struct E_IdentifierResolutionRule +{ + E_IdentifierResolutionPath *paths; + U64 count; +}; + //////////////////////////////// //~ rjf: IR State @@ -49,6 +76,51 @@ struct E_IRState E_IRCacheSlot *ir_cache_slots; }; +//////////////////////////////// +//~ rjf: Globals + +E_IdentifierResolutionPath e_default_identifier_resolution_paths[] = +{ + E_IdentifierResolutionPath_ParentExpr, + E_IdentifierResolutionPath_ParentExprMember, + E_IdentifierResolutionPath_ImplicitThisMember, + E_IdentifierResolutionPath_Local, + E_IdentifierResolutionPath_Globals, + E_IdentifierResolutionPath_ThreadLocals, + E_IdentifierResolutionPath_Procedures, + E_IdentifierResolutionPath_Types, + E_IdentifierResolutionPath_Registers, + E_IdentifierResolutionPath_RegisterAliases, + E_IdentifierResolutionPath_Constants, + E_IdentifierResolutionPath_Macros, +}; +E_IdentifierResolutionRule e_default_identifier_resolution_rule = +{ + e_default_identifier_resolution_paths, + ArrayCount(e_default_identifier_resolution_paths), +}; + +E_IdentifierResolutionPath e_callable_identifier_resolution_paths[] = +{ + E_IdentifierResolutionPath_Macros, + E_IdentifierResolutionPath_ParentExpr, + E_IdentifierResolutionPath_ParentExprMember, + E_IdentifierResolutionPath_ImplicitThisMember, + E_IdentifierResolutionPath_Local, + E_IdentifierResolutionPath_Globals, + E_IdentifierResolutionPath_ThreadLocals, + E_IdentifierResolutionPath_Procedures, + E_IdentifierResolutionPath_Types, + E_IdentifierResolutionPath_Registers, + E_IdentifierResolutionPath_RegisterAliases, + E_IdentifierResolutionPath_Constants, +}; +E_IdentifierResolutionRule e_callable_identifier_resolution_rule = +{ + e_callable_identifier_resolution_paths, + ArrayCount(e_callable_identifier_resolution_paths), +}; + //////////////////////////////// //~ rjf: IR-ization Functions @@ -88,7 +160,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_IdentifierResolutionRule *identifier_resolution_rule, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 6493b55e..d6babada 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2661,7 +2661,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) E_IRNode *idxed_base_tree = &e_irnode_nil; if(base_ptr_tree != &e_irnode_nil) { - E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, expr->first->next); + E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, &e_default_identifier_resolution_rule, 0, 1, expr->first->next); E_IRNode *idx_root = e_irtree_resolve_to_value(arena, idx_irtree.mode, idx_irtree.root, idx_irtree.type_key); E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All)))); idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, base_ptr_tree, off_root); diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index cc199519..ba936b4b 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1952,6 +1952,12 @@ fancy_viz_eval_tests(void) Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; raddbg_pin(foo); + //- rjf: name collisions with debugger rules + Function_Few_Params_Type *raw = 0; + char *text = "some_important_text_here\n"; + Bitmap bitmap = foo; + int x3 = 0; + //- rjf: 3D geometry float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ... { @@ -2143,7 +2149,7 @@ fancy_viz_eval_tests(void) float *vtx = vertex_data; int vtx_size = sizeof vertex_data; raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size)); - int x3 = 0; + int x4 = 0; } //////////////////////////////// diff --git a/src/render/opengl/generated/render_opengl.meta.c b/src/render/opengl/generated/render_opengl.meta.c index 60c10194..7084ac1b 100644 --- a/src/render/opengl/generated/render_opengl.meta.c +++ b/src/render/opengl/generated/render_opengl.meta.c @@ -1,38 +1,38 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -C_LINKAGE_BEGIN -String8 r_ogl_shader_kind_name_table[2] = -{ -str8_lit_comp("rect"), -str8_lit_comp("blur"), -}; - -String8 * r_ogl_shader_kind_vshad_src_table[2] = -{ -&r_ogl_rect_vshad_src, -&r_ogl_blur_vshad_src, -}; - -String8 * r_ogl_shader_kind_pshad_src_table[2] = -{ -&r_ogl_rect_pshad_src, -&r_ogl_blur_pshad_src, -}; - -R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2] = -{ -{ r_ogl_rect_input_attributes, ArrayCount(r_ogl_rect_input_attributes) }, -{ 0, }, -}; - -R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2] = -{ -{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, -{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, -}; - -C_LINKAGE_END - +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//- GENERATED CODE + +C_LINKAGE_BEGIN +String8 r_ogl_shader_kind_name_table[2] = +{ +str8_lit_comp("rect"), +str8_lit_comp("blur"), +}; + +String8 * r_ogl_shader_kind_vshad_src_table[2] = +{ +&r_ogl_rect_vshad_src, +&r_ogl_blur_vshad_src, +}; + +String8 * r_ogl_shader_kind_pshad_src_table[2] = +{ +&r_ogl_rect_pshad_src, +&r_ogl_blur_pshad_src, +}; + +R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2] = +{ +{ r_ogl_rect_input_attributes, ArrayCount(r_ogl_rect_input_attributes) }, +{ 0, }, +}; + +R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2] = +{ +{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, +{ r_ogl_single_color_output_attributes, ArrayCount(r_ogl_single_color_output_attributes) }, +}; + +C_LINKAGE_END + diff --git a/src/render/opengl/generated/render_opengl.meta.h b/src/render/opengl/generated/render_opengl.meta.h index 6e7f6024..9f33f24d 100644 --- a/src/render/opengl/generated/render_opengl.meta.h +++ b/src/render/opengl/generated/render_opengl.meta.h @@ -1,276 +1,276 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -#ifndef RENDER_OPENGL_META_H -#define RENDER_OPENGL_META_H - -typedef enum R_OGL_ShaderKind -{ -R_OGL_ShaderKind_Rect, -R_OGL_ShaderKind_Blur, -R_OGL_ShaderKind_COUNT, -} R_OGL_ShaderKind; - -C_LINKAGE_BEGIN -extern String8 r_ogl_shader_kind_name_table[2]; -extern String8 * r_ogl_shader_kind_vshad_src_table[2]; -extern String8 * r_ogl_shader_kind_pshad_src_table[2]; -extern R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2]; -extern R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2]; -read_only global String8 r_ogl_rect_vshad_src = -str8_lit_comp( -"" -"\n" -"#version 330 core\n" -"\n" -"in vec4 c2v_dst_rect;\n" -"in vec4 c2v_src_rect;\n" -"in vec4 c2v_colors_0;\n" -"in vec4 c2v_colors_1;\n" -"in vec4 c2v_colors_2;\n" -"in vec4 c2v_colors_3;\n" -"in vec4 c2v_corner_radii;\n" -"in vec4 c2v_style; // x: border_thickness_px, y: softness_px, z: omit_texture, w: unused\n" -"\n" -"out vec2 v2p_sdf_sample_pos;\n" -"out vec2 v2p_texcoord_pct;\n" -"out vec2 v2p_rect_half_size_px;\n" -"out vec4 v2p_tint;\n" -"out float v2p_corner_radius;\n" -"out float v2p_border_thickness;\n" -"out float v2p_softness;\n" -"out float v2p_omit_texture;\n" -"\n" -"uniform sampler2D u_tex_color;\n" -"uniform vec2 u_viewport_size_px;\n" -"\n" -"void main(void)\n" -"{\n" -" // rjf: constants\n" -" vec2 vertices[] = vec2[](vec2(-1, -1), vec2(-1, +1), vec2(+1, -1), vec2(+1, +1));\n" -" \n" -" // rjf: find dst position\n" -" vec2 dst_half_size = (c2v_dst_rect.zw - c2v_dst_rect.xy) / 2;\n" -" vec2 dst_center = (c2v_dst_rect.zw + c2v_dst_rect.xy) / 2;\n" -" vec2 dst_position = vertices[gl_VertexID] * dst_half_size + dst_center;\n" -" \n" -" // rjf: find src position\n" -" vec2 src_half_size = (c2v_src_rect.zw - c2v_src_rect.xy) / 2;\n" -" vec2 src_center = (c2v_src_rect.zw + c2v_src_rect.xy) / 2;\n" -" vec2 src_position = vertices[gl_VertexID] * src_half_size + src_center;\n" -" \n" -" // rjf: find color\n" -" vec4 colors[] = vec4[](c2v_colors_0, c2v_colors_1, c2v_colors_2, c2v_colors_3);\n" -" vec4 color = colors[gl_VertexID];\n" -" \n" -" // rjf: find corner radius\n" -" float corner_radii[] = float[](c2v_corner_radii.x, c2v_corner_radii.y, c2v_corner_radii.z, c2v_corner_radii.w);\n" -" float corner_radius = corner_radii[gl_VertexID];\n" -" \n" -" // rjf: fill outputs\n" -" vec2 dst_verts_pct = vec2(((gl_VertexID >> 1) != 1) ? 1.f : 0.f,\n" -" ((gl_VertexID & 1) != 0) ? 0.f : 1.f);\n" -" ivec2 u_tex_color_size_i = textureSize(u_tex_color, 0);\n" -" vec2 u_tex_color_size = vec2(float(u_tex_color_size_i.x), float(u_tex_color_size_i.y));\n" -" {\n" -" gl_Position = vec4(2 * dst_position.x / u_viewport_size_px.x - 1,\n" -" 2 * (1 - dst_position.y / u_viewport_size_px.y) - 1,\n" -" 0.0, 1.0);\n" -" v2p_sdf_sample_pos = (2.f * dst_verts_pct - 1.f) * dst_half_size;\n" -" v2p_texcoord_pct = src_position / u_tex_color_size;\n" -" v2p_rect_half_size_px = dst_half_size;\n" -" v2p_tint = color;\n" -" v2p_corner_radius = corner_radius;\n" -" v2p_border_thickness = c2v_style.x;\n" -" v2p_softness = c2v_style.y;\n" -" v2p_omit_texture = c2v_style.z;\n" -" }\n" -"}\n" -"" -); - -read_only global String8 r_ogl_rect_pshad_src = -str8_lit_comp( -"" -"\n" -"#version 330 core\n" -"\n" -"in vec2 v2p_sdf_sample_pos;\n" -"in vec2 v2p_texcoord_pct;\n" -"in vec2 v2p_rect_half_size_px;\n" -"in vec4 v2p_tint;\n" -"in float v2p_corner_radius;\n" -"in float v2p_border_thickness;\n" -"in float v2p_softness;\n" -"in float v2p_omit_texture;\n" -"\n" -"out vec4 final_color;\n" -"\n" -"uniform float u_opacity;\n" -"uniform sampler2D u_tex_color;\n" -"uniform mat4 u_texture_sample_channel_map;\n" -"\n" -"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" -"{\n" -" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" -"}\n" -"\n" -"float linear_from_srgb_f32(float x)\n" -"{\n" -" return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);\n" -"}\n" -"\n" -"vec4 linear_from_srgba(vec4 v)\n" -"{\n" -" vec4 result = vec4(linear_from_srgb_f32(v.x),\n" -" linear_from_srgb_f32(v.y),\n" -" linear_from_srgb_f32(v.z),\n" -" v.w);\n" -" return result;\n" -"}\n" -"\n" -"void main(void)\n" -"{\n" -" // rjf: sample texture\n" -" vec4 albedo_sample = vec4(1, 1, 1, 1);\n" -" if(v2p_omit_texture < 1)\n" -" {\n" -" albedo_sample = u_texture_sample_channel_map * texture(u_tex_color, v2p_texcoord_pct);\n" -" albedo_sample = linear_from_srgba(albedo_sample);\n" -" }\n" -" \n" -" // rjf: sample for borders\n" -" float border_sdf_t = 1;\n" -" if(v2p_border_thickness > 0)\n" -" {\n" -" float border_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" -" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f) - v2p_border_thickness,\n" -" max(v2p_corner_radius-v2p_border_thickness, 0));\n" -" border_sdf_t = smoothstep(0, 2*v2p_softness, border_sdf_s);\n" -" }\n" -" if(border_sdf_t < 0.001f)\n" -" {\n" -" discard;\n" -" }\n" -" \n" -" // rjf: sample for corners\n" -" float corner_sdf_t = 1;\n" -" if(v2p_corner_radius > 0 || v2p_softness > 0.75f)\n" -" {\n" -" float corner_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" -" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f),\n" -" v2p_corner_radius);\n" -" corner_sdf_t = 1-smoothstep(0, 2*v2p_softness, corner_sdf_s);\n" -" }\n" -" \n" -" // rjf: form+return final color\n" -" final_color = albedo_sample;\n" -" final_color *= v2p_tint;\n" -" final_color.a *= u_opacity;\n" -" final_color.a *= corner_sdf_t;\n" -" final_color.a *= border_sdf_t;\n" -"}\n" -"" -); - -read_only global String8 r_ogl_blur_vshad_src = -str8_lit_comp( -"" -"\n" -"#version 330 core\n" -"\n" -"uniform vec4 rect;\n" -"uniform vec4 corner_radii_px;\n" -"uniform vec2 viewport_size;\n" -"uniform uint blur_count;\n" -"\n" -"out vec2 texcoord;\n" -"out vec2 sdf_sample_pos;\n" -"out vec2 rect_half_size;\n" -"out float corner_radius;\n" -"\n" -"void main(void)\n" -"{\n" -" vec2 vertex_positions_scrn[] = vec2[](rect.xw,\n" -" rect.xy,\n" -" rect.zw,\n" -" rect.zy);\n" -" float corner_radii_px[] = float[](corner_radii_px.y,\n" -" corner_radii_px.x,\n" -" corner_radii_px.w,\n" -" corner_radii_px.z);\n" -" vec2 cornercoords_pct = vec2((gl_VertexID >> 1) != 0 ? 1.f : 0.f,\n" -" (gl_VertexID & 1) != 0 ? 0.f : 1.f);\n" -" \n" -" vec2 vertex_position_pct = vertex_positions_scrn[gl_VertexID] / viewport_size;\n" -" vec2 vertex_position_scr = 2.f * vertex_position_pct - 1.f;\n" -" \n" -" vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2);\n" -" \n" -" gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f);\n" -" texcoord = vertex_position_pct;\n" -" sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size;\n" -" rect_half_size = rect_half_size - 2.f;\n" -" corner_radius = corner_radii_px[gl_VertexID];\n" -"}\n" -"" -); - -read_only global String8 r_ogl_blur_pshad_src = -str8_lit_comp( -"" -"\n" -"#version 330 core\n" -"\n" -"uniform sampler2D tex;\n" -"uniform vec4 kernel[32];\n" -"uniform int blur_count;\n" -"uniform vec2 direction;\n" -"\n" -"in vec2 texcoord;\n" -"in vec2 sdf_sample_pos;\n" -"in vec2 rect_half_size;\n" -"in float corner_radius;\n" -"\n" -"out vec4 final_color;\n" -"\n" -"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" -"{\n" -" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" -"}\n" -"\n" -"void main(void)\n" -"{\n" -" // rjf: blend weighted texture samples into color\n" -" vec3 color = kernel[0].x * texture(tex, texcoord).rgb;\n" -" \n" -" for(int i = 1; i < blur_count; i += 1)\n" -" {\n" -" float weight = kernel[i].x;\n" -" float offset = kernel[i].y;\n" -" color += weight * texture(tex, texcoord - offset * direction).rgb;\n" -" color += weight * texture(tex, texcoord + offset * direction).rgb;\n" -" }\n" -" \n" -" // rjf: sample for corners\n" -" float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius);\n" -" float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s);\n" -" \n" -" // rjf: weight output color by sdf\n" -" // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n" -" if(corner_sdf_t < 0.9f)\n" -" {\n" -" discard;\n" -" }\n" -" \n" -" final_color = vec4(color, 1.f);\n" -"}\n" -"" -); - - -C_LINKAGE_END - -#endif // RENDER_OPENGL_META_H +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//- GENERATED CODE + +#ifndef RENDER_OPENGL_META_H +#define RENDER_OPENGL_META_H + +typedef enum R_OGL_ShaderKind +{ +R_OGL_ShaderKind_Rect, +R_OGL_ShaderKind_Blur, +R_OGL_ShaderKind_COUNT, +} R_OGL_ShaderKind; + +C_LINKAGE_BEGIN +extern String8 r_ogl_shader_kind_name_table[2]; +extern String8 * r_ogl_shader_kind_vshad_src_table[2]; +extern String8 * r_ogl_shader_kind_pshad_src_table[2]; +extern R_OGL_AttributeArray r_ogl_shader_kind_input_attributes_table[2]; +extern R_OGL_AttributeArray r_ogl_shader_kind_output_attributes_table[2]; +read_only global String8 r_ogl_rect_vshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"in vec4 c2v_dst_rect;\n" +"in vec4 c2v_src_rect;\n" +"in vec4 c2v_colors_0;\n" +"in vec4 c2v_colors_1;\n" +"in vec4 c2v_colors_2;\n" +"in vec4 c2v_colors_3;\n" +"in vec4 c2v_corner_radii;\n" +"in vec4 c2v_style; // x: border_thickness_px, y: softness_px, z: omit_texture, w: unused\n" +"\n" +"out vec2 v2p_sdf_sample_pos;\n" +"out vec2 v2p_texcoord_pct;\n" +"out vec2 v2p_rect_half_size_px;\n" +"out vec4 v2p_tint;\n" +"out float v2p_corner_radius;\n" +"out float v2p_border_thickness;\n" +"out float v2p_softness;\n" +"out float v2p_omit_texture;\n" +"\n" +"uniform sampler2D u_tex_color;\n" +"uniform vec2 u_viewport_size_px;\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: constants\n" +" vec2 vertices[] = vec2[](vec2(-1, -1), vec2(-1, +1), vec2(+1, -1), vec2(+1, +1));\n" +" \n" +" // rjf: find dst position\n" +" vec2 dst_half_size = (c2v_dst_rect.zw - c2v_dst_rect.xy) / 2;\n" +" vec2 dst_center = (c2v_dst_rect.zw + c2v_dst_rect.xy) / 2;\n" +" vec2 dst_position = vertices[gl_VertexID] * dst_half_size + dst_center;\n" +" \n" +" // rjf: find src position\n" +" vec2 src_half_size = (c2v_src_rect.zw - c2v_src_rect.xy) / 2;\n" +" vec2 src_center = (c2v_src_rect.zw + c2v_src_rect.xy) / 2;\n" +" vec2 src_position = vertices[gl_VertexID] * src_half_size + src_center;\n" +" \n" +" // rjf: find color\n" +" vec4 colors[] = vec4[](c2v_colors_0, c2v_colors_1, c2v_colors_2, c2v_colors_3);\n" +" vec4 color = colors[gl_VertexID];\n" +" \n" +" // rjf: find corner radius\n" +" float corner_radii[] = float[](c2v_corner_radii.x, c2v_corner_radii.y, c2v_corner_radii.z, c2v_corner_radii.w);\n" +" float corner_radius = corner_radii[gl_VertexID];\n" +" \n" +" // rjf: fill outputs\n" +" vec2 dst_verts_pct = vec2(((gl_VertexID >> 1) != 1) ? 1.f : 0.f,\n" +" ((gl_VertexID & 1) != 0) ? 0.f : 1.f);\n" +" ivec2 u_tex_color_size_i = textureSize(u_tex_color, 0);\n" +" vec2 u_tex_color_size = vec2(float(u_tex_color_size_i.x), float(u_tex_color_size_i.y));\n" +" {\n" +" gl_Position = vec4(2 * dst_position.x / u_viewport_size_px.x - 1,\n" +" 2 * (1 - dst_position.y / u_viewport_size_px.y) - 1,\n" +" 0.0, 1.0);\n" +" v2p_sdf_sample_pos = (2.f * dst_verts_pct - 1.f) * dst_half_size;\n" +" v2p_texcoord_pct = src_position / u_tex_color_size;\n" +" v2p_rect_half_size_px = dst_half_size;\n" +" v2p_tint = color;\n" +" v2p_corner_radius = corner_radius;\n" +" v2p_border_thickness = c2v_style.x;\n" +" v2p_softness = c2v_style.y;\n" +" v2p_omit_texture = c2v_style.z;\n" +" }\n" +"}\n" +"" +); + +read_only global String8 r_ogl_rect_pshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"in vec2 v2p_sdf_sample_pos;\n" +"in vec2 v2p_texcoord_pct;\n" +"in vec2 v2p_rect_half_size_px;\n" +"in vec4 v2p_tint;\n" +"in float v2p_corner_radius;\n" +"in float v2p_border_thickness;\n" +"in float v2p_softness;\n" +"in float v2p_omit_texture;\n" +"\n" +"out vec4 final_color;\n" +"\n" +"uniform float u_opacity;\n" +"uniform sampler2D u_tex_color;\n" +"uniform mat4 u_texture_sample_channel_map;\n" +"\n" +"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" +"{\n" +" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" +"}\n" +"\n" +"float linear_from_srgb_f32(float x)\n" +"{\n" +" return x < 0.0404482362771082 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);\n" +"}\n" +"\n" +"vec4 linear_from_srgba(vec4 v)\n" +"{\n" +" vec4 result = vec4(linear_from_srgb_f32(v.x),\n" +" linear_from_srgb_f32(v.y),\n" +" linear_from_srgb_f32(v.z),\n" +" v.w);\n" +" return result;\n" +"}\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: sample texture\n" +" vec4 albedo_sample = vec4(1, 1, 1, 1);\n" +" if(v2p_omit_texture < 1)\n" +" {\n" +" albedo_sample = u_texture_sample_channel_map * texture(u_tex_color, v2p_texcoord_pct);\n" +" albedo_sample = linear_from_srgba(albedo_sample);\n" +" }\n" +" \n" +" // rjf: sample for borders\n" +" float border_sdf_t = 1;\n" +" if(v2p_border_thickness > 0)\n" +" {\n" +" float border_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" +" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f) - v2p_border_thickness,\n" +" max(v2p_corner_radius-v2p_border_thickness, 0));\n" +" border_sdf_t = smoothstep(0, 2*v2p_softness, border_sdf_s);\n" +" }\n" +" if(border_sdf_t < 0.001f)\n" +" {\n" +" discard;\n" +" }\n" +" \n" +" // rjf: sample for corners\n" +" float corner_sdf_t = 1;\n" +" if(v2p_corner_radius > 0 || v2p_softness > 0.75f)\n" +" {\n" +" float corner_sdf_s = rect_sdf(v2p_sdf_sample_pos,\n" +" v2p_rect_half_size_px - vec2(v2p_softness*2.f, v2p_softness*2.f),\n" +" v2p_corner_radius);\n" +" corner_sdf_t = 1-smoothstep(0, 2*v2p_softness, corner_sdf_s);\n" +" }\n" +" \n" +" // rjf: form+return final color\n" +" final_color = albedo_sample;\n" +" final_color *= v2p_tint;\n" +" final_color.a *= u_opacity;\n" +" final_color.a *= corner_sdf_t;\n" +" final_color.a *= border_sdf_t;\n" +"}\n" +"" +); + +read_only global String8 r_ogl_blur_vshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"uniform vec4 rect;\n" +"uniform vec4 corner_radii_px;\n" +"uniform vec2 viewport_size;\n" +"uniform uint blur_count;\n" +"\n" +"out vec2 texcoord;\n" +"out vec2 sdf_sample_pos;\n" +"out vec2 rect_half_size;\n" +"out float corner_radius;\n" +"\n" +"void main(void)\n" +"{\n" +" vec2 vertex_positions_scrn[] = vec2[](rect.xw,\n" +" rect.xy,\n" +" rect.zw,\n" +" rect.zy);\n" +" float corner_radii_px[] = float[](corner_radii_px.y,\n" +" corner_radii_px.x,\n" +" corner_radii_px.w,\n" +" corner_radii_px.z);\n" +" vec2 cornercoords_pct = vec2((gl_VertexID >> 1) != 0 ? 1.f : 0.f,\n" +" (gl_VertexID & 1) != 0 ? 0.f : 1.f);\n" +" \n" +" vec2 vertex_position_pct = vertex_positions_scrn[gl_VertexID] / viewport_size;\n" +" vec2 vertex_position_scr = 2.f * vertex_position_pct - 1.f;\n" +" \n" +" vec2 rect_half_size = vec2((rect.z-rect.x)/2, (rect.w-rect.y)/2);\n" +" \n" +" gl_Position = vec4(vertex_position_scr.x, -vertex_position_scr.y, 0.f, 1.f);\n" +" texcoord = vertex_position_pct;\n" +" sdf_sample_pos = (2.f * cornercoords_pct - 1.f) * rect_half_size;\n" +" rect_half_size = rect_half_size - 2.f;\n" +" corner_radius = corner_radii_px[gl_VertexID];\n" +"}\n" +"" +); + +read_only global String8 r_ogl_blur_pshad_src = +str8_lit_comp( +"" +"\n" +"#version 330 core\n" +"\n" +"uniform sampler2D tex;\n" +"uniform vec4 kernel[32];\n" +"uniform int blur_count;\n" +"uniform vec2 direction;\n" +"\n" +"in vec2 texcoord;\n" +"in vec2 sdf_sample_pos;\n" +"in vec2 rect_half_size;\n" +"in float corner_radius;\n" +"\n" +"out vec4 final_color;\n" +"\n" +"float rect_sdf(vec2 sample_pos, vec2 rect_half_size, float r)\n" +"{\n" +" return length(max(abs(sample_pos) - rect_half_size + r, 0.0)) - r;\n" +"}\n" +"\n" +"void main(void)\n" +"{\n" +" // rjf: blend weighted texture samples into color\n" +" vec3 color = kernel[0].x * texture(tex, texcoord).rgb;\n" +" \n" +" for(int i = 1; i < blur_count; i += 1)\n" +" {\n" +" float weight = kernel[i].x;\n" +" float offset = kernel[i].y;\n" +" color += weight * texture(tex, texcoord - offset * direction).rgb;\n" +" color += weight * texture(tex, texcoord + offset * direction).rgb;\n" +" }\n" +" \n" +" // rjf: sample for corners\n" +" float corner_sdf_s = rect_sdf(sdf_sample_pos, rect_half_size, corner_radius);\n" +" float corner_sdf_t = 1-smoothstep(0, 2, corner_sdf_s);\n" +" \n" +" // rjf: weight output color by sdf\n" +" // this is doing alpha testing, leave blurring only where mostly opaque pixels are\n" +" if(corner_sdf_t < 0.9f)\n" +" {\n" +" discard;\n" +" }\n" +" \n" +" final_color = vec4(color, 1.f);\n" +"}\n" +"" +); + + +C_LINKAGE_END + +#endif // RENDER_OPENGL_META_H From a5b227a1c63d87aea71ddd911030c7cb1da832ff Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 16:03:36 -0700 Subject: [PATCH 677/755] egl/glx work; eliminate unneeded path normalization paths; do not assume os current path when normalizing paths; gl synchronous debug strings --- src/base/base_strings.c | 124 +++++++++++------- src/base/base_strings.h | 16 ++- src/ctrl/ctrl_core.c | 2 +- src/os/core/win32/os_core_win32.c | 2 +- src/os/gfx/linux/os_gfx_linux.c | 19 ++- src/os/gfx/linux/os_gfx_linux.h | 2 + src/os/gfx/win32/os_gfx_win32.c | 2 + src/os/gfx/win32/os_gfx_win32.h | 1 + src/path/path.c | 109 +++++++-------- src/path/path.h | 16 +-- src/raddbg/raddbg_core.c | 53 +++----- src/raddbg/raddbg_legacy_config.c | 17 +-- src/raddbg/raddbg_main.c | 2 +- src/raddbg/raddbg_views.c | 2 +- src/rdi_from_pdb/rdi_from_pdb.c | 12 +- .../linux/egl/render_opengl_linux_egl.c | 36 ++++- .../linux/glx/render_opengl_linux_glx.c | 6 +- src/render/opengl/render_opengl.c | 2 +- src/render/opengl/render_opengl.h | 1 + src/render/opengl/win32/render_opengl_win32.c | 11 +- 20 files changed, 230 insertions(+), 205 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index b51e70fc..2a9a096e 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1226,40 +1226,51 @@ str8_from_version(Arena *arena, U64 version) //~ rjf: String Path Helpers internal String8 -str8_chop_last_slash(String8 string){ - if (string.size > 0){ +str8_chop_last_slash(String8 string) +{ + if(string.size > 0) + { U8 *ptr = string.str + string.size - 1; - for (;ptr >= string.str; ptr -= 1){ - if (*ptr == '/' || *ptr == '\\'){ + for(;ptr >= string.str; ptr -= 1) + { + if(*ptr == '/' || *ptr == '\\') + { break; } } - if (ptr >= string.str){ + if(ptr >= string.str) + { string.size = (U64)(ptr - string.str); } - else{ + else + { string.size = 0; } } - return(string); + return string; } internal String8 -str8_skip_last_slash(String8 string){ - if (string.size > 0){ +str8_skip_last_slash(String8 string) +{ + if(string.size > 0) + { U8 *ptr = string.str + string.size - 1; - for (;ptr >= string.str; ptr -= 1){ - if (*ptr == '/' || *ptr == '\\'){ + for(;ptr >= string.str; ptr -= 1) + { + if(*ptr == '/' || *ptr == '\\') + { break; } } - if (ptr >= string.str){ + if(ptr >= string.str) + { ptr += 1; string.size = (U64)(string.str + string.size - ptr); string.str = ptr; } } - return(string); + return string; } internal String8 @@ -1267,80 +1278,94 @@ str8_chop_last_dot(String8 string) { String8 result = string; U64 p = string.size; - for (;p > 0;){ + for(;p > 0;) + { p -= 1; - if (string.str[p] == '.'){ + if(string.str[p] == '.') + { result = str8_prefix(string, p); break; } } - return(result); + return result; } internal String8 -str8_skip_last_dot(String8 string){ +str8_skip_last_dot(String8 string) +{ String8 result = string; U64 p = string.size; - for (;p > 0;){ + for(;p > 0;) + { p -= 1; - if (string.str[p] == '.'){ + if(string.str[p] == '.') + { result = str8_skip(string, p + 1); break; } } - return(result); + return result; } internal PathStyle -path_style_from_str8(String8 string){ +path_style_from_str8(String8 string) +{ PathStyle result = PathStyle_Relative; - if (string.size >= 1 && string.str[0] == '/'){ + if(string.size >= 1 && string.str[0] == '/') + { result = PathStyle_UnixAbsolute; } - else if (string.size >= 2 && - char_is_alpha(string.str[0]) && - string.str[1] == ':'){ - if (string.size == 2 || - char_is_slash(string.str[2])){ + else if(string.size >= 2 && + char_is_alpha(string.str[0]) && + string.str[1] == ':') + { + if(string.size == 2 || char_is_slash(string.str[2])) + { result = PathStyle_WindowsAbsolute; } } - return(result); + return result; } internal String8List -str8_split_path(Arena *arena, String8 string){ +str8_split_path(Arena *arena, String8 string) +{ String8List result = str8_split(arena, string, (U8*)"/\\", 2, 0); - return(result); + return result; } internal void -str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ +str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style) +{ Temp scratch = scratch_begin(0, 0); - String8MetaNode *stack = 0; String8MetaNode *free_meta_node = 0; String8Node *first = path->first; - MemoryZeroStruct(path); - for (String8Node *node = first, *next = 0; - node != 0; - node = next){ + for(String8Node *node = first, *next = 0; + node != 0; + node = next) + { // save next now next = node->next; // cases: - if (node == first && style == PathStyle_WindowsAbsolute){ + if(node == first && style == PathStyle_WindowsAbsolute) + { goto save_without_stack; } - if (node->string.size == 1 && node->string.str[0] == '.'){ + if(node->string.size == 1 && node->string.str[0] == '.') + { goto do_nothing; } - if (node->string.size == 2 && node->string.str[0] == '.' && node->string.str[1] == '.'){ - if (stack != 0){ + if(node->string.size == 2 && node->string.str[0] == '.' && node->string.str[1] == '.') + { + if(stack != 0) + { goto eliminate_stack_top; } - else{ + else + { goto save_without_stack; } } @@ -1351,24 +1376,23 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ save_with_stack: { str8_list_push_node(path, node); - String8MetaNode *stack_node = free_meta_node; - if (stack_node != 0){ + if(stack_node != 0) + { SLLStackPop(free_meta_node); } - else{ + else + { stack_node = push_array_no_zero(scratch.arena, String8MetaNode, 1); } SLLStackPush(stack, stack_node); stack_node->node = node; - continue; } save_without_stack: { str8_list_push_node(path, node); - continue; } @@ -1376,13 +1400,13 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ { path->node_count -= 1; path->total_size -= stack->node->string.size; - SLLStackPop(stack); - - if (stack == 0){ + if(stack == 0) + { path->last = path->first; } - else{ + else + { path->last = stack->node; } continue; diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 06c7bbfc..b9b155ee 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -96,7 +96,7 @@ typedef enum PathStyle #elif OS_LINUX PathStyle_SystemAbsolute = PathStyle_UnixAbsolute #else -# error "absolute path style is undefined for this OS" +# error Absolute path style is undefined for this OS. #endif } PathStyle; @@ -302,6 +302,20 @@ internal String8 str8_from_version(Arena *arena, U64 version); //////////////////////////////// //~ rjf: String Path Helpers +global read_only struct +{ + String8 string; + PathStyle path_style; +} +g_path_style_map[] = +{ + { str8_lit_comp(""), PathStyle_Null }, + { str8_lit_comp("relative"), PathStyle_Relative }, + { str8_lit_comp("windows"), PathStyle_WindowsAbsolute }, + { str8_lit_comp("unix"), PathStyle_UnixAbsolute }, + { str8_lit_comp("system"), PathStyle_SystemAbsolute }, +}; + internal String8 str8_chop_last_slash(String8 string); internal String8 str8_skip_last_slash(String8 string); internal String8 str8_chop_last_dot(String8 string); diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index b3d477d1..9ad6dd4f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3989,7 +3989,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ FileProperties props = os_properties_from_file_path(candidate_path); if(props.modified != 0 && props.size != 0) { - initial_debug_info_path = push_str8_copy(arena, candidate_path); + initial_debug_info_path = push_str8_copy(arena, path_normalized_from_string(scratch.arena, candidate_path)); break; } } diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 94d994b4..f49e7418 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -712,7 +712,7 @@ os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags) } else { - w32_iter->handle = FindFirstFileW((WCHAR*)path16.str, &w32_iter->find_data); + w32_iter->handle = FindFirstFileExW((WCHAR*)path16.str, FindExInfoBasic, &w32_iter->find_data, FindExSearchNameMatch, 0, FIND_FIRST_EX_LARGE_FETCH); } scratch_end(scratch); return iter; diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index a125f5c3..9a473ea9 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -1,11 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: Prototypes (which seem to sometimes be missing) - -int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out); - //////////////////////////////// //~ rjf: Helpers @@ -41,6 +36,9 @@ os_gfx_init(void) os_lnx_gfx_state->wm_sync_request_atom = XInternAtom(os_lnx_gfx_state->display, "_NET_WM_SYNC_REQUEST", 0); os_lnx_gfx_state->wm_sync_request_counter_atom = XInternAtom(os_lnx_gfx_state->display, "_NET_WM_SYNC_REQUEST_COUNTER", 0); + //- rjf: open im + os_lnx_gfx_state->xim = XOpenIM(os_lnx_gfx_state->display, 0, 0, 0); + //- rjf: fill out gfx info os_lnx_gfx_state->gfx_info.double_click_time = 0.5f; os_lnx_gfx_state->gfx_info.caret_blink_time = 0.5f; @@ -149,6 +147,13 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) } XChangeProperty(os_lnx_gfx_state->display, w->window, os_lnx_gfx_state->wm_sync_request_counter_atom, XA_CARDINAL, 32, PropModeReplace, (U8 *)&w->counter_xid, 1); + //- rjf: create xic + w->xic = XCreateIC(os_lnx_gfx_state->xim, + XNInputStyle, XIMPreeditNothing|XIMStatusNothing, + XNClientWindow, w->window, + XNFocusWindow, w->window, + NULL); + //- rjf: attach name Temp scratch = scratch_begin(0, 0); String8 title_copy = push_str8_copy(scratch.arena, title); @@ -399,9 +404,10 @@ os_get_events(Arena *arena, B32 wait) if(evt.xkey.state & Mod1Mask) { modifiers |= OS_Modifier_Alt; } // rjf: map keycode -> keysym & codepoint + OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xkey.window); KeySym keysym = 0; U8 text[256] = {0}; - U64 text_size = XLookupString(&evt.xkey, (char *)text, sizeof(text), &keysym, 0); + U64 text_size = Xutf8LookupString(window->xic, &evt.xkey, (char *)text, sizeof(text), &keysym, 0); // rjf: map keysym -> OS_Key B32 is_right_sided = 0; @@ -475,7 +481,6 @@ os_get_events(Arena *arena, B32 wait) } // rjf: push text event - OS_LNX_Window *window = os_lnx_window_from_x11window(evt.xkey.window); if(evt.type == KeyPress && text_size != 0) { for(U64 off = 0; off < text_size;) diff --git a/src/os/gfx/linux/os_gfx_linux.h b/src/os/gfx/linux/os_gfx_linux.h index 96341575..b0e23df2 100644 --- a/src/os/gfx/linux/os_gfx_linux.h +++ b/src/os/gfx/linux/os_gfx_linux.h @@ -23,6 +23,7 @@ struct OS_LNX_Window OS_LNX_Window *next; OS_LNX_Window *prev; Window window; + XIC xic; XID counter_xid; U64 counter_value; }; @@ -35,6 +36,7 @@ struct OS_LNX_GfxState { Arena *arena; Display *display; + XIM xim; OS_LNX_Window *first_window; OS_LNX_Window *last_window; OS_LNX_Window *free_window; diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 7d04f2c2..8caf11fd 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -95,6 +95,7 @@ os_w32_window_release(OS_W32_Window *window) { arena_release(window->paint_arena); } + ReleaseDC(window->hwnd, window->hdc); DestroyWindow(window->hwnd); DLLRemove(os_w32_gfx_state->first_window, os_w32_gfx_state->last_window, window); SLLStackPush(os_w32_gfx_state->free_window, window); @@ -1056,6 +1057,7 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title) OS_W32_Window *window = os_w32_window_alloc(); { window->hwnd = hwnd; + window->hdc = GetDC(hwnd); if(w32_GetDpiForWindow_func != 0) { window->dpi = (F32)w32_GetDpiForWindow_func(hwnd); diff --git a/src/os/gfx/win32/os_gfx_win32.h b/src/os/gfx/win32/os_gfx_win32.h index d47c4df4..78d0daaa 100644 --- a/src/os/gfx/win32/os_gfx_win32.h +++ b/src/os/gfx/win32/os_gfx_win32.h @@ -38,6 +38,7 @@ struct OS_W32_Window OS_W32_Window *next; OS_W32_Window *prev; HWND hwnd; + HDC hdc; WINDOWPLACEMENT last_window_placement; F32 dpi; B32 first_paint_done; diff --git a/src/path/path.c b/src/path/path.c index a6b79995..72d2c710 100644 --- a/src/path/path.c +++ b/src/path/path.c @@ -1,6 +1,9 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: Relative <-> Absolute Path + internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src) { @@ -8,7 +11,7 @@ path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src) // rjf: gather path parts String8 dst_name = str8_skip_last_slash(dst); - String8 src_folder = str8_chop_last_slash(src); + String8 src_folder = src; String8 dst_folder = str8_chop_last_slash(dst); String8List src_folders = str8_split_path(scratch.arena, src_folder); String8List dst_folders = str8_split_path(scratch.arena, dst_folder); @@ -35,7 +38,7 @@ path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src) String8 dst_path = {0}; if(num_backtracks >= src_folders.node_count) { - dst_path = path_normalized_from_string(arena, dst); + dst_path = dst; } else { @@ -90,54 +93,43 @@ path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src) if(dst_style == PathStyle_Relative) { Temp scratch = scratch_begin(&arena, 1); - String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", str8_chop_last_slash(src), dst); - String8 dst_from_src_absolute_normalized = path_normalized_from_string(arena, dst_from_src_absolute); - result = dst_from_src_absolute_normalized; + String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", src, dst); + String8List dst_from_src_absolute_parts = str8_split_path(scratch.arena, dst_from_src_absolute); + PathStyle dst_from_src_absolute_style = path_style_from_str8(src); + str8_path_list_resolve_dots_in_place(&dst_from_src_absolute_parts, dst_from_src_absolute_style); + result = str8_path_list_join_by_style(arena, &dst_from_src_absolute_parts, dst_from_src_absolute_style); scratch_end(scratch); } return result; } +//////////////////////////////// +//~ rjf: Path Normalization + internal String8List path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *style_out) { - // analyze path + // rjf: analyze path PathStyle path_style = path_style_from_str8(path_string); String8List path = str8_split_path(arena, path_string); - // prepend current path to convert relative -> absolute - PathStyle path_style_full = path_style; - if(path.node_count != 0 && path_style == PathStyle_Relative) - { - String8 current_path_string = os_get_current_path(arena); - - PathStyle current_path_style = path_style_from_str8(current_path_string); - Assert(current_path_style != PathStyle_Relative); - - String8List current_path = str8_split_path(arena, current_path_string); - str8_list_concat_in_place(¤t_path, &path); - path = current_path; - path_style_full = current_path_style; - } + // rjf: resolve dots + str8_path_list_resolve_dots_in_place(&path, path_style); - // resolve dots - str8_path_list_resolve_dots_in_place(&path, path_style_full); - - // return + // rjf: return if(style_out != 0) { - *style_out = path_style_full; + *style_out = path_style; } return path; } internal String8 -path_normalized_from_string(Arena *arena, String8 path_string){ +path_normalized_from_string(Arena *arena, String8 path_string) +{ Temp scratch = scratch_begin(&arena, 1); - PathStyle style = PathStyle_Relative; String8List path = path_normalized_list_from_string(scratch.arena, path_string, &style); - String8 result = str8_path_list_join_by_style(arena, &path, style); scratch_end(scratch); return result; @@ -154,8 +146,31 @@ path_match_normalized(String8 left, String8 right) return result; } +//////////////////////////////// +//~ rjf: Basic Helpers + +internal PathStyle +path_style_from_string(String8 string) +{ + for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i) + { + if(str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive)) + { + return g_path_style_map[i].path_style; + } + } + return PathStyle_Null; +} + internal String8 -path_char_from_style(PathStyle style) +string_from_path_style(PathStyle style) +{ + Assert(style < ArrayCount(g_path_style_map)); + return g_path_style_map[style].string; +} + +internal String8 +path_separator_string_from_style(PathStyle style) { String8 result = str8_zero(); switch (style) @@ -194,7 +209,7 @@ path_convert_slashes(Arena *arena, String8 path, PathStyle path_style) Temp scratch = scratch_begin(&arena, 1); String8List list = str8_split_path(scratch.arena, path); StringJoin join = {0}; - join.sep = path_char_from_style(path_style); + join.sep = path_separator_string_from_style(path_style); String8 result = str8_list_join(arena, &list, &join); scratch_end(scratch); return result; @@ -207,37 +222,3 @@ path_replace_file_extension(Arena *arena, String8 file_name, String8 ext) String8 result = push_str8f(arena, "%S.%S", file_name_no_ext, ext); return result; } - -global read_only struct -{ - String8 string; - PathStyle path_style; -} g_path_style_map[] = -{ - { str8_lit_comp(""), PathStyle_Null }, - { str8_lit_comp("relative"), PathStyle_Relative }, - { str8_lit_comp("windows"), PathStyle_WindowsAbsolute }, - { str8_lit_comp("unix"), PathStyle_UnixAbsolute }, - { str8_lit_comp("system"), PathStyle_SystemAbsolute }, -}; - -internal PathStyle -path_style_from_string(String8 string) -{ - for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i) - { - if(str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive)) - { - return g_path_style_map[i].path_style; - } - } - return PathStyle_Null; -} - -internal String8 -path_string_from_style(PathStyle style) -{ - Assert(style < ArrayCount(g_path_style_map)); - return g_path_style_map[style].string; -} - diff --git a/src/path/path.h b/src/path/path.h index c6ae12da..0aa18ec2 100644 --- a/src/path/path.h +++ b/src/path/path.h @@ -5,30 +5,26 @@ #define PATH_H //////////////////////////////// -// Relative <-> Absolute Path +//~ rjf: Relative <-> Absolute Path internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src); internal String8 path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src); //////////////////////////////// -// Normal Path Helpers +//~ rjf: Path Normalization internal String8List path_normalized_list_from_string(Arena *arena, String8 path, PathStyle *style_out); internal String8 path_normalized_from_string(Arena *arena, String8 path); internal B32 path_match_normalized(String8 left, String8 right); //////////////////////////////// -// Misc Helpers +//~ rjf: Basic Helpers -internal String8 path_char_from_style(PathStyle style); +internal PathStyle path_style_from_string(String8 string); +internal String8 string_from_path_style(PathStyle style); +internal String8 path_separator_string_from_style(PathStyle style); internal StringMatchFlags path_match_flags_from_os(OperatingSystem os); internal String8 path_convert_slashes(Arena *arena, String8 path, PathStyle path_style); internal String8 path_replace_file_extension(Arena *arena, String8 file_name, String8 ext); -//////////////////////////////// -// Enum <-> String - -internal PathStyle path_style_from_string(String8 string); -internal String8 path_string_from_style(PathStyle style); - #endif //PATH_H diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 9d5855ec..b0fedcee 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1489,8 +1489,7 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) String8 result = file_path; if(file_path.size != 0) { - String8 file_path__normalized = path_normalized_from_string(scratch.arena, file_path); - String8List file_path_parts = str8_split_path(scratch.arena, file_path__normalized); + String8List file_path_parts = str8_split_path(scratch.arena, file_path); RD_CfgList maps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); String8 best_map_dst = {0}; U64 best_map_match_length = max_U64; @@ -1498,8 +1497,7 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) for(RD_CfgNode *n = maps.first; n != 0; n = n->next) { String8 map_src = rd_cfg_child_from_string(n->v, str8_lit("source"))->first->string; - String8 map_src__normalized = path_normalized_from_string(scratch.arena, map_src); - String8List map_src_parts = str8_split_path(scratch.arena, map_src__normalized); + String8List map_src_parts = str8_split_path(scratch.arena, map_src); B32 matches = 1; U64 match_length = 0; String8Node *file_path_part_n = file_path_parts.first; @@ -1523,8 +1521,7 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) } if(best_map_dst.size != 0) { - String8 best_map_dst__normalized = path_normalized_from_string(scratch.arena, best_map_dst); - String8List best_map_dst_parts = str8_split_path(scratch.arena, best_map_dst__normalized); + String8List best_map_dst_parts = str8_split_path(scratch.arena, best_map_dst); for(String8Node *n = best_map_remaining_suffix_first; n != 0; n = n->next) { str8_list_push(scratch.arena, &best_map_dst_parts, n->string); @@ -1532,10 +1529,6 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) StringJoin join = {.sep = str8_lit("/")}; result = str8_list_join(arena, &best_map_dst_parts, &join); } - else - { - result = path_normalized_from_string(arena, result); - } } scratch_end(scratch); return result; @@ -9263,7 +9256,7 @@ rd_window_frame(void) for(String8Node *n = evt->paths.first; n != 0; n = n->next) { Temp scratch = scratch_begin(0, 0); - String8 path = path_normalized_from_string(scratch.arena, n->string); + String8 path = n->string; if(str8_match(str8_skip_last_dot(path), str8_lit("exe"), StringMatchFlag_CaseInsensitive)) { str8_list_push(ws->drop_completion_arena, &ws->drop_completion_paths, push_str8_copy(ws->drop_completion_arena, path)); @@ -10897,14 +10890,13 @@ rd_init(CmdLine *cmdln) String8 user_path = cmd_line_string(cmdln, str8_lit("user")); String8 project_path = cmd_line_string(cmdln, str8_lit("project")); { - String8 initial_path = push_str8f(scratch.arena, "%S/", os_get_process_info()->initial_path); if(user_path.size != 0) { - user_path = path_absolute_dst_from_relative_dst_src(scratch.arena, user_path, initial_path); + user_path = path_absolute_dst_from_relative_dst_src(scratch.arena, user_path, os_get_process_info()->initial_path); } if(project_path.size != 0) { - project_path = path_absolute_dst_from_relative_dst_src(scratch.arena, project_path, initial_path); + project_path = path_absolute_dst_from_relative_dst_src(scratch.arena, project_path, os_get_process_info()->initial_path); } } { @@ -12857,7 +12849,7 @@ rd_frame(void) } else { - file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, file_path, file_data); + file_cfg_list = rd_cfg_tree_list_from_string(scratch.arena, str8_chop_last_slash(file_path), file_data); } } @@ -12956,7 +12948,7 @@ rd_frame(void) { recent_project = rd_cfg_new(user, str8_lit("recent_project")); RD_Cfg *path_root = rd_cfg_new(recent_project, str8_lit("path")); - rd_cfg_new(path_root, path_normalized_from_string(scratch.arena, file_path)); + rd_cfg_new(path_root, path_absolute_dst_from_relative_dst_src(scratch.arena, file_path, str8_chop_last_slash(rd_state->user_path))); } rd_cfg_unhook(user, recent_project); rd_cfg_insert_child(user, &rd_nil_cfg, recent_project); @@ -13102,7 +13094,7 @@ rd_frame(void) str8_list_pushf(scratch.arena, &strings, "// raddbg %s %S file\n\n", BUILD_VERSION_STRING_LITERAL, bucket_name); for(RD_Cfg *child = tree_root->first; child != &rd_nil_cfg; child = child->next) { - str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, child)); + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, str8_chop_last_slash(dst_path), child)); } String8 data = str8_list_join(scratch.arena, &strings, 0); B32 temp_write_good = os_write_data_to_file_path(temp_path, data); @@ -13496,10 +13488,8 @@ rd_frame(void) //- rjf: unpack String8 src_path = rd_regs()->string; String8 dst_path = rd_regs()->file_path; - String8 src_path__normalized = path_normalized_from_string(scratch.arena, src_path); - String8 dst_path__normalized = path_normalized_from_string(scratch.arena, dst_path); - String8List src_path_parts = str8_split_path(scratch.arena, src_path__normalized); - String8List dst_path_parts = str8_split_path(scratch.arena, dst_path__normalized); + String8List src_path_parts = str8_split_path(scratch.arena, src_path); + String8List dst_path_parts = str8_split_path(scratch.arena, dst_path); //- rjf: reverse path parts String8List src_path_parts__reversed = {0}; @@ -13918,7 +13908,7 @@ rd_frame(void) //- rjf: files case RD_CmdKind_Open: { - String8 path = rd_regs()->file_path; + String8 path = path_absolute_dst_from_relative_dst_src(scratch.arena, rd_regs()->file_path, os_get_current_path(scratch.arena)); FileProperties props = os_properties_from_file_path(path); if(props.created != 0) { @@ -13940,10 +13930,9 @@ rd_frame(void) case RD_CmdKind_SwitchToPartnerFile: { String8 file_path = rd_regs()->file_path; - String8 file_full_path = path_normalized_from_string(scratch.arena, file_path); - String8 file_folder = str8_chop_last_slash(file_full_path); - String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_full_path)); - String8 file_ext = str8_skip_last_dot(file_full_path); + String8 file_folder = str8_chop_last_slash(file_path); + String8 file_name = str8_skip_last_slash(str8_chop_last_dot(file_path)); + String8 file_ext = str8_skip_last_dot(file_path); String8 partner_ext_candidates[] = { str8_lit_comp("h"), @@ -13972,7 +13961,7 @@ rd_frame(void) case RD_CmdKind_RecordFileInProject: if(rd_regs()->file_path.size != 0) { - String8 path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); + String8 path = rd_regs()->file_path; RD_Cfg *project = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("project")); RD_CfgList recent_files = rd_cfg_child_list_from_string(scratch.arena, project, str8_lit("recent_file")); RD_Cfg *recent_file = &rd_nil_cfg; @@ -14001,7 +13990,7 @@ rd_frame(void) case RD_CmdKind_ShowFileInExplorer: if(rd_regs()->file_path.size != 0) { - String8 full_path = path_normalized_from_string(scratch.arena, rd_regs()->file_path); + String8 full_path = rd_regs()->file_path; os_show_in_filesystem_ui(full_path); }break; @@ -14976,11 +14965,7 @@ rd_frame(void) { current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); } - else - { - current_path_string = path_normalized_from_string(scratch.arena, current_path_string); - } - initial_input = path_normalized_from_string(scratch.arena, current_path_string); + initial_input = current_path_string; initial_input = push_str8f(scratch.arena, "%S/", initial_input); } else if(cmd_kind_info->query.flags & RD_QueryFlag_KeepOldInput) @@ -15383,7 +15368,7 @@ rd_frame(void) String8List strings = {0}; for(RD_CfgNode *n = colors.first; n != 0; n = n->next) { - str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, dst_path, n->v)); + str8_list_push(scratch.arena, &strings, rd_string_from_cfg_tree(scratch.arena, str8_chop_last_slash(dst_path), n->v)); } String8 data = str8_list_join(scratch.arena, &strings, 0); if(os_write_data_to_file_path(dst_path, data)) diff --git a/src/raddbg/raddbg_legacy_config.c b/src/raddbg/raddbg_legacy_config.c index 3932abce..119ea215 100644 --- a/src/raddbg/raddbg_legacy_config.c +++ b/src/raddbg/raddbg_legacy_config.c @@ -7,6 +7,7 @@ rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String RD_CfgList result = {0}; { Temp scratch = scratch_begin(&arena, 1); + String8 folder_path = str8_skip_last_slash(file_path); MD_Node *src_root = md_parse_from_text(scratch.arena, file_path, data).root; { for MD_EachNode(tln, src_root->first) @@ -26,13 +27,13 @@ rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, str8_lit("target")); rd_cfg_list_push(arena, &result, dst_root); { - if(executable.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("executable")), path_absolute_dst_from_relative_dst_src(scratch.arena, executable, file_path)); } + if(executable.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("executable")), path_absolute_dst_from_relative_dst_src(scratch.arena, executable, folder_path)); } if(arguments.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("arguments")), raw_from_escaped_str8(scratch.arena, arguments)); } - if(working_directory.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("working_directory")), path_absolute_dst_from_relative_dst_src(scratch.arena, working_directory, file_path)); } + if(working_directory.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("working_directory")), path_absolute_dst_from_relative_dst_src(scratch.arena, working_directory, folder_path)); } if(entry_point.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("entry_point")), raw_from_escaped_str8(scratch.arena, entry_point)); } - if(stdout_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdout_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdout_path, file_path)); } - if(stderr_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stderr_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stderr_path, file_path)); } - if(stdin_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdin_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdin_path, file_path)); } + if(stdout_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdout_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdout_path, folder_path)); } + if(stderr_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stderr_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stderr_path, folder_path)); } + if(stdin_path.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("stdin_path")), path_absolute_dst_from_relative_dst_src(scratch.arena, stdin_path, folder_path)); } if(debug_subprocesses.size != 0) { rd_cfg_new(rd_cfg_new(dst_root, str8_lit("debug_subprocesses")), raw_from_escaped_str8(scratch.arena, debug_subprocesses)); } if(!str8_match(disabled_string, str8_lit("1"), 0)) { @@ -47,7 +48,7 @@ rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String { RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, tln->string); rd_cfg_list_push(arena, &result, dst_root); - rd_cfg_new(rd_cfg_new(dst_root, str8_lit("path")), path_absolute_dst_from_relative_dst_src(scratch.arena, tln->first->string, file_path)); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("path")), path_absolute_dst_from_relative_dst_src(scratch.arena, tln->first->string, folder_path)); } //- rjf: file path maps @@ -57,8 +58,8 @@ rd_cfg_tree_list_from_string__pre_0_9_16(Arena *arena, String8 file_path, String String8 dest = md_child_from_string(tln, str8_lit("dest"), 0)->first->string; RD_Cfg *dst_root = rd_cfg_new(&rd_nil_cfg, tln->string); rd_cfg_list_push(arena, &result, dst_root); - rd_cfg_new(rd_cfg_new(dst_root, str8_lit("source")), path_absolute_dst_from_relative_dst_src(scratch.arena, source, file_path)); - rd_cfg_new(rd_cfg_new(dst_root, str8_lit("dest")), path_absolute_dst_from_relative_dst_src(scratch.arena, dest, file_path)); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("source")), path_absolute_dst_from_relative_dst_src(scratch.arena, source, folder_path)); + rd_cfg_new(rd_cfg_new(dst_root, str8_lit("dest")), path_absolute_dst_from_relative_dst_src(scratch.arena, dest, folder_path)); } } } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index a3abc191..eb9d1336 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -468,11 +468,11 @@ entry_point(CmdLine *cmd_line) // rjf: unpack full executable path if(args.first->string.size != 0) { - String8 current_path = os_get_current_path(scratch.arena); String8 exe_name = args.first->string; PathStyle style = path_style_from_str8(exe_name); if(style == PathStyle_Relative) { + String8 current_path = os_get_current_path(scratch.arena); exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); exe_name = path_normalized_from_string(scratch.arena, exe_name); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index cd4653ae..7ac74838 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2461,7 +2461,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) U64 cursor_vaddr = (1 <= rd_regs()->cursor.line && rd_regs()->cursor.line <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[rd_regs()->cursor.line-1].code_off) : 0; if(dasm_module != &ctrl_entity_nil) { - ui_labelf("%S", path_normalized_from_string(scratch.arena, dasm_module->string)); + ui_labelf("%S", dasm_module->string); ui_spacer(ui_em(1.5f, 1)); } ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, rd_regs()->cursor.line, rd_regs()->cursor.column); diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 7228b9d0..70105610 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -642,14 +642,10 @@ ASYNC_WORK_DEF(p2r_units_convert_work) String8 file_path = lines->file_name; String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); { - for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) - { - if(file_path_normalized.str[idx] == '\\') - { - file_path_normalized.str[idx] = '/'; - } - } - file_path_normalized = path_normalized_from_string(scratch.arena, file_path_normalized); + PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); + String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); + str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); + file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); } // rjf: normalized file path -> source file node diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.c b/src/render/opengl/linux/egl/render_opengl_linux_egl.c index dc34a3b0..33e79804 100644 --- a/src/render/opengl/linux/egl/render_opengl_linux_egl.c +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.c @@ -52,7 +52,9 @@ r_ogl_os_init(CmdLine *cmdln) os_abort(1); } - //- rjf: set up EGL config + //- rjf: get all EGL configs + EGLConfig configs[256] = {0}; + EGLint configs_count = 0; { EGLint options[] = { @@ -69,14 +71,39 @@ r_ogl_os_init(CmdLine *cmdln) EGL_NONE, }; - EGLint config_count = 0; - if(!eglChooseConfig(r_ogl_lnx_state->display, options, &r_ogl_lnx_state->config, 1, &config_count) || config_count != 1) + if(!eglChooseConfig(r_ogl_lnx_state->display, options, configs, ArrayCount(configs), &configs_count) || configs_count == 0) { os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); os_abort(1); } } + //- rjf: actually choose the egl config + { + Window dummy_window = XCreateWindow(os_lnx_gfx_state->display, XDefaultRootWindow(os_lnx_gfx_state->display), 0, 0, 100, 100, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0); + EGLint options[] = + { + EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, + EGL_NONE, + }; + for(U32 idx = 0; idx < configs_count; idx += 1) + { + EGLSurface *dummy_surface = eglCreateWindowSurface(r_ogl_lnx_state->display, configs[idx], dummy_window, options); + if(dummy_surface != EGL_NO_SURFACE) + { + r_ogl_lnx_state->config = configs[idx]; + eglDestroySurface(r_ogl_lnx_state->display, dummy_surface); + break; + } + } + if(r_ogl_lnx_state->config == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find a suitable EGL configuration.")); + os_abort(1); + } + XDestroyWindow(os_lnx_gfx_state->display, dummy_window); + } + //- rjf: construct context { B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); @@ -118,8 +145,7 @@ r_ogl_os_window_equip(OS_Handle window) { EGLint options[] = { - EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR, - EGL_RENDER_BUFFER, EGL_BACK_BUFFER, + EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, EGL_NONE, }; w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, options); diff --git a/src/render/opengl/linux/glx/render_opengl_linux_glx.c b/src/render/opengl/linux/glx/render_opengl_linux_glx.c index 66403bc3..f8ca0af0 100644 --- a/src/render/opengl/linux/glx/render_opengl_linux_glx.c +++ b/src/render/opengl/linux/glx/render_opengl_linux_glx.c @@ -51,10 +51,6 @@ r_ogl_os_init(CmdLine *cmdln) GLXFBConfig framebuffer_config = framebuffer_configs[0]; XFree(framebuffer_configs); - //- rjf: get visual info; create color map - XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config); - Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone); - //- rjf: construct set-window-attributes XSetWindowAttributes set_window_attributes = {0}; set_window_attributes.background_pixmap = None; @@ -79,7 +75,7 @@ r_ogl_os_init(CmdLine *cmdln) r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options); } - glXMakeCurrent(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), r_ogl_lnx_ctx); + glXMakeCurrent(os_lnx_gfx_state->display, 0, r_ogl_lnx_ctx); } internal R_Handle diff --git a/src/render/opengl/render_opengl.c b/src/render/opengl/render_opengl.c index e23df2ac..0661e8dc 100644 --- a/src/render/opengl/render_opengl.c +++ b/src/render/opengl/render_opengl.c @@ -193,7 +193,7 @@ r_init(CmdLine *cmdln) #endif if(debug_mode) { - glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback(r_ogl_debug_message_callback, 0); } } diff --git a/src/render/opengl/render_opengl.h b/src/render/opengl/render_opengl.h index e8c56ccb..618298e1 100644 --- a/src/render/opengl/render_opengl.h +++ b/src/render/opengl/render_opengl.h @@ -71,6 +71,7 @@ typedef ptrdiff_t GLintptr; #define GL_TEXTURE31 0x84DF #define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 //////////////////////////////// //~ rjf: OS Backend Includes diff --git a/src/render/opengl/win32/render_opengl_win32.c b/src/render/opengl/win32/render_opengl_win32.c index 48944a80..f031758f 100644 --- a/src/render/opengl/win32/render_opengl_win32.c +++ b/src/render/opengl/win32/render_opengl_win32.c @@ -98,8 +98,6 @@ r_ogl_os_init(CmdLine *cmdline) wglDeleteContext(bootstrap_ctx); wglMakeCurrent(dc, real_ctx); wglSwapIntervalEXT(1); - ReleaseDC(bootstrap_hwnd, dc); - DestroyWindow(bootstrap_hwnd); } internal R_Handle @@ -108,7 +106,7 @@ r_ogl_os_window_equip(OS_Handle window) //- rjf: unpack window OS_W32_Window *w = os_w32_window_from_handle(window); HWND hwnd = w->hwnd; - HDC hdc = GetDC(hwnd); + HDC hdc = w->hdc; //- rjf: select in ctx wglMakeCurrent(hdc, r_ogl_w32_hglrc); @@ -152,7 +150,6 @@ r_ogl_os_window_equip(OS_Handle window) SetPixelFormat(hdc, pixel_format, &pfd); //- rjf: release hdc - ReleaseDC(hwnd, hdc); R_Handle result = {0}; return result; } @@ -169,9 +166,8 @@ r_ogl_os_select_window(OS_Handle os, R_Handle r) if(w != 0) { HWND hwnd = w->hwnd; - HDC hdc = GetDC(hwnd); + HDC hdc = w->hdc; wglMakeCurrent(hdc, r_ogl_w32_hglrc); - ReleaseDC(hwnd, hdc); } } @@ -181,8 +177,7 @@ r_ogl_os_window_swap(OS_Handle os, R_Handle r) OS_W32_Window *w = os_w32_window_from_handle(os); if(w != 0) { - HDC dc = GetDC(w->hwnd); + HDC dc = w->hdc; SwapBuffers(dc); - ReleaseDC(w->hwnd, dc); } } From d564184d315b750679b114a3b43725d90523a333 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 17:09:13 -0700 Subject: [PATCH 678/755] chip away more unneeded path processing, impeding proper support for relative paths; we want to mostly preserve paths as we see them, and then we should find a different story for mapping the paths in very few places --- src/raddbg/raddbg_core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b0fedcee..dd46afa4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1486,7 +1486,6 @@ internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path) { Temp scratch = scratch_begin(&arena, 1); - String8 result = file_path; if(file_path.size != 0) { String8List file_path_parts = str8_split_path(scratch.arena, file_path); @@ -1527,9 +1526,10 @@ rd_mapped_from_file_path(Arena *arena, String8 file_path) str8_list_push(scratch.arena, &best_map_dst_parts, n->string); } StringJoin join = {.sep = str8_lit("/")}; - result = str8_list_join(arena, &best_map_dst_parts, &join); + file_path = str8_list_join(scratch.arena, &best_map_dst_parts, &join); } } + String8 result = push_str8_copy(arena, file_path); scratch_end(scratch); return result; } @@ -13473,6 +13473,10 @@ rd_frame(void) { // NOTE(rjf): // + // foo.c + // C:/test/bar/baz/foo.c + // -> override foo.c -> C:/test/bar/baz/foo.c + // // C:/foo/bar/baz.c // D:/foo/bar/baz.c // -> override C: -> D: @@ -13509,7 +13513,9 @@ rd_frame(void) String8Node *first_diff_dst = dst_path_parts__reversed.first; for(;first_diff_src != 0 && first_diff_dst != 0;) { - if(!str8_match(first_diff_src->string, first_diff_dst->string, StringMatchFlag_CaseInsensitive)) + if(!str8_match(first_diff_src->string, first_diff_dst->string, StringMatchFlag_CaseInsensitive) || + first_diff_src->next == 0 || + first_diff_dst->next == 0) { break; } @@ -14539,7 +14545,7 @@ rd_frame(void) U64 vaddr = 0; B32 require_disasm_snap = 0; { - file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path); + file_path = rd_regs()->file_path; point = rd_regs()->cursor; thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); From 533136875ece133c1e51baf0a87e8a049b582fd4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 17:20:46 -0700 Subject: [PATCH 679/755] eliminate dummy window egl setup --- .../linux/egl/render_opengl_linux_egl.c | 113 +++++++++--------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/src/render/opengl/linux/egl/render_opengl_linux_egl.c b/src/render/opengl/linux/egl/render_opengl_linux_egl.c index 33e79804..3d3370c6 100644 --- a/src/render/opengl/linux/egl/render_opengl_linux_egl.c +++ b/src/render/opengl/linux/egl/render_opengl_linux_egl.c @@ -52,58 +52,6 @@ r_ogl_os_init(CmdLine *cmdln) os_abort(1); } - //- rjf: get all EGL configs - EGLConfig configs[256] = {0}; - EGLint configs_count = 0; - { - EGLint options[] = - { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_CONFORMANT, EGL_OPENGL_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, - - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - - EGL_NONE, - }; - if(!eglChooseConfig(r_ogl_lnx_state->display, options, configs, ArrayCount(configs), &configs_count) || configs_count == 0) - { - os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); - os_abort(1); - } - } - - //- rjf: actually choose the egl config - { - Window dummy_window = XCreateWindow(os_lnx_gfx_state->display, XDefaultRootWindow(os_lnx_gfx_state->display), 0, 0, 100, 100, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0); - EGLint options[] = - { - EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, - EGL_NONE, - }; - for(U32 idx = 0; idx < configs_count; idx += 1) - { - EGLSurface *dummy_surface = eglCreateWindowSurface(r_ogl_lnx_state->display, configs[idx], dummy_window, options); - if(dummy_surface != EGL_NO_SURFACE) - { - r_ogl_lnx_state->config = configs[idx]; - eglDestroySurface(r_ogl_lnx_state->display, dummy_surface); - break; - } - } - if(r_ogl_lnx_state->config == 0) - { - os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find a suitable EGL configuration.")); - os_abort(1); - } - XDestroyWindow(os_lnx_gfx_state->display, dummy_window); - } - //- rjf: construct context { B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug")); @@ -118,7 +66,7 @@ r_ogl_os_init(CmdLine *cmdln) debug_mode ? EGL_CONTEXT_OPENGL_DEBUG : EGL_NONE, EGL_TRUE, EGL_NONE, }; - r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, r_ogl_lnx_state->config, EGL_NO_CONTEXT, options); + r_ogl_lnx_state->context = eglCreateContext(r_ogl_lnx_state->display, 0, EGL_NO_CONTEXT, options); if(r_ogl_lnx_state->context == EGL_NO_CONTEXT) { os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create OpenGL context with EGL.")); @@ -127,6 +75,7 @@ r_ogl_os_init(CmdLine *cmdln) } eglMakeCurrent(r_ogl_lnx_state->display, 0, 0, r_ogl_lnx_state->context); + glDrawBuffer(GL_BACK); } internal R_Handle @@ -143,12 +92,66 @@ r_ogl_os_window_equip(OS_Handle window) w = push_array(r_ogl_lnx_state->arena, R_OGL_LNX_Window, 1); } { - EGLint options[] = + EGLint surface_options[] = { EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, EGL_NONE, }; - w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, options); + if(r_ogl_lnx_state->config == 0) + { + //- rjf: get all EGL configs + EGLConfig configs[256] = {0}; + EGLint configs_count = 0; + { + EGLint options[] = + { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_CONFORMANT, EGL_OPENGL_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, + + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + + EGL_NONE, + }; + if(!eglChooseConfig(r_ogl_lnx_state->display, options, configs, ArrayCount(configs), &configs_count) || configs_count == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't choose EGL configuration.")); + os_abort(1); + } + } + + //- rjf: actually choose the egl config + { + EGLint config_options[] = + { + EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB, + EGL_NONE, + }; + for(U32 idx = 0; idx < configs_count; idx += 1) + { + w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, configs[idx], window_os->window, config_options); + if(w->surface != EGL_NO_SURFACE) + { + r_ogl_lnx_state->config = configs[idx]; + break; + } + } + if(r_ogl_lnx_state->config == 0) + { + os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't find a suitable EGL configuration.")); + os_abort(1); + } + } + } + else + { + w->surface = eglCreateWindowSurface(r_ogl_lnx_state->display, r_ogl_lnx_state->config, window_os->window, surface_options); + } if(w->surface == EGL_NO_SURFACE) { os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Couldn't create EGL surface.")); From 4c1585444c77cbcd716c84cfd736c804e6c2e83e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 17:33:57 -0700 Subject: [PATCH 680/755] be less ambitious about occupying basic type names in debugger; can conflict with common purposes in codebases, and really we should defer to debug info when possible --- src/codeview/codeview.mdesk | 66 +++++++++++++------------- src/codeview/generated/codeview.meta.c | 66 +++++++++++++------------- src/eval/eval_parse.c | 30 ++++++------ 3 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/codeview/codeview.mdesk b/src/codeview/codeview.mdesk index 3cfb11e6..ac511efd 100644 --- a/src/codeview/codeview.mdesk +++ b/src/codeview/codeview.mdesk @@ -395,48 +395,48 @@ CV_BasicTypeTable: {FBASICSTR 0x06 "" } {NOTTRANS 0x07 "" } {HRESULT 0x08 "HRESULT" } - {CHAR 0x10 "char" } - {SHORT 0x11 "S16" } - {LONG 0x12 "S32" } - {QUAD 0x13 "S64" } - {OCT 0x14 "S128" } + {CHAR 0x10 "CHAR" } + {SHORT 0x11 "SHORT" } + {LONG 0x12 "LONG" } + {QUAD 0x13 "QUAD" } + {OCT 0x14 "OCT" } {UCHAR 0x20 "UCHAR" } - {USHORT 0x21 "U16" } - {ULONG 0x22 "U32" } - {UQUAD 0x23 "U64" } - {UOCT 0x24 "U128" } - {BOOL8 0x30 "B8" } - {BOOL16 0x31 "B16" } - {BOOL32 0x32 "B32" } - {BOOL64 0x33 "B64" } - {FLOAT32 0x40 "F32" } - {FLOAT64 0x41 "F64" } - {FLOAT80 0x42 "F80" } - {FLOAT128 0x43 "F128" } - {FLOAT48 0x44 "F48" } - {FLOAT32PP 0x45 "F32PP" } - {FLOAT16 0x46 "F16" } + {USHORT 0x21 "USHORT" } + {ULONG 0x22 "ULONG" } + {UQUAD 0x23 "UQUAD" } + {UOCT 0x24 "UOCT" } + {BOOL8 0x30 "BOOL8" } + {BOOL16 0x31 "BOOL16" } + {BOOL32 0x32 "BOOL32" } + {BOOL64 0x33 "BOOL64" } + {FLOAT32 0x40 "FLOAT32" } + {FLOAT64 0x41 "FLOAT64" } + {FLOAT80 0x42 "FLOAT80" } + {FLOAT128 0x43 "FLOAT128" } + {FLOAT48 0x44 "FLOAT48" } + {FLOAT32PP 0x45 "FLOAT32PP" } + {FLOAT16 0x46 "FLOAT16" } {COMPLEX32 0x50 "ComplexF32" } {COMPLEX64 0x51 "ComplexF64" } {COMPLEX80 0x52 "ComplexF80" } {COMPLEX128 0x53 "ComplexF128" } {BIT 0x60 "" } {PASCHAR 0x61 "" } - {BOOL32FF 0x62 "B32FF" } - {INT8 0x68 "S8" } - {UINT8 0x69 "U8" } + {BOOL32FF 0x62 "BOOL32FF" } + {INT8 0x68 "int8" } + {UINT8 0x69 "uint8" } {RCHAR 0x70 "char" } {WCHAR 0x71 "WCHAR" } - {INT16 0x72 "S16" } - {UINT16 0x73 "U16" } - {INT32 0x74 "S32" } - {UINT32 0x75 "U32" } - {INT64 0x76 "S64" } - {UINT64 0x77 "U64" } - {INT128 0x78 "S128" } - {UINT128 0x79 "U128" } - {CHAR16 0x7a "CHAR16" } - {CHAR32 0x7b "CHAR32" } + {INT16 0x72 "int16" } + {UINT16 0x73 "uint16" } + {INT32 0x74 "int32" } + {UINT32 0x75 "uint32" } + {INT64 0x76 "int64" } + {UINT64 0x77 "uint64" } + {INT128 0x78 "int128" } + {UINT128 0x79 "uint128" } + {CHAR16 0x7a "char16" } + {CHAR32 0x7b "char32" } {CHAR8 0x7c "char" } {PTR 0xf0 "PTR" } } diff --git a/src/codeview/generated/codeview.meta.c b/src/codeview/generated/codeview.meta.c index 7e5be454..898e4989 100644 --- a/src/codeview/generated/codeview.meta.c +++ b/src/codeview/generated/codeview.meta.c @@ -392,48 +392,48 @@ case CV_BasicType_NBASICSTR:{result = str8_lit("");}break; case CV_BasicType_FBASICSTR:{result = str8_lit("");}break; case CV_BasicType_NOTTRANS:{result = str8_lit("");}break; case CV_BasicType_HRESULT:{result = str8_lit("HRESULT");}break; -case CV_BasicType_CHAR:{result = str8_lit("char");}break; -case CV_BasicType_SHORT:{result = str8_lit("S16");}break; -case CV_BasicType_LONG:{result = str8_lit("S32");}break; -case CV_BasicType_QUAD:{result = str8_lit("S64");}break; -case CV_BasicType_OCT:{result = str8_lit("S128");}break; +case CV_BasicType_CHAR:{result = str8_lit("CHAR");}break; +case CV_BasicType_SHORT:{result = str8_lit("SHORT");}break; +case CV_BasicType_LONG:{result = str8_lit("LONG");}break; +case CV_BasicType_QUAD:{result = str8_lit("QUAD");}break; +case CV_BasicType_OCT:{result = str8_lit("OCT");}break; case CV_BasicType_UCHAR:{result = str8_lit("UCHAR");}break; -case CV_BasicType_USHORT:{result = str8_lit("U16");}break; -case CV_BasicType_ULONG:{result = str8_lit("U32");}break; -case CV_BasicType_UQUAD:{result = str8_lit("U64");}break; -case CV_BasicType_UOCT:{result = str8_lit("U128");}break; -case CV_BasicType_BOOL8:{result = str8_lit("B8");}break; -case CV_BasicType_BOOL16:{result = str8_lit("B16");}break; -case CV_BasicType_BOOL32:{result = str8_lit("B32");}break; -case CV_BasicType_BOOL64:{result = str8_lit("B64");}break; -case CV_BasicType_FLOAT32:{result = str8_lit("F32");}break; -case CV_BasicType_FLOAT64:{result = str8_lit("F64");}break; -case CV_BasicType_FLOAT80:{result = str8_lit("F80");}break; -case CV_BasicType_FLOAT128:{result = str8_lit("F128");}break; -case CV_BasicType_FLOAT48:{result = str8_lit("F48");}break; -case CV_BasicType_FLOAT32PP:{result = str8_lit("F32PP");}break; -case CV_BasicType_FLOAT16:{result = str8_lit("F16");}break; +case CV_BasicType_USHORT:{result = str8_lit("USHORT");}break; +case CV_BasicType_ULONG:{result = str8_lit("ULONG");}break; +case CV_BasicType_UQUAD:{result = str8_lit("UQUAD");}break; +case CV_BasicType_UOCT:{result = str8_lit("UOCT");}break; +case CV_BasicType_BOOL8:{result = str8_lit("BOOL8");}break; +case CV_BasicType_BOOL16:{result = str8_lit("BOOL16");}break; +case CV_BasicType_BOOL32:{result = str8_lit("BOOL32");}break; +case CV_BasicType_BOOL64:{result = str8_lit("BOOL64");}break; +case CV_BasicType_FLOAT32:{result = str8_lit("FLOAT32");}break; +case CV_BasicType_FLOAT64:{result = str8_lit("FLOAT64");}break; +case CV_BasicType_FLOAT80:{result = str8_lit("FLOAT80");}break; +case CV_BasicType_FLOAT128:{result = str8_lit("FLOAT128");}break; +case CV_BasicType_FLOAT48:{result = str8_lit("FLOAT48");}break; +case CV_BasicType_FLOAT32PP:{result = str8_lit("FLOAT32PP");}break; +case CV_BasicType_FLOAT16:{result = str8_lit("FLOAT16");}break; case CV_BasicType_COMPLEX32:{result = str8_lit("ComplexF32");}break; case CV_BasicType_COMPLEX64:{result = str8_lit("ComplexF64");}break; case CV_BasicType_COMPLEX80:{result = str8_lit("ComplexF80");}break; case CV_BasicType_COMPLEX128:{result = str8_lit("ComplexF128");}break; case CV_BasicType_BIT:{result = str8_lit("");}break; case CV_BasicType_PASCHAR:{result = str8_lit("");}break; -case CV_BasicType_BOOL32FF:{result = str8_lit("B32FF");}break; -case CV_BasicType_INT8:{result = str8_lit("S8");}break; -case CV_BasicType_UINT8:{result = str8_lit("U8");}break; +case CV_BasicType_BOOL32FF:{result = str8_lit("BOOL32FF");}break; +case CV_BasicType_INT8:{result = str8_lit("int8");}break; +case CV_BasicType_UINT8:{result = str8_lit("uint8");}break; case CV_BasicType_RCHAR:{result = str8_lit("char");}break; case CV_BasicType_WCHAR:{result = str8_lit("WCHAR");}break; -case CV_BasicType_INT16:{result = str8_lit("S16");}break; -case CV_BasicType_UINT16:{result = str8_lit("U16");}break; -case CV_BasicType_INT32:{result = str8_lit("S32");}break; -case CV_BasicType_UINT32:{result = str8_lit("U32");}break; -case CV_BasicType_INT64:{result = str8_lit("S64");}break; -case CV_BasicType_UINT64:{result = str8_lit("U64");}break; -case CV_BasicType_INT128:{result = str8_lit("S128");}break; -case CV_BasicType_UINT128:{result = str8_lit("U128");}break; -case CV_BasicType_CHAR16:{result = str8_lit("CHAR16");}break; -case CV_BasicType_CHAR32:{result = str8_lit("CHAR32");}break; +case CV_BasicType_INT16:{result = str8_lit("int16");}break; +case CV_BasicType_UINT16:{result = str8_lit("uint16");}break; +case CV_BasicType_INT32:{result = str8_lit("int32");}break; +case CV_BasicType_UINT32:{result = str8_lit("uint32");}break; +case CV_BasicType_INT64:{result = str8_lit("int64");}break; +case CV_BasicType_UINT64:{result = str8_lit("uint64");}break; +case CV_BasicType_INT128:{result = str8_lit("int128");}break; +case CV_BasicType_UINT128:{result = str8_lit("uint128");}break; +case CV_BasicType_CHAR16:{result = str8_lit("char16");}break; +case CV_BasicType_CHAR32:{result = str8_lit("char32");}break; case CV_BasicType_CHAR8:{result = str8_lit("char");}break; case CV_BasicType_PTR:{result = str8_lit("PTR");}break; } diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 980f2977..ed79b907 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -533,7 +533,7 @@ e_leaf_type_from_name(String8 name) { #define Case(str) (str8_match(name, str8_lit(str), 0)) if(0){} - else if(Case("u8") || Case("uint8") || Case("uint8_t") || Case("U8")) + else if(Case("uint8") || Case("uint8_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U8); @@ -543,7 +543,7 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_UChar8); } - else if(Case("u16") || Case("uint16") || Case("uint16_t") || Case("U16")) + else if(Case("uint16") || Case("uint16_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U16); @@ -553,7 +553,7 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_UChar16); } - else if(Case("u32") || Case("uint32") || Case("uint32_t") || Case("U32") || Case("uint")) + else if(Case("uint32") || Case("uint32_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U32); @@ -563,27 +563,27 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_UChar32); } - else if(Case("u64") || Case("uint64") || Case("uint64_t") || Case("U64") || Case("size_t")) + else if(Case("uint64") || Case("uint64_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U64); } - else if(Case("u128") || Case("uint128") || Case("uint128_t") || Case("U128")) + else if(Case("uint128") || Case("uint128_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U128); } - else if(Case("u256") || Case("uint256") || Case("uint256_t") || Case("U256")) + else if(Case("uint256") || Case("uint256_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U256); } - else if(Case("u512") || Case("uint512") || Case("uint512_t") || Case("U512")) + else if(Case("uint512") || Case("uint512_t")) { found = 1; key = e_type_key_basic(E_TypeKind_U512); } - else if(Case("s8") || Case("b8") || Case("B8") || Case("i8") || Case("int8") || Case("int8_t") || Case("S8")) + else if(Case("s8") || Case("b8") || Case("B8") || Case("i8") || Case("int8") || Case("int8_t")) { found = 1; key = e_type_key_basic(E_TypeKind_S8); @@ -593,7 +593,7 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_Char8); } - else if(Case("s16") || Case("b16") || Case("B16") || Case("i16") || Case("int16") || Case("int16_t") || Case("S16")) + else if(Case("int16") || Case("int16_t")) { found = 1; key = e_type_key_basic(E_TypeKind_S16); @@ -603,7 +603,7 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_Char16); } - else if(Case("s32") || Case("b32") || Case("B32") || Case("i32") || Case("int32") || Case("int32_t") || Case("char32") || Case("S32") || Case("int")) + else if(Case("int32") || Case("int32_t") || Case("char32")) { found = 1; key = e_type_key_basic(E_TypeKind_S32); @@ -613,17 +613,17 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_Char32); } - else if(Case("s64") || Case("b64") || Case("B64") || Case("i64") || Case("int64") || Case("int64_t") || Case("S64") || Case("ssize_t")) + else if(Case("int64") || Case("int64_t")) { found = 1; key = e_type_key_basic(E_TypeKind_S64); } - else if(Case("s256") || Case("i256") || Case("int256") || Case("int256_t") || Case("S256")) + else if(Case("int256") || Case("int256_t")) { found = 1; key = e_type_key_basic(E_TypeKind_S256); } - else if(Case("s512") || Case("i512") || Case("int512") || Case("int512_t") || Case("S512")) + else if(Case("int512") || Case("int512_t")) { found = 1; key = e_type_key_basic(E_TypeKind_S512); @@ -638,12 +638,12 @@ e_leaf_type_from_name(String8 name) found = 1; key = e_type_key_basic(E_TypeKind_Bool); } - else if(Case("float") || Case("float32") || Case("f32") || Case("F32") || Case("r32") || Case("R32")) + else if(Case("float") || Case("float32")) { found = 1; key = e_type_key_basic(E_TypeKind_F32); } - else if(Case("double") || Case("float64") || Case("f64") || Case("F64") || Case("r64") || Case("R64")) + else if(Case("double") || Case("float64")) { found = 1; key = e_type_key_basic(E_TypeKind_F64); From bc75635a655bd68ebc755b3151aee581e964d371 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 May 2025 21:22:03 -0700 Subject: [PATCH 681/755] os/gfx/linux: window focus querying --- src/os/gfx/linux/os_gfx_linux.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 9a473ea9..7a142531 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -204,8 +204,12 @@ internal B32 os_window_is_focused(OS_Handle handle) { if(os_handle_match(handle, os_handle_zero())) {return 0;} - // TODO(rjf) - return 0; + OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0]; + Window focused_window = 0; + int revert_to = 0; + XGetInputFocus(os_lnx_gfx_state->display, &focused_window, &revert_to); + B32 result = (w->window == focused_window); + return result; } internal B32 From 73c91ae2bc82bf398d765004d7a7bad46d0c4ac9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 10:19:47 -0700 Subject: [PATCH 682/755] eval: adjust array expansion, use parent key of pointer argument, rather than key of pointer argument, to scope count expression evaluation; fix up a few edge cases with $. and implicit $ member accesses; make `omit` much more powerful, by allowing list of arguments to control all expansion expressions, rather than assuming only member names --- src/eval/eval_ir.c | 4 ++-- src/eval/eval_types.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9ec5976c..864c376e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -715,7 +715,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I String8 full_qualified_name = str8_list_join(scratch.arena, &parts, &(StringJoin){.sep = str8_lit(".")}); E_Expr *leaf_expr_name = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, r1u64(0, 0)); leaf_expr_name->string = full_qualified_name; - result = e_push_irtree_and_type_from_expr(arena, root_parent, &e_default_identifier_resolution_rule, disallow_autohooks, disallow_autohooks, leaf_expr_name); + result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, disallow_autohooks, leaf_expr_name); } } }break; @@ -1627,7 +1627,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) { E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, root_parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d6babada..964af400 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2423,10 +2423,10 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { E_Expr *arg = type->args[idx]; - if(arg->string.size != 0) - { - evals_out[out_idx] = e_eval_wrapf(eval, "$.%S", arg->string); - } + Temp scratch = scratch_begin(&arena, 1); + String8 string = e_string_from_expr(scratch.arena, arg, str8_zero()); + evals_out[out_idx] = e_eval_wrap(eval, string); + scratch_end(scratch); } } @@ -2522,7 +2522,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) { E_Type *type = e_type_from_key(eval.irtree.type_key); U64 count = 1; - if(type->args != 0 && type->count > 0) E_ParentKey(eval.key) + if(type->args != 0 && type->count > 0) E_ParentKey(eval.parent_key) { E_Key count_key = e_key_from_expr(type->args[0]); E_Value count_value = e_value_from_key(count_key); From 11c1b5277e2c0682d42ccd85d943df5f768e24b0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 10:44:06 -0700 Subject: [PATCH 683/755] only -> rows; table -> columns --- src/eval/eval_types.c | 6 +++--- src/eval/eval_types.h | 6 +++--- src/mule/mule_main.cpp | 8 ++++---- src/raddbg/raddbg.mdesk | 4 ++-- src/raddbg/raddbg_core.c | 4 ++-- src/raddbg/raddbg_views.c | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 964af400..2810513c 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2407,16 +2407,16 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) } //////////////////////////////// -//~ rjf: (Built-In Type Hooks) `only` lens +//~ rjf: (Built-In Type Hooks) `rows` lens -E_TYPE_EXPAND_INFO_FUNCTION_DEF(only) +E_TYPE_EXPAND_INFO_FUNCTION_DEF(rows) { E_Type *type = e_type_from_key(eval.irtree.type_key); E_TypeExpandInfo info = {0, type->count}; return info; } -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only) +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(rows) { E_Type *type = e_type_from_key(eval.irtree.type_key); U64 out_idx = 0; diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 4577152c..1e771975 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -142,10 +142,10 @@ E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity); //////////////////////////////// -//~ rjf: (Built-In Type Hooks) `only` lens +//~ rjf: (Built-In Type Hooks) `rows` lens -E_TYPE_EXPAND_INFO_FUNCTION_DEF(only); -E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(rows); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(rows); //////////////////////////////// //~ rjf: (Built-In Type Hooks) `sequence` lens diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index ba936b4b..d61baf1a 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -190,7 +190,7 @@ union Vector_R2 }; float v[2]; }; -raddbg_type_view(Vector_R2, only($, x, y)); +raddbg_type_view(Vector_R2, rows($, x, y)); typedef union Matrix4x4F32 Matrix4x4F32; union Matrix4x4F32 @@ -310,9 +310,9 @@ struct Crazy_Union }; }; raddbg_type_view(Crazy_Union, - kind == Kind.First ? only($, first_and_third, first) : - kind == Kind.Second ? only($, second) : - kind == Kind.Third ? only($, first_and_third, third) : + kind == Kind.First ? rows($, first_and_third, first) : + kind == Kind.Second ? rows($, second) : + kind == Kind.Third ? rows($, first_and_third, third) : kind == Kind.Fourth ? kind : $); diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 12fde4a5..806b563f 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -2363,7 +2363,7 @@ raddbg_readme: @p "`pointer, 64`: Visualizes `pointer` as pointing to a 256-element array."; @p "`pointer, count`: Visualizes `pointer` as pointing to a `count`-element array."; @p "`slice(some_slice_struct)`: Interprets a structure type as containing a base pointer and a count (either through an integer, or an 'end pointer'), and visualizes the base pointer, pointing to that many elements."; - @p "`only(some_struct, a, b, c)`: Displays the value of `some_struct`, but only showing members `a`, `b`, and `c`."; + @p "`rows(some_struct, a, b, c)`: Displays the value of `some_struct`, but only showing members `a`, `b`, and `c`."; @p "`omit(some_struct, a, b, c)`: Displays the value of `some_struct`, but only showing members other than `a`, `b`, and `c`."; @p "`hex(my_int)`: Visualizes the value of `my_int` in base-16 (hexadecimal) form."; @p "`dec(my_int)`: Visualizes the value of `my_int` in base-10 (decimal) form."; @@ -2446,7 +2446,7 @@ raddbg_readme: @p "`no_char(expr)`: Disables character visualization with character or integer evaluations in `expr`."; @p "`no_addr(expr)`: Disables explicit address visualization with pointer evaluations in `expr`."; @p "`sequence(expr)`: Interprets `expr` as an integer, encoding how many sub-expressions `expr` should expand to produce. This can be used in combination with the `table` view to easily generate tables, indexing amongst many arrays."; - @p "`only(expr, ...)`: Interpreting all post-`expr` arguments as member names, only expands to show those members of `expr`."; + @p "`rows(expr, ...)`: Interpreting all post-`expr` arguments as member names, only expands to show those members of `expr`."; @p "`omit(expr, ...)`: Interpreting all post-`expr` arguments as member names, expands to show all members of `expr`, except those with matching names."; @p "`range1(expr, min, max)`: Expresses that `expr` is a bounded numeric value between `min` and `max`. Interpreted by the debugger to build slider UI for an evaluation."; @p "`array(expr, count)`: Expresses that `expr` points to `count` values, rather than 1, or the fixed size implied by a static array. When expanded, displays only that many values."; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index dd46afa4..8ffe4fb1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12257,12 +12257,12 @@ rd_frame(void) {str8_lit("no_char"), 1, 1, 0, 0, 0, {0}}, {str8_lit("no_addr"), 1, 1, 0, 0, 0, {0}}, {str8_lit("sequence"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(sequence), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(sequence)}}, - {str8_lit("only"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(only), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(only)}}, + {str8_lit("rows"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(rows), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(rows)}}, + {str8_lit("columns"), 0, 0, 0, 0, 0, {0}}, {str8_lit("omit"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(omit)}}, {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, {str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}}, - {str8_lit("table"), 0, 0, 0, 0, 0, {0}}, {str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 7ac74838..9214405e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1075,13 +1075,13 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.view_ui_rule = rd_view_ui_rule_from_string(row->block->viz_expand_rule->string); //////////////////////////// - //- rjf: find possible table type + //- rjf: find possible "columns" type // E_Type *maybe_table_type = block_type; for(;;) { if(maybe_table_type->kind == E_TypeKind_Lens && - str8_match(maybe_table_type->name, str8_lit("table"), 0)) + str8_match(maybe_table_type->name, str8_lit("columns"), 0)) { break; } @@ -1100,7 +1100,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) //- rjf: @watch_row_build_cells table rows // if(0){} - else if(block->parent != &ev_nil_block && maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("table"), 0) && maybe_table_type->count >= 1) + else if(block->parent != &ev_nil_block && maybe_table_type->kind == E_TypeKind_Lens && str8_match(maybe_table_type->name, str8_lit("columns"), 0) && maybe_table_type->count >= 1) { U64 column_count = maybe_table_type->count; info.cell_style_key = push_str8f(arena, "table_%I64u_cols", column_count); From 34304280c935c581a7df229072a0c904f351155c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 10:55:39 -0700 Subject: [PATCH 684/755] fix old usage of table in mule_main; resolve to value in (sequence) --- src/eval/eval_types.c | 2 +- src/mule/mule_main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 2810513c..2f8675b5 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2502,7 +2502,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(omit) E_TYPE_EXPAND_INFO_FUNCTION_DEF(sequence) { - E_TypeExpandInfo info = {0, eval.value.u64}; + E_TypeExpandInfo info = {0, e_value_eval_from_eval(eval).value.u64}; return info; } diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index d61baf1a..ef7b19f8 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -197,7 +197,7 @@ union Matrix4x4F32 { float elements[4][4]; }; -raddbg_type_view(Matrix4x4F32, table($.elements, $[0], $[1], $[2], $[3])); +raddbg_type_view(Matrix4x4F32, columns($.elements, $[0], $[1], $[2], $[3])); union PackedF16 { @@ -427,7 +427,7 @@ type_coverage_eval_tests(void) 6 }; - raddbg_pin(table(sequence(6), fixed.pairs[$], memory_[$])); + raddbg_pin(columns(sequence(6), fixed.pairs[$], memory_[$])); raddbg_pin(basics); raddbg_pin(fixed); raddbg_pin(pointer); @@ -1886,7 +1886,7 @@ fancy_viz_eval_tests(void) { 5, 2, 8, 6 }; - raddbg_pin(table(node_indices, nodes[$])); + raddbg_pin(columns(node_indices, nodes[$])); //- rjf: bitmaps unsigned int background_color = 0x00000000; From 97c58e37478a7097b77bb9b1f011483a99bb6cf0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 11:55:06 -0700 Subject: [PATCH 685/755] start sketching out pieces for flattened expansions in rows(...) --- src/eval/eval_types.c | 28 +++++++++++++++++++++------- src/mule/mule_main.cpp | 2 +- src/raddbg/raddbg_core.c | 1 + 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 2f8675b5..4db6fab9 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -2409,24 +2409,38 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) //////////////////////////////// //~ rjf: (Built-In Type Hooks) `rows` lens +typedef struct E_RowsAccel E_RowsAccel; +struct E_RowsAccel +{ + E_Eval *root_evals; + Rng1U64 *root_evals_ranges; +}; + E_TYPE_EXPAND_INFO_FUNCTION_DEF(rows) { E_Type *type = e_type_from_key(eval.irtree.type_key); - E_TypeExpandInfo info = {0, type->count}; + E_RowsAccel *accel = push_array(arena, E_RowsAccel, 1); + accel->root_evals = push_array(arena, E_Eval, type->count); + accel->root_evals_ranges = push_array(arena, Rng1U64, type->count); + E_ParentKey(eval.key) + { + for EachIndex(idx, type->count) + { + accel->root_evals[idx] = e_eval_from_expr(type->args[idx]); + accel->root_evals_ranges[idx] = r1u64(idx, idx+1); + } + } + E_TypeExpandInfo info = {accel, type->count}; return info; } E_TYPE_EXPAND_RANGE_FUNCTION_DEF(rows) { - E_Type *type = e_type_from_key(eval.irtree.type_key); + E_RowsAccel *accel = (E_RowsAccel *)user_data; U64 out_idx = 0; for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { - E_Expr *arg = type->args[idx]; - Temp scratch = scratch_begin(&arena, 1); - String8 string = e_string_from_expr(scratch.arena, arg, str8_zero()); - evals_out[out_idx] = e_eval_wrap(eval, string); - scratch_end(scratch); + evals_out[out_idx] = accel->root_evals[idx]; } } diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index ef7b19f8..72136675 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -1785,7 +1785,7 @@ struct Bitmap int width; int height; }; -raddbg_type_view(Bitmap, lens:bitmap(base, width, height)); +raddbg_type_view(Bitmap, bitmap(base, width, height)); static unsigned int mule_bswap_u32(unsigned int x) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 8ffe4fb1..d682bba0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12259,6 +12259,7 @@ rd_frame(void) {str8_lit("sequence"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(sequence), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(sequence)}}, {str8_lit("rows"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(rows), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(rows)}}, {str8_lit("columns"), 0, 0, 0, 0, 0, {0}}, + {str8_lit("flatten"), 0, 0, 0, 0, 0, {0}}, {str8_lit("omit"), 0, 0, 0, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(omit), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(omit)}}, {str8_lit("range1"), 0, 0, 0, 0, 0, {0}}, {str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}}, From 8b8c88f310746322c096d851e8d5991eba82470e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 13:44:14 -0700 Subject: [PATCH 686/755] preserve whole chain of parent irtrees, do not simply apply only to autohook overrides; straighten out some event consumption weirdness in interaction between autocompletion floating view & query floating view; ensure we mark the cfg space as dirty when modifying strings --- src/eval/eval_ir.c | 11 +- src/raddbg/generated/raddbg.meta.c | 4 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 188 +++++++++++++++-------------- 4 files changed, 110 insertions(+), 97 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 864c376e..3f66b739 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1602,11 +1602,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) { E_IRTreeAndType *parent_irtree = parent; - if(disallow_autohooks) { - for(E_IRTreeAndType *prev = parent_irtree->prev; prev != 0; prev = prev->prev) + for(E_IRTreeAndType *prev = parent_irtree; prev != 0; prev = prev->prev) { parent_irtree = prev; + if(prev->root != &e_irnode_nil) + { + break; + } } } E_OpList oplist = e_oplist_from_irtree(arena, parent_irtree->root); @@ -2331,10 +2334,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I } //- rjf: equip previous task's irtree - if(t->overridden != 0) + if(parent != 0) { result.prev = push_array(arena, E_IRTreeAndType, 1); - result.prev[0] = *t->overridden; + result.prev[0] = *parent; } //- rjf: find any auto hooks according to this generation's type diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7bd6942a..0d652895 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -417,8 +417,8 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("watch"), str8_lit_comp("@inherit(tab) x:\n{\n @override @display_name('Tab Row Height') @description(\"Controls the tab's row height, in multiples of the font size.\")\n 'row_height': @range[1.75f, 5.f] f32,\n 'label': code_string,\n @description(\"The root expression which is evaluated to produce the watch window.\")\n 'expression': expr_string,\n @no_expand 'watches': query,\n}\n")}, {str8_lit_comp("text"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe data which should be viewed as text or code.\")\n 'expression': expr_string,\n @description(\"The language that the text should be interpreted as being within. Used for syntax highlighting and other parsing features.\")\n 'lang': code_string,\n @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers':bool,\n @no_callee_helper @default(0) @display_name('Scroll To Bottom On Change') @description(\"Scrolls to the bottom if the text is changed.\")\n 'scroll_to_bottom_on_change':bool,\n @no_callee_helper @no_revert @default(0) @display_name('Transient') @description(\"Controls whether or not this tab will be automatically replaced by the debugger when it snaps to new source code locations.\")\n 'auto': bool,\n}\n")}, {str8_lit_comp("disasm"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression to describe the base address or offset of the disassembly.\")\n 'expression': expr_string,\n 'arch': code_string,\n 'syntax': code_string,\n 'size': expr_string,\n @no_callee_helper @default(1) @description(\"Controls whether or not addresses are shown in the disassembly text.\")\n 'show_addresses': bool,\n @no_callee_helper @default(0) @description(\"Controls whether or not code bytes are shown in the disassembly text.\")\n 'show_code_bytes': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not source lines, corresponding to disassembly instruction ranges, are shown in the disassembly text.\")\n 'show_source_lines': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not disassembly text is decorated with symbol names.\")\n 'show_symbol_names': bool,\n @no_callee_helper @default(1) @description(\"Controls whether or not line numbers are shown.\")\n 'show_line_numbers': bool,\n}\n")}, -{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Address\") @description(\"An expression to describe the base address or offset of the memory view.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, -{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Base Pointer\") @description(\"An expression to describe the base address or offset of the bitmap data.\")\n 'expression': expr_string,\n @description(\"An expression describing the width of the bitmap, in pixels.\") @order(0) 'w': u64,\n @description(\"An expression describing the height of the bitmap, in pixels.\") @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, +{str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression which refers to the data which should be viewed as memory.\")\n 'expression': expr_string,\n @display_name(\"Address Range Size\") @description(\"The number of bytes of the viewed memory range.\")\n 'size': expr_string,\n @display_name(\"Cursor Address\") @description(\"The address of the cursor.\")\n 'cursor': expr_string,\n @display_name(\"Cursor Size\") @description(\"The size, in bytes, of the cursor.\")\n 'cursor_size': @range[1, 16] u64,\n @default(16) @description(\"The number of columns to build before building new rows.\")\n 'num_columns': @range[1, 64] u64,\n}\n")}, +{str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @description(\"An expression which refers to the data which should be viewed as a bitmap.\")\n 'expression': expr_string,\n @description(\"An expression describing the width of the bitmap, in pixels.\") @order(0) 'w': u64,\n @description(\"An expression describing the height of the bitmap, in pixels.\") @order(1) 'h': u64,\n @display_name(\"Bitmap Format\") @description(\"The pixel format that the bitmap data should be interpreted as being within.\")\n 'fmt': code_string,\n}\n")}, {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 806b563f..86129cf8 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -503,7 +503,7 @@ RD_VocabTable: ``` @inherit(tab) x: { - @display_name("Base Address") @description("An expression to describe the base address or offset of the memory view.") + @description("An expression which refers to the data which should be viewed as memory.") 'expression': expr_string, @display_name("Address Range Size") @description("The number of bytes of the viewed memory range.") 'size': expr_string, @@ -521,7 +521,7 @@ RD_VocabTable: ``` @inherit(tab) x: { - @display_name("Base Pointer") @description("An expression to describe the base address or offset of the bitmap data.") + @description("An expression which refers to the data which should be viewed as a bitmap.") 'expression': expr_string, @description("An expression describing the width of the bitmap, in pixels.") @order(0) 'w': u64, @description("An expression describing the height of the bitmap, in pixels.") @order(1) 'h': u64, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d682bba0..fdeafc0c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -483,6 +483,7 @@ rd_cfg_equip_string(RD_Cfg *cfg, String8 string) { rd_name_release(cfg->string); cfg->string = rd_name_alloc(string); + rd_state->cfg_change_gen += 1; } internal void @@ -1847,10 +1848,15 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) if(child_key.size != 0) { MD_NodePtrList schemas = rd_schemas_from_name(root_cfg->string); + MD_Node *expr_child_schema = &md_nil_node; MD_Node *child_schema = &md_nil_node; for(MD_NodePtrNode *n = schemas.first; n != 0 && child_schema == &md_nil_node; n = n->next) { child_schema = md_child_from_string(n->v, child_key, 0); + if(child_schema != &md_nil_node) + { + expr_child_schema = md_child_from_string(n->v, str8_lit("expression"), 0); + } } String8 child_type_name = child_schema->first->string; if(str8_match(child_type_name, str8_lit("path"), 0) || @@ -1885,25 +1891,33 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } } } - if(str8_match(child_type_name, str8_lit("bool"), 0)) + E_Key parent_key = {0}; + if(expr_child_schema != &md_nil_node && child_schema != expr_child_schema) { - B32 value = !!e_value_from_stringf("(bool)(%S)", value_string).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + parent_key = e_key_from_string(rd_cfg_child_from_string(root_cfg, expr_child_schema->string)->first->string); } - else if(str8_match(child_type_name, str8_lit("u64"), 0)) + E_ParentKey(parent_key) { - U64 value = e_value_from_stringf("(uint64)(%S)", value_string).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); - } - else if(str8_match(child_type_name, str8_lit("u32"), 0)) - { - U64 value = e_value_from_stringf("(uint32)(%S)", value_string).u64; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); - } - else if(str8_match(child_type_name, str8_lit("f32"), 0)) - { - F32 value = e_value_from_stringf("(float32)(%S)", value_string).f32; - read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + if(str8_match(child_type_name, str8_lit("bool"), 0)) + { + B32 value = !!e_value_from_stringf("(bool)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("u64"), 0)) + { + U64 value = e_value_from_stringf("(uint64)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("u32"), 0)) + { + U64 value = e_value_from_stringf("(uint32)(%S)", value_string).u64; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } + else if(str8_match(child_type_name, str8_lit("f32"), 0)) + { + F32 value = e_value_from_stringf("(float32)(%S)", value_string).f32; + read_data = push_str8_copy(scratch.arena, str8_struct(&value)); + } } } } @@ -3677,6 +3691,7 @@ rd_view_ui(Rng2F32 rect) { B32 success = 0; success = rd_commit_eval_value_string(cell->eval, new_string); + state_dirty = 1; if(!success) { log_user_error(str8_lit("Could not commit value successfully.")); @@ -7394,87 +7409,82 @@ rd_window_frame(void) { UI_TagF("inactive") UI_Transparency(1-open_t) UI_Rect(content_rect) ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_Floating, ui_key_zero()); } - } - } - - //////////////////////////// - //- rjf: @window_ui_part do special handling of floating view interactions - // - { - //- rjf: autocompletion view early-closing rules - if(autocomp_floating_view_task) - { - B32 has_autocomplete_hint = ui_autocomplete_string().size != 0; - B32 has_accept_operation = 0; - for(UI_Event *evt = 0; ui_next_event(&evt);) + + //- rjf: autocompletion view early-closing rules + if(t == autocomp_floating_view_task) { - if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept) + B32 has_autocomplete_hint = ui_autocomplete_string().size != 0; + B32 has_accept_operation = 0; + for(UI_Event *evt = 0; ui_next_event(&evt);) { - has_accept_operation = 1; - break; + if(evt->kind == UI_EventKind_Press && evt->slot == UI_EventActionSlot_Accept) + { + has_accept_operation = 1; + break; + } + } + if(has_autocomplete_hint && has_accept_operation) + { + autocomp_floating_view_task->signal.box->fixed_position = v2f32(10000, 10000); } } - if(has_autocomplete_hint && has_accept_operation) - { - autocomp_floating_view_task->signal.box->fixed_position = v2f32(10000, 10000); - } - } - - //- rjf: hover eval focus rules - if(hover_eval_floating_view_task) - { - UI_Signal sig = hover_eval_floating_view_task->signal; - if(ui_pressed(sig) || hover_eval_floating_view_task->pressed) - { - ws->hover_eval_focused = 1; - } - if(ui_mouse_over(sig) || ws->hover_eval_focused) - { - ws->hover_eval_lastt_us = rd_state->time_in_us; - } - else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) - { - rd_request_frame(); - } - if(hover_eval_floating_view_task->pressed_outside || ui_slot_press(UI_EventActionSlot_Cancel)) - { - ws->hover_eval_focused = 0; - MemoryZeroStruct(&ws->hover_eval_string); - arena_clear(ws->hover_eval_arena); - rd_request_frame(); - } - } - - //- rjf: query interactions - if(query_floating_view_task) - { - RD_Cfg *view = query_floating_view_task->view; - RD_ViewState *vs = rd_view_state_from_cfg(query_floating_view_task->view); - String8 cmd_name = ws->query_regs->cmd_name; - RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); - // rjf: close queries - if(query_floating_view_task->pressed_outside || - (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_open) || - (cmd_name.size != 0 && !vs->query_is_open) || - ui_slot_press(UI_EventActionSlot_Cancel)) + //- rjf: hover eval focus rules + if(t == hover_eval_floating_view_task) { - rd_cmd(RD_CmdKind_CancelQuery); - } - - // rjf: any queries which take a file path mutate the debugger's "current path" - if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) - { - RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); - RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); - if(input != &rd_nil_cfg) + UI_Signal sig = hover_eval_floating_view_task->signal; + if(ui_pressed(sig) || hover_eval_floating_view_task->pressed) { - String8 path_chopped = str8_chop_last_slash(input->first->string); - RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *current_path = rd_cfg_child_from_string_or_alloc(user, str8_lit("current_path")); - if(!str8_match(current_path->first->string, path_chopped, 0)) + ws->hover_eval_focused = 1; + } + if(ui_mouse_over(sig) || ws->hover_eval_focused) + { + ws->hover_eval_lastt_us = rd_state->time_in_us; + } + else if(ws->hover_eval_lastt_us+1000000 < rd_state->time_in_us) + { + rd_request_frame(); + } + if(hover_eval_floating_view_task->pressed_outside || ui_slot_press(UI_EventActionSlot_Cancel)) + { + ws->hover_eval_focused = 0; + MemoryZeroStruct(&ws->hover_eval_string); + arena_clear(ws->hover_eval_arena); + rd_request_frame(); + } + } + + //- rjf: query interactions + if(t == query_floating_view_task) + { + RD_Cfg *view = query_floating_view_task->view; + RD_ViewState *vs = rd_view_state_from_cfg(query_floating_view_task->view); + String8 cmd_name = ws->query_regs->cmd_name; + RD_CmdKindInfo *cmd_kind_info = rd_cmd_kind_info_from_string(cmd_name); + + // rjf: close queries + if(query_floating_view_task->pressed_outside || + (rd_cfg_child_from_string(view, str8_lit("lister")) != &rd_nil_cfg && !vs->query_is_open) || + (cmd_name.size != 0 && !vs->query_is_open) || + ui_slot_press(UI_EventActionSlot_Cancel)) + { + rd_cmd(RD_CmdKind_CancelQuery); + } + + // rjf: any queries which take a file path mutate the debugger's "current path" + if(cmd_kind_info->query.slot == RD_RegSlot_FilePath) + { + RD_Cfg *query = rd_cfg_child_from_string(view, str8_lit("query")); + RD_Cfg *input = rd_cfg_child_from_string(query, str8_lit("input")); + if(input != &rd_nil_cfg) { - rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + String8 path_chopped = str8_chop_last_slash(input->first->string); + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string_or_alloc(user, str8_lit("current_path")); + if(!str8_match(current_path->first->string, path_chopped, 0)) + { + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = path_chopped); + } } } } From 89e93459d7ba6df3acf3bcbb2fc2c9157c70a15c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 13:51:56 -0700 Subject: [PATCH 687/755] fix ufcs-style 'raw' lens application --- src/eval/eval_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 3f66b739..41d0767d 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1425,7 +1425,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I { e_expr_push_child(call, e_expr_copy(arena, arg)); } - if(str8_match(callee->string, str8_lit("raw"), 0)) + if(str8_match(callee->ref->string, str8_lit("raw"), 0)) { strip_lenses = 1; disallow_autohooks = 1; From e10f0489da3e5291e208dd5f1c9c5fad4b92aba1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 14:19:30 -0700 Subject: [PATCH 688/755] record which irtree-and-type generations were produced via auto-hooks; skip those when doing typeofs --- src/eval/eval_core.h | 1 + src/eval/eval_ir.c | 24 +++++++++++++++++++++++- src/raddbg/raddbg_core.c | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index c9561d3a..b88f742b 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -318,6 +318,7 @@ struct E_IRTreeAndType E_TypeKey type_key; void *user_data; E_Mode mode; + B32 auto_hook; E_MsgList msgs; E_IRTreeAndType *prev; }; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 41d0767d..94f341ba 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -903,9 +903,20 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 1, 1, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); + // rjf: find the first non-autohook result + E_TypeKey type_key = r_tree.type_key; + for(E_IRTreeAndType *t = &r_tree; t != 0; t = t->prev) + { + type_key = t->type_key; + if(t->auto_hook == 0) + { + break; + } + } + // rjf: fill output result.root = e_irtree_const_u(arena, 0); - result.type_key = r_tree.type_key; + result.type_key = type_key; result.mode = E_Mode_Null; }break; @@ -1573,6 +1584,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I case E_ExprKind_LeafIdentifier: { Temp scratch = scratch_begin(&arena, 1); + B32 is_auto_hook = 0; String8 qualifier = expr->qualifier; String8 string = expr->string; String8 string__redirected = string; @@ -1617,6 +1629,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = parent_irtree->mode; mapped_type_key = parent_irtree->type_key; + is_auto_hook = parent_irtree->auto_hook; disallow_autohooks = 1; E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); e_msg_list_concat_in_place(&result.msgs, &msgs); @@ -2054,6 +2067,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); } + //- rjf: mark if auto hook + result.auto_hook = is_auto_hook; + //- rjf: error on failure-to-generate if(!generated && !str8_match(string, str8_lit("$"), 0)) { @@ -2340,6 +2356,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I result.prev[0] = *parent; } + //- rjf: mark this result as an auto-hook, if we have an override + if(t->overridden) + { + result.auto_hook = 1; + } + //- rjf: find any auto hooks according to this generation's type if(!disallow_autohooks && result.mode != E_Mode_Null) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index fdeafc0c..b2c7622f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2428,6 +2428,7 @@ rd_view_from_eval(RD_Cfg *parent, E_Eval eval) rd_cfg_child_from_string_or_alloc(view, str8_lit("selected")); { // rjf: get expression evaluation + // TODO(rjf): we need to account for UFCS style expressions here... E_Eval expr_eval = eval; if(eval.expr->kind == E_ExprKind_Call && type_is_visualizer) { From 258b45a8377135877b1a9f4ac273ecd2b5f1c74c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 15:11:41 -0700 Subject: [PATCH 689/755] eliminate a bit of duplicate font cache lookups in code view build, + eliminate unnecessary per-box color lookups --- src/eval/eval_core.c | 5 +- .../dwrite/font_provider_dwrite.c | 2 +- src/os/core/win32/os_core_win32.c | 2 +- src/raddbg/raddbg_widgets.c | 132 +++++++++--------- src/ui/ui_core.c | 30 ++-- 5 files changed, 92 insertions(+), 79 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 1a5d11cf..158dc310 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -849,7 +849,10 @@ e_irtree_from_bundle(E_CacheBundle *bundle) bundle->flags |= E_CacheBundleFlag_IRTree; E_IRTreeAndType parent = 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, &parent, &e_default_identifier_resolution_rule, 0, 0, parse.expr); + ProfScope("irtree generation for '%.*s'", str8_varg(bundle->string)) + { + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, &e_default_identifier_resolution_rule, 0, 0, parse.expr); + } E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); } diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index f46aea56..1ed86554 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -352,7 +352,7 @@ fp_font_open(String8 path) DWORD data_size = sizeof(data); DWORD type = 0; status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Fonts", 0, KEY_QUERY_VALUE, ®_key); - status = RegEnumValueA(reg_key, 0, name, &name_size, 0, &type, data, &data_size); + status = RegEnumValueA(reg_key, 0, name, &name_size, 0, &type, (unsigned char *)data, &data_size); String8 user_fonts_path = str8_cstring(data); PathTask *task = push_array(scratch.arena, PathTask, 1); task->path = push_str8f(scratch.arena, "%s/%S", user_fonts_path, path); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index f49e7418..ed69e685 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1443,7 +1443,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"A fatal exception (code 0x%x) occurred. The process is terminating.\n", exception_code); // load dbghelp dynamically just in case if it is missing - BOOL (WINAPI *dbg_MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + BOOL (WINAPI *dbg_MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam) = 0; HMODULE dbghelp = LoadLibraryA("dbghelp.dll"); if(dbghelp) { diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1f7659c0..c2468470 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1241,6 +1241,71 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe pop_color = ui_color_from_name(str8_lit("background")); } + ////////////////////////////// + //- rjf: produce fancy strings for each line + // + DR_FStrList *lines_fstrs = push_array(scratch.arena, DR_FStrList, dim_1s64(params->line_num_range)+1); + { + DR_FStrParams fstr_params = + { + params->font, + rd_raster_flags_from_slot(RD_FontSlot_Code), + rd_rgba_from_code_color_slot(RD_CodeColorSlot_CodeDefault), + params->font_size, + }; + U64 line_idx = 0; + for(S64 line_num = params->line_num_range.min; + line_num < params->line_num_range.max; + line_num += 1, line_idx += 1) + { + String8 line_string = params->line_text[line_idx]; + Rng1U64 line_range = params->line_ranges[line_idx]; + TXT_TokenArray *line_tokens = ¶ms->line_tokens[line_idx]; + DR_FStrList fstrs = {0}; + if(line_tokens->count == 0) + { + dr_fstrs_push_new(scratch.arena, &fstrs, &fstr_params, line_string); + } + else + { + TXT_Token *line_tokens_first = line_tokens->v; + TXT_Token *line_tokens_opl = line_tokens->v + line_tokens->count; + for(TXT_Token *token = line_tokens_first; token < line_tokens_opl; token += 1) + { + // rjf: token -> token string + String8 token_string = {0}; + { + Rng1U64 token_range = r1u64(0, line_string.size); + if(token->range.min > line_range.min) + { + token_range.min += token->range.min-line_range.min; + } + if(token->range.max < line_range.max) + { + token_range.max = token->range.max-line_range.min; + } + token_string = str8_substr(line_string, token_range); + } + + // rjf: token -> token color + RD_CodeColorSlot token_color_slot = rd_code_color_slot_from_txt_token_kind(token->kind); + RD_CodeColorSlot lookup_color_slot = rd_code_color_slot_from_txt_token_kind_lookup_string(token->kind, token_string); + Vec4F32 token_color = rd_rgba_from_code_color_slot(token_color_slot); + if(lookup_color_slot != RD_CodeColorSlot_CodeDefault) + { + Vec4F32 lookup_color = rd_rgba_from_code_color_slot(lookup_color_slot); + F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); + token_color = mix_4f32(token_color, lookup_color, lookup_color_mix_t); + } + + // rjf: push fancy string + dr_fstrs_push_new(scratch.arena, &fstrs, &fstr_params, token_string, .color = token_color); + } + } + lines_fstrs[line_idx] = fstrs; + } + } + ////////////////////////////// //- rjf: build top-level container // @@ -1885,8 +1950,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num < params->line_num_range.max; line_num += 1, line_idx += 1) { - String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = fnt_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; + DR_FStrList line_fstrs = lines_fstrs[line_idx]; + F32 line_text_dim = dr_dim_from_fstrs(&line_fstrs).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; line_extras_off[line_idx] = Max(line_text_dim, params->font_size*30); } } @@ -2445,7 +2510,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { String8 line_string = params->line_text[line_idx]; Rng1U64 line_range = params->line_ranges[line_idx]; - TXT_TokenArray *line_tokens = ¶ms->line_tokens[line_idx]; + DR_FStrList line_fstrs = lines_fstrs[line_idx]; ui_set_next_text_padding(line_num_padding_px); UI_Key line_key = ui_key_from_stringf(top_container_box->key, "ln_%I64x", line_num); Vec4F32 line_bg_color = line_bg_colors[line_idx]; @@ -2458,67 +2523,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe UI_Box *line_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, line_key); DR_Bucket *line_bucket = dr_bucket_make(); dr_push_bucket(line_bucket); - - // rjf: string * tokens -> fancy string list - DR_FStrList line_fstrs = {0}; - { - if(line_tokens->count == 0) - { - DR_FStrParams fstr_params = - { - params->font, - ui_top_text_raster_flags(), - rd_rgba_from_code_color_slot(RD_CodeColorSlot_CodeDefault), - params->font_size, - }; - dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, line_string); - } - else - { - TXT_Token *line_tokens_first = line_tokens->v; - TXT_Token *line_tokens_opl = line_tokens->v + line_tokens->count; - for(TXT_Token *token = line_tokens_first; token < line_tokens_opl; token += 1) - { - // rjf: token -> token string - String8 token_string = {0}; - { - Rng1U64 token_range = r1u64(0, line_string.size); - if(token->range.min > line_range.min) - { - token_range.min += token->range.min-line_range.min; - } - if(token->range.max < line_range.max) - { - token_range.max = token->range.max-line_range.min; - } - token_string = str8_substr(line_string, token_range); - } - - // rjf: token -> token color - RD_CodeColorSlot token_color_slot = rd_code_color_slot_from_txt_token_kind(token->kind); - RD_CodeColorSlot lookup_color_slot = rd_code_color_slot_from_txt_token_kind_lookup_string(token->kind, token_string); - Vec4F32 token_color = rd_rgba_from_code_color_slot(token_color_slot); - if(lookup_color_slot != RD_CodeColorSlot_CodeDefault) - { - Vec4F32 lookup_color = rd_rgba_from_code_color_slot(lookup_color_slot); - F32 lookup_color_mix_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "%S_lookup", token_string), 1.f); - token_color = mix_4f32(token_color, lookup_color, lookup_color_mix_t); - } - - // rjf: push fancy string - DR_FStrParams fstr_params = - { - params->font, - ui_top_text_raster_flags(), - token_color, - params->font_size, - }; - dr_fstrs_push_new(scratch.arena, &line_fstrs, &fstr_params, token_string); - } - } - } - - // rjf: equip fancy strings to line box ui_box_equip_display_fstrs(line_box, &line_fstrs); // rjf: extra rendering for strings that are currently being searched for diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 0d3c78f3..9659939d 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2584,21 +2584,27 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) { box->tags_key = ui_state->tags_key_stack_top->key; } - if(ui_state->background_color_stack.top != &ui_state->background_color_nil_stack_top) + if(box->flags & UI_BoxFlag_DrawBackground) { - box->background_color = ui_state->background_color_stack.top->v; + if(ui_state->background_color_stack.top != &ui_state->background_color_nil_stack_top) + { + box->background_color = ui_state->background_color_stack.top->v; + } + else + { + box->background_color = ui_color_from_name(str8_lit("background")); + } } - else + if(box->flags & UI_BoxFlag_DrawText) { - box->background_color = ui_color_from_name(str8_lit("background")); - } - if(ui_state->text_color_stack.top != &ui_state->text_color_nil_stack_top) - { - box->text_color = ui_state->text_color_stack.top->v; - } - else - { - box->text_color = ui_color_from_name(str8_lit("text")); + if(ui_state->text_color_stack.top != &ui_state->text_color_nil_stack_top) + { + box->text_color = ui_state->text_color_stack.top->v; + } + else + { + box->text_color = ui_color_from_name(str8_lit("text")); + } } } From 5532aa690359c09d4faf428fa09d7195b23ef5a0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 16:23:31 -0700 Subject: [PATCH 690/755] rdi_from_pdb: when relative paths are supplied by line info, build them as being relative to OBJ; this is not necessarily correct but it is the best thing we can do given the available information. the user needs to remap this once in the debugger, but then it will work. --- src/raddbg/raddbg_core.c | 2 +- src/rdi_from_pdb/rdi_from_pdb.c | 35 +++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b2c7622f..a6899d88 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -14557,7 +14557,7 @@ rd_frame(void) U64 vaddr = 0; B32 require_disasm_snap = 0; { - file_path = rd_regs()->file_path; + file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path); point = rd_regs()->cursor; thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 70105610..b6b61b0e 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -616,13 +616,14 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } } - //- rjf: produce obj name + //- rjf: produce obj name/path String8 obj_name = pdb_unit->obj_name; if(str8_match(obj_name, str8_lit("* Linker *"), 0) || str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) { MemoryZeroStruct(&obj_name); } + String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); //- rjf: build this unit's line table, fill out primary line info (inline info added after) RDIM_LineTable *line_table = 0; @@ -644,6 +645,13 @@ ASYNC_WORK_DEF(p2r_units_convert_work) { PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); + if(file_path_normalized_style == PathStyle_Relative) + { + String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); + str8_list_concat_in_place(&obj_folder_path_parts, &file_path_normalized_parts); + file_path_normalized_parts = obj_folder_path_parts; + file_path_normalized_style = path_style_from_str8(obj_folder_path); + } str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); } @@ -715,10 +723,23 @@ ASYNC_WORK_DEF(p2r_units_convert_work) ProfScope("pass 3: parse all inlinee line tables") for(U64 comp_unit_idx = 0; comp_unit_idx < in->comp_units->count; comp_unit_idx += 1) { + //- rjf: unpack unit + PDB_CompUnit *pdb_unit = in->comp_units->units[comp_unit_idx]; CV_SymParsed *unit_sym = in->comp_unit_syms[comp_unit_idx]; CV_C13Parsed *unit_c13 = in->comp_unit_c13s[comp_unit_idx]; CV_RecRange *rec_ranges_first = unit_sym->sym_ranges.ranges; CV_RecRange *rec_ranges_opl = rec_ranges_first+unit_sym->sym_ranges.count; + + //- rjf: produce obj name/path + String8 obj_name = pdb_unit->obj_name; + if(str8_match(obj_name, str8_lit("* Linker *"), 0) || + str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) + { + MemoryZeroStruct(&obj_name); + } + String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); + + //- rjf: parse inlinee line tables U64 base_voff = 0; for(CV_RecRange *rec_range = rec_ranges_first; rec_range < rec_ranges_opl; @@ -839,12 +860,18 @@ ASYNC_WORK_DEF(p2r_units_convert_work) // rjf: file name -> normalized file path String8 file_path = seq_file_name; String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); - for(U64 idx = 0; idx < file_path_normalized.size; idx += 1) { - if(file_path_normalized.str[idx] == '\\') + PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); + String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); + if(file_path_normalized_style == PathStyle_Relative) { - file_path_normalized.str[idx] = '/'; + String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); + str8_list_concat_in_place(&obj_folder_path_parts, &file_path_normalized_parts); + file_path_normalized_parts = obj_folder_path_parts; + file_path_normalized_style = path_style_from_str8(obj_folder_path); } + str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); + file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); } // rjf: normalized file path -> source file node From 271e8e4523de25d08950471e67f59682b42006d3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 May 2025 16:29:23 -0700 Subject: [PATCH 691/755] deduplicate new file path maps on-add --- src/raddbg/raddbg_core.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a6899d88..71591dfd 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13552,11 +13552,27 @@ rd_frame(void) //- rjf: store as file path map cfg RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); - RD_Cfg *map = rd_cfg_new(user, str8_lit("file_path_map")); - RD_Cfg *src = rd_cfg_new(map, str8_lit("source")); - RD_Cfg *dst = rd_cfg_new(map, str8_lit("dest")); - rd_cfg_new(src, map_src); - rd_cfg_new(dst, map_dst); + { + RD_CfgList cfgs = rd_cfg_child_list_from_string(scratch.arena, user, str8_lit("file_path_map")); + RD_Cfg *map = &rd_nil_cfg; + for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next) + { + RD_Cfg *src = rd_cfg_child_from_string(n->v, str8_lit("source")); + if(path_match_normalized(src->first->string, map_src)) + { + map = n->v; + break; + } + } + if(map == &rd_nil_cfg) + { + map = rd_cfg_new(user, str8_lit("file_path_map")); + } + RD_Cfg *src = rd_cfg_child_from_string_or_alloc(map, str8_lit("source")); + RD_Cfg *dst = rd_cfg_child_from_string_or_alloc(map, str8_lit("dest")); + rd_cfg_new_replace(src, map_src); + rd_cfg_new_replace(dst, map_dst); + } }break; //- rjf: panel removal From ad714e9baa1ab7a23d827ce084342c799074eb79 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 08:11:13 -0700 Subject: [PATCH 692/755] dwrite: do not try to create font face if font file creation fails --- src/font_provider/dwrite/font_provider_dwrite.c | 5 ++++- src/raddbg/raddbg_core.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 1ed86554..0a0c7737 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -337,7 +337,10 @@ fp_font_open(String8 path) { String16 path16 = str16_from_8(scratch.arena, t->path); error = IDWriteFactory_CreateFontFileReference(fp_dwrite_state->factory, (WCHAR *)path16.str, 0, &font.file); - error = IDWriteFactory_CreateFontFace(fp_dwrite_state->factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font.file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font.face); + if(font.file != 0) + { + error = IDWriteFactory_CreateFontFace(fp_dwrite_state->factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font.file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font.face); + } // rjf: failure trying just the normal path? -> generate new tasks that search in system folders if(t == first_task && font.file == 0) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 71591dfd..292988ab 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11310,7 +11310,8 @@ rd_frame(void) { U64 candidate_frame_time_us = 1000000/(U64)candidate; S64 frame_time_us_diff = (S64)frame_time_history_avg_us - (S64)candidate_frame_time_us; - if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff) + if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff && + frame_time_history_avg_us < candidate_frame_time_us + 1000) { best_target_hz = candidate; best_target_hz_frame_time_us_diff = frame_time_us_diff; From a371374d6c6d82eb6a4a1e1864819b8022df3cda Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 08:19:30 -0700 Subject: [PATCH 693/755] require file existence before calling into dwrite --- src/font_provider/dwrite/font_provider_dwrite.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/font_provider/dwrite/font_provider_dwrite.c b/src/font_provider/dwrite/font_provider_dwrite.c index 0a0c7737..003fd299 100644 --- a/src/font_provider/dwrite/font_provider_dwrite.c +++ b/src/font_provider/dwrite/font_provider_dwrite.c @@ -335,15 +335,19 @@ fp_font_open(String8 path) //- rjf: try to open font for(PathTask *t = first_task; t != 0 && font.file == 0; t = t->next) { + B32 file_exists = (os_properties_from_file_path(t->path).created != 0); String16 path16 = str16_from_8(scratch.arena, t->path); - error = IDWriteFactory_CreateFontFileReference(fp_dwrite_state->factory, (WCHAR *)path16.str, 0, &font.file); + if(file_exists) + { + error = IDWriteFactory_CreateFontFileReference(fp_dwrite_state->factory, (WCHAR *)path16.str, 0, &font.file); + } if(font.file != 0) { error = IDWriteFactory_CreateFontFace(fp_dwrite_state->factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font.file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font.face); } // rjf: failure trying just the normal path? -> generate new tasks that search in system folders - if(t == first_task && font.file == 0) + if(t == first_task && font.file == 0 && t->path.size != 0) { // rjf: generate task for user-installed fonts { From 141b96c17ebba66e8b6a1949417a3a9430068586 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 08:21:54 -0700 Subject: [PATCH 694/755] do not skip 0 with texture formats --- src/raddbg/raddbg_views.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 9214405e..7d943f60 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -3532,7 +3532,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) Vec2S32 dim = v2s32((S32)rd_view_setting_u64_from_name(str8_lit("w")), (S32)rd_view_setting_u64_from_name(str8_lit("h"))); String8 fmt_string = rd_view_setting_from_name(str8_lit("fmt")); R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; - for EachNonZeroEnumVal(R_Tex2DFormat, f) + for EachEnumVal(R_Tex2DFormat, f) { if(str8_match(fmt_string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) { From 70ae35cbd7c0fdc30b4ed23bf7afdb30c31a7d6d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 09:51:46 -0700 Subject: [PATCH 695/755] do not use worker thread arenas from main thread in rdi baker... --- project.4coder | 3 +- src/rdi_make/rdi_make_help.c | 72 ++++++++-------- src/rdi_make/rdi_make_local.c | 152 +++++++++++++++------------------- 3 files changed, 105 insertions(+), 122 deletions(-) diff --git a/project.4coder b/project.4coder index 22f59d81..5be24aab 100644 --- a/project.4coder +++ b/project.4coder @@ -55,7 +55,8 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target - .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c index 28d27f22..35ff0d9b 100644 --- a/src/rdi_make/rdi_make_help.c +++ b/src/rdi_make/rdi_make_help.c @@ -402,12 +402,12 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) { Temp scratch = scratch_begin(0,0); RDIM_BakeResults out = {0}; - + rdim_help_state = state; - + //////////////////////////////// // compute type indices - + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); ////////////////////////////// @@ -426,7 +426,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) RDIM_BakePathTree *path_tree = 0; ProfScope("build interned path tree") { - path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + path_tree = rdim_bake_path_tree_from_params(state->arena, in_params); } ////////////////////////////// @@ -564,7 +564,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) } } } - + ProfScope("kick off inline site string map build task") { U64 items_per_task = 4096; @@ -658,7 +658,7 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) ////////////////////////////// //- rjf: produce joined string map // - RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->arena, &bake_string_map_topology); ProfScope("produce joined string map") { U64 slots_per_task = 16384; @@ -685,16 +685,16 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) } // rjf: insert small top-level stuff - rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + rdim_bake_string_map_loose_push_top_level_info(state->arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->arena, &bake_string_map_topology, unsorted_bake_string_map, path_tree); } ////////////////////////////// //- rjf: kick off string map sorting tasks // ASYNC_TaskList sort_bake_string_map_tasks = {0}; - RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->arena, &bake_string_map_topology); { U64 slots_per_task = 4096; U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; @@ -732,10 +732,10 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) //- rjf: build finalized string map // ProfBegin("build finalized string map base indices"); - RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->arena, &bake_string_map_topology, sorted_bake_string_map); ProfEnd(); ProfBegin("build finalized string map"); - RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->arena, &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); ProfEnd(); ////////////////////////////// @@ -759,31 +759,31 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); - + RDIM_String8List location_blocks = {0}; RDIM_String8List location_data_blobs = {0}; - + // reserve null location block for opl - rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); - + rdim_location_block_chunk_list_push_array(state->arena, &location_blocks, 1); + // TODO: export location instead of VOFF RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - + // TODO: export location instead of VOFF RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - + ////////////////////////////// //- rjf: join name map building tasks // @@ -804,15 +804,15 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) RDIM_BakeIdxRunMap *idx_runs = 0; ProfScope("build interned idx run map") { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); + idx_runs = rdim_bake_idx_run_map_from_params(state->arena, name_maps, type_indices, in_params); } ////////////////////////////// //- rjf: do small top-level bakes // - ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->arena, &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->arena, &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->arena, &bake_strings, idx_runs, name_maps); ////////////////////////////// //- rjf: kick off pass 3 tasks @@ -875,15 +875,15 @@ rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) // ProfScope("join all name map bakes into final name map bake") { - out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + out.name_maps = rdim_name_map_bake_results_combine(state->arena, name_map_bakes, ArrayCount(name_map_bakes)); } - - + + //////////////////////////////// - - out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); - out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); - + + out.location_blocks = rdim_str8_list_join(state->arena, &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->arena, &location_data_blobs, rdim_str8(0,0)); + rdim_help_state = 0; scratch_end(scratch); @@ -894,22 +894,22 @@ internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) { RDIM_SerializedSectionBundle out = {0}; - + //- rjf: set up compression context rr_lzb_simple_context ctx = {0}; ctx.m_tableSizeBits = 14; ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; RDIM_SerializedSection *dst = &out.sections[k]; MemoryCopyStruct(dst, src); - + // rjf: determine if this section should be compressed B32 should_compress = 1; - + // rjf: compress if needed if(should_compress) { @@ -920,6 +920,6 @@ rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) dst->encoding = RDI_SectionEncoding_LZB; } } - + return out; } diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index 575a5421..01fa4949 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -9,31 +9,13 @@ internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) { RDIM_DataModel data_model = RDIM_DataModel_Null; - switch (os) { - case OperatingSystem_Null: break; - case OperatingSystem_Windows: { - switch (arch) { - case RDI_Arch_X86: - case RDI_Arch_X64: - data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Linux: { - switch (arch) { - case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Mac: { - switch (arch) { - case RDI_Arch_X86: NotImplemented; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; - } - } break; - default: InvalidPath; - } +#define Case(os_name, arch_name, model_name) if(os == OperatingSystem_##os_name && arch == Arch_##arch_name) { data_model = RDIM_DataModel_##model_name; } + Case(Windows, x86, LLP64); + Case(Windows, x64, LLP64); + Case(Linux, x86, ILP32); + Case(Linux, x64, LLP64); + Case(Mac, x64, LP64); +#undef Case return data_model; } @@ -45,28 +27,28 @@ rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_Binar // convert arch RDI_Arch arch_rdi; switch (arch) { - case Arch_Null: arch_rdi = RDI_Arch_NULL; break; - case Arch_x64: arch_rdi = RDI_Arch_X64; break; - case Arch_x86: arch_rdi = RDI_Arch_X86; break; - default: NotImplemented; break; + case Arch_Null: arch_rdi = RDI_Arch_NULL; break; + case Arch_x64: arch_rdi = RDI_Arch_X64; break; + case Arch_x86: arch_rdi = RDI_Arch_X86; break; + default: NotImplemented; break; } - - + + // find max VOFF U64 exe_voff_max = 0; for (RDIM_BinarySectionNode *sect_n = sections.first; sect_n != 0 ; sect_n = sect_n->next) { exe_voff_max = Max(exe_voff_max, sect_n->v.voff_opl); } - - + + // fill out top level info RDIM_TopLevelInfo top_level_info = {0}; top_level_info.arch = arch_rdi; top_level_info.exe_hash = exe_hash; top_level_info.voff_max = exe_voff_max; top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); - - + + return top_level_info; } @@ -467,11 +449,11 @@ internal void rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList *udts) { ProfBeginFunction(); - + Temp scratch = scratch_begin(0,0); - + U64 total_type_count = types->total_count + 1; - + ProfBegin("Build Hash Table"); RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, total_type_count); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) @@ -483,7 +465,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList { RDIM_String8 name = type->link_name.size ? type->link_name : type->name; RDI_U64 hash = rdim_local_hash(name); - + RDI_U64 best_slot = hash % types->total_count; RDI_U64 slot = best_slot; do @@ -493,7 +475,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList { break; } - + if(s->link_name.size) { if(str8_match(s->link_name, name, 0)) @@ -508,10 +490,10 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList break; } } - + slot = (slot + 1) % total_type_count; } while (slot != best_slot); - + if(name_ht[slot] == 0) { name_ht[slot] = type; @@ -520,7 +502,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList } } ProfEnd(); - + ProfBegin("Make Fwd Map"); RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, total_type_count); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) @@ -528,14 +510,14 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList for(RDI_U64 i = 0; i < chunk->count; i += 1) { RDIM_Type *type = &chunk->v[i]; - + if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) { RDIM_String8 name = type->link_name.size ? type->link_name : type->name; RDI_U64 hash = rdim_local_hash(name); RDI_U64 best_slot = hash % types->total_count; RDI_U64 slot = best_slot; - + RDIM_Type *match = 0; do { @@ -560,14 +542,14 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList break; } } - + slot = (slot + 1) % total_type_count; } while(slot != best_slot); - + if(match) { type->kind = RDI_TypeKind_NULL; - + RDI_U64 type_idx = rdim_idx_from_type(type); fwd_map[type_idx] = match; } @@ -575,7 +557,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList } } ProfEnd(); - + ProfBegin("Resolve Types"); for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) { @@ -613,7 +595,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList { udt->self_type = fwd_map[self_idx]; } - + for(RDIM_UDTMember *member = udt->first_member; member != 0; member = member->next) { RDI_U64 member_idx = rdim_idx_from_type(member->type); @@ -625,7 +607,7 @@ rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types, RDIM_UDTChunkList } } ProfEnd(); - + scratch_end(scratch); ProfEnd(); } @@ -650,7 +632,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { Temp scratch = scratch_begin(0,0); RDIM_BakeResults out = {0}; - + rdim_local_state = state; ////////////////////////////// @@ -669,7 +651,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) RDIM_BakePathTree *path_tree = 0; ProfScope("build interned path tree") { - path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + path_tree = rdim_bake_path_tree_from_params(state->arena, in_params); } ////////////////////////////// @@ -807,7 +789,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) } } } - + ProfScope("kick off inline site string map build task") { U64 items_per_task = 4096; @@ -900,7 +882,7 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) ////////////////////////////// //- rjf: produce joined string map // - RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->arena, &bake_string_map_topology); ProfScope("produce joined string map") { U64 slots_per_task = 16384; @@ -927,16 +909,16 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) } // rjf: insert small top-level stuff - rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + rdim_bake_string_map_loose_push_top_level_info(state->arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->arena, &bake_string_map_topology, unsorted_bake_string_map, path_tree); } ////////////////////////////// //- rjf: kick off string map sorting tasks // ASYNC_TaskList sort_bake_string_map_tasks = {0}; - RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->arena, &bake_string_map_topology); { U64 slots_per_task = 4096; U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; @@ -974,10 +956,10 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) //- rjf: build finalized string map // ProfBegin("build finalized string map base indices"); - RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->arena, &bake_string_map_topology, sorted_bake_string_map); ProfEnd(); ProfBegin("build finalized string map"); - RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->arena, &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); ProfEnd(); ////////////////////////////// @@ -1001,31 +983,31 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); - + RDIM_String8List location_blocks = {0}; RDIM_String8List location_data_blobs = {0}; - + // reserve null location block for opl - rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); - + rdim_location_block_chunk_list_push_array(state->arena, &location_blocks, 1); + // TODO: export location instead of VOFF RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - + // TODO: export location instead of VOFF RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, &location_blocks, &location_data_blobs}; ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - + ////////////////////////////// //- rjf: join name map building tasks // @@ -1046,15 +1028,15 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) RDIM_BakeIdxRunMap *idx_runs = 0; ProfScope("build interned idx run map") { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, in_params); + idx_runs = rdim_bake_idx_run_map_from_params(state->arena, name_maps, in_params); } ////////////////////////////// //- rjf: do small top-level bakes // - ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->arena, &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->arena, &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->arena, &bake_strings, idx_runs, name_maps); ////////////////////////////// //- rjf: kick off pass 3 tasks @@ -1117,15 +1099,15 @@ rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) // ProfScope("join all name map bakes into final name map bake") { - out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + out.name_maps = rdim_name_map_bake_results_combine(state->arena, name_map_bakes, ArrayCount(name_map_bakes)); } - - + + //////////////////////////////// - - out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); - out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); - + + out.location_blocks = rdim_str8_list_join(state->arena, &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->arena, &location_data_blobs, rdim_str8(0,0)); + rdim_local_state = 0; scratch_end(scratch); @@ -1136,22 +1118,22 @@ internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) { RDIM_SerializedSectionBundle out = {0}; - + //- rjf: set up compression context rr_lzb_simple_context ctx = {0}; ctx.m_tableSizeBits = 14; ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; RDIM_SerializedSection *dst = &out.sections[k]; MemoryCopyStruct(dst, src); - + // rjf: determine if this section should be compressed B32 should_compress = 1; - + // rjf: compress if needed if(should_compress) { @@ -1162,7 +1144,7 @@ rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) dst->encoding = RDI_SectionEncoding_LZB; } } - + return out; } From 2e2eb4a6f2288d03bb7e1ed594ab87b31d828b74 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 09:53:50 -0700 Subject: [PATCH 696/755] bump to 18 --- src/base/base_context_cracking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index d1717744..976ff941 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -159,7 +159,7 @@ #endif #if !defined(BUILD_VERSION_PATCH) -# define BUILD_VERSION_PATCH 17 +# define BUILD_VERSION_PATCH 18 #endif #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) From 10c4dcecd12e72274979e93c7408cbe5b678a8e5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 10:15:42 -0700 Subject: [PATCH 697/755] do not prohibit same-rips from stopping unwinds --- src/ctrl/ctrl_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 9ad6dd4f..e201843a 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3142,8 +3142,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa unwind.flags |= step.flags; if(step.flags & CTRL_UnwindFlag_Error || regs_rsp_from_arch_block(arch, regs_block) == 0 || - regs_rip_from_arch_block(arch, regs_block) == 0 || - regs_rip_from_arch_block(arch, regs_block) == rip) + regs_rip_from_arch_block(arch, regs_block) == 0) { break; } From a67f326f78efab703c2af392701ffdb85bdb5c45 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 10:27:01 -0700 Subject: [PATCH 698/755] eliminate redundant recomputation of ir extensions --- src/eval/eval_ir.c | 7 +++++-- src/raddbg/raddbg_views.c | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 94f341ba..b3aa726c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1597,6 +1597,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I E_Mode mapped_bytecode_mode = E_Mode_Offset; E_Space mapped_bytecode_space = zero_struct; String8 mapped_bytecode = {0}; + void *mapped_user_data = 0; B32 generated = 0; //- rjf: iterate identifier resolution rule paths, try to resolve @@ -1629,6 +1630,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); mapped_bytecode_mode = parent_irtree->mode; mapped_type_key = parent_irtree->type_key; + mapped_user_data = parent_irtree->user_data; is_auto_hook = parent_irtree->auto_hook; disallow_autohooks = 1; E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); @@ -2067,8 +2069,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access); } - //- rjf: mark if auto hook + //- rjf: mark if auto hook, equip user data result.auto_hook = is_auto_hook; + result.user_data = mapped_user_data; //- rjf: error on failure-to-generate if(!generated && !str8_match(string, str8_lit("$"), 0)) @@ -2269,7 +2272,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I break; } } - if(irext != 0) + if(irext != 0 && result.user_data == 0) { E_IRTreeAndType irtree_stripped = result; if(type->kind == E_TypeKind_Lens) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 7d943f60..8b2accfc 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1430,9 +1430,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct From e60e0c85550291608ffe5c1e1eaa980f1eb9009e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 11:43:01 -0700 Subject: [PATCH 699/755] sketch out unwind cache --- src/ctrl/ctrl_core.c | 126 ++++++++++++++----------------- src/ctrl/ctrl_core.h | 54 +++++++++++-- src/dbg_engine/dbg_engine_core.c | 22 +++--- src/raddbg/raddbg_core.c | 12 +-- 4 files changed, 118 insertions(+), 96 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e201843a..6b14633f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1084,7 +1084,7 @@ internal CTRL_Entity * ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates) { CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - U64 thread_rip_vaddr = ctrl_query_cached_rip_from_thread(store, thread->handle); + U64 thread_rip_vaddr = ctrl_rip_from_thread(store, thread->handle); CTRL_Entity *src_module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); CTRL_Entity *module = &ctrl_entity_nil; for(CTRL_EntityNode *n = candidates->first; n != 0; n = n->next) @@ -1266,7 +1266,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) } } thread->stack_base = event->stack_base; - ctrl_query_cached_rip_from_thread(store, event->entity); + ctrl_rip_from_thread(store, event->entity); }break; case CTRL_EventKind_EndThread: { @@ -1432,6 +1432,15 @@ ctrl_init(void) ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc(); ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } + ctrl_state->thread_unwind_cache.slots_count = 1024; + ctrl_state->thread_unwind_cache.slots = push_array(arena, CTRL_ThreadUnwindCacheSlot, ctrl_state->thread_unwind_cache.slots_count); + ctrl_state->thread_unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; + ctrl_state->thread_unwind_cache.stripes = push_array(arena, CTRL_ThreadUnwindCacheStripe, ctrl_state->thread_unwind_cache.stripes_count); + for(U64 idx = 0; idx < ctrl_state->thread_unwind_cache.stripes_count; idx += 1) + { + ctrl_state->thread_unwind_cache.stripes[idx].arena = arena_alloc(); + ctrl_state->thread_unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); + } ctrl_state->module_image_info_cache.slots_count = 1024; ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count); ctrl_state->module_image_info_cache.stripes_count = os_get_system_info()->logical_processor_count; @@ -1686,7 +1695,7 @@ ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, //- rjf: process memory cache reading helpers internal CTRL_ProcessMemorySlice -ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us) +ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us) { ProfBeginFunction(); CTRL_ProcessMemorySlice result = {0}; @@ -1829,37 +1838,12 @@ ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle proces return result; } -internal CTRL_ProcessMemorySlice -ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us) -{ - CTRL_ProcessMemorySlice result = ctrl_query_cached_data_from_process_vaddr_range(arena, process, r1u64(vaddr, vaddr+limit), endt_us); - U64 element_count = result.data.size/element_size; - for(U64 element_idx = 0; element_idx < element_count; element_idx += 1) - { - B32 element_is_zero = 1; - for(U64 element_byte_idx = 0; element_byte_idx < element_size; element_byte_idx += 1) - { - if(result.data.str[element_idx*element_size + element_byte_idx] != 0) - { - element_is_zero = 0; - break; - } - } - if(element_is_zero) - { - result.data.size = element_idx*element_size; - break; - } - } - return result; -} - internal B32 -ctrl_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us) +ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us) { Temp scratch = scratch_begin(0, 0); U64 needed_size = dim_1u64(range); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process, range, endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, range, endt_us); B32 good = (slice.data.size >= needed_size && !slice.any_byte_bad); if(good) { @@ -1932,7 +1916,7 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src) for(Task *task = first_task; task != 0; task = task->next) { Temp temp = temp_begin(scratch.arena); - ctrl_query_cached_data_from_process_vaddr_range(temp.arena, task->process, task->range, endt_us); + ctrl_process_memory_slice_from_vaddr_range(temp.arena, task->process, task->range, endt_us); temp_end(temp); } @@ -1949,7 +1933,7 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src) //- rjf: thread register cache reading internal void * -ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle) { CTRL_ThreadRegCache *cache = &ctrl_state->thread_reg_cache; CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); @@ -2008,31 +1992,31 @@ ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, C } internal U64 -ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) { U64 result = dmn_tls_root_vaddr_from_thread(handle.dmn_handle); return result; } internal U64 -ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) { Temp scratch = scratch_begin(0, 0); CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); Arch arch = thread_entity->arch; - void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle); U64 result = regs_rip_from_arch_block(arch, block); scratch_end(scratch); return result; } internal U64 -ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) { Temp scratch = scratch_begin(0, 0); CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); Arch arch = thread_entity->arch; - void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle); U64 result = regs_rsp_from_arch_block(arch, block); scratch_end(scratch); return result; @@ -2294,7 +2278,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 inst[4] = {0}; if(read_vaddr + sizeof(inst) <= read_vaddr_opl) { - inst_good = ctrl_read_cached_process_memory(process_handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us); + inst_good = ctrl_process_memory_read(process_handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us); inst_good = inst_good && !is_stale; } if(!inst_good) @@ -2375,7 +2359,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 inst_byte = 0; if(read_vaddr + sizeof(inst_byte) <= read_vaddr_opl) { - inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); } if(!inst_byte_good || is_stale) { @@ -2391,7 +2375,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT check_vaddr = read_vaddr + 1; if(read_vaddr + sizeof(check_inst_byte) <= read_vaddr_opl) { - check_inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us); + check_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us); } if(!check_inst_byte_good || is_stale) { @@ -2427,7 +2411,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 imm_good = 0; if(read_vaddr + sizeof(imm) <= read_vaddr_opl) { - imm_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us); + imm_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us); } if(!imm_good || is_stale) { @@ -2456,7 +2440,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 next_inst_byte_good = 0; if(read_vaddr + sizeof(next_inst_byte) <= read_vaddr_opl) { - next_inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &next_inst_byte, endt_us); + next_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &next_inst_byte, endt_us); } if(next_inst_byte_good) { @@ -2485,7 +2469,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT //- rjf: read next instruction byte U8 inst_byte = 0; - is_good = is_good && ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && !is_stale; read_vaddr += 1; @@ -2494,7 +2478,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT if((inst_byte & 0xF0) == 0x40) { rex = inst_byte & 0xF; // rex prefix - is_good = is_good && ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && !is_stale; read_vaddr += 1; } @@ -2515,7 +2499,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read value at rsp U64 sp = regs->rsp.u64; U64 value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &value, endt_us) || is_stale) { is_good = 0; @@ -2540,7 +2524,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read the 4-byte immediate S32 imm = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2563,7 +2547,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read the 4-byte immediate S8 imm = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2583,7 +2567,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT { // rjf: read source register U8 modrm = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &modrm, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &modrm, endt_us) || is_stale) { is_good = 0; @@ -2601,7 +2585,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT if((modrm >> 6) == 1) { S8 imm8 = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm8, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm8, endt_us) || is_stale) { is_good = 0; @@ -2614,7 +2598,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read 4-byte immediate else { - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2637,7 +2621,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read new ip U64 sp = regs->rsp.u64; U64 new_ip = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || is_stale) { is_good = 0; @@ -2646,7 +2630,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read 2-byte immediate & advance stack pointer U16 imm = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2669,7 +2653,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read new ip U64 sp = regs->rsp.u64; U64 new_ip = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || is_stale) { is_good = 0; @@ -2716,7 +2700,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT { U64 unwind_info_off = first_pdata->voff_unwind_info; PE_UnwindInfo unwind_info = {0}; - if(!ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) || is_stale) { is_good = 0; @@ -2740,11 +2724,11 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 good_unwind_info = 1; U64 unwind_info_off = pdata->voff_unwind_info; PE_UnwindInfo unwind_info = {0}; - good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us); + good_unwind_info = good_unwind_info && ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us); PE_UnwindCode *unwind_codes = push_array(scratch.arena, PE_UnwindCode, unwind_info.codes_num); - good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory(process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info), - module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num), - &is_stale, unwind_codes, endt_us); + good_unwind_info = good_unwind_info && ctrl_process_memory_read(process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info), + module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num), + &is_stale, unwind_codes, endt_us); good_unwind_info = good_unwind_info && !is_stale; //- rjf: bad unwind info -> abort @@ -2799,7 +2783,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read value from stack pointer U64 rsp = regs->rsp.u64; U64 value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, rsp, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2861,7 +2845,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 off = code_ptr[1].u16*8; U64 addr = frame_base + off; U64 value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, addr, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2880,7 +2864,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 addr = frame_base + off; U64 value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, addr, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2911,7 +2895,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 buf[16]; U64 off = code_ptr[1].u16*16; U64 addr = frame_base + off; - if(!ctrl_read_cached_process_memory(process->handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us)) + if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us)) { keep_parsing = 0; is_good = 0; @@ -2929,7 +2913,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 buf[16]; U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 addr = frame_base + off; - if(!ctrl_read_cached_process_memory(process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) || + if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) || is_stale) { keep_parsing = 0; @@ -2961,7 +2945,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT sp_adj += 8; } U64 ip_value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp_adj, &is_stale, &ip_value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp_adj, &is_stale, &ip_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2970,7 +2954,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_ip = sp_adj + 8; U16 ss_value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2979,7 +2963,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_ss = sp_after_ip + 8; U64 rflags_value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2988,7 +2972,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_rflags = sp_after_ss + 8; U64 sp_value = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) || is_stale) { keep_parsing = 0; @@ -3022,7 +3006,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 chained_pdata_off = unwind_info_off + sizeof(PE_UnwindInfo) + code_size; last_pdata = pdata; pdata = push_array(scratch.arena, PE_IntelPdata, 1); - if(!ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+chained_pdata_off, &is_stale, pdata, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+chained_pdata_off, &is_stale, pdata, endt_us) || is_stale) { is_good = 0; @@ -3040,7 +3024,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read rip from stack pointer U64 rsp = regs->rsp.u64; U64 new_rip = 0; - if(!ctrl_read_cached_process_memory_struct(process->handle, rsp, &is_stale, &new_rip, endt_us) || + if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &new_rip, endt_us) || is_stale) { is_good = 0; @@ -3099,7 +3083,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa U64 arch_reg_block_size = regs_block_size_from_arch(arch); //- rjf: grab initial register block - void *regs_block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, thread); + void *regs_block = ctrl_reg_block_from_thread(scratch.arena, store, thread); B32 regs_block_good = (arch != Arch_Null && regs_block != 0); //- rjf: loop & unwind @@ -4724,7 +4708,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); U64 regs_size = regs_block_size_from_arch(entity->arch); - void *regs = ctrl_query_cached_reg_block_from_thread(scratch.arena, ctrl_state->ctrl_thread_entity_store, entity->handle); + void *regs = ctrl_reg_block_from_thread(scratch.arena, ctrl_state->ctrl_thread_entity_store, entity->handle); Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 read_range = intersect_1u64(legal_range, range); U64 read_size = dim_1u64(read_range); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 4c33c20d..5304759e 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -593,6 +593,44 @@ struct CTRL_ThreadRegCache CTRL_ThreadRegCacheStripe *stripes; }; +//////////////////////////////// +//~ rjf: Thread Unwind Cache Types + +typedef struct CTRL_ThreadUnwindCacheNode CTRL_ThreadUnwindCacheNode; +struct CTRL_ThreadUnwindCacheNode +{ + CTRL_ThreadUnwindCacheNode *next; + CTRL_ThreadUnwindCacheNode *prev; + Arena *arena; + CTRL_Handle thread; + U64 reg_gen; + U64 mem_gen; + CTRL_Unwind unwind; +}; + +typedef struct CTRL_ThreadUnwindCacheSlot CTRL_ThreadUnwindCacheSlot; +struct CTRL_ThreadUnwindCacheSlot +{ + CTRL_ThreadUnwindCacheNode *first; + CTRL_ThreadUnwindCacheNode *last; +}; + +typedef struct CTRL_ThreadUnwindCacheStripe CTRL_ThreadUnwindCacheStripe; +struct CTRL_ThreadUnwindCacheStripe +{ + Arena *arena; + OS_Handle rw_mutex; +}; + +typedef struct CTRL_ThreadUnwindCache CTRL_ThreadUnwindCache; +struct CTRL_ThreadUnwindCache +{ + U64 slots_count; + CTRL_ThreadUnwindCacheSlot *slots; + U64 stripes_count; + CTRL_ThreadUnwindCacheStripe *stripes; +}; + //////////////////////////////// //~ rjf: Module Image Info Cache Types @@ -686,6 +724,7 @@ struct CTRL_State // rjf: caches CTRL_ProcessMemoryCache process_memory_cache; CTRL_ThreadRegCache thread_reg_cache; + CTRL_ThreadUnwindCache thread_unwind_cache; CTRL_ModuleImageInfoCache module_image_info_cache; // rjf: user -> ctrl msg ring buffer @@ -885,10 +924,9 @@ internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); //- rjf: process memory cache reading helpers -internal CTRL_ProcessMemorySlice ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); -internal CTRL_ProcessMemorySlice ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us); -internal B32 ctrl_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); -#define ctrl_read_cached_process_memory_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_read_cached_process_memory((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us)) +internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); +internal B32 ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); +#define ctrl_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us)) //- rjf: process memory writing internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src); @@ -897,10 +935,10 @@ internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src); //~ rjf: Thread Register Functions //- rjf: thread register cache reading -internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); +internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle); +internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); +internal U64 ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); +internal U64 ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); //- rjf: thread register writing internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block); diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index f8b15ef2..a28216d9 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -300,13 +300,13 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) // rjf: thread => unpacked info CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); Arch arch = thread->arch; - U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); // rjf: ip => machine code String8 machine_code = {0}; { Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch)); - CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, rng, os_now_microseconds()+5000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, os_now_microseconds()+5000); machine_code = machine_code_slice.data; } @@ -337,7 +337,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) // rjf: thread => info Arch arch = thread->arch; - U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); @@ -380,7 +380,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) String8 machine_code = {0}; if(good_line_info) { - CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+50000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+50000); machine_code = machine_code_slice.data; LogInfoNamedBlockF("machine_code_slice") { @@ -498,7 +498,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) // rjf: thread => info Arch arch = thread->arch; - U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); @@ -536,7 +536,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) String8 machine_code = {0}; if(good_line_info) { - CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+5000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+5000); machine_code = machine_code_slice.data; } @@ -1073,7 +1073,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 U64 tls_index = 0; if(addr_size != 0) { - CTRL_ProcessMemorySlice tls_index_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0); + CTRL_ProcessMemorySlice tls_index_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0); if(tls_index_slice.data.size >= addr_size) { tls_index = *(U64 *)tls_index_slice.data.str; @@ -1086,13 +1086,13 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 U64 thread_info_addr = root_vaddr; U64 tls_addr_off = tls_index*addr_size; U64 tls_addr_array = 0; - CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0); + CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0); String8 tls_addr_array_data = tls_addr_array_slice.data; if(tls_addr_array_data.size >= 8) { MemoryCopy(&tls_addr_array, tls_addr_array_data.str, sizeof(U64)); } - CTRL_ProcessMemorySlice result_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0); + CTRL_ProcessMemorySlice result_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0); String8 result_data = result_slice.data; if(result_data.size >= 8) { @@ -1267,7 +1267,7 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count) U64 result = 0; if(unwind_count == 0) { - result = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + result = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); } else { @@ -2020,7 +2020,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread); U64 vaddr = params->vaddr; - void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle); regs_arch_block_write_rip(thread->arch, block, vaddr); B32 result = ctrl_thread_write_reg_block(thread->handle, block); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 292988ab..5f550abc 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1805,7 +1805,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) default:{}break; case CTRL_EntityKind_Process: { - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, entity->handle, range, rd_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, entity->handle, range, rd_state->frame_eval_memread_endt_us); String8 data = slice.data; if(data.size == dim_1u64(range)) { @@ -2021,7 +2021,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 write_range = intersect_1u64(legal_range, range); U64 write_size = dim_1u64(write_range); - void *new_regs = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, entity->handle); + void *new_regs = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, entity->handle); MemoryCopy((U8 *)new_regs + write_range.min, in, write_size); result = ctrl_thread_write_reg_block(entity->handle, new_regs); scratch_end(scratch); @@ -4508,7 +4508,7 @@ rd_view_ui(Rng2F32 rect) U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key); size = Min(size, 64); Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { if(slice.byte_changed_flags[idx] != 0) @@ -11644,7 +11644,7 @@ rd_frame(void) CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - U64 tls_root_vaddr = ctrl_query_cached_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle); CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); U64 eval_modules_count = Max(1, all_modules.count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); @@ -15650,7 +15650,7 @@ rd_frame(void) { CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle)); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle)); CTRL_Entity *machine = ctrl_entity_ancestor_from_kind(process, CTRL_EntityKind_Machine); rd_state->base_regs.v.unwind_count = 0; rd_state->base_regs.v.inline_depth = 0; @@ -16423,7 +16423,7 @@ rd_frame(void) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); - U64 test_cached_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 test_cached_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); // rjf: valid stop thread? -> select & snap if(need_refocus && thread != &ctrl_entity_nil && evt->cause != D_EventCause_Halt) From f12b66c1ee6ad1c4e70bc8186c03b9bb573d8357 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:27:10 -0700 Subject: [PATCH 700/755] sketch out asynchronous unwinding stuff --- project.4coder | 4 +-- src/ctrl/ctrl_core.c | 83 +++++++++++++++++++++++++++++++++++++++----- src/ctrl/ctrl_core.h | 53 ++++++++++++++++++---------- 3 files changed, 112 insertions(+), 28 deletions(-) diff --git a/project.4coder b/project.4coder index 5be24aab..32a1e737 100644 --- a/project.4coder +++ b/project.4coder @@ -55,8 +55,8 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target - .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 6b14633f..795e8dfc 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1432,14 +1432,14 @@ ctrl_init(void) ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc(); ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } - ctrl_state->thread_unwind_cache.slots_count = 1024; - ctrl_state->thread_unwind_cache.slots = push_array(arena, CTRL_ThreadUnwindCacheSlot, ctrl_state->thread_unwind_cache.slots_count); - ctrl_state->thread_unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; - ctrl_state->thread_unwind_cache.stripes = push_array(arena, CTRL_ThreadUnwindCacheStripe, ctrl_state->thread_unwind_cache.stripes_count); - for(U64 idx = 0; idx < ctrl_state->thread_unwind_cache.stripes_count; idx += 1) + ctrl_state->unwind_cache.slots_count = 1024; + ctrl_state->unwind_cache.slots = push_array(arena, CTRL_UnwindCacheSlot, ctrl_state->unwind_cache.slots_count); + ctrl_state->unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; + ctrl_state->unwind_cache.stripes = push_array(arena, CTRL_UnwindCacheStripe, ctrl_state->unwind_cache.stripes_count); + for(U64 idx = 0; idx < ctrl_state->unwind_cache.stripes_count; idx += 1) { - ctrl_state->thread_unwind_cache.stripes[idx].arena = arena_alloc(); - ctrl_state->thread_unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); + ctrl_state->unwind_cache.stripes[idx].arena = arena_alloc(); + ctrl_state->unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } ctrl_state->module_image_info_cache.slots_count = 1024; ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count); @@ -1484,6 +1484,10 @@ ctrl_init(void) ctrl_state->u2ms_ring_base = push_array(arena, U8, ctrl_state->u2ms_ring_size); ctrl_state->u2ms_ring_mutex = os_mutex_alloc(); ctrl_state->u2ms_ring_cv = os_condition_variable_alloc(); + ctrl_state->u2uw_ring_size = KB(64); + ctrl_state->u2uw_ring_base = push_array(arena, U8, ctrl_state->u2uw_ring_size); + ctrl_state->u2uw_ring_mutex = os_mutex_alloc(); + ctrl_state->u2uw_ring_cv = os_condition_variable_alloc(); ctrl_state->ctrl_thread_log = log_alloc(); ctrl_state->ctrl_thread = os_thread_launch(ctrl_thread__entry_point, 0, 0); } @@ -6334,7 +6338,7 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } //////////////////////////////// -//~ rjf: Memory-Stream-Thread-Only Functions +//~ rjf: Asynchronous Memory Streaming Functions //- rjf: user -> memory stream communication @@ -6545,5 +6549,68 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) os_condition_variable_broadcast(process_stripe->cv); ProfEnd(); ProfEnd(); + return 0; +} + +//////////////////////////////// +//~ rjf: Asynchronous Unwinding Functions + +//- rjf: user -> memory stream communication + +internal B32 +ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us) +{ + B32 good = 0; + OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + { + U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; + U64 available_size = ctrl_state->u2uw_ring_size - unconsumed_size; + if(available_size >= sizeof(thread)) + { + good = 1; + ctrl_state->u2uw_ring_write_pos += ring_write_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_write_pos, &thread); + break; + } + if(os_now_microseconds() >= endt_us) + { + break; + } + os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, endt_us); + } + if(good) + { + os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); + } + return good; +} + +internal void +ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread) +{ + OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + { + U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; + if(unconsumed_size >= sizeof(*out_thread)) + { + ctrl_state->u2uw_ring_read_pos += ring_read_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_read_pos, out_thread); + break; + } + os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, max_U64); + } + os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); +} + +//- rjf: entry point + +ASYNC_WORK_DEF(ctrl_unwind_work) +{ + CTRL_UnwindCache *cache = &ctrl_state->unwind_cache; + + //- rjf: get next request + CTRL_Handle thread_handle = {0}; + ctrl_u2uw_dequeue_req(&thread_handle); + + + return 0; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 5304759e..cbec99ca 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -594,13 +594,13 @@ struct CTRL_ThreadRegCache }; //////////////////////////////// -//~ rjf: Thread Unwind Cache Types +//~ rjf: Unwind Cache Types -typedef struct CTRL_ThreadUnwindCacheNode CTRL_ThreadUnwindCacheNode; -struct CTRL_ThreadUnwindCacheNode +typedef struct CTRL_UnwindCacheNode CTRL_UnwindCacheNode; +struct CTRL_UnwindCacheNode { - CTRL_ThreadUnwindCacheNode *next; - CTRL_ThreadUnwindCacheNode *prev; + CTRL_UnwindCacheNode *next; + CTRL_UnwindCacheNode *prev; Arena *arena; CTRL_Handle thread; U64 reg_gen; @@ -608,27 +608,27 @@ struct CTRL_ThreadUnwindCacheNode CTRL_Unwind unwind; }; -typedef struct CTRL_ThreadUnwindCacheSlot CTRL_ThreadUnwindCacheSlot; -struct CTRL_ThreadUnwindCacheSlot +typedef struct CTRL_UnwindCacheSlot CTRL_UnwindCacheSlot; +struct CTRL_UnwindCacheSlot { - CTRL_ThreadUnwindCacheNode *first; - CTRL_ThreadUnwindCacheNode *last; + CTRL_UnwindCacheNode *first; + CTRL_UnwindCacheNode *last; }; -typedef struct CTRL_ThreadUnwindCacheStripe CTRL_ThreadUnwindCacheStripe; -struct CTRL_ThreadUnwindCacheStripe +typedef struct CTRL_UnwindCacheStripe CTRL_UnwindCacheStripe; +struct CTRL_UnwindCacheStripe { Arena *arena; OS_Handle rw_mutex; }; -typedef struct CTRL_ThreadUnwindCache CTRL_ThreadUnwindCache; -struct CTRL_ThreadUnwindCache +typedef struct CTRL_UnwindCache CTRL_UnwindCache; +struct CTRL_UnwindCache { U64 slots_count; - CTRL_ThreadUnwindCacheSlot *slots; + CTRL_UnwindCacheSlot *slots; U64 stripes_count; - CTRL_ThreadUnwindCacheStripe *stripes; + CTRL_UnwindCacheStripe *stripes; }; //////////////////////////////// @@ -724,7 +724,7 @@ struct CTRL_State // rjf: caches CTRL_ProcessMemoryCache process_memory_cache; CTRL_ThreadRegCache thread_reg_cache; - CTRL_ThreadUnwindCache thread_unwind_cache; + CTRL_UnwindCache unwind_cache; CTRL_ModuleImageInfoCache module_image_info_cache; // rjf: user -> ctrl msg ring buffer @@ -768,6 +768,14 @@ struct CTRL_State U64 u2ms_ring_read_pos; OS_Handle u2ms_ring_mutex; OS_Handle u2ms_ring_cv; + + // rjf: user -> unwind ring buffer + U64 u2uw_ring_size; + U8 *u2uw_ring_base; + U64 u2uw_ring_write_pos; + U64 u2uw_ring_read_pos; + OS_Handle u2uw_ring_mutex; + OS_Handle u2uw_ring_cv; }; //////////////////////////////// @@ -1039,7 +1047,7 @@ internal void ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); //////////////////////////////// -//~ rjf: Memory-Stream Thread Functions +//~ rjf: Asynchronous Memory Streaming Functions //- rjf: user -> memory stream communication internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); @@ -1047,6 +1055,15 @@ internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr //- rjf: entry point ASYNC_WORK_DEF(ctrl_mem_stream_work); -internal void ctrl_mem_stream_thread__entry_point(void *p); + +//////////////////////////////// +//~ rjf: Asynchronous Unwinding Functions + +//- rjf: user -> memory stream communication +internal B32 ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us); +internal void ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread); + +//- rjf: entry point +ASYNC_WORK_DEF(ctrl_unwind_work); #endif // CTRL_CORE_H From b49f4559ce5f599d5b096b27a9ca7db5a59bb83d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:32:32 -0700 Subject: [PATCH 701/755] get main unwinding path off of requiring entire ctrl entity store --- src/ctrl/ctrl_core.c | 78 +++++++++++++++++++++----------------------- src/ctrl/ctrl_core.h | 4 +-- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 795e8dfc..373b1264 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -2241,7 +2241,7 @@ ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX } internal CTRL_UnwindStepResult -ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CTRL_Handle module_handle, REGS_RegBlockX64 *regs, U64 endt_us) +ctrl_unwind_step__pe_x64(CTRL_Handle process_handle, CTRL_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us) { B32 is_stale = 0; B32 is_good = 1; @@ -2250,9 +2250,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT ////////////////////////////// //- rjf: unpack parameters // - CTRL_Entity *module = ctrl_entity_from_handle(store, module_handle); - CTRL_Entity *process = ctrl_entity_from_handle(store, process_handle); - U64 rip_voff = regs->rip.u64 - module->vaddr_range.min; + U64 rip_voff = regs->rip.u64 - module_base_vaddr; ////////////////////////////// //- rjf: rip_voff -> first pdata @@ -2363,7 +2361,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 inst_byte = 0; if(read_vaddr + sizeof(inst_byte) <= read_vaddr_opl) { - inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + inst_byte_good = ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &inst_byte, endt_us); } if(!inst_byte_good || is_stale) { @@ -2379,7 +2377,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT check_vaddr = read_vaddr + 1; if(read_vaddr + sizeof(check_inst_byte) <= read_vaddr_opl) { - check_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us); + check_inst_byte_good = ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &check_inst_byte, endt_us); } if(!check_inst_byte_good || is_stale) { @@ -2415,7 +2413,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 imm_good = 0; if(read_vaddr + sizeof(imm) <= read_vaddr_opl) { - imm_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us); + imm_good = ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm, endt_us); } if(!imm_good || is_stale) { @@ -2424,7 +2422,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT if(imm_good) { U64 next_vaddr = (U64)(imm_vaddr + sizeof(imm) + imm); - U64 next_voff = next_vaddr - module->vaddr_range.min; // TODO(rjf): verify that this offset is from module base vaddr, not section + U64 next_voff = next_vaddr - module_base_vaddr; // TODO(rjf): verify that this offset is from module base vaddr, not section if(!(first_pdata->voff_first <= next_voff && next_voff < first_pdata->voff_one_past_last)) { keep_parsing = 0; @@ -2444,7 +2442,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 next_inst_byte_good = 0; if(read_vaddr + sizeof(next_inst_byte) <= read_vaddr_opl) { - next_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &next_inst_byte, endt_us); + next_inst_byte_good = ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &next_inst_byte, endt_us); } if(next_inst_byte_good) { @@ -2473,7 +2471,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT //- rjf: read next instruction byte U8 inst_byte = 0; - is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + is_good = is_good && ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && !is_stale; read_vaddr += 1; @@ -2482,7 +2480,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT if((inst_byte & 0xF0) == 0x40) { rex = inst_byte & 0xF; // rex prefix - is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us); + is_good = is_good && ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &inst_byte, endt_us); is_good = is_good && !is_stale; read_vaddr += 1; } @@ -2503,7 +2501,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read value at rsp U64 sp = regs->rsp.u64; U64 value = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp, &is_stale, &value, endt_us) || is_stale) { is_good = 0; @@ -2528,7 +2526,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read the 4-byte immediate S32 imm = 0; - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2551,7 +2549,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read the 4-byte immediate S8 imm = 0; - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2571,7 +2569,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT { // rjf: read source register U8 modrm = 0; - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &modrm, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &modrm, endt_us) || is_stale) { is_good = 0; @@ -2589,7 +2587,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT if((modrm >> 6) == 1) { S8 imm8 = 0; - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm8, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm8, endt_us) || is_stale) { is_good = 0; @@ -2602,7 +2600,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read 4-byte immediate else { - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2625,7 +2623,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read new ip U64 sp = regs->rsp.u64; U64 new_ip = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) || is_stale) { is_good = 0; @@ -2634,7 +2632,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read 2-byte immediate & advance stack pointer U16 imm = 0; - if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, read_vaddr, &is_stale, &imm, endt_us) || is_stale) { is_good = 0; @@ -2657,7 +2655,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read new ip U64 sp = regs->rsp.u64; U64 new_ip = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp, &is_stale, &new_ip, endt_us) || is_stale) { is_good = 0; @@ -2704,7 +2702,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT { U64 unwind_info_off = first_pdata->voff_unwind_info; PE_UnwindInfo unwind_info = {0}; - if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, module_base_vaddr+unwind_info_off, &is_stale, &unwind_info, endt_us) || is_stale) { is_good = 0; @@ -2728,10 +2726,10 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT B32 good_unwind_info = 1; U64 unwind_info_off = pdata->voff_unwind_info; PE_UnwindInfo unwind_info = {0}; - good_unwind_info = good_unwind_info && ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us); + good_unwind_info = good_unwind_info && ctrl_process_memory_read_struct(process_handle, module_base_vaddr+unwind_info_off, &is_stale, &unwind_info, endt_us); PE_UnwindCode *unwind_codes = push_array(scratch.arena, PE_UnwindCode, unwind_info.codes_num); - good_unwind_info = good_unwind_info && ctrl_process_memory_read(process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info), - module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num), + good_unwind_info = good_unwind_info && ctrl_process_memory_read(process_handle, r1u64(module_base_vaddr+unwind_info_off+sizeof(unwind_info), + module_base_vaddr+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num), &is_stale, unwind_codes, endt_us); good_unwind_info = good_unwind_info && !is_stale; @@ -2787,7 +2785,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read value from stack pointer U64 rsp = regs->rsp.u64; U64 value = 0; - if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, rsp, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2849,7 +2847,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 off = code_ptr[1].u16*8; U64 addr = frame_base + off; U64 value = 0; - if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, addr, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2868,7 +2866,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 addr = frame_base + off; U64 value = 0; - if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, addr, &is_stale, &value, endt_us) || is_stale) { keep_parsing = 0; @@ -2899,7 +2897,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 buf[16]; U64 off = code_ptr[1].u16*16; U64 addr = frame_base + off; - if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us)) + if(!ctrl_process_memory_read(process_handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us)) { keep_parsing = 0; is_good = 0; @@ -2917,7 +2915,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U8 buf[16]; U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16); U64 addr = frame_base + off; - if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) || + if(!ctrl_process_memory_read(process_handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) || is_stale) { keep_parsing = 0; @@ -2949,7 +2947,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT sp_adj += 8; } U64 ip_value = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp_adj, &is_stale, &ip_value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp_adj, &is_stale, &ip_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2958,7 +2956,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_ip = sp_adj + 8; U16 ss_value = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp_after_ip, &is_stale, &ss_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2967,7 +2965,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_ss = sp_after_ip + 8; U64 rflags_value = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp_after_ss, &is_stale, &rflags_value, endt_us) || is_stale) { keep_parsing = 0; @@ -2976,7 +2974,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT } U64 sp_after_rflags = sp_after_ss + 8; U64 sp_value = 0; - if(!ctrl_process_memory_read_struct(process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, sp_after_rflags, &is_stale, &sp_value, endt_us) || is_stale) { keep_parsing = 0; @@ -3010,7 +3008,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT U64 chained_pdata_off = unwind_info_off + sizeof(PE_UnwindInfo) + code_size; last_pdata = pdata; pdata = push_array(scratch.arena, PE_IntelPdata, 1); - if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+chained_pdata_off, &is_stale, pdata, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, module_base_vaddr+chained_pdata_off, &is_stale, pdata, endt_us) || is_stale) { is_good = 0; @@ -3028,7 +3026,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT // rjf: read rip from stack pointer U64 rsp = regs->rsp.u64; U64 new_rip = 0; - if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &new_rip, endt_us) || + if(!ctrl_process_memory_read_struct(process_handle, rsp, &is_stale, &new_rip, endt_us) || is_stale) { is_good = 0; @@ -3056,7 +3054,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT //- rjf: abstracted unwind step internal CTRL_UnwindStepResult -ctrl_unwind_step(CTRL_EntityStore *store, CTRL_Handle process, CTRL_Handle module, Arch arch, void *reg_block, U64 endt_us) +ctrl_unwind_step(CTRL_Handle process, CTRL_Handle module, U64 module_base_vaddr, Arch arch, void *reg_block, U64 endt_us) { CTRL_UnwindStepResult result = {0}; switch(arch) @@ -3064,7 +3062,7 @@ ctrl_unwind_step(CTRL_EntityStore *store, CTRL_Handle process, CTRL_Handle modul default:{}break; case Arch_x64: { - result = ctrl_unwind_step__pe_x64(store, process, module, (REGS_RegBlockX64 *)reg_block, endt_us); + result = ctrl_unwind_step__pe_x64(process, module, module_base_vaddr, (REGS_RegBlockX64 *)reg_block, endt_us); }break; } return result; @@ -3101,12 +3099,12 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa { // rjf: regs -> rip*module U64 rip = regs_rip_from_arch_block(arch, regs_block); - CTRL_Handle module = {0}; + CTRL_Entity *module = &ctrl_entity_nil; for(CTRL_Entity *m = process_entity->first; m != &ctrl_entity_nil; m = m->next) { if(m->kind == CTRL_EntityKind_Module && contains_1u64(m->vaddr_range, rip)) { - module = m->handle; + module = m; break; } } @@ -3126,7 +3124,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa frame_node_count += 1; // rjf: unwind one step - CTRL_UnwindStepResult step = ctrl_unwind_step(store, process_entity->handle, module, arch, regs_block, endt_us); + CTRL_UnwindStepResult step = ctrl_unwind_step(process_entity->handle, module->handle, module->vaddr_range.min, arch, regs_block, endt_us); unwind.flags |= step.flags; if(step.flags & CTRL_UnwindFlag_Error || regs_rsp_from_arch_block(arch, regs_block) == 0 || diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index cbec99ca..1a04b525 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -969,10 +969,10 @@ internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, CTRL_Unwind //- rjf: [x64] internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg); -internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CTRL_Handle module_handle, REGS_RegBlockX64 *regs, U64 endt_us); +internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_Handle process_handle, CTRL_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us); //- rjf: abstracted unwind step -internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_EntityStore *store, CTRL_Handle process, CTRL_Handle module, Arch arch, void *reg_block, U64 endt_us); +internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_Handle process, CTRL_Handle module, U64 module_base_vaddr, Arch arch, void *reg_block, U64 endt_us); //- rjf: abstracted full unwind internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle thread, U64 endt_us); From a7b6e6f02af6e96871f6a941b43145210bda3fe2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:51:59 -0700 Subject: [PATCH 702/755] eliminate usage of old overcomplicated call stack data structure, which required actively holding debug info references... we want to eliminate this so that we can trivially cache call stacks / unwinds --- src/ctrl/ctrl_core.c | 2 -- src/raddbg/raddbg_core.c | 46 +++++++++------------------------------- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 373b1264..c9afb603 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -6608,7 +6608,5 @@ ASYNC_WORK_DEF(ctrl_unwind_work) CTRL_Handle thread_handle = {0}; ctrl_u2uw_dequeue_req(&thread_handle); - - return 0; } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5f550abc..07f0f216 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -6392,8 +6392,9 @@ rd_window_frame(void) } // rjf: unwind - if(ctrl_entity->kind == CTRL_EntityKind_Thread) + if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) { + Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); @@ -6402,44 +6403,17 @@ rd_window_frame(void) { ui_spacer(ui_em(1.5f, 1.f)); } - for(U64 idx = 0; idx < call_stack.count; idx += 1) + EV_StringParams string_params = {EV_StringFlag_ReadOnlyDisplayRules, .radix = 16}; + String8 thread_handle_string = ctrl_string_from_handle(scratch.arena, ctrl_entity->handle); + for(U64 idx = 0; idx < 16; idx += 1) { - CTRL_CallStackFrame *f = &call_stack.frames[idx]; - RDI_Parsed *rdi = f->rdi; - RDI_Procedure *procedure = f->procedure; - U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); - String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string); - UI_PrefWidth(ui_children_sum(1)) UI_Row + E_Eval rip_eval = e_eval_from_stringf("query:control.%S.call_stack[%I64u]", thread_handle_string, idx); + if(rip_eval.irtree.mode != E_Mode_Value) { - String8 name = {0}; - if(f->inline_site != 0) - { - name.str = rdi_string_from_idx(rdi, f->inline_site->name_string_idx, &name.size); - name.size = Min(512, name.size); - } - else if(f->procedure != 0) - { - name.str = rdi_name_from_procedure(rdi, procedure, &name.size); - name.size = Min(512, name.size); - } - UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr); - if(f->parent_num != 0) - { - RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]")); - } - if(name.size != 0) - { - RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1)) - { - rd_code_label(1.f, 0, symbol_color, name); - } - } - else - { - RD_Font(RD_FontSlot_Code) UI_TagF("weak") UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name); - } + break; } + String8 rip_value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, rip_eval); + rd_code_label(1, 0, code_color, rip_value_string); } } From 99a8108b2a3fd911ded52135fdc8de1e742bdc77 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:53:24 -0700 Subject: [PATCH 703/755] eliminate now-unnecessary debug info references in call stack data structure --- src/ctrl/ctrl_core.c | 4 ---- src/ctrl/ctrl_core.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index c9afb603..1c76c975 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3200,8 +3200,6 @@ ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *proce SLLQueuePush(first_frame, last_frame, dst_inline); dst_inline->v.unwind_count = base_frame_idx; dst_inline->v.regs = src->regs; - dst_inline->v.rdi = rdi; - dst_inline->v.inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); frame_count += 1; inline_frame_count += 1; } @@ -3211,8 +3209,6 @@ ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *proce SLLQueuePush(first_frame, last_frame, dst_base); dst_base->v.unwind_count = base_frame_idx; dst_base->v.regs = src->regs; - dst_base->v.rdi = rdi; - dst_base->v.procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx); frame_count += 1; // rjf: hook up inline frames to point to concrete frame, and to account for inline depth diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 1a04b525..c309cd46 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -249,9 +249,6 @@ struct CTRL_CallStackFrame U64 unwind_count; U64 inline_depth; void *regs; - RDI_Parsed *rdi; - RDI_Procedure *procedure; - RDI_InlineSite *inline_site; }; typedef struct CTRL_CallStack CTRL_CallStack; From 1e53ac29ef0fd75f860f3158769b027098e41bab Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:55:16 -0700 Subject: [PATCH 704/755] still protect against infinite unwinds, but require that both rsp/rip remain unchanged, rather than just rip --- src/ctrl/ctrl_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1c76c975..998a65ac 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3099,6 +3099,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa { // rjf: regs -> rip*module U64 rip = regs_rip_from_arch_block(arch, regs_block); + U64 rsp = regs_rsp_from_arch_block(arch, regs_block); CTRL_Entity *module = &ctrl_entity_nil; for(CTRL_Entity *m = process_entity->first; m != &ctrl_entity_nil; m = m->next) { @@ -3128,7 +3129,9 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa unwind.flags |= step.flags; if(step.flags & CTRL_UnwindFlag_Error || regs_rsp_from_arch_block(arch, regs_block) == 0 || - regs_rip_from_arch_block(arch, regs_block) == 0) + regs_rip_from_arch_block(arch, regs_block) == 0 || + (regs_rsp_from_arch_block(arch, regs_block) == rsp && + regs_rip_from_arch_block(arch, regs_block) == rip)) { break; } From 81483f51003da86ddd1939adbbe9c4eee5f9fff2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 14:41:13 -0700 Subject: [PATCH 705/755] eliminate per-callstack-frame 'parent num' - redundant info --- src/ctrl/ctrl_core.c | 3 +-- src/ctrl/ctrl_core.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 998a65ac..09f59317 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3218,7 +3218,6 @@ ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *proce U64 inline_frame_idx = 0; for(FrameNode *inline_frame = first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, inline_frame_idx += 1) { - inline_frame->v.parent_num = frame_count; inline_frame->v.inline_depth = inline_frame_count - inline_frame_idx; if(inline_frame == last_inline_frame) { @@ -3250,7 +3249,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U U64 base_frame_idx = 0; for(U64 idx = 0; idx < call_stack->count; idx += 1) { - if(call_stack->frames[idx].parent_num == 0) + if(call_stack->frames[idx].inline_depth == 0) { if(base_frame_idx == unwind_count) { diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index c309cd46..745dbe73 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -245,7 +245,6 @@ struct CTRL_Unwind typedef struct CTRL_CallStackFrame CTRL_CallStackFrame; struct CTRL_CallStackFrame { - U64 parent_num; U64 unwind_count; U64 inline_depth; void *regs; From 60e47fb82162e77ac582f8ee1166cd2251e42729 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 15:28:57 -0700 Subject: [PATCH 706/755] unwind cache -> callstack cache --- src/ctrl/ctrl_core.c | 54 ++++++++++++++--------------- src/ctrl/ctrl_core.h | 55 +++++++++++++++--------------- src/demon/win32/demon_core_win32.c | 2 ++ 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 09f59317..068185bd 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1432,14 +1432,14 @@ ctrl_init(void) ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc(); ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } - ctrl_state->unwind_cache.slots_count = 1024; - ctrl_state->unwind_cache.slots = push_array(arena, CTRL_UnwindCacheSlot, ctrl_state->unwind_cache.slots_count); - ctrl_state->unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; - ctrl_state->unwind_cache.stripes = push_array(arena, CTRL_UnwindCacheStripe, ctrl_state->unwind_cache.stripes_count); - for(U64 idx = 0; idx < ctrl_state->unwind_cache.stripes_count; idx += 1) + ctrl_state->call_stack_cache.slots_count = 1024; + ctrl_state->call_stack_cache.slots = push_array(arena, CTRL_CallStackCacheSlot, ctrl_state->call_stack_cache.slots_count); + ctrl_state->call_stack_cache.stripes_count = os_get_system_info()->logical_processor_count; + ctrl_state->call_stack_cache.stripes = push_array(arena, CTRL_CallStackCacheStripe, ctrl_state->call_stack_cache.stripes_count); + for(U64 idx = 0; idx < ctrl_state->call_stack_cache.stripes_count; idx += 1) { - ctrl_state->unwind_cache.stripes[idx].arena = arena_alloc(); - ctrl_state->unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); + ctrl_state->call_stack_cache.stripes[idx].arena = arena_alloc(); + ctrl_state->call_stack_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } ctrl_state->module_image_info_cache.slots_count = 1024; ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count); @@ -1484,10 +1484,10 @@ ctrl_init(void) ctrl_state->u2ms_ring_base = push_array(arena, U8, ctrl_state->u2ms_ring_size); ctrl_state->u2ms_ring_mutex = os_mutex_alloc(); ctrl_state->u2ms_ring_cv = os_condition_variable_alloc(); - ctrl_state->u2uw_ring_size = KB(64); - ctrl_state->u2uw_ring_base = push_array(arena, U8, ctrl_state->u2uw_ring_size); - ctrl_state->u2uw_ring_mutex = os_mutex_alloc(); - ctrl_state->u2uw_ring_cv = os_condition_variable_alloc(); + ctrl_state->u2csb_ring_size = KB(64); + ctrl_state->u2csb_ring_base = push_array(arena, U8, ctrl_state->u2csb_ring_size); + ctrl_state->u2csb_ring_mutex = os_mutex_alloc(); + ctrl_state->u2csb_ring_cv = os_condition_variable_alloc(); ctrl_state->ctrl_thread_log = log_alloc(); ctrl_state->ctrl_thread = os_thread_launch(ctrl_thread__entry_point, 0, 0); } @@ -6554,57 +6554,57 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) //- rjf: user -> memory stream communication internal B32 -ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us) +ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us) { B32 good = 0; - OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + OS_MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) { - U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; - U64 available_size = ctrl_state->u2uw_ring_size - unconsumed_size; + U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; + U64 available_size = ctrl_state->u2csb_ring_size - unconsumed_size; if(available_size >= sizeof(thread)) { good = 1; - ctrl_state->u2uw_ring_write_pos += ring_write_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_write_pos, &thread); + ctrl_state->u2csb_ring_write_pos += ring_write_struct(ctrl_state->u2csb_ring_base, ctrl_state->u2csb_ring_size, ctrl_state->u2csb_ring_write_pos, &thread); break; } if(os_now_microseconds() >= endt_us) { break; } - os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, endt_us); + os_condition_variable_wait(ctrl_state->u2csb_ring_cv, ctrl_state->u2csb_ring_mutex, endt_us); } if(good) { - os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); + os_condition_variable_broadcast(ctrl_state->u2csb_ring_cv); } return good; } internal void -ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread) +ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread) { - OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + OS_MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) { - U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; + U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; if(unconsumed_size >= sizeof(*out_thread)) { - ctrl_state->u2uw_ring_read_pos += ring_read_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_read_pos, out_thread); + ctrl_state->u2csb_ring_read_pos += ring_read_struct(ctrl_state->u2csb_ring_base, ctrl_state->u2csb_ring_size, ctrl_state->u2csb_ring_read_pos, out_thread); break; } - os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, max_U64); + os_condition_variable_wait(ctrl_state->u2csb_ring_cv, ctrl_state->u2csb_ring_mutex, max_U64); } - os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); + os_condition_variable_broadcast(ctrl_state->u2csb_ring_cv); } //- rjf: entry point -ASYNC_WORK_DEF(ctrl_unwind_work) +ASYNC_WORK_DEF(ctrl_call_stack_build_work) { - CTRL_UnwindCache *cache = &ctrl_state->unwind_cache; + CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; //- rjf: get next request CTRL_Handle thread_handle = {0}; - ctrl_u2uw_dequeue_req(&thread_handle); + ctrl_u2csb_dequeue_req(&thread_handle); return 0; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 745dbe73..c21098e4 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -590,41 +590,42 @@ struct CTRL_ThreadRegCache }; //////////////////////////////// -//~ rjf: Unwind Cache Types +//~ rjf: Call Stack Cache Types -typedef struct CTRL_UnwindCacheNode CTRL_UnwindCacheNode; -struct CTRL_UnwindCacheNode +typedef struct CTRL_CallStackCacheNode CTRL_CallStackCacheNode; +struct CTRL_CallStackCacheNode { - CTRL_UnwindCacheNode *next; - CTRL_UnwindCacheNode *prev; + CTRL_CallStackCacheNode *next; + CTRL_CallStackCacheNode *prev; Arena *arena; CTRL_Handle thread; U64 reg_gen; U64 mem_gen; CTRL_Unwind unwind; + CTRL_CallStack call_stack; }; -typedef struct CTRL_UnwindCacheSlot CTRL_UnwindCacheSlot; -struct CTRL_UnwindCacheSlot +typedef struct CTRL_CallStackCacheSlot CTRL_CallStackCacheSlot; +struct CTRL_CallStackCacheSlot { - CTRL_UnwindCacheNode *first; - CTRL_UnwindCacheNode *last; + CTRL_CallStackCacheNode *first; + CTRL_CallStackCacheNode *last; }; -typedef struct CTRL_UnwindCacheStripe CTRL_UnwindCacheStripe; -struct CTRL_UnwindCacheStripe +typedef struct CTRL_CallStackCacheStripe CTRL_CallStackCacheStripe; +struct CTRL_CallStackCacheStripe { Arena *arena; OS_Handle rw_mutex; }; -typedef struct CTRL_UnwindCache CTRL_UnwindCache; -struct CTRL_UnwindCache +typedef struct CTRL_CallStackCache CTRL_CallStackCache; +struct CTRL_CallStackCache { U64 slots_count; - CTRL_UnwindCacheSlot *slots; + CTRL_CallStackCacheSlot *slots; U64 stripes_count; - CTRL_UnwindCacheStripe *stripes; + CTRL_CallStackCacheStripe *stripes; }; //////////////////////////////// @@ -720,7 +721,7 @@ struct CTRL_State // rjf: caches CTRL_ProcessMemoryCache process_memory_cache; CTRL_ThreadRegCache thread_reg_cache; - CTRL_UnwindCache unwind_cache; + CTRL_CallStackCache call_stack_cache; CTRL_ModuleImageInfoCache module_image_info_cache; // rjf: user -> ctrl msg ring buffer @@ -765,13 +766,13 @@ struct CTRL_State OS_Handle u2ms_ring_mutex; OS_Handle u2ms_ring_cv; - // rjf: user -> unwind ring buffer - U64 u2uw_ring_size; - U8 *u2uw_ring_base; - U64 u2uw_ring_write_pos; - U64 u2uw_ring_read_pos; - OS_Handle u2uw_ring_mutex; - OS_Handle u2uw_ring_cv; + // rjf: user -> call stack builder ring buffer + U64 u2csb_ring_size; + U8 *u2csb_ring_base; + U64 u2csb_ring_write_pos; + U64 u2csb_ring_read_pos; + OS_Handle u2csb_ring_mutex; + OS_Handle u2csb_ring_cv; }; //////////////////////////////// @@ -1053,13 +1054,13 @@ internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr ASYNC_WORK_DEF(ctrl_mem_stream_work); //////////////////////////////// -//~ rjf: Asynchronous Unwinding Functions +//~ rjf: Asynchronous Call Stack Building Functions //- rjf: user -> memory stream communication -internal B32 ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us); -internal void ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread); +internal B32 ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us); +internal void ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread); //- rjf: entry point -ASYNC_WORK_DEF(ctrl_unwind_work); +ASYNC_WORK_DEF(ctrl_call_stack_build_work); #endif // CTRL_CORE_H diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index bd6bfb6f..c1752395 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -56,9 +56,11 @@ dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id) // rjf: allocate DMN_W32_Entity *e = dmn_w32_shared->entities_first_free; { + U32 gen = 0; if(e != 0) { SLLStackPop(dmn_w32_shared->entities_first_free); + gen = e->gen; } else { From e513af536193a8ef267cff205308456fb4145fc5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 15:30:49 -0700 Subject: [PATCH 707/755] ditto --- src/demon/win32/demon_core_win32.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index c1752395..fee9e9f6 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -67,7 +67,6 @@ dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id) e = push_array_no_zero(dmn_w32_shared->entities_arena, DMN_W32_Entity, 1); dmn_w32_shared->entities_count += 1; } - U32 gen = e->gen; MemoryZeroStruct(e); e->gen = gen+1; } From 1e6b3ee2e66a17636c416dede48356c940f0e6fd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 18:35:25 -0700 Subject: [PATCH 708/755] split read-only ctrl entity operations from read-write ctrl entity operations, represent in type system via EntityCtx vs. EntityStore --- src/ctrl/ctrl_core.c | 541 +++++++++++++++++-------------- src/ctrl/ctrl_core.h | 73 +++-- src/dbg_engine/dbg_engine_core.c | 36 +- src/raddbg/raddbg_core.c | 72 ++-- src/raddbg/raddbg_eval.c | 10 +- src/raddbg/raddbg_views.c | 24 +- src/raddbg/raddbg_widgets.c | 10 +- 7 files changed, 407 insertions(+), 359 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 068185bd..b4d85938 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -653,12 +653,12 @@ ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity) } internal CTRL_EntityList -ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityStore *store, CTRL_HandleList *list) +ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityCtx *ctx, CTRL_HandleList *list) { CTRL_EntityList result = {0}; for(CTRL_HandleNode *n = list->first; n != 0; n = n->next) { - CTRL_Entity *entity = ctrl_entity_from_handle(store, n->v); + CTRL_Entity *entity = ctrl_entity_from_handle(ctx, n->v); ctrl_entity_list_push(arena, &result, entity); } return result; @@ -680,6 +680,172 @@ ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list) return result; } +//- rjf: entity context (entity group read-only) functions + +internal CTRL_Entity * +ctrl_entity_from_handle(CTRL_EntityCtx *ctx, CTRL_Handle handle) +{ + CTRL_Entity *entity = &ctrl_entity_nil; + if(!ctrl_handle_match(handle, ctrl_handle_zero())) + { + U64 hash = ctrl_hash_from_handle(handle); + U64 slot_idx = hash%ctx->hash_slots_count; + CTRL_EntityHashSlot *slot = &ctx->hash_slots[slot_idx]; + CTRL_EntityHashNode *node = 0; + for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->entity->handle, handle)) + { + entity = n->entity; + break; + } + } + } + return entity; +} + +internal CTRL_Entity * +ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind) +{ + CTRL_Entity *result = &ctrl_entity_nil; + for(CTRL_Entity *child = parent->first; + child != &ctrl_entity_nil; + child = child->next) + { + if(child->kind == kind) + { + result = child; + break; + } + } + return result; +} + +internal CTRL_Entity * +ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind) +{ + CTRL_Entity *result = &ctrl_entity_nil; + for(CTRL_Entity *p = entity->parent; p != &ctrl_entity_nil; p = p->parent) + { + if(p->kind == kind) + { + result = p; + break; + } + } + return result; +} + +internal CTRL_Entity * +ctrl_process_from_entity(CTRL_Entity *entity) +{ + CTRL_Entity *result = &ctrl_entity_nil; + if(entity->kind == CTRL_EntityKind_Process) + { + result = entity; + } + else + { + result = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + } + return result; +} + +internal CTRL_Entity * +ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr) +{ + CTRL_Entity *result = &ctrl_entity_nil; + for(CTRL_Entity *child = process->first; + child != &ctrl_entity_nil; + child = child->next) + { + if(child->kind == CTRL_EntityKind_Module && contains_1u64(child->vaddr_range, vaddr)) + { + result = child; + break; + } + } + return result; +} + +internal DI_Key +ctrl_dbgi_key_from_module(CTRL_Entity *module) +{ + CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); + DI_Key dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; + return dbgi_key; +} + +internal CTRL_Entity * +ctrl_module_from_thread_candidates(CTRL_EntityCtx *ctx, CTRL_Entity *thread, CTRL_EntityList *candidates) +{ + CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); + U64 thread_rip_vaddr = ctrl_rip_from_thread(ctx, thread->handle); + CTRL_Entity *src_module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); + CTRL_Entity *module = &ctrl_entity_nil; + for(CTRL_EntityNode *n = candidates->first; n != 0; n = n->next) + { + CTRL_Entity *candidate_module = n->v; + CTRL_Entity *candidate_process = ctrl_entity_ancestor_from_kind(candidate_module, CTRL_EntityKind_Process); + if(candidate_process == process) + { + module = candidate_module; + } + if(candidate_module == src_module) + { + break; + } + } + return module; +} + +internal U64 +ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff) +{ + U64 result = voff + module->vaddr_range.min; + return result; +} + +internal U64 +ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr) +{ + U64 result = vaddr - module->vaddr_range.min; + return result; +} + +internal Rng1U64 +ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range) +{ + U64 dim = dim_1u64(voff_range); + U64 min = ctrl_vaddr_from_voff(module, voff_range.min); + Rng1U64 result = {min, min+dim}; + return result; +} + +internal Rng1U64 +ctrl_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range) +{ + U64 dim = dim_1u64(vaddr_range); + U64 min = ctrl_voff_from_vaddr(module, vaddr_range.min); + Rng1U64 result = {min, min+dim}; + return result; +} + +internal B32 +ctrl_entity_tree_is_frozen(CTRL_Entity *root) +{ + B32 is_frozen = 1; + for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next) + { + if(e->kind == CTRL_EntityKind_Thread && !e->is_frozen) + { + is_frozen = 0; + break; + } + } + return is_frozen; +} + //- rjf: cache creation/destruction internal CTRL_EntityStore * @@ -688,13 +854,13 @@ ctrl_entity_store_alloc(void) Arena *arena = arena_alloc(); CTRL_EntityStore *store = push_array(arena, CTRL_EntityStore, 1); store->arena = arena; - store->hash_slots_count = 1024; - store->hash_slots = push_array(arena, CTRL_EntityHashSlot, store->hash_slots_count); + store->ctx.hash_slots_count = 1024; + store->ctx.hash_slots = push_array(arena, CTRL_EntityHashSlot, store->ctx.hash_slots_count); for EachEnumVal(CTRL_EntityKind, k) { store->entity_kind_arrays_arenas[k] = arena_alloc(); } - CTRL_Entity *root = store->root = ctrl_entity_alloc(store, &ctrl_entity_nil, CTRL_EntityKind_Root, Arch_Null, ctrl_handle_zero(), 0); + CTRL_Entity *root = store->ctx.root = ctrl_entity_alloc(store, &ctrl_entity_nil, CTRL_EntityKind_Root, Arch_Null, ctrl_handle_zero(), 0); CTRL_Entity *local_machine = ctrl_entity_alloc(store, root, CTRL_EntityKind_Machine, arch_from_context(), ctrl_handle_make(CTRL_MachineID_Local, dmn_handle_zero()), 0); Temp scratch = scratch_begin(0, 0); String8 local_machine_name = push_str8f(scratch.arena, "This PC (%S)", os_get_system_info()->machine_name); @@ -846,8 +1012,8 @@ ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind // rjf: insert into hash map { U64 hash = ctrl_hash_from_handle(handle); - U64 slot_idx = hash%store->hash_slots_count; - CTRL_EntityHashSlot *slot = &store->hash_slots[slot_idx]; + U64 slot_idx = hash%store->ctx.hash_slots_count; + CTRL_EntityHashSlot *slot = &store->ctx.hash_slots[slot_idx]; CTRL_EntityHashNode *node = 0; for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) { @@ -918,8 +1084,8 @@ ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity) // rjf: remove from hash map { U64 hash = ctrl_hash_from_handle(t->e->handle); - U64 slot_idx = hash%store->hash_slots_count; - CTRL_EntityHashSlot *slot = &store->hash_slots[slot_idx]; + U64 slot_idx = hash%store->ctx.hash_slots_count; + CTRL_EntityHashSlot *slot = &store->ctx.hash_slots[slot_idx]; CTRL_EntityHashNode *node = 0; for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) { @@ -954,113 +1120,28 @@ ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 s //- rjf: entity store lookups -internal CTRL_Entity * -ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Handle handle) +internal CTRL_EntityArray +ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind) { - CTRL_Entity *entity = &ctrl_entity_nil; - if(!ctrl_handle_match(handle, ctrl_handle_zero())) + if(store->entity_kind_arrays_gens[kind] != store->entity_kind_alloc_gens[kind]) { - U64 hash = ctrl_hash_from_handle(handle); - U64 slot_idx = hash%store->hash_slots_count; - CTRL_EntityHashSlot *slot = &store->hash_slots[slot_idx]; - CTRL_EntityHashNode *node = 0; - for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) + Temp scratch = scratch_begin(0, 0); + CTRL_EntityList entities = {0}; + for(CTRL_Entity *e = store->ctx.root; + e != &ctrl_entity_nil; + e = ctrl_entity_rec_depth_first_pre(e, store->ctx.root).next) { - if(ctrl_handle_match(n->entity->handle, handle)) + if(e->kind == kind) { - entity = n->entity; - break; + ctrl_entity_list_push(scratch.arena, &entities, e); } } + store->entity_kind_arrays_gens[kind] = store->entity_kind_alloc_gens[kind]; + arena_clear(store->entity_kind_arrays_arenas[kind]); + store->entity_kind_arrays[kind] = ctrl_entity_array_from_list(store->entity_kind_arrays_arenas[kind], &entities); + scratch_end(scratch); } - return entity; -} - -internal CTRL_Entity * -ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind) -{ - CTRL_Entity *result = &ctrl_entity_nil; - for(CTRL_Entity *child = parent->first; - child != &ctrl_entity_nil; - child = child->next) - { - if(child->kind == kind) - { - result = child; - break; - } - } - return result; -} - -internal CTRL_Entity * -ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind) -{ - CTRL_Entity *result = &ctrl_entity_nil; - for(CTRL_Entity *p = entity->parent; p != &ctrl_entity_nil; p = p->parent) - { - if(p->kind == kind) - { - result = p; - break; - } - } - return result; -} - -internal CTRL_Entity * -ctrl_process_from_entity(CTRL_Entity *entity) -{ - CTRL_Entity *result = &ctrl_entity_nil; - if(entity->kind == CTRL_EntityKind_Process) - { - result = entity; - } - else - { - result = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); - } - return result; -} - -internal CTRL_Entity * -ctrl_thread_from_id(CTRL_EntityStore *store, U64 id) -{ - CTRL_Entity *thread = &ctrl_entity_nil; - CTRL_EntityArray threads = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Thread); - for EachIndex(idx, threads.count) - { - if(threads.v[idx]->id == id) - { - thread = threads.v[idx]; - } - } - return thread; -} - -internal CTRL_Entity * -ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr) -{ - CTRL_Entity *result = &ctrl_entity_nil; - for(CTRL_Entity *child = process->first; - child != &ctrl_entity_nil; - child = child->next) - { - if(child->kind == CTRL_EntityKind_Module && contains_1u64(child->vaddr_range, vaddr)) - { - result = child; - break; - } - } - return result; -} - -internal DI_Key -ctrl_dbgi_key_from_module(CTRL_Entity *module) -{ - CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); - DI_Key dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; - return dbgi_key; + return store->entity_kind_arrays[kind]; } internal CTRL_EntityList @@ -1081,97 +1162,18 @@ ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_k } internal CTRL_Entity * -ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates) +ctrl_thread_from_id(CTRL_EntityStore *store, U64 id) { - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - U64 thread_rip_vaddr = ctrl_rip_from_thread(store, thread->handle); - CTRL_Entity *src_module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr); - CTRL_Entity *module = &ctrl_entity_nil; - for(CTRL_EntityNode *n = candidates->first; n != 0; n = n->next) + CTRL_Entity *thread = &ctrl_entity_nil; + CTRL_EntityArray threads = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) { - CTRL_Entity *candidate_module = n->v; - CTRL_Entity *candidate_process = ctrl_entity_ancestor_from_kind(candidate_module, CTRL_EntityKind_Process); - if(candidate_process == process) + if(threads.v[idx]->id == id) { - module = candidate_module; - } - if(candidate_module == src_module) - { - break; + thread = threads.v[idx]; } } - return module; -} - -internal CTRL_EntityArray -ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind) -{ - if(store->entity_kind_arrays_gens[kind] != store->entity_kind_alloc_gens[kind]) - { - Temp scratch = scratch_begin(0, 0); - CTRL_EntityList entities = {0}; - for(CTRL_Entity *e = store->root; - e != &ctrl_entity_nil; - e = ctrl_entity_rec_depth_first_pre(e, store->root).next) - { - if(e->kind == kind) - { - ctrl_entity_list_push(scratch.arena, &entities, e); - } - } - store->entity_kind_arrays_gens[kind] = store->entity_kind_alloc_gens[kind]; - arena_clear(store->entity_kind_arrays_arenas[kind]); - store->entity_kind_arrays[kind] = ctrl_entity_array_from_list(store->entity_kind_arrays_arenas[kind], &entities); - scratch_end(scratch); - } - return store->entity_kind_arrays[kind]; -} - -internal U64 -ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff) -{ - U64 result = voff + module->vaddr_range.min; - return result; -} - -internal U64 -ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr) -{ - U64 result = vaddr - module->vaddr_range.min; - return result; -} - -internal Rng1U64 -ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range) -{ - U64 dim = dim_1u64(voff_range); - U64 min = ctrl_vaddr_from_voff(module, voff_range.min); - Rng1U64 result = {min, min+dim}; - return result; -} - -internal Rng1U64 -ctrl_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range) -{ - U64 dim = dim_1u64(vaddr_range); - U64 min = ctrl_voff_from_vaddr(module, vaddr_range.min); - Rng1U64 result = {min, min+dim}; - return result; -} - -internal B32 -ctrl_entity_tree_is_frozen(CTRL_Entity *root) -{ - B32 is_frozen = 1; - for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next) - { - if(e->kind == CTRL_EntityKind_Thread && !e->is_frozen) - { - is_frozen = 0; - break; - } - } - return is_frozen; + return thread; } //- rjf: entity tree iteration @@ -1214,14 +1216,14 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) //- rjf: processes case CTRL_EventKind_NewProc: { - CTRL_Entity *machine = ctrl_entity_from_handle(store, ctrl_handle_make(event->entity.machine_id, dmn_handle_zero())); + CTRL_Entity *machine = ctrl_entity_from_handle(&store->ctx, ctrl_handle_make(event->entity.machine_id, dmn_handle_zero())); CTRL_Entity *process = ctrl_entity_alloc(store, machine, CTRL_EntityKind_Process, event->arch, event->entity, (U64)event->entity_id); }break; case CTRL_EventKind_EndProc: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->entity); ctrl_entity_release(store, process); - for(CTRL_Entity *entry = store->root->first, *next = &ctrl_entity_nil; + for(CTRL_Entity *entry = store->ctx.root->first, *next = &ctrl_entity_nil; entry != &ctrl_entity_nil; entry = next) { @@ -1236,7 +1238,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) //- rjf: threads case CTRL_EventKind_NewThread: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); CTRL_Entity *thread = ctrl_entity_alloc(store, process, CTRL_EntityKind_Thread, event->arch, event->entity, (U64)event->entity_id); CTRL_Entity *first_thread = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Thread); if(first_thread == thread) @@ -1266,20 +1268,20 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) } } thread->stack_base = event->stack_base; - ctrl_rip_from_thread(store, event->entity); + ctrl_rip_from_thread(&store->ctx, event->entity); }break; case CTRL_EventKind_EndThread: { - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *thread = ctrl_entity_from_handle(&store->ctx, event->entity); ctrl_entity_release(store, thread); }break; case CTRL_EventKind_ThreadName: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); CTRL_Entity *thread = &ctrl_entity_nil; if(event->entity_id == 0) { - thread = ctrl_entity_from_handle(store, event->entity); + thread = ctrl_entity_from_handle(&store->ctx, event->entity); } else { @@ -1297,11 +1299,11 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) }break; case CTRL_EventKind_ThreadColor: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); CTRL_Entity *thread = &ctrl_entity_nil; if(event->entity_id == 0) { - thread = ctrl_entity_from_handle(store, event->entity); + thread = ctrl_entity_from_handle(&store->ctx, event->entity); } else { @@ -1319,12 +1321,12 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) }break; case CTRL_EventKind_ThreadFrozen: { - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *thread = ctrl_entity_from_handle(&store->ctx, event->entity); thread->is_frozen = 1; }break; case CTRL_EventKind_ThreadThawed: { - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *thread = ctrl_entity_from_handle(&store->ctx, event->entity); thread->is_frozen = 0; }break; @@ -1332,7 +1334,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) case CTRL_EventKind_NewModule: { Temp scratch = scratch_begin(0, 0); - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); CTRL_Entity *module = ctrl_entity_alloc(store, process, CTRL_EntityKind_Module, event->arch, event->entity, event->vaddr_rng.min); ctrl_entity_equip_string(store, module, event->string); module->timestamp = event->timestamp; @@ -1346,12 +1348,12 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) }break; case CTRL_EventKind_EndModule: { - CTRL_Entity *module = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *module = ctrl_entity_from_handle(&store->ctx, event->entity); ctrl_entity_release(store, module); }break; case CTRL_EventKind_ModuleDebugInfoPathChange: { - CTRL_Entity *module = ctrl_entity_from_handle(store, event->entity); + CTRL_Entity *module = ctrl_entity_from_handle(&store->ctx, event->entity); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); if(debug_info_path == &ctrl_entity_nil) { @@ -1364,14 +1366,14 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) //- rjf: dynamic, program-created breakpoints case CTRL_EventKind_SetBreakpoint: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); CTRL_Entity *bp = ctrl_entity_alloc(store, process, CTRL_EntityKind_Breakpoint, Arch_Null, ctrl_handle_zero(), 0); bp->vaddr_range = event->vaddr_rng; bp->bp_flags = event->bp_flags; }break; case CTRL_EventKind_UnsetBreakpoint: { - CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *process = ctrl_entity_from_handle(&store->ctx, event->parent); for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) { if(child->kind == CTRL_EntityKind_Breakpoint && @@ -1468,6 +1470,7 @@ ctrl_init(void) os_write_data_to_file_path(ctrl_state->ctrl_thread_log_path, str8_zero()); scratch_end(scratch); } + ctrl_state->ctrl_thread_entity_ctx_rw_mutex = os_rw_mutex_alloc(); ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); ctrl_state->ctrl_thread_eval_cache = e_cache_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); @@ -1937,10 +1940,10 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src) //- rjf: thread register cache reading internal void * -ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle handle) { CTRL_ThreadRegCache *cache = &ctrl_state->thread_reg_cache; - CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); + CTRL_Entity *thread_entity = ctrl_entity_from_handle(ctx, handle); Arch arch = thread_entity->arch; U64 reg_block_size = regs_block_size_from_arch(arch); U64 hash = ctrl_hash_from_handle(handle); @@ -1996,31 +1999,31 @@ ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle ha } internal U64 -ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_tls_root_vaddr_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle) { U64 result = dmn_tls_root_vaddr_from_thread(handle.dmn_handle); return result; } internal U64 -ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_rip_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle) { Temp scratch = scratch_begin(0, 0); - CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); + CTRL_Entity *thread_entity = ctrl_entity_from_handle(ctx, handle); Arch arch = thread_entity->arch; - void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, ctx, handle); U64 result = regs_rip_from_arch_block(arch, block); scratch_end(scratch); return result; } internal U64 -ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle) +ctrl_rsp_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle) { Temp scratch = scratch_begin(0, 0); - CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle); + CTRL_Entity *thread_entity = ctrl_entity_from_handle(ctx, handle); Arch arch = thread_entity->arch; - void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, ctx, handle); U64 result = regs_rsp_from_arch_block(arch, block); scratch_end(scratch); return result; @@ -3071,7 +3074,7 @@ ctrl_unwind_step(CTRL_Handle process, CTRL_Handle module, U64 module_base_vaddr, //- rjf: abstracted full unwind internal CTRL_Unwind -ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle thread, U64 endt_us) +ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle thread, U64 endt_us) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -3079,13 +3082,13 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa unwind.flags |= CTRL_UnwindFlag_Error; //- rjf: unpack args - CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, thread); + CTRL_Entity *thread_entity = ctrl_entity_from_handle(ctx, thread); CTRL_Entity *process_entity = thread_entity->parent; Arch arch = thread_entity->arch; U64 arch_reg_block_size = regs_block_size_from_arch(arch); //- rjf: grab initial register block - void *regs_block = ctrl_reg_block_from_thread(scratch.arena, store, thread); + void *regs_block = ctrl_reg_block_from_thread(scratch.arena, ctx, thread); B32 regs_block_good = (arch != Arch_Null && regs_block != 0); //- rjf: loop & unwind @@ -3158,9 +3161,10 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa //~ rjf: Call Stack Building Functions internal CTRL_CallStack -ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind) +ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *base_unwind) { Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); Arch arch = process->arch; CTRL_CallStack result = {0}; { @@ -3237,6 +3241,7 @@ ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *proce } } } + di_scope_close(di_scope); scratch_end(scratch); return result; } @@ -3267,6 +3272,20 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U return f; } +//////////////////////////////// +//~ rjf: Call Stack Cache Functions + +internal CTRL_CallStack +ctrl_call_stack_from_thread(HS_Scope *hs_scope, CTRL_Entity *thread, U64 endt_us) +{ + CTRL_CallStack call_stack = {0}; + { + CTRL_Handle handle = thread->handle; + + } + return call_stack; +} + //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -3507,7 +3526,7 @@ ctrl_thread__entry_point(void *p) case CTRL_MsgKind_SetModuleDebugInfoPath: { String8 path = msg->path; - CTRL_Entity *module = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, msg->entity); + CTRL_Entity *module = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, msg->entity); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); DI_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; di_close(&old_dbgi_key); @@ -3569,7 +3588,7 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope * if(user_bps->first == 0) { return; } Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = eval_scope->di_scope; - CTRL_Entity *module_entity = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module); + CTRL_Entity *module_entity = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, module); CTRL_Entity *debug_info_path_entity = ctrl_entity_child_from_kind(module_entity, CTRL_EntityKind_DebugInfoPath); DI_Key dbgi_key = {debug_info_path_entity->string, debug_info_path_entity->timestamp}; RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64); @@ -4139,7 +4158,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, (spoof == 0 || ev->instruction_pointer != spoof->new_ip_value)) { DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, ev->process)); + CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->process)); CTRL_Entity *module = &ctrl_entity_nil; for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) { @@ -4230,7 +4249,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, U64 size_of_spoof = 0; if(do_spoof) ProfScope("prep spoof") { - CTRL_Entity *spoof_process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, spoof->process)); + CTRL_Entity *spoof_process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->process)); Arch arch = spoof_process->arch; size_of_spoof = bit_size_from_arch(arch)/8; dmn_process_read(spoof_process->handle.dmn_handle, r1u64(spoof->vaddr, spoof->vaddr+size_of_spoof), &spoof_old_ip_value); @@ -4296,7 +4315,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, // simply been sent other debug events first if(spoof != 0) { - CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, spoof->thread)); + CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->thread)); Arch arch = thread->arch; void *regs_block = push_array(scratch.arena, U8, regs_block_size_from_arch(arch)); dmn_thread_read_reg_block(spoof->thread, regs_block); @@ -4388,7 +4407,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); CTRL_Handle module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); - CTRL_Entity *module_ent = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, module_handle); + CTRL_Entity *module_ent = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, module_handle); CTRL_Entity *process_ent = ctrl_process_from_entity(module_ent); String8 module_path = event->string; ctrl_thread__module_close(process_ent->handle, module_handle, module_ent->vaddr_range); @@ -4489,8 +4508,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, //- rjf: unpack event CTRL_Handle process_handle = ctrl_handle_make(CTRL_MachineID_Local, event->process); CTRL_Handle loaded_module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); - CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, process_handle); - CTRL_Entity *loaded_module = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, loaded_module_handle); + CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, process_handle); + CTRL_Entity *loaded_module = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, loaded_module_handle); //- rjf: for each module, use its full path as the start to a new limited recursive // directory search. cache each directory once traversed in the dbg_dir tree. if any @@ -4708,7 +4727,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); U64 regs_size = regs_block_size_from_arch(entity->arch); - void *regs = ctrl_reg_block_from_thread(scratch.arena, ctrl_state->ctrl_thread_entity_store, entity->handle); + void *regs = ctrl_reg_block_from_thread(scratch.arena, &ctrl_state->ctrl_thread_entity_store->ctx, entity->handle); Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 read_range = intersect_1u64(legal_range, range); U64 read_size = dim_1u64(read_range); @@ -4755,7 +4774,7 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) eval_modules_primary->vaddr_range = r1u64(0, max_U64); { U64 eval_module_idx = 0; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -4926,7 +4945,7 @@ ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) for(String8Node *n = msg->entry_points.first; n != 0; n = n->next) { String8 string = n->string; - CTRL_Entity *entry = ctrl_entity_alloc(ctrl_state->ctrl_thread_entity_store, ctrl_state->ctrl_thread_entity_store->root, CTRL_EntityKind_EntryPoint, Arch_Null, ctrl_handle_zero(), (U64)id); + CTRL_Entity *entry = ctrl_entity_alloc(ctrl_state->ctrl_thread_entity_store, ctrl_state->ctrl_thread_entity_store->ctx.root, CTRL_EntityKind_EntryPoint, Arch_Null, ctrl_handle_zero(), (U64)id); ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, entry, string); } } @@ -5093,7 +5112,7 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) default:{}break; case DMN_EventKind_CreateProcess: { - CTRL_Entity *new_process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *new_process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); Task *t = push_array(scratch.arena, Task, 1); t->process = new_process; DLLPushBack(first_task, last_task, t); @@ -5184,7 +5203,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) CTRL_EventCause stop_cause = CTRL_EventCause_Null; CTRL_Handle target_thread = msg->entity; CTRL_Handle target_process = msg->parent; - CTRL_Entity *target_process_entity = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, target_process); + CTRL_Entity *target_process_entity = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, target_process); U64 spoof_ip_vaddr = 911; log_infof("ctrl_thread__run:\n{\n"); @@ -5193,9 +5212,9 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) // DMN_TrapChunkList user_traps = {0}; { - CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, target_thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, target_thread); CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5252,7 +5271,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { // rjf: gather stuck threads DMN_HandleList stuck_threads = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5357,7 +5376,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: gather frozen threads // CTRL_EntityList frozen_threads = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->root->first; + for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5508,7 +5527,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) }break; case DMN_EventKind_LoadModule: { - CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); { DMN_TrapChunkList new_traps = {0}; @@ -5533,7 +5552,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { CTRL_Entity *bp = &ctrl_entity_nil; { - CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) { if(child->kind == CTRL_EntityKind_Breakpoint && @@ -5565,7 +5584,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) DI_Scope *di_scope = di_scope_open(); //- rjf: unpack process/module info - CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); CTRL_Entity *module = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Module); U64 module_base_vaddr = module->vaddr_range.min; CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); @@ -5641,7 +5660,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: add traps for PID-correllated entry points if(!entries_found) { - for(CTRL_Entity *e = ctrl_state->ctrl_thread_entity_store->root->first; e != &ctrl_entity_nil; e = e->next) + for(CTRL_Entity *e = ctrl_state->ctrl_thread_entity_store->ctx.root->first; e != &ctrl_entity_nil; e = e->next) { if(e->id == process->id) { @@ -5789,8 +5808,8 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ////////////////////////// //- rjf: unpack info about thread attached to event // - CTRL_Entity *thread = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); - CTRL_Entity *process = ctrl_entity_from_handle(ctrl_state->ctrl_thread_entity_store, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); Arch arch = thread->arch; U64 thread_rip_vaddr = dmn_rip_from_thread(event->thread); CTRL_Entity *module = &ctrl_entity_nil; @@ -6602,9 +6621,33 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) { CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; - //- rjf: get next request + //- rjf: get next request & unpack CTRL_Handle thread_handle = {0}; ctrl_u2csb_dequeue_req(&thread_handle); + U64 hash = ctrl_hash_from_handle(thread_handle); + U64 slot_idx = hash%cache->slots_count; + U64 stripe_idx = hash%cache->stripes_count; + CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; + CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; + + //- rjf: do task +#if 0 + OS_MutexScopeR(ctrl_state->call_stack_builder_entity_store_rw_mutex) + { + Temp scratch = scratch_begin(0, 0); + CTRL_EntityStore *store = ctrl_state->call_stack_builder_entity_store; + + //- rjf: compute unwind to find list of all concrete frames, then + // call stack, to determine list of all concrete & inline frames + CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, store, thread_handle, os_now_microseconds()+1000000); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena); + + //- rjf: use debug info to to list of all (concrete & inline) frames + + + scratch_end(scratch); + } +#endif return 0; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index c21098e4..1d455584 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -178,15 +178,21 @@ read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] = 0xffffffffffffffffull, }; +typedef struct CTRL_EntityCtx CTRL_EntityCtx; +struct CTRL_EntityCtx +{ + CTRL_Entity *root; + CTRL_EntityHashSlot *hash_slots; + U64 hash_slots_count; +}; + typedef struct CTRL_EntityStore CTRL_EntityStore; struct CTRL_EntityStore { Arena *arena; - CTRL_Entity *root; + CTRL_EntityCtx ctx; CTRL_Entity *free; - CTRL_EntityHashSlot *hash_slots; CTRL_EntityHashNode *hash_node_free; - U64 hash_slots_count; CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)]; U64 entity_kind_counts[CTRL_EntityKind_COUNT]; Arena *entity_kind_arrays_arenas[CTRL_EntityKind_COUNT]; @@ -601,7 +607,6 @@ struct CTRL_CallStackCacheNode CTRL_Handle thread; U64 reg_gen; U64 mem_gen; - CTRL_Unwind unwind; CTRL_CallStack call_stack; }; @@ -745,6 +750,7 @@ struct CTRL_State String8 ctrl_thread_log_path; OS_Handle ctrl_thread; Log *ctrl_thread_log; + OS_Handle ctrl_thread_entity_ctx_rw_mutex; CTRL_EntityStore *ctrl_thread_entity_store; E_Cache *ctrl_thread_eval_cache; Arena *dmn_event_arena; @@ -860,13 +866,32 @@ internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 stri //- rjf: entity list data structures internal void ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity); -internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityStore *store, CTRL_HandleList *list); +internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityCtx *ctx, CTRL_HandleList *list); #define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil) //- rjf: entity array data structure internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list); #define ctrl_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &ctrl_entity_nil) +//- rjf: entity context (entity group read-only) functions +internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityCtx *ctx, CTRL_Handle handle); +internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); +internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); +internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); +internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); +internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); +internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityCtx *ctx, CTRL_Entity *thread, CTRL_EntityList *candidates); +internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff); +internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr); +internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range); +internal Rng1U64 ctrl_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range); +internal B32 ctrl_entity_tree_is_frozen(CTRL_Entity *root); + +//- rjf: entity tree iteration +internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_Entity *subtree_root, U64 sib_off, U64 child_off); +#define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first)) +#define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last)) + //- rjf: cache creation/destruction internal CTRL_EntityStore *ctrl_entity_store_alloc(void); internal void ctrl_entity_store_release(CTRL_EntityStore *store); @@ -884,26 +909,9 @@ internal void ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity); internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string); //- rjf: entity store lookups -internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Handle handle); -internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); -internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); -internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); -internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityStore *store, U64 id); -internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); -internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); -internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); -internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates); internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind); -internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff); -internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr); -internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range); -internal Rng1U64 ctrl_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range); -internal B32 ctrl_entity_tree_is_frozen(CTRL_Entity *root); - -//- rjf: entity tree iteration -internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_Entity *subtree_root, U64 sib_off, U64 child_off); -#define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first)) -#define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last)) +internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); +internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityStore *store, U64 id); //- rjf: applying events to entity caches internal void ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list); @@ -940,10 +948,10 @@ internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src); //~ rjf: Thread Register Functions //- rjf: thread register cache reading -internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); -internal U64 ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); +internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle handle); +internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle); +internal U64 ctrl_rip_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle); +internal U64 ctrl_rsp_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle); //- rjf: thread register writing internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block); @@ -972,14 +980,19 @@ internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_Handle process_hand internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_Handle process, CTRL_Handle module, U64 module_base_vaddr, Arch arch, void *reg_block, U64 endt_us); //- rjf: abstracted full unwind -internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle thread, U64 endt_us); +internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle thread, U64 endt_us); //////////////////////////////// //~ rjf: Call Stack Building Functions -internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind); +internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *base_unwind); internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth); +//////////////////////////////// +//~ rjf: Call Stack Cache Functions + +internal CTRL_CallStack ctrl_call_stack_from_thread(HS_Scope *hs_scope, CTRL_Entity *thread, U64 endt_us); + //////////////////////////////// //~ rjf: Halting All Attached Processes diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index a28216d9..e3dbf114 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -300,7 +300,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) // rjf: thread => unpacked info CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); Arch arch = thread->arch; - U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); // rjf: ip => machine code String8 machine_code = {0}; @@ -337,7 +337,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) // rjf: thread => info Arch arch = thread->arch; - U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); @@ -498,7 +498,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) // rjf: thread => info Arch arch = thread->arch; - U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); @@ -1240,7 +1240,7 @@ d_query_cached_unwind_from_thread(CTRL_Entity *thread) } if(!d_state->ctrl_is_running && (node->reggen != reg_gen || node->memgen != mem_gen)) { - CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle, os_now_microseconds()+100); + CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle, os_now_microseconds()+100); if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0) { node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind); @@ -1267,7 +1267,7 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count) U64 result = 0; if(unwind_count == 0) { - result = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + result = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); } else { @@ -1579,7 +1579,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: push stop event to caller, if this is not a soft-halt if(should_snap) { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, event->entity); D_EventCause cause = D_EventCause_Null; switch(event->cause) { @@ -1743,7 +1743,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P for(D_UnwindCacheNode *n = slot->first, *next = 0; n != 0; n = next) { next = n->next; - if(ctrl_entity_from_handle(d_state->ctrl_entity_store, n->thread) == &ctrl_entity_nil) + if(ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, n->thread) == &ctrl_entity_nil) { DLLRemove(slot->first, slot->last, n); arena_release(n->arena); @@ -1869,7 +1869,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Kill: { - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->process); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->process); if(process == &ctrl_entity_nil) { log_user_error(str8_lit("Cannot kill; no process was specified.")); @@ -1892,7 +1892,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Detach: { - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->process); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->process); if(process == &ctrl_entity_nil) { log_user_error(str8_lit("Cannot detach; no process specified.")); @@ -1938,7 +1938,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepOverLine: case D_CmdKind_StepOut: { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->thread); if(thread == &ctrl_entity_nil) { log_user_error(str8_lit("Must have a selected thread to step.")); @@ -1968,7 +1968,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepOut: { // rjf: thread => full unwind - CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle, os_now_microseconds()+10000); + CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle, os_now_microseconds()+10000); // rjf: use first unwind frame to generate trap if(unwind.flags == 0 && unwind.frames.count > 1) @@ -2012,15 +2012,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { need_run = 1; run_kind = d_state->ctrl_last_run_kind; - run_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, d_state->ctrl_last_run_thread_handle); + run_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, d_state->ctrl_last_run_thread_handle); run_flags = d_state->ctrl_last_run_flags; run_traps = d_state->ctrl_last_run_traps; }break; case D_CmdKind_SetThreadIP: { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->thread); U64 vaddr = params->vaddr; - void *block = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle); + void *block = ctrl_reg_block_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle); regs_arch_block_write_rip(thread->arch, block, vaddr); B32 result = ctrl_thread_write_reg_block(thread->handle, block); @@ -2136,7 +2136,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_ThawEntity: { B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity); - CTRL_Entity *root = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); + CTRL_Entity *root = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity); for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next) { if(e->kind == CTRL_EntityKind_Thread) @@ -2151,7 +2151,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { need_run = 1; run_kind = d_state->ctrl_last_run_kind; - run_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, d_state->ctrl_last_run_thread_handle); + run_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, d_state->ctrl_last_run_thread_handle); run_flags = d_state->ctrl_last_run_flags; run_traps = d_state->ctrl_last_run_traps; } @@ -2160,12 +2160,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P //- rjf: entity decoration case D_CmdKind_SetEntityColor: { - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); + CTRL_Entity *entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity); entity->rgba = params->rgba; }break; case D_CmdKind_SetEntityName: { - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); + CTRL_Entity *entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity); ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, params->string); }break; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 07f0f216..f2330d73 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1693,7 +1693,7 @@ rd_ctrl_entity_from_eval_space(E_Space space) CTRL_Handle handle; handle.machine_id = space.u64s[0]; handle.dmn_handle.u64[0] = space.u64s[1]; - entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, handle); } return entity; } @@ -2021,7 +2021,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 write_range = intersect_1u64(legal_range, range); U64 write_size = dim_1u64(write_range); - void *new_regs = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, entity->handle); + void *new_regs = ctrl_reg_block_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, entity->handle); MemoryCopy((U8 *)new_regs + write_range.min, in, write_size); result = ctrl_thread_write_reg_block(entity->handle, new_regs); scratch_end(scratch); @@ -3352,7 +3352,7 @@ rd_view_ui(Rng2F32 rect) String8 name = {0}; { U64 vaddr = eval.value.u64; - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); @@ -5601,7 +5601,7 @@ rd_arch_from_eval(E_Eval eval) CTRL_Entity *process = ctrl_process_from_entity(ctrl_entity); if(process == &ctrl_entity_nil) { - process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); } Arch arch = process->arch; if(arch == Arch_Null) @@ -6337,16 +6337,15 @@ rd_window_frame(void) //////////////////////// //- rjf: control entity tooltips // - case RD_RegSlot_Machine: {ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->machine); }goto ctrl_entity_tooltip; - case RD_RegSlot_Process: {ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->process); }goto ctrl_entity_tooltip; - case RD_RegSlot_Module: {ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->module); }goto ctrl_entity_tooltip; - case RD_RegSlot_Thread: {ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->thread); }goto ctrl_entity_tooltip; - case RD_RegSlot_CtrlEntity:{ctrl_entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, regs->ctrl_entity); }goto ctrl_entity_tooltip; + case RD_RegSlot_Machine: {ctrl_entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, regs->machine); }goto ctrl_entity_tooltip; + case RD_RegSlot_Process: {ctrl_entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, regs->process); }goto ctrl_entity_tooltip; + case RD_RegSlot_Module: {ctrl_entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, regs->module); }goto ctrl_entity_tooltip; + case RD_RegSlot_Thread: {ctrl_entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, regs->thread); }goto ctrl_entity_tooltip; + case RD_RegSlot_CtrlEntity:{ctrl_entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, regs->ctrl_entity); }goto ctrl_entity_tooltip; ctrl_entity_tooltip:; UI_Tooltip { // rjf: unpack - DI_Scope *di_scope = di_scope_open(); Arch arch = ctrl_entity->arch; String8 arch_str = string_from_arch(arch); DR_FStrList fstrs = rd_title_fstrs_from_ctrl_entity(scratch.arena, ctrl_entity, 0); @@ -6398,7 +6397,7 @@ rd_window_frame(void) Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); if(call_stack.count != 0) { ui_spacer(ui_em(1.5f, 1.f)); @@ -6417,7 +6416,6 @@ rd_window_frame(void) } } - di_scope_close(di_scope); }break; //////////////////////// @@ -10193,7 +10191,7 @@ rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 RD_CodeColorSlot color = RD_CodeColorSlot_CodeDefault; if(kind == TXT_TokenKind_Identifier || kind == TXT_TokenKind_Keyword) { - CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); B32 mapped = 0; @@ -10312,7 +10310,7 @@ rd_string_from_exception_code(U32 code) internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, CTRL_Event *event) { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, event->entity); DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0); DR_FStrList fstrs = {0}; DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; @@ -11610,15 +11608,15 @@ rd_frame(void) //- rjf: unpack eval-dependent info // ProfBegin("unpack eval-dependent info"); - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); Arch arch = thread->arch; U64 unwind_count = rd_regs()->unwind_count; U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); - U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); U64 eval_modules_count = Max(1, all_modules.count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); @@ -14006,12 +14004,12 @@ rd_frame(void) //- rjf: source <-> disasm case RD_CmdKind_GoToDisassembly: { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); U64 vaddr = 0; for(D_LineNode *n = rd_regs()->lines.first; n != 0; n = n->next) { CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); - CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules); + CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); @@ -14294,7 +14292,7 @@ rd_frame(void) RD_RegsScope(.window = ws->cfg_id) { DI_Scope *scope = di_scope_open(); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); U64 unwind_index = rd_regs()->unwind_count; U64 inline_depth = rd_regs()->inline_depth; if(thread->kind == CTRL_EntityKind_Thread) @@ -14366,7 +14364,7 @@ rd_frame(void) for(RD_WindowState *ws = rd_state->first_window_state; ws != &rd_nil_window_state; ws = ws->order_next) RD_RegsScope(.window = ws->cfg_id) { - CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); rd_cmd(RD_CmdKind_FindThread, .thread = selected_thread->handle, .unwind_count = rd_base_regs()->unwind_count, @@ -14550,8 +14548,8 @@ rd_frame(void) { file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path); point = rd_regs()->cursor; - thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); + process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); vaddr = rd_regs()->vaddr; if(file_path.size == 0) { @@ -14567,7 +14565,7 @@ rd_frame(void) for(D_LineNode *n = lines.first; n != 0; n = n->next) { CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); - CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules); + CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); break; } @@ -15501,7 +15499,7 @@ rd_frame(void) }break; case RD_CmdKind_SetNextStatement: { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); String8 file_path = rd_regs()->file_path; U64 new_rip_vaddr = rd_regs()->vaddr_range.min; if(file_path.size != 0) @@ -15510,7 +15508,7 @@ rd_frame(void) for(D_LineNode *n = lines->first; n != 0; n = n->next) { CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); - CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules); + CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); @@ -15622,9 +15620,9 @@ rd_frame(void) }break; case RD_CmdKind_SelectThread: { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle)); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle)); CTRL_Entity *machine = ctrl_entity_ancestor_from_kind(process, CTRL_EntityKind_Machine); rd_state->base_regs.v.unwind_count = 0; rd_state->base_regs.v.inline_depth = 0; @@ -15636,11 +15634,10 @@ rd_frame(void) }break; case RD_CmdKind_SelectUnwind: { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); if(frame == 0) { @@ -15652,16 +15649,14 @@ rd_frame(void) rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; } rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth); - di_scope_close(di_scope); }break; case RD_CmdKind_UpOneFrame: case RD_CmdKind_DownOneFrame: { - DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *next_frame = current_frame; if(current_frame != 0) switch(kind) @@ -15685,7 +15680,6 @@ rd_frame(void) .unwind_count = next_frame->unwind_count, .inline_depth = next_frame->inline_depth); } - di_scope_close(di_scope); }break; //- rjf: meta controls @@ -16391,13 +16385,13 @@ rd_frame(void) case D_EventKind_Stop: { B32 need_refocus = (evt->cause != D_EventCause_SoftHalt); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, evt->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, evt->thread); U64 vaddr = evt->vaddr; CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); - U64 test_cached_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle); + U64 test_cached_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); // rjf: valid stop thread? -> select & snap if(need_refocus && thread != &ctrl_entity_nil && evt->cause != D_EventCause_Halt) @@ -16406,7 +16400,7 @@ rd_frame(void) } // rjf: no stop-causing thread, but have selected thread? -> snap to selected - CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_base_regs()->thread); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); if(need_refocus && (evt->cause == D_EventCause_Halt || thread == &ctrl_entity_nil) && selected_thread != &ctrl_entity_nil) { rd_cmd(RD_CmdKind_SelectThread, .thread = selected_thread->handle); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index f2674ae2..79094843 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -205,7 +205,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers) { Temp scratch = scratch_begin(&arena, 1); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); Arch arch = thread->arch; U64 reg_count = regs_reg_code_count_from_arch(arch); U64 alias_count = regs_alias_code_count_from_arch(arch); @@ -658,7 +658,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(control) str8_match(str8_prefix(rhs->string, 1), str8_lit("$"), 0)) { CTRL_Handle handle = ctrl_handle_from_string(rhs->string); - CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + CTRL_Entity *entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, handle); E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, ctrl_entity_kind_code_name_table[entity->kind]); @@ -959,7 +959,7 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); accel->arch = entity->arch; accel->process = process->handle; - accel->call_stack = ctrl_call_stack_from_unwind(arena, rd_state->frame_di_scope, process, &base_unwind); + accel->call_stack = ctrl_call_stack_from_unwind(arena, process, &base_unwind); } scratch_end(scratch); } @@ -977,7 +977,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack) CTRL_CallStack *call_stack = &accel->call_stack; if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) { - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, accel->process); CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs))); result.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); @@ -1420,7 +1420,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities) { String8 rhs_name = expr->first->next->string; CTRL_Handle handle = ctrl_handle_from_string(rhs_name); - entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, handle); }break; case E_ExprKind_ArrayIndex: { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8b2accfc..27fb0679 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -44,7 +44,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla F32 scroll_bar_dim = floor_f32(main_font_size*1.5f); Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim); S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1; - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers")); @@ -260,7 +260,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find live threads mapping to source code if(!dasm_lines) ProfScope("find live threads mapping to this file") { - CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { @@ -323,7 +323,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(!dasm_lines) ProfScope("find all src -> dasm info for source code") { String8 file_path = rd_regs()->file_path; - CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); D_LineListArray lines_array = d_lines_array_from_dbgi_key_file_path_line_range(scratch.arena, dbgi_key, file_path, visible_line_num_range); if(lines_array.count != 0) @@ -336,7 +336,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla // rjf: find live threads mapping to disasm if(dasm_lines) ProfScope("find live threads mapping to this disassembly") { - CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { @@ -1008,11 +1008,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); if(entity->kind == CTRL_EntityKind_Thread) { - DI_Scope *di_scope = di_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_process_from_entity(entity), &unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, ctrl_process_from_entity(entity), &unwind); if(1 <= frame_num && frame_num <= call_stack.count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; @@ -1020,7 +1019,6 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.callstack_inline_depth = f->inline_depth; info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); } - di_scope_close(di_scope); } } @@ -2143,7 +2141,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) // if(rd_regs()->file_path.size != 0) { - CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->module); + CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line); } @@ -2284,13 +2282,13 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == ctrl_run_gen()) { auto_selected = 1; - auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); + auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); eval = e_eval_from_stringf("(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); } else { auto_selected = 1; - auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); + auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); eval = e_eval_from_stringf("(rip.u64 & (~(0x4000 - 1)))"); } } @@ -2522,7 +2520,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) Rng1U64 view_range = r1u64(base_offset, base_offset+size); if(eval.space.kind == 0) { - eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); + eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); view_range = rd_whole_range_from_eval_space(eval.space); } if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity && dim_1u64(view_range) == KB(16)) @@ -2839,7 +2837,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) }; AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size); { - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); @@ -2863,7 +2861,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) String8 symbol_name = {0}; { U64 vaddr = eval.value.u64; - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); + CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); U64 voff = ctrl_voff_from_vaddr(module, vaddr); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index c2468470..57218fb7 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1210,7 +1210,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe RD_CodeSliceSignal result = {0}; ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *selected_thread_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process); U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count); CTRL_Entity *selected_thread_module = ctrl_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr); @@ -1218,7 +1218,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe F32 selected_thread_module_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###selected_thread_module_alive_t_%p", selected_thread_module), 1.f); F32 selected_thread_arch_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###selected_thread_arch_alive_t_%i", selected_thread->arch), 1.f); CTRL_Event stop_event = d_ctrl_last_stop_event(); - CTRL_Entity *stopper_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, stop_event.entity); + CTRL_Entity *stopper_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, stop_event.entity); B32 is_focused = ui_is_focus_active(); B32 ctrlified = (os_get_modifiers() & OS_Modifier_Ctrl); Vec4F32 code_line_bgs[] = @@ -1353,7 +1353,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) { drop_can_hit_lines = 1; - drop_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_state->drag_drop_regs->thread); + drop_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_state->drag_drop_regs->thread); drop_color = rd_color_from_ctrl_entity(drop_thread); if(drop_color.w == 0) { @@ -2326,7 +2326,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe for(D_LineNode *n = lines->first; n != 0; n = n->next) { CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); - CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules); + CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); @@ -2493,7 +2493,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe Rng1U64 hover_voff_range = hover_regs->voff_range; if(hover_voff_range.min == 0 && hover_voff_range.max == 0) { - CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, hover_regs->module); + CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, hover_regs->module); hover_voff_range = ctrl_voff_range_from_vaddr_range(module, hover_regs->vaddr_range); } ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); From 1b26c3f180cbc3d10de1ef0fb032316e27516eec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 19:11:02 -0700 Subject: [PATCH 709/755] entity_ctx * entity_store -> entity_ctx, entity_ctx_rw_store, thread-local entity_ctx_lookup_accel --- src/ctrl/ctrl_core.c | 167 +++++++++++++++++-------------- src/ctrl/ctrl_core.h | 48 +++++---- src/dbg_engine/dbg_engine_core.c | 16 +-- src/dbg_engine/dbg_engine_core.h | 2 +- src/raddbg/raddbg_core.c | 30 +++--- src/raddbg/raddbg_eval.c | 6 +- src/raddbg/raddbg_views.c | 4 +- src/raddbg/raddbg_widgets.c | 4 +- 8 files changed, 153 insertions(+), 124 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index b4d85938..1cf0ce94 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -846,20 +846,16 @@ ctrl_entity_tree_is_frozen(CTRL_Entity *root) return is_frozen; } -//- rjf: cache creation/destruction +//- rjf: entity ctx r/w store state functions -internal CTRL_EntityStore * -ctrl_entity_store_alloc(void) +internal CTRL_EntityCtxRWStore * +ctrl_entity_ctx_rw_store_alloc(void) { Arena *arena = arena_alloc(); - CTRL_EntityStore *store = push_array(arena, CTRL_EntityStore, 1); + CTRL_EntityCtxRWStore *store = push_array(arena, CTRL_EntityCtxRWStore, 1); store->arena = arena; store->ctx.hash_slots_count = 1024; store->ctx.hash_slots = push_array(arena, CTRL_EntityHashSlot, store->ctx.hash_slots_count); - for EachEnumVal(CTRL_EntityKind, k) - { - store->entity_kind_arrays_arenas[k] = arena_alloc(); - } CTRL_Entity *root = store->ctx.root = ctrl_entity_alloc(store, &ctrl_entity_nil, CTRL_EntityKind_Root, Arch_Null, ctrl_handle_zero(), 0); CTRL_Entity *local_machine = ctrl_entity_alloc(store, root, CTRL_EntityKind_Machine, arch_from_context(), ctrl_handle_make(CTRL_MachineID_Local, dmn_handle_zero()), 0); Temp scratch = scratch_begin(0, 0); @@ -870,9 +866,9 @@ ctrl_entity_store_alloc(void) } internal void -ctrl_entity_store_release(CTRL_EntityStore *cache) +ctrl_entity_ctx_rw_store_release(CTRL_EntityCtxRWStore *store) { - arena_release(cache->arena); + arena_release(store->arena); } //- rjf: string allocation/deletion @@ -896,7 +892,7 @@ ctrl_name_bucket_num_from_string_size(U64 size) } internal String8 -ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string) +ctrl_entity_string_alloc(CTRL_EntityCtxRWStore *store, String8 string) { //- rjf: allocate node CTRL_EntityStringChunkNode *node = 0; @@ -962,7 +958,7 @@ ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string) } internal void -ctrl_entity_string_release(CTRL_EntityStore *store, String8 string) +ctrl_entity_string_release(CTRL_EntityCtxRWStore *store, String8 string) { U64 bucket_num = ctrl_name_bucket_num_from_string_size(string.size); if(1 <= bucket_num && bucket_num <= ArrayCount(rd_name_bucket_chunk_sizes)) @@ -977,7 +973,7 @@ ctrl_entity_string_release(CTRL_EntityStore *store, String8 string) //- rjf: entity construction/deletion internal CTRL_Entity * -ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id) +ctrl_entity_alloc(CTRL_EntityCtxRWStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id) { CTRL_Entity *entity = &ctrl_entity_nil; { @@ -1041,14 +1037,14 @@ ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind } // rjf: bump counters - store->entity_kind_counts[kind] += 1; - store->entity_kind_alloc_gens[kind] += 1; + store->ctx.entity_kind_counts[kind] += 1; + store->ctx.entity_kind_alloc_gens[kind] += 1; } return entity; } internal void -ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity) +ctrl_entity_release(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity) { // rjf: unhook root if(entity->parent != &ctrl_entity_nil) @@ -1099,8 +1095,8 @@ ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity) } // rjf: dec counter - store->entity_kind_counts[t->e->kind] -= 1; - store->entity_kind_alloc_gens[t->e->kind] += 1; + store->ctx.entity_kind_counts[t->e->kind] -= 1; + store->ctx.entity_kind_alloc_gens[t->e->kind] += 1; } scratch_end(scratch); } @@ -1109,7 +1105,7 @@ ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity) //- rjf: entity equipment internal void -ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string) +ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity, String8 string) { if(entity->string.size != 0) { @@ -1118,37 +1114,54 @@ ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 s entity->string = ctrl_entity_string_alloc(store, string); } -//- rjf: entity store lookups +//- rjf: accelerated entity context lookups + +internal CTRL_EntityCtxLookupAccel * +ctrl_thread_entity_ctx_lookup_accel(void) +{ + if(ctrl_entity_ctx_lookup_accel == 0) + { + Arena *arena = arena_alloc(); + ctrl_entity_ctx_lookup_accel = push_array(arena, CTRL_EntityCtxLookupAccel, 1); + ctrl_entity_ctx_lookup_accel->arena = arena; + for EachEnumVal(CTRL_EntityKind, k) + { + ctrl_entity_ctx_lookup_accel->entity_kind_arrays_arenas[k] = arena_alloc(); + } + } + return ctrl_entity_ctx_lookup_accel; +} internal CTRL_EntityArray -ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind) +ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind) { - if(store->entity_kind_arrays_gens[kind] != store->entity_kind_alloc_gens[kind]) + CTRL_EntityCtxLookupAccel *accel = ctrl_thread_entity_ctx_lookup_accel(); + if(accel->entity_kind_arrays_gens[kind] != ctx->entity_kind_alloc_gens[kind]) { Temp scratch = scratch_begin(0, 0); CTRL_EntityList entities = {0}; - for(CTRL_Entity *e = store->ctx.root; + for(CTRL_Entity *e = ctx->root; e != &ctrl_entity_nil; - e = ctrl_entity_rec_depth_first_pre(e, store->ctx.root).next) + e = ctrl_entity_rec_depth_first_pre(e, ctx->root).next) { if(e->kind == kind) { ctrl_entity_list_push(scratch.arena, &entities, e); } } - store->entity_kind_arrays_gens[kind] = store->entity_kind_alloc_gens[kind]; - arena_clear(store->entity_kind_arrays_arenas[kind]); - store->entity_kind_arrays[kind] = ctrl_entity_array_from_list(store->entity_kind_arrays_arenas[kind], &entities); + accel->entity_kind_arrays_gens[kind] = ctx->entity_kind_alloc_gens[kind]; + arena_clear(accel->entity_kind_arrays_arenas[kind]); + accel->entity_kind_arrays[kind] = ctrl_entity_array_from_list(accel->entity_kind_arrays_arenas[kind], &entities); scratch_end(scratch); } - return store->entity_kind_arrays[kind]; + return accel->entity_kind_arrays[kind]; } internal CTRL_EntityList -ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key) +ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key *dbgi_key) { CTRL_EntityList list = {0}; - CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Module); + CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Module); for EachIndex(idx, all_modules.count) { CTRL_Entity *module = all_modules.v[idx]; @@ -1162,10 +1175,10 @@ ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_k } internal CTRL_Entity * -ctrl_thread_from_id(CTRL_EntityStore *store, U64 id) +ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id) { CTRL_Entity *thread = &ctrl_entity_nil; - CTRL_EntityArray threads = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { if(threads.v[idx]->id == id) @@ -1203,7 +1216,7 @@ ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_Entity *subtree_root, U64 //- rjf: applying events to entity caches internal void -ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) +ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list) { //- rjf: scan events & construct entities for(CTRL_EventNode *n = list->first; n != 0; n = n->next) @@ -1245,7 +1258,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) { ctrl_entity_equip_string(store, thread, str8_lit("main_thread")); } - CTRL_EntityArray pending_thread_names = ctrl_entity_array_from_kind(store, CTRL_EntityKind_PendingThreadName); + CTRL_EntityArray pending_thread_names = ctrl_entity_array_from_kind(&store->ctx, CTRL_EntityKind_PendingThreadName); for EachIndex(idx, pending_thread_names.count) { CTRL_Entity *entity = pending_thread_names.v[idx]; @@ -1256,7 +1269,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) break; } } - CTRL_EntityArray pending_thread_colors = ctrl_entity_array_from_kind(store, CTRL_EntityKind_PendingThreadColor); + CTRL_EntityArray pending_thread_colors = ctrl_entity_array_from_kind(&store->ctx, CTRL_EntityKind_PendingThreadColor); for EachIndex(idx, pending_thread_colors.count) { CTRL_Entity *entity = pending_thread_colors.v[idx]; @@ -1285,7 +1298,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) } else { - thread = ctrl_thread_from_id(store, event->entity_id); + thread = ctrl_thread_from_id(&store->ctx, event->entity_id); } if(thread != &ctrl_entity_nil) { @@ -1307,7 +1320,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) } else { - thread = ctrl_thread_from_id(store, event->entity_id); + thread = ctrl_thread_from_id(&store->ctx, event->entity_id); } if(thread != &ctrl_entity_nil) { @@ -1471,7 +1484,7 @@ ctrl_init(void) scratch_end(scratch); } ctrl_state->ctrl_thread_entity_ctx_rw_mutex = os_rw_mutex_alloc(); - ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); + ctrl_state->ctrl_thread_entity_store = ctrl_entity_ctx_rw_store_alloc(); ctrl_state->ctrl_thread_eval_cache = e_cache_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); ctrl_state->user_entry_point_arena = arena_alloc(); @@ -3404,7 +3417,10 @@ ctrl_c2u_push_events(CTRL_EventList *events) { if(events->count != 0) ProfScope("ctrl_c2u_push_events") { - ctrl_entity_store_apply_events(ctrl_state->ctrl_thread_entity_store, events); + OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + { + ctrl_entity_store_apply_events(ctrl_state->ctrl_thread_entity_store, events); + } for(CTRL_EventNode *n = events->first; n != 0; n = n ->next) { Temp scratch = scratch_begin(0, 0); @@ -3525,12 +3541,14 @@ ctrl_thread__entry_point(void *p) }break; case CTRL_MsgKind_SetModuleDebugInfoPath: { + CTRL_EntityCtxRWStore *entity_store = ctrl_state->ctrl_thread_entity_store; + CTRL_EntityCtx *entity_ctx = &entity_store->ctx; String8 path = msg->path; - CTRL_Entity *module = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, msg->entity); + CTRL_Entity *module = ctrl_entity_from_handle(entity_ctx, msg->entity); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); DI_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; di_close(&old_dbgi_key); - ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path); + OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) ctrl_entity_equip_string(entity_store, debug_info_path, path); U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified; debug_info_path->timestamp = new_dbgi_timestamp; DI_Key new_dbgi_key = {debug_info_path->string, new_dbgi_timestamp}; @@ -3588,7 +3606,8 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope * if(user_bps->first == 0) { return; } Temp scratch = scratch_begin(&arena, 1); DI_Scope *di_scope = eval_scope->di_scope; - CTRL_Entity *module_entity = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, module); + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; + CTRL_Entity *module_entity = ctrl_entity_from_handle(entity_ctx, module); CTRL_Entity *debug_info_path_entity = ctrl_entity_child_from_kind(module_entity, CTRL_EntityKind_DebugInfoPath); DI_Key dbgi_key = {debug_info_path_entity->string, debug_info_path_entity->timestamp}; RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64); @@ -4086,6 +4105,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, ProfBeginFunction(); DMN_Event *event = push_array(arena, DMN_Event, 1); Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; //- rjf: loop -> try to get event, run, repeat U64 spoof_old_ip_value = 0; @@ -4158,7 +4178,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, (spoof == 0 || ev->instruction_pointer != spoof->new_ip_value)) { DI_Scope *di_scope = di_scope_open(); - CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->process)); + CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->process)); CTRL_Entity *module = &ctrl_entity_nil; for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) { @@ -4249,7 +4269,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, U64 size_of_spoof = 0; if(do_spoof) ProfScope("prep spoof") { - CTRL_Entity *spoof_process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->process)); + CTRL_Entity *spoof_process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->process)); Arch arch = spoof_process->arch; size_of_spoof = bit_size_from_arch(arch)/8; dmn_process_read(spoof_process->handle.dmn_handle, r1u64(spoof->vaddr, spoof->vaddr+size_of_spoof), &spoof_old_ip_value); @@ -4315,7 +4335,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, // simply been sent other debug events first if(spoof != 0) { - CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->thread)); + CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, spoof->thread)); Arch arch = thread->arch; void *regs_block = push_array(scratch.arena, U8, regs_block_size_from_arch(arch)); dmn_thread_read_reg_block(spoof->thread, regs_block); @@ -4407,7 +4427,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); CTRL_Handle module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); - CTRL_Entity *module_ent = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, module_handle); + CTRL_Entity *module_ent = ctrl_entity_from_handle(entity_ctx, module_handle); CTRL_Entity *process_ent = ctrl_process_from_entity(module_ent); String8 module_path = event->string; ctrl_thread__module_close(process_ent->handle, module_handle, module_ent->vaddr_range); @@ -4500,16 +4520,16 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, // dealing with insane-town projects) // if(event->kind == DMN_EventKind_LoadModule && - (ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module] > 256 || - ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module] == 1)) + (entity_ctx->entity_kind_counts[CTRL_EntityKind_Module] > 256 || + entity_ctx->entity_kind_counts[CTRL_EntityKind_Module] == 1)) { U64 endt_us = os_now_microseconds() + 1000000; //- rjf: unpack event CTRL_Handle process_handle = ctrl_handle_make(CTRL_MachineID_Local, event->process); CTRL_Handle loaded_module_handle = ctrl_handle_make(CTRL_MachineID_Local, event->module); - CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, process_handle); - CTRL_Entity *loaded_module = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, loaded_module_handle); + CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, process_handle); + CTRL_Entity *loaded_module = ctrl_entity_from_handle(entity_ctx, loaded_module_handle); //- rjf: for each module, use its full path as the start to a new limited recursive // directory search. cache each directory once traversed in the dbg_dir tree. if any @@ -4726,8 +4746,9 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case CTRL_EntityKind_Thread: { Temp scratch = scratch_begin(0, 0); + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; U64 regs_size = regs_block_size_from_arch(entity->arch); - void *regs = ctrl_reg_block_from_thread(scratch.arena, &ctrl_state->ctrl_thread_entity_store->ctx, entity->handle); + void *regs = ctrl_reg_block_from_thread(scratch.arena, entity_ctx, entity->handle); Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 read_range = intersect_1u64(legal_range, range); U64 read_size = dim_1u64(read_range); @@ -4752,6 +4773,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) internal CTRL_EvalScope * ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) { + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; CTRL_EvalScope *scope = push_array(arena, CTRL_EvalScope, 1); scope->di_scope = di_scope_open(); @@ -4767,14 +4789,14 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ////////////////////////////// //- rjf: gather evaluation modules // - U64 eval_modules_count = Max(1, ctrl_state->ctrl_thread_entity_store->entity_kind_counts[CTRL_EntityKind_Module]); + U64 eval_modules_count = Max(1, entity_ctx->entity_kind_counts[CTRL_EntityKind_Module]); E_Module *eval_modules = push_array(arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; eval_modules_primary->rdi = &rdi_parsed_nil; eval_modules_primary->vaddr_range = r1u64(0, max_U64); { U64 eval_module_idx = 0; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; + for(CTRL_Entity *machine = entity_ctx->root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5065,9 +5087,10 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); U32 exit_code = msg->exit_code; + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; //- rjf: gather all currently existing processes - CTRL_EntityArray initial_processes = ctrl_entity_array_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray initial_processes = ctrl_entity_array_from_kind(entity_ctx, CTRL_EntityKind_Process); typedef struct Task Task; struct Task { @@ -5112,7 +5135,7 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) default:{}break; case DMN_EventKind_CreateProcess: { - CTRL_Entity *new_process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *new_process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); Task *t = push_array(scratch.arena, Task, 1); t->process = new_process; DLLPushBack(first_task, last_task, t); @@ -5122,7 +5145,7 @@ ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } // rjf: end if all processes are gone - CTRL_EntityArray processes = ctrl_entity_array_from_kind(ctrl_state->ctrl_thread_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(entity_ctx, CTRL_EntityKind_Process); if(processes.count == 0) { done = 1; @@ -5201,9 +5224,10 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) Temp scratch = scratch_begin(0, 0); DMN_Event *stop_event = 0; CTRL_EventCause stop_cause = CTRL_EventCause_Null; + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; CTRL_Handle target_thread = msg->entity; CTRL_Handle target_process = msg->parent; - CTRL_Entity *target_process_entity = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, target_process); + CTRL_Entity *target_process_entity = ctrl_entity_from_handle(entity_ctx, target_process); U64 spoof_ip_vaddr = 911; log_infof("ctrl_thread__run:\n{\n"); @@ -5212,9 +5236,9 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) // DMN_TrapChunkList user_traps = {0}; { - CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, target_thread); + CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, target_thread); CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; + for(CTRL_Entity *machine = entity_ctx->root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5527,7 +5551,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) }break; case DMN_EventKind_LoadModule: { - CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); CTRL_EvalScope *eval_scope = ctrl_thread__eval_scope_begin(scratch.arena, thread); { DMN_TrapChunkList new_traps = {0}; @@ -5552,7 +5576,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { CTRL_Entity *bp = &ctrl_entity_nil; { - CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next) { if(child->kind == CTRL_EntityKind_Breakpoint && @@ -5584,7 +5608,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) DI_Scope *di_scope = di_scope_open(); //- rjf: unpack process/module info - CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); CTRL_Entity *module = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Module); U64 module_base_vaddr = module->vaddr_range.min; CTRL_Entity *dbg_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); @@ -5808,8 +5832,8 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ////////////////////////// //- rjf: unpack info about thread attached to event // - CTRL_Entity *thread = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); - CTRL_Entity *process = ctrl_entity_from_handle(&ctrl_state->ctrl_thread_entity_store->ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); + CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->thread)); + CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process)); Arch arch = thread->arch; U64 thread_rip_vaddr = dmn_rip_from_thread(event->thread); CTRL_Entity *module = &ctrl_entity_nil; @@ -6631,23 +6655,20 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; //- rjf: do task -#if 0 - OS_MutexScopeR(ctrl_state->call_stack_builder_entity_store_rw_mutex) + OS_MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { Temp scratch = scratch_begin(0, 0); - CTRL_EntityStore *store = ctrl_state->call_stack_builder_entity_store; + CTRL_EntityCtx *ctx = &ctrl_state->ctrl_thread_entity_store->ctx; + CTRL_Entity *thread = ctrl_entity_from_handle(ctx, thread_handle); + CTRL_Entity *process = ctrl_process_from_entity(thread); //- rjf: compute unwind to find list of all concrete frames, then // call stack, to determine list of all concrete & inline frames - CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, store, thread_handle, os_now_microseconds()+1000000); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena); - - //- rjf: use debug info to to list of all (concrete & inline) frames - + CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, ctx, thread_handle, os_now_microseconds()+1000000); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &unwind); scratch_end(scratch); } -#endif return 0; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 1d455584..d7249831 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -182,23 +182,29 @@ typedef struct CTRL_EntityCtx CTRL_EntityCtx; struct CTRL_EntityCtx { CTRL_Entity *root; - CTRL_EntityHashSlot *hash_slots; U64 hash_slots_count; + CTRL_EntityHashSlot *hash_slots; + U64 entity_kind_counts[CTRL_EntityKind_COUNT]; + U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT]; }; -typedef struct CTRL_EntityStore CTRL_EntityStore; -struct CTRL_EntityStore +typedef struct CTRL_EntityCtxRWStore CTRL_EntityCtxRWStore; +struct CTRL_EntityCtxRWStore { Arena *arena; CTRL_EntityCtx ctx; CTRL_Entity *free; CTRL_EntityHashNode *hash_node_free; CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)]; - U64 entity_kind_counts[CTRL_EntityKind_COUNT]; +}; + +typedef struct CTRL_EntityCtxLookupAccel CTRL_EntityCtxLookupAccel; +struct CTRL_EntityCtxLookupAccel +{ + Arena *arena; Arena *entity_kind_arrays_arenas[CTRL_EntityKind_COUNT]; - U64 entity_kind_arrays_gens[CTRL_EntityKind_COUNT]; - U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT]; CTRL_EntityArray entity_kind_arrays[CTRL_EntityKind_COUNT]; + U64 entity_kind_arrays_gens[CTRL_EntityKind_COUNT]; }; //////////////////////////////// @@ -751,7 +757,7 @@ struct CTRL_State OS_Handle ctrl_thread; Log *ctrl_thread_log; OS_Handle ctrl_thread_entity_ctx_rw_mutex; - CTRL_EntityStore *ctrl_thread_entity_store; + CTRL_EntityCtxRWStore *ctrl_thread_entity_store; E_Cache *ctrl_thread_eval_cache; Arena *dmn_event_arena; DMN_EventNode *first_dmn_event_node; @@ -793,6 +799,7 @@ read_only global CTRL_Entity ctrl_entity_nil = &ctrl_entity_nil, &ctrl_entity_nil, }; +thread_static CTRL_EntityCtxLookupAccel *ctrl_entity_ctx_lookup_accel = 0; //////////////////////////////// //~ rjf: Logging Markup @@ -892,29 +899,30 @@ internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_En #define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first)) #define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last)) -//- rjf: cache creation/destruction -internal CTRL_EntityStore *ctrl_entity_store_alloc(void); -internal void ctrl_entity_store_release(CTRL_EntityStore *store); +//- rjf: entity ctx r/w store state functions +internal CTRL_EntityCtxRWStore *ctrl_entity_ctx_rw_store_alloc(void); +internal void ctrl_entity_ctx_rw_store_release(CTRL_EntityCtxRWStore *store); //- rjf: string allocation/deletion internal U64 ctrl_name_bucket_num_from_string_size(U64 size); -internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string); -internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string); +internal String8 ctrl_entity_string_alloc(CTRL_EntityCtxRWStore *store, String8 string); +internal void ctrl_entity_string_release(CTRL_EntityCtxRWStore *store, String8 string); //- rjf: entity construction/deletion -internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id); -internal void ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity); +internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityCtxRWStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id); +internal void ctrl_entity_release(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity); //- rjf: entity equipment -internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string); +internal void ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity, String8 string); -//- rjf: entity store lookups -internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind); -internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); -internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityStore *store, U64 id); +//- rjf: accelerated entity context lookups +internal CTRL_EntityCtxLookupAccel *ctrl_thread_entity_ctx_lookup_accel(void); +internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind); +internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key *dbgi_key); +internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id); //- rjf: applying events to entity caches -internal void ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list); +internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list); //////////////////////////////// //~ rjf: Main Layer Initialization diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index e3dbf114..3a9e9bb8 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1187,7 +1187,7 @@ internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena) { DI_KeyList dbgis = {0}; - CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + CTRL_EntityArray modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module); for EachIndex(idx, modules.count) { CTRL_Entity *module = modules.v[idx]; @@ -1484,7 +1484,7 @@ d_init(void) d_state->cmds_arena = arena_alloc(); d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key")); hs_submit_data(d_state->output_log_key, 0, str8_zero()); - d_state->ctrl_entity_store = ctrl_entity_store_alloc(); + d_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc(); d_state->ctrl_stop_arena = arena_alloc(); d_state->ctrl_msg_arena = arena_alloc(); @@ -1614,7 +1614,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case CTRL_EventKind_NewProc: { // rjf: the first process? -> clear session output - CTRL_EntityArray existing_processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray existing_processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(existing_processes.count == 1) { MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; @@ -1697,7 +1697,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: build data strings of all param data String8List strings = {0}; { - CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { CTRL_Entity *thread = threads.v[idx]; @@ -1908,7 +1908,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_Continue: { B32 good_to_run = 0; - CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread); if(threads.count > 0) { for EachIndex(idx, threads.count) @@ -2064,7 +2064,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Run: { - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count != 0) { d_cmd(D_CmdKind_Continue); @@ -2076,7 +2076,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P }break; case D_CmdKind_Restart: { - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count != 0) { d_cmd(D_CmdKind_KillAll); @@ -2086,7 +2086,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepInto: case D_CmdKind_StepOver: { - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count != 0) { D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 536f852b..4e7b2f04 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -343,7 +343,7 @@ struct D_State CTRL_MsgList ctrl_msgs; // rjf: ctrl -> user reading state - CTRL_EntityStore *ctrl_entity_store; + CTRL_EntityCtxRWStore *ctrl_entity_store; Arena *ctrl_stop_arena; CTRL_Event ctrl_last_stop_event; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f2330d73..04fb7fe3 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2710,7 +2710,7 @@ rd_view_ui(Rng2F32 rect) UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) { RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); //- rjf: icon & info UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") @@ -6668,7 +6668,7 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_AddTarget, .file_path = n->string); } - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count != 0) { rd_cmd(RD_CmdKind_KillAll); @@ -6687,7 +6687,7 @@ rd_window_frame(void) { rd_cmd(RD_CmdKind_AddTarget, .file_path = n->string); } - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count != 0) { rd_cmd(RD_CmdKind_KillAll); @@ -7839,7 +7839,7 @@ rd_window_frame(void) { Temp scratch = scratch_begin(0, 0); RD_CfgList targets = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("target")); - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); B32 can_send_signal = !d_ctrl_targets_running(); typedef struct CenterButtonTask CenterButtonTask; struct CenterButtonTask @@ -11617,7 +11617,7 @@ rd_frame(void) CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); - CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module); U64 eval_modules_count = Max(1, all_modules.count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules_primary = &eval_modules[0]; @@ -11977,7 +11977,7 @@ rd_frame(void) { String8 name = evallable_ctrl_names[idx]; CTRL_EntityKind kind = ctrl_entity_kind_from_string(name); - CTRL_EntityArray array = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, kind); + CTRL_EntityArray array = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, kind); E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); for EachIndex(idx, array.count) { @@ -12303,7 +12303,7 @@ rd_frame(void) //- rjf: gather config from loaded modules // RD_CfgList immediate_type_views = {0}; - CTRL_EntityArray modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + CTRL_EntityArray modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module); for EachIndex(idx, modules.count) { CTRL_Entity *module = modules.v[idx]; @@ -12475,7 +12475,7 @@ rd_frame(void) case RD_CmdKind_Restart: { // rjf: reset hit counts - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count == 0 || kind == RD_CmdKind_Restart) { RD_CfgList bps = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); @@ -12631,7 +12631,7 @@ rd_frame(void) { // rjf: if control processes are live, but this is not force-confirmed, then // get confirmation from user - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation")); if(processes.count != 0 && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key)) { @@ -14008,7 +14008,7 @@ rd_frame(void) U64 vaddr = 0; for(D_LineNode *n = rd_regs()->lines.first; n != 0; n = n->next) { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); + CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, &d_state->ctrl_entity_store->ctx, &n->v.dbgi_key); CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { @@ -14466,7 +14466,7 @@ rd_frame(void) U64 vaddr = 0; if(voff_dbgi_key.path.size != 0) { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &voff_dbgi_key); + CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, &d_state->ctrl_entity_store->ctx, &voff_dbgi_key); CTRL_Entity *module = ctrl_entity_list_first(&modules); process = ctrl_entity_ancestor_from_kind(module, CTRL_EntityKind_Process); if(process != &ctrl_entity_nil) @@ -14564,7 +14564,7 @@ rd_frame(void) D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, point.line); for(D_LineNode *n = lines.first; n != 0; n = n->next) { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); + CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, &d_state->ctrl_entity_store->ctx, &n->v.dbgi_key); CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min); break; @@ -15507,7 +15507,7 @@ rd_frame(void) D_LineList *lines = &rd_regs()->lines; for(D_LineNode *n = lines->first; n != 0; n = n->next) { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); + CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, &d_state->ctrl_entity_store->ctx, &n->v.dbgi_key); CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { @@ -16372,7 +16372,7 @@ rd_frame(void) case D_EventKind_ProcessEnd: if(rd_state->quit_after_success) { - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(evt->code == 0 && processes.count == 0) { rd_cmd(RD_CmdKind_Exit); @@ -16409,7 +16409,7 @@ rd_frame(void) // rjf: no stop-causing thread, but don't have selected thread? -> snap to first available thread if(need_refocus && thread == &ctrl_entity_nil && selected_thread == &ctrl_entity_nil) { - CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread); CTRL_Entity *first_available_thread = ctrl_entity_array_first(&threads); rd_cmd(RD_CmdKind_SelectThread, .thread = first_available_thread->handle); } diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 79094843..f1d37d5c 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -1323,7 +1323,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) } else { - machines = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + machines = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Machine); } //- rjf: gather system processes from this machine @@ -1428,7 +1428,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities) CTRL_EntityKind kind = ctrl_entity_kind_from_string(rd_singular_from_code_name_plural(type->name)); E_Value rhs_value = e_value_from_expr(expr->first->next); U64 rhs_idx = rhs_value.u64; - CTRL_EntityArray entities = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, kind); + CTRL_EntityArray entities = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, kind); if(0 <= rhs_idx && rhs_idx < entities.count) { entity = entities.v[rhs_idx]; @@ -1470,7 +1470,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities) CTRL_EntityArray array = {0}; if(scoping_entity == &ctrl_entity_nil) { - array = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, entity_kind); + array = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, entity_kind); } else { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 27fb0679..72413ee0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -261,7 +261,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(!dasm_lines) ProfScope("find live threads mapping to this file") { CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); - CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { CTRL_Entity *thread = threads.v[idx]; @@ -337,7 +337,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla if(dasm_lines) ProfScope("find live threads mapping to this disassembly") { CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); - CTRL_EntityArray threads = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread); for EachIndex(idx, threads.count) { CTRL_Entity *thread = threads.v[idx]; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 57218fb7..689e215c 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -483,7 +483,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e if(entity->kind == CTRL_EntityKind_Thread || entity->kind == CTRL_EntityKind_Module) { - CTRL_EntityArray processes = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process); if(processes.count > 1) { CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); @@ -2325,7 +2325,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe D_LineList *lines = ¶ms->line_infos[line_idx]; for(D_LineNode *n = lines->first; n != 0; n = n->next) { - CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key); + CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, &d_state->ctrl_entity_store->ctx, &n->v.dbgi_key); CTRL_Entity *module = ctrl_module_from_thread_candidates(&d_state->ctrl_entity_store->ctx, thread, &modules); if(module != &ctrl_entity_nil) { From 981dd2e02c830553f5b5bc474486daec5b80edc7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 19:16:06 -0700 Subject: [PATCH 710/755] tighten up usage of ctrl entity ctx vs. r/w ctx store vs. accel --- src/ctrl/ctrl_core.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1cf0ce94..21cf9e81 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3541,14 +3541,13 @@ ctrl_thread__entry_point(void *p) }break; case CTRL_MsgKind_SetModuleDebugInfoPath: { - CTRL_EntityCtxRWStore *entity_store = ctrl_state->ctrl_thread_entity_store; - CTRL_EntityCtx *entity_ctx = &entity_store->ctx; + CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; String8 path = msg->path; CTRL_Entity *module = ctrl_entity_from_handle(entity_ctx, msg->entity); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); DI_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; di_close(&old_dbgi_key); - OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) ctrl_entity_equip_string(entity_store, debug_info_path, path); + OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path); U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified; debug_info_path->timestamp = new_dbgi_timestamp; DI_Key new_dbgi_key = {debug_info_path->string, new_dbgi_timestamp}; @@ -4852,7 +4851,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->primary_module = eval_modules_primary; //- rjf: fill space hooks - ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; ctx->space_read = ctrl_eval_space_read; } e_select_base_ctx(&scope->base_ctx); @@ -4878,7 +4876,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) // { E_InterpretCtx *ctx = &scope->interpret_ctx; - ctx->space_rw_user_data = ctrl_state->ctrl_thread_entity_store; ctx->space_read = ctrl_eval_space_read; ctx->primary_space = eval_modules_primary->space; ctx->reg_arch = eval_modules_primary->arch; @@ -4964,11 +4961,15 @@ ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) os_file_close(stdin_handle); //- rjf: record (id -> entry points), so that we know custom entry points for this PID - for(String8Node *n = msg->entry_points.first; n != 0; n = n->next) + CTRL_EntityCtxRWStore *entity_ctx_rw_store = ctrl_state->ctrl_thread_entity_store; + OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { - String8 string = n->string; - CTRL_Entity *entry = ctrl_entity_alloc(ctrl_state->ctrl_thread_entity_store, ctrl_state->ctrl_thread_entity_store->ctx.root, CTRL_EntityKind_EntryPoint, Arch_Null, ctrl_handle_zero(), (U64)id); - ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, entry, string); + for(String8Node *n = msg->entry_points.first; n != 0; n = n->next) + { + String8 string = n->string; + CTRL_Entity *entry = ctrl_entity_alloc(entity_ctx_rw_store, entity_ctx_rw_store->ctx.root, CTRL_EntityKind_EntryPoint, Arch_Null, ctrl_handle_zero(), (U64)id); + ctrl_entity_equip_string(entity_ctx_rw_store, entry, string); + } } } @@ -5295,7 +5296,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { // rjf: gather stuck threads DMN_HandleList stuck_threads = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; + for(CTRL_Entity *machine = entity_ctx->root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5400,7 +5401,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: gather frozen threads // CTRL_EntityList frozen_threads = {0}; - for(CTRL_Entity *machine = ctrl_state->ctrl_thread_entity_store->ctx.root->first; + for(CTRL_Entity *machine = entity_ctx->root->first; machine != &ctrl_entity_nil; machine = machine->next) { @@ -5684,7 +5685,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: add traps for PID-correllated entry points if(!entries_found) { - for(CTRL_Entity *e = ctrl_state->ctrl_thread_entity_store->ctx.root->first; e != &ctrl_entity_nil; e = e->next) + for(CTRL_Entity *e = entity_ctx->root->first; e != &ctrl_entity_nil; e = e->next) { if(e->id == process->id) { From a84739e1c4d7121689102bdec6beb794c1ee5986 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 20:15:10 -0700 Subject: [PATCH 711/755] set up async cached call stack building --- src/ctrl/ctrl_core.c | 159 +++++++++++++++++++++++++++++++++++++++++-- src/ctrl/ctrl_core.h | 42 +++++++++++- 2 files changed, 195 insertions(+), 6 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 21cf9e81..baeb2a43 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1403,6 +1403,60 @@ ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *lis } } +//////////////////////////////// +//~ rjf: Cache Accessing Scopes + +internal CTRL_Scope * +ctrl_scope_open(void) +{ + if(ctrl_tctx == 0) + { + Arena *arena = arena_alloc(); + ctrl_tctx = push_array(arena, CTRL_TCTX, 1); + ctrl_tctx->arena = arena; + } + CTRL_Scope *scope = ctrl_tctx->free_scope; + if(scope != 0) + { + SLLStackPop(ctrl_tctx->free_scope); + } + else + { + scope = push_array_no_zero(ctrl_tctx->arena, CTRL_Scope, 1); + } + MemoryZeroStruct(scope); + return scope; +} + +internal void +ctrl_scope_close(CTRL_Scope *scope) +{ + for(CTRL_ScopeCallStackTouch *t = scope->first_call_stack_touch, *next = 0; t != 0; t = next) + { + next = t->next; + ins_atomic_u64_dec_eval(&t->node->scope_touch_count); + SLLStackPush(ctrl_tctx->free_call_stack_touch, t); + } + SLLStackPush(ctrl_tctx->free_scope, scope); +} + +internal void +ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node) +{ + ins_atomic_u64_eval(&node->scope_touch_count); + CTRL_ScopeCallStackTouch *touch = ctrl_tctx->free_call_stack_touch; + if(touch != 0) + { + SLLStackPop(ctrl_tctx->free_call_stack_touch); + } + else + { + touch = push_array(ctrl_tctx->arena, CTRL_ScopeCallStackTouch, 1); + } + SLLQueuePush(scope->first_call_stack_touch, scope->last_call_stack_touch, touch); + touch->node = node; +} + //////////////////////////////// //~ rjf: Main Layer Initialization @@ -1455,6 +1509,7 @@ ctrl_init(void) { ctrl_state->call_stack_cache.stripes[idx].arena = arena_alloc(); ctrl_state->call_stack_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); + ctrl_state->call_stack_cache.stripes[idx].cv = os_condition_variable_alloc(); } ctrl_state->module_image_info_cache.slots_count = 1024; ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count); @@ -3289,12 +3344,73 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U //~ rjf: Call Stack Cache Functions internal CTRL_CallStack -ctrl_call_stack_from_thread(HS_Scope *hs_scope, CTRL_Entity *thread, U64 endt_us) +ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) { CTRL_CallStack call_stack = {0}; { - CTRL_Handle handle = thread->handle; + CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; + //- rjf: unpack thread + CTRL_Handle handle = thread->handle; + U64 hash = ctrl_hash_from_handle(handle); + U64 slot_idx = hash%cache->slots_count; + U64 stripe_idx = slot_idx%cache->stripes_count; + CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; + CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; + + //- rjf: loop: try to grab cached call stack; request; wait + U64 reg_gen = ctrl_reg_gen(); + U64 mem_gen = ctrl_mem_gen(); + OS_MutexScopeW(stripe->rw_mutex) for(;;) + { + //- rjf: try to grab cached + B32 is_good = 0; + B32 is_stale = 0; + B32 is_working = 0; + CTRL_CallStackCacheNode *node = 0; + { + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->thread, handle)) + { + node = n; + is_good = 1; + is_stale = (reg_gen > n->reg_gen || mem_gen > n->mem_gen); + is_working = (n->working_count > 0); + call_stack = n->call_stack; + ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, n); + break; + } + } + } + + //- rjf: create node if needed + if(!is_good) + { + node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); + DLLPushBack(slot->first, slot->last, node); + node->thread = thread->handle; + } + + //- rjf: request if needed + if(!is_working && (!is_good || !is_stale)) + { + if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && + async_push_work(ctrl_call_stack_build_work)) + { + node->working_count += 1; + } + } + + //- rjf: good, or timeout? -> exit + if((is_good && !is_stale) || os_now_microseconds() >= endt_us) + { + break; + } + + //- rjf: time to wait for new result? -> wait + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, endt_us); + } } return call_stack; } @@ -6665,8 +6781,43 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) //- rjf: compute unwind to find list of all concrete frames, then // call stack, to determine list of all concrete & inline frames - CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, ctx, thread_handle, os_now_microseconds()+1000000); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &unwind); + U64 pre_reg_gen = ctrl_reg_gen(); + U64 pre_mem_gen = ctrl_mem_gen(); + Arena *arena = arena_alloc(); + CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, os_now_microseconds()+1000000); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); + U64 post_reg_gen = ctrl_reg_gen(); + U64 post_mem_gen = ctrl_mem_gen(); + + //- rjf: store in cache + Arena *last_arena = arena; + OS_MutexScopeW(stripe->rw_mutex) + { + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->thread, thread_handle)) + { + if(pre_reg_gen == post_reg_gen && + pre_mem_gen == post_mem_gen) + { + last_arena = n->arena; + n->arena = arena; + n->reg_gen = pre_reg_gen; + n->mem_gen = pre_mem_gen; + n->unwind = unwind; + n->call_stack = call_stack; + } + n->working_count -= 1; + break; + } + } + } + + //- rjf: release last results + if(last_arena != 0) + { + arena_release(last_arena); + } scratch_end(scratch); } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index d7249831..49bfa0cb 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -609,10 +609,13 @@ struct CTRL_CallStackCacheNode { CTRL_CallStackCacheNode *next; CTRL_CallStackCacheNode *prev; - Arena *arena; CTRL_Handle thread; + U64 scope_touch_count; + U64 working_count; + Arena *arena; U64 reg_gen; U64 mem_gen; + CTRL_Unwind unwind; CTRL_CallStack call_stack; }; @@ -628,6 +631,7 @@ struct CTRL_CallStackCacheStripe { Arena *arena; OS_Handle rw_mutex; + OS_Handle cv; }; typedef struct CTRL_CallStackCache CTRL_CallStackCache; @@ -710,6 +714,32 @@ struct CTRL_EvalScope E_InterpretCtx interpret_ctx; }; +//////////////////////////////// +//~ rjf: Control Cache Accessing Scopes + +typedef struct CTRL_ScopeCallStackTouch CTRL_ScopeCallStackTouch; +struct CTRL_ScopeCallStackTouch +{ + CTRL_ScopeCallStackTouch *next; + CTRL_CallStackCacheNode *node; +}; + +typedef struct CTRL_Scope CTRL_Scope; +struct CTRL_Scope +{ + CTRL_Scope *next; + CTRL_ScopeCallStackTouch *first_call_stack_touch; + CTRL_ScopeCallStackTouch *last_call_stack_touch; +}; + +typedef struct CTRL_TCTX CTRL_TCTX; +struct CTRL_TCTX +{ + Arena *arena; + CTRL_Scope *free_scope; + CTRL_ScopeCallStackTouch *free_call_stack_touch; +}; + //////////////////////////////// //~ rjf: Wakeup Hook Function Types @@ -799,6 +829,7 @@ read_only global CTRL_Entity ctrl_entity_nil = &ctrl_entity_nil, &ctrl_entity_nil, }; +thread_static CTRL_TCTX *ctrl_tctx = 0; thread_static CTRL_EntityCtxLookupAccel *ctrl_entity_ctx_lookup_accel = 0; //////////////////////////////// @@ -924,6 +955,13 @@ internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id); //- rjf: applying events to entity caches internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list); +//////////////////////////////// +//~ rjf: Cache Accessing Scopes + +internal CTRL_Scope *ctrl_scope_open(void); +internal void ctrl_scope_close(CTRL_Scope *scope); +internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node); + //////////////////////////////// //~ rjf: Main Layer Initialization @@ -999,7 +1037,7 @@ internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth //////////////////////////////// //~ rjf: Call Stack Cache Functions -internal CTRL_CallStack ctrl_call_stack_from_thread(HS_Scope *hs_scope, CTRL_Entity *thread, U64 endt_us); +internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us); //////////////////////////////// //~ rjf: Halting All Attached Processes From e5d6a49055e8407760fed8e11f10a3849fb1fce3 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 21:44:09 -0700 Subject: [PATCH 712/755] first pass at call stack cache, need a lot of clean up before this is working... --- src/ctrl/ctrl_core.c | 98 +++++++++++++++++++++++++++---------- src/ctrl/ctrl_core.h | 17 +++++-- src/raddbg/raddbg_core.c | 42 +++++++++------- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_eval.c | 10 ++-- src/raddbg/raddbg_views.c | 23 +++++---- src/raddbg/raddbg_widgets.c | 10 ++-- 7 files changed, 132 insertions(+), 69 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index baeb2a43..e6a1a193 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1443,7 +1443,7 @@ ctrl_scope_close(CTRL_Scope *scope) internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node) { - ins_atomic_u64_eval(&node->scope_touch_count); + ins_atomic_u64_inc_eval(&node->scope_touch_count); CTRL_ScopeCallStackTouch *touch = ctrl_tctx->free_call_stack_touch; if(touch != 0) { @@ -3299,13 +3299,21 @@ ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *bas } //- rjf: package - result.count = frame_count; - result.frames = push_array(arena, CTRL_CallStackFrame, result.count); + result.frames_count = frame_count; + result.frames = push_array(arena, CTRL_CallStackFrame, result.frames_count); + result.concrete_frames_count = base_unwind->frames.count; + result.concrete_frames = push_array(arena, CTRL_CallStackFrame *, result.concrete_frames_count); { U64 idx = 0; + U64 concrete_idx = 0; for(FrameNode *n = first_frame; n != 0; n = n->next, idx += 1) { MemoryCopyStruct(&result.frames[idx], &n->v); + if(n->v.inline_depth == 0 && concrete_idx < result.concrete_frames_count) + { + result.concrete_frames[concrete_idx] = &result.frames[idx]; + concrete_idx += 1; + } } } } @@ -3320,7 +3328,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U CTRL_CallStackFrame *f = 0; { U64 base_frame_idx = 0; - for(U64 idx = 0; idx < call_stack->count; idx += 1) + for(U64 idx = 0; idx < call_stack->frames_count; idx += 1) { if(call_stack->frames[idx].inline_depth == 0) { @@ -3361,7 +3369,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) //- rjf: loop: try to grab cached call stack; request; wait U64 reg_gen = ctrl_reg_gen(); U64 mem_gen = ctrl_mem_gen(); - OS_MutexScopeW(stripe->rw_mutex) for(;;) + OS_MutexScopeR(stripe->rw_mutex) for(;;) { //- rjf: try to grab cached B32 is_good = 0; @@ -3385,20 +3393,31 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) } //- rjf: create node if needed - if(!is_good) + if(!is_good) OS_MutexScopeRWPromote(stripe->rw_mutex) { - node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); - DLLPushBack(slot->first, slot->last, node); - node->thread = thread->handle; + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->thread, handle)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); + DLLPushBack(slot->first, slot->last, node); + node->thread = thread->handle; + } } //- rjf: request if needed - if(!is_working && (!is_good || !is_stale)) + if(!is_working && (!is_good || is_stale)) { if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && async_push_work(ctrl_call_stack_build_work)) { - node->working_count += 1; + ins_atomic_u64_inc_eval(&node->working_count); } } @@ -3409,7 +3428,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) } //- rjf: time to wait for new result? -> wait - os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, endt_us); + os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); } } return call_stack; @@ -6784,30 +6803,47 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) U64 pre_reg_gen = ctrl_reg_gen(); U64 pre_mem_gen = ctrl_mem_gen(); Arena *arena = arena_alloc(); - CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, os_now_microseconds()+1000000); + CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, 0); CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); U64 post_reg_gen = ctrl_reg_gen(); U64 post_mem_gen = ctrl_mem_gen(); - //- rjf: store in cache + //- rjf: store new results in cache Arena *last_arena = arena; - OS_MutexScopeW(stripe->rw_mutex) + if(pre_reg_gen == post_reg_gen && + pre_mem_gen == post_mem_gen) { - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + for(B32 done = 0; !done;) { - if(ctrl_handle_match(n->thread, thread_handle)) + B32 found = 0; + OS_MutexScopeW(stripe->rw_mutex) { - if(pre_reg_gen == post_reg_gen && - pre_mem_gen == post_mem_gen) + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) { - last_arena = n->arena; - n->arena = arena; - n->reg_gen = pre_reg_gen; - n->mem_gen = pre_mem_gen; - n->unwind = unwind; - n->call_stack = call_stack; + if(ctrl_handle_match(n->thread, thread_handle)) + { + found = 1; + if(n->scope_touch_count == 0) + { + done = 1; + if(unwind.flags == 0 || call_stack.frames_count >= n->call_stack.frames_count) + { + last_arena = n->arena; + n->arena = arena; + n->call_stack = call_stack; + } + if(unwind.flags == 0) + { + n->reg_gen = pre_reg_gen; + n->mem_gen = pre_mem_gen; + } + } + break; + } } - n->working_count -= 1; + } + if(!found) + { break; } } @@ -6819,6 +6855,16 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) arena_release(last_arena); } + //- rjf: mark work as done + OS_MutexScopeW(stripe->rw_mutex) for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->thread, thread_handle)) + { + ins_atomic_u64_dec_eval(&n->working_count); + break; + } + } + scratch_end(scratch); } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 49bfa0cb..50196a58 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -266,7 +266,9 @@ typedef struct CTRL_CallStack CTRL_CallStack; struct CTRL_CallStack { CTRL_CallStackFrame *frames; - U64 count; + U64 frames_count; + CTRL_CallStackFrame **concrete_frames; + U64 concrete_frames_count; }; //////////////////////////////// @@ -609,13 +611,18 @@ struct CTRL_CallStackCacheNode { CTRL_CallStackCacheNode *next; CTRL_CallStackCacheNode *prev; + + // rjf: key CTRL_Handle thread; - U64 scope_touch_count; - U64 working_count; - Arena *arena; U64 reg_gen; U64 mem_gen; - CTRL_Unwind unwind; + + // rjf: refcounts + U64 scope_touch_count; + U64 working_count; + + // rjf: value + Arena *arena; CTRL_CallStack call_stack; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 04fb7fe3..d0f0527f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1815,11 +1815,12 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) }break; case CTRL_EntityKind_Thread: { - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - U64 frame_idx = e_interpret_ctx->reg_unwind_count; - if(frame_idx < unwind.frames.count) + CTRL_Scope *ctrl_scope = ctrl_scope_open(); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; + if(concrete_frame_idx < call_stack.concrete_frames_count) { - CTRL_UnwindFrame *f = &unwind.frames.v[frame_idx]; + CTRL_CallStackFrame *f = call_stack.concrete_frames[concrete_frame_idx]; U64 regs_size = regs_block_size_from_arch(e_interpret_ctx->reg_arch); Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 read_range = intersect_1u64(legal_range, range); @@ -1827,6 +1828,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size); result = (read_size == dim_1u64(range)); } + ctrl_scope_close(ctrl_scope); }break; } }break; @@ -6393,12 +6395,12 @@ rd_window_frame(void) // rjf: unwind if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) { + CTRL_Scope *ctrl_scope = ctrl_scope_open(); Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); - if(call_stack.count != 0) + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, 0); + if(call_stack.frames_count != 0) { ui_spacer(ui_em(1.5f, 1.f)); } @@ -6414,6 +6416,7 @@ rd_window_frame(void) String8 rip_value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, rip_eval); rd_code_label(1, 0, code_color, rip_value_string); } + ctrl_scope_close(ctrl_scope); } }break; @@ -11238,10 +11241,12 @@ rd_frame(void) } ////////////////////////////// - //- rjf: open frame debug info scope + //- rjf: open frame scopes // + if(rd_state->frame_depth == 0) { rd_state->frame_di_scope = di_scope_open(); + rd_state->frame_ctrl_scope = ctrl_scope_open(); } ////////////////////////////// @@ -11283,7 +11288,7 @@ rd_frame(void) U64 candidate_frame_time_us = 1000000/(U64)candidate; S64 frame_time_us_diff = (S64)frame_time_history_avg_us - (S64)candidate_frame_time_us; if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff && - frame_time_history_avg_us < candidate_frame_time_us + 1000) + frame_time_history_avg_us < candidate_frame_time_us + candidate_frame_time_us/4) { best_target_hz = candidate; best_target_hz_frame_time_us_diff = frame_time_us_diff; @@ -11613,7 +11618,6 @@ rd_frame(void) Arch arch = thread->arch; U64 unwind_count = rd_regs()->unwind_count; U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle); @@ -15634,10 +15638,9 @@ rd_frame(void) }break; case RD_CmdKind_SelectUnwind: { + CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); if(frame == 0) { @@ -15649,14 +15652,14 @@ rd_frame(void) rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; } rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth); + ctrl_scope_close(ctrl_scope); }break; case RD_CmdKind_UpOneFrame: case RD_CmdKind_DownOneFrame: { + CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *next_frame = current_frame; if(current_frame != 0) switch(kind) @@ -15668,7 +15671,7 @@ rd_frame(void) next_frame = current_frame-1; }break; case RD_CmdKind_DownOneFrame: - if(current_frame+1 < call_stack.frames + call_stack.count) + if(current_frame+1 < call_stack.frames + call_stack.frames_count) { next_frame = current_frame+1; }break; @@ -15680,6 +15683,7 @@ rd_frame(void) .unwind_count = next_frame->unwind_count, .inline_depth = next_frame->inline_depth); } + ctrl_scope_close(ctrl_scope); }break; //- rjf: meta controls @@ -16700,10 +16704,12 @@ rd_frame(void) } ////////////////////////////// - //- rjf: close frame debug info scope + //- rjf: close frame scopes // + if(rd_state->frame_depth == 0) { di_scope_close(rd_state->frame_di_scope); + ctrl_scope_close(rd_state->frame_ctrl_scope); } ////////////////////////////// diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 790b9904..3e4335c6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -599,6 +599,7 @@ struct RD_State // rjf: frame parameters F32 frame_dt; DI_Scope *frame_di_scope; + CTRL_Scope *frame_ctrl_scope; // rjf: dbgi match store DI_MatchStore *match_store; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index f1d37d5c..a329257e 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -955,11 +955,9 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); if(entity->kind == CTRL_EntityKind_Thread) { - CTRL_Entity *process = ctrl_process_from_entity(entity); - CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity); accel->arch = entity->arch; - accel->process = process->handle; - accel->call_stack = ctrl_call_stack_from_unwind(arena, process, &base_unwind); + accel->process = ctrl_process_from_entity(entity)->handle; + accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, 0); } scratch_end(scratch); } @@ -975,7 +973,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack) RD_CallStackAccel *accel = (RD_CallStackAccel *)lhs_irtree->user_data; E_Value rhs_value = e_value_from_expr(expr->first->next); CTRL_CallStack *call_stack = &accel->call_stack; - if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count) + if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->frames_count) { CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, accel->process); CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; @@ -992,7 +990,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) RD_CallStackAccel *accel = (RD_CallStackAccel *)eval.irtree.user_data; E_TypeExpandInfo result = {0}; result.user_data = accel; - result.expr_count = accel->call_stack.count; + result.expr_count = accel->call_stack.frames_count; return result; } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 72413ee0..81fdc192 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1008,17 +1008,18 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); if(entity->kind == CTRL_EntityKind_Thread) { + CTRL_Scope *ctrl_scope = ctrl_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, ctrl_process_from_entity(entity), &unwind); - if(1 <= frame_num && frame_num <= call_stack.count) + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + if(1 <= frame_num && frame_num <= call_stack.frames_count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; info.callstack_unwind_index = f->unwind_count; info.callstack_inline_depth = f->inline_depth; info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); } + ctrl_scope_close(ctrl_scope); } } @@ -2837,17 +2838,18 @@ RD_VIEW_UI_FUNCTION_DEF(memory) }; AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size); { + CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 0); //- rjf: fill unwind frame annotations - if(unwind.frames.count != 0) UI_Tag(str8_lit("weak")) + if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) { - U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs); - for(U64 idx = 1; idx < unwind.frames.count; idx += 1) + U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs); + for(U64 idx = 1; idx < call_stack.concrete_frames_count; idx += 1) { - CTRL_UnwindFrame *f = &unwind.frames.v[idx]; + CTRL_CallStackFrame *f = call_stack.concrete_frames[idx]; U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs); Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top); Rng1U64 frame_vaddr_range_in_viz = intersect_1u64(frame_vaddr_range, viz_range_bytes); @@ -2896,10 +2898,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } //- rjf: fill selected thread stack range annotation - if(unwind.frames.count > 0) + if(call_stack.concrete_frames_count > 0) { U64 stack_base_vaddr = thread->stack_base; - U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs); + U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs); Rng1U64 stack_vaddr_range = r1u64(stack_base_vaddr, stack_top_vaddr); Rng1U64 stack_vaddr_range_in_viz = intersect_1u64(stack_vaddr_range, viz_range_bytes); if(dim_1u64(stack_vaddr_range_in_viz) != 0) @@ -2954,6 +2956,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) } di_scope_close(scope); } + ctrl_scope_close(ctrl_scope); } ////////////////////////////// diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 689e215c..1257da53 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -521,13 +521,14 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e { Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + CTRL_Scope *ctrl_scope = ctrl_scope_open(); DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); - for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1) + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1) { - CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx]; + CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx]; U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr); U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr); @@ -542,7 +543,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e if(name.size != 0) { dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color); - if(idx+1 < unwind.frames.count) + if(idx+1 < call_stack.frames_count) { dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size); if(idx+1 == limit) @@ -554,6 +555,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e } } di_scope_close(di_scope); + ctrl_scope_close(ctrl_scope); } //- rjf: modules get debug info status extras From 9a805b8bb526e4acabaa937416706303d1013418 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 13:27:11 -0700 Subject: [PATCH 713/755] adjust call stack cachc committing mechanism, to guarantee commits in face of scope touches, and to ensure waiting for new commits in face of cache lookup --- src/ctrl/ctrl_core.c | 63 +++++++++++++++++++++++++++----------------- src/ctrl/ctrl_core.h | 3 ++- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e6a1a193..557fceae 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1434,14 +1434,17 @@ ctrl_scope_close(CTRL_Scope *scope) for(CTRL_ScopeCallStackTouch *t = scope->first_call_stack_touch, *next = 0; t != 0; t = next) { next = t->next; - ins_atomic_u64_dec_eval(&t->node->scope_touch_count); + if(!ins_atomic_u64_dec_eval(&t->node->scope_touch_count)) + { + os_condition_variable_broadcast(t->stripe->cv); + } SLLStackPush(ctrl_tctx->free_call_stack_touch, t); } SLLStackPush(ctrl_tctx->free_scope, scope); } internal void -ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node) +ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheStripe *stripe, CTRL_CallStackCacheNode *node) { ins_atomic_u64_inc_eval(&node->scope_touch_count); CTRL_ScopeCallStackTouch *touch = ctrl_tctx->free_call_stack_touch; @@ -1454,6 +1457,7 @@ ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallS touch = push_array(ctrl_tctx->arena, CTRL_ScopeCallStackTouch, 1); } SLLQueuePush(scope->first_call_stack_touch, scope->last_call_stack_touch, touch); + touch->stripe = stripe; touch->node = node; } @@ -3386,7 +3390,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) is_stale = (reg_gen > n->reg_gen || mem_gen > n->mem_gen); is_working = (n->working_count > 0); call_stack = n->call_stack; - ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, n); + ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, stripe, n); break; } } @@ -6813,39 +6817,50 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) if(pre_reg_gen == post_reg_gen && pre_mem_gen == post_mem_gen) { - for(B32 done = 0; !done;) + B32 found = 0; + B32 committed = 0; + OS_MutexScopeW(stripe->rw_mutex) for(;;) { - B32 found = 0; - OS_MutexScopeW(stripe->rw_mutex) + // rjf: try to find node & commit + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) { - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + if(ctrl_handle_match(n->thread, thread_handle)) { - if(ctrl_handle_match(n->thread, thread_handle)) + found = 1; + if(n->scope_touch_count == 0) { - found = 1; - if(n->scope_touch_count == 0) + committed = 1; + if(unwind.flags == 0 || call_stack.frames_count >= n->call_stack.frames_count) { - done = 1; - if(unwind.flags == 0 || call_stack.frames_count >= n->call_stack.frames_count) - { - last_arena = n->arena; - n->arena = arena; - n->call_stack = call_stack; - } - if(unwind.flags == 0) - { - n->reg_gen = pre_reg_gen; - n->mem_gen = pre_mem_gen; - } + last_arena = n->arena; + n->arena = arena; + n->call_stack = call_stack; + } + if(unwind.flags == 0) + { + n->reg_gen = pre_reg_gen; + n->mem_gen = pre_mem_gen; } - break; } + break; } } - if(!found) + + // rjf: not found, or committed? -> abort + if(!found || committed) { break; } + + // rjf: found, not committed? -> wait & retry + if(found && !committed) + { + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10000); + } + } + if(committed) + { + os_condition_variable_broadcast(stripe->cv); } } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 50196a58..351bb8f7 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -728,6 +728,7 @@ typedef struct CTRL_ScopeCallStackTouch CTRL_ScopeCallStackTouch; struct CTRL_ScopeCallStackTouch { CTRL_ScopeCallStackTouch *next; + CTRL_CallStackCacheStripe *stripe; CTRL_CallStackCacheNode *node; }; @@ -967,7 +968,7 @@ internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_ internal CTRL_Scope *ctrl_scope_open(void); internal void ctrl_scope_close(CTRL_Scope *scope); -internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node); +internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheStripe *stripe, CTRL_CallStackCacheNode *node); //////////////////////////////// //~ rjf: Main Layer Initialization From 95032147e82fc7b65f09fbe93772d0df95ea8f7c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 13:47:55 -0700 Subject: [PATCH 714/755] lock ctrl thread entity ctx for much less long when doing unwinds; only copy the minimal entity tree needed into a mini entity ctx, then use that to do the unwind --- src/ctrl/ctrl_core.c | 96 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 557fceae..5c866084 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -6783,6 +6783,7 @@ ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread) ASYNC_WORK_DEF(ctrl_call_stack_build_work) { + Temp scratch = scratch_begin(0, 0); CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; //- rjf: get next request & unpack @@ -6794,12 +6795,94 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; - //- rjf: do task + //- rjf: produce mini entity context for just this process + CTRL_EntityCtx *entity_ctx = push_array(scratch.arena, CTRL_EntityCtx, 1); OS_MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { - Temp scratch = scratch_begin(0, 0); - CTRL_EntityCtx *ctx = &ctrl_state->ctrl_thread_entity_store->ctx; - CTRL_Entity *thread = ctrl_entity_from_handle(ctx, thread_handle); + CTRL_EntityCtx *src_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; + CTRL_EntityCtx *dst_ctx = entity_ctx; + { + dst_ctx->root = &ctrl_entity_nil; + dst_ctx->hash_slots_count = 1024; + dst_ctx->hash_slots = push_array(scratch.arena, CTRL_EntityHashSlot, dst_ctx->hash_slots_count); + MemoryCopyArray(dst_ctx->entity_kind_counts, src_ctx->entity_kind_counts); + MemoryCopyArray(dst_ctx->entity_kind_alloc_gens, src_ctx->entity_kind_alloc_gens); + } + CTRL_Entity *src_thread = ctrl_entity_from_handle(src_ctx, thread_handle); + CTRL_Entity *src_process = ctrl_process_from_entity(src_thread); + { + CTRL_EntityRec rec = {0}; + CTRL_Entity *dst_parent = &ctrl_entity_nil; + for(CTRL_Entity *src_e = src_process; src_e != &ctrl_entity_nil; src_e = rec.next) + { + rec = ctrl_entity_rec_depth_first_pre(src_e, src_process); + + // rjf: copy this entity + CTRL_Entity *dst_e = push_array(scratch.arena, CTRL_Entity, 1); + { + dst_e->first = dst_e->last = dst_e->next = dst_e->prev = &ctrl_entity_nil; + dst_e->parent = dst_parent; + dst_e->kind = src_e->kind; + dst_e->arch = src_e->arch; + dst_e->is_frozen = src_e->is_frozen; + dst_e->is_soloed = src_e->is_soloed; + dst_e->rgba = src_e->rgba; + dst_e->handle = src_e->handle; + dst_e->id = src_e->id; + dst_e->vaddr_range = src_e->vaddr_range; + dst_e->stack_base = src_e->stack_base; + dst_e->timestamp = src_e->timestamp; + dst_e->bp_flags = src_e->bp_flags; + dst_e->string = push_str8_copy(scratch.arena, src_e->string); + } + if(dst_parent == &ctrl_entity_nil) + { + dst_ctx->root = dst_e; + } + else + { + DLLPushBack_NPZ(&ctrl_entity_nil, dst_parent->first, dst_parent->last, dst_e, next, prev); + } + + // rjf: insert into hash map + { + U64 hash = ctrl_hash_from_handle(dst_e->handle); + U64 slot_idx = hash%dst_ctx->hash_slots_count; + CTRL_EntityHashSlot *slot = &dst_ctx->hash_slots[slot_idx]; + CTRL_EntityHashNode *node = 0; + for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->entity->handle, dst_e->handle)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(scratch.arena, CTRL_EntityHashNode, 1); + MemoryZeroStruct(node); + DLLPushBack(slot->first, slot->last, node); + node->entity = dst_e; + } + } + + // rjf: push/pop + if(rec.push_count) + { + dst_parent = dst_e; + } + else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) + { + dst_parent = dst_parent->parent; + } + } + } + } + + //- rjf: do task + { + CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, thread_handle); CTRL_Entity *process = ctrl_process_from_entity(thread); //- rjf: compute unwind to find list of all concrete frames, then @@ -6807,7 +6890,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) U64 pre_reg_gen = ctrl_reg_gen(); U64 pre_mem_gen = ctrl_mem_gen(); Arena *arena = arena_alloc(); - CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, 0); + CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, 0); CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); U64 post_reg_gen = ctrl_reg_gen(); U64 post_mem_gen = ctrl_mem_gen(); @@ -6879,9 +6962,8 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) break; } } - - scratch_end(scratch); } + scratch_end(scratch); return 0; } From 6ff66b0fefafb4c1e71192a6e9289dab535b71c9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 14:05:14 -0700 Subject: [PATCH 715/755] adjust static breakpoint disqualification to not assume invalid eval -> statically disqualfiied --- src/raddbg/raddbg_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d0f0527f..e9366882 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -16247,14 +16247,17 @@ rd_frame(void) { E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, t->expr->string); E_Eval eval = e_eval_from_string(t->expr->string); - switch(eval.space.kind) + if(eval.msgs.max_kind == E_MsgKind_Null) { - default:{is_static_for_ctrl_thread = 0;}break; - case E_SpaceKind_Null: - case RD_EvalSpaceKind_MetaCfg: + switch(eval.space.kind) { - is_static_for_ctrl_thread = 1; - }break; + default:{is_static_for_ctrl_thread = 0;}break; + case E_SpaceKind_Null: + case RD_EvalSpaceKind_MetaCfg: + { + is_static_for_ctrl_thread = 1; + }break; + } } } for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) From ed9866e9e214f79abccd9a962fd778b75e13708b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 14:17:17 -0700 Subject: [PATCH 716/755] retry call stack commits a bit more aggressively --- src/ctrl/ctrl_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 5c866084..be8416f2 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -6938,7 +6938,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) // rjf: found, not committed? -> wait & retry if(found && !committed) { - os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10000); + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+100); } } if(committed) From 965f5f48964c500526f730e830e48942e69dab3f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 14:37:37 -0700 Subject: [PATCH 717/755] 0.9.18 notes --- src/raddbg/raddbg_main.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index eb9d1336..a3400fe4 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -1,6 +1,27 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: 0.9.18 Release Notes +/* +- Adjusted identifier resolution rules in the evaluation language to prefer visualizer names when used in a call expression. For example, even if you have a variable named `bitmap`, if you evaluate `bitmap(...)`, it will prefer resolving `bitmap` to the visualizer. You can still always disambiguate with qualifiers, e.g. `local:bitmap` or `type:bitmap`. +- Adjusted the `only` view to allow arbitrary derivative expressions, rather than only member names. This allows custom expansions to insert rows for arbitrary expressions. These expressions are derivative from the expanded expression, meaning they can refer to the expanded expression via `$`, or implicitly, its member names. +- Renamed the `table` view to `columns`, and the `only` view to `rows`, since these more directly reflect the way these views are used in the evaluation visualization pipeline. +- Added an option to all text views to scroll to the bottom if the textual content changes at all. Can be used with the `Output` tab. +- Improved toggle switches to allow clicking and dragging to toggle many switches in a single operation. +- The debugger now records the last user file which was loaded while it was opened, and reopens that file on startup, if no user is explicitly specified. (#482) + - The debugger now unfocuses query bars (e.g. that opened by `Ctrl + F` in a source view) if the main view content is clicked by the mouse. The query bar can be refocused also by clicking. + - Moved call stack evaluation to occur asynchronously, so that deeper call stacks (which can be expensive to compute) do not block the UI. + - Stopped the debugger from running the default Windows message handling path for most `Alt`-based keybindings, which was causing a Windows beep sound to play. + - Fixed a bug which was preventing backslashes from working in file system querying interfaces correctly. + - Fixed a bug which was preventing some recursive callstacks from fully displaying in the debugger. + - Fixed a bug which prevented `Space` from being used as a keybinding. Bound `Space` by default to the `Accept` command (to which `Enter` / `Return` is also defaultly bound). + - Fixed a bug which was preventing conditional breakpoints from correctly being placed, if the condition expression did not evaluate when the debuggees were resumed. + - Fixed the debugger applying too much path processing, which was causing relative paths in debug info to be interpreted incorrectly. The debugger should now work much better with relative paths (e.g. produced via `/d1trimfile`). In these cases, the debugger may still not be able to fully compute the correct absolute paths, because this information is not stored within debug information. But once the debugger is redirected to the correct file once through the UI, it should work with relative paths correctly. + - If the debugger crashes, the message box which opens and displays the crash call stack now also allows the creation of crash dump files. Please submit these, if possible, with crash reports; it will help us to debug crashes more effectively. + - Fixed a bug which was causing text rendering to fail both when running the debugger on WINE and also on Windows 7. +*/ + //////////////////////////////// //~ rjf: post-0.9.16 TODO notes // From 86eabe0d6def6ec37290456cbe645980147e90fe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 21:57:50 -0700 Subject: [PATCH 718/755] offer priority selection in call stack retrieval; prioritize selected thread & operations which require a result; adjust call stack builder path to be a bit more generous while waiting for memory reads --- src/ctrl/ctrl_core.c | 26 +++++++++++++++++--------- src/ctrl/ctrl_core.h | 2 +- src/raddbg/raddbg_core.c | 8 ++++---- src/raddbg/raddbg_eval.c | 2 +- src/raddbg/raddbg_views.c | 4 ++-- src/raddbg/raddbg_widgets.c | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index be8416f2..6a5e8830 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3356,7 +3356,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U //~ rjf: Call Stack Cache Functions internal CTRL_CallStack -ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) +ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us) { CTRL_CallStack call_stack = {0}; { @@ -3419,7 +3419,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) if(!is_working && (!is_good || is_stale)) { if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && - async_push_work(ctrl_call_stack_build_work)) + async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) { ins_atomic_u64_inc_eval(&node->working_count); } @@ -6887,13 +6887,21 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) //- rjf: compute unwind to find list of all concrete frames, then // call stack, to determine list of all concrete & inline frames - U64 pre_reg_gen = ctrl_reg_gen(); - U64 pre_mem_gen = ctrl_mem_gen(); Arena *arena = arena_alloc(); - CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, 0); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); - U64 post_reg_gen = ctrl_reg_gen(); - U64 post_mem_gen = ctrl_mem_gen(); + U64 pre_reg_gen = 0; + U64 post_reg_gen = 0; + U64 pre_mem_gen = 0; + U64 post_mem_gen = 0; + CTRL_Unwind unwind = {0}; + CTRL_CallStack call_stack = {0}; + { + pre_reg_gen = ctrl_reg_gen(); + pre_mem_gen = ctrl_mem_gen(); + unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+1000); + call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); + post_reg_gen = ctrl_reg_gen(); + post_mem_gen = ctrl_mem_gen(); + } //- rjf: store new results in cache Arena *last_arena = arena; @@ -6938,7 +6946,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) // rjf: found, not committed? -> wait & retry if(found && !committed) { - os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+100); + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10); } } if(committed) diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 351bb8f7..45ba1a4b 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -1045,7 +1045,7 @@ internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth //////////////////////////////// //~ rjf: Call Stack Cache Functions -internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us); +internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us); //////////////////////////////// //~ rjf: Halting All Attached Processes diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e9366882..24bbfd56 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1816,7 +1816,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case CTRL_EntityKind_Thread: { CTRL_Scope *ctrl_scope = ctrl_scope_open(); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 1, 0); U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; if(concrete_frame_idx < call_stack.concrete_frames_count) { @@ -6399,7 +6399,7 @@ rd_window_frame(void) Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread), 0); if(call_stack.frames_count != 0) { ui_spacer(ui_em(1.5f, 1.f)); @@ -15640,7 +15640,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); if(frame == 0) { @@ -15659,7 +15659,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *next_frame = current_frame; if(current_frame != 0) switch(kind) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a329257e..7183fffb 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -957,7 +957,7 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) { accel->arch = entity->arch; accel->process = ctrl_process_from_entity(entity)->handle; - accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, 0); + accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); } scratch_end(scratch); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 81fdc192..2022ad37 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1011,7 +1011,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Scope *ctrl_scope = ctrl_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); if(1 <= frame_num && frame_num <= call_stack.frames_count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; @@ -2841,7 +2841,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, 0); //- rjf: fill unwind frame annotations if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1257da53..8dc6df38 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -525,7 +525,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1) { CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx]; From a379134ed817964283c52c3a00b522e775a2255a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 16 May 2025 21:12:58 -0700 Subject: [PATCH 719/755] demon tweaks / debugging; adjust call stack cache reading API to account for high-priority path, where we want to try computing the thread's call stack immediately --- src/async/async.c | 3 ++- src/ctrl/ctrl_core.c | 12 +++++++++++- src/ctrl/ctrl_core.h | 2 +- src/demon/win32/demon_core_win32.c | 20 +++++++++++++++++++- src/raddbg/raddbg_core.c | 8 ++++---- src/raddbg/raddbg_eval.c | 2 +- src/raddbg/raddbg_main.c | 1 + src/raddbg/raddbg_views.c | 4 ++-- src/raddbg/raddbg_widgets.c | 2 +- 9 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/async/async.c b/src/async/async.c index 75c1318e..01a24100 100644 --- a/src/async/async.c +++ b/src/async/async.c @@ -26,8 +26,9 @@ async_init(CmdLine *cmdline) String8 work_thread_count_string = cmd_line_string(cmdline, str8_lit("work_threads_count")); if(work_thread_count_string.size == 0 || !try_u64_from_str8_c_rules(work_thread_count_string, &async_shared->work_threads_count)) { - async_shared->work_threads_count = Max(1, os_get_system_info()->logical_processor_count-1); + async_shared->work_threads_count = Max(4, os_get_system_info()->logical_processor_count-1); } + async_shared->work_threads_count = Max(4, async_shared->work_threads_count); async_shared->work_threads = push_array(arena, OS_Handle, async_shared->work_threads_count); for EachIndex(idx, async_shared->work_threads_count) { diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 6a5e8830..ee65d2ec 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3356,7 +3356,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U //~ rjf: Call Stack Cache Functions internal CTRL_CallStack -ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us) +ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_Entity *thread, B32 high_priority, U64 endt_us) { CTRL_CallStack call_stack = {0}; { @@ -3399,6 +3399,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_pri //- rjf: create node if needed if(!is_good) OS_MutexScopeRWPromote(stripe->rw_mutex) { + node = 0; for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->thread, handle)) @@ -4271,6 +4272,15 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, log_infof("string: \"%S\"\n", ev->string); log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer); } + raddbg_log("event:\n"); + raddbg_log("kind: %S\n", dmn_event_kind_string_table[ev->kind]); + raddbg_log("process: [%I64u]\n", ev->process.u64[0]); + raddbg_log("thread: [%I64u]\n", ev->thread.u64[0]); + raddbg_log("module: [%I64u]\n", ev->module.u64[0]); + raddbg_log("pid: %I64u\n", ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->process))->id); + raddbg_log("tid: %I64u\n", ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->thread))->id); + raddbg_log("code: %I64u\n", ev->code); + raddbg_log("\n"); } // rjf: determine if we should filter diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 45ba1a4b..00c83aae 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -1045,7 +1045,7 @@ internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth //////////////////////////////// //~ rjf: Call Stack Cache Functions -internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us); +internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_Entity *thread, B32 high_priority, U64 endt_us); //////////////////////////////// //~ rjf: Halting All Attached Processes diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index fee9e9f6..d684c573 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -156,6 +156,7 @@ dmn_w32_entity_release(DMN_W32_Entity *entity) { CloseHandle(t->e->handle); } + t->e->kind = DMN_W32_EntityKind_Null; // rjf: remove from id -> entity map if(t->e->id != 0) @@ -1870,13 +1871,14 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { dmn_w32_shared->resume_needed = 0; resume_good = !!ContinueDebugEvent(dmn_w32_shared->resume_pid, dmn_w32_shared->resume_tid, resume_code); + DWORD error = GetLastError(); dmn_w32_shared->resume_needed = 0; dmn_w32_shared->resume_tid = 0; dmn_w32_shared->resume_pid = 0; } if(resume_good) { - evt_good = !!WaitForDebugEvent(&evt, 100); + evt_good = !!WaitForDebugEvent(&evt, 1000); if(evt_good) { dmn_w32_shared->resume_needed = 1; @@ -1885,6 +1887,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } else { + DWORD err = GetLastError(); + (void)err; keep_going = 1; } ins_atomic_u64_inc_eval(&dmn_w32_shared->run_gen); @@ -1992,6 +1996,15 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + // rjf: if this was the process we were going to resume, then we will + // just not resume, and wait for another debug event + if(evt.dwProcessId == dmn_w32_shared->resume_pid) + { + dmn_w32_shared->resume_needed = 0; + dmn_w32_shared->resume_tid = 0; + dmn_w32_shared->resume_pid = 0; + } + // rjf: generate events for children for(DMN_W32_Entity *child = process->first; child != &dmn_w32_entity_nil; child = child->next) { @@ -2097,6 +2110,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) e->kind = DMN_EventKind_Halt; dmn_w32_shared->halter_process = dmn_handle_zero(); dmn_w32_shared->halter_tid = 0; + keep_going = 0; } // rjf: if this thread is *not* the halter, then generate a regular exit-thread event @@ -2643,6 +2657,10 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) { DMN_W32_Entity *thread = n->v; + if(thread->kind != DMN_W32_EntityKind_Thread) + { + continue; + } DWORD suspend_result = SuspendThread(thread->handle); switch(suspend_result) { diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 24bbfd56..a68fb50d 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1816,7 +1816,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case CTRL_EntityKind_Thread: { CTRL_Scope *ctrl_scope = ctrl_scope_open(); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 1, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, 1, 0); U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; if(concrete_frame_idx < call_stack.concrete_frames_count) { @@ -6399,7 +6399,7 @@ rd_window_frame(void) Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread), 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, ctrl_entity, ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread), 0); if(call_stack.frames_count != 0) { ui_spacer(ui_em(1.5f, 1.f)); @@ -15640,7 +15640,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); if(frame == 0) { @@ -15659,7 +15659,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *next_frame = current_frame; if(current_frame != 0) switch(kind) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7183fffb..6e68bc68 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -957,7 +957,7 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) { accel->arch = entity->arch; accel->process = ctrl_process_from_entity(entity)->handle; - accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); } scratch_end(scratch); } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index a3400fe4..97e514d6 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -13,6 +13,7 @@ - The debugger now unfocuses query bars (e.g. that opened by `Ctrl + F` in a source view) if the main view content is clicked by the mouse. The query bar can be refocused also by clicking. - Moved call stack evaluation to occur asynchronously, so that deeper call stacks (which can be expensive to compute) do not block the UI. - Stopped the debugger from running the default Windows message handling path for most `Alt`-based keybindings, which was causing a Windows beep sound to play. +- Fixed a bug where RDI files would sometimes fail to generate, resulting in no debug info being available on some runs. - Fixed a bug which was preventing backslashes from working in file system querying interfaces correctly. - Fixed a bug which was preventing some recursive callstacks from fully displaying in the debugger. - Fixed a bug which prevented `Space` from being used as a keybinding. Bound `Space` by default to the `Accept` command (to which `Enter` / `Return` is also defaultly bound). diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2022ad37..2f4a461e 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1011,7 +1011,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Scope *ctrl_scope = ctrl_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); if(1 <= frame_num && frame_num <= call_stack.frames_count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; @@ -2841,7 +2841,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, 0); //- rjf: fill unwind frame annotations if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 8dc6df38..44a0dfc4 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -525,7 +525,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1) { CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx]; From 7a44cbbd0dda029bf8c22cd8901012cb012b4883 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 08:41:51 -0700 Subject: [PATCH 720/755] adjust high priority call stack timeout threshold --- src/ctrl/ctrl_core.c | 2 +- src/ctrl/ctrl_core.h | 2 +- src/raddbg/raddbg_core.c | 5 +++-- src/raddbg/raddbg_eval.c | 3 ++- src/raddbg/raddbg_views.c | 3 ++- src/raddbg/raddbg_widgets.c | 3 ++- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ee65d2ec..249fbb5f 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -6907,7 +6907,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) { pre_reg_gen = ctrl_reg_gen(); pre_mem_gen = ctrl_mem_gen(); - unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+1000); + unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+5000); call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); post_reg_gen = ctrl_reg_gen(); post_mem_gen = ctrl_mem_gen(); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 00c83aae..3b2e1405 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -617,7 +617,7 @@ struct CTRL_CallStackCacheNode U64 reg_gen; U64 mem_gen; - // rjf: refcounts + // rjf: counters U64 scope_touch_count; U64 working_count; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a68fb50d..6dece756 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1816,7 +1816,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case CTRL_EntityKind_Thread: { CTRL_Scope *ctrl_scope = ctrl_scope_open(); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, 1, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, 1, rd_state->frame_eval_memread_endt_us); U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; if(concrete_frame_idx < call_stack.concrete_frames_count) { @@ -6399,7 +6399,8 @@ rd_window_frame(void) Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, ctrl_entity, ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread), 0); + B32 call_stack_high_priority = ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, ctrl_entity, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); if(call_stack.frames_count != 0) { ui_spacer(ui_em(1.5f, 1.f)); diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 6e68bc68..f67da862 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -955,9 +955,10 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); if(entity->kind == CTRL_EntityKind_Thread) { + B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread); accel->arch = entity->arch; accel->process = ctrl_process_from_entity(entity)->handle; - accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); } scratch_end(scratch); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 2f4a461e..177f9bd5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1011,7 +1011,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Scope *ctrl_scope = ctrl_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); if(1 <= frame_num && frame_num <= call_stack.frames_count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 44a0dfc4..5cd62bbc 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -525,7 +525,8 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); + B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, entity, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1) { CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx]; From 66fdfc84fc7f97bf8285a4d0289d70b9f544b746 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 10:16:49 -0700 Subject: [PATCH 721/755] further pass over call stack cache lookup path --- src/ctrl/ctrl_core.c | 150 +++++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 249fbb5f..bf855bf1 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3359,82 +3359,94 @@ internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_Entity *thread, B32 high_priority, U64 endt_us) { CTRL_CallStack call_stack = {0}; + CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; + + ////////////////////////////// + //- rjf: unpack thread + // + CTRL_Handle handle = thread->handle; + U64 hash = ctrl_hash_from_handle(handle); + U64 slot_idx = hash%cache->slots_count; + U64 stripe_idx = slot_idx%cache->stripes_count; + CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; + CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; + U64 reg_gen = ctrl_reg_gen(); + U64 mem_gen = ctrl_mem_gen(); + + ////////////////////////////// + //- rjf: loop: try to grab cached call stack; request; wait + // + OS_MutexScopeR(stripe->rw_mutex) for(;;) { - CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; - - //- rjf: unpack thread - CTRL_Handle handle = thread->handle; - U64 hash = ctrl_hash_from_handle(handle); - U64 slot_idx = hash%cache->slots_count; - U64 stripe_idx = slot_idx%cache->stripes_count; - CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; - CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; - - //- rjf: loop: try to grab cached call stack; request; wait - U64 reg_gen = ctrl_reg_gen(); - U64 mem_gen = ctrl_mem_gen(); - OS_MutexScopeR(stripe->rw_mutex) for(;;) + //////////////////////////// + //- rjf: try to grab cached + // + B32 is_good = 0; + B32 is_stale = 1; + B32 is_working = 0; + CTRL_CallStackCacheNode *node = 0; { - //- rjf: try to grab cached - B32 is_good = 0; - B32 is_stale = 0; - B32 is_working = 0; - CTRL_CallStackCacheNode *node = 0; + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) { - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + if(ctrl_handle_match(n->thread, handle)) { - if(ctrl_handle_match(n->thread, handle)) - { - node = n; - is_good = 1; - is_stale = (reg_gen > n->reg_gen || mem_gen > n->mem_gen); - is_working = (n->working_count > 0); - call_stack = n->call_stack; - ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, stripe, n); - break; - } + node = n; + is_good = 1; + is_stale = (reg_gen > n->reg_gen || mem_gen > n->mem_gen); + is_working = (n->working_count > 0); + call_stack = n->call_stack; + ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, stripe, n); + break; } } - - //- rjf: create node if needed - if(!is_good) OS_MutexScopeRWPromote(stripe->rw_mutex) - { - node = 0; - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, handle)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); - DLLPushBack(slot->first, slot->last, node); - node->thread = thread->handle; - } - } - - //- rjf: request if needed - if(!is_working && (!is_good || is_stale)) - { - if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && - async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) - { - ins_atomic_u64_inc_eval(&node->working_count); - } - } - - //- rjf: good, or timeout? -> exit - if((is_good && !is_stale) || os_now_microseconds() >= endt_us) - { - break; - } - - //- rjf: time to wait for new result? -> wait - os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); } + + //////////////////////////// + //- rjf: create node if needed + // + if(!is_good) OS_MutexScopeRWPromote(stripe->rw_mutex) + { + node = 0; + for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->thread, handle)) + { + node = n; + break; + } + } + if(node == 0) + { + node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); + DLLPushBack(slot->first, slot->last, node); + node->thread = thread->handle; + } + } + + //////////////////////////// + //- rjf: request if needed + // + if(node != 0 && !is_working && is_stale) + { + if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && + async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) + { + ins_atomic_u64_inc_eval(&node->working_count); + } + } + + //////////////////////////// + //- rjf: good, or timeout? -> exit + // + if(!is_stale || os_now_microseconds() >= endt_us) + { + break; + } + + //////////////////////////// + //- rjf: time to wait for new result? -> wait + // + os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); } return call_stack; } From ea5dcafd1e1d3f99b2c38cc015acbe88fed4d278 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 12:41:47 -0700 Subject: [PATCH 722/755] hash store key closing path --- src/hash_store/hash_store.c | 56 +++++++++++++++++++++++++++++++++++-- src/hash_store/hash_store.h | 7 +++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 8296ec38..fff4e2fa 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -47,6 +47,7 @@ hs_init(void) hs_shared->key_stripes_count = Min(hs_shared->key_slots_count, os_get_system_info()->logical_processor_count); hs_shared->key_slots = push_array(arena, HS_KeySlot, hs_shared->key_slots_count); hs_shared->key_stripes = push_array(arena, HS_Stripe, hs_shared->key_stripes_count); + hs_shared->key_stripes_free_nodes = push_array(arena, HS_KeyNode *, hs_shared->key_stripes_count); for(U64 idx = 0; idx < hs_shared->key_stripes_count; idx += 1) { HS_Stripe *stripe = &hs_shared->key_stripes[idx]; @@ -149,9 +150,17 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) } if(!key_node) { - key_node = push_array(key_stripe->arena, HS_KeyNode, 1); + key_node = hs_shared->key_stripes_free_nodes[key_stripe_idx]; + if(key_node) + { + SLLStackPop(hs_shared->key_stripes_free_nodes[key_stripe_idx]); + } + else + { + key_node = push_array(key_stripe->arena, HS_KeyNode, 1); + } key_node->key = key; - SLLQueuePush(key_slot->first, key_slot->last, key_node); + DLLPushBack(key_slot->first, key_slot->last, key_node); } if(key_node) { @@ -253,6 +262,49 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) SLLStackPush(scope->top_touch, touch); } +//////////////////////////////// +//~ rjf: Key Closing + +internal void +hs_key_close(U128 key) +{ + U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count; + U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; + HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; + HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; + OS_MutexScopeW(key_stripe->rw_mutex) + { + for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) + { + if(u128_match(n->key, key)) + { + for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1) + { + U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)]; + U64 hash_slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count; + HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; + HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx]; + OS_MutexScope(hash_stripe->rw_mutex) + { + for(HS_Node *n = hash_slot->first; n != 0; n = n->next) + { + if(u128_match(n->hash, hash)) + { + ins_atomic_u64_dec_eval(&n->key_ref_count); + break; + } + } + } + } + DLLRemove(key_slot->first, key_slot->last, n); + SLLStackPush(hs_shared->key_stripes_free_nodes[key_stripe_idx], n); + break; + } + } + } +} + //////////////////////////////// //~ rjf: Downstream Accesses diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index 784a9203..3cbee4f5 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -14,6 +14,7 @@ typedef struct HS_KeyNode HS_KeyNode; struct HS_KeyNode { HS_KeyNode *next; + HS_KeyNode *prev; U128 key; U128 hash_history[HS_KEY_HASH_HISTORY_COUNT]; U64 hash_history_gen; @@ -102,6 +103,7 @@ struct HS_Shared U64 key_stripes_count; HS_KeySlot *key_slots; HS_Stripe *key_stripes; + HS_KeyNode **key_stripes_free_nodes; // rjf: evictor thread OS_Handle evictor_thread; @@ -140,6 +142,11 @@ internal HS_Scope *hs_scope_open(void); internal void hs_scope_close(HS_Scope *scope); internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node); +//////////////////////////////// +//~ rjf: Key Closing + +internal void hs_key_close(U128 key); + //////////////////////////////// //~ rjf: Downstream Accesses From 5712c2ac075ea6d489d794c96da242689e3a4f9c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 12:56:49 -0700 Subject: [PATCH 723/755] fix ternary expr tree stringification --- src/eval/eval.mdesk | 2 +- src/eval/generated/eval.meta.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 3b8d0588..f7f382ed 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -119,7 +119,7 @@ E_ExprKindTable: { LogAnd Binary 11 "" " && " "" "" } { LogOr Binary 12 "" " || " "" "" } - { Ternary Null 0 "" " ? " " : " "" } + { Ternary Null 0 "" " ? " "" " : "} { Call Null 15 "" "(" ")" ", "} diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 28c61a6b..a1305840 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -231,7 +231,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp(" | "), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp(" && "), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp(" || "), str8_lit_comp(""), str8_lit_comp("") }, -{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(" ? "), str8_lit_comp(" : "), str8_lit_comp("") }, +{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(" ? "), str8_lit_comp(""), str8_lit_comp(" : ") }, { E_OpKind_Null, 15, str8_lit_comp(""), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(", ") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") }, From 5cb2a7bbde3014a2119b68d53d5108b3d79adaea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 13:05:07 -0700 Subject: [PATCH 724/755] fix usage of [] operator on pointer values; fix incorrect interpretation of []s as assembly style derefs in chained cases --- src/eval/eval_ir.c | 1 + src/eval/eval_parse.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index b3aa726c..da9157cb 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -574,6 +574,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) // rjf: ops to compute the final address new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + mode = E_Mode_Offset; } } diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index ed79b907..a82b01db 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1023,7 +1023,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t //////////////////////// //- rjf: descent to assembly-style dereference sub-expression [...] // - if(!got_new_atom) + if(atom == &e_expr_nil && !got_new_atom) { E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); From f99dd2a477489bf8503c340a0f0ad0dd573cb7cf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sat, 17 May 2025 13:33:43 -0700 Subject: [PATCH 725/755] clean up search data commit on scope-hold mechanism --- src/dbgi/dbgi.c | 19 +++++++++++++------ src/dbgi/dbgi.h | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 4aea445c..b4afa856 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -283,6 +283,7 @@ di_scope_close(DI_Scope *scope) if(t->search_node != 0) { ins_atomic_u64_dec_eval(&t->search_node->scope_refcount); + os_condition_variable_broadcast(t->search_stripe->cv); } SLLStackPush(di_tctx->free_touch, t); } @@ -311,7 +312,7 @@ di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node) } internal void -di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node) +di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node) { if(node != 0) { @@ -329,6 +330,7 @@ di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNod MemoryZeroStruct(touch); SLLQueuePush(scope->first_touch, scope->last_touch, touch); touch->search_node = node; + touch->search_stripe = stripe; } //////////////////////////////// @@ -709,7 +711,7 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams B32 results_stale = 1; if(node->bucket_read_gen != 0) { - di_scope_touch_search_node__stripe_mutex_r_guarded(scope, node); + di_scope_touch_search_node__stripe_mutex_r_guarded(scope, stripe, node); items = node->items; params_stale = (params_hash != node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash); query_stale = !str8_match(query, node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].query, 0); @@ -1473,13 +1475,14 @@ di_search_thread__entry_point(void *p) quick_sort(items.v, items.count, sizeof(DI_SearchItem), di_qsort_compare_search_items); } - //- rjf: commit to cache - busyloop on scope touches + //- rjf: commit to cache - wait on scope touches if(arena != 0) { - for(B32 done = 0; !done;) + OS_MutexScopeW(stripe->rw_mutex) for(;;) { B32 found = 0; - OS_MutexScopeW(stripe->rw_mutex) for(DI_SearchNode *n = slot->first; n != 0; n = n->next) + B32 done = 0; + for(DI_SearchNode *n = slot->first; n != 0; n = n->next) { if(u128_match(n->key, key)) { @@ -1498,10 +1501,14 @@ di_search_thread__entry_point(void *p) break; } } - if(!found) + if((found && done) || !found) { break; } + if(found && !done) + { + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+1000); + } } } diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index ecf29632..c663c3e7 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -219,6 +219,7 @@ struct DI_Touch DI_Touch *next; DI_Node *node; DI_SearchNode *search_node; + DI_SearchStripe *search_stripe; }; typedef struct DI_Scope DI_Scope; @@ -410,7 +411,7 @@ internal void di_init(void); internal DI_Scope *di_scope_open(void); internal void di_scope_close(DI_Scope *scope); internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node); -internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node); +internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node); //////////////////////////////// //~ rjf: Per-Slot Functions From 0a51de094da6fc523d141de4e8b8f42a18a0a73b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 18 May 2025 12:58:44 -0700 Subject: [PATCH 726/755] switch to stripe-cv-based waiting mechanism on nonzero scope touches --- src/ctrl/ctrl_core.c | 6 ++---- src/dbgi/dbgi.c | 20 +++++++++----------- src/dbgi/dbgi.h | 3 ++- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index bf855bf1..8e92c34e 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1434,10 +1434,8 @@ ctrl_scope_close(CTRL_Scope *scope) for(CTRL_ScopeCallStackTouch *t = scope->first_call_stack_touch, *next = 0; t != 0; t = next) { next = t->next; - if(!ins_atomic_u64_dec_eval(&t->node->scope_touch_count)) - { - os_condition_variable_broadcast(t->stripe->cv); - } + ins_atomic_u64_dec_eval(&t->node->scope_touch_count); + os_condition_variable_broadcast(t->stripe->cv); SLLStackPush(ctrl_tctx->free_call_stack_touch, t); } SLLStackPush(ctrl_tctx->free_scope, scope); diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index b4afa856..96f0b480 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -279,6 +279,7 @@ di_scope_close(DI_Scope *scope) if(t->node != 0) { ins_atomic_u64_dec_eval(&t->node->touch_count); + os_condition_variable_broadcast(t->stripe->cv); } if(t->search_node != 0) { @@ -291,7 +292,7 @@ di_scope_close(DI_Scope *scope) } internal void -di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node) +di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Stripe *stripe, DI_Node *node) { if(node != 0) { @@ -309,6 +310,7 @@ di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node) MemoryZeroStruct(touch); SLLQueuePush(scope->first_touch, scope->last_touch, touch); touch->node = node; + touch->stripe = stripe; } internal void @@ -529,6 +531,7 @@ di_close(DI_Key *key) DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key_normalized.path, key_normalized.min_timestamp); + B32 closed = 0; OS_MutexScopeW(stripe->rw_mutex) { //- rjf: find existing node @@ -540,16 +543,8 @@ di_close(DI_Key *key) node->ref_count -= 1; if(node->ref_count == 0) for(;;) { - //- rjf: wait for touch count to go to 0 - if(ins_atomic_u64_eval(&node->touch_count) != 0) - { - os_rw_mutex_drop_w(stripe->rw_mutex); - for(U64 start_t = os_now_microseconds(); os_now_microseconds() <= start_t + 250;); - os_rw_mutex_take_w(stripe->rw_mutex); - } - //- rjf: release - if(node->ref_count == 0 && ins_atomic_u64_eval(&node->touch_count) == 0) + if(ins_atomic_u64_eval(&node->touch_count) == 0) { di_string_release__stripe_mutex_w_guarded(stripe, node->key.path); if(node->file_base != 0) @@ -572,6 +567,9 @@ di_close(DI_Key *key) SLLStackPush(stripe->free_node, node); break; } + + //- rjf: wait for touch count to go to 0 + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, max_U64); } } } @@ -617,7 +615,7 @@ di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) //- rjf: parse done -> touch, grab result if(node != 0 && node->parse_done) { - di_scope_touch_node__stripe_mutex_r_guarded(scope, node); + di_scope_touch_node__stripe_mutex_r_guarded(scope, stripe, node); result = &node->rdi; break; } diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index c663c3e7..ca8b8e77 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -218,6 +218,7 @@ struct DI_Touch { DI_Touch *next; DI_Node *node; + DI_Stripe *stripe; DI_SearchNode *search_node; DI_SearchStripe *search_stripe; }; @@ -410,7 +411,7 @@ internal void di_init(void); internal DI_Scope *di_scope_open(void); internal void di_scope_close(DI_Scope *scope); -internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node); +internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Stripe *stripe, DI_Node *node); internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node); //////////////////////////////// From 342627ae3be38c6cf5d96049cff71b6a8a71db01 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 18 May 2025 13:16:51 -0700 Subject: [PATCH 727/755] dead code deletion --- src/dbg_engine/dbg_engine_core.c | 39 -------------------------------- src/dbg_engine/dbg_engine_core.h | 1 - 2 files changed, 40 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 3a9e9bb8..e9888f38 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -696,45 +696,6 @@ d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name) return result; } -internal U64 -d_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name) -{ - ProfBeginFunction(); - DI_Scope *scope = di_scope_open(); - U64 result = 0; - { - RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0); - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, name.str, name.size); - U64 entity_num = 0; - if(node != 0) - { - switch(node->match_count) - { - case 1: - { - entity_num = node->match_idx_or_idx_run_first + 1; - }break; - default: - { - U32 num = 0; - U32 *run = rdi_matches_from_map_node(rdi, node, &num); - if(num != 0) - { - entity_num = run[0]+1; - } - }break; - } - } - result = entity_num; - } - di_scope_close(scope); - ProfEnd(); - return result; -} - //- rjf: voff -> line info internal D_LineList diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 4e7b2f04..3773329e 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -397,7 +397,6 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL //- rjf: symbol -> voff lookups internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name); -internal U64 d_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name); //- rjf: voff -> line info internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff); From 90955ac2a8c7e8ca4aaac240cb55dd58f1e464f7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 18 May 2025 15:24:56 -0700 Subject: [PATCH 728/755] fix incorrect lock type in hs key closing path --- src/hash_store/hash_store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index fff4e2fa..55903601 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -285,7 +285,7 @@ hs_key_close(U128 key) U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count; HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx]; - OS_MutexScope(hash_stripe->rw_mutex) + OS_MutexScopeR(hash_stripe->rw_mutex) { for(HS_Node *n = hash_slot->first; n != 0; n = n->next) { From cb2f8aa766d5cb988f30ad5f683cab4378f27b1f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 18 May 2025 15:46:50 -0700 Subject: [PATCH 729/755] sketch out 'root cache' in hash store --- src/hash_store/hash_store.c | 21 +++------ src/hash_store/hash_store.h | 85 ++++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 55903601..baa6f3b6 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -58,20 +58,6 @@ hs_init(void) hs_shared->evictor_thread = os_thread_launch(hs_evictor_thread__entry_point, 0, 0); } -//////////////////////////////// -//~ rjf: Thread Context Initialization - -internal void -hs_tctx_ensure_inited(void) -{ - if(hs_tctx == 0) - { - Arena *arena = arena_alloc(); - hs_tctx = push_array(arena, HS_TCTX, 1); - hs_tctx->arena = arena; - } -} - //////////////////////////////// //~ rjf: Cache Submission @@ -203,7 +189,12 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) internal HS_Scope * hs_scope_open(void) { - hs_tctx_ensure_inited(); + if(hs_tctx == 0) + { + Arena *arena = arena_alloc(); + hs_tctx = push_array(arena, HS_TCTX, 1); + hs_tctx->arena = arena; + } HS_Scope *scope = hs_tctx->free_scope; if(scope) { diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index 3cbee4f5..e9f56998 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -4,9 +4,80 @@ #ifndef HASH_STORE_H #define HASH_STORE_H +//////////////////////////////// +//~ NOTE(rjf): Hash Store Notes (2025/05/18) +// +// The hash store is a general-purpose data cache. It offers three layers of +// caching: (a) content (hash of data), (b) key (unique identity correllated +// with history of hashes), and (c) root (bucket for many keys, manually +// allocated / deallocated). +// +// (a) The "content" level of cache access is a simply hash(data) -> data +// mapping. This bypasses all identity/key/root mechanisms and provides a +// way to just talk about unique (and deduplicated) blobs of data. +// +// (b) The "key" level of cache access is used to encode a history of hashes +// for some unique "identity", where the "identity" is a concept managed +// by the user. One example of an identity would be a particular address +// range inside of some process to which the debugger is attached. Another +// might be a range inside of some file. +// +// (c) The "root" level is to provide a top-level allocation/deallocation +// mechanism for a large set of keys. It also provides an extra level of +// key uniqueness. For instance, each process to which the debugger is +// attached might have its own root, and each key might correspond to a +// particular address range within that process. This way, when the +// process ends, all of its keys can be easily destroyed using a single +// deallocation of the root. +// +// The way this might be generally used inside of the debugger would be that +// some evaluation - let's say it's some variable `x` - is mapped (via debug +// info) to some address range. If `x` is a `char[4096]`, then it might map +// to some address range [&x, &x + 4096). This, together with the process +// within which `x` is evaluated, forms both a `root` (for the process) and +// a `key` (for the address range). Some asynchronous memory streaming system +// can then, together with the root and key, read memory for that range, then +// submit that data to the hash store, correllating with the root and key +// combo. + //////////////////////////////// //~ rjf: Cache Types +typedef struct HS_RootKeyChunkNode HS_RootKeyChunkNode; +struct HS_RootKeyChunkNode +{ + HS_RootKeyChunkNode *next; + U128 *v; + U64 count; + U64 cap; +}; + +typedef struct HS_RootKeyChunkList HS_RootKeyChunkList; +struct HS_RootKeyChunkList +{ + HS_RootKeyChunkNode *first; + HS_RootKeyChunkNode *last; + U64 chunk_count; + U64 total_count; +}; + +typedef struct HS_RootNode HS_RootNode; +struct HS_RootNode +{ + HS_RootNode *next; + HS_RootNode *prev; + Arena *arena; + U128 root; + HS_RootKeyChunkList keys; +}; + +typedef struct HS_RootSlot HS_RootSlot; +struct HS_RootSlot +{ + HS_RootNode *first; + HS_RootNode *last; +}; + #define HS_KEY_HASH_HISTORY_COUNT 64 #define HS_KEY_HASH_HISTORY_STRONG_REF_COUNT 2 @@ -105,6 +176,13 @@ struct HS_Shared HS_Stripe *key_stripes; HS_KeyNode **key_stripes_free_nodes; + // rjf: root cache + U64 root_slots_count; + U64 root_stripes_count; + HS_RootSlot *root_slots; + HS_Stripe root_stripes; + HS_RootNode **root_stripes_free_nodes; + // rjf: evictor thread OS_Handle evictor_thread; }; @@ -126,12 +204,7 @@ internal U128 hs_hash_from_data(String8 data); internal void hs_init(void); //////////////////////////////// -//~ rjf: Thread Context Initialization - -internal void hs_tctx_ensure_inited(void); - -//////////////////////////////// -//~ rjf: Cache Submission/Derefs +//~ rjf: Cache Submission internal U128 hs_submit_data(U128 key, Arena **data_arena, String8 data); From 8b4e2a099f9847dfbb59ecee6758aab0d0b4830e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 18 May 2025 16:00:18 -0700 Subject: [PATCH 730/755] hash store root allocation/deallocation --- src/hash_store/hash_store.c | 64 +++++++++++++++++++++++++++++++++++++ src/hash_store/hash_store.h | 9 +++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index baa6f3b6..20c26aee 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -55,9 +55,73 @@ hs_init(void) stripe->rw_mutex = os_rw_mutex_alloc(); stripe->cv = os_condition_variable_alloc(); } + hs_shared->root_slots_count = 4096; + hs_shared->root_stripes_count = Min(hs_shared->root_slots_count, os_get_system_info()->logical_processor_count); + hs_shared->root_slots = push_array(arena, HS_RootSlot, hs_shared->root_slots_count); + hs_shared->root_stripes = push_array(arena, HS_Stripe, hs_shared->root_stripes_count); + hs_shared->root_stripes_free_nodes = push_array(arena, HS_RootNode *, hs_shared->root_stripes_count); + for(U64 idx = 0; idx < hs_shared->root_stripes_count; idx += 1) + { + HS_Stripe *stripe = &hs_shared->root_stripes[idx]; + stripe->arena = arena_alloc(); + stripe->rw_mutex = os_rw_mutex_alloc(); + stripe->cv = os_condition_variable_alloc(); + } hs_shared->evictor_thread = os_thread_launch(hs_evictor_thread__entry_point, 0, 0); } +//////////////////////////////// +//~ rjf: Root Allocation/Deallocation + +internal U128 +hs_root_alloc(void) +{ + U128 root = {0}; + root.u64[1] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen); + U64 slot_idx = root.u64[1]%hs_shared->root_slots_count; + U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; + HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx]; + OS_MutexScopeW(stripe->rw_mutex) + { + HS_RootNode *node = hs_shared->root_stripes_free_nodes[stripe_idx]; + if(node != 0) + { + SLLStackPop(hs_shared->root_stripes_free_nodes[stripe_idx]); + } + else + { + node = push_array(stripe->arena, HS_RootNode, 1); + } + DLLPushBack(slot->first, slot->last, node); + node->root = root; + node->arena = arena_alloc(); + } + return root; +} + +internal void +hs_root_release(U128 root) +{ + U64 slot_idx = root.u64[1]%hs_shared->root_slots_count; + U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; + HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx]; + OS_MutexScopeW(stripe->rw_mutex) + { + for(HS_RootNode *n = slot->first; n != 0; n = n->next) + { + if(u128_match(n->root, root)) + { + DLLRemove(slot->first, slot->last, n); + arena_release(n->arena); + SLLStackPush(hs_shared->root_stripes_free_nodes[stripe_idx], n); + break; + } + } + } +} + //////////////////////////////// //~ rjf: Cache Submission diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index e9f56998..b626a0ba 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -180,8 +180,9 @@ struct HS_Shared U64 root_slots_count; U64 root_stripes_count; HS_RootSlot *root_slots; - HS_Stripe root_stripes; + HS_Stripe *root_stripes; HS_RootNode **root_stripes_free_nodes; + U64 root_id_gen; // rjf: evictor thread OS_Handle evictor_thread; @@ -203,6 +204,12 @@ internal U128 hs_hash_from_data(String8 data); internal void hs_init(void); +//////////////////////////////// +//~ rjf: Root Allocation/Deallocation + +internal U128 hs_root_alloc(void); +internal void hs_root_release(U128 root); + //////////////////////////////// //~ rjf: Cache Submission From b9e3df4cae5b328647f444877a5d1db604cd5e33 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 14:52:28 -0700 Subject: [PATCH 731/755] pass over hash store layer / all users, to switch to explicit 64-bit root alloc/dealloc, and 128-bit ids, for a full 192-bit hs key --- src/async/async.c | 7 + src/async/async.h | 2 + src/ctrl/ctrl_core.c | 251 +++++++++++++++++++++++------ src/ctrl/ctrl_core.h | 24 ++- src/dasm_cache/dasm_cache.c | 105 +++++------- src/dasm_cache/dasm_cache.h | 14 +- src/dbg_engine/dbg_engine_core.c | 2 +- src/dbg_engine/dbg_engine_core.h | 2 +- src/file_stream/file_stream.c | 246 +++++++++++++++------------- src/file_stream/file_stream.h | 16 +- src/geo_cache/geo_cache.c | 2 +- src/geo_cache/geo_cache.h | 2 +- src/hash_store/hash_store.c | 67 ++++++-- src/hash_store/hash_store.h | 58 +++++-- src/mutable_text/mutable_text.c | 11 +- src/mutable_text/mutable_text.h | 6 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/generated/raddbg.meta.h | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 35 ++-- src/raddbg/raddbg_core.h | 2 +- src/raddbg/raddbg_views.c | 8 +- src/text_cache/text_cache.c | 2 +- src/text_cache/text_cache.h | 2 +- src/texture_cache/texture_cache.c | 2 +- src/texture_cache/texture_cache.h | 2 +- 26 files changed, 567 insertions(+), 307 deletions(-) diff --git a/src/async/async.c b/src/async/async.c index 01a24100..2cf0f666 100644 --- a/src/async/async.c +++ b/src/async/async.c @@ -61,6 +61,7 @@ async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params work.output = params->output; work.semaphore = params->semaphore; work.completion_counter = params->completion_counter; + work.working_counter = params->working_counter; // rjf: loop; try to write into user -> writer ring buffer. if we're on a // worker thread, determine if we need to execute this task locally on this @@ -227,6 +228,12 @@ async_execute_work(ASYNC_Work work) { ins_atomic_u64_inc_eval(work.completion_counter); } + + //- rjf: decrement working counter + if(work.working_counter != 0) + { + ins_atomic_u64_dec_eval(work.working_counter); + } } //////////////////////////////// diff --git a/src/async/async.h b/src/async/async.h index f793f3d1..6d9f2b00 100644 --- a/src/async/async.h +++ b/src/async/async.h @@ -29,6 +29,7 @@ struct ASYNC_WorkParams void **output; OS_Handle semaphore; U64 *completion_counter; + U64 *working_counter; U64 endt_us; ASYNC_Priority priority; }; @@ -41,6 +42,7 @@ struct ASYNC_Work void **output; OS_Handle semaphore; U64 *completion_counter; + U64 *working_counter; }; //////////////////////////////// diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 8e92c34e..a12d31a1 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1577,8 +1577,188 @@ ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook) //////////////////////////////// //~ rjf: Process Memory Functions +//- rjf: process memory cache key reading + +internal HS_Key +ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale) +{ + CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; + + //- rjf: unpack process key + U64 process_hash = ctrl_hash_from_handle(process); + U64 process_slot_idx = process_hash%cache->slots_count; + U64 process_stripe_idx = process_slot_idx%cache->stripes_count; + CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx]; + CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx]; + + //- rjf: get the hash store root for this process; construct process node if it + // doesn't exist + HS_Root root = {0}; + { + B32 node_found = 0; + OS_MutexScopeR(process_stripe->rw_mutex) + { + for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->handle, process)) + { + node_found = 1; + root = n->root; + break; + } + } + } + if(!node_found) OS_MutexScopeW(process_stripe->rw_mutex) + { + for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->handle, process)) + { + node_found = 1; + root = n->root; + break; + } + } + if(!node_found) + { + Arena *node_arena = arena_alloc(); + CTRL_ProcessMemoryCacheNode *node = push_array(node_arena, CTRL_ProcessMemoryCacheNode, 1); + DLLPushBack(process_slot->first, process_slot->last, node); + node->arena = node_arena; + node->handle = process; + node->root = hs_root_alloc(); + node->range_hash_slots_count = 1024; + node->range_hash_slots = push_array(node_arena, CTRL_ProcessMemoryRangeHashSlot, node->range_hash_slots_count); + root = node->root; + } + } + } + + //- rjf: form ID for this process memory query + HS_ID id = {0}; + { + id.u128[0].u64[0] = vaddr_range.min & 0x00ffffffffffffffull; + id.u128[0].u64[1] = vaddr_range.max & 0x00ffffffffffffffull; + if(zero_terminated) + { + id.u128[0].u64[0] |= (1ull << 63); + } + } + U64 range_hash = hs_little_hash_from_data(str8_struct(&id)); + + //- rjf: form full key + HS_Key key = hs_key_make(root, id); + + //- rjf: loop: try to look for current results, request if not there, wait if we can, repeat until we can't + U64 mem_gen = ctrl_mem_gen(); + B32 key_is_stale = 0; + for(;;) + { + //- rjf: step 1: [read-only] try to look for current results for key's ID + B32 id_exists = 0; + B32 id_stale = 0; + OS_MutexScopeR(process_stripe->rw_mutex) + { + for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) + { + if(ctrl_handle_match(process_n->handle, process)) + { + U64 range_slot_idx = range_hash%process_n->range_hash_slots_count; + CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx]; + for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next) + { + if(hs_id_match(n->id, id)) + { + id_exists = 1; + id_stale = (n->mem_gen < mem_gen); + goto end_fast_lookup; + } + } + } + } + end_fast_lookup:; + } + key_is_stale = id_stale; + + //- rjf: step 2: if the ID exists and is not stale, then we're done; + // the hash store contains the most up-to-date representation of the + // process memory for this key. + if(id_exists && !id_stale) + { + break; + } + + //- rjf: step 3: if the ID does not exist in the process' cache, then we + // need to build a node for it. if that, or if the ID is stale, then also + // request that that range is streamed. + if(!id_exists || (id_exists && id_stale)) + { + B32 node_needs_stream = 0; + U64 *node_working_count = 0; + OS_MutexScopeW(process_stripe->rw_mutex) + { + for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) + { + if(ctrl_handle_match(process_n->handle, process)) + { + U64 range_slot_idx = range_hash%process_n->range_hash_slots_count; + CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx]; + CTRL_ProcessMemoryRangeHashNode *range_n = 0; + for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next) + { + if(hs_id_match(n->id, id)) + { + range_n = n; + break; + } + } + if(range_n == 0) + { + range_n = push_array(process_n->arena, CTRL_ProcessMemoryRangeHashNode, 1); + SLLQueuePush(range_slot->first, range_slot->last, range_n); + range_n->vaddr_range = vaddr_range; + range_n->zero_terminated = zero_terminated; + range_n->id = id; + range_n->working_count += 1; + node_needs_stream = 1; + } + else + { + node_needs_stream = (range_n->mem_gen < mem_gen); + } + node_working_count = &range_n->working_count; + break; + } + } + } + if(node_needs_stream) + { + ctrl_u2ms_enqueue_req(key, process, vaddr_range, zero_terminated, max_U64); + async_push_work(ctrl_mem_stream_work, .working_counter = node_working_count); + } + } + + //- rjf: step 4: if we have no time to wait, then abort; otherwise, + // wait on this process' stripe + if(os_now_microseconds() >= endt_us) + { + break; + } + else OS_MutexScopeR(process_stripe->rw_mutex) + { + os_condition_variable_wait_rw_r(process_stripe->cv, process_stripe->rw_mutex, endt_us); + } + } + if(out_is_stale) + { + *out_is_stale = key_is_stale; + } + return key; +} + //- rjf: process memory cache interaction +#if 0 // TODO(rjf): @hs internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated) { @@ -1758,9 +1938,11 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3 ProfEnd(); return result; } +#endif //- rjf: bundled key/stream helper +#if 0 // TODO(rjf): @hs internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated) { @@ -1768,6 +1950,7 @@ ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, ctrl_stored_hash_from_process_vaddr_range(process, range, zero_terminated, 0, 0); return key; } +#endif //- rjf: process memory cache reading helpers @@ -1798,9 +1981,9 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn for(U64 page_idx = 0; page_idx < page_count; page_idx += 1) { U64 page_base_vaddr = page_range.min + page_idx*page_size; - U128 page_key = ctrl_calc_hash_store_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0); B32 page_is_stale = 0; - U128 page_hash = ctrl_stored_hash_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, &page_is_stale, endt_us); + HS_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale); + U128 page_hash = hs_hash_from_key(page_key, 0); U128 page_last_hash = hs_hash_from_key(page_key, 1); result.stale = (result.stale || page_is_stale); page_hashes[page_idx] = page_hash; @@ -6542,16 +6725,17 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: user -> memory stream communication internal B32 -ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us) +ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us) { B32 good = 0; OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos; U64 available_size = ctrl_state->u2ms_ring_size-unconsumed_size; - if(available_size >= sizeof(process)+sizeof(vaddr_range)+sizeof(zero_terminated)) + if(available_size >= sizeof(key)+sizeof(process)+sizeof(vaddr_range)+sizeof(zero_terminated)) { good = 1; + ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &key); ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &process); ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &vaddr_range); ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &zero_terminated); @@ -6565,13 +6749,14 @@ ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_termina } internal void -ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated) +ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated) { OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos; - if(unconsumed_size >= sizeof(*out_process)+sizeof(*out_vaddr_range)+sizeof(*out_zero_terminated)) + if(unconsumed_size >= sizeof(*out_key)+sizeof(*out_process)+sizeof(*out_vaddr_range)+sizeof(*out_zero_terminated)) { + ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_key); ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_process); ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_vaddr_range); ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_zero_terminated); @@ -6590,50 +6775,29 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; //- rjf: unpack next request + HS_Key key = {0}; CTRL_Handle process = {0}; Rng1U64 vaddr_range = {0}; B32 zero_terminated = 0; - ctrl_u2ms_dequeue_req(&process, &vaddr_range, &zero_terminated); - U128 key = ctrl_calc_hash_store_key_from_process_vaddr_range(process, vaddr_range, zero_terminated); + ctrl_u2ms_dequeue_req(&key, &process, &vaddr_range, &zero_terminated); ProfBegin("memory stream request"); - //- rjf: unpack process memory cache key - U64 process_hash = ctrl_hash_from_string(str8_struct(&process)); + //- rjf: unpack process key + U64 process_hash = ctrl_hash_from_handle(process); U64 process_slot_idx = process_hash%cache->slots_count; U64 process_stripe_idx = process_slot_idx%cache->stripes_count; CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx]; CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx]; //- rjf: unpack address range hash cache key - U64 range_hash = ctrl_hash_from_string(str8_struct(&vaddr_range)); + U64 range_hash = hs_little_hash_from_data(str8_struct(&key.id)); - //- rjf: take task - B32 got_task = 0; - U64 preexisting_mem_gen = 0; - U128 preexisting_hash = {0}; - Rng1U64 vaddr_range_clamped = {0}; - OS_MutexScopeW(process_stripe->rw_mutex) + //- rjf: clamp vaddr range + Rng1U64 vaddr_range_clamped = vaddr_range; { - for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, process)) - { - U64 range_slot_idx = range_hash%n->range_hash_slots_count; - CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; - for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) - { - if(MemoryMatchStruct(&range_n->vaddr_range, &vaddr_range) && range_n->zero_terminated == zero_terminated) - { - got_task = !ins_atomic_u32_eval_cond_assign(&range_n->is_taken, 1, 0); - preexisting_mem_gen = range_n->mem_gen; - preexisting_hash = range_n->hash; - vaddr_range_clamped = range_n->vaddr_range_clamped; - goto take_task__break_all; - } - } - } - } - take_task__break_all:; + vaddr_range_clamped.max = Max(vaddr_range_clamped.max, vaddr_range_clamped.min); + U64 max_size_cap = Min(max_U64-vaddr_range_clamped.min, GB(1)); + vaddr_range_clamped.max = Min(vaddr_range_clamped.max, vaddr_range_clamped.min+max_size_cap); } //- rjf: task was taken -> read memory @@ -6641,9 +6805,8 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) Arena *range_arena = 0; void *range_base = 0; U64 zero_terminated_size = 0; - U64 pre_read_mem_gen = dmn_mem_gen(); + U64 pre_read_mem_gen = ctrl_mem_gen(); U64 post_read_mem_gen = 0; - if(got_task && pre_read_mem_gen != preexisting_mem_gen) { range_size = dim_1u64(vaddr_range_clamped); U64 page_size = os_get_system_info()->page_size; @@ -6708,7 +6871,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) //- rjf: read successful -> submit to hash store U128 hash = {0}; - if(got_task && range_base != 0 && pre_read_mem_gen == post_read_mem_gen) + if(range_base != 0 && pre_read_mem_gen == post_read_mem_gen) { hash = hs_submit_data(key, &range_arena, str8((U8*)range_base, zero_terminated_size)); } @@ -6717,8 +6880,8 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) arena_release(range_arena); } - //- rjf: commit hash to cache - if(got_task) OS_MutexScopeW(process_stripe->rw_mutex) + //- rjf: commit new info to cache + OS_MutexScopeW(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) { @@ -6728,14 +6891,12 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) { - if(MemoryMatchStruct(&range_n->vaddr_range, &vaddr_range) && range_n->zero_terminated == zero_terminated) + if(hs_id_match(range_n->id, key.id)) { if(!u128_match(u128_zero(), hash)) { - range_n->hash = hash; range_n->mem_gen = post_read_mem_gen; } - ins_atomic_u32_eval_assign(&range_n->is_taken, 0); goto commit__break_all; } } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 3b2e1405..337555bd 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -505,13 +505,19 @@ typedef struct CTRL_ProcessMemoryRangeHashNode CTRL_ProcessMemoryRangeHashNode; struct CTRL_ProcessMemoryRangeHashNode { CTRL_ProcessMemoryRangeHashNode *next; + + // rjf: key Rng1U64 vaddr_range; B32 zero_terminated; - Rng1U64 vaddr_range_clamped; - U128 hash; + HS_ID id; + + // rjf: staleness info U64 mem_gen; + + // rjf: metadata + U64 working_count; U64 last_time_requested_us; - B32 is_taken; + U64 last_user_clock_idx_touched; }; typedef struct CTRL_ProcessMemoryRangeHashSlot CTRL_ProcessMemoryRangeHashSlot; @@ -528,6 +534,7 @@ struct CTRL_ProcessMemoryCacheNode CTRL_ProcessMemoryCacheNode *prev; Arena *arena; CTRL_Handle handle; + HS_Root root; U64 range_hash_slots_count; CTRL_ProcessMemoryRangeHashSlot *range_hash_slots; }; @@ -983,12 +990,19 @@ internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook); //////////////////////////////// //~ rjf: Process Memory Functions +//- rjf: process memory cache key reading +internal HS_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale); + //- rjf: process memory cache interaction +#if 0 // TODO(rjf): @hs internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us); +#endif //- rjf: bundled key/stream helper +#if 0 // TODO(rjf): @hs internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); +#endif //- rjf: process memory cache reading helpers internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); @@ -1114,8 +1128,8 @@ internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); //~ rjf: Asynchronous Memory Streaming Functions //- rjf: user -> memory stream communication -internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); -internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated); +internal B32 ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); +internal void ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated); //- rjf: entry point ASYNC_WORK_DEF(ctrl_mem_stream_work); diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 3c937b37..26d6df9f 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -345,10 +345,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) DASM_Info info = {0}; if(!u128_match(hash, u128_zero())) { + //- rjf: unpack hash U64 slot_idx = hash.u64[1]%dasm_shared->slots_count; U64 stripe_idx = slot_idx%dasm_shared->stripes_count; DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; + + //- rjf: try to get existing results B32 found = 0; OS_MutexScopeR(stripe->rw_mutex) { @@ -363,9 +366,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) } } } - B32 node_is_new = 0; + + //- rjf: miss -> kick off work to fill cache if(!found) { + B32 node_is_new = 0; + U64 *node_working_count = 0; + HS_Root root = {0}; OS_MutexScopeW(stripe->rw_mutex) { DASM_Node *node = 0; @@ -379,16 +386,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) } if(node == 0) { - LogInfoNamedBlockF("dasm_new_node") - { - log_infof("hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]); - log_infof("vaddr: 0x%I64x\n", params->vaddr); - log_infof("arch: %S\n", string_from_arch(params->arch)); - log_infof("style_flags: 0x%x\n", params->style_flags); - log_infof("syntax: %i\n", params->syntax); - log_infof("base_vaddr: 0x%I64x\n", params->base_vaddr); - log_infof("dbgi_key: [%S 0x%I64x]\n", params->dbgi_key.path, params->dbgi_key.min_timestamp); - } + // rjf: allocate node node = stripe->free_node; if(node) { @@ -399,26 +397,34 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) node = push_array_no_zero(stripe->arena, DASM_Node, 1); } MemoryZeroStruct(node); + + // rjf: fill node DLLPushBack(slot->first, slot->last, node); node->hash = hash; MemoryCopyStruct(&node->params, params); + node->root = hs_root_alloc(); // TODO(rjf): need to make this releasable - currently all exe_paths just leak node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key); + + // rjf: gather work kickoff params node_is_new = 1; + ins_atomic_u64_inc_eval(&node->working_count); + node_working_count = &node->working_count; + root = node->root; } } - } - if(node_is_new) - { - dasm_u2p_enqueue_req(hash, params, max_U64); - async_push_work(dasm_parse_work); + if(node_is_new) + { + dasm_u2p_enqueue_req(root, hash, params, max_U64); + async_push_work(dasm_parse_work, .working_counter = node_working_count); + } } } return info; } internal DASM_Info -dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out) +dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out) { DASM_Info result = {0}; for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) @@ -441,16 +447,17 @@ dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 //~ rjf: Parse Threads internal B32 -dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us) +dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us) { B32 good = 0; OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; U64 available_size = dasm_shared->u2p_ring_size - unconsumed_size; - if(available_size >= sizeof(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64)) + if(available_size >= sizeof(root)+sizeof(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64)) { good = 1; + dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &root); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &hash); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->vaddr); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->arch); @@ -476,13 +483,14 @@ dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us) } internal void -dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out) +dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out) { OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+sizeof(U64)) { + dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, root_out); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, hash_out); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->vaddr); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->arch); @@ -509,9 +517,10 @@ ASYNC_WORK_DEF(dasm_parse_work) TXT_Scope *txt_scope = txt_scope_open(); //- rjf: get next request + HS_Root root = {0}; U128 hash = {0}; DASM_Params params = {0}; - dasm_u2p_dequeue_req(scratch.arena, &hash, ¶ms); + dasm_u2p_dequeue_req(scratch.arena, &root, &hash, ¶ms); U64 change_gen = fs_change_gen(); //- rjf: unpack hash @@ -520,38 +529,19 @@ ASYNC_WORK_DEF(dasm_parse_work) DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; - //- rjf: take task - B32 got_task = 0; - OS_MutexScopeR(stripe->rw_mutex) - { - for(DASM_Node *n = slot->first; n != 0; n = n->next) - { - if(u128_match(n->hash, hash) && dasm_params_match(&n->params, ¶ms)) - { - got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0); - break; - } - } - } - //- rjf: get dbg info RDI_Parsed *rdi = &rdi_parsed_nil; - if(got_task && params.dbgi_key.path.size != 0) + if(params.dbgi_key.path.size != 0) { rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, max_U64); } //- rjf: hash -> data - String8 data = {0}; - if(got_task) - { - data = hs_data_from_hash(hs_scope, hash); - } + String8 data = hs_data_from_hash(hs_scope, hash); //- rjf: data * arch * addr * dbg -> decode artifacts DASM_LineChunkList line_list = {0}; String8List inst_strings = {0}; - if(got_task) { switch(params.arch) { @@ -621,7 +611,7 @@ ASYNC_WORK_DEF(dasm_parse_work) { // TODO(rjf): need redirection path - this may map to a different path on the local machine, // need frontend to communicate path remapping info to this layer - U128 key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64)); + HS_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0); TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path); U64 endt_us = max_U64; U128 hash = {0}; @@ -712,7 +702,6 @@ ASYNC_WORK_DEF(dasm_parse_work) //- rjf: artifacts -> value bundle Arena *info_arena = 0; DASM_Info info = {0}; - if(got_task) { //- rjf: produce joined text Arena *text_arena = arena_alloc(); @@ -721,21 +710,7 @@ ASYNC_WORK_DEF(dasm_parse_work) String8 text = str8_list_join(text_arena, &inst_strings, &text_join); //- rjf: produce unique key for this disassembly's text - U128 text_key = {0}; - { - U64 hash_data[] = - { - hash.u64[0], - hash.u64[1], - params.vaddr, - (U64)params.arch, - (U64)params.style_flags, - (U64)params.syntax, - (U64)rdi, - 0x4d534144, - }; - text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data))); - } + HS_Key text_key = hs_key_make(root, hs_id_make(0, 0)); //- rjf: submit text data to hash store U128 text_hash = hs_submit_data(text_key, &text_arena, text); @@ -747,7 +722,7 @@ ASYNC_WORK_DEF(dasm_parse_work) } //- rjf: commit results to cache - if(got_task) OS_MutexScopeW(stripe->rw_mutex) + OS_MutexScopeW(stripe->rw_mutex) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -763,8 +738,6 @@ ASYNC_WORK_DEF(dasm_parse_work) { n->change_gen = 0; } - ins_atomic_u32_eval_assign(&n->is_working, 0); - ins_atomic_u64_inc_eval(&n->load_count); break; } } @@ -807,8 +780,7 @@ dasm_evictor_detector_thread__entry_point(void *p) if(n->scope_ref_count == 0 && n->last_time_touched_us+evict_threshold_us <= check_time_us && n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && - n->load_count != 0 && - n->is_working == 0) + ins_atomic_u64_eval(&n->working_count) == 0) { slot_has_work = 1; break; @@ -830,8 +802,7 @@ dasm_evictor_detector_thread__entry_point(void *p) if(n->scope_ref_count == 0 && n->last_time_touched_us+evict_threshold_us <= check_time_us && n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && - n->load_count != 0 && - n->is_working == 0) + ins_atomic_u64_eval(&n->working_count) == 0) { DLLRemove(slot->first, slot->last, n); if(n->info_arena != 0) @@ -844,7 +815,7 @@ dasm_evictor_detector_thread__entry_point(void *p) n->last_time_requested_us+retry_threshold_us <= check_time_us && n->last_user_clock_idx_requested+retry_threshold_user_clocks <= check_time_user_clocks) { - if(dasm_u2p_enqueue_req(n->hash, &n->params, max_U64)) + if(dasm_u2p_enqueue_req(n->root, n->hash, &n->params, max_U64)) { async_push_work(dasm_parse_work); n->last_time_requested_us = os_now_microseconds(); diff --git a/src/dasm_cache/dasm_cache.h b/src/dasm_cache/dasm_cache.h index 2d670111..25a222fe 100644 --- a/src/dasm_cache/dasm_cache.h +++ b/src/dasm_cache/dasm_cache.h @@ -159,7 +159,7 @@ struct DASM_Result typedef struct DASM_Info DASM_Info; struct DASM_Info { - U128 text_key; + HS_Key text_key; DASM_LineArray lines; }; @@ -177,6 +177,9 @@ struct DASM_Node U128 hash; DASM_Params params; + // rjf: root + HS_Root root; + // rjf: generations U64 change_gen; @@ -185,11 +188,10 @@ struct DASM_Node DASM_Info info; // rjf: metadata - B32 is_working; + U64 working_count; U64 scope_ref_count; U64 last_time_touched_us; U64 last_user_clock_idx_touched; - U64 load_count; U64 last_time_requested_us; U64 last_user_clock_idx_requested; }; @@ -309,13 +311,13 @@ internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_No //~ rjf: Cache Lookups internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params); -internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out); +internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out); //////////////////////////////// //~ rjf: Parse Threads -internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us); -internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out); +internal B32 dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us); +internal void dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out); ASYNC_WORK_DEF(dasm_parse_work); //////////////////////////////// diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index e9888f38..5c90af76 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1443,7 +1443,7 @@ d_init(void) d_state = push_array(arena, D_State, 1); d_state->arena = arena; d_state->cmds_arena = arena_alloc(); - d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key")); + d_state->output_log_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0)); hs_submit_data(d_state->output_log_key, 0, str8_zero()); d_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc(); d_state->ctrl_stop_arena = arena_alloc(); diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 3773329e..16d5101b 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -312,7 +312,7 @@ struct D_State D_CmdList cmds; // rjf: output log key - U128 output_log_key; + HS_Key output_log_key; // rjf: per-run caches D_UnwindCache unwind_cache; diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index 3229a321..feb6d815 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -71,125 +71,151 @@ fs_change_gen(void) //////////////////////////////// //~ rjf: Cache Interaction -internal U128 -fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us) +internal HS_Key +fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) { Temp scratch = scratch_begin(0, 0); //- rjf: unpack args path = path_normalized_from_string(scratch.arena, path); - U128 key = fs_big_hash_from_string_range(path, range); + U64 path_little_hash = fs_little_hash_from_string(path); + U64 path_slot_idx = path_little_hash%fs_shared->slots_count; + U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count; + FS_Slot *path_slot = &fs_shared->slots[path_slot_idx]; + FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx]; - //- rjf: loop through key -> hash history; obtain most recent hash for this key - U128 result = {0}; - for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) + //- rjf: get root for this path + HS_Root root = {0}; + OS_MutexScopeR(path_stripe->rw_mutex) { - result = hs_hash_from_key(key, rewind_idx); - - //- rjf: nonzero hash -> got valid results, return - if(!u128_match(result, u128_zero())) + B32 node_found = 0; + for(FS_Node *n = path_slot->first; n != 0; n = n->next) { - break; - } - - //- rjf: zero hash, not rewound? -> send new stream request if needed - else if(u128_match(result, u128_zero()) && rewind_idx == 0) - { - // rjf: unpack path cache info - U64 path_little_hash = fs_little_hash_from_string(path); - U64 path_slot_idx = path_little_hash%fs_shared->slots_count; - U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count; - FS_Slot *path_slot = &fs_shared->slots[path_slot_idx]; - FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx]; - - // rjf: loop: request, check for results, return until we can't - OS_MutexScopeW(path_stripe->rw_mutex) for(;;) + if(str8_match(n->path, path, 0)) { - // rjf: path -> node - FS_Node *node = 0; - for(FS_Node *n = path_slot->first; n != 0; n = n->next) - { - if(str8_match(path, n->path, 0)) - { - node = n; - break; - } - } - - // rjf: node does not exist? -> create & store - if(node == 0) - { - node = push_array(path_stripe->arena, FS_Node, 1); - SLLQueuePush(path_slot->first, path_slot->last, node); - node->path = push_str8_copy(path_stripe->arena, path); - node->slots_count = 64; - node->slots = push_array(path_stripe->arena, FS_RangeSlot, node->slots_count); - } - - // rjf: range -> node - U64 range_hash = fs_little_hash_from_string(str8_struct(&range)); - U64 range_slot_idx = range_hash%node->slots_count; - FS_RangeSlot *range_slot = &node->slots[range_slot_idx]; - FS_RangeNode *range_node = 0; - for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next) - { - if(MemoryMatchStruct(&n->range, &range)) - { - range_node = n; - break; - } - } - - // rjf: range node does not exist? create & store - if(range_node == 0) - { - range_node = push_array(path_stripe->arena, FS_RangeNode, 1); - SLLQueuePush(range_slot->first, range_slot->last, range_node); - range_node->range = range; - } - - // rjf: try to send stream request - if((ins_atomic_u64_eval(&range_node->request_count) == ins_atomic_u64_eval(&range_node->completion_count) || - ins_atomic_u64_eval(&range_node->last_time_requested_us)+100000 < os_now_microseconds()) && - fs_u2s_enqueue_req(range, path, endt_us)) - { - ins_atomic_u64_eval_assign(&range_node->last_time_requested_us, os_now_microseconds()); - ins_atomic_u64_inc_eval(&range_node->request_count); - DeferLoop(os_rw_mutex_drop_w(path_stripe->rw_mutex), os_rw_mutex_take_w(path_stripe->rw_mutex)) - { - async_push_work(fs_stream_work, .completion_counter = &range_node->completion_count); - } - } - - // rjf: try to reobtain results - result = hs_hash_from_key(key, 0); - - // rjf: have time to wait? -> wait on this stripe; otherwise exit - if(u128_match(result, u128_zero()) && os_now_microseconds() <= endt_us) - { - os_condition_variable_wait_rw_w(path_stripe->cv, path_stripe->rw_mutex, endt_us); - } - else + node_found = 1; + root = n->root; + break; + } + } + if(!node_found) OS_MutexScopeRWPromote(path_stripe->rw_mutex) + { + B32 node_found = 0; + for(FS_Node *n = path_slot->first; n != 0; n = n->next) + { + if(str8_match(n->path, path, 0)) { + node_found = 1; + root = n->root; break; } } + if(!node_found) + { + FS_Node *node = push_array(path_stripe->arena, FS_Node, 1); + SLLQueuePush(path_slot->first, path_slot->last, node); + node->path = push_str8_copy(path_stripe->arena, path); + node->root = hs_root_alloc(); + node->slots_count = 64; + node->slots = push_array(path_stripe->arena, FS_RangeSlot, node->slots_count); + root = node->root; + } + } + } + + //- rjf: build a key for this path/range combo + HS_Key key = hs_key_make(root, hs_id_make(range.min, range.max)); + + //- rjf: if the most recent hash for this key is zero, then try to submit a new + // request to pull it in. + if(u128_match(hs_hash_from_key(key, 0), u128_zero())) + { + // rjf: loop: request, check for results, return until we can't + OS_MutexScopeW(path_stripe->rw_mutex) for(;;) + { + // rjf: path -> node + FS_Node *node = 0; + for(FS_Node *n = path_slot->first; n != 0; n = n->next) + { + if(str8_match(path, n->path, 0)) + { + node = n; + break; + } + } + + // rjf: no node? -> weird case, node should've been made at this point. + if(node == 0) + { + break; + } + + // rjf: range -> node + U64 range_hash = fs_little_hash_from_string(str8_struct(&key.id)); + U64 range_slot_idx = range_hash%node->slots_count; + FS_RangeSlot *range_slot = &node->slots[range_slot_idx]; + FS_RangeNode *range_node = 0; + for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next) + { + if(hs_id_match(n->id, key.id)) + { + range_node = n; + break; + } + } + + // rjf: range node does not exist? create & store + if(range_node == 0) + { + range_node = push_array(path_stripe->arena, FS_RangeNode, 1); + SLLQueuePush(range_slot->first, range_slot->last, range_node); + range_node->id = key.id; + } + + // rjf: try to send stream request + if(ins_atomic_u64_eval(&range_node->working_count) == 0 && + fs_u2s_enqueue_req(key, range, path, endt_us)) + { + ins_atomic_u64_inc_eval(&range_node->working_count); + DeferLoop(os_rw_mutex_drop_w(path_stripe->rw_mutex), os_rw_mutex_take_w(path_stripe->rw_mutex)) + { + async_push_work(fs_stream_work, .working_counter = &range_node->working_count); + } + } + + // rjf: have time to wait? -> wait on this stripe; otherwise exit + B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero()); + if(!have_results && os_now_microseconds() < endt_us) + { + os_condition_variable_wait_rw_w(path_stripe->cv, path_stripe->rw_mutex, endt_us); + } + else + { + break; + } } } scratch_end(scratch); - return result; + return key; } internal U128 -fs_key_from_path_range(String8 path, Rng1U64 range) +fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us) { - Temp scratch = scratch_begin(0, 0); - String8 path_normalized = path_normalized_from_string(scratch.arena, path); - U128 key = fs_big_hash_from_string_range(path_normalized, range); - fs_hash_from_path_range(path_normalized, range, 0); - scratch_end(scratch); - return key; + U128 hash = {0}; + { + HS_Key key = fs_key_from_path_range(path, range, endt_us); + for EachIndex(rewind_idx, HS_KEY_HASH_HISTORY_COUNT) + { + hash = hs_hash_from_key(key, rewind_idx); + if(!u128_match(hash, u128_zero())) + { + break; + } + } + } + return hash; } internal FileProperties @@ -222,7 +248,7 @@ fs_properties_from_path(String8 path) //~ rjf: Streamer Threads internal B32 -fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us) +fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us) { B32 result = 0; path.size = Min(path.size, fs_shared->u2s_ring_size); @@ -230,10 +256,11 @@ fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us) { U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos; U64 available_size = fs_shared->u2s_ring_size - unconsumed_size; - U64 needed_size = sizeof(range.min) + sizeof(range.max) + sizeof(path.size) + path.size; + U64 needed_size = sizeof(key) + sizeof(range.min) + sizeof(range.max) + sizeof(path.size) + path.size; if(available_size >= needed_size) { result = 1; + fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &key); fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.min); fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.max); fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &path.size); @@ -250,13 +277,14 @@ fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us) } internal void -fs_u2s_dequeue_req(Arena *arena, Rng1U64 *range_out, String8 *path_out) +fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out) { OS_MutexScope(fs_shared->u2s_ring_mutex) for(;;) { U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos; - if(unconsumed_size >= sizeof(U64)) + if(unconsumed_size >= sizeof(*key_out) + sizeof(U64)*2 + sizeof(U64)) { + fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, key_out); fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->min); fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->max); fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &path_out->size); @@ -275,12 +303,12 @@ ASYNC_WORK_DEF(fs_stream_work) Temp scratch = scratch_begin(0, 0); //- rjf: get next request + HS_Key key = {0}; Rng1U64 range = {0}; String8 path = {0}; - fs_u2s_dequeue_req(scratch.arena, &range, &path); + fs_u2s_dequeue_req(scratch.arena, &key, &range, &path); //- rjf: unpack request - U128 key = fs_big_hash_from_string_range(path, range); U64 path_hash = fs_little_hash_from_string(path); U64 path_slot_idx = path_hash%fs_shared->slots_count; U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count; @@ -387,12 +415,12 @@ fs_detector_thread__entry_point(void *p) range_n != 0; range_n = range_n->next) { - if(ins_atomic_u64_eval(&range_n->request_count) == ins_atomic_u64_eval(&range_n->completion_count) && - fs_u2s_enqueue_req(range_n->range, n->path, os_now_microseconds()+100000)) + HS_Key key = hs_key_make(n->root, range_n->id); + if(ins_atomic_u64_eval(&range_n->working_count) == 0 && + fs_u2s_enqueue_req(key, r1u64(key.id.u128[0].u64[0], key.id.u128[0].u64[1]), n->path, os_now_microseconds()+100000)) { - ins_atomic_u64_eval_assign(&range_n->last_time_requested_us, os_now_microseconds()); - ins_atomic_u64_inc_eval(&range_n->request_count); - async_push_work(fs_stream_work, .completion_counter = &range_n->completion_count); + ins_atomic_u64_inc_eval(&range_n->working_count); + async_push_work(fs_stream_work, .working_counter = &range_n->working_count); } } } diff --git a/src/file_stream/file_stream.h b/src/file_stream/file_stream.h index d1ec870b..a0ede57c 100644 --- a/src/file_stream/file_stream.h +++ b/src/file_stream/file_stream.h @@ -11,10 +11,8 @@ typedef struct FS_RangeNode FS_RangeNode; struct FS_RangeNode { FS_RangeNode *next; - Rng1U64 range; - U64 request_count; - U64 completion_count; - U64 last_time_requested_us; + HS_ID id; + U64 working_count; }; typedef struct FS_RangeSlot FS_RangeSlot; @@ -33,6 +31,9 @@ struct FS_Node String8 path; FileProperties props; + // rjf: hash store root + HS_Root root; + // rjf: sub-table of per-requested-file-range info U64 slots_count; FS_RangeSlot *slots; @@ -104,16 +105,15 @@ internal U64 fs_change_gen(void); //////////////////////////////// //~ rjf: Cache Interaction +internal HS_Key fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us); internal U128 fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us); -internal U128 fs_key_from_path_range(String8 path, Rng1U64 range); - internal FileProperties fs_properties_from_path(String8 path); //////////////////////////////// //~ rjf: Streaming Work -internal B32 fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us); -internal void fs_u2s_dequeue_req(Arena *arena, Rng1U64 *range_out, String8 *path_out); +internal B32 fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us); +internal void fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out); ASYNC_WORK_DEF(fs_stream_work); //////////////////////////////// diff --git a/src/geo_cache/geo_cache.c b/src/geo_cache/geo_cache.c index 1af64fec..dd7fa2e0 100644 --- a/src/geo_cache/geo_cache.c +++ b/src/geo_cache/geo_cache.c @@ -181,7 +181,7 @@ geo_buffer_from_hash(GEO_Scope *scope, U128 hash) } internal R_Handle -geo_buffer_from_key(GEO_Scope *scope, U128 key) +geo_buffer_from_key(GEO_Scope *scope, HS_Key key) { R_Handle handle = {0}; for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) diff --git a/src/geo_cache/geo_cache.h b/src/geo_cache/geo_cache.h index 230d059e..d343be8e 100644 --- a/src/geo_cache/geo_cache.h +++ b/src/geo_cache/geo_cache.h @@ -118,7 +118,7 @@ internal void geo_scope_touch_node__stripe_r_guarded(GEO_Scope *scope, GEO_Node //~ rjf: Cache Lookups internal R_Handle geo_buffer_from_hash(GEO_Scope *scope, U128 hash); -internal R_Handle geo_buffer_from_key(GEO_Scope *scope, U128 key); +internal R_Handle geo_buffer_from_key(GEO_Scope *scope, HS_Key key); //////////////////////////////// //~ rjf: Transfer Threads diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 20c26aee..297f532f 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -13,6 +13,13 @@ # include "third_party/xxHash/xxhash.h" #endif +internal U64 +hs_little_hash_from_data(String8 data) +{ + U64 result = XXH3_64bits(data.str, data.size); + return result; +} + internal U128 hs_hash_from_data(String8 data) { @@ -22,6 +29,35 @@ hs_hash_from_data(String8 data) return u128; } +internal HS_ID +hs_id_make(U64 u64_0, U64 u64_1) +{ + HS_ID id; + id.u128[0].u64[0] = u64_0; + id.u128[0].u64[1] = u64_1; + return id; +} + +internal B32 +hs_id_match(HS_ID a, HS_ID b) +{ + B32 result = MemoryMatchStruct(&a, &b); + return result; +} + +internal HS_Key +hs_key_make(HS_Root root, HS_ID id) +{ + HS_Key key = {root, 0, id}; + return key; +} + +internal B32 +hs_key_match(HS_Key a, HS_Key b) +{ + return (MemoryMatchStruct(&a.root, &b.root) && hs_id_match(a.id, b.id)); +} + //////////////////////////////// //~ rjf: Main Layer Initialization @@ -73,11 +109,11 @@ hs_init(void) //////////////////////////////// //~ rjf: Root Allocation/Deallocation -internal U128 +internal HS_Root hs_root_alloc(void) { - U128 root = {0}; - root.u64[1] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen); + HS_Root root = {0}; + root.u64[0] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen); U64 slot_idx = root.u64[1]%hs_shared->root_slots_count; U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; @@ -101,7 +137,7 @@ hs_root_alloc(void) } internal void -hs_root_release(U128 root) +hs_root_release(HS_Root root) { U64 slot_idx = root.u64[1]%hs_shared->root_slots_count; U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; @@ -111,7 +147,7 @@ hs_root_release(U128 root) { for(HS_RootNode *n = slot->first; n != 0; n = n->next) { - if(u128_match(n->root, root)) + if(MemoryMatchStruct(&root, &n->root)) { DLLRemove(slot->first, slot->last, n); arena_release(n->arena); @@ -126,9 +162,10 @@ hs_root_release(U128 root) //~ rjf: Cache Submission internal U128 -hs_submit_data(U128 key, Arena **data_arena, String8 data) +hs_submit_data(HS_Key key, Arena **data_arena, String8 data) { - U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count; + U64 key_hash = hs_little_hash_from_data(str8_struct(&key)); + U64 key_slot_idx = key_hash%hs_shared->key_slots_count; U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; @@ -192,7 +229,7 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) HS_KeyNode *key_node = 0; for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { - if(u128_match(n->key, key)) + if(hs_key_match(n->key, key)) { key_node = n; break; @@ -321,9 +358,10 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) //~ rjf: Key Closing internal void -hs_key_close(U128 key) +hs_key_close(HS_Key key) { - U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count; + U64 key_hash = hs_little_hash_from_data(str8_struct(&key)); + U64 key_slot_idx = key_hash%hs_shared->key_slots_count; U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; @@ -331,7 +369,7 @@ hs_key_close(U128 key) { for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { - if(u128_match(n->key, key)) + if(hs_key_match(n->key, key)) { for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1) { @@ -407,10 +445,11 @@ hs_hash_downstream_dec(U128 hash) //~ rjf: Cache Lookup internal U128 -hs_hash_from_key(U128 key, U64 rewind_count) +hs_hash_from_key(HS_Key key, U64 rewind_count) { U128 result = {0}; - U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count; + U64 key_hash = hs_little_hash_from_data(str8_struct(&key)); + U64 key_slot_idx = key_hash%hs_shared->key_slots_count; U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; @@ -418,7 +457,7 @@ hs_hash_from_key(U128 key, U64 rewind_count) { for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { - if(u128_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count) + if(hs_key_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count) { result = n->hash_history[(n->hash_history_gen-1-rewind_count)%ArrayCount(n->hash_history)]; break; diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index b626a0ba..c5c3412e 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -40,23 +40,46 @@ // submit that data to the hash store, correllating with the root and key // combo. +//////////////////////////////// +//~ rjf: Key Types + +typedef struct HS_Root HS_Root; +struct HS_Root +{ + U64 u64[1]; +}; + +typedef struct HS_ID HS_ID; +struct HS_ID +{ + U128 u128[1]; +}; + +typedef struct HS_Key HS_Key; +struct HS_Key +{ + HS_Root root; + U64 _padding_; + HS_ID id; +}; + //////////////////////////////// //~ rjf: Cache Types -typedef struct HS_RootKeyChunkNode HS_RootKeyChunkNode; -struct HS_RootKeyChunkNode +typedef struct HS_RootIDChunkNode HS_RootIDChunkNode; +struct HS_RootIDChunkNode { - HS_RootKeyChunkNode *next; + HS_RootIDChunkNode *next; U128 *v; U64 count; U64 cap; }; -typedef struct HS_RootKeyChunkList HS_RootKeyChunkList; -struct HS_RootKeyChunkList +typedef struct HS_RootIDChunkList HS_RootIDChunkList; +struct HS_RootIDChunkList { - HS_RootKeyChunkNode *first; - HS_RootKeyChunkNode *last; + HS_RootIDChunkNode *first; + HS_RootIDChunkNode *last; U64 chunk_count; U64 total_count; }; @@ -67,8 +90,8 @@ struct HS_RootNode HS_RootNode *next; HS_RootNode *prev; Arena *arena; - U128 root; - HS_RootKeyChunkList keys; + HS_Root root; + HS_RootIDChunkList ids; }; typedef struct HS_RootSlot HS_RootSlot; @@ -86,7 +109,7 @@ struct HS_KeyNode { HS_KeyNode *next; HS_KeyNode *prev; - U128 key; + HS_Key key; U128 hash_history[HS_KEY_HASH_HISTORY_COUNT]; U64 hash_history_gen; }; @@ -197,7 +220,12 @@ global HS_Shared *hs_shared = 0; //////////////////////////////// //~ rjf: Basic Helpers +internal U64 hs_little_hash_from_data(String8 data); internal U128 hs_hash_from_data(String8 data); +internal HS_ID hs_id_make(U64 u64_0, U64 u64_1); +internal B32 hs_id_match(HS_ID a, HS_ID b); +internal HS_Key hs_key_make(HS_Root root, HS_ID id); +internal B32 hs_key_match(HS_Key a, HS_Key b); //////////////////////////////// //~ rjf: Main Layer Initialization @@ -207,13 +235,13 @@ internal void hs_init(void); //////////////////////////////// //~ rjf: Root Allocation/Deallocation -internal U128 hs_root_alloc(void); -internal void hs_root_release(U128 root); +internal HS_Root hs_root_alloc(void); +internal void hs_root_release(HS_Root root); //////////////////////////////// //~ rjf: Cache Submission -internal U128 hs_submit_data(U128 key, Arena **data_arena, String8 data); +internal U128 hs_submit_data(HS_Key key, Arena **data_arena, String8 data); //////////////////////////////// //~ rjf: Scoped Access @@ -225,7 +253,7 @@ internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *no //////////////////////////////// //~ rjf: Key Closing -internal void hs_key_close(U128 key); +internal void hs_key_close(HS_Key key); //////////////////////////////// //~ rjf: Downstream Accesses @@ -236,7 +264,7 @@ internal void hs_hash_downstream_dec(U128 hash); //////////////////////////////// //~ rjf: Cache Lookups -internal U128 hs_hash_from_key(U128 key, U64 rewind_count); +internal U128 hs_hash_from_key(HS_Key key, U64 rewind_count); internal String8 hs_data_from_hash(HS_Scope *scope, U128 hash); //////////////////////////////// diff --git a/src/mutable_text/mutable_text.c b/src/mutable_text/mutable_text.c index 006ea601..94549be7 100644 --- a/src/mutable_text/mutable_text.c +++ b/src/mutable_text/mutable_text.c @@ -38,9 +38,10 @@ mtx_init(void) //~ rjf: Buffer Operations internal void -mtx_push_op(U128 buffer_key, MTX_Op op) +mtx_push_op(HS_Key buffer_key, MTX_Op op) { - MTX_MutThread *thread = &mtx_shared->mut_threads[buffer_key.u64[1]%mtx_shared->mut_threads_count]; + U64 hash = hs_little_hash_from_data(str8_struct(&buffer_key)); + MTX_MutThread *thread = &mtx_shared->mut_threads[hash%mtx_shared->mut_threads_count]; mtx_enqueue_op(thread, buffer_key, op); } @@ -48,7 +49,7 @@ mtx_push_op(U128 buffer_key, MTX_Op op) //~ rjf: Mutation Threads internal void -mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op) +mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op) { // TODO(rjf): if op.replace is too big, need to split into multiple edits OS_MutexScope(thread->mutex) for(;;) @@ -70,7 +71,7 @@ mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op) } internal void -mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out) +mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out) { OS_MutexScope(thread->mutex) for(;;) { @@ -100,7 +101,7 @@ mtx_mut_thread__entry_point(void *p) HS_Scope *hs_scope = hs_scope_open(); //- rjf: get next op - U128 buffer_key = {0}; + HS_Key buffer_key = {0}; MTX_Op op = {0}; mtx_dequeue_op(scratch.arena, mut_thread, &buffer_key, &op); diff --git a/src/mutable_text/mutable_text.h b/src/mutable_text/mutable_text.h index 505caac6..1614ae48 100644 --- a/src/mutable_text/mutable_text.h +++ b/src/mutable_text/mutable_text.h @@ -84,13 +84,13 @@ internal void mtx_init(void); //////////////////////////////// //~ rjf: Buffer Operations -internal void mtx_push_op(U128 buffer_key, MTX_Op op); +internal void mtx_push_op(HS_Key buffer_key, MTX_Op op); //////////////////////////////// //~ rjf: Mutation Threads -internal void mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op); -internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out); +internal void mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op); +internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out); internal void mtx_mut_thread__entry_point(void *p); #endif // MUTABLE_TEXT_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 0d652895..7c2e92df 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -456,7 +456,7 @@ Rng1U64 rd_reg_slot_range_table[44] = {OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)}, {OffsetOf(RD_Regs, cursor), OffsetOf(RD_Regs, cursor) + sizeof(TxtPt)}, {OffsetOf(RD_Regs, mark), OffsetOf(RD_Regs, mark) + sizeof(TxtPt)}, -{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(U128)}, +{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(HS_Key)}, {OffsetOf(RD_Regs, lang_kind), OffsetOf(RD_Regs, lang_kind) + sizeof(TXT_LangKind)}, {OffsetOf(RD_Regs, lines), OffsetOf(RD_Regs, lines) + sizeof(D_LineList)}, {OffsetOf(RD_Regs, dbgi_key), OffsetOf(RD_Regs, dbgi_key) + sizeof(DI_Key)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 6473c8bd..8d48807c 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -450,7 +450,7 @@ U64 inline_depth; String8 file_path; TxtPt cursor; TxtPt mark; -U128 text_key; +HS_Key text_key; TXT_LangKind lang_kind; D_LineList lines; DI_Key dbgi_key; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 86129cf8..aceda3d5 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -712,7 +712,7 @@ RD_RegTable: {String8 file_path FilePath } {TxtPt cursor Cursor } {TxtPt mark Mark } - {U128 text_key TextKey } + {HS_Key text_key TextKey } {TXT_LangKind lang_kind LangKind } {D_LineList lines Lines } {DI_Key dbgi_key DbgiKey } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6dece756..458ee937 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1747,7 +1747,9 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) //- rjf: reads from hash store key case E_SpaceKind_HashStoreKey: { - U128 key = space.u128; + HS_Root root = {space.u64_0}; + HS_ID id = {space.u128}; + HS_Key key = hs_key_make(root, id); U128 hash = hs_hash_from_key(key, 0); HS_Scope *scope = hs_scope_open(); { @@ -1778,7 +1780,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) containing_range.max -= containing_range.max%chunk_size; // rjf: map to hash - U128 key = fs_key_from_path_range(file_path, containing_range); + HS_Key key = fs_key_from_path_range(file_path, containing_range, 0); U128 hash = hs_hash_from_key(key, 0); // rjf: look up from hash store @@ -2136,28 +2138,30 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) //- rjf: asynchronous streamed reads -> hashes from spaces -internal U128 +internal HS_Key rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) { - U128 result = {0}; + HS_Key result = {0}; switch(space.kind) { case E_SpaceKind_HashStoreKey: { - result = space.u128; + HS_Root root = {space.u64_0}; + HS_ID id = {space.u128}; + result = hs_key_make(root, id); }break; case E_SpaceKind_File: { U64 file_path_string_id = space.u64_0; String8 file_path = e_string_from_id(file_path_string_id); - result = fs_key_from_path_range(file_path, range); + result = fs_key_from_path_range(file_path, range, 0); }break; case RD_EvalSpaceKind_CtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); if(entity->kind == CTRL_EntityKind_Process) { - result = ctrl_hash_store_key_from_process_vaddr_range(entity->handle, range, zero_terminated); + result = ctrl_key_from_process_vaddr_range(entity->handle, range, zero_terminated, 0, 0); } }break; } @@ -2174,7 +2178,9 @@ rd_whole_range_from_eval_space(E_Space space) { case E_SpaceKind_HashStoreKey: { - U128 key = space.u128; + HS_Root root = {space.u64_0}; + HS_ID id = {space.u128}; + HS_Key key = hs_key_make(root, id); U128 hash = hs_hash_from_key(key, 0); HS_Scope *hs_scope = hs_scope_open(); { @@ -2867,7 +2873,7 @@ rd_view_ui(Rng2F32 rect) // rjf: unpack view's target expression & hash E_Eval eval = e_eval_from_string(expr_string); Rng1U64 range = r1u64(0, 1024); - U128 key = rd_key_from_eval_space_range(eval.space, range, 0); + HS_Key key = rd_key_from_eval_space_range(eval.space, range, 0); U128 hash = hs_hash_from_key(key, 0); // rjf: determine if hash's blob is ready, and which viewer to use @@ -6519,7 +6525,7 @@ rd_window_frame(void) if(ws->dev_menu_is_open) RD_Font(RD_FontSlot_Code) { ui_set_next_flags(UI_BoxFlag_ViewScrollY|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClamp); - UI_PaneF(r2f32p(30, 30, 30+ui_top_font_size()*100, ui_top_font_size()*150), "###dev_ctx_menu") + UI_PaneF(r2f32p(30, 30, 30+ui_top_font_size()*100, ui_top_font_size()*60), "###dev_ctx_menu") { //- rjf: capture if(!ProfIsCapturing() && ui_clicked(ui_buttonf("Begin Profiler Capture###prof_cap"))) @@ -6580,7 +6586,7 @@ rd_window_frame(void) ui_labelf("mark: (L:%I64d, C:%I64d)", regs->mark.line, regs->mark.column); ui_labelf("unwind_count: %I64u", regs->unwind_count); ui_labelf("inline_depth: %I64u", regs->inline_depth); - ui_labelf("text_key: [0x%I64x, 0x%I64x]", regs->text_key.u64[0], regs->text_key.u64[1]); + ui_labelf("text_key: [0x%I64x / 0x%I64x:0x%I64x]", regs->text_key.root.u64[0], regs->text_key.id.u128[0].u64[0], regs->text_key.id.u128[0].u64[1]); ui_labelf("lang_kind: '%S'", txt_extension_from_lang_kind(regs->lang_kind)); ui_labelf("vaddr_range: [0x%I64x, 0x%I64x)", regs->vaddr_range.min, regs->vaddr_range.max); ui_labelf("voff_range: [0x%I64x, 0x%I64x)", regs->voff_range.min, regs->voff_range.max); @@ -12174,12 +12180,13 @@ rd_frame(void) //- rjf: add macro for output log { HS_Scope *hs_scope = hs_scope_open(); - U128 key = d_state->output_log_key; + HS_Key key = d_state->output_log_key; U128 hash = hs_hash_from_key(key, 0); String8 data = hs_data_from_hash(hs_scope, hash); E_Space space = e_space_make(E_SpaceKind_HashStoreKey); + space.u64_0 = key.root.u64[0]; + space.u128 = key.id.u128[0]; E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); - space.u128 = key; expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); @@ -15479,7 +15486,7 @@ rd_frame(void) HS_Scope *hs_scope = hs_scope_open(); TXT_Scope *txt_scope = txt_scope_open(); RD_Regs *regs = rd_regs(); - U128 text_key = regs->text_key; + HS_Key text_key = regs->text_key; TXT_LangKind lang_kind = regs->lang_kind; TxtRng range = txt_rng(regs->cursor, regs->mark); U128 hash = {0}; diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 3e4335c6..6468fbc6 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -890,7 +890,7 @@ internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range); //- rjf: asynchronous streamed reads -> hashes from spaces -internal U128 rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated); +internal HS_Key rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated); //- rjf: space -> entire range internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 177f9bd5..80fd780b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2381,7 +2381,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) syntax = DASM_Syntax_ATT; } } - U128 dasm_key = rd_key_from_eval_space_range(space, range, 0); + HS_Key dasm_key = rd_key_from_eval_space_range(space, range, 0); U128 dasm_data_hash = {0}; DASM_Params dasm_params = {0}; { @@ -3572,7 +3572,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: map expression artifacts -> texture // - U128 texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0); + HS_Key texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0); TEX_Topology topology = tex_topology_make(dim, fmt); U128 data_hash = {0}; R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology, &data_hash); @@ -4058,8 +4058,8 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) U64 base_offset = e_base_offset_from_eval(eval); Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32)); Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size); - U128 idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0); - U128 vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0); + HS_Key idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0); + HS_Key vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0); R_Handle idxs_buffer = geo_buffer_from_key(geo_scope, idxs_key); R_Handle vtxs_buffer = geo_buffer_from_key(geo_scope, vtxs_key); diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index e8c5da5c..e8706c1d 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -1771,7 +1771,7 @@ txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang) } internal TXT_TextInfo -txt_text_info_from_key_lang(TXT_Scope *scope, U128 key, TXT_LangKind lang, U128 *hash_out) +txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out) { TXT_TextInfo result = {0}; for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) diff --git a/src/text_cache/text_cache.h b/src/text_cache/text_cache.h index 2311139e..143a7b75 100644 --- a/src/text_cache/text_cache.h +++ b/src/text_cache/text_cache.h @@ -274,7 +274,7 @@ internal void txt_scope_touch_node__stripe_r_guarded(TXT_Scope *scope, TXT_Node //~ rjf: Cache Lookups internal TXT_TextInfo txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang); -internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, U128 key, TXT_LangKind lang, U128 *hash_out); +internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out); //////////////////////////////// //~ rjf: Text Info Extractor Helpers diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index bca74e24..8bc7e657 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -196,7 +196,7 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog } internal R_Handle -tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out) +tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out) { R_Handle handle = {0}; for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) diff --git a/src/texture_cache/texture_cache.h b/src/texture_cache/texture_cache.h index 617618dd..25a00be1 100644 --- a/src/texture_cache/texture_cache.h +++ b/src/texture_cache/texture_cache.h @@ -135,7 +135,7 @@ internal void tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node //~ rjf: Cache Lookups internal R_Handle tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology); -internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out); +internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out); //////////////////////////////// //~ rjf: Transfer Threads From 47d658daed114af180e520d433786966f09d367f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 16:21:38 -0700 Subject: [PATCH 732/755] ensure rd frame depth is always computed correctly; eliminate incorrect frame scope (ctrl/di) usage - fix weird deadlocks! --- src/hash_store/hash_store.c | 142 ++++++++++++++++++++++++------------ src/hash_store/hash_store.h | 9 +-- src/raddbg/raddbg_core.c | 37 ++++------ 3 files changed, 115 insertions(+), 73 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 297f532f..95cdd20f 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -139,10 +139,15 @@ hs_root_alloc(void) internal void hs_root_release(HS_Root root) { + //- rjf: unpack root U64 slot_idx = root.u64[1]%hs_shared->root_slots_count; U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx]; + + //- rjf: release root node, grab its arena / ID list + Arena *root_arena = 0; + HS_RootIDChunkList root_ids = {0}; OS_MutexScopeW(stripe->rw_mutex) { for(HS_RootNode *n = slot->first; n != 0; n = n->next) @@ -150,12 +155,62 @@ hs_root_release(HS_Root root) if(MemoryMatchStruct(&root, &n->root)) { DLLRemove(slot->first, slot->last, n); - arena_release(n->arena); + root_arena = n->arena; + root_ids = n->ids; SLLStackPush(hs_shared->root_stripes_free_nodes[stripe_idx], n); break; } } } + + //- rjf: release all IDs + for(HS_RootIDChunkNode *id_chunk_n = root_ids.first; id_chunk_n != 0; id_chunk_n = id_chunk_n->next) + { + for EachIndex(chunk_idx, id_chunk_n->count) + { + HS_ID id = id_chunk_n->v[chunk_idx]; + HS_Key key = hs_key_make(root, id); + U64 key_hash = hs_little_hash_from_data(str8_struct(&key)); + U64 key_slot_idx = key_hash%hs_shared->key_slots_count; + U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; + HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; + HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; + OS_MutexScopeW(key_stripe->rw_mutex) + { + for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) + { + if(hs_key_match(n->key, key)) + { + // rjf: release reference to all hashes + for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1) + { + U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)]; + U64 hash_slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count; + HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; + HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx]; + OS_MutexScopeR(hash_stripe->rw_mutex) + { + for(HS_Node *n = hash_slot->first; n != 0; n = n->next) + { + if(u128_match(n->hash, hash)) + { + ins_atomic_u64_dec_eval(&n->key_ref_count); + break; + } + } + } + } + + // rjf: release key node + DLLRemove(key_slot->first, key_slot->last, n); + SLLStackPush(hs_shared->key_stripes_free_nodes[key_stripe_idx], n); + break; + } + } + } + } + } } //////////////////////////////// @@ -226,6 +281,8 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) U128 key_expired_hash = {0}; ProfScope("commit this hash to key cache") OS_MutexScopeW(key_stripe->rw_mutex) { + // rjf: find existing key + B32 key_is_new = 0; HS_KeyNode *key_node = 0; for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { @@ -235,8 +292,11 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) break; } } + + // rjf: create key node if it doesn't exist if(!key_node) { + key_is_new = 1; key_node = hs_shared->key_stripes_free_nodes[key_stripe_idx]; if(key_node) { @@ -249,6 +309,8 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) key_node->key = key; DLLPushBack(key_slot->first, key_slot->last, key_node); } + + // rjf: push hash into key's history if(key_node) { if(key_node->hash_history_gen >= HS_KEY_HASH_HISTORY_STRONG_REF_COUNT) @@ -258,6 +320,40 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; key_node->hash_history_gen += 1; } + + // rjf: key is new -> add this key to the associated root + if(key_is_new) + { + U64 root_hash = hs_little_hash_from_data(str8_struct(&key.root)); + U64 root_slot_idx = root_hash%hs_shared->root_slots_count; + U64 root_stripe_idx = root_slot_idx%hs_shared->root_stripes_count; + HS_RootSlot *root_slot = &hs_shared->root_slots[root_slot_idx]; + HS_Stripe *root_stripe = &hs_shared->root_stripes[root_stripe_idx]; + OS_MutexScopeW(root_stripe->rw_mutex) + { + for(HS_RootNode *n = root_slot->first; n != 0; n = n->next) + { + if(MemoryMatchStruct(&n->root, &key.root)) + { + HS_RootIDChunkNode *chunk = n->ids.last; + if(chunk == 0 || chunk->count >= chunk->cap) + { + chunk = push_array(n->arena, HS_RootIDChunkNode, 1); + SLLQueuePush(n->ids.first, n->ids.last, chunk); + n->ids.chunk_count += 1; + chunk->cap = 1024; + chunk->v = push_array_no_zero(n->arena, HS_ID, chunk->cap); + } + chunk->v[chunk->count] = key.id; + key_node->root_id_chunk_node = chunk; + key_node->root_id_chunk_idx = chunk->count; + chunk->count += 1; + n->ids.total_count += 1; + break; + } + } + } + } } //- rjf: decrement key ref count of expired hash @@ -354,50 +450,6 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) SLLStackPush(scope->top_touch, touch); } -//////////////////////////////// -//~ rjf: Key Closing - -internal void -hs_key_close(HS_Key key) -{ - U64 key_hash = hs_little_hash_from_data(str8_struct(&key)); - U64 key_slot_idx = key_hash%hs_shared->key_slots_count; - U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; - HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; - HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; - OS_MutexScopeW(key_stripe->rw_mutex) - { - for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) - { - if(hs_key_match(n->key, key)) - { - for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1) - { - U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)]; - U64 hash_slot_idx = hash.u64[1]%hs_shared->slots_count; - U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count; - HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; - HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx]; - OS_MutexScopeR(hash_stripe->rw_mutex) - { - for(HS_Node *n = hash_slot->first; n != 0; n = n->next) - { - if(u128_match(n->hash, hash)) - { - ins_atomic_u64_dec_eval(&n->key_ref_count); - break; - } - } - } - } - DLLRemove(key_slot->first, key_slot->last, n); - SLLStackPush(hs_shared->key_stripes_free_nodes[key_stripe_idx], n); - break; - } - } - } -} - //////////////////////////////// //~ rjf: Downstream Accesses diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index c5c3412e..209fd03c 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -70,7 +70,7 @@ typedef struct HS_RootIDChunkNode HS_RootIDChunkNode; struct HS_RootIDChunkNode { HS_RootIDChunkNode *next; - U128 *v; + HS_ID *v; U64 count; U64 cap; }; @@ -109,6 +109,8 @@ struct HS_KeyNode { HS_KeyNode *next; HS_KeyNode *prev; + HS_RootIDChunkNode *root_id_chunk_node; + U64 root_id_chunk_idx; HS_Key key; U128 hash_history[HS_KEY_HASH_HISTORY_COUNT]; U64 hash_history_gen; @@ -250,11 +252,6 @@ internal HS_Scope *hs_scope_open(void); internal void hs_scope_close(HS_Scope *scope); internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node); -//////////////////////////////// -//~ rjf: Key Closing - -internal void hs_key_close(HS_Key key); - //////////////////////////////// //~ rjf: Downstream Accesses diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 458ee937..e1fb2b4b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5778,7 +5778,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) if(window_cfg != &rd_nil_cfg && ws == &rd_nil_window_state) { Temp scratch = scratch_begin(0, 0); - rd_state->frame_depth += 1; // rjf: unpack configuration options B32 has_pos = 0; @@ -5853,7 +5852,6 @@ rd_window_state_from_cfg(RD_Cfg *cfg) DLLPushBack_NPZ(&rd_nil_window_state, rd_state->first_window_state, rd_state->last_window_state, ws, order_next, order_prev); DLLPushBack_NP(slot->first, slot->last, ws, hash_next, hash_prev); - rd_state->frame_depth -= 1; scratch_end(scratch); } @@ -11026,6 +11024,7 @@ rd_frame(void) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); log_scope_begin(); + rd_state->frame_depth += 1; ////////////////////////////// //- rjf: (DEBUG) take top-level cfg roots, stringize them, and store them to hash store @@ -11076,7 +11075,7 @@ rd_frame(void) ////////////////////////////// //- rjf: iterate all tabs, touch their view-states // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { Temp scratch = scratch_begin(0, 0); RD_CfgList windows = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("window")); @@ -11103,7 +11102,7 @@ rd_frame(void) ////////////////////////////// //- rjf: garbage collect untouched immediate cfg trees // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { RD_Cfg *transient = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("transient")); for(RD_Cfg *tln = transient->first, *next = &rd_nil_cfg; tln != &rd_nil_cfg; tln = next) @@ -11136,7 +11135,7 @@ rd_frame(void) ////////////////////////////// //- rjf: garbage collect untouched view states // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { for EachIndex(slot_idx, rd_state->view_state_slots_count) { @@ -11195,7 +11194,7 @@ rd_frame(void) ////////////////////////////// //- rjf: animate all views // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { F32 slow_rate = 1 - pow_f32(2, (-10.f * rd_state->frame_dt)); F32 fast_rate = 1 - pow_f32(2, (-40.f * rd_state->frame_dt)); @@ -11242,7 +11241,7 @@ rd_frame(void) //- rjf: get events from the OS // OS_EventList events = {0}; - if(rd_state->frame_depth == 0) DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) + if(rd_state->frame_depth == 1) { events = os_get_events(scratch.arena, rd_state->num_frames_requested == 0); } @@ -11250,8 +11249,10 @@ rd_frame(void) ////////////////////////////// //- rjf: open frame scopes // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { + if(rd_state->frame_di_scope) { di_scope_close(rd_state->frame_di_scope); } + if(rd_state->frame_ctrl_scope) { ctrl_scope_close(rd_state->frame_ctrl_scope); } rd_state->frame_di_scope = di_scope_open(); rd_state->frame_ctrl_scope = ctrl_scope_open(); } @@ -12456,7 +12457,7 @@ rd_frame(void) //////////////////////////// //- rjf: process top-level graphical commands // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { for(;rd_next_cmd(&cmd);) RD_RegsScope() { @@ -16512,7 +16513,7 @@ rd_frame(void) // the commands pushed by the view will be in the queue, and the core can // treat that queue as r/w again. // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { // rjf: rotate { @@ -16714,15 +16715,6 @@ rd_frame(void) rd_state->num_frames_requested -= 1; } - ////////////////////////////// - //- rjf: close frame scopes - // - if(rd_state->frame_depth == 0) - { - di_scope_close(rd_state->frame_di_scope); - ctrl_scope_close(rd_state->frame_ctrl_scope); - } - ////////////////////////////// //- rjf: submit rendering to all windows // @@ -16741,7 +16733,7 @@ rd_frame(void) ////////////////////////////// //- rjf: show windows after first frame // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { RD_CfgIDList windows_to_show = {0}; for(RD_WindowState *w = rd_state->first_window_state; w != &rd_nil_window_state; w = w->order_next) @@ -16755,7 +16747,7 @@ rd_frame(void) { RD_Cfg *window = rd_cfg_from_id(n->v); RD_WindowState *ws = rd_window_state_from_cfg(window); - DeferLoop(rd_state->frame_depth += 1, rd_state->frame_depth -= 1) os_window_first_paint(ws->os); + os_window_first_paint(ws->os); } } @@ -16776,7 +16768,7 @@ rd_frame(void) ////////////////////////////// //- rjf: bump command batch ring buffer generation // - if(rd_state->frame_depth == 0) + if(rd_state->frame_depth == 1) { rd_state->cmds_gen += 1; } @@ -16809,6 +16801,7 @@ rd_frame(void) } #endif + rd_state->frame_depth -= 1; scratch_end(scratch); ProfEnd(); } From 862e0ef882af4673377236cf2816ded1d775bed9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 18:47:52 -0700 Subject: [PATCH 733/755] fix lens expansions being treated like set expansions in eval viz string iter --- src/eval_visualization/eval_visualization_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 97c68827..cf599c1a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1648,7 +1648,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_task.eval = eval; new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); } - else if(type->expand.info != 0) + else if(type->kind != E_TypeKind_Lens && type->expand.info != 0) { need_new_task = 1; need_pop = 1; From 54325828b2ad833f658f43071adca990c0352f9d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 18:56:13 -0700 Subject: [PATCH 734/755] absolutify target stdout/stderr/stdin paths based on working directory --- src/ctrl/ctrl_core.c | 21 +++++++++++++++------ src/path/path.c | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index a12d31a1..54cb0bc1 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -5262,25 +5262,32 @@ ctrl_thread__end_and_flush_info_log(void) internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) { + Temp scratch = scratch_begin(0, 0); + + //- rjf: produce full stdout/stderr/stdin paths + String8 stdout_path = path_absolute_dst_from_relative_dst_src(scratch.arena, msg->stdout_path, msg->path); + String8 stdin_path = path_absolute_dst_from_relative_dst_src(scratch.arena, msg->stdin_path, msg->path); + String8 stderr_path = path_absolute_dst_from_relative_dst_src(scratch.arena, msg->stderr_path, msg->path); + //- rjf: obtain stdout/stderr/stdin handles OS_Handle stdout_handle = {0}; OS_Handle stderr_handle = {0}; OS_Handle stdin_handle = {0}; - if(msg->stdout_path.size != 0) + if(stdout_path.size != 0) { - OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, msg->stdout_path); + OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path); os_file_close(f); stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, msg->stdout_path); } - if(msg->stderr_path.size != 0) + if(stderr_path.size != 0) { - OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, msg->stderr_path); + OS_Handle f = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stderr_path); os_file_close(f); stderr_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, msg->stderr_path); } - if(msg->stdin_path.size != 0) + if(stdin_path.size != 0) { - stdin_handle = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, msg->stdin_path); + stdin_handle = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, stdin_path); } //- rjf: launch @@ -5313,6 +5320,8 @@ ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ctrl_entity_equip_string(entity_ctx_rw_store, entry, string); } } + + scratch_end(scratch); } internal void diff --git a/src/path/path.c b/src/path/path.c index 72d2c710..32c928b7 100644 --- a/src/path/path.c +++ b/src/path/path.c @@ -90,7 +90,7 @@ path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src) { String8 result = dst; PathStyle dst_style = path_style_from_str8(dst); - if(dst_style == PathStyle_Relative) + if(dst.size != 0 && dst_style == PathStyle_Relative) { Temp scratch = scratch_begin(&arena, 1); String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", src, dst); From 9ae0ee9a46d154402b32c981e262279a34df684b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 19:21:06 -0700 Subject: [PATCH 735/755] correctly use tab width px in new code slice fstrs measuring path --- src/draw/draw.c | 4 ++-- src/draw/draw.h | 2 +- src/raddbg/raddbg_core.c | 2 +- src/raddbg/raddbg_widgets.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/draw/draw.c b/src/draw/draw.c index e26a55b6..db34c9b0 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -187,10 +187,10 @@ dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs) } internal Vec2F32 -dr_dim_from_fstrs(DR_FStrList *fstrs) +dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs) { Temp scratch = scratch_begin(0, 0); - DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, 0, fstrs); + DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, tab_size_px, fstrs); Vec2F32 dim = fruns.dim; scratch_end(scratch); return dim; diff --git a/src/draw/draw.h b/src/draw/draw.h index d98f1081..f338e0fd 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -125,7 +125,7 @@ internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src); internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list); internal FuzzyMatchRangeList dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle); internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs); -internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs); +internal Vec2F32 dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs); //////////////////////////////// //~ rjf: Top-Level API diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e1fb2b4b..0da5f4b0 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8920,7 +8920,7 @@ rd_window_frame(void) TabTask *t = push_array(scratch.arena, TabTask, 1); t->tab = tab; t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab); - F32 tab_width_target = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; + F32 tab_width_target = dr_dim_from_fstrs(ui_top_tab_size(), &t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f; tab_width_target = Min(max_tab_width_px, tab_width_target); t->tab_width = floor_f32(ui_anim(ui_key_from_stringf(ui_key_zero(), "tab_width_%p", tab), tab_width_target, .initial = reset ? tab_width_target : 0, .rate = rd_state->menu_animation_rate)); SLLQueuePush(first_tab_task, last_tab_task, t); diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 5cd62bbc..98faec79 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1954,7 +1954,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { DR_FStrList line_fstrs = lines_fstrs[line_idx]; - F32 line_text_dim = dr_dim_from_fstrs(&line_fstrs).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; + F32 line_text_dim = dr_dim_from_fstrs(params->tab_size, &line_fstrs).x + params->line_num_width_px + params->catchall_margin_width_px + params->priority_margin_width_px; line_extras_off[line_idx] = Max(line_text_dim, params->font_size*30); } } From 7dc43993005d3faf3cc27a6a3e659f238c42ef15 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 19:38:27 -0700 Subject: [PATCH 736/755] dead ctrl process memory cache elimination --- src/ctrl/ctrl_core.c | 196 ------------------------------------------- src/ctrl/ctrl_core.h | 11 --- 2 files changed, 207 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 54cb0bc1..11627f6a 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1756,202 +1756,6 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 return key; } -//- rjf: process memory cache interaction - -#if 0 // TODO(rjf): @hs -internal U128 -ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated) -{ - U64 key_hash_data[] = - { - (U64)process.machine_id, - (U64)process.dmn_handle.u64[0], - range.min, - range.max, - (U64)zero_terminated, - }; - U128 key = hs_hash_from_data(str8((U8*)key_hash_data, sizeof(key_hash_data))); - return key; -} - -internal U128 -ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us) -{ - ProfBeginFunction(); - U128 result = {0}; - U64 size = dim_1u64(range); - U64 pre_mem_gen = dmn_mem_gen(); - CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; - U64 range_hash = ctrl_hash_from_string(str8_struct(&range)); - U64 process_hash = ctrl_hash_from_string(str8_struct(&process)); - U64 process_slot_idx = process_hash%cache->slots_count; - U64 process_stripe_idx = process_slot_idx%cache->stripes_count; - CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx]; - CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx]; - if(size != 0) for(;;) - { - //- rjf: try to read from cache - B32 is_good = 0; - B32 process_node_exists = 0; - B32 is_stale = 1; - OS_MutexScopeR(process_stripe->rw_mutex) - { - for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, process)) - { - process_node_exists = 1; - U64 range_slot_idx = range_hash%n->range_hash_slots_count; - CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; - for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) - { - if(MemoryMatchStruct(&range_n->vaddr_range, &range) && range_n->zero_terminated == zero_terminated) - { - result = range_n->hash; - is_good = 1; - is_stale = (range_n->mem_gen != pre_mem_gen); - goto read_cache__break_all; - } - } - } - } - read_cache__break_all:; - } - - //- rjf: not good -> create process cache node if necessary - if(!is_good && !process_node_exists) - { - OS_MutexScopeW(process_stripe->rw_mutex) - { - B32 process_node_exists = 0; - for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, process)) - { - process_node_exists = 1; - break; - } - } - if(!process_node_exists) - { - Arena *node_arena = arena_alloc(); - CTRL_ProcessMemoryCacheNode *node = push_array(node_arena, CTRL_ProcessMemoryCacheNode, 1); - node->arena = node_arena; - node->handle = process; - node->range_hash_slots_count = 1024; - node->range_hash_slots = push_array(node_arena, CTRL_ProcessMemoryRangeHashSlot, node->range_hash_slots_count); - DLLPushBack(process_slot->first, process_slot->last, node); - } - } - } - - //- rjf: not good -> create range node if necessary - U64 last_time_requested_us = 0; - if(!is_good) - { - OS_MutexScopeW(process_stripe->rw_mutex) - { - for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, process)) - { - U64 range_slot_idx = range_hash%n->range_hash_slots_count; - CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; - B32 range_node_exists = 0; - for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) - { - if(MemoryMatchStruct(&range_n->vaddr_range, &range) && range_n->zero_terminated == zero_terminated) - { - last_time_requested_us = range_n->last_time_requested_us; - range_node_exists = 1; - break; - } - } - if(!range_node_exists) - { - CTRL_ProcessMemoryRangeHashNode *range_n = push_array(n->arena, CTRL_ProcessMemoryRangeHashNode, 1); - SLLQueuePush(range_slot->first, range_slot->last, range_n); - range_n->vaddr_range = range; - range_n->zero_terminated = zero_terminated; - range_n->vaddr_range_clamped = range; - { - range_n->vaddr_range_clamped.max = Max(range_n->vaddr_range_clamped.max, range_n->vaddr_range_clamped.min); - U64 max_size_cap = Min(max_U64-range_n->vaddr_range_clamped.min, GB(1)); - range_n->vaddr_range_clamped.max = Min(range_n->vaddr_range_clamped.max, range_n->vaddr_range_clamped.min+max_size_cap); - } - break; - } - } - } - } - } - - //- rjf: not good, or is stale -> submit hash request - if((!is_good || is_stale) && os_now_microseconds() >= last_time_requested_us+100000) - { - if(ctrl_u2ms_enqueue_req(process, range, zero_terminated, endt_us)) - { - OS_MutexScopeW(process_stripe->rw_mutex) - { - for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, process)) - { - U64 range_slot_idx = range_hash%n->range_hash_slots_count; - CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx]; - for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next) - { - if(MemoryMatchStruct(&range_n->vaddr_range, &range) && range_n->zero_terminated == zero_terminated) - { - range_n->last_time_requested_us = os_now_microseconds(); - break; - } - } - } - } - } - async_push_work(ctrl_mem_stream_work); - } - } - - //- rjf: out of time? -> exit - if(os_now_microseconds() >= endt_us) - { - if(is_stale && out_is_stale) - { - out_is_stale[0] = 1; - } - break; - } - - //- rjf: done? -> exit - if(is_good && !is_stale) - { - break; - } - } - U64 post_mem_gen = dmn_mem_gen(); - if(post_mem_gen != pre_mem_gen && out_is_stale) - { - out_is_stale[0] = 1; - } - ProfEnd(); - return result; -} -#endif - -//- rjf: bundled key/stream helper - -#if 0 // TODO(rjf): @hs -internal U128 -ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated) -{ - U128 key = ctrl_calc_hash_store_key_from_process_vaddr_range(process, range, zero_terminated); - ctrl_stored_hash_from_process_vaddr_range(process, range, zero_terminated, 0, 0); - return key; -} -#endif - //- rjf: process memory cache reading helpers internal CTRL_ProcessMemorySlice diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 337555bd..02cf46b4 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -993,17 +993,6 @@ internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook); //- rjf: process memory cache key reading internal HS_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale); -//- rjf: process memory cache interaction -#if 0 // TODO(rjf): @hs -internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); -internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us); -#endif - -//- rjf: bundled key/stream helper -#if 0 // TODO(rjf): @hs -internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); -#endif - //- rjf: process memory cache reading helpers internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); internal B32 ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); From 7d274dd2f680aaed32c96b929f34be00fe94334a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 22:09:52 -0700 Subject: [PATCH 737/755] fix incorrect lens application condition in eval viz string iter --- src/eval_visualization/eval_visualization_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index cf599c1a..84778d07 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1648,7 +1648,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_task.eval = eval; new_task.eval.irtree.type_key = e_type_key_direct(eval.irtree.type_key); } - else if(type->kind != E_TypeKind_Lens && type->expand.info != 0) + else if(type->kind != E_TypeKind_Lens || type->expand.info != 0) { need_new_task = 1; need_pop = 1; From b94535b20bff735f74d4cfe6ef236fc22afcab68 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 19 May 2025 22:22:47 -0700 Subject: [PATCH 738/755] fix array-indexing in type evaluation mode --- src/eval/eval_ir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index da9157cb..643946c9 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -574,7 +574,10 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) // rjf: ops to compute the final address new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - mode = E_Mode_Offset; + if(mode != E_Mode_Null) + { + mode = E_Mode_Offset; + } } } From 56b975a6b11e212a97472b67fe915f1aef1a3cd4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 10:36:44 -0700 Subject: [PATCH 739/755] adjust async call stack querying API to guard against waiting in clearly-invalid cases (trying to wait for call stacks when running, for example); also eliminate logs --- src/ctrl/ctrl_core.c | 23 ++++++++--------------- src/ctrl/ctrl_core.h | 1 + src/demon/win32/demon_core_win32.c | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 11627f6a..4b50ef9a 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3361,6 +3361,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ ////////////////////////////// //- rjf: loop: try to grab cached call stack; request; wait // + B32 can_request = !ins_atomic_u64_eval(&ctrl_state->ctrl_thread_run_state); OS_MutexScopeR(stripe->rw_mutex) for(;;) { //////////////////////////// @@ -3411,7 +3412,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ //////////////////////////// //- rjf: request if needed // - if(node != 0 && !is_working && is_stale) + if(can_request && node != 0 && !is_working && is_stale) { if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) @@ -3423,7 +3424,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ //////////////////////////// //- rjf: good, or timeout? -> exit // - if(!is_stale || os_now_microseconds() >= endt_us) + if(!can_request || !is_stale || os_now_microseconds() >= endt_us) { break; } @@ -3639,6 +3640,7 @@ ctrl_thread__entry_point(void *p) //- rjf: process messages DMN_CtrlExclusiveAccessScope { + ins_atomic_u64_eval_assign(&ctrl_state->ctrl_thread_run_state, 1); for(CTRL_MsgNode *msg_n = msgs.first; msg_n != 0; msg_n = msg_n->next) { CTRL_Msg *msg = &msg_n->v; @@ -3715,6 +3717,7 @@ ctrl_thread__entry_point(void *p) }break; } } + ins_atomic_u64_eval_assign(&ctrl_state->ctrl_thread_run_state, 0); } //- rjf: gather & output logs @@ -4269,15 +4272,6 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, log_infof("string: \"%S\"\n", ev->string); log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer); } - raddbg_log("event:\n"); - raddbg_log("kind: %S\n", dmn_event_kind_string_table[ev->kind]); - raddbg_log("process: [%I64u]\n", ev->process.u64[0]); - raddbg_log("thread: [%I64u]\n", ev->thread.u64[0]); - raddbg_log("module: [%I64u]\n", ev->module.u64[0]); - raddbg_log("pid: %I64u\n", ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->process))->id); - raddbg_log("tid: %I64u\n", ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, ev->thread))->id); - raddbg_log("code: %I64u\n", ev->code); - raddbg_log("\n"); } // rjf: determine if we should filter @@ -6943,10 +6937,6 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10); } } - if(committed) - { - os_condition_variable_broadcast(stripe->cv); - } } //- rjf: release last results @@ -6964,6 +6954,9 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) break; } } + + //- rjf: broadcast update + os_condition_variable_broadcast(stripe->cv); } scratch_end(scratch); diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 02cf46b4..1eb83b5e 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -798,6 +798,7 @@ struct CTRL_State OS_Handle c2u_ring_cv; // rjf: ctrl thread state + U64 ctrl_thread_run_state; String8 ctrl_thread_log_path; OS_Handle ctrl_thread; Log *ctrl_thread_log; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index d684c573..d9fe31df 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1878,7 +1878,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } if(resume_good) { - evt_good = !!WaitForDebugEvent(&evt, 1000); + evt_good = !!WaitForDebugEvent(&evt, 100); if(evt_good) { dmn_w32_shared->resume_needed = 1; From 34df269c58b25992539402fcbee05021a00149ff Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 10:53:02 -0700 Subject: [PATCH 740/755] eliminate extra root id list placement in key nodes --- src/hash_store/hash_store.c | 2 -- src/hash_store/hash_store.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 95cdd20f..f7b819e9 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -345,8 +345,6 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) chunk->v = push_array_no_zero(n->arena, HS_ID, chunk->cap); } chunk->v[chunk->count] = key.id; - key_node->root_id_chunk_node = chunk; - key_node->root_id_chunk_idx = chunk->count; chunk->count += 1; n->ids.total_count += 1; break; diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index 209fd03c..8141eeb9 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -109,8 +109,6 @@ struct HS_KeyNode { HS_KeyNode *next; HS_KeyNode *prev; - HS_RootIDChunkNode *root_id_chunk_node; - U64 root_id_chunk_idx; HS_Key key; U128 hash_history[HS_KEY_HASH_HISTORY_COUNT]; U64 hash_history_gen; From 41ee0c83d4af61026d39bfba5b1d6eb89803459b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 11:00:18 -0700 Subject: [PATCH 741/755] notes; skip relativization path for stdout/stderr/stdin paths --- src/raddbg/generated/raddbg.meta.c | 4 ++-- src/raddbg/raddbg.mdesk | 8 ++++---- src/raddbg/raddbg_core.c | 4 ++-- src/raddbg/raddbg_main.c | 4 +++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 7c2e92df..fbe190a4 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -422,10 +422,10 @@ RD_NameSchemaInfo rd_name_schema_info_table[24] = {str8_lit_comp("color"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': @no_relativize path,\n 'stderr_path': @no_relativize path,\n 'stdin_path': @no_relativize path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n}\n")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @no_relativize path, 'dest': @no_relativize path}")}, {str8_lit_comp("type_view"), str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index aceda3d5..f0329658 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -580,9 +580,9 @@ RD_VocabTable: 'arguments': string, 'working_directory': path, 'entry_point': expr_string, - 'stdout_path': path, - 'stderr_path': path, - 'stdin_path': path, + 'stdout_path': @no_relativize path, + 'stderr_path': @no_relativize path, + 'stdin_path': @no_relativize path, 'environment': query, 'debug_subprocesses': bool, @no_revert @no_expand @default(0) 'enabled': bool, @@ -630,7 +630,7 @@ RD_VocabTable: //- rjf: file path maps { file_path_map, - ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @absolute path, 'dest': @absolute path}```, + ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source': @no_relativize path, 'dest': @no_relativize path}```, } //- rjf: type views diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0da5f4b0..d4773de7 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -640,7 +640,7 @@ rd_cfg_tree_list_from_string(Arena *arena, String8 root_path, String8 string) { String8 src_n_string = src_n->string; String8 src_n_string__raw = raw_from_escaped_str8(scratch.arena, src_n_string); - if(!md_node_has_tag(schema->first, str8_lit("absolute"), 0)) + if(!md_node_has_tag(schema->first, str8_lit("no_relativize"), 0)) { if(str8_match(schema->first->string, str8_lit("path"), 0)) { @@ -730,7 +730,7 @@ rd_string_from_cfg_tree(Arena *arena, String8 root_path, RD_Cfg *cfg) } // rjf: paths -> relativize - if(!md_node_has_tag(c_schema->first, str8_lit("absolute"), 0)) + if(!md_node_has_tag(c_schema->first, str8_lit("no_relativize"), 0)) { if(str8_match(c_schema->first->string, str8_lit("path"), 0)) { diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 97e514d6..9243b825 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -15,12 +15,14 @@ - Stopped the debugger from running the default Windows message handling path for most `Alt`-based keybindings, which was causing a Windows beep sound to play. - Fixed a bug where RDI files would sometimes fail to generate, resulting in no debug info being available on some runs. - Fixed a bug which was preventing backslashes from working in file system querying interfaces correctly. - - Fixed a bug which was preventing some recursive callstacks from fully displaying in the debugger. + - Fixed a bug which was preventing some recursive call stacks from fully displaying in the debugger. - Fixed a bug which prevented `Space` from being used as a keybinding. Bound `Space` by default to the `Accept` command (to which `Enter` / `Return` is also defaultly bound). - Fixed a bug which was preventing conditional breakpoints from correctly being placed, if the condition expression did not evaluate when the debuggees were resumed. - Fixed the debugger applying too much path processing, which was causing relative paths in debug info to be interpreted incorrectly. The debugger should now work much better with relative paths (e.g. produced via `/d1trimfile`). In these cases, the debugger may still not be able to fully compute the correct absolute paths, because this information is not stored within debug information. But once the debugger is redirected to the correct file once through the UI, it should work with relative paths correctly. - If the debugger crashes, the message box which opens and displays the crash call stack now also allows the creation of crash dump files. Please submit these, if possible, with crash reports; it will help us to debug crashes more effectively. - Fixed a bug which was causing text rendering to fail both when running the debugger on WINE and also on Windows 7. +- Fixed a bug where exception information inlined in source code would overlap the source code text. +- The debugger now correctly correctly interprets relative per-target `stdout`, `stderr`, and `stdin` paths. */ //////////////////////////////// From 7fc39a3d97e6095c3f329afbb64f2c9eeb18e1b7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 11:13:04 -0700 Subject: [PATCH 742/755] eliminate old debug engine unwind cache --- src/ctrl/ctrl_core.c | 1 + src/dbg_engine/dbg_engine_core.c | 116 ++++--------------------------- src/dbg_engine/dbg_engine_core.h | 31 --------- 3 files changed, 14 insertions(+), 134 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 4b50ef9a..eebc8fb5 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -2091,6 +2091,7 @@ ctrl_rsp_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle) internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block) { + // TODO(rjf): @callstacks immediately reflect this in the call stack cache B32 good = dmn_thread_write_reg_block(thread.dmn_handle, block); return good; } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 5c90af76..dc76e3dc 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1160,61 +1160,6 @@ d_push_active_dbgi_key_list(Arena *arena) //- rjf: per-run caches -internal CTRL_Unwind -d_query_cached_unwind_from_thread(CTRL_Entity *thread) -{ - Temp scratch = scratch_begin(0, 0); - CTRL_Unwind result = {0}; - if(thread->kind == CTRL_EntityKind_Thread) - { - U64 reg_gen = ctrl_reg_gen(); - U64 mem_gen = ctrl_mem_gen(); - D_UnwindCache *cache = &d_state->unwind_cache; - CTRL_Handle handle = thread->handle; - U64 hash = d_hash_from_string(str8_struct(&handle)); - U64 slot_idx = hash%cache->slots_count; - D_UnwindCacheSlot *slot = &cache->slots[slot_idx]; - D_UnwindCacheNode *node = 0; - for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(handle, n->thread)) - { - node = n; - break; - } - } - if(node == 0) - { - node = cache->free_node; - if(node != 0) - { - SLLStackPop(cache->free_node); - } - else - { - node = push_array_no_zero(d_state->arena, D_UnwindCacheNode, 1); - } - MemoryZeroStruct(node); - DLLPushBack(slot->first, slot->last, node); - node->arena = arena_alloc(); - node->thread = handle; - } - if(!d_state->ctrl_is_running && (node->reggen != reg_gen || node->memgen != mem_gen)) - { - CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle, os_now_microseconds()+100); - if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0) - { - node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind); - node->reggen = reg_gen; - node->memgen = mem_gen; - } - } - result = node->unwind; - } - scratch_end(scratch); - return result; -} - internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread) { @@ -1232,10 +1177,11 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count) } else { - CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); - if(unwind.frames.count != 0) + CTRL_Scope *ctrl_scope = ctrl_scope_open(); + CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, 0); + if(callstack.concrete_frames_count != 0) { - result = regs_rip_from_arch_block(thread->arch, unwind.frames.v[unwind_count%unwind.frames.count].regs); + result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs); } } return result; @@ -1450,8 +1396,6 @@ d_init(void) d_state->ctrl_msg_arena = arena_alloc(); // rjf: set up caches - d_state->unwind_cache.slots_count = 1024; - d_state->unwind_cache.slots = push_array(arena, D_UnwindCacheSlot, d_state->unwind_cache.slots_count); for(U64 idx = 0; idx < ArrayCount(d_state->tls_base_caches); idx += 1) { d_state->tls_base_caches[idx].arena = arena_alloc(); @@ -1695,24 +1639,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P d_cmd(D_CmdKind_SoftHaltRefresh); } - ////////////////////////////// - //- rjf: garbage collect eliminated thread unwinds - // - for(U64 slot_idx = 0; slot_idx < d_state->unwind_cache.slots_count; slot_idx += 1) - { - D_UnwindCacheSlot *slot = &d_state->unwind_cache.slots[slot_idx]; - for(D_UnwindCacheNode *n = slot->first, *next = 0; n != 0; n = next) - { - next = n->next; - if(ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, n->thread) == &ctrl_entity_nil) - { - DLLRemove(slot->first, slot->last, n); - arena_release(n->arena); - SLLStackPush(d_state->unwind_cache.free_node, n); - } - } - } - ////////////////////////////// //- rjf: process top-level commands // @@ -1928,13 +1854,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; case D_CmdKind_StepOut: { - // rjf: thread => full unwind - CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle, os_now_microseconds()+10000); + CTRL_Scope *ctrl_scope = ctrl_scope_open(); + + // rjf: thread => call stack + CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, os_now_microseconds()+10000); // rjf: use first unwind frame to generate trap - if(unwind.flags == 0 && unwind.frames.count > 1) + if(callstack.concrete_frames_count > 1) { - U64 vaddr = regs_rip_from_arch_block(thread->arch, unwind.frames.v[1].regs); + U64 vaddr = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[1]->regs); CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr}; ctrl_trap_list_push(scratch.arena, &traps, &trap); } @@ -1943,6 +1871,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P log_user_error(str8_lit("Could not find the return address of the current callstack frame successfully.")); good = 0; } + + ctrl_scope_close(ctrl_scope); }break; } if(good && traps.count != 0) @@ -1984,27 +1914,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P void *block = ctrl_reg_block_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle); regs_arch_block_write_rip(thread->arch, block, vaddr); B32 result = ctrl_thread_write_reg_block(thread->handle, block); - - // rjf: early mutation of unwind cache for immediate frontend effect - if(result) - { - D_UnwindCache *cache = &d_state->unwind_cache; - if(cache->slots_count != 0) - { - CTRL_Handle thread_handle = thread->handle; - U64 hash = d_hash_from_string(str8_struct(&thread_handle)); - U64 slot_idx = hash%cache->slots_count; - D_UnwindCacheSlot *slot = &cache->slots[slot_idx]; - for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, thread_handle) && n->unwind.frames.count != 0) - { - regs_arch_block_write_rip(thread->arch, n->unwind.frames.v[0].regs, vaddr); - break; - } - } - } - } + (void)result; }break; //- rjf: high-level composite target control operations diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 16d5101b..042ffd3a 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -215,35 +215,6 @@ struct D_CmdList //////////////////////////////// //~ rjf: Main State Caches -//- rjf: per-thread unwind cache - -typedef struct D_UnwindCacheNode D_UnwindCacheNode; -struct D_UnwindCacheNode -{ - D_UnwindCacheNode *next; - D_UnwindCacheNode *prev; - U64 reggen; - U64 memgen; - Arena *arena; - CTRL_Handle thread; - CTRL_Unwind unwind; -}; - -typedef struct D_UnwindCacheSlot D_UnwindCacheSlot; -struct D_UnwindCacheSlot -{ - D_UnwindCacheNode *first; - D_UnwindCacheNode *last; -}; - -typedef struct D_UnwindCache D_UnwindCache; -struct D_UnwindCache -{ - U64 slots_count; - D_UnwindCacheSlot *slots; - D_UnwindCacheNode *free_node; -}; - //- rjf: per-run tls-base-vaddr cache typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode; @@ -315,7 +286,6 @@ struct D_State HS_Key output_log_key; // rjf: per-run caches - D_UnwindCache unwind_cache; U64 tls_base_cache_reggen_idx; U64 tls_base_cache_memgen_idx; D_RunTLSBaseCache tls_base_caches[2]; @@ -435,7 +405,6 @@ internal B32 d_ctrl_targets_running(void); internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena); //- rjf: per-run caches -internal CTRL_Unwind d_query_cached_unwind_from_thread(CTRL_Entity *thread); internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread); internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count); internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr); From d7097241284055126990f74a82d5b695b3617e65 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 11:15:55 -0700 Subject: [PATCH 743/755] fix ctrl scope mal-usage --- src/dbg_engine/dbg_engine_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index dc76e3dc..d9a0643b 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1183,6 +1183,7 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count) { result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs); } + ctrl_scope_close(ctrl_scope); } return result; } From 15459edc75744067de443640715e29a6e63b60a7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 13:03:58 -0700 Subject: [PATCH 744/755] adjust wait timeout properties of ctrl process memory cache grab; don't wait forever to submit, don't wait if work was completed even if results bad, etc. --- src/async/async.c | 2 -- src/ctrl/ctrl_core.c | 47 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/async/async.c b/src/async/async.c index 2cf0f666..ec84c372 100644 --- a/src/async/async.c +++ b/src/async/async.c @@ -164,7 +164,6 @@ async_task_join(ASYNC_Task *task) internal ASYNC_Work async_pop_work(void) { - ProfBeginFunction(); ASYNC_Work work = {0}; B32 done = 0; ASYNC_Priority taken_priority = ASYNC_Priority_Low; @@ -199,7 +198,6 @@ async_pop_work(void) } os_condition_variable_broadcast(async_shared->ring_cv); os_condition_variable_broadcast(async_shared->rings[taken_priority].ring_cv); - ProfEnd(); return work; } diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index eebc8fb5..e3ac5773 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1652,11 +1652,13 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 //- rjf: loop: try to look for current results, request if not there, wait if we can, repeat until we can't U64 mem_gen = ctrl_mem_gen(); B32 key_is_stale = 0; + B32 requested = 0; for(;;) { //- rjf: step 1: [read-only] try to look for current results for key's ID B32 id_exists = 0; B32 id_stale = 0; + B32 id_working = 0; OS_MutexScopeR(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) @@ -1671,6 +1673,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 { id_exists = 1; id_stale = (n->mem_gen < mem_gen); + id_working = (ins_atomic_u64_eval(&n->working_count) != 0); goto end_fast_lookup; } } @@ -1691,7 +1694,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 //- rjf: step 3: if the ID does not exist in the process' cache, then we // need to build a node for it. if that, or if the ID is stale, then also // request that that range is streamed. - if(!id_exists || (id_exists && id_stale)) + if(!id_exists || (id_exists && id_stale && !id_working)) { B32 node_needs_stream = 0; U64 *node_working_count = 0; @@ -1719,12 +1722,16 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 range_n->vaddr_range = vaddr_range; range_n->zero_terminated = zero_terminated; range_n->id = id; - range_n->working_count += 1; + ins_atomic_u64_inc_eval(&range_n->working_count); node_needs_stream = 1; } else { node_needs_stream = (range_n->mem_gen < mem_gen); + if(node_needs_stream) + { + ins_atomic_u64_inc_eval(&range_n->working_count); + } } node_working_count = &range_n->working_count; break; @@ -1733,17 +1740,45 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 } if(node_needs_stream) { - ctrl_u2ms_enqueue_req(key, process, vaddr_range, zero_terminated, max_U64); - async_push_work(ctrl_mem_stream_work, .working_counter = node_working_count); + if(ctrl_u2ms_enqueue_req(key, process, vaddr_range, zero_terminated, endt_us)) + { + async_push_work(ctrl_mem_stream_work, .working_counter = node_working_count); + requested = 1; + } + else OS_MutexScopeR(process_stripe->rw_mutex) + { + for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) + { + if(ctrl_handle_match(process_n->handle, process)) + { + U64 range_slot_idx = range_hash%process_n->range_hash_slots_count; + CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx]; + for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next) + { + if(hs_id_match(n->id, id)) + { + ins_atomic_u64_dec_eval(&n->working_count); + goto end_fail_work; + } + } + } + } + end_fail_work:; + } } } - //- rjf: step 4: if we have no time to wait, then abort; otherwise, - // wait on this process' stripe + //- rjf: step 4: if we have no time to wait, then abort; if we submitted a + // request, but the work is done and we have no results, then abort; + // otherwise, wait on this process' stripe if(os_now_microseconds() >= endt_us) { break; } + else if(!id_working && requested) + { + break; + } else OS_MutexScopeR(process_stripe->rw_mutex) { os_condition_variable_wait_rw_r(process_stripe->cv, process_stripe->rw_mutex, endt_us); From a55c5b49aa309244f6a84fe6a8060b2f9a3431cf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 13:06:16 -0700 Subject: [PATCH 745/755] similarly adjust call stack cache timeout periods --- src/ctrl/ctrl_core.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e3ac5773..10335062 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3398,6 +3398,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ //- rjf: loop: try to grab cached call stack; request; wait // B32 can_request = !ins_atomic_u64_eval(&ctrl_state->ctrl_thread_run_state); + B32 did_request = 0; OS_MutexScopeR(stripe->rw_mutex) for(;;) { //////////////////////////// @@ -3450,10 +3451,12 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ // if(can_request && node != 0 && !is_working && is_stale) { - if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && - async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) + if(ctrl_u2csb_enqueue_req(thread->handle, endt_us)) { + did_request = 1; + is_working = 1; ins_atomic_u64_inc_eval(&node->working_count); + async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low); } } @@ -3468,7 +3471,14 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_ //////////////////////////// //- rjf: time to wait for new result? -> wait // - os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); + if(did_request && !is_working) + { + break; + } + else if(did_request) + { + os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); + } } return call_stack; } From 95dbba1144b6f942f3c92b1a091bc5c0106cd8f5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 13:18:15 -0700 Subject: [PATCH 746/755] debugging notes of programmatic data breakpoints --- src/ctrl/ctrl_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 10335062..e70715b7 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4671,6 +4671,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, }break; case DMN_EventKind_UnsetBreakpoint: { + // TODO(rjf): this needs to be reflected in the resolved trap list too!!!!!!!! CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts); out_evt->kind = CTRL_EventKind_UnsetBreakpoint; out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); From 2f5082fb6100196d0415853637b1c209596eff29 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 14:10:34 -0700 Subject: [PATCH 747/755] fix treatment of octal strings in try_u64/s64_from_str8_c_rules --- src/base/base_strings.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 2a9a096e..63faf8e2 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -603,44 +603,50 @@ s32_from_str8(String8 string, U32 radix) } internal B32 -try_u64_from_str8_c_rules(String8 string, U64 *x){ +try_u64_from_str8_c_rules(String8 string, U64 *x) +{ B32 is_integer = 0; - if (str8_is_integer(string, 10)){ + if(str8_is_integer(string, 10) && !str8_match(str8_prefix(string, 1), str8_lit("0"), 0)) + { is_integer = 1; *x = u64_from_str8(string, 10); } - else{ + else + { String8 hex_string = str8_skip(string, 2); - if (str8_match(str8_prefix(string, 2), str8_lit("0x"), 0) && - str8_is_integer(hex_string, 0x10)){ + if(str8_match(str8_prefix(string, 2), str8_lit("0x"), 0) && + str8_is_integer(hex_string, 0x10)) + { is_integer = 1; *x = u64_from_str8(hex_string, 0x10); } - else if (str8_match(str8_prefix(string, 2), str8_lit("0b"), 0) && - str8_is_integer(hex_string, 2)){ + else if(str8_match(str8_prefix(string, 2), str8_lit("0b"), 0) && str8_is_integer(hex_string, 2)) + { is_integer = 1; *x = u64_from_str8(hex_string, 2); } - else{ + else + { String8 oct_string = str8_skip(string, 1); - if (str8_match(str8_prefix(string, 1), str8_lit("0"), 0) && - str8_is_integer(hex_string, 010)){ + if(str8_match(str8_prefix(string, 1), str8_lit("0"), 0) && str8_is_integer(hex_string, 010)) + { is_integer = 1; *x = u64_from_str8(oct_string, 010); } } } - return(is_integer); + return is_integer; } internal B32 -try_s64_from_str8_c_rules(String8 string, S64 *x){ +try_s64_from_str8_c_rules(String8 string, S64 *x) +{ String8 string_tail = {0}; S64 sign = sign_from_str8(string, &string_tail); U64 x_u64 = 0; B32 is_integer = try_u64_from_str8_c_rules(string_tail, &x_u64); *x = x_u64*sign; - return(is_integer); + return is_integer; } //- rjf: integer -> string From 206ec346cfc633ac285525dcc1a1300c050bc4ac Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 14:46:46 -0700 Subject: [PATCH 748/755] fix 2-byte utf decoding issues, fix utf8 lexing issues --- src/base/base_strings.c | 2 +- src/text_cache/text_cache.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 63faf8e2..f98d6e44 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1517,7 +1517,7 @@ utf8_decode(U8 *str, U64 max){ }break; case 2: { - if (2 < max) + if (1 < max) { U8 cont_byte = str[1]; if (utf8_class[cont_byte >> 3] == 0) diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index e8706c1d..29200950 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -262,7 +262,7 @@ txt_token_array_from_string__c_cpp(Arena *arena, U64 *bytes_processed_counter, S }break; case TXT_TokenKind_Identifier: { - ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$'); + ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$' && byte < 128); }break; case TXT_TokenKind_Numeric: { @@ -606,7 +606,7 @@ txt_token_array_from_string__odin(Arena *arena, U64 *bytes_processed_counter, St }break; case TXT_TokenKind_Identifier: { - ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$'); + ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$' && byte < 128); }break; case TXT_TokenKind_Numeric: { @@ -892,7 +892,7 @@ txt_token_array_from_string__jai(Arena *arena, U64 *bytes_processed_counter, Str }break; case TXT_TokenKind_Identifier: { - ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$'); + ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$' && byte < 128); }break; case TXT_TokenKind_Numeric: { @@ -1177,7 +1177,7 @@ txt_token_array_from_string__zig(Arena *arena, U64 *bytes_processed_counter, Str }break; case TXT_TokenKind_Identifier: { - ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$'); + ender_found = (!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && byte != '$' && byte < 128); }break; case TXT_TokenKind_Numeric: { From f7df65678f27390e3a16fe8f5badadb8e34ef168 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:05:05 -0700 Subject: [PATCH 749/755] fix incorrect bounds check in regrel32 frameproc grab --- src/rdi_from_pdb/rdi_from_pdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index b6b61b0e..a15b21cb 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -2482,7 +2482,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) if(is_stack_reg) { U32 frame_size = 0xFFFFFFFF; - if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num < procedure_frameprocs_count) + if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num <= procedure_frameprocs_count) { CV_SymFrameproc *frameproc = procedure_frameprocs[procedure_num-1]; frame_size = frameproc->frame_size; From 0eb37c527cdc8083829f34474b2b158f8ef3c28f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:09:35 -0700 Subject: [PATCH 750/755] fix incorrect abort-on-0-rip condition in unwinder path; we can still have nonzero rsps and find valid frames. --- src/ctrl/ctrl_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e70715b7..99cd7cd8 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3206,8 +3206,8 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle thread, U } } - // rjf: cancel on 0 rip - if(rip == 0) + // rjf: cancel on 0 rip/rsp + if(rsp == 0 && rip == 0) { break; } From e6f53a39bb3fb946c4aeba0e9cd83bd9c81c5481 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:13:23 -0700 Subject: [PATCH 751/755] old windows dpi awareness paths --- src/os/gfx/win32/os_gfx_win32.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index 8caf11fd..ee0b4412 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -831,6 +831,21 @@ os_gfx_init(void) { SetProcessDpiAwarenessContext_func(w32_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); } + else + { + HMODULE shcore = LoadLibraryA("shcore.dll"); + if(shcore) + { + typedef HRESULT (WINAPI* SetProcessDpiAwareness_t)(int); + SetProcessDpiAwareness_t SetProcessDpiAwareness = (void*)GetProcAddress(shcore, "SetProcessDpiAwareness"); + if(SetProcessDpiAwareness) + { + SetProcessDpiAwareness(2); + } + FreeLibrary(shcore); + } + SetProcessDPIAware(); + } //- rjf: register graphical-window class { From 16fd72ef4f541f2d53ce71793854939f005c5cd0 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:31:37 -0700 Subject: [PATCH 752/755] more granular watch window fresh/bad visualization, since each cell can be an arbitrary evaluation now; also reintroduce failed-memory-read visualization --- src/raddbg/raddbg_core.c | 105 ++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d4773de7..6dc6f366 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4499,51 +4499,13 @@ rd_view_ui(Rng2F32 rect) // last_row_info = *row_info; - //////////////////////// - //- rjf: determine if row's data is fresh and/or bad - // - ProfBegin("determine if row's data is fresh and/or bad"); - B32 row_is_fresh = 0; - B32 row_is_bad = 0; - switch(row->eval.irtree.mode) - { - default:{}break; - case E_Mode_Offset: - { - CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(row->eval.space); - if(row->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) - { - U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key); - size = Min(size, 64); - Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size); - CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); - for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) - { - if(slice.byte_changed_flags[idx] != 0) - { - row_is_fresh = 1; - } - if(slice.byte_bad_flags[idx] != 0) - {row_is_bad = 1; - } - } - } - }break; - } - ProfEnd(); - //////////////////////// //- rjf: determine row's flags & color palette // ProfBegin("determine row's flags & color palette"); UI_BoxFlags row_flags = UI_BoxFlag_DisableFocusOverlay; { - if(row_is_fresh) - { - ui_set_next_tag(str8_lit("fresh")); - row_flags |= UI_BoxFlag_DrawBackground; - } - else if(global_row_idx & 1) + if(global_row_idx & 1) { ui_set_next_tag(str8_lit("alt")); row_flags |= UI_BoxFlag_DrawBackground; @@ -4653,6 +4615,43 @@ rd_view_ui(Rng2F32 rect) B32 cell_toggled = (cell_value_eval.value.u64 != 0); B32 next_cell_toggled = cell_toggled; + //////////////////////// + //- rjf: determine if cell evaluation's data is fresh and/or bad + // + ProfBegin("determine if cell evaluation's data is fresh and/or bad"); + B32 cell_is_fresh = 0; + B32 cell_is_bad = 0; + if(!(cell_info.flags & RD_WatchCellFlag_NoEval)) + { + switch(cell->eval.irtree.mode) + { + default:{}break; + case E_Mode_Offset: + { + CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(cell->eval.space); + if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) + { + U64 size = e_type_byte_size_from_key(cell->eval.irtree.type_key); + size = Min(size, 64); + Rng1U64 vaddr_rng = r1u64(cell->eval.value.u64, cell->eval.value.u64+size); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us); + for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) + { + if(slice.byte_changed_flags[idx] != 0) + { + cell_is_fresh = 1; + } + if(slice.byte_bad_flags[idx] != 0) + { + cell_is_bad = 1; + } + } + } + }break; + } + } + ProfEnd(); + //////////// //- rjf: compute slider parameters // @@ -4694,9 +4693,7 @@ rd_view_ui(Rng2F32 rect) //////////// //- rjf: determine cell's palette // - UI_BoxFlags cell_flags = 0; Vec4F32 cell_background_color_override = {0}; - String8 cell_tag = {0}; { if(cell_info.cfg->id == rd_get_hover_regs()->cfg && rd_state->hover_regs_slot == RD_RegSlot_Cfg) @@ -4711,7 +4708,6 @@ rd_view_ui(Rng2F32 rect) } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; } else if(ctrl_handle_match(cell_info.entity->handle, rd_get_hover_regs()->ctrl_entity) && rd_state->hover_regs_slot == RD_RegSlot_CtrlEntity) @@ -4726,7 +4722,21 @@ rd_view_ui(Rng2F32 rect) } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; - cell_flags |= UI_BoxFlag_DrawBackground; + } + else if(cell_is_fresh) + { + UI_TagF(".") UI_TagF("fresh") + { + cell_background_color_override = ui_color_from_name(str8_lit("background")); + } + } + else if(cell_is_bad) + { + UI_TagF(".") UI_TagF("bad_pop") + { + cell_background_color_override = ui_color_from_name(str8_lit("background")); + cell_background_color_override.w *= 0.2f; + } } } @@ -4737,7 +4747,7 @@ rd_view_ui(Rng2F32 rect) UI_PrefWidth(ui_px(cell_width_px, cell_width_strictness)) { ui_set_next_fixed_height(floor_f32(row->visual_size * row_height_px)); - cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft|cell_flags, "cell_%I64x_%I64x", row_hash, cell_id); + cell_box = ui_build_box_from_stringf(UI_BoxFlag_DrawSideLeft, "cell_%I64x_%I64x", row_hash, cell_id); } //////////// @@ -4752,7 +4762,6 @@ rd_view_ui(Rng2F32 rect) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off) RD_Font(RD_FontSlot_Code) UI_TagF("weak") - UI_Tag(cell_tag) { //- rjf: cell has hook? -> build ui by calling hook if(cell->kind == RD_WatchCellKind_ViewUI && cell_info.view_ui_rule != &rd_nil_view_ui_rule) @@ -5012,6 +5021,12 @@ rd_view_ui(Rng2F32 rect) cell_params.flags |= RD_CellFlag_Bindings; cell_params.bindings_name = rd_cmd_name_from_eval(cell->eval); } + + // rjf: apply background override + if(cell_background_color_override.w != 0) + { + cell_params.flags &= ~RD_CellFlag_NoBackground; + } } // rjf: build From 2d5bf9efc2aefad6477894989654cf2c8b6d63c1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:41:16 -0700 Subject: [PATCH 753/755] last-hit-breakpoint visualization --- src/raddbg/raddbg_widgets.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 98faec79..40eaa452 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -99,6 +99,27 @@ rd_title_fstrs_from_cfg(Arena *arena, RD_Cfg *cfg) params.color = rgba_secondary; } + //- rjf: [breakpoints] push hit marker + if(str8_match(cfg->string, str8_lit("breakpoint"), 0)) + { + CTRL_Event stop_event = d_ctrl_last_stop_event(); + if(stop_event.cause == CTRL_EventCause_UserBreakpoint) + { + RD_Cfg *bp = rd_cfg_from_id(stop_event.u64_code); + if(bp == cfg) + { + CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, stop_event.entity); + Vec4F32 thread_color = rd_color_from_ctrl_entity(thread); + if(thread_color.w == 0) + { + thread_color = rgba_secondary; + } + dr_fstrs_push_new(arena, &result, ¶ms, rd_icon_kind_text_table[RD_IconKind_RightArrow], .font = rd_font_from_slot(RD_FontSlot_Icons), .raster_flags = rd_raster_flags_from_slot(RD_FontSlot_Icons), .color = thread_color); + dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" ")); + } + } + } + //- rjf: push icon if(icon_kind != RD_IconKind_Null) { From 25dda717ada0c565aaa9a09f55fe41c732c1ffeb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 15:59:49 -0700 Subject: [PATCH 754/755] setting to prefer os native file dialog uis (off by default because they are slow and bad) --- src/os/gfx/linux/os_gfx_linux.c | 6 ++++++ src/os/gfx/os_gfx.h | 1 + src/os/gfx/stub/os_gfx_stub.c | 6 ++++++ src/os/gfx/win32/os_gfx_win32.c | 23 +++++++++++++++++++++++ src/os/gfx/win32/os_gfx_win32.h | 1 + src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 4 ++++ src/raddbg/raddbg_core.c | 19 +++++++++++++++++++ 8 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/os/gfx/linux/os_gfx_linux.c b/src/os/gfx/linux/os_gfx_linux.c index 7a142531..f8d43416 100644 --- a/src/os/gfx/linux/os_gfx_linux.c +++ b/src/os/gfx/linux/os_gfx_linux.c @@ -680,6 +680,12 @@ os_graphical_message(B32 error, String8 title, String8 message) fprintf(stderr, "%.*s\n\n", str8_varg(message)); } +internal String8 +os_graphical_pick_file(Arena *arena, String8 initial_path) +{ + return str8_zero(); +} + //////////////////////////////// //~ rjf: @os_hooks Shell Operations diff --git a/src/os/gfx/os_gfx.h b/src/os/gfx/os_gfx.h index 028a0195..1058c304 100644 --- a/src/os/gfx/os_gfx.h +++ b/src/os/gfx/os_gfx.h @@ -191,6 +191,7 @@ internal void os_set_cursor(OS_Cursor cursor); //~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS) internal void os_graphical_message(B32 error, String8 title, String8 message); +internal String8 os_graphical_pick_file(Arena *arena, String8 initial_path); //////////////////////////////// //~ rjf: @os_hooks Shell Operations diff --git a/src/os/gfx/stub/os_gfx_stub.c b/src/os/gfx/stub/os_gfx_stub.c index bb89d335..3a095ab2 100644 --- a/src/os/gfx/stub/os_gfx_stub.c +++ b/src/os/gfx/stub/os_gfx_stub.c @@ -242,6 +242,12 @@ os_graphical_message(B32 error, String8 title, String8 message) { } +internal String8 +os_graphical_pick_file(Arena *arena, String8 initial_path) +{ + return str8_zero(); +} + //////////////////////////////// //~ rjf: @os_hooks Shell Operations diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index ee0b4412..e298c187 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -1577,6 +1577,29 @@ os_graphical_message(B32 error, String8 title, String8 message) scratch_end(scratch); } +internal String8 +os_graphical_pick_file(Arena *arena, String8 initial_path) +{ + String8 result = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + U64 buffer_size = 4096; + U16 *buffer = push_array(scratch.arena, U16, buffer_size); + OPENFILENAMEW params = {sizeof(params)}; + { + params.lpstrFile = (WCHAR *)buffer; + params.nMaxFile = buffer_size; + params.lpstrInitialDir = (WCHAR *)str16_from_8(scratch.arena, initial_path).str; + } + if(GetOpenFileNameW(¶ms)) + { + result = str8_from_16(arena, str16_cstring((U16 *)buffer)); + } + scratch_end(scratch); + } + return result; +} + //////////////////////////////// //~ rjf: @os_hooks Shell Operations diff --git a/src/os/gfx/win32/os_gfx_win32.h b/src/os/gfx/win32/os_gfx_win32.h index 78d0daaa..3ab4de16 100644 --- a/src/os/gfx/win32/os_gfx_win32.h +++ b/src/os/gfx/win32/os_gfx_win32.h @@ -15,6 +15,7 @@ #pragma comment(lib, "UxTheme") #pragma comment(lib, "ole32") #pragma comment(lib, "user32") +#pragma comment(lib, "comdlg32") #ifndef WM_NCUAHDRAWCAPTION #define WM_NCUAHDRAWCAPTION (0x00AE) #endif diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index fbe190a4..89359b92 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -409,7 +409,7 @@ RD_VocabInfo rd_vocab_info_table[343] = RD_NameSchemaInfo rd_name_schema_info_table[24] = { -{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n @default('') 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n @default('') 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n @display_name('View Call Argument Helper') @description(\"Enables the view call argument helper, which shows view arguments and documentation, while typing expressions.\") @default(1)\n 'view_call_argument_helper': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n}\n")}, +{str8_lit_comp("user"), str8_lit_comp("@expand_commands(edit_user_theme) x:\n{\n //- rjf: animations\n @display_name('Animations') @description(\"Enables animations.\")\n @default(1) 'animations': bool,\n @display_name('Scrolling Animations') @description(\"Enables scrolling animations.\")\n @expand_if(\"$.animations\") @default(1) 'scrolling_animations': bool,\n @display_name('Tooltip Animations') @description(\"Enables tooltip animations.\")\n @expand_if(\"$.animations\") @default(1) 'tooltip_animations': bool,\n @display_name('Menu Animations') @description(\"Enables menu animations.\")\n @expand_if(\"$.animations\") @default(1) 'menu_animations': bool,\n\n //- rjf: fonts\n @display_name('UI Font') @description(\"The name of, or path to, the font used when displaying non-code UI elements.\")\n @default('') 'main_font': string,\n @display_name('Code Font') @description(\"The name of, or path to, the font used when displaying code.\")\n @default('') 'code_font': string,\n\n //- rjf: theme\n @default(\"Default (Dark)\") @display_name('User Theme')\n @description(\"The user's theme, which describes all colors used throughout the UI.\")\n 'theme': string,\n @no_expand @display_name('User Theme')\n 'theme_colors': query,\n\n //- rjf: autocompletion\n @display_name('Autocompletion Lister') @description(\"Enables the autocompletion lister while typing expressions.\") @default(1)\n 'autocompletion_lister': bool,\n @display_name('View Call Argument Helper') @description(\"Enables the view call argument helper, which shows view arguments and documentation, while typing expressions.\") @default(1)\n 'view_call_argument_helper': bool,\n\n //- rjf: thread & breakpoint decorations\n @default(1) @display_name('Thread Lines') @description(\"Controls whether or not a long horizontal line is drawn before the next line or instruction that the selected thread will execute in source and disassembly views.\")\n 'thread_lines': bool,\n @default(1) @display_name('Thread Glow') @description(\"Controls whether or not a glowing effect is drawn on the selected thread in source and disassembly views.\")\n 'thread_glow': bool,\n @default(1) @display_name('Breakpoint Lines') @description(\"Controls whether or not a long horizontal line is drawn before the line or instruction at which a breakpoint is placed, in source and disassembly views.\")\n 'breakpoint_lines': bool,\n @default(1) @display_name('Breakpoint Glow') @description(\"Controls whether or not a glowing effect is drawn on breakpoints in source and disassembly views.\")\n 'breakpoint_glow': bool,\n\n //- rjf: occluding background settings\n @default(0) @display_name('Opaque Backgrounds') @description(\"Controls whether or not all floating background colors are forced to be fully opaque.\")\n 'opaque_backgrounds': bool,\n @default(1) @display_name('Background Blur') @description(\"Controls whether or not occluded regions behind floating elements are blurred.\")\n 'background_blur': bool,\n\n //- rjf: appearance settings\n @default(1) @display_name('Drop Shadows') @description(\"Controls whether or not drop shadows are drawn.\")\n 'drop_shadows': bool,\n @default(1.f) @display_name('Rounded Corner Amount') @description(\"Controls the degree to which UI corners are rounded.\")\n 'rounded_corner_amount': @range[0, 1] f32,\n\n //- rjf: code formatting settings\n @default(2) @display_name('User Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: windows style menu bar\n @default(1) @display_name('Focus Menu Bar With Alt') @description(\"Mimics standard Windows behavior of focusing the menu bar using the Alt key.\")\n 'focus_menu_bar_with_alt': bool,\n\n //- rjf: native filesystem dialogues\n @default(0) @display_name('Use Native File System Dialog') @description(\"Uses the operating system's file system dialog box, rather than the debugger's built-in UI.\")\n 'use_native_file_system_dialog': bool,\n}\n")}, {str8_lit_comp("project"), str8_lit_comp("@expand_commands(edit_project_theme) x:\n{\n @default(2) @display_name('Project Tab Width') 'tab_width': @range[1, 32] u64,\n\n //- rjf: visualizers\n @display_name('Use Default C++ STL Type Visualizers') @description(\"Enables the built-in type views for C++ STL types.\")\n @default(1) use_default_stl_type_views: bool,\n // @display_name('Use Default Unreal Engine Type Visualizers') @description(\"Enables the built-in type views for Unreal Engine types.\")\n // @default(1) use_default_ue_type_views: bool,\n\n //- rjf: theme\n @default(\"None\") @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme': string,\n @no_expand @display_name('Project Theme') @description(\"The project's theme, which describes all colors used throughout the UI, and can override the user's theme.\")\n 'theme_colors': query,\n\n //- rjf: exception settings\n @default(1) @display_name(\"Break On Win32 Control-C Exceptions\") @description(\"Code: 0x40010005\")\n win32_ctrl_c: bool;\n @default(1) @display_name(\"Break On Win32 Control-Break Exceptions\") @description(\"Code: 0x40010008\")\n win32_ctrl_break: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Originate Error Exceptions\") @description(\"Code: 0x40080201\")\n win32_win_rt_originate_error: bool;\n @default(0) @display_name(\"Break On Win32 WinRT Transform Error Exceptions\") @description(\"Code: 0x40080202\")\n win32_win_rt_transform_error: bool;\n @default(0) @display_name(\"Break On Win32 RPC Call Cancelled Exceptions\") @description(\"Code: 0x0000071a\")\n win32_rpc_call_cancelled: bool;\n @default(0) @display_name(\"Break On Win32 Data Type Misalignment Exceptions\") @description(\"Code: 0x80000002\")\n win32_datatype_misalignment: bool;\n @default(1) @display_name(\"Break On Win32 Access Violation Exceptions\") @description(\"Code: 0xc0000005\")\n win32_access_violation: bool;\n @default(0) @display_name(\"Break On Win32 In Page Error Exceptions\") @description(\"Code: 0xc0000006\")\n win32_in_page_error: bool;\n @default(1) @display_name(\"Break On Win32 Invalid Handle Specified Exceptions\") @description(\"Code: 0xc0000008\")\n win32_invalid_handle: bool;\n @default(0) @display_name(\"Break On Win32 Not Enough Quota Exceptions\") @description(\"Code: 0xc0000017\")\n win32_not_enough_quota: bool;\n @default(0) @display_name(\"Break On Win32 Illegal Instruction Exceptions\") @description(\"Code: 0xc000001d\")\n win32_illegal_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Cannot Continue From Exception Exceptions\") @description(\"Code: 0xc0000025\")\n win32_cannot_continue_exception: bool;\n @default(0) @display_name(\"Break On Win32 Invalid Exception Disposition Returned By Handler Exceptions\") @description(\"Code: 0xc0000026\")\n win32_invalid_exception_disposition: bool;\n @default(0) @display_name(\"Break On Win32 Array Bounds Exceeded Exceptions\") @description(\"Code: 0xc000008c\")\n win32_array_bounds_exceeded: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Denormal Operand Exceptions\") @description(\"Code: 0xc000008d\")\n win32_floating_point_denormal_operand: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Division By Zero Exceptions\") @description(\"Code: 0xc000008e\")\n win32_floating_point_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Inexact Result Exceptions\") @description(\"Code: 0xc000008f\")\n win32_floating_point_inexact_result: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Invalid Operation Exceptions\") @description(\"Code: 0xc0000090\")\n win32_floating_point_invalid_operation: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Overflow Exceptions\") @description(\"Code: 0xc0000091\")\n win32_floating_point_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Stack Check Exceptions\") @description(\"Code: 0xc0000092\")\n win32_floating_point_stack_check: bool;\n @default(0) @display_name(\"Break On Win32 Floating-Point Underflow Exceptions\") @description(\"Code: 0xc0000093\")\n win32_floating_point_underflow: bool;\n @default(0) @display_name(\"Break On Win32 Integer Division By Zero Exceptions\") @description(\"Code: 0xc0000094\")\n win32_integer_division_by_zero: bool;\n @default(0) @display_name(\"Break On Win32 Integer Overflow Exceptions\") @description(\"Code: 0xc0000095\")\n win32_integer_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Privileged Instruction Exceptions\") @description(\"Code: 0xc0000096\")\n win32_privileged_instruction: bool;\n @default(0) @display_name(\"Break On Win32 Stack Overflow Exceptions\") @description(\"Code: 0xc00000fd\")\n win32_stack_overflow: bool;\n @default(0) @display_name(\"Break On Win32 Unable To Locate DLL Exceptions\") @description(\"Code: 0xc0000135\")\n win32_unable_to_locate_dll: bool;\n @default(0) @display_name(\"Break On Win32 Ordinal Not Found Exceptions\") @description(\"Code: 0xc0000138\")\n win32_ordinal_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Entry Point Not Found Exceptions\") @description(\"Code: 0xc0000139\")\n win32_entry_point_not_found: bool;\n @default(0) @display_name(\"Break On Win32 DLL Initialization Failed Exceptions\") @description(\"Code: 0xc0000142\")\n win32_dll_initialization_failed: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Faults Exceptions\") @description(\"Code: 0xc00002b4\")\n win32_floating_point_sse_multiple_faults: bool;\n @default(0) @display_name(\"Break On Win32 Floating Point SSE Multiple Traps Exceptions\") @description(\"Code: 0xc00002b5\")\n win32_floating_point_sse_multiple_traps: bool;\n @default(1) @display_name(\"Break On Win32 Assertion Failed Exceptions\") @description(\"Code: 0xc0000420\")\n win32_assertion_failed: bool;\n @default(0) @display_name(\"Break On Win32 Module Not Found Exceptions\") @description(\"Code: 0xc06d007e\")\n win32_module_not_found: bool;\n @default(0) @display_name(\"Break On Win32 Procedure Not Found Exceptions\") @description(\"Code: 0xc06d007f\")\n win32_procedure_not_found: bool;\n @default(1) @display_name(\"Break On Win32 Sanitizer Error Detected Exceptions\") @description(\"Code: 0xe073616e\")\n win32_sanitizer_error_detected: bool;\n @default(0) @display_name(\"Break On Win32 Sanitizer Raw Access Violation Exceptions\") @description(\"Code: 0xe0736171\")\n win32_sanitizer_raw_access_violation: bool;\n @default(1) @display_name(\"Break On Win32 DirectX Debug Layer Exceptions\") @description(\"Code: 0x0000087a\")\n win32_directx_debug_layer: bool;\n}\n")}, {str8_lit_comp("theme_color"), str8_lit_comp("@collection_commands(add_theme_color, fork_theme, save_theme, save_and_set_theme)\n@row_commands(duplicate_cfg, remove_cfg)\nx:\n{\n @display_name('Tags') tags: string,\n @display_name('Value') value: @color @hex u32,\n}\n")}, {str8_lit_comp("window"), str8_lit_comp("x:\n{\n //- rjf: text rasterization settings\n @default(1) @display_name('Smooth UI Text') @description(\"Controls whether or not UI text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_ui_text': bool,\n @default(1) @display_name('Hint UI Text') @description(\"Controls whether or not UI text is hinted, for better text readability at small sizes.\")\n 'hint_ui_text': bool,\n @default(0) @display_name('Smooth Code Text') @description(\"Controls whether or not code text is fully anti-aliased, for a smoother appearance.\")\n 'smooth_code_text': bool,\n @default(1) @display_name('Hint Code Text') @description(\"Controls whether or not code text is hinted, for better text readability at small sizes.\")\n 'hint_code_text': bool,\n @default(11) @display_name('Window Font Size') @description(\"Controls the window's default font size. Does not apply to tabs with their own font size set.\")\n 'font_size': @range[6, 72] u64,\n\n //- rjf: size settings\n @default(3.f) @display_name('Window Row Height') @description(\"Controls the window's default row height, in multiples of the font size. Does not apply to tabs with their own row height set.\")\n 'row_height': @range[1.75f, 5.f] f32,\n @default(3.f) @description(\"Controls the height of tabs, in multiples of the font size.\")\n 'tab_height': @range[1.75f, 5.f] f32,\n\n //- rjf: theme settings\n @default(1) @display_name('Use Project Theme') @description(\"Prefer using the project theme for this window, if any. If off, only the user's theme settings will be used.\")\n 'use_project_theme': bool,\n}\n")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f0329658..0f70fa7b 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -279,6 +279,10 @@ RD_VocabTable: //- rjf: windows style menu bar @default(1) @display_name('Focus Menu Bar With Alt') @description("Mimics standard Windows behavior of focusing the menu bar using the Alt key.") 'focus_menu_bar_with_alt': bool, + + //- rjf: native filesystem dialogues + @default(0) @display_name('Use Native File System Dialog') @description("Uses the operating system's file system dialog box, rather than the debugger's built-in UI.") + 'use_native_file_system_dialog': bool, } ``` } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6dc6f366..0c639e56 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -12645,6 +12645,25 @@ rd_frame(void) RD_RegsScope(.cmd_name = str8_zero()) rd_push_cmd(cmd->regs->cmd_name, rd_regs()); } + // rjf: command has filesystem query, user wants native filesystem UI -> get the path then run the command + else if(info->query.slot == RD_RegSlot_FilePath && rd_setting_b32_from_name(str8_lit("use_native_file_system_dialog"))) + { + RD_Cfg *user = rd_cfg_child_from_string(rd_state->root_cfg, str8_lit("user")); + RD_Cfg *current_path = rd_cfg_child_from_string(user, str8_lit("current_path")); + String8 current_path_string = current_path->first->string; + if(current_path_string.size == 0) + { + current_path_string = path_normalized_from_string(scratch.arena, os_get_current_path(scratch.arena)); + } + String8 file_path = os_graphical_pick_file(scratch.arena, current_path_string); + file_path = path_normalized_from_string(scratch.arena, file_path); + if(file_path.size != 0) + { + RD_RegsScope(.cmd_name = str8_zero(), .file_path = file_path) rd_push_cmd(cmd->regs->cmd_name, rd_regs()); + rd_cmd(RD_CmdKind_SetCurrentPath, .file_path = str8_chop_last_slash(file_path)); + } + } + // rjf: command has required query -> prep query else { From 8bed56adde258ce062b5126bafb5250013cacef5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 20 May 2025 16:15:03 -0700 Subject: [PATCH 755/755] step-into-line trap nets: omit stopping at non-final call destinations with no line info --- src/dbg_engine/dbg_engine_core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index d9a0643b..69c5432d 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -555,6 +555,16 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) machine_code); } + // rjf: determine last + DASM_CtrlFlowPoint *last_call_point = 0; + if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) + { + if(n->v.inst_flags & DASM_InstFlag_Call) + { + last_call_point = &n->v; + } + } + // rjf: push traps for all exit points if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) { @@ -563,6 +573,23 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) B32 add = 1; U64 trap_addr = point->vaddr; + // rjf: if this is not the last call instruction in the control flow, + // and if we have no line info for this address, then do not add. + if(point != last_call_point && + point->inst_flags & DASM_InstFlag_Call && + point->jump_dest_vaddr != 0) + { + U64 jump_dest_vaddr = point->jump_dest_vaddr; + CTRL_Entity *jump_dest_module = ctrl_module_from_process_vaddr(process, jump_dest_vaddr); + U64 jump_dest_voff = ctrl_voff_from_vaddr(jump_dest_module, jump_dest_vaddr); + DI_Key jump_dest_dbgi_key = ctrl_dbgi_key_from_module(jump_dest_module); + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &jump_dest_dbgi_key, jump_dest_voff); + if(lines.count == 0) + { + add = 0; + } + } + // rjf: branches/jumps/returns => single-step & end, OR trap @ destination. if(point->inst_flags & (DASM_InstFlag_Call| DASM_InstFlag_Branch|